@polymarbot/nuxt-layer-shadcn-ui 0.1.9 → 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.
Files changed (103) hide show
  1. package/app/assets/styles/colors.css +10 -10
  2. package/app/assets/styles/globals.css +1 -0
  3. package/app/assets/styles/z-index.css +27 -0
  4. package/app/components/ui/Accordion/index.stories.ts +60 -56
  5. package/app/components/ui/Accordion/index.vue +1 -1
  6. package/app/components/ui/AdminLayout/SidebarMenus.vue +0 -2
  7. package/app/components/ui/AdminLayout/index.stories.ts +9 -8
  8. package/app/components/ui/Alert/index.stories.ts +28 -26
  9. package/app/components/ui/Alert/index.vue +6 -6
  10. package/app/components/ui/Alert/types.ts +2 -1
  11. package/app/components/ui/AlertDialog/index.stories.ts +85 -50
  12. package/app/components/ui/AsyncDataTable/index.stories.ts +53 -36
  13. package/app/components/ui/Avatar/index.stories.ts +56 -51
  14. package/app/components/ui/Avatar/index.vue +1 -1
  15. package/app/components/ui/Avatar/types.ts +5 -2
  16. package/app/components/ui/Badge/index.stories.ts +41 -41
  17. package/app/components/ui/Badge/index.vue +1 -1
  18. package/app/components/ui/Badge/types.ts +3 -1
  19. package/app/components/ui/Breadcrumb/index.stories.ts +48 -37
  20. package/app/components/ui/Breadcrumb/index.vue +1 -1
  21. package/app/components/ui/Button/index.stories.ts +94 -90
  22. package/app/components/ui/Button/index.vue +1 -1
  23. package/app/components/ui/Button/types.ts +4 -1
  24. package/app/components/ui/ButtonGroup/index.stories.ts +61 -49
  25. package/app/components/ui/Card/index.stories.ts +55 -47
  26. package/app/components/ui/Card/index.vue +1 -1
  27. package/app/components/ui/Checkbox/index.stories.ts +69 -46
  28. package/app/components/ui/Checkbox/index.vue +1 -1
  29. package/app/components/ui/CopyButton/index.stories.ts +89 -31
  30. package/app/components/ui/DataTable/index.stories.ts +218 -168
  31. package/app/components/ui/DataTable/index.vue +1 -1
  32. package/app/components/ui/DatePicker/index.stories.ts +131 -37
  33. package/app/components/ui/DateRangePicker/index.stories.ts +107 -33
  34. package/app/components/ui/Divider/index.stories.ts +46 -24
  35. package/app/components/ui/Divider/index.vue +1 -1
  36. package/app/components/ui/Drawer/index.stories.ts +131 -81
  37. package/app/components/ui/Drawer/index.vue +1 -7
  38. package/app/components/ui/Drawer/types.ts +1 -1
  39. package/app/components/ui/Dropdown/index.stories.ts +134 -89
  40. package/app/components/ui/Dropdown/index.vue +5 -1
  41. package/app/components/ui/Dropdown/types.ts +1 -1
  42. package/app/components/ui/FormItem/index.stories.ts +87 -43
  43. package/app/components/ui/FormItem/index.vue +1 -1
  44. package/app/components/ui/Help/index.stories.ts +46 -35
  45. package/app/components/ui/Icon/index.stories.ts +41 -43
  46. package/app/components/ui/Input/index.stories.ts +95 -41
  47. package/app/components/ui/Input/index.vue +1 -1
  48. package/app/components/ui/InputCurrency/index.stories.ts +89 -49
  49. package/app/components/ui/InputNumber/index.stories.ts +93 -29
  50. package/app/components/ui/InputNumber/index.vue +1 -1
  51. package/app/components/ui/InputOtp/index.stories.ts +6 -7
  52. package/app/components/ui/InputOtp/index.vue +1 -1
  53. package/app/components/ui/InputPercent/index.stories.ts +6 -7
  54. package/app/components/ui/InputRange/index.stories.ts +6 -7
  55. package/app/components/ui/Loading/index.stories.ts +19 -19
  56. package/app/components/ui/Markdown/index.stories.ts +7 -10
  57. package/app/components/ui/Modal/index.stories.ts +135 -80
  58. package/app/components/ui/Modal/index.vue +1 -6
  59. package/app/components/ui/Modal/types.ts +1 -1
  60. package/app/components/ui/ModalContent/index.stories.ts +54 -26
  61. package/app/components/ui/ModalContent/index.vue +2 -2
  62. package/app/components/ui/PageCard/index.stories.ts +177 -67
  63. package/app/components/ui/Pagination/index.stories.ts +68 -51
  64. package/app/components/ui/Pagination/index.vue +2 -2
  65. package/app/components/ui/Popover/index.stories.ts +47 -45
  66. package/app/components/ui/Popover/index.vue +1 -1
  67. package/app/components/ui/Qrcode/index.stories.ts +42 -34
  68. package/app/components/ui/RadioCardGroup/index.stories.ts +23 -32
  69. package/app/components/ui/RadioCardGroup/index.vue +1 -1
  70. package/app/components/ui/RadioGroup/index.stories.ts +123 -0
  71. package/app/components/ui/RadioGroup/index.vue +73 -0
  72. package/app/components/ui/RadioGroup/types.ts +13 -0
  73. package/app/components/ui/ScrollArea/index.stories.ts +69 -37
  74. package/app/components/ui/ScrollArea/index.vue +1 -1
  75. package/app/components/ui/SearchSelect/index.stories.ts +104 -66
  76. package/app/components/ui/Select/index.stories.ts +152 -98
  77. package/app/components/ui/Select/index.vue +3 -3
  78. package/app/components/ui/Skeleton/index.stories.ts +27 -30
  79. package/app/components/ui/Skeleton/index.vue +1 -1
  80. package/app/components/ui/Slider/index.stories.ts +73 -31
  81. package/app/components/ui/Slider/index.vue +1 -1
  82. package/app/components/ui/Surface/index.stories.ts +47 -21
  83. package/app/components/ui/Surface/index.vue +39 -28
  84. package/app/components/ui/Surface/types.ts +2 -2
  85. package/app/components/ui/Switch/index.stories.ts +6 -7
  86. package/app/components/ui/Switch/index.vue +1 -1
  87. package/app/components/ui/Tabs/index.stories.ts +103 -61
  88. package/app/components/ui/Tabs/index.vue +1 -1
  89. package/app/components/ui/Tag/index.stories.ts +42 -25
  90. package/app/components/ui/Tag/index.vue +39 -28
  91. package/app/components/ui/Tag/types.ts +2 -2
  92. package/app/components/ui/Textarea/index.stories.ts +73 -9
  93. package/app/components/ui/Textarea/index.vue +1 -1
  94. package/app/components/ui/Toast/index.stories.ts +71 -18
  95. package/app/components/ui/Toast/index.vue +1 -1
  96. package/app/components/ui/Tooltip/index.stories.ts +45 -38
  97. package/app/components/ui/Tooltip/index.vue +1 -1
  98. package/app/components/ui/WebLink/index.stories.ts +76 -41
  99. package/app/components/ui/WebLink/index.vue +1 -1
  100. package/package.json +2 -2
  101. package/app/components/ui/Radio/index.stories.ts +0 -71
  102. package/app/components/ui/Radio/index.vue +0 -10
  103. package/app/components/ui/Radio/types.ts +0 -3
@@ -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 { name, email }
49
+ return { email }
20
50
  },
21
51
  template: `
22
- <div class="space-y-10 max-w-md">
23
- <section>
24
- <h3 class="mb-4 text-lg font-medium">Basic</h3>
25
- <FormItem label="Name">
26
- <Input v-model="name" placeholder="Enter your name" />
27
- </FormItem>
28
- </section>
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
- <section>
31
- <h3 class="mb-4 text-lg font-medium">Required</h3>
32
- <FormItem label="Email" required>
33
- <Input v-model="email" placeholder="Enter your email" />
34
- </FormItem>
35
- </section>
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
- <section>
38
- <h3 class="mb-4 text-lg font-medium">With Error</h3>
39
- <FormItem label="Username" required error="Username is already taken">
40
- <Input model-value="admin" />
41
- </FormItem>
42
- </section>
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
- <section>
45
- <h3 class="mb-4 text-lg font-medium">With Description</h3>
46
- <FormItem label="Password" description="Must be at least 8 characters long">
47
- <Input type="password" placeholder="Enter password" />
48
- </FormItem>
49
- </section>
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
- <section>
52
- <h3 class="mb-4 text-lg font-medium">Horizontal Orientation</h3>
53
- <FormItem label="Display Name" orientation="horizontal">
54
- <Input placeholder="Enter display name" />
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
- </section>
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
  }),
@@ -5,7 +5,7 @@ import {
5
5
  FieldDescription,
6
6
  FieldError,
7
7
  FieldLabel,
8
- } from '@polymarbot/nuxt-layer-shadcn-ui/app/components/shadcn/field'
8
+ } from '../../shadcn/field'
9
9
  import type { FormItemProps } from './types'
10
10
 
11
11
  const props = defineProps<FormItemProps>()
@@ -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="space-y-10">
17
- <section>
18
- <h3 class="mb-4 text-lg font-medium">Basic</h3>
19
- <Help text="This is a helpful tooltip" />
20
- </section>
21
-
22
- <section>
23
- <h3 class="mb-4 text-lg font-medium">Positions</h3>
24
- <div class="flex items-center gap-8 py-10 justify-center">
25
- <div class="flex flex-col items-center gap-2">
26
- <Help text="Top tooltip" position="top" />
27
- <span class="text-sm text-muted-foreground">Top</span>
28
- </div>
29
- <div class="flex flex-col items-center gap-2">
30
- <Help text="Bottom tooltip" position="bottom" />
31
- <span class="text-sm text-muted-foreground">Bottom</span>
32
- </div>
33
- <div class="flex flex-col items-center gap-2">
34
- <Help text="Left tooltip" position="left" />
35
- <span class="text-sm text-muted-foreground">Left</span>
36
- </div>
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
- <section>
45
- <h3 class="mb-4 text-lg font-medium">Inline with Label</h3>
46
- <div class="flex items-center gap-1">
47
- <span class="text-sm font-medium">API Key</span>
48
- <Help text="Your unique API key for authentication" />
49
- </div>
50
- </section>
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
  }),
@@ -1,6 +1,15 @@
1
1
  import type { Meta, StoryObj } from '@storybook/vue3'
2
2
  import Icon from './index.vue'
3
3
 
4
+ const commonIcons = [
5
+ 'house', 'search', 'settings', 'user', 'mail', 'bell',
6
+ 'heart', 'star', 'plus', 'minus', 'check', 'x',
7
+ 'chevron-left', 'chevron-right', 'chevron-up', 'chevron-down',
8
+ 'arrow-left', 'arrow-right', 'arrow-up', 'arrow-down',
9
+ 'eye', 'eye-off', 'trash-2', 'pencil', 'copy', 'download',
10
+ 'upload', 'share', 'link', 'external-link', 'info', 'triangle-alert',
11
+ ]
12
+
4
13
  const meta = {
5
14
  title: 'UI/Icon',
6
15
  component: Icon,
@@ -10,58 +19,47 @@ const meta = {
10
19
  args: {
11
20
  name: 'house',
12
21
  },
22
+ render: args => ({
23
+ components: { Icon },
24
+ setup: () => ({ args }),
25
+ template: '<Icon v-bind="args" />',
26
+ }),
13
27
  } satisfies Meta<typeof Icon>
14
28
 
15
29
  export default meta
16
30
  type Story = StoryObj<typeof meta>
17
31
 
18
- const commonIcons = [
19
- 'house', 'search', 'settings', 'user', 'mail', 'bell',
20
- 'heart', 'star', 'plus', 'minus', 'check', 'x',
21
- 'chevron-left', 'chevron-right', 'chevron-up', 'chevron-down',
22
- 'arrow-left', 'arrow-right', 'arrow-up', 'arrow-down',
23
- 'eye', 'eye-off', 'trash-2', 'pencil', 'copy', 'download',
24
- 'upload', 'share', 'link', 'external-link', 'info', 'triangle-alert',
25
- ]
32
+ export const Default: Story = {}
26
33
 
27
- export const Default: Story = {
28
- render: args => ({
34
+ export const CommonIcons: Story = {
35
+ render: () => ({
29
36
  components: { Icon },
30
- setup: () => ({ args, commonIcons }),
37
+ setup: () => ({ commonIcons }),
31
38
  template: `
32
- <div class="space-y-10">
33
- <!-- Controlled -->
34
- <section>
35
- <h3 class="mb-4 text-lg font-medium">Controlled</h3>
36
- <Icon v-bind="args" />
37
- </section>
38
-
39
- <!-- Common Icons -->
40
- <section>
41
- <h3 class="mb-4 text-lg font-medium">Common Icons</h3>
42
- <div class="grid grid-cols-8 gap-4">
43
- <div
44
- v-for="name in commonIcons"
45
- :key="name"
46
- class="flex flex-col items-center gap-2 rounded-md border p-3"
47
- >
48
- <Icon :name="name" class="size-5" />
49
- <span class="text-xs text-muted-foreground">{{ name }}</span>
50
- </div>
51
- </div>
52
- </section>
39
+ <div class="grid grid-cols-8 gap-4">
40
+ <div
41
+ v-for="name in commonIcons"
42
+ :key="name"
43
+ class="flex flex-col items-center gap-2 rounded-md border p-3"
44
+ >
45
+ <Icon :name="name" class="size-5" />
46
+ <span class="text-xs text-muted-foreground">{{ name }}</span>
47
+ </div>
48
+ </div>
49
+ `,
50
+ }),
51
+ }
53
52
 
54
- <!-- Sizes -->
55
- <section>
56
- <h3 class="mb-4 text-lg font-medium">Sizes</h3>
57
- <div class="flex items-end gap-4">
58
- <Icon name="star" class="size-3" />
59
- <Icon name="star" class="size-4" />
60
- <Icon name="star" class="size-5" />
61
- <Icon name="star" class="size-6" />
62
- <Icon name="star" class="size-8" />
63
- </div>
64
- </section>
53
+ export const Sizes: Story = {
54
+ render: () => ({
55
+ components: { Icon },
56
+ template: `
57
+ <div class="flex items-end gap-4">
58
+ <Icon name="star" class="size-3" />
59
+ <Icon name="star" class="size-4" />
60
+ <Icon name="star" class="size-5" />
61
+ <Icon name="star" class="size-6" />
62
+ <Icon name="star" class="size-8" />
65
63
  </div>
66
64
  `,
67
65
  }),
@@ -6,68 +6,122 @@ const meta = {
6
6
  title: 'UI/Input',
7
7
  component: Input,
8
8
  argTypes: {
9
+ modelValue: { control: 'text' },
10
+ autocomplete: { control: 'text' },
9
11
  disabled: { control: 'boolean' },
10
12
  readonly: { control: 'boolean' },
11
13
  invalid: { control: 'boolean' },
12
14
  },
13
15
  args: {
16
+ modelValue: '',
17
+ autocomplete: 'off',
14
18
  disabled: false,
15
19
  readonly: false,
16
20
  invalid: false,
17
21
  },
18
- } satisfies Meta
22
+ render: args => ({
23
+ components: { Input },
24
+ setup: () => ({ args }),
25
+ template: `
26
+ <Input v-bind="args" placeholder="Type something..." class="max-w-sm" />
27
+ `,
28
+ }),
29
+ } satisfies Meta<typeof Input>
19
30
 
20
31
  export default meta
21
32
  type Story = StoryObj<typeof meta>
22
33
 
23
- export const Default: Story = {
24
- render: args => ({
25
- components: { Input, Icon },
34
+ export const Default: Story = {}
35
+
36
+ export const Controlled: Story = {
37
+ render: () => ({
38
+ components: { Input },
26
39
  setup () {
27
40
  const value = ref('')
28
- const withPrefix = ref('')
29
- const withSuffix = ref('')
30
- const password = ref('')
31
- return { args, value, withPrefix, withSuffix, password }
41
+ return { value }
32
42
  },
33
43
  template: `
34
- <div class="space-y-10 max-w-sm">
35
- <!-- Controlled -->
36
- <section>
37
- <h3 class="mb-4 text-lg font-medium">Controlled</h3>
38
- <Input v-model="value" v-bind="args" placeholder="Enter your name..." />
39
- <div class="mt-2 text-sm text-muted-foreground">Value: {{ value }}</div>
40
- </section>
44
+ <div class="max-w-sm space-y-2">
45
+ <Input v-model="value" placeholder="Enter your name..." />
46
+ <div class="text-sm text-muted-foreground">Value: {{ value }}</div>
47
+ </div>
48
+ `,
49
+ }),
50
+ }
41
51
 
42
- <!-- With Prefix Icon -->
43
- <section>
44
- <h3 class="mb-4 text-lg font-medium">With Prefix Icon</h3>
45
- <Input v-model="withPrefix" placeholder="Search...">
46
- <template #prefix>
47
- <Icon name="search" />
48
- </template>
49
- </Input>
50
- <div class="mt-2 text-sm text-muted-foreground">Value: {{ withPrefix }}</div>
51
- </section>
52
+ export const WithPrefix: Story = {
53
+ render: () => ({
54
+ components: { Input, Icon },
55
+ setup () {
56
+ const value = ref('')
57
+ return { value }
58
+ },
59
+ template: `
60
+ <div class="max-w-sm space-y-2">
61
+ <Input v-model="value" placeholder="Search...">
62
+ <template #prefix>
63
+ <Icon name="search" />
64
+ </template>
65
+ </Input>
66
+ <div class="text-sm text-muted-foreground">Value: {{ value }}</div>
67
+ </div>
68
+ `,
69
+ }),
70
+ }
52
71
 
53
- <!-- With Suffix Icon -->
54
- <section>
55
- <h3 class="mb-4 text-lg font-medium">With Suffix Icon</h3>
56
- <Input v-model="withSuffix" placeholder="Email">
57
- <template #suffix>
58
- <Icon name="mail" />
59
- </template>
60
- </Input>
61
- <div class="mt-2 text-sm text-muted-foreground">Value: {{ withSuffix }}</div>
62
- </section>
72
+ export const WithSuffix: Story = {
73
+ render: () => ({
74
+ components: { Input, Icon },
75
+ setup () {
76
+ const value = ref('')
77
+ return { value }
78
+ },
79
+ template: `
80
+ <div class="max-w-sm space-y-2">
81
+ <Input v-model="value" placeholder="Email">
82
+ <template #suffix>
83
+ <Icon name="mail" />
84
+ </template>
85
+ </Input>
86
+ <div class="text-sm text-muted-foreground">Value: {{ value }}</div>
87
+ </div>
88
+ `,
89
+ }),
90
+ }
63
91
 
64
- <!-- Password -->
65
- <section>
66
- <h3 class="mb-4 text-lg font-medium">Password</h3>
67
- <Input v-model="password" type="password" placeholder="Password" />
68
- <div class="mt-2 text-sm text-muted-foreground">Value: {{ password }}</div>
69
- </section>
92
+ export const Password: Story = {
93
+ render: () => ({
94
+ components: { Input },
95
+ setup () {
96
+ const value = ref('')
97
+ return { value }
98
+ },
99
+ template: `
100
+ <div class="max-w-sm space-y-2">
101
+ <Input v-model="value" type="password" placeholder="Password" />
102
+ <div class="text-sm text-muted-foreground">Value: {{ value }}</div>
70
103
  </div>
71
104
  `,
72
105
  }),
73
106
  }
107
+
108
+ export const Disabled: Story = {
109
+ render: () => ({
110
+ components: { Input },
111
+ template: '<Input disabled placeholder="Disabled input" class="max-w-sm" />',
112
+ }),
113
+ }
114
+
115
+ export const Readonly: Story = {
116
+ render: () => ({
117
+ components: { Input },
118
+ template: '<Input readonly modelValue="Read-only value" class="max-w-sm" />',
119
+ }),
120
+ }
121
+
122
+ export const Invalid: Story = {
123
+ render: () => ({
124
+ components: { Input },
125
+ template: '<Input invalid modelValue="Invalid value" class="max-w-sm" />',
126
+ }),
127
+ }
@@ -4,7 +4,7 @@ import {
4
4
  InputGroupAddon,
5
5
  InputGroupButton,
6
6
  InputGroupInput,
7
- } from '@polymarbot/nuxt-layer-shadcn-ui/app/components/shadcn/input-group'
7
+ } from '../../shadcn/input-group'
8
8
  import type { InputProps } from './types'
9
9
 
10
10
  defineOptions({ inheritAttrs: false })