@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,195 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi } from "vitest";
|
|
2
|
-
import { render, screen, fireEvent } from "@testing-library/react";
|
|
3
|
-
import { UserAvatar, UserMenu } from "../user-avatar";
|
|
4
|
-
|
|
5
|
-
describe("UserAvatar", () => {
|
|
6
|
-
it("should render with image when src is provided", () => {
|
|
7
|
-
const { container } = render(
|
|
8
|
-
<UserAvatar
|
|
9
|
-
src="https://example.com/avatar.jpg"
|
|
10
|
-
name="John Doe"
|
|
11
|
-
/>
|
|
12
|
-
);
|
|
13
|
-
|
|
14
|
-
// Avatar uses Fade animation, so query directly
|
|
15
|
-
const img = container.querySelector('img.MuiAvatar-img');
|
|
16
|
-
expect(img).toHaveAttribute("src", "https://example.com/avatar.jpg");
|
|
17
|
-
expect(img).toHaveAttribute("alt", "John Doe");
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
it("should render initials when no src is provided", () => {
|
|
21
|
-
render(<UserAvatar name="John Doe" />);
|
|
22
|
-
|
|
23
|
-
expect(screen.getByText("JD")).toBeInTheDocument();
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
it("should render single initial for single-word name", () => {
|
|
27
|
-
render(<UserAvatar name="John" />);
|
|
28
|
-
|
|
29
|
-
expect(screen.getByText("JO")).toBeInTheDocument();
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
it("should render question mark when no name or src", () => {
|
|
33
|
-
render(<UserAvatar />);
|
|
34
|
-
|
|
35
|
-
expect(screen.getByText("?")).toBeInTheDocument();
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
it("should render initials from first and last name", () => {
|
|
39
|
-
render(<UserAvatar name="John Michael Doe" />);
|
|
40
|
-
|
|
41
|
-
expect(screen.getByText("JD")).toBeInTheDocument();
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
it("should apply size lg", () => {
|
|
45
|
-
const { container } = render(<UserAvatar name="John" size="lg" />);
|
|
46
|
-
|
|
47
|
-
// Avatar size "lg" is 48x48 per UI package Avatar
|
|
48
|
-
const avatar = container.querySelector('.MuiAvatar-root');
|
|
49
|
-
expect(avatar).toBeInTheDocument();
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it("should use default size md", () => {
|
|
53
|
-
const { container } = render(<UserAvatar name="John" />);
|
|
54
|
-
|
|
55
|
-
// Avatar default size "md" is 40x40 per UI package Avatar
|
|
56
|
-
const avatar = container.querySelector('.MuiAvatar-root');
|
|
57
|
-
expect(avatar).toBeInTheDocument();
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
it("should call onClick when clicked", () => {
|
|
61
|
-
const handleClick = vi.fn();
|
|
62
|
-
const { container } = render(
|
|
63
|
-
<UserAvatar name="John" onClick={handleClick} />
|
|
64
|
-
);
|
|
65
|
-
|
|
66
|
-
const avatar = container.querySelector('.MuiAvatar-root') as HTMLElement;
|
|
67
|
-
fireEvent.click(avatar);
|
|
68
|
-
|
|
69
|
-
expect(handleClick).toHaveBeenCalledTimes(1);
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
it("should have button role when onClick is provided", () => {
|
|
73
|
-
const handleClick = vi.fn();
|
|
74
|
-
const { container } = render(
|
|
75
|
-
<UserAvatar name="John" onClick={handleClick} />
|
|
76
|
-
);
|
|
77
|
-
|
|
78
|
-
const avatar = container.querySelector('.MuiAvatar-root');
|
|
79
|
-
expect(avatar).toHaveAttribute("role", "button");
|
|
80
|
-
expect(avatar).toHaveAttribute("tabIndex", "0");
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
it("should not have button role when onClick is not provided", () => {
|
|
84
|
-
const { container } = render(<UserAvatar name="John" />);
|
|
85
|
-
|
|
86
|
-
const avatar = container.querySelector('.MuiAvatar-root');
|
|
87
|
-
expect(avatar).not.toHaveAttribute("role", "button");
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
it("should be interactive when onClick is provided", () => {
|
|
91
|
-
const handleClick = vi.fn();
|
|
92
|
-
const { container } = render(
|
|
93
|
-
<UserAvatar name="John" onClick={handleClick} />
|
|
94
|
-
);
|
|
95
|
-
|
|
96
|
-
const avatar = container.querySelector('.MuiAvatar-root');
|
|
97
|
-
// Interactive avatars have cursor: pointer style and hover effects
|
|
98
|
-
expect(avatar).toHaveAttribute("tabIndex", "0");
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
it("should handle null src gracefully", () => {
|
|
102
|
-
render(<UserAvatar src={null} name="John Doe" />);
|
|
103
|
-
|
|
104
|
-
expect(screen.getByText("JD")).toBeInTheDocument();
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
it("should handle null name gracefully", () => {
|
|
108
|
-
render(<UserAvatar name={null} />);
|
|
109
|
-
|
|
110
|
-
expect(screen.getByText("?")).toBeInTheDocument();
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
it("should render image with fallback alt text", () => {
|
|
114
|
-
const { container } = render(<UserAvatar src="https://example.com/avatar.jpg" />);
|
|
115
|
-
|
|
116
|
-
// Avatar uses Fade animation, so query directly
|
|
117
|
-
const img = container.querySelector('img.MuiAvatar-img');
|
|
118
|
-
expect(img).toHaveAttribute("alt", "User avatar");
|
|
119
|
-
});
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
describe("UserMenu", () => {
|
|
123
|
-
const mockUser = {
|
|
124
|
-
name: "John Doe",
|
|
125
|
-
email: "john@example.com",
|
|
126
|
-
image: "https://example.com/avatar.jpg",
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
it("should render user name and email", () => {
|
|
130
|
-
render(<UserMenu user={mockUser} onSignOut={vi.fn()} />);
|
|
131
|
-
|
|
132
|
-
expect(screen.getByText("John Doe")).toBeInTheDocument();
|
|
133
|
-
expect(screen.getByText("john@example.com")).toBeInTheDocument();
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
it("should render user avatar with image", () => {
|
|
137
|
-
const { container } = render(<UserMenu user={mockUser} onSignOut={vi.fn()} />);
|
|
138
|
-
|
|
139
|
-
// Avatar uses Fade animation, so query directly
|
|
140
|
-
const img = container.querySelector('img.MuiAvatar-img');
|
|
141
|
-
expect(img).toHaveAttribute("src", mockUser.image);
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
it("should render sign out button", () => {
|
|
145
|
-
render(<UserMenu user={mockUser} onSignOut={vi.fn()} />);
|
|
146
|
-
|
|
147
|
-
expect(screen.getByText("Sign out")).toBeInTheDocument();
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
it("should call onSignOut when sign out button is clicked", () => {
|
|
151
|
-
const handleSignOut = vi.fn();
|
|
152
|
-
render(<UserMenu user={mockUser} onSignOut={handleSignOut} />);
|
|
153
|
-
|
|
154
|
-
const signOutButton = screen.getByText("Sign out");
|
|
155
|
-
fireEvent.click(signOutButton);
|
|
156
|
-
|
|
157
|
-
expect(handleSignOut).toHaveBeenCalledTimes(1);
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
it("should render default name when name is null", () => {
|
|
161
|
-
const userWithoutName = {
|
|
162
|
-
...mockUser,
|
|
163
|
-
name: null,
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
render(<UserMenu user={userWithoutName} onSignOut={vi.fn()} />);
|
|
167
|
-
|
|
168
|
-
expect(screen.getByText("User")).toBeInTheDocument();
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
it("should render avatar with initials when no image", () => {
|
|
172
|
-
const userWithoutImage = {
|
|
173
|
-
name: "John Doe",
|
|
174
|
-
email: "john@example.com",
|
|
175
|
-
image: null,
|
|
176
|
-
};
|
|
177
|
-
|
|
178
|
-
render(<UserMenu user={userWithoutImage} onSignOut={vi.fn()} />);
|
|
179
|
-
|
|
180
|
-
expect(screen.getByText("JD")).toBeInTheDocument();
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
it("should handle empty user object gracefully", () => {
|
|
184
|
-
const emptyUser = {
|
|
185
|
-
name: null,
|
|
186
|
-
email: null,
|
|
187
|
-
image: null,
|
|
188
|
-
};
|
|
189
|
-
|
|
190
|
-
render(<UserMenu user={emptyUser} onSignOut={vi.fn()} />);
|
|
191
|
-
|
|
192
|
-
expect(screen.getByText("User")).toBeInTheDocument();
|
|
193
|
-
expect(screen.getByText("?")).toBeInTheDocument();
|
|
194
|
-
});
|
|
195
|
-
});
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Viewport helpers: full-height surfaces must be pinned to the DYNAMIC viewport,
|
|
3
|
-
* because iOS resolves `100vh` against the large viewport and parks the bottom of
|
|
4
|
-
* a fixed panel (the submit row) underneath the browser toolbar.
|
|
5
|
-
*/
|
|
6
|
-
import { describe, expect, it } from "vitest";
|
|
7
|
-
|
|
8
|
-
import {
|
|
9
|
-
DYNAMIC_VIEWPORT_HEIGHT,
|
|
10
|
-
VIEWPORT_HEIGHT_FALLBACK,
|
|
11
|
-
dynamicViewportHeight,
|
|
12
|
-
safeAreaBottom,
|
|
13
|
-
} from "../utils/viewport";
|
|
14
|
-
|
|
15
|
-
const SUPPORTS_DVH = `@supports (height: ${DYNAMIC_VIEWPORT_HEIGHT})`;
|
|
16
|
-
|
|
17
|
-
describe("dynamicViewportHeight", () => {
|
|
18
|
-
it("emits the vh fallback up front and upgrades to dvh under @supports", () => {
|
|
19
|
-
const styles = dynamicViewportHeight("height");
|
|
20
|
-
|
|
21
|
-
expect(styles.height).toBe(VIEWPORT_HEIGHT_FALLBACK);
|
|
22
|
-
expect(styles[SUPPORTS_DVH]).toEqual({ height: DYNAMIC_VIEWPORT_HEIGHT });
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
it("pins every requested property, so maxHeight can't re-clamp to 100vh", () => {
|
|
26
|
-
const styles = dynamicViewportHeight("height", "maxHeight");
|
|
27
|
-
|
|
28
|
-
expect(styles.height).toBe(VIEWPORT_HEIGHT_FALLBACK);
|
|
29
|
-
expect(styles.maxHeight).toBe(VIEWPORT_HEIGHT_FALLBACK);
|
|
30
|
-
expect(styles[SUPPORTS_DVH]).toEqual({
|
|
31
|
-
height: DYNAMIC_VIEWPORT_HEIGHT,
|
|
32
|
-
maxHeight: DYNAMIC_VIEWPORT_HEIGHT,
|
|
33
|
-
});
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it("defaults to `height` when called with no properties", () => {
|
|
37
|
-
expect(dynamicViewportHeight()).toEqual(dynamicViewportHeight("height"));
|
|
38
|
-
});
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
describe("safeAreaBottom", () => {
|
|
42
|
-
it("keeps the base padding as the fallback and adds the inset on top", () => {
|
|
43
|
-
const styles = safeAreaBottom(16);
|
|
44
|
-
|
|
45
|
-
expect(styles.paddingBottom).toBe("16px");
|
|
46
|
-
expect(styles["@supports (padding: max(0px))"]).toEqual({
|
|
47
|
-
paddingBottom: "max(16px, calc(16px + env(safe-area-inset-bottom)))",
|
|
48
|
-
});
|
|
49
|
-
});
|
|
50
|
-
});
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi } from "vitest";
|
|
2
|
-
import { fireEvent, render, screen } from "@testing-library/react";
|
|
3
|
-
|
|
4
|
-
import { Command } from "../../form/Command/Command";
|
|
5
|
-
import type { CommandItem } from "../../form/Command/Command.types";
|
|
6
|
-
|
|
7
|
-
const items: CommandItem[] = [
|
|
8
|
-
{ id: "new-file", label: "New File", category: "File" },
|
|
9
|
-
{ id: "open-file", label: "Open File", category: "File" },
|
|
10
|
-
{ id: "settings", label: "Settings", category: "Preferences" },
|
|
11
|
-
];
|
|
12
|
-
|
|
13
|
-
function renderCommand(props: Partial<React.ComponentProps<typeof Command>> = {}) {
|
|
14
|
-
return render(
|
|
15
|
-
<Command
|
|
16
|
-
open
|
|
17
|
-
items={items}
|
|
18
|
-
autoFocus={false}
|
|
19
|
-
dataTestId="command"
|
|
20
|
-
{...props}
|
|
21
|
-
/>,
|
|
22
|
-
);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
describe("Command (REUSE — form/Command primitive)", () => {
|
|
26
|
-
it("renders items grouped into sections via category when showCategories is on", () => {
|
|
27
|
-
renderCommand({ showCategories: true });
|
|
28
|
-
|
|
29
|
-
// Category headings rendered as group containers.
|
|
30
|
-
expect(screen.getByTestId("command-group-File")).toBeInTheDocument();
|
|
31
|
-
expect(screen.getByTestId("command-group-Preferences")).toBeInTheDocument();
|
|
32
|
-
|
|
33
|
-
// All items present.
|
|
34
|
-
expect(screen.getByTestId("command-item-new-file")).toBeInTheDocument();
|
|
35
|
-
expect(screen.getByTestId("command-item-open-file")).toBeInTheDocument();
|
|
36
|
-
expect(screen.getByTestId("command-item-settings")).toBeInTheDocument();
|
|
37
|
-
|
|
38
|
-
// The File group contains both file items.
|
|
39
|
-
const fileGroup = screen.getByTestId("command-group-File");
|
|
40
|
-
expect(fileGroup).toHaveTextContent("New File");
|
|
41
|
-
expect(fileGroup).toHaveTextContent("Open File");
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
it("moves the visible highlight down with ArrowDown", () => {
|
|
45
|
-
renderCommand();
|
|
46
|
-
const input = screen.getByTestId("command-input");
|
|
47
|
-
|
|
48
|
-
// First item highlighted by default.
|
|
49
|
-
expect(screen.getByTestId("command-item-new-file")).toHaveClass(
|
|
50
|
-
"Mui-selected",
|
|
51
|
-
);
|
|
52
|
-
|
|
53
|
-
fireEvent.keyDown(input, { key: "ArrowDown" });
|
|
54
|
-
|
|
55
|
-
// Highlight advances to the second item.
|
|
56
|
-
expect(screen.getByTestId("command-item-open-file")).toHaveClass(
|
|
57
|
-
"Mui-selected",
|
|
58
|
-
);
|
|
59
|
-
expect(screen.getByTestId("command-item-new-file")).not.toHaveClass(
|
|
60
|
-
"Mui-selected",
|
|
61
|
-
);
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
it("moves the visible highlight up with ArrowUp", () => {
|
|
65
|
-
renderCommand();
|
|
66
|
-
const input = screen.getByTestId("command-input");
|
|
67
|
-
|
|
68
|
-
// Move down twice, then up once → land on the second item.
|
|
69
|
-
fireEvent.keyDown(input, { key: "ArrowDown" });
|
|
70
|
-
fireEvent.keyDown(input, { key: "ArrowDown" });
|
|
71
|
-
fireEvent.keyDown(input, { key: "ArrowUp" });
|
|
72
|
-
|
|
73
|
-
expect(screen.getByTestId("command-item-open-file")).toHaveClass(
|
|
74
|
-
"Mui-selected",
|
|
75
|
-
);
|
|
76
|
-
expect(screen.getByTestId("command-item-settings")).not.toHaveClass(
|
|
77
|
-
"Mui-selected",
|
|
78
|
-
);
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
it("calls onSelect with the highlighted item on Enter", () => {
|
|
82
|
-
const onSelect = vi.fn();
|
|
83
|
-
renderCommand({ onSelect, closeOnSelect: false });
|
|
84
|
-
const input = screen.getByTestId("command-input");
|
|
85
|
-
|
|
86
|
-
fireEvent.keyDown(input, { key: "ArrowDown" });
|
|
87
|
-
fireEvent.keyDown(input, { key: "Enter" });
|
|
88
|
-
|
|
89
|
-
expect(onSelect).toHaveBeenCalledTimes(1);
|
|
90
|
-
expect(onSelect).toHaveBeenCalledWith(
|
|
91
|
-
expect.objectContaining({ id: "open-file" }),
|
|
92
|
-
);
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
it("calls onOpenChange(false) on Escape", () => {
|
|
96
|
-
const onOpenChange = vi.fn();
|
|
97
|
-
renderCommand({ onOpenChange });
|
|
98
|
-
const input = screen.getByTestId("command-input");
|
|
99
|
-
|
|
100
|
-
fireEvent.keyDown(input, { key: "Escape" });
|
|
101
|
-
|
|
102
|
-
expect(onOpenChange).toHaveBeenCalledWith(false);
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
it("renders the empty message when there are no items", () => {
|
|
106
|
-
renderCommand({ items: [], emptyMessage: "Nothing here" });
|
|
107
|
-
|
|
108
|
-
expect(screen.getByTestId("command-empty")).toHaveTextContent(
|
|
109
|
-
"Nothing here",
|
|
110
|
-
);
|
|
111
|
-
});
|
|
112
|
-
});
|