diff --git a/.styleguidist/StyleGuideRenderer.tsx b/.styleguidist/StyleGuideRenderer.tsx index 83a506756..82ca90a49 100644 --- a/.styleguidist/StyleGuideRenderer.tsx +++ b/.styleguidist/StyleGuideRenderer.tsx @@ -13,7 +13,7 @@ import { Classes } from 'jss'; import Ribbon from 'react-styleguidist/lib/client/rsg-components/Ribbon'; import Version from 'react-styleguidist/lib/client/rsg-components/Version'; import * as Rsg from 'react-styleguidist/lib/typings'; -import { Alert } from '../src/core/Alert/'; +import { Alert } from '../src/core/Alert/Alert'; const styles = ({ color, diff --git a/.styleguidist/icons.md b/.styleguidist/icons.md index 2ad213ad5..04b1349f4 100644 --- a/.styleguidist/icons.md +++ b/.styleguidist/icons.md @@ -17,7 +17,7 @@ import { IconArchive } from 'suomifi-ui-components'; ; ``` -To use icons as a property for other components, simply give an icon element with the desired properties as a value for the component property. +To use icons as a property for other components, simply provide an icon element with the desired properties as a value for the component property. ```js import { Button, IconLogin } from 'suomifi-ui-components'; diff --git a/.styleguidist/styleguidist.sections.js b/.styleguidist/styleguidist.sections.js index 9fe34927a..4dd7c6224 100644 --- a/.styleguidist/styleguidist.sections.js +++ b/.styleguidist/styleguidist.sections.js @@ -1,14 +1,20 @@ const path = require('path'); -const glob = require('glob'); const versions = require('../styleguide.versions'); -const primitiveComponents = [ +const singularComponents = [ 'Block', 'Button', 'Heading', 'Tooltip', 'VisuallyHidden', 'Pagination', + 'Alert', + 'InlineAlert', + 'LoadingSpinner', + 'Text', + 'Paragraph', + 'Notification', + 'Toast', ['Form', 'TextInput'], ['Form', 'SearchInput'], ['Form', 'Textarea'], @@ -16,6 +22,8 @@ const primitiveComponents = [ ['Form', 'Label'], ['Form', 'HintText'], ['Form', 'StatusText'], + ['Form/Select/MultiSelect/', 'MultiSelect'], + ['Form/Select', 'SingleSelect'], ]; const getComponent = ({ name, underName }) => @@ -118,7 +126,7 @@ module.exports = { { name: 'Components', content: './.styleguidist/components.md', - components: getComponents(primitiveComponents), + components: getComponents(singularComponents), sections: [ { name: 'Toggle', @@ -127,21 +135,6 @@ module.exports = { 'ToggleInput/ToggleInput', ]), }, - { - name: 'Text', - components: getComponents(['Text', 'Paragraph']), - }, - { - name: 'Alert', - components: getComponentWithVariants('Alert')([ - 'Alert/Alert', - 'InlineAlert/InlineAlert', - ]), - }, - { - name: 'LoadingSpinner', - components: getComponents(['LoadingSpinner']), - }, { name: 'Checkbox', components: getComponentWithVariants('Form/Checkbox')([ @@ -183,7 +176,7 @@ module.exports = { name: 'Icon', content: './.styleguidist/icon.md', }, - { + /*{ name: 'MultiSelect', components: getComponentWithVariants('Form/Select')([ 'MultiSelect/MultiSelect/MultiSelect', @@ -194,7 +187,7 @@ module.exports = { components: getComponentWithVariants('Form/Select')([ 'SingleSelect/SingleSelect', ]), - }, + }, */ { name: 'Breadcrumb', components: getComponentWithVariants('Breadcrumb')([ @@ -217,18 +210,14 @@ module.exports = { 'LanguageMenuLink/LanguageMenuLink', ]), }, - { - name: 'Notification', - components: getComponents(['Notification']), - }, { name: 'Expander', components: getComponentWithVariants('Expander')([ 'Expander/Expander', - 'ExpanderGroup/ExpanderGroup', - 'ExpanderTitle/ExpanderTitle', 'ExpanderTitleButton/ExpanderTitleButton', 'ExpanderContent/ExpanderContent', + 'ExpanderGroup/ExpanderGroup', + 'ExpanderTitle/ExpanderTitle', ]), }, { @@ -236,13 +225,10 @@ module.exports = { components: getComponentWithVariants('Modal')([ 'Modal/Modal', 'ModalContent/ModalContent', + 'ModalTitle/ModalTitle', 'ModalFooter/ModalFooter', ]), }, - { - name: 'Toast', - components: getComponents(['Toast']), - }, { name: 'WizardNavigation', components: getComponentWithVariants('Navigation/WizardNavigation')([ diff --git a/src/core/ActionMenu/ActionMenu.md b/src/core/ActionMenu/ActionMenu.md index e36ca01e7..f5a922d49 100644 --- a/src/core/ActionMenu/ActionMenu.md +++ b/src/core/ActionMenu/ActionMenu.md @@ -1,142 +1,217 @@ -### Default ActionMenu +`` is used for selecting an action if the amount of available actions is so great regular `; +``` -<> - +### Full width button - - -; +Use `fullwidth` Button on smaller screen sizes. + +```js +import { Button } from 'suomifi-ui-components'; + +; ``` +### Disabled button + +In the example below + +- The first Button is fully `disabled` +- The second one is `aria-disabled`. Aria-disabled allows focus but disables the button's `onClick()` functionality. + +It is good practice to provide additional information as to why a Button is disabled. + ```js import { Button, Paragraph, Text } from 'suomifi-ui-components'; <> + - Additional information for aria-disabled button + You must fill all required fields before submitting ; ``` +### Icons in button + +When using a Button whose only visible content is an icon, provide a descriptive `aria-label` for . + ```js -import { Button } from 'suomifi-ui-components'; -import { IconLogin } from 'suomifi-icons'; +import { Button, IconArrowRight } from 'suomifi-ui-components'; <> - + - + + + ; ``` -```js -import { Button } from 'suomifi-ui-components'; -import { IconLogin } from 'suomifi-icons'; +### Secondary button -<> -
- - - -
-; -``` +A secondary Button is used for an optional action. A borderless variant can be used to further diminsh the Button's notability. ```js import { Button } from 'suomifi-ui-components'; -import { IconLogin } from 'suomifi-icons'; <> - + - + +; +``` - +### Light secondary button - +A light secondary Button is used for a noteworthy but not necessarily required action. Example use case: a table where the Button is repeated on every row. - +```js +import { Button } from 'suomifi-ui-components'; - -; +; ``` -```js -import { Button } from 'suomifi-ui-components'; -import { IconLogin } from 'suomifi-icons'; +### Inverted button -<> - +An inverted Button is used on colored backgrounds. - -; +```js +import { + Button, + Block, + suomifiDesignTokens +} from 'suomifi-ui-components'; + + + +; ``` + +### Props & methods diff --git a/src/core/Button/Button.tsx b/src/core/Button/Button.tsx index 8295a1b32..1e8ddfe77 100644 --- a/src/core/Button/Button.tsx +++ b/src/core/Button/Button.tsx @@ -26,7 +26,8 @@ export interface ButtonProps children?: ReactNode; /** * Define a label if button's text content does not indicate the button's purpose (for example, button with only an icon). - * Alternatively you can define an aria-labelledby + * If the button has a visible label, make sure the aria-label includes the visible text. + * Alternatively you can define an `aria-labelledby`. */ 'aria-label'?: string; /** Disables the button */ @@ -111,10 +112,7 @@ const StyledButton = styled( )` ${({ theme }) => baseStyles(theme)} `; -/** - * - * Use for inside Application onClick events.
- */ + const Button = forwardRef( (props: ButtonProps, ref: React.RefObject) => ( diff --git a/src/core/Chip/Chip/Chip.md b/src/core/Chip/Chip/Chip.md index a340f8e76..5a3fdb84a 100644 --- a/src/core/Chip/Chip/Chip.md +++ b/src/core/Chip/Chip/Chip.md @@ -1,54 +1,89 @@ +The `` component is used when you want to present concise information in a clear visually prominent way, for example to display the selected values of a listbox. In its most typical usecase, the Chip is a button with a "remove" icon. + +Examples: + +- [Basic use](/#/Components/Chip?id=basic-use) +- [Without remove icon](/#/Components/Chip?id=without-remove-icon) +- [Disabled](/#/Components/Chip?id=disabled) +- [Static chip](/#/Components/Chip?id=static-chip) + +
+ [Props & methods (Chip)](/#/Components/Chip?id=props--methods) +
+
+ [Props & methods (StaticChip)](/#/Components/Chip?id=staticchip) +
+ +### Basic use + +It is important to set the `actionLabel` text so that can describe the function of the Chip. + +```js +import { Chip } from 'suomifi-ui-components'; + + console.log('Deselected: Finland')} +> + Finland +; +``` + +### Without remove icon + +The remove icon can be hidden to allow for more use cases + ```js import { Chip } from 'suomifi-ui-components'; -import React from 'react'; - -const removeAction = () => { - alert('Selection removed'); -}; - -const exampleRef = React.createRef(); -const chipStyle = { - display: 'inline-block', - marginRight: '10px', - marginBottom: '24px' -}; + + console.log('Clicked option: Finland')} +> + Finland +; +``` + +### Disabled + +In the example below + +- The first Chip is fully `disabled` +- The second one is `aria-disabled`. Aria-disabled allows focus but disables the Chip's `onClick()` functionality. + +```js +import { Chip } from 'suomifi-ui-components'; + <> -
- - Removable chip - - { - console.log(exampleRef.current); - removeAction(); - }} - > - Removable chip with ref - -
-
- - Clickable chip without remove icon - -
- - - Chip with a - reallyReallyLongWeirdWordThatNeedsToBeBrokenToFitInToTheChip and - content that doesn't fit in one line and spans multiple lines. + console.log('Deselected: Finland')} + > + Finland - Disabled chip - - Aria-disabled chip + console.log('Deselected: Finland')} + > + Finland + ; ``` + +### Static chip + +`` is a Chip without the button functionality, i.e only for visual presentation. + +```js +import { StaticChip } from 'suomifi-ui-components'; + +Finland; +``` + +### Props & methods diff --git a/src/core/Chip/StaticChip/StaticChip.md b/src/core/Chip/StaticChip/StaticChip.md index f5d933544..e69de29bb 100644 --- a/src/core/Chip/StaticChip/StaticChip.md +++ b/src/core/Chip/StaticChip/StaticChip.md @@ -1,24 +0,0 @@ -```js -import { StaticChip } from 'suomifi-ui-components'; -import React from 'react'; - -const chipStyle = { - display: 'inline-block', - marginRight: '10px', - marginBottom: '24px' -}; - -<> -
- Basic static chip - - Disabled static chip - -
- - Static chip with a - reallyReallyLongWeirdWordThatNeedsToBeBrokenToFitInToTheChip and - content that doesn't fit in one line and spans multiple lines. - -; -``` diff --git a/src/core/Dropdown/Dropdown/Dropdown.md b/src/core/Dropdown/Dropdown/Dropdown.md index 976bd0493..cbc1be850 100644 --- a/src/core/Dropdown/Dropdown/Dropdown.md +++ b/src/core/Dropdown/Dropdown/Dropdown.md @@ -1,238 +1,378 @@ +The `` component is used to select a value from a list of options. The component is rendered as a combination of a ` - - Test expander 1 - Test expander content 1 + + + Can I manage my own devices? + + + + You can manage the devices you use: + + + In the Suomi.fi application +
    +
  • Settings: Login and Security
  • +
+ + In the Suomi.fi Web Service or mobile device browser{' '} + +
    +
  • Messages section: Device Manager
  • +
+
+ + Device data will include the name of each device and the + time at which the application has last been used. You can + log out of the Suomi.fi application the devices you choose. + Logging out will remove all Suomi.fi applications from the + device you have selected. In this case, the Suomi.fi + Messages cannot be used on the device until a new + e-identification. + +
- - Test expander 2 - Test expander content 2 + + + Is the application secure? + + + + Suomi.fi Messages is a secure way to communicate with + organisations that use the service. +
    +
  • + The messages and attachments shown in the application + are transmitted in encrypted form between the mobile + device and the server. +
  • +
  • + The app requires permissions to use your mobile device’s + photographs and other files, so it can process + attachments included in messages. +
  • +
  • + The user is individually identified using strong + identification. This means that you are the only person + who can access your data. +
  • +
+
+ + If you break your mobile device or lose it, you can sign out + of the Suomi.fi application either in the Suomi.fi web + service or by using another phone. + +
- { - if (window.confirm('Toggle Expander 3')) { - setExpanderThreeOpen(!open); - } - }} - > - Test expander 3 - Test expander content 3 + + + Errors in the Suomi.fi mobile application + + + + If the application does not work on your mobile device for + some reason, you can also read your messages via a browser + + + Errors occurring in the Suomi.fi application generally do + not affect the preservation of Suomi.fi Messages. + +
; ``` + +### Interactive elements in Expander title + +If you need to have interactive elements in the Expander title, use `` instead of ``. + +ExpanderTitle creates a smaller toggle button to the right side of the Expander. Generally `ariaOpenText`/`ariaCloseText` props should have the same value, because state is already communicated to assistive technology using `aria-expanded`. Point `toggleButtonAriaDescribedBy` to the ID of interactive element to provide additional context for assistive technology. + +```jsx +import { + Expander, + ExpanderTitle, + ExpanderContent, + Checkbox, + Paragraph +} from 'suomifi-ui-components'; + + + + Guardianship + + + + Guardianship means the management of other persons’ finances and + looking after their interests when they are no longer able to do + it. Choose guardianship if the matters of a person close to you + cannot be managed in any other way. + + + You can safeguard the management of your property and other + personal matters with a continuing power of attorney. + + +; +``` + +### Props & methods diff --git a/src/core/Expander/Expander/Expander.tsx b/src/core/Expander/Expander/Expander.tsx index 64f61cc73..10d9d831a 100644 --- a/src/core/Expander/Expander/Expander.tsx +++ b/src/core/Expander/Expander/Expander.tsx @@ -190,10 +190,6 @@ interface ExpanderState { openState: boolean; } -/** - * - * Hide or show content with always visible title - */ const Expander = forwardRef( (props: ExpanderProps, ref: React.Ref) => { const { id: propId, ...passProps } = props; diff --git a/src/core/Expander/ExpanderContent/ExpanderContent.tsx b/src/core/Expander/ExpanderContent/ExpanderContent.tsx index 4f469432e..9625cbc6a 100644 --- a/src/core/Expander/ExpanderContent/ExpanderContent.tsx +++ b/src/core/Expander/ExpanderContent/ExpanderContent.tsx @@ -68,10 +68,6 @@ const StyledExpanderContent = styled(BaseExpanderContent)` ${({ theme }) => baseStyles(theme)} `; -/** - * - * Expander content wrapper, controlled by expander - */ const ExpanderContent = (props: ExpanderContentProps) => ( {({ suomifiTheme }) => ( diff --git a/src/core/Expander/ExpanderGroup/ExpanderGroup.tsx b/src/core/Expander/ExpanderGroup/ExpanderGroup.tsx index 13a7b0882..f26be1e0d 100644 --- a/src/core/Expander/ExpanderGroup/ExpanderGroup.tsx +++ b/src/core/Expander/ExpanderGroup/ExpanderGroup.tsx @@ -198,11 +198,6 @@ const StyledExpanderGroup = styled(BaseExpanderGroup)` ${({ theme }) => baseStyles(theme)} `; -/** - * - * Wrapper for multiple expanders with Open/Close All button - */ - const ExpanderGroup = forwardRef( (props: ExpanderGroupProps, ref: React.Ref) => ( diff --git a/src/core/Expander/ExpanderTitle/ExpanderTitle.tsx b/src/core/Expander/ExpanderTitle/ExpanderTitle.tsx index 5c3f74f33..dff625878 100644 --- a/src/core/Expander/ExpanderTitle/ExpanderTitle.tsx +++ b/src/core/Expander/ExpanderTitle/ExpanderTitle.tsx @@ -26,9 +26,9 @@ export interface ExpanderTitleProps extends Omit { className?: string; /** Title for Expander */ children?: ReactNode; - /** Screen reader action label for collapsed expander toggle button. E.g. "open expander". */ + /** Screen reader action label for collapsed expander toggle button. E.g. "Additional information". */ ariaOpenText: string; - /** Screen reader action label for expanded expander toggle button. E.g. "close expander". */ + /** Screen reader action label for expanded expander toggle button. Should usually be the same as `ariaOpenText` */ ariaCloseText: string; /** Expander title id for screen reader reference in expander toggle button. */ toggleButtonAriaDescribedBy: string; @@ -99,10 +99,6 @@ const StyledExpanderTitle = styled(BaseExpanderTitle)` ${({ theme }) => expanderTitleBaseStyles(theme)} `; -/** - * - * Expander title for focusable content and toggle button for content visiblity - */ const ExpanderTitle = (props: ExpanderTitleProps) => ( {({ suomifiTheme }) => ( diff --git a/src/core/Expander/ExpanderTitleButton/ExpanderTitleButton.tsx b/src/core/Expander/ExpanderTitleButton/ExpanderTitleButton.tsx index 2cbfe585c..4fdd7bc93 100644 --- a/src/core/Expander/ExpanderTitleButton/ExpanderTitleButton.tsx +++ b/src/core/Expander/ExpanderTitleButton/ExpanderTitleButton.tsx @@ -85,10 +85,6 @@ const StyledExpanderTitle = styled(BaseExpanderTitleButton)` ${({ theme }) => expanderTitleButtonBaseStyles(theme)} `; -/** - * - * Expander title button for static title content and toggle for content visiblity - */ const ExpanderTitleButton = forwardRef( ( props: ExpanderTitleButtonProps, diff --git a/src/core/Form/Checkbox/Checkbox.md b/src/core/Form/Checkbox/Checkbox.md index f6be8b685..3cbaaad43 100644 --- a/src/core/Form/Checkbox/Checkbox.md +++ b/src/core/Form/Checkbox/Checkbox.md @@ -1,88 +1,212 @@ +The `` component is used to mark a value as selected in a form. + +Examples: + +- [Basic use](/#/Components/Checkbox?id=basic-use) +- [Hint text](/#/Components/Checkbox?id=hint-text) +- [Error status](/#/Components/Checkbox?id=error-status) +- [Default state](/#/Components/Checkbox?id=default-state) +- [Controlled state](/#/Components/Checkbox?id=controlled-state) +- [Disabled](/#/Components/Checkbox?id=disabled) +- [Accessing value with ref](/#/Components/Checkbox?id=accessing-value-with-ref) +- [Large checkbox](/#/Components/Checkbox?id=large-checkbox) +- [Checkboxes in group](/#/Components/Checkbox?id=checkboxes-in-group) +- [Group error status](/#/Components/Checkbox?id=group-error-status) +- [Optional input](/#/Components/Checkbox?id=optional-input) +- [Group with a tooltip](/#/Components/Checkbox?id=group-with-a-tooltip) + +
+ [Props & methods (Checkbox)](/#/Components/Checkbox?id=props--methods) +
+
+ [Props & methods (CheckboxGroup)](/#/Components/Checkbox?id=checkboxgroup) +
+ +### Basic use + +```js +import { Checkbox } from 'suomifi-ui-components'; + +I accept the terms & conditions; +``` + +### Hint text + +Use the `hintText` prop to provide additional information about the field + +```js +import { Checkbox } from 'suomifi-ui-components'; + + + I wish to be contacted regularly +; +``` + +### Error status + +Toggle the error status of the component using the `status` and `statusText` props. The `statusText` is connected to the `` using `aria-describedby` and read out to screen readers automatically upon change using `aria-live="assertive"`. + +```js +import { Checkbox } from 'suomifi-ui-components'; + + + I accept the terms & conditions +; +``` + +### Default state + +The initial state of the component can be set with the `defaultChecked` prop. + +```js +import { Checkbox } from 'suomifi-ui-components'; + +I accept the terms & conditions; +``` + +### Controlled state + +The state of the component can be accessed and controlled programmatically using the `checked` prop. + +A typical use case involves setting the state manually in the `onClick()` function. + +```js +import { Checkbox } from 'suomifi-ui-components'; +import { useState } from 'react'; + +const [checked, setChecked] = useState(false); + + { + setChecked(newState.checkboxState); + }} +> + I wish to be contacted regularly +; +``` + +### Disabled + +You can disable the component with the `disabled` prop. A Checkbox could be disabled when the user has not yet performed some other required action. + +```js +import { Checkbox } from 'suomifi-ui-components'; + +I accept the terms & conditions; +``` + +### Accessing value with ref + +The value of a Checkbox can be accessed using React ref. + +```js +import { Checkbox } from 'suomifi-ui-components'; +import { useRef } from 'react'; + +const checkboxRef = useRef(); + + console.log(checkboxRef.current.checked)} +> + I accept the terms & conditions +; +``` + +### Large checkbox + +Use `variant="large"` on smaller screen sizes. + ```js import { Checkbox } from 'suomifi-ui-components'; + +I accept the terms & conditions; +``` + +### Checkboxes in group + +Use the `` component to place multiple Checkboxes into a group. The group is rendered as an HTML `
`. Both `labelText` and `groupHintText` are rendered inside the ``. + +The group can have a common `groupHintText`, and an individual Checkbox inside the group can have its own `hintText` + +If you only allow the user to select a single option, use the RadioButton component instead. + +```js +import { Checkbox, CheckboxGroup } from 'suomifi-ui-components'; import React from 'react'; -const exampleRef = React.createRef(); - -const [checked, setChecked] = React.useState(false); -<> - { - console.log(value); - }} - > - Regular checkbox that is checked and has a hint text - + + By email - - Regular checkbox with a hint text and an error message + + By phone - Large checkbox - - { - console.log(exampleRef.current); - }} - > - Checked large checkbox with a hint text and ref - + By personal visit +; +``` + +### Group error status + +The CheckboxGroup can have a `groupStatus` which is passed down to all children. An individual Checkbox inside the group can still have its own status which will override the group status. + +Always use a descriptive `groupStatusText` with the error status. It uses `aria-live="polite"`, and will be read automatically by screen readers. The `statusText` for individual Checkboxes uses `aria-live="assertive"` and could override the group status. - Disabled checkbox - - { - if (window.confirm('Change checkbox state?')) { - setChecked(checkboxState); - } - }} - > - Checkbox with controlled checked state +```js +import { Checkbox, CheckboxGroup } from 'suomifi-ui-components'; +import React from 'react'; + + + By email + + + By phone -; + + By personal visit +; ``` -### Checkboxes in group +### Optional input + +Suomi.fi inputs are required by default, but can be marked optional using the `optionalText` property. ```js import { Checkbox, CheckboxGroup } from 'suomifi-ui-components'; import React from 'react'; -<> - - - By email - - - - By phone - - - - By personal visit - - -; + + By email + + + By phone + + + By personal visit +; ``` ### Group with a tooltip +A `` component can be used with the CheckboxGroup to provide additional information. + +In terms of instructive texts, Tooltip should only be used as a "last resort" when the info text is too long for `groupHintText`. Tooltip can be used for other nice-to-know information. + +For instructions regarding how to ensure your Tooltip is accessible, please refer to the [Tooltip documentation](/#/Components/Tooltip). + ```js import { Checkbox, @@ -92,24 +216,36 @@ import { Text } from 'suomifi-ui-components'; -const labelText = 'Checkboxes with a tooltip'; +const labelText = 'How do you wish to be contacted?'; - Tooltip + Why you are being asked this information? - Text content for the tooltip + + Your contact information is used only to contact you in + matters regarding the application process, and is not shared + between third parties. More information about handling of + personal data is available in service privacy policies. + } > - Choice 1 - Choice 2 - Choice 3 + By email + + + By phone + + + By personal visit ; ``` + +### Props & methods diff --git a/src/core/Form/Checkbox/CheckboxGroup.tsx b/src/core/Form/Checkbox/CheckboxGroup.tsx index 731d76531..0faf1ad3f 100644 --- a/src/core/Form/Checkbox/CheckboxGroup.tsx +++ b/src/core/Form/Checkbox/CheckboxGroup.tsx @@ -148,9 +148,6 @@ const StyledCheckboxGroup = styled(BaseCheckboxGroup)` ${({ theme }) => baseStyles(theme)} `; -/** - * Use for grouping Checkboxes. - */ const CheckboxGroup = forwardRef( (props: CheckboxGroupProps, ref: React.Ref) => { const { id: propId, ...passProps } = props; diff --git a/src/core/Form/DateInput/DateInput.md b/src/core/Form/DateInput/DateInput.md index 60d4e8472..568962af7 100644 --- a/src/core/Form/DateInput/DateInput.md +++ b/src/core/Form/DateInput/DateInput.md @@ -1,53 +1,129 @@ -### Default DateInput +`` is used to input dates. Additionally, you can use the date picker calendar to allow users to select the date. + +Examples: + +- [Basic use](/#/Components/DateInput?id=basic-use) +- [Default value](/#/Components/DateInput?id=default-value) +- [Controlled value](/#/Components/DateInput?id=controlled-value) +- [Date picker](/#/Components/DateInput?id=date-picker) +- [MinDate & maxDate](/#/Components/DateInput?id=mindate--maxdate) +- [Validation](/#/Components/DateInput?id=validation) +- [Initial focused date in date picker](/#/Components/DateInput?id=initial-focused-date-in-date-picker) +- [Disabled dates in date picker](/#/Components/DateInput?id=disabled-dates-in-date-picker) +- [Custom dateAdapter](/#/Components/DateInput?id=custom-dateadapter) +- [Custom texts for date picker](/#/Components/DateInput?id=custom-texts-for-date-picker) +- [Accessing value with ref](/#/Components/DateInput?id=accessing-value-with-ref) +- [Small screen date picker](/#/Components/DateInput?id=small-screen-date-picker) +- [Hidden label](/#/Components/DateInput?id=hidden-label) +- [Full width and fixed width](/#/Components/DateInput?id=full-width-and-fixed-width) +- [Optional input](/#/Components/DateInput?id=optional-input) +- [Tooltip](/#/Components/DateInput?id=tooltip) + +
+ [Props & methods](/#/Components/DateInput?id=props--methods) +
+ +### Basic use + +Always use a `labelText` to label the input. + +You must also provide formatting instructions to the user. The recommended way to do this is to use `hintText`. + +The `visualPlaceholder` prop is used to apply a placeholder text to the input. For accessibility reasons, do not use placeholders for instructions. ```js import { DateInput } from 'suomifi-ui-components'; -import React from 'react'; -<> - -; +; ``` -### DateInput with DatePicker +### Default value + +Default value for the input can be set with the `defaultValue` prop. + +Note that the value is providen as a string. ```js import { DateInput } from 'suomifi-ui-components'; -import React from 'react'; -<> - -; +; ``` -### DateInput with DatePicker, smallScreen +### Controlled value + +Use the `value` prop to access and control the input's value programmatically. + +A typical use case involves setting the input's value manually in the `onChange()` function. ```js import { DateInput } from 'suomifi-ui-components'; -import React from 'react'; +import { useState } from 'react'; -<> - -; +const [controlledValue, setControlledValue] = useState(''); + + setControlledValue(value)} +/>; ``` -### DateInput with minDate, maxDate, and change validation +### Date picker + +Use the `datePickerEnabled` prop to enable the date picker calendar. + +You can set the language of the calendar with the `language` prop. Finnish (fi), Swedish (sv) and English (en) are available. + +```js +import { DateInput } from 'suomifi-ui-components'; + +; +``` + +### MinDate & maxDate + +Use the `minDate` and `maxDate` props to control the available dates in the date picker calendar. + +```js +import { DateInput } from 'suomifi-ui-components'; + +const minDate = new Date(2023, 1, 2); +const maxDate = new Date(2024, 11, 31); + +; +``` + +### Validation + +- Use the `onChange()` function to run validation logic and set the `status` and `statusText` props accordingly. +- `date-fns` is a internal dependency of `suomifi-ui-components` so you can import it for your validations. +- You can use the `debounce` prop to only run the validation when the user stops typing. ```js import { DateInput } from 'suomifi-ui-components'; import { isWithinInterval } from 'date-fns'; -import React from 'react'; +import { useState } from 'react'; const minDate = new Date(2023, 1, 2); const maxDate = new Date(2024, 11, 31); @@ -58,12 +134,12 @@ const validate = ({ value, date }) => { setStatusText(''); setStatus('default'); } else if (Number.isNaN(date.valueOf())) { - setStatusText('Format like D.M.YYYY'); + setStatusText('Invalid date format'); setStatus('error'); } else if ( !isWithinInterval(date, { start: minDate, end: maxDate }) ) { - setStatusText('Not in date range'); + setStatusText('Date is not in range'); setStatus('error'); } else if ( isWithinInterval(date, { start: minDate, end: maxDate }) @@ -73,265 +149,201 @@ const validate = ({ value, date }) => { } }; -<> - -; +; ``` -### DateInput with initialDate +### Initial focused date in date picker + +You can use the `initialDate` prop to control which date gets focused when the date picker opens. ```js import { DateInput } from 'suomifi-ui-components'; -import React from 'react'; -<> - -; +; ``` -### DateInput with dates disabled +### Disabled dates in date picker + +Use the `shouldDisableDate()` prop to disable certain dates from the date picker. Disabled dates can still be accessed through keyboard navigation but they are not selectable. ```js import { DateInput } from 'suomifi-ui-components'; import { isWeekend } from 'date-fns'; -import React from 'react'; -<> - isWeekend(date)} - /> -; + isWeekend(date)} +/>; ``` -### DateInput with custom dateAdapter +### Custom dateAdapter + +The `dateAdapter` prop enables custom formatting and parsing for the date selected with the date picker calendar. ```js import { DateInput } from 'suomifi-ui-components'; import { format, parse } from 'date-fns'; -import React from 'react'; const customDateAdapter = { format: (date) => format(date, 'y-M-d'), parse: (value) => parse(value, 'y-M-d', new Date()) }; -<> - -; +; ``` -### DatePicker with custom texts +### Custom texts for date picker -```js -import { DateInput } from 'suomifi-ui-components'; -import React from 'react'; +If you need to customize the texts in the date picker calendar, use the `datePickerTexts` prop. -<> - -; -``` - -### Label options +For a full list of customisable text options, refer to props & methods ```js import { DateInput } from 'suomifi-ui-components'; -import React from 'react'; -<> - console.log(event.target.value)} - labelText="Visible label" - /> - console.log(event.target.value)} - labelText="Hidden label" - labelMode="hidden" - visualPlaceholder="Has hidden label" - /> -; +; ``` -### Hint text +### Accessing value with ref + +The value of a DateInput can be accessed using React ref. ```js import { DateInput } from 'suomifi-ui-components'; -import React from 'react'; +import { useRef } from 'react'; -const exampleRef = React.createRef(); +const dateInputRef = useRef(); -<> - console.log(event.target.value)} - labelText="Date" - language="en" - hintText="Use format D.M.YYYY" - /> -; + console.log(dateInputRef.current.value)} +/>; ``` -### Optional text +### Small screen date picker + +Use the `smallScreen` prop to enable a version of the date picker which is designed for narrower screens. ```js import { DateInput } from 'suomifi-ui-components'; -import React from 'react'; -<> - -; +; ``` -### Ref +### Hidden label + +Label can be visually hidden with the `labelMode="hidden"` prop. ```js import { DateInput } from 'suomifi-ui-components'; import React from 'react'; -const exampleRef = React.createRef(); - -<> - { - console.log(exampleRef.current); - }} - /> -; + console.log(event.target.value)} + labelText="Beginning date" + labelMode="hidden" +/>; ``` -### Statuses +### Full width and fixed width -```js -import { DateInput } from 'suomifi-ui-components'; +You can use the `fullWidth` prop to make the input take all available horizontal space. + +You can use `wrapperProps` to set inline styles for the input. +```js +import { DateInput, Button } from 'suomifi-ui-components'; <> console.log(event.target.value)} - labelText="Default" + labelText="Beginning date" + hintText="Use format D.M.YYYY" language="en" datePickerEnabled + fullWidth /> + - ; ``` -### DateInput with changing error status +### Optional input -```js -import { DateInput, Button } from 'suomifi-ui-components'; +Suomi.fi inputs are required by default, but can be marked optional using the `optionalText` property. -const [errorState, setErrorState] = React.useState(false); -const simplifiedRegex = /[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,4}/g; -const statusText = errorState - ? 'You entered invalid data' - : undefined; -const status = errorState ? 'error' : 'default'; +```js +import { DateInput } from 'suomifi-ui-components'; { - const isValid = simplifiedRegex.test(value); - setErrorState(!isValid); - }} + optionalText="optional" + fullWidth />; ``` -### DateInput with fixed width or full width +### Tooltip -```js -import { DateInput, Button } from 'suomifi-ui-components'; -<> - +A `` component can be used with DateInput to provide additional information. - -; -``` - -### DateInput with debounced onChange event - -```js -import { DateInput } from 'suomifi-ui-components'; - -<> - console.log(change)} - debounce={800} - /> -; -``` +Do not use Tooltip for formatting instructions. Tooltip can be used for other nice-to-know information. -### DateInput with tooltip +For instructions regarding how to ensure your Tooltip is accessible, please refer to the [Tooltip documentation](/#/Components/Tooltip). ```js import { @@ -341,21 +353,28 @@ import { Text } from 'suomifi-ui-components'; -<> - - - Date - - Example text - - } - /> -; +const labelText = 'Beginning date'; + + + + What happens on the beginning date? + + + Your service will begin on the selected date during the early + morning hours, before 9.00 + + + } +/>; ``` + +### Props & methods diff --git a/src/core/Form/DateInput/DateInput.tsx b/src/core/Form/DateInput/DateInput.tsx index dfd61d17b..9924d9011 100644 --- a/src/core/Form/DateInput/DateInput.tsx +++ b/src/core/Form/DateInput/DateInput.tsx @@ -453,14 +453,6 @@ const StyledDateInput = styled( ${({ theme }) => baseStyles(theme)} `; -/** - * - * Use for user inputting date. - * Can be used as an input field or with an additional DatePicker. - * - * Props other than specified explicitly are passed on to underlying input element. For example defaultValue and onClick. - * @component - */ const DateInput = forwardRef( (props: DateInputProps, ref: React.Ref) => { const { id: propId, ...passProps } = props; diff --git a/src/core/Form/HintText/HintText.md b/src/core/Form/HintText/HintText.md index c81719206..6aa968eef 100644 --- a/src/core/Form/HintText/HintText.md +++ b/src/core/Form/HintText/HintText.md @@ -1,32 +1,42 @@ -HintText is a component that generates an accessible hint text for an adjacent element. Give the ID of the HintText as an `aria-describedby` value to the related component. Applicable form components in the library already have HintText as an integral part. +The `` component creates an accessible instruction text for an adjacent element. + +Under the hood, the `suomifi-ui-components` library uses this component extensively in form components. + +Examples: + +- [Basic use](/#/Components/HintText?id=basic-use) + +
+ [Props & methods](/#/Components/HintText?id=props--methods) +
+ +### Basic use + +Provide the id of the HintText as an `aria-describedby` value to the related component. ```js -import React from 'react'; import { HintText } from 'suomifi-ui-components'; -This is a hint regarding an adjacent input; +
+ + + Please enter your first name + + +
; ``` +### Integrated hint text + +Many components allow you to provide `hintText` as a prop. + ```js -import React from 'react'; -import { HintText } from 'suomifi-ui-components'; +import { TextInput } from 'suomifi-ui-components'; -<> -
- - - This is a hint regarding an adjacent input - - -
-; +; ``` + +### Props & methods diff --git a/src/core/Form/Label/Label.md b/src/core/Form/Label/Label.md index 1d8a3225d..6cd95921a 100644 --- a/src/core/Form/Label/Label.md +++ b/src/core/Form/Label/Label.md @@ -1,53 +1,72 @@ -Label is an accessible label component to use with custom input elements. Applicable form components in the library already have Label as an integral part. +`