@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.
- package/package.json +17 -8
- 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 -77
- 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 -753
- 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 -503
- package/src/components/data-display/Carousel/Carousel.stories.tsx +0 -607
- package/src/components/data-display/Carousel/Carousel.test.stories.tsx +0 -691
- 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 -1101
- 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 -955
- 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 -975
- 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 -909
- 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 -918
- 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 -750
- 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 -472
- 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 -762
- 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,918 +0,0 @@
|
|
|
1
|
-
import { Box, Typography } from '@mui/material';
|
|
2
|
-
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
3
|
-
import {
|
|
4
|
-
AlignCenter,
|
|
5
|
-
AlignLeft,
|
|
6
|
-
AlignRight,
|
|
7
|
-
Bold,
|
|
8
|
-
Bookmark,
|
|
9
|
-
Heart,
|
|
10
|
-
Italic,
|
|
11
|
-
Monitor,
|
|
12
|
-
Moon,
|
|
13
|
-
Star,
|
|
14
|
-
Sun,
|
|
15
|
-
Underline,
|
|
16
|
-
} from 'lucide-react';
|
|
17
|
-
import React from 'react';
|
|
18
|
-
import { expect, fn,userEvent, waitFor, within } from 'storybook/test';
|
|
19
|
-
|
|
20
|
-
import { ToggleGroup } from './ToggleGroup';
|
|
21
|
-
|
|
22
|
-
const meta: Meta<typeof ToggleGroup> = {
|
|
23
|
-
title: 'Form/ToggleGroup/Tests',
|
|
24
|
-
component: ToggleGroup,
|
|
25
|
-
parameters: {
|
|
26
|
-
layout: 'centered',
|
|
27
|
-
chromatic: { disableSnapshot: false },
|
|
28
|
-
},
|
|
29
|
-
tags: ['autodocs', 'test', 'component:ToggleGroup'],
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
export default meta;
|
|
33
|
-
type Story = StoryObj<typeof meta>;
|
|
34
|
-
|
|
35
|
-
// Test options for different scenarios
|
|
36
|
-
const formatOptions = [
|
|
37
|
-
{ value: 'bold', label: 'Bold', icon: <Bold size={16} /> },
|
|
38
|
-
{ value: 'italic', label: 'Italic', icon: <Italic size={16} /> },
|
|
39
|
-
{ value: 'underline', label: 'Underline', icon: <Underline size={16} /> },
|
|
40
|
-
];
|
|
41
|
-
|
|
42
|
-
const alignOptions = [
|
|
43
|
-
{ value: 'left', label: 'Left', icon: <AlignLeft size={16} /> },
|
|
44
|
-
{ value: 'center', label: 'Center', icon: <AlignCenter size={16} /> },
|
|
45
|
-
{ value: 'right', label: 'Right', icon: <AlignRight size={16} /> },
|
|
46
|
-
];
|
|
47
|
-
|
|
48
|
-
const themeOptions = [
|
|
49
|
-
{ value: 'light', label: 'Light', icon: <Sun size={16} /> },
|
|
50
|
-
{ value: 'dark', label: 'Dark', icon: <Moon size={16} /> },
|
|
51
|
-
{ value: 'system', label: 'System', icon: <Monitor size={16} /> },
|
|
52
|
-
];
|
|
53
|
-
|
|
54
|
-
const actionOptions = [
|
|
55
|
-
{ value: 'like', label: 'Like', icon: <Heart size={16} /> },
|
|
56
|
-
{ value: 'star', label: 'Star', icon: <Star size={16} /> },
|
|
57
|
-
{ value: 'bookmark', label: 'Save', icon: <Bookmark size={16} /> },
|
|
58
|
-
];
|
|
59
|
-
|
|
60
|
-
const optionsWithDisabled = [
|
|
61
|
-
{ value: 'option1', label: 'Available', icon: <Star size={16} /> },
|
|
62
|
-
{ value: 'option2', label: 'Disabled', icon: <Heart size={16} />, disabled: true },
|
|
63
|
-
{ value: 'option3', label: 'Available', icon: <Bookmark size={16} /> },
|
|
64
|
-
];
|
|
65
|
-
|
|
66
|
-
// Component for controlled testing
|
|
67
|
-
const ControlledBasicInteraction = () => {
|
|
68
|
-
const [value, setValue] = React.useState<string>('');
|
|
69
|
-
|
|
70
|
-
return (
|
|
71
|
-
<ToggleGroup
|
|
72
|
-
options={alignOptions}
|
|
73
|
-
variant="single"
|
|
74
|
-
value={value}
|
|
75
|
-
onChange={(_, newValue) => setValue(newValue || '')}
|
|
76
|
-
/>
|
|
77
|
-
);
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
// 1. Basic Interaction Tests
|
|
81
|
-
export const BasicInteraction: Story = {
|
|
82
|
-
render: () => <ControlledBasicInteraction />,
|
|
83
|
-
play: async ({ canvasElement }) => {
|
|
84
|
-
const canvas = within(canvasElement);
|
|
85
|
-
|
|
86
|
-
// Test initial state
|
|
87
|
-
const toggleButtons = canvas.getAllByRole('button');
|
|
88
|
-
expect(toggleButtons).toHaveLength(3);
|
|
89
|
-
|
|
90
|
-
// Test clicking a button
|
|
91
|
-
await userEvent.click(toggleButtons[0]);
|
|
92
|
-
|
|
93
|
-
// Verify button state changes
|
|
94
|
-
await waitFor(() => {
|
|
95
|
-
expect(toggleButtons[0]).toHaveAttribute('aria-pressed', 'true');
|
|
96
|
-
});
|
|
97
|
-
},
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
// 2. Form Interaction Tests
|
|
101
|
-
export const FormInteraction: Story = {
|
|
102
|
-
args: {
|
|
103
|
-
options: formatOptions,
|
|
104
|
-
variant: 'multiple',
|
|
105
|
-
onChange: fn(),
|
|
106
|
-
value: [],
|
|
107
|
-
},
|
|
108
|
-
play: async ({ canvasElement, args }) => {
|
|
109
|
-
const canvas = within(canvasElement);
|
|
110
|
-
|
|
111
|
-
const toggleButtons = canvas.getAllByRole('button');
|
|
112
|
-
|
|
113
|
-
// Test multiple selection
|
|
114
|
-
await userEvent.click(toggleButtons[0]); // Bold
|
|
115
|
-
await userEvent.click(toggleButtons[2]); // Underline
|
|
116
|
-
|
|
117
|
-
// Verify both calls were made
|
|
118
|
-
await waitFor(() => {
|
|
119
|
-
expect(args.onChange).toHaveBeenCalledTimes(2);
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
// Test deselection
|
|
123
|
-
await userEvent.click(toggleButtons[0]); // Unselect Bold
|
|
124
|
-
|
|
125
|
-
await waitFor(() => {
|
|
126
|
-
expect(args.onChange).toHaveBeenCalledTimes(3);
|
|
127
|
-
});
|
|
128
|
-
},
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
// 3. Keyboard Navigation Tests
|
|
132
|
-
export const KeyboardNavigation: Story = {
|
|
133
|
-
args: {
|
|
134
|
-
options: alignOptions,
|
|
135
|
-
variant: 'single',
|
|
136
|
-
onChange: fn(),
|
|
137
|
-
},
|
|
138
|
-
play: async ({ canvasElement, args }) => {
|
|
139
|
-
const canvas = within(canvasElement);
|
|
140
|
-
|
|
141
|
-
const firstButton = canvas.getAllByRole('button')[0];
|
|
142
|
-
|
|
143
|
-
// Focus the first button
|
|
144
|
-
firstButton.focus();
|
|
145
|
-
await waitFor(() => {
|
|
146
|
-
expect(firstButton).toHaveFocus();
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
// Test Tab navigation between buttons (MUI default behavior)
|
|
150
|
-
await userEvent.tab();
|
|
151
|
-
const secondButton = canvas.getAllByRole('button')[1];
|
|
152
|
-
await waitFor(() => {
|
|
153
|
-
expect(secondButton).toHaveFocus();
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
// Test Space key activation
|
|
157
|
-
await userEvent.keyboard(' ');
|
|
158
|
-
await waitFor(() => {
|
|
159
|
-
expect(args.onChange).toHaveBeenCalled();
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
// Test Enter key activation
|
|
163
|
-
await userEvent.keyboard('{Enter}');
|
|
164
|
-
await waitFor(() => {
|
|
165
|
-
expect(args.onChange).toHaveBeenCalledTimes(2);
|
|
166
|
-
});
|
|
167
|
-
},
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
// 4. Screen Reader Tests
|
|
171
|
-
export const ScreenReader: Story = {
|
|
172
|
-
args: {
|
|
173
|
-
options: themeOptions,
|
|
174
|
-
variant: 'single',
|
|
175
|
-
'aria-label': 'Theme selector',
|
|
176
|
-
},
|
|
177
|
-
play: async ({ canvasElement }) => {
|
|
178
|
-
const canvas = within(canvasElement);
|
|
179
|
-
|
|
180
|
-
// Test ARIA attributes
|
|
181
|
-
const toggleGroup = canvas.getByRole('group');
|
|
182
|
-
expect(toggleGroup).toBeInTheDocument();
|
|
183
|
-
|
|
184
|
-
// Test button roles and labels
|
|
185
|
-
const buttons = canvas.getAllByRole('button');
|
|
186
|
-
|
|
187
|
-
buttons.forEach((button, index) => {
|
|
188
|
-
// MUI ToggleButton doesn't explicitly set role="button" as it's implicit
|
|
189
|
-
expect(button.tagName.toLowerCase()).toBe('button');
|
|
190
|
-
expect(button).toHaveAttribute('aria-pressed');
|
|
191
|
-
|
|
192
|
-
// Verify accessible names
|
|
193
|
-
const option = themeOptions[index];
|
|
194
|
-
expect(button).toHaveAccessibleName(expect.stringContaining(option.label));
|
|
195
|
-
});
|
|
196
|
-
},
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
// 5. Focus Management Tests
|
|
200
|
-
export const FocusManagement: Story = {
|
|
201
|
-
args: {
|
|
202
|
-
options: actionOptions,
|
|
203
|
-
variant: 'single',
|
|
204
|
-
onChange: fn(),
|
|
205
|
-
},
|
|
206
|
-
play: async ({ canvasElement }) => {
|
|
207
|
-
const canvas = within(canvasElement);
|
|
208
|
-
|
|
209
|
-
const buttons = canvas.getAllByRole('button');
|
|
210
|
-
|
|
211
|
-
// Test initial focus
|
|
212
|
-
buttons[0].focus();
|
|
213
|
-
await waitFor(() => {
|
|
214
|
-
expect(buttons[0]).toHaveFocus();
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
// Test focus moves correctly with tab navigation
|
|
218
|
-
await userEvent.tab();
|
|
219
|
-
await waitFor(() => {
|
|
220
|
-
expect(buttons[1]).toHaveFocus();
|
|
221
|
-
});
|
|
222
|
-
|
|
223
|
-
// Test focus doesn't get lost after selection
|
|
224
|
-
await userEvent.click(buttons[1]);
|
|
225
|
-
await waitFor(() => {
|
|
226
|
-
expect(buttons[1]).toHaveFocus();
|
|
227
|
-
});
|
|
228
|
-
},
|
|
229
|
-
};
|
|
230
|
-
|
|
231
|
-
// 6. Responsive Design Tests
|
|
232
|
-
export const ResponsiveDesign: Story = {
|
|
233
|
-
args: {
|
|
234
|
-
options: formatOptions,
|
|
235
|
-
size: 'md',
|
|
236
|
-
},
|
|
237
|
-
parameters: {
|
|
238
|
-
viewport: { defaultViewport: 'mobile1' },
|
|
239
|
-
},
|
|
240
|
-
play: async ({ canvasElement }) => {
|
|
241
|
-
const canvas = within(canvasElement);
|
|
242
|
-
|
|
243
|
-
// Test component renders on small screens
|
|
244
|
-
const toggleGroup = canvas.getByRole('group');
|
|
245
|
-
expect(toggleGroup).toBeInTheDocument();
|
|
246
|
-
|
|
247
|
-
// Test buttons are still accessible
|
|
248
|
-
const buttons = canvas.getAllByRole('button');
|
|
249
|
-
expect(buttons).toHaveLength(3);
|
|
250
|
-
|
|
251
|
-
// Test buttons maintain minimum touch target size (44px)
|
|
252
|
-
buttons.forEach((button) => {
|
|
253
|
-
const styles = window.getComputedStyle(button);
|
|
254
|
-
const height = parseInt(styles.height);
|
|
255
|
-
expect(height).toBeGreaterThanOrEqual(40); // Allow some margin for borders/padding
|
|
256
|
-
});
|
|
257
|
-
},
|
|
258
|
-
};
|
|
259
|
-
|
|
260
|
-
// 7. Theme Variations Tests
|
|
261
|
-
export const ThemeVariations: Story = {
|
|
262
|
-
render: () => (
|
|
263
|
-
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
|
|
264
|
-
{(['primary', 'secondary', 'success', 'warning', 'danger'] as const).map((color) => (
|
|
265
|
-
<Box key={color}>
|
|
266
|
-
<Typography variant="h6" gutterBottom sx={{ textTransform: 'capitalize' }}>
|
|
267
|
-
{color}
|
|
268
|
-
</Typography>
|
|
269
|
-
<ToggleGroup color={color} options={alignOptions} data-testid={`toggle-group-${color}`} />
|
|
270
|
-
</Box>
|
|
271
|
-
))}
|
|
272
|
-
</Box>
|
|
273
|
-
),
|
|
274
|
-
play: async ({ canvasElement }) => {
|
|
275
|
-
const canvas = within(canvasElement);
|
|
276
|
-
|
|
277
|
-
// Test each color variant renders
|
|
278
|
-
const colors = ['primary', 'secondary', 'success', 'warning', 'danger'];
|
|
279
|
-
|
|
280
|
-
for (const color of colors) {
|
|
281
|
-
const toggleGroup = canvas.getByTestId(`toggle-group-${color}`);
|
|
282
|
-
expect(toggleGroup).toBeInTheDocument();
|
|
283
|
-
|
|
284
|
-
// Test buttons within each color variant
|
|
285
|
-
const buttons = within(toggleGroup).getAllByRole('button');
|
|
286
|
-
expect(buttons).toHaveLength(3);
|
|
287
|
-
}
|
|
288
|
-
},
|
|
289
|
-
};
|
|
290
|
-
|
|
291
|
-
// 8. Visual States Tests
|
|
292
|
-
export const VisualStates: Story = {
|
|
293
|
-
render: () => (
|
|
294
|
-
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
|
|
295
|
-
<Box>
|
|
296
|
-
<Typography variant="h6" gutterBottom>
|
|
297
|
-
Normal State
|
|
298
|
-
</Typography>
|
|
299
|
-
<ToggleGroup options={alignOptions} data-testid="normal" />
|
|
300
|
-
</Box>
|
|
301
|
-
|
|
302
|
-
<Box>
|
|
303
|
-
<Typography variant="h6" gutterBottom>
|
|
304
|
-
With Disabled Options
|
|
305
|
-
</Typography>
|
|
306
|
-
<ToggleGroup options={optionsWithDisabled} data-testid="disabled" />
|
|
307
|
-
</Box>
|
|
308
|
-
|
|
309
|
-
<Box>
|
|
310
|
-
<Typography variant="h6" gutterBottom>
|
|
311
|
-
Glass Effect
|
|
312
|
-
</Typography>
|
|
313
|
-
<ToggleGroup options={themeOptions} glass data-testid="glass" />
|
|
314
|
-
</Box>
|
|
315
|
-
|
|
316
|
-
<Box>
|
|
317
|
-
<Typography variant="h6" gutterBottom>
|
|
318
|
-
Gradient Effect
|
|
319
|
-
</Typography>
|
|
320
|
-
<ToggleGroup options={actionOptions} gradient color="secondary" data-testid="gradient" />
|
|
321
|
-
</Box>
|
|
322
|
-
|
|
323
|
-
<Box>
|
|
324
|
-
<Typography variant="h6" gutterBottom>
|
|
325
|
-
Size Variations
|
|
326
|
-
</Typography>
|
|
327
|
-
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
|
|
328
|
-
{(['xs', 'sm', 'md', 'lg', 'xl'] as const).map((size) => (
|
|
329
|
-
<ToggleGroup
|
|
330
|
-
key={size}
|
|
331
|
-
options={formatOptions}
|
|
332
|
-
size={size}
|
|
333
|
-
data-testid={`size-${size}`}
|
|
334
|
-
/>
|
|
335
|
-
))}
|
|
336
|
-
</Box>
|
|
337
|
-
</Box>
|
|
338
|
-
</Box>
|
|
339
|
-
),
|
|
340
|
-
play: async ({ canvasElement }) => {
|
|
341
|
-
const canvas = within(canvasElement);
|
|
342
|
-
|
|
343
|
-
// Test normal state
|
|
344
|
-
const normalGroup = canvas.getByTestId('normal');
|
|
345
|
-
expect(normalGroup).toBeInTheDocument();
|
|
346
|
-
|
|
347
|
-
// Test disabled options
|
|
348
|
-
const disabledGroup = canvas.getByTestId('disabled');
|
|
349
|
-
const disabledButtons = within(disabledGroup).getAllByRole('button');
|
|
350
|
-
expect(disabledButtons[1]).toBeDisabled();
|
|
351
|
-
expect(disabledButtons[0]).not.toBeDisabled();
|
|
352
|
-
expect(disabledButtons[2]).not.toBeDisabled();
|
|
353
|
-
|
|
354
|
-
// Test glass effect - verify backdrop filter and styling
|
|
355
|
-
const glassGroup = canvas.getByTestId('glass');
|
|
356
|
-
expect(glassGroup).toBeInTheDocument();
|
|
357
|
-
|
|
358
|
-
// Verify glass effect styling is applied
|
|
359
|
-
const styles = window.getComputedStyle(glassGroup);
|
|
360
|
-
expect(styles.backdropFilter).toContain('blur');
|
|
361
|
-
expect(styles.backgroundColor).not.toBe('transparent');
|
|
362
|
-
expect(parseInt(styles.padding)).toBeGreaterThan(0);
|
|
363
|
-
|
|
364
|
-
// Test gradient effect
|
|
365
|
-
const gradientGroup = canvas.getByTestId('gradient');
|
|
366
|
-
expect(gradientGroup).toBeInTheDocument();
|
|
367
|
-
|
|
368
|
-
// Test size variations
|
|
369
|
-
const sizes = ['xs', 'sm', 'md', 'lg', 'xl'];
|
|
370
|
-
for (const size of sizes) {
|
|
371
|
-
const sizeGroup = canvas.getByTestId(`size-${size}`);
|
|
372
|
-
expect(sizeGroup).toBeInTheDocument();
|
|
373
|
-
|
|
374
|
-
const buttons = within(sizeGroup).getAllByRole('button');
|
|
375
|
-
expect(buttons).toHaveLength(3);
|
|
376
|
-
}
|
|
377
|
-
},
|
|
378
|
-
};
|
|
379
|
-
|
|
380
|
-
// 9. Performance Tests
|
|
381
|
-
export const Performance: Story = {
|
|
382
|
-
args: {
|
|
383
|
-
options: Array.from({ length: 20 }, (_, i) => ({
|
|
384
|
-
value: `option-${i}`,
|
|
385
|
-
label: `Option ${i + 1}`,
|
|
386
|
-
icon: <Star size={16} />,
|
|
387
|
-
})),
|
|
388
|
-
variant: 'multiple',
|
|
389
|
-
},
|
|
390
|
-
play: async ({ canvasElement }) => {
|
|
391
|
-
const canvas = within(canvasElement);
|
|
392
|
-
|
|
393
|
-
const startTime = window.performance.now();
|
|
394
|
-
|
|
395
|
-
// Test rendering performance with many options
|
|
396
|
-
const buttons = canvas.getAllByRole('button');
|
|
397
|
-
expect(buttons).toHaveLength(20);
|
|
398
|
-
|
|
399
|
-
const renderTime = window.performance.now() - startTime;
|
|
400
|
-
|
|
401
|
-
// Should render within reasonable time (less than 100ms for initial query)
|
|
402
|
-
expect(renderTime).toBeLessThan(100);
|
|
403
|
-
|
|
404
|
-
// Test interaction performance
|
|
405
|
-
const interactionStart = window.performance.now();
|
|
406
|
-
|
|
407
|
-
// Click multiple buttons rapidly
|
|
408
|
-
await userEvent.click(buttons[0]);
|
|
409
|
-
await userEvent.click(buttons[5]);
|
|
410
|
-
await userEvent.click(buttons[10]);
|
|
411
|
-
|
|
412
|
-
const interactionTime = window.performance.now() - interactionStart;
|
|
413
|
-
|
|
414
|
-
// Interactions should be responsive (less than 600ms for 3 clicks)
|
|
415
|
-
// This accounts for userEvent simulation delays, React state updates,
|
|
416
|
-
// browser reflows, and Storybook rendering overhead in CI/CD environments
|
|
417
|
-
expect(interactionTime).toBeLessThan(600);
|
|
418
|
-
},
|
|
419
|
-
};
|
|
420
|
-
|
|
421
|
-
// 10. Edge Cases Tests
|
|
422
|
-
export const EdgeCases: Story = {
|
|
423
|
-
render: () => (
|
|
424
|
-
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
|
|
425
|
-
<Box>
|
|
426
|
-
<Typography variant="h6" gutterBottom>
|
|
427
|
-
Single Option
|
|
428
|
-
</Typography>
|
|
429
|
-
<ToggleGroup
|
|
430
|
-
options={[{ value: 'only', label: 'Only Option' }]}
|
|
431
|
-
data-testid="single-option"
|
|
432
|
-
/>
|
|
433
|
-
</Box>
|
|
434
|
-
|
|
435
|
-
<Box>
|
|
436
|
-
<Typography variant="h6" gutterBottom>
|
|
437
|
-
Empty Labels
|
|
438
|
-
</Typography>
|
|
439
|
-
<ToggleGroup
|
|
440
|
-
options={[
|
|
441
|
-
{ value: 'icon1', label: '', icon: <Heart size={16} /> },
|
|
442
|
-
{ value: 'icon2', label: '', icon: <Star size={16} /> },
|
|
443
|
-
]}
|
|
444
|
-
data-testid="empty-labels"
|
|
445
|
-
/>
|
|
446
|
-
</Box>
|
|
447
|
-
|
|
448
|
-
<Box>
|
|
449
|
-
<Typography variant="h6" gutterBottom>
|
|
450
|
-
Long Labels
|
|
451
|
-
</Typography>
|
|
452
|
-
<ToggleGroup
|
|
453
|
-
options={[
|
|
454
|
-
{ value: 'long1', label: 'This is a very long label that might wrap' },
|
|
455
|
-
{ value: 'long2', label: 'Another extremely long label for testing purposes' },
|
|
456
|
-
]}
|
|
457
|
-
data-testid="long-labels"
|
|
458
|
-
/>
|
|
459
|
-
</Box>
|
|
460
|
-
|
|
461
|
-
<Box>
|
|
462
|
-
<Typography variant="h6" gutterBottom>
|
|
463
|
-
All Disabled
|
|
464
|
-
</Typography>
|
|
465
|
-
<ToggleGroup
|
|
466
|
-
options={[
|
|
467
|
-
{ value: 'dis1', label: 'Disabled 1', disabled: true },
|
|
468
|
-
{ value: 'dis2', label: 'Disabled 2', disabled: true },
|
|
469
|
-
]}
|
|
470
|
-
data-testid="all-disabled"
|
|
471
|
-
/>
|
|
472
|
-
</Box>
|
|
473
|
-
</Box>
|
|
474
|
-
),
|
|
475
|
-
play: async ({ canvasElement }) => {
|
|
476
|
-
const canvas = within(canvasElement);
|
|
477
|
-
|
|
478
|
-
// Test single option
|
|
479
|
-
const singleOption = canvas.getByTestId('single-option');
|
|
480
|
-
const singleButtons = within(singleOption).getAllByRole('button');
|
|
481
|
-
expect(singleButtons).toHaveLength(1);
|
|
482
|
-
|
|
483
|
-
// Test empty labels (icon-only buttons)
|
|
484
|
-
const emptyLabels = canvas.getByTestId('empty-labels');
|
|
485
|
-
const emptyLabelButtons = within(emptyLabels).getAllByRole('button');
|
|
486
|
-
expect(emptyLabelButtons).toHaveLength(2);
|
|
487
|
-
|
|
488
|
-
// Test long labels
|
|
489
|
-
const longLabels = canvas.getByTestId('long-labels');
|
|
490
|
-
const longLabelButtons = within(longLabels).getAllByRole('button');
|
|
491
|
-
expect(longLabelButtons).toHaveLength(2);
|
|
492
|
-
|
|
493
|
-
// Test all disabled
|
|
494
|
-
const allDisabled = canvas.getByTestId('all-disabled');
|
|
495
|
-
const disabledButtons = within(allDisabled).getAllByRole('button');
|
|
496
|
-
expect(disabledButtons).toHaveLength(2);
|
|
497
|
-
disabledButtons.forEach((button) => {
|
|
498
|
-
expect(button).toBeDisabled();
|
|
499
|
-
});
|
|
500
|
-
},
|
|
501
|
-
};
|
|
502
|
-
|
|
503
|
-
// Component for controlled glow testing
|
|
504
|
-
const ControlledGlowTest = () => {
|
|
505
|
-
const [normalValue, setNormalValue] = React.useState<string>('');
|
|
506
|
-
const [glassValue, setGlassValue] = React.useState<string>('');
|
|
507
|
-
const [gradientValue, setGradientValue] = React.useState<string>('');
|
|
508
|
-
|
|
509
|
-
return (
|
|
510
|
-
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 4, p: 4, backgroundColor: '#f0f0f0' }}>
|
|
511
|
-
<Box>
|
|
512
|
-
<Typography variant="h6" gutterBottom>
|
|
513
|
-
Normal Toggle Group
|
|
514
|
-
</Typography>
|
|
515
|
-
<ToggleGroup
|
|
516
|
-
options={alignOptions}
|
|
517
|
-
data-testid="normal-group"
|
|
518
|
-
value={normalValue}
|
|
519
|
-
onChange={(_, newValue) => setNormalValue(newValue || '')}
|
|
520
|
-
/>
|
|
521
|
-
</Box>
|
|
522
|
-
|
|
523
|
-
<Box>
|
|
524
|
-
<Typography variant="h6" gutterBottom>
|
|
525
|
-
Glass Effect Toggle Group
|
|
526
|
-
</Typography>
|
|
527
|
-
<ToggleGroup
|
|
528
|
-
options={alignOptions}
|
|
529
|
-
glass
|
|
530
|
-
data-testid="glass-group"
|
|
531
|
-
value={glassValue}
|
|
532
|
-
onChange={(_, newValue) => setGlassValue(newValue || '')}
|
|
533
|
-
/>
|
|
534
|
-
</Box>
|
|
535
|
-
|
|
536
|
-
<Box>
|
|
537
|
-
<Typography variant="h6" gutterBottom>
|
|
538
|
-
Glass + Gradient Toggle Group
|
|
539
|
-
</Typography>
|
|
540
|
-
<ToggleGroup
|
|
541
|
-
options={themeOptions}
|
|
542
|
-
glass
|
|
543
|
-
gradient
|
|
544
|
-
color="secondary"
|
|
545
|
-
data-testid="glass-gradient-group"
|
|
546
|
-
value={gradientValue}
|
|
547
|
-
onChange={(_, newValue) => setGradientValue(newValue || '')}
|
|
548
|
-
/>
|
|
549
|
-
</Box>
|
|
550
|
-
</Box>
|
|
551
|
-
);
|
|
552
|
-
};
|
|
553
|
-
|
|
554
|
-
// 11. Glow Effect Tests
|
|
555
|
-
export const GlowEffectTest: Story = {
|
|
556
|
-
render: () => <ControlledGlowTest />,
|
|
557
|
-
play: async ({ canvasElement }) => {
|
|
558
|
-
const canvas = within(canvasElement);
|
|
559
|
-
|
|
560
|
-
// Test normal group (no glass)
|
|
561
|
-
const normalGroup = canvas.getByTestId('normal-group');
|
|
562
|
-
const normalStyles = window.getComputedStyle(normalGroup);
|
|
563
|
-
expect(normalStyles.backdropFilter).toBe('none');
|
|
564
|
-
// CSS transparent can be rendered as rgba(0, 0, 0, 0)
|
|
565
|
-
expect(normalStyles.backgroundColor).toMatch(/transparent|rgba\(0,\s*0,\s*0,\s*0\)/);
|
|
566
|
-
|
|
567
|
-
// Test glass effect group
|
|
568
|
-
const glassGroup = canvas.getByTestId('glass-group');
|
|
569
|
-
const glassStyles = window.getComputedStyle(glassGroup);
|
|
570
|
-
|
|
571
|
-
// Verify glass-specific styling
|
|
572
|
-
expect(glassStyles.backdropFilter).toContain('blur(20px)');
|
|
573
|
-
expect(glassStyles.backgroundColor).toContain('rgba');
|
|
574
|
-
expect(parseInt(glassStyles.padding)).toBe(4);
|
|
575
|
-
expect(glassStyles.borderRadius).not.toBe('0px');
|
|
576
|
-
expect(glassStyles.border).toContain('1px solid');
|
|
577
|
-
|
|
578
|
-
// Test glass + gradient combination
|
|
579
|
-
const glassGradientGroup = canvas.getByTestId('glass-gradient-group');
|
|
580
|
-
const glassGradientStyles = window.getComputedStyle(glassGradientGroup);
|
|
581
|
-
|
|
582
|
-
// Verify glass effect is still applied
|
|
583
|
-
expect(glassGradientStyles.backdropFilter).toContain('blur(20px)');
|
|
584
|
-
expect(glassGradientStyles.backgroundColor).toContain('rgba');
|
|
585
|
-
|
|
586
|
-
// Test interaction with glass effect
|
|
587
|
-
const glassButtons = within(glassGroup).getAllByRole('button');
|
|
588
|
-
|
|
589
|
-
// Click a button and verify glass effect is maintained
|
|
590
|
-
await userEvent.click(glassButtons[1]);
|
|
591
|
-
|
|
592
|
-
await waitFor(() => {
|
|
593
|
-
const updatedStyles = window.getComputedStyle(glassGroup);
|
|
594
|
-
expect(updatedStyles.backdropFilter).toContain('blur(20px)');
|
|
595
|
-
// For uncontrolled mode, check aria-pressed
|
|
596
|
-
expect(glassButtons[1]).toHaveAttribute('aria-pressed', 'true');
|
|
597
|
-
});
|
|
598
|
-
|
|
599
|
-
// Test that gradient effect works on selected button
|
|
600
|
-
const gradientButtons = within(glassGradientGroup).getAllByRole('button');
|
|
601
|
-
await userEvent.click(gradientButtons[0]);
|
|
602
|
-
|
|
603
|
-
await waitFor(() => {
|
|
604
|
-
const buttonStyles = window.getComputedStyle(gradientButtons[0]);
|
|
605
|
-
// Selected button should have gradient (linear-gradient in background)
|
|
606
|
-
expect(buttonStyles.background).toContain('linear-gradient');
|
|
607
|
-
});
|
|
608
|
-
},
|
|
609
|
-
};
|
|
610
|
-
|
|
611
|
-
// 12. Integration Tests
|
|
612
|
-
const IntegrationComponent = () => {
|
|
613
|
-
const [singleValue, setSingleValue] = React.useState<string>('');
|
|
614
|
-
const [multipleValue, setMultipleValue] = React.useState<string[]>([]);
|
|
615
|
-
|
|
616
|
-
return (
|
|
617
|
-
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
|
|
618
|
-
<Box>
|
|
619
|
-
<Typography variant="h6" gutterBottom>
|
|
620
|
-
Text Alignment
|
|
621
|
-
</Typography>
|
|
622
|
-
<ToggleGroup
|
|
623
|
-
variant="single"
|
|
624
|
-
options={alignOptions}
|
|
625
|
-
value={singleValue}
|
|
626
|
-
onChange={(_, value) => setSingleValue(value || '')}
|
|
627
|
-
data-testid="alignment-group"
|
|
628
|
-
/>
|
|
629
|
-
<Typography variant="body2" color="text.secondary" sx={{ mt: 1 }}>
|
|
630
|
-
Selected: {singleValue || 'None'}
|
|
631
|
-
</Typography>
|
|
632
|
-
</Box>
|
|
633
|
-
|
|
634
|
-
<Box>
|
|
635
|
-
<Typography variant="h6" gutterBottom>
|
|
636
|
-
Text Formatting
|
|
637
|
-
</Typography>
|
|
638
|
-
<ToggleGroup
|
|
639
|
-
variant="multiple"
|
|
640
|
-
options={formatOptions}
|
|
641
|
-
value={multipleValue}
|
|
642
|
-
onChange={(_, value) => setMultipleValue(value || [])}
|
|
643
|
-
color="secondary"
|
|
644
|
-
data-testid="formatting-group"
|
|
645
|
-
/>
|
|
646
|
-
<Typography variant="body2" color="text.secondary" sx={{ mt: 1 }}>
|
|
647
|
-
Selected: {multipleValue.join(', ') || 'None'}
|
|
648
|
-
</Typography>
|
|
649
|
-
</Box>
|
|
650
|
-
|
|
651
|
-
<Box>
|
|
652
|
-
<Typography variant="h6" gutterBottom>
|
|
653
|
-
Preview Text
|
|
654
|
-
</Typography>
|
|
655
|
-
<Typography
|
|
656
|
-
variant="body1"
|
|
657
|
-
sx={{
|
|
658
|
-
fontWeight: multipleValue.includes('bold') ? 'bold' : 'normal',
|
|
659
|
-
fontStyle: multipleValue.includes('italic') ? 'italic' : 'normal',
|
|
660
|
-
textDecoration: multipleValue.includes('underline') ? 'underline' : 'none',
|
|
661
|
-
textAlign: (singleValue as 'left' | 'center' | 'right' | undefined) || 'left',
|
|
662
|
-
border: 1,
|
|
663
|
-
borderColor: 'divider',
|
|
664
|
-
p: 2,
|
|
665
|
-
borderRadius: 1,
|
|
666
|
-
}}
|
|
667
|
-
data-testid="preview-text"
|
|
668
|
-
>
|
|
669
|
-
This is preview text showing the applied formatting and alignment.
|
|
670
|
-
</Typography>
|
|
671
|
-
</Box>
|
|
672
|
-
</Box>
|
|
673
|
-
);
|
|
674
|
-
};
|
|
675
|
-
|
|
676
|
-
export const Integration: Story = {
|
|
677
|
-
render: () => <IntegrationComponent />,
|
|
678
|
-
play: async ({ canvasElement }) => {
|
|
679
|
-
const canvas = within(canvasElement);
|
|
680
|
-
|
|
681
|
-
// Test alignment integration
|
|
682
|
-
const alignmentGroup = canvas.getByTestId('alignment-group');
|
|
683
|
-
const alignButtons = within(alignmentGroup).getAllByRole('button');
|
|
684
|
-
|
|
685
|
-
await userEvent.click(alignButtons[1]); // Center align
|
|
686
|
-
|
|
687
|
-
const previewText = canvas.getByTestId('preview-text');
|
|
688
|
-
await waitFor(() => {
|
|
689
|
-
const styles = window.getComputedStyle(previewText);
|
|
690
|
-
expect(styles.textAlign).toBe('center');
|
|
691
|
-
});
|
|
692
|
-
|
|
693
|
-
// Test formatting integration
|
|
694
|
-
const formattingGroup = canvas.getByTestId('formatting-group');
|
|
695
|
-
const formatButtons = within(formattingGroup).getAllByRole('button');
|
|
696
|
-
|
|
697
|
-
await userEvent.click(formatButtons[0]); // Bold
|
|
698
|
-
await waitFor(() => {
|
|
699
|
-
const styles = window.getComputedStyle(previewText);
|
|
700
|
-
expect(styles.fontWeight).toBe('700');
|
|
701
|
-
});
|
|
702
|
-
|
|
703
|
-
await userEvent.click(formatButtons[1]); // Italic
|
|
704
|
-
await waitFor(() => {
|
|
705
|
-
const styles = window.getComputedStyle(previewText);
|
|
706
|
-
expect(styles.fontStyle).toBe('italic');
|
|
707
|
-
});
|
|
708
|
-
},
|
|
709
|
-
};
|
|
710
|
-
|
|
711
|
-
// 13. TestId Tests
|
|
712
|
-
export const TestIds: Story = {
|
|
713
|
-
render: () => {
|
|
714
|
-
const TestIdComponent = () => {
|
|
715
|
-
const [defaultValue, setDefaultValue] = React.useState<string>('');
|
|
716
|
-
const [customValue, setCustomValue] = React.useState<string>('');
|
|
717
|
-
const [iconValue, setIconValue] = React.useState<string>('');
|
|
718
|
-
const [disabledValue, setDisabledValue] = React.useState<string>('');
|
|
719
|
-
|
|
720
|
-
return (
|
|
721
|
-
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
|
|
722
|
-
<Box>
|
|
723
|
-
<Typography variant="h6" gutterBottom>
|
|
724
|
-
Default TestId
|
|
725
|
-
</Typography>
|
|
726
|
-
<ToggleGroup
|
|
727
|
-
options={alignOptions}
|
|
728
|
-
value={defaultValue}
|
|
729
|
-
onChange={(_, val) => setDefaultValue(val || '')}
|
|
730
|
-
/>
|
|
731
|
-
</Box>
|
|
732
|
-
|
|
733
|
-
<Box>
|
|
734
|
-
<Typography variant="h6" gutterBottom>
|
|
735
|
-
Custom TestId
|
|
736
|
-
</Typography>
|
|
737
|
-
<ToggleGroup
|
|
738
|
-
options={formatOptions}
|
|
739
|
-
dataTestId="custom-toggle"
|
|
740
|
-
value={customValue}
|
|
741
|
-
onChange={(_, val) => setCustomValue(val || '')}
|
|
742
|
-
/>
|
|
743
|
-
</Box>
|
|
744
|
-
|
|
745
|
-
<Box>
|
|
746
|
-
<Typography variant="h6" gutterBottom>
|
|
747
|
-
TestId with Icons
|
|
748
|
-
</Typography>
|
|
749
|
-
<ToggleGroup
|
|
750
|
-
options={themeOptions}
|
|
751
|
-
dataTestId="icon-toggle"
|
|
752
|
-
value={iconValue}
|
|
753
|
-
onChange={(_, val) => setIconValue(val || '')}
|
|
754
|
-
/>
|
|
755
|
-
</Box>
|
|
756
|
-
|
|
757
|
-
<Box>
|
|
758
|
-
<Typography variant="h6" gutterBottom>
|
|
759
|
-
TestId with Disabled Options
|
|
760
|
-
</Typography>
|
|
761
|
-
<ToggleGroup
|
|
762
|
-
options={optionsWithDisabled}
|
|
763
|
-
dataTestId="disabled-toggle"
|
|
764
|
-
value={disabledValue}
|
|
765
|
-
onChange={(_, val) => setDisabledValue(val || '')}
|
|
766
|
-
/>
|
|
767
|
-
</Box>
|
|
768
|
-
</Box>
|
|
769
|
-
);
|
|
770
|
-
};
|
|
771
|
-
|
|
772
|
-
return <TestIdComponent />;
|
|
773
|
-
},
|
|
774
|
-
play: async ({ canvasElement }) => {
|
|
775
|
-
const canvas = within(canvasElement);
|
|
776
|
-
|
|
777
|
-
// Test default testId
|
|
778
|
-
const defaultGroup = canvas.getByTestId('toggle-group');
|
|
779
|
-
expect(defaultGroup).toBeInTheDocument();
|
|
780
|
-
|
|
781
|
-
// Test default item testIds
|
|
782
|
-
expect(canvas.getByTestId('toggle-group-item-left')).toBeInTheDocument();
|
|
783
|
-
expect(canvas.getByTestId('toggle-group-item-center')).toBeInTheDocument();
|
|
784
|
-
expect(canvas.getByTestId('toggle-group-item-right')).toBeInTheDocument();
|
|
785
|
-
|
|
786
|
-
// Test custom testId
|
|
787
|
-
const customGroup = canvas.getByTestId('custom-toggle');
|
|
788
|
-
expect(customGroup).toBeInTheDocument();
|
|
789
|
-
|
|
790
|
-
// Test custom item testIds
|
|
791
|
-
expect(canvas.getByTestId('custom-toggle-item-bold')).toBeInTheDocument();
|
|
792
|
-
expect(canvas.getByTestId('custom-toggle-item-italic')).toBeInTheDocument();
|
|
793
|
-
expect(canvas.getByTestId('custom-toggle-item-underline')).toBeInTheDocument();
|
|
794
|
-
|
|
795
|
-
// Test testIds with icons
|
|
796
|
-
const iconGroup = canvas.getByTestId('icon-toggle');
|
|
797
|
-
expect(iconGroup).toBeInTheDocument();
|
|
798
|
-
expect(canvas.getByTestId('icon-toggle-item-light')).toBeInTheDocument();
|
|
799
|
-
expect(canvas.getByTestId('icon-toggle-item-dark')).toBeInTheDocument();
|
|
800
|
-
expect(canvas.getByTestId('icon-toggle-item-system')).toBeInTheDocument();
|
|
801
|
-
|
|
802
|
-
// Test testIds with disabled options
|
|
803
|
-
const disabledGroup = canvas.getByTestId('disabled-toggle');
|
|
804
|
-
expect(disabledGroup).toBeInTheDocument();
|
|
805
|
-
|
|
806
|
-
const enabledItem = canvas.getByTestId('disabled-toggle-item-option1');
|
|
807
|
-
const disabledItem = canvas.getByTestId('disabled-toggle-item-option2');
|
|
808
|
-
const anotherEnabledItem = canvas.getByTestId('disabled-toggle-item-option3');
|
|
809
|
-
|
|
810
|
-
expect(enabledItem).not.toBeDisabled();
|
|
811
|
-
expect(disabledItem).toBeDisabled();
|
|
812
|
-
expect(anotherEnabledItem).not.toBeDisabled();
|
|
813
|
-
|
|
814
|
-
// Test interaction with testIds
|
|
815
|
-
await userEvent.click(enabledItem);
|
|
816
|
-
await waitFor(() => {
|
|
817
|
-
expect(enabledItem).toHaveAttribute('aria-pressed', 'true');
|
|
818
|
-
});
|
|
819
|
-
|
|
820
|
-
// Verify disabled item remains disabled and cannot be interacted with
|
|
821
|
-
// Note: We don't attempt to click disabled items as they have pointer-events: none
|
|
822
|
-
await waitFor(() => {
|
|
823
|
-
expect(disabledItem).toHaveAttribute('aria-pressed', 'false');
|
|
824
|
-
expect(disabledItem).toBeDisabled();
|
|
825
|
-
});
|
|
826
|
-
},
|
|
827
|
-
};
|
|
828
|
-
|
|
829
|
-
// Component for controlled testId testing
|
|
830
|
-
const ControlledTestIdComponent = () => {
|
|
831
|
-
const [value, setValue] = React.useState<string>('');
|
|
832
|
-
|
|
833
|
-
return (
|
|
834
|
-
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
|
|
835
|
-
<Box>
|
|
836
|
-
<Typography variant="h6" gutterBottom>
|
|
837
|
-
Controlled Toggle with TestId
|
|
838
|
-
</Typography>
|
|
839
|
-
<ToggleGroup
|
|
840
|
-
variant="single"
|
|
841
|
-
options={alignOptions}
|
|
842
|
-
value={value}
|
|
843
|
-
onChange={(_, newValue) => setValue(newValue || '')}
|
|
844
|
-
dataTestId="controlled-toggle"
|
|
845
|
-
/>
|
|
846
|
-
<Typography variant="body2" color="text.secondary" sx={{ mt: 1 }}>
|
|
847
|
-
Selected: {value || 'None'}
|
|
848
|
-
</Typography>
|
|
849
|
-
</Box>
|
|
850
|
-
</Box>
|
|
851
|
-
);
|
|
852
|
-
};
|
|
853
|
-
|
|
854
|
-
// 14. TestId Controlled Component Test
|
|
855
|
-
export const TestIdControlled: Story = {
|
|
856
|
-
render: () => <ControlledTestIdComponent />,
|
|
857
|
-
play: async ({ canvasElement }) => {
|
|
858
|
-
const canvas = within(canvasElement);
|
|
859
|
-
|
|
860
|
-
// Test controlled component with testIds
|
|
861
|
-
const group = canvas.getByTestId('controlled-toggle');
|
|
862
|
-
expect(group).toBeInTheDocument();
|
|
863
|
-
|
|
864
|
-
// Test items are accessible by testId
|
|
865
|
-
const leftButton = canvas.getByTestId('controlled-toggle-item-left');
|
|
866
|
-
const centerButton = canvas.getByTestId('controlled-toggle-item-center');
|
|
867
|
-
const rightButton = canvas.getByTestId('controlled-toggle-item-right');
|
|
868
|
-
|
|
869
|
-
expect(leftButton).toBeInTheDocument();
|
|
870
|
-
expect(centerButton).toBeInTheDocument();
|
|
871
|
-
expect(rightButton).toBeInTheDocument();
|
|
872
|
-
|
|
873
|
-
// Test clicking via testId updates state
|
|
874
|
-
await userEvent.click(leftButton);
|
|
875
|
-
await waitFor(() => {
|
|
876
|
-
expect(leftButton).toHaveAttribute('aria-pressed', 'true');
|
|
877
|
-
});
|
|
878
|
-
|
|
879
|
-
// Test clicking another button
|
|
880
|
-
await userEvent.click(centerButton);
|
|
881
|
-
await waitFor(() => {
|
|
882
|
-
expect(centerButton).toHaveAttribute('aria-pressed', 'true');
|
|
883
|
-
expect(leftButton).toHaveAttribute('aria-pressed', 'false');
|
|
884
|
-
});
|
|
885
|
-
|
|
886
|
-
// Test clicking the same button deselects in single mode
|
|
887
|
-
await userEvent.click(centerButton);
|
|
888
|
-
await waitFor(() => {
|
|
889
|
-
expect(centerButton).toHaveAttribute('aria-pressed', 'false');
|
|
890
|
-
});
|
|
891
|
-
},
|
|
892
|
-
};
|
|
893
|
-
|
|
894
|
-
// 15. TestId with Special Characters
|
|
895
|
-
export const TestIdSpecialCharacters: Story = {
|
|
896
|
-
args: {
|
|
897
|
-
options: [
|
|
898
|
-
{ value: 'option-with-dash', label: 'With Dash' },
|
|
899
|
-
{ value: 'option_with_underscore', label: 'With Underscore' },
|
|
900
|
-
{ value: 'option.with.dots', label: 'With Dots' },
|
|
901
|
-
{ value: 'option123', label: 'With Numbers' },
|
|
902
|
-
],
|
|
903
|
-
dataTestId: 'special-chars-toggle',
|
|
904
|
-
},
|
|
905
|
-
play: async ({ canvasElement }) => {
|
|
906
|
-
const canvas = within(canvasElement);
|
|
907
|
-
|
|
908
|
-
// Test group testId
|
|
909
|
-
const group = canvas.getByTestId('special-chars-toggle');
|
|
910
|
-
expect(group).toBeInTheDocument();
|
|
911
|
-
|
|
912
|
-
// Test items with special characters in values
|
|
913
|
-
expect(canvas.getByTestId('special-chars-toggle-item-option-with-dash')).toBeInTheDocument();
|
|
914
|
-
expect(canvas.getByTestId('special-chars-toggle-item-option_with_underscore')).toBeInTheDocument();
|
|
915
|
-
expect(canvas.getByTestId('special-chars-toggle-item-option.with.dots')).toBeInTheDocument();
|
|
916
|
-
expect(canvas.getByTestId('special-chars-toggle-item-option123')).toBeInTheDocument();
|
|
917
|
-
},
|
|
918
|
-
};
|