@nxgt/material 3.82.0 → 3.84.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.
- package/CHANGELOG.md +40 -0
- package/README.md +4 -3
- package/dist/{alert-dialog-DXLJ4AZP.js → alert-dialog-1t6ULy5i.js} +1 -1
- package/dist/{async-slice-BfVokA46.js → async-slice-xyA9Uzct.js} +1 -1
- package/dist/{button-CSKUtMI3.js → button-DhiNGrdT.js} +1 -1
- package/dist/{calculator-Cv00UQgR.js → calculator-BcgxxScL.js} +10 -10
- package/dist/calculator-field.js +6 -6
- package/dist/{calculator-segment-CwnC2cV_.js → calculator-segment-C4WQAHcN.js} +1 -1
- package/dist/calculator.js +1 -1
- package/dist/charts.js +3 -3
- package/dist/{chip-BGn0V6Pt.js → chip-m0_usuzd.js} +2 -2
- package/dist/{code-editor-B25-mWhb.js → code-editor-BgKFrcld.js} +4 -4
- package/dist/code-editor.js +4 -4
- package/dist/{code-language-items-oRjtO3qV.js → code-language-items-BWw17W9s.js} +2 -2
- package/dist/components/theme-tokens.css +3 -3
- package/dist/components/ui/collections/server-table/server-table-phone-row.css +12 -0
- package/dist/{components-BmZk-git.js → components-JPnObL9i.js} +8914 -8812
- package/dist/components.js +37 -37
- package/dist/{conversion-variant-wZd-G6xR.js → conversion-variant-DultZZQm.js} +3 -3
- package/dist/{currency-field-DizBTAat.js → currency-field-CPbaM7ay.js} +4 -4
- package/dist/{dialog-B-3s-oXt.js → dialog-DmlG9opW.js} +3 -3
- package/dist/dnd.js +1 -1
- package/dist/{dropdown-menu-C6rcYGB9.js → dropdown-menu-CDKev8dk.js} +1 -1
- package/dist/editor.js +7 -7
- package/dist/{empty-state-CSkghnD9.js → empty-state-C56000TB.js} +1 -1
- package/dist/{financial-variant-igpGRbGw.js → financial-variant-BYjQ690K.js} +5 -5
- package/dist/{hooks-k8_f3B0k.js → hooks-BTwLAy_A.js} +119 -83
- package/dist/hooks.js +3 -3
- package/dist/{hover-card-DuaVVKMb.js → hover-card-CDtW6utN.js} +1 -1
- package/dist/i18n.js +3 -3
- package/dist/{icon-badge-3ThP6EOl.js → icon-badge-ec7MmUGA.js} +1 -1
- package/dist/{icon-button-4PKlaI1g.js → icon-button-CG4aO8Gh.js} +1 -1
- package/dist/lib/components/ui/display/index.d.ts +1 -0
- package/dist/lib/components/ui/display/totals-list/index.d.ts +2 -0
- package/dist/lib/components/ui/display/totals-list/totals-list.d.ts +43 -0
- package/dist/lib/components/ui/fields/contacts/placeholders.d.ts +1 -1
- package/dist/lib/components/ui/media/galleries/types.d.ts +8 -0
- package/dist/lib/components/ui/media/galleries/use-gallery.d.ts +1 -0
- package/dist/lib/components/ui/widgets/event-calendar/event-calendar-context.d.ts +6 -1
- package/dist/lib/components/ui/widgets/event-calendar/event-calendar-shell.d.ts +1 -1
- package/dist/lib/components/ui/widgets/event-calendar/index.d.ts +1 -1
- package/dist/lib/components/ui/widgets/event-calendar/partials/event-preview-title.d.ts +6 -2
- package/dist/lib/components/ui/widgets/event-calendar/partials/event-preview.d.ts +3 -1
- package/dist/lib/components/ui/widgets/event-calendar/template.types.d.ts +5 -1
- package/dist/lib/components/ui/widgets/event-calendar/types.d.ts +20 -0
- package/dist/lib/components/ui/widgets/event-calendar/use-template-calendar.d.ts +3 -1
- package/dist/lib/hooks/index.d.ts +1 -0
- package/dist/lib/hooks/poll.d.ts +26 -0
- package/dist/lib/hooks/use-poll.d.ts +30 -0
- package/dist/lib/i18n/resources/en/en.d.ts +1 -0
- package/dist/lib/i18n/resources/en/material.json.d.ts +1 -0
- package/dist/lib/i18n/resources/fr/fr.d.ts +1 -0
- package/dist/lib/i18n/resources/fr/material.json.d.ts +1 -0
- package/dist/lib/i18n/resources/resources.d.ts +2 -0
- package/dist/lib/i18n/translator.d.ts +1 -1
- package/dist/lib.js +1 -1
- package/dist/main.js +53 -53
- package/dist/map.js +7 -7
- package/dist/material.css +1 -1
- package/dist/pdf-reader.js +1 -1
- package/dist/{percent-field-QwU1l2Q4.js → percent-field-8_pILs15.js} +1 -1
- package/dist/{picker-surface-CiTycWgV.js → picker-surface-pyGv-Qh9.js} +4 -4
- package/dist/{popover-YmbzbKQG.js → popover-3EF4q2CT.js} +1 -1
- package/dist/{pos-types-BFrapNmx.js → pos-types-Dv2UxKSN.js} +1 -1
- package/dist/{pos-variant-CctfqieO.js → pos-variant-DJvtN9N8.js} +4 -4
- package/dist/print.js +1 -1
- package/dist/{programmer-variant-Dd0YOixn.js → programmer-variant-Bmcq2KzC.js} +2 -2
- package/dist/{public-CshR_aW7.js → public-BNebh4z0.js} +9 -9
- package/dist/{rich-code-block-BuJLDoBu.js → rich-code-block-DmX7d58S.js} +5 -5
- package/dist/{scientific-variant-CjErQxuZ.js → scientific-variant-DijUrpP8.js} +2 -2
- package/dist/{sortable-provider-DU2nvpFc.js → sortable-provider-Cnmt_gWu.js} +2 -2
- package/dist/{spinner-DH1mm8hH.js → spinner-C6LP2Rw8.js} +1 -1
- package/dist/{tabs-Um0SFyf1.js → tabs-Bj1zOe7-.js} +1 -1
- package/dist/theme-picker.js +2 -2
- package/dist/{theme-toggle-C-Ih4uQU.js → theme-toggle-Cxku5iBP.js} +1 -1
- package/dist/{toolbar-items-BoEY5bkt.js → toolbar-items-CEIuSxU_.js} +4 -4
- package/dist/{translate-material-D4rn5UaQ.js → translate-material-DI3nmQ6I.js} +1 -1
- package/dist/{translator-CcEgQ-H7.js → translator-BstxG_hN.js} +177 -163
- package/dist/{use-chat-composer-BfFcmDua.js → use-chat-composer-BqLkk_iH.js} +71 -66
- package/dist/{use-heading-spy-gDNtK1sU.js → use-heading-spy-nFyb9_KE.js} +4 -4
- package/dist/{use-material-translation-DYrfV_JJ.js → use-material-translation-1kCHtB0p.js} +1 -1
- package/dist/{use-return-focus-C_Qz_yTk.js → use-return-focus-Hv8rn55-.js} +1 -1
- package/docs/components/data-display.md +38 -8
- package/docs/components/media-and-files.md +11 -0
- package/docs/components/rich-widgets.md +22 -1
- package/docs/guides/helpers.md +40 -0
- package/docs/guides/layouts.md +5 -2
- package/docs/guides/theming.md +2 -2
- package/docs/roadmap.md +9 -4
- package/docs/troubleshooting.md +2 -2
- package/lib/components/theme-tokens.css +3 -3
- package/lib/components/ui/collections/server-table/server-table-phone-row.css +12 -0
- package/lib/themes/ambre.css +2 -2
- package/lib/themes/ardoise.css +2 -2
- package/lib/themes/bleumono.css +2 -2
- package/lib/themes/bluemoon.css +2 -2
- package/lib/themes/corail.css +2 -2
- package/lib/themes/foret.css +2 -2
- package/lib/themes/lavande.css +2 -2
- package/lib/themes/menthe.css +2 -2
- package/lib/themes/ocean.css +2 -2
- package/lib/themes/pink.css +2 -2
- package/lib/themes/prune.css +1 -1
- package/lib/themes/sable.css +2 -2
- package/lib/themes/slate.css +1 -1
- package/lib/themes/teal.css +2 -2
- package/package.json +4 -4
|
@@ -4,28 +4,28 @@ import { t as n } from "./utils-BLfntITJ.js";
|
|
|
4
4
|
import { n as r } from "./use-shape-morph-BKA_R5P5.js";
|
|
5
5
|
import { n as i, o as a, t as o } from "./dist-DVRQkaTK.js";
|
|
6
6
|
import { i as s, n as c, r as l, t as u } from "./dist-DWZXlCZR.js";
|
|
7
|
-
import { _ as d, a as f, b as p, g as m, h, i as g, m as _, n as v, o as y, r as b, s as x, t as S, v as C, y as w } from "./spinner-
|
|
7
|
+
import { _ as d, a as f, b as p, g as m, h, i as g, m as _, n as v, o as y, r as b, s as x, t as S, v as C, y as w } from "./spinner-C6LP2Rw8.js";
|
|
8
8
|
import { a as T, i as E, n as D, r as O, t as k } from "./dist-DHdUUM1w.js";
|
|
9
9
|
import { a as A, i as ee } from "./dist-DOK3zo5C.js";
|
|
10
10
|
import { i as j, n as M } from "./in-dialog-D61Yeaol.js";
|
|
11
|
-
import { c as N, l as P, n as te, r as F, t as ne } from "./alert-dialog-
|
|
11
|
+
import { c as N, l as P, n as te, r as F, t as ne } from "./alert-dialog-1t6ULy5i.js";
|
|
12
12
|
import { A as re, C as ie, D as ae, E as oe, O as se, S as I, T as ce, _ as le, a as ue, b as de, d as fe, f as pe, g as me, h as he, i as ge, k as _e, l as ve, m as ye, n as be, o as xe, p as Se, r as Ce, s as we, t as Te, u as Ee, v as De, w as Oe, x as ke, y as Ae } from "./floating-ui.dom-KkZSW8_E.js";
|
|
13
|
-
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, k as ze, m as Be, n as Ve, o as He, p as Ue, t as We, u as Ge } from "./dropdown-menu-
|
|
13
|
+
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, k as ze, m as Be, n as Ve, o as He, p as Ue, t as We, u as Ge } from "./dropdown-menu-CDKev8dk.js";
|
|
14
14
|
import { a as Ke, i as qe, n as Je } from "./field-blur-context-BLGgf_3z.js";
|
|
15
|
-
import { i as Ye, n as Xe, r as Ze, t as Qe } from "./popover-
|
|
15
|
+
import { i as Ye, n as Xe, r as Ze, t as Qe } from "./popover-3EF4q2CT.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-
|
|
18
|
-
import { a as ct, n as lt, o as ut, s as dt, v as ft, y as pt } from "./toolbar-items-
|
|
17
|
+
import { n as it, r as at, t as ot, u as st } from "./tabs-Bj1zOe7-.js";
|
|
18
|
+
import { a as ct, n as lt, o as ut, s as dt, v as ft, y as pt } from "./toolbar-items-CEIuSxU_.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-Bwg_caHO.js";
|
|
21
21
|
import { a as vt, r as yt } from "./icon-sprites-CaYXzOL4.js";
|
|
22
22
|
import { t as bt } from "./warn-once-C_e47JM8.js";
|
|
23
|
-
import { r as xt, t as St } from "./button-
|
|
24
|
-
import { a as Ct } from "./translator-
|
|
23
|
+
import { r as xt, t as St } from "./button-DhiNGrdT.js";
|
|
24
|
+
import { a as Ct } from "./translator-BstxG_hN.js";
|
|
25
25
|
import { h as wt } from "./get-CTzJAwfc.js";
|
|
26
26
|
import { t as Tt } from "./isEmpty-F_g3jLf8.js";
|
|
27
|
-
import { t as L } from "./use-material-translation-
|
|
28
|
-
import { t as R } from "./icon-button-
|
|
27
|
+
import { t as L } from "./use-material-translation-1kCHtB0p.js";
|
|
28
|
+
import { t as R } from "./icon-button-CG4aO8Gh.js";
|
|
29
29
|
import { t as Et } from "./use-ssr-media-query-C6M5m8sf.js";
|
|
30
30
|
import { n as Dt, t as Ot } from "./typography-CYEquVeb.js";
|
|
31
31
|
import { n as kt, t as At } from "./util-4heV2LPI.js";
|
|
@@ -36,14 +36,14 @@ import { a as Bt } from "./toggle-group-CVMxEpWi.js";
|
|
|
36
36
|
import { n as Vt } from "./use-slice-reducer-BGkeGtML.js";
|
|
37
37
|
import { t as Ht } from "./browser-only-DQ94lWF8.js";
|
|
38
38
|
import { t as Ut } from "./compose-refs-G4J4kaUA.js";
|
|
39
|
-
import { n as Wt, r as Gt, t as Kt } from "./chip-
|
|
39
|
+
import { n as Wt, r as Gt, t as Kt } from "./chip-m0_usuzd.js";
|
|
40
40
|
import { a as qt, c as Jt, o as Yt, r as Xt, s as Zt, t as Qt } from "./input-CC2joTjB.js";
|
|
41
41
|
import { t as $t } from "./text-field-BAdY-kpO.js";
|
|
42
42
|
import { r as en } from "./use-csp-nonce-ZKs9k-ov.js";
|
|
43
|
-
import { t as tn } from "./empty-state-
|
|
43
|
+
import { t as tn } from "./empty-state-C56000TB.js";
|
|
44
44
|
import { t as nn } from "./skeleton-DSdtr2qc.js";
|
|
45
|
-
import { l as rn, n as an, o as on, r as sn, s as cn, t as ln, u as un } from "./dialog-
|
|
46
|
-
import { t as dn } from "./icon-badge-
|
|
45
|
+
import { l as rn, n as an, o as on, r as sn, s as cn, t as ln, u as un } from "./dialog-DmlG9opW.js";
|
|
46
|
+
import { t as dn } from "./icon-badge-ec7MmUGA.js";
|
|
47
47
|
import { H as fn, V as pn, X as mn, bt as hn, it as gn, lt as _n, n as vn, t as yn, xt as bn, yt as xn } from "./dist-moutbfbd.js";
|
|
48
48
|
import { t as Sn } from "./markdown-Dw_uH7j7.js";
|
|
49
49
|
import { r as Cn, t as wn } from "./create-store-Dqp-PLLn.js";
|
|
@@ -11229,7 +11229,7 @@ var aS = (e = {}) => Cn({
|
|
|
11229
11229
|
let [{ default: t }, { lowlight: n }, { richCodeBlock: r }] = await Promise.all([
|
|
11230
11230
|
import("./dist-CRMFGjng.js"),
|
|
11231
11231
|
import("./lowlight-OtcjU2Sa.js"),
|
|
11232
|
-
import("./rich-code-block-
|
|
11232
|
+
import("./rich-code-block-DmX7d58S.js")
|
|
11233
11233
|
]);
|
|
11234
11234
|
return [r(t, {
|
|
11235
11235
|
lowlight: n,
|
|
@@ -20005,18 +20005,22 @@ function RN({ className: e }) {
|
|
|
20005
20005
|
//#endregion
|
|
20006
20006
|
//#region lib/components/ui/media/galleries/partials/gallery-selection-bar.tsx
|
|
20007
20007
|
function zN() {
|
|
20008
|
-
let { state: e, selectable: t,
|
|
20008
|
+
let { state: e, selectable: t, selectionActions: n, clearSelection: r } = KC(), { t: i } = L();
|
|
20009
20009
|
return !t || e.selectedIds.length === 0 ? null : /* @__PURE__ */ K("div", {
|
|
20010
20010
|
"data-slot": "gallery-selection-bar",
|
|
20011
20011
|
className: "mb-2 flex flex-wrap items-center justify-between gap-2 rounded-(--nxgt-shape-corner-lg) border border-border bg-background px-3 py-2",
|
|
20012
20012
|
children: [/* @__PURE__ */ G(Ot, {
|
|
20013
20013
|
className: "text-sm",
|
|
20014
|
-
children:
|
|
20015
|
-
}), /* @__PURE__ */
|
|
20016
|
-
|
|
20017
|
-
|
|
20018
|
-
|
|
20019
|
-
|
|
20014
|
+
children: i("material.gallery.selected", "{count} selected", { count: e.selectedIds.length })
|
|
20015
|
+
}), /* @__PURE__ */ K("div", {
|
|
20016
|
+
"data-slot": "gallery-selection-actions",
|
|
20017
|
+
className: "flex flex-wrap items-center gap-2",
|
|
20018
|
+
children: [typeof n == "function" ? n(e.selectedIds) : n, /* @__PURE__ */ G(St, {
|
|
20019
|
+
variant: "ghost",
|
|
20020
|
+
color: "default",
|
|
20021
|
+
onClick: r,
|
|
20022
|
+
children: i("material.gallery.clear-selection", "Clear selection")
|
|
20023
|
+
})]
|
|
20020
20024
|
})]
|
|
20021
20025
|
});
|
|
20022
20026
|
}
|
|
@@ -20342,68 +20346,69 @@ function oP({ open: e, close: t, currentIndex: n, lightboxOpen: r }) {
|
|
|
20342
20346
|
//#endregion
|
|
20343
20347
|
//#region lib/components/ui/media/galleries/use-gallery.ts
|
|
20344
20348
|
function sP(e) {
|
|
20345
|
-
let { items: t, defaultIndex: n = 0, defaultOpen: r = !1, onDelete: i, trigger: a, selectable: o = !1 } = e,
|
|
20349
|
+
let { items: t, defaultIndex: n = 0, defaultOpen: r = !1, onDelete: i, trigger: a, selectable: o = !1, selectionActions: s } = e, c = eP(e), [l, u] = Vt(UM, {
|
|
20346
20350
|
currentIndex: n,
|
|
20347
|
-
loop:
|
|
20351
|
+
loop: c.loop ?? !1,
|
|
20348
20352
|
lightboxOpen: r
|
|
20349
20353
|
});
|
|
20350
|
-
nP(e,
|
|
20351
|
-
let { next:
|
|
20352
|
-
lightboxOpen:
|
|
20353
|
-
open:
|
|
20354
|
-
close:
|
|
20355
|
-
currentIndex:
|
|
20356
|
-
}),
|
|
20357
|
-
|
|
20354
|
+
nP(e, l, u);
|
|
20355
|
+
let { next: d, prev: f, select: p, downloadCurrent: m } = XN(t, l, u), h = oP({
|
|
20356
|
+
lightboxOpen: l.lightboxOpen,
|
|
20357
|
+
open: u.openLightbox,
|
|
20358
|
+
close: u.closeLightbox,
|
|
20359
|
+
currentIndex: l.currentIndex
|
|
20360
|
+
}), g = B((e, t) => {
|
|
20361
|
+
c.lightbox ? h.openWith(e, t) : u.setIndex(e);
|
|
20358
20362
|
}, [
|
|
20359
|
-
|
|
20360
|
-
|
|
20361
|
-
|
|
20362
|
-
]),
|
|
20363
|
+
c.lightbox,
|
|
20364
|
+
u,
|
|
20365
|
+
h.openWith
|
|
20366
|
+
]), _ = qN({
|
|
20363
20367
|
items: t,
|
|
20364
|
-
state:
|
|
20365
|
-
sliceActions:
|
|
20366
|
-
resolved:
|
|
20367
|
-
next:
|
|
20368
|
-
prev:
|
|
20369
|
-
close:
|
|
20370
|
-
downloadCurrent:
|
|
20371
|
-
zoomable: t[
|
|
20368
|
+
state: l,
|
|
20369
|
+
sliceActions: u,
|
|
20370
|
+
resolved: c,
|
|
20371
|
+
next: d,
|
|
20372
|
+
prev: f,
|
|
20373
|
+
close: h.closeWith,
|
|
20374
|
+
downloadCurrent: m,
|
|
20375
|
+
zoomable: t[l.currentIndex]?.kind !== "video"
|
|
20372
20376
|
});
|
|
20373
20377
|
return {
|
|
20374
20378
|
items: t,
|
|
20375
|
-
resolved:
|
|
20376
|
-
state:
|
|
20377
|
-
current: WM.selectCurrent(
|
|
20378
|
-
canNext: WM.selectCanNext(
|
|
20379
|
-
canPrev: WM.selectCanPrev(
|
|
20379
|
+
resolved: c,
|
|
20380
|
+
state: l,
|
|
20381
|
+
current: WM.selectCurrent(l, t),
|
|
20382
|
+
canNext: WM.selectCanNext(l, t.length),
|
|
20383
|
+
canPrev: WM.selectCanPrev(l, t.length),
|
|
20380
20384
|
onDelete: i,
|
|
20381
20385
|
trigger: a,
|
|
20382
|
-
openAt:
|
|
20383
|
-
select:
|
|
20384
|
-
next:
|
|
20385
|
-
prev:
|
|
20386
|
-
closeLightbox:
|
|
20387
|
-
setZoom:
|
|
20388
|
-
setPan:
|
|
20389
|
-
morph:
|
|
20390
|
-
toggleLoop:
|
|
20391
|
-
goToFirst: () =>
|
|
20392
|
-
goToLast: () =>
|
|
20393
|
-
downloadCurrent:
|
|
20386
|
+
openAt: g,
|
|
20387
|
+
select: p,
|
|
20388
|
+
next: d,
|
|
20389
|
+
prev: f,
|
|
20390
|
+
closeLightbox: h.closeWith,
|
|
20391
|
+
setZoom: u.setZoom,
|
|
20392
|
+
setPan: u.setPan,
|
|
20393
|
+
morph: h.morph,
|
|
20394
|
+
toggleLoop: u.toggleLoop,
|
|
20395
|
+
goToFirst: () => u.setIndex(0),
|
|
20396
|
+
goToLast: () => u.setIndex(Math.max(0, t.length - 1)),
|
|
20397
|
+
downloadCurrent: m,
|
|
20394
20398
|
selectable: o,
|
|
20395
|
-
|
|
20396
|
-
|
|
20397
|
-
|
|
20399
|
+
selectionActions: s,
|
|
20400
|
+
toggleSelected: u.toggleSelected,
|
|
20401
|
+
clearSelection: u.clearSelection,
|
|
20402
|
+
onKeyDown: _
|
|
20398
20403
|
};
|
|
20399
20404
|
}
|
|
20400
20405
|
//#endregion
|
|
20401
20406
|
//#region lib/components/ui/media/galleries/gallery.tsx
|
|
20402
20407
|
function cP(e) {
|
|
20403
|
-
let t = sP(e), { items: n, preset: r, layout: i, columns: a, aspect: o, loop: s, maxItems: c, lightbox: l, captions: u, shape: d, carousel: f, carouselAlign: p, carouselOrientation: m, defaultIndex: h, currentIndex: g, onIndexChange: _, open: v, defaultOpen: y, onOpenChange: b, onDelete: x, selectable: S, onSelectionChange: C,
|
|
20408
|
+
let t = sP(e), { items: n, preset: r, layout: i, columns: a, aspect: o, loop: s, maxItems: c, lightbox: l, captions: u, shape: d, carousel: f, carouselAlign: p, carouselOrientation: m, defaultIndex: h, currentIndex: g, onIndexChange: _, open: v, defaultOpen: y, onOpenChange: b, onDelete: x, selectable: S, onSelectionChange: C, selectionActions: w, trigger: T, ...E } = e;
|
|
20404
20409
|
return /* @__PURE__ */ G(GC, {
|
|
20405
20410
|
value: t,
|
|
20406
|
-
children: /* @__PURE__ */ G(lP, { ...
|
|
20411
|
+
children: /* @__PURE__ */ G(lP, { ...E })
|
|
20407
20412
|
});
|
|
20408
20413
|
}
|
|
20409
20414
|
function lP({ className: e, onKeyDown: t, ...r }) {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { t as e } from "./utils-BLfntITJ.js";
|
|
2
|
-
import { a as t, c as n, d as r, i, n as a, r as o, t as s, u as c } from "./alert-dialog-
|
|
3
|
-
import { a as l } from "./button-
|
|
4
|
-
import { i as u } from "./translate-material-
|
|
5
|
-
import { t as d } from "./use-material-translation-
|
|
2
|
+
import { a as t, c as n, d as r, i, n as a, r as o, t as s, u as c } from "./alert-dialog-1t6ULy5i.js";
|
|
3
|
+
import { a as l } from "./button-DhiNGrdT.js";
|
|
4
|
+
import { i as u } from "./translate-material-DI3nmQ6I.js";
|
|
5
|
+
import { t as d } from "./use-material-translation-1kCHtB0p.js";
|
|
6
6
|
import { _ as f, g as p, h as m, t as h, v as g, y as _ } from "./date.utils-JTEIo3mM.js";
|
|
7
7
|
import { useCallback as v, useEffect as y, useMemo as b, useRef as x, useState as S } from "react";
|
|
8
8
|
import { Fragment as C, jsx as w, jsxs as T } from "react/jsx-runtime";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { o as e, r as t } from "./dist-DVRQkaTK.js";
|
|
2
2
|
import { i as n, n as r, r as i, t as a } from "./dist-DWZXlCZR.js";
|
|
3
|
-
import { C as o, S as s, x as c } from "./spinner-
|
|
3
|
+
import { C as o, S as s, x as c } from "./spinner-C6LP2Rw8.js";
|
|
4
4
|
import { a as l, i as u, r as d } from "./dist-DHdUUM1w.js";
|
|
5
5
|
import { c as f, i as p, l as m, o as h, r as g, s as ee } from "./in-dialog-D61Yeaol.js";
|
|
6
6
|
import { r as te } from "./escape-owner-DpaP0lm1.js";
|
|
@@ -18,6 +18,7 @@ from `@nxgt/material/components`.
|
|
|
18
18
|
| <img src="../previews/data-display-periodcards.webp" width="96" alt=""> | [PeriodCards](#periodcards) | Consecutive date ranges (terms, sprints) as cards, with a current marker and an optional link per card |
|
|
19
19
|
| <img src="../previews/data-display-chip.webp" width="96" alt=""> | [Chip](#chip) | Three looks and a dashed add pill, with slots, a selected state and a dismiss button |
|
|
20
20
|
| <img src="../previews/data-display-statcard.webp" width="96" alt=""> | [StatCard](#statcard) | KPI tile with value, hint, icon and toned delta; `href` makes it one link |
|
|
21
|
+
| | [TotalsList](#totalslist) | Labelled figures in a `dl`, amounts right-aligned, a ruled grand-total row; the screen twin of `PrintTotals` |
|
|
21
22
|
| <img src="../previews/data-display-metric-cards.webp" width="96" alt=""> | [Metric cards](#metric-cards) | Sixteen dashboard tiles |
|
|
22
23
|
| <img src="../previews/data-display-card-presets.webp" width="96" alt=""> | [Card presets](#card-presets) | Twenty-seven ready-made cards |
|
|
23
24
|
| <img src="../previews/data-display-statusindicator.webp" width="96" alt=""> | [StatusIndicator](#statusindicator) | Coloured status dot with a label |
|
|
@@ -194,7 +195,7 @@ no `style` attribute and a strict CSP is fine.
|
|
|
194
195
|
- Seat changes are not animated beyond a colour fade, which stops under
|
|
195
196
|
`prefers-reduced-motion`.
|
|
196
197
|
|
|
197
|
-
**Storybook:** `Data display/SeatRing` · **Vue:** not yet (#
|
|
198
|
+
**Storybook:** `Data display/SeatRing` · **Vue:** not yet (#1931)
|
|
198
199
|
|
|
199
200
|
---
|
|
200
201
|
|
|
@@ -269,7 +270,7 @@ const [open, setOpen] = useState(false);
|
|
|
269
270
|
the layout follows `dir` (RTL) and dark mode.
|
|
270
271
|
- Keep `front` and `description` free of the secret: they are always in the page.
|
|
271
272
|
|
|
272
|
-
**Storybook:** `Data display/SecretCard` · **Vue:** not yet (#
|
|
273
|
+
**Storybook:** `Data display/SecretCard` · **Vue:** not yet (#1938)
|
|
273
274
|
|
|
274
275
|
---
|
|
275
276
|
|
|
@@ -603,6 +604,35 @@ pass `disabled` with a `Spinner` in `leading`, or use a `Button`.
|
|
|
603
604
|
|
|
604
605
|
---
|
|
605
606
|
|
|
607
|
+
## TotalsList
|
|
608
|
+
|
|
609
|
+
On-screen counterpart of `PrintTotals`: a `dl` of labelled figures, labels at the start, amounts right-aligned in tabular figures, one column at any width (a side rail, a phone). Rows have the shape of `PrintTotalRow` (`label`, `value`, `last`), so one array feeds the screen and its print.
|
|
610
|
+
|
|
611
|
+
```tsx
|
|
612
|
+
import { TotalsList } from '@nxgt/material/components';
|
|
613
|
+
|
|
614
|
+
<TotalsList
|
|
615
|
+
label="Order totals"
|
|
616
|
+
rows={[
|
|
617
|
+
{ label: 'Subtotal', value: '1,000.00' },
|
|
618
|
+
{ label: 'Tax (19%)', value: '190.00' },
|
|
619
|
+
{ label: 'Total', value: '1,190.00', last: true },
|
|
620
|
+
]}
|
|
621
|
+
/>
|
|
622
|
+
```
|
|
623
|
+
|
|
624
|
+
| Prop | Type | Default | Effect |
|
|
625
|
+
| --- | --- | --- | --- |
|
|
626
|
+
| `rows` | `{ label, value, last?, strong?, tone? }[]` | required | `last` makes the grand total larger and bold with a rule above; `strong` emphasises a row with no rule; `tone` colours the amount (`error` for a due or negative amount, `success` for a credit; an `AppTones` tone works too) |
|
|
627
|
+
| `label` | `string` | — | accessible name: the block becomes a `group` named by it |
|
|
628
|
+
| `variant` | `'card' \| 'plain'` | `'card'` | `plain` has no border or padding, to sit inside a card you already have |
|
|
629
|
+
|
|
630
|
+
Format the amounts for the locale before passing them (`Intl.NumberFormat`); a long label wraps and the amount stays whole.
|
|
631
|
+
|
|
632
|
+
**Storybook:** `Data display/TotalsList`
|
|
633
|
+
|
|
634
|
+
---
|
|
635
|
+
|
|
606
636
|
## StatCard
|
|
607
637
|
|
|
608
638
|

|
|
@@ -812,7 +842,7 @@ import { TubeCap } from '@nxgt/material/components';
|
|
|
812
842
|
| `action` | `ReactNode` | none | trailing slot, such as an `IconButton` |
|
|
813
843
|
| `size` | `'sm' \| 'default' \| 'lg'` | `'default'` | cap of 20, 28 or 40px |
|
|
814
844
|
|
|
815
|
-
`TUBE_CAP_KINDS` lists the kinds
|
|
845
|
+
`TUBE_CAP_KINDS` lists the kinds, and `TubeCapKind` is the exported type of `kind`. The look is CSS on `data-kind`, with no inline style (strict CSP). The cap is `aria-hidden`.
|
|
816
846
|
|
|
817
847
|
**Storybook:** `Data display/TubeCap` · **Vue:** `TubeCap` (`@nxgt/material-vue/components`)
|
|
818
848
|
|
|
@@ -1367,7 +1397,7 @@ and the user's zone) and both sides agree:
|
|
|
1367
1397
|
<ChangeHistory entries={entries} now={loaderData.now} timeZone={loaderData.timeZone} />
|
|
1368
1398
|
```
|
|
1369
1399
|
|
|
1370
|
-
**Storybook:** `Data display/ChangeHistory` · **Vue:** not yet (
|
|
1400
|
+
**Storybook:** `Data display/ChangeHistory` · **Vue:** not yet (tracked as a `vue` issue)
|
|
1371
1401
|
|
|
1372
1402
|
---
|
|
1373
1403
|
|
|
@@ -1404,7 +1434,7 @@ The offset follows the instant (`Europe/Paris` is `UTC+1` in winter and
|
|
|
1404
1434
|
`UTC+2` in summer). `ChangeHistory` takes a `timeZone` and `RelativeTime` a `now`
|
|
1405
1435
|
the same way; pass the app's zone from the server so every screen agrees.
|
|
1406
1436
|
|
|
1407
|
-
**Storybook:** `Data display/ZonedTime` · **Vue:** not yet (
|
|
1437
|
+
**Storybook:** `Data display/ZonedTime` · **Vue:** not yet (tracked as a `vue` issue)
|
|
1408
1438
|
|
|
1409
1439
|
---
|
|
1410
1440
|
|
|
@@ -1473,7 +1503,7 @@ own, so they add up to less.
|
|
|
1473
1503
|
- Bar widths are SVG attributes, so server markup has no `style` attribute and
|
|
1474
1504
|
a strict CSP is fine.
|
|
1475
1505
|
|
|
1476
|
-
**Storybook:** `Data display/VoteTally` · **Vue:** not yet (#
|
|
1506
|
+
**Storybook:** `Data display/VoteTally` · **Vue:** not yet (#1940)
|
|
1477
1507
|
|
|
1478
1508
|
---
|
|
1479
1509
|
|
|
@@ -1806,7 +1836,7 @@ lock set by another code form disables its field and leaves Cancel usable.
|
|
|
1806
1836
|
button by `getByRole('button', { name: 'Activate' })` and the lock by
|
|
1807
1837
|
`getByRole('alert')`.
|
|
1808
1838
|
|
|
1809
|
-
**Storybook:** `Data display/EnrolmentCard`, `…/Shared lock`, `Guides/Accessibility/Touch targets/Verification code` · **Vue:** not yet
|
|
1839
|
+
**Storybook:** `Data display/EnrolmentCard`, `…/Shared lock`, `Guides/Accessibility/Touch targets/Verification code` · **Vue:** not yet
|
|
1810
1840
|
|
|
1811
1841
|
---
|
|
1812
1842
|
|
|
@@ -1949,4 +1979,4 @@ import { RecoveryCodesStatus, VerificationLockProvider } from '@nxgt/material/co
|
|
|
1949
1979
|
|
|
1950
1980
|
It reads the page-wide lock like [EnrolmentCard](#enrolmentcard) does. With `requireCode={false}` there is no code form, so `error` and `attemptsLeft` are not shown: the plain button follows `pending`, and is disabled by `locked` and by the page-wide lock; then the lock's text (the message of the answer that locked, or "Too many wrong codes. Try again later.") shows above it as a muted line that describes the button.
|
|
1951
1981
|
|
|
1952
|
-
**Storybook:** `Data display/RecoveryCodesStatus`, `Data display/EnrolmentCard/Shared lock` · **Vue:** not yet
|
|
1982
|
+
**Storybook:** `Data display/RecoveryCodesStatus`, `Data display/EnrolmentCard/Shared lock` · **Vue:** not yet
|
|
@@ -602,6 +602,14 @@ const items: GalleryItem[] = [
|
|
|
602
602
|
|
|
603
603
|
<Gallery items={items} preset="grid" selectable onSelectionChange={console.log} />;
|
|
604
604
|
|
|
605
|
+
// Bulk actions on the selection: they appear in the "n selected" bar.
|
|
606
|
+
<Gallery
|
|
607
|
+
items={items}
|
|
608
|
+
preset="grid"
|
|
609
|
+
selectable
|
|
610
|
+
selectionActions={(ids) => <Button onClick={() => removeAll(ids)}>Delete</Button>}
|
|
611
|
+
/>;
|
|
612
|
+
|
|
605
613
|
<LightboxGallery items={items} trigger={<button type="button">Open gallery</button>} />;
|
|
606
614
|
|
|
607
615
|
<MiniGallery items={items} maxItems={5} />;
|
|
@@ -622,6 +630,7 @@ with a `+N` tile).
|
|
|
622
630
|
| `carouselAlign` / `carouselOrientation` | `'start' \| 'center'` / `'horizontal' \| 'vertical'` | `'start'` / `'horizontal'` | where the large tile of `hero` sits; the scroll axis |
|
|
623
631
|
| `lightbox` | `boolean` | from `preset` | click opens the full-screen viewer (gestures, zoom, filmstrip, download, keyboard) |
|
|
624
632
|
| `selectable` | `boolean` | — | checkboxes on tiles; `onSelectionChange(ids)` |
|
|
633
|
+
| `selectionActions` | `ReactNode \| (selectedIds: string[]) => ReactNode` | — | bulk actions (download, move, delete) at the end of the "n selected" bar of a `selectable` gallery; a render function receives the selected ids. Hidden while nothing is selected; wraps under the count on a phone |
|
|
625
634
|
| `open` / `defaultOpen` / `onOpenChange` | `boolean` | — | control the lightbox |
|
|
626
635
|
| `onDelete` | `(item) => void` | — | adds a delete button on each tile |
|
|
627
636
|
| `aria-label` / `aria-labelledby` | `string` | `'Gallery'` label | names the gallery (the root has `role="application"`); a given `aria-labelledby` replaces the default label. `MiniGallery` and `LightboxGallery` take both. Other `div` props (`id`, `data-*`, `onKeyDown`) reach the root element |
|
|
@@ -1913,6 +1922,8 @@ Parts: `PrintDocument`, `PrintHeader`, `PrintSection`, `PrintInfoRow`,
|
|
|
1913
1922
|
`definePrintColumns` and the helpers `resolvePrintTable`,
|
|
1914
1923
|
`resolvePrintFields`, `toPrintValue` and `formatPrintValue`.
|
|
1915
1924
|
|
|
1925
|
+
For the same rows on screen, use [`TotalsList`](data-display.md#totalslist).
|
|
1926
|
+
|
|
1916
1927
|
**To get the file**, pass the document to one function: `downloadPdf`
|
|
1917
1928
|
saves it, `openPdf` opens it in a new tab (a download when a popup blocker
|
|
1918
1929
|
stops the tab), `usePdfFile` keeps a preview current, and `pdfResponse`
|
|
@@ -8,7 +8,7 @@ the app owns the data.
|
|
|
8
8
|
| --- | --- | --- |
|
|
9
9
|
| <img src="../previews/rich-widgets-chat-overview.webp" width="96" alt=""> | [Chat kit](#chat-kit) | Inbox, thread, grouped bubbles with receipts and replies, composer with quick replies, floating widget |
|
|
10
10
|
| <img src="../previews/rich-widgets-kanban.webp" width="96" alt=""> | [Kanban](#kanban) | Board with columns, swimlanes, WIP limits and drag-and-drop |
|
|
11
|
-
| <img src="../previews/rich-widgets-eventcalendar.webp" width="96" alt=""> | [EventCalendar](#eventcalendar) | Month / week / day / agenda calendar, a day view split by resource, a named time zone, phone to desktop |
|
|
11
|
+
| <img src="../previews/rich-widgets-eventcalendar.webp" width="96" alt=""> | [EventCalendar](#eventcalendar) | Month / week / day / agenda calendar, a day view split by resource, a named time zone, an event preview you can route to your app, phone to desktop |
|
|
12
12
|
| <img src="../previews/rich-widgets-native-charts-linechart.webp" width="96" alt=""> | [Charts](#charts) | Native SVG charts (line, area, bar, pie, donut, gauge, radial, funnel, heat map, radar, scatter, combo) with keyboard, summary and View data; the Nivo ones were removed in 3.0 |
|
|
13
13
|
| <img src="../previews/rich-widgets-drawing.webp" width="96" alt=""> | [Drawing](#drawing) | Vector drawing from a scene of plain data or JSX primitives: theme colours, accessible, focusable nodes, strict-CSP safe |
|
|
14
14
|
| <img src="../previews/rich-widgets-barcode.webp" width="96" alt=""> | [Barcode](#barcode) | Code 128 and Data Matrix as accessible SVG, themed and dark-aware, black on white in print, with `LabelSheet` for a printed sheet of labels |
|
|
@@ -289,11 +289,28 @@ function Schedule() {
|
|
|
289
289
|
}
|
|
290
290
|
```
|
|
291
291
|
|
|
292
|
+
To edit and delete in your own dialog instead of the built-in inline fields:
|
|
293
|
+
|
|
294
|
+
```tsx
|
|
295
|
+
<EventCalendar
|
|
296
|
+
events={events}
|
|
297
|
+
onEventsChange={setEvents}
|
|
298
|
+
previewFields={[]}
|
|
299
|
+
onEventEdit={(e) => openEditor(e.id)}
|
|
300
|
+
onEventDelete={(e) => confirmThenRemove(e.id)}
|
|
301
|
+
/>
|
|
302
|
+
```
|
|
303
|
+
|
|
292
304
|
| Prop | Type | Default | Effect |
|
|
293
305
|
| --- | --- | --- | --- |
|
|
294
306
|
| `events` / `defaultEvents` | `CalendarEvent[]` | — | controlled / uncontrolled events (ISO `start` / `end`) |
|
|
295
307
|
| `onChange` | `(change: EventCalendarChange) => void` | — | after a drag or resize, with the previous event |
|
|
296
308
|
| `onSlotClick` | `(slot: EventCalendarSlot) => void` | — | click on an empty slot or day — create an event there |
|
|
309
|
+
| `onEventClick` | `(event: CalendarEvent) => void` | — | an event was clicked; it runs even with `onSlotClick` set (an event click never reports a slot) |
|
|
310
|
+
| `eventPreview` | `boolean` | `true` | `false` skips the preview popover, so `onEventClick` alone handles the click |
|
|
311
|
+
| `previewFields` | `EventCalendarPreviewField[]` | all three | the fields the preview edits in place (`'title' \| 'color' \| 'description'`); `[]` keeps the time range and the actions |
|
|
312
|
+
| `onEventEdit` | `(event: CalendarEvent) => void` | — | adds an Edit button to the preview; the app opens its own editor; hidden when the calendar or the event is `disabled` |
|
|
313
|
+
| `onEventDelete` | `(event: CalendarEvent) => void` | — | the preview's delete button calls this instead of the built-in confirmation and removal; the app confirms and deletes; hidden when the calendar or the event is `disabled`, so it never runs for those |
|
|
297
314
|
| `view` / `defaultView` | `'month' \| 'week' \| 'workweek' \| 'day' \| 'agenda'` | `'month'` | the visible view |
|
|
298
315
|
| `date` / `defaultDate` | `string` | today | the date the view is centred on |
|
|
299
316
|
| `startHour` / `endHour` | `number` | `0` / `24` | hours shown in the time grids |
|
|
@@ -425,6 +442,10 @@ function Timetable() {
|
|
|
425
442
|
| `onEventsChange` | `(events: EventCalendarTemplateEvent[]) => void` | — | the whole list after a move, a resize, an edit or a delete |
|
|
426
443
|
| `onChange` | `(change: EventCalendarTemplateChange) => void` | — | `{ events, event, previous }` after a move, a resize or an edit |
|
|
427
444
|
| `onEventClick` | `(event: EventCalendarTemplateEvent) => void` | — | an event was clicked |
|
|
445
|
+
| `onEventEdit` | `(event: EventCalendarTemplateEvent) => void` | — | adds an Edit button to the preview and receives the `EventCalendarTemplateEvent`; both buttons are hidden when the calendar or the event is `disabled` |
|
|
446
|
+
| `onEventDelete` | `(event: EventCalendarTemplateEvent) => void` | — | the Delete button calls this with the `EventCalendarTemplateEvent`, skipping the built-in confirmation and removal; both buttons are hidden when the calendar or the event is `disabled` |
|
|
447
|
+
| `eventPreview` | `boolean` | `true` | `false` skips the preview popover; see the dated table |
|
|
448
|
+
| `previewFields` | `EventCalendarPreviewField[]` | all three | the fields the preview edits (`'title' \| 'color' \| 'description'`); see the dated table |
|
|
428
449
|
| `onSlotClick` | `(slot: EventCalendarTemplateSlot) => void` | — | `{ weekday, start, end, lane? }` of the free slot clicked or dragged over; `lane` is the one picked in the switch |
|
|
429
450
|
| `view` / `defaultView` / `onViewChange` | `'week' \| 'workweek'` | `'week'` | the visible view |
|
|
430
451
|
| `renderEvent` | `(event: EventCalendarTemplateEvent) => ReactNode` | — | replaces how an event is drawn |
|
package/docs/guides/helpers.md
CHANGED
|
@@ -142,6 +142,7 @@ Vue: the Redux helpers are Pinia store factories: `defineLocalStore`
|
|
|
142
142
|
| `useSubmitOnce(busy?)` | One submit in flight: wraps a submit handler so a double click or a second Enter is dropped until the request ends (the handler's promise, or `busy` back to false). See [below](#usesubmitonce). |
|
|
143
143
|
| `useDrafts<T>(storageKey, { serialize?, parse?, storage? })`, `clearDrafts(storageKey, storage?)` | Unsent values kept by key in `sessionStorage`: `{ get, set, drop, clear, keys, loaded }`. Read after the first render (no hydration mismatch), storage errors swallowed, `drop(key)` once saved; `clearDrafts` empties a store key without a hook (sign-out). See [below](#usedrafts). |
|
|
144
144
|
| `useUnsavedGuard(dirty, { block, … })`, `useDiscardGuard(dirty)`, `useReactRouterBlock` | Stop losing a dirty form: a "Leave without saving?" dialog on in-app navigation and on closing a dialog form, plus the browser's own `beforeunload` prompt. See [below](#useunsavedguard). |
|
|
145
|
+
| `usePoll({ ms, enabled?, read, onError? })`, `startPoll({ ms, read, active?, visible?, onError? })` | Reads again every `ms` while `enabled` and the page is visible, one read at a time; the timer is cleared on unmount and when `enabled` turns false. `startPoll` is the framework-free loop, and returns its stop. See [below](#usepoll). |
|
|
145
146
|
| `createSubmitGuard()`, `busySettler(guard)` | The framework-free guard behind `useSubmitOnce` (`@nxgt/material-core/submit-guard`): `{ once(run, { settleSync? }), settle(run?), pendingRun() }`, and the function that settles it from a busy flag. |
|
|
146
147
|
|
|
147
148
|
```tsx
|
|
@@ -436,6 +437,45 @@ drafts keep what was typed, the guard asks before it is dropped; they combine.
|
|
|
436
437
|
Storybook: `Guides/Hooks/useUnsavedGuard` (leave, stay, release after save,
|
|
437
438
|
query change, flush, dialog form). No Vue twin yet (`vue` issue #2019).
|
|
438
439
|
|
|
440
|
+
### `usePoll`
|
|
441
|
+
|
|
442
|
+
Several screens re-read a resource every few seconds while something is under
|
|
443
|
+
way (a sync, a pending state). The hook owns the interval, the visibility check
|
|
444
|
+
and the single-flight guard.
|
|
445
|
+
|
|
446
|
+
```tsx
|
|
447
|
+
import { usePoll } from '@nxgt/material/hooks';
|
|
448
|
+
|
|
449
|
+
export function JobStatus({ job, reload }: { job: Job; reload: () => Promise<void> }) {
|
|
450
|
+
usePoll({
|
|
451
|
+
ms: 3000,
|
|
452
|
+
enabled: job.status === 'running',
|
|
453
|
+
read: reload,
|
|
454
|
+
onError: (error) => console.warn('poll failed', error),
|
|
455
|
+
});
|
|
456
|
+
return <p>{job.status}</p>;
|
|
457
|
+
}
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
- **Visible pages only.** A tick that falls while
|
|
461
|
+
`document.visibilityState` is not `visible` is skipped, not queued, so
|
|
462
|
+
returning to the tab waits for the next tick.
|
|
463
|
+
- **Never two reads at once.** A tick that falls while `read` (its promise) is
|
|
464
|
+
still running is skipped, also after a restart (a new `ms`, `enabled` back on).
|
|
465
|
+
- **Stops cleanly.** The timer is cleared on unmount and when `enabled` turns
|
|
466
|
+
false; turning it back on starts a new interval.
|
|
467
|
+
- **First read after `ms`.** Call `read` yourself for an immediate one.
|
|
468
|
+
- **Latest `read`.** `read` and `onError` may be new on every render; the
|
|
469
|
+
interval does not restart. Only `ms` and `enabled` restart it.
|
|
470
|
+
- **Errors.** A read that throws or rejects is passed to `onError` and the poll
|
|
471
|
+
goes on; without `onError` it is ignored.
|
|
472
|
+
- **Server.** Nothing runs during render or on the server.
|
|
473
|
+
- **Outside React**, `startPoll({ ms, read, active?, visible? })` is the same
|
|
474
|
+
loop; `active()` and `visible()` are checked at each tick, and the call
|
|
475
|
+
returns the function that stops it.
|
|
476
|
+
|
|
477
|
+
No Vue twin yet (`vue` issue #2498).
|
|
478
|
+
|
|
439
479
|
## `@nxgt/material/i18n`
|
|
440
480
|
|
|
441
481
|
| Export | What it does |
|
package/docs/guides/layouts.md
CHANGED
|
@@ -204,8 +204,11 @@ The props of each are in
|
|
|
204
204
|
The `Guides/Recipes` stories in Storybook are tested whole screens (the code
|
|
205
205
|
ships with the `screen-recipes` skill of the `nxgt-material` plugin): a home
|
|
206
206
|
dashboard, a list and detail, a form and dialog, a table and settings, a dense
|
|
207
|
-
detail page, a status board, a landing page
|
|
208
|
-
|
|
207
|
+
detail page, a status board, a landing page, a search dialog with its results
|
|
208
|
+
page, a team feed, the sign-in, sign-up and forgotten-password screens, a
|
|
209
|
+
gallery of pictures, settings with sections, a messages thread, an overview of
|
|
210
|
+
rearrangeable widgets on `DashboardGrid` and a document editor. Start from the
|
|
211
|
+
closest one and replace the data.
|
|
209
212
|
|
|
210
213
|
## See also
|
|
211
214
|
|
package/docs/guides/theming.md
CHANGED
|
@@ -68,7 +68,7 @@ at the top are needed is in [getting started](../getting-started.md#styles).
|
|
|
68
68
|
| `--accent`, `--accent-foreground` | `bg-accent`, … | hover surfaces |
|
|
69
69
|
| `--nxgt-accent` | `[--nxgt-accent:…]` | the mark colour of the selection controls: the fill, handle, state layer and stop dots of `Slider`, the on state of `Switch`, the box and dot of `Checkbox` and `Radio`. It defaults to `--primary` (`--primary-text` in dark) and is set per control, so override it on the control itself, not on `:root` |
|
|
70
70
|
| `--error`, `--success`, `--info`, `--warning` (+ `-foreground`) | `bg-error`, `text-success`, … | the status colours of `Button`, `Alert`, `Badge`, toasts |
|
|
71
|
-
| `--primary-text` | `text-primary-text` | primary drawn as text or an icon on a page, card or popover surface: `Typography tone="primary"`, links, the `Alert` primary icon, selected labels. In light, `--primary` mixed toward black: 96 % at most, solved lower on a tinted page so a tonal Button label on a striped row, or straight on the page ground, reaches 4.6:1 (
|
|
71
|
+
| `--primary-text` | `text-primary-text` | primary drawn as text or an icon on a page, card or popover surface: `Typography tone="primary"`, links, the `Alert` primary icon, selected labels. In light, `--primary` mixed toward black: 96 % at most, solved lower on a tinted page so a tonal Button label on a striped, selected or header row, or straight on the page ground, reaches 4.6:1 (79 % on teal, 76 % on corail; read the shipped theme file for each preset); in dark, `--primary` mixed 60 % with white (`color-mix(in oklab, var(--primary) 40%, white)`), well over 4.5:1 on `--background` and `--card` |
|
|
72
72
|
| `--primary-indicator` | `bg-primary-indicator`, `border-primary-indicator`, `ring-primary-indicator`, `stroke-primary-indicator` | primary drawn as a non-text mark that carries a state (WCAG 1.4.11, 3:1): an active bar or dot, a selected or focused border, a ring, a spinner arc. Equal to `--primary` in light; in dark, `--primary` mixed 25 % with white (`color-mix(in oklab, var(--primary) 75%, white)`), 4.8:1 on `--background`, 4.5:1 on `--card`, 4.2:1 on `--muted` (`--primary` itself gives 2.7, 2.5 and 2.3:1) |
|
|
73
73
|
| `--error-text` | `text-error-text` | error drawn as text: field messages, `HelperText` in its error state, form and dialog errors, `variant="error"` menu items |
|
|
74
74
|
| `--destructive` | `bg-destructive`, `text-destructive` | deprecated alias of `--error`: the light theme sets it to `var(--error)`, the dark theme keeps its own value; use `--error` |
|
|
@@ -1012,7 +1012,7 @@ override on the root, or use a [theme zone](#themes), which re-declares them.
|
|
|
1012
1012
|
for the same reason: the brand colour is a dark fill (it keeps near-white text
|
|
1013
1013
|
readable on a button) and reads at only about 2:1 as text on the dark surfaces.
|
|
1014
1014
|
The light value is `color-mix(in oklab, var(--primary) 96%, black)` at most (primary
|
|
1015
|
-
4 % toward black, 7.9:1 on the white page; the share is solved per theme and drops when a tinted page would leave a tonal Button label under 4.6:1 on a striped row or on the page ground, to
|
|
1015
|
+
4 % toward black, 7.9:1 on the white page; the share is solved per theme and drops when a tinted page would leave a tonal Button label under 4.6:1 on a striped, selected or header row or on the page ground, to 79 % on teal); the dark one is
|
|
1016
1016
|
`color-mix(in oklab, var(--primary) 40%, white)` (primary mixed 60 % with
|
|
1017
1017
|
white, the recipe of the tonal `Button` labels). `Typography tone="primary"`,
|
|
1018
1018
|
the `Alert` primary icon, links, selected labels and the other primary text of
|
package/docs/roadmap.md
CHANGED
|
@@ -6,6 +6,12 @@ version they shipped in, and planned entries may name the major they target.
|
|
|
6
6
|
|
|
7
7
|
## Now
|
|
8
8
|
|
|
9
|
+
- **App shell header refresh** — `AppHeader` and the look `TopAppBar`
|
|
10
|
+
shares sit flat on the page ground and tint when content scrolls under
|
|
11
|
+
them; the actions are grouped in a pill, the search is a pill field (an
|
|
12
|
+
icon on a phone), and the menu button is a ghost icon button. The new look
|
|
13
|
+
is the default in a minor, with no API change; an A/B preview comes first
|
|
14
|
+
([#2503](https://github.com/softistx/nxgt-material/issues/2503)).
|
|
9
15
|
- **Calculator** — `@nxgt/material/calculator` is an exact-decimal calculator
|
|
10
16
|
(Standard, Scientific, point of sale, Financial, Conversion, Programmer;
|
|
11
17
|
every variant but Standard loads on demand)
|
|
@@ -166,13 +172,10 @@ version they shipped in, and planned entries may name the major they target.
|
|
|
166
172
|
descriptions, a small empty state, loading rows and an in-list search
|
|
167
173
|
pill. What changes on upgrade:
|
|
168
174
|
[The field look (2.x)](guides/field-look-2-x.md)
|
|
175
|
+
- **`TotalsList`** — the on-screen `PrintTotals` (#2490): React only for now; Vue twin is #2492.
|
|
169
176
|
|
|
170
177
|
## Next
|
|
171
178
|
|
|
172
|
-
- **Seven more layout recipes** — Feed, Gallery, Auth, Thread, settings,
|
|
173
|
-
dashboard and editor screens, each a tested Storybook recipe under
|
|
174
|
-
Guides/Recipes with its code beside it, on the layouts the shell now ships
|
|
175
|
-
([#2413](https://github.com/softistx/nxgt-material/issues/2413)).
|
|
176
179
|
- **FilterBar "Add a filter" stays on its row** — the button no longer wraps
|
|
177
180
|
alone onto a second row on a desktop screen ([#1752](https://github.com/softistx/nxgt-material/issues/1752)).
|
|
178
181
|
|
|
@@ -383,6 +386,8 @@ version they shipped in, and planned entries may name the major they target.
|
|
|
383
386
|
|
|
384
387
|
## Shipped
|
|
385
388
|
|
|
389
|
+
- **Seven more layout recipes (next minor)** — whole screens to start from under Guides/Recipes, each a tested Storybook story with its code in the plugin's `screen-recipes` skill: a team feed, a gallery of pictures by day, sign-in, sign-up and forgotten-password screens, a messages thread, settings with sections, an overview of rearrangeable widgets and a document editor, on the layouts the shell ships ([#2413](https://github.com/softistx/nxgt-material/issues/2413)).
|
|
390
|
+
|
|
386
391
|
- **Search dialog and results page recipe (next patch)** — a command dialog (Ctrl/Cmd+K and a header button), debounced grouped suggestions, type chips, a conditional filter and highlighted result cards, with its code in the plugin's `screen-recipes` skill ([#2333](https://github.com/softistx/nxgt-material/issues/2333)).
|
|
387
392
|
|
|
388
393
|
- **Layouts: adaptive navigation, headers and page layouts (3.80.0)** — `ActivityLayout` takes `navigation` (a bottom bar with More and badges, a rail with a FAB or expanded, a standard or modal drawer, a collapsible sidebar, a top navigation with dropdowns, two-level navigation, a floating toolbar or none, chosen for phone, tablet and desktop) and `header` (small, center-aligned, medium and large collapsing on scroll, hide on scroll, a search bar that opens full screen on a phone, sticky tabs), and a route adds a back arrow with `handle.back`; each piece is also exported. Page layouts grow with it: an inspector pane and the selection in the URL for `ListDetailsLayout`, phone modes and a container breakpoint for `PaneLayout`, a centred form and wizard for `ThreadLayout`, a split `AuthCard`, spans and masonry for `ResponsiveGrid`, tabs for `Kanban` on a phone, `Doc` drawn inside the shell, and new `SettingsLayout`, `DashboardGrid` (tiles the user rearranges), `EditorLayout` and `LandingLayout` (with `LandingSection` and `SiteFooter`). Everything is opt-in; the shell's default is unchanged. [Layouts guide](guides/layouts.md) ([#2103](https://github.com/softistx/nxgt-material/issues/2103)). Follow-ups: a resize handle for `EditorLayout`'s properties panel and a separate open state for its phone sheet.
|
package/docs/troubleshooting.md
CHANGED
|
@@ -1182,7 +1182,7 @@ given, `leading` replaces `icon` (and warns in development).
|
|
|
1182
1182
|
**When:** axe (or Lighthouse) reports `color-contrast` on a `tonal` or
|
|
1183
1183
|
`outlined` `Button` or `IconButton` (`primary` in the dark theme, `error`,
|
|
1184
1184
|
`warning` and `success`), at rest or hovered, focused or pressed; on the
|
|
1185
|
-
subtitle of a selected `ListTile`; or on a `Badge` link while it is hovered.
|
|
1185
|
+
subtitle of a selected `ListTile`; or on a `Badge` link while it is hovered; or on a tonal primary `Button` in a selected `Table` row or a table header cell (light, 4.1 to 4.4:1 before the share of `--primary-text` was solved against those surfaces, #2495).
|
|
1186
1186
|
**Why:** those variants drew their text in the token itself, and some tokens
|
|
1187
1187
|
do not reach 4.5:1 as text on the page and on their own tint: the dark
|
|
1188
1188
|
`--primary` is a dark indigo (2.2:1 on `--card`), the light `--error` gave
|
|
@@ -1245,7 +1245,7 @@ on the page; the catalogue's own primary text passes.
|
|
|
1245
1245
|
**Why:** it is drawn with `text-primary`, the fill colour. The brand colour is
|
|
1246
1246
|
dark so that near-white text reads on it, which makes it too dark to read as
|
|
1247
1247
|
text on the dark surfaces. Primary text has its own token, `--primary-text`:
|
|
1248
|
-
`--primary` mixed toward black in light (96 % at most, solved per theme), `--primary` mixed 60 % with white in dark.
|
|
1248
|
+
`--primary` mixed toward black in light (96 % at most, solved per theme, lower when a tonal label sits on a tinted row, selected row or header), `--primary` mixed 60 % with white in dark.
|
|
1249
1249
|
**Fix:** draw primary text with `text-primary-text`; keep `text-primary` for
|
|
1250
1250
|
fills, borders and rings:
|
|
1251
1251
|
|
|
@@ -21,9 +21,9 @@
|
|
|
21
21
|
--primary: oklch(46% 0.1135 276.35);
|
|
22
22
|
--primary-foreground: oklch(0.984 0.003 247.858);
|
|
23
23
|
/* Primary drawn as text or an icon on a normal surface (`text-primary-text`):
|
|
24
|
-
the colour mixed
|
|
25
|
-
the
|
|
26
|
-
--primary-text: color-mix(in oklab, var(--primary)
|
|
24
|
+
the colour mixed 10 % toward black in light, which keeps it above 4.5:1 on
|
|
25
|
+
the page, a Card and the tinted row, header and ground surfaces a tonal Button label sits on; the dark theme lifts it. */
|
|
26
|
+
--primary-text: color-mix(in oklab, var(--primary) 90%, black);
|
|
27
27
|
/* Primary drawn as a non-text mark (WCAG 1.4.11, 3:1): an indicator bar or dot,
|
|
28
28
|
a selected or focused border, a ring, a spinner arc, a progress fill
|
|
29
29
|
(`bg-primary-indicator`, `border-primary-indicator`...). Light is --primary;
|
|
@@ -184,6 +184,18 @@
|
|
|
184
184
|
min-height: 2.75rem;
|
|
185
185
|
}
|
|
186
186
|
}
|
|
187
|
+
/* Nothing to show (#2497): no select-all, no sort, no "Filters" trigger, no
|
|
188
|
+
* actions and no bulk bar leave both slots empty, and the row would be an
|
|
189
|
+
* empty 40px gap under the filter bar. Any control fills a slot, and the row
|
|
190
|
+
* is back. */
|
|
191
|
+
[data-slot="server-table-phone-row"]:has(
|
|
192
|
+
> [data-slot="server-table-phone-row-start"]:empty
|
|
193
|
+
):has(
|
|
194
|
+
> [data-slot="server-table-phone-row-end"]
|
|
195
|
+
> [data-slot="server-table-phone-sort"]:only-child:empty
|
|
196
|
+
) {
|
|
197
|
+
display: none;
|
|
198
|
+
}
|
|
187
199
|
@media (pointer: coarse) {
|
|
188
200
|
/* The 32px bulk buttons reach 44px with an invisible 6px margin: a gap of
|
|
189
201
|
* 12px keeps neighbours from taking each other's edge. */
|