diff --git a/src/stories/ComboBoxAutoComplete.stories.tsx b/src/stories/ComboBoxAutoComplete.stories.tsx index 392e98e..7ff2f6b 100644 --- a/src/stories/ComboBoxAutoComplete.stories.tsx +++ b/src/stories/ComboBoxAutoComplete.stories.tsx @@ -1,13 +1,12 @@ -import type { Meta, StoryObj } from "@storybook/react"; +import { Meta, StoryObj } from "@storybook/react"; import { ComboBoxAutoComplete } from "../components/ComboBox/ComboBoxAutoComplete"; -import React from "react"; +import React, { useState, useEffect } from "react"; +import { dummyData } from '../shared/DummyData/ComboBoxDummyData'; import { useArgs } from '@storybook/preview-api'; -import { dummyData } from '../shared/DummyData/ComboBoxDummyData' - const meta: Meta = { - component: ComboBoxAutoComplete, - tags: ["autodocs"], + component: ComboBoxAutoComplete, + tags: ["autodocs"], }; export default meta; type Story = StoryObj; @@ -20,45 +19,122 @@ type Story = StoryObj; Instead, the dropdown list automatically appears and disappears based on the input and search results. */ -export const Example: Story = { - args: { - listItemRender: (x) => { return (

{x.name}

) }, - inputValue: '', - isLoading: false, - EmptyResultMessage: 'no records found', - placeholder: 'search items...', - buttonDropDownAriaKey: 'aria key here', - ariaKey: 'name', - }, +export const WithHardcodedData: Story = { + args: { + listItemRender: (x) =>

{x.name}

, + inputValue: '', + isLoading: false, + EmptyResultMessage: 'No records found', + placeholder: 'Search items...', + buttonDropDownAriaKey: 'Search items', + ariaKey: 'name', + }, - render: function Render(args) { - const [{ inputValue, dataSource }, updateArgs] = useArgs(); + render: function Render(args) { + const [{ inputValue, dataSource }, updateArgs] = useArgs(); - function onItemClick(_e: any, x: any) { - console.log(`input value selected: ${x.name}`) - updateArgs({ selectedValue: x, inputValue: x.name, dataSource: [] }); - } - - function onInputChange(e: any) { - updateArgs({ - selectedValue: null, - inputValue: e.target.value, - dataSource: e.target.value === '' ? [] : dummyData.filter(x => { return x.name.toLowerCase().includes(e.target.value.toLowerCase()) }) - }); - } + function onItemClick(_e: any, x: any) { + console.log(`Input value selected: ${x.name}`); + updateArgs({ selectedValue: x, inputValue: x.name, dataSource: [] }); + } - function onDropdownClosed() { - console.log('closed') - } + function onInputChange(e: any) { + updateArgs({ + selectedValue: null, + inputValue: e.target.value, + dataSource: e.target.value === '' + ? [] + : dummyData.filter(x => x.name.toLowerCase().includes(e.target.value.toLowerCase())), + }); + } - return ( - { onItemClick(_e, x) }} - onInputChange={onInputChange} - inputValue={inputValue} - onDropdownClosed={onDropdownClosed} - dataSource={dataSource} - /> - ) + function onDropdownClosed() { + console.log('Dropdown closed'); } + + return ( + + ); + }, }; + +/** Example using dynamic data from the DummyJSON API for the ComboBoxAutoComplete. */ +export const WithAPIData: Story = { + args: { + listItemRender: (x) =>

{x.title}

, + inputValue: '', + isLoading: false, + EmptyResultMessage: 'No products found', + placeholder: 'Search for products...', + buttonDropDownAriaKey: 'Search products', + ariaKey: 'title', + }, + + render: function Render(args) { + const [inputValue, setInputValue] = useState(''); + const [dataSource, setDataSource] = useState([]); + const [isLoading, setIsLoading] = useState(false); + const [isTyping, setIsTyping] = useState(false); // Track if the input change is due to typing. + + useEffect(() => { + if (!isTyping || inputValue.trim() === '') { + setIsTyping(false); + setDataSource([]); + return; + } + + setIsLoading(true); + const fetchProducts = async () => { + try { + const response = await fetch(`https://dummyjson.com/products/search?q=${inputValue}`); + const data = await response.json(); + setDataSource(data.products || []); + } catch (error) { + console.error('Error fetching products:', error); + setDataSource([]); + } finally { + setIsLoading(false); + } + }; + + const debounceFetch = setTimeout(fetchProducts, 300); + return () => clearTimeout(debounceFetch); + }, [inputValue, isTyping]); + + function onItemClick(_e: any, x: any) { + console.log(`Selected product: ${x.title}`); + setInputValue(x.title); + setDataSource([]); + setIsTyping(false); // Mark as not typing to prevent fetching. + } + + function onInputChange(e: any) { + setIsTyping(e.target.value !== null); // Mark as typing for input changes. + setInputValue(e.target.value); + } + + function onDropdownClosed() { + console.log('Dropdown closed'); + } + + return ( + + ); + }, + }; + \ No newline at end of file