@aleph-alpha/ui-library 1.13.0 → 1.14.0

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.
Files changed (120) hide show
  1. package/README.md +1 -1
  2. package/config.js +34 -1
  3. package/dist/system/index.d.ts +1728 -234
  4. package/dist/system/lib.js +19804 -16600
  5. package/package.json +1 -1
  6. package/src/components/UiKbd/UiKbd.stories.ts +1 -1
  7. package/src/components/UiNavigationMenu/UiNavigationMenu.stories.ts +1196 -0
  8. package/src/components/UiNavigationMenu/UiNavigationMenu.vue +39 -0
  9. package/src/components/UiNavigationMenu/UiNavigationMenuContent.vue +25 -0
  10. package/src/components/UiNavigationMenu/UiNavigationMenuIndicator.vue +14 -0
  11. package/src/components/UiNavigationMenu/UiNavigationMenuItem.vue +16 -0
  12. package/src/components/UiNavigationMenu/UiNavigationMenuLink.vue +27 -0
  13. package/src/components/UiNavigationMenu/UiNavigationMenuList.vue +16 -0
  14. package/src/components/UiNavigationMenu/UiNavigationMenuTrigger.vue +16 -0
  15. package/src/components/UiNavigationMenu/__tests__/UiNavigationMenu.test.ts +428 -0
  16. package/src/components/UiNavigationMenu/index.ts +11 -0
  17. package/src/components/UiNavigationMenu/types.ts +185 -0
  18. package/src/components/UiSheet/UiSheet.stories.ts +715 -0
  19. package/src/components/UiSheet/__tests__/UiSheet.test.ts +229 -0
  20. package/src/components/UiSheet/index.ts +12 -0
  21. package/src/components/UiSheet/types.ts +83 -0
  22. package/src/components/UiSidebar/UiSidebar.stories.ts +1010 -0
  23. package/src/components/UiSidebar/UiSidebar.vue +20 -0
  24. package/src/components/UiSidebar/UiSidebarGroupAction.vue +18 -0
  25. package/src/components/UiSidebar/UiSidebarGroupLabel.vue +18 -0
  26. package/src/components/UiSidebar/UiSidebarHeaderTrigger.vue +53 -0
  27. package/src/components/UiSidebar/UiSidebarInput.vue +14 -0
  28. package/src/components/UiSidebar/UiSidebarMenuAction.vue +19 -0
  29. package/src/components/UiSidebar/UiSidebarMenuButton.vue +27 -0
  30. package/src/components/UiSidebar/UiSidebarMenuSkeleton.vue +16 -0
  31. package/src/components/UiSidebar/UiSidebarMenuSubButton.vue +24 -0
  32. package/src/components/UiSidebar/UiSidebarProvider.vue +18 -0
  33. package/src/components/UiSidebar/UiSidebarSeparator.vue +13 -0
  34. package/src/components/UiSidebar/__tests__/UiSidebar.test.ts +221 -0
  35. package/src/components/UiSidebar/index.ts +34 -0
  36. package/src/components/UiSidebar/types.ts +168 -0
  37. package/src/components/UiStepper/UiStepper.stories.ts +425 -0
  38. package/src/components/UiStepper/UiStepper.vue +27 -0
  39. package/src/components/UiStepper/UiStepperDescription.vue +20 -0
  40. package/src/components/UiStepper/UiStepperIndicator.vue +13 -0
  41. package/src/components/UiStepper/UiStepperItem.vue +25 -0
  42. package/src/components/UiStepper/UiStepperSeparator.vue +17 -0
  43. package/src/components/UiStepper/UiStepperTitle.vue +19 -0
  44. package/src/components/UiStepper/UiStepperTrigger.vue +18 -0
  45. package/src/components/UiStepper/__tests__/UiStepper.test.ts +167 -0
  46. package/src/components/UiStepper/index.ts +9 -0
  47. package/src/components/UiStepper/types.ts +65 -0
  48. package/src/components/core/alert/index.ts +2 -2
  49. package/src/components/core/alert-dialog/AlertDialogContent.vue +1 -1
  50. package/src/components/core/card/Card.vue +1 -1
  51. package/src/components/core/drawer/DrawerContent.vue +1 -1
  52. package/src/components/core/dropdown-menu/DropdownMenuContent.vue +1 -1
  53. package/src/components/core/dropdown-menu/DropdownMenuSubContent.vue +1 -1
  54. package/src/components/core/input/Input.vue +1 -1
  55. package/src/components/core/native-select/NativeSelect.vue +1 -1
  56. package/src/components/core/native-select/NativeSelectOptGroup.vue +1 -1
  57. package/src/components/core/native-select/NativeSelectOption.vue +1 -1
  58. package/src/components/core/navigation-menu/NavigationMenu.vue +40 -0
  59. package/src/components/core/navigation-menu/NavigationMenuContent.vue +28 -0
  60. package/src/components/core/navigation-menu/NavigationMenuIndicator.vue +26 -0
  61. package/src/components/core/navigation-menu/NavigationMenuItem.vue +19 -0
  62. package/src/components/core/navigation-menu/NavigationMenuLink.vue +27 -0
  63. package/src/components/core/navigation-menu/NavigationMenuList.vue +21 -0
  64. package/src/components/core/navigation-menu/NavigationMenuTrigger.vue +27 -0
  65. package/src/components/core/navigation-menu/NavigationMenuViewport.vue +26 -0
  66. package/src/components/core/navigation-menu/index.ts +14 -0
  67. package/src/components/core/popover/PopoverContent.vue +1 -1
  68. package/src/components/core/select/SelectContent.vue +1 -1
  69. package/src/components/core/select/SelectTrigger.vue +1 -1
  70. package/src/components/core/sheet/Sheet.vue +15 -0
  71. package/src/components/core/sheet/SheetClose.vue +12 -0
  72. package/src/components/core/sheet/SheetContent.vue +56 -0
  73. package/src/components/core/sheet/SheetDescription.vue +19 -0
  74. package/src/components/core/sheet/SheetFooter.vue +9 -0
  75. package/src/components/core/sheet/SheetHeader.vue +9 -0
  76. package/src/components/core/sheet/SheetOverlay.vue +24 -0
  77. package/src/components/core/sheet/SheetTitle.vue +19 -0
  78. package/src/components/core/sheet/SheetTrigger.vue +12 -0
  79. package/src/components/core/sheet/index.ts +8 -0
  80. package/src/components/core/sidebar/Sidebar.vue +105 -0
  81. package/src/components/core/sidebar/SidebarContent.vue +21 -0
  82. package/src/components/core/sidebar/SidebarFooter.vue +16 -0
  83. package/src/components/core/sidebar/SidebarGroup.vue +16 -0
  84. package/src/components/core/sidebar/SidebarGroupAction.vue +25 -0
  85. package/src/components/core/sidebar/SidebarGroupContent.vue +16 -0
  86. package/src/components/core/sidebar/SidebarGroupLabel.vue +23 -0
  87. package/src/components/core/sidebar/SidebarHeader.vue +16 -0
  88. package/src/components/core/sidebar/SidebarInput.vue +17 -0
  89. package/src/components/core/sidebar/SidebarInset.vue +21 -0
  90. package/src/components/core/sidebar/SidebarMenu.vue +16 -0
  91. package/src/components/core/sidebar/SidebarMenuAction.vue +33 -0
  92. package/src/components/core/sidebar/SidebarMenuBadge.vue +26 -0
  93. package/src/components/core/sidebar/SidebarMenuButton.vue +49 -0
  94. package/src/components/core/sidebar/SidebarMenuButtonChild.vue +36 -0
  95. package/src/components/core/sidebar/SidebarMenuItem.vue +16 -0
  96. package/src/components/core/sidebar/SidebarMenuSkeleton.vue +32 -0
  97. package/src/components/core/sidebar/SidebarMenuSub.vue +22 -0
  98. package/src/components/core/sidebar/SidebarMenuSubButton.vue +38 -0
  99. package/src/components/core/sidebar/SidebarMenuSubItem.vue +16 -0
  100. package/src/components/core/sidebar/SidebarProvider.vue +102 -0
  101. package/src/components/core/sidebar/SidebarRail.vue +33 -0
  102. package/src/components/core/sidebar/SidebarSeparator.vue +17 -0
  103. package/src/components/core/sidebar/SidebarTrigger.vue +25 -0
  104. package/src/components/core/sidebar/index.ts +58 -0
  105. package/src/components/core/sidebar/utils.ts +19 -0
  106. package/src/components/core/stepper/Stepper.vue +20 -0
  107. package/src/components/core/stepper/StepperDescription.vue +23 -0
  108. package/src/components/core/stepper/StepperIndicator.vue +34 -0
  109. package/src/components/core/stepper/StepperItem.vue +23 -0
  110. package/src/components/core/stepper/StepperSeparator.vue +29 -0
  111. package/src/components/core/stepper/StepperTitle.vue +24 -0
  112. package/src/components/core/stepper/StepperTrigger.vue +22 -0
  113. package/src/components/core/stepper/index.ts +7 -0
  114. package/src/components/core/tabs/TabsTrigger.vue +1 -1
  115. package/src/components/core/tags-input/TagsInput.vue +1 -1
  116. package/src/components/core/textarea/Textarea.vue +1 -1
  117. package/src/components/index.ts +4 -0
  118. package/src/theme/Background.stories.ts +84 -35
  119. package/src/theme/Extended.stories.ts +4 -4
  120. package/tokens.json +145 -8
@@ -0,0 +1,229 @@
1
+ import { render } from '@testing-library/vue';
2
+ import { describe, expect, test, vi } from 'vitest';
3
+ import {
4
+ UiSheet,
5
+ UiSheetClose,
6
+ UiSheetContent,
7
+ UiSheetDescription,
8
+ UiSheetFooter,
9
+ UiSheetHeader,
10
+ UiSheetTitle,
11
+ UiSheetTrigger,
12
+ } from '../index';
13
+ import { UiButton } from '../../UiButton';
14
+ import { ref } from 'vue';
15
+
16
+ describe('UiSheet', () => {
17
+ test('emits update:open when trigger is clicked', async () => {
18
+ const onUpdateOpen = vi.fn();
19
+ const { getByText } = render({
20
+ components: {
21
+ UiSheet,
22
+ UiSheetContent,
23
+ UiSheetDescription,
24
+ UiSheetHeader,
25
+ UiSheetTitle,
26
+ UiSheetTrigger,
27
+ },
28
+ setup() {
29
+ return { onUpdateOpen };
30
+ },
31
+ template: `
32
+ <UiSheet @update:open="onUpdateOpen">
33
+ <UiSheetTrigger>Open</UiSheetTrigger>
34
+ <UiSheetContent>
35
+ <UiSheetHeader>
36
+ <UiSheetTitle>Title</UiSheetTitle>
37
+ <UiSheetDescription>Description</UiSheetDescription>
38
+ </UiSheetHeader>
39
+ Content
40
+ </UiSheetContent>
41
+ </UiSheet>
42
+ `,
43
+ });
44
+
45
+ await getByText('Open').click();
46
+ expect(onUpdateOpen).toHaveBeenCalledWith(true);
47
+ });
48
+
49
+ test('works with as-child pattern and UiButton', async () => {
50
+ const onUpdateOpen = vi.fn();
51
+ const { getByRole } = render({
52
+ components: {
53
+ UiSheet,
54
+ UiSheetContent,
55
+ UiSheetDescription,
56
+ UiSheetHeader,
57
+ UiSheetTitle,
58
+ UiSheetTrigger,
59
+ UiButton,
60
+ },
61
+ setup() {
62
+ return { onUpdateOpen };
63
+ },
64
+ template: `
65
+ <UiSheet @update:open="onUpdateOpen">
66
+ <UiSheetTrigger as-child>
67
+ <UiButton variant="outline">Open Sheet</UiButton>
68
+ </UiSheetTrigger>
69
+ <UiSheetContent>
70
+ <UiSheetHeader>
71
+ <UiSheetTitle>Title</UiSheetTitle>
72
+ <UiSheetDescription>Description</UiSheetDescription>
73
+ </UiSheetHeader>
74
+ Content
75
+ </UiSheetContent>
76
+ </UiSheet>
77
+ `,
78
+ });
79
+
80
+ await getByRole('button', { name: 'Open Sheet' }).click();
81
+ expect(onUpdateOpen).toHaveBeenCalledWith(true);
82
+ });
83
+
84
+ test('closes via UiSheetClose', async () => {
85
+ const onUpdateOpen = vi.fn();
86
+ const { getByRole, getByText } = render({
87
+ components: {
88
+ UiSheet,
89
+ UiSheetClose,
90
+ UiSheetContent,
91
+ UiSheetDescription,
92
+ UiSheetFooter,
93
+ UiSheetHeader,
94
+ UiSheetTitle,
95
+ UiSheetTrigger,
96
+ },
97
+ setup() {
98
+ return { onUpdateOpen };
99
+ },
100
+ template: `
101
+ <UiSheet @update:open="onUpdateOpen">
102
+ <UiSheetTrigger>Open</UiSheetTrigger>
103
+ <UiSheetContent>
104
+ <UiSheetHeader>
105
+ <UiSheetTitle>Title</UiSheetTitle>
106
+ <UiSheetDescription>Description</UiSheetDescription>
107
+ </UiSheetHeader>
108
+ <UiSheetFooter>
109
+ <UiSheetClose>Close sheet</UiSheetClose>
110
+ </UiSheetFooter>
111
+ </UiSheetContent>
112
+ </UiSheet>
113
+ `,
114
+ });
115
+
116
+ await getByText('Open').click();
117
+ expect(getByRole('dialog')).toBeInTheDocument();
118
+
119
+ await getByText('Close sheet').click();
120
+ expect(onUpdateOpen).toHaveBeenCalledWith(false);
121
+ });
122
+
123
+ test('emits escapeKeyDown and closes when Escape is pressed', async () => {
124
+ const onEscapeKeyDown = vi.fn();
125
+ const onUpdateOpen = vi.fn();
126
+ const { getByText, getByRole } = render({
127
+ components: {
128
+ UiSheet,
129
+ UiSheetContent,
130
+ UiSheetDescription,
131
+ UiSheetHeader,
132
+ UiSheetTitle,
133
+ UiSheetTrigger,
134
+ },
135
+ setup() {
136
+ return { onEscapeKeyDown, onUpdateOpen };
137
+ },
138
+ template: `
139
+ <UiSheet @update:open="onUpdateOpen">
140
+ <UiSheetTrigger>Open</UiSheetTrigger>
141
+ <UiSheetContent @escape-key-down="onEscapeKeyDown">
142
+ <UiSheetHeader>
143
+ <UiSheetTitle>Title</UiSheetTitle>
144
+ <UiSheetDescription>Description</UiSheetDescription>
145
+ </UiSheetHeader>
146
+ Content
147
+ </UiSheetContent>
148
+ </UiSheet>
149
+ `,
150
+ });
151
+
152
+ await getByText('Open').click();
153
+ expect(getByRole('dialog')).toBeInTheDocument();
154
+
155
+ await getByRole('dialog').dispatchEvent(
156
+ new KeyboardEvent('keydown', { key: 'Escape', bubbles: true }),
157
+ );
158
+
159
+ expect(onEscapeKeyDown).toHaveBeenCalled();
160
+ expect(onUpdateOpen).toHaveBeenCalledWith(false);
161
+ });
162
+
163
+ test('forwards class to the underlying sheet content element', async () => {
164
+ const { getByText, getByRole } = render({
165
+ components: {
166
+ UiSheet,
167
+ UiSheetContent,
168
+ UiSheetDescription,
169
+ UiSheetHeader,
170
+ UiSheetTitle,
171
+ UiSheetTrigger,
172
+ },
173
+ template: `
174
+ <UiSheet>
175
+ <UiSheetTrigger>Open</UiSheetTrigger>
176
+ <UiSheetContent class="my-sheet-class">
177
+ <UiSheetHeader>
178
+ <UiSheetTitle>Title</UiSheetTitle>
179
+ <UiSheetDescription>Description</UiSheetDescription>
180
+ </UiSheetHeader>
181
+ Content
182
+ </UiSheetContent>
183
+ </UiSheet>
184
+ `,
185
+ });
186
+
187
+ await getByText('Open').click();
188
+ expect(getByRole('dialog')).toHaveClass('my-sheet-class');
189
+ });
190
+
191
+ test('supports controlled mode via v-model:open', async () => {
192
+ const { getByRole, getByText } = render({
193
+ components: {
194
+ UiSheet,
195
+ UiSheetContent,
196
+ UiSheetDescription,
197
+ UiSheetHeader,
198
+ UiSheetTitle,
199
+ UiSheetTrigger,
200
+ },
201
+ setup() {
202
+ const open = ref(false);
203
+ return { open };
204
+ },
205
+ template: `
206
+ <div>
207
+ <button type="button" @click="open = true">Open via model</button>
208
+ <button type="button" @click="open = false">Close via model</button>
209
+ <UiSheet v-model:open="open">
210
+ <UiSheetTrigger>Open</UiSheetTrigger>
211
+ <UiSheetContent>
212
+ <UiSheetHeader>
213
+ <UiSheetTitle>Title</UiSheetTitle>
214
+ <UiSheetDescription>Description</UiSheetDescription>
215
+ </UiSheetHeader>
216
+ Content
217
+ </UiSheetContent>
218
+ </UiSheet>
219
+ </div>
220
+ `,
221
+ });
222
+
223
+ await getByText('Open via model').click();
224
+ expect(getByRole('dialog')).toHaveAttribute('data-state', 'open');
225
+
226
+ await getByText('Close via model').click();
227
+ expect(getByRole('dialog')).toHaveAttribute('data-state', 'closed');
228
+ });
229
+ });
@@ -0,0 +1,12 @@
1
+ export {
2
+ Sheet as UiSheet,
3
+ SheetTrigger as UiSheetTrigger,
4
+ SheetContent as UiSheetContent,
5
+ SheetClose as UiSheetClose,
6
+ SheetHeader as UiSheetHeader,
7
+ SheetFooter as UiSheetFooter,
8
+ SheetTitle as UiSheetTitle,
9
+ SheetDescription as UiSheetDescription,
10
+ } from '@/components/core/sheet';
11
+
12
+ export type * from './types';
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Side of the screen where the sheet slides in from.
3
+ */
4
+ export type UiSheetSide = 'top' | 'right' | 'bottom' | 'left';
5
+
6
+ /**
7
+ * A panel that slides in from the edge of the screen to display
8
+ * supplementary content. Use for forms, filters, detail views, or
9
+ * any content that complements the main screen.
10
+ *
11
+ * @category Overlays
12
+ * @useCases side panel, filter panel, detail view, settings panel, form drawer
13
+ * @keywords sheet, drawer, panel, slide, overlay, side panel
14
+ * @related UiDrawer, UiAlertDialog
15
+ */
16
+ export interface UiSheetProps {
17
+ /**
18
+ * The controlled open state of the sheet.
19
+ * - Omit for uncontrolled mode (component manages state internally)
20
+ * - Use `v-model:open` for controlled mode
21
+ */
22
+ open?: boolean;
23
+
24
+ /**
25
+ * The open state of the sheet when it is initially rendered.
26
+ * Use when you do not need to control its open state.
27
+ * @default false
28
+ */
29
+ defaultOpen?: boolean;
30
+
31
+ /**
32
+ * The modality of the sheet.
33
+ * When set to `true`, interaction with outside elements will be disabled
34
+ * and only sheet content will be visible to screen readers.
35
+ * @default true
36
+ */
37
+ modal?: boolean;
38
+ }
39
+
40
+ /**
41
+ * Props for the UiSheetTrigger component.
42
+ * The element that opens the sheet when clicked.
43
+ */
44
+ export interface UiSheetTriggerProps {
45
+ /**
46
+ * Render as child element (merges props into slotted element instead of wrapping).
47
+ * Set to `true` when using custom button components like `UiButton` or `UiIconButton`.
48
+ * @default false
49
+ */
50
+ asChild?: boolean;
51
+ }
52
+
53
+ /**
54
+ * Props for the UiSheetContent component.
55
+ * The main content container for the sheet.
56
+ */
57
+ export interface UiSheetContentProps {
58
+ /**
59
+ * The side of the screen from which the sheet slides in.
60
+ * @default 'right'
61
+ */
62
+ side?: UiSheetSide;
63
+
64
+ /**
65
+ * Accessible label for the built-in close button (sr-only text).
66
+ * Override for i18n or to provide a more descriptive label.
67
+ * @default 'Close'
68
+ */
69
+ closeLabel?: string;
70
+ }
71
+
72
+ /**
73
+ * Props for the UiSheetClose component.
74
+ * A button that closes the sheet when clicked.
75
+ */
76
+ export interface UiSheetCloseProps {
77
+ /**
78
+ * Render as child element (merges props into slotted element instead of wrapping).
79
+ * Set to `true` when using a custom button for the close action.
80
+ * @default false
81
+ */
82
+ asChild?: boolean;
83
+ }