Skip to content

Commit

Permalink
feat(form): add verification field (#4360)
Browse files Browse the repository at this point in the history
* feat(form): add verification field

* fix: import and unit tests
  • Loading branch information
matthprost authored Oct 22, 2024
1 parent 8e77c03 commit ff15811
Show file tree
Hide file tree
Showing 10 changed files with 424 additions and 15 deletions.
5 changes: 5 additions & 0 deletions .changeset/red-buttons-eat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@ultraviolet/form": minor
---

Add `<VerificationCodeField />`
30 changes: 15 additions & 15 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
* @matthprost @lisalupi
/packages/form @johnrazeur
**/package.json @scaleway/front-kernel
Dockerfile @scaleway/front-kernel
babel.config.json @scaleway/front-kernel
tsconfig.json @scaleway/front-kernel
vite.config.ts @scaleway/front-kernel
turbo.json @scaleway/front-kernel
biome.json @scaleway/front-kernel
eslint.config.mjs @scaleway/front-kernel
pnpm-workspace.yaml @scaleway/front-kernel
svgo.config.cjs @scaleway/front-kernel
.github @scaleway/front-kernel
.changeset @scaleway/front-kernel
.aws @scaleway/front-kernel
* @matthprost @lisalupi
/packages/form @johnrazeur
**/package.json @scaleway/front-kernel
Dockerfile @scaleway/front-kernel
babel.config.json @scaleway/front-kernel
tsconfig.json @scaleway/front-kernel
vite.config.ts @scaleway/front-kernel
turbo.json @scaleway/front-kernel
biome.json @scaleway/front-kernel
eslint.config.mjs @scaleway/front-kernel
pnpm-workspace.yaml @scaleway/front-kernel
svgo.config.cjs @scaleway/front-kernel
.github @scaleway/front-kernel
.changeset/config.json @scaleway/front-kernel
.aws @scaleway/front-kernel
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Template } from './Template.stories'

export const Playground = Template.bind({})

Playground.args = Template.args
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { StoryFn } from '@storybook/react'
import { Stack } from '@ultraviolet/ui'
import type { ComponentProps } from 'react'
import { VerificationCodeField } from '..'
import { Submit } from '../../Submit'
import { Template } from './Template.stories'

export const Required: StoryFn<
ComponentProps<typeof VerificationCodeField>
> = args => (
<Stack gap={1} width="fit-content">
<VerificationCodeField {...args} />
<Submit>Submit</Submit>
</Stack>
)

Required.args = { ...Template.args, required: true }
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import type { StoryFn } from '@storybook/react'
import { Stack } from '@ultraviolet/ui'
import type { ComponentProps } from 'react'
import { VerificationCodeField } from '..'
import { Submit } from '../..'

export const Template: StoryFn<
ComponentProps<typeof VerificationCodeField>
> = args => (
<Stack gap="1" width="fit-content">
<VerificationCodeField {...args} />
<Submit>Submit</Submit>
</Stack>
)

Template.args = { name: 'verification' }
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import type { Meta } from '@storybook/react'
import { Snippet, Stack, Text } from '@ultraviolet/ui'
import { Form, VerificationCodeField } from '../..'
import { useForm } from '../../..'
import { mockErrors } from '../../../mocks'

export default {
component: VerificationCodeField,
decorators: [
ChildStory => {
const methods = useForm()
const {
errors,
isDirty,
isSubmitting,
touchedFields,
submitCount,
dirtyFields,
isValid,
isLoading,
isSubmitted,
isValidating,
isSubmitSuccessful,
} = methods.formState

return (
<Form onSubmit={() => {}} errors={mockErrors} methods={methods}>
<Stack gap={2}>
<ChildStory />
<Stack gap={1}>
<Text variant="bodyStrong" as="p">
Form input values:
</Text>
<Snippet prefix="lines" initiallyExpanded>
{JSON.stringify(methods.watch(), null, 1)}
</Snippet>
</Stack>
<Stack gap={1}>
<Text variant="bodyStrong" as="p">
Form values:
</Text>
<Snippet prefix="lines">
{JSON.stringify(
{
errors,
isDirty,
isSubmitting,
touchedFields,
submitCount,
dirtyFields,
isValid,
isLoading,
isSubmitted,
isValidating,
isSubmitSuccessful,
},
null,
1,
)}
</Snippet>
</Stack>
</Stack>
</Form>
)
},
],
title: 'Form/Components/Fields/VerificationCodeField',
} as Meta

export { Playground } from './Playground.stories'
export { Required } from './Required.stories'
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`VerificationCodeField > should render correctly 1`] = `
<DocumentFragment>
.emotion-0 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
gap: 8px;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: center;
-ms-flex-pack: center;
-webkit-justify-content: center;
justify-content: center;
-webkit-box-flex-wrap: nowrap;
-webkit-flex-wrap: nowrap;
-ms-flex-wrap: nowrap;
flex-wrap: nowrap;
}
.emotion-2 {
font-size: 16px;
font-family: Inter,Asap,sans-serif;
font-weight: 400;
letter-spacing: 0;
line-height: 24px;
text-transform: none;
-webkit-text-decoration: none;
text-decoration: none;
}
.emotion-4 {
background: #ffffff;
border: solid 1px #d9dadd;
color: #3f4250;
font-size: 16px;
font-weight: 400;
text-align: center;
border-radius: 4px;
margin-right: 8px;
width: 40px;
height: 48px;
outline-style: none;
-webkit-transition: border-color 0.2s ease,box-shadow 0.2s ease;
transition: border-color 0.2s ease,box-shadow 0.2s ease;
}
.emotion-4:hover,
.emotion-4:focus {
border-color: #792dd4;
}
.emotion-4:focus {
box-shadow: 0px 0px 0px 3px #8c40ef40;
}
.emotion-4:last-child {
margin-right: 0;
}
.emotion-4::-webkit-input-placeholder {
color: #727683;
}
.emotion-4::-moz-placeholder {
color: #727683;
}
.emotion-4:-ms-input-placeholder {
color: #727683;
}
.emotion-4::placeholder {
color: #727683;
}
<div
data-testid="testing"
>
<form
novalidate=""
>
<div
aria-label="verification-code-field"
class="emotion-0 emotion-1"
>
<label
for="verification-code-input-0"
id="verification-code-input-label"
style="cursor: pointer; flex-shrink: 0;"
>
<p
class="emotion-2 emotion-3"
>
Code
</p>
</label>
<div>
<input
aria-invalid="false"
aria-label="Verification code 0"
class="emotion-4 emotion-5"
data-testid="0"
id="verification-code-input-0"
pattern="[0-9]*"
placeholder="0"
required=""
type="tel"
value=""
/>
<input
aria-invalid="false"
aria-label="Verification code 1"
class="emotion-4 emotion-5"
data-testid="1"
id="verification-code-input-1"
pattern="[0-9]*"
placeholder=""
required=""
type="tel"
value=""
/>
<input
aria-invalid="false"
aria-label="Verification code 2"
class="emotion-4 emotion-5"
data-testid="2"
id="verification-code-input-2"
pattern="[0-9]*"
placeholder=""
required=""
type="tel"
value=""
/>
<input
aria-invalid="false"
aria-label="Verification code 3"
class="emotion-4 emotion-5"
data-testid="3"
id="verification-code-input-3"
pattern="[0-9]*"
placeholder=""
required=""
type="tel"
value=""
/>
</div>
</div>
</form>
</div>
</DocumentFragment>
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { renderWithForm } from '@utils/test'
import { describe, expect, test } from 'vitest'
import { VerificationCodeField } from '..'

describe('VerificationCodeField', () => {
test('should render correctly', () => {
const { asFragment } = renderWithForm(
<VerificationCodeField
name="code"
label="Code"
placeholder="0"
required
/>,
)
expect(asFragment()).toMatchSnapshot()
})
})
Loading

0 comments on commit ff15811

Please sign in to comment.