@nxgt/material 3.17.0 → 3.19.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 +26 -0
- package/README.md +3 -3
- package/dist/{async-slice-BA7wI9qp.js → async-slice-nTRgm_ct.js} +2 -2
- package/dist/{button-DOYHfcMJ.js → button-rdIhY2BT.js} +1 -1
- package/dist/charts.js +3 -3
- package/dist/{chip-C8MB2xzb.js → chip-CEau88ZV.js} +1 -1
- package/dist/{code-editor-BqeS_XMJ.js → code-editor-DHB5ytUz.js} +4 -4
- package/dist/code-editor.js +4 -4
- package/dist/{code-language-items-DOr9J9yu.js → code-language-items-Dww9amx_.js} +2 -2
- package/dist/{components-D5-uZqnU.js → components-CjC1GISf.js} +18498 -17839
- package/dist/components.js +15 -15
- package/dist/{dialog-CFIn1NPR.js → dialog-B2GXKBp3.js} +1 -1
- package/dist/dnd.js +1 -1
- package/dist/{dropdown-menu-CL6mNhgT.js → dropdown-menu-mTDyFwbQ.js} +1 -1
- package/dist/editor.js +7 -7
- package/dist/{empty-state-BNljKZLV.js → empty-state-CJh9f2pc.js} +1 -1
- package/dist/hooks.js +2 -2
- package/dist/{i18n-provider-WReTVxE3.js → i18n-provider-BpZOKh7U.js} +1 -1
- package/dist/i18n.js +5 -5
- package/dist/{icon-badge-lfAUxNe8.js → icon-badge-CiWXvKCs.js} +1 -1
- package/dist/lib/components/ui/collections/data-table/partials/data-table-page-control.d.ts +3 -1
- package/dist/lib/components/ui/collections/data-table/server-pagination.d.ts +5 -0
- package/dist/lib/components/ui/collections/list-empty/empty-icon-style.d.ts +11 -0
- package/dist/lib/components/ui/collections/list-empty/list-empty-page.d.ts +9 -0
- package/dist/lib/components/ui/collections/list-empty/list-empty.d.ts +29 -6
- package/dist/lib/components/ui/collections/server-table/partials/server-table-band-classes.d.ts +9 -0
- package/dist/lib/components/ui/collections/server-table/partials/server-table-band.d.ts +5 -1
- package/dist/lib/components/ui/collections/server-table/partials/server-table-empty-page.d.ts +10 -0
- package/dist/lib/components/ui/collections/server-table/partials/server-table-passed-through.d.ts +2 -0
- package/dist/lib/components/ui/collections/server-table/server-table.d.ts +1 -1
- package/dist/lib/components/ui/collections/server-table/types.d.ts +43 -8
- package/dist/lib/components/ui/feedback/empty-state/empty-state.d.ts +2 -0
- package/dist/lib/components/ui/selection/switcher/partials/switcher-footer.d.ts +13 -0
- package/dist/lib/components/ui/selection/switcher/partials/switcher-groups.d.ts +9 -0
- package/dist/lib/components/ui/selection/switcher/partials/switcher-list.d.ts +8 -0
- package/dist/lib/components/ui/selection/switcher/partials/switcher-menu.d.ts +13 -0
- package/dist/lib/components/ui/selection/switcher/partials/switcher-popover.d.ts +12 -0
- package/dist/lib/components/ui/selection/switcher/partials/switcher-row.d.ts +22 -0
- package/dist/lib/components/ui/selection/switcher/partials/switcher-search.d.ts +14 -0
- package/dist/lib/components/ui/selection/switcher/partials/switcher-sheet.d.ts +12 -0
- package/dist/lib/components/ui/selection/switcher/partials/switcher-tile.d.ts +7 -0
- package/dist/lib/components/ui/selection/switcher/partials/switcher-tooltip.d.ts +9 -0
- package/dist/lib/components/ui/selection/switcher/partials/switcher-trigger.d.ts +17 -0
- package/dist/lib/components/ui/selection/switcher/switcher.d.ts +10 -15
- package/dist/lib/components/ui/selection/switcher/switcher.utils.d.ts +13 -0
- package/dist/lib/components/ui/selection/switcher/types.d.ts +73 -0
- package/dist/lib/components/ui/selection/switcher/use-clipped.d.ts +3 -0
- package/dist/lib/components/ui/selection/switcher/use-switcher-list.d.ts +21 -0
- package/dist/lib/i18n/resources/en/en.d.ts +12 -0
- package/dist/lib/i18n/resources/en/material.json.d.ts +12 -0
- package/dist/lib/i18n/resources/fr/fr.d.ts +12 -0
- package/dist/lib/i18n/resources/fr/material.json.d.ts +12 -0
- package/dist/lib/i18n/resources/resources.d.ts +24 -0
- package/dist/lib/i18n/translator.d.ts +1 -1
- package/dist/lib.js +1 -1
- package/dist/main.js +21 -21
- package/dist/map.js +4 -4
- package/dist/material.css +1 -1
- package/dist/pdf-reader.js +1 -1
- package/dist/print.js +2 -2
- package/dist/{public-B4lpmahC.js → public-DWuBn4t_.js} +6 -6
- package/dist/{rich-code-block-CvqJmvuT.js → rich-code-block-CLkufAhI.js} +4 -4
- package/dist/{sortable-provider-DE692phf.js → sortable-provider-BofwO9zZ.js} +1 -1
- package/dist/{spinner-CGgOgUCe.js → spinner-B7HCQMFr.js} +1 -1
- package/dist/{stored-language-DiCe2ZcR.js → stored-language-CJn_iWwG.js} +26 -2
- package/dist/theme-picker.js +2 -2
- package/dist/{theme-toggle-O6z6PokP.js → theme-toggle-mQzIR1hw.js} +1 -1
- package/dist/{toolbar-items-DCZxamGy.js → toolbar-items-Tn3MMu-s.js} +2 -2
- package/dist/{translate-material-DZ_i8xJx.js → translate-material-CCyVEi_f.js} +2 -2
- package/dist/{translator-Ch1dEqFf.js → translator-1THr41fc.js} +1 -1
- package/dist/{use-chat-composer-ByWwRuYg.js → use-chat-composer-BBFuKNqC.js} +12 -12
- package/dist/{use-heading-spy-S6PT8wPG.js → use-heading-spy-DNFfHQJs.js} +1 -1
- package/dist/{use-material-translation-C4ysFJtw.js → use-material-translation-BFQODuQz.js} +2 -2
- package/docs/components/data-table-filter-and-lists.md +75 -10
- package/docs/components/overlays-and-menus.md +1 -1
- package/docs/components/selection-and-choice.md +76 -6
- package/docs/previews/selection-choice-switcher.webp +0 -0
- package/docs/roadmap.md +1 -1
- package/docs/troubleshooting.md +18 -1
- package/package.json +2 -2
package/dist/pdf-reader.js
CHANGED
package/dist/print.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { r as e } from "./i18n-provider-
|
|
2
|
-
import { t } from "./translate-material-
|
|
1
|
+
import { r as e } from "./i18n-provider-BpZOKh7U.js";
|
|
2
|
+
import { t } from "./translate-material-CCyVEi_f.js";
|
|
3
3
|
import { Children as n, createContext as r, isValidElement as i, useCallback as a, useContext as o, useEffect as s, useMemo as c, useState as l } from "react";
|
|
4
4
|
import { jsx as u, jsxs as d } from "react/jsx-runtime";
|
|
5
5
|
import { resolvePdfFileName as f } from "@nxgt/material-core/pdf-file-name";
|
|
@@ -6,18 +6,18 @@ import { c as i, i as a, l as o, n as s, o as c, s as l } from "./dist-lmHmz_bu.
|
|
|
6
6
|
import { a as u, o as d } from "./tooltip-CkttDIab.js";
|
|
7
7
|
import { i as f } from "./dist-C4wtXCjf.js";
|
|
8
8
|
import { r as p, t as m } from "./in-dialog-Vwkyp-M5.js";
|
|
9
|
-
import { C as h, D as g, E as _, O as v, S as y, T as b, _ as x, f as S, g as ee, k as te, r as ne, t as C, u as re, w } from "./dialog-
|
|
10
|
-
import { c as T, d as ie, f as E, i as ae, l as oe, n as se, o as D, t as ce, u as O } from "./dropdown-menu-
|
|
11
|
-
import { S as le, a as k, d as A, g as ue, h as de, i as fe, m as pe, n as j, r as me, t as M, u as he, w as ge } from "./toolbar-items-
|
|
12
|
-
import { t as N } from "./use-material-translation-
|
|
13
|
-
import { t as _e } from "./button-
|
|
9
|
+
import { C as h, D as g, E as _, O as v, S as y, T as b, _ as x, f as S, g as ee, k as te, r as ne, t as C, u as re, w } from "./dialog-B2GXKBp3.js";
|
|
10
|
+
import { c as T, d as ie, f as E, i as ae, l as oe, n as se, o as D, t as ce, u as O } from "./dropdown-menu-mTDyFwbQ.js";
|
|
11
|
+
import { S as le, a as k, d as A, g as ue, h as de, i as fe, m as pe, n as j, r as me, t as M, u as he, w as ge } from "./toolbar-items-Tn3MMu-s.js";
|
|
12
|
+
import { t as N } from "./use-material-translation-BFQODuQz.js";
|
|
13
|
+
import { t as _e } from "./button-rdIhY2BT.js";
|
|
14
14
|
import { n as ve, t as ye } from "./icon-button-ifTpXt0A.js";
|
|
15
15
|
import { t as be } from "./useEvent-2fKq-6w8.js";
|
|
16
16
|
import { n as xe, t as Se } from "./toggle-group-BMJNcFAC.js";
|
|
17
17
|
import { o as Ce } from "./escape-owner-C4W_sOAU.js";
|
|
18
18
|
import { n as we } from "./use-slice-reducer-BGkeGtML.js";
|
|
19
19
|
import { r as Te } from "./use-csp-nonce-ZKs9k-ov.js";
|
|
20
|
-
import { n as Ee, t as De } from "./empty-state-
|
|
20
|
+
import { n as Ee, t as De } from "./empty-state-CJh9f2pc.js";
|
|
21
21
|
import { t as Oe } from "./client-only.utils-3nHNzCki.js";
|
|
22
22
|
import { t as ke } from "./use-scroll-away-PQRFZkT2.js";
|
|
23
23
|
import { ArrowLeft as Ae, BookOpenText as je, ChevronDown as Me, ChevronLeft as Ne, ChevronRight as Pe, ChevronUp as Fe, Download as Ie, Eraser as Le, FileText as Re, FileWarning as ze, FileX2 as Be, Highlighter as Ve, KeyRound as He, LayoutGrid as Ue, List as We, Loader2 as Ge, Maximize as Ke, MessageSquareText as qe, Minimize as Je, MoreVertical as Ye, MousePointer2 as Xe, MoveHorizontal as Ze, PanelLeft as Qe, Pen as $e, PencilLine as et, Printer as tt, RotateCw as nt, Search as rt, StickyNote as it, Type as at, Underline as ot, Undo2 as st, Volume2 as ct, X as lt, XIcon as ut, ZoomIn as dt, ZoomOut as ft } from "lucide-react";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as e } from "./tooltip-CkttDIab.js";
|
|
2
|
-
import { c as t, n, t as r } from "./dropdown-menu-
|
|
3
|
-
import { t as i } from "./use-material-translation-
|
|
4
|
-
import { a, i as o, n as s, o as c, t as l } from "./code-language-items-
|
|
2
|
+
import { c as t, n, t as r } from "./dropdown-menu-mTDyFwbQ.js";
|
|
3
|
+
import { t as i } from "./use-material-translation-BFQODuQz.js";
|
|
4
|
+
import { a, i as o, n as s, o as c, t as l } from "./code-language-items-Dww9amx_.js";
|
|
5
5
|
import { i as u, n as d, r as f, s as p } from "./dist-C3GR7kJd.js";
|
|
6
6
|
import { t as m } from "./code-block-spec-CGLKRhwD.js";
|
|
7
7
|
import { Check as h, ChevronDown as g, Copy as _, Maximize2 as v, WrapText as y } from "lucide-react";
|
|
@@ -143,7 +143,7 @@ function M({ node: e, editor: t, updateAttributes: n, editable: r, wrap: a, onWr
|
|
|
143
143
|
}
|
|
144
144
|
//#endregion
|
|
145
145
|
//#region lib/components/ui/widgets/editor/extensions/code/code-block-open.tsx
|
|
146
|
-
var N = x(() => import("./code-editor-
|
|
146
|
+
var N = x(() => import("./code-editor-DHB5ytUz.js").then((e) => e.n).then((e) => ({ default: e.CodeEditor })));
|
|
147
147
|
function P() {
|
|
148
148
|
let { t: e } = i();
|
|
149
149
|
return /* @__PURE__ */ T("div", {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as e } from "./utils-BLfntITJ.js";
|
|
2
2
|
import { t } from "./dist-DVRQkaTK.js";
|
|
3
|
-
import { t as n } from "./use-material-translation-
|
|
3
|
+
import { t as n } from "./use-material-translation-BFQODuQz.js";
|
|
4
4
|
import { t as r } from "./icon-button-ifTpXt0A.js";
|
|
5
5
|
import { t as i } from "./compose-refs-DZ0iIVF-.js";
|
|
6
6
|
import { GripVertical as a } from "lucide-react";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as e } from "./utils-BLfntITJ.js";
|
|
2
2
|
import { o as t } from "./tooltip-CkttDIab.js";
|
|
3
|
-
import { t as n } from "./use-material-translation-
|
|
3
|
+
import { t as n } from "./use-material-translation-BFQODuQz.js";
|
|
4
4
|
import { jsx as r } from "react/jsx-runtime";
|
|
5
5
|
//#region lib/components/ui/feedback/spinner/spinner.tsx
|
|
6
6
|
var i = t("transition-all duration-500", {
|
|
@@ -505,6 +505,8 @@ var t = {
|
|
|
505
505
|
pagination: {
|
|
506
506
|
previous: "Previous",
|
|
507
507
|
next: "Next",
|
|
508
|
+
"previous-page": "Previous page",
|
|
509
|
+
"next-page": "Next page",
|
|
508
510
|
"go-to-next-page": "Go to next page",
|
|
509
511
|
"go-to-previous-page": "Go to previous page",
|
|
510
512
|
"go-to-first-page": "Go to first page",
|
|
@@ -2600,7 +2602,17 @@ var t = {
|
|
|
2600
2602
|
"scatter-series": "{series}: {count, plural, one {# point} other {# points}}."
|
|
2601
2603
|
}
|
|
2602
2604
|
},
|
|
2603
|
-
"list-details": { back: "Back to the list" }
|
|
2605
|
+
"list-details": { back: "Back to the list" },
|
|
2606
|
+
switcher: {
|
|
2607
|
+
search: "Search",
|
|
2608
|
+
"search-placeholder": "Search…",
|
|
2609
|
+
clear: "Clear the search",
|
|
2610
|
+
empty: "No results for “{query}”",
|
|
2611
|
+
results: "{count, plural, =0 {No results} one {# result} other {# results}}",
|
|
2612
|
+
recent: "Recent",
|
|
2613
|
+
manage: "Manage…",
|
|
2614
|
+
choose: "Choose"
|
|
2615
|
+
}
|
|
2604
2616
|
} },
|
|
2605
2617
|
fr: { material: {
|
|
2606
2618
|
"empty-state": {
|
|
@@ -3105,6 +3117,8 @@ var t = {
|
|
|
3105
3117
|
pagination: {
|
|
3106
3118
|
previous: "Précédent",
|
|
3107
3119
|
next: "Suivant",
|
|
3120
|
+
"previous-page": "Page précédente",
|
|
3121
|
+
"next-page": "Page suivante",
|
|
3108
3122
|
"go-to-next-page": "Aller à la page suivante",
|
|
3109
3123
|
"go-to-previous-page": "Aller à la page précédente",
|
|
3110
3124
|
"go-to-first-page": "Aller à la première page",
|
|
@@ -5200,7 +5214,17 @@ var t = {
|
|
|
5200
5214
|
"scatter-series": "{series} : {count, plural, one {# point} other {# points}}."
|
|
5201
5215
|
}
|
|
5202
5216
|
},
|
|
5203
|
-
"list-details": { back: "Retour à la liste" }
|
|
5217
|
+
"list-details": { back: "Retour à la liste" },
|
|
5218
|
+
switcher: {
|
|
5219
|
+
search: "Rechercher",
|
|
5220
|
+
"search-placeholder": "Rechercher…",
|
|
5221
|
+
clear: "Effacer la recherche",
|
|
5222
|
+
empty: "Aucun résultat pour « {query} »",
|
|
5223
|
+
results: "{count, plural, =0 {Aucun résultat} one {# résultat} other {# résultats}}",
|
|
5224
|
+
recent: "Récents",
|
|
5225
|
+
manage: "Gérer…",
|
|
5226
|
+
choose: "Choisir"
|
|
5227
|
+
}
|
|
5204
5228
|
} }
|
|
5205
5229
|
}, n = "language", r = "en", i = Object.keys(t);
|
|
5206
5230
|
//#endregion
|
package/dist/theme-picker.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { t as e } from "./utils-BLfntITJ.js";
|
|
2
2
|
import { a as t, i as n, n as r, o as i, r as a, t as o } from "./bubble-input-B7BVd9fX.js";
|
|
3
|
-
import { t as s } from "./use-material-translation-
|
|
3
|
+
import { t as s } from "./use-material-translation-BFQODuQz.js";
|
|
4
4
|
import { n as c, r as l } from "./icon-sprites-FxHyqyhg.js";
|
|
5
5
|
import { t as u } from "./use-theme-DMcyJ52N.js";
|
|
6
6
|
import { a as d, r as f } from "./theme-context-Cofk6vgs.js";
|
|
7
|
-
import { t as p } from "./theme-toggle-
|
|
7
|
+
import { t as p } from "./theme-toggle-mQzIR1hw.js";
|
|
8
8
|
import { n as m, t as h } from "./nxgt-theme-ZS945iMP.js";
|
|
9
9
|
import { Check as g } from "lucide-react";
|
|
10
10
|
import { useContext as _ } from "react";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as e } from "./use-material-translation-
|
|
1
|
+
import { t as e } from "./use-material-translation-BFQODuQz.js";
|
|
2
2
|
import { i as t } from "./theme-store-CSl51uNH.js";
|
|
3
3
|
import { n, t as r } from "./use-theme-DMcyJ52N.js";
|
|
4
4
|
import { r as i } from "./theme-context-Cofk6vgs.js";
|
|
@@ -4,9 +4,9 @@ import { a as i, c as a, i as o, l as s, r as c, s as l } from "./dist-lmHmz_bu.
|
|
|
4
4
|
import { b as u, c as d, d as f, f as p, l as m, t as h, u as g, x as _ } from "./tooltip-CkttDIab.js";
|
|
5
5
|
import { i as v, n as y, r as b, t as x } from "./dist-C4wtXCjf.js";
|
|
6
6
|
import { a as S, c as C, l as w, o as T, r as ee, s as te, t as E } from "./in-dialog-Vwkyp-M5.js";
|
|
7
|
-
import { A as ne, M as re, N as ie, b as ae, d as oe, f as se, i as ce, j as le, l as ue, n as de, o as fe, r as pe, t as me, u as he, y as ge } from "./dropdown-menu-
|
|
7
|
+
import { A as ne, M as re, N as ie, b as ae, d as oe, f as se, i as ce, j as le, l as ue, n as de, o as fe, r as pe, t as me, u as he, y as ge } from "./dropdown-menu-mTDyFwbQ.js";
|
|
8
8
|
import { a as _e, n as ve, r as ye, t as be } from "./dist-B7RjY7SL.js";
|
|
9
|
-
import { t as xe } from "./use-material-translation-
|
|
9
|
+
import { t as xe } from "./use-material-translation-BFQODuQz.js";
|
|
10
10
|
import { t as Se } from "./warn-once-C_e47JM8.js";
|
|
11
11
|
import { o as Ce } from "./escape-owner-C4W_sOAU.js";
|
|
12
12
|
import { ChevronLeft as we, ChevronRightIcon as Te, MoreVertical as Ee } from "lucide-react";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import "./stored-language-
|
|
2
|
-
import { a as e, r as t } from "./translator-
|
|
1
|
+
import "./stored-language-CJn_iWwG.js";
|
|
2
|
+
import { a as e, r as t } from "./translator-1THr41fc.js";
|
|
3
3
|
//#region lib/i18n/translate-material.ts
|
|
4
4
|
function n(n, r, i, a) {
|
|
5
5
|
if (n) for (let e of /* @__PURE__ */ new Set([n, n.split("-")[0]])) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as e } from "./is-production-GLw59WU8.js";
|
|
2
|
-
import { a as t, i as n, r, t as i } from "./stored-language-
|
|
2
|
+
import { a as t, i as n, r, t as i } from "./stored-language-CJn_iWwG.js";
|
|
3
3
|
import { t as a } from "./get-CTzJAwfc.js";
|
|
4
4
|
//#region ../../node_modules/@formatjs/fast-memoize/index.js
|
|
5
5
|
function o(e, t) {
|
|
@@ -7,21 +7,21 @@ import { a as o, c as s, i as c, l, n as u, o as d, r as f, s as p, t as m } fro
|
|
|
7
7
|
import { _ as h, a as g, g as _, h as v, m as y, o as b, p as x, t as S, v as C, y as w } from "./tooltip-CkttDIab.js";
|
|
8
8
|
import { a as T, i as E, n as D, r as O, t as k } from "./dist-C4wtXCjf.js";
|
|
9
9
|
import { i as A, n as ee, t as j } from "./in-dialog-Vwkyp-M5.js";
|
|
10
|
-
import { A as M, C as N, D as te, E as ne, O as P, S as re, T as ie, _ as F, b as ae, f as oe, g as se, k as I, l as ce, m as le, n as ue, o as de, r as fe, s as pe, t as me, u as he, v as ge, w as _e, x as ve, y as ye } from "./dialog-
|
|
10
|
+
import { A as M, C as N, D as te, E as ne, O as P, S as re, T as ie, _ as F, b as ae, f as oe, g as se, k as I, l as ce, m as le, n as ue, o as de, r as fe, s as pe, t as me, u as he, v as ge, w as _e, x as ve, y as ye } from "./dialog-B2GXKBp3.js";
|
|
11
11
|
import { A as be, C as xe, D as Se, E as Ce, O as we, S as Te, T as Ee, _ as De, a as Oe, b as ke, d as Ae, f as je, g as Me, h as Ne, i as Pe, k as Fe, l as Ie, m as Le, n as Re, o as ze, p as Be, r as Ve, s as He, t as Ue, u as We, v as Ge, w as Ke, x as qe, y as Je } from "./floating-ui.dom-KkZSW8_E.js";
|
|
12
|
-
import { D as Ye, E as Xe, N as Ze, O as Qe, c as $e, d as et, f as tt, i as nt, k as rt, m as it, n as at, o as ot, p as st, t as ct, u as lt } from "./dropdown-menu-
|
|
12
|
+
import { D as Ye, E as Xe, N as Ze, O as Qe, c as $e, d as et, f as tt, i as nt, k as rt, m as it, n as at, o as ot, p as st, t as ct, u as lt } from "./dropdown-menu-mTDyFwbQ.js";
|
|
13
13
|
import { a as ut, i as dt, n as ft } from "./field-blur-context-Cft9s7Hg.js";
|
|
14
|
-
import { C as pt, S as mt, a as ht, c as gt, d as _t, l as vt, n as yt, o as bt, s as xt, u as St } from "./toolbar-items-
|
|
14
|
+
import { C as pt, S as mt, a as ht, c as gt, d as _t, l as vt, n as yt, o as bt, s as xt, u as St } from "./toolbar-items-Tn3MMu-s.js";
|
|
15
15
|
import { a as Ct, i as wt, n as Tt, o as Et, t as Dt } from "./bubble-input-B7BVd9fX.js";
|
|
16
16
|
import { i as Ot } from "./dist-B7RjY7SL.js";
|
|
17
|
-
import "./stored-language-
|
|
18
|
-
import { a as kt } from "./translator-
|
|
17
|
+
import "./stored-language-CJn_iWwG.js";
|
|
18
|
+
import { a as kt } from "./translator-1THr41fc.js";
|
|
19
19
|
import { h as At } from "./get-CTzJAwfc.js";
|
|
20
20
|
import { t as jt } from "./isEmpty-F_g3jLf8.js";
|
|
21
|
-
import { t as L } from "./use-material-translation-
|
|
22
|
-
import { t as Mt } from "./spinner-
|
|
21
|
+
import { t as L } from "./use-material-translation-BFQODuQz.js";
|
|
22
|
+
import { t as Mt } from "./spinner-B7HCQMFr.js";
|
|
23
23
|
import { a as Nt } from "./button-tones-BwuVvAmd.js";
|
|
24
|
-
import { a as Pt, i as Ft, n as It, r as Lt, t as Rt } from "./button-
|
|
24
|
+
import { a as Pt, i as Ft, n as It, r as Lt, t as Rt } from "./button-rdIhY2BT.js";
|
|
25
25
|
import { t as R } from "./icon-button-ifTpXt0A.js";
|
|
26
26
|
import { n as zt, r as Bt } from "./icon-sprites-FxHyqyhg.js";
|
|
27
27
|
import { t as Vt } from "./use-ssr-media-query-C6M5m8sf.js";
|
|
@@ -35,10 +35,10 @@ import { a as tn, i as nn, o as rn } from "./escape-owner-C4W_sOAU.js";
|
|
|
35
35
|
import { n as an } from "./use-slice-reducer-BGkeGtML.js";
|
|
36
36
|
import { t as on } from "./browser-only-DQ94lWF8.js";
|
|
37
37
|
import { t as sn } from "./compose-refs-DZ0iIVF-.js";
|
|
38
|
-
import { n as cn, r as ln, t as un } from "./chip-
|
|
39
|
-
import { n as dn, t as fn } from "./icon-badge-
|
|
38
|
+
import { n as cn, r as ln, t as un } from "./chip-CEau88ZV.js";
|
|
39
|
+
import { n as dn, t as fn } from "./icon-badge-CiWXvKCs.js";
|
|
40
40
|
import { r as pn } from "./use-csp-nonce-ZKs9k-ov.js";
|
|
41
|
-
import { t as mn } from "./empty-state-
|
|
41
|
+
import { t as mn } from "./empty-state-CJh9f2pc.js";
|
|
42
42
|
import { t as hn } from "./skeleton-DSdtr2qc.js";
|
|
43
43
|
import { H as gn, V as _n, X as vn, bt as yn, it as bn, lt as xn, n as Sn, t as Cn, xt as wn, yt as Tn } from "./dist-moutbfbd.js";
|
|
44
44
|
import { t as En } from "./markdown-Dw_uH7j7.js";
|
|
@@ -10782,7 +10782,7 @@ var CS = (e = {}) => Dn({
|
|
|
10782
10782
|
let [{ default: t }, { lowlight: n }, { richCodeBlock: r }] = await Promise.all([
|
|
10783
10783
|
import("./dist-CRMFGjng.js"),
|
|
10784
10784
|
import("./lowlight-OtcjU2Sa.js"),
|
|
10785
|
-
import("./rich-code-block-
|
|
10785
|
+
import("./rich-code-block-CLkufAhI.js")
|
|
10786
10786
|
]);
|
|
10787
10787
|
return [r(t, {
|
|
10788
10788
|
lowlight: n,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as e } from "./i18n-provider-
|
|
1
|
+
import { r as e } from "./i18n-provider-BpZOKh7U.js";
|
|
2
2
|
import { _ as t, g as n, h as r, n as i, v as a, y as o } from "./number.utils-BG_eEt5g.js";
|
|
3
3
|
import { useCallback as s, useEffect as c, useMemo as l, useRef as u } from "react";
|
|
4
4
|
//#region ../../node_modules/date-fns/locale/fr/_lib/formatDistance.js
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { r as e } from "./i18n-provider-
|
|
2
|
-
import { t } from "./translate-material-
|
|
1
|
+
import { r as e } from "./i18n-provider-BpZOKh7U.js";
|
|
2
|
+
import { t } from "./translate-material-CCyVEi_f.js";
|
|
3
3
|
import { useCallback as n } from "react";
|
|
4
4
|
//#region lib/i18n/use-material-translation.ts
|
|
5
5
|
function r() {
|
|
@@ -14,8 +14,8 @@ either can be used alone.
|
|
|
14
14
|
| | Component | What it does |
|
|
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
|
-
| <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: sort, cursor paging, the empty page with removable chips, one count announced |
|
|
18
|
-
| <img src="../previews/data-table-filter-lists-listempty.webp" width="96" alt=""> | [ListEmpty](#listempty) | A list's empty page: nothing yet, or nothing matches and the way out |
|
|
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-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 |
|
|
19
19
|
| <img src="../previews/data-table-filter-lists-datagrid.webp" width="96" alt=""> | [DataGrid](#datagrid) | An editable grid: spreadsheet keys, paste, a fill handle with series, undo, totals, saving with versions and conflicts (lazy ones fetch theirs on "Keep mine"), `onRefuse` for a refused paste or fill, row selection (`enableRowSelection`), and resizable, hideable and reorderable columns (`columnControls`, `columnLayout`, `DataGridColumnsMenu`) |
|
|
20
20
|
| <img src="../previews/data-table-filter-lists-daygroupedlist.webp" width="96" alt=""> | [DayGroupedList](#daygroupedlist) | A list split by day under sticky Today / Yesterday / Earlier headings |
|
|
21
21
|
| <img src="../previews/data-table-filter-lists-filter.webp" width="96" alt=""> | [Filter](#filter) | Schema-driven filters with chips, presets and persistence |
|
|
@@ -115,9 +115,9 @@ table enables, for typing your own column defs.
|
|
|
115
115
|
| `sorting` / `onSortingChange` | `SortingState` / `(sorting) => void` | held inside | controlled sorting; the callback gets the new state, not an updater, and is not called for an update that resolves to the current value |
|
|
116
116
|
| `getRowId` | `(row, index) => string` | the index | the row's id, the key of `rowSelection` |
|
|
117
117
|
| `enableRowSelection` | `boolean \| (row) => boolean` | `true` | which rows can be selected (`row` is the data). A row that cannot has a disabled checkbox; "Select all" skips it and its checked and indeterminate states count only selectable rows. A locked row already in the selection can be cleared by its own box (and only cleared) |
|
|
118
|
-
| `rowSelectionDisabledReason` | `(row) => string \| undefined` | — | why a row cannot be selected: its checkbox is `aria-disabled` but stays focusable, shows the reason in a tooltip on hover and
|
|
118
|
+
| `rowSelectionDisabledReason` | `(row) => string \| undefined` | — | why a row cannot be selected: its checkbox is `aria-disabled` but stays focusable, shows the reason in a tooltip on hover, focus and tap, and has it as its `aria-describedby`; without a reason it is a plain `disabled` box |
|
|
119
119
|
| `rowSelection` / `onRowSelectionChange` | `RowSelectionState` / `(selection) => void` | held inside | controlled selection, by id; may hold rows of other pages; the callback is not called for an update that resolves to the current value |
|
|
120
|
-
| `pagination` | `{ totalCount?, offset?, previous?, next?, live? }` | — | the server footer's range ("41–60 of 133") and Previous / Next: an href (a link) or a callback (a button); `live: false` renders the range as plain text instead of a polite live region (a page that tells a new query's count elsewhere) |
|
|
120
|
+
| `pagination` | `{ totalCount?, offset?, previous?, next?, live?, pageControls? }` | — | the server footer's range ("41–60 of 133") and Previous / Next: an href (a link) or a callback (a button); `live: false` renders the range as plain text instead of a polite live region (a page that tells a new query's count elsewhere); `pageControls: 'icon'` draws Previous and Next as icon-only buttons (default `'labelled'`, the tonal buttons with their word): a tooltip and the names "Previous page" / "Next page" (`material.table.pagination.previous-page`, `next-page`), `rel` and `data-slot` kept, a link staying a link, the disabled one in place |
|
|
121
121
|
| `footer` | `false \| (table) => ReactNode` | the pagination | replaces the footer, or removes it |
|
|
122
122
|
| `getRowHref` | `(row) => string \| undefined` | — | the first data cell links to the row's page; a click elsewhere on the row follows it |
|
|
123
123
|
| `onRowClick` | `(row, event) => void` | — | a click on the row (not on a control); alone (without `getRowHref`), it makes the row focusable and Enter calls it |
|
|
@@ -824,7 +824,21 @@ export default function Students() {
|
|
|
824
824
|
the selection is kept across pages and drops on a new query.
|
|
825
825
|
`selection.clear()` empties it and moves the focus to the table
|
|
826
826
|
(`tabindex="-1"`, by script only; the list of cards or tiles in those layouts); `selection.deselect(ids)` drops rows
|
|
827
|
-
gone since the page was read.
|
|
827
|
+
gone since the page was read. **Locked rows:** `enableRowSelection` (`true`,
|
|
828
|
+
`false` or `(row) => boolean`, as DataTable's) leaves rows out of it, and
|
|
829
|
+
`rowSelectionDisabledReason` says why; a locked row's checkbox is
|
|
830
|
+
`aria-disabled` but focusable, described by the reason (`aria-describedby`)
|
|
831
|
+
and shown in a tooltip on hover, focus and tap. Space on it does nothing,
|
|
832
|
+
"Select all" skips it, and its state counts only the rows that can be
|
|
833
|
+
selected.
|
|
834
|
+
```tsx
|
|
835
|
+
<ServerTable<Request>
|
|
836
|
+
{...props}
|
|
837
|
+
bulkActions={(ids) => <Button>{`Apply ${ids.length}`}</Button>}
|
|
838
|
+
enableRowSelection={(row) => !row.applied}
|
|
839
|
+
rowSelectionDisabledReason={() => 'Already applied'}
|
|
840
|
+
/>
|
|
841
|
+
```
|
|
828
842
|
- **Your own controls instead.** Without `filter`, pass
|
|
829
843
|
`filters={tableFilters(model)}`: whether the page is "nothing matches",
|
|
830
844
|
and its "Clear search and filters" button
|
|
@@ -833,7 +847,8 @@ export default function Students() {
|
|
|
833
847
|
- **Passed through** to `DataTable`: `columns`, `maxHeight`, `scrollLabel`,
|
|
834
848
|
`showViewOptions`, `renderExpandedRow`, `options`, `loading`,
|
|
835
849
|
`loadingRows`, `getRowHref`, `onRowClick`, `linkComponent`, `density`,
|
|
836
|
-
`layout`, `
|
|
850
|
+
`layout`, `enableRowSelection`, `rowSelectionDisabledReason`,
|
|
851
|
+
`renderCard`, `renderTile` (a list of cards or tiles instead of the
|
|
837
852
|
table: [Cards and tiles](../guides/cards-and-tiles.md)).
|
|
838
853
|
|
|
839
854
|
Its props are `ServerTableProps<T>`; `filter` is a `ServerTableFilter`,
|
|
@@ -849,23 +864,72 @@ Its props are `ServerTableProps<T>`; `filter` is a `ServerTableFilter`,
|
|
|
849
864
|
| `getRowId` | `(row) => string` | — | the selection's key |
|
|
850
865
|
| `filter` | `ServerTableFilter` | — | `{ model, locked?, fieldProps?, variant?, sheetTrigger?, quick?, density?, shortcuts?, previewCount?, counts?, liveDelayMs?, label?, searchLabel?, searchPlaceholder?, searchApply?, searchMinLength?, codec? }` |
|
|
851
866
|
| `filter.codec` | `{ keepKnownValues?, encoding? }` | — | how the page reads and writes the URL: pass the loader's `keepKnownValues` / `encoding` so chips and rows agree |
|
|
852
|
-
| `title` | `ReactNode` | — | the band's title (a string is an `<h2>`) |
|
|
867
|
+
| `title` | `ReactNode` | — | the band's title (a string is an `<h2>`). Leave it out when the page's `h1` is elsewhere (the app bar's): the band then has no heading |
|
|
868
|
+
| `description` | `ReactNode` | — | a muted line under the `title`, or alone above the band's controls without one; the `actions` stay at the band's end |
|
|
853
869
|
| `actions` | `ReactNode` | — | the page's actions, at the band's end |
|
|
870
|
+
| `bandDensity` | `'comfortable' \| 'compact'` | `'comfortable'` | `'compact'` halves the room above the band (16px to 8px) and under it (12px to 6px), for a list under a sticky app bar and a breadcrumb; the controls keep their size (the Filter's own `density` is the controls') |
|
|
871
|
+
| `pageControls` | `'labelled' \| 'icon'` | `'labelled'` | the footer's Previous / Next: `'icon'` is icon-only, with a tooltip and the names "Previous page" / "Next page" (`DataTable`'s default is unchanged) |
|
|
872
|
+
| `filterRef` | `Ref<ServerTableFilterHandle>` | — | with `filter`: `filterRef.current.focus()` focuses the Filter's first control, the search, else the first quick filter, "Add filter" or "Filters (N)" the width shows |
|
|
854
873
|
| `sorting` | `createSorting(…)` | — | headers sorted from the URL |
|
|
855
874
|
| `filters` | `tableFilters(model)` | — | without `filter`: "nothing matches" and its clear |
|
|
856
|
-
| `empty` | `ServerTableEmpty`: `{ none, noMatch, clear?, headingLevel? }` | — | the empty page
|
|
875
|
+
| `empty` | `ServerTableEmpty`: `{ none, noMatch, clear?, headingLevel?, iconStyle? }` | — | the empty page: `none` and `noMatch` are a title or a `ListEmptyPage` (`{ title, description?, illustration?, action? }`); `headingLevel` (default 2) is the level of its title and of the error's; `iconStyle` styles the scenes (see below) |
|
|
857
876
|
| `error` | `ServerTableError \| null` | — | the fetch failed: the failure and a Retry replace the rows |
|
|
858
877
|
| `onRetry` | `() => unknown` | — | the error's Retry; a returned promise keeps it loading |
|
|
859
878
|
| `onClearFilters` | `() => void` | focus the table | without `filter`, after "clear" |
|
|
860
879
|
| `bulkActions` | `(ids, selection: ServerTableSelection) => ReactNode` | — | the selection's toolbar |
|
|
880
|
+
| `enableRowSelection`, `rowSelectionDisabledReason` | `boolean \| (row) => boolean`, `(row) => string \| undefined` | all rows, no reason | with `bulkActions`: which rows can be selected, and why one cannot ([DataTable](#datatable)) |
|
|
861
881
|
| `pageHref` | `(params) => string` | `` `?${params}` `` | Previous / Next hrefs |
|
|
862
882
|
| `pagingNames` | `{ after?, trail? }` | `after`, `trail` | the cursor's params |
|
|
863
883
|
| `resultsLabel` | `(count) => string` | "N results" | without `filter`: what the list's region says. The page past the last has its own words: `material.server-table.past-end`, `past-end-hint`, `first-page` and `past-end-status` |
|
|
864
884
|
| `className` | `string` | — | on the list's surface |
|
|
865
885
|
|
|
886
|
+
**Where the focus goes.** After "Clear" on an empty page, or the last chip
|
|
887
|
+
removed, the focus returns to the Filter's search; a bar without one falls to
|
|
888
|
+
its first shown control (a quick filter, "Add filter", or "Filters (N)" on a
|
|
889
|
+
phone, never a control hidden at the width). An app that moves the focus
|
|
890
|
+
itself holds `filterRef`:
|
|
891
|
+
|
|
892
|
+
```tsx
|
|
893
|
+
const filterRef = useRef<ServerTableFilterHandle>(null);
|
|
894
|
+
<ServerTable {...props} filter={{ model }} filterRef={filterRef} bandDensity="compact" pageControls="icon" />;
|
|
895
|
+
filterRef.current?.focus();
|
|
896
|
+
```
|
|
897
|
+
|
|
898
|
+
**A page whose heading is elsewhere, and a "nothing yet" with a scene.** Without
|
|
899
|
+
`title` the band has no heading; `description` is the line above its controls,
|
|
900
|
+
and `empty.none` takes the scene and the call to action (the same
|
|
901
|
+
`ListEmptyPage` as [ListEmpty](#listempty)):
|
|
902
|
+
|
|
903
|
+
```tsx
|
|
904
|
+
// Once, above: <IllustrationDefaults sets={[EDUCATION_SCENES]}> (from
|
|
905
|
+
// '@nxgt/material-core/illustrations/education'), so 'no-students' resolves.
|
|
906
|
+
<ServerTable<Student>
|
|
907
|
+
{...page}
|
|
908
|
+
description="12 students this year"
|
|
909
|
+
actions={<Button>New student</Button>}
|
|
910
|
+
empty={{
|
|
911
|
+
none: {
|
|
912
|
+
title: 'No students yet',
|
|
913
|
+
description: 'Enrol the first one.',
|
|
914
|
+
illustration: 'no-students', // a scene of a registered set; decorative
|
|
915
|
+
action: <Button>New student</Button>,
|
|
916
|
+
},
|
|
917
|
+
noMatch: 'No student matches', // keeps the "no results" scene and "Clear"
|
|
918
|
+
iconStyle: 'solid', // the sprite file the app serves
|
|
919
|
+
}}
|
|
920
|
+
/>
|
|
921
|
+
```
|
|
922
|
+
|
|
923
|
+
A scene id from a set (`EDUCATION_SCENES`, `HEALTH_SCENES`) is registered once
|
|
924
|
+
with `IllustrationDefaults sets` above the table; `iconStyle` keeps that
|
|
925
|
+
provider's icons and sets and changes only the style (`{ family?, type? }`, a
|
|
926
|
+
sprite file's name, or a list of them). On "nothing matches", an `action` in
|
|
927
|
+
`noMatch` replaces "Clear search and filters". The live region speaks the
|
|
928
|
+
page's `title`.
|
|
929
|
+
|
|
866
930
|
`ServerTable` uses `DataTable`'s `focusable`, `focusRef` (the table, or the list of cards or tiles), `announceLoading`, `announceEmpty`, `filtered` and `pagination.live` (see [DataTable](#datatable)).
|
|
867
931
|
|
|
868
|
-
**Storybook:** `Data table, filter & lists/ServerTable` (`Error No Loading`, `Error Retry`), `…/ServerTable/Phone`, `…/ServerTable/Cards`, `…/ServerTable/Tiles`, `…/ServerTable/Own controls` (`Past The Last Page`, `Slow Router Keeps Search`) · **Vue:** `ServerTable`
|
|
932
|
+
**Storybook:** `Data table, filter & lists/ServerTable` (`Error No Loading`, `Error Retry`), `…/ServerTable/Band and empty page`, `…/ServerTable/Phone`, `…/ServerTable/Cards`, `…/ServerTable/Tiles`, `…/ServerTable/Own controls` (`Past The Last Page`, `Slow Router Keeps Search`), `…/ServerTable/Locked rows`, `…/ServerTable/Compact band and icon paging` · **Vue:** `ServerTable`
|
|
869
933
|
|
|
870
934
|
---
|
|
871
935
|
|
|
@@ -892,7 +956,8 @@ import { ListEmpty } from '@nxgt/material/components';
|
|
|
892
956
|
| Prop | Type | Default | Effect |
|
|
893
957
|
| --- | --- | --- | --- |
|
|
894
958
|
| `filtered` | `boolean` | — | "nothing matches" rather than "nothing yet" |
|
|
895
|
-
| `none`, `noMatch` | `ReactNode` | — | the two titles |
|
|
959
|
+
| `none`, `noMatch` | `ReactNode \| ListEmptyPage` | — | the two titles, or `{ title, description?, illustration?, action? }`: a line, a scene (a scene id, `true` for the kind's, `false` for none; decorative) and a call to action. On `noMatch`, `action` replaces the way out |
|
|
960
|
+
| `iconStyle` | `IconStyleInput` | — | the icon style of the scenes (`{ family?, type? }`, a sprite file's name, or a list), keeping the `IllustrationDefaults` above |
|
|
896
961
|
| `children` | `ReactNode` | — | while nothing matches, above the way out (`ServerTable`'s removable chips) |
|
|
897
962
|
| `clear` | `string` | "Clear search and filters" | the way out's label (`material.list-empty.clear`) |
|
|
898
963
|
| `onClear` | `() => void` | — | the way out is a button |
|
|
@@ -21,7 +21,7 @@ that prevents the default and focuses nothing) goes to the layer's content.
|
|
|
21
21
|
Non-modal layers (`modal={false}`, and `DropdownMenu` and `Popover` by
|
|
22
22
|
default) leave the page as it is.
|
|
23
23
|
|
|
24
|
-
**Checked and radio items draw a mark.** The check of a `*CheckboxItem` draws in and out and the dot of a `*RadioItem` springs in; a checked `CommandItem`, a chosen `Select` or `Combobox` option, the `PhoneField` country menu
|
|
24
|
+
**Checked and radio items draw a mark.** The check of a `*CheckboxItem` draws in and out and the dot of a `*RadioItem` springs in; a checked `CommandItem`, a chosen `Select` or `Combobox` option, the `PhoneField` country menu and the `FilterPresets` menu draw their check in. The mark is `data-slot="option-mark"`, `aria-hidden`, follows the row's text colour and stops moving under reduced motion. Roles, `aria-checked` and keyboard behaviour are unchanged: read `aria-checked` on the item, not the mark.
|
|
25
25
|
|
|
26
26
|
**Chosen and highlighted items look the same everywhere.** In the radio groups of `DropdownMenu`, `ContextMenu` and `Menubar`, and in `Select` and
|
|
27
27
|
`Autocomplete` lists, the one chosen item has a 12 % primary tint, a 3px rounded bar
|
|
@@ -28,7 +28,7 @@ value type each one writes. Everything is imported from
|
|
|
28
28
|
| <img src="../previews/selection-choice-transferlist.webp" width="96" alt=""> | [TransferList](#transferlist) | Two-pane picker: search, counts, select-all, drag between panes |
|
|
29
29
|
| <img src="../previews/selection-choice-sortablelist.webp" width="96" alt=""> | [SortableList](#sortablelist) | Reorderable list: drag or keyboard, announced |
|
|
30
30
|
| <img src="../previews/selection-choice-treeselectfield.webp" width="96" alt=""> | [TreeSelectField](#treeselectfield) | Pick from a tree, single or multiple |
|
|
31
|
-
| <img src="../previews/selection-choice-switcher.webp" width="96" alt=""> | [Switcher](#switcher) | Workspace or
|
|
31
|
+
| <img src="../previews/selection-choice-switcher.webp" width="96" alt=""> | [Switcher](#switcher) | Workspace, establishment or class switcher: menu, search, groups, links |
|
|
32
32
|
|
|
33
33
|
## Select
|
|
34
34
|
|
|
@@ -1125,7 +1125,7 @@ multiple mode).
|
|
|
1125
1125
|
|
|
1126
1126
|

|
|
1127
1127
|
|
|
1128
|
-
|
|
1128
|
+
Switches the workspace, the establishment or the class a page is about. A 44px card trigger (initial or icon tile, title, subtitle, up-down chevron) opens a menu for up to 7 options, and from 8 a panel with a search, groups and a listbox; on a phone it is a bottom sheet. `variant="expressive"` is a pill with a larger panel, "Recent" tiles and soft badges. With `getHref` the options are links.
|
|
1129
1129
|
|
|
1130
1130
|
```tsx
|
|
1131
1131
|
import { Switcher, type SwitcherItem } from '@nxgt/material/components';
|
|
@@ -1138,17 +1138,87 @@ const workspaces: SwitcherItem[] = [
|
|
|
1138
1138
|
|
|
1139
1139
|
export function Workspaces() {
|
|
1140
1140
|
const [value, setValue] = useState('acme');
|
|
1141
|
-
return <Switcher label="
|
|
1141
|
+
return <Switcher label="Workspace" options={workspaces} value={value} onValueChange={setValue} />;
|
|
1142
1142
|
}
|
|
1143
1143
|
```
|
|
1144
1144
|
|
|
1145
|
+
An option with no `icon` draws its `initial` (default: the first letter of its title) in a tile of its `tone`. Establishments take an icon, a tone and a "Manage…" footer:
|
|
1146
|
+
|
|
1147
|
+
```tsx
|
|
1148
|
+
import { Icon, Switcher } from '@nxgt/material/components';
|
|
1149
|
+
|
|
1150
|
+
<Switcher
|
|
1151
|
+
label="Establishment"
|
|
1152
|
+
value={school}
|
|
1153
|
+
onValueChange={setSchool}
|
|
1154
|
+
options={[
|
|
1155
|
+
{ id: 'ljc', title: 'Lycée Joss', subtitle: 'Lycée · Douala', icon: <Icon name="school" />, tone: 'primary' },
|
|
1156
|
+
{ id: 'src', title: 'École La Source', subtitle: 'Primaire · Bafoussam', icon: <Icon name="graduation-cap" />, tone: 'success' },
|
|
1157
|
+
]}
|
|
1158
|
+
footer={{ onSelect: () => navigate('/establishments') }}
|
|
1159
|
+
/>;
|
|
1160
|
+
```
|
|
1161
|
+
|
|
1162
|
+
### Classes: search, groups and links
|
|
1163
|
+
|
|
1164
|
+
Eight options or more (or `searchable`) open a popover with a search field. It is a combobox over a listbox: typing filters on the title, the subtitle and the group (accents and case ignored), the arrows move the active option, Enter chooses it and gives the focus back to the trigger. Options with a `group` are listed under its header, and put the pupil count in the subtitle **or** in `badge`, not both.
|
|
1165
|
+
|
|
1166
|
+
With `getHref` each option is a link, for a switcher that is a navigation (`/classes/6b`): the panel is a `nav` of links with `aria-current="page"` on the chosen one (no `listbox` role), and the arrows move the real focus. Pass your router's link as `linkComponent`, as for `ListTile` and `AccountMenu`:
|
|
1167
|
+
|
|
1168
|
+
```tsx
|
|
1169
|
+
import { Link } from 'react-router';
|
|
1170
|
+
import { Switcher, type AppShellLinkComponent } from '@nxgt/material/components';
|
|
1171
|
+
|
|
1172
|
+
// Hoisted, outside the render: not a new component on every render.
|
|
1173
|
+
const RouterLink: AppShellLinkComponent = ({ href, ...props }) => <Link to={href} {...props} />;
|
|
1174
|
+
|
|
1175
|
+
<Switcher
|
|
1176
|
+
label="Class"
|
|
1177
|
+
value={classId}
|
|
1178
|
+
options={classes} // { id: '6b', title: '6e B', subtitle: 'Mathematics · 26 pupils', group: '6e', tone: 'primary' }
|
|
1179
|
+
getHref={(item) => `/classes/${item.id}`}
|
|
1180
|
+
linkComponent={RouterLink}
|
|
1181
|
+
footer={{ label: 'Manage my classes…', href: '/classes' }}
|
|
1182
|
+
/>;
|
|
1183
|
+
```
|
|
1184
|
+
|
|
1185
|
+
### Expressive
|
|
1186
|
+
|
|
1187
|
+
`variant="expressive"` is a pill that opens a larger panel (always with a search). `recent` lists up to 3 option ids shown as tiles above the groups while nothing is typed; `badge` draws a soft badge after the title. On a phone the sheet is full height with a close button.
|
|
1188
|
+
|
|
1189
|
+
```tsx
|
|
1190
|
+
<Switcher
|
|
1191
|
+
variant="expressive"
|
|
1192
|
+
label="Class"
|
|
1193
|
+
value={classId}
|
|
1194
|
+
onValueChange={setClassId}
|
|
1195
|
+
options={classes.map((c) => ({ ...c, badge: c.pupils }))}
|
|
1196
|
+
recent={['6b', 't1', '4a']}
|
|
1197
|
+
/>
|
|
1198
|
+
```
|
|
1199
|
+
|
|
1200
|
+
A title that does not fit the trigger is cut with an ellipsis: the span carries the full title in `aria-label` (what `expectNoTextOverflow` of `@nxgt/playwright` reads), hovering or focusing the trigger shows it with the subtitle in a tooltip, and the trigger's accessible name is the label, the full title and the subtitle.
|
|
1201
|
+
|
|
1145
1202
|
| Prop | Type | Default | Effect |
|
|
1146
1203
|
| --- | --- | --- | --- |
|
|
1147
|
-
| `options` | `SwitcherItem[]` | — |
|
|
1204
|
+
| `options` | `SwitcherItem[]` | — | see below |
|
|
1148
1205
|
| `value` | `string` | — | the active `id` |
|
|
1149
1206
|
| `onValueChange` | `(value: string) => void` | — | |
|
|
1150
|
-
| `label` | `ReactNode` | — |
|
|
1207
|
+
| `label` | `ReactNode` | — | what is switched: names the trigger, the panel and the list |
|
|
1208
|
+
| `variant` | `'default' \| 'expressive'` | `'default'` | tile trigger and menu, or pill and large panel |
|
|
1209
|
+
| `searchable` | `boolean` | from 8 options (always, expressive) | the search field of the panel; `true` also replaces the menu with the panel |
|
|
1210
|
+
| `recent` | `string[]` | — | up to 3 option ids shown as tiles (expressive) |
|
|
1211
|
+
| `getHref` | `(item) => string \| undefined` | — | link mode; falls back to `item.href` |
|
|
1212
|
+
| `linkComponent` | `LinkComponent` | `<a>` | your router's link: takes `href`, spreads every prop, forwards `ref` |
|
|
1213
|
+
| `footer` | `{ label?, onSelect?, href? }` | — | a "Manage…" button (a link with `href`) at the end of the panel; `label` defaults to `material.switcher.manage` |
|
|
1214
|
+
| `emptyLabel` | `ReactNode` | `material.switcher.empty` | shown when the search matches nothing |
|
|
1215
|
+
| `sheet` | `boolean` | on a phone | `true` always opens a sheet, `false` never |
|
|
1216
|
+
| `name`, button props | `ComponentProps<'button'>` | — | spread on the trigger; `name` is its `data-pw` |
|
|
1217
|
+
|
|
1218
|
+
`SwitcherItem`: `{ id, title, subtitle?, icon?, group?, initial?, tone?, badge?, href?, disabled? }`.
|
|
1219
|
+
|
|
1220
|
+
Strings (the search field, "Recent", "Manage…", the empty and result texts) are `material.switcher.*` keys, in English and French.
|
|
1151
1221
|
|
|
1152
1222
|
**Emits:** `string` (the item `id`). No form wrapper — it switches context,
|
|
1153
1223
|
it is not a form value.
|
|
1154
|
-
**Storybook:** `Selection & choice/Switcher` · **Vue:** `Switcher`
|
|
1224
|
+
**Storybook:** `Selection & choice/Switcher` (and `/Behaviour`) · **Vue:** `Switcher` (the earlier look; the modern one is React only for now)
|
|
Binary file
|
package/docs/roadmap.md
CHANGED
|
@@ -566,7 +566,7 @@ version they shipped in, and planned entries may name the major they target.
|
|
|
566
566
|
`FilterChips` still work, now deprecated. Shipped in 2.37.0.
|
|
567
567
|
[Filter bar](components/data-table-filter-and-lists.md#filter-bar) ·
|
|
568
568
|
[Server lists in the URL](guides/server-lists-url.md)
|
|
569
|
-
- **A server list driven by the URL: `ServerTable`** — a server-mode `DataTable` with the filter bar in its top band beside the page's title and actions, the query, sort and cursor in the URL for any router, the empty page listing the filters as removable chips, and one count announced. Shipped in 2.37.0.
|
|
569
|
+
- **A server list driven by the URL: `ServerTable`** — a server-mode `DataTable` with the filter bar in its top band beside the page's optional title, its description line and its actions, the query, sort and cursor in the URL for any router, the empty page listing the filters as removable chips (and, for "nothing yet", a scene and an action), and one count announced. Shipped in 2.37.0.
|
|
570
570
|
- **LocalizedTextFields** — one text in several
|
|
571
571
|
languages: a fieldset with an input per language, the default as a
|
|
572
572
|
placeholder with a reset button, `lang` and `dir` on each input, an error
|
package/docs/troubleshooting.md
CHANGED
|
@@ -111,6 +111,7 @@ words in your error.
|
|
|
111
111
|
|
|
112
112
|
- [A `ListTile` link shows two chevrons](#a-listtile-link-shows-two-chevrons)
|
|
113
113
|
- [A `ListTile` link reloads the whole page](#a-listtile-link-reloads-the-whole-page)
|
|
114
|
+
- [A `Switcher` in link mode reloads the page](#a-switcher-in-link-mode-reloads-the-page)
|
|
114
115
|
- [After a link in the phone menu, the focus goes to `<main>`, not to the page's title](#after-a-link-in-the-phone-menu-the-focus-goes-to-main-not-to-the-pages-title)
|
|
115
116
|
- [The phone menu needs two Escapes to close, or a tooltip shows over it](#the-phone-menu-needs-two-escapes-to-close-or-a-tooltip-shows-over-it)
|
|
116
117
|
- [The phone menu stays open after a navigation, or an app clicks its button to close it](#the-phone-menu-stays-open-after-a-navigation-or-an-app-clicks-its-button-to-close-it)
|
|
@@ -1115,7 +1116,7 @@ expect(screen.getByRole('checkbox', { name: 'Email me receipts' })).toHaveAttrib
|
|
|
1115
1116
|
|
|
1116
1117
|
### A test looked for `lucide-check` in a menu item
|
|
1117
1118
|
|
|
1118
|
-
**When:** a test or a style looks for the `lucide-check` or `lucide-circle` svg in a checked item of `DropdownMenu`, `ContextMenu`, `Menubar`, `Select`, `Combobox`, `Command`, the `PhoneField` country menu
|
|
1119
|
+
**When:** a test or a style looks for the `lucide-check` or `lucide-circle` svg in a checked item of `DropdownMenu`, `ContextMenu`, `Menubar`, `Select`, `Combobox`, `Command`, the `PhoneField` country menu or the filter presets.
|
|
1119
1120
|
**Why:** those items draw an animated mark, an `aria-hidden` element with `data-slot="option-mark"`. In `Select` and `Combobox` it is present only on the chosen option; the menu items keep it mounted while unchecked.
|
|
1120
1121
|
**Fix:** read `aria-checked` (or `aria-selected`) on the item:
|
|
1121
1122
|
|
|
@@ -2057,6 +2058,22 @@ const RouterLink: AppShellLinkComponent = ({ href, ...props }) => (
|
|
|
2057
2058
|
<ListTile title="Notifications" href="/settings/notifications" linkComponent={RouterLink} />
|
|
2058
2059
|
```
|
|
2059
2060
|
|
|
2061
|
+
### A `Switcher` in link mode reloads the page
|
|
2062
|
+
|
|
2063
|
+
**When:** a `Switcher` with `getHref` is used in a router app and choosing an option loads the document again (the page flashes, client state is lost).
|
|
2064
|
+
**Why:** link mode renders plain `<a href>` links, which need no router and so cannot navigate on the client. Without `getHref` the options are not links and `href` on an item does nothing.
|
|
2065
|
+
**Fix:** pass `linkComponent`, with the contract of the app shell's: it takes `href`, spreads every other prop (`aria-current`, `className`, handlers) and forwards `ref`. React Router's `Link` takes `to`, so wrap it:
|
|
2066
|
+
|
|
2067
|
+
```tsx
|
|
2068
|
+
import { Link } from 'react-router';
|
|
2069
|
+
import { Switcher, type AppShellLinkComponent } from '@nxgt/material/components';
|
|
2070
|
+
|
|
2071
|
+
// Hoisted, outside the render: not a new component on every render.
|
|
2072
|
+
const RouterLink: AppShellLinkComponent = ({ href, ...props }) => <Link to={href} {...props} />;
|
|
2073
|
+
|
|
2074
|
+
<Switcher label="Class" value={classId} options={classes} getHref={(item) => `/classes/${item.id}`} linkComponent={RouterLink} />
|
|
2075
|
+
```
|
|
2076
|
+
|
|
2060
2077
|
### After a link in the phone menu, the focus goes to `<main>`, not to the page's title
|
|
2061
2078
|
|
|
2062
2079
|
**When:** on a phone, a link followed in the menu sheet of `ActivityLayout` or
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nxgt/material",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.19.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"bugs": {
|
|
6
6
|
"email": "stevegires@gmail.com"
|
|
@@ -357,7 +357,7 @@
|
|
|
357
357
|
"docs:previews": "rm -rf node_modules/.cache/nxgt-preview-free/missing && NXGT_PREVIEW_FREE=1 vitest run --project previews && bun .storybook/preview-free-report.ts"
|
|
358
358
|
},
|
|
359
359
|
"dependencies": {
|
|
360
|
-
"@nxgt/material-core": "^0.
|
|
360
|
+
"@nxgt/material-core": "^0.33.0",
|
|
361
361
|
"@base-ui/react": "^1.6.0",
|
|
362
362
|
"@dnd-kit/core": "^6.3.1",
|
|
363
363
|
"@dnd-kit/sortable": "^10.0.0",
|