@300codes/design-system 1.0.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 (47) hide show
  1. package/README.md +155 -0
  2. package/package.json +63 -0
  3. package/src/components/BaseIcon/BaseIcon.stories.ts +66 -0
  4. package/src/components/BaseIcon/BaseIcon.vue +96 -0
  5. package/src/components/BaseIcon/index.ts +2 -0
  6. package/src/components/BaseLabel/BaseLabel.stories.ts +114 -0
  7. package/src/components/BaseLabel/BaseLabel.vue +149 -0
  8. package/src/components/BaseLabel/index.ts +2 -0
  9. package/src/components/BaseTooltip/BaseTooltip.stories.ts +113 -0
  10. package/src/components/BaseTooltip/BaseTooltip.vue +123 -0
  11. package/src/components/BaseTooltip/index.ts +2 -0
  12. package/src/components/ButtonWithIcon/ButtonWithIcon.stories.ts +149 -0
  13. package/src/components/ButtonWithIcon/ButtonWithIcon.vue +77 -0
  14. package/src/components/ButtonWithIcon/index.ts +2 -0
  15. package/src/components/CheckboxInput/CheckboxInput.stories.ts +99 -0
  16. package/src/components/CheckboxInput/CheckboxInput.vue +176 -0
  17. package/src/components/CheckboxInput/index.ts +2 -0
  18. package/src/components/LabelInput/LabelInput.vue +111 -0
  19. package/src/components/LabelInput/index.ts +2 -0
  20. package/src/components/RadioInput/RadioInput.stories.ts +114 -0
  21. package/src/components/RadioInput/RadioInput.vue +174 -0
  22. package/src/components/RadioInput/index.ts +2 -0
  23. package/src/components/SearchInput/SearchInput.stories.ts +103 -0
  24. package/src/components/SearchInput/SearchInput.vue +83 -0
  25. package/src/components/SearchInput/index.ts +2 -0
  26. package/src/components/SelectInput/SelectInput.stories.ts +111 -0
  27. package/src/components/SelectInput/SelectInput.vue +497 -0
  28. package/src/components/SelectInput/index.ts +2 -0
  29. package/src/components/SelectInputField/SelectInputField.stories.ts +141 -0
  30. package/src/components/SelectInputField/SelectInputField.vue +64 -0
  31. package/src/components/SelectInputField/index.ts +2 -0
  32. package/src/components/SimpleButton/SimpleButton.stories.ts +143 -0
  33. package/src/components/SimpleButton/SimpleButton.vue +193 -0
  34. package/src/components/SimpleButton/index.ts +2 -0
  35. package/src/components/TabsList/TabsList.stories.ts +83 -0
  36. package/src/components/TabsList/TabsList.vue +156 -0
  37. package/src/components/TabsList/index.ts +2 -0
  38. package/src/components/TextInput/TextInput.stories.ts +125 -0
  39. package/src/components/TextInput/TextInput.vue +273 -0
  40. package/src/components/TextInput/components/InputIconButton.vue +54 -0
  41. package/src/components/TextInput/index.ts +2 -0
  42. package/src/components/TextInputField/TextInputField.stories.ts +133 -0
  43. package/src/components/TextInputField/TextInputField.vue +93 -0
  44. package/src/components/TextInputField/index.ts +2 -0
  45. package/src/components/index.ts +15 -0
  46. package/src/css/tokens.css +417 -0
  47. package/src/types/icon.ts +1 -0
@@ -0,0 +1,141 @@
1
+ import { ref } from 'vue';
2
+ import type { Meta, StoryObj } from '@storybook/vue3-vite';
3
+ import type { ConcreteComponent } from 'vue';
4
+ import type { SelectInputFieldProps } from './SelectInputField.vue';
5
+ import SelectInputField from './SelectInputField.vue';
6
+
7
+ const OPTIONS = [
8
+ { value: 'pl', label: 'Poland' },
9
+ { value: 'de', label: 'Germany' },
10
+ { value: 'fr', label: 'France' },
11
+ { value: 'es', label: 'Spain' },
12
+ { value: 'it', label: 'Italy' },
13
+ ];
14
+
15
+ const meta: Meta<SelectInputFieldProps> = {
16
+ title: 'Form/SelectInputField',
17
+ component: SelectInputField as unknown as ConcreteComponent<SelectInputFieldProps>,
18
+ tags: ['autodocs'],
19
+ decorators: [
20
+ () => ({ template: '<div style="max-width: 25rem; width: 100%;"><story /></div>' }),
21
+ ],
22
+ argTypes: {
23
+ size: { control: 'select', options: ['sm', 'md', 'lg'] },
24
+ invalid: { control: 'boolean' },
25
+ required: { control: 'boolean' },
26
+ disabled: { control: 'boolean' },
27
+ },
28
+ };
29
+
30
+ export default meta;
31
+ type Story = StoryObj<SelectInputFieldProps>;
32
+
33
+ export const Default: Story = {
34
+ args: {
35
+ name: 'country',
36
+ label: 'Country',
37
+ options: OPTIONS,
38
+ placeholder: 'Select country',
39
+ size: 'md',
40
+ },
41
+ render: (args: SelectInputFieldProps) => ({
42
+ components: { SelectInputField },
43
+ setup() {
44
+ const value = ref('');
45
+ return { args, value };
46
+ },
47
+ template: '<SelectInputField v-bind="args" v-model="value" />',
48
+ }),
49
+ };
50
+
51
+ export const WithMessage: Story = {
52
+ args: {
53
+ name: 'country',
54
+ label: 'Country',
55
+ options: OPTIONS,
56
+ placeholder: 'Select country',
57
+ message: 'Please select a country',
58
+ invalid: true,
59
+ },
60
+ render: (args: SelectInputFieldProps) => ({
61
+ components: { SelectInputField },
62
+ setup() {
63
+ const value = ref('');
64
+ return { args, value };
65
+ },
66
+ template: '<SelectInputField v-bind="args" v-model="value" />',
67
+ }),
68
+ };
69
+
70
+ export const Valid: Story = {
71
+ args: {
72
+ name: 'country',
73
+ label: 'Country',
74
+ options: OPTIONS,
75
+ placeholder: 'Select country',
76
+ invalid: false,
77
+ },
78
+ render: (args: SelectInputFieldProps) => ({
79
+ components: { SelectInputField },
80
+ setup() {
81
+ const value = ref('de');
82
+ return { args, value };
83
+ },
84
+ template: '<SelectInputField v-bind="args" v-model="value" />',
85
+ }),
86
+ };
87
+
88
+ export const Required: Story = {
89
+ args: {
90
+ name: 'country',
91
+ label: 'Country',
92
+ options: OPTIONS,
93
+ placeholder: 'Select country',
94
+ required: true,
95
+ },
96
+ render: (args: SelectInputFieldProps) => ({
97
+ components: { SelectInputField },
98
+ setup() {
99
+ const value = ref('');
100
+ return { args, value };
101
+ },
102
+ template: '<SelectInputField v-bind="args" v-model="value" />',
103
+ }),
104
+ };
105
+
106
+ export const Disabled: Story = {
107
+ args: {
108
+ name: 'country',
109
+ label: 'Country',
110
+ options: OPTIONS,
111
+ placeholder: 'Select country',
112
+ disabled: true,
113
+ },
114
+ render: (args: SelectInputFieldProps) => ({
115
+ components: { SelectInputField },
116
+ setup() {
117
+ const value = ref('pl');
118
+ return { args, value };
119
+ },
120
+ template: '<SelectInputField v-bind="args" v-model="value" />',
121
+ }),
122
+ };
123
+
124
+ export const Sizes: Story = {
125
+ render: () => ({
126
+ components: { SelectInputField },
127
+ setup() {
128
+ const sm = ref('');
129
+ const md = ref('');
130
+ const lg = ref('');
131
+ return { sm, md, lg, OPTIONS };
132
+ },
133
+ template: `
134
+ <div class="flex flex-col gap-4 w-80">
135
+ <SelectInputField name="sm" label="Small" size="sm" placeholder="Select..." :options="OPTIONS" v-model="sm" />
136
+ <SelectInputField name="md" label="Medium" size="md" placeholder="Select..." :options="OPTIONS" v-model="md" />
137
+ <SelectInputField name="lg" label="Large" size="lg" placeholder="Select..." :options="OPTIONS" v-model="lg" />
138
+ </div>
139
+ `,
140
+ }),
141
+ };
@@ -0,0 +1,64 @@
1
+ <script setup lang="ts">
2
+ import { computed } from 'vue';
3
+ import SelectInput from '../SelectInput/SelectInput.vue';
4
+ import LabelInput from '../LabelInput/LabelInput.vue';
5
+ import type { SelectOption } from '../SelectInput/SelectInput.vue';
6
+
7
+ export interface SelectInputFieldProps {
8
+ name: string;
9
+ label: string;
10
+ id?: string;
11
+ options: readonly SelectOption[];
12
+ placeholder?: string;
13
+ mobileTitle?: string;
14
+ message?: string;
15
+ invalid?: boolean | null;
16
+ required?: boolean;
17
+ disabled?: boolean;
18
+ size?: 'sm' | 'md' | 'lg';
19
+ hasStatus?: boolean;
20
+ }
21
+
22
+ const props = withDefaults(defineProps<SelectInputFieldProps>(), {
23
+ id: undefined,
24
+ placeholder: '',
25
+ mobileTitle: undefined,
26
+ size: 'md',
27
+ invalid: null,
28
+ message: '',
29
+ disabled: false,
30
+ hasStatus: false,
31
+ });
32
+
33
+ const model = defineModel<string>({ required: true });
34
+
35
+ const selectInvalid = computed(() =>
36
+ typeof props.invalid === 'boolean' ? props.invalid : undefined,
37
+ );
38
+ </script>
39
+
40
+ <template>
41
+ <LabelInput
42
+ :name="id || name"
43
+ :label="label"
44
+ :message="message"
45
+ :required="required"
46
+ :invalid="invalid"
47
+ :disabled="disabled"
48
+ :size="size"
49
+ :has-status="hasStatus"
50
+ >
51
+ <SelectInput
52
+ :id="id"
53
+ v-model="model"
54
+ :name="name"
55
+ :options="options"
56
+ :placeholder="placeholder"
57
+ :mobile-title="mobileTitle"
58
+ :invalid="selectInvalid"
59
+ :required="required"
60
+ :disabled="disabled"
61
+ :size="size"
62
+ />
63
+ </LabelInput>
64
+ </template>
@@ -0,0 +1,2 @@
1
+ export { default as SelectInputField } from './SelectInputField.vue';
2
+ export type { SelectInputFieldProps } from './SelectInputField.vue';
@@ -0,0 +1,143 @@
1
+ import type { Meta, StoryObj } from '@storybook/vue3-vite';
2
+ import type { ConcreteComponent } from 'vue';
3
+ import type { SimpleButtonProps } from './SimpleButton.vue';
4
+ import SimpleButton from './SimpleButton.vue';
5
+
6
+ const meta: Meta<SimpleButtonProps> = {
7
+ title: 'Components/SimpleButton',
8
+ component: SimpleButton as unknown as ConcreteComponent<SimpleButtonProps>,
9
+ tags: ['autodocs'],
10
+ argTypes: {
11
+ variant: {
12
+ control: 'select',
13
+ options: ['primary', 'secondary', 'tertiary'],
14
+ },
15
+ size: {
16
+ control: 'select',
17
+ options: ['sm', 'md'],
18
+ },
19
+ type: {
20
+ control: 'select',
21
+ options: ['button', 'submit', 'reset'],
22
+ },
23
+ loading: { control: 'boolean' },
24
+ full: { control: 'boolean' },
25
+ disabled: { control: 'boolean' },
26
+ href: { control: 'text' },
27
+ target: { control: 'text' },
28
+ rel: { control: 'text' },
29
+ },
30
+ };
31
+
32
+ export default meta;
33
+ type Story = StoryObj<SimpleButtonProps>;
34
+
35
+ export const Primary: Story = {
36
+ args: { variant: 'primary', size: 'md' },
37
+ render: (args: SimpleButtonProps) => ({
38
+ components: { SimpleButton },
39
+ setup() {
40
+ return { args };
41
+ },
42
+ template: '<SimpleButton v-bind="args">Button label</SimpleButton>',
43
+ }),
44
+ };
45
+
46
+ export const Secondary: Story = {
47
+ args: { variant: 'secondary', size: 'md' },
48
+ render: (args: SimpleButtonProps) => ({
49
+ components: { SimpleButton },
50
+ setup() {
51
+ return { args };
52
+ },
53
+ template: '<SimpleButton v-bind="args">Button label</SimpleButton>',
54
+ }),
55
+ };
56
+
57
+ export const Tertiary: Story = {
58
+ args: { variant: 'tertiary', size: 'md' },
59
+ render: (args: SimpleButtonProps) => ({
60
+ components: { SimpleButton },
61
+ setup() {
62
+ return { args };
63
+ },
64
+ template: '<SimpleButton v-bind="args">Button label</SimpleButton>',
65
+ }),
66
+ };
67
+
68
+ export const Loading: Story = {
69
+ args: { variant: 'primary', size: 'md', loading: true },
70
+ render: (args: SimpleButtonProps) => ({
71
+ components: { SimpleButton },
72
+ setup() {
73
+ return { args };
74
+ },
75
+ template: '<SimpleButton v-bind="args">Button label</SimpleButton>',
76
+ }),
77
+ };
78
+
79
+ export const Disabled: Story = {
80
+ args: { variant: 'primary', size: 'md', disabled: true },
81
+ render: (args: SimpleButtonProps) => ({
82
+ components: { SimpleButton },
83
+ setup() {
84
+ return { args };
85
+ },
86
+ template: '<SimpleButton v-bind="args">Button label</SimpleButton>',
87
+ }),
88
+ };
89
+
90
+ export const AsLink: Story = {
91
+ args: {
92
+ variant: 'primary',
93
+ size: 'md',
94
+ href: 'https://example.com',
95
+ target: '_blank',
96
+ rel: 'noopener noreferrer',
97
+ } satisfies SimpleButtonProps,
98
+ render: (args: SimpleButtonProps) => ({
99
+ components: { SimpleButton },
100
+ setup() {
101
+ return { args };
102
+ },
103
+ template: '<SimpleButton v-bind="args">Open link</SimpleButton>',
104
+ }),
105
+ };
106
+
107
+ export const AsButtonSubmit: Story = {
108
+ args: {
109
+ variant: 'primary',
110
+ size: 'md',
111
+ type: 'submit',
112
+ } satisfies SimpleButtonProps,
113
+ render: (args: SimpleButtonProps) => ({
114
+ components: { SimpleButton },
115
+ setup() {
116
+ return { args };
117
+ },
118
+ template: '<SimpleButton v-bind="args">Submit form</SimpleButton>',
119
+ }),
120
+ };
121
+
122
+ export const FullWidth: Story = {
123
+ args: { variant: 'primary', size: 'md', full: true },
124
+ render: (args: SimpleButtonProps) => ({
125
+ components: { SimpleButton },
126
+ setup() {
127
+ return { args };
128
+ },
129
+ template: '<SimpleButton v-bind="args">Full width</SimpleButton>',
130
+ }),
131
+ };
132
+
133
+ export const Sizes: Story = {
134
+ render: () => ({
135
+ components: { SimpleButton },
136
+ template: `
137
+ <div class="flex items-center gap-4">
138
+ <SimpleButton size="sm">Small</SimpleButton>
139
+ <SimpleButton size="md">Medium</SimpleButton>
140
+ </div>
141
+ `,
142
+ }),
143
+ };
@@ -0,0 +1,193 @@
1
+ <script setup lang="ts">
2
+ import { computed } from 'vue';
3
+ import type { AnchorHTMLAttributes, ButtonHTMLAttributes } from 'vue';
4
+
5
+ export interface SimpleButtonProps {
6
+ variant?: 'primary' | 'secondary' | 'tertiary';
7
+ size?: 'sm' | 'md';
8
+ loading?: boolean;
9
+ full?: boolean;
10
+ disabled?: boolean;
11
+ href?: string;
12
+ type?: ButtonHTMLAttributes['type'];
13
+ name?: ButtonHTMLAttributes['name'];
14
+ value?: ButtonHTMLAttributes['value'];
15
+ target?: AnchorHTMLAttributes['target'];
16
+ rel?: AnchorHTMLAttributes['rel'];
17
+ download?: AnchorHTMLAttributes['download'];
18
+ ariaLabel?: string;
19
+ }
20
+
21
+ const props = withDefaults(defineProps<SimpleButtonProps>(), {
22
+ variant: 'primary',
23
+ size: 'md',
24
+ loading: false,
25
+ full: false,
26
+ disabled: false,
27
+ href: undefined,
28
+ type: undefined,
29
+ name: undefined,
30
+ value: undefined,
31
+ target: undefined,
32
+ rel: undefined,
33
+ download: undefined,
34
+ ariaLabel: undefined,
35
+ });
36
+
37
+ const tag = computed(() => (props.href ? 'a' : 'button'));
38
+
39
+ const nativeAttrs = computed((): Record<string, unknown> => {
40
+ if (props.href) {
41
+ const isInactive = props.disabled || props.loading;
42
+ return {
43
+ href: isInactive ? undefined : props.href,
44
+ target: props.target,
45
+ rel: props.rel,
46
+ download: props.download,
47
+ 'aria-disabled': isInactive ? 'true' : undefined,
48
+ 'aria-label': props.ariaLabel,
49
+ tabindex: isInactive ? -1 : undefined,
50
+ };
51
+ }
52
+ return {
53
+ type: props.type ?? 'button',
54
+ disabled: props.disabled || props.loading,
55
+ name: props.name,
56
+ value: props.value,
57
+ 'aria-label': props.ariaLabel,
58
+ };
59
+ });
60
+ </script>
61
+
62
+ <template>
63
+ <component
64
+ :is="tag"
65
+ v-bind="nativeAttrs"
66
+ :aria-busy="props.loading ? 'true' : undefined"
67
+ :class="[
68
+ 'simpleButton',
69
+ `simpleButton--${props.variant}`,
70
+ `simpleButton--${props.size}`,
71
+ 'outline-offset-2 relative inline-flex items-center justify-center select-none cursor-pointer',
72
+ {
73
+ 'w-full': props.full,
74
+ 'simpleButton--loading': props.loading,
75
+ 'simpleButton--disabled': props.disabled || props.loading,
76
+ },
77
+ ]"
78
+ >
79
+ <slot />
80
+ </component>
81
+ </template>
82
+
83
+ <style scoped>
84
+ @reference "tailwindcss";
85
+
86
+ .simpleButton {
87
+ --_fg: var(--simpleButton-fg, #ffffff);
88
+ background-color: var(--simpleButton-bg, #0024d6);
89
+ color: var(--_fg);
90
+ border: var(--simpleButton-border-width, 1px) solid var(--simpleButton-border, #0024d6);
91
+ border-radius: var(--simpleButton-radius, 3.5rem);
92
+ padding: var(--simpleButton-py, 0.375rem) var(--simpleButton-px, 1.5rem);
93
+ min-height: var(--simpleButton-min-h, 3.5rem);
94
+ font-size: var(--simpleButton-font-size, 1rem);
95
+ font-weight: var(--simpleButton-font-weight, 600);
96
+ line-height: 1.2;
97
+ gap: var(--simpleButton-gap, 1rem);
98
+ }
99
+
100
+ .simpleButton:hover:not(.simpleButton--disabled) {
101
+ background-color: var(--simpleButton-bg-hover, #0e161b);
102
+ color: var(--simpleButton-fg-hover, var(--_fg));
103
+ border-color: var(--simpleButton-border-hover, #0e161b);
104
+ }
105
+
106
+ .simpleButton:focus-visible {
107
+ outline: 2px solid var(--simpleButton-ring, #0066cc);
108
+ }
109
+
110
+ .simpleButton--disabled {
111
+ --_fg: var(--simpleButton-disabled-fg, #89979f);
112
+ background-color: var(--simpleButton-disabled-bg, #f3f5f7);
113
+ color: var(--_fg);
114
+ border-color: var(--simpleButton-disabled-border, #f3f5f7);
115
+
116
+ @apply cursor-not-allowed pointer-events-none;
117
+ }
118
+
119
+ /* ── secondary ── */
120
+
121
+ .simpleButton--secondary {
122
+ --_fg: var(--simpleButton-secondary-fg, #0e161b);
123
+ background-color: var(--simpleButton-secondary-bg, #f3f5f7);
124
+ color: var(--_fg);
125
+ border-color: var(--simpleButton-secondary-border, #f3f5f7);
126
+ }
127
+
128
+ .simpleButton--secondary:hover:not(.simpleButton--disabled) {
129
+ background-color: var(--simpleButton-secondary-bg-hover, #0e161b);
130
+ color: var(--simpleButton-secondary-fg-hover, #ffffff);
131
+ border-color: var(--simpleButton-secondary-border-hover, #0e161b);
132
+ }
133
+
134
+ .simpleButton--secondary:focus-visible {
135
+ outline: 2px solid var(--simpleButton-secondary-ring, #0066cc);
136
+ }
137
+
138
+ .simpleButton--secondary.simpleButton--disabled {
139
+ --_fg: var(--simpleButton-secondary-disabled-fg, #89979f);
140
+ background-color: var(--simpleButton-secondary-disabled-bg, #f3f5f7);
141
+ color: var(--_fg);
142
+ border-color: var(--simpleButton-secondary-disabled-border, #f3f5f7);
143
+ }
144
+
145
+ /* ── tertiary ── */
146
+
147
+ .simpleButton--tertiary {
148
+ --_fg: var(--simpleButton-tertiary-fg, #0e161b);
149
+ background-color: var(--simpleButton-tertiary-bg, transparent);
150
+ color: var(--_fg);
151
+ border-color: var(--simpleButton-tertiary-border, transparent);
152
+ }
153
+
154
+ .simpleButton--tertiary:hover:not(.simpleButton--disabled) {
155
+ background-color: var(--simpleButton-tertiary-bg-hover, #f3f4f6);
156
+ color: var(--simpleButton-tertiary-fg-hover, var(--_fg));
157
+ border-color: var(--simpleButton-tertiary-border-hover, #f3f4f6);
158
+ }
159
+
160
+ .simpleButton--tertiary:focus-visible {
161
+ outline: 2px solid var(--simpleButton-tertiary-ring, #0066cc);
162
+ }
163
+
164
+ .simpleButton--tertiary.simpleButton--disabled {
165
+ --_fg: var(--simpleButton-tertiary-disabled-fg, #89979f);
166
+ background-color: var(--simpleButton-tertiary-disabled-bg, transparent);
167
+ color: var(--_fg);
168
+ border-color: var(--simpleButton-tertiary-disabled-border, transparent);
169
+ }
170
+
171
+ /* ── sm ── */
172
+
173
+ .simpleButton--sm {
174
+ padding: var(--simpleButton-sm-py, 0.25rem) var(--simpleButton-sm-px, 1rem);
175
+ font-size: var(--simpleButton-sm-font-size, 0.875rem);
176
+ font-weight: var(--simpleButton-sm-font-weight, 600);
177
+ min-height: var(--simpleButton-sm-min-h, 2.5rem);
178
+ gap: var(--simpleButton-sm-gap, 0.625rem);
179
+ }
180
+
181
+ /* ── loading ── */
182
+
183
+ .simpleButton--loading {
184
+ color: transparent !important;
185
+ }
186
+
187
+ .simpleButton--loading::after {
188
+ content: '';
189
+ border-color: var(--_fg);
190
+
191
+ @apply absolute top-1/2 left-1/2 w-4 h-4 -mt-2 -ml-2 border-2 border-solid border-t-transparent border-b-transparent rounded-full animate-spin;
192
+ }
193
+ </style>
@@ -0,0 +1,2 @@
1
+ export { default as SimpleButton } from './SimpleButton.vue';
2
+ export type { SimpleButtonProps } from './SimpleButton.vue';
@@ -0,0 +1,83 @@
1
+ import type { Meta, StoryObj } from '@storybook/vue3-vite';
2
+ import type { ConcreteComponent } from 'vue';
3
+ import { ref } from 'vue';
4
+ import type { TabsListProps } from './TabsList.vue';
5
+ import TabsList from './TabsList.vue';
6
+
7
+ const meta: Meta<TabsListProps> = {
8
+ title: 'Components/TabsList',
9
+ component: TabsList as unknown as ConcreteComponent<TabsListProps>,
10
+ tags: ['autodocs'],
11
+ argTypes: {
12
+ size: {
13
+ control: 'select',
14
+ options: ['md', 'lg'],
15
+ },
16
+ items: { control: 'object' },
17
+ },
18
+ };
19
+
20
+ export default meta;
21
+ type Story = StoryObj<TabsListProps>;
22
+
23
+ const defaultItems = [
24
+ { label: 'Overview', value: 'overview' },
25
+ { label: 'Analytics', value: 'analytics' },
26
+ { label: 'Reports', value: 'reports' },
27
+ { label: 'Settings', value: 'settings' },
28
+ ];
29
+
30
+ export const Default: Story = {
31
+ args: {
32
+ size: 'md',
33
+ items: defaultItems,
34
+ },
35
+ render: (args: TabsListProps) => ({
36
+ components: { TabsList },
37
+ setup() {
38
+ const active = ref('overview');
39
+ return { args, active };
40
+ },
41
+ template: '<TabsList v-bind="args" v-model="active" />',
42
+ }),
43
+ };
44
+
45
+ export const Sizes: Story = {
46
+ parameters: {
47
+ controls: { disable: true },
48
+ },
49
+ render: () => ({
50
+ components: { TabsList },
51
+ setup() {
52
+ const activeMd = ref('overview');
53
+ const activeLg = ref('overview');
54
+ return { activeMd, activeLg, defaultItems };
55
+ },
56
+ template: `
57
+ <div class="flex flex-col gap-6">
58
+ <TabsList :items="defaultItems" v-model="activeMd" size="md" />
59
+ <TabsList :items="defaultItems" v-model="activeLg" size="lg" />
60
+ </div>
61
+ `,
62
+ }),
63
+ };
64
+
65
+ export const WithDisabled: Story = {
66
+ args: {
67
+ size: 'md',
68
+ items: [
69
+ { label: 'Overview', value: 'overview' },
70
+ { label: 'Analytics', value: 'analytics' },
71
+ { label: 'Reports', value: 'reports', disabled: true },
72
+ { label: 'Settings', value: 'settings' },
73
+ ],
74
+ },
75
+ render: (args: TabsListProps) => ({
76
+ components: { TabsList },
77
+ setup() {
78
+ const active = ref('overview');
79
+ return { args, active };
80
+ },
81
+ template: '<TabsList v-bind="args" v-model="active" />',
82
+ }),
83
+ };