@polymarbot/nuxt-layer-shadcn-ui 0.1.10 → 0.2.0-w
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/app/assets/styles/colors.css +10 -10
- package/app/components/ui/Accordion/index.stories.ts +60 -56
- package/app/components/ui/Accordion/index.vue +1 -1
- package/app/components/ui/AdminLayout/SidebarMenus.vue +0 -2
- package/app/components/ui/AdminLayout/index.stories.ts +9 -8
- package/app/components/ui/Alert/index.stories.ts +28 -26
- package/app/components/ui/Alert/index.vue +6 -6
- package/app/components/ui/Alert/types.ts +2 -1
- package/app/components/ui/AlertDialog/index.stories.ts +85 -50
- package/app/components/ui/AsyncDataTable/index.stories.ts +53 -36
- package/app/components/ui/Avatar/index.stories.ts +56 -51
- package/app/components/ui/Avatar/index.vue +1 -1
- package/app/components/ui/Avatar/types.ts +5 -2
- package/app/components/ui/Badge/index.stories.ts +41 -41
- package/app/components/ui/Badge/index.vue +1 -1
- package/app/components/ui/Badge/types.ts +3 -1
- package/app/components/ui/Breadcrumb/index.stories.ts +48 -37
- package/app/components/ui/Breadcrumb/index.vue +1 -1
- package/app/components/ui/Button/index.stories.ts +94 -90
- package/app/components/ui/Button/index.vue +1 -1
- package/app/components/ui/Button/types.ts +4 -1
- package/app/components/ui/ButtonGroup/index.stories.ts +61 -49
- package/app/components/ui/Card/index.stories.ts +55 -47
- package/app/components/ui/Card/index.vue +1 -1
- package/app/components/ui/Checkbox/index.stories.ts +69 -46
- package/app/components/ui/Checkbox/index.vue +1 -1
- package/app/components/ui/CopyButton/index.stories.ts +89 -31
- package/app/components/ui/DataTable/index.stories.ts +218 -168
- package/app/components/ui/DataTable/index.vue +1 -1
- package/app/components/ui/DatePicker/index.stories.ts +131 -37
- package/app/components/ui/DateRangePicker/index.stories.ts +107 -33
- package/app/components/ui/Divider/index.stories.ts +46 -24
- package/app/components/ui/Divider/index.vue +1 -1
- package/app/components/ui/Drawer/index.stories.ts +131 -81
- package/app/components/ui/Drawer/index.vue +1 -1
- package/app/components/ui/Drawer/types.ts +1 -1
- package/app/components/ui/Dropdown/index.stories.ts +134 -89
- package/app/components/ui/Dropdown/index.vue +5 -1
- package/app/components/ui/Dropdown/types.ts +1 -1
- package/app/components/ui/FormItem/index.stories.ts +87 -43
- package/app/components/ui/FormItem/index.vue +1 -1
- package/app/components/ui/Help/index.stories.ts +46 -35
- package/app/components/ui/Icon/index.stories.ts +41 -43
- package/app/components/ui/Input/index.stories.ts +95 -41
- package/app/components/ui/Input/index.vue +1 -1
- package/app/components/ui/InputCurrency/index.stories.ts +89 -49
- package/app/components/ui/InputNumber/index.stories.ts +93 -29
- package/app/components/ui/InputNumber/index.vue +1 -1
- package/app/components/ui/InputOtp/index.stories.ts +6 -7
- package/app/components/ui/InputOtp/index.vue +1 -1
- package/app/components/ui/InputPercent/index.stories.ts +6 -7
- package/app/components/ui/InputRange/index.stories.ts +6 -7
- package/app/components/ui/Loading/index.stories.ts +19 -19
- package/app/components/ui/Markdown/index.stories.ts +7 -10
- package/app/components/ui/Modal/index.stories.ts +135 -80
- package/app/components/ui/Modal/index.vue +1 -1
- package/app/components/ui/Modal/types.ts +1 -1
- package/app/components/ui/ModalContent/index.stories.ts +54 -26
- package/app/components/ui/ModalContent/index.vue +2 -2
- package/app/components/ui/PageCard/index.stories.ts +177 -67
- package/app/components/ui/Pagination/index.stories.ts +68 -51
- package/app/components/ui/Pagination/index.vue +2 -2
- package/app/components/ui/Popover/index.stories.ts +47 -45
- package/app/components/ui/Popover/index.vue +1 -1
- package/app/components/ui/Qrcode/index.stories.ts +42 -34
- package/app/components/ui/RadioCardGroup/index.stories.ts +23 -32
- package/app/components/ui/RadioCardGroup/index.vue +1 -1
- package/app/components/ui/RadioGroup/index.stories.ts +123 -0
- package/app/components/ui/RadioGroup/index.vue +73 -0
- package/app/components/ui/RadioGroup/types.ts +13 -0
- package/app/components/ui/ScrollArea/index.stories.ts +69 -37
- package/app/components/ui/ScrollArea/index.vue +1 -1
- package/app/components/ui/SearchSelect/index.stories.ts +104 -66
- package/app/components/ui/Select/index.stories.ts +152 -98
- package/app/components/ui/Select/index.vue +3 -3
- package/app/components/ui/Skeleton/index.stories.ts +27 -30
- package/app/components/ui/Skeleton/index.vue +1 -1
- package/app/components/ui/Slider/index.stories.ts +73 -31
- package/app/components/ui/Slider/index.vue +1 -1
- package/app/components/ui/Surface/index.stories.ts +47 -21
- package/app/components/ui/Surface/index.vue +39 -28
- package/app/components/ui/Surface/types.ts +2 -2
- package/app/components/ui/Switch/index.stories.ts +6 -7
- package/app/components/ui/Switch/index.vue +1 -1
- package/app/components/ui/Tabs/index.stories.ts +103 -61
- package/app/components/ui/Tabs/index.vue +1 -1
- package/app/components/ui/Tag/index.stories.ts +42 -25
- package/app/components/ui/Tag/index.vue +39 -28
- package/app/components/ui/Tag/types.ts +2 -2
- package/app/components/ui/Textarea/index.stories.ts +73 -9
- package/app/components/ui/Textarea/index.vue +1 -1
- package/app/components/ui/Toast/index.stories.ts +71 -18
- package/app/components/ui/Toast/index.vue +1 -1
- package/app/components/ui/Tooltip/index.stories.ts +45 -38
- package/app/components/ui/Tooltip/index.vue +1 -1
- package/app/components/ui/WebLink/index.stories.ts +76 -41
- package/app/components/ui/WebLink/index.vue +1 -1
- package/package.json +2 -2
- package/app/components/ui/Radio/index.stories.ts +0 -71
- package/app/components/ui/Radio/index.vue +0 -10
- package/app/components/ui/Radio/types.ts +0 -3
|
@@ -3,74 +3,132 @@ import type { DropdownItem } from './types'
|
|
|
3
3
|
import Button from '../Button/index.vue'
|
|
4
4
|
import Dropdown from './index.vue'
|
|
5
5
|
|
|
6
|
+
const basicMenus: DropdownItem[] = [
|
|
7
|
+
{ label: 'Edit', icon: 'pencil' },
|
|
8
|
+
{ label: 'Duplicate', icon: 'copy' },
|
|
9
|
+
{ type: 'separator' },
|
|
10
|
+
{ label: 'Delete', icon: 'trash-2', color: 'danger' },
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
const accountMenus: DropdownItem[] = [
|
|
14
|
+
{ label: 'Profile', icon: 'user' },
|
|
15
|
+
{ label: 'Settings', icon: 'settings' },
|
|
16
|
+
{ label: 'Admin Panel', icon: 'shield', disabled: true },
|
|
17
|
+
{ type: 'separator' },
|
|
18
|
+
{ label: 'Logout', icon: 'log-out' },
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
const linkMenus: DropdownItem[] = [
|
|
22
|
+
{ label: 'Documentation', icon: 'book-open', href: 'https://example.com/docs', target: '_blank' },
|
|
23
|
+
{ label: 'Support', icon: 'life-buoy', href: 'https://example.com/support', target: '_blank' },
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
const groupedMenus: DropdownItem[] = [
|
|
27
|
+
{ type: 'label', label: 'Organization' },
|
|
28
|
+
{ label: 'Switch Org', icon: 'arrow-left-right' },
|
|
29
|
+
{ type: 'separator' },
|
|
30
|
+
{ type: 'label', label: 'Account' },
|
|
31
|
+
{ label: 'Profile', icon: 'user' },
|
|
32
|
+
{ label: 'Settings', icon: 'settings' },
|
|
33
|
+
{ type: 'separator' },
|
|
34
|
+
{ label: 'Logout', icon: 'log-out' },
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
const customMenus: DropdownItem[] = [
|
|
38
|
+
{
|
|
39
|
+
type: 'custom-label',
|
|
40
|
+
slot: 'profile',
|
|
41
|
+
title: 'Demo User',
|
|
42
|
+
email: 'demo@example.com',
|
|
43
|
+
},
|
|
44
|
+
{ type: 'separator' },
|
|
45
|
+
{ label: 'Profile', icon: 'user' },
|
|
46
|
+
{ label: 'Settings', icon: 'settings' },
|
|
47
|
+
{ type: 'separator' },
|
|
48
|
+
{
|
|
49
|
+
type: 'custom-action',
|
|
50
|
+
slot: 'logout',
|
|
51
|
+
command: () => alert('Logged out'),
|
|
52
|
+
},
|
|
53
|
+
]
|
|
54
|
+
|
|
6
55
|
const meta = {
|
|
7
56
|
title: 'UI/Dropdown',
|
|
8
57
|
component: Dropdown,
|
|
58
|
+
argTypes: {
|
|
59
|
+
menus: { control: 'object' },
|
|
60
|
+
trigger: { control: 'inline-radio', options: [ 'click', 'hover' ]},
|
|
61
|
+
side: { control: 'select', options: [ 'top', 'bottom', 'left', 'right' ]},
|
|
62
|
+
align: { control: 'select', options: [ 'start', 'center', 'end' ]},
|
|
63
|
+
sideOffset: { control: 'number' },
|
|
64
|
+
},
|
|
65
|
+
args: {
|
|
66
|
+
menus: basicMenus,
|
|
67
|
+
trigger: 'click',
|
|
68
|
+
side: undefined,
|
|
69
|
+
align: undefined,
|
|
70
|
+
sideOffset: undefined,
|
|
71
|
+
},
|
|
72
|
+
render: args => ({
|
|
73
|
+
components: { Dropdown, Button },
|
|
74
|
+
setup: () => ({ args }),
|
|
75
|
+
template: `
|
|
76
|
+
<Dropdown v-bind="args">
|
|
77
|
+
<Button variant="outline">Open Menu</Button>
|
|
78
|
+
</Dropdown>
|
|
79
|
+
`,
|
|
80
|
+
}),
|
|
9
81
|
} satisfies Meta<typeof Dropdown>
|
|
10
82
|
|
|
11
83
|
export default meta
|
|
12
84
|
type Story = StoryObj<typeof meta>
|
|
13
85
|
|
|
14
|
-
const
|
|
15
|
-
{ label: 'Edit', icon: 'pencil' },
|
|
16
|
-
{ label: 'Duplicate', icon: 'copy' },
|
|
17
|
-
{ type: 'separator' },
|
|
18
|
-
{ label: 'Delete', icon: 'trash-2', color: 'danger' },
|
|
19
|
-
]
|
|
86
|
+
export const Default: Story = {}
|
|
20
87
|
|
|
21
|
-
export const
|
|
88
|
+
export const HoverTrigger: Story = {
|
|
22
89
|
render: () => ({
|
|
23
90
|
components: { Dropdown, Button },
|
|
24
|
-
setup () {
|
|
25
|
-
const menus: DropdownItem[] = [
|
|
26
|
-
{ label: 'Profile', icon: 'user' },
|
|
27
|
-
{ label: 'Settings', icon: 'settings' },
|
|
28
|
-
{ label: 'Admin Panel', icon: 'shield', disabled: true },
|
|
29
|
-
{ type: 'separator' },
|
|
30
|
-
{ label: 'Logout', icon: 'log-out' },
|
|
31
|
-
]
|
|
32
|
-
|
|
33
|
-
const linkMenus: DropdownItem[] = [
|
|
34
|
-
{ label: 'Documentation', icon: 'book-open', href: 'https://example.com/docs', target: '_blank' },
|
|
35
|
-
{ label: 'Support', icon: 'life-buoy', href: 'https://example.com/support', target: '_blank' },
|
|
36
|
-
]
|
|
37
|
-
|
|
38
|
-
return { basicMenus, menus, linkMenus }
|
|
39
|
-
},
|
|
91
|
+
setup: () => ({ basicMenus }),
|
|
40
92
|
template: `
|
|
41
|
-
<
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
</Dropdown>
|
|
48
|
-
</section>
|
|
93
|
+
<Dropdown :menus="basicMenus" trigger="hover">
|
|
94
|
+
<Button variant="outline">Hover me</Button>
|
|
95
|
+
</Dropdown>
|
|
96
|
+
`,
|
|
97
|
+
}),
|
|
98
|
+
}
|
|
49
99
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
</
|
|
100
|
+
export const ClickTrigger: Story = {
|
|
101
|
+
render: () => ({
|
|
102
|
+
components: { Dropdown, Button },
|
|
103
|
+
setup: () => ({ basicMenus }),
|
|
104
|
+
template: `
|
|
105
|
+
<Dropdown :menus="basicMenus" trigger="click">
|
|
106
|
+
<Button variant="outline">Click me</Button>
|
|
107
|
+
</Dropdown>
|
|
108
|
+
`,
|
|
109
|
+
}),
|
|
110
|
+
}
|
|
57
111
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
</
|
|
112
|
+
export const WithDisabledItems: Story = {
|
|
113
|
+
render: () => ({
|
|
114
|
+
components: { Dropdown, Button },
|
|
115
|
+
setup: () => ({ accountMenus }),
|
|
116
|
+
template: `
|
|
117
|
+
<Dropdown :menus="accountMenus" trigger="click">
|
|
118
|
+
<Button variant="outline">Account</Button>
|
|
119
|
+
</Dropdown>
|
|
120
|
+
`,
|
|
121
|
+
}),
|
|
122
|
+
}
|
|
65
123
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
</
|
|
73
|
-
</
|
|
124
|
+
export const WithLinks: Story = {
|
|
125
|
+
render: () => ({
|
|
126
|
+
components: { Dropdown, Button },
|
|
127
|
+
setup: () => ({ linkMenus }),
|
|
128
|
+
template: `
|
|
129
|
+
<Dropdown :menus="linkMenus" trigger="click">
|
|
130
|
+
<Button variant="outline">Resources</Button>
|
|
131
|
+
</Dropdown>
|
|
74
132
|
`,
|
|
75
133
|
}),
|
|
76
134
|
}
|
|
@@ -78,20 +136,7 @@ export const Default: Story = {
|
|
|
78
136
|
export const WithGroups: Story = {
|
|
79
137
|
render: () => ({
|
|
80
138
|
components: { Dropdown, Button },
|
|
81
|
-
setup () {
|
|
82
|
-
const groupedMenus: DropdownItem[] = [
|
|
83
|
-
{ type: 'label', label: 'Organization' },
|
|
84
|
-
{ label: 'Switch Org', icon: 'arrow-left-right' },
|
|
85
|
-
{ type: 'separator' },
|
|
86
|
-
{ type: 'label', label: 'Account' },
|
|
87
|
-
{ label: 'Profile', icon: 'user' },
|
|
88
|
-
{ label: 'Settings', icon: 'settings' },
|
|
89
|
-
{ type: 'separator' },
|
|
90
|
-
{ label: 'Logout', icon: 'log-out' },
|
|
91
|
-
]
|
|
92
|
-
|
|
93
|
-
return { groupedMenus }
|
|
94
|
-
},
|
|
139
|
+
setup: () => ({ groupedMenus }),
|
|
95
140
|
template: `
|
|
96
141
|
<Dropdown :menus="groupedMenus" trigger="click">
|
|
97
142
|
<Button variant="outline">Menu with Groups</Button>
|
|
@@ -100,30 +145,10 @@ export const WithGroups: Story = {
|
|
|
100
145
|
}),
|
|
101
146
|
}
|
|
102
147
|
|
|
103
|
-
export const
|
|
148
|
+
export const CustomSlots: Story = {
|
|
104
149
|
render: () => ({
|
|
105
150
|
components: { Dropdown, Button },
|
|
106
|
-
setup () {
|
|
107
|
-
const customMenus: DropdownItem[] = [
|
|
108
|
-
{
|
|
109
|
-
type: 'custom-label',
|
|
110
|
-
slot: 'profile',
|
|
111
|
-
title: 'Demo User',
|
|
112
|
-
email: 'demo@example.com',
|
|
113
|
-
},
|
|
114
|
-
{ type: 'separator' },
|
|
115
|
-
{ label: 'Profile', icon: 'user' },
|
|
116
|
-
{ label: 'Settings', icon: 'settings' },
|
|
117
|
-
{ type: 'separator' },
|
|
118
|
-
{
|
|
119
|
-
type: 'custom-action',
|
|
120
|
-
slot: 'logout',
|
|
121
|
-
command: () => alert('Logged out'),
|
|
122
|
-
},
|
|
123
|
-
]
|
|
124
|
-
|
|
125
|
-
return { customMenus }
|
|
126
|
-
},
|
|
151
|
+
setup: () => ({ customMenus }),
|
|
127
152
|
template: `
|
|
128
153
|
<Dropdown :menus="customMenus" trigger="click">
|
|
129
154
|
<Button variant="outline">Custom Slots</Button>
|
|
@@ -143,3 +168,23 @@ export const WithCustomSlots: Story = {
|
|
|
143
168
|
`,
|
|
144
169
|
}),
|
|
145
170
|
}
|
|
171
|
+
|
|
172
|
+
export const PopupSlot: Story = {
|
|
173
|
+
render: () => ({
|
|
174
|
+
components: { Dropdown, Button },
|
|
175
|
+
template: `
|
|
176
|
+
<Dropdown trigger="click">
|
|
177
|
+
<Button variant="outline">Custom Popup</Button>
|
|
178
|
+
<template #popup="{ hide }">
|
|
179
|
+
<div class="flex flex-col gap-2 p-3 min-w-[220px]">
|
|
180
|
+
<div class="text-sm font-semibold">Custom content</div>
|
|
181
|
+
<p class="text-sm text-muted-foreground">
|
|
182
|
+
Use the <code>popup</code> slot to render arbitrary content inside the menu.
|
|
183
|
+
</p>
|
|
184
|
+
<Button size="sm" @click="hide">Close</Button>
|
|
185
|
+
</div>
|
|
186
|
+
</template>
|
|
187
|
+
</Dropdown>
|
|
188
|
+
`,
|
|
189
|
+
}),
|
|
190
|
+
}
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
DropdownMenuLabel,
|
|
7
7
|
DropdownMenuSeparator,
|
|
8
8
|
DropdownMenuTrigger,
|
|
9
|
-
} from '
|
|
9
|
+
} from '../../shadcn/dropdown-menu'
|
|
10
10
|
import { cva } from 'class-variance-authority'
|
|
11
11
|
import type {
|
|
12
12
|
DropdownActionItem,
|
|
@@ -18,6 +18,10 @@ const actionColorVariants = cva('', {
|
|
|
18
18
|
variants: {
|
|
19
19
|
color: {
|
|
20
20
|
default: '',
|
|
21
|
+
primary: `
|
|
22
|
+
text-primary
|
|
23
|
+
focus:bg-primary/10 focus:text-primary
|
|
24
|
+
`,
|
|
21
25
|
success: `
|
|
22
26
|
text-success
|
|
23
27
|
focus:bg-success/10 focus:text-success
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Component } from 'vue'
|
|
2
2
|
|
|
3
|
-
export type DropdownItemColor = 'default' | 'success' | 'info' | 'help' | 'warn' | 'danger'
|
|
3
|
+
export type DropdownItemColor = 'default' | 'primary' | 'success' | 'info' | 'help' | 'warn' | 'danger'
|
|
4
4
|
|
|
5
5
|
export interface DropdownActionItem {
|
|
6
6
|
/** Defaults to 'action' when omitted. */
|
|
@@ -2,68 +2,112 @@ import type { Meta, StoryObj } from '@storybook/vue3'
|
|
|
2
2
|
import Input from '../Input/index.vue'
|
|
3
3
|
import FormItem from './index.vue'
|
|
4
4
|
|
|
5
|
+
const orientations = [ 'vertical', 'horizontal', 'responsive' ] as const
|
|
6
|
+
|
|
5
7
|
const meta = {
|
|
6
8
|
title: 'UI/FormItem',
|
|
7
9
|
component: FormItem,
|
|
10
|
+
argTypes: {
|
|
11
|
+
label: { control: 'text' },
|
|
12
|
+
error: { control: 'text' },
|
|
13
|
+
description: { control: 'text' },
|
|
14
|
+
required: { control: 'boolean' },
|
|
15
|
+
orientation: { control: 'select', options: orientations },
|
|
16
|
+
class: { control: 'text' },
|
|
17
|
+
},
|
|
18
|
+
args: {
|
|
19
|
+
label: 'Name',
|
|
20
|
+
error: '',
|
|
21
|
+
description: '',
|
|
22
|
+
required: false,
|
|
23
|
+
orientation: 'vertical',
|
|
24
|
+
class: '',
|
|
25
|
+
},
|
|
26
|
+
render: args => ({
|
|
27
|
+
components: { FormItem, Input },
|
|
28
|
+
setup: () => ({ args }),
|
|
29
|
+
template: `
|
|
30
|
+
<div class="max-w-md">
|
|
31
|
+
<FormItem v-bind="args">
|
|
32
|
+
<Input placeholder="Enter value" />
|
|
33
|
+
</FormItem>
|
|
34
|
+
</div>
|
|
35
|
+
`,
|
|
36
|
+
}),
|
|
8
37
|
} satisfies Meta<typeof FormItem>
|
|
9
38
|
|
|
10
39
|
export default meta
|
|
11
40
|
type Story = StoryObj<typeof meta>
|
|
12
41
|
|
|
13
|
-
export const Default: Story = {
|
|
42
|
+
export const Default: Story = {}
|
|
43
|
+
|
|
44
|
+
export const Required: Story = {
|
|
14
45
|
render: () => ({
|
|
15
46
|
components: { FormItem, Input },
|
|
16
47
|
setup () {
|
|
17
|
-
const name = ref('')
|
|
18
48
|
const email = ref('')
|
|
19
|
-
return {
|
|
49
|
+
return { email }
|
|
20
50
|
},
|
|
21
51
|
template: `
|
|
22
|
-
<div class="
|
|
23
|
-
<
|
|
24
|
-
<
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
52
|
+
<div class="max-w-md">
|
|
53
|
+
<FormItem label="Email" required>
|
|
54
|
+
<Input v-model="email" placeholder="Enter your email" />
|
|
55
|
+
</FormItem>
|
|
56
|
+
</div>
|
|
57
|
+
`,
|
|
58
|
+
}),
|
|
59
|
+
}
|
|
29
60
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
61
|
+
export const WithError: Story = {
|
|
62
|
+
render: () => ({
|
|
63
|
+
components: { FormItem, Input },
|
|
64
|
+
template: `
|
|
65
|
+
<div class="max-w-md">
|
|
66
|
+
<FormItem label="Username" required error="Username is already taken">
|
|
67
|
+
<Input model-value="admin" />
|
|
68
|
+
</FormItem>
|
|
69
|
+
</div>
|
|
70
|
+
`,
|
|
71
|
+
}),
|
|
72
|
+
}
|
|
36
73
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
74
|
+
export const WithDescription: Story = {
|
|
75
|
+
render: () => ({
|
|
76
|
+
components: { FormItem, Input },
|
|
77
|
+
template: `
|
|
78
|
+
<div class="max-w-md">
|
|
79
|
+
<FormItem label="Password" description="Must be at least 8 characters long">
|
|
80
|
+
<Input type="password" placeholder="Enter password" />
|
|
81
|
+
</FormItem>
|
|
82
|
+
</div>
|
|
83
|
+
`,
|
|
84
|
+
}),
|
|
85
|
+
}
|
|
43
86
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
87
|
+
export const Horizontal: Story = {
|
|
88
|
+
render: () => ({
|
|
89
|
+
components: { FormItem, Input },
|
|
90
|
+
template: `
|
|
91
|
+
<div class="max-w-md">
|
|
92
|
+
<FormItem label="Display Name" orientation="horizontal">
|
|
93
|
+
<Input placeholder="Enter display name" />
|
|
94
|
+
</FormItem>
|
|
95
|
+
</div>
|
|
96
|
+
`,
|
|
97
|
+
}),
|
|
98
|
+
}
|
|
50
99
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
100
|
+
export const Responsive: Story = {
|
|
101
|
+
render: () => ({
|
|
102
|
+
components: { FormItem, Input },
|
|
103
|
+
template: `
|
|
104
|
+
<div class="max-w-md">
|
|
105
|
+
<div class="@container/field-group resize-x overflow-auto rounded border border-dashed border-border bg-card p-4" style="min-width: 200px;">
|
|
106
|
+
<FormItem label="Address" orientation="responsive" description="Your mailing address">
|
|
107
|
+
<Input placeholder="Enter address" />
|
|
55
108
|
</FormItem>
|
|
56
|
-
</
|
|
57
|
-
|
|
58
|
-
<section>
|
|
59
|
-
<h3 class="mb-4 text-lg font-medium">Responsive Orientation</h3>
|
|
60
|
-
<p class="mb-2 text-sm text-muted-foreground">Drag the right edge to resize ↔</p>
|
|
61
|
-
<div class="@container/field-group resize-x overflow-auto rounded border border-dashed border-border bg-card p-4" style="min-width: 200px;">
|
|
62
|
-
<FormItem label="Address" orientation="responsive" description="Your mailing address">
|
|
63
|
-
<Input placeholder="Enter address" />
|
|
64
|
-
</FormItem>
|
|
65
|
-
</div>
|
|
66
|
-
</section>
|
|
109
|
+
</div>
|
|
110
|
+
<p class="mt-2 text-sm text-muted-foreground">Drag the right edge to resize horizontally.</p>
|
|
67
111
|
</div>
|
|
68
112
|
`,
|
|
69
113
|
}),
|
|
@@ -1,53 +1,64 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from '@storybook/vue3'
|
|
2
2
|
import Help from './index.vue'
|
|
3
3
|
|
|
4
|
+
const positions = [ 'top', 'bottom', 'left', 'right' ] as const
|
|
5
|
+
|
|
4
6
|
const meta = {
|
|
5
7
|
title: 'UI/Help',
|
|
6
8
|
component: Help,
|
|
9
|
+
argTypes: {
|
|
10
|
+
text: { control: 'text' },
|
|
11
|
+
position: { control: 'select', options: positions },
|
|
12
|
+
},
|
|
13
|
+
args: {
|
|
14
|
+
text: 'This is a helpful tooltip',
|
|
15
|
+
position: 'top',
|
|
16
|
+
},
|
|
17
|
+
render: args => ({
|
|
18
|
+
components: { Help },
|
|
19
|
+
setup: () => ({ args }),
|
|
20
|
+
template: '<Help v-bind="args" />',
|
|
21
|
+
}),
|
|
7
22
|
} satisfies Meta<typeof Help>
|
|
8
23
|
|
|
9
24
|
export default meta
|
|
10
25
|
type Story = StoryObj<typeof meta>
|
|
11
26
|
|
|
12
|
-
export const Default: Story = {
|
|
27
|
+
export const Default: Story = {}
|
|
28
|
+
|
|
29
|
+
export const Positions: Story = {
|
|
13
30
|
render: () => ({
|
|
14
31
|
components: { Help },
|
|
15
32
|
template: `
|
|
16
|
-
<div class="
|
|
17
|
-
<
|
|
18
|
-
<
|
|
19
|
-
<
|
|
20
|
-
</
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
<
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
<div class="flex flex-col items-center gap-2">
|
|
38
|
-
<Help text="Right tooltip" position="right" />
|
|
39
|
-
<span class="text-sm text-muted-foreground">Right</span>
|
|
40
|
-
</div>
|
|
41
|
-
</div>
|
|
42
|
-
</section>
|
|
33
|
+
<div class="flex items-center gap-8 py-10 justify-center">
|
|
34
|
+
<div class="flex flex-col items-center gap-2">
|
|
35
|
+
<Help text="Top tooltip" position="top" />
|
|
36
|
+
<span class="text-sm text-muted-foreground">Top</span>
|
|
37
|
+
</div>
|
|
38
|
+
<div class="flex flex-col items-center gap-2">
|
|
39
|
+
<Help text="Bottom tooltip" position="bottom" />
|
|
40
|
+
<span class="text-sm text-muted-foreground">Bottom</span>
|
|
41
|
+
</div>
|
|
42
|
+
<div class="flex flex-col items-center gap-2">
|
|
43
|
+
<Help text="Left tooltip" position="left" />
|
|
44
|
+
<span class="text-sm text-muted-foreground">Left</span>
|
|
45
|
+
</div>
|
|
46
|
+
<div class="flex flex-col items-center gap-2">
|
|
47
|
+
<Help text="Right tooltip" position="right" />
|
|
48
|
+
<span class="text-sm text-muted-foreground">Right</span>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
`,
|
|
52
|
+
}),
|
|
53
|
+
}
|
|
43
54
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
55
|
+
export const InlineWithLabel: Story = {
|
|
56
|
+
render: () => ({
|
|
57
|
+
components: { Help },
|
|
58
|
+
template: `
|
|
59
|
+
<div class="flex items-center gap-1">
|
|
60
|
+
<span class="text-sm font-medium">API Key</span>
|
|
61
|
+
<Help text="Your unique API key for authentication" />
|
|
51
62
|
</div>
|
|
52
63
|
`,
|
|
53
64
|
}),
|