@dvcol/neo-svelte 0.1.2 → 0.1.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 (152) hide show
  1. package/CHANGELOG.md +83 -0
  2. package/README.md +25 -26
  3. package/dist/buttons/NeoButton.svelte +140 -128
  4. package/dist/buttons/NeoButtonGroup.svelte +99 -108
  5. package/dist/buttons/neo-button-group.model.d.ts +18 -19
  6. package/dist/buttons/neo-button.model.d.ts +6 -10
  7. package/dist/cards/NeoCard.svelte +176 -73
  8. package/dist/cards/NeoCard.svelte.d.ts +1 -1
  9. package/dist/cards/neo-card.model.d.ts +29 -1
  10. package/dist/containers/NeoTransitionContainer.svelte +13 -2
  11. package/dist/containers/neo-transition-container.model.d.ts +9 -1
  12. package/dist/divider/NeoDivider.svelte +11 -11
  13. package/dist/icons/IconAccount.svelte +10 -2
  14. package/dist/icons/IconAdd.svelte +10 -2
  15. package/dist/icons/IconAlert.svelte +2 -2
  16. package/dist/icons/IconCalendar.svelte +23 -0
  17. package/dist/icons/IconCalendar.svelte.d.ts +26 -0
  18. package/dist/icons/IconCheckbox.svelte +87 -0
  19. package/dist/icons/IconCheckbox.svelte.d.ts +55 -0
  20. package/dist/icons/IconCircleLoading.svelte +2 -2
  21. package/dist/icons/IconClear.svelte +10 -2
  22. package/dist/icons/IconClose.svelte +2 -2
  23. package/dist/icons/IconConfirm.svelte +2 -2
  24. package/dist/icons/IconDownload.svelte +17 -0
  25. package/dist/icons/IconDownload.svelte.d.ts +26 -0
  26. package/dist/icons/IconEmpty.svelte +2 -2
  27. package/dist/icons/IconFileUpload.svelte +2 -2
  28. package/dist/icons/IconGithub.svelte +2 -2
  29. package/dist/icons/IconImage.svelte +2 -2
  30. package/dist/icons/IconMinus.svelte +2 -2
  31. package/dist/icons/IconMoon.svelte +2 -2
  32. package/dist/icons/IconPaint.svelte +19 -0
  33. package/dist/icons/{IconSunrise.svelte.d.ts → IconPaint.svelte.d.ts} +3 -3
  34. package/dist/icons/IconPencil.svelte +13 -0
  35. package/dist/icons/IconPencil.svelte.d.ts +26 -0
  36. package/dist/icons/IconRadio.svelte +14 -0
  37. package/dist/icons/IconRadio.svelte.d.ts +22 -0
  38. package/dist/icons/IconSave.svelte +1 -1
  39. package/dist/icons/IconSave.svelte.d.ts +3 -3
  40. package/dist/icons/IconSaveOff.svelte +1 -1
  41. package/dist/icons/IconSaveOff.svelte.d.ts +3 -3
  42. package/dist/icons/IconSearch.svelte +2 -2
  43. package/dist/icons/IconSun.svelte +3 -3
  44. package/dist/icons/{IconSunrise.svelte → IconSunFull.svelte} +5 -4
  45. package/dist/icons/IconSunFull.svelte.d.ts +26 -0
  46. package/dist/icons/IconVideo.svelte +2 -2
  47. package/dist/icons/IconWatch.svelte +2 -2
  48. package/dist/icons/IconWatchOff.svelte +2 -2
  49. package/dist/inputs/NeoCheckbox.svelte +316 -0
  50. package/dist/inputs/NeoCheckbox.svelte.d.ts +19 -0
  51. package/dist/inputs/NeoColorPicker.svelte +140 -0
  52. package/dist/inputs/NeoColorPicker.svelte.d.ts +19 -0
  53. package/dist/inputs/NeoDateTime.svelte +96 -0
  54. package/dist/inputs/NeoDateTime.svelte.d.ts +19 -0
  55. package/dist/inputs/NeoFilePicker.svelte +528 -0
  56. package/dist/inputs/NeoFilePicker.svelte.d.ts +19 -0
  57. package/dist/inputs/NeoFilePickerCard.svelte +314 -0
  58. package/dist/inputs/NeoFilePickerCard.svelte.d.ts +19 -0
  59. package/dist/inputs/NeoNumberStep.svelte +174 -0
  60. package/dist/inputs/NeoNumberStep.svelte.d.ts +19 -0
  61. package/dist/inputs/NeoPassword.svelte +86 -17
  62. package/dist/inputs/NeoPassword.svelte.d.ts +19 -16
  63. package/dist/inputs/NeoPin.svelte +589 -0
  64. package/dist/inputs/NeoPin.svelte.d.ts +19 -0
  65. package/dist/inputs/NeoRadio.svelte +254 -0
  66. package/dist/inputs/NeoRadio.svelte.d.ts +19 -0
  67. package/dist/inputs/NeoRange.svelte +518 -0
  68. package/dist/inputs/NeoRange.svelte.d.ts +18 -0
  69. package/dist/inputs/NeoSwitch.svelte +373 -0
  70. package/dist/inputs/NeoSwitch.svelte.d.ts +19 -0
  71. package/dist/inputs/NeoTextarea.svelte +335 -301
  72. package/dist/inputs/NeoTextarea.svelte.d.ts +5 -2
  73. package/dist/inputs/common/NeoAffix.svelte +166 -0
  74. package/dist/inputs/common/NeoAffix.svelte.d.ts +19 -0
  75. package/dist/inputs/common/NeoBaseInput.svelte +338 -0
  76. package/dist/inputs/common/NeoBaseInput.svelte.d.ts +30 -0
  77. package/dist/inputs/common/NeoInput.svelte +684 -0
  78. package/dist/inputs/{NeoInput.svelte.d.ts → common/NeoInput.svelte.d.ts} +2 -10
  79. package/dist/inputs/common/NeoInputValidation.svelte +45 -0
  80. package/dist/inputs/common/NeoInputValidation.svelte.d.ts +22 -0
  81. package/dist/inputs/common/NeoLabel.svelte +93 -0
  82. package/dist/inputs/common/NeoLabel.svelte.d.ts +19 -0
  83. package/dist/inputs/{NeoValidation.svelte → common/NeoValidation.svelte} +9 -16
  84. package/dist/inputs/common/NeoValidation.svelte.d.ts +22 -0
  85. package/dist/inputs/common/neo-affix.model.d.ts +32 -0
  86. package/dist/inputs/common/neo-input-validation.model.d.ts +20 -0
  87. package/dist/inputs/common/neo-input-validation.model.js +1 -0
  88. package/dist/inputs/{neo-input.model.d.ts → common/neo-input.model.d.ts} +148 -68
  89. package/dist/inputs/common/neo-label.model.d.ts +36 -0
  90. package/dist/inputs/common/neo-label.model.js +1 -0
  91. package/dist/inputs/common/neo-validation.model.d.ts +70 -0
  92. package/dist/inputs/common/neo-validation.model.js +1 -0
  93. package/dist/inputs/index.d.ts +2 -2
  94. package/dist/inputs/index.js +1 -1
  95. package/dist/inputs/neo-checkbox.model.d.ts +9 -0
  96. package/dist/inputs/neo-checkbox.model.js +1 -0
  97. package/dist/inputs/neo-color-picker.model.d.ts +17 -0
  98. package/dist/inputs/neo-color-picker.model.js +1 -0
  99. package/dist/inputs/neo-date-time.model.d.ts +8 -0
  100. package/dist/inputs/neo-date-time.model.js +1 -0
  101. package/dist/inputs/neo-file-picker.model.d.ts +138 -0
  102. package/dist/inputs/neo-file-picker.model.js +1 -0
  103. package/dist/inputs/neo-number-step.model.d.ts +24 -0
  104. package/dist/inputs/neo-number-step.model.js +1 -0
  105. package/dist/inputs/neo-password.model.d.ts +13 -0
  106. package/dist/inputs/neo-password.model.js +1 -0
  107. package/dist/inputs/neo-pin.model.d.ts +47 -0
  108. package/dist/inputs/neo-pin.model.js +1 -0
  109. package/dist/inputs/neo-radio.model.d.ts +3 -0
  110. package/dist/inputs/neo-radio.model.js +1 -0
  111. package/dist/inputs/neo-switch.model.d.ts +9 -0
  112. package/dist/inputs/neo-switch.model.js +1 -0
  113. package/dist/nav/NeoTab.svelte +29 -25
  114. package/dist/nav/NeoTabPanel.svelte +1 -1
  115. package/dist/nav/NeoTabs.svelte +51 -44
  116. package/dist/nav/NeoTabsCard.svelte +8 -10
  117. package/dist/nav/neo-tabs-context.svelte.d.ts +2 -11
  118. package/dist/nav/neo-tabs-context.svelte.js +1 -41
  119. package/dist/nav/neo-tabs.model.d.ts +6 -0
  120. package/dist/providers/NeoThemeProvider.svelte +417 -305
  121. package/dist/providers/NeoThemeSelector.svelte +10 -10
  122. package/dist/providers/neo-theme-provider-context.svelte.js +16 -15
  123. package/dist/providers/neo-theme-provider.model.d.ts +6 -6
  124. package/dist/providers/neo-theme-provider.model.js +17 -12
  125. package/dist/providers/neo-theme-selector.model.d.ts +2 -2
  126. package/dist/skeletons/NeoSkeletonMedia.svelte +4 -4
  127. package/dist/skeletons/NeoSkeletonText.svelte +12 -12
  128. package/dist/styles/common/colors.scss +85 -97
  129. package/dist/styles/common/filters.scss +17 -0
  130. package/dist/styles/common/shadows.scss +531 -293
  131. package/dist/styles/common/spacing.scss +7 -3
  132. package/dist/styles/common/typography.scss +1 -1
  133. package/dist/styles/common/utils.scss +1 -1
  134. package/dist/styles/common/z-index.scss +1 -1
  135. package/dist/styles/mixin.scss +80 -27
  136. package/dist/styles/reset.scss +8 -1
  137. package/dist/styles/theme.scss +39 -16
  138. package/dist/utils/html-element.utils.d.ts +3 -0
  139. package/dist/utils/regex.utils.d.ts +3 -0
  140. package/dist/utils/regex.utils.js +3 -0
  141. package/dist/utils/shadow.utils.d.ts +30 -3
  142. package/dist/utils/shadow.utils.js +41 -14
  143. package/dist/utils/transition.utils.d.ts +4 -0
  144. package/dist/utils/transition.utils.js +10 -1
  145. package/dist/utils/utils.svelte.d.ts +6 -0
  146. package/dist/utils/utils.svelte.js +13 -0
  147. package/package.json +13 -12
  148. package/dist/inputs/NeoInput.svelte +0 -750
  149. package/dist/inputs/NeoValidation.svelte.d.ts +0 -22
  150. package/dist/inputs/neo-validation.model.d.ts +0 -40
  151. /package/dist/inputs/{neo-validation.model.js → common/neo-affix.model.js} +0 -0
  152. /package/dist/inputs/{neo-input.model.js → common/neo-input.model.js} +0 -0
@@ -1,59 +1,77 @@
1
1
  <script lang="ts">
2
2
  import { wait } from '@dvcol/common-utils/common/promise';
3
- import { fade } from 'svelte/transition';
3
+
4
+ import { tick } from 'svelte';
4
5
 
5
6
  import type { EventHandler, FocusEventHandler, FormEventHandler, MouseEventHandler } from 'svelte/elements';
6
7
 
7
- import IconAlert from '../icons/IconAlert.svelte';
8
- import IconCircleLoading from '../icons/IconCircleLoading.svelte';
9
- import IconClear from '../icons/IconClear.svelte';
10
- import IconConfirm from '../icons/IconConfirm.svelte';
11
- import NeoValidation from './NeoValidation.svelte';
8
+ import type { SvelteEvent } from '../utils/html-element.utils.js';
9
+
10
+ import NeoAffix from './common/NeoAffix.svelte';
11
+ import NeoInputValidation from './common/NeoInputValidation.svelte';
12
+ import NeoLabel from './common/NeoLabel.svelte';
12
13
  import {
13
14
  type NeoInputContext,
14
15
  NeoInputLabelPosition,
15
16
  type NeoInputMethods,
16
17
  type NeoInputState,
18
+ type NeoInputValue,
19
+ type NeoTextareaHTMLElement,
17
20
  type NeoTextareaProps,
18
- } from './neo-input.model.js';
21
+ } from './common/neo-input.model.js';
19
22
  import { toAction, toActionProps, toTransition, toTransitionProps } from '../utils/action.utils.js';
20
- import { computeGlassFilter, computeHoverShadowElevation, computeShadowElevation } from '../utils/shadow.utils.js';
21
- import { enterDefaultTransition, leaveDefaultTransition } from '../utils/transition.utils.js';
23
+ import {
24
+ computeGlassFilter,
25
+ computeHoverShadowElevation,
26
+ computeShadowElevation,
27
+ getDefaultElevation,
28
+ getDefaultHoverElevation,
29
+ isShadowFlat,
30
+ } from '../utils/shadow.utils.js';
22
31
 
23
32
  /* eslint-disable prefer-const -- necessary for binding checked */
24
33
  let {
25
34
  // Snippets
26
35
  label,
27
- suffix,
36
+ after,
28
37
  message,
29
38
  error,
39
+ children,
30
40
 
31
41
  // States
32
42
  id = label ? `neo-textarea-${crypto.randomUUID()}` : undefined,
33
43
  ref = $bindable(),
34
- value = $bindable(''),
35
- valid = $bindable(undefined),
44
+
45
+ value = $bindable(),
46
+ valid = $bindable(),
36
47
  dirty = $bindable(false),
37
48
  touched = $bindable(false),
49
+ hovered = $bindable(false),
50
+ focused = $bindable(false),
38
51
  readonly,
39
52
  disabled,
40
53
  loading,
41
54
  clearable,
55
+ nullable = true,
56
+
42
57
  dirtyOnInput,
58
+ dirtyOnBlur,
43
59
  validateOnInput,
60
+ validateOnBlur,
44
61
  position = NeoInputLabelPosition.Inside,
45
62
  autoResize = true,
46
63
 
47
64
  // Styles
48
- elevation = 3,
49
- hover = -1,
50
65
  borderless,
66
+ pressed,
51
67
  rounded,
52
68
  glass,
53
69
  start,
54
70
  floating = true,
55
71
  skeleton,
56
72
  validation,
73
+ elevation = getDefaultElevation(pressed),
74
+ hover = getDefaultHoverElevation(pressed),
57
75
 
58
76
  // Transition
59
77
  in: inAction,
@@ -75,8 +93,9 @@
75
93
  // Other props
76
94
  labelRef = $bindable(),
77
95
  labelProps,
78
- suffixProps,
79
- suffixTag = suffixProps?.onclick ? 'button' : 'span',
96
+ afterRef = $bindable(),
97
+ afterProps,
98
+ afterTag = afterProps?.onclick ? 'button' : 'span',
80
99
  containerProps,
81
100
  containerTag = 'div',
82
101
  wrapperProps,
@@ -90,14 +109,28 @@
90
109
  let initial = $state(value);
91
110
  let validationMessage: string | undefined = $state(ref?.validationMessage);
92
111
 
93
- const filter = $derived.by(() => computeGlassFilter(elevation, glass));
94
- const boxShadow = $derived.by(() => computeShadowElevation(elevation, glass));
95
- const hoverShadow = $derived.by(() => computeHoverShadowElevation(elevation, hover, glass) ?? boxShadow);
112
+ const filter = $derived(computeGlassFilter(elevation, glass));
113
+ const boxShadow = $derived(computeShadowElevation(elevation, { glass, pressed }));
114
+ const hoverShadow = $derived(computeHoverShadowElevation(elevation, hover, { glass, pressed }) ?? boxShadow);
96
115
 
97
- const hoverFlat = $derived(boxShadow.endsWith('flat') && !hoverShadow.endsWith('flat'));
98
- const flatHover = $derived(hoverShadow.endsWith('flat') && !boxShadow.endsWith('flat'));
116
+ const hoverFlat = $derived(isShadowFlat(boxShadow) && !isShadowFlat(hoverShadow));
117
+ const flatHover = $derived(isShadowFlat(hoverShadow) && !isShadowFlat(boxShadow));
118
+
119
+ const affix = $derived(clearable || loading !== undefined || validation);
120
+ const hasValue = $derived(value !== undefined && (typeof value === 'string' ? !!value.length : value !== null));
121
+ const close = $derived(clearable && (focused || hovered) && hasValue && !disabled && !readonly);
122
+ const isFloating = $derived(floating && !focused && !hasValue && !disabled && !readonly);
123
+
124
+ const validate: NeoInputMethods<HTMLTextAreaElement>['validate'] = (
125
+ update: { dirty?: boolean; valid?: boolean } = { dirty: true, valid: true },
126
+ ) => {
127
+ if (update.dirty) dirty = value !== initial;
128
+ if (!update.valid) return { touched, dirty, valid, value, initial };
129
+ valid = ref?.checkValidity();
130
+ validationMessage = ref?.validationMessage;
131
+ return { touched, dirty, valid, value };
132
+ };
99
133
 
100
- let hovered = $state(false);
101
134
  const onMouseEnter: MouseEventHandler<HTMLDivElement> = e => {
102
135
  hovered = true;
103
136
  containerProps?.onmouseenter?.(e);
@@ -108,7 +141,6 @@
108
141
  containerProps?.onmouseleave?.(e);
109
142
  };
110
143
 
111
- let focused = $state(false);
112
144
  const onFocus: FocusEventHandler<HTMLTextAreaElement> = e => {
113
145
  focused = true;
114
146
  touched = true;
@@ -117,23 +149,27 @@
117
149
 
118
150
  const onBlur: FocusEventHandler<HTMLTextAreaElement> = e => {
119
151
  focused = false;
152
+ validate({ dirty: dirtyOnBlur, valid: validateOnBlur });
120
153
  onblur?.(e);
121
154
  };
122
155
 
123
- const checkValidity = (update: { dirty?: boolean; valid?: boolean } = { dirty: true, valid: true }) => {
124
- if (update.dirty) dirty = value !== initial;
125
- if (!update.valid) return;
126
- valid = ref?.checkValidity();
127
- validationMessage = ref?.validationMessage;
128
- };
129
-
130
156
  const onInput: FormEventHandler<HTMLTextAreaElement> = e => {
131
- checkValidity({ dirty: dirtyOnInput, valid: validateOnInput });
157
+ touched = true;
158
+ validate({ dirty: dirtyOnInput, valid: validateOnInput });
132
159
  oninput?.(e);
133
160
  };
134
161
 
162
+ const fallback = () => {
163
+ if (nullable) return value;
164
+ if (hasValue) return value;
165
+ value = rest?.defaultValue ?? '';
166
+ return value;
167
+ };
168
+
135
169
  const onChange: FormEventHandler<HTMLTextAreaElement> = e => {
136
- checkValidity();
170
+ touched = true;
171
+ validate();
172
+ fallback();
137
173
  onchange?.(e);
138
174
  };
139
175
 
@@ -148,7 +184,7 @@
148
184
  * Change the state of the input
149
185
  * @param state
150
186
  */
151
- export const mark: NeoInputMethods<HTMLTextAreaElement>['mark'] = (state: NeoInputState) => {
187
+ export const mark: NeoInputMethods<HTMLTextAreaElement>['mark'] = (state: NeoInputState<HTMLTextAreaElement>) => {
152
188
  if (state.touched !== undefined) touched = state.touched;
153
189
  if (state.valid !== undefined) valid = state.valid;
154
190
  if (state.dirty === undefined) return onmark?.({ touched, dirty, valid });
@@ -165,21 +201,35 @@
165
201
  /**
166
202
  * Clear the input state
167
203
  */
168
- export const clear: NeoInputMethods<HTMLTextAreaElement>['clear'] = (state?: NeoInputState) => {
169
- value = '';
204
+ export const clear: NeoInputMethods<HTMLTextAreaElement>['clear'] = async (
205
+ state?: NeoInputState<HTMLTextAreaElement>,
206
+ event?: InputEvent | SvelteEvent<InputEvent>,
207
+ ) => {
208
+ value = nullable ? '' : (rest?.defaultValue ?? '');
209
+ await tick();
170
210
  focus();
171
- if (!state) {
172
- setTimeout(() => checkValidity());
173
- return onclear?.({ touched, dirty, valid, value });
174
- }
175
- initial = value;
176
- setTimeout(() => mark({ touched: false, dirty: false, ...state }));
177
- return onclear?.({ touched, dirty, valid, value });
211
+ if (state) mark({ touched: false, dirty: false, ...state });
212
+ else validate();
213
+ onclear?.({ touched, dirty, valid, value, initial }, event);
214
+ if (event) return ref?.dispatchEvent(event);
215
+ const _event: InputEventInit = { bubbles: true, cancelable: false, data: value as InputEventInit['data'], inputType: 'clear' };
216
+ oninput?.(new InputEvent('input', _event) as SvelteEvent<InputEvent, HTMLTextAreaElement>);
178
217
  };
179
218
 
180
- const affix = $derived(clearable || loading !== undefined || validation);
181
- const close = $derived(clearable && (focused || hovered) && value?.length && !disabled && !readonly);
182
- const isFloating = $derived(floating && !focused && !value?.length && !disabled && !readonly);
219
+ /**
220
+ * Change the value of the input
221
+ */
222
+ export const change: NeoInputMethods<HTMLTextAreaElement>['change'] = (_value: NeoInputValue<HTMLTextAreaElement>, event?: InputEvent) => {
223
+ if (event) ref?.dispatchEvent(event);
224
+ value = _value;
225
+ focus();
226
+ return validate();
227
+ };
228
+
229
+ $effect(() => {
230
+ if (!ref) return;
231
+ Object.assign(ref, { mark, clear, change, validate });
232
+ });
183
233
 
184
234
  let labelHeight = $state<string>();
185
235
  let labelWidth = $state<string>();
@@ -197,13 +247,13 @@
197
247
  if (!labelRef) return;
198
248
  if (position === NeoInputLabelPosition.Inside && !floating) return;
199
249
  labelHeight = `${labelRef?.clientHeight ?? 0}px`;
200
- if (position === NeoInputLabelPosition.Left || position === NeoInputLabelPosition.Right) return;
250
+ if (position !== NeoInputLabelPosition.Left && position !== NeoInputLabelPosition.Right) return;
201
251
  labelWidth = `${labelRef?.clientWidth ?? 0}px`;
202
252
  });
203
253
 
204
254
  const rows = $derived.by(() => {
205
- if (typeof autoResize === 'boolean' || !autoResize) return suffix ? 3 : undefined;
206
- if (suffix) return Math.max(3, autoResize.min ?? 0);
255
+ if (typeof autoResize === 'boolean' || !autoResize) return after ? 3 : undefined;
256
+ if (after) return Math.max(3, autoResize.min ?? 0);
207
257
  return autoResize.min;
208
258
  });
209
259
 
@@ -238,23 +288,18 @@
238
288
  resize();
239
289
  });
240
290
 
241
- const errorMessage = $derived.by(() => {
242
- if (valid || valid === undefined) return;
243
- if (error) return error;
244
- if (!validation) return;
245
- return error ?? validationMessage;
246
- });
247
-
248
- const showMessage = $derived(message || errorMessage || error || validation);
249
- const messageId = $derived(showMessage ? (messageProps?.id ?? `neo-textarea-message-${crypto.randomUUID()}`) : undefined);
291
+ let visible = $state(false);
292
+ let messageId = $state(`neo-textarea-message-${crypto.randomUUID()}`);
250
293
 
251
- const context = $derived<NeoInputContext<HTMLTextAreaElement>>({
294
+ const context = $derived<NeoInputContext<NeoTextareaHTMLElement>>({
252
295
  // Ref
253
296
  ref,
254
297
 
255
298
  // Methods
256
299
  mark,
257
300
  clear,
301
+ change,
302
+ validate,
258
303
 
259
304
  // State
260
305
  value,
@@ -267,6 +312,7 @@
267
312
  // Styles
268
313
  elevation,
269
314
  hover,
315
+ pressed,
270
316
  borderless,
271
317
  rounded,
272
318
  glass,
@@ -283,34 +329,24 @@
283
329
  const useProps = $derived(toActionProps(use));
284
330
  </script>
285
331
 
286
- {#snippet after()}
332
+ {#snippet suffix()}
287
333
  <!-- Affix (loafing, clear, placeholder) -->
288
334
  {#if affix}
289
- <span class="neo-textarea-affix" role="none" onclick={focus}>
290
- {#if loading}
291
- <span out:fade={enterDefaultTransition}>
292
- <IconCircleLoading width="1.1875rem" height="1.1875rem" />
293
- </span>
294
- {:else if close}
295
- <button class="neo-textarea-clear" aria-label="clear" in:fade out:fade={enterDefaultTransition} onclick={() => clear()}>
296
- <IconClear width="1.1875rem" height="1.1875rem" />
297
- </button>
298
- {:else}
299
- <span class="neo-textarea-affix-validation" in:fade={leaveDefaultTransition}>
300
- {#if validation && valid === false}
301
- <IconAlert width="1.1875rem" height="1.1875rem" />
302
- {:else if validation && valid === true && touched}
303
- <IconConfirm width="1.1875rem" height="1.1875rem" />
304
- {/if}
305
- </span>
306
- {/if}
307
- </span>
335
+ <NeoAffix
336
+ {loading}
337
+ {close}
338
+ {disabled}
339
+ {skeleton}
340
+ valid={validation ? valid : undefined}
341
+ closeProps={{ onclick: () => clear() }}
342
+ onclick={() => focus()}
343
+ />
308
344
  {/if}
309
345
 
310
346
  <!-- Suffix -->
311
- {#if suffix}
312
- <svelte:element this={suffixTag} class:neo-textarea-suffix={true} {disabled} {readonly} {...suffixProps}>
313
- {@render suffix(context)}
347
+ {#if after}
348
+ <svelte:element this={afterTag} bind:this={afterRef} class:neo-textarea-after={true} {disabled} {readonly} {...afterProps}>
349
+ {@render after(context)}
314
350
  </svelte:element>
315
351
  {/if}
316
352
  {/snippet}
@@ -321,11 +357,11 @@
321
357
  {disabled}
322
358
  {readonly}
323
359
  aria-invalid={valid === undefined ? undefined : !valid}
324
- aria-describedby={messageId}
360
+ aria-describedby={visible ? messageId : undefined}
325
361
  bind:this={ref}
326
362
  bind:value
327
363
  class:neo-textarea={true}
328
- class:affix={affix || suffix}
364
+ class:neo-affix={affix || after}
329
365
  {rows}
330
366
  onblur={onBlur}
331
367
  onfocus={onFocus}
@@ -338,6 +374,14 @@
338
374
  </textarea>
339
375
  {/snippet}
340
376
 
377
+ {#snippet labelGroup()}
378
+ {#if typeof label === 'string'}
379
+ {label}
380
+ {:else if label}
381
+ {@render label(context)}
382
+ {/if}
383
+ {/snippet}
384
+
341
385
  {#snippet textareaGroup()}
342
386
  <svelte:element
343
387
  this={containerTag}
@@ -347,20 +391,23 @@
347
391
  data-dirty={dirty}
348
392
  data-valid={valid}
349
393
  class:neo-textarea-group={true}
350
- class:readonly
351
- class:borderless
352
- class:rounded
353
- class:glass
354
- class:hover
355
- class:start
356
- class:skeleton
357
- class:validation
358
- class:disabled
359
- class:raised={elevation > 3 || elevation + hover > 3}
360
- class:inset={elevation < -3 || elevation + hover < -3}
361
- class:flat={!elevation}
362
- class:hover-flat={hoverFlat}
363
- class:flat-hover={flatHover}
394
+ class:neo-readonly={readonly}
395
+ class:neo-pressed={pressed}
396
+ class:neo-borderless={borderless}
397
+ class:neo-rounded={rounded}
398
+ class:neo-glass={glass}
399
+ class:neo-hover={hover}
400
+ class:neo-hovered={hovered}
401
+ class:neo-floating={floating}
402
+ class:neo-start={start}
403
+ class:neo-skeleton={skeleton}
404
+ class:neo-validation={validation}
405
+ class:neo-disabled={disabled}
406
+ class:neo-raised={elevation > 3 || elevation + hover > 3}
407
+ class:neo-inset={elevation < -3 || elevation + hover < -3}
408
+ class:neo-flat={!elevation}
409
+ class:neo-hover-flat={hoverFlat}
410
+ class:neo-flat-hover={flatHover}
364
411
  style:--neo-textarea-glass-blur={filter}
365
412
  style:--neo-textarea-box-shadow={boxShadow}
366
413
  style:--neo-textarea-hover-shadow={hoverShadow}
@@ -373,49 +420,60 @@
373
420
  {...containerProps}
374
421
  >
375
422
  {#if label}
376
- <div class="neo-textarea-label-container" class:floating={isFloating} role="none" onclick={focus}>
377
- <label bind:this={labelRef} for={id} class:neo-textarea-label={true} class:first class:rounded class:required={rest.required} {...labelProps}>
378
- {#if typeof label === 'string'}
379
- {label}
380
- {:else}
381
- {@render label(context)}
382
- {/if}
383
- </label>
423
+ <NeoLabel
424
+ for={id}
425
+ bind:ref={labelRef}
426
+ containerProps={{
427
+ class: [
428
+ affix || after ? 'neo-affix' : undefined,
429
+ first ? 'neo-first' : undefined,
430
+ rounded ? 'neo-rounded' : undefined,
431
+ isFloating ? 'neo-floating' : undefined,
432
+ ]
433
+ .filter(Boolean)
434
+ .join(' '),
435
+ onclick: focus,
436
+ }}
437
+ label={labelGroup}
438
+ required={rest.required}
439
+ {disabled}
440
+ {...labelProps}
441
+ >
384
442
  {@render textarea()}
385
- </div>
443
+ </NeoLabel>
386
444
  {:else}
387
445
  {@render textarea()}
388
446
  {/if}
389
- {@render after()}
447
+ {@render suffix()}
448
+ {@render children?.(context)}
390
449
  </svelte:element>
391
450
  {/snippet}
392
451
 
393
- {#if showMessage}
394
- <NeoValidation
395
- tag={wrapperTag}
396
- error={errorMessage}
397
- {context}
398
- {message}
399
- {messageId}
400
- {messageTag}
401
- {messageProps}
402
- in={inAction}
403
- out={outAction}
404
- transition={transitionAction}
405
- {...wrapperProps}
406
- >
407
- {@render textareaGroup()}
408
- </NeoValidation>
409
- {:else}
452
+ <NeoInputValidation
453
+ tag={wrapperTag}
454
+ bind:visible
455
+ bind:messageId
456
+ {valid}
457
+ {validation}
458
+ {validationMessage}
459
+ {error}
460
+ {rounded}
461
+ {context}
462
+ {message}
463
+ {messageTag}
464
+ {messageProps}
465
+ in={inAction}
466
+ out={outAction}
467
+ transition={transitionAction}
468
+ {...wrapperProps}
469
+ >
410
470
  {@render textareaGroup()}
411
- {/if}
471
+ </NeoInputValidation>
412
472
 
413
473
  <style>.neo-textarea-group,
414
474
  .neo-textarea,
415
- .neo-textarea-clear,
416
- .neo-textarea-affix,
417
- .neo-textarea-suffix {
418
- display: flex;
475
+ .neo-textarea-after {
476
+ display: inline-flex;
419
477
  box-sizing: border-box;
420
478
  font: inherit;
421
479
  text-decoration: none;
@@ -423,32 +481,13 @@
423
481
  transition: color 0.3s ease, margin 0.3s ease, padding 0.3s ease, background-color 0.3s ease, backdrop-filter 0.3s ease, border-color 0.3s ease, border-radius 0.3s ease, box-shadow 0.3s ease-out;
424
482
  }
425
483
 
426
- .neo-textarea-clear, .neo-textarea-suffix:is(button, a) {
427
- cursor: pointer;
428
- }
429
- .neo-textarea-clear:focus-visible, .neo-textarea-suffix:focus-visible:is(button, a) {
430
- color: var(--neo-textarea-focus-color, var(--neo-text-color-focused));
431
- }
432
- .neo-textarea-clear:hover, .neo-textarea-suffix:hover:is(button, a) {
433
- color: var(--neo-textarea-hover-color, var(--neo-text-color-hover));
434
- }
435
- .neo-textarea-clear:active, .neo-textarea-suffix:active:is(button, a) {
436
- color: var(--neo-textarea-active-color, var(--neo-text-color-hover-active));
437
- scale: 0.9;
438
- }
439
- .neo-textarea-clear:disabled, .neo-textarea-suffix:disabled:is(button, a) {
440
- color: var(--neo-text-color-disabled);
441
- cursor: not-allowed;
442
- scale: 1;
443
- }
444
-
445
484
  .neo-textarea {
446
485
  flex: 1 1 auto;
447
486
  align-self: center;
448
- min-width: 100%;
487
+ min-width: fit-content;
449
488
  max-width: 100%;
450
489
  min-height: fit-content;
451
- padding: 0.75rem;
490
+ padding: 0.75rem 0.95rem;
452
491
  color: inherit;
453
492
  text-overflow: ellipsis;
454
493
  background-color: transparent;
@@ -456,40 +495,48 @@
456
495
  border-radius: var(--neo-textarea-border-radius, var(--neo-border-radius));
457
496
  outline: none;
458
497
  }
459
- .neo-textarea.affix {
460
- padding: 0.75rem 2.5rem 0.75rem 0.75rem;
461
- }
462
- .neo-textarea-affix, .neo-textarea-suffix {
463
- align-items: center;
464
- margin: 0.25rem;
465
- padding: 0.5rem;
498
+ .neo-textarea.neo-affix {
499
+ padding: 0.75rem 2.25rem 0.75rem 0.95rem;
466
500
  }
467
- .neo-textarea-suffix {
501
+ .neo-textarea-after {
468
502
  position: absolute;
469
503
  right: 0.125rem;
470
504
  bottom: 0.125rem;
471
- color: var(--neo-textarea-suffix-color, inherit);
472
- background-color: var(--neo-textarea-suffix-bg-color, transparent);
505
+ align-items: center;
506
+ margin: 0.25rem;
507
+ padding: 0.5rem;
508
+ color: var(--neo-textarea-after-color, inherit);
509
+ background-color: var(--neo-textarea-after-bg-color, transparent);
473
510
  border: none;
474
- border-radius: var(--neo-textarea-suffix-border-radius, var(--neo-border-radius));
511
+ border-radius: var(--neo-textarea-after-border-radius, var(--neo-border-radius));
475
512
  }
476
- .neo-textarea-affix {
477
- position: absolute;
478
- top: 0.125rem;
479
- right: 0.125rem;
480
- display: inline-grid;
481
- grid-template-areas: "affix";
482
- min-width: 2rem;
483
- min-height: 2rem;
484
- border: none;
485
- border-radius: var(--neo-textarea-affix-border-radius, var(--neo-border-radius));
513
+ .neo-textarea-after:is(button, a) {
514
+ cursor: pointer;
486
515
  }
487
- .neo-textarea-affix > * {
488
- grid-area: affix;
516
+ .neo-textarea-after:is(button, a):focus-visible {
517
+ color: var(--neo-textarea-focus-color, var(--neo-text-color-focused));
489
518
  }
490
- .neo-textarea-affix-validation {
491
- width: 100%;
492
- height: 100%;
519
+ .neo-textarea-after:is(button, a):hover {
520
+ color: var(--neo-textarea-hover-color, var(--neo-text-color-hover));
521
+ }
522
+ .neo-textarea-after:is(button, a):active {
523
+ color: var(--neo-textarea-active-color, var(--neo-text-color-hover-active));
524
+ scale: 0.9;
525
+ }
526
+ .neo-textarea-after:is(button, a):disabled {
527
+ color: var(--neo-text-color-disabled);
528
+ cursor: not-allowed;
529
+ scale: 1;
530
+ }
531
+ .neo-textarea-after:has(:global(.neo-button:only-child)) {
532
+ padding: 0;
533
+ }
534
+ .neo-textarea-after :global(.neo-button) {
535
+ --neo-btn-padding-empty: 0.4375rem;
536
+ --neo-btn-margin: auto;
537
+ --neo-btn-box-shadow-active-flat-toggle: var(--neo-box-shadow-inset-2);
538
+ --neo-btn-bg-color: transparent;
539
+ --neo-btn-backdrop-filter: none;
493
540
  }
494
541
  .neo-textarea::placeholder {
495
542
  color: var(--neo-textarea-placeholder-color, var(--neo-text-color-disabled));
@@ -504,68 +551,10 @@
504
551
  resize: none;
505
552
  }
506
553
 
507
- .neo-textarea-clear {
508
- align-items: center;
509
- justify-content: center;
510
- color: var(--neo-textarea-clear-color, inherit);
511
- background-color: var(--neo-background-color-darker);
512
- border: none;
513
- border-radius: 50%;
514
- aspect-ratio: 1;
515
- }
516
- .neo-textarea-clear:focus-visible {
517
- color: var(--neo-close-color-focused, rgba(255, 0, 0, 0.75));
518
- background-color: var(--neo-close-bg-color-focused, rgba(255, 0, 0, 0.05));
519
- }
520
- .neo-textarea-clear:hover {
521
- color: var(--neo-color-warning, rgba(255, 0, 0, 0.75));
522
- background-color: var(--neo-close-bg-color-focused, rgba(255, 0, 0, 0.05));
523
- }
524
- .neo-textarea-clear:disabled {
525
- color: var(--neo-text-color-disabled);
526
- cursor: not-allowed;
527
- }
528
-
529
- .neo-textarea-label-container {
530
- display: flex;
531
- flex: 1 1 auto;
532
- flex-direction: column;
533
- width: 100%;
534
- }
535
- .neo-textarea-label-container .neo-textarea-label {
536
- display: flex;
537
- min-height: var(--neo-textarea-label-height);
538
- padding: 0 0.75rem;
539
- overflow: hidden;
540
- color: var(--neo-textarea-label-color, inherit);
541
- text-wrap: stable;
542
- text-overflow: ellipsis;
543
- cursor: inherit;
544
- transition: padding 0.3s ease, color 0.3s ease, font-size 0.3s ease, line-height 0.3s ease, top 0.3s ease, left 0.3s ease, right 0.3s ease, translate 0.3s ease;
545
- }
546
- .neo-textarea-label-container .neo-textarea-label.first {
547
- transition: none;
548
- }
549
- .neo-textarea-label-container .neo-textarea-label.required::after {
550
- margin-left: 0.1rem;
551
- color: var(--neo-textarea-required-color, var(--neo-color-error-75));
552
- font-size: var(--neo-font-size);
553
- content: "*";
554
- }
555
- .neo-textarea-label-container.floating .neo-textarea-label {
556
- color: var(--neo-textarea-floating-label-color, var(--neo-text-color-disabled));
557
- translate: 0 calc(50% + 0.7rem - var(--neo-textarea-label-height) / 2);
558
- }
559
- .neo-textarea-label-container.floating .neo-textarea-label.required::after {
560
- color: var(--neo-textarea-required-color, var(--neo-color-error-50));
561
- }
562
- .neo-textarea-label-container.floating ::placeholder {
563
- opacity: 0;
564
- }
565
-
566
554
  .neo-textarea-group {
567
555
  position: relative;
568
- margin: var(--neo-shadow-margin, 0.6rem);
556
+ min-width: min-content;
557
+ margin: var(--neo-shadow-margin, 0.625rem);
569
558
  color: var(--neo-textarea-text-color, inherit);
570
559
  background-color: var(--neo-textarea-bg-color, inherit);
571
560
  border: var(--neo-border-width, 1px) var(--neo-textarea-border-color, transparent) solid;
@@ -573,128 +562,176 @@
573
562
  box-shadow: var(--neo-textarea-box-shadow, var(--neo-box-shadow-flat));
574
563
  cursor: text;
575
564
  }
576
- .neo-textarea-group.readonly {
565
+ .neo-textarea-group.neo-readonly {
577
566
  cursor: initial;
578
567
  }
579
- .neo-textarea-group.borderless {
568
+ .neo-textarea-group.neo-borderless {
580
569
  border-color: transparent !important;
581
570
  }
582
- .neo-textarea-group.raised {
571
+ .neo-textarea-group.neo-inset.neo-pressed, .neo-textarea-group.neo-raised {
583
572
  margin: var(--neo-shadow-margin-lg, 1.125rem);
584
573
  }
585
- .neo-textarea-group.inset {
574
+ .neo-textarea-group.neo-inset {
586
575
  padding: 0.25rem;
587
576
  }
588
- .neo-textarea-group.hover.flat-hover:hover, .neo-textarea-group.hover.flat-hover:focus-within, .neo-textarea-group.flat:not(.borderless, .hover-flat:hover, .hover-flat:focus-within) {
577
+ .neo-textarea-group.neo-hover.neo-flat-hover.neo-hovered, .neo-textarea-group.neo-hover.neo-flat-hover:hover, .neo-textarea-group.neo-hover.neo-flat-hover:focus-within, .neo-textarea-group.neo-flat:not(.neo-borderless, .neo-hover-flat:hover, .neo-hover-flat.neo-hovered .neo-hover-flat:focus-within) {
589
578
  border-color: var(--neo-textarea-border-color, var(--neo-border-color));
590
579
  }
591
- .neo-textarea-group:focus-within, .neo-textarea-group.hover:hover {
580
+ .neo-textarea-group:focus-within, .neo-textarea-group.neo-hover:hover, .neo-textarea-group.neo-hover.neo-hovered {
592
581
  box-shadow: var(--neo-textarea-hover-shadow, var(--neo-box-shadow-flat));
593
582
  }
594
- .neo-textarea-group.disabled {
583
+ .neo-textarea-group.neo-disabled {
595
584
  box-shadow: var(--neo-box-shadow-flat) !important;
596
585
  opacity: var(--neo-textarea-opacity-disabled, var(--neo-opacity-disabled));
597
586
  }
598
- .neo-textarea-group.disabled:not(.borderless) {
599
- border-color: var(--neo-btn-border-color-disabled, var(--neo-border-color-disabled)) !important;
587
+ .neo-textarea-group.neo-disabled:not(.neo-borderless) {
588
+ border-color: var(--neo-input-border-color-disabled, var(--neo-border-color-disabled)) !important;
589
+ }
590
+ .neo-textarea-group :global(.neo-affix-container) {
591
+ position: absolute;
592
+ top: 0.125rem;
593
+ right: 0.125rem;
594
+ margin: 0.25rem;
595
+ padding: 0.5rem;
596
+ border: none;
597
+ border-radius: var(--neo-textarea-affix-border-radius, var(--neo-border-radius));
598
+ }
599
+ .neo-textarea-group :global(.neo-label-container) {
600
+ width: 100%;
601
+ }
602
+ .neo-textarea-group :global(.neo-label-container) :global(.neo-label) {
603
+ --neo-label-padding: 0 1rem;
604
+ --neo-label-margin: 0;
605
+ --neo-label-color: var(--neo-textarea-label-color, inherit);
606
+ min-height: var(--neo-textarea-label-height);
607
+ transition: padding 0.3s ease, color 0.3s ease, font-size 0.3s ease, line-height 0.3s ease, top 0.3s ease, left 0.3s ease, right 0.3s ease, translate 0.3s ease;
608
+ }
609
+ .neo-textarea-group :global(.neo-label-container.neo-first .neo-label) {
610
+ transition: none;
611
+ }
612
+ .neo-textarea-group :global(.neo-label-container.neo-affix .neo-label) {
613
+ padding-right: 3.25rem;
600
614
  }
601
- .neo-textarea-group.disabled .neo-textarea-label {
602
- color: unset;
615
+ .neo-textarea-group :global(.neo-label-container.neo-floating) :global(.neo-label) {
616
+ --neo-label-color: var(--neo-textarea-floating-label-color, var(--neo-text-color-disabled));
617
+ --neo-label-required-color: var(--neo-input-required-color, var(--neo-color-error-50));
618
+ translate: 0 calc(50% + 0.75rem - var(--neo-textarea-label-height) / 2);
603
619
  }
604
- .neo-textarea-group.rounded {
620
+ .neo-textarea-group :global(.neo-label-container.neo-floating) :global(.neo-input) {
621
+ color: var(--neo-input-floating-text-color, transparent);
622
+ }
623
+ .neo-textarea-group :global(.neo-label-container.neo-floating) :global(::placeholder) {
624
+ opacity: 0;
625
+ }
626
+ .neo-textarea-group.neo-rounded {
605
627
  border-radius: var(--neo-textarea-border-radius, var(--neo-border-radius-lg));
606
628
  }
607
- .neo-textarea-group.rounded .neo-textarea {
629
+ .neo-textarea-group.neo-rounded :global(.neo-affix-container) {
630
+ right: 0.365rem;
631
+ }
632
+ .neo-textarea-group.neo-rounded .neo-textarea {
608
633
  --neo-scrollbar-button-height: 0.75rem;
609
634
  padding: 0.75rem 1rem;
610
635
  border-radius: var(--neo-border-radius-lg, 2rem);
611
636
  }
612
- .neo-textarea-group.rounded .neo-textarea.affix {
613
- padding: 0.75rem 2.75rem 0.75rem 1rem;
637
+ .neo-textarea-group.neo-rounded .neo-textarea.neo-affix {
638
+ padding: 0.75rem 2.75rem 0.75rem 1.2rem;
614
639
  }
615
- .neo-textarea-group.rounded .neo-textarea-suffix, .neo-textarea-group.rounded .neo-textarea-affix {
640
+ .neo-textarea-group.neo-rounded .neo-textarea-after {
616
641
  right: 0.365rem;
617
642
  }
618
- .neo-textarea-group.rounded .neo-textarea-label-container {
619
- padding-left: 0.5rem;
643
+ .neo-textarea-group.neo-rounded :global(.neo-label-container .neo-label) {
644
+ padding: 0 1.25rem;
620
645
  }
621
- .neo-textarea-group.rounded .neo-textarea-label-container .neo-textarea-label {
622
- padding: 0 1rem;
623
- }
624
- .neo-textarea-group[data-position=top] {
625
- --neo-textarea-margin-top: calc(var(--neo-shadow-margin, 0.6rem) + var(--neo-textarea-label-height, var(--neo-line-height)));
626
- margin-top: var(--neo-textarea-margin-top);
627
- }
628
- .neo-textarea-group[data-position=top] .neo-textarea-label-container .neo-textarea-label {
629
- position: absolute;
630
- top: calc(0% - var(--neo-textarea-margin-top));
646
+ .neo-textarea-group.neo-rounded :global(.neo-label-container.neo-affix .neo-label) {
647
+ padding-right: 3.5rem;
631
648
  }
632
649
  .neo-textarea-group[data-position=left] {
633
- --neo-textarea-margin-left: calc(var(--neo-shadow-margin, 0.6rem) + var(--neo-textarea-label-width, auto));
650
+ --neo-textarea-margin-left: calc(var(--neo-shadow-margin, 0.625rem) + var(--neo-textarea-label-width, auto));
634
651
  margin-left: var(--neo-textarea-margin-left);
635
652
  }
636
- .neo-textarea-group[data-position=left] .neo-textarea-label-container .neo-textarea-label {
653
+ .neo-textarea-group[data-position=left] :global(.neo-label-container .neo-label) {
637
654
  position: absolute;
638
655
  top: 0.75rem;
639
656
  left: calc(0% - var(--neo-textarea-margin-left));
640
657
  }
658
+ .neo-textarea-group[data-position=left] :global(.neo-label-container.neo-affix:not(.neo-floating) .neo-label) {
659
+ left: calc(2.5rem - var(--neo-textarea-margin-left));
660
+ }
661
+ .neo-textarea-group[data-position=left] :global(.neo-label-container.neo-affix:not(.neo-floating).neo-rounded .neo-label) {
662
+ left: calc(2.25rem - var(--neo-textarea-margin-left));
663
+ }
664
+ .neo-textarea-group[data-position=left] :global(.neo-label-container.neo-floating .neo-label) {
665
+ left: 0;
666
+ }
641
667
  .neo-textarea-group[data-position=right] {
642
- --neo-textarea-margin-right: calc(var(--shadow-margin, 0.6rem) + var(--neo-textarea-label-width, auto));
668
+ --neo-textarea-margin-right: calc(var(--neo-shadow-margin, 0.625rem) + var(--neo-textarea-label-width, auto));
643
669
  margin-right: var(--neo-textarea-margin-right);
644
670
  }
645
- .neo-textarea-group[data-position=right] .neo-textarea-label-container .neo-textarea-label {
671
+ .neo-textarea-group[data-position=right] :global(.neo-label-container .neo-label) {
646
672
  position: absolute;
647
673
  top: 0.75rem;
674
+ right: calc(0.25rem - var(--neo-textarea-margin-right));
675
+ }
676
+ .neo-textarea-group[data-position=right] :global(.neo-label-container:not(.neo-floating).neo-rounded .neo-label) {
648
677
  right: calc(0% - var(--neo-textarea-margin-right));
649
678
  }
650
- .neo-textarea-group[data-position=inside] .neo-textarea-label-container .neo-textarea {
651
- padding: 0 1rem 0.5rem;
679
+ .neo-textarea-group[data-position=right] :global(.neo-label-container.neo-floating .neo-label) {
680
+ right: calc(100% - var(--neo-textarea-label-width));
652
681
  }
653
- .neo-textarea-group[data-position=inside] .neo-textarea-label-container .neo-textarea-label {
654
- padding: 0.75rem 1rem 0.2rem;
682
+ .neo-textarea-group[data-position=right] :global(.neo-label-container.neo-floating.neo-rounded .neo-label) {
683
+ right: calc(100% - 0.5rem - var(--neo-textarea-label-width));
684
+ }
685
+ .neo-textarea-group[data-position=inside] :global(.neo-label-container .neo-textarea) {
686
+ padding-top: 0.25rem;
687
+ }
688
+ .neo-textarea-group[data-position=inside] :global(.neo-label-container .neo-label) {
689
+ padding: 0.75rem 1rem 0.1875rem;
655
690
  line-height: var(--neo-line-height-xs, 1rem);
656
691
  }
657
- .neo-textarea-group[data-position=inside] .neo-textarea-label-container:not(.floating) .neo-textarea-label {
692
+ .neo-textarea-group[data-position=inside] :global(.neo-label-container.neo-rounded .neo-label) {
693
+ padding: 0.75rem 1rem 0.1875rem 1.25rem;
694
+ }
695
+ .neo-textarea-group[data-position=inside] :global(.neo-label-container:not(.neo-floating) .neo-label) {
658
696
  font-size: var(--neo-font-size-sm, 0.875rem);
659
697
  }
660
- .neo-textarea-group[data-position=top] .neo-textarea-label-container.floating .neo-textarea-label, .neo-textarea-group[data-position=left] .neo-textarea-label-container.floating .neo-textarea-label, .neo-textarea-group[data-position=right] .neo-textarea-label-container.floating .neo-textarea-label {
661
- top: 0;
698
+ .neo-textarea-group[data-position=top][data-position=top] {
699
+ --neo-textarea-margin-top: calc(var(--neo-shadow-margin, 0.625rem) + var(--neo-textarea-label-height, var(--neo-line-height)));
700
+ margin-top: var(--neo-textarea-margin-top);
662
701
  }
663
- .neo-textarea-group[data-position=left] .neo-textarea-label-container.floating .neo-textarea-label {
664
- left: 0.5rem;
702
+ .neo-textarea-group[data-position=top][data-position=top] :global(.neo-label-container .neo-label) {
703
+ position: absolute;
704
+ top: calc(0% - var(--neo-textarea-margin-top));
665
705
  }
666
- .neo-textarea-group[data-position=right] .neo-textarea-label-container.floating .neo-textarea-label {
667
- right: calc(100% - var(--neo-textarea-label-width) - 0.5rem);
706
+ .neo-textarea-group[data-position=top] :global(.neo-label-container.neo-floating .neo-label), .neo-textarea-group[data-position=left] :global(.neo-label-container.neo-floating .neo-label), .neo-textarea-group[data-position=right] :global(.neo-label-container.neo-floating .neo-label) {
707
+ top: 0;
668
708
  }
669
- .neo-textarea-group.glass {
709
+ .neo-textarea-group.neo-glass {
670
710
  --neo-skeleton-color: var(--neo-glass-skeleton-color);
711
+ --neo-border-color: var(--neo-glass-border-color);
671
712
  background-color: var(--neo-textarea-bg-color, var(--neo-glass-background-color));
672
713
  border-color: var(--neo-textarea-border-color, var(--neo-glass-top-border-color) var(--neo-glass-right-border-color) var(--neo-glass-bottom-border-color) var(--neo-glass-left-border-color));
673
- backdrop-filter: var(--neo-textarea-glass-blur, var(--neo-blur-4) var(--neo-saturate-2));
714
+ backdrop-filter: var(--neo-textarea-glass-blur, var(--neo-blur-3) var(--neo-saturate-2));
674
715
  }
675
- .neo-textarea-group.validation[data-valid=false] {
716
+ .neo-textarea-group.neo-validation[data-valid=false] {
676
717
  --neo-textarea-label-color: var(--neo-textarea-label-color-error, var(--neo-color-error));
677
718
  --neo-textarea-floating-label-color: var(--neo-textarea-floating-label-color-error, var(--neo-color-error-50));
719
+ --neo-label-disabled-color: var(--neo-input-floating-label-color-error, var(--neo-color-error-50));
678
720
  }
679
- .neo-textarea-group.validation[data-valid=false] .neo-textarea-affix-validation {
680
- color: var(--neo-textarea-validation-color-error, var(--neo-color-error));
681
- }
682
- .neo-textarea-group.validation[data-valid=true] {
721
+ .neo-textarea-group.neo-validation[data-valid=true] {
683
722
  --neo-textarea-label-color: var(--neo-textarea-label-color-success, var(--neo-color-success));
684
723
  --neo-textarea-floating-label-color: var(--neo-textarea-floating-label-color-success, var(--neo-color-success-50));
685
- }
686
- .neo-textarea-group.validation[data-valid=true] .neo-textarea-affix-validation {
687
- color: var(--neo-textarea-validation-color-success, var(--neo-color-success));
724
+ --neo-label-disabled-color: var(--neo-input-floating-label-color-success, var(--neo-color-success-50));
688
725
  }
689
726
  @starting-style {
690
- .neo-textarea-group.start {
727
+ .neo-textarea-group.neo-start {
691
728
  box-shadow: var(--neo-box-shadow-flat);
692
729
  }
693
- .neo-textarea-group.start:not(.borderless) {
730
+ .neo-textarea-group.neo-start:not(.neo-borderless) {
694
731
  border-color: var(--neo-textarea-border-color, var(--neo-border-color));
695
732
  }
696
733
  }
697
- .neo-textarea-group.skeleton {
734
+ .neo-textarea-group.neo-skeleton {
698
735
  box-shadow: var(--neo-box-shadow-flat);
699
736
  pointer-events: none;
700
737
  --neo-skeleton-color-start: var(--neo-skeleton-color);
@@ -706,10 +743,10 @@
706
743
  animation: skeleton 3s var(--neo-transition-skeleton) infinite;
707
744
  animation-delay: 1s;
708
745
  }
709
- .neo-textarea-group.skeleton::before, .neo-textarea-group.skeleton::after,
710
- .neo-textarea-group.skeleton :global(> *::before),
711
- .neo-textarea-group.skeleton :global(> *::after),
712
- .neo-textarea-group.skeleton :global(> *) {
746
+ .neo-textarea-group.neo-skeleton::before, .neo-textarea-group.neo-skeleton::after,
747
+ .neo-textarea-group.neo-skeleton :global(> *::before),
748
+ .neo-textarea-group.neo-skeleton :global(> *::after),
749
+ .neo-textarea-group.neo-skeleton :global(> *) {
713
750
  visibility: hidden;
714
751
  pointer-events: none;
715
752
  }
@@ -735,14 +772,11 @@
735
772
  border-color: var(--neo-skeleton-color-start);
736
773
  }
737
774
  }
738
- .neo-textarea-group.skeleton.glass {
739
- --neo-skeleton-color: var(--neo-glass-skeleton-color);
740
- }
741
775
  .neo-textarea-group .neo-textarea {
742
776
  scrollbar-gutter: stable;
743
777
  }
744
778
  .neo-textarea-group .neo-textarea::-webkit-scrollbar {
745
- width: var(--neo-scrollbar-width, 0.45rem);
779
+ width: var(--neo-scrollbar-width, 0.375rem);
746
780
  background-color: transparent;
747
781
  border: none;
748
782
  cursor: pointer;
@@ -763,6 +797,6 @@
763
797
  outline: none;
764
798
  }
765
799
  .neo-textarea-group .neo-textarea::-webkit-resizer {
766
- background: url("~/assets/neo-icon-resizer-bottom-right.svg") no-repeat bottom;
800
+ background: url("../assets/neo-icon-resizer-bottom-right.svg") no-repeat bottom;
767
801
  background-clip: border-box;
768
802
  }</style>