From 0b534af6c5a530418f054f18c27feb85bd4c913a Mon Sep 17 00:00:00 2001 From: Lauri Lukkarinen Date: Fri, 19 May 2023 15:30:02 +0300 Subject: [PATCH 01/21] Added optionKeyField to dropdown - this allows users to use options with duplicate labels in dropdowns --- packages/react/package.json | 1 + .../components/dropdown/combobox/Combobox.tsx | 3 +++ .../src/components/dropdown/select/Select.tsx | 9 ++++++++ .../components/searchInput/SearchInput.tsx | 8 +++++++ .../internal/dropdownMenu/DropdownMenu.tsx | 8 ++++++- .../internal/selectedItems/SelectedItems.tsx | 8 ++++++- yarn.lock | 21 +++++++++++++++++++ 7 files changed, 56 insertions(+), 2 deletions(-) diff --git a/packages/react/package.json b/packages/react/package.json index bec2a41c86..73dfc13bf3 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -68,6 +68,7 @@ "@typescript-eslint/eslint-plugin": "5.10.2", "@wessberg/rollup-plugin-ts": "2.0.4", "babel-jest": "^26.0.1", + "babel-plugin-polyfill-corejs2": "^0.4.1", "babel-plugin-require-context-hook": "1.0.0", "chalk": "4.0.0", "eslint": "7.1.0", diff --git a/packages/react/src/components/dropdown/combobox/Combobox.tsx b/packages/react/src/components/dropdown/combobox/Combobox.tsx index a79e4bfed7..fbc5d4203d 100644 --- a/packages/react/src/components/dropdown/combobox/Combobox.tsx +++ b/packages/react/src/components/dropdown/combobox/Combobox.tsx @@ -97,6 +97,7 @@ export const Combobox = (props: ComboboxProps) => { label, onBlur = () => null, onFocus = () => null, + optionKeyField, optionLabelField = 'label', options = [], placeholder, @@ -517,6 +518,7 @@ export const Combobox = (props: ComboboxProps) => { toggleButtonRef.current.focus(); }} onRemove={removeSelectedItem} + optionKeyField={optionKeyField || optionLabelField} optionLabelField={optionLabelField} removeButtonAriaLabel={props.selectedItemRemoveButtonAriaLabel} selectedItems={selectedItems} @@ -622,6 +624,7 @@ export const Combobox = (props: ComboboxProps) => { menuStyles={styles} multiselect={props.multiselect} open={isOpen} + optionKeyField={optionKeyField || optionLabelField} optionLabelField={optionLabelField} options={getFilteredItems} selectedItem={selectedItem} diff --git a/packages/react/src/components/dropdown/select/Select.tsx b/packages/react/src/components/dropdown/select/Select.tsx index 4767329b42..cfca397485 100644 --- a/packages/react/src/components/dropdown/select/Select.tsx +++ b/packages/react/src/components/dropdown/select/Select.tsx @@ -140,6 +140,12 @@ export type CommonSelectProps = LabelType & { * Callback function fired when the component is focused */ onFocus?: () => void; + /** + * Sets the data item field that represents the item key. Key needs to be unique between items. + * E.g. an `optionKeyField` value of `'bar'` and a data item `{ foo: 'Label', bar: 'value' }`, would use `'value'` as the key in the menu for that specific item + * Uses value of `optionLabelField` by default. + */ + optionKeyField?: string; /** * Sets the data item field that represents the item label * E.g. an `optionLabelField` value of `'foo'` and a data item `{ foo: 'Label', bar: 'value' }`, would display `Label` in the menu for that specific item @@ -329,6 +335,7 @@ export const Select = (props: SelectProps) => { label, onBlur = () => null, onFocus = () => null, + optionKeyField, optionLabelField = 'label', options = [], placeholder, @@ -536,6 +543,7 @@ export const Select = (props: SelectProps) => { toggleButtonRef.current.focus(); }} onRemove={removeSelectedItem} + optionKeyField={optionKeyField || optionLabelField} optionLabelField={optionLabelField} removeButtonAriaLabel={props.selectedItemRemoveButtonAriaLabel} selectedItems={selectedItems} @@ -608,6 +616,7 @@ export const Select = (props: SelectProps) => { menuStyles={styles} multiselect={props.multiselect} open={isOpen} + optionKeyField={optionKeyField || optionLabelField} optionLabelField={optionLabelField} options={options} selectedItem={selectedItem} diff --git a/packages/react/src/components/searchInput/SearchInput.tsx b/packages/react/src/components/searchInput/SearchInput.tsx index d922ce054e..2aa1946044 100644 --- a/packages/react/src/components/searchInput/SearchInput.tsx +++ b/packages/react/src/components/searchInput/SearchInput.tsx @@ -77,6 +77,12 @@ export type SearchInputProps = { * Override or extend the styles applied to the component. */ style?: React.CSSProperties; + /** + * Field of the SuggestionItem that represents the item key. Key needs to be unique between item. + * E.g. an `suggestionKeyField` value of `'bar'` and a suggestion item `{ foo: 'Label', bar: 'value' }`, would use `'value'` as the key in the menu for that specific item. + * Uses value of `suggestionLabelField` by default. + */ + suggestionKeyField?: keyof SuggestionItem; /** * Field of the SuggestionItem that represents the item label. * E.g. an `suggestionLabelField` value of `'foo'` and a suggestion item `{ foo: 'Label', bar: 'value' }`, would display `'Label'` in the menu for that specific suggestion. @@ -107,6 +113,7 @@ export const SearchInput = ({ searchButtonAriaLabel = 'Search', hideSearchButton = false, style, + suggestionKeyField, suggestionLabelField, visibleSuggestions = 8, onChange, @@ -303,6 +310,7 @@ export const SearchInput = ({ highlightValue={highlightSuggestions && inputValue.length >= 3 && inputValue} menuStyles={styles} options={suggestions} + optionKeyField={`${String(suggestionKeyField || suggestionLabelField)}`} optionLabelField={`${String(suggestionLabelField)}`} menuProps={getMenuProps({ style: { maxHeight: DROPDOWN_MENU_ITEM_HEIGHT * visibleSuggestions }, diff --git a/packages/react/src/internal/dropdownMenu/DropdownMenu.tsx b/packages/react/src/internal/dropdownMenu/DropdownMenu.tsx index 357f0607c7..27c32ca321 100644 --- a/packages/react/src/internal/dropdownMenu/DropdownMenu.tsx +++ b/packages/react/src/internal/dropdownMenu/DropdownMenu.tsx @@ -105,6 +105,10 @@ type DropdownMenuProps = { * Menu open state */ open: boolean; + /** + * Data item field that represents the item key + */ + optionKeyField: string; /** * Data item field that represents the item label */ @@ -139,6 +143,7 @@ export const DropdownMenu = ({ multiselect, open, optionLabelField, + optionKeyField, options, selectedItem, selectedItems, @@ -163,6 +168,7 @@ export const DropdownMenu = ({ const item = options[index]; const optionLabel: string = item[optionLabelField]; + const optionKey = item[optionKeyField]; const selected: boolean = multiselect ? getIsInSelectedOptions(selectedItems, item) : isEqual(selectedItem, item); @@ -171,7 +177,7 @@ export const DropdownMenu = ({ return ( = { * Callback function fired when the when an item is removed */ onRemove: (selectedItem: OptionType) => void; + /** + * Sets the data item field that represents the item key + */ + optionKeyField: string; /** * Sets the data item field that represents the item label */ @@ -193,6 +197,7 @@ export const SelectedItems = ({ hideItems = false, onClear, onRemove, + optionKeyField, optionLabelField, removeButtonAriaLabel, selectedItems, @@ -242,12 +247,13 @@ export const SelectedItems = ({ )} > {selectedItems.map((_selectedItem, index) => { + const selectedItemKey = _selectedItem[optionKeyField]; const selectedItemLabel = _selectedItem[optionLabelField]; const tagId = uniqueId('hds-tag-'); return ( Date: Wed, 24 May 2023 10:24:44 +0200 Subject: [PATCH 02/21] fix FileInput validateAccept for files having an empty file.type --- packages/react/src/components/fileInput/FileInput.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/react/src/components/fileInput/FileInput.tsx b/packages/react/src/components/fileInput/FileInput.tsx index e1ad0cb47e..a4c94e1810 100644 --- a/packages/react/src/components/fileInput/FileInput.tsx +++ b/packages/react/src/components/fileInput/FileInput.tsx @@ -307,8 +307,10 @@ const validateAccept = (language: Language, accept: string) => (file: File): tru (acceptExtension) => acceptExtension.includes(fileType) || acceptExtension.includes(`${fileType.split('/')[0]}/*`), ); const hasMatchingFileExtension = !!acceptedExtensions.find((acceptExtension) => acceptExtension === extension); + return ( - (!!fileType && (isMatchingType || hasMatchingFileExtension)) || { + isMatchingType || + hasMatchingFileExtension || { type: ValidationErrorType.accept, text: getAcceptErrorMessage(language, file, accept), } From 60f7edebb5dd7a63306cee24769cf6dfca5e4f75 Mon Sep 17 00:00:00 2001 From: Tuomo Kivinen Date: Thu, 25 May 2023 09:14:34 +0200 Subject: [PATCH 03/21] remove fileType check altogether since it only relies on the file extension and the client --- packages/react/src/components/fileInput/FileInput.tsx | 5 ----- 1 file changed, 5 deletions(-) diff --git a/packages/react/src/components/fileInput/FileInput.tsx b/packages/react/src/components/fileInput/FileInput.tsx index a4c94e1810..5749016bf3 100644 --- a/packages/react/src/components/fileInput/FileInput.tsx +++ b/packages/react/src/components/fileInput/FileInput.tsx @@ -301,15 +301,10 @@ const getExtension = (path: string): string => { const validateAccept = (language: Language, accept: string) => (file: File): true | ValidationError => { const extension: string = getExtension(file.name); - const fileType: string = file.type; const acceptedExtensions = accept.split(',').map((str) => str.trim()); - const isMatchingType = !!acceptedExtensions.find( - (acceptExtension) => acceptExtension.includes(fileType) || acceptExtension.includes(`${fileType.split('/')[0]}/*`), - ); const hasMatchingFileExtension = !!acceptedExtensions.find((acceptExtension) => acceptExtension === extension); return ( - isMatchingType || hasMatchingFileExtension || { type: ValidationErrorType.accept, text: getAcceptErrorMessage(language, file, accept), From 4b47d1a94ec477dea8c4429a3b3060db1233a76d Mon Sep 17 00:00:00 2001 From: Tuomo Kivinen Date: Thu, 25 May 2023 09:29:11 +0200 Subject: [PATCH 04/21] fix fileInput site example --- site/src/docs/components/file-input/code.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/site/src/docs/components/file-input/code.mdx b/site/src/docs/components/file-input/code.mdx index 38dd105b33..919b505080 100644 --- a/site/src/docs/components/file-input/code.mdx +++ b/site/src/docs/components/file-input/code.mdx @@ -69,7 +69,7 @@ import { FileInput } from 'hds-react'; ```jsx import { FileInput } from 'hds-react'; -{() => { +() => { const [files, setFiles] = React.useState([ new File(['string content'], 'dummy.txt', { type: 'text/plain' }), new File(['string content with more text'], 'anotherDummy.txt', { type: 'text/plain' }), @@ -82,7 +82,7 @@ import { FileInput } from 'hds-react'; onChange={setFiles} defaultValue={files} /> -}} +} ``` From 3b120b57b8e206ee0c98bfd26e51c6a479792269 Mon Sep 17 00:00:00 2001 From: Tuomo Kivinen Date: Thu, 25 May 2023 09:38:58 +0200 Subject: [PATCH 05/21] update FileInput documentation about the accept-parameter. --- site/src/docs/components/file-input/index.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/site/src/docs/components/file-input/index.mdx b/site/src/docs/components/file-input/index.mdx index 6b40da4d3a..880831e013 100644 --- a/site/src/docs/components/file-input/index.mdx +++ b/site/src/docs/components/file-input/index.mdx @@ -47,6 +47,7 @@ export const FileInputExample = () => { - Dragging and dropping files can be allowed by using the `dragAndDrop` property. - The FileInput uses an info text element to inform the user about the status of the component. You can read more about the usage of the info text element in the HDS Form validation pattern documentation page. - The FileInput component resolves human-readable file size abbreviations based on a binary system. The file size texts are shown after the selected file name and in maxSize messages if maxSize validation is used. +- The accept parameter only checks and allows selecting the correct file types according to the file extension(s) and does not do any in-depth analysis. Any safety and/or other checks should be done on the receiving end if necessary. ### Variations From dc0df67b043d64282e1e173baecd625f215df1e2 Mon Sep 17 00:00:00 2001 From: Tuomo Kivinen Date: Thu, 25 May 2023 09:55:08 +0200 Subject: [PATCH 06/21] remove filetype property from documentation --- site/src/docs/components/file-input/code.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/src/docs/components/file-input/code.mdx b/site/src/docs/components/file-input/code.mdx index 919b505080..e74a7a8ee9 100644 --- a/site/src/docs/components/file-input/code.mdx +++ b/site/src/docs/components/file-input/code.mdx @@ -100,7 +100,7 @@ Also, note that this component is an input. All features supported by the HDS Te | Property | Description | Values | Default value | | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | ------------- | -| `accept` | A comma-separated list of unique file type specifiers describing file types to allow. If present, the filename extension or filetype property is validated against the list. | `string` | - | +| `accept` | A comma-separated list of unique file type specifiers describing file types to allow. If present, the filename extension is validated against the list. | `string` | - | | `buttonLabel` | The label for the file button. Overrides default text. The button is not visible for assistive technology. | `string` | - | | `defaultValue`| If set, pre-fill the file(s) selection | `File[]` | - | | `dragAndDrop` | If set to true, the input will show a drag and rop area. | `boolean` | false | From 5544163b17f281d8ac0506d9f3f60bfe1cba5919 Mon Sep 17 00:00:00 2001 From: Tuomo Kivinen Date: Thu, 25 May 2023 10:32:26 +0200 Subject: [PATCH 07/21] Keep the fileType check and mod docs a bit --- packages/react/src/components/fileInput/FileInput.tsx | 5 +++++ site/src/docs/components/file-input/code.mdx | 2 +- site/src/docs/components/file-input/index.mdx | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/react/src/components/fileInput/FileInput.tsx b/packages/react/src/components/fileInput/FileInput.tsx index 5749016bf3..a4c94e1810 100644 --- a/packages/react/src/components/fileInput/FileInput.tsx +++ b/packages/react/src/components/fileInput/FileInput.tsx @@ -301,10 +301,15 @@ const getExtension = (path: string): string => { const validateAccept = (language: Language, accept: string) => (file: File): true | ValidationError => { const extension: string = getExtension(file.name); + const fileType: string = file.type; const acceptedExtensions = accept.split(',').map((str) => str.trim()); + const isMatchingType = !!acceptedExtensions.find( + (acceptExtension) => acceptExtension.includes(fileType) || acceptExtension.includes(`${fileType.split('/')[0]}/*`), + ); const hasMatchingFileExtension = !!acceptedExtensions.find((acceptExtension) => acceptExtension === extension); return ( + isMatchingType || hasMatchingFileExtension || { type: ValidationErrorType.accept, text: getAcceptErrorMessage(language, file, accept), diff --git a/site/src/docs/components/file-input/code.mdx b/site/src/docs/components/file-input/code.mdx index e74a7a8ee9..919b505080 100644 --- a/site/src/docs/components/file-input/code.mdx +++ b/site/src/docs/components/file-input/code.mdx @@ -100,7 +100,7 @@ Also, note that this component is an input. All features supported by the HDS Te | Property | Description | Values | Default value | | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | ------------- | -| `accept` | A comma-separated list of unique file type specifiers describing file types to allow. If present, the filename extension is validated against the list. | `string` | - | +| `accept` | A comma-separated list of unique file type specifiers describing file types to allow. If present, the filename extension or filetype property is validated against the list. | `string` | - | | `buttonLabel` | The label for the file button. Overrides default text. The button is not visible for assistive technology. | `string` | - | | `defaultValue`| If set, pre-fill the file(s) selection | `File[]` | - | | `dragAndDrop` | If set to true, the input will show a drag and rop area. | `boolean` | false | diff --git a/site/src/docs/components/file-input/index.mdx b/site/src/docs/components/file-input/index.mdx index 880831e013..177f1404fb 100644 --- a/site/src/docs/components/file-input/index.mdx +++ b/site/src/docs/components/file-input/index.mdx @@ -47,7 +47,7 @@ export const FileInputExample = () => { - Dragging and dropping files can be allowed by using the `dragAndDrop` property. - The FileInput uses an info text element to inform the user about the status of the component. You can read more about the usage of the info text element in the HDS Form validation pattern documentation page. - The FileInput component resolves human-readable file size abbreviations based on a binary system. The file size texts are shown after the selected file name and in maxSize messages if maxSize validation is used. -- The accept parameter only checks and allows selecting the correct file types according to the file extension(s) and does not do any in-depth analysis. Any safety and/or other checks should be done on the receiving end if necessary. +- The accept parameter only checks and allows selecting the correct file types according to the file extension(s) or file types and does not do any in-depth analysis. Any safety and/or other checks should be done on the receiving end if necessary. ### Variations From 4fe867ddfe6bda220e8a8bb594cc835944cbdfcb Mon Sep 17 00:00:00 2001 From: Tuomo Kivinen Date: Mon, 29 May 2023 08:25:09 +0200 Subject: [PATCH 08/21] revise the docs a bit --- site/src/docs/components/file-input/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/src/docs/components/file-input/index.mdx b/site/src/docs/components/file-input/index.mdx index 177f1404fb..dba5d1ba93 100644 --- a/site/src/docs/components/file-input/index.mdx +++ b/site/src/docs/components/file-input/index.mdx @@ -47,7 +47,7 @@ export const FileInputExample = () => { - Dragging and dropping files can be allowed by using the `dragAndDrop` property. - The FileInput uses an info text element to inform the user about the status of the component. You can read more about the usage of the info text element in the HDS Form validation pattern documentation page. - The FileInput component resolves human-readable file size abbreviations based on a binary system. The file size texts are shown after the selected file name and in maxSize messages if maxSize validation is used. -- The accept parameter only checks and allows selecting the correct file types according to the file extension(s) or file types and does not do any in-depth analysis. Any safety and/or other checks should be done on the receiving end if necessary. +- The accept parameter only checks and allows correct file types according to the file extension(s) or file types, instead of doing any in-depth analysis. ### Variations From 3c3fc19e3d18633e76c2b5cd82f2d69fb8f0a684 Mon Sep 17 00:00:00 2001 From: Lauri Lukkarinen Date: Tue, 30 May 2023 13:06:30 +0300 Subject: [PATCH 09/21] Removed unnecessary dependency --- packages/react/package.json | 1 - yarn.lock | 21 --------------------- 2 files changed, 22 deletions(-) diff --git a/packages/react/package.json b/packages/react/package.json index 73dfc13bf3..bec2a41c86 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -68,7 +68,6 @@ "@typescript-eslint/eslint-plugin": "5.10.2", "@wessberg/rollup-plugin-ts": "2.0.4", "babel-jest": "^26.0.1", - "babel-plugin-polyfill-corejs2": "^0.4.1", "babel-plugin-require-context-hook": "1.0.0", "chalk": "4.0.0", "eslint": "7.1.0", diff --git a/yarn.lock b/yarn.lock index 51d1d6fe9c..edc92105d3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -219,18 +219,6 @@ resolve "^1.14.2" semver "^6.1.2" -"@babel/helper-define-polyfill-provider@^0.4.0": - version "0.4.0" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.0.tgz#487053f103110f25b9755c5980e031e93ced24d8" - integrity sha512-RnanLx5ETe6aybRi1cO/edaRH+bNYWaryCEmjDDYyNr4wnSzyOp8T0dWipmqVHKEY3AbVKUom50AKSlj1zmKbg== - dependencies: - "@babel/helper-compilation-targets" "^7.17.7" - "@babel/helper-plugin-utils" "^7.16.7" - debug "^4.1.1" - lodash.debounce "^4.0.8" - resolve "^1.14.2" - semver "^6.1.2" - "@babel/helper-environment-visitor@^7.18.9": version "7.18.9" resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be" @@ -8799,15 +8787,6 @@ babel-plugin-polyfill-corejs2@^0.3.3: "@babel/helper-define-polyfill-provider" "^0.3.3" semver "^6.1.1" -babel-plugin-polyfill-corejs2@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.1.tgz#65daabf234f7e3e2368a5d566b32a6c4d1714edc" - integrity sha512-7gKaNF3qkEt1w2p3Q2D2f+UofAKtjWT5B82VXKdDlPqJI8eLT8phBKHq6uLEOCAEtnAWW3lomu3+X6VJrFMoSg== - dependencies: - "@babel/compat-data" "^7.17.7" - "@babel/helper-define-polyfill-provider" "^0.4.0" - semver "^6.1.1" - babel-plugin-polyfill-corejs3@^0.1.0: version "0.1.7" resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.1.7.tgz#80449d9d6f2274912e05d9e182b54816904befd0" From dde61ed9ddbd1c3041b18e82d8aa4772a5997875 Mon Sep 17 00:00:00 2001 From: Tuomo Kivinen Date: Mon, 5 Jun 2023 10:21:47 +0200 Subject: [PATCH 10/21] Don't use default value in Storybook custom example --- .../react/src/components/radioButton/RadioButton.stories.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react/src/components/radioButton/RadioButton.stories.tsx b/packages/react/src/components/radioButton/RadioButton.stories.tsx index 53ff092166..12fca64a61 100644 --- a/packages/react/src/components/radioButton/RadioButton.stories.tsx +++ b/packages/react/src/components/radioButton/RadioButton.stories.tsx @@ -30,7 +30,7 @@ export const SelectedDisabled = () => { - const [radioValue, setRadioValue] = useState('foo'); + const [radioValue, setRadioValue] = useState(''); const options = ['foo', 'bar']; const customStyles = { From 9201c7b06fd6444a5a89e8d3e3d94623f50ee824 Mon Sep 17 00:00:00 2001 From: Tuomo Kivinen Date: Mon, 5 Jun 2023 11:23:12 +0200 Subject: [PATCH 11/21] Add new instructions and modify examples for radio button default value to be empty --- .../docs/components/radio-button/index.mdx | 33 +++++++++++++++---- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/site/src/docs/components/radio-button/index.mdx b/site/src/docs/components/radio-button/index.mdx index dddaa179c9..b4a4ace0dc 100644 --- a/site/src/docs/components/radio-button/index.mdx +++ b/site/src/docs/components/radio-button/index.mdx @@ -16,7 +16,7 @@ export default ({ children, pageContext }) => { - const [selectedItem, setSelectedItem] = React.useState('1'); + const [selectedItem, setSelectedItem] = React.useState(''); const onChange = (event) => { setSelectedItem(event.target.value); }; @@ -38,6 +38,14 @@ export const RadioButtonExample = () => { checked={selectedItem === '2'} onChange={onChange} /> + ); }; @@ -50,7 +58,10 @@ export const RadioButtonExample = () => { - If the user can select more than one option from a list, use checkboxes instead. - Radio button label should always clearly describe what will happen if the specific option is chosen. A good practice is to keep labels a maximum of three words long. -- It is recommended to have a default option checked for radio button groups Radio button groups. +- **It is not recommended to have a default option selected** because + - The user might not realise they’ve missed a question + - The user might submit a wrong answer +- If an answer can be left empty, include a 'None of the abobe' or similar option if it's suitable. - When there are more than 4 options, consider switching to dropdown component. - If the choices are not mutually exclusive, use checkboxes component instead. Also see guidelines for choosing between radiobuttons, checkboxes, and toggles. - If Radio buttons are related to each other, use selection group to achieve that. @@ -60,14 +71,14 @@ export const RadioButtonExample = () => { #### Default export const DefaultRadioButtonExample = () => { - const [selectedItem2, setSelectedItem2] = React.useState('1'); + const [selectedItem2, setSelectedItem2] = React.useState(''); const onChange2 = (event) => { setSelectedItem2(event.target.value); }; return ( <> { onChange={onChange2} /> - + ); }; @@ -96,7 +115,7 @@ export const DefaultRadioButtonExample = () => { Related radio buttons can be grouped together with the Selection group component. See HDS selection group page for full documentation. export const GroupExample = () => { - const [selectedItem, setSelectedItem] = React.useState('1'); + const [selectedItem, setSelectedItem] = React.useState(''); const onChange = (event) => { setSelectedItem(event.target.value); }; From 2f350084d7d742b1d9ed358a89a07e29429dc4fe Mon Sep 17 00:00:00 2001 From: Tuomo Kivinen Date: Mon, 5 Jun 2023 12:34:00 +0200 Subject: [PATCH 12/21] update loki-images --- ...ponents_RadioButton_With_custom_styles.png | Bin 8883 -> 8066 bytes ...ponents_RadioButton_With_custom_styles.png | Bin 4568 -> 4087 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/packages/react/.loki/reference/chrome_iphone7_Components_RadioButton_With_custom_styles.png b/packages/react/.loki/reference/chrome_iphone7_Components_RadioButton_With_custom_styles.png index dbd29c51383500f27a5e63f29316a77e940c3da6..9c858c087c32a6fc99112310b1a75bd2823349d1 100644 GIT binary patch literal 8066 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 U0*4zNz%~T(u7)!Hj^&g82geJN1ONa4 literal 8883 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 M3Ea5B$m`a>0k8c$KmY&$ literal 4568 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 Date: Tue, 6 Jun 2023 10:06:37 +0300 Subject: [PATCH 13/21] Fix FileInput maximum file size to maxSize Currently, if maxSize is set, the file added in FileInput needs to be smaller than the file. If adding a file exactly the size of the limit, we get a confusing validation message: > - File, test.png, is too large (100 B). The maximum file size is 100 B. Fix this by allowing the file to be smaller or equal to maxSize. --- .../react/src/components/fileInput/FileInput.test.tsx | 8 +++++--- packages/react/src/components/fileInput/FileInput.tsx | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/react/src/components/fileInput/FileInput.test.tsx b/packages/react/src/components/fileInput/FileInput.test.tsx index a02b255aa4..ff49dac9d8 100644 --- a/packages/react/src/components/fileInput/FileInput.test.tsx +++ b/packages/react/src/components/fileInput/FileInput.test.tsx @@ -142,6 +142,8 @@ describe(' spec', () => { const firstFile = new File(['test'], firstFileName, { type: 'image/png' }); const secondFileName = 'test-file-b'; const secondFile = new File(['test-file-with-too-long-content'], secondFileName, { type: 'image/png' }); + const thirdFileName = 'test-file-with-exactly-max-size-bytes'; + const thirdFile = new File(['0123456789'], thirdFileName, { type: 'image/png' }); render( spec', () => { />, ); const fileUpload = screen.getByLabelText(inputLabel); - userEvent.upload(fileUpload, [firstFile, secondFile]); + userEvent.upload(fileUpload, [firstFile, secondFile, thirdFile]); expect(screen.getByText(firstFileName)).toBeInTheDocument(); - expect(screen.getByText('1/2 file(s) added', { exact: false })).toBeInTheDocument(); - expect(screen.getByText('File processing failed for 1/2 files:', { exact: false })).toBeInTheDocument(); + expect(screen.getByText('2/3 file(s) added', { exact: false })).toBeInTheDocument(); + expect(screen.getByText('File processing failed for 1/3 files:', { exact: false })).toBeInTheDocument(); expect( screen.getByText(`File, ${secondFileName}, is too large (31 B). The maximum file size is 10 B.`, { exact: false, diff --git a/packages/react/src/components/fileInput/FileInput.tsx b/packages/react/src/components/fileInput/FileInput.tsx index a4c94e1810..3e4b7da4a9 100644 --- a/packages/react/src/components/fileInput/FileInput.tsx +++ b/packages/react/src/components/fileInput/FileInput.tsx @@ -319,7 +319,7 @@ const validateAccept = (language: Language, accept: string) => (file: File): tru const validateMaxSize = (language: Language, maxSize: number) => (file: File): true | ValidationError => { return ( - file.size < maxSize || { + file.size <= maxSize || { type: ValidationErrorType.maxSize, text: getMaxSizeErrorMessage(language, file, maxSize), } From 8172a0d01604abc0e5e76f55a76ce26cc1fb5678 Mon Sep 17 00:00:00 2001 From: Tuomo Kivinen Date: Tue, 6 Jun 2023 09:35:47 +0200 Subject: [PATCH 14/21] change null to empty string --- .../react/src/components/radioButton/RadioButton.stories.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react/src/components/radioButton/RadioButton.stories.tsx b/packages/react/src/components/radioButton/RadioButton.stories.tsx index 12fca64a61..c49f22bd9d 100644 --- a/packages/react/src/components/radioButton/RadioButton.stories.tsx +++ b/packages/react/src/components/radioButton/RadioButton.stories.tsx @@ -67,7 +67,7 @@ Custom.storyName = 'With custom styles'; export const WithHelperText = () => ; export const Playground = (args) => { - const [radioValue, setRadioValue] = useState(null); + const [radioValue, setRadioValue] = useState(''); const options = ['foo', 'bar', 'baz']; const styles = { From 602a04e30a20f14c01f90327361620db8ed6fd1f Mon Sep 17 00:00:00 2001 From: Tuomo Kivinen Date: Mon, 19 Jun 2023 08:43:56 +0200 Subject: [PATCH 15/21] add .nvmrc and bum CI node version to v16 --- .github/workflows/development.yml | 2 +- .github/workflows/gh-pages.yml | 2 +- .nvmrc | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 .nvmrc diff --git a/.github/workflows/development.yml b/.github/workflows/development.yml index 7b7eb83b0f..bc684f34ba 100644 --- a/.github/workflows/development.yml +++ b/.github/workflows/development.yml @@ -17,7 +17,7 @@ jobs: - name: setup node uses: actions/setup-node@v2.5.1 with: - node-version: '14.x' + node-version: '16.x' registry-url: 'https://registry.npmjs.org' - name: install dependencies diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index f83bd35596..92185eb162 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -15,7 +15,7 @@ jobs: - name: setup node uses: actions/setup-node@v2.5.1 with: - node-version: "14.x" + node-version: "16.x" registry-url: "https://registry.npmjs.org" - name: install dependencies diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000000..e329619ca2 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +v16.19.1 From e845c38c59bf1459ab01ef7cb2077d42a2c7208c Mon Sep 17 00:00:00 2001 From: Tuomo Kivinen Date: Mon, 19 Jun 2023 08:56:56 +0200 Subject: [PATCH 16/21] read .nvmrc to install node version in CI --- .github/workflows/development.yml | 8 ++++++-- .github/workflows/gh-pages.yml | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/.github/workflows/development.yml b/.github/workflows/development.yml index bc684f34ba..70ee469c81 100644 --- a/.github/workflows/development.yml +++ b/.github/workflows/development.yml @@ -14,10 +14,14 @@ jobs: - name: Checkout code uses: actions/checkout@v3 - - name: setup node + - name: Read .nvmrc + run: echo ::set-output name=NODE_VERSION::$(cat .nvmrc) + id: nvm + + - name: setup node ${{ steps.nvm.outputs.NODE_VERSION }} uses: actions/setup-node@v2.5.1 with: - node-version: '16.x' + node-version: ${{ steps.nvm.outputs.NODE_VERSION }} registry-url: 'https://registry.npmjs.org' - name: install dependencies diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index 92185eb162..2857c7a5af 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -12,10 +12,14 @@ jobs: - name: Checkout code uses: actions/checkout@v3 - - name: setup node + - name: Read .nvmrc + run: echo ::set-output name=NODE_VERSION::$(cat .nvmrc) + id: nvm + + - name: setup node ${{ steps.nvm.outputs.NODE_VERSION }} uses: actions/setup-node@v2.5.1 with: - node-version: "16.x" + node-version: ${{ steps.nvm.outputs.NODE_VERSION }} registry-url: "https://registry.npmjs.org" - name: install dependencies From 89ca1aace0e5cca1b24e1114d4db50c7b621f509 Mon Sep 17 00:00:00 2001 From: Tuomo Kivinen Date: Mon, 19 Jun 2023 09:33:14 +0200 Subject: [PATCH 17/21] rework the nvmrc read in CI not to use the deprecated way --- .github/workflows/development.yml | 10 +++++----- .github/workflows/gh-pages.yml | 12 ++++++------ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/development.yml b/.github/workflows/development.yml index 70ee469c81..4d0d331067 100644 --- a/.github/workflows/development.yml +++ b/.github/workflows/development.yml @@ -15,13 +15,13 @@ jobs: uses: actions/checkout@v3 - name: Read .nvmrc - run: echo ::set-output name=NODE_VERSION::$(cat .nvmrc) - id: nvm + run: echo "NODE_VERSION=$(cat .nvmrc)" >> $GITHUB_OUTPUT + id: nvmrc - - name: setup node ${{ steps.nvm.outputs.NODE_VERSION }} - uses: actions/setup-node@v2.5.1 + - name: setup node ${{ steps.nvmrc.outputs.NODE_VERSION }} + uses: actions/setup-node@v3 with: - node-version: ${{ steps.nvm.outputs.NODE_VERSION }} + node-version: '${{ steps.nvmrc.outputs.NODE_VERSION }}' registry-url: 'https://registry.npmjs.org' - name: install dependencies diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index 2857c7a5af..6435eb24cc 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -13,14 +13,14 @@ jobs: uses: actions/checkout@v3 - name: Read .nvmrc - run: echo ::set-output name=NODE_VERSION::$(cat .nvmrc) - id: nvm + run: echo "NODE_VERSION=$(cat .nvmrc)" >> $GITHUB_OUTPUT + id: nvmrc - - name: setup node ${{ steps.nvm.outputs.NODE_VERSION }} - uses: actions/setup-node@v2.5.1 + - name: setup node ${{ steps.nvmrc.outputs.NODE_VERSION }} + uses: actions/setup-node@v3 with: - node-version: ${{ steps.nvm.outputs.NODE_VERSION }} - registry-url: "https://registry.npmjs.org" + node-version: '${{ steps.nvmrc.outputs.NODE_VERSION }}' + registry-url: 'https://registry.npmjs.org' - name: install dependencies run: yarn From 9d5812b1252ab942e8bcd495cb0478464e4065c5 Mon Sep 17 00:00:00 2001 From: Tuomo Kivinen Date: Mon, 19 Jun 2023 09:57:50 +0200 Subject: [PATCH 18/21] add info regarding nvm to development info --- DEVELOPMENT.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 8dda9f207e..03c3464c8f 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -2,10 +2,11 @@ ## Development environment -> Helsinki Design System uses [**Lerna**](https://lerna.js.org/) for running scripts across the repo as well as versioning and creating releases of the packages. [**Yarn workspaces**](https://yarnpkg.com/lang/en/docs/workspaces/) is used to manage dependencies. This allows the separate packages to reference each other via symlinks during local development. +> Helsinki Design System uses [**Lerna**](https://lerna.js.org/) for running scripts across the repo as well as versioning and creating releases of the packages. [**Yarn workspaces**](https://yarnpkg.com/lang/en/docs/workspaces/) is used to manage dependencies. This allows the separate packages to reference each other via symlinks during local development. [**Nvm**](https://github.com/nvm-sh/nvm) is a node version manager used to specify the preferred node version across the project (optional but highly recommended, if not used, see the preferred version in .nvmrc file). ### Prerequisites +- [Nvm](https://github.com/nvm-sh/nvm) - [Node](https://nodejs.org/en/) - [Yarn](https://yarnpkg.com/) - [Docker](https://www.docker.com/) (for visual regression tests) From 39f8df19a49394a8689be4743d03f802bd1aa96e Mon Sep 17 00:00:00 2001 From: Tuomo Kivinen Date: Wed, 21 Jun 2023 13:17:52 +0200 Subject: [PATCH 19/21] HDS-1684 yarn.lock cleanup, fix array index & classNames errors, fix jsx-a11y eslint-rules, update lerna, update rimraf, bump node to v16 in GH --- lerna.json | 1 - package.json | 4 +- packages/react/.eslintrc.json | 2 + .../headerUniversalBar/HeaderUniversalBar.tsx | 3 +- .../navigationLink/NavigationLink.tsx | 1 + .../sideNavigation/SideNavigation.tsx | 1 + .../sideNavigation/mainLevel/MainLevel.tsx | 1 + yarn.lock | 7705 ++++++++--------- 8 files changed, 3574 insertions(+), 4144 deletions(-) diff --git a/lerna.json b/lerna.json index 06cff9cd69..140d2c6043 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,4 @@ { "npmClient": "yarn", - "useWorkspaces": true, "version": "independent" } diff --git a/package.json b/package.json index dc920bbe6b..7137b89ded 100644 --- a/package.json +++ b/package.json @@ -19,8 +19,8 @@ "update-versions": "lerna version --exact --no-git-tag-version --no-push --amend --yes" }, "devDependencies": { - "lerna": "^3.16.4", - "rimraf": "^4.1.3" + "lerna": "^7.0.1", + "rimraf": "^5.0.1" }, "resolutions": { "multer": "1.4.4-lts.1", diff --git a/packages/react/.eslintrc.json b/packages/react/.eslintrc.json index 922ec09465..88a14bd032 100644 --- a/packages/react/.eslintrc.json +++ b/packages/react/.eslintrc.json @@ -52,6 +52,8 @@ "react/prop-types": "off", "import/extensions": "off", "import/prefer-default-export": "off", + "jsx-a11y/control-has-associated-label": "warn", + "jsx-a11y/no-interactive-element-to-noninteractive-role": "warn", "jsx-a11y/label-has-associated-control": [ 2, { diff --git a/packages/react/src/components/header/components/headerUniversalBar/HeaderUniversalBar.tsx b/packages/react/src/components/header/components/headerUniversalBar/HeaderUniversalBar.tsx index f9b243988a..fa55fc2f0f 100644 --- a/packages/react/src/components/header/components/headerUniversalBar/HeaderUniversalBar.tsx +++ b/packages/react/src/components/header/components/headerUniversalBar/HeaderUniversalBar.tsx @@ -39,6 +39,7 @@ export type HeaderUniversalBarProps = React.PropsWithChildren<{ export const HeaderUniversalBar = ({ ariaLabel, children, + className, id, primaryLinkHref, primaryLinkText, @@ -48,7 +49,7 @@ export const HeaderUniversalBar = ({ const childElements = getChildElementsEvenIfContainerInbetween(children); return ( -