From e33568339621473e497687aaa0bd924cceb87e94 Mon Sep 17 00:00:00 2001 From: Andrew Nelson Date: Fri, 19 Jan 2024 10:52:20 -0800 Subject: [PATCH 1/3] Added hook to combobox for when options change - added test - updated story to use this feature - added veggies to food list and renamed file --- .../forms/ComboBox/ComboBox.stories.tsx | 31 +++++++++++---- .../forms/ComboBox/ComboBox.test.tsx | 39 ++++++++++++++++--- src/components/forms/ComboBox/ComboBox.tsx | 4 ++ .../forms/ComboBox/{fruits.ts => foods.ts} | 6 +++ 4 files changed, 67 insertions(+), 13 deletions(-) rename src/components/forms/ComboBox/{fruits.ts => foods.ts} (94%) diff --git a/src/components/forms/ComboBox/ComboBox.stories.tsx b/src/components/forms/ComboBox/ComboBox.stories.tsx index e2861d94a9..8e73c5fe8f 100644 --- a/src/components/forms/ComboBox/ComboBox.stories.tsx +++ b/src/components/forms/ComboBox/ComboBox.stories.tsx @@ -1,11 +1,11 @@ -import React, { useRef } from 'react' +import React, { useRef, useState } from 'react' import { ComboBox, ComboBoxRef } from './ComboBox' import { Form } from '../Form/Form' import { Label } from '../Label/Label' -import { TextInput } from '../TextInput/TextInput' import { Button } from '../../Button/Button' -import { fruits } from './fruits' +import { fruits, veggies } from './foods' +import { Radio } from '../Radio/Radio' export default { title: 'Components/Combo box', @@ -112,12 +112,29 @@ export const withOtherFields = (): React.ReactElement => { label: key, })) + const veggieList = Object.entries(veggies).map(([value, key]) => ({ + value: value, + label: key, + })) + + const [options, setOptions] = useState(fruitList) + return (
- - - - + + setOptions(fruitList)} + defaultChecked> + setOptions(veggieList)}> + + ) } diff --git a/src/components/forms/ComboBox/ComboBox.test.tsx b/src/components/forms/ComboBox/ComboBox.test.tsx index 419e3dc3aa..b8803174a6 100644 --- a/src/components/forms/ComboBox/ComboBox.test.tsx +++ b/src/components/forms/ComboBox/ComboBox.test.tsx @@ -2,9 +2,9 @@ import React from 'react' import { screen, render, waitFor } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import { ComboBox, ComboBoxRef } from './ComboBox' +import { ComboBox, ComboBoxOption, ComboBoxRef } from './ComboBox' import { TextInput } from '../TextInput/TextInput' -import { fruits } from './fruits' +import { fruits, veggies } from './foods' /* Source of truth for combo box behavior is USWDS storybook examples and tests. For more: @@ -12,10 +12,19 @@ import { fruits } from './fruits' - https://github.com/uswds/uswds/tree/7a89611fe649650922e4d431b78c39fed6a867e1/spec/unit/combo-box */ -const fruitOptions = Object.entries(fruits).map(([value, key]) => ({ - value: value, - label: key, -})) +const fruitOptions: ComboBoxOption[] = Object.entries(fruits).map( + ([value, key]) => ({ + value: value, + label: key, + }) +) + +const veggieOptions: ComboBoxOption[] = Object.entries(veggies).map( + ([value, key]) => ({ + value: value, + label: key, + }) +) describe('ComboBox component', () => { it('renders the expected markup without errors', () => { @@ -87,6 +96,24 @@ describe('ComboBox component', () => { expect(comboBoxInput).toHaveValue('Avocado') }) + it('updates options when prop changes', async () => { + const Wrapper = (props: { options: ComboBoxOption[] }) => { + return ( + + ) + } + const { rerender } = render() + const comboBoxSelect = screen.getByTestId('combo-box-select') + expect(comboBoxSelect).toHaveValue(fruitOptions[0].value) + rerender() + expect(comboBoxSelect).toHaveValue(veggieOptions[0].value) + }) + describe('toggling the list', () => { it('renders all options when the list is open', async () => { const fruitAbridged = fruitOptions.slice(0, 3) diff --git a/src/components/forms/ComboBox/ComboBox.tsx b/src/components/forms/ComboBox/ComboBox.tsx index 2f6ad5c6cf..b8463c80ab 100644 --- a/src/components/forms/ComboBox/ComboBox.tsx +++ b/src/components/forms/ComboBox/ComboBox.tsx @@ -146,6 +146,10 @@ const ComboBoxForwardRef: React.ForwardRefRenderFunction< const listRef = useRef(null) const focusedItemRef = useRef(null) + useEffect(() => { + state.filteredOptions = options + }, [options]) + useEffect(() => { onChange && onChange(state.selectedOption?.value || undefined) }, [state.selectedOption]) diff --git a/src/components/forms/ComboBox/fruits.ts b/src/components/forms/ComboBox/foods.ts similarity index 94% rename from src/components/forms/ComboBox/fruits.ts rename to src/components/forms/ComboBox/foods.ts index 3bebcaf597..960f08b123 100644 --- a/src/components/forms/ComboBox/fruits.ts +++ b/src/components/forms/ComboBox/foods.ts @@ -64,3 +64,9 @@ export const fruits = { 'white currant': 'White currant', yuzu: 'Yuzu', } + +export const veggies = { + celery: 'Celery', + onion: 'Onion', + pepper: 'Pepper', +} From c8e93c126fdde036cb4fe86e294a989f6514d00a Mon Sep 17 00:00:00 2001 From: Andrew Nelson Date: Wed, 7 Feb 2024 16:46:05 -0800 Subject: [PATCH 2/3] added clear to story --- .../forms/ComboBox/ComboBox.stories.tsx | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/components/forms/ComboBox/ComboBox.stories.tsx b/src/components/forms/ComboBox/ComboBox.stories.tsx index 8e73c5fe8f..2b3e54c8b1 100644 --- a/src/components/forms/ComboBox/ComboBox.stories.tsx +++ b/src/components/forms/ComboBox/ComboBox.stories.tsx @@ -119,6 +119,13 @@ export const withOtherFields = (): React.ReactElement => { const [options, setOptions] = useState(fruitList) + const ref = useRef(null) + const handleChange = (e: React.ChangeEvent) => { + ref.current?.clearSelection() + const selection = e.target.id + setOptions(selection === 'fruit' ? fruitList : veggieList) + } + return (
@@ -126,15 +133,21 @@ export const withOtherFields = (): React.ReactElement => { name="food" id="fruit" label="Fruits" - onChange={() => setOptions(fruitList)} + onChange={handleChange} defaultChecked> setOptions(veggieList)}> + onChange={handleChange}> - + ) } From d2638a99a659386a0ab602cfdc696a303312bb9a Mon Sep 17 00:00:00 2001 From: Andrew Nelson Date: Tue, 5 Mar 2024 11:55:15 -0800 Subject: [PATCH 3/3] vite fix --- src/components/forms/ComboBox/ComboBox.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/forms/ComboBox/ComboBox.test.tsx b/src/components/forms/ComboBox/ComboBox.test.tsx index 64dfce826e..09d537f63b 100644 --- a/src/components/forms/ComboBox/ComboBox.test.tsx +++ b/src/components/forms/ComboBox/ComboBox.test.tsx @@ -103,7 +103,7 @@ describe('ComboBox component', () => { id="favorite-fruit" name="favorite-fruit" options={props.options} - onChange={jest.fn()} + onChange={vi.fn()} /> ) }