Skip to content

Commit 1b01b38

Browse files
committed
feat(Suggestion): add count display mode for multiple selection
1 parent 13cce03 commit 1b01b38

3 files changed

Lines changed: 77 additions & 0 deletions

File tree

packages/css/src/suggestion.css

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,37 @@
6262
display: none; /* Hide data elements when not in multiple mode */
6363
}
6464

65+
/* Count display mode: hide chips, show count label inside input */
66+
&[data-count] data {
67+
display: none;
68+
}
69+
70+
/* NOTE: This styling should be reflected in tag.css */
71+
&[data-count]::before {
72+
content: attr(data-count) ' ' var(--dsc-count-label, 'valgt');
73+
position: absolute;
74+
inset-inline-start: var(--ds-size-3);
75+
top: 50%;
76+
translate: 0 -50%;
77+
pointer-events: none;
78+
z-index: 1;
79+
align-items: center;
80+
background: var(--ds-color-surface-tinted);
81+
border: solid transparent var(--ds-border-width-default);
82+
border-radius: var(--ds-border-radius-sm);
83+
box-sizing: border-box;
84+
color: var(--ds-color-text-default);
85+
font-size: var(--ds-body-sm-font-size);
86+
line-height: var(--ds-line-height-sm);
87+
min-height: var(--ds-size-8);
88+
padding: 0 var(--ds-size-2);
89+
display: inline-flex;
90+
}
91+
92+
&[data-count]:focus-within::before {
93+
display: none;
94+
}
95+
6596
/* NOTE: This styling should be reflected in chip.css */
6697
& > data {
6798
align-items: center;

packages/react/src/components/suggestion/suggestion.stories.tsx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,36 @@ Multiple.args = {
507507
multiple: true,
508508
};
509509

510+
export const MultipleCount: StoryFn<SuggestionMultipleProps> = (args) => {
511+
const [selected, setSelected] = useState<string[]>([]);
512+
513+
return (
514+
<Field>
515+
<Label>Velg destinasjoner</Label>
516+
<Suggestion
517+
{...args}
518+
multiple
519+
display='count'
520+
selected={selected}
521+
onSelectedChange={(items) =>
522+
setSelected(items.map((item) => item.value))
523+
}
524+
>
525+
<Suggestion.Input />
526+
<Suggestion.Clear />
527+
<Suggestion.List>
528+
<Suggestion.Empty>Tomt</Suggestion.Empty>
529+
{DATA_PLACES.map((place) => (
530+
<Suggestion.Option key={place} label={place} value={place}>
531+
{place}
532+
</Suggestion.Option>
533+
))}
534+
</Suggestion.List>
535+
</Suggestion>
536+
</Field>
537+
);
538+
};
539+
510540
export const InDetails: StoryFn<typeof Suggestion> = (args) => {
511541
return (
512542
<Details>

packages/react/src/components/suggestion/suggestion.tsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,17 @@ type SuggestionBaseProps = {
9292
* @default ({ label }) => label
9393
*/
9494
renderSelected?: (args: { label: string; value: string }) => ReactNode;
95+
/**
96+
* How selected items are displayed when `multiple` is true.
97+
*
98+
* - `chips` renders removable chips for each selected item (default)
99+
* - `count` hides chips and shows a count label (e.g. "2 valgt")
100+
*
101+
* Customize the label text with the `--dsc-count-label` CSS variable.
102+
*
103+
* @default 'chips'
104+
*/
105+
display?: 'chips' | 'count';
95106
} & Omit<HTMLAttributes<DSSuggestionElement>, 'defaultValue'>;
96107

97108
type SuggestionValueProps<T extends { multiple: boolean }> = {
@@ -169,6 +180,7 @@ export const Suggestion = forwardRef<DSSuggestionElement, SuggestionProps>(
169180
className,
170181
creatable = false,
171182
defaultSelected,
183+
display = 'chips',
172184
filter = true,
173185
multiple = false,
174186
name,
@@ -266,6 +278,10 @@ export const Suggestion = forwardRef<DSSuggestionElement, SuggestionProps>(
266278
<ds-suggestion
267279
data-multiple={multiple || undefined}
268280
data-creatable={creatable || undefined}
281+
data-count={
282+
(multiple && display === 'count' && selectedItems.length) ||
283+
undefined
284+
}
269285
class={cl('ds-suggestion', className)} // Using "class" since React does not translate className on custom elements
270286
ref={mergedRefs}
271287
suppressHydrationWarning // Since <ds-suggestion> adds attributes

0 commit comments

Comments
 (0)