@mindlogic-ai/logician-ui 5.0.0-alpha.12 → 5.0.0-alpha.14
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 +1 -0
- package/dist/components/NavList/NavList.d.ts +35 -0
- package/dist/components/NavList/NavList.d.ts.map +1 -0
- package/dist/components/NavList/NavList.js +113 -0
- package/dist/components/NavList/NavList.js.map +1 -0
- package/dist/components/NavList/NavList.mjs +111 -0
- package/dist/components/NavList/NavList.mjs.map +1 -0
- package/dist/components/NavList/NavList.styles.d.ts +90 -0
- package/dist/components/NavList/NavList.styles.d.ts.map +1 -0
- package/dist/components/NavList/NavList.styles.js +104 -0
- package/dist/components/NavList/NavList.styles.js.map +1 -0
- package/dist/components/NavList/NavList.styles.mjs +97 -0
- package/dist/components/NavList/NavList.styles.mjs.map +1 -0
- package/dist/components/NavList/NavList.translations.json.js +19 -0
- package/dist/components/NavList/NavList.translations.json.js.map +1 -0
- package/dist/components/NavList/NavList.translations.json.mjs +14 -0
- package/dist/components/NavList/NavList.translations.json.mjs.map +1 -0
- package/dist/components/NavList/NavList.types.d.ts +140 -0
- package/dist/components/NavList/NavList.types.d.ts.map +1 -0
- package/dist/components/NavList/NavListContext.d.ts +30 -0
- package/dist/components/NavList/NavListContext.d.ts.map +1 -0
- package/dist/components/NavList/NavListContext.js +16 -0
- package/dist/components/NavList/NavListContext.js.map +1 -0
- package/dist/components/NavList/NavListContext.mjs +13 -0
- package/dist/components/NavList/NavListContext.mjs.map +1 -0
- package/dist/components/NavList/NavListGroup.d.ts +31 -0
- package/dist/components/NavList/NavListGroup.d.ts.map +1 -0
- package/dist/components/NavList/NavListGroup.js +115 -0
- package/dist/components/NavList/NavListGroup.js.map +1 -0
- package/dist/components/NavList/NavListGroup.mjs +113 -0
- package/dist/components/NavList/NavListGroup.mjs.map +1 -0
- package/dist/components/NavList/NavListItem.d.ts +16 -0
- package/dist/components/NavList/NavListItem.d.ts.map +1 -0
- package/dist/components/NavList/NavListItem.js +273 -0
- package/dist/components/NavList/NavListItem.js.map +1 -0
- package/dist/components/NavList/NavListItem.mjs +271 -0
- package/dist/components/NavList/NavListItem.mjs.map +1 -0
- package/dist/components/NavList/NavListSkeleton.d.ts +17 -0
- package/dist/components/NavList/NavListSkeleton.d.ts.map +1 -0
- package/dist/components/NavList/NavListSkeleton.js +33 -0
- package/dist/components/NavList/NavListSkeleton.js.map +1 -0
- package/dist/components/NavList/NavListSkeleton.mjs +31 -0
- package/dist/components/NavList/NavListSkeleton.mjs.map +1 -0
- package/dist/components/NavList/index.d.ts +7 -0
- package/dist/components/NavList/index.d.ts.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +6 -1
- package/dist/index.mjs.map +1 -1
- package/dist/utils/focusRing.d.ts +22 -0
- package/dist/utils/focusRing.d.ts.map +1 -1
- package/dist/utils/focusRing.js +22 -0
- package/dist/utils/focusRing.js.map +1 -1
- package/dist/utils/focusRing.mjs +21 -1
- package/dist/utils/focusRing.mjs.map +1 -1
- package/package.json +2 -1
- package/src/components/Menu/Menu.usage.mdx +8 -0
- package/src/components/NavList/NavList.stories.tsx +895 -0
- package/src/components/NavList/NavList.styles.ts +114 -0
- package/src/components/NavList/NavList.test.tsx +1282 -0
- package/src/components/NavList/NavList.translations.json +9 -0
- package/src/components/NavList/NavList.tsx +160 -0
- package/src/components/NavList/NavList.types.ts +155 -0
- package/src/components/NavList/NavList.usage.mdx +545 -0
- package/src/components/NavList/NavListContext.ts +25 -0
- package/src/components/NavList/NavListGroup.tsx +243 -0
- package/src/components/NavList/NavListItem.tsx +530 -0
- package/src/components/NavList/NavListSkeleton.tsx +57 -0
- package/src/components/NavList/index.ts +15 -0
- package/src/components/Tabs/Tabs.usage.mdx +58 -14
- package/src/components/Tooltip/Tooltip.usage.mdx +8 -0
- package/src/components/a11y.kwcag.test.tsx +66 -0
- package/src/components/claude.md +1 -1
- package/src/index.ts +7 -1
- package/src/utils/focusRing.ts +23 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import type { MouseEventHandler, ReactNode } from 'react';
|
|
2
|
+
import type { HTMLChakraProps } from '@chakra-ui/react';
|
|
3
|
+
export type NavListOrientation = 'vertical' | 'horizontal';
|
|
4
|
+
type NavListBreakpoint = 'base' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';
|
|
5
|
+
/**
|
|
6
|
+
* One orientation, or one per breakpoint. The media-template rails and the
|
|
7
|
+
* Drive source rail lie down into a sideways-scrolling row below `md`:
|
|
8
|
+
*
|
|
9
|
+
* ```tsx
|
|
10
|
+
* <NavList orientation={{ base: 'horizontal', md: 'vertical' }} />
|
|
11
|
+
* ```
|
|
12
|
+
*
|
|
13
|
+
* The switch is pure CSS (one rule per breakpoint), so it never renders the
|
|
14
|
+
* wrong axis first and corrects itself after hydration.
|
|
15
|
+
*/
|
|
16
|
+
export type NavListResponsiveOrientation = NavListOrientation | Partial<Record<NavListBreakpoint, NavListOrientation>>;
|
|
17
|
+
export type NavListProps = Omit<HTMLChakraProps<'ul'>, 'children'> & {
|
|
18
|
+
children?: ReactNode;
|
|
19
|
+
/**
|
|
20
|
+
* `vertical` is a rail; `horizontal` is a single row that scrolls sideways
|
|
21
|
+
* instead of wrapping. Accepts a per-breakpoint object.
|
|
22
|
+
* @default 'vertical'
|
|
23
|
+
*/
|
|
24
|
+
orientation?: NavListResponsiveOrientation;
|
|
25
|
+
/**
|
|
26
|
+
* Naming the list makes it a `<nav>` landmark around the list. Leave it off
|
|
27
|
+
* when the list already sits inside a named landmark (the app sidebar) — a
|
|
28
|
+
* second, unnamed `nav` is noise in the landmark menu.
|
|
29
|
+
*/
|
|
30
|
+
'aria-label'?: string;
|
|
31
|
+
/** As `aria-label`, pointing at a visible heading. Also makes it a `<nav>`. */
|
|
32
|
+
'aria-labelledby'?: string;
|
|
33
|
+
/**
|
|
34
|
+
* The collapsed rail: every row is a 40px icon-only square whose label is
|
|
35
|
+
* still its accessible name (visually hidden) and shows as a tooltip on
|
|
36
|
+
* hover and keyboard focus. `trailingVisual`, `trailingAction` and group
|
|
37
|
+
* titles are hidden; a collapsible group shows its rows. Every row needs a
|
|
38
|
+
* `leadingVisual` in this mode. Vertical only.
|
|
39
|
+
* @default false
|
|
40
|
+
*/
|
|
41
|
+
isCollapsed?: boolean;
|
|
42
|
+
};
|
|
43
|
+
export type NavListTrailingActionVisibility = 'always' | 'hover';
|
|
44
|
+
export type NavListItemProps = Omit<HTMLChakraProps<'a'>, 'children' | 'onClick' | 'aria-current' | 'asChild'> & {
|
|
45
|
+
/**
|
|
46
|
+
* The label. With `asChild`, the single link element (e.g. `next/link`)
|
|
47
|
+
* whose own children are the label.
|
|
48
|
+
*/
|
|
49
|
+
children?: ReactNode;
|
|
50
|
+
/** Renders an `<a>`. Without `href` (and without `asChild`) the row is a `<button>`. */
|
|
51
|
+
href?: string;
|
|
52
|
+
/**
|
|
53
|
+
* Merge the row onto the one child element instead of rendering an `<a>` —
|
|
54
|
+
* for a router link: `<NavList.Item asChild><NextLink href="/x">X</NextLink></NavList.Item>`.
|
|
55
|
+
* The row is treated as a link.
|
|
56
|
+
*/
|
|
57
|
+
asChild?: boolean;
|
|
58
|
+
onClick?: MouseEventHandler<HTMLElement>;
|
|
59
|
+
/**
|
|
60
|
+
* This row is where the user is: `aria-current="page"` on a link,
|
|
61
|
+
* `aria-current="true"` on a button (the active filter of a rail). Shown as
|
|
62
|
+
* an ink label, bold, on a `bg.emphasized` fill.
|
|
63
|
+
*/
|
|
64
|
+
isCurrent?: boolean;
|
|
65
|
+
/**
|
|
66
|
+
* A button becomes `disabled`. A link — `asChild` included — is rendered
|
|
67
|
+
* as an `<a role="link" aria-disabled="true">` with no `href`: still
|
|
68
|
+
* announced as a link, out of the tab order, and nothing to open in a new tab.
|
|
69
|
+
*/
|
|
70
|
+
isDisabled?: boolean;
|
|
71
|
+
/** Icon before the label. Decorative — the label names the row. */
|
|
72
|
+
leadingVisual?: ReactNode;
|
|
73
|
+
/** Count or badge after the label, in muted text. Read as part of the row's name. */
|
|
74
|
+
trailingVisual?: ReactNode;
|
|
75
|
+
/**
|
|
76
|
+
* A separate control beside the row (more-menu, remove), e.g. an
|
|
77
|
+
* `IconButton` with its own `aria-label`. It is a sibling of the row, never
|
|
78
|
+
* inside it, so there is no interactive element nested in another.
|
|
79
|
+
*/
|
|
80
|
+
trailingAction?: ReactNode;
|
|
81
|
+
/**
|
|
82
|
+
* `hover`: the trailing action is transparent until the row is hovered, or
|
|
83
|
+
* focus is anywhere in the row, or the action's own menu is open
|
|
84
|
+
* (`aria-expanded="true"` / `data-state="open"` inside it). It is never
|
|
85
|
+
* removed, so Tab still reaches it — focusing it is what reveals it. Always
|
|
86
|
+
* shown on touch screens (`hover: none`), where there is no hover to reveal it.
|
|
87
|
+
* @default 'always'
|
|
88
|
+
*/
|
|
89
|
+
trailingActionVisibility?: NavListTrailingActionVisibility;
|
|
90
|
+
/**
|
|
91
|
+
* A tooltip that adds to the label — a description, or why a row is
|
|
92
|
+
* disabled. It is also the row's accessible DESCRIPTION, through a hidden
|
|
93
|
+
* element that is referenced whether or not the tooltip is open — so a
|
|
94
|
+
* disabled row, which cannot take focus, still says why. It must not repeat
|
|
95
|
+
* the label. In a collapsed list it shows under the label.
|
|
96
|
+
*
|
|
97
|
+
* Label tooltips need no prop: a label cut off by the ellipsis shows itself
|
|
98
|
+
* in full on hover/focus, and every row of a collapsed list shows its label.
|
|
99
|
+
* Those are not wired as a description, because they would read the name twice.
|
|
100
|
+
*/
|
|
101
|
+
tooltip?: ReactNode;
|
|
102
|
+
/**
|
|
103
|
+
* Which side of an expanded row its tooltips open on. `'end'` is the side
|
|
104
|
+
* away from the label's start — the right on a left-to-right page — for a
|
|
105
|
+
* side rail whose description should sit beside the row, not over the row
|
|
106
|
+
* above it. A collapsed list always opens them at the end.
|
|
107
|
+
* @default 'top'
|
|
108
|
+
*/
|
|
109
|
+
tooltipPlacement?: NavListTooltipPlacement;
|
|
110
|
+
};
|
|
111
|
+
export type NavListTooltipPlacement = 'top' | 'end';
|
|
112
|
+
export type NavListGroupProps = Omit<HTMLChakraProps<'li'>, 'children' | 'title'> & {
|
|
113
|
+
children?: ReactNode;
|
|
114
|
+
/**
|
|
115
|
+
* Text above the group's rows, in overline style. Not interactive and not a
|
|
116
|
+
* heading element — it names the group's list (`aria-labelledby`), so it
|
|
117
|
+
* does not add a level to the page outline.
|
|
118
|
+
*/
|
|
119
|
+
title?: ReactNode;
|
|
120
|
+
/**
|
|
121
|
+
* The title becomes a `<button aria-expanded>` that shows and hides the
|
|
122
|
+
* group's rows. Needs a `title`. Persisting the state (local storage, a
|
|
123
|
+
* store) is the caller's: pass `isOpen` + `onOpenChange`.
|
|
124
|
+
* @default false
|
|
125
|
+
*/
|
|
126
|
+
isCollapsible?: boolean;
|
|
127
|
+
/** Controlled open state of a collapsible group. */
|
|
128
|
+
isOpen?: boolean;
|
|
129
|
+
/** Uncontrolled initial state of a collapsible group. @default true */
|
|
130
|
+
defaultOpen?: boolean;
|
|
131
|
+
onOpenChange?: (isOpen: boolean) => void;
|
|
132
|
+
};
|
|
133
|
+
export type NavListSkeletonProps = Omit<HTMLChakraProps<'ul'>, 'children'> & {
|
|
134
|
+
/** How many placeholder rows. @default 5 */
|
|
135
|
+
count?: number;
|
|
136
|
+
/** Lay the placeholders out like the list they stand in for. @default 'vertical' */
|
|
137
|
+
orientation?: NavListResponsiveOrientation;
|
|
138
|
+
};
|
|
139
|
+
export {};
|
|
140
|
+
//# sourceMappingURL=NavList.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NavList.types.d.ts","sourceRoot":"","sources":["../../../src/components/NavList/NavList.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExD,MAAM,MAAM,kBAAkB,GAAG,UAAU,GAAG,YAAY,CAAC;AAE3D,KAAK,iBAAiB,GAAG,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,CAAC;AAEpE;;;;;;;;;;GAUG;AACH,MAAM,MAAM,4BAA4B,GACpC,kBAAkB,GAClB,OAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE,kBAAkB,CAAC,CAAC,CAAC;AAE3D,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC,GAAG;IACnE,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;;;;OAIG;IACH,WAAW,CAAC,EAAE,4BAA4B,CAAC;IAC3C;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+EAA+E;IAC/E,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,+BAA+B,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEjE,MAAM,MAAM,gBAAgB,GAAG,IAAI,CACjC,eAAe,CAAC,GAAG,CAAC,EACpB,UAAU,GAAG,SAAS,GAAG,cAAc,GAAG,SAAS,CACpD,GAAG;IACF;;;OAGG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,wFAAwF;IACxF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,iBAAiB,CAAC,WAAW,CAAC,CAAC;IACzC;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,mEAAmE;IACnE,aAAa,CAAC,EAAE,SAAS,CAAC;IAC1B,qFAAqF;IACrF,cAAc,CAAC,EAAE,SAAS,CAAC;IAC3B;;;;OAIG;IACH,cAAc,CAAC,EAAE,SAAS,CAAC;IAC3B;;;;;;;OAOG;IACH,wBAAwB,CAAC,EAAE,+BAA+B,CAAC;IAC3D;;;;;;;;;;OAUG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,uBAAuB,CAAC;CAC5C,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG,KAAK,GAAG,KAAK,CAAC;AAEpD,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAClC,eAAe,CAAC,IAAI,CAAC,EACrB,UAAU,GAAG,OAAO,CACrB,GAAG;IACF,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;;;;OAIG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,oDAAoD;IACpD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,uEAAuE;IACvE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;CAC1C,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC,GAAG;IAC3E,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oFAAoF;IACpF,WAAW,CAAC,EAAE,4BAA4B,CAAC;CAC5C,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { NavListResponsiveOrientation } from './NavList.types';
|
|
2
|
+
export declare const NavListContext: import("react").Context<{
|
|
3
|
+
orientation: NavListResponsiveOrientation;
|
|
4
|
+
isCollapsed: boolean;
|
|
5
|
+
/**
|
|
6
|
+
* The direction the list inherits, measured after mount — for the rows'
|
|
7
|
+
* tooltips (their text direction, and which side a collapsed rail's tooltip
|
|
8
|
+
* opens on) and the `dir` attribute zag stamps on its parts. Never for
|
|
9
|
+
* layout: rows inherit `direction` in CSS, so a server render is right
|
|
10
|
+
* before this is known.
|
|
11
|
+
*/
|
|
12
|
+
tooltipDir: "ltr" | "rtl";
|
|
13
|
+
/** A row that just became current asks the list to bring it into view. */
|
|
14
|
+
revealCurrent: () => void;
|
|
15
|
+
}>;
|
|
16
|
+
export declare const useNavListContext: () => {
|
|
17
|
+
orientation: NavListResponsiveOrientation;
|
|
18
|
+
isCollapsed: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* The direction the list inherits, measured after mount — for the rows'
|
|
21
|
+
* tooltips (their text direction, and which side a collapsed rail's tooltip
|
|
22
|
+
* opens on) and the `dir` attribute zag stamps on its parts. Never for
|
|
23
|
+
* layout: rows inherit `direction` in CSS, so a server render is right
|
|
24
|
+
* before this is known.
|
|
25
|
+
*/
|
|
26
|
+
tooltipDir: "ltr" | "rtl";
|
|
27
|
+
/** A row that just became current asks the list to bring it into view. */
|
|
28
|
+
revealCurrent: () => void;
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=NavListContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NavListContext.d.ts","sourceRoot":"","sources":["../../../src/components/NavList/NavListContext.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,iBAAiB,CAAC;AAEpE,eAAO,MAAM,cAAc;iBACZ,4BAA4B;iBAC5B,OAAO;IACpB;;;;;;OAMG;gBACS,KAAK,GAAG,KAAK;IACzB,0EAA0E;mBAC3D,MAAM,IAAI;EAMzB,CAAC;AAEH,eAAO,MAAM,iBAAiB;iBAnBf,4BAA4B;iBAC5B,OAAO;IACpB;;;;;;OAMG;gBACS,KAAK,GAAG,KAAK;IACzB,0EAA0E;mBAC3D,MAAM,IAAI;CAQsC,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var React = require('react');
|
|
5
|
+
|
|
6
|
+
const NavListContext = React.createContext({
|
|
7
|
+
orientation: 'vertical',
|
|
8
|
+
isCollapsed: false,
|
|
9
|
+
tooltipDir: 'ltr',
|
|
10
|
+
revealCurrent: () => { },
|
|
11
|
+
});
|
|
12
|
+
const useNavListContext = () => React.useContext(NavListContext);
|
|
13
|
+
|
|
14
|
+
exports.NavListContext = NavListContext;
|
|
15
|
+
exports.useNavListContext = useNavListContext;
|
|
16
|
+
//# sourceMappingURL=NavListContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NavListContext.js","sources":["../../../src/components/NavList/NavListContext.ts"],"sourcesContent":[null],"names":["createContext","useContext"],"mappings":";;;;;AAIO,MAAM,cAAc,GAAGA,mBAAa,CAaxC;AACD,IAAA,WAAW,EAAE,UAAU;AACvB,IAAA,WAAW,EAAE,KAAK;AAClB,IAAA,UAAU,EAAE,KAAK;AACjB,IAAA,aAAa,EAAE,MAAK,EAAE,CAAC;AACxB,CAAA;AAEM,MAAM,iBAAiB,GAAG,MAAMC,gBAAU,CAAC,cAAc;;;;;"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { createContext, useContext } from 'react';
|
|
3
|
+
|
|
4
|
+
const NavListContext = createContext({
|
|
5
|
+
orientation: 'vertical',
|
|
6
|
+
isCollapsed: false,
|
|
7
|
+
tooltipDir: 'ltr',
|
|
8
|
+
revealCurrent: () => { },
|
|
9
|
+
});
|
|
10
|
+
const useNavListContext = () => useContext(NavListContext);
|
|
11
|
+
|
|
12
|
+
export { NavListContext, useNavListContext };
|
|
13
|
+
//# sourceMappingURL=NavListContext.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NavListContext.mjs","sources":["../../../src/components/NavList/NavListContext.ts"],"sourcesContent":[null],"names":[],"mappings":";;;AAIO,MAAM,cAAc,GAAG,aAAa,CAaxC;AACD,IAAA,WAAW,EAAE,UAAU;AACvB,IAAA,WAAW,EAAE,KAAK;AAClB,IAAA,UAAU,EAAE,KAAK;AACjB,IAAA,aAAa,EAAE,MAAK,EAAE,CAAC;AACxB,CAAA;AAEM,MAAM,iBAAiB,GAAG,MAAM,UAAU,CAAC,cAAc;;;;"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A run of rows under an optional title.
|
|
3
|
+
*
|
|
4
|
+
* Rendered as `<li>` → title + nested `<ul aria-labelledby={title}>`, so a
|
|
5
|
+
* screen reader announces "목록, 공유 드라이브, 3개 항목" on entering it. The
|
|
6
|
+
* title is overline text, not `<h*>`: which heading level a rail's group is
|
|
7
|
+
* can only be known at the call site, and a typography default that decides
|
|
8
|
+
* the outline is exactly the `Subtitle as="h6"` defect in `ACCESSIBILITY.md`.
|
|
9
|
+
*
|
|
10
|
+
* `isCollapsible` turns the title into a disclosure button
|
|
11
|
+
* (`aria-expanded` + `aria-controls`); the list stays labelled by the title
|
|
12
|
+
* text. A collapsed RAIL (`NavList isCollapsed`) shows every group's rows and
|
|
13
|
+
* folds the titles away visually — a column of icons has no room for either.
|
|
14
|
+
*
|
|
15
|
+
* The rows open and close on Collapsible's own motion: Ark's collapsible
|
|
16
|
+
* measures the list into `--height`, the recipe's `expand-height` /
|
|
17
|
+
* `collapse-height` move it, and `animationStyle="presence"` sets the house
|
|
18
|
+
* clock (300ms in, 150ms out) with a fade instead of the height under reduced
|
|
19
|
+
* motion. Ark sets `hidden` once the close has finished, so closed rows are
|
|
20
|
+
* out of the tab order and the accessibility tree; `inert` covers the 150ms
|
|
21
|
+
* the list is still leaving, so a closing row cannot be tabbed into.
|
|
22
|
+
*/
|
|
23
|
+
export declare const NavListGroup: import("react").ForwardRefExoticComponent<Omit<import("@chakra-ui/react").HTMLChakraProps<"li">, "title" | "children"> & {
|
|
24
|
+
children?: import("react").ReactNode;
|
|
25
|
+
title?: import("react").ReactNode;
|
|
26
|
+
isCollapsible?: boolean;
|
|
27
|
+
isOpen?: boolean;
|
|
28
|
+
defaultOpen?: boolean;
|
|
29
|
+
onOpenChange?: (isOpen: boolean) => void;
|
|
30
|
+
} & import("react").RefAttributes<HTMLLIElement>>;
|
|
31
|
+
//# sourceMappingURL=NavListGroup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NavListGroup.d.ts","sourceRoot":"","sources":["../../../src/components/NavList/NavListGroup.tsx"],"names":[],"mappings":"AAuBA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,YAAY;;;;;;;iDAmMxB,CAAC"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
+
var React = require('react');
|
|
6
|
+
var react = require('@chakra-ui/react');
|
|
7
|
+
var index = require('../Icon/index.js');
|
|
8
|
+
var Overline = require('../Typography/Overline.js');
|
|
9
|
+
var focusRing = require('../../utils/focusRing.js');
|
|
10
|
+
var NavList_styles = require('./NavList.styles.js');
|
|
11
|
+
var NavListContext = require('./NavListContext.js');
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* A run of rows under an optional title.
|
|
15
|
+
*
|
|
16
|
+
* Rendered as `<li>` → title + nested `<ul aria-labelledby={title}>`, so a
|
|
17
|
+
* screen reader announces "목록, 공유 드라이브, 3개 항목" on entering it. The
|
|
18
|
+
* title is overline text, not `<h*>`: which heading level a rail's group is
|
|
19
|
+
* can only be known at the call site, and a typography default that decides
|
|
20
|
+
* the outline is exactly the `Subtitle as="h6"` defect in `ACCESSIBILITY.md`.
|
|
21
|
+
*
|
|
22
|
+
* `isCollapsible` turns the title into a disclosure button
|
|
23
|
+
* (`aria-expanded` + `aria-controls`); the list stays labelled by the title
|
|
24
|
+
* text. A collapsed RAIL (`NavList isCollapsed`) shows every group's rows and
|
|
25
|
+
* folds the titles away visually — a column of icons has no room for either.
|
|
26
|
+
*
|
|
27
|
+
* The rows open and close on Collapsible's own motion: Ark's collapsible
|
|
28
|
+
* measures the list into `--height`, the recipe's `expand-height` /
|
|
29
|
+
* `collapse-height` move it, and `animationStyle="presence"` sets the house
|
|
30
|
+
* clock (300ms in, 150ms out) with a fade instead of the height under reduced
|
|
31
|
+
* motion. Ark sets `hidden` once the close has finished, so closed rows are
|
|
32
|
+
* out of the tab order and the accessibility tree; `inert` covers the 150ms
|
|
33
|
+
* the list is still leaving, so a closing row cannot be tabbed into.
|
|
34
|
+
*/
|
|
35
|
+
const NavListGroup = React.forwardRef(({ title, children, isCollapsible = false, isOpen: isOpenProp, defaultOpen = true, onOpenChange, ...rest }, ref) => {
|
|
36
|
+
const { orientation, isCollapsed, tooltipDir } = NavListContext.useNavListContext();
|
|
37
|
+
const inherited = react.useLocaleContext();
|
|
38
|
+
const titleId = React.useId();
|
|
39
|
+
const listId = React.useId();
|
|
40
|
+
const hasTitle = title != null && title !== false;
|
|
41
|
+
const [isOpenState, setIsOpenState] = React.useState(defaultOpen);
|
|
42
|
+
// The disclosure exists whenever the caller asked for one; a collapsed
|
|
43
|
+
// rail only forces it open, so toggling the rail does not remount rows.
|
|
44
|
+
const isDisclosure = isCollapsible && hasTitle;
|
|
45
|
+
const canCollapse = isDisclosure && !isCollapsed;
|
|
46
|
+
const isOpen = !canCollapse || (isOpenProp ?? isOpenState);
|
|
47
|
+
const listRef = React.useRef(null);
|
|
48
|
+
// A DOM property rather than the attribute: React 18 does not know
|
|
49
|
+
// `inert`, and 19 reads it as a boolean.
|
|
50
|
+
React.useEffect(() => {
|
|
51
|
+
if (listRef.current)
|
|
52
|
+
listRef.current.inert = !isOpen;
|
|
53
|
+
}, [isOpen]);
|
|
54
|
+
const toggle = () => {
|
|
55
|
+
const next = !isOpen;
|
|
56
|
+
if (isOpenProp === undefined)
|
|
57
|
+
setIsOpenState(next);
|
|
58
|
+
onOpenChange?.(next);
|
|
59
|
+
};
|
|
60
|
+
// Space on the axis the rows stack along, on both sides of a group: before
|
|
61
|
+
// it unless it opens the list, and before whatever row follows it, so the
|
|
62
|
+
// row after a group does not read as one more member of it.
|
|
63
|
+
const gapBefore = {
|
|
64
|
+
marginTop: NavList_styles.byOrientation(orientation, 3, 0),
|
|
65
|
+
marginInlineStart: NavList_styles.byOrientation(orientation, 0, 3),
|
|
66
|
+
};
|
|
67
|
+
const titleText = (jsxRuntime.jsx(Overline.Overline, { as: "span", id: titleId, display: "block", color: NavList_styles.NAV_LIST_RAMP.groupTitle, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis", children: title }));
|
|
68
|
+
let heading = null;
|
|
69
|
+
if (canCollapse) {
|
|
70
|
+
heading = (jsxRuntime.jsxs(react.chakra.button, { type: "button", "aria-expanded": isOpen, "aria-controls": listId, onClick: toggle, display: "flex", alignItems: "center", justifyContent: "space-between", gap: 2, minH: 8, px: 2.5, borderRadius: "md", bg: "transparent", border: "none", cursor: "pointer", color: NavList_styles.NAV_LIST_RAMP.groupTitle, textAlign: "start", _hover: { bg: NavList_styles.NAV_LIST_RAMP.hoverFill }, _active: NavList_styles.pressedFill, ...focusRing.focusRingInset, children: [titleText, jsxRuntime.jsx(index.ChevronDownIcon, { "aria-hidden": true, boxSize: 4, flexShrink: 0,
|
|
71
|
+
// Closed points to the inline end: right, or left on an RTL page.
|
|
72
|
+
rotate: isOpen ? '0deg' : '-90deg', _rtl: { rotate: isOpen ? '0deg' : '90deg' },
|
|
73
|
+
// Turns with the list, on the same clock as its enter.
|
|
74
|
+
animationStyle: "travel", transitionProperty: "rotate" })] }));
|
|
75
|
+
}
|
|
76
|
+
else if (hasTitle) {
|
|
77
|
+
heading = (jsxRuntime.jsx(react.chakra.span, { display: "block", px: 2.5, py: NavList_styles.byOrientation(orientation, 1, 0), children: titleText }));
|
|
78
|
+
}
|
|
79
|
+
// A collapsed rail has no room for titles. The title folds to no height
|
|
80
|
+
// and fades on the rows' clock instead of being swapped out, so the rows
|
|
81
|
+
// under it slide up with the rail rather than jumping. It stays in the
|
|
82
|
+
// DOM either way: it is what names the group's list.
|
|
83
|
+
if (heading) {
|
|
84
|
+
heading = (jsxRuntime.jsx(react.chakra.div, { display: "grid", gridTemplateRows: isCollapsed ? '0fr' : '1fr', opacity: isCollapsed ? 0 : 1, animationStyle: "feedback", transitionProperty: "grid-template-rows, opacity", children: jsxRuntime.jsx(react.chakra.div, { minH: 0, overflow: "hidden", display: "flex", flexDirection: "column", children: heading }) }));
|
|
85
|
+
}
|
|
86
|
+
const listProps = {
|
|
87
|
+
id: listId,
|
|
88
|
+
'aria-labelledby': hasTitle ? titleId : undefined,
|
|
89
|
+
...NavList_styles.listStyles(orientation),
|
|
90
|
+
alignItems: NavList_styles.byOrientation(orientation, 'stretch', 'center'),
|
|
91
|
+
...NavList_styles.inheritDirection,
|
|
92
|
+
};
|
|
93
|
+
const list = isDisclosure ? (jsxRuntime.jsx(react.Collapsible.Content, { asChild: true, animationStyle: "presence",
|
|
94
|
+
// `hidden` loses to the list's own `display: flex`.
|
|
95
|
+
css: { '&[hidden]': { display: 'none' } }, children: jsxRuntime.jsx(react.chakra.ul, { ref: listRef, ...listProps, children: children }) })) : (jsxRuntime.jsx(react.chakra.ul, { ...listProps, children: children }));
|
|
96
|
+
const group = (jsxRuntime.jsx(react.chakra.li, { ref: ref, display: "flex", flexDirection: NavList_styles.byOrientation(orientation, 'column', 'row'), alignItems: NavList_styles.byOrientation(orientation, 'stretch', 'center'), gap: 0.5, flexShrink: 0, minW: 0, css: {
|
|
97
|
+
'&:not(:first-child)': gapBefore,
|
|
98
|
+
'& + li': gapBefore,
|
|
99
|
+
}, ...NavList_styles.inheritDirection, ...rest, children: jsxRuntime.jsxs(react.LocaleProvider, { locale: inherited.locale, children: [heading, list] }) }));
|
|
100
|
+
if (!isDisclosure)
|
|
101
|
+
return group;
|
|
102
|
+
// The title stays our own button, so `aria-expanded` flips on the click
|
|
103
|
+
// rather than when the closing animation ends, and the rail can force the
|
|
104
|
+
// group open without the button having a say.
|
|
105
|
+
return (
|
|
106
|
+
// Zag stamps `dir` on the group and its list; give it the measured
|
|
107
|
+
// direction so the attributes agree with the layout after mount. The
|
|
108
|
+
// layout does not read it (`inheritDirection`), and the rows inside get
|
|
109
|
+
// the caller's own locale back.
|
|
110
|
+
jsxRuntime.jsx(react.LocaleProvider, { locale: NavList_styles.localeFor(inherited, tooltipDir), children: jsxRuntime.jsx(react.Collapsible.Root, { asChild: true, open: isOpen, ids: { content: listId }, children: group }) }));
|
|
111
|
+
});
|
|
112
|
+
NavListGroup.displayName = 'NavList.Group';
|
|
113
|
+
|
|
114
|
+
exports.NavListGroup = NavListGroup;
|
|
115
|
+
//# sourceMappingURL=NavListGroup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NavListGroup.js","sources":["../../../src/components/NavList/NavListGroup.tsx"],"sourcesContent":[null],"names":["forwardRef","useNavListContext","useLocaleContext","useId","useState","useRef","useEffect","byOrientation","_jsx","Overline","NAV_LIST_RAMP","_jsxs","chakra","pressedFill","focusRingInset","ChevronDownIcon","listStyles","inheritDirection","ChakraCollapsible","LocaleProvider","localeFor"],"mappings":"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"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
3
|
+
import { forwardRef, useId, useState, useRef, useEffect } from 'react';
|
|
4
|
+
import { useLocaleContext, chakra, Collapsible, LocaleProvider } from '@chakra-ui/react';
|
|
5
|
+
import { ChevronDownIcon } from '../Icon/index.mjs';
|
|
6
|
+
import { Overline } from '../Typography/Overline.mjs';
|
|
7
|
+
import { focusRingInset } from '../../utils/focusRing.mjs';
|
|
8
|
+
import { byOrientation, NAV_LIST_RAMP, pressedFill, listStyles, inheritDirection, localeFor } from './NavList.styles.mjs';
|
|
9
|
+
import { useNavListContext } from './NavListContext.mjs';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* A run of rows under an optional title.
|
|
13
|
+
*
|
|
14
|
+
* Rendered as `<li>` → title + nested `<ul aria-labelledby={title}>`, so a
|
|
15
|
+
* screen reader announces "목록, 공유 드라이브, 3개 항목" on entering it. The
|
|
16
|
+
* title is overline text, not `<h*>`: which heading level a rail's group is
|
|
17
|
+
* can only be known at the call site, and a typography default that decides
|
|
18
|
+
* the outline is exactly the `Subtitle as="h6"` defect in `ACCESSIBILITY.md`.
|
|
19
|
+
*
|
|
20
|
+
* `isCollapsible` turns the title into a disclosure button
|
|
21
|
+
* (`aria-expanded` + `aria-controls`); the list stays labelled by the title
|
|
22
|
+
* text. A collapsed RAIL (`NavList isCollapsed`) shows every group's rows and
|
|
23
|
+
* folds the titles away visually — a column of icons has no room for either.
|
|
24
|
+
*
|
|
25
|
+
* The rows open and close on Collapsible's own motion: Ark's collapsible
|
|
26
|
+
* measures the list into `--height`, the recipe's `expand-height` /
|
|
27
|
+
* `collapse-height` move it, and `animationStyle="presence"` sets the house
|
|
28
|
+
* clock (300ms in, 150ms out) with a fade instead of the height under reduced
|
|
29
|
+
* motion. Ark sets `hidden` once the close has finished, so closed rows are
|
|
30
|
+
* out of the tab order and the accessibility tree; `inert` covers the 150ms
|
|
31
|
+
* the list is still leaving, so a closing row cannot be tabbed into.
|
|
32
|
+
*/
|
|
33
|
+
const NavListGroup = forwardRef(({ title, children, isCollapsible = false, isOpen: isOpenProp, defaultOpen = true, onOpenChange, ...rest }, ref) => {
|
|
34
|
+
const { orientation, isCollapsed, tooltipDir } = useNavListContext();
|
|
35
|
+
const inherited = useLocaleContext();
|
|
36
|
+
const titleId = useId();
|
|
37
|
+
const listId = useId();
|
|
38
|
+
const hasTitle = title != null && title !== false;
|
|
39
|
+
const [isOpenState, setIsOpenState] = useState(defaultOpen);
|
|
40
|
+
// The disclosure exists whenever the caller asked for one; a collapsed
|
|
41
|
+
// rail only forces it open, so toggling the rail does not remount rows.
|
|
42
|
+
const isDisclosure = isCollapsible && hasTitle;
|
|
43
|
+
const canCollapse = isDisclosure && !isCollapsed;
|
|
44
|
+
const isOpen = !canCollapse || (isOpenProp ?? isOpenState);
|
|
45
|
+
const listRef = useRef(null);
|
|
46
|
+
// A DOM property rather than the attribute: React 18 does not know
|
|
47
|
+
// `inert`, and 19 reads it as a boolean.
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
if (listRef.current)
|
|
50
|
+
listRef.current.inert = !isOpen;
|
|
51
|
+
}, [isOpen]);
|
|
52
|
+
const toggle = () => {
|
|
53
|
+
const next = !isOpen;
|
|
54
|
+
if (isOpenProp === undefined)
|
|
55
|
+
setIsOpenState(next);
|
|
56
|
+
onOpenChange?.(next);
|
|
57
|
+
};
|
|
58
|
+
// Space on the axis the rows stack along, on both sides of a group: before
|
|
59
|
+
// it unless it opens the list, and before whatever row follows it, so the
|
|
60
|
+
// row after a group does not read as one more member of it.
|
|
61
|
+
const gapBefore = {
|
|
62
|
+
marginTop: byOrientation(orientation, 3, 0),
|
|
63
|
+
marginInlineStart: byOrientation(orientation, 0, 3),
|
|
64
|
+
};
|
|
65
|
+
const titleText = (jsx(Overline, { as: "span", id: titleId, display: "block", color: NAV_LIST_RAMP.groupTitle, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis", children: title }));
|
|
66
|
+
let heading = null;
|
|
67
|
+
if (canCollapse) {
|
|
68
|
+
heading = (jsxs(chakra.button, { type: "button", "aria-expanded": isOpen, "aria-controls": listId, onClick: toggle, display: "flex", alignItems: "center", justifyContent: "space-between", gap: 2, minH: 8, px: 2.5, borderRadius: "md", bg: "transparent", border: "none", cursor: "pointer", color: NAV_LIST_RAMP.groupTitle, textAlign: "start", _hover: { bg: NAV_LIST_RAMP.hoverFill }, _active: pressedFill, ...focusRingInset, children: [titleText, jsx(ChevronDownIcon, { "aria-hidden": true, boxSize: 4, flexShrink: 0,
|
|
69
|
+
// Closed points to the inline end: right, or left on an RTL page.
|
|
70
|
+
rotate: isOpen ? '0deg' : '-90deg', _rtl: { rotate: isOpen ? '0deg' : '90deg' },
|
|
71
|
+
// Turns with the list, on the same clock as its enter.
|
|
72
|
+
animationStyle: "travel", transitionProperty: "rotate" })] }));
|
|
73
|
+
}
|
|
74
|
+
else if (hasTitle) {
|
|
75
|
+
heading = (jsx(chakra.span, { display: "block", px: 2.5, py: byOrientation(orientation, 1, 0), children: titleText }));
|
|
76
|
+
}
|
|
77
|
+
// A collapsed rail has no room for titles. The title folds to no height
|
|
78
|
+
// and fades on the rows' clock instead of being swapped out, so the rows
|
|
79
|
+
// under it slide up with the rail rather than jumping. It stays in the
|
|
80
|
+
// DOM either way: it is what names the group's list.
|
|
81
|
+
if (heading) {
|
|
82
|
+
heading = (jsx(chakra.div, { display: "grid", gridTemplateRows: isCollapsed ? '0fr' : '1fr', opacity: isCollapsed ? 0 : 1, animationStyle: "feedback", transitionProperty: "grid-template-rows, opacity", children: jsx(chakra.div, { minH: 0, overflow: "hidden", display: "flex", flexDirection: "column", children: heading }) }));
|
|
83
|
+
}
|
|
84
|
+
const listProps = {
|
|
85
|
+
id: listId,
|
|
86
|
+
'aria-labelledby': hasTitle ? titleId : undefined,
|
|
87
|
+
...listStyles(orientation),
|
|
88
|
+
alignItems: byOrientation(orientation, 'stretch', 'center'),
|
|
89
|
+
...inheritDirection,
|
|
90
|
+
};
|
|
91
|
+
const list = isDisclosure ? (jsx(Collapsible.Content, { asChild: true, animationStyle: "presence",
|
|
92
|
+
// `hidden` loses to the list's own `display: flex`.
|
|
93
|
+
css: { '&[hidden]': { display: 'none' } }, children: jsx(chakra.ul, { ref: listRef, ...listProps, children: children }) })) : (jsx(chakra.ul, { ...listProps, children: children }));
|
|
94
|
+
const group = (jsx(chakra.li, { ref: ref, display: "flex", flexDirection: byOrientation(orientation, 'column', 'row'), alignItems: byOrientation(orientation, 'stretch', 'center'), gap: 0.5, flexShrink: 0, minW: 0, css: {
|
|
95
|
+
'&:not(:first-child)': gapBefore,
|
|
96
|
+
'& + li': gapBefore,
|
|
97
|
+
}, ...inheritDirection, ...rest, children: jsxs(LocaleProvider, { locale: inherited.locale, children: [heading, list] }) }));
|
|
98
|
+
if (!isDisclosure)
|
|
99
|
+
return group;
|
|
100
|
+
// The title stays our own button, so `aria-expanded` flips on the click
|
|
101
|
+
// rather than when the closing animation ends, and the rail can force the
|
|
102
|
+
// group open without the button having a say.
|
|
103
|
+
return (
|
|
104
|
+
// Zag stamps `dir` on the group and its list; give it the measured
|
|
105
|
+
// direction so the attributes agree with the layout after mount. The
|
|
106
|
+
// layout does not read it (`inheritDirection`), and the rows inside get
|
|
107
|
+
// the caller's own locale back.
|
|
108
|
+
jsx(LocaleProvider, { locale: localeFor(inherited, tooltipDir), children: jsx(Collapsible.Root, { asChild: true, open: isOpen, ids: { content: listId }, children: group }) }));
|
|
109
|
+
});
|
|
110
|
+
NavListGroup.displayName = 'NavList.Group';
|
|
111
|
+
|
|
112
|
+
export { NavListGroup };
|
|
113
|
+
//# sourceMappingURL=NavListGroup.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NavListGroup.mjs","sources":["../../../src/components/NavList/NavListGroup.tsx"],"sourcesContent":[null],"names":["_jsx","_jsxs","ChakraCollapsible"],"mappings":";;;;;;;;;;AAuBA;;;;;;;;;;;;;;;;;;;;;AAqBG;AACI,MAAM,YAAY,GAAG,UAAU,CACpC,CACE,EACE,KAAK,EACL,QAAQ,EACR,aAAa,GAAG,KAAK,EACrB,MAAM,EAAE,UAAU,EAClB,WAAW,GAAG,IAAI,EAClB,YAAY,EACZ,GAAG,IAAI,EACR,EACD,GAAG,KACD;IACF,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,iBAAiB,EAAE;AACpE,IAAA,MAAM,SAAS,GAAG,gBAAgB,EAAE;AACpC,IAAA,MAAM,OAAO,GAAG,KAAK,EAAE;AACvB,IAAA,MAAM,MAAM,GAAG,KAAK,EAAE;IACtB,MAAM,QAAQ,GAAG,KAAK,IAAI,IAAI,IAAI,KAAK,KAAK,KAAK;IACjD,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,WAAW,CAAC;;;AAG3D,IAAA,MAAM,YAAY,GAAG,aAAa,IAAI,QAAQ;AAC9C,IAAA,MAAM,WAAW,GAAG,YAAY,IAAI,CAAC,WAAW;IAChD,MAAM,MAAM,GAAG,CAAC,WAAW,KAAK,UAAU,IAAI,WAAW,CAAC;AAC1D,IAAA,MAAM,OAAO,GAAG,MAAM,CAAmB,IAAI,CAAC;;;IAG9C,SAAS,CAAC,MAAK;QACb,IAAI,OAAO,CAAC,OAAO;AAAE,YAAA,OAAO,CAAC,OAAO,CAAC,KAAK,GAAG,CAAC,MAAM;AACtD,IAAA,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;IAEZ,MAAM,MAAM,GAAG,MAAK;AAClB,QAAA,MAAM,IAAI,GAAG,CAAC,MAAM;QACpB,IAAI,UAAU,KAAK,SAAS;YAAE,cAAc,CAAC,IAAI,CAAC;AAClD,QAAA,YAAY,GAAG,IAAI,CAAC;AACtB,IAAA,CAAC;;;;AAKD,IAAA,MAAM,SAAS,GAAG;QAChB,SAAS,EAAE,aAAa,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC,CAAC;QAC3C,iBAAiB,EAAE,aAAa,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC,CAAC;KACpD;AAED,IAAA,MAAM,SAAS,IACbA,GAAA,CAAC,QAAQ,IACP,EAAE,EAAC,MAAM,EACT,EAAE,EAAE,OAAO,EACX,OAAO,EAAC,OAAO,EACf,KAAK,EAAE,aAAa,CAAC,UAAU,EAC/B,UAAU,EAAC,QAAQ,EACnB,QAAQ,EAAC,QAAQ,EACjB,YAAY,EAAC,UAAU,YAEtB,KAAK,EAAA,CACG,CACZ;IAED,IAAI,OAAO,GAAG,IAAI;IAClB,IAAI,WAAW,EAAE;QACf,OAAO,IACLC,IAAA,CAAC,MAAM,CAAC,MAAM,EAAA,EACZ,IAAI,EAAC,QAAQ,mBACE,MAAM,EAAA,eAAA,EACN,MAAM,EACrB,OAAO,EAAE,MAAM,EACf,OAAO,EAAC,MAAM,EACd,UAAU,EAAC,QAAQ,EACnB,cAAc,EAAC,eAAe,EAC9B,GAAG,EAAE,CAAC,EACN,IAAI,EAAE,CAAC,EACP,EAAE,EAAE,GAAG,EACP,YAAY,EAAC,IAAI,EACjB,EAAE,EAAC,aAAa,EAChB,MAAM,EAAC,MAAM,EACb,MAAM,EAAC,SAAS,EAChB,KAAK,EAAE,aAAa,CAAC,UAAU,EAC/B,SAAS,EAAC,OAAO,EACjB,MAAM,EAAE,EAAE,EAAE,EAAE,aAAa,CAAC,SAAS,EAAE,EACvC,OAAO,EAAE,WAAW,KAChB,cAAc,EAAA,QAAA,EAAA,CAEjB,SAAS,EACVD,GAAA,CAAC,eAAe,EAAA,EAAA,aAAA,EAAA,IAAA,EAEd,OAAO,EAAE,CAAC,EACV,UAAU,EAAE,CAAC;;oBAEb,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ,EAClC,IAAI,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,EAAE;;oBAE3C,cAAc,EAAC,QAAQ,EACvB,kBAAkB,EAAC,QAAQ,EAAA,CAC3B,CAAA,EAAA,CACY,CACjB;IACH;SAAO,IAAI,QAAQ,EAAE;AACnB,QAAA,OAAO,IACLA,GAAA,CAAC,MAAM,CAAC,IAAI,EAAA,EACV,OAAO,EAAC,OAAO,EACf,EAAE,EAAE,GAAG,EACP,EAAE,EAAE,aAAa,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC,CAAC,EAAA,QAAA,EAEnC,SAAS,EAAA,CACE,CACf;IACH;;;;;IAKA,IAAI,OAAO,EAAE;AACX,QAAA,OAAO,IACLA,GAAA,CAAC,MAAM,CAAC,GAAG,EAAA,EACT,OAAO,EAAC,MAAM,EACd,gBAAgB,EAAE,WAAW,GAAG,KAAK,GAAG,KAAK,EAC7C,OAAO,EAAE,WAAW,GAAG,CAAC,GAAG,CAAC,EAC5B,cAAc,EAAC,UAAU,EACzB,kBAAkB,EAAC,6BAA6B,EAAA,QAAA,EAEhDA,GAAA,CAAC,MAAM,CAAC,GAAG,EAAA,EACT,IAAI,EAAE,CAAC,EACP,QAAQ,EAAC,QAAQ,EACjB,OAAO,EAAC,MAAM,EACd,aAAa,EAAC,QAAQ,EAAA,QAAA,EAErB,OAAO,EAAA,CACG,EAAA,CACF,CACd;IACH;AAEA,IAAA,MAAM,SAAS,GAAG;AAChB,QAAA,EAAE,EAAE,MAAM;QACV,iBAAiB,EAAE,QAAQ,GAAG,OAAO,GAAG,SAAS;QACjD,GAAG,UAAU,CAAC,WAAW,CAAC;QAC1B,UAAU,EAAE,aAAa,CAAC,WAAW,EAAE,SAAS,EAAE,QAAQ,CAAC;AAC3D,QAAA,GAAG,gBAAgB;KACX;AAEV,IAAA,MAAM,IAAI,GAAG,YAAY,IACvBA,GAAA,CAACE,WAAiB,CAAC,OAAO,EAAA,EACxB,OAAO,EAAA,IAAA,EACP,cAAc,EAAC,UAAU;;AAEzB,QAAA,GAAG,EAAE,EAAE,WAAW,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAA,QAAA,EAEzCF,IAAC,MAAM,CAAC,EAAE,EAAA,EAAC,GAAG,EAAE,OAAO,EAAA,GAAM,SAAS,EAAA,QAAA,EACnC,QAAQ,EAAA,CACC,EAAA,CACc,KAE5BA,GAAA,CAAC,MAAM,CAAC,EAAE,EAAA,EAAA,GAAK,SAAS,YAAG,QAAQ,EAAA,CAAa,CACjD;IAED,MAAM,KAAK,IACTA,GAAA,CAAC,MAAM,CAAC,EAAE,EAAA,EACR,GAAG,EAAE,GAAG,EACR,OAAO,EAAC,MAAM,EACd,aAAa,EAAE,aAAa,CAAC,WAAW,EAAE,QAAQ,EAAE,KAAK,CAAC,EAC1D,UAAU,EAAE,aAAa,CAAC,WAAW,EAAE,SAAS,EAAE,QAAQ,CAAC,EAC3D,GAAG,EAAE,GAAG,EACR,UAAU,EAAE,CAAC,EACb,IAAI,EAAE,CAAC,EACP,GAAG,EAAE;AACH,YAAA,qBAAqB,EAAE,SAAS;AAChC,YAAA,QAAQ,EAAE,SAAS;AACpB,SAAA,EAAA,GACG,gBAAgB,EAAA,GAChB,IAAI,YAERC,IAAA,CAAC,cAAc,IAAC,MAAM,EAAE,SAAS,CAAC,MAAM,aACrC,OAAO,EACP,IAAI,CAAA,EAAA,CACU,EAAA,CACP,CACb;AAED,IAAA,IAAI,CAAC,YAAY;AAAE,QAAA,OAAO,KAAK;;;;IAI/B;;;;;AAKE,IAAAD,GAAA,CAAC,cAAc,EAAA,EAAC,MAAM,EAAE,SAAS,CAAC,SAAS,EAAE,UAAU,CAAC,EAAA,QAAA,EACtDA,GAAA,CAACE,WAAiB,CAAC,IAAI,EAAA,EAAC,OAAO,EAAA,IAAA,EAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,EAAA,QAAA,EACnE,KAAK,EAAA,CACiB,EAAA,CACV;AAErB,CAAC;AAGH,YAAY,CAAC,WAAW,GAAG,eAAe;;;;"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { MouseEventHandler, ReactNode } from 'react';
|
|
2
|
+
export declare const NavListItem: import("react").ForwardRefExoticComponent<Omit<import("@chakra-ui/react").HTMLChakraProps<"a">, "asChild" | "aria-current" | "children" | "onClick"> & {
|
|
3
|
+
children?: ReactNode;
|
|
4
|
+
href?: string;
|
|
5
|
+
asChild?: boolean;
|
|
6
|
+
onClick?: MouseEventHandler<HTMLElement>;
|
|
7
|
+
isCurrent?: boolean;
|
|
8
|
+
isDisabled?: boolean;
|
|
9
|
+
leadingVisual?: ReactNode;
|
|
10
|
+
trailingVisual?: ReactNode;
|
|
11
|
+
trailingAction?: ReactNode;
|
|
12
|
+
trailingActionVisibility?: import("./NavList.types").NavListTrailingActionVisibility;
|
|
13
|
+
tooltip?: ReactNode;
|
|
14
|
+
tooltipPlacement?: import("./NavList.types").NavListTooltipPlacement;
|
|
15
|
+
} & import("react").RefAttributes<HTMLElement>>;
|
|
16
|
+
//# sourceMappingURL=NavListItem.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NavListItem.d.ts","sourceRoot":"","sources":["../../../src/components/NavList/NavListItem.tsx"],"names":[],"mappings":"AAAA,OAAO,EAOL,iBAAiB,EAEjB,SAAS,EAMV,MAAM,OAAO,CAAC;AAsDf,eAAO,MAAM,WAAW;;;;;;;;;;;;;+CA0cvB,CAAC"}
|