@lerianstudio/sindarian-ui 2.0.0-beta.2 → 2.0.0-beta.21
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/LICENSE +93 -0
- package/README.md +52 -1
- package/dist/components/breadcrumb/index.d.ts.map +1 -1
- package/dist/components/breadcrumb/index.js +25 -1
- package/dist/components/card/account-card/index.js +5 -5
- package/dist/components/card/basic-card/index.d.ts.map +1 -1
- package/dist/components/card/basic-card/index.js +2 -2
- package/dist/components/card/entity-card/index.js +1 -1
- package/dist/components/dialog/confirmation-dialog/index.d.ts.map +1 -1
- package/dist/components/dialog/confirmation-dialog/index.js +4 -1
- package/dist/components/entity-box/index.d.ts +18 -2
- package/dist/components/entity-box/index.d.ts.map +1 -1
- package/dist/components/entity-box/index.js +32 -4
- package/dist/components/form/date-picker-field/index.js +1 -1
- package/dist/components/form/date-range-field/index.js +1 -1
- package/dist/components/form/date-time-picker-field/index.js +1 -1
- package/dist/components/form/password-field/index.d.ts +5 -1
- package/dist/components/form/password-field/index.d.ts.map +1 -1
- package/dist/components/form/password-field/index.js +2 -2
- package/dist/components/form/select-field/index.d.ts +15 -1
- package/dist/components/form/select-field/index.d.ts.map +1 -1
- package/dist/components/form/select-field/index.js +28 -3
- package/dist/components/form/switch-field/index.d.ts.map +1 -1
- package/dist/components/form/switch-field/index.js +6 -1
- package/dist/components/page/index.d.ts +35 -1
- package/dist/components/page/index.d.ts.map +1 -1
- package/dist/components/page/index.js +6 -2
- package/dist/components/page-header/index.js +1 -1
- package/dist/components/table/id-table-cell.d.ts +13 -1
- package/dist/components/table/id-table-cell.d.ts.map +1 -1
- package/dist/components/table/id-table-cell.js +99 -9
- 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 +1 -0
- package/dist/components/table/locked-table-actions.d.ts +24 -0
- package/dist/components/table/locked-table-actions.d.ts.map +1 -1
- package/dist/components/table/locked-table-actions.js +31 -1
- package/dist/components/table/name-table-cell.d.ts +57 -4
- package/dist/components/table/name-table-cell.d.ts.map +1 -1
- package/dist/components/table/name-table-cell.js +50 -2
- package/dist/components/ui/autocomplete/index.d.ts +24 -0
- package/dist/components/ui/autocomplete/index.d.ts.map +1 -1
- package/dist/components/ui/autocomplete/index.js +24 -0
- package/dist/components/ui/badge/index.d.ts +11 -7
- package/dist/components/ui/badge/index.d.ts.map +1 -1
- package/dist/components/ui/badge/index.js +20 -8
- package/dist/components/ui/button/index.d.ts +3 -3
- package/dist/components/ui/copy-field/index.d.ts +25 -1
- package/dist/components/ui/copy-field/index.d.ts.map +1 -1
- package/dist/components/ui/copy-field/index.js +16 -8
- package/dist/components/ui/dialog/index.d.ts +1 -1
- package/dist/components/ui/dialog/index.d.ts.map +1 -1
- package/dist/components/ui/dialog/index.js +2 -2
- package/dist/components/ui/file-upload/index.d.ts +159 -0
- package/dist/components/ui/file-upload/index.d.ts.map +1 -1
- package/dist/components/ui/file-upload/index.js +308 -6
- package/dist/components/ui/icon-button/index.d.ts +1 -1
- package/dist/components/ui/icon-button/styles.css +42 -0
- package/dist/components/ui/input/styles.css +79 -4
- package/dist/components/ui/lerian-wordmark/index.d.ts +6 -0
- package/dist/components/ui/lerian-wordmark/index.d.ts.map +1 -0
- package/dist/components/ui/lerian-wordmark/index.js +7 -0
- package/dist/components/ui/otp-input/index.js +1 -1
- package/dist/components/ui/radio-group/index.js +1 -1
- package/dist/components/ui/select/index.d.ts.map +1 -1
- package/dist/components/ui/select/index.js +8 -4
- package/dist/components/ui/select/styles.css +1 -1
- package/dist/components/ui/sheet/index.d.ts +42 -0
- package/dist/components/ui/sheet/index.d.ts.map +1 -1
- package/dist/components/ui/sheet/index.js +47 -14
- package/dist/components/ui/sidebar/index.d.ts +1 -0
- package/dist/components/ui/sidebar/index.d.ts.map +1 -1
- package/dist/components/ui/sidebar/index.js +1 -0
- package/dist/components/ui/sidebar/sidebar-expand-button.d.ts +1 -1
- package/dist/components/ui/sidebar/sidebar-expand-button.d.ts.map +1 -1
- package/dist/components/ui/sidebar/sidebar-expand-button.js +15 -1
- package/dist/components/ui/sidebar/sidebar-item.d.ts +1 -1
- package/dist/components/ui/sidebar/sidebar-item.d.ts.map +1 -1
- package/dist/components/ui/sidebar/sidebar-item.js +28 -4
- package/dist/components/ui/sidebar/sidebar-provider.d.ts +58 -0
- package/dist/components/ui/sidebar/sidebar-provider.d.ts.map +1 -1
- package/dist/components/ui/sidebar/sidebar-provider.js +146 -4
- package/dist/components/ui/sidebar/sidebar-root.d.ts +38 -1
- package/dist/components/ui/sidebar/sidebar-root.d.ts.map +1 -1
- package/dist/components/ui/sidebar/sidebar-root.js +111 -5
- package/dist/components/ui/sidebar/sidebar-trigger.d.ts +45 -0
- package/dist/components/ui/sidebar/sidebar-trigger.d.ts.map +1 -0
- package/dist/components/ui/sidebar/sidebar-trigger.js +57 -0
- package/dist/components/ui/textarea/index.js +1 -1
- package/dist/components/ui/toast/toaster.d.ts +5 -1
- package/dist/components/ui/toast/toaster.d.ts.map +1 -1
- package/dist/components/ui/toast/toaster.js +3 -2
- package/dist/enterprise/data-table/index.d.ts +77 -7
- package/dist/enterprise/data-table/index.d.ts.map +1 -1
- package/dist/enterprise/data-table/index.js +56 -11
- package/dist/enterprise/date-range-picker/index.js +4 -4
- package/dist/enterprise/number-input/index.d.ts.map +1 -1
- package/dist/enterprise/number-input/index.js +1 -1
- package/dist/esm/components/breadcrumb/index.d.ts.map +1 -1
- package/dist/esm/components/breadcrumb/index.js +25 -1
- package/dist/esm/components/card/account-card/index.js +5 -5
- package/dist/esm/components/card/basic-card/index.d.ts.map +1 -1
- package/dist/esm/components/card/basic-card/index.js +2 -2
- package/dist/esm/components/card/entity-card/index.js +1 -1
- package/dist/esm/components/dialog/confirmation-dialog/index.d.ts.map +1 -1
- package/dist/esm/components/dialog/confirmation-dialog/index.js +4 -1
- package/dist/esm/components/entity-box/index.d.ts +18 -2
- package/dist/esm/components/entity-box/index.d.ts.map +1 -1
- package/dist/esm/components/entity-box/index.js +29 -4
- package/dist/esm/components/form/date-picker-field/index.js +1 -1
- package/dist/esm/components/form/date-range-field/index.js +1 -1
- package/dist/esm/components/form/date-time-picker-field/index.js +1 -1
- package/dist/esm/components/form/password-field/index.d.ts +5 -1
- package/dist/esm/components/form/password-field/index.d.ts.map +1 -1
- package/dist/esm/components/form/password-field/index.js +2 -2
- package/dist/esm/components/form/select-field/index.d.ts +15 -1
- package/dist/esm/components/form/select-field/index.d.ts.map +1 -1
- package/dist/esm/components/form/select-field/index.js +29 -4
- package/dist/esm/components/form/switch-field/index.d.ts.map +1 -1
- package/dist/esm/components/form/switch-field/index.js +7 -2
- package/dist/esm/components/page/index.d.ts +35 -1
- package/dist/esm/components/page/index.d.ts.map +1 -1
- package/dist/esm/components/page/index.js +6 -2
- package/dist/esm/components/page-header/index.js +1 -1
- package/dist/esm/components/table/id-table-cell.d.ts +13 -1
- package/dist/esm/components/table/id-table-cell.d.ts.map +1 -1
- package/dist/esm/components/table/id-table-cell.js +100 -7
- package/dist/esm/components/table/index.d.ts +1 -0
- package/dist/esm/components/table/index.d.ts.map +1 -1
- package/dist/esm/components/table/index.js +1 -0
- package/dist/esm/components/table/locked-table-actions.d.ts +24 -0
- package/dist/esm/components/table/locked-table-actions.d.ts.map +1 -1
- package/dist/esm/components/table/locked-table-actions.js +31 -1
- package/dist/esm/components/table/name-table-cell.d.ts +57 -4
- package/dist/esm/components/table/name-table-cell.d.ts.map +1 -1
- package/dist/esm/components/table/name-table-cell.js +50 -2
- package/dist/esm/components/ui/autocomplete/index.d.ts +24 -0
- package/dist/esm/components/ui/autocomplete/index.d.ts.map +1 -1
- package/dist/esm/components/ui/autocomplete/index.js +24 -0
- package/dist/esm/components/ui/badge/index.d.ts +11 -7
- package/dist/esm/components/ui/badge/index.d.ts.map +1 -1
- package/dist/esm/components/ui/badge/index.js +20 -8
- package/dist/esm/components/ui/button/index.d.ts +3 -3
- package/dist/esm/components/ui/copy-field/index.d.ts +25 -1
- package/dist/esm/components/ui/copy-field/index.d.ts.map +1 -1
- package/dist/esm/components/ui/copy-field/index.js +16 -8
- package/dist/esm/components/ui/dialog/index.d.ts +1 -1
- package/dist/esm/components/ui/dialog/index.d.ts.map +1 -1
- package/dist/esm/components/ui/dialog/index.js +3 -3
- package/dist/esm/components/ui/file-upload/index.d.ts +159 -0
- package/dist/esm/components/ui/file-upload/index.d.ts.map +1 -1
- package/dist/esm/components/ui/file-upload/index.js +307 -5
- package/dist/esm/components/ui/icon-button/index.d.ts +1 -1
- package/dist/esm/components/ui/lerian-wordmark/index.d.ts +6 -0
- package/dist/esm/components/ui/lerian-wordmark/index.d.ts.map +1 -0
- package/dist/esm/components/ui/lerian-wordmark/index.js +4 -0
- package/dist/esm/components/ui/otp-input/index.js +1 -1
- package/dist/esm/components/ui/radio-group/index.js +1 -1
- package/dist/esm/components/ui/select/index.d.ts.map +1 -1
- package/dist/esm/components/ui/select/index.js +8 -4
- package/dist/esm/components/ui/sheet/index.d.ts +42 -0
- package/dist/esm/components/ui/sheet/index.d.ts.map +1 -1
- package/dist/esm/components/ui/sheet/index.js +48 -15
- package/dist/esm/components/ui/sidebar/index.d.ts +1 -0
- package/dist/esm/components/ui/sidebar/index.d.ts.map +1 -1
- package/dist/esm/components/ui/sidebar/index.js +1 -0
- package/dist/esm/components/ui/sidebar/sidebar-expand-button.d.ts +1 -1
- package/dist/esm/components/ui/sidebar/sidebar-expand-button.d.ts.map +1 -1
- package/dist/esm/components/ui/sidebar/sidebar-expand-button.js +15 -1
- package/dist/esm/components/ui/sidebar/sidebar-item.d.ts +1 -1
- package/dist/esm/components/ui/sidebar/sidebar-item.d.ts.map +1 -1
- package/dist/esm/components/ui/sidebar/sidebar-item.js +28 -4
- package/dist/esm/components/ui/sidebar/sidebar-provider.d.ts +58 -0
- package/dist/esm/components/ui/sidebar/sidebar-provider.d.ts.map +1 -1
- package/dist/esm/components/ui/sidebar/sidebar-provider.js +143 -1
- package/dist/esm/components/ui/sidebar/sidebar-root.d.ts +38 -1
- package/dist/esm/components/ui/sidebar/sidebar-root.d.ts.map +1 -1
- package/dist/esm/components/ui/sidebar/sidebar-root.js +113 -7
- package/dist/esm/components/ui/sidebar/sidebar-trigger.d.ts +45 -0
- package/dist/esm/components/ui/sidebar/sidebar-trigger.d.ts.map +1 -0
- package/dist/esm/components/ui/sidebar/sidebar-trigger.js +53 -0
- package/dist/esm/components/ui/textarea/index.js +1 -1
- package/dist/esm/components/ui/toast/toaster.d.ts +5 -1
- package/dist/esm/components/ui/toast/toaster.d.ts.map +1 -1
- package/dist/esm/components/ui/toast/toaster.js +3 -2
- package/dist/esm/enterprise/data-table/index.d.ts +77 -7
- package/dist/esm/enterprise/data-table/index.d.ts.map +1 -1
- package/dist/esm/enterprise/data-table/index.js +57 -12
- package/dist/esm/enterprise/date-range-picker/index.js +4 -4
- package/dist/esm/enterprise/number-input/index.d.ts.map +1 -1
- package/dist/esm/enterprise/number-input/index.js +1 -1
- package/dist/esm/hooks/use-toast.d.ts +18 -2
- package/dist/esm/hooks/use-toast.d.ts.map +1 -1
- package/dist/esm/hooks/use-toast.js +60 -16
- package/dist/esm/index.d.ts +3 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +3 -0
- package/dist/esm/lib/utils.d.ts +2 -0
- package/dist/esm/lib/utils.d.ts.map +1 -1
- package/dist/esm/lib/utils.js +10 -0
- package/dist/esm/toast/helpers.d.ts +13 -0
- package/dist/esm/toast/helpers.d.ts.map +1 -1
- package/dist/esm/toast/helpers.js +8 -1
- package/dist/fonts/OFL.txt +96 -0
- package/dist/fonts/ibm-plex-mono-latin-400.woff2 +0 -0
- package/dist/fonts/ibm-plex-mono-latin-500.woff2 +0 -0
- package/dist/fonts/ibm-plex-serif-latin-400.woff2 +0 -0
- package/dist/fonts/ibm-plex-serif-latin-500.woff2 +0 -0
- package/dist/fonts/inter-latin.woff2 +0 -0
- package/dist/fonts.css +46 -0
- package/dist/globals.css +62 -362
- package/dist/hooks/use-toast.d.ts +18 -2
- package/dist/hooks/use-toast.d.ts.map +1 -1
- package/dist/hooks/use-toast.js +61 -16
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/lib/utils.d.ts +2 -0
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/utils.js +11 -0
- package/dist/public/wordmark.svg +1 -0
- package/dist/standalone.css +10 -0
- package/dist/toast/helpers.d.ts +13 -0
- package/dist/toast/helpers.d.ts.map +1 -1
- package/dist/toast/helpers.js +8 -1
- package/dist/tokens.css +367 -0
- package/package.json +9 -6
|
@@ -6,19 +6,125 @@ const jsx_runtime_1 = require("react/jsx-runtime");
|
|
|
6
6
|
const class_variance_authority_1 = require("class-variance-authority");
|
|
7
7
|
const sidebar_provider_1 = require("./sidebar-provider");
|
|
8
8
|
const utils_1 = require("../../../lib/utils");
|
|
9
|
+
const sheet_1 = require("../sheet");
|
|
10
|
+
/**
|
|
11
|
+
* ⛔ THE WIDTHS ARE TOKENS, NOT LITERALS.
|
|
12
|
+
*
|
|
13
|
+
* They were `w-[72px]` and `w-[244px]`, which a consumer could only override by
|
|
14
|
+
* winning a specificity argument with `cn`. `--sidebar-width` and
|
|
15
|
+
* `--sidebar-width-collapsed` are declared in `tokens.css`, so the default
|
|
16
|
+
* still ships with the stylesheet, and a consumer re-points either one with
|
|
17
|
+
* `className="[--sidebar-width:280px]"` ON THE RAIL, which moves the rail and
|
|
18
|
+
* the mobile drawer together (see `liftWidthOverrides` below), or with a rule
|
|
19
|
+
* on `:root`/`html`.
|
|
20
|
+
*
|
|
21
|
+
* ⚠️ A DECLARATION ON A REACT-TREE ANCESTOR REACHES THE RAIL AND NOT THE
|
|
22
|
+
* DRAWER. Custom properties inherit down the DOM tree, and the drawer is
|
|
23
|
+
* portalled to `document.body`, so a layout wrapper is not an ancestor of it.
|
|
24
|
+
* `:root` is, which is why it is named above and a wrapper is not.
|
|
25
|
+
*/
|
|
9
26
|
const sidebarVariants = (0, class_variance_authority_1.cva)('group/sidebar shadow-sidebar relative flex flex-col transition-[width] duration-300 ease-in-out', {
|
|
10
27
|
variants: {
|
|
11
28
|
collapsed: {
|
|
12
|
-
true: 'w-[
|
|
13
|
-
false: 'w-[
|
|
29
|
+
true: 'w-[var(--sidebar-width-collapsed)]',
|
|
30
|
+
false: 'w-[var(--sidebar-width)]'
|
|
14
31
|
}
|
|
15
32
|
},
|
|
16
33
|
defaultVariants: {
|
|
17
34
|
collapsed: false
|
|
18
35
|
}
|
|
19
36
|
});
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
37
|
+
/**
|
|
38
|
+
* Tailwind arbitrary-property classes that re-point the sidebar geometry, e.g.
|
|
39
|
+
* `[--sidebar-width:320px]` or `[--sidebar-width-collapsed:88px]`.
|
|
40
|
+
*
|
|
41
|
+
* ⚠️ ANCHORED TO A CLASS BOUNDARY, WHICH IS THE WHOLE POINT OF THE LOOKBEHIND.
|
|
42
|
+
* Unanchored it also matched the tail of `md:[--sidebar-width:320px]` and
|
|
43
|
+
* lifted it with the prefix stripped — an override a consumer scoped to
|
|
44
|
+
* ≥768px, applied unconditionally to the drawer that only exists below it.
|
|
45
|
+
*/
|
|
46
|
+
const WIDTH_OVERRIDE = /(?<=^|\s)\[--sidebar-width(?:-collapsed)?:[^\]]+\]/g;
|
|
47
|
+
/**
|
|
48
|
+
* ⛔ THE ONE PART OF THE CONSUMER'S className THAT HAS TO CROSS THE PORTAL.
|
|
49
|
+
*
|
|
50
|
+
* `SheetContent` mounts through `SheetPortal` into `document.body`, and custom
|
|
51
|
+
* properties inherit down the DOM tree rather than the React tree. So the
|
|
52
|
+
* documented override — a class on the rail — set `--sidebar-width` on an
|
|
53
|
+
* element the drawer is not a descendant of, and the whole className that DOES
|
|
54
|
+
* travel lands on the inner `<nav>`, which is BELOW the element that reads the
|
|
55
|
+
* variable. Measured in Chromium: rail 320px, drawer 244px. Following the
|
|
56
|
+
* instruction handed to product-console produced a 280px rail on desktop and a
|
|
57
|
+
* 244px drawer on a phone, silently.
|
|
58
|
+
*
|
|
59
|
+
* ⚠️ ONLY THE GEOMETRY TOKENS. The rest of a rail className is rail-shaped —
|
|
60
|
+
* `h-full`, and the `data-[collapsed=false]:min-w-70` all eight console
|
|
61
|
+
* sidebars pass — and putting that on the sheet would reinstate the
|
|
62
|
+
* 280px-inside-a-244px-sheet overflow from the other side.
|
|
63
|
+
*/
|
|
64
|
+
function liftWidthOverrides(className) {
|
|
65
|
+
return className?.match(WIDTH_OVERRIDE)?.join(' ');
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* ⛔ BELOW 768px A RAIL IS NOT A LAYOUT — once a consumer opts in.
|
|
69
|
+
*
|
|
70
|
+
* The widths above are a fixed share of a flex row, so at 390px the expanded
|
|
71
|
+
* rail took 63% of the screen and left the page 146px, and the only affordance
|
|
72
|
+
* — `SidebarExpandButton` — shrinks it to 72px, which is still 18% and still
|
|
73
|
+
* permanently on screen. There was nothing that removed it.
|
|
74
|
+
*
|
|
75
|
+
* With `mobile="drawer"` the rail is replaced below the breakpoint by an
|
|
76
|
+
* overlay drawer. Escape, the backdrop click, the focus trap and returning
|
|
77
|
+
* focus to whatever opened it are Radix Dialog's, through the kit's own
|
|
78
|
+
* `Sheet`; none of that is re-implemented here.
|
|
79
|
+
*/
|
|
80
|
+
const SidebarRoot = ({ className, id, mobile = 'inline', mobileTitle = 'Navigation', ...props }) => {
|
|
81
|
+
const context = (0, sidebar_provider_1.useSidebar)();
|
|
82
|
+
const { isCollapsed, isMobile, openMobile, setOpenMobile, restoreDrawerFocus, sidebarId } = context;
|
|
83
|
+
if (!isMobile || mobile === 'inline') {
|
|
84
|
+
return ((0, jsx_runtime_1.jsx)("nav", { "data-slot": "sidebar-root", className: (0, utils_1.cn)(sidebarVariants({ collapsed: isCollapsed }), className), "data-collapsed": isCollapsed, ...props, id: mobile === 'drawer' ? sidebarId : id }));
|
|
85
|
+
}
|
|
86
|
+
return ((0, jsx_runtime_1.jsx)(sidebar_provider_1.SidebarContext.Provider, { value: { ...context, isCollapsed: false, isDrawer: true }, children: (0, jsx_runtime_1.jsx)(sheet_1.Sheet, { open: openMobile, onOpenChange: setOpenMobile, children: (0, jsx_runtime_1.jsxs)(sheet_1.SheetContent, { side: "left",
|
|
87
|
+
// The Sheet's own paddings are built for a form panel; a rail brings
|
|
88
|
+
// its own. `max-w-full` so a consumer widening `--sidebar-width` past
|
|
89
|
+
// the viewport still cannot push the drawer off screen. The lifted
|
|
90
|
+
// override goes LAST so it re-points the variable this element reads.
|
|
91
|
+
//
|
|
92
|
+
// ⛔ THE `max-sm:` PAIR IS NOT A DUPLICATE. `SheetContent` grew a
|
|
93
|
+
// phone step — `max-sm:w-full max-sm:px-4` — because a form panel at
|
|
94
|
+
// two fifths of a 390px screen is unreadable. A NAVIGATION drawer is
|
|
95
|
+
// the one panel that must not take it: 244px over a dimmed page is
|
|
96
|
+
// the design, and full-bleed removes the tap-outside-to-close target
|
|
97
|
+
// that every other way out of this drawer is an alternative to.
|
|
98
|
+
// tailwind-merge drops a conflicting class only when the modifiers
|
|
99
|
+
// match, so a bare `w-[…]` cannot reach `max-sm:w-full` and these two
|
|
100
|
+
// tokens are what state the exemption. Measured: without them the
|
|
101
|
+
// drawer is 390px wide with 16px of inset on a 390px phone.
|
|
102
|
+
className: (0, utils_1.cn)('w-[var(--sidebar-width)] max-w-full gap-0 p-0 max-sm:w-[var(--sidebar-width)] max-sm:p-0', liftWidthOverrides(className)), "aria-describedby": undefined,
|
|
103
|
+
// ⛔ RADIX'S OWN RESTORE GOES NOWHERE HERE. `DialogContent`
|
|
104
|
+
// preventDefaults the focus scope's restore and focuses the ref a
|
|
105
|
+
// `SheetTrigger` would have filled; this drawer is opened from provider
|
|
106
|
+
// state, so that ref is null and closing dropped focus onto `<body>`.
|
|
107
|
+
// Running first means `composeEventHandlers` skips Radix's half.
|
|
108
|
+
onCloseAutoFocus: (event) => {
|
|
109
|
+
event.preventDefault();
|
|
110
|
+
restoreDrawerFocus();
|
|
111
|
+
}, children: [(0, jsx_runtime_1.jsx)(sheet_1.SheetTitle, { className: "sr-only", children: mobileTitle }), (0, jsx_runtime_1.jsx)("nav", { "data-slot": "sidebar-root", "data-mobile": "true",
|
|
112
|
+
/* ⛔ NO `data-collapsed` HERE. The consumer className is forwarded
|
|
113
|
+
verbatim, and all eight console sidebars pass
|
|
114
|
+
`data-[collapsed=false]:min-w-70`; stamping the attribute armed
|
|
115
|
+
it, giving the navigation a 280px min-width inside a 244px sheet.
|
|
116
|
+
`min-width` resolves after `max-width`, so the sheet could not
|
|
117
|
+
claw it back and the contents were 36px wider than the drawer.
|
|
118
|
+
`data-mobile` already names this surface and a drawer is never
|
|
119
|
+
collapsed, so the attribute had nothing left to say. */
|
|
120
|
+
className: (0, utils_1.cn)(sidebarVariants({ collapsed: false }), 'h-full w-full shadow-none', className), ...props,
|
|
121
|
+
/* ⛔ AFTER THE SPREAD, AND NOT THE CALLER'S. This is the target of
|
|
122
|
+
`SidebarTrigger`'s `aria-controls` and the handle the provider
|
|
123
|
+
uses to put focus back into the navigation when the viewport
|
|
124
|
+
grows. Spread first, a caller that set `id` replaced it and left
|
|
125
|
+
a dangling `aria-controls` — which axe reports as a CRITICAL
|
|
126
|
+
`aria-valid-attr-value` — and a focus restore that lands on
|
|
127
|
+
`<body>`. Both silent. */
|
|
128
|
+
id: sidebarId })] }) }) }));
|
|
23
129
|
};
|
|
24
130
|
exports.SidebarRoot = SidebarRoot;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { IconButton } from '../icon-button';
|
|
3
|
+
export type SidebarTriggerProps = React.ComponentProps<typeof IconButton>;
|
|
4
|
+
/**
|
|
5
|
+
* The control that opens the mobile drawer.
|
|
6
|
+
*
|
|
7
|
+
* Hidden from 768px up by default, because above it the rail is already on
|
|
8
|
+
* screen and a second way to reach it is a second thing to explain; a consumer
|
|
9
|
+
* that wants it everywhere passes its own display class.
|
|
10
|
+
*
|
|
11
|
+
* ⛔ THE BREAKPOINT IS IN PIXELS, AND `md:hidden` IS NOT A SPELLING OF IT.
|
|
12
|
+
*
|
|
13
|
+
* Whether the rail became a drawer is decided by `SIDEBAR_MOBILE_QUERY`, which
|
|
14
|
+
* is `not (min-width: 768px)` — pixels. `md:` is 48rem, and rem inside a MEDIA
|
|
15
|
+
* QUERY resolves against the browser's default font size rather than anything
|
|
16
|
+
* the page declares, so the two flip at different widths the moment a reader
|
|
17
|
+
* changes that setting. At Chrome's "Small" (12px) `md:` turns over at 576px
|
|
18
|
+
* while the drawer still turns over at 768px: every window between them showed
|
|
19
|
+
* NO RAIL AND NO HAMBURGER, which is a console with no navigation at all.
|
|
20
|
+
* Measured on product-console; the band is four of this package's own fixtures
|
|
21
|
+
* in `scripts/measure-phone-shapes.mjs`. At "Very large" (20px) the same
|
|
22
|
+
* mismatch runs the other way and 768–959px drew both.
|
|
23
|
+
*
|
|
24
|
+
* `min-[768px]:hidden` is the exact complement of that query, at every font
|
|
25
|
+
* size AND at any sub-pixel precision — which is why the query next door is
|
|
26
|
+
* spelled as a negation rather than as `(max-width: 767px)`: that pair leaves
|
|
27
|
+
* the open interval (767, 768) matched by neither, and a viewport there draws
|
|
28
|
+
* the rail plus a hamburger that opens nothing.
|
|
29
|
+
*
|
|
30
|
+
* ⚠️ THE PROPERTY IS ABOUT THE TWO MEDIA DECISIONS, NOT ABOUT THE FIRST PAINT.
|
|
31
|
+
* The harness enforces one of the two and never neither or both, which holds
|
|
32
|
+
* wherever `isMobile` has been read. `isMobile` starts false on purpose — there
|
|
33
|
+
* is no viewport on the server — and is corrected in an effect, so on a phone
|
|
34
|
+
* the first painted frame shows the inline rail while this control is already
|
|
35
|
+
* on screen. That one hydration is the deliberate price of hydration safety,
|
|
36
|
+
* documented on `SidebarProvider`'s own effect, and predates this class.
|
|
37
|
+
*
|
|
38
|
+
* ⚠️ `aria-controls` IS SET ONLY WHILE THE DRAWER EXISTS. Radix unmounts the
|
|
39
|
+
* dialog content when closed, and a reference to an element that is not in the
|
|
40
|
+
* DOM is what axe-core reports as a CRITICAL `aria-valid-attr-value` — the same
|
|
41
|
+
* defect the Autocomplete panel was repaired for (console-sdk#150). A toggle
|
|
42
|
+
* with `aria-expanded="false"` and no `aria-controls` is complete on its own.
|
|
43
|
+
*/
|
|
44
|
+
export declare const SidebarTrigger: ({ className, onClick, "aria-label": ariaLabel, ...props }: SidebarTriggerProps) => React.JSX.Element;
|
|
45
|
+
//# sourceMappingURL=sidebar-trigger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sidebar-trigger.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/sidebar/sidebar-trigger.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAG3C,MAAM,MAAM,mBAAmB,GAAG,KAAK,CAAC,cAAc,CAAC,OAAO,UAAU,CAAC,CAAA;AAEzE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,eAAO,MAAM,cAAc,GAAI,2DAK5B,mBAAmB,sBAqBrB,CAAA"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.SidebarTrigger = void 0;
|
|
5
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
6
|
+
const lucide_react_1 = require("lucide-react");
|
|
7
|
+
const utils_1 = require("../../../lib/utils");
|
|
8
|
+
const icon_button_1 = require("../icon-button");
|
|
9
|
+
const sidebar_provider_1 = require("./sidebar-provider");
|
|
10
|
+
/**
|
|
11
|
+
* The control that opens the mobile drawer.
|
|
12
|
+
*
|
|
13
|
+
* Hidden from 768px up by default, because above it the rail is already on
|
|
14
|
+
* screen and a second way to reach it is a second thing to explain; a consumer
|
|
15
|
+
* that wants it everywhere passes its own display class.
|
|
16
|
+
*
|
|
17
|
+
* ⛔ THE BREAKPOINT IS IN PIXELS, AND `md:hidden` IS NOT A SPELLING OF IT.
|
|
18
|
+
*
|
|
19
|
+
* Whether the rail became a drawer is decided by `SIDEBAR_MOBILE_QUERY`, which
|
|
20
|
+
* is `not (min-width: 768px)` — pixels. `md:` is 48rem, and rem inside a MEDIA
|
|
21
|
+
* QUERY resolves against the browser's default font size rather than anything
|
|
22
|
+
* the page declares, so the two flip at different widths the moment a reader
|
|
23
|
+
* changes that setting. At Chrome's "Small" (12px) `md:` turns over at 576px
|
|
24
|
+
* while the drawer still turns over at 768px: every window between them showed
|
|
25
|
+
* NO RAIL AND NO HAMBURGER, which is a console with no navigation at all.
|
|
26
|
+
* Measured on product-console; the band is four of this package's own fixtures
|
|
27
|
+
* in `scripts/measure-phone-shapes.mjs`. At "Very large" (20px) the same
|
|
28
|
+
* mismatch runs the other way and 768–959px drew both.
|
|
29
|
+
*
|
|
30
|
+
* `min-[768px]:hidden` is the exact complement of that query, at every font
|
|
31
|
+
* size AND at any sub-pixel precision — which is why the query next door is
|
|
32
|
+
* spelled as a negation rather than as `(max-width: 767px)`: that pair leaves
|
|
33
|
+
* the open interval (767, 768) matched by neither, and a viewport there draws
|
|
34
|
+
* the rail plus a hamburger that opens nothing.
|
|
35
|
+
*
|
|
36
|
+
* ⚠️ THE PROPERTY IS ABOUT THE TWO MEDIA DECISIONS, NOT ABOUT THE FIRST PAINT.
|
|
37
|
+
* The harness enforces one of the two and never neither or both, which holds
|
|
38
|
+
* wherever `isMobile` has been read. `isMobile` starts false on purpose — there
|
|
39
|
+
* is no viewport on the server — and is corrected in an effect, so on a phone
|
|
40
|
+
* the first painted frame shows the inline rail while this control is already
|
|
41
|
+
* on screen. That one hydration is the deliberate price of hydration safety,
|
|
42
|
+
* documented on `SidebarProvider`'s own effect, and predates this class.
|
|
43
|
+
*
|
|
44
|
+
* ⚠️ `aria-controls` IS SET ONLY WHILE THE DRAWER EXISTS. Radix unmounts the
|
|
45
|
+
* dialog content when closed, and a reference to an element that is not in the
|
|
46
|
+
* DOM is what axe-core reports as a CRITICAL `aria-valid-attr-value` — the same
|
|
47
|
+
* defect the Autocomplete panel was repaired for (console-sdk#150). A toggle
|
|
48
|
+
* with `aria-expanded="false"` and no `aria-controls` is complete on its own.
|
|
49
|
+
*/
|
|
50
|
+
const SidebarTrigger = ({ className, onClick, 'aria-label': ariaLabel = 'Open navigation', ...props }) => {
|
|
51
|
+
const { openMobile, setOpenMobile, sidebarId } = (0, sidebar_provider_1.useSidebar)();
|
|
52
|
+
return ((0, jsx_runtime_1.jsx)(icon_button_1.IconButton, { type: "button", variant: "outline", "data-slot": "sidebar-trigger", "aria-label": ariaLabel, "aria-expanded": openMobile, "aria-controls": openMobile ? sidebarId : undefined, className: (0, utils_1.cn)('min-[768px]:hidden', className), onClick: (event) => {
|
|
53
|
+
onClick?.(event);
|
|
54
|
+
setOpenMobile(!openMobile);
|
|
55
|
+
}, ...props, children: (0, jsx_runtime_1.jsx)(lucide_react_1.Menu, { "aria-hidden": true }) }));
|
|
56
|
+
};
|
|
57
|
+
exports.SidebarTrigger = SidebarTrigger;
|
|
@@ -4,5 +4,5 @@ exports.Textarea = Textarea;
|
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
5
|
const utils_1 = require("../../../lib/utils");
|
|
6
6
|
function Textarea({ className, ...props }) {
|
|
7
|
-
return ((0, jsx_runtime_1.jsx)("textarea", { className: (0, utils_1.cn)('border-input bg-background ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring flex w-full rounded-md border px-3 py-2 text-base focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden', 'read-only:bg-muted read-only:cursor-default read-only:caret-transparent read-only:opacity-50 read-only:select-text read-only:focus:ring-0 read-only:focus:ring-offset-0 read-only:focus:outline-hidden', 'disabled:cursor-not-allowed disabled:opacity-50', className), ...props }));
|
|
7
|
+
return ((0, jsx_runtime_1.jsx)("textarea", { className: (0, utils_1.cn)('border-input-border bg-background ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring flex w-full rounded-md border px-3 py-2 text-base focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden', 'read-only:bg-muted read-only:cursor-default read-only:caret-transparent read-only:opacity-50 read-only:select-text read-only:focus:ring-0 read-only:focus:ring-offset-0 read-only:focus:outline-hidden', 'disabled:cursor-not-allowed disabled:opacity-50', className), ...props }));
|
|
8
8
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { ComponentProps } from 'react';
|
|
2
|
+
import { Toaster as SonnerToaster } from 'sonner';
|
|
1
3
|
type ToasterProps = {
|
|
2
4
|
/**
|
|
3
5
|
* Forces the toast theme. Omit it inside a `ThemeProvider` to follow the
|
|
@@ -5,7 +7,9 @@ type ToasterProps = {
|
|
|
5
7
|
* leaving the light/dark call to sonner's own media query.
|
|
6
8
|
*/
|
|
7
9
|
theme?: 'light' | 'dark' | 'system';
|
|
10
|
+
/** Where the toast stack sits on screen. Defaults to `'bottom-right'`. */
|
|
11
|
+
position?: ComponentProps<typeof SonnerToaster>['position'];
|
|
8
12
|
};
|
|
9
|
-
export declare function Toaster({ theme }: ToasterProps): import("react").JSX.Element;
|
|
13
|
+
export declare function Toaster({ theme, position }: ToasterProps): import("react").JSX.Element;
|
|
10
14
|
export {};
|
|
11
15
|
//# sourceMappingURL=toaster.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toaster.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/toast/toaster.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"toaster.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/toast/toaster.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAA;AAC3C,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,QAAQ,CAAA;AAKjD,KAAK,YAAY,GAAG;IAClB;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAA;IACnC,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,cAAc,CAAC,OAAO,aAAa,CAAC,CAAC,UAAU,CAAC,CAAA;CAC5D,CAAA;AAED,wBAAgB,OAAO,CAAC,EAAE,KAAK,EAAE,QAAyB,EAAE,EAAE,YAAY,+BAqBzE"}
|
|
@@ -4,12 +4,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
4
4
|
exports.Toaster = Toaster;
|
|
5
5
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
6
6
|
const sonner_1 = require("sonner");
|
|
7
|
+
const use_toast_1 = require("../../../hooks/use-toast");
|
|
7
8
|
const theme_provider_1 = require("../../../theme/theme-provider");
|
|
8
|
-
function Toaster({ theme }) {
|
|
9
|
+
function Toaster({ theme, position = 'bottom-right' }) {
|
|
9
10
|
// Optional read: a Toaster mounted outside any ThemeProvider must still
|
|
10
11
|
// render, so this cannot go through `useTheme`, which throws.
|
|
11
12
|
const themeContext = (0, theme_provider_1.useOptionalTheme)();
|
|
12
|
-
return ((0, jsx_runtime_1.jsx)(sonner_1.Toaster, { theme: theme ?? themeContext?.resolvedTheme ?? 'system', position:
|
|
13
|
+
return ((0, jsx_runtime_1.jsx)(sonner_1.Toaster, { theme: theme ?? themeContext?.resolvedTheme ?? 'system', position: position, visibleToasts: 3, duration: use_toast_1.DEFAULT_DURATION, expand: false, closeButton: true, richColors: false, offset: 16, gap: 8, toastOptions: {
|
|
13
14
|
className: 'font-sans !text-sm !font-medium'
|
|
14
15
|
} }));
|
|
15
16
|
}
|
|
@@ -1,13 +1,53 @@
|
|
|
1
|
-
import { type ColumnDef, type OnChangeFn, type RowData, type RowSelectionState, type SortingState } from '@tanstack/react-table';
|
|
1
|
+
import { type ColumnDef, type OnChangeFn, type RowData, type RowSelectionState, type SortingState, type VisibilityState } from '@tanstack/react-table';
|
|
2
2
|
import { type EmptyStateProps } from '../empty-state';
|
|
3
3
|
/**
|
|
4
|
-
* Per-column
|
|
5
|
-
*
|
|
6
|
-
* its
|
|
4
|
+
* Per-column channel into the cells DataTable renders on the consumer's behalf:
|
|
5
|
+
* how a column aligns, what classes it carries on head and body, and whether it
|
|
6
|
+
* renders its own `<td>` at all. The member names are frozen by plan
|
|
7
|
+
* 2026-09-21-console-simplification C9.
|
|
7
8
|
*/
|
|
8
9
|
declare module '@tanstack/react-table' {
|
|
9
10
|
interface ColumnMeta<TData extends RowData, TValue> {
|
|
11
|
+
/**
|
|
12
|
+
* Ledger numeric treatment: right-aligns the header and its body cells and
|
|
13
|
+
* gives the body mono tabular figures. `align` overrides the alignment half
|
|
14
|
+
* on its own — the figures stay mono.
|
|
15
|
+
*/
|
|
10
16
|
numeric?: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Column alignment, header and body. Beats `numeric`'s implicit right, so a
|
|
19
|
+
* money column can read left or centre without losing its figure treatment.
|
|
20
|
+
* With `renderOwnCell` it reaches the header only — the body cell is the
|
|
21
|
+
* consumer's, and so is aligning it.
|
|
22
|
+
*/
|
|
23
|
+
align?: 'left' | 'right' | 'center';
|
|
24
|
+
/**
|
|
25
|
+
* Extra classes on this column's `<th>`, merged AFTER the table-level
|
|
26
|
+
* `headClassName` so one column can override what the table set for all.
|
|
27
|
+
*/
|
|
28
|
+
headerClassName?: string;
|
|
29
|
+
/**
|
|
30
|
+
* Extra classes on this column's body `<td>`, merged after the numeric and
|
|
31
|
+
* density treatments. IGNORED when `renderOwnCell` is set: there is no cell
|
|
32
|
+
* of the table's left to carry them. Use `headerClassName` for the `<th>`,
|
|
33
|
+
* which the table still owns either way.
|
|
34
|
+
*/
|
|
35
|
+
className?: string;
|
|
36
|
+
/**
|
|
37
|
+
* The column's `cell` renderer emits its own `<td>`; DataTable renders it
|
|
38
|
+
* bare rather than wrapping it. The HEADER is still the table's `<th>` —
|
|
39
|
+
* nothing about owning a body cell makes a column own its header, and a
|
|
40
|
+
* table whose head and body disagree on cell count is broken markup.
|
|
41
|
+
*
|
|
42
|
+
* So the split is by element, not by column: the head still takes `align`,
|
|
43
|
+
* `numeric`, `headerClassName` and the declared width, because the `<th>`
|
|
44
|
+
* is the table's to style; the BODY takes none of them, because the `<td>`
|
|
45
|
+
* is the consumer's. A money column declaring `align: 'right'` therefore
|
|
46
|
+
* gets a right-aligned header and must right-align its own cell to match —
|
|
47
|
+
* leave the cell's alignment out and the figures sit under a heading that
|
|
48
|
+
* points somewhere else.
|
|
49
|
+
*/
|
|
50
|
+
renderOwnCell?: boolean;
|
|
11
51
|
}
|
|
12
52
|
}
|
|
13
53
|
/**
|
|
@@ -71,6 +111,35 @@ type SortingProps = {
|
|
|
71
111
|
/** Controlled sort updater (TanStack `OnChangeFn`). */
|
|
72
112
|
onSortingChange: OnChangeFn<SortingState>;
|
|
73
113
|
};
|
|
114
|
+
/**
|
|
115
|
+
* Column visibility is controlled but, deliberately, NOT a required pair — a
|
|
116
|
+
* departure from the two unions above, and not drift. Those two are unions
|
|
117
|
+
* because each has an `enable*` flag whose "on" state is meaningless without
|
|
118
|
+
* the controlled pair. TanStack has no enable flag for visibility: the model is
|
|
119
|
+
* always running, and the only shipped consumer passes STATE WITH NO UPDATER,
|
|
120
|
+
* because a separate dropdown owns the state on the page. Requiring the pair
|
|
121
|
+
* would refuse that usage.
|
|
122
|
+
*
|
|
123
|
+
* What the union does forbid is the updater ALONE: TanStack reads an
|
|
124
|
+
* `on[State]Change` callback as a declaration of controlled state, so a
|
|
125
|
+
* callback with no `columnVisibility` freezes visibility at its initial value
|
|
126
|
+
* while the callback keeps firing. Prop names frozen by plan
|
|
127
|
+
* 2026-09-21-console-simplification C9.
|
|
128
|
+
*
|
|
129
|
+
* Omit both and the table keeps its own visibility state, exactly as before.
|
|
130
|
+
*/
|
|
131
|
+
type ColumnVisibilityProps = {
|
|
132
|
+
/** Controlled column-visibility state (TanStack `VisibilityState`). */
|
|
133
|
+
columnVisibility: VisibilityState;
|
|
134
|
+
/**
|
|
135
|
+
* Controlled updater (TanStack `OnChangeFn`). Optional: a consumer may
|
|
136
|
+
* drive the state from outside the table entirely.
|
|
137
|
+
*/
|
|
138
|
+
onColumnVisibilityChange?: OnChangeFn<VisibilityState>;
|
|
139
|
+
} | {
|
|
140
|
+
columnVisibility?: undefined;
|
|
141
|
+
onColumnVisibilityChange?: undefined;
|
|
142
|
+
};
|
|
74
143
|
type DataTableBaseProps<TData> = {
|
|
75
144
|
columns: ColumnDef<TData, unknown>[];
|
|
76
145
|
data: TData[];
|
|
@@ -117,7 +186,8 @@ type DataTableBaseProps<TData> = {
|
|
|
117
186
|
/**
|
|
118
187
|
* Extra classes merged onto every header cell, after the kit label voice —
|
|
119
188
|
* so a caller can override the voice's size/tracking/color for one table
|
|
120
|
-
* without restating the cluster. Per
|
|
189
|
+
* without restating the cluster. Per column, `meta.headerClassName` merges
|
|
190
|
+
* after this one and `meta.align` / `meta.numeric` own the alignment.
|
|
121
191
|
*/
|
|
122
192
|
headClassName?: string;
|
|
123
193
|
/**
|
|
@@ -127,7 +197,7 @@ type DataTableBaseProps<TData> = {
|
|
|
127
197
|
*/
|
|
128
198
|
footer?: React.ReactNode;
|
|
129
199
|
};
|
|
130
|
-
export type DataTableProps<TData> = DataTableBaseProps<TData> & RowSelectionProps<TData> & SortingProps;
|
|
131
|
-
export declare function DataTable<TData>({ columns, data, loading, skeletonRows, loadingLabel, empty, getRowId, flush, density, enableRowSelection, rowSelection, onRowSelectionChange, getRowSelectionLabel, enableSorting, sorting, onSortingChange, onRowActivate, rowHref, className, headClassName, footer }: DataTableProps<TData>): import("react").JSX.Element;
|
|
200
|
+
export type DataTableProps<TData> = DataTableBaseProps<TData> & RowSelectionProps<TData> & SortingProps & ColumnVisibilityProps;
|
|
201
|
+
export declare function DataTable<TData>({ columns, data, loading, skeletonRows, loadingLabel, empty, getRowId, flush, density, enableRowSelection, rowSelection, onRowSelectionChange, getRowSelectionLabel, enableSorting, sorting, onSortingChange, columnVisibility, onColumnVisibilityChange, onRowActivate, rowHref, className, headClassName, footer }: DataTableProps<TData>): import("react").JSX.Element;
|
|
132
202
|
export {};
|
|
133
203
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/enterprise/data-table/index.tsx"],"names":[],"mappings":"AAuDA,OAAO,EAKL,KAAK,SAAS,EACd,KAAK,UAAU,EAEf,KAAK,OAAO,EACZ,KAAK,iBAAiB,EACtB,KAAK,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/enterprise/data-table/index.tsx"],"names":[],"mappings":"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"}
|
|
@@ -65,8 +65,21 @@ const empty_state_1 = require("../empty-state");
|
|
|
65
65
|
const column_size_1 = require("./column-size");
|
|
66
66
|
const SELECTION_COLUMN_ID = '__select__';
|
|
67
67
|
const CHECKBOX_CLASS = 'accent-primary block size-4';
|
|
68
|
-
/**
|
|
69
|
-
|
|
68
|
+
/** Figure treatment for `meta: { numeric: true }` columns; the alignment half
|
|
69
|
+
* lives in ALIGN_CELL_CLASS so `meta.align` can override one without the other. */
|
|
70
|
+
const NUMERIC_FIGURE_CLASS = 'font-mono tabular-nums';
|
|
71
|
+
/**
|
|
72
|
+
* Body-cell alignment, one class per direction rather than a single string with
|
|
73
|
+
* `text-right` baked in: an explicit `meta.align` has to beat `numeric` by
|
|
74
|
+
* choosing the class, not by out-ordering it — tailwind-merge resolving two
|
|
75
|
+
* conflicting alignment utilities by source order is not a contract worth
|
|
76
|
+
* relying on.
|
|
77
|
+
*/
|
|
78
|
+
const ALIGN_CELL_CLASS = {
|
|
79
|
+
left: 'text-left',
|
|
80
|
+
center: 'text-center',
|
|
81
|
+
right: 'text-right'
|
|
82
|
+
};
|
|
70
83
|
/**
|
|
71
84
|
* Keydown events whose target sits inside one of these are never hijacked
|
|
72
85
|
* by the row-level keyboard handler — Space in a checkbox and Enter on an
|
|
@@ -116,7 +129,7 @@ function createSelectionColumn(getLabel) {
|
|
|
116
129
|
cell: ({ row }) => (0, jsx_runtime_1.jsx)(RowSelectionCheckbox, { row: row, getLabel: getLabel })
|
|
117
130
|
};
|
|
118
131
|
}
|
|
119
|
-
function DataTable({ columns, data, loading = false, skeletonRows = 8, loadingLabel = 'Loading table rows', empty, getRowId, flush = false, density = 'comfortable', enableRowSelection = false, rowSelection, onRowSelectionChange, getRowSelectionLabel, enableSorting = false, sorting, onSortingChange, onRowActivate, rowHref, className, headClassName, footer }) {
|
|
132
|
+
function DataTable({ columns, data, loading = false, skeletonRows = 8, loadingLabel = 'Loading table rows', empty, getRowId, flush = false, density = 'comfortable', enableRowSelection = false, rowSelection, onRowSelectionChange, getRowSelectionLabel, enableSorting = false, sorting, onSortingChange, columnVisibility, onColumnVisibilityChange, onRowActivate, rowHref, className, headClassName, footer }) {
|
|
120
133
|
const tableColumns = (0, react_1.useMemo)(() => enableRowSelection
|
|
121
134
|
? [createSelectionColumn(getRowSelectionLabel), ...columns]
|
|
122
135
|
: columns, [columns, enableRowSelection, getRowSelectionLabel]);
|
|
@@ -142,12 +155,33 @@ function DataTable({ columns, data, loading = false, skeletonRows = 8, loadingLa
|
|
|
142
155
|
manualSorting: true,
|
|
143
156
|
enableSorting,
|
|
144
157
|
onSortingChange: enableSorting ? onSortingChange : undefined,
|
|
158
|
+
// ⛔ EACH VISIBILITY ENTRY IS GUARDED ON ITS OWN PROP, NEVER ON THE OTHER.
|
|
159
|
+
//
|
|
160
|
+
// TanStack merges options as `{...defaultOptions, ...options}` and state as
|
|
161
|
+
// `{...internalState, ...options.state}`, both plain spreads — so a key
|
|
162
|
+
// present and holding `undefined` OVERWRITES what it was meant to leave
|
|
163
|
+
// alone. `onColumnVisibilityChange: undefined` replaces the feature's own
|
|
164
|
+
// `makeStateUpdater`, and `setColumnVisibility` reads
|
|
165
|
+
// `options.onColumnVisibilityChange == null ? void 0 : ...`, so it (and
|
|
166
|
+
// every `column.toggleVisibility` behind it) becomes a silent no-op.
|
|
167
|
+
// `columnVisibility: undefined` replaces the table's initial `{}`, so a
|
|
168
|
+
// consumer reading the slice gets `undefined` instead of an empty object.
|
|
169
|
+
//
|
|
170
|
+
// Guarding the UPDATER on the STATE put that `undefined` back for the
|
|
171
|
+
// union's first arm — state with no updater, which is the shipped console
|
|
172
|
+
// usage, where a separate dropdown owns the state. A table that passes
|
|
173
|
+
// neither prop is uncontrolled, exactly as before.
|
|
174
|
+
...(onColumnVisibilityChange !== undefined && { onColumnVisibilityChange }),
|
|
145
175
|
state: {
|
|
146
176
|
rowSelection: enableRowSelection ? (rowSelection ?? {}) : undefined,
|
|
147
|
-
sorting: enableSorting ? (sorting ?? []) : undefined
|
|
177
|
+
sorting: enableSorting ? (sorting ?? []) : undefined,
|
|
178
|
+
...(columnVisibility !== undefined && { columnVisibility })
|
|
148
179
|
}
|
|
149
180
|
});
|
|
150
|
-
|
|
181
|
+
// Visible, not declared: the skeleton grid and the empty row's colSpan have
|
|
182
|
+
// to match the header the table actually rendered, and a hidden column is in
|
|
183
|
+
// `tableColumns` but in no `<th>`.
|
|
184
|
+
const colCount = table.getVisibleLeafColumns().length;
|
|
151
185
|
const dataRows = table.getRowModel().rows;
|
|
152
186
|
const rowCount = dataRows.length;
|
|
153
187
|
// Compact density overrides only THIS table's cell padding (tailwind-merge
|
|
@@ -265,13 +299,13 @@ function DataTable({ columns, data, loading = false, skeletonRows = 8, loadingLa
|
|
|
265
299
|
: rowCount === 0
|
|
266
300
|
? 'No rows'
|
|
267
301
|
: `${rowCount} rows` }), (0, jsx_runtime_1.jsxs)(table_1.Table, { "aria-busy": loading ? 'true' : undefined, children: [(0, jsx_runtime_1.jsx)(table_1.TableHeader, { children: table.getHeaderGroups().map((headerGroup) => ((0, jsx_runtime_1.jsx)(table_1.TableRow, { className: "hover:bg-transparent", children: headerGroup.headers.map((header) => {
|
|
268
|
-
const
|
|
269
|
-
return ((0, jsx_runtime_1.jsx)(table_1.TableHead, { align: numeric ? 'right' : undefined, "aria-sort": header.isPlaceholder
|
|
302
|
+
const meta = header.column.columnDef.meta;
|
|
303
|
+
return ((0, jsx_runtime_1.jsx)(table_1.TableHead, { align: meta?.align ?? (meta?.numeric ? 'right' : undefined), "aria-sort": header.isPlaceholder
|
|
270
304
|
? undefined
|
|
271
305
|
: ariaSortFor(header.column),
|
|
272
306
|
// Only a column that DECLARED sizing gets an inline width;
|
|
273
307
|
// everything else keeps the auto table layout it has today.
|
|
274
|
-
style: (0, column_size_1.readPreferredColumnSize)(header.column), className: (0, utils_1.cn)(typography_1.LABEL_VOICE_CLASS, headDensityClass, header.column.id === SELECTION_COLUMN_ID && 'w-10', headClassName), children: header.isPlaceholder
|
|
308
|
+
style: (0, column_size_1.readPreferredColumnSize)(header.column), className: (0, utils_1.cn)(typography_1.LABEL_VOICE_CLASS, headDensityClass, header.column.id === SELECTION_COLUMN_ID && 'w-10', headClassName, meta?.headerClassName), children: header.isPlaceholder
|
|
275
309
|
? null
|
|
276
310
|
: (0, react_table_1.flexRender)(header.column.columnDef.header, header.getContext()) }, header.id));
|
|
277
311
|
}) }, headerGroup.id))) }), (0, jsx_runtime_1.jsx)(table_1.TableBody, { children: loading ? (Array.from({ length: skeletonRows }).map((_, rowIndex) => ((0, jsx_runtime_1.jsx)(table_1.TableRow, { className: "hover:bg-transparent", children: Array.from({ length: colCount }).map((__, cellIndex) => ((0, jsx_runtime_1.jsx)(table_1.TableCell, { className: cellDensityClass, children: (0, jsx_runtime_1.jsx)(skeleton_1.Skeleton, { className: "h-4 w-full max-w-[160px]" }) }, `skeleton-${rowIndex}-${cellIndex}`))) }, `skeleton-${rowIndex}`)))) : rowCount === 0 ? ((0, jsx_runtime_1.jsx)(table_1.TableRow, { className: "hover:bg-transparent", children: (0, jsx_runtime_1.jsx)(table_1.TableCell, { colSpan: colCount, className: "p-0", children: (0, jsx_runtime_1.jsx)(empty_state_1.EmptyState, { title: empty?.title ?? 'Nothing here yet', description: empty?.description, icon: empty?.icon, action: empty?.action,
|
|
@@ -294,7 +328,18 @@ function DataTable({ columns, data, loading = false, skeletonRows = 8, loadingLa
|
|
|
294
328
|
? (event) => handleRowKeyDown(event, row, rowIndex)
|
|
295
329
|
: undefined, className: keyboardNav ? ROW_FOCUS_CLASS : undefined, "data-state": enableRowSelection && row.getIsSelected()
|
|
296
330
|
? 'selected'
|
|
297
|
-
: undefined, children: row.getVisibleCells().map((cell) =>
|
|
298
|
-
|
|
299
|
-
|
|
331
|
+
: undefined, children: row.getVisibleCells().map((cell) => {
|
|
332
|
+
const meta = cell.column.columnDef.meta;
|
|
333
|
+
const content = (0, react_table_1.flexRender)(cell.column.columnDef.cell, cell.getContext());
|
|
334
|
+
// The column owns its `<td>`: render the consumer's cell bare.
|
|
335
|
+
// The kit's selection column is built here and carries no
|
|
336
|
+
// meta, so it can never take this path.
|
|
337
|
+
if (meta?.renderOwnCell) {
|
|
338
|
+
return (0, jsx_runtime_1.jsx)(react_1.Fragment, { children: content }, cell.id);
|
|
339
|
+
}
|
|
340
|
+
const align = meta?.align ?? (meta?.numeric ? 'right' : undefined);
|
|
341
|
+
return ((0, jsx_runtime_1.jsx)(table_1.TableCell, { style: (0, column_size_1.readPreferredColumnSize)(cell.column), className: (0, utils_1.cn)(meta?.numeric && NUMERIC_FIGURE_CLASS, align && ALIGN_CELL_CLASS[align], cellDensityClass, cell.column.id === SELECTION_COLUMN_ID && 'w-10', meta?.className), onClick: cell.column.id === SELECTION_COLUMN_ID
|
|
342
|
+
? stopPropagation
|
|
343
|
+
: undefined, children: content }, cell.id));
|
|
344
|
+
}) }, row.id)))) }), footer ? (0, jsx_runtime_1.jsx)(table_1.TableFooter, { children: footer }) : null] })] }));
|
|
300
345
|
}
|
|
@@ -92,12 +92,12 @@ function DateRangePicker({ value, onValueChange, fromId, toId, fromLabel, toLabe
|
|
|
92
92
|
});
|
|
93
93
|
};
|
|
94
94
|
const triggerClass = (0, utils_1.cn)(
|
|
95
|
-
// border-
|
|
96
|
-
// white in the light theme, so the trigger had no visible edge next to
|
|
97
|
-
// Input and Select it sits with. font-sans, not font-mono: the dates are
|
|
95
|
+
// border-input-border, not border-input: `--input` is a SURFACE token and
|
|
96
|
+
// is white in the light theme, so the trigger had no visible edge next to
|
|
97
|
+
// the Input and Select it sits with. font-sans, not font-mono: the dates are
|
|
98
98
|
// figures in the body face with tabular figures, like every other figure in
|
|
99
99
|
// the console.
|
|
100
|
-
'border-
|
|
100
|
+
'border-input-border bg-card hover:bg-secondary focus-visible:ring-ring flex h-9 items-center gap-2 rounded-md border px-3 text-left font-sans text-sm tabular-nums transition-colors duration-150 ease-out focus-visible:ring-2 focus-visible:ring-offset-1 focus-visible:outline-none sm:w-40', invalid && 'border-destructive',
|
|
101
101
|
// Conditional rather than `disabled:` variants, matching how this file
|
|
102
102
|
// already applies `border-destructive`: with the prop absent the class
|
|
103
103
|
// string stays byte-identical to what consumers render today.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/enterprise/number-input/index.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAQ9B,MAAM,MAAM,gBAAgB,GAAG;IAC7B,wDAAwD;IACxD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,+EAA+E;IAC/E,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAA;IAC5C,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,wCAAwC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,kEAAkE;IAClE,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,8CAA8C;IAC9C,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,sDAAsD;IACtD,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAA;AAmED;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAgBpE;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAMxE;AAED,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,aAAa,EACb,GAAG,EACH,GAAG,EACH,IAAQ,EACR,SAAS,EACT,MAAM,EACN,QAAgB,EAChB,EAAE,EACF,SAAS,EACT,WAAW,EACX,YAAY,EAAE,SAAS,EACvB,kBAAkB,EAAE,eAAe,EACpC,EAAE,gBAAgB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/enterprise/number-input/index.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAQ9B,MAAM,MAAM,gBAAgB,GAAG;IAC7B,wDAAwD;IACxD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,+EAA+E;IAC/E,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAA;IAC5C,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,wCAAwC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,kEAAkE;IAClE,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,8CAA8C;IAC9C,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,sDAAsD;IACtD,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAA;AAmED;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAgBpE;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAMxE;AAED,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,aAAa,EACb,GAAG,EACH,GAAG,EACH,IAAQ,EACR,SAAS,EACT,MAAM,EACN,QAAgB,EAChB,EAAE,EACF,SAAS,EACT,WAAW,EACX,YAAY,EAAE,SAAS,EACvB,kBAAkB,EAAE,eAAe,EACpC,EAAE,gBAAgB,qBA2JlB"}
|
|
@@ -248,5 +248,5 @@ function NumberInput({ value, onValueChange, min, max, step = 1, precision, loca
|
|
|
248
248
|
};
|
|
249
249
|
const atMin = typeof min === 'number' && value !== null && value <= min;
|
|
250
250
|
const atMax = typeof max === 'number' && value !== null && value >= max;
|
|
251
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: (0, utils_1.cn)('inline-flex items-stretch gap-1', className), children: [(0, jsx_runtime_1.jsx)(icon_button_1.IconButton, { type: "button", variant: "outline", disabled: disabled || atMin, "aria-label": `Decrease${ariaLabel ? ` ${ariaLabel}` : ''}`, onClick: () => stepBy(-1), tabIndex: -1, children: (0, jsx_runtime_1.jsx)(lucide_react_1.Minus, { className: "size-4", "aria-hidden": true }) }), (0, jsx_runtime_1.jsx)("div", { className: "w-28", children: (0, jsx_runtime_1.jsx)(input_1.Input, { id: id, inputMode: "decimal", role: "spinbutton", "aria-valuenow": value ?? undefined, "aria-valuemin": min, "aria-valuemax": max, className: "text-right tabular-nums", value: displayValue, placeholder: placeholder, disabled: disabled, "aria-label": ariaLabel, "aria-describedby": ariaDescribedBy, onChange: onChange, onKeyDown: onKeyDown, onFocus: onFocus, onBlur: onBlur }) }), (0, jsx_runtime_1.jsx)(icon_button_1.IconButton, { type: "button", variant: "outline", disabled: disabled || atMax, "aria-label": `Increase${ariaLabel ? ` ${ariaLabel}` : ''}`, onClick: () => stepBy(1), tabIndex: -1, children: (0, jsx_runtime_1.jsx)(lucide_react_1.Plus, { className: "size-4", "aria-hidden": true }) })] }));
|
|
251
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: (0, utils_1.cn)('inline-flex items-stretch gap-1', className), children: [(0, jsx_runtime_1.jsx)(icon_button_1.IconButton, { className: "shrink-0", type: "button", variant: "outline", disabled: disabled || atMin, "aria-label": `Decrease${ariaLabel ? ` ${ariaLabel}` : ''}`, onClick: () => stepBy(-1), tabIndex: -1, children: (0, jsx_runtime_1.jsx)(lucide_react_1.Minus, { className: "size-4", "aria-hidden": true }) }), (0, jsx_runtime_1.jsx)("div", { className: "w-28 min-w-0", children: (0, jsx_runtime_1.jsx)(input_1.Input, { id: id, inputMode: "decimal", role: "spinbutton", "aria-valuenow": value ?? undefined, "aria-valuemin": min, "aria-valuemax": max, className: "text-right tabular-nums", value: displayValue, placeholder: placeholder, disabled: disabled, "aria-label": ariaLabel, "aria-describedby": ariaDescribedBy, onChange: onChange, onKeyDown: onKeyDown, onFocus: onFocus, onBlur: onBlur }) }), (0, jsx_runtime_1.jsx)(icon_button_1.IconButton, { className: "shrink-0", type: "button", variant: "outline", disabled: disabled || atMax, "aria-label": `Increase${ariaLabel ? ` ${ariaLabel}` : ''}`, onClick: () => stepBy(1), tabIndex: -1, children: (0, jsx_runtime_1.jsx)(lucide_react_1.Plus, { className: "size-4", "aria-hidden": true }) })] }));
|
|
252
252
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/breadcrumb/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAUzB,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;CACd,CAAA;AAED,KAAK,eAAe,GAAG;IACrB,KAAK,EAAE,cAAc,EAAE,CAAA;CACxB,CAAA;AAED,eAAO,MAAM,UAAU,GAAI,WAAW,eAAe,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/breadcrumb/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAUzB,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;CACd,CAAA;AAED,KAAK,eAAe,GAAG;IACrB,KAAK,EAAE,cAAc,EAAE,CAAA;CACxB,CAAA;AAED,eAAO,MAAM,UAAU,GAAI,WAAW,eAAe,sBAmDpD,CAAA"}
|
|
@@ -2,5 +2,29 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { Breadcrumb as BaseBreadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator } from '../../components/ui/breadcrumb/index.js';
|
|
4
4
|
export const Breadcrumb = ({ paths }) => {
|
|
5
|
-
|
|
5
|
+
const last = paths.length - 1;
|
|
6
|
+
return (_jsx(BaseBreadcrumb, { children: _jsx(BreadcrumbList, { children: paths.map((path, index) => {
|
|
7
|
+
/**
|
|
8
|
+
* ⛔ THE LAST CRUMB IS THE PAGE, whatever the caller passed.
|
|
9
|
+
*
|
|
10
|
+
* The page marker used to be a side effect of the caller omitting
|
|
11
|
+
* `href`, and nothing in `getBreadcrumbPaths` makes the last entry
|
|
12
|
+
* omit one. A trail whose final entry carried an href therefore had
|
|
13
|
+
* no `aria-current="page"` anywhere — a screen reader could not tell
|
|
14
|
+
* which of three links was the page being read — and the crumb was a
|
|
15
|
+
* live link back to the page the reader is already on.
|
|
16
|
+
*
|
|
17
|
+
* ⚠️ AND AN HREF-LESS ANCESTOR IS NOT A SWITCHED-OFF LINK. It used
|
|
18
|
+
* to reach `BreadcrumbPage` too, which hard-codes `role="link"
|
|
19
|
+
* aria-disabled="true"` — the right shape for the page you are ON,
|
|
20
|
+
* a destination that exists and simply is not navigable from here.
|
|
21
|
+
* An ancestor with no href is a grouping label: there is no page
|
|
22
|
+
* behind it, so "Settings, link, dimmed" told the reader a
|
|
23
|
+
* destination was unavailable to them rather than that it was never
|
|
24
|
+
* a destination, and inflated the link count of the trail. It is
|
|
25
|
+
* plain text now, and only the last crumb is the page.
|
|
26
|
+
*/
|
|
27
|
+
const isLast = index === last;
|
|
28
|
+
return (_jsxs(React.Fragment, { children: [_jsx(BreadcrumbItem, { children: path.href && !isLast ? (_jsx(BreadcrumbLink, { href: path.href, children: path.name })) : isLast ? (_jsx(BreadcrumbPage, { children: path.name })) : (_jsx("span", { className: "breadcrumb-page", children: path.name })) }), !isLast && _jsx(BreadcrumbSeparator, {})] }, index));
|
|
29
|
+
}) }) }));
|
|
6
30
|
};
|