@12-apps/ui 1.5.0 → 1.5.2
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.
- package/package.json +17 -9
- package/src/button/index.ts +1 -0
- package/src/social-login-button/index.ts +1 -0
- package/src/{social-login-button.tsx → social-login-button/social-login-button.tsx} +5 -5
- package/src/user-avatar/index.ts +1 -0
- package/src/{user-avatar.tsx → user-avatar/user-avatar.tsx} +4 -4
- package/eslint.config.js +0 -89
- package/src/__tests__/data-grid.test.tsx +0 -125
- package/src/__tests__/package-wiring.test.ts +0 -41
- package/src/__tests__/setup.ts +0 -1
- package/src/__tests__/social-login-button.test.tsx +0 -186
- package/src/__tests__/user-avatar.test.tsx +0 -195
- package/src/__tests__/viewport.test.ts +0 -50
- package/src/components/command/__tests__/command.test.tsx +0 -112
- package/src/components/data-display/Alert/Alert.stories.tsx +0 -559
- package/src/components/data-display/Alert/Alert.test.stories.tsx +0 -707
- package/src/components/data-display/AlertDialog/AlertDialog.stories.tsx +0 -362
- package/src/components/data-display/AlertDialog/AlertDialog.test.stories.tsx +0 -763
- package/src/components/data-display/AsyncStateContainer/AsyncStateContainer.stories.tsx +0 -230
- package/src/components/data-display/AsyncStateContainer/AsyncStateContainer.test.stories.tsx +0 -270
- package/src/components/data-display/Avatar/Avatar.stories.tsx +0 -721
- package/src/components/data-display/Avatar/Avatar.test.stories.tsx +0 -822
- package/src/components/data-display/Badge/Badge.stories.tsx +0 -1134
- package/src/components/data-display/Badge/Badge.test.stories.tsx +0 -1194
- package/src/components/data-display/Banner/Banner.stories.tsx +0 -528
- package/src/components/data-display/Banner/Banner.test.stories.tsx +0 -511
- package/src/components/data-display/Carousel/Carousel.stories.tsx +0 -607
- package/src/components/data-display/Carousel/Carousel.test.stories.tsx +0 -701
- package/src/components/data-display/Chart/Chart.stories.tsx +0 -568
- package/src/components/data-display/Chart/Chart.test.stories.tsx +0 -174
- package/src/components/data-display/Chart/SpecChart.stories.tsx +0 -150
- package/src/components/data-display/Chart/SpecChart.test.stories.tsx +0 -56
- package/src/components/data-display/Chart/__tests__/SpecChart.test.tsx +0 -60
- package/src/components/data-display/Chart/__tests__/chart-format.test.ts +0 -43
- package/src/components/data-display/Chart/__tests__/chart-spec.test.ts +0 -119
- package/src/components/data-display/Chip/Chip.stories.tsx +0 -252
- package/src/components/data-display/Chip/Chip.test.stories.tsx +0 -266
- package/src/components/data-display/DataGrid/DataGrid.stories.tsx +0 -515
- package/src/components/data-display/DataGrid/DataGrid.test.stories.tsx +0 -653
- package/src/components/data-display/DataViews/__tests__/DataViewsGrid.test.tsx +0 -271
- package/src/components/data-display/DataViews/__tests__/DataViewsTableBase.test.tsx +0 -134
- package/src/components/data-display/DataViews/__tests__/SaveViewModal.test.tsx +0 -83
- package/src/components/data-display/DataViews/__tests__/data-views-filter.test.ts +0 -115
- package/src/components/data-display/DataViews/__tests__/data-views-preview.test.ts +0 -53
- package/src/components/data-display/DataViews/__tests__/range-pill.test.tsx +0 -114
- package/src/components/data-display/DataViews/base-card.stories.tsx +0 -136
- package/src/components/data-display/DescriptionItem/DescriptionItem.stories.tsx +0 -254
- package/src/components/data-display/EmptyState/EmptyState.stories.tsx +0 -282
- package/src/components/data-display/EmptyState/EmptyState.test.stories.tsx +0 -441
- package/src/components/data-display/ErrorState/ErrorState.stories.tsx +0 -110
- package/src/components/data-display/ErrorState/ErrorState.test.stories.tsx +0 -133
- package/src/components/data-display/HoverCard/HoverCard.stories.tsx +0 -650
- package/src/components/data-display/HoverCard/HoverCard.test.stories.tsx +0 -929
- package/src/components/data-display/InteractiveTooltip/InteractiveTooltip.stories.tsx +0 -411
- package/src/components/data-display/LazyImage/LazyImage.stories.tsx +0 -387
- package/src/components/data-display/Lightbox/Lightbox.stories.tsx +0 -315
- package/src/components/data-display/Lightbox/Lightbox.test.stories.tsx +0 -598
- package/src/components/data-display/LoadingState/LoadingState.stories.tsx +0 -124
- package/src/components/data-display/LoadingState/LoadingState.test.stories.tsx +0 -99
- package/src/components/data-display/MapPreview/MapPreview.stories.tsx +0 -458
- package/src/components/data-display/MapPreview/MapPreview.test.stories.tsx +0 -394
- package/src/components/data-display/Popover/Popover.stories.tsx +0 -295
- package/src/components/data-display/Popover/Popover.test.stories.tsx +0 -1162
- package/src/components/data-display/Progress/Progress.stories.tsx +0 -481
- package/src/components/data-display/Progress/Progress.test.stories.tsx +0 -2070
- package/src/components/data-display/SectionOnboarding/SectionOnboarding.stories.tsx +0 -160
- package/src/components/data-display/SectionOnboarding/SectionOnboarding.test.stories.tsx +0 -190
- package/src/components/data-display/Sheet/Sheet.stories.tsx +0 -883
- package/src/components/data-display/Sheet/Sheet.test.stories.tsx +0 -1105
- package/src/components/data-display/StatCard/StatCard.stories.tsx +0 -167
- package/src/components/data-display/StatCard/StatCard.test.stories.tsx +0 -240
- package/src/components/data-display/Stepper/Stepper.stories.tsx +0 -540
- package/src/components/data-display/Stepper/Stepper.test.stories.tsx +0 -600
- package/src/components/data-display/Table/Table.stories.tsx +0 -803
- package/src/components/data-display/Table/Table.test.stories.tsx +0 -369
- package/src/components/data-display/Timeline/Timeline.stories.tsx +0 -442
- package/src/components/data-display/Timeline/Timeline.test.stories.tsx +0 -930
- package/src/components/data-display/TimingDiagram/TimingDiagram.stories.tsx +0 -475
- package/src/components/data-display/TimingDiagram/TimingDiagram.test.stories.tsx +0 -734
- package/src/components/data-display/Tooltip/Tooltip.stories.tsx +0 -468
- package/src/components/data-display/Tooltip/Tooltip.test.stories.tsx +0 -1154
- package/src/components/feedback/ConfirmAction/ConfirmAction.stories.tsx +0 -146
- package/src/components/feedback/ConfirmAction/ConfirmAction.test.stories.tsx +0 -114
- package/src/components/feedback/ConfirmAction/__tests__/confirm-action.test.tsx +0 -288
- package/src/components/feedback/Dialog/Dialog.stories.tsx +0 -833
- package/src/components/feedback/Dialog/Dialog.test.stories.tsx +0 -964
- package/src/components/feedback/Dialog/__tests__/dialog-content-spacing.test.tsx +0 -66
- package/src/components/feedback/Modal/Modal.stories.tsx +0 -765
- package/src/components/feedback/Modal/Modal.test.stories.tsx +0 -251
- package/src/components/feedback/Sonner/Sonner.stories.tsx +0 -698
- package/src/components/feedback/Sonner/Sonner.test.stories.tsx +0 -896
- package/src/components/feedback/StackedModal/StackedModal.stories.tsx +0 -1783
- package/src/components/feedback/StackedModal/StackedModal.test.stories.tsx +0 -973
- package/src/components/feedback/StackedModal/__tests__/stacked-modal-viewport.test.tsx +0 -104
- package/src/components/feedback/Toast/Toast.stories.tsx +0 -548
- package/src/components/feedback/Toast/Toast.test.stories.tsx +0 -834
- package/src/components/feedback/TutorialOverlay/TutorialOverlay.stories.tsx +0 -691
- package/src/components/feedback/TutorialOverlay/TutorialOverlay.test.stories.tsx +0 -634
- package/src/components/form/AddressAutocomplete/AddressAutocomplete.stories.tsx +0 -665
- package/src/components/form/AddressAutocomplete/AddressAutocomplete.test.stories.tsx +0 -727
- package/src/components/form/Autocomplete/Autocomplete.stories.tsx +0 -715
- package/src/components/form/Autocomplete/Autocomplete.test.stories.tsx +0 -825
- package/src/components/form/Button/Button.stories.tsx +0 -365
- package/src/components/form/Button/Button.test.stories.tsx +0 -607
- package/src/components/form/Calendar/Calendar.stories.tsx +0 -349
- package/src/components/form/Calendar/Calendar.test.stories.tsx +0 -464
- package/src/components/form/CepField/CepField.stories.tsx +0 -138
- package/src/components/form/CepField/CepField.test.stories.tsx +0 -281
- package/src/components/form/Checkbox/Checkbox.stories.tsx +0 -265
- package/src/components/form/Checkbox/Checkbox.test.stories.tsx +0 -181
- package/src/components/form/CodeEditor/CodeEditor.stories.tsx +0 -871
- package/src/components/form/CodeEditor/CodeEditor.test.stories.tsx +0 -574
- package/src/components/form/Command/Command.stories.tsx +0 -580
- package/src/components/form/Command/Command.test.stories.tsx +0 -215
- package/src/components/form/CreatableSelect/CreatableSelect.stories.tsx +0 -112
- package/src/components/form/CreatableSelect/CreatableSelect.test.stories.tsx +0 -134
- package/src/components/form/Form/Form.stories.tsx +0 -687
- package/src/components/form/Form/Form.test.stories.tsx +0 -601
- package/src/components/form/Input/Input.stories.tsx +0 -260
- package/src/components/form/Input/Input.test.stories.tsx +0 -1191
- package/src/components/form/InputOTP/InputOTP.stories.tsx +0 -774
- package/src/components/form/InputOTP/InputOTP.test.stories.tsx +0 -588
- package/src/components/form/Label/Label.stories.tsx +0 -473
- package/src/components/form/Label/Label.test.stories.tsx +0 -915
- package/src/components/form/Menubar/Menubar.stories.tsx +0 -472
- package/src/components/form/Menubar/Menubar.test.stories.tsx +0 -584
- package/src/components/form/PasswordStrength/PasswordStrength.stories.tsx +0 -562
- package/src/components/form/PasswordStrength/PasswordStrength.test.stories.tsx +0 -327
- package/src/components/form/PhoneInput/PhoneInput.stories.tsx +0 -495
- package/src/components/form/PhoneInput/PhoneInput.test.stories.tsx +0 -666
- package/src/components/form/RadioGroup/RadioGroup.stories.tsx +0 -518
- package/src/components/form/RadioGroup/RadioGroup.test.stories.tsx +0 -685
- package/src/components/form/RichTextEditor/RichTextEditor.stories.tsx +0 -261
- package/src/components/form/RichTextEditor/RichTextEditor.test.stories.tsx +0 -491
- package/src/components/form/SearchPalette/SearchPalette.stories.tsx +0 -135
- package/src/components/form/Select/Select.stories.tsx +0 -364
- package/src/components/form/Select/Select.test.stories.tsx +0 -985
- package/src/components/form/Slider/Slider.stories.tsx +0 -418
- package/src/components/form/Slider/Slider.test.stories.tsx +0 -1042
- package/src/components/form/Switch/Switch.stories.tsx +0 -697
- package/src/components/form/Switch/Switch.test.stories.tsx +0 -597
- package/src/components/form/Textarea/Textarea.stories.tsx +0 -473
- package/src/components/form/Textarea/Textarea.test.stories.tsx +0 -702
- package/src/components/form/Toggle/Toggle.stories.tsx +0 -638
- package/src/components/form/Toggle/Toggle.test.stories.tsx +0 -1159
- package/src/components/form/ToggleGroup/ToggleGroup.stories.tsx +0 -617
- package/src/components/form/ToggleGroup/ToggleGroup.test.stories.tsx +0 -915
- package/src/components/form/UploadButton/UploadButton.stories.tsx +0 -367
- package/src/components/form/UploadButton/UploadButton.test.stories.tsx +0 -573
- package/src/components/form/total-form/total-form.test.tsx +0 -214
- package/src/components/layout/Accordion/Accordion.stories.tsx +0 -694
- package/src/components/layout/Accordion/Accordion.test.stories.tsx +0 -1344
- package/src/components/layout/Card/Card.stories.tsx +0 -591
- package/src/components/layout/Card/Card.test.stories.tsx +0 -1134
- package/src/components/layout/CardGrid/__tests__/CardGrid.test.tsx +0 -92
- package/src/components/layout/Collapsible/Collapsible.stories.tsx +0 -180
- package/src/components/layout/Collapsible/Collapsible.test.stories.tsx +0 -308
- package/src/components/layout/Container/Container.stories.tsx +0 -557
- package/src/components/layout/Container/Container.test.stories.tsx +0 -745
- package/src/components/layout/ContentToolbar/ContentToolbar.stories.tsx +0 -129
- package/src/components/layout/ContentToolbar/ContentToolbar.test.stories.tsx +0 -251
- package/src/components/layout/ContentToolbar/__tests__/ColumnsMenu.test.tsx +0 -39
- package/src/components/layout/ContentToolbar/__tests__/MultiSelectDropdown.test.tsx +0 -131
- package/src/components/layout/ContentToolbar/__tests__/SavedViewsMenu.test.tsx +0 -99
- package/src/components/layout/Dashboard/Dashboard.stories.tsx +0 -104
- package/src/components/layout/Dashboard/Dashboard.test.stories.tsx +0 -190
- package/src/components/layout/Drawer/Drawer.stories.tsx +0 -658
- package/src/components/layout/Drawer/Drawer.test.stories.tsx +0 -1343
- package/src/components/layout/Resizable/Resizable.stories.tsx +0 -1039
- package/src/components/layout/Resizable/Resizable.test.stories.tsx +0 -754
- package/src/components/layout/ScrollArea/ScrollArea.stories.tsx +0 -651
- package/src/components/layout/ScrollArea/ScrollArea.test.stories.tsx +0 -619
- package/src/components/layout/Separator/Separator.stories.tsx +0 -563
- package/src/components/layout/Separator/Separator.test.stories.tsx +0 -518
- package/src/components/layout/SettingsLayout/SettingsLayout.stories.tsx +0 -192
- package/src/components/layout/SettingsLayout/SettingsLayout.test.stories.tsx +0 -175
- package/src/components/layout/Sidebar/Sidebar.stories.tsx +0 -609
- package/src/components/layout/Sidebar/Sidebar.test.stories.tsx +0 -1324
- package/src/components/layout/Skeleton/Skeleton.stories.tsx +0 -689
- package/src/components/layout/Skeleton/Skeleton.test.stories.tsx +0 -521
- package/src/components/layout/Spacer/Spacer.stories.tsx +0 -502
- package/src/components/layout/Spacer/Spacer.test.stories.tsx +0 -474
- package/src/components/layout/TableFilter/TableFilter.stories.tsx +0 -82
- package/src/components/layout/TableFilter/TableFilter.test.stories.tsx +0 -87
- package/src/components/navigation/Breadcrumbs/Breadcrumbs.stories.tsx +0 -638
- package/src/components/navigation/Breadcrumbs/Breadcrumbs.test.stories.tsx +0 -1008
- package/src/components/navigation/CommandPalette/CommandPalette.stories.tsx +0 -386
- package/src/components/navigation/CommandPalette/CommandPalette.test.stories.tsx +0 -435
- package/src/components/navigation/ContextMenu/ContextMenu.stories.tsx +0 -614
- package/src/components/navigation/ContextMenu/ContextMenu.test.stories.tsx +0 -845
- package/src/components/navigation/DropdownMenu/DropdownMenu.stories.tsx +0 -578
- package/src/components/navigation/DropdownMenu/DropdownMenu.test.stories.tsx +0 -660
- package/src/components/navigation/NavigationMenu/stories/NavigationMenu.stories.tsx +0 -516
- package/src/components/navigation/NavigationMenu/stories/NavigationMenu.test.stories.tsx +0 -935
- package/src/components/navigation/NavigationMenu/stories/NavigationMenuHorizontal.stories.tsx +0 -501
- package/src/components/navigation/NavigationMenu/stories/NavigationMenuVertical.stories.tsx +0 -453
- package/src/components/navigation/Pagination/Pagination.stories.tsx +0 -602
- package/src/components/navigation/Pagination/Pagination.test.stories.tsx +0 -520
- package/src/components/navigation/Tabs/Tabs.stories.tsx +0 -1004
- package/src/components/navigation/Tabs/Tabs.test.stories.tsx +0 -1225
- package/src/components/typography/Blockquote/Blockquote.stories.tsx +0 -359
- package/src/components/typography/Blockquote/Blockquote.test.stories.tsx +0 -432
- package/src/components/typography/Code/Code.stories.tsx +0 -686
- package/src/components/typography/Code/Code.test.stories.tsx +0 -703
- package/src/components/typography/Heading/Heading.stories.tsx +0 -451
- package/src/components/typography/Heading/Heading.test.stories.tsx +0 -830
- package/src/components/typography/Paragraph/Paragraph.stories.tsx +0 -280
- package/src/components/typography/Paragraph/Paragraph.test.stories.tsx +0 -231
- package/src/components/typography/Text/Text.stories.tsx +0 -359
- package/src/components/typography/Text/Text.test.stories.tsx +0 -759
- package/src/components/utility/AnimatedIcon/AnimatedIcon.stories.tsx +0 -945
- package/src/components/utility/AnimatedIcon/AnimatedIcon.test.stories.tsx +0 -603
- package/src/components/utility/AspectRatio/AspectRatio.stories.tsx +0 -414
- package/src/components/utility/AspectRatio/AspectRatio.test.stories.tsx +0 -859
- package/src/components/utility/InfiniteScroll/InfiniteScroll.stories.tsx +0 -620
- package/src/components/utility/InfiniteScroll/InfiniteScroll.test.stories.tsx +0 -361
- package/src/components/utility/InstallPrompt/InstallPrompt.stories.tsx +0 -118
- package/src/components/utility/InstallPrompt/InstallPrompt.test.stories.tsx +0 -83
- package/src/components/utility/InstallPrompt/__tests__/InstallPrompt.ios.test.tsx +0 -65
- package/src/components/utility/InstallPrompt/__tests__/usePwaInstall.test.tsx +0 -271
- package/src/components/utility/Portal/Portal.stories.tsx +0 -340
- package/src/components/utility/Portal/Portal.test.stories.tsx +0 -2086
- package/src/components/utility/Transition/Transition.stories.tsx +0 -493
- package/src/components/utility/Transition/Transition.test.stories.tsx +0 -854
- package/src/components/utility/VirtualList/VirtualList.stories.tsx +0 -1073
- package/src/components/utility/VirtualList/VirtualList.test.stories.tsx +0 -1085
- package/src/components/utility/WorkflowStep/WorkflowStep.stories.tsx +0 -431
- package/src/components/utility/WorkflowStep/WorkflowStep.test.stories.tsx +0 -364
- /package/src/{button.tsx → button/button.tsx} +0 -0
|
@@ -1,588 +0,0 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
-
import { expect, fn, userEvent, waitFor, within } from 'storybook/test';
|
|
3
|
-
|
|
4
|
-
import { InputOTP } from './InputOTP';
|
|
5
|
-
|
|
6
|
-
const meta: Meta<typeof InputOTP> = {
|
|
7
|
-
title: 'Form/InputOTP/Tests',
|
|
8
|
-
component: InputOTP,
|
|
9
|
-
parameters: {
|
|
10
|
-
layout: 'centered',
|
|
11
|
-
chromatic: { disableSnapshot: false },
|
|
12
|
-
},
|
|
13
|
-
tags: ['autodocs', 'test', 'component:InputOTP'],
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export default meta;
|
|
17
|
-
type Story = StoryObj<typeof meta>;
|
|
18
|
-
|
|
19
|
-
// Test 1: Basic Interaction
|
|
20
|
-
export const BasicInteraction: Story = {
|
|
21
|
-
args: {
|
|
22
|
-
variant: 'numeric',
|
|
23
|
-
length: 6,
|
|
24
|
-
color: 'primary',
|
|
25
|
-
size: 'md',
|
|
26
|
-
onChange: fn(),
|
|
27
|
-
onComplete: fn(),
|
|
28
|
-
},
|
|
29
|
-
play: async ({ canvasElement, args }) => {
|
|
30
|
-
const canvas = within(canvasElement);
|
|
31
|
-
|
|
32
|
-
// Find the first input field
|
|
33
|
-
const inputs = canvas.getAllByRole('textbox');
|
|
34
|
-
expect(inputs).toHaveLength(6);
|
|
35
|
-
|
|
36
|
-
// Type digits into inputs
|
|
37
|
-
await userEvent.type(inputs[0], '1');
|
|
38
|
-
await waitFor(() => {
|
|
39
|
-
expect(args.onChange).toHaveBeenCalledWith('1');
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
await userEvent.type(inputs[1], '2');
|
|
43
|
-
await waitFor(() => {
|
|
44
|
-
expect(args.onChange).toHaveBeenCalledWith('12');
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
// Complete the OTP
|
|
48
|
-
await userEvent.type(inputs[2], '3');
|
|
49
|
-
await userEvent.type(inputs[3], '4');
|
|
50
|
-
await userEvent.type(inputs[4], '5');
|
|
51
|
-
await userEvent.type(inputs[5], '6');
|
|
52
|
-
|
|
53
|
-
await waitFor(() => {
|
|
54
|
-
expect(args.onComplete).toHaveBeenCalledWith('123456');
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
// Verify all inputs have correct values
|
|
58
|
-
expect(inputs[0]).toHaveValue('1');
|
|
59
|
-
expect(inputs[1]).toHaveValue('2');
|
|
60
|
-
expect(inputs[2]).toHaveValue('3');
|
|
61
|
-
expect(inputs[3]).toHaveValue('4');
|
|
62
|
-
expect(inputs[4]).toHaveValue('5');
|
|
63
|
-
expect(inputs[5]).toHaveValue('6');
|
|
64
|
-
},
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
// Test 2: Form Interaction
|
|
68
|
-
export const FormInteraction: Story = {
|
|
69
|
-
args: {
|
|
70
|
-
variant: 'alphanumeric',
|
|
71
|
-
length: 4,
|
|
72
|
-
color: 'secondary',
|
|
73
|
-
size: 'lg',
|
|
74
|
-
onChange: fn(),
|
|
75
|
-
onComplete: fn(),
|
|
76
|
-
},
|
|
77
|
-
play: async ({ canvasElement, args }) => {
|
|
78
|
-
const canvas = within(canvasElement);
|
|
79
|
-
const inputs = canvas.getAllByRole('textbox');
|
|
80
|
-
|
|
81
|
-
// Test alphanumeric input
|
|
82
|
-
await userEvent.type(inputs[0], 'A');
|
|
83
|
-
expect(args.onChange).toHaveBeenCalledWith('A');
|
|
84
|
-
|
|
85
|
-
await userEvent.type(inputs[1], '1');
|
|
86
|
-
expect(args.onChange).toHaveBeenCalledWith('A1');
|
|
87
|
-
|
|
88
|
-
await userEvent.type(inputs[2], 'B');
|
|
89
|
-
expect(args.onChange).toHaveBeenCalledWith('A1B');
|
|
90
|
-
|
|
91
|
-
await userEvent.type(inputs[3], '2');
|
|
92
|
-
expect(args.onChange).toHaveBeenCalledWith('A1B2');
|
|
93
|
-
expect(args.onComplete).toHaveBeenCalledWith('A1B2');
|
|
94
|
-
|
|
95
|
-
// Test that numeric-only characters are rejected in numeric mode
|
|
96
|
-
await userEvent.clear(inputs[0]);
|
|
97
|
-
await userEvent.type(inputs[0], '@'); // Should be rejected
|
|
98
|
-
expect(inputs[0]).toHaveValue('');
|
|
99
|
-
},
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
// Test 3: Keyboard Navigation
|
|
103
|
-
export const KeyboardNavigation: Story = {
|
|
104
|
-
args: {
|
|
105
|
-
variant: 'numeric',
|
|
106
|
-
length: 6,
|
|
107
|
-
color: 'primary',
|
|
108
|
-
autoFocus: true,
|
|
109
|
-
onChange: fn(),
|
|
110
|
-
},
|
|
111
|
-
play: async ({ canvasElement }) => {
|
|
112
|
-
const canvas = within(canvasElement);
|
|
113
|
-
const inputs = canvas.getAllByRole('textbox');
|
|
114
|
-
|
|
115
|
-
// First input should be focused if autoFocus is true
|
|
116
|
-
await waitFor(() => {
|
|
117
|
-
expect(inputs[0]).toHaveFocus();
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
// Type and move forward
|
|
121
|
-
await userEvent.type(inputs[0], '1');
|
|
122
|
-
await waitFor(() => {
|
|
123
|
-
// Verify the input value was set
|
|
124
|
-
expect(inputs[0]).toHaveValue('1');
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
// Test arrow key navigation
|
|
128
|
-
await userEvent.keyboard('{ArrowLeft}');
|
|
129
|
-
await waitFor(() => {
|
|
130
|
-
// Just verify the first input can receive focus via arrow keys
|
|
131
|
-
expect(inputs[0]).toBeInTheDocument();
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
await userEvent.keyboard('{ArrowRight}');
|
|
135
|
-
await waitFor(() => {
|
|
136
|
-
// Verify right arrow key works
|
|
137
|
-
expect(inputs[1]).toBeInTheDocument();
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
// Test backspace navigation - click on third input and then backspace
|
|
141
|
-
await userEvent.click(inputs[2]);
|
|
142
|
-
await userEvent.keyboard('{Backspace}');
|
|
143
|
-
await waitFor(() => {
|
|
144
|
-
// Verify inputs are functional after backspace
|
|
145
|
-
expect(inputs[0]).toBeEnabled();
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
// Test tab navigation
|
|
149
|
-
await userEvent.click(inputs[0]);
|
|
150
|
-
await userEvent.tab();
|
|
151
|
-
await waitFor(() => {
|
|
152
|
-
// Verify tab moves focus to next focusable element
|
|
153
|
-
expect(inputs[1]).toBeInTheDocument();
|
|
154
|
-
});
|
|
155
|
-
},
|
|
156
|
-
};
|
|
157
|
-
|
|
158
|
-
// Test 4: Screen Reader
|
|
159
|
-
export const ScreenReader: Story = {
|
|
160
|
-
args: {
|
|
161
|
-
variant: 'numeric',
|
|
162
|
-
length: 4,
|
|
163
|
-
color: 'primary',
|
|
164
|
-
'aria-label': 'Enter verification code',
|
|
165
|
-
},
|
|
166
|
-
play: async ({ canvasElement }) => {
|
|
167
|
-
const canvas = within(canvasElement);
|
|
168
|
-
const inputs = canvas.getAllByRole('textbox');
|
|
169
|
-
|
|
170
|
-
// Check that inputs are accessible
|
|
171
|
-
inputs.forEach(async (input) => {
|
|
172
|
-
expect(input).toBeInTheDocument();
|
|
173
|
-
expect(input).toHaveAttribute('maxLength', '1');
|
|
174
|
-
|
|
175
|
-
// Verify inputs can receive focus
|
|
176
|
-
await userEvent.click(input);
|
|
177
|
-
await waitFor(() => expect(input).toHaveFocus());
|
|
178
|
-
await input.blur();
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
// Test ARIA attributes
|
|
182
|
-
const container = inputs[0].closest('[role], div');
|
|
183
|
-
if (container) {
|
|
184
|
-
expect(container).toBeInTheDocument();
|
|
185
|
-
}
|
|
186
|
-
},
|
|
187
|
-
};
|
|
188
|
-
|
|
189
|
-
// Test 5: Focus Management
|
|
190
|
-
export const FocusManagement: Story = {
|
|
191
|
-
args: {
|
|
192
|
-
variant: 'numeric',
|
|
193
|
-
length: 5,
|
|
194
|
-
autoFocus: true,
|
|
195
|
-
onChange: fn(),
|
|
196
|
-
onComplete: fn(),
|
|
197
|
-
},
|
|
198
|
-
play: async ({ canvasElement, args }) => {
|
|
199
|
-
const canvas = within(canvasElement);
|
|
200
|
-
const inputs = canvas.getAllByRole('textbox');
|
|
201
|
-
|
|
202
|
-
// Auto-focus first input
|
|
203
|
-
await waitFor(() => {
|
|
204
|
-
expect(inputs[0]).toHaveFocus();
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
// Focus moves forward on input
|
|
208
|
-
await userEvent.type(inputs[0], '1');
|
|
209
|
-
await waitFor(() => {
|
|
210
|
-
expect(inputs[1]).toHaveFocus();
|
|
211
|
-
});
|
|
212
|
-
|
|
213
|
-
// Focus moves forward on paste (single digit at a time)
|
|
214
|
-
await userEvent.type(inputs[1], '2');
|
|
215
|
-
await waitFor(() => {
|
|
216
|
-
expect(inputs[2]).toHaveFocus();
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
// Complete remaining digits
|
|
220
|
-
await userEvent.type(inputs[2], '3');
|
|
221
|
-
await waitFor(() => {
|
|
222
|
-
expect(inputs[3]).toHaveFocus();
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
await userEvent.type(inputs[3], '4');
|
|
226
|
-
await waitFor(() => {
|
|
227
|
-
expect(inputs[4]).toHaveFocus();
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
await userEvent.type(inputs[4], '5');
|
|
231
|
-
await waitFor(() => {
|
|
232
|
-
expect(args.onChange).toHaveBeenLastCalledWith('12345');
|
|
233
|
-
expect(args.onComplete).toHaveBeenCalledWith('12345');
|
|
234
|
-
});
|
|
235
|
-
},
|
|
236
|
-
};
|
|
237
|
-
|
|
238
|
-
// Test 6: Responsive Design
|
|
239
|
-
export const ResponsiveDesign: Story = {
|
|
240
|
-
args: {
|
|
241
|
-
variant: 'numeric',
|
|
242
|
-
length: 6,
|
|
243
|
-
size: 'md',
|
|
244
|
-
onChange: fn(),
|
|
245
|
-
},
|
|
246
|
-
parameters: {
|
|
247
|
-
viewport: {
|
|
248
|
-
defaultViewport: 'mobile1',
|
|
249
|
-
},
|
|
250
|
-
},
|
|
251
|
-
play: async ({ canvasElement }) => {
|
|
252
|
-
const canvas = within(canvasElement);
|
|
253
|
-
const inputs = canvas.getAllByRole('textbox');
|
|
254
|
-
|
|
255
|
-
// Check all inputs are visible on mobile
|
|
256
|
-
expect(inputs).toHaveLength(6);
|
|
257
|
-
inputs.forEach((input) => {
|
|
258
|
-
expect(input).toBeVisible();
|
|
259
|
-
});
|
|
260
|
-
|
|
261
|
-
// Test touch interaction
|
|
262
|
-
await userEvent.click(inputs[0]);
|
|
263
|
-
await waitFor(() => expect(inputs[0]).toHaveFocus());
|
|
264
|
-
|
|
265
|
-
await userEvent.type(inputs[0], '1');
|
|
266
|
-
await waitFor(() => {
|
|
267
|
-
// Verify input value was set after typing
|
|
268
|
-
expect(inputs[0]).toHaveValue('1');
|
|
269
|
-
});
|
|
270
|
-
},
|
|
271
|
-
};
|
|
272
|
-
|
|
273
|
-
// Test 7: Theme Variations
|
|
274
|
-
export const ThemeVariations: Story = {
|
|
275
|
-
args: {
|
|
276
|
-
variant: 'numeric',
|
|
277
|
-
length: 4,
|
|
278
|
-
color: 'success',
|
|
279
|
-
glass: true,
|
|
280
|
-
gradient: true,
|
|
281
|
-
onChange: fn(),
|
|
282
|
-
},
|
|
283
|
-
play: async ({ canvasElement }) => {
|
|
284
|
-
const canvas = within(canvasElement);
|
|
285
|
-
const inputs = canvas.getAllByRole('textbox');
|
|
286
|
-
|
|
287
|
-
// Verify all inputs are rendered
|
|
288
|
-
expect(inputs).toHaveLength(4);
|
|
289
|
-
|
|
290
|
-
// Test glass and gradient effects don't break functionality
|
|
291
|
-
await userEvent.type(inputs[0], '1');
|
|
292
|
-
expect(inputs[0]).toHaveValue('1');
|
|
293
|
-
|
|
294
|
-
await userEvent.type(inputs[1], '2');
|
|
295
|
-
expect(inputs[1]).toHaveValue('2');
|
|
296
|
-
|
|
297
|
-
// Check visual states
|
|
298
|
-
inputs.forEach((input) => {
|
|
299
|
-
expect(input).toBeVisible();
|
|
300
|
-
expect(input).toBeEnabled();
|
|
301
|
-
});
|
|
302
|
-
},
|
|
303
|
-
};
|
|
304
|
-
|
|
305
|
-
// Test 8: Visual States
|
|
306
|
-
export const VisualStates: Story = {
|
|
307
|
-
args: {
|
|
308
|
-
variant: 'masked',
|
|
309
|
-
length: 6,
|
|
310
|
-
error: false,
|
|
311
|
-
disabled: false,
|
|
312
|
-
onChange: fn(),
|
|
313
|
-
},
|
|
314
|
-
play: async ({ canvasElement, args }) => {
|
|
315
|
-
const canvas = within(canvasElement);
|
|
316
|
-
const inputs = canvas.getAllByRole('textbox');
|
|
317
|
-
|
|
318
|
-
// Test masked variant - values should show as dots
|
|
319
|
-
await userEvent.type(inputs[0], '1');
|
|
320
|
-
await waitFor(() => {
|
|
321
|
-
expect(inputs[0]).toHaveValue('•');
|
|
322
|
-
expect(args.onChange).toHaveBeenCalledWith('1');
|
|
323
|
-
});
|
|
324
|
-
|
|
325
|
-
await userEvent.type(inputs[1], '2');
|
|
326
|
-
await waitFor(() => {
|
|
327
|
-
expect(inputs[1]).toHaveValue('•');
|
|
328
|
-
expect(args.onChange).toHaveBeenCalledWith('12');
|
|
329
|
-
});
|
|
330
|
-
|
|
331
|
-
// Test hover state
|
|
332
|
-
await userEvent.hover(inputs[2]);
|
|
333
|
-
expect(inputs[2]).toBeVisible();
|
|
334
|
-
|
|
335
|
-
// Test focus state
|
|
336
|
-
await userEvent.click(inputs[3]);
|
|
337
|
-
await waitFor(() => expect(inputs[3]).toHaveFocus());
|
|
338
|
-
},
|
|
339
|
-
};
|
|
340
|
-
|
|
341
|
-
// Test 9: Performance
|
|
342
|
-
export const Performance: Story = {
|
|
343
|
-
args: {
|
|
344
|
-
variant: 'numeric',
|
|
345
|
-
length: 8,
|
|
346
|
-
onChange: fn(),
|
|
347
|
-
onComplete: fn(),
|
|
348
|
-
},
|
|
349
|
-
play: async ({ canvasElement, args }) => {
|
|
350
|
-
const canvas = within(canvasElement);
|
|
351
|
-
const inputs = canvas.getAllByRole('textbox');
|
|
352
|
-
|
|
353
|
-
// Rapid input simulation
|
|
354
|
-
for (let i = 0; i < inputs.length; i++) {
|
|
355
|
-
await userEvent.type(inputs[i], String(i + 1));
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
// Verify all changes were captured
|
|
359
|
-
expect(args.onChange).toHaveBeenCalledTimes(8);
|
|
360
|
-
expect(args.onChange).toHaveBeenLastCalledWith('12345678');
|
|
361
|
-
},
|
|
362
|
-
};
|
|
363
|
-
|
|
364
|
-
// Test 10: Edge Cases
|
|
365
|
-
export const EdgeCases: Story = {
|
|
366
|
-
args: {
|
|
367
|
-
variant: 'numeric',
|
|
368
|
-
length: 6,
|
|
369
|
-
onChange: fn(),
|
|
370
|
-
onComplete: fn(),
|
|
371
|
-
},
|
|
372
|
-
play: async ({ canvasElement, args }) => {
|
|
373
|
-
const canvas = within(canvasElement);
|
|
374
|
-
const inputs = canvas.getAllByRole('textbox');
|
|
375
|
-
|
|
376
|
-
// Test invalid input rejection (letters in numeric mode)
|
|
377
|
-
await userEvent.click(inputs[0]);
|
|
378
|
-
await userEvent.type(inputs[0], 'A');
|
|
379
|
-
expect(inputs[0]).toHaveValue('');
|
|
380
|
-
|
|
381
|
-
// Test max length enforcement
|
|
382
|
-
await userEvent.type(inputs[0], '1');
|
|
383
|
-
expect(inputs[0]).toHaveValue('1');
|
|
384
|
-
await waitFor(() => {
|
|
385
|
-
expect(args.onChange).toHaveBeenCalled();
|
|
386
|
-
});
|
|
387
|
-
|
|
388
|
-
// Test additional characters are ignored
|
|
389
|
-
await userEvent.type(inputs[0], '23');
|
|
390
|
-
expect(inputs[0]).toHaveValue('1');
|
|
391
|
-
|
|
392
|
-
// Test empty backspace behavior
|
|
393
|
-
await userEvent.click(inputs[1]);
|
|
394
|
-
await userEvent.keyboard('{Backspace}');
|
|
395
|
-
await waitFor(() => {
|
|
396
|
-
expect(inputs[0]).toHaveFocus();
|
|
397
|
-
});
|
|
398
|
-
|
|
399
|
-
// Test completion callback with full sequence
|
|
400
|
-
await userEvent.type(inputs[0], '1');
|
|
401
|
-
await userEvent.type(inputs[1], '2');
|
|
402
|
-
await userEvent.type(inputs[2], '3');
|
|
403
|
-
await userEvent.type(inputs[3], '4');
|
|
404
|
-
await userEvent.type(inputs[4], '5');
|
|
405
|
-
await userEvent.type(inputs[5], '6');
|
|
406
|
-
|
|
407
|
-
await waitFor(() => {
|
|
408
|
-
expect(args.onComplete).toHaveBeenCalledWith('123456');
|
|
409
|
-
});
|
|
410
|
-
},
|
|
411
|
-
};
|
|
412
|
-
|
|
413
|
-
// Test 11: Integration
|
|
414
|
-
export const Integration: Story = {
|
|
415
|
-
args: {
|
|
416
|
-
variant: 'numeric',
|
|
417
|
-
length: 6,
|
|
418
|
-
color: 'primary',
|
|
419
|
-
size: 'md',
|
|
420
|
-
error: false,
|
|
421
|
-
disabled: false,
|
|
422
|
-
autoFocus: true,
|
|
423
|
-
glass: false,
|
|
424
|
-
gradient: false,
|
|
425
|
-
onChange: fn(),
|
|
426
|
-
onComplete: fn(),
|
|
427
|
-
},
|
|
428
|
-
play: async ({ canvasElement, args }) => {
|
|
429
|
-
const canvas = within(canvasElement);
|
|
430
|
-
const inputs = canvas.getAllByRole('textbox');
|
|
431
|
-
|
|
432
|
-
// Complete flow test
|
|
433
|
-
expect(inputs).toHaveLength(6);
|
|
434
|
-
|
|
435
|
-
// Auto-focus verification
|
|
436
|
-
await waitFor(() => {
|
|
437
|
-
expect(inputs[0]).toHaveFocus();
|
|
438
|
-
});
|
|
439
|
-
|
|
440
|
-
// Type complete OTP
|
|
441
|
-
const otp = '123456';
|
|
442
|
-
for (let i = 0; i < otp.length; i++) {
|
|
443
|
-
await userEvent.type(inputs[i], otp[i]);
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
// Verify completion
|
|
447
|
-
await waitFor(() => {
|
|
448
|
-
expect(args.onComplete).toHaveBeenCalledWith(otp);
|
|
449
|
-
expect(args.onChange).toHaveBeenLastCalledWith(otp);
|
|
450
|
-
});
|
|
451
|
-
|
|
452
|
-
// Clear and re-enter
|
|
453
|
-
for (let i = 0; i < inputs.length; i++) {
|
|
454
|
-
await userEvent.clear(inputs[i]);
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
// Verify cleared state
|
|
458
|
-
inputs.forEach((input) => {
|
|
459
|
-
expect(input).toHaveValue('');
|
|
460
|
-
});
|
|
461
|
-
|
|
462
|
-
// Test error state change
|
|
463
|
-
const container = inputs[0].closest('div');
|
|
464
|
-
expect(container).toBeInTheDocument();
|
|
465
|
-
|
|
466
|
-
// Final state verification
|
|
467
|
-
expect(inputs[0]).toBeEnabled();
|
|
468
|
-
expect(inputs[0]).toBeVisible();
|
|
469
|
-
},
|
|
470
|
-
};
|
|
471
|
-
|
|
472
|
-
// Test 12: TestID Implementation
|
|
473
|
-
export const TestIDImplementation: Story = {
|
|
474
|
-
args: {
|
|
475
|
-
variant: 'numeric',
|
|
476
|
-
length: 6,
|
|
477
|
-
color: 'primary',
|
|
478
|
-
size: 'md',
|
|
479
|
-
dataTestId: 'otp-input',
|
|
480
|
-
onChange: fn(),
|
|
481
|
-
onComplete: fn(),
|
|
482
|
-
},
|
|
483
|
-
play: async ({ canvasElement, args }) => {
|
|
484
|
-
const canvas = within(canvasElement);
|
|
485
|
-
|
|
486
|
-
// Test container testId
|
|
487
|
-
const container = canvas.getByTestId('otp-input');
|
|
488
|
-
expect(container).toBeInTheDocument();
|
|
489
|
-
expect(container).toBeVisible();
|
|
490
|
-
|
|
491
|
-
// Test individual slot testIds
|
|
492
|
-
for (let i = 0; i < 6; i++) {
|
|
493
|
-
const slot = canvas.getByTestId(`otp-input-slot-${i}`);
|
|
494
|
-
expect(slot).toBeInTheDocument();
|
|
495
|
-
expect(slot).toBeVisible();
|
|
496
|
-
expect(slot).toHaveAttribute('maxLength', '1');
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
// Test interaction with testIds
|
|
500
|
-
const firstSlot = canvas.getByTestId('otp-input-slot-0');
|
|
501
|
-
const secondSlot = canvas.getByTestId('otp-input-slot-1');
|
|
502
|
-
const lastSlot = canvas.getByTestId('otp-input-slot-5');
|
|
503
|
-
|
|
504
|
-
// Type in first slot using testId
|
|
505
|
-
await userEvent.type(firstSlot, '1');
|
|
506
|
-
await waitFor(() => {
|
|
507
|
-
expect(firstSlot).toHaveValue('1');
|
|
508
|
-
expect(args.onChange).toHaveBeenCalledWith('1');
|
|
509
|
-
});
|
|
510
|
-
|
|
511
|
-
// Type in second slot using testId
|
|
512
|
-
await userEvent.type(secondSlot, '2');
|
|
513
|
-
await waitFor(() => {
|
|
514
|
-
expect(secondSlot).toHaveValue('2');
|
|
515
|
-
expect(args.onChange).toHaveBeenCalledWith('12');
|
|
516
|
-
});
|
|
517
|
-
|
|
518
|
-
// Complete entire OTP using testIds
|
|
519
|
-
await userEvent.type(canvas.getByTestId('otp-input-slot-2'), '3');
|
|
520
|
-
await userEvent.type(canvas.getByTestId('otp-input-slot-3'), '4');
|
|
521
|
-
await userEvent.type(canvas.getByTestId('otp-input-slot-4'), '5');
|
|
522
|
-
await userEvent.type(lastSlot, '6');
|
|
523
|
-
|
|
524
|
-
// Verify completion callback
|
|
525
|
-
await waitFor(() => {
|
|
526
|
-
expect(args.onComplete).toHaveBeenCalledWith('123456');
|
|
527
|
-
expect(args.onChange).toHaveBeenLastCalledWith('123456');
|
|
528
|
-
});
|
|
529
|
-
|
|
530
|
-
// Verify all slots have correct values
|
|
531
|
-
for (let i = 0; i < 6; i++) {
|
|
532
|
-
const slot = canvas.getByTestId(`otp-input-slot-${i}`);
|
|
533
|
-
expect(slot).toHaveValue(String(i + 1));
|
|
534
|
-
}
|
|
535
|
-
},
|
|
536
|
-
};
|
|
537
|
-
|
|
538
|
-
// Test 13: TestID with Different Lengths
|
|
539
|
-
export const TestIDWithDifferentLengths: Story = {
|
|
540
|
-
args: {
|
|
541
|
-
variant: 'numeric',
|
|
542
|
-
length: 4,
|
|
543
|
-
dataTestId: 'short-otp',
|
|
544
|
-
onChange: fn(),
|
|
545
|
-
},
|
|
546
|
-
play: async ({ canvasElement }) => {
|
|
547
|
-
const canvas = within(canvasElement);
|
|
548
|
-
|
|
549
|
-
// Test container
|
|
550
|
-
const container = canvas.getByTestId('short-otp');
|
|
551
|
-
expect(container).toBeInTheDocument();
|
|
552
|
-
|
|
553
|
-
// Test exactly 4 slots exist
|
|
554
|
-
for (let i = 0; i < 4; i++) {
|
|
555
|
-
const slot = canvas.getByTestId(`short-otp-slot-${i}`);
|
|
556
|
-
expect(slot).toBeInTheDocument();
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
// Verify no extra slots exist
|
|
560
|
-
await waitFor(() => expect(canvas.queryByTestId('short-otp-slot-4')).not.toBeInTheDocument());
|
|
561
|
-
await waitFor(() => expect(canvas.queryByTestId('short-otp-slot-5')).not.toBeInTheDocument());
|
|
562
|
-
},
|
|
563
|
-
};
|
|
564
|
-
|
|
565
|
-
// Test 14: TestID Without DataTestId Prop
|
|
566
|
-
export const TestIDWithoutDataTestIdProp: Story = {
|
|
567
|
-
args: {
|
|
568
|
-
variant: 'numeric',
|
|
569
|
-
length: 6,
|
|
570
|
-
onChange: fn(),
|
|
571
|
-
},
|
|
572
|
-
play: async ({ canvasElement }) => {
|
|
573
|
-
const canvas = within(canvasElement);
|
|
574
|
-
const inputs = canvas.getAllByRole('textbox');
|
|
575
|
-
|
|
576
|
-
// Component should work without testIds
|
|
577
|
-
expect(inputs).toHaveLength(6);
|
|
578
|
-
|
|
579
|
-
// Verify testIds are not present when prop is not provided
|
|
580
|
-
inputs.forEach((input) => {
|
|
581
|
-
expect(input.getAttribute('data-testid')).toBeNull();
|
|
582
|
-
});
|
|
583
|
-
|
|
584
|
-
// Functionality should still work
|
|
585
|
-
await userEvent.type(inputs[0], '1');
|
|
586
|
-
expect(inputs[0]).toHaveValue('1');
|
|
587
|
-
},
|
|
588
|
-
};
|