Skip to content

Commit e19fa08

Browse files
committed
ui+common: Added components from terminal-web
- Grid container - Date picker input - Full page overlay form - Text helpers
1 parent 4aab704 commit e19fa08

File tree

6 files changed

+328
-0
lines changed

6 files changed

+328
-0
lines changed

app/src/components/base/grid.tsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,21 @@
11
import React, { CSSProperties } from 'react';
22

3+
/**
4+
* This component represents a container in the bootstrap Grid layout
5+
*/
6+
export const Container: React.FC<{
7+
className?: string;
8+
style?: CSSProperties;
9+
}> = ({ children, className, style }) => {
10+
const cn: string[] = ['container'];
11+
className && cn.push(className);
12+
return (
13+
<div className={cn.join(' ')} style={style}>
14+
{children}
15+
</div>
16+
);
17+
};
18+
319
/**
420
* This component represents a Row in the bootstrap Grid layout
521
*/
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import React, { ReactNode } from 'react';
2+
import styled from '@emotion/styled';
3+
4+
const Styled = {
5+
Wrapper: styled.div`
6+
position: relative;
7+
font-family: ${props => props.theme.fonts.work.light};
8+
font-weight: 300;
9+
font-size: ${props => props.theme.sizes.s};
10+
color: ${props => props.theme.colors.offWhite};
11+
`,
12+
Input: styled.input`
13+
color: ${props => props.theme.colors.offWhite};
14+
background-color: ${props => props.theme.colors.overlay};
15+
border-width: 0;
16+
border-bottom: 1px solid ${props => props.theme.colors.gray};
17+
padding: 5px 40px 5px 5px;
18+
width: 100%;
19+
20+
&:active,
21+
&:focus {
22+
outline: none;
23+
border-bottom-color: ${props => props.theme.colors.white};
24+
}
25+
26+
&::placeholder {
27+
color: ${props => props.theme.colors.gray};
28+
}
29+
`,
30+
Extra: styled.div`
31+
position: absolute;
32+
top: 0;
33+
right: 0;
34+
background-color: transparent;
35+
padding: 5px;
36+
`,
37+
};
38+
39+
interface Props {
40+
label?: string;
41+
value?: string;
42+
extra?: ReactNode;
43+
placeholder?: string;
44+
className?: string;
45+
onChange?: (value: string) => void;
46+
}
47+
48+
const FormDate: React.FC<Props> = ({
49+
label,
50+
value,
51+
placeholder,
52+
extra,
53+
className,
54+
onChange,
55+
}) => {
56+
const { Wrapper, Input, Extra } = Styled;
57+
return (
58+
<Wrapper className={className}>
59+
<Input
60+
type="date"
61+
value={value}
62+
onChange={e => onChange && onChange(e.target.value)}
63+
placeholder={placeholder}
64+
aria-label={label}
65+
/>
66+
{extra && <Extra>{extra}</Extra>}
67+
</Wrapper>
68+
);
69+
};
70+
71+
export default FormDate;
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import React, { ReactNode, useEffect } from 'react';
2+
import { observer } from 'mobx-react-lite';
3+
import styled from '@emotion/styled';
4+
import { Button, Column, Container, Row, Close } from 'components/base';
5+
import { DisplayLarge, Header } from './v2/Text';
6+
7+
const Styled = {
8+
Wrapper: styled.div`
9+
h4 {
10+
color: ${props => props.theme.colors.offWhite};
11+
}
12+
`,
13+
BackLink: styled(Button)`
14+
display: inline-block;
15+
position: absolute;
16+
top: 30px;
17+
right: 0px;
18+
left: auto;
19+
z-index: 10;
20+
21+
@media (${props => props.theme.breakpoints.m}) {
22+
top: 30px;
23+
right: 0px;
24+
}
25+
`,
26+
Title: styled(DisplayLarge)`
27+
font-weight: ${props => props.theme.fonts.open.bold};
28+
margin-bottom: 16px;
29+
`,
30+
Content: styled.div``,
31+
};
32+
33+
interface Props {
34+
title: string;
35+
description: ReactNode;
36+
onBackClick?: () => void;
37+
}
38+
39+
const OverlayFormWrap: React.FC<Props> = ({
40+
title,
41+
description,
42+
onBackClick,
43+
children,
44+
}) => {
45+
// scroll to the top of the screen when this comp is mounted
46+
useEffect(() => window.scrollTo(0, 0), []);
47+
48+
const { Wrapper, BackLink, Title, Content } = Styled;
49+
return (
50+
<Wrapper>
51+
{onBackClick && (
52+
<BackLink onClick={onBackClick} ghost borderless>
53+
<Close />
54+
</BackLink>
55+
)}
56+
<Container>
57+
<Row>
58+
<Column className="col-md-9 offset-md-1">
59+
<Title bold>{title}</Title>
60+
<Header muted space={32}>
61+
{description}
62+
</Header>
63+
<Content>{children}</Content>
64+
</Column>
65+
</Row>
66+
</Container>
67+
</Wrapper>
68+
);
69+
};
70+
71+
export default observer(OverlayFormWrap);

app/src/components/common/v2/Text.tsx

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
import styled from '@emotion/styled';
2+
3+
interface TextProps {
4+
bold?: boolean;
5+
semiBold?: boolean;
6+
center?: boolean;
7+
block?: boolean;
8+
muted?: boolean;
9+
space?: 4 | 8 | 12 | 16 | 20 | 24 | 32 | 40 | 48 | 56 | 64 | 96 | 120 | 160 | 200;
10+
desktopSpace?:
11+
| 4
12+
| 8
13+
| 12
14+
| 16
15+
| 20
16+
| 24
17+
| 32
18+
| 40
19+
| 48
20+
| 56
21+
| 64
22+
| 96
23+
| 120
24+
| 160
25+
| 200;
26+
}
27+
28+
const BaseText = styled.span<TextProps>`
29+
// On mobile, default to semi-bold when the bold prop is used
30+
font-family: ${props =>
31+
props.bold || props.semiBold
32+
? props.theme.fonts.open.semiBold
33+
: props.theme.fonts.open.regular};
34+
font-weight: ${props => (props.bold || props.semiBold ? 600 : 400)};
35+
${props => props.muted && `color: ${props.theme.colors.gray};`}
36+
${props => props.space && `margin-bottom: ${props.space}px;`}
37+
text-align: left;
38+
39+
@media (${props => props.theme.breakpoints.m}) {
40+
${props => props.desktopSpace && `margin-bottom: ${props.desktopSpace}px;`}
41+
42+
// On larger devices, make bold elements bold instead of semi-bold
43+
font-family: ${props =>
44+
props.bold
45+
? props.theme.fonts.open.bold
46+
: props.semiBold
47+
? props.theme.fonts.open.semiBold
48+
: props.theme.fonts.open.regular};
49+
50+
// The text-align property is ignored on mobile
51+
text-align: ${props => (props.center ? 'center' : 'left')};
52+
}
53+
`;
54+
55+
const BaseBlock = BaseText.withComponent('div');
56+
57+
export const Mega = styled(BaseBlock)`
58+
font-size: 40px;
59+
line-height: 48px;
60+
61+
@media (${props => props.theme.breakpoints.m}) {
62+
font-size: 56px;
63+
line-height: 56px;
64+
}
65+
`;
66+
67+
export const DisplayLarge = styled(BaseBlock)`
68+
font-size: 32px;
69+
line-height: 40px;
70+
71+
@media (${props => props.theme.breakpoints.m}) {
72+
font-size: 40px;
73+
line-height: 48px;
74+
}
75+
`;
76+
77+
export const Display = styled(BaseBlock)`
78+
font-size: 24px;
79+
line-height: 32px;
80+
81+
@media (${props => props.theme.breakpoints.m}) {
82+
font-size: 32px;
83+
line-height: 40px;
84+
}
85+
`;
86+
87+
export const DisplaySmall = styled(BaseBlock)`
88+
font-size: 20px;
89+
line-height: 24px;
90+
91+
@media (${props => props.theme.breakpoints.m}) {
92+
font-size: 24px;
93+
line-height: 32px;
94+
}
95+
`;
96+
97+
export const Title = styled(BaseBlock)`
98+
font-size: 18px;
99+
line-height: 24px;
100+
101+
@media (${props => props.theme.breakpoints.m}) {
102+
font-size: 20px;
103+
line-height: 24px;
104+
}
105+
`;
106+
107+
export const Header = styled(BaseBlock)`
108+
font-size: 16px;
109+
line-height: 24px;
110+
111+
@media (${props => props.theme.breakpoints.m}) {
112+
font-size: 18px;
113+
line-height: 24px;
114+
}
115+
`;
116+
117+
export const Paragraph = styled(BaseBlock)`
118+
font-size: 14px;
119+
line-height: 20px;
120+
121+
@media (${props => props.theme.breakpoints.m}) {
122+
font-size: 16px;
123+
line-height: 24px;
124+
}
125+
`;
126+
127+
export const Small = styled(BaseText)`
128+
display: ${props => (props.block ? 'block' : 'inline-block')};
129+
font-size: 14px;
130+
line-height: 20px;
131+
`;
132+
133+
export const Micro = styled(BaseText)`
134+
display: ${props => (props.block ? 'block' : 'inline-block')};
135+
font-size: 12px;
136+
line-height: 16px;
137+
`;
138+
139+
export const Label = styled(BaseText)`
140+
display: ${props => (props.block ? 'block' : 'inline-block')};
141+
font-size: 14px;
142+
line-height: 16px;
143+
text-transform: uppercase;
144+
`;
145+
146+
export const Muted = styled.span`
147+
color: ${props => props.theme.colors.gray};
148+
`;
149+
150+
export const Highlight = styled.span`
151+
color: ${props => props.theme.colors.white};
152+
`;

app/src/components/theme.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,15 @@ const theme: Theme = {
4545
lightBlue: '#384770',
4646
paleBlue: '#2E3A5C',
4747
lightningRed: '#EF4444',
48+
lightningGray: '#B9BDC5',
49+
lightningNavy: '#1D253A',
50+
iris: '#5D5FEF',
51+
},
52+
breakpoints: {
53+
s: 'min-width: 576px',
54+
m: 'min-width: 768px',
55+
l: 'min-width: 992px',
56+
xl: 'min-width: 1200px',
4857
},
4958
};
5059

app/src/emotion-theme.d.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,15 @@ declare module '@emotion/react' {
4141
lightBlue: string;
4242
paleBlue: string;
4343
lightningRed: string;
44+
lightningGray: string;
45+
lightningNavy: string;
46+
iris: string;
47+
};
48+
breakpoints: {
49+
s: string;
50+
m: string;
51+
l: string;
52+
xl: string;
4453
};
4554
}
4655
}

0 commit comments

Comments
 (0)