diff --git a/.changeset/afraid-glasses-relax.md b/.changeset/afraid-glasses-relax.md new file mode 100644 index 0000000000..20b57c70c1 --- /dev/null +++ b/.changeset/afraid-glasses-relax.md @@ -0,0 +1,5 @@ +--- +"@marigold/docs": patch +--- + +docs: change multiselect recipe diff --git a/docs/content/concepts/multiple-selection.mdx b/docs/content/concepts/multiple-selection.mdx index 48cbbb0b9e..f2c1f21236 100644 --- a/docs/content/concepts/multiple-selection.mdx +++ b/docs/content/concepts/multiple-selection.mdx @@ -45,7 +45,7 @@ It allows users to choose multiple options by clicking on the items in the list #### Examples - + ### TagGroup diff --git a/docs/content/concepts/multiselect.demo.tsx b/docs/content/concepts/multiselect.demo.tsx deleted file mode 100644 index 72c76b28e1..0000000000 --- a/docs/content/concepts/multiselect.demo.tsx +++ /dev/null @@ -1,18 +0,0 @@ -/** - * INFO: This is an alpha release for the component. - * The API might change in future. - */ -import { Multiselect } from '@marigold/components'; - -export default () => { - return ( - - 🍎 Apple - 🍌 Banana - 🍊 Orange - 🍓 Strawberry - 🥭 Mango - 🍉 Watermelon - - ); -}; diff --git a/docs/content/recipes/multiselect-basic.demo.tsx b/docs/content/recipes/multiselect-basic.demo.tsx index 4ed79bb57f..ab21858a6c 100644 --- a/docs/content/recipes/multiselect-basic.demo.tsx +++ b/docs/content/recipes/multiselect-basic.demo.tsx @@ -1,4 +1,101 @@ -import { Multiselect } from '@marigold/components'; +import { Children, ReactNode, useState } from 'react'; + +import { + ComboBox, + ComboBoxProps, + Tag, + useListData, +} from '@marigold/components'; + +type Key = string | number; +export interface MultiSelectItemProps { + id: Key; + children: ReactNode; +} + +const Item = (_: MultiSelectItemProps) => null; + +export interface MultiSelectProps extends ComboBoxProps { + label?: string; + children?: ReactNode; + defaultSelectedKeys?: 'all' | Iterable; +} + +const Multiselect = ({ label, children, ...props }: MultiSelectProps) => { + const items = Children.map(children, ({ props }: any) => props); + + const list = useListData({ + initialItems: items, + initialSelectedKeys: props.defaultSelectedKeys, + getKey: item => item.id, + }); + + const selected = list.items.filter(item => + list.selectedKeys === 'all' ? true : list.selectedKeys.has(item.id) + ); + const unselected = list.items.filter(item => !selected.includes(item)); + + const setUnselected = (keys: Set) => { + const next: Set = + list.selectedKeys === 'all' ? new Set(items) : new Set(list.selectedKeys); + + if (list.selectedKeys !== 'all') { + keys.forEach(key => { + next.delete(key); + }); + } + + list.setSelectedKeys(next); + }; + + const [value, setValue] = useState(''); + const selectItem = (key: Key) => { + if (list.selectedKeys !== 'all') { + const next = list.selectedKeys.add(key); + list.setSelectedKeys(next); + } + + const input = document.activeElement as HTMLInputElement; + setTimeout(() => { + setValue(''); + }, 0); + input.focus(); + }; + + return ( +
+ null} + > + {(item: MultiSelectItemProps) => ( + + {item.children} + + )} + + + {unselected.map((item: MultiSelectItemProps) => ( + + {item.children} + + ))} + +
+ ); +}; + +Multiselect.Item = Item; export default () => { return ( diff --git a/docs/content/recipes/multiselect-recipe.mdx b/docs/content/recipes/multiselect-recipe.mdx index 39f39f725c..9f6a3737a3 100644 --- a/docs/content/recipes/multiselect-recipe.mdx +++ b/docs/content/recipes/multiselect-recipe.mdx @@ -6,16 +6,6 @@ badge: new The `` component combines a text input with a listbox, allowing users to filter a list of options to items matching a query, selecting multiple items or adding a new value. -## Usage - -### Import - -To import the component you just have to use this code below. - -```tsx -import { MultiSelect } from '@marigold/components'; -``` - ## Example You can use the `MultiSelect` to enable users to select multiple values and search for them.