@polymarbot/nuxt-layer-shadcn-ui 0.1.10 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/app/assets/styles/colors.css +10 -10
  2. package/app/components/ui/Accordion/index.stories.ts +60 -56
  3. package/app/components/ui/Accordion/index.vue +1 -1
  4. package/app/components/ui/AdminLayout/SidebarMenus.vue +0 -2
  5. package/app/components/ui/AdminLayout/index.stories.ts +9 -8
  6. package/app/components/ui/Alert/index.stories.ts +28 -26
  7. package/app/components/ui/Alert/index.vue +6 -6
  8. package/app/components/ui/Alert/types.ts +2 -1
  9. package/app/components/ui/AlertDialog/index.stories.ts +85 -50
  10. package/app/components/ui/AsyncDataTable/index.stories.ts +53 -36
  11. package/app/components/ui/Avatar/index.stories.ts +56 -51
  12. package/app/components/ui/Avatar/index.vue +1 -1
  13. package/app/components/ui/Avatar/types.ts +5 -2
  14. package/app/components/ui/Badge/index.stories.ts +41 -41
  15. package/app/components/ui/Badge/index.vue +1 -1
  16. package/app/components/ui/Badge/types.ts +3 -1
  17. package/app/components/ui/Breadcrumb/index.stories.ts +48 -37
  18. package/app/components/ui/Breadcrumb/index.vue +1 -1
  19. package/app/components/ui/Button/index.stories.ts +94 -90
  20. package/app/components/ui/Button/index.vue +1 -1
  21. package/app/components/ui/Button/types.ts +4 -1
  22. package/app/components/ui/ButtonGroup/index.stories.ts +61 -49
  23. package/app/components/ui/Card/index.stories.ts +55 -47
  24. package/app/components/ui/Card/index.vue +1 -1
  25. package/app/components/ui/Checkbox/index.stories.ts +69 -46
  26. package/app/components/ui/Checkbox/index.vue +1 -1
  27. package/app/components/ui/CopyButton/index.stories.ts +89 -31
  28. package/app/components/ui/DataTable/index.stories.ts +218 -168
  29. package/app/components/ui/DataTable/index.vue +1 -1
  30. package/app/components/ui/DatePicker/index.stories.ts +131 -37
  31. package/app/components/ui/DateRangePicker/index.stories.ts +107 -33
  32. package/app/components/ui/Divider/index.stories.ts +46 -24
  33. package/app/components/ui/Divider/index.vue +1 -1
  34. package/app/components/ui/Drawer/index.stories.ts +131 -81
  35. package/app/components/ui/Drawer/index.vue +1 -1
  36. package/app/components/ui/Drawer/types.ts +1 -1
  37. package/app/components/ui/Dropdown/index.stories.ts +134 -89
  38. package/app/components/ui/Dropdown/index.vue +5 -1
  39. package/app/components/ui/Dropdown/types.ts +1 -1
  40. package/app/components/ui/FormItem/index.stories.ts +87 -43
  41. package/app/components/ui/FormItem/index.vue +1 -1
  42. package/app/components/ui/Help/index.stories.ts +46 -35
  43. package/app/components/ui/Icon/index.stories.ts +41 -43
  44. package/app/components/ui/Input/index.stories.ts +95 -41
  45. package/app/components/ui/Input/index.vue +1 -1
  46. package/app/components/ui/InputCurrency/index.stories.ts +89 -49
  47. package/app/components/ui/InputNumber/index.stories.ts +93 -29
  48. package/app/components/ui/InputNumber/index.vue +1 -1
  49. package/app/components/ui/InputOtp/index.stories.ts +6 -7
  50. package/app/components/ui/InputOtp/index.vue +1 -1
  51. package/app/components/ui/InputPercent/index.stories.ts +6 -7
  52. package/app/components/ui/InputRange/index.stories.ts +6 -7
  53. package/app/components/ui/Loading/index.stories.ts +19 -19
  54. package/app/components/ui/Markdown/index.stories.ts +7 -10
  55. package/app/components/ui/Modal/index.stories.ts +135 -80
  56. package/app/components/ui/Modal/index.vue +1 -1
  57. package/app/components/ui/Modal/types.ts +1 -1
  58. package/app/components/ui/ModalContent/index.stories.ts +54 -26
  59. package/app/components/ui/ModalContent/index.vue +2 -2
  60. package/app/components/ui/PageCard/index.stories.ts +177 -67
  61. package/app/components/ui/Pagination/index.stories.ts +68 -51
  62. package/app/components/ui/Pagination/index.vue +2 -2
  63. package/app/components/ui/Popover/index.stories.ts +47 -45
  64. package/app/components/ui/Popover/index.vue +1 -1
  65. package/app/components/ui/Qrcode/index.stories.ts +42 -34
  66. package/app/components/ui/RadioCardGroup/index.stories.ts +23 -32
  67. package/app/components/ui/RadioCardGroup/index.vue +1 -1
  68. package/app/components/ui/RadioGroup/index.stories.ts +123 -0
  69. package/app/components/ui/RadioGroup/index.vue +73 -0
  70. package/app/components/ui/RadioGroup/types.ts +13 -0
  71. package/app/components/ui/ScrollArea/index.stories.ts +69 -37
  72. package/app/components/ui/ScrollArea/index.vue +1 -1
  73. package/app/components/ui/SearchSelect/index.stories.ts +104 -66
  74. package/app/components/ui/Select/index.stories.ts +152 -98
  75. package/app/components/ui/Select/index.vue +3 -3
  76. package/app/components/ui/Skeleton/index.stories.ts +27 -30
  77. package/app/components/ui/Skeleton/index.vue +1 -1
  78. package/app/components/ui/Slider/index.stories.ts +73 -31
  79. package/app/components/ui/Slider/index.vue +1 -1
  80. package/app/components/ui/Surface/index.stories.ts +47 -21
  81. package/app/components/ui/Surface/index.vue +39 -28
  82. package/app/components/ui/Surface/types.ts +2 -2
  83. package/app/components/ui/Switch/index.stories.ts +6 -7
  84. package/app/components/ui/Switch/index.vue +1 -1
  85. package/app/components/ui/Tabs/index.stories.ts +103 -61
  86. package/app/components/ui/Tabs/index.vue +1 -1
  87. package/app/components/ui/Tag/index.stories.ts +42 -25
  88. package/app/components/ui/Tag/index.vue +39 -28
  89. package/app/components/ui/Tag/types.ts +2 -2
  90. package/app/components/ui/Textarea/index.stories.ts +73 -9
  91. package/app/components/ui/Textarea/index.vue +1 -1
  92. package/app/components/ui/Toast/index.stories.ts +71 -18
  93. package/app/components/ui/Toast/index.vue +1 -1
  94. package/app/components/ui/Tooltip/index.stories.ts +45 -38
  95. package/app/components/ui/Tooltip/index.vue +1 -1
  96. package/app/components/ui/WebLink/index.stories.ts +76 -41
  97. package/app/components/ui/WebLink/index.vue +1 -1
  98. package/package.json +2 -2
  99. package/app/components/ui/Radio/index.stories.ts +0 -71
  100. package/app/components/ui/Radio/index.vue +0 -10
  101. package/app/components/ui/Radio/types.ts +0 -3
@@ -15,7 +15,7 @@ const options: RadioCardGroupOption[] = [
15
15
  },
16
16
  ]
17
17
 
18
- const manyOptions: RadioCardGroupOption[] = [
18
+ const planOptions: RadioCardGroupOption[] = [
19
19
  {
20
20
  value: 'free',
21
21
  title: 'Free',
@@ -38,53 +38,44 @@ const meta = {
38
38
  title: 'UI/RadioCardGroup',
39
39
  component: RadioCardGroup,
40
40
  argTypes: {
41
+ modelValue: { control: 'text' },
42
+ options: { control: 'object' },
41
43
  disabled: { control: 'boolean' },
42
44
  },
43
45
  args: {
46
+ modelValue: 'current',
44
47
  options,
45
48
  disabled: false,
46
49
  },
47
- } satisfies Meta<typeof RadioCardGroup>
48
-
49
- export default meta
50
- type Story = StoryObj<typeof meta>
51
-
52
- export const Default: Story = {
53
50
  render: args => ({
54
51
  components: { RadioCardGroup },
55
52
  setup () {
56
- const selected = ref('current')
57
- return { args, selected, options }
53
+ const selected = ref(args.modelValue ?? '')
54
+ return { args, selected }
58
55
  },
59
56
  template: `
60
57
  <div class="max-w-md space-y-4">
61
- <RadioCardGroup
62
- v-model="selected"
63
- :options="options"
64
- :disabled="args.disabled"
65
- />
58
+ <RadioCardGroup v-bind="args" v-model="selected" />
66
59
  <div class="text-sm text-muted-foreground">Selected: {{ selected }}</div>
67
60
  </div>
68
61
  `,
69
62
  }),
70
- }
63
+ } satisfies Meta<typeof RadioCardGroup>
64
+
65
+ export default meta
66
+ type Story = StoryObj<typeof meta>
67
+
68
+ export const Default: Story = {}
71
69
 
72
70
  export const WithDisabledOption: Story = {
73
- render: args => ({
74
- components: { RadioCardGroup },
75
- setup () {
76
- const selected = ref('pro')
77
- return { args, selected, manyOptions }
78
- },
79
- template: `
80
- <div class="max-w-md space-y-4">
81
- <RadioCardGroup
82
- v-model="selected"
83
- :options="manyOptions"
84
- :disabled="args.disabled"
85
- />
86
- <div class="text-sm text-muted-foreground">Selected: {{ selected }}</div>
87
- </div>
88
- `,
89
- }),
71
+ args: {
72
+ modelValue: 'pro',
73
+ options: planOptions,
74
+ },
75
+ }
76
+
77
+ export const Disabled: Story = {
78
+ args: {
79
+ disabled: true,
80
+ },
90
81
  }
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  RadioGroup,
4
4
  RadioGroupItem,
5
- } from '@polymarbot/nuxt-layer-shadcn-ui/app/components/shadcn/radio-group'
5
+ } from '../../shadcn/radio-group'
6
6
  import type { RadioCardGroupProps } from './types'
7
7
 
8
8
  const props = withDefaults(defineProps<RadioCardGroupProps>(), {
@@ -0,0 +1,123 @@
1
+ import type { Meta, StoryObj } from '@storybook/vue3'
2
+ import type { RadioGroupItem } from './types'
3
+ import RadioGroup from './index.vue'
4
+
5
+ const options: RadioGroupItem[] = [
6
+ { value: 'option1', label: 'Option 1' },
7
+ { value: 'option2', label: 'Option 2' },
8
+ { value: 'option3', label: 'Option 3' },
9
+ ]
10
+
11
+ const plans: RadioGroupItem[] = [
12
+ { value: 'free', label: 'Free - $0/month' },
13
+ { value: 'pro', label: 'Pro - $9/month' },
14
+ { value: 'enterprise', label: 'Enterprise - $29/month', disabled: true },
15
+ ]
16
+
17
+ const meta = {
18
+ title: 'UI/RadioGroup',
19
+ component: RadioGroup,
20
+ argTypes: {
21
+ items: { control: 'object' },
22
+ modelValue: { control: 'text' },
23
+ disabled: { control: 'boolean' },
24
+ orientation: { control: 'inline-radio', options: [ 'vertical', 'horizontal' ]},
25
+ },
26
+ args: {
27
+ items: options,
28
+ modelValue: 'option1',
29
+ disabled: false,
30
+ orientation: 'vertical',
31
+ },
32
+ render: args => ({
33
+ components: { RadioGroup },
34
+ setup: () => ({ args }),
35
+ template: '<RadioGroup v-bind="args" />',
36
+ }),
37
+ } satisfies Meta<typeof RadioGroup>
38
+
39
+ export default meta
40
+ type Story = StoryObj<typeof meta>
41
+
42
+ export const Default: Story = {}
43
+
44
+ export const Controlled: Story = {
45
+ render: () => ({
46
+ components: { RadioGroup },
47
+ setup () {
48
+ const selected = ref('option1')
49
+ return { options, selected }
50
+ },
51
+ template: `
52
+ <div class="space-y-2">
53
+ <RadioGroup v-model="selected" :items="options" />
54
+ <div class="text-sm text-muted-foreground">Selected: {{ selected }}</div>
55
+ </div>
56
+ `,
57
+ }),
58
+ }
59
+
60
+ export const Horizontal: Story = {
61
+ render: () => ({
62
+ components: { RadioGroup },
63
+ setup () {
64
+ const selected = ref('option1')
65
+ return { options, selected }
66
+ },
67
+ template: `
68
+ <div class="space-y-2">
69
+ <RadioGroup v-model="selected" :items="options" orientation="horizontal" />
70
+ <div class="text-sm text-muted-foreground">Selected: {{ selected }}</div>
71
+ </div>
72
+ `,
73
+ }),
74
+ }
75
+
76
+ export const WithDisabledItem: Story = {
77
+ render: () => ({
78
+ components: { RadioGroup },
79
+ setup () {
80
+ const plan = ref('pro')
81
+ return { plans, plan }
82
+ },
83
+ template: `
84
+ <div class="space-y-2">
85
+ <RadioGroup v-model="plan" :items="plans" />
86
+ <div class="text-sm text-muted-foreground">Plan: {{ plan }}</div>
87
+ </div>
88
+ `,
89
+ }),
90
+ }
91
+
92
+ export const Disabled: Story = {
93
+ render: () => ({
94
+ components: { RadioGroup },
95
+ setup () {
96
+ const selected = ref('option1')
97
+ return { options, selected }
98
+ },
99
+ template: '<RadioGroup v-model="selected" :items="options" disabled />',
100
+ }),
101
+ }
102
+
103
+ export const CustomSlots: Story = {
104
+ render: () => ({
105
+ components: { RadioGroup },
106
+ setup () {
107
+ const plan = ref('pro')
108
+ return { plans, plan }
109
+ },
110
+ template: `
111
+ <div class="space-y-2">
112
+ <RadioGroup v-model="plan" :items="plans">
113
+ <template #label="{ item, checked }">
114
+ <span :class="checked ? 'font-semibold text-primary' : 'text-foreground'">
115
+ {{ item.label }}
116
+ </span>
117
+ </template>
118
+ </RadioGroup>
119
+ <div class="text-sm text-muted-foreground">Plan: {{ plan }}</div>
120
+ </div>
121
+ `,
122
+ }),
123
+ }
@@ -0,0 +1,73 @@
1
+ <script setup lang="ts">
2
+ import {
3
+ RadioGroup as ShadcnRadioGroup,
4
+ RadioGroupItem as ShadcnRadioGroupItem,
5
+ } from '../../shadcn/radio-group'
6
+ import type { RadioGroupItem, RadioGroupProps } from './types'
7
+
8
+ const props = withDefaults(defineProps<RadioGroupProps>(), {
9
+ items: () => [],
10
+ modelValue: undefined,
11
+ disabled: false,
12
+ orientation: 'vertical',
13
+ class: undefined,
14
+ })
15
+
16
+ const emit = defineEmits<{
17
+ 'update:modelValue': [value: string]
18
+ }>()
19
+
20
+ defineSlots<{
21
+ label?: (props: { item: RadioGroupItem, checked: boolean }) => unknown
22
+ }>()
23
+
24
+ const model = computed({
25
+ get: () => props.modelValue,
26
+ set: value => {
27
+ if (value !== undefined) emit('update:modelValue', value)
28
+ },
29
+ })
30
+
31
+ const orientationClass = {
32
+ horizontal: 'flex-row flex-wrap items-center',
33
+ vertical: 'flex-col',
34
+ } as const
35
+
36
+ const mergedClass = computed(() => cn(
37
+ 'flex gap-3',
38
+ orientationClass[props.orientation],
39
+ props.class,
40
+ ))
41
+ </script>
42
+
43
+ <template>
44
+ <ShadcnRadioGroup
45
+ v-model="model"
46
+ :disabled="disabled"
47
+ :orientation="orientation"
48
+ :class="mergedClass"
49
+ >
50
+ <label
51
+ v-for="item in items"
52
+ :key="item.value"
53
+ class="
54
+ flex cursor-pointer items-center gap-2
55
+ has-data-disabled:cursor-not-allowed has-data-disabled:opacity-50
56
+ "
57
+ >
58
+ <ShadcnRadioGroupItem
59
+ :value="item.value"
60
+ :disabled="item.disabled"
61
+ />
62
+ <span class="text-sm">
63
+ <slot
64
+ name="label"
65
+ :item="item"
66
+ :checked="model === item.value"
67
+ >
68
+ {{ item.label ?? item.value }}
69
+ </slot>
70
+ </span>
71
+ </label>
72
+ </ShadcnRadioGroup>
73
+ </template>
@@ -0,0 +1,13 @@
1
+ export interface RadioGroupItem {
2
+ value: string
3
+ label?: string
4
+ disabled?: boolean
5
+ }
6
+
7
+ export interface RadioGroupProps {
8
+ modelValue?: string
9
+ items?: RadioGroupItem[]
10
+ disabled?: boolean
11
+ orientation?: 'vertical' | 'horizontal'
12
+ class?: ClassValue
13
+ }
@@ -1,65 +1,97 @@
1
1
  import type { Meta, StoryObj } from '@storybook/vue3'
2
2
  import ScrollArea from './index.vue'
3
3
 
4
+ const types = [ 'auto', 'always', 'scroll', 'hover' ] as const
5
+
4
6
  const meta = {
5
7
  title: 'UI/ScrollArea',
6
8
  component: ScrollArea,
7
9
  argTypes: {
8
10
  fadeMask: { control: 'boolean' },
11
+ type: { control: 'select', options: types },
12
+ dir: { control: 'select', options: [ 'ltr', 'rtl' ]},
13
+ scrollHideDelay: { control: 'number' },
9
14
  },
10
15
  args: {
11
16
  fadeMask: false,
17
+ type: 'hover',
18
+ dir: 'ltr',
19
+ scrollHideDelay: 600,
12
20
  },
21
+ render: args => ({
22
+ components: { ScrollArea },
23
+ setup () {
24
+ const items = Array.from({ length: 30 }, (_, i) => `Item ${i + 1}`)
25
+ return { args, items }
26
+ },
27
+ template: `
28
+ <div class="h-[250px] w-[250px] rounded-md border bg-card">
29
+ <ScrollArea class="h-full" v-bind="args">
30
+ <div class="p-4 space-y-2">
31
+ <div
32
+ v-for="item in items"
33
+ :key="item"
34
+ class="rounded-md border bg-muted px-3 py-2 text-sm"
35
+ >
36
+ {{ item }}
37
+ </div>
38
+ </div>
39
+ </ScrollArea>
40
+ </div>
41
+ `,
42
+ }),
13
43
  } satisfies Meta<typeof ScrollArea>
14
44
 
15
45
  export default meta
16
46
  type Story = StoryObj<typeof meta>
17
47
 
18
- export const Default: Story = {
19
- render: args => ({
48
+ export const Default: Story = {}
49
+
50
+ export const FadeMask: Story = {
51
+ render: () => ({
20
52
  components: { ScrollArea },
21
53
  setup () {
22
54
  const items = Array.from({ length: 30 }, (_, i) => `Item ${i + 1}`)
23
- const fewItems = Array.from({ length: 3 }, (_, i) => `Item ${i + 1}`)
24
- return { args, items, fewItems }
55
+ return { items }
25
56
  },
26
57
  template: `
27
- <div class="space-y-10">
28
- <!-- Controlled -->
29
- <section>
30
- <h3 class="mb-4 text-lg font-medium">Controlled</h3>
31
- <div class="h-[250px] w-[250px] rounded-md border bg-card">
32
- <ScrollArea class="h-full" v-bind="args">
33
- <div class="p-4 space-y-2">
34
- <div
35
- v-for="item in items"
36
- :key="item"
37
- class="rounded-md border bg-muted px-3 py-2 text-sm"
38
- >
39
- {{ item }}
40
- </div>
41
- </div>
42
- </ScrollArea>
58
+ <div class="h-[250px] w-[250px] rounded-md border bg-card">
59
+ <ScrollArea class="h-full" fadeMask>
60
+ <div class="p-4 space-y-2">
61
+ <div
62
+ v-for="item in items"
63
+ :key="item"
64
+ class="rounded-md border bg-muted px-3 py-2 text-sm"
65
+ >
66
+ {{ item }}
67
+ </div>
43
68
  </div>
44
- </section>
69
+ </ScrollArea>
70
+ </div>
71
+ `,
72
+ }),
73
+ }
45
74
 
46
- <!-- No Overflow -->
47
- <section>
48
- <h3 class="mb-4 text-lg font-medium">No Overflow</h3>
49
- <div class="h-[250px] w-[250px] rounded-md border bg-card">
50
- <ScrollArea class="h-full" fadeMask>
51
- <div class="p-4 space-y-2">
52
- <div
53
- v-for="item in fewItems"
54
- :key="item"
55
- class="rounded-md border bg-muted px-3 py-2 text-sm"
56
- >
57
- {{ item }}
58
- </div>
59
- </div>
60
- </ScrollArea>
75
+ export const NoOverflow: Story = {
76
+ render: () => ({
77
+ components: { ScrollArea },
78
+ setup () {
79
+ const fewItems = Array.from({ length: 3 }, (_, i) => `Item ${i + 1}`)
80
+ return { fewItems }
81
+ },
82
+ template: `
83
+ <div class="h-[250px] w-[250px] rounded-md border bg-card">
84
+ <ScrollArea class="h-full" fadeMask>
85
+ <div class="p-4 space-y-2">
86
+ <div
87
+ v-for="item in fewItems"
88
+ :key="item"
89
+ class="rounded-md border bg-muted px-3 py-2 text-sm"
90
+ >
91
+ {{ item }}
92
+ </div>
61
93
  </div>
62
- </section>
94
+ </ScrollArea>
63
95
  </div>
64
96
  `,
65
97
  }),
@@ -1,7 +1,7 @@
1
1
  <script setup lang="ts">
2
2
  import {
3
3
  ScrollArea as ShadcnScrollArea,
4
- } from '@polymarbot/nuxt-layer-shadcn-ui/app/components/shadcn/scroll-area'
4
+ } from '../../shadcn/scroll-area'
5
5
  import { useResizeObserver } from '@vueuse/core'
6
6
  import type { ScrollAreaProps } from './types'
7
7
 
@@ -31,95 +31,133 @@ function mockLoadValueOptionMethod (value: string) {
31
31
  })
32
32
  }
33
33
 
34
+ const defaultOptions = [
35
+ { label: 'All Items', value: 'all' },
36
+ { label: 'Featured', value: 'featured' },
37
+ ]
38
+
34
39
  const meta = {
35
40
  title: 'UI/SearchSelect',
36
41
  component: SearchSelect as any,
37
42
  argTypes: {
43
+ placeholder: { control: 'text' },
44
+ searchPlaceholder: { control: 'text' },
45
+ emptyText: { control: 'text' },
46
+ searchEmptyText: { control: 'text' },
47
+ createNewTo: { control: 'text' },
48
+ createNewText: { control: 'text' },
49
+ loadLimit: { control: 'number' },
38
50
  autoLoad: { control: 'boolean' },
39
51
  disabled: { control: 'boolean' },
40
52
  },
41
53
  args: {
54
+ placeholder: '',
55
+ searchPlaceholder: '',
56
+ emptyText: '',
57
+ searchEmptyText: '',
58
+ createNewTo: '',
59
+ createNewText: '',
60
+ loadLimit: 20,
42
61
  autoLoad: false,
43
62
  disabled: false,
44
63
  },
64
+ render: args => ({
65
+ components: { SearchSelect },
66
+ setup () {
67
+ const value = ref<string>()
68
+ return { args, value, mockLoadMethod }
69
+ },
70
+ template: `
71
+ <div class="max-w-sm">
72
+ <SearchSelect
73
+ v-model="value"
74
+ :loadMethod="mockLoadMethod"
75
+ v-bind="args"
76
+ />
77
+ <div class="mt-2 text-sm text-muted-foreground">Selected: {{ value ?? 'none' }}</div>
78
+ </div>
79
+ `,
80
+ }),
45
81
  } satisfies Meta
46
82
 
47
83
  export default meta
48
84
  type Story = StoryObj<typeof meta>
49
85
 
50
- export const Default: Story = {
51
- render: args => ({
86
+ export const Default: Story = {}
87
+
88
+ export const Preselected: Story = {
89
+ render: () => ({
52
90
  components: { SearchSelect },
53
91
  setup () {
54
- const selected = ref<string>()
55
- const withPreselect = ref<string>('item-42')
56
- const withDefaults = ref<string>()
57
- const withCreateNew = ref<string>()
58
-
59
- const defaultOptions = [
60
- { label: 'All Items', value: 'all' },
61
- { label: 'Featured', value: 'featured' },
62
- ]
63
-
64
- return {
65
- args,
66
- selected,
67
- withPreselect,
68
- withDefaults,
69
- withCreateNew,
70
- defaultOptions,
71
- mockLoadMethod,
72
- mockLoadValueOptionMethod,
73
- }
92
+ const value = ref<string>('item-42')
93
+ return { value, mockLoadMethod, mockLoadValueOptionMethod }
74
94
  },
75
95
  template: `
76
- <div class="space-y-10 max-w-sm">
77
- <!-- Controlled -->
78
- <section>
79
- <h3 class="mb-4 text-lg font-medium">Controlled</h3>
80
- <SearchSelect
81
- v-model="selected"
82
- :loadMethod="mockLoadMethod"
83
- v-bind="args"
84
- />
85
- <div class="mt-2 text-sm text-muted-foreground">Selected: {{ selected ?? 'none' }}</div>
86
- </section>
96
+ <div class="max-w-sm">
97
+ <SearchSelect
98
+ v-model="value"
99
+ :loadMethod="mockLoadMethod"
100
+ :loadValueOptionMethod="mockLoadValueOptionMethod"
101
+ autoLoad
102
+ />
103
+ <div class="mt-2 text-sm text-muted-foreground">Selected: {{ value ?? 'none' }}</div>
104
+ </div>
105
+ `,
106
+ }),
107
+ }
87
108
 
88
- <!-- Pre-selected Value -->
89
- <section>
90
- <h3 class="mb-4 text-lg font-medium">Pre-selected Value (item-42)</h3>
91
- <SearchSelect
92
- v-model="withPreselect"
93
- :loadMethod="mockLoadMethod"
94
- :loadValueOptionMethod="mockLoadValueOptionMethod"
95
- autoLoad
96
- />
97
- <div class="mt-2 text-sm text-muted-foreground">Selected: {{ withPreselect ?? 'none' }}</div>
98
- </section>
109
+ export const WithDefaultOptions: Story = {
110
+ render: () => ({
111
+ components: { SearchSelect },
112
+ setup () {
113
+ const value = ref<string>()
114
+ return { value, mockLoadMethod, defaultOptions }
115
+ },
116
+ template: `
117
+ <div class="max-w-sm">
118
+ <SearchSelect
119
+ v-model="value"
120
+ :loadMethod="mockLoadMethod"
121
+ :defaultOptions="defaultOptions"
122
+ autoLoad
123
+ />
124
+ <div class="mt-2 text-sm text-muted-foreground">Selected: {{ value ?? 'none' }}</div>
125
+ </div>
126
+ `,
127
+ }),
128
+ }
99
129
 
100
- <!-- With Default Options -->
101
- <section>
102
- <h3 class="mb-4 text-lg font-medium">With Default Options</h3>
103
- <SearchSelect
104
- v-model="withDefaults"
105
- :loadMethod="mockLoadMethod"
106
- :defaultOptions="defaultOptions"
107
- autoLoad
108
- />
109
- <div class="mt-2 text-sm text-muted-foreground">Selected: {{ withDefaults ?? 'none' }}</div>
110
- </section>
130
+ export const WithCreateNew: Story = {
131
+ render: () => ({
132
+ components: { SearchSelect },
133
+ setup () {
134
+ const value = ref<string>()
135
+ return { value, mockLoadMethod }
136
+ },
137
+ template: `
138
+ <div class="max-w-sm">
139
+ <SearchSelect
140
+ v-model="value"
141
+ :loadMethod="mockLoadMethod"
142
+ createNewTo="/create"
143
+ autoLoad
144
+ />
145
+ <div class="mt-2 text-sm text-muted-foreground">Selected: {{ value ?? 'none' }}</div>
146
+ </div>
147
+ `,
148
+ }),
149
+ }
111
150
 
112
- <!-- With Create New -->
113
- <section>
114
- <h3 class="mb-4 text-lg font-medium">With Create New</h3>
115
- <SearchSelect
116
- v-model="withCreateNew"
117
- :loadMethod="mockLoadMethod"
118
- createNewTo="/create"
119
- autoLoad
120
- />
121
- <div class="mt-2 text-sm text-muted-foreground">Selected: {{ withCreateNew ?? 'none' }}</div>
122
- </section>
151
+ export const Disabled: Story = {
152
+ render: () => ({
153
+ components: { SearchSelect },
154
+ setup () {
155
+ const value = ref<string>()
156
+ return { value, mockLoadMethod }
157
+ },
158
+ template: `
159
+ <div class="max-w-sm">
160
+ <SearchSelect v-model="value" :loadMethod="mockLoadMethod" disabled />
123
161
  </div>
124
162
  `,
125
163
  }),