@marianmeres/stuic 2.65.0 → 3.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.
- package/README.md +292 -4
- package/dist/README.md +41 -18
- package/dist/actions/popover/README.md +19 -0
- package/dist/actions/popover/index.css +6 -9
- package/dist/actions/popover/popover.svelte.js +2 -2
- package/dist/actions/tooltip/README.md +18 -0
- package/dist/actions/tooltip/index.css +5 -8
- package/dist/actions/tooltip/tooltip.svelte.js +1 -1
- package/dist/components/AlertConfirmPrompt/AlertConfirmPrompt.svelte +9 -10
- package/dist/components/AlertConfirmPrompt/AlertConfirmPrompt.svelte.d.ts +3 -3
- package/dist/components/AlertConfirmPrompt/Current.svelte +15 -17
- package/dist/components/AlertConfirmPrompt/Current.svelte.d.ts +5 -3
- package/dist/components/AlertConfirmPrompt/acp-icons.js +5 -4
- package/dist/components/AlertConfirmPrompt/index.css +62 -0
- package/dist/components/AssetsPreview/AssetsPreview.svelte +92 -73
- package/dist/components/AssetsPreview/AssetsPreview.svelte.d.ts +1 -0
- package/dist/components/AssetsPreview/index.css +59 -0
- package/dist/components/Avatar/Avatar.svelte +32 -18
- package/dist/components/Avatar/Avatar.svelte.d.ts +1 -0
- package/dist/components/Avatar/README.md +166 -0
- package/dist/components/Avatar/index.css +128 -0
- package/dist/components/Backdrop/Backdrop.svelte +8 -2
- package/dist/components/Backdrop/Backdrop.svelte.d.ts +1 -0
- package/dist/components/Backdrop/README.md +71 -6
- package/dist/components/Backdrop/index.css +29 -0
- package/dist/components/Button/Button.svelte +117 -124
- package/dist/components/Button/Button.svelte.d.ts +35 -23
- package/dist/components/Button/README.md +87 -21
- package/dist/components/Button/index.css +473 -9
- package/dist/components/Button/index.d.ts +1 -1
- package/dist/components/Button/index.js +1 -1
- package/dist/components/ButtonGroupRadio/ButtonGroupRadio.svelte +7 -38
- package/dist/components/ButtonGroupRadio/README.md +82 -4
- package/dist/components/ButtonGroupRadio/index.css +152 -14
- package/dist/components/Collapsible/Collapsible.svelte +7 -7
- package/dist/components/Collapsible/Collapsible.svelte.d.ts +2 -2
- package/dist/components/Collapsible/README.md +34 -2
- package/dist/components/Collapsible/index.css +38 -0
- package/dist/components/CommandMenu/CommandMenu.svelte +13 -24
- package/dist/components/CommandMenu/README.md +39 -0
- package/dist/components/CommandMenu/index.css +45 -2
- package/dist/components/DismissibleMessage/DismissibleMessage.svelte +53 -50
- package/dist/components/DismissibleMessage/DismissibleMessage.svelte.d.ts +6 -5
- package/dist/components/DismissibleMessage/README.md +93 -11
- package/dist/components/DismissibleMessage/index.css +122 -8
- package/dist/components/DismissibleMessage/index.d.ts +1 -1
- package/dist/components/DropdownMenu/DropdownMenu.svelte +14 -50
- package/dist/components/DropdownMenu/DropdownMenu.svelte.d.ts +6 -6
- package/dist/components/DropdownMenu/README.md +132 -0
- package/dist/components/DropdownMenu/index.css +231 -27
- package/dist/components/Input/FieldAssets.svelte +8 -5
- package/dist/components/Input/FieldCheckbox.svelte +7 -44
- package/dist/components/Input/FieldFile.svelte +1 -6
- package/dist/components/Input/FieldInput.svelte +1 -1
- package/dist/components/Input/FieldOptions.svelte +41 -38
- package/dist/components/Input/FieldRadios.svelte +7 -16
- package/dist/components/Input/FieldSelect.svelte +1 -1
- package/dist/components/Input/FieldSwitch.svelte +1 -5
- package/dist/components/Input/FieldTextarea.svelte +1 -1
- package/dist/components/Input/README.md +194 -0
- package/dist/components/Input/_internal/FieldRadioInternal.svelte +2 -40
- package/dist/components/Input/_internal/InputWrap.svelte +8 -48
- package/dist/components/Input/index.css +522 -127
- package/dist/components/ListItemButton/ListItemButton.svelte +37 -73
- package/dist/components/ListItemButton/ListItemButton.svelte.d.ts +1 -9
- package/dist/components/ListItemButton/README.md +100 -45
- package/dist/components/ListItemButton/index.css +175 -56
- package/dist/components/ListItemButton/index.d.ts +1 -1
- package/dist/components/ListItemButton/index.js +1 -1
- package/dist/components/Modal/Modal.svelte +2 -8
- package/dist/components/Modal/Modal.svelte.d.ts +1 -0
- package/dist/components/Modal/README.md +29 -0
- package/dist/components/Modal/index.css +36 -0
- package/dist/components/ModalDialog/ModalDialog.svelte +2 -21
- package/dist/components/ModalDialog/README.md +35 -0
- package/dist/components/ModalDialog/index.css +57 -0
- package/dist/components/Notifications/Notifications.svelte +44 -128
- package/dist/components/Notifications/Notifications.svelte.d.ts +9 -17
- package/dist/components/Notifications/README.md +186 -70
- package/dist/components/Notifications/index.css +212 -15
- package/dist/components/Progress/README.md +15 -0
- package/dist/components/Progress/_internal/Bar.svelte +2 -2
- package/dist/components/Progress/index.css +4 -4
- package/dist/components/Skeleton/Skeleton.svelte +3 -2
- package/dist/components/Skeleton/index.css +11 -14
- package/dist/components/Spinner/Spinner.svelte +2 -2
- package/dist/components/Spinner/SpinnerCircle.svelte +1 -1
- package/dist/components/Switch/README.md +15 -0
- package/dist/components/Switch/Switch.svelte +4 -7
- package/dist/components/Switch/Switch.svelte.d.ts +1 -1
- package/dist/components/Switch/SwitchButton.svelte +4 -5
- package/dist/components/Switch/index.css +3 -4
- package/dist/components/TabbedMenu/README.md +26 -21
- package/dist/components/TabbedMenu/TabbedMenu.svelte +5 -5
- package/dist/components/TabbedMenu/index.css +7 -22
- package/dist/components/ThemePreview/README.md +289 -0
- package/dist/components/ThemePreview/ThemePreview.svelte +341 -0
- package/dist/components/ThemePreview/ThemePreview.svelte.d.ts +33 -0
- package/dist/components/ThemePreview/index.css +493 -0
- package/dist/components/ThemePreview/index.d.ts +1 -0
- package/dist/components/ThemePreview/index.js +1 -0
- package/dist/components/TwCheck/TwCheck.svelte +4 -4
- package/dist/components/TwCheck/index.css +3 -2
- package/dist/components/TypeaheadInput/TypeaheadInput.svelte +1 -1
- package/dist/components/X/X.svelte +16 -4
- package/dist/components/X/X.svelte.d.ts +1 -0
- package/dist/icons/index.d.ts +1 -0
- package/dist/icons/index.js +1 -0
- package/dist/index.css +31 -16
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/themes/blue-orange.css +163 -0
- package/dist/themes/blue-orange.d.ts +6 -0
- package/dist/themes/blue-orange.js +151 -0
- package/dist/themes/cyan-red.css +163 -0
- package/dist/themes/cyan-red.d.ts +6 -0
- package/dist/themes/cyan-red.js +151 -0
- package/dist/themes/cyan-slate.css +163 -0
- package/dist/themes/cyan-slate.d.ts +6 -0
- package/dist/themes/cyan-slate.js +151 -0
- package/dist/themes/emerald-pink.css +163 -0
- package/dist/themes/emerald-pink.d.ts +6 -0
- package/dist/themes/emerald-pink.js +151 -0
- package/dist/themes/fuchsia-emerald.css +163 -0
- package/dist/themes/fuchsia-emerald.d.ts +6 -0
- package/dist/themes/fuchsia-emerald.js +151 -0
- package/dist/themes/gray.css +163 -0
- package/dist/themes/gray.d.ts +6 -0
- package/dist/themes/gray.js +151 -0
- package/dist/themes/indigo-amber.css +163 -0
- package/dist/themes/indigo-amber.d.ts +6 -0
- package/dist/themes/indigo-amber.js +151 -0
- package/dist/themes/neutral.css +163 -0
- package/dist/themes/neutral.d.ts +6 -0
- package/dist/themes/neutral.js +151 -0
- package/dist/themes/pink-emerald.css +163 -0
- package/dist/themes/pink-emerald.d.ts +6 -0
- package/dist/themes/pink-emerald.js +151 -0
- package/dist/themes/purple-yellow.css +163 -0
- package/dist/themes/purple-yellow.d.ts +6 -0
- package/dist/themes/purple-yellow.js +151 -0
- package/dist/themes/rainbow.css +163 -0
- package/dist/themes/rainbow.d.ts +6 -0
- package/dist/themes/rainbow.js +156 -0
- package/dist/themes/red-blue.css +163 -0
- package/dist/themes/red-blue.d.ts +6 -0
- package/dist/themes/red-blue.js +151 -0
- package/dist/themes/red-cyan.css +163 -0
- package/dist/themes/red-cyan.d.ts +6 -0
- package/dist/themes/red-cyan.js +151 -0
- package/dist/themes/rose-teal.css +163 -0
- package/dist/themes/rose-teal.d.ts +6 -0
- package/dist/themes/rose-teal.js +151 -0
- package/dist/themes/sky-amber.css +163 -0
- package/dist/themes/sky-amber.d.ts +6 -0
- package/dist/themes/sky-amber.js +151 -0
- package/dist/themes/slate-cyan.css +163 -0
- package/dist/themes/slate-cyan.d.ts +6 -0
- package/dist/themes/slate-cyan.js +151 -0
- package/dist/themes/tailwind-color-pairs.md +31 -0
- package/dist/themes/teal-rose.css +163 -0
- package/dist/themes/teal-rose.d.ts +6 -0
- package/dist/themes/teal-rose.js +151 -0
- package/dist/themes/violet-lime.css +163 -0
- package/dist/themes/violet-lime.d.ts +6 -0
- package/dist/themes/violet-lime.js +151 -0
- package/dist/utils/design-tokens.d.ts +43 -0
- package/dist/utils/design-tokens.js +100 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/package.json +22 -2
|
@@ -63,30 +63,23 @@
|
|
|
63
63
|
let validation = $state<ValidationResult | undefined>();
|
|
64
64
|
let invalid = $derived(validation && !validation?.valid);
|
|
65
65
|
|
|
66
|
-
//
|
|
67
|
-
let _classCommon = $derived(
|
|
68
|
-
[invalid && "invalid", disabled && "disabled", required && "required", renderSize]
|
|
69
|
-
.filter(Boolean)
|
|
70
|
-
.join(" ")
|
|
71
|
-
);
|
|
72
66
|
// $inspect(value);
|
|
73
67
|
</script>
|
|
74
68
|
|
|
75
69
|
{#if _options.length}
|
|
76
|
-
<div
|
|
70
|
+
<div
|
|
71
|
+
class={twMerge("stuic-radios", invalid && "invalid", disabled && "disabled")}
|
|
72
|
+
data-size={renderSize}
|
|
73
|
+
{style}
|
|
74
|
+
>
|
|
77
75
|
<div
|
|
78
76
|
class={twMerge(
|
|
79
77
|
"radios-box",
|
|
80
|
-
|
|
81
|
-
"gap-y-2 grid rounded-md p-2 mb-8",
|
|
82
|
-
"border border-neutral-300 dark:border-neutral-600",
|
|
83
|
-
"bg-neutral-100 dark:bg-neutral-700",
|
|
84
|
-
invalid && "border-input-accent-invalid dark:border-input-accent-invalid-dark",
|
|
78
|
+
"gap-y-2 grid p-2 mb-8",
|
|
85
79
|
classProp
|
|
86
80
|
)}
|
|
87
81
|
>
|
|
88
82
|
{#each _options as o, i}
|
|
89
|
-
<!-- value={o.value || o.label} -->
|
|
90
83
|
<FieldRadioInternal
|
|
91
84
|
{name}
|
|
92
85
|
bind:group={value}
|
|
@@ -114,9 +107,7 @@
|
|
|
114
107
|
transition:slide={{ duration: 150 }}
|
|
115
108
|
class={twMerge(
|
|
116
109
|
"validation-box",
|
|
117
|
-
|
|
118
|
-
`mt-1 px-2 text-sm text-input-accent dark:text-input-accent-dark
|
|
119
|
-
tracking-tight`,
|
|
110
|
+
"mt-1 px-2 text-sm tracking-tight",
|
|
120
111
|
classValidationBox
|
|
121
112
|
)}
|
|
122
113
|
>
|
|
@@ -111,14 +111,10 @@
|
|
|
111
111
|
{classLabel}
|
|
112
112
|
{classLabelBox}
|
|
113
113
|
{classInputBox}
|
|
114
|
-
classInputBoxWrap={twMerge(
|
|
115
|
-
"border-0 focus-within:border-0 focus-within:dark:border-0 focus-within:ring-0",
|
|
116
|
-
"bg-transparent dark:bg-transparent",
|
|
117
|
-
classInputBoxWrap
|
|
118
|
-
)}
|
|
119
114
|
{classDescBox}
|
|
120
115
|
{classBelowBox}
|
|
121
116
|
{validation}
|
|
117
|
+
classInputBoxWrap={twMerge("input-wrap-transparent", classInputBoxWrap)}
|
|
122
118
|
{style}
|
|
123
119
|
>
|
|
124
120
|
<Switch bind:checked {name} {required} {disabled} {validate} {setValidationResult} />
|
|
@@ -232,3 +232,197 @@ Validation is handled by the `validate` action. Pass `validate={true}` for defau
|
|
|
232
232
|
}}
|
|
233
233
|
/>
|
|
234
234
|
```
|
|
235
|
+
|
|
236
|
+
## CSS Variables
|
|
237
|
+
|
|
238
|
+
### Component Tokens
|
|
239
|
+
|
|
240
|
+
Override globally in `:root` or locally via `style` prop:
|
|
241
|
+
|
|
242
|
+
| Variable | Default | Description |
|
|
243
|
+
|----------|---------|-------------|
|
|
244
|
+
| `--stuic-input-radius` | `--radius-md` | Border radius |
|
|
245
|
+
| `--stuic-input-font-family` | `--font-sans` | Font family |
|
|
246
|
+
| `--stuic-input-transition` | `150ms` | Transition duration |
|
|
247
|
+
| `--stuic-input-ring-width` | `4px` | Focus ring width |
|
|
248
|
+
| `--stuic-input-ring-color` | `--stuic-color-ring` | Focus ring color |
|
|
249
|
+
| `--stuic-input-accent` | `--stuic-color-primary` | Accent color |
|
|
250
|
+
| `--stuic-input-accent-error` | `--stuic-color-destructive` | Error/validation color |
|
|
251
|
+
|
|
252
|
+
### Color Tokens
|
|
253
|
+
|
|
254
|
+
| Variable | Default | Description |
|
|
255
|
+
|----------|---------|-------------|
|
|
256
|
+
| `--stuic-input-bg` | `--stuic-color-input` | Background color |
|
|
257
|
+
| `--stuic-input-border` | `--stuic-color-border` | Border color |
|
|
258
|
+
| `--stuic-input-border-focus` | `--stuic-input-accent` | Border color on focus |
|
|
259
|
+
| `--stuic-input-text` | `--stuic-color-foreground` | Text color |
|
|
260
|
+
| `--stuic-input-placeholder` | `--stuic-color-muted-foreground` | Placeholder color |
|
|
261
|
+
|
|
262
|
+
### Size Tokens
|
|
263
|
+
|
|
264
|
+
Each size (sm, md, lg) has corresponding tokens:
|
|
265
|
+
|
|
266
|
+
| Variable | sm | md | lg |
|
|
267
|
+
|----------|----|----|-----|
|
|
268
|
+
| `--stuic-input-padding-x-{size}` | `calc(--spacing * 2.5)` | `calc(--spacing * 3)` | `calc(--spacing * 4)` |
|
|
269
|
+
| `--stuic-input-padding-y-{size}` | `calc(--spacing * 2)` | `calc(--spacing * 2.5)` | `calc(--spacing * 3)` |
|
|
270
|
+
| `--stuic-input-font-size-{size}` | `--text-sm` | `--text-base` | `--text-lg` |
|
|
271
|
+
| `--stuic-input-min-height-{size}` | `2.5rem` | `2.75rem` | `3rem` |
|
|
272
|
+
|
|
273
|
+
### Checkbox/Radio Tokens
|
|
274
|
+
|
|
275
|
+
| Variable | Default | Description |
|
|
276
|
+
|----------|---------|-------------|
|
|
277
|
+
| `--stuic-checkbox-size` | `1.25rem` | Checkbox size |
|
|
278
|
+
| `--stuic-checkbox-radius` | `--radius-sm` | Checkbox border radius |
|
|
279
|
+
| `--stuic-radio-size` | `1rem` | Radio button size |
|
|
280
|
+
| `--stuic-checkbox-bg` | `--stuic-color-muted` | Unchecked background |
|
|
281
|
+
| `--stuic-checkbox-border` | `--stuic-color-border` | Unchecked border |
|
|
282
|
+
| `--stuic-checkbox-checked-bg` | `--stuic-input-accent` | Checked background |
|
|
283
|
+
| `--stuic-checkbox-checked-border` | `--stuic-input-accent` | Checked border |
|
|
284
|
+
|
|
285
|
+
### Range Input Tokens
|
|
286
|
+
|
|
287
|
+
| Variable | Default | Description |
|
|
288
|
+
|----------|---------|-------------|
|
|
289
|
+
| `--stuic-input-range-thumb-size` | `18px` | Slider thumb size |
|
|
290
|
+
| `--stuic-input-range-track-height` | `4px` | Track height |
|
|
291
|
+
| `--stuic-input-range-track-radius` | `18px` | Track border radius |
|
|
292
|
+
| `--stuic-input-range-track-bg` | `--stuic-color-muted` | Track background |
|
|
293
|
+
|
|
294
|
+
### Customization Examples
|
|
295
|
+
|
|
296
|
+
```css
|
|
297
|
+
/* Global: Make all inputs have pill shape */
|
|
298
|
+
:root {
|
|
299
|
+
--stuic-input-radius: 9999px;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/* Global: Custom accent color */
|
|
303
|
+
:root {
|
|
304
|
+
--stuic-input-accent: var(--color-violet-600);
|
|
305
|
+
}
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
```svelte
|
|
309
|
+
<!-- Local: Custom radius for one input -->
|
|
310
|
+
<FieldInput
|
|
311
|
+
label="Search"
|
|
312
|
+
style="--stuic-input-radius: 9999px;"
|
|
313
|
+
/>
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
## Data Attributes
|
|
317
|
+
|
|
318
|
+
Components use data attributes for CSS styling:
|
|
319
|
+
|
|
320
|
+
- `data-size` - The size value ("sm", "md", "lg")
|
|
321
|
+
|
|
322
|
+
## Class Props
|
|
323
|
+
|
|
324
|
+
| Prop | Target |
|
|
325
|
+
|------|--------|
|
|
326
|
+
| `class` | Root container |
|
|
327
|
+
| `classInput` | Input element |
|
|
328
|
+
| `classLabel` | Label element |
|
|
329
|
+
| `classLabelBox` | Label container |
|
|
330
|
+
| `classInputBox` | Input container (outer) |
|
|
331
|
+
| `classInputBoxWrap` | Input wrapper (inner, has border) |
|
|
332
|
+
| `classInputBoxWrapInvalid` | Input wrapper when invalid |
|
|
333
|
+
| `classDescBox` | Description container |
|
|
334
|
+
| `classBelowBox` | Below slot container |
|
|
335
|
+
|
|
336
|
+
---
|
|
337
|
+
|
|
338
|
+
## FieldOptions
|
|
339
|
+
|
|
340
|
+
A modal-based multi-select/single-select component with search functionality, typeahead support, and option grouping.
|
|
341
|
+
|
|
342
|
+
### Props
|
|
343
|
+
|
|
344
|
+
| Prop | Type | Default | Description |
|
|
345
|
+
|------|------|---------|-------------|
|
|
346
|
+
| `value` | `string` | `"[]"` | JSON array of selected items (bindable) |
|
|
347
|
+
| `name` | `string` | - | Form field name |
|
|
348
|
+
| `getOptions` | `(q: string, current: Item[]) => Promise<{found: Item[]}>` | - | Async function to fetch options |
|
|
349
|
+
| `cardinality` | `number` | `Infinity` | Max selections (-1 for unlimited) |
|
|
350
|
+
| `allowUnknown` | `boolean` | `false` | Allow typing custom values |
|
|
351
|
+
| `renderOptionLabel` | `(item: Item) => string` | - | Custom option label renderer |
|
|
352
|
+
| `renderOptionGroup` | `(s: string) => string` | - | Custom optgroup label renderer |
|
|
353
|
+
| `renderValue` | `(stringifiedItems: string) => string` | - | Custom value display renderer |
|
|
354
|
+
| `showIconsCheckbox` | `boolean` | `true` | Show checkbox icons in multi-select |
|
|
355
|
+
| `showIconsRadio` | `boolean` | `false` | Show radio icons in single-select |
|
|
356
|
+
| `searchPlaceholder` | `string` | - | Custom search placeholder |
|
|
357
|
+
| `itemIdPropName` | `string` | `"id"` | Property name for item ID |
|
|
358
|
+
| `notifications` | `NotificationsStack` | - | Notification handler for errors |
|
|
359
|
+
|
|
360
|
+
### Class Props
|
|
361
|
+
|
|
362
|
+
| Prop | Target |
|
|
363
|
+
|------|--------|
|
|
364
|
+
| `classOption` | Option item (ListItemButton) |
|
|
365
|
+
| `classOptionActive` | Active/selected option |
|
|
366
|
+
| `classOptgroup` | Option group label |
|
|
367
|
+
| `classModalField` | Modal field wrapper |
|
|
368
|
+
|
|
369
|
+
### CSS Variables
|
|
370
|
+
|
|
371
|
+
#### Component Tokens
|
|
372
|
+
|
|
373
|
+
| Variable | Default | Description |
|
|
374
|
+
|----------|---------|-------------|
|
|
375
|
+
| `--stuic-field-options-divider` | `--stuic-color-border` | Divider/separator color |
|
|
376
|
+
| `--stuic-field-options-control-text` | `--stuic-color-muted-foreground` | Control button text color |
|
|
377
|
+
| `--stuic-field-options-control-text-hover` | `--stuic-color-foreground` | Control button hover text color |
|
|
378
|
+
| `--stuic-field-options-control-ring` | `--stuic-color-ring` | Control button focus ring |
|
|
379
|
+
| `--stuic-field-options-muted-text` | `--stuic-color-muted-foreground` | Muted/secondary text color |
|
|
380
|
+
| `--stuic-field-options-optgroup-text` | `--stuic-color-muted-foreground` | Option group label color |
|
|
381
|
+
|
|
382
|
+
### Usage
|
|
383
|
+
|
|
384
|
+
```svelte
|
|
385
|
+
<script lang="ts">
|
|
386
|
+
import { FieldOptions } from 'stuic';
|
|
387
|
+
|
|
388
|
+
let value = $state('[]');
|
|
389
|
+
|
|
390
|
+
async function getOptions(query: string, current: any[]) {
|
|
391
|
+
const response = await fetch(`/api/search?q=${query}`);
|
|
392
|
+
const data = await response.json();
|
|
393
|
+
return { found: data.items };
|
|
394
|
+
}
|
|
395
|
+
</script>
|
|
396
|
+
|
|
397
|
+
<FieldOptions
|
|
398
|
+
label="Select Tags"
|
|
399
|
+
name="tags"
|
|
400
|
+
bind:value
|
|
401
|
+
{getOptions}
|
|
402
|
+
cardinality={5}
|
|
403
|
+
allowUnknown
|
|
404
|
+
/>
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
### Customization Examples
|
|
408
|
+
|
|
409
|
+
```css
|
|
410
|
+
/* Make optgroup labels more prominent */
|
|
411
|
+
:root {
|
|
412
|
+
--stuic-field-options-optgroup-text: var(--stuic-color-primary);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/* Custom control button colors */
|
|
416
|
+
:root {
|
|
417
|
+
--stuic-field-options-control-text: var(--stuic-color-primary);
|
|
418
|
+
--stuic-field-options-control-text-hover: var(--stuic-color-primary-hover);
|
|
419
|
+
}
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
```svelte
|
|
423
|
+
<!-- Local customization -->
|
|
424
|
+
<FieldOptions
|
|
425
|
+
style="--stuic-field-options-divider: var(--color-red-500);"
|
|
426
|
+
...
|
|
427
|
+
/>
|
|
428
|
+
```
|
|
@@ -69,21 +69,7 @@
|
|
|
69
69
|
let id = getId();
|
|
70
70
|
let idDesc = getId();
|
|
71
71
|
|
|
72
|
-
//
|
|
73
|
-
let _classCommon = $derived(
|
|
74
|
-
[invalid && "invalid", disabled && "disabled", renderSize].filter(Boolean).join(" ")
|
|
75
|
-
);
|
|
76
72
|
|
|
77
|
-
const _preset = {
|
|
78
|
-
labelBox: {
|
|
79
|
-
label: {
|
|
80
|
-
size: {
|
|
81
|
-
sm: "text-sm mt-0.5",
|
|
82
|
-
lg: "font-semibold",
|
|
83
|
-
} as any,
|
|
84
|
-
},
|
|
85
|
-
},
|
|
86
|
-
};
|
|
87
73
|
</script>
|
|
88
74
|
|
|
89
75
|
{#snippet snippetOrThc({ id, value }: { id: string; value?: SnippetWithId | THC })}
|
|
@@ -97,7 +83,6 @@
|
|
|
97
83
|
<label
|
|
98
84
|
class={twMerge(
|
|
99
85
|
"radio-box",
|
|
100
|
-
_classCommon,
|
|
101
86
|
"flex items-start cursor-pointer pr-1",
|
|
102
87
|
disabled && "cursor-not-allowed",
|
|
103
88
|
classRadioBox
|
|
@@ -106,7 +91,6 @@
|
|
|
106
91
|
<div
|
|
107
92
|
class={twMerge(
|
|
108
93
|
"input-box",
|
|
109
|
-
_classCommon,
|
|
110
94
|
"flex h-6 items-center ml-1",
|
|
111
95
|
classInputBox
|
|
112
96
|
)}
|
|
@@ -118,26 +102,7 @@
|
|
|
118
102
|
bind:group
|
|
119
103
|
{value}
|
|
120
104
|
{name}
|
|
121
|
-
class={twMerge(
|
|
122
|
-
_classCommon,
|
|
123
|
-
`size-4 rounded-full
|
|
124
|
-
bg-neutral-100
|
|
125
|
-
border-neutral-300
|
|
126
|
-
text-input-accent dark:text-input-accent-dark
|
|
127
|
-
cursor-pointer
|
|
128
|
-
|
|
129
|
-
checked:border-input-accent checked:bg-input-accent
|
|
130
|
-
checked:dark:border-input-accent-dark checked:dark:bg-input-accent-dark
|
|
131
|
-
|
|
132
|
-
focus:border-input-accent
|
|
133
|
-
focus:ring-4
|
|
134
|
-
focus:ring-offset-0
|
|
135
|
-
focus:ring-input-accent/20 focus:dark:ring-input-accent-dark/20
|
|
136
|
-
|
|
137
|
-
disabled:cursor-not-allowed`,
|
|
138
|
-
disabled && "cursor-not-allowed",
|
|
139
|
-
classInput
|
|
140
|
-
)}
|
|
105
|
+
class={twMerge(classInput)}
|
|
141
106
|
aria-describedby={description ? idDesc : undefined}
|
|
142
107
|
use:validateAction={() => ({
|
|
143
108
|
enabled: !!validate,
|
|
@@ -149,14 +114,12 @@
|
|
|
149
114
|
{...rest}
|
|
150
115
|
/>
|
|
151
116
|
</div>
|
|
152
|
-
<div class={twMerge("label-box",
|
|
117
|
+
<div class={twMerge("label-box", "ml-3 w-full", classLabelBox)}>
|
|
153
118
|
{#if label}
|
|
154
119
|
<div
|
|
155
120
|
class={twMerge(
|
|
156
121
|
"label",
|
|
157
|
-
_classCommon,
|
|
158
122
|
"block w-full cursor-pointer",
|
|
159
|
-
renderSize && _preset.labelBox.label.size[renderSize],
|
|
160
123
|
required && "after:content-['*'] after:opacity-40 after:pl-1",
|
|
161
124
|
classLabel
|
|
162
125
|
)}
|
|
@@ -173,7 +136,6 @@
|
|
|
173
136
|
id={idDesc}
|
|
174
137
|
class={twMerge(
|
|
175
138
|
"desc-box",
|
|
176
|
-
_classCommon,
|
|
177
139
|
"text-sm opacity-50 cursor-pointer font-normal",
|
|
178
140
|
disabled && "cursor-not-allowed",
|
|
179
141
|
classDescBox
|
|
@@ -87,28 +87,8 @@
|
|
|
87
87
|
}
|
|
88
88
|
});
|
|
89
89
|
|
|
90
|
-
let _classCommon = $derived(
|
|
91
|
-
[invalid && "invalid", disabled && "disabled", required && "required", size]
|
|
92
|
-
.filter(Boolean)
|
|
93
|
-
.join(" ")
|
|
94
|
-
);
|
|
95
|
-
|
|
96
90
|
let hasLabel = $derived(isTHCNotEmpty(label) || typeof label === "function");
|
|
97
91
|
|
|
98
|
-
const _preset = {
|
|
99
|
-
label: {
|
|
100
|
-
size: {
|
|
101
|
-
sm: "text-sm",
|
|
102
|
-
lg: "font-semibold",
|
|
103
|
-
} as any,
|
|
104
|
-
},
|
|
105
|
-
inputBox: {
|
|
106
|
-
size: {
|
|
107
|
-
sm: "text-sm",
|
|
108
|
-
lg: "p-1",
|
|
109
|
-
} as any,
|
|
110
|
-
},
|
|
111
|
-
};
|
|
112
92
|
</script>
|
|
113
93
|
|
|
114
94
|
{#snippet snippetOrThc({ id, value }: { id: string; value?: SnippetWithId | THC })}
|
|
@@ -122,20 +102,21 @@
|
|
|
122
102
|
<div
|
|
123
103
|
class={twMerge(
|
|
124
104
|
"stuic-input",
|
|
125
|
-
_classCommon,
|
|
126
105
|
"mb-8",
|
|
106
|
+
invalid && "invalid",
|
|
107
|
+
disabled && "disabled",
|
|
127
108
|
hasLabel && labelLeft && "flex",
|
|
128
109
|
hasLabel && labelLeft && labelLeftWidth === "normal" && "width-normal",
|
|
129
110
|
hasLabel && labelLeft && labelLeftWidth === "wide" && "width-wide",
|
|
130
111
|
classProp
|
|
131
112
|
)}
|
|
113
|
+
data-size={size}
|
|
132
114
|
bind:clientWidth={width}
|
|
133
115
|
{style}
|
|
134
116
|
>
|
|
135
117
|
<div
|
|
136
118
|
class={twMerge(
|
|
137
119
|
"label-box",
|
|
138
|
-
_classCommon,
|
|
139
120
|
"flex flex-1",
|
|
140
121
|
labelLeft ? "left items-start mt-2" : "items-end",
|
|
141
122
|
classLabelBox
|
|
@@ -145,11 +126,8 @@
|
|
|
145
126
|
<label
|
|
146
127
|
for={id}
|
|
147
128
|
class={twMerge(
|
|
148
|
-
"block",
|
|
149
|
-
_classCommon,
|
|
150
|
-
"flex-1 px-2 mb-1 text-base",
|
|
129
|
+
"block flex-1 px-2 mb-1 text-base",
|
|
151
130
|
required && "after:content-['*'] after:opacity-40 after:pl-1",
|
|
152
|
-
_preset.label.size[size],
|
|
153
131
|
classLabel
|
|
154
132
|
)}
|
|
155
133
|
>
|
|
@@ -163,7 +141,6 @@
|
|
|
163
141
|
<div
|
|
164
142
|
class={twMerge(
|
|
165
143
|
"input-box",
|
|
166
|
-
_classCommon,
|
|
167
144
|
hasLabel && labelLeft && labelLeftWidth === "normal" && "flex-3",
|
|
168
145
|
hasLabel && labelLeft && labelLeftWidth === "wide" && "flex-2",
|
|
169
146
|
classInputBox
|
|
@@ -172,23 +149,8 @@
|
|
|
172
149
|
<div
|
|
173
150
|
class={twMerge(
|
|
174
151
|
"input-wrap",
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
bg-neutral-100 dark:bg-neutral-700
|
|
178
|
-
focus-within:border-input-accent focus-within:dark:border-input-accent-dark
|
|
179
|
-
focus-within:ring-input-accent/20 focus-within:dark:ring-input-accent-dark/20
|
|
180
|
-
focus-within:ring-4`,
|
|
181
|
-
disabled && "cursor-not-allowed opacity-50",
|
|
182
|
-
_preset.inputBox.size[size],
|
|
183
|
-
invalid
|
|
184
|
-
? twMerge(
|
|
185
|
-
classInputBoxWrap,
|
|
186
|
-
`border-input-accent-invalid dark:border-input-accent-invalid-dark
|
|
187
|
-
focus-within:border-input-accent-invalid focus-within:dark:border-input-accent-invalid-dark
|
|
188
|
-
focus-within:ring-input-accent-invalid/20 focus-within:dark:ring-input-accent-invalid-dark/20`,
|
|
189
|
-
classInputBoxWrapInvalid
|
|
190
|
-
)
|
|
191
|
-
: classInputBoxWrap
|
|
152
|
+
classInputBoxWrap,
|
|
153
|
+
invalid && classInputBoxWrapInvalid
|
|
192
154
|
)}
|
|
193
155
|
>
|
|
194
156
|
<div class="flex">
|
|
@@ -204,8 +166,7 @@
|
|
|
204
166
|
transition:slide={{ duration: 150 }}
|
|
205
167
|
class={twMerge(
|
|
206
168
|
"validation-box",
|
|
207
|
-
|
|
208
|
-
"my-1 text-sm px-2 text-input-accent-invalid dark:text-input-accent-invalid-dark",
|
|
169
|
+
"my-1 text-sm px-2",
|
|
209
170
|
classValidationBox
|
|
210
171
|
)}
|
|
211
172
|
>
|
|
@@ -217,7 +178,6 @@
|
|
|
217
178
|
<div
|
|
218
179
|
class={twMerge(
|
|
219
180
|
"desc-box",
|
|
220
|
-
_classCommon,
|
|
221
181
|
"mx-2 mt-1 text-sm opacity-50",
|
|
222
182
|
classDescBox
|
|
223
183
|
)}
|
|
@@ -236,7 +196,7 @@
|
|
|
236
196
|
{/if}
|
|
237
197
|
|
|
238
198
|
{#if below}
|
|
239
|
-
<div class={twMerge("below-box",
|
|
199
|
+
<div class={twMerge("below-box", "mx-2 my-1", classBelowBox)}>
|
|
240
200
|
{@render snippetOrThc({ id, value: below })}
|
|
241
201
|
</div>
|
|
242
202
|
{/if}
|