@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.
- package/README.md +1 -1
- package/config.js +34 -1
- package/dist/system/index.d.ts +1728 -234
- package/dist/system/lib.js +19804 -16600
- package/package.json +1 -1
- package/src/components/UiKbd/UiKbd.stories.ts +1 -1
- package/src/components/UiNavigationMenu/UiNavigationMenu.stories.ts +1196 -0
- package/src/components/UiNavigationMenu/UiNavigationMenu.vue +39 -0
- package/src/components/UiNavigationMenu/UiNavigationMenuContent.vue +25 -0
- package/src/components/UiNavigationMenu/UiNavigationMenuIndicator.vue +14 -0
- package/src/components/UiNavigationMenu/UiNavigationMenuItem.vue +16 -0
- package/src/components/UiNavigationMenu/UiNavigationMenuLink.vue +27 -0
- package/src/components/UiNavigationMenu/UiNavigationMenuList.vue +16 -0
- package/src/components/UiNavigationMenu/UiNavigationMenuTrigger.vue +16 -0
- package/src/components/UiNavigationMenu/__tests__/UiNavigationMenu.test.ts +428 -0
- package/src/components/UiNavigationMenu/index.ts +11 -0
- package/src/components/UiNavigationMenu/types.ts +185 -0
- package/src/components/UiSheet/UiSheet.stories.ts +715 -0
- package/src/components/UiSheet/__tests__/UiSheet.test.ts +229 -0
- package/src/components/UiSheet/index.ts +12 -0
- package/src/components/UiSheet/types.ts +83 -0
- package/src/components/UiSidebar/UiSidebar.stories.ts +1010 -0
- package/src/components/UiSidebar/UiSidebar.vue +20 -0
- package/src/components/UiSidebar/UiSidebarGroupAction.vue +18 -0
- package/src/components/UiSidebar/UiSidebarGroupLabel.vue +18 -0
- package/src/components/UiSidebar/UiSidebarHeaderTrigger.vue +53 -0
- package/src/components/UiSidebar/UiSidebarInput.vue +14 -0
- package/src/components/UiSidebar/UiSidebarMenuAction.vue +19 -0
- package/src/components/UiSidebar/UiSidebarMenuButton.vue +27 -0
- package/src/components/UiSidebar/UiSidebarMenuSkeleton.vue +16 -0
- package/src/components/UiSidebar/UiSidebarMenuSubButton.vue +24 -0
- package/src/components/UiSidebar/UiSidebarProvider.vue +18 -0
- package/src/components/UiSidebar/UiSidebarSeparator.vue +13 -0
- package/src/components/UiSidebar/__tests__/UiSidebar.test.ts +221 -0
- package/src/components/UiSidebar/index.ts +34 -0
- package/src/components/UiSidebar/types.ts +168 -0
- package/src/components/UiStepper/UiStepper.stories.ts +425 -0
- package/src/components/UiStepper/UiStepper.vue +27 -0
- package/src/components/UiStepper/UiStepperDescription.vue +20 -0
- package/src/components/UiStepper/UiStepperIndicator.vue +13 -0
- package/src/components/UiStepper/UiStepperItem.vue +25 -0
- package/src/components/UiStepper/UiStepperSeparator.vue +17 -0
- package/src/components/UiStepper/UiStepperTitle.vue +19 -0
- package/src/components/UiStepper/UiStepperTrigger.vue +18 -0
- package/src/components/UiStepper/__tests__/UiStepper.test.ts +167 -0
- package/src/components/UiStepper/index.ts +9 -0
- package/src/components/UiStepper/types.ts +65 -0
- package/src/components/core/alert/index.ts +2 -2
- package/src/components/core/alert-dialog/AlertDialogContent.vue +1 -1
- package/src/components/core/card/Card.vue +1 -1
- package/src/components/core/drawer/DrawerContent.vue +1 -1
- package/src/components/core/dropdown-menu/DropdownMenuContent.vue +1 -1
- package/src/components/core/dropdown-menu/DropdownMenuSubContent.vue +1 -1
- package/src/components/core/input/Input.vue +1 -1
- package/src/components/core/native-select/NativeSelect.vue +1 -1
- package/src/components/core/native-select/NativeSelectOptGroup.vue +1 -1
- package/src/components/core/native-select/NativeSelectOption.vue +1 -1
- package/src/components/core/navigation-menu/NavigationMenu.vue +40 -0
- package/src/components/core/navigation-menu/NavigationMenuContent.vue +28 -0
- package/src/components/core/navigation-menu/NavigationMenuIndicator.vue +26 -0
- package/src/components/core/navigation-menu/NavigationMenuItem.vue +19 -0
- package/src/components/core/navigation-menu/NavigationMenuLink.vue +27 -0
- package/src/components/core/navigation-menu/NavigationMenuList.vue +21 -0
- package/src/components/core/navigation-menu/NavigationMenuTrigger.vue +27 -0
- package/src/components/core/navigation-menu/NavigationMenuViewport.vue +26 -0
- package/src/components/core/navigation-menu/index.ts +14 -0
- package/src/components/core/popover/PopoverContent.vue +1 -1
- package/src/components/core/select/SelectContent.vue +1 -1
- package/src/components/core/select/SelectTrigger.vue +1 -1
- package/src/components/core/sheet/Sheet.vue +15 -0
- package/src/components/core/sheet/SheetClose.vue +12 -0
- package/src/components/core/sheet/SheetContent.vue +56 -0
- package/src/components/core/sheet/SheetDescription.vue +19 -0
- package/src/components/core/sheet/SheetFooter.vue +9 -0
- package/src/components/core/sheet/SheetHeader.vue +9 -0
- package/src/components/core/sheet/SheetOverlay.vue +24 -0
- package/src/components/core/sheet/SheetTitle.vue +19 -0
- package/src/components/core/sheet/SheetTrigger.vue +12 -0
- package/src/components/core/sheet/index.ts +8 -0
- package/src/components/core/sidebar/Sidebar.vue +105 -0
- package/src/components/core/sidebar/SidebarContent.vue +21 -0
- package/src/components/core/sidebar/SidebarFooter.vue +16 -0
- package/src/components/core/sidebar/SidebarGroup.vue +16 -0
- package/src/components/core/sidebar/SidebarGroupAction.vue +25 -0
- package/src/components/core/sidebar/SidebarGroupContent.vue +16 -0
- package/src/components/core/sidebar/SidebarGroupLabel.vue +23 -0
- package/src/components/core/sidebar/SidebarHeader.vue +16 -0
- package/src/components/core/sidebar/SidebarInput.vue +17 -0
- package/src/components/core/sidebar/SidebarInset.vue +21 -0
- package/src/components/core/sidebar/SidebarMenu.vue +16 -0
- package/src/components/core/sidebar/SidebarMenuAction.vue +33 -0
- package/src/components/core/sidebar/SidebarMenuBadge.vue +26 -0
- package/src/components/core/sidebar/SidebarMenuButton.vue +49 -0
- package/src/components/core/sidebar/SidebarMenuButtonChild.vue +36 -0
- package/src/components/core/sidebar/SidebarMenuItem.vue +16 -0
- package/src/components/core/sidebar/SidebarMenuSkeleton.vue +32 -0
- package/src/components/core/sidebar/SidebarMenuSub.vue +22 -0
- package/src/components/core/sidebar/SidebarMenuSubButton.vue +38 -0
- package/src/components/core/sidebar/SidebarMenuSubItem.vue +16 -0
- package/src/components/core/sidebar/SidebarProvider.vue +102 -0
- package/src/components/core/sidebar/SidebarRail.vue +33 -0
- package/src/components/core/sidebar/SidebarSeparator.vue +17 -0
- package/src/components/core/sidebar/SidebarTrigger.vue +25 -0
- package/src/components/core/sidebar/index.ts +58 -0
- package/src/components/core/sidebar/utils.ts +19 -0
- package/src/components/core/stepper/Stepper.vue +20 -0
- package/src/components/core/stepper/StepperDescription.vue +23 -0
- package/src/components/core/stepper/StepperIndicator.vue +34 -0
- package/src/components/core/stepper/StepperItem.vue +23 -0
- package/src/components/core/stepper/StepperSeparator.vue +29 -0
- package/src/components/core/stepper/StepperTitle.vue +24 -0
- package/src/components/core/stepper/StepperTrigger.vue +22 -0
- package/src/components/core/stepper/index.ts +7 -0
- package/src/components/core/tabs/TabsTrigger.vue +1 -1
- package/src/components/core/tags-input/TagsInput.vue +1 -1
- package/src/components/core/textarea/Textarea.vue +1 -1
- package/src/components/index.ts +4 -0
- package/src/theme/Background.stories.ts +84 -35
- package/src/theme/Extended.stories.ts +4 -4
- package/tokens.json +145 -8
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/vue3-vite';
|
|
2
|
+
import { ref, watch } from 'vue';
|
|
3
|
+
import {
|
|
4
|
+
UiStepper,
|
|
5
|
+
UiStepperItem,
|
|
6
|
+
UiStepperTrigger,
|
|
7
|
+
UiStepperIndicator,
|
|
8
|
+
UiStepperTitle,
|
|
9
|
+
UiStepperDescription,
|
|
10
|
+
UiStepperSeparator,
|
|
11
|
+
} from './index';
|
|
12
|
+
import { UiIcon } from '../UiIcon';
|
|
13
|
+
|
|
14
|
+
const meta: Meta<typeof UiStepper> = {
|
|
15
|
+
title: 'Primitives/UiStepper',
|
|
16
|
+
component: UiStepper,
|
|
17
|
+
tags: ['autodocs'],
|
|
18
|
+
argTypes: {
|
|
19
|
+
modelValue: {
|
|
20
|
+
control: 'number',
|
|
21
|
+
description: 'The controlled value of the active step (use with v-model)',
|
|
22
|
+
},
|
|
23
|
+
defaultValue: {
|
|
24
|
+
control: 'number',
|
|
25
|
+
},
|
|
26
|
+
orientation: {
|
|
27
|
+
control: 'select',
|
|
28
|
+
options: ['horizontal', 'vertical'],
|
|
29
|
+
},
|
|
30
|
+
linear: {
|
|
31
|
+
control: 'boolean',
|
|
32
|
+
description:
|
|
33
|
+
'Whether navigation must be sequential (user cannot skip ahead to incomplete steps)',
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
args: {
|
|
37
|
+
orientation: 'horizontal',
|
|
38
|
+
linear: true,
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export default meta;
|
|
43
|
+
|
|
44
|
+
type Story = StoryObj<typeof UiStepper>;
|
|
45
|
+
|
|
46
|
+
const defaultTemplateSource = `<script setup lang="ts">
|
|
47
|
+
import { ref } from 'vue'
|
|
48
|
+
import {
|
|
49
|
+
UiStepper,
|
|
50
|
+
UiStepperItem,
|
|
51
|
+
UiStepperTrigger,
|
|
52
|
+
UiStepperIndicator,
|
|
53
|
+
UiStepperTitle,
|
|
54
|
+
UiStepperDescription,
|
|
55
|
+
UiStepperSeparator,
|
|
56
|
+
UiIcon,
|
|
57
|
+
} from '@aleph-alpha/ui-library'
|
|
58
|
+
|
|
59
|
+
const currentStep = ref(1)
|
|
60
|
+
|
|
61
|
+
const steps = [
|
|
62
|
+
{ step: 1, title: 'Address', description: 'Add your address', icon: 'book-user' },
|
|
63
|
+
{ step: 2, title: 'Shipping', description: 'Set your preferred', icon: 'truck' },
|
|
64
|
+
{ step: 3, title: 'Payment', description: 'Add any payment', icon: 'credit-card' },
|
|
65
|
+
{ step: 4, title: 'Checkout', description: 'Confirm your order' },
|
|
66
|
+
]
|
|
67
|
+
</script>
|
|
68
|
+
|
|
69
|
+
<template>
|
|
70
|
+
<UiStepper v-model="currentStep" class="flex w-full items-start gap-2">
|
|
71
|
+
<UiStepperItem
|
|
72
|
+
v-for="item in steps"
|
|
73
|
+
:key="item.step"
|
|
74
|
+
:step="item.step"
|
|
75
|
+
class="relative flex w-full flex-col items-center justify-center"
|
|
76
|
+
>
|
|
77
|
+
<UiStepperTrigger>
|
|
78
|
+
<UiStepperIndicator class="">
|
|
79
|
+
<UiIcon v-if="item.icon" :name="item.icon" :size="16" />
|
|
80
|
+
<span v-else>{{ item.step }}</span>
|
|
81
|
+
</UiStepperIndicator>
|
|
82
|
+
</UiStepperTrigger>
|
|
83
|
+
<UiStepperSeparator
|
|
84
|
+
v-if="item.step !== steps[steps.length - 1]?.step"
|
|
85
|
+
/>
|
|
86
|
+
<div class="flex flex-col items-center">
|
|
87
|
+
<UiStepperTitle>{{ item.title }}</UiStepperTitle>
|
|
88
|
+
<UiStepperDescription>{{ item.description }}</UiStepperDescription>
|
|
89
|
+
</div>
|
|
90
|
+
</UiStepperItem>
|
|
91
|
+
</UiStepper>
|
|
92
|
+
</template>`;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Default stepper with icon indicators for each step. Steps without an icon
|
|
96
|
+
* fall back to displaying the step number. Use for multi-step workflows like
|
|
97
|
+
* checkout flows or onboarding sequences.
|
|
98
|
+
*/
|
|
99
|
+
export const Default: Story = {
|
|
100
|
+
render: (args) => ({
|
|
101
|
+
components: {
|
|
102
|
+
UiStepper,
|
|
103
|
+
UiStepperItem,
|
|
104
|
+
UiStepperTrigger,
|
|
105
|
+
UiStepperIndicator,
|
|
106
|
+
UiStepperTitle,
|
|
107
|
+
UiStepperDescription,
|
|
108
|
+
UiStepperSeparator,
|
|
109
|
+
UiIcon,
|
|
110
|
+
},
|
|
111
|
+
setup() {
|
|
112
|
+
const currentStep = ref(args.modelValue ?? 1);
|
|
113
|
+
watch(
|
|
114
|
+
() => args.modelValue,
|
|
115
|
+
(val) => {
|
|
116
|
+
if (val != null) currentStep.value = val;
|
|
117
|
+
},
|
|
118
|
+
);
|
|
119
|
+
const steps = [
|
|
120
|
+
{ step: 1, title: 'Address', description: 'Add your address', icon: 'book-user' },
|
|
121
|
+
{ step: 2, title: 'Shipping', description: 'Set your preferred', icon: 'truck' },
|
|
122
|
+
{ step: 3, title: 'Payment', description: 'Add any payment', icon: 'credit-card' },
|
|
123
|
+
{ step: 4, title: 'Checkout', description: 'Confirm your order' },
|
|
124
|
+
];
|
|
125
|
+
return { args, currentStep, steps };
|
|
126
|
+
},
|
|
127
|
+
template: `
|
|
128
|
+
<UiStepper
|
|
129
|
+
v-model="currentStep"
|
|
130
|
+
:orientation="args.orientation"
|
|
131
|
+
:linear="args.linear"
|
|
132
|
+
:class="args.orientation === 'vertical'
|
|
133
|
+
? 'mx-auto flex w-full max-w-md flex-col justify-start gap-10'
|
|
134
|
+
: 'flex w-full items-start gap-2'"
|
|
135
|
+
>
|
|
136
|
+
<UiStepperItem
|
|
137
|
+
v-for="item in steps"
|
|
138
|
+
:key="item.step"
|
|
139
|
+
:step="item.step"
|
|
140
|
+
:class="args.orientation === 'vertical'
|
|
141
|
+
? 'relative flex w-full items-start justify-start gap-6'
|
|
142
|
+
: 'relative flex w-full flex-col items-center justify-center'"
|
|
143
|
+
>
|
|
144
|
+
<UiStepperTrigger>
|
|
145
|
+
<UiStepperIndicator>
|
|
146
|
+
<UiIcon v-if="item.icon" :name="item.icon" :size="16" />
|
|
147
|
+
<span v-else>{{ item.step }}</span>
|
|
148
|
+
</UiStepperIndicator>
|
|
149
|
+
</UiStepperTrigger>
|
|
150
|
+
<UiStepperSeparator
|
|
151
|
+
v-if="item.step !== steps[steps.length - 1]?.step"
|
|
152
|
+
/>
|
|
153
|
+
<div :class="args.orientation === 'vertical' ? 'flex flex-col gap-1' : 'flex flex-col items-center'">
|
|
154
|
+
<UiStepperTitle>{{ item.title }}</UiStepperTitle>
|
|
155
|
+
<UiStepperDescription>{{ item.description }}</UiStepperDescription>
|
|
156
|
+
</div>
|
|
157
|
+
</UiStepperItem>
|
|
158
|
+
</UiStepper>
|
|
159
|
+
`,
|
|
160
|
+
}),
|
|
161
|
+
parameters: {
|
|
162
|
+
docs: {
|
|
163
|
+
source: {
|
|
164
|
+
code: defaultTemplateSource,
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
const horizontalTemplateSource = `<script setup lang="ts">
|
|
171
|
+
import { ref } from 'vue'
|
|
172
|
+
import {
|
|
173
|
+
UiStepper,
|
|
174
|
+
UiStepperItem,
|
|
175
|
+
UiStepperTrigger,
|
|
176
|
+
UiStepperIndicator,
|
|
177
|
+
UiStepperTitle,
|
|
178
|
+
UiStepperDescription,
|
|
179
|
+
UiStepperSeparator,
|
|
180
|
+
UiIcon,
|
|
181
|
+
} from '@aleph-alpha/ui-library'
|
|
182
|
+
|
|
183
|
+
const currentStep = ref(1)
|
|
184
|
+
|
|
185
|
+
const steps = [
|
|
186
|
+
{ step: 1, title: 'Your details', description: 'Provide your name and email' },
|
|
187
|
+
{ step: 2, title: 'Company details', description: 'A few details about your company' },
|
|
188
|
+
{ step: 3, title: 'Invite your team', description: 'Start collaborating with your team' },
|
|
189
|
+
]
|
|
190
|
+
</script>
|
|
191
|
+
|
|
192
|
+
<template>
|
|
193
|
+
<UiStepper v-model="currentStep" :linear="true" class="flex w-full items-start gap-2">
|
|
194
|
+
<UiStepperItem
|
|
195
|
+
v-for="step in steps"
|
|
196
|
+
:key="step.step"
|
|
197
|
+
v-slot="{ state }"
|
|
198
|
+
:step="step.step"
|
|
199
|
+
class="relative flex w-full flex-col items-center justify-center"
|
|
200
|
+
>
|
|
201
|
+
<UiStepperTrigger>
|
|
202
|
+
<UiStepperIndicator
|
|
203
|
+
:class="[
|
|
204
|
+
state === 'completed' && 'bg-[oklch(var(--background-accent-default))] group-data-[state=completed]:text-content-on-accent-default',
|
|
205
|
+
state === 'inactive' && 'bg-transparent border-2 border-content-on-surface-muted/30',
|
|
206
|
+
]"
|
|
207
|
+
>
|
|
208
|
+
<UiIcon v-if="state === 'completed'" name="check" class="size-5" />
|
|
209
|
+
<UiIcon v-if="state === 'active'" name="circle" class="size-4" />
|
|
210
|
+
<UiIcon v-if="state === 'inactive'" name="dot" class="size-4" />
|
|
211
|
+
</UiStepperIndicator>
|
|
212
|
+
</UiStepperTrigger>
|
|
213
|
+
<UiStepperSeparator
|
|
214
|
+
v-if="step.step !== steps[steps.length - 1]?.step"
|
|
215
|
+
/>
|
|
216
|
+
<div class="flex flex-col items-center text-center">
|
|
217
|
+
<UiStepperTitle>{{ step.title }}</UiStepperTitle>
|
|
218
|
+
<UiStepperDescription>{{ step.description }}</UiStepperDescription>
|
|
219
|
+
</div>
|
|
220
|
+
</UiStepperItem>
|
|
221
|
+
</UiStepper>
|
|
222
|
+
</template>`;
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Horizontal stepper with check/circle/dot icons. Completed and active steps
|
|
226
|
+
* show a filled blue indicator, inactive steps show an outlined circle.
|
|
227
|
+
*/
|
|
228
|
+
export const Horizontal: Story = {
|
|
229
|
+
render: () => ({
|
|
230
|
+
components: {
|
|
231
|
+
UiStepper,
|
|
232
|
+
UiStepperItem,
|
|
233
|
+
UiStepperTrigger,
|
|
234
|
+
UiStepperIndicator,
|
|
235
|
+
UiStepperTitle,
|
|
236
|
+
UiStepperDescription,
|
|
237
|
+
UiStepperSeparator,
|
|
238
|
+
UiIcon,
|
|
239
|
+
},
|
|
240
|
+
setup() {
|
|
241
|
+
const currentStep = ref(1);
|
|
242
|
+
const steps = [
|
|
243
|
+
{ step: 1, title: 'Your details', description: 'Provide your name and email' },
|
|
244
|
+
{
|
|
245
|
+
step: 2,
|
|
246
|
+
title: 'Company details',
|
|
247
|
+
description: 'A few details about your company',
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
step: 3,
|
|
251
|
+
title: 'Invite your team',
|
|
252
|
+
description: 'Start collaborating with your team',
|
|
253
|
+
},
|
|
254
|
+
];
|
|
255
|
+
return { currentStep, steps };
|
|
256
|
+
},
|
|
257
|
+
template: `
|
|
258
|
+
<UiStepper v-model="currentStep" :linear="true" class="flex w-full items-start gap-2">
|
|
259
|
+
<UiStepperItem
|
|
260
|
+
v-for="step in steps"
|
|
261
|
+
:key="step.step"
|
|
262
|
+
v-slot="{ state }"
|
|
263
|
+
:step="step.step"
|
|
264
|
+
class="relative flex w-full flex-col items-center justify-center"
|
|
265
|
+
>
|
|
266
|
+
<UiStepperTrigger>
|
|
267
|
+
<UiStepperIndicator
|
|
268
|
+
:class="[
|
|
269
|
+
state === 'completed' && 'bg-[oklch(var(--background-accent-default))] group-data-[state=completed]:text-content-on-accent-default',
|
|
270
|
+
state === 'inactive' && 'bg-transparent border-2 border-content-on-surface-muted/30',
|
|
271
|
+
]"
|
|
272
|
+
>
|
|
273
|
+
<UiIcon v-if="state === 'completed'" name="check" class="size-5" />
|
|
274
|
+
<UiIcon v-if="state === 'active'" name="circle" class="size-4" />
|
|
275
|
+
<UiIcon v-if="state === 'inactive'" name="dot" class="size-4" />
|
|
276
|
+
</UiStepperIndicator>
|
|
277
|
+
</UiStepperTrigger>
|
|
278
|
+
<UiStepperSeparator
|
|
279
|
+
v-if="step.step !== steps[steps.length - 1]?.step"
|
|
280
|
+
/>
|
|
281
|
+
<div class="flex flex-col items-center text-center">
|
|
282
|
+
<UiStepperTitle>{{ step.title }}</UiStepperTitle>
|
|
283
|
+
<UiStepperDescription>{{ step.description }}</UiStepperDescription>
|
|
284
|
+
</div>
|
|
285
|
+
</UiStepperItem>
|
|
286
|
+
</UiStepper>
|
|
287
|
+
`,
|
|
288
|
+
}),
|
|
289
|
+
parameters: {
|
|
290
|
+
docs: {
|
|
291
|
+
source: {
|
|
292
|
+
code: horizontalTemplateSource,
|
|
293
|
+
},
|
|
294
|
+
},
|
|
295
|
+
},
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
const verticalTemplateSource = `<script setup lang="ts">
|
|
299
|
+
import { ref } from 'vue'
|
|
300
|
+
import {
|
|
301
|
+
UiStepper,
|
|
302
|
+
UiStepperItem,
|
|
303
|
+
UiStepperTrigger,
|
|
304
|
+
UiStepperIndicator,
|
|
305
|
+
UiStepperTitle,
|
|
306
|
+
UiStepperDescription,
|
|
307
|
+
UiStepperSeparator,
|
|
308
|
+
UiIcon,
|
|
309
|
+
} from '@aleph-alpha/ui-library'
|
|
310
|
+
|
|
311
|
+
const currentStep = ref(1)
|
|
312
|
+
|
|
313
|
+
const steps = [
|
|
314
|
+
{ step: 1, title: 'Your details', description: 'Provide your name and email' },
|
|
315
|
+
{ step: 2, title: 'Company details', description: 'A few details about your company' },
|
|
316
|
+
{ step: 3, title: 'Invite your team', description: 'Start collaborating with your team' },
|
|
317
|
+
]
|
|
318
|
+
</script>
|
|
319
|
+
|
|
320
|
+
<template>
|
|
321
|
+
<UiStepper v-model="currentStep" orientation="vertical" :linear="true" class="mx-auto flex w-full max-w-md flex-col justify-start gap-10">
|
|
322
|
+
<UiStepperItem
|
|
323
|
+
v-for="step in steps"
|
|
324
|
+
:key="step.step"
|
|
325
|
+
v-slot="{ state }"
|
|
326
|
+
:step="step.step"
|
|
327
|
+
class="relative flex w-full items-start justify-start gap-6"
|
|
328
|
+
>
|
|
329
|
+
<UiStepperTrigger>
|
|
330
|
+
<UiStepperIndicator
|
|
331
|
+
:class="[
|
|
332
|
+
state === 'completed' && 'bg-[oklch(var(--background-accent-default))] group-data-[state=completed]:text-content-on-accent-default',
|
|
333
|
+
state === 'inactive' && 'bg-transparent border-2 border-content-on-surface-muted/30',
|
|
334
|
+
]"
|
|
335
|
+
>
|
|
336
|
+
<UiIcon v-if="state === 'completed'" name="check" class="size-5" />
|
|
337
|
+
<UiIcon v-if="state === 'active'" name="circle" class="size-4" />
|
|
338
|
+
<UiIcon v-if="state === 'inactive'" name="dot" class="size-4" />
|
|
339
|
+
</UiStepperIndicator>
|
|
340
|
+
</UiStepperTrigger>
|
|
341
|
+
<UiStepperSeparator
|
|
342
|
+
v-if="step.step !== steps[steps.length - 1]?.step"
|
|
343
|
+
/>
|
|
344
|
+
<div class="flex flex-col gap-1">
|
|
345
|
+
<UiStepperTitle>{{ step.title }}</UiStepperTitle>
|
|
346
|
+
<UiStepperDescription>{{ step.description }}</UiStepperDescription>
|
|
347
|
+
</div>
|
|
348
|
+
</UiStepperItem>
|
|
349
|
+
</UiStepper>
|
|
350
|
+
</template>`;
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* Vertical stepper with check/circle/dot icons. Uses the same indicator
|
|
354
|
+
* pattern as Horizontal but with vertical layout and connecting lines
|
|
355
|
+
* running top-to-bottom.
|
|
356
|
+
*/
|
|
357
|
+
export const Vertical: Story = {
|
|
358
|
+
render: () => ({
|
|
359
|
+
components: {
|
|
360
|
+
UiStepper,
|
|
361
|
+
UiStepperItem,
|
|
362
|
+
UiStepperTrigger,
|
|
363
|
+
UiStepperIndicator,
|
|
364
|
+
UiStepperTitle,
|
|
365
|
+
UiStepperDescription,
|
|
366
|
+
UiStepperSeparator,
|
|
367
|
+
UiIcon,
|
|
368
|
+
},
|
|
369
|
+
setup() {
|
|
370
|
+
const currentStep = ref(1);
|
|
371
|
+
const steps = [
|
|
372
|
+
{ step: 1, title: 'Your details', description: 'Provide your name and email' },
|
|
373
|
+
{
|
|
374
|
+
step: 2,
|
|
375
|
+
title: 'Company details',
|
|
376
|
+
description: 'A few details about your company',
|
|
377
|
+
},
|
|
378
|
+
{
|
|
379
|
+
step: 3,
|
|
380
|
+
title: 'Invite your team',
|
|
381
|
+
description: 'Start collaborating with your team',
|
|
382
|
+
},
|
|
383
|
+
];
|
|
384
|
+
return { currentStep, steps };
|
|
385
|
+
},
|
|
386
|
+
template: `
|
|
387
|
+
<UiStepper v-model="currentStep" orientation="vertical" :linear="true" class="mx-auto flex w-full max-w-md flex-col justify-start gap-10">
|
|
388
|
+
<UiStepperItem
|
|
389
|
+
v-for="step in steps"
|
|
390
|
+
:key="step.step"
|
|
391
|
+
v-slot="{ state }"
|
|
392
|
+
:step="step.step"
|
|
393
|
+
class="relative flex w-full items-start justify-start gap-6"
|
|
394
|
+
>
|
|
395
|
+
<UiStepperTrigger>
|
|
396
|
+
<UiStepperIndicator
|
|
397
|
+
:class="[
|
|
398
|
+
state === 'completed' && 'bg-[oklch(var(--background-accent-default))] group-data-[state=completed]:text-content-on-accent-default',
|
|
399
|
+
state === 'inactive' && 'bg-transparent border-2 border-content-on-surface-muted/30',
|
|
400
|
+
]"
|
|
401
|
+
>
|
|
402
|
+
<UiIcon v-if="state === 'completed'" name="check" class="size-5" />
|
|
403
|
+
<UiIcon v-if="state === 'active'" name="circle" class="size-4" />
|
|
404
|
+
<UiIcon v-if="state === 'inactive'" name="dot" class="size-4" />
|
|
405
|
+
</UiStepperIndicator>
|
|
406
|
+
</UiStepperTrigger>
|
|
407
|
+
<UiStepperSeparator
|
|
408
|
+
v-if="step.step !== steps[steps.length - 1]?.step"
|
|
409
|
+
/>
|
|
410
|
+
<div class="flex flex-col gap-1">
|
|
411
|
+
<UiStepperTitle>{{ step.title }}</UiStepperTitle>
|
|
412
|
+
<UiStepperDescription>{{ step.description }}</UiStepperDescription>
|
|
413
|
+
</div>
|
|
414
|
+
</UiStepperItem>
|
|
415
|
+
</UiStepper>
|
|
416
|
+
`,
|
|
417
|
+
}),
|
|
418
|
+
parameters: {
|
|
419
|
+
docs: {
|
|
420
|
+
source: {
|
|
421
|
+
code: verticalTemplateSource,
|
|
422
|
+
},
|
|
423
|
+
},
|
|
424
|
+
},
|
|
425
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { Stepper as ShadcnStepper } from '@/components/core/stepper';
|
|
3
|
+
import type { UiStepperProps } from './types';
|
|
4
|
+
|
|
5
|
+
defineOptions({
|
|
6
|
+
name: 'UiStepper',
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
defineProps<UiStepperProps>();
|
|
10
|
+
const model = defineModel<number>();
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<template>
|
|
14
|
+
<ShadcnStepper
|
|
15
|
+
#default="slotProps"
|
|
16
|
+
v-model="model"
|
|
17
|
+
:default-value="$props.defaultValue"
|
|
18
|
+
:orientation="$props.orientation"
|
|
19
|
+
:linear="$props.linear"
|
|
20
|
+
:class="[
|
|
21
|
+
'w-full items-start',
|
|
22
|
+
'data-[orientation=vertical]:flex-col data-[orientation=vertical]:gap-10',
|
|
23
|
+
]"
|
|
24
|
+
>
|
|
25
|
+
<slot v-bind="slotProps" />
|
|
26
|
+
</ShadcnStepper>
|
|
27
|
+
</template>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { StepperDescription as ShadcnStepperDescription } from '@/components/core/stepper';
|
|
3
|
+
|
|
4
|
+
defineOptions({
|
|
5
|
+
name: 'UiStepperDescription',
|
|
6
|
+
});
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<template>
|
|
10
|
+
<ShadcnStepperDescription
|
|
11
|
+
#default="slotProps"
|
|
12
|
+
:class="[
|
|
13
|
+
'transition-colors',
|
|
14
|
+
'group-data-[state=active]:text-content-on-surface-primary',
|
|
15
|
+
'group-data-[state=completed]:text-content-on-surface-primary',
|
|
16
|
+
]"
|
|
17
|
+
>
|
|
18
|
+
<slot v-bind="slotProps" />
|
|
19
|
+
</ShadcnStepperDescription>
|
|
20
|
+
</template>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { StepperIndicator as ShadcnStepperIndicator } from '@/components/core/stepper';
|
|
3
|
+
|
|
4
|
+
defineOptions({
|
|
5
|
+
name: 'UiStepperIndicator',
|
|
6
|
+
});
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<template>
|
|
10
|
+
<ShadcnStepperIndicator #default="slotProps" :class="['transition-colors']">
|
|
11
|
+
<slot v-bind="slotProps" />
|
|
12
|
+
</ShadcnStepperIndicator>
|
|
13
|
+
</template>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { StepperItem as ShadcnStepperItem } from '@/components/core/stepper';
|
|
3
|
+
import type { UiStepperItemProps } from './types';
|
|
4
|
+
|
|
5
|
+
defineOptions({
|
|
6
|
+
name: 'UiStepperItem',
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
const props = defineProps<UiStepperItemProps>();
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<template>
|
|
13
|
+
<ShadcnStepperItem
|
|
14
|
+
#default="slotProps"
|
|
15
|
+
:step="props.step"
|
|
16
|
+
:disabled="props.disabled"
|
|
17
|
+
:completed="props.completed"
|
|
18
|
+
:class="[
|
|
19
|
+
'relative w-full flex-col justify-center',
|
|
20
|
+
'data-[orientation=vertical]:flex-row data-[orientation=vertical]:items-start data-[orientation=vertical]:gap-6',
|
|
21
|
+
]"
|
|
22
|
+
>
|
|
23
|
+
<slot v-bind="slotProps" />
|
|
24
|
+
</ShadcnStepperItem>
|
|
25
|
+
</template>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { StepperSeparator as ShadcnStepperSeparator } from '@/components/core/stepper';
|
|
3
|
+
|
|
4
|
+
defineOptions({
|
|
5
|
+
name: 'UiStepperSeparator',
|
|
6
|
+
});
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<template>
|
|
10
|
+
<ShadcnStepperSeparator
|
|
11
|
+
:class="[
|
|
12
|
+
'absolute block shrink-0 rounded-full transition-colors',
|
|
13
|
+
'left-[calc(50%+24px)] right-[calc(-50%+16px)] top-[23px] h-0.5',
|
|
14
|
+
'group-data-[orientation=vertical]:left-[23px] group-data-[orientation=vertical]:top-[48px] group-data-[orientation=vertical]:bottom-[-40px] group-data-[orientation=vertical]:h-auto group-data-[orientation=vertical]:w-0.5 group-data-[orientation=vertical]:right-auto',
|
|
15
|
+
]"
|
|
16
|
+
/>
|
|
17
|
+
</template>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { StepperTitle as ShadcnStepperTitle } from '@/components/core/stepper';
|
|
3
|
+
|
|
4
|
+
defineOptions({
|
|
5
|
+
name: 'UiStepperTitle',
|
|
6
|
+
});
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<template>
|
|
10
|
+
<ShadcnStepperTitle
|
|
11
|
+
:class="[
|
|
12
|
+
'transition-colors',
|
|
13
|
+
'group-data-[state=active]:text-content-on-surface-primary',
|
|
14
|
+
'group-data-[state=completed]:text-content-on-surface-primary',
|
|
15
|
+
]"
|
|
16
|
+
>
|
|
17
|
+
<slot />
|
|
18
|
+
</ShadcnStepperTitle>
|
|
19
|
+
</template>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { StepperTrigger as ShadcnStepperTrigger } from '@/components/core/stepper';
|
|
3
|
+
import type { UiStepperTriggerProps } from './types';
|
|
4
|
+
|
|
5
|
+
defineOptions({
|
|
6
|
+
name: 'UiStepperTrigger',
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
const props = withDefaults(defineProps<UiStepperTriggerProps>(), {
|
|
10
|
+
asChild: false,
|
|
11
|
+
});
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<template>
|
|
15
|
+
<ShadcnStepperTrigger :as-child="props.asChild">
|
|
16
|
+
<slot />
|
|
17
|
+
</ShadcnStepperTrigger>
|
|
18
|
+
</template>
|