@nxgt/material 3.76.0 → 3.77.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 (53) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/README.md +2 -2
  3. package/dist/{calculator-BaSMe0SK.js → calculator-DSSaYRmM.js} +2 -2
  4. package/dist/calculator-field.js +2 -2
  5. package/dist/calculator.js +1 -1
  6. package/dist/components/ui/display/chip/chip-hairline.css +19 -0
  7. package/dist/components/ui/display/chip/chip-soft.css +18 -0
  8. package/dist/{components-Ci3Zo8kC.js → components-ZJx47chq.js} +11714 -11637
  9. package/dist/components.js +34 -34
  10. package/dist/{currency-field-BJ9rSrif.js → currency-field-DWHB5oms.js} +3 -2
  11. package/dist/editor.js +1 -1
  12. package/dist/{financial-variant-BsZEa5sF.js → financial-variant-vZdgyMeN.js} +3 -3
  13. package/dist/lib/components/ui/collections/row-menu/use-row-menu-focus.d.ts +11 -1
  14. package/dist/lib/components/ui/collections/server-table/partials/server-table-phone-row.d.ts +1 -1
  15. package/dist/lib/components/ui/display/entity-header/partials/entity-header-actions.d.ts +3 -1
  16. package/dist/lib/components/ui/display/entity-header/partials/entity-header-layout.d.ts +10 -0
  17. package/dist/lib/components/ui/fields/quantity-field/quantity-row.d.ts +4 -3
  18. package/dist/lib/components/ui/layout/app-shell/page-title.d.ts +4 -3
  19. package/dist/lib/components/ui/layout/hero/hero-backdrop.d.ts +7 -0
  20. package/dist/lib/components/ui/layout/hero/hero-parts.d.ts +27 -0
  21. package/dist/lib/components/ui/layout/hero/hero.d.ts +26 -1
  22. package/dist/lib/components/ui/primitives/tabs/tabs-manual-scroll.d.ts +16 -0
  23. package/dist/lib/components/ui/primitives/tabs/use-tabs-overflow.d.ts +1 -1
  24. package/dist/main.js +49 -49
  25. package/dist/material.css +1 -1
  26. package/dist/{percent-field-lahyDJDG.js → percent-field--WIXV5dX.js} +1 -1
  27. package/dist/{tabs-DzEqMb1W.js → tabs-BT9pSRwk.js} +128 -97
  28. package/dist/{use-chat-composer-DMXu9E1O.js → use-chat-composer-BOx4I6Ma.js} +1 -1
  29. package/docs/components/data-display.md +2 -1
  30. package/docs/components/data-table-filter-and-lists.md +13 -1
  31. package/docs/components/form-fields.md +6 -3
  32. package/docs/components/navigation-and-layout.md +29 -1
  33. package/docs/components/selection-and-choice.md +3 -1
  34. package/docs/guides/app-shell.md +6 -4
  35. package/docs/guides/theming.md +5 -5
  36. package/docs/troubleshooting.md +3 -2
  37. package/lib/components/ui/display/chip/chip-hairline.css +19 -0
  38. package/lib/components/ui/display/chip/chip-soft.css +18 -0
  39. package/lib/themes/ambre.css +1 -1
  40. package/lib/themes/ardoise.css +1 -1
  41. package/lib/themes/bleumono.css +1 -1
  42. package/lib/themes/bluemoon.css +1 -1
  43. package/lib/themes/corail.css +2 -2
  44. package/lib/themes/foret.css +1 -1
  45. package/lib/themes/lavande.css +1 -1
  46. package/lib/themes/menthe.css +1 -1
  47. package/lib/themes/ocean.css +1 -1
  48. package/lib/themes/pink.css +2 -2
  49. package/lib/themes/prune.css +1 -1
  50. package/lib/themes/sable.css +1 -1
  51. package/lib/themes/slate.css +1 -1
  52. package/lib/themes/teal.css +3 -3
  53. package/package.json +2 -2
@@ -1,4 +1,4 @@
1
- import { r as e } from "./currency-field-BJ9rSrif.js";
1
+ import { r as e } from "./currency-field-DWHB5oms.js";
2
2
  import { jsx as t } from "react/jsx-runtime";
3
3
  //#region lib/components/ui/fields/percent-field/percent-field.tsx
4
4
  function n({ min: n = 0, max: r = 100, step: i = 1, ...a }) {
@@ -6,20 +6,20 @@ import { i as c, n as l, r as u, t as d } from "./dist-DOK3zo5C.js";
6
6
  import { t as f } from "./use-material-translation-CD6QoVal.js";
7
7
  import * as p from "react";
8
8
  import { createContext as m, useCallback as h, useContext as g, useEffect as ee, useLayoutEffect as _, useRef as v, useState as te } from "react";
9
- import { Fragment as y, jsx as b, jsxs as x } from "react/jsx-runtime";
10
- import { ChevronLeft as ne, ChevronRight as re } from "lucide-react";
9
+ import { Fragment as ne, jsx as y, jsxs as b } from "react/jsx-runtime";
10
+ import { ChevronLeft as re, ChevronRight as ie } from "lucide-react";
11
11
  //#region ../../node_modules/@radix-ui/react-tabs/dist/index.mjs
12
- var S = Object.defineProperty, C = (e, t) => S(e, "name", {
12
+ var ae = Object.defineProperty, x = (e, t) => ae(e, "name", {
13
13
  value: t,
14
14
  configurable: !0
15
- }), w = "Tabs", [ie, ae] = a(w, [u]), T = u(), [oe, E] = ie(w), D = /* @__PURE__ */ p.forwardRef(/* @__PURE__ */ C(function(e, t) {
15
+ }), S = "Tabs", [oe, se] = a(S, [u]), C = u(), [ce, w] = oe(S), le = /* @__PURE__ */ p.forwardRef(/* @__PURE__ */ x(function(e, t) {
16
16
  let { __scopeTabs: r, value: a, onValueChange: o, defaultValue: l, orientation: u = "horizontal", dir: d, activationMode: f = "automatic", ...p } = e, m = c(d), [h, g] = i({
17
17
  prop: a,
18
18
  onChange: o,
19
19
  defaultProp: l ?? "",
20
- caller: w
20
+ caller: S
21
21
  });
22
- return /* @__PURE__ */ b(oe, {
22
+ return /* @__PURE__ */ y(ce, {
23
23
  scope: r,
24
24
  baseId: s(),
25
25
  value: h,
@@ -27,36 +27,36 @@ var S = Object.defineProperty, C = (e, t) => S(e, "name", {
27
27
  orientation: u,
28
28
  dir: m,
29
29
  activationMode: f,
30
- children: /* @__PURE__ */ b(n.div, {
30
+ children: /* @__PURE__ */ y(n.div, {
31
31
  dir: m,
32
32
  "data-orientation": u,
33
33
  ...p,
34
34
  ref: t
35
35
  })
36
36
  });
37
- }, "Tabs")), O = "TabsList", k = /* @__PURE__ */ p.forwardRef(/* @__PURE__ */ C(function(e, t) {
38
- let { __scopeTabs: r, loop: i = !0, ...a } = e, o = E(O, r);
39
- return /* @__PURE__ */ b(l, {
37
+ }, "Tabs")), ue = "TabsList", T = /* @__PURE__ */ p.forwardRef(/* @__PURE__ */ x(function(e, t) {
38
+ let { __scopeTabs: r, loop: i = !0, ...a } = e, o = w(ue, r);
39
+ return /* @__PURE__ */ y(l, {
40
40
  asChild: !0,
41
- ...T(r),
41
+ ...C(r),
42
42
  orientation: o.orientation,
43
43
  dir: o.dir,
44
44
  loop: i,
45
- children: /* @__PURE__ */ b(n.div, {
45
+ children: /* @__PURE__ */ y(n.div, {
46
46
  role: "tablist",
47
47
  "aria-orientation": o.orientation,
48
48
  ...a,
49
49
  ref: t
50
50
  })
51
51
  });
52
- }, "TabsList")), se = "TabsTrigger", ce = /* @__PURE__ */ p.forwardRef(/* @__PURE__ */ C(function(e, t) {
53
- let { __scopeTabs: i, value: a, disabled: o = !1, ...s } = e, c = E(se, i), l = T(i), u = A(c.baseId, a), f = j(c.baseId, a), p = a === c.value;
54
- return /* @__PURE__ */ b(d, {
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;
54
+ return /* @__PURE__ */ y(d, {
55
55
  asChild: !0,
56
56
  ...l,
57
57
  focusable: !o,
58
58
  active: p,
59
- children: /* @__PURE__ */ b(n.button, {
59
+ children: /* @__PURE__ */ y(n.button, {
60
60
  type: "button",
61
61
  role: "tab",
62
62
  "aria-selected": p,
@@ -79,14 +79,14 @@ var S = Object.defineProperty, C = (e, t) => S(e, "name", {
79
79
  })
80
80
  })
81
81
  });
82
- }, "TabsTrigger")), le = "TabsContent", ue = /* @__PURE__ */ p.forwardRef(/* @__PURE__ */ C(function(e, t) {
83
- let { __scopeTabs: r, value: i, forceMount: a, children: s, ...c } = e, l = E(le, r), u = A(l.baseId, i), d = j(l.baseId, i), f = i === l.value, m = p.useRef(f);
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);
84
84
  return p.useEffect(() => {
85
85
  let e = requestAnimationFrame(() => m.current = !1);
86
86
  return () => cancelAnimationFrame(e);
87
- }, []), /* @__PURE__ */ b(o, {
87
+ }, []), /* @__PURE__ */ y(o, {
88
88
  present: a || f,
89
- children: ({ present: r }) => /* @__PURE__ */ b(n.div, {
89
+ children: ({ present: r }) => /* @__PURE__ */ y(n.div, {
90
90
  "data-state": f ? "active" : "inactive",
91
91
  "data-orientation": l.orientation,
92
92
  role: "tabpanel",
@@ -104,37 +104,37 @@ var S = Object.defineProperty, C = (e, t) => S(e, "name", {
104
104
  })
105
105
  });
106
106
  }, "TabsContent"));
107
- function A(e, t) {
107
+ function k(e, t) {
108
108
  return `${e}-trigger-${t}`;
109
109
  }
110
- C(A, "makeTriggerId");
111
- function j(e, t) {
110
+ x(k, "makeTriggerId");
111
+ function A(e, t) {
112
112
  return `${e}-content-${t}`;
113
113
  }
114
- C(j, "makeContentId");
115
- var de = D, fe = k, pe = ce, me = ue;
114
+ x(A, "makeContentId");
115
+ var fe = le, pe = T, me = D, he = de;
116
116
  //#endregion
117
117
  //#region lib/components/ui/primitives/tabs/tabs-classes.ts
118
- function M(e) {
118
+ function j(e) {
119
119
  return e === "segmented" || e === "line" ? "segmented" : "underline";
120
120
  }
121
- var N = "aria-[orientation=vertical]:flex-col", he = {
121
+ var M = "aria-[orientation=vertical]:flex-col", ge = {
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
- }, P = {
125
- underline: `group/tabs-list relative flex gap-1 border-b border-border overflow-x-auto [scrollbar-width:none] [&::-webkit-scrollbar]:hidden ${N} 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 ${N} aria-[orientation=vertical]:rounded-3xl aria-[orientation=vertical]:overflow-x-visible aria-[orientation=vertical]:overflow-y-auto`
127
- }, F = "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", I = "group-data-[indicator=ready]/tabs-list:after:hidden", L = {
128
- underline: `${F} 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 ${I}`,
129
- segmented: `${F} 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 ${I}`
130
- }, R = "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", ge = {
131
- underline: `${R} 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: `${R} 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
- }, _e = "inline-flex items-center gap-2", ve = "flex justify-center", ye = "w-full flex-1 outline-none";
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";
134
134
  //#endregion
135
135
  //#region lib/components/ui/primitives/tabs/partials/tabs-content.tsx
136
136
  function be({ className: t, ...n }) {
137
- return /* @__PURE__ */ b(me, {
137
+ return /* @__PURE__ */ y(he, {
138
138
  "data-slot": "tabs-content",
139
139
  className: e(ye, t),
140
140
  ...n
@@ -147,8 +147,33 @@ function H() {
147
147
  return g(V);
148
148
  }
149
149
  //#endregion
150
+ //#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));
154
+ }
155
+ function Te(e, t) {
156
+ let n = 0, r = 0, i = "", a = () => `${e.clientWidth}/${e.scrollWidth}`, o = { follow: !0 }, s = () => {
157
+ o.follow = !1;
158
+ }, c = (e) => {
159
+ Math.abs(e.deltaX) > Math.abs(e.deltaY) && s();
160
+ }, l = () => {
161
+ a() === i && (e.scrollLeft < n - 1 || e.scrollLeft > r + 1) && s();
162
+ };
163
+ return i = a(), e.addEventListener("wheel", c, { passive: !0 }), e.addEventListener("scroll", l, { passive: !0 }), e.addEventListener(U, s), {
164
+ state: o,
165
+ reveal(o, s) {
166
+ let c = e.scrollLeft, l = t(e, o, s);
167
+ n = Math.min(c, c + l), r = Math.max(c, c + l), i = a();
168
+ },
169
+ dispose() {
170
+ e.removeEventListener("wheel", c), e.removeEventListener("scroll", l), e.removeEventListener(U, s);
171
+ }
172
+ };
173
+ }
174
+ //#endregion
150
175
  //#region lib/components/ui/primitives/tabs/tabs-selectors.ts
151
- var U = "[role=\"tab\"], [data-slot=\"tabs-trigger\"]", W = "[role=\"tab\"][data-state=\"active\"], [data-slot=\"tabs-trigger\"][data-state=\"active\"]", G = 64, K = {
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 = {
152
177
  left: !1,
153
178
  right: !1,
154
179
  top: 0,
@@ -156,13 +181,13 @@ var U = "[role=\"tab\"], [data-slot=\"tabs-trigger\"]", W = "[role=\"tab\"][data
156
181
  width: 0,
157
182
  height: 0
158
183
  };
159
- function q() {
184
+ function J() {
160
185
  return window.matchMedia("(prefers-reduced-motion: reduce)").matches ? "instant" : "smooth";
161
186
  }
162
- function J(e) {
163
- if (e.getAttribute("aria-orientation") === "vertical") return K;
187
+ function Y(e) {
188
+ if (e.getAttribute("aria-orientation") === "vertical") return q;
164
189
  let t = e.scrollWidth - e.clientWidth;
165
- if (t <= 1) return K;
190
+ if (t <= 1) return q;
166
191
  let n = Math.abs(e.scrollLeft), r = n > 1, i = t - n > 1, a = getComputedStyle(e).direction === "rtl";
167
192
  return {
168
193
  left: a ? i : r,
@@ -173,64 +198,69 @@ function J(e) {
173
198
  height: e.offsetHeight
174
199
  };
175
200
  }
176
- var Y = (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;
177
- function X(e, t, n = q()) {
178
- if (e.scrollWidth <= e.clientWidth) return;
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()) {
203
+ if (e.scrollWidth <= e.clientWidth) return 0;
179
204
  let r = e.getBoundingClientRect(), i = t.getBoundingClientRect(), a = 0;
180
- i.left < r.left + G ? a = i.left - r.left - G : i.right > r.right - G && (a = i.right - r.right + G), a && e.scrollBy({
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({
181
206
  left: a,
182
207
  behavior: n
183
- });
208
+ }), a;
184
209
  }
185
210
  function Z(e, t = {
186
- tab: U,
187
- active: W
211
+ tab: W,
212
+ active: G
188
213
  }) {
189
- let [n, r] = te(K);
214
+ let [n, r] = te(q);
190
215
  return _(() => {
191
216
  let n = e.current;
192
217
  if (!n) return;
193
218
  let i = 0, a = () => {
194
219
  cancelAnimationFrame(i), i = requestAnimationFrame(() => {
195
- let e = J(n);
196
- r((t) => Y(t, e) ? t : e);
220
+ let e = Y(n);
221
+ r((t) => X(t, e) ? t : e);
197
222
  });
198
- }, o = () => n.querySelector(t.active), s = new ResizeObserver(a), c = () => {
199
- s.disconnect(), s.observe(n);
200
- for (let e of n.querySelectorAll(t.tab)) s.observe(e);
201
- }, l = new MutationObserver((e) => {
202
- if (c(), a(), e.some((e) => e.type === "attributes")) {
223
+ }, o = () => n.querySelector(t.active), s = Te(n, Ee), { state: c, reveal: l } = s, u = new ResizeObserver(() => {
224
+ a();
225
+ let e = c.follow ? o() : null;
226
+ e && l(e, "instant");
227
+ }), d = () => {
228
+ u.disconnect(), u.observe(n);
229
+ for (let e of n.querySelectorAll(t.tab)) u.observe(e);
230
+ }, f = new MutationObserver((e) => {
231
+ if (d(), a(), e.some((e) => e.type === "attributes")) {
232
+ c.follow = !0;
203
233
  let e = o();
204
- e && X(n, e);
234
+ e && l(e);
205
235
  }
206
236
  });
207
- l.observe(n, {
237
+ f.observe(n, {
208
238
  subtree: !0,
209
239
  childList: !0,
210
240
  attributeFilter: ["data-state"]
211
241
  });
212
- let u = (e) => {
213
- e.target instanceof HTMLElement && e.target.matches(t.tab) && X(n, e.target);
242
+ let p = (e) => {
243
+ e.target instanceof HTMLElement && e.target.matches(t.tab) && (c.follow = e.target.matches(t.active), l(e.target));
214
244
  };
215
- n.addEventListener("focusin", u), c();
216
- let d = o();
217
- return d && X(n, d, "instant"), r(J(n)), () => {
218
- cancelAnimationFrame(i), s.disconnect(), l.disconnect(), n.removeEventListener("focusin", u);
245
+ n.addEventListener("focusin", p), d();
246
+ let m = o();
247
+ return m && l(m, "instant"), r(Y(n)), () => {
248
+ cancelAnimationFrame(i), u.disconnect(), f.disconnect(), n.removeEventListener("focusin", p), s.dispose();
219
249
  };
220
250
  }, [
221
251
  e,
222
252
  t.tab,
223
253
  t.active
224
- ]), we(e, n.left || n.right, r), n;
254
+ ]), De(e, n.left || n.right, r), n;
225
255
  }
226
- function we(e, t, n) {
256
+ function De(e, t, n) {
227
257
  ee(() => {
228
258
  let r = e.current;
229
259
  if (!r || !t) return;
230
260
  let i = 0, a = () => {
231
261
  cancelAnimationFrame(i), i = requestAnimationFrame(() => {
232
- let e = J(r);
233
- n((t) => Y(t, e) ? t : e);
262
+ let e = Y(r);
263
+ n((t) => X(t, e) ? t : e);
234
264
  });
235
265
  };
236
266
  return document.addEventListener("scroll", a, {
@@ -254,14 +284,14 @@ function Q({ look: t }) {
254
284
  if (!e || !t) return;
255
285
  let r = 0, i = () => {
256
286
  cancelAnimationFrame(r), r = requestAnimationFrame(() => {
257
- let n = t.querySelector(W);
287
+ let n = t.querySelector(G);
258
288
  if (!n) return;
259
289
  let r = t.getAttribute("aria-orientation") === "vertical", i = r ? n.offsetHeight : n.offsetWidth, a = r ? n.offsetTop : n.offsetLeft;
260
290
  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");
261
291
  });
262
292
  }, a = new ResizeObserver(i), o = () => {
263
293
  a.disconnect(), a.observe(t);
264
- for (let e of t.querySelectorAll(U)) a.observe(e);
294
+ for (let e of t.querySelectorAll(W)) a.observe(e);
265
295
  }, s = new MutationObserver(() => {
266
296
  o(), i();
267
297
  });
@@ -274,11 +304,11 @@ function Q({ look: t }) {
274
304
  return c && s.observe(c, { attributeFilter: ["dir"] }), o(), i(), () => {
275
305
  cancelAnimationFrame(r), a.disconnect(), s.disconnect();
276
306
  };
277
- }, []), /* @__PURE__ */ b("span", {
307
+ }, []), /* @__PURE__ */ y("span", {
278
308
  ref: n,
279
309
  "aria-hidden": !0,
280
310
  "data-slot": "tabs-indicator",
281
- className: e(ge[t])
311
+ className: e(_e[t])
282
312
  });
283
313
  }
284
314
  //#endregion
@@ -289,17 +319,18 @@ function $({ list: e, overflow: t }) {
289
319
  let r = (t) => {
290
320
  let n = e.current;
291
321
  if (!n) return;
322
+ we(n);
292
323
  let r = Math.max(96, n.clientWidth * .75);
293
324
  n.scrollBy({
294
325
  left: t * r,
295
- behavior: q()
326
+ behavior: J()
296
327
  });
297
328
  }, i = {
298
329
  type: "button",
299
330
  tabIndex: -1,
300
331
  onMouseDown: (e) => e.preventDefault()
301
332
  };
302
- return /* @__PURE__ */ x("div", {
333
+ return /* @__PURE__ */ b("div", {
303
334
  "data-slot": "tabs-scroll",
304
335
  className: xe,
305
336
  style: {
@@ -308,28 +339,28 @@ function $({ list: e, overflow: t }) {
308
339
  width: t.width,
309
340
  height: t.height
310
341
  },
311
- children: [t.left && /* @__PURE__ */ b("button", {
342
+ children: [t.left && /* @__PURE__ */ y("button", {
312
343
  ...i,
313
344
  "data-slot": "tabs-scroll-left",
314
345
  "aria-label": n("material.tabs.scroll-left", "Scroll tabs left"),
315
346
  className: Se,
316
347
  onClick: () => r(-1),
317
- children: /* @__PURE__ */ b(ne, { "aria-hidden": !0 })
318
- }), t.right && /* @__PURE__ */ b("button", {
348
+ children: /* @__PURE__ */ y(re, { "aria-hidden": !0 })
349
+ }), t.right && /* @__PURE__ */ y("button", {
319
350
  ...i,
320
351
  "data-slot": "tabs-scroll-right",
321
352
  "aria-label": n("material.tabs.scroll-right", "Scroll tabs right"),
322
353
  className: Ce,
323
354
  onClick: () => r(1),
324
- children: /* @__PURE__ */ b(re, { "aria-hidden": !0 })
355
+ children: /* @__PURE__ */ y(ie, { "aria-hidden": !0 })
325
356
  })]
326
357
  });
327
358
  }
328
359
  //#endregion
329
360
  //#region lib/components/ui/primitives/tabs/partials/tabs-list.tsx
330
- function Te({ className: n, children: r, ref: i, ...a }) {
361
+ function Oe({ className: n, children: r, ref: i, ...a }) {
331
362
  let o = H(), s = v(null), c = Z(s);
332
- return /* @__PURE__ */ x(y, { children: [/* @__PURE__ */ x(fe, {
363
+ return /* @__PURE__ */ b(ne, { children: [/* @__PURE__ */ b(pe, {
333
364
  ref: h((e) => {
334
365
  s.current = e, typeof i == "function" ? i(e) : i && (i.current = e);
335
366
  }, [i]),
@@ -337,28 +368,28 @@ function Te({ className: n, children: r, ref: i, ...a }) {
337
368
  "data-pw": "tabs-list",
338
369
  "data-overflow-left": c.left ? "" : void 0,
339
370
  "data-overflow-right": c.right ? "" : void 0,
340
- className: e(P[o], z, n),
371
+ className: e(N[o], z, n),
341
372
  ...a,
342
- children: [/* @__PURE__ */ b(t, { children: r }), /* @__PURE__ */ b(Q, { look: o })]
343
- }), /* @__PURE__ */ b($, {
373
+ children: [/* @__PURE__ */ y(t, { children: r }), /* @__PURE__ */ y(Q, { look: o })]
374
+ }), /* @__PURE__ */ y($, {
344
375
  list: s,
345
376
  overflow: c
346
377
  })] });
347
378
  }
348
379
  //#endregion
349
380
  //#region lib/components/ui/primitives/tabs/partials/tabs-trigger.tsx
350
- function Ee({ className: n, children: r, icon: i, ...a }) {
351
- return /* @__PURE__ */ x(pe, {
381
+ function ke({ className: n, children: r, icon: i, ...a }) {
382
+ return /* @__PURE__ */ b(me, {
352
383
  "data-slot": "tabs-trigger",
353
- className: e(L[H()], n),
384
+ className: e(I[H()], n),
354
385
  ...a,
355
- children: [i && /* @__PURE__ */ b("span", {
386
+ children: [i && /* @__PURE__ */ y("span", {
356
387
  "data-slot": "tabs-trigger-icon",
357
388
  className: "flex justify-center",
358
389
  children: i
359
- }), /* @__PURE__ */ b(t, {
390
+ }), /* @__PURE__ */ y(t, {
360
391
  child: r,
361
- children: (e) => e && /* @__PURE__ */ b("span", {
392
+ children: (e) => e && /* @__PURE__ */ y("span", {
362
393
  className: "inline-flex items-center gap-2",
363
394
  children: e
364
395
  })
@@ -367,17 +398,17 @@ function Ee({ className: n, children: r, icon: i, ...a }) {
367
398
  }
368
399
  //#endregion
369
400
  //#region lib/components/ui/primitives/tabs/tabs.tsx
370
- function De({ className: t, variant: n = "underline", ...r }) {
371
- let i = M(n);
372
- return /* @__PURE__ */ b(V.Provider, {
401
+ function Ae({ className: t, variant: n = "underline", ...r }) {
402
+ let i = j(n);
403
+ return /* @__PURE__ */ y(V.Provider, {
373
404
  value: i,
374
- children: /* @__PURE__ */ b(de, {
405
+ children: /* @__PURE__ */ y(fe, {
375
406
  "data-slot": "tabs",
376
407
  "data-variant": n,
377
- className: e(he[i], t),
408
+ className: e(ge[i], t),
378
409
  ...r
379
410
  })
380
411
  });
381
412
  }
382
413
  //#endregion
383
- export { Q as a, H as c, ve as d, _e as f, M as h, $ as i, z as l, L as m, Ee as n, Z as o, P as p, Te as r, V as s, De as t, be as u };
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 };
@@ -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-DzEqMb1W.js";
17
+ import { n as it, r as at, t as ot, u as st } from "./tabs-BT9pSRwk.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";
@@ -554,7 +554,8 @@ and the `tag` dot still read `--chip-tone`, not the tone channel); `tag`
554
554
  a smaller tag led by a colour dot; `dashed` a muted "add" pill. 28px tall,
555
555
  24px with `size="sm"`, 44px with `size="lg"`. Selected (`active`, or `aria-pressed` on a toggle
556
556
  chip) takes a primary tint and a primary edge, and a pressed toggle with
557
- nothing leading draws a check. The label is truncated as one piece; the ✕
557
+ nothing leading draws a check. An unselected neutral toggle chip keeps a
558
+ boundary of at least 3:1 against the page and the card. The label is truncated as one piece; the ✕
558
559
  and `trailing` stay whole.
559
560
 
560
561
  A chip with `onClick` is a button; with `onDismiss` it gains a ✕ button;
@@ -15,7 +15,7 @@ either can be used alone.
15
15
  | --- | --- | --- |
16
16
  | <img src="../previews/data-table-filter-lists-datatable.webp" width="96" alt=""> | [DataTable](#datatable) | TanStack Table v9 with sorting, selection, expansion and pagination, client-side or one server page at a time |
17
17
  | <img src="../previews/data-table-filter-lists-servertable.webp" width="96" alt=""> | [ServerTable](#servertable) | A server-mode `DataTable` driven by the URL, with the Filter in its top band (a title and a description, or neither): sort, cursor paging, the empty page with a scene, an action and removable chips, one count announced |
18
- | <img src="../previews/data-table-filter-lists-rowmenu.webp" width="96" alt=""> | [RowMenu](#rowmenu) | A row's "..." button named after its row ("Actions for Ada"), its menu aligned to the end with the destructive item last, a loading state while an action runs, `rowMenuColumn` to drop both in a table, and `useRowMenuFocus` to hand the focus back to a row's button after an action |
18
+ | <img src="../previews/data-table-filter-lists-rowmenu.webp" width="96" alt=""> | [RowMenu](#rowmenu) | A row's "..." button named after its row ("Actions for Ada"), its menu aligned to the end with the destructive item last, a loading state while an action runs, `rowMenuColumn` to drop both in a table, and `useRowMenuFocus` (with `rowFocusProps` for a plain row button) to hand the focus back to a row's button after an action |
19
19
  | <img src="../previews/data-table-filter-lists-recordactionsmenu.webp" width="96" alt=""> | [RecordActionsMenu](#recordactionsmenu) | A record's archive, restore and delete menu over `RowMenu`: Archive runs at once with an Undo toast that stays until dismissed, Restore runs at once, Delete permanently asks first and keeps a refusal in its dialog; `archivePolicy="confirm"` asks before archiving, `consequence` notes what an action entails, `successAction` adds a toast action, and an `ActionRefusal` (`isActionRefusal`) carries a refusal's details and action |
20
20
  | <img src="../previews/data-table-filter-lists-listempty.webp" width="96" alt=""> | [ListEmpty](#listempty) | A list's empty page: nothing yet, with a scene and an action, or nothing matches and the way out |
21
21
  | <img src="../previews/data-table-filter-lists-pagefooter.webp" width="96" alt=""> | [PageFooter](#pagefooter) | The page footer of a feed that is not a table (cards, a news feed) under a FilterBar: the range and Previous / Next as links from the URL's cursor trail, `pageControls="icon"`; no `totalCount` for a feed with no total (no range, Previous / Next only); `hideOnSinglePage` hides it on a single page |
@@ -1312,6 +1312,18 @@ const columns = useMemo(
1312
1312
  searched. For a dialog, [`onCloseAutoFocus`](#focus-after-a-bulk-action) with
1313
1313
  `preventDefault()` is the precise hook if you want to take the focus yourself.
1314
1314
 
1315
+ A row whose action is a plain button (an edit pen that opens a dialog) has no
1316
+ `RowMenu`. Spread `rowFocusProps(rowId)` on it and `focusRowMenu(rowId)` finds
1317
+ it the same way; it writes the two attributes `RowMenu` writes on its trigger.
1318
+
1319
+ ```tsx
1320
+ import { IconButton, rowFocusProps } from '@nxgt/material/components';
1321
+
1322
+ <IconButton aria-label={`Edit ${person.name}`} onClick={open} {...rowFocusProps(person.id)} />;
1323
+ // after the dialog closes
1324
+ focusRowMenu(person.id);
1325
+ ```
1326
+
1315
1327
  `findRowMenuTrigger(rowId, scope?)` is the lookup the hook uses: it returns the
1316
1328
  row's button (an `HTMLElement`) inside `scope` (default `document`), or `null`.
1317
1329
  Use it instead of the hook when you only need the element (to scroll it into
@@ -677,7 +677,8 @@ Without a form library, `QuantityField` takes `value` and `onChange` (or
677
677
  `defaultValue`). The number is the one `NumberField` has: the language's
678
678
  decimal separator, `min`, `max` and `step` (clamped on blur), and steppers
679
679
  named after the field ("Increase Dose"). Both parts stay on one line on a
680
- phone: the number shrinks, the unit is sized to its longest label (see Unit width below).
680
+ phone: the unit is sized to its longest label and shrinks first, the
681
+ number keeps 9rem (see Unit width below).
681
682
 
682
683
  | Prop | Type | Default | What it does |
683
684
  | --- | --- | --- | --- |
@@ -698,8 +699,10 @@ phone: the number shrinks, the unit is sized to its longest label (see Unit widt
698
699
  `allowCustomUnit`, a text input) named "Dose unit". The message describes
699
700
  the group, the number and the unit, and both are `aria-invalid` on an error.
700
701
  - **Unit width:** the unit part is sized to the longest label of `units`
701
- (never under 7rem, never over 55% of the row, so the number keeps room at
702
- 360px). Beyond the cap the label is cut with an ellipsis and the full label
702
+ (never under 7rem, never over 55% of the row). It shrinks before the number
703
+ does: the number's cell keeps 9rem (two 44px steppers and a 44px input), so
704
+ the input stays a tap target at 375px, also in a padded side sheet. Beyond
705
+ the cap the label is cut with an ellipsis and the full label
703
706
  is the select's `title` (the `units` select only; a free unit typed past
704
707
  the cap scrolls in its input). No inline style is used for it.
705
708
  - **Translations:** `material.quantity-field.unit` and `.unit-named` (English
@@ -25,7 +25,7 @@ documentation-site shell. Everything is imported from
25
25
  | <img src="../previews/navigation-layout-toc.webp" width="96" alt=""> | [Toc](#toc) | On-this-page outline |
26
26
  | <img src="../previews/navigation-layout-stepper.webp" width="96" alt=""> | [Stepper](#stepper) | Clickable steps with progress: shaped indicators, optional steps, a phone header |
27
27
  | <img src="../previews/navigation-layout-steps.webp" width="96" alt=""> | [Steps](#steps) | Numbered editorial steps |
28
- | <img src="../previews/navigation-layout-hero.webp" width="96" alt=""> | [Hero](#hero) | Landing band |
28
+ | <img src="../previews/navigation-layout-hero.webp" width="96" alt=""> | [Hero](#hero) | Landing band, or a compact greeting band, with an optional `Background` |
29
29
  | <img src="../previews/navigation-layout-doc.webp" width="96" alt=""> | [Doc](#doc) | Documentation site shell |
30
30
  | <img src="../previews/navigation-layout-background.webp" width="96" alt=""> | [Background](#background) | Gradient backdrop with colour blobs; the `/backgrounds` one takes its unset props from the nearest theme |
31
31
  | | [NavigationRail](#navigationrail) | Placeholder, no props yet |
@@ -898,6 +898,34 @@ import { Button, Hero } from '@nxgt/material/components';
898
898
  `eyebrow`, `title`, `description`, `actions` and `children` (below the
899
899
  actions) are all content slots.
900
900
 
901
+ `background` draws a decorative `Background` (the props of the one in
902
+ `@nxgt/material/backgrounds`: `preset`, `intensity`, `tone`, `fill`, `animated`…)
903
+ `aria-hidden` behind the content, clipped by the band's radius.
904
+ It replaces the built-in gradient and glows, loads on demand, and follows
905
+ `Background` in dark mode and under reduced motion.
906
+ Its type, `HeroBackgroundProps`, is exported from `@nxgt/material/components`.
907
+
908
+ `headingLevel` (1 to 6, default 1) sets the title's heading.
909
+
910
+ `aria-label` names the section.
911
+
912
+ `size` is `'default'` (the landing band) or `'compact'`.
913
+ `size="compact"` is a greeting band for a home page: `rounded-xl`, the padding
914
+ of a Card's content, the title in `headline-lg` emphasized, a muted description,
915
+ and the actions at the end from `lg` (wrapping below it).
916
+ Each action is at least 44px tall, for its direct `a` and `button` children; a
917
+ Tooltip or Link wrapping a Button is not covered.
918
+
919
+ ```tsx
920
+ <Hero
921
+ size="compact"
922
+ background={{ preset: 'gradient', intensity: 'subtle', fill: 'container' }}
923
+ title={`Hello ${name}`}
924
+ description="2 items in progress"
925
+ actions={<><Button variant="tonal">History</Button><Button>Browse</Button></>}
926
+ />
927
+ ```
928
+
901
929
  **Storybook:** `Navigation & layout/Hero` · **Vue:** `Hero`
902
930
 
903
931
  ---
@@ -807,7 +807,9 @@ One choice or several, shown as chips. `type="single"` (the default) is a
807
807
  radio group of `radio` chips; `type="multiple"` is a `group` of `checkbox`
808
808
  chips. A chosen chip has the chip's selected tint and its leading check, so
809
809
  colour is never the only cue (an option's `icon` gives way to the check while
810
- it is chosen).
810
+ it is chosen). An unchosen chip keeps a boundary of at least 3:1 against the
811
+ page and the card, in light and dark, so it reads as a control and not as
812
+ plain text.
811
813
 
812
814
  The `ref` reaches the chip that holds the tab stop (the first chosen enabled
813
815
  chip, else the first), so a form library's `setFocus` works.
@@ -376,8 +376,10 @@ export const invoiceRoute: RouteObject = {
376
376
  context the page fills while it renders cannot do this: the bar is written
377
377
  before the page is reached.)
378
378
  - **It is the page's `h1`**, in `--font-display` (the body face when you
379
- define none), truncated with an ellipsis; when it is cut off, its full text
380
- is the `title` tooltip, as for `headerTitle` (#629), and its accessible
379
+ define none). On a phone a long title wraps to a second line first, so a
380
+ record's number stays readable by touch (#2324); from `md` up, and on a
381
+ phone once two lines are not enough, it is cut with an ellipsis. When it is
382
+ cut off, its full text is the `title` tooltip, as for `headerTitle` (#629), and its accessible
381
383
  name stays the text itself. It sits after `headerTitle`, which gives it room.
382
384
  - **Typing it.** `AppShellHandle<Data>` (`{ breadcrumb?, title?, titleAfter? }`) and
383
385
  `PageTitle<Data>` are exported for a route's `handle`; `Data` types the
@@ -455,7 +457,7 @@ export const handle = {
455
457
  (`[data-slot=app-header-title-after]`), vertically centred with the title, so
456
458
  the heading's accessible name stays the plain title.
457
459
  - **On a phone it stays on screen** and shares the row with the title: the
458
- title truncates first (ellipsis), the slot never shrinks.
460
+ title gives way first (two lines, then an ellipsis), the slot never shrinks.
459
461
  - **Nothing changes without it**: the markup of a bar with no slot is the same
460
462
  as before, and the slot is read from the matches like the title, so it is in
461
463
  the server HTML and does not flash on a route change.
@@ -484,7 +486,7 @@ A multi-tenant app keeps the current tenant visible on a desktop screen with
484
486
  adds nothing to the bar, and setting both never shows the name twice on one
485
487
  screen.
486
488
  - **The title truncates first**: with a long title, the slot and the line
487
- together, the title gives way; the slot stays whole and the line keeps its cap.
489
+ together, the title gives way (two lines on a phone, then an ellipsis); the slot stays whole and the line keeps its cap.
488
490
  - **It needs a page title**: while the bar shows none (no `handle.title`),
489
491
  `headerTitle` is the context line and `headerContext` is ignored.
490
492