From 92128f437bbce112c4561093042fe5caf3ae66fe Mon Sep 17 00:00:00 2001 From: Mike Flood Date: Mon, 20 Mar 2023 16:31:30 +0000 Subject: [PATCH 1/5] docs(PPDSC-2704): update stories --- scripts/generate-icons/used-icons-list.json | 1 + src/form/__tests__/form-input.stories.tsx | 1176 +++++++++---------- 2 files changed, 534 insertions(+), 643 deletions(-) diff --git a/scripts/generate-icons/used-icons-list.json b/scripts/generate-icons/used-icons-list.json index 1b68014a29..80aae7dbc0 100644 --- a/scripts/generate-icons/used-icons-list.json +++ b/scripts/generate-icons/used-icons-list.json @@ -51,6 +51,7 @@ "PlayArrow", "Remove", "RemoveCircle", + "RemoveRedEye", "Search", "SkipNext", "SkipPrevious", diff --git a/src/form/__tests__/form-input.stories.tsx b/src/form/__tests__/form-input.stories.tsx index 70d42bfd41..604731ad4c 100644 --- a/src/form/__tests__/form-input.stories.tsx +++ b/src/form/__tests__/form-input.stories.tsx @@ -4,53 +4,36 @@ import { Form, FormInput, FormInputAssistiveText, + FormInputCharacterCount, + FormInputCheckbox, FormInputLabel, + FormInputRadioButton, FormInputSelect, + FormInputTextArea, FormInputTextField, - FormInputCheckbox, - FormInputRadioButton, } from '..'; import { Block, Button, + createTheme, + FieldsetProps, + FormInputTextFieldProps, + GridLayout, IconButton, - Stack, styled, + TextBlock, ThemeProvider, - CreateThemeArgs, - TextFieldSize, } from '../..'; import { - IconFilledAccountBalance, - IconFilledAccountTree, - IconFilledAddCircleOutline, + IconFilledAddCircle, + IconFilledRemoveRedEye, + IconFilledStop, } from '../../icons'; import {SelectOption} from '../../select'; -import { - StorybookHeading, - StorybookSubHeading, -} from '../../test/storybook-comps'; import {Fieldset} from '../../fieldset'; import {RadioGroup} from '../../radio-button'; import {createCustomThemeWithBaseThemeSwitch} from '../../test/theme-select-object'; -const formInputCustomThemeObject: CreateThemeArgs = { - name: 'my-custom-select-theme', - overrides: { - stylePresets: { - fieldsetWithBorder: { - base: { - borderColor: '{{colors.amber010}}', - borderWidth: '1px', - borderStyle: 'solid', - }, - }, - }, - }, -}; - -const FormInputBlock = styled(Block)``; - const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)); // eslint-disable-next-line @typescript-eslint/no-explicit-any const onSubmit = async (data: any) => { @@ -64,201 +47,212 @@ const validateUserName = async (value: string) => { return value !== 'newskit' || 'This username is already taken'; }; -export const StoryFormField = () => ( - <> - - FormInput with assistive text, label and before and after icon - - Valid State -
- ()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i, - message: 'Please provide a valid email', - }, - }} - > - E-mail - - - - } - /> - Assistive Text - +const sharedProps: Pick< + FormInputTextFieldProps, + 'size' | 'placeholder' | 'startEnhancer' | 'endEnhancer' +> = { + size: 'small', + placeholder: 'Placeholder', + startEnhancer: ( + <> + + + ), + endEnhancer: ( + <> + + + ), +}; - Invalid State +const usernameRule = { + required: 'Required field', + validate: validateUserName, +}; - - Username - - - - - - } - endEnhancer={ - <> - - - - - } - overrides={{ - startEnhancer: { - spaceInline: 'space020', - }, - endEnhancer: { - spaceInline: 'space040', - }, - }} - /> - Assistive Text - +const emailRule = { + required: 'Required field', + pattern: { + // eslint-disable-next-line no-useless-escape + value: /^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i, + message: 'Please provide a valid email', + }, +}; - ( + + {label && ( + - Default State - Surname - - } - endEnhancer={ - <> - - - - - } - overrides={{ - startEnhancer: { - spaceInline: 'space050', - }, - endEnhancer: { - spaceInline: 'space050', - }, - }} - /> - Assistive Text - + {label} + + )} + {children} + +); - - Disabled State - Password - - } - endEnhancer={} - /> - Assistive Text - +const FormInputAssistiveTextWithErrorIcon = () => ( + + + Assistive Text + +); + +const Container = styled.div` + max-width: 300px; +`; + +export const StoryFormInputTextField = () => ( + + + + + E-mail + + Assistive Text + + + + + Username + + Assistive Text + + + + + First name + + + + + + + Surname + + Assistive Text + + - + ); -StoryFormField.storyName = 'form-input-before-and-after-icon'; +StoryFormInputTextField.storyName = 'Form input text field'; -export const FormFieldWithIconButton = () => { - const [showPassword, setShowPassword] = React.useState(false); - return ( - <> - FormInput with Button enhancer - -
- - - Enter Password - - - - } - endEnhancer={ - setShowPassword(!showPassword)} - size="small" - > - {showPassword ? ( - - ) : ( - - )} - - } - overrides={{ - startEnhancer: { - spaceInline: 'space070', - }, - endEnhancer: { - spaceInline: 'space070', - }, - }} - /> - Assistive Text - - - -
-
- - ); -}; -FormFieldWithIconButton.storyName = 'form-input-with-icon-button'; +export const StoryFormInputTextArea = () => ( + +
+ + + E-mail + + Assistive Text + + + + + Username + + Assistive Text + + + + + First name + + + + + + + Surname + + Assistive Text + + + +
+
+); +StoryFormInputTextArea.storyName = 'Form input text area'; + +export const FormFieldWithIconButton = () => ( + +
+ + + E-mail + + + + } + /> + Assistive Text + + + +
+
+); +FormFieldWithIconButton.storyName = 'Form input with icon button'; export const FormInputWithSelect = () => ( - <> - FormInput with Select - - Standalone Select -
+ + + ( Select Item - + Option 1 Option 2 Assistive Text - - -
- - Select with enhancers -
+ + ( Select Item - - } - endEnhancer={ - - } - > + Option 1 Option 2 Assistive Text - - -
- + + + + ); -FormInputWithSelect.storyName = 'form-input-with-select'; - -const spaceStack = { - small: 'space020', - medium: 'space020', - large: 'space030', -}; +FormInputWithSelect.storyName = 'Form input select'; export const FormFieldCheckbox = () => (
- Single checkbox validation - - {['small', 'medium', 'large'].map(size => ( - - - + + + + Please agree with our terms & conditions + + + + + +); +FormFieldCheckbox.storyName = 'Form input checkbox'; + +export const FormFieldRadioButton = () => ( +
+ +
+ + + - - Please agree with our T&C - - - ))} - - - + + + + + + + + + Assistive Text + +
+
+
); -FormFieldCheckbox.storyName = 'form-input-checkbox'; -export const FormFieldRadioButton = () => { - const rules = { - required: 'Required field', - }; +FormFieldRadioButton.storyName = 'Form input radio button'; +export const StoryFormFieldset = () => { + const sizes: NonNullable[] = [ + 'small', + 'medium', + 'large', + ]; return ( - -
- RadioButton and RadioGroup -
- - {['Reading', 'Writing', 'Speaking', 'Listening'].map(value => ( - - - - ))} - - - Assistive Text - -
- - - -
+ + {sizes.map(size => ( + +
+
+ + + Email + + + Assistive text + + + + + + Username + + + Assistive text + + + + +
+
+
+ ))} +
); }; +StoryFormFieldset.storyName = 'Form input fieldset'; -FormFieldRadioButton.storyName = 'form-input-radio-button'; - -export const StoryFormFieldset = () => ( - <> - FormInputs inside Fieldset - +export const StoryFormInputCharacterCount = () => ( +
- -
+ - - - - First name - - - } - overrides={{spaceStack: 'space000'}} - /> - - - - - - Last name - - - } - overrides={{spaceStack: 'space020'}} - /> - - This should be your legal last name - - - - - - - - - - - -
- -
E-mail + + + + + + + Username + + + + + + + First name + + + + + + - + Surname + + + + + + + +); +StoryFormInputCharacterCount.storyName = 'Form input character count'; + +const FormContainer = styled.div` + height: 700px; + overflow: auto; + max-width: 500px; + padding: 20px; + margin: 0 auto; + border: 1px solid #ccc; + border-radius: 5px; +`; + +const ShowPasswordButton = ({ + onClick, + isVisible, +}: { + onClick: () => void; + isVisible: boolean; +}) => ( + + {isVisible ? ( + + ) : ( + + )} + +); + +const formExampleTheme = createTheme({ + name: 'my-form-theme', + overrides: { + componentDefaults: { + label: { + medium: { + spaceStack: 'space020', + }, + }, + textField: { + medium: { + spaceStack: 'space030', + }, + }, + radioButton: { + medium: { + spaceStack: 'space030', + }, + }, + checkbox: { + medium: { + spaceStack: 'space030', + }, + }, + assistiveText: { + medium: { + spaceStack: 'space060', + }, + }, + // Why we cant change this ? + fieldset: { + spaceStack: 'space040', + }, + legend: { + medium: { + typographyPreset: 'utilityLabel030', + spaceStack: 'space050', + }, + }, + }, + }, +}); + +export const StoryFormComplete = () => { + const [showPassword, toggleShowPassword] = React.useState(false); + return ( + + +
+
( value: 2, message: 'Name must be at least 2 characters long', }, - validate: validateUserName, }} > - - First name - - - } - overrides={{spaceStack: 'space000'}} - /> + First name + + + Enter your first name + - - - - Last name - - - } - overrides={{spaceStack: 'space020'}} - /> + Last name + - This should be your legal last name + Enter your last name - - - - - - - - -
- -
- - - - First name - - - } - overrides={{ - spaceStack: 'space000', - }} - /> - - - - - - Last name - - - } - overrides={{ - spaceStack: 'space020', - }} - /> + Country + + Bulgaria + United Kingdom + The Netherlands + Germany + - This should be your legal last name + Enter your last name - +
- +
- + Email + + Enter your email - - - - -
-
- - - First name - + Password - } - overrides={{spaceStack: 'space000'}} - /> - - - - - - Last name - - toggleShowPassword(!showPassword)} + isVisible={showPassword} /> } - overrides={{spaceStack: 'space020'}} /> - This should be your legal last name + Enter your password - - +
+ +
- + + + + + + + Make your choice +
+ +
{ + if (value.length < 3) { + return 'Select at least 3 interests'; + } + + return true; + }, }} > - + + + + + + + Make your choice - -
- - - -); -StoryFormFieldset.storyName = 'form-input-fieldset'; +
+ + + + + + ); +}; +StoryFormComplete.storyName = 'Form complete'; export default { - title: 'Components/form-input', + title: 'Components/Form input', component: () => 'None', disabledRules: [], decorators: [ @@ -817,7 +707,7 @@ export default { From ac230c5ef304b2a42d4e83750bfa4a302b661afb Mon Sep 17 00:00:00 2001 From: Mike Flood Date: Tue, 21 Mar 2023 14:48:38 +0000 Subject: [PATCH 2/5] docs(PPDSC-2704): design feedback --- .storybook/preview.js | 1 + src/form/__tests__/form-input.stories.tsx | 10 +++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.storybook/preview.js b/.storybook/preview.js index 58f73e43c0..b525de3632 100644 --- a/.storybook/preview.js +++ b/.storybook/preview.js @@ -23,6 +23,7 @@ const unlimitedScenarios = [ 'Stack', 'card', 'drawer', + 'Form input', 'modal', 'Image', 'image-e2e', diff --git a/src/form/__tests__/form-input.stories.tsx b/src/form/__tests__/form-input.stories.tsx index 604731ad4c..81850f0a37 100644 --- a/src/form/__tests__/form-input.stories.tsx +++ b/src/form/__tests__/form-input.stories.tsx @@ -282,7 +282,11 @@ export const FormInputWithSelect = () => ( Select Item
- + Option 1 Option 2 @@ -368,10 +372,10 @@ export const StoryFormFieldset = () => { 'large', ]; return ( - + {sizes.map(size => ( -
+
Date: Tue, 21 Mar 2023 16:57:39 +0000 Subject: [PATCH 3/5] docs(PPDSC-2704): a11y issues --- src/form/__tests__/form-input.stories.tsx | 158 ++++++++++++---------- 1 file changed, 88 insertions(+), 70 deletions(-) diff --git a/src/form/__tests__/form-input.stories.tsx b/src/form/__tests__/form-input.stories.tsx index 81850f0a37..881b2e6be4 100644 --- a/src/form/__tests__/form-input.stories.tsx +++ b/src/form/__tests__/form-input.stories.tsx @@ -15,7 +15,6 @@ import { import { Block, Button, - createTheme, FieldsetProps, FormInputTextFieldProps, GridLayout, @@ -471,7 +470,7 @@ export const StoryFormInputCharacterCount = () => ( > Surname - + @@ -511,56 +510,13 @@ const ShowPasswordButton = ({ ); -const formExampleTheme = createTheme({ - name: 'my-form-theme', - overrides: { - componentDefaults: { - label: { - medium: { - spaceStack: 'space020', - }, - }, - textField: { - medium: { - spaceStack: 'space030', - }, - }, - radioButton: { - medium: { - spaceStack: 'space030', - }, - }, - checkbox: { - medium: { - spaceStack: 'space030', - }, - }, - assistiveText: { - medium: { - spaceStack: 'space060', - }, - }, - // Why we cant change this ? - fieldset: { - spaceStack: 'space040', - }, - legend: { - medium: { - typographyPreset: 'utilityLabel030', - spaceStack: 'space050', - }, - }, - }, - }, -}); - export const StoryFormComplete = () => { const [showPassword, toggleShowPassword] = React.useState(false); return ( - - - -
+ + +
+ { Enter your first name + + { Enter your last name + + { Enter your last name -
+ +
-
+
+ { Enter your email + + { Enter your password -
+ +
-
+
+ { }} > - - - - + + + + Make your choice -
+ +
-
+
+ { }, }} > - - - - - - + + + + + + Make your choice -
+ +
- - -
-
+ + + ); }; StoryFormComplete.storyName = 'Form complete'; From 9ec58133f173c57694e0856460ab2c1ce9ef33fd Mon Sep 17 00:00:00 2001 From: Mike Flood Date: Wed, 22 Mar 2023 11:41:05 +0000 Subject: [PATCH 4/5] docs(PPDSC-2704): lowercase ids --- src/form/__tests__/form-input.stories.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/form/__tests__/form-input.stories.tsx b/src/form/__tests__/form-input.stories.tsx index 881b2e6be4..9083cbbb1f 100644 --- a/src/form/__tests__/form-input.stories.tsx +++ b/src/form/__tests__/form-input.stories.tsx @@ -646,7 +646,7 @@ export const StoryFormComplete = () => { overrides={{marginBlockEnd: 'space020'}} /> { overrides={{marginBlockEnd: 'space020'}} /> Date: Thu, 23 Mar 2023 11:24:15 +0000 Subject: [PATCH 5/5] docs(PPDSC-2704): meta --- src/form/__tests__/form-input.stories.tsx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/form/__tests__/form-input.stories.tsx b/src/form/__tests__/form-input.stories.tsx index 9083cbbb1f..7bdabb014d 100644 --- a/src/form/__tests__/form-input.stories.tsx +++ b/src/form/__tests__/form-input.stories.tsx @@ -736,4 +736,12 @@ export default { ), ], + parameters: { + nkDocs: { + title: 'Form input', + url: 'https://newskit.co.uk/components/form', + description: + 'The form component allows users to enter and edit information into a UI using form controls. Based on React Hook Form.', + }, + }, };