@12-apps/ui 1.4.1 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (229) hide show
  1. package/package.json +17 -8
  2. package/src/button/index.ts +1 -0
  3. package/src/social-login-button/index.ts +1 -0
  4. package/src/{social-login-button.tsx → social-login-button/social-login-button.tsx} +5 -5
  5. package/src/user-avatar/index.ts +1 -0
  6. package/src/{user-avatar.tsx → user-avatar/user-avatar.tsx} +4 -4
  7. package/eslint.config.js +0 -77
  8. package/src/__tests__/data-grid.test.tsx +0 -125
  9. package/src/__tests__/package-wiring.test.ts +0 -41
  10. package/src/__tests__/setup.ts +0 -1
  11. package/src/__tests__/social-login-button.test.tsx +0 -186
  12. package/src/__tests__/user-avatar.test.tsx +0 -195
  13. package/src/__tests__/viewport.test.ts +0 -50
  14. package/src/components/command/__tests__/command.test.tsx +0 -112
  15. package/src/components/data-display/Alert/Alert.stories.tsx +0 -559
  16. package/src/components/data-display/Alert/Alert.test.stories.tsx +0 -707
  17. package/src/components/data-display/AlertDialog/AlertDialog.stories.tsx +0 -362
  18. package/src/components/data-display/AlertDialog/AlertDialog.test.stories.tsx +0 -753
  19. package/src/components/data-display/AsyncStateContainer/AsyncStateContainer.stories.tsx +0 -230
  20. package/src/components/data-display/AsyncStateContainer/AsyncStateContainer.test.stories.tsx +0 -270
  21. package/src/components/data-display/Avatar/Avatar.stories.tsx +0 -721
  22. package/src/components/data-display/Avatar/Avatar.test.stories.tsx +0 -822
  23. package/src/components/data-display/Badge/Badge.stories.tsx +0 -1134
  24. package/src/components/data-display/Badge/Badge.test.stories.tsx +0 -1194
  25. package/src/components/data-display/Banner/Banner.stories.tsx +0 -528
  26. package/src/components/data-display/Banner/Banner.test.stories.tsx +0 -503
  27. package/src/components/data-display/Carousel/Carousel.stories.tsx +0 -607
  28. package/src/components/data-display/Carousel/Carousel.test.stories.tsx +0 -691
  29. package/src/components/data-display/Chart/Chart.stories.tsx +0 -568
  30. package/src/components/data-display/Chart/Chart.test.stories.tsx +0 -174
  31. package/src/components/data-display/Chart/SpecChart.stories.tsx +0 -150
  32. package/src/components/data-display/Chart/SpecChart.test.stories.tsx +0 -56
  33. package/src/components/data-display/Chart/__tests__/SpecChart.test.tsx +0 -60
  34. package/src/components/data-display/Chart/__tests__/chart-format.test.ts +0 -43
  35. package/src/components/data-display/Chart/__tests__/chart-spec.test.ts +0 -119
  36. package/src/components/data-display/Chip/Chip.stories.tsx +0 -252
  37. package/src/components/data-display/Chip/Chip.test.stories.tsx +0 -266
  38. package/src/components/data-display/DataGrid/DataGrid.stories.tsx +0 -515
  39. package/src/components/data-display/DataGrid/DataGrid.test.stories.tsx +0 -653
  40. package/src/components/data-display/DataViews/__tests__/DataViewsGrid.test.tsx +0 -271
  41. package/src/components/data-display/DataViews/__tests__/DataViewsTableBase.test.tsx +0 -134
  42. package/src/components/data-display/DataViews/__tests__/SaveViewModal.test.tsx +0 -83
  43. package/src/components/data-display/DataViews/__tests__/data-views-filter.test.ts +0 -115
  44. package/src/components/data-display/DataViews/__tests__/data-views-preview.test.ts +0 -53
  45. package/src/components/data-display/DataViews/__tests__/range-pill.test.tsx +0 -114
  46. package/src/components/data-display/DataViews/base-card.stories.tsx +0 -136
  47. package/src/components/data-display/DescriptionItem/DescriptionItem.stories.tsx +0 -254
  48. package/src/components/data-display/EmptyState/EmptyState.stories.tsx +0 -282
  49. package/src/components/data-display/EmptyState/EmptyState.test.stories.tsx +0 -441
  50. package/src/components/data-display/ErrorState/ErrorState.stories.tsx +0 -110
  51. package/src/components/data-display/ErrorState/ErrorState.test.stories.tsx +0 -133
  52. package/src/components/data-display/HoverCard/HoverCard.stories.tsx +0 -650
  53. package/src/components/data-display/HoverCard/HoverCard.test.stories.tsx +0 -929
  54. package/src/components/data-display/InteractiveTooltip/InteractiveTooltip.stories.tsx +0 -411
  55. package/src/components/data-display/LazyImage/LazyImage.stories.tsx +0 -387
  56. package/src/components/data-display/Lightbox/Lightbox.stories.tsx +0 -315
  57. package/src/components/data-display/Lightbox/Lightbox.test.stories.tsx +0 -598
  58. package/src/components/data-display/LoadingState/LoadingState.stories.tsx +0 -124
  59. package/src/components/data-display/LoadingState/LoadingState.test.stories.tsx +0 -99
  60. package/src/components/data-display/MapPreview/MapPreview.stories.tsx +0 -458
  61. package/src/components/data-display/MapPreview/MapPreview.test.stories.tsx +0 -394
  62. package/src/components/data-display/Popover/Popover.stories.tsx +0 -295
  63. package/src/components/data-display/Popover/Popover.test.stories.tsx +0 -1162
  64. package/src/components/data-display/Progress/Progress.stories.tsx +0 -481
  65. package/src/components/data-display/Progress/Progress.test.stories.tsx +0 -2070
  66. package/src/components/data-display/SectionOnboarding/SectionOnboarding.stories.tsx +0 -160
  67. package/src/components/data-display/SectionOnboarding/SectionOnboarding.test.stories.tsx +0 -190
  68. package/src/components/data-display/Sheet/Sheet.stories.tsx +0 -883
  69. package/src/components/data-display/Sheet/Sheet.test.stories.tsx +0 -1101
  70. package/src/components/data-display/StatCard/StatCard.stories.tsx +0 -167
  71. package/src/components/data-display/StatCard/StatCard.test.stories.tsx +0 -240
  72. package/src/components/data-display/Stepper/Stepper.stories.tsx +0 -540
  73. package/src/components/data-display/Stepper/Stepper.test.stories.tsx +0 -600
  74. package/src/components/data-display/Table/Table.stories.tsx +0 -803
  75. package/src/components/data-display/Table/Table.test.stories.tsx +0 -369
  76. package/src/components/data-display/Timeline/Timeline.stories.tsx +0 -442
  77. package/src/components/data-display/Timeline/Timeline.test.stories.tsx +0 -930
  78. package/src/components/data-display/TimingDiagram/TimingDiagram.stories.tsx +0 -475
  79. package/src/components/data-display/TimingDiagram/TimingDiagram.test.stories.tsx +0 -734
  80. package/src/components/data-display/Tooltip/Tooltip.stories.tsx +0 -468
  81. package/src/components/data-display/Tooltip/Tooltip.test.stories.tsx +0 -1154
  82. package/src/components/feedback/ConfirmAction/ConfirmAction.stories.tsx +0 -146
  83. package/src/components/feedback/ConfirmAction/ConfirmAction.test.stories.tsx +0 -114
  84. package/src/components/feedback/ConfirmAction/__tests__/confirm-action.test.tsx +0 -288
  85. package/src/components/feedback/Dialog/Dialog.stories.tsx +0 -833
  86. package/src/components/feedback/Dialog/Dialog.test.stories.tsx +0 -955
  87. package/src/components/feedback/Dialog/__tests__/dialog-content-spacing.test.tsx +0 -66
  88. package/src/components/feedback/Modal/Modal.stories.tsx +0 -765
  89. package/src/components/feedback/Modal/Modal.test.stories.tsx +0 -251
  90. package/src/components/feedback/Sonner/Sonner.stories.tsx +0 -698
  91. package/src/components/feedback/Sonner/Sonner.test.stories.tsx +0 -896
  92. package/src/components/feedback/StackedModal/StackedModal.stories.tsx +0 -1783
  93. package/src/components/feedback/StackedModal/StackedModal.test.stories.tsx +0 -975
  94. package/src/components/feedback/StackedModal/__tests__/stacked-modal-viewport.test.tsx +0 -104
  95. package/src/components/feedback/Toast/Toast.stories.tsx +0 -548
  96. package/src/components/feedback/Toast/Toast.test.stories.tsx +0 -834
  97. package/src/components/feedback/TutorialOverlay/TutorialOverlay.stories.tsx +0 -691
  98. package/src/components/feedback/TutorialOverlay/TutorialOverlay.test.stories.tsx +0 -634
  99. package/src/components/form/AddressAutocomplete/AddressAutocomplete.stories.tsx +0 -665
  100. package/src/components/form/AddressAutocomplete/AddressAutocomplete.test.stories.tsx +0 -727
  101. package/src/components/form/Autocomplete/Autocomplete.stories.tsx +0 -715
  102. package/src/components/form/Autocomplete/Autocomplete.test.stories.tsx +0 -825
  103. package/src/components/form/Button/Button.stories.tsx +0 -365
  104. package/src/components/form/Button/Button.test.stories.tsx +0 -607
  105. package/src/components/form/Calendar/Calendar.stories.tsx +0 -349
  106. package/src/components/form/Calendar/Calendar.test.stories.tsx +0 -464
  107. package/src/components/form/CepField/CepField.stories.tsx +0 -138
  108. package/src/components/form/CepField/CepField.test.stories.tsx +0 -281
  109. package/src/components/form/Checkbox/Checkbox.stories.tsx +0 -265
  110. package/src/components/form/Checkbox/Checkbox.test.stories.tsx +0 -181
  111. package/src/components/form/CodeEditor/CodeEditor.stories.tsx +0 -871
  112. package/src/components/form/CodeEditor/CodeEditor.test.stories.tsx +0 -574
  113. package/src/components/form/Command/Command.stories.tsx +0 -580
  114. package/src/components/form/Command/Command.test.stories.tsx +0 -215
  115. package/src/components/form/CreatableSelect/CreatableSelect.stories.tsx +0 -112
  116. package/src/components/form/CreatableSelect/CreatableSelect.test.stories.tsx +0 -134
  117. package/src/components/form/Form/Form.stories.tsx +0 -687
  118. package/src/components/form/Form/Form.test.stories.tsx +0 -601
  119. package/src/components/form/Input/Input.stories.tsx +0 -260
  120. package/src/components/form/Input/Input.test.stories.tsx +0 -1191
  121. package/src/components/form/InputOTP/InputOTP.stories.tsx +0 -774
  122. package/src/components/form/InputOTP/InputOTP.test.stories.tsx +0 -588
  123. package/src/components/form/Label/Label.stories.tsx +0 -473
  124. package/src/components/form/Label/Label.test.stories.tsx +0 -909
  125. package/src/components/form/Menubar/Menubar.stories.tsx +0 -472
  126. package/src/components/form/Menubar/Menubar.test.stories.tsx +0 -584
  127. package/src/components/form/PasswordStrength/PasswordStrength.stories.tsx +0 -562
  128. package/src/components/form/PasswordStrength/PasswordStrength.test.stories.tsx +0 -327
  129. package/src/components/form/PhoneInput/PhoneInput.stories.tsx +0 -495
  130. package/src/components/form/PhoneInput/PhoneInput.test.stories.tsx +0 -666
  131. package/src/components/form/RadioGroup/RadioGroup.stories.tsx +0 -518
  132. package/src/components/form/RadioGroup/RadioGroup.test.stories.tsx +0 -685
  133. package/src/components/form/RichTextEditor/RichTextEditor.stories.tsx +0 -261
  134. package/src/components/form/RichTextEditor/RichTextEditor.test.stories.tsx +0 -491
  135. package/src/components/form/SearchPalette/SearchPalette.stories.tsx +0 -135
  136. package/src/components/form/Select/Select.stories.tsx +0 -364
  137. package/src/components/form/Select/Select.test.stories.tsx +0 -985
  138. package/src/components/form/Slider/Slider.stories.tsx +0 -418
  139. package/src/components/form/Slider/Slider.test.stories.tsx +0 -1042
  140. package/src/components/form/Switch/Switch.stories.tsx +0 -697
  141. package/src/components/form/Switch/Switch.test.stories.tsx +0 -597
  142. package/src/components/form/Textarea/Textarea.stories.tsx +0 -473
  143. package/src/components/form/Textarea/Textarea.test.stories.tsx +0 -702
  144. package/src/components/form/Toggle/Toggle.stories.tsx +0 -638
  145. package/src/components/form/Toggle/Toggle.test.stories.tsx +0 -1159
  146. package/src/components/form/ToggleGroup/ToggleGroup.stories.tsx +0 -617
  147. package/src/components/form/ToggleGroup/ToggleGroup.test.stories.tsx +0 -918
  148. package/src/components/form/UploadButton/UploadButton.stories.tsx +0 -367
  149. package/src/components/form/UploadButton/UploadButton.test.stories.tsx +0 -573
  150. package/src/components/form/total-form/total-form.test.tsx +0 -214
  151. package/src/components/layout/Accordion/Accordion.stories.tsx +0 -694
  152. package/src/components/layout/Accordion/Accordion.test.stories.tsx +0 -1344
  153. package/src/components/layout/Card/Card.stories.tsx +0 -591
  154. package/src/components/layout/Card/Card.test.stories.tsx +0 -1134
  155. package/src/components/layout/CardGrid/__tests__/CardGrid.test.tsx +0 -92
  156. package/src/components/layout/Collapsible/Collapsible.stories.tsx +0 -180
  157. package/src/components/layout/Collapsible/Collapsible.test.stories.tsx +0 -308
  158. package/src/components/layout/Container/Container.stories.tsx +0 -557
  159. package/src/components/layout/Container/Container.test.stories.tsx +0 -745
  160. package/src/components/layout/ContentToolbar/ContentToolbar.stories.tsx +0 -129
  161. package/src/components/layout/ContentToolbar/ContentToolbar.test.stories.tsx +0 -251
  162. package/src/components/layout/ContentToolbar/__tests__/ColumnsMenu.test.tsx +0 -39
  163. package/src/components/layout/ContentToolbar/__tests__/MultiSelectDropdown.test.tsx +0 -131
  164. package/src/components/layout/ContentToolbar/__tests__/SavedViewsMenu.test.tsx +0 -99
  165. package/src/components/layout/Dashboard/Dashboard.stories.tsx +0 -104
  166. package/src/components/layout/Dashboard/Dashboard.test.stories.tsx +0 -190
  167. package/src/components/layout/Drawer/Drawer.stories.tsx +0 -658
  168. package/src/components/layout/Drawer/Drawer.test.stories.tsx +0 -1343
  169. package/src/components/layout/Resizable/Resizable.stories.tsx +0 -1039
  170. package/src/components/layout/Resizable/Resizable.test.stories.tsx +0 -750
  171. package/src/components/layout/ScrollArea/ScrollArea.stories.tsx +0 -651
  172. package/src/components/layout/ScrollArea/ScrollArea.test.stories.tsx +0 -619
  173. package/src/components/layout/Separator/Separator.stories.tsx +0 -563
  174. package/src/components/layout/Separator/Separator.test.stories.tsx +0 -518
  175. package/src/components/layout/SettingsLayout/SettingsLayout.stories.tsx +0 -192
  176. package/src/components/layout/SettingsLayout/SettingsLayout.test.stories.tsx +0 -175
  177. package/src/components/layout/Sidebar/Sidebar.stories.tsx +0 -609
  178. package/src/components/layout/Sidebar/Sidebar.test.stories.tsx +0 -1324
  179. package/src/components/layout/Skeleton/Skeleton.stories.tsx +0 -689
  180. package/src/components/layout/Skeleton/Skeleton.test.stories.tsx +0 -521
  181. package/src/components/layout/Spacer/Spacer.stories.tsx +0 -502
  182. package/src/components/layout/Spacer/Spacer.test.stories.tsx +0 -472
  183. package/src/components/layout/TableFilter/TableFilter.stories.tsx +0 -82
  184. package/src/components/layout/TableFilter/TableFilter.test.stories.tsx +0 -87
  185. package/src/components/navigation/Breadcrumbs/Breadcrumbs.stories.tsx +0 -638
  186. package/src/components/navigation/Breadcrumbs/Breadcrumbs.test.stories.tsx +0 -1008
  187. package/src/components/navigation/CommandPalette/CommandPalette.stories.tsx +0 -386
  188. package/src/components/navigation/CommandPalette/CommandPalette.test.stories.tsx +0 -435
  189. package/src/components/navigation/ContextMenu/ContextMenu.stories.tsx +0 -614
  190. package/src/components/navigation/ContextMenu/ContextMenu.test.stories.tsx +0 -845
  191. package/src/components/navigation/DropdownMenu/DropdownMenu.stories.tsx +0 -578
  192. package/src/components/navigation/DropdownMenu/DropdownMenu.test.stories.tsx +0 -660
  193. package/src/components/navigation/NavigationMenu/stories/NavigationMenu.stories.tsx +0 -516
  194. package/src/components/navigation/NavigationMenu/stories/NavigationMenu.test.stories.tsx +0 -935
  195. package/src/components/navigation/NavigationMenu/stories/NavigationMenuHorizontal.stories.tsx +0 -501
  196. package/src/components/navigation/NavigationMenu/stories/NavigationMenuVertical.stories.tsx +0 -453
  197. package/src/components/navigation/Pagination/Pagination.stories.tsx +0 -602
  198. package/src/components/navigation/Pagination/Pagination.test.stories.tsx +0 -520
  199. package/src/components/navigation/Tabs/Tabs.stories.tsx +0 -1004
  200. package/src/components/navigation/Tabs/Tabs.test.stories.tsx +0 -1225
  201. package/src/components/typography/Blockquote/Blockquote.stories.tsx +0 -359
  202. package/src/components/typography/Blockquote/Blockquote.test.stories.tsx +0 -432
  203. package/src/components/typography/Code/Code.stories.tsx +0 -686
  204. package/src/components/typography/Code/Code.test.stories.tsx +0 -703
  205. package/src/components/typography/Heading/Heading.stories.tsx +0 -451
  206. package/src/components/typography/Heading/Heading.test.stories.tsx +0 -830
  207. package/src/components/typography/Paragraph/Paragraph.stories.tsx +0 -280
  208. package/src/components/typography/Paragraph/Paragraph.test.stories.tsx +0 -231
  209. package/src/components/typography/Text/Text.stories.tsx +0 -359
  210. package/src/components/typography/Text/Text.test.stories.tsx +0 -762
  211. package/src/components/utility/AnimatedIcon/AnimatedIcon.stories.tsx +0 -945
  212. package/src/components/utility/AnimatedIcon/AnimatedIcon.test.stories.tsx +0 -603
  213. package/src/components/utility/AspectRatio/AspectRatio.stories.tsx +0 -414
  214. package/src/components/utility/AspectRatio/AspectRatio.test.stories.tsx +0 -859
  215. package/src/components/utility/InfiniteScroll/InfiniteScroll.stories.tsx +0 -620
  216. package/src/components/utility/InfiniteScroll/InfiniteScroll.test.stories.tsx +0 -361
  217. package/src/components/utility/InstallPrompt/InstallPrompt.stories.tsx +0 -118
  218. package/src/components/utility/InstallPrompt/InstallPrompt.test.stories.tsx +0 -83
  219. package/src/components/utility/InstallPrompt/__tests__/InstallPrompt.ios.test.tsx +0 -65
  220. package/src/components/utility/InstallPrompt/__tests__/usePwaInstall.test.tsx +0 -271
  221. package/src/components/utility/Portal/Portal.stories.tsx +0 -340
  222. package/src/components/utility/Portal/Portal.test.stories.tsx +0 -2086
  223. package/src/components/utility/Transition/Transition.stories.tsx +0 -493
  224. package/src/components/utility/Transition/Transition.test.stories.tsx +0 -854
  225. package/src/components/utility/VirtualList/VirtualList.stories.tsx +0 -1073
  226. package/src/components/utility/VirtualList/VirtualList.test.stories.tsx +0 -1085
  227. package/src/components/utility/WorkflowStep/WorkflowStep.stories.tsx +0 -431
  228. package/src/components/utility/WorkflowStep/WorkflowStep.test.stories.tsx +0 -364
  229. /package/src/{button.tsx → button/button.tsx} +0 -0
@@ -1,825 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/react-vite';
2
- import { useState } from 'react';
3
- import { expect, userEvent, waitFor,within } from 'storybook/test';
4
-
5
- import { Autocomplete } from './Autocomplete';
6
- import type { AutocompleteProps } from './Autocomplete.types';
7
-
8
- interface Person {
9
- id: string;
10
- name: string;
11
- email: string;
12
- department?: string;
13
- }
14
-
15
- const samplePeople: Person[] = [
16
- { id: '1', name: 'John Doe', email: 'john@example.com', department: 'Engineering' },
17
- { id: '2', name: 'Jane Smith', email: 'jane@example.com', department: 'Design' },
18
- { id: '3', name: 'Bob Johnson', email: 'bob@example.com', department: 'Marketing' },
19
- { id: '4', name: 'Alice Brown', email: 'alice@example.com', department: 'Engineering' },
20
- { id: '5', name: 'Charlie Wilson', email: 'charlie@example.com', department: 'Sales' },
21
- ];
22
-
23
- const stringSuggestions = ['Apple', 'Banana', 'Cherry', 'Date', 'Elderberry', 'Fig', 'Grape'];
24
-
25
- const meta: Meta<typeof Autocomplete> = {
26
- title: 'Form/Autocomplete/Tests',
27
- component: Autocomplete,
28
- tags: ['autodocs', 'test', 'component:Autocomplete'],
29
- parameters: {
30
- docs: {
31
- description: {
32
- component:
33
- 'A comprehensive autocomplete component with ARIA support, keyboard navigation, and multiple selection modes.',
34
- },
35
- },
36
- },
37
- argTypes: {
38
- value: { control: 'text' },
39
- suggestions: { control: false },
40
- multiple: { control: 'boolean' },
41
- disabled: { control: 'boolean' },
42
- allowFreeText: { control: 'boolean' },
43
- showGhostText: { control: 'boolean' },
44
- matchMode: { control: { type: 'select', options: ['contains', 'startsWith', 'fuzzy'] } },
45
- debounceMs: { control: { type: 'number', min: 0, max: 1000 } },
46
- maxVisibleItems: { control: { type: 'number', min: 1, max: 20 } },
47
- },
48
- };
49
-
50
- export default meta;
51
- type Story = StoryObj<typeof Autocomplete>;
52
-
53
- // Test Component wrapper for controlled state
54
- const AutocompleteWrapper = (props: Partial<AutocompleteProps<Person | string>>) => {
55
- const [value, setValue] = useState(props.value || '');
56
- const [selectedItems, setSelectedItems] = useState(props.selectedItems || []);
57
-
58
- return (
59
- <div style={{ padding: '20px', minHeight: '200px' }}>
60
- <Autocomplete
61
- {...props}
62
- value={value}
63
- onChange={setValue}
64
- selectedItems={selectedItems}
65
- onSelectedItemsChange={setSelectedItems}
66
- />
67
- </div>
68
- );
69
- };
70
-
71
- // Basic Tests
72
- export const Default: Story = {
73
- render: () => (
74
- <AutocompleteWrapper suggestions={stringSuggestions} placeholder="Type to search fruits..." />
75
- ),
76
- play: async ({ canvasElement }) => {
77
- const canvas = within(canvasElement);
78
- const input = canvas.getByRole('combobox');
79
-
80
- // Test input is present and accessible
81
- await expect(input).toBeInTheDocument();
82
- await expect(input).toHaveAttribute('aria-expanded', 'false');
83
-
84
- // Test typing shows suggestions
85
- await userEvent.click(input);
86
- await userEvent.type(input, 'ap');
87
-
88
- // Wait for listbox to appear first (which confirms dropdown opened)
89
- const listbox = await canvas.findByRole('listbox');
90
- await expect(listbox).toBeInTheDocument();
91
-
92
- // Now check aria-expanded is true
93
- await expect(input).toHaveAttribute('aria-expanded', 'true');
94
-
95
- const options = canvas.getAllByRole('option');
96
- await expect(options).toHaveLength(2); // Apple, Grape (both contain "ap")
97
- await expect(options[0]).toHaveTextContent('Apple');
98
- await expect(options[1]).toHaveTextContent('Grape');
99
- },
100
- };
101
-
102
- export const WithObjectSuggestions: Story = {
103
- render: () => (
104
- <AutocompleteWrapper
105
- suggestions={samplePeople}
106
- getKey={(person: Person) => person.id}
107
- getLabel={(person: Person) => person.name}
108
- getDescription={(person: Person) => `${person.email} - ${person.department}`}
109
- placeholder="Search people..."
110
- />
111
- ),
112
- play: async ({ canvasElement }) => {
113
- const canvas = within(canvasElement);
114
- const input = canvas.getByRole('combobox');
115
-
116
- await userEvent.click(input);
117
- await userEvent.type(input, 'john');
118
-
119
- // Wait for listbox to appear first
120
- const listbox = await canvas.findByRole('listbox');
121
- await expect(listbox).toBeInTheDocument();
122
-
123
- const options = canvas.getAllByRole('option');
124
- await expect(options).toHaveLength(2); // John Doe, Bob Johnson
125
-
126
- // Test custom rendering with description
127
- await expect(options[0]).toHaveTextContent('john@example.com - Engineering');
128
- },
129
- };
130
-
131
- // Ghost Text Tests
132
- export const GhostText: Story = {
133
- render: () => (
134
- <AutocompleteWrapper
135
- suggestions={stringSuggestions}
136
- showGhostText={true}
137
- placeholder="Type 'ap' to see ghost text..."
138
- />
139
- ),
140
- play: async ({ canvasElement }) => {
141
- const canvas = within(canvasElement);
142
- const input = canvas.getByRole('combobox');
143
-
144
- // Focus input first to enable ghost text
145
- await userEvent.click(input);
146
- await userEvent.type(input, 'ap');
147
-
148
- // Wait for listbox to appear first
149
- const listbox = await canvas.findByRole('listbox');
150
- await expect(listbox).toBeInTheDocument();
151
-
152
- // Test ghost text appears - look for the new inline suggestion pattern
153
- // Since we're using the new pattern, check for the presence of the suggestion
154
- const options = canvas.getAllByRole('option');
155
- await expect(options).toHaveLength(2); // Apple, Grape both contain "ap"
156
- await expect(options[0]).toHaveTextContent('Apple');
157
-
158
- // Test that Tab key completes the ghost text
159
- await userEvent.keyboard('{Tab}');
160
- await expect(input).toHaveValue('apple'); // lowercase because user typed "ap"
161
- // Verify dropdown closes after completion
162
- await waitFor(() => expect(input).toHaveAttribute('aria-expanded', 'false'));
163
- },
164
- };
165
-
166
- export const GhostTextArrowRight: Story = {
167
- render: () => (
168
- <AutocompleteWrapper
169
- suggestions={stringSuggestions}
170
- showGhostText={true}
171
- placeholder="Type 'ch' and press ArrowRight..."
172
- />
173
- ),
174
- play: async ({ canvasElement }) => {
175
- const canvas = within(canvasElement);
176
- const input = canvas.getByRole('combobox');
177
-
178
- // Focus and type to trigger ghost text
179
- await userEvent.click(input);
180
- await userEvent.type(input, 'ch');
181
-
182
- // Wait for listbox to appear first
183
- const listbox = await canvas.findByRole('listbox');
184
- await expect(listbox).toBeInTheDocument();
185
-
186
- // Verify suggestion appears
187
- const options = canvas.getAllByRole('option');
188
- await expect(options).toHaveLength(1);
189
- await expect(options[0]).toHaveTextContent('Cherry');
190
-
191
- // Test that ArrowRight key completes the ghost text
192
- await userEvent.keyboard('{ArrowRight}');
193
- await expect(input).toHaveValue('Cherry');
194
- await waitFor(() => expect(input).toHaveAttribute('aria-expanded', 'false'));
195
- },
196
- };
197
-
198
- export const FocusBlurBehavior: Story = {
199
- name: '🔄 Focus/Blur Behavior Test',
200
- render: () => (
201
- <AutocompleteWrapper
202
- suggestions={stringSuggestions}
203
- showGhostText={true}
204
- placeholder="Test focus/blur behavior..."
205
- data-testid="focus-blur-autocomplete"
206
- />
207
- ),
208
- play: async ({ canvasElement, step }) => {
209
- const canvas = within(canvasElement);
210
-
211
- await step('Initial state verification', async () => {
212
- const input = canvas.getByRole('combobox');
213
- await expect(input).toBeInTheDocument();
214
- await expect(input).toHaveAttribute('aria-expanded', 'false');
215
- });
216
-
217
- await step('Open dropdown with typing', async () => {
218
- const input = canvas.getByRole('combobox');
219
- await userEvent.click(input);
220
- await userEvent.type(input, 'ap');
221
-
222
- // Wait for listbox to appear
223
- const listbox = await canvas.findByRole('listbox');
224
- await expect(listbox).toBeInTheDocument();
225
- await expect(input).toHaveAttribute('aria-expanded', 'true');
226
- });
227
-
228
- await step('Close dropdown (test dropdown close functionality)', async () => {
229
- const input = canvas.getByRole('combobox');
230
- // Try multiple methods to close dropdown
231
- await userEvent.keyboard('{Escape}');
232
-
233
- // Give some time for the state to update
234
- await waitFor(() => expect(input).toHaveAttribute('aria-expanded', 'false'), {
235
- timeout: 1000,
236
- });
237
- });
238
- },
239
- };
240
-
241
- // Keyboard Navigation Tests
242
- export const KeyboardNavigation: Story = {
243
- name: '⌨️ Keyboard Navigation Test',
244
- render: () => (
245
- <AutocompleteWrapper
246
- suggestions={stringSuggestions}
247
- placeholder="Test keyboard navigation..."
248
- data-testid="keyboard-nav-autocomplete"
249
- />
250
- ),
251
- play: async ({ canvasElement, step }) => {
252
- const canvas = within(canvasElement);
253
-
254
- await step('Open dropdown with typing', async () => {
255
- const input = canvas.getByRole('combobox');
256
- await userEvent.click(input);
257
- await userEvent.type(input, 'e');
258
-
259
- // Wait for listbox to appear
260
- const listbox = await canvas.findByRole('listbox');
261
- await expect(listbox).toBeInTheDocument();
262
- });
263
-
264
- await step('Verify options are displayed', async () => {
265
- const options = canvas.getAllByRole('option');
266
- await expect(options).toHaveLength(5); // Apple, Cherry, Date, Elderberry, Grape
267
- });
268
-
269
- await step('Test arrow key navigation', async () => {
270
- const input = canvas.getByRole('combobox');
271
- const options = canvas.getAllByRole('option');
272
-
273
- // Navigate down - should select some option
274
- await userEvent.keyboard('{ArrowDown}');
275
-
276
- // Wait for some option to become selected
277
- await waitFor(() => {
278
- const selectedOptions = options.filter(
279
- (option) => option.getAttribute('aria-selected') === 'true',
280
- );
281
- expect(selectedOptions.length).toBeGreaterThan(0);
282
- });
283
-
284
- // Test selection with Enter
285
- await userEvent.keyboard('{Enter}');
286
-
287
- // Should have some value selected
288
- const finalValue = input.getAttribute('value') || '';
289
- expect(finalValue.length).toBeGreaterThan(0);
290
- });
291
- },
292
- };
293
-
294
- // Multiple Selection Tests
295
- export const MultipleSelection: Story = {
296
- render: () => (
297
- <AutocompleteWrapper
298
- suggestions={stringSuggestions}
299
- multiple={true}
300
- placeholder="Select multiple fruits..."
301
- />
302
- ),
303
- play: async ({ canvasElement }) => {
304
- const canvas = within(canvasElement);
305
- const input = canvas.getByRole('combobox');
306
-
307
- // Select first item
308
- await userEvent.click(input);
309
- await userEvent.type(input, 'Apple', { delay: 50 });
310
-
311
- // Wait for dropdown and select
312
- await waitFor(() => expect(canvas.queryByRole('listbox')).toBeInTheDocument(), {
313
- timeout: 1500,
314
- });
315
- await userEvent.keyboard('{Enter}');
316
-
317
- // Wait for first chip to appear and input to clear
318
- await waitFor(
319
- () => {
320
- const chip = canvas.getByTestId('selected-chip-0');
321
- expect(chip).toBeInTheDocument();
322
- expect(input).toHaveValue('');
323
- },
324
- { timeout: 2000 },
325
- );
326
-
327
- // Wait for the dropdown to settle closed after the first selection (deterministic,
328
- // instead of a fixed debounce sleep) before starting the second selection.
329
- await waitFor(() => expect(canvas.queryByRole('listbox')).not.toBeInTheDocument());
330
-
331
- // Select second item
332
- await userEvent.type(input, 'Banana', { delay: 50 });
333
-
334
- // Wait for dropdown and select
335
- await waitFor(() => expect(canvas.queryByRole('listbox')).toBeInTheDocument(), {
336
- timeout: 1500,
337
- });
338
- await userEvent.keyboard('{Enter}');
339
-
340
- // Should have 2 chips
341
- await waitFor(
342
- () => {
343
- const chip0 = canvas.getByTestId('selected-chip-0');
344
- const chip1 = canvas.getByTestId('selected-chip-1');
345
- expect(chip0).toBeInTheDocument();
346
- expect(chip1).toBeInTheDocument();
347
- },
348
- { timeout: 2000 },
349
- );
350
- },
351
- };
352
-
353
- // Async Loading Tests
354
- export const AsyncLoading: Story = {
355
- render: () => (
356
- <AutocompleteWrapper
357
- suggestions={stringSuggestions}
358
- async={true}
359
- isLoading={true}
360
- placeholder="Async autocomplete..."
361
- />
362
- ),
363
- play: async ({ canvasElement }) => {
364
- const canvas = within(canvasElement);
365
- const input = canvas.getByRole('combobox');
366
-
367
- await userEvent.click(input);
368
- await userEvent.type(input, 'test');
369
-
370
- // Wait for dropdown to open due to loading state
371
- await waitFor(
372
- async () => {
373
- await expect(input).toHaveAttribute('aria-expanded', 'true');
374
- },
375
- { timeout: 1000 },
376
- );
377
-
378
- // Check loading indicator in input - it's in the InputProps endAdornment
379
- // We verify loading state by checking for the loading text in dropdown
380
- // The CircularProgress in the input is harder to query reliably
381
-
382
- // Check for loading text in dropdown
383
- await waitFor(
384
- async () => {
385
- const loadingText = canvas.getByText('Loading...');
386
- await expect(loadingText).toBeInTheDocument();
387
- },
388
- { timeout: 1000 },
389
- );
390
- },
391
- };
392
-
393
- // Match Mode Tests
394
- export const FuzzyMatchingTest: Story = {
395
- render: () => (
396
- <AutocompleteWrapper
397
- suggestions={['JavaScript', 'TypeScript', 'CoffeeScript', 'ActionScript']}
398
- matchMode="fuzzy"
399
- placeholder="Type 'jvs' for fuzzy matching..."
400
- />
401
- ),
402
- play: async ({ canvasElement }) => {
403
- const canvas = within(canvasElement);
404
- const input = canvas.getByRole('combobox');
405
-
406
- // Test fuzzy matching
407
- await userEvent.click(input);
408
- await userEvent.type(input, 'jvs');
409
-
410
- // Wait for listbox to appear first
411
- const listbox = await canvas.findByRole('listbox');
412
- await expect(listbox).toBeInTheDocument();
413
-
414
- const options = canvas.getAllByRole('option');
415
- await expect(options).toHaveLength(1);
416
- await expect(options[0]).toHaveTextContent('JavaScript');
417
- },
418
- };
419
-
420
- // Disabled State Tests
421
- export const DisabledState: Story = {
422
- render: () => (
423
- <AutocompleteWrapper
424
- suggestions={stringSuggestions}
425
- disabled={true}
426
- placeholder="This is disabled..."
427
- />
428
- ),
429
- play: async ({ canvasElement }) => {
430
- const canvas = within(canvasElement);
431
- const input = canvas.getByRole('combobox');
432
-
433
- await expect(input).toBeDisabled();
434
-
435
- // Try typing - should not work
436
- await userEvent.type(input, 'test');
437
- await expect(input).toHaveValue('');
438
- },
439
- };
440
-
441
- // No Results Tests
442
- export const NoResults: Story = {
443
- render: () => (
444
- <AutocompleteWrapper
445
- suggestions={stringSuggestions}
446
- placeholder="Type 'xyz' for no results..."
447
- />
448
- ),
449
- play: async ({ canvasElement }) => {
450
- const canvas = within(canvasElement);
451
- const input = canvas.getByRole('combobox');
452
-
453
- await userEvent.click(input);
454
- await userEvent.type(input, 'xyz');
455
-
456
- // Wait for the dropdown to open with no results message
457
- await waitFor(
458
- async () => {
459
- const noResults = canvas.getByText('No results found');
460
- await expect(noResults).toBeInTheDocument();
461
- },
462
- { timeout: 1000 },
463
- );
464
- },
465
- };
466
-
467
- // Escape Key Tests
468
- export const EscapeKey: Story = {
469
- render: () => (
470
- <AutocompleteWrapper
471
- suggestions={stringSuggestions}
472
- placeholder="Test escape key behavior..."
473
- />
474
- ),
475
- play: async ({ canvasElement }) => {
476
- const canvas = within(canvasElement);
477
- const input = canvas.getByRole('combobox');
478
-
479
- // Open suggestions
480
- await userEvent.click(input);
481
- await userEvent.type(input, 'apple');
482
-
483
- // Wait for dropdown to open
484
- await waitFor(() => expect(input).toHaveAttribute('aria-expanded', 'true'), {
485
- timeout: 1000,
486
- });
487
-
488
- // Single escape closes dropdown
489
- await userEvent.keyboard('{Escape}');
490
- await waitFor(() => expect(input).toHaveAttribute('aria-expanded', 'false'));
491
- await expect(input).toHaveValue('apple');
492
-
493
- // Double escape clears value (simulated by double press)
494
- await userEvent.keyboard('{Escape}');
495
- await userEvent.keyboard('{Escape}');
496
- // Note: Double escape detection requires special handling
497
- },
498
- };
499
-
500
- // Free Text Tests
501
- export const FreeText: Story = {
502
- render: () => (
503
- <AutocompleteWrapper
504
- suggestions={stringSuggestions}
505
- allowFreeText={true}
506
- placeholder="Type anything and press Enter..."
507
- />
508
- ),
509
- play: async ({ canvasElement }) => {
510
- const canvas = within(canvasElement);
511
- const input = canvas.getByRole('combobox');
512
-
513
- // Type custom text not in suggestions
514
- await userEvent.type(input, 'Custom Value');
515
- await userEvent.keyboard('{Enter}');
516
-
517
- await expect(input).toHaveValue('Custom Value');
518
- },
519
- };
520
-
521
- // Accessibility Tests
522
- export const AccessibilityCompliance: Story = {
523
- render: () => (
524
- <AutocompleteWrapper
525
- suggestions={samplePeople}
526
- getKey={(person: Person) => person.id}
527
- getLabel={(person: Person) => person.name}
528
- inputAriaLabel="Search for team members"
529
- placeholder="Search team members..."
530
- />
531
- ),
532
- play: async ({ canvasElement }) => {
533
- const canvas = within(canvasElement);
534
- const input = canvas.getByRole('combobox');
535
-
536
- // Test ARIA attributes
537
- await expect(input).toHaveAttribute('role', 'combobox');
538
- await expect(input).toHaveAttribute('aria-autocomplete', 'list');
539
- await expect(input).toHaveAttribute('aria-expanded', 'false');
540
- await expect(input).toHaveAttribute('aria-label', 'Search for team members');
541
-
542
- // Open dropdown
543
- await userEvent.click(input);
544
- await userEvent.type(input, 'john');
545
-
546
- // Wait for dropdown to open
547
- await waitFor(() => expect(input).toHaveAttribute('aria-expanded', 'true'), {
548
- timeout: 1000,
549
- });
550
- await expect(input).toHaveAttribute('aria-controls');
551
-
552
- const listbox = canvas.getByRole('listbox');
553
- await expect(listbox).toBeInTheDocument();
554
-
555
- const options = canvas.getAllByRole('option');
556
- // Options should have aria-selected attribute (first may be true if active)
557
- options.forEach((option) => {
558
- expect(option).toHaveAttribute('aria-selected');
559
- });
560
- },
561
- };
562
-
563
- // Performance Tests
564
- export const LargeDataset: Story = {
565
- render: () => {
566
- const largeSuggestions = Array.from({ length: 1000 }, (_, i) => `Item ${i + 1}`);
567
-
568
- return (
569
- <AutocompleteWrapper
570
- suggestions={largeSuggestions}
571
- maxVisibleItems={10}
572
- debounceMs={300}
573
- placeholder="Search 1000 items..."
574
- />
575
- );
576
- },
577
- play: async ({ canvasElement }) => {
578
- const canvas = within(canvasElement);
579
- const input = canvas.getByRole('combobox');
580
-
581
- // Test with large dataset
582
- await userEvent.click(input);
583
- await userEvent.type(input, '99');
584
-
585
- // Wait for listbox to appear first
586
- const listbox = await canvas.findByRole('listbox');
587
- await expect(listbox).toBeInTheDocument();
588
-
589
- const options = canvas.getAllByRole('option');
590
- // Should limit visible items
591
- await expect(options.length).toBeLessThanOrEqual(10);
592
- },
593
- };
594
-
595
- // Edge Cases
596
- export const EdgeCases: Story = {
597
- render: () => (
598
- <AutocompleteWrapper
599
- suggestions={['', 'Normal Item', ' Spaces ', 'Special!@#$%^&*()']}
600
- placeholder="Test edge cases..."
601
- />
602
- ),
603
- play: async ({ canvasElement }) => {
604
- const canvas = within(canvasElement);
605
- const input = canvas.getByRole('combobox');
606
-
607
- // Test searching for items with spaces
608
- await userEvent.click(input);
609
- await userEvent.type(input, 'Spaces');
610
-
611
- // Wait for listbox to appear
612
- await waitFor(() => expect(canvas.queryByRole('listbox')).toBeInTheDocument(), {
613
- timeout: 1000,
614
- });
615
-
616
- // Should handle empty and special characters
617
- const options = canvas.getAllByRole('option');
618
- await expect(options.length).toBeGreaterThan(0);
619
- },
620
- };
621
-
622
- // Form Interaction Tests
623
- export const FormInteraction: Story = {
624
- render: () => (
625
- <AutocompleteWrapper suggestions={stringSuggestions} placeholder="Form interaction test..." />
626
- ),
627
- play: async ({ canvasElement }) => {
628
- const canvas = within(canvasElement);
629
- const input = canvas.getByRole('combobox');
630
-
631
- // Test form submission behavior
632
- await userEvent.click(input);
633
- await userEvent.type(input, 'Apple');
634
-
635
- // Wait for dropdown and select
636
- const listbox = await canvas.findByRole('listbox');
637
- await expect(listbox).toBeInTheDocument();
638
-
639
- await userEvent.keyboard('{Enter}');
640
- await expect(input).toHaveValue('Apple');
641
-
642
- // Test that form would submit correctly (value is selected)
643
- const finalValue = input.getAttribute('value') || '';
644
- expect(finalValue).toBe('Apple');
645
- },
646
- };
647
-
648
- // Responsive Design Tests
649
- export const ResponsiveDesign: Story = {
650
- render: () => (
651
- <div style={{ width: '100%', maxWidth: '300px' }}>
652
- <AutocompleteWrapper suggestions={stringSuggestions} placeholder="Responsive test..." />
653
- </div>
654
- ),
655
- play: async ({ canvasElement }) => {
656
- const canvas = within(canvasElement);
657
- const input = canvas.getByRole('combobox');
658
-
659
- // Test responsive behavior
660
- await userEvent.click(input);
661
- await userEvent.type(input, 'a');
662
-
663
- // Wait for dropdown to appear
664
- const listbox = await canvas.findByRole('listbox');
665
- await expect(listbox).toBeInTheDocument();
666
-
667
- // Verify dropdown adapts to container width
668
- const options = canvas.getAllByRole('option');
669
- expect(options.length).toBeGreaterThan(0);
670
-
671
- // Test mobile-friendly interaction
672
- const firstOption = options[0];
673
- await userEvent.click(firstOption);
674
-
675
- // Should select the option
676
- const selectedValue = input.getAttribute('value') || '';
677
- expect(selectedValue.length).toBeGreaterThan(0);
678
- },
679
- };
680
-
681
- // Theme Variations Tests
682
- export const ThemeVariations: Story = {
683
- render: () => (
684
- <AutocompleteWrapper suggestions={stringSuggestions} placeholder="Theme variation test..." />
685
- ),
686
- play: async ({ canvasElement }) => {
687
- const canvas = within(canvasElement);
688
- const input = canvas.getByRole('combobox');
689
-
690
- // Test that component renders with theme
691
- await expect(input).toBeInTheDocument();
692
- await expect(input).toHaveAttribute('placeholder', 'Theme variation test...');
693
-
694
- // Test interaction with theming
695
- await userEvent.click(input);
696
- await userEvent.type(input, 'Apple');
697
-
698
- // Wait for dropdown
699
- const listbox = await canvas.findByRole('listbox');
700
- await expect(listbox).toBeInTheDocument();
701
-
702
- // Verify themed elements render correctly
703
- const options = canvas.getAllByRole('option');
704
- expect(options.length).toBeGreaterThan(0);
705
- await expect(options[0]).toHaveTextContent('Apple');
706
- },
707
- };
708
-
709
- // Visual States Tests
710
- export const VisualStates: Story = {
711
- render: () => (
712
- <AutocompleteWrapper
713
- suggestions={stringSuggestions}
714
- placeholder="Visual states test..."
715
- disabled={false}
716
- />
717
- ),
718
- play: async ({ canvasElement }) => {
719
- const canvas = within(canvasElement);
720
- const input = canvas.getByRole('combobox');
721
-
722
- // Test normal state
723
- await expect(input).toBeInTheDocument();
724
- await expect(input).not.toBeDisabled();
725
-
726
- // Test focus state (waitFor keeps the focus assertion but avoids flakiness).
727
- await userEvent.click(input);
728
- await waitFor(() => expect(input).toHaveFocus());
729
-
730
- // Test with content state
731
- await userEvent.type(input, 'Test');
732
- await expect(input).toHaveValue('Test');
733
-
734
- // Test dropdown open state
735
- await userEvent.clear(input);
736
- await userEvent.type(input, 'Apple');
737
-
738
- const listbox = await canvas.findByRole('listbox');
739
- await expect(listbox).toBeInTheDocument();
740
-
741
- // Test selection state
742
- await userEvent.keyboard('{Enter}');
743
- await expect(input).toHaveValue('Apple');
744
- },
745
- };
746
-
747
- // Typed suggestions (search vs. link) — Google-style results
748
- interface SearchLinkItem {
749
- id: string;
750
- text: string;
751
- type: 'search' | 'link';
752
- url?: string;
753
- }
754
-
755
- const searchLinkItems: SearchLinkItem[] = [
756
- { id: 's1', text: 'Produtos', type: 'search' },
757
- { id: 's2', text: 'Pedidos', type: 'search' },
758
- { id: 'l1', text: 'Abrir documentação', type: 'link', url: 'https://example.com/docs' },
759
- ];
760
-
761
- const SearchLinkWrapper = () => {
762
- const [value, setValue] = useState('');
763
- const [openedUrl, setOpenedUrl] = useState('');
764
-
765
- return (
766
- <div style={{ padding: '20px', minHeight: '260px' }}>
767
- <Autocomplete<SearchLinkItem>
768
- value={value}
769
- onChange={setValue}
770
- suggestions={searchLinkItems}
771
- getKey={(item) => item.id}
772
- getLabel={(item) => item.text}
773
- getSuggestionType={(item) => item.type}
774
- getUrl={(item) => item.url}
775
- openLink={(url) => setOpenedUrl(url)}
776
- placeholder="Buscar ou abrir link..."
777
- />
778
- <div data-testid="opened-url">{openedUrl}</div>
779
- </div>
780
- );
781
- };
782
-
783
- export const SearchAndLinkSuggestions: Story = {
784
- render: () => <SearchLinkWrapper />,
785
- play: async ({ canvasElement, step }) => {
786
- const canvas = within(canvasElement);
787
- const input = canvas.getByRole('combobox');
788
-
789
- await step('link suggestion opens the URL and leaves the input unchanged', async () => {
790
- await userEvent.click(input);
791
- await userEvent.type(input, 'o'); // matches all three (contains "o")
792
-
793
- const listbox = await canvas.findByRole('listbox');
794
- await expect(listbox).toBeInTheDocument();
795
-
796
- const linkOption = await canvas.findByText('Abrir documentação');
797
- // A `link` suggestion renders a leading icon.
798
- await expect(linkOption.closest('[role="option"]')?.querySelector('svg')).toBeInTheDocument();
799
-
800
- await userEvent.click(linkOption);
801
-
802
- // openLink fired with the target URL...
803
- await expect(canvas.getByTestId('opened-url')).toHaveTextContent(
804
- 'https://example.com/docs',
805
- );
806
- // ...and the input value was NOT replaced by the link label.
807
- await expect(input).toHaveValue('o');
808
- await waitFor(() => expect(input).toHaveAttribute('aria-expanded', 'false'));
809
- });
810
-
811
- await step('search suggestion fills the input', async () => {
812
- await userEvent.clear(input);
813
- await userEvent.type(input, 'produt');
814
-
815
- const searchOption = await canvas.findByText('Produtos');
816
- await userEvent.click(searchOption);
817
-
818
- await expect(input).toHaveValue('Produtos');
819
- // The link was not re-opened by a search selection.
820
- await expect(canvas.getByTestId('opened-url')).toHaveTextContent(
821
- 'https://example.com/docs',
822
- );
823
- });
824
- },
825
- };