@marianmeres/stuic 3.167.0 → 3.168.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 (103) hide show
  1. package/AGENTS.md +6 -6
  2. package/dist/attachments/index.d.ts +1 -0
  3. package/dist/attachments/index.js +1 -0
  4. package/dist/attachments/long-press.d.ts +43 -0
  5. package/dist/attachments/long-press.js +107 -0
  6. package/dist/components/Breadcrumbs/Breadcrumbs.svelte +198 -0
  7. package/dist/components/Breadcrumbs/Breadcrumbs.svelte.d.ts +60 -0
  8. package/dist/components/Breadcrumbs/README.md +174 -0
  9. package/dist/components/Breadcrumbs/i18n-sk.d.ts +17 -0
  10. package/dist/components/Breadcrumbs/i18n-sk.js +19 -0
  11. package/dist/components/Breadcrumbs/i18n.d.ts +31 -0
  12. package/dist/components/Breadcrumbs/i18n.js +40 -0
  13. package/dist/components/Breadcrumbs/index.css +84 -0
  14. package/dist/components/Breadcrumbs/index.d.ts +4 -0
  15. package/dist/components/Breadcrumbs/index.js +4 -0
  16. package/dist/components/Breadcrumbs/json-ld.d.ts +58 -0
  17. package/dist/components/Breadcrumbs/json-ld.js +56 -0
  18. package/dist/components/Collapsible/Collapsible.svelte +84 -15
  19. package/dist/components/Collapsible/Collapsible.svelte.d.ts +29 -2
  20. package/dist/components/Collapsible/README.md +82 -23
  21. package/dist/components/Collapsible/index.css +38 -0
  22. package/dist/components/Collapsible/index.d.ts +1 -1
  23. package/dist/components/ContextMenu/ContextMenu.svelte +302 -0
  24. package/dist/components/ContextMenu/ContextMenu.svelte.d.ts +94 -0
  25. package/dist/components/ContextMenu/README.md +159 -0
  26. package/dist/components/ContextMenu/i18n-sk.d.ts +17 -0
  27. package/dist/components/ContextMenu/i18n-sk.js +18 -0
  28. package/dist/components/ContextMenu/i18n.d.ts +30 -0
  29. package/dist/components/ContextMenu/i18n.js +38 -0
  30. package/dist/components/ContextMenu/index.css +26 -0
  31. package/dist/components/ContextMenu/index.d.ts +3 -0
  32. package/dist/components/ContextMenu/index.js +3 -0
  33. package/dist/components/CopyButton/CopyButton.svelte +278 -0
  34. package/dist/components/CopyButton/CopyButton.svelte.d.ts +76 -0
  35. package/dist/components/CopyButton/README.md +241 -0
  36. package/dist/components/CopyButton/i18n-sk.d.ts +17 -0
  37. package/dist/components/CopyButton/i18n-sk.js +20 -0
  38. package/dist/components/CopyButton/i18n.d.ts +35 -0
  39. package/dist/components/CopyButton/i18n.js +43 -0
  40. package/dist/components/CopyButton/index.css +67 -0
  41. package/dist/components/CopyButton/index.d.ts +3 -0
  42. package/dist/components/CopyButton/index.js +3 -0
  43. package/dist/components/DataTable/DataTable.svelte +41 -34
  44. package/dist/components/DataTable/README.md +45 -0
  45. package/dist/components/DataTable/i18n-sk.js +1 -0
  46. package/dist/components/DataTable/i18n.d.ts +1 -0
  47. package/dist/components/DataTable/i18n.js +3 -0
  48. package/dist/components/DataTable/index.css +41 -3
  49. package/dist/components/EmptyState/EmptyState.svelte +121 -0
  50. package/dist/components/EmptyState/EmptyState.svelte.d.ts +40 -0
  51. package/dist/components/EmptyState/README.md +188 -0
  52. package/dist/components/EmptyState/index.css +154 -0
  53. package/dist/components/EmptyState/index.d.ts +1 -0
  54. package/dist/components/EmptyState/index.js +1 -0
  55. package/dist/components/Pagination/Pagination.svelte +250 -0
  56. package/dist/components/Pagination/Pagination.svelte.d.ts +69 -0
  57. package/dist/components/Pagination/README.md +152 -0
  58. package/dist/components/Pagination/i18n-sk.d.ts +17 -0
  59. package/dist/components/Pagination/i18n-sk.js +24 -0
  60. package/dist/components/Pagination/i18n.d.ts +41 -0
  61. package/dist/components/Pagination/i18n.js +49 -0
  62. package/dist/components/Pagination/index.css +50 -0
  63. package/dist/components/Pagination/index.d.ts +4 -0
  64. package/dist/components/Pagination/index.js +4 -0
  65. package/dist/components/Pagination/pagination-range.d.ts +21 -0
  66. package/dist/components/Pagination/pagination-range.js +41 -0
  67. package/dist/components/Stat/README.md +157 -0
  68. package/dist/components/Stat/Stat.svelte +226 -0
  69. package/dist/components/Stat/Stat.svelte.d.ts +54 -0
  70. package/dist/components/Stat/index.css +217 -0
  71. package/dist/components/Stat/index.d.ts +1 -0
  72. package/dist/components/Stat/index.js +1 -0
  73. package/dist/components/Stepper/README.md +181 -0
  74. package/dist/components/Stepper/Stepper.svelte +240 -0
  75. package/dist/components/Stepper/Stepper.svelte.d.ts +86 -0
  76. package/dist/components/Stepper/i18n-sk.d.ts +17 -0
  77. package/dist/components/Stepper/i18n-sk.js +21 -0
  78. package/dist/components/Stepper/i18n.d.ts +35 -0
  79. package/dist/components/Stepper/i18n.js +43 -0
  80. package/dist/components/Stepper/index.css +302 -0
  81. package/dist/components/Stepper/index.d.ts +3 -0
  82. package/dist/components/Stepper/index.js +3 -0
  83. package/dist/components/TrendChart/README.md +123 -0
  84. package/dist/components/TrendChart/TrendChart.svelte +114 -0
  85. package/dist/components/TrendChart/TrendChart.svelte.d.ts +36 -0
  86. package/dist/components/TrendChart/index.css +51 -0
  87. package/dist/components/TrendChart/index.d.ts +1 -0
  88. package/dist/components/TrendChart/index.js +1 -0
  89. package/dist/icons/index.d.ts +4 -0
  90. package/dist/icons/index.js +4 -0
  91. package/dist/index.css +7 -0
  92. package/dist/index.d.ts +7 -0
  93. package/dist/index.js +12 -0
  94. package/dist/utils/copy-to-clipboard.d.ts +43 -0
  95. package/dist/utils/copy-to-clipboard.js +102 -0
  96. package/dist/utils/index.d.ts +1 -0
  97. package/dist/utils/index.js +1 -0
  98. package/docs/architecture.md +1 -1
  99. package/docs/domains/attachments.md +41 -4
  100. package/docs/domains/components.md +280 -13
  101. package/docs/domains/utils.md +8 -6
  102. package/docs/maybe-todo.md +111 -0
  103. package/package.json +11 -1
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## Overview
4
4
 
5
- 64 Svelte 5 component directories with consistent API patterns. All use runes-based reactivity.
5
+ 73 Svelte 5 component directories with consistent API patterns. All use runes-based reactivity.
6
6
 
7
7
  ## Component Categories
8
8
 
@@ -20,22 +20,27 @@
20
20
  | SlidingPanels | Panel transitions |
21
21
  | TabbedMenu | Tab navigation |
22
22
  | Nav | Navigation wrapper |
23
+ | Breadcrumbs | Breadcrumb trail (collapse + JSON-LD helpers) |
23
24
  | WithSidePanel | Two-column layout with collapsible/resizable panel |
24
25
 
25
26
  ### Interactive
26
27
 
27
- | Component | Purpose |
28
- | -------------------- | ------------------------------------------- |
29
- | Button | Actions with intent/variant/size |
30
- | ButtonGroupRadio | Toggle group (single selection) |
31
- | Switch | Boolean toggle |
32
- | Slider | Fancy range input (fill + optional thumb) |
33
- | TwCheck | Styled checkbox/radio |
34
- | DropdownMenu | Popover menu |
35
- | CommandMenu | Command palette (keyboard-driven) |
36
- | TypeaheadInput | Autocomplete input |
37
- | ColorScheme | Dark/light mode management with persistence |
38
- | HoverExpandableWidth | Width-expanding container on hover |
28
+ | Component | Purpose |
29
+ | -------------------- | ----------------------------------------------------------------------------------------- |
30
+ | Button | Actions with intent/variant/size |
31
+ | CopyButton | Click-to-copy Button with copied/error feedback; `copyToClipboard()` util for code |
32
+ | ButtonGroupRadio | Toggle group (single selection) |
33
+ | Switch | Boolean toggle |
34
+ | Slider | Fancy range input (fill + optional thumb) |
35
+ | TwCheck | Styled checkbox/radio |
36
+ | DropdownMenu | Popover menu |
37
+ | ContextMenu | Right-click / long-press menu at the cursor (the DropdownMenu engine + trigger semantics) |
38
+ | CommandMenu | Command palette (keyboard-driven) |
39
+ | Pagination | Standalone pager: compact prev/next or windowed page numbers; DataTable-compatible |
40
+ | Stepper | Numbered step indicator for wizard/checkout flows; optional click navigation |
41
+ | TypeaheadInput | Autocomplete input |
42
+ | ColorScheme | Dark/light mode management with persistence |
43
+ | HoverExpandableWidth | Width-expanding container on hover |
39
44
 
40
45
  ### Feedback
41
46
 
@@ -83,6 +88,7 @@
83
88
  | AnimatedElipsis | Loading dots animation |
84
89
  | IconSwap | N-state visibility swap with opacity transitions (e.g. hamburger/X) |
85
90
  | DataTable | Responsive data table with paging, selection, batch actions |
91
+ | EmptyState | Icon + title + description + CTA placeholder for empty lists/tables/search results |
86
92
  | ThemePreview | Theme color swatches |
87
93
  | AssetsPreview | Modal-based asset/file preview with zoom, pan, swipe, area clicking |
88
94
  | AssetsPreviewInline | Always-visible (non-modal) asset preview with same feature set |
@@ -93,6 +99,8 @@
93
99
  | Separator | Horizontal/vertical separator line |
94
100
  | Thc | Flexible renderer for text, HTML, components, or snippets |
95
101
  | Card | Flexible card with image, title, footer; vertical/horizontal layout |
102
+ | Stat | KPI/stat card: label + value + delta with trend arrow and semantic coloring |
103
+ | TrendChart | Svelte wrapper for `@marianmeres/trend-chart` (subpath-only: `@marianmeres/stuic/trend-chart`) |
96
104
  | Tree | Hierarchical tree view with keyboard nav and drag-and-drop |
97
105
  | X | Styled close/multiply SVG icon |
98
106
  | ImageCycler | Auto-cycling image carousel with fade transitions and preloading |
@@ -788,6 +796,48 @@ Components use private CSS vars (`--_*`) set by intent/variant:
788
796
 
789
797
  ---
790
798
 
799
+ ## Breadcrumbs
800
+
801
+ Breadcrumb navigation trail — `<nav aria-label>` + ordered list (the WAI-ARIA APG pattern) with the last crumb marked `aria-current="page"`. Long trails optionally collapse their middle into an expandable ellipsis button (`maxItems` + `itemsBeforeCollapse`/`itemsAfterCollapse`; a new `items` array re-collapses). Ships schema.org `BreadcrumbList` JSON-LD helpers for SEO — usable standalone in `<svelte:head>` or rendered inline by the component via the `jsonLd` prop.
802
+
803
+ ### Exports
804
+
805
+ | Export | Kind | Description |
806
+ | -------------------------- | --------- | ----------------------------------------------------------------- |
807
+ | `Breadcrumbs` | component | Main component |
808
+ | `BreadcrumbsProps` | type | Props type |
809
+ | `BreadcrumbItem` | type | `{ label: string; href?: string }` |
810
+ | `breadcrumbsJsonLd` | function | Builds the schema.org `BreadcrumbList` object |
811
+ | `breadcrumbsJsonLdScript` | function | Full `<script type="application/ld+json">` string, `{@html}`-safe |
812
+ | `BreadcrumbsJsonLdOptions` | type | `{ baseUrl? }` — resolves relative hrefs to absolute URLs |
813
+ | `BreadcrumbListJsonLd` | type | The JSON-LD output shape (+ `BreadcrumbListItemJsonLd`) |
814
+ | `createBreadcrumbsT` | function | Builds the `t` prop from a (partial) message catalog |
815
+ | `BREADCRUMBS_MESSAGES_EN` | constant | Built-in English catalog (also the fallback) |
816
+ | `BREADCRUMBS_MESSAGES_SK` | constant | Bundled Slovak catalog (opt-in) |
817
+ | `BreadcrumbsMessageKey` | type | Message key union |
818
+ | `BreadcrumbsMessages` | type | One locale's catalog |
819
+
820
+ ### Key Props
821
+
822
+ | Prop | Type | Default | Description |
823
+ | ------------------------------------------ | ------------------------ | ------- | ----------------------------------------------------- |
824
+ | `items` | `BreadcrumbItem[]` | — | The trail, first-to-current; last item = current page |
825
+ | `separator` | `string` | `"/"` | Separator text (or the `renderSeparator` snippet) |
826
+ | `maxItems` | `number` | `0` | Collapse when longer than this; `0` never collapses |
827
+ | `itemsBeforeCollapse`/`itemsAfterCollapse` | `number` | `1`/`1` | Crumbs kept visible around the ellipsis |
828
+ | `jsonLd` | `boolean \| { baseUrl }` | `false` | Render `BreadcrumbList` JSON-LD along with the trail |
829
+ | `t` | `TranslateFn` | English | i18n (`createBreadcrumbsT`) |
830
+
831
+ Snippets: `renderItem` (`(item, index, isLast)`), `renderSeparator`. Class slots: `class`, `classItem`, `classLink`, `classCurrent`, `classSeparator`. Data attributes: `data-current` on the current `<li>`.
832
+
833
+ ### CSS Tokens
834
+
835
+ Prefix: `--stuic-breadcrumbs-*`
836
+
837
+ `gap`, `font-size`, `text`, `text-hover`, `text-current`, `font-weight-current`, `separator-text`, `transition` (falls back to `--stuic-transition`)
838
+
839
+ ---
840
+
791
841
  ## Card
792
842
 
793
843
  Flexible, responsive card for displaying content in a contained box. Supports images (top or side), titles, descriptions, footers, and interactive states.
@@ -824,6 +874,223 @@ Prefix: `--stuic-card-*`
824
874
 
825
875
  ---
826
876
 
877
+ ## ContextMenu
878
+
879
+ Right-click / long-press triggered menu positioned at the pointer. Wraps content into a context target area: `contextmenu` (right-click), long-press (touch/pen, via the `longPress` attachment), or Shift+F10 / the menu key open the menu anchored at the interaction point (an invisible 0×0 fixed anchor the underlying DropdownMenu positions against). The menu panel **is** a `DropdownMenu` — item model, keyboard navigation, search, overflow handling, and theming (`--stuic-dropdown-menu-*`) all come from there.
880
+
881
+ ### Exports
882
+
883
+ | Export | Kind | Description |
884
+ | -------------------------- | --------- | ---------------------------------------------------- |
885
+ | `ContextMenu` | component | Main component |
886
+ | `ContextMenuProps` | type | Props type |
887
+ | `ContextMenuItem` | type | Alias of `DropdownMenuItem` (full item model) |
888
+ | `ContextMenuActionItem` | type | Alias of `DropdownMenuActionItem` |
889
+ | `ContextMenuPosition` | type | Alias of `DropdownMenuPosition` |
890
+ | `ContextMenuSearchConfig` | type | Alias of `DropdownMenuSearchConfig` |
891
+ | `createContextMenuT` | function | Builds the `t` prop from a (partial) message catalog |
892
+ | `CONTEXT_MENU_MESSAGES_EN` | constant | Built-in English catalog (also the fallback) |
893
+ | `CONTEXT_MENU_MESSAGES_SK` | constant | Bundled Slovak catalog (opt-in) |
894
+ | `ContextMenuMessageKey` | type | Message key union |
895
+ | `ContextMenuMessages` | type | One locale's catalog |
896
+
897
+ ### Key Props
898
+
899
+ | Prop | Type | Default | Description |
900
+ | ----------- | --------------------- | --------------------- | --------------------------------------------------------------------------------------- |
901
+ | `items` | `ContextMenuItem[]` | — | Menu items (the DropdownMenu item model) |
902
+ | `children` | `Snippet` | — | The right-clickable / long-pressable target area content |
903
+ | `isOpen` | `boolean` | `false` | Bindable; programmatic `true` anchors at the target area |
904
+ | `disabled` | `boolean` | `false` | Triggers inert — the native context menu works again |
905
+ | `longPress` | `number \| false` | `500` | Long-press duration ms (touch/pen); `false` disables |
906
+ | `position` | `ContextMenuPosition` | `"bottom-span-right"` | Placement relative to the pointer (below-right = native convention); flips at the edges |
907
+ | `t` | `TranslateFn` | English | Localizes the sr-only menu label (`createContextMenuT`) |
908
+
909
+ Pass-throughs to the underlying DropdownMenu: `offset` (default `"0px"`), `maxHeight`, `closeOnSelect`, `closeOnClickOutside`, `closeOnEscape`, `search`, `showBackdrop`, `scrollbarGutter`, `noScrollLock`, `forceFallback`, `onOpen`/`onClose`/`onSelect`, and the menu part classes (`classDropdown`, `classItem`, …). Class slots on the wrapper: `class`. Bindables: `el` (target wrapper), `dropdownEl` (open menu). Data attributes on the wrapper: `data-open` (while open), `data-longpress` (long-press enabled — drives the CSS suppressing the platform's own long-press behaviors).
910
+
911
+ ### CSS Tokens
912
+
913
+ None of its own — theme the menu via `--stuic-dropdown-menu-*`. `.stuic-context-menu` is the target area hook; `[data-open]` styles it while the menu is open.
914
+
915
+ ---
916
+
917
+ ## CopyButton
918
+
919
+ Click-to-copy button with built-in feedback. It IS a `Button` (same intent/variant/size/theming) that writes `text` to the clipboard on click, flips to a "copied" state for `feedbackDuration` ms (check icon, `success` intent, localized label / accessible name, visually hidden `role="status"` announcement) and reports the outcome via `onCopied` / `onError`. A failed write (clipboard unavailable, denied, getter threw) is the "error" state (× icon, `destructive` intent). Icon-only by default; `label` (THC or `true`) adds a visible label. The write itself is the `copyToClipboard()` util (async Clipboard API + `execCommand("copy")` fallback), usable without the button.
920
+
921
+ ### Exports
922
+
923
+ | Export | Kind | Description |
924
+ | ---------------------------- | --------- | ------------------------------------------------------------- |
925
+ | `CopyButton` | component | Main component |
926
+ | `CopyButtonProps` | type | Props type |
927
+ | `CopyButtonState` | type | `"idle" \| "copied" \| "error"` |
928
+ | `CopyButtonText` | type | `string \| (() => string \| Promise<string>)` |
929
+ | `createCopyButtonT` | function | Builds the `t` prop from a (partial) message catalog |
930
+ | `COPY_BUTTON_MESSAGES_EN` | constant | Built-in English catalog (also the fallback) |
931
+ | `COPY_BUTTON_MESSAGES_SK` | constant | Bundled Slovak catalog (opt-in) |
932
+ | `CopyButtonMessageKey` | type | Message key union (`copy`, `copied`, `copy_failed`) |
933
+ | `CopyButtonMessages` | type | One locale's catalog |
934
+ | `copyToClipboard` | function | (utils) `(text) => Promise<void>` — the write the button does |
935
+ | `isCopyToClipboardSupported` | function | (utils) any clipboard write path available? (false in SSR) |
936
+
937
+ ### Key Props
938
+
939
+ | Prop | Type | Default | Description |
940
+ | ----------------------------------- | ------------------------------------------- | ------------------ | ------------------------------------------------------------------------ |
941
+ | `text` | `string \| () => string \| Promise<string>` | required | What to copy; a getter is resolved on click |
942
+ | `label` | `THC \| true` | — | Visible label; omit for icon-only (aria-label from `t`), `true` = "Copy" |
943
+ | `labelCopied` | `THC` | `t("copied")` | Label while copied |
944
+ | `labelError` | `THC` | `t("copy_failed")` | Label while in error |
945
+ | `icon` / `iconCopied` / `iconError` | `string \| false` | copy / check / × | Icons per state; `icon={false}` = no icons |
946
+ | `feedbackDuration` | `number` | `2000` | ms the feedback stays; `0` = until the next click |
947
+ | `intentCopied` | `IntentColorKey \| false` | `"success"` | Intent while copied; `false` keeps `intent` |
948
+ | `intentError` | `IntentColorKey \| false` | `"destructive"` | Intent while in error; `false` keeps `intent` |
949
+ | `onCopied` | `(text) => void` | — | After a successful copy |
950
+ | `onError` | `(error) => void` | — | After a failed copy |
951
+ | `onclick` | `(e) => void` | — | Runs first; `preventDefault()` skips the copy |
952
+ | `tooltip` | `boolean \| string \| TooltipConfig` | icon-only: `true` | State-aware tooltip ("Copy" → "Copied"), live while showing |
953
+ | `variant` / `size` | Button's | `"ghost"` / `"sm"` | Defaults differ from Button |
954
+ | `t` | `TranslateFn` | English | i18n |
955
+
956
+ Snippets: `children` (full content override, receives `{ state, copied }`). Class slots: `class`, `classIcon`, `classLabel`. `data-state` is kept even when `unstyled` (it is behavior, not styling).
957
+
958
+ ### CSS Tokens
959
+
960
+ Prefix: `--stuic-copy-button-*` (the surface themes via `--stuic-button-*`)
961
+
962
+ `icon-size`, `icon-pop-duration`, `icon-pop-scale`
963
+
964
+ ---
965
+
966
+ ## EmptyState
967
+
968
+ Icon + title + description + CTA placeholder for empty lists, tables, and search results. Centered, non-interactive; the CTA area is a snippet filled with consumer `Button`s/links. Pairs naturally with `DataTable` ("no rows") and search UIs ("no results").
969
+
970
+ ### Exports
971
+
972
+ | Export | Kind | Description |
973
+ | ------------------- | --------- | ---------------------------------- |
974
+ | `EmptyState` | component | Main component |
975
+ | `EmptyStateProps` | type | Props type |
976
+ | `EmptyStateVariant` | type | `"plain" \| "outline" \| "dashed"` |
977
+ | `EmptyStateSize` | type | `"sm" \| "md" \| "lg"` |
978
+
979
+ ### Key Props
980
+
981
+ | Prop | Type | Default | Description |
982
+ | ------------- | ---------------------------------- | --------- | ------------------------------------------------- |
983
+ | `icon` | `THC` | — | Icon area content (e.g. `{ html: iconSearch() }`) |
984
+ | `title` | `THC` | — | Title headline |
985
+ | `description` | `THC` | — | Supporting text below the title |
986
+ | `variant` | `"plain" \| "outline" \| "dashed"` | `"plain"` | Container treatment (bordered box or none) |
987
+ | `size` | `"sm" \| "md" \| "lg"` | `"md"` | Padding, icon and typography scale |
988
+
989
+ Snippets: `actions` (CTA area), `renderIcon` (icon override), `children` (full layout override). Class slots: `class`, `classIcon`, `classTitle`, `classDescription`, `classActions`. No implicit ARIA role — pass `role="status"` when the empty state replaces content dynamically.
990
+
991
+ ### CSS Tokens
992
+
993
+ Prefix: `--stuic-empty-state-*`
994
+
995
+ `gap`, `padding-{sm,md,lg}`, `icon-size-{sm,md,lg}`, `icon-text`, `icon-opacity`, `icon-margin-bottom`, `title-font-size-{sm,md,lg}`, `title-font-weight`, `title-text`, `description-font-size-{sm,md,lg}`, `description-text`, `description-max-width`, `actions-gap`, `actions-margin-top`, `bg`, `border`, `border-width`, `radius`
996
+
997
+ Falls back to shared structural tokens `--stuic-border-width` and `--stuic-radius-container` (outline/dashed variants).
998
+
999
+ ---
1000
+
1001
+ ## Pagination
1002
+
1003
+ Standalone pagination for lists, search results, and custom views. Two variants: `compact` (prev / "Page X of Y" / next — the pager `DataTable` renders internally) and `numbers` (windowed page-number buttons with ellipsis gaps). Consumes the same `PagingCalcResult` from `@marianmeres/paging-store` that `DataTable` does, so one paging store can feed both (`<DataTable showPager={false} />` + standalone `Pagination`); `total`/`limit`/`offset` convenience props compute paging internally for quick standalone use.
1004
+
1005
+ ### Exports
1006
+
1007
+ | Export | Kind | Description |
1008
+ | ------------------------ | --------- | ---------------------------------------------------- |
1009
+ | `Pagination` | component | Main component |
1010
+ | `PaginationProps` | type | Props type |
1011
+ | `PaginationVariant` | type | `"compact" \| "numbers"` |
1012
+ | `paginationRange` | function | Pure windowing helper behind the numbers variant |
1013
+ | `PaginationRangeItem` | type | `number \| "ellipsis"` |
1014
+ | `PaginationRangeOptions` | type | `{ siblingCount?, boundaryCount? }` |
1015
+ | `createPaginationT` | function | Builds the `t` prop from a (partial) message catalog |
1016
+ | `PAGINATION_MESSAGES_EN` | constant | Built-in English catalog (also the fallback) |
1017
+ | `PAGINATION_MESSAGES_SK` | constant | Bundled Slovak catalog (opt-in) |
1018
+ | `PaginationMessageKey` | type | Message key union |
1019
+ | `PaginationMessages` | type | One locale's catalog |
1020
+
1021
+ ### Key Props
1022
+
1023
+ | Prop | Type | Default | Description |
1024
+ | ------------------------ | ------------------------ | ----------- | ---------------------------------------------------------------------------- |
1025
+ | `paging` | `PagingCalcResult` | — | Paging metadata (`DataTable`-compatible); wins over `total`/`limit`/`offset` |
1026
+ | `total`/`limit`/`offset` | `number` | —/`10`/`0` | Convenience alternative to `paging` (computed via `calculatePaging`) |
1027
+ | `onPageChange` | `(offset, page) => void` | — | New offset (`DataTable`'s signature as first arg) + 1-based target page |
1028
+ | `variant` | `"compact" \| "numbers"` | `"compact"` | Prev/info/next, or windowed page-number buttons |
1029
+ | `siblingCount` | `number` | `1` | Numbers: pages always shown around the current page |
1030
+ | `boundaryCount` | `number` | `1` | Numbers: pages always shown at the start and end |
1031
+ | `showFirstLast` | `boolean` | `false` | First/last jump buttons (« ») |
1032
+ | `showInfo` | `boolean` | per variant | "Page X of Y" info (`true` for compact, `false` for numbers) |
1033
+ | `hideSinglePage` | `boolean` | `true` | Render nothing when there is at most one page (the `DataTable` rule) |
1034
+ | `disabled` | `boolean` | `false` | Disable all controls (e.g. while loading) |
1035
+ | `size` | `ButtonSize` | `"sm"` | Size preset of the inner Buttons |
1036
+ | `t` | `TranslateFn` | English | i18n; `previous_page`/`next_page`/`page_x_of_y` keys match `DataTable`'s |
1037
+
1038
+ Snippets: `renderInfo` (info override, receives `PagingCalcResult`). Class slots: `class`, `classButton`, `classButtonCurrent`, `classInfo`. Renders a `<nav aria-label>` landmark; the current page button carries `aria-current="page"`.
1039
+
1040
+ ### CSS Tokens
1041
+
1042
+ Prefix: `--stuic-pagination-*`
1043
+
1044
+ `gap`, `button-min-width`, `info-font-size`, `info-text`, `ellipsis-text`
1045
+
1046
+ `button-min-width` defaults to `--stuic-button-min-height-sm` so single-character buttons stay square-ish.
1047
+
1048
+ ---
1049
+
1050
+ ## Stepper
1051
+
1052
+ Numbered multi-step progress header for wizard/checkout flows. Accessible `<nav>` landmark with an ordered list: completed steps get a check mark and filled connector, the current step is highlighted (`aria-current="step"`), upcoming steps stay muted; per-step `error` renders a destructive "×". Display-only by default; `onSelect` makes steps clickable (completed-only by default, `clickable="all"` for free navigation). `current` is a zero-based index — exactly `@marianmeres/wizard`'s `step.index` (`steps.length` = all done).
1053
+
1054
+ ### Exports
1055
+
1056
+ | Export | Kind | Description |
1057
+ | ---------------------- | --------- | ---------------------------------------------------- |
1058
+ | `Stepper` | component | Main component |
1059
+ | `StepperProps` | type | Props type |
1060
+ | `StepperStep` | type | `{ label, description?, icon?, error?, disabled? }` |
1061
+ | `StepperStepState` | type | `"completed" \| "current" \| "upcoming"` |
1062
+ | `StepperOrientation` | type | `"horizontal" \| "vertical"` |
1063
+ | `StepperLabelPosition` | type | `"end" \| "below"` |
1064
+ | `StepperClickable` | type | `"none" \| "completed" \| "all"` |
1065
+ | `createStepperT` | function | Builds the `t` prop from a (partial) message catalog |
1066
+ | `STEPPER_MESSAGES_EN` | constant | Built-in English catalog (also the fallback) |
1067
+ | `STEPPER_MESSAGES_SK` | constant | Bundled Slovak catalog (opt-in) |
1068
+ | `StepperMessageKey` | type | Message key union |
1069
+ | `StepperMessages` | type | One locale's catalog |
1070
+
1071
+ ### Key Props
1072
+
1073
+ | Prop | Type | Default | Description |
1074
+ | --------------- | -------------------------------- | -------------- | ------------------------------------------------------------------------------------ |
1075
+ | `steps` | `(StepperStep \| string)[]` | required | The steps; plain strings are shorthand for `{ label }` (labels/descriptions are THC) |
1076
+ | `current` | `number` | `0` | Zero-based current step index; `steps.length` = all completed; clamped |
1077
+ | `onSelect` | `(index, step) => void` | — | Navigation callback; when present, steps render as buttons |
1078
+ | `clickable` | `"none" \| "completed" \| "all"` | `"completed"` | Click policy (the current step never fires) |
1079
+ | `orientation` | `"horizontal" \| "vertical"` | `"horizontal"` | Layout direction |
1080
+ | `labelPosition` | `"end" \| "below"` | `"end"` | Horizontal only: labels beside the indicator or centered below it |
1081
+ | `disabled` | `boolean` | `false` | Disable all interaction |
1082
+ | `t` | `TranslateFn` | English | i18n: landmark label + sr-only step announcements ("Step X of Y", Completed/Failed) |
1083
+
1084
+ Snippets: `renderIndicator` (bubble override, receives `{ index, step, state }`). Class slots: `class`, `classStep`, `classIndicator`, `classLabel`, `classDescription`, `classConnector`. Indicator bubbles are `aria-hidden` — visually hidden text announces position + state instead.
1085
+
1086
+ ### CSS Tokens
1087
+
1088
+ Prefix: `--stuic-stepper-*`
1089
+
1090
+ `gap`, `gap-vertical`, `connector-min-length`, `indicator-size`, `indicator-border-width`, `indicator-radius`, `indicator-font-size`, `indicator-font-weight`, `indicator-{bg,text,border}{,-current,-completed,-error}`, `label-font-size`, `label-font-weight`, `label-text{,-current,-completed,-error}`, `description-font-size`, `description-text`, `connector-thickness`, `connector-bg{,-completed}`, `ring-width`, `ring-color`, `opacity-disabled`
1091
+
1092
+ ---
1093
+
827
1094
  ## CronInput
828
1095
 
829
1096
  Cron expression editor with preset selector, manual 5-field editor, raw expression input, human-readable descriptions, and next-run calculation.
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## Overview
4
4
 
5
- 44 utility modules for common tasks. Organized by category.
5
+ 45 utility modules for common tasks. Organized by category.
6
6
 
7
7
  ---
8
8
 
@@ -35,11 +35,13 @@ theme.value = "dark";
35
35
 
36
36
  ## DOM Utilities
37
37
 
38
- | Util | Purpose |
39
- | ------------------ | ------------------------ |
40
- | `qsa` | querySelectorAll wrapper |
41
- | `bodyScrollLocker` | Lock/unlock body scroll |
42
- | `getId` | Generate unique IDs |
38
+ | Util | Purpose |
39
+ | ---------------------------- | ---------------------------------------------------------------- |
40
+ | `qsa` | querySelectorAll wrapper |
41
+ | `bodyScrollLocker` | Lock/unlock body scroll |
42
+ | `getId` | Generate unique IDs |
43
+ | `copyToClipboard` | Write text to the clipboard (async API + `execCommand` fallback) |
44
+ | `isCopyToClipboardSupported` | Whether any clipboard write path exists (false during SSR) |
43
45
 
44
46
  ---
45
47
 
@@ -0,0 +1,111 @@
1
+ # Maybe-todo: missing component candidates
2
+
3
+ An analysis of typical (widely used) UI/UX components that stuic does not yet ship,
4
+ compared against the usual baseline of comparable libraries (shadcn, Bits UI, Melt,
5
+ Skeleton, Flowbite, DaisyUI). Snapshot as of 2026-09. Nothing here is committed work —
6
+ it is a menu to pick from.
7
+
8
+ ## Already covered under non-obvious names (not gaps)
9
+
10
+ Checked first, to avoid false positives:
11
+
12
+ - **Tooltip / Popover** — actions (`actions/tooltip`, `actions/popover`), not components
13
+ - **Toast** — `Notifications` (notifications stack)
14
+ - **Badge** — `Pill`
15
+ - **Toggle group** — `ButtonGroupRadio`
16
+ - **Sheet** — `Drawer`
17
+ - **Alert / callout** — `DismissibleMessage`
18
+ - **Table pagination** — built into `DataTable` (`showpager`)
19
+ - **Multi-select / tags input** — `FieldOptions` (async `getOptions` search, typeahead,
20
+ `cardinality`, option groups, `allowUnknown` for ad-hoc values, `ordered` for manual
21
+ arrangement). See the note at the bottom on the inline-chip presentation variant.
22
+ - **File dropzone** — `actions/file-dropzone` + `FieldFile` / `FieldAssets`
23
+
24
+ ## Tier 1 — staples nearly every comparable library ships
25
+
26
+ 1. **Date picker / Calendar** — the single biggest gap. No calendar grid, no date-range
27
+ picker anywhere in the lib (only native `type="date"` via `FieldInput`).
28
+ `@marianmeres/calendar-utils` already does the date math, so this is mostly UI work.
29
+ A `FieldDate` / `FieldDateRange` would slot naturally next to `FieldMoney` /
30
+ `FieldPhoneNumber`. Most work of anything on this list, but also the absence
31
+ consumers will actually notice.
32
+ 2. ~~**Breadcrumbs**~~ — ✅ shipped (see `src/lib/components/Breadcrumbs/`):
33
+ APG nav/ol trail, collapsible long trails, schema.org `BreadcrumbList` JSON-LD
34
+ helpers (`breadcrumbsJsonLd` / `breadcrumbsJsonLdScript` + inline `jsonLd` prop).
35
+ 3. ~~**Pagination (standalone)**~~ — ✅ shipped (see `src/lib/components/Pagination/`):
36
+ compact (the `DataTable` pager) + windowed page-numbers variants, consumes the same
37
+ `PagingCalcResult` as `DataTable` so one paging store can feed both.
38
+
39
+ ## Tier 2 — very common, clear use cases
40
+
41
+ 4. ~~**Stepper / step indicator**~~ — ✅ shipped (see `src/lib/components/Stepper/`):
42
+ numbered step indicator with completed/current/upcoming/error states, optional
43
+ click navigation, horizontal (labels end/below) + vertical orientations; `current`
44
+ is a zero-based index matching `@marianmeres/wizard`'s `step.index`.
45
+ 5. ~~**ContextMenu**~~ — ✅ shipped (see `src/lib/components/ContextMenu/`): wraps the
46
+ `DropdownMenu` engine behind context-menu trigger semantics — positions at the
47
+ cursor via a 0×0 fixed anchor, `contextmenu` event, long-press on touch/pen (new
48
+ reusable `longPress` attachment), Shift+F10 / menu key.
49
+ 6. ~~**EmptyState**~~ — ✅ shipped (see `src/lib/components/EmptyState/`): icon +
50
+ title + description + CTA placeholder for empty lists/tables/search results.
51
+ 7. **Rating (stars)** — display + input variants. `FieldLikeButton` is adjacent but not
52
+ this.
53
+
54
+ ## Tier 3 — common, but judge by actual app needs
55
+
56
+ 8. **SplitPane / resizable panels** — general two-pane draggable splitter
57
+ (horizontal/vertical, min/max, persisted size). `actions/resizable-width`,
58
+ `WithSidePanel`, and `persistent-state` already provide the pieces.
59
+ 9. **Range slider (dual-thumb)** — `Slider` is deliberately single-value; a min/max
60
+ range variant (price filters etc.) is a recurring ask.
61
+ 10. **Timeline / activity feed** — vertical event list with markers; common in
62
+ admin/audit views.
63
+ 11. ~~**Stat / KPI card**~~ — ✅ shipped (see `src/lib/components/Stat/`): label +
64
+ value + delta with trend arrow and semantic coloring (`trendIntent` for
65
+ down-is-good metrics), hint, corner icon, footer/sparkline area.
66
+ 12. ~~**CopyButton**~~ — ✅ shipped (see `src/lib/components/CopyButton/`): a
67
+ `Button` that copies `text` (string or sync/async getter) with copied/error
68
+ feedback (icon + intent swap, localized label/name, sr live announcement),
69
+ `onCopied` / `onError` callbacks; the write is the reusable `copyToClipboard()`
70
+ util (async Clipboard API + `execCommand` fallback) in `utils/`.
71
+ 13. **ColorPicker** — beyond native `type="color"`: swatch palette + custom input.
72
+ Given stuic's theming/design-tokens focus, a swatch picker would be on-brand.
73
+
74
+ ## Deliberately out of scope (or close enough to covered)
75
+
76
+ - scroll-area (native is fine)
77
+ - virtual list / infinite scroll (belongs closer to `@marianmeres/paging-store`)
78
+ - lightbox (`AssetsPreview` territory)
79
+ - menubar / mega-menu (`Nav` + `DropdownMenu` compose it)
80
+ - password strength meter, toolbar
81
+
82
+ ## Note: inline-chip presentation of FieldOptions
83
+
84
+ Initially listed as a Tier-1 "tags input" gap; retracted — `FieldOptions` covers the
85
+ capability. What stuic lacks is at most the _inline chip form factor_: chips inside the
86
+ field with per-chip remove ×, a text input riding alongside, suggestions in a popover
87
+ without leaving the page. Faster for dense desktop/admin work; the existing modal flow
88
+ is arguably better on mobile.
89
+
90
+ If ever built, the design to argue for: a presentation mode of `FieldOptions` (the
91
+ selection model — `ItemCollection`, `cardinality`, `allowUnknown` — is already there),
92
+ not a new component. Inline combobox on pointer devices, delegating to the existing
93
+ modal on touch/small screens (`breakpoint.svelte.ts` + `device-pointer.svelte.ts`
94
+ enable the switch).
95
+
96
+ Mobile reality check for the inline variant, if it were ever made touch-capable
97
+ instead of delegating:
98
+
99
+ - a floating anchor-positioned dropdown is the first casualty of the on-screen
100
+ keyboard (clipped/covered/scrolled); the mobile-viable idiom is a full-width
101
+ suggestion list in document flow under the field (cf. Gmail's To: field), sized via
102
+ the `visualViewport` API
103
+ - chip removal: tiny × falls below ~44px touch targets, and backspace-to-delete is
104
+ unreliable (Android IMEs report `keyCode 229`); workable patterns are
105
+ tap-to-select-then-delete or generously padded delete zones, detected via
106
+ `beforeinput`/`input` rather than `keydown`
107
+ - committing unknown values: on separator via `input` event or on blur, not keydown
108
+
109
+ Once all three adaptations are made, the small-screen result is behaviorally ~90% of
110
+ what the `FieldOptions` modal already does — which is why delegating below a
111
+ breakpoint is the pragmatic answer.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marianmeres/stuic",
3
- "version": "3.167.0",
3
+ "version": "3.168.0",
4
4
  "packageManager": "pnpm@11.5.0",
5
5
  "scripts": {
6
6
  "dev": "vite dev",
@@ -60,6 +60,11 @@
60
60
  "types": "./dist/components/CommentInput/index.d.ts",
61
61
  "svelte": "./dist/components/CommentInput/index.js",
62
62
  "default": "./dist/components/CommentInput/index.js"
63
+ },
64
+ "./trend-chart": {
65
+ "types": "./dist/components/TrendChart/index.d.ts",
66
+ "svelte": "./dist/components/TrendChart/index.js",
67
+ "default": "./dist/components/TrendChart/index.js"
63
68
  }
64
69
  },
65
70
  "peerDependencies": {
@@ -69,6 +74,7 @@
69
74
  "@codemirror/language-data": "^6.0.0",
70
75
  "@codemirror/state": "^6.0.0",
71
76
  "@codemirror/view": "^6.0.0",
77
+ "@marianmeres/trend-chart": "^0.5.0",
72
78
  "@milkdown/core": "^7.0.0",
73
79
  "@milkdown/ctx": "^7.0.0",
74
80
  "@milkdown/plugin-history": "^7.0.0",
@@ -99,6 +105,9 @@
99
105
  "@codemirror/view": {
100
106
  "optional": true
101
107
  },
108
+ "@marianmeres/trend-chart": {
109
+ "optional": true
110
+ },
102
111
  "@milkdown/core": {
103
112
  "optional": true
104
113
  },
@@ -136,6 +145,7 @@
136
145
  "@codemirror/view": "^6.43.9",
137
146
  "@eslint/js": "^9.39.5",
138
147
  "@marianmeres/random-human-readable": "^1.10.2",
148
+ "@marianmeres/trend-chart": "^0.5.0",
139
149
  "@milkdown/core": "^7.22.1",
140
150
  "@milkdown/ctx": "^7.22.1",
141
151
  "@milkdown/plugin-history": "^7.22.1",