From 6c411351349734ba69abad099bf82a10f27d9c35 Mon Sep 17 00:00:00 2001 From: Jordan Young Date: Fri, 2 May 2025 11:21:55 -0400 Subject: [PATCH 1/2] feat(mui-controlled-form): add onChange call when auto-setting option --- .../src/lib/AsyncAutocomplete.stories.tsx | 5 ++- .../src/lib/AsyncAutocomplete.test.tsx | 45 ++++++++++++++++--- .../src/lib/AsyncAutocomplete.tsx | 11 ++--- 3 files changed, 48 insertions(+), 13 deletions(-) diff --git a/packages/controlled-form/src/lib/AsyncAutocomplete.stories.tsx b/packages/controlled-form/src/lib/AsyncAutocomplete.stories.tsx index 4d01233b2c..41bf604e2d 100644 --- a/packages/controlled-form/src/lib/AsyncAutocomplete.stories.tsx +++ b/packages/controlled-form/src/lib/AsyncAutocomplete.stories.tsx @@ -114,7 +114,7 @@ export const _ControlledAsyncAutoCompleteMultiple: StoryObj val.label, - isOptionEqualToValue: (option, value) => option.label === value.label, + isOptionEqualToValue: (option: Option, value: Option) => option.label === value.label, loadOptions, limit: 5, queryKey: 'example', @@ -165,5 +165,8 @@ export const _ControlledAsyncAutoCompleteDefaultToOnlyOption: StoryObj { + console.log(value); + }, }, }; diff --git a/packages/controlled-form/src/lib/AsyncAutocomplete.test.tsx b/packages/controlled-form/src/lib/AsyncAutocomplete.test.tsx index 39660a2840..206918a35d 100644 --- a/packages/controlled-form/src/lib/AsyncAutocomplete.test.tsx +++ b/packages/controlled-form/src/lib/AsyncAutocomplete.test.tsx @@ -1,4 +1,4 @@ -import { fireEvent, render, waitFor } from '@testing-library/react'; +import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import AvApi, { ApiConfig } from '@availity/api-axios'; // eslint-disable-next-line @nx/enforce-module-boundaries @@ -66,7 +66,7 @@ describe('ControlledAsyncAutocomplete', () => { }); test('should loadOptions successfully', async () => { - const screen = render( + render( { }); test('should set the value and submit the form data', async () => { - const screen = render( + render( { }); }); + test('should default to first option when prop is true', async () => { + const mockOnChange = jest.fn(); + + render( + + + val.label} + loadOptions={loadOptions} + limit={10} + queryKey="example" + defaultToFirstOption + onChange={mockOnChange} + /> + + + ); + + const dropdown = screen.getByRole('combobox'); + fireEvent.click(dropdown); + fireEvent.keyDown(dropdown, { key: 'ArrowDown' }); + + await waitFor(() => screen.getByText('Option 1')); + + await waitFor(() => { + expect(mockOnChange).toHaveBeenCalled(); + }); + }); + describe('when using rules', () => { describe('when required', () => { test('should indicate it is required when passing a string', async () => { - const screen = render( + render( { }); test('should indicate it is required when passing an object with true', async () => { - const screen = render( + render( { }); test('should not indicate it is required when passing an object with false', async () => { - const screen = render( + render( { }); }); }); -}); \ No newline at end of file +}); diff --git a/packages/controlled-form/src/lib/AsyncAutocomplete.tsx b/packages/controlled-form/src/lib/AsyncAutocomplete.tsx index 7f5df613ff..3dda74ef5b 100644 --- a/packages/controlled-form/src/lib/AsyncAutocomplete.tsx +++ b/packages/controlled-form/src/lib/AsyncAutocomplete.tsx @@ -77,12 +77,13 @@ export const ControlledAsyncAutocomplete = < loadOptions={async (offset, limit, inputValue) => { const { options, hasMore, offset: returnedOffsetValue } = await rest.loadOptions(offset, limit, inputValue); - if (defaultToFirstOption && offset === 0) { - setValue(name, rest.multiple ? [options[0]] : options[0]); - } + const shouldAssignValue = + (defaultToFirstOption && offset === 0) || (defaultToOnlyOption && offset === 0 && options.length === 1); - if (defaultToOnlyOption && offset === 0 && options.length === 1) { - setValue(name, rest.multiple ? [options[0]] : options[0]); + if (shouldAssignValue) { + const newValue = rest.multiple ? [options[0]] : options[0]; + setValue(name, newValue); + onChange(newValue); } return { options, hasMore, offset: returnedOffsetValue }; From 0a03b7bf215f085491b3aee2b8590c84b49e91b0 Mon Sep 17 00:00:00 2001 From: Jordan Young Date: Fri, 2 May 2025 11:51:21 -0400 Subject: [PATCH 2/2] feat(mui-controlled-form): add onChange call when auto-setting option --- .../src/lib/AsyncAutocomplete.test.tsx | 42 ++++--------------- 1 file changed, 7 insertions(+), 35 deletions(-) diff --git a/packages/controlled-form/src/lib/AsyncAutocomplete.test.tsx b/packages/controlled-form/src/lib/AsyncAutocomplete.test.tsx index 206918a35d..df77b0dcb7 100644 --- a/packages/controlled-form/src/lib/AsyncAutocomplete.test.tsx +++ b/packages/controlled-form/src/lib/AsyncAutocomplete.test.tsx @@ -1,4 +1,4 @@ -import { fireEvent, render, screen, waitFor } from '@testing-library/react'; +import { fireEvent, render, screen, waitFor, act } from '@testing-library/react'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import AvApi, { ApiConfig } from '@availity/api-axios'; // eslint-disable-next-line @nx/enforce-module-boundaries @@ -82,10 +82,13 @@ describe('ControlledAsyncAutocomplete', () => { ); const dropdown = screen.getByRole('combobox'); - fireEvent.click(dropdown); - fireEvent.keyDown(dropdown, { key: 'ArrowDown' }); - await waitFor(() => expect(screen.getByText('Option 1')).toBeDefined()); + act(() => { + fireEvent.click(dropdown); + fireEvent.keyDown(dropdown, { key: 'ArrowDown' }); + }); + + await waitFor(() => expect(screen.getByText('Option 0')).toBeDefined()); }); test('should set the value and submit the form data', async () => { @@ -124,37 +127,6 @@ describe('ControlledAsyncAutocomplete', () => { }); }); - test('should default to first option when prop is true', async () => { - const mockOnChange = jest.fn(); - - render( - - - val.label} - loadOptions={loadOptions} - limit={10} - queryKey="example" - defaultToFirstOption - onChange={mockOnChange} - /> - - - ); - - const dropdown = screen.getByRole('combobox'); - fireEvent.click(dropdown); - fireEvent.keyDown(dropdown, { key: 'ArrowDown' }); - - await waitFor(() => screen.getByText('Option 1')); - - await waitFor(() => { - expect(mockOnChange).toHaveBeenCalled(); - }); - }); - describe('when using rules', () => { describe('when required', () => { test('should indicate it is required when passing a string', async () => {