windly-ui 1.0.2 → 1.0.4

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/{ui-library/dist → dist}/module.json +2 -2
  2. package/dist/module.mjs +33 -0
  3. package/dist/runtime/components/Accordion.d.vue.ts +39 -0
  4. package/dist/runtime/components/Accordion.vue +96 -0
  5. package/dist/runtime/components/Accordion.vue.d.ts +39 -0
  6. package/dist/runtime/components/Alert.d.vue.ts +83 -0
  7. package/dist/runtime/components/Alert.vue +78 -0
  8. package/dist/runtime/components/Alert.vue.d.ts +83 -0
  9. package/dist/runtime/components/Avatar.d.vue.ts +141 -0
  10. package/dist/runtime/components/Avatar.vue +72 -0
  11. package/dist/runtime/components/Avatar.vue.d.ts +141 -0
  12. package/dist/runtime/components/Badge.d.vue.ts +133 -0
  13. package/dist/runtime/components/Badge.vue +99 -0
  14. package/dist/runtime/components/Badge.vue.d.ts +133 -0
  15. package/dist/runtime/components/Breadcrumbs.d.vue.ts +83 -0
  16. package/dist/runtime/components/Breadcrumbs.vue +116 -0
  17. package/dist/runtime/components/Breadcrumbs.vue.d.ts +83 -0
  18. package/dist/runtime/components/Button.d.vue.ts +208 -0
  19. package/dist/runtime/components/Button.vue +126 -0
  20. package/dist/runtime/components/Button.vue.d.ts +208 -0
  21. package/dist/runtime/components/Card.d.vue.ts +83 -0
  22. package/dist/runtime/components/Card.vue +71 -0
  23. package/dist/runtime/components/Card.vue.d.ts +83 -0
  24. package/dist/runtime/components/Checkbox.d.vue.ts +190 -0
  25. package/dist/runtime/components/Checkbox.vue +125 -0
  26. package/dist/runtime/components/Checkbox.vue.d.ts +190 -0
  27. package/dist/runtime/components/CodeBlock.d.vue.ts +16 -0
  28. package/dist/runtime/components/CodeBlock.vue +75 -0
  29. package/dist/runtime/components/CodeBlock.vue.d.ts +16 -0
  30. package/dist/runtime/components/ColorPicker.d.vue.ts +91 -0
  31. package/dist/runtime/components/ColorPicker.vue +244 -0
  32. package/dist/runtime/components/ColorPicker.vue.d.ts +91 -0
  33. package/dist/runtime/components/Date.d.vue.ts +137 -0
  34. package/dist/runtime/components/Date.vue +201 -0
  35. package/dist/runtime/components/Date.vue.d.ts +137 -0
  36. package/dist/runtime/components/Dialog.d.vue.ts +63 -0
  37. package/dist/runtime/components/Dialog.vue +85 -0
  38. package/dist/runtime/components/Dialog.vue.d.ts +63 -0
  39. package/dist/runtime/components/Divider.d.vue.ts +51 -0
  40. package/dist/runtime/components/Divider.vue +52 -0
  41. package/dist/runtime/components/Divider.vue.d.ts +51 -0
  42. package/dist/runtime/components/Drawer.d.vue.ts +30 -0
  43. package/dist/runtime/components/Drawer.vue +43 -0
  44. package/dist/runtime/components/Drawer.vue.d.ts +30 -0
  45. package/dist/runtime/components/Dropdown.d.vue.ts +34 -0
  46. package/dist/runtime/components/Dropdown.vue +127 -0
  47. package/dist/runtime/components/Dropdown.vue.d.ts +34 -0
  48. package/dist/runtime/components/FileUploader.d.vue.ts +65 -0
  49. package/dist/runtime/components/FileUploader.vue +358 -0
  50. package/dist/runtime/components/FileUploader.vue.d.ts +65 -0
  51. package/dist/runtime/components/Icon.d.vue.ts +41 -0
  52. package/dist/runtime/components/Icon.vue +66 -0
  53. package/dist/runtime/components/Icon.vue.d.ts +41 -0
  54. package/dist/runtime/components/Image.d.vue.ts +77 -0
  55. package/dist/runtime/components/Image.vue +61 -0
  56. package/dist/runtime/components/Image.vue.d.ts +77 -0
  57. package/dist/runtime/components/Input.d.vue.ts +68 -0
  58. package/dist/runtime/components/Input.vue +241 -0
  59. package/dist/runtime/components/Input.vue.d.ts +68 -0
  60. package/dist/runtime/components/Radio.d.vue.ts +41 -0
  61. package/dist/runtime/components/Radio.vue +222 -0
  62. package/dist/runtime/components/Radio.vue.d.ts +41 -0
  63. package/dist/runtime/components/ScrollArea.d.vue.ts +79 -0
  64. package/dist/runtime/components/ScrollArea.vue +36 -0
  65. package/dist/runtime/components/ScrollArea.vue.d.ts +79 -0
  66. package/dist/runtime/components/Select.d.vue.ts +51 -0
  67. package/dist/runtime/components/Select.vue +271 -0
  68. package/dist/runtime/components/Select.vue.d.ts +51 -0
  69. package/dist/runtime/components/Stepper.d.vue.ts +46 -0
  70. package/dist/runtime/components/Stepper.vue +218 -0
  71. package/dist/runtime/components/Stepper.vue.d.ts +46 -0
  72. package/dist/runtime/components/TabPanel.d.vue.ts +17 -0
  73. package/dist/runtime/components/TabPanel.vue +21 -0
  74. package/dist/runtime/components/TabPanel.vue.d.ts +17 -0
  75. package/dist/runtime/components/Table.d.vue.ts +40 -0
  76. package/dist/runtime/components/Table.vue +92 -0
  77. package/dist/runtime/components/Table.vue.d.ts +40 -0
  78. package/dist/runtime/components/Tabs.d.vue.ts +20 -0
  79. package/dist/runtime/components/Tabs.vue +62 -0
  80. package/dist/runtime/components/Tabs.vue.d.ts +20 -0
  81. package/dist/runtime/components/Textarea.d.vue.ts +208 -0
  82. package/dist/runtime/components/Textarea.vue +185 -0
  83. package/dist/runtime/components/Textarea.vue.d.ts +208 -0
  84. package/dist/runtime/components/Toggle.d.vue.ts +36 -0
  85. package/dist/runtime/components/Toggle.vue +173 -0
  86. package/dist/runtime/components/Toggle.vue.d.ts +36 -0
  87. package/dist/runtime/components/Tooltip.d.vue.ts +63 -0
  88. package/dist/runtime/components/Tooltip.vue +144 -0
  89. package/dist/runtime/components/Tooltip.vue.d.ts +63 -0
  90. package/dist/runtime/components/uiProps.d.ts +38 -0
  91. package/dist/runtime/components/uiProps.js +11 -0
  92. package/dist/runtime/components/useUiClasses.d.ts +43 -0
  93. package/dist/runtime/components/useUiClasses.js +124 -0
  94. package/dist/runtime/composables/plugin.d.ts +2 -0
  95. package/dist/runtime/composables/plugin.js +3 -0
  96. package/dist/runtime/tailwind-color.d.ts +2 -0
  97. package/dist/runtime/tailwind-color.js +5859 -0
  98. package/package.json +12 -46
  99. package/LICENSE +0 -21
  100. package/README.md +0 -232
  101. package/ui-library/dist/module.mjs +0 -22
  102. /package/{ui-library/dist → dist}/module.d.mts +0 -0
  103. /package/{ui-library/dist → dist}/types.d.mts +0 -0
@@ -0,0 +1,40 @@
1
+ type Separator = "none" | "horizontal" | "vertical" | "cell";
2
+ type Rounded = "none" | "sm" | "md" | "lg" | "xl";
3
+ type __VLS_Props = {
4
+ flat?: boolean;
5
+ bordered?: boolean;
6
+ striped?: boolean;
7
+ dense?: boolean;
8
+ hover?: boolean;
9
+ rounded?: Rounded;
10
+ separator?: Separator;
11
+ borderColor?: string;
12
+ bgColor?: string;
13
+ };
14
+ declare var __VLS_1: {}, __VLS_3: {}, __VLS_5: {};
15
+ type __VLS_Slots = {} & {
16
+ header?: (props: typeof __VLS_1) => any;
17
+ } & {
18
+ default?: (props: typeof __VLS_3) => any;
19
+ } & {
20
+ footer?: (props: typeof __VLS_5) => any;
21
+ };
22
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
23
+ hover: boolean;
24
+ dense: boolean;
25
+ rounded: Rounded;
26
+ borderColor: string;
27
+ separator: Separator;
28
+ flat: boolean;
29
+ bordered: boolean;
30
+ striped: boolean;
31
+ bgColor: string;
32
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
33
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
34
+ declare const _default: typeof __VLS_export;
35
+ export default _default;
36
+ type __VLS_WithSlots<T, S> = T & {
37
+ new (): {
38
+ $slots: S;
39
+ };
40
+ };
@@ -0,0 +1,92 @@
1
+ <script setup>
2
+ import { computed } from "vue";
3
+ const props = defineProps({
4
+ flat: { type: Boolean, required: false, default: false },
5
+ bordered: { type: Boolean, required: false, default: false },
6
+ striped: { type: Boolean, required: false, default: false },
7
+ dense: { type: Boolean, required: false, default: false },
8
+ hover: { type: Boolean, required: false, default: true },
9
+ rounded: { type: String, required: false, default: "md" },
10
+ separator: { type: String, required: false, default: "horizontal" },
11
+ borderColor: { type: String, required: false, default: "border-gray-200 dark:border-gray-700" },
12
+ bgColor: { type: String, required: false, default: "bg-white dark:bg-gray-900" }
13
+ });
14
+ const roundedClass = computed(() => {
15
+ const map = {
16
+ none: "",
17
+ sm: "rounded-sm",
18
+ md: "rounded-md",
19
+ lg: "rounded-lg",
20
+ xl: "rounded-xl"
21
+ };
22
+ return map[props.rounded];
23
+ });
24
+ const wrapperClass = computed(() => [
25
+ "w-full overflow-x-auto",
26
+ roundedClass.value,
27
+ props.bordered ? `border ${props.borderColor}` : "",
28
+ props.flat ? "shadow-none" : "shadow-sm",
29
+ props.bgColor
30
+ ]);
31
+ const separatorClass = computed(() => {
32
+ switch (props.separator) {
33
+ case "vertical":
34
+ return [
35
+ "[&_th]:border-r",
36
+ "[&_td]:border-r",
37
+ props.borderColor
38
+ ];
39
+ case "cell":
40
+ return [
41
+ "[&_th]:border",
42
+ "[&_td]:border",
43
+ props.borderColor
44
+ ];
45
+ case "none":
46
+ return [];
47
+ case "horizontal":
48
+ default:
49
+ return [
50
+ "[&_tr]:border-b",
51
+ props.borderColor
52
+ ];
53
+ }
54
+ });
55
+ const tableClass = computed(() => [
56
+ "w-full border-collapse",
57
+ separatorClass.value
58
+ ]);
59
+ const headerClass = computed(() => [
60
+ "bg-gray-50 dark:bg-gray-800"
61
+ ]);
62
+ const bodyClass = computed(() => [
63
+ props.striped ? "[&_tr:nth-child(even)]:bg-gray-50 dark:[&_tr:nth-child(even)]:bg-gray-800/40" : "",
64
+ props.hover ? "[&_tr:hover]:bg-gray-100 dark:[&_tr:hover]:bg-gray-700" : "",
65
+ props.dense ? "[&_td]:py-2 [&_th]:py-2" : "[&_td]:py-3 [&_th]:py-3"
66
+ ]);
67
+ const footerClass = computed(() => [
68
+ "bg-gray-50 dark:bg-gray-900"
69
+ ]);
70
+ </script>
71
+
72
+ <template>
73
+ <div :class="wrapperClass">
74
+ <table :class="tableClass">
75
+ <thead
76
+ v-if="$slots.header"
77
+ :class="headerClass"
78
+ >
79
+ <slot name="header" />
80
+ </thead>
81
+ <tbody :class="bodyClass">
82
+ <slot />
83
+ </tbody>
84
+ <tfoot
85
+ v-if="$slots.footer"
86
+ :class="footerClass"
87
+ >
88
+ <slot name="footer" />
89
+ </tfoot>
90
+ </table>
91
+ </div>
92
+ </template>
@@ -0,0 +1,40 @@
1
+ type Separator = "none" | "horizontal" | "vertical" | "cell";
2
+ type Rounded = "none" | "sm" | "md" | "lg" | "xl";
3
+ type __VLS_Props = {
4
+ flat?: boolean;
5
+ bordered?: boolean;
6
+ striped?: boolean;
7
+ dense?: boolean;
8
+ hover?: boolean;
9
+ rounded?: Rounded;
10
+ separator?: Separator;
11
+ borderColor?: string;
12
+ bgColor?: string;
13
+ };
14
+ declare var __VLS_1: {}, __VLS_3: {}, __VLS_5: {};
15
+ type __VLS_Slots = {} & {
16
+ header?: (props: typeof __VLS_1) => any;
17
+ } & {
18
+ default?: (props: typeof __VLS_3) => any;
19
+ } & {
20
+ footer?: (props: typeof __VLS_5) => any;
21
+ };
22
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
23
+ hover: boolean;
24
+ dense: boolean;
25
+ rounded: Rounded;
26
+ borderColor: string;
27
+ separator: Separator;
28
+ flat: boolean;
29
+ bordered: boolean;
30
+ striped: boolean;
31
+ bgColor: string;
32
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
33
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
34
+ declare const _default: typeof __VLS_export;
35
+ export default _default;
36
+ type __VLS_WithSlots<T, S> = T & {
37
+ new (): {
38
+ $slots: S;
39
+ };
40
+ };
@@ -0,0 +1,20 @@
1
+ type __VLS_Props = {
2
+ modelValue: string;
3
+ };
4
+ declare var __VLS_1: {};
5
+ type __VLS_Slots = {} & {
6
+ default?: (props: typeof __VLS_1) => any;
7
+ };
8
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
9
+ "update:modelValue": (value: string) => any;
10
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
11
+ "onUpdate:modelValue"?: ((value: string) => any) | undefined;
12
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
13
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
14
+ declare const _default: typeof __VLS_export;
15
+ export default _default;
16
+ type __VLS_WithSlots<T, S> = T & {
17
+ new (): {
18
+ $slots: S;
19
+ };
20
+ };
@@ -0,0 +1,62 @@
1
+ <script setup>
2
+ import { ref, reactive, watch, nextTick, provide, computed, onMounted } from "vue";
3
+ const props = defineProps({
4
+ modelValue: { type: String, required: true }
5
+ });
6
+ const emit = defineEmits(["update:modelValue"]);
7
+ const tabs = ref([]);
8
+ const tabRefs = ref([]);
9
+ const tabsEl = ref(null);
10
+ const indicatorStyle = ref({
11
+ width: "0px",
12
+ transform: "translateX(0px)"
13
+ });
14
+ function updateIndicator(index) {
15
+ const tab = tabRefs.value[index];
16
+ if (!tab || !tabsEl.value) return;
17
+ indicatorStyle.value = {
18
+ width: `${tab.offsetWidth}px`,
19
+ transform: `translateX(${tab.offsetLeft}px)`
20
+ };
21
+ }
22
+ function setActive(name, index) {
23
+ emit("update:modelValue", name);
24
+ nextTick(() => updateIndicator(index));
25
+ }
26
+ function registerTab(tab) {
27
+ tabs.value.push(tab);
28
+ }
29
+ onMounted(() => {
30
+ watch(
31
+ () => props.modelValue,
32
+ async () => {
33
+ await nextTick();
34
+ const index = tabs.value.findIndex((t) => t.name === props.modelValue);
35
+ if (index !== -1) updateIndicator(index);
36
+ },
37
+ { immediate: true }
38
+ );
39
+ });
40
+ provide("tabs", {
41
+ modelValue: computed(() => props.modelValue),
42
+ registerTab
43
+ });
44
+ </script>
45
+
46
+ <template>
47
+ <!-- Tabs Header -->
48
+ <div ref="tabsEl" class="relative flex border-b bg-gray-100">
49
+ <span class="absolute bottom-0 h-0.5 bg-blue-600 transition-all duration-300 ease-out"
50
+ :style="indicatorStyle" />
51
+
52
+ <button v-for="(tab, index) in tabs" :key="tab.name" :ref="(el) => tabRefs[index] = el"
53
+ @click="setActive(tab.name, index)" class="relative px-4 py-2 text-sm font-medium transition-colors" :class="modelValue === tab.name ? 'text-blue-600' : 'text-gray-600 hover:text-gray-800'">
54
+ {{ tab.label }}
55
+ </button>
56
+ </div>
57
+
58
+ <!-- Content -->
59
+ <div class="relative">
60
+ <slot />
61
+ </div>
62
+ </template>
@@ -0,0 +1,20 @@
1
+ type __VLS_Props = {
2
+ modelValue: string;
3
+ };
4
+ declare var __VLS_1: {};
5
+ type __VLS_Slots = {} & {
6
+ default?: (props: typeof __VLS_1) => any;
7
+ };
8
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
9
+ "update:modelValue": (value: string) => any;
10
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
11
+ "onUpdate:modelValue"?: ((value: string) => any) | undefined;
12
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
13
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
14
+ declare const _default: typeof __VLS_export;
15
+ export default _default;
16
+ type __VLS_WithSlots<T, S> = T & {
17
+ new (): {
18
+ $slots: S;
19
+ };
20
+ };
@@ -0,0 +1,208 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
2
+ contentClass: {
3
+ readonly type: StringConstructor;
4
+ readonly default: "";
5
+ };
6
+ contentStyle: {
7
+ readonly type: StringConstructor;
8
+ readonly default: "";
9
+ };
10
+ textColor: {
11
+ readonly type: StringConstructor;
12
+ readonly default: "";
13
+ };
14
+ disable: {
15
+ readonly type: BooleanConstructor;
16
+ readonly default: false;
17
+ };
18
+ loading: {
19
+ readonly type: BooleanConstructor;
20
+ readonly default: false;
21
+ };
22
+ color: {
23
+ readonly type: StringConstructor;
24
+ readonly default: "blue-900";
25
+ };
26
+ rounded: {
27
+ readonly type: StringConstructor;
28
+ readonly default: "md";
29
+ };
30
+ size: {
31
+ readonly type: StringConstructor;
32
+ readonly default: "md";
33
+ };
34
+ iconSize: {
35
+ readonly type: StringConstructor;
36
+ readonly default: "lg";
37
+ };
38
+ modelValue: {
39
+ type: StringConstructor;
40
+ default: string;
41
+ };
42
+ label: {
43
+ type: StringConstructor;
44
+ default: string;
45
+ };
46
+ placeholder: {
47
+ type: StringConstructor;
48
+ default: string;
49
+ };
50
+ rows: {
51
+ type: NumberConstructor;
52
+ default: number;
53
+ };
54
+ maxRows: {
55
+ type: NumberConstructor;
56
+ default: number;
57
+ };
58
+ autoGrow: {
59
+ type: BooleanConstructor;
60
+ default: boolean;
61
+ };
62
+ readonly: {
63
+ type: BooleanConstructor;
64
+ default: boolean;
65
+ };
66
+ error: {
67
+ type: BooleanConstructor;
68
+ default: boolean;
69
+ };
70
+ errorMessage: {
71
+ type: StringConstructor;
72
+ default: string;
73
+ };
74
+ hint: {
75
+ type: StringConstructor;
76
+ default: string;
77
+ };
78
+ showWordCount: {
79
+ type: BooleanConstructor;
80
+ default: boolean;
81
+ };
82
+ showCharCount: {
83
+ type: BooleanConstructor;
84
+ default: boolean;
85
+ };
86
+ maxlength: {
87
+ type: NumberConstructor;
88
+ default: undefined;
89
+ };
90
+ }>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
91
+ "update:modelValue": (...args: any[]) => void;
92
+ }, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
93
+ contentClass: {
94
+ readonly type: StringConstructor;
95
+ readonly default: "";
96
+ };
97
+ contentStyle: {
98
+ readonly type: StringConstructor;
99
+ readonly default: "";
100
+ };
101
+ textColor: {
102
+ readonly type: StringConstructor;
103
+ readonly default: "";
104
+ };
105
+ disable: {
106
+ readonly type: BooleanConstructor;
107
+ readonly default: false;
108
+ };
109
+ loading: {
110
+ readonly type: BooleanConstructor;
111
+ readonly default: false;
112
+ };
113
+ color: {
114
+ readonly type: StringConstructor;
115
+ readonly default: "blue-900";
116
+ };
117
+ rounded: {
118
+ readonly type: StringConstructor;
119
+ readonly default: "md";
120
+ };
121
+ size: {
122
+ readonly type: StringConstructor;
123
+ readonly default: "md";
124
+ };
125
+ iconSize: {
126
+ readonly type: StringConstructor;
127
+ readonly default: "lg";
128
+ };
129
+ modelValue: {
130
+ type: StringConstructor;
131
+ default: string;
132
+ };
133
+ label: {
134
+ type: StringConstructor;
135
+ default: string;
136
+ };
137
+ placeholder: {
138
+ type: StringConstructor;
139
+ default: string;
140
+ };
141
+ rows: {
142
+ type: NumberConstructor;
143
+ default: number;
144
+ };
145
+ maxRows: {
146
+ type: NumberConstructor;
147
+ default: number;
148
+ };
149
+ autoGrow: {
150
+ type: BooleanConstructor;
151
+ default: boolean;
152
+ };
153
+ readonly: {
154
+ type: BooleanConstructor;
155
+ default: boolean;
156
+ };
157
+ error: {
158
+ type: BooleanConstructor;
159
+ default: boolean;
160
+ };
161
+ errorMessage: {
162
+ type: StringConstructor;
163
+ default: string;
164
+ };
165
+ hint: {
166
+ type: StringConstructor;
167
+ default: string;
168
+ };
169
+ showWordCount: {
170
+ type: BooleanConstructor;
171
+ default: boolean;
172
+ };
173
+ showCharCount: {
174
+ type: BooleanConstructor;
175
+ default: boolean;
176
+ };
177
+ maxlength: {
178
+ type: NumberConstructor;
179
+ default: undefined;
180
+ };
181
+ }>> & Readonly<{
182
+ "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
183
+ }>, {
184
+ modelValue: string;
185
+ label: string;
186
+ contentClass: string;
187
+ contentStyle: string;
188
+ textColor: string;
189
+ disable: boolean;
190
+ loading: boolean;
191
+ color: string;
192
+ rounded: string;
193
+ size: string;
194
+ iconSize: string;
195
+ placeholder: string;
196
+ readonly: boolean;
197
+ error: boolean;
198
+ hint: string;
199
+ errorMessage: string;
200
+ maxlength: number;
201
+ rows: number;
202
+ maxRows: number;
203
+ autoGrow: boolean;
204
+ showWordCount: boolean;
205
+ showCharCount: boolean;
206
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
207
+ declare const _default: typeof __VLS_export;
208
+ export default _default;
@@ -0,0 +1,185 @@
1
+ <script setup>
2
+ defineOptions({
3
+ inheritAttrs: false
4
+ });
5
+ import { computed, ref, watch, nextTick } from "vue";
6
+ import { useUiClasses } from "./useUiClasses";
7
+ import { uiProps } from "./uiProps";
8
+ const props = defineProps({
9
+ modelValue: {
10
+ type: String,
11
+ default: ""
12
+ },
13
+ label: {
14
+ type: String,
15
+ default: ""
16
+ },
17
+ placeholder: {
18
+ type: String,
19
+ default: ""
20
+ },
21
+ rows: {
22
+ type: Number,
23
+ default: 3
24
+ },
25
+ maxRows: {
26
+ type: Number,
27
+ default: 10
28
+ },
29
+ autoGrow: {
30
+ type: Boolean,
31
+ default: false
32
+ },
33
+ readonly: {
34
+ type: Boolean,
35
+ default: false
36
+ },
37
+ error: {
38
+ type: Boolean,
39
+ default: false
40
+ },
41
+ errorMessage: {
42
+ type: String,
43
+ default: ""
44
+ },
45
+ hint: {
46
+ type: String,
47
+ default: ""
48
+ },
49
+ showWordCount: {
50
+ type: Boolean,
51
+ default: false
52
+ },
53
+ showCharCount: {
54
+ type: Boolean,
55
+ default: false
56
+ },
57
+ maxlength: {
58
+ type: Number,
59
+ default: void 0
60
+ },
61
+ ...uiProps
62
+ });
63
+ const emit = defineEmits([
64
+ "update:modelValue"
65
+ ]);
66
+ const textareaRef = ref();
67
+ const {
68
+ contentClass,
69
+ contentStyle,
70
+ color,
71
+ textColor,
72
+ rounded,
73
+ size,
74
+ disable,
75
+ roundedClass,
76
+ sizeClass,
77
+ computedContentClass,
78
+ isHex
79
+ } = useUiClasses(props);
80
+ const paddingClass = {
81
+ sm: "px-3 py-2",
82
+ md: "px-4 py-3",
83
+ lg: "px-5 py-4"
84
+ };
85
+ const textareaStyle = computed(() => {
86
+ const style = {
87
+ ...typeof contentStyle.value === "object" && contentStyle.value !== null ? contentStyle.value : {}
88
+ };
89
+ if (isHex(color.value)) {
90
+ style.borderColor = color.value;
91
+ }
92
+ if (isHex(textColor.value)) {
93
+ style.color = textColor.value;
94
+ }
95
+ return style;
96
+ });
97
+ const textareaClass = computed(() => {
98
+ const rKey = rounded.value;
99
+ const sKey = size.value;
100
+ const pKey = size.value;
101
+ const rClass = roundedClass[rKey] ?? "";
102
+ const sClass = sizeClass[sKey] ?? "";
103
+ const pClass = paddingClass[pKey] ?? "";
104
+ let cls = `
105
+ w-full
106
+ border
107
+ transition-all
108
+ duration-300
109
+ focus:outline-none
110
+ focus:ring-2
111
+ ${rClass}
112
+ ${sClass}
113
+ ${pClass}
114
+ `;
115
+ if (disable.value) {
116
+ cls += " opacity-50 cursor-not-allowed";
117
+ }
118
+ if (props.error) {
119
+ cls += " border-red-500";
120
+ } else if (!isHex(color.value)) {
121
+ cls += ` border-${color.value}`;
122
+ }
123
+ if (textColor.value && !isHex(textColor.value)) {
124
+ cls += ` text-${textColor.value}`;
125
+ }
126
+ cls += ` ${computedContentClass.value}`;
127
+ cls += ` ${contentClass.value || ""}`;
128
+ return cls;
129
+ });
130
+ const wordCount = computed(() => {
131
+ return props.modelValue.trim().split(/\s+/).filter(Boolean).length;
132
+ });
133
+ const charCount = computed(() => {
134
+ return props.modelValue.length;
135
+ });
136
+ function updateValue(event) {
137
+ emit(
138
+ "update:modelValue",
139
+ event.target.value
140
+ );
141
+ }
142
+ function resizeTextarea() {
143
+ if (!props.autoGrow) return;
144
+ if (!textareaRef.value) return;
145
+ textareaRef.value.style.height = "auto";
146
+ textareaRef.value.style.height = textareaRef.value.scrollHeight + "px";
147
+ }
148
+ watch(
149
+ () => props.modelValue,
150
+ async () => {
151
+ await nextTick();
152
+ resizeTextarea();
153
+ },
154
+ { immediate: true }
155
+ );
156
+ </script>
157
+
158
+ <template>
159
+ <div class="flex flex-col gap-1">
160
+ <label v-if="label" class="font-medium">
161
+ {{ label }}
162
+ </label>
163
+
164
+ <textarea ref="textareaRef" :value="modelValue" :rows="rows" :placeholder="placeholder" :disabled="disable"
165
+ :readonly="readonly" :maxlength="maxlength" :class="textareaClass" :style="textareaStyle"
166
+ @input="updateValue" v-bind="$attrs" />
167
+ <div class="flex justify-between text-xs text-gray-500">
168
+ <span>
169
+ {{ error ? errorMessage : hint }}
170
+ </span>
171
+ <span class="flex gap-3">
172
+ <span v-if="showWordCount">
173
+ {{ wordCount }} words
174
+ </span>
175
+
176
+ <span v-if="showCharCount">
177
+ {{ charCount }}
178
+ <template v-if="maxlength">
179
+ / {{ maxlength }}
180
+ </template>
181
+ </span>
182
+ </span>
183
+ </div>
184
+ </div>
185
+ </template>