@marianmeres/stuic 3.115.0 → 3.117.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 (101) hide show
  1. package/API.md +297 -304
  2. package/dist/actions/dim-behind/index.css +4 -1
  3. package/dist/actions/focus-trap.fixture.svelte +16 -0
  4. package/dist/actions/focus-trap.fixture.svelte.d.ts +7 -0
  5. package/dist/actions/focus-trap.js +3 -1
  6. package/dist/components/Accordion/README.md +17 -17
  7. package/dist/components/Accordion/index.css +4 -2
  8. package/dist/components/AssetsPreview/README.md +7 -7
  9. package/dist/components/AssetsPreview/_internal/assets-preview-types.d.ts +1 -2
  10. package/dist/components/AssetsPreview/_internal/assets-preview-utils.d.ts +1 -1
  11. package/dist/components/AssetsPreview/_internal/assets-preview-utils.js +9 -3
  12. package/dist/components/Avatar/Avatar.svelte +1 -3
  13. package/dist/components/Avatar/README.md +33 -27
  14. package/dist/components/Book/Book.svelte +6 -1
  15. package/dist/components/Book/README.md +22 -20
  16. package/dist/components/Book/index.css +4 -2
  17. package/dist/components/Button/README.md +17 -17
  18. package/dist/components/Card/Card.svelte +25 -8
  19. package/dist/components/Card/README.md +52 -56
  20. package/dist/components/Card/index.css +2 -1
  21. package/dist/components/Carousel/Carousel.svelte +1 -3
  22. package/dist/components/Carousel/README.md +28 -28
  23. package/dist/components/Cart/Cart.svelte +2 -1
  24. package/dist/components/Cart/README.md +25 -25
  25. package/dist/components/Checkout/CheckoutGuestOrLoginForm.svelte +8 -3
  26. package/dist/components/Checkout/CheckoutShippingStep.svelte +1 -2
  27. package/dist/components/Checkout/README.md +143 -130
  28. package/dist/components/CommandMenu/CommandMenu.fixture.svelte +24 -0
  29. package/dist/components/CommandMenu/CommandMenu.fixture.svelte.d.ts +7 -0
  30. package/dist/components/CommandMenu/CommandMenu.svelte +10 -13
  31. package/dist/components/CommandMenu/_internal/command-menu-utils.d.ts +22 -0
  32. package/dist/components/CommandMenu/_internal/command-menu-utils.js +37 -0
  33. package/dist/components/CronInput/CronInput.svelte +64 -60
  34. package/dist/components/CronInput/README.md +46 -46
  35. package/dist/components/DataTable/DataTable.svelte +5 -1
  36. package/dist/components/DataTable/README.md +78 -63
  37. package/dist/components/DropdownMenu/DropdownMenu.svelte +14 -29
  38. package/dist/components/DropdownMenu/README.md +33 -27
  39. package/dist/components/DropdownMenu/_internal/dropdown-menu-search.d.ts +21 -0
  40. package/dist/components/DropdownMenu/_internal/dropdown-menu-search.js +47 -0
  41. package/dist/components/EmailVerifyForm/EmailVerifyForm.svelte +2 -9
  42. package/dist/components/EmailVerifyForm/README.md +30 -30
  43. package/dist/components/Header/Header.svelte +161 -165
  44. package/dist/components/Header/README.md +7 -7
  45. package/dist/components/IconSwap/README.md +20 -15
  46. package/dist/components/IconSwap/index.css +2 -1
  47. package/dist/components/ImageCycler/ImageCycler.svelte +19 -5
  48. package/dist/components/ImageCycler/ImageCycler.svelte.d.ts +14 -10
  49. package/dist/components/ImageCycler/README.md +15 -15
  50. package/dist/components/ImageCycler/index.css +26 -20
  51. package/dist/components/Input/FieldFile.svelte +1 -3
  52. package/dist/components/Input/FieldInput.svelte +1 -3
  53. package/dist/components/Input/FieldKeyValues.svelte +2 -6
  54. package/dist/components/Input/FieldObject.svelte +2 -1
  55. package/dist/components/Input/README.md +11 -11
  56. package/dist/components/Input/node_modules/.vite/vitest/d2a04d71301a8915217dd5faf81d12cffd6cd958/_svelte_metadata.json +1 -0
  57. package/dist/components/Input/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/_svelte_metadata.json +1 -0
  58. package/dist/components/KbdShortcut/index.css +2 -1
  59. package/dist/components/LoginForm/LoginForm.svelte +1 -7
  60. package/dist/components/LoginForm/README.md +46 -46
  61. package/dist/components/ModalDialog/ModalDialog.fixture.svelte +19 -0
  62. package/dist/components/ModalDialog/ModalDialog.fixture.svelte.d.ts +4 -0
  63. package/dist/components/ModalDialog/index.css +2 -1
  64. package/dist/components/Notifications/index.css +24 -6
  65. package/dist/components/OtpInput/OtpInput.svelte +0 -0
  66. package/dist/components/OtpInput/README.md +15 -19
  67. package/dist/components/OtpInput/index.css +1 -4
  68. package/dist/components/OtpInput/index.d.ts +1 -1
  69. package/dist/components/OtpInput/index.js +1 -1
  70. package/dist/components/Pill/README.md +41 -40
  71. package/dist/components/Pill/index.css +3 -6
  72. package/dist/components/PricingTable/README.md +86 -86
  73. package/dist/components/PricingTable/index.css +20 -35
  74. package/dist/components/RegisterForm/README.md +60 -60
  75. package/dist/components/RegisterForm/RegisterForm.svelte +1 -7
  76. package/dist/components/Separator/README.md +7 -7
  77. package/dist/components/SlidingPanels/SlidingPanels.fixture.svelte +20 -0
  78. package/dist/components/SlidingPanels/SlidingPanels.fixture.svelte.d.ts +6 -0
  79. package/dist/components/TabbedMenu/index.css +6 -3
  80. package/dist/components/Tree/README.md +67 -67
  81. package/dist/components/UserAvatarMenu/UserAvatarMenu.svelte +1 -5
  82. package/dist/components/WithSidePanel/index.css +4 -4
  83. package/dist/index.css +12 -8
  84. package/dist/utils/design-tokens.d.ts +1 -1
  85. package/dist/utils/design-tokens.js +1 -1
  86. package/docs/architecture.md +7 -7
  87. package/docs/component-testing/00-overview-and-roadmap.md +19 -19
  88. package/docs/component-testing/01-framework-setup.md +6 -6
  89. package/docs/component-testing/02-test-conventions.md +6 -5
  90. package/docs/component-testing/03-component-coverage-roadmap.md +27 -27
  91. package/docs/component-testing/04-hard-cases-and-e2e.md +8 -8
  92. package/docs/component-testing/05-ci.md +3 -3
  93. package/docs/component-testing/PROGRESS.md +118 -26
  94. package/docs/component-testing/README.md +8 -8
  95. package/docs/conventions.md +25 -25
  96. package/docs/domains/components.md +386 -385
  97. package/docs/domains/theming.md +24 -24
  98. package/docs/domains/utils.md +22 -25
  99. package/docs/testing.md +2 -2
  100. package/docs/upgrading.md +32 -28
  101. package/package.json +2 -1
package/API.md CHANGED
@@ -78,14 +78,14 @@ Overlay container with backdrop. Controlled programmatically.
78
78
 
79
79
  Pre-styled modal dialog with title and action buttons. Uses native `<dialog>` element with focus trap and backdrop.
80
80
 
81
- | Prop | Type | Default | Description |
82
- | ------------------ | ---------- | ----------- | ----------------------------------------------------- |
83
- | `classDialog` | `string` | `undefined` | CSS class for the dialog element |
84
- | `noClickOutsideClose` | `boolean` | `false` | Disable close on outside click |
85
- | `noEscapeClose` | `boolean` | `false` | Disable close on Escape key |
86
- | `noScrollLock` | `boolean` | `false` | Disable body scroll lock when open |
87
- | `preEscapeClose` | `() => any` | — | Pre-close hook for Escape. Return false to prevent. |
88
- | `preClose` | `() => any` | — | Pre-close hook. Return false to prevent. |
81
+ | Prop | Type | Default | Description |
82
+ | --------------------- | ----------- | ----------- | --------------------------------------------------- |
83
+ | `classDialog` | `string` | `undefined` | CSS class for the dialog element |
84
+ | `noClickOutsideClose` | `boolean` | `false` | Disable close on outside click |
85
+ | `noEscapeClose` | `boolean` | `false` | Disable close on Escape key |
86
+ | `noScrollLock` | `boolean` | `false` | Disable body scroll lock when open |
87
+ | `preEscapeClose` | `() => any` | — | Pre-close hook for Escape. Return false to prevent. |
88
+ | `preClose` | `() => any` | — | Pre-close hook. Return false to prevent. |
89
89
 
90
90
  **Methods:** `open(openerOrEvent?)`, `close()`
91
91
 
@@ -134,37 +134,37 @@ Navigation wrapper component.
134
134
 
135
135
  Responsive navigation header with leading slot, logo, nav items, locale switcher, action icon buttons, avatar, and configurable responsive collapse (`"hamburger"` fold or `"hide"` for app-like shells). Renders as `<header>`.
136
136
 
137
- | Prop | Type | Default | Description |
138
- | ----------------------- | ----------------------------------------- | ---------------------- | -------------------------------------------------------------------------------------------------------------------- |
139
- | `leading` | `Snippet<[{ isCollapsed }]>` | — | Leading (left-side) slot. Overrides `leadingHamburger`. |
140
- | `leadingHamburger` | `boolean \| "collapsed"` | `false` | Built-in hamburger in the leading slot (`"collapsed"` = only below threshold). Ignored when `leading` is provided. |
141
- | `onLeadingHamburger` | `() => void` | — | Click handler for the built-in leading hamburger (typically opens a drawer). |
142
- | `leadingHamburgerIcon` | `THC` | menu icon | Icon override for the built-in leading hamburger. |
143
- | `leadingHamburgerLabel` | `string` | `"Open menu"` | Aria-label for the leading hamburger. |
144
- | `logo` | `Snippet` | — | Logo/brand snippet. |
145
- | `projectName` | `string` | — | Simple text logo alternative. |
146
- | `navVariant` | `ButtonVariant` | `"ghost"` | Button variant for nav items and the locale switcher trigger. |
147
- | `items` | `HeaderNavItem[]` | `[]` | Navigation items — inline when expanded, dropdown when collapsed (hamburger mode). |
148
- | `actions` | `HeaderActionItem[]` | `[]` | Action icon buttons between the locale switcher and the avatar. Always visible — never fold into the dropdown. |
149
- | `onActionSelect` | `(action) => void` | — | Called after the per-item `onclick`. |
150
- | `avatar` | `Snippet` | — | Avatar snippet (far right). |
151
- | `avatarOnClick` | `() => void` | — | Makes the avatar interactive. In `"hamburger"` collapse mode it moves into the dropdown. |
152
- | `avatarLabel` | `THC` | `"Account"` | Label for the avatar entry inside the collapsed dropdown. |
153
- | `locales` | `HeaderLocaleItem[]` | `[]` | Locale items. Switcher only renders when 2+. |
154
- | `activeLocale` | `string` | — | Current locale id. |
155
- | `onLocaleChange` | `(localeId) => void` | — | Locale selection callback. |
156
- | `localeLabel` | `THC` | `"Language"` | Section header inside the collapsed dropdown. |
157
- | `contentMaxWidth` | `string \| number` | — | Max-width of the inner content row (outer header stays 100%). Accepts any CSS length. Maps to `--stuic-header-content-max-width`. |
158
- | `collapseThreshold` | `number` | `768` | Width (px) to collapse; 0 disables. |
159
- | `collapseMode` | `"hamburger" \| "hide"` | `"hamburger"` | Collapse behavior. `"hide"` keeps avatar/actions visible and renders no trailing hamburger (app-shell pattern). |
160
- | `keepLocaleOnCollapse` | `boolean` | `false` | Keep the locale switcher visible in collapsed mode (only `collapseMode === "hide"`). |
161
- | `fixed` | `boolean` | `false` | Fixed positioning at the top. |
162
- | `isCollapsed` | `boolean` | — | Bindable: collapsed state. |
163
- | `isMenuOpen` | `boolean` | — | Bindable: hamburger menu open. |
164
- | `dropdownPosition` | `DropdownMenuPosition` | `"bottom-span-right"` | Position of the collapsed dropdown. |
165
- | `iconSize` | `number` | `24` | Hamburger/X icon size in px. |
166
- | `onSelect` | `(item) => void` | — | Item selection callback (both modes). |
167
- | `children` | `Snippet<[{ isCollapsed, items, offsetWidth }]>` | — | Escape hatch: override the entire inner layout. |
137
+ | Prop | Type | Default | Description |
138
+ | ----------------------- | ------------------------------------------------ | --------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
139
+ | `leading` | `Snippet<[{ isCollapsed }]>` | — | Leading (left-side) slot. Overrides `leadingHamburger`. |
140
+ | `leadingHamburger` | `boolean \| "collapsed"` | `false` | Built-in hamburger in the leading slot (`"collapsed"` = only below threshold). Ignored when `leading` is provided. |
141
+ | `onLeadingHamburger` | `() => void` | — | Click handler for the built-in leading hamburger (typically opens a drawer). |
142
+ | `leadingHamburgerIcon` | `THC` | menu icon | Icon override for the built-in leading hamburger. |
143
+ | `leadingHamburgerLabel` | `string` | `"Open menu"` | Aria-label for the leading hamburger. |
144
+ | `logo` | `Snippet` | — | Logo/brand snippet. |
145
+ | `projectName` | `string` | — | Simple text logo alternative. |
146
+ | `navVariant` | `ButtonVariant` | `"ghost"` | Button variant for nav items and the locale switcher trigger. |
147
+ | `items` | `HeaderNavItem[]` | `[]` | Navigation items — inline when expanded, dropdown when collapsed (hamburger mode). |
148
+ | `actions` | `HeaderActionItem[]` | `[]` | Action icon buttons between the locale switcher and the avatar. Always visible — never fold into the dropdown. |
149
+ | `onActionSelect` | `(action) => void` | — | Called after the per-item `onclick`. |
150
+ | `avatar` | `Snippet` | — | Avatar snippet (far right). |
151
+ | `avatarOnClick` | `() => void` | — | Makes the avatar interactive. In `"hamburger"` collapse mode it moves into the dropdown. |
152
+ | `avatarLabel` | `THC` | `"Account"` | Label for the avatar entry inside the collapsed dropdown. |
153
+ | `locales` | `HeaderLocaleItem[]` | `[]` | Locale items. Switcher only renders when 2+. |
154
+ | `activeLocale` | `string` | — | Current locale id. |
155
+ | `onLocaleChange` | `(localeId) => void` | — | Locale selection callback. |
156
+ | `localeLabel` | `THC` | `"Language"` | Section header inside the collapsed dropdown. |
157
+ | `contentMaxWidth` | `string \| number` | — | Max-width of the inner content row (outer header stays 100%). Accepts any CSS length. Maps to `--stuic-header-content-max-width`. |
158
+ | `collapseThreshold` | `number` | `768` | Width (px) to collapse; 0 disables. |
159
+ | `collapseMode` | `"hamburger" \| "hide"` | `"hamburger"` | Collapse behavior. `"hide"` keeps avatar/actions visible and renders no trailing hamburger (app-shell pattern). |
160
+ | `keepLocaleOnCollapse` | `boolean` | `false` | Keep the locale switcher visible in collapsed mode (only `collapseMode === "hide"`). |
161
+ | `fixed` | `boolean` | `false` | Fixed positioning at the top. |
162
+ | `isCollapsed` | `boolean` | — | Bindable: collapsed state. |
163
+ | `isMenuOpen` | `boolean` | — | Bindable: hamburger menu open. |
164
+ | `dropdownPosition` | `DropdownMenuPosition` | `"bottom-span-right"` | Position of the collapsed dropdown. |
165
+ | `iconSize` | `number` | `24` | Hamburger/X icon size in px. |
166
+ | `onSelect` | `(item) => void` | — | Item selection callback (both modes). |
167
+ | `children` | `Snippet<[{ isCollapsed, items, offsetWidth }]>` | — | Escape hatch: override the entire inner layout. |
168
168
 
169
169
  Class slots: `class`, `classContent`, `classLeading`, `classLeadingHamburger`, `classLogo`, `classNav`, `classNavItem`, `classNavItemActive`, `classActions`, `classAction`, `classActionActive`, `classEnd`, `classAvatar`, `classLocale`, `classHamburger`, `classDropdown`.
170
170
 
@@ -361,18 +361,18 @@ Toggle button styled as a "like" action.
361
361
 
362
362
  International phone number input with country dial code picker. Parses and composes full phone numbers (e.g. `+421905123456`), handles paste with international prefix detection, supports country filtering and preferred countries.
363
363
 
364
- | Prop | Type | Default | Description |
365
- | -------------------- | ----------------------------------- | ----------- | -------------------------------------------------- |
366
- | `value` | `string` | `""` | Bindable full phone number (e.g. `"+421905123456"`) |
367
- | `country` | `string` | `""` | Bindable selected country ISO code (e.g. `"SK"`) |
368
- | `dialCode` | `string` | `""` | Bindable dial code with `+` (e.g. `"+421"`) |
369
- | `localNumber` | `string` | `""` | Bindable local number part |
370
- | `defaultCountry` | `string` | — | ISO code for initial country selection |
371
- | `flags` | `boolean` | `true` | Show country flag emoji |
372
- | `countries` | `string[]` | all | Filtered list of country ISO codes to show |
373
- | `preferredCountries` | `string[]` | — | ISO codes pinned at top of dropdown |
374
- | `name` | `string` | — | Hidden input name for form submission |
375
- | `validate` | `boolean \| ValidateOptions` | — | Enable phone validation |
364
+ | Prop | Type | Default | Description |
365
+ | -------------------- | ---------------------------- | ------- | --------------------------------------------------- |
366
+ | `value` | `string` | `""` | Bindable full phone number (e.g. `"+421905123456"`) |
367
+ | `country` | `string` | `""` | Bindable selected country ISO code (e.g. `"SK"`) |
368
+ | `dialCode` | `string` | `""` | Bindable dial code with `+` (e.g. `"+421"`) |
369
+ | `localNumber` | `string` | `""` | Bindable local number part |
370
+ | `defaultCountry` | `string` | — | ISO code for initial country selection |
371
+ | `flags` | `boolean` | `true` | Show country flag emoji |
372
+ | `countries` | `string[]` | all | Filtered list of country ISO codes to show |
373
+ | `preferredCountries` | `string[]` | — | ISO codes pinned at top of dropdown |
374
+ | `name` | `string` | — | Hidden input name for form submission |
375
+ | `validate` | `boolean \| ValidateOptions` | — | Enable phone validation |
376
376
 
377
377
  Exports: `FieldPhoneNumber`, `FieldPhoneNumberProps`, `validatePhoneNumber`, `Country`.
378
378
 
@@ -380,19 +380,19 @@ Exports: `FieldPhoneNumber`, `FieldPhoneNumberProps`, `validatePhoneNumber`, `Co
380
380
 
381
381
  Country picker dropdown with searchable, optionally flag-prefixed list. Submits a country ISO alpha-2 code via a hidden input. Pairs naturally with `FieldPhoneNumber` and with checkout/address forms.
382
382
 
383
- | Prop | Type | Default | Description |
384
- | -------------------- | --------------------------------- | ----------- | -------------------------------------------------------------------------- |
385
- | `value` | `string` | `""` | Bindable ISO alpha-2 code (e.g. `"SK"`). Empty = unselected. |
386
- | `onChange` | `(iso: string) => void` | — | Called when selection changes. |
387
- | `countryList` | `Country[] \| string[]` | all | Restrict the list to specific countries (objects or ISO codes). |
388
- | `preferredCountries` | `string[]` | — | ISO codes pinned at the top of the dropdown. |
389
- | `countryNames` | `Record<string, string>` | English | Override displayed country names (keyed by ISO code). |
390
- | `flags` | `boolean` | `true` | Show country flag emoji. |
391
- | `name` | `string` | — | Hidden input name (enables form submission + native validation). |
392
- | `placeholder` | `string` | — | Trigger placeholder text when nothing is selected. |
393
- | `required` | `boolean` | `false` | Required indicator + validation. |
394
- | `disabled` | `boolean` | `false` | Disable the trigger and dropdown. |
395
- | `validate` | `boolean \| ValidateOptions` | enabled | Validation behavior (default-on, see Imperative validate API). |
383
+ | Prop | Type | Default | Description |
384
+ | -------------------- | ---------------------------- | ------- | ---------------------------------------------------------------- |
385
+ | `value` | `string` | `""` | Bindable ISO alpha-2 code (e.g. `"SK"`). Empty = unselected. |
386
+ | `onChange` | `(iso: string) => void` | — | Called when selection changes. |
387
+ | `countryList` | `Country[] \| string[]` | all | Restrict the list to specific countries (objects or ISO codes). |
388
+ | `preferredCountries` | `string[]` | — | ISO codes pinned at the top of the dropdown. |
389
+ | `countryNames` | `Record<string, string>` | English | Override displayed country names (keyed by ISO code). |
390
+ | `flags` | `boolean` | `true` | Show country flag emoji. |
391
+ | `name` | `string` | — | Hidden input name (enables form submission + native validation). |
392
+ | `placeholder` | `string` | — | Trigger placeholder text when nothing is selected. |
393
+ | `required` | `boolean` | `false` | Required indicator + validation. |
394
+ | `disabled` | `boolean` | `false` | Disable the trigger and dropdown. |
395
+ | `validate` | `boolean \| ValidateOptions` | enabled | Validation behavior (default-on, see Imperative validate API). |
396
396
 
397
397
  Integrates with `InputWrap` — supports `label`, `description`, `renderSize`, `labelLeft`, `labelLeftWidth`, `labelLeftBreakpoint`, `inputBefore`, `inputAfter`, `inputBelow`, `below`, `classInput`, `classDropdown`.
398
398
 
@@ -429,17 +429,17 @@ Dual-mode JSON object editor with pretty-print and raw edit modes. Validates JSO
429
429
 
430
430
  Cron expression editor with preset selector, manual 5-field editor, raw expression input, human-readable descriptions, and next-run calculation.
431
431
 
432
- | Prop | Type | Default | Description |
433
- | ----------------- | ----------------------------- | ------------- | ------------------------------- |
434
- | `value` | `string` | `"* * * * *"` | Bindable cron expression |
435
- | `mode` | `CronInputMode` | — | Bindable; predefined or manual |
436
- | `showPresets` | `boolean` | `true` | Show preset selector |
437
- | `showFields` | `boolean` | `true` | Show 5-column field editor |
438
- | `showRawInput` | `boolean` | `true` | Show raw expression input |
439
- | `showDescription` | `boolean` | `true` | Show human-readable description |
440
- | `showNextRun` | `boolean` | `true` | Show next run time |
441
- | `presets` | `CronPreset[]` | default set | Custom presets |
442
- | `onchange` | `(expr: string, valid: boolean) => void` | — | Change callback |
432
+ | Prop | Type | Default | Description |
433
+ | ----------------- | ---------------------------------------- | ------------- | ------------------------------- |
434
+ | `value` | `string` | `"* * * * *"` | Bindable cron expression |
435
+ | `mode` | `CronInputMode` | — | Bindable; predefined or manual |
436
+ | `showPresets` | `boolean` | `true` | Show preset selector |
437
+ | `showFields` | `boolean` | `true` | Show 5-column field editor |
438
+ | `showRawInput` | `boolean` | `true` | Show raw expression input |
439
+ | `showDescription` | `boolean` | `true` | Show human-readable description |
440
+ | `showNextRun` | `boolean` | `true` | Show next run time |
441
+ | `presets` | `CronPreset[]` | default set | Custom presets |
442
+ | `onchange` | `(expr: string, valid: boolean) => void` | — | Change callback |
443
443
 
444
444
  Integrates with `InputWrap` — supports `label`, `description`, `renderSize`, `required`, `disabled`, `validate`, `labelLeft`, `below`.
445
445
 
@@ -453,10 +453,10 @@ Exports: `CronInput`, `CronInputProps`, `CronPreset`, `CronInputMode`, `CRON_DEF
453
453
 
454
454
  ```ts
455
455
  const next = new CronNextRun("0 9 * * 1-5");
456
- next.nextRun; // Date | null
456
+ next.nextRun; // Date | null
457
457
  next.nextRunFormatted; // "YYYY-MM-DD HH:MM"
458
- next.valid; // boolean
459
- next.destroy(); // cleanup timer
458
+ next.valid; // boolean
459
+ next.destroy(); // cleanup timer
460
460
  ```
461
461
 
462
462
  CSS tokens: `--stuic-cron-input-fields-gap`, `--stuic-cron-input-section-gap`, `--stuic-cron-input-field-label-text`, `--stuic-cron-input-summary-text`, `--stuic-cron-input-error-text`, `--stuic-cron-input-field-bg`, `--stuic-cron-input-field-border`, `--stuic-cron-input-field-border-focus`.
@@ -575,33 +575,33 @@ Loading spinner indicator (default SVG spinner).
575
575
 
576
576
  CSS-only circular spinner.
577
577
 
578
- | Prop | Type | Default | Description |
579
- | ----------- | --------------------------------- | ---------- | -------------------------- |
580
- | `duration` | `number` | `750` | One loop duration in ms |
581
- | `thickness` | `"normal" \| "thin" \| "thick"` | `"normal"` | Border thickness preset |
582
- | `direction` | `"cw" \| "ccw"` | `"cw"` | Rotation direction |
578
+ | Prop | Type | Default | Description |
579
+ | ----------- | ------------------------------- | ---------- | ----------------------- |
580
+ | `duration` | `number` | `750` | One loop duration in ms |
581
+ | `thickness` | `"normal" \| "thin" \| "thick"` | `"normal"` | Border thickness preset |
582
+ | `direction` | `"cw" \| "ccw"` | `"cw"` | Rotation direction |
583
583
 
584
584
  #### `SpinnerCircleOscillate`
585
585
 
586
586
  Animated Circle-based spinner with oscillating arc completeness.
587
587
 
588
- | Prop | Type | Default | Description |
589
- | ---------------- | --------- | ------- | ----------------------------- |
590
- | `bgStrokeColor` | `string` | — | Background circle stroke |
591
- | `strokeWidth` | `number` | — | SVG stroke width |
592
- | `noOscillate` | `boolean` | — | Fixed completeness (no anim) |
593
- | `rotateDuration` | `string` | — | CSS animation duration |
588
+ | Prop | Type | Default | Description |
589
+ | ---------------- | --------- | ------- | ---------------------------- |
590
+ | `bgStrokeColor` | `string` | — | Background circle stroke |
591
+ | `strokeWidth` | `number` | — | SVG stroke width |
592
+ | `noOscillate` | `boolean` | — | Fixed completeness (no anim) |
593
+ | `rotateDuration` | `string` | — | CSS animation duration |
594
594
 
595
595
  #### `SpinnerUnicode`
596
596
 
597
597
  Unicode character frame animation with 17 built-in variants.
598
598
 
599
- | Prop | Type | Default | Description |
600
- | ---------- | ------------------------ | ------------------- | ---------------------------- |
601
- | `speed` | `number` | `100` | Frame interval in ms |
602
- | `variant` | `SpinnerUnicodeVariant` | `"braille_bar_dot"` | Built-in animation variant |
603
- | `reversed` | `boolean` | `false` | Reverse frame order |
604
- | `frames` | `string[]` | — | Custom animation frames |
599
+ | Prop | Type | Default | Description |
600
+ | ---------- | ----------------------- | ------------------- | -------------------------- |
601
+ | `speed` | `number` | `100` | Frame interval in ms |
602
+ | `variant` | `SpinnerUnicodeVariant` | `"braille_bar_dot"` | Built-in animation variant |
603
+ | `reversed` | `boolean` | `false` | Reverse frame order |
604
+ | `frames` | `string[]` | — | Custom animation frames |
605
605
 
606
606
  Variants: `braille_bar`, `braille_bar_dot`, `braille_dot_circle`, `braille_dot_bounce`, `half_circle`, `quarter_circle`, `ascii`, `bar_v`, `bar_h`, `shade`, `arrows`, `arrows2`, `asterix`, `asterix2`, `asterix3`, `asterix4`, `asterix5`.
607
607
 
@@ -919,21 +919,21 @@ User avatar with fallback to initials or icon.
919
919
 
920
920
  Thin wrapper around `Avatar` + `DropdownMenu` for the "user avatar in the header → small menu" pattern. Renders sensibly in both authenticated (header tile, View profile, color-scheme toggle, Logout) and unauthenticated (Login, Register) states from the same trigger position. Built-in color-scheme item calls `ColorScheme.toggle()`; all other actions are consumer callbacks. No auth/router/i18n ownership.
921
921
 
922
- | Prop | Type | Default | Description |
923
- | ---------------- | -------------------------------------------- | ------- | -------------------------------------------------------------------------------------- |
924
- | `identity` | `UserAvatarMenuIdentity \| null` | `null` | `{ email, name?, src?, roles? }`. `null` → unauth mode. |
925
- | `actions` | `UserAvatarMenuActions` | `{}` | `onProfile`, `onSettings`, `onLogout`, `onLoginOrRegister`, `onLogin`, `onRegister`. Missing → item hidden. |
926
- | `labels` | `UserAvatarMenuLabels` | English | Translated strings for built-in items. |
927
- | `colorScheme` | `boolean \| { enabled?, onToggle?, isDark? }` | `true` | Built-in dark/light toggle. `false` to disable. |
928
- | `showHeaderTile` | `boolean` | `true` | Render the avatar+email tile (auth only). |
929
- | `showRoles` | `boolean` | `false` | Render `identity.roles` under the email. |
930
- | `extraItems` | `DropdownMenuItem[]` | — | Appended to the standard item set. |
931
- | `items` | `DropdownMenuItem[]` | — | Full override of the item list (trigger + shell still render). |
932
- | `avatar` | `Partial<AvatarProps>` | — | Forwarded to the trigger Avatar (and header-tile Avatar). |
933
- | `position` | `DropdownMenuPosition` | — | Forwarded to `DropdownMenu`. |
934
- | `classDropdown` | `string` | — | Forwarded. |
935
- | `trigger` | `Snippet<[{ isOpen, toggle, triggerProps }]>` | — | Custom trigger snippet (replaces default `Avatar`). |
936
- | `headerTile` | `Snippet<[{ identity }]>` | — | Custom header-tile snippet. |
922
+ | Prop | Type | Default | Description |
923
+ | ---------------- | --------------------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------- |
924
+ | `identity` | `UserAvatarMenuIdentity \| null` | `null` | `{ email, name?, src?, roles? }`. `null` → unauth mode. |
925
+ | `actions` | `UserAvatarMenuActions` | `{}` | `onProfile`, `onSettings`, `onLogout`, `onLoginOrRegister`, `onLogin`, `onRegister`. Missing → item hidden. |
926
+ | `labels` | `UserAvatarMenuLabels` | English | Translated strings for built-in items. |
927
+ | `colorScheme` | `boolean \| { enabled?, onToggle?, isDark? }` | `true` | Built-in dark/light toggle. `false` to disable. |
928
+ | `showHeaderTile` | `boolean` | `true` | Render the avatar+email tile (auth only). |
929
+ | `showRoles` | `boolean` | `false` | Render `identity.roles` under the email. |
930
+ | `extraItems` | `DropdownMenuItem[]` | — | Appended to the standard item set. |
931
+ | `items` | `DropdownMenuItem[]` | — | Full override of the item list (trigger + shell still render). |
932
+ | `avatar` | `Partial<AvatarProps>` | — | Forwarded to the trigger Avatar (and header-tile Avatar). |
933
+ | `position` | `DropdownMenuPosition` | — | Forwarded to `DropdownMenu`. |
934
+ | `classDropdown` | `string` | — | Forwarded. |
935
+ | `trigger` | `Snippet<[{ isOpen, toggle, triggerProps }]>` | — | Custom trigger snippet (replaces default `Avatar`). |
936
+ | `headerTile` | `Snippet<[{ identity }]>` | — | Custom header-tile snippet. |
937
937
 
938
938
  ```svelte
939
939
  <!-- Authenticated -->
@@ -960,22 +960,22 @@ CSS tokens: `--stuic-user-avatar-menu-trigger-{radius,opacity-hover,outline-colo
960
960
 
961
961
  Inline rounded badge/tag/chip with intent + variant + size system. Polymorphic: renders as `<span>` (default), `<a>` (when `href` set), or `<button>` (when `onclick` set).
962
962
 
963
- | Prop | Type | Default | Description |
964
- | --------------- | ------------------------------------------------------------------ | -------- | ---------------------------------------------------- |
965
- | `intent` | `"primary" \| "accent" \| "destructive" \| "warning" \| "success"` | - | Semantic color |
966
- | `variant` | `"solid" \| "outline" \| "ghost" \| "soft" \| "link"` | `"soft"` | Visual treatment |
967
- | `size` | `"sm" \| "md" \| "lg"` | `"md"` | Pill size |
968
- | `roundedFull` | `boolean` | `true` | Fully rounded (9999px). `false` → element radius |
969
- | `block` | `boolean` | `false` | Block-level flex (full width) |
970
- | `dot` | `boolean` | `false` | Status dot before content |
971
- | `dismissible` | `boolean` | `false` | Built-in X dismiss button |
972
- | `ondismiss` | `(e: MouseEvent) => void` | - | Called when X clicked (stops propagation) |
973
- | `active` | `boolean` | `false` | Selected state (filter-chip) |
974
- | `muted` | `boolean` | `false` | Lower opacity |
975
- | `href`, `target`| `string` | - | Render as `<a>` |
976
- | `onclick` | `(e: MouseEvent) => void` | - | Render as `<button>` |
977
- | `contentBefore` | `THC` | - | Content before children |
978
- | `contentAfter` | `THC` | - | Content after children |
963
+ | Prop | Type | Default | Description |
964
+ | ---------------- | ------------------------------------------------------------------ | -------- | ------------------------------------------------ |
965
+ | `intent` | `"primary" \| "accent" \| "destructive" \| "warning" \| "success"` | - | Semantic color |
966
+ | `variant` | `"solid" \| "outline" \| "ghost" \| "soft" \| "link"` | `"soft"` | Visual treatment |
967
+ | `size` | `"sm" \| "md" \| "lg"` | `"md"` | Pill size |
968
+ | `roundedFull` | `boolean` | `true` | Fully rounded (9999px). `false` → element radius |
969
+ | `block` | `boolean` | `false` | Block-level flex (full width) |
970
+ | `dot` | `boolean` | `false` | Status dot before content |
971
+ | `dismissible` | `boolean` | `false` | Built-in X dismiss button |
972
+ | `ondismiss` | `(e: MouseEvent) => void` | - | Called when X clicked (stops propagation) |
973
+ | `active` | `boolean` | `false` | Selected state (filter-chip) |
974
+ | `muted` | `boolean` | `false` | Lower opacity |
975
+ | `href`, `target` | `string` | - | Render as `<a>` |
976
+ | `onclick` | `(e: MouseEvent) => void` | - | Render as `<button>` |
977
+ | `contentBefore` | `THC` | - | Content before children |
978
+ | `contentAfter` | `THC` | - | Content after children |
979
979
 
980
980
  ```svelte
981
981
  <Pill intent="success" dot>Online</Pill>
@@ -998,39 +998,32 @@ Keyboard shortcut display.
998
998
 
999
999
  Image/content slider with scroll snap, keyboard navigation, wheel scroll, optional arrows, and active item tracking via IntersectionObserver.
1000
1000
 
1001
- | Prop | Type | Default | Description |
1002
- | ------------------- | ------------------------------------------------- | ----------- | -------------------------------------------------- |
1003
- | `items` | `CarouselItem[]` | required | Array of carousel items |
1004
- | `itemsPerView` | `number` | `1` | Number of items visible per view |
1005
- | `peekPercent` | `number` | `0` | Percentage of next item to show as peek (0-50) |
1006
- | `gap` | `number \| string` | `undefined` | Gap between items |
1007
- | `trackActive` | `boolean` | `false` | Enable active item tracking |
1008
- | `syncActiveOnScroll`| `boolean` | `false` | Sync active item based on scroll position |
1009
- | `activeIndex` | `number` | `0` | Currently active item index (bindable) |
1010
- | `value` | `string \| number` | `undefined` | Currently active item ID (bindable) |
1011
- | `snap` | `boolean` | `true` | Enable scroll snap behavior |
1012
- | `snapAlign` | `"start" \| "center" \| "end"` | `"start"` | Snap alignment |
1013
- | `keyboard` | `boolean` | `true` | Enable keyboard navigation (arrows, Home, End) |
1014
- | `loop` | `boolean` | `false` | Allow cycling from last to first and vice versa |
1015
- | `scrollBehavior` | `ScrollBehavior` | `"smooth"` | Scroll behavior for programmatic navigation |
1016
- | `scrollbar` | `boolean` | `true` | Show scrollbar on hover |
1017
- | `wheelScroll` | `boolean` | `true` | Enable horizontal scrolling via mouse wheel |
1018
- | `arrows` | `boolean` | `false` | Show prev/next arrow buttons |
1019
- | `minItemWidth` | `number` | `undefined` | Minimum item width (px) for auto-fit |
1020
- | `onActiveChange` | `(item: CarouselItem, index: number) => void` | — | Callback when active item changes |
1021
- | `renderItem` | `Snippet<[{ item, index, active }]>` | — | Custom render snippet for items |
1001
+ | Prop | Type | Default | Description |
1002
+ | -------------------- | --------------------------------------------- | ----------- | ----------------------------------------------- |
1003
+ | `items` | `CarouselItem[]` | required | Array of carousel items |
1004
+ | `itemsPerView` | `number` | `1` | Number of items visible per view |
1005
+ | `peekPercent` | `number` | `0` | Percentage of next item to show as peek (0-50) |
1006
+ | `gap` | `number \| string` | `undefined` | Gap between items |
1007
+ | `trackActive` | `boolean` | `false` | Enable active item tracking |
1008
+ | `syncActiveOnScroll` | `boolean` | `false` | Sync active item based on scroll position |
1009
+ | `activeIndex` | `number` | `0` | Currently active item index (bindable) |
1010
+ | `value` | `string \| number` | `undefined` | Currently active item ID (bindable) |
1011
+ | `snap` | `boolean` | `true` | Enable scroll snap behavior |
1012
+ | `snapAlign` | `"start" \| "center" \| "end"` | `"start"` | Snap alignment |
1013
+ | `keyboard` | `boolean` | `true` | Enable keyboard navigation (arrows, Home, End) |
1014
+ | `loop` | `boolean` | `false` | Allow cycling from last to first and vice versa |
1015
+ | `scrollBehavior` | `ScrollBehavior` | `"smooth"` | Scroll behavior for programmatic navigation |
1016
+ | `scrollbar` | `boolean` | `true` | Show scrollbar on hover |
1017
+ | `wheelScroll` | `boolean` | `true` | Enable horizontal scrolling via mouse wheel |
1018
+ | `arrows` | `boolean` | `false` | Show prev/next arrow buttons |
1019
+ | `minItemWidth` | `number` | `undefined` | Minimum item width (px) for auto-fit |
1020
+ | `onActiveChange` | `(item: CarouselItem, index: number) => void` | — | Callback when active item changes |
1021
+ | `renderItem` | `Snippet<[{ item, index, active }]>` | — | Custom render snippet for items |
1022
1022
 
1023
1023
  **Methods:** `goTo(index)`, `goToId(id)`, `next()`, `previous()`
1024
1024
 
1025
1025
  ```svelte
1026
- <Carousel
1027
- items={slides}
1028
- itemsPerView={3}
1029
- gap={16}
1030
- arrows
1031
- trackActive
1032
- syncActiveOnScroll
1033
- >
1026
+ <Carousel items={slides} itemsPerView={3} gap={16} arrows trackActive syncActiveOnScroll>
1034
1027
  {#snippet renderItem({ item, index, active })}
1035
1028
  <img src={item.data.src} alt={item.data.alt} />
1036
1029
  {/snippet}
@@ -1104,15 +1097,15 @@ Responsive data table with paging, row selection, batch actions, and mobile card
1104
1097
 
1105
1098
  Auto-cycling image carousel with fade transitions. Preloads next image before displaying. Supports custom title/description snippets.
1106
1099
 
1107
- | Prop | Type | Default | Description |
1108
- | -------------------- | ------------------- | --------- | ---------------------------------------- |
1109
- | `images` | `ImageCyclerImage[]`| required | Array of images to cycle through |
1110
- | `fit` | `ImageCyclerFit` | `"cover"` | CSS object-fit: `"cover"`, `"contain"`, `"fill"` |
1111
- | `minWait` | `number` | `3000` | Minimum wait (ms) before next image |
1112
- | `transitionDuration` | `number` | `500` | Fade transition duration (ms) |
1113
- | `onclick` | `(image, index) => void` | — | Click handler |
1114
- | `title` | `Snippet` | — | Custom title snippet `({ image, index, onclick })` |
1115
- | `description` | `Snippet` | — | Custom description snippet |
1100
+ | Prop | Type | Default | Description |
1101
+ | -------------------- | ------------------------ | --------- | -------------------------------------------------- |
1102
+ | `images` | `ImageCyclerImage[]` | required | Array of images to cycle through |
1103
+ | `fit` | `ImageCyclerFit` | `"cover"` | CSS object-fit: `"cover"`, `"contain"`, `"fill"` |
1104
+ | `minWait` | `number` | `3000` | Minimum wait (ms) before next image |
1105
+ | `transitionDuration` | `number` | `500` | Fade transition duration (ms) |
1106
+ | `onclick` | `(image, index) => void` | — | Click handler |
1107
+ | `title` | `Snippet` | — | Custom title snippet `({ image, index, onclick })` |
1108
+ | `description` | `Snippet` | — | Custom description snippet |
1116
1109
 
1117
1110
  ```ts
1118
1111
  interface ImageCyclerImage {
@@ -1136,23 +1129,23 @@ Theme color swatch preview.
1136
1129
 
1137
1130
  Interactive book/flipbook reader with 3D CSS page flip animation, zoom, pan, swipe, clickable areas, and responsive single-page mode.
1138
1131
 
1139
- | Prop | Type | Default | Description |
1140
- | ---------------- | ------------------------------------------------------------- | -------------- | --------------------------------------------- |
1141
- | `pages` | `BookPage[]` | required | Ordered array of book pages |
1142
- | `baseUrl` | `string` | `undefined` | Fallback base URL for relative page src |
1143
- | `activeSpread` | `number` | `0` | Currently active spread index (bindable) |
1144
- | `keyboard` | `boolean` | `true` | Enable keyboard navigation |
1145
- | `swipe` | `boolean` | `true` | Enable swipe gesture navigation |
1146
- | `duration` | `number` | `500` | Flip animation duration in ms |
1147
- | `zoom` | `boolean` | `true` | Enable zoom capability |
1148
- | `zoomLevels` | `readonly number[]` | `[1,1.5,2,3]` | Discrete zoom levels |
1149
- | `clampPan` | `boolean` | `false` | Clamp panning within bounds |
1150
- | `singlePage` | `boolean` | `false` | Force single-page layout |
1151
- | `responsive` | `boolean` | `true` | Auto-switch to single-page when narrow |
1152
- | `onSpreadChange` | `(spread: BookSpread, index: number) => void` | — | Callback when active spread changes |
1153
- | `onPageClick` | `(data: { page: BookPage; x: number; y: number }) => void` | — | Callback on page click (coordinates 0–1) |
1154
- | `onAreaClick` | `(data: { area: BookPageArea; page: BookPage }) => void` | — | Callback when clickable area is clicked |
1155
- | `renderPage` | `Snippet<[{ page, position }]>` | — | Custom page render snippet |
1132
+ | Prop | Type | Default | Description |
1133
+ | ---------------- | ---------------------------------------------------------- | ------------- | ---------------------------------------- |
1134
+ | `pages` | `BookPage[]` | required | Ordered array of book pages |
1135
+ | `baseUrl` | `string` | `undefined` | Fallback base URL for relative page src |
1136
+ | `activeSpread` | `number` | `0` | Currently active spread index (bindable) |
1137
+ | `keyboard` | `boolean` | `true` | Enable keyboard navigation |
1138
+ | `swipe` | `boolean` | `true` | Enable swipe gesture navigation |
1139
+ | `duration` | `number` | `500` | Flip animation duration in ms |
1140
+ | `zoom` | `boolean` | `true` | Enable zoom capability |
1141
+ | `zoomLevels` | `readonly number[]` | `[1,1.5,2,3]` | Discrete zoom levels |
1142
+ | `clampPan` | `boolean` | `false` | Clamp panning within bounds |
1143
+ | `singlePage` | `boolean` | `false` | Force single-page layout |
1144
+ | `responsive` | `boolean` | `true` | Auto-switch to single-page when narrow |
1145
+ | `onSpreadChange` | `(spread: BookSpread, index: number) => void` | — | Callback when active spread changes |
1146
+ | `onPageClick` | `(data: { page: BookPage; x: number; y: number }) => void` | — | Callback on page click (coordinates 0–1) |
1147
+ | `onAreaClick` | `(data: { area: BookPageArea; page: BookPage }) => void` | — | Callback when clickable area is clicked |
1148
+ | `renderPage` | `Snippet<[{ page, position }]>` | — | Custom page render snippet |
1156
1149
 
1157
1150
  **Exported helpers:** `buildSpreads(pages)`, `buildSinglePageSpreads(pages)`, `buildSheets(spreads)`, `computeBookPageSize(pages)`
1158
1151
 
@@ -1173,25 +1166,21 @@ Interactive book/flipbook reader with 3D CSS page flip animation, zoom, pan, swi
1173
1166
 
1174
1167
  Responsive wrapper around Book that intelligently switches between book mode (dual/single-page) and an inline asset preview mode based on container width. Inherits all Book props except `responsive` and `singlePage` (managed internally).
1175
1168
 
1176
- | Prop | Type | Default | Description |
1177
- | ----------------- | --------------------- | ----------- | ------------------------------------------------------- |
1178
- | `minPageWidth` | `number` | `150` | Min page width (px) before switching to single-page |
1179
- | `debounce` | `number` | `150` | Resize debounce delay in ms |
1180
- | `inlineThreshold` | `number` | `480` | Container width (px) below which switches to inline (0 = disabled) |
1181
- | `forceInline` | `boolean` | `false` | Force inline asset preview mode |
1182
- | `noPrevNext` | `boolean` | `false` | Hide prev/next arrow buttons |
1183
- | `classControls` | `string` | `undefined` | Custom class for prev/next buttons |
1184
- | `noModeSwitch` | `boolean` | `false` | Hide the book/inline toggle button |
1185
- | `initialMode` | `"book" \| "inline"` | `undefined` | Override auto-detection on mount |
1169
+ | Prop | Type | Default | Description |
1170
+ | ----------------- | -------------------- | ----------- | ------------------------------------------------------------------ |
1171
+ | `minPageWidth` | `number` | `150` | Min page width (px) before switching to single-page |
1172
+ | `debounce` | `number` | `150` | Resize debounce delay in ms |
1173
+ | `inlineThreshold` | `number` | `480` | Container width (px) below which switches to inline (0 = disabled) |
1174
+ | `forceInline` | `boolean` | `false` | Force inline asset preview mode |
1175
+ | `noPrevNext` | `boolean` | `false` | Hide prev/next arrow buttons |
1176
+ | `classControls` | `string` | `undefined` | Custom class for prev/next buttons |
1177
+ | `noModeSwitch` | `boolean` | `false` | Hide the book/inline toggle button |
1178
+ | `initialMode` | `"book" \| "inline"` | `undefined` | Override auto-detection on mount |
1186
1179
 
1187
1180
  **Exported utility:** `bookPagesToAssets(pages)` — Converts `BookPage[]` to `AssetPreview[]` for inline mode.
1188
1181
 
1189
1182
  ```svelte
1190
- <BookResponsive
1191
- pages={bookPages}
1192
- inlineThreshold={600}
1193
- onAreaClick={handleAreaClick}
1194
- />
1183
+ <BookResponsive pages={bookPages} inlineThreshold={600} onAreaClick={handleAreaClick} />
1195
1184
  ```
1196
1185
 
1197
1186
  #### `Circle`
@@ -1236,25 +1225,25 @@ Element that expands width on hover with delayed transitions and shadow effects.
1236
1225
 
1237
1226
  Modal-based asset/file preview gallery with zoom, pan, pinch-zoom, swipe navigation, clickable area overlays, and download controls. Opens in a full-screen ModalDialog.
1238
1227
 
1239
- | Prop | Type | Default | Description |
1240
- | ----------------- | ----------------------------------------------------------------- | ----------- | -------------------------------------------- |
1241
- | `assets` | `string[] \| AssetPreview[]` | required | Asset URLs or asset objects |
1242
- | `baseUrl` | `string` | `undefined` | Fallback base URL for relative asset URLs |
1243
- | `modalClassDialog`| `string` | `undefined` | CSS class for the modal dialog |
1244
- | `modalClass` | `string` | `undefined` | CSS class for the modal container |
1245
- | `classControls` | `string` | `undefined` | CSS class for control buttons |
1246
- | `t` | `TranslateFn` | built-in | Translation function |
1247
- | `onDelete` | `(asset: AssetPreview, index: number, { close }) => void` | — | Delete handler (shows delete button) |
1248
- | `onAreaClick` | `(data: { area: AssetArea; asset: AssetPreviewNormalized }) => void` | — | Callback for clickable area on image |
1249
- | `noName` | `boolean` | `false` | Hide file name display |
1250
- | `clampPan` | `boolean` | `true` | Clamp panning within image bounds |
1251
- | `noDownload` | `boolean` | `false` | Hide download button |
1252
- | `noPrevNext` | `boolean` | `false` | Hide prev/next arrows |
1253
- | `noZoom` | `boolean` | `false` | Disable all zooming |
1254
- | `noZoomButtons` | `boolean` | `false` | Hide zoom buttons (gestures still work) |
1255
- | `noDots` | `boolean` | `false` | Never show pagination dots |
1256
- | `noCurrentOfTotal`| `boolean` | `false` | Never show "x / y" counter |
1257
- | `prevNextBottom` | `boolean` | `false` | Render prev/next arrows at bottom |
1228
+ | Prop | Type | Default | Description |
1229
+ | ------------------ | -------------------------------------------------------------------- | ----------- | ----------------------------------------- |
1230
+ | `assets` | `string[] \| AssetPreview[]` | required | Asset URLs or asset objects |
1231
+ | `baseUrl` | `string` | `undefined` | Fallback base URL for relative asset URLs |
1232
+ | `modalClassDialog` | `string` | `undefined` | CSS class for the modal dialog |
1233
+ | `modalClass` | `string` | `undefined` | CSS class for the modal container |
1234
+ | `classControls` | `string` | `undefined` | CSS class for control buttons |
1235
+ | `t` | `TranslateFn` | built-in | Translation function |
1236
+ | `onDelete` | `(asset: AssetPreview, index: number, { close }) => void` | — | Delete handler (shows delete button) |
1237
+ | `onAreaClick` | `(data: { area: AssetArea; asset: AssetPreviewNormalized }) => void` | — | Callback for clickable area on image |
1238
+ | `noName` | `boolean` | `false` | Hide file name display |
1239
+ | `clampPan` | `boolean` | `true` | Clamp panning within image bounds |
1240
+ | `noDownload` | `boolean` | `false` | Hide download button |
1241
+ | `noPrevNext` | `boolean` | `false` | Hide prev/next arrows |
1242
+ | `noZoom` | `boolean` | `false` | Disable all zooming |
1243
+ | `noZoomButtons` | `boolean` | `false` | Hide zoom buttons (gestures still work) |
1244
+ | `noDots` | `boolean` | `false` | Never show pagination dots |
1245
+ | `noCurrentOfTotal` | `boolean` | `false` | Never show "x / y" counter |
1246
+ | `prevNextBottom` | `boolean` | `false` | Render prev/next arrows at bottom |
1258
1247
 
1259
1248
  **Methods:** `open(index?)`, `close()`
1260
1249
 
@@ -1265,10 +1254,17 @@ Modal-based asset/file preview gallery with zoom, pan, pinch-zoom, swipe navigat
1265
1254
  ```svelte
1266
1255
  <AssetsPreview
1267
1256
  assets={[
1268
- { url: { full: "/photo.jpg", thumb: "/photo-thumb.jpg" }, name: "Photo", type: "image/jpeg" },
1257
+ {
1258
+ url: { full: "/photo.jpg", thumb: "/photo-thumb.jpg" },
1259
+ name: "Photo",
1260
+ type: "image/jpeg",
1261
+ },
1269
1262
  "/document.pdf",
1270
1263
  ]}
1271
- onDelete={(asset, i, { close }) => { deleteAsset(i); close(); }}
1264
+ onDelete={(asset, i, { close }) => {
1265
+ deleteAsset(i);
1266
+ close();
1267
+ }}
1272
1268
  />
1273
1269
  ```
1274
1270
 
@@ -1276,34 +1272,31 @@ Modal-based asset/file preview gallery with zoom, pan, pinch-zoom, swipe navigat
1276
1272
 
1277
1273
  Always-visible (non-modal) variant of AssetsPreview with the same zoom, pan, swipe, and area clicking features. For embedding asset galleries directly in layouts.
1278
1274
 
1279
- | Prop | Type | Default | Description |
1280
- | ----------------- | ----------------------------------------------------------------- | ----------- | -------------------------------------------- |
1281
- | `assets` | `string[] \| AssetPreview[]` | required | Asset URLs or asset objects |
1282
- | `baseUrl` | `string` | `undefined` | Fallback base URL for relative asset URLs |
1283
- | `initialIndex` | `number` | `0` | Starting asset index |
1284
- | `currentIndex` | `number` | `0` | Current display index (bindable) |
1285
- | `class` | `string` | `undefined` | Container CSS class |
1286
- | `classControls` | `string` | `undefined` | CSS class for control buttons |
1287
- | `t` | `TranslateFn` | built-in | Translation function |
1288
- | `onDelete` | `(asset, index, { close }) => void` | — | Delete handler |
1289
- | `onAreaClick` | `(data: { area: AssetArea; asset: AssetPreviewNormalized }) => void` | — | Callback for clickable area on image |
1290
- | `noName` | `boolean` | `false` | Hide file name display |
1291
- | `clampPan` | `boolean` | `true` | Clamp panning within bounds |
1292
- | `noDownload` | `boolean` | `false` | Hide download button |
1293
- | `noPrevNext` | `boolean` | `false` | Hide prev/next arrows |
1294
- | `noZoom` | `boolean` | `false` | Disable all zooming |
1295
- | `noZoomButtons` | `boolean` | `false` | Hide zoom buttons (gestures still work) |
1296
- | `noDots` | `boolean` | `false` | Never show pagination dots |
1297
- | `noCurrentOfTotal`| `boolean` | `false` | Never show "x / y" counter |
1298
- | `prevNextBottom` | `boolean` | `false` | Render prev/next arrows at bottom |
1275
+ | Prop | Type | Default | Description |
1276
+ | ------------------ | -------------------------------------------------------------------- | ----------- | ----------------------------------------- |
1277
+ | `assets` | `string[] \| AssetPreview[]` | required | Asset URLs or asset objects |
1278
+ | `baseUrl` | `string` | `undefined` | Fallback base URL for relative asset URLs |
1279
+ | `initialIndex` | `number` | `0` | Starting asset index |
1280
+ | `currentIndex` | `number` | `0` | Current display index (bindable) |
1281
+ | `class` | `string` | `undefined` | Container CSS class |
1282
+ | `classControls` | `string` | `undefined` | CSS class for control buttons |
1283
+ | `t` | `TranslateFn` | built-in | Translation function |
1284
+ | `onDelete` | `(asset, index, { close }) => void` | — | Delete handler |
1285
+ | `onAreaClick` | `(data: { area: AssetArea; asset: AssetPreviewNormalized }) => void` | — | Callback for clickable area on image |
1286
+ | `noName` | `boolean` | `false` | Hide file name display |
1287
+ | `clampPan` | `boolean` | `true` | Clamp panning within bounds |
1288
+ | `noDownload` | `boolean` | `false` | Hide download button |
1289
+ | `noPrevNext` | `boolean` | `false` | Hide prev/next arrows |
1290
+ | `noZoom` | `boolean` | `false` | Disable all zooming |
1291
+ | `noZoomButtons` | `boolean` | `false` | Hide zoom buttons (gestures still work) |
1292
+ | `noDots` | `boolean` | `false` | Never show pagination dots |
1293
+ | `noCurrentOfTotal` | `boolean` | `false` | Never show "x / y" counter |
1294
+ | `prevNextBottom` | `boolean` | `false` | Render prev/next arrows at bottom |
1299
1295
 
1300
1296
  **Methods:** `goTo(index)`, `next()`, `previous()`
1301
1297
 
1302
1298
  ```svelte
1303
- <AssetsPreviewInline
1304
- assets={imageUrls}
1305
- bind:currentIndex
1306
- />
1299
+ <AssetsPreviewInline assets={imageUrls} bind:currentIndex />
1307
1300
  ```
1308
1301
 
1309
1302
  #### `Card`
@@ -1347,24 +1340,24 @@ CSS tokens: `--stuic-card-bg`, `--stuic-card-bg-hover`, `--stuic-card-border`, `
1347
1340
 
1348
1341
  Accessible, keyboard-navigable hierarchical tree view with optional drag-and-drop reordering, expand/collapse, and localStorage persistence.
1349
1342
 
1350
- | Prop | Type | Default | Description |
1351
- | ----------------- | ---------------------------------------- | ------------ | ------------------------------------ |
1352
- | `items` | `TreeNodeDTO<T>[]` | required | Tree data |
1353
- | `renderItem` | `Snippet<[item, depth, isExpanded]>` | — | Custom item content |
1354
- | `renderIcon` | `Snippet<[item, depth, isExpanded]>` | — | Custom item icon |
1355
- | `activeId` | `string` | — | Selected item ID |
1356
- | `isActive` | `(item) => boolean` | — | Custom active check |
1357
- | `onSelect` | `(item) => void` | — | Item selection callback |
1358
- | `onToggle` | `(item, expanded) => void` | — | Branch toggle callback |
1359
- | `sort` | `(a, b) => number` | — | Sort comparator (per-level) |
1360
- | `defaultExpanded` | `boolean` | `false` | Default expand state |
1361
- | `expandedIds` | `Set<string>` | — | Initially expanded IDs |
1362
- | `persistState` | `boolean` | `false` | Save expand state to localStorage |
1363
- | `draggable` | `boolean` | `false` | Enable drag-and-drop |
1364
- | `isDraggable` | `(item) => boolean` | — | Per-item drag control |
1365
- | `isDropTarget` | `(item) => boolean` | — | Per-item drop target control |
1366
- | `onMove` | `(event: TreeMoveEvent) => void \| false`| | Drop handler; return false to reject |
1367
- | `dragExpandDelay` | `number` | `800` | Auto-expand delay (ms) on drag hover |
1343
+ | Prop | Type | Default | Description |
1344
+ | ----------------- | ----------------------------------------- | -------- | ------------------------------------ |
1345
+ | `items` | `TreeNodeDTO<T>[]` | required | Tree data |
1346
+ | `renderItem` | `Snippet<[item, depth, isExpanded]>` | — | Custom item content |
1347
+ | `renderIcon` | `Snippet<[item, depth, isExpanded]>` | — | Custom item icon |
1348
+ | `activeId` | `string` | — | Selected item ID |
1349
+ | `isActive` | `(item) => boolean` | — | Custom active check |
1350
+ | `onSelect` | `(item) => void` | — | Item selection callback |
1351
+ | `onToggle` | `(item, expanded) => void` | — | Branch toggle callback |
1352
+ | `sort` | `(a, b) => number` | — | Sort comparator (per-level) |
1353
+ | `defaultExpanded` | `boolean` | `false` | Default expand state |
1354
+ | `expandedIds` | `Set<string>` | — | Initially expanded IDs |
1355
+ | `persistState` | `boolean` | `false` | Save expand state to localStorage |
1356
+ | `draggable` | `boolean` | `false` | Enable drag-and-drop |
1357
+ | `isDraggable` | `(item) => boolean` | — | Per-item drag control |
1358
+ | `isDropTarget` | `(item) => boolean` | — | Per-item drop target control |
1359
+ | `onMove` | `(event: TreeMoveEvent) => void \| false` | | Drop handler; return false to reject |
1360
+ | `dragExpandDelay` | `number` | `800` | Auto-expand delay (ms) on drag hover |
1368
1361
 
1369
1362
  ```svelte
1370
1363
  <Tree
@@ -1528,24 +1521,24 @@ Spotlight/coach mark overlay that highlights a target element by dimming everyth
1528
1521
 
1529
1522
  **Options:**
1530
1523
 
1531
- | Option | Type | Default | Description |
1532
- | ---------------------- | ------------------- | ----------- | ---------------------------------------------------------------- |
1533
- | `enabled` | `boolean` | `true` | Whether the spotlight is enabled |
1534
- | `content` | `THC \| null` | `undefined` | Annotation content (string, {html}, {component, props}, snippet) |
1535
- | `position` | `SpotlightPosition` | `"bottom"` | Annotation placement relative to target |
1536
- | `padding` | `number` | `8` | Padding around target in the cutout (px) |
1537
- | `borderRadius` | `number` | `8` | Border radius of the cutout hole (px) |
1538
- | `class` | `string` | `undefined` | Custom class for annotation |
1539
- | `classBackdrop` | `string` | `undefined` | Custom class for backdrop |
1540
- | `offset` | `string` | `"0.5rem"` | Annotation offset from target (CSS value) |
1541
- | `closeOnEscape` | `boolean` | `true` | Close on Escape key |
1542
- | `closeOnBackdropClick` | `boolean` | `true` | Close on backdrop click |
1543
- | `scrollIntoView` | `boolean` | `true` | Scroll target into view before showing |
1544
- | `open` | `boolean` | `undefined` | Reactive programmatic control |
1545
- | `id` | `string` | `undefined` | ID for registry-based control |
1524
+ | Option | Type | Default | Description |
1525
+ | ---------------------- | ------------------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
1526
+ | `enabled` | `boolean` | `true` | Whether the spotlight is enabled |
1527
+ | `content` | `THC \| null` | `undefined` | Annotation content (string, {html}, {component, props}, snippet) |
1528
+ | `position` | `SpotlightPosition` | `"bottom"` | Annotation placement relative to target |
1529
+ | `padding` | `number` | `8` | Padding around target in the cutout (px) |
1530
+ | `borderRadius` | `number` | `8` | Border radius of the cutout hole (px) |
1531
+ | `class` | `string` | `undefined` | Custom class for annotation |
1532
+ | `classBackdrop` | `string` | `undefined` | Custom class for backdrop |
1533
+ | `offset` | `string` | `"0.5rem"` | Annotation offset from target (CSS value) |
1534
+ | `closeOnEscape` | `boolean` | `true` | Close on Escape key |
1535
+ | `closeOnBackdropClick` | `boolean` | `true` | Close on backdrop click |
1536
+ | `scrollIntoView` | `boolean` | `true` | Scroll target into view before showing |
1537
+ | `open` | `boolean` | `undefined` | Reactive programmatic control |
1538
+ | `id` | `string` | `undefined` | ID for registry-based control |
1546
1539
  | `autoTrack` | `boolean` | `true` | Per-frame rAF compare-loop that keeps the spotlight glued to its target through layout shifts caused by sibling/ancestor movement (not just resize/scroll). Set to `false` to opt out. |
1547
- | `onShow` | `() => void` | `undefined` | Callback when spotlight opens |
1548
- | `onHide` | `() => void` | `undefined` | Callback when spotlight hides |
1540
+ | `onShow` | `() => void` | `undefined` | Callback when spotlight opens |
1541
+ | `onHide` | `() => void` | `undefined` | Callback when spotlight hides |
1549
1542
 
1550
1543
  **Registry functions:**
1551
1544
 
@@ -1600,20 +1593,20 @@ Multi-step onboarding tour built on the spotlight primitive. Define steps centra
1600
1593
 
1601
1594
  **`createTour(options)`**
1602
1595
 
1603
- | Option | Type | Default | Description |
1604
- | ----------------- | ----------------------------- | --------- | ---------------------------------------------------- |
1605
- | `steps` | `TourStepDef[]` | required | Tour step definitions |
1606
- | `waitForElement` | `number` | `500` | Max wait (ms) for step element to appear |
1607
- | `labels` | `TourLabels` | defaults | Default button labels (Next, Back, Skip, Finish) |
1608
- | `shell` | `Snippet<[TourShellContext]>` | — | Custom shell snippet replacing default UI |
1609
- | `closeOnEscape` | `boolean` | `true` | Press Escape to skip |
1610
- | `confirmSkip` | `() => boolean \| Promise<boolean>` | — | Guard before skipping (return `false` to cancel) |
1611
- | `storageKey` | `string` | — | Persist tour completion (skips on re-run) |
1612
- | `storage` | `"local" \| "session"` | `"local"` | Storage backend for persistence |
1613
- | `onStart` | `() => void` | — | Called when tour starts |
1614
- | `onEnd` | `() => void` | — | Called when tour completes |
1615
- | `onSkip` | `() => void` | — | Called when tour is skipped |
1616
- | `onStepChange` | `(step, index) => void` | — | Called on every step change |
1596
+ | Option | Type | Default | Description |
1597
+ | ---------------- | ----------------------------------- | --------- | ------------------------------------------------ |
1598
+ | `steps` | `TourStepDef[]` | required | Tour step definitions |
1599
+ | `waitForElement` | `number` | `500` | Max wait (ms) for step element to appear |
1600
+ | `labels` | `TourLabels` | defaults | Default button labels (Next, Back, Skip, Finish) |
1601
+ | `shell` | `Snippet<[TourShellContext]>` | — | Custom shell snippet replacing default UI |
1602
+ | `closeOnEscape` | `boolean` | `true` | Press Escape to skip |
1603
+ | `confirmSkip` | `() => boolean \| Promise<boolean>` | — | Guard before skipping (return `false` to cancel) |
1604
+ | `storageKey` | `string` | — | Persist tour completion (skips on re-run) |
1605
+ | `storage` | `"local" \| "session"` | `"local"` | Storage backend for persistence |
1606
+ | `onStart` | `() => void` | — | Called when tour starts |
1607
+ | `onEnd` | `() => void` | — | Called when tour completes |
1608
+ | `onSkip` | `() => void` | — | Called when tour is skipped |
1609
+ | `onStepChange` | `(step, index) => void` | — | Called on every step change |
1617
1610
 
1618
1611
  **Returns:** `{ start(), stop(), next(), prev(), skip(), reset(), reposition(), active, currentStep, currentIndex }`
1619
1612
 
@@ -1621,17 +1614,17 @@ Multi-step onboarding tour built on the spotlight primitive. Define steps centra
1621
1614
 
1622
1615
  **`TourStepDef`:**
1623
1616
 
1624
- | Field | Type | Description |
1625
- | ------------- | ------------------- | ----------------------------------------- |
1626
- | `id` | `string` | Unique ID (must match `use:tourStep`) |
1627
- | `title` | `string` | Step title |
1628
- | `content` | `THC` | Step description (string/html/component) |
1629
- | `position` | `SpotlightPosition` | Annotation placement |
1630
- | `padding` | `number` | Cutout padding (px) |
1631
- | `borderRadius`| `number` | Cutout border radius (px) |
1632
- | `onEnter` | `() => void` | Called when entering step |
1633
- | `onLeave` | `() => void` | Called when leaving step |
1634
- | `selector` | `string` | CSS selector to find the target element (alternative to `use:tourStep`) |
1617
+ | Field | Type | Description |
1618
+ | -------------- | ------------------- | ----------------------------------------------------------------------- |
1619
+ | `id` | `string` | Unique ID (must match `use:tourStep`) |
1620
+ | `title` | `string` | Step title |
1621
+ | `content` | `THC` | Step description (string/html/component) |
1622
+ | `position` | `SpotlightPosition` | Annotation placement |
1623
+ | `padding` | `number` | Cutout padding (px) |
1624
+ | `borderRadius` | `number` | Cutout border radius (px) |
1625
+ | `onEnter` | `() => void` | Called when entering step |
1626
+ | `onLeave` | `() => void` | Called when leaving step |
1627
+ | `selector` | `string` | CSS selector to find the target element (alternative to `use:tourStep`) |
1635
1628
 
1636
1629
  **`tourStep` action:** `use:tourStep={[tour, stepId]}`
1637
1630
 
@@ -1657,9 +1650,6 @@ Multi-step onboarding tour built on the spotlight primitive. Define steps centra
1657
1650
  **Selector-based targeting:** Steps can target elements by CSS selector instead of `use:tourStep`. Useful when the target lives inside a reusable component that shouldn't know about the tour:
1658
1651
 
1659
1652
  ```svelte
1660
- <!-- ReusableComponent.svelte — no tour knowledge -->
1661
- <button data-tour-id="download">Download</button>
1662
-
1663
1653
  <!-- Tour config -->
1664
1654
  <script>
1665
1655
  const tour = createTour({
@@ -1673,6 +1663,9 @@ Multi-step onboarding tour built on the spotlight primitive. Define steps centra
1673
1663
  ],
1674
1664
  });
1675
1665
  </script>
1666
+
1667
+ <!-- ReusableComponent.svelte — no tour knowledge -->
1668
+ <button data-tour-id="download">Download</button>
1676
1669
  ```
1677
1670
 
1678
1671
  When a step has `selector`, the tour uses `document.querySelector(selector)` to find the target element. If the element isn't in the DOM yet, the tour polls periodically until `waitForElement` ms elapse (same timeout as `use:tourStep`). Steps without `selector` continue to use `use:tourStep` as before — both mechanisms coexist freely.