@nxgt/material 3.77.0 → 3.79.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/README.md +1 -1
  3. package/dist/{calculator-DSSaYRmM.js → calculator-KqIMBXSh.js} +2 -2
  4. package/dist/calculator-field.js +1 -1
  5. package/dist/calculator.js +1 -1
  6. package/dist/{components-ZJx47chq.js → components-ConMf2w-.js} +12367 -12323
  7. package/dist/components.js +3 -3
  8. package/dist/editor.js +1 -1
  9. package/dist/{financial-variant-vZdgyMeN.js → financial-variant-CggTpad2.js} +1 -1
  10. package/dist/lib/components/ui/actions/back-link/back-link.d.ts +12 -3
  11. package/dist/lib/components/ui/collections/server-table/partials/server-table-band.d.ts +2 -2
  12. package/dist/lib/components/ui/collections/server-table/partials/server-table-grid-sorting.d.ts +6 -0
  13. package/dist/lib/components/ui/collections/server-table/partials/server-table-passed-through.d.ts +1 -0
  14. package/dist/lib/components/ui/collections/server-table/types.d.ts +1 -1
  15. package/dist/lib/components/ui/feedback/state-frame/scene-registry.d.ts +24 -4
  16. package/dist/lib/components/ui/primitives/tabs/tabs-clipped.d.ts +9 -0
  17. package/dist/lib/components/ui/primitives/tabs/tabs-overflow-classes.d.ts +1 -1
  18. package/dist/lib/components/ui/primitives/tabs/tabs-overflow-state.d.ts +11 -0
  19. package/dist/lib/components/ui/primitives/tabs/use-tabs-overflow.d.ts +2 -9
  20. package/dist/lib/components/ui/selection/sortable-list/partials/sortable-list-frame.d.ts +2 -1
  21. package/dist/lib/components/ui/selection/sortable-list/sortable-list.d.ts +3 -1
  22. package/dist/lib/components/ui/widgets/event-calendar/partials/calendar-view-toggle.d.ts +2 -1
  23. package/dist/lib/illustrations/index.d.ts +1 -1
  24. package/dist/main.js +3 -3
  25. package/dist/material.css +1 -1
  26. package/dist/{tabs-BT9pSRwk.js → tabs-KGKvve3y.js} +101 -93
  27. package/dist/{use-chat-composer-BOx4I6Ma.js → use-chat-composer-BFhRMHcX.js} +1 -1
  28. package/docs/components/buttons-and-actions.md +9 -1
  29. package/docs/components/data-table-filter-and-lists.md +8 -4
  30. package/docs/components/primitives.md +4 -4
  31. package/docs/components/selection-and-choice.md +2 -1
  32. package/docs/guides/illustrations.md +34 -1
  33. package/package.json +1 -1
@@ -34,7 +34,7 @@ var ae = Object.defineProperty, x = (e, t) => ae(e, "name", {
34
34
  ref: t
35
35
  })
36
36
  });
37
- }, "Tabs")), ue = "TabsList", T = /* @__PURE__ */ p.forwardRef(/* @__PURE__ */ x(function(e, t) {
37
+ }, "Tabs")), ue = "TabsList", de = /* @__PURE__ */ p.forwardRef(/* @__PURE__ */ x(function(e, t) {
38
38
  let { __scopeTabs: r, loop: i = !0, ...a } = e, o = w(ue, r);
39
39
  return /* @__PURE__ */ y(l, {
40
40
  asChild: !0,
@@ -49,8 +49,8 @@ var ae = Object.defineProperty, x = (e, t) => ae(e, "name", {
49
49
  ref: t
50
50
  })
51
51
  });
52
- }, "TabsList")), E = "TabsTrigger", D = /* @__PURE__ */ p.forwardRef(/* @__PURE__ */ x(function(e, t) {
53
- let { __scopeTabs: i, value: a, disabled: o = !1, ...s } = e, c = w(E, i), l = C(i), u = k(c.baseId, a), f = A(c.baseId, a), p = a === c.value;
52
+ }, "TabsList")), T = "TabsTrigger", E = /* @__PURE__ */ p.forwardRef(/* @__PURE__ */ x(function(e, t) {
53
+ let { __scopeTabs: i, value: a, disabled: o = !1, ...s } = e, c = w(T, i), l = C(i), u = D(c.baseId, a), f = O(c.baseId, a), p = a === c.value;
54
54
  return /* @__PURE__ */ y(d, {
55
55
  asChild: !0,
56
56
  ...l,
@@ -79,8 +79,8 @@ var ae = Object.defineProperty, x = (e, t) => ae(e, "name", {
79
79
  })
80
80
  })
81
81
  });
82
- }, "TabsTrigger")), O = "TabsContent", de = /* @__PURE__ */ p.forwardRef(/* @__PURE__ */ x(function(e, t) {
83
- let { __scopeTabs: r, value: i, forceMount: a, children: s, ...c } = e, l = w(O, r), u = k(l.baseId, i), d = A(l.baseId, i), f = i === l.value, m = p.useRef(f);
82
+ }, "TabsTrigger")), fe = "TabsContent", pe = /* @__PURE__ */ p.forwardRef(/* @__PURE__ */ x(function(e, t) {
83
+ let { __scopeTabs: r, value: i, forceMount: a, children: s, ...c } = e, l = w(fe, r), u = D(l.baseId, i), d = O(l.baseId, i), f = i === l.value, m = p.useRef(f);
84
84
  return p.useEffect(() => {
85
85
  let e = requestAnimationFrame(() => m.current = !1);
86
86
  return () => cancelAnimationFrame(e);
@@ -104,55 +104,68 @@ var ae = Object.defineProperty, x = (e, t) => ae(e, "name", {
104
104
  })
105
105
  });
106
106
  }, "TabsContent"));
107
- function k(e, t) {
107
+ function D(e, t) {
108
108
  return `${e}-trigger-${t}`;
109
109
  }
110
- x(k, "makeTriggerId");
111
- function A(e, t) {
110
+ x(D, "makeTriggerId");
111
+ function O(e, t) {
112
112
  return `${e}-content-${t}`;
113
113
  }
114
- x(A, "makeContentId");
115
- var fe = le, pe = T, me = D, he = de;
114
+ x(O, "makeContentId");
115
+ var me = le, he = de, ge = E, _e = pe;
116
116
  //#endregion
117
117
  //#region lib/components/ui/primitives/tabs/tabs-classes.ts
118
- function j(e) {
118
+ function k(e) {
119
119
  return e === "segmented" || e === "line" ? "segmented" : "underline";
120
120
  }
121
- var M = "aria-[orientation=vertical]:flex-col", ge = {
121
+ var A = "aria-[orientation=vertical]:flex-col", ve = {
122
122
  underline: "flex min-w-0 flex-col gap-2 items-stretch data-[orientation=vertical]:flex-row",
123
123
  segmented: "flex min-w-0 flex-col gap-2 items-start data-[orientation=vertical]:flex-row"
124
- }, N = {
125
- underline: `group/tabs-list relative flex gap-1 border-b border-border overflow-x-auto [scrollbar-width:none] [&::-webkit-scrollbar]:hidden ${M} aria-[orientation=vertical]:border-b-0 aria-[orientation=vertical]:border-l aria-[orientation=vertical]:overflow-x-visible aria-[orientation=vertical]:overflow-y-auto`,
126
- segmented: `group/tabs-list relative inline-flex max-w-full rounded-full bg-muted p-1 overflow-x-auto [scrollbar-width:none] [&::-webkit-scrollbar]:hidden ${M} aria-[orientation=vertical]:rounded-3xl aria-[orientation=vertical]:overflow-x-visible aria-[orientation=vertical]:overflow-y-auto`
127
- }, P = "relative inline-flex shrink-0 cursor-pointer select-none items-center justify-center gap-2 whitespace-nowrap text-sm font-medium text-muted-foreground transition-colors disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=size-])]:size-4 focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-primary dark:focus-visible:outline-track-fill", F = "group-data-[indicator=ready]/tabs-list:after:hidden", I = {
128
- underline: `${P} h-10 px-4 rounded-t-md hover:bg-primary/5 data-[state=inactive]:hover:text-foreground data-[state=active]:text-primary-text data-[orientation=vertical]:justify-start data-[orientation=vertical]:rounded-t-none data-[orientation=vertical]:rounded-r-md after:pointer-events-none after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 after:rounded-full data-[state=active]:after:bg-primary dark:data-[state=active]:after:bg-track-fill data-[orientation=vertical]:after:inset-x-auto data-[orientation=vertical]:after:left-0 data-[orientation=vertical]:after:inset-y-0 data-[orientation=vertical]:after:h-auto data-[orientation=vertical]:after:w-0.5 ${F}`,
129
- segmented: `${P} z-10 h-8 px-4 rounded-full data-[state=inactive]:hover:text-foreground data-[state=active]:text-foreground data-[state=active]:font-semibold after:pointer-events-none after:absolute after:inset-0 after:-z-10 after:rounded-full data-[state=active]:after:bg-background data-[state=active]:after:shadow-sm data-[state=active]:after:border data-[state=active]:after:border-muted-foreground dark:data-[state=active]:after:bg-card ${F}`
130
- }, L = "pointer-events-none absolute left-0 invisible group-data-[indicator=ready]/tabs-list:visible group-data-[indicator=ready]/tabs-list:motion-safe:transition-[translate,width,height] duration-300 ease-out", _e = {
131
- underline: `${L} bottom-0 h-0.5 rounded-full bg-primary dark:bg-track-fill w-(--tabs-indicator-w) translate-x-(--tabs-indicator-x) group-aria-[orientation=vertical]/tabs-list:bottom-auto group-aria-[orientation=vertical]/tabs-list:top-0 group-aria-[orientation=vertical]/tabs-list:w-0.5 group-aria-[orientation=vertical]/tabs-list:h-(--tabs-indicator-w) group-aria-[orientation=vertical]/tabs-list:translate-x-0 group-aria-[orientation=vertical]/tabs-list:translate-y-(--tabs-indicator-x)`,
132
- segmented: `${L} inset-y-1 rounded-full bg-background shadow-sm border border-muted-foreground dark:bg-card w-(--tabs-indicator-w) translate-x-(--tabs-indicator-x) group-aria-[orientation=vertical]/tabs-list:inset-y-auto group-aria-[orientation=vertical]/tabs-list:inset-x-1 group-aria-[orientation=vertical]/tabs-list:top-0 group-aria-[orientation=vertical]/tabs-list:w-auto group-aria-[orientation=vertical]/tabs-list:h-(--tabs-indicator-w) group-aria-[orientation=vertical]/tabs-list:translate-x-0 group-aria-[orientation=vertical]/tabs-list:translate-y-(--tabs-indicator-x)`
133
- }, ve = "inline-flex items-center gap-2", R = "flex justify-center", ye = "w-full flex-1 outline-none";
124
+ }, j = {
125
+ underline: `group/tabs-list relative flex gap-1 border-b border-border overflow-x-auto [scrollbar-width:none] [&::-webkit-scrollbar]:hidden ${A} aria-[orientation=vertical]:border-b-0 aria-[orientation=vertical]:border-l aria-[orientation=vertical]:overflow-x-visible aria-[orientation=vertical]:overflow-y-auto`,
126
+ segmented: `group/tabs-list relative inline-flex max-w-full rounded-full bg-muted p-1 overflow-x-auto [scrollbar-width:none] [&::-webkit-scrollbar]:hidden ${A} aria-[orientation=vertical]:rounded-3xl aria-[orientation=vertical]:overflow-x-visible aria-[orientation=vertical]:overflow-y-auto`
127
+ }, M = "relative inline-flex shrink-0 cursor-pointer select-none items-center justify-center gap-2 whitespace-nowrap text-sm font-medium text-muted-foreground transition-colors disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=size-])]:size-4 focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-primary dark:focus-visible:outline-track-fill", N = "group-data-[indicator=ready]/tabs-list:after:hidden", P = {
128
+ underline: `${M} h-10 px-4 rounded-t-md hover:bg-primary/5 data-[state=inactive]:hover:text-foreground data-[state=active]:text-primary-text data-[orientation=vertical]:justify-start data-[orientation=vertical]:rounded-t-none data-[orientation=vertical]:rounded-r-md after:pointer-events-none after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 after:rounded-full data-[state=active]:after:bg-primary dark:data-[state=active]:after:bg-track-fill data-[orientation=vertical]:after:inset-x-auto data-[orientation=vertical]:after:left-0 data-[orientation=vertical]:after:inset-y-0 data-[orientation=vertical]:after:h-auto data-[orientation=vertical]:after:w-0.5 ${N}`,
129
+ segmented: `${M} z-10 h-8 px-4 rounded-full data-[state=inactive]:hover:text-foreground data-[state=active]:text-foreground data-[state=active]:font-semibold after:pointer-events-none after:absolute after:inset-0 after:-z-10 after:rounded-full data-[state=active]:after:bg-background data-[state=active]:after:shadow-sm data-[state=active]:after:border data-[state=active]:after:border-muted-foreground dark:data-[state=active]:after:bg-card ${N}`
130
+ }, F = "pointer-events-none absolute left-0 invisible group-data-[indicator=ready]/tabs-list:visible group-data-[indicator=ready]/tabs-list:motion-safe:transition-[translate,width,height] duration-300 ease-out", ye = {
131
+ underline: `${F} bottom-0 h-0.5 rounded-full bg-primary dark:bg-track-fill w-(--tabs-indicator-w) translate-x-(--tabs-indicator-x) group-aria-[orientation=vertical]/tabs-list:bottom-auto group-aria-[orientation=vertical]/tabs-list:top-0 group-aria-[orientation=vertical]/tabs-list:w-0.5 group-aria-[orientation=vertical]/tabs-list:h-(--tabs-indicator-w) group-aria-[orientation=vertical]/tabs-list:translate-x-0 group-aria-[orientation=vertical]/tabs-list:translate-y-(--tabs-indicator-x)`,
132
+ segmented: `${F} inset-y-1 rounded-full bg-background shadow-sm border border-muted-foreground dark:bg-card w-(--tabs-indicator-w) translate-x-(--tabs-indicator-x) group-aria-[orientation=vertical]/tabs-list:inset-y-auto group-aria-[orientation=vertical]/tabs-list:inset-x-1 group-aria-[orientation=vertical]/tabs-list:top-0 group-aria-[orientation=vertical]/tabs-list:w-auto group-aria-[orientation=vertical]/tabs-list:h-(--tabs-indicator-w) group-aria-[orientation=vertical]/tabs-list:translate-x-0 group-aria-[orientation=vertical]/tabs-list:translate-y-(--tabs-indicator-x)`
133
+ }, be = "inline-flex items-center gap-2", xe = "flex justify-center", Se = "w-full flex-1 outline-none";
134
134
  //#endregion
135
135
  //#region lib/components/ui/primitives/tabs/partials/tabs-content.tsx
136
- function be({ className: t, ...n }) {
137
- return /* @__PURE__ */ y(he, {
136
+ function Ce({ className: t, ...n }) {
137
+ return /* @__PURE__ */ y(_e, {
138
138
  "data-slot": "tabs-content",
139
- className: e(ye, t),
139
+ className: e(Se, t),
140
140
  ...n
141
141
  });
142
142
  }
143
143
  //#endregion
144
144
  //#region lib/components/ui/primitives/tabs/tabs-overflow-classes.ts
145
- var z = "[--tabs-cue:2rem] pointer-coarse:[--tabs-cue:3rem] data-[overflow-left]:[--tabs-inset-left:var(--tabs-cue)] data-[overflow-left]:[--tabs-fade-left:calc(var(--tabs-cue)_+_1rem)] data-[overflow-right]:[--tabs-inset-right:var(--tabs-cue)] data-[overflow-right]:[--tabs-fade-right:calc(var(--tabs-cue)_+_1rem)] data-[overflow-left]:[mask-image:linear-gradient(to_right,transparent_var(--tabs-inset-left,0px),#000_var(--tabs-fade-left,0px),#000_calc(100%_-_var(--tabs-fade-right,0px)),transparent_calc(100%_-_var(--tabs-inset-right,0px)))] data-[overflow-right]:[mask-image:linear-gradient(to_right,transparent_var(--tabs-inset-left,0px),#000_var(--tabs-fade-left,0px),#000_calc(100%_-_var(--tabs-fade-right,0px)),transparent_calc(100%_-_var(--tabs-inset-right,0px)))]", xe = "pointer-events-none absolute z-20 overflow-hidden", B = "pointer-events-auto absolute top-1/2 inline-flex size-7 -translate-y-1/2 cursor-pointer items-center justify-center rounded-full border border-border bg-background text-foreground shadow-sm transition-colors hover:bg-muted pointer-coarse:h-full pointer-coarse:max-h-11 pointer-coarse:w-11 focus-visible:outline-2 focus-visible:outline-offset-[-3px] focus-visible:outline-primary dark:focus-visible:outline-track-fill [&_svg]:size-4", Se = `${B} left-1`, Ce = `${B} right-1`, V = m("underline");
146
- function H() {
147
- return g(V);
145
+ var I = "[--tabs-cue:2rem] pointer-coarse:[--tabs-cue:3rem] data-[overflow-left]:[--tabs-inset-left:var(--tabs-cue)] data-[overflow-right]:[--tabs-inset-right:var(--tabs-cue)] data-[overflow-left]:[mask-image:linear-gradient(to_right,transparent_var(--tabs-inset-left,0px),#000_var(--tabs-inset-left,0px),#000_calc(100%_-_var(--tabs-inset-right,0px)),transparent_calc(100%_-_var(--tabs-inset-right,0px)))] data-[overflow-right]:[mask-image:linear-gradient(to_right,transparent_var(--tabs-inset-left,0px),#000_var(--tabs-inset-left,0px),#000_calc(100%_-_var(--tabs-inset-right,0px)),transparent_calc(100%_-_var(--tabs-inset-right,0px)))] [&_[data-clipped]]:opacity-0", we = "pointer-events-none absolute z-20 overflow-hidden", L = "pointer-events-auto absolute top-1/2 inline-flex size-7 -translate-y-1/2 cursor-pointer items-center justify-center rounded-full border border-border bg-background text-foreground shadow-sm transition-colors hover:bg-muted pointer-coarse:h-full pointer-coarse:max-h-11 pointer-coarse:w-11 focus-visible:outline-2 focus-visible:outline-offset-[-3px] focus-visible:outline-primary dark:focus-visible:outline-track-fill [&_svg]:size-4", Te = `${L} left-1`, Ee = `${L} right-1`, R = m("underline");
146
+ function z() {
147
+ return g(R);
148
+ }
149
+ //#endregion
150
+ //#region lib/components/ui/primitives/tabs/tabs-clipped.ts
151
+ function B(e) {
152
+ let t = getComputedStyle(e).getPropertyValue("--tabs-cue").trim(), n = Number.parseFloat(t);
153
+ return Number.isFinite(n) ? t.endsWith("rem") ? n * Number.parseFloat(getComputedStyle(document.documentElement).fontSize) : n : 0;
154
+ }
155
+ function V(e, t, n, r) {
156
+ let i = e.getBoundingClientRect(), a = B(e), o = i.left + (n ? a : 0), s = i.right - (r ? a : 0);
157
+ for (let a of e.querySelectorAll(t.tab)) {
158
+ let e = a.getBoundingClientRect(), c = n && e.left < o - 1 && e.right > i.left || r && e.right > s + 1 && e.left < i.right, l = a.matches(t.active) || a === document.activeElement, u = c && !l;
159
+ u !== a.hasAttribute("data-clipped") && a.toggleAttribute("data-clipped", u);
160
+ }
148
161
  }
149
162
  //#endregion
150
163
  //#region lib/components/ui/primitives/tabs/tabs-manual-scroll.ts
151
- var U = "tabs-manual-scroll";
152
- function we(e) {
153
- e.dispatchEvent(new Event(U));
164
+ var H = "tabs-manual-scroll";
165
+ function De(e) {
166
+ e.dispatchEvent(new Event(H));
154
167
  }
155
- function Te(e, t) {
168
+ function Oe(e, t) {
156
169
  let n = 0, r = 0, i = "", a = () => `${e.clientWidth}/${e.scrollWidth}`, o = { follow: !0 }, s = () => {
157
170
  o.follow = !1;
158
171
  }, c = (e) => {
@@ -160,67 +173,65 @@ function Te(e, t) {
160
173
  }, l = () => {
161
174
  a() === i && (e.scrollLeft < n - 1 || e.scrollLeft > r + 1) && s();
162
175
  };
163
- return i = a(), e.addEventListener("wheel", c, { passive: !0 }), e.addEventListener("scroll", l, { passive: !0 }), e.addEventListener(U, s), {
176
+ return i = a(), e.addEventListener("wheel", c, { passive: !0 }), e.addEventListener("scroll", l, { passive: !0 }), e.addEventListener(H, s), {
164
177
  state: o,
165
178
  reveal(o, s) {
166
179
  let c = e.scrollLeft, l = t(e, o, s);
167
180
  n = Math.min(c, c + l), r = Math.max(c, c + l), i = a();
168
181
  },
169
182
  dispose() {
170
- e.removeEventListener("wheel", c), e.removeEventListener("scroll", l), e.removeEventListener(U, s);
183
+ e.removeEventListener("wheel", c), e.removeEventListener("scroll", l), e.removeEventListener(H, s);
171
184
  }
172
185
  };
173
186
  }
174
187
  //#endregion
175
- //#region lib/components/ui/primitives/tabs/tabs-selectors.ts
176
- var W = "[role=\"tab\"], [data-slot=\"tabs-trigger\"]", G = "[role=\"tab\"][data-state=\"active\"], [data-slot=\"tabs-trigger\"][data-state=\"active\"]", K = 64, q = {
188
+ //#region lib/components/ui/primitives/tabs/tabs-overflow-state.ts
189
+ var U = {
177
190
  left: !1,
178
191
  right: !1,
179
192
  top: 0,
180
193
  x: 0,
181
194
  width: 0,
182
195
  height: 0
196
+ }, W = (e, t) => e.left === t.left && e.right === t.right && e.top === t.top && e.x === t.x && e.width === t.width && e.height === t.height, G = "[role=\"tab\"], [data-slot=\"tabs-trigger\"]", K = "[role=\"tab\"][data-state=\"active\"], [data-slot=\"tabs-trigger\"][data-state=\"active\"]", q = 64, J = {
197
+ tab: G,
198
+ active: K
183
199
  };
184
- function J() {
200
+ function Y() {
185
201
  return window.matchMedia("(prefers-reduced-motion: reduce)").matches ? "instant" : "smooth";
186
202
  }
187
- function Y(e) {
188
- if (e.getAttribute("aria-orientation") === "vertical") return q;
189
- let t = e.scrollWidth - e.clientWidth;
190
- if (t <= 1) return q;
191
- let n = Math.abs(e.scrollLeft), r = n > 1, i = t - n > 1, a = getComputedStyle(e).direction === "rtl";
192
- return {
193
- left: a ? i : r,
194
- right: a ? r : i,
203
+ function X(e, t = J) {
204
+ let n = e.scrollWidth - e.clientWidth;
205
+ if (e.getAttribute("aria-orientation") === "vertical" || n <= 1) return V(e, t, !1, !1), U;
206
+ let r = Math.abs(e.scrollLeft), i = r > 1, a = n - r > 1, o = getComputedStyle(e).direction === "rtl", s = o ? a : i, c = o ? i : a;
207
+ return V(e, t, s, c), {
208
+ left: s,
209
+ right: c,
195
210
  top: e.offsetTop,
196
211
  x: e.offsetLeft,
197
212
  width: e.offsetWidth,
198
213
  height: e.offsetHeight
199
214
  };
200
215
  }
201
- var X = (e, t) => e.left === t.left && e.right === t.right && e.top === t.top && e.x === t.x && e.width === t.width && e.height === t.height;
202
- function Ee(e, t, n = J()) {
216
+ function ke(e, t, n = Y()) {
203
217
  if (e.scrollWidth <= e.clientWidth) return 0;
204
218
  let r = e.getBoundingClientRect(), i = t.getBoundingClientRect(), a = 0;
205
- return i.left < r.left + K ? a = i.left - r.left - K : i.right > r.right - K && (a = i.right - r.right + K), a && e.scrollBy({
219
+ return i.left < r.left + q ? a = i.left - r.left - q : i.right > r.right - q && (a = i.right - r.right + q), a && e.scrollBy({
206
220
  left: a,
207
221
  behavior: n
208
222
  }), a;
209
223
  }
210
- function Z(e, t = {
211
- tab: W,
212
- active: G
213
- }) {
214
- let [n, r] = te(q);
224
+ function Z(e, t = J) {
225
+ let [n, r] = te(U);
215
226
  return _(() => {
216
227
  let n = e.current;
217
228
  if (!n) return;
218
229
  let i = 0, a = () => {
219
230
  cancelAnimationFrame(i), i = requestAnimationFrame(() => {
220
- let e = Y(n);
221
- r((t) => X(t, e) ? t : e);
231
+ let e = X(n, t);
232
+ r((t) => W(t, e) ? t : e);
222
233
  });
223
- }, o = () => n.querySelector(t.active), s = Te(n, Ee), { state: c, reveal: l } = s, u = new ResizeObserver(() => {
234
+ }, o = () => n.querySelector(t.active), s = Oe(n, ke), { state: c, reveal: l } = s, u = new ResizeObserver(() => {
224
235
  a();
225
236
  let e = c.follow ? o() : null;
226
237
  e && l(e, "instant");
@@ -244,35 +255,32 @@ function Z(e, t = {
244
255
  };
245
256
  n.addEventListener("focusin", p), d();
246
257
  let m = o();
247
- return m && l(m, "instant"), r(Y(n)), () => {
258
+ return m && l(m, "instant"), r(X(n, t)), () => {
248
259
  cancelAnimationFrame(i), u.disconnect(), f.disconnect(), n.removeEventListener("focusin", p), s.dispose();
249
260
  };
250
- }, [
251
- e,
252
- t.tab,
253
- t.active
254
- ]), De(e, n.left || n.right, r), n;
261
+ }, [e, t]), Ae(e, n.left || n.right, r, t), n;
255
262
  }
256
- function De(e, t, n) {
263
+ function Ae(e, t, n, r) {
257
264
  ee(() => {
258
- let r = e.current;
259
- if (!r || !t) return;
260
- let i = 0, a = () => {
261
- cancelAnimationFrame(i), i = requestAnimationFrame(() => {
262
- let e = Y(r);
263
- n((t) => X(t, e) ? t : e);
265
+ let i = e.current;
266
+ if (!i || !t) return;
267
+ let a = 0, o = () => {
268
+ cancelAnimationFrame(a), a = requestAnimationFrame(() => {
269
+ let e = X(i, r);
270
+ n((t) => W(t, e) ? t : e);
264
271
  });
265
272
  };
266
- return document.addEventListener("scroll", a, {
273
+ return document.addEventListener("scroll", o, {
267
274
  passive: !0,
268
275
  capture: !0
269
276
  }), () => {
270
- cancelAnimationFrame(i), document.removeEventListener("scroll", a, { capture: !0 });
277
+ cancelAnimationFrame(a), document.removeEventListener("scroll", o, { capture: !0 });
271
278
  };
272
279
  }, [
273
280
  e,
274
281
  t,
275
- n
282
+ n,
283
+ r
276
284
  ]);
277
285
  }
278
286
  //#endregion
@@ -284,14 +292,14 @@ function Q({ look: t }) {
284
292
  if (!e || !t) return;
285
293
  let r = 0, i = () => {
286
294
  cancelAnimationFrame(r), r = requestAnimationFrame(() => {
287
- let n = t.querySelector(G);
295
+ let n = t.querySelector(K);
288
296
  if (!n) return;
289
297
  let r = t.getAttribute("aria-orientation") === "vertical", i = r ? n.offsetHeight : n.offsetWidth, a = r ? n.offsetTop : n.offsetLeft;
290
298
  e.style.setProperty("--tabs-indicator-w", `${i}px`), e.style.setProperty("--tabs-indicator-x", `${a}px`), t.dataset.indicator !== "ready" && (e.offsetWidth, t.dataset.indicator = "ready");
291
299
  });
292
300
  }, a = new ResizeObserver(i), o = () => {
293
301
  a.disconnect(), a.observe(t);
294
- for (let e of t.querySelectorAll(W)) a.observe(e);
302
+ for (let e of t.querySelectorAll(G)) a.observe(e);
295
303
  }, s = new MutationObserver(() => {
296
304
  o(), i();
297
305
  });
@@ -308,7 +316,7 @@ function Q({ look: t }) {
308
316
  ref: n,
309
317
  "aria-hidden": !0,
310
318
  "data-slot": "tabs-indicator",
311
- className: e(_e[t])
319
+ className: e(ye[t])
312
320
  });
313
321
  }
314
322
  //#endregion
@@ -319,11 +327,11 @@ function $({ list: e, overflow: t }) {
319
327
  let r = (t) => {
320
328
  let n = e.current;
321
329
  if (!n) return;
322
- we(n);
330
+ De(n);
323
331
  let r = Math.max(96, n.clientWidth * .75);
324
332
  n.scrollBy({
325
333
  left: t * r,
326
- behavior: J()
334
+ behavior: Y()
327
335
  });
328
336
  }, i = {
329
337
  type: "button",
@@ -332,7 +340,7 @@ function $({ list: e, overflow: t }) {
332
340
  };
333
341
  return /* @__PURE__ */ b("div", {
334
342
  "data-slot": "tabs-scroll",
335
- className: xe,
343
+ className: we,
336
344
  style: {
337
345
  top: t.top,
338
346
  left: t.x,
@@ -343,14 +351,14 @@ function $({ list: e, overflow: t }) {
343
351
  ...i,
344
352
  "data-slot": "tabs-scroll-left",
345
353
  "aria-label": n("material.tabs.scroll-left", "Scroll tabs left"),
346
- className: Se,
354
+ className: Te,
347
355
  onClick: () => r(-1),
348
356
  children: /* @__PURE__ */ y(re, { "aria-hidden": !0 })
349
357
  }), t.right && /* @__PURE__ */ y("button", {
350
358
  ...i,
351
359
  "data-slot": "tabs-scroll-right",
352
360
  "aria-label": n("material.tabs.scroll-right", "Scroll tabs right"),
353
- className: Ce,
361
+ className: Ee,
354
362
  onClick: () => r(1),
355
363
  children: /* @__PURE__ */ y(ie, { "aria-hidden": !0 })
356
364
  })]
@@ -358,9 +366,9 @@ function $({ list: e, overflow: t }) {
358
366
  }
359
367
  //#endregion
360
368
  //#region lib/components/ui/primitives/tabs/partials/tabs-list.tsx
361
- function Oe({ className: n, children: r, ref: i, ...a }) {
362
- let o = H(), s = v(null), c = Z(s);
363
- return /* @__PURE__ */ b(ne, { children: [/* @__PURE__ */ b(pe, {
369
+ function je({ className: n, children: r, ref: i, ...a }) {
370
+ let o = z(), s = v(null), c = Z(s);
371
+ return /* @__PURE__ */ b(ne, { children: [/* @__PURE__ */ b(he, {
364
372
  ref: h((e) => {
365
373
  s.current = e, typeof i == "function" ? i(e) : i && (i.current = e);
366
374
  }, [i]),
@@ -368,7 +376,7 @@ function Oe({ className: n, children: r, ref: i, ...a }) {
368
376
  "data-pw": "tabs-list",
369
377
  "data-overflow-left": c.left ? "" : void 0,
370
378
  "data-overflow-right": c.right ? "" : void 0,
371
- className: e(N[o], z, n),
379
+ className: e(j[o], I, n),
372
380
  ...a,
373
381
  children: [/* @__PURE__ */ y(t, { children: r }), /* @__PURE__ */ y(Q, { look: o })]
374
382
  }), /* @__PURE__ */ y($, {
@@ -378,10 +386,10 @@ function Oe({ className: n, children: r, ref: i, ...a }) {
378
386
  }
379
387
  //#endregion
380
388
  //#region lib/components/ui/primitives/tabs/partials/tabs-trigger.tsx
381
- function ke({ className: n, children: r, icon: i, ...a }) {
382
- return /* @__PURE__ */ b(me, {
389
+ function Me({ className: n, children: r, icon: i, ...a }) {
390
+ return /* @__PURE__ */ b(ge, {
383
391
  "data-slot": "tabs-trigger",
384
- className: e(I[H()], n),
392
+ className: e(P[z()], n),
385
393
  ...a,
386
394
  children: [i && /* @__PURE__ */ y("span", {
387
395
  "data-slot": "tabs-trigger-icon",
@@ -398,17 +406,17 @@ function ke({ className: n, children: r, icon: i, ...a }) {
398
406
  }
399
407
  //#endregion
400
408
  //#region lib/components/ui/primitives/tabs/tabs.tsx
401
- function Ae({ className: t, variant: n = "underline", ...r }) {
402
- let i = j(n);
403
- return /* @__PURE__ */ y(V.Provider, {
409
+ function Ne({ className: t, variant: n = "underline", ...r }) {
410
+ let i = k(n);
411
+ return /* @__PURE__ */ y(R.Provider, {
404
412
  value: i,
405
- children: /* @__PURE__ */ y(fe, {
413
+ children: /* @__PURE__ */ y(me, {
406
414
  "data-slot": "tabs",
407
415
  "data-variant": n,
408
- className: e(ge[i], t),
416
+ className: e(ve[i], t),
409
417
  ...r
410
418
  })
411
419
  });
412
420
  }
413
421
  //#endregion
414
- export { Q as a, H as c, R as d, ve as f, j as h, $ as i, z as l, I as m, ke as n, Z as o, N as p, Oe as r, V as s, Ae as t, be as u };
422
+ export { Q as a, z as c, xe as d, be as f, k as h, $ as i, I as l, P as m, Me as n, Z as o, j as p, je as r, R as s, Ne as t, Ce as u };
@@ -14,7 +14,7 @@ import { D as je, E as Me, N as Ne, O as Pe, c as Fe, d as Ie, f as Le, i as Re,
14
14
  import { a as Ke, i as qe, n as Je } from "./field-blur-context-BLGgf_3z.js";
15
15
  import { i as Ye, n as Xe, r as Ze, t as Qe } from "./popover-Cd7DkND4.js";
16
16
  import { a as $e, i as et, n as tt, o as nt, t as rt } from "./bubble-input-CQwVSoU3.js";
17
- import { n as it, r as at, t as ot, u as st } from "./tabs-BT9pSRwk.js";
17
+ import { n as it, r as at, t as ot, u as st } from "./tabs-KGKvve3y.js";
18
18
  import { a as ct, n as lt, o as ut, s as dt, v as ft, y as pt } from "./toolbar-items-D310xDuM.js";
19
19
  import { t as mt } from "./dist-DkQbkF9T.js";
20
20
  import { o as ht, s as gt, t as _t } from "./use-click-lock-BZYtTmVt.js";
@@ -931,7 +931,15 @@ It renders one `<a>`. The label names the destination and is the link's accessib
931
931
 
932
932
  It takes every [`LinkButton`](#linkbutton) prop (`to`, `variant`, `color`, `size`, `replace`, `state`, `linkComponent`, ...), so it follows the router or the [`LinkComponentProvider`](./primitives.md#linkcomponentprovider). Only the default differs: `variant` is `'ghost'`.
933
933
 
934
- **Storybook:** `Buttons & actions/BackLink` (`Default`, `LinkStyle`, `Rtl`) · **Vue:** none yet
934
+ In a page header with other actions, `collapse="phone"` keeps only the arrow below 768px, as [`ResponsiveLinkButton`](#linkbutton) does: the label stays in the DOM as the accessible name and, when it is a string, the tooltip, and `variant` and `aria-label` are kept. The collapse is CSS, so the server HTML is right on every device. Unset (the default), the label always shows.
935
+
936
+ ```tsx
937
+ <BackLink to="/items" variant="outlined" collapse="phone">
938
+ Back to items
939
+ </BackLink>
940
+ ```
941
+
942
+ **Storybook:** `Buttons & actions/BackLink` (`Default`, `LinkStyle`, `Rtl`, `CollapsedOnPhone`) · **Vue:** none yet
935
943
 
936
944
  ---
937
945
 
@@ -1083,6 +1083,9 @@ not three:
1083
1083
  "Select all on this page"); at the end, the sort menu, "Filters (N)" and
1084
1084
  the page's `actions`.
1085
1085
 
1086
+ Without `actions`, "Filters (N)" stays beside the search, inside the `search`
1087
+ landmark, and row 2 holds the "Select all" checkbox and the sort menu.
1088
+
1086
1089
  On a phone (below 768px) the "Select all" text shortens with an ellipsis (the box keeps its
1087
1090
  full name) rather than run under the sort, "Filters (N)" or the actions. When
1088
1091
  the end group is too wide to leave the start 6rem, it wraps to a line of its
@@ -1105,8 +1108,8 @@ form (`bulkActions={(ids) => node}`) is drawn whole in the row, so keep it to
1105
1108
  one or two compact buttons; the footer's polite status still tells the selection once. The cards'
1106
1109
  own list bar row is gone in this layout; the names, the sort menu and the
1107
1110
  Filters sheet are the same. A list that cannot be selected has no checkbox
1108
- (row 2 starts with the sort). The table layout, a list without `filter` or
1109
- without `actions`, `variant: 'facets'` and every width from 768px are
1111
+ (row 2 starts with the sort). The table layout, a list without `filter`,
1112
+ `variant: 'facets'` and every width from 768px are
1110
1113
  unchanged, and `bandActions` has no effect while the second row is there.
1111
1114
 
1112
1115
  The row is narrow, so it compacts to the band's width: when the end group is
@@ -1176,7 +1179,7 @@ sprite file's name, or a list of them). On "nothing matches", an `action` in
1176
1179
  `noMatch` replaces "Clear search and filters". The live region speaks the
1177
1180
  page's `title`.
1178
1181
 
1179
- `ServerTable` uses `DataTable`'s `focusable`, `focusRef` (the table, or the list of cards or tiles), `announceLoading`, `announceEmpty`, `filtered` and `pagination.live` (see [DataTable](#datatable)).
1182
+ `ServerTable` takes `focusRef` like `DataTable` (a `Ref<HTMLElement>`, filled with the table, or the list of cards or tiles, beside its own): give it `useRowMenuFocus()`'s so `focusRowMenu(id)` looks only inside that table. It uses `DataTable`'s `focusable`, `focusRef`, `announceLoading`, `announceEmpty`, `filtered` and `pagination.live` (see [DataTable](#datatable)).
1180
1183
 
1181
1184
  **Storybook:** `Data table, filter & lists/ServerTable` (`Error No Loading`, `Error Retry`), `…/ServerTable/Band and empty page`, `…/ServerTable/Phone`, `…/ServerTable/Phone header`, `…/ServerTable/Cards`, `…/ServerTable/Tiles`, `…/ServerTable/Own controls` (`Past The Last Page`, `Slow Router Keeps Search`), `…/ServerTable/Locked rows`, `…/ServerTable/Compact band and icon paging` · **Vue:** `ServerTable`
1182
1185
 
@@ -1308,7 +1311,8 @@ const columns = useMemo(
1308
1311
  <DataTable focusRef={focusRef} getRowId={(p) => p.id} columns={columns} data={people} />;
1309
1312
  ```
1310
1313
 
1311
- `focusRef` scopes the search to that table; without it the whole document is
1314
+ `focusRef` scopes the search to that table (`ServerTable` takes it too, in the
1315
+ table and the cards and tiles layouts); without it the whole document is
1312
1316
  searched. For a dialog, [`onCloseAutoFocus`](#focus-after-a-bulk-action) with
1313
1317
  `preventDefault()` is the precise hook if you want to take the focus yourself.
1314
1318
 
@@ -737,9 +737,9 @@ Parts: `Tabs`, `TabsList`, `TabsTrigger`, `TabsContent`. `TabsList` and
737
737
  takes the primary colour, and a bar under it slides to the tab clicked or
738
738
  reached with the arrow keys. The list scrolls sideways when the tabs do not
739
739
  fit (its scrollbar hidden), which suits a phone or a narrow popover. While it
740
- overflows, each side with hidden tabs fades and gets a small scroll button
740
+ overflows, each side with hidden tabs gets a small scroll button
741
741
  ("Scroll tabs left" / "Scroll tabs right", from `material.tabs.*`; out of the
742
- tab order; on a touch screen 44px wide and as tall as the list, so it never covers content). Under a button the list shows nothing (its edge mask is transparent there and fades in just beyond), so no label is ever cut by the button, even at 375px; the selected and the focused tab are
742
+ tab order; on a touch screen 44px wide and as tall as the list, so it never covers content). Under a button the list shows nothing (its edge mask is transparent there, with a hard edge), and a tab that does not fit whole between the buttons turns transparent (`data-clipped`, still focusable), so a label is shown whole or not at all, even at 375px; the selected and the focused tab are
743
743
  scrolled into view clear of the button, instantly under reduced motion. A list that fits has
744
744
  neither, and neither is in the server markup. `segmented` does the same.
745
745
 
@@ -856,8 +856,8 @@ address can be copied. `aria-label` names the navigation and is required.
856
856
  - **Keyboard**: the links are plain links, so Tab moves from one to the next;
857
857
  the arrow keys do nothing (they are not tabs, there is no `tablist`).
858
858
  - **Looks**: `variant="underline"` (the default) or `"segmented"`, as `Tabs`.
859
- A nav wider than its container scrolls inside itself, with the same edge
860
- fades and scroll buttons as `Tabs`. On a coarse pointer each link is 44px
859
+ A nav wider than its container scrolls inside itself, with the same
860
+ hard-edged mask, clipped tabs (`data-clipped`) and scroll buttons as `Tabs`. On a coarse pointer each link is 44px
861
861
  tall at least. In forced colours the current link keeps a `Highlight` mark.
862
862
  - **The link**: `TabsNavLink` takes `LinkButton`'s props (`to`, `replace`,
863
863
  `state`, `target`, `reloadDocument`, `download`, `linkComponent`) and an
@@ -1145,6 +1145,7 @@ export function Ranking() {
1145
1145
  | `searchable` | `boolean` | `true` | filter box |
1146
1146
  | `height` | `number \| string` | `320` | list height |
1147
1147
  | `required` | `boolean` | — | the asterisk, and `aria-required` on the `listbox`, which the label names |
1148
+ | `hideLabel` | `boolean` | `false` | `true` keeps `label` as the list's accessible name (`aria-labelledby`) but draws nothing, for a heading that already titles it |
1148
1149
  | `numbered` | `boolean` | `false` | each row shows its rank in the whole order |
1149
1150
  | `removable` | `boolean` | `false` | a remove button on each row, and Delete: the row leaves the value |
1150
1151
  | `appearance` | `'cards' \| 'plain'` | `'cards'` | raised cards, or flat rows in one surface |
@@ -1156,7 +1157,7 @@ where it is: no grip, not draggable, not movable from the keyboard, not
1156
1157
  removable).
1157
1158
 
1158
1159
  **Emits:** `string[]`, in the new order.
1159
- **Form wrapper:** `SortableListFormField` — `control` and `name`, see
1160
+ **Form wrapper:** `SortableListFormField` — `control` and `name` plus the same props, `hideLabel` included (the label's `required` asterisk is hidden with it; the `listbox` keeps `aria-required`), see
1160
1161
  [forms](../guides/forms.md#the-pair) and [what each field emits](../guides/forms.md#what-each-field-emits).
1161
1162
  **Storybook:** `Selection & choice/SortableList` · **Vue:** `SortableList`, `SortableListFormField`
1162
1163
 
@@ -120,7 +120,7 @@ in a state, a string that is not a registered id is a node, as before (so the
120
120
  set must be registered for the string shorthand). An app that never imports the
121
121
  subpath does not carry the table. A table of your own is a `SceneTable`
122
122
  (`SceneRow` from `@nxgt/material-core/illustrations`), passed through `sets` or
123
- `scenes`; its ids are not in `SceneId`, so type them with the `scenes` prop. `HEALTH_SUGGESTED_ICONS` (like `SUGGESTED_ICONS`) lists the icon names the set draws, hero first.
123
+ `scenes`; its ids join `SceneId` once you register them ([Scenes of your own](#scenes-of-your-own)). `HEALTH_SUGGESTED_ICONS` (like `SUGGESTED_ICONS`) lists the icon names the set draws, hero first.
124
124
 
125
125
  ## Scene sets: the education scenes
126
126
 
@@ -179,6 +179,39 @@ unrelated to the `night-sky` Background preset. Every icon is in the Free sheet,
179
179
  needs no substitution; `GAME_SUGGESTED_ICONS` lists the names, hero first.
180
180
  Importing the entry adds the ids to `SceneId`.
181
181
 
182
+ ## Scenes of your own
183
+
184
+ A table of your own is a `SceneTable` (a row is `[plate, tone, layout, hero, ...satellites]`). Register it with `IllustrationDefaults` `sets`, and declare its ids once so `scene` accepts them beside the built-in ones, without a cast:
185
+
186
+ The file that holds the `declare module` must be a module (it has an `import` or an `export`), otherwise the declaration replaces the module's types instead of augmenting them.
187
+
188
+ ```tsx
189
+ import type { SceneTable } from '@nxgt/material-core/illustrations';
190
+ import {
191
+ Illustration,
192
+ IllustrationDefaults,
193
+ type SceneTableIds,
194
+ } from '@nxgt/material/illustrations';
195
+
196
+ const MY_SCENES = {
197
+ 'my-scene': ['cookie-9', 'primary', 0, 'star', 'moon', 'heart'],
198
+ } satisfies SceneTable;
199
+
200
+ declare module '@nxgt/material/illustrations' {
201
+ interface RegisteredScenes extends SceneTableIds<typeof MY_SCENES> {}
202
+ }
203
+
204
+ export function Example({ id }: { id: 'empty' | 'my-scene' }) {
205
+ return (
206
+ <IllustrationDefaults sets={[MY_SCENES]}>
207
+ <Illustration scene={id} />
208
+ </IllustrationDefaults>
209
+ );
210
+ }
211
+ ```
212
+
213
+ `RegisteredScenes` is an empty interface: each key is a scene id (the value is ignored). `SceneTableIds<typeof TABLE>` derives the keys of a table, so the augmentation is one line; write `interface RegisteredScenes { 'my-scene': true }` by hand if you prefer. The ids widen `SceneId` (so `RegisteredScene` too) for `Illustration scene`, a state's `illustration` and `emptyIllustration`. The declaration is only types: the table still has to be registered (`sets`) or passed (`scenes={MY_SCENES}`) to be drawn. Passing `scenes={MY_SCENES}` keeps its own typing: `scene` is then one of that table's ids only.
214
+
182
215
  ## Turn them on for an app
183
216
 
184
217
  `IllustrationDefaults` opts a subtree in: every default-size `EmptyState` and
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nxgt/material",
3
- "version": "3.77.0",
3
+ "version": "3.79.0",
4
4
  "license": "MIT",
5
5
  "bugs": {
6
6
  "email": "stevegires@gmail.com"