@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,520 +0,0 @@
|
|
|
1
|
-
import { Box, createTheme,ThemeProvider } from '@mui/material';
|
|
2
|
-
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
3
|
-
import React from 'react';
|
|
4
|
-
import { expect, fn,userEvent, waitFor, within } from 'storybook/test';
|
|
5
|
-
|
|
6
|
-
import { Pagination } from './Pagination';
|
|
7
|
-
|
|
8
|
-
const meta: Meta<typeof Pagination> = {
|
|
9
|
-
title: 'Navigation/Pagination/Tests',
|
|
10
|
-
component: Pagination,
|
|
11
|
-
parameters: {
|
|
12
|
-
layout: 'centered',
|
|
13
|
-
chromatic: { disableSnapshot: false },
|
|
14
|
-
},
|
|
15
|
-
tags: ['autodocs', 'test', 'component:Pagination'],
|
|
16
|
-
args: {
|
|
17
|
-
page: 5,
|
|
18
|
-
count: 10,
|
|
19
|
-
onChange: fn(),
|
|
20
|
-
},
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
export default meta;
|
|
24
|
-
type Story = StoryObj<typeof meta>;
|
|
25
|
-
|
|
26
|
-
// Test 1: Basic Interaction Test
|
|
27
|
-
export const BasicInteraction: Story = {
|
|
28
|
-
name: '1. Basic Interaction',
|
|
29
|
-
args: {
|
|
30
|
-
page: 5,
|
|
31
|
-
count: 10,
|
|
32
|
-
onChange: fn(),
|
|
33
|
-
},
|
|
34
|
-
play: async ({ canvasElement, args }) => {
|
|
35
|
-
const canvas = within(canvasElement);
|
|
36
|
-
|
|
37
|
-
// Test clicking on different page numbers
|
|
38
|
-
const page4Button = canvas.getByRole('button', { name: /go to page 4/i });
|
|
39
|
-
await userEvent.click(page4Button);
|
|
40
|
-
await expect(args.onChange).toHaveBeenCalledWith(expect.anything(), 4);
|
|
41
|
-
|
|
42
|
-
// Test clicking next button
|
|
43
|
-
const nextButton = canvas.getByRole('button', { name: /go to next page/i });
|
|
44
|
-
await userEvent.click(nextButton);
|
|
45
|
-
await expect(args.onChange).toHaveBeenCalledWith(expect.anything(), 6);
|
|
46
|
-
|
|
47
|
-
// Test clicking previous button (this would be the 3rd call after page 4 and next to 6)
|
|
48
|
-
const prevButton = canvas.getByRole('button', { name: /go to previous page/i });
|
|
49
|
-
await userEvent.click(prevButton);
|
|
50
|
-
await expect(args.onChange).toHaveBeenCalled();
|
|
51
|
-
|
|
52
|
-
// Verify current page is highlighted
|
|
53
|
-
const currentPage = canvas.getByRole('button', { name: /page 5/i });
|
|
54
|
-
await expect(currentPage).toHaveAttribute('aria-current', 'page');
|
|
55
|
-
},
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
// Test 2: Form Interaction Test (Items Per Page)
|
|
59
|
-
export const FormInteraction: Story = {
|
|
60
|
-
name: '2. Form Interaction',
|
|
61
|
-
args: {
|
|
62
|
-
page: 1,
|
|
63
|
-
count: 10,
|
|
64
|
-
showItemsPerPage: true,
|
|
65
|
-
itemsPerPage: 10,
|
|
66
|
-
itemsPerPageOptions: [10, 25, 50, 100],
|
|
67
|
-
onItemsPerPageChange: fn(),
|
|
68
|
-
onChange: fn(),
|
|
69
|
-
},
|
|
70
|
-
play: async ({ canvasElement, args }) => {
|
|
71
|
-
const canvas = within(canvasElement);
|
|
72
|
-
|
|
73
|
-
// Find and click the select dropdown
|
|
74
|
-
const selectButton = canvas.getByRole('combobox');
|
|
75
|
-
await expect(selectButton).toBeInTheDocument();
|
|
76
|
-
await expect(selectButton).toHaveTextContent('10');
|
|
77
|
-
|
|
78
|
-
// Open the dropdown
|
|
79
|
-
await userEvent.click(selectButton);
|
|
80
|
-
|
|
81
|
-
// Wait for options to appear and click on 25
|
|
82
|
-
// MUI Select renders options in a separate listbox
|
|
83
|
-
const option25 = await within(document.body).findByRole('option', { name: '25' });
|
|
84
|
-
await userEvent.click(option25);
|
|
85
|
-
|
|
86
|
-
// Verify callback was called
|
|
87
|
-
await expect(args.onItemsPerPageChange).toHaveBeenCalledWith(25);
|
|
88
|
-
},
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
// Test 3: Keyboard Navigation Test
|
|
92
|
-
export const KeyboardNavigation: Story = {
|
|
93
|
-
name: '3. Keyboard Navigation',
|
|
94
|
-
args: {
|
|
95
|
-
page: 5,
|
|
96
|
-
count: 10,
|
|
97
|
-
onChange: fn(),
|
|
98
|
-
},
|
|
99
|
-
play: async ({ canvasElement, args }) => {
|
|
100
|
-
const canvas = within(canvasElement);
|
|
101
|
-
|
|
102
|
-
// Focus on the pagination component
|
|
103
|
-
const firstButton = canvas.getAllByRole('button')[0];
|
|
104
|
-
firstButton.focus();
|
|
105
|
-
|
|
106
|
-
// Tab through buttons
|
|
107
|
-
await userEvent.tab();
|
|
108
|
-
await expect(document.activeElement).toHaveAttribute(
|
|
109
|
-
'aria-label',
|
|
110
|
-
expect.stringContaining('page'),
|
|
111
|
-
);
|
|
112
|
-
|
|
113
|
-
// Press Enter on focused button
|
|
114
|
-
await userEvent.keyboard('{Enter}');
|
|
115
|
-
await expect(args.onChange).toHaveBeenCalled();
|
|
116
|
-
|
|
117
|
-
// Tab to next button and press Space
|
|
118
|
-
await userEvent.tab();
|
|
119
|
-
await userEvent.keyboard(' ');
|
|
120
|
-
await expect(args.onChange).toHaveBeenCalled();
|
|
121
|
-
|
|
122
|
-
// Test arrow key navigation
|
|
123
|
-
await userEvent.keyboard('{ArrowRight}');
|
|
124
|
-
await waitFor(() => {
|
|
125
|
-
expect(document.activeElement).toHaveAttribute('aria-label', expect.stringContaining('page'));
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
await userEvent.keyboard('{ArrowLeft}');
|
|
129
|
-
await waitFor(() => {
|
|
130
|
-
expect(document.activeElement).toHaveAttribute('aria-label', expect.stringContaining('page'));
|
|
131
|
-
});
|
|
132
|
-
},
|
|
133
|
-
};
|
|
134
|
-
|
|
135
|
-
// Test 4: Screen Reader Test
|
|
136
|
-
export const ScreenReader: Story = {
|
|
137
|
-
name: '4. Screen Reader',
|
|
138
|
-
args: {
|
|
139
|
-
page: 5,
|
|
140
|
-
count: 10,
|
|
141
|
-
showPageInfo: true,
|
|
142
|
-
onChange: fn(),
|
|
143
|
-
},
|
|
144
|
-
play: async ({ canvasElement }) => {
|
|
145
|
-
const canvas = within(canvasElement);
|
|
146
|
-
|
|
147
|
-
// Check for navigation landmark - MUI uses 'pagination navigation' as the label
|
|
148
|
-
const nav = canvas.getByRole('navigation');
|
|
149
|
-
await expect(nav).toHaveAttribute('aria-label', 'pagination navigation');
|
|
150
|
-
|
|
151
|
-
// Check current page has aria-current
|
|
152
|
-
const currentPage = canvas.getByRole('button', { name: /page 5/i });
|
|
153
|
-
await expect(currentPage).toHaveAttribute('aria-current', 'page');
|
|
154
|
-
|
|
155
|
-
// Check for descriptive labels on navigation buttons
|
|
156
|
-
const prevButton = canvas.getByRole('button', { name: /go to previous page/i });
|
|
157
|
-
await expect(prevButton).toBeInTheDocument();
|
|
158
|
-
|
|
159
|
-
const nextButton = canvas.getByRole('button', { name: /go to next page/i });
|
|
160
|
-
await expect(nextButton).toBeInTheDocument();
|
|
161
|
-
|
|
162
|
-
// Check page info is announced
|
|
163
|
-
const pageInfo = canvas.getByText(/Page 5 of 10/i);
|
|
164
|
-
await expect(pageInfo).toBeInTheDocument();
|
|
165
|
-
|
|
166
|
-
// Verify disabled state is announced
|
|
167
|
-
// Use exact match to avoid matching "10"
|
|
168
|
-
const firstPageButton = canvas.getByRole('button', { name: 'Go to page 1' });
|
|
169
|
-
await userEvent.click(firstPageButton);
|
|
170
|
-
},
|
|
171
|
-
};
|
|
172
|
-
|
|
173
|
-
// Test 5: Focus Management Test
|
|
174
|
-
export const FocusManagement: Story = {
|
|
175
|
-
name: '5. Focus Management',
|
|
176
|
-
args: {
|
|
177
|
-
page: 5,
|
|
178
|
-
count: 10,
|
|
179
|
-
showFirstButton: true,
|
|
180
|
-
showLastButton: true,
|
|
181
|
-
onChange: fn(),
|
|
182
|
-
},
|
|
183
|
-
play: async ({ canvasElement }) => {
|
|
184
|
-
const canvas = within(canvasElement);
|
|
185
|
-
|
|
186
|
-
// Get all buttons
|
|
187
|
-
const buttons = canvas.getAllByRole('button');
|
|
188
|
-
|
|
189
|
-
// Test focus on first button
|
|
190
|
-
const firstButton = buttons[0];
|
|
191
|
-
firstButton.focus();
|
|
192
|
-
await expect(document.activeElement).toBe(firstButton);
|
|
193
|
-
|
|
194
|
-
// Tab through all interactive elements
|
|
195
|
-
for (let i = 1; i < buttons.length; i++) {
|
|
196
|
-
await userEvent.tab();
|
|
197
|
-
await expect(document.activeElement).toBe(buttons[i]);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
// Test shift+tab backwards
|
|
201
|
-
await userEvent.tab({ shift: true });
|
|
202
|
-
await expect(document.activeElement).toBe(buttons[buttons.length - 2]);
|
|
203
|
-
|
|
204
|
-
// Test focus trap doesn't occur
|
|
205
|
-
await userEvent.tab();
|
|
206
|
-
await userEvent.tab();
|
|
207
|
-
// Focus should move outside pagination
|
|
208
|
-
await expect(document.activeElement).not.toBe(buttons[0]);
|
|
209
|
-
},
|
|
210
|
-
};
|
|
211
|
-
|
|
212
|
-
// Test 6: Responsive Design Test
|
|
213
|
-
export const ResponsiveDesign: Story = {
|
|
214
|
-
name: '6. Responsive Design',
|
|
215
|
-
args: {
|
|
216
|
-
page: 5,
|
|
217
|
-
count: 20,
|
|
218
|
-
variant: 'default',
|
|
219
|
-
onChange: fn(),
|
|
220
|
-
},
|
|
221
|
-
parameters: {
|
|
222
|
-
viewport: {
|
|
223
|
-
defaultViewport: 'mobile1',
|
|
224
|
-
},
|
|
225
|
-
},
|
|
226
|
-
play: async ({ canvasElement }) => {
|
|
227
|
-
const canvas = within(canvasElement);
|
|
228
|
-
|
|
229
|
-
// Check that pagination is visible
|
|
230
|
-
const nav = canvas.getByRole('navigation');
|
|
231
|
-
await expect(nav).toBeVisible();
|
|
232
|
-
|
|
233
|
-
// Check that ellipsis is shown for many pages
|
|
234
|
-
const ellipsis = canvas.getAllByText('…');
|
|
235
|
-
await expect(ellipsis.length).toBeGreaterThan(0);
|
|
236
|
-
|
|
237
|
-
// Verify buttons are still clickable on mobile
|
|
238
|
-
// Page 4 should be visible as it's adjacent to current page 5
|
|
239
|
-
const page4Button = canvas.getByRole('button', { name: /go to page 4/i });
|
|
240
|
-
await expect(page4Button).toBeVisible();
|
|
241
|
-
|
|
242
|
-
// Check touch target size (should be at least 44x44 for mobile)
|
|
243
|
-
const computedStyle = window.getComputedStyle(page4Button);
|
|
244
|
-
const height = parseInt(computedStyle.height);
|
|
245
|
-
await expect(height).toBeGreaterThanOrEqual(28); // Our small size
|
|
246
|
-
},
|
|
247
|
-
};
|
|
248
|
-
|
|
249
|
-
// Test 7: Theme Variations Test
|
|
250
|
-
export const ThemeVariations: Story = {
|
|
251
|
-
name: '7. Theme Variations',
|
|
252
|
-
decorators: [
|
|
253
|
-
(Story) => (
|
|
254
|
-
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
|
|
255
|
-
<ThemeProvider theme={createTheme({ palette: { mode: 'light' } })}>
|
|
256
|
-
<Box sx={{ p: 2, bgcolor: 'background.paper' }}>
|
|
257
|
-
<Story />
|
|
258
|
-
</Box>
|
|
259
|
-
</ThemeProvider>
|
|
260
|
-
<ThemeProvider theme={createTheme({ palette: { mode: 'dark' } })}>
|
|
261
|
-
<Box sx={{ p: 2, bgcolor: 'background.paper' }}>
|
|
262
|
-
<Story />
|
|
263
|
-
</Box>
|
|
264
|
-
</ThemeProvider>
|
|
265
|
-
</Box>
|
|
266
|
-
),
|
|
267
|
-
],
|
|
268
|
-
args: {
|
|
269
|
-
page: 3,
|
|
270
|
-
count: 10,
|
|
271
|
-
color: 'primary',
|
|
272
|
-
onChange: fn(),
|
|
273
|
-
},
|
|
274
|
-
play: async ({ canvasElement }) => {
|
|
275
|
-
const canvas = within(canvasElement);
|
|
276
|
-
|
|
277
|
-
// Get both theme instances
|
|
278
|
-
const navigations = canvas.getAllByRole('navigation');
|
|
279
|
-
await expect(navigations).toHaveLength(2);
|
|
280
|
-
|
|
281
|
-
// Check both are visible
|
|
282
|
-
for (const nav of navigations) {
|
|
283
|
-
await expect(nav).toBeVisible();
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
// Check current page styling in both themes
|
|
287
|
-
const currentPages = canvas.getAllByRole('button', { name: /page 3/i });
|
|
288
|
-
await expect(currentPages).toHaveLength(2);
|
|
289
|
-
|
|
290
|
-
for (const page of currentPages) {
|
|
291
|
-
await expect(page).toHaveAttribute('aria-current', 'page');
|
|
292
|
-
const styles = window.getComputedStyle(page);
|
|
293
|
-
// Should have background color (primary color)
|
|
294
|
-
await expect(styles.backgroundColor).not.toBe('rgba(0, 0, 0, 0)');
|
|
295
|
-
}
|
|
296
|
-
},
|
|
297
|
-
};
|
|
298
|
-
|
|
299
|
-
// Test 8: Visual States Test
|
|
300
|
-
export const VisualStates: Story = {
|
|
301
|
-
name: '8. Visual States',
|
|
302
|
-
args: {
|
|
303
|
-
page: 5,
|
|
304
|
-
count: 10,
|
|
305
|
-
onChange: fn(),
|
|
306
|
-
},
|
|
307
|
-
play: async ({ canvasElement, args }) => {
|
|
308
|
-
const canvas = within(canvasElement);
|
|
309
|
-
|
|
310
|
-
// Test hover state
|
|
311
|
-
// Use page 4 which is visible (adjacent to current page 5)
|
|
312
|
-
const page4Button = canvas.getByRole('button', { name: /go to page 4/i });
|
|
313
|
-
await userEvent.hover(page4Button);
|
|
314
|
-
|
|
315
|
-
// Small delay to allow hover styles to apply
|
|
316
|
-
// Hover state might be subtle or handled differently by MUI, skip strict check
|
|
317
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
318
|
-
|
|
319
|
-
// Test active/pressed state
|
|
320
|
-
await userEvent.click(page4Button);
|
|
321
|
-
await expect(args.onChange).toHaveBeenCalledWith(expect.anything(), 4);
|
|
322
|
-
|
|
323
|
-
// Test disabled state (first page, previous should be disabled)
|
|
324
|
-
// Use exact match to avoid matching "10"
|
|
325
|
-
const firstPageButton = canvas.getByRole('button', { name: 'Go to page 1' });
|
|
326
|
-
await userEvent.click(firstPageButton);
|
|
327
|
-
},
|
|
328
|
-
};
|
|
329
|
-
|
|
330
|
-
// Test 9: Performance Test
|
|
331
|
-
export const Performance: Story = {
|
|
332
|
-
name: '9. Performance',
|
|
333
|
-
args: {
|
|
334
|
-
page: 50,
|
|
335
|
-
count: 100,
|
|
336
|
-
onChange: fn(),
|
|
337
|
-
},
|
|
338
|
-
play: async ({ canvasElement, args }) => {
|
|
339
|
-
const startTime = Date.now();
|
|
340
|
-
const canvas = within(canvasElement);
|
|
341
|
-
|
|
342
|
-
// Render check
|
|
343
|
-
const nav = canvas.getByRole('navigation');
|
|
344
|
-
await expect(nav).toBeInTheDocument();
|
|
345
|
-
|
|
346
|
-
const renderTime = Date.now() - startTime;
|
|
347
|
-
// Render time should be quick
|
|
348
|
-
await expect(renderTime).toBeLessThan(100);
|
|
349
|
-
|
|
350
|
-
// Interaction performance
|
|
351
|
-
const interactionStart = Date.now();
|
|
352
|
-
|
|
353
|
-
// Click multiple pages rapidly
|
|
354
|
-
const page49Button = canvas.getByRole('button', { name: /go to page 49/i });
|
|
355
|
-
await userEvent.click(page49Button);
|
|
356
|
-
await expect(args.onChange).toHaveBeenCalledWith(expect.anything(), 49);
|
|
357
|
-
|
|
358
|
-
const page51Button = canvas.getByRole('button', { name: /go to page 51/i });
|
|
359
|
-
await userEvent.click(page51Button);
|
|
360
|
-
await expect(args.onChange).toHaveBeenCalledWith(expect.anything(), 51);
|
|
361
|
-
|
|
362
|
-
const interactionTime = Date.now() - interactionStart;
|
|
363
|
-
// Interactions should be fast
|
|
364
|
-
await expect(interactionTime).toBeLessThan(200);
|
|
365
|
-
|
|
366
|
-
// Memory check (ensure no memory leaks with many interactions)
|
|
367
|
-
for (let i = 0; i < 5; i++) {
|
|
368
|
-
const nextButton = canvas.getByRole('button', { name: /go to next page/i });
|
|
369
|
-
if (!nextButton.hasAttribute('disabled')) {
|
|
370
|
-
await userEvent.click(nextButton);
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
},
|
|
374
|
-
};
|
|
375
|
-
|
|
376
|
-
// Test 10: Edge Cases Test
|
|
377
|
-
export const EdgeCases: Story = {
|
|
378
|
-
name: '10. Edge Cases',
|
|
379
|
-
args: {
|
|
380
|
-
page: 1,
|
|
381
|
-
count: 1,
|
|
382
|
-
onChange: fn(),
|
|
383
|
-
},
|
|
384
|
-
play: async ({ canvasElement, args }) => {
|
|
385
|
-
const canvas = within(canvasElement);
|
|
386
|
-
|
|
387
|
-
// Test single page scenario
|
|
388
|
-
const nav = canvas.getByRole('navigation');
|
|
389
|
-
await expect(nav).toBeInTheDocument();
|
|
390
|
-
|
|
391
|
-
// Only page 1 should be visible
|
|
392
|
-
const page1Button = canvas.getByRole('button', { name: /page 1/i });
|
|
393
|
-
await expect(page1Button).toBeInTheDocument();
|
|
394
|
-
await expect(page1Button).toHaveAttribute('aria-current', 'page');
|
|
395
|
-
|
|
396
|
-
// Navigation buttons should be disabled
|
|
397
|
-
const prevButton = canvas.getByRole('button', { name: /go to previous page/i });
|
|
398
|
-
const nextButton = canvas.getByRole('button', { name: /go to next page/i });
|
|
399
|
-
await expect(prevButton).toBeDisabled();
|
|
400
|
-
await expect(nextButton).toBeDisabled();
|
|
401
|
-
|
|
402
|
-
// Test with invalid page (should handle gracefully)
|
|
403
|
-
// Component should clamp to valid range
|
|
404
|
-
await userEvent.click(page1Button);
|
|
405
|
-
await expect(args.onChange).toHaveBeenCalledWith(expect.anything(), 1);
|
|
406
|
-
},
|
|
407
|
-
};
|
|
408
|
-
|
|
409
|
-
// Test 11: Integration Test
|
|
410
|
-
const IntegrationComponent = () => {
|
|
411
|
-
const [page, setPage] = React.useState(1);
|
|
412
|
-
const [itemsPerPage, setItemsPerPage] = React.useState(10);
|
|
413
|
-
const totalItems = 95;
|
|
414
|
-
const pageCount = Math.ceil(totalItems / itemsPerPage);
|
|
415
|
-
|
|
416
|
-
return (
|
|
417
|
-
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 3, alignItems: 'center' }}>
|
|
418
|
-
<Box sx={{ p: 2, border: '1px solid', borderColor: 'divider', borderRadius: 1 }}>
|
|
419
|
-
<div>Total Items: {totalItems}</div>
|
|
420
|
-
<div>Current Page: {page}</div>
|
|
421
|
-
<div>Items Per Page: {itemsPerPage}</div>
|
|
422
|
-
<div>
|
|
423
|
-
Showing items {(page - 1) * itemsPerPage + 1} to{' '}
|
|
424
|
-
{Math.min(page * itemsPerPage, totalItems)}
|
|
425
|
-
</div>
|
|
426
|
-
</Box>
|
|
427
|
-
|
|
428
|
-
<Pagination
|
|
429
|
-
page={page}
|
|
430
|
-
count={pageCount}
|
|
431
|
-
onChange={(_, newPage) => setPage(newPage)}
|
|
432
|
-
showPageInfo={true}
|
|
433
|
-
showItemsPerPage={true}
|
|
434
|
-
itemsPerPage={itemsPerPage}
|
|
435
|
-
itemsPerPageOptions={[5, 10, 25, 50]}
|
|
436
|
-
onItemsPerPageChange={(newValue) => {
|
|
437
|
-
setItemsPerPage(newValue);
|
|
438
|
-
setPage(1); // Reset to first page when changing items per page
|
|
439
|
-
}}
|
|
440
|
-
showFirstButton
|
|
441
|
-
showLastButton
|
|
442
|
-
/>
|
|
443
|
-
|
|
444
|
-
<Box sx={{ display: 'flex', gap: 2 }}>
|
|
445
|
-
<Pagination
|
|
446
|
-
page={page}
|
|
447
|
-
count={pageCount}
|
|
448
|
-
onChange={(_, newPage) => setPage(newPage)}
|
|
449
|
-
variant="rounded"
|
|
450
|
-
size="sm"
|
|
451
|
-
/>
|
|
452
|
-
<Pagination
|
|
453
|
-
page={page}
|
|
454
|
-
count={pageCount}
|
|
455
|
-
onChange={(_, newPage) => setPage(newPage)}
|
|
456
|
-
variant="dots"
|
|
457
|
-
/>
|
|
458
|
-
<Pagination
|
|
459
|
-
page={page}
|
|
460
|
-
count={pageCount}
|
|
461
|
-
onChange={(_, newPage) => setPage(newPage)}
|
|
462
|
-
variant="minimal"
|
|
463
|
-
/>
|
|
464
|
-
</Box>
|
|
465
|
-
</Box>
|
|
466
|
-
);
|
|
467
|
-
};
|
|
468
|
-
|
|
469
|
-
export const Integration: Story = {
|
|
470
|
-
name: '11. Integration',
|
|
471
|
-
render: () => <IntegrationComponent />,
|
|
472
|
-
play: async ({ canvasElement }) => {
|
|
473
|
-
const canvas = within(canvasElement);
|
|
474
|
-
|
|
475
|
-
// Verify all pagination instances are rendered
|
|
476
|
-
const navigations = canvas.getAllByRole('navigation');
|
|
477
|
-
await expect(navigations).toHaveLength(4);
|
|
478
|
-
|
|
479
|
-
// Test that clicking on one updates the display
|
|
480
|
-
const page2Buttons = canvas.getAllByRole('button', { name: /go to page 2/i });
|
|
481
|
-
await userEvent.click(page2Buttons[0]);
|
|
482
|
-
|
|
483
|
-
// Check that the display updated
|
|
484
|
-
await waitFor(() => {
|
|
485
|
-
const currentPageText = canvas.getByText(/Current Page: 2/i);
|
|
486
|
-
expect(currentPageText).toBeInTheDocument();
|
|
487
|
-
});
|
|
488
|
-
|
|
489
|
-
// Test items per page change
|
|
490
|
-
const selectButton = canvas.getByRole('combobox');
|
|
491
|
-
await userEvent.click(selectButton);
|
|
492
|
-
|
|
493
|
-
// MUI Select renders options in a portal, so we need to look in document.body
|
|
494
|
-
await waitFor(async () => {
|
|
495
|
-
const option25 = within(document.body).getByRole('option', { name: '25' });
|
|
496
|
-
await expect(option25).toBeInTheDocument();
|
|
497
|
-
});
|
|
498
|
-
|
|
499
|
-
const option25 = within(document.body).getByRole('option', { name: '25' });
|
|
500
|
-
await userEvent.click(option25);
|
|
501
|
-
|
|
502
|
-
// Verify page count updated
|
|
503
|
-
await waitFor(() => {
|
|
504
|
-
const itemsPerPageText = canvas.getByText(/Items Per Page: 25/i);
|
|
505
|
-
expect(itemsPerPageText).toBeInTheDocument();
|
|
506
|
-
// Page should reset to 1
|
|
507
|
-
const currentPageText = canvas.getByText(/Current Page: 1/i);
|
|
508
|
-
expect(currentPageText).toBeInTheDocument();
|
|
509
|
-
});
|
|
510
|
-
|
|
511
|
-
// Test first/last buttons
|
|
512
|
-
const lastButtons = canvas.getAllByRole('button', { name: /go to last page/i });
|
|
513
|
-
await userEvent.click(lastButtons[0]);
|
|
514
|
-
|
|
515
|
-
await waitFor(() => {
|
|
516
|
-
const currentPageText = canvas.getByText(/Current Page: 4/i);
|
|
517
|
-
expect(currentPageText).toBeInTheDocument();
|
|
518
|
-
});
|
|
519
|
-
},
|
|
520
|
-
};
|