edvoyui-component-library-test-flight 0.0.22 → 0.0.24

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 (125) hide show
  1. package/dist/EUIButton.vue.d.ts.map +1 -0
  2. package/dist/inputNormal/EUIInputNormal.vue.d.ts.map +1 -0
  3. package/dist/library-vue-ts.cjs.js +1 -0
  4. package/dist/library-vue-ts.es.js +1 -0
  5. package/dist/library-vue-ts.umd.js +1 -0
  6. package/package.json +16 -13
  7. package/src/App.vue +16 -0
  8. package/src/assets/fonts/gilroy/GilroyBold/font.woff +0 -0
  9. package/src/assets/fonts/gilroy/GilroyBold/font.woff2 +0 -0
  10. package/src/assets/fonts/gilroy/GilroyBoldItalic/font.woff +0 -0
  11. package/src/assets/fonts/gilroy/GilroyBoldItalic/font.woff2 +0 -0
  12. package/src/assets/fonts/gilroy/GilroyExtraBold/font.woff +0 -0
  13. package/src/assets/fonts/gilroy/GilroyExtraBold/font.woff2 +0 -0
  14. package/src/assets/fonts/gilroy/GilroyExtraBoldItalic/font.woff +0 -0
  15. package/src/assets/fonts/gilroy/GilroyExtraBoldItalic/font.woff2 +0 -0
  16. package/src/assets/fonts/gilroy/GilroyMedium/font.woff +0 -0
  17. package/src/assets/fonts/gilroy/GilroyMedium/font.woff2 +0 -0
  18. package/src/assets/fonts/gilroy/GilroyRegular/font.woff +0 -0
  19. package/src/assets/fonts/gilroy/GilroyRegular/font.woff2 +0 -0
  20. package/src/assets/fonts/gilroy/GilroySemiBold/font.woff +0 -0
  21. package/src/assets/fonts/gilroy/GilroySemiBold/font.woff2 +0 -0
  22. package/src/assets/fonts/inter/Inter-Bold.woff +0 -0
  23. package/src/assets/fonts/inter/Inter-Bold.woff2 +0 -0
  24. package/src/assets/fonts/inter/Inter-Italic.woff +0 -0
  25. package/src/assets/fonts/inter/Inter-Italic.woff2 +0 -0
  26. package/src/assets/fonts/inter/Inter-Medium.woff +0 -0
  27. package/src/assets/fonts/inter/Inter-Medium.woff2 +0 -0
  28. package/src/assets/fonts/inter/Inter-MediumItalic.woff +0 -0
  29. package/src/assets/fonts/inter/Inter-MediumItalic.woff2 +0 -0
  30. package/src/assets/fonts/inter/Inter-Regular.woff +0 -0
  31. package/src/assets/fonts/inter/Inter-Regular.woff2 +0 -0
  32. package/src/assets/fonts/inter/Inter-SemiBold.woff +0 -0
  33. package/src/assets/fonts/inter/Inter-SemiBold.woff2 +0 -0
  34. package/src/assets/fonts/inter/Inter-SemiBoldItalic.woff +0 -0
  35. package/src/assets/fonts/inter/Inter-SemiBoldItalic.woff2 +0 -0
  36. package/src/assets/scss/body.scss +15 -0
  37. package/src/assets/svg/ChevronDownSolid.vue +19 -0
  38. package/src/assets/svg/ChevronDownStroke.vue +22 -0
  39. package/src/assets/svg/SortArrow.vue +24 -0
  40. package/src/assets/svg/Student.vue +30 -0
  41. package/src/assets/svg/partner.vue +33 -0
  42. package/src/assets/svg/people.vue +25 -0
  43. package/src/assets/vue.svg +1 -0
  44. package/src/components/HelloWorld.vue +999 -0
  45. package/src/components/accordion/EUIAccordion.stories.ts +157 -0
  46. package/src/components/accordion/EUIAccordion.vue +90 -0
  47. package/src/components/avatar/EUIAvatar.stories.ts +157 -0
  48. package/src/components/avatar/EUIAvatar.vue +96 -0
  49. package/src/components/button/EUIButton.stories.ts +252 -0
  50. package/src/components/button/EUIButton.vue +151 -0
  51. package/src/components/checkbox/EUICheckbox.stories.ts +58 -0
  52. package/src/components/checkbox/EUICheckbox.vue +103 -0
  53. package/src/components/datepicker/EUIDatepicker.stories.ts +280 -0
  54. package/src/components/datepicker/EUIDatepicker.vue +192 -0
  55. package/src/components/delete.vue +158 -0
  56. package/src/components/dropdown/EUIMultiDropdown.stories.ts +187 -0
  57. package/src/components/dropdown/EUIMultiDropdown.vue +129 -0
  58. package/src/components/errorMessage/EUIErrorMessage.scss +0 -0
  59. package/src/components/errorMessage/EUIErrorMessage.stories.ts +41 -0
  60. package/src/components/errorMessage/EUIErrorMessage.vue +25 -0
  61. package/src/components/index.ts +46 -0
  62. package/src/components/input/EUIInput.stories.ts +174 -0
  63. package/src/components/input/EUIInput.vue +169 -0
  64. package/src/components/inputNormal/EUIInputNormal.stories.ts +164 -0
  65. package/src/components/inputNormal/EUIInputNormal.vue +161 -0
  66. package/src/components/loader/EUICircleLoader.vue +31 -0
  67. package/src/components/loader/EUICubeLoader.vue +237 -0
  68. package/src/components/loader/EUILoader.stories.ts +99 -0
  69. package/src/components/loader/EUILoader.vue +17 -0
  70. package/src/components/loader/EUISquareLoader.vue +47 -0
  71. package/src/components/modal/EUIModal.stories.ts +372 -0
  72. package/src/components/modal/EUIModal.vue +163 -0
  73. package/src/components/pillSelect/EUIPillSelect.stories.ts +74 -0
  74. package/src/components/pillSelect/EUIPillSelect.vue +149 -0
  75. package/src/components/popover/EUIPopover.stories.ts +247 -0
  76. package/src/components/popover/EUIPopover.vue +159 -0
  77. package/src/components/radio/EUIRadio.stories.ts +54 -0
  78. package/src/components/radio/EUIRadio.vue +78 -0
  79. package/src/components/searchInput/EUISearch.stories.ts +24 -0
  80. package/src/components/searchInput/EUISearch.vue +215 -0
  81. package/src/components/select/EUISelect.scss +0 -0
  82. package/src/components/select/EUISelect.stories.ts +49 -0
  83. package/src/components/select/EUISelect.vue +682 -0
  84. package/src/components/selectSearch/EUISelectSearch.vue +23 -0
  85. package/src/components/slideover/EUISlideover.stories.ts +318 -0
  86. package/src/components/slideover/EUISlideover.vue +207 -0
  87. package/src/components/stepperTimeline/EUIStepperHorizontal.vue +112 -0
  88. package/src/components/stepperTimeline/EUIStepperTimeline.stories.ts +54 -0
  89. package/src/components/stepperTimeline/EUIStepperTimeline.vue +16 -0
  90. package/src/components/stepperTimeline/EUIStepperVertical.vue +112 -0
  91. package/src/components/table/EUIDashboardTable.vue +482 -0
  92. package/src/components/table/EUIPageLimit.vue +66 -0
  93. package/src/components/table/EUIPagination.vue +175 -0
  94. package/src/components/table/EUIStudentPagination.vue +172 -0
  95. package/src/components/table/EUITable.stories.ts +190 -0
  96. package/src/components/table/EUITable.vue +508 -0
  97. package/src/components/table/EUITableCheckbox.vue +97 -0
  98. package/src/components/tabs/EUITabs.vue +128 -0
  99. package/src/components/tabs/EUItabs.stories.ts +123 -0
  100. package/src/components/tag/EUITag.stories.ts +46 -0
  101. package/src/components/tag/EUITag.vue +46 -0
  102. package/src/components/telephone/EUITelephone.stories.ts +202 -0
  103. package/src/components/telephone/EUITelephone.vue +280 -0
  104. package/src/components/textArea/EUITextArea.stories.ts +82 -0
  105. package/src/components/textArea/EUITextArea.vue +122 -0
  106. package/src/components/timeLine/EUITimeLine.stories.ts +247 -0
  107. package/src/components/timeLine/EUITimeLine.vue +43 -0
  108. package/src/components/timeLine/EUITimeLineItem.vue +124 -0
  109. package/src/components/toggle/EUIToggle.stories.ts +63 -0
  110. package/src/components/toggle/EUIToggle.vue +99 -0
  111. package/src/components/tooltip/EUITooltip.stories.ts +53 -0
  112. package/src/components/tooltip/EUITooltip.vue +108 -0
  113. package/src/data/books.ts +163 -0
  114. package/src/data/tab.ts +33 -0
  115. package/src/data/table.ts +5392 -0
  116. package/src/main.ts +5 -0
  117. package/src/utils/lodash.ts +9 -0
  118. package/src/utils/types.ts +9 -0
  119. package/src/vite-env.d.ts +5 -0
  120. package/dist/EUIInputNormal.vue.d.ts.map +0 -1
  121. package/dist/button/EUIButton.vue.d.ts.map +0 -1
  122. package/dist/library-vue-ts.css +0 -1
  123. /package/dist/{button/EUIButton.vue.d.ts → EUIButton.vue.d.ts} +0 -0
  124. /package/dist/{EUIInputNormal.vue.d.ts → inputNormal/EUIInputNormal.vue.d.ts} +0 -0
  125. /package/{dist → src}/style.scss +0 -0
@@ -0,0 +1,280 @@
1
+ <template>
2
+ <div class="relative z-0">
3
+ <button
4
+ type="button"
5
+ :class="disabled ? 'pointer-events-none cursor-not-allowed' : ''"
6
+ class="relative w-full mb-2 bg-white border border-gray-100 cursor-pointer z-1 group h-14 rounded-2xl focus-within:border-purple-600 focus-within:ring-1 focus-within:ring-purple-600"
7
+ @click="focusInput"
8
+ >
9
+ <label
10
+ :for="`${name}-${id}`"
11
+ :class="[
12
+ getIconClass(),
13
+ inputValue
14
+ ? 'top-3.5 text-xs text-gray-400 leading-none cursor-default'
15
+ : 'top-1/2 text-sm w-full text-gray-700 cursor-pointer h-14 pt-5 pb-4 bg-white ring-1 ring-gray-200',
16
+ disabled ? ' cursor-not-allowed' : '',
17
+ required && `after:content-['*'] after:ml-0.5 after:text-red-500`,
18
+ ]"
19
+ class="absolute font-medium left-0 px-4 z-[1] -translate-y-1/2 duration-200 group-focus-within:top-3.5 group-focus-within:text-xs group-focus-within:text-gray-400 rounded-2xl group-focus-within:bg-transparent group-focus-within:-translate-y-1/2 group-focus-within:ring-transparent group-focus-within:h-auto group-focus-within:py-0 text-start first-letter:capitalize"
20
+ >
21
+ {{ label }}
22
+ </label>
23
+ <div
24
+ v-if="icon && iconType"
25
+ class="absolute inset-y-0 z-10 flex items-center pointer-events-none"
26
+ :class="[
27
+ iconType === 'startIcon' ? 'start-0 ps-3' : 'end-0 pe-3',
28
+ disabled ? 'cursor-not-allowed' : '',
29
+ ]"
30
+ >
31
+ <component
32
+ :is="icon"
33
+ class="w-6 h-6 text-gray-400"
34
+ aria-hidden="true"
35
+ />
36
+ </div>
37
+ <vue-tel-input
38
+ ref="inputRef"
39
+ v-model.trim="mobile"
40
+ v-bind="bindProps"
41
+ :class="[getIconClass()]"
42
+ @on-input="onInputChanged"
43
+ @country-changed="onCountryChanged"
44
+ @blur="$emit('blur')"
45
+ ></vue-tel-input>
46
+ </button>
47
+ <EUIErrorMessage :errors="errors" :name="name" />
48
+ <div class="errors" v-if="errorMessage">
49
+ <p class="mt-2 text-xs text-red-600">
50
+ {{ errorMessage }}
51
+ </p>
52
+ </div>
53
+ <div
54
+ class="absolute top-0 px-2 text-xs text-white rounded right-2"
55
+ :class="[
56
+ { 'bg-gray-400': tagColor === 'None' },
57
+ { 'bg-green-400': tagColor === 'Success' },
58
+ { 'bg-red-400': tagColor === 'Error' },
59
+ ]"
60
+ v-if="tag"
61
+ >
62
+ {{ tag }}
63
+ </div>
64
+ </div>
65
+ </template>
66
+ <script lang="ts" setup>
67
+ import { computed, onUpdated, PropType, ref, toRefs, watch } from "vue";
68
+ import { VueTelInput, VueTelInputCountryOption } from "vue-tel-input";
69
+ import "vue-tel-input/vue-tel-input.css";
70
+ import EUIErrorMessage from "../errorMessage/EUIErrorMessage.vue";
71
+ const emit = defineEmits(["update:modelValue", "blur", "update:isValid"]);
72
+ const props = defineProps({
73
+ modelValue: {
74
+ type: [String, Number],
75
+ default: "",
76
+ },
77
+ name: {
78
+ type: String,
79
+ default: "",
80
+ },
81
+ label: {
82
+ type: String,
83
+ default: "Mobile Number"
84
+ },
85
+ placeholder: {
86
+ type: String,
87
+ },
88
+ required: {
89
+ type: Boolean,
90
+ default: false,
91
+ },
92
+ readonly: {
93
+ type: Boolean,
94
+ },
95
+ disabled: {
96
+ type: Boolean,
97
+ },
98
+ autoFocus: {
99
+ type: Boolean,
100
+ required: false,
101
+ default: false,
102
+ },
103
+ errors: { type: Object, required: false, default: () => {} },
104
+ isValid: {
105
+ type: Boolean,
106
+ default: false,
107
+ },
108
+ tag: {
109
+ type: String,
110
+ default: "",
111
+ },
112
+ tagColor: {
113
+ type: String as PropType<"None" | "Success" | "Error">,
114
+ default: "None",
115
+ },
116
+ length: {
117
+ type: Number,
118
+ required: false,
119
+ default: 25,
120
+ },
121
+ iconType: {
122
+ type: String as PropType<"startIcon" | "endIcon">,
123
+ default: "",
124
+ },
125
+ icon: {
126
+ type: [Object, String],
127
+ default: "",
128
+ },
129
+ });
130
+ const { isValid } = toRefs(props);
131
+
132
+ const generateUID = () => {
133
+ const data = "euid-" + Math.random().toString(36).substr(2, 9) + "-" + Date.now().toString(36);
134
+ return data;
135
+ };
136
+ const id = generateUID();
137
+
138
+ const hasError = computed({
139
+ set: (value) => {
140
+ emit("update:isValid", value);
141
+ },
142
+ get: () => isValid.value,
143
+ });
144
+
145
+ const inputValue = computed(() => {
146
+ return props.modelValue === 0 ? true : !!props.modelValue;
147
+ });
148
+
149
+ const mobile = ref(props.modelValue);
150
+ const listener = computed(() => props.modelValue);
151
+ watch(listener, (value) => {
152
+ mobile.value = value;
153
+ });
154
+
155
+ const updateValue = computed(() => {
156
+ return {
157
+ focus: props.autoFocus,
158
+ place: props.placeholder,
159
+ disabled: props.disabled,
160
+ required: props.required,
161
+ name: props.name,
162
+ length: props.length,
163
+ readonly: props.readonly
164
+ };
165
+ });
166
+
167
+ const bindProps = {
168
+ mode: "international",
169
+ autoFormat: false,
170
+ autoDefaultCountry: true,
171
+ styleClasses: "eui-tel",
172
+ invalidMsg: "Required mobile number",
173
+ validCharactersOnly: true,
174
+ preferredCountries: [],
175
+ disabled: updateValue.value.disabled,
176
+ inputOptions: {
177
+ autocomplete: "off",
178
+ autofocus: updateValue.value.focus,
179
+ name: updateValue.value.name,
180
+ id: id,
181
+ placeholder: updateValue.value.place,
182
+ maxlength: updateValue.value.length,
183
+ showDialCode: true,
184
+ tabindex: 0,
185
+ readonly: updateValue.value.readonly,
186
+ required: updateValue.value.required,
187
+ styleClasses: "eui-tel_input",
188
+ },
189
+ dropdownOptions: {
190
+ disabled: false,
191
+ showFlags: true,
192
+ showDialCodeInList: true,
193
+ showSearchBox: true,
194
+ searchBoxPlaceholder: "Search country...",
195
+ },
196
+ };
197
+
198
+ const onInputChanged = (_formattedNumber: string, phoneObject: any) => {
199
+ console.log(phoneObject.number); // Debugging
200
+ hasError.value = phoneObject.valid ? true : false;
201
+ emit("update:modelValue", phoneObject.number);
202
+ };
203
+
204
+ const firstTime = ref(true);
205
+ const onCountryChanged = (_event: VueTelInputCountryOption) => {
206
+ if (!firstTime.value) {
207
+ emit("update:modelValue", "");
208
+ }
209
+ };
210
+
211
+ onUpdated(() => {
212
+ setTimeout(() => {
213
+ firstTime.value = false;
214
+ }, 1500);
215
+ });
216
+
217
+ const errorMessage = computed(() => {
218
+ if (Array.isArray(props.errors)) {
219
+ if (typeof props.errors?.at(0) === "object") {
220
+ return props.errors?.at(0)?.$message;
221
+ } else {
222
+ return props.errors[0];
223
+ }
224
+ } else {
225
+ if (typeof props.errors === "object") {
226
+ return props.errors?.[props.name];
227
+ } else {
228
+ return props.errors;
229
+ }
230
+ }
231
+ });
232
+
233
+ const getIconClass = () => {
234
+ switch (props.iconType) {
235
+ case "startIcon":
236
+ return "pl-12 pr-4";
237
+ case "endIcon":
238
+ return "pr-12 pl-4";
239
+ default:
240
+ return "px-4";
241
+ }
242
+ };
243
+
244
+ const inputRef = ref<HTMLElement | null>(null);
245
+ const focusInput = () => {
246
+ if (inputRef.value) {
247
+ inputRef.value?.focus();
248
+ }
249
+ };
250
+ </script>
251
+
252
+ <style lang="scss">
253
+ .vue-tel-input.eui-tel {
254
+ @apply rounded-none border-none focus-within:shadow-none focus-within:border-transparent;
255
+ .vti__dropdown {
256
+ @apply mt-4 p-2 ps-0 rounded-2xl hover:bg-transparent open:bg-transparent bg-transparent;
257
+ }
258
+ .vti__dropdown-list {
259
+ @apply rounded-md;
260
+ .vti__search_box_container {
261
+ @apply sticky top-0 left-0 p-1 pr-0 bg-white;
262
+ }
263
+ .vti__dropdown-item {
264
+ @apply text-sm text-gray-700 hover:text-gray-900;
265
+ strong {
266
+ @apply font-medium;
267
+ }
268
+ &.highlighted {
269
+ @apply bg-gray-100;
270
+ }
271
+ }
272
+ }
273
+ .vti__search_box {
274
+ @apply w-[98%] rounded-[4px] placeholder:text-sm;
275
+ }
276
+ .eui-tel_input {
277
+ @apply z-0 h-full w-full rounded-2xl pt-6 pb-3 placeholder:text-gray-400 focus:outline-none block text-sm font-medium appearance-none disabled:opacity-75 focus:border-purple-600 autofill:bg-white leading-6;
278
+ }
279
+ }
280
+ </style>
@@ -0,0 +1,82 @@
1
+ import type { Meta, StoryObj } from "@storybook/vue3";
2
+ import EUITextarea from "./EUITextArea.vue"; // Adjust the path if necessary
3
+
4
+ const meta = {
5
+ title: "Forms/Textarea",
6
+ component: EUITextarea,
7
+ tags: ["autodocs"],
8
+ argTypes: {
9
+ modelValue: {
10
+ control: "text",
11
+ description: "Two-way binding value for the textarea field.",
12
+ },
13
+ name: {
14
+ control: "text",
15
+ description:
16
+ "The `name` attribute of the input, typically used for form identification and validation.",
17
+ },
18
+ label: {
19
+ control: "text",
20
+ description:
21
+ "The label for the textarea field, usually displayed above or inside the textarea.",
22
+ },
23
+ placeholder: {
24
+ control: "text",
25
+ description: "Placeholder text for the textarea.",
26
+ },
27
+ rows: {
28
+ control: { type: "number", min: 1 },
29
+ description: "The number of rows for the textarea.",
30
+ },
31
+ cols: {
32
+ control: { type: "number", min: 1 },
33
+ description: "The number of columns for the textarea.",
34
+ },
35
+ errors: {
36
+ control: "object",
37
+ description:
38
+ "Validation errors object, with field names as keys and error messages as values.",
39
+ },
40
+ },
41
+ } satisfies Meta<typeof EUITextarea>;
42
+
43
+ export default meta;
44
+ type Story = StoryObj<typeof meta>;
45
+
46
+ // Default story for EUITextarea
47
+ export const Default: Story = {
48
+ args: {
49
+ label: "Description",
50
+ modelValue: "",
51
+ rows: 3,
52
+ cols: 150,
53
+ placeholder: "Enter some description here...",
54
+ },
55
+ };
56
+
57
+ // Story to demonstrate textarea with an error message
58
+ export const WithError: Story = {
59
+ args: {
60
+ label: "Description",
61
+ modelValue: "",
62
+ rows: 3,
63
+ cols: 150,
64
+ placeholder: "Enter your comments...",
65
+ errors: {
66
+ message: "This description field is required.",
67
+ },
68
+ },
69
+ };
70
+
71
+ // Story to demonstrate a pre-filled textarea
72
+ export const PrefilledTextarea: Story = {
73
+ args: {
74
+ label: "Description",
75
+ name: "messageDesc",
76
+ modelValue:
77
+ "Lorem ipsum dolor sit amet consectetur, adipisicing elit. Eum porro quia hic sed voluptatem, laudantium dignissimos sequi illo quasi error maxime vel nam deleniti adipisci itaque.",
78
+ rows: 3,
79
+ cols: 150,
80
+ placeholder: "Enter some text...",
81
+ },
82
+ };
@@ -0,0 +1,122 @@
1
+ <template>
2
+ <div class="relative">
3
+ <button
4
+ :class="[
5
+ disabled ? 'pointer-events-none cursor-not-allowed' : '',
6
+ 'group transition-all duration-100 ease-in-out outline-none border-none z-0 focus:border-purple-600 min-h-[4.5rem] mb-2 relative w-full rounded-md ring-1 ring-gray-200 focus-within:ring-2 focus-within:ring-purple-600 cursor-pointer overflow-hidden;',
7
+ ]"
8
+ @click="focusInput"
9
+ >
10
+ <label
11
+ for="text"
12
+ :class="[
13
+ inputValue
14
+ ? 'top-2 text-xs text-gray-400 cursor-default'
15
+ : 'top-4 text-sm text-gray-700 cursor-pointer pb-2',
16
+ disabled ? 'cursor-not-allowed' : '',
17
+ required && `after:content-['*'] after:ml-0.5 after:text-red-500`,
18
+ ]"
19
+ class="absolute left-0 z-10 w-full h-auto px-4 font-medium leading-normal text-left transition-all duration-100 ease-in-out transform translate-y-0 bg-white group-focus-within:top-2 group-focus-within:py-0"
20
+ >
21
+ {{ label }}
22
+ </label>
23
+ <textarea
24
+ ref="inputRef"
25
+ :class="[errors ? 'border-red-500' : '']"
26
+ class="min-h-[4.5rem] max-h-40 appearance-none block w-full px-4 py-2 placeholder:text-gray-400 text-sm font-medium relative z-0 mt-4 bg-transparent border-none focus:outline-none focus:shadow-none focus-within:outline-none focus:border-none disabled:opacity-75 autofill:bg-white leading-6 placeholder:capitalize rounded-2xl"
27
+ :placeholder="placeholder"
28
+ v-model="localValue"
29
+ :disabled="disabled"
30
+ :autofocus="autoFocus"
31
+ aria-invalid="true"
32
+ :rows="rows"
33
+ :cols="cols"
34
+ @input="$emit('update:modelValue', localValue)"
35
+ @blur="$emit('blur')"
36
+ >
37
+ </textarea>
38
+ </button>
39
+
40
+ </div>
41
+ <EUIErrorMessage :errors="errors" :name="name" />
42
+ </template>
43
+ <script setup lang="ts">
44
+ import { PropType, ref, watch, computed } from "vue";
45
+ import { ValidationErrors } from "../../utils/types";
46
+ import EUIErrorMessage from "../errorMessage/EUIErrorMessage.vue";
47
+
48
+ const props = defineProps({
49
+ errors: {
50
+ type: Object as PropType<ValidationErrors>,
51
+ required: false,
52
+ default: () => {},
53
+ },
54
+ modelValue: {
55
+ type: String as PropType<string>,
56
+ required: true,
57
+ default: "",
58
+ },
59
+ name: {
60
+ type: String,
61
+ required: false,
62
+ default: "",
63
+ },
64
+ label: {
65
+ type: String as PropType<string>,
66
+ required: true,
67
+ default: "",
68
+ },
69
+ placeholder: {
70
+ type: String as PropType<string>,
71
+ required: true,
72
+ default: "",
73
+ },
74
+ rows: {
75
+ type: Number as PropType<number>,
76
+ required: true,
77
+ default: 5,
78
+ },
79
+ cols: {
80
+ type: Number as PropType<number>,
81
+ required: true,
82
+ default: 0,
83
+ },
84
+ disabled: {
85
+ type: Boolean,
86
+ default: false,
87
+ required: false,
88
+ },
89
+ autoFocus: {
90
+ type: Boolean,
91
+ default: false,
92
+ },
93
+ required: {
94
+ type: Boolean,
95
+ default: false,
96
+ },
97
+ });
98
+
99
+ const { label, rows, cols, placeholder } = props;
100
+
101
+ const localValue = ref(props.modelValue);
102
+ const emit = defineEmits(["update:modelValue", "blur"]);
103
+
104
+ watch(() => props.modelValue, (newVal) => {
105
+ localValue.value = newVal;
106
+ });
107
+
108
+ const inputRef = ref<HTMLElement | null>(null);
109
+ const inputValue = computed(() => {
110
+ return !!localValue.value;
111
+ });
112
+
113
+ const focusInput = () => {
114
+ if (inputRef.value) {
115
+ inputRef.value?.focus();
116
+ }
117
+ };
118
+ </script>
119
+
120
+ <style lang="scss" scoped>
121
+
122
+ </style>