Skip to content

Commit

Permalink
Fix async data management for Combobox (#120)
Browse files Browse the repository at this point in the history
Co-authored-by: Brian Cooper <brian@brian-cooper.com>
  • Loading branch information
hobbescodes and coopbri authored Oct 16, 2024
1 parent 77fbad8 commit 00ef25c
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 4 deletions.
5 changes: 5 additions & 0 deletions .changeset/tender-rice-dance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@omnidev/sigil": patch
---

Allow customization of `Combobox` async data fetch preloading via `preloadItems` prop
40 changes: 40 additions & 0 deletions src/components/core/Combobox/Combobox.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,46 @@ export const AsyncItems: StoryObj = {
},
};

/**
* Asynchronously load items without preloading them. To load items, the input field must be updated.
*/
export const AsyncItemsWithoutPreloading: StoryObj = {
render: () => {
const [items, setItems] = useState<CollectionItem[]>([]);

useEffect(() => {
// simulate async data fetching
const fetchItems = async () => {
const asyncData: CollectionItem[] = await new Promise((resolve) => {
setTimeout(() => {
resolve(
fruitBasket.map(({ name, icon }, idx) => ({
label: `${name} ${icon}`,
value: name,
disabled: idx === 2,
})),
);
// simulate 1s delay
}, 1000);
});

setItems(asyncData);
};

void fetchItems();
}, []);

return (
<Combobox
{...Default.args}
preloadItems={false}
placeholder="Search..."
collection={createListCollection({ items })}
/>
);
},
};

/**
* The input field and group labels can be hidden by setting the `displayFieldLabel` and `displayGroupLabel` props to `false`, respectively.
*/
Expand Down
17 changes: 13 additions & 4 deletions src/components/core/Combobox/Combobox.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Combobox as ArkCombobox } from "@ark-ui/react/combobox";
import { useState } from "react";
import { useEffect, useState } from "react";
import { BiCheck, BiExpandVertical, BiX } from "react-icons/bi";

import Button from "components/core/Button/Button";
Expand Down Expand Up @@ -116,13 +116,17 @@ export interface ComboboxTriggerProps
extends AssignJSXStyleProps<ArkCombobox.TriggerProps> {}

export interface ComboboxProps extends ComboboxRootProps {
/** Color palette. Defaults to "accent". */
colorPalette?: ColorPalette;
/** Whether to display the input field label. */
/** Whether to display the input field label. Defaults to true. */
displayFieldLabel?: boolean;
/** Whether to display the group label contained in the dropdown. */
/** Whether to display the group label contained in the dropdown. Defaults to true. */
displayGroupLabel?: boolean;
/** Whether to display the clear trigger button. */
/** Whether to display the clear trigger button. Defaults to true. */
displayClearTrigger?: boolean;
/** Whether to preload items (useful for async data fetching). Defaults to true. If false, items will be loaded on input change. */
preloadItems?: boolean;
/** Label. */
label: {
// TODO calculate ID from singular (add dashes, lowercase, etc.)
id: string;
Expand Down Expand Up @@ -164,6 +168,7 @@ const Combobox = ({
displayFieldLabel = true,
displayGroupLabel = true,
displayClearTrigger = true,
preloadItems = true,
label,
onInputValueChange,
labelProps,
Expand Down Expand Up @@ -201,6 +206,10 @@ const Combobox = ({
onInputValueChange?.(evt);
};

useEffect(() => {
preloadItems && setFilteredItems(collection.items);
}, [collection.items, preloadItems]);

return (
<ComboboxRoot
collection={collection}
Expand Down

0 comments on commit 00ef25c

Please sign in to comment.