Components
Suggestion
Suggestion is a searchable "select" with support for multiple selections.
Suggestion is under development. If you find any errors or bugs, please report them on Github or Slack.
React
Unable to parse html
const PreviewEn = () => { const DATA_PLACES = [ 'Sogndal', 'Oslo', 'Brønnøysund', 'Stavanger', 'Trondheim', 'Bergen', 'Lillestrøm', ]; return ( <Field> <Label>Select a destination</Label> <EXPERIMENTAL_Suggestion> <EXPERIMENTAL_Suggestion.Input /> <EXPERIMENTAL_Suggestion.Clear /> <EXPERIMENTAL_Suggestion.List> <EXPERIMENTAL_Suggestion.Empty> No results found </EXPERIMENTAL_Suggestion.Empty> {DATA_PLACES.map((place) => ( <EXPERIMENTAL_Suggestion.Option key={place} label={place} value={place} > {place} <div>Municipality</div> </EXPERIMENTAL_Suggestion.Option> ))} </EXPERIMENTAL_Suggestion.List> </EXPERIMENTAL_Suggestion> </Field> ); }; render(<PreviewEn />)
- filter
- Description
Filter options; boolean or a custom callback. See {@link Filter} for the callback signature.
- Type
boolean | Filter- Default
true
- creatable
- Description
Allows the user to create new items
- Type
boolean- Default
false
- onBeforeMatch
- Description
Callback when matching input value against options
- Type
((event: EventBeforeMatch) => void)
- name
- Description
The name of the associated form control
- Type
string- Default
undefined
- renderSelected
- Description
Change how the selected options are rendered inside the `Chip`.
- Type
((args: { label: string; value: string; }) => ReactNode)- Default
({ label }) => label
- multiple
- Description
Allows the user to select multiple items
- Type
boolean- Default
false
- selected
- Description
The selected item of the Suggestion. If `label` and `value` are the same, each item can be a `string`. Otherwise, each item must be a `SuggestionItem`. Using this makes the component controlled and it must be used in combination with `onSelectedChange`.
- Type
string | SuggestionItem | (string | SuggestionItem)[] | null
- defaultSelected
- Description
Default selected item when uncontrolled
- Type
string | SuggestionItem | (string | SuggestionItem)[]
- onSelectedChange
- Description
Callback when selected items changes
- Type
((value: SuggestionItem | null) => void) | ((value: SuggestionItem[]) => void)
| Name | Type | Default | Description |
|---|---|---|---|
| filter | boolean | Filter | true | Filter options; boolean or a custom callback. See {@link Filter} for the callback signature. |
| creatable | boolean | false | Allows the user to create new items |
| onBeforeMatch | ((event: EventBeforeMatch) => void) | - | Callback when matching input value against options |
| name | string | undefined | The name of the associated form control |
| renderSelected | ((args: { label: string; value: string; }) => ReactNode) | ({ label }) => label | Change how the selected options are rendered inside the `Chip`. |
| multiple | boolean | false | Allows the user to select multiple items |
| selected | string | SuggestionItem | (string | SuggestionItem)[] | null | - | The selected item of the Suggestion. If `label` and `value` are the same, each item can be a `string`. Otherwise, each item must be a `SuggestionItem`. Using this makes the component controlled and it must be used in combination with `onSelectedChange`. |
| defaultSelected | string | SuggestionItem | (string | SuggestionItem)[] | - | Default selected item when uncontrolled |
| onSelectedChange | ((value: SuggestionItem | null) => void) | ((value: SuggestionItem[]) => void) | - | Callback when selected items changes |
SuggestionClear
- aria-label
- Description
Aria label for the clear button
- Type
string- Default
Tøm
| Name | Type | Default | Description |
|---|---|---|---|
| aria-label | string | Tøm | Aria label for the clear button |
SuggestionInput
- type
- Description
Supported `input` types
- Type
"number" | "hidden" | "color" | "email" | "tel" | "search" | "text" | "url" | "date" | "time" | "checkbox" | "datetime-local" | "file" | "month" | "password" | "radio" | "week"- Default
'text'
- size
- Description
Defines the width of `Input` in count of characters.
- Type
number
- disabled
- Description
Disables element @note Avoid using if possible for accessibility purposes
- Type
boolean
- readOnly
- Description
Toggle `readOnly`
- Type
boolean
- role
- Description
Set role, i.e. `switch` when `checkbox` or `radio`
- Type
AriaRole
- data-indeterminate
- Description
Indeterminate state for checkbox inputs Only works when used inside `Field` component
- Type
boolean- Default
false
| Name | Type | Default | Description |
|---|---|---|---|
| type | "number" | "hidden" | "color" | "email" | "tel" | "search" | "text" | "url" | "date" | "time" | "checkbox" | "datetime-local" | "file" | "month" | "password" | "radio" | "week" | 'text' | Supported `input` types |
| size | number | - | Defines the width of `Input` in count of characters. |
| disabled | boolean | - | Disables element @note Avoid using if possible for accessibility purposes |
| readOnly | boolean | - | Toggle `readOnly` |
| role | AriaRole | - | Set role, i.e. `switch` when `checkbox` or `radio` |
| data-indeterminate | boolean | false | Indeterminate state for checkbox inputs Only works when used inside `Field` component |
SuggestionList
- singular
- Description
The screen reader announcement for singular Suggestion, where %d is the number of Suggestions
- Type
string- Default
%d forslag
- plural
- Description
The screen reader announcement for plural Suggestions, where %d is the number of Suggestions
- Type
string- Default
%d forslag
- autoPlacement
- Description
Whether to enable auto placement.
- Type
boolean- Default
true
| Name | Type | Default | Description |
|---|---|---|---|
| singular | string | %d forslag | The screen reader announcement for singular Suggestion, where %d is the number of Suggestions |
| plural | string | %d forslag | The screen reader announcement for plural Suggestions, where %d is the number of Suggestions |
| autoPlacement | boolean | true | Whether to enable auto placement. |
Usage
Suggestion is based on u-combobox from u-elements (github.io). It is inspected by open-ui's combobox pattern (open-ui.org).
Examples
Multiple Choice
Use multiple on Suggestion.
If you want to change how selected options are displayed, you can use renderSelected.
React
Unable to parse html
const MultipleEn = () => { const DATA_PLACES = [ 'Sogndal', 'Oslo', 'Brønnøysund', 'Stavanger', 'Trondheim', 'Bergen', 'Lillestrøm', ]; return ( <Field> <Label>Select a destination</Label> <EXPERIMENTAL_Suggestion multiple> <EXPERIMENTAL_Suggestion.Input /> <EXPERIMENTAL_Suggestion.Clear /> <EXPERIMENTAL_Suggestion.List> <EXPERIMENTAL_Suggestion.Empty> No results found </EXPERIMENTAL_Suggestion.Empty> {DATA_PLACES.map((place) => ( <EXPERIMENTAL_Suggestion.Option key={place}> {place} </EXPERIMENTAL_Suggestion.Option> ))} </EXPERIMENTAL_Suggestion.List> </EXPERIMENTAL_Suggestion> </Field> ); }; render(<MultipleEn />)
Controlled Multiple Choice
React
Unable to parse html
const ControlledMultipleEn = () => { const DATA_PLACES = [ 'Sogndal', 'Oslo', 'Brønnøysund', 'Stavanger', 'Trondheim', 'Bergen', 'Lillestrøm', ]; const [selected, setSelected] = useState<string[]>(['Oslo']); return ( <> <Field> <Label>Select destinations</Label> <EXPERIMENTAL_Suggestion multiple selected={selected} onSelectedChange={(items) => setSelected(items.map((item) => item.value)) } > <EXPERIMENTAL_Suggestion.Input /> <EXPERIMENTAL_Suggestion.Clear /> <EXPERIMENTAL_Suggestion.List> <EXPERIMENTAL_Suggestion.Empty> No results found </EXPERIMENTAL_Suggestion.Empty> {DATA_PLACES.map((place) => ( <EXPERIMENTAL_Suggestion.Option key={place} label={place} value={place} > {place} <div>Municipality</div> </EXPERIMENTAL_Suggestion.Option> ))} </EXPERIMENTAL_Suggestion.List> </EXPERIMENTAL_Suggestion> </Field> <Divider style={{ marginTop: 'var(--ds-size-4)' }} /> <Paragraph style={{ margin: 'var(--ds-size-2) 0' }}> Selected destinations: {selected.join(', ')} </Paragraph> <Button onClick={() => { setSelected(['Sogndal', 'Stavanger']); }} > Set destinations to Sogndal, Stavanger </Button> </> ); }; render(<ControlledMultipleEn />)
Adding new options
With creatable on Suggestion, a user can create new selected options by entering text in the input and pressing Enter.
React
Unable to parse html
const CreatableEn = () => { const DATA_PLACES = [ 'Sogndal', 'Oslo', 'Brønnøysund', 'Stavanger', 'Trondheim', 'Bergen', 'Lillestrøm', ]; return ( <Field> <Label>Select destination</Label> <EXPERIMENTAL_Suggestion creatable multiple> <EXPERIMENTAL_Suggestion.Input /> <EXPERIMENTAL_Suggestion.Clear /> <EXPERIMENTAL_Suggestion.List> <EXPERIMENTAL_Suggestion.Empty> No results found, press enter to add </EXPERIMENTAL_Suggestion.Empty> {DATA_PLACES.map((place) => ( <EXPERIMENTAL_Suggestion.Option key={place}> {place} </EXPERIMENTAL_Suggestion.Option> ))} </EXPERIMENTAL_Suggestion.List> </EXPERIMENTAL_Suggestion> </Field> ); }; render(<CreatableEn />)
HTML
ds-suggestion is an extension of u-combobox from u-elements.
You can find general documentation on using u-combobox at u-elements:
https://u-elements.github.io/u-elements/elements/u-combobox.
To get the Design System styling, add the class name ds-suggestion to the <ds-combobox> element.
<input> should have the ds-input class.
If you enable multiple choice, <data> should have the class name ds-chip and the data attribute data-removable="true".
CSS variables and data attributes
| Name | Value |
|---|---|
| --dsc-suggestion-option-background--selected | var(--ds-color-surface-tinted) |
| --dsc-suggestion-option-border-color | var(--ds-color-base-default) |
| --dsc-suggestion-option-border-radius | var(--ds-color-base-default) |
| --dsc-suggestion-option-checkmark-size | var(--ds-size-7) |
| --dsc-suggestion-option-checkmark-url | url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1em' height='1em' fill='none' viewBox='0 0 24 24'%3E%3Cpath fill='currentColor' fill-rule='evenodd' d='M18.998 6.94a.75.75 0 0 1 .063 1.058l-8 9a.75.75 0 0 1-1.091.032l-5-5a.75.75 0 1 1 1.06-1.06l4.438 4.437 7.471-8.405A.75.75 0 0 1 19 6.939' clip-rule='evenodd'/%3E%3C/svg%3E") |
| --dsc-suggestion-option-padding | var(--ds-size-2) var(--ds-size-3) |
| --dsc-suggestion-clear-gap | var(--ds-size-2) |
| --dsc-suggestion-clear-padding | var(--ds-size-1) |
| --dsc-suggestion-clear-size | var(--ds-size-9) |
| --dsc-suggestion-clear-icon-url | url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24'%3E%3Cpath fill='currentColor' d='M6.53 5.47a.75.75 0 0 0-1.06 1.06L10.94 12l-5.47 5.47a.75.75 0 1 0 1.06 1.06L12 13.06l5.47 5.47a.75.75 0 1 0 1.06-1.06L13.06 12l5.47-5.47a.75.75 0 0 0-1.06-1.06L12 10.94z'/%3E%3C/svg%3E") |
| --dsc-suggestion-clear-border-radius | var(--ds-border-radius-md) |
| --dsc-suggestion-clear-background--hover | var(--ds-color-surface-hover) |
| --dsc-suggestion-clear-background--active | var(--ds-color-surface-active) |
| --dsc-suggestion-list-background | var(--ds-color-surface-default) |
| --dsc-suggestion-list-border-radius | var(--ds-border-radius-md) |
| --dsc-suggestion-list-box-shadow | var(--ds-shadow-md) |
| --dsc-suggestion-list-color | var(--ds-color-text-default) |
| --dsc-suggestion-list-gap | var(--ds-size-2) |
| --dsc-suggestion-list-placement | bottom |
| --dsc-suggestion-border-width | var(--ds-border-width-default) |
| --dsc-suggestion-border-style | solid |
| --dsc-suggestion-border-color | var(--ds-color-border-default) |
| --dsc-suggestion-chip-gap | var(--ds-size-1) |
| --dsc-suggestion-chip-background | var(--ds-color-base-default) |
| --dsc-suggestion-chip-background--hover | var(--ds-color-base-hover) |
| --dsc-suggestion-chip-border-width | var(--ds-border-width-default) |
| --dsc-suggestion-chip-height | var(--ds-size-8) |
| --dsc-suggestion-chip-font-size | var(--ds-body-sm-font-size) |
| --dsc-suggestion-chip-border-style | solid |
| --dsc-suggestion-chip-border-color | transparent |
| --dsc-suggestion-chip-border-radius | var(--ds-border-radius-full) |
| --dsc-suggestion-chip-padding | 0 var(--ds-size-3) |
| --dsc-suggestion-chip-color | var(--ds-color-base-contrast-default) |
| --dsc-suggestion-chip-icon-url | url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1em' height='1em' fill='none' viewBox='0 0 24 24'%3E%3Cpath fill='currentColor' d='M6.53 5.47a.75.75 0 0 0-1.06 1.06L10.94 12l-5.47 5.47a.75.75 0 1 0 1.06 1.06L12 13.06l5.47 5.47a.75.75 0 1 0 1.06-1.06L13.06 12l5.47-5.47a.75.75 0 0 0-1.06-1.06L12 10.94z'/%3E%3C/svg%3E") |
| --dsc-suggestion-chip-icon-size | var(--ds-size-7) |
| --dsc-suggestion-chip-input-size | var(--ds-size-5) |
| --dsc-suggestion-chip-spacing | calc((var(--dsc-suggestion-chip-height) - var(--dsc-suggestion-chip-input-size))/2) |
| --dsc-button-size | var(--dsc-suggestion-clear-size) |
| Name | Value |
|---|---|
| data-multiple | false |
| data-overscroll | contain |
| data-floating| | top, right, bottom, left |
| data-empty |
Suggestion is based on u-combobox from u-elements (github.io).
It is inspected by open-ui's combobox pattern (open-ui.org).