Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ Enable the `multiple` property for multiple selection of values.
<Canvas of={ComponentStories.Multiple} />

### Selection display
Use the `selectionDisplay` prop to control how selected items are displayed in the input field. The default is `summary`, which shows a count of selected items. Use `chips` to display each selected item as a removable chip.
Use the `selectionDisplay` prop to control how selected items are displayed in the input field. The default is `summary`, which shows a count of selected items. Use `chips` to display each selected item as a removable chip. If you want to limit the amount of chips shown, use the `chipCount` prop

<Canvas of={ComponentStories.SelectionDisplay} />

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ Multiple.args = {
export const SelectionDisplay: StoryFn<AutocompleteProps<MyOptionType>> = (
args,
) => {
const { options } = args
const { options, chipCount } = args

return (
<>
Expand All @@ -223,6 +223,7 @@ export const SelectionDisplay: StoryFn<AutocompleteProps<MyOptionType>> = (
multiple
placeholder="Select stocks"
optionLabel={optionLabel}
chipCount={chipCount}
selectionDisplay="chips"
initialSelectedOptions={[options[0], options[1]]}
/>
Expand All @@ -232,6 +233,7 @@ export const SelectionDisplay: StoryFn<AutocompleteProps<MyOptionType>> = (
SelectionDisplay.storyName = 'Selection display'
SelectionDisplay.args = {
options: stocks,
chipCount: 2,
}

export const ControlledSingleSelect: StoryFn<
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -945,6 +945,25 @@ describe('Autocomplete: Scroll position and navigation memory', () => {
expect(chip2).toBeInTheDocument()
})

it('Shows + N more chips if chipCount is set', async () => {
render(
<Autocomplete
label={labelText}
options={items}
multiple
selectionDisplay="chips"
chipCount={1}
initialSelectedOptions={['One', 'Two']}
/>,
)

const chip1 = await screen.findByText('One')
const chip2 = await screen.findByText('+1 more')

expect(chip1).toBeInTheDocument()
expect(chip2).toBeInTheDocument()
})

it('Removes chip when clicking the chip remove button', async () => {
const handleChange = jest.fn()
render(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ export type AutocompleteProps<T = string> = {
* @default 'summary'
*/
selectionDisplay?: 'chips' | 'summary'
/** Amount of values to list in chips (only relevant if selectionDisplay = 'chips')
* When left blank, all values will be shown as chips
* @default undefined
*/
chipCount?: number
/** Callback for the selected item change
* changes.selectedItems gives the selected items
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export const MultipleInput = () => {
hideClearButton,
restHtmlProps,
consolidatedEvents,
chipCount,
inputRef,
} = useAutocompleteContext()

Expand All @@ -55,7 +56,10 @@ export const MultipleInput = () => {
if (isKeyboardEvent && selectedItems.length > 1) {
const isLastChip = index === selectedItems.length - 1
const nextItem = selectedItems[isLastChip ? index - 1 : index + 1]
chipRefs.current.get(getLabel(nextItem))?.focus()
const nextRef = chipRefs.current.get(getLabel(nextItem))
// Fall back to input when next chip is hidden (beyond chipCount)
if (nextRef) nextRef.focus()
else inputRef.current?.focus()
} else if (!isKeyboardEvent) {
inputRef.current?.focus()
}
Expand Down Expand Up @@ -92,13 +96,35 @@ export const MultipleInput = () => {
>
<ChipContainer $density={density}>
{selectionDisplay === 'chips' &&
selectedItems.map((item, index) => (
selectedItems
.slice(0, chipCount > 0 ? chipCount : undefined)
.map((item, index) => (
<Chip
key={getLabel(item)}
ref={(el) => {
if (el) chipRefs.current.set(getLabel(item), el)
else chipRefs.current.delete(getLabel(item))
}}
style={{
outline:
'1px solid var(--eds_interactive_primary__resting, rgba(0, 112, 121, 1))',
...(density === 'compact' && {
height: '16px',
fontSize: '12px',
gridGap: '0px',
}),
}}
onDelete={handleChipDelete(item, index)}
onClick={handleChipClick(item, index)}
disabled={readOnly}
>
{getLabel(item)}
</Chip>
))}
{selectionDisplay === 'chips' &&
chipCount &&
selectedItems.length > chipCount && (
<Chip
key={getLabel(item)}
ref={(el) => {
if (el) chipRefs.current.set(getLabel(item), el)
else chipRefs.current.delete(getLabel(item))
}}
style={{
outline:
'1px solid var(--eds_interactive_primary__resting, rgba(0, 112, 121, 1))',
Expand All @@ -108,13 +134,11 @@ export const MultipleInput = () => {
gridGap: '0px',
}),
}}
onDelete={handleChipDelete(item, index)}
onClick={handleChipClick(item, index)}
disabled={readOnly}
>
{getLabel(item)}
+{selectedItems.length - chipCount} more
</Chip>
))}
)}
<UnstyledInput
{...restHtmlProps}
{...inputProps}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export const useAutocomplete = <T>({
onInputChange,
selectedOptions: _selectedOptions,
selectionDisplay = 'summary',
chipCount,
multiple,
itemToKey: _itemToKey,
itemCompare: _itemCompare,
Expand Down Expand Up @@ -699,6 +700,7 @@ export const useAutocomplete = <T>({
onInputChange,
selectedOptions,
selectionDisplay,
chipCount,
itemToKey,
itemCompare,
allowSelectAll,
Expand Down
Loading