diff --git a/packages/opub-ui/src/components/Combobox/Combobox.stories.tsx b/packages/opub-ui/src/components/Combobox/Combobox.stories.tsx index f911a52a..f931ec70 100644 --- a/packages/opub-ui/src/components/Combobox/Combobox.stories.tsx +++ b/packages/opub-ui/src/components/Combobox/Combobox.stories.tsx @@ -109,6 +109,23 @@ export const Grouping: Story = { }, }; +export const GroupingMissingType: Story = { + args: { + label: 'Select an Item', + placeholder: 'e.g., Apple, Red', + list: [ + { label: 'Mango', value: 'mango' }, + { label: 'France', value: 'france' }, + { label: 'Red', value: 'red', type: 'Colours' }, + { label: 'Black', value: 'black', type: 'Colours' }, + { label: 'Apple', value: 'apple', type: 'Fruits' }, + ], + selectedValue: [], + group: true, + displaySelected: true, + }, +}; + export const Disabled: Story = { args: { label: 'Select an Item', diff --git a/packages/opub-ui/src/components/Combobox/Combobox.tsx b/packages/opub-ui/src/components/Combobox/Combobox.tsx index b95525ab..3254d82d 100644 --- a/packages/opub-ui/src/components/Combobox/Combobox.tsx +++ b/packages/opub-ui/src/components/Combobox/Combobox.tsx @@ -9,6 +9,7 @@ import { import { matchSorter } from 'match-sorter'; import type { ComboboxProps, TListItem } from '../../types/combobox'; +import { groupBy } from '../../utils'; import itemStyles from '../ActionList/ActionList.module.scss'; import { Divider } from '../Divider'; import { Tag } from '../Tag'; @@ -16,18 +17,6 @@ import { Text } from '../Text'; import { Combobox as Component } from './Atoms'; import styles from './Combobox.module.scss'; -const groupBy = function (arr: any[], criteria: string) { - return arr.reduce(function (obj, item) { - var key = item[criteria]; - // If the key doesn't exist yet, create it - if (!Object.prototype.hasOwnProperty.call(obj, key)) obj[key] = []; - // Push the value to the object - obj[key].push(item); - - return obj; - }, {}); -}; - export const Combobox = React.forwardRef( ( props: ComboboxProps & { @@ -53,11 +42,17 @@ export const Combobox = React.forwardRef( const combobox = useComboboxStore(); const matches = useMemo(() => { - const items = matchSorter(props.list, deferredValue, { + if (props.group) { + const items = matchSorter(props.list, deferredValue, { + keys: ['label', 'value', 'type'], + }); + + return Object.entries(groupBy(items, 'type')); + } + + return matchSorter(props.list, deferredValue, { keys: ['label', 'value'], }); - if (props.group) return Object.entries(groupBy(items, 'type')); - return items; }, [deferredValue]); function removeTag(value: string) { @@ -175,6 +170,13 @@ const List = ({ matches }: { matches: any }) => { }; const ListGroup = ({ matches }: { matches: any }) => { + // sorting items witout type first + matches.sort((a: any, b: any) => { + if (a[0] === 'undefined') return -1; + if (b[0] === 'undefined') return 1; + return 0; + }); + return ( <> {matches.map(([type, items]: [string, TListItem[]], i: number) => ( @@ -182,7 +184,12 @@ const ListGroup = ({ matches }: { matches: any }) => { {/* @ts-expect-error */} diff --git a/packages/opub-ui/src/utils/helpers.tsx b/packages/opub-ui/src/utils/helpers.tsx index f23e1aa6..741ab9ec 100644 --- a/packages/opub-ui/src/utils/helpers.tsx +++ b/packages/opub-ui/src/utils/helpers.tsx @@ -132,3 +132,15 @@ export const range = (len: number) => { } return arr; }; + +export const groupBy = function (arr: any[], criteria: string) { + return arr.reduce(function (obj, item) { + var key = item[criteria]; + // If the key doesn't exist yet, create it + if (!Object.prototype.hasOwnProperty.call(obj, key)) obj[key] = []; + // Push the value to the object + obj[key].push(item); + + return obj; + }, {}); +};