Skip to content

Commit

Permalink
feat(app-general): create first ui-components
Browse files Browse the repository at this point in the history
  • Loading branch information
albertodigioacchino committed Jan 14, 2021
1 parent 66a2636 commit cb5cc5d
Show file tree
Hide file tree
Showing 8 changed files with 415 additions and 36 deletions.
137 changes: 102 additions & 35 deletions packages/game-app/package-lock.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions packages/game-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"react-router-dom": "^5.2.0",
"react-zoom-pan-pinch": "^1.6.1",
"redux-saga": "^1.1.3",
"styled-components": "^5.2.1",
"web-vitals": "^0.2.4",
"yup": "^0.32.8"
},
Expand Down Expand Up @@ -68,6 +69,7 @@
"@types/react-redux": "^7.1.14",
"@types/react-router-dom": "^5.1.6",
"@types/redux-saga": "^0.10.5",
"@types/styled-components": "^5.1.7",
"cypress": "^6.2.0",
"env-cmd": "^10.1.0",
"firebase-admin": "^9.4.2",
Expand Down
70 changes: 70 additions & 0 deletions packages/game-app/src/ui-kit/Button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import React, { DetailedHTMLProps, ButtonHTMLAttributes } from 'react';
import styled from 'styled-components';

type Props = Omit<DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, 'type' | 'ref'> & {
type?: 'primary' | 'secondary';
variant?: 'rounded' | 'text-icon' | 'icon';
};

const StyledButton = styled.button`
cursor: pointer;
&:hover {
transform: scale(1.05);
}
&:focus {
outline: none;
}
`;

const PrimaryButton = styled(StyledButton)`
background-color: #101820; /* Green */
border: none;
color: white;
padding: 10px 35px;
text-align: center;
text-decoration: none;
font-size: 16px;
border-radius: 25px;
font-weight: 600;
margin: 15px 0;
`;

const SecondaryButton = styled(StyledButton)`
//TODO
`;

const IconButton = styled(StyledButton)`
background-color: transparent;
border: none;
padding: 8px;
`;

const Button: React.FC<Props> = ({ type = 'primary', variant = 'rounded', children, ...other }) => {
if (type === 'primary') {
if (variant === 'icon') {
return (
<IconButton type="button" {...other}>
{children}
</IconButton>
);
} else {
return (
<PrimaryButton type="button" {...other}>
{children}
</PrimaryButton>
);
}
} else if (type === 'secondary') {
return (
<SecondaryButton type="button" {...other}>
{children}
</SecondaryButton>
);
} else {
return null;
}
};

Button.displayName = 'Button';

export default Button;
160 changes: 160 additions & 0 deletions packages/game-app/src/ui-kit/Card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
import styled from 'styled-components';
import { Card, CardTags, CardTypes } from '@pipeline/common';
import React from 'react';
import FontSizeResizableTextArea from './FontSizeResizableTextArea';

type CardProps = Card & { headerTitle: string; readOnly?: boolean; imgURL?: string };

interface CardHeaderProps {
type: CardTypes;
}
interface CardTagProps {
tag: CardTags;
}

const tagObj = {
[CardTags.ManualStep]: {
backgroundColor: '#ffd100',
},
[CardTags.DeliveryStep]: {
backgroundColor: '#f7951c',
},
[CardTags.DeployStep]: {
backgroundColor: '#3fc7f4',
},
[CardTags.Package]: {
backgroundColor: '#e6accd',
},
[CardTags.SystemTest]: {
backgroundColor: '#6e3695',
},
} as { [key in CardTags]: { backgroundColor: string } };

const headerObj = {
[CardTypes.GameRule]: {
fromColor: '#b685ab',
toColor: '#711d60',
},
[CardTypes.PipelineStep]: {
fromColor: '#52c2b0',
toColor: '#009778',
},
[CardTypes.Review]: {
fromColor: '#fd9468',
toColor: '#f34600',
},
[CardTypes.Scenario]: {
fromColor: '#6ed6ea',
toColor: '#00bddd',
},
} as {
[key in CardTypes]: {
fromColor: string;
toColor: string;
};
};

const CardWrapper = styled.div`
overflow: hidden;
padding: 0 0 32px;
margin: 48px auto 0;
width: 400px;
height: 250px;
font-family: Quicksand, arial, sans-serif;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.05), 0 0 40px rgba(0, 0, 0, 0.08);
border-radius: 5px;
`;

const CardHeader = styled.header<CardHeaderProps>`
padding-top: 16px;
padding-bottom: 16px;
padding-left: 12px;
padding-right: 12px;
background: ${(props: CardHeaderProps) =>
`linear-gradient(90deg, ${headerObj[props.type].fromColor} 0%, ${headerObj[props.type].toColor} 100%)`};
`;

const CardHeadingTag = styled.span<CardTagProps>`
font-size: 10px;
font-weight: bold;
color: ${(props: CardTagProps) => (props.tag === CardTags.ManualStep ? 'black' : 'white')};
background-color: ${(props: CardTagProps) => tagObj[props.tag].backgroundColor};
border-radius: 10px;
padding-top: 4px;
padding-bottom: 4px;
padding-left: 6px;
padding-right: 6px;
margin-left: 2px;
`;

const CardHeading = styled.h1`
font-size: 16px;
font-weight: bolder;
text-align: right;
color: white;
`;

const CardBody = styled.div`
padding-right: 32px;
padding-left: 32px;
padding-top: 12px;
padding-bottom: 12px;
height: 100%;
`;

const CardBodyTitle = styled.h2`
font-size: 15px;
font-weight: bolder;
margin-bottom: 3px;
`;

const CardBodySubTitle = styled.h3`
font-size: 12px;
font-weight: bolder;
color: #00b582;
margin-bottom: 3px;
`;

const CardTextArea = styled(FontSizeResizableTextArea)`
outline: none;
border: none;
background-color: transparent;
resize: none;
overflow: hidden;
height: 100% !important;
width: 100% !important;
`;

const CardComponent: React.FC<CardProps> = ({
headerTitle,
type,
title,
subtitle,
content,
readOnly = true,
tags,
...other
}) => {
console.log('tags', tags);
return (
<CardWrapper>
<CardHeader type={type}>
<CardHeading>{headerTitle}</CardHeading>
{tags?.map(t => (
<CardHeadingTag key={t} tag={t}>
{t}
</CardHeadingTag>
))}
</CardHeader>
<CardBody>
<CardBodyTitle>{title}</CardBodyTitle>
{subtitle && <CardBodySubTitle>{subtitle}</CardBodySubTitle>}
<CardTextArea textAreaProps={{ readOnly: false }}>{content}</CardTextArea>
</CardBody>
</CardWrapper>
);
};

CardComponent.displayName = 'Card';

export default CardComponent;
47 changes: 47 additions & 0 deletions packages/game-app/src/ui-kit/FontSizeResizableTextArea.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { TextareaHTMLAttributes, DetailedHTMLProps, FC, useMemo, useState, useCallback, ChangeEvent } from 'react';

export type TextAreaProps = DetailedHTMLProps<TextareaHTMLAttributes<HTMLTextAreaElement>, HTMLTextAreaElement>;

interface FontSizeResizableTextAreaProps {
textAreaProps: Omit<TextAreaProps, 'className'>;
className?: TextAreaProps['className'];
}

const FontSizeResizableTextArea: FC<FontSizeResizableTextAreaProps> = ({
textAreaProps: { onChange, value, style, ...others },
className,
}) => {
const [val, setValue] = useState(value);

const handleChange = useCallback(
(event: ChangeEvent<HTMLTextAreaElement>) => {
setValue(event.target.value);
onChange && onChange(event);
},
[onChange],
);

const fontSize = useMemo(() => {
const baseSize = 32;
const amtLength = val ? val.toString().length : 0;
const maxLength = 10;
// increase/decrease deduction amount
const fudgeFactor = 5;

if (amtLength > maxLength) {
const diff = amtLength - maxLength + fudgeFactor;
return `${baseSize - diff}px`;
}
return `${baseSize}px`;
}, [val]);

const memoStyle = useMemo(() => {
return { ...style, fontSize };
}, [style, fontSize]);

return <textarea className={className} style={memoStyle} {...others} onChange={handleChange} value={value} />;
};

FontSizeResizableTextArea.displayName = 'FontSizeResizableTextArea';

export default FontSizeResizableTextArea;
26 changes: 26 additions & 0 deletions packages/game-app/src/ui-kit/Link.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from 'react';
import styled from 'styled-components';

type Props = {
onClick: () => void;
};

const LinkButton = styled.button`
background-color: transparent;
border: 0;
text-decoration: underline;
font-size: 15px;
color: #9f998f;
`;

const Link: React.FC<Props> = ({ onClick, children }) => {
return (
<LinkButton type="button" onClick={onClick}>
{children}
</LinkButton>
);
};

Link.displayName = 'Link';

export default Link;
6 changes: 6 additions & 0 deletions packages/game-app/src/ui-kit/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import Card from './Card';
import FontSizeResizableTextArea from './FontSizeResizableTextArea';
import Link from './Link';
import Button from './Button';

export { Card, FontSizeResizableTextArea, Link, Button };
3 changes: 2 additions & 1 deletion packages/game-app/tsconfig.paths.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
"@pipeline/form": ["src/_shared/form"],
"@pipeline/components": ["src/_shared/components"],
"@pipeline/models": ["src/_shared/models"],
"@pipeline/dynamicData": ["src/_shared/dynamicData"]
"@pipeline/dynamicData": ["src/_shared/dynamicData"],
"@pipeline/ui-kit": ["src/ui-kit"]
}
}
}

0 comments on commit cb5cc5d

Please sign in to comment.