diff --git a/apps/design-system/content/docs/fragments/multi-select.mdx b/apps/design-system/content/docs/fragments/multi-select.mdx index 73e09df3899..e20164f4593 100644 --- a/apps/design-system/content/docs/fragments/multi-select.mdx +++ b/apps/design-system/content/docs/fragments/multi-select.mdx @@ -60,16 +60,16 @@ creatable: `boolean` -### Badge Limit +### Badge limit badgeLimit: `number` | `"wrap"`. `badgeLimit` prop on the `MultiSelectorTrigger` component can be used to limit the number of badges displayed. -### Badge Limit="wrap" +### Wrapped badge limit -`badgeLimit` prop can also be "wrap" to wrap the badges to the next line. +Combine `badgeLimit` with `wrapBadges` to limit the number of badges and allow them to wrap onto additional lines. Use `badgeLimit="wrap"` to show and wrap every selected badge. diff --git a/apps/design-system/registry/default/example/multi-select-badge-limit-wrap.tsx b/apps/design-system/registry/default/example/multi-select-badge-limit-wrap.tsx index 7b1b8b283ad..fae3733b2ec 100644 --- a/apps/design-system/registry/default/example/multi-select-badge-limit-wrap.tsx +++ b/apps/design-system/registry/default/example/multi-select-badge-limit-wrap.tsx @@ -1,4 +1,6 @@ +import { Minus, Plus } from 'lucide-react' import { useState } from 'react' +import { Button } from 'ui' import { MultiSelector, MultiSelectorContent, @@ -15,30 +17,42 @@ export default function MultiSelectDemo() { 'Date', 'Elderberrie', ]) + const [limit, setLimit] = useState(3) return ( - - - - - Apple - Banana - Cherry - Date - Elderberrie - Fig - Grape - Kiwi - Mango - Strawberry - - - +
+
+ + Limit: {limit} + +
+ + + + + Apple + Banana + Cherry + Date + Elderberrie + Fig + Grape + Kiwi + Mango + Strawberry + + + +
) } diff --git a/packages/ui-patterns/src/multi-select/multi-select.test.tsx b/packages/ui-patterns/src/multi-select/multi-select.test.tsx index a3278b7d6f6..9c50c5284b4 100644 --- a/packages/ui-patterns/src/multi-select/multi-select.test.tsx +++ b/packages/ui-patterns/src/multi-select/multi-select.test.tsx @@ -97,6 +97,24 @@ describe('multi-select', () => { expect(badge).toHaveClass('normal-case', 'tracking-normal') }) + it('supports wrapping badges with a numeric badge limit', () => { + render( + undefined} + > + + + ) + + const trigger = screen.getByRole('combobox') + expect(trigger.firstElementChild).toHaveClass('flex-wrap') + expect(trigger).toHaveTextContent('Apple') + expect(trigger).toHaveTextContent('Banana') + expect(trigger).toHaveTextContent('+3') + expect(trigger).not.toHaveTextContent('Cherry') + }) + it('opens the dropdown when the MultiSelectorTrigger is clicked', () => { render() diff --git a/packages/ui-patterns/src/multi-select/multi-select.tsx b/packages/ui-patterns/src/multi-select/multi-select.tsx index 6771530488d..df0bd27b5e7 100644 --- a/packages/ui-patterns/src/multi-select/multi-select.tsx +++ b/packages/ui-patterns/src/multi-select/multi-select.tsx @@ -223,6 +223,7 @@ export interface MultiSelectorTriggerProps extends React.HTMLAttributes { if (!inputRef?.current || !badgesRef.current) return - if (IS_BADGE_LIMIT_WRAP) { - setVisibleBadges(values) - setExtraBadgesCount(0) - } else { + if (IS_NUMERIC_LIMIT) { setVisibleBadges(values.slice(0, badgeLimit)) setExtraBadgesCount(Math.max(0, values.length - badgeLimit)) + } else { + setVisibleBadges(values) + setExtraBadgesCount(0) } }, [values, badgeLimit]) @@ -427,8 +429,8 @@ const MultiSelectorTrigger = React.forwardRef @@ -478,7 +480,7 @@ const MultiSelectorTrigger = React.forwardRef