@nxgt/material 2.7.1 → 2.9.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 +201 -0
- package/README.md +9 -6
- package/dist/{_Uint8Array-JRUmWcRr.js → _Uint8Array-azThpjEP.js} +1 -1
- package/dist/{_overRest-DvC5rm5s.js → _overRest-DMn4Dt71.js} +1 -1
- package/dist/{abnfDiagram-O67JEVCF-Cl4ukf6a.js → abnfDiagram-O67JEVCF-D-rmT4BY.js} +4 -4
- package/dist/{architectureDiagram-NJMV4G6O-WmFlBQF5.js → architectureDiagram-NJMV4G6O-DOc_c_T9.js} +7 -7
- package/dist/{async-slice-OftEOtMA.js → async-slice-DhZDjEtw.js} +2 -2
- package/dist/{blockDiagram-BEXU5L5S-BM-gkWAO.js → blockDiagram-BEXU5L5S-BOsyK4E_.js} +11 -11
- package/dist/{c4Diagram-YGBWAQC7-D9xSt2QO.js → c4Diagram-YGBWAQC7-El4SkIzX.js} +8 -8
- package/dist/{channel-Dg92Hoym.js → channel-CnLB6790.js} +1 -1
- package/dist/{chunk-3FUC2YCW-Cf18L00V.js → chunk-3FUC2YCW-BCsKm3ZT.js} +8 -8
- package/dist/{chunk-5DYCD2WN-Cja1INgd.js → chunk-5DYCD2WN-Cd1zazNp.js} +3 -3
- package/dist/{chunk-6AEJRKK7-3YWRP4aV.js → chunk-6AEJRKK7-BLBlw8ui.js} +2 -2
- package/dist/{chunk-742MDFTN-Cs1qGiTK.js → chunk-742MDFTN-CsUjFyzK.js} +2 -2
- package/dist/{chunk-7INBJB4K-BY5n77ka.js → chunk-7INBJB4K-k-I67NSP.js} +6 -6
- package/dist/{chunk-7M6MHVWA-C3x6E3yT.js → chunk-7M6MHVWA-C3qpW8zM.js} +9 -9
- package/dist/{chunk-7PRAP22T-_Av9vcXz.js → chunk-7PRAP22T-0C6_H8Li.js} +1 -1
- package/dist/{chunk-GNY47TPC-D1E6DHDV.js → chunk-GNY47TPC-CzPNLW5k.js} +11 -11
- package/dist/{chunk-GTNCS2PH-BZ9WMD1v.js → chunk-GTNCS2PH-AJi9PVT7.js} +3 -3
- package/dist/{chunk-GWA4HPMP-Co-A6dtV.js → chunk-GWA4HPMP-B8jXI0Tl.js} +3 -3
- package/dist/{chunk-MBY4JIJT-C3RQP_Nk.js → chunk-MBY4JIJT-BFIqOe-8.js} +4 -4
- package/dist/{chunk-NETBCI7D-DJUuN4EY.js → chunk-NETBCI7D-tNinefdn.js} +1 -1
- package/dist/{chunk-O7XYJQB3-A66QSOPA.js → chunk-O7XYJQB3-BChweQ_V.js} +1 -1
- package/dist/{chunk-UA2S7LBM-BNeHeMx9.js → chunk-UA2S7LBM-ChuksCDg.js} +6 -6
- package/dist/{chunk-WEXAMYUT-CucJfehv.js → chunk-WEXAMYUT-CbFOhEve.js} +2 -2
- package/dist/{chunk-XXDRQBXY-FgXU14Bh.js → chunk-XXDRQBXY-dKXxu_aj.js} +1 -1
- package/dist/{chunk-Z7XXMR3K-DMTBxZxM.js → chunk-Z7XXMR3K-C9P-XjM2.js} +8 -8
- package/dist/{chunk-ZIGJFQKS-C3xUAXJq.js → chunk-ZIGJFQKS-9VXArDKF.js} +3 -3
- package/dist/{classDiagram-v2-NBCMYWYE-BDaxYvDy.js → classDiagram-v2-NBCMYWYE-D00ZobEC.js} +14 -14
- package/dist/clsx-CbxlCXZ3.js +16 -0
- package/dist/components/base-content.css +139 -0
- package/dist/components/base.css +150 -0
- package/dist/components/components.css +2 -0
- package/dist/components/reduced-motion.css +56 -0
- package/dist/components/theme-tokens.css +116 -0
- package/dist/components/ui/actions/button-group/button-group.css +1 -1
- package/dist/components/ui/feedback/toast/toast.css +21 -0
- package/dist/components/ui/primitives/label/label.css +33 -0
- package/dist/{components-DrStgM4J.js → components-km60bAdr.js} +34658 -34218
- package/dist/components.js +6 -6
- package/dist/{cose-bilkent-JH36ORCC-DRUT3qBb.js → cose-bilkent-JH36ORCC-P94vkHv_.js} +2 -2
- package/dist/{cynefinDiagram-VND7K2PF-B9HrdQW8.js → cynefinDiagram-VND7K2PF-EIpXbLXm.js} +4 -4
- package/dist/{dagre-6A5THRUB-DZF0nICj.js → dagre-6A5THRUB-D_F3_LlW.js} +20 -20
- package/dist/{diagram-22UHCM2B-CVZYpeev.js → diagram-22UHCM2B-CsxOExpW.js} +15 -15
- package/dist/{diagram-3UASUU5V-D7MmBJbM.js → diagram-3UASUU5V-Dl7AETV1.js} +7 -7
- package/dist/{diagram-ATOU4E4O-CNY-8kl0.js → diagram-ATOU4E4O-isL7nwg2.js} +3 -3
- package/dist/{diagram-CDSNMT55-C8Mk1smi.js → diagram-CDSNMT55-Bnhlo5at.js} +5 -5
- package/dist/{diagram-MLGK6HIB-CpfeILwW.js → diagram-MLGK6HIB-DvBcyz8v.js} +4 -4
- package/dist/{diagram-MPIPVDR6-Do7bUnTd.js → diagram-MPIPVDR6-iTevwmNE.js} +4 -4
- package/dist/{dist-C3YK_ean.js → dist-B6_-RPZ3.js} +1 -1
- package/dist/{dist-CRbPtqwD.js → dist-BvUQHUs_.js} +4 -4
- package/dist/dnd.js +1 -1
- package/dist/{ebnfDiagram-ZINNZB2B-1GewX9Zq.js → ebnfDiagram-ZINNZB2B-RVuQIpm0.js} +4 -4
- package/dist/{elk-276RUBZZ-DI4eicFj.js → elk-276RUBZZ-BK-NMLiI.js} +26 -26
- package/dist/{erDiagram-OPXOYQCR-CUbpVns3.js → erDiagram-OPXOYQCR-DC1GgS4l.js} +14 -14
- package/dist/field-blur--x_n3oMy.js +3637 -0
- package/dist/flowDiagram-KWPJA3E3-BUSlDNQP.js +17 -0
- package/dist/{ganttDiagram-FUAMR5RP-D3vmspam.js → ganttDiagram-FUAMR5RP-DOp1p_x0.js} +6 -6
- package/dist/{gitGraphDiagram-X574FWY7-80yOq8dE.js → gitGraphDiagram-X574FWY7-DerJL1Q-.js} +3 -3
- package/dist/{graphlib-DLJn7qS3.js → graphlib-DLjE3QPd.js} +6 -6
- package/dist/hooks.js +3 -3
- package/dist/{i18n-provider-DBFRz5uH.js → i18n-provider-CQL7fqLy.js} +1 -1
- package/dist/i18n.js +6 -6
- package/dist/icon-button-G9zdQ3Ix.js +2753 -0
- package/dist/{infoDiagram-VRGFBTTK-Cboh-B9n.js → infoDiagram-VRGFBTTK-CtVsLyCQ.js} +3 -3
- package/dist/{isArrayLikeObject-CO5xeuaJ.js → isArrayLikeObject-CO-5KAzG.js} +3 -3
- package/dist/{isEmpty-DOC38Ces.js → isEmpty-Bl1drJE7.js} +3 -3
- package/dist/{ishikawaDiagram-OU5B5YK6-DwTd1YxL.js → ishikawaDiagram-OU5B5YK6-D1n8vp8C.js} +4 -4
- package/dist/{journeyDiagram-ZHPQQLJL-Dxvl3oeN.js → journeyDiagram-ZHPQQLJL-DuQ9Th0y.js} +4 -4
- package/dist/{kanban-definition-PNTS6WVX-S8plI4wn.js → kanban-definition-PNTS6WVX-D1-Owjil.js} +10 -10
- package/dist/lib/components/ui/actions/button/busy-click-capture.d.ts +11 -0
- package/dist/lib/components/ui/actions/button/button-tones.d.ts +36 -0
- package/dist/lib/components/ui/actions/button/button.d.ts +19 -0
- package/dist/lib/components/ui/actions/button/button.wrap.d.ts +8 -0
- package/dist/lib/components/ui/actions/button/label-text.d.ts +10 -0
- package/dist/lib/components/ui/actions/button/use-click-lock.d.ts +18 -0
- package/dist/lib/components/ui/actions/copy-button/copy-button.d.ts +5 -1
- package/dist/lib/components/ui/actions/icon-button/icon-button.compound-variants.d.ts +114 -0
- package/dist/lib/components/ui/collections/data-table/hooks.d.ts +13 -13
- package/dist/lib/components/ui/collections/data-table/partials/data-table-empty-row.d.ts +5 -1
- package/dist/lib/components/ui/collections/data-table/partials/data-table-scroll-region.d.ts +16 -0
- package/dist/lib/components/ui/collections/data-table/partials/data-table-toolbar.d.ts +24 -0
- package/dist/lib/components/ui/collections/data-table/select-checkbox.d.ts +10 -0
- package/dist/lib/components/ui/collections/data-table/types.d.ts +9 -0
- package/dist/lib/components/ui/collections/data-table/use-data-table.d.ts +12 -1
- package/dist/lib/components/ui/collections/data-table/use-scroll-edges.d.ts +22 -0
- package/dist/lib/components/ui/dates/calendar/calendar-day.d.ts +8 -0
- package/dist/lib/components/ui/dates/calendar/calendar.d.ts +3 -3
- package/dist/lib/components/ui/dates/calendar/calendar.utils.d.ts +8 -0
- package/dist/lib/components/ui/dates/calendar/use-calendar-labels.d.ts +22 -0
- package/dist/lib/components/ui/display/description/description.d.ts +2 -1
- package/dist/lib/components/ui/display/list-tile/list-tile.d.ts +9 -1
- package/dist/lib/components/ui/display/list-tile/partials/list-tile-body.d.ts +11 -0
- package/dist/lib/components/ui/display/list-tile/partials/list-tile-classes.d.ts +10 -0
- package/dist/lib/components/ui/feedback/alert-dialog/alert-dialog.d.ts +1 -1
- package/dist/lib/components/ui/feedback/toast/partials/toast-actions.d.ts +3 -0
- package/dist/lib/components/ui/feedback/toast/toast.d.ts +27 -3
- package/dist/lib/components/ui/feedback/toast/toaster.d.ts +19 -0
- package/dist/lib/components/ui/feedback/toast/toasts.d.ts +3 -0
- package/dist/lib/components/ui/forms/field-blur.d.ts +7 -2
- package/dist/lib/components/ui/forms/use-field-blur.d.ts +8 -1
- package/dist/lib/components/ui/layout/app-shell/activity-content.d.ts +10 -1
- package/dist/lib/components/ui/layout/app-shell/activity-layout.d.ts +26 -2
- package/dist/lib/components/ui/layout/app-shell/app-header.d.ts +8 -2
- package/dist/lib/components/ui/layout/app-shell/app-sidebar.d.ts +8 -2
- package/dist/lib/components/ui/layout/app-shell/types.d.ts +3 -0
- package/dist/lib/components/ui/layout/app-shell/use-content-scroll.d.ts +10 -0
- package/dist/lib/components/ui/layout/app-shell/use-navigation-sheet.d.ts +19 -0
- package/dist/lib/components/ui/layout/sidebar/index.d.ts +5 -0
- package/dist/lib/components/ui/layout/sidebar/sidebar-content.d.ts +2 -0
- package/dist/lib/components/ui/layout/sidebar/sidebar-context.d.ts +7 -0
- package/dist/lib/components/ui/layout/sidebar/sidebar-footer.d.ts +2 -0
- package/dist/lib/components/ui/layout/sidebar/sidebar-header.d.ts +2 -0
- package/dist/lib/components/ui/layout/sidebar/sidebar-menu-item-tooltip.d.ts +7 -0
- package/dist/lib/components/ui/layout/sidebar/sidebar-menu-item.d.ts +31 -0
- package/dist/lib/components/ui/layout/sidebar/sidebar-menu-label.d.ts +4 -0
- package/dist/lib/components/ui/layout/sidebar/sidebar.d.ts +1 -12
- package/dist/lib/components/ui/overlays/context-menu/context-menu-items.d.ts +10 -0
- package/dist/lib/components/ui/overlays/context-menu/context-menu-sub.d.ts +8 -0
- package/dist/lib/components/ui/overlays/context-menu/context-menu.d.ts +4 -14
- package/dist/lib/components/ui/overlays/dialog/dialog-outside.d.ts +6 -0
- package/dist/lib/components/ui/overlays/dialog/dialog-scroll-content.d.ts +1 -1
- package/dist/lib/components/ui/overlays/dialog/dialog.d.ts +1 -1
- package/dist/lib/components/ui/overlays/dialog/use-return-focus.d.ts +3 -2
- package/dist/lib/components/ui/overlays/drawer/drawer.d.ts +1 -1
- package/dist/lib/components/ui/overlays/dropdown-menu/dropdown-menu-items.d.ts +11 -0
- package/dist/lib/components/ui/overlays/dropdown-menu/dropdown-menu-sub.d.ts +8 -0
- package/dist/lib/components/ui/overlays/dropdown-menu/dropdown-menu.d.ts +6 -21
- package/dist/lib/components/ui/overlays/popover/popover.d.ts +1 -1
- package/dist/lib/components/ui/overlays/sheet/sheet.d.ts +1 -1
- package/dist/lib/components/ui/primitives/card/card.d.ts +10 -1
- package/dist/lib/components/ui/primitives/link/link-component.d.ts +14 -0
- package/dist/lib/components/ui/primitives/tabs/partials/tabs-content.d.ts +3 -0
- package/dist/lib/components/ui/primitives/tabs/partials/tabs-indicator.d.ts +13 -0
- package/dist/lib/components/ui/primitives/tabs/partials/tabs-list.d.ts +3 -0
- package/dist/lib/components/ui/primitives/tabs/partials/tabs-trigger.d.ts +6 -0
- package/dist/lib/components/ui/primitives/tabs/tabs-classes.d.ts +27 -0
- package/dist/lib/components/ui/primitives/tabs/tabs-variant.d.ts +5 -0
- package/dist/lib/components/ui/primitives/tabs/tabs.d.ts +11 -7
- package/dist/lib/components/ui/selection/select/select.d.ts +1 -1
- package/dist/lib/components/ui/selection/select-chip-field/select-chip-field.d.ts +1 -1
- package/dist/lib/components/ui/widgets/emoji/types.d.ts +1 -6
- package/dist/lib/i18n/resources/en/en.d.ts +23 -0
- package/dist/lib/i18n/resources/en/material.json.d.ts +28 -5
- package/dist/lib/i18n/resources/fr/fr.d.ts +23 -0
- package/dist/lib/i18n/resources/fr/material.json.d.ts +28 -5
- package/dist/lib/i18n/resources/resources.d.ts +46 -0
- package/dist/lib/i18n/translator.d.ts +1 -1
- package/dist/lib/lib/redux/status-slice.d.ts +1 -1
- package/dist/lib.js +39 -55
- package/dist/main.js +13 -13
- package/dist/map.js +35 -35
- package/dist/material.css +1 -1
- package/dist/{merge-CuDTNgpm.js → merge-CwwtONfp.js} +4 -4
- package/dist/{mermaid.core-O7mtb1-p.js → mermaid.core-Dfr4zfuP.js} +49 -49
- package/dist/{mindmap-definition-NLK3R4M7-CO0E97EZ.js → mindmap-definition-NLK3R4M7-_qKWGSrk.js} +13 -13
- package/dist/{pegDiagram-GJSIUBJH-CAO6aYvj.js → pegDiagram-GJSIUBJH-CWKobqLl.js} +4 -4
- package/dist/{pieDiagram-5QR66LMP-BXxVfv5K.js → pieDiagram-5QR66LMP-B6at48Bd.js} +5 -5
- package/dist/print.js +2 -2
- package/dist/{quadrantDiagram-O4NWA36T-BbidZDM8.js → quadrantDiagram-O4NWA36T-Cr9bA0xJ.js} +3 -3
- package/dist/{railroadDiagram-XR7U4H2S-DmKDXg8V.js → railroadDiagram-XR7U4H2S-fsZ7oqPG.js} +4 -4
- package/dist/{requirementDiagram-PLB6GJNP-wFvgSWJP.js → requirementDiagram-PLB6GJNP-BBs-lByV.js} +13 -13
- package/dist/rolldown-runtime-BFFgcFxR.js +30 -0
- package/dist/{sankeyDiagram-IPEJSGJF-Cka5t09q.js → sankeyDiagram-IPEJSGJF-BzX37jGY.js} +3 -3
- package/dist/{sequenceDiagram-PO4LG4MO-B2qb55A5.js → sequenceDiagram-PO4LG4MO-Bgx1kuGA.js} +5 -5
- package/dist/{sortable-provider-C5VYhY8u.js → sortable-provider-WZT5I34N.js} +24 -24
- package/dist/{src-C9kQSo6K.js → src-CsLQInsN.js} +1 -1
- package/dist/{stateDiagram-v2-GCMORJYK-EMa7q3ju.js → stateDiagram-v2-GCMORJYK-Chc9Z6Mr.js} +14 -14
- package/dist/{stored-language-B0o4cBh8.js → stored-language-BW32owje.js} +56 -10
- package/dist/styles.css +10 -368
- package/dist/{swimlanes-2SLR337P-BtZ7Di5u.js → swimlanes-2SLR337P-D0yLvfot.js} +12 -12
- package/dist/swimlanesDiagram-TC7HE7FX-BOd0Czfs.js +28 -0
- package/dist/{timeline-definition-EJHVYXUP-2Z6UABw8.js → timeline-definition-EJHVYXUP-nDNR-Dt-.js} +5 -5
- package/dist/{translate-material-BCwQrt2G.js → translate-material-ZEzF-LKH.js} +2 -2
- package/dist/{translator-CwpmpI24.js → translator-BfqVlNGW.js} +1 -1
- package/dist/{use-heading-spy-BtBJiU63.js → use-heading-spy-DvZVu15k.js} +37 -37
- package/dist/{use-material-translation-DG_7z3Q7.js → use-material-translation-B2GUtxUY.js} +2 -2
- package/dist/{usecaseDiagram-POWQR4AR-DT56cp_B.js → usecaseDiagram-POWQR4AR-Bwen99ay.js} +13 -13
- package/dist/{utils-UBn-46YY.js → utils-DC8bw9A_.js} +346 -360
- package/dist/{vennDiagram-UO4OBE2U-CO0yFCI8.js → vennDiagram-UO4OBE2U-BpgP__1T.js} +4 -4
- package/dist/{wardleyDiagram-VNRHLVJA-QkwghAYo.js → wardleyDiagram-VNRHLVJA-CYqKMb2f.js} +4 -4
- package/dist/{xychartDiagram-PMCCYNJV-B2aZlrno.js → xychartDiagram-PMCCYNJV-b-Quuxoi.js} +7 -7
- package/docs/components/buttons-and-actions.md +60 -10
- package/docs/components/data-display.md +24 -2
- package/docs/components/data-table-filter-and-lists.md +88 -10
- package/docs/components/date-and-time.md +24 -0
- package/docs/components/feedback-and-status.md +85 -8
- package/docs/components/form-fields.md +14 -5
- package/docs/components/media-and-files.md +7 -0
- package/docs/components/navigation-and-layout.md +21 -3
- package/docs/components/overlays-and-menus.md +21 -6
- package/docs/components/primitives.md +96 -7
- package/docs/components/rich-widgets.md +10 -0
- package/docs/components/selection-and-choice.md +13 -2
- package/docs/getting-started.md +4 -2
- package/docs/guides/app-shell.md +97 -4
- package/docs/guides/forms.md +54 -5
- package/docs/guides/helpers.md +2 -2
- package/docs/guides/i18n.md +24 -4
- package/docs/guides/ssr.md +1 -1
- package/docs/guides/theming.md +147 -5
- package/docs/previews/data-display-codegroup.webp +0 -0
- package/docs/previews/data-display-description.webp +0 -0
- package/docs/previews/feedback-status-toast.webp +0 -0
- package/docs/previews/primitives-tabs.webp +0 -0
- package/docs/previews/rich-widgets-emojipicker.webp +0 -0
- package/docs/roadmap.md +29 -1
- package/docs/troubleshooting.md +937 -11
- package/lib/components/base-content.css +139 -0
- package/lib/components/base.css +150 -0
- package/lib/components/components.css +2 -0
- package/lib/components/reduced-motion.css +56 -0
- package/lib/components/theme-tokens.css +116 -0
- package/lib/components/ui/actions/button-group/button-group.css +1 -1
- package/lib/components/ui/feedback/toast/toast.css +21 -0
- package/lib/components/ui/primitives/label/label.css +33 -0
- package/lib/styles.css +10 -368
- package/package.json +2 -2
- package/dist/field-blur-DWQtxiAe.js +0 -3483
- package/dist/flowDiagram-KWPJA3E3-DZxumFfu.js +0 -17
- package/dist/icon-button-BxySFfrr.js +0 -2718
- package/dist/lib/components/ui/widgets/emoji/emoji.groups.d.ts +0 -6
- package/dist/swimlanesDiagram-TC7HE7FX-CROh8GTF.js +0 -28
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,206 @@
|
|
|
1
1
|
# @nxgt/material
|
|
2
2
|
|
|
3
|
+
## 2.9.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#468](https://github.com/softistx/nxgt-material/pull/468) [`5d57954`](https://github.com/softistx/nxgt-material/commit/5d57954d477f81d02872382b8ba54a97168dd191) Thanks [@SteveGT96](https://github.com/SteveGT96)! - `Tabs` has two looks: `underline`, the new default (tabs over a border, the active one in the primary colour with a bar under it that slides to the tab clicked or reached with the arrow keys), and `segmented` (a neutral pill track whose raised surface slides to the active tab, whose label also turns foreground and semibold). `TabsVariant` is `'underline' | 'segmented' | 'bar' | 'line'`; `bar` is a deprecated alias of `underline` and `line` of `segmented`, so no call site or type breaks. The list scrolls sideways when the tabs overflow (its scrollbar hidden), `orientation="vertical"` puts the indicator on the side, and the focus ring is a primary outline inside the tab. Server HTML and pages without JavaScript show a static indicator under the active tab; once measured, the list carries `data-indicator="ready"` and the sliding one takes over, with no hydration mismatch. In the dark theme the active label is the primary colour mixed with white (it was the bare primary, 2.7:1 on the page). `TabsTrigger`'s `icon` now renders in a `<span data-slot="tabs-trigger-icon">` (it was a `<div>` inside the `<button>`). `CodeGroup` and the emoji lists use `underline`.
|
|
8
|
+
|
|
9
|
+
The indicator jumps instead of sliding under `prefers-reduced-motion: reduce`, and `dir="rtl"` runs the tabs and the indicator from the right. The `segmented` track scrolls sideways on a phone too, rather than widening the page. The emoji list's icon-only group tabs are named (`aria-label` and `title`, from the new `material.emoji.groups.*` keys, in English and French); an icon-only `TabsTrigger` of your own needs an `aria-label` the same way.
|
|
10
|
+
|
|
11
|
+
`TabsList` accepts `asChild` (it threw in React with two children; the sliding indicator now sits inside the child, and in Vue a list with `asChild` keeps the static indicator), and the indicator follows a tab inserted or removed before the active one.
|
|
12
|
+
|
|
13
|
+
**Deprecated:** `variant="bar"` and `variant="line"`. They still type-check and render, as `underline` and `segmented`; write those instead.
|
|
14
|
+
|
|
15
|
+
**Visible change:** a `Tabs` with no `variant`, or with `variant="bar"`, no longer renders the boxed look (equal-width triggers, a primary ring and tint around the active one, a 10px label under its icon on the phone); it renders `underline`. `variant="line"` renders `segmented` (a rounded pill, not the muted strip).
|
|
16
|
+
|
|
17
|
+
### Migration
|
|
18
|
+
|
|
19
|
+
- Search for `variant="bar"` and replace it with `variant="underline"` (or remove it: `underline` is the default). Search for `variant="line"` and replace it with `variant="segmented"`. Search for `variant: 'bar'` / `variant: 'line'` in objects and typed props the same way.
|
|
20
|
+
- The old `bar` look is gone. The closest is `underline`; to keep its equal-width triggers, add `className="w-full"` to `TabsList` and `className="flex-1"` to each `TabsTrigger`. To keep a boxed active tab, `segmented` is the closest.
|
|
21
|
+
- Tests that queried the old classes must change: `ring-primary`, `ring-1`, `bg-primary/10`, `text-primary` on the active trigger, `text-[10px]` / `md:text-xs` on its label, `bg-muted/60` on the `line` list. Query the state instead: `getByRole('tab', { selected: true })`, or `toHaveAttribute('data-state', 'active')`, and `data-variant` on `[data-slot="tabs"]` for the look (it holds the variant as written: `bar` stays `bar`).
|
|
22
|
+
- A test that looked for the icon as a `div` inside the trigger must look for `[data-slot="tabs-trigger-icon"]`.
|
|
23
|
+
|
|
24
|
+
### Patch Changes
|
|
25
|
+
|
|
26
|
+
- [#470](https://github.com/softistx/nxgt-material/pull/470) [`853d093`](https://github.com/softistx/nxgt-material/commit/853d093f0620dc6940ea1ce69e025b61e3b0094d) Thanks [@SteveGT96](https://github.com/SteveGT96)! - The roadmap names the release that ships the two Tabs looks and the emoji groups.
|
|
27
|
+
- Updated dependencies [[`5f984fa`](https://github.com/softistx/nxgt-material/commit/5f984fa95a2944e6c71acd81d0272730d87c2c0a), [`853d093`](https://github.com/softistx/nxgt-material/commit/853d093f0620dc6940ea1ce69e025b61e3b0094d)]:
|
|
28
|
+
- @nxgt/material-core@0.6.0
|
|
29
|
+
|
|
30
|
+
## 2.8.0
|
|
31
|
+
|
|
32
|
+
### Minor Changes
|
|
33
|
+
|
|
34
|
+
- [#441](https://github.com/softistx/nxgt-material/pull/441) [`832e0e9`](https://github.com/softistx/nxgt-material/commit/832e0e90d828f13db132bf374cf87a316345565f) Thanks [@SteveGT96](https://github.com/SteveGT96)! - Every day of a `Calendar` (and so of `DateField`, `DateFormField`, `DateRangeField` and the date picker of `EventCalendar`) is named by its full localized date and nothing else: "Thursday, October 1, 2026", "jeudi 1 octobre 2026", on the button and on the `gridcell` around it (Testing Library names a cell from its content). Before, the button was named "Thursday, October 1st, 2026" (with "Today, " and ", selected" added) and the cell was named by its text, "1". The name is built with `Intl`, so `labels.labelDayButton` is no longer needed to translate it (pass your own to override it on the cell and the button). The chosen day keeps `aria-selected="true"` on its cell and its button is now described by one hidden, translated "Selected" (`material.calendar.selected`); today carries `aria-current="date"` on its cell and its button. The days of the neighbouring months are named by their own dates, so a bare number matches no day.
|
|
35
|
+
|
|
36
|
+
The language is the calendar's `locale`, else the active `I18nProvider` language, else English, and it now drives the day names, the heading, the weekday row and the month dropdown (`captionLayout="dropdown"`), which followed the browser's language before, alike: a `Calendar` under a French `I18nProvider` shows French month names (pass `locale={enUS}` from `react-day-picker/locale` to keep English). A test that looked for a day by "Today" or "selected", or by its number alone must use the date: `getByRole('gridcell', { name: 'Thursday, October 1, 2026', exact: true })` or `getByRole('button', { name: 'Thursday, October 1, 2026', exact: true })`, and check `aria-selected` / `aria-current` on the cell. Compute the name with `Intl.DateTimeFormat('en', { dateStyle: 'full' })` for today's.
|
|
37
|
+
|
|
38
|
+
- [#453](https://github.com/softistx/nxgt-material/pull/453) [`0ad04c8`](https://github.com/softistx/nxgt-material/commit/0ad04c8c013e48761abc70aaed10efaf79001159) Thanks [@SteveGT96](https://github.com/SteveGT96)! - More contrast fixes in `styles.css` and the components. The light `--muted-foreground` is darker (`oklch(0.52 ...)`): muted text reaches 5.5:1 on `--background`, 5.1:1 on the `bg-background-paper` tint and 5.0:1 on `--muted` (it was 4.8, 4.4 and 4.3:1). The dark `--muted` was the light value, a near-white surface on a dark page (`bg-muted`: `Alert variant="foreground"`, code, the default `Timeline` marker...); it is now a dark surface, `oklch(0.279 0.041 260.031)`, and `--muted-foreground` reads at 4.7:1 on it. If your app set its own dark `--muted`, check it against `--muted-foreground` at 4.5:1.
|
|
39
|
+
|
|
40
|
+
In the dark theme, the filled `secondary`, `success`, `info` and `warning` `Button` and `IconButton` are tinted like the `Badge` (`dark:bg-secondary/70`, `dark:bg-success/60`..., hover, focus and pressed further down): their near-white text keeps 5.2, 7.3, 5.7 and 7.5:1 on `--background` and 4.9, 6.7, 5.3 and 7.0:1 on `--card` (it was 4.3, 3.5, 2.5 and 3.4:1).
|
|
41
|
+
|
|
42
|
+
In the light theme, the filled `primary`, `secondary`, `success`, `info`, `warning` and `error` `Button` and `IconButton` no longer fade when hovered, focused or pressed (`hover:bg-primary/90`, `focus:bg-primary/80` and `active:bg-primary/70` let the white page through: down to 3.1:1 pressed, 3.75:1 focused): they darken instead (`hover:bg-[color-mix(in_oklab,var(--color-primary)_90%,black)]`, 85% focused, 80% pressed), so their text keeps at least 4.5:1 in every state, in both themes. The tonal variant's focus tint is lighter (`focus:bg-*/10`, was `/50`: 2.7:1 for `secondary`), the outlined one's `focus:bg-*/15` (was `/20`), and the outlined hover keeps the text colour (`hover:text-*/90` is gone). A `className`/`class` of your own that sets those states back to `/90`, `/80` or `/70` brings the low contrast back: search for `hover:bg-<color>/90`, `focus:bg-<color>/80` and `active:bg-<color>/70` on a filled button and drop them.
|
|
43
|
+
|
|
44
|
+
New `--track` and `--track-fill` tokens (`bg-track`, `bg-track-fill`, `border-track-fill`) for non-text parts that `bg-muted` drew: the `Slider` track, range and thumb border, the password strength meter's empty bars and the `Drawer` handle. In the dark theme the track reaches 3.6:1 on `--background` and 3.2:1 on `--card` (WCAG 1.4.11; `bg-muted` gave 1.4 and 1.2:1) and the fill 3.4:1 on the track; the light theme looks as before. A track, bar, handle or divider of your own drawn with `bg-muted` is near invisible in the dark theme now: draw it with `bg-track`.
|
|
45
|
+
|
|
46
|
+
A library toast's text is no longer faded in with its wrapper (sonner starts it at opacity 0, which an accessibility audit reports as low contrast while it enters): it slides and scales in at full opacity. `toast()` and `toasts.*` render through sonner's `toast.custom` (`data-styled="false"`); a toast sonner styles itself (a plain `toast('…')` from `sonner`, or `sonnerToast`) still fades in. `DropdownMenuItem`'s `active` now sets `data-active` instead of the invalid `aria-active` (React warned "Invalid aria prop"); style it with `data-[active]:` or `[data-active]`. The `StxPlayer` captions menu is a radio group (`menuitemradio`, the chosen entry `aria-checked`), like its speed menu. Pressing `c` before choosing a caption language turns on the track's first one, and the menu checks it (it showed every track while "Off" stayed checked). The `focus:bg-muted0` typo on the filled `Button` and `IconButton` is `focus:bg-muted`.
|
|
47
|
+
|
|
48
|
+
`styles.css` now imports its colour tokens from `components/theme-tokens.css` and its base layer from `components/base.css` and `components/base-content.css`, shipped beside it; it has the same rules, in the same order. Nothing to change in an app that imports `styles.css`; an app that copied the file instead of importing it finds the `:root` and `.dark` tokens in `theme-tokens.css`.
|
|
49
|
+
|
|
50
|
+
**Migration, for an app that overrides the theme's tokens** (search its stylesheets for each name under `:root` and under `.dark` / `[data-theme="dark"]`):
|
|
51
|
+
|
|
52
|
+
- A dark `--secondary` of your own: the filled `secondary` `Button`, `IconButton` and `Badge` now draw it at 70 % in the dark theme under near-white text. Keep your value bright enough to read as text on `--background` and `--card` (4.5:1: the `tonal`, `outlined` and `link` secondary variants), and check the filled button's near-white text on it at 70 %. A darker value, picked for white text at 100 %, now fails as text on the dark page and looks dim at 70 %: raise its lightness (the shipped one is `oklch(0.66 0.1135 245.65)`).
|
|
53
|
+
- A light `--muted-foreground` of your own: the shipped one is now `oklch(0.52 0.046 257.417)`. Check yours at 4.5:1 on `--background`, the paper tint and `--muted`, or delete the override.
|
|
54
|
+
- A dark `--muted` of your own: it was a near-white value in the shipped theme and is now a dark surface (`oklch(0.279 0.041 260.031)`). If yours is light, `Alert variant="foreground"`, code and the `Timeline` marker draw near-white blocks on the dark page: replace it with a dark surface that keeps `--muted-foreground` at 4.5:1.
|
|
55
|
+
- New `--track` and `--track-fill`: if you restyled the `Slider`, the password strength meter or the `Drawer` handle by overriding `--muted`, override `--track` (the empty part, 3:1 on `--background` and `--card`) and `--track-fill` (the range and thumb border, 3:1 on the track) instead. Your own tracks, bars, handles and dividers drawn with `bg-muted`: replace `bg-muted` with `bg-track` (and a fill with `bg-track-fill`).
|
|
56
|
+
|
|
57
|
+
The filled `default` `IconButton` drew its icon in the page foreground on a foreground background (invisible); it now draws it in `background`. The `link` `IconButton` took the primary colour for every `color`; each colour now uses its own text colour (in the light theme `warning` and `error`, in the dark theme `primary`, `success`, `warning` and `error`, are mixed toward black or white to keep 4.5:1 in every state; the `Button` link variant uses the same tones). The `ButtonGroup`'s active item darkens on hover like the filled `Button`.
|
|
58
|
+
|
|
59
|
+
- [#459](https://github.com/softistx/nxgt-material/pull/459) [`9ca2a84`](https://github.com/softistx/nxgt-material/commit/9ca2a847b846c996502978275cf68ef253408e80) Thanks [@SteveGT96](https://github.com/SteveGT96)! - The `tonal` and `outlined` variants of `Button` and `IconButton` read at 4.5:1 or more in every colour, in both themes, on `--background` and `--card`, at rest, hovered, focused and pressed (WCAG 1.4.3). They drew their text and icon in the token itself, which some tokens do not reach as text: in the dark theme `primary` gave 2.5:1 on `--background` and 2.2:1 on `--card` (the dark `--primary` is the same dark indigo as the light one), `error` 3.9 and 3.5:1, `success` 4.0:1 on `--card`; in the light theme `error` gave 3.6:1 on its tonal tint (4.0 hovered, 3.6 outlined and focused) and `warning` 4.3:1. They now take the `link` variant's tones, mixed from the tokens: in the light theme `warning` and `error` mixed with 15 % black (now 6.0 and 5.4:1), in the dark theme `primary` with 60 % white (8.1:1 on `--card`), `success` and `warning` with 15 % white (5.0 and 5.4:1) and `error` with 30 % white (5.9:1); the other colours keep the token (light `primary` 5.8, `secondary` 4.8, `info` 4.9, `success` 4.7:1; dark `secondary` 4.6, `info` 5.3:1). The tones live in one place (`button-tones.ts`) shared by the three variants and by `IconButton`'s icon line.
|
|
60
|
+
|
|
61
|
+
A `Badge` used as a link (`asChild` around an `<a>`) no longer fades on hover (`[a&]:hover:bg-*/90` let the page through: 4.3:1 for `error` in the light theme, 3.0:1 for `info` and 3.5:1 for `secondary` in the dark one): it darkens like a filled button, `[a&]:hover:bg-[color-mix(in_oklab,var(--color-*)_90%,black)]`, and in the dark theme its tint drops by ten points (`dark:[a&]:hover:bg-secondary/60`, `/50` for `success`, `info`, `warning` and `error`); every colour now keeps 5.9:1 or more hovered.
|
|
62
|
+
|
|
63
|
+
A selected `ListTile` draws its subtitle in `text-foreground/70`: the muted colour gave 4.4:1 on the selected tint, it is now 7.0:1 (8.9:1 in the dark theme).
|
|
64
|
+
|
|
65
|
+
The light `--error` is a shade darker, `oklch(0.56 0.245 27.325)` (was `0.577`): a filled `error` `Button`, `IconButton` or `Badge` gives its near-white text 4.8:1 (was 4.6:1), and the colour as text 5.0:1 on white. The dark `--error` is unchanged. The light `--destructive` (the deprecated alias of `--error`) is now `var(--error)`, so invalid borders and rings drawn with it match.
|
|
66
|
+
|
|
67
|
+
`Guides/Theming/Contrast` now measures `Button` and `IconButton` in every variant and colour and a `Badge` link in every colour, in all four states and both themes; `Data display/ListTile` measures its tiles, the selected one included.
|
|
68
|
+
|
|
69
|
+
**Migration, for an app that overrides tokens or classes:**
|
|
70
|
+
|
|
71
|
+
- A text colour of your own on a `tonal`, `outlined` or `link` button (`className="text-primary"`, `text-error`…) replaces the tone and brings the low contrast back: drop it, or check it at 4.5:1 on `--background`, `--card` and the variant's 15 % tint, in both themes.
|
|
72
|
+
- An override of `--primary`, `--success`, `--warning` or `--error` moves its tone with it (the tones are `color-mix` of the token). A dark `--primary` of your own that is already light enough to read as text now reads lighter still (mixed with 60 % white); a light `--warning` or `--error` of your own is drawn 15 % darker as text. Check both against the page.
|
|
73
|
+
- A light `--error` of your own: the shipped one is now `oklch(0.56 0.245 27.325)`. Keep yours or delete the override; check near-white text on it at 4.5:1.
|
|
74
|
+
- A `Badge` link given a hover fade such as `[a&]:hover:bg-error/90` in its `className`: replace it with a darkening, `[a&]:hover:bg-[color-mix(in_oklab,var(--color-error)_90%,black)]` (with the badge's colour in place of `error`).
|
|
75
|
+
- A subtitle colour of your own on a selected `ListTile`: check it at 4.5:1 on `bg-primary/15`.
|
|
76
|
+
|
|
77
|
+
- [#448](https://github.com/softistx/nxgt-material/pull/448) [`e1a4059`](https://github.com/softistx/nxgt-material/commit/e1a405978ae92c4f5720b864b4f42a513a3b959f) Thanks [@SteveGT96](https://github.com/SteveGT96)! - Text and icons now reach WCAG contrast, and animations honour `prefers-reduced-motion`. In `styles.css`, the light `--secondary`, `--success`, `--info` and `--warning` are darker, so a filled `Badge` or `Button` keeps 4.5:1 with its near-white text (5.7, 5.6, 5.8 and 5.3:1; it was 4.3, 3.5, 2.5 and 3.4:1) and the colour read as text (an `outlined` or `link` button, a link) 5.5:1 or more on the page, at rest. The dark theme keeps bright values, read as text on the dark surfaces: its `--secondary` is brighter, `oklch(0.66 0.1135 245.65)` (6.5:1 on `--background`, 5.8:1 on `--card`; a `tonal` secondary `Button` 5.4 and 4.6:1), and the filled surfaces under near-white text are tinted, the dark `secondary` `Badge` at 70 % (5.2:1 on `--background`, 4.9:1 on `--card`), `success`, `info` and `warning` at 60 % (7.3, 5.7 and 7.5:1); the dark `--muted-foreground` is brighter, `oklch(0.66 ...)` (6.4:1 on `--background`, 5.7:1 on `--card`; it was 4.2 and 3.7:1). The toast's X button has a visible focus ring and no colour transition, and the toast description reads at 4.5:1; the muted shortcut text of a highlighted dropdown, context or menubar entry, and the `LanguageSwitcher` code, switch to `--accent-foreground`. One `@media (prefers-reduced-motion: reduce)` rule, in `components/reduced-motion.css` imported by `styles.css`, turns off the transitions and animations of every catalogue component (dialogs, sheets, menus, toasts, buttons); the `Spinner` and `animate-spin` elements keep turning. If your app overrides those tokens, check them against 4.5:1; to keep one animation for everyone, override it with your own `!important` rule on that element inside the same media query (the rule is unlayered with a specificity of 0, so yours wins). See the theming guide's "Contrast and reduced motion".
|
|
78
|
+
|
|
79
|
+
- [#463](https://github.com/softistx/nxgt-material/pull/463) [`e3b10d6`](https://github.com/softistx/nxgt-material/commit/e3b10d64b55867eb320472ee0185b24d9dea81da) Thanks [@SteveGT96](https://github.com/SteveGT96)! - New `--error-text` token (`--color-error-text` in `@theme`, so `text-error-text`) for error drawn as text. In the light theme it is `color-mix(in oklab, var(--error) 94%, black)`, 5.7:1 on white and 4.8:1 on the `bg-error/10` tint of a focused error menu item (every light menu uses that one tint; `--error` itself gives 5.0 and 4.2:1); in the dark theme it is `color-mix(in oklab, var(--error) 80%, white)`, 5.9:1 on `--background` and 5.3:1 on `--card`, where `--error` as text gave 4.18 and 3.75:1. The dark `--error` itself is unchanged: it stays dark enough for near-white text on a filled error surface.
|
|
80
|
+
|
|
81
|
+
The catalogue's error text now uses it, so it is lighter in the dark theme: `HelperText` in its error state (and so every field's error message), the error of `ConfirmDialog`, the PDF reader's password form, `ImageCropper`, the number-range filter, the chat composer and a failed chat message, a network upload's failed item (its icon too), `StxPlayerMini`, an `OtpField` in error, a textarea's counter over its limit, the error lines of `Terminal`, `ParamTable`'s required mark, the falling values of `StatCard` and the metric cards, and `variant="error"` menu items (`DropdownMenu`, `ContextMenu`, `Menubar`). In the dark theme the focused error item of `DropdownMenu` and `ContextMenu` now uses the `/20` tint, the same as `Menubar` and the Vue menus. Fills, borders, rings, the `Button` and `Badge` tones, the `Banner` (its icon only takes the colour; its text is foreground) and standalone icons (the `Alert` and toast icons, `EmptyState`, `Timeline` markers, `RatingField`) keep `--error`.
|
|
82
|
+
|
|
83
|
+
**Migration** (only text changes: lighter in the dark theme, slightly darker in the light one; nothing breaks):
|
|
84
|
+
|
|
85
|
+
- Search the app for `text-error` not followed by `-` (for example `rg '\btext-error($|[^-])'`). Where it colours **text** on a page, card or popover surface (a validation message, an inline error, a red value), and an icon drawn beside such text, replace it with `text-error-text`: `<p className="text-sm text-error">` becomes `<p className="text-sm text-error-text">`, except on a `Button`/`IconButton`, where the tone already colours it: drop the class instead (see the contrast note on button text colours). Leave it on fills, borders, rings and icons that stand alone, and leave `text-error-foreground` (text on a filled error surface) as it is. Check by hand the arbitrary forms the search cannot see: `text-(--color-error)`, `text-[var(--error)]`, and `color: var(--error)` / `var(--color-error)` in CSS.
|
|
86
|
+
- An app that overrides `--error` under `:root` and `.dark, [data-theme="dark"]`: `--error-text` follows it (the 94 % mix with black in light, the 80 % mix with white in dark). Check the dark mix at 4.5:1 on `--background` and `--card`, or set `--error-text` yourself beside your `--error`. Below the root, setting `--error` or `--error-text` on an element changes nothing (`@theme` resolves `--color-error-text` on the root): set `--color-error-text` (and `--color-error` for fills) on that element, or put the override on the root.
|
|
87
|
+
|
|
88
|
+
- [#450](https://github.com/softistx/nxgt-material/pull/450) [`8e568c3`](https://github.com/softistx/nxgt-material/commit/8e568c3544327c1ba273482963ec13e1930d3be6) Thanks [@SteveGT96](https://github.com/SteveGT96)! - An invalid field takes focus. React Hook Form focuses the first invalid field on a failed `handleSubmit` (`shouldFocusError`) and the one named by `setError(name, error, { shouldFocus: true })` or `setFocus(name)` by calling `focus()` on the `ref` the field registered, and no wrapper handed it over: every `*FormField`, the plain text inputs included, and the config-driven `FormField` left `field.ref` unset, so `shouldFocusError`, `setError(…, { shouldFocus: true })` and `setFocus(name)` did nothing. Every wrapper now forwards `field.ref`: an input takes it directly, and a field made of several controls (a select, a group of chips or cards, a date range, an upload, a slider, a dialog editor such as `ContactsFormField`) hands React Hook Form a handle that focuses the first control a user can reach, looked up when `focus()` is called. `FilterFormField` is the one exception (it holds criteria, not a value that can be invalid). `useFieldBlur(onBlur)` takes `field.ref` as an optional second argument for a field of your own. A story (`Guides/Forms/Focus on error`) and `scripts/form-field-blur.spec.ts` fail when a wrapper stops forwarding it.
|
|
89
|
+
|
|
90
|
+
Focus now survives the error appearing: `TextField`, `SelectField`, `UploadField` and `Switch` used to build a different tree once they had help text, so the control was remounted (and lost focus) the moment a validation message arrived. They keep one tree with or without help text; the DOM gains one wrapping `div` around the control where there was no help text before.
|
|
91
|
+
|
|
92
|
+
`SelectField` (and `SelectFormField`) describe their trigger by the help or error text (`aria-describedby`) and mark it `aria-invalid` on error, so `toHaveAccessibleDescription` and `toBeInvalid` match; the name still comes from the label.
|
|
93
|
+
|
|
94
|
+
`TextField` (and `TextFormField`) describes its input by the help or error text too (`aria-describedby`, after any `aria-describedby` you pass), so a screen reader reads the validation message with the field and `toHaveAccessibleDescription` matches.
|
|
95
|
+
|
|
96
|
+
`SelectChipField` (and `SelectChipFormField`, and `FormField` types `chips-single` / `chips-multiple`): the chips are toggle buttons, so a chosen one is `aria-pressed="true"` instead of `aria-selected="true"` (which is not allowed on a button), in single mode too since pressing the chosen chip clears it, and the chips sit in a `role="group"` named by the label and described by the help text. A test that matched a chip by `aria-selected`, or by `getByRole('option')`, must query `getByRole('button', { name })` and check `aria-pressed`; to find the group, `getByRole('group', { name: <label> })`. `SelectCardField` is unchanged.
|
|
97
|
+
|
|
98
|
+
- [#449](https://github.com/softistx/nxgt-material/pull/449) [`907bd37`](https://github.com/softistx/nxgt-material/commit/907bd37132e81529c66d4a6312512bf7a9f66c3a) Thanks [@SteveGT96](https://github.com/SteveGT96)! - `ActivityLayout` follows the page instead of fighting it, on desktops and phones:
|
|
99
|
+
|
|
100
|
+
- **Size and scrolling.** It was `100lvw × 100lvh` and scrolled its content inside an absolutely positioned box: the page was a scrollbar's width too wide and, on a phone, the bottom of the content sat under the browser's toolbar. It is now `100%` wide and at least `100dvh` high, and **the document scrolls**; the header and the desktop sidebar are sticky. A screen that needs the old in-shell scrolling (a full-height map, a board) passes the new `scroll="container"`. Migration: a test or script that scrolled the shell's inner `.overflow-auto` box scrolls the window instead; a screen sized `h-full` to fill the shell adds `scroll="container"` to its `ActivityLayout`.
|
|
101
|
+
- **A new screen starts at the top with `scroll="container"`.** The content region outlives navigations, so a new page used to open at the previous page's scroll position, and Back did not restore it (React Router's `ScrollRestoration` only handles the window). The region now starts each new pathname at the top (a change of query or hash only — a filter, a tab, an `#anchor` — keeps the position), and Back or Forward returns to where that entry was left. With the default document scrolling, the router's own restoration applies.
|
|
102
|
+
- **One `<main>`.** The content region is now the page's `<main>` landmark (`getByRole('main')`). An app that already renders a `<main>` around the shell passes the new `contentAs="div"`.
|
|
103
|
+
- **`className` reaches the outer element** (`[data-slot=activity-layout]`), as the docs said, with the other `div` props; it used to land on the inner box. Migration: search for `<ActivityLayout className=` and check the classes were meant for the whole shell.
|
|
104
|
+
- **The phone menu sheet** is a dialog named "Navigation" (new key `material.app-shell.navigation`, "Navigation" in English and French) with a visible "Close" button. Following an entry, or any change of location, closes it and moves focus to `<main>`; Escape, the close button and the overlay still return focus to the menu button. Its entries show their labels, so no tooltip opens over the first one as the sheet takes focus.
|
|
105
|
+
- **`SidebarMenuItem`** shows its label as a tooltip only while its `Sidebar` is collapsed; an expanded sidebar shows the label itself. An explicit `tooltip` is always shown.
|
|
106
|
+
|
|
107
|
+
`ActivityContent`'s `title` is now a heading, `h1` by default — a screen's title is the page's top heading, and the shell renders none — with a new `titleAs` (`'h1'` … `'h6'`, or `'div'` for no heading). The title no longer carries `Typography`'s `overflow-auto` (it wraps instead of scrolling), and the header card wraps, so the actions go under the title on a narrow screen. Migration: a test can find it with `getByRole('heading', { level: 1, name: 'Invoices' })`; a screen nested under a heading of its own passes `titleAs="h2"`.
|
|
108
|
+
|
|
109
|
+
`CardTitle` is now a heading, `h3` by default (it was a `div`), with a new `as` (`'h2'` … `'h6'`, or `'div'`); its classes are unchanged. Migration: search for selectors on `div[data-slot=card-title]` and use `getByRole('heading', { name })`; pass `as="div"` where the title must not be a heading.
|
|
110
|
+
|
|
111
|
+
`CardTitleProps`, `CardTitleElement` and `ActivityContentTitleElement` are exported.
|
|
112
|
+
|
|
113
|
+
`Typography`'s misspelled `data-test="typogaphy"` is now `data-test="typography"`. Migration: search for `typogaphy` in tests and selectors and replace it with `typography`.
|
|
114
|
+
|
|
115
|
+
`AppHeader` used on its own, outside `ActivityLayout`, now needs a React Router context: its menu sheet reads the location (`useLocation`) to close when it changes. Migration: render it under your router, or inside a `MemoryRouter` in a test.
|
|
116
|
+
|
|
117
|
+
`Background` is sized `w-lvw h-lvh` instead of the custom `size-lv`, which tailwind-merge did not know: a `className` such as `h-96 w-full` or `size-auto` now overrides the viewport size, as the docs said — before, `size-lv` won, which also kept `ActivityLayout` one screen high. Its default look, and `HydrateLoading`'s and `ThreadLayout`'s, are unchanged. The `size-lv` utility is still defined.
|
|
118
|
+
|
|
119
|
+
- [#437](https://github.com/softistx/nxgt-material/pull/437) [`679cc06`](https://github.com/softistx/nxgt-material/commit/679cc06a184f401c34e770ea2acfc12bfd10d24d) Thanks [@SteveGT96](https://github.com/SteveGT96)! - `ActivityLayout`, `AppSidebar` and `AppHeader` menu entries (`MenuItem` with a `url`) now render as real links, `<a href>`, instead of buttons that called `navigate()`. They work on a server-rendered page before hydration, open in a new tab on middle-click or ctrl-click, are announced as links, and the current page carries `aria-current="page"`. By default each is a React Router `Link`, so client-side navigation and the router `basename` behave as before. New optional `linkComponent` prop on `ActivityLayout`, `AppHeader` and `AppSidebar` (type `AppShellLinkComponent`: takes `href`, spreads the rest of its props) renders another link; `SidebarMenuItem` also takes `href` and `linkComponent` to render a link instead of a button. A test or selector that looked for a `button` role on a sidebar entry should look for `link`. The icon inside an entry is decorative (`aria-hidden`), so a link is named by its label alone (`getByRole('link', { name: 'Identities' })`), and an entry shows a focus ring for the keyboard. `linkComponent` must spread every prop it receives and forward `ref`.
|
|
120
|
+
|
|
121
|
+
- [#454](https://github.com/softistx/nxgt-material/pull/454) [`6b3b904`](https://github.com/softistx/nxgt-material/commit/6b3b904b9d2a281f9680da870a229fafdd3a4704) Thanks [@SteveGT96](https://github.com/SteveGT96)! - A loading `Button` is busy at once and submits nothing: `loading` now also sets `aria-busy="true"` and `aria-disabled="true"` (it set neither before, and still sets no native `disabled`, so it stays focusable), and cancels every click in the capture phase — the click that Enter in a field sends to the form's submit button included — so a double click or Enter pressed twice submits once. A busy click runs no handler: not your `onClick`, not an `asChild` child's own `onClick` (which used to run), and not a clickable ancestor's. New `lockOnClick`: a click makes the button busy before `loading` has rendered, until `loading` has turned true and back (or for one second when it never does), for a `loading` that turns true only after an `await` (a mutation's `isPending`). The recommended wiring is `loading={formState.isSubmitting}`. Busy buttons show a progress cursor: the class string now holds `aria-busy:cursor-progress`, so a markup assertion such as `expect(html).not.toContain('aria-busy')` matches it — test the attribute (`/\saria-busy=/`, `toHaveAttribute('aria-busy')`) instead. A busy state wins over an `aria-busy` or `aria-disabled` you pass; yours still apply while idle.
|
|
122
|
+
|
|
123
|
+
- [#447](https://github.com/softistx/nxgt-material/pull/447) [`5bafe79`](https://github.com/softistx/nxgt-material/commit/5bafe79c92c2ec65b9be33b603c38d79123173ce) Thanks [@SteveGT96](https://github.com/SteveGT96)! - `DataTable` works on a phone (WCAG 2.2 AA). **Breaking defaults** — search your code for each and act as said:
|
|
124
|
+
|
|
125
|
+
- **No height cap by default.** The table no longer scrolls inside `max-h-[400px]` on `[data-slot="table-wrapper"]`, and the stylesheet no longer caps `[data-slot="data-table"]` and `[data-slot="table-wrapper"]` to viewport-based heights (`max-h-[calc(100lvh-184px)]`, `max-h-[calc(100vh-432px)]`, …): on a phone they made a scroll inside the page's. The table is as tall as its rows. Where a table should scroll inside a box, pass the new `maxHeight` prop (a number of pixels or a CSS length): `<DataTable maxHeight={400} … />`.
|
|
126
|
+
- **The header row shows at every width.** Below 768px it used to be hidden, which lost the column names, sorting and "Select all". Pass `showHeader={false}` to hide it (or `showHeader={!isPhone}` for the old behaviour).
|
|
127
|
+
- **The toolbar renders only when it has content.** `actions` that return nothing (`() => null`, `false`, `''`) no longer leave an empty `<fieldset data-slot="header">`; look for what the toolbar holds, not for the fieldset.
|
|
128
|
+
- **A reserved toolbar band with selection actions.** A table with `actions` and the `select` column now shows the toolbar's height (68px) above the rows before anything is selected, as an empty `aria-hidden` `[data-slot="header-placeholder"]`, so the first selection no longer pushes the rows down. Expect screenshot and visual tests of such tables to change.
|
|
129
|
+
|
|
130
|
+
New: while its columns overflow, the table scrolls sideways in one box (`[data-slot="table-wrapper"]`; the `Table` primitive's own container no longer scrolls inside it), which is then a keyboard-focusable `region` (`tabindex="0"`) named "Scrollable table" (new key `material.table.labels.scroll-region`, or the new `scrollLabel` prop), with an edge fade on each side where columns are hidden (`data-scroll-start` / `data-scroll-end` on `[data-slot="table-scroll"]`). A test that used a bare `getByRole('region')` on a page with a wide table must query by name. The empty state is centred within the visible width instead of across the whole scroll width, and the `select` column's checkboxes keep their 16px box with a 24px target around it (WCAG 2.5.8).
|
|
131
|
+
|
|
132
|
+
With `maxHeight`, the header row sticks to the top of the box, on an opaque background, while the rows scroll under it. Selection actions no longer push the rows down: with `actions` and the `select` column, the toolbar's height (one row of default-size buttons) is reserved, as an empty `aria-hidden` `[data-slot="header-placeholder"]` while they render nothing, so the button that appears on the first selection does not move the tapped row. Once focused, the scroll region stays a tab stop until focus leaves.
|
|
133
|
+
|
|
134
|
+
- [#454](https://github.com/softistx/nxgt-material/pull/454) [`9e9a571`](https://github.com/softistx/nxgt-material/commit/9e9a571f39b26c86ee37a3dfb954a271b5f6ba21) Thanks [@SteveGT96](https://github.com/SteveGT96)! - Every `*FormField` without an `id` of yours now gives its control a generated id (`useId`), never the field `name`. Two forms on one page with the same field name — a sign-in and a sign-up form both with `email`, two steps of a code check both with `code` — gave both controls one `id`, so the second label named the first form's input and the second field had no accessible name. Concerned: `TextFormField`, `TextareaFormField`, `EmailFormField`, `PasswordFormField`, `UrlFormField`, `NumberFormField`, `CurrencyFormField`, `PercentFormField`, `InputGroupFormField`, `PhoneFormField`, `OtpFormField`, `ColorFormField`, `TimezoneFormField`, `RatingFormField`, `DateFormField`, `TimeFormField`, `DateRangeFormField`, `DurationFormField`, `ComboboxFormField`, `AutocompleteFormField`, `TreeSelectFormField`, `FilesFormField` and `LocationFormField` (the switch, checkbox, slider and group wrappers already did). Migration: search for selectors or `htmlFor` that name a form field by its `name` used as an id (`#email`, `getElementById('code')`, `<label htmlFor="email">`) and replace them with a role query (`getByRole('textbox', { name: 'Email' })`), a `[name="email"]` selector, or pass `id="…"` to the wrapper. `setFocus(name)` on mount focuses a `PasswordFormField` or an `OtpFormField`, as every wrapper (Storybook: `Guides/Forms/Focus on error`).
|
|
135
|
+
|
|
136
|
+
- [#461](https://github.com/softistx/nxgt-material/pull/461) [`c6cc00a`](https://github.com/softistx/nxgt-material/commit/c6cc00a83a866c632aac043e44e46259272a31bb) Thanks [@SteveGT96](https://github.com/SteveGT96)! - The page behind a modal layer is now `inert`, not only `aria-hidden`: while a `Dialog` (and `DialogScrollContent`, `CommandDialog`), `AlertDialog`, `Sheet` or `Drawer` is open, or a `Select` list, a `ContextMenu`, or a `DropdownMenu` or `Popover` given `modal`, the page's controls leave the tab order and the accessibility tree, and axe's `aria-hidden-focus` ("ARIA hidden element must not be focusable or contain focusable elements") no longer fails on them. The `Toaster`'s live region stays reachable: a toast shown over a dialog is still announced and its action usable. Nested layers stack: a `Select` open in a `Dialog` makes the dialog inert until its list closes. The page is released as soon as the layer closes, so its exit animation runs over a usable page. Non-modal layers (`modal={false}`, and `DropdownMenu` and `Popover` by default) are unchanged.
|
|
137
|
+
|
|
138
|
+
A minor rather than a patch because three things a consumer can see change:
|
|
139
|
+
|
|
140
|
+
- An `onOpenAutoFocus` that calls `event.preventDefault()` on a modal `DialogContent`, `AlertDialogContent`, `SheetContent` or `DrawerContent` and focuses nothing no longer leaves focus on the element that opened it: the opener is inert, so focus goes to the layer's content. Search for `onOpenAutoFocus={(event) => event.preventDefault()}`: focus the element you want inside the layer in that handler, or make the layer non-modal (`modal={false}` on `Dialog`, `Sheet` or `Drawer`) to keep focus behind it.
|
|
141
|
+
- A test or script that reaches the page behind an open modal layer — `getByRole(…, { hidden: true })`, `element.focus()` on it, a Playwright locator outside the layer — now finds elements that are `inert` (they carry `inert` and `data-nxgt-inert`): close the layer first, or query inside it.
|
|
142
|
+
- Only `[aria-live]` regions (and scripts) stay reachable behind the layer, the same set `aria-hidden` keeps. An element with `role="status"`, `"alert"` or `"log"` but no `aria-live` — a `Banner`, for example — is inert while a modal layer is open: it is not announced and its controls cannot be reached. To keep one reachable, give it `aria-live` (`polite` for a status), or show it inside the layer.
|
|
143
|
+
|
|
144
|
+
- [#455](https://github.com/softistx/nxgt-material/pull/455) [`670de59`](https://github.com/softistx/nxgt-material/commit/670de597d2115c613855db9d1fd5cf2c64ddbc53) Thanks [@SteveGT96](https://github.com/SteveGT96)! - `ListTile` takes an optional `linkComponent` prop, with the app shell's contract (`AppShellLinkComponent`: it takes `href`, spreads every other prop and forwards `ref`), so a tile with an `href` can navigate on the client through a router `Link` instead of reloading the page. The default stays a plain `<a>`, which needs no router; the classes, `aria-current` and `data-slot="item-detail"` are unchanged. `Alert` now carries `data-slot="alert"` on its root, `data-slot="alert-title"` on the title and `data-slot="alert-description"` on the description.
|
|
145
|
+
|
|
146
|
+
- [#446](https://github.com/softistx/nxgt-material/pull/446) [`6d793fc`](https://github.com/softistx/nxgt-material/commit/6d793fc07326025e3bb31e17477b53aca0d7dc52) Thanks [@SteveGT96](https://github.com/SteveGT96)! - Four accessibility fixes found by an application's audit.
|
|
147
|
+
|
|
148
|
+
- **`DropdownMenu` (and `LanguageSwitcher`) is non-modal by default.** Radix's modal menu marks the rest of the page `aria-hidden` while its buttons and links stay focusable, which axe reports as `aria-hidden-focus`. Now nothing is hidden, and the menu still closes on Escape or an outside click (Tab stays in the menu). Pass `modal` to `DropdownMenu` to get the old behaviour back (scroll lock, outside clicks swallowed). If you relied on a click outside the menu being swallowed, add `modal`.
|
|
149
|
+
- **`ResponsiveButton` / `ResponsiveLinkButton` collapse with CSS, not a JS effect.** The label is always in the DOM and hidden below 768 px with a `max-md` media query, so the first paint is right (no flash of the full label on a phone, no hydration mismatch) and the accessible name is the same at every width. `expanded` still forces one state at every width. A test that fakes a mobile `matchMedia` to collapse the button should pass `expanded={false}`.
|
|
150
|
+
- **`Description` no longer spans the whole row, and its label is a label.** It had `col-start-full`, which broke a parent two-column grid; it now takes one cell (add `className="col-start-full"` for a full-width row). The label is small muted text above the value instead of a title with an underline bar, and the value is in the normal text colour.
|
|
151
|
+
- **`CopyButton` waits for the clipboard and announces the outcome.** "Copied" shows only once the write succeeded; a refusal shows "Copy failed" (new `failedLabel` prop and `material.copy.failed` string, in English and French). The result is announced through a visually hidden `role="status"` region next to the button instead of renaming the button, whose accessible name stays `Copy`. Tests that looked for a button named `Copied` should read the status next to the button, `within(button.parentElement!).getByRole('status')`; a test that reads another `role="status"` on a page with a `CopyButton` must now scope the query. `react-use`'s `useCopyToClipboard` is no longer used by it.
|
|
152
|
+
|
|
153
|
+
- [#458](https://github.com/softistx/nxgt-material/pull/458) [`f468ba0`](https://github.com/softistx/nxgt-material/commit/f468ba0b2bae04ed8cc629c5a2b0e353dca2e88e) Thanks [@SteveGT96](https://github.com/SteveGT96)! - `Button` is never wider than its container, and a long label is cut with "…" inside it instead of sticking out of a card on a phone (a 349 px button in a 343 px card). The button had `width: max-content` (`w-max`); it now has `width: fit-content; max-width: 100%` (`w-fit max-w-full`), and its bare text is rendered in a `<span data-slot="button-label">`, which shrinks and ends in an ellipsis. Its accessible name, and a `title` you give it, keep the whole label. New prop `wrap`: the label breaks onto as many lines as it needs, centred, and the button grows taller, never shorter than its `size` (ignored by the `icon*` sizes).
|
|
154
|
+
|
|
155
|
+
**Migration:** a `Button` that relied on growing past its container now truncates. Search for `<Button` with a long label in a narrow box (a card, a dialog footer, a table cell) and pass `wrap`, or give it a width of your own (`className="w-full"`). With `asChild`, the text inside the child element is clipped without an ellipsis: put the label in a `<span>` inside it. Code that read the button's first child node as its text (`button.firstChild`) now gets that span: read `textContent`, or find the button by role and name.
|
|
156
|
+
|
|
157
|
+
`OtpField`'s slots shrink with a narrow field and stay square: six fit a 320 px-wide card, each above WCAG 2.5.8's 24 px target, and the gaps narrow under the `sm` breakpoint (the input-otp container and groups take `min-w-0`). At full width they are the same size as before. A slot in error now carries `data-invalid` instead of `aria-invalid` (not allowed on a plain `div`); the input keeps `aria-invalid="true"`. **Migration:** a test that selected `[data-slot="input-otp-slot"][aria-invalid]` asserts `aria-invalid` on the input (`getByLabelText(<label>)`) instead; CSS keyed on a slot's `aria-invalid` uses `[data-invalid]`.
|
|
158
|
+
|
|
159
|
+
**Migration (tests):** `getByText('<label>')` now returns the inner `<span data-slot="button-label">`, not the button. Search for `getByText(<button label>)` followed by an attribute or class assertion (`toBeDisabled`, `toHaveAttribute`, `toHaveClass`) and switch it to `getByRole('button', { name: '<label>' })`. Consecutive text and numbers (`Delete {name}?`) are one span.
|
|
160
|
+
|
|
161
|
+
**Migration (OtpField):** a composed `InputOTPSlot` that is passed `aria-invalid` must be passed `data-invalid` instead.
|
|
162
|
+
|
|
163
|
+
- [#440](https://github.com/softistx/nxgt-material/pull/440) [`4827b01`](https://github.com/softistx/nxgt-material/commit/4827b015f23623f3e303af042bdc85bc43f8847a) Thanks [@SteveGT96](https://github.com/SteveGT96)! - The required `*` of `Label` (`withAsterisk`, so every `required` field) is now drawn by CSS (a mask in the package stylesheet, still visible in forced-colors mode and in print) instead of typed into the label, so it is in neither the label's text nor its accessible name. `getByLabel('First name', { exact: true })` (Playwright) and `getByLabelText('First name')` (Testing Library) now find a required field; before, the label text was "First name *" even though the asterisk was `aria-hidden`. The name was already "First name" for `getByRole`; screen readers still announce "required" from the field's own `required` / `aria-required`. The `SelectField` trigger is now named by its label (`aria-labelledby`), so `getByRole('combobox', { name: 'Framework' })` finds it.
|
|
164
|
+
|
|
165
|
+
Migration: a test that matched the label text with the asterisk (`getByLabelText('Email*')`, `getByLabel('Email *')`, `{ name: /Email \*/ }`) must drop it; check requiredness with `toBeRequired()` or `toHaveAttribute('aria-required', 'true')`; update DOM/HTML snapshots, which no longer contain the mark. The mark needs the package stylesheet (`label.css` is part of it); without it nothing is drawn. Custom CSS that targeted the asterisk `<span class="text-error">` should target `[data-slot="label-text"][data-required]::after` (colour: `background-color`, size: `width` / `height`).
|
|
166
|
+
|
|
167
|
+
- [#439](https://github.com/softistx/nxgt-material/pull/439) [`b4a3914`](https://github.com/softistx/nxgt-material/commit/b4a3914913673385305f5eec8d5d293f0ab64580) Thanks [@SteveGT96](https://github.com/SteveGT96)! - Toasts are announced by screen readers without double reading: the `Toaster`'s `aria-live="polite"` region (already there) announces every toast, so a `Toast` has no `role` by default. New optional `role` (`'status' | 'alert'`) on `toast()` and `Toast`; `toasts.error` sets `role: 'alert'` as a default a caller's `role` overrides. A `Toast` rendered outside a `Toaster` needs its own live region. In tests, find an error toast with `findByRole('alert')` and the others by their text inside `section[aria-live="polite"]`; the message is the text, not the name (`toHaveTextContent`).
|
|
168
|
+
|
|
169
|
+
- [#443](https://github.com/softistx/nxgt-material/pull/443) [`a92b5f6`](https://github.com/softistx/nxgt-material/commit/a92b5f672fccfab16c7390a2047f239629b02642) Thanks [@SteveGT96](https://github.com/SteveGT96)! - `toast()` itself now treats an `action` as persistent: a toast with an `action` stays until dismissed (`options.duration: Infinity`, WCAG 2.2.1) unless you pass `options.duration`, and shows a close (X) icon button named by the translated `material.toast.buttons.close` ("Close" / "Fermer") beside it, unless you pass your own new optional `dismissLabel` (`''` hides the button). `toasts.success`, `info`, `warning` and `error` no longer replace the `action` you pass with their own "Close" button: `toasts.info({ description: 'A new version is available', action: { label: 'Reload', onClick } })` now shows Reload. Escape closes a toast from inside it, with or without an action, and the X is now drawn in a visible colour on the toast. A toast without an `action` looks and times out as before. In tests, close an action toast with `toasts.dismiss()` or its "Close" button instead of waiting for it to time out.
|
|
170
|
+
|
|
171
|
+
- [#457](https://github.com/softistx/nxgt-material/pull/457) [`78ef976`](https://github.com/softistx/nxgt-material/commit/78ef976d92b4551e7cb8eaf52e254e61c086199f) Thanks [@SteveGT96](https://github.com/SteveGT96)! - `Toaster` is now the library's own component (same name, same props, every prop forwarded to sonner's), with two changes on phones.
|
|
172
|
+
|
|
173
|
+
- **Toasts show at the top on a phone.** Under 600px wide (the width under which sonner lays toasts out across the screen), a `Toaster` with no `position` now shows its toasts at `top-center` instead of across the bottom, where they covered a form's submit button. This is a visible change: to keep the bottom on phones, pass a `position` (`<Toaster position="bottom-right" />`), which applies on every screen. The server and the hydrating client render the desktop default (`bottom-right`), so there is no hydration mismatch; a phone moves the toasts to the top once hydrated.
|
|
174
|
+
- **A tap no longer pauses a toast for good.** A toast pauses while a mouse hovers it (WCAG 2.2.1, unchanged on a desktop); on a phone, the hover the browser emulates after a tap left the toast paused until the next tap elsewhere. That emulated hover is now ignored (`@nxgt/material-core/touch-hover`): the toast pauses while the finger is down and its timer runs again once lifted. One consequence on a touch screen: a tap no longer fans out a stack of two or more toasts; pass `expand` (`<Toaster expand />`) to keep the stack open.
|
|
175
|
+
|
|
176
|
+
Nothing to change in an app that mounts `<Toaster />` from `@nxgt/material/components`. An app that imports `Toaster` straight from `sonner` does not get either fix: search for `import { Toaster } from 'sonner'` and import it from `@nxgt/material/components` instead. `ToasterProps` is exported beside it.
|
|
177
|
+
|
|
178
|
+
### Patch Changes
|
|
179
|
+
|
|
180
|
+
- [#438](https://github.com/softistx/nxgt-material/pull/438) [`2aed8de`](https://github.com/softistx/nxgt-material/commit/2aed8de1561275a74a5fbe8fd055576462746b70) Thanks [@SteveGT96](https://github.com/SteveGT96)! - `DataTable`'s server footer announces its range: "41–60 of 133" is now a polite live region (`role="status"`, `aria-atomic="true"`, named "Rows shown" through the new `material.table.pagination.range-label` key, so it is told apart from the table's own "Loading data…" status: `getByRole('status', { name: 'Rows shown' })`) that is in the DOM from the first render, so a screen reader reads the new range when the page changes. A row with `getRowHref` already exposed one link named by its cell text and no extra role on the row; a story now asserts it.
|
|
181
|
+
|
|
182
|
+
- [#451](https://github.com/softistx/nxgt-material/pull/451) [`5736e94`](https://github.com/softistx/nxgt-material/commit/5736e94cc7dae9433e1956e8a5d2005dd15afbf9) Thanks [@SteveGT96](https://github.com/SteveGT96)! - `DataTable` no longer sets state when no row is expanded for TanStack Table's reset of the expanded rows, which runs in a microtask after `data` changes (a page, a search), so the reset cannot land as an update during another component's render. It also drops a sorting or row-selection update that resolves to the current value instead of calling `onSortingChange` / `onRowSelectionChange` with it. This removes the "Cannot update a component (`DataTable`) while rendering a different component (`CheckboxProvider`)" warning a browser that runs microtasks during React's render could log.
|
|
183
|
+
|
|
184
|
+
Side effect: an update that resolves to the same value no longer calls `onSortingChange` or `onRowSelectionChange`; an app that relied on those calls firing for a no-op update will not see them.
|
|
185
|
+
|
|
186
|
+
- [#452](https://github.com/softistx/nxgt-material/pull/452) [`74745da`](https://github.com/softistx/nxgt-material/commit/74745da45e1dbeddda162b211fab3a62654f8fcc) Thanks [@SteveGT96](https://github.com/SteveGT96)! - A `Dialog`, `AlertDialog` or `Sheet` closed and reopened at once (a `ConfirmationDialog` or `ConfirmDialog` that shows the next step's title as soon as the first is confirmed) no longer leaves its overlay above its content. Radix portals the overlay and the content separately, and the overlay's exit animation (150ms) ends before the content's (200ms, 300ms for a sheet): reopened in between, the new overlay was appended after the content and took every click, so Confirm did nothing. The overlay now stays under its content. A `key` per step, used to work around it, can be removed.
|
|
187
|
+
|
|
188
|
+
Docs: the weekday row of `Calendar`, `DateField` and `DateRangeField` (in the calendar's language, labelled by full weekday, 4.5:1 in both themes), "Several steps, one dialog" on the `ConfirmDialog` page, and two troubleshooting entries ("A `ConfirmationDialog` reopened with new content blocks clicks", "A calendar's weekday row is in English on a French page").
|
|
189
|
+
|
|
190
|
+
- [#456](https://github.com/softistx/nxgt-material/pull/456) [`13eb9a3`](https://github.com/softistx/nxgt-material/commit/13eb9a3deba5e3cd31fbaf030dabadff8832085f) Thanks [@SteveGT96](https://github.com/SteveGT96)! - An Escape pressed while an `AlertDialog`, `Dialog`, `Sheet` or `Drawer` is animating out (a confirmation closed over a `Sheet`, then Escape again at once) now closes the overlay below instead of doing nothing. Radix gives Escape to the highest overlay only, and the closed one stayed the highest until its exit animation ended (200ms for a dialog, 300ms for a sheet, 500ms for a drawer). `AlertDialogContent`, `DialogContent`, `DialogScrollContent`, `SheetContent` and `DrawerContent` now press Escape again for the overlay below once they have left. Your `onEscapeKeyDown` still runs first; preventing the default in it while the overlay closes keeps the key. Docs: the troubleshooting entry "The first Escape after closing a nested dialog does nothing".
|
|
191
|
+
|
|
192
|
+
- [#454](https://github.com/softistx/nxgt-material/pull/454) [`ae64988`](https://github.com/softistx/nxgt-material/commit/ae649889e866ee0476e2da2c54f9f1d618803028) Thanks [@SteveGT96](https://github.com/SteveGT96)! - A field's help or error text now describes its control (`aria-describedby`) in `TextareaField`, `NumberField`, `PercentField`, `InputGroupField`, `PhoneField`, `OtpField`, `RatingField`, `ComboboxField`, `TimezoneField` and `Autocomplete` — and so in their `*FormField` wrappers and `FilesFormField`: a screen reader read "invalid" on the control without saying why. The control also carries `aria-invalid="true"` on an error (`RatingField`'s radio group, `InputGroupField`'s and `OtpField`'s input had none), and none without one. A caller's own `aria-describedby` on `TextareaField`, `InputGroupField` or `OtpField` comes first.
|
|
193
|
+
|
|
194
|
+
- [#462](https://github.com/softistx/nxgt-material/pull/462) [`ab8c55d`](https://github.com/softistx/nxgt-material/commit/ab8c55de88f20e827f45cf9e3ca3ff32147be381) Thanks [@SteveGT96](https://github.com/SteveGT96)! - On a phone, the menu sheet of `ActivityLayout` and `AppHeader` shows no tooltip over its entries and closes on one Escape: before, focus landing on the first entry opened a tooltip whose own layer took the first Escape. An expanded `Sidebar` gives its entries no tooltip (they show their label); a collapsed one keeps them, and an explicit `tooltip` is always shown.
|
|
195
|
+
|
|
196
|
+
- [#435](https://github.com/softistx/nxgt-material/pull/435) [`ddd4971`](https://github.com/softistx/nxgt-material/commit/ddd497104f35e73d0cb20040daf1dead52a3b53f) Thanks [@SteveGT96](https://github.com/SteveGT96)! - `SearchField` and `SearchFormField` no longer lose a pending debounced search when the parent re-renders with a new `onValueChange` function (an inline arrow, for example). The call now reaches the latest `onValueChange` once the `debounceMs` delay ends; changing `debounceMs` or unmounting still cancels it.
|
|
197
|
+
|
|
198
|
+
- [#464](https://github.com/softistx/nxgt-material/pull/464) [`fac20c8`](https://github.com/softistx/nxgt-material/commit/fac20c8a81653219b6658d45f537e3f7b2920bf9) Thanks [@SteveGT96](https://github.com/SteveGT96)! - A toast shown over an open modal `Dialog`, `Sheet`, `Drawer` or `AlertDialog` can be clicked and tapped: its action runs and the dialog stays open. Before, the modal layer's `pointer-events: none` on `<body>` reached the `Toaster`, so its buttons could not be clicked, and a pointer down on a toast counted as outside the dialog. The `Toaster` now sets `pointer-events: auto` (in the stylesheets `styles.css` imports), and the modal contents treat a pointer down or a focus inside the `Toaster` as inside: your `onPointerDownOutside`, `onFocusOutside` and `onInteractOutside` still run, except where the primitive replaces them: a `Drawer`'s `onFocusOutside`, an `AlertDialog`'s pointer-down and interact outside. A non-modal layer (`modal={false}`) also stays open on a click or a focus on a toast, which is intended.
|
|
199
|
+
|
|
200
|
+
- [#450](https://github.com/softistx/nxgt-material/pull/450) [`8e568c3`](https://github.com/softistx/nxgt-material/commit/8e568c3544327c1ba273482963ec13e1930d3be6) Thanks [@SteveGT96](https://github.com/SteveGT96)! - `zodLocaleError` words the length of a string as a length, and starts every format message with a capital. `z.string().min(3)` now says "Must contain at least 3 characters." / "Doit contenir au moins 3 caractères." and `.max(80)` "Must contain at most 80 characters." / "Doit contenir au plus 80 caractères." (exclusive bounds: "fewer than" / "more than", "moins de" / "plus de"), and one character is singular (`.min(1)`: "Must contain at least 1 character." / "Doit contenir au moins 1 caractère."; the new keys take the count as an ICU `plural`) where it said "This value is too small: it must be at least 3 characters." and, in French, "trop grande … caractères". A number, a list, a set or a file keeps the "too large / too small" wording. The French `invalid_format` message for an email was "adresse e-mail invalide." and is "Adresse e-mail invalide." (the noun opens the sentence, so it is capitalized in every language). New keys, in both `en` and `fr`: `material.zod.too_big_string_inclusive` / `_exclusive` and `material.zod.too_small_string_inclusive` / `_exclusive`; an app that overrode `material.zod.too_big_inclusive` (or `too_small_inclusive`) for strings must override these. A test or a snapshot that asserted the old text must be updated.
|
|
201
|
+
- Updated dependencies [[`7200d8c`](https://github.com/softistx/nxgt-material/commit/7200d8c05e8b94de10910ccb3609be3ed1b59061), [`8e568c3`](https://github.com/softistx/nxgt-material/commit/8e568c3544327c1ba273482963ec13e1930d3be6), [`f6cb264`](https://github.com/softistx/nxgt-material/commit/f6cb2649cbdae34201eba18d0ec69846a281deba), [`025bf28`](https://github.com/softistx/nxgt-material/commit/025bf28872d1954596cf7d7054245646309e4525)]:
|
|
202
|
+
- @nxgt/material-core@0.5.0
|
|
203
|
+
|
|
3
204
|
## 2.7.1
|
|
4
205
|
|
|
5
206
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -62,7 +62,7 @@ bun add react react-dom react-hook-form react-redux @reduxjs/toolkit @tanstack/r
|
|
|
62
62
|
| `react-hook-form` `^7` | every `*FormField` |
|
|
63
63
|
| `react-redux` `^9`, `@reduxjs/toolkit` `^2` | `DataTable`, filter, gallery, kanban, player, slice helpers |
|
|
64
64
|
| `@tanstack/react-table` `^9` | `DataTable` |
|
|
65
|
-
| `react-use` `^17` | `useTheme`, `useIsMobile`, `ScrollProgress` (`useScroll` / `useWindowScroll`),
|
|
65
|
+
| `react-use` `^17` | `useTheme`, `useIsMobile`, `ScrollProgress` (`useScroll` / `useWindowScroll`), other hooks |
|
|
66
66
|
|
|
67
67
|
**Optional peers**, installed only by the app that imports the entry needing
|
|
68
68
|
them: `@react-pdf/renderer` `^4.9` and `react-pdf-tailwind` `^3` for
|
|
@@ -94,6 +94,9 @@ required, and nothing warns you when it is missing. Tailwind v4 does not scan
|
|
|
94
94
|
`node_modules`, so without it every utility used *inside* a component is
|
|
95
95
|
missing and the UI renders unstyled.
|
|
96
96
|
|
|
97
|
+
The required-field mark after a `Label` is drawn by this stylesheet too, so
|
|
98
|
+
a page or test rendered without it shows no `*`.
|
|
99
|
+
|
|
97
100
|
Import it **explicitly**, because nothing injects it. Tailwind v4 builds one
|
|
98
101
|
`@theme` from a single CSS graph, and Tailwind CSS IntelliSense reads the
|
|
99
102
|
tokens from this entry file to autocomplete them in your components.
|
|
@@ -243,7 +246,7 @@ Each area a consumer starts from has its own page under `docs/guides/`.
|
|
|
243
246
|
| --- | --- |
|
|
244
247
|
| [Forms](https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/guides/forms.md) | wiring fields to React Hook Form and Zod, composite values (contacts, opening hours), config-driven `Field`, server errors, what each field emits |
|
|
245
248
|
| [i18n](https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/guides/i18n.md) | adding your strings next to the package's, switching language, translated Zod messages, SSR without a text mismatch |
|
|
246
|
-
| [App shell](https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/guides/app-shell.md) | laying out an app with `ActivityLayout`, its `items
|
|
249
|
+
| [App shell](https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/guides/app-shell.md) | laying out an app with `ActivityLayout`, its `items` (rendered as links; `linkComponent` to pass your own), the active entry and breadcrumbs (needs a data router), the `<main>` landmark, the `h1` title and document scrolling |
|
|
247
250
|
| [Theming](https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/guides/theming.md) | changing colours, radius or fonts, dark mode, using the compiled CSS without Tailwind |
|
|
248
251
|
| [Printing](https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/guides/printing.md) | producing PDFs with `@nxgt/material/print` and getting the file in one call (download, new tab, preview, server `Response`) — its own entry since 2.0.0, with optional peers, a bundling trap on SSR servers, and the `next.config.ts` a Next.js route handler (and `output: 'standalone'`) needs |
|
|
249
252
|
| [Maps](https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/guides/maps.md) | using `@nxgt/material/map` — browser-only, optional leaflet peers, `map.css` |
|
|
@@ -287,7 +290,7 @@ React-only today: `Combobox` (not planned in Vue) and `StepperIndicator`.
|
|
|
287
290
|
| <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/previews/primitives-separator.webp" width="120" alt="Separator"> | [`Separator`](https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/components/primitives.md#separator) | Horizontal or vertical divider. | `Separator` |
|
|
288
291
|
| <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/previews/primitives-scrollarea.webp" width="120" alt="ScrollArea"> | [`ScrollArea`](https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/components/primitives.md#scrollarea), `ScrollBar` | Scroll container with a thin custom scrollbar that matches the theme. | `ScrollArea`, `ScrollBar` |
|
|
289
292
|
| <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/previews/primitives-table.webp" width="120" alt="Table"> | [`Table`](https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/components/primitives.md#table), `TableHeader`, `TableBody`, `TableFooter`, `TableRow`, `TableHead`, `TableCell`, `TableCaption`, `TableEmpty` | Styled semantic table inside a scrollable wrapper; `TableEmpty` is the full-width "nothing here" row. | `Table` (same parts) |
|
|
290
|
-
| <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/previews/primitives-tabs.webp" width="120" alt="Tabs"> | [`Tabs`](https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/components/primitives.md#tabs), `TabsList`, `TabsTrigger`, `TabsContent` | Tabs whose triggers can take an icon
|
|
293
|
+
| <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/previews/primitives-tabs.webp" width="120" alt="Tabs"> | [`Tabs`](https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/components/primitives.md#tabs), `TabsList`, `TabsTrigger`, `TabsContent` | Tabs whose triggers can take an icon, in two looks: `underline` (the default) and the `segmented` pill. | `Tabs` (same parts) |
|
|
291
294
|
| <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/previews/primitives-toggle.webp" width="120" alt="Toggle"> | [`Toggle`](https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/components/primitives.md#toggle) | Pressable on / off button: default or outlined, three sizes. | `Toggle` |
|
|
292
295
|
| <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/previews/primitives-togglegroup.webp" width="120" alt="ToggleGroup"> | [`ToggleGroup`](https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/components/primitives.md#togglegroup), `ToggleGroupItem`, `ToggleGroupSeparator` | Single or multiple toggle group sharing variant and size. | `ToggleGroup`, `ToggleGroupItem` |
|
|
293
296
|
| — | [`Activity`](https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/components/primitives.md#activity) | React `<Activity>` switched by a boolean `visible`. | `Activity` |
|
|
@@ -390,7 +393,7 @@ React-only today: `Combobox` (not planned in Vue) and `StepperIndicator`.
|
|
|
390
393
|
| <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/previews/data-display-accordioncard.webp" width="120" alt="AccordionCard"> | [`AccordionCard`](https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/components/data-display.md#accordioncard) | Renders `items` (title, content) as a styled accordion. | `AccordionCard` |
|
|
391
394
|
| <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/previews/data-display-timeline.webp" width="120" alt="Timeline"> | [`Timeline`](https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/components/data-display.md#timeline), `TimelineItem`, `RelativeTime` | Vertical event timeline with toned icons and relative times. | `Timeline`, `TimelineItem`, `RelativeTime` |
|
|
392
395
|
| <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/previews/data-display-eventchip.webp" width="120" alt="EventChip"> | [`EventChip`](https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/components/data-display.md#eventchip) | Calendar event pill with time, all-day and continuation edges. | `EventChip` |
|
|
393
|
-
| <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/previews/data-display-codeblock.webp" width="120" alt="CodeBlock"> | [`CodeBlock`](https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/components/data-display.md#codeblock), `CodeDiff`, `JsonViewer`, `CodeGroup` | Highlighted code with line numbers and copy, a Monaco diff, a collapsible JSON tree, and tabbed samples (`Tabs
|
|
396
|
+
| <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/previews/data-display-codeblock.webp" width="120" alt="CodeBlock"> | [`CodeBlock`](https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/components/data-display.md#codeblock), `CodeDiff`, `JsonViewer`, `CodeGroup` | Highlighted code with line numbers and copy, a Monaco diff, a collapsible JSON tree, and tabbed samples (`Tabs`, underlined). | `CodeBlock`, `CodeDiff`, `JsonViewer`, `CodeGroup` |
|
|
394
397
|
| <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/previews/data-display-markdown.webp" width="120" alt="Markdown"> | [`Markdown`](https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/components/data-display.md#markdown), `MermaidDiagram` | GFM markdown with KaTeX math and mermaid diagrams (`clientOnly`). Fences reuse `CodeBlock`. `ChatMarkdown` renders through it. | `Markdown`, `MermaidDiagram` |
|
|
395
398
|
| <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/previews/data-display-terminal.webp" width="120" alt="Terminal"> | [`Terminal`](https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/components/data-display.md#terminal) | Display-only log with prompt, copy, and error/input tones. Container queries. | `Terminal` |
|
|
396
399
|
| <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/previews/data-display-figure.webp" width="120" alt="Figure"> | [`Figure`](https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/components/data-display.md#figure) | Framed media with an optional caption. | `Figure` |
|
|
@@ -403,7 +406,7 @@ React-only today: `Combobox` (not planned in Vue) and `StepperIndicator`.
|
|
|
403
406
|
|
|
404
407
|
| Preview | Component | What it does | @nxgt/material-vue |
|
|
405
408
|
| --- | --- | --- | --- |
|
|
406
|
-
| <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/previews/data-table-filter-lists-datatable.webp" width="120" alt="DataTable"> | [`DataTable`](https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/components/data-table-filter-and-lists.md#datatable), `DataTableColumnHeader`, `DataTablePagination`, `DataTableServerFooter`, `DataTableViewOptions` | TanStack Table v9 with sorting, filtering, selection, expandable rows, pagination or load-more, column visibility, skeleton rows while loading and your own empty state — or one server page at a time, with controlled sorting and selection, cursor Previous / Next links and row links. | `DataTable`, `DataTableColumnHeader`, `DataTablePagination`, `DataTableServerFooter`, `DataTableViewOptions` |
|
|
409
|
+
| <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/previews/data-table-filter-lists-datatable.webp" width="120" alt="DataTable"> | [`DataTable`](https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/components/data-table-filter-and-lists.md#datatable), `DataTableColumnHeader`, `DataTablePagination`, `DataTableServerFooter`, `DataTableViewOptions` | TanStack Table v9 with sorting, filtering, selection, expandable rows, pagination or load-more, column visibility, skeleton rows while loading and your own empty state — or one server page at a time, with controlled sorting and selection, cursor Previous / Next links and row links. On a phone it keeps its header row and scrolls sideways in a keyboard-reachable region; the page does not. | `DataTable`, `DataTableColumnHeader`, `DataTablePagination`, `DataTableServerFooter`, `DataTableViewOptions` |
|
|
407
410
|
| <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/previews/data-table-filter-lists-filter.webp" width="120" alt="Filter"> | [`Filter`](https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/components/data-table-filter-and-lists.md#filter), `FilterProvider`, `FilterContent`, `FilterChips`, `FilterPresets` · `FilterFormField` | Schema-driven filters with chips, presets, validation, and URL or storage persistence. | `Filter`, `FilterProvider`, `FilterContent`, `FilterChips`, `FilterPresets`, `FilterFormField` |
|
|
408
411
|
| — | [`FilterInline`](https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/components/data-table-filter-and-lists.md#filterinline-filterpopover-filterdialog-filtersheet-filterdrawer), `FilterPopover`, `FilterDialog`, `FilterSheet`, `FilterDrawer` | The filter panel shown inline, or in a popover, dialog, sheet or drawer. | `FilterInline`, `FilterPopover`, `FilterDialog`, `FilterSheet`, `FilterDrawer` |
|
|
409
412
|
| <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/previews/data-table-filter-lists-pagination.webp" width="120" alt="Pagination"> | [`Pagination`](https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/components/data-table-filter-and-lists.md#pagination), `PaginationContent`, `PaginationItem`, `PaginationFirst`, `PaginationLast`, `PaginationLink`, `PaginationBar`, `paginationItems`… | Pagination primitives, with first / last links. `PaginationBar` adds a sibling window with ellipses. | `Pagination` (parts), `PaginationFirst`, `PaginationLast`, `PaginationLink`, `PaginationBar`, `paginationItems` |
|
|
@@ -414,7 +417,7 @@ React-only today: `Combobox` (not planned in Vue) and `StepperIndicator`.
|
|
|
414
417
|
|
|
415
418
|
| Preview | Component | What it does | @nxgt/material-vue |
|
|
416
419
|
| --- | --- | --- | --- |
|
|
417
|
-
| <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/previews/navigation-layout-appshell.webp" width="120" alt="ActivityLayout"> | [`ActivityLayout`](https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/components/navigation-and-layout.md#activitylayout), `ActivityContent`, `AppSidebar`, `AppHeader`, `AppBreadcrumb`, `AppBreadcrumbItem`, `AppBreadcrumbSeparator` | App shell: sidebar built from `items`, a header with a mobile sheet, route breadcrumbs and a titled page. See the [app shell guide](https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/guides/app-shell.md). | `ActivityLayout`, `ActivityContent`, `AppSidebar`, `AppHeader`, `AppBreadcrumb` |
|
|
420
|
+
| <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/previews/navigation-layout-appshell.webp" width="120" alt="ActivityLayout"> | [`ActivityLayout`](https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/components/navigation-and-layout.md#activitylayout), `ActivityContent`, `AppSidebar`, `AppHeader`, `AppBreadcrumb`, `AppBreadcrumbItem`, `AppBreadcrumbSeparator` | App shell: sidebar built from `items`, a header with a mobile sheet, route breadcrumbs and a titled page; entries are real links, and `linkComponent` swaps the link. See the [app shell guide](https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/guides/app-shell.md). | `ActivityLayout`, `ActivityContent`, `AppSidebar`, `AppHeader`, `AppBreadcrumb` |
|
|
418
421
|
| <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/previews/navigation-layout-sidebar.webp" width="120" alt="Sidebar"> | [`Sidebar`](https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/components/navigation-and-layout.md#sidebar), `SidebarHeader`, `SidebarContent`, `SidebarFooter`, `SidebarMenuItem`, `SidebarMenuLabel` | Collapsible navigation sidebar with icons, tooltips and active items. | `Sidebar` (same parts) |
|
|
419
422
|
| <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/previews/navigation-layout-topappbar.webp" width="120" alt="TopAppBar"> | [`TopAppBar`](https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/components/navigation-and-layout.md#topappbar), `BottomAppBar` | Top bar surface, and a bottom bar of icon actions with an active state. | `TopAppBar`, `BottomAppBar` |
|
|
420
423
|
| <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/previews/navigation-layout-breadcrumb.webp" width="120" alt="Breadcrumb"> | [`Breadcrumb`](https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/components/navigation-and-layout.md#breadcrumb), `BreadcrumbList`, `BreadcrumbItem`, `BreadcrumbLink`, `BreadcrumbPage`, `BreadcrumbSeparator`, `BreadcrumbEllipsis` | Breadcrumb primitives. | `Breadcrumb` (same parts) |
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { S as e, T as t, d as n, g as r, l as i, u as a, v as o, w as s, x as c } from "./translator-
|
|
1
|
+
import { S as e, T as t, d as n, g as r, l as i, u as a, v as o, w as s, x as c } from "./translator-BfqVlNGW.js";
|
|
2
2
|
//#region ../../node_modules/lodash-es/_isIndex.js
|
|
3
3
|
var l = 9007199254740991, u = /^(?:0|[1-9]\d*)$/;
|
|
4
4
|
function d(e, t) {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { n as e } from "./src-
|
|
1
|
+
import { n as e } from "./src-CsLQInsN.js";
|
|
2
2
|
import { m as t, t as n } from "./mermaid-parser.core-BXD_TD1T.js";
|
|
3
3
|
import { n as r } from "./chunk-Y2CYZVJY-BAad7w_K.js";
|
|
4
|
-
import "./chunk-O7XYJQB3-
|
|
5
|
-
import "./chunk-6AEJRKK7-
|
|
6
|
-
import { n as i, r as a, t as o } from "./chunk-GTNCS2PH-
|
|
4
|
+
import "./chunk-O7XYJQB3-BChweQ_V.js";
|
|
5
|
+
import "./chunk-6AEJRKK7-BLBlw8ui.js";
|
|
6
|
+
import { n as i, r as a, t as o } from "./chunk-GTNCS2PH-AJi9PVT7.js";
|
|
7
7
|
import { t as s } from "./chunk-JWPE2WC7-BGVSGRTC.js";
|
|
8
8
|
//#region ../../node_modules/mermaid/dist/chunks/mermaid.core/abnfDiagram-O67JEVCF.mjs
|
|
9
9
|
var c = t().RailroadAbnf.parser.LangiumParser, l = /* @__PURE__ */ r((e) => {
|
package/dist/{architectureDiagram-NJMV4G6O-WmFlBQF5.js → architectureDiagram-NJMV4G6O-DOc_c_T9.js}
RENAMED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { n, t as r } from "./src-
|
|
3
|
-
import { c as i, i as a } from "./chunk-ZIGJFQKS-
|
|
1
|
+
import { a as e, t } from "./rolldown-runtime-BFFgcFxR.js";
|
|
2
|
+
import { n, t as r } from "./src-CsLQInsN.js";
|
|
3
|
+
import { c as i, i as a } from "./chunk-ZIGJFQKS-9VXArDKF.js";
|
|
4
4
|
import { n as o } from "./mermaid-parser.core-BXD_TD1T.js";
|
|
5
5
|
import { n as s } from "./chunk-Y2CYZVJY-BAad7w_K.js";
|
|
6
|
-
import { H as c, U as l, Y as u, a as d, b as f, f as p, q as m, v as h, w as g, x as _, y as v, z as y } from "./chunk-O7XYJQB3-
|
|
7
|
-
import { t as b } from "./chunk-6AEJRKK7-
|
|
6
|
+
import { H as c, U as l, Y as u, a as d, b as f, f as p, q as m, v as h, w as g, x as _, y as v, z as y } from "./chunk-O7XYJQB3-BChweQ_V.js";
|
|
7
|
+
import { t as b } from "./chunk-6AEJRKK7-BLBlw8ui.js";
|
|
8
8
|
import { t as x } from "./chunk-JWPE2WC7-BGVSGRTC.js";
|
|
9
|
-
import { i as S, r as C, t as w } from "./chunk-742MDFTN-
|
|
10
|
-
import { n as T } from "./chunk-MBY4JIJT-
|
|
9
|
+
import { i as S, r as C, t as w } from "./chunk-742MDFTN-CsUjFyzK.js";
|
|
10
|
+
import { n as T } from "./chunk-MBY4JIJT-BFIqOe-8.js";
|
|
11
11
|
import { t as E } from "./cytoscape.esm-DXVRLXF3.js";
|
|
12
12
|
//#region ../../node_modules/cytoscape-fcose/node_modules/cose-base/node_modules/layout-base/layout-base.js
|
|
13
13
|
var D = /* @__PURE__ */ t(((e, t) => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as e, S as t, h as n, l as r, m as i, p as a, u as o, v as s, w as c, x as l } from "./translator-
|
|
2
|
-
import { a as u, c as d, d as f, i as p, n as m, r as h, t as g, u as _ } from "./_Uint8Array-
|
|
1
|
+
import { C as e, S as t, h as n, l as r, m as i, p as a, u as o, v as s, w as c, x as l } from "./translator-BfqVlNGW.js";
|
|
2
|
+
import { a as u, c as d, d as f, i as p, n as m, r as h, t as g, u as _ } from "./_Uint8Array-azThpjEP.js";
|
|
3
3
|
import { L as v } from "./number.utils-BiBN2hWJ.js";
|
|
4
4
|
import { Suspense as y, createContext as b, createElement as x, useContext as ee, useEffect as te, useMemo as S, useReducer as ne, useState as re, useSyncExternalStore as ie } from "react";
|
|
5
5
|
import { asyncThunkCreator as ae, buildCreateSlice as oe } from "@reduxjs/toolkit";
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import { t as e } from "./graphlib-
|
|
2
|
-
import { n as t, t as n } from "./src-
|
|
3
|
-
import { A as r, B as i, C as a, D as o, E as s, F as c, G as l, H as u, I as d, L as f, M as p, N as m, O as h, P as g, R as _, T as v, U as ee, V as y, W as b, b as x, j as S, k as C, l as w, v as T, w as E, z as D } from "./chunk-ZIGJFQKS-
|
|
1
|
+
import { t as e } from "./graphlib-DLjE3QPd.js";
|
|
2
|
+
import { n as t, t as n } from "./src-CsLQInsN.js";
|
|
3
|
+
import { A as r, B as i, C as a, D as o, E as s, F as c, G as l, H as u, I as d, L as f, M as p, N as m, O as h, P as g, R as _, T as v, U as ee, V as y, W as b, b as x, j as S, k as C, l as w, v as T, w as E, z as D } from "./chunk-ZIGJFQKS-9VXArDKF.js";
|
|
4
4
|
import { n as O } from "./chunk-Y2CYZVJY-BAad7w_K.js";
|
|
5
|
-
import { a as k, at as A, b as j, c as te, s as ne, x as re } from "./chunk-O7XYJQB3-
|
|
6
|
-
import { t as ie } from "./channel-
|
|
7
|
-
import "./chunk-742MDFTN-
|
|
8
|
-
import "./chunk-MBY4JIJT-
|
|
5
|
+
import { a as k, at as A, b as j, c as te, s as ne, x as re } from "./chunk-O7XYJQB3-BChweQ_V.js";
|
|
6
|
+
import { t as ie } from "./channel-CnLB6790.js";
|
|
7
|
+
import "./chunk-742MDFTN-CsUjFyzK.js";
|
|
8
|
+
import "./chunk-MBY4JIJT-BFIqOe-8.js";
|
|
9
9
|
import { t as ae } from "./chunk-5VM5RSS4-BFskf6Qk.js";
|
|
10
10
|
import { t as oe } from "./chunk-DUW6YSOI-9R-v-IIp.js";
|
|
11
|
-
import "./chunk-7PRAP22T-
|
|
11
|
+
import "./chunk-7PRAP22T-0C6_H8Li.js";
|
|
12
12
|
import { i as se, n as ce, o as le, r as ue, s as de } from "./chunk-J5ZVWO5B-DmRRmhon.js";
|
|
13
|
-
import "./chunk-7INBJB4K-
|
|
14
|
-
import { i as fe, r as pe } from "./chunk-5DYCD2WN-
|
|
15
|
-
import { a as me, c as he, i as ge, l as _e } from "./chunk-Z7XXMR3K-
|
|
13
|
+
import "./chunk-7INBJB4K-k-I67NSP.js";
|
|
14
|
+
import { i as fe, r as pe } from "./chunk-5DYCD2WN-Cd1zazNp.js";
|
|
15
|
+
import { a as me, c as he, i as ge, l as _e } from "./chunk-Z7XXMR3K-C9P-XjM2.js";
|
|
16
16
|
//#region ../../node_modules/es-toolkit/dist/compat/predicate/isArray.mjs
|
|
17
17
|
function ve(e) {
|
|
18
18
|
return Array.isArray(e);
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { n as e, t } from "./src-
|
|
2
|
-
import { _ as n, n as r, r as i } from "./chunk-ZIGJFQKS-
|
|
1
|
+
import { n as e, t } from "./src-CsLQInsN.js";
|
|
2
|
+
import { _ as n, n as r, r as i } from "./chunk-ZIGJFQKS-9VXArDKF.js";
|
|
3
3
|
import { n as a } from "./chunk-Y2CYZVJY-BAad7w_K.js";
|
|
4
|
-
import { H as o, U as s, c as l, r as u, s as d, v as f, x as p, y as m, z as h } from "./chunk-O7XYJQB3-
|
|
5
|
-
import "./chunk-742MDFTN-
|
|
6
|
-
import "./chunk-MBY4JIJT-
|
|
7
|
-
import "./chunk-7PRAP22T-
|
|
8
|
-
import { r as g, s as _ } from "./chunk-7INBJB4K-
|
|
9
|
-
import { a as v } from "./chunk-GWA4HPMP-
|
|
4
|
+
import { H as o, U as s, c as l, r as u, s as d, v as f, x as p, y as m, z as h } from "./chunk-O7XYJQB3-BChweQ_V.js";
|
|
5
|
+
import "./chunk-742MDFTN-CsUjFyzK.js";
|
|
6
|
+
import "./chunk-MBY4JIJT-BFIqOe-8.js";
|
|
7
|
+
import "./chunk-7PRAP22T-0C6_H8Li.js";
|
|
8
|
+
import { r as g, s as _ } from "./chunk-7INBJB4K-k-I67NSP.js";
|
|
9
|
+
import { a as v } from "./chunk-GWA4HPMP-B8jXI0Tl.js";
|
|
10
10
|
//#region ../../node_modules/mermaid/dist/chunks/mermaid.core/c4Diagram-YGBWAQC7.mjs
|
|
11
11
|
var y = (function() {
|
|
12
12
|
var e = /* @__PURE__ */ a(function(e, t, n, r) {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { t as e } from "./graphlib-
|
|
2
|
-
import { n as t } from "./src-
|
|
3
|
-
import { g as n } from "./chunk-ZIGJFQKS-
|
|
1
|
+
import { t as e } from "./graphlib-DLjE3QPd.js";
|
|
2
|
+
import { n as t } from "./src-CsLQInsN.js";
|
|
3
|
+
import { g as n } from "./chunk-ZIGJFQKS-9VXArDKF.js";
|
|
4
4
|
import { n as r } from "./chunk-Y2CYZVJY-BAad7w_K.js";
|
|
5
|
-
import { b as i, x as a } from "./chunk-O7XYJQB3-
|
|
6
|
-
import { o } from "./chunk-7INBJB4K-
|
|
7
|
-
import { i as s, n as c, r as l, t as u } from "./chunk-5DYCD2WN-
|
|
8
|
-
import { a as d, c as f, i as p, n as m, r as h, t as g, u as _ } from "./chunk-Z7XXMR3K-
|
|
9
|
-
import { r as v, t as y } from "./chunk-UA2S7LBM-
|
|
5
|
+
import { b as i, x as a } from "./chunk-O7XYJQB3-BChweQ_V.js";
|
|
6
|
+
import { o } from "./chunk-7INBJB4K-k-I67NSP.js";
|
|
7
|
+
import { i as s, n as c, r as l, t as u } from "./chunk-5DYCD2WN-Cd1zazNp.js";
|
|
8
|
+
import { a as d, c as f, i as p, n as m, r as h, t as g, u as _ } from "./chunk-Z7XXMR3K-C9P-XjM2.js";
|
|
9
|
+
import { r as v, t as y } from "./chunk-UA2S7LBM-ChuksCDg.js";
|
|
10
10
|
//#region ../../node_modules/mermaid/dist/chunks/mermaid.core/chunk-3FUC2YCW.mjs
|
|
11
11
|
function b(e, { edgePathsClass: t = "edges edgePaths" } = {}) {
|
|
12
12
|
let n = e.insert("g").attr("class", "root");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { n as e } from "./src-
|
|
2
|
-
import { u as t } from "./chunk-ZIGJFQKS-
|
|
1
|
+
import { n as e } from "./src-CsLQInsN.js";
|
|
2
|
+
import { u as t } from "./chunk-ZIGJFQKS-9VXArDKF.js";
|
|
3
3
|
import { n } from "./chunk-Y2CYZVJY-BAad7w_K.js";
|
|
4
|
-
import { s as r } from "./chunk-7INBJB4K-
|
|
4
|
+
import { s as r } from "./chunk-7INBJB4K-k-I67NSP.js";
|
|
5
5
|
//#region ../../node_modules/mermaid/dist/chunks/mermaid.core/chunk-5DYCD2WN.mjs
|
|
6
6
|
var i = /* @__PURE__ */ n(({ flowchart: e }) => {
|
|
7
7
|
let t = e?.subGraphTitleMargin?.top ?? 0, n = e?.subGraphTitleMargin?.bottom ?? 0;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { t as e } from "./src-
|
|
1
|
+
import { t as e } from "./src-CsLQInsN.js";
|
|
2
2
|
import { n as t } from "./chunk-Y2CYZVJY-BAad7w_K.js";
|
|
3
|
-
import { x as n } from "./chunk-O7XYJQB3-
|
|
3
|
+
import { x as n } from "./chunk-O7XYJQB3-BChweQ_V.js";
|
|
4
4
|
//#region ../../node_modules/mermaid/dist/chunks/mermaid.core/chunk-6AEJRKK7.mjs
|
|
5
5
|
var r = /* @__PURE__ */ t((t) => {
|
|
6
6
|
let { securityLevel: r } = n(), i = e("body");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { n as e } from "./src-
|
|
1
|
+
import { n as e } from "./src-CsLQInsN.js";
|
|
2
2
|
import { n as t } from "./chunk-Y2CYZVJY-BAad7w_K.js";
|
|
3
|
-
import { b as n, z as r } from "./chunk-O7XYJQB3-
|
|
3
|
+
import { b as n, z as r } from "./chunk-O7XYJQB3-BChweQ_V.js";
|
|
4
4
|
//#region ../../node_modules/@iconify/utils/lib/icon/defaults.js
|
|
5
5
|
var i = Object.freeze({
|
|
6
6
|
left: 0,
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { n as e, t } from "./src-
|
|
2
|
-
import { a as n, p as r, r as i, u as a } from "./chunk-ZIGJFQKS-
|
|
1
|
+
import { n as e, t } from "./src-CsLQInsN.js";
|
|
2
|
+
import { a as n, p as r, r as i, u as a } from "./chunk-ZIGJFQKS-9VXArDKF.js";
|
|
3
3
|
import { n as o } from "./chunk-Y2CYZVJY-BAad7w_K.js";
|
|
4
|
-
import { A as s, B as c, M as l, T as u, b as d, f, g as p, x as m, z as h } from "./chunk-O7XYJQB3-
|
|
5
|
-
import { n as g, t as _ } from "./chunk-742MDFTN-
|
|
6
|
-
import { n as v, r as y } from "./chunk-MBY4JIJT-
|
|
7
|
-
import { a as b, i as x, r as S, t as C } from "./chunk-7PRAP22T-
|
|
4
|
+
import { A as s, B as c, M as l, T as u, b as d, f, g as p, x as m, z as h } from "./chunk-O7XYJQB3-BChweQ_V.js";
|
|
5
|
+
import { n as g, t as _ } from "./chunk-742MDFTN-CsUjFyzK.js";
|
|
6
|
+
import { n as v, r as y } from "./chunk-MBY4JIJT-BFIqOe-8.js";
|
|
7
|
+
import { a as b, i as x, r as S, t as C } from "./chunk-7PRAP22T-0C6_H8Li.js";
|
|
8
8
|
import { s as w } from "./chunk-J5ZVWO5B-DmRRmhon.js";
|
|
9
9
|
import { t as T } from "./rough.esm-Cvc79rxE.js";
|
|
10
10
|
//#region ../../node_modules/mermaid/dist/chunks/mermaid.core/chunk-7INBJB4K.mjs
|