@nonoun/native-ui 0.2.8 → 0.2.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/dist/components-lean.css +119 -6
  2. package/dist/components.css +119 -6
  3. package/dist/{ui-icon-element.js → components.js} +1387 -465
  4. package/dist/containers/ui-layout-sidebar/ui-layout-sidebar-element.d.ts.map +1 -1
  5. package/dist/core/trait-runtime.d.ts.map +1 -1
  6. package/dist/{register-all2.js → core.js} +79 -35
  7. package/dist/custom-elements.json +2747 -2747
  8. package/dist/foundation.css +1 -15
  9. package/dist/inspector/build-inspector.d.ts +8 -0
  10. package/dist/inspector/build-inspector.d.ts.map +1 -0
  11. package/dist/inspector/index.d.ts +10 -0
  12. package/dist/inspector/index.d.ts.map +1 -0
  13. package/dist/{nav/inspector/ds-color-swatch-element.d.ts → inspector/native-tokens-color-swatch-element.d.ts} +3 -3
  14. package/dist/inspector/native-tokens-color-swatch-element.d.ts.map +1 -0
  15. package/dist/inspector/native-tokens-color-swatch.d.ts +3 -0
  16. package/dist/inspector/native-tokens-color-swatch.d.ts.map +1 -0
  17. package/dist/{nav/inspector/ds-colors-element.d.ts → inspector/native-tokens-colors-element.d.ts} +4 -4
  18. package/dist/inspector/native-tokens-colors-element.d.ts.map +1 -0
  19. package/dist/inspector/native-tokens-colors.d.ts +4 -0
  20. package/dist/inspector/native-tokens-colors.d.ts.map +1 -0
  21. package/dist/inspector/native-tokens-inspector-element.d.ts +15 -0
  22. package/dist/inspector/native-tokens-inspector-element.d.ts.map +1 -0
  23. package/dist/inspector/native-tokens-inspector.d.ts +3 -0
  24. package/dist/inspector/native-tokens-inspector.d.ts.map +1 -0
  25. package/dist/{nav/inspector/ds-themes-element.d.ts → inspector/native-tokens-themes-element.d.ts} +4 -4
  26. package/dist/inspector/native-tokens-themes-element.d.ts.map +1 -0
  27. package/dist/inspector/native-tokens-themes.d.ts +4 -0
  28. package/dist/inspector/native-tokens-themes.d.ts.map +1 -0
  29. package/dist/{nav/inspector/ds-variable-element.d.ts → inspector/native-tokens-variable-element.d.ts} +4 -4
  30. package/dist/inspector/native-tokens-variable-element.d.ts.map +1 -0
  31. package/dist/inspector/native-tokens-variable.d.ts +4 -0
  32. package/dist/inspector/native-tokens-variable.d.ts.map +1 -0
  33. package/dist/inspector.css +31 -31
  34. package/dist/inspector.d.ts +11 -6
  35. package/dist/inspector.d.ts.map +1 -1
  36. package/dist/inspector.js +123 -105
  37. package/dist/kernel.js +77 -77
  38. package/dist/native-ui-lean.css +120 -21
  39. package/dist/native-ui.css +120 -21
  40. package/dist/native-ui.js +4 -49
  41. package/dist/register-all.js +4 -3
  42. package/dist/traits/adapters/draggable-adapter.d.ts.map +1 -1
  43. package/dist/traits/drag-controller.d.ts +3 -0
  44. package/dist/traits/drag-controller.d.ts.map +1 -1
  45. package/dist/traits.js +3 -6
  46. package/dist/ui-icon.js +56 -0
  47. package/package.json +1 -1
  48. package/dist/define.js +0 -62
  49. package/dist/dialog-controller.js +0 -703
  50. package/dist/nav/inspector/build-inspector.d.ts +0 -8
  51. package/dist/nav/inspector/build-inspector.d.ts.map +0 -1
  52. package/dist/nav/inspector/ds-color-swatch-element.d.ts.map +0 -1
  53. package/dist/nav/inspector/ds-color-swatch.d.ts +0 -3
  54. package/dist/nav/inspector/ds-color-swatch.d.ts.map +0 -1
  55. package/dist/nav/inspector/ds-colors-element.d.ts.map +0 -1
  56. package/dist/nav/inspector/ds-colors.d.ts +0 -4
  57. package/dist/nav/inspector/ds-colors.d.ts.map +0 -1
  58. package/dist/nav/inspector/ds-themes-element.d.ts.map +0 -1
  59. package/dist/nav/inspector/ds-themes.d.ts +0 -4
  60. package/dist/nav/inspector/ds-themes.d.ts.map +0 -1
  61. package/dist/nav/inspector/ds-variable-element.d.ts.map +0 -1
  62. package/dist/nav/inspector/ds-variable.d.ts +0 -4
  63. package/dist/nav/inspector/ds-variable.d.ts.map +0 -1
  64. package/dist/nav/inspector/index.d.ts +0 -9
  65. package/dist/nav/inspector/index.d.ts.map +0 -1
  66. package/dist/ui-element.js +0 -133
  67. package/dist/uid.js +0 -87
package/dist/kernel.js CHANGED
@@ -1,16 +1,16 @@
1
- import { n as e, t } from "./uid.js";
2
- import { i as n, n as r, r as i, t as a } from "./define.js";
1
+ import { Gt as e, It as t, Kt as n, Wt as r, qt as i } from "./components.js";
2
+ import { G as a } from "./core.js";
3
3
  var o = class {
4
4
  #e = /* @__PURE__ */ new Map();
5
5
  #t = [];
6
6
  #n = [];
7
- #r = n(null);
8
- #i = n(!1);
9
- #a = n(null);
7
+ #r = i(null);
8
+ #i = i(!1);
9
+ #a = i(null);
10
10
  #o = 0;
11
- lastCommand = i(() => this.#r.value);
12
- dispatching = i(() => this.#i.value);
13
- errors = i(() => this.#a.value);
11
+ lastCommand = n(() => this.#r.value);
12
+ dispatching = n(() => this.#i.value);
13
+ errors = n(() => this.#a.value);
14
14
  on(e, t) {
15
15
  if (typeof e == "string") {
16
16
  let n = e, r = this.#e.get(n);
@@ -77,13 +77,13 @@ function s() {
77
77
  return new o();
78
78
  }
79
79
  var c = class {
80
- #e = n([]);
81
- #t = n([]);
80
+ #e = i([]);
81
+ #t = i([]);
82
82
  #n = 100;
83
- undoStack = i(() => this.#e.value);
84
- redoStack = i(() => this.#t.value);
85
- canUndo = i(() => this.#e.value.length > 0);
86
- canRedo = i(() => this.#t.value.length > 0);
83
+ undoStack = n(() => this.#e.value);
84
+ redoStack = n(() => this.#t.value);
85
+ canUndo = n(() => this.#e.value.length > 0);
86
+ canRedo = n(() => this.#t.value.length > 0);
87
87
  push(e) {
88
88
  e.meta?.undoType && r(() => {
89
89
  let t = [...this.#e.value, e];
@@ -132,11 +132,11 @@ function l(e) {
132
132
  return e !== void 0 && t.setMaxSize(e), t;
133
133
  }
134
134
  var u = 1e3, d = 10, f = class {
135
- #e = n([]);
135
+ #e = i([]);
136
136
  #t = !1;
137
137
  #n = /* @__PURE__ */ new Map();
138
- stack = i(() => this.#e.value);
139
- topOverlay = i(() => {
138
+ stack = n(() => this.#e.value);
139
+ topOverlay = n(() => {
140
140
  let e = this.#e.value;
141
141
  return e.length > 0 ? e[e.length - 1] : null;
142
142
  });
@@ -214,9 +214,9 @@ function p() {
214
214
  }
215
215
  var m = 0, h = class {
216
216
  #e = [];
217
- #t = n(["global"]);
217
+ #t = i(["global"]);
218
218
  #n = !1;
219
- activeScope = i(() => {
219
+ activeScope = n(() => {
220
220
  let e = this.#t.value;
221
221
  return e[e.length - 1];
222
222
  });
@@ -398,10 +398,10 @@ function se(e) {
398
398
  return new oe(e);
399
399
  }
400
400
  var ce = class {
401
- #e = n([]);
401
+ #e = i([]);
402
402
  #t = 1e3;
403
- entries = i(() => this.#e.value);
404
- size = i(() => this.#e.value.length);
403
+ entries = n(() => this.#e.value);
404
+ size = n(() => this.#e.value.length);
405
405
  log(e) {
406
406
  let n = Object.freeze({
407
407
  id: t("log"),
@@ -463,9 +463,9 @@ function le(e) {
463
463
  return e !== void 0 && t.setMaxSize(e), t;
464
464
  }
465
465
  var v = class {
466
- #e = n([]);
466
+ #e = i([]);
467
467
  #t = 500;
468
- samples = i(() => this.#e.value);
468
+ samples = n(() => this.#e.value);
469
469
  measure(e, t) {
470
470
  let n = performance.now();
471
471
  try {
@@ -522,31 +522,31 @@ function pe(e) {
522
522
  var y = class {
523
523
  #e = /* @__PURE__ */ new Map();
524
524
  #t = /* @__PURE__ */ new Map();
525
- #n = n(!1);
526
- #r = n(null);
525
+ #n = i(!1);
526
+ #r = i(null);
527
527
  #i = 0;
528
- loading = i(() => this.#n.value);
529
- error = i(() => this.#r.value);
528
+ loading = n(() => this.#n.value);
529
+ error = n(() => this.#r.value);
530
530
  query(e) {
531
531
  let t = pe(e), r = e.cacheTtl ?? 0, a = this.#e.get(t);
532
- if (a && r > 0 && Date.now() - a.entry.timestamp < r) return i(() => a.signal.value);
532
+ if (a && r > 0 && Date.now() - a.entry.timestamp < r) return n(() => a.signal.value);
533
533
  let o = a;
534
534
  return o || (o = {
535
535
  entry: {
536
536
  data: null,
537
537
  timestamp: 0
538
538
  },
539
- signal: n(null)
540
- }, this.#e.set(t, o)), this.#a(e, t), i(() => o.signal.value);
539
+ signal: i(null)
540
+ }, this.#e.set(t, o)), this.#a(e, t), n(() => o.signal.value);
541
541
  }
542
542
  async mutate(e, t) {
543
- let i, a;
544
- if (t) if (a = this.#e.get(t.key), i = a?.signal.peek() ?? null, a) a.signal.value = t.value, a.entry = Object.freeze({
543
+ let n, a;
544
+ if (t) if (a = this.#e.get(t.key), n = a?.signal.peek() ?? null, a) a.signal.value = t.value, a.entry = Object.freeze({
545
545
  data: t.value,
546
546
  timestamp: Date.now()
547
547
  });
548
548
  else {
549
- let e = n(t.value);
549
+ let e = i(t.value);
550
550
  a = {
551
551
  entry: Object.freeze({
552
552
  data: t.value,
@@ -556,29 +556,29 @@ var y = class {
556
556
  }, this.#e.set(t.key, a);
557
557
  }
558
558
  try {
559
- let i = await this.#s(e), a = pe(e);
559
+ let n = await this.#s(e), a = pe(e);
560
560
  return r(() => {
561
561
  let e = Object.freeze({
562
- data: i,
562
+ data: n,
563
563
  timestamp: Date.now()
564
564
  }), r = this.#e.get(a);
565
- if (r ? (r.signal.value = i, r.entry = e) : this.#e.set(a, {
565
+ if (r ? (r.signal.value = n, r.entry = e) : this.#e.set(a, {
566
566
  entry: e,
567
- signal: n(i)
567
+ signal: i(n)
568
568
  }), t && t.key !== a) {
569
- let n = this.#e.get(t.key);
570
- n && (n.signal.value = i, n.entry = e);
569
+ let r = this.#e.get(t.key);
570
+ r && (r.signal.value = n, r.entry = e);
571
571
  }
572
- }), i;
572
+ }), n;
573
573
  } catch (e) {
574
574
  t && a && r(() => {
575
- a.signal.value = i, a.entry = Object.freeze({
576
- data: i,
575
+ a.signal.value = n, a.entry = Object.freeze({
576
+ data: n,
577
577
  timestamp: Date.now()
578
578
  });
579
579
  });
580
- let n = e instanceof Error ? e : Error(String(e));
581
- throw this.#r.value = n, n;
580
+ let i = e instanceof Error ? e : Error(String(e));
581
+ throw this.#r.value = i, i;
582
582
  }
583
583
  }
584
584
  invalidate(e) {
@@ -611,15 +611,15 @@ var y = class {
611
611
  async #a(e, t) {
612
612
  this.#c();
613
613
  try {
614
- let i = await this.#o(e);
614
+ let n = await this.#o(e);
615
615
  r(() => {
616
616
  let e = Object.freeze({
617
- data: i,
617
+ data: n,
618
618
  timestamp: Date.now()
619
619
  }), r = this.#e.get(t);
620
- r ? (r.signal.value = i, r.entry = e) : this.#e.set(t, {
620
+ r ? (r.signal.value = n, r.entry = e) : this.#e.set(t, {
621
621
  entry: e,
622
- signal: n(i)
622
+ signal: i(n)
623
623
  }), this.#r.value = null;
624
624
  });
625
625
  } catch (e) {
@@ -1066,15 +1066,15 @@ function E(e, t) {
1066
1066
  return !1;
1067
1067
  }
1068
1068
  var D = class {
1069
- #e = n([]);
1070
- #t = n([]);
1069
+ #e = i([]);
1070
+ #t = i([]);
1071
1071
  #n = /* @__PURE__ */ new Map();
1072
- #r = n(null);
1073
- #i = n(0);
1074
- capabilities = i(() => this.#e.value);
1075
- rules = i(() => this.#t.value);
1076
- lastDecision = i(() => this.#r.value);
1077
- deniedCount = i(() => this.#i.value);
1072
+ #r = i(null);
1073
+ #i = i(0);
1074
+ capabilities = n(() => this.#e.value);
1075
+ rules = n(() => this.#t.value);
1076
+ lastDecision = n(() => this.#r.value);
1077
+ deniedCount = n(() => this.#i.value);
1078
1078
  grant(e) {
1079
1079
  let n = t("cap"), r = Object.freeze({
1080
1080
  id: n,
@@ -1759,48 +1759,48 @@ var L = class {
1759
1759
  #t;
1760
1760
  #n;
1761
1761
  #r = /* @__PURE__ */ new Map();
1762
- #i = n(0);
1763
- surfaceCount = i(() => this.#i.value);
1762
+ #i = i(0);
1763
+ surfaceCount = n(() => this.#i.value);
1764
1764
  constructor(e, t, n) {
1765
1765
  this.#e = e, this.#t = t, this.#n = n ?? null;
1766
1766
  }
1767
1767
  handleMessage(e, t) {
1768
1768
  Ye(e) ? this.#a(e, t) : Xe(e) ? this.#o(e, t) : Ze(e) ? this.#l(e) : Qe(e) && this.#u(e);
1769
1769
  }
1770
- #a(e, r) {
1771
- let { surfaceId: i, catalogId: a, theme: o } = e.createSurface, s = this.#r.get(i);
1770
+ #a(e, n) {
1771
+ let { surfaceId: r, catalogId: a, theme: o } = e.createSurface, s = this.#r.get(r);
1772
1772
  if (s) {
1773
1773
  s.catalogId = a, s.theme = o;
1774
1774
  return;
1775
1775
  }
1776
1776
  let c = {
1777
- surfaceId: i,
1777
+ surfaceId: r,
1778
1778
  planId: t("a2ui-plan"),
1779
1779
  catalogId: a,
1780
1780
  theme: o,
1781
- container: r ?? document.createElement("div"),
1781
+ container: n ?? document.createElement("div"),
1782
1782
  components: [],
1783
- dataModel: n({}),
1783
+ dataModel: i({}),
1784
1784
  bindings: /* @__PURE__ */ new Map(),
1785
1785
  bindingDisposers: [],
1786
1786
  actionDisposer: null,
1787
1787
  rendered: !1
1788
1788
  };
1789
- this.#r.set(i, c), this.#i.value = this.#r.size;
1789
+ this.#r.set(r, c), this.#i.value = this.#r.size;
1790
1790
  }
1791
- #o(e, r) {
1792
- let { surfaceId: i, components: a } = e.updateComponents, o = this.#r.get(i);
1793
- o ? r && (o.container = r) : (o = {
1794
- surfaceId: i,
1791
+ #o(e, n) {
1792
+ let { surfaceId: r, components: a } = e.updateComponents, o = this.#r.get(r);
1793
+ o ? n && (o.container = n) : (o = {
1794
+ surfaceId: r,
1795
1795
  planId: t("a2ui-plan"),
1796
- container: r ?? document.createElement("div"),
1796
+ container: n ?? document.createElement("div"),
1797
1797
  components: [],
1798
- dataModel: n({}),
1798
+ dataModel: i({}),
1799
1799
  bindings: /* @__PURE__ */ new Map(),
1800
1800
  bindingDisposers: [],
1801
1801
  actionDisposer: null,
1802
1802
  rendered: !1
1803
- }, this.#r.set(i, o), this.#i.value = this.#r.size), o.rendered ? (this.#c(o, a), o.components = [...a]) : (o.components = [...a], this.#s(o)), o.rendered && this.#n?.(o.surfaceId, o.container);
1803
+ }, this.#r.set(r, o), this.#i.value = this.#r.size), o.rendered ? (this.#c(o, a), o.components = [...a]) : (o.components = [...a], this.#s(o)), o.rendered && this.#n?.(o.surfaceId, o.container);
1804
1804
  }
1805
1805
  #s(e) {
1806
1806
  let t = P(e.components, { surfaceId: e.surfaceId });
@@ -2122,10 +2122,10 @@ var Et = class {
2122
2122
  perf;
2123
2123
  data;
2124
2124
  policy;
2125
- #e = n(/* @__PURE__ */ new Map());
2125
+ #e = i(/* @__PURE__ */ new Map());
2126
2126
  #t;
2127
2127
  #n = null;
2128
- registry = i(() => this.#e.value);
2128
+ registry = n(() => this.#e.value);
2129
2129
  /** Lazy-initialized A2UI protocol adapter. Only created on first access. */
2130
2130
  get a2ui() {
2131
2131
  return this.#n ||= new R(this), this.#n;
@@ -2187,7 +2187,7 @@ var kt = 200, At = class e {
2187
2187
  history;
2188
2188
  running;
2189
2189
  constructor(e, t) {
2190
- this.#e = e, this.#t = t, this.#n = /* @__PURE__ */ new Map(), this.#r = /* @__PURE__ */ new Map(), this.#c(e.states, void 0), this.#i = n(e.initial), this.#a = n(e.context ? Object.freeze({ ...e.context }) : Object.freeze({})), this.#o = n(Object.freeze([])), this.#s = n(!1), this.currentState = i(() => this.#i.value), this.context = i(() => this.#a.value), this.history = i(() => this.#o.value), this.running = i(() => this.#s.value);
2190
+ this.#e = e, this.#t = t, this.#n = /* @__PURE__ */ new Map(), this.#r = /* @__PURE__ */ new Map(), this.#c(e.states, void 0), this.#i = i(e.initial), this.#a = i(e.context ? Object.freeze({ ...e.context }) : Object.freeze({})), this.#o = i(Object.freeze([])), this.#s = i(!1), this.currentState = n(() => this.#i.value), this.context = n(() => this.#a.value), this.history = n(() => this.#o.value), this.running = n(() => this.#s.value);
2191
2191
  }
2192
2192
  #c(e, t) {
2193
2193
  for (let n of e) this.#n.set(n.id, n), t !== void 0 && this.#r.set(n.id, t), n.children && this.#c(n.children, n.id);
@@ -2451,10 +2451,10 @@ function zt(e) {
2451
2451
  }
2452
2452
  var Bt = class {
2453
2453
  #e;
2454
- #t = n([]);
2454
+ #t = i([]);
2455
2455
  #n = /* @__PURE__ */ new Map();
2456
2456
  #r = /* @__PURE__ */ new Map();
2457
- activeBindings = i(() => this.#t.value);
2457
+ activeBindings = n(() => this.#t.value);
2458
2458
  constructor(e) {
2459
2459
  this.#e = e;
2460
2460
  }
@@ -1374,21 +1374,6 @@
1374
1374
 
1375
1375
 
1376
1376
 
1377
- /* ── Popover Anchor Positioning ──
1378
- Shared anchor-to-trigger positioning for dropdown popovers.
1379
- Coordinators (select, combobox) use this for their popover listbox. */
1380
-
1381
- :where(ui-select) > :where(ui-listbox[popover]),
1382
- :where(ui-combobox) > :where(ui-listbox[popover]) {
1383
- position: fixed;
1384
- position-area: block-end span-inline-end;
1385
- position-try-fallbacks: flip-block;
1386
- margin: var(--ui-popover-gap) 0 0;
1387
- min-width: anchor-size(inline);
1388
- max-height: var(--ui-popover-max-height);
1389
- overflow-y: auto;
1390
- }
1391
-
1392
1377
  /* ── Container-Level Disabled ──
1393
1378
  Containers that disable all children use aria-disabled="true".
1394
1379
  Disabled colors propagate via inheritance — children inherit the muted text.
@@ -1510,6 +1495,7 @@
1510
1495
  /* Popover (select / combobox / command) */
1511
1496
  --ui-popover-max-height: calc(100dvh - 2rem);
1512
1497
  --ui-popover-gap: 0.25rem;
1498
+ --ui-popover-viewport-margin: 0.5rem;
1513
1499
 
1514
1500
  /* Drawer */
1515
1501
  --ui-drawer-width: 24rem;
@@ -3218,6 +3204,23 @@
3218
3204
  cursor: text;
3219
3205
  }
3220
3206
 
3207
+ /* ── Popover Listbox Positioning ──
3208
+ WHY: Must come after ui-listbox.css base rule (which sets min-width: 0
3209
+ for flex-child shrinking) so min-width: anchor-size(inline) wins by
3210
+ source order — both are zero-specificity via :where(). */
3211
+
3212
+ :where(ui-combobox) > :where(ui-listbox[popover]) {
3213
+ position: fixed;
3214
+ position-area: block-end span-inline-end;
3215
+ position-try-fallbacks: flip-block;
3216
+ margin-block: var(--ui-popover-viewport-margin);
3217
+ margin-inline: 0;
3218
+ margin-block-start: var(--ui-popover-gap);
3219
+ min-width: anchor-size(inline);
3220
+ max-height: var(--ui-popover-max-height);
3221
+ overflow-y: auto;
3222
+ }
3223
+
3221
3224
  }
3222
3225
 
3223
3226
  @layer ui {
@@ -3878,6 +3881,39 @@
3878
3881
  display: none;
3879
3882
  }
3880
3883
 
3884
+ /* ── Popover Animation ──
3885
+ WHY: Shared entry/exit transition for all popover listboxes.
3886
+ Context CSS overrides --_popover-origin and --_popover-from
3887
+ to match the popover's anchor direction (e.g. sidebar flyouts
3888
+ open to the right → rotateY instead of rotateX). */
3889
+
3890
+ :where(ui-listbox[popover]) {
3891
+ --_popover-origin: top center;
3892
+ --_popover-from: perspective(800px) scale(0.96) rotateX(-20deg);
3893
+
3894
+ transform-origin: var(--_popover-origin);
3895
+ opacity: 0;
3896
+ transform: var(--_popover-from);
3897
+
3898
+ transition:
3899
+ opacity var(--_duration) var(--_easing),
3900
+ transform var(--_duration) var(--_easing),
3901
+ display var(--_duration) var(--_easing) allow-discrete,
3902
+ overlay var(--_duration) var(--_easing) allow-discrete;
3903
+ }
3904
+
3905
+ :where(ui-listbox[popover]):popover-open {
3906
+ opacity: 1;
3907
+ transform: none;
3908
+ }
3909
+
3910
+ @starting-style {
3911
+ :where(ui-listbox[popover]):popover-open {
3912
+ opacity: 0;
3913
+ transform: var(--_popover-from);
3914
+ }
3915
+ }
3916
+
3881
3917
  /* ── Option / Command Item Base ── */
3882
3918
 
3883
3919
  :where(ui-option, ui-command-item, [role="option"]) {
@@ -4258,10 +4294,14 @@
4258
4294
  instead of expanding the <details>. Same pattern as sidebar-trigger menus. */
4259
4295
 
4260
4296
  :where(ui-nav-group) > :where(ui-listbox.nav-group-flyout[popover]) {
4297
+ --_popover-origin: left center;
4298
+ --_popover-from: perspective(800px) scale(0.96) rotateY(20deg);
4299
+
4261
4300
  position: fixed;
4262
4301
  position-area: inline-end span-block-end;
4263
4302
  position-try-fallbacks: --nav-flyout-flip-up;
4264
- margin: 0;
4303
+ margin-block: var(--ui-popover-viewport-margin);
4304
+ margin-inline: 0;
4265
4305
  margin-inline-start: var(--ui-popover-gap);
4266
4306
  min-width: 200px;
4267
4307
  max-height: var(--ui-popover-max-height);
@@ -4272,6 +4312,10 @@
4272
4312
  position-area: inline-end span-block-start;
4273
4313
  }
4274
4314
 
4315
+ @position-try --nav-flyout-flip-down {
4316
+ position-area: inline-end span-block-end;
4317
+ }
4318
+
4275
4319
  /* ── Container Query: Collapsed Sidebar ── */
4276
4320
  /* WHY: Nav components own their own collapsed behavior via @container.
4277
4321
  The sidebar aside declares container-name: sidebar. When it shrinks
@@ -4315,6 +4359,14 @@
4315
4359
  font-size: var(--_font-size, 1rem);
4316
4360
  }
4317
4361
 
4362
+ /* WHY: In collapsed mode the group is a small icon — centering
4363
+ the flyout vertically with the anchor is more natural than top-aligning.
4364
+ Fallbacks handle viewport clipping (top/bottom edge). */
4365
+ :where(ui-nav-group) > :where(ui-listbox.nav-group-flyout[popover]) {
4366
+ position-area: inline-end;
4367
+ position-try-fallbacks: --nav-flyout-flip-up, --nav-flyout-flip-down;
4368
+ }
4369
+
4318
4370
  /* Collapse inter-group spacing in icon rail. */
4319
4371
  :where(ui-nav-group) + :where(ui-nav-group) {
4320
4372
  margin-block-start: 0;
@@ -4548,6 +4600,8 @@
4548
4600
  min-width: 0;
4549
4601
  align-items: center;
4550
4602
  position: relative;
4603
+ /* WHY: Isolate internal z-index (thumb z-index: 1) from parent stacking context */
4604
+ isolation: isolate;
4551
4605
 
4552
4606
  min-height: var(--_track-height);
4553
4607
 
@@ -4829,6 +4883,23 @@
4829
4883
  display: contents;
4830
4884
  }
4831
4885
 
4886
+ /* ── Popover Listbox Positioning ──
4887
+ WHY: Must come after ui-listbox.css base rule (which sets min-width: 0
4888
+ for flex-child shrinking) so min-width: anchor-size(inline) wins by
4889
+ source order — both are zero-specificity via :where(). */
4890
+
4891
+ :where(ui-select) > :where(ui-listbox[popover]) {
4892
+ position: fixed;
4893
+ position-area: block-end span-inline-end;
4894
+ position-try-fallbacks: flip-block;
4895
+ margin-block: var(--ui-popover-viewport-margin);
4896
+ margin-inline: 0;
4897
+ margin-block-start: var(--ui-popover-gap);
4898
+ min-width: anchor-size(inline);
4899
+ max-height: var(--ui-popover-max-height);
4900
+ overflow-y: auto;
4901
+ }
4902
+
4832
4903
  }
4833
4904
 
4834
4905
  @layer ui {
@@ -5955,7 +6026,7 @@
5955
6026
  /* Default placement: above the anchor */
5956
6027
  position-area: block-start;
5957
6028
  position-try-fallbacks: flip-block, flip-inline;
5958
- margin: 0;
6029
+ margin: var(--ui-popover-viewport-margin);
5959
6030
 
5960
6031
  max-width: var(--ui-tooltip-max-width);
5961
6032
  padding-block: calc(var(--_space) * 1.5);
@@ -5977,8 +6048,12 @@
5977
6048
  inset: unset;
5978
6049
  overflow: visible;
5979
6050
 
6051
+ --_popover-origin: bottom center;
6052
+ --_popover-from: perspective(800px) scale(0.96) rotateX(10deg);
6053
+
6054
+ transform-origin: var(--_popover-origin);
5980
6055
  opacity: 0;
5981
- transform: scale(0.96);
6056
+ transform: var(--_popover-from);
5982
6057
  transition:
5983
6058
  opacity var(--_duration) var(--_easing),
5984
6059
  transform var(--_duration) var(--_easing),
@@ -5990,35 +6065,43 @@
5990
6065
 
5991
6066
  :where(ui-tooltip[popover]):popover-open {
5992
6067
  opacity: 1;
5993
- transform: scale(1);
6068
+ transform: none;
5994
6069
  }
5995
6070
 
5996
6071
  /* Starting style for entry animation */
5997
6072
  @starting-style {
5998
6073
  :where(ui-tooltip[popover]):popover-open {
5999
6074
  opacity: 0;
6000
- transform: scale(0.96);
6075
+ transform: var(--_popover-from);
6001
6076
  }
6002
6077
  }
6003
6078
 
6004
6079
  /* ── Placement Variants ── */
6005
6080
 
6006
6081
  :where(ui-tooltip[placement="top"]) {
6082
+ --_popover-origin: bottom center;
6083
+ --_popover-from: perspective(800px) scale(0.96) rotateX(10deg);
6007
6084
  position-area: block-start;
6008
6085
  margin-block-end: calc(var(--_space) * 2);
6009
6086
  }
6010
6087
 
6011
6088
  :where(ui-tooltip[placement="bottom"]) {
6089
+ --_popover-origin: top center;
6090
+ --_popover-from: perspective(800px) scale(0.96) rotateX(-10deg);
6012
6091
  position-area: block-end;
6013
6092
  margin-block-start: calc(var(--_space) * 2);
6014
6093
  }
6015
6094
 
6016
6095
  :where(ui-tooltip[placement="left"]) {
6096
+ --_popover-origin: right center;
6097
+ --_popover-from: perspective(800px) scale(0.96) rotateY(-10deg);
6017
6098
  position-area: inline-start;
6018
6099
  margin-inline-end: calc(var(--_space) * 2);
6019
6100
  }
6020
6101
 
6021
6102
  :where(ui-tooltip[placement="right"]) {
6103
+ --_popover-origin: left center;
6104
+ --_popover-from: perspective(800px) scale(0.96) rotateY(10deg);
6022
6105
  position-area: inline-end;
6023
6106
  margin-inline-start: calc(var(--_space) * 2);
6024
6107
  }
@@ -7007,10 +7090,14 @@
7007
7090
  Flip: bottom-aligned, grows upward (span-block-start). */
7008
7091
 
7009
7092
  :where(ui-layout-sidebar-item) > :where(ui-listbox[popover]) {
7093
+ --_popover-origin: left center;
7094
+ --_popover-from: perspective(800px) scale(0.96) rotateY(20deg);
7095
+
7010
7096
  position: fixed;
7011
7097
  position-area: inline-end span-block-end;
7012
7098
  position-try-fallbacks: --sidebar-item-flip-up;
7013
- margin: 0;
7099
+ margin-block: var(--ui-popover-viewport-margin);
7100
+ margin-inline: 0;
7014
7101
  margin-inline-start: var(--ui-popover-gap);
7015
7102
  min-width: 200px;
7016
7103
  max-height: var(--ui-popover-max-height);
@@ -7021,6 +7108,10 @@
7021
7108
  position-area: inline-end span-block-start;
7022
7109
  }
7023
7110
 
7111
+ @position-try --sidebar-item-flip-down {
7112
+ position-area: inline-end span-block-end;
7113
+ }
7114
+
7024
7115
  /* ── Container Query: Collapsed Sidebar ── */
7025
7116
  /* WHY: Each component owns its own collapsed behavior via @container.
7026
7117
  The aside is the container (container-name: sidebar). When it shrinks
@@ -7061,6 +7152,14 @@
7061
7152
  :where(ui-layout-sidebar-item) > :where(:not([slot="icon"]):not(ui-listbox[popover]):not(.nav-group-flyout)) {
7062
7153
  display: none;
7063
7154
  }
7155
+
7156
+ /* WHY: In collapsed mode the sidebar item is a small icon — centering
7157
+ the popover vertically with the anchor is more natural than top-aligning.
7158
+ Fallbacks handle viewport clipping (top/bottom edge). */
7159
+ :where(ui-layout-sidebar-item) > :where(ui-listbox[popover]) {
7160
+ position-area: inline-end;
7161
+ position-try-fallbacks: --sidebar-item-flip-up, --sidebar-item-flip-down;
7162
+ }
7064
7163
  }
7065
7164
 
7066
7165
  }