srcdev-nuxt-forms 3.0.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/assets/styles/ally/_utils.css +20 -0
  2. package/assets/styles/ally/_variables.css +8 -0
  3. package/assets/styles/ally/index.css +2 -0
  4. package/assets/styles/forms/index.css +2 -0
  5. package/assets/styles/forms/themes/_error.css +85 -0
  6. package/assets/styles/forms/themes/_ghost.css +85 -0
  7. package/assets/styles/forms/themes/_input-action-underlined.css +20 -0
  8. package/assets/styles/forms/themes/_input-action.css +20 -0
  9. package/assets/styles/forms/themes/_primary.css +92 -0
  10. package/assets/styles/forms/themes/_secondary.css +85 -0
  11. package/assets/styles/forms/themes/_success.css +85 -0
  12. package/assets/styles/forms/themes/_tertiary.css +85 -0
  13. package/assets/styles/forms/themes/_warning.css +85 -0
  14. package/assets/styles/forms/themes/index.css +9 -0
  15. package/assets/styles/forms/variables/_sizes.css +71 -0
  16. package/assets/styles/forms/variables/_theme.css +11 -0
  17. package/assets/styles/forms/variables/index.css +2 -0
  18. package/assets/styles/main.css +5 -0
  19. package/assets/styles/typography/index.css +2 -0
  20. package/assets/styles/typography/utils/_font-classes.css +190 -0
  21. package/assets/styles/typography/utils/_weights.css +69 -0
  22. package/assets/styles/typography/utils/index.css +2 -0
  23. package/assets/styles/typography/variables/_colors.css +14 -0
  24. package/assets/styles/typography/variables/_reponsive-font-size.css +10 -0
  25. package/assets/styles/typography/variables/index.css +2 -0
  26. package/assets/styles/utils/_margin-helpers.css +334 -0
  27. package/assets/styles/utils/_padding-helpers.css +308 -0
  28. package/assets/styles/utils/_page.css +49 -0
  29. package/assets/styles/utils/index.css +3 -0
  30. package/assets/styles/variables/colors/_blue.css +15 -0
  31. package/assets/styles/variables/colors/_gray.css +16 -0
  32. package/assets/styles/variables/colors/_green.css +15 -0
  33. package/assets/styles/variables/colors/_orange.css +15 -0
  34. package/assets/styles/variables/colors/_red.css +15 -0
  35. package/assets/styles/variables/colors/_yellow.css +15 -0
  36. package/assets/styles/variables/colors/colors.css +6 -0
  37. package/assets/styles/variables/index.css +1 -0
  38. package/components/forms/c12/prop-validators/index.ts +38 -0
  39. package/components/forms/c12/utils.ts +14 -0
  40. package/components/forms/form-errors/InputError.vue +172 -0
  41. package/components/forms/form-errors/tests/InputError.spec.ts +67 -0
  42. package/components/forms/input-button/InputButtonCore.vue +191 -0
  43. package/components/forms/input-button/variants/InputButtonConfirm.vue +66 -0
  44. package/components/forms/input-button/variants/InputButtonSubmit.vue +62 -0
  45. package/components/forms/input-checkbox/MultipleCheckboxes.vue +203 -0
  46. package/components/forms/input-checkbox/SingleCheckbox.vue +169 -0
  47. package/components/forms/input-checkbox/tests/MultipleCheckboxes.spec.ts +98 -0
  48. package/components/forms/input-checkbox/tests/data/tags.json +67 -0
  49. package/components/forms/input-checkbox-radio/InputCheckboxRadioButton.vue +214 -0
  50. package/components/forms/input-checkbox-radio/InputCheckboxRadioCore.vue +191 -0
  51. package/components/forms/input-checkbox-radio/InputCheckboxRadioWithLabel.vue +111 -0
  52. package/components/forms/input-number/InputNumberCore.vue +203 -0
  53. package/components/forms/input-number/variants/InputNumberDefault.vue +154 -0
  54. package/components/forms/input-radio/MultipleRadiobuttons.vue +201 -0
  55. package/components/forms/input-radio/tests/MultipleRadioButtons.spec.ts +89 -0
  56. package/components/forms/input-radio/tests/data/tags.json +67 -0
  57. package/components/forms/input-range/InputRangeCore.vue +274 -0
  58. package/components/forms/input-range/variants/InputRangeDefault.vue +156 -0
  59. package/components/forms/input-range-fancy/InputRangeFancyCore.vue +450 -0
  60. package/components/forms/input-range-fancy/InputRangeFancyWithLabel.vue +124 -0
  61. package/components/forms/input-text/InputTextCore.vue +331 -0
  62. package/components/forms/input-text/variants/InputPasswordWithLabel.vue +130 -0
  63. package/components/forms/input-text/variants/InputTextAsNumberWithLabel.vue +187 -0
  64. package/components/forms/input-text/variants/InputTextWithLabel.vue +298 -0
  65. package/components/forms/input-textarea/InputTextareaCore.vue +234 -0
  66. package/components/forms/input-textarea/variants/InputTextareaWithLabel.vue +267 -0
  67. package/components/forms/toggle-switch/ToggleSwitchCore.vue +198 -0
  68. package/components/forms/toggle-switch/ToggleSwitchCoreOld.vue +216 -0
  69. package/components/forms/toggle-switch/variants/ToggleSwitchWithLabel.vue +105 -0
  70. package/components/forms/toggle-switch/variants/ToggleSwitchWithLabelInline.vue +102 -0
  71. package/components/forms/ui/FormField.vue +78 -0
  72. package/components/forms/ui/FormWrapper.vue +35 -0
  73. package/components/utils/colour-scheme-select/ColourSchemeSelect.vue +270 -0
  74. package/components/utils/colour-scheme-select/ColourSchemeSelectOld.vue +225 -0
  75. package/components/utils/dark-mode-switcher/DarkModeSwitcher.vue +47 -0
  76. package/composables/useApiRequest.ts +25 -0
  77. package/composables/useColourScheme.ts +25 -0
  78. package/composables/useErrorMessages.ts +59 -0
  79. package/composables/useFormControl.ts +248 -0
  80. package/composables/useSleep.ts +5 -0
  81. package/composables/useStyleClassPassthrough.ts +30 -0
  82. package/composables/useZodValidation.ts +148 -0
  83. package/nuxt.config.ts +0 -3
  84. package/package.json +1 -1
  85. package/types/types.forms.ts +216 -0
  86. package/types/types.zodFormControl.ts +21 -0
@@ -0,0 +1,298 @@
1
+ <template>
2
+ <div>
3
+ <div class="input-text-with-label" :data-form-theme="formTheme" :class="[elementClasses, inputVariant, { dirty: isDirty }, { active: isActive }]">
4
+ <label :for="id" class="input-text-label">{{ label }}</label>
5
+
6
+ <div v-if="inputVariant === 'normal' && hasDescriptionSlot" :id="`${id}-description`">
7
+ <slot name="description"></slot>
8
+ </div>
9
+
10
+ <InputTextCore
11
+ v-model="modelValue"
12
+ v-model:isDirty="isDirty"
13
+ v-model:isActive="isActive"
14
+ :type
15
+ :inputmode
16
+ :maxlength
17
+ :id
18
+ :name
19
+ :placeholder
20
+ :label
21
+ :errorMessage
22
+ :fieldHasError
23
+ :required
24
+ :styleClassPassthrough
25
+ :theme
26
+ :ariaDescribedby
27
+ :size
28
+ :inputVariant
29
+ >
30
+ <template v-if="hasLeftSlot" #left>
31
+ <slot name="left"></slot>
32
+ </template>
33
+ <template v-if="hasRightSlot" #right>
34
+ <slot name="right"></slot>
35
+ </template>
36
+ </InputTextCore>
37
+
38
+ <InputError :errorMessage :showError="fieldHasError" :id="errorId" :isDetached="false" :inputVariant />
39
+ </div>
40
+
41
+ <div v-if="inputVariant !== 'normal' && hasDescriptionSlot" :id="`${id}-description`">
42
+ <slot name="description"></slot>
43
+ </div>
44
+ </div>
45
+ </template>
46
+
47
+ <script setup lang="ts">
48
+ import propValidators from '../../c12/prop-validators';
49
+ const props = defineProps({
50
+ maxlength: {
51
+ type: Number,
52
+ default: 255,
53
+ },
54
+ type: {
55
+ type: String as PropType<'text' | 'email' | 'password' | 'number' | 'tel' | 'url'>,
56
+ required: true,
57
+ },
58
+ inputmode: {
59
+ type: String as PropType<'text' | 'email' | 'tel' | 'url' | 'search' | 'numeric' | 'none' | 'decimal'>,
60
+ default: 'text',
61
+ validator(value: string) {
62
+ return propValidators.inputMode.includes(value);
63
+ },
64
+ },
65
+ name: {
66
+ type: String,
67
+ required: true,
68
+ },
69
+ placeholder: {
70
+ type: String,
71
+ default: '',
72
+ },
73
+ label: {
74
+ type: String,
75
+ required: true,
76
+ },
77
+ errorMessage: {
78
+ type: [Object, String],
79
+ required: true,
80
+ },
81
+ fieldHasError: {
82
+ type: Boolean,
83
+ default: false,
84
+ },
85
+ required: {
86
+ type: Boolean,
87
+ default: false,
88
+ },
89
+ styleClassPassthrough: {
90
+ type: Array as PropType<string[]>,
91
+ default: () => [],
92
+ },
93
+ theme: {
94
+ type: String as PropType<string>,
95
+ default: 'primary',
96
+ validator(value: string) {
97
+ return propValidators.theme.includes(value);
98
+ },
99
+ },
100
+ size: {
101
+ type: String as PropType<string>,
102
+ default: 'normal',
103
+ validator(value: string) {
104
+ return propValidators.size.includes(value);
105
+ },
106
+ },
107
+ inputVariant: {
108
+ type: String as PropType<string>,
109
+ default: 'normal',
110
+ validator(value: string) {
111
+ return propValidators.inputVariant.includes(value);
112
+ },
113
+ },
114
+ });
115
+
116
+ const slots = useSlots();
117
+ const hasDescriptionSlot = computed(() => slots.description !== undefined);
118
+ const hasLeftSlot = computed(() => slots.left !== undefined);
119
+ const hasRightSlot = computed(() => slots.right !== undefined);
120
+
121
+ const formTheme = computed(() => {
122
+ return props.fieldHasError ? 'error' : props.theme;
123
+ });
124
+
125
+ const id = useId();
126
+ const errorId = `${id}-error-message`;
127
+ const ariaDescribedby = computed(() => {
128
+ const ariaDescribedbyId = hasDescriptionSlot.value ? `${id}-description` : undefined;
129
+ return props.fieldHasError ? errorId : ariaDescribedbyId;
130
+ });
131
+
132
+ const modelValue = defineModel();
133
+ const isActive = ref<boolean>(false);
134
+ const isDirty = ref<boolean>(false);
135
+
136
+ const { elementClasses } = useStyleClassPassthrough(props.styleClassPassthrough);
137
+
138
+ const testDirty = () => {
139
+ const watchValue = modelValue.value ?? '';
140
+
141
+ if (!isDirty.value && typeof watchValue === 'string' && watchValue.length > 0) {
142
+ isDirty.value = true;
143
+ }
144
+ };
145
+
146
+ onMounted(() => {
147
+ testDirty();
148
+ });
149
+
150
+ watch(
151
+ () => modelValue.value,
152
+ () => {
153
+ testDirty();
154
+ }
155
+ );
156
+ </script>
157
+
158
+ <style lang="css">
159
+ .input-text-with-label {
160
+ --_input-text-with-label-margin-block-start: 0;
161
+ --_input-text-with-label-background-color: transparent;
162
+
163
+ --_input-text-wrapper-border: var(--form-element-border-width) solid var(--theme-form-input-border);
164
+ --_input-text-wrapper-border-radius: var(--form-input-border-radius);
165
+ --_input-text-wrapper-border-underlined: var(--form-element-border-width-underlined) solid var(--theme-form-input-border);
166
+ --_input-text-wrapper-outline: var(--form-element-outline-width) solid var(--theme-form-input-outline);
167
+ --_input-text-wrapper-box-shadow: var(--_focus-box-shadow);
168
+ --_input-text-wrapper-padding-block: 0;
169
+
170
+ --_focus-box-shadow: var(--box-shadow-off);
171
+
172
+ /* Label vars */
173
+ --_label-text-color: var(--theme-form-input-text-label-color-normal);
174
+ --_label-text-margin-block: 0.8rem;
175
+ --_label-text-size: var(--step-2);
176
+ --_label-text-weight: normal;
177
+ --_label-text-line-height: 1.5;
178
+ --_label-text-background-color: var(--_input-text-with-label-background-color);
179
+
180
+ &.underlined {
181
+ --_label-text-color: var(--theme-form-input-text-label-color-underlined);
182
+ --_label-offset: 1rem 0.2rem;
183
+ --_input-text-with-label-background-color: color-mix(in srgb, currentColor 5%, transparent);
184
+
185
+ --_input-text-wrapper-underlined-border-radius-top-left: 0;
186
+ --_input-text-wrapper-underlined-border-radius-top-right: 0;
187
+ --_input-text-wrapper-underlined-border-radius-bottom-left: 4px;
188
+ --_input-text-wrapper-underlined-border-radius-bottom-right: 4px;
189
+
190
+ --_label-text-background-color: transparent;
191
+
192
+ &:has(.input-text-wrapper.active),
193
+ &:has(.input-text-wrapper.dirty) {
194
+ --_label-offset: 0 -3.2rem;
195
+ --_label-text-weight: bolder;
196
+ --_label-text-size: var(--step-1);
197
+ /* line-height: 1.5; */
198
+ /* padding: 0.2rem 1.2rem; */
199
+ }
200
+ }
201
+
202
+ &.outlined {
203
+ --_label-text-color: var(--theme-form-input-text-label-color-outlined);
204
+
205
+ --_label-offset: 1rem -0.2rem;
206
+ --_input-text-with-label-background-color: var(--theme-form-input-bg-normal);
207
+
208
+ --_input-text-wrapper-padding-block: 0.4em 0;
209
+
210
+ &:has(.input-text-wrapper.active),
211
+ &:has(.input-text-wrapper.dirty) {
212
+ --_label-offset: 1rem -2.8rem;
213
+ --_label-text-weight: normal;
214
+ /* --_label-text-size: var(--step-1); */
215
+ /* line-height: 1.5; */
216
+ /* padding: 0.2rem 1.2rem; */
217
+ }
218
+ }
219
+
220
+ &:not(.normal) {
221
+ --_input-text-with-label-margin-block-start: 3em;
222
+
223
+ &:has(.input-text-wrapper.active),
224
+ &:has(.input-text-wrapper.dirty) {
225
+ /* --_label-offset: 1rem -2.8rem; */
226
+ /* font-size: var(--step-1); */
227
+ /* line-height: 1.5; */
228
+ /* padding: 0.2rem 1.2rem; */
229
+ }
230
+
231
+ &:focus-within {
232
+ --_input-text-wrapper-box-shadow: var(--box-shadow-on);
233
+ --_input-text-wrapper-outline: var(--form-element-outline-width) solid hsl(from var(--theme-form-input-outline-focus) h s 90%);
234
+ }
235
+ }
236
+
237
+ /*
238
+ * Apply generic styles
239
+ **/
240
+
241
+ background-color: var(--_input-text-with-label-background-color);
242
+ border-radius: var(--_input-text-wrapper-border-radius);
243
+
244
+ /* overflow: clip; */
245
+
246
+ &.underlined {
247
+ border-bottom: var(--_input-text-wrapper-border-underlined);
248
+ border-top-left-radius: var(--_input-text-wrapper-underlined-border-radius-top-left);
249
+ border-top-right-radius: var(--_input-text-wrapper-underlined-border-radius-top-right);
250
+ border-bottom-left-radius: var(--_input-text-wrapper-underlined-border-radius-bottom-left);
251
+ border-bottom-right-radius: var(--_input-text-wrapper-underlined-border-radius-bottom-right);
252
+ }
253
+
254
+ &.outlined {
255
+ border: var(--_input-text-wrapper-border);
256
+ outline: var(--_input-text-wrapper-outline);
257
+ box-shadow: var(--_input-text-wrapper-box-shadow);
258
+ padding-block: var(--_input-text-wrapper-padding-block);
259
+ }
260
+
261
+ &:not(.normal) {
262
+ display: grid;
263
+ grid-template-columns: 1fr;
264
+ grid-template-rows: 1fr;
265
+ grid-template-areas: 'underlined-text-stack';
266
+
267
+ margin-block-start: var(--_input-text-with-label-margin-block-start);
268
+
269
+ .input-text-label {
270
+ grid-area: underlined-text-stack;
271
+ z-index: 2;
272
+ }
273
+ .input-text-wrapper {
274
+ grid-area: underlined-text-stack;
275
+ z-index: 1;
276
+ }
277
+ }
278
+
279
+ .input-text-label {
280
+ display: inline-block;
281
+ color: var(--_label-text-color);
282
+ background-color: var(--_label-text-background-color);
283
+ margin-block: var(--_label-text-margin-block);
284
+ font-size: var(--_label-text-size);
285
+ font-weight: var(--_label-text-weight);
286
+ line-height: var(--_label-text-line-height);
287
+ translate: var(--_label-offset);
288
+ width: fit-content;
289
+ height: fit-content;
290
+ transition: font-size 0.2s ease-in-out, translate 0.2s ease-in-out;
291
+
292
+ &:not(.normal) {
293
+ display: flex;
294
+ align-items: center;
295
+ }
296
+ }
297
+ }
298
+ </style>
@@ -0,0 +1,234 @@
1
+ <template>
2
+ <div
3
+ class="input-textarea-wrapper"
4
+ :data-form-theme="formTheme"
5
+ :data-size="size"
6
+ :class="[inputVariant, { dirty: isDirty }, { active: isActive }, { error: fieldHasError }, { 'has-left-slot': hasLeftSlot }, { 'has-right-slot': hasRightSlot }]"
7
+ >
8
+ <span v-if="hasLeftSlot" class="slot left-slot">
9
+ <slot name="left"></slot>
10
+ </span>
11
+
12
+ <textarea
13
+ :maxlength
14
+ :placeholder
15
+ :id
16
+ :name
17
+ :required
18
+ :class="['input-textarea-core', elementClasses, { dirty: isDirty }, { active: isActive }]"
19
+ v-model="modelValue"
20
+ ref="inputField"
21
+ :aria-invalid="fieldHasError"
22
+ :aria-describedby="`${id}-error-message`"
23
+ @focusin="updateFocus(true)"
24
+ @focusout="updateFocus(false)"
25
+ ></textarea>
26
+
27
+ <span v-if="hasRightSlot" class="slot right-slot">
28
+ <slot name="right"></slot>
29
+ </span>
30
+ </div>
31
+ </template>
32
+
33
+ <script setup lang="ts">
34
+ import propValidators from '../c12/prop-validators';
35
+ const props = defineProps({
36
+ maxlength: {
37
+ type: Number,
38
+ default: 255,
39
+ },
40
+ id: {
41
+ type: String,
42
+ required: true,
43
+ },
44
+ name: {
45
+ type: String,
46
+ required: true,
47
+ },
48
+ placeholder: {
49
+ type: String,
50
+ default: '',
51
+ },
52
+ fieldHasError: {
53
+ type: Boolean,
54
+ default: false,
55
+ },
56
+ required: {
57
+ type: Boolean,
58
+ default: false,
59
+ },
60
+ styleClassPassthrough: {
61
+ type: Array as PropType<string[]>,
62
+ default: () => [],
63
+ },
64
+ theme: {
65
+ type: String as PropType<string>,
66
+ default: 'primary',
67
+ validator(value: string) {
68
+ return propValidators.theme.includes(value);
69
+ },
70
+ },
71
+ size: {
72
+ type: String as PropType<string>,
73
+ default: 'normal',
74
+ validator(value: string) {
75
+ return propValidators.size.includes(value);
76
+ },
77
+ },
78
+ inputVariant: {
79
+ type: String as PropType<string>,
80
+ default: 'normal',
81
+ validator(value: string) {
82
+ return propValidators.inputVariant.includes(value);
83
+ },
84
+ },
85
+ });
86
+
87
+ const slots = useSlots();
88
+ const hasLeftSlot = computed(() => slots.left !== undefined);
89
+ const hasRightSlot = computed(() => slots.right !== undefined);
90
+
91
+ const formTheme = computed(() => {
92
+ return props.fieldHasError ? 'error' : props.theme;
93
+ });
94
+
95
+ const modelValue = defineModel<string | number | readonly string[] | null | undefined>();
96
+ const isDirty = defineModel('isDirty');
97
+ const isActive = defineModel('isActive');
98
+
99
+ const updateFocus = (isFocused: boolean) => {
100
+ isActive.value = isFocused;
101
+ };
102
+
103
+ const inputField = ref<HTMLInputElement | null>(null);
104
+
105
+ const { elementClasses } = useStyleClassPassthrough(props.styleClassPassthrough);
106
+ </script>
107
+
108
+ <style lang="css">
109
+ .input-textarea-wrapper {
110
+ --_focus-box-shadow: var(--box-shadow-off);
111
+ --_input-textarea-core-color: var(--theme-form-input-text-color-normal);
112
+
113
+ --_input-textarea-wrapper-background-color: var(--theme-form-input-bg-normal);
114
+
115
+ --_input-textarea-wrapper-border: var(--form-element-border-width) solid var(--theme-form-input-border);
116
+ --_input-textarea-wrapper-border-radius: var(--form-input-border-radius);
117
+
118
+ --_input-textarea-wrapper-outline: var(--form-element-outline-width) solid var(--theme-form-input-outline);
119
+ --_input-textarea-wrapper-opacity: 1;
120
+ --_input-textarea-wrapper-box-shadow: var(--_focus-box-shadow);
121
+ --_input-textarea-wrapper-margin-inline: 0;
122
+ --_input-textarea-wrapper-padding-block: 0;
123
+
124
+ &.underlined {
125
+ --_input-textarea-core-color: var(--theme-form-input-text-color-underlined);
126
+ --_input-textarea-wrapper-background-color: transparent;
127
+ --_input-textarea-wrapper-padding-block: 0.5rem;
128
+ }
129
+
130
+ &.outlined {
131
+ --_input-textarea-wrapper-margin-inline: 1px;
132
+ --_input-textarea-wrapper-background-color: var(--theme-form-input-bg-outlined);
133
+ }
134
+
135
+ &.normal {
136
+ &:focus-within {
137
+ --_input-textarea-wrapper-box-shadow: var(--box-shadow-on);
138
+ --_input-textarea-wrapper-outline: var(--form-element-outline-width) solid hsl(from var(--theme-form-input-outline-focus) h s 90%);
139
+ }
140
+ }
141
+
142
+ &:not(.normal) {
143
+ --_input-textarea-wrapper-border: none;
144
+ --_input-textarea-wrapper-box-shadow: none;
145
+ --_input-textarea-wrapper-outline: none;
146
+ --_input-textarea-wrapper-opacity: 0;
147
+
148
+ &:focus {
149
+ --_input-textarea-wrapper-border: none;
150
+ --_input-textarea-wrapper-box-shadow: none;
151
+ --_input-textarea-wrapper-outline: none;
152
+ --_input-textarea-wrapper-background-color: transparent;
153
+ }
154
+
155
+ &:focus-within {
156
+ --_input-textarea-wrapper-border: none;
157
+ --_input-textarea-wrapper-box-shadow: none;
158
+ --_input-textarea-wrapper-outline: none;
159
+ --_input-textarea-wrapper-background-color: transparent;
160
+ }
161
+
162
+ &.active,
163
+ &.dirty {
164
+ --_input-textarea-wrapper-border: none;
165
+ --_input-textarea-wrapper-box-shadow: none;
166
+ --_input-textarea-wrapper-outline: none;
167
+ --_input-textarea-wrapper-background-color: transparent;
168
+
169
+ --_input-textarea-wrapper-opacity: 1;
170
+ }
171
+ }
172
+
173
+ display: flex;
174
+ align-items: center;
175
+
176
+ background-color: var(--_input-textarea-wrapper-background-color);
177
+ border-radius: var(--_input-textarea-wrapper-border-radius);
178
+ border: var(--_input-textarea-wrapper-border);
179
+ outline: var(--_input-textarea-wrapper-outline);
180
+ box-shadow: var(--_input-textarea-wrapper-box-shadow);
181
+ opacity: var(--_input-textarea-wrapper-opacity);
182
+
183
+ margin-inline: var(--_input-textarea-wrapper-margin-inline);
184
+ padding-block: var(--_input-textarea-wrapper-padding-block);
185
+
186
+ &:not(.normal) {
187
+ transition: opacity 0.2s ease-in-out;
188
+ }
189
+
190
+ &.has-left-slot {
191
+ .left-slot {
192
+ display: flex;
193
+ align-items: center;
194
+ margin-inline-start: 1rem;
195
+ }
196
+ }
197
+
198
+ &.has-right-slot {
199
+ .right-slot {
200
+ display: flex;
201
+ align-items: center;
202
+ margin-inline-end: 1rem;
203
+ }
204
+ }
205
+
206
+ .input-textarea-core {
207
+ background-color: transparent;
208
+ border: none;
209
+ outline: none;
210
+ box-shadow: none;
211
+ flex-grow: 1;
212
+
213
+ min-height: 4lh;
214
+ field-sizing: content;
215
+
216
+ color: var(--_input-textarea-core-color);
217
+ font-family: var(--font-family);
218
+ font-size: var(--form-element-font-size);
219
+ line-height: var(--form-element-line-height);
220
+
221
+ padding-inline: var(--form-text-padding-inline);
222
+ padding-block-start: var(--form-element-padding-block-start);
223
+ padding-block-end: var(--form-element-padding-block-end);
224
+
225
+ &::placeholder,
226
+ &::-webkit-input-placeholder {
227
+ font-family: var(--font-family);
228
+ font-size: var(--form-element-font-size);
229
+ font-style: italic;
230
+ font-weight: 400;
231
+ }
232
+ }
233
+ }
234
+ </style>