Skip to content
This repository has been archived by the owner on Dec 27, 2022. It is now read-only.

Commit

Permalink
feat: new SubmitErrorAlert (#82)
Browse files Browse the repository at this point in the history
* feat: new SubmitErrorAlert

* fix: type

* fix: feedback

* fix: feedback
  • Loading branch information
chambo-e authored Feb 10, 2022
1 parent b91010e commit de535a4
Show file tree
Hide file tree
Showing 7 changed files with 288 additions and 9 deletions.
8 changes: 4 additions & 4 deletions src/components/Form/__tests__/index.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ describe('Form', () => {
test('renders correctly with validate', () =>
shouldMatchEmotionSnapshot(
<Form errors={mockErrors} validate={() => ({ test: 'test' })}>
{() => 'Test'}
Test
</Form>,
))

Expand All @@ -30,7 +30,7 @@ describe('Form', () => {
onSubmit={onSubmit}
onSubmitError={onSubmitError}
>
{() => <button type="submit">Submit</button>}
<button type="submit">Submit</button>
</Form>,
{
transform: async ({ getByText }) => {
Expand All @@ -55,7 +55,7 @@ describe('Form', () => {
onSubmit={onSubmit}
onSubmitError={onSubmitError}
>
{() => <button type="submit">Submit</button>}
<button type="submit">Submit</button>
</Form>,
{
transform: async ({ getByText }) => {
Expand All @@ -80,7 +80,7 @@ describe('Form', () => {
onSubmit={onSubmit}
onSubmitError={onSubmitError}
>
{() => <button type="submit">Submit</button>}
<button type="submit">Submit</button>
</Form>,
{
transform: async ({ getByText }) => {
Expand Down
6 changes: 3 additions & 3 deletions src/components/Submit/__stories__/index.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ export default {
title: 'Components/Submit',
} as Meta

export const Default: Story<ComponentProps<typeof Submit>> = ({ children }) => (
<Form errors={mockErrors}>{() => <Submit>{children}</Submit>}</Form>
export const Default: Story<ComponentProps<typeof Submit>> = ({ children, ...props }) => (
<Form errors={mockErrors}><Submit {...props}>{children}</Submit></Form>
)

Default.args = {
Expand All @@ -26,7 +26,7 @@ Default.args = {

export const Invalid: Story<ComponentProps<typeof Submit>> = ({ children }) => (
<Form errors={mockErrors} validate={() => ({ fake: 'error' })}>
{() => <Submit>{children}</Submit>}
<Submit>{children}</Submit>
</Form>
)

Expand Down
4 changes: 2 additions & 2 deletions src/components/Submit/__tests__/index.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ describe('Submit', () => {
test('form is invalid', () =>
shouldMatchEmotionSnapshot(
<Form validate={() => ({ test: 'test' })} errors={mockErrors}>
{() => <Submit>Test</Submit>}
<Submit>Test</Submit>
</Form>,
))

Expand All @@ -30,7 +30,7 @@ describe('Submit', () => {
}
errors={mockErrors}
>
{() => <Submit>Test</Submit>}
<Submit>Test</Submit>
</Form>,
{
transform: ({ getByText }) => {
Expand Down
30 changes: 30 additions & 0 deletions src/components/SubmitErrorAlert/__stories__/index.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import styled from '@emotion/styled'
import { Meta, Story } from '@storybook/react'
import { FORM_ERROR } from 'final-form'
import React, { ComponentProps } from 'react'
import SubmitErrorAlert from '..'
import mockErrors from '../../../mocks/mockErrors'
import Form from '../../Form'
import Submit from '../../Submit'

export default {
component: SubmitErrorAlert,
title: 'Components/SubmitErrorAlert',
} as Meta

const Container = styled.div`
display: flex;
flex-direction: column;
gap: 8px;
`

export const Default: Story<ComponentProps<typeof SubmitErrorAlert>> = ({
className,
}) => (
<Form errors={mockErrors} onSubmit={() => ({ [FORM_ERROR]: 'Not Good' })}>
<Container>
<SubmitErrorAlert className={className} />
<Submit>Click Me</Submit>
</Container>
</Form>
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`SubmitErrorAlert should display an alert when submitError is present 1`] = `
<DocumentFragment>
.cache-1czz0m3-StyledButton {
display: -webkit-inline-box;
display: -webkit-inline-flex;
display: -ms-inline-flexbox;
display: inline-flex;
border-radius: 4px;
border-width: 0;
cursor: pointer;
-webkit-box-pack: center;
-ms-flex-pack: center;
-webkit-justify-content: center;
justify-content: center;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
text-align: center;
-webkit-text-decoration: none;
text-decoration: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
outline: none;
vertical-align: middle;
white-space: nowrap;
font-weight: 500;
-webkit-transition: color 150ms ease-in-out,background-color 150ms ease-in-out,border-color 150ms ease-in-out;
transition: color 150ms ease-in-out,background-color 150ms ease-in-out,border-color 150ms ease-in-out;
background-color: #45d6b5;
color: #fff;
font-size: 16px;
line-height: 32px;
font-weight: 500;
padding: 8px 16px;
cursor: default;
pointer-events: none;
color: #d4dae7;
background-color: #fafafb;
border-color: #fafafb;
box-shadow: none;
}
.cache-1czz0m3-StyledButton:hover,
.cache-1czz0m3-StyledButton:focus {
-webkit-text-decoration: none;
text-decoration: none;
}
.cache-1czz0m3-StyledButton:hover,
.cache-1czz0m3-StyledButton:focus {
color: #fff;
background-color: #30d1ad;
}
.cache-1czz0m3-StyledButton:focus {
box-shadow: 0 0 0 2px rgba(69,214,181,0.25);
}
.cache-m245rk-StyledContent {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-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;
pointer-events: none;
}
.cache-18hq5l0-StyledContainer-alertStyles {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
border-radius: 4px;
padding: 12px;
background-color: #ffe1e7;
color: #ef5774;
}
.cache-zpmnud-StyledIcon-sizeStyles-StyledIcon {
fill: currentColor;
height: 32px;
width: 32px;
min-width: 32px;
min-height: 32px;
margin-right: 16px;
}
.cache-zpmnud-StyledIcon-sizeStyles-StyledIcon.cache-zpmnud-StyledIcon-sizeStyles-StyledIcon {
vertical-align: middle;
}
.cache-db05j6-AlertContainer {
color: inherit;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
-webkit-flex: 1;
-ms-flex: 1;
flex: 1;
}
.cache-1vtfjnf-StyledText-styles-variantStyles-colorStyles {
color: #4a4f62;
font-weight: 400;
margin-bottom: 0;
margin-top: 0;
color: #4a4f62;
font-size: 16px;
line-height: 24px;
color: inherit;
}
<form
novalidate=""
>
<button
aria-disabled="true"
class="em6gco80 cache-1czz0m3-StyledButton"
disabled=""
type="submit"
>
<div
class="cache-m245rk-StyledContent em6gco81"
>
Submit
</div>
</button>
<div
class="eenhiht2 cache-18hq5l0-StyledContainer-alertStyles"
>
<svg
aria-hidden="true"
class="eenhiht1 etwatq50 cache-zpmnud-StyledIcon-sizeStyles-StyledIcon"
viewBox="0 0 24 24"
>
<path
d="M13,14H11V10H13M13,18H11V16H13M1,21H23L12,2L1,21Z"
/>
</svg>
<div
class="cache-db05j6-AlertContainer eenhiht0"
>
<p
class="e1g1zfwd0 cache-1vtfjnf-StyledText-styles-variantStyles-colorStyles"
>
hello
</p>
</div>
</div>
,
</form>
</DocumentFragment>
`;

exports[`SubmitErrorAlert should render nothing if no error 1`] = `
<DocumentFragment>
<form
novalidate=""
/>
</DocumentFragment>
`;
48 changes: 48 additions & 0 deletions src/components/SubmitErrorAlert/__tests__/index.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { waitFor } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { FORM_ERROR } from 'final-form'
import React from 'react'
import SubmitErrorAlert from '..'
import {
shouldMatchEmotionSnapshot,
shouldMatchEmotionSnapshotFormWrapper,
} from '../../../helpers/jestHelpers'
import mockErrors from '../../../mocks/mockErrors'
import Form from '../../Form'
import Submit from '../../Submit'

describe('SubmitErrorAlert', () => {
beforeAll(() => {
jest.spyOn(global.Math, 'random').mockReturnValue(0.4155913669444804)
})

afterAll(() => {
jest.spyOn(global.Math, 'random').mockRestore()
})

test('should render nothing if no error', () =>
shouldMatchEmotionSnapshotFormWrapper(
<SubmitErrorAlert />,
))

test('should display an alert when submitError is present', async () => {
const onSubmit = jest.fn(() => ({ [FORM_ERROR]: 'hello' }))
const onSubmitError = jest.fn(() => {})

await shouldMatchEmotionSnapshot(
<Form errors={mockErrors} onSubmit={onSubmit} onSubmitError={onSubmitError}>
<Submit>Submit</Submit>
<SubmitErrorAlert />,
</Form>,
{
transform: async ({ getByText }) => {
userEvent.click(
getByText('Submit').closest('button') as HTMLButtonElement,
)
await waitFor(() => expect(onSubmitError).toBeCalledTimes(1))
await waitFor(() => expect(getByText('hello')).toBeInTheDocument())
},
},
)
})
})
17 changes: 17 additions & 0 deletions src/components/SubmitErrorAlert/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Alert } from '@scaleway/ui'
import React from 'react'
import { FormSpy } from 'react-final-form'

const FormErrorAlert = <FormValues, >({ className }: { className?: string }) => (
<FormSpy<FormValues> subscription={{ submitError: true }}>
{({ submitError }) =>
submitError ? (
<Alert className={className} type="warning">
{submitError}
</Alert>
) : null
}
</FormSpy>
)

export default FormErrorAlert

0 comments on commit de535a4

Please sign in to comment.