@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,441 +0,0 @@
|
|
|
1
|
-
import { Box, SvgIcon } from '@mui/material';
|
|
2
|
-
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
3
|
-
import { expect, fn, userEvent, waitFor, within } from 'storybook/test';
|
|
4
|
-
|
|
5
|
-
import { EmptyState } from './EmptyState';
|
|
6
|
-
|
|
7
|
-
// Test illustration component
|
|
8
|
-
const TestIcon = () => (
|
|
9
|
-
<SvgIcon sx={{ fontSize: 64 }} data-testid="empty-state-icon">
|
|
10
|
-
<svg viewBox="0 0 24 24">
|
|
11
|
-
<path
|
|
12
|
-
fill="currentColor"
|
|
13
|
-
d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"
|
|
14
|
-
/>
|
|
15
|
-
</svg>
|
|
16
|
-
</SvgIcon>
|
|
17
|
-
);
|
|
18
|
-
|
|
19
|
-
const meta: Meta<typeof EmptyState> = {
|
|
20
|
-
title: 'DataDisplay/AsyncStates/EmptyState/Tests',
|
|
21
|
-
component: EmptyState,
|
|
22
|
-
parameters: {
|
|
23
|
-
layout: 'centered',
|
|
24
|
-
chromatic: { disableSnapshot: false },
|
|
25
|
-
},
|
|
26
|
-
tags: ['autodocs', 'test', 'component:EmptyState'],
|
|
27
|
-
// Disable auto-action generation for onCreate/onRefresh to prevent them from
|
|
28
|
-
// being truthy when not explicitly passed (otherwise they get auto-mocked by
|
|
29
|
-
// the global argTypesRegex: '^on[A-Z].*' pattern)
|
|
30
|
-
argTypes: {
|
|
31
|
-
onCreate: { action: false },
|
|
32
|
-
onRefresh: { action: false },
|
|
33
|
-
},
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
export default meta;
|
|
37
|
-
export type Story = StoryObj<typeof meta>;
|
|
38
|
-
|
|
39
|
-
// Interaction Tests
|
|
40
|
-
export const BasicInteraction: Story = {
|
|
41
|
-
args: {
|
|
42
|
-
title: 'Basic Interaction Test',
|
|
43
|
-
description: 'Testing basic rendering and accessibility.',
|
|
44
|
-
// Explicitly set to undefined to override auto-generated actions from argTypesRegex
|
|
45
|
-
onCreate: undefined,
|
|
46
|
-
onRefresh: undefined,
|
|
47
|
-
},
|
|
48
|
-
play: async ({ canvasElement }) => {
|
|
49
|
-
const canvas = within(canvasElement);
|
|
50
|
-
|
|
51
|
-
// Test component renders
|
|
52
|
-
const title = canvas.getByRole('heading', { name: 'Basic Interaction Test' });
|
|
53
|
-
await expect(title).toBeInTheDocument();
|
|
54
|
-
|
|
55
|
-
// Test region role
|
|
56
|
-
const region = canvas.getByRole('region');
|
|
57
|
-
await expect(region).toBeInTheDocument();
|
|
58
|
-
|
|
59
|
-
// Test aria-labelledby
|
|
60
|
-
await expect(region).toHaveAttribute('aria-labelledby', title.id);
|
|
61
|
-
|
|
62
|
-
// Test description
|
|
63
|
-
const description = canvas.getByText('Testing basic rendering and accessibility.');
|
|
64
|
-
await expect(description).toBeInTheDocument();
|
|
65
|
-
},
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
export const ActionInteraction: Story = {
|
|
69
|
-
args: {
|
|
70
|
-
title: 'Action Interaction Test',
|
|
71
|
-
description: 'Testing action button interactions.',
|
|
72
|
-
primaryAction: {
|
|
73
|
-
label: 'Primary Action',
|
|
74
|
-
onClick: fn(),
|
|
75
|
-
},
|
|
76
|
-
secondaryAction: {
|
|
77
|
-
label: 'Secondary Action',
|
|
78
|
-
onClick: fn(),
|
|
79
|
-
},
|
|
80
|
-
helpLink: {
|
|
81
|
-
label: 'Help Link',
|
|
82
|
-
href: '#help',
|
|
83
|
-
},
|
|
84
|
-
// Explicitly set to undefined to override auto-generated actions from argTypesRegex
|
|
85
|
-
onCreate: undefined,
|
|
86
|
-
onRefresh: undefined,
|
|
87
|
-
},
|
|
88
|
-
play: async ({ canvasElement, args }) => {
|
|
89
|
-
const canvas = within(canvasElement);
|
|
90
|
-
|
|
91
|
-
// Test primary action click
|
|
92
|
-
const primaryButton = canvas.getByRole('button', { name: 'Primary Action' });
|
|
93
|
-
await expect(primaryButton).toBeInTheDocument();
|
|
94
|
-
await userEvent.click(primaryButton);
|
|
95
|
-
await expect(args.primaryAction?.onClick).toHaveBeenCalledTimes(1);
|
|
96
|
-
|
|
97
|
-
// Test secondary action click
|
|
98
|
-
const secondaryButton = canvas.getByRole('button', { name: 'Secondary Action' });
|
|
99
|
-
await expect(secondaryButton).toBeInTheDocument();
|
|
100
|
-
await userEvent.click(secondaryButton);
|
|
101
|
-
await expect(args.secondaryAction?.onClick).toHaveBeenCalledTimes(1);
|
|
102
|
-
|
|
103
|
-
// Test help link
|
|
104
|
-
const helpLink = canvas.getByRole('link', { name: 'Help Link' });
|
|
105
|
-
await expect(helpLink).toBeInTheDocument();
|
|
106
|
-
await expect(helpLink).toHaveAttribute('href', '#help');
|
|
107
|
-
},
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
export const KeyboardNavigation: Story = {
|
|
111
|
-
args: {
|
|
112
|
-
title: 'Keyboard Navigation Test',
|
|
113
|
-
description: 'Testing keyboard accessibility.',
|
|
114
|
-
primaryAction: {
|
|
115
|
-
label: 'Primary',
|
|
116
|
-
onClick: fn(),
|
|
117
|
-
},
|
|
118
|
-
secondaryAction: {
|
|
119
|
-
label: 'Secondary',
|
|
120
|
-
onClick: fn(),
|
|
121
|
-
},
|
|
122
|
-
helpLink: {
|
|
123
|
-
label: 'Help',
|
|
124
|
-
href: '#help',
|
|
125
|
-
},
|
|
126
|
-
// Explicitly set to undefined to override auto-generated actions from argTypesRegex
|
|
127
|
-
onCreate: undefined,
|
|
128
|
-
onRefresh: undefined,
|
|
129
|
-
},
|
|
130
|
-
play: async ({ canvasElement, args }) => {
|
|
131
|
-
const canvas = within(canvasElement);
|
|
132
|
-
|
|
133
|
-
// Tab to primary button
|
|
134
|
-
await userEvent.tab();
|
|
135
|
-
const primaryButton = canvas.getByRole('button', { name: 'Primary' });
|
|
136
|
-
await waitFor(() => expect(primaryButton).toHaveFocus());
|
|
137
|
-
|
|
138
|
-
// Press Enter to activate
|
|
139
|
-
await userEvent.keyboard('{Enter}');
|
|
140
|
-
await expect(args.primaryAction?.onClick).toHaveBeenCalledTimes(1);
|
|
141
|
-
|
|
142
|
-
// Tab to secondary button
|
|
143
|
-
await userEvent.tab();
|
|
144
|
-
const secondaryButton = canvas.getByRole('button', { name: 'Secondary' });
|
|
145
|
-
await waitFor(() => expect(secondaryButton).toHaveFocus());
|
|
146
|
-
|
|
147
|
-
// Tab to help link
|
|
148
|
-
await userEvent.tab();
|
|
149
|
-
const helpLink = canvas.getByRole('link', { name: 'Help' });
|
|
150
|
-
await waitFor(() => expect(helpLink).toHaveFocus());
|
|
151
|
-
},
|
|
152
|
-
};
|
|
153
|
-
|
|
154
|
-
export const ScreenReader: Story = {
|
|
155
|
-
args: {
|
|
156
|
-
title: 'Screen Reader Test',
|
|
157
|
-
description: 'Testing screen reader accessibility features.',
|
|
158
|
-
illustration: <TestIcon />,
|
|
159
|
-
// Explicitly set to undefined to override auto-generated actions from argTypesRegex
|
|
160
|
-
onCreate: undefined,
|
|
161
|
-
onRefresh: undefined,
|
|
162
|
-
},
|
|
163
|
-
play: async ({ canvasElement }) => {
|
|
164
|
-
const canvas = within(canvasElement);
|
|
165
|
-
|
|
166
|
-
// Test region has proper labeling
|
|
167
|
-
const region = canvas.getByRole('region');
|
|
168
|
-
const heading = canvas.getByRole('heading');
|
|
169
|
-
await expect(region).toHaveAttribute('aria-labelledby', heading.id);
|
|
170
|
-
|
|
171
|
-
// Test heading structure
|
|
172
|
-
await expect(heading).toHaveAttribute('id');
|
|
173
|
-
await expect(heading.tagName).toBe('H3');
|
|
174
|
-
|
|
175
|
-
// Test illustration accessibility
|
|
176
|
-
const icon = canvas.getAllByTestId('empty-state-icon')[0];
|
|
177
|
-
await expect(icon).toBeInTheDocument();
|
|
178
|
-
},
|
|
179
|
-
};
|
|
180
|
-
|
|
181
|
-
export const FocusManagement: Story = {
|
|
182
|
-
args: {
|
|
183
|
-
title: 'Focus Management Test',
|
|
184
|
-
description: 'Testing focus behavior and management.',
|
|
185
|
-
primaryAction: {
|
|
186
|
-
label: 'Focus Test Button',
|
|
187
|
-
onClick: fn(),
|
|
188
|
-
},
|
|
189
|
-
helpLink: {
|
|
190
|
-
label: 'Focus Test Link',
|
|
191
|
-
href: '#focus',
|
|
192
|
-
},
|
|
193
|
-
// Explicitly set to undefined to override auto-generated actions from argTypesRegex
|
|
194
|
-
onCreate: undefined,
|
|
195
|
-
onRefresh: undefined,
|
|
196
|
-
},
|
|
197
|
-
play: async ({ canvasElement }) => {
|
|
198
|
-
const canvas = within(canvasElement);
|
|
199
|
-
|
|
200
|
-
// Test initial focus state
|
|
201
|
-
const button = canvas.getByRole('button', { name: 'Focus Test Button' });
|
|
202
|
-
const link = canvas.getByRole('link', { name: 'Focus Test Link' });
|
|
203
|
-
|
|
204
|
-
// Test focus indicators are visible
|
|
205
|
-
await userEvent.tab();
|
|
206
|
-
await waitFor(() => expect(button).toHaveFocus());
|
|
207
|
-
|
|
208
|
-
await userEvent.tab();
|
|
209
|
-
await waitFor(() => expect(link).toHaveFocus());
|
|
210
|
-
|
|
211
|
-
// Test focus trap doesn't exist (buttons should be focusable)
|
|
212
|
-
await userEvent.tab();
|
|
213
|
-
await waitFor(() => expect(link).not.toHaveFocus());
|
|
214
|
-
},
|
|
215
|
-
};
|
|
216
|
-
|
|
217
|
-
export const ResponsiveDesign: Story = {
|
|
218
|
-
args: {
|
|
219
|
-
title: 'Responsive Design Test',
|
|
220
|
-
description: 'Testing responsive behavior across viewport sizes.',
|
|
221
|
-
variant: 'action',
|
|
222
|
-
primaryAction: {
|
|
223
|
-
label: 'Primary',
|
|
224
|
-
onClick: fn(),
|
|
225
|
-
},
|
|
226
|
-
secondaryAction: {
|
|
227
|
-
label: 'Secondary',
|
|
228
|
-
onClick: fn(),
|
|
229
|
-
},
|
|
230
|
-
// Explicitly set to undefined to override auto-generated actions from argTypesRegex
|
|
231
|
-
onCreate: undefined,
|
|
232
|
-
onRefresh: undefined,
|
|
233
|
-
},
|
|
234
|
-
parameters: {
|
|
235
|
-
viewport: {
|
|
236
|
-
viewports: {
|
|
237
|
-
mobile: { name: 'Mobile', styles: { width: '375px', height: '667px' } },
|
|
238
|
-
tablet: { name: 'Tablet', styles: { width: '768px', height: '1024px' } },
|
|
239
|
-
},
|
|
240
|
-
},
|
|
241
|
-
},
|
|
242
|
-
play: async ({ canvasElement }) => {
|
|
243
|
-
const canvas = within(canvasElement);
|
|
244
|
-
|
|
245
|
-
// Test buttons are present and accessible
|
|
246
|
-
const primaryButton = canvas.getByRole('button', { name: 'Primary' });
|
|
247
|
-
const secondaryButton = canvas.getByRole('button', { name: 'Secondary' });
|
|
248
|
-
|
|
249
|
-
await expect(primaryButton).toBeInTheDocument();
|
|
250
|
-
await expect(secondaryButton).toBeInTheDocument();
|
|
251
|
-
|
|
252
|
-
// Test responsive text wrapping
|
|
253
|
-
const title = canvas.getByRole('heading');
|
|
254
|
-
await expect(title).toBeInTheDocument();
|
|
255
|
-
},
|
|
256
|
-
};
|
|
257
|
-
|
|
258
|
-
export const ThemeVariations: Story = {
|
|
259
|
-
args: {
|
|
260
|
-
title: 'Theme Variations Test',
|
|
261
|
-
description: 'Testing theme compatibility and color contrast.',
|
|
262
|
-
illustration: <TestIcon />,
|
|
263
|
-
// Explicitly set to undefined to override auto-generated actions from argTypesRegex
|
|
264
|
-
onCreate: undefined,
|
|
265
|
-
onRefresh: undefined,
|
|
266
|
-
},
|
|
267
|
-
parameters: {
|
|
268
|
-
backgrounds: {
|
|
269
|
-
default: 'dark',
|
|
270
|
-
values: [
|
|
271
|
-
{ name: 'light', value: '#ffffff' },
|
|
272
|
-
{ name: 'dark', value: '#1a1a1a' },
|
|
273
|
-
],
|
|
274
|
-
},
|
|
275
|
-
},
|
|
276
|
-
play: async ({ canvasElement }) => {
|
|
277
|
-
const canvas = within(canvasElement);
|
|
278
|
-
|
|
279
|
-
// Test component renders in different themes
|
|
280
|
-
const title = canvas.getByRole('heading', { name: 'Theme Variations Test' });
|
|
281
|
-
await expect(title).toBeInTheDocument();
|
|
282
|
-
|
|
283
|
-
const description = canvas.getByText('Testing theme compatibility and color contrast.');
|
|
284
|
-
await expect(description).toBeInTheDocument();
|
|
285
|
-
|
|
286
|
-
// Test icon renders
|
|
287
|
-
const icon = canvas.getAllByTestId('empty-state-icon')[0];
|
|
288
|
-
await expect(icon).toBeInTheDocument();
|
|
289
|
-
},
|
|
290
|
-
};
|
|
291
|
-
|
|
292
|
-
export const VisualStates: Story = {
|
|
293
|
-
render: () => (
|
|
294
|
-
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
|
|
295
|
-
<EmptyState title="Default State" description="Default visual appearance." />
|
|
296
|
-
<EmptyState
|
|
297
|
-
variant="illustrated"
|
|
298
|
-
title="Illustrated State"
|
|
299
|
-
description="With illustration visual state."
|
|
300
|
-
illustration={<TestIcon />}
|
|
301
|
-
/>
|
|
302
|
-
<EmptyState
|
|
303
|
-
variant="minimal"
|
|
304
|
-
title="Minimal State"
|
|
305
|
-
description="Minimal visual appearance."
|
|
306
|
-
/>
|
|
307
|
-
<EmptyState
|
|
308
|
-
variant="action"
|
|
309
|
-
title="Action State"
|
|
310
|
-
description="With action buttons."
|
|
311
|
-
primaryAction={{
|
|
312
|
-
label: 'Primary',
|
|
313
|
-
onClick: () => {},
|
|
314
|
-
}}
|
|
315
|
-
/>
|
|
316
|
-
</Box>
|
|
317
|
-
),
|
|
318
|
-
play: async ({ canvasElement }) => {
|
|
319
|
-
const canvas = within(canvasElement);
|
|
320
|
-
|
|
321
|
-
// Test all visual states render
|
|
322
|
-
const states = ['Default State', 'Illustrated State', 'Minimal State', 'Action State'];
|
|
323
|
-
|
|
324
|
-
for (const stateName of states) {
|
|
325
|
-
const heading = canvas.getByRole('heading', { name: stateName });
|
|
326
|
-
await expect(heading).toBeInTheDocument();
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
// Test action button in action state
|
|
330
|
-
const actionButton = canvas.getByRole('button', { name: 'Primary' });
|
|
331
|
-
await expect(actionButton).toBeInTheDocument();
|
|
332
|
-
},
|
|
333
|
-
};
|
|
334
|
-
|
|
335
|
-
export const Performance: Story = {
|
|
336
|
-
args: {
|
|
337
|
-
title: 'Performance Test',
|
|
338
|
-
description: 'Testing component render performance.',
|
|
339
|
-
illustration: <TestIcon />,
|
|
340
|
-
primaryAction: {
|
|
341
|
-
label: 'Performance Action',
|
|
342
|
-
onClick: fn(),
|
|
343
|
-
},
|
|
344
|
-
// Explicitly set to undefined to override auto-generated actions from argTypesRegex
|
|
345
|
-
onCreate: undefined,
|
|
346
|
-
onRefresh: undefined,
|
|
347
|
-
},
|
|
348
|
-
parameters: {
|
|
349
|
-
chromatic: { disableSnapshot: true },
|
|
350
|
-
},
|
|
351
|
-
play: async ({ canvasElement, args }) => {
|
|
352
|
-
const canvas = within(canvasElement);
|
|
353
|
-
|
|
354
|
-
// Test all key elements are present
|
|
355
|
-
const title = canvas.getByRole('heading', { name: 'Performance Test' });
|
|
356
|
-
const description = canvas.getByText('Testing component render performance.');
|
|
357
|
-
const icon = canvas.getAllByTestId('empty-state-icon')[0];
|
|
358
|
-
const button = canvas.getByRole('button', { name: 'Performance Action' });
|
|
359
|
-
|
|
360
|
-
await expect(title).toBeInTheDocument();
|
|
361
|
-
await expect(description).toBeInTheDocument();
|
|
362
|
-
await expect(icon).toBeInTheDocument();
|
|
363
|
-
await expect(button).toBeInTheDocument();
|
|
364
|
-
|
|
365
|
-
// Test interaction performance
|
|
366
|
-
await userEvent.click(button);
|
|
367
|
-
await waitFor(
|
|
368
|
-
() => expect(args.primaryAction?.onClick).toHaveBeenCalled(),
|
|
369
|
-
{ timeout: 3000 }
|
|
370
|
-
);
|
|
371
|
-
|
|
372
|
-
// Verify click handler was called exactly once
|
|
373
|
-
await expect(args.primaryAction?.onClick).toHaveBeenCalledTimes(1);
|
|
374
|
-
},
|
|
375
|
-
};
|
|
376
|
-
|
|
377
|
-
export const EdgeCases: Story = {
|
|
378
|
-
args: {
|
|
379
|
-
title:
|
|
380
|
-
'Very Long Title That Should Wrap Properly Even When It Exceeds The Maximum Width Of The Container And Continues To Be Very Long',
|
|
381
|
-
description:
|
|
382
|
-
'Very long description text that should wrap properly and maintain readability even when it contains a lot of content and exceeds the normal expected length for description text in an empty state component. This should handle text overflow gracefully.',
|
|
383
|
-
helpLink: {
|
|
384
|
-
label: 'Very Long Help Link Text That Should Also Handle Overflow Gracefully',
|
|
385
|
-
href: '#very-long-url-that-might-cause-layout-issues-if-not-handled-properly',
|
|
386
|
-
external: true,
|
|
387
|
-
},
|
|
388
|
-
// Explicitly set to undefined to override auto-generated actions from argTypesRegex
|
|
389
|
-
onCreate: undefined,
|
|
390
|
-
onRefresh: undefined,
|
|
391
|
-
},
|
|
392
|
-
play: async ({ canvasElement }) => {
|
|
393
|
-
const canvas = within(canvasElement);
|
|
394
|
-
|
|
395
|
-
// Test long title renders and wraps
|
|
396
|
-
const title = canvas.getByRole('heading');
|
|
397
|
-
await expect(title).toBeInTheDocument();
|
|
398
|
-
|
|
399
|
-
// Test long description renders
|
|
400
|
-
const description = canvas.getByText(/Very long description text/);
|
|
401
|
-
await expect(description).toBeInTheDocument();
|
|
402
|
-
|
|
403
|
-
// Test long help link renders
|
|
404
|
-
const helpLink = canvas.getByRole('link');
|
|
405
|
-
await expect(helpLink).toBeInTheDocument();
|
|
406
|
-
await expect(helpLink).toHaveAttribute('target', '_blank');
|
|
407
|
-
await expect(helpLink).toHaveAttribute('rel', 'noopener noreferrer');
|
|
408
|
-
},
|
|
409
|
-
};
|
|
410
|
-
|
|
411
|
-
export const Integration: Story = {
|
|
412
|
-
render: () => (
|
|
413
|
-
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2, p: 2, border: '1px solid #ddd' }}>
|
|
414
|
-
<Box sx={{ p: 2, bgcolor: 'background.paper', borderRadius: 1 }}>
|
|
415
|
-
<EmptyState
|
|
416
|
-
title="Integrated Empty State"
|
|
417
|
-
description="This empty state is integrated within other components."
|
|
418
|
-
primaryAction={{
|
|
419
|
-
label: 'Integrated Action',
|
|
420
|
-
onClick: fn(),
|
|
421
|
-
}}
|
|
422
|
-
/>
|
|
423
|
-
</Box>
|
|
424
|
-
</Box>
|
|
425
|
-
),
|
|
426
|
-
play: async ({ canvasElement }) => {
|
|
427
|
-
const canvas = within(canvasElement);
|
|
428
|
-
|
|
429
|
-
// Test integration within container
|
|
430
|
-
const title = canvas.getByRole('heading', { name: 'Integrated Empty State' });
|
|
431
|
-
await expect(title).toBeInTheDocument();
|
|
432
|
-
|
|
433
|
-
// Test integrated action works
|
|
434
|
-
const button = canvas.getByRole('button', { name: 'Integrated Action' });
|
|
435
|
-
await expect(button).toBeInTheDocument();
|
|
436
|
-
|
|
437
|
-
// Test container integration doesn't break functionality
|
|
438
|
-
const region = canvas.getByRole('region');
|
|
439
|
-
await expect(region).toBeInTheDocument();
|
|
440
|
-
},
|
|
441
|
-
};
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import BugReportIcon from '@mui/icons-material/BugReport';
|
|
2
|
-
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
3
|
-
import { fn } from 'storybook/test';
|
|
4
|
-
|
|
5
|
-
import { ErrorState } from './ErrorState';
|
|
6
|
-
|
|
7
|
-
const meta: Meta<typeof ErrorState> = {
|
|
8
|
-
title: 'DataDisplay/AsyncStates/ErrorState',
|
|
9
|
-
component: ErrorState,
|
|
10
|
-
parameters: {
|
|
11
|
-
layout: 'centered',
|
|
12
|
-
docs: {
|
|
13
|
-
description: {
|
|
14
|
-
component:
|
|
15
|
-
'An error state component that displays error messages with optional retry functionality.',
|
|
16
|
-
},
|
|
17
|
-
},
|
|
18
|
-
},
|
|
19
|
-
tags: ['autodocs', 'component:ErrorState'],
|
|
20
|
-
argTypes: {
|
|
21
|
-
severity: {
|
|
22
|
-
control: 'radio',
|
|
23
|
-
options: ['error', 'warning'],
|
|
24
|
-
description: 'Visual severity of the error state',
|
|
25
|
-
},
|
|
26
|
-
message: {
|
|
27
|
-
control: 'text',
|
|
28
|
-
description: 'The error message to display',
|
|
29
|
-
},
|
|
30
|
-
title: {
|
|
31
|
-
control: 'text',
|
|
32
|
-
description: 'Optional title for the error state',
|
|
33
|
-
},
|
|
34
|
-
retryLabel: {
|
|
35
|
-
control: 'text',
|
|
36
|
-
description: 'Custom label for the retry button',
|
|
37
|
-
},
|
|
38
|
-
onRetry: {
|
|
39
|
-
action: 'retry clicked',
|
|
40
|
-
},
|
|
41
|
-
},
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
export default meta;
|
|
45
|
-
type Story = StoryObj<typeof meta>;
|
|
46
|
-
|
|
47
|
-
export const Default: Story = {
|
|
48
|
-
args: {
|
|
49
|
-
message: 'Something went wrong while loading the data.',
|
|
50
|
-
},
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
export const WithTitle: Story = {
|
|
54
|
-
args: {
|
|
55
|
-
title: 'Connection Error',
|
|
56
|
-
message: 'Unable to connect to the server. Please check your internet connection.',
|
|
57
|
-
onRetry: fn(),
|
|
58
|
-
},
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
export const WithRetryButton: Story = {
|
|
62
|
-
args: {
|
|
63
|
-
message: 'Failed to load data. Please try again.',
|
|
64
|
-
onRetry: fn(),
|
|
65
|
-
},
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
export const CustomRetryLabel: Story = {
|
|
69
|
-
args: {
|
|
70
|
-
message: 'The request timed out.',
|
|
71
|
-
onRetry: fn(),
|
|
72
|
-
retryLabel: 'Try Again',
|
|
73
|
-
},
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
export const WarningSeverity: Story = {
|
|
77
|
-
args: {
|
|
78
|
-
severity: 'warning',
|
|
79
|
-
title: 'Warning',
|
|
80
|
-
message: 'Some items could not be loaded. You can continue with partial data.',
|
|
81
|
-
onRetry: fn(),
|
|
82
|
-
},
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
export const NetworkError: Story = {
|
|
86
|
-
args: {
|
|
87
|
-
title: 'Network Error',
|
|
88
|
-
message: 'Unable to reach the server. Please check your connection and try again.',
|
|
89
|
-
onRetry: fn(),
|
|
90
|
-
},
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
export const ServerError: Story = {
|
|
94
|
-
args: {
|
|
95
|
-
title: 'Server Error',
|
|
96
|
-
message: 'The server encountered an unexpected error. Our team has been notified.',
|
|
97
|
-
onRetry: fn(),
|
|
98
|
-
retryLabel: 'Reload Page',
|
|
99
|
-
},
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
export const CustomIcon: Story = {
|
|
103
|
-
args: {
|
|
104
|
-
title: 'Bug Detected',
|
|
105
|
-
message: "We've found a bug in your code. Please review the error logs.",
|
|
106
|
-
icon: <BugReportIcon sx={{ fontSize: 48, color: 'error.main' }} />,
|
|
107
|
-
onRetry: fn(),
|
|
108
|
-
retryLabel: 'View Logs',
|
|
109
|
-
},
|
|
110
|
-
};
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
-
import { expect, fn, userEvent, waitFor, within } from 'storybook/test';
|
|
3
|
-
|
|
4
|
-
import { ErrorState } from './ErrorState';
|
|
5
|
-
|
|
6
|
-
const meta: Meta<typeof ErrorState> = {
|
|
7
|
-
title: 'DataDisplay/AsyncStates/ErrorState/Tests',
|
|
8
|
-
component: ErrorState,
|
|
9
|
-
parameters: {
|
|
10
|
-
layout: 'padded',
|
|
11
|
-
chromatic: { disableSnapshot: false },
|
|
12
|
-
},
|
|
13
|
-
tags: ['autodocs', 'test', 'component:ErrorState'],
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export default meta;
|
|
17
|
-
type Story = StoryObj<typeof meta>;
|
|
18
|
-
|
|
19
|
-
export const AccessibilityTest: Story = {
|
|
20
|
-
name: '🧪 Accessibility Attributes',
|
|
21
|
-
args: {
|
|
22
|
-
title: 'Error Title',
|
|
23
|
-
message: 'An error occurred while loading data.',
|
|
24
|
-
},
|
|
25
|
-
play: async ({ canvasElement, step }) => {
|
|
26
|
-
const canvas = within(canvasElement);
|
|
27
|
-
|
|
28
|
-
await step('Verify error state container exists', async () => {
|
|
29
|
-
const container = canvas.getByTestId('error-state');
|
|
30
|
-
await expect(container).toBeInTheDocument();
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
await step('Verify alert role for accessibility', async () => {
|
|
34
|
-
const container = canvas.getByTestId('error-state');
|
|
35
|
-
await expect(container).toHaveAttribute('role', 'alert');
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
await step('Verify title is displayed', async () => {
|
|
39
|
-
const title = canvas.getByTestId('error-state-title');
|
|
40
|
-
await expect(title).toHaveTextContent('Error Title');
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
await step('Verify message is displayed', async () => {
|
|
44
|
-
const message = canvas.getByTestId('error-state-message');
|
|
45
|
-
await expect(message).toHaveTextContent('An error occurred while loading data.');
|
|
46
|
-
});
|
|
47
|
-
},
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
export const RetryButtonInteraction: Story = {
|
|
51
|
-
name: '🧪 Retry Button Click',
|
|
52
|
-
args: {
|
|
53
|
-
message: 'Failed to load data.',
|
|
54
|
-
onRetry: fn(),
|
|
55
|
-
},
|
|
56
|
-
play: async ({ canvasElement, args, step }) => {
|
|
57
|
-
const canvas = within(canvasElement);
|
|
58
|
-
|
|
59
|
-
await step('Verify retry button is present', async () => {
|
|
60
|
-
const retryButton = canvas.getByTestId('error-state-retry-button');
|
|
61
|
-
await expect(retryButton).toBeInTheDocument();
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
await step('Click retry button', async () => {
|
|
65
|
-
const retryButton = canvas.getByTestId('error-state-retry-button');
|
|
66
|
-
await userEvent.click(retryButton);
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
await step('Verify onRetry callback was called', async () => {
|
|
70
|
-
await expect(args.onRetry).toHaveBeenCalledTimes(1);
|
|
71
|
-
});
|
|
72
|
-
},
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
export const CustomRetryLabel: Story = {
|
|
76
|
-
name: '🧪 Custom Retry Label',
|
|
77
|
-
args: {
|
|
78
|
-
message: 'Request failed.',
|
|
79
|
-
onRetry: fn(),
|
|
80
|
-
retryLabel: 'Try Again',
|
|
81
|
-
},
|
|
82
|
-
play: async ({ canvasElement, step }) => {
|
|
83
|
-
const canvas = within(canvasElement);
|
|
84
|
-
|
|
85
|
-
await step('Verify custom retry label is displayed', async () => {
|
|
86
|
-
const retryButton = canvas.getByTestId('error-state-retry-button');
|
|
87
|
-
await expect(retryButton).toHaveTextContent('Try Again');
|
|
88
|
-
});
|
|
89
|
-
},
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
export const WarningSeverityTest: Story = {
|
|
93
|
-
name: '🧪 Warning Severity',
|
|
94
|
-
args: {
|
|
95
|
-
severity: 'warning',
|
|
96
|
-
message: 'Some items could not be loaded.',
|
|
97
|
-
},
|
|
98
|
-
play: async ({ canvasElement, step }) => {
|
|
99
|
-
const canvas = within(canvasElement);
|
|
100
|
-
|
|
101
|
-
await step('Verify error state renders with warning severity', async () => {
|
|
102
|
-
const container = canvas.getByTestId('error-state');
|
|
103
|
-
await expect(container).toBeInTheDocument();
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
await step('Verify icon container exists', async () => {
|
|
107
|
-
const icon = canvas.getByTestId('error-state-icon');
|
|
108
|
-
await expect(icon).toBeInTheDocument();
|
|
109
|
-
});
|
|
110
|
-
},
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
export const KeyboardNavigation: Story = {
|
|
114
|
-
name: '🧪 Keyboard Navigation',
|
|
115
|
-
args: {
|
|
116
|
-
message: 'Error occurred.',
|
|
117
|
-
onRetry: fn(),
|
|
118
|
-
},
|
|
119
|
-
play: async ({ canvasElement, args, step }) => {
|
|
120
|
-
const canvas = within(canvasElement);
|
|
121
|
-
|
|
122
|
-
await step('Focus retry button via Tab', async () => {
|
|
123
|
-
await userEvent.tab();
|
|
124
|
-
const retryButton = canvas.getByTestId('error-state-retry-button');
|
|
125
|
-
await waitFor(() => expect(retryButton).toHaveFocus());
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
await step('Activate button with Enter key', async () => {
|
|
129
|
-
await userEvent.keyboard('{Enter}');
|
|
130
|
-
await expect(args.onRetry).toHaveBeenCalled();
|
|
131
|
-
});
|
|
132
|
-
},
|
|
133
|
-
};
|