windly-ui 1.0.1 → 1.0.3

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 (123) hide show
  1. package/dist/module.d.mts +3 -0
  2. package/dist/module.json +8 -0
  3. package/dist/module.mjs +26 -0
  4. package/dist/runtime/components/Accordion.d.vue.ts +39 -0
  5. package/{ui-library → dist/runtime}/components/Accordion.vue +44 -70
  6. package/dist/runtime/components/Accordion.vue.d.ts +39 -0
  7. package/dist/runtime/components/Avatar.d.vue.ts +141 -0
  8. package/dist/runtime/components/Avatar.vue +72 -0
  9. package/dist/runtime/components/Avatar.vue.d.ts +141 -0
  10. package/dist/runtime/components/Badge.d.vue.ts +133 -0
  11. package/dist/runtime/components/Badge.vue +99 -0
  12. package/dist/runtime/components/Badge.vue.d.ts +133 -0
  13. package/dist/runtime/components/Breadcrumbs.d.vue.ts +83 -0
  14. package/{ui-library → dist/runtime}/components/Breadcrumbs.vue +37 -59
  15. package/dist/runtime/components/Breadcrumbs.vue.d.ts +83 -0
  16. package/dist/runtime/components/Button.d.vue.ts +199 -0
  17. package/dist/runtime/components/Button.vue +125 -0
  18. package/dist/runtime/components/Button.vue.d.ts +199 -0
  19. package/dist/runtime/components/Card.d.vue.ts +83 -0
  20. package/{ui-library → dist/runtime}/components/Card.vue +26 -39
  21. package/dist/runtime/components/Card.vue.d.ts +83 -0
  22. package/dist/runtime/components/Checkbox.d.vue.ts +190 -0
  23. package/{ui-library → dist/runtime}/components/Checkbox.vue +45 -68
  24. package/dist/runtime/components/Checkbox.vue.d.ts +190 -0
  25. package/dist/runtime/components/CodeBlock.d.vue.ts +16 -0
  26. package/dist/runtime/components/CodeBlock.vue +75 -0
  27. package/dist/runtime/components/CodeBlock.vue.d.ts +16 -0
  28. package/dist/runtime/components/ColorPicker.d.vue.ts +91 -0
  29. package/dist/runtime/components/ColorPicker.vue +244 -0
  30. package/dist/runtime/components/ColorPicker.vue.d.ts +91 -0
  31. package/dist/runtime/components/Date.d.vue.ts +137 -0
  32. package/dist/runtime/components/Date.vue +201 -0
  33. package/dist/runtime/components/Date.vue.d.ts +137 -0
  34. package/dist/runtime/components/Dialog.d.vue.ts +103 -0
  35. package/{ui-library → dist/runtime}/components/Dialog.vue +30 -65
  36. package/dist/runtime/components/Dialog.vue.d.ts +103 -0
  37. package/dist/runtime/components/Divider.d.vue.ts +51 -0
  38. package/dist/runtime/components/Divider.vue +52 -0
  39. package/dist/runtime/components/Divider.vue.d.ts +51 -0
  40. package/dist/runtime/components/Drawer.d.vue.ts +30 -0
  41. package/dist/runtime/components/Drawer.vue +43 -0
  42. package/dist/runtime/components/Drawer.vue.d.ts +30 -0
  43. package/dist/runtime/components/Dropdown.d.vue.ts +34 -0
  44. package/dist/runtime/components/Dropdown.vue +127 -0
  45. package/dist/runtime/components/Dropdown.vue.d.ts +34 -0
  46. package/dist/runtime/components/FileUploader.d.vue.ts +58 -0
  47. package/dist/runtime/components/FileUploader.vue +202 -0
  48. package/dist/runtime/components/FileUploader.vue.d.ts +58 -0
  49. package/dist/runtime/components/Icon.d.vue.ts +41 -0
  50. package/dist/runtime/components/Icon.vue +66 -0
  51. package/dist/runtime/components/Icon.vue.d.ts +41 -0
  52. package/dist/runtime/components/Image.d.vue.ts +77 -0
  53. package/dist/runtime/components/Image.vue +61 -0
  54. package/dist/runtime/components/Image.vue.d.ts +77 -0
  55. package/dist/runtime/components/Input.d.vue.ts +66 -0
  56. package/dist/runtime/components/Input.vue +233 -0
  57. package/dist/runtime/components/Input.vue.d.ts +66 -0
  58. package/dist/runtime/components/Radio.d.vue.ts +41 -0
  59. package/dist/runtime/components/Radio.vue +222 -0
  60. package/dist/runtime/components/Radio.vue.d.ts +41 -0
  61. package/dist/runtime/components/ScrollArea.d.vue.ts +79 -0
  62. package/dist/runtime/components/ScrollArea.vue +36 -0
  63. package/dist/runtime/components/ScrollArea.vue.d.ts +79 -0
  64. package/dist/runtime/components/Select.d.vue.ts +43 -0
  65. package/dist/runtime/components/Select.vue +200 -0
  66. package/dist/runtime/components/Select.vue.d.ts +43 -0
  67. package/dist/runtime/components/Stepper.d.vue.ts +46 -0
  68. package/dist/runtime/components/Stepper.vue +218 -0
  69. package/dist/runtime/components/Stepper.vue.d.ts +46 -0
  70. package/dist/runtime/components/TabPanel.d.vue.ts +17 -0
  71. package/dist/runtime/components/TabPanel.vue +21 -0
  72. package/dist/runtime/components/TabPanel.vue.d.ts +17 -0
  73. package/dist/runtime/components/Table.d.vue.ts +40 -0
  74. package/dist/runtime/components/Table.vue +92 -0
  75. package/dist/runtime/components/Table.vue.d.ts +40 -0
  76. package/dist/runtime/components/Tabs.d.vue.ts +20 -0
  77. package/dist/runtime/components/Tabs.vue +62 -0
  78. package/dist/runtime/components/Tabs.vue.d.ts +20 -0
  79. package/dist/runtime/components/Textarea.d.vue.ts +208 -0
  80. package/dist/runtime/components/Textarea.vue +185 -0
  81. package/dist/runtime/components/Textarea.vue.d.ts +208 -0
  82. package/dist/runtime/components/Toggle.d.vue.ts +36 -0
  83. package/dist/runtime/components/Toggle.vue +173 -0
  84. package/dist/runtime/components/Toggle.vue.d.ts +36 -0
  85. package/dist/runtime/components/Tooltip.d.vue.ts +63 -0
  86. package/dist/runtime/components/Tooltip.vue +144 -0
  87. package/dist/runtime/components/Tooltip.vue.d.ts +63 -0
  88. package/dist/runtime/components/uiProps.d.ts +38 -0
  89. package/{ui-library/components/uiProps.ts → dist/runtime/components/uiProps.js} +2 -2
  90. package/dist/runtime/components/useUiClasses.d.ts +43 -0
  91. package/{ui-library/components/useUiClasses.ts → dist/runtime/components/useUiClasses.js} +25 -60
  92. package/dist/runtime/composables/plugin.d.ts +2 -0
  93. package/dist/runtime/composables/plugin.js +3 -0
  94. package/dist/runtime/tailwind-color.d.ts +2 -0
  95. package/dist/runtime/tailwind-color.js +5859 -0
  96. package/dist/types.d.mts +7 -0
  97. package/package.json +14 -16
  98. package/README.md +0 -208
  99. package/ui-library/components/Avatar.vue +0 -121
  100. package/ui-library/components/Badge.vue +0 -116
  101. package/ui-library/components/Button.vue +0 -154
  102. package/ui-library/components/CodeBlock.vue +0 -99
  103. package/ui-library/components/ColorPicker.vue +0 -302
  104. package/ui-library/components/Date.vue +0 -240
  105. package/ui-library/components/Divider.vue +0 -78
  106. package/ui-library/components/Drawer.vue +0 -67
  107. package/ui-library/components/Dropdown.vue +0 -248
  108. package/ui-library/components/FileUploader.vue +0 -330
  109. package/ui-library/components/Icon.vue +0 -82
  110. package/ui-library/components/Image.vue +0 -78
  111. package/ui-library/components/Input.vue +0 -531
  112. package/ui-library/components/Radio.vue +0 -356
  113. package/ui-library/components/ScrollArea.vue +0 -43
  114. package/ui-library/components/Select.vue +0 -309
  115. package/ui-library/components/Stepper.vue +0 -361
  116. package/ui-library/components/TabPanel.vue +0 -25
  117. package/ui-library/components/Table.vue +0 -152
  118. package/ui-library/components/Tabs.vue +0 -71
  119. package/ui-library/components/Textarea.vue +0 -233
  120. package/ui-library/components/Toggle.vue +0 -319
  121. package/ui-library/components/Tooltip.vue +0 -200
  122. package/ui-library/components/plugin.ts +0 -8
  123. package/ui-library/module.ts +0 -20
@@ -0,0 +1,36 @@
1
+ <script setup>
2
+ defineOptions({
3
+ inheritAttrs: false
4
+ });
5
+ import { computed } from "vue";
6
+ const props = defineProps({
7
+ width: { type: String, default: "100%" },
8
+ height: { type: String, default: "300px" },
9
+ maxWidth: { type: String, default: "" },
10
+ maxHeight: { type: String, default: "" },
11
+ horizontal: { type: Boolean, default: false },
12
+ vertical: { type: Boolean, default: true },
13
+ hideScrollbar: { type: Boolean, default: false }
14
+ });
15
+ const scrollStyle = computed(() => ({
16
+ width: props.width,
17
+ height: props.height,
18
+ maxWidth: props.maxWidth || void 0,
19
+ maxHeight: props.maxHeight || void 0
20
+ }));
21
+ const scrollClass = computed(() => [
22
+ props.vertical ? "overflow-y-auto" : "overflow-y-hidden",
23
+ props.horizontal ? "overflow-x-auto" : "overflow-x-hidden",
24
+ props.hideScrollbar ? "scrollbar-hide" : ""
25
+ ]);
26
+ </script>
27
+
28
+ <template>
29
+ <div
30
+ :class="scrollClass"
31
+ :style="scrollStyle"
32
+ v-bind="$attrs"
33
+ >
34
+ <slot />
35
+ </div>
36
+ </template>
@@ -0,0 +1,79 @@
1
+ declare var __VLS_1: {};
2
+ type __VLS_Slots = {} & {
3
+ default?: (props: typeof __VLS_1) => any;
4
+ };
5
+ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
6
+ width: {
7
+ type: StringConstructor;
8
+ default: string;
9
+ };
10
+ height: {
11
+ type: StringConstructor;
12
+ default: string;
13
+ };
14
+ maxWidth: {
15
+ type: StringConstructor;
16
+ default: string;
17
+ };
18
+ maxHeight: {
19
+ type: StringConstructor;
20
+ default: string;
21
+ };
22
+ horizontal: {
23
+ type: BooleanConstructor;
24
+ default: boolean;
25
+ };
26
+ vertical: {
27
+ type: BooleanConstructor;
28
+ default: boolean;
29
+ };
30
+ hideScrollbar: {
31
+ type: BooleanConstructor;
32
+ default: boolean;
33
+ };
34
+ }>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
35
+ width: {
36
+ type: StringConstructor;
37
+ default: string;
38
+ };
39
+ height: {
40
+ type: StringConstructor;
41
+ default: string;
42
+ };
43
+ maxWidth: {
44
+ type: StringConstructor;
45
+ default: string;
46
+ };
47
+ maxHeight: {
48
+ type: StringConstructor;
49
+ default: string;
50
+ };
51
+ horizontal: {
52
+ type: BooleanConstructor;
53
+ default: boolean;
54
+ };
55
+ vertical: {
56
+ type: BooleanConstructor;
57
+ default: boolean;
58
+ };
59
+ hideScrollbar: {
60
+ type: BooleanConstructor;
61
+ default: boolean;
62
+ };
63
+ }>> & Readonly<{}>, {
64
+ horizontal: boolean;
65
+ vertical: boolean;
66
+ width: string;
67
+ maxWidth: string;
68
+ height: string;
69
+ maxHeight: string;
70
+ hideScrollbar: boolean;
71
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
72
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
73
+ declare const _default: typeof __VLS_export;
74
+ export default _default;
75
+ type __VLS_WithSlots<T, S> = T & {
76
+ new (): {
77
+ $slots: S;
78
+ };
79
+ };
@@ -0,0 +1,43 @@
1
+ interface SelectOption {
2
+ text: string;
3
+ value: string | number | boolean;
4
+ }
5
+ type Rounded = 'none' | 'sm' | 'md' | 'lg' | 'xl' | 'full';
6
+ type __VLS_Props = {
7
+ filter?: boolean;
8
+ modelValue?: string | number | boolean;
9
+ label: string;
10
+ id?: string;
11
+ options: SelectOption[];
12
+ placeholder?: string;
13
+ disabled?: boolean;
14
+ required?: boolean;
15
+ hint?: string;
16
+ flat?: boolean;
17
+ bordered?: boolean;
18
+ rounded?: Rounded;
19
+ borderColor?: string;
20
+ bgColor?: string;
21
+ textColor?: string;
22
+ };
23
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
24
+ "update:modelValue": (value: string | number | boolean) => any;
25
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
26
+ "onUpdate:modelValue"?: ((value: string | number | boolean) => any) | undefined;
27
+ }>, {
28
+ modelValue: string | number | boolean;
29
+ disabled: boolean;
30
+ filter: boolean;
31
+ textColor: string;
32
+ rounded: Rounded;
33
+ borderColor: string;
34
+ required: boolean;
35
+ flat: boolean;
36
+ id: string;
37
+ placeholder: string;
38
+ bordered: boolean;
39
+ bgColor: string;
40
+ hint: string;
41
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
42
+ declare const _default: typeof __VLS_export;
43
+ export default _default;
@@ -0,0 +1,200 @@
1
+ <script setup>
2
+ defineOptions({
3
+ name: "UISelect"
4
+ });
5
+ import {
6
+ computed,
7
+ ref,
8
+ watch
9
+ } from "vue";
10
+ const props = defineProps({
11
+ filter: { type: Boolean, required: false, default: false },
12
+ modelValue: { type: [String, Number, Boolean], required: false, default: "" },
13
+ label: { type: String, required: true },
14
+ id: { type: String, required: false, default: void 0 },
15
+ options: { type: Array, required: true },
16
+ placeholder: { type: String, required: false, default: "Search or select..." },
17
+ disabled: { type: Boolean, required: false, default: false },
18
+ required: { type: Boolean, required: false, default: false },
19
+ hint: { type: String, required: false, default: "" },
20
+ flat: { type: Boolean, required: false, default: false },
21
+ bordered: { type: Boolean, required: false, default: true },
22
+ rounded: { type: String, required: false, default: "md" },
23
+ borderColor: { type: String, required: false, default: "gray-300" },
24
+ bgColor: { type: String, required: false, default: "white" },
25
+ textColor: { type: String, required: false, default: "black" }
26
+ });
27
+ const emit = defineEmits(["update:modelValue"]);
28
+ const searchQuery = ref("");
29
+ const showDropdown = ref(false);
30
+ const isHex = (val) => {
31
+ return val.startsWith("#") || val.startsWith("rgb") || val.startsWith("hsl");
32
+ };
33
+ const roundedClass = computed(() => {
34
+ const map = {
35
+ none: "rounded-none",
36
+ sm: "rounded-sm",
37
+ md: "rounded-md",
38
+ lg: "rounded-lg",
39
+ xl: "rounded-xl",
40
+ full: "rounded-full"
41
+ };
42
+ return map[props.rounded];
43
+ });
44
+ const selectClasses = computed(() => [
45
+ "block w-full px-3 py-2 transition-all focus:outline-none",
46
+ roundedClass.value,
47
+ props.flat ? "shadow-none" : "shadow-sm",
48
+ props.bordered ? !isHex(
49
+ props.borderColor
50
+ ) ? `border border-${props.borderColor}` : "border" : "border-0",
51
+ !isHex(props.bgColor) ? `bg-${props.bgColor}` : "",
52
+ !isHex(
53
+ props.textColor
54
+ ) ? `text-${props.textColor}` : "",
55
+ props.disabled ? "opacity-50 cursor-not-allowed" : ""
56
+ ]);
57
+ const selectStyles = computed(() => {
58
+ const style = {};
59
+ if (isHex(props.bgColor)) {
60
+ style.backgroundColor = props.bgColor;
61
+ }
62
+ if (isHex(
63
+ props.borderColor
64
+ )) {
65
+ style.borderColor = props.borderColor;
66
+ }
67
+ if (isHex(
68
+ props.textColor
69
+ )) {
70
+ style.color = props.textColor;
71
+ }
72
+ return style;
73
+ });
74
+ const filteredOptions = computed(() => {
75
+ const query = searchQuery.value.toLowerCase();
76
+ return props.options.filter(
77
+ (option) => option.text.toLowerCase().includes(query)
78
+ );
79
+ });
80
+ watch(
81
+ () => props.modelValue,
82
+ (val) => {
83
+ const selected = props.options.find(
84
+ (opt) => opt.value === val
85
+ );
86
+ if (selected) {
87
+ searchQuery.value = selected.text;
88
+ }
89
+ },
90
+ {
91
+ immediate: true
92
+ }
93
+ );
94
+ const selectOption = (option) => {
95
+ searchQuery.value = option.text;
96
+ emit(
97
+ "update:modelValue",
98
+ option.value
99
+ );
100
+ showDropdown.value = false;
101
+ };
102
+ const handleChange = (event) => {
103
+ const target = event.target;
104
+ emit(
105
+ "update:modelValue",
106
+ target.value
107
+ );
108
+ };
109
+ const handleBlur = () => {
110
+ setTimeout(() => {
111
+ showDropdown.value = false;
112
+ }, 100);
113
+ };
114
+ </script>
115
+
116
+ <template>
117
+ <div class="relative my-5">
118
+ <!-- Label -->
119
+ <label v-if="label" :for="id" class="block mb-2 text-sm font-medium text-gray-600 dark:text-gray-300">
120
+ {{ label }}
121
+ </label>
122
+
123
+ <!-- Filterable Select -->
124
+ <div v-if="filter" class="relative">
125
+ <input v-model="
126
+ searchQuery
127
+ " :placeholder="
128
+ placeholder
129
+ " :disabled="
130
+ disabled
131
+ " :required="
132
+ required
133
+ " :class="
134
+ selectClasses
135
+ " :style="
136
+ selectStyles
137
+ " @focus="
138
+ showDropdown = true
139
+ " @blur="
140
+ handleBlur
141
+ " @input="
142
+ showDropdown = true
143
+ ">
144
+
145
+ <!-- Dropdown -->
146
+ <ul v-if="
147
+ showDropdown
148
+ "
149
+ class="absolute z-10 mt-1 w-full max-h-48 overflow-y-auto bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-md shadow-lg">
150
+ <li v-for="option in filteredOptions" :key="
151
+ option.value.toString()
152
+ " class="px-4 py-2 cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-700" @mousedown.prevent="
153
+ selectOption(
154
+ option
155
+ )
156
+ ">
157
+ {{ option.text }}
158
+ </li>
159
+
160
+ <li v-if="
161
+ filteredOptions.length === 0
162
+ " class="px-4 py-2 text-gray-500">
163
+ No results found
164
+ </li>
165
+ </ul>
166
+ </div>
167
+
168
+ <!-- Native Select -->
169
+ <select v-else :id="id" :value="
170
+ modelValue
171
+ " :disabled="
172
+ disabled
173
+ " :required="
174
+ required
175
+ " :class="
176
+ selectClasses
177
+ " :style="
178
+ selectStyles
179
+ " @change="
180
+ handleChange
181
+ ">
182
+ <option disabled value="">
183
+ {{ placeholder }}
184
+ </option>
185
+
186
+ <option v-for="option in options" :key="
187
+ option.value.toString()
188
+ " :value="
189
+ option.value
190
+ ">
191
+ {{ option.text }}
192
+ </option>
193
+ </select>
194
+
195
+ <!-- Hint -->
196
+ <p v-if="hint" class="mt-1 text-sm text-gray-500">
197
+ {{ hint }}
198
+ </p>
199
+ </div>
200
+ </template>
@@ -0,0 +1,43 @@
1
+ interface SelectOption {
2
+ text: string;
3
+ value: string | number | boolean;
4
+ }
5
+ type Rounded = 'none' | 'sm' | 'md' | 'lg' | 'xl' | 'full';
6
+ type __VLS_Props = {
7
+ filter?: boolean;
8
+ modelValue?: string | number | boolean;
9
+ label: string;
10
+ id?: string;
11
+ options: SelectOption[];
12
+ placeholder?: string;
13
+ disabled?: boolean;
14
+ required?: boolean;
15
+ hint?: string;
16
+ flat?: boolean;
17
+ bordered?: boolean;
18
+ rounded?: Rounded;
19
+ borderColor?: string;
20
+ bgColor?: string;
21
+ textColor?: string;
22
+ };
23
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
24
+ "update:modelValue": (value: string | number | boolean) => any;
25
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
26
+ "onUpdate:modelValue"?: ((value: string | number | boolean) => any) | undefined;
27
+ }>, {
28
+ modelValue: string | number | boolean;
29
+ disabled: boolean;
30
+ filter: boolean;
31
+ textColor: string;
32
+ rounded: Rounded;
33
+ borderColor: string;
34
+ required: boolean;
35
+ flat: boolean;
36
+ id: string;
37
+ placeholder: string;
38
+ bordered: boolean;
39
+ bgColor: string;
40
+ hint: string;
41
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
42
+ declare const _default: typeof __VLS_export;
43
+ export default _default;
@@ -0,0 +1,46 @@
1
+ interface StepItem {
2
+ label: string;
3
+ name?: string;
4
+ icon?: string;
5
+ iconColor?: string;
6
+ }
7
+ type Step = string | StepItem;
8
+ type __VLS_Props = {
9
+ steps: Step[];
10
+ modelValue?: number;
11
+ vertical?: boolean;
12
+ completedColor?: string;
13
+ activeColor?: string;
14
+ inactiveColor?: string;
15
+ connectorCompletedColor?: string;
16
+ connectorInactiveColor?: string;
17
+ inactiveSteps?: number[];
18
+ };
19
+ declare var __VLS_1: {
20
+ step: number;
21
+ };
22
+ type __VLS_Slots = {} & {
23
+ default?: (props: typeof __VLS_1) => any;
24
+ };
25
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
26
+ "update:modelValue": (value: number) => any;
27
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
28
+ "onUpdate:modelValue"?: ((value: number) => any) | undefined;
29
+ }>, {
30
+ modelValue: number;
31
+ activeColor: string;
32
+ vertical: boolean;
33
+ completedColor: string;
34
+ inactiveColor: string;
35
+ connectorCompletedColor: string;
36
+ connectorInactiveColor: string;
37
+ inactiveSteps: number[];
38
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
39
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
40
+ declare const _default: typeof __VLS_export;
41
+ export default _default;
42
+ type __VLS_WithSlots<T, S> = T & {
43
+ new (): {
44
+ $slots: S;
45
+ };
46
+ };
@@ -0,0 +1,218 @@
1
+ <script setup>
2
+ import { computed } from "vue";
3
+ const props = defineProps({
4
+ steps: { type: Array, required: true },
5
+ modelValue: { type: Number, required: false, default: 0 },
6
+ vertical: { type: Boolean, required: false, default: false },
7
+ completedColor: { type: String, required: false, default: "green-500" },
8
+ activeColor: { type: String, required: false, default: "blue-500" },
9
+ inactiveColor: { type: String, required: false, default: "gray-300" },
10
+ connectorCompletedColor: { type: String, required: false, default: "green-500" },
11
+ connectorInactiveColor: { type: String, required: false, default: "gray-300" },
12
+ inactiveSteps: { type: Array, required: false, default: () => [] }
13
+ });
14
+ const emit = defineEmits(["update:modelValue"]);
15
+ const currentStep = computed(
16
+ () => props.modelValue
17
+ );
18
+ const normalizedSteps = computed(
19
+ () => props.steps.map((step) => {
20
+ if (typeof step === "string") {
21
+ return {
22
+ label: step
23
+ };
24
+ }
25
+ return step;
26
+ })
27
+ );
28
+ const isHex = (val) => val.startsWith("#");
29
+ const isInactiveStep = (index) => {
30
+ return props.inactiveSteps.includes(
31
+ index
32
+ );
33
+ };
34
+ const stepState = (index) => {
35
+ if (isInactiveStep(index)) {
36
+ return "inactive";
37
+ }
38
+ if (index < currentStep.value) {
39
+ return "completed";
40
+ }
41
+ if (index === currentStep.value) {
42
+ return "active";
43
+ }
44
+ return "pending";
45
+ };
46
+ const stepClasses = (index) => {
47
+ const state = stepState(index);
48
+ switch (state) {
49
+ case "completed":
50
+ return [
51
+ !isHex(
52
+ props.completedColor
53
+ ) ? `bg-${props.completedColor}` : "",
54
+ "text-white"
55
+ ];
56
+ case "active":
57
+ return [
58
+ !isHex(
59
+ props.activeColor
60
+ ) ? `bg-${props.activeColor}` : "",
61
+ "text-white"
62
+ ];
63
+ case "inactive":
64
+ return [
65
+ !isHex(
66
+ props.inactiveColor
67
+ ) ? `bg-${props.inactiveColor}` : "",
68
+ "text-gray-500 opacity-60 cursor-not-allowed"
69
+ ];
70
+ case "pending":
71
+ default:
72
+ return [
73
+ !isHex(
74
+ props.inactiveColor
75
+ ) ? `bg-${props.inactiveColor}` : "",
76
+ "text-gray-600"
77
+ ];
78
+ }
79
+ };
80
+ const stepStyle = (index) => {
81
+ const style = {};
82
+ const state = stepState(index);
83
+ const colorMap = {
84
+ completed: props.completedColor,
85
+ active: props.activeColor,
86
+ inactive: props.inactiveColor,
87
+ pending: props.inactiveColor
88
+ };
89
+ const color = colorMap[state];
90
+ if (isHex(color)) {
91
+ style.backgroundColor = color;
92
+ }
93
+ return style;
94
+ };
95
+ const connectorClasses = (index) => {
96
+ const completed = index < currentStep.value && !isInactiveStep(index + 1);
97
+ const color = completed ? props.connectorCompletedColor : props.connectorInactiveColor;
98
+ return [
99
+ !isHex(color) ? `bg-${color}` : ""
100
+ ];
101
+ };
102
+ const connectorStyle = (index) => {
103
+ const style = {};
104
+ const completed = index < currentStep.value && !isInactiveStep(index + 1);
105
+ const color = completed ? props.connectorCompletedColor : props.connectorInactiveColor;
106
+ if (isHex(color)) {
107
+ style.backgroundColor = color;
108
+ }
109
+ return style;
110
+ };
111
+ const labelClasses = (index) => {
112
+ if (isInactiveStep(index)) {
113
+ return "text-gray-400 opacity-60 cursor-not-allowed";
114
+ }
115
+ if (index === currentStep.value) {
116
+ return "text-black dark:text-white";
117
+ }
118
+ return "text-gray-500";
119
+ };
120
+ const navigate = (index) => {
121
+ if (isInactiveStep(index)) {
122
+ return;
123
+ }
124
+ emit(
125
+ "update:modelValue",
126
+ index
127
+ );
128
+ };
129
+ </script>
130
+
131
+ <template>
132
+ <div :class="{
133
+ flex: vertical,
134
+ block: !vertical
135
+ }">
136
+ <!-- Steps -->
137
+ <div :class="{
138
+ 'flex flex-col items-start': vertical,
139
+ 'flex items-start justify-between': !vertical
140
+ }">
141
+ <div v-for="(
142
+ step, index
143
+ ) in normalizedSteps" :key="index" :class="{
144
+ 'relative flex-1 flex items-start': !vertical,
145
+ 'relative flex flex-col items-start': vertical
146
+ }">
147
+ <div :class="{
148
+ 'flex items-center': vertical,
149
+ 'flex flex-col items-center': !vertical
150
+ }">
151
+ <!-- Step Indicator -->
152
+ <div @click="
153
+ navigate(index)
154
+ " :class="[
155
+ 'flex items-center justify-center w-10 h-10 rounded-full font-bold z-10 transition-colors',
156
+ stepClasses(index)
157
+ ]" :style="
158
+ stepStyle(index)
159
+ ">
160
+ <template v-if="step.icon">
161
+ <span class="material-icons">
162
+ {{ step.icon }}
163
+ </span>
164
+ </template>
165
+
166
+ <template v-else>
167
+ {{ index + 1 }}
168
+ </template>
169
+ </div>
170
+
171
+ <!-- Label -->
172
+ <div class="text-center text-sm font-medium mx-2" :class="[
173
+ vertical ? 'ml-4' : 'mt-2',
174
+ labelClasses(index)
175
+ ]" @click="
176
+ navigate(index)
177
+ ">
178
+ {{ step.label }}
179
+ </div>
180
+ </div>
181
+
182
+ <!-- Connector -->
183
+ <div v-if="
184
+ index !== normalizedSteps.length - 1
185
+ " :class="{
186
+ 'flex-1 h-[1px] mt-5 relative': !vertical,
187
+ 'w-[1px] h-16 ml-5 relative': vertical
188
+ }">
189
+ <div class="absolute w-full h-full" :class="
190
+ connectorClasses(
191
+ index
192
+ )
193
+ " :style="[
194
+ connectorStyle(
195
+ index
196
+ ),
197
+ {
198
+ top: vertical ? '50%' : '',
199
+ transform: 'translateY(-50%)'
200
+ }
201
+ ]" />
202
+ </div>
203
+ </div>
204
+ </div>
205
+
206
+ <!-- Content -->
207
+ <div :class="{
208
+ 'ml-4': vertical,
209
+ 'mt-4': !vertical
210
+ }">
211
+ <slot :step="currentStep" />
212
+ </div>
213
+ </div>
214
+ </template>
215
+
216
+ <style scoped>
217
+ .material-icons{font-size:1.5rem}
218
+ </style>