@uni-design-system/uni-mcp 4.7.0 → 4.7.2

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,16 +7,16 @@ import { z } from "zod";
7
7
  // src/data/uni-index.json
8
8
  var uni_index_default = {
9
9
  meta: {
10
- version: "8.2.0",
11
- builtAt: "2026-08-20T22:58:33.744Z",
10
+ version: "9.0.0",
11
+ builtAt: "2026-08-23T15:31:18.523Z",
12
12
  frameworks: [
13
13
  "angular"
14
14
  ],
15
15
  counts: {
16
- components: 76,
17
- tokens: 353,
16
+ components: 79,
17
+ tokens: 401,
18
18
  themes: 2,
19
- examples: 168
19
+ examples: 194
20
20
  }
21
21
  },
22
22
  components: [
@@ -27,7 +27,7 @@ var uni_index_default = {
27
27
  summary: "",
28
28
  description: "",
29
29
  category: "feedback",
30
- version: "8.2.0",
30
+ version: "9.0.0",
31
31
  bindings: {
32
32
  angular: {
33
33
  importPath: "@uni-design-system/uni-angular",
@@ -90,7 +90,7 @@ var uni_index_default = {
90
90
  relatedTokens: [
91
91
  "alert.behavior.topPosition",
92
92
  "alert.behavior.borderRadius",
93
- "alert.behavior.transitionSpeed",
93
+ "alert.behavior.motion",
94
94
  "alert.behavior.elevation"
95
95
  ]
96
96
  },
@@ -101,7 +101,7 @@ var uni_index_default = {
101
101
  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.",
102
102
  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.",
103
103
  category: "components",
104
- version: "8.2.0",
104
+ version: "9.0.0",
105
105
  bindings: {
106
106
  angular: {
107
107
  importPath: "@uni-design-system/uni-angular",
@@ -158,7 +158,7 @@ var uni_index_default = {
158
158
  summary: "Identity avatar with a graceful fallback chain: image \u2192 initials from `name` \u2192 themed symbol.",
159
159
  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.",
160
160
  category: "components",
161
- version: "8.2.0",
161
+ version: "9.0.0",
162
162
  bindings: {
163
163
  angular: {
164
164
  importPath: "@uni-design-system/uni-angular",
@@ -237,7 +237,7 @@ var uni_index_default = {
237
237
  summary: "Overlapping stack of avatars.",
238
238
  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.",
239
239
  category: "components",
240
- version: "8.2.0",
240
+ version: "9.0.0",
241
241
  bindings: {
242
242
  angular: {
243
243
  importPath: "@uni-design-system/uni-angular",
@@ -270,7 +270,7 @@ var uni_index_default = {
270
270
  summary: "",
271
271
  description: "",
272
272
  category: "primitives",
273
- version: "8.2.0",
273
+ version: "9.0.0",
274
274
  bindings: {
275
275
  angular: {
276
276
  importPath: "@uni-design-system/uni-angular",
@@ -351,7 +351,7 @@ var uni_index_default = {
351
351
  summary: "",
352
352
  description: "",
353
353
  category: "feedback",
354
- version: "8.2.0",
354
+ version: "9.0.0",
355
355
  bindings: {
356
356
  angular: {
357
357
  importPath: "@uni-design-system/uni-angular",
@@ -432,7 +432,7 @@ var uni_index_default = {
432
432
  summary: "",
433
433
  description: "",
434
434
  category: "directives",
435
- version: "8.2.0",
435
+ version: "9.0.0",
436
436
  bindings: {
437
437
  angular: {
438
438
  importPath: "@uni-design-system/uni-angular",
@@ -454,20 +454,20 @@ var uni_index_default = {
454
454
  name: "Box",
455
455
  status: "stable",
456
456
  summary: 'The base layout primitive, applied as an attribute to any element so semantics stay yours: `<main box-layout [grow]="1" padding="md">`.',
457
- description: 'The base layout primitive, applied as an attribute to any element so semantics stay yours: `<main box-layout [grow]="1" padding="md">`. Exception: other components\' host elements (`<uni-card box-layout>` would put two components on one element) \u2014 wrap those in a `<div box-layout>`. 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.',
457
+ 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.',
458
458
  category: "layout",
459
- version: "8.2.0",
459
+ version: "9.0.0",
460
460
  bindings: {
461
461
  angular: {
462
462
  importPath: "@uni-design-system/uni-angular",
463
463
  selectorOrTag: "[uni-box-layout], [box-layout]",
464
464
  api: [
465
465
  {
466
- name: "color",
466
+ name: "containerColor",
467
467
  kind: "input",
468
468
  type: "ContainerColorToken",
469
469
  required: false,
470
- description: ""
470
+ description: "A container color *pair*: the named surface plus its paired on-color, so a box and its contents stay legible together. Named `containerColor`, not `color`, because it is not the CSS `color` property \u2014 `uni-text` owns that name, and it maps to it directly. The two directives share elements routinely (`<div row-layout uni-text>`), and one `color` binding would feed both: the box would paint the surface and the text would take the same token, rendering ink on identical ink."
471
471
  },
472
472
  {
473
473
  name: "backgroundColor",
@@ -638,6 +638,34 @@ var uni_index_default = {
638
638
  required: false,
639
639
  description: ""
640
640
  },
641
+ {
642
+ name: "flex",
643
+ kind: "input",
644
+ type: "number | string",
645
+ required: false,
646
+ description: 'The `flex` shorthand. `[flex]="1"` is `flex: 1` \u2014 grow, shrink and a zero basis \u2014 which `grow` alone cannot express, since it leaves `flex-basis: auto`. Wins over `grow` when both are set.'
647
+ },
648
+ {
649
+ name: "shrink",
650
+ kind: "input",
651
+ type: "number",
652
+ required: false,
653
+ description: ""
654
+ },
655
+ {
656
+ name: "basis",
657
+ kind: "input",
658
+ type: "number | string",
659
+ required: false,
660
+ description: ""
661
+ },
662
+ {
663
+ name: "marginInline",
664
+ kind: "input",
665
+ type: "'auto' | NullableSize",
666
+ required: false,
667
+ description: 'Inline-axis margin. `marginInline="auto"` centers a `maxWidth` container \u2014 the one thing flex centering cannot do without an extra wrapper. Only the inline axis is exposed: block margins collapse and fight `gap`, which is why the primitives carry no margin otherwise.'
668
+ },
641
669
  {
642
670
  name: "display",
643
671
  kind: "input",
@@ -801,11 +829,26 @@ var uni_index_default = {
801
829
  {
802
830
  title: "Primary",
803
831
  framework: "angular",
804
- code: "<!-- Storybook story: Primary -->\n<div box-layout ${argsToTemplate(props)}>\n<span uni-text>${ngContent}</span>\n</div>\n<!-- args:\n{\n color: 'secondary-container',\n borderRadius: 'md',\n padding: 'lg',\n ngContent: 'Box Content.',\n }\n-->"
832
+ code: "<!-- Storybook story: Primary -->\n<div box-layout ${argsToTemplate(props)}>\n<span uni-text>${ngContent}</span>\n</div>\n<!-- args:\n{\n containerColor: 'secondary-container',\n borderRadius: 'md',\n padding: 'lg',\n ngContent: 'Box Content.',\n }\n-->"
833
+ },
834
+ {
835
+ title: "Flex children",
836
+ framework: "angular",
837
+ code: "<!-- Storybook story: Flex children -->\n<div box-layout ${argsToTemplate(props)}>\n<span uni-text>${ngContent}</span>\n</div>"
838
+ },
839
+ {
840
+ title: "Centered page shell",
841
+ framework: "angular",
842
+ code: "<!-- Storybook story: Centered page shell -->\n<div box-layout ${argsToTemplate(props)}>\n<span uni-text>${ngContent}</span>\n</div>"
843
+ },
844
+ {
845
+ title: "Composition",
846
+ framework: "angular",
847
+ code: "<!-- Storybook story: Composition -->\n<div box-layout ${argsToTemplate(props)}>\n<span uni-text>${ngContent}</span>\n</div>"
805
848
  }
806
849
  ],
807
850
  guidelines: {
808
- whenToUse: "Box is the base Layout component. It is highly configurable.\nEach layout component extends the Box component while providing presets to support their application.",
851
+ whenToUse: "Box is the base layout primitive \u2014 an attribute directive you put on any element, so\nyour HTML semantics stay yours. It is highly configurable; every other layout\ndirective extends it and adds presets.\nBecause it is a directive rather than a component, it composes freely: with another\nlayout attribute, with `uni-text`, and with a component's own host element. Angular\nmerges the host `class` bindings, so each contributor's styles survive.\n```html\n```\nColors stay unambiguous across that composition. The box's surface is\n`containerColor` \u2014 a **pair**: the named surface plus its paired on-color \u2014 while\nplain `color` belongs to `uni-text` and maps to the CSS property. So an element\nwearing both can set each independently:\n```html\n```\nLayout attributes only apply when the directive is in your component's `imports`.\nAn unimported attribute compiles cleanly and silently does nothing \u2014 import\n`UNI_LAYOUT` to bring the whole family in at once.",
809
852
  dos: [],
810
853
  donts: [],
811
854
  accessibility: []
@@ -819,7 +862,7 @@ var uni_index_default = {
819
862
  summary: 'WAI-ARIA breadcrumb: a `nav` landmark wrapping an ordered list; the last item is the current page (`aria-current="page"`), separators are decorative.',
820
863
  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.',
821
864
  category: "components",
822
- version: "8.2.0",
865
+ version: "9.0.0",
823
866
  bindings: {
824
867
  angular: {
825
868
  importPath: "@uni-design-system/uni-angular",
@@ -888,7 +931,7 @@ var uni_index_default = {
888
931
  summary: "",
889
932
  description: "",
890
933
  category: "primitives",
891
- version: "8.2.0",
934
+ version: "9.0.0",
892
935
  bindings: {
893
936
  angular: {
894
937
  importPath: "@uni-design-system/uni-angular",
@@ -1031,7 +1074,7 @@ var uni_index_default = {
1031
1074
  summary: "",
1032
1075
  description: "",
1033
1076
  category: "primitives",
1034
- version: "8.2.0",
1077
+ version: "9.0.0",
1035
1078
  bindings: {
1036
1079
  angular: {
1037
1080
  importPath: "@uni-design-system/uni-angular",
@@ -1063,7 +1106,7 @@ var uni_index_default = {
1063
1106
  summary: "Inline month calendar: single-date or start\u2013end range selection, day markers (availability dots), min/max fences and disabled dates.",
1064
1107
  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.",
1065
1108
  category: "forms",
1066
- version: "8.2.0",
1109
+ version: "9.0.0",
1067
1110
  bindings: {
1068
1111
  angular: {
1069
1112
  importPath: "@uni-design-system/uni-angular",
@@ -1282,6 +1325,203 @@ var uni_index_default = {
1282
1325
  "calendar.behavior.todayStyle"
1283
1326
  ]
1284
1327
  },
1328
+ {
1329
+ id: "callout",
1330
+ name: "Callout",
1331
+ status: "stable",
1332
+ summary: "Anchored coach-mark panel that dims the page and cuts a spotlight hole around its target.",
1333
+ 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).',
1334
+ category: "components",
1335
+ version: "9.0.0",
1336
+ bindings: {
1337
+ angular: {
1338
+ importPath: "@uni-design-system/uni-angular",
1339
+ selectorOrTag: "uni-callout",
1340
+ api: [
1341
+ {
1342
+ name: "open",
1343
+ kind: "model",
1344
+ type: "boolean",
1345
+ required: false,
1346
+ default: "false",
1347
+ description: ""
1348
+ },
1349
+ {
1350
+ name: "key",
1351
+ kind: "input",
1352
+ type: "string",
1353
+ required: false,
1354
+ description: "Identifies this callout in `dismissed` payloads. Empty string = unset."
1355
+ },
1356
+ {
1357
+ name: "target",
1358
+ kind: "input",
1359
+ type: "HTMLElement | string",
1360
+ required: false,
1361
+ description: "Element (or id, resolved at open time) to spotlight. '' = unset."
1362
+ },
1363
+ {
1364
+ name: "placement",
1365
+ kind: "input",
1366
+ type: "Placement",
1367
+ required: false,
1368
+ default: "'bottom'",
1369
+ description: ""
1370
+ },
1371
+ {
1372
+ name: "backdrop",
1373
+ kind: "input",
1374
+ type: "'spotlight' | 'dim' | 'none'",
1375
+ required: false,
1376
+ description: "Defaults to `spotlight` when a target resolves, else `dim`."
1377
+ },
1378
+ {
1379
+ name: "targetInteractive",
1380
+ kind: "input",
1381
+ type: "boolean",
1382
+ required: false,
1383
+ default: "true",
1384
+ description: "When false, a transparent cover blocks the spotlit target."
1385
+ },
1386
+ {
1387
+ name: "dismissible",
1388
+ kind: "input",
1389
+ type: "boolean",
1390
+ required: false,
1391
+ default: "true",
1392
+ description: "Gates Escape and the close button."
1393
+ },
1394
+ {
1395
+ name: "dismissOnBackdrop",
1396
+ kind: "input",
1397
+ type: "boolean",
1398
+ required: false,
1399
+ default: "false",
1400
+ description: "When true, scrim clicks close (reason `backdrop`); else the panel pulses."
1401
+ },
1402
+ {
1403
+ name: "header",
1404
+ kind: "input",
1405
+ type: "string",
1406
+ required: false,
1407
+ description: ""
1408
+ },
1409
+ {
1410
+ name: "arrow",
1411
+ kind: "input",
1412
+ type: "boolean",
1413
+ required: false,
1414
+ default: "true",
1415
+ description: ""
1416
+ },
1417
+ {
1418
+ name: "ariaLabel",
1419
+ kind: "input",
1420
+ type: "string",
1421
+ required: false,
1422
+ description: 'Wins over the header/body labelling; the tour sets "{title}, step n of N".'
1423
+ },
1424
+ {
1425
+ name: "closeLabel",
1426
+ kind: "input",
1427
+ type: "string",
1428
+ required: false,
1429
+ default: "'Close'",
1430
+ description: "Accessible name of the dismiss button (the tour passes its skip label)."
1431
+ },
1432
+ {
1433
+ name: "opened",
1434
+ kind: "output",
1435
+ type: "void",
1436
+ required: false,
1437
+ description: ""
1438
+ },
1439
+ {
1440
+ name: "closed",
1441
+ kind: "output",
1442
+ type: "void",
1443
+ required: false,
1444
+ description: ""
1445
+ },
1446
+ {
1447
+ name: "dismissed",
1448
+ kind: "output",
1449
+ type: "UniCalloutDismissal",
1450
+ required: false,
1451
+ description: ""
1452
+ },
1453
+ {
1454
+ name: "panelKeydown",
1455
+ kind: "output",
1456
+ type: "KeyboardEvent",
1457
+ required: false,
1458
+ description: "Keys pressed while focus is inside the panel (the tour's arrow-key hook)."
1459
+ }
1460
+ ]
1461
+ }
1462
+ },
1463
+ examples: [
1464
+ {
1465
+ title: "Spotlight",
1466
+ framework: "angular",
1467
+ code: '<!-- Storybook story: Spotlight -->\n<div stack-layout gap="md">\n<button text-button (click)="open = true">Show me around</button>\n<uni-input label="Search projects" id="callout-demo-search"></uni-input>\n<uni-callout\n [(open)]="open"\n key="search-intro"\n target="callout-demo-search"\n header="Find anything"\n placement="bottom"\n>\n Type to filter projects, people, and documents \u2014 try it right here.\n <button text-button callout-actions size="sm" variant="secondary" (click)="open = false">Got it</button>\n</uni-callout>\n</div>'
1468
+ },
1469
+ {
1470
+ title: "Locked Spotlight",
1471
+ framework: "angular",
1472
+ code: '<!-- Storybook story: Locked Spotlight -->\n<div stack-layout gap="md">\n<button text-button (click)="open = true">Show me around</button>\n<uni-input label="Search projects" id="callout-demo-search"></uni-input>\n<uni-callout\n [(open)]="open"\n key="search-intro"\n target="callout-demo-search"\n header="Find anything"\n placement="bottom"\n>\n Type to filter projects, people, and documents \u2014 try it right here.\n <button text-button callout-actions size="sm" variant="secondary" (click)="open = false">Got it</button>\n</uni-callout>\n</div>'
1473
+ },
1474
+ {
1475
+ title: "Dim",
1476
+ framework: "angular",
1477
+ code: '<!-- Storybook story: Dim -->\n<div stack-layout gap="md">\n<button text-button (click)="open = true">Show me around</button>\n<uni-input label="Search projects" id="callout-demo-search"></uni-input>\n<uni-callout\n [(open)]="open"\n key="search-intro"\n target="callout-demo-search"\n header="Find anything"\n placement="bottom"\n>\n Type to filter projects, people, and documents \u2014 try it right here.\n <button text-button callout-actions size="sm" variant="secondary" (click)="open = false">Got it</button>\n</uni-callout>\n</div>'
1478
+ },
1479
+ {
1480
+ title: "No Backdrop",
1481
+ framework: "angular",
1482
+ code: '<!-- Storybook story: No Backdrop -->\n<div stack-layout gap="md">\n<button text-button (click)="open = true">Show me around</button>\n<uni-input label="Search projects" id="callout-demo-search"></uni-input>\n<uni-callout\n [(open)]="open"\n key="search-intro"\n target="callout-demo-search"\n header="Find anything"\n placement="bottom"\n>\n Type to filter projects, people, and documents \u2014 try it right here.\n <button text-button callout-actions size="sm" variant="secondary" (click)="open = false">Got it</button>\n</uni-callout>\n</div>'
1483
+ },
1484
+ {
1485
+ title: "Dismissal Tracking",
1486
+ framework: "angular",
1487
+ code: '<!-- Storybook story: Dismissal Tracking -->\n<div stack-layout gap="md">\n<button text-button (click)="open = true">Show me around</button>\n<uni-input label="Search projects" id="callout-demo-search"></uni-input>\n<uni-callout\n [(open)]="open"\n key="search-intro"\n target="callout-demo-search"\n header="Find anything"\n placement="bottom"\n>\n Type to filter projects, people, and documents \u2014 try it right here.\n <button text-button callout-actions size="sm" variant="secondary" (click)="open = false">Got it</button>\n</uni-callout>\n</div>'
1488
+ }
1489
+ ],
1490
+ guidelines: {
1491
+ whenToUse: 'Callout is an anchored coach-mark panel that dims the page and cuts a\nspotlight hole around its target \u2014 the feature-introduction surface. The\nscrim and hole are CSS-anchor-positioned to the target, so the spotlight\ntracks scroll, resize, and layout with zero listeners, and the spotlit\nelement stays genuinely clickable through the hole (or covered, with\n`targetInteractive` false). Both surfaces ride the native popover top layer,\nabove every app z-index.\nThe panel is a non-modal `role="dialog"`: focus moves in on open, Tab runs a\nduet loop over the panel\'s controls plus the interactive target, and close\nrestores focus \u2014 unless the user moved into the target, where it stays.\nCallouts are storage-free by rule: `key` and the `dismissed` output (with a\n`reason`) are the "don\'t show again" hooks, and persistence belongs to the\napp.',
1492
+ dos: [
1493
+ 'Point one callout at one action, and let `key` + `dismissed` drive "don\'t show again"',
1494
+ "Keep the target interactive when the callout invites trying it"
1495
+ ],
1496
+ donts: [
1497
+ "Stack multiple callouts at once \u2014 sequence them with `uni-tour`",
1498
+ "Use a callout for blocking confirmation; that is a dialog"
1499
+ ],
1500
+ accessibility: [
1501
+ 'Non-modal `role="dialog"`, labelled by `header` (or `ariaLabel`); `aria-modal` is deliberately absent \u2014 the page is dimmed, not removed.',
1502
+ "Initial focus: `[autofocus]` \u2192 first action \u2192 first focusable \u2192 the panel itself.",
1503
+ "Focus restore on close skips users who deliberately moved into the target.",
1504
+ "The spotlight ring is the `variant` color role and pairs with a shape (the ring), not color alone."
1505
+ ]
1506
+ },
1507
+ relatedTokens: [
1508
+ "callout.behavior.color",
1509
+ "callout.behavior.borderRadius",
1510
+ "callout.behavior.shadow",
1511
+ "callout.behavior.width",
1512
+ "callout.behavior.padding",
1513
+ "callout.behavior.headerTypeface",
1514
+ "callout.behavior.typeface",
1515
+ "callout.behavior.closeSymbol",
1516
+ "callout.behavior.arrowSize",
1517
+ "callout.behavior.offset",
1518
+ "callout.behavior.scrimColor",
1519
+ "callout.behavior.spotlightPadding",
1520
+ "callout.behavior.spotlightRadius",
1521
+ "callout.behavior.ringWidth",
1522
+ "callout.behavior.motion"
1523
+ ]
1524
+ },
1285
1525
  {
1286
1526
  id: "card",
1287
1527
  name: "Card",
@@ -1289,7 +1529,7 @@ var uni_index_default = {
1289
1529
  summary: "",
1290
1530
  description: "",
1291
1531
  category: "layout",
1292
- version: "8.2.0",
1532
+ version: "9.0.0",
1293
1533
  bindings: {
1294
1534
  angular: {
1295
1535
  importPath: "@uni-design-system/uni-angular",
@@ -1334,7 +1574,7 @@ var uni_index_default = {
1334
1574
  summary: "",
1335
1575
  description: "",
1336
1576
  category: "layout",
1337
- version: "8.2.0",
1577
+ version: "9.0.0",
1338
1578
  bindings: {
1339
1579
  angular: {
1340
1580
  importPath: "@uni-design-system/uni-angular",
@@ -1358,7 +1598,7 @@ var uni_index_default = {
1358
1598
  summary: "",
1359
1599
  description: "",
1360
1600
  category: "layout",
1361
- version: "8.2.0",
1601
+ version: "9.0.0",
1362
1602
  bindings: {
1363
1603
  angular: {
1364
1604
  importPath: "@uni-design-system/uni-angular",
@@ -1399,7 +1639,7 @@ var uni_index_default = {
1399
1639
  summary: "",
1400
1640
  description: "",
1401
1641
  category: "layout",
1402
- version: "8.2.0",
1642
+ version: "9.0.0",
1403
1643
  bindings: {
1404
1644
  angular: {
1405
1645
  importPath: "@uni-design-system/uni-angular",
@@ -1454,7 +1694,7 @@ var uni_index_default = {
1454
1694
  summary: "",
1455
1695
  description: "",
1456
1696
  category: "forms",
1457
- version: "8.2.0",
1697
+ version: "9.0.0",
1458
1698
  bindings: {
1459
1699
  angular: {
1460
1700
  importPath: "@uni-design-system/uni-angular",
@@ -1547,43 +1787,306 @@ var uni_index_default = {
1547
1787
  {
1548
1788
  title: "Disabled",
1549
1789
  framework: "angular",
1550
- code: "<!-- Storybook story: Disabled -->\n<uni-checkbox ${argsToTemplate(args)}></uni-checkbox>\n<!-- args:\n{\n label: 'Disabled checkbox',\n variant: 'primary',\n disabled: true,\n }\n-->"
1790
+ code: "<!-- Storybook story: Disabled -->\n<uni-checkbox ${argsToTemplate(args)}></uni-checkbox>\n<!-- args:\n{\n label: 'Disabled checkbox',\n variant: 'primary',\n disabled: true,\n }\n-->"
1791
+ },
1792
+ {
1793
+ title: "Variants",
1794
+ framework: "angular",
1795
+ code: "<!-- Storybook story: Variants -->\n<uni-checkbox ${argsToTemplate(args)}></uni-checkbox>"
1796
+ },
1797
+ {
1798
+ title: "With Change Event",
1799
+ framework: "angular",
1800
+ code: "<!-- Storybook story: With Change Event -->\n<uni-checkbox ${argsToTemplate(args)}></uni-checkbox>"
1801
+ },
1802
+ {
1803
+ title: "Form Signals",
1804
+ framework: "angular",
1805
+ code: "<!-- Storybook story: Form Signals -->\n<uni-checkbox ${argsToTemplate(args)}></uni-checkbox>"
1806
+ }
1807
+ ],
1808
+ guidelines: {
1809
+ whenToUse: 'Binary choice control for forms: check to opt in, submit to apply. It implements\n`FormCheckboxControl` for the Signal Forms `[field]` directive (or bind\n`[(checked)]` directly), exposes `aria-invalid` once touched, and supports an\n`indeterminate` model for "select all" parents \u2014 cleared automatically on the next\nuser interaction, matching native behavior.\nThe box color, check stroke (the variant\'s paired on-color), and size resolve from\nthe `checkbox` theme options.',
1810
+ dos: [
1811
+ "Use for choices that apply when the form is submitted"
1812
+ ],
1813
+ donts: [
1814
+ "Use for instant on/off effects \u2014 that is a toggle"
1815
+ ],
1816
+ accessibility: [
1817
+ 'Semantic `<input type="checkbox">` + `<label>`; Space toggles.',
1818
+ "`aria-invalid` reflects the error state once the field was touched or is dirty.",
1819
+ 'The indeterminate visual state is carried by the native `indeterminate` property, announced as "mixed".'
1820
+ ]
1821
+ },
1822
+ relatedTokens: [
1823
+ "checkbox.behavior.size",
1824
+ "checkbox.behavior.boxColor",
1825
+ "checkbox.behavior.borderRadius",
1826
+ "checkbox.behavior.focusRingGap"
1827
+ ]
1828
+ },
1829
+ {
1830
+ id: "combobox",
1831
+ name: "Combobox",
1832
+ status: "stable",
1833
+ summary: "Form-bound, closed-set, single-select autocomplete: `FormValueControl<T | null>` over object `Options<T>`, type-to-filter, commit-on-select.",
1834
+ 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.",
1835
+ category: "forms",
1836
+ version: "9.0.0",
1837
+ bindings: {
1838
+ angular: {
1839
+ importPath: "@uni-design-system/uni-angular",
1840
+ selectorOrTag: "uni-combobox, Combobox",
1841
+ api: [
1842
+ {
1843
+ name: "value",
1844
+ kind: "model",
1845
+ type: "T | null",
1846
+ required: false,
1847
+ default: "null",
1848
+ description: ""
1849
+ },
1850
+ {
1851
+ name: "disabled",
1852
+ kind: "input",
1853
+ type: "boolean",
1854
+ required: false,
1855
+ default: "false",
1856
+ description: ""
1857
+ },
1858
+ {
1859
+ name: "touched",
1860
+ kind: "model",
1861
+ type: "boolean",
1862
+ required: false,
1863
+ default: "false",
1864
+ description: ""
1865
+ },
1866
+ {
1867
+ name: "invalid",
1868
+ kind: "input",
1869
+ type: "boolean",
1870
+ required: false,
1871
+ default: "false",
1872
+ description: ""
1873
+ },
1874
+ {
1875
+ name: "dirty",
1876
+ kind: "input",
1877
+ type: "boolean",
1878
+ required: false,
1879
+ default: "false",
1880
+ description: ""
1881
+ },
1882
+ {
1883
+ name: "required",
1884
+ kind: "input",
1885
+ type: "boolean",
1886
+ required: false,
1887
+ default: "false",
1888
+ description: ""
1889
+ },
1890
+ {
1891
+ name: "ariaDescribedBy",
1892
+ kind: "input",
1893
+ type: "string",
1894
+ required: false,
1895
+ description: ""
1896
+ },
1897
+ {
1898
+ name: "label",
1899
+ kind: "input",
1900
+ type: "string",
1901
+ required: true,
1902
+ description: 'Accessible name for the field, e.g. "State"; echoed on the listbox.'
1903
+ },
1904
+ {
1905
+ name: "placeholder",
1906
+ kind: "input",
1907
+ type: "string",
1908
+ required: false,
1909
+ description: ""
1910
+ },
1911
+ {
1912
+ name: "options",
1913
+ kind: "input",
1914
+ type: "Options<T>",
1915
+ required: false,
1916
+ default: "[]",
1917
+ description: ""
1918
+ },
1919
+ {
1920
+ name: "width",
1921
+ kind: "input",
1922
+ type: "string | number",
1923
+ required: false,
1924
+ default: "'100%'",
1925
+ description: ""
1926
+ },
1927
+ {
1928
+ name: "clearable",
1929
+ kind: "input",
1930
+ type: "boolean",
1931
+ required: false,
1932
+ default: "true",
1933
+ description: "Show a \u2715 while a value is set; an emptied field on blur also clears."
1934
+ },
1935
+ {
1936
+ name: "commitOnBlur",
1937
+ kind: "input",
1938
+ type: "boolean",
1939
+ required: false,
1940
+ default: "true",
1941
+ description: "Blur commits an exact-match draft; a non-matching draft reverts."
1942
+ },
1943
+ {
1944
+ name: "emptyText",
1945
+ kind: "input",
1946
+ type: "string",
1947
+ required: false,
1948
+ default: "'No matches'",
1949
+ description: "i18n-able empty row, also announced when a filter matches nothing."
1950
+ },
1951
+ {
1952
+ name: "filterLocally",
1953
+ kind: "input",
1954
+ type: "boolean",
1955
+ required: false,
1956
+ default: "true",
1957
+ description: "`false` renders `options` verbatim; narrow them app-side from `query`."
1958
+ },
1959
+ {
1960
+ name: "debounceTime",
1961
+ kind: "input",
1962
+ type: "number",
1963
+ required: false,
1964
+ default: "250",
1965
+ description: ""
1966
+ },
1967
+ {
1968
+ name: "query",
1969
+ kind: "output",
1970
+ type: "string",
1971
+ required: false,
1972
+ description: "Debounced draft text, for async option lists."
1973
+ },
1974
+ {
1975
+ name: "selected",
1976
+ kind: "output",
1977
+ type: "Option<T>",
1978
+ required: false,
1979
+ description: "An option committed."
1980
+ },
1981
+ {
1982
+ name: "cleared",
1983
+ kind: "output",
1984
+ type: "void",
1985
+ required: false,
1986
+ description: ""
1987
+ },
1988
+ {
1989
+ name: "rejected",
1990
+ kind: "output",
1991
+ type: "UniComboboxRejection",
1992
+ required: false,
1993
+ description: "A commit was refused (no match); the field reverted."
1994
+ }
1995
+ ]
1996
+ }
1997
+ },
1998
+ examples: [
1999
+ {
2000
+ title: "Primary",
2001
+ framework: "angular",
2002
+ code: `<!-- Storybook story: Primary -->
2003
+ <uni-combobox
2004
+ label="Country"
2005
+ placeholder="Type to search countries"
2006
+ emptyText="No countries found"
2007
+ [filterLocally]="false"
2008
+ [options]="options"
2009
+ (query)="onQuery($event)"
2010
+ />
2011
+ <!-- args:
2012
+ { value: 'Arizona' }
2013
+ -->`
2014
+ },
2015
+ {
2016
+ title: "Disabled Options",
2017
+ framework: "angular",
2018
+ code: `<!-- Storybook story: Disabled Options -->
2019
+ <uni-combobox
2020
+ label="Country"
2021
+ placeholder="Type to search countries"
2022
+ emptyText="No countries found"
2023
+ [filterLocally]="false"
2024
+ [options]="options"
2025
+ (query)="onQuery($event)"
2026
+ />
2027
+ <!-- args:
2028
+ { label: 'Assignee', placeholder: 'Choose a person', options: ASSIGNEES }
2029
+ -->`
2030
+ },
2031
+ {
2032
+ title: "Async",
2033
+ framework: "angular",
2034
+ code: '<!-- Storybook story: Async -->\n<uni-combobox\nlabel="Country"\nplaceholder="Type to search countries"\nemptyText="No countries found"\n[filterLocally]="false"\n[options]="options"\n(query)="onQuery($event)"\n/>\n<!-- args:\n{ required: true, invalid: true, touched: true }\n-->'
1551
2035
  },
1552
2036
  {
1553
- title: "Variants",
2037
+ title: "Create New Values",
1554
2038
  framework: "angular",
1555
- code: "<!-- Storybook story: Variants -->\n<uni-checkbox ${argsToTemplate(args)}></uni-checkbox>"
2039
+ code: '<!-- Storybook story: Create New Values -->\n<uni-combobox\nlabel="Country"\nplaceholder="Type to search countries"\nemptyText="No countries found"\n[filterLocally]="false"\n[options]="options"\n(query)="onQuery($event)"\n/>\n<!-- args:\n{ required: true, invalid: true, touched: true }\n-->'
1556
2040
  },
1557
2041
  {
1558
- title: "With Change Event",
2042
+ title: "Invalid",
1559
2043
  framework: "angular",
1560
- code: "<!-- Storybook story: With Change Event -->\n<uni-checkbox ${argsToTemplate(args)}></uni-checkbox>"
2044
+ code: '<!-- Storybook story: Invalid -->\n<uni-combobox\nlabel="Country"\nplaceholder="Type to search countries"\nemptyText="No countries found"\n[filterLocally]="false"\n[options]="options"\n(query)="onQuery($event)"\n/>\n<!-- args:\n{ required: true, invalid: true, touched: true }\n-->'
1561
2045
  },
1562
2046
  {
1563
- title: "Form Signals",
2047
+ title: "Disabled",
1564
2048
  framework: "angular",
1565
- code: "<!-- Storybook story: Form Signals -->\n<uni-checkbox ${argsToTemplate(args)}></uni-checkbox>"
2049
+ code: `<!-- Storybook story: Disabled -->
2050
+ <uni-combobox
2051
+ label="Country"
2052
+ placeholder="Type to search countries"
2053
+ emptyText="No countries found"
2054
+ [filterLocally]="false"
2055
+ [options]="options"
2056
+ (query)="onQuery($event)"
2057
+ />
2058
+ <!-- args:
2059
+ { value: 'Colorado', disabled: true }
2060
+ -->`
1566
2061
  }
1567
2062
  ],
1568
2063
  guidelines: {
1569
- whenToUse: 'Binary choice control for forms: check to opt in, submit to apply. It implements\n`FormCheckboxControl` for the Signal Forms `[field]` directive (or bind\n`[(checked)]` directly), exposes `aria-invalid` once touched, and supports an\n`indeterminate` model for "select all" parents \u2014 cleared automatically on the next\nuser interaction, matching native behavior.\nThe box color, check stroke (the variant\'s paired on-color), and size resolve from\nthe `checkbox` theme options.',
1570
- dos: [
1571
- "Use for choices that apply when the form is submitted"
1572
- ],
2064
+ whenToUse: "The form-bound, **closed-set, single-select** autocomplete: object\n`Options<T>`, `FormValueControl<T | null>`, type-to-filter, commit-on-select.\nTyping produces a *draft* \u2014 a filter, never a value; the value changes only\nwhen an option commits, the field clears, or the model is written from\noutside. Select semantics, not search: a real label, a chevron, no magnifier,\nnothing submits.\nUnder ~10 options and no need to type \u2192 `uni-select`, the native, zero-JS,\nmobile-friendly answer. More options, or users know what they're looking for \u2192\n`uni-combobox`. The value contract is identical (`T | null`, `compareWith`),\nso swapping one for the other as a list grows is a template-only change \u2014 that\nis deliberate. For open sets, where typing *creates* values, use\n`uni-tag-input` (multi) or `uni-search-input` (queries); for closed multi\nsets, `uni-multi-select-dropdown`.",
2065
+ dos: [],
1573
2066
  donts: [
1574
- "Use for instant on/off effects \u2014 that is a toggle"
2067
+ "Don't expect free text to commit implicitly \u2014 it never does. Offer creation",
2068
+ "Don't wire `(query)` \u2192 filter \u2192 `[options]` when the list is already in",
2069
+ "Don't use `Escape` to clear: it closes, then reverts. The \u2715 and an emptied"
1575
2070
  ],
1576
2071
  accessibility: [
1577
- 'Semantic `<input type="checkbox">` + `<label>`; Space toggles.',
1578
- "`aria-invalid` reflects the error state once the field was touched or is dirty.",
1579
- 'The indeterminate visual state is carried by the native `indeterminate` property, announced as "mixed".'
2072
+ 'The input is `role="combobox"` with `aria-expanded`, `aria-controls` and',
2073
+ "Home and End move the caret, never the list, per APG's editable-combobox",
2074
+ "`aria-selected` marks the **committed** option; the active one is carried by",
2075
+ "Disabled options are rendered, announced (`aria-disabled`), and skipped by",
2076
+ 'Commits (*"Alabama selected."*), clears, refusals and debounced result',
2077
+ "`aria-invalid` is gated on `invalid && (touched || dirty)`, per the"
1580
2078
  ]
1581
2079
  },
1582
2080
  relatedTokens: [
1583
- "checkbox.behavior.size",
1584
- "checkbox.behavior.boxColor",
1585
- "checkbox.behavior.borderRadius",
1586
- "checkbox.behavior.focusRingGap"
2081
+ "combobox.behavior.toggleIcon",
2082
+ "combobox.behavior.clearIcon",
2083
+ "combobox.behavior.selectedIcon",
2084
+ "combobox.behavior.listColor",
2085
+ "combobox.behavior.listShadow",
2086
+ "combobox.behavior.listBorderRadius",
2087
+ "combobox.behavior.activeColor",
2088
+ "combobox.behavior.maxVisibleOptions",
2089
+ "combobox.behavior.descriptionColor"
1587
2090
  ]
1588
2091
  },
1589
2092
  {
@@ -1593,7 +2096,7 @@ var uni_index_default = {
1593
2096
  summary: "",
1594
2097
  description: "",
1595
2098
  category: "feedback",
1596
- version: "8.2.0",
2099
+ version: "9.0.0",
1597
2100
  bindings: {
1598
2101
  angular: {
1599
2102
  importPath: "@uni-design-system/uni-angular",
@@ -1640,7 +2143,7 @@ var uni_index_default = {
1640
2143
  summary: "",
1641
2144
  description: "",
1642
2145
  category: "forms",
1643
- version: "8.2.0",
2146
+ version: "9.0.0",
1644
2147
  bindings: {
1645
2148
  angular: {
1646
2149
  importPath: "@uni-design-system/uni-angular",
@@ -1723,7 +2226,7 @@ var uni_index_default = {
1723
2226
  summary: "",
1724
2227
  description: "",
1725
2228
  category: "data",
1726
- version: "8.2.0",
2229
+ version: "9.0.0",
1727
2230
  bindings: {
1728
2231
  angular: {
1729
2232
  importPath: "@uni-design-system/uni-angular",
@@ -1824,7 +2327,7 @@ var uni_index_default = {
1824
2327
  summary: "Date field with free-typed parsing and a popup calendar.",
1825
2328
  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.",
1826
2329
  category: "forms",
1827
- version: "8.2.0",
2330
+ version: "9.0.0",
1828
2331
  bindings: {
1829
2332
  angular: {
1830
2333
  importPath: "@uni-design-system/uni-angular",
@@ -2032,7 +2535,7 @@ var uni_index_default = {
2032
2535
  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.",
2033
2536
  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.",
2034
2537
  category: "forms",
2035
- version: "8.2.0",
2538
+ version: "9.0.0",
2036
2539
  bindings: {
2037
2540
  angular: {
2038
2541
  importPath: "@uni-design-system/uni-angular",
@@ -2202,7 +2705,7 @@ var uni_index_default = {
2202
2705
  summary: "Text input that emits `change` only after the user pauses typing.",
2203
2706
  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.",
2204
2707
  category: "forms",
2205
- version: "8.2.0",
2708
+ version: "9.0.0",
2206
2709
  bindings: {
2207
2710
  angular: {
2208
2711
  importPath: "@uni-design-system/uni-angular",
@@ -2253,6 +2756,28 @@ var uni_index_default = {
2253
2756
  default: "false",
2254
2757
  description: ""
2255
2758
  },
2759
+ {
2760
+ name: "type",
2761
+ kind: "input",
2762
+ type: "UniInputType",
2763
+ required: false,
2764
+ default: "'text'",
2765
+ description: "Native input type; text-like only, matching `uni-input`."
2766
+ },
2767
+ {
2768
+ name: "autocomplete",
2769
+ kind: "input",
2770
+ type: "string",
2771
+ required: false,
2772
+ description: ""
2773
+ },
2774
+ {
2775
+ name: "inputMode",
2776
+ kind: "input",
2777
+ type: "UniInputMode",
2778
+ required: false,
2779
+ description: ""
2780
+ },
2256
2781
  {
2257
2782
  name: "role",
2258
2783
  kind: "input",
@@ -2283,11 +2808,11 @@ var uni_index_default = {
2283
2808
  description: ""
2284
2809
  },
2285
2810
  {
2286
- name: "change",
2811
+ name: "valueChange",
2287
2812
  kind: "output",
2288
2813
  type: "string",
2289
2814
  required: false,
2290
- description: ""
2815
+ description: "The debounced value, emitted once the user pauses typing."
2291
2816
  }
2292
2817
  ]
2293
2818
  }
@@ -2297,7 +2822,7 @@ var uni_index_default = {
2297
2822
  title: "Primary",
2298
2823
  framework: "angular",
2299
2824
  code: `<!-- Storybook story: Primary -->
2300
- <uni-debounce-input \${argsToTemplate(props)} (change)="lastEmitted = $event" #debounce />
2825
+ <uni-debounce-input \${argsToTemplate(props)} (valueChange)="lastEmitted = $event" #debounce />
2301
2826
  <div box-layout paddingTop="md">
2302
2827
  <div>Live value: {{ debounce.value() }}</div>
2303
2828
  <div>Debounced value: {{ lastEmitted }}</div>
@@ -2311,7 +2836,7 @@ var uni_index_default = {
2311
2836
  }
2312
2837
  ],
2313
2838
  guidelines: {
2314
- whenToUse: "A themed text input that emits its `change` output only after the user pauses typing\n(400&nbsp;ms by default) and only when the value actually changed \u2014 a signal-based\ndebounce with no rxjs involved. The live value is exposed as the `value` signal, and\n`clear()` empties the field immediately (cancelling any pending emit).\nIt wears the shared input chrome (color, border, typeface, focus ring) via the input\nbox, and offers `pre-input` / `post-input` attribute slots for adornments plus ARIA\npassthrough inputs (`role`, `ariaExpanded`, `ariaControls`, `ariaActivedescendant`)\nso composite widgets can annotate the real input element.\nUsed by the [Search Input](?path=/docs/components-forms-search-input--search-input), which\nprojects its magnifier and clear button through the slots and drives the combobox\nARIA through the passthroughs.",
2839
+ whenToUse: "A themed text input that emits its `valueChange` output only after the user pauses typing\n(400&nbsp;ms by default) and only when the value actually changed \u2014 a signal-based\ndebounce with no rxjs involved. The live value is exposed as the `value` signal, and\n`clear()` empties the field immediately (cancelling any pending emit).\nIt wears the shared input chrome (color, border, typeface, focus ring) via the input\nbox, and offers `pre-input` / `post-input` attribute slots for adornments plus ARIA\npassthrough inputs (`role`, `ariaExpanded`, `ariaControls`, `ariaActivedescendant`)\nso composite widgets can annotate the real input element.\nUsed by the [Search Input](?path=/docs/components-forms-search-input--search-input), which\nprojects its magnifier and clear button through the slots and drives the combobox\nARIA through the passthroughs.",
2315
2840
  dos: [],
2316
2841
  donts: [],
2317
2842
  accessibility: [
@@ -2328,7 +2853,7 @@ var uni_index_default = {
2328
2853
  summary: "",
2329
2854
  description: "",
2330
2855
  category: "feedback",
2331
- version: "8.2.0",
2856
+ version: "9.0.0",
2332
2857
  bindings: {
2333
2858
  angular: {
2334
2859
  importPath: "@uni-design-system/uni-angular",
@@ -2406,7 +2931,7 @@ var uni_index_default = {
2406
2931
  summary: "",
2407
2932
  description: "",
2408
2933
  category: "feedback",
2409
- version: "8.2.0",
2934
+ version: "9.0.0",
2410
2935
  bindings: {
2411
2936
  angular: {
2412
2937
  importPath: "@uni-design-system/uni-angular",
@@ -2494,7 +3019,7 @@ var uni_index_default = {
2494
3019
  summary: "",
2495
3020
  description: "",
2496
3021
  category: "feedback",
2497
- version: "8.2.0",
3022
+ version: "9.0.0",
2498
3023
  bindings: {
2499
3024
  angular: {
2500
3025
  importPath: "@uni-design-system/uni-angular",
@@ -2518,7 +3043,7 @@ var uni_index_default = {
2518
3043
  summary: "",
2519
3044
  description: "",
2520
3045
  category: "layout",
2521
- version: "8.2.0",
3046
+ version: "9.0.0",
2522
3047
  bindings: {
2523
3048
  angular: {
2524
3049
  importPath: "@uni-design-system/uni-angular",
@@ -2574,18 +3099,18 @@ var uni_index_default = {
2574
3099
  summary: "",
2575
3100
  description: "",
2576
3101
  category: "directives",
2577
- version: "8.2.0",
3102
+ version: "9.0.0",
2578
3103
  bindings: {
2579
3104
  angular: {
2580
3105
  importPath: "@uni-design-system/uni-angular",
2581
3106
  selectorOrTag: "[uni-drag-n-drop], [dragAndDrop]",
2582
3107
  api: [
2583
3108
  {
2584
- name: "onFileDropped",
3109
+ name: "fileDropped",
2585
3110
  kind: "output",
2586
3111
  type: "FileList",
2587
3112
  required: false,
2588
- description: ""
3113
+ description: "The dropped files."
2589
3114
  }
2590
3115
  ]
2591
3116
  }
@@ -2606,7 +3131,7 @@ var uni_index_default = {
2606
3131
  summary: "Navigation drawer with two modes sharing one content slot: - `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.",
2607
3132
  description: "Navigation drawer with two modes sharing one content slot: - `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. Surface, width, divider, elevation, padding and backdrop all resolve from `drawer` theme tokens.",
2608
3133
  category: "components",
2609
- version: "8.2.0",
3134
+ version: "9.0.0",
2610
3135
  bindings: {
2611
3136
  angular: {
2612
3137
  importPath: "@uni-design-system/uni-angular",
@@ -2685,7 +3210,7 @@ var uni_index_default = {
2685
3210
  summary: "",
2686
3211
  description: "",
2687
3212
  category: "components",
2688
- version: "8.2.0",
3213
+ version: "9.0.0",
2689
3214
  bindings: {
2690
3215
  angular: {
2691
3216
  importPath: "@uni-design-system/uni-angular",
@@ -2758,11 +3283,11 @@ var uni_index_default = {
2758
3283
  description: ""
2759
3284
  },
2760
3285
  {
2761
- name: "color",
3286
+ name: "containerColor",
2762
3287
  kind: "input",
2763
3288
  type: "ContainerColorToken | undefined",
2764
3289
  required: false,
2765
- description: ""
3290
+ description: "A container color pair; `color` belongs to `uni-text` across the library."
2766
3291
  },
2767
3292
  {
2768
3293
  name: "dropdownShowing",
@@ -2792,7 +3317,8 @@ var uni_index_default = {
2792
3317
  "dropdown.behavior.border",
2793
3318
  "dropdown.behavior.borderRadius",
2794
3319
  "dropdown.behavior.color",
2795
- "dropdown.behavior.shadow"
3320
+ "dropdown.behavior.shadow",
3321
+ "dropdown.behavior.motion"
2796
3322
  ]
2797
3323
  },
2798
3324
  {
@@ -2802,7 +3328,7 @@ var uni_index_default = {
2802
3328
  summary: "",
2803
3329
  description: "",
2804
3330
  category: "layout",
2805
- version: "8.2.0",
3331
+ version: "9.0.0",
2806
3332
  bindings: {
2807
3333
  angular: {
2808
3334
  importPath: "@uni-design-system/uni-angular",
@@ -2880,7 +3406,7 @@ var uni_index_default = {
2880
3406
  ]
2881
3407
  },
2882
3408
  relatedTokens: [
2883
- "expand.behavior.transitionSpeed"
3409
+ "expand.behavior.motion"
2884
3410
  ]
2885
3411
  },
2886
3412
  {
@@ -2890,7 +3416,7 @@ var uni_index_default = {
2890
3416
  summary: "",
2891
3417
  description: "",
2892
3418
  category: "layout",
2893
- version: "8.2.0",
3419
+ version: "9.0.0",
2894
3420
  bindings: {
2895
3421
  angular: {
2896
3422
  importPath: "@uni-design-system/uni-angular",
@@ -2960,8 +3486,8 @@ var uni_index_default = {
2960
3486
  status: "stable",
2961
3487
  summary: "Trigger for a {@link UniExpandComponent} region.",
2962
3488
  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.",
2963
- category: "forms",
2964
- version: "8.2.0",
3489
+ category: "layout",
3490
+ version: "9.0.0",
2965
3491
  bindings: {
2966
3492
  angular: {
2967
3493
  importPath: "@uni-design-system/uni-angular",
@@ -3046,7 +3572,7 @@ var uni_index_default = {
3046
3572
  summary: "",
3047
3573
  description: "",
3048
3574
  category: "forms",
3049
- version: "8.2.0",
3575
+ version: "9.0.0",
3050
3576
  bindings: {
3051
3577
  angular: {
3052
3578
  importPath: "@uni-design-system/uni-angular",
@@ -3204,7 +3730,7 @@ var uni_index_default = {
3204
3730
  summary: "",
3205
3731
  description: "",
3206
3732
  category: "layout",
3207
- version: "8.2.0",
3733
+ version: "9.0.0",
3208
3734
  bindings: {
3209
3735
  angular: {
3210
3736
  importPath: "@uni-design-system/uni-angular",
@@ -3262,19 +3788,19 @@ var uni_index_default = {
3262
3788
  framework: "angular",
3263
3789
  code: `<!-- Storybook story: Simple Grid -->
3264
3790
  <div grid-layout \${argsToTemplate(props)}>
3265
- <div box-layout gridArea="nav" color="quaternary" padding="md" borderRadius="sm">
3791
+ <div box-layout gridArea="nav" containerColor="quaternary" padding="md" borderRadius="sm">
3266
3792
  <span uni-text>nav</span>
3267
3793
  </div>
3268
- <div box-layout gridArea="a1" color="primary" padding="md" borderRadius="sm">
3794
+ <div box-layout gridArea="a1" containerColor="primary" padding="md" borderRadius="sm">
3269
3795
  <span uni-text>a1</span>
3270
3796
  </div>
3271
- <div box-layout gridArea="a2" color="secondary" padding="md" borderRadius="sm">
3797
+ <div box-layout gridArea="a2" containerColor="secondary" padding="md" borderRadius="sm">
3272
3798
  <span uni-text>a2</span>
3273
3799
  </div>
3274
- <div box-layout gridArea="b1" color="tertiary" padding="md" borderRadius="sm">
3800
+ <div box-layout gridArea="b1" containerColor="tertiary" padding="md" borderRadius="sm">
3275
3801
  <span uni-text>b1</span>
3276
3802
  </div>
3277
- <div box-layout gridArea="b2" color="warn" padding="md" borderRadius="sm">
3803
+ <div box-layout gridArea="b2" containerColor="warn" padding="md" borderRadius="sm">
3278
3804
  <span uni-text>b2</span>
3279
3805
  </div>
3280
3806
  </div>
@@ -3301,7 +3827,7 @@ var uni_index_default = {
3301
3827
  summary: "",
3302
3828
  description: "",
3303
3829
  category: "layout",
3304
- version: "8.2.0",
3830
+ version: "9.0.0",
3305
3831
  bindings: {
3306
3832
  angular: {
3307
3833
  importPath: "@uni-design-system/uni-angular",
@@ -3333,7 +3859,7 @@ var uni_index_default = {
3333
3859
  summary: "",
3334
3860
  description: "",
3335
3861
  category: "primitives",
3336
- version: "8.2.0",
3862
+ version: "9.0.0",
3337
3863
  bindings: {
3338
3864
  angular: {
3339
3865
  importPath: "@uni-design-system/uni-angular",
@@ -3393,7 +3919,7 @@ var uni_index_default = {
3393
3919
  summary: "",
3394
3920
  description: "",
3395
3921
  category: "primitives",
3396
- version: "8.2.0",
3922
+ version: "9.0.0",
3397
3923
  bindings: {
3398
3924
  angular: {
3399
3925
  importPath: "@uni-design-system/uni-angular",
@@ -3496,7 +4022,7 @@ var uni_index_default = {
3496
4022
  summary: "",
3497
4023
  description: "",
3498
4024
  category: "forms",
3499
- version: "8.2.0",
4025
+ version: "9.0.0",
3500
4026
  bindings: {
3501
4027
  angular: {
3502
4028
  importPath: "@uni-design-system/uni-angular",
@@ -3571,6 +4097,129 @@ var uni_index_default = {
3571
4097
  required: false,
3572
4098
  default: "''",
3573
4099
  description: ""
4100
+ },
4101
+ {
4102
+ name: "type",
4103
+ kind: "input",
4104
+ type: "UniInputType",
4105
+ required: false,
4106
+ default: "'text'",
4107
+ description: "Native input type. Text-like types only \u2014 `date`/`time` have dedicated components, and non-text types break the input chrome and the string value."
4108
+ },
4109
+ {
4110
+ name: "readonly",
4111
+ kind: "input",
4112
+ type: "boolean",
4113
+ required: false,
4114
+ default: "false",
4115
+ description: ""
4116
+ },
4117
+ {
4118
+ name: "name",
4119
+ kind: "input",
4120
+ type: "string",
4121
+ required: false,
4122
+ default: "''",
4123
+ description: ""
4124
+ },
4125
+ {
4126
+ name: "min",
4127
+ kind: "input",
4128
+ type: "number | undefined",
4129
+ required: false,
4130
+ default: "undefined",
4131
+ description: ""
4132
+ },
4133
+ {
4134
+ name: "max",
4135
+ kind: "input",
4136
+ type: "number | undefined",
4137
+ required: false,
4138
+ default: "undefined",
4139
+ description: ""
4140
+ },
4141
+ {
4142
+ name: "minLength",
4143
+ kind: "input",
4144
+ type: "number | undefined",
4145
+ required: false,
4146
+ default: "undefined",
4147
+ description: ""
4148
+ },
4149
+ {
4150
+ name: "maxLength",
4151
+ kind: "input",
4152
+ type: "number | undefined",
4153
+ required: false,
4154
+ default: "undefined",
4155
+ description: ""
4156
+ },
4157
+ {
4158
+ name: "pattern",
4159
+ kind: "input",
4160
+ type: "readonly RegExp[]",
4161
+ required: false,
4162
+ default: "[]",
4163
+ description: "Patterns the value must match \u2014 all of them, per Signal Forms. The native `pattern` attribute can only express one, so it is reflected only when there is exactly one; Signal Forms validates the rest either way."
4164
+ },
4165
+ {
4166
+ name: "step",
4167
+ kind: "input",
4168
+ type: "number | string",
4169
+ required: false,
4170
+ description: "Granularity for `type=\"number\"`, e.g. `0.01` or `'any'`."
4171
+ },
4172
+ {
4173
+ name: "autocomplete",
4174
+ kind: "input",
4175
+ type: "string",
4176
+ required: false,
4177
+ description: "Autofill hint, e.g. `email`, `current-password`, `off`."
4178
+ },
4179
+ {
4180
+ name: "inputMode",
4181
+ kind: "input",
4182
+ type: "UniInputMode",
4183
+ required: false,
4184
+ description: "On-screen keyboard hint; defaults to whatever `type` implies."
4185
+ },
4186
+ {
4187
+ name: "list",
4188
+ kind: "input",
4189
+ type: "string",
4190
+ required: false,
4191
+ description: "Id of a `<datalist>` supplying suggestions."
4192
+ },
4193
+ {
4194
+ name: "spellcheck",
4195
+ kind: "input",
4196
+ type: "boolean",
4197
+ required: false,
4198
+ description: ""
4199
+ },
4200
+ {
4201
+ name: "width",
4202
+ kind: "input",
4203
+ type: "string | number | undefined",
4204
+ required: false,
4205
+ default: "undefined",
4206
+ description: ""
4207
+ },
4208
+ {
4209
+ name: "fullWidth",
4210
+ kind: "input",
4211
+ type: "boolean",
4212
+ required: false,
4213
+ default: "false",
4214
+ description: ""
4215
+ },
4216
+ {
4217
+ name: "grow",
4218
+ kind: "input",
4219
+ type: "number | undefined",
4220
+ required: false,
4221
+ default: "undefined",
4222
+ description: ""
3574
4223
  }
3575
4224
  ]
3576
4225
  }
@@ -3605,6 +4254,16 @@ var uni_index_default = {
3605
4254
  title: "Long Label",
3606
4255
  framework: "angular",
3607
4256
  code: "<!-- Storybook story: Long Label -->\n<uni-input ${argsToTemplate(props)}>\n</uni-input>\n<!-- args:\n{\n label: 'A Very Long Label That Demonstrates How The Component Handles Extended Text',\n placeholder: 'Enter some text',\n value: '',\n disabled: false,\n touched: false,\n invalid: false,\n dirty: false,\n }\n-->"
4257
+ },
4258
+ {
4259
+ title: "Types",
4260
+ framework: "angular",
4261
+ code: "<!-- Storybook story: Types -->\n<uni-input ${argsToTemplate(props)}>\n</uni-input>"
4262
+ },
4263
+ {
4264
+ title: "With datalist",
4265
+ framework: "angular",
4266
+ code: "<!-- Storybook story: With datalist -->\n<uni-input ${argsToTemplate(props)}>\n</uni-input>"
3608
4267
  }
3609
4268
  ],
3610
4269
  guidelines: {
@@ -3641,7 +4300,7 @@ var uni_index_default = {
3641
4300
  summary: "",
3642
4301
  description: "",
3643
4302
  category: "forms",
3644
- version: "8.2.0",
4303
+ version: "9.0.0",
3645
4304
  bindings: {
3646
4305
  angular: {
3647
4306
  importPath: "@uni-design-system/uni-angular",
@@ -3678,6 +4337,30 @@ var uni_index_default = {
3678
4337
  required: false,
3679
4338
  default: "undefined",
3680
4339
  description: "Override the themed field height, e.g. `'auto'` for multi-line fields."
4340
+ },
4341
+ {
4342
+ name: "width",
4343
+ kind: "input",
4344
+ type: "string | number | undefined",
4345
+ required: false,
4346
+ default: "undefined",
4347
+ description: ""
4348
+ },
4349
+ {
4350
+ name: "fullWidth",
4351
+ kind: "input",
4352
+ type: "boolean",
4353
+ required: false,
4354
+ default: "false",
4355
+ description: ""
4356
+ },
4357
+ {
4358
+ name: "grow",
4359
+ kind: "input",
4360
+ type: "number | undefined",
4361
+ required: false,
4362
+ default: "undefined",
4363
+ description: ""
3681
4364
  }
3682
4365
  ]
3683
4366
  }
@@ -3714,7 +4397,7 @@ var uni_index_default = {
3714
4397
  summary: "",
3715
4398
  description: "",
3716
4399
  category: "components",
3717
- version: "8.2.0",
4400
+ version: "9.0.0",
3718
4401
  bindings: {
3719
4402
  angular: {
3720
4403
  importPath: "@uni-design-system/uni-angular",
@@ -3784,7 +4467,7 @@ var uni_index_default = {
3784
4467
  summary: "",
3785
4468
  description: "",
3786
4469
  category: "layout",
3787
- version: "8.2.0",
4470
+ version: "9.0.0",
3788
4471
  bindings: {
3789
4472
  angular: {
3790
4473
  importPath: "@uni-design-system/uni-angular",
@@ -3827,7 +4510,7 @@ var uni_index_default = {
3827
4510
  title: "Primary",
3828
4511
  framework: "angular",
3829
4512
  code: `<!-- Storybook story: Primary -->
3830
- <div box-layout color="primary" padding="sm">
4513
+ <div box-layout containerColor="primary" padding="sm">
3831
4514
  <uni-menu \${argsToTemplate(props)}>
3832
4515
  <button text-button variant="ghost" symbolRight="arrow_drop_down">Menu</button>
3833
4516
  </uni-menu>
@@ -3846,7 +4529,7 @@ var uni_index_default = {
3846
4529
  title: "Tones",
3847
4530
  framework: "angular",
3848
4531
  code: `<!-- Storybook story: Tones -->
3849
- <div box-layout color="primary" padding="sm">
4532
+ <div box-layout containerColor="primary" padding="sm">
3850
4533
  <uni-menu \${argsToTemplate(props)}>
3851
4534
  <button text-button variant="ghost" symbolRight="arrow_drop_down">Menu</button>
3852
4535
  </uni-menu>
@@ -3888,7 +4571,7 @@ var uni_index_default = {
3888
4571
  summary: "",
3889
4572
  description: "",
3890
4573
  category: "layout",
3891
- version: "8.2.0",
4574
+ version: "9.0.0",
3892
4575
  bindings: {
3893
4576
  angular: {
3894
4577
  importPath: "@uni-design-system/uni-angular",
@@ -3970,7 +4653,7 @@ var uni_index_default = {
3970
4653
  summary: "",
3971
4654
  description: "",
3972
4655
  category: "forms",
3973
- version: "8.2.0",
4656
+ version: "9.0.0",
3974
4657
  bindings: {
3975
4658
  angular: {
3976
4659
  importPath: "@uni-design-system/uni-angular",
@@ -4034,6 +4717,11 @@ var uni_index_default = {
4034
4717
  framework: "angular",
4035
4718
  code: "<!-- Storybook story: Single Selection -->\n<uni-multi-select ${argsToTemplate(props)}>\n</uni-multi-select>\n<!-- args:\n{\n options: [\n { value: 'red', label: 'Red' },\n { value: 'green', label: 'Green' },\n { value: 'blue', label: 'Blue' },\n ],\n selections: ['red'],\n }\n-->"
4036
4719
  },
4720
+ {
4721
+ title: "Disabled Options",
4722
+ framework: "angular",
4723
+ code: "<!-- Storybook story: Disabled Options -->\n<uni-multi-select ${argsToTemplate(props)}>\n</uni-multi-select>\n<!-- args:\n{\n options: [\n { value: 'email', label: 'Email' },\n { value: 'sms', label: 'SMS \u2014 verify a phone number first', disabled: true },\n { value: 'push', label: 'Push' },\n { value: 'fax', label: 'Fax \u2014 retired', disabled: true },\n ],\n selections: ['email'],\n }\n-->"
4724
+ },
4037
4725
  {
4038
4726
  title: "Many Options",
4039
4727
  framework: "angular",
@@ -4046,7 +4734,8 @@ var uni_index_default = {
4046
4734
  donts: [],
4047
4735
  accessibility: [
4048
4736
  "Options are real checkboxes in a labelled group \u2014 Space toggles, Tab moves between them.",
4049
- "Selection state is announced per option."
4737
+ "Selection state is announced per option.",
4738
+ "Disabled options stay rendered and announced, not hidden \u2014 removing them would"
4050
4739
  ]
4051
4740
  },
4052
4741
  relatedTokens: []
@@ -4058,7 +4747,7 @@ var uni_index_default = {
4058
4747
  summary: "",
4059
4748
  description: "",
4060
4749
  category: "forms",
4061
- version: "8.2.0",
4750
+ version: "9.0.0",
4062
4751
  bindings: {
4063
4752
  angular: {
4064
4753
  importPath: "@uni-design-system/uni-angular",
@@ -4173,6 +4862,11 @@ var uni_index_default = {
4173
4862
  framework: "angular",
4174
4863
  code: "<!-- Storybook story: Many Options -->\n<uni-multi-select-dropdown ${argsToTemplate(props)}>\n</uni-multi-select-dropdown>\n<!-- args:\n{\n options: [\n { value: 'option1', label: 'First Option' },\n { value: 'option2', label: 'Second Option' },\n { value: 'option3', label: 'Third Option' },\n { value: 'option4', label: 'Fourth Option' },\n { value: 'option5', label: 'Fifth Option' },\n { value: 'option6', label: 'Sixth Option' },\n { value: 'option7', label: 'Seventh Option' },\n { value: 'option8', label: 'Eighth Option' },\n ],\n value: ['option2', 'option4', 'option6'],\n }\n-->"
4175
4864
  },
4865
+ {
4866
+ title: "Disabled Options",
4867
+ framework: "angular",
4868
+ code: "<!-- Storybook story: Disabled Options -->\n<uni-multi-select-dropdown ${argsToTemplate(props)}>\n</uni-multi-select-dropdown>\n<!-- args:\n{\n options: [\n { value: 'email', label: 'Email' },\n { value: 'sms', label: 'SMS \u2014 verify a phone number first', disabled: true },\n { value: 'push', label: 'Push' },\n { value: 'fax', label: 'Fax \u2014 retired', disabled: true },\n ],\n value: ['email'],\n }\n-->"
4869
+ },
4176
4870
  {
4177
4871
  title: "Disabled",
4178
4872
  framework: "angular",
@@ -4196,7 +4890,8 @@ var uni_index_default = {
4196
4890
  accessibility: [
4197
4891
  'The trigger is a disclosure (`aria-haspopup="dialog"`, `aria-expanded`); the popover contains native focusables Tab reaches normally.',
4198
4892
  "The search input is labelled; options are real checkboxes announced with their state.",
4199
- "Escape closes the popover and returns focus to the trigger."
4893
+ "Escape closes the popover and returns focus to the trigger.",
4894
+ "Disabled options stay rendered and announced; arrows step over them and"
4200
4895
  ]
4201
4896
  },
4202
4897
  relatedTokens: []
@@ -4208,7 +4903,7 @@ var uni_index_default = {
4208
4903
  summary: "",
4209
4904
  description: "",
4210
4905
  category: "feedback",
4211
- version: "8.2.0",
4906
+ version: "9.0.0",
4212
4907
  bindings: {
4213
4908
  angular: {
4214
4909
  importPath: "@uni-design-system/uni-angular",
@@ -4452,7 +5147,7 @@ var uni_index_default = {
4452
5147
  summary: "",
4453
5148
  description: "",
4454
5149
  category: "feedback",
4455
- version: "8.2.0",
5150
+ version: "9.0.0",
4456
5151
  bindings: {
4457
5152
  angular: {
4458
5153
  importPath: "@uni-design-system/uni-angular",
@@ -4476,7 +5171,7 @@ var uni_index_default = {
4476
5171
  summary: "",
4477
5172
  description: "",
4478
5173
  category: "data",
4479
- version: "8.2.0",
5174
+ version: "9.0.0",
4480
5175
  bindings: {
4481
5176
  angular: {
4482
5177
  importPath: "@uni-design-system/uni-angular",
@@ -4558,10 +5253,10 @@ var uni_index_default = {
4558
5253
  id: "popover",
4559
5254
  name: "Popover",
4560
5255
  status: "stable",
4561
- summary: "",
4562
- description: "",
5256
+ 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.",
5257
+ 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.',
4563
5258
  category: "layout",
4564
- version: "8.2.0",
5259
+ version: "9.0.0",
4565
5260
  bindings: {
4566
5261
  angular: {
4567
5262
  importPath: "@uni-design-system/uni-angular",
@@ -4582,6 +5277,87 @@ var uni_index_default = {
4582
5277
  required: false,
4583
5278
  default: "true",
4584
5279
  description: 'Light-dismiss on outside click / Escape (native popover="auto").'
5280
+ },
5281
+ {
5282
+ name: "open",
5283
+ kind: "model",
5284
+ type: "boolean",
5285
+ required: false,
5286
+ default: "false",
5287
+ description: "Two-way open state; light dismissal and hover timers sync back into it."
5288
+ },
5289
+ {
5290
+ name: "mode",
5291
+ kind: "input",
5292
+ type: "'rich' | 'tooltip'",
5293
+ required: false,
5294
+ default: "'rich'",
5295
+ description: "`rich` = click-toggled disclosure; `tooltip` = hover/focus description."
5296
+ },
5297
+ {
5298
+ name: "anchor",
5299
+ kind: "input",
5300
+ type: "HTMLElement | string",
5301
+ required: false,
5302
+ description: "Anchor the panel to another element (or element id, resolved each time the panel opens) while the projected trigger keeps the disclosure ARIA. Empty string means unset."
5303
+ },
5304
+ {
5305
+ name: "header",
5306
+ kind: "input",
5307
+ type: "string",
5308
+ required: false,
5309
+ description: "Title rendered in the header row and used as the accessible name."
5310
+ },
5311
+ {
5312
+ name: "closable",
5313
+ kind: "input",
5314
+ type: "boolean",
5315
+ required: false,
5316
+ default: "false",
5317
+ description: 'Renders a "Close" icon button in the header row.'
5318
+ },
5319
+ {
5320
+ name: "arrow",
5321
+ kind: "input",
5322
+ type: "boolean",
5323
+ required: false,
5324
+ default: "true",
5325
+ description: ""
5326
+ },
5327
+ {
5328
+ name: "maxWidth",
5329
+ kind: "input",
5330
+ type: "string | number",
5331
+ required: false,
5332
+ description: "Panel max-width; numbers are px. Defaults to the theme's `maxWidth`."
5333
+ },
5334
+ {
5335
+ name: "openDelay",
5336
+ kind: "input",
5337
+ type: "number",
5338
+ required: false,
5339
+ description: "Tooltip-mode hover-open delay, ms; defaults to the theme option."
5340
+ },
5341
+ {
5342
+ name: "closeDelay",
5343
+ kind: "input",
5344
+ type: "number",
5345
+ required: false,
5346
+ description: "Tooltip-mode pointer-leave close delay, ms; defaults to the theme option."
5347
+ },
5348
+ {
5349
+ name: "opened",
5350
+ kind: "output",
5351
+ type: "void",
5352
+ required: false,
5353
+ description: ""
5354
+ },
5355
+ {
5356
+ name: "closed",
5357
+ kind: "output",
5358
+ type: "void",
5359
+ required: false,
5360
+ description: ""
4585
5361
  }
4586
5362
  ]
4587
5363
  }
@@ -4590,18 +5366,64 @@ var uni_index_default = {
4590
5366
  {
4591
5367
  title: "Primary",
4592
5368
  framework: "angular",
4593
- code: '<!-- Storybook story: Primary -->\n<uni-popover placement="${placement}" [autoClose]="${autoClose}" #popover>\n <button text-button trigger>Open Popover</button>\n <div stack-layout gap="sm">\n <div>\n <span uni-text="title-small" display="block">\n This is a Popover.\n </span>\n It is possible to add any markup you want to a Popover.\n </div>\n <div>\n <button text-button symbolLeft="thumb_up" size="sm" variant="secondary" (click)="popover.hidePopover()">OK!</button>\n </div>\n </div>\n</uni-popover>\n<!-- args:\n{\n placement: \'right-start\',\n autoClose: true,\n }\n-->'
5369
+ code: '<!-- Storybook story: Primary -->\n<uni-popover placement="${placement}" [autoClose]="${autoClose}" [arrow]="${arrow}" #popover>\n <button text-button trigger>Open Popover</button>\n <div stack-layout gap="sm">\n <div>\n <span uni-text="title-small" display="block">\n This is a Popover.\n </span>\n It is possible to add any markup you want to a Popover.\n </div>\n <div>\n <button text-button symbolLeft="thumb_up" size="sm" variant="secondary" (click)="popover.hidePopover()">OK!</button>\n </div>\n </div>\n</uni-popover>\n<!-- args:\n{\n placement: \'right-start\',\n autoClose: true,\n arrow: true,\n }\n-->'
5370
+ },
5371
+ {
5372
+ title: "Structured Form",
5373
+ framework: "angular",
5374
+ code: '<!-- Storybook story: Structured Form -->\n<uni-popover placement="${placement}" [autoClose]="${autoClose}" [arrow]="${arrow}" #popover>\n <button text-button trigger>Open Popover</button>\n <div stack-layout gap="sm">\n <div>\n <span uni-text="title-small" display="block">\n This is a Popover.\n </span>\n It is possible to add any markup you want to a Popover.\n </div>\n <div>\n <button text-button symbolLeft="thumb_up" size="sm" variant="secondary" (click)="popover.hidePopover()">OK!</button>\n </div>\n </div>\n</uni-popover>'
5375
+ },
5376
+ {
5377
+ title: "Detached Anchor",
5378
+ framework: "angular",
5379
+ code: '<!-- Storybook story: Detached Anchor -->\n<uni-popover placement="${placement}" [autoClose]="${autoClose}" [arrow]="${arrow}" #popover>\n <button text-button trigger>Open Popover</button>\n <div stack-layout gap="sm">\n <div>\n <span uni-text="title-small" display="block">\n This is a Popover.\n </span>\n It is possible to add any markup you want to a Popover.\n </div>\n <div>\n <button text-button symbolLeft="thumb_up" size="sm" variant="secondary" (click)="popover.hidePopover()">OK!</button>\n </div>\n </div>\n</uni-popover>'
5380
+ },
5381
+ {
5382
+ title: "Tooltip Mode",
5383
+ framework: "angular",
5384
+ code: '<!-- Storybook story: Tooltip Mode -->\n<uni-popover placement="${placement}" [autoClose]="${autoClose}" [arrow]="${arrow}" #popover>\n <button text-button trigger>Open Popover</button>\n <div stack-layout gap="sm">\n <div>\n <span uni-text="title-small" display="block">\n This is a Popover.\n </span>\n It is possible to add any markup you want to a Popover.\n </div>\n <div>\n <button text-button symbolLeft="thumb_up" size="sm" variant="secondary" (click)="popover.hidePopover()">OK!</button>\n </div>\n </div>\n</uni-popover>'
5385
+ },
5386
+ {
5387
+ title: "Manual Close",
5388
+ framework: "angular",
5389
+ code: '<!-- Storybook story: Manual Close -->\n<uni-popover placement="${placement}" [autoClose]="${autoClose}" [arrow]="${arrow}" #popover>\n <button text-button trigger>Open Popover</button>\n <div stack-layout gap="sm">\n <div>\n <span uni-text="title-small" display="block">\n This is a Popover.\n </span>\n It is possible to add any markup you want to a Popover.\n </div>\n <div>\n <button text-button symbolLeft="thumb_up" size="sm" variant="secondary" (click)="popover.hidePopover()">OK!</button>\n </div>\n </div>\n</uni-popover>'
4594
5390
  }
4595
5391
  ],
4596
5392
  guidelines: {
4597
- whenToUse: "Popover is a non-modal dialog that floats around a trigger.\nAny type of content can be added inside a popover; however, it is most suitable for short callouts or compact actions.\n**Note:** It is important to add the `trigger` attribute to the item you want to open and be referenced to the Popover.",
4598
- dos: [],
4599
- donts: [],
5393
+ whenToUse: 'Popover is an anchored, non-modal panel on the native popover top layer: the\nbrowser owns positioning, stacking, and light dismissal. Rich mode (the\ndefault) is a click-toggled disclosure for short callouts, small forms, and\ncompact actions; `mode="tooltip"` turns the same element into a hover/focus\ndescription with the full WCAG 1.4.13 contract. Anchoring and control are\nseparate \u2014 `anchor` re-anchors the panel to any element or id while the\nprojected `[trigger]` keeps the disclosure semantics, and with no trigger the\napp drives the two-way `open` model directly.',
5394
+ dos: [
5395
+ "Use rich mode for short callouts, small forms, and compact action clusters",
5396
+ "Give form popovers an `[autofocus]` field and a `[popover-footer]` action",
5397
+ "Use `anchor` when the panel should hug a field the trigger merely explains"
5398
+ ],
5399
+ donts: [
5400
+ "Put focusable content inside tooltip mode \u2014 promote it to rich mode instead",
5401
+ "Reach for a popover when the flow needs modality; that is a dialog"
5402
+ ],
4600
5403
  accessibility: [
4601
- "The trigger carries `aria-expanded` and `aria-controls`; light-dismiss comes from the native popover."
5404
+ "Rich mode wires `aria-expanded`/`aria-controls` onto the focusable trigger; with no projected trigger, no element claims controller ARIA.",
5405
+ 'Tooltip mode is `role="tooltip"` + `aria-describedby` \u2014 a description, never a name \u2014 and warns in dev mode if the content contains focusable elements.',
5406
+ "Focus stays on the trigger when the panel opens (APG disclosure) unless the panel marks an `[autofocus]` field; close returns focus to the trigger.",
5407
+ "The panel sits in the DOM right after the trigger, so Tab order is natural and there is no focus trap in either mode."
4602
5408
  ]
4603
5409
  },
4604
- relatedTokens: []
5410
+ relatedTokens: [
5411
+ "popover.behavior.color",
5412
+ "popover.behavior.border",
5413
+ "popover.behavior.borderRadius",
5414
+ "popover.behavior.shadow",
5415
+ "popover.behavior.typeface",
5416
+ "popover.behavior.padding",
5417
+ "popover.behavior.maxWidth",
5418
+ "popover.behavior.offset",
5419
+ "popover.behavior.arrowSize",
5420
+ "popover.behavior.closeSymbol",
5421
+ "popover.behavior.headerTypeface",
5422
+ "popover.behavior.tooltipPadding",
5423
+ "popover.behavior.tooltipOpenDelay",
5424
+ "popover.behavior.tooltipCloseDelay",
5425
+ "popover.behavior.motion"
5426
+ ]
4605
5427
  },
4606
5428
  {
4607
5429
  id: "progress-bar",
@@ -4610,7 +5432,7 @@ var uni_index_default = {
4610
5432
  summary: "",
4611
5433
  description: "",
4612
5434
  category: "feedback",
4613
- version: "8.2.0",
5435
+ version: "9.0.0",
4614
5436
  bindings: {
4615
5437
  angular: {
4616
5438
  importPath: "@uni-design-system/uni-angular",
@@ -4674,7 +5496,7 @@ var uni_index_default = {
4674
5496
  summary: "",
4675
5497
  description: "",
4676
5498
  category: "feedback",
4677
- version: "8.2.0",
5499
+ version: "9.0.0",
4678
5500
  bindings: {
4679
5501
  angular: {
4680
5502
  importPath: "@uni-design-system/uni-angular",
@@ -4730,7 +5552,7 @@ var uni_index_default = {
4730
5552
  summary: "",
4731
5553
  description: "",
4732
5554
  category: "forms",
4733
- version: "8.2.0",
5555
+ version: "9.0.0",
4734
5556
  bindings: {
4735
5557
  angular: {
4736
5558
  importPath: "@uni-design-system/uni-angular",
@@ -4872,7 +5694,7 @@ var uni_index_default = {
4872
5694
  "radio.behavior.size",
4873
5695
  "radio.behavior.ringColor",
4874
5696
  "radio.behavior.fillColor",
4875
- "radio.behavior.transitionSpeed"
5697
+ "radio.behavior.motion"
4876
5698
  ]
4877
5699
  },
4878
5700
  {
@@ -4882,7 +5704,7 @@ var uni_index_default = {
4882
5704
  summary: "",
4883
5705
  description: "",
4884
5706
  category: "directives",
4885
- version: "8.2.0",
5707
+ version: "9.0.0",
4886
5708
  bindings: {
4887
5709
  angular: {
4888
5710
  importPath: "@uni-design-system/uni-angular",
@@ -4906,7 +5728,7 @@ var uni_index_default = {
4906
5728
  summary: "",
4907
5729
  description: "",
4908
5730
  category: "layout",
4909
- version: "8.2.0",
5731
+ version: "9.0.0",
4910
5732
  bindings: {
4911
5733
  angular: {
4912
5734
  importPath: "@uni-design-system/uni-angular",
@@ -4961,18 +5783,18 @@ var uni_index_default = {
4961
5783
  summary: "Native scroll area with theme-driven scrollbar styling.",
4962
5784
  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.",
4963
5785
  category: "layout",
4964
- version: "8.2.0",
5786
+ version: "9.0.0",
4965
5787
  bindings: {
4966
5788
  angular: {
4967
5789
  importPath: "@uni-design-system/uni-angular",
4968
5790
  selectorOrTag: "[uni-scroll-area], [scroll-area]",
4969
5791
  api: [
4970
5792
  {
4971
- name: "color",
5793
+ name: "containerColor",
4972
5794
  kind: "input",
4973
5795
  type: "ContainerColorToken",
4974
5796
  required: false,
4975
- description: ""
5797
+ description: "A container color *pair*: the named surface plus its paired on-color. Named `containerColor`, not `color`, for the same reason as the layout primitives: this is an attribute directive-style selector that shares elements with `uni-text`, which owns `color` and maps it to the CSS property. One `color` binding feeding both would render ink on ink."
4976
5798
  },
4977
5799
  {
4978
5800
  name: "borderRadius",
@@ -5090,7 +5912,7 @@ var uni_index_default = {
5090
5912
  {
5091
5913
  title: "Primary",
5092
5914
  framework: "angular",
5093
- code: '<!-- Storybook story: Primary -->\n<div scroll-area ${argsToTemplate(props)} #scrollArea>\n <button size="sm" text-button variant="ghost" symbolLeft="arrow_downward" (click)="scrollArea.scrollToBottom()">Scroll to bottom</button>\n ${ngContent}\n <button size="sm" text-button variant="ghost" symbolLeft="arrow_upward" (click)="scrollArea.scrollToTop()">Back to top</button>\n</div>\n<!-- args:\n{\n border: \'quaternary\',\n color: \'tertiary-surface\',\n height: 200,\n ngContent: `\n <span uni-text="headline-medium">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</span>\n <span uni-text="body-1-long">\n <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quis facere debitis ullam, quae quidem, impedit\n culpa nam\n repellat in voluptatibus esse ab harum, hic? Aliquam nesciunt voluptates repellendus assumenda labore.\n </p>\n <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Porro quos voluptate doloribus. Optio unde\n inventore, tempore\n nemo repellat expedita! Quod, accusamus nobis iure. Aliquam quibusdam, nemo explicabo ipsum provident\n asperiores.</p>\n <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat, qui, rem! Debitis cum maiores iste,\n possimus!\n Obcaecati accusamus eaque expedita quo soluta quis, repudiandae similique, veritatis repellendus facere\n suscipit!\n Et!</p>\n <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Harum doloremque repellat praesentium quae et\n consectetur\n iure quos porro, provident voluptates reprehenderit a. Accusamus ut, quaerat asperiores blanditiis\n voluptate, sint\n facilis.</p>\n <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus beatae inventore nobis esse\n temporibus\n exercitationem\n eos illo minima non magnam, provident sit doloribus maiores odio in animi quidem unde. Perferendis.</p>\n\n </span>\n\n\n `,\n }\n-->'
5915
+ code: '<!-- Storybook story: Primary -->\n<div scroll-area ${argsToTemplate(props)} #scrollArea>\n <button size="sm" text-button variant="ghost" symbolLeft="arrow_downward" (click)="scrollArea.scrollToBottom()">Scroll to bottom</button>\n ${ngContent}\n <button size="sm" text-button variant="ghost" symbolLeft="arrow_upward" (click)="scrollArea.scrollToTop()">Back to top</button>\n</div>\n<!-- args:\n{\n border: \'quaternary\',\n containerColor: \'tertiary-surface\',\n height: 200,\n ngContent: `\n <span uni-text="headline-medium">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</span>\n <span uni-text="body-1-long">\n <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quis facere debitis ullam, quae quidem, impedit\n culpa nam\n repellat in voluptatibus esse ab harum, hic? Aliquam nesciunt voluptates repellendus assumenda labore.\n </p>\n <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Porro quos voluptate doloribus. Optio unde\n inventore, tempore\n nemo repellat expedita! Quod, accusamus nobis iure. Aliquam quibusdam, nemo explicabo ipsum provident\n asperiores.</p>\n <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat, qui, rem! Debitis cum maiores iste,\n possimus!\n Obcaecati accusamus eaque expedita quo soluta quis, repudiandae similique, veritatis repellendus facere\n suscipit!\n Et!</p>\n <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Harum doloremque repellat praesentium quae et\n consectetur\n iure quos porro, provident voluptates reprehenderit a. Accusamus ut, quaerat asperiores blanditiis\n voluptate, sint\n facilis.</p>\n <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus beatae inventore nobis esse\n temporibus\n exercitationem\n eos illo minima non magnam, provident sit doloribus maiores odio in animi quidem unde. Perferendis.</p>\n\n </span>\n\n\n `,\n }\n-->'
5094
5916
  }
5095
5917
  ],
5096
5918
  guidelines: {
@@ -5108,7 +5930,7 @@ var uni_index_default = {
5108
5930
  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.",
5109
5931
  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.",
5110
5932
  category: "forms",
5111
- version: "8.2.0",
5933
+ version: "9.0.0",
5112
5934
  bindings: {
5113
5935
  angular: {
5114
5936
  importPath: "@uni-design-system/uni-angular",
@@ -5153,18 +5975,18 @@ var uni_index_default = {
5153
5975
  description: "Type-ahead entries. Keep them fresh from `change` emissions; the list shows while the field has focus and entries exist."
5154
5976
  },
5155
5977
  {
5156
- name: "change",
5978
+ name: "searchChange",
5157
5979
  kind: "output",
5158
5980
  type: "string",
5159
5981
  required: false,
5160
- description: ""
5982
+ description: "The debounced query, emitted as the user types."
5161
5983
  },
5162
5984
  {
5163
- name: "search",
5985
+ name: "searchSubmit",
5164
5986
  kind: "output",
5165
5987
  type: "string",
5166
5988
  required: false,
5167
- description: ""
5989
+ description: "A committed search: Enter, or a suggestion chosen from the list."
5168
5990
  },
5169
5991
  {
5170
5992
  name: "suggestionSelected",
@@ -5186,8 +6008,8 @@ var uni_index_default = {
5186
6008
  label="Search the docs"
5187
6009
  [debounceTime]="200"
5188
6010
  [suggestions]="suggestions"
5189
- (change)="filter($event)"
5190
- (search)="log($event)"
6011
+ (searchChange)="filter($event)"
6012
+ (searchSubmit)="log($event)"
5191
6013
  ></uni-search-input>
5192
6014
  </div>
5193
6015
  <!-- args:
@@ -5197,11 +6019,11 @@ var uni_index_default = {
5197
6019
  {
5198
6020
  title: "Type-ahead",
5199
6021
  framework: "angular",
5200
- code: '<!-- Storybook story: Type-ahead -->\n<div box-layout maxWidth="420px">\n<uni-search-input\n label="Search the docs"\n [debounceTime]="200"\n [suggestions]="suggestions"\n (change)="filter($event)"\n (search)="log($event)"\n></uni-search-input>\n</div>'
6022
+ code: '<!-- Storybook story: Type-ahead -->\n<div box-layout maxWidth="420px">\n<uni-search-input\n label="Search the docs"\n [debounceTime]="200"\n [suggestions]="suggestions"\n (searchChange)="filter($event)"\n (searchSubmit)="log($event)"\n></uni-search-input>\n</div>'
5201
6023
  }
5202
6024
  ],
5203
6025
  guidelines: {
5204
- whenToUse: "Generic search field wearing the shared input chrome: a decorative leading magnifier,\na clear button while there's a query, and Enter to submit (`search`). `change` emits\ndebounced as the user types \u2014 use it to refresh results or the `suggestions` input.\nWith `suggestions`, the field becomes an ARIA combobox: entries render in a listbox\nunder the field, ArrowUp/Down move the highlight, Enter selects (emitting both\n`suggestionSelected` and `search`), and Escape closes the list first, then clears the\nquery. The suggestion list's surface, elevation and radius resolve from the theme's\n`searchInput` options, alongside the search/clear symbols.",
6026
+ whenToUse: "Generic search field wearing the shared input chrome: a decorative leading magnifier,\na clear button while there's a query, and Enter to submit (`searchSubmit`). `searchChange` emits\ndebounced as the user types \u2014 use it to refresh results or the `suggestions` input.\nWith `suggestions`, the field becomes an ARIA combobox: entries render in a listbox\nunder the field, ArrowUp/Down move the highlight, Enter selects (emitting both\n`suggestionSelected` and `searchSubmit`), and Escape closes the list first, then clears the\nquery. The suggestion list's surface, elevation and radius resolve from the theme's\n`searchInput` options, alongside the search/clear symbols.",
5205
6027
  dos: [],
5206
6028
  donts: [],
5207
6029
  accessibility: [
@@ -5219,7 +6041,7 @@ var uni_index_default = {
5219
6041
  summary: "",
5220
6042
  description: "",
5221
6043
  category: "forms",
5222
- version: "8.2.0",
6044
+ version: "9.0.0",
5223
6045
  bindings: {
5224
6046
  angular: {
5225
6047
  importPath: "@uni-design-system/uni-angular",
@@ -5295,6 +6117,30 @@ var uni_index_default = {
5295
6117
  required: false,
5296
6118
  description: ""
5297
6119
  },
6120
+ {
6121
+ name: "width",
6122
+ kind: "input",
6123
+ type: "string | number | undefined",
6124
+ required: false,
6125
+ default: "undefined",
6126
+ description: ""
6127
+ },
6128
+ {
6129
+ name: "fullWidth",
6130
+ kind: "input",
6131
+ type: "boolean",
6132
+ required: false,
6133
+ default: "false",
6134
+ description: ""
6135
+ },
6136
+ {
6137
+ name: "grow",
6138
+ kind: "input",
6139
+ type: "number | undefined",
6140
+ required: false,
6141
+ default: "undefined",
6142
+ description: ""
6143
+ },
5298
6144
  {
5299
6145
  name: "ariaLabel",
5300
6146
  kind: "input",
@@ -5321,6 +6167,11 @@ var uni_index_default = {
5321
6167
  framework: "angular",
5322
6168
  code: "<!-- Storybook story: Disabled -->\n<uni-select ${argsToTemplate(props)}>\n</uni-select>\n<!-- args:\n{\n placeholder: 'Cannot select...',\n options: [\n { value: 'option1', label: 'Option 1' },\n { value: 'option2', label: 'Option 2' },\n { value: 'option3', label: 'Option 3' },\n ],\n value: 'option2',\n disabled: true,\n touched: false,\n invalid: false,\n dirty: false,\n }\n-->"
5323
6169
  },
6170
+ {
6171
+ title: "Disabled Options",
6172
+ framework: "angular",
6173
+ code: "<!-- Storybook story: Disabled Options -->\n<uni-select ${argsToTemplate(props)}>\n</uni-select>\n<!-- args:\n{\n placeholder: 'Select a plan...',\n options: [\n { value: 'free', label: 'Free' },\n { value: 'pro', label: 'Pro' },\n { value: 'team', label: 'Team \u2014 requires an organization', disabled: true },\n { value: 'enterprise', label: 'Enterprise \u2014 contact sales', disabled: true },\n ],\n value: null,\n disabled: false,\n touched: false,\n invalid: false,\n dirty: false,\n }\n-->"
6174
+ },
5324
6175
  {
5325
6176
  title: "Invalid",
5326
6177
  framework: "angular",
@@ -5338,12 +6189,13 @@ var uni_index_default = {
5338
6189
  }
5339
6190
  ],
5340
6191
  guidelines: {
5341
- whenToUse: "Single choice from a list, on a native `<select>` \u2014 platform pickers on mobile,\nplatform keyboard behavior everywhere. Options are typed generically\n(`options: T[]` with `optionLabel`/`optionValue` accessors), and the component\nimplements `FormValueControl` for the Signal Forms `[field]` directive. Errors\nstyle the field only after interaction, matching Input.\nFor choosing several, use Multi Select; for type-to-filter over large sets, use\nSearch Input's type-ahead.",
6192
+ whenToUse: "Single choice from a list, on a native `<select>` \u2014 platform pickers on mobile,\nplatform keyboard behavior everywhere. Options are typed generically\n(`options: T[]` with `optionLabel`/`optionValue` accessors), and the component\nimplements `FormValueControl` for the Signal Forms `[field]` directive. Errors\nstyle the field only after interaction, matching Input.\nFor choosing several, use Multi Select. When the list outgrows ~10 options, or\nusers know what they're looking for and want to type it, use Combobox \u2014 the\nvalue contract is identical (`T | null`, `compareWith`), so the swap is a\ntemplate-only change.",
5342
6193
  dos: [],
5343
6194
  donts: [],
5344
6195
  accessibility: [
5345
6196
  "Native `<select>`: platform keyboard interaction and mobile pickers for free.",
5346
- "`label` becomes the accessible name; `aria-invalid` reflects the touched error state."
6197
+ "`label` becomes the accessible name; `aria-invalid` reflects the touched error state.",
6198
+ "Disabled options are rendered and announced, not hidden \u2014 removing them would"
5347
6199
  ]
5348
6200
  },
5349
6201
  relatedTokens: []
@@ -5353,9 +6205,9 @@ var uni_index_default = {
5353
6205
  name: "Skeleton",
5354
6206
  status: "stable",
5355
6207
  summary: "Loading placeholder painted with surface tokens.",
5356
- 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`.",
6208
+ 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.",
5357
6209
  category: "components",
5358
- version: "8.2.0",
6210
+ version: "9.0.0",
5359
6211
  bindings: {
5360
6212
  angular: {
5361
6213
  importPath: "@uni-design-system/uni-angular",
@@ -5392,6 +6244,38 @@ var uni_index_default = {
5392
6244
  required: false,
5393
6245
  default: "1",
5394
6246
  description: "Number of text lines (text shape only)."
6247
+ },
6248
+ {
6249
+ name: "color",
6250
+ kind: "input",
6251
+ type: "ColorKey | undefined",
6252
+ required: false,
6253
+ default: "undefined",
6254
+ description: "Base color token; overrides the theme option for this skeleton."
6255
+ },
6256
+ {
6257
+ name: "highlightColor",
6258
+ kind: "input",
6259
+ type: "ColorKey | undefined",
6260
+ required: false,
6261
+ default: "undefined",
6262
+ description: "Shimmer highlight token; overrides the theme option for this skeleton."
6263
+ },
6264
+ {
6265
+ name: "borderRadius",
6266
+ kind: "input",
6267
+ type: "Radius | undefined",
6268
+ required: false,
6269
+ default: "undefined",
6270
+ description: "Radius token; overrides the theme option. Circles are always round."
6271
+ },
6272
+ {
6273
+ name: "label",
6274
+ kind: "input",
6275
+ type: "string | undefined",
6276
+ required: false,
6277
+ default: "undefined",
6278
+ description: "Announces the skeleton to assistive tech as a polite status. Leave unset when a container already carries `aria-busy` \u2014 the skeleton then stays `aria-hidden`, as a decorative placeholder should."
5395
6279
  }
5396
6280
  ]
5397
6281
  }
@@ -5401,37 +6285,42 @@ var uni_index_default = {
5401
6285
  title: "Text Lines",
5402
6286
  framework: "angular",
5403
6287
  code: `<!-- Storybook story: Text Lines -->
5404
- <div box-layout maxWidth="360px">
6288
+ <div box-layout maxWidth="360px" gap="md">
5405
6289
  <uni-card>
5406
- <div row-layout gap="sm" alignItems="center" padding="md">
5407
- <uni-skeleton shape="circle" [height]="40" />
5408
- <div box-layout [grow]="1">
5409
- <uni-skeleton [lines]="2" />
6290
+ <div box-layout padding="md" gap="sm">
6291
+ <div row-layout gap="sm" alignItems="center">
6292
+ <uni-skeleton shape="rect" borderRadius="max" [width]="56" [height]="20" />
6293
+ <uni-skeleton shape="rect" [width]="120" [height]="12" />
5410
6294
  </div>
5411
- </div>
5412
- <div box-layout paddingHorizontal="md" paddingBottom="md">
5413
- <uni-skeleton shape="rect" [height]="120" />
6295
+ <uni-skeleton [lines]="2" />
5414
6296
  </div>
5415
6297
  </uni-card>
6298
+ <uni-skeleton color="surface" highlightColor="surface-variant" [lines]="2" />
5416
6299
  </div>
5417
6300
  <!-- args:
5418
6301
  { shape: 'text', lines: 3 }
5419
6302
  -->`
5420
6303
  },
6304
+ {
6305
+ title: "Per Instance Tokens",
6306
+ framework: "angular",
6307
+ code: '<!-- Storybook story: Per Instance Tokens -->\n<div box-layout maxWidth="360px" gap="md">\n<uni-card>\n <div box-layout padding="md" gap="sm">\n <div row-layout gap="sm" alignItems="center">\n <uni-skeleton shape="rect" borderRadius="max" [width]="56" [height]="20" />\n <uni-skeleton shape="rect" [width]="120" [height]="12" />\n </div>\n <uni-skeleton [lines]="2" />\n </div>\n</uni-card>\n<uni-skeleton color="surface" highlightColor="surface-variant" [lines]="2" />\n</div>'
6308
+ },
5421
6309
  {
5422
6310
  title: "Card Placeholder",
5423
6311
  framework: "angular",
5424
- code: '<!-- Storybook story: Card Placeholder -->\n<div box-layout maxWidth="360px">\n<uni-card>\n <div row-layout gap="sm" alignItems="center" padding="md">\n <uni-skeleton shape="circle" [height]="40" />\n <div box-layout [grow]="1">\n <uni-skeleton [lines]="2" />\n </div>\n </div>\n <div box-layout paddingHorizontal="md" paddingBottom="md">\n <uni-skeleton shape="rect" [height]="120" />\n </div>\n</uni-card>\n</div>'
6312
+ code: '<!-- Storybook story: Card Placeholder -->\n<div box-layout maxWidth="360px" gap="md">\n<uni-card>\n <div box-layout padding="md" gap="sm">\n <div row-layout gap="sm" alignItems="center">\n <uni-skeleton shape="rect" borderRadius="max" [width]="56" [height]="20" />\n <uni-skeleton shape="rect" [width]="120" [height]="12" />\n </div>\n <uni-skeleton [lines]="2" />\n </div>\n</uni-card>\n<uni-skeleton color="surface" highlightColor="surface-variant" [lines]="2" />\n</div>'
5425
6313
  }
5426
6314
  ],
5427
6315
  guidelines: {
5428
- whenToUse: "Loading placeholder that sketches the shape of incoming content: `text` renders one or\nmore lines (ending on a short line, as real copy would), `rect` stands in for media and\ncharts, `circle` for avatars. Skeletons paint with the theme's surface tokens so they\nsit naturally on any brand in both modes, and the shimmer sweep only animates for users\nwho allow motion \u2014 under `prefers-reduced-motion` it degrades to calm static blocks.\nSkeletons are `aria-hidden`; announce loading on the container (e.g. `aria-busy`)\nwhere your app knows what is actually loading.",
6316
+ whenToUse: "Loading placeholder that sketches the shape of incoming content: `text` renders one or\nmore lines (ending on a short line, as real copy would), `rect` stands in for media and\ncharts, `circle` for avatars. Skeletons paint with the theme's surface tokens so they\nsit naturally on any brand in both modes, and the shimmer sweep only animates for users\nwho allow motion \u2014 under `prefers-reduced-motion` it degrades to calm static blocks.\nSkeletons are `aria-hidden` by default; announce loading on the container (e.g. `aria-busy`)\nwhere your app knows what is actually loading, or give a standalone skeleton a `label`.",
5429
6317
  dos: [],
5430
6318
  donts: [
5431
- "Announce individual skeletons to assistive tech \u2014 they are decorative placeholders"
6319
+ "Announce every skeleton in a group \u2014 label the container, or one skeleton, not twelve"
5432
6320
  ],
5433
6321
  accessibility: [
5434
- "Skeletons are `aria-hidden` \u2014 announce loading on the container (e.g. `aria-busy`) where your app knows what is loading.",
6322
+ "Skeletons are `aria-hidden` unless given a `label` \u2014 announce loading on the container (e.g. `aria-busy`) where your app knows what is loading.",
6323
+ 'A `label` puts `role="status"` on the host with visually hidden text, so a standalone skeleton announces politely on mount.',
5435
6324
  "The shimmer respects `prefers-reduced-motion`, degrading to static blocks."
5436
6325
  ]
5437
6326
  },
@@ -5441,6 +6330,8 @@ var uni_index_default = {
5441
6330
  "skeleton.behavior.borderRadius",
5442
6331
  "skeleton.behavior.animation",
5443
6332
  "skeleton.behavior.duration",
6333
+ "skeleton.behavior.direction",
6334
+ "skeleton.behavior.highlightWidth",
5444
6335
  "skeleton.behavior.gap"
5445
6336
  ]
5446
6337
  },
@@ -5451,7 +6342,7 @@ var uni_index_default = {
5451
6342
  summary: 'Range slider on a native `<input type="range">` \u2014 keyboard interaction and the ARIA slider contract come from the platform.',
5452
6343
  description: 'Range slider on a native `<input type="range">` \u2014 keyboard interaction and the ARIA slider contract come from the platform. Fill, track, thumb and radii resolve from `slider` theme tokens; the fill percentage rides a CSS custom property so dragging never regenerates styles.',
5453
6344
  category: "forms",
5454
- version: "8.2.0",
6345
+ version: "9.0.0",
5455
6346
  bindings: {
5456
6347
  angular: {
5457
6348
  importPath: "@uni-design-system/uni-angular",
@@ -5588,7 +6479,7 @@ var uni_index_default = {
5588
6479
  summary: "",
5589
6480
  description: "",
5590
6481
  category: "feedback",
5591
- version: "8.2.0",
6482
+ version: "9.0.0",
5592
6483
  bindings: {
5593
6484
  angular: {
5594
6485
  importPath: "@uni-design-system/uni-angular",
@@ -5665,11 +6556,15 @@ var uni_index_default = {
5665
6556
  whenToUse: "The Snackbar component is used to give feedback to users after an action has taken place.\nIt appears near the bottom center of the screen temporarily and floats above the UI to not affect the application's layout.\nA side action can be defined (e.g. undoing a process or navigating to the details of a newly created record).",
5666
6557
  dos: [],
5667
6558
  donts: [],
5668
- accessibility: []
6559
+ accessibility: [
6560
+ '`role="status"` announces the message politely, without moving focus away',
6561
+ "The bar renders in the browser's top layer, so it cannot be covered by a",
6562
+ 'It is a `popover="manual"`, not a modal: the rest of the page stays'
6563
+ ]
5669
6564
  },
5670
6565
  relatedTokens: [
5671
6566
  "snackbar.behavior.bottomPosition",
5672
- "snackbar.behavior.transitionDelay",
6567
+ "snackbar.behavior.motion",
5673
6568
  "snackbar.behavior.autoCloseDelay"
5674
6569
  ]
5675
6570
  },
@@ -5680,7 +6575,7 @@ var uni_index_default = {
5680
6575
  summary: "",
5681
6576
  description: "",
5682
6577
  category: "data",
5683
- version: "8.2.0",
6578
+ version: "9.0.0",
5684
6579
  bindings: {
5685
6580
  angular: {
5686
6581
  importPath: "@uni-design-system/uni-angular",
@@ -5739,7 +6634,7 @@ var uni_index_default = {
5739
6634
  summary: "",
5740
6635
  description: "",
5741
6636
  category: "layout",
5742
- version: "8.2.0",
6637
+ version: "9.0.0",
5743
6638
  bindings: {
5744
6639
  angular: {
5745
6640
  importPath: "@uni-design-system/uni-angular",
@@ -5794,7 +6689,7 @@ var uni_index_default = {
5794
6689
  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.',
5795
6690
  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.',
5796
6691
  category: "components",
5797
- version: "8.2.0",
6692
+ version: "9.0.0",
5798
6693
  bindings: {
5799
6694
  angular: {
5800
6695
  importPath: "@uni-design-system/uni-angular",
@@ -5896,7 +6791,7 @@ var uni_index_default = {
5896
6791
  summary: "",
5897
6792
  description: "",
5898
6793
  category: "primitives",
5899
- version: "8.2.0",
6794
+ version: "9.0.0",
5900
6795
  bindings: {
5901
6796
  angular: {
5902
6797
  importPath: "@uni-design-system/uni-angular",
@@ -5969,7 +6864,7 @@ var uni_index_default = {
5969
6864
  summary: "One tab inside `uni-tabs`: a label for the tablist plus projected panel content.",
5970
6865
  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.",
5971
6866
  category: "components",
5972
- version: "8.2.0",
6867
+ version: "9.0.0",
5973
6868
  bindings: {
5974
6869
  angular: {
5975
6870
  importPath: "@uni-design-system/uni-angular",
@@ -6009,7 +6904,7 @@ var uni_index_default = {
6009
6904
  summary: "WAI-ARIA tabs: roving tabindex, automatic activation (arrow keys move focus and select), Home/End, disabled tabs skipped.",
6010
6905
  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.",
6011
6906
  category: "components",
6012
- version: "8.2.0",
6907
+ version: "9.0.0",
6013
6908
  bindings: {
6014
6909
  angular: {
6015
6910
  importPath: "@uni-design-system/uni-angular",
@@ -6073,7 +6968,7 @@ var uni_index_default = {
6073
6968
  summary: "Compact chip for categories, states, filters and tokens.",
6074
6969
  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. 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.",
6075
6970
  category: "data",
6076
- version: "8.2.0",
6971
+ version: "9.0.0",
6077
6972
  bindings: {
6078
6973
  angular: {
6079
6974
  importPath: "@uni-design-system/uni-angular",
@@ -6435,7 +7330,7 @@ var uni_index_default = {
6435
7330
  summary: "",
6436
7331
  description: "",
6437
7332
  category: "forms",
6438
- version: "8.2.0",
7333
+ version: "9.0.0",
6439
7334
  bindings: {
6440
7335
  angular: {
6441
7336
  importPath: "@uni-design-system/uni-angular",
@@ -6750,9 +7645,9 @@ placeholder="Name or address\u2026"
6750
7645
  name: "Text",
6751
7646
  status: "stable",
6752
7647
  summary: "The typography primitive, applied as an attribute to any element so semantics stay yours.",
6753
- 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.',
7648
+ 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.',
6754
7649
  category: "primitives",
6755
- version: "8.2.0",
7650
+ version: "9.0.0",
6756
7651
  bindings: {
6757
7652
  angular: {
6758
7653
  importPath: "@uni-design-system/uni-angular",
@@ -6779,7 +7674,7 @@ placeholder="Name or address\u2026"
6779
7674
  kind: "input",
6780
7675
  type: "ColorKey",
6781
7676
  required: false,
6782
- description: ""
7677
+ description: "The ink, mapping straight to the CSS `color` property."
6783
7678
  },
6784
7679
  {
6785
7680
  name: "display",
@@ -6833,7 +7728,7 @@ placeholder="Name or address\u2026"
6833
7728
  }
6834
7729
  ],
6835
7730
  guidelines: {
6836
- whenToUse: 'The typography primitive, applied as an **attribute on any element** so your HTML\nsemantics stay intact. The attribute value is the typeface \u2014\n`<h1 uni-text="display-small">` \u2014 and `[uni-text]="role()"` binds it dynamically.\nWith no value, the typeface is inferred from the host element (`h1` \u2192\n`headline-large`, `p` \u2192 `body-1-long`, `small` \u2192 `caption`, `blockquote` \u2192 `quote`,\nfalling back to `title-small`), so plain semantic markup is correctly set with zero\nconfiguration. `color` takes any theme color token; `align`, `nowrap`, `maxWidth`,\nand `ellipsis` handle common text layout.',
7731
+ whenToUse: 'The typography primitive, applied as an **attribute on any element** so your HTML\nsemantics stay intact. The attribute value is the typeface \u2014\n`<h1 uni-text="display-small">` \u2014 and `[uni-text]="role()"` binds it dynamically.\nWith no value, the typeface is inferred from the host element (`h1` \u2192\n`headline-large`, `p` \u2192 `body-1-long`, `small` \u2192 `caption`, `blockquote` \u2192 `quote`,\nfalling back to `title-small`), so plain semantic markup is correctly set with zero\nconfiguration. `color` takes any theme color token; `align`, `nowrap`, `maxWidth`,\nand `ellipsis` handle common text layout.\nIt is a directive, so it stacks with anything else on the element \u2014 a layout\nattribute or a component\'s own host \u2014 rather than colliding with it:\n```html\n```\nText owns `color`, because it maps straight to the CSS property. The layout\ndirectives name their container pair `containerColor`, so the two never compete\nfor one binding \u2014 set both on the same element and each reaches its own\ndirective:\n```html\n Heading\n```\n`containerColor` sets a background **and** its paired on-color, so both\ndirectives write `color` to the element. An explicit `uni-text` `color` always\nwins that \u2014 it is emitted at higher specificity rather than left to stylesheet\norder. Set no `color` and the container\'s on-color shows through, which is the\npoint of a pair.',
6837
7732
  dos: [
6838
7733
  "Reach for semantic elements first and let the element-aware defaults set the type"
6839
7734
  ],
@@ -6853,8 +7748,8 @@ placeholder="Name or address\u2026"
6853
7748
  status: "stable",
6854
7749
  summary: "",
6855
7750
  description: "",
6856
- category: "primitives",
6857
- version: "8.2.0",
7751
+ category: "forms",
7752
+ version: "9.0.0",
6858
7753
  bindings: {
6859
7754
  angular: {
6860
7755
  importPath: "@uni-design-system/uni-angular",
@@ -6937,6 +7832,76 @@ placeholder="Name or address\u2026"
6937
7832
  required: false,
6938
7833
  default: "undefined",
6939
7834
  description: "Visible text rows. Defaults to the theme's `textarea` options."
7835
+ },
7836
+ {
7837
+ name: "readonly",
7838
+ kind: "input",
7839
+ type: "boolean",
7840
+ required: false,
7841
+ default: "false",
7842
+ description: ""
7843
+ },
7844
+ {
7845
+ name: "name",
7846
+ kind: "input",
7847
+ type: "string",
7848
+ required: false,
7849
+ default: "''",
7850
+ description: ""
7851
+ },
7852
+ {
7853
+ name: "minLength",
7854
+ kind: "input",
7855
+ type: "number | undefined",
7856
+ required: false,
7857
+ default: "undefined",
7858
+ description: ""
7859
+ },
7860
+ {
7861
+ name: "maxLength",
7862
+ kind: "input",
7863
+ type: "number | undefined",
7864
+ required: false,
7865
+ default: "undefined",
7866
+ description: ""
7867
+ },
7868
+ {
7869
+ name: "autocomplete",
7870
+ kind: "input",
7871
+ type: "string",
7872
+ required: false,
7873
+ description: ""
7874
+ },
7875
+ {
7876
+ name: "spellcheck",
7877
+ kind: "input",
7878
+ type: "boolean",
7879
+ required: false,
7880
+ description: ""
7881
+ },
7882
+ {
7883
+ name: "width",
7884
+ kind: "input",
7885
+ type: "string | number | undefined",
7886
+ required: false,
7887
+ default: "undefined",
7888
+ description: ""
7889
+ },
7890
+ {
7891
+ name: "fullWidth",
7892
+ kind: "input",
7893
+ type: "boolean",
7894
+ required: false,
7895
+ default: "false",
7896
+ description: ""
7897
+ },
7898
+ {
7899
+ name: "grow",
7900
+ kind: "input",
7901
+ type: "number | undefined",
7902
+ required: false,
7903
+ default: "undefined",
7904
+ description: ""
6940
7905
  }
6941
7906
  ]
6942
7907
  }
@@ -6984,7 +7949,7 @@ placeholder="Name or address\u2026"
6984
7949
  summary: "",
6985
7950
  description: "",
6986
7951
  category: "primitives",
6987
- version: "8.2.0",
7952
+ version: "9.0.0",
6988
7953
  bindings: {
6989
7954
  angular: {
6990
7955
  importPath: "@uni-design-system/uni-angular",
@@ -7014,7 +7979,7 @@ placeholder="Name or address\u2026"
7014
7979
  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).",
7015
7980
  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).",
7016
7981
  category: "components",
7017
- version: "8.2.0",
7982
+ version: "9.0.0",
7018
7983
  bindings: {
7019
7984
  angular: {
7020
7985
  importPath: "@uni-design-system/uni-angular",
@@ -7072,7 +8037,7 @@ placeholder="Name or address\u2026"
7072
8037
  summary: "Time field: a combobox over time options \u2014 the same listbox contract as uni-search-input and uni-tag-input.",
7073
8038
  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.",
7074
8039
  category: "forms",
7075
- version: "8.2.0",
8040
+ version: "9.0.0",
7076
8041
  bindings: {
7077
8042
  angular: {
7078
8043
  importPath: "@uni-design-system/uni-angular",
@@ -7264,7 +8229,7 @@ placeholder="Name or address\u2026"
7264
8229
  summary: "",
7265
8230
  description: "",
7266
8231
  category: "forms",
7267
- version: "8.2.0",
8232
+ version: "9.0.0",
7268
8233
  bindings: {
7269
8234
  angular: {
7270
8235
  importPath: "@uni-design-system/uni-angular",
@@ -7394,7 +8359,7 @@ placeholder="Name or address\u2026"
7394
8359
  summary: "",
7395
8360
  description: "",
7396
8361
  category: "feedback",
7397
- version: "8.2.0",
8362
+ version: "9.0.0",
7398
8363
  bindings: {
7399
8364
  angular: {
7400
8365
  importPath: "@uni-design-system/uni-angular",
@@ -7430,14 +8395,6 @@ placeholder="Name or address\u2026"
7430
8395
  required: false,
7431
8396
  default: "false",
7432
8397
  description: ""
7433
- },
7434
- {
7435
- name: "appendToBody",
7436
- kind: "input",
7437
- type: "boolean",
7438
- required: false,
7439
- default: "false",
7440
- description: "@deprecated The tooltip renders in the native top layer; ignored."
7441
8398
  }
7442
8399
  ]
7443
8400
  }
@@ -7466,6 +8423,117 @@ placeholder="Name or address\u2026"
7466
8423
  "tooltip.behavior.typeface"
7467
8424
  ]
7468
8425
  },
8426
+ {
8427
+ id: "tour",
8428
+ name: "Tour",
8429
+ status: "stable",
8430
+ 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).',
8431
+ 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.',
8432
+ category: "components",
8433
+ version: "9.0.0",
8434
+ bindings: {
8435
+ angular: {
8436
+ importPath: "@uni-design-system/uni-angular",
8437
+ selectorOrTag: "uni-tour",
8438
+ api: [
8439
+ {
8440
+ name: "steps",
8441
+ kind: "input",
8442
+ type: "UniTourStep[]",
8443
+ required: true,
8444
+ description: ""
8445
+ },
8446
+ {
8447
+ name: "active",
8448
+ kind: "model",
8449
+ type: "number | null",
8450
+ required: false,
8451
+ default: "null",
8452
+ description: "The presented step index, or null when the tour is not running."
8453
+ },
8454
+ {
8455
+ name: "nextLabel",
8456
+ kind: "input",
8457
+ type: "string",
8458
+ required: false,
8459
+ default: "'Next'",
8460
+ description: ""
8461
+ },
8462
+ {
8463
+ name: "backLabel",
8464
+ kind: "input",
8465
+ type: "string",
8466
+ required: false,
8467
+ default: "'Back'",
8468
+ description: ""
8469
+ },
8470
+ {
8471
+ name: "skipLabel",
8472
+ kind: "input",
8473
+ type: "string",
8474
+ required: false,
8475
+ default: "'Skip'",
8476
+ description: ""
8477
+ },
8478
+ {
8479
+ name: "doneLabel",
8480
+ kind: "input",
8481
+ type: "string",
8482
+ required: false,
8483
+ default: "'Done'",
8484
+ description: ""
8485
+ },
8486
+ {
8487
+ name: "started",
8488
+ kind: "output",
8489
+ type: "void",
8490
+ required: false,
8491
+ description: ""
8492
+ },
8493
+ {
8494
+ name: "finished",
8495
+ kind: "output",
8496
+ type: "void",
8497
+ required: false,
8498
+ description: ""
8499
+ }
8500
+ ]
8501
+ }
8502
+ },
8503
+ examples: [
8504
+ {
8505
+ title: "Primary",
8506
+ framework: "angular",
8507
+ code: '<!-- Storybook story: Primary -->\n<div stack-layout gap="md">\n<button text-button (click)="tour.start()">Start tour</button>\n<uni-input label="Search projects" id="tour-demo-search"></uni-input>\n<uni-input label="Weekly report" id="tour-demo-report"></uni-input>\n<uni-input label="Project name" id="tour-demo-name"></uni-input>\n<div><button text-button variant="secondary" id="tour-demo-create">Create project</button></div>\n<uni-tour #tour [steps]="steps"></uni-tour>\n</div>'
8508
+ },
8509
+ {
8510
+ title: "Fraction Progress",
8511
+ framework: "angular",
8512
+ code: '<!-- Storybook story: Fraction Progress -->\n<div stack-layout gap="md">\n<button text-button (click)="tour.start()">Start tour</button>\n<uni-input label="Search projects" id="tour-demo-search"></uni-input>\n<uni-input label="Weekly report" id="tour-demo-report"></uni-input>\n<uni-input label="Project name" id="tour-demo-name"></uni-input>\n<div><button text-button variant="secondary" id="tour-demo-create">Create project</button></div>\n<uni-tour #tour [steps]="steps"></uni-tour>\n</div>'
8513
+ }
8514
+ ],
8515
+ guidelines: {
8516
+ whenToUse: 'Tour sequences one `uni-callout` through a list of steps: spotlight targets,\ndim interludes, and interaction gates. A step with `advanceOn` locks Next\nuntil the user performs the gesture on its target \u2014 clicks auto-advance\n(the gesture is complete), anything else unlocks Next and announces it\nthrough one polite `role="status"` region, so nobody is yanked forward\nmid-typing. Steps whose declared target cannot be found are skipped in the\ndirection of travel with a dev warning, never an error. `active` is a\ntwo-way model, so tours are deep-linkable; Escape or the close button skips\nand reports the step through `skipped`.',
8517
+ dos: [
8518
+ "Keep tours short and gate only steps whose gesture teaches something",
8519
+ "Handle `skipped`/`finished` and persist them \u2014 the tour holds no storage"
8520
+ ],
8521
+ donts: [
8522
+ "Point steps at elements that may not exist without accepting the skip",
8523
+ "Span routes in one tour; sequence per page instead"
8524
+ ],
8525
+ accessibility: [
8526
+ 'Each panel is labelled `"<title>, step <n> of <total>"`; the dots are `aria-hidden` decoration.',
8527
+ 'Gate unlocks are announced ("Next available") through a single persistent live region.',
8528
+ "Arrow-key navigation never fires while the user is typing in a spotlit target.",
8529
+ "The close button reads as the skip affordance (`skipLabel`)."
8530
+ ]
8531
+ },
8532
+ relatedTokens: [
8533
+ "tour.behavior.progressStyle",
8534
+ "tour.behavior.footerGap"
8535
+ ]
8536
+ },
7469
8537
  {
7470
8538
  id: "wrap",
7471
8539
  name: "Wrap",
@@ -7473,7 +8541,7 @@ placeholder="Name or address\u2026"
7473
8541
  summary: "",
7474
8542
  description: "",
7475
8543
  category: "layout",
7476
- version: "8.2.0",
8544
+ version: "9.0.0",
7477
8545
  bindings: {
7478
8546
  angular: {
7479
8547
  importPath: "@uni-design-system/uni-angular",
@@ -8505,6 +9573,17 @@ placeholder="Name or address\u2026"
8505
9573
  DarkTheme: "64px"
8506
9574
  }
8507
9575
  },
9576
+ {
9577
+ id: "spacing.xxl",
9578
+ value: "128px",
9579
+ type: "spacing",
9580
+ kind: "style",
9581
+ target: "emotion-css",
9582
+ themeValues: {
9583
+ LightTheme: "128px",
9584
+ DarkTheme: "128px"
9585
+ }
9586
+ },
8508
9587
  {
8509
9588
  id: "border.primary",
8510
9589
  value: "1px solid #6A6F8F",
@@ -8992,15 +10071,15 @@ placeholder="Name or address\u2026"
8992
10071
  }
8993
10072
  },
8994
10073
  {
8995
- id: "alert.behavior.transitionSpeed",
8996
- value: 0.35,
8997
- type: "number",
10074
+ id: "alert.behavior.motion",
10075
+ value: "notification",
10076
+ type: "string",
8998
10077
  kind: "behavioral",
8999
10078
  target: "component-prop",
9000
10079
  appliesTo: "alert",
9001
10080
  themeValues: {
9002
- LightTheme: 0.35,
9003
- DarkTheme: 0.35
10081
+ LightTheme: "notification",
10082
+ DarkTheme: "notification"
9004
10083
  }
9005
10084
  },
9006
10085
  {
@@ -9351,6 +10430,18 @@ placeholder="Name or address\u2026"
9351
10430
  DarkTheme: "xs"
9352
10431
  }
9353
10432
  },
10433
+ {
10434
+ id: "searchInput.behavior.activeColor",
10435
+ value: "primary-container",
10436
+ type: "string",
10437
+ kind: "behavioral",
10438
+ target: "component-prop",
10439
+ appliesTo: "searchInput",
10440
+ themeValues: {
10441
+ LightTheme: "primary-container",
10442
+ DarkTheme: "primary-container"
10443
+ }
10444
+ },
9354
10445
  {
9355
10446
  id: "searchInput.behavior.maxSuggestions",
9356
10447
  value: 8,
@@ -9448,15 +10539,15 @@ placeholder="Name or address\u2026"
9448
10539
  }
9449
10540
  },
9450
10541
  {
9451
- id: "radio.behavior.transitionSpeed",
9452
- value: 0.3,
9453
- type: "number",
10542
+ id: "radio.behavior.motion",
10543
+ value: "control",
10544
+ type: "string",
9454
10545
  kind: "behavioral",
9455
10546
  target: "component-prop",
9456
10547
  appliesTo: "radio",
9457
10548
  themeValues: {
9458
- LightTheme: 0.3,
9459
- DarkTheme: 0.3
10549
+ LightTheme: "control",
10550
+ DarkTheme: "control"
9460
10551
  }
9461
10552
  },
9462
10553
  {
@@ -9771,6 +10862,18 @@ placeholder="Name or address\u2026"
9771
10862
  DarkTheme: "menu"
9772
10863
  }
9773
10864
  },
10865
+ {
10866
+ id: "dropdown.behavior.motion",
10867
+ value: "popup",
10868
+ type: "string",
10869
+ kind: "behavioral",
10870
+ target: "component-prop",
10871
+ appliesTo: "dropdown",
10872
+ themeValues: {
10873
+ LightTheme: "popup",
10874
+ DarkTheme: "popup"
10875
+ }
10876
+ },
9774
10877
  {
9775
10878
  id: "menu.behavior.minWidth",
9776
10879
  value: 184,
@@ -9916,27 +11019,207 @@ placeholder="Name or address\u2026"
9916
11019
  }
9917
11020
  },
9918
11021
  {
9919
- id: "menuItem.behavior.transitionSpeed",
9920
- value: 0.35,
9921
- type: "number",
11022
+ id: "menuItem.behavior.motion",
11023
+ value: "control",
11024
+ type: "string",
9922
11025
  kind: "behavioral",
9923
11026
  target: "component-prop",
9924
11027
  appliesTo: "menuItem",
9925
11028
  themeValues: {
9926
- LightTheme: 0.35,
9927
- DarkTheme: 0.35
11029
+ LightTheme: "control",
11030
+ DarkTheme: "control"
11031
+ }
11032
+ },
11033
+ {
11034
+ id: "popover.behavior.color",
11035
+ value: "primary-surface",
11036
+ type: "string",
11037
+ kind: "behavioral",
11038
+ target: "component-prop",
11039
+ appliesTo: "popover",
11040
+ themeValues: {
11041
+ LightTheme: "primary-surface",
11042
+ DarkTheme: "primary-surface"
11043
+ }
11044
+ },
11045
+ {
11046
+ id: "popover.behavior.border",
11047
+ value: "quaternary",
11048
+ type: "string",
11049
+ kind: "behavioral",
11050
+ target: "component-prop",
11051
+ appliesTo: "popover",
11052
+ themeValues: {
11053
+ LightTheme: "quaternary",
11054
+ DarkTheme: "quaternary"
11055
+ }
11056
+ },
11057
+ {
11058
+ id: "popover.behavior.borderRadius",
11059
+ value: "xs",
11060
+ type: "string",
11061
+ kind: "behavioral",
11062
+ target: "component-prop",
11063
+ appliesTo: "popover",
11064
+ themeValues: {
11065
+ LightTheme: "xs",
11066
+ DarkTheme: "xs"
11067
+ }
11068
+ },
11069
+ {
11070
+ id: "popover.behavior.shadow",
11071
+ value: "raised",
11072
+ type: "string",
11073
+ kind: "behavioral",
11074
+ target: "component-prop",
11075
+ appliesTo: "popover",
11076
+ themeValues: {
11077
+ LightTheme: "raised",
11078
+ DarkTheme: "raised"
11079
+ }
11080
+ },
11081
+ {
11082
+ id: "popover.behavior.typeface",
11083
+ value: "label",
11084
+ type: "string",
11085
+ kind: "behavioral",
11086
+ target: "component-prop",
11087
+ appliesTo: "popover",
11088
+ themeValues: {
11089
+ LightTheme: "label",
11090
+ DarkTheme: "label"
11091
+ }
11092
+ },
11093
+ {
11094
+ id: "popover.behavior.padding",
11095
+ value: "6px 12px",
11096
+ type: "string",
11097
+ kind: "behavioral",
11098
+ target: "component-prop",
11099
+ appliesTo: "popover",
11100
+ themeValues: {
11101
+ LightTheme: "6px 12px",
11102
+ DarkTheme: "6px 12px"
11103
+ }
11104
+ },
11105
+ {
11106
+ id: "popover.behavior.maxWidth",
11107
+ value: "38ch",
11108
+ type: "string",
11109
+ kind: "behavioral",
11110
+ target: "component-prop",
11111
+ appliesTo: "popover",
11112
+ themeValues: {
11113
+ LightTheme: "38ch",
11114
+ DarkTheme: "38ch"
11115
+ }
11116
+ },
11117
+ {
11118
+ id: "popover.behavior.offset",
11119
+ value: 7,
11120
+ type: "number",
11121
+ kind: "behavioral",
11122
+ target: "component-prop",
11123
+ appliesTo: "popover",
11124
+ themeValues: {
11125
+ LightTheme: 7,
11126
+ DarkTheme: 7
11127
+ }
11128
+ },
11129
+ {
11130
+ id: "popover.behavior.arrowSize",
11131
+ value: 8,
11132
+ type: "number",
11133
+ kind: "behavioral",
11134
+ target: "component-prop",
11135
+ appliesTo: "popover",
11136
+ themeValues: {
11137
+ LightTheme: 8,
11138
+ DarkTheme: 8
11139
+ }
11140
+ },
11141
+ {
11142
+ id: "popover.behavior.closeSymbol",
11143
+ value: "close",
11144
+ type: "string",
11145
+ kind: "behavioral",
11146
+ target: "component-prop",
11147
+ appliesTo: "popover",
11148
+ themeValues: {
11149
+ LightTheme: "close",
11150
+ DarkTheme: "close"
11151
+ }
11152
+ },
11153
+ {
11154
+ id: "popover.behavior.headerTypeface",
11155
+ value: "title-small",
11156
+ type: "string",
11157
+ kind: "behavioral",
11158
+ target: "component-prop",
11159
+ appliesTo: "popover",
11160
+ themeValues: {
11161
+ LightTheme: "title-small",
11162
+ DarkTheme: "title-small"
11163
+ }
11164
+ },
11165
+ {
11166
+ id: "popover.behavior.tooltipPadding",
11167
+ value: "4px 8px",
11168
+ type: "string",
11169
+ kind: "behavioral",
11170
+ target: "component-prop",
11171
+ appliesTo: "popover",
11172
+ themeValues: {
11173
+ LightTheme: "4px 8px",
11174
+ DarkTheme: "4px 8px"
11175
+ }
11176
+ },
11177
+ {
11178
+ id: "popover.behavior.tooltipOpenDelay",
11179
+ value: 500,
11180
+ type: "number",
11181
+ kind: "behavioral",
11182
+ target: "component-prop",
11183
+ appliesTo: "popover",
11184
+ themeValues: {
11185
+ LightTheme: 500,
11186
+ DarkTheme: 500
9928
11187
  }
9929
11188
  },
9930
11189
  {
9931
- id: "expand.behavior.transitionSpeed",
9932
- value: 0.35,
11190
+ id: "popover.behavior.tooltipCloseDelay",
11191
+ value: 150,
9933
11192
  type: "number",
9934
11193
  kind: "behavioral",
9935
11194
  target: "component-prop",
11195
+ appliesTo: "popover",
11196
+ themeValues: {
11197
+ LightTheme: 150,
11198
+ DarkTheme: 150
11199
+ }
11200
+ },
11201
+ {
11202
+ id: "popover.behavior.motion",
11203
+ value: "panel",
11204
+ type: "string",
11205
+ kind: "behavioral",
11206
+ target: "component-prop",
11207
+ appliesTo: "popover",
11208
+ themeValues: {
11209
+ LightTheme: "panel",
11210
+ DarkTheme: "panel"
11211
+ }
11212
+ },
11213
+ {
11214
+ id: "expand.behavior.motion",
11215
+ value: "reveal",
11216
+ type: "string",
11217
+ kind: "behavioral",
11218
+ target: "component-prop",
9936
11219
  appliesTo: "expand",
9937
11220
  themeValues: {
9938
- LightTheme: 0.35,
9939
- DarkTheme: 0.35
11221
+ LightTheme: "reveal",
11222
+ DarkTheme: "reveal"
9940
11223
  }
9941
11224
  },
9942
11225
  {
@@ -10503,6 +11786,18 @@ placeholder="Name or address\u2026"
10503
11786
  DarkTheme: "xs"
10504
11787
  }
10505
11788
  },
11789
+ {
11790
+ id: "tagInput.behavior.activeColor",
11791
+ value: "primary-container",
11792
+ type: "string",
11793
+ kind: "behavioral",
11794
+ target: "component-prop",
11795
+ appliesTo: "tagInput",
11796
+ themeValues: {
11797
+ LightTheme: "primary-container",
11798
+ DarkTheme: "primary-container"
11799
+ }
11800
+ },
10506
11801
  {
10507
11802
  id: "tagInput.behavior.maxSuggestions",
10508
11803
  value: 8,
@@ -10533,82 +11828,190 @@ placeholder="Name or address\u2026"
10533
11828
  type: "string",
10534
11829
  kind: "behavioral",
10535
11830
  target: "component-prop",
10536
- appliesTo: "calendar",
11831
+ appliesTo: "calendar",
11832
+ themeValues: {
11833
+ LightTheme: "label",
11834
+ DarkTheme: "label"
11835
+ }
11836
+ },
11837
+ {
11838
+ id: "calendar.behavior.gap",
11839
+ value: "xxs",
11840
+ type: "string",
11841
+ kind: "behavioral",
11842
+ target: "component-prop",
11843
+ appliesTo: "calendar",
11844
+ themeValues: {
11845
+ LightTheme: "xxs",
11846
+ DarkTheme: "xxs"
11847
+ }
11848
+ },
11849
+ {
11850
+ id: "calendar.behavior.navPrevSymbol",
11851
+ value: "chevron_left",
11852
+ type: "string",
11853
+ kind: "behavioral",
11854
+ target: "component-prop",
11855
+ appliesTo: "calendar",
11856
+ themeValues: {
11857
+ LightTheme: "chevron_left",
11858
+ DarkTheme: "chevron_left"
11859
+ }
11860
+ },
11861
+ {
11862
+ id: "calendar.behavior.navNextSymbol",
11863
+ value: "chevron_right",
11864
+ type: "string",
11865
+ kind: "behavioral",
11866
+ target: "component-prop",
11867
+ appliesTo: "calendar",
11868
+ themeValues: {
11869
+ LightTheme: "chevron_right",
11870
+ DarkTheme: "chevron_right"
11871
+ }
11872
+ },
11873
+ {
11874
+ id: "calendar.behavior.weekdayFormat",
11875
+ value: "short",
11876
+ type: "string",
11877
+ kind: "behavioral",
11878
+ target: "component-prop",
11879
+ appliesTo: "calendar",
11880
+ themeValues: {
11881
+ LightTheme: "short",
11882
+ DarkTheme: "short"
11883
+ }
11884
+ },
11885
+ {
11886
+ id: "calendar.behavior.showOutsideDays",
11887
+ value: false,
11888
+ type: "boolean",
11889
+ kind: "behavioral",
11890
+ target: "component-prop",
11891
+ appliesTo: "calendar",
11892
+ themeValues: {
11893
+ LightTheme: false,
11894
+ DarkTheme: false
11895
+ }
11896
+ },
11897
+ {
11898
+ id: "calendar.behavior.todayStyle",
11899
+ value: "outline",
11900
+ type: "string",
11901
+ kind: "behavioral",
11902
+ target: "component-prop",
11903
+ appliesTo: "calendar",
11904
+ themeValues: {
11905
+ LightTheme: "outline",
11906
+ DarkTheme: "outline"
11907
+ }
11908
+ },
11909
+ {
11910
+ id: "combobox.behavior.toggleIcon",
11911
+ value: "chevronDown",
11912
+ type: "string",
11913
+ kind: "behavioral",
11914
+ target: "component-prop",
11915
+ appliesTo: "combobox",
11916
+ themeValues: {
11917
+ LightTheme: "chevronDown",
11918
+ DarkTheme: "chevronDown"
11919
+ }
11920
+ },
11921
+ {
11922
+ id: "combobox.behavior.clearIcon",
11923
+ value: "close",
11924
+ type: "string",
11925
+ kind: "behavioral",
11926
+ target: "component-prop",
11927
+ appliesTo: "combobox",
11928
+ themeValues: {
11929
+ LightTheme: "close",
11930
+ DarkTheme: "close"
11931
+ }
11932
+ },
11933
+ {
11934
+ id: "combobox.behavior.selectedIcon",
11935
+ value: "check",
11936
+ type: "string",
11937
+ kind: "behavioral",
11938
+ target: "component-prop",
11939
+ appliesTo: "combobox",
10537
11940
  themeValues: {
10538
- LightTheme: "label",
10539
- DarkTheme: "label"
11941
+ LightTheme: "check",
11942
+ DarkTheme: "check"
10540
11943
  }
10541
11944
  },
10542
11945
  {
10543
- id: "calendar.behavior.gap",
10544
- value: "xxs",
11946
+ id: "combobox.behavior.listColor",
11947
+ value: "primary-surface",
10545
11948
  type: "string",
10546
11949
  kind: "behavioral",
10547
11950
  target: "component-prop",
10548
- appliesTo: "calendar",
11951
+ appliesTo: "combobox",
10549
11952
  themeValues: {
10550
- LightTheme: "xxs",
10551
- DarkTheme: "xxs"
11953
+ LightTheme: "primary-surface",
11954
+ DarkTheme: "primary-surface"
10552
11955
  }
10553
11956
  },
10554
11957
  {
10555
- id: "calendar.behavior.navPrevSymbol",
10556
- value: "chevron_left",
11958
+ id: "combobox.behavior.listShadow",
11959
+ value: "menu",
10557
11960
  type: "string",
10558
11961
  kind: "behavioral",
10559
11962
  target: "component-prop",
10560
- appliesTo: "calendar",
11963
+ appliesTo: "combobox",
10561
11964
  themeValues: {
10562
- LightTheme: "chevron_left",
10563
- DarkTheme: "chevron_left"
11965
+ LightTheme: "menu",
11966
+ DarkTheme: "menu"
10564
11967
  }
10565
11968
  },
10566
11969
  {
10567
- id: "calendar.behavior.navNextSymbol",
10568
- value: "chevron_right",
11970
+ id: "combobox.behavior.listBorderRadius",
11971
+ value: "xs",
10569
11972
  type: "string",
10570
11973
  kind: "behavioral",
10571
11974
  target: "component-prop",
10572
- appliesTo: "calendar",
11975
+ appliesTo: "combobox",
10573
11976
  themeValues: {
10574
- LightTheme: "chevron_right",
10575
- DarkTheme: "chevron_right"
11977
+ LightTheme: "xs",
11978
+ DarkTheme: "xs"
10576
11979
  }
10577
11980
  },
10578
11981
  {
10579
- id: "calendar.behavior.weekdayFormat",
10580
- value: "short",
11982
+ id: "combobox.behavior.activeColor",
11983
+ value: "primary-container",
10581
11984
  type: "string",
10582
11985
  kind: "behavioral",
10583
11986
  target: "component-prop",
10584
- appliesTo: "calendar",
11987
+ appliesTo: "combobox",
10585
11988
  themeValues: {
10586
- LightTheme: "short",
10587
- DarkTheme: "short"
11989
+ LightTheme: "primary-container",
11990
+ DarkTheme: "primary-container"
10588
11991
  }
10589
11992
  },
10590
11993
  {
10591
- id: "calendar.behavior.showOutsideDays",
10592
- value: false,
10593
- type: "boolean",
11994
+ id: "combobox.behavior.maxVisibleOptions",
11995
+ value: 8,
11996
+ type: "number",
10594
11997
  kind: "behavioral",
10595
11998
  target: "component-prop",
10596
- appliesTo: "calendar",
11999
+ appliesTo: "combobox",
10597
12000
  themeValues: {
10598
- LightTheme: false,
10599
- DarkTheme: false
12001
+ LightTheme: 8,
12002
+ DarkTheme: 8
10600
12003
  }
10601
12004
  },
10602
12005
  {
10603
- id: "calendar.behavior.todayStyle",
10604
- value: "outline",
12006
+ id: "combobox.behavior.descriptionColor",
12007
+ value: "on-primary-surface-variant",
10605
12008
  type: "string",
10606
12009
  kind: "behavioral",
10607
12010
  target: "component-prop",
10608
- appliesTo: "calendar",
12011
+ appliesTo: "combobox",
10609
12012
  themeValues: {
10610
- LightTheme: "outline",
10611
- DarkTheme: "outline"
12013
+ LightTheme: "on-primary-surface-variant",
12014
+ DarkTheme: "on-primary-surface-variant"
10612
12015
  }
10613
12016
  },
10614
12017
  {
@@ -10707,6 +12110,18 @@ placeholder="Name or address\u2026"
10707
12110
  DarkTheme: "xs"
10708
12111
  }
10709
12112
  },
12113
+ {
12114
+ id: "timeInput.behavior.activeColor",
12115
+ value: "primary-container",
12116
+ type: "string",
12117
+ kind: "behavioral",
12118
+ target: "component-prop",
12119
+ appliesTo: "timeInput",
12120
+ themeValues: {
12121
+ LightTheme: "primary-container",
12122
+ DarkTheme: "primary-container"
12123
+ }
12124
+ },
10710
12125
  {
10711
12126
  id: "timeInput.behavior.maxVisibleOptions",
10712
12127
  value: 7,
@@ -11439,6 +12854,30 @@ placeholder="Name or address\u2026"
11439
12854
  DarkTheme: 1.4
11440
12855
  }
11441
12856
  },
12857
+ {
12858
+ id: "skeleton.behavior.direction",
12859
+ value: "ltr",
12860
+ type: "string",
12861
+ kind: "behavioral",
12862
+ target: "component-prop",
12863
+ appliesTo: "skeleton",
12864
+ themeValues: {
12865
+ LightTheme: "ltr",
12866
+ DarkTheme: "ltr"
12867
+ }
12868
+ },
12869
+ {
12870
+ id: "skeleton.behavior.highlightWidth",
12871
+ value: 40,
12872
+ type: "number",
12873
+ kind: "behavioral",
12874
+ target: "component-prop",
12875
+ appliesTo: "skeleton",
12876
+ themeValues: {
12877
+ LightTheme: 40,
12878
+ DarkTheme: 40
12879
+ }
12880
+ },
11442
12881
  {
11443
12882
  id: "skeleton.behavior.gap",
11444
12883
  value: "sm",
@@ -11464,15 +12903,15 @@ placeholder="Name or address\u2026"
11464
12903
  }
11465
12904
  },
11466
12905
  {
11467
- id: "snackbar.behavior.transitionDelay",
11468
- value: "0.35s",
12906
+ id: "snackbar.behavior.motion",
12907
+ value: "notification",
11469
12908
  type: "string",
11470
12909
  kind: "behavioral",
11471
12910
  target: "component-prop",
11472
12911
  appliesTo: "snackbar",
11473
12912
  themeValues: {
11474
- LightTheme: "0.35s",
11475
- DarkTheme: "0.35s"
12913
+ LightTheme: "notification",
12914
+ DarkTheme: "notification"
11476
12915
  }
11477
12916
  },
11478
12917
  {
@@ -11618,6 +13057,210 @@ placeholder="Name or address\u2026"
11618
13057
  LightTheme: "label",
11619
13058
  DarkTheme: "label"
11620
13059
  }
13060
+ },
13061
+ {
13062
+ id: "callout.behavior.color",
13063
+ value: "primary-surface",
13064
+ type: "string",
13065
+ kind: "behavioral",
13066
+ target: "component-prop",
13067
+ appliesTo: "callout",
13068
+ themeValues: {
13069
+ LightTheme: "primary-surface",
13070
+ DarkTheme: "primary-surface"
13071
+ }
13072
+ },
13073
+ {
13074
+ id: "callout.behavior.borderRadius",
13075
+ value: "xs",
13076
+ type: "string",
13077
+ kind: "behavioral",
13078
+ target: "component-prop",
13079
+ appliesTo: "callout",
13080
+ themeValues: {
13081
+ LightTheme: "xs",
13082
+ DarkTheme: "xs"
13083
+ }
13084
+ },
13085
+ {
13086
+ id: "callout.behavior.shadow",
13087
+ value: "menu",
13088
+ type: "string",
13089
+ kind: "behavioral",
13090
+ target: "component-prop",
13091
+ appliesTo: "callout",
13092
+ themeValues: {
13093
+ LightTheme: "menu",
13094
+ DarkTheme: "menu"
13095
+ }
13096
+ },
13097
+ {
13098
+ id: "callout.behavior.width",
13099
+ value: "320px",
13100
+ type: "string",
13101
+ kind: "behavioral",
13102
+ target: "component-prop",
13103
+ appliesTo: "callout",
13104
+ themeValues: {
13105
+ LightTheme: "320px",
13106
+ DarkTheme: "320px"
13107
+ }
13108
+ },
13109
+ {
13110
+ id: "callout.behavior.padding",
13111
+ value: "16px",
13112
+ type: "string",
13113
+ kind: "behavioral",
13114
+ target: "component-prop",
13115
+ appliesTo: "callout",
13116
+ themeValues: {
13117
+ LightTheme: "16px",
13118
+ DarkTheme: "16px"
13119
+ }
13120
+ },
13121
+ {
13122
+ id: "callout.behavior.headerTypeface",
13123
+ value: "title-small",
13124
+ type: "string",
13125
+ kind: "behavioral",
13126
+ target: "component-prop",
13127
+ appliesTo: "callout",
13128
+ themeValues: {
13129
+ LightTheme: "title-small",
13130
+ DarkTheme: "title-small"
13131
+ }
13132
+ },
13133
+ {
13134
+ id: "callout.behavior.typeface",
13135
+ value: "label",
13136
+ type: "string",
13137
+ kind: "behavioral",
13138
+ target: "component-prop",
13139
+ appliesTo: "callout",
13140
+ themeValues: {
13141
+ LightTheme: "label",
13142
+ DarkTheme: "label"
13143
+ }
13144
+ },
13145
+ {
13146
+ id: "callout.behavior.closeSymbol",
13147
+ value: "close",
13148
+ type: "string",
13149
+ kind: "behavioral",
13150
+ target: "component-prop",
13151
+ appliesTo: "callout",
13152
+ themeValues: {
13153
+ LightTheme: "close",
13154
+ DarkTheme: "close"
13155
+ }
13156
+ },
13157
+ {
13158
+ id: "callout.behavior.arrowSize",
13159
+ value: 8,
13160
+ type: "number",
13161
+ kind: "behavioral",
13162
+ target: "component-prop",
13163
+ appliesTo: "callout",
13164
+ themeValues: {
13165
+ LightTheme: 8,
13166
+ DarkTheme: 8
13167
+ }
13168
+ },
13169
+ {
13170
+ id: "callout.behavior.offset",
13171
+ value: 12,
13172
+ type: "number",
13173
+ kind: "behavioral",
13174
+ target: "component-prop",
13175
+ appliesTo: "callout",
13176
+ themeValues: {
13177
+ LightTheme: 12,
13178
+ DarkTheme: 12
13179
+ }
13180
+ },
13181
+ {
13182
+ id: "callout.behavior.scrimColor",
13183
+ value: "rgba(0, 0, 0, 0.45)",
13184
+ type: "string",
13185
+ kind: "behavioral",
13186
+ target: "component-prop",
13187
+ appliesTo: "callout",
13188
+ themeValues: {
13189
+ LightTheme: "rgba(0, 0, 0, 0.45)",
13190
+ DarkTheme: "rgba(0, 0, 0, 0.45)"
13191
+ }
13192
+ },
13193
+ {
13194
+ id: "callout.behavior.spotlightPadding",
13195
+ value: 6,
13196
+ type: "number",
13197
+ kind: "behavioral",
13198
+ target: "component-prop",
13199
+ appliesTo: "callout",
13200
+ themeValues: {
13201
+ LightTheme: 6,
13202
+ DarkTheme: 6
13203
+ }
13204
+ },
13205
+ {
13206
+ id: "callout.behavior.spotlightRadius",
13207
+ value: "xs",
13208
+ type: "string",
13209
+ kind: "behavioral",
13210
+ target: "component-prop",
13211
+ appliesTo: "callout",
13212
+ themeValues: {
13213
+ LightTheme: "xs",
13214
+ DarkTheme: "xs"
13215
+ }
13216
+ },
13217
+ {
13218
+ id: "callout.behavior.ringWidth",
13219
+ value: 2,
13220
+ type: "number",
13221
+ kind: "behavioral",
13222
+ target: "component-prop",
13223
+ appliesTo: "callout",
13224
+ themeValues: {
13225
+ LightTheme: 2,
13226
+ DarkTheme: 2
13227
+ }
13228
+ },
13229
+ {
13230
+ id: "callout.behavior.motion",
13231
+ value: "panel",
13232
+ type: "string",
13233
+ kind: "behavioral",
13234
+ target: "component-prop",
13235
+ appliesTo: "callout",
13236
+ themeValues: {
13237
+ LightTheme: "panel",
13238
+ DarkTheme: "panel"
13239
+ }
13240
+ },
13241
+ {
13242
+ id: "tour.behavior.progressStyle",
13243
+ value: "dots",
13244
+ type: "string",
13245
+ kind: "behavioral",
13246
+ target: "component-prop",
13247
+ appliesTo: "tour",
13248
+ themeValues: {
13249
+ LightTheme: "dots",
13250
+ DarkTheme: "dots"
13251
+ }
13252
+ },
13253
+ {
13254
+ id: "tour.behavior.footerGap",
13255
+ value: "sm",
13256
+ type: "string",
13257
+ kind: "behavioral",
13258
+ target: "component-prop",
13259
+ appliesTo: "tour",
13260
+ themeValues: {
13261
+ LightTheme: "sm",
13262
+ DarkTheme: "sm"
13263
+ }
11621
13264
  }
11622
13265
  ],
11623
13266
  themes: [
@@ -11716,6 +13359,7 @@ placeholder="Name or address\u2026"
11716
13359
  "spacing.md": "16px",
11717
13360
  "spacing.lg": "32px",
11718
13361
  "spacing.xl": "64px",
13362
+ "spacing.xxl": "128px",
11719
13363
  "border.primary": "1px solid #6A6F8F",
11720
13364
  "border.secondary": "1px solid #8C685D",
11721
13365
  "border.tertiary": "1px solid #597B66",
@@ -11763,7 +13407,7 @@ placeholder="Name or address\u2026"
11763
13407
  alert: {
11764
13408
  topPosition: 40,
11765
13409
  borderRadius: "sm",
11766
- transitionSpeed: 0.35,
13410
+ motion: "notification",
11767
13411
  elevation: "md"
11768
13412
  },
11769
13413
  breadcrumb: {
@@ -11805,6 +13449,7 @@ placeholder="Name or address\u2026"
11805
13449
  listColor: "primary-surface",
11806
13450
  listShadow: "menu",
11807
13451
  listBorderRadius: "xs",
13452
+ activeColor: "primary-container",
11808
13453
  maxSuggestions: 8
11809
13454
  },
11810
13455
  checkbox: {
@@ -11817,7 +13462,7 @@ placeholder="Name or address\u2026"
11817
13462
  size: 20,
11818
13463
  ringColor: "outline",
11819
13464
  fillColor: "surface",
11820
- transitionSpeed: 0.3
13465
+ motion: "control"
11821
13466
  },
11822
13467
  dialog: {
11823
13468
  borderRadius: "lg",
@@ -11851,7 +13496,8 @@ placeholder="Name or address\u2026"
11851
13496
  border: "none",
11852
13497
  borderRadius: "xxs",
11853
13498
  color: "primary-surface",
11854
- shadow: "menu"
13499
+ shadow: "menu",
13500
+ motion: "popup"
11855
13501
  },
11856
13502
  menu: {
11857
13503
  minWidth: 184,
@@ -11868,10 +13514,27 @@ placeholder="Name or address\u2026"
11868
13514
  typeface: "label",
11869
13515
  hoverColor: "primary-container",
11870
13516
  activeSymbol: "check",
11871
- transitionSpeed: 0.35
13517
+ motion: "control"
13518
+ },
13519
+ popover: {
13520
+ color: "primary-surface",
13521
+ border: "quaternary",
13522
+ borderRadius: "xs",
13523
+ shadow: "raised",
13524
+ typeface: "label",
13525
+ padding: "6px 12px",
13526
+ maxWidth: "38ch",
13527
+ offset: 7,
13528
+ arrowSize: 8,
13529
+ closeSymbol: "close",
13530
+ headerTypeface: "title-small",
13531
+ tooltipPadding: "4px 8px",
13532
+ tooltipOpenDelay: 500,
13533
+ tooltipCloseDelay: 150,
13534
+ motion: "panel"
11872
13535
  },
11873
13536
  expand: {
11874
- transitionSpeed: 0.35
13537
+ motion: "reveal"
11875
13538
  },
11876
13539
  footer: {
11877
13540
  height: 52,
@@ -11935,6 +13598,7 @@ placeholder="Name or address\u2026"
11935
13598
  listColor: "primary-surface",
11936
13599
  listShadow: "menu",
11937
13600
  listBorderRadius: "xs",
13601
+ activeColor: "primary-container",
11938
13602
  maxSuggestions: 8
11939
13603
  },
11940
13604
  calendar: {
@@ -11947,6 +13611,17 @@ placeholder="Name or address\u2026"
11947
13611
  showOutsideDays: false,
11948
13612
  todayStyle: "outline"
11949
13613
  },
13614
+ combobox: {
13615
+ toggleIcon: "chevronDown",
13616
+ clearIcon: "close",
13617
+ selectedIcon: "check",
13618
+ listColor: "primary-surface",
13619
+ listShadow: "menu",
13620
+ listBorderRadius: "xs",
13621
+ activeColor: "primary-container",
13622
+ maxVisibleOptions: 8,
13623
+ descriptionColor: "on-primary-surface-variant"
13624
+ },
11950
13625
  dateInput: {
11951
13626
  toggleSymbol: "calendar_month",
11952
13627
  popupShadow: "menu",
@@ -11958,6 +13633,7 @@ placeholder="Name or address\u2026"
11958
13633
  listColor: "primary-surface",
11959
13634
  listShadow: "menu",
11960
13635
  listBorderRadius: "xs",
13636
+ activeColor: "primary-container",
11961
13637
  maxVisibleOptions: 7
11962
13638
  },
11963
13639
  dateTimeInput: {
@@ -12041,11 +13717,13 @@ placeholder="Name or address\u2026"
12041
13717
  borderRadius: "xs",
12042
13718
  animation: "shimmer",
12043
13719
  duration: 1.4,
13720
+ direction: "ltr",
13721
+ highlightWidth: 40,
12044
13722
  gap: "sm"
12045
13723
  },
12046
13724
  snackbar: {
12047
13725
  bottomPosition: 40,
12048
- transitionDelay: "0.35s",
13726
+ motion: "notification",
12049
13727
  autoCloseDelay: 35e3
12050
13728
  },
12051
13729
  symbol: {
@@ -12064,6 +13742,27 @@ placeholder="Name or address\u2026"
12064
13742
  shadow: "raised",
12065
13743
  color: "inverse-surface",
12066
13744
  typeface: "label"
13745
+ },
13746
+ callout: {
13747
+ color: "primary-surface",
13748
+ borderRadius: "xs",
13749
+ shadow: "menu",
13750
+ width: "320px",
13751
+ padding: "16px",
13752
+ headerTypeface: "title-small",
13753
+ typeface: "label",
13754
+ closeSymbol: "close",
13755
+ arrowSize: 8,
13756
+ offset: 12,
13757
+ scrimColor: "rgba(0, 0, 0, 0.45)",
13758
+ spotlightPadding: 6,
13759
+ spotlightRadius: "xs",
13760
+ ringWidth: 2,
13761
+ motion: "panel"
13762
+ },
13763
+ tour: {
13764
+ progressStyle: "dots",
13765
+ footerGap: "sm"
12067
13766
  }
12068
13767
  },
12069
13768
  usage: "Apply style overrides through the Emotion theme provider (the `UniTheme` object), and pass component options as component inputs/props. Import the theme from `@uni-design-system/uni-core` (`LightTheme`)."
@@ -12163,6 +13862,7 @@ placeholder="Name or address\u2026"
12163
13862
  "spacing.md": "16px",
12164
13863
  "spacing.lg": "32px",
12165
13864
  "spacing.xl": "64px",
13865
+ "spacing.xxl": "128px",
12166
13866
  "border.primary": "1px solid #AFB5D8",
12167
13867
  "border.secondary": "1px solid #D5ADA1",
12168
13868
  "border.tertiary": "1px solid #9EC2AB",
@@ -12210,7 +13910,7 @@ placeholder="Name or address\u2026"
12210
13910
  alert: {
12211
13911
  topPosition: 40,
12212
13912
  borderRadius: "sm",
12213
- transitionSpeed: 0.35,
13913
+ motion: "notification",
12214
13914
  elevation: "md"
12215
13915
  },
12216
13916
  breadcrumb: {
@@ -12252,6 +13952,7 @@ placeholder="Name or address\u2026"
12252
13952
  listColor: "primary-surface",
12253
13953
  listShadow: "menu",
12254
13954
  listBorderRadius: "xs",
13955
+ activeColor: "primary-container",
12255
13956
  maxSuggestions: 8
12256
13957
  },
12257
13958
  checkbox: {
@@ -12264,7 +13965,7 @@ placeholder="Name or address\u2026"
12264
13965
  size: 20,
12265
13966
  ringColor: "outline",
12266
13967
  fillColor: "surface",
12267
- transitionSpeed: 0.3
13968
+ motion: "control"
12268
13969
  },
12269
13970
  dialog: {
12270
13971
  borderRadius: "lg",
@@ -12298,7 +13999,8 @@ placeholder="Name or address\u2026"
12298
13999
  border: "none",
12299
14000
  borderRadius: "xxs",
12300
14001
  color: "primary-surface",
12301
- shadow: "menu"
14002
+ shadow: "menu",
14003
+ motion: "popup"
12302
14004
  },
12303
14005
  menu: {
12304
14006
  minWidth: 184,
@@ -12315,10 +14017,27 @@ placeholder="Name or address\u2026"
12315
14017
  typeface: "label",
12316
14018
  hoverColor: "primary-container",
12317
14019
  activeSymbol: "check",
12318
- transitionSpeed: 0.35
14020
+ motion: "control"
14021
+ },
14022
+ popover: {
14023
+ color: "primary-surface",
14024
+ border: "quaternary",
14025
+ borderRadius: "xs",
14026
+ shadow: "raised",
14027
+ typeface: "label",
14028
+ padding: "6px 12px",
14029
+ maxWidth: "38ch",
14030
+ offset: 7,
14031
+ arrowSize: 8,
14032
+ closeSymbol: "close",
14033
+ headerTypeface: "title-small",
14034
+ tooltipPadding: "4px 8px",
14035
+ tooltipOpenDelay: 500,
14036
+ tooltipCloseDelay: 150,
14037
+ motion: "panel"
12319
14038
  },
12320
14039
  expand: {
12321
- transitionSpeed: 0.35
14040
+ motion: "reveal"
12322
14041
  },
12323
14042
  footer: {
12324
14043
  height: 52,
@@ -12382,6 +14101,7 @@ placeholder="Name or address\u2026"
12382
14101
  listColor: "primary-surface",
12383
14102
  listShadow: "menu",
12384
14103
  listBorderRadius: "xs",
14104
+ activeColor: "primary-container",
12385
14105
  maxSuggestions: 8
12386
14106
  },
12387
14107
  calendar: {
@@ -12394,6 +14114,17 @@ placeholder="Name or address\u2026"
12394
14114
  showOutsideDays: false,
12395
14115
  todayStyle: "outline"
12396
14116
  },
14117
+ combobox: {
14118
+ toggleIcon: "chevronDown",
14119
+ clearIcon: "close",
14120
+ selectedIcon: "check",
14121
+ listColor: "primary-surface",
14122
+ listShadow: "menu",
14123
+ listBorderRadius: "xs",
14124
+ activeColor: "primary-container",
14125
+ maxVisibleOptions: 8,
14126
+ descriptionColor: "on-primary-surface-variant"
14127
+ },
12397
14128
  dateInput: {
12398
14129
  toggleSymbol: "calendar_month",
12399
14130
  popupShadow: "menu",
@@ -12405,6 +14136,7 @@ placeholder="Name or address\u2026"
12405
14136
  listColor: "primary-surface",
12406
14137
  listShadow: "menu",
12407
14138
  listBorderRadius: "xs",
14139
+ activeColor: "primary-container",
12408
14140
  maxVisibleOptions: 7
12409
14141
  },
12410
14142
  dateTimeInput: {
@@ -12488,11 +14220,13 @@ placeholder="Name or address\u2026"
12488
14220
  borderRadius: "xs",
12489
14221
  animation: "shimmer",
12490
14222
  duration: 1.4,
14223
+ direction: "ltr",
14224
+ highlightWidth: 40,
12491
14225
  gap: "sm"
12492
14226
  },
12493
14227
  snackbar: {
12494
14228
  bottomPosition: 40,
12495
- transitionDelay: "0.35s",
14229
+ motion: "notification",
12496
14230
  autoCloseDelay: 35e3
12497
14231
  },
12498
14232
  symbol: {
@@ -12511,6 +14245,27 @@ placeholder="Name or address\u2026"
12511
14245
  shadow: "raised",
12512
14246
  color: "inverse-surface",
12513
14247
  typeface: "label"
14248
+ },
14249
+ callout: {
14250
+ color: "primary-surface",
14251
+ borderRadius: "xs",
14252
+ shadow: "menu",
14253
+ width: "320px",
14254
+ padding: "16px",
14255
+ headerTypeface: "title-small",
14256
+ typeface: "label",
14257
+ closeSymbol: "close",
14258
+ arrowSize: 8,
14259
+ offset: 12,
14260
+ scrimColor: "rgba(0, 0, 0, 0.45)",
14261
+ spotlightPadding: 6,
14262
+ spotlightRadius: "xs",
14263
+ ringWidth: 2,
14264
+ motion: "panel"
14265
+ },
14266
+ tour: {
14267
+ progressStyle: "dots",
14268
+ footerGap: "sm"
12514
14269
  }
12515
14270
  },
12516
14271
  usage: "Apply style overrides through the Emotion theme provider (the `UniTheme` object), and pass component options as component inputs/props. Import the theme from `@uni-design-system/uni-core` (`DarkTheme`)."
@@ -12520,6 +14275,152 @@ placeholder="Name or address\u2026"
12520
14275
  {
12521
14276
  package: "@uni-design-system/uni-angular",
12522
14277
  releases: [
14278
+ {
14279
+ version: "9.0.0",
14280
+ entries: [
14281
+ {
14282
+ bump: "major",
14283
+ title: "Box learns `flex` / `shrink` / `basis` and `marginInline`.",
14284
+ body: '**`flex`.** `grow` emits `flex-grow` alone, which leaves `flex-basis: auto` \u2014 so\nit cannot express `flex: 1`, and any layout wanting siblings to share space\nevenly regardless of content width had to stay in CSS. `[flex]="1"` now emits\nthe shorthand; `shrink` and `basis` cover the rest. `grow` is unchanged, so no\nexisting layout moves.\n\nThese three go through a new `ThemeService.styleIfSet()`, which treats only\n`undefined` as unset \u2014 the shared `style()` helper drops falsy values, which\nwould have silently swallowed `[shrink]="0"`, the single most useful value.\n\n**`marginInline`.** `margin: 0 auto` on a max-width container had no Box\nequivalent, so page shells kept an inline style for it. `marginInline="auto"`\ncenters such a container, and a spacing token works too.\n\n```html\n<main box-layout maxWidth="1200px" marginInline="auto" padding="lg">\u2026</main>\n```\n\nOnly the inline axis is exposed. Block margins collapse and fight `gap`, which\nis why the primitives carry no margin otherwise \u2014 inline margins do neither, so\nthis is a deliberate line rather than a crack in the token-only surface.',
14285
+ commit: "c0c6056"
14286
+ },
14287
+ {
14288
+ bump: "major",
14289
+ title: "Every deprecated API is removed. The library now carries no `@deprecated`",
14290
+ body: "symbols at all.\n\n**Per-component duration options \u2192 the `motion` scale.** Six components carried\ntheir own duration knob that predated the motion scale and _won over_ it:\n`expand.transitionSpeed`, `callout.transitionMs`, `radio.transitionSpeed`,\n`menuItem.transitionSpeed`, `alert.transitionSpeed` and\n`snackbar.transitionDelay`. All are gone, along with the precedence branch each\none required \u2014 timing now comes from the token, full stop.\n\nRetime the token instead; one edit covers every component pointing at it. To\nretime a single component, define a token of your own and point that\ncomponent's `motion` option at it:\n\n```ts\ncreateTheme({\n \u2026,\n motion: { productive: { duration: 110, easing: 'ease' } },\n components: { menuItem: { options: { motion: 'productive' } } },\n});\n```\n\nA `duration: 0` token is how a theme opts out of motion \u2014 that is what\n`transitionSpeed: 0` used to mean. Both showcase themes are migrated this way\n(Carbon to a 110ms `productive` token, Wellsourced to an `instant` one).\n\n**Options that never did anything.** `card.transitionSpeed` and\n`inputBox.transitionSpeed` were read by nothing and never had been. Delete them\nfrom your theme; nothing replaces them.\n\n**Renames and obsolete APIs**\n- `inputBox.typeFace` \u2192 `typeface` (the casing every other component uses).\n- `uni-tooltip`'s `appendToBody` input \u2014 inert since the tooltip moved to the\n native top layer, which escapes any overflow context by itself.\n- Box's `elevation` input \u2192 `shadow`, in both the Angular and React packages.\n It was a second name for the same thing.\n- The Angular `icons` re-export \u2192 import `BaseIcons` from\n `@uni-design-system/uni-core`. The default set ships with every theme.\n\n**The HSL color legacy is gone from uni-core.** `uniColor`, `randomRangeValue`,\n`CategorySaturation` and `CategoryLightness` are removed, superseded by the\ndeterministic OKLCH engine (`generateThemes` / `generatePalette`) \u2014 same input,\nsame theme, WCAG-checked. `RoleHues` and the `UniColor` type go with them: they\nwere reachable only through `uniColor`, and `RoleHues` had gone stale enough to\nhold saturation values in a table of hues.\n\n**Deferred output renames.** Three outputs were held back because renaming is\nbreaking; this is that release. Each also drops an eslint escape it needed for\nshadowing a native event name or using an `on` prefix.\n\n| Component | Before | After |\n| -------------------- | ----------------- | ---------------- |\n| `uni-debounce-input` | `(change)` | `(valueChange)` |\n| `uni-search-input` | `(change)` | `(searchChange)` |\n| `uni-search-input` | `(search)` | `(searchSubmit)` |\n| `dragAndDrop` | `(onFileDropped)` | `(fileDropped)` |\n\n**`uni-dropdown`'s `color` input \u2192 `containerColor`,** completing the rule the\nlayout directives set: every container-pair input in the library is now\n`containerColor`, and plain `color` always means the CSS property.\n\n**`ThemeService.getSpacing('none')` now returns `0`, not the string `'none'`.**\n`'none'` is not a valid length, so it was silently dropped wherever it landed \u2014\n`uni-menu` carried a comment working around exactly that, which is now deleted.",
14291
+ commit: "8250162"
14292
+ },
14293
+ {
14294
+ bump: "major",
14295
+ title: "`uni-input` gets a `type`, and the input chrome stops needing a wrapper div.",
14296
+ body: "**Types.** `uni-input` was text-only with no `type` at all, so every email, URL,\nnumber and phone field had to fall back to `uni-input-box` plus a hand-written\nnative `<input>`, and `type=\"password\"` could not go through it. It now takes\nthe text-like types: `text` (default), `email`, `password`, `search`, `tel`,\n`url`, `number`.\n\nNon-text types (`checkbox`, `radio`, `file`, `range`, `color`) stay out \u2014 they\nbreak both the input chrome and the `FormValueControl<string>` value contract \u2014\nas do `date` / `time` / `datetime-local`, which have dedicated components.\n\n**Native passthroughs.** `autocomplete`, `inputMode`, `list` (a `<datalist>` id),\n`step` and `spellcheck` are plain passthroughs; an unset one emits no attribute.\n`readonly`, `name`, `min`, `max`, `minLength`, `maxLength` and `pattern` are\nSignal Forms' own optional control inputs, so the `[field]` directive syncs them\nfrom your validators exactly as it already syncs `required` \u2014 and they are\nreflected onto the native element so the browser contributes too. Signal Forms\ntreats multiple `pattern`s as all-must-match, which the native attribute cannot\nexpress, so it is reflected only when there is exactly one.\n\n`uni-textarea` gains `readonly`, `name`, `minLength`, `maxLength`, `autocomplete`\nand `spellcheck`; `uni-debounce-input` gains `type`, `autocomplete` and\n`inputMode`.\n\n**Sizing.** `uni-input-box`'s host is `display: contents`, so a width or layout\nattribute set on the element itself was silently dropped and every call site\nneeded a wrapper `<div>`. It now takes `width`, `fullWidth` and `grow` (joining\n`minWidth`), which reach the real box inside; `uni-input`, `uni-textarea` and\n`uni-select` forward all four. The `display: contents` behavior is now documented\ntoo \u2014 it stays surprising even once sizing works.\n\nBoth `uni-input` and `uni-debounce-input` now accept the adornment slots as\neither element or attribute selectors (`<span pre-input>` as well as\n`<pre-input>`), which had drifted apart between them.",
14297
+ commit: "c0c6056"
14298
+ },
14299
+ {
14300
+ bump: "major",
14301
+ title: "The layout primitives and `uni-text` are now **directives**, so they compose.",
14302
+ body: 'They were components with attribute-only selectors, which meant any two of them\non one element threw NG0300 ("multiple components match"). `<div row-layout\nso it reached production as a silent style mismatch. `<uni-card box-layout>`\nwas blocked for the same reason, and `box.component.ts` documented the\nwrap-it-in-a-div workaround as permanent.\n\nAll eight are pure host-styling wrappers (an `<ng-content>`-only template plus a\n`[class]` host binding), so as directives they render identically and now stack\nfreely \u2014 with each other, with `uni-text`, and with a component\'s own host\nelement. Angular reconciles the host `class` bindings additively, so each\ncontributor\'s styles survive rather than one silently winning; there is a spec\npinning that.\n\n```html\n<div row-layout uni-text="title-small" padding="md">Heading</div>\n<uni-card box-layout padding="lg">\u2026</uni-card>\n```\n\n**BREAKING: class renames.** `UniBoxComponent` \u2192 `UniBoxDirective`, and likewise\nfor Row, Stack, Center, Wrap, Grid, GridArea and Text. No compatibility aliases:\na major is where the break belongs, and an alias shipped on day one of a major\ntends to survive to the next one. Rename the symbols in your `imports: []`.\n\n**BREAKING: the layout directives\' `color` is now `containerColor`.**\n\nComposing the two directives exposed a name collision. `color` was an input on\nboth \u2014 a _container pair_ on the layout primitives, the CSS `color` property on\n`uni-text` \u2014 so on a shared element one binding fed both: the box painted the\nsurface, the text took the same token, and the text rendered as ink on identical\nink. A deprecated alias would have kept that path alive, so there isn\'t one.\n\n`color` belongs to `uni-text`, which maps it straight to the CSS property. The\ncontainer pair is an invented concept and now says so:\n\n```html\n<!-- before -->\n<div box-layout color="surface">\n <!-- after -->\n <div box-layout containerColor="surface"></div>\n</div>\n```\n\nThis applies to all seven layout directives (Box and its subclasses) and to\n`uni-scroll-area`, which is attribute-selected too and carried the identical\nhazard. `backgroundColor`, which sets only the background and no paired\non-color, is unchanged, as is `color` on `uni-icon` / `uni-skeleton` /\n`uni-badge` \u2014 there it already means a foreground color, the same sense as\n`uni-text`\'s.\n\nCodemod: rename `color` \u2192 `containerColor` on any element carrying a `*-layout`\nor `scroll-area` attribute; leave `color` alone everywhere else.\n\nThe rename fixed the input collision; a second one sat underneath it in CSS.\n`containerColor` emits a background **and** its paired on-color, so both\ndirectives write `color` to the element \u2014 at equal specificity, which left the\ncascade to Emotion\'s insertion order (text won on `row-layout`, lost on\n`scroll-area`). An explicit `uni-text` `color` is now emitted at doubled\nspecificity, so it deterministically wins; with no explicit color, the\ncontainer\'s on-color still shows through as intended.\n\n`uni-dropdown` still names its container pair `color`. It is an element selector\n(`<uni-dropdown>`), so the collision needs someone to put `uni-text` on a\ncomponent host \u2014 possible, but not the natural path the layout attributes are.\n\n**New: `UNI_LAYOUT` and `UNI_FORMS`.** These are attribute selectors, so an\nelement carrying one whose directive was never imported compiles cleanly and\nsilently does nothing. Spreading a family is the cheapest guard:\n\n```ts\nimports: [...UNI_LAYOUT];\n```',
14303
+ commit: "c0c6056"
14304
+ },
14305
+ {
14306
+ bump: "major",
14307
+ title: "The spacing scale is open, and `createTheme` finally accepts one.",
14308
+ body: 'The scale was a closed seven-name union on a doubling curve (2/4/8/16/32/64px).\nReal layouts are rarely built exclusively on one \u2014 the gaps between 8 and 16,\nand 16 and 32, are where a lot of real spacing lives \u2014 and there was no way to\nadd a step, because **`ThemeConfig` had no `spacing` field at all**:\n`createTheme` hardcoded the base scale. The Wellsourced showcase theme had to\nbolt its scale on after the fact with a post-hoc spread.\n\nThree changes, which only work together:\n- `NullableSize` gains a `(string & {})` arm, so any name the theme defines is a\n valid `padding` / `gap` / `marginInline` value while the seven named steps keep\n their autocomplete. `Size` itself stays closed \u2014 it also types _component_\n sizes, where an arbitrary name has nothing to resolve against.\n- `Spacing` is spelled out as named-optional-keys plus an index signature\n (mirroring `Typography`), rather than a `Partial<Record<\u2026>>` that would\n collapse to a plain string record and lose the named steps.\n- `createTheme({ spacing })` merges over the base scale.\n\n```ts\ncreateTheme({ id, name, colors, spacing: { tight: \'6px\', snug: \'10px\' } });\n```\n\n```html\n<div stack-layout padding="tight" gap="snug">\u2026</div>\n```\n\nBecause the scale is open, a mistyped token can no longer be a compile error. It\nis dropped \u2014 an `undefined` CSS value simply does not render \u2014 and\n`ThemeService` now warns once per unknown token in development, naming the\ntokens the active theme does define. Scaffolded `uni-theme.ts` files carry a\n`spacing` block so the static theme file stays the editable source of truth.\n\n**Behavior change:** `xxl` was in the `Size` union but defined by no base theme,\nso `padding="xxl"` type-checked and rendered nothing. It is now `128px`,\ncompleting the doubling \u2014 any element relying on the silent drop will start\nshowing spacing.',
14309
+ commit: "c0c6056"
14310
+ }
14311
+ ],
14312
+ dependencyBumps: [
14313
+ "@uni-design-system/uni-core@9.0.0"
14314
+ ]
14315
+ },
14316
+ {
14317
+ version: "8.4.0",
14318
+ entries: [
14319
+ {
14320
+ bump: "minor",
14321
+ title: "`uni-callout` and `uni-expand` now read their timing from the theme's `motion`",
14322
+ body: "scale, so every animated surface in the library is retimed from one place.\nThey were the last two carrying their own motion options \u2014 in different units,\nunder different names (`transitionMs` in milliseconds, `transitionSpeed` in\nseconds).\n\nA third token joins `popup` and `panel`:\n\n| Token | Default | Used by |\n| -------- | ----------------- | --------------------- |\n| `reveal` | 350ms ease-in-out | expand, expand-toggle |\n\n`reveal` is a _base_ speed, not a final duration: `uni-expand` still scales it\nby content height (\u221A-of-height, clamped) so short regions stay snappy and tall\nones aren't rushed, and its easing now drives the reveal curve, which was\nhardcoded. `uni-expand-toggle` resolves the token the same way, so the chevron\nand the region cannot drift apart. `uni-callout` maps onto `panel`, whose\n250ms matches what it already used.\n\n**Not breaking.** `transitionMs` and `transitionSpeed` are deprecated but\nstill honoured, and deliberately outrank `motion` \u2014 a theme that set either\nkeeps precisely its current timing rather than being retimed underneath it.\nThey are removed next major. Per-instance inputs, like `uni-expand`'s\n`transitionSpeed`, still outrank everything.\n\nNothing moves differently by default: callout renders 0.25s ease and expand\n0.35s ease-in-out exactly as before, verified against the rendered styles.",
14323
+ commit: "1aca747"
14324
+ },
14325
+ {
14326
+ bump: "minor",
14327
+ title: "New `createAnnouncer()` in the CDK's a11y helpers: the polite live region a",
14328
+ body: 'form control uses for its running commentary \u2014 commits, clears, refused\nentries, result counts \u2014 changes a sighted user sees but that are otherwise\nsilent to a screen reader.\n\n`uni-combobox`, `uni-tag-input`, `uni-time-input`, `uni-date-input`,\n`uni-calendar` and `uni-tour` now share it instead of carrying byte-identical\ncopies. The helper holds no DOM and no styling: the `role="status"` element\nstays in each component\'s own template, where its placement and\nvisually-hidden class already belong.\n\nThis fixes a real bug in `uni-tour`, which had a plain signal rather than a\ncopy of the shared idiom. Assistive tech reads a live region when its content\n_changes_, so writing the identical string is a no-op \u2014 its "Next available"\ngate message was announced on the first step that used it and silently dropped\non every later one. `createAnnouncer` breaks the equality with a trailing\nspace, inaudible to a screen reader, alternating between the two forms so\nnothing accumulates.\n\nConsuming the helper directly:\n\n```ts\nprotected readonly announcer = createAnnouncer();\n// this.announcer.announce(\'Alabama selected.\');\n```\n\n```html\n<span role="status" aria-live="polite" [class]="srOnly"> {{ announcer.message() }} </span>\n```\n\nThe region must already be in the DOM when the component renders \u2014 one added\nat the moment it gains text is not reliably announced.',
14329
+ commit: "e459f91"
14330
+ },
14331
+ {
14332
+ bump: "minor",
14333
+ title: "Home and End now move the caret in the combobox-style controls \u2014",
14334
+ body: "`uni-combobox`, `uni-search-input`, `uni-tag-input` \u2014 instead of jumping to\nthe ends of the suggestion list. APG reserves those keys for text editing in\nan editable combobox, and a field that claims them makes its own text\nun-navigable exactly when you are most likely to be editing it: with the list\nopen. `uni-time-input` already behaved this way.\n\nNothing is lost. ArrowUp on a closed list already opens it on the last option,\nArrowDown on the first, and navigation wraps at both ends, so every position\nHome/End reached is still one keystroke away.\n\n`uni-multi-select-dropdown` keeps them: its roving focus rides the option\ncheckboxes rather than a text field, so there is no caret with a better claim.\n\n`ListboxNavigation` carries the switch as `homeEndNavigates`, defaulting to\nfalse \u2014 off is the right default for a control built around a text input,\nwhich is every consumer but one. If you build on the CDK helper directly and\nwant the old behavior, pass `homeEndNavigates: true`.\n\nThis also fixes a sharper bug in `uni-search-input` and `uni-tag-input`, where\nHome/End reached the navigation helper unconditionally: pressing either not\nonly moved the active option but _opened a closed suggestion list_.",
14335
+ commit: "6e2cfb1"
14336
+ },
14337
+ {
14338
+ bump: "minor",
14339
+ title: "The four listbox popups \u2014 `uni-search-input`, `uni-tag-input`,",
14340
+ body: "`uni-time-input` and `uni-combobox` \u2014 now render in the browser's top layer,\nanchored to their field, instead of as absolutely-positioned children of it.\nPut any of them inside a card, a table cell, a scroll area or a dialog and the\nsuggestion list is no longer clipped by that ancestor's `overflow`. The browser\ntracks the field natively, so the list follows on scroll and resize with no\nlisteners, and flips above the field near the bottom of the viewport.\n\nThey also open the way `uni-dropdown` does now \u2014 the same 100 ms scale-and-fade\n\u2014 so every popup panel in the library animates alike instead of the listboxes\nalone snapping into place. The origin is measured from where the popup actually\nopened, so one that flips above its field near the bottom of the viewport still\ngrows out of the edge it is attached to. Under `prefers-reduced-motion` there is\nno transition at all.\n\nNothing changes in the components' APIs or in how they dismiss. The popups use\n`popover=\"manual\"`, not `auto`: these controls already own dismissal through\nfocusout, Escape and commit, and `auto`'s light-dismiss fires on pointerdown\noutside the popup \u2014 which includes their own input, so it would close the list\non every click into the field.\n\nPositioning is gated on CSS anchor positioning support, checked together with\nthe top layer rather than separately. Browsers that have `popover` but not\nanchors \u2014 Safari 17 through 25 \u2014 keep the previous in-flow popup, which still\nclips inside `overflow: hidden` ancestors but stays on its field; promoting it\nthere would strand the list a viewport height down the page, since a top-layer\nelement has no positioned ancestor to resolve against.\n\nShared plumbing lives in `components/forms/listbox-popup.ts` alongside\n`listboxPopupStyles()`, which grew an optional `anchor` and now emits the\nin-flow rules as the base with the anchored ones in an `@supports` block.",
14341
+ commit: "dd33baa"
14342
+ },
14343
+ {
14344
+ bump: "minor",
14345
+ title: "`Option.disabled` now works in the three remaining `Options<T>` consumers, not",
14346
+ body: "just `uni-combobox`: `uni-select`, `uni-multi-select-dropdown` and\n`uni-multi-select`. Marking an individual choice `disabled` shows it without\noffering it \u2014 the plan that needs an upgrade, the channel that needs a verified\nphone number \u2014 instead of dropping it from the array and leaving the list\nlying about what exists.\n\n`uni-select` passes it to the native `<option>`, so the platform handles\nskipping, greying and announcement. The two multi-selects disable the option's\ncheckbox and refuse the toggle even when called directly. In\n`uni-multi-select-dropdown` the arrow keys step over disabled rows and Home/End\nland on the nearest enabled option \u2014 `ListboxNavigation` already knew how, it\njust was not being told which rows were disabled \u2014 so focus never parks on a\ncheckbox that cannot take it.\n\n`selectAll()` on both multi-selects now selects only enabled options. A\ndisabled option is not committable, so nothing may commit one on the user's\nbehalf; `deselectAll()` still clears everything. If you relied on `selectAll()`\nreturning every value including disabled ones, note that only options you have\nexplicitly marked `disabled` are affected. Whole-field `disabled` is unchanged\nand still disables the entire control.",
14347
+ commit: "2910c67"
14348
+ },
14349
+ {
14350
+ bump: "minor",
14351
+ title: "`uni-alert`, `uni-snackbar`, `uni-radio` and `uni-menu-item` now read their",
14352
+ body: "timing from the theme's `motion` scale, which completes the migration: every\nanimated component in the library is retimed from one place.\n\nTwo tokens join `popup`, `panel` and `reveal`:\n\n| Token | Default | Used by |\n| -------------- | ----------------- | ---------------- |\n| `notification` | 350ms ease-in-out | alert, snackbar |\n| `control` | 300ms ease | radio, menu-item |\n\n**One thing moves differently:** `menu-item`'s hover transition goes from\n0.35s to 0.3s, joining `radio` on the shared `control` token. The two were\nnever deliberately different \u2014 `radio`'s own option documented its 0.3 as\n\"matching menuItem\", which was not true \u2014 so this corrects drift rather than\nchanging a decision. A theme that wants the old timing can set the deprecated\n`transitionSpeed`, or retime `control`. Everything else is byte-identical,\nverified against the rendered styles.\n\n**Deprecated, still honoured, removed next major:**\n`alert.transitionSpeed`, `snackbar.transitionDelay`, `radio.transitionSpeed`\nand `menuItem.transitionSpeed` all still work and still outrank `motion`, so a\ntheme that set them keeps its exact timing. `menu-item`'s escape hatch is\nintact too: with neither the option nor a token set it still renders no\ntransition at all, and a token with `duration: 0` is the way to ask for\ninstant now.\n\n`card.transitionSpeed` and `input-box.transitionSpeed` are also deprecated,\nfor a different reason: **neither was ever read by its component.** Setting\nthem has never had any effect. They are removed next major and nothing needs\nto replace them.\n\n`uni-skeleton` is deliberately left out. Its shimmer is a loop rather than a\ntransition, and folding a repeating animation into a scale built around\nentering and leaving would make the scale mean two different things.",
14353
+ commit: "6f76c1d"
14354
+ },
14355
+ {
14356
+ bump: "minor",
14357
+ title: '`uni-skeleton` picks up the knobs an app theme could not reach. `color`, `highlightColor` and `borderRadius` are now inputs that take a token name and fall back to the theme option, because one screen routinely needs several of each \u2014 text bars and a pill chip do not share a corner (`borderRadius="max"`), and a skeleton on a card wants a different tint than one on the page background.',
14358
+ body: "The shimmer is now a band swept with `transform` rather than an animated `background-position`: it composites instead of repainting every frame, and its geometry is themeable via two new options, `direction` (`'ltr' | 'rtl'`, default `'ltr'` \u2014 the sweep previously ran right-to-left) and `highlightWidth` (band width as a percentage of the block, default `40`). Both ends of the band are the base color, so it dissolves into the block with no alpha and no fringing.\n\nA new `label` input announces a standalone skeleton: set it and the host becomes `role=\"status\"` with visually hidden text instead of `aria-hidden=\"true\"`. Unlabelled skeletons stay `aria-hidden`, so container-level `aria-busy` patterns are unchanged.",
14359
+ commit: "228c17f"
14360
+ },
14361
+ {
14362
+ bump: "minor",
14363
+ title: "`uni-snackbar` now renders in the browser's top layer, so it can no longer be",
14364
+ body: 'covered by a high `z-index` or clipped by an `overflow: hidden` or transformed\nancestor. It was the last overlay in the library still competing on stacking\norder: a `<dialog>` opened with `.show()`, which is the _non-modal_ form and\nnever enters the top layer, left it relying on `zIndex: Z_INDEX.dialog`. That\nheld only because apps mount the bar near the root \u2014 anywhere else, a\nconfirmation of what just happened could be silently buried.\n\nThe bar is now a `popover="manual"`. Manual rather than auto because a\nsnackbar must not light-dismiss: a click anywhere else on the page would tear\nit away from someone still reading it. It is not `showModal()` either \u2014 that\nwould make the rest of the page inert to announce a transient message.\n\n`role="status"`, the auto-close timer, its pause-on-hover and pause-on-focus\nbehaviour, the entry and exit animations, and the `[(show)]` / `open()` /\n`close()` API are all unchanged.\n\nThe element behind the component changed from `<dialog>` to `<div>`: the bar\nis never modal, and `<dialog>`\'s `open` attribute would have been a second,\ncompeting notion of "shown" alongside the popover\'s own state. Styles that\nreach inside the component to target `uni-snackbar dialog` need updating \u2014\n`uni-snackbar [role="status"]` is the stable selector.',
14365
+ commit: "eb795a3"
14366
+ },
14367
+ {
14368
+ bump: "minor",
14369
+ title: "Overlay timing is now a theme token. `UniTheme` gains a `motion` scale",
14370
+ body: "alongside `radii`, `shadows` and the rest, and the overlays point at it by\nname instead of carrying their own hardcoded durations.\n\nUntil now a theme could slow a skeleton shimmer but not a dropdown: `expand`,\n`skeleton` and `callout` each exposed their own motion option while\n`uni-dropdown` hardcoded 100ms and the combobox-style listbox popups copied\nthat constant. Retiming the library meant editing components.\n\nTwo tokens ship, because two things genuinely move differently \u2014 a small panel\nattached to a control snaps, a larger free-floating surface settles:\n\n| Token | Default | Used by |\n| ------- | ------------------ | --------------------------------------------------------------------------- |\n| `popup` | 100ms linear, \xD70.8 | dropdown, menu, multi-select, combobox, search-input, tag-input, time-input |\n| `panel` | 250ms ease | popover |\n\nA token carries `duration` (ms), `easing`, and an optional `scale` for panels\nthat grow into place \u2014 one token rather than separate duration and easing\nscales, because they are one design decision: slowing a panel without\nsoftening its curve reads as sluggish rather than calm.\n\n```ts\ncreateTheme({\n id: 'Calm',\n name: 'Calm',\n colors,\n motion: { popup: { duration: 240, easing: 'ease-out', scale: 0.95 } },\n});\n```\n\nTokens you don't restate keep their base values, and a component can still\npoint at a token of its own through its `motion` option.\n\nNothing moves differently by default \u2014 every current duration, easing and\nscale is preserved exactly, verified against the rendered styles. Themes that\npredate the scale keep working: `createTheme` fills it in, the validator does\nnot require it, and a theme registered as JSON without it resolves to the base\ntiming rather than failing. `motionSafe` remains the floor, so a theme decides\nhow overlays move for people who want movement, never whether they move at\nall.\n\n`callout`'s existing `transitionMs` option and the `expand`/`skeleton`\ndurations are untouched for now; folding them into this scale is a follow-up.",
14371
+ commit: "3b51ace"
14372
+ },
14373
+ {
14374
+ bump: "patch",
14375
+ title: "`uni-dropdown` now uses the CDK's overlay helpers instead of its own copies of",
14376
+ body: "them. It predates `cdk/overlay`, so it had been carrying a duplicate\nplacement-to-`transform-origin` map, a duplicate focus-restore rule, a\nduplicate discrete-transition block, and hand-written anchor and toggle-state\ncode. `TRANSFORM_ORIGINS` had no consumers at all as a result \u2014 the shared\nconstant existed while the one component that needed it used its own copy.\n\nNo behaviour change: the dropdown's 100 ms linear scale-and-fade, its measured\ntransform origin, its focus restore and its ARIA wiring are all identical,\nverified against the rendered styles. Every export in `cdk/overlay` now has a\nconsumer, and the component is 35 lines shorter.\n\n`discreteOverlayTransition()` takes an optional fourth argument, a\n`transition-timing-function`. Omitted, nothing is emitted and the CSS initial\nvalue stands, so existing callers are untouched.\n\nOne real inconsistency fixed along the way: the listbox popups\n(`uni-combobox`, `uni-search-input`, `uni-tag-input`, `uni-time-input`) were\nintroduced to match `uni-dropdown`'s animation but ran on the default `ease`,\nwhile the dropdown uses `linear` \u2014 so a combobox and a multi-select dropdown\nin the same form opened at visibly different rates. They now share the\ndropdown's easing exactly.",
14377
+ commit: "676ec55"
14378
+ }
14379
+ ],
14380
+ dependencyBumps: []
14381
+ },
14382
+ {
14383
+ version: "8.3.1",
14384
+ entries: [
14385
+ {
14386
+ bump: "patch",
14387
+ title: '`uni-combobox` docs: "Allowing new values" \u2014 free text never commits implicitly (closed-set contract: typing filters, a non-matching draft reverts with `(rejected)`). The supported create-new pattern is now documented with a working story: drive `[options]` from the debounced `(query)` with `[filterLocally]="false"` and, when nothing matches exactly, append a sentinel option \u2014 `{ label: `Create "${text}"`, value: \u2026 }`. As a real option it commits through every normal path (arrow + Enter, click, Enter when the filter narrows to it alone); resolve it in `(selected)` by minting the entity and writing the model. Blur intentionally never commits the sentinel \u2014 creation takes an explicit Enter or click. Lighter alternative: listen to `(rejected: { query })` and offer creation outside the control. If most values are user-created, use `uni-tag-input` (open set) instead.',
14388
+ body: "",
14389
+ commit: "66f4051"
14390
+ },
14391
+ {
14392
+ bump: "patch",
14393
+ title: "`uni-dropdown` (and everything riding it \u2014 the date picker popup, menus, multi-select): the open/close scale animation now originates from the corner actually touching the trigger. The origin was mapped statically from the _requested_ placement, but `position-try-fallbacks` lets the browser flip the panel at viewport edges \u2014 so a `bottom-end` date picker repositioned above its field still animated from the top-right corner. The panel is now measured on each toggle (open and close-start) and the transform origin follows the rendered position, via the new cdk helper `transformOriginFor(panelRect, triggerRect)`.",
14394
+ body: "",
14395
+ commit: "dc7aef9"
14396
+ }
14397
+ ],
14398
+ dependencyBumps: []
14399
+ },
14400
+ {
14401
+ version: "8.3.0",
14402
+ entries: [
14403
+ {
14404
+ bump: "minor",
14405
+ title: '`uni-combobox` \u2014 the form-bound, closed-set, single-select autocomplete. `FormValueControl<T | null>` over the cdk\'s object `Options<T>`, so it drops into Signal Forms via `[field]`; minimum usage is `<uni-combobox label="State" [options]="states" [(value)]="state" />`. Typing filters, it never selects: the draft commits on an active option, a unique exact label match, or (Enter only) a filter narrowed to one enabled option; anything else reverts and emits `(rejected)`. The value contract is identical to `uni-select` (`T | null`, `compareWith`), so swapping one for the other as a list grows is a template-only change. Filtering is local by default; `[filterLocally]="false"` renders `options` verbatim and the app narrows them from the debounced `(query)` output \u2014 the async/server-side story. Glyphs are theme icon primitives (`toggleIcon`/`clearIcon`/`selectedIcon`) rendered by `uni-icon`.',
14406
+ body: "Supporting cdk changes, both non-breaking:\n- `Option<T>` gains optional `description` (secondary line, read as part of the option's name) and `disabled` (visible and announced, not committable).\n- `ListboxNavigation` accepts a `disabled?: (index) => boolean` config hook \u2014 arrows skip disabled options, `Home`/`End` land on the nearest enabled one, an all-disabled list never activates. Existing consumers pass nothing and behave identically.",
14407
+ commit: "eb8b7ae"
14408
+ },
14409
+ {
14410
+ bump: "minor",
14411
+ title: "Listbox popups (`uni-search-input`, `uni-tag-input`, `uni-time-input`, `uni-combobox`): the active/hover option fill is now the themable `activeColor` option (default `'primary-container'`, on-color derived) instead of a hardcoded token pair. Set it when your theme maps `primary-container` and `primary-surface` to the same color \u2014 the keyboard highlight is otherwise invisible; a canvas/hover tint like the one your menus use is usually right (`searchInput: { options: { activeColor: 'tertiary-surface' } }`, and likewise `tagInput`/`timeInput`/`combobox`). The base theme carries the default explicitly so the option is discoverable in each component's Theme options table.",
14412
+ body: "The four popups now share one style source, the exported `listboxPopupStyles(theme, options, { maxHeight? })` helper (`UniListboxPopupOptions`), so their surface trio and highlight can no longer drift apart. Rendering is unchanged under existing themes; the active row's text color now derives from `listColor`'s on-pair rather than assuming `on-primary-surface`.",
14413
+ commit: "eb8b7ae"
14414
+ },
14415
+ {
14416
+ bump: "minor",
14417
+ title: "Popover v2, `uni-callout`, and `uni-tour` \u2014 the coach-mark family from the popover prototype, plus shared overlay primitives in the cdk.",
14418
+ body: "**`uni-popover` v2 (upgrade in place).** Everything v1 shipped keeps its exact behavior (`placement`, `autoClose`, the three methods \u2014 `togglePopover`'s event is now optional \u2014 and both slots), and the chrome now resolves from a real `popover` theme entry whose defaults match the old hardcoded look. New: a two-way `open` model; `mode=\"tooltip\"` (hover/focus timers, `role=\"tooltip\"` + `aria-describedby`, WCAG 1.4.13 hoverable/dismissable, dev warning on focusable content \u2014 `uni-tooltip` remains for the wrap-content case); a detached `anchor` input (element or id, resolved at open) so the panel can hug a field while the trigger keeps the disclosure ARIA \u2014 and with no trigger content, no element claims `aria-expanded` it doesn't deserve; structured anatomy (`header` + `closable` \u2715, `[popover-header]`/`[popover-footer]` slots that collapse when empty); `arrow`, `maxWidth` (theme default `38ch` \u2014 the one visible change for long unwrapped content; set the theme's `maxWidth: 'none'` to opt out), `openDelay`/`closeDelay`, and `opened`/`closed` outputs. Focus follows the APG disclosure pattern: stays on the trigger unless the panel marks `[autofocus]`, returns on close.\n\n**`uni-callout` (new).** An anchored coach mark that dims the page and cuts a spotlight hole around its target. Every scrim piece is CSS-anchor-positioned, so the hole tracks scroll/resize/layout with zero listeners, and the spotlit element stays genuinely clickable through it (`targetInteractive=false` covers it instead). Non-modal `role=\"dialog\"` with the \"duet\" focus loop \u2014 Tab cycles the panel's controls plus the interactive target \u2014 and focus restore that respects a user who moved into the target. `backdrop: 'spotlight' | 'dim' | 'none'`, `dismissible`, `dismissOnBackdrop` (otherwise backdrop clicks pulse the panel), and a `dismissed` output with `reason` (`close-button`/`escape`/`backdrop`/`programmatic`) plus `key` \u2014 the storage-free \"don't show again\" hooks. Retargets in place when `target` changes while open, which is what the tour rides.\n\n**`uni-tour` (new).** A thin sequencer over one callout: `steps` with per-step placement/backdrop/interactivity, a two-way deep-linkable `active` model, Back/Next/Done with dots-or-fraction progress, and `advanceOn` interaction gates \u2014 clicks auto-advance, anything else unlocks Next and announces it through one polite live region. Missing-target steps are skipped in the direction of travel with a dev warning. Escape/\u2715 (named by `skipLabel`) skip and report the step.\n\n**cdk.** New `overlay` module (`TRANSFORM_ORIGINS`, `setAnchorName`/`clearAnchorName`, `resolveElement` \u2014 `''` is unset, `isToggleOpen`, `discreteOverlayTransition`, `restoreOverlayFocus`, `focusableElements`) extracted from the dropdown's plumbing (dropdown's public API unchanged); `spotlightStyles(anchor, { pad, ringWidth, scrimColor })` beside `anchorStyles`, returning the window/strips/cover pieces as pure `calc(anchor(...))` style objects.\n\n**Arrow fix.** `anchorArrowStyles` now clips the rotated-square arrow to its outer half with a per-placement `clip-path` cut exactly on the panel-edge diagonal: the two border strokes previously ran the full square and visibly cut into the panel surface; they now terminate precisely at the panel edge, and the panel's own border line \u2014 which sits just outside that edge \u2014 falls inside the kept half, so the arrow background covers it and the base reads as an opening in the border. Tooltip, popover, and callout inherit the fix with no call-site changes.",
14419
+ commit: "6f87212"
14420
+ }
14421
+ ],
14422
+ dependencyBumps: []
14423
+ },
12523
14424
  {
12524
14425
  version: "8.2.0",
12525
14426
  entries: [
@@ -12994,6 +14895,83 @@ placeholder="Name or address\u2026"
12994
14895
  {
12995
14896
  package: "@uni-design-system/uni-core",
12996
14897
  releases: [
14898
+ {
14899
+ version: "9.0.0",
14900
+ entries: [
14901
+ {
14902
+ bump: "major",
14903
+ title: "Every deprecated API is removed. The library now carries no `@deprecated`",
14904
+ body: "symbols at all.\n\n**Per-component duration options \u2192 the `motion` scale.** Six components carried\ntheir own duration knob that predated the motion scale and _won over_ it:\n`expand.transitionSpeed`, `callout.transitionMs`, `radio.transitionSpeed`,\n`menuItem.transitionSpeed`, `alert.transitionSpeed` and\n`snackbar.transitionDelay`. All are gone, along with the precedence branch each\none required \u2014 timing now comes from the token, full stop.\n\nRetime the token instead; one edit covers every component pointing at it. To\nretime a single component, define a token of your own and point that\ncomponent's `motion` option at it:\n\n```ts\ncreateTheme({\n \u2026,\n motion: { productive: { duration: 110, easing: 'ease' } },\n components: { menuItem: { options: { motion: 'productive' } } },\n});\n```\n\nA `duration: 0` token is how a theme opts out of motion \u2014 that is what\n`transitionSpeed: 0` used to mean. Both showcase themes are migrated this way\n(Carbon to a 110ms `productive` token, Wellsourced to an `instant` one).\n\n**Options that never did anything.** `card.transitionSpeed` and\n`inputBox.transitionSpeed` were read by nothing and never had been. Delete them\nfrom your theme; nothing replaces them.\n\n**Renames and obsolete APIs**\n- `inputBox.typeFace` \u2192 `typeface` (the casing every other component uses).\n- `uni-tooltip`'s `appendToBody` input \u2014 inert since the tooltip moved to the\n native top layer, which escapes any overflow context by itself.\n- Box's `elevation` input \u2192 `shadow`, in both the Angular and React packages.\n It was a second name for the same thing.\n- The Angular `icons` re-export \u2192 import `BaseIcons` from\n `@uni-design-system/uni-core`. The default set ships with every theme.\n\n**The HSL color legacy is gone from uni-core.** `uniColor`, `randomRangeValue`,\n`CategorySaturation` and `CategoryLightness` are removed, superseded by the\ndeterministic OKLCH engine (`generateThemes` / `generatePalette`) \u2014 same input,\nsame theme, WCAG-checked. `RoleHues` and the `UniColor` type go with them: they\nwere reachable only through `uniColor`, and `RoleHues` had gone stale enough to\nhold saturation values in a table of hues.\n\n**Deferred output renames.** Three outputs were held back because renaming is\nbreaking; this is that release. Each also drops an eslint escape it needed for\nshadowing a native event name or using an `on` prefix.\n\n| Component | Before | After |\n| -------------------- | ----------------- | ---------------- |\n| `uni-debounce-input` | `(change)` | `(valueChange)` |\n| `uni-search-input` | `(change)` | `(searchChange)` |\n| `uni-search-input` | `(search)` | `(searchSubmit)` |\n| `dragAndDrop` | `(onFileDropped)` | `(fileDropped)` |\n\n**`uni-dropdown`'s `color` input \u2192 `containerColor`,** completing the rule the\nlayout directives set: every container-pair input in the library is now\n`containerColor`, and plain `color` always means the CSS property.\n\n**`ThemeService.getSpacing('none')` now returns `0`, not the string `'none'`.**\n`'none'` is not a valid length, so it was silently dropped wherever it landed \u2014\n`uni-menu` carried a comment working around exactly that, which is now deleted.",
14905
+ commit: "8250162"
14906
+ },
14907
+ {
14908
+ bump: "major",
14909
+ title: "The spacing scale is open, and `createTheme` finally accepts one.",
14910
+ body: 'The scale was a closed seven-name union on a doubling curve (2/4/8/16/32/64px).\nReal layouts are rarely built exclusively on one \u2014 the gaps between 8 and 16,\nand 16 and 32, are where a lot of real spacing lives \u2014 and there was no way to\nadd a step, because **`ThemeConfig` had no `spacing` field at all**:\n`createTheme` hardcoded the base scale. The Wellsourced showcase theme had to\nbolt its scale on after the fact with a post-hoc spread.\n\nThree changes, which only work together:\n- `NullableSize` gains a `(string & {})` arm, so any name the theme defines is a\n valid `padding` / `gap` / `marginInline` value while the seven named steps keep\n their autocomplete. `Size` itself stays closed \u2014 it also types _component_\n sizes, where an arbitrary name has nothing to resolve against.\n- `Spacing` is spelled out as named-optional-keys plus an index signature\n (mirroring `Typography`), rather than a `Partial<Record<\u2026>>` that would\n collapse to a plain string record and lose the named steps.\n- `createTheme({ spacing })` merges over the base scale.\n\n```ts\ncreateTheme({ id, name, colors, spacing: { tight: \'6px\', snug: \'10px\' } });\n```\n\n```html\n<div stack-layout padding="tight" gap="snug">\u2026</div>\n```\n\nBecause the scale is open, a mistyped token can no longer be a compile error. It\nis dropped \u2014 an `undefined` CSS value simply does not render \u2014 and\n`ThemeService` now warns once per unknown token in development, naming the\ntokens the active theme does define. Scaffolded `uni-theme.ts` files carry a\n`spacing` block so the static theme file stays the editable source of truth.\n\n**Behavior change:** `xxl` was in the `Size` union but defined by no base theme,\nso `padding="xxl"` type-checked and rendered nothing. It is now `128px`,\ncompleting the doubling \u2014 any element relying on the silent drop will start\nshowing spacing.',
14911
+ commit: "c0c6056"
14912
+ }
14913
+ ],
14914
+ dependencyBumps: []
14915
+ },
14916
+ {
14917
+ version: "8.4.0",
14918
+ entries: [
14919
+ {
14920
+ bump: "minor",
14921
+ title: "`uni-callout` and `uni-expand` now read their timing from the theme's `motion`",
14922
+ body: "scale, so every animated surface in the library is retimed from one place.\nThey were the last two carrying their own motion options \u2014 in different units,\nunder different names (`transitionMs` in milliseconds, `transitionSpeed` in\nseconds).\n\nA third token joins `popup` and `panel`:\n\n| Token | Default | Used by |\n| -------- | ----------------- | --------------------- |\n| `reveal` | 350ms ease-in-out | expand, expand-toggle |\n\n`reveal` is a _base_ speed, not a final duration: `uni-expand` still scales it\nby content height (\u221A-of-height, clamped) so short regions stay snappy and tall\nones aren't rushed, and its easing now drives the reveal curve, which was\nhardcoded. `uni-expand-toggle` resolves the token the same way, so the chevron\nand the region cannot drift apart. `uni-callout` maps onto `panel`, whose\n250ms matches what it already used.\n\n**Not breaking.** `transitionMs` and `transitionSpeed` are deprecated but\nstill honoured, and deliberately outrank `motion` \u2014 a theme that set either\nkeeps precisely its current timing rather than being retimed underneath it.\nThey are removed next major. Per-instance inputs, like `uni-expand`'s\n`transitionSpeed`, still outrank everything.\n\nNothing moves differently by default: callout renders 0.25s ease and expand\n0.35s ease-in-out exactly as before, verified against the rendered styles.",
14923
+ commit: "1aca747"
14924
+ },
14925
+ {
14926
+ bump: "minor",
14927
+ title: "`uni-alert`, `uni-snackbar`, `uni-radio` and `uni-menu-item` now read their",
14928
+ body: "timing from the theme's `motion` scale, which completes the migration: every\nanimated component in the library is retimed from one place.\n\nTwo tokens join `popup`, `panel` and `reveal`:\n\n| Token | Default | Used by |\n| -------------- | ----------------- | ---------------- |\n| `notification` | 350ms ease-in-out | alert, snackbar |\n| `control` | 300ms ease | radio, menu-item |\n\n**One thing moves differently:** `menu-item`'s hover transition goes from\n0.35s to 0.3s, joining `radio` on the shared `control` token. The two were\nnever deliberately different \u2014 `radio`'s own option documented its 0.3 as\n\"matching menuItem\", which was not true \u2014 so this corrects drift rather than\nchanging a decision. A theme that wants the old timing can set the deprecated\n`transitionSpeed`, or retime `control`. Everything else is byte-identical,\nverified against the rendered styles.\n\n**Deprecated, still honoured, removed next major:**\n`alert.transitionSpeed`, `snackbar.transitionDelay`, `radio.transitionSpeed`\nand `menuItem.transitionSpeed` all still work and still outrank `motion`, so a\ntheme that set them keeps its exact timing. `menu-item`'s escape hatch is\nintact too: with neither the option nor a token set it still renders no\ntransition at all, and a token with `duration: 0` is the way to ask for\ninstant now.\n\n`card.transitionSpeed` and `input-box.transitionSpeed` are also deprecated,\nfor a different reason: **neither was ever read by its component.** Setting\nthem has never had any effect. They are removed next major and nothing needs\nto replace them.\n\n`uni-skeleton` is deliberately left out. Its shimmer is a loop rather than a\ntransition, and folding a repeating animation into a scale built around\nentering and leaving would make the scale mean two different things.",
14929
+ commit: "6f76c1d"
14930
+ },
14931
+ {
14932
+ bump: "minor",
14933
+ title: '`uni-skeleton` picks up the knobs an app theme could not reach. `color`, `highlightColor` and `borderRadius` are now inputs that take a token name and fall back to the theme option, because one screen routinely needs several of each \u2014 text bars and a pill chip do not share a corner (`borderRadius="max"`), and a skeleton on a card wants a different tint than one on the page background.',
14934
+ body: "The shimmer is now a band swept with `transform` rather than an animated `background-position`: it composites instead of repainting every frame, and its geometry is themeable via two new options, `direction` (`'ltr' | 'rtl'`, default `'ltr'` \u2014 the sweep previously ran right-to-left) and `highlightWidth` (band width as a percentage of the block, default `40`). Both ends of the band are the base color, so it dissolves into the block with no alpha and no fringing.\n\nA new `label` input announces a standalone skeleton: set it and the host becomes `role=\"status\"` with visually hidden text instead of `aria-hidden=\"true\"`. Unlabelled skeletons stay `aria-hidden`, so container-level `aria-busy` patterns are unchanged.",
14935
+ commit: "228c17f"
14936
+ },
14937
+ {
14938
+ bump: "minor",
14939
+ title: "Overlay timing is now a theme token. `UniTheme` gains a `motion` scale",
14940
+ body: "alongside `radii`, `shadows` and the rest, and the overlays point at it by\nname instead of carrying their own hardcoded durations.\n\nUntil now a theme could slow a skeleton shimmer but not a dropdown: `expand`,\n`skeleton` and `callout` each exposed their own motion option while\n`uni-dropdown` hardcoded 100ms and the combobox-style listbox popups copied\nthat constant. Retiming the library meant editing components.\n\nTwo tokens ship, because two things genuinely move differently \u2014 a small panel\nattached to a control snaps, a larger free-floating surface settles:\n\n| Token | Default | Used by |\n| ------- | ------------------ | --------------------------------------------------------------------------- |\n| `popup` | 100ms linear, \xD70.8 | dropdown, menu, multi-select, combobox, search-input, tag-input, time-input |\n| `panel` | 250ms ease | popover |\n\nA token carries `duration` (ms), `easing`, and an optional `scale` for panels\nthat grow into place \u2014 one token rather than separate duration and easing\nscales, because they are one design decision: slowing a panel without\nsoftening its curve reads as sluggish rather than calm.\n\n```ts\ncreateTheme({\n id: 'Calm',\n name: 'Calm',\n colors,\n motion: { popup: { duration: 240, easing: 'ease-out', scale: 0.95 } },\n});\n```\n\nTokens you don't restate keep their base values, and a component can still\npoint at a token of its own through its `motion` option.\n\nNothing moves differently by default \u2014 every current duration, easing and\nscale is preserved exactly, verified against the rendered styles. Themes that\npredate the scale keep working: `createTheme` fills it in, the validator does\nnot require it, and a theme registered as JSON without it resolves to the base\ntiming rather than failing. `motionSafe` remains the floor, so a theme decides\nhow overlays move for people who want movement, never whether they move at\nall.\n\n`callout`'s existing `transitionMs` option and the `expand`/`skeleton`\ndurations are untouched for now; folding them into this scale is a follow-up.",
14941
+ commit: "3b51ace"
14942
+ }
14943
+ ],
14944
+ dependencyBumps: []
14945
+ },
14946
+ {
14947
+ version: "8.3.1",
14948
+ entries: [],
14949
+ dependencyBumps: []
14950
+ },
14951
+ {
14952
+ version: "8.3.0",
14953
+ entries: [
14954
+ {
14955
+ bump: "minor",
14956
+ title: "`'combobox'` joins `ComponentName`, with a base-theme entry: `toggleIcon: 'chevronDown'`, `clearIcon: 'close'`, `selectedIcon: 'check'` (BaseIcons names rendered by `uni-icon` \u2014 not Material Symbol ligatures), the listbox surface trio (`listColor`/`listShadow`/`listBorderRadius`), `activeColor`, `descriptionColor`, and `maxVisibleOptions: 8` \u2014 a scroll height, never a cap. Field chrome comes from the `input` entry via `uni-input-box`, as everywhere.",
14957
+ body: "",
14958
+ commit: "eb8b7ae"
14959
+ },
14960
+ {
14961
+ bump: "minor",
14962
+ title: "Listbox popups (`uni-search-input`, `uni-tag-input`, `uni-time-input`, `uni-combobox`): the active/hover option fill is now the themable `activeColor` option (default `'primary-container'`, on-color derived) instead of a hardcoded token pair. Set it when your theme maps `primary-container` and `primary-surface` to the same color \u2014 the keyboard highlight is otherwise invisible; a canvas/hover tint like the one your menus use is usually right (`searchInput: { options: { activeColor: 'tertiary-surface' } }`, and likewise `tagInput`/`timeInput`/`combobox`). The base theme carries the default explicitly so the option is discoverable in each component's Theme options table.",
14963
+ body: "The four popups now share one style source, the exported `listboxPopupStyles(theme, options, { maxHeight? })` helper (`UniListboxPopupOptions`), so their surface trio and highlight can no longer drift apart. Rendering is unchanged under existing themes; the active row's text color now derives from `listColor`'s on-pair rather than assuming `on-primary-surface`.",
14964
+ commit: "eb8b7ae"
14965
+ },
14966
+ {
14967
+ bump: "minor",
14968
+ title: "`'popover'`, `'callout'`, and `'tour'` join `ComponentName`, with base-theme entries. The popover defaults reproduce the previously hardcoded look (`primary-surface`, `quaternary` border, `xs` radius, `raised` shadow, `6px 12px` padding, 7px offset) plus the tooltip-mode options; the callout entry carries the scrim/spotlight geometry (`scrimColor`, `spotlightPadding`, `spotlightRadius`, `ringWidth` \u2014 the ring color is deliberately the `variant` role, not an option); the tour entry is just `progressStyle` and `footerGap`, since its skin is the callout's.",
14969
+ body: "",
14970
+ commit: "6f87212"
14971
+ }
14972
+ ],
14973
+ dependencyBumps: []
14974
+ },
12997
14975
  {
12998
14976
  version: "8.2.0",
12999
14977
  entries: [
@@ -13364,6 +15342,40 @@ placeholder="Name or address\u2026"
13364
15342
  {
13365
15343
  package: "@uni-design-system/uni-react",
13366
15344
  releases: [
15345
+ {
15346
+ version: "9.0.0",
15347
+ entries: [
15348
+ {
15349
+ bump: "major",
15350
+ title: "Every deprecated API is removed. The library now carries no `@deprecated`",
15351
+ body: "symbols at all.\n\n**Per-component duration options \u2192 the `motion` scale.** Six components carried\ntheir own duration knob that predated the motion scale and _won over_ it:\n`expand.transitionSpeed`, `callout.transitionMs`, `radio.transitionSpeed`,\n`menuItem.transitionSpeed`, `alert.transitionSpeed` and\n`snackbar.transitionDelay`. All are gone, along with the precedence branch each\none required \u2014 timing now comes from the token, full stop.\n\nRetime the token instead; one edit covers every component pointing at it. To\nretime a single component, define a token of your own and point that\ncomponent's `motion` option at it:\n\n```ts\ncreateTheme({\n \u2026,\n motion: { productive: { duration: 110, easing: 'ease' } },\n components: { menuItem: { options: { motion: 'productive' } } },\n});\n```\n\nA `duration: 0` token is how a theme opts out of motion \u2014 that is what\n`transitionSpeed: 0` used to mean. Both showcase themes are migrated this way\n(Carbon to a 110ms `productive` token, Wellsourced to an `instant` one).\n\n**Options that never did anything.** `card.transitionSpeed` and\n`inputBox.transitionSpeed` were read by nothing and never had been. Delete them\nfrom your theme; nothing replaces them.\n\n**Renames and obsolete APIs**\n- `inputBox.typeFace` \u2192 `typeface` (the casing every other component uses).\n- `uni-tooltip`'s `appendToBody` input \u2014 inert since the tooltip moved to the\n native top layer, which escapes any overflow context by itself.\n- Box's `elevation` input \u2192 `shadow`, in both the Angular and React packages.\n It was a second name for the same thing.\n- The Angular `icons` re-export \u2192 import `BaseIcons` from\n `@uni-design-system/uni-core`. The default set ships with every theme.\n\n**The HSL color legacy is gone from uni-core.** `uniColor`, `randomRangeValue`,\n`CategorySaturation` and `CategoryLightness` are removed, superseded by the\ndeterministic OKLCH engine (`generateThemes` / `generatePalette`) \u2014 same input,\nsame theme, WCAG-checked. `RoleHues` and the `UniColor` type go with them: they\nwere reachable only through `uniColor`, and `RoleHues` had gone stale enough to\nhold saturation values in a table of hues.\n\n**Deferred output renames.** Three outputs were held back because renaming is\nbreaking; this is that release. Each also drops an eslint escape it needed for\nshadowing a native event name or using an `on` prefix.\n\n| Component | Before | After |\n| -------------------- | ----------------- | ---------------- |\n| `uni-debounce-input` | `(change)` | `(valueChange)` |\n| `uni-search-input` | `(change)` | `(searchChange)` |\n| `uni-search-input` | `(search)` | `(searchSubmit)` |\n| `dragAndDrop` | `(onFileDropped)` | `(fileDropped)` |\n\n**`uni-dropdown`'s `color` input \u2192 `containerColor`,** completing the rule the\nlayout directives set: every container-pair input in the library is now\n`containerColor`, and plain `color` always means the CSS property.\n\n**`ThemeService.getSpacing('none')` now returns `0`, not the string `'none'`.**\n`'none'` is not a valid length, so it was silently dropped wherever it landed \u2014\n`uni-menu` carried a comment working around exactly that, which is now deleted.",
15352
+ commit: "8250162"
15353
+ }
15354
+ ],
15355
+ dependencyBumps: []
15356
+ },
15357
+ {
15358
+ version: "8.4.0",
15359
+ entries: [
15360
+ {
15361
+ bump: "minor",
15362
+ title: 'React layout primitives, at parity with Angular: `Box`, `Stack`, `Row`, `Center`, `Wrap`, `Grid` and `GridArea`. Angular applies layout as an attribute so the element\'s semantics stay the author\'s (`<main box-layout>`); React\'s equivalent is the polymorphic `as` prop \u2014 `<Box as="main" padding="md">` \u2014 with refs and DOM props forwarded to whatever element it renders.',
15363
+ body: 'Props, defaults and resolution order are ported one-for-one from `UniBoxComponent`, so the same tokens produce the same CSS in both frameworks: token-driven color pairs, padding, radius, border, shadow, gap and z-index; a number is px and a string is a CSS length for every sizing prop; `dashBorder` draws the SVG dashed outline; `ignoreDir` (default on) still flips flex direction under `dir="rtl"`. `Stack` keeps its `minHeight: fit-content` guard and `Row` its `minWidth: fit-content` \u2014 set `minHeight={0}` / `minWidth={0}` to shrink inside a constrained flex parent.\n\nSupporting this: `createThemeStyles`/`useThemeStyles` \u2014 the React port of the Angular `ThemeService` token \u2192 CSS resolvers, method-for-method \u2014 and `@emotion/css` (new peer dependency, matching the Angular package) so pseudo-selectors like `:dir(rtl)` resolve in a real class rather than an inline style. A Box that paints a container color now also provides that token to its descendants, so `Text` inside it picks up the matching on-color.',
15364
+ commit: "82d1341"
15365
+ }
15366
+ ],
15367
+ dependencyBumps: []
15368
+ },
15369
+ {
15370
+ version: "8.3.1",
15371
+ entries: [],
15372
+ dependencyBumps: []
15373
+ },
15374
+ {
15375
+ version: "8.3.0",
15376
+ entries: [],
15377
+ dependencyBumps: []
15378
+ },
13367
15379
  {
13368
15380
  version: "8.2.0",
13369
15381
  entries: [
@@ -13541,6 +15553,30 @@ placeholder="Name or address\u2026"
13541
15553
  {
13542
15554
  package: "@uni-design-system/uni-mcp",
13543
15555
  releases: [
15556
+ {
15557
+ version: "4.7.2",
15558
+ entries: [
15559
+ {
15560
+ bump: "patch",
15561
+ title: "Fix three miscategorized components in the index.",
15562
+ body: 'Categories come from an ordered list of substring regexes, so a name that merely\ncontains an earlier row\'s keyword lands in the wrong bucket \u2014 and a\nmiscategorized component is invisible to `list-components --category`, which is\nhow agents and humans find things.\n- `textarea` \u2192 **forms** (was `primitives`: `/text/` matches inside "textarea"\n and wins before the forms row is tried)\n- `combobox` \u2192 **forms** (was `layout`: `/box/` matches inside "combobox")\n- `expand-toggle` \u2192 **layout** (was `forms`: `/toggle/` beat `/expand/`)\n\nKnown ids now go through an explicit override map consulted before the keyword\npass, so a fix is a one-line entry rather than a regex that has to be reasoned\nabout globally.\n\nAlso: MDX pages are matched to their source by basename, stripping only\n`.component.ts`. With the layout primitives and `uni-text` becoming directives,\n`.directive.ts` is stripped too, so their docs keep attaching by name instead of\nfalling through to the same-directory fallback.',
15563
+ commit: "c0c6056"
15564
+ }
15565
+ ],
15566
+ dependencyBumps: []
15567
+ },
15568
+ {
15569
+ version: "4.7.1",
15570
+ entries: [
15571
+ {
15572
+ bump: "patch",
15573
+ title: "README: the hosted (Render) endpoint is marked dormant \u2014 no deployment is currently running; stdio via `npx -y @uni-design-system/uni-mcp` is the canonical path (pin the package to your installed Uni version for version-locked answers). The HTTP mode stays documented and deployable for when a browser-based consumer needs it. The `get-changelog` and `export-dtcg-tokens` tools are now listed in the tools table.",
15574
+ body: "",
15575
+ commit: "b160b3c"
15576
+ }
15577
+ ],
15578
+ dependencyBumps: []
15579
+ },
13544
15580
  {
13545
15581
  version: "4.7.0",
13546
15582
  entries: [
@@ -13965,6 +16001,32 @@ var EXPAND_MIN_DURATION = 0.15;
13965
16001
  var EXPAND_MAX_DURATION = 0.6;
13966
16002
  var MIN_SCALE = EXPAND_MIN_DURATION / EXPAND_DEFAULT_SPEED;
13967
16003
  var MAX_SCALE = EXPAND_MAX_DURATION / EXPAND_DEFAULT_SPEED;
16004
+ var clamp$2 = (value, min, max) => Math.min(max, Math.max(min, value));
16005
+ var toHex2 = (value) => clamp$2(Math.round(value), 0, 255).toString(16).padStart(2, "0");
16006
+ var rgbToHex = ({ red, green, blue }) => `#${toHex2(red)}${toHex2(green)}${toHex2(blue)}`.toUpperCase();
16007
+ var hexToRgb = (hex) => {
16008
+ let h = hex.replace("#", "").trim();
16009
+ if (h.length === 3) h = h.split("").map((c) => c + c).join("");
16010
+ const int = parseInt(h, 16);
16011
+ return {
16012
+ red: int >> 16 & 255,
16013
+ green: int >> 8 & 255,
16014
+ blue: int & 255
16015
+ };
16016
+ };
16017
+ var relativeLuminance = ({ red, green, blue }) => {
16018
+ const channel = (value) => {
16019
+ const v = value / 255;
16020
+ return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);
16021
+ };
16022
+ return 0.2126 * channel(red) + 0.7152 * channel(green) + 0.0722 * channel(blue);
16023
+ };
16024
+ var contrastRatio = (a, b) => {
16025
+ const la = relativeLuminance(typeof a === "string" ? hexToRgb(a) : a);
16026
+ const lb = relativeLuminance(typeof b === "string" ? hexToRgb(b) : b);
16027
+ const [hi, lo] = la > lb ? [la, lb] : [lb, la];
16028
+ return (hi + 0.05) / (lo + 0.05);
16029
+ };
13968
16030
  var cycle = (angle) => {
13969
16031
  if (angle > 360) return angle - 360;
13970
16032
  if (angle < 0) return angle + 360;
@@ -14016,32 +16078,6 @@ var schemeHues = (hue, scheme) => {
14016
16078
  }
14017
16079
  }
14018
16080
  };
14019
- var clamp$2 = (value, min, max) => Math.min(max, Math.max(min, value));
14020
- var toHex2 = (value) => clamp$2(Math.round(value), 0, 255).toString(16).padStart(2, "0");
14021
- var rgbToHex = ({ red, green, blue }) => `#${toHex2(red)}${toHex2(green)}${toHex2(blue)}`.toUpperCase();
14022
- var hexToRgb = (hex) => {
14023
- let h = hex.replace("#", "").trim();
14024
- if (h.length === 3) h = h.split("").map((c) => c + c).join("");
14025
- const int = parseInt(h, 16);
14026
- return {
14027
- red: int >> 16 & 255,
14028
- green: int >> 8 & 255,
14029
- blue: int & 255
14030
- };
14031
- };
14032
- var relativeLuminance = ({ red, green, blue }) => {
14033
- const channel = (value) => {
14034
- const v = value / 255;
14035
- return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);
14036
- };
14037
- return 0.2126 * channel(red) + 0.7152 * channel(green) + 0.0722 * channel(blue);
14038
- };
14039
- var contrastRatio = (a, b) => {
14040
- const la = relativeLuminance(typeof a === "string" ? hexToRgb(a) : a);
14041
- const lb = relativeLuminance(typeof b === "string" ? hexToRgb(b) : b);
14042
- const [hi, lo] = la > lb ? [la, lb] : [lb, la];
14043
- return (hi + 0.05) / (lo + 0.05);
14044
- };
14045
16081
  var clamp$1 = (value, min, max) => Math.min(max, Math.max(min, value));
14046
16082
  var srgbToLinear = (channel) => channel <= 0.04045 ? channel / 12.92 : Math.pow((channel + 0.055) / 1.055, 2.4);
14047
16083
  var linearToSrgb = (channel) => channel <= 31308e-7 ? 12.92 * channel : 1.055 * Math.pow(channel, 1 / 2.4) - 0.055;
@@ -14714,13 +16750,37 @@ var BaseSpacing = {
14714
16750
  sm: "8px",
14715
16751
  md: "16px",
14716
16752
  lg: "32px",
14717
- xl: "64px"
16753
+ xl: "64px",
16754
+ xxl: "128px"
14718
16755
  };
14719
16756
  var BaseThicknesses = {
14720
16757
  thin: 1,
14721
16758
  standard: 2,
14722
16759
  thick: 4
14723
16760
  };
16761
+ var BaseMotion = {
16762
+ popup: {
16763
+ duration: 100,
16764
+ easing: "linear",
16765
+ scale: 0.8
16766
+ },
16767
+ panel: {
16768
+ duration: 250,
16769
+ easing: "ease"
16770
+ },
16771
+ reveal: {
16772
+ duration: 350,
16773
+ easing: "ease-in-out"
16774
+ },
16775
+ notification: {
16776
+ duration: 350,
16777
+ easing: "ease-in-out"
16778
+ },
16779
+ control: {
16780
+ duration: 300,
16781
+ easing: "ease"
16782
+ }
16783
+ };
14724
16784
  var BaseRadii = {
14725
16785
  none: "none",
14726
16786
  xxs: "4px",
@@ -14758,7 +16818,7 @@ var buildComponents = (c) => ({
14758
16818
  alert: { options: {
14759
16819
  topPosition: 40,
14760
16820
  borderRadius: "sm",
14761
- transitionSpeed: 0.35,
16821
+ motion: "notification",
14762
16822
  elevation: "md"
14763
16823
  } },
14764
16824
  breadcrumb: { options: {
@@ -14851,6 +16911,7 @@ var buildComponents = (c) => ({
14851
16911
  listColor: "primary-surface",
14852
16912
  listShadow: "menu",
14853
16913
  listBorderRadius: "xs",
16914
+ activeColor: "primary-container",
14854
16915
  maxSuggestions: 8
14855
16916
  } },
14856
16917
  checkbox: { options: {
@@ -14863,7 +16924,7 @@ var buildComponents = (c) => ({
14863
16924
  size: 20,
14864
16925
  ringColor: "outline",
14865
16926
  fillColor: "surface",
14866
- transitionSpeed: 0.3
16927
+ motion: "control"
14867
16928
  } },
14868
16929
  dialog: { options: {
14869
16930
  borderRadius: "lg",
@@ -14900,7 +16961,8 @@ var buildComponents = (c) => ({
14900
16961
  border: "none",
14901
16962
  borderRadius: "xxs",
14902
16963
  color: "primary-surface",
14903
- shadow: "menu"
16964
+ shadow: "menu",
16965
+ motion: "popup"
14904
16966
  } },
14905
16967
  menu: { options: {
14906
16968
  minWidth: 184,
@@ -14923,7 +16985,7 @@ var buildComponents = (c) => ({
14923
16985
  textColor: void 0,
14924
16986
  hoverColor: "primary-container",
14925
16987
  activeSymbol: "check",
14926
- transitionSpeed: 0.35
16988
+ motion: "control"
14927
16989
  },
14928
16990
  variants: { warn: {
14929
16991
  color: c.warn,
@@ -14933,7 +16995,24 @@ var buildComponents = (c) => ({
14933
16995
  }
14934
16996
  } }
14935
16997
  },
14936
- expand: { options: { transitionSpeed: 0.35 } },
16998
+ popover: { options: {
16999
+ color: "primary-surface",
17000
+ border: "quaternary",
17001
+ borderRadius: "xs",
17002
+ shadow: "raised",
17003
+ typeface: "label",
17004
+ padding: "6px 12px",
17005
+ maxWidth: "38ch",
17006
+ offset: 7,
17007
+ arrowSize: 8,
17008
+ closeSymbol: "close",
17009
+ headerTypeface: "title-small",
17010
+ tooltipPadding: "4px 8px",
17011
+ tooltipOpenDelay: 500,
17012
+ tooltipCloseDelay: 150,
17013
+ motion: "panel"
17014
+ } },
17015
+ expand: { options: { motion: "reveal" } },
14937
17016
  footer: { options: {
14938
17017
  height: 52,
14939
17018
  color: "primary",
@@ -15052,6 +17131,7 @@ var buildComponents = (c) => ({
15052
17131
  listColor: "primary-surface",
15053
17132
  listShadow: "menu",
15054
17133
  listBorderRadius: "xs",
17134
+ activeColor: "primary-container",
15055
17135
  maxSuggestions: 8
15056
17136
  } },
15057
17137
  calendar: {
@@ -15087,6 +17167,17 @@ var buildComponents = (c) => ({
15087
17167
  }
15088
17168
  }
15089
17169
  },
17170
+ combobox: { options: {
17171
+ toggleIcon: "chevronDown",
17172
+ clearIcon: "close",
17173
+ selectedIcon: "check",
17174
+ listColor: "primary-surface",
17175
+ listShadow: "menu",
17176
+ listBorderRadius: "xs",
17177
+ activeColor: "primary-container",
17178
+ maxVisibleOptions: 8,
17179
+ descriptionColor: "on-primary-surface-variant"
17180
+ } },
15090
17181
  dateInput: { options: {
15091
17182
  toggleSymbol: "calendar_month",
15092
17183
  popupShadow: "menu",
@@ -15098,6 +17189,7 @@ var buildComponents = (c) => ({
15098
17189
  listColor: "primary-surface",
15099
17190
  listShadow: "menu",
15100
17191
  listBorderRadius: "xs",
17192
+ activeColor: "primary-container",
15101
17193
  maxVisibleOptions: 7
15102
17194
  } },
15103
17195
  dateTimeInput: { options: {
@@ -15381,11 +17473,13 @@ var buildComponents = (c) => ({
15381
17473
  borderRadius: "xs",
15382
17474
  animation: "shimmer",
15383
17475
  duration: 1.4,
17476
+ direction: "ltr",
17477
+ highlightWidth: 40,
15384
17478
  gap: "sm"
15385
17479
  } },
15386
17480
  snackbar: { options: {
15387
17481
  bottomPosition: 40,
15388
- transitionDelay: "0.35s",
17482
+ motion: "notification",
15389
17483
  autoCloseDelay: 35e3
15390
17484
  } },
15391
17485
  symbol: { options: {
@@ -15405,6 +17499,27 @@ var buildComponents = (c) => ({
15405
17499
  shadow: "raised",
15406
17500
  color: "inverse-surface",
15407
17501
  typeface: "label"
17502
+ } },
17503
+ callout: { options: {
17504
+ color: "primary-surface",
17505
+ borderRadius: "xs",
17506
+ shadow: "menu",
17507
+ width: "320px",
17508
+ padding: "16px",
17509
+ headerTypeface: "title-small",
17510
+ typeface: "label",
17511
+ closeSymbol: "close",
17512
+ arrowSize: 8,
17513
+ offset: 12,
17514
+ scrimColor: "rgba(0, 0, 0, 0.45)",
17515
+ spotlightPadding: 6,
17516
+ spotlightRadius: "xs",
17517
+ ringWidth: 2,
17518
+ motion: "panel"
17519
+ } },
17520
+ tour: { options: {
17521
+ progressStyle: "dots",
17522
+ footerGap: "sm"
15408
17523
  } }
15409
17524
  });
15410
17525
  var isRecord$1 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
@@ -15414,7 +17529,7 @@ var deepMerge = (base, override) => {
15414
17529
  for (const [key, value] of Object.entries(override)) out[key] = isRecord$1(value) && isRecord$1(out[key]) ? deepMerge(out[key], value) : value;
15415
17530
  return out;
15416
17531
  };
15417
- var createTheme = ({ id, name, colors, icons = {}, radii = BaseRadii, shadows = BaseShadows, typography, borders, thicknesses, components }) => ({
17532
+ var createTheme = ({ id, name, colors, icons = {}, radii = BaseRadii, shadows = BaseShadows, motion, typography, borders, thicknesses, spacing, components }) => ({
15418
17533
  id,
15419
17534
  name,
15420
17535
  colors,
@@ -15422,7 +17537,14 @@ var createTheme = ({ id, name, colors, icons = {}, radii = BaseRadii, shadows =
15422
17537
  borders: deepMerge(buildBorders(colors), borders),
15423
17538
  radii,
15424
17539
  shadows,
15425
- spacing: BaseSpacing,
17540
+ spacing: {
17541
+ ...BaseSpacing,
17542
+ ...spacing
17543
+ },
17544
+ motion: {
17545
+ ...BaseMotion,
17546
+ ...motion
17547
+ },
15426
17548
  thicknesses: {
15427
17549
  ...BaseThicknesses,
15428
17550
  ...thicknesses
@@ -15601,6 +17723,7 @@ var themeExport = (exportName, displayName, colorsConst, shadowsConst, radii) =>
15601
17723
  ` shadows: ${shadowsConst},`,
15602
17724
  " icons,",
15603
17725
  ...radii ? [" radii,"] : [],
17726
+ " spacing,",
15604
17727
  "});"
15605
17728
  ].join("\n");
15606
17729
  var emitThemeFile = (input) => {
@@ -15647,6 +17770,7 @@ var emitThemeFile = (input) => {
15647
17770
  " type ComponentThemes,",
15648
17771
  " type Icons,",
15649
17772
  " type Shadows,",
17773
+ " type Spacing,",
15650
17774
  " type UniTheme,",
15651
17775
  "} from '@uni-design-system/uni-core';",
15652
17776
  "",
@@ -15689,6 +17813,15 @@ ${recordLiteral(shadows, " ")}
15689
17813
  " */",
15690
17814
  "const icons: Icons = {};",
15691
17815
  "",
17816
+ "/**",
17817
+ " * Spacing steps, merged over the base scale",
17818
+ " * (none: 0, xxs: 2px, xs: 4px, sm: 8px, md: 16px, lg: 32px, xl: 64px, xxl: 128px).",
17819
+ " * Restate a named step to retune the rhythm, and add your own names for the",
17820
+ " * gaps your design actually uses \u2014 every extra key is then a valid `padding`,",
17821
+ " * `gap` or `marginInline` value: `<div stack-layout gap='tight'>`.",
17822
+ " */",
17823
+ "const spacing: Spacing = {};",
17824
+ "",
15692
17825
  ...radii ? [
15693
17826
  `/** Shape language: '${input.shape}'. */`,
15694
17827
  `const radii = {
@@ -16751,4 +18884,4 @@ export {
16751
18884
  buildStoredTheme,
16752
18885
  createUniServer
16753
18886
  };
16754
- //# sourceMappingURL=chunk-JOMMURY6.js.map
18887
+ //# sourceMappingURL=chunk-HXXP4PTK.js.map