@uni-design-system/uni-mcp 11.7.0 → 11.9.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.
@@ -7,17 +7,17 @@ import { z } from "zod";
7
7
  // src/data/uni-index.json
8
8
  var uni_index_default = {
9
9
  meta: {
10
- version: "11.7.0",
11
- builtAt: "2026-10-22T04:29:01.107Z",
10
+ version: "11.9.0",
11
+ builtAt: "2026-10-22T15:35:59.427Z",
12
12
  frameworks: [
13
13
  "angular"
14
14
  ],
15
15
  counts: {
16
- components: 88,
17
- tokens: 511,
16
+ components: 89,
17
+ tokens: 514,
18
18
  themes: 2,
19
- examples: 256,
20
- utilities: 122
19
+ examples: 263,
20
+ utilities: 124
21
21
  }
22
22
  },
23
23
  components: [
@@ -28,7 +28,7 @@ var uni_index_default = {
28
28
  summary: "",
29
29
  description: "",
30
30
  category: "feedback",
31
- version: "11.7.0",
31
+ version: "11.9.0",
32
32
  bindings: {
33
33
  angular: {
34
34
  importPath: "@uni-design-system/uni-angular",
@@ -118,7 +118,7 @@ var uni_index_default = {
118
118
  summary: "Horizontal application bar: project leading controls (menu button, logo) with the `leading` attribute, actions with `trailing` (pushed to the far edge), and either pass `title` or project custom center content.",
119
119
  description: "Horizontal application bar: project leading controls (menu button, logo) with the `leading` attribute, actions with `trailing` (pushed to the far edge), and either pass `title` or project custom center content. Surface, divider, height, typography and spacing all resolve from `appBar` tokens. Place it inside your page's `<header>` landmark.",
120
120
  category: "components",
121
- version: "11.7.0",
121
+ version: "11.9.0",
122
122
  bindings: {
123
123
  angular: {
124
124
  importPath: "@uni-design-system/uni-angular",
@@ -191,7 +191,7 @@ var uni_index_default = {
191
191
  summary: "Identity avatar with a graceful fallback chain: image \u2192 initials from `name` \u2192 themed symbol.",
192
192
  description: "Identity avatar with a graceful fallback chain: image \u2192 initials from `name` \u2192 themed symbol. Coloring, radius, typeface and sizes all resolve from `avatar` theme tokens; `variant` picks the container palette.",
193
193
  category: "components",
194
- version: "11.7.0",
194
+ version: "11.9.0",
195
195
  bindings: {
196
196
  angular: {
197
197
  importPath: "@uni-design-system/uni-angular",
@@ -286,7 +286,7 @@ var uni_index_default = {
286
286
  summary: "Overlapping stack of avatars.",
287
287
  description: "Overlapping stack of avatars. `max` collapses the overflow into a themed \u201C+N\u201D chip (itself a `uni-avatar`). Overlap and separator ring resolve from `avatarGroup` theme tokens.",
288
288
  category: "components",
289
- version: "11.7.0",
289
+ version: "11.9.0",
290
290
  bindings: {
291
291
  angular: {
292
292
  importPath: "@uni-design-system/uni-angular",
@@ -335,7 +335,7 @@ var uni_index_default = {
335
335
  summary: "",
336
336
  description: "",
337
337
  category: "primitives",
338
- version: "11.7.0",
338
+ version: "11.9.0",
339
339
  bindings: {
340
340
  angular: {
341
341
  importPath: "@uni-design-system/uni-angular",
@@ -416,7 +416,7 @@ var uni_index_default = {
416
416
  summary: "",
417
417
  description: "",
418
418
  category: "feedback",
419
- version: "11.7.0",
419
+ version: "11.9.0",
420
420
  bindings: {
421
421
  angular: {
422
422
  importPath: "@uni-design-system/uni-angular",
@@ -513,7 +513,7 @@ var uni_index_default = {
513
513
  summary: "",
514
514
  description: "",
515
515
  category: "directives",
516
- version: "11.7.0",
516
+ version: "11.9.0",
517
517
  bindings: {
518
518
  angular: {
519
519
  importPath: "@uni-design-system/uni-angular",
@@ -537,7 +537,7 @@ var uni_index_default = {
537
537
  summary: 'The base layout primitive, applied as an attribute to any element so semantics stay yours: `<main box-layout [grow]="1" padding="md">`.',
538
538
  description: 'The base layout primitive, applied as an attribute to any element so semantics stay yours: `<main box-layout [grow]="1" padding="md">`. It is a directive, so it composes freely \u2014 with another layout attribute (`<div stack-layout uni-text="body-1-long">`) and with a component\'s own host element (`<uni-card box-layout padding="lg">`); Angular merges the host `class` bindings rather than letting one win. Sizing convention (height/width/min/max/inset): a **number is px and needs a binding** \u2014 `[height]="420"`; a **plain attribute is a CSS length string** \u2014 `height="420px"`. Spacing/radius/color inputs take theme tokens.',
539
539
  category: "layout",
540
- version: "11.7.0",
540
+ version: "11.9.0",
541
541
  bindings: {
542
542
  angular: {
543
543
  importPath: "@uni-design-system/uni-angular",
@@ -945,7 +945,7 @@ var uni_index_default = {
945
945
  summary: 'WAI-ARIA breadcrumb: a `nav` landmark wrapping an ordered list; the last item is the current page (`aria-current="page"`), separators are decorative.',
946
946
  description: 'WAI-ARIA breadcrumb: a `nav` landmark wrapping an ordered list; the last item is the current page (`aria-current="page"`), separators are decorative. Items with `href` render as real links; without one they render as link-styled buttons emitting `itemClicked` \u2014 wire that to your router.',
947
947
  category: "components",
948
- version: "11.7.0",
948
+ version: "11.9.0",
949
949
  bindings: {
950
950
  angular: {
951
951
  importPath: "@uni-design-system/uni-angular",
@@ -1030,7 +1030,7 @@ var uni_index_default = {
1030
1030
  summary: "",
1031
1031
  description: "",
1032
1032
  category: "primitives",
1033
- version: "11.7.0",
1033
+ version: "11.9.0",
1034
1034
  bindings: {
1035
1035
  angular: {
1036
1036
  importPath: "@uni-design-system/uni-angular",
@@ -1198,7 +1198,7 @@ var uni_index_default = {
1198
1198
  summary: "",
1199
1199
  description: "",
1200
1200
  category: "primitives",
1201
- version: "11.7.0",
1201
+ version: "11.9.0",
1202
1202
  bindings: {
1203
1203
  angular: {
1204
1204
  importPath: "@uni-design-system/uni-angular",
@@ -1230,7 +1230,7 @@ var uni_index_default = {
1230
1230
  summary: "Inline month calendar: single-date or start\u2013end range selection, day markers (availability dots), min/max fences and disabled dates.",
1231
1231
  description: "Inline month calendar: single-date or start\u2013end range selection, day markers (availability dots), min/max fences and disabled dates. One tab stop with a roving-tabindex `role=\"grid\"`; every day is a real button named with its full date. Values are plain ISO strings (`'YYYY-MM-DD'`), never `Date` objects, so bindings are timezone-free and serializable. Selection and today colours come from the theme's `primary` role pair; geometry and glyphs come from the `calendar` theme entry.",
1232
1232
  category: "forms",
1233
- version: "11.7.0",
1233
+ version: "11.9.0",
1234
1234
  bindings: {
1235
1235
  angular: {
1236
1236
  importPath: "@uni-design-system/uni-angular",
@@ -1471,7 +1471,7 @@ var uni_index_default = {
1471
1471
  summary: "Anchored coach-mark panel that dims the page and cuts a spotlight hole around its target.",
1472
1472
  description: 'Anchored coach-mark panel that dims the page and cuts a spotlight hole around its target. Both the scrim and the panel are `popover="manual"` elements shown in order, so they stack deterministically in the top layer above every app z-index, and every scrim piece is CSS-anchor-positioned to the target \u2014 the hole tracks scroll/resize/layout with zero listeners. The panel is a non-modal `role="dialog"` (deliberately no `aria-modal`): focus moves into it on open, Tab runs a "duet loop" over the panel\'s focusables plus the spotlit target while it stays interactive, and on close focus returns to the pre-open element \u2014 unless the user moved into the target, where it stays. Storage-free by rule: `key` and the `dismissed` output are the "don\'t show again" hooks; persistence is the app\'s business (e.g. cdk local-storage).',
1473
1473
  category: "components",
1474
- version: "11.7.0",
1474
+ version: "11.9.0",
1475
1475
  bindings: {
1476
1476
  angular: {
1477
1477
  importPath: "@uni-design-system/uni-angular",
@@ -1691,7 +1691,7 @@ var uni_index_default = {
1691
1691
  summary: "",
1692
1692
  description: "",
1693
1693
  category: "layout",
1694
- version: "11.7.0",
1694
+ version: "11.9.0",
1695
1695
  bindings: {
1696
1696
  angular: {
1697
1697
  importPath: "@uni-design-system/uni-angular",
@@ -1753,7 +1753,7 @@ var uni_index_default = {
1753
1753
  summary: "",
1754
1754
  description: "",
1755
1755
  category: "layout",
1756
- version: "11.7.0",
1756
+ version: "11.9.0",
1757
1757
  bindings: {
1758
1758
  angular: {
1759
1759
  importPath: "@uni-design-system/uni-angular",
@@ -1794,7 +1794,7 @@ var uni_index_default = {
1794
1794
  summary: "",
1795
1795
  description: "",
1796
1796
  category: "layout",
1797
- version: "11.7.0",
1797
+ version: "11.9.0",
1798
1798
  bindings: {
1799
1799
  angular: {
1800
1800
  importPath: "@uni-design-system/uni-angular",
@@ -1851,7 +1851,7 @@ var uni_index_default = {
1851
1851
  summary: "",
1852
1852
  description: "",
1853
1853
  category: "layout",
1854
- version: "11.7.0",
1854
+ version: "11.9.0",
1855
1855
  bindings: {
1856
1856
  angular: {
1857
1857
  importPath: "@uni-design-system/uni-angular",
@@ -1906,7 +1906,7 @@ var uni_index_default = {
1906
1906
  summary: "",
1907
1907
  description: "",
1908
1908
  category: "forms",
1909
- version: "11.7.0",
1909
+ version: "11.9.0",
1910
1910
  bindings: {
1911
1911
  angular: {
1912
1912
  importPath: "@uni-design-system/uni-angular",
@@ -2128,7 +2128,7 @@ var uni_index_default = {
2128
2128
  summary: "Form-bound, closed-set, single-select autocomplete: `FormValueControl<T | null>` over object `Options<T>`, type-to-filter, commit-on-select.",
2129
2129
  description: "Form-bound, closed-set, single-select autocomplete: `FormValueControl<T | null>` over object `Options<T>`, type-to-filter, commit-on-select. Typing produces a draft \u2014 a filter, never a value; the value changes only when an option commits, `clear()` runs, or the model is written from outside. Select semantics, not search: a real label, a chevron, no magnifier, nothing submits. For short lists with no need to type, prefer `uni-select` \u2014 the value contract is identical, so swapping is a template-only change.",
2130
2130
  category: "forms",
2131
- version: "11.7.0",
2131
+ version: "11.9.0",
2132
2132
  bindings: {
2133
2133
  angular: {
2134
2134
  importPath: "@uni-design-system/uni-angular",
@@ -2430,7 +2430,7 @@ emptyText="No countries found"
2430
2430
  summary: "",
2431
2431
  description: "",
2432
2432
  category: "feedback",
2433
- version: "11.7.0",
2433
+ version: "11.9.0",
2434
2434
  bindings: {
2435
2435
  angular: {
2436
2436
  importPath: "@uni-design-system/uni-angular",
@@ -2477,7 +2477,7 @@ emptyText="No countries found"
2477
2477
  summary: "Recipient field for picking people: removable chips, a text input, and a list of known contacts that opens on focus and narrows as the user types \u2014 each row drawn as a person (avatar, name, address, a trailing note).",
2478
2478
  description: "Recipient field for picking people: removable chips, a text input, and a list of known contacts that opens on focus and narrows as the user types \u2014 each row drawn as a person (avatar, name, address, a trailing note). A thin composition of `uni-tag-input` with a mail client's manners baked in: ArrowDown walks the matches and Enter picks the active one, Backspace in an empty field removes the last person, and text that is neither a known contact nor a valid address stays in the field to be fixed (`rejected` says why). Reach for `uni-tag-input` itself when the tokens are not people.",
2479
2479
  category: "forms",
2480
- version: "11.7.0",
2480
+ version: "11.9.0",
2481
2481
  bindings: {
2482
2482
  angular: {
2483
2483
  importPath: "@uni-design-system/uni-angular",
@@ -2762,7 +2762,7 @@ emptyText="No countries found"
2762
2762
  summary: "",
2763
2763
  description: "",
2764
2764
  category: "forms",
2765
- version: "11.7.0",
2765
+ version: "11.9.0",
2766
2766
  bindings: {
2767
2767
  angular: {
2768
2768
  importPath: "@uni-design-system/uni-angular",
@@ -2858,10 +2858,10 @@ emptyText="No countries found"
2858
2858
  id: "data-table",
2859
2859
  name: "DataTable",
2860
2860
  status: "stable",
2861
- summary: "",
2862
- description: "",
2861
+ summary: "Data grid over a `UniDatasource`: sortable headers, a leading selection column, and an expandable detail row per record.",
2862
+ description: "Data grid over a `UniDatasource`: sortable headers, a leading selection column, and an expandable detail row per record. Rows are addressed by the datasource's `rowId` where it has one \u2014 so a selection survives a re-fetch that rebuilds the records, and the expanded row follows its record through a sort \u2014 and by reference (selection) or page index (expansion) where it has none.",
2863
2863
  category: "data",
2864
- version: "11.7.0",
2864
+ version: "11.9.0",
2865
2865
  bindings: {
2866
2866
  angular: {
2867
2867
  importPath: "@uni-design-system/uni-angular",
@@ -2881,13 +2881,36 @@ emptyText="No countries found"
2881
2881
  required: true,
2882
2882
  description: ""
2883
2883
  },
2884
+ {
2885
+ name: "expanded",
2886
+ kind: "model",
2887
+ type: "RowKey | null",
2888
+ required: false,
2889
+ default: "null",
2890
+ description: "The expanded row, two-way: its `rowId` when the datasource has one, else its index on the page. `null` collapses every row. Keyed by id, a deep link can open a row before the records arrive, and a sort or a realtime reorder keeps the same record open."
2891
+ },
2884
2892
  {
2885
2893
  name: "useMultiSelect",
2886
2894
  kind: "input",
2887
2895
  type: "boolean",
2888
2896
  required: false,
2889
2897
  default: "false",
2890
- description: ""
2898
+ description: "Draw a leading checkbox column over the datasource's `selections`: a header box that selects or clears every selectable row on the page (`indeterminate` while only some are), and a box per row."
2899
+ },
2900
+ {
2901
+ name: "selectAllLabel",
2902
+ kind: "input",
2903
+ type: "string",
2904
+ required: false,
2905
+ default: "'Select all rows'",
2906
+ description: "Accessible name of the header checkbox."
2907
+ },
2908
+ {
2909
+ name: "selectionChange",
2910
+ kind: "output",
2911
+ type: "T[]",
2912
+ required: false,
2913
+ description: "The datasource's selection after a checkbox changed it \u2014 the same array `selections()` holds."
2891
2914
  },
2892
2915
  {
2893
2916
  name: "useRowClick",
@@ -3097,6 +3120,44 @@ emptyText="No countries found"
3097
3120
  base[1]
3098
3121
  ]"
3099
3122
  />`
3123
+ },
3124
+ {
3125
+ title: "Selection",
3126
+ framework: "angular",
3127
+ code: `<!-- Storybook story: Selection -->
3128
+ <uni-data-table
3129
+ [datasource]="datasource"
3130
+ [columns]="columns"
3131
+ [useMultiSelect]="true"
3132
+ [selectableWhen]="selectable"
3133
+ [useRowClick]="false"
3134
+ [selectLabel]="selectLabelOf"
3135
+ (selectionChange)="selected = $event"
3136
+ />
3137
+ <p uni-text="body-2">Selected: {{ selected.length ? (selected | json) : 'nothing' }}</p>`
3138
+ },
3139
+ {
3140
+ title: "Expanded Row",
3141
+ framework: "angular",
3142
+ code: `<!-- Storybook story: Expanded Row -->
3143
+ <div row-layout gap="sm" alignItems="center" paddingBottom="sm">
3144
+ <button text-button size="sm" variant="secondary" (click)="expanded = 'po-104'">Open po-104</button>
3145
+ <button text-button size="sm" variant="ghost" (click)="expanded = null">Collapse</button>
3146
+ <span uni-text="body-2">Expanded: {{ expanded ?? 'none' }}</span>
3147
+ </div>
3148
+ <uni-data-table
3149
+ [datasource]="datasource"
3150
+ [columns]="columns"
3151
+ [detailRowTemplate]="detail"
3152
+ [(expanded)]="expanded"
3153
+ [expandableWhen]="expandable"
3154
+ [rowClass]="dim"
3155
+ />
3156
+ <ng-template #detail let-row>
3157
+ <div box-layout padding="md" uni-text="body-2-long">
3158
+ {{ row.item }} from {{ row.vendor }} \u2014 tracking and notes would go here.
3159
+ </div>
3160
+ </ng-template>`
3100
3161
  }
3101
3162
  ],
3102
3163
  guidelines: {
@@ -3106,7 +3167,8 @@ emptyText="No countries found"
3106
3167
  accessibility: [
3107
3168
  'Column headers use `scope="col"`; sortable headers are real buttons with `aria-sort` on the `<th>`. A `sortable: false` column is a plain heading with neither.',
3108
3169
  'The loading overlay is a `role="status"` region and the table is `aria-busy` while loading.',
3109
- "Collapsed detail rows are `inert`, out of the accessibility tree until expanded."
3170
+ "Collapsed detail rows are `inert`, out of the accessibility tree until expanded; a row with a detail carries `aria-expanded`.",
3171
+ 'Selection boxes are real `uni-checkbox`es named without drawing \u2014 "Select row" and "Select all rows" by default, or per row through `selectLabel` \u2014 and a box is its own control: a click or Space on it is never the row\'s click.'
3110
3172
  ]
3111
3173
  },
3112
3174
  relatedTokens: []
@@ -3118,7 +3180,7 @@ emptyText="No countries found"
3118
3180
  summary: "Date field with free-typed parsing and a popup calendar.",
3119
3181
  description: "Date field with free-typed parsing and a popup calendar. Type `aug 20`, `8/20/2026` or `2026-08-20`, or pick from the grid \u2014 the form gets the same canonical `'YYYY-MM-DD'` string either way. Parsing is `Intl`-driven (locale digit order and month names, never hardcoded); unreadable text stays in the field, flagged, with a `rejected` event. The popup is a native popover hosting the same `uni-calendar` an app could render inline.",
3120
3182
  category: "forms",
3121
- version: "11.7.0",
3183
+ version: "11.9.0",
3122
3184
  bindings: {
3123
3185
  angular: {
3124
3186
  importPath: "@uni-design-system/uni-angular",
@@ -3349,7 +3411,7 @@ emptyText="No countries found"
3349
3411
  summary: "One field for a date and a time: a thin composer seating a uni-date-input and a uni-time-input in one input-box chrome under one label, yielding one combined `'YYYY-MM-DDTHH:mm'` value.",
3350
3412
  description: "One field for a date and a time: a thin composer seating a uni-date-input and a uni-time-input in one input-box chrome under one label, yielding one combined `'YYYY-MM-DDTHH:mm'` value. The value emits only when both parts are set \u2014 a time without a day is not an answer \u2014 and clearing the date clears it. With `slotsFor`, the time part stays disabled until a day is chosen and offers exactly that day's slots: the scheduling flow in one attribute. Two honest tab stops (it is two questions); apps needing a different arrangement compose the primitives directly.",
3351
3413
  category: "forms",
3352
- version: "11.7.0",
3414
+ version: "11.9.0",
3353
3415
  bindings: {
3354
3416
  angular: {
3355
3417
  importPath: "@uni-design-system/uni-angular",
@@ -3542,7 +3604,7 @@ emptyText="No countries found"
3542
3604
  summary: "Text input that emits `change` only after the user pauses typing.",
3543
3605
  description: "Text input that emits `change` only after the user pauses typing. Wears the shared input chrome (themed color, border, typeface, focus ring) via `uni-input-box`; project adornments with the `pre-input` / `post-input` slots, matching `uni-input`'s convention. The ARIA passthrough inputs let a wrapping composite (e.g. SearchInput's combobox) annotate the real input element.",
3544
3606
  category: "forms",
3545
- version: "11.7.0",
3607
+ version: "11.9.0",
3546
3608
  bindings: {
3547
3609
  angular: {
3548
3610
  importPath: "@uni-design-system/uni-angular",
@@ -3690,7 +3752,7 @@ emptyText="No countries found"
3690
3752
  summary: "Modal dialog on the native `<dialog>` element, laid out as three rows: an optional `[dialog-header]`, the projected body, an optional `[dialog-buttons]`.",
3691
3753
  description: "Modal dialog on the native `<dialog>` element, laid out as three rows: an optional `[dialog-header]`, the projected body, an optional `[dialog-buttons]`. **The surface is never the scroll container.** It is a flex column that is `overflow: clip` on both axes; the header and buttons pin while only the body row scrolls. Unlike the drawer, which is deliberately viewport-tall, the dialog stays content-sized: it has no `height`, and grows until it hits `calc(100dvh - 2 x inset)` \u2014 the point at which the body starts to scroll. The theme's `padding` insets all three rows (which is what makes the default header read as a pill floating inside the surface); `bodyPadding` pads the scrolling row alone.",
3692
3754
  category: "feedback",
3693
- version: "11.7.0",
3755
+ version: "11.9.0",
3694
3756
  bindings: {
3695
3757
  angular: {
3696
3758
  importPath: "@uni-design-system/uni-angular",
@@ -3813,6 +3875,21 @@ uni-dialog
3813
3875
  </div>
3814
3876
  <footer dialog-buttons confirmButtonText="Save" cancelButtonText="Cancel"></footer>
3815
3877
  </dialog>`
3878
+ },
3879
+ {
3880
+ title: "Rich Head",
3881
+ framework: "angular",
3882
+ code: '<!-- Storybook story: Rich Head -->\n<button text-button variant="primary" (click)="show = true">Open dialog</button>\n<dialog uni-dialog [(show)]="show">\n<header dialog-header rich>\n <span uni-text="label" display="block" color="on-surface-variant">Custom work</span>\n <h2 uni-text="headline-small" dialog-title>Add custom work</h2>\n <span uni-text="body-2-long" display="block" color="on-surface-variant">\n Describe the piece, who it is for, and when it is needed.\n </span>\n</header>\n<div stack-layout gap="md" padding="md" [width]="420">\n <uni-input label="Piece" placeholder="What is being made" />\n <uni-input label="Client" placeholder="Who it is for" />\n</div>\n<footer dialog-buttons confirmButtonText="Add" cancelButtonText="Cancel"></footer>\n</dialog>'
3883
+ },
3884
+ {
3885
+ title: "Custom Footer",
3886
+ framework: "angular",
3887
+ code: '<!-- Storybook story: Custom Footer -->\n<button text-button variant="primary" (click)="show = true">Open dialog</button>\n<dialog uni-dialog [(show)]="show" #dialog>\n<header dialog-header>Confirm purchase order</header>\n<div box-layout padding="md" [width]="420">\n <span uni-text="body-1-long">Three line items, one vendor, delivery in two weeks.</span>\n</div>\n<footer dialog-buttons [closeOnConfirm]="false" [loading]="saving" (confirmed)="save(dialog)">\n <span dialog-footnote uni-text="caption" color="on-surface-variant">The order opens for your review.</span>\n</footer>\n</dialog>'
3888
+ },
3889
+ {
3890
+ title: "Projected Actions",
3891
+ framework: "angular",
3892
+ code: '<!-- Storybook story: Projected Actions -->\n<button text-button variant="primary" (click)="show = true">Open dialog</button>\n<dialog uni-dialog [(show)]="show" #dialog>\n<header dialog-header>Unsaved changes</header>\n<div box-layout padding="md" [width]="420">\n <span uni-text="body-1-long">Keep the draft, use the saved version, or discard both?</span>\n</div>\n<footer dialog-buttons justifyContent="flex-end">\n <button text-button variant="warn" (click)="dialog.close()">Discard</button>\n <button text-button variant="secondary" (click)="dialog.close()">Use saved</button>\n <button text-button variant="primary" (click)="dialog.close()">Keep draft</button>\n</footer>\n</dialog>'
3816
3893
  }
3817
3894
  ],
3818
3895
  guidelines: {
@@ -3822,7 +3899,8 @@ uni-dialog
3822
3899
  accessibility: [
3823
3900
  "Focus trapping and keyboard navigation (Tab, Escape, Enter)",
3824
3901
  "Screen reader announcements",
3825
- "Semantic dialog roles"
3902
+ "Semantic dialog roles",
3903
+ "A `[dialog-header]` labels the dialog; in a `rich` head, mark the headline"
3826
3904
  ]
3827
3905
  },
3828
3906
  relatedTokens: [
@@ -3841,10 +3919,10 @@ uni-dialog
3841
3919
  id: "dialog-buttons",
3842
3920
  name: "DialogButtons",
3843
3921
  status: "stable",
3844
- summary: "",
3845
- description: "",
3922
+ summary: "The dialog's pinned footer action row.",
3923
+ description: "The dialog's pinned footer action row. Empty, it renders a Confirm/Cancel pair wired to the dialog. Project your own buttons and they replace the pair while keeping the row's chrome \u2014 padding, gap, justification, divider, `stretch` and `reverseOrder`. A `[dialog-footnote]` projects on the leading edge, pushing the actions to the trailing one.",
3846
3924
  category: "feedback",
3847
- version: "11.7.0",
3925
+ version: "11.9.0",
3848
3926
  bindings: {
3849
3927
  angular: {
3850
3928
  importPath: "@uni-design-system/uni-angular",
@@ -3885,6 +3963,22 @@ uni-dialog
3885
3963
  required: false,
3886
3964
  description: ""
3887
3965
  },
3966
+ {
3967
+ name: "closeOnConfirm",
3968
+ kind: "input",
3969
+ type: "unknown",
3970
+ required: false,
3971
+ default: "true, { transform: booleanAttribute }",
3972
+ description: "Whether Confirm closes the dialog as it emits `confirmed`. On by default. Off, the caller closes when its save resolves \u2014 a dialog that confirms asynchronously stays open with its error when the save fails."
3973
+ },
3974
+ {
3975
+ name: "loading",
3976
+ kind: "input",
3977
+ type: "unknown",
3978
+ required: false,
3979
+ default: "false, { transform: booleanAttribute }",
3980
+ description: "Passed to the Confirm button: a spinner, and no second click."
3981
+ },
3888
3982
  {
3889
3983
  name: "padding",
3890
3984
  kind: "input",
@@ -3945,15 +4039,23 @@ uni-dialog
3945
4039
  id: "dialog-header",
3946
4040
  name: "DialogHeader",
3947
4041
  status: "stable",
3948
- summary: "",
3949
- description: "",
4042
+ summary: "The dialog's pinned header row, in one of two shapes: - **Title bar** (default): one line of text, set in the theme's `textRole` and aligned by `textAlign`, beside a close button.",
4043
+ description: "The dialog's pinned header row, in one of two shapes: - **Title bar** (default): one line of text, set in the theme's `textRole` and aligned by `textAlign`, beside a close button. - **Rich** (`rich`): the projection is rendered as a block \u2014 an eyebrow, a headline, a blurb \u2014 beside the close button, in its own `richColor` and `richPadding`. Mark the headline `[dialog-title]` so it alone names the dialog.",
3950
4044
  category: "feedback",
3951
- version: "11.7.0",
4045
+ version: "11.9.0",
3952
4046
  bindings: {
3953
4047
  angular: {
3954
4048
  importPath: "@uni-design-system/uni-angular",
3955
4049
  selectorOrTag: "[uni-dialog-header], [dialog-header]",
3956
4050
  api: [
4051
+ {
4052
+ name: "rich",
4053
+ kind: "input",
4054
+ type: "unknown",
4055
+ required: false,
4056
+ default: "false, { transform: booleanAttribute }",
4057
+ description: "Render the projection as a block rather than one line of text. A sheet's head \u2014 eyebrow, headline, blurb \u2014 has nowhere to go in a title bar."
4058
+ },
3957
4059
  {
3958
4060
  name: "variant",
3959
4061
  kind: "input",
@@ -3982,6 +4084,30 @@ uni-dialog
3982
4084
  },
3983
4085
  relatedTokens: []
3984
4086
  },
4087
+ {
4088
+ id: "dialog-title",
4089
+ name: "DialogTitle",
4090
+ status: "stable",
4091
+ summary: "Marks the element that names the dialog inside a rich `[dialog-header]`.",
4092
+ description: "Marks the element that names the dialog inside a rich `[dialog-header]`. A rich head projects an eyebrow, a headline and a blurb; the dialog should be labelled by the headline alone, not read all three as its name. Put this on the headline and it carries the id the dialog's `aria-labelledby` points at. Without one, the whole projected block is the label.",
4093
+ category: "feedback",
4094
+ version: "11.9.0",
4095
+ bindings: {
4096
+ angular: {
4097
+ importPath: "@uni-design-system/uni-angular",
4098
+ selectorOrTag: "[uni-dialog-title], [dialog-title]",
4099
+ api: []
4100
+ }
4101
+ },
4102
+ examples: [],
4103
+ guidelines: {
4104
+ whenToUse: "",
4105
+ dos: [],
4106
+ donts: [],
4107
+ accessibility: []
4108
+ },
4109
+ relatedTokens: []
4110
+ },
3985
4111
  {
3986
4112
  id: "divider",
3987
4113
  name: "Divider",
@@ -3989,7 +4115,7 @@ uni-dialog
3989
4115
  summary: "",
3990
4116
  description: "",
3991
4117
  category: "layout",
3992
- version: "11.7.0",
4118
+ version: "11.9.0",
3993
4119
  bindings: {
3994
4120
  angular: {
3995
4121
  importPath: "@uni-design-system/uni-angular",
@@ -4045,7 +4171,7 @@ uni-dialog
4045
4171
  summary: "",
4046
4172
  description: "",
4047
4173
  category: "directives",
4048
- version: "11.7.0",
4174
+ version: "11.9.0",
4049
4175
  bindings: {
4050
4176
  angular: {
4051
4177
  importPath: "@uni-design-system/uni-angular",
@@ -4075,9 +4201,9 @@ uni-dialog
4075
4201
  name: "Drawer",
4076
4202
  status: "stable",
4077
4203
  summary: "Drawer with two modes sharing one three-row layout: - `side` \u2014 an in-flow `<aside>` that pushes content (dashboard sidenav); opening/closing animates its width, and the divider border primitive separates it from the page.",
4078
- description: "Drawer with two modes sharing one three-row layout: - `side` \u2014 an in-flow `<aside>` that pushes content (dashboard sidenav); opening/closing animates its width, and the divider border primitive separates it from the page. - `over` \u2014 a native `<dialog>` in the top layer: focus trap, Escape and scrim backdrop come from the platform (same machinery as `uni-dialog`), sliding in from its edge. **The panel is never the scroll container.** It is a flex column of three rows \u2014 an optional `[uni-drawer-header]`, the projected body, an optional `[uni-drawer-buttons]` \u2014 and only the body scrolls. The panel itself is `overflow: clip` on both axes. That is what lets a header and a save bar pin while a long form scrolls between them, and it is why the theme's `padding` option lands on the body row rather than the panel: padding on a scrolling box scrolls away with its content. Surface, width, divider, elevation, padding, backdrop, scrim and background all resolve from `drawer` theme tokens.",
4204
+ description: 'Drawer with two modes sharing one three-row layout: - `side` \u2014 an in-flow `<aside>` that pushes content (dashboard sidenav); opening/closing animates its width, and the divider border primitive separates it from the page. - `over` \u2014 a native `<dialog>` in the top layer: focus trap, Escape and scrim backdrop come from the platform (same machinery as `uni-dialog`), sliding in from its edge. With `modal` off it is shown as a `popover="manual"` instead: still the top layer, but no focus trap, no inert page and no backdrop \u2014 a workbench beside a live document. **The panel is never the scroll container.** It is a flex column of three rows \u2014 an optional `[uni-drawer-header]`, the projected body, an optional `[uni-drawer-buttons]` \u2014 and only the body scrolls. The panel itself is `overflow: clip` on both axes. That is what lets a header and a save bar pin while a long form scrolls between them, and it is why the theme\'s `padding` option lands on the body row rather than the panel: padding on a scrolling box scrolls away with its content. Surface, width, divider, elevation, padding, backdrop, scrim and background all resolve from `drawer` theme tokens.',
4079
4205
  category: "components",
4080
- version: "11.7.0",
4206
+ version: "11.9.0",
4081
4207
  bindings: {
4082
4208
  angular: {
4083
4209
  importPath: "@uni-design-system/uni-angular",
@@ -4107,6 +4233,22 @@ uni-dialog
4107
4233
  default: "'start'",
4108
4234
  description: ""
4109
4235
  },
4236
+ {
4237
+ name: "modal",
4238
+ kind: "input",
4239
+ type: "unknown",
4240
+ required: false,
4241
+ default: "true, { transform: booleanAttribute }",
4242
+ description: 'Whether `over` mode is modal. On by default: `showModal()`, a focus trap, an inert page and a scrim. Off, the panel is a `popover="manual"` \u2014 in the top layer, so nothing can clip or cover it, but the page behind stays live: a settings panel beside the canvas it changes. Escape still asks to close through `closeRequest`; `scrim` has no backdrop to paint and is ignored; see `closeOnOutsideClick` for clicks beyond the panel.'
4243
+ },
4244
+ {
4245
+ name: "closeOnOutsideClick",
4246
+ kind: "input",
4247
+ type: "unknown",
4248
+ required: false,
4249
+ default: "false, { transform: booleanAttribute }",
4250
+ description: "Non-modal only: ask to close (`reason: 'outside'`) on a click beyond the panel. Off by default \u2014 for a workbench the canvas *is* the outside."
4251
+ },
4110
4252
  {
4111
4253
  name: "ariaLabel",
4112
4254
  kind: "input",
@@ -4235,10 +4377,32 @@ initialFocus="input"
4235
4377
  title: "Overlay",
4236
4378
  framework: "angular",
4237
4379
  code: '<!-- Storybook story: Overlay -->\n<button text-button variant="primary" size="md" (click)="open = true">Open drawer</button>\n<uni-drawer mode="over" position="start" [(open)]="open" ariaLabel="Main navigation">\n<span uni-text="title-small" display="block">Dashboard</span>\n<span uni-text="title-small" display="block">Reports</span>\n<span uni-text="title-small" display="block">Settings</span>\n<button text-button variant="secondary" size="sm" (click)="open = false">Close</button>\n</uni-drawer>'
4380
+ },
4381
+ {
4382
+ title: "Non Modal",
4383
+ framework: "angular",
4384
+ code: '<!-- Storybook story: Non Modal -->\n<div box-layout padding="md">\n<h2 uni-text="headline-small">Presentation preview</h2>\n<span uni-text="body-1-long" display="block">\n Change a setting in the panel and judge the result here, without closing it.\n</span>\n<div row-layout gap="sm" alignItems="center">\n <button text-button variant="secondary" size="md" (click)="clicks = clicks + 1">\n Still clickable\n </button>\n <span uni-text="body-2">Clicked {{ clicks }} times</span>\n</div>\n<button text-button variant="primary" size="md" (click)="open = true">Open settings</button>\n</div>\n<uni-drawer\nmode="over"\nposition="end"\n[modal]="false"\n[width]="360"\nheadline="Settings"\ninitialFocus="input"\n[(open)]="open"\n>\n<div stack-layout gap="md">\n <uni-input label="Cover title" placeholder="Spring collection" />\n <uni-input label="Subtitle" placeholder="For the Hartley residence" />\n</div>\n<div drawer-buttons confirmButtonText="Apply"></div>\n</uni-drawer>'
4385
+ },
4386
+ {
4387
+ title: "Custom Footer",
4388
+ framework: "angular",
4389
+ code: `<!-- Storybook story: Custom Footer -->
4390
+ <button text-button variant="primary" size="md" (click)="open = true">Edit quote</button>
4391
+ <uni-drawer mode="over" position="end" [width]="480" headline="Edit quote" [(open)]="open" #drawer>
4392
+ <div stack-layout gap="md">
4393
+ <uni-input label="Line" placeholder="Describe the line" />
4394
+ <uni-number-input label="Unit price" [value]="24.5" />
4395
+ </div>
4396
+ <div drawer-buttons>
4397
+ <span drawer-footnote uni-text="label">Total 1,204.00 USD</span>
4398
+ <button text-button variant="warn" size="md" (click)="drawer.requestClose('close-button')">Discard</button>
4399
+ <button text-button variant="primary" size="md" (click)="open = false">Save</button>
4400
+ </div>
4401
+ </uni-drawer>`
4238
4402
  }
4239
4403
  ],
4240
4404
  guidelines: {
4241
- whenToUse: "A panel attached to an edge of the page, in one of two modes:\n- **`side`** renders an in-flow `<aside>` that pushes page content \u2014 the classic\n dashboard sidenav. Opening and closing animates its width; a divider border primitive\n separates it from the content, and it is hidden from assistive tech while closed.\n- **`over`** renders a native `<dialog>` in the top layer: focus trapping, Escape, and\n the scrim backdrop come from the platform, and the panel slides in from its edge\n (`position`: `start` or `end`).\n`[(open)]` is two-way; Escape and backdrop clicks keep it in sync.",
4405
+ whenToUse: 'A panel attached to an edge of the page, in one of two modes:\n- **`side`** renders an in-flow `<aside>` that pushes page content \u2014 the classic\n dashboard sidenav. Opening and closing animates its width; a divider border primitive\n separates it from the content, and it is hidden from assistive tech while closed.\n- **`over`** renders a native `<dialog>` in the top layer: focus trapping, Escape, and\n the scrim backdrop come from the platform, and the panel slides in from its edge\n (`position`: `start` or `end`). With `modal` off it is a `popover="manual"`\n instead \u2014 still the top layer, but the page behind stays live.\n`[(open)]` is two-way; Escape and backdrop clicks keep it in sync.',
4242
4406
  dos: [],
4243
4407
  donts: [],
4244
4408
  accessibility: [
@@ -4246,6 +4410,7 @@ initialFocus="input"
4246
4410
  'A drawer with a header is labelled by that header\'s title via `aria-labelledby`. Without one, give it an `ariaLabel`. There is deliberately no default: a panel that inherited the name "Navigation" would announce itself as something it is not, and a wrong accessible name is worse than a missing one.',
4247
4411
  "`initialFocus` matters more here than in a dialog. The platform focuses the first focusable element, which in a panel with a header is the close button; point it at the first field instead.",
4248
4412
  "`scrim: false` keeps the drawer modal \u2014 focus is still trapped, the page behind is still inert \u2014 while leaving the backdrop transparent. Do not read a missing scrim as a non-modal drawer.",
4413
+ '`modal: false` is the non-modal drawer: a `popover="manual"` `<dialog>` with no `aria-modal`, no focus trap and a live page behind it. Escape asks to close only while focus is inside the panel; nothing else dismisses it unless `closeOnOutsideClick` is set.',
4249
4414
  "A closed side drawer is `aria-hidden`, so its links leave the accessibility tree."
4250
4415
  ]
4251
4416
  },
@@ -4266,9 +4431,9 @@ initialFocus="input"
4266
4431
  name: "DrawerButtons",
4267
4432
  status: "stable",
4268
4433
  summary: "The drawer's pinned footer action row \u2014 the save bar of an editor panel.",
4269
- description: "The drawer's pinned footer action row \u2014 the save bar of an editor panel. Sits outside the scrolling body, so the actions stay reachable however long the form is. Mirrors `[dialog-buttons]`; the difference is posture, which lives in the `drawerButtons` theme options rather than here.",
4434
+ description: "The drawer's pinned footer action row \u2014 the save bar of an editor panel. Sits outside the scrolling body, so the actions stay reachable however long the form is. Mirrors `[dialog-buttons]`; the difference is posture, which lives in the `drawerButtons` theme options rather than here. Empty, it renders a Cancel/Save pair wired to the drawer. Project your own buttons and they replace the pair while keeping the row's chrome; a `[drawer-footnote]` projects on the leading edge.",
4270
4435
  category: "primitives",
4271
- version: "11.7.0",
4436
+ version: "11.9.0",
4272
4437
  bindings: {
4273
4438
  angular: {
4274
4439
  importPath: "@uni-design-system/uni-angular",
@@ -4309,6 +4474,14 @@ initialFocus="input"
4309
4474
  required: false,
4310
4475
  description: ""
4311
4476
  },
4477
+ {
4478
+ name: "loading",
4479
+ kind: "input",
4480
+ type: "unknown",
4481
+ required: false,
4482
+ default: "false, { transform: booleanAttribute }",
4483
+ description: "Passed to the Save button: a spinner, and no second click."
4484
+ },
4312
4485
  {
4313
4486
  name: "padding",
4314
4487
  kind: "input",
@@ -4365,7 +4538,7 @@ initialFocus="input"
4365
4538
  summary: "The drawer's pinned header row: a title, and optionally a close button.",
4366
4539
  description: "The drawer's pinned header row: a title, and optionally a close button. Sits outside the scrolling body, so it stays put while the form beneath it moves. Reached either by projecting it \u2014 `<div uni-drawer-header>` \u2014 or implicitly, by giving `uni-drawer` a `headline`, in which case the drawer renders one of these itself.",
4367
4540
  category: "components",
4368
- version: "11.7.0",
4541
+ version: "11.9.0",
4369
4542
  bindings: {
4370
4543
  angular: {
4371
4544
  importPath: "@uni-design-system/uni-angular",
@@ -4413,7 +4586,7 @@ initialFocus="input"
4413
4586
  summary: "",
4414
4587
  description: "",
4415
4588
  category: "components",
4416
- version: "11.7.0",
4589
+ version: "11.9.0",
4417
4590
  bindings: {
4418
4591
  angular: {
4419
4592
  importPath: "@uni-design-system/uni-angular",
@@ -4547,7 +4720,7 @@ initialFocus="input"
4547
4720
  summary: "",
4548
4721
  description: "",
4549
4722
  category: "layout",
4550
- version: "11.7.0",
4723
+ version: "11.9.0",
4551
4724
  bindings: {
4552
4725
  angular: {
4553
4726
  importPath: "@uni-design-system/uni-angular",
@@ -4654,7 +4827,7 @@ initialFocus="input"
4654
4827
  summary: "",
4655
4828
  description: "",
4656
4829
  category: "layout",
4657
- version: "11.7.0",
4830
+ version: "11.9.0",
4658
4831
  bindings: {
4659
4832
  angular: {
4660
4833
  importPath: "@uni-design-system/uni-angular",
@@ -4725,7 +4898,7 @@ initialFocus="input"
4725
4898
  summary: "Trigger for a {@link UniExpandComponent} region.",
4726
4899
  description: "Trigger for a {@link UniExpandComponent} region. Two shapes, chosen by whether `label` is set: - **Icon only** (default) \u2014 the bare chevron, sized for a Card Header. - **Labelled** \u2014 chevron plus a label and optional muted sublabel, as a single full-width button. Most real disclosures need a name for the section, and building that row by hand is the thing this saves; it also makes the label the button's accessible name rather than adjacent text.",
4727
4900
  category: "layout",
4728
- version: "11.7.0",
4901
+ version: "11.9.0",
4729
4902
  bindings: {
4730
4903
  angular: {
4731
4904
  importPath: "@uni-design-system/uni-angular",
@@ -4810,7 +4983,7 @@ initialFocus="input"
4810
4983
  summary: "",
4811
4984
  description: "",
4812
4985
  category: "forms",
4813
- version: "11.7.0",
4986
+ version: "11.9.0",
4814
4987
  bindings: {
4815
4988
  angular: {
4816
4989
  importPath: "@uni-design-system/uni-angular",
@@ -4968,7 +5141,7 @@ initialFocus="input"
4968
5141
  summary: "",
4969
5142
  description: "",
4970
5143
  category: "layout",
4971
- version: "11.7.0",
5144
+ version: "11.9.0",
4972
5145
  bindings: {
4973
5146
  angular: {
4974
5147
  importPath: "@uni-design-system/uni-angular",
@@ -5065,7 +5238,7 @@ initialFocus="input"
5065
5238
  summary: "",
5066
5239
  description: "",
5067
5240
  category: "layout",
5068
- version: "11.7.0",
5241
+ version: "11.9.0",
5069
5242
  bindings: {
5070
5243
  angular: {
5071
5244
  importPath: "@uni-design-system/uni-angular",
@@ -5097,7 +5270,7 @@ initialFocus="input"
5097
5270
  summary: "",
5098
5271
  description: "",
5099
5272
  category: "primitives",
5100
- version: "11.7.0",
5273
+ version: "11.9.0",
5101
5274
  bindings: {
5102
5275
  angular: {
5103
5276
  importPath: "@uni-design-system/uni-angular",
@@ -5157,7 +5330,7 @@ initialFocus="input"
5157
5330
  summary: "",
5158
5331
  description: "",
5159
5332
  category: "primitives",
5160
- version: "11.7.0",
5333
+ version: "11.9.0",
5161
5334
  bindings: {
5162
5335
  angular: {
5163
5336
  importPath: "@uni-design-system/uni-angular",
@@ -5270,7 +5443,7 @@ initialFocus="input"
5270
5443
  summary: "A button that lives inside a sentence.",
5271
5444
  description: "A button that lives inside a sentence. Every other button in the library owns a box. Even `ghost` is a flex box with a hit area, horizontal padding and a type scale of its own, so dropping one into a sentence takes it out of the run of text entirely. This one inherits that type \u2014 family, size, weight, line height and colour \u2014 and adds no padding, so a paragraph reads as one continuous run with an action in the middle of it. It is always a real `<button>`: it can *look* like a link (`underline`, `link`) without claiming to be navigation, so Enter and Space activate it and assistive tech announces a button rather than an unfollowable link. A glyph may sit alongside the label without disturbing that: it is sized in `em`, so it scales with the type it lands in rather than pinning a px size into someone else's paragraph. One limit comes from the element itself. Browsers blockify a `<button>` to `inline-block` whatever `display` it asks for, so the control is an atomic inline box: its own label wraps inside it, but the run cannot split across a line break the way the words around it do. `display: contents` would buy that at the cost of the button being focusable at all, which is not a trade worth making \u2014 keep labels to a few words, which is what an inline action wants anyway.",
5272
5445
  category: "primitives",
5273
- version: "11.7.0",
5446
+ version: "11.9.0",
5274
5447
  bindings: {
5275
5448
  angular: {
5276
5449
  importPath: "@uni-design-system/uni-angular",
@@ -5385,7 +5558,7 @@ initialFocus="input"
5385
5558
  summary: "",
5386
5559
  description: "",
5387
5560
  category: "forms",
5388
- version: "11.7.0",
5561
+ version: "11.9.0",
5389
5562
  bindings: {
5390
5563
  angular: {
5391
5564
  importPath: "@uni-design-system/uni-angular",
@@ -5685,7 +5858,7 @@ initialFocus="input"
5685
5858
  summary: "",
5686
5859
  description: "",
5687
5860
  category: "forms",
5688
- version: "11.7.0",
5861
+ version: "11.9.0",
5689
5862
  bindings: {
5690
5863
  angular: {
5691
5864
  importPath: "@uni-design-system/uni-angular",
@@ -5814,7 +5987,7 @@ initialFocus="input"
5814
5987
  summary: "",
5815
5988
  description: "",
5816
5989
  category: "components",
5817
- version: "11.7.0",
5990
+ version: "11.9.0",
5818
5991
  bindings: {
5819
5992
  angular: {
5820
5993
  importPath: "@uni-design-system/uni-angular",
@@ -5884,7 +6057,7 @@ initialFocus="input"
5884
6057
  summary: "",
5885
6058
  description: "",
5886
6059
  category: "layout",
5887
- version: "11.7.0",
6060
+ version: "11.9.0",
5888
6061
  bindings: {
5889
6062
  angular: {
5890
6063
  importPath: "@uni-design-system/uni-angular",
@@ -5988,7 +6161,7 @@ initialFocus="input"
5988
6161
  summary: "",
5989
6162
  description: "",
5990
6163
  category: "layout",
5991
- version: "11.7.0",
6164
+ version: "11.9.0",
5992
6165
  bindings: {
5993
6166
  angular: {
5994
6167
  importPath: "@uni-design-system/uni-angular",
@@ -6070,7 +6243,7 @@ initialFocus="input"
6070
6243
  summary: "",
6071
6244
  description: "",
6072
6245
  category: "forms",
6073
- version: "11.7.0",
6246
+ version: "11.9.0",
6074
6247
  bindings: {
6075
6248
  angular: {
6076
6249
  importPath: "@uni-design-system/uni-angular",
@@ -6164,7 +6337,7 @@ initialFocus="input"
6164
6337
  summary: "",
6165
6338
  description: "",
6166
6339
  category: "forms",
6167
- version: "11.7.0",
6340
+ version: "11.9.0",
6168
6341
  bindings: {
6169
6342
  angular: {
6170
6343
  importPath: "@uni-design-system/uni-angular",
@@ -6343,7 +6516,7 @@ initialFocus="input"
6343
6516
  summary: "",
6344
6517
  description: "",
6345
6518
  category: "feedback",
6346
- version: "11.7.0",
6519
+ version: "11.9.0",
6347
6520
  bindings: {
6348
6521
  angular: {
6349
6522
  importPath: "@uni-design-system/uni-angular",
@@ -6603,7 +6776,7 @@ initialFocus="input"
6603
6776
  summary: "",
6604
6777
  description: "",
6605
6778
  category: "feedback",
6606
- version: "11.7.0",
6779
+ version: "11.9.0",
6607
6780
  bindings: {
6608
6781
  angular: {
6609
6782
  importPath: "@uni-design-system/uni-angular",
@@ -6627,7 +6800,7 @@ initialFocus="input"
6627
6800
  summary: "Numeric field with locale-aware parsing, `Intl` formatting on commit, prefix/suffix adornments and steppers that hold to repeat.",
6628
6801
  description: 'Numeric field with locale-aware parsing, `Intl` formatting on commit, prefix/suffix adornments and steppers that hold to repeat. Not `<input type="number">`, and the first reason is a data-loss bug: per the HTML value sanitization algorithm, a number input whose text is not a valid floating-point number reports `value === \'\'`. Type `12,50` as most of Europe does, or paste `1,234.56` from a spreadsheet, and the app reads an empty field. This is `type="text"` with `role="spinbutton"`, which is the only way to keep the user\'s malformed text on screen and tell them about it. Chrome comes from `uni-input-box`, so error, disabled and focus states match every other field. All arithmetic runs on the cdk\'s exact decimal helpers.',
6629
6802
  category: "forms",
6630
- version: "11.7.0",
6803
+ version: "11.9.0",
6631
6804
  bindings: {
6632
6805
  angular: {
6633
6806
  importPath: "@uni-design-system/uni-angular",
@@ -7061,7 +7234,7 @@ initialFocus="input"
7061
7234
  summary: "Two linked numeric fields in one chrome, with one `{ start, end }` value \u2014 price filters, thresholds, tolerances.",
7062
7235
  description: "Two linked numeric fields in one chrome, with one `{ start, end }` value \u2014 price filters, thresholds, tolerances. `start`/`end` deliberately match `UniDateRange`, so the library has one range vocabulary, and they avoid colliding with the `min`/`max` **inputs**, which mean the fence rather than the value. It owns its commit path rather than nesting two `uni-number-input`s, because the two behaviours the spec asks for need *different* bounds: a stepper must be fenced at the other end, while a typed commit must reach the parent un-clamped so a backwards range can be swapped instead of destroyed. A child field applies one bound pair to both. The arithmetic, parsing and formatting are still the cdk's, shared with every other numeric control.",
7063
7236
  category: "forms",
7064
- version: "11.7.0",
7237
+ version: "11.9.0",
7065
7238
  bindings: {
7066
7239
  angular: {
7067
7240
  importPath: "@uni-design-system/uni-angular",
@@ -7352,7 +7525,7 @@ initialFocus="input"
7352
7525
  summary: "",
7353
7526
  description: "",
7354
7527
  category: "data",
7355
- version: "11.7.0",
7528
+ version: "11.9.0",
7356
7529
  bindings: {
7357
7530
  angular: {
7358
7531
  importPath: "@uni-design-system/uni-angular",
@@ -7453,7 +7626,7 @@ initialFocus="input"
7453
7626
  summary: "Anchored, top-layer panel on the native `popover` element \u2014 the browser owns positioning (CSS anchor positioning), stacking, and, in rich mode, light dismissal.",
7454
7627
  description: 'Anchored, top-layer panel on the native `popover` element \u2014 the browser owns positioning (CSS anchor positioning), stacking, and, in rich mode, light dismissal. Two modes share one implementation: - `rich` (default): a click-toggled disclosure. The projected `[trigger]` carries `aria-expanded`/`aria-controls`; with no trigger content the app drives `open` and no element claims controller ARIA. Focus stays on the trigger (APG disclosure) unless the panel marks an `[autofocus]` field, and returns to the trigger on close. - `tooltip`: hover/focus-triggered, `role="tooltip"` + `aria-describedby`, WCAG 1.4.13 dismissable/hoverable/persistent. Content must not contain focusable elements. Anchoring and control are separate: `anchor` re-anchors the panel to any element (or id) while the trigger keeps the disclosure semantics.',
7455
7628
  category: "layout",
7456
- version: "11.7.0",
7629
+ version: "11.9.0",
7457
7630
  bindings: {
7458
7631
  angular: {
7459
7632
  importPath: "@uni-design-system/uni-angular",
@@ -7645,7 +7818,7 @@ initialFocus="input"
7645
7818
  summary: "",
7646
7819
  description: "",
7647
7820
  category: "feedback",
7648
- version: "11.7.0",
7821
+ version: "11.9.0",
7649
7822
  bindings: {
7650
7823
  angular: {
7651
7824
  importPath: "@uni-design-system/uni-angular",
@@ -7709,7 +7882,7 @@ initialFocus="input"
7709
7882
  summary: "",
7710
7883
  description: "",
7711
7884
  category: "feedback",
7712
- version: "11.7.0",
7885
+ version: "11.9.0",
7713
7886
  bindings: {
7714
7887
  angular: {
7715
7888
  importPath: "@uni-design-system/uni-angular",
@@ -7781,7 +7954,7 @@ initialFocus="input"
7781
7954
  summary: "`\u2212 3 +` for cart lines, table cells and seat counts: the numeric core with no field chrome, no label and no room for either.",
7782
7955
  description: '`\u2212 3 +` for cart lines, table cells and seat counts: the numeric core with no field chrome, no label and no room for either. A separate component rather than a `chrome="bare"` flag on `uni-number-input`, because this control is defined by what it does *not* have \u2014 presets, affixes, expressions, four stepper layouts \u2014 and eight inputs are easier to write correctly than forty with a list of which ones to leave alone. The arithmetic, parsing and hold-to-repeat are the cdk\'s, shared with the field, so `1,200` and the keyboard map behave identically in both. The middle stays a real input by default: typing `12` beats tapping `+` eleven times. `editable=false` is for read-mostly tables.',
7783
7956
  category: "forms",
7784
- version: "11.7.0",
7957
+ version: "11.9.0",
7785
7958
  bindings: {
7786
7959
  angular: {
7787
7960
  importPath: "@uni-design-system/uni-angular",
@@ -7984,7 +8157,7 @@ initialFocus="input"
7984
8157
  summary: "",
7985
8158
  description: "",
7986
8159
  category: "forms",
7987
- version: "11.7.0",
8160
+ version: "11.9.0",
7988
8161
  bindings: {
7989
8162
  angular: {
7990
8163
  importPath: "@uni-design-system/uni-angular",
@@ -8213,7 +8386,7 @@ initialFocus="input"
8213
8386
  summary: "Content for each of a radio group's options, in place of the plain label string.",
8214
8387
  description: 'Content for each of a radio group\'s options, in place of the plain label string. A group renders N labels from an `options` array, so it cannot take `<ng-content />` the way `uni-checkbox` and `uni-toggle` do \u2014 there is no single slot to project into. A template is the shape that survives the repetition: it is instantiated once per option and handed that option, so a row can carry a description, a price or a badge and still be part of the `<label>` that drives the input. ```html <uni-radio [options]="plans"> <ng-template uniRadioOption let-option> <span uni-text="body-2-long">{{ option.label }}</span> </ng-template> </uni-radio> ```',
8215
8388
  category: "forms",
8216
- version: "11.7.0",
8389
+ version: "11.9.0",
8217
8390
  bindings: {
8218
8391
  angular: {
8219
8392
  importPath: "@uni-design-system/uni-angular",
@@ -8237,7 +8410,7 @@ initialFocus="input"
8237
8410
  summary: "",
8238
8411
  description: "",
8239
8412
  category: "directives",
8240
- version: "11.7.0",
8413
+ version: "11.9.0",
8241
8414
  bindings: {
8242
8415
  angular: {
8243
8416
  importPath: "@uni-design-system/uni-angular",
@@ -8261,7 +8434,7 @@ initialFocus="input"
8261
8434
  summary: "",
8262
8435
  description: "",
8263
8436
  category: "layout",
8264
- version: "11.7.0",
8437
+ version: "11.9.0",
8265
8438
  bindings: {
8266
8439
  angular: {
8267
8440
  importPath: "@uni-design-system/uni-angular",
@@ -8316,7 +8489,7 @@ initialFocus="input"
8316
8489
  summary: "Native scroll area with theme-driven scrollbar styling.",
8317
8490
  description: "Native scroll area with theme-driven scrollbar styling. Scrollbars are styled entirely through Emotion-generated CSS: `::-webkit-scrollbar` rules cover Chromium/Safari, with a `scrollbar-width`/`scrollbar-color` fallback for Firefox.",
8318
8491
  category: "layout",
8319
- version: "11.7.0",
8492
+ version: "11.9.0",
8320
8493
  bindings: {
8321
8494
  angular: {
8322
8495
  importPath: "@uni-design-system/uni-angular",
@@ -8483,7 +8656,7 @@ initialFocus="input"
8483
8656
  summary: "Generic search field: shared input chrome with a leading magnifier, a clear button while there's a query, Enter to submit, and optional type-ahead \u2014 pass `suggestions` (refresh them from `change`) and the field becomes an ARIA combobox with a keyboard-navigable listbox.",
8484
8657
  description: "Generic search field: shared input chrome with a leading magnifier, a clear button while there's a query, Enter to submit, and optional type-ahead \u2014 pass `suggestions` (refresh them from `change`) and the field becomes an ARIA combobox with a keyboard-navigable listbox. Escape closes the list first, then clears the query.",
8485
8658
  category: "forms",
8486
- version: "11.7.0",
8659
+ version: "11.9.0",
8487
8660
  bindings: {
8488
8661
  angular: {
8489
8662
  importPath: "@uni-design-system/uni-angular",
@@ -8618,7 +8791,7 @@ initialFocus="input"
8618
8791
  summary: "",
8619
8792
  description: "",
8620
8793
  category: "forms",
8621
- version: "11.7.0",
8794
+ version: "11.9.0",
8622
8795
  bindings: {
8623
8796
  angular: {
8624
8797
  importPath: "@uni-design-system/uni-angular",
@@ -8790,7 +8963,7 @@ initialFocus="input"
8790
8963
  summary: "Loading placeholder painted with surface tokens.",
8791
8964
  description: "Loading placeholder painted with surface tokens. `text` renders one or more lines (the last line shortened, as real text would be), `rect` and `circle` render fixed shapes. The shimmer only animates when the user allows motion; it degrades to static blocks under `prefers-reduced-motion`. Color and radius are theme options with per-instance overrides, because one app routinely needs several: skeletons on a card and on the page background want different tints, and a pill placeholder wants a different corner than the text bars beside it.",
8792
8965
  category: "components",
8793
- version: "11.7.0",
8966
+ version: "11.9.0",
8794
8967
  bindings: {
8795
8968
  angular: {
8796
8969
  importPath: "@uni-design-system/uni-angular",
@@ -8941,7 +9114,7 @@ initialFocus="input"
8941
9114
  summary: "Bounded numeric input by pointer, for values where the *position* is the information: volume, opacity, weightings, price filters.",
8942
9115
  description: "Bounded numeric input by pointer, for values where the *position* is the information: volume, opacity, weightings, price filters. Custom thumbs rather than `<input type=\"range\">`, which the previous version used: one native range input cannot carry two thumbs, marks or a tooltip, and a second component for the range case would mean two keyboard maps to keep in step. The step model and the keyboard map are the cdk's, shared with the numeric fields, so nothing new is learned moving between them. All arithmetic on values runs through the cdk's exact decimal helpers \u2014 stepping `0.1` never yields `0.30000000000000004`. Only pointer *positions* use floats, and they are snapped to the grid before becoming a value.",
8943
9116
  category: "forms",
8944
- version: "11.7.0",
9117
+ version: "11.9.0",
8945
9118
  bindings: {
8946
9119
  angular: {
8947
9120
  importPath: "@uni-design-system/uni-angular",
@@ -9218,7 +9391,7 @@ initialFocus="input"
9218
9391
  summary: "",
9219
9392
  description: "",
9220
9393
  category: "feedback",
9221
- version: "11.7.0",
9394
+ version: "11.9.0",
9222
9395
  bindings: {
9223
9396
  angular: {
9224
9397
  importPath: "@uni-design-system/uni-angular",
@@ -9330,7 +9503,7 @@ initialFocus="input"
9330
9503
  summary: "",
9331
9504
  description: "",
9332
9505
  category: "data",
9333
- version: "11.7.0",
9506
+ version: "11.9.0",
9334
9507
  bindings: {
9335
9508
  angular: {
9336
9509
  importPath: "@uni-design-system/uni-angular",
@@ -9404,7 +9577,7 @@ initialFocus="input"
9404
9577
  summary: "",
9405
9578
  description: "",
9406
9579
  category: "layout",
9407
- version: "11.7.0",
9580
+ version: "11.9.0",
9408
9581
  bindings: {
9409
9582
  angular: {
9410
9583
  importPath: "@uni-design-system/uni-angular",
@@ -9459,7 +9632,7 @@ initialFocus="input"
9459
9632
  summary: 'KPI stat tile: muted label, large value (numbers auto-compact: 48234 \u2192 "48.2K"), an optional delta whose ink is decided by *direction \xD7 whether up is good* (never direction alone \u2014 churn going down is good news), and an optional decorative sparkline.',
9460
9633
  description: 'KPI stat tile: muted label, large value (numbers auto-compact: 48234 \u2192 "48.2K"), an optional delta whose ink is decided by *direction \xD7 whether up is good* (never direction alone \u2014 churn going down is good news), and an optional decorative sparkline. Frame, typography and inks are all `stat` theme tokens.',
9461
9634
  category: "components",
9462
- version: "11.7.0",
9635
+ version: "11.9.0",
9463
9636
  bindings: {
9464
9637
  angular: {
9465
9638
  importPath: "@uni-design-system/uni-angular",
@@ -9577,7 +9750,7 @@ initialFocus="input"
9577
9750
  summary: "",
9578
9751
  description: "",
9579
9752
  category: "primitives",
9580
- version: "11.7.0",
9753
+ version: "11.9.0",
9581
9754
  bindings: {
9582
9755
  angular: {
9583
9756
  importPath: "@uni-design-system/uni-angular",
@@ -9666,7 +9839,7 @@ initialFocus="input"
9666
9839
  summary: "One tab inside `uni-tabs`: a label for the tablist plus projected panel content.",
9667
9840
  description: "One tab inside `uni-tabs`: a label for the tablist plus projected panel content. Content is captured in a template and only instantiated while the tab is selected, so inactive panels cost nothing.",
9668
9841
  category: "components",
9669
- version: "11.7.0",
9842
+ version: "11.9.0",
9670
9843
  bindings: {
9671
9844
  angular: {
9672
9845
  importPath: "@uni-design-system/uni-angular",
@@ -9706,7 +9879,7 @@ initialFocus="input"
9706
9879
  summary: "WAI-ARIA tabs: roving tabindex, automatic activation (arrow keys move focus and select), Home/End, disabled tabs skipped.",
9707
9880
  description: "WAI-ARIA tabs: roving tabindex, automatic activation (arrow keys move focus and select), Home/End, disabled tabs skipped. Only the selected panel is instantiated. All styling resolves from `tabs` theme option tokens. A tab switch is softened by the `panelMotion` option: the incoming content fades in while the panel animates from the outgoing content's height to its own. The new content is live from the first frame \u2014 nothing waits on the animation.",
9708
9881
  category: "components",
9709
- version: "11.7.0",
9882
+ version: "11.9.0",
9710
9883
  bindings: {
9711
9884
  angular: {
9712
9885
  importPath: "@uni-design-system/uni-angular",
@@ -9794,7 +9967,7 @@ initialFocus="input"
9794
9967
  summary: "Compact chip for categories, states, filters and tokens.",
9795
9968
  description: "Compact chip for categories, states, filters and tokens. Two orthogonal style axes: `variant` picks the colour role and `tone` picks the archetype (soft / solid / outline). Both live in the theme's `tag` entry, so a theme restyles every chip in the app without touching markup. Two state classes ride alongside the tone class for the same reason: `tag-selected` and `tag-interactive` let the theme paint selection and hover beside the colours they belong to, instead of an app swapping `tone` by hand on every chip. Structurally a chip is **body + trailing action as siblings**, never nested buttons: an interactive chip whose body is a `<button>` cannot contain the remove `<button>` (invalid HTML, and the inner control becomes unreachable for keyboard users). Both stay independently operable.",
9796
9969
  category: "data",
9797
- version: "11.7.0",
9970
+ version: "11.9.0",
9798
9971
  bindings: {
9799
9972
  angular: {
9800
9973
  importPath: "@uni-design-system/uni-angular",
@@ -10172,7 +10345,7 @@ initialFocus="input"
10172
10345
  summary: "A row of chips the user picks from: filters, facets, a set of labels.",
10173
10346
  description: "A row of chips the user picks from: filters, facets, a set of labels. The group **renders its own chips** from `items` rather than projecting them. That is what lets it own the things an app was otherwise wiring per chip \u2014 which one is selected, which one holds the tab stop \u2014 since a parent cannot write a projected child's inputs. `uni-tag` is unchanged by this component; `controlTabIndex` was already its hook for a composite that manages focus. Keyboard model is the toolbar pattern: one tab stop for the whole group, and the arrow keys move within it. Twelve filter chips should cost one Tab to pass, not twelve.",
10174
10347
  category: "data",
10175
- version: "11.7.0",
10348
+ version: "11.9.0",
10176
10349
  bindings: {
10177
10350
  angular: {
10178
10351
  importPath: "@uni-design-system/uni-angular",
@@ -10370,7 +10543,7 @@ initialFocus="input"
10370
10543
  summary: "",
10371
10544
  description: "",
10372
10545
  category: "forms",
10373
- version: "11.7.0",
10546
+ version: "11.9.0",
10374
10547
  bindings: {
10375
10548
  angular: {
10376
10549
  importPath: "@uni-design-system/uni-angular",
@@ -10821,7 +10994,7 @@ placeholder="Name or address\u2026"
10821
10994
  summary: "The typography primitive, applied as an attribute to any element so semantics stay yours.",
10822
10995
  description: 'The typography primitive, applied as an attribute to any element so semantics stay yours. The attribute value is the typeface: `<h1 uni-text="display-small">`, `<span uni-text="caption">`, dynamic via `[uni-text]="role()"`. With no value, the typeface is inferred from the host element (h1 \u2192 headline-large, p \u2192 body-1-long, \u2026), falling back to `title-small`; the `typeface` input remains as an explicit override. It is a directive, so it stacks with anything else on the element \u2014 a layout attribute (`<div stack-layout uni-text="title-small">`) or a component\'s own host \u2014 rather than colliding with it.',
10823
10996
  category: "primitives",
10824
- version: "11.7.0",
10997
+ version: "11.9.0",
10825
10998
  bindings: {
10826
10999
  angular: {
10827
11000
  importPath: "@uni-design-system/uni-angular",
@@ -10931,7 +11104,7 @@ placeholder="Name or address\u2026"
10931
11104
  summary: "",
10932
11105
  description: "",
10933
11106
  category: "forms",
10934
- version: "11.7.0",
11107
+ version: "11.9.0",
10935
11108
  bindings: {
10936
11109
  angular: {
10937
11110
  importPath: "@uni-design-system/uni-angular",
@@ -11146,7 +11319,7 @@ placeholder="Name or address\u2026"
11146
11319
  summary: "",
11147
11320
  description: "",
11148
11321
  category: "primitives",
11149
- version: "11.7.0",
11322
+ version: "11.9.0",
11150
11323
  bindings: {
11151
11324
  angular: {
11152
11325
  importPath: "@uni-design-system/uni-angular",
@@ -11176,7 +11349,7 @@ placeholder="Name or address\u2026"
11176
11349
  summary: "Drop-in switcher for the themes registered via `UNI_THEMES`: a select over `ThemeService.themeOptions` that applies the choice through `selectTheme` (so it persists across reloads like any other theme selection).",
11177
11350
  description: "Drop-in switcher for the themes registered via `UNI_THEMES`: a select over `ThemeService.themeOptions` that applies the choice through `selectTheme` (so it persists across reloads like any other theme selection).",
11178
11351
  category: "components",
11179
- version: "11.7.0",
11352
+ version: "11.9.0",
11180
11353
  bindings: {
11181
11354
  angular: {
11182
11355
  importPath: "@uni-design-system/uni-angular",
@@ -11234,7 +11407,7 @@ placeholder="Name or address\u2026"
11234
11407
  summary: "Time field: a combobox over time options \u2014 the same listbox contract as uni-search-input and uni-tag-input.",
11235
11408
  description: "Time field: a combobox over time options \u2014 the same listbox contract as uni-search-input and uni-tag-input. Type `3p`, `930` or `15:00`, or pick `3:00 PM` from the list; the form always gets 24-hour `'HH:mm'` (`hour12` affects display only). The list is assistive, not exhaustive: any parseable time commits, unless `slots` pins the choices (a slot picker) \u2014 then a typed time must match one. Unreadable or unavailable text stays in the field, flagged, with a `rejected` event.",
11236
11409
  category: "forms",
11237
- version: "11.7.0",
11410
+ version: "11.9.0",
11238
11411
  bindings: {
11239
11412
  angular: {
11240
11413
  importPath: "@uni-design-system/uni-angular",
@@ -11449,7 +11622,7 @@ placeholder="Name or address\u2026"
11449
11622
  summary: "",
11450
11623
  description: "",
11451
11624
  category: "forms",
11452
- version: "11.7.0",
11625
+ version: "11.9.0",
11453
11626
  bindings: {
11454
11627
  angular: {
11455
11628
  importPath: "@uni-design-system/uni-angular",
@@ -11711,7 +11884,7 @@ placeholder="Name or address\u2026"
11711
11884
  summary: "",
11712
11885
  description: "",
11713
11886
  category: "feedback",
11714
- version: "11.7.0",
11887
+ version: "11.9.0",
11715
11888
  bindings: {
11716
11889
  angular: {
11717
11890
  importPath: "@uni-design-system/uni-angular",
@@ -11799,7 +11972,7 @@ placeholder="Name or address\u2026"
11799
11972
  summary: 'A thin sequencer over one `uni-callout`: steps spotlight their targets, a footer walks Next/Back with dots-or-fraction progress, and `advanceOn` gates a step behind an interaction with its target (auto-advancing for clicks, unlocking Next otherwise \u2014 announced through one `role="status"` region).',
11800
11973
  description: 'A thin sequencer over one `uni-callout`: steps spotlight their targets, a footer walks Next/Back with dots-or-fraction progress, and `advanceOn` gates a step behind an interaction with its target (auto-advancing for clicks, unlocking Next otherwise \u2014 announced through one `role="status"` region). Escape or the close button skips the tour and reports the step. `active` is a two-way model, so a tour is deep-linkable and inspectable; steps whose declared target cannot be resolved are skipped (with a dev warning) in the direction of travel rather than erroring.',
11801
11974
  category: "components",
11802
- version: "11.7.0",
11975
+ version: "11.9.0",
11803
11976
  bindings: {
11804
11977
  angular: {
11805
11978
  importPath: "@uni-design-system/uni-angular",
@@ -11933,7 +12106,7 @@ placeholder="Name or address\u2026"
11933
12106
  summary: "",
11934
12107
  description: "",
11935
12108
  category: "layout",
11936
- version: "11.7.0",
12109
+ version: "11.9.0",
11937
12110
  bindings: {
11938
12111
  angular: {
11939
12112
  importPath: "@uni-design-system/uni-angular",
@@ -14595,6 +14768,18 @@ placeholder="Name or address\u2026"
14595
14768
  DarkTheme: "md"
14596
14769
  }
14597
14770
  },
14771
+ {
14772
+ id: "dialogHeader.behavior.richPadding",
14773
+ value: "md",
14774
+ type: "string",
14775
+ kind: "behavioral",
14776
+ target: "component-prop",
14777
+ appliesTo: "dialogHeader",
14778
+ themeValues: {
14779
+ LightTheme: "md",
14780
+ DarkTheme: "md"
14781
+ }
14782
+ },
14598
14783
  {
14599
14784
  id: "select.behavior.toggleIcon",
14600
14785
  value: "chevronDown",
@@ -16995,6 +17180,30 @@ placeholder="Name or address\u2026"
16995
17180
  DarkTheme: 40
16996
17181
  }
16997
17182
  },
17183
+ {
17184
+ id: "dataTable.behavior.selectionColumnWidth",
17185
+ value: 40,
17186
+ type: "number",
17187
+ kind: "behavioral",
17188
+ target: "component-prop",
17189
+ appliesTo: "dataTable",
17190
+ themeValues: {
17191
+ LightTheme: 40,
17192
+ DarkTheme: 40
17193
+ }
17194
+ },
17195
+ {
17196
+ id: "dataTable.behavior.selectionCheckboxSize",
17197
+ value: "sm",
17198
+ type: "string",
17199
+ kind: "behavioral",
17200
+ target: "component-prop",
17201
+ appliesTo: "dataTable",
17202
+ themeValues: {
17203
+ LightTheme: "sm",
17204
+ DarkTheme: "sm"
17205
+ }
17206
+ },
16998
17207
  {
16999
17208
  id: "notificationBadge.behavior.borderRadius",
17000
17209
  value: "sm",
@@ -18232,7 +18441,8 @@ placeholder="Name or address\u2026"
18232
18441
  textRole: "title-large",
18233
18442
  textAlign: "center",
18234
18443
  closeButtonIcon: "close",
18235
- closeButtonSize: "md"
18444
+ closeButtonSize: "md",
18445
+ richPadding: "md"
18236
18446
  },
18237
18447
  select: {
18238
18448
  toggleIcon: "chevronDown",
@@ -18494,7 +18704,9 @@ placeholder="Name or address\u2026"
18494
18704
  rowHoverColor: "primary-container",
18495
18705
  loadingOverlayColor: "scrim",
18496
18706
  loadingSpinnerColor: "primary",
18497
- loadingSpinnerSize: 40
18707
+ loadingSpinnerSize: 40,
18708
+ selectionColumnWidth: 40,
18709
+ selectionCheckboxSize: "sm"
18498
18710
  },
18499
18711
  notificationBadge: {
18500
18712
  borderRadius: "sm",
@@ -18865,7 +19077,8 @@ placeholder="Name or address\u2026"
18865
19077
  textRole: "title-large",
18866
19078
  textAlign: "center",
18867
19079
  closeButtonIcon: "close",
18868
- closeButtonSize: "md"
19080
+ closeButtonSize: "md",
19081
+ richPadding: "md"
18869
19082
  },
18870
19083
  select: {
18871
19084
  toggleIcon: "chevronDown",
@@ -19127,7 +19340,9 @@ placeholder="Name or address\u2026"
19127
19340
  rowHoverColor: "primary-container",
19128
19341
  loadingOverlayColor: "scrim",
19129
19342
  loadingSpinnerColor: "primary",
19130
- loadingSpinnerSize: 40
19343
+ loadingSpinnerSize: 40,
19344
+ selectionColumnWidth: 40,
19345
+ selectionCheckboxSize: "sm"
19131
19346
  },
19132
19347
  notificationBadge: {
19133
19348
  borderRadius: "sm",
@@ -19240,6 +19455,30 @@ placeholder="Name or address\u2026"
19240
19455
  {
19241
19456
  package: "@uni-design-system/uni-angular",
19242
19457
  releases: [
19458
+ {
19459
+ version: "11.9.0",
19460
+ entries: [
19461
+ {
19462
+ bump: "minor",
19463
+ title: "`uni-data-table` gains a real selection column and an id-keyed, bindable detail row; the datasources gain a row identity.",
19464
+ body: "- **`rowId` on the datasources** (`new UniRecordDatasource(rows, { rowId: (row) => row.id })`, also a third argument on `UniServerSideDatasource`, and settable afterwards): a stable identity for a row. Without one, rows are compared by reference, which never matches a row rebuilt from a fresh fetch \u2014 a realtime update that replaced the records emptied the selection. With one, `isSelected`, `toggleSelection` and the new `setSelected(rows, selected)` key by it, and so do the table's expanded row and its row tracking.\n- **`useMultiSelect`** is read now (it was declared and wired to nothing): a leading checkbox column over the datasource's own `selections` \u2014 a header box that selects or clears every selectable row on the page, `indeterminate` while only some are, and a box per row. `selectableWhen` keeps rows out of it (a disabled box, skipped by select-all); `selectLabel` and `selectAllLabel` name the boxes; `selectionChange` reports the datasource's selection after a box changed it. A box is its own control: a click on it is never the row's click. Theme options `selectionColumnWidth` (40), `selectionCheckboxSize` (`sm`) and `selectedRowColor` (unset: no tint).\n- **`expanded`**, a two-way model: the expanded row's `rowId`, or its page index when the datasource has none; `null` collapses all. A deep link can open a row before the records arrive, and a sort or re-fetch that reorders them keeps the same record open. **`expandableWhen`** names the rows that have a detail \u2014 the rest take no hover affordance and no `aria-expanded`, and a click on them only emits `rowClick`. **`rowClass`** adds a class per row. Rows with a detail carry `aria-expanded`.\n- `expandedIndex` is now a read-only computed of the open row's page index, **deprecated** in favour of `expanded`; `toggleRow(index)` still works. Removed in 12.0.",
19465
+ commit: "cfddc14"
19466
+ }
19467
+ ],
19468
+ dependencyBumps: []
19469
+ },
19470
+ {
19471
+ version: "11.8.0",
19472
+ entries: [
19473
+ {
19474
+ bump: "minor",
19475
+ title: "The dialog and drawer release: footers that take your own actions, a rich dialog head, and a non-modal overlay drawer.",
19476
+ body: "- **`[dialog-buttons]`, `[drawer-buttons]`**: an `<ng-content>` inside the row. Empty, each renders its pair (Confirm/Cancel, Cancel/Save) as before; project your own buttons and they replace the pair while keeping the row's chrome \u2014 padding, gap, `justifyContent`, the divider, `stretch`, `reverseOrder`. Until now importing either component silently discarded whatever a consumer projected, which is why apps carried the slot attribute _without_ the import to keep a real footer. A `[dialog-footnote]` / `[drawer-footnote]` projects on the leading edge and pushes the actions to the trailing one. `loading` puts the spinner on the confirm button; on the dialog, `closeOnConfirm` (default `true`) can be turned off so an asynchronous save closes the dialog itself \u2014 and a failed one leaves it open with its error.\n- **`[dialog-header]`**: a `rich` input renders the projection as a block beside the close button \u2014 an eyebrow, a headline, a blurb \u2014 instead of one centred line. Two `dialogHeader` theme options dress it: `richColor` (unset by default: the head is part of the sheet, not a pill on it) and `richPadding` (`md`). The new **`[dialog-title]`** directive marks the headline inside a rich head so it alone is the dialog's accessible name; without one the whole block is. The title bar is unchanged.\n- **`uni-drawer`**: `modal` (default `true`) on `over` mode. Off, the panel is shown as a `popover=\"manual\"` \u2014 still the top layer, where nothing can clip or cover it, but no focus trap, no inert page and no backdrop: a workbench beside the live document it changes, and the reason a toast's Undo stays clickable while a panel is open. Escape still asks to close through `closeRequest` (while focus is inside the panel), so `disableAutoClose` vetoes it as in modal mode; `scrim` is ignored with a dev-mode warning; and `closeOnOutsideClick` (default `false`, reason `'outside'`) opts into dismissal on a click beyond the panel. `DrawerCloseReason` gains `'outside'`.\n- **`uni-callout`** (and so `uni-tour`): every retarget re-shows the scrim and panel, so a panel opened by the previous step's click \u2014 which entered the top layer after them and covered them \u2014 ends up beneath them again, and the next step can point inside it. The panel has to be non-modal for that: a `showModal()` dialog makes everything outside it inert, which no stacking undoes. That is what `modal: false` on the drawer is for.\n\nBase theme: `dialogHeader.options.richColor` (undefined) and `richPadding` (`md`).",
19477
+ commit: "fa02607"
19478
+ }
19479
+ ],
19480
+ dependencyBumps: []
19481
+ },
19243
19482
  {
19244
19483
  version: "11.7.0",
19245
19484
  entries: [
@@ -20216,6 +20455,30 @@ placeholder="Name or address\u2026"
20216
20455
  {
20217
20456
  package: "@uni-design-system/uni-core",
20218
20457
  releases: [
20458
+ {
20459
+ version: "11.9.0",
20460
+ entries: [
20461
+ {
20462
+ bump: "minor",
20463
+ title: "`uni-data-table` gains a real selection column and an id-keyed, bindable detail row; the datasources gain a row identity.",
20464
+ body: "- **`rowId` on the datasources** (`new UniRecordDatasource(rows, { rowId: (row) => row.id })`, also a third argument on `UniServerSideDatasource`, and settable afterwards): a stable identity for a row. Without one, rows are compared by reference, which never matches a row rebuilt from a fresh fetch \u2014 a realtime update that replaced the records emptied the selection. With one, `isSelected`, `toggleSelection` and the new `setSelected(rows, selected)` key by it, and so do the table's expanded row and its row tracking.\n- **`useMultiSelect`** is read now (it was declared and wired to nothing): a leading checkbox column over the datasource's own `selections` \u2014 a header box that selects or clears every selectable row on the page, `indeterminate` while only some are, and a box per row. `selectableWhen` keeps rows out of it (a disabled box, skipped by select-all); `selectLabel` and `selectAllLabel` name the boxes; `selectionChange` reports the datasource's selection after a box changed it. A box is its own control: a click on it is never the row's click. Theme options `selectionColumnWidth` (40), `selectionCheckboxSize` (`sm`) and `selectedRowColor` (unset: no tint).\n- **`expanded`**, a two-way model: the expanded row's `rowId`, or its page index when the datasource has none; `null` collapses all. A deep link can open a row before the records arrive, and a sort or re-fetch that reorders them keeps the same record open. **`expandableWhen`** names the rows that have a detail \u2014 the rest take no hover affordance and no `aria-expanded`, and a click on them only emits `rowClick`. **`rowClass`** adds a class per row. Rows with a detail carry `aria-expanded`.\n- `expandedIndex` is now a read-only computed of the open row's page index, **deprecated** in favour of `expanded`; `toggleRow(index)` still works. Removed in 12.0.",
20465
+ commit: "cfddc14"
20466
+ }
20467
+ ],
20468
+ dependencyBumps: []
20469
+ },
20470
+ {
20471
+ version: "11.8.0",
20472
+ entries: [
20473
+ {
20474
+ bump: "minor",
20475
+ title: "The dialog and drawer release: footers that take your own actions, a rich dialog head, and a non-modal overlay drawer.",
20476
+ body: "- **`[dialog-buttons]`, `[drawer-buttons]`**: an `<ng-content>` inside the row. Empty, each renders its pair (Confirm/Cancel, Cancel/Save) as before; project your own buttons and they replace the pair while keeping the row's chrome \u2014 padding, gap, `justifyContent`, the divider, `stretch`, `reverseOrder`. Until now importing either component silently discarded whatever a consumer projected, which is why apps carried the slot attribute _without_ the import to keep a real footer. A `[dialog-footnote]` / `[drawer-footnote]` projects on the leading edge and pushes the actions to the trailing one. `loading` puts the spinner on the confirm button; on the dialog, `closeOnConfirm` (default `true`) can be turned off so an asynchronous save closes the dialog itself \u2014 and a failed one leaves it open with its error.\n- **`[dialog-header]`**: a `rich` input renders the projection as a block beside the close button \u2014 an eyebrow, a headline, a blurb \u2014 instead of one centred line. Two `dialogHeader` theme options dress it: `richColor` (unset by default: the head is part of the sheet, not a pill on it) and `richPadding` (`md`). The new **`[dialog-title]`** directive marks the headline inside a rich head so it alone is the dialog's accessible name; without one the whole block is. The title bar is unchanged.\n- **`uni-drawer`**: `modal` (default `true`) on `over` mode. Off, the panel is shown as a `popover=\"manual\"` \u2014 still the top layer, where nothing can clip or cover it, but no focus trap, no inert page and no backdrop: a workbench beside the live document it changes, and the reason a toast's Undo stays clickable while a panel is open. Escape still asks to close through `closeRequest` (while focus is inside the panel), so `disableAutoClose` vetoes it as in modal mode; `scrim` is ignored with a dev-mode warning; and `closeOnOutsideClick` (default `false`, reason `'outside'`) opts into dismissal on a click beyond the panel. `DrawerCloseReason` gains `'outside'`.\n- **`uni-callout`** (and so `uni-tour`): every retarget re-shows the scrim and panel, so a panel opened by the previous step's click \u2014 which entered the top layer after them and covered them \u2014 ends up beneath them again, and the next step can point inside it. The panel has to be non-modal for that: a `showModal()` dialog makes everything outside it inert, which no stacking undoes. That is what `modal: false` on the drawer is for.\n\nBase theme: `dialogHeader.options.richColor` (undefined) and `richPadding` (`md`).",
20477
+ commit: "fa02607"
20478
+ }
20479
+ ],
20480
+ dependencyBumps: []
20481
+ },
20219
20482
  {
20220
20483
  version: "11.7.0",
20221
20484
  entries: [
@@ -20917,6 +21180,16 @@ placeholder="Name or address\u2026"
20917
21180
  {
20918
21181
  package: "@uni-design-system/uni-react",
20919
21182
  releases: [
21183
+ {
21184
+ version: "11.9.0",
21185
+ entries: [],
21186
+ dependencyBumps: []
21187
+ },
21188
+ {
21189
+ version: "11.8.0",
21190
+ entries: [],
21191
+ dependencyBumps: []
21192
+ },
20920
21193
  {
20921
21194
  version: "11.7.0",
20922
21195
  entries: [],
@@ -21233,6 +21506,16 @@ placeholder="Name or address\u2026"
21233
21506
  {
21234
21507
  package: "@uni-design-system/uni-mcp",
21235
21508
  releases: [
21509
+ {
21510
+ version: "11.9.0",
21511
+ entries: [],
21512
+ dependencyBumps: []
21513
+ },
21514
+ {
21515
+ version: "11.8.0",
21516
+ entries: [],
21517
+ dependencyBumps: []
21518
+ },
21236
21519
  {
21237
21520
  version: "11.7.0",
21238
21521
  entries: [],
@@ -21507,7 +21790,7 @@ placeholder="Name or address\u2026"
21507
21790
  summary: "Returns a document-unique id for wiring ARIA relationships (aria-controls, aria-describedby, aria-labelledby, ...).",
21508
21791
  description: "Returns a document-unique id for wiring ARIA relationships (aria-controls, aria-describedby, aria-labelledby, ...).",
21509
21792
  members: [],
21510
- version: "11.7.0"
21793
+ version: "11.9.0"
21511
21794
  },
21512
21795
  {
21513
21796
  id: "focusable-selector",
@@ -21519,7 +21802,7 @@ placeholder="Name or address\u2026"
21519
21802
  summary: "Selector matching natively focusable elements.",
21520
21803
  description: "Selector matching natively focusable elements. Used to locate the interactive element inside a projected trigger so ARIA attributes land on the element that actually receives focus.",
21521
21804
  members: [],
21522
- version: "11.7.0"
21805
+ version: "11.9.0"
21523
21806
  },
21524
21807
  {
21525
21808
  id: "resolve-focus-target",
@@ -21531,7 +21814,7 @@ placeholder="Name or address\u2026"
21531
21814
  summary: "Resolves the element that should carry ARIA state for a trigger: the element itself when focusable, otherwise its first focusable descendant.",
21532
21815
  description: "Resolves the element that should carry ARIA state for a trigger: the element itself when focusable, otherwise its first focusable descendant.",
21533
21816
  members: [],
21534
- version: "11.7.0"
21817
+ version: "11.9.0"
21535
21818
  },
21536
21819
  {
21537
21820
  id: "visually-hidden",
@@ -21543,7 +21826,7 @@ placeholder="Name or address\u2026"
21543
21826
  summary: "Visually hides content while keeping it available to screen readers.",
21544
21827
  description: "Visually hides content while keeping it available to screen readers. Use for text alternatives (e.g. badge counts, icon-only affordances). `fixed`, not `absolute`, and that is load-bearing. An absolutely positioned box resolves its containing block to the nearest *positioned* ancestor \u2014 which, since the controls emitting these spans are `position: static`, is whatever positioned box happens to be above them in the consumer's layout, often several scroll containers up. The span then skips every intervening `overflow: auto` and lands in that distant ancestor's scrollable overflow, turning 1x1 of invisible text into real scrollable distance in a box that never opted into scrolling. A fixed box's containing block is the viewport, so it joins no ancestor's scrollable overflow at all. Caveat: inside a `transform`ed (or `filter`ed/`contain`ed) ancestor a fixed box re-anchors to that ancestor. Harmless here \u2014 the element is 1x1 and clipped to nothing, so where it lands never matters, only what it overflows.",
21545
21828
  members: [],
21546
- version: "11.7.0"
21829
+ version: "11.9.0"
21547
21830
  },
21548
21831
  {
21549
21832
  id: "motion-safe",
@@ -21555,7 +21838,7 @@ placeholder="Name or address\u2026"
21555
21838
  summary: "Wraps animation/transition styles so they only apply when the user has not requested reduced motion (WCAG 2.3.3).",
21556
21839
  description: "Wraps animation/transition styles so they only apply when the user has not requested reduced motion (WCAG 2.3.3).",
21557
21840
  members: [],
21558
- version: "11.7.0"
21841
+ version: "11.9.0"
21559
21842
  },
21560
21843
  {
21561
21844
  id: "announcer",
@@ -21580,7 +21863,7 @@ placeholder="Name or address\u2026"
21580
21863
  description: "Announce `text`, even when it repeats what was just announced."
21581
21864
  }
21582
21865
  ],
21583
- version: "11.7.0"
21866
+ version: "11.9.0"
21584
21867
  },
21585
21868
  {
21586
21869
  id: "create-announcer",
@@ -21592,7 +21875,7 @@ placeholder="Name or address\u2026"
21592
21875
  summary: "A polite live region's text, for the running commentary a form control owes a screen reader: commits, clears, refused entries, result counts \u2014 changes a sighted user sees but that are otherwise silent.",
21593
21876
  description: "A polite live region's text, for the running commentary a form control owes a screen reader: commits, clears, refused entries, result counts \u2014 changes a sighted user sees but that are otherwise silent. Extracted because five controls (`uni-combobox`, `uni-tag-input`, `uni-time-input`, `uni-date-input`, `uni-calendar`) carried byte-identical copies, including the repeat trick below \u2014 the kind of subtlety that is quietly dropped when the sixth control hand-rolls its own. Announcing the same text twice must still be heard: assistive tech reads a live region when its content *changes*, so setting an identical string is a no-op and the second \"No match.\" would be silent. A trailing space breaks the equality without changing a word of what is read. Successive repeats alternate between the padded and unpadded form, so nothing accumulates. Deliberately holds no DOM and no styling: the region belongs to the component's own template, where its placement and visually-hidden class are already the component's business.",
21594
21877
  members: [],
21595
- version: "11.7.0"
21878
+ version: "11.9.0"
21596
21879
  },
21597
21880
  {
21598
21881
  id: "uni-date",
@@ -21604,7 +21887,7 @@ placeholder="Name or address\u2026"
21604
21887
  summary: "A calendar date, `'YYYY-MM-DD'`.",
21605
21888
  description: "A calendar date, `'YYYY-MM-DD'`.",
21606
21889
  members: [],
21607
- version: "11.7.0"
21890
+ version: "11.9.0"
21608
21891
  },
21609
21892
  {
21610
21893
  id: "uni-time",
@@ -21616,7 +21899,7 @@ placeholder="Name or address\u2026"
21616
21899
  summary: "A wall-clock time, `'HH:mm'` (24-hour).",
21617
21900
  description: "A wall-clock time, `'HH:mm'` (24-hour). Display format is separate.",
21618
21901
  members: [],
21619
- version: "11.7.0"
21902
+ version: "11.9.0"
21620
21903
  },
21621
21904
  {
21622
21905
  id: "uni-date-time",
@@ -21628,7 +21911,7 @@ placeholder="Name or address\u2026"
21628
21911
  summary: "A combined date and time, `'YYYY-MM-DDTHH:mm'`.",
21629
21912
  description: "A combined date and time, `'YYYY-MM-DDTHH:mm'`.",
21630
21913
  members: [],
21631
- version: "11.7.0"
21914
+ version: "11.9.0"
21632
21915
  },
21633
21916
  {
21634
21917
  id: "uni-date-range",
@@ -21653,7 +21936,7 @@ placeholder="Name or address\u2026"
21653
21936
  description: ""
21654
21937
  }
21655
21938
  ],
21656
- version: "11.7.0"
21939
+ version: "11.9.0"
21657
21940
  },
21658
21941
  {
21659
21942
  id: "iso-date",
@@ -21665,7 +21948,7 @@ placeholder="Name or address\u2026"
21665
21948
  summary: "`(2026, 8, 5)` \u2192 `'2026-08-05'`.",
21666
21949
  description: "`(2026, 8, 5)` \u2192 `'2026-08-05'`. Does not validate \u2014 see `isValidDate`.",
21667
21950
  members: [],
21668
- version: "11.7.0"
21951
+ version: "11.9.0"
21669
21952
  },
21670
21953
  {
21671
21954
  id: "is-valid-date",
@@ -21677,7 +21960,7 @@ placeholder="Name or address\u2026"
21677
21960
  summary: "The ISO date when the parts form a real calendar day, else `null`.",
21678
21961
  description: "The ISO date when the parts form a real calendar day, else `null`.",
21679
21962
  members: [],
21680
- version: "11.7.0"
21963
+ version: "11.9.0"
21681
21964
  },
21682
21965
  {
21683
21966
  id: "days-in-month",
@@ -21689,7 +21972,7 @@ placeholder="Name or address\u2026"
21689
21972
  summary: "Days in a month, leap-year aware.",
21690
21973
  description: "Days in a month, leap-year aware.",
21691
21974
  members: [],
21692
- version: "11.7.0"
21975
+ version: "11.9.0"
21693
21976
  },
21694
21977
  {
21695
21978
  id: "add-days",
@@ -21701,7 +21984,7 @@ placeholder="Name or address\u2026"
21701
21984
  summary: "",
21702
21985
  description: "",
21703
21986
  members: [],
21704
- version: "11.7.0"
21987
+ version: "11.9.0"
21705
21988
  },
21706
21989
  {
21707
21990
  id: "add-months",
@@ -21713,7 +21996,7 @@ placeholder="Name or address\u2026"
21713
21996
  summary: "Same day \xB1 n months, clamping the day to the target month's length.",
21714
21997
  description: "Same day \xB1 n months, clamping the day to the target month's length.",
21715
21998
  members: [],
21716
- version: "11.7.0"
21999
+ version: "11.9.0"
21717
22000
  },
21718
22001
  {
21719
22002
  id: "day-of-week",
@@ -21725,7 +22008,7 @@ placeholder="Name or address\u2026"
21725
22008
  summary: "Day of week, 0 = Sunday \u2026 6 = Saturday.",
21726
22009
  description: "Day of week, 0 = Sunday \u2026 6 = Saturday.",
21727
22010
  members: [],
21728
- version: "11.7.0"
22011
+ version: "11.9.0"
21729
22012
  },
21730
22013
  {
21731
22014
  id: "month-of",
@@ -21737,7 +22020,7 @@ placeholder="Name or address\u2026"
21737
22020
  summary: "`'2026-08-20'` \u2192 `'2026-08'`.",
21738
22021
  description: "`'2026-08-20'` \u2192 `'2026-08'`.",
21739
22022
  members: [],
21740
- version: "11.7.0"
22023
+ version: "11.9.0"
21741
22024
  },
21742
22025
  {
21743
22026
  id: "today-iso",
@@ -21749,7 +22032,7 @@ placeholder="Name or address\u2026"
21749
22032
  summary: "Today as a local-wall-clock ISO date (the one place local time matters).",
21750
22033
  description: "Today as a local-wall-clock ISO date (the one place local time matters).",
21751
22034
  members: [],
21752
- version: "11.7.0"
22035
+ version: "11.9.0"
21753
22036
  },
21754
22037
  {
21755
22038
  id: "inclusive-day-count",
@@ -21761,7 +22044,7 @@ placeholder="Name or address\u2026"
21761
22044
  summary: "Inclusive day count of a range: `('-20', '-24')` \u2192 5.",
21762
22045
  description: "Inclusive day count of a range: `('-20', '-24')` \u2192 5.",
21763
22046
  members: [],
21764
- version: "11.7.0"
22047
+ version: "11.9.0"
21765
22048
  },
21766
22049
  {
21767
22050
  id: "uni-month-grid-cell",
@@ -21786,7 +22069,7 @@ placeholder="Name or address\u2026"
21786
22069
  description: "True for leading/trailing cells that belong to the adjacent months."
21787
22070
  }
21788
22071
  ],
21789
- version: "11.7.0"
22072
+ version: "11.9.0"
21790
22073
  },
21791
22074
  {
21792
22075
  id: "build-month-grid",
@@ -21798,7 +22081,7 @@ placeholder="Name or address\u2026"
21798
22081
  summary: "The week matrix a calendar renders: full weeks covering `'YYYY-MM'`, starting on `weekStart` (0 = Sunday).",
21799
22082
  description: "The week matrix a calendar renders: full weeks covering `'YYYY-MM'`, starting on `weekStart` (0 = Sunday). Outside cells are always present so showing or hiding them is a pure render decision.",
21800
22083
  members: [],
21801
- version: "11.7.0"
22084
+ version: "11.9.0"
21802
22085
  },
21803
22086
  {
21804
22087
  id: "format-date",
@@ -21810,7 +22093,7 @@ placeholder="Name or address\u2026"
21810
22093
  summary: "",
21811
22094
  description: "",
21812
22095
  members: [],
21813
- version: "11.7.0"
22096
+ version: "11.9.0"
21814
22097
  },
21815
22098
  {
21816
22099
  id: "format-month-heading",
@@ -21822,7 +22105,7 @@ placeholder="Name or address\u2026"
21822
22105
  summary: "`'2026-08'` \u2192 `'August 2026'` in the locale.",
21823
22106
  description: "`'2026-08'` \u2192 `'August 2026'` in the locale.",
21824
22107
  members: [],
21825
- version: "11.7.0"
22108
+ version: "11.9.0"
21826
22109
  },
21827
22110
  {
21828
22111
  id: "uni-weekday-name",
@@ -21847,7 +22130,7 @@ placeholder="Name or address\u2026"
21847
22130
  description: "Full weekday name, for the columnheader's `abbr`."
21848
22131
  }
21849
22132
  ],
21850
- version: "11.7.0"
22133
+ version: "11.9.0"
21851
22134
  },
21852
22135
  {
21853
22136
  id: "weekday-names",
@@ -21859,7 +22142,7 @@ placeholder="Name or address\u2026"
21859
22142
  summary: "Weekday header labels starting at `weekStart` (0 = Sunday).",
21860
22143
  description: "Weekday header labels starting at `weekStart` (0 = Sunday).",
21861
22144
  members: [],
21862
- version: "11.7.0"
22145
+ version: "11.9.0"
21863
22146
  },
21864
22147
  {
21865
22148
  id: "format-time",
@@ -21871,7 +22154,7 @@ placeholder="Name or address\u2026"
21871
22154
  summary: "`'15:00'` \u2192 `'3:00 PM'` (or `'15:00'` when `hour12` is false).",
21872
22155
  description: "`'15:00'` \u2192 `'3:00 PM'` (or `'15:00'` when `hour12` is false).",
21873
22156
  members: [],
21874
- version: "11.7.0"
22157
+ version: "11.9.0"
21875
22158
  },
21876
22159
  {
21877
22160
  id: "locale-week-start",
@@ -21883,7 +22166,7 @@ placeholder="Name or address\u2026"
21883
22166
  summary: "The locale's first day of week, 0 = Sunday \u2026 6 = Saturday.",
21884
22167
  description: "The locale's first day of week, 0 = Sunday \u2026 6 = Saturday. Falls back to Sunday where `Intl.Locale` week info is unavailable.",
21885
22168
  members: [],
21886
- version: "11.7.0"
22169
+ version: "11.9.0"
21887
22170
  },
21888
22171
  {
21889
22172
  id: "locale-default-hour12",
@@ -21895,7 +22178,7 @@ placeholder="Name or address\u2026"
21895
22178
  summary: "Whether the locale's default clock is 12-hour.",
21896
22179
  description: "Whether the locale's default clock is 12-hour.",
21897
22180
  members: [],
21898
- version: "11.7.0"
22181
+ version: "11.9.0"
21899
22182
  },
21900
22183
  {
21901
22184
  id: "locale-field-order",
@@ -21907,7 +22190,7 @@ placeholder="Name or address\u2026"
21907
22190
  summary: "The locale's numeric-date field order, e.g.",
21908
22191
  description: "The locale's numeric-date field order, e.g. en-US \u2192 month, day, year.",
21909
22192
  members: [],
21910
- version: "11.7.0"
22193
+ version: "11.9.0"
21911
22194
  },
21912
22195
  {
21913
22196
  id: "locale-month-names",
@@ -21919,7 +22202,7 @@ placeholder="Name or address\u2026"
21919
22202
  summary: "Long + short month names \u2192 month number, lowercased, dots stripped.",
21920
22203
  description: "Long + short month names \u2192 month number, lowercased, dots stripped.",
21921
22204
  members: [],
21922
- version: "11.7.0"
22205
+ version: "11.9.0"
21923
22206
  },
21924
22207
  {
21925
22208
  id: "locale-date-placeholder",
@@ -21931,7 +22214,7 @@ placeholder="Name or address\u2026"
21931
22214
  summary: "The locale's digit pattern as a placeholder, e.g.",
21932
22215
  description: "The locale's digit pattern as a placeholder, e.g. `'MM/DD/YYYY'`.",
21933
22216
  members: [],
21934
- version: "11.7.0"
22217
+ version: "11.9.0"
21935
22218
  },
21936
22219
  {
21937
22220
  id: "parse-date-text",
@@ -21943,7 +22226,7 @@ placeholder="Name or address\u2026"
21943
22226
  summary: "Free-typed date text \u2192 ISO date, or `null` when unreadable.",
21944
22227
  description: "Free-typed date text \u2192 ISO date, or `null` when unreadable. Accepts, in order: ISO (`2026-08-20`), a month name from the locale's own long/short lists (`aug 20`, `20 aug 2026`, `August 20th`), and locale-numeric text (`8/20/2026`, `20.8.2026`, `08-20`) with the digit order taken from `Intl.DateTimeFormat(locale).formatToParts()`. A missing year resolves to the next occurrence; two-digit years are refused rather than guessed.",
21945
22228
  members: [],
21946
- version: "11.7.0"
22229
+ version: "11.9.0"
21947
22230
  },
21948
22231
  {
21949
22232
  id: "parse-time-text",
@@ -21955,7 +22238,7 @@ placeholder="Name or address\u2026"
21955
22238
  summary: "Free-typed time text \u2192 `'HH:mm'`, or `null`.",
21956
22239
  description: "Free-typed time text \u2192 `'HH:mm'`, or `null`. Accepts `9`, `930`, `9:30`, `9.30`, `9 30`, `3p`, `3pm`, `3 PM`, `15:00`. Bare hours 1\u20137 with no meridiem lean PM when `hour12` \u2014 typing `3` into an appointment field means 15:00, not 03:00.",
21957
22240
  members: [],
21958
- version: "11.7.0"
22241
+ version: "11.9.0"
21959
22242
  },
21960
22243
  {
21961
22244
  id: "time-slots",
@@ -21967,7 +22250,7 @@ placeholder="Name or address\u2026"
21967
22250
  summary: "Every `minuteStep` time between `min` and `max` (inclusive bounds).",
21968
22251
  description: "Every `minuteStep` time between `min` and `max` (inclusive bounds).",
21969
22252
  members: [],
21970
- version: "11.7.0"
22253
+ version: "11.9.0"
21971
22254
  },
21972
22255
  {
21973
22256
  id: "split-date-time",
@@ -21979,7 +22262,7 @@ placeholder="Name or address\u2026"
21979
22262
  summary: "",
21980
22263
  description: "",
21981
22264
  members: [],
21982
- version: "11.7.0"
22265
+ version: "11.9.0"
21983
22266
  },
21984
22267
  {
21985
22268
  id: "join-date-time",
@@ -21991,7 +22274,7 @@ placeholder="Name or address\u2026"
21991
22274
  summary: "One combined value only when both parts are present.",
21992
22275
  description: "One combined value only when both parts are present.",
21993
22276
  members: [],
21994
- version: "11.7.0"
22277
+ version: "11.9.0"
21995
22278
  },
21996
22279
  {
21997
22280
  id: "uni-number-range",
@@ -22016,7 +22299,7 @@ placeholder="Name or address\u2026"
22016
22299
  description: ""
22017
22300
  }
22018
22301
  ],
22019
- version: "11.7.0"
22302
+ version: "11.9.0"
22020
22303
  },
22021
22304
  {
22022
22305
  id: "uni-rounding-mode",
@@ -22028,7 +22311,7 @@ placeholder="Name or address\u2026"
22028
22311
  summary: "How a tie is resolved when rounding to a fraction-digit count.",
22029
22312
  description: "How a tie is resolved when rounding to a fraction-digit count. `half-up` is the invoice default (ties away from zero: `1.15` \u2192 `1.2`); `half-even` is banker's rounding, which removes the upward bias across a column of figures (`1.25` \u2192 `1.2`, `1.35` \u2192 `1.4`).",
22030
22313
  members: [],
22031
- version: "11.7.0"
22314
+ version: "11.9.0"
22032
22315
  },
22033
22316
  {
22034
22317
  id: "uni-number-preset",
@@ -22040,7 +22323,7 @@ placeholder="Name or address\u2026"
22040
22323
  summary: "Format archetype.",
22041
22324
  description: "Format archetype. Supplies decimals, grouping, affix and `inputmode`.",
22042
22325
  members: [],
22043
- version: "11.7.0"
22326
+ version: "11.9.0"
22044
22327
  },
22045
22328
  {
22046
22329
  id: "uni-number-grouping",
@@ -22052,7 +22335,7 @@ placeholder="Name or address\u2026"
22052
22335
  summary: "Thousands-separator policy, mapped onto `Intl`'s `useGrouping`.",
22053
22336
  description: "Thousands-separator policy, mapped onto `Intl`'s `useGrouping`. `min2` \u2014 the default \u2014 groups only from five integer digits, so a year renders `2026` rather than `2,026` while a price still renders `10,000`.",
22054
22337
  members: [],
22055
- version: "11.7.0"
22338
+ version: "11.9.0"
22056
22339
  },
22057
22340
  {
22058
22341
  id: "uni-number-reject-reason",
@@ -22064,7 +22347,7 @@ placeholder="Name or address\u2026"
22064
22347
  summary: "Why a typed commit was refused.",
22065
22348
  description: "Why a typed commit was refused. The raw text stays in the field.",
22066
22349
  members: [],
22067
- version: "11.7.0"
22350
+ version: "11.9.0"
22068
22351
  },
22069
22352
  {
22070
22353
  id: "uni-number-step-config",
@@ -22107,7 +22390,7 @@ placeholder="Name or address\u2026"
22107
22390
  description: "Cycle past a fence instead of stopping at it \u2014 for genuinely cyclic fields only (23 \u2192 0 hours, 359 \u2192 0 degrees). Needs both `min` and `max`."
22108
22391
  }
22109
22392
  ],
22110
- version: "11.7.0"
22393
+ version: "11.9.0"
22111
22394
  },
22112
22395
  {
22113
22396
  id: "uni-number-clamp",
@@ -22132,7 +22415,7 @@ placeholder="Name or address\u2026"
22132
22415
  description: "Which fence was hit, or `null` when the value was already in range."
22133
22416
  }
22134
22417
  ],
22135
- version: "11.7.0"
22418
+ version: "11.9.0"
22136
22419
  },
22137
22420
  {
22138
22421
  id: "uni-locale-number-parts",
@@ -22175,7 +22458,7 @@ placeholder="Name or address\u2026"
22175
22458
  description: "Fraction digits `Intl` uses for the currency \u2014 JPY 0, USD 2."
22176
22459
  }
22177
22460
  ],
22178
- version: "11.7.0"
22461
+ version: "11.9.0"
22179
22462
  },
22180
22463
  {
22181
22464
  id: "uni-number-format-config",
@@ -22260,7 +22543,7 @@ placeholder="Name or address\u2026"
22260
22543
  description: "Spoken long form of an abbreviated suffix, for `aria-valuetext`."
22261
22544
  }
22262
22545
  ],
22263
- version: "11.7.0"
22546
+ version: "11.9.0"
22264
22547
  },
22265
22548
  {
22266
22549
  id: "uni-resolved-number-format",
@@ -22351,7 +22634,7 @@ placeholder="Name or address\u2026"
22351
22634
  description: ""
22352
22635
  }
22353
22636
  ],
22354
- version: "11.7.0"
22637
+ version: "11.9.0"
22355
22638
  },
22356
22639
  {
22357
22640
  id: "uni-number-parse-result",
@@ -22363,7 +22646,7 @@ placeholder="Name or address\u2026"
22363
22646
  summary: "The outcome of reading a user's text.",
22364
22647
  description: "The outcome of reading a user's text. Refused text is never swallowed: the caller keeps it in the field and flags it, so nobody loses their work to a silently emptied box.",
22365
22648
  members: [],
22366
- version: "11.7.0"
22649
+ version: "11.9.0"
22367
22650
  },
22368
22651
  {
22369
22652
  id: "is-canonical-decimal",
@@ -22375,7 +22658,7 @@ placeholder="Name or address\u2026"
22375
22658
  summary: "True when `text` is already a canonical decimal (leading/trailing space allowed).",
22376
22659
  description: "True when `text` is already a canonical decimal (leading/trailing space allowed).",
22377
22660
  members: [],
22378
- version: "11.7.0"
22661
+ version: "11.9.0"
22379
22662
  },
22380
22663
  {
22381
22664
  id: "decimal-scale",
@@ -22387,7 +22670,7 @@ placeholder="Name or address\u2026"
22387
22670
  summary: "Fraction-digit count.",
22388
22671
  description: "Fraction-digit count. `'1.250'` \u2192 3, `'12'` \u2192 0, `'5.'` \u2192 0.",
22389
22672
  members: [],
22390
- version: "11.7.0"
22673
+ version: "11.9.0"
22391
22674
  },
22392
22675
  {
22393
22676
  id: "to-scaled",
@@ -22399,7 +22682,7 @@ placeholder="Name or address\u2026"
22399
22682
  summary: "Canonical decimal \u2192 integer scaled by `10^scale`.",
22400
22683
  description: "Canonical decimal \u2192 integer scaled by `10^scale`. Fraction digits beyond `scale` are truncated, so callers that must not lose them pass a `scale` at least `decimalScale(value)`.",
22401
22684
  members: [],
22402
- version: "11.7.0"
22685
+ version: "11.9.0"
22403
22686
  },
22404
22687
  {
22405
22688
  id: "from-scaled",
@@ -22411,7 +22694,7 @@ placeholder="Name or address\u2026"
22411
22694
  summary: "Scaled integer \u2192 canonical decimal, with trailing fraction zeros trimmed.",
22412
22695
  description: "Scaled integer \u2192 canonical decimal, with trailing fraction zeros trimmed.",
22413
22696
  members: [],
22414
- version: "11.7.0"
22697
+ version: "11.9.0"
22415
22698
  },
22416
22699
  {
22417
22700
  id: "normalize-decimal",
@@ -22423,7 +22706,7 @@ placeholder="Name or address\u2026"
22423
22706
  summary: "Strip a leading `+`, leading zeros and trailing fraction zeros: `'+01.50'` \u2192 `'1.5'`.",
22424
22707
  description: "Strip a leading `+`, leading zeros and trailing fraction zeros: `'+01.50'` \u2192 `'1.5'`. Requires a canonical decimal; guard with `isCanonicalDecimal`.",
22425
22708
  members: [],
22426
- version: "11.7.0"
22709
+ version: "11.9.0"
22427
22710
  },
22428
22711
  {
22429
22712
  id: "to-decimal",
@@ -22435,7 +22718,7 @@ placeholder="Name or address\u2026"
22435
22718
  summary: "Any numeric input \u2192 canonical decimal, expanding the exponential notation `String(number)` produces outside 1e-7\u20261e21.",
22436
22719
  description: "Any numeric input \u2192 canonical decimal, expanding the exponential notation `String(number)` produces outside 1e-7\u20261e21. A `step` of `1e-7` would otherwise reach the arithmetic as the literal text `'1e-7'`. Throws on text that is not numeric at all \u2014 every caller here passes either a `number` input or text already cleared by the parser.",
22437
22720
  members: [],
22438
- version: "11.7.0"
22721
+ version: "11.9.0"
22439
22722
  },
22440
22723
  {
22441
22724
  id: "compare-decimal",
@@ -22447,7 +22730,7 @@ placeholder="Name or address\u2026"
22447
22730
  summary: "`-1` when `a < b`, `1` when `a > b`, `0` when equal.",
22448
22731
  description: "`-1` when `a < b`, `1` when `a > b`, `0` when equal. `'1.50'` equals `'1.5'`.",
22449
22732
  members: [],
22450
- version: "11.7.0"
22733
+ version: "11.9.0"
22451
22734
  },
22452
22735
  {
22453
22736
  id: "round-decimal",
@@ -22459,7 +22742,7 @@ placeholder="Name or address\u2026"
22459
22742
  summary: "Round to `fractionDigits`, breaking ties per `mode`.",
22460
22743
  description: "Round to `fractionDigits`, breaking ties per `mode`. Exact where `Number.prototype.toFixed` is not \u2014 see the file header.",
22461
22744
  members: [],
22462
- version: "11.7.0"
22745
+ version: "11.9.0"
22463
22746
  },
22464
22747
  {
22465
22748
  id: "shift-decimal",
@@ -22471,7 +22754,7 @@ placeholder="Name or address\u2026"
22471
22754
  summary: "Multiply by `10^places`, exactly.",
22472
22755
  description: "Multiply by `10^places`, exactly. Used for the percent preset's fraction \u21C4 display shift (`0.15` \u21C4 `15`) and for deriving a default large step of `step \xD7 10` without touching a float.",
22473
22756
  members: [],
22474
- version: "11.7.0"
22757
+ version: "11.9.0"
22475
22758
  },
22476
22759
  {
22477
22760
  id: "clamp-decimal",
@@ -22483,7 +22766,7 @@ placeholder="Name or address\u2026"
22483
22766
  summary: "Hold a value inside its fences, reporting which one it hit so the caller can announce it.",
22484
22767
  description: "Hold a value inside its fences, reporting which one it hit so the caller can announce it. Clamping belongs on commit, never per keystroke: a `min=10` field that clamps live can never be typed into, because the `1` becomes `10` before the `5` arrives.",
22485
22768
  members: [],
22486
- version: "11.7.0"
22769
+ version: "11.9.0"
22487
22770
  },
22488
22771
  {
22489
22772
  id: "step-decimal",
@@ -22495,7 +22778,7 @@ placeholder="Name or address\u2026"
22495
22778
  summary: "One step from `current`, in `direction` (`1` up, `-1` down).",
22496
22779
  description: "One step from `current`, in `direction` (`1` up, `-1` down). Steps land on the grid `origin + n \xB7 step`, where `origin` is `min` by default. A value that is *off* the grid snaps to the nearest grid point **in the direction of travel** rather than jumping past it: with `min=5, step=10` the grid is 5, 15, 25, and stepping up from 7 gives 15, not 17. Fences stop the value; they never wrap unless `wrap` is set and both bounds are defined. Returns `current` unchanged when `step` is zero.",
22497
22780
  members: [],
22498
- version: "11.7.0"
22781
+ version: "11.9.0"
22499
22782
  },
22500
22783
  {
22501
22784
  id: "locale-number-parts",
@@ -22507,7 +22790,7 @@ placeholder="Name or address\u2026"
22507
22790
  summary: "Locale separators plus, when a currency is given, its symbol, side and fraction digits.",
22508
22791
  description: "Locale separators plus, when a currency is given, its symbol, side and fraction digits. Memoized: constructing an `Intl.NumberFormat` is expensive and a field re-resolves this on every keystroke.",
22509
22792
  members: [],
22510
- version: "11.7.0"
22793
+ version: "11.9.0"
22511
22794
  },
22512
22795
  {
22513
22796
  id: "to-ascii-digits",
@@ -22519,7 +22802,7 @@ placeholder="Name or address\u2026"
22519
22802
  summary: "Map localized digits and Arabic separators to ASCII, so `\u0661\u0662\u0663\u0664\u066B\u0665` parses in `ar` and `\u0967\u0968\u0969\u096A.\u096B` in `hi`.",
22520
22803
  description: "Map localized digits and Arabic separators to ASCII, so `\u0661\u0662\u0663\u0664\u066B\u0665` parses in `ar` and `\u0967\u0968\u0969\u096A.\u096B` in `hi`.",
22521
22804
  members: [],
22522
- version: "11.7.0"
22805
+ version: "11.9.0"
22523
22806
  },
22524
22807
  {
22525
22808
  id: "evaluate-expression",
@@ -22531,7 +22814,7 @@ placeholder="Name or address\u2026"
22531
22814
  summary: "Evaluate `+ \u2212 \xD7 \xF7 ( )` over decimal literals \u2014 shunting-yard, roughly thirty lines, and **never `eval`**.",
22532
22815
  description: "Evaluate `+ \u2212 \xD7 \xF7 ( )` over decimal literals \u2014 shunting-yard, roughly thirty lines, and **never `eval`**. Returns a canonical decimal, or `null` when the text is not a well-formed expression. Floats are acceptable here in a way they are not elsewhere: this is a convenience path for spreadsheet muscle memory (`12*3`, `100/4+5`), and the result is settled to ten decimals before re-entering exact arithmetic. Division is the only operation that can produce a non-terminating decimal, and no exact representation would help there either.",
22533
22816
  members: [],
22534
- version: "11.7.0"
22817
+ version: "11.9.0"
22535
22818
  },
22536
22819
  {
22537
22820
  id: "resolve-number-format",
@@ -22543,7 +22826,7 @@ placeholder="Name or address\u2026"
22543
22826
  summary: "Fill in every preset, locale and currency default.",
22544
22827
  description: "Fill in every preset, locale and currency default.",
22545
22828
  members: [],
22546
- version: "11.7.0"
22829
+ version: "11.9.0"
22547
22830
  },
22548
22831
  {
22549
22832
  id: "parse-number",
@@ -22555,7 +22838,7 @@ placeholder="Name or address\u2026"
22555
22838
  summary: "Read a user's text into a canonical decimal in **model units**.",
22556
22839
  description: "Read a user's text into a canonical decimal in **model units**. Accepted, in order: canonical/ASCII (always, whatever the locale \u2014 it is what agents and APIs write), locale-grouped, affixed, localized digits, compact (`1.5k`), accounting negatives (`(1,234.56)` \u2192 `-1234.56`), and expressions when `allowExpressions` is set.",
22557
22840
  members: [],
22558
- version: "11.7.0"
22841
+ version: "11.9.0"
22559
22842
  },
22560
22843
  {
22561
22844
  id: "format-number",
@@ -22567,7 +22850,7 @@ placeholder="Name or address\u2026"
22567
22850
  summary: "Canonical decimal (model units) \u2192 the display number, without affixes.",
22568
22851
  description: "Canonical decimal (model units) \u2192 the display number, without affixes. `min2` grouping \u2014 the default \u2014 starts at five integer digits, so a year renders `2026` rather than `2,026` while a price still renders `10,000`.",
22569
22852
  members: [],
22570
- version: "11.7.0"
22853
+ version: "11.9.0"
22571
22854
  },
22572
22855
  {
22573
22856
  id: "raw-number-text",
@@ -22579,7 +22862,7 @@ placeholder="Name or address\u2026"
22579
22862
  summary: "The plain text the field shows while focused: the display number with no grouping and no affixes, so the caret never has to walk over a separator that appears and vanishes mid-word.",
22580
22863
  description: "The plain text the field shows while focused: the display number with no grouping and no affixes, so the caret never has to walk over a separator that appears and vanishes mid-word.",
22581
22864
  members: [],
22582
- version: "11.7.0"
22865
+ version: "11.9.0"
22583
22866
  },
22584
22867
  {
22585
22868
  id: "settle-number",
@@ -22591,7 +22874,7 @@ placeholder="Name or address\u2026"
22591
22874
  summary: "Round a committed value to the field's precision, in model units.",
22592
22875
  description: "Round a committed value to the field's precision, in model units.",
22593
22876
  members: [],
22594
- version: "11.7.0"
22877
+ version: "11.9.0"
22595
22878
  },
22596
22879
  {
22597
22880
  id: "speak-number",
@@ -22603,7 +22886,7 @@ placeholder="Name or address\u2026"
22603
22886
  summary: "The `aria-valuetext` string: the formatted number with its affixes spoken.",
22604
22887
  description: 'The `aria-valuetext` string: the formatted number with its affixes spoken. `aria-valuenow` alone announces "1234.56", which is the one thing about a money field that is not the point. An empty field says "Empty" per APG.',
22605
22888
  members: [],
22606
- version: "11.7.0"
22889
+ version: "11.9.0"
22607
22890
  },
22608
22891
  {
22609
22892
  id: "to-number",
@@ -22615,7 +22898,7 @@ placeholder="Name or address\u2026"
22615
22898
  summary: "Model-units canonical decimal \u2192 the bound `number`.",
22616
22899
  description: "Model-units canonical decimal \u2192 the bound `number`.",
22617
22900
  members: [],
22618
- version: "11.7.0"
22901
+ version: "11.9.0"
22619
22902
  },
22620
22903
  {
22621
22904
  id: "loses-precision",
@@ -22627,7 +22910,7 @@ placeholder="Name or address\u2026"
22627
22910
  summary: "True when a value cannot survive the trip through `number` \u2014 the reason the components also expose an exact `valueAsString` model, and the trigger for the dev-mode warning.",
22628
22911
  description: "True when a value cannot survive the trip through `number` \u2014 the reason the components also expose an exact `valueAsString` model, and the trigger for the dev-mode warning. Silent precision loss is the whole point of that second model, so it is worth saying out loud once. A `number` can only be checked for magnitude, since it has already lost whatever it was going to lose. A canonical string can be checked properly: `'9007199254740993'` comes back as `'9007199254740992'`.",
22629
22912
  members: [],
22630
- version: "11.7.0"
22913
+ version: "11.9.0"
22631
22914
  },
22632
22915
  {
22633
22916
  id: "press-repeat-timing",
@@ -22664,7 +22947,7 @@ placeholder="Name or address\u2026"
22664
22947
  description: ""
22665
22948
  }
22666
22949
  ],
22667
- version: "11.7.0"
22950
+ version: "11.9.0"
22668
22951
  },
22669
22952
  {
22670
22953
  id: "press-repeat-config",
@@ -22713,7 +22996,7 @@ placeholder="Name or address\u2026"
22713
22996
  description: ""
22714
22997
  }
22715
22998
  ],
22716
- version: "11.7.0"
22999
+ version: "11.9.0"
22717
23000
  },
22718
23001
  {
22719
23002
  id: "press-repeat",
@@ -22750,7 +23033,7 @@ placeholder="Name or address\u2026"
22750
23033
  description: "End a hold without firing `onRelease` \u2014 for `Escape` and `pointercancel`."
22751
23034
  }
22752
23035
  ],
22753
- version: "11.7.0"
23036
+ version: "11.9.0"
22754
23037
  },
22755
23038
  {
22756
23039
  id: "create-press-repeat",
@@ -22762,7 +23045,7 @@ placeholder="Name or address\u2026"
22762
23045
  summary: "",
22763
23046
  description: "",
22764
23047
  members: [],
22765
- version: "11.7.0"
23048
+ version: "11.9.0"
22766
23049
  },
22767
23050
  {
22768
23051
  id: "listbox-navigation-config",
@@ -22805,7 +23088,7 @@ placeholder="Name or address\u2026"
22805
23088
  description: "Let Home/End jump to the ends of the list. Default false. In an editable combobox those keys belong to the caret \u2014 APG reserves them for text editing, and a control that steals them makes the text un-navigable while its list is open. Opt in only where focus is *not* in a text field (uni-multi-select-dropdown, whose focus rides the option checkboxes). Nothing is lost by leaving it off: opening with ArrowUp already lands on the last option, ArrowDown on the first, and navigation wraps at both ends."
22806
23089
  }
22807
23090
  ],
22808
- version: "11.7.0"
23091
+ version: "11.9.0"
22809
23092
  },
22810
23093
  {
22811
23094
  id: "listbox-navigation",
@@ -22878,7 +23161,7 @@ placeholder="Name or address\u2026"
22878
23161
  description: "Close when focus leaves the control entirely (not on internal moves)."
22879
23162
  }
22880
23163
  ],
22881
- version: "11.7.0"
23164
+ version: "11.9.0"
22882
23165
  },
22883
23166
  {
22884
23167
  id: "create-listbox-navigation",
@@ -22890,7 +23173,7 @@ placeholder="Name or address\u2026"
22890
23173
  summary: "Factory mirroring the signal-API style used elsewhere in the CDK.",
22891
23174
  description: "Factory mirroring the signal-API style used elsewhere in the CDK.",
22892
23175
  members: [],
22893
- version: "11.7.0"
23176
+ version: "11.9.0"
22894
23177
  },
22895
23178
  {
22896
23179
  id: "placement",
@@ -22902,7 +23185,7 @@ placeholder="Name or address\u2026"
22902
23185
  summary: "Native CSS Anchor Positioning helpers (Baseline 2026).",
22903
23186
  description: "Native CSS Anchor Positioning helpers (Baseline 2026). These replace the former",
22904
23187
  members: [],
22905
- version: "11.7.0"
23188
+ version: "11.9.0"
22906
23189
  },
22907
23190
  {
22908
23191
  id: "anchor-offset",
@@ -22927,7 +23210,7 @@ placeholder="Name or address\u2026"
22927
23210
  description: "Shift along the cross axis, from the aligned edge."
22928
23211
  }
22929
23212
  ],
22930
- version: "11.7.0"
23213
+ version: "11.9.0"
22931
23214
  },
22932
23215
  {
22933
23216
  id: "new-anchor-name",
@@ -22939,7 +23222,7 @@ placeholder="Name or address\u2026"
22939
23222
  summary: "Returns a document-unique dashed-ident usable as a CSS `anchor-name`.",
22940
23223
  description: "Returns a document-unique dashed-ident usable as a CSS `anchor-name`.",
22941
23224
  members: [],
22942
- version: "11.7.0"
23225
+ version: "11.9.0"
22943
23226
  },
22944
23227
  {
22945
23228
  id: "anchor-styles",
@@ -22951,7 +23234,7 @@ placeholder="Name or address\u2026"
22951
23234
  summary: "Emotion style object anchoring a panel to `anchor` at `placement`.",
22952
23235
  description: "Emotion style object anchoring a panel to `anchor` at `placement`. Spread into the panel's `css()` styles. The trigger element must carry `anchor-name: <anchor>` (see `newAnchorName`).",
22953
23236
  members: [],
22954
- version: "11.7.0"
23237
+ version: "11.9.0"
22955
23238
  },
22956
23239
  {
22957
23240
  id: "anchor-arrow-styles",
@@ -22963,7 +23246,7 @@ placeholder="Name or address\u2026"
22963
23246
  summary: "Absolute positioning for a rotated-square arrow sitting on the panel edge that faces the anchor.",
22964
23247
  description: "Absolute positioning for a rotated-square arrow sitting on the panel edge that faces the anchor. Static per placement: if the browser flips the panel via position-try, the arrow stays on the configured side (cosmetic-only degradation, matching the flip-support caveat above). `overlap` (default 0 \u2014 cut exactly on the panel edge) extends the kept half into the panel; see for when that is ever wanted.",
22965
23248
  members: [],
22966
- version: "11.7.0"
23249
+ version: "11.9.0"
22967
23250
  },
22968
23251
  {
22969
23252
  id: "spotlight-options",
@@ -22994,7 +23277,7 @@ placeholder="Name or address\u2026"
22994
23277
  description: "Scrim paint; scheme-invariant by convention, like `::backdrop`."
22995
23278
  }
22996
23279
  ],
22997
- version: "11.7.0"
23280
+ version: "11.9.0"
22998
23281
  },
22999
23282
  {
23000
23283
  id: "spotlight-styles",
@@ -23025,7 +23308,7 @@ placeholder="Name or address\u2026"
23025
23308
  description: "Hole-sized click-blocker, shown when the target must not be interactive."
23026
23309
  }
23027
23310
  ],
23028
- version: "11.7.0"
23311
+ version: "11.9.0"
23029
23312
  },
23030
23313
  {
23031
23314
  id: "anchor-rect",
@@ -23074,7 +23357,7 @@ placeholder="Name or address\u2026"
23074
23357
  description: ""
23075
23358
  }
23076
23359
  ],
23077
- version: "11.7.0"
23360
+ version: "11.9.0"
23078
23361
  },
23079
23362
  {
23080
23363
  id: "transform-origin-for",
@@ -23086,7 +23369,7 @@ placeholder="Name or address\u2026"
23086
23369
  summary: "Transform origin for a panel's open/close scale animation, derived from where the panel **actually** rendered relative to its anchor \u2014 not from the requested placement.",
23087
23370
  description: "Transform origin for a panel's open/close scale animation, derived from where the panel **actually** rendered relative to its anchor \u2014 not from the requested placement. `position-try-fallbacks` lets the browser flip a panel at viewport edges, and a statically mapped origin then animates from the wrong corner (a `bottom-end` picker flipped above its field would still scale from `top right`). Measure after the popover is shown and apply the result as an inline style. Returns keyword pairs like `'top right'` / `'bottom center'`, or `null` when the panel has no box yet (e.g. `display: none`, or jsdom).",
23088
23371
  members: [],
23089
- version: "11.7.0"
23372
+ version: "11.9.0"
23090
23373
  },
23091
23374
  {
23092
23375
  id: "transform-origins",
@@ -23098,7 +23381,7 @@ placeholder="Name or address\u2026"
23098
23381
  summary: "Placement \u2192 `transform-origin`, so scale animations grow from the anchor.",
23099
23382
  description: "Placement \u2192 `transform-origin`, so scale animations grow from the anchor.",
23100
23383
  members: [],
23101
- version: "11.7.0"
23384
+ version: "11.9.0"
23102
23385
  },
23103
23386
  {
23104
23387
  id: "set-anchor-name",
@@ -23110,7 +23393,7 @@ placeholder="Name or address\u2026"
23110
23393
  summary: "Write a CSS `anchor-name` onto an element (detached anchors and targets).",
23111
23394
  description: "Write a CSS `anchor-name` onto an element (detached anchors and targets).",
23112
23395
  members: [],
23113
- version: "11.7.0"
23396
+ version: "11.9.0"
23114
23397
  },
23115
23398
  {
23116
23399
  id: "clear-anchor-name",
@@ -23122,7 +23405,7 @@ placeholder="Name or address\u2026"
23122
23405
  summary: "",
23123
23406
  description: "",
23124
23407
  members: [],
23125
- version: "11.7.0"
23408
+ version: "11.9.0"
23126
23409
  },
23127
23410
  {
23128
23411
  id: "resolve-element",
@@ -23134,7 +23417,7 @@ placeholder="Name or address\u2026"
23134
23417
  summary: "Resolve an element-or-id reference.",
23135
23418
  description: "Resolve an element-or-id reference. Id strings are looked up at call time \u2014 never cache the result across opens, the element may have been re-rendered. `''` and null-ish mean \"unset\" (falsy guard: an empty string is the only typeable empty for a string-typed input).",
23136
23419
  members: [],
23137
- version: "11.7.0"
23420
+ version: "11.9.0"
23138
23421
  },
23139
23422
  {
23140
23423
  id: "is-toggle-open",
@@ -23146,7 +23429,7 @@ placeholder="Name or address\u2026"
23146
23429
  summary: "True when a native `toggle` event reports the overlay opening.",
23147
23430
  description: "True when a native `toggle` event reports the overlay opening.",
23148
23431
  members: [],
23149
- version: "11.7.0"
23432
+ version: "11.9.0"
23150
23433
  },
23151
23434
  {
23152
23435
  id: "discrete-overlay-transition",
@@ -23158,7 +23441,7 @@ placeholder="Name or address\u2026"
23158
23441
  summary: "The discrete-transition block that animates an element into and out of the top layer: `transition-behavior: allow-discrete` over the `hidden` keys plus `display`/`overlay`, the shown state under `:popover-open`, and `@starting-style` so entry transitions run from the hidden state.",
23159
23442
  description: "The discrete-transition block that animates an element into and out of the top layer: `transition-behavior: allow-discrete` over the `hidden` keys plus `display`/`overlay`, the shown state under `:popover-open`, and `@starting-style` so entry transitions run from the hidden state. `display` and `overlay` must ride along or the element cannot animate into and out of the top layer at all \u2014 it would simply appear and vanish. `timingFunction` is omitted from the output when not given, leaving the CSS initial value (`ease`), so callers that never asked for one are unaffected.",
23160
23443
  members: [],
23161
- version: "11.7.0"
23444
+ version: "11.9.0"
23162
23445
  },
23163
23446
  {
23164
23447
  id: "restore-overlay-focus",
@@ -23170,7 +23453,7 @@ placeholder="Name or address\u2026"
23170
23453
  summary: "Returns focus to `target` when an overlay closes while focus was inside its panel (or was dropped on `<body>` by the top layer closing), so keyboard users are never stranded (WCAG 2.4.3).",
23171
23454
  description: "Returns focus to `target` when an overlay closes while focus was inside its panel (or was dropped on `<body>` by the top layer closing), so keyboard users are never stranded (WCAG 2.4.3). Focus resting anywhere else is left alone.",
23172
23455
  members: [],
23173
- version: "11.7.0"
23456
+ version: "11.9.0"
23174
23457
  },
23175
23458
  {
23176
23459
  id: "focusable-elements",
@@ -23182,7 +23465,7 @@ placeholder="Name or address\u2026"
23182
23465
  summary: "The focusable elements inside `root`, in DOM order.",
23183
23466
  description: "The focusable elements inside `root`, in DOM order. Filters disabled controls, and hidden ones where the environment can tell: jsdom reports `offsetParent` as null for every element, so the visibility filter applies only when the document actually lays out (some element has an offsetParent).",
23184
23467
  members: [],
23185
- version: "11.7.0"
23468
+ version: "11.9.0"
23186
23469
  },
23187
23470
  {
23188
23471
  id: "backdrop-dismiss",
@@ -23207,7 +23490,7 @@ placeholder="Name or address\u2026"
23207
23490
  description: "True only when both the press and the click landed on the dialog itself."
23208
23491
  }
23209
23492
  ],
23210
- version: "11.7.0"
23493
+ version: "11.9.0"
23211
23494
  },
23212
23495
  {
23213
23496
  id: "sort-direction",
@@ -23219,7 +23502,38 @@ placeholder="Name or address\u2026"
23219
23502
  summary: "",
23220
23503
  description: "",
23221
23504
  members: [],
23222
- version: "11.7.0"
23505
+ version: "11.9.0"
23506
+ },
23507
+ {
23508
+ id: "row-key",
23509
+ name: "RowKey",
23510
+ kind: "type",
23511
+ module: "datasource",
23512
+ importPath: "@uni-design-system/uni-angular",
23513
+ signature: "type RowKey = string | number",
23514
+ summary: "What `rowId` returns: a stable identity for a row across re-fetches.",
23515
+ description: "What `rowId` returns: a stable identity for a row across re-fetches.",
23516
+ members: [],
23517
+ version: "11.9.0"
23518
+ },
23519
+ {
23520
+ id: "uni-datasource-options",
23521
+ name: "UniDatasourceOptions",
23522
+ kind: "interface",
23523
+ module: "datasource",
23524
+ importPath: "@uni-design-system/uni-angular",
23525
+ signature: "interface UniDatasourceOptions<T>",
23526
+ summary: "Options shared by every datasource.",
23527
+ description: "Options shared by every datasource.",
23528
+ members: [
23529
+ {
23530
+ name: "rowId",
23531
+ kind: "property",
23532
+ signature: "rowId?: (row: T) => RowKey",
23533
+ description: "Stable identity for a row. Unset, rows are compared by reference, which never matches a row rebuilt from a fresh fetch \u2014 a realtime update that replaces the records would empty a selection and move an expanded row. Set it (`(row) => row.id`) and selection, `uni-data-table`'s expanded row and its row tracking all key by it instead."
23534
+ }
23535
+ ],
23536
+ version: "11.9.0"
23223
23537
  },
23224
23538
  {
23225
23539
  id: "sort",
@@ -23244,7 +23558,7 @@ placeholder="Name or address\u2026"
23244
23558
  description: ""
23245
23559
  }
23246
23560
  ],
23247
- version: "11.7.0"
23561
+ version: "11.9.0"
23248
23562
  },
23249
23563
  {
23250
23564
  id: "uni-base-datasource",
@@ -23274,6 +23588,18 @@ placeholder="Name or address\u2026"
23274
23588
  signature: "selections = signal<T[]>([])",
23275
23589
  description: ""
23276
23590
  },
23591
+ {
23592
+ name: "rowId",
23593
+ kind: "property",
23594
+ signature: "rowId?: (row: T) => RowKey",
23595
+ description: "See `UniDatasourceOptions.rowId`. Settable after construction."
23596
+ },
23597
+ {
23598
+ name: "rowKey",
23599
+ kind: "method",
23600
+ signature: "rowKey(row: T): RowKey | T",
23601
+ description: "The row's identity: its `rowId`, or the row itself when there is none."
23602
+ },
23277
23603
  {
23278
23604
  name: "sort",
23279
23605
  kind: "property",
@@ -23358,6 +23684,12 @@ placeholder="Name or address\u2026"
23358
23684
  signature: "toggleSelection(row: T)",
23359
23685
  description: ""
23360
23686
  },
23687
+ {
23688
+ name: "setSelected",
23689
+ kind: "method",
23690
+ signature: "setSelected(rows: T[], selected: boolean)",
23691
+ description: "Select or deselect several rows at once \u2014 a select-all over the rows that may be selected, leaving any others (another page's) as they are. Keyed by `rowId`, so a selected row re-fetched as a new object is replaced rather than duplicated."
23692
+ },
23361
23693
  {
23362
23694
  name: "clearSelections",
23363
23695
  kind: "method",
@@ -23413,7 +23745,7 @@ placeholder="Name or address\u2026"
23413
23745
  description: ""
23414
23746
  }
23415
23747
  ],
23416
- version: "11.7.0"
23748
+ version: "11.9.0"
23417
23749
  },
23418
23750
  {
23419
23751
  id: "page-request",
@@ -23456,7 +23788,7 @@ placeholder="Name or address\u2026"
23456
23788
  description: ""
23457
23789
  }
23458
23790
  ],
23459
- version: "11.7.0"
23791
+ version: "11.9.0"
23460
23792
  },
23461
23793
  {
23462
23794
  id: "page-response",
@@ -23493,7 +23825,7 @@ placeholder="Name or address\u2026"
23493
23825
  description: ""
23494
23826
  }
23495
23827
  ],
23496
- version: "11.7.0"
23828
+ version: "11.9.0"
23497
23829
  },
23498
23830
  {
23499
23831
  id: "data-loader",
@@ -23505,7 +23837,7 @@ placeholder="Name or address\u2026"
23505
23837
  summary: "",
23506
23838
  description: "",
23507
23839
  members: [],
23508
- version: "11.7.0"
23840
+ version: "11.9.0"
23509
23841
  },
23510
23842
  {
23511
23843
  id: "uni-server-side-datasource",
@@ -23644,7 +23976,7 @@ placeholder="Name or address\u2026"
23644
23976
  description: ""
23645
23977
  }
23646
23978
  ],
23647
- version: "11.7.0"
23979
+ version: "11.9.0"
23648
23980
  },
23649
23981
  {
23650
23982
  id: "uni-datasource",
@@ -23656,7 +23988,7 @@ placeholder="Name or address\u2026"
23656
23988
  summary: "",
23657
23989
  description: "",
23658
23990
  members: [],
23659
- version: "11.7.0"
23991
+ version: "11.9.0"
23660
23992
  },
23661
23993
  {
23662
23994
  id: "uni-record-datasource",
@@ -23765,7 +24097,7 @@ placeholder="Name or address\u2026"
23765
24097
  description: ""
23766
24098
  }
23767
24099
  ],
23768
- version: "11.7.0"
24100
+ version: "11.9.0"
23769
24101
  },
23770
24102
  {
23771
24103
  id: "local-storage-service",
@@ -23820,7 +24152,7 @@ placeholder="Name or address\u2026"
23820
24152
  description: ""
23821
24153
  }
23822
24154
  ],
23823
- version: "11.7.0"
24155
+ version: "11.9.0"
23824
24156
  },
23825
24157
  {
23826
24158
  id: "alert",
@@ -23875,7 +24207,7 @@ placeholder="Name or address\u2026"
23875
24207
  description: ""
23876
24208
  }
23877
24209
  ],
23878
- version: "11.7.0"
24210
+ version: "11.9.0"
23879
24211
  },
23880
24212
  {
23881
24213
  id: "snackbar",
@@ -23930,7 +24262,7 @@ placeholder="Name or address\u2026"
23930
24262
  description: ""
23931
24263
  }
23932
24264
  ],
23933
- version: "11.7.0"
24265
+ version: "11.9.0"
23934
24266
  },
23935
24267
  {
23936
24268
  id: "confirmation",
@@ -23979,7 +24311,7 @@ placeholder="Name or address\u2026"
23979
24311
  description: ""
23980
24312
  }
23981
24313
  ],
23982
- version: "11.7.0"
24314
+ version: "11.9.0"
23983
24315
  },
23984
24316
  {
23985
24317
  id: "notification-service",
@@ -24046,7 +24378,7 @@ placeholder="Name or address\u2026"
24046
24378
  description: ""
24047
24379
  }
24048
24380
  ],
24049
- version: "11.7.0"
24381
+ version: "11.9.0"
24050
24382
  },
24051
24383
  {
24052
24384
  id: "option",
@@ -24083,7 +24415,7 @@ placeholder="Name or address\u2026"
24083
24415
  description: "Visible and announced, but not committable; listbox navigation skips it."
24084
24416
  }
24085
24417
  ],
24086
- version: "11.7.0"
24418
+ version: "11.9.0"
24087
24419
  },
24088
24420
  {
24089
24421
  id: "options",
@@ -24095,7 +24427,7 @@ placeholder="Name or address\u2026"
24095
24427
  summary: "",
24096
24428
  description: "",
24097
24429
  members: [],
24098
- version: "11.7.0"
24430
+ version: "11.9.0"
24099
24431
  },
24100
24432
  {
24101
24433
  id: "use-timer",
@@ -24107,7 +24439,7 @@ placeholder="Name or address\u2026"
24107
24439
  summary: "",
24108
24440
  description: "",
24109
24441
  members: [],
24110
- version: "11.7.0"
24442
+ version: "11.9.0"
24111
24443
  },
24112
24444
  {
24113
24445
  id: "acceptable-file",
@@ -24119,7 +24451,7 @@ placeholder="Name or address\u2026"
24119
24451
  summary: "",
24120
24452
  description: "",
24121
24453
  members: [],
24122
- version: "11.7.0"
24454
+ version: "11.9.0"
24123
24455
  },
24124
24456
  {
24125
24457
  id: "get-file-extension",
@@ -24131,7 +24463,7 @@ placeholder="Name or address\u2026"
24131
24463
  summary: "",
24132
24464
  description: "",
24133
24465
  members: [],
24134
- version: "11.7.0"
24466
+ version: "11.9.0"
24135
24467
  },
24136
24468
  {
24137
24469
  id: "query-permission",
@@ -24143,7 +24475,7 @@ placeholder="Name or address\u2026"
24143
24475
  summary: "The current state of a browser permission.",
24144
24476
  description: 'The current state of a browser permission. Resolves `unsupported` \u2014 never rejects \u2014 where the Permissions API is missing or does not know the name, which is the norm rather than the exception: Firefox and Safari reject `clipboard-write`, for one. Treat `unsupported` as "can\'t tell", not "no".',
24145
24477
  members: [],
24146
- version: "11.7.0"
24478
+ version: "11.9.0"
24147
24479
  },
24148
24480
  {
24149
24481
  id: "permission-service",
@@ -24168,7 +24500,7 @@ placeholder="Name or address\u2026"
24168
24500
  description: ""
24169
24501
  }
24170
24502
  ],
24171
- version: "11.7.0"
24503
+ version: "11.9.0"
24172
24504
  },
24173
24505
  {
24174
24506
  id: "permission",
@@ -24180,7 +24512,7 @@ placeholder="Name or address\u2026"
24180
24512
  summary: "",
24181
24513
  description: "",
24182
24514
  members: [],
24183
- version: "11.7.0"
24515
+ version: "11.9.0"
24184
24516
  },
24185
24517
  {
24186
24518
  id: "permission-state",
@@ -24192,7 +24524,7 @@ placeholder="Name or address\u2026"
24192
24524
  summary: "",
24193
24525
  description: "",
24194
24526
  members: [],
24195
- version: "11.7.0"
24527
+ version: "11.9.0"
24196
24528
  },
24197
24529
  {
24198
24530
  id: "clipboard-copy-result",
@@ -24204,7 +24536,7 @@ placeholder="Name or address\u2026"
24204
24536
  summary: "How a copy ended: - `copied` \u2014 the content is on the clipboard.",
24205
24537
  description: "How a copy ended: - `copied` \u2014 the content is on the clipboard. - `denied` \u2014 the user or a policy has blocked clipboard access for this site; only a change in the browser's site settings will fix it. - `unsupported` \u2014 no Clipboard API here (an insecure context, a server render, an old browser) or the browser cannot write one of the types. - `failed` \u2014 the browser refused this attempt for another reason, most often a call made outside a user gesture or from an unfocused document.",
24206
24538
  members: [],
24207
- version: "11.7.0"
24539
+ version: "11.9.0"
24208
24540
  },
24209
24541
  {
24210
24542
  id: "clipboard-data",
@@ -24216,7 +24548,7 @@ placeholder="Name or address\u2026"
24216
24548
  summary: "One clipboard representation; a promise lets the data arrive after the gesture.",
24217
24549
  description: "One clipboard representation; a promise lets the data arrive after the gesture.",
24218
24550
  members: [],
24219
- version: "11.7.0"
24551
+ version: "11.9.0"
24220
24552
  },
24221
24553
  {
24222
24554
  id: "clipboard-content",
@@ -24228,7 +24560,7 @@ placeholder="Name or address\u2026"
24228
24560
  summary: "What to copy: a plain string, or one item in several representations keyed by MIME type \u2014 `{ 'text/plain': \u2026, 'text/html': \u2026 }`, `{ 'image/png': blob }`.",
24229
24561
  description: "What to copy: a plain string, or one item in several representations keyed by MIME type \u2014 `{ 'text/plain': \u2026, 'text/html': \u2026 }`, `{ 'image/png': blob }`.",
24230
24562
  members: [],
24231
- version: "11.7.0"
24563
+ version: "11.9.0"
24232
24564
  },
24233
24565
  {
24234
24566
  id: "copy-to-clipboard",
@@ -24240,14 +24572,14 @@ placeholder="Name or address\u2026"
24240
24572
  summary: "Copies text or rich content with the Async Clipboard API.",
24241
24573
  description: "Copies text or rich content with the Async Clipboard API. Never rejects: the result says what happened, so a caller can tell the user why. Call it directly from the click or key handler. The write starts synchronously, before anything is awaited, because browsers only honor it inside the user gesture \u2014 which is also why the `clipboard-write` permission is consulted after a refusal, to explain it, rather than before the attempt. For content that has to be fetched or rendered first, pass a promise as the value instead of awaiting it yourself.",
24242
24574
  members: [],
24243
- version: "11.7.0"
24575
+ version: "11.9.0"
24244
24576
  }
24245
24577
  ],
24246
24578
  utilityDocs: [
24247
24579
  {
24248
24580
  module: "datasource",
24249
24581
  title: "Datasource",
24250
- markdown: "# Datasource\n\nThe Datasource system provides a flexible and reactive way to manage data collections in Angular applications. It supports both client-side and server-side data operations with a unified API.\n\n## Architecture\n\nThe datasource system consists of three main classes:\n\n- **`UniBaseDatasource<T>`**: Abstract base class defining the common interface\n- **`UniRecordDatasource<T>`**: Client-side datasource for in-memory data operations\n- **`UniServerSideDatasource<T>`**: Server-side datasource using Angular's resource signal\n\n## Features\n\n- **Reactive State Management**: Built with Angular signals for efficient reactivity\n- **Unified API**: Both client-side and server-side datasources implement the same interface\n- **Sorting**: Sort data by any column in ascending or descending order\n- **Filtering**: Apply filters with appropriate handling for client vs server-side\n- **Pagination**: Navigate through data with built-in pagination controls\n- **Selection**: Track and manage selected items\n- **Loading States**: Server-side datasource provides loading and error states\n\n## Client-Side Datasource\n\nFor in-memory data operations, use `UniRecordDatasource`:\n\n```typescript\nimport { UniRecordDatasource } from '@uni-design-system/uni-angular';\n\ninterface User {\n id: number;\n name: string;\n email: string;\n age: number;\n}\n\n@Component({...})\nclass ClientSideComponent {\n // Static data for client-side operations\n users: User[] = [\n { id: 1, name: 'John Doe', email: 'john@example.com', age: 30 },\n { id: 2, name: 'Jane Smith', email: 'jane@example.com', age: 25 },\n // more users...\n ];\n\n datasource = new UniRecordDatasource<User>(this.users);\n\n constructor() {\n // Set page size for pagination\n this.datasource.setPageSize(10);\n\n // Apply a filter function (client-side filtering)\n this.datasource.setFilter(user => user.age > 18);\n\n // Sort by a column\n this.datasource.sortRecords({\n column: 'name',\n direction: 'asc'\n });\n }\n\n // Handle row selection\n onRowClick(user: User) {\n this.datasource.toggleSelection(user);\n }\n\n // Navigate to next page\n nextPage() {\n this.datasource.nextPage();\n }\n}\n```\n\n## Server-Side Datasource\n\nFor server-side operations with automatic loading states, use `UniServerSideDatasource`:\n\n```typescript\nimport { UniServerSideDatasource, PageRequest, PageResponse } from '@uni-design-system/uni-angular';\n\n@Component({...})\nclass ServerSideComponent {\n datasource = new UniServerSideDatasource<User>(\n // Data loader function\n async (request: PageRequest): Promise<PageResponse<User>> => {\n const response = await this.userService.getUsers({\n page: request.pageNumber,\n size: request.pageSize,\n sort: request.sortColumn,\n order: request.sortDirection,\n filter: request.filter\n });\n\n return {\n data: response.users,\n totalRecords: response.total,\n pageNumber: request.pageNumber,\n pageSize: request.pageSize\n };\n },\n 10 // initial page size\n );\n\n constructor() {\n // Apply server-side filter (sends filter object to server)\n this.datasource.setFilter({ department: 'Engineering', active: true });\n\n // Sort by a column (triggers server request)\n this.datasource.sortRecords({\n column: 'name',\n direction: 'asc'\n });\n }\n\n // Access loading and error states\n get isLoading() {\n return this.datasource.isLoading();\n }\n\n get hasError() {\n return this.datasource.hasError();\n }\n\n // Refresh data from server\n refreshData() {\n this.datasource.refresh();\n }\n}\n```\n\n## API Reference\n\n### Common Properties (Both Datasources)\n\n- `records`: Signal containing the current page's filtered and sorted records\n- `recordCount`: Signal with the count of filtered records\n- `selections`: Signal containing currently selected items\n- `sort`: Signal containing the current sort configuration\n- `sortColumn`: Computed signal with the current sort column\n- `sortDirection`: Computed signal with the current sort direction\n- `pageIndex`: Signal with the current page index (zero-based)\n- `pageSize`: Signal with the number of items per page\n- `pageCount`: Signal with the total number of pages\n- `pages`: Signal with array of page numbers for pagination UI\n- `truncatedPages`: Signal with truncated page numbers (includes ellipsis)\n- `disablePrevious`: Signal indicating if previous button should be disabled\n- `disableNext`: Signal indicating if next button should be disabled\n\n### Common Methods (Both Datasources)\n\n- `isSelected(row)`: Checks if a row is selected\n- `toggleSelection(row)`: Toggles selection state of a row\n- `clearSelections()`: Clears all selections\n- `selectAll()`: Selects all records on current page\n- `sortRecords(sort)`: Sets the sort configuration\n- `firstPage()`, `nextPage()`, `previousPage()`, `lastPage()`: Navigation methods\n- `jumpToPage(page)`: Jumps to a specific page\n- `setPageSize(size)`: Sets the page size and resets to first page\n\n### Record Datasource Specific\n\n**Properties:**\n\n- `initialRecords`: Signal containing the original unfiltered data\n- `filter`: Signal containing the current filter function\n\n**Methods:**\n\n- `setFilter(predicate: (item: T) => boolean)`: Sets a filter function for client-side filtering\n- `clearFilter()`: Clears the current filter (shows all records)\n\n### Server-Side Datasource Specific\n\n**Properties:**\n\n- `isLoading`: Signal indicating if data is currently being loaded\n- `error`: Signal containing any loading errors\n- `hasError`: Signal indicating if there's an error state\n\n**Methods:**\n\n- `setFilter(filterObj: Record<string, any>)`: Sets filter parameters sent to server\n- `clearFilter()`: Clears all filter parameters\n- `refresh()`: Manually triggers a data reload from server\n- `getPageRequest()`: Returns the current page request parameters\n\n### Types\n\n```typescript\ninterface PageRequest {\n pageNumber: number;\n pageSize: number;\n sortColumn?: string;\n sortDirection?: SortDirection;\n filter?: Record<string, any>;\n}\n\ninterface PageResponse<T> {\n data: T[];\n totalRecords: number;\n pageNumber: number;\n pageSize: number;\n}\n\ntype DataLoader<T> = (request: PageRequest) => Promise<PageResponse<T>>;\n\ntype SortDirection = 'asc' | 'desc' | 'indet';\n\ninterface Sort<T> {\n column?: keyof T;\n direction: SortDirection;\n}\n```\n\n## Examples\n\n_Live demo on the Storybook page._"
24582
+ markdown: "# Datasource\n\nThe Datasource system provides a flexible and reactive way to manage data collections in Angular applications. It supports both client-side and server-side data operations with a unified API.\n\n## Architecture\n\nThe datasource system consists of three main classes:\n\n- **`UniBaseDatasource<T>`**: Abstract base class defining the common interface\n- **`UniRecordDatasource<T>`**: Client-side datasource for in-memory data operations\n- **`UniServerSideDatasource<T>`**: Server-side datasource using Angular's resource signal\n\n## Features\n\n- **Reactive State Management**: Built with Angular signals for efficient reactivity\n- **Unified API**: Both client-side and server-side datasources implement the same interface\n- **Sorting**: Sort data by any column in ascending or descending order\n- **Filtering**: Apply filters with appropriate handling for client vs server-side\n- **Pagination**: Navigate through data with built-in pagination controls\n- **Selection**: Track and manage selected items\n- **Loading States**: Server-side datasource provides loading and error states\n\n## Client-Side Datasource\n\nFor in-memory data operations, use `UniRecordDatasource`:\n\n```typescript\nimport { UniRecordDatasource } from '@uni-design-system/uni-angular';\n\ninterface User {\n id: number;\n name: string;\n email: string;\n age: number;\n}\n\n@Component({...})\nclass ClientSideComponent {\n // Static data for client-side operations\n users: User[] = [\n { id: 1, name: 'John Doe', email: 'john@example.com', age: 30 },\n { id: 2, name: 'Jane Smith', email: 'jane@example.com', age: 25 },\n // more users...\n ];\n\n datasource = new UniRecordDatasource<User>(this.users);\n\n constructor() {\n // Set page size for pagination\n this.datasource.setPageSize(10);\n\n // Apply a filter function (client-side filtering)\n this.datasource.setFilter(user => user.age > 18);\n\n // Sort by a column\n this.datasource.sortRecords({\n column: 'name',\n direction: 'asc'\n });\n }\n\n // Handle row selection\n onRowClick(user: User) {\n this.datasource.toggleSelection(user);\n }\n\n // Navigate to next page\n nextPage() {\n this.datasource.nextPage();\n }\n}\n```\n\n## Server-Side Datasource\n\nFor server-side operations with automatic loading states, use `UniServerSideDatasource`:\n\n```typescript\nimport { UniServerSideDatasource, PageRequest, PageResponse } from '@uni-design-system/uni-angular';\n\n@Component({...})\nclass ServerSideComponent {\n datasource = new UniServerSideDatasource<User>(\n // Data loader function\n async (request: PageRequest): Promise<PageResponse<User>> => {\n const response = await this.userService.getUsers({\n page: request.pageNumber,\n size: request.pageSize,\n sort: request.sortColumn,\n order: request.sortDirection,\n filter: request.filter\n });\n\n return {\n data: response.users,\n totalRecords: response.total,\n pageNumber: request.pageNumber,\n pageSize: request.pageSize\n };\n },\n 10 // initial page size\n );\n\n constructor() {\n // Apply server-side filter (sends filter object to server)\n this.datasource.setFilter({ department: 'Engineering', active: true });\n\n // Sort by a column (triggers server request)\n this.datasource.sortRecords({\n column: 'name',\n direction: 'asc'\n });\n }\n\n // Access loading and error states\n get isLoading() {\n return this.datasource.isLoading();\n }\n\n get hasError() {\n return this.datasource.hasError();\n }\n\n // Refresh data from server\n refreshData() {\n this.datasource.refresh();\n }\n}\n```\n\n## API Reference\n\n### Common Properties (Both Datasources)\n\n- `records`: Signal containing the current page's filtered and sorted records\n- `recordCount`: Signal with the count of filtered records\n- `selections`: Signal containing currently selected items\n- `sort`: Signal containing the current sort configuration\n- `sortColumn`: Computed signal with the current sort column\n- `sortDirection`: Computed signal with the current sort direction\n- `pageIndex`: Signal with the current page index (zero-based)\n- `pageSize`: Signal with the number of items per page\n- `pageCount`: Signal with the total number of pages\n- `pages`: Signal with array of page numbers for pagination UI\n- `truncatedPages`: Signal with truncated page numbers (includes ellipsis)\n- `disablePrevious`: Signal indicating if previous button should be disabled\n- `disableNext`: Signal indicating if next button should be disabled\n\n### Row identity\n\nBoth constructors take an options object with `rowId`, a function returning a\nstable key for a row (`{ rowId: (row) => row.id }`); it is also settable\nafterwards (`datasource.rowId = \u2026`). Without one, rows are compared by\nreference \u2014 which never matches a row rebuilt from a fresh fetch, so a\nrealtime update that replaced the records would empty the selection. With\none, `isSelected`, `toggleSelection` and `setSelected` key by it, and so do\n`uni-data-table`'s expanded row and its row tracking.\n\n### Common Methods (Both Datasources)\n\n- `isSelected(row)`: Checks if a row is selected (by `rowId` when set)\n- `toggleSelection(row)`: Toggles selection state of a row\n- `setSelected(rows, selected)`: Selects or deselects several rows, leaving the rest as they are\n- `clearSelections()`: Clears all selections\n- `selectAll()`: Selects all records on current page\n- `sortRecords(sort)`: Sets the sort configuration\n- `firstPage()`, `nextPage()`, `previousPage()`, `lastPage()`: Navigation methods\n- `jumpToPage(page)`: Jumps to a specific page\n- `setPageSize(size)`: Sets the page size and resets to first page\n\n### Record Datasource Specific\n\n**Properties:**\n\n- `initialRecords`: Signal containing the original unfiltered data\n- `filter`: Signal containing the current filter function\n\n**Methods:**\n\n- `setFilter(predicate: (item: T) => boolean)`: Sets a filter function for client-side filtering\n- `clearFilter()`: Clears the current filter (shows all records)\n\n### Server-Side Datasource Specific\n\n**Properties:**\n\n- `isLoading`: Signal indicating if data is currently being loaded\n- `error`: Signal containing any loading errors\n- `hasError`: Signal indicating if there's an error state\n\n**Methods:**\n\n- `setFilter(filterObj: Record<string, any>)`: Sets filter parameters sent to server\n- `clearFilter()`: Clears all filter parameters\n- `refresh()`: Manually triggers a data reload from server\n- `getPageRequest()`: Returns the current page request parameters\n\n### Types\n\n```typescript\ninterface PageRequest {\n pageNumber: number;\n pageSize: number;\n sortColumn?: string;\n sortDirection?: SortDirection;\n filter?: Record<string, any>;\n}\n\ninterface PageResponse<T> {\n data: T[];\n totalRecords: number;\n pageNumber: number;\n pageSize: number;\n}\n\ntype DataLoader<T> = (request: PageRequest) => Promise<PageResponse<T>>;\n\ntype SortDirection = 'asc' | 'desc' | 'indet';\n\ninterface Sort<T> {\n column?: keyof T;\n direction: SortDirection;\n}\n```\n\n## Examples\n\n_Live demo on the Storybook page._"
24251
24583
  },
24252
24584
  {
24253
24585
  module: "local-storage",
@@ -25703,7 +26035,9 @@ var buildComponents = (c) => ({
25703
26035
  textAlign: "center",
25704
26036
  divider: void 0,
25705
26037
  closeButtonIcon: "close",
25706
- closeButtonSize: "md"
26038
+ closeButtonSize: "md",
26039
+ richColor: void 0,
26040
+ richPadding: "md"
25707
26041
  } },
25708
26042
  select: { options: {
25709
26043
  toggleIcon: "chevronDown",
@@ -26312,7 +26646,10 @@ var buildComponents = (c) => ({
26312
26646
  rowHoverColor: "primary-container",
26313
26647
  loadingOverlayColor: "scrim",
26314
26648
  loadingSpinnerColor: "primary",
26315
- loadingSpinnerSize: 40
26649
+ loadingSpinnerSize: 40,
26650
+ selectionColumnWidth: 40,
26651
+ selectionCheckboxSize: "sm",
26652
+ selectedRowColor: void 0
26316
26653
  } },
26317
26654
  notificationBadge: {
26318
26655
  options: {
@@ -27880,4 +28217,4 @@ export {
27880
28217
  buildStoredTheme,
27881
28218
  createUniServer
27882
28219
  };
27883
- //# sourceMappingURL=chunk-Y6SCKJEM.js.map
28220
+ //# sourceMappingURL=chunk-5CI6QESE.js.map