@polymarbot/nuxt-layer-shadcn-ui 0.3.9 → 0.4.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/app/components/ui/Accordion/index.stories.ts +43 -15
- package/app/components/ui/AdminLayout/index.stories.ts +6 -14
- package/app/components/ui/Alert/index.stories.ts +32 -2
- package/app/components/ui/AlertDialog/index.stories.ts +114 -5
- package/app/components/ui/AsyncDataTable/index.stories.ts +36 -2
- package/app/components/ui/Avatar/index.stories.ts +58 -4
- package/app/components/ui/Badge/index.stories.ts +48 -3
- package/app/components/ui/Breadcrumb/index.stories.ts +8 -19
- package/app/components/ui/Button/index.stories.ts +116 -7
- package/app/components/ui/ButtonGroup/index.stories.ts +63 -4
- package/app/components/ui/Card/index.stories.ts +40 -14
- package/app/components/ui/Checkbox/index.stories.ts +53 -3
- package/app/components/ui/CopyButton/index.stories.ts +77 -5
- package/app/components/ui/DataTable/index.stories.ts +184 -11
- package/app/components/ui/DatePicker/index.stories.ts +56 -7
- package/app/components/ui/DateRangePicker/index.stories.ts +40 -5
- package/app/components/ui/Divider/index.stories.ts +18 -15
- package/app/components/ui/Drawer/index.stories.ts +115 -16
- package/app/components/ui/Drawer/index.vue +27 -12
- package/app/components/ui/Dropdown/index.stories.ts +72 -54
- package/app/components/ui/Dropdown/index.vue +5 -8
- package/app/components/ui/Dropdown/types.ts +3 -8
- package/app/components/ui/FormItem/index.stories.ts +33 -45
- package/app/components/ui/Help/index.stories.ts +34 -2
- package/app/components/ui/Icon/index.stories.ts +41 -2
- package/app/components/ui/Input/index.stories.ts +73 -31
- package/app/components/ui/Input/index.vue +1 -0
- package/app/components/ui/InputCurrency/index.stories.ts +20 -65
- package/app/components/ui/InputNumber/index.stories.ts +31 -58
- package/app/components/ui/InputOtp/index.stories.ts +41 -9
- package/app/components/ui/InputPercent/index.stories.ts +3 -7
- package/app/components/ui/InputRange/index.stories.ts +51 -4
- package/app/components/ui/Loading/index.stories.ts +16 -1
- package/app/components/ui/Markdown/index.stories.ts +9 -0
- package/app/components/ui/Modal/index.stories.ts +133 -16
- package/app/components/ui/Modal/index.vue +27 -12
- package/app/components/ui/ModalContent/index.stories.ts +35 -11
- package/app/components/ui/PageCard/index.stories.ts +154 -56
- package/app/components/ui/Pagination/index.stories.ts +75 -41
- package/app/components/ui/Pagination/index.vue +4 -1
- package/app/components/ui/Popover/index.stories.ts +73 -27
- package/app/components/ui/Popover/index.vue +67 -4
- package/app/components/ui/Popover/types.ts +5 -2
- package/app/components/ui/Qrcode/index.stories.ts +32 -2
- package/app/components/ui/RadioCardGroup/index.stories.ts +45 -6
- package/app/components/ui/RadioGroup/index.stories.ts +64 -52
- package/app/components/ui/ScrollArea/index.stories.ts +21 -23
- package/app/components/ui/SearchSelect/index.stories.ts +73 -24
- package/app/components/ui/Select/index.stories.ts +121 -6
- package/app/components/ui/Select/index.vue +7 -6
- package/app/components/ui/Skeleton/index.stories.ts +34 -2
- package/app/components/ui/Slider/index.stories.ts +67 -4
- package/app/components/ui/Surface/index.stories.ts +86 -5
- package/app/components/ui/Surface/index.vue +115 -2
- package/app/components/ui/Surface/types.ts +2 -0
- package/app/components/ui/Switch/index.stories.ts +46 -0
- package/app/components/ui/Tabs/index.stories.ts +61 -64
- package/app/components/ui/Tag/index.stories.ts +45 -3
- package/app/components/ui/Textarea/index.stories.ts +61 -32
- package/app/components/ui/Toast/index.stories.ts +77 -3
- package/app/components/ui/Tooltip/index.stories.ts +60 -2
- package/app/components/ui/WebLink/index.stories.ts +53 -15
- package/package.json +2 -2
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
SheetFooter,
|
|
8
8
|
SheetHeader,
|
|
9
9
|
SheetTitle,
|
|
10
|
+
SheetTrigger,
|
|
10
11
|
} from '../../shadcn/sheet'
|
|
11
12
|
import type { DrawerProps } from './types'
|
|
12
13
|
|
|
@@ -41,28 +42,32 @@ const resolvedCancelText = computed(
|
|
|
41
42
|
() => props.cancelText || t('common.actions.cancel'),
|
|
42
43
|
)
|
|
43
44
|
|
|
44
|
-
const sheetOpen =
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
onCancel()
|
|
49
|
-
}
|
|
50
|
-
},
|
|
45
|
+
const sheetOpen = ref(props.visible ?? false)
|
|
46
|
+
|
|
47
|
+
watch(() => props.visible, value => {
|
|
48
|
+
if (value !== undefined) sheetOpen.value = value
|
|
51
49
|
})
|
|
52
50
|
|
|
53
|
-
watch(
|
|
54
|
-
|
|
51
|
+
watch(sheetOpen, value => {
|
|
52
|
+
emit('update:visible', value)
|
|
53
|
+
if (value) emit('open')
|
|
55
54
|
else emit('close')
|
|
56
55
|
})
|
|
57
56
|
|
|
57
|
+
function onOpenUpdate (value: boolean) {
|
|
58
|
+
if (!value && props.loading) return
|
|
59
|
+
if (value) sheetOpen.value = true
|
|
60
|
+
else onCancel()
|
|
61
|
+
}
|
|
62
|
+
|
|
58
63
|
function onConfirm () {
|
|
59
64
|
emit('confirm')
|
|
60
|
-
|
|
65
|
+
sheetOpen.value = false
|
|
61
66
|
}
|
|
62
67
|
|
|
63
68
|
function onCancel () {
|
|
64
69
|
emit('cancel')
|
|
65
|
-
|
|
70
|
+
sheetOpen.value = false
|
|
66
71
|
}
|
|
67
72
|
|
|
68
73
|
function onPointerDownOutside (event: Event) {
|
|
@@ -75,7 +80,17 @@ const contentClass = computed(() =>
|
|
|
75
80
|
</script>
|
|
76
81
|
|
|
77
82
|
<template>
|
|
78
|
-
<Sheet
|
|
83
|
+
<Sheet
|
|
84
|
+
:open="sheetOpen"
|
|
85
|
+
@update:open="onOpenUpdate"
|
|
86
|
+
>
|
|
87
|
+
<SheetTrigger
|
|
88
|
+
v-if="$slots.trigger"
|
|
89
|
+
asChild
|
|
90
|
+
>
|
|
91
|
+
<slot name="trigger" />
|
|
92
|
+
</SheetTrigger>
|
|
93
|
+
|
|
79
94
|
<SheetContent
|
|
80
95
|
:side="side"
|
|
81
96
|
:class="contentClass"
|
|
@@ -3,6 +3,10 @@ import type { DropdownItem } from './types'
|
|
|
3
3
|
import Button from '../Button/index.vue'
|
|
4
4
|
import Dropdown from './index.vue'
|
|
5
5
|
|
|
6
|
+
const triggers = [ 'click', 'hover' ] as const
|
|
7
|
+
const sides = [ 'top', 'bottom', 'left', 'right' ] as const
|
|
8
|
+
const aligns = [ 'start', 'center', 'end' ] as const
|
|
9
|
+
|
|
6
10
|
const basicMenus: DropdownItem[] = [
|
|
7
11
|
{ label: 'Edit', icon: 'pencil' },
|
|
8
12
|
{ label: 'Duplicate', icon: 'copy' },
|
|
@@ -57,9 +61,9 @@ const meta = {
|
|
|
57
61
|
component: Dropdown,
|
|
58
62
|
argTypes: {
|
|
59
63
|
menus: { control: 'object' },
|
|
60
|
-
trigger: { control: 'inline-radio', options:
|
|
61
|
-
side: { control: 'select', options:
|
|
62
|
-
align: { control: 'select', options:
|
|
64
|
+
trigger: { control: 'inline-radio', options: triggers },
|
|
65
|
+
side: { control: 'select', options: sides },
|
|
66
|
+
align: { control: 'select', options: aligns },
|
|
63
67
|
sideOffset: { control: 'number' },
|
|
64
68
|
},
|
|
65
69
|
args: {
|
|
@@ -89,71 +93,63 @@ export const Default: Story = {}
|
|
|
89
93
|
|
|
90
94
|
export const HoverTrigger: Story = {
|
|
91
95
|
parameters: noControls,
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
<Dropdown :menus="basicMenus" trigger="hover">
|
|
97
|
-
<Button variant="outline">Hover me</Button>
|
|
98
|
-
</Dropdown>
|
|
99
|
-
`,
|
|
100
|
-
}),
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
export const ClickTrigger: Story = {
|
|
104
|
-
parameters: noControls,
|
|
105
|
-
render: () => ({
|
|
106
|
-
components: { Dropdown, Button },
|
|
107
|
-
setup: () => ({ basicMenus }),
|
|
108
|
-
template: `
|
|
109
|
-
<Dropdown :menus="basicMenus" trigger="click">
|
|
110
|
-
<Button variant="outline">Click me</Button>
|
|
111
|
-
</Dropdown>
|
|
112
|
-
`,
|
|
113
|
-
}),
|
|
96
|
+
args: {
|
|
97
|
+
menus: basicMenus,
|
|
98
|
+
trigger: 'hover',
|
|
99
|
+
},
|
|
114
100
|
}
|
|
115
101
|
|
|
116
102
|
export const WithDisabledItems: Story = {
|
|
117
103
|
parameters: noControls,
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
<Dropdown :menus="accountMenus" trigger="click">
|
|
123
|
-
<Button variant="outline">Account</Button>
|
|
124
|
-
</Dropdown>
|
|
125
|
-
`,
|
|
126
|
-
}),
|
|
104
|
+
args: {
|
|
105
|
+
menus: accountMenus,
|
|
106
|
+
trigger: 'click',
|
|
107
|
+
},
|
|
127
108
|
}
|
|
128
109
|
|
|
129
110
|
export const WithLinks: Story = {
|
|
130
111
|
parameters: noControls,
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
<Dropdown :menus="linkMenus" trigger="click">
|
|
136
|
-
<Button variant="outline">Resources</Button>
|
|
137
|
-
</Dropdown>
|
|
138
|
-
`,
|
|
139
|
-
}),
|
|
112
|
+
args: {
|
|
113
|
+
menus: linkMenus,
|
|
114
|
+
trigger: 'click',
|
|
115
|
+
},
|
|
140
116
|
}
|
|
141
117
|
|
|
142
118
|
export const WithGroups: Story = {
|
|
143
119
|
parameters: noControls,
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
<Dropdown :menus="groupedMenus" trigger="click">
|
|
149
|
-
<Button variant="outline">Menu with Groups</Button>
|
|
150
|
-
</Dropdown>
|
|
151
|
-
`,
|
|
152
|
-
}),
|
|
120
|
+
args: {
|
|
121
|
+
menus: groupedMenus,
|
|
122
|
+
trigger: 'click',
|
|
123
|
+
},
|
|
153
124
|
}
|
|
154
125
|
|
|
155
126
|
export const CustomSlots: Story = {
|
|
156
|
-
parameters:
|
|
127
|
+
parameters: {
|
|
128
|
+
...noControls,
|
|
129
|
+
docs: {
|
|
130
|
+
source: {
|
|
131
|
+
code: `
|
|
132
|
+
<template>
|
|
133
|
+
<Dropdown :menus="customMenus" trigger="click">
|
|
134
|
+
<Button variant="outline">Custom Slots</Button>
|
|
135
|
+
<template #profile="{ item }">
|
|
136
|
+
<div class="flex flex-col gap-1 px-2 py-1.5">
|
|
137
|
+
<span class="font-semibold text-sm">{{ item.title }}</span>
|
|
138
|
+
<span class="text-xs text-muted-foreground">{{ item.email }}</span>
|
|
139
|
+
</div>
|
|
140
|
+
</template>
|
|
141
|
+
<template #logout>
|
|
142
|
+
<span class="flex items-center gap-2 text-danger font-semibold">
|
|
143
|
+
<span>🚪</span>
|
|
144
|
+
<span>Custom Logout</span>
|
|
145
|
+
</span>
|
|
146
|
+
</template>
|
|
147
|
+
</Dropdown>
|
|
148
|
+
</template>
|
|
149
|
+
`.trim(),
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
},
|
|
157
153
|
render: () => ({
|
|
158
154
|
components: { Dropdown, Button },
|
|
159
155
|
setup: () => ({ customMenus }),
|
|
@@ -178,7 +174,29 @@ export const CustomSlots: Story = {
|
|
|
178
174
|
}
|
|
179
175
|
|
|
180
176
|
export const PopupSlot: Story = {
|
|
181
|
-
parameters:
|
|
177
|
+
parameters: {
|
|
178
|
+
...noControls,
|
|
179
|
+
docs: {
|
|
180
|
+
source: {
|
|
181
|
+
code: `
|
|
182
|
+
<template>
|
|
183
|
+
<Dropdown trigger="click">
|
|
184
|
+
<Button variant="outline">Custom Popup</Button>
|
|
185
|
+
<template #popup="{ hide }">
|
|
186
|
+
<div class="flex flex-col gap-2 p-3 min-w-[220px]">
|
|
187
|
+
<div class="text-sm font-semibold">Custom content</div>
|
|
188
|
+
<p class="text-sm text-muted-foreground">
|
|
189
|
+
Use the <code>popup</code> slot to render arbitrary content inside the menu.
|
|
190
|
+
</p>
|
|
191
|
+
<Button size="sm" @click="hide">Close</Button>
|
|
192
|
+
</div>
|
|
193
|
+
</template>
|
|
194
|
+
</Dropdown>
|
|
195
|
+
</template>
|
|
196
|
+
`.trim(),
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
},
|
|
182
200
|
render: () => ({
|
|
183
201
|
components: { Dropdown, Button },
|
|
184
202
|
template: `
|
|
@@ -47,12 +47,11 @@ const actionColorVariants = cva('', {
|
|
|
47
47
|
defaultVariants: { color: 'default' },
|
|
48
48
|
})
|
|
49
49
|
|
|
50
|
+
defineOptions({ inheritAttrs: false })
|
|
51
|
+
|
|
50
52
|
const props = withDefaults(defineProps<DropdownProps>(), {
|
|
51
53
|
menus: () => [],
|
|
52
54
|
trigger: 'hover',
|
|
53
|
-
side: undefined,
|
|
54
|
-
align: undefined,
|
|
55
|
-
sideOffset: undefined,
|
|
56
55
|
class: undefined,
|
|
57
56
|
})
|
|
58
57
|
|
|
@@ -138,9 +137,7 @@ onBeforeUnmount(() => {
|
|
|
138
137
|
<slot />
|
|
139
138
|
</DropdownMenuTrigger>
|
|
140
139
|
<DropdownMenuContent
|
|
141
|
-
|
|
142
|
-
:align="align"
|
|
143
|
-
:sideOffset="sideOffset"
|
|
140
|
+
v-bind="$attrs"
|
|
144
141
|
:class="props.class"
|
|
145
142
|
@mouseenter="handleMenuEnter"
|
|
146
143
|
@mouseleave="handleMenuLeave"
|
|
@@ -192,7 +189,7 @@ onBeforeUnmount(() => {
|
|
|
192
189
|
<Icon
|
|
193
190
|
v-if="item.active"
|
|
194
191
|
name="check"
|
|
195
|
-
class="ml-auto
|
|
192
|
+
class="size-4 ml-auto"
|
|
196
193
|
/>
|
|
197
194
|
</DropdownMenuItem>
|
|
198
195
|
<!-- Built-in: action (default) -->
|
|
@@ -208,7 +205,7 @@ onBeforeUnmount(() => {
|
|
|
208
205
|
unstyled
|
|
209
206
|
:href="item.href"
|
|
210
207
|
:target="item.target"
|
|
211
|
-
class="flex w-full items-center
|
|
208
|
+
class="gap-2 flex w-full items-center"
|
|
212
209
|
@click="handleItemAction(item, $event)"
|
|
213
210
|
>
|
|
214
211
|
<Icon
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { DropdownMenuContentProps } from 'reka-ui'
|
|
1
2
|
import type { Component } from 'vue'
|
|
2
3
|
|
|
3
4
|
export type DropdownItemColor = 'default' | 'primary' | 'success' | 'info' | 'help' | 'warn' | 'danger'
|
|
@@ -71,17 +72,11 @@ export type DropdownItem
|
|
|
71
72
|
| DropdownCustomActionItem
|
|
72
73
|
| DropdownCustomLabelItem
|
|
73
74
|
|
|
74
|
-
export interface DropdownProps {
|
|
75
|
+
export interface DropdownProps extends /* @vue-ignore */ DropdownMenuContentProps {
|
|
75
76
|
/** Menu items to display in the dropdown (not required when using popup slot) */
|
|
76
77
|
menus?: DropdownItem[]
|
|
77
|
-
/** Trigger mode for showing the dropdown */
|
|
78
|
+
/** Trigger mode for showing the dropdown. Defaults to 'hover'. */
|
|
78
79
|
trigger?: 'click' | 'hover'
|
|
79
|
-
/** Preferred side of the trigger to render against. */
|
|
80
|
-
side?: 'top' | 'bottom' | 'left' | 'right'
|
|
81
|
-
/** Alignment against the trigger. */
|
|
82
|
-
align?: 'start' | 'center' | 'end'
|
|
83
|
-
/** Distance in pixels from the trigger. */
|
|
84
|
-
sideOffset?: number
|
|
85
80
|
/** Extra class for the dropdown content container. */
|
|
86
81
|
class?: ClassValue
|
|
87
82
|
}
|
|
@@ -45,66 +45,54 @@ export const Default: Story = {}
|
|
|
45
45
|
|
|
46
46
|
export const Required: Story = {
|
|
47
47
|
parameters: noControls,
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
return { email }
|
|
53
|
-
},
|
|
54
|
-
template: `
|
|
55
|
-
<div class="max-w-md">
|
|
56
|
-
<FormItem label="Email" required>
|
|
57
|
-
<Input v-model="email" placeholder="Enter your email" />
|
|
58
|
-
</FormItem>
|
|
59
|
-
</div>
|
|
60
|
-
`,
|
|
61
|
-
}),
|
|
48
|
+
args: {
|
|
49
|
+
label: 'Email',
|
|
50
|
+
required: true,
|
|
51
|
+
},
|
|
62
52
|
}
|
|
63
53
|
|
|
64
54
|
export const WithError: Story = {
|
|
65
55
|
parameters: noControls,
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
<Input model-value="admin" />
|
|
72
|
-
</FormItem>
|
|
73
|
-
</div>
|
|
74
|
-
`,
|
|
75
|
-
}),
|
|
56
|
+
args: {
|
|
57
|
+
label: 'Username',
|
|
58
|
+
required: true,
|
|
59
|
+
error: 'Username is already taken',
|
|
60
|
+
},
|
|
76
61
|
}
|
|
77
62
|
|
|
78
63
|
export const WithDescription: Story = {
|
|
79
64
|
parameters: noControls,
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
<FormItem label="Password" description="Must be at least 8 characters long">
|
|
85
|
-
<Input type="password" placeholder="Enter password" />
|
|
86
|
-
</FormItem>
|
|
87
|
-
</div>
|
|
88
|
-
`,
|
|
89
|
-
}),
|
|
65
|
+
args: {
|
|
66
|
+
label: 'Password',
|
|
67
|
+
description: 'Must be at least 8 characters long',
|
|
68
|
+
},
|
|
90
69
|
}
|
|
91
70
|
|
|
92
71
|
export const Horizontal: Story = {
|
|
93
72
|
parameters: noControls,
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
<FormItem label="Display Name" orientation="horizontal">
|
|
99
|
-
<Input placeholder="Enter display name" />
|
|
100
|
-
</FormItem>
|
|
101
|
-
</div>
|
|
102
|
-
`,
|
|
103
|
-
}),
|
|
73
|
+
args: {
|
|
74
|
+
label: 'Display Name',
|
|
75
|
+
orientation: 'horizontal',
|
|
76
|
+
},
|
|
104
77
|
}
|
|
105
78
|
|
|
106
79
|
export const Responsive: Story = {
|
|
107
|
-
parameters:
|
|
80
|
+
parameters: {
|
|
81
|
+
...noControls,
|
|
82
|
+
docs: {
|
|
83
|
+
source: {
|
|
84
|
+
code: `
|
|
85
|
+
<template>
|
|
86
|
+
<div class="@container/field-group resize-x overflow-auto rounded border border-dashed border-border bg-card p-4" style="min-width: 200px;">
|
|
87
|
+
<FormItem label="Address" orientation="responsive" description="Your mailing address">
|
|
88
|
+
<Input placeholder="Enter address" />
|
|
89
|
+
</FormItem>
|
|
90
|
+
</div>
|
|
91
|
+
</template>
|
|
92
|
+
`.trim(),
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
},
|
|
108
96
|
render: () => ({
|
|
109
97
|
components: { FormItem, Input },
|
|
110
98
|
template: `
|
|
@@ -9,10 +9,12 @@ const meta = {
|
|
|
9
9
|
argTypes: {
|
|
10
10
|
text: { control: 'text' },
|
|
11
11
|
position: { control: 'select', options: positions },
|
|
12
|
+
class: { control: 'text' },
|
|
12
13
|
},
|
|
13
14
|
args: {
|
|
14
15
|
text: 'This is a helpful tooltip',
|
|
15
16
|
position: 'top',
|
|
17
|
+
class: '',
|
|
16
18
|
},
|
|
17
19
|
render: args => ({
|
|
18
20
|
components: { Help },
|
|
@@ -29,7 +31,23 @@ const noControls = { controls: { disable: true }} satisfies Story['parameters']
|
|
|
29
31
|
export const Default: Story = {}
|
|
30
32
|
|
|
31
33
|
export const Positions: Story = {
|
|
32
|
-
parameters:
|
|
34
|
+
parameters: {
|
|
35
|
+
...noControls,
|
|
36
|
+
docs: {
|
|
37
|
+
source: {
|
|
38
|
+
code: `
|
|
39
|
+
<template>
|
|
40
|
+
<div class="flex items-center gap-8 py-10 justify-center">
|
|
41
|
+
<Help text="Top tooltip" position="top" />
|
|
42
|
+
<Help text="Bottom tooltip" position="bottom" />
|
|
43
|
+
<Help text="Left tooltip" position="left" />
|
|
44
|
+
<Help text="Right tooltip" position="right" />
|
|
45
|
+
</div>
|
|
46
|
+
</template>
|
|
47
|
+
`.trim(),
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
},
|
|
33
51
|
render: () => ({
|
|
34
52
|
components: { Help },
|
|
35
53
|
template: `
|
|
@@ -56,7 +74,21 @@ export const Positions: Story = {
|
|
|
56
74
|
}
|
|
57
75
|
|
|
58
76
|
export const InlineWithLabel: Story = {
|
|
59
|
-
parameters:
|
|
77
|
+
parameters: {
|
|
78
|
+
...noControls,
|
|
79
|
+
docs: {
|
|
80
|
+
source: {
|
|
81
|
+
code: `
|
|
82
|
+
<template>
|
|
83
|
+
<div class="flex items-center gap-1">
|
|
84
|
+
<span class="text-sm font-medium">API Key</span>
|
|
85
|
+
<Help text="Your unique API key for authentication" />
|
|
86
|
+
</div>
|
|
87
|
+
</template>
|
|
88
|
+
`.trim(),
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
},
|
|
60
92
|
render: () => ({
|
|
61
93
|
components: { Help },
|
|
62
94
|
template: `
|
|
@@ -15,9 +15,11 @@ const meta = {
|
|
|
15
15
|
component: Icon,
|
|
16
16
|
argTypes: {
|
|
17
17
|
name: { control: 'text' },
|
|
18
|
+
class: { control: 'text' },
|
|
18
19
|
},
|
|
19
20
|
args: {
|
|
20
21
|
name: 'house',
|
|
22
|
+
class: '',
|
|
21
23
|
},
|
|
22
24
|
render: args => ({
|
|
23
25
|
components: { Icon },
|
|
@@ -34,7 +36,27 @@ const noControls = { controls: { disable: true }} satisfies Story['parameters']
|
|
|
34
36
|
export const Default: Story = {}
|
|
35
37
|
|
|
36
38
|
export const CommonIcons: Story = {
|
|
37
|
-
parameters:
|
|
39
|
+
parameters: {
|
|
40
|
+
...noControls,
|
|
41
|
+
docs: {
|
|
42
|
+
source: {
|
|
43
|
+
code: `
|
|
44
|
+
<template>
|
|
45
|
+
<div class="grid grid-cols-8 gap-4">
|
|
46
|
+
<div
|
|
47
|
+
v-for="name in commonIcons"
|
|
48
|
+
:key="name"
|
|
49
|
+
class="flex flex-col items-center gap-2 rounded-md border p-3"
|
|
50
|
+
>
|
|
51
|
+
<Icon :name="name" class="size-5" />
|
|
52
|
+
<span class="text-xs text-muted-foreground">{{ name }}</span>
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
</template>
|
|
56
|
+
`.trim(),
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
},
|
|
38
60
|
render: () => ({
|
|
39
61
|
components: { Icon },
|
|
40
62
|
setup: () => ({ commonIcons }),
|
|
@@ -54,7 +76,24 @@ export const CommonIcons: Story = {
|
|
|
54
76
|
}
|
|
55
77
|
|
|
56
78
|
export const Sizes: Story = {
|
|
57
|
-
parameters:
|
|
79
|
+
parameters: {
|
|
80
|
+
...noControls,
|
|
81
|
+
docs: {
|
|
82
|
+
source: {
|
|
83
|
+
code: `
|
|
84
|
+
<template>
|
|
85
|
+
<div class="flex items-end gap-4">
|
|
86
|
+
<Icon name="star" class="size-3" />
|
|
87
|
+
<Icon name="star" class="size-4" />
|
|
88
|
+
<Icon name="star" class="size-5" />
|
|
89
|
+
<Icon name="star" class="size-6" />
|
|
90
|
+
<Icon name="star" class="size-8" />
|
|
91
|
+
</div>
|
|
92
|
+
</template>
|
|
93
|
+
`.trim(),
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
},
|
|
58
97
|
render: () => ({
|
|
59
98
|
components: { Icon },
|
|
60
99
|
template: `
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from '@storybook/vue3'
|
|
2
|
+
import EventLog from '#storybook/EventLog.vue'
|
|
2
3
|
import Icon from '../Icon/index.vue'
|
|
3
4
|
import Input from './index.vue'
|
|
4
5
|
|
|
@@ -11,6 +12,7 @@ const meta = {
|
|
|
11
12
|
disabled: { control: 'boolean' },
|
|
12
13
|
readonly: { control: 'boolean' },
|
|
13
14
|
invalid: { control: 'boolean' },
|
|
15
|
+
class: { control: 'text' },
|
|
14
16
|
},
|
|
15
17
|
args: {
|
|
16
18
|
modelValue: '',
|
|
@@ -18,12 +20,13 @@ const meta = {
|
|
|
18
20
|
disabled: false,
|
|
19
21
|
readonly: false,
|
|
20
22
|
invalid: false,
|
|
23
|
+
class: 'max-w-sm',
|
|
21
24
|
},
|
|
22
25
|
render: args => ({
|
|
23
26
|
components: { Input },
|
|
24
27
|
setup: () => ({ args }),
|
|
25
28
|
template: `
|
|
26
|
-
<Input v-bind="args" placeholder="Type something..."
|
|
29
|
+
<Input v-bind="args" placeholder="Type something..." />
|
|
27
30
|
`,
|
|
28
31
|
}),
|
|
29
32
|
} satisfies Meta<typeof Input>
|
|
@@ -35,25 +38,23 @@ const noControls = { controls: { disable: true }} satisfies Story['parameters']
|
|
|
35
38
|
|
|
36
39
|
export const Default: Story = {}
|
|
37
40
|
|
|
38
|
-
export const Controlled: Story = {
|
|
39
|
-
parameters: noControls,
|
|
40
|
-
render: () => ({
|
|
41
|
-
components: { Input },
|
|
42
|
-
setup () {
|
|
43
|
-
const value = ref('')
|
|
44
|
-
return { value }
|
|
45
|
-
},
|
|
46
|
-
template: `
|
|
47
|
-
<div class="max-w-sm space-y-2">
|
|
48
|
-
<Input v-model="value" placeholder="Enter your name..." />
|
|
49
|
-
<div class="text-sm text-muted-foreground">Value: {{ value }}</div>
|
|
50
|
-
</div>
|
|
51
|
-
`,
|
|
52
|
-
}),
|
|
53
|
-
}
|
|
54
|
-
|
|
55
41
|
export const WithPrefix: Story = {
|
|
56
|
-
parameters:
|
|
42
|
+
parameters: {
|
|
43
|
+
...noControls,
|
|
44
|
+
docs: {
|
|
45
|
+
source: {
|
|
46
|
+
code: `
|
|
47
|
+
<template>
|
|
48
|
+
<Input v-model="value" placeholder="Search...">
|
|
49
|
+
<template #prefix>
|
|
50
|
+
<Icon name="search" />
|
|
51
|
+
</template>
|
|
52
|
+
</Input>
|
|
53
|
+
</template>
|
|
54
|
+
`.trim(),
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
},
|
|
57
58
|
render: () => ({
|
|
58
59
|
components: { Input, Icon },
|
|
59
60
|
setup () {
|
|
@@ -74,7 +75,22 @@ export const WithPrefix: Story = {
|
|
|
74
75
|
}
|
|
75
76
|
|
|
76
77
|
export const WithSuffix: Story = {
|
|
77
|
-
parameters:
|
|
78
|
+
parameters: {
|
|
79
|
+
...noControls,
|
|
80
|
+
docs: {
|
|
81
|
+
source: {
|
|
82
|
+
code: `
|
|
83
|
+
<template>
|
|
84
|
+
<Input v-model="value" placeholder="Email">
|
|
85
|
+
<template #suffix>
|
|
86
|
+
<Icon name="mail" />
|
|
87
|
+
</template>
|
|
88
|
+
</Input>
|
|
89
|
+
</template>
|
|
90
|
+
`.trim(),
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
},
|
|
78
94
|
render: () => ({
|
|
79
95
|
components: { Input, Icon },
|
|
80
96
|
setup () {
|
|
@@ -95,7 +111,14 @@ export const WithSuffix: Story = {
|
|
|
95
111
|
}
|
|
96
112
|
|
|
97
113
|
export const Password: Story = {
|
|
98
|
-
parameters:
|
|
114
|
+
parameters: {
|
|
115
|
+
...noControls,
|
|
116
|
+
docs: {
|
|
117
|
+
source: {
|
|
118
|
+
code: '<Input v-model="value" type="password" placeholder="Password" />',
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
},
|
|
99
122
|
render: () => ({
|
|
100
123
|
components: { Input },
|
|
101
124
|
setup () {
|
|
@@ -113,24 +136,43 @@ export const Password: Story = {
|
|
|
113
136
|
|
|
114
137
|
export const Disabled: Story = {
|
|
115
138
|
parameters: noControls,
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
}
|
|
139
|
+
args: {
|
|
140
|
+
disabled: true,
|
|
141
|
+
modelValue: 'Disabled input',
|
|
142
|
+
},
|
|
120
143
|
}
|
|
121
144
|
|
|
122
145
|
export const Readonly: Story = {
|
|
123
146
|
parameters: noControls,
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
}
|
|
147
|
+
args: {
|
|
148
|
+
readonly: true,
|
|
149
|
+
modelValue: 'Read-only value',
|
|
150
|
+
},
|
|
128
151
|
}
|
|
129
152
|
|
|
130
153
|
export const Invalid: Story = {
|
|
154
|
+
parameters: noControls,
|
|
155
|
+
args: {
|
|
156
|
+
invalid: true,
|
|
157
|
+
modelValue: 'Invalid value',
|
|
158
|
+
},
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export const EventHandling: Story = {
|
|
131
162
|
parameters: noControls,
|
|
132
163
|
render: () => ({
|
|
133
|
-
components: { Input },
|
|
134
|
-
|
|
164
|
+
components: { Input, EventLog },
|
|
165
|
+
setup: () => ({ value: ref('') }),
|
|
166
|
+
template: `
|
|
167
|
+
<EventLog v-slot="{ record }">
|
|
168
|
+
<Input
|
|
169
|
+
v-model="value"
|
|
170
|
+
class="max-w-sm"
|
|
171
|
+
placeholder="Type and blur to see events"
|
|
172
|
+
@update:modelValue="(v) => record('update:modelValue', v)"
|
|
173
|
+
@change="(v) => record('change', v)"
|
|
174
|
+
/>
|
|
175
|
+
</EventLog>
|
|
176
|
+
`,
|
|
135
177
|
}),
|
|
136
178
|
}
|