@omnitron-dev/prism 0.3.0 → 0.3.2
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/README.md +216 -2
- package/THIRD-PARTY-NOTICES.txt +26 -0
- package/dist/accessibility/index.js +2 -0
- package/dist/accessibility/index.js.map +1 -1
- package/dist/auth/index.d.ts +4 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +4 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/blocks/auth-block/guards.d.ts +3 -2
- package/dist/blocks/auth-block/guards.d.ts.map +1 -1
- package/dist/blocks/dashboard-block/dashboard-block.d.ts.map +1 -1
- package/dist/blocks/dashboard-block/types.d.ts +4 -2
- package/dist/blocks/dashboard-block/types.d.ts.map +1 -1
- package/dist/blocks/dashboard-block/use-dashboard-block.d.ts +2 -2
- package/dist/blocks/dashboard-block/use-dashboard-block.d.ts.map +1 -1
- package/dist/blocks/data-grid-block/data-grid-block.d.ts.map +1 -1
- package/dist/blocks/data-grid-block/types.d.ts +3 -0
- package/dist/blocks/data-grid-block/types.d.ts.map +1 -1
- package/dist/blocks/index.js +80 -253
- package/dist/blocks/index.js.map +1 -1
- package/dist/chunk-2AB7VGPW.js +447 -0
- package/dist/chunk-2AB7VGPW.js.map +1 -0
- package/dist/{chunk-WFD54GQQ.js → chunk-2E67PQ4T.js} +14 -573
- package/dist/chunk-2E67PQ4T.js.map +1 -0
- package/dist/chunk-2KG2NI73.js +84 -0
- package/dist/chunk-2KG2NI73.js.map +1 -0
- package/dist/chunk-2UYRW6X3.js +44 -0
- package/dist/chunk-2UYRW6X3.js.map +1 -0
- package/dist/chunk-36C5H56C.js +208 -0
- package/dist/chunk-36C5H56C.js.map +1 -0
- package/dist/chunk-36FOXX25.js +73 -0
- package/dist/chunk-36FOXX25.js.map +1 -0
- package/dist/chunk-3VSM7NZG.js +562 -0
- package/dist/chunk-3VSM7NZG.js.map +1 -0
- package/dist/chunk-4B2LTPK2.js +826 -0
- package/dist/chunk-4B2LTPK2.js.map +1 -0
- package/dist/chunk-4HUGZJKU.js +108 -0
- package/dist/chunk-4HUGZJKU.js.map +1 -0
- package/dist/chunk-4Q5L7LDG.js +74 -0
- package/dist/chunk-4Q5L7LDG.js.map +1 -0
- package/dist/{chunk-BRDWQVRT.js → chunk-4R7EZ7GQ.js} +3 -2
- package/dist/chunk-4R7EZ7GQ.js.map +1 -0
- package/dist/chunk-6IANOSMD.js +185 -0
- package/dist/chunk-6IANOSMD.js.map +1 -0
- package/dist/chunk-7ATBURW2.js +206 -0
- package/dist/chunk-7ATBURW2.js.map +1 -0
- package/dist/{chunk-6AHI4GSV.js → chunk-AATAOOSF.js} +4 -3
- package/dist/chunk-AATAOOSF.js.map +1 -0
- package/dist/chunk-AKLRKCYH.js +128 -0
- package/dist/chunk-AKLRKCYH.js.map +1 -0
- package/dist/chunk-CT46KJOR.js +133 -0
- package/dist/chunk-CT46KJOR.js.map +1 -0
- package/dist/{chunk-YQW43BDH.js → chunk-D4GFAJAZ.js} +1168 -6354
- package/dist/chunk-D4GFAJAZ.js.map +1 -0
- package/dist/chunk-D5J3KW6Q.js +106 -0
- package/dist/chunk-D5J3KW6Q.js.map +1 -0
- package/dist/chunk-DEPJRTVT.js +3 -0
- package/dist/{chunk-FU52GL2E.js.map → chunk-DEPJRTVT.js.map} +1 -1
- package/dist/{chunk-S6SEGBX6.js → chunk-DHTYHUYI.js} +85 -107
- package/dist/chunk-DHTYHUYI.js.map +1 -0
- package/dist/chunk-E7WM2RXA.js +249 -0
- package/dist/chunk-E7WM2RXA.js.map +1 -0
- package/dist/chunk-F6RZ7LW6.js +1271 -0
- package/dist/chunk-F6RZ7LW6.js.map +1 -0
- package/dist/chunk-FOGY3HA4.js +217 -0
- package/dist/chunk-FOGY3HA4.js.map +1 -0
- package/dist/chunk-G2GANYMW.js +139 -0
- package/dist/chunk-G2GANYMW.js.map +1 -0
- package/dist/chunk-I6DILPFE.js +293 -0
- package/dist/chunk-I6DILPFE.js.map +1 -0
- package/dist/chunk-IRYU3NTG.js +573 -0
- package/dist/chunk-IRYU3NTG.js.map +1 -0
- package/dist/chunk-JTIUGPW5.js +284 -0
- package/dist/chunk-JTIUGPW5.js.map +1 -0
- package/dist/{chunk-GUFHFEPZ.js → chunk-JZBSPDED.js} +2 -2
- package/dist/{chunk-GUFHFEPZ.js.map → chunk-JZBSPDED.js.map} +1 -1
- package/dist/chunk-KPY7TA4D.js +191 -0
- package/dist/chunk-KPY7TA4D.js.map +1 -0
- package/dist/{chunk-OBJ244BO.js → chunk-LFWKGNCX.js} +50 -656
- package/dist/chunk-LFWKGNCX.js.map +1 -0
- package/dist/chunk-LH4ZZZYB.js +37 -0
- package/dist/chunk-LH4ZZZYB.js.map +1 -0
- package/dist/chunk-NFJ7CPG3.js +13 -0
- package/dist/chunk-NFJ7CPG3.js.map +1 -0
- package/dist/chunk-NFPOIHD4.js +3 -0
- package/dist/{chunk-AYYFMTMI.js.map → chunk-NFPOIHD4.js.map} +1 -1
- package/dist/{chunk-XIXSSI3B.js → chunk-NJM5AVBM.js} +3 -2
- package/dist/chunk-NJM5AVBM.js.map +1 -0
- package/dist/{chunk-Z5OSPAOC.js → chunk-NSNM53WI.js} +196 -175
- package/dist/chunk-NSNM53WI.js.map +1 -0
- package/dist/chunk-NTREGTG7.js +31 -0
- package/dist/chunk-NTREGTG7.js.map +1 -0
- package/dist/{chunk-ADG4HZEP.js → chunk-OKJA6SJM.js} +4 -4
- package/dist/chunk-OKJA6SJM.js.map +1 -0
- package/dist/chunk-Q6JDNFSG.js +303 -0
- package/dist/chunk-Q6JDNFSG.js.map +1 -0
- package/dist/chunk-RPOGINR5.js +115 -0
- package/dist/chunk-RPOGINR5.js.map +1 -0
- package/dist/{chunk-ZTATTUH7.js → chunk-RSWVYIXK.js} +282 -683
- package/dist/chunk-RSWVYIXK.js.map +1 -0
- package/dist/chunk-SSEHL5VP.js +110 -0
- package/dist/chunk-SSEHL5VP.js.map +1 -0
- package/dist/chunk-TEIGUOWN.js +523 -0
- package/dist/chunk-TEIGUOWN.js.map +1 -0
- package/dist/{chunk-AYYFMTMI.js → chunk-TJ7DHXUX.js} +2 -2
- package/dist/chunk-TJ7DHXUX.js.map +1 -0
- package/dist/chunk-TZHWYT34.js +590 -0
- package/dist/chunk-TZHWYT34.js.map +1 -0
- package/dist/chunk-TZWHELY4.js +45 -0
- package/dist/chunk-TZWHELY4.js.map +1 -0
- package/dist/{chunk-BZOL7GMU.js → chunk-UEINJFLS.js} +7 -7
- package/dist/chunk-UEINJFLS.js.map +1 -0
- package/dist/chunk-URFQX3I6.js +129 -0
- package/dist/chunk-URFQX3I6.js.map +1 -0
- package/dist/chunk-VG6FOMOH.js +187 -0
- package/dist/chunk-VG6FOMOH.js.map +1 -0
- package/dist/chunk-VQVVHMPG.js +106 -0
- package/dist/chunk-VQVVHMPG.js.map +1 -0
- package/dist/{chunk-DRFNMZLG.js → chunk-VUKOT432.js} +3 -2
- package/dist/chunk-VUKOT432.js.map +1 -0
- package/dist/chunk-WD4N72DL.js +315 -0
- package/dist/chunk-WD4N72DL.js.map +1 -0
- package/dist/chunk-XBYMG4QK.js +119 -0
- package/dist/chunk-XBYMG4QK.js.map +1 -0
- package/dist/chunk-YHM6GIHV.js +3 -0
- package/dist/chunk-YHM6GIHV.js.map +1 -0
- package/dist/{chunk-SNZK5X6F.js → chunk-Z2AN43YU.js} +4 -2
- package/dist/chunk-Z2AN43YU.js.map +1 -0
- package/dist/chunk-ZNWHMQRM.js +171 -0
- package/dist/chunk-ZNWHMQRM.js.map +1 -0
- package/dist/{chunk-YSIG2XYH.js → chunk-ZRJYQN6Y.js} +2 -2
- package/dist/{chunk-YSIG2XYH.js.map → chunk-ZRJYQN6Y.js.map} +1 -1
- package/dist/{chunk-AD4W7HYC.js → chunk-ZYI3MHLE.js} +3 -2
- package/dist/chunk-ZYI3MHLE.js.map +1 -0
- package/dist/cli/index.js +66 -423
- package/dist/cli/index.js.map +1 -1
- package/dist/components/accordion/accordion.d.ts.map +1 -1
- package/dist/components/admin-filters/admin-data-table.d.ts +7 -1
- package/dist/components/admin-filters/admin-data-table.d.ts.map +1 -1
- package/dist/components/admin-filters/filter-toolbar.d.ts.map +1 -1
- package/dist/components/admin-filters/index.js +8 -0
- package/dist/components/admin-filters/index.js.map +1 -0
- package/dist/components/alert/alert.d.ts.map +1 -1
- package/dist/components/alert/index.js +5 -0
- package/dist/components/alert/index.js.map +1 -0
- package/dist/components/animate/index.js +5 -0
- package/dist/components/animate/index.js.map +1 -0
- package/dist/components/breadcrumbs/breadcrumbs.d.ts.map +1 -1
- package/dist/components/breadcrumbs/index.js +4 -0
- package/dist/components/breadcrumbs/index.js.map +1 -0
- package/dist/components/card/index.js +4 -0
- package/dist/components/card/index.js.map +1 -0
- package/dist/components/chart/chart.d.ts.map +1 -1
- package/dist/components/chart/index.css +52 -0
- package/dist/components/chart/index.css.map +1 -0
- package/dist/components/chart/index.js +5 -0
- package/dist/components/chart/index.js.map +1 -0
- package/dist/components/chart/types.d.ts +3 -1
- package/dist/components/chart/types.d.ts.map +1 -1
- package/dist/components/chart/use-chart.d.ts.map +1 -1
- package/dist/components/command-palette/command-palette.d.ts +3 -1
- package/dist/components/command-palette/command-palette.d.ts.map +1 -1
- package/dist/components/command-palette/index.js +4 -0
- package/dist/components/command-palette/index.js.map +1 -0
- package/dist/components/confirm-dialog/index.js +4 -0
- package/dist/components/confirm-dialog/index.js.map +1 -0
- package/dist/components/date-input/date-input.d.ts +28 -0
- package/dist/components/date-input/date-input.d.ts.map +1 -0
- package/dist/components/date-input/index.d.ts +3 -0
- package/dist/components/date-input/index.d.ts.map +1 -0
- package/dist/components/date-input/value.d.ts +9 -0
- package/dist/components/date-input/value.d.ts.map +1 -0
- package/dist/components/doc-layout/doc-sidebar.d.ts +4 -1
- package/dist/components/doc-layout/doc-sidebar.d.ts.map +1 -1
- package/dist/components/doc-layout/index.js +7 -0
- package/dist/components/doc-layout/index.js.map +1 -0
- package/dist/components/editor/editor.d.ts.map +1 -1
- package/dist/components/editor/icons/index.d.ts +32 -40
- package/dist/components/editor/icons/index.d.ts.map +1 -1
- package/dist/components/editor/index.js +4 -1
- package/dist/components/editor/index.js.map +1 -1
- package/dist/components/emoji-picker/index.js +2 -1
- package/dist/components/emoji-picker/index.js.map +1 -1
- package/dist/components/empty-content/empty-content.d.ts.map +1 -1
- package/dist/components/empty-content/index.js +4 -0
- package/dist/components/empty-content/index.js.map +1 -0
- package/dist/components/error-boundary/error-boundary.d.ts.map +1 -1
- package/dist/components/error-boundary/index.js +6 -0
- package/dist/components/error-boundary/index.js.map +1 -0
- package/dist/components/index.css +17 -10
- package/dist/components/index.css.map +1 -1
- package/dist/components/index.d.ts +5 -4
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +47 -11
- package/dist/components/index.js.map +1 -1
- package/dist/components/knowledge-graph/edge-labels.d.ts +14 -0
- package/dist/components/knowledge-graph/edge-labels.d.ts.map +1 -0
- package/dist/components/knowledge-graph/graph.d.ts +56 -0
- package/dist/components/knowledge-graph/graph.d.ts.map +1 -0
- package/dist/components/knowledge-graph/index.css +176 -0
- package/dist/components/knowledge-graph/index.css.map +1 -0
- package/dist/components/knowledge-graph/index.d.ts +3 -0
- package/dist/components/knowledge-graph/index.d.ts.map +1 -0
- package/dist/components/knowledge-graph/index.js +797 -0
- package/dist/components/knowledge-graph/index.js.map +1 -0
- package/dist/components/knowledge-graph/label-layout.d.ts +28 -0
- package/dist/components/knowledge-graph/label-layout.d.ts.map +1 -0
- package/dist/components/knowledge-graph/label-store.d.ts +15 -0
- package/dist/components/knowledge-graph/label-store.d.ts.map +1 -0
- package/dist/components/knowledge-graph/model.d.ts +92 -0
- package/dist/components/knowledge-graph/model.d.ts.map +1 -0
- package/dist/components/label/index.js +5 -0
- package/dist/components/label/index.js.map +1 -0
- package/dist/components/label/label.d.ts.map +1 -1
- package/dist/components/lightbox/lightbox.d.ts.map +1 -1
- package/dist/components/loading-screen/index.js +4 -0
- package/dist/components/loading-screen/index.js.map +1 -0
- package/dist/components/map/Map.d.ts +19 -43
- package/dist/components/map/Map.d.ts.map +1 -1
- package/dist/components/map/MapCoverageLayer.d.ts +1 -1
- package/dist/components/map/MapCoverageLayer.d.ts.map +1 -1
- package/dist/components/map/MapMarker.d.ts +1 -1
- package/dist/components/map/MapMarker.d.ts.map +1 -1
- package/dist/components/map/MapPlaceSearch.d.ts +33 -0
- package/dist/components/map/MapPlaceSearch.d.ts.map +1 -0
- package/dist/components/map/MapPointPicker.d.ts +21 -12
- package/dist/components/map/MapPointPicker.d.ts.map +1 -1
- package/dist/components/map/coordinates.d.ts +10 -0
- package/dist/components/map/coordinates.d.ts.map +1 -0
- package/dist/components/map/index.css +4 -0
- package/dist/components/map/index.css.map +1 -0
- package/dist/components/map/index.d.ts +7 -2
- package/dist/components/map/index.d.ts.map +1 -1
- package/dist/components/map/index.js +4 -0
- package/dist/components/map/index.js.map +1 -0
- package/dist/components/nav-card/nav-card.d.ts.map +1 -1
- package/dist/components/navigation-progress/index.js +4 -0
- package/dist/components/navigation-progress/index.js.map +1 -0
- package/dist/components/page-content/index.js +4 -0
- package/dist/components/page-content/index.js.map +1 -0
- package/dist/components/popover/index.js +4 -0
- package/dist/components/popover/index.js.map +1 -0
- package/dist/components/rail/rail.d.ts.map +1 -1
- package/dist/components/research/diagram-image.d.ts +11 -0
- package/dist/components/research/diagram-image.d.ts.map +1 -0
- package/dist/components/research/diagram.d.ts +8 -0
- package/dist/components/research/diagram.d.ts.map +1 -0
- package/dist/components/research/document.d.ts +33 -0
- package/dist/components/research/document.d.ts.map +1 -0
- package/dist/components/research/frontmatter.d.ts +15 -0
- package/dist/components/research/frontmatter.d.ts.map +1 -0
- package/dist/components/research/index.css +51 -0
- package/dist/components/research/index.css.map +1 -0
- package/dist/components/research/index.d.ts +3 -0
- package/dist/components/research/index.d.ts.map +1 -0
- package/dist/components/research/index.js +8 -0
- package/dist/components/research/index.js.map +1 -0
- package/dist/components/research/parse.d.ts +29 -0
- package/dist/components/research/parse.d.ts.map +1 -0
- package/dist/components/research-editor/block-commands.d.ts +20 -0
- package/dist/components/research-editor/block-commands.d.ts.map +1 -0
- package/dist/components/research-editor/block-controls.d.ts +13 -0
- package/dist/components/research-editor/block-controls.d.ts.map +1 -0
- package/dist/components/research-editor/editor.d.ts +75 -0
- package/dist/components/research-editor/editor.d.ts.map +1 -0
- package/dist/components/research-editor/extensions.d.ts +14 -0
- package/dist/components/research-editor/extensions.d.ts.map +1 -0
- package/dist/components/research-editor/index.css +332 -0
- package/dist/components/research-editor/index.css.map +1 -0
- package/dist/components/research-editor/index.d.ts +5 -0
- package/dist/components/research-editor/index.d.ts.map +1 -0
- package/dist/components/research-editor/index.js +1593 -0
- package/dist/components/research-editor/index.js.map +1 -0
- package/dist/components/research-editor/math-input.d.ts +32 -0
- package/dist/components/research-editor/math-input.d.ts.map +1 -0
- package/dist/components/research-editor/math-markup.d.ts +4 -0
- package/dist/components/research-editor/math-markup.d.ts.map +1 -0
- package/dist/components/research-editor/math-navigation.d.ts +6 -0
- package/dist/components/research-editor/math-navigation.d.ts.map +1 -0
- package/dist/components/research-editor/math-node.d.ts +11 -0
- package/dist/components/research-editor/math-node.d.ts.map +1 -0
- package/dist/components/research-editor/source.d.ts +19 -0
- package/dist/components/research-editor/source.d.ts.map +1 -0
- package/dist/components/scroll-to-top/index.js +4 -0
- package/dist/components/scroll-to-top/index.js.map +1 -0
- package/dist/components/scrollbar/scrollbar.d.ts +4 -2
- package/dist/components/scrollbar/scrollbar.d.ts.map +1 -1
- package/dist/components/search-input/index.js +7 -0
- package/dist/components/search-input/index.js.map +1 -0
- package/dist/components/search-input/search-input.d.ts +3 -11
- package/dist/components/search-input/search-input.d.ts.map +1 -1
- package/dist/components/skeleton/index.js +4 -0
- package/dist/components/skeleton/index.js.map +1 -0
- package/dist/components/snackbar/index.js +6 -0
- package/dist/components/snackbar/index.js.map +1 -0
- package/dist/components/stepper/index.js +4 -0
- package/dist/components/stepper/index.js.map +1 -0
- package/dist/components/table/index.d.ts +1 -0
- package/dist/components/table/index.d.ts.map +1 -1
- package/dist/components/table/index.js +5 -0
- package/dist/components/table/index.js.map +1 -0
- package/dist/components/table/table-viewport.d.ts +13 -0
- package/dist/components/table/table-viewport.d.ts.map +1 -0
- package/dist/components/table/table.d.ts +3 -1
- package/dist/components/table/table.d.ts.map +1 -1
- package/dist/components/tabs/index.js +6 -0
- package/dist/components/tabs/index.js.map +1 -0
- package/dist/components/tabs/tabs.d.ts +12 -1
- package/dist/components/tabs/tabs.d.ts.map +1 -1
- package/dist/components/tiptap-renderer/tiptap-renderer.d.ts +4 -3
- package/dist/components/tiptap-renderer/tiptap-renderer.d.ts.map +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +12 -6
- package/dist/core/index.js.map +1 -1
- package/dist/core/provider.d.ts +7 -2
- package/dist/core/provider.d.ts.map +1 -1
- package/dist/forms/index.js +2 -0
- package/dist/forms/index.js.map +1 -1
- package/dist/forms/schema-provider.d.ts +3 -3
- package/dist/forms/schema-utils.d.ts +3 -3
- package/dist/hooks/index.js +14 -8
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/use-config-from-query.d.ts +2 -0
- package/dist/hooks/use-config-from-query.d.ts.map +1 -1
- package/dist/hooks/use-image-dimensions.d.ts.map +1 -1
- package/dist/hooks/use-keyboard-shortcut.d.ts.map +1 -1
- package/dist/hooks/use-scroll-position.d.ts.map +1 -1
- package/dist/hooks/use-window-size.d.ts.map +1 -1
- package/dist/icons/context.d.ts +17 -0
- package/dist/icons/context.d.ts.map +1 -0
- package/dist/icons/controls.d.ts +51 -0
- package/dist/icons/controls.d.ts.map +1 -0
- package/dist/icons/index.d.ts +3 -0
- package/dist/icons/index.d.ts.map +1 -0
- package/dist/icons/index.js +5 -0
- package/dist/icons/index.js.map +1 -0
- package/dist/icons/theme.d.ts +4 -0
- package/dist/icons/theme.d.ts.map +1 -0
- package/dist/index.css +17 -10
- package/dist/index.css.map +1 -1
- package/dist/index.js +57 -20
- package/dist/index.js.map +1 -1
- package/dist/internal/research-parser.js +3 -0
- package/dist/internal/research-parser.js.map +1 -0
- package/dist/layouts/core/header-section.d.ts +1 -0
- package/dist/layouts/core/header-section.d.ts.map +1 -1
- package/dist/layouts/dashboard/labels.d.ts +12 -0
- package/dist/layouts/dashboard/labels.d.ts.map +1 -0
- package/dist/layouts/dashboard/layout.d.ts +9 -1
- package/dist/layouts/dashboard/layout.d.ts.map +1 -1
- package/dist/layouts/dashboard/sidenav.d.ts +7 -3
- package/dist/layouts/dashboard/sidenav.d.ts.map +1 -1
- package/dist/layouts/index.d.ts +5 -0
- package/dist/layouts/index.d.ts.map +1 -1
- package/dist/layouts/index.js +9 -3
- package/dist/layouts/index.js.map +1 -1
- package/dist/layouts/panel-layout.d.ts +35 -0
- package/dist/layouts/panel-layout.d.ts.map +1 -0
- package/dist/layouts/sidebar-toggle.d.ts +11 -0
- package/dist/layouts/sidebar-toggle.d.ts.map +1 -0
- package/dist/netron/index.js +2 -1
- package/dist/netron/index.js.map +1 -1
- package/dist/registry/index.js +1 -1
- package/dist/state/create-store.d.ts.map +1 -1
- package/dist/state/index.js +3 -2
- package/dist/state/index.js.map +1 -1
- package/dist/state/settings-version.d.ts.map +1 -1
- package/dist/state/stores/auth.d.ts +4 -16
- package/dist/state/stores/auth.d.ts.map +1 -1
- package/dist/state/stores/ui.d.ts +7 -105
- package/dist/state/stores/ui.d.ts.map +1 -1
- package/dist/theme/components/Button.d.ts.map +1 -1
- package/dist/theme/components/Chip.d.ts.map +1 -1
- package/dist/theme/components/Dialog.d.ts.map +1 -1
- package/dist/theme/components/FormControls.d.ts +3 -12
- package/dist/theme/components/FormControls.d.ts.map +1 -1
- package/dist/theme/components/TextField.d.ts.map +1 -1
- package/dist/theme/components/index.d.ts.map +1 -1
- package/dist/theme/components/theme-utils.d.ts +2 -2
- package/dist/theme/components/theme-utils.d.ts.map +1 -1
- package/dist/theme/create-theme.d.ts +5 -17
- package/dist/theme/create-theme.d.ts.map +1 -1
- package/dist/theme/index.js +8 -2
- package/dist/theme/index.js.map +1 -1
- package/dist/theme/mixins.d.ts +3 -1
- package/dist/theme/mixins.d.ts.map +1 -1
- package/dist/theme/palette/overrides.d.ts +24 -0
- package/dist/theme/palette/overrides.d.ts.map +1 -0
- package/dist/theme/semantic-surface.d.ts +8 -0
- package/dist/theme/semantic-surface.d.ts.map +1 -0
- package/dist/types/index.js +2 -2
- package/dist/ui/index.d.ts +18 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +149 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/utils/async-lock.d.ts.map +1 -1
- package/package.json +200 -47
- package/dist/chunk-6AHI4GSV.js.map +0 -1
- package/dist/chunk-AD4W7HYC.js.map +0 -1
- package/dist/chunk-ADG4HZEP.js.map +0 -1
- package/dist/chunk-BRDWQVRT.js.map +0 -1
- package/dist/chunk-BZOL7GMU.js.map +0 -1
- package/dist/chunk-DRFNMZLG.js.map +0 -1
- package/dist/chunk-FU52GL2E.js +0 -3
- package/dist/chunk-OBJ244BO.js.map +0 -1
- package/dist/chunk-S6SEGBX6.js.map +0 -1
- package/dist/chunk-SNZK5X6F.js.map +0 -1
- package/dist/chunk-WFD54GQQ.js.map +0 -1
- package/dist/chunk-XIXSSI3B.js.map +0 -1
- package/dist/chunk-YQW43BDH.js.map +0 -1
- package/dist/chunk-Z5OSPAOC.js.map +0 -1
- package/dist/chunk-ZTATTUH7.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/date-range-picker/date-range-picker.tsx","../src/components/date-range-picker/date-range-input.tsx","../src/components/admin-filters/filter-toolbar.tsx","../src/components/admin-filters/admin-data-table.tsx","../src/components/admin-filters/status-chip.tsx","../src/utils/format-crypto.ts","../src/components/admin-filters/amount-cell.tsx"],"names":["jsxs","jsx","useCallback","Fragment","TextField","useState","useMemo","Typography","Box","Button","alpha","Stack","Chip"],"mappings":"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","file":"chunk-F6RZ7LW6.js","sourcesContent":["'use client';\n\n/**\n * DateRangePicker — Dialog-based date range selector.\n *\n * Responsive: shows calendar view on desktop, input fields on mobile.\n * Based on @mui/x-date-pickers DatePicker and DateCalendar.\n */\n\nimport type { DialogProps } from '@mui/material/Dialog';\nimport type { PaperProps } from '@mui/material/Paper';\nimport type { UseDateRangePickerReturn } from './use-date-range-picker.js';\n\nimport { useCallback } from 'react';\n\nimport Button from '@mui/material/Button';\nimport Dialog from '@mui/material/Dialog';\nimport DialogTitle from '@mui/material/DialogTitle';\nimport DialogActions from '@mui/material/DialogActions';\nimport DialogContent from '@mui/material/DialogContent';\nimport useMediaQuery from '@mui/material/useMediaQuery';\nimport FormHelperText from '@mui/material/FormHelperText';\nimport { DatePicker } from '@mui/x-date-pickers/DatePicker';\nimport { DateCalendar, dateCalendarClasses } from '@mui/x-date-pickers/DateCalendar';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * Translatable strings rendered inside the picker dialog.\n *\n * Prism components stay framework-agnostic: we don't depend on\n * react-i18next here. Consumers pass already-translated strings via\n * this prop. Every key is optional so callers can override only the\n * ones they need; missing keys fall back to English.\n */\nexport interface DateRangePickerTranslations {\n /** Dialog title — \"Select date range\" */\n title?: string;\n /** Start-date input label (mobile/input variant) — \"Start date\" */\n startDate?: string;\n /** End-date input label (mobile/input variant) — \"End date\" */\n endDate?: string;\n /** Helper text when end < start — \"End date cannot be earlier than start date\" */\n errorRange?: string;\n /** Cancel button — \"Cancel\" */\n cancel?: string;\n /** Apply button — \"Apply\" */\n apply?: string;\n}\n\nexport type DateRangePickerProps = DialogProps &\n UseDateRangePickerReturn & {\n onSubmit?: () => void;\n variant?: 'calendar' | 'input';\n /** @deprecated Use `translations.title` instead. */\n title?: string;\n translations?: DateRangePickerTranslations;\n };\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport function DateRangePicker({\n open,\n error,\n onClose,\n onSubmit,\n startDate,\n endDate,\n onChangeStartDate,\n onChangeEndDate,\n slotProps,\n variant = 'input',\n title,\n translations,\n // Exclude hook props that shouldn't go to Dialog\n selected: _selected,\n label: _label,\n shortLabel: _shortLabel,\n onOpen: _onOpen,\n onReset: _onReset,\n setStartDate: _setStartDate,\n setEndDate: _setEndDate,\n ...other\n}: DateRangePickerProps) {\n // Precedence: explicit translations > legacy `title` prop > English default.\n const txTitle = translations?.title ?? title ?? 'Select date range';\n const txStart = translations?.startDate ?? 'Start date';\n const txEnd = translations?.endDate ?? 'End date';\n // \"Later than\" overstates the rule: the guard is `isAfter`, so an equal\n // pair is a valid one-day range and the label formats it as a single date.\n const txErrorRange = translations?.errorRange ?? 'End date cannot be earlier than start date';\n const txCancel = translations?.cancel ?? 'Cancel';\n const txApply = translations?.apply ?? 'Apply';\n const mdUp = useMediaQuery((theme: any) => theme.breakpoints.up('md'));\n const isCalendarView = mdUp && variant === 'calendar';\n\n const handleSubmit = useCallback(() => {\n onClose({}, 'backdropClick');\n onSubmit?.();\n }, [onClose, onSubmit]);\n\n const handleClose = useCallback(() => {\n onClose({}, 'backdropClick');\n }, [onClose]);\n\n const dialogPaperSx = (slotProps?.paper as PaperProps)?.sx;\n\n return (\n <Dialog\n fullWidth\n open={open}\n onClose={onClose}\n maxWidth={isCalendarView ? false : 'xs'}\n slotProps={{\n ...slotProps,\n paper: {\n ...slotProps?.paper,\n sx: [\n { ...(isCalendarView && { maxWidth: 720 }) },\n ...(Array.isArray(dialogPaperSx) ? dialogPaperSx : dialogPaperSx ? [dialogPaperSx] : []),\n ],\n },\n }}\n {...other}\n >\n <DialogTitle>{txTitle}</DialogTitle>\n\n <DialogContent\n sx={[\n (theme) => ({\n gap: 3,\n display: 'flex',\n overflow: 'unset',\n flexDirection: isCalendarView ? 'row' : 'column',\n [`& .${dateCalendarClasses.root}`]: {\n borderRadius: 2,\n border: `dashed 1px ${theme.palette.divider}`,\n },\n }),\n ]}\n >\n {isCalendarView ? (\n <>\n <DateCalendar value={startDate} onChange={onChangeStartDate} />\n <DateCalendar value={endDate} onChange={onChangeEndDate} />\n </>\n ) : (\n <>\n <DatePicker label={txStart} value={startDate} onChange={onChangeStartDate} />\n <DatePicker label={txEnd} value={endDate} onChange={onChangeEndDate} />\n </>\n )}\n\n {error && (\n <FormHelperText error sx={{ px: 2 }}>\n {txErrorRange}\n </FormHelperText>\n )}\n </DialogContent>\n\n <DialogActions>\n <Button variant=\"outlined\" color=\"inherit\" onClick={handleClose}>\n {txCancel}\n </Button>\n <Button disabled={error} variant=\"contained\" onClick={handleSubmit}>\n {txApply}\n </Button>\n </DialogActions>\n </Dialog>\n );\n}\n","'use client';\n\n/**\n * DateRangeInput — Compact inline date range selector for filter toolbars.\n *\n * Renders as a clickable TextField that opens a DateRangePicker dialog.\n * Shows the selected range as a short label or placeholder.\n */\n\nimport type { DateRangeValue } from './use-date-range-picker.js';\nimport type { DateRangePickerTranslations } from './date-range-picker.js';\n\nimport { useState, useCallback, useMemo } from 'react';\nimport dayjs from 'dayjs';\n\nimport TextField from '@mui/material/TextField';\nimport InputAdornment from '@mui/material/InputAdornment';\nimport IconButton from '@mui/material/IconButton';\nimport { DateRangePicker } from './date-range-picker.js';\n\n// ---------------------------------------------------------------------------\n// Icons (inline to avoid external deps)\n// ---------------------------------------------------------------------------\n\nfunction CalendarIcon() {\n return (\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <rect x=\"3\" y=\"4\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\" />\n <line x1=\"16\" y1=\"2\" x2=\"16\" y2=\"6\" />\n <line x1=\"8\" y1=\"2\" x2=\"8\" y2=\"6\" />\n <line x1=\"3\" y1=\"10\" x2=\"21\" y2=\"10\" />\n </svg>\n );\n}\n\nfunction ClearIcon() {\n return (\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * Translatable strings rendered around the input field.\n *\n * Stays prop-driven so prism doesn't pull in a translation library.\n * Pass already-translated strings; missing keys fall back to English.\n *\n * For the picker dialog's own strings (Cancel, Apply, etc.) see\n * `DateRangePickerTranslations` — those can be passed via\n * `pickerTranslations` and are threaded through to the dialog.\n */\nexport interface DateRangeInputTranslations {\n /** Placeholder shown when both ends are empty — \"Select dates...\" */\n placeholder?: string;\n /** Prefix for partial range with only start — \"From\" → \"From 12 Jan 2026\" */\n from?: string;\n /** Prefix for partial range with only end — \"To\" → \"To 31 Dec 2026\" */\n to?: string;\n /**\n * Accessible name for the clear button — \"Clear date range\".\n *\n * The button is an icon with no text, so this string IS its name to a\n * screen reader. Without one the control announces as \"button\".\n */\n clear?: string;\n}\n\nexport interface DateRangeInputProps {\n /** Label displayed on the field */\n label?: string;\n /** Start date as ISO string (YYYY-MM-DD) */\n startDate: string;\n /** End date as ISO string (YYYY-MM-DD) */\n endDate: string;\n /** Called when dates change */\n onChange: (startDate: string, endDate: string) => void;\n /** Minimum width */\n width?: number | string;\n /** Picker variant */\n variant?: 'calendar' | 'input';\n /** Size of the field */\n size?: 'small' | 'medium';\n /** Translations for the input field surface (placeholder, \"From\"/\"To\") */\n translations?: DateRangeInputTranslations;\n /** Translations forwarded into the embedded picker dialog */\n pickerTranslations?: DateRangePickerTranslations;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction toDayjs(value: string): DateRangeValue {\n if (!value) return null;\n const d = dayjs(value);\n return d.isValid() ? d : null;\n}\n\nfunction toIso(value: DateRangeValue): string {\n if (!value || !value.isValid()) return '';\n return value.format('YYYY-MM-DD');\n}\n\nfunction formatLabel(\n start: string,\n end: string,\n fromPrefix: string,\n toPrefix: string,\n): string {\n if (!start && !end) return '';\n const s = toDayjs(start);\n const e = toDayjs(end);\n if (s && e) {\n if (s.isSame(e, 'day')) return e.format('DD MMM YYYY');\n if (s.isSame(e, 'month')) return `${s.format('DD')} – ${e.format('DD MMM YYYY')}`;\n if (s.isSame(e, 'year')) return `${s.format('DD MMM')} – ${e.format('DD MMM YYYY')}`;\n return `${s.format('DD MMM YYYY')} – ${e.format('DD MMM YYYY')}`;\n }\n if (s) return `${fromPrefix} ${s.format('DD MMM YYYY')}`;\n if (e) return `${toPrefix} ${e.format('DD MMM YYYY')}`;\n return '';\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport function DateRangeInput({\n label = 'Date range',\n startDate,\n endDate,\n onChange,\n width = 220,\n variant = 'input',\n size = 'small',\n translations,\n pickerTranslations,\n}: DateRangeInputProps) {\n const [open, setOpen] = useState(false);\n const [tempStart, setTempStart] = useState<DateRangeValue>(toDayjs(startDate));\n const [tempEnd, setTempEnd] = useState<DateRangeValue>(toDayjs(endDate));\n\n const txPlaceholder = translations?.placeholder ?? 'Select dates...';\n const txFrom = translations?.from ?? 'From';\n const txTo = translations?.to ?? 'To';\n const txClear = translations?.clear ?? 'Clear date range';\n\n const displayLabel = useMemo(\n () => formatLabel(startDate, endDate, txFrom, txTo),\n [startDate, endDate, txFrom, txTo],\n );\n const hasValue = !!startDate || !!endDate;\n\n const handleOpen = useCallback(() => {\n setTempStart(toDayjs(startDate));\n setTempEnd(toDayjs(endDate));\n setOpen(true);\n }, [startDate, endDate]);\n\n const handleClose = useCallback(() => {\n setOpen(false);\n }, []);\n\n const handleSubmit = useCallback(() => {\n onChange(toIso(tempStart), toIso(tempEnd));\n setOpen(false);\n }, [tempStart, tempEnd, onChange]);\n\n const handleClear = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation();\n onChange('', '');\n },\n [onChange]\n );\n\n const error = !!(tempStart && tempEnd && tempStart.isAfter(tempEnd));\n\n return (\n <>\n <TextField\n size={size}\n label={label}\n value={displayLabel}\n placeholder={txPlaceholder}\n onClick={handleOpen}\n slotProps={{\n input: {\n readOnly: true,\n sx: { cursor: 'pointer' },\n startAdornment: (\n <InputAdornment position=\"start\" sx={{ color: 'text.disabled' }}>\n <CalendarIcon />\n </InputAdornment>\n ),\n ...(hasValue && {\n endAdornment: (\n <InputAdornment position=\"end\">\n <IconButton size=\"small\" onClick={handleClear} aria-label={txClear} sx={{ p: 0.25 }}>\n <ClearIcon />\n </IconButton>\n </InputAdornment>\n ),\n }),\n },\n inputLabel: { shrink: true },\n }}\n sx={{\n minWidth: width,\n '& .MuiOutlinedInput-root': { borderRadius: 1 },\n '& .MuiInputBase-input': { cursor: 'pointer' },\n }}\n />\n\n <DateRangePicker\n open={open}\n error={error}\n onClose={handleClose}\n onSubmit={handleSubmit}\n startDate={tempStart}\n endDate={tempEnd}\n onChangeStartDate={setTempStart}\n onChangeEndDate={setTempEnd}\n variant={variant}\n translations={pickerTranslations}\n selected={!!(tempStart && tempEnd)}\n label=\"\"\n shortLabel=\"\"\n onOpen={handleOpen}\n onReset={() => {\n setTempStart(null);\n setTempEnd(null);\n }}\n setStartDate={setTempStart}\n setEndDate={setTempEnd}\n />\n </>\n );\n}\n","'use client';\n\nimport { FilterIcon } from '../../icons/controls.js';\n\n/**\n * Filter Toolbar Component\n *\n * Declarative filter toolbar for admin sections. Renders filters based on\n * a configuration array, supporting search, select, multi-select, date ranges,\n * boolean toggles, and number ranges.\n *\n * @module components/admin-filters\n */\n\nimport type { ReactNode, ChangeEvent } from 'react';\nimport { useState, useCallback, useMemo, useRef, useEffect, useTransition } from 'react';\nimport Stack from '@mui/material/Stack';\nimport TextField from '@mui/material/TextField';\nimport Chip from '@mui/material/Chip';\nimport MenuItem from '@mui/material/MenuItem';\nimport Box from '@mui/material/Box';\nimport Button from '@mui/material/Button';\nimport Typography from '@mui/material/Typography';\nimport Badge from '@mui/material/Badge';\nimport { alpha } from '@mui/material/styles';\nimport type { SxProps, Theme } from '@mui/material/styles';\n\nimport { DateRangeInput } from '../date-range-picker/date-range-input.js';\nimport { SearchInput } from '../search-input/search-input.js';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type FilterType = 'search' | 'select' | 'multi-select' | 'date-range' | 'boolean' | 'number-range';\n\nexport interface FilterOption {\n value: string;\n label: string;\n color?: string;\n}\n\nexport interface FilterConfig {\n /** Unique key used as the property name in FilterValues */\n key: string;\n /** Type of filter to render */\n type: FilterType;\n /** Display label */\n label: string;\n /** Placeholder text */\n placeholder?: string;\n /** Options for select / multi-select filters */\n options?: FilterOption[];\n /** Width of the filter control */\n width?: number | string;\n /** Default value */\n defaultValue?: unknown;\n}\n\nexport interface FilterValues {\n [key: string]: unknown;\n search?: string;\n dateFrom?: string;\n dateTo?: string;\n}\n\nexport interface FilterToolbarProps {\n /** Filter configurations */\n filters: FilterConfig[];\n /** Current filter values */\n values: FilterValues;\n /** Called when any filter value changes */\n onChange: (values: FilterValues) => void;\n /** Called when the reset button is clicked */\n onReset?: () => void;\n /** Total count to display */\n total?: number;\n /** Debounce delay for search input in ms */\n searchDebounce?: number;\n /** Compact mode (single row) */\n compact?: boolean;\n /** Additional styles */\n sx?: SxProps<Theme>;\n /**\n * Localized label for the Reset button. Defaults to \"Reset\" so\n * existing call sites still work; pass `t('common.reset')` from\n * the host app to translate.\n */\n resetLabel?: string;\n /**\n * Formatter for the \"N results\" counter below the toolbar.\n * Defaults to English pluralisation. Pass a function from the host\n * app's i18n to get plural-aware translation, e.g.\n * (n) => t('common.resultsCount', { count: n })\n * Receives the already-formatted number string for direct use.\n */\n resultsLabel?: (count: number) => string;\n}\n\n// =============================================================================\n// SEARCH ICON (inline SVG to avoid external dependency)\n// =============================================================================\n\n// =============================================================================\n// HELPERS\n// =============================================================================\n\nfunction useDebounce(value: string, delay: number): string {\n const [debouncedValue, setDebouncedValue] = useState(value);\n\n useEffect(() => {\n const timer = setTimeout(() => setDebouncedValue(value), delay);\n return () => clearTimeout(timer);\n }, [value, delay]);\n\n return debouncedValue;\n}\n\nfunction isFilterActive(config: FilterConfig, values: FilterValues): boolean {\n if (config.type === 'date-range') return !!(values[`${config.key}From`] || values[`${config.key}To`]);\n if (config.type === 'number-range') {\n return ['Min', 'Max'].some((suffix) => {\n const end = values[`${config.key}${suffix}`];\n return end !== undefined && end !== null && end !== '';\n });\n }\n const value = values[config.key];\n if (value === undefined || value === null || value === '') return false;\n if (Array.isArray(value) && value.length === 0) return false;\n if (config.type === 'boolean' && value === false) return false;\n if (config.type === 'select' && value === '') return false;\n return true;\n}\n\n// =============================================================================\n// COMPONENT\n// =============================================================================\n\n/**\n * FilterToolbar - Declarative filter toolbar for admin sections.\n *\n * Renders a row of filter controls based on a configuration array.\n * Supports search (debounced), select, multi-select, date-range,\n * boolean, and number-range filters.\n *\n * @example\n * ```tsx\n * const filters: FilterConfig[] = [\n * { key: 'search', type: 'search', label: 'Search', placeholder: 'Search users...' },\n * { key: 'status', type: 'select', label: 'Status', options: [\n * { value: 'active', label: 'Active' },\n * { value: 'blocked', label: 'Blocked' },\n * ]},\n * { key: 'verified', type: 'boolean', label: 'Verified' },\n * ];\n *\n * <FilterToolbar\n * filters={filters}\n * values={filterValues}\n * onChange={setFilterValues}\n * total={245}\n * />\n * ```\n */\nexport function FilterToolbar({\n filters,\n values,\n onChange,\n onReset,\n total,\n searchDebounce = 300,\n compact = false,\n sx,\n resetLabel = 'Reset',\n resultsLabel,\n}: FilterToolbarProps): ReactNode {\n const [, startTransition] = useTransition();\n\n // Track local search text so the input feels responsive (debounce only propagates)\n const searchFilter = filters.find((f) => f.type === 'search');\n const [localSearch, setLocalSearch] = useState<string>((values[searchFilter?.key ?? 'search'] as string) ?? '');\n const debouncedSearch = useDebounce(localSearch, searchDebounce);\n const prevDebouncedRef = useRef(debouncedSearch);\n\n // Propagate debounced search to parent\n useEffect(() => {\n if (debouncedSearch !== prevDebouncedRef.current) {\n prevDebouncedRef.current = debouncedSearch;\n const key = searchFilter?.key ?? 'search';\n startTransition(() => {\n onChange({ ...values, [key]: debouncedSearch });\n });\n }\n }, [debouncedSearch, searchFilter?.key, onChange, values]);\n\n // Adopt an EXTERNAL change to the search value.\n //\n // The text box holds its own state so typing stays responsive, seeded from\n // `values` once at mount. Nothing re-seeded it, so a reset performed by the\n // parent — switching tabs, clearing filters programmatically, restoring a\n // saved view — left the box showing a term that was no longer filtering\n // anything. The operator reads a search that isn't applied.\n //\n // Only external changes are adopted: `prevDebouncedRef` holds the last\n // value this toolbar itself sent up, so a value echoed back from the parent\n // mid-typing does not overwrite what is being typed.\n const searchValue = (values[searchFilter?.key ?? 'search'] as string | undefined) ?? '';\n useEffect(() => {\n if (searchValue === prevDebouncedRef.current) return;\n prevDebouncedRef.current = searchValue;\n setLocalSearch(searchValue);\n }, [searchValue]);\n\n // Count active filters (excluding search)\n const activeCount = useMemo(\n () => filters.filter((f) => f.type !== 'search' && isFilterActive(f, values)).length,\n [filters, values]\n );\n\n const hasAnyActive = useMemo(\n () => filters.some((f) => isFilterActive(f, f.type === 'search' ? { [f.key]: localSearch } : values)),\n [filters, values, localSearch]\n );\n\n // Handlers\n const handleChange = useCallback(\n (key: string, value: unknown) => {\n startTransition(() => {\n onChange({ ...values, [key]: value });\n });\n },\n [onChange, values]\n );\n\n const handleReset = useCallback(() => {\n setLocalSearch('');\n if (onReset) {\n onReset();\n } else {\n const resetValues: FilterValues = {};\n for (const f of filters) {\n if (f.type === 'search') resetValues[f.key] = '';\n else if (f.type === 'multi-select') resetValues[f.key] = [];\n else if (f.type === 'boolean') resetValues[f.key] = false;\n else if (f.type === 'date-range') {\n resetValues[`${f.key}From`] = '';\n resetValues[`${f.key}To`] = '';\n } else if (f.type === 'number-range') {\n resetValues[`${f.key}Min`] = '';\n resetValues[`${f.key}Max`] = '';\n } else {\n resetValues[f.key] = '';\n }\n }\n onChange(resetValues);\n }\n }, [onReset, onChange, filters]);\n\n // Render individual filter\n const renderFilter = useCallback(\n (config: FilterConfig): ReactNode => {\n const { key, type, label, placeholder, options } = config;\n\n switch (type) {\n case 'search':\n return (\n <SearchInput\n key={key}\n value={localSearch}\n onChange={setLocalSearch}\n placeholder={placeholder ?? 'Search...'}\n aria-label={label}\n fullWidth\n />\n );\n\n case 'select':\n return (\n <TextField\n key={key}\n select\n size=\"small\"\n value={(values[key] as string) ?? ''}\n onChange={(e: ChangeEvent<HTMLInputElement>) => handleChange(key, e.target.value)}\n // The visible \"label\" is rendered as the empty-value MenuItem so\n // the control reads as a placeholder — deliberate, and it leaves\n // the field with NO accessible name. A screen-reader user hears\n // \"combo box\" with no indication of what it filters. Name it\n // explicitly rather than adding a visual label the design does\n // not want.\n slotProps={{ select: { displayEmpty: true, 'aria-label': label } }}\n sx={{\n minWidth: 0,\n width: '100%',\n '& .MuiOutlinedInput-root': { borderRadius: 1 },\n }}\n >\n <MenuItem value=\"\">\n <Typography\n variant=\"body2\"\n sx={{\n color: 'text.secondary',\n }}\n >\n {label}\n </Typography>\n </MenuItem>\n {options?.map((opt) => (\n <MenuItem key={opt.value} value={opt.value}>\n {opt.label}\n </MenuItem>\n ))}\n </TextField>\n );\n\n case 'multi-select': {\n const selectedValues = (values[key] as string[] | undefined) ?? [];\n return (\n <TextField\n key={key}\n select\n size=\"small\"\n value={selectedValues}\n onChange={(e: any) => handleChange(key, e.target.value)}\n slotProps={{\n select: {\n multiple: true,\n displayEmpty: true,\n // Same reason as the single select above: the label lives in\n // `renderValue` as placeholder text, leaving the control\n // without an accessible name.\n 'aria-label': label,\n renderValue: (selected: unknown) => {\n const sel = selected as string[];\n if (sel.length === 0) {\n return (\n <Typography\n variant=\"body2\"\n sx={{\n color: 'text.secondary',\n }}\n >\n {label}\n </Typography>\n );\n }\n return (\n <Stack direction=\"row\" spacing={0.5} sx={{ overflow: 'hidden' }}>\n {sel.map((val) => {\n const opt = options?.find((o) => o.value === val);\n return (\n <Chip\n key={val}\n label={opt?.label ?? val}\n size=\"small\"\n sx={{ height: 20, fontSize: '0.75rem' }}\n />\n );\n })}\n </Stack>\n );\n },\n },\n }}\n sx={{\n minWidth: 0,\n width: '100%',\n '& .MuiOutlinedInput-root': { borderRadius: 1 },\n }}\n >\n {options?.map((opt) => (\n <MenuItem key={opt.value} value={opt.value}>\n {opt.label}\n </MenuItem>\n ))}\n </TextField>\n );\n }\n\n case 'date-range':\n return (\n <DateRangeInput\n key={key}\n label={label}\n startDate={(values[`${key}From`] as string) ?? ''}\n endDate={(values[`${key}To`] as string) ?? ''}\n onChange={(from, to) => {\n startTransition(() => onChange({ ...values, [`${key}From`]: from, [`${key}To`]: to }));\n }}\n width=\"100%\"\n size=\"small\"\n />\n );\n\n case 'boolean':\n return (\n <Chip\n key={key}\n label={label}\n variant={values[key] ? 'filled' : 'outlined'}\n color={values[key] ? 'primary' : 'default'}\n onClick={() => handleChange(key, !values[key])}\n size=\"small\"\n sx={{\n borderRadius: 1,\n fontWeight: 500,\n height: 32,\n cursor: 'pointer',\n transition: (theme) =>\n theme.transitions.create(['background-color', 'color', 'border-color'], {\n duration: theme.transitions.duration.shorter,\n }),\n }}\n />\n );\n\n case 'number-range':\n return (\n <Stack\n key={key}\n direction=\"row\"\n spacing={1}\n sx={{\n alignItems: 'center',\n }}\n >\n <TextField\n type=\"number\"\n size=\"small\"\n label={`${label} min`}\n value={(values[`${key}Min`] as string) ?? ''}\n onChange={(e: ChangeEvent<HTMLInputElement>) => handleChange(`${key}Min`, e.target.value)}\n sx={{ flex: 1, minWidth: 0 }}\n />\n <Typography\n variant=\"body2\"\n sx={{\n color: 'text.disabled',\n px: 0.5,\n }}\n >\n —\n </Typography>\n <TextField\n type=\"number\"\n size=\"small\"\n label={`${label} max`}\n value={(values[`${key}Max`] as string) ?? ''}\n onChange={(e: ChangeEvent<HTMLInputElement>) => handleChange(`${key}Max`, e.target.value)}\n sx={{ flex: 1, minWidth: 0 }}\n />\n </Stack>\n );\n\n default:\n return null;\n }\n },\n [localSearch, values, handleChange, onChange]\n );\n\n return (\n <Stack\n spacing={compact ? 0 : 1.5}\n sx={{\n p: 1.5,\n minWidth: 0,\n borderRadius: 1,\n border: (theme) => `1px solid ${theme.palette.divider}`,\n bgcolor: (theme) => alpha(theme.palette.background.default, 0.5),\n ...sx,\n }}\n >\n {/* Filter controls row */}\n <Stack\n direction=\"row\"\n sx={{\n alignItems: 'center',\n flexWrap: 'wrap',\n gap: 1.5,\n }}\n >\n {filters.map((filter) => (\n <Box\n key={filter.key}\n sx={{\n flex: filter.type === 'search' ? '1 1 220px' : '0 1 auto',\n width: filter.width ?? (filter.type === 'number-range' ? 260 : filter.type === 'boolean' ? 'auto' : 180),\n minWidth: 0,\n maxWidth: '100%',\n '& > .MuiFormControl-root': { width: '100%', minWidth: 0 },\n }}\n >\n {renderFilter(filter)}\n </Box>\n ))}\n\n {/* Active filter count + reset */}\n <Stack\n direction=\"row\"\n spacing={1}\n sx={{\n alignItems: 'center',\n ml: 'auto',\n }}\n >\n {activeCount > 0 && (\n <Badge badgeContent={activeCount} color=\"primary\" sx={{ '& .MuiBadge-badge': { fontSize: '0.65rem' } }}>\n <Box sx={{ color: 'text.secondary', display: 'flex', alignItems: 'center' }}>\n <FilterIcon />\n </Box>\n </Badge>\n )}\n\n {hasAnyActive && (\n <Button\n size=\"small\"\n onClick={handleReset}\n sx={{\n minWidth: 0,\n px: 1.5,\n fontSize: '0.75rem',\n fontWeight: 500,\n color: 'text.secondary',\n '&:hover': { color: 'text.primary' },\n }}\n >\n {resetLabel}\n </Button>\n )}\n </Stack>\n </Stack>\n {/* Results count */}\n {total !== undefined && !compact && (\n <Typography\n variant=\"caption\"\n sx={{\n color: 'text.disabled',\n mt: 0.5,\n }}\n >\n {resultsLabel ? resultsLabel(total) : `${total.toLocaleString()} result${total !== 1 ? 's' : ''}`}\n </Typography>\n )}\n </Stack>\n );\n}\n","'use client';\n\nimport { EmptyIcon } from '../../icons/controls.js';\n\n/**\n * Admin Data Table Component\n *\n * Optimized table for admin data displays with built-in sorting,\n * skeleton loading, empty states, and pagination.\n *\n * @module components/admin-filters\n */\n\nimport { Fragment } from 'react';\nimport type { ReactNode } from 'react';\nimport { useCallback, useMemo } from 'react';\nimport MuiTable from '@mui/material/Table';\nimport TableBody from '@mui/material/TableBody';\nimport TableCell from '@mui/material/TableCell';\nimport { isRowActionTarget, TableViewport } from '../table/table-viewport.js';\nimport TableHead from '@mui/material/TableHead';\nimport TableRow from '@mui/material/TableRow';\nimport TableSortLabel from '@mui/material/TableSortLabel';\nimport TablePagination from '@mui/material/TablePagination';\nimport Paper from '@mui/material/Paper';\nimport Box from '@mui/material/Box';\nimport Stack from '@mui/material/Stack';\nimport Checkbox from '@mui/material/Checkbox';\nimport Typography from '@mui/material/Typography';\nimport Skeleton from '@mui/material/Skeleton';\nimport { styled, alpha } from '@mui/material/styles';\nimport type { SxProps, Theme } from '@mui/material/styles';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport interface ColumnDef<T> {\n /** Unique column identifier */\n key: string;\n /** Column header label */\n header: string;\n /** Column width */\n width?: number | string;\n /** Minimum readable column width before horizontal scrolling. */\n minWidth?: number;\n /** Whether column is sortable */\n sortable?: boolean;\n /** Cell alignment */\n align?: 'left' | 'center' | 'right';\n /** Custom cell renderer */\n render: (row: T, index: number) => ReactNode;\n}\n\nexport interface AdminDataTableProps<T> {\n /** Column definitions */\n columns: ColumnDef<T>[];\n /** Data rows */\n data: T[];\n /** Total number of rows (for pagination) */\n total: number;\n /** Loading state */\n loading?: boolean;\n /**\n * Placeholder rows drawn while `loading`, capped by `pageSize`.\n * Defaults to 5 — see the note where they are built.\n */\n loadingRows?: number;\n /** Current page (0-indexed) */\n page: number;\n /** Rows per page */\n pageSize: number;\n /** Page change handler */\n onPageChange: (page: number) => void;\n /** Page size change handler */\n onPageSizeChange?: (size: number) => void;\n /** Current sort column key */\n sortBy?: string;\n /** Current sort direction */\n sortOrder?: 'asc' | 'desc';\n /** Sort change handler */\n onSort?: (column: string) => void;\n /** Message shown when no data */\n emptyMessage?: string;\n /**\n * Why the table has no rows, when the reason is a failure rather than an\n * absence.\n *\n * \"No data found\" and \"we could not load this\" look identical without it,\n * and the first reads as a healthy answer. That confusion is not\n * hypothetical: the omnitron console's traces page had both of its queries\n * failing against the database schema, had never returned a row, and\n * displayed \"No traces collected yet\" — a plausible answer that was not the\n * true one, for as long as the page had existed.\n *\n * When there are no rows, the empty state says the data could not be\n * loaded and shows this text as the reason, instead of `emptyMessage`.\n *\n * When there ARE rows it is a partial failure — some of the data arrived\n * and some did not — and a bar above the table says so. That case was\n * originally ignored, on the reasoning that rows on screen are their own\n * answer. They are not: a list that is short because one of its sources\n * failed looks exactly like a list that is short, which is the whole\n * defect this prop exists to remove, surviving in the case where it does\n * the most damage.\n */\n loadError?: string | null;\n /**\n * What to CALL a failed read, in the reader's language.\n *\n * `loadError` itself is a reason the caller has already translated; these\n * two are the sentences around it, and they were English literals in this\n * file. That was invisible while one consumer passed `loadError` at all —\n * and the moment four more did, four Russian screens grew an English\n * heading. Same contract as `emptyMessage` and `paginationLabels`: the\n * component states the situation, the host names it. Omitted, the English\n * defaults apply.\n */\n loadErrorLabels?: {\n /** Heading when the list is empty AND the read failed. */\n empty?: string;\n /** Heading when some rows arrived and the read still failed. */\n partial?: string;\n };\n /** Extract unique key from row */\n rowKey?: (row: T) => string;\n /** Row click handler */\n onRowClick?: (row: T) => void;\n /**\n * Per-row styling, for state a single column cannot carry.\n *\n * A disabled rule, a superseded release, a row the reader should still be\n * able to read but not act on: the signal belongs to the whole row, and\n * painting it cell by cell makes one row look like six unrelated ones.\n * Returned styles are merged over the row's own (cursor, hover, selected).\n */\n rowSx?: (row: T, index: number) => SxProps<Theme>;\n /**\n * Detail rendered in a full-width row directly under `row`, when it returns\n * something. Return `null`/`undefined` for a row that is not expanded.\n *\n * Expansion state belongs to the caller — which row is open is usually tied\n * to a URL, a keyboard handler, or a single-open-at-a-time rule this\n * component has no opinion about. Without this, a table that expands a row\n * had to be built by hand, and omnitron's console has two that still are:\n * pipeline run history and the trace list.\n */\n renderExpanded?: (row: T, index: number) => ReactNode;\n /** Page size options for the selector */\n pageSizeOptions?: number[];\n /** Sticky header */\n stickyHeader?: boolean;\n /** Dense mode (less padding) */\n dense?: boolean;\n /** Minimum table width before horizontal scrolling. */\n minWidth?: number | string;\n /** Accessible name of the scrollable table region. */\n scrollLabel?: string;\n /** Container max height */\n maxHeight?: number | string;\n /**\n * Localised labels for the underlying MUI TablePagination. When\n * omitted, the MUI defaults (English) apply — consumers that\n * need a translated UI pass the strings from their i18n layer.\n */\n paginationLabels?: {\n /** \"Rows per page:\" label next to the page-size selector */\n rowsPerPage?: string;\n /** Renderer for the \"1–10 of 42\" line. Same signature as MUI's labelDisplayedRows. */\n displayedRows?: (info: { from: number; to: number; count: number; page: number }) => React.ReactNode;\n };\n /** Additional styles */\n sx?: SxProps<Theme>;\n /**\n * Multi-select mode — adds a leading checkbox column and a header\n * checkbox that toggles all rows on the current page. Selection\n * state is controlled: pass `selectedKeys` and `onSelectionChange`.\n */\n selectable?: boolean;\n /** Currently-selected row keys (matched against `rowKey(row)`). */\n selectedKeys?: ReadonlySet<string>;\n /** Selection change handler. The new set is rebuilt every change. */\n onSelectionChange?: (keys: Set<string>) => void;\n /**\n * Render slot displayed above the table whenever `selectedKeys` is\n * non-empty — typically a row of bulk-action buttons. Receives the\n * current selection so callers can wire actions without re-tracking\n * state externally.\n */\n bulkActions?: (selected: ReadonlySet<string>) => ReactNode;\n}\n\n// =============================================================================\n// STYLED COMPONENTS\n// =============================================================================\n\nconst StyledTableContainer = styled(Paper)(({ theme }) => ({\n borderRadius: theme.shape.borderRadius,\n border: `1px solid ${theme.palette.divider}`,\n overflow: 'hidden',\n minWidth: 0,\n maxWidth: '100%',\n}));\n\nconst StyledTableHead = styled(TableHead)(({ theme }) => ({\n backgroundColor: alpha(theme.palette.grey[500], 0.08),\n '& .MuiTableCell-head': {\n fontWeight: 600,\n fontSize: theme.typography.pxToRem(13),\n color: theme.palette.text.secondary,\n backgroundColor: theme.vars?.palette.background.paper ?? theme.palette.background.paper,\n whiteSpace: 'nowrap',\n borderBottom: `1px solid ${theme.palette.divider}`,\n },\n}));\n\nconst StyledTableRow = styled(TableRow)(({ theme }) => ({\n transition: theme.transitions.create('background-color', {\n duration: theme.transitions.duration.shortest,\n }),\n // `:nth-child(even)` for zebra-striping — table rows are homogeneous\n // siblings, so child-position is equivalent to of-type but doesn't\n // assume the rendered tag never changes (e.g. a row replaced by a\n // skeleton placeholder still alternates correctly).\n '&:nth-child(even)': {\n backgroundColor: alpha(theme.palette.grey[500], 0.02),\n },\n '&:hover': {\n backgroundColor: alpha(theme.palette.primary.main, 0.04),\n },\n '& .MuiTableCell-body': {\n borderBottom: `1px solid ${alpha(theme.palette.divider, 0.6)}`,\n },\n}));\n\n// Single shared empty Set so default `selection` doesn't churn references\n// when `selectedKeys` is omitted.\nconst EMPTY_SELECTION: ReadonlySet<string> = new Set<string>();\n\n// =============================================================================\n// EMPTY STATE ICON\n// =============================================================================\n\n// =============================================================================\n// COMPONENT\n// =============================================================================\n\n/**\n * AdminDataTable - Data table optimized for admin sections.\n *\n * Features skeleton loading rows, sortable column headers, empty states,\n * alternating row colors, sticky header support, and compact pagination.\n *\n * @example\n * ```tsx\n * const columns: ColumnDef<Transaction>[] = [\n * { key: 'id', header: 'ID', width: 80, render: (row) => row.id },\n * { key: 'amount', header: 'Amount', align: 'right', sortable: true,\n * render: (row) => <AmountCell amount={row.amount} currency=\"BTC\" /> },\n * { key: 'status', header: 'Status', render: (row) => <StatusChip status={row.status} /> },\n * ];\n *\n * <AdminDataTable\n * columns={columns}\n * data={transactions}\n * total={1200}\n * page={0}\n * pageSize={25}\n * onPageChange={setPage}\n * loading={isLoading}\n * sortBy=\"amount\"\n * sortOrder=\"desc\"\n * onSort={handleSort}\n * />\n * ```\n */\nexport function AdminDataTable<T>({\n columns,\n data,\n total,\n loading = false,\n loadingRows = 5,\n page,\n pageSize,\n onPageChange,\n onPageSizeChange,\n sortBy,\n sortOrder = 'asc',\n onSort,\n emptyMessage = 'No data found',\n loadError = null,\n loadErrorLabels,\n rowKey,\n onRowClick,\n rowSx,\n renderExpanded,\n pageSizeOptions = [10, 25, 50, 100],\n stickyHeader = false,\n dense = false,\n maxHeight,\n minWidth,\n scrollLabel,\n paginationLabels,\n sx,\n selectable = false,\n selectedKeys,\n onSelectionChange,\n bulkActions,\n}: AdminDataTableProps<T>): ReactNode {\n const getRowKey = useCallback(\n (row: T, index: number): string => {\n if (rowKey) return rowKey(row);\n const record = row as Record<string, unknown>;\n if (record['id'] !== undefined) return String(record['id']);\n\n // Falling back to the index is fine for React reconciliation, but it is\n // NOT an identity: sort or paginate and position N is a different\n // record. With `selectable` that turns a selection into \"rows 2 and 5\n // of whatever is currently on screen\", and a bulk action then applies\n // to records the operator never picked. Surface it in development\n // rather than let a delete find out at runtime.\n if (selectable && process.env['NODE_ENV'] !== 'production') {\n console.error(\n '[AdminDataTable] `selectable` is on but rows have no stable key: ' +\n 'pass `rowKey`, or give each row an `id`. Index-based keys make the ' +\n 'selection positional, so sorting or paging silently re-targets it.'\n );\n }\n return String(index);\n },\n [rowKey, selectable]\n );\n\n // Stable empty set so callers can omit `selectedKeys` without us\n // creating a fresh Set every render (which would defeat memoisation\n // downstream).\n const selection = selectedKeys ?? EMPTY_SELECTION;\n\n const pageRowKeys = useMemo(\n () => (selectable ? data.map((row, index) => getRowKey(row, index)) : []),\n [selectable, data, getRowKey]\n );\n\n const allPageSelected = pageRowKeys.length > 0 && pageRowKeys.every((k) => selection.has(k));\n const somePageSelected = !allPageSelected && pageRowKeys.some((k) => selection.has(k));\n\n const toggleAllOnPage = useCallback(() => {\n if (!onSelectionChange) return;\n const next = new Set(selection);\n if (allPageSelected) {\n pageRowKeys.forEach((k) => next.delete(k));\n } else {\n pageRowKeys.forEach((k) => next.add(k));\n }\n onSelectionChange(next);\n }, [onSelectionChange, selection, allPageSelected, pageRowKeys]);\n\n const toggleRow = useCallback(\n (key: string) => {\n if (!onSelectionChange) return;\n const next = new Set(selection);\n if (next.has(key)) next.delete(key);\n else next.add(key);\n onSelectionChange(next);\n },\n [onSelectionChange, selection]\n );\n\n const handleSort = useCallback(\n (columnKey: string) => {\n onSort?.(columnKey);\n },\n [onSort]\n );\n\n const handlePageChange = useCallback(\n (_: unknown, newPage: number) => {\n onPageChange(newPage);\n },\n [onPageChange]\n );\n\n const handlePageSizeChange = useCallback(\n (event: React.ChangeEvent<HTMLInputElement>) => {\n onPageSizeChange?.(parseInt(event.target.value, 10));\n onPageChange(0);\n },\n [onPageSizeChange, onPageChange]\n );\n\n // Skeleton rows for loading state.\n //\n // Not `pageSize` of them. A page size of 25 or 100 is a ceiling on what the\n // table MAY hold, not a prediction of what is coming, so a table that\n // resolves to three rows — or to none — first drew a hundred grey bars and\n // then threw them away. Measured on omnitron's /deployments, which has no\n // deployments and flashed 25. Enough rows to read as a table, capped by the\n // page size so a deliberately small page does not overshoot.\n const skeletonRowCount = Math.max(1, Math.min(pageSize, loadingRows));\n const skeletonRows = useMemo(\n () =>\n Array.from({ length: skeletonRowCount }, (_, i) => (\n <TableRow key={`skeleton-${i}`}>\n {selectable && (\n <TableCell padding=\"checkbox\">\n <Skeleton variant=\"rectangular\" width={18} height={18} sx={{ borderRadius: 0.5 }} />\n </TableCell>\n )}\n {columns.map((col) => (\n <TableCell key={col.key} align={col.align ?? 'left'}>\n <Skeleton\n variant=\"text\"\n width={col.align === 'right' ? '60%' : '80%'}\n sx={{\n ml: col.align === 'right' ? 'auto' : 0,\n borderRadius: 0.5,\n }}\n />\n </TableCell>\n ))}\n </TableRow>\n )),\n [skeletonRowCount, columns, selectable]\n );\n\n const showBulkBar = selectable && selection.size > 0 && !!bulkActions;\n\n // Empty state\n if (!loading && data.length === 0) {\n return (\n <StyledTableContainer sx={sx}>\n <TableViewport label={scrollLabel}>\n <MuiTable sx={{ minWidth }} size={dense ? 'small' : 'medium'} stickyHeader={stickyHeader}>\n <StyledTableHead>\n <TableRow>\n {selectable && <TableCell padding=\"checkbox\" />}\n {columns.map((col) => (\n <TableCell\n key={col.key}\n align={col.align ?? 'left'}\n style={{ width: col.width, minWidth: col.minWidth }}\n >\n {col.header}\n </TableCell>\n ))}\n </TableRow>\n </StyledTableHead>\n </MuiTable>\n </TableViewport>\n <Box\n sx={{\n py: 6,\n px: 2,\n textAlign: 'center',\n overflowWrap: 'anywhere',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: 1.5,\n }}\n >\n <EmptyIcon />\n <Typography\n variant=\"body2\"\n // `text.secondary` rather than `text.disabled` for a failure: a\n // reason the reader needs must not be the palette's quietest text.\n sx={{ color: loadError ? 'text.secondary' : 'text.disabled' }}\n >\n {loadError ? (loadErrorLabels?.empty ?? 'Could not load this data') : emptyMessage}\n </Typography>\n {loadError && (\n <Typography variant=\"caption\" sx={{ color: 'text.disabled', maxWidth: 420, textAlign: 'center' }}>\n {loadError}\n </Typography>\n )}\n </Box>\n </StyledTableContainer>\n );\n }\n\n return (\n <StyledTableContainer sx={sx}>\n {loadError && (\n <Box\n role=\"status\"\n sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 1,\n px: 2,\n py: 1,\n borderBottom: 1,\n borderColor: 'divider',\n bgcolor: (theme) => alpha(theme.palette.warning.main, 0.12),\n }}\n >\n <Typography variant=\"body2\" sx={{ color: 'warning.dark', fontWeight: 600 }}>\n {loadErrorLabels?.partial ?? 'Some of this data could not be loaded'}\n </Typography>\n <Typography variant=\"caption\" sx={{ color: 'text.secondary' }}>\n {loadError}\n </Typography>\n </Box>\n )}\n {showBulkBar && (\n <Stack\n direction=\"row\"\n spacing={2}\n sx={{\n alignItems: 'center',\n px: 2,\n py: 1,\n borderBottom: (theme) => `1px solid ${theme.palette.divider}`,\n bgcolor: (theme) => alpha(theme.palette.primary.main, 0.06),\n }}\n >\n <Typography\n variant=\"body2\"\n sx={{\n fontWeight: 600,\n }}\n >\n {selection.size} selected\n </Typography>\n <Box sx={{ flex: 1 }} />\n {bulkActions(selection)}\n </Stack>\n )}\n <TableViewport label={scrollLabel} maxHeight={maxHeight}>\n <MuiTable sx={{ minWidth }} size={dense ? 'small' : 'medium'} stickyHeader={stickyHeader}>\n <StyledTableHead>\n <TableRow>\n {selectable && (\n <TableCell padding=\"checkbox\">\n <Checkbox\n size=\"small\"\n indeterminate={somePageSelected}\n checked={allPageSelected}\n disabled={loading || pageRowKeys.length === 0}\n onChange={toggleAllOnPage}\n slotProps={{\n input: { 'aria-label': 'select all rows on page' },\n }}\n />\n </TableCell>\n )}\n {columns.map((col) => (\n <TableCell\n key={col.key}\n align={col.align ?? 'left'}\n style={{ width: col.width, minWidth: col.minWidth }}\n sortDirection={sortBy === col.key ? sortOrder : false}\n >\n {col.sortable && onSort ? (\n <TableSortLabel\n active={sortBy === col.key}\n direction={sortBy === col.key ? sortOrder : 'asc'}\n onClick={() => handleSort(col.key)}\n >\n {col.header}\n </TableSortLabel>\n ) : (\n col.header\n )}\n </TableCell>\n ))}\n </TableRow>\n </StyledTableHead>\n\n <TableBody>\n {loading\n ? skeletonRows\n : data.map((row, index) => {\n const key = getRowKey(row, index);\n const isSelected = selectable && selection.has(key);\n const body = (\n <StyledTableRow\n key={key}\n hover\n selected={isSelected}\n tabIndex={onRowClick || selectable ? -1 : undefined}\n data-row-action={onRowClick ? true : undefined}\n onClick={onRowClick ? event => { if (isRowActionTarget(event.target)) onRowClick(row); } : undefined}\n sx={{\n cursor: onRowClick ? 'pointer' : 'default',\n '&:focus-visible': { outline: '2px solid', outlineColor: 'primary.main', outlineOffset: -2 },\n ...rowSx?.(row, index),\n }}\n >\n {selectable && (\n <TableCell\n padding=\"checkbox\"\n // Stop row-click bubbling so toggling a row's\n // checkbox doesn't also fire onRowClick.\n onClick={(e) => e.stopPropagation()}\n >\n <Checkbox\n size=\"small\"\n checked={isSelected}\n onChange={() => toggleRow(key)}\n slotProps={{\n input: { 'aria-label': 'select row' },\n }}\n />\n </TableCell>\n )}\n {columns.map((col) => (\n <TableCell key={col.key} align={col.align ?? 'left'}>\n {col.render(row, index)}\n </TableCell>\n ))}\n </StyledTableRow>\n );\n const detail = renderExpanded?.(row, index);\n if (detail == null) return body;\n return (\n <Fragment key={`${key}-group`}>\n {body}\n {/*\n `hover` and the row styling are deliberately absent:\n this is a continuation of the row above, not a row of\n its own, and giving it its own hover state makes the\n pair read as two records.\n */}\n <TableRow>\n <TableCell colSpan={columns.length + (selectable ? 1 : 0)} sx={{ py: 0, borderBottom: 0 }}>\n {detail}\n </TableCell>\n </TableRow>\n </Fragment>\n );\n })}\n </TableBody>\n </MuiTable>\n </TableViewport>\n <TablePagination\n component=\"div\"\n count={total}\n page={page}\n rowsPerPage={pageSize}\n rowsPerPageOptions={pageSizeOptions}\n onPageChange={handlePageChange}\n onRowsPerPageChange={handlePageSizeChange}\n {...(paginationLabels?.rowsPerPage != null && { labelRowsPerPage: paginationLabels.rowsPerPage })}\n {...(paginationLabels?.displayedRows != null && { labelDisplayedRows: paginationLabels.displayedRows })}\n sx={{\n borderTop: (theme) => `1px solid ${theme.palette.divider}`,\n '& .MuiTablePagination-displayedRows': {\n fontSize: '0.8rem',\n },\n '& .MuiTablePagination-selectLabel': {\n fontSize: '0.8rem',\n },\n }}\n />\n </StyledTableContainer>\n );\n}\n","'use client';\n\n/**\n * Status Chip Component\n *\n * Universal status badge with automatic color mapping.\n *\n * @module components/admin-filters\n */\n\nimport type { ReactNode, Ref } from 'react';\nimport Chip, { type ChipProps } from '@mui/material/Chip';\nimport { alpha } from '@mui/material/styles';\nimport type { SxProps, Theme } from '@mui/material/styles';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type StatusColor = 'success' | 'error' | 'warning' | 'info' | 'default';\n\ninterface StatusChipOwnProps {\n /** Status string to display (drives color mapping) */\n status: string;\n /**\n * Optional display override — pass a localized label while keeping\n * `status` as the raw enum value used for color mapping. When omitted,\n * the chip falls back to the capitalized `status` string.\n */\n label?: ReactNode;\n /** Map status values to colors */\n colorMap?: Record<string, StatusColor>;\n /** Chip size */\n size?: 'small' | 'medium';\n /** Additional styles */\n sx?: SxProps<Theme>;\n}\n\n/**\n * The chip takes `ref` and passes everything else to MUI's `Chip`, as every\n * leaf in this library does: the portal's members tab put two of these\n * inside a `Tooltip`, which attaches its ref and its hover handlers to its\n * child — and a chip that dropped both was a tooltip that never opened.\n */\nexport type StatusChipProps = StatusChipOwnProps &\n Omit<ChipProps, keyof StatusChipOwnProps | 'ref'> & { ref?: Ref<HTMLDivElement> };\n\n// =============================================================================\n// DEFAULT COLOR MAP\n// =============================================================================\n\nconst DEFAULT_COLOR_MAP: Record<string, StatusColor> = {\n active: 'success',\n completed: 'success',\n confirmed: 'success',\n approved: 'success',\n enabled: 'success',\n online: 'success',\n paid: 'success',\n resolved: 'success',\n success: 'success',\n\n pending: 'warning',\n processing: 'warning',\n waiting: 'warning',\n review: 'warning',\n draft: 'warning',\n\n failed: 'error',\n error: 'error',\n rejected: 'error',\n blocked: 'error',\n banned: 'error',\n disabled: 'error',\n cancelled: 'error',\n expired: 'error',\n suspended: 'error',\n offline: 'error',\n\n info: 'info',\n new: 'info',\n open: 'info',\n};\n\n// =============================================================================\n// COMPONENT\n// =============================================================================\n\n/**\n * StatusChip - Universal status badge with color mapping.\n *\n * Automatically maps common status strings to appropriate colors.\n * Provide a custom `colorMap` to override or extend the defaults.\n *\n * @example\n * ```tsx\n * <StatusChip status=\"active\" />\n * <StatusChip status=\"pending\" size=\"small\" />\n * <StatusChip\n * status=\"custom\"\n * colorMap={{ custom: 'info', special: 'success' }}\n * />\n * ```\n */\nexport function StatusChip({ status, label, colorMap, size = 'small', sx, ref, ...other }: StatusChipProps): ReactNode {\n const normalizedStatus = status.toLowerCase();\n const mergedMap = colorMap ? { ...DEFAULT_COLOR_MAP, ...colorMap } : DEFAULT_COLOR_MAP;\n // Own-property lookup only. Statuses arrive from the server, and a plain\n // object answers `map['constructor']` with a FUNCTION — which `?? 'default'`\n // accepts as a colour, sending `theme.palette[fn].main` into a TypeError\n // that takes the whole React tree down. `toString`, `valueOf` and\n // `hasOwnProperty` do the same.\n const mapped = Object.hasOwn(mergedMap, normalizedStatus) ? mergedMap[normalizedStatus] : undefined;\n const color: StatusColor = mapped ?? 'default';\n\n const displayLabel: ReactNode = label ?? status.charAt(0).toUpperCase() + status.slice(1).toLowerCase();\n\n return (\n <Chip\n ref={ref}\n {...other}\n label={displayLabel}\n size={size}\n sx={[\n {\n height: size === 'small' ? 22 : 28,\n fontSize: size === 'small' ? '0.7rem' : '0.775rem',\n fontWeight: 600,\n borderRadius: 0.75,\n letterSpacing: '0.01em',\n ...(color !== 'default' && {\n color: (theme: Theme) => theme.palette[color].main,\n bgcolor: (theme: Theme) => alpha(theme.palette[color].main, 0.1),\n border: (theme: Theme) => `1px solid ${alpha(theme.palette[color].main, 0.2)}`,\n }),\n ...(color === 'default' && {\n color: 'text.secondary',\n bgcolor: (theme: Theme) => alpha(theme.palette.grey[500], 0.08),\n border: (theme: Theme) => `1px solid ${alpha(theme.palette.grey[500], 0.16)}`,\n }),\n },\n ...(Array.isArray(sx) ? sx : sx ? [sx] : []),\n ]}\n />\n );\n}\n","/**\n * Canonical BTC / XMR amount formatter.\n *\n * Why this exists\n * ---------------\n * Pre-consolidation the platform had ~8 independent formatters,\n * each shipping its own opinion of precision:\n *\n * - `org-finances/formatBtc` → BTC 8, XMR 4\n * - `org-revenue-card` → BTC 4, XMR 4\n * - `orgs-overview/formatBtc` → tiered 8 → 4 → 2 by magnitude\n * - `shop-dashboard` → BTC 4\n * - `shop-categories` → BTC 8 with trailing-zero trim\n * - `finances/hooks` → BTC 8, XMR 8 (already canonical\n * but isolated from everyone else)\n * - `pages/finances DEFAULT_ASSETS` → XMR 12 (wire-precision leak)\n *\n * Result: a single dashboard showed BTC 4 in the KPI tile, BTC 8\n * in the Financial Overview tile, and BTC 6 in another corner —\n * three \"truths\" for the same value. This module is the single\n * source of truth from now on; all call sites import from here.\n *\n * Display vs wire precision\n * -------------------------\n * Wire precision (what the backend stores) is 8 for BTC, 12 for\n * XMR — those are the on-chain atomic units (satoshi, piconero).\n * Display precision is 8 for BOTH coins by platform convention:\n *\n * - 8 fractional digits is a satoshi-level read for BTC,\n * - 8 fractional digits for XMR is \"good enough\" for human eyes\n * and keeps the column widths symmetric. The last 4 digits of\n * XMR's wire value are dropped from display only — never from\n * storage, math, or wire transfers.\n *\n * The platform-wide symmetric formatting was a direct user-facing\n * request: the same coin column should align cleanly whether the\n * row holds BTC or XMR.\n *\n * Which way a dropped digit goes\n * ------------------------------\n * Those four dropped XMR digits are the reason this module has a\n * rounding DIRECTION and not just a scale. Display rounding used\n * to be half-up, so a balance of\n *\n * 1.586170199999 XMR (what the account holds)\n *\n * rendered as `1.58617020 XMR` — a tenth of a piconero MORE than\n * exists. A person who reads that number and types it back into a\n * withdrawal is refused for insufficient funds, by a figure the\n * platform itself put on their screen. The same arithmetic seeds\n * the \"max balance\" shortcut, so the refusal arrives from a button\n * whose entire purpose is to be correct.\n *\n * So the rule for anything rendered as money is: **the displayed\n * magnitude is never larger than the real one.** Quantization for\n * display truncates toward zero (`'down'`), at any precision, in\n * either sign. That is not a matter of taste at eight decimals\n * versus twelve — it holds whatever the scale, which is why it is\n * a separate decision from the 8-vs-12 convention above.\n *\n * Half-up remains available and remains the default for the\n * ARITHMETIC primitives (`toScaledInteger`, `sumDecimalStrings`,\n * `subtractDecimalStrings`), where the scale is the value's own\n * and the last digit is a genuine rounding rather than a\n * truncation of digits that are really there. Arithmetic on money\n * belongs at `getCoinWireDecimals(coin)`, not at display scale;\n * quantize once, at the end, downward.\n *\n * The other direction is a lie too\n * --------------------------------\n * Truncating `0.000000004916 XMR` to eight decimals gives\n * `0.00000000` — a balance that exists, shown as nothing at all.\n * `formatCoinAmount` renders that as `< 0.00000001 XMR` instead\n * (`> -0.00000001` below zero). A threshold marker is honest about\n * both the amount and the limit of the column; a flat zero is not.\n * Pass `markDust: false` where a bare numeral is required.\n *\n * If you need a *narrower* surface (a dense table, a stat-card\n * subtitle), use `{ trim: true }` to drop trailing zeros while\n * keeping the canonical precision as the cap. Don't bypass this\n * module with an ad-hoc `toFixed(N)` — that's exactly the entropy\n * we just cleaned up, and `toFixed` rounds the wrong way for money\n * on top of rounding a double.\n */\n\n/**\n * Canonical display-precision per supported coin. Use this when\n * you need the raw precision number (e.g. populating an input\n * field's `.toFixed(...)` to seed a \"max balance\" button). For\n * actual rendering of a value, prefer `formatCoinAmount`.\n */\nexport const COIN_DISPLAY_DECIMALS: Readonly<Record<string, number>> = Object.freeze(\n // Prototype-free: a plain literal answers `COIN_DISPLAY_DECIMALS['constructor']`\n // with a function, which `?? FALLBACK_DECIMALS` accepts as a precision. That\n // produced `toFixed(NaN)` — silently formatting with zero decimals instead\n // of eight, for any coin code that collides with an Object.prototype key.\n Object.assign(Object.create(null) as Record<string, number>, { btc: 8, xmr: 8 })\n);\n\n/**\n * Atomic-unit precision per coin — what the backend actually stores.\n *\n * This is NOT a display precision and must never be used as one; the\n * platform shows both coins at eight digits on purpose (see the module\n * docblock). It is the scale to do ARITHMETIC at: totalling balances,\n * subtracting a lock from a total, comparing an entered amount against\n * what is available. Doing that at display scale quantizes four XMR\n * digits away before the sum, and each quantization is a chance to\n * report a figure the ledger does not agree with.\n *\n * The authority is payments's `coins.precision` column (`BTC` 8, `XMR` 12);\n * main keeps its own copy in `billing.service.ts` as `CRYPTO_PRECISION`.\n * This is the browser's copy, because a synchronous formatter cannot\n * query a table. Three copies of one fact: when a coin is added, all\n * three change, and a mismatch here shows up as arithmetic that silently\n * drops the coin's last digits.\n */\nexport const COIN_WIRE_DECIMALS: Readonly<Record<string, number>> = Object.freeze(\n Object.assign(Object.create(null) as Record<string, number>, { btc: 8, xmr: 12 })\n);\n\n/** Default precision when the coin code isn't recognized. */\nconst FALLBACK_DECIMALS = 8;\n\n/**\n * Wire-scale fallback for an unrecognized coin.\n *\n * Deliberately the WIDEST scale this module knows rather than the\n * narrowest. An unknown coin's digits survive arithmetic done at a scale\n * too wide; at a scale too narrow they are gone before the first\n * operation, and nothing downstream can tell. The display fallback goes\n * the other way for the same reason it truncates: too few digits shown is\n * a smaller error than digits invented.\n */\nconst FALLBACK_WIRE_DECIMALS = 12;\n\n/**\n * Which way a value that does not fit the requested scale is quantized.\n *\n * `'down'` toward zero. The displayed magnitude is never larger\n * than the real one — the rule for money on a screen.\n * `'half-up'` to the nearest, ties away from zero. The rule for\n * arithmetic, where the scale is the value's own.\n */\nexport type DecimalRounding = 'down' | 'half-up';\n\n/** A plain decimal: optional sign, digits, optional fraction. No exponents. */\nconst DECIMAL = /^([+-]?)(\\d*)(?:\\.(\\d*))?$/;\n\nexport interface FormatCoinAmountOptions {\n /**\n * Append the uppercase coin symbol (`\"0.00012345 BTC\"`).\n * Default `true`. Disable for places where the symbol is\n * rendered separately (e.g. a chip beside the number).\n */\n withSymbol?: boolean;\n /**\n * Trim trailing zeros after the decimal point. Useful in dense\n * tables where `0 BTC` reads cleaner than `0.00000000 BTC`. The\n * precision cap (8) is still honoured — we just drop tail\n * zeros up to and including the decimal point. Default `false`.\n */\n trim?: boolean;\n /**\n * Override precision. ONLY use this for legacy back-compat\n * (e.g. a screen that genuinely needs to truncate at a non-\n * standard width). Prefer the default. Negative values clamp\n * to 0.\n */\n precision?: number;\n /**\n * Custom symbol override. Defaults to `coin.toUpperCase()`. Set\n * this if you need a non-standard label (e.g. \"₿\" for BTC) —\n * but be aware that mixing symbols across the platform is what\n * this module was built to prevent.\n */\n symbol?: string;\n /**\n * Which way to quantize digits that do not fit `precision`.\n * Default `'down'` — a rendered amount is never larger than the\n * amount that exists. Pass `'half-up'` only where the figure is\n * not a quantity anyone holds (a rate, an average, a chart axis).\n */\n rounding?: DecimalRounding;\n /**\n * Render a non-zero amount that vanishes at this precision as\n * `< 0.00000001` rather than `0.00000000`. Default `true`.\n * Disable where the output has to be a bare numeral.\n */\n markDust?: boolean;\n}\n\n/**\n * Resolve the canonical display precision for a coin code.\n * Case-insensitive. Unknown codes fall back to 8.\n */\nexport function getCoinDecimals(coin: string): number {\n const decimals = COIN_DISPLAY_DECIMALS[coin.toLowerCase()];\n return typeof decimals === 'number' ? decimals : FALLBACK_DECIMALS;\n}\n\n/**\n * Resolve the ATOMIC-UNIT precision for a coin code — the scale the value\n * arrived at and the scale to compute at. Case-insensitive.\n *\n * `getCoinDecimals` is for rendering; this is for `sumDecimalStrings`,\n * `subtractDecimalStrings`, and any comparison between an amount a person\n * entered and an amount the ledger holds.\n */\nexport function getCoinWireDecimals(coin: string): number {\n const decimals = COIN_WIRE_DECIMALS[coin.toLowerCase()];\n return typeof decimals === 'number' ? decimals : FALLBACK_WIRE_DECIMALS;\n}\n\n/**\n * Format a decimal STRING at a fixed scale without going through a float.\n *\n * Exported because more than one surface needs it: `formatCoinAmount` for\n * coin balances, `AmountCell` for financial tables. Anything that receives a\n * decimal string from the wire and renders it should use this rather than\n * `Number(x).toFixed(n)`.\n *\n * The docblock above promises that string input \"preserves full precision\n * end-to-end from the RPC wire\", but the implementation used to hand the\n * string straight to `Number()` — inheriting binary floating point along with\n * its rounding surprises. `'1.005'` is fractionally BELOW 1.005 as a double,\n * so `toFixed(2)` rendered `'1.00'`: a balance displayed one cent short of\n * the one actually stored.\n *\n * This is the RENDERING half of the pair, so it quantizes DOWN by default:\n * the string it returns never stands for more than the string it was given.\n * Its arithmetic counterpart `toScaledInteger` defaults to `'half-up'`;\n * the two differ on purpose and the module docblock says why.\n *\n * Unlike `formatCoinAmount` it always returns a plain parseable decimal —\n * no threshold marker, no symbol — because its callers feed the result back\n * into `Number()`.\n *\n * @returns the formatted string, or `null` when `raw` is not a plain decimal\n * (exponent notation, junk) — the caller then falls back to `Number`.\n */\nexport function formatDecimalString(\n raw: string,\n decimals: number,\n rounding: DecimalRounding = 'down'\n): string | null {\n const scaled = toScaledInteger(raw, decimals, rounding);\n return scaled === null ? null : fromScaledInteger(scaled, decimals);\n}\n\n/**\n * A decimal string as an exact integer at `decimals` scale.\n *\n * `'1.005'` at scale 2 is `101n` under the default half-up — which is the\n * whole point: as a double the same literal sits fractionally BELOW 1.005,\n * so any arithmetic that starts with `Number('1.005')` has already lost\n * before it begins.\n *\n * The default is `'half-up'` because this is the arithmetic primitive:\n * callers pass the value's own scale, where the last digit is a rounding\n * and not a truncation. Rendering goes through `formatDecimalString`, which\n * defaults to `'down'` — see the module docblock.\n *\n * @returns null when `raw` is not a plain decimal (exponent notation, junk).\n */\nexport function toScaledInteger(\n raw: string,\n decimals: number,\n rounding: DecimalRounding = 'half-up'\n): bigint | null {\n const match = DECIMAL.exec(raw.trim());\n if (!match) return null;\n\n const [, sign = '', intPart = '', fracPart = ''] = match;\n if (intPart === '' && fracPart === '') return null;\n\n const digits = `${intPart || '0'}${fracPart.slice(0, decimals).padEnd(decimals, '0')}`;\n const roundUp = rounding === 'half-up' && (fracPart[decimals] ?? '0') >= '5';\n const magnitude = BigInt(digits) + (roundUp ? 1n : 0n);\n\n return sign === '-' ? -magnitude : magnitude;\n}\n\n/** Render a scaled integer back as a decimal string. Inverse of `toScaledInteger`. */\nexport function fromScaledInteger(scaled: bigint, decimals: number): string {\n const negative = scaled < 0n;\n const asString = (negative ? -scaled : scaled).toString().padStart(decimals + 1, '0');\n const whole = asString.slice(0, asString.length - decimals) || '0';\n const fraction = decimals > 0 ? asString.slice(asString.length - decimals) : '';\n const magnitude = decimals > 0 ? `${whole}.${fraction}` : whole;\n\n // -0 is not a balance anyone holds.\n return `${negative && scaled !== 0n ? '-' : ''}${magnitude}`;\n}\n\n/**\n * Whether `raw` reads as a plain decimal that is not zero.\n *\n * Used to tell \"this is nothing\" from \"this is less than the column can\n * show\". Exponent notation reads as neither — this module refuses it\n * everywhere, so a value it cannot parse is not claimed to be dust either.\n */\nfunction isNonZeroDecimal(raw: string): boolean {\n const match = DECIMAL.exec(raw.trim());\n if (!match) return false;\n\n const [, , intPart = '', fracPart = ''] = match;\n if (intPart === '' && fracPart === '') return false;\n\n return /[1-9]/.test(intPart) || /[1-9]/.test(fracPart);\n}\n\n/**\n * Add decimal strings exactly, returning a decimal string.\n *\n * For totalling amounts that arrived from the wire as strings. Accumulating\n * them with `parseFloat` is the same mistake as formatting with it, one step\n * earlier and harder to see: `0.1 + 0.2 + 0.3` is `0.6000000000000001`, and\n * while a formatter capped at eight decimals rounds that back to `0.60000000`,\n * anything that shows the raw total — a tooltip, a CSV export, a value posted\n * back to the server — shows the artefact.\n *\n * Values that are not plain decimals are skipped rather than poisoning the\n * total with `NaN`; `null` and `undefined` count as absent, not as zero-ish\n * junk. Numbers are accepted for callers mid-migration, and go through their\n * decimal representation rather than their binary one.\n *\n * @param decimals scale to accumulate at — use the coin's WIRE precision\n * (`getCoinWireDecimals`). Accumulating at display scale quantizes\n * each value before it is added, so the total is a sum of roundings;\n * `getCoinDecimals` is for the one quantization at the end.\n * @param options.rounding how each value is quantized to `decimals`. Default\n * `'half-up'`; at wire scale nothing is dropped and it does not\n * arise. Pass `'down'` if you must accumulate at display scale and\n * the total is money — a sum of half-ups can exceed what exists.\n */\nexport function sumDecimalStrings(\n values: Iterable<string | number | null | undefined>,\n decimals: number,\n options?: { rounding?: DecimalRounding }\n): string {\n const rounding = options?.rounding ?? 'half-up';\n let total = 0n;\n\n for (const value of values) {\n if (value === null || value === undefined || value === '') continue;\n const scaled = toScaledInteger(\n typeof value === 'number' ? String(value) : value,\n decimals,\n rounding\n );\n if (scaled !== null) total += scaled;\n }\n\n return fromScaledInteger(total, decimals);\n}\n\n/**\n * Subtract decimal strings exactly, returning a decimal string.\n *\n * The companion to `sumDecimalStrings`, and the one a wallet needs more\n * often: available balance is total minus locked, and computing it with\n * `parseFloat` produces `0.19999999999999998` from `0.30000000 - 0.10000000`.\n * A formatter capped at the coin's precision rounds that back, but the raw\n * value does not always reach a formatter — a tooltip, a CSV column, a\n * \"max\" button that fills an amount field, or a value posted back to the\n * server all show it as it is. Small amounts are worse than wrong: they\n * become exponential notation, and `1.0999999999999999e-7` is not a number\n * any balance field will accept.\n *\n * Unparseable inputs are treated as absent — `null` when the minuend cannot\n * be read, since a difference from an unknown quantity is unknown, and\n * subtracting nothing when a subtrahend cannot be read.\n *\n * @param decimals scale to compute at — `getCoinWireDecimals(coin)`. At\n * display scale the minuend and the subtrahends are each quantized\n * first, and an available balance assembled from two roundings can\n * come out above the amount the ledger will actually release.\n * @param clampAtZero return '0' rather than a negative result. On for the\n * available-balance case, where a negative would be a display artefact\n * of two readings taken a moment apart, not a debt.\n * @param rounding how each operand is quantized to `decimals`. Default\n * `'half-up'`, matching `toScaledInteger`.\n */\nexport function subtractDecimalStrings(\n minuend: string | number | null | undefined,\n subtrahends: Iterable<string | number | null | undefined>,\n decimals: number,\n options?: { clampAtZero?: boolean; rounding?: DecimalRounding }\n): string | null {\n if (minuend === null || minuend === undefined || minuend === '') return null;\n\n const rounding = options?.rounding ?? 'half-up';\n let total = toScaledInteger(\n typeof minuend === 'number' ? String(minuend) : minuend,\n decimals,\n rounding\n );\n if (total === null) return null;\n\n for (const value of subtrahends) {\n if (value === null || value === undefined || value === '') continue;\n const scaled = toScaledInteger(\n typeof value === 'number' ? String(value) : value,\n decimals,\n rounding\n );\n if (scaled !== null) total -= scaled;\n }\n\n if (options?.clampAtZero && total < 0n) total = 0n;\n return fromScaledInteger(total, decimals);\n}\n\n/**\n * Format a crypto amount for display.\n *\n * Input can be a string (preferred — preserves full precision\n * end-to-end from the RPC wire) or a number. Non-finite / NaN\n * inputs render as the zero-shaped placeholder so the UI never\n * shows `NaN BTC`.\n *\n * Digits below the coin's display precision are dropped, not rounded up:\n * the string returned never stands for more coin than the argument did.\n * An amount that is real but smaller than the last displayed digit renders\n * as `< 0.00000001` rather than as a flat zero.\n *\n * @example\n * formatCoinAmount('0.001', 'BTC') // '0.00100000 BTC'\n * formatCoinAmount('0.001', 'BTC', { trim: true }) // '0.001 BTC'\n * formatCoinAmount(null, 'XMR') // '0.00000000 XMR'\n * formatCoinAmount('1.23456789', 'BTC', { withSymbol: false }) // '1.23456789'\n * formatCoinAmount('1.586170199999', 'XMR') // '1.58617019 XMR'\n * formatCoinAmount('0.000000004916', 'XMR') // '< 0.00000001 XMR'\n */\nexport function formatCoinAmount(\n value: string | number | null | undefined,\n coin: string,\n options?: FormatCoinAmountOptions,\n): string {\n const code = coin.toLowerCase();\n const symbol = options?.symbol ?? coin.toUpperCase();\n const withSymbol = options?.withSymbol !== false;\n const decimals = Math.max(0, options?.precision ?? getCoinDecimals(code));\n const trim = options?.trim === true;\n const rounding = options?.rounding ?? 'down';\n const markDust = options?.markDust !== false;\n\n // A number goes through its DECIMAL representation, not its binary one —\n // the same choice `sumDecimalStrings` makes. `String(1.586170199999)` is\n // the shortest round-tripping decimal for that double; handing the double\n // itself to `toFixed` reintroduces exactly the rounding this module\n // exists to avoid.\n const raw =\n typeof value === 'string'\n ? value.trim()\n : typeof value === 'number' && Number.isFinite(value)\n ? String(Object.is(value, -0) ? 0 : value)\n : '';\n\n let formatted = raw === '' ? null : formatDecimalString(raw, decimals, rounding);\n const exact = formatted !== null;\n\n if (formatted === null) {\n // Not a plain decimal: exponent notation, or junk. The float path stays\n // for those, because there is nothing better to do with them.\n let n = typeof value === 'number' ? value : Number(raw);\n if (!Number.isFinite(n)) n = 0;\n // `-0` formats as \"-0.00000000\" otherwise.\n if (Object.is(n, -0)) n = 0;\n formatted = n.toFixed(decimals);\n }\n\n // Real, and smaller than this column can show. A flat zero here is the\n // mirror of rounding up: it reports an amount the holder does not have.\n if (markDust && exact && !/[1-9]/.test(formatted) && isNonZeroDecimal(raw)) {\n const epsilon = fromScaledInteger(1n, decimals);\n const below = raw.startsWith('-');\n return withSymbol\n ? `${below ? '>' : '<'} ${below ? '-' : ''}${epsilon} ${symbol}`\n : `${below ? '>' : '<'} ${below ? '-' : ''}${epsilon}`;\n }\n\n if (trim && formatted.includes('.')) {\n // Drop trailing zeros and a trailing solitary decimal point.\n formatted = formatted.replace(/\\.?0+$/, '');\n if (formatted === '' || formatted === '-') formatted = '0';\n }\n\n return withSymbol ? `${formatted} ${symbol}` : formatted;\n}\n\n/**\n * Render a multi-coin total map (e.g. revenue across coins)\n * as a single inline string: `\"0.00010000 BTC · 0.00000000 XMR\"`.\n *\n * Stable ordering by lower-cased coin code so BTC always appears\n * before XMR regardless of object-property iteration quirks.\n */\nexport function formatCoinAmountList(\n totals: Partial<Record<string, string | number | null | undefined>>,\n options?: FormatCoinAmountOptions & { separator?: string },\n): string {\n const sep = options?.separator ?? ' · ';\n return Object.keys(totals)\n .sort()\n .map((coin) => formatCoinAmount(totals[coin], coin, options))\n .join(sep);\n}\n","'use client';\n\n/**\n * Amount Cell Component\n *\n * Formatted amount display for financial tables with monospace font,\n * optional sign coloring, and currency display.\n *\n * @module components/admin-filters\n */\n\nimport type { ReactNode } from 'react';\nimport { useMemo } from 'react';\nimport Typography from '@mui/material/Typography';\nimport type { SxProps, Theme } from '@mui/material/styles';\n\nimport { formatDecimalString } from '../../utils/format-crypto.js';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport interface AmountCellProps {\n /** Amount as string (to preserve precision for crypto values) */\n amount: string;\n /** Currency code (e.g. \"BTC\", \"USD\", \"XMR\") */\n currency?: string;\n /** Number of decimal places */\n decimals?: number;\n /** Show +/- sign prefix */\n showSign?: boolean;\n /** Color positive green / negative red */\n color?: boolean;\n /** Additional styles */\n sx?: SxProps<Theme>;\n}\n\n// =============================================================================\n// HELPERS\n// =============================================================================\n\nfunction formatAmount(amount: string, decimals?: number): string {\n const num = parseFloat(amount);\n if (Number.isNaN(num)) return amount;\n\n // Scale the DECIMAL STRING, never `Number(amount).toFixed(n)`.\n //\n // This component exists for financial tables, and its own docblock shows\n // `<AmountCell amount=\"0.00045123\" currency=\"XMR\" decimals={12} />` — a\n // precision at which a double has already lost digits. The amount arrives\n // as a string precisely so those digits survive; rounding it through a\n // float discarded them at the last step before display.\n const scaled = decimals !== undefined ? formatDecimalString(amount, decimals) : null;\n const fixed = scaled ?? (decimals !== undefined ? num.toFixed(decimals) : amount);\n const [intPart, decPart] = fixed.split('.');\n const absInt = intPart.replace('-', '');\n\n // Add thousands separators\n const formatted = absInt.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const prefix = num < 0 ? '-' : '';\n return decPart !== undefined ? `${prefix}${formatted}.${decPart}` : `${prefix}${formatted}`;\n}\n\n// =============================================================================\n// COMPONENT\n// =============================================================================\n\n/**\n * AmountCell - Formatted amount display for financial data.\n *\n * Uses monospace font for alignment. Supports sign display, color coding\n * (green for positive, red for negative), and currency suffixes.\n *\n * @example\n * ```tsx\n * <AmountCell amount=\"1234.56\" currency=\"BTC\" decimals={8} />\n * <AmountCell amount=\"-500.00\" currency=\"USD\" showSign color />\n * <AmountCell amount=\"0.00045123\" currency=\"XMR\" decimals={12} />\n * ```\n */\nexport function AmountCell({\n amount,\n currency,\n decimals,\n showSign = false,\n color = false,\n sx,\n}: AmountCellProps): ReactNode {\n const num = parseFloat(amount);\n const isNegative = num < 0;\n const isPositive = num > 0;\n\n const formatted = useMemo(() => formatAmount(amount, decimals), [amount, decimals]);\n\n const signPrefix = useMemo(() => {\n if (!showSign) return '';\n if (isPositive) return '+';\n return '';\n }, [showSign, isPositive]);\n\n const textColor = useMemo(() => {\n if (!color) return undefined;\n if (isPositive) return 'success.main';\n if (isNegative) return 'error.main';\n return 'text.secondary';\n }, [color, isPositive, isNegative]);\n\n return (\n <Typography\n variant=\"body2\"\n color={textColor}\n sx={{\n fontFamily: '\"JetBrains Mono\", \"Fira Code\", \"SF Mono\", \"Consolas\", monospace',\n fontVariantNumeric: 'tabular-nums',\n fontSize: '0.8rem',\n fontWeight: 500,\n whiteSpace: 'nowrap',\n textAlign: 'right',\n ...sx,\n }}\n >\n {signPrefix}\n {formatted}\n {currency && (\n <Typography\n component=\"span\"\n variant=\"caption\"\n sx={{\n color: \"text.disabled\",\n ml: 0.5,\n fontFamily: 'inherit',\n fontSize: '0.7rem',\n fontWeight: 400\n }}>\n {currency}\n </Typography>\n )}\n </Typography>\n );\n}\n"]}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { CloseIcon } from './chunk-VQVVHMPG.js';
|
|
2
|
+
import { useState, useId, useRef, useCallback, useMemo, Children, isValidElement, useEffect } from 'react';
|
|
3
|
+
import MuiTabs from '@mui/material/Tabs';
|
|
4
|
+
import MuiTab from '@mui/material/Tab';
|
|
5
|
+
import Box from '@mui/material/Box';
|
|
6
|
+
import IconButton from '@mui/material/IconButton';
|
|
7
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
8
|
+
|
|
9
|
+
function Tabs({
|
|
10
|
+
tabs,
|
|
11
|
+
value: controlledValue,
|
|
12
|
+
defaultValue,
|
|
13
|
+
onChange,
|
|
14
|
+
onClose,
|
|
15
|
+
children,
|
|
16
|
+
keepMounted = false,
|
|
17
|
+
action,
|
|
18
|
+
sx,
|
|
19
|
+
...muiProps
|
|
20
|
+
}) {
|
|
21
|
+
const [internalValue, setInternalValue] = useState(defaultValue ?? tabs?.[0]?.value ?? "");
|
|
22
|
+
const value = controlledValue ?? internalValue;
|
|
23
|
+
const id = useId();
|
|
24
|
+
const tabRefs = useRef(/* @__PURE__ */ new Map());
|
|
25
|
+
const closing = useRef(null);
|
|
26
|
+
const handleChange = useCallback(
|
|
27
|
+
(_event, newValue) => {
|
|
28
|
+
if (controlledValue === void 0) {
|
|
29
|
+
setInternalValue(newValue);
|
|
30
|
+
}
|
|
31
|
+
onChange?.(newValue);
|
|
32
|
+
},
|
|
33
|
+
[controlledValue, onChange]
|
|
34
|
+
);
|
|
35
|
+
const tabItems = useMemo(() => {
|
|
36
|
+
if (tabs) return tabs;
|
|
37
|
+
const items = [];
|
|
38
|
+
Children.forEach(children, (child) => {
|
|
39
|
+
if (isValidElement(child) && child.type === TabPanel) {
|
|
40
|
+
const props = child.props;
|
|
41
|
+
items.push({
|
|
42
|
+
value: props.value,
|
|
43
|
+
label: props.label ?? props.value,
|
|
44
|
+
icon: props.icon,
|
|
45
|
+
content: props.children,
|
|
46
|
+
disabled: props.disabled,
|
|
47
|
+
closable: props.closable,
|
|
48
|
+
closeDisabled: props.closeDisabled,
|
|
49
|
+
closeLabel: props.closeLabel
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
return items;
|
|
54
|
+
}, [tabs, children]);
|
|
55
|
+
const requestClose = (tab) => {
|
|
56
|
+
if (!onClose || !tab.closable || tab.disabled || tab.closeDisabled) return;
|
|
57
|
+
const index = tabItems.indexOf(tab);
|
|
58
|
+
const next = tabItems.slice(index + 1).find((item) => !item.disabled) ?? tabItems.slice(0, index).reverse().find((item) => !item.disabled);
|
|
59
|
+
closing.current = { value: tab.value, next: next?.value };
|
|
60
|
+
onClose(tab.value);
|
|
61
|
+
};
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
const pending = closing.current;
|
|
64
|
+
if (!pending || tabItems.some((tab) => tab.value === pending.value)) return;
|
|
65
|
+
closing.current = null;
|
|
66
|
+
if (controlledValue === void 0 && value === pending.value) {
|
|
67
|
+
setInternalValue(pending.next ?? "");
|
|
68
|
+
if (pending.next) onChange?.(pending.next);
|
|
69
|
+
}
|
|
70
|
+
if (pending.next) tabRefs.current.get(pending.next)?.focus();
|
|
71
|
+
}, [tabItems, controlledValue, value, onChange]);
|
|
72
|
+
const hasAction = action !== void 0 && action !== null && action !== false;
|
|
73
|
+
return /* @__PURE__ */ jsxs(Box, { sx: { width: "100%", minWidth: 0, flexShrink: 0 }, children: [
|
|
74
|
+
/* @__PURE__ */ jsxs(
|
|
75
|
+
Box,
|
|
76
|
+
{
|
|
77
|
+
sx: {
|
|
78
|
+
display: "flex",
|
|
79
|
+
alignItems: "center",
|
|
80
|
+
justifyContent: "space-between",
|
|
81
|
+
gap: 2,
|
|
82
|
+
minWidth: 0
|
|
83
|
+
},
|
|
84
|
+
children: [
|
|
85
|
+
/* @__PURE__ */ jsx(
|
|
86
|
+
MuiTabs,
|
|
87
|
+
{
|
|
88
|
+
value: value || false,
|
|
89
|
+
onChange: handleChange,
|
|
90
|
+
...muiProps,
|
|
91
|
+
sx: [{ flex: 1, minWidth: 0 }, ...Array.isArray(sx) ? sx : [sx]],
|
|
92
|
+
children: tabItems.map((tab) => {
|
|
93
|
+
const closable = Boolean(tab.closable && onClose);
|
|
94
|
+
return /* @__PURE__ */ jsx(
|
|
95
|
+
MuiTab,
|
|
96
|
+
{
|
|
97
|
+
ref: (element) => {
|
|
98
|
+
if (element) tabRefs.current.set(tab.value, element);
|
|
99
|
+
else tabRefs.current.delete(tab.value);
|
|
100
|
+
},
|
|
101
|
+
component: closable ? "div" : "button",
|
|
102
|
+
id: `${id}-tab-${tab.value}`,
|
|
103
|
+
"aria-controls": tab.content === void 0 ? void 0 : `${id}-panel-${tab.value}`,
|
|
104
|
+
"aria-label": tab.label,
|
|
105
|
+
"aria-keyshortcuts": closable && !tab.closeDisabled ? "Delete" : void 0,
|
|
106
|
+
value: tab.value,
|
|
107
|
+
label: closable ? /* @__PURE__ */ jsxs(
|
|
108
|
+
Box,
|
|
109
|
+
{
|
|
110
|
+
component: "span",
|
|
111
|
+
sx: { display: "inline-flex", alignItems: "center", gap: 0.5, minWidth: 0, maxWidth: "100%" },
|
|
112
|
+
children: [
|
|
113
|
+
/* @__PURE__ */ jsx(Box, { component: "span", sx: { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: tab.label }),
|
|
114
|
+
/* @__PURE__ */ jsx(
|
|
115
|
+
IconButton,
|
|
116
|
+
{
|
|
117
|
+
component: "button",
|
|
118
|
+
type: "button",
|
|
119
|
+
size: "small",
|
|
120
|
+
tabIndex: -1,
|
|
121
|
+
"aria-label": tab.closeLabel ?? `Close ${tab.label}`,
|
|
122
|
+
title: tab.closeLabel ?? `Close ${tab.label}`,
|
|
123
|
+
disabled: tab.disabled || tab.closeDisabled,
|
|
124
|
+
sx: { p: 0.25, flexShrink: 0, color: "text.secondary" },
|
|
125
|
+
onMouseDown: (event) => {
|
|
126
|
+
event.preventDefault();
|
|
127
|
+
event.stopPropagation();
|
|
128
|
+
},
|
|
129
|
+
onClick: (event) => {
|
|
130
|
+
event.stopPropagation();
|
|
131
|
+
requestClose(tab);
|
|
132
|
+
},
|
|
133
|
+
onKeyDown: (event) => event.stopPropagation(),
|
|
134
|
+
children: /* @__PURE__ */ jsx(CloseIcon, { sx: { fontSize: 16 } })
|
|
135
|
+
}
|
|
136
|
+
)
|
|
137
|
+
]
|
|
138
|
+
}
|
|
139
|
+
) : tab.label,
|
|
140
|
+
icon: tab.icon,
|
|
141
|
+
iconPosition: "start",
|
|
142
|
+
disabled: tab.disabled,
|
|
143
|
+
onKeyDown: (event) => {
|
|
144
|
+
if (event.key === "Delete" && closable && !tab.closeDisabled) {
|
|
145
|
+
event.preventDefault();
|
|
146
|
+
event.stopPropagation();
|
|
147
|
+
requestClose(tab);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
tab.value
|
|
152
|
+
);
|
|
153
|
+
})
|
|
154
|
+
}
|
|
155
|
+
),
|
|
156
|
+
hasAction && /* @__PURE__ */ jsx(
|
|
157
|
+
Box,
|
|
158
|
+
{
|
|
159
|
+
sx: {
|
|
160
|
+
display: "flex",
|
|
161
|
+
alignItems: "center",
|
|
162
|
+
gap: 1,
|
|
163
|
+
flexShrink: 0
|
|
164
|
+
},
|
|
165
|
+
children: action
|
|
166
|
+
}
|
|
167
|
+
)
|
|
168
|
+
]
|
|
169
|
+
}
|
|
170
|
+
),
|
|
171
|
+
tabItems.map((tab) => {
|
|
172
|
+
const isActive = tab.value === value;
|
|
173
|
+
if (!isActive && !keepMounted) return null;
|
|
174
|
+
if (tab.content === void 0) return null;
|
|
175
|
+
return /* @__PURE__ */ jsx(
|
|
176
|
+
Box,
|
|
177
|
+
{
|
|
178
|
+
role: "tabpanel",
|
|
179
|
+
hidden: !isActive,
|
|
180
|
+
id: `${id}-panel-${tab.value}`,
|
|
181
|
+
"aria-labelledby": `${id}-tab-${tab.value}`,
|
|
182
|
+
sx: { pt: 2 },
|
|
183
|
+
children: tab.content
|
|
184
|
+
},
|
|
185
|
+
tab.value
|
|
186
|
+
);
|
|
187
|
+
})
|
|
188
|
+
] });
|
|
189
|
+
}
|
|
190
|
+
function TabPanel({ children }) {
|
|
191
|
+
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
192
|
+
}
|
|
193
|
+
function useTabs({ defaultValue = "", onChange } = {}) {
|
|
194
|
+
const [value, setValueInternal] = useState(defaultValue);
|
|
195
|
+
const setValue = useCallback(
|
|
196
|
+
(newValue) => {
|
|
197
|
+
setValueInternal(newValue);
|
|
198
|
+
onChange?.(newValue);
|
|
199
|
+
},
|
|
200
|
+
[onChange]
|
|
201
|
+
);
|
|
202
|
+
return useMemo(
|
|
203
|
+
() => ({
|
|
204
|
+
value,
|
|
205
|
+
setValue,
|
|
206
|
+
tabsProps: {
|
|
207
|
+
value,
|
|
208
|
+
onChange: setValue
|
|
209
|
+
}
|
|
210
|
+
}),
|
|
211
|
+
[value, setValue]
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
export { TabPanel, Tabs, useTabs };
|
|
216
|
+
//# sourceMappingURL=chunk-FOGY3HA4.js.map
|
|
217
|
+
//# sourceMappingURL=chunk-FOGY3HA4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/tabs/tabs.tsx"],"names":[],"mappings":"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","file":"chunk-FOGY3HA4.js","sourcesContent":["'use client';\n\n/**\n * Tabs Component\n *\n * Tabbed interface with panel support.\n *\n * @module components/tabs\n */\n\nimport type { ReactNode, ReactElement, SyntheticEvent, ComponentProps, KeyboardEvent } from 'react';\nimport { useState, useCallback, Children, isValidElement, useMemo, useId, useRef, useEffect } from 'react';\nimport MuiTabs from '@mui/material/Tabs';\nimport MuiTab from '@mui/material/Tab';\nimport Box from '@mui/material/Box';\nimport IconButton from '@mui/material/IconButton';\nimport { CloseIcon } from '../../icons/controls.js';\n\n/**\n * Tab item definition.\n */\nexport interface TabItem {\n /** Unique value for the tab */\n value: string;\n /** Tab label */\n label: string;\n /** Optional icon (must be a React element, not arbitrary ReactNode) */\n icon?: ReactElement;\n /** Tab content */\n content?: ReactNode;\n /** Disabled state */\n disabled?: boolean;\n /** Show an individual close control. Requires Tabs.onClose. */\n closable?: boolean;\n /** Disable closing without disabling selection (e.g. during a save). */\n closeDisabled?: boolean;\n /** Localized accessible name for the close control. */\n closeLabel?: string;\n}\n\n/**\n * Props for Tabs component.\n */\n// `action` clashes with MUI's imperative `action: Ref<TabsActions>` —\n// we're not exposing the imperative ref API (it's almost never used\n// in app code) and reclaim the name for the actions slot instead.\nexport interface TabsProps extends Omit<ComponentProps<typeof MuiTabs>, 'onChange' | 'value' | 'action'> {\n /** Tab items configuration */\n tabs?: TabItem[];\n /** Controlled value */\n value?: string;\n /** Default value (uncontrolled) */\n defaultValue?: string;\n /** Change handler */\n onChange?: (value: string) => void;\n /** Request closure. The caller owns confirmation, removal and controlled selection. */\n onClose?: (value: string) => void;\n /** Tab panel children (alternative to tabs prop) */\n children?: ReactNode;\n /** Keep unmounted tabs in DOM */\n keepMounted?: boolean;\n /**\n * Optional actions area rendered to the right of the tab strip\n * (e.g. a primary \"Create\" button). Mirrors the action slot on\n * `Breadcrumbs`. When set, the tab strip's bottom border moves\n * onto the surrounding flex row so the divider runs full-width\n * past the action area without breaking.\n */\n action?: ReactNode;\n}\n\n/**\n * Tabs - Tabbed interface component.\n *\n * @example\n * ```tsx\n * // Using tabs prop\n * <Tabs\n * tabs={[\n * { value: 'tab1', label: 'General', content: <GeneralSettings /> },\n * { value: 'tab2', label: 'Security', content: <SecuritySettings /> },\n * { value: 'tab3', label: 'Notifications', content: <NotificationSettings /> },\n * ]}\n * defaultValue=\"tab1\"\n * />\n *\n * // Using children\n * <Tabs defaultValue=\"overview\">\n * <TabPanel value=\"overview\" label=\"Overview\">\n * Overview content\n * </TabPanel>\n * <TabPanel value=\"details\" label=\"Details\">\n * Details content\n * </TabPanel>\n * </Tabs>\n * ```\n */\nexport function Tabs({\n tabs,\n value: controlledValue,\n defaultValue,\n onChange,\n onClose,\n children,\n keepMounted = false,\n action,\n sx,\n ...muiProps\n}: TabsProps): ReactNode {\n const [internalValue, setInternalValue] = useState(defaultValue ?? tabs?.[0]?.value ?? '');\n\n const value = controlledValue ?? internalValue;\n const id = useId();\n const tabRefs = useRef(new Map<string, HTMLElement>());\n const closing = useRef<{ value: string; next?: string } | null>(null);\n\n const handleChange = useCallback(\n (_event: SyntheticEvent, newValue: string) => {\n if (controlledValue === undefined) {\n setInternalValue(newValue);\n }\n onChange?.(newValue);\n },\n [controlledValue, onChange]\n );\n\n // Extract tab items from children if using TabPanel pattern\n const tabItems = useMemo(() => {\n if (tabs) return tabs;\n\n const items: TabItem[] = [];\n Children.forEach(children, (child) => {\n if (isValidElement(child) && child.type === TabPanel) {\n const props = child.props as TabPanelProps;\n items.push({\n value: props.value,\n label: props.label ?? props.value,\n icon: props.icon,\n content: props.children,\n disabled: props.disabled,\n closable: props.closable,\n closeDisabled: props.closeDisabled,\n closeLabel: props.closeLabel,\n });\n }\n });\n return items;\n }, [tabs, children]);\n\n const requestClose = (tab: TabItem) => {\n if (!onClose || !tab.closable || tab.disabled || tab.closeDisabled) return;\n const index = tabItems.indexOf(tab);\n const next =\n tabItems.slice(index + 1).find((item) => !item.disabled) ??\n tabItems\n .slice(0, index)\n .reverse()\n .find((item) => !item.disabled);\n closing.current = { value: tab.value, next: next?.value };\n onClose(tab.value);\n };\n\n // A confirmation may defer or cancel closure. Move focus only after removal.\n useEffect(() => {\n const pending = closing.current;\n if (!pending || tabItems.some((tab) => tab.value === pending.value)) return;\n closing.current = null;\n if (controlledValue === undefined && value === pending.value) {\n setInternalValue(pending.next ?? '');\n if (pending.next) onChange?.(pending.next);\n }\n if (pending.next) tabRefs.current.get(pending.next)?.focus();\n }, [tabItems, controlledValue, value, onChange]);\n\n // Flex wrapper exists only to host the optional action node to\n // the right of the tab strip — no bottom divider; MuiTabs keeps\n // its own active-tab indicator track and that's the only line\n // we want under the strip.\n const hasAction = action !== undefined && action !== null && action !== false;\n\n return (\n <Box sx={{ width: '100%', minWidth: 0, flexShrink: 0 }}>\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 2,\n minWidth: 0,\n }}\n >\n <MuiTabs\n value={value || false}\n onChange={handleChange}\n {...muiProps}\n sx={[{ flex: 1, minWidth: 0 }, ...(Array.isArray(sx) ? sx : [sx])]}\n >\n {tabItems.map((tab) => {\n const closable = Boolean(tab.closable && onClose);\n return (\n <MuiTab\n key={tab.value}\n ref={(element: HTMLElement | null) => {\n if (element) tabRefs.current.set(tab.value, element);\n else tabRefs.current.delete(tab.value);\n }}\n component={closable ? 'div' : 'button'}\n id={`${id}-tab-${tab.value}`}\n aria-controls={tab.content === undefined ? undefined : `${id}-panel-${tab.value}`}\n aria-label={tab.label}\n aria-keyshortcuts={closable && !tab.closeDisabled ? 'Delete' : undefined}\n value={tab.value}\n label={\n closable ? (\n <Box\n component=\"span\"\n sx={{ display: 'inline-flex', alignItems: 'center', gap: 0.5, minWidth: 0, maxWidth: '100%' }}\n >\n <Box component=\"span\" sx={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>\n {tab.label}\n </Box>\n <IconButton\n component=\"button\"\n type=\"button\"\n size=\"small\"\n tabIndex={-1}\n aria-label={tab.closeLabel ?? `Close ${tab.label}`}\n title={tab.closeLabel ?? `Close ${tab.label}`}\n disabled={tab.disabled || tab.closeDisabled}\n sx={{ p: 0.25, flexShrink: 0, color: 'text.secondary' }}\n onMouseDown={(event) => {\n event.preventDefault();\n event.stopPropagation();\n }}\n onClick={(event) => {\n event.stopPropagation();\n requestClose(tab);\n }}\n onKeyDown={(event) => event.stopPropagation()}\n >\n <CloseIcon sx={{ fontSize: 16 }} />\n </IconButton>\n </Box>\n ) : (\n tab.label\n )\n }\n icon={tab.icon}\n iconPosition=\"start\"\n disabled={tab.disabled}\n onKeyDown={(event: KeyboardEvent<HTMLElement>) => {\n if (event.key === 'Delete' && closable && !tab.closeDisabled) {\n event.preventDefault();\n event.stopPropagation();\n requestClose(tab);\n }\n }}\n />\n );\n })}\n </MuiTabs>\n {hasAction && (\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 1,\n flexShrink: 0,\n }}\n >\n {action}\n </Box>\n )}\n </Box>\n {tabItems.map((tab) => {\n const isActive = tab.value === value;\n if (!isActive && !keepMounted) return null;\n // Strip-only usage (`tabs` entries without `content`):\n // the page renders its own content below the tabs and\n // just needs the navigation strip. Skipping the panel\n // box keeps the layout flush.\n if (tab.content === undefined) return null;\n\n return (\n <Box\n key={tab.value}\n role=\"tabpanel\"\n hidden={!isActive}\n id={`${id}-panel-${tab.value}`}\n aria-labelledby={`${id}-tab-${tab.value}`}\n sx={{ pt: 2 }}\n >\n {tab.content}\n </Box>\n );\n })}\n </Box>\n );\n}\n\n/**\n * Props for TabPanel component.\n */\nexport interface TabPanelProps {\n /** Unique value (must match Tabs value) */\n value: string;\n /** Tab label */\n label?: string;\n /** Optional icon (must be a React element, not arbitrary ReactNode) */\n icon?: ReactElement;\n /** Panel content */\n children?: ReactNode;\n /** Disabled state */\n disabled?: boolean;\n closable?: boolean;\n closeDisabled?: boolean;\n closeLabel?: string;\n}\n\n/**\n * TabPanel - Individual tab panel for use with Tabs children pattern.\n *\n * @example\n * ```tsx\n * <Tabs defaultValue=\"tab1\">\n * <TabPanel value=\"tab1\" label=\"First\">\n * First panel content\n * </TabPanel>\n * <TabPanel value=\"tab2\" label=\"Second\">\n * Second panel content\n * </TabPanel>\n * </Tabs>\n * ```\n */\nexport function TabPanel({ children }: TabPanelProps): ReactNode {\n // This component is only used for configuration extraction\n // The actual rendering happens in the Tabs component\n return <>{children}</>;\n}\n\n/**\n * Hook for managing tab state externally.\n */\nexport interface UseTabsOptions {\n /** Initial tab value */\n defaultValue?: string;\n /** Callback when tab changes */\n onChange?: (value: string) => void;\n}\n\nexport interface UseTabsReturn {\n /** Current tab value */\n value: string;\n /** Set the active tab */\n setValue: (value: string) => void;\n /** Props to spread on Tabs component */\n tabsProps: {\n value: string;\n onChange: (value: string) => void;\n };\n}\n\n/**\n * useTabs - Hook for external tab state management.\n *\n * Uses proper memoization to prevent unnecessary re-renders.\n *\n * @example\n * ```tsx\n * const { tabsProps, value, setValue } = useTabs({ defaultValue: 'tab1' });\n *\n * return (\n * <>\n * <button onClick={() => setValue('tab2')}>Go to Tab 2</button>\n * <Tabs {...tabsProps} tabs={tabs} />\n * </>\n * );\n * ```\n */\nexport function useTabs({ defaultValue = '', onChange }: UseTabsOptions = {}): UseTabsReturn {\n const [value, setValueInternal] = useState(defaultValue);\n\n const setValue = useCallback(\n (newValue: string) => {\n setValueInternal(newValue);\n onChange?.(newValue);\n },\n [onChange]\n );\n\n // Memoize the return value to prevent unnecessary re-renders\n return useMemo(\n () => ({\n value,\n setValue,\n tabsProps: {\n value,\n onChange: setValue,\n },\n }),\n [value, setValue]\n );\n}\n"]}
|