@12-apps/ui 1.5.0 → 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 +16 -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 -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,192 +0,0 @@
|
|
|
1
|
-
import LanguageOutlined from '@mui/icons-material/LanguageOutlined';
|
|
2
|
-
import LockOutlined from '@mui/icons-material/LockOutlined';
|
|
3
|
-
import NotificationsOutlined from '@mui/icons-material/NotificationsOutlined';
|
|
4
|
-
import PaletteOutlined from '@mui/icons-material/PaletteOutlined';
|
|
5
|
-
import PaymentOutlined from '@mui/icons-material/PaymentOutlined';
|
|
6
|
-
import PersonOutlined from '@mui/icons-material/PersonOutlined';
|
|
7
|
-
import { Box, Stack, Typography } from '@mui/material';
|
|
8
|
-
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
9
|
-
import React, { useState } from 'react';
|
|
10
|
-
|
|
11
|
-
import { SettingsLayout } from './SettingsLayout';
|
|
12
|
-
import type { SettingsNavGroup } from './SettingsLayout.types';
|
|
13
|
-
|
|
14
|
-
const GROUPS: SettingsNavGroup[] = [
|
|
15
|
-
{
|
|
16
|
-
id: 'account',
|
|
17
|
-
label: 'Account',
|
|
18
|
-
items: [
|
|
19
|
-
{ id: 'profile', label: 'Profile', icon: <PersonOutlined fontSize="small" /> },
|
|
20
|
-
{
|
|
21
|
-
id: 'security',
|
|
22
|
-
label: 'Security',
|
|
23
|
-
icon: <LockOutlined fontSize="small" />,
|
|
24
|
-
keywords: ['password', 'two-factor', '2fa'],
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
id: 'notifications',
|
|
28
|
-
label: 'Notifications',
|
|
29
|
-
icon: <NotificationsOutlined fontSize="small" />,
|
|
30
|
-
},
|
|
31
|
-
],
|
|
32
|
-
},
|
|
33
|
-
{
|
|
34
|
-
id: 'workspace',
|
|
35
|
-
label: 'Workspace',
|
|
36
|
-
description: 'Preferences that apply to this workspace only.',
|
|
37
|
-
items: [
|
|
38
|
-
{ id: 'appearance', label: 'Appearance', icon: <PaletteOutlined fontSize="small" /> },
|
|
39
|
-
{
|
|
40
|
-
id: 'billing',
|
|
41
|
-
label: 'Billing',
|
|
42
|
-
icon: <PaymentOutlined fontSize="small" />,
|
|
43
|
-
keywords: ['invoice', 'plan', 'payment'],
|
|
44
|
-
},
|
|
45
|
-
],
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
id: 'advanced',
|
|
49
|
-
label: 'Advanced',
|
|
50
|
-
items: [
|
|
51
|
-
{ id: 'language', label: 'Language & region', icon: <LanguageOutlined fontSize="small" /> },
|
|
52
|
-
],
|
|
53
|
-
},
|
|
54
|
-
];
|
|
55
|
-
|
|
56
|
-
const ALL_ITEMS = GROUPS.flatMap((group) => group.items);
|
|
57
|
-
|
|
58
|
-
/** A minimal example panel that reflects the selected item. */
|
|
59
|
-
function ExamplePanel({ itemId }: { itemId: string }): React.JSX.Element {
|
|
60
|
-
const item = ALL_ITEMS.find((candidate) => candidate.id === itemId) ?? ALL_ITEMS[0];
|
|
61
|
-
return (
|
|
62
|
-
<Stack spacing={1} sx={{ p: 1 }}>
|
|
63
|
-
<Typography variant="h6">{item?.label}</Typography>
|
|
64
|
-
<Typography variant="body2" color="text.secondary">
|
|
65
|
-
This central panel renders a custom screen for “{item?.label}”. In a real app each item
|
|
66
|
-
maps to its own route/component.
|
|
67
|
-
</Typography>
|
|
68
|
-
<Box
|
|
69
|
-
sx={{
|
|
70
|
-
mt: 1,
|
|
71
|
-
height: 160,
|
|
72
|
-
borderRadius: 1,
|
|
73
|
-
border: (theme) => `1px dashed ${theme.palette.divider}`,
|
|
74
|
-
}}
|
|
75
|
-
/>
|
|
76
|
-
</Stack>
|
|
77
|
-
);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const meta: Meta<typeof SettingsLayout> = {
|
|
81
|
-
title: 'Layout/SettingsLayout',
|
|
82
|
-
component: SettingsLayout,
|
|
83
|
-
parameters: {
|
|
84
|
-
layout: 'fullscreen',
|
|
85
|
-
},
|
|
86
|
-
tags: ['autodocs', 'component:SettingsLayout'],
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
export default meta;
|
|
90
|
-
type Story = StoryObj<typeof meta>;
|
|
91
|
-
|
|
92
|
-
/** Controlled example: clicking a rail item swaps the central panel. */
|
|
93
|
-
export const Default: Story = {
|
|
94
|
-
render: () => {
|
|
95
|
-
const InteractiveSettings = (): React.JSX.Element => {
|
|
96
|
-
const [active, setActive] = useState('profile');
|
|
97
|
-
return (
|
|
98
|
-
<Box sx={{ p: 3, minHeight: 480 }}>
|
|
99
|
-
<SettingsLayout
|
|
100
|
-
title="Settings"
|
|
101
|
-
searchPlaceholder="Search settings"
|
|
102
|
-
groups={GROUPS}
|
|
103
|
-
activeItemId={active}
|
|
104
|
-
onSelectItem={setActive}
|
|
105
|
-
>
|
|
106
|
-
<ExamplePanel itemId={active} />
|
|
107
|
-
</SettingsLayout>
|
|
108
|
-
</Box>
|
|
109
|
-
);
|
|
110
|
-
};
|
|
111
|
-
return <InteractiveSettings />;
|
|
112
|
-
},
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
/** Group headers can carry a one-line description (Facebook-style). */
|
|
116
|
-
export const WithDescriptions: Story = {
|
|
117
|
-
render: () => (
|
|
118
|
-
<Box sx={{ p: 3, minHeight: 480 }}>
|
|
119
|
-
<SettingsLayout title="Settings" groups={GROUPS} activeItemId="billing">
|
|
120
|
-
<ExamplePanel itemId="billing" />
|
|
121
|
-
</SettingsLayout>
|
|
122
|
-
</Box>
|
|
123
|
-
),
|
|
124
|
-
};
|
|
125
|
-
|
|
126
|
-
/** A single group renders as a flat list under the search field. */
|
|
127
|
-
export const FlatSingleGroup: Story = {
|
|
128
|
-
render: () => (
|
|
129
|
-
<Box sx={{ p: 3, minHeight: 480 }}>
|
|
130
|
-
<SettingsLayout
|
|
131
|
-
title="Settings"
|
|
132
|
-
groups={[{ id: 'all', label: 'All settings', items: ALL_ITEMS }]}
|
|
133
|
-
activeItemId="profile"
|
|
134
|
-
>
|
|
135
|
-
<ExamplePanel itemId="profile" />
|
|
136
|
-
</SettingsLayout>
|
|
137
|
-
</Box>
|
|
138
|
-
),
|
|
139
|
-
};
|
|
140
|
-
|
|
141
|
-
/** Items with `href` + a `linkComponent` render as navigation links. */
|
|
142
|
-
export const AsLinks: Story = {
|
|
143
|
-
render: () => {
|
|
144
|
-
const linkedGroups: SettingsNavGroup[] = GROUPS.map((group) => ({
|
|
145
|
-
...group,
|
|
146
|
-
items: group.items.map((item) => ({ ...item, href: `#/settings/${item.id}` })),
|
|
147
|
-
}));
|
|
148
|
-
return (
|
|
149
|
-
<Box sx={{ p: 3, minHeight: 480 }}>
|
|
150
|
-
<SettingsLayout
|
|
151
|
-
title="Settings"
|
|
152
|
-
groups={linkedGroups}
|
|
153
|
-
activeItemId="security"
|
|
154
|
-
linkComponent="a"
|
|
155
|
-
>
|
|
156
|
-
<ExamplePanel itemId="security" />
|
|
157
|
-
</SettingsLayout>
|
|
158
|
-
</Box>
|
|
159
|
-
);
|
|
160
|
-
},
|
|
161
|
-
};
|
|
162
|
-
|
|
163
|
-
/** Items without icons still align cleanly. */
|
|
164
|
-
export const NoIcons: Story = {
|
|
165
|
-
render: () => {
|
|
166
|
-
const plainGroups: SettingsNavGroup[] = GROUPS.map((group) => ({
|
|
167
|
-
...group,
|
|
168
|
-
items: group.items.map(({ icon: _icon, ...rest }) => rest),
|
|
169
|
-
}));
|
|
170
|
-
return (
|
|
171
|
-
<Box sx={{ p: 3, minHeight: 480 }}>
|
|
172
|
-
<SettingsLayout title="Settings" groups={plainGroups} activeItemId="appearance">
|
|
173
|
-
<ExamplePanel itemId="appearance" />
|
|
174
|
-
</SettingsLayout>
|
|
175
|
-
</Box>
|
|
176
|
-
);
|
|
177
|
-
},
|
|
178
|
-
};
|
|
179
|
-
|
|
180
|
-
/** Below `md` the rail stacks full-width above the panel. */
|
|
181
|
-
export const Responsive: Story = {
|
|
182
|
-
parameters: {
|
|
183
|
-
viewport: { defaultViewport: 'mobile1' },
|
|
184
|
-
},
|
|
185
|
-
render: () => (
|
|
186
|
-
<Box sx={{ p: 2, minHeight: 480 }}>
|
|
187
|
-
<SettingsLayout title="Settings" groups={GROUPS} activeItemId="profile">
|
|
188
|
-
<ExamplePanel itemId="profile" />
|
|
189
|
-
</SettingsLayout>
|
|
190
|
-
</Box>
|
|
191
|
-
),
|
|
192
|
-
};
|
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
import { Typography } from '@mui/material';
|
|
2
|
-
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
3
|
-
import { expect, fn, userEvent, waitFor, within } from 'storybook/test';
|
|
4
|
-
|
|
5
|
-
import { SettingsLayout } from './SettingsLayout';
|
|
6
|
-
import type { SettingsNavGroup } from './SettingsLayout.types';
|
|
7
|
-
|
|
8
|
-
const GROUPS: SettingsNavGroup[] = [
|
|
9
|
-
{
|
|
10
|
-
id: 'account',
|
|
11
|
-
label: 'Account',
|
|
12
|
-
items: [
|
|
13
|
-
{ id: 'profile', label: 'Profile' },
|
|
14
|
-
{ id: 'security', label: 'Security', keywords: ['password', '2fa'] },
|
|
15
|
-
],
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
id: 'workspace',
|
|
19
|
-
label: 'Workspace',
|
|
20
|
-
description: 'Workspace-only preferences.',
|
|
21
|
-
items: [{ id: 'billing', label: 'Billing' }],
|
|
22
|
-
},
|
|
23
|
-
];
|
|
24
|
-
|
|
25
|
-
const meta: Meta<typeof SettingsLayout> = {
|
|
26
|
-
title: 'Layout/SettingsLayout/Tests',
|
|
27
|
-
component: SettingsLayout,
|
|
28
|
-
parameters: {
|
|
29
|
-
layout: 'fullscreen',
|
|
30
|
-
chromatic: { disableSnapshot: false },
|
|
31
|
-
},
|
|
32
|
-
tags: ['autodocs', 'test', 'component:SettingsLayout'],
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
export default meta;
|
|
36
|
-
type Story = StoryObj<typeof meta>;
|
|
37
|
-
|
|
38
|
-
const panel = <Typography data-testid="demo-panel">Panel content</Typography>;
|
|
39
|
-
|
|
40
|
-
export const StructureRender: Story = {
|
|
41
|
-
name: '🧪 Structure Render Test',
|
|
42
|
-
render: () => (
|
|
43
|
-
<SettingsLayout title="Settings" groups={GROUPS} activeItemId="profile">
|
|
44
|
-
{panel}
|
|
45
|
-
</SettingsLayout>
|
|
46
|
-
),
|
|
47
|
-
play: async ({ canvasElement, step }) => {
|
|
48
|
-
const canvas = within(canvasElement);
|
|
49
|
-
|
|
50
|
-
await step('Rail, search, groups and panel render', async () => {
|
|
51
|
-
await expect(canvas.getByTestId('settings-rail')).toBeInTheDocument();
|
|
52
|
-
await expect(canvas.getByTestId('settings-search')).toBeInTheDocument();
|
|
53
|
-
await expect(canvas.getByTestId('settings-group-account')).toBeInTheDocument();
|
|
54
|
-
await expect(canvas.getByTestId('settings-group-workspace')).toBeInTheDocument();
|
|
55
|
-
await expect(canvas.getByTestId('settings-item-profile')).toBeInTheDocument();
|
|
56
|
-
await expect(canvas.getByTestId('settings-panel')).toBeInTheDocument();
|
|
57
|
-
await expect(canvas.getByTestId('demo-panel')).toBeInTheDocument();
|
|
58
|
-
});
|
|
59
|
-
},
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
export const ActiveHighlight: Story = {
|
|
63
|
-
name: '🎯 Active Item Highlight Test',
|
|
64
|
-
render: () => (
|
|
65
|
-
<SettingsLayout title="Settings" groups={GROUPS} activeItemId="security">
|
|
66
|
-
{panel}
|
|
67
|
-
</SettingsLayout>
|
|
68
|
-
),
|
|
69
|
-
play: async ({ canvasElement, step }) => {
|
|
70
|
-
const canvas = within(canvasElement);
|
|
71
|
-
|
|
72
|
-
await step('Active item carries aria-current=page', async () => {
|
|
73
|
-
const active = canvas.getByTestId('settings-item-security');
|
|
74
|
-
await expect(active).toHaveAttribute('aria-current', 'page');
|
|
75
|
-
const inactive = canvas.getByTestId('settings-item-profile');
|
|
76
|
-
await expect(inactive).not.toHaveAttribute('aria-current');
|
|
77
|
-
});
|
|
78
|
-
},
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
export const SelectionCallback: Story = {
|
|
82
|
-
name: '🖱️ Selection Callback Test',
|
|
83
|
-
args: { onSelectItem: fn() },
|
|
84
|
-
render: (args) => (
|
|
85
|
-
<SettingsLayout title="Settings" groups={GROUPS} activeItemId="profile" {...args}>
|
|
86
|
-
{panel}
|
|
87
|
-
</SettingsLayout>
|
|
88
|
-
),
|
|
89
|
-
play: async ({ canvasElement, step, args }) => {
|
|
90
|
-
const canvas = within(canvasElement);
|
|
91
|
-
|
|
92
|
-
await step('Clicking a button item fires onSelectItem with its id', async () => {
|
|
93
|
-
await userEvent.click(canvas.getByTestId('settings-item-billing'));
|
|
94
|
-
await expect(args.onSelectItem).toHaveBeenCalledWith('billing');
|
|
95
|
-
});
|
|
96
|
-
},
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
export const SearchFilters: Story = {
|
|
100
|
-
name: '🔎 Search Filter Test',
|
|
101
|
-
render: () => (
|
|
102
|
-
<SettingsLayout title="Settings" groups={GROUPS} activeItemId="profile">
|
|
103
|
-
{panel}
|
|
104
|
-
</SettingsLayout>
|
|
105
|
-
),
|
|
106
|
-
play: async ({ canvasElement, step }) => {
|
|
107
|
-
const canvas = within(canvasElement);
|
|
108
|
-
const search = canvas.getByTestId('settings-search').querySelector('input');
|
|
109
|
-
|
|
110
|
-
await step('Typing a label narrows the rail', async () => {
|
|
111
|
-
await userEvent.type(search as HTMLInputElement, 'secur');
|
|
112
|
-
await expect(canvas.getByTestId('settings-item-security')).toBeInTheDocument();
|
|
113
|
-
await waitFor(() => {
|
|
114
|
-
expect(canvas.queryByTestId('settings-item-profile')).not.toBeInTheDocument();
|
|
115
|
-
expect(canvas.queryByTestId('settings-group-workspace')).not.toBeInTheDocument();
|
|
116
|
-
});
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
await step('Keywords are matched too', async () => {
|
|
120
|
-
await userEvent.clear(search as HTMLInputElement);
|
|
121
|
-
await userEvent.type(search as HTMLInputElement, 'password');
|
|
122
|
-
await expect(canvas.getByTestId('settings-item-security')).toBeInTheDocument();
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
await step('No match shows the empty state', async () => {
|
|
126
|
-
await userEvent.clear(search as HTMLInputElement);
|
|
127
|
-
await userEvent.type(search as HTMLInputElement, 'zzzzz');
|
|
128
|
-
await expect(canvas.getByTestId('settings-empty')).toBeInTheDocument();
|
|
129
|
-
});
|
|
130
|
-
},
|
|
131
|
-
};
|
|
132
|
-
|
|
133
|
-
export const LinkMode: Story = {
|
|
134
|
-
name: '🔗 Link Mode Test',
|
|
135
|
-
render: () => {
|
|
136
|
-
const linked: SettingsNavGroup[] = GROUPS.map((group) => ({
|
|
137
|
-
...group,
|
|
138
|
-
items: group.items.map((item) => ({ ...item, href: `#/settings/${item.id}` })),
|
|
139
|
-
}));
|
|
140
|
-
return (
|
|
141
|
-
<SettingsLayout title="Settings" groups={linked} activeItemId="profile" linkComponent="a">
|
|
142
|
-
{panel}
|
|
143
|
-
</SettingsLayout>
|
|
144
|
-
);
|
|
145
|
-
},
|
|
146
|
-
play: async ({ canvasElement, step }) => {
|
|
147
|
-
const canvas = within(canvasElement);
|
|
148
|
-
|
|
149
|
-
await step('Items with href render as anchors', async () => {
|
|
150
|
-
const item = canvas.getByTestId('settings-item-security');
|
|
151
|
-
await expect(item.tagName.toLowerCase()).toBe('a');
|
|
152
|
-
await expect(item).toHaveAttribute('href', '#/settings/security');
|
|
153
|
-
});
|
|
154
|
-
},
|
|
155
|
-
};
|
|
156
|
-
|
|
157
|
-
export const KeyboardNavigation: Story = {
|
|
158
|
-
name: '⌨️ Keyboard Navigation Test',
|
|
159
|
-
render: () => (
|
|
160
|
-
<SettingsLayout title="Settings" groups={GROUPS} activeItemId="profile">
|
|
161
|
-
{panel}
|
|
162
|
-
</SettingsLayout>
|
|
163
|
-
),
|
|
164
|
-
play: async ({ canvasElement, step }) => {
|
|
165
|
-
const canvas = within(canvasElement);
|
|
166
|
-
|
|
167
|
-
await step('Search field is focusable and typeable', async () => {
|
|
168
|
-
const input = canvas.getByTestId('settings-search').querySelector('input') as HTMLInputElement;
|
|
169
|
-
await userEvent.click(input);
|
|
170
|
-
await waitFor(() => expect(input).toHaveFocus());
|
|
171
|
-
await userEvent.keyboard('pro');
|
|
172
|
-
await expect(canvas.getByTestId('settings-item-profile')).toBeInTheDocument();
|
|
173
|
-
});
|
|
174
|
-
},
|
|
175
|
-
};
|