srcdev-nuxt-forms 6.0.1 → 6.1.1

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 (40) hide show
  1. package/README.md +45 -5
  2. package/app/assets/styles/extends-layer/srcdev-forms/components/_form-fieldset.css +1 -1
  3. package/app/assets/styles/extends-layer/srcdev-forms/components/_input-button.css +1 -1
  4. package/app/assets/styles/extends-layer/srcdev-forms/components/_input-checkbox-radio-core.css +1 -1
  5. package/app/assets/styles/extends-layer/srcdev-forms/components/_input-checkbox-radio-options-button.css +1 -1
  6. package/app/assets/styles/extends-layer/srcdev-forms/components/_input-error.css +1 -1
  7. package/app/assets/styles/extends-layer/srcdev-forms/components/_input-label.css +1 -1
  8. package/app/assets/styles/extends-layer/srcdev-forms/components/_input-select.css +1 -1
  9. package/app/assets/styles/extends-layer/srcdev-forms/components/_input-text.css +1 -1
  10. package/app/assets/styles/extends-layer/srcdev-forms/components/_input-textarea.css +1 -1
  11. package/app/assets/styles/setup/_head.css +1 -1
  12. package/app/assets/styles/setup/typography/vars/_reponsive-font-sizes.css +10 -10
  13. package/app/assets/styles/setup/typography/vars/index.css +0 -1
  14. package/app/components/forms/form-fieldset/FormFieldset.vue +19 -10
  15. package/app/components/forms/input-button/InputButtonCore.vue +25 -28
  16. package/app/components/forms/input-checkbox/MultipleCheckboxes.vue +48 -27
  17. package/app/components/forms/input-checkbox/SingleCheckbox.vue +52 -33
  18. package/app/components/forms/input-checkbox-radio/InputCheckboxRadioButton.vue +40 -22
  19. package/app/components/forms/input-checkbox-radio/InputCheckboxRadioWithLabel.vue +33 -17
  20. package/app/components/forms/input-label/InputLabel.vue +10 -12
  21. package/app/components/forms/input-number/InputNumberCore.vue +26 -22
  22. package/app/components/forms/input-number/variants/InputNumberDefault.vue +50 -27
  23. package/app/components/forms/input-radio/MultipleRadiobuttons.vue +31 -25
  24. package/app/components/forms/input-range/InputRangeCore.vue +30 -28
  25. package/app/components/forms/input-range/variants/InputRangeDefault.vue +45 -28
  26. package/app/components/forms/input-range-fancy/InputRangeFancyWithLabel.vue +31 -18
  27. package/app/components/forms/input-select/variants/InputSelectWithLabel.vue +48 -37
  28. package/app/components/forms/input-text/InputTextCore.vue +56 -52
  29. package/app/components/forms/input-text/variants/InputTextAsNumberWithLabel.vue +42 -33
  30. package/app/components/forms/input-text/variants/InputTextWithLabel.vue +51 -42
  31. package/app/components/forms/input-textarea/InputTextareaCore.vue +29 -24
  32. package/app/components/forms/input-textarea/variants/InputTextareaWithLabel.vue +41 -31
  33. package/app/components/forms/toggle-switch/ToggleSwitchCore.vue +43 -25
  34. package/app/components/forms/toggle-switch/ToggleSwitchCoreOld.vue +36 -22
  35. package/app/components/forms/toggle-switch/variants/ToggleSwitchWithLabel.vue +42 -25
  36. package/app/components/forms/toggle-switch/variants/ToggleSwitchWithLabelInline.vue +30 -26
  37. package/nuxt.config.ts +11 -11
  38. package/package.json +2 -2
  39. package/app/assets/styles/setup/typography/vars/_colors.css +0 -14
  40. package/app/assets/styles/setup/variables/index.css +0 -1
@@ -4,9 +4,16 @@
4
4
  :data-theme="formTheme"
5
5
  :data-size="size"
6
6
  :data-inputmode="inputmode"
7
- :class="[inputVariant, { dirty: isDirty }, { active: isActive }, { error: fieldHasError }, { 'has-left-slot': hasLeftSlot }, { 'has-right-slot': hasRightSlot }]"
7
+ :class="[
8
+ inputVariant,
9
+ { dirty: isDirty },
10
+ { active: isActive },
11
+ { error: fieldHasError },
12
+ { 'has-left-slot': slots.left },
13
+ { 'has-right-slot': slots.right },
14
+ ]"
8
15
  >
9
- <span v-if="hasLeftSlot" class="slot left-slot">
16
+ <span v-if="slots.left" class="slot left-slot">
10
17
  <slot name="left"></slot>
11
18
  </span>
12
19
 
@@ -28,29 +35,28 @@
28
35
  @focusout="updateFocus(false)"
29
36
  />
30
37
 
31
- <span v-if="hasRightSlot" class="slot right-slot">
38
+ <span v-if="slots.right" class="slot right-slot">
32
39
  <slot name="right"></slot>
33
40
  </span>
34
41
  </div>
35
42
  </template>
36
43
 
37
44
  <script setup lang="ts">
38
- import propValidators from '../c12/prop-validators';
45
+ import propValidators from "../c12/prop-validators"
39
46
 
40
47
  const props = defineProps({
41
48
  type: {
42
- type: String as PropType<'text' | 'email' | 'password' | 'number' | 'tel' | 'url'>,
43
- // type: String,
44
- default: 'text',
49
+ type: String as PropType<"text" | "email" | "password" | "number" | "tel" | "url">,
50
+ default: "text",
45
51
  validator(value: string) {
46
- return propValidators.inputTypesText.includes(value);
52
+ return propValidators.inputTypesText.includes(value)
47
53
  },
48
54
  },
49
55
  inputmode: {
50
- type: String as PropType<'text' | 'email' | 'tel' | 'url' | 'search' | 'numeric' | 'none' | 'decimal'>,
51
- default: 'text',
56
+ type: String as PropType<"text" | "email" | "tel" | "url" | "search" | "numeric" | "none" | "decimal">,
57
+ default: "text",
52
58
  validator(value: string) {
53
- return propValidators.inputMode.includes(value);
59
+ return propValidators.inputMode.includes(value)
54
60
  },
55
61
  },
56
62
  maxlength: {
@@ -71,7 +77,7 @@ const props = defineProps({
71
77
  },
72
78
  placeholder: {
73
79
  type: String,
74
- default: '',
80
+ default: "",
75
81
  },
76
82
  fieldHasError: {
77
83
  type: Boolean,
@@ -83,9 +89,9 @@ const props = defineProps({
83
89
  },
84
90
  theme: {
85
91
  type: String as PropType<string>,
86
- default: 'primary',
92
+ default: "primary",
87
93
  validator(value: string) {
88
- return propValidators.theme.includes(value);
94
+ return propValidators.theme.includes(value)
89
95
  },
90
96
  },
91
97
  ariaDescribedby: {
@@ -94,66 +100,64 @@ const props = defineProps({
94
100
  },
95
101
  size: {
96
102
  type: String as PropType<string>,
97
- default: 'default',
103
+ default: "default",
98
104
  validator(value: string) {
99
- return propValidators.size.includes(value);
105
+ return propValidators.size.includes(value)
100
106
  },
101
107
  },
102
108
  inputVariant: {
103
109
  type: String as PropType<string>,
104
- default: 'normal',
110
+ default: "normal",
105
111
  validator(value: string) {
106
- return propValidators.inputVariant.includes(value);
112
+ return propValidators.inputVariant.includes(value)
107
113
  },
108
114
  },
109
- });
115
+ })
110
116
 
111
- const slots = useSlots();
112
- const hasLeftSlot = computed(() => slots.left !== undefined);
113
- const hasRightSlot = computed(() => slots.right !== undefined);
117
+ const slots = useSlots()
114
118
 
115
119
  const formTheme = computed(() => {
116
- return props.fieldHasError ? 'error' : props.theme;
117
- });
120
+ return props.fieldHasError ? "error" : props.theme
121
+ })
118
122
 
119
- const modelValue = defineModel();
120
- const isDirty = defineModel('isDirty');
121
- const isActive = defineModel('isActive');
123
+ const modelValue = defineModel()
124
+ const isDirty = defineModel("isDirty")
125
+ const isActive = defineModel("isActive")
122
126
 
123
127
  const inputPattern = computed(() => {
124
- return props.inputmode === 'numeric' ? '[0-9]+' : undefined;
125
- });
128
+ return props.inputmode === "numeric" ? "[0-9]+" : undefined
129
+ })
126
130
 
127
131
  const updateFocus = (isFocused: boolean) => {
128
- isActive.value = isFocused;
129
- };
132
+ isActive.value = isFocused
133
+ }
130
134
 
131
- const inputField = ref<HTMLInputElement | null>(null);
135
+ const inputField = ref<HTMLInputElement | null>(null)
132
136
 
133
- const { elementClasses } = useStyleClassPassthrough(props.styleClassPassthrough);
137
+ const { elementClasses } = useStyleClassPassthrough(props.styleClassPassthrough)
134
138
 
135
139
  // TODO: Move this to a utility function to allow removeEventListener on unmounted
136
140
  // Leaving like this could lead to memory leaks
137
141
  const validateInput = () => {
138
142
  if (inputField.value !== null) {
139
- inputField.value.addEventListener('beforeinput', (event: any) => {
140
- let beforeValue = modelValue.value;
143
+ inputField.value.addEventListener("beforeinput", (event: any) => {
144
+ let beforeValue = modelValue.value
141
145
  event.target.addEventListener(
142
- 'input',
146
+ "input",
143
147
  () => {
144
148
  if (inputField.value !== null && inputField.value.validity.patternMismatch) {
145
- inputField.value.value = beforeValue as string;
149
+ inputField.value.value = beforeValue as string
146
150
  }
147
151
  },
148
152
  { once: true }
149
- );
150
- });
153
+ )
154
+ })
151
155
  }
152
- };
156
+ }
153
157
 
154
158
  onMounted(() => {
155
- if (props.inputmode === 'numeric') validateInput();
156
- });
159
+ if (props.inputmode === "numeric") validateInput()
160
+ })
157
161
  </script>
158
162
 
159
163
  <style lang="css">
@@ -197,13 +201,13 @@ onMounted(() => {
197
201
  place-items: center;
198
202
  background-clip: padding-box;
199
203
 
200
- &.left-slot:not([data-theme='input-action']) {
204
+ &.left-slot:not([data-theme="input-action"]) {
201
205
  .icon {
202
206
  width: 2.2rem;
203
207
  height: 2.2rem;
204
208
  }
205
209
 
206
- [data-theme='input-action'] {
210
+ [data-theme="input-action"] {
207
211
  width: initial;
208
212
  height: initial;
209
213
  padding: 0.5rem;
@@ -214,13 +218,13 @@ onMounted(() => {
214
218
  }
215
219
  }
216
220
  }
217
- &.right-slot:not([data-theme='input-action']) {
221
+ &.right-slot:not([data-theme="input-action"]) {
218
222
  .icon {
219
223
  width: 2.2rem;
220
224
  height: 2.2rem;
221
225
  }
222
226
 
223
- [data-theme='input-action'] {
227
+ [data-theme="input-action"] {
224
228
  width: initial;
225
229
  height: initial;
226
230
  padding: 0.5rem;
@@ -233,12 +237,12 @@ onMounted(() => {
233
237
  }
234
238
  }
235
239
 
236
- &[data-inputmode='numeric'] {
240
+ &[data-inputmode="numeric"] {
237
241
  padding-block: 0rem;
238
242
  padding-inline: 0.75rem;
239
243
 
240
244
  .slot {
241
- [data-theme='input-action'] {
245
+ [data-theme="input-action"] {
242
246
  width: initial;
243
247
  height: initial;
244
248
  padding: 0.5rem;
@@ -281,13 +285,13 @@ onMounted(() => {
281
285
  place-items: center;
282
286
  background-clip: padding-box;
283
287
 
284
- &.left-slot:not([data-theme='input-action-underlined']) {
288
+ &.left-slot:not([data-theme="input-action-underlined"]) {
285
289
  .icon {
286
290
  width: 2.2rem;
287
291
  height: 2.2rem;
288
292
  }
289
293
 
290
- [data-theme='input-action-underlined'] {
294
+ [data-theme="input-action-underlined"] {
291
295
  width: initial;
292
296
  height: initial;
293
297
  padding: 0.5rem;
@@ -298,13 +302,13 @@ onMounted(() => {
298
302
  }
299
303
  }
300
304
  }
301
- &.right-slot:not([data-theme='input-action-underlined']) {
305
+ &.right-slot:not([data-theme="input-action-underlined"]) {
302
306
  .icon {
303
307
  width: 2.2rem;
304
308
  height: 2.2rem;
305
309
  }
306
310
 
307
- [data-theme='input-action-underlined'] {
311
+ [data-theme="input-action-underlined"] {
308
312
  width: initial;
309
313
  height: initial;
310
314
  padding: 0.5rem;
@@ -1,10 +1,22 @@
1
1
  <template>
2
- <div class="input-text-with-label" :data-theme="formTheme" :class="[inputVariant, elementClasses, { dirty: isDirty }, { active: isActive }]">
3
- <InputLabel :for="id" :id :theme :name :input-variant :field-has-error :style-class-passthrough="['input-text-label', 'body-normal-bold']">
2
+ <div
3
+ class="input-text-with-label"
4
+ :data-theme="formTheme"
5
+ :class="[inputVariant, elementClasses, { dirty: isDirty }, { active: isActive }]"
6
+ >
7
+ <InputLabel
8
+ :for="id"
9
+ :id
10
+ :theme
11
+ :name
12
+ :input-variant
13
+ :field-has-error
14
+ :style-class-passthrough="['input-text-label', 'body-normal-bold']"
15
+ >
4
16
  <template #textLabel>{{ label }}</template>
5
17
  </InputLabel>
6
18
 
7
- <div v-if="hasDescriptionSlot" :id="`${id}-description`">
19
+ <div v-if="slots.description" :id="`${id}-description`">
8
20
  <slot name="description"></slot>
9
21
  </div>
10
22
 
@@ -28,7 +40,7 @@
28
40
  :size
29
41
  :inputVariant
30
42
  >
31
- <template v-if="hasLeftSlot" #left>
43
+ <template v-if="slots.left" #left>
32
44
  <InputButtonCore
33
45
  type="button"
34
46
  @click.stop.prevent="updateValue(-step, Number(modelValue) > min)"
@@ -43,7 +55,7 @@
43
55
  </template>
44
56
  </InputButtonCore>
45
57
  </template>
46
- <template v-if="hasRightSlot" #right>
58
+ <template v-if="slots.right" #right>
47
59
  <InputButtonCore
48
60
  type="button"
49
61
  @click.stop.prevent="updateValue(step, Number(modelValue) < max)"
@@ -64,7 +76,7 @@
64
76
  </template>
65
77
 
66
78
  <script setup lang="ts">
67
- import propValidators from '../../c12/prop-validators';
79
+ import propValidators from "../../c12/prop-validators"
68
80
  const props = defineProps({
69
81
  maxlength: {
70
82
  type: Number,
@@ -76,7 +88,7 @@ const props = defineProps({
76
88
  },
77
89
  placeholder: {
78
90
  type: String,
79
- default: '',
91
+ default: "",
80
92
  },
81
93
  label: {
82
94
  type: String,
@@ -100,9 +112,9 @@ const props = defineProps({
100
112
  },
101
113
  theme: {
102
114
  type: String as PropType<string>,
103
- default: 'primary',
115
+ default: "primary",
104
116
  validator(value: string) {
105
- return propValidators.theme.includes(value);
117
+ return propValidators.theme.includes(value)
106
118
  },
107
119
  },
108
120
  min: {
@@ -119,50 +131,47 @@ const props = defineProps({
119
131
  },
120
132
  size: {
121
133
  type: String as PropType<string>,
122
- default: 'default',
134
+ default: "default",
123
135
  validator(value: string) {
124
- return propValidators.size.includes(value);
136
+ return propValidators.size.includes(value)
125
137
  },
126
138
  },
127
139
  inputVariant: {
128
140
  type: String as PropType<string>,
129
- default: 'normal',
141
+ default: "normal",
130
142
  validator(value: string) {
131
- return propValidators.inputVariant.includes(value);
143
+ return propValidators.inputVariant.includes(value)
132
144
  },
133
145
  },
134
- });
146
+ })
135
147
 
136
- const slots = useSlots();
137
- const hasDescriptionSlot = computed(() => slots.description !== undefined);
138
- const hasLeftSlot = computed(() => slots.left !== undefined);
139
- const hasRightSlot = computed(() => slots.right !== undefined);
148
+ const slots = useSlots()
140
149
 
141
150
  const formTheme = computed(() => {
142
- return props.fieldHasError ? 'error' : props.theme;
143
- });
151
+ return props.fieldHasError ? "error" : props.theme
152
+ })
144
153
 
145
- const id = useId();
146
- const errorId = `${id}-error-message`;
154
+ const id = useId()
155
+ const errorId = `${id}-error-message`
147
156
  const ariaDescribedby = computed(() => {
148
- const ariaDescribedbyId = hasDescriptionSlot.value ? `${id}-description` : undefined;
149
- return props.fieldHasError ? errorId : ariaDescribedbyId;
150
- });
157
+ const ariaDescribedbyId = slots.description ? `${id}-description` : undefined
158
+ return props.fieldHasError ? errorId : ariaDescribedbyId
159
+ })
151
160
 
152
- const modelValue = defineModel();
153
- const isActive = ref<boolean>(false);
154
- const isDirty = ref<boolean>(false);
161
+ const modelValue = defineModel()
162
+ const isActive = ref<boolean>(false)
163
+ const isDirty = ref<boolean>(false)
155
164
 
156
- const { elementClasses, updateElementClasses } = useStyleClassPassthrough(props.styleClassPassthrough);
157
- const minLength = computed(() => `${props.max.toString().length + 1}em`);
165
+ const { elementClasses, updateElementClasses } = useStyleClassPassthrough(props.styleClassPassthrough)
166
+ const minLength = computed(() => `${props.max.toString().length + 1}em`)
158
167
 
159
168
  const updateValue = (step: number, withinRangeLimit: boolean) => {
160
169
  if (withinRangeLimit) {
161
- modelValue.value = (Number(modelValue.value) + step) as number;
170
+ modelValue.value = (Number(modelValue.value) + step) as number
162
171
  }
163
- };
172
+ }
164
173
 
165
- updateElementClasses(['input-text-as-number', 'has-left-button', 'has-right-button']);
174
+ updateElementClasses(["input-text-as-number", "has-left-button", "has-right-button"])
166
175
  </script>
167
176
 
168
177
  <style lang="css">
@@ -1,11 +1,23 @@
1
1
  <template>
2
2
  <div>
3
- <div class="input-text-with-label" :data-theme="formTheme" :class="[elementClasses, inputVariant, { dirty: isDirty }, { active: isActive }]">
4
- <InputLabel :for="id" :id :theme :name :input-variant :field-has-error :style-class-passthrough="['input-text-label']">
3
+ <div
4
+ class="input-text-with-label"
5
+ :data-theme="formTheme"
6
+ :class="[elementClasses, inputVariant, { dirty: isDirty }, { active: isActive }]"
7
+ >
8
+ <InputLabel
9
+ :for="id"
10
+ :id
11
+ :theme
12
+ :name
13
+ :input-variant
14
+ :field-has-error
15
+ :style-class-passthrough="['input-text-label']"
16
+ >
5
17
  <template #textLabel>{{ label }}</template>
6
18
  </InputLabel>
7
19
 
8
- <div v-if="inputVariant === 'normal' && hasDescriptionSlot" :id="`${id}-description`">
20
+ <div v-if="inputVariant === 'normal' && slots.description" :id="`${id}-description`">
9
21
  <slot name="description"></slot>
10
22
  </div>
11
23
 
@@ -29,10 +41,10 @@
29
41
  :size
30
42
  :inputVariant
31
43
  >
32
- <template v-if="hasLeftSlot" #left>
44
+ <template v-if="slots.left" #left>
33
45
  <slot name="left"></slot>
34
46
  </template>
35
- <template v-if="hasRightSlot" #right>
47
+ <template v-if="slots.right" #right>
36
48
  <slot name="right"></slot>
37
49
  </template>
38
50
  </InputTextCore>
@@ -40,28 +52,28 @@
40
52
  <InputError :errorMessage :showError="fieldHasError" :id="errorId" :isDetached="false" :inputVariant />
41
53
  </div>
42
54
 
43
- <div v-if="inputVariant !== 'normal' && hasDescriptionSlot" :id="`${id}-description`">
55
+ <div v-if="inputVariant !== 'normal' && slots.description" :id="`${id}-description`">
44
56
  <slot name="description"></slot>
45
57
  </div>
46
58
  </div>
47
59
  </template>
48
60
 
49
61
  <script setup lang="ts">
50
- import propValidators from '../../c12/prop-validators';
62
+ import propValidators from "../../c12/prop-validators"
51
63
  const props = defineProps({
52
64
  maxlength: {
53
65
  type: Number,
54
66
  default: 255,
55
67
  },
56
68
  type: {
57
- type: String as PropType<'text' | 'email' | 'password' | 'number' | 'tel' | 'url'>,
69
+ type: String as PropType<"text" | "email" | "password" | "number" | "tel" | "url">,
58
70
  required: true,
59
71
  },
60
72
  inputmode: {
61
- type: String as PropType<'text' | 'email' | 'tel' | 'url' | 'search' | 'numeric' | 'none' | 'decimal'>,
62
- default: 'text',
73
+ type: String as PropType<"text" | "email" | "tel" | "url" | "search" | "numeric" | "none" | "decimal">,
74
+ default: "text",
63
75
  validator(value: string) {
64
- return propValidators.inputMode.includes(value);
76
+ return propValidators.inputMode.includes(value)
65
77
  },
66
78
  },
67
79
  name: {
@@ -70,7 +82,7 @@ const props = defineProps({
70
82
  },
71
83
  placeholder: {
72
84
  type: String,
73
- default: '',
85
+ default: "",
74
86
  },
75
87
  label: {
76
88
  type: String,
@@ -94,65 +106,62 @@ const props = defineProps({
94
106
  },
95
107
  theme: {
96
108
  type: String as PropType<string>,
97
- default: 'primary',
109
+ default: "primary",
98
110
  validator(value: string) {
99
- return propValidators.theme.includes(value);
111
+ return propValidators.theme.includes(value)
100
112
  },
101
113
  },
102
114
  size: {
103
115
  type: String as PropType<string>,
104
- default: 'default',
116
+ default: "default",
105
117
  validator(value: string) {
106
- return propValidators.size.includes(value);
118
+ return propValidators.size.includes(value)
107
119
  },
108
120
  },
109
121
  inputVariant: {
110
122
  type: String as PropType<string>,
111
- default: 'normal',
123
+ default: "normal",
112
124
  validator(value: string) {
113
- return propValidators.inputVariant.includes(value);
125
+ return propValidators.inputVariant.includes(value)
114
126
  },
115
127
  },
116
- });
128
+ })
117
129
 
118
- const slots = useSlots();
119
- const hasDescriptionSlot = computed(() => slots.description !== undefined);
120
- const hasLeftSlot = computed(() => slots.left !== undefined);
121
- const hasRightSlot = computed(() => slots.right !== undefined);
130
+ const slots = useSlots()
122
131
 
123
132
  const formTheme = computed(() => {
124
- return props.fieldHasError ? 'error' : props.theme;
125
- });
133
+ return props.fieldHasError ? "error" : props.theme
134
+ })
126
135
 
127
- const id = `${props.name}-${useId()}`;
128
- const errorId = `${id}-error-message`;
136
+ const id = `${props.name}-${useId()}`
137
+ const errorId = `${id}-error-message`
129
138
  const ariaDescribedby = computed(() => {
130
- const ariaDescribedbyId = hasDescriptionSlot.value ? `${id}-description` : undefined;
131
- return props.fieldHasError ? errorId : ariaDescribedbyId;
132
- });
139
+ const ariaDescribedbyId = slots.description ? `${id}-description` : undefined
140
+ return props.fieldHasError ? errorId : ariaDescribedbyId
141
+ })
133
142
 
134
- const modelValue = defineModel();
135
- const isActive = ref<boolean>(false);
136
- const isDirty = ref<boolean>(false);
143
+ const modelValue = defineModel()
144
+ const isActive = ref<boolean>(false)
145
+ const isDirty = ref<boolean>(false)
137
146
 
138
- const { elementClasses } = useStyleClassPassthrough(props.styleClassPassthrough);
147
+ const { elementClasses } = useStyleClassPassthrough(props.styleClassPassthrough)
139
148
 
140
149
  const testDirty = () => {
141
- const watchValue = modelValue.value ?? '';
150
+ const watchValue = modelValue.value ?? ""
142
151
 
143
- if (!isDirty.value && typeof watchValue === 'string' && watchValue.length > 0) {
144
- isDirty.value = true;
152
+ if (!isDirty.value && typeof watchValue === "string" && watchValue.length > 0) {
153
+ isDirty.value = true
145
154
  }
146
- };
155
+ }
147
156
 
148
157
  onMounted(() => {
149
- testDirty();
150
- });
158
+ testDirty()
159
+ })
151
160
 
152
161
  watch(
153
162
  () => modelValue.value,
154
163
  () => {
155
- testDirty();
164
+ testDirty()
156
165
  }
157
- );
166
+ )
158
167
  </script>
@@ -3,9 +3,16 @@
3
3
  class="input-textarea-wrapper"
4
4
  :data-theme="formTheme"
5
5
  :data-size="size"
6
- :class="[inputVariant, { dirty: isDirty }, { active: isActive }, { error: fieldHasError }, { 'has-left-slot': hasLeftSlot }, { 'has-right-slot': hasRightSlot }]"
6
+ :class="[
7
+ inputVariant,
8
+ { dirty: isDirty },
9
+ { active: isActive },
10
+ { error: fieldHasError },
11
+ { 'has-left-slot': slots.left },
12
+ { 'has-right-slot': slots.right },
13
+ ]"
7
14
  >
8
- <span v-if="hasLeftSlot" class="slot left-slot">
15
+ <span v-if="slots.left" class="slot left-slot">
9
16
  <slot name="left"></slot>
10
17
  </span>
11
18
 
@@ -24,14 +31,14 @@
24
31
  @focusout="updateFocus(false)"
25
32
  ></textarea>
26
33
 
27
- <span v-if="hasRightSlot" class="slot right-slot">
34
+ <span v-if="slots.right" class="slot right-slot">
28
35
  <slot name="right"></slot>
29
36
  </span>
30
37
  </div>
31
38
  </template>
32
39
 
33
40
  <script setup lang="ts">
34
- import propValidators from '../c12/prop-validators';
41
+ import propValidators from "../c12/prop-validators"
35
42
  const props = defineProps({
36
43
  maxlength: {
37
44
  type: Number,
@@ -47,7 +54,7 @@ const props = defineProps({
47
54
  },
48
55
  placeholder: {
49
56
  type: String,
50
- default: '',
57
+ default: "",
51
58
  },
52
59
  fieldHasError: {
53
60
  type: Boolean,
@@ -63,46 +70,44 @@ const props = defineProps({
63
70
  },
64
71
  theme: {
65
72
  type: String as PropType<string>,
66
- default: 'primary',
73
+ default: "primary",
67
74
  validator(value: string) {
68
- return propValidators.theme.includes(value);
75
+ return propValidators.theme.includes(value)
69
76
  },
70
77
  },
71
78
  size: {
72
79
  type: String as PropType<string>,
73
- default: 'default',
80
+ default: "default",
74
81
  validator(value: string) {
75
- return propValidators.size.includes(value);
82
+ return propValidators.size.includes(value)
76
83
  },
77
84
  },
78
85
  inputVariant: {
79
86
  type: String as PropType<string>,
80
- default: 'normal',
87
+ default: "normal",
81
88
  validator(value: string) {
82
- return propValidators.inputVariant.includes(value);
89
+ return propValidators.inputVariant.includes(value)
83
90
  },
84
91
  },
85
- });
92
+ })
86
93
 
87
- const slots = useSlots();
88
- const hasLeftSlot = computed(() => slots.left !== undefined);
89
- const hasRightSlot = computed(() => slots.right !== undefined);
94
+ const slots = useSlots()
90
95
 
91
96
  const formTheme = computed(() => {
92
- return props.fieldHasError ? 'error' : props.theme;
93
- });
97
+ return props.fieldHasError ? "error" : props.theme
98
+ })
94
99
 
95
- const modelValue = defineModel<string | number | readonly string[] | null | undefined>();
96
- const isDirty = defineModel('isDirty');
97
- const isActive = defineModel('isActive');
100
+ const modelValue = defineModel<string | number | readonly string[] | null | undefined>()
101
+ const isDirty = defineModel("isDirty")
102
+ const isActive = defineModel("isActive")
98
103
 
99
104
  const updateFocus = (isFocused: boolean) => {
100
- isActive.value = isFocused;
101
- };
105
+ isActive.value = isFocused
106
+ }
102
107
 
103
- const inputField = ref<HTMLInputElement | null>(null);
108
+ const inputField = ref<HTMLInputElement | null>(null)
104
109
 
105
- const { elementClasses } = useStyleClassPassthrough(props.styleClassPassthrough);
110
+ const { elementClasses } = useStyleClassPassthrough(props.styleClassPassthrough)
106
111
  </script>
107
112
 
108
113
  <style lang="css">