Skip to content

Commit ace7713

Browse files
committed
feat: Add form components
Also add MDX stories
1 parent 8a8c423 commit ace7713

File tree

16 files changed

+1135
-67
lines changed

16 files changed

+1135
-67
lines changed

.github/workflows/ci.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@ jobs:
3232
name: Install dependencies
3333
- run: yarn ci
3434
name: Run integration tests
35-
- uses: coverallsapp/github-action@832e70b
36-
name: Report code coverage
37-
with:
38-
github-token: ${{ secrets.GITHUB_TOKEN }}
35+
# - uses: coverallsapp/github-action@832e70b
36+
# name: Report code coverage
37+
# with:
38+
# github-token: ${{ secrets.GITHUB_TOKEN }}
3939
- uses: 8398a7/action-slack@78391c2
4040
name: Notify on Slack
4141
if: always() # Pick up events even if the job fails or is canceled.

next.config.js

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1-
const withTM = require('next-transpile-modules')(['@47ng/chakra-next'])
1+
const withPlugins = require('next-compose-plugins')
2+
const withTranspilation = require('next-transpile-modules')([
3+
'@47ng/chakra-next'
4+
])
5+
const withMDX = require('@next/mdx')({
6+
extension: /\.mdx?$/
7+
})
28

3-
module.exports = withTM()
9+
const nextConfig = {
10+
pageExtensions: ['tsx', 'mdx'],
11+
experimental: {
12+
reactRefresh: true
13+
}
14+
}
15+
16+
module.exports = withPlugins([withTranspilation, withMDX], nextConfig)

package.json

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,32 +33,36 @@
3333
"ci": "run-s build test"
3434
},
3535
"dependencies": {
36-
"@47ng/chakra-next": "^2.1.2",
37-
"@chiffre/analytics-processing": "^1.0.0",
36+
"@47ng/chakra-next": "^2.2.0",
37+
"@chiffre/analytics-processing": "^1.0.1",
3838
"@nivo/pie": "^0.61.1"
3939
},
4040
"devDependencies": {
4141
"@chakra-ui/core": "^0.7.0",
4242
"@commitlint/config-conventional": "^8.3.4",
4343
"@emotion/core": "^10.0.28",
4444
"@emotion/styled": "^10.0.27",
45+
"@mdx-js/loader": "^1.6.0",
46+
"@next/mdx": "^9.3.6",
4547
"@testing-library/jest-dom": "^5.5.0",
46-
"@testing-library/react": "^10.0.2",
48+
"@testing-library/react": "^10.0.3",
4749
"@types/jest": "^25.2.1",
48-
"@types/node": "^13.11.1",
50+
"@types/node": "^13.13.4",
4951
"@types/styled-system__css": "^5.0.8",
5052
"commitlint": "^8.3.5",
5153
"emotion-theming": "^10.0.27",
54+
"formik": "^2.1.4",
5255
"husky": "^4.2.5",
53-
"jest": "^25.3.0",
54-
"next": "^9.3.5",
55-
"next-transpile-modules": "^3.2.0",
56+
"jest": "^25.5.2",
57+
"next": "^9.3.6",
58+
"next-compose-plugins": "^2.2.0",
59+
"next-transpile-modules": "^3.3.0",
5660
"npm-run-all": "^4.1.5",
57-
"prettier": "^2.0.4",
61+
"prettier": "^2.0.5",
5862
"react": "^16.13.1",
5963
"react-dom": "^16.13.1",
60-
"ts-jest": "^25.3.1",
61-
"ts-node": "^8.8.2",
64+
"ts-jest": "^25.4.0",
65+
"ts-node": "^8.9.1",
6266
"typescript": "^3.8.3"
6367
},
6468
"jest": {
@@ -127,7 +131,8 @@
127131
"@emotion/core": "^10.0.28",
128132
"@emotion/styled": "^10.0.27",
129133
"emotion-theming": "^10.0.27",
130-
"next": "^9.3.5",
134+
"formik": "^2.1.4",
135+
"next": "^9.3.6",
131136
"react": "^16.13.1",
132137
"react-dom": "^16.13.1"
133138
}

pages/index.mdx

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import { NextPage } from 'next'
2+
import Head from 'next/head'
3+
import { Divider, Box, Stack } from '@chakra-ui/core'
4+
import { Card, StackContainer } from '@47ng/chakra-next'
5+
import {
6+
AnimatedLogo,
7+
Logo,
8+
EmailField,
9+
ErrorText,
10+
FieldHelpText,
11+
LabelWithAside,
12+
InputField,
13+
Label,
14+
PasswordField,
15+
TwoFactorTokenField
16+
} from '../src/index'
17+
import { Formik, Form, ErrorMessage } from 'formik'
18+
19+
export default ({ children, ...props }) => (
20+
<>
21+
<Head>
22+
<title>Chiffre.io - Design System</title>
23+
</Head>
24+
<StackContainer my={8} wide {...props}>
25+
{children}
26+
</StackContainer>
27+
</>
28+
)
29+
30+
<!----------------------------------------------------------------------------->
31+
32+
## Logos
33+
34+
Normal:
35+
36+
<Logo h={8} />
37+
38+
Animated:
39+
40+
<AnimatedLogo h={8} speed={2} />
41+
42+
<Divider />
43+
44+
## Form Components
45+
46+
<Card>
47+
<Formik
48+
initialValues={{
49+
email: '',
50+
input: '',
51+
password: ''
52+
}}
53+
validate={() => {
54+
return {
55+
email: 'Email is invalid',
56+
input: 'Foo bar',
57+
password: 'Egg spam',
58+
error: 'blop'
59+
}
60+
}}
61+
>
62+
{() => (
63+
<Form>
64+
<Stack spacing={4}>
65+
<Box>
66+
<LabelWithAside
67+
htmlFor="email"
68+
aside={() => (
69+
<FieldHelpText id="email-help-text" fontSize="xs">
70+
You'll use your email address to log in
71+
</FieldHelpText>
72+
)}
73+
>
74+
Account
75+
</LabelWithAside>
76+
<EmailField name="email" />
77+
</Box>
78+
<Box>
79+
<LabelWithAside
80+
htmlFor="input"
81+
aside={() => (
82+
<FieldHelpText id="input-help-text" fontSize="xs">
83+
What shall we call you ?
84+
</FieldHelpText>
85+
)}
86+
>
87+
Display Name
88+
</LabelWithAside>
89+
<InputField
90+
name="input"
91+
aria-describedby="input-help-text"
92+
placeholder="enter your name"
93+
autoComplete="name"
94+
/>
95+
</Box>
96+
<Box>
97+
<PasswordField name="password" />
98+
</Box>
99+
</Stack>
100+
</Form>
101+
)}
102+
</Formik>
103+
</Card>

pages/index.tsx

Lines changed: 0 additions & 19 deletions
This file was deleted.

src/form/EmailField.tsx

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import React from 'react'
2+
import Input, { InputProps } from '@chakra-ui/core/dist/Input'
3+
import Icon from '@chakra-ui/core/dist/Icon'
4+
import InputGroup from '@chakra-ui/core/dist/InputGroup'
5+
import { InputLeftElement } from '@chakra-ui/core/dist/InputElement'
6+
import { ErrorMessage, useField, FieldMetaProps } from 'formik'
7+
import { ErrorText } from './ErrorText'
8+
import { formIconColors } from './formIconColors'
9+
10+
// --
11+
12+
const _getAtSignColor = (meta: FieldMetaProps<string>) => {
13+
if (!meta.touched) {
14+
if (meta.value.length === 0) {
15+
return formIconColors.gray.light
16+
}
17+
// There is some text
18+
if (!meta.error) {
19+
return formIconColors.green.light
20+
}
21+
// But it's not valid yet
22+
return formIconColors.gray.light
23+
}
24+
if (meta.error || meta.value.length === 0) {
25+
return formIconColors.red.light
26+
}
27+
return formIconColors.green.light
28+
}
29+
30+
// --
31+
32+
export interface EmailFieldProps extends InputProps {
33+
colorValidation?: boolean
34+
name?: string
35+
getAtSignColor?: (meta: FieldMetaProps<string>) => string
36+
}
37+
38+
export const EmailField: React.FC<EmailFieldProps> = ({
39+
colorValidation = false,
40+
name = 'email',
41+
getAtSignColor = _getAtSignColor,
42+
w,
43+
...props
44+
}) => {
45+
const [{ onBlur: _, ...field }, meta] = useField(name)
46+
const atSignColor = colorValidation
47+
? getAtSignColor(meta)
48+
: formIconColors.gray.light
49+
50+
return (
51+
<>
52+
<InputGroup w={w}>
53+
<InputLeftElement
54+
children={<Icon name="at-sign" color={atSignColor} />}
55+
/>
56+
<Input
57+
id={name}
58+
name={name}
59+
type="email"
60+
placeholder="email address"
61+
mb={1}
62+
{...field}
63+
{...props}
64+
/>
65+
</InputGroup>
66+
<ErrorMessage name={name} component={ErrorText} />
67+
</>
68+
)
69+
}

src/form/ErrorText.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import React from 'react'
2+
import Text from '@chakra-ui/core/dist/Text'
3+
import { BoxProps } from '@chakra-ui/core/dist/Box'
4+
5+
export interface ErrorTextProps extends BoxProps {
6+
bold?: boolean
7+
}
8+
9+
export const ErrorText: React.FC<ErrorTextProps> = ({
10+
bold = false,
11+
...props
12+
}) => {
13+
return (
14+
<Text
15+
fontSize="xs"
16+
fontWeight={bold ? 'semibold' : 'normal'}
17+
color="red.600"
18+
mb={2}
19+
{...props}
20+
/>
21+
)
22+
}

src/form/FieldHelpText.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import React from 'react'
2+
import FormHelperText from '@chakra-ui/core/dist/FormHelperText'
3+
import { BoxProps } from '@chakra-ui/core/dist/Box'
4+
5+
export const FieldHelpText: React.FC<BoxProps> = ({ ...props }) => {
6+
return (
7+
<FormHelperText fontSize="sm" color="gray.600" m="0" mb={2} {...props} />
8+
)
9+
}

src/form/InputField.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import React from 'react'
2+
import Input, { InputProps } from '@chakra-ui/core/dist/Input'
3+
import { ErrorMessage, useField } from 'formik'
4+
import { ErrorText } from './ErrorText'
5+
6+
export interface InputFieldProps extends InputProps {
7+
name: string
8+
}
9+
10+
export const InputField: React.FC<InputFieldProps> = ({ name, ...props }) => {
11+
const [{ onBlur: _, ...field }] = useField(name)
12+
return (
13+
<>
14+
<Input id={name} name={name} type="text" mb={1} {...field} {...props} />
15+
<ErrorMessage name={name} component={ErrorText} />
16+
</>
17+
)
18+
}

src/form/Label.tsx

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import React from 'react'
2+
import FormLabel from '@chakra-ui/core/dist/FormLabel'
3+
import Flex, { FlexProps } from '@chakra-ui/core/dist/Flex'
4+
import Text from '@chakra-ui/core/dist/Text'
5+
import { BoxProps } from '@chakra-ui/core/dist/Box'
6+
import { FormLabelProps } from '@chakra-ui/core/dist/FormLabel'
7+
8+
const LabelAside: React.FC<BoxProps> = ({ children, ...props }) => (
9+
<Text
10+
as="aside"
11+
display="block"
12+
fontSize="xs"
13+
fontWeight="normal"
14+
color="gray.600"
15+
{...props}
16+
>
17+
{children}
18+
</Text>
19+
)
20+
21+
export interface LabelWithAsideProps extends FlexProps {
22+
htmlFor: string
23+
aside: () => string | React.ReactElement
24+
asideLeft?: boolean
25+
}
26+
27+
export const LabelWithAside = React.forwardRef<any, LabelWithAsideProps>(
28+
({ children, aside, asideLeft = false, htmlFor, ...props }, ref) => (
29+
<Flex
30+
justifyContent={asideLeft ? 'flex-start' : 'space-between'}
31+
alignItems="baseline"
32+
ref={ref}
33+
{...props}
34+
>
35+
<Label htmlFor={htmlFor} mb={0}>
36+
{children}
37+
</Label>
38+
<LabelAside ml={asideLeft ? -1 : 0}>{aside()}</LabelAside>
39+
</Flex>
40+
)
41+
)
42+
43+
export const Label: React.FC<FormLabelProps> = ({ ...props }) => (
44+
<FormLabel
45+
as="label"
46+
fontWeight="semibold"
47+
display="inline-flex"
48+
{...props}
49+
/>
50+
)

0 commit comments

Comments
 (0)