@devslab/dds-react 0.28.0 → 0.29.1
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.ko.md +19 -0
- package/README.md +30 -0
- package/dist/console-shell.d.ts +9 -13
- package/dist/console-shell.d.ts.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +280 -139
- package/dist/index.js.map +1 -1
- package/dist/layout.d.ts +19 -0
- package/dist/layout.d.ts.map +1 -0
- package/dist/left-nav.d.ts +33 -0
- package/dist/left-nav.d.ts.map +1 -0
- package/dist/top-nav.d.ts +4 -0
- package/dist/top-nav.d.ts.map +1 -0
- package/package.json +4 -4
package/README.ko.md
CHANGED
|
@@ -80,3 +80,22 @@ Input/InputGroup은 검색 전용이 아닌 일반 입력 기반이며 라벨
|
|
|
80
80
|
|
|
81
81
|
상세 import: `@devslab/dds-react/input`, `/combobox`, `/select-picker`, `/dropdown-menu`, `/popover`, `/calendar`, `/date-picker`, `/date-range-picker`, `/month-picker`. 기존 루트 import와 `styles.css`는 유지합니다. [공통 사용 가이드](https://github.com/devslab-kr/dds/blob/main/docs/components-input-choice-calendar.ko.md)를 참고하세요.
|
|
82
82
|
상세 import: `@devslab/dds-react/input`, `/combobox`, `/select-picker`, `/dropdown-menu`, `/popover`, `/calendar`, `/date-picker`, `/time-picker`, `/date-range-picker`, `/month-picker`, `/segmented-control`, `/number-input`. 기존 루트 import와 `styles.css`는 유지합니다. [공통 사용 가이드](https://github.com/devslab-kr/dds/blob/main/docs/components-input-choice-calendar.ko.md)를 참고하세요.
|
|
83
|
+
|
|
84
|
+
## 선택형 콘솔 메뉴 그룹
|
|
85
|
+
|
|
86
|
+
기존 그룹은 계속 펼쳐집니다. 고유한 `id`와 `collapsible: true`를 지정한 그룹에만
|
|
87
|
+
접기·펼치기 버튼을 제공합니다. 항목의 `icon`은 장식용이며 이름은 `label`로 제공합니다.
|
|
88
|
+
`expandedGroups`와 `onExpandedGroupsChange`로 앱에서 상태를 제어합니다.
|
|
89
|
+
외부 상태를 생략하면 내부 상태를 사용합니다. `defaultExpandedGroups`가 초기값이며,
|
|
90
|
+
빈 배열은 모두 접기, 초기값 생략은 활성 항목을 포함한 그룹만 펼치기입니다.
|
|
91
|
+
옵션이 없는 그룹은 항상 펼쳐지고 여러 그룹을 동시에 열 수 있습니다.
|
|
92
|
+
ID 생략 시 `group-<index>`를 사용하므로 순서 변경·상태 보관에는 안정적인 고유 ID를 쓰세요.
|
|
93
|
+
페이지 이동 시 그룹 열기와 세션 보관은 앱에서 처리합니다. 저장소는 hydration 이후 읽고
|
|
94
|
+
서버와 최초 클라이언트 상태를 일치시키세요. DDS는 저장소에 접근하거나 제어 상태를
|
|
95
|
+
임의로 덮어쓰지 않습니다. 데스크톱·모바일 모두 Enter/Space 조작과
|
|
96
|
+
`aria-expanded`, `aria-controls`를 지원합니다.
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
## 공통 업무 화면
|
|
100
|
+
|
|
101
|
+
Layout·LeftNav·TopNav는 공통 간격과 타이포 규격을 사용합니다. [조립 방법과 수치](../../docs/layouts.ko.md)를 참고하세요.
|
package/README.md
CHANGED
|
@@ -114,3 +114,33 @@ Input/InputGroup are general-purpose native inputs, not search-only, with label
|
|
|
114
114
|
|
|
115
115
|
Use explicit subpaths `@devslab/dds-react/input`, `/combobox`, `/select-picker`, `/dropdown-menu`, `/popover`, `/calendar`, `/date-picker`, `/date-range-picker`, `/month-picker`, or the existing root exports. Keep importing `styles.css` once. See the [common usage guide](https://github.com/devslab-kr/dds/blob/main/docs/components-input-choice-calendar.md).
|
|
116
116
|
Use explicit subpaths `@devslab/dds-react/input`, `/combobox`, `/select-picker`, `/dropdown-menu`, `/popover`, `/calendar`, `/date-picker`, `/time-picker`, `/date-range-picker`, `/month-picker`, `/segmented-control`, `/number-input`, or the existing root exports. Keep importing `styles.css` once. See the [common usage guide](https://github.com/devslab-kr/dds/blob/main/docs/components-input-choice-calendar.md).
|
|
117
|
+
|
|
118
|
+
## Optional console navigation groups
|
|
119
|
+
|
|
120
|
+
`ConsoleShell` keeps legacy groups expanded. Set a unique, stable `id` and
|
|
121
|
+
`collapsible: true` on a group to opt into disclosure buttons. An item's optional
|
|
122
|
+
`icon` is decorative; keep its text `label`.
|
|
123
|
+
|
|
124
|
+
```tsx
|
|
125
|
+
<ConsoleShell {...shellProps}
|
|
126
|
+
nav={[{ id: "settings", label: "Settings", collapsible: true,
|
|
127
|
+
items: [{ id: "policies", href: "/policies", label: "Policies", icon: <Icon name="check" /> }] }]}
|
|
128
|
+
expandedGroups={expandedGroups}
|
|
129
|
+
onExpandedGroupsChange={setExpandedGroups}
|
|
130
|
+
/>
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Omit `expandedGroups` for internal state. `defaultExpandedGroups` supplies its
|
|
134
|
+
initial value; `[]` starts all collapsible groups closed. With neither prop, only
|
|
135
|
+
groups containing the active item start open. Other groups always stay open.
|
|
136
|
+
Multiple groups may be expanded. Missing IDs fall back to `group-<index>`; prefer
|
|
137
|
+
stable unique IDs for persistence or reordering. The app owns route-change
|
|
138
|
+
expansion and persistence. Read browser storage after hydration, keeping server
|
|
139
|
+
and initial client state equal. DDS never accesses storage or overwrites a
|
|
140
|
+
controlled selection. Enter/Space and `aria-expanded`/`aria-controls` work in both
|
|
141
|
+
the desktop rail and mobile drawer.
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
## Shared application layouts
|
|
145
|
+
|
|
146
|
+
Layout, LeftNav and TopNav use the common geometry and typography rules. See [composition and exact dimensions](../../docs/layouts.md).
|
package/dist/console-shell.d.ts
CHANGED
|
@@ -1,15 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
href: string;
|
|
5
|
-
label: string;
|
|
6
|
-
badge?: number;
|
|
7
|
-
active?: boolean;
|
|
8
|
-
}
|
|
9
|
-
export interface ConsoleNavGroup {
|
|
10
|
-
label: string;
|
|
11
|
-
items: readonly ConsoleNavItem[];
|
|
12
|
-
}
|
|
1
|
+
import type { HTMLAttributes, ReactNode } from "react";
|
|
2
|
+
import { type ConsoleNavGroup } from "./left-nav";
|
|
3
|
+
export type { ConsoleNavItem, ConsoleNavGroup } from "./left-nav";
|
|
13
4
|
export interface ConsoleShellLabels {
|
|
14
5
|
skip: string;
|
|
15
6
|
menuOpen: string;
|
|
@@ -34,7 +25,12 @@ export interface ConsoleShellProps extends Omit<HTMLAttributes<HTMLDivElement>,
|
|
|
34
25
|
label: string;
|
|
35
26
|
value: string;
|
|
36
27
|
}[];
|
|
37
|
-
nav
|
|
28
|
+
nav?: readonly ConsoleNavGroup[];
|
|
29
|
+
/** Supply a standalone LeftNav or custom navigation. */
|
|
30
|
+
navigation?: ReactNode;
|
|
31
|
+
expandedGroups?: readonly string[];
|
|
32
|
+
defaultExpandedGroups?: readonly string[];
|
|
33
|
+
onExpandedGroupsChange?: (groupIds: string[]) => void;
|
|
38
34
|
labels: ConsoleShellLabels;
|
|
39
35
|
header: ConsoleHeader;
|
|
40
36
|
foot?: ReactNode;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"console-shell.d.ts","sourceRoot":"","sources":["../src/console-shell.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"console-shell.d.ts","sourceRoot":"","sources":["../src/console-shell.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvD,OAAO,EAAW,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AAC3D,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClE,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AACD,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,SAAS,CAAC;CACrB;AACD,MAAM,WAAW,iBAAkB,SAAQ,IAAI,CAC7C,cAAc,CAAC,cAAc,CAAC,EAC9B,UAAU,GAAG,SAAS,CACvB;IACC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACpD,OAAO,CAAC,EAAE,SAAS;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACtD,GAAG,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IACjC,wDAAwD;IACxD,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,qBAAqB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,sBAAsB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACtD,MAAM,EAAE,kBAAkB,CAAC;IAC3B,MAAM,EAAE,aAAa,CAAC;IACtB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,QAAQ,EAAE,SAAS,CAAC;CACrB;AACD,eAAO,MAAM,YAAY,8GA8ExB,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -4,6 +4,9 @@ export * from "./overlays";
|
|
|
4
4
|
export * from "./icon";
|
|
5
5
|
export * from "./toast";
|
|
6
6
|
export * from "./console-shell";
|
|
7
|
+
export { LeftNav, type LeftNavProps } from "./left-nav";
|
|
8
|
+
export * from "./layout";
|
|
9
|
+
export * from "./top-nav";
|
|
7
10
|
export { Dialog as ArkDialog } from "@ark-ui/react/dialog";
|
|
8
11
|
export { Tabs as ArkTabs } from "@ark-ui/react/tabs";
|
|
9
12
|
export { Tooltip as ArkTooltip } from "@ark-ui/react/tooltip";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,iBAAiB,CAAC;AAChC,OAAO,EAAE,MAAM,IAAI,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,IAAI,IAAI,OAAO,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,UAAU,IAAI,aAAa,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,EAAE,QAAQ,IAAI,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,MAAM,IAAI,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,KAAK,IAAI,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,KAAK,IAAI,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAExD,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,UAAU,IAAI,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAExE,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AAEjC,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AACpF,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,iBAAiB,CAAC;AAChC,OAAO,EAAE,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AACxD,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,OAAO,EAAE,MAAM,IAAI,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,IAAI,IAAI,OAAO,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,UAAU,IAAI,aAAa,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,EAAE,QAAQ,IAAI,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,MAAM,IAAI,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,KAAK,IAAI,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,KAAK,IAAI,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAExD,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,UAAU,IAAI,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAExE,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AAEjC,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AACpF,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -10,41 +10,41 @@ import { Popover as g } from "./popover.js";
|
|
|
10
10
|
import { Calendar as _ } from "./calendar.js";
|
|
11
11
|
import { t as v } from "./time-picker-BNmQMQdq.js";
|
|
12
12
|
import { SegmentedControl as y, validateSegmentedItems as b } from "./segmented-control.js";
|
|
13
|
-
import { NumberInput as x, normalizeNumberText as S, numberInputMessages as
|
|
14
|
-
import { createContext as
|
|
15
|
-
import { Field as
|
|
13
|
+
import { NumberInput as x, normalizeNumberText as S, numberInputMessages as C } from "./number-input.js";
|
|
14
|
+
import { createContext as w, forwardRef as T, useCallback as E, useContext as D, useEffect as O, useId as k, useMemo as A, useRef as j, useState as M } from "react";
|
|
15
|
+
import { Field as ee } from "@ark-ui/react/field";
|
|
16
16
|
import { Checkbox as N } from "@ark-ui/react/checkbox";
|
|
17
17
|
import { Switch as P } from "@ark-ui/react/switch";
|
|
18
18
|
import { Fragment as F, jsx as I, jsxs as L } from "react/jsx-runtime";
|
|
19
19
|
import { Tabs as R, Tabs as z, useTabsContext as B } from "@ark-ui/react/tabs";
|
|
20
|
-
import { RadioGroup as
|
|
21
|
-
import { Dialog as
|
|
22
|
-
import { Tooltip as
|
|
23
|
-
import { Portal as
|
|
24
|
-
import { directionPolicy as
|
|
25
|
-
import { Toast as
|
|
26
|
-
import { DatePicker as
|
|
20
|
+
import { RadioGroup as te, RadioGroup as V, useRadioGroupContext as ne } from "@ark-ui/react/radio-group";
|
|
21
|
+
import { Dialog as re, Dialog as H } from "@ark-ui/react/dialog";
|
|
22
|
+
import { Tooltip as U, Tooltip as W } from "@ark-ui/react/tooltip";
|
|
23
|
+
import { Portal as G } from "@ark-ui/react/portal";
|
|
24
|
+
import { directionPolicy as K, icons as q } from "@devslab/dds-icons";
|
|
25
|
+
import { Toast as J, Toast as Y, Toaster as ie, createToaster as ae } from "@ark-ui/react/toast";
|
|
26
|
+
import { DatePicker as oe } from "@ark-ui/react/date-picker";
|
|
27
27
|
//#region src/selection.tsx
|
|
28
|
-
var
|
|
28
|
+
var se = T(function({ onValueChange: e, unstyled: n, className: r, ...i }, a) {
|
|
29
29
|
return /* @__PURE__ */ I(z.Root, {
|
|
30
30
|
...i,
|
|
31
31
|
ref: a,
|
|
32
32
|
onValueChange: (t) => e?.(t.value),
|
|
33
33
|
className: t(!n && "dds-tabs-root", r)
|
|
34
34
|
});
|
|
35
|
-
}),
|
|
35
|
+
}), ce = T(function({ unstyled: e, className: n, ...r }, i) {
|
|
36
36
|
return /* @__PURE__ */ I(z.List, {
|
|
37
37
|
...r,
|
|
38
38
|
ref: i,
|
|
39
39
|
className: t(!e && "dds-tabs", n)
|
|
40
40
|
});
|
|
41
|
-
}),
|
|
41
|
+
}), le = T(function({ unstyled: e, className: n, ...r }, i) {
|
|
42
42
|
return /* @__PURE__ */ I(z.Trigger, {
|
|
43
43
|
...r,
|
|
44
44
|
ref: i,
|
|
45
45
|
className: t(!e && "dds-tab", n)
|
|
46
46
|
});
|
|
47
|
-
}),
|
|
47
|
+
}), ue = T(function({ value: e, style: t, ...n }, r) {
|
|
48
48
|
let i = B().value !== e;
|
|
49
49
|
return /* @__PURE__ */ I(z.Content, {
|
|
50
50
|
...n,
|
|
@@ -57,8 +57,8 @@ var ie = w(function({ onValueChange: e, unstyled: n, className: r, ...i }, a) {
|
|
|
57
57
|
} : t
|
|
58
58
|
});
|
|
59
59
|
});
|
|
60
|
-
function
|
|
61
|
-
let t =
|
|
60
|
+
function de({ option: e }) {
|
|
61
|
+
let t = ne(), { style: n, defaultChecked: r, ...i } = t.getItemHiddenInputProps(e);
|
|
62
62
|
return /* @__PURE__ */ I("input", {
|
|
63
63
|
...i,
|
|
64
64
|
checked: t.value === e.value,
|
|
@@ -66,8 +66,8 @@ function ce({ option: e }) {
|
|
|
66
66
|
className: "dds-check__input"
|
|
67
67
|
});
|
|
68
68
|
}
|
|
69
|
-
var
|
|
70
|
-
return /* @__PURE__ */ L(
|
|
69
|
+
var fe = T(function({ options: e, label: n, onValueChange: r, className: i, children: a, ...o }, s) {
|
|
70
|
+
return /* @__PURE__ */ L(V.Root, {
|
|
71
71
|
...o,
|
|
72
72
|
ref: s,
|
|
73
73
|
onValueChange: (e) => {
|
|
@@ -75,26 +75,26 @@ var le = w(function({ options: e, label: n, onValueChange: r, className: i, chil
|
|
|
75
75
|
},
|
|
76
76
|
className: t("dds-radio-group", i),
|
|
77
77
|
children: [
|
|
78
|
-
/* @__PURE__ */ I(
|
|
78
|
+
/* @__PURE__ */ I(V.Label, {
|
|
79
79
|
className: "dds-field__label",
|
|
80
80
|
children: n
|
|
81
81
|
}),
|
|
82
|
-
e.map((e) => /* @__PURE__ */ L(
|
|
82
|
+
e.map((e) => /* @__PURE__ */ L(V.Item, {
|
|
83
83
|
value: e.value,
|
|
84
84
|
disabled: e.disabled,
|
|
85
85
|
className: "dds-check",
|
|
86
|
-
children: [/* @__PURE__ */ I(
|
|
86
|
+
children: [/* @__PURE__ */ I(de, { option: e }), /* @__PURE__ */ I(V.ItemText, { children: e.label })]
|
|
87
87
|
}, e.value)),
|
|
88
88
|
a
|
|
89
89
|
]
|
|
90
90
|
});
|
|
91
|
-
}),
|
|
91
|
+
}), pe = T(function({ title: e, description: n, children: r, actions: i, onOpenChange: a, closeOnOutside: o, portal: s = !0, className: c, overlayClassName: l, contentProps: u, initialFocus: d, finalFocus: f, frame: p, unstyled: m, ...h }, g) {
|
|
92
92
|
let _ = {
|
|
93
|
-
title: /* @__PURE__ */ I(
|
|
93
|
+
title: /* @__PURE__ */ I(H.Title, {
|
|
94
94
|
className: m ? void 0 : "dds-dialog__title",
|
|
95
95
|
children: e
|
|
96
96
|
}),
|
|
97
|
-
description: n && /* @__PURE__ */ I(
|
|
97
|
+
description: n && /* @__PURE__ */ I(H.Description, {
|
|
98
98
|
className: m ? void 0 : "dds-dialog__body",
|
|
99
99
|
children: n
|
|
100
100
|
}),
|
|
@@ -103,9 +103,9 @@ var le = w(function({ options: e, label: n, onValueChange: r, className: i, chil
|
|
|
103
103
|
className: m ? void 0 : "dds-dialog__actions",
|
|
104
104
|
children: i
|
|
105
105
|
})
|
|
106
|
-
}, v = /* @__PURE__ */ I(
|
|
106
|
+
}, v = /* @__PURE__ */ I(H.Positioner, {
|
|
107
107
|
className: t(!m && "dds-dialog-overlay", l),
|
|
108
|
-
children: /* @__PURE__ */ I(
|
|
108
|
+
children: /* @__PURE__ */ I(H.Content, {
|
|
109
109
|
...u,
|
|
110
110
|
ref: g,
|
|
111
111
|
"aria-describedby": n ? u?.["aria-describedby"] : void 0,
|
|
@@ -118,7 +118,7 @@ var le = w(function({ options: e, label: n, onValueChange: r, className: i, chil
|
|
|
118
118
|
] })
|
|
119
119
|
})
|
|
120
120
|
});
|
|
121
|
-
return /* @__PURE__ */ I(
|
|
121
|
+
return /* @__PURE__ */ I(H.Root, {
|
|
122
122
|
...h,
|
|
123
123
|
onOpenChange: (e) => a?.(e.open),
|
|
124
124
|
closeOnInteractOutside: o ?? h.closeOnInteractOutside,
|
|
@@ -126,21 +126,21 @@ var le = w(function({ options: e, label: n, onValueChange: r, className: i, chil
|
|
|
126
126
|
finalFocusEl: f ? () => f() ?? null : h.finalFocusEl,
|
|
127
127
|
lazyMount: !0,
|
|
128
128
|
unmountOnExit: !0,
|
|
129
|
-
children: s ? /* @__PURE__ */ I(
|
|
129
|
+
children: s ? /* @__PURE__ */ I(G, { children: v }) : v
|
|
130
130
|
});
|
|
131
131
|
});
|
|
132
|
-
function
|
|
133
|
-
return /* @__PURE__ */ I(
|
|
132
|
+
function me({ content: e, children: n, onOpenChange: r, className: i, contentProps: a, ...o }) {
|
|
133
|
+
return /* @__PURE__ */ I(W.Root, {
|
|
134
134
|
openDelay: 0,
|
|
135
135
|
closeDelay: 0,
|
|
136
136
|
...o,
|
|
137
137
|
onOpenChange: (e) => r?.(e.open),
|
|
138
138
|
children: /* @__PURE__ */ L("span", {
|
|
139
139
|
className: t("dds-tooltip", i),
|
|
140
|
-
children: [typeof n == "function" ? /* @__PURE__ */ I(
|
|
140
|
+
children: [typeof n == "function" ? /* @__PURE__ */ I(W.Context, { children: (e) => n(e.getTriggerProps()) }) : /* @__PURE__ */ I(W.Trigger, {
|
|
141
141
|
asChild: !0,
|
|
142
142
|
children: n
|
|
143
|
-
}), /* @__PURE__ */ I(
|
|
143
|
+
}), /* @__PURE__ */ I(G, { children: /* @__PURE__ */ I(W.Positioner, { children: /* @__PURE__ */ I(W.Content, {
|
|
144
144
|
...a,
|
|
145
145
|
className: t("dds-tooltip__bubble", a?.className),
|
|
146
146
|
children: e
|
|
@@ -150,8 +150,8 @@ function de({ content: e, children: n, onOpenChange: r, className: i, contentPro
|
|
|
150
150
|
}
|
|
151
151
|
//#endregion
|
|
152
152
|
//#region src/icon.tsx
|
|
153
|
-
var
|
|
154
|
-
let c =
|
|
153
|
+
var he = T(function({ name: e, label: n, size: r = 24, directional: i, className: a, ...o }, s) {
|
|
154
|
+
let c = q[e];
|
|
155
155
|
return /* @__PURE__ */ L("svg", {
|
|
156
156
|
...o,
|
|
157
157
|
ref: s,
|
|
@@ -166,19 +166,19 @@ var fe = w(function({ name: e, label: n, size: r = 24, directional: i, className
|
|
|
166
166
|
role: n ? "img" : void 0,
|
|
167
167
|
"aria-label": n,
|
|
168
168
|
"aria-hidden": !n || void 0,
|
|
169
|
-
className: t((i ??
|
|
169
|
+
className: t((i ?? K.mirrorInRtl.includes(e)) && K.cssClass, a),
|
|
170
170
|
children: [n && /* @__PURE__ */ I("title", { children: n }), /* @__PURE__ */ I("g", { dangerouslySetInnerHTML: { __html: c.body } })]
|
|
171
171
|
});
|
|
172
|
-
}),
|
|
173
|
-
function
|
|
174
|
-
let o =
|
|
172
|
+
}), X = w(null);
|
|
173
|
+
function ge({ children: e, defaultDuration: n = 5e3, dismissLabel: r, regionLabel: i, className: a }) {
|
|
174
|
+
let o = k(), s = j(0), c = A(() => ae({
|
|
175
175
|
placement: "bottom-end",
|
|
176
176
|
overlap: !1,
|
|
177
177
|
gap: 8,
|
|
178
178
|
offsets: "var(--dds-space-16)",
|
|
179
179
|
removeDelay: 0,
|
|
180
180
|
hotkey: ["DDS_NO_HOTKEY"]
|
|
181
|
-
}), []), l =
|
|
181
|
+
}), []), l = A(() => ({
|
|
182
182
|
show(e) {
|
|
183
183
|
let t = `dds-toast-${o}-${++s.current}`, r = e.duration ?? n;
|
|
184
184
|
return c.create({
|
|
@@ -199,9 +199,9 @@ function pe({ children: e, defaultDuration: n = 5e3, dismissLabel: r, regionLabe
|
|
|
199
199
|
o,
|
|
200
200
|
n
|
|
201
201
|
]);
|
|
202
|
-
return
|
|
202
|
+
return O(() => () => c.remove(), [c]), /* @__PURE__ */ L(X.Provider, {
|
|
203
203
|
value: l,
|
|
204
|
-
children: [e, /* @__PURE__ */ I(
|
|
204
|
+
children: [e, /* @__PURE__ */ I(ie, {
|
|
205
205
|
toaster: c,
|
|
206
206
|
label: i ?? "",
|
|
207
207
|
"aria-label": i ?? "",
|
|
@@ -209,10 +209,10 @@ function pe({ children: e, defaultDuration: n = 5e3, dismissLabel: r, regionLabe
|
|
|
209
209
|
className: t("dds-toast-region", a),
|
|
210
210
|
children: (e) => {
|
|
211
211
|
let n = e.meta?.dds;
|
|
212
|
-
return /* @__PURE__ */ L(
|
|
212
|
+
return /* @__PURE__ */ L(J.Root, {
|
|
213
213
|
className: t("dds-toast", `dds-toast--${n.tone ?? "info"}`),
|
|
214
214
|
role: n.tone === "danger" ? "alert" : "status",
|
|
215
|
-
children: [/* @__PURE__ */ I(
|
|
215
|
+
children: [/* @__PURE__ */ I(J.Description, { children: e.description }), r && /* @__PURE__ */ I(J.CloseTrigger, {
|
|
216
216
|
className: "dds-iconbtn dds-iconbtn--sm",
|
|
217
217
|
"aria-label": typeof r == "function" ? r(n) : r,
|
|
218
218
|
children: "×"
|
|
@@ -222,126 +222,267 @@ function pe({ children: e, defaultDuration: n = 5e3, dismissLabel: r, regionLabe
|
|
|
222
222
|
})]
|
|
223
223
|
});
|
|
224
224
|
}
|
|
225
|
-
function
|
|
226
|
-
let e =
|
|
225
|
+
function _e() {
|
|
226
|
+
let e = D(X);
|
|
227
227
|
if (!e) throw Error("useToast must be called inside <ToastProvider>");
|
|
228
228
|
return e;
|
|
229
229
|
}
|
|
230
230
|
//#endregion
|
|
231
|
-
//#region src/
|
|
232
|
-
function
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
return
|
|
238
|
-
|
|
239
|
-
let e = (
|
|
240
|
-
e.
|
|
231
|
+
//#region src/layout.tsx
|
|
232
|
+
var Z = T(function({ navigationPosition: e = "left", contentWidth: n = "workspace", labels: r, header: i, navigation: a, railStart: o, railEnd: s, footer: c, children: l, surface: u, className: d, ...f }, p) {
|
|
233
|
+
let m = k(), h = `dds-console-rail-${m}`, g = `dds-console-main-${m}`, [_, v] = M(!1), [y, b] = M(!1), x = j(null), S = j(null);
|
|
234
|
+
function C() {
|
|
235
|
+
v(!1), x.current?.focus();
|
|
236
|
+
}
|
|
237
|
+
return O(() => {
|
|
238
|
+
if (b(!0), typeof window.matchMedia != "function") return;
|
|
239
|
+
let e = window.matchMedia("(max-width: 56.25rem)"), t = () => {
|
|
240
|
+
e.matches || v(!1);
|
|
241
241
|
};
|
|
242
|
-
return
|
|
243
|
-
}, []),
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
242
|
+
return e.addEventListener("change", t), () => e.removeEventListener("change", t);
|
|
243
|
+
}, []), O(() => {
|
|
244
|
+
if (!_) return;
|
|
245
|
+
let e = () => [x.current, ...Array.from(S.current?.querySelectorAll("a[href],button,summary,input,select,textarea,[tabindex=\"0\"]") ?? [])].filter((e) => !!e && !e.closest("[hidden]") && e.getClientRects().length > 0 && getComputedStyle(e).visibility !== "hidden" && !Array.from(S.current?.querySelectorAll("details:not([open])") ?? []).some((t) => t.contains(e) && !t.querySelector("summary")?.contains(e)) && !e.hasAttribute("disabled"));
|
|
246
|
+
e()[1]?.focus();
|
|
247
|
+
function t(t) {
|
|
248
|
+
if (t.key === "Escape" && (t.preventDefault(), C()), t.key === "Tab") {
|
|
249
|
+
let n = e(), r = n[0], i = n.at(-1);
|
|
250
|
+
t.shiftKey && document.activeElement === r ? (t.preventDefault(), i?.focus()) : !t.shiftKey && document.activeElement === i && (t.preventDefault(), r?.focus());
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
return document.addEventListener("keydown", t), () => {
|
|
254
|
+
document.removeEventListener("keydown", t);
|
|
255
|
+
};
|
|
256
|
+
}, [_]), /* @__PURE__ */ L("div", {
|
|
257
|
+
...f,
|
|
258
|
+
ref: p,
|
|
259
|
+
className: t("dds-console-shell dds-layout", d),
|
|
260
|
+
"data-navigation-position": e,
|
|
261
|
+
"data-surface": u,
|
|
262
|
+
"data-hydrated": y ? "true" : void 0,
|
|
249
263
|
children: [
|
|
250
264
|
/* @__PURE__ */ I("a", {
|
|
251
265
|
className: "dds-console-skip dds-visually-hidden",
|
|
252
|
-
href: `#${
|
|
253
|
-
children:
|
|
266
|
+
href: `#${g}`,
|
|
267
|
+
children: r.skip
|
|
254
268
|
}),
|
|
255
269
|
/* @__PURE__ */ L("button", {
|
|
270
|
+
ref: x,
|
|
256
271
|
className: "dds-console-rail__toggle",
|
|
257
272
|
type: "button",
|
|
258
273
|
"data-action": "toggle-rail",
|
|
259
|
-
"aria-controls":
|
|
260
|
-
"aria-expanded":
|
|
261
|
-
onClick: () =>
|
|
274
|
+
"aria-controls": h,
|
|
275
|
+
"aria-expanded": _,
|
|
276
|
+
onClick: () => _ ? C() : v(!0),
|
|
262
277
|
children: [/* @__PURE__ */ I("span", { "aria-hidden": !0 }), /* @__PURE__ */ I("span", {
|
|
263
278
|
className: "dds-visually-hidden",
|
|
264
|
-
children:
|
|
279
|
+
children: _ ? r.menuClose : r.menuOpen
|
|
265
280
|
})]
|
|
266
281
|
}),
|
|
267
282
|
/* @__PURE__ */ I("div", {
|
|
268
283
|
className: "dds-console-rail__scrim",
|
|
269
|
-
"data-open": String(
|
|
270
|
-
onClick:
|
|
284
|
+
"data-open": String(_),
|
|
285
|
+
onClick: C
|
|
271
286
|
}),
|
|
272
287
|
/* @__PURE__ */ L("aside", {
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
"
|
|
288
|
+
ref: S,
|
|
289
|
+
id: h,
|
|
290
|
+
className: "dds-console-rail dds-layout__navigation",
|
|
291
|
+
"data-open": String(_),
|
|
292
|
+
onClick: (e) => {
|
|
293
|
+
_ && e.target instanceof Element && e.target.closest("a[href]") && C();
|
|
294
|
+
},
|
|
276
295
|
children: [
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
children: [/* @__PURE__ */ I("img", {
|
|
281
|
-
src: r.mark,
|
|
282
|
-
alt: "",
|
|
283
|
-
width: 20,
|
|
284
|
-
height: 20
|
|
285
|
-
}), /* @__PURE__ */ I("strong", { children: r.name })]
|
|
286
|
-
}),
|
|
287
|
-
i && i.length > 0 && /* @__PURE__ */ I("dl", {
|
|
288
|
-
className: "dds-console-rail__context",
|
|
289
|
-
children: i.map((e, t) => /* @__PURE__ */ L("div", { children: [/* @__PURE__ */ I("dt", { children: e.label }), /* @__PURE__ */ I("dd", { children: e.value })] }, t))
|
|
290
|
-
}),
|
|
291
|
-
/* @__PURE__ */ I("nav", {
|
|
292
|
-
className: "dds-console-rail__nav",
|
|
293
|
-
"aria-label": o.nav,
|
|
294
|
-
children: a.map((t, r) => /* @__PURE__ */ L("section", {
|
|
295
|
-
className: "dds-console-rail__group",
|
|
296
|
-
"aria-labelledby": `${_}-group-${r}`,
|
|
297
|
-
children: [/* @__PURE__ */ I("h2", {
|
|
298
|
-
id: `${_}-group-${r}`,
|
|
299
|
-
className: "dds-console-rail__group-label",
|
|
300
|
-
children: t.label
|
|
301
|
-
}), /* @__PURE__ */ I("ul", { children: t.items.map((t) => /* @__PURE__ */ I("li", { children: /* @__PURE__ */ L("a", {
|
|
302
|
-
className: "dds-console-rail__item",
|
|
303
|
-
"data-nav": `${e}.${t.id}`,
|
|
304
|
-
href: t.href,
|
|
305
|
-
"aria-current": he(n, t) ? "page" : void 0,
|
|
306
|
-
onClick: () => m(!1),
|
|
307
|
-
children: [/* @__PURE__ */ I("span", { children: t.label }), t.badge !== void 0 && t.badge > 0 && /* @__PURE__ */ I("span", {
|
|
308
|
-
className: "dds-console-rail__badge",
|
|
309
|
-
"aria-label": o.badge.replace("{count}", () => String(t.badge)),
|
|
310
|
-
children: t.badge
|
|
311
|
-
})]
|
|
312
|
-
}) }, t.id)) })]
|
|
313
|
-
}, r))
|
|
314
|
-
}),
|
|
315
|
-
c && /* @__PURE__ */ I("div", {
|
|
316
|
-
className: "dds-console-rail__foot",
|
|
317
|
-
children: c
|
|
318
|
-
})
|
|
296
|
+
o,
|
|
297
|
+
a,
|
|
298
|
+
s
|
|
319
299
|
]
|
|
320
300
|
}),
|
|
321
|
-
/* @__PURE__ */
|
|
322
|
-
id:
|
|
323
|
-
className: "dds-console-main",
|
|
301
|
+
/* @__PURE__ */ I("main", {
|
|
302
|
+
id: g,
|
|
303
|
+
className: "dds-console-main dds-layout__main",
|
|
324
304
|
tabIndex: -1,
|
|
325
|
-
children:
|
|
326
|
-
className: "dds-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
className: "dds-
|
|
331
|
-
children:
|
|
332
|
-
}),
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
305
|
+
children: /* @__PURE__ */ L("div", {
|
|
306
|
+
className: "dds-layout__content",
|
|
307
|
+
"data-width": n,
|
|
308
|
+
children: [
|
|
309
|
+
i != null && /* @__PURE__ */ I("header", {
|
|
310
|
+
className: "dds-layout__header",
|
|
311
|
+
children: i
|
|
312
|
+
}),
|
|
313
|
+
l,
|
|
314
|
+
c != null && /* @__PURE__ */ I("footer", {
|
|
315
|
+
className: "dds-layout__footer",
|
|
316
|
+
children: c
|
|
317
|
+
})
|
|
318
|
+
]
|
|
319
|
+
})
|
|
338
320
|
})
|
|
339
321
|
]
|
|
340
322
|
});
|
|
341
323
|
});
|
|
342
324
|
//#endregion
|
|
325
|
+
//#region src/left-nav.tsx
|
|
326
|
+
function Q(e, t) {
|
|
327
|
+
return t.active ?? (t.href.split("/").filter(Boolean).length <= 1 ? e === t.href : e === t.href || e.startsWith(`${t.href}/`));
|
|
328
|
+
}
|
|
329
|
+
function $({ surface: e, activePath: t, nav: n, labels: r, expandedGroups: i, defaultExpandedGroups: a, onExpandedGroupsChange: o, onNavigate: s }) {
|
|
330
|
+
let c = k(), [l, u] = M(() => a ?? n.flatMap((e, n) => e.collapsible && e.items.some((e) => Q(t, e)) ? [e.id ?? `group-${n}`] : [])), d = i ?? l;
|
|
331
|
+
function f(e) {
|
|
332
|
+
let t = d.includes(e) ? d.filter((t) => t !== e) : [...d, e];
|
|
333
|
+
i === void 0 && u(t), o?.(t);
|
|
334
|
+
}
|
|
335
|
+
return /* @__PURE__ */ I("nav", {
|
|
336
|
+
className: "dds-console-rail__nav dds-left-nav",
|
|
337
|
+
"aria-label": r.nav,
|
|
338
|
+
children: n.map((n, i) => /* @__PURE__ */ L("section", {
|
|
339
|
+
"data-collapsible": n.collapsible ? "true" : void 0,
|
|
340
|
+
className: "dds-console-rail__group",
|
|
341
|
+
"aria-labelledby": `${c}-group-${i}`,
|
|
342
|
+
children: [/* @__PURE__ */ I("h2", {
|
|
343
|
+
id: `${c}-group-${i}`,
|
|
344
|
+
className: "dds-console-rail__group-label",
|
|
345
|
+
children: n.collapsible ? /* @__PURE__ */ L("button", {
|
|
346
|
+
type: "button",
|
|
347
|
+
className: "dds-console-rail__group-toggle",
|
|
348
|
+
"aria-expanded": d.includes(n.id ?? `group-${i}`),
|
|
349
|
+
"aria-controls": `${c}-group-items-${i}`,
|
|
350
|
+
onClick: () => f(n.id ?? `group-${i}`),
|
|
351
|
+
children: [/* @__PURE__ */ I("span", { children: n.label }), /* @__PURE__ */ I("span", {
|
|
352
|
+
className: "dds-console-rail__chevron",
|
|
353
|
+
"aria-hidden": "true"
|
|
354
|
+
})]
|
|
355
|
+
}) : n.label
|
|
356
|
+
}), /* @__PURE__ */ I("ul", {
|
|
357
|
+
id: `${c}-group-items-${i}`,
|
|
358
|
+
hidden: n.collapsible && !d.includes(n.id ?? `group-${i}`),
|
|
359
|
+
children: n.items.map((n) => /* @__PURE__ */ I("li", { children: /* @__PURE__ */ L("a", {
|
|
360
|
+
className: "dds-console-rail__item",
|
|
361
|
+
"data-nav": `${e}.${n.id}`,
|
|
362
|
+
href: n.href,
|
|
363
|
+
"aria-current": Q(t, n) ? "page" : void 0,
|
|
364
|
+
onClick: s,
|
|
365
|
+
children: [n.icon == null ? /* @__PURE__ */ I("span", { children: n.label }) : /* @__PURE__ */ L("span", {
|
|
366
|
+
className: "dds-console-rail__item-content",
|
|
367
|
+
children: [/* @__PURE__ */ I("span", {
|
|
368
|
+
className: "dds-console-rail__item-icon",
|
|
369
|
+
"aria-hidden": "true",
|
|
370
|
+
children: n.icon
|
|
371
|
+
}), /* @__PURE__ */ I("span", { children: n.label })]
|
|
372
|
+
}), n.badge !== void 0 && n.badge > 0 && /* @__PURE__ */ I("span", {
|
|
373
|
+
className: "dds-console-rail__badge",
|
|
374
|
+
"aria-label": r.badge.replace("{count}", () => String(n.badge)),
|
|
375
|
+
children: n.badge
|
|
376
|
+
})]
|
|
377
|
+
}) }, n.id))
|
|
378
|
+
})]
|
|
379
|
+
}, n.id ?? i))
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
//#endregion
|
|
383
|
+
//#region src/console-shell.tsx
|
|
384
|
+
var ve = T(function({ surface: e, activePath: t, brand: n, context: r, nav: i = [], navigation: a, expandedGroups: o, defaultExpandedGroups: s, onExpandedGroupsChange: c, labels: l, header: u, foot: d, children: f, ...p }, m) {
|
|
385
|
+
return /* @__PURE__ */ I(Z, {
|
|
386
|
+
...p,
|
|
387
|
+
ref: m,
|
|
388
|
+
surface: e,
|
|
389
|
+
labels: l,
|
|
390
|
+
railStart: /* @__PURE__ */ L(F, { children: [/* @__PURE__ */ L("a", {
|
|
391
|
+
className: "dds-console-rail__brand",
|
|
392
|
+
href: n.href,
|
|
393
|
+
children: [/* @__PURE__ */ I("img", {
|
|
394
|
+
src: n.mark,
|
|
395
|
+
alt: "",
|
|
396
|
+
width: 20,
|
|
397
|
+
height: 20
|
|
398
|
+
}), /* @__PURE__ */ I("strong", { children: n.name })]
|
|
399
|
+
}), r && r.length > 0 && /* @__PURE__ */ I("dl", {
|
|
400
|
+
className: "dds-console-rail__context",
|
|
401
|
+
children: r.map((e, t) => /* @__PURE__ */ L("div", { children: [/* @__PURE__ */ I("dt", { children: e.label }), /* @__PURE__ */ I("dd", { children: e.value })] }, t))
|
|
402
|
+
})] }),
|
|
403
|
+
navigation: a ?? /* @__PURE__ */ I($, {
|
|
404
|
+
surface: e,
|
|
405
|
+
activePath: t,
|
|
406
|
+
nav: i,
|
|
407
|
+
labels: l,
|
|
408
|
+
expandedGroups: o,
|
|
409
|
+
defaultExpandedGroups: s,
|
|
410
|
+
onExpandedGroupsChange: c
|
|
411
|
+
}),
|
|
412
|
+
railEnd: d && /* @__PURE__ */ I("div", {
|
|
413
|
+
className: "dds-console-rail__foot",
|
|
414
|
+
children: d
|
|
415
|
+
}),
|
|
416
|
+
header: /* @__PURE__ */ L("div", {
|
|
417
|
+
className: "dds-console-page-header",
|
|
418
|
+
children: [/* @__PURE__ */ L("div", {
|
|
419
|
+
className: "dds-console-page-header__text",
|
|
420
|
+
children: [u.eyebrow && /* @__PURE__ */ I("p", {
|
|
421
|
+
className: "dds-console-page-eyebrow",
|
|
422
|
+
children: u.eyebrow
|
|
423
|
+
}), /* @__PURE__ */ I("h1", { children: u.title })]
|
|
424
|
+
}), u.actions && /* @__PURE__ */ I("div", {
|
|
425
|
+
className: "dds-console-page-header__actions",
|
|
426
|
+
children: u.actions
|
|
427
|
+
})]
|
|
428
|
+
}),
|
|
429
|
+
children: f
|
|
430
|
+
});
|
|
431
|
+
});
|
|
432
|
+
//#endregion
|
|
433
|
+
//#region src/top-nav.tsx
|
|
434
|
+
function ye({ surface: e, activePath: t, nav: n, labels: r, onNavigate: i }) {
|
|
435
|
+
let a = j(null);
|
|
436
|
+
return O(() => {
|
|
437
|
+
function e(e) {
|
|
438
|
+
a.current?.contains(e.target) || a.current?.querySelectorAll("details[open]").forEach((e) => e.removeAttribute("open"));
|
|
439
|
+
}
|
|
440
|
+
return document.addEventListener("pointerdown", e), () => document.removeEventListener("pointerdown", e);
|
|
441
|
+
}, []), /* @__PURE__ */ I("nav", {
|
|
442
|
+
ref: a,
|
|
443
|
+
className: "dds-top-nav",
|
|
444
|
+
"aria-label": r.nav,
|
|
445
|
+
onKeyDown: (e) => {
|
|
446
|
+
if (e.key !== "Escape") return;
|
|
447
|
+
let t = e.target.closest("details");
|
|
448
|
+
t?.open && (e.preventDefault(), e.stopPropagation(), t.open = !1, t.querySelector("summary")?.focus());
|
|
449
|
+
},
|
|
450
|
+
children: n.map((n, a) => /* @__PURE__ */ L("details", {
|
|
451
|
+
className: "dds-top-nav__group",
|
|
452
|
+
children: [/* @__PURE__ */ I("summary", {
|
|
453
|
+
className: "dds-top-nav__trigger",
|
|
454
|
+
children: n.label
|
|
455
|
+
}), /* @__PURE__ */ I("ul", {
|
|
456
|
+
className: "dds-top-nav__items",
|
|
457
|
+
children: n.items.map((n) => /* @__PURE__ */ I("li", { children: /* @__PURE__ */ L("a", {
|
|
458
|
+
className: "dds-top-nav__item",
|
|
459
|
+
"data-nav": `${e}.${n.id}`,
|
|
460
|
+
href: n.href,
|
|
461
|
+
"aria-current": n.active ?? (t === n.href || n.href.split("/").filter(Boolean).length > 1 && t.startsWith(`${n.href}/`)) ? "page" : void 0,
|
|
462
|
+
onClick: (e) => {
|
|
463
|
+
e.currentTarget.closest("details")?.removeAttribute("open"), i?.();
|
|
464
|
+
},
|
|
465
|
+
children: [
|
|
466
|
+
n.icon != null && /* @__PURE__ */ I("span", {
|
|
467
|
+
className: "dds-top-nav__item-icon",
|
|
468
|
+
"aria-hidden": "true",
|
|
469
|
+
children: n.icon
|
|
470
|
+
}),
|
|
471
|
+
/* @__PURE__ */ I("span", { children: n.label }),
|
|
472
|
+
n.badge != null && n.badge > 0 && /* @__PURE__ */ I("span", {
|
|
473
|
+
className: "dds-console-rail__badge",
|
|
474
|
+
"aria-label": r.badge.replace("{count}", () => String(n.badge)),
|
|
475
|
+
children: n.badge
|
|
476
|
+
})
|
|
477
|
+
]
|
|
478
|
+
}) }, n.id))
|
|
479
|
+
})]
|
|
480
|
+
}, n.id ?? a))
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
//#endregion
|
|
343
484
|
//#region src/status-pill.tsx
|
|
344
|
-
function
|
|
485
|
+
function be(e) {
|
|
345
486
|
let t = new Set(e.openDomains ?? []);
|
|
346
487
|
return function(n) {
|
|
347
488
|
let r = e.tones[n.domain]?.[n.value], i = e.label(n.domain, n.value, n.locale);
|
|
@@ -362,12 +503,12 @@ function _e(e) {
|
|
|
362
503
|
}
|
|
363
504
|
//#endregion
|
|
364
505
|
//#region src/pending-action.ts
|
|
365
|
-
function
|
|
366
|
-
let [e, t] =
|
|
367
|
-
|
|
506
|
+
function xe() {
|
|
507
|
+
let [e, t] = M(null), n = j(null);
|
|
508
|
+
O(() => () => {
|
|
368
509
|
n.current?.abort(), n.current = null;
|
|
369
510
|
}, []);
|
|
370
|
-
let r =
|
|
511
|
+
let r = E(async (e, r, i) => {
|
|
371
512
|
if (n.current && !i?.replace) return;
|
|
372
513
|
n.current?.abort();
|
|
373
514
|
let a = new AbortController();
|
|
@@ -377,10 +518,10 @@ function ve() {
|
|
|
377
518
|
} finally {
|
|
378
519
|
n.current === a && (n.current = null, t(null));
|
|
379
520
|
}
|
|
380
|
-
}, []), i =
|
|
521
|
+
}, []), i = E(() => {
|
|
381
522
|
n.current?.abort(), n.current = null, t(null);
|
|
382
523
|
}, []);
|
|
383
|
-
return
|
|
524
|
+
return A(() => ({
|
|
384
525
|
current: e,
|
|
385
526
|
busy: e !== null,
|
|
386
527
|
is: (t) => e === t,
|
|
@@ -393,6 +534,6 @@ function ve() {
|
|
|
393
534
|
]);
|
|
394
535
|
}
|
|
395
536
|
//#endregion
|
|
396
|
-
export { N as ArkCheckbox,
|
|
537
|
+
export { N as ArkCheckbox, oe as ArkDatePicker, re as ArkDialog, ee as ArkField, te as ArkRadioGroup, P as ArkSwitch, R as ArkTabs, Y as ArkToast, U as ArkTooltip, s as Button, _ as Calendar, r as Checkbox, p as Combobox, ve as ConsoleShell, c as DatePicker, l as DateRangePicker, pe as Dialog, h as DropdownMenu, a as Field, he as Icon, n as IconButton, d as Input, f as InputGroup, Z as Layout, $ as LeftNav, u as MonthPicker, x as NumberInput, g as Popover, e as Radio, fe as RadioGroup, y as SegmentedControl, i as Select, m as SelectPicker, o as Switch, le as Tab, ce as TabList, ue as TabPanel, se as Tabs, v as TimePicker, ge as ToastProvider, me as Tooltip, ye as TopNav, t as classes, be as createStatusPill, S as normalizeNumberText, C as numberInputMessages, xe as usePendingAction, _e as useToast, b as validateSegmentedItems };
|
|
397
538
|
|
|
398
539
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/selection.tsx","../src/overlays.tsx","../src/icon.tsx","../src/toast.tsx","../src/console-shell.tsx","../src/status-pill.tsx","../src/pending-action.ts"],"sourcesContent":["import { forwardRef, type ComponentProps, type ReactNode } from \"react\";\nimport { Tabs as ArkTabs, useTabsContext } from \"@ark-ui/react/tabs\";\nimport {\n RadioGroup as ArkRadioGroup,\n useRadioGroupContext,\n} from \"@ark-ui/react/radio-group\";\nimport { classes } from \"./controls\";\nexport interface TabsProps\n extends Omit<ComponentProps<typeof ArkTabs.Root>, \"onValueChange\"> {\n onValueChange?: (value: string) => void;\n unstyled?: boolean;\n}\nexport const Tabs = forwardRef<HTMLDivElement, TabsProps>(function Tabs(\n { onValueChange, unstyled, className, ...rest },\n ref\n) {\n return (\n <ArkTabs.Root\n {...rest}\n ref={ref}\n onValueChange={(details) => onValueChange?.(details.value)}\n className={classes(!unstyled && \"dds-tabs-root\", className)}\n />\n );\n});\nexport type TabProps = ComponentProps<typeof ArkTabs.Trigger> & {\n unstyled?: boolean;\n};\nexport type TabPanelProps = ComponentProps<typeof ArkTabs.Content>;\nexport const TabList = forwardRef<\n HTMLDivElement,\n ComponentProps<typeof ArkTabs.List> & { unstyled?: boolean }\n>(function TabList({ unstyled, className, ...rest }, ref) {\n return (\n <ArkTabs.List\n {...rest}\n ref={ref}\n className={classes(!unstyled && \"dds-tabs\", className)}\n />\n );\n});\nexport const Tab = forwardRef<HTMLButtonElement, TabProps>(function Tab(\n { unstyled, className, ...rest },\n ref\n) {\n return (\n <ArkTabs.Trigger\n {...rest}\n ref={ref}\n className={classes(!unstyled && \"dds-tab\", className)}\n />\n );\n});\nexport const TabPanel = forwardRef<HTMLDivElement, TabPanelProps>(\n function TabPanel({ value, style, ...rest }, ref) {\n const tabs = useTabsContext();\n const inactive = tabs.value !== value;\n return (\n <ArkTabs.Content\n {...rest}\n value={value}\n ref={ref}\n hidden={inactive}\n style={inactive ? { ...style, display: \"none\" } : style}\n />\n );\n }\n);\nfunction VisibleRadioInput({ option }: { option: RadioOption }) {\n const group = useRadioGroupContext();\n // Ark owns selection and roving focus; DDS displays the native radio.\n const {\n style: _,\n defaultChecked: __,\n ...inputProps\n } = group.getItemHiddenInputProps(option);\n return (\n <input\n {...inputProps}\n checked={group.value === option.value}\n onChange={() => {}}\n className=\"dds-check__input\"\n />\n );\n}\nexport interface RadioOption {\n value: string;\n label: ReactNode;\n disabled?: boolean;\n}\nexport interface RadioGroupProps\n extends Omit<\n ComponentProps<typeof ArkRadioGroup.Root>,\n \"onValueChange\" | \"children\"\n > {\n options: readonly RadioOption[];\n label: ReactNode;\n onValueChange?: (value: string) => void;\n children?: ReactNode;\n}\nexport const RadioGroup = forwardRef<HTMLDivElement, RadioGroupProps>(\n function RadioGroup(\n { options, label, onValueChange, className, children, ...rest },\n ref\n ) {\n return (\n <ArkRadioGroup.Root\n {...rest}\n ref={ref}\n onValueChange={(details) => {\n if (details.value !== null) onValueChange?.(details.value);\n }}\n className={classes(\"dds-radio-group\", className)}\n >\n <ArkRadioGroup.Label className=\"dds-field__label\">\n {label}\n </ArkRadioGroup.Label>\n {options.map((option) => (\n <ArkRadioGroup.Item\n key={option.value}\n value={option.value}\n disabled={option.disabled}\n className=\"dds-check\"\n >\n <VisibleRadioInput option={option} />\n <ArkRadioGroup.ItemText>{option.label}</ArkRadioGroup.ItemText>\n </ArkRadioGroup.Item>\n ))}\n {children}\n </ArkRadioGroup.Root>\n );\n }\n);\n","import {\n forwardRef,\n type ComponentProps,\n type ButtonHTMLAttributes,\n type ReactNode,\n} from \"react\";\nimport { Dialog as ArkDialog } from \"@ark-ui/react/dialog\";\nimport { Tooltip as ArkTooltip } from \"@ark-ui/react/tooltip\";\nimport { Portal } from \"@ark-ui/react/portal\";\nimport { classes } from \"./controls\";\nexport interface DialogFrameParts {\n title: ReactNode;\n description: ReactNode;\n children: ReactNode;\n actions: ReactNode;\n}\nexport interface DialogProps\n extends Omit<\n ComponentProps<typeof ArkDialog.Root>,\n \"children\" | \"onOpenChange\"\n > {\n title: ReactNode;\n description?: ReactNode;\n children: ReactNode;\n actions?: ReactNode;\n onOpenChange?: (open: boolean) => void;\n closeOnOutside?: boolean;\n portal?: boolean;\n className?: string;\n overlayClassName?: string;\n contentProps?: ComponentProps<typeof ArkDialog.Content>;\n initialFocus?: () => HTMLElement | null | undefined;\n finalFocus?: () => HTMLElement | null | undefined;\n frame?: (parts: DialogFrameParts) => ReactNode;\n unstyled?: boolean;\n}\nexport const Dialog = forwardRef<HTMLDivElement, DialogProps>(function Dialog(\n {\n title,\n description,\n children,\n actions,\n onOpenChange,\n closeOnOutside,\n portal = true,\n className,\n overlayClassName,\n contentProps,\n initialFocus,\n finalFocus,\n frame,\n unstyled,\n ...rest\n },\n ref\n) {\n const parts: DialogFrameParts = {\n title: (\n <ArkDialog.Title className={unstyled ? undefined : \"dds-dialog__title\"}>\n {title}\n </ArkDialog.Title>\n ),\n description: description && (\n <ArkDialog.Description\n className={unstyled ? undefined : \"dds-dialog__body\"}\n >\n {description}\n </ArkDialog.Description>\n ),\n children,\n actions: actions && (\n <div className={unstyled ? undefined : \"dds-dialog__actions\"}>\n {actions}\n </div>\n ),\n };\n const content = (\n <ArkDialog.Positioner\n className={classes(!unstyled && \"dds-dialog-overlay\", overlayClassName)}\n >\n <ArkDialog.Content\n {...contentProps}\n ref={ref}\n aria-describedby={\n description ? contentProps?.[\"aria-describedby\"] : undefined\n }\n className={classes(\n !unstyled && \"dds-dialog\",\n className,\n contentProps?.className\n )}\n >\n {frame ? (\n frame(parts)\n ) : (\n <>\n {parts.title}\n {parts.description}\n {children}\n {parts.actions}\n </>\n )}\n </ArkDialog.Content>\n </ArkDialog.Positioner>\n );\n return (\n <ArkDialog.Root\n {...rest}\n onOpenChange={(details) => onOpenChange?.(details.open)}\n closeOnInteractOutside={closeOnOutside ?? rest.closeOnInteractOutside}\n initialFocusEl={\n initialFocus ? () => initialFocus() ?? null : rest.initialFocusEl\n }\n finalFocusEl={finalFocus ? () => finalFocus() ?? null : rest.finalFocusEl}\n lazyMount\n unmountOnExit\n >\n {portal ? <Portal>{content}</Portal> : content}\n </ArkDialog.Root>\n );\n});\nexport type TooltipTriggerProps = ButtonHTMLAttributes<HTMLButtonElement>;\nexport interface TooltipProps\n extends Omit<\n ComponentProps<typeof ArkTooltip.Root>,\n \"children\" | \"onOpenChange\"\n > {\n content: ReactNode;\n children: ReactNode | ((props: TooltipTriggerProps) => ReactNode);\n onOpenChange?: (open: boolean) => void;\n className?: string;\n contentProps?: ComponentProps<typeof ArkTooltip.Content>;\n}\nexport function Tooltip({\n content,\n children,\n onOpenChange,\n className,\n contentProps,\n ...rest\n}: TooltipProps) {\n return (\n <ArkTooltip.Root\n openDelay={0}\n closeDelay={0}\n {...rest}\n onOpenChange={(details) => onOpenChange?.(details.open)}\n >\n <span className={classes(\"dds-tooltip\", className)}>\n {typeof children === \"function\" ? (\n <ArkTooltip.Context>\n {(api) => children(api.getTriggerProps())}\n </ArkTooltip.Context>\n ) : (\n <ArkTooltip.Trigger asChild>{children}</ArkTooltip.Trigger>\n )}\n <Portal>\n <ArkTooltip.Positioner>\n <ArkTooltip.Content\n {...contentProps}\n className={classes(\n \"dds-tooltip__bubble\",\n contentProps?.className\n )}\n >\n {content}\n </ArkTooltip.Content>\n </ArkTooltip.Positioner>\n </Portal>\n </span>\n </ArkTooltip.Root>\n );\n}\n","import { forwardRef, type SVGProps } from \"react\";\nimport { icons, directionPolicy, type DdsIconName } from \"@devslab/dds-icons\";\nimport { classes } from \"./controls\";\nexport interface IconProps\n extends Omit<SVGProps<SVGSVGElement>, \"name\" | \"children\"> {\n name: DdsIconName;\n label?: string;\n size?: number | string;\n directional?: boolean;\n}\nexport const Icon = forwardRef<SVGSVGElement, IconProps>(function Icon(\n { name, label, size = 24, directional, className, ...rest },\n ref\n) {\n const icon = icons[name];\n return (\n <svg\n {...rest}\n ref={ref}\n viewBox={icon.viewBox}\n width={size}\n height={size}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={icon.strokeWidth}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n role={label ? \"img\" : undefined}\n aria-label={label}\n aria-hidden={label ? undefined : true}\n className={classes(\n (directional ?? directionPolicy.mirrorInRtl.includes(name)) &&\n directionPolicy.cssClass,\n className\n )}\n >\n {label && <title>{label}</title>}\n <g dangerouslySetInnerHTML={{ __html: icon.body }} />\n </svg>\n );\n});\n","import {\n createContext,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n type ReactNode,\n} from \"react\";\nimport { Toast as ArkToast, Toaster, createToaster } from \"@ark-ui/react/toast\";\nimport { classes } from \"./controls\";\nexport type ToastTone = \"success\" | \"warning\" | \"danger\" | \"info\";\nexport interface ToastInput {\n message: ReactNode;\n tone?: ToastTone;\n duration?: number;\n}\nexport interface ToastRecord extends ToastInput {\n id: string;\n}\nexport interface ToastApi {\n show: (toast: ToastInput) => string;\n dismiss: (id: string) => void;\n clear: () => void;\n}\nexport interface ToastProviderProps {\n children: ReactNode;\n defaultDuration?: number;\n dismissLabel?: string | ((toast: ToastRecord) => string);\n regionLabel?: string;\n className?: string;\n}\nconst ToastContext = createContext<ToastApi | null>(null);\nexport function ToastProvider({\n children,\n defaultDuration = 5000,\n dismissLabel,\n regionLabel,\n className,\n}: ToastProviderProps) {\n const prefix = useId();\n const sequence = useRef(0);\n const toaster = useMemo(\n () =>\n createToaster({\n placement: \"bottom-end\",\n overlap: false,\n gap: 8,\n offsets: \"var(--dds-space-16)\",\n removeDelay: 0,\n hotkey: [\"DDS_NO_HOTKEY\"],\n }),\n []\n );\n const api = useMemo<ToastApi>(() => {\n return {\n show(input) {\n const id = `dds-toast-${prefix}-${++sequence.current}`;\n const duration = input.duration ?? defaultDuration;\n toaster.create({\n id,\n description: input.message,\n type: input.tone === \"danger\" ? \"error\" : input.tone ?? \"info\",\n duration: duration > 0 ? duration : Infinity,\n meta: { dds: { ...input, id } },\n });\n return id;\n },\n dismiss: (id) => toaster.remove(id),\n clear: () => toaster.remove(),\n };\n }, [toaster, prefix, defaultDuration]);\n useEffect(() => () => toaster.remove(), [toaster]);\n return (\n <ToastContext.Provider value={api}>\n {children}\n <Toaster\n toaster={toaster}\n label={regionLabel ?? \"\"}\n aria-label={regionLabel ?? \"\"}\n role={regionLabel ? \"region\" : \"presentation\"}\n className={classes(\"dds-toast-region\", className)}\n >\n {(toast) => {\n const record = toast.meta?.dds as ToastRecord;\n return (\n <ArkToast.Root\n className={classes(\n \"dds-toast\",\n `dds-toast--${record.tone ?? \"info\"}`\n )}\n role={record.tone === \"danger\" ? \"alert\" : \"status\"}\n >\n <ArkToast.Description>{toast.description}</ArkToast.Description>\n {dismissLabel && (\n <ArkToast.CloseTrigger\n className=\"dds-iconbtn dds-iconbtn--sm\"\n aria-label={\n typeof dismissLabel === \"function\"\n ? dismissLabel(record)\n : dismissLabel\n }\n >\n ×\n </ArkToast.CloseTrigger>\n )}\n </ArkToast.Root>\n );\n }}\n </Toaster>\n </ToastContext.Provider>\n );\n}\nexport function useToast(): ToastApi {\n const api = useContext(ToastContext);\n if (!api) throw new Error(\"useToast must be called inside <ToastProvider>\");\n return api;\n}\n","import {\n forwardRef,\n useEffect,\n useId,\n useState,\n type HTMLAttributes,\n type ReactNode,\n} from \"react\";\nimport { classes } from \"./controls\";\nexport interface ConsoleNavItem {\n id: string;\n href: string;\n label: string;\n badge?: number;\n active?: boolean;\n}\nexport interface ConsoleNavGroup {\n label: string;\n items: readonly ConsoleNavItem[];\n}\nexport interface ConsoleShellLabels {\n skip: string;\n menuOpen: string;\n menuClose: string;\n nav: string;\n badge: string;\n}\nexport interface ConsoleHeader {\n eyebrow?: string;\n title: string;\n actions?: ReactNode;\n}\nexport interface ConsoleShellProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"children\" | \"context\"> {\n surface: string;\n activePath: string;\n brand: { href: string; name: string; mark: string };\n context?: readonly { label: string; value: string }[];\n nav: readonly ConsoleNavGroup[];\n labels: ConsoleShellLabels;\n header: ConsoleHeader;\n foot?: ReactNode;\n children: ReactNode;\n}\nfunction isActive(path: string, item: ConsoleNavItem) {\n return (\n item.active ??\n (item.href.split(\"/\").filter(Boolean).length <= 1\n ? path === item.href\n : path === item.href || path.startsWith(`${item.href}/`))\n );\n}\nexport const ConsoleShell = forwardRef<HTMLDivElement, ConsoleShellProps>(\n function ConsoleShell(\n {\n surface,\n activePath,\n brand,\n context,\n nav,\n labels,\n header,\n foot,\n children,\n className,\n ...rest\n },\n ref\n ) {\n const [open, setOpen] = useState(false);\n const [hydrated, setHydrated] = useState(false);\n const id = useId();\n const railId = `dds-console-rail-${id}`;\n const mainId = `dds-console-main-${id}`;\n useEffect(() => {\n setHydrated(true);\n const onKey = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") setOpen(false);\n };\n document.addEventListener(\"keydown\", onKey);\n return () => document.removeEventListener(\"keydown\", onKey);\n }, []);\n return (\n <div\n {...rest}\n ref={ref}\n className={classes(\"dds-console-shell\", className)}\n data-surface={surface}\n data-hydrated={hydrated ? \"true\" : undefined}\n >\n <a className=\"dds-console-skip dds-visually-hidden\" href={`#${mainId}`}>\n {labels.skip}\n </a>\n <button\n className=\"dds-console-rail__toggle\"\n type=\"button\"\n data-action=\"toggle-rail\"\n aria-controls={railId}\n aria-expanded={open}\n onClick={() => setOpen(!open)}\n >\n <span aria-hidden />\n <span className=\"dds-visually-hidden\">\n {open ? labels.menuClose : labels.menuOpen}\n </span>\n </button>\n <div\n className=\"dds-console-rail__scrim\"\n data-open={String(open)}\n onClick={() => setOpen(false)}\n />\n <aside\n id={railId}\n className=\"dds-console-rail\"\n data-open={String(open)}\n >\n <a className=\"dds-console-rail__brand\" href={brand.href}>\n <img src={brand.mark} alt=\"\" width={20} height={20} />\n <strong>{brand.name}</strong>\n </a>\n {context && context.length > 0 && (\n <dl className=\"dds-console-rail__context\">\n {context.map((row, index) => (\n <div key={index}>\n <dt>{row.label}</dt>\n <dd>{row.value}</dd>\n </div>\n ))}\n </dl>\n )}\n <nav className=\"dds-console-rail__nav\" aria-label={labels.nav}>\n {nav.map((group, index) => (\n <section\n key={index}\n className=\"dds-console-rail__group\"\n aria-labelledby={`${id}-group-${index}`}\n >\n <h2\n id={`${id}-group-${index}`}\n className=\"dds-console-rail__group-label\"\n >\n {group.label}\n </h2>\n <ul>\n {group.items.map((item) => (\n <li key={item.id}>\n <a\n className=\"dds-console-rail__item\"\n data-nav={`${surface}.${item.id}`}\n href={item.href}\n aria-current={\n isActive(activePath, item) ? \"page\" : undefined\n }\n onClick={() => setOpen(false)}\n >\n <span>{item.label}</span>\n {item.badge !== undefined && item.badge > 0 && (\n <span\n className=\"dds-console-rail__badge\"\n aria-label={labels.badge.replace(\"{count}\", () =>\n String(item.badge)\n )}\n >\n {item.badge}\n </span>\n )}\n </a>\n </li>\n ))}\n </ul>\n </section>\n ))}\n </nav>\n {foot && <div className=\"dds-console-rail__foot\">{foot}</div>}\n </aside>\n <main id={mainId} className=\"dds-console-main\" tabIndex={-1}>\n <header className=\"dds-console-page-header\">\n <div className=\"dds-console-page-header__text\">\n {header.eyebrow && (\n <p className=\"dds-console-page-eyebrow\">{header.eyebrow}</p>\n )}\n <h1>{header.title}</h1>\n </div>\n {header.actions && (\n <div className=\"dds-console-page-header__actions\">\n {header.actions}\n </div>\n )}\n </header>\n {children}\n </main>\n </div>\n );\n }\n);\n","export type StatusTone = \"success\" | \"warning\" | \"danger\" | \"info\" | \"brand\" | \"neutral\";\nexport function createStatusPill<D extends string>(config:{\n tones:Record<D,Record<string,StatusTone>>;\n label:(domain:D,value:string,locale:string)=>string|undefined;\n openDomains?:readonly NoInfer<D>[];\n}){\n const open=new Set<string>(config.openDomains??[]);\n return function StatusPill(props:{domain:D;value:string;locale:string}){\n const tone=config.tones[props.domain]?.[props.value];\n const label=config.label(props.domain,props.value,props.locale);\n if(!tone||!label){\n if(open.has(props.domain))return <code data-status={`${props.domain}.${props.value}`}>{props.value}</code>;\n throw new Error(!tone?`StatusPill: no tone for ${props.domain}.${props.value}`:`StatusPill: no label for ${props.domain}.${props.value}`);\n }\n return <span className={tone==='neutral'?'dds-badge':`dds-badge dds-badge--${tone}`} data-status={`${props.domain}.${props.value}`} data-tone={tone}>{label}</span>;\n };\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\n/** Options for one `run` call. */\nexport interface PendingActionRunOptions {\n /**\n * Start even while another action runs: that one is aborted and this one takes its place, so the\n * latest request wins (a list reload after typing, paging or sorting). Without it a second start\n * while one runs is ignored, which is what a button wants.\n */\n replace?: boolean;\n}\n\n/**\n * Which of a screen's actions is running. A screen with several buttons gives each one its own\n * key, so only the button that started the work shows progress, while every other control can\n * still be locked through `busy`. One shared flag for all the buttons spins every one of them.\n * The same contract as `createPendingAction` in `@devslab/dds-solid`, with values for accessors.\n */\nexport interface PendingAction<K extends string = string> {\n /** The key of the action now running, or null. */\n readonly current: K | null;\n /** True while any action runs: lock the other controls with it. */\n readonly busy: boolean;\n /** True while `key` is the running action: give that control its progress state. */\n is(key: K): boolean;\n /**\n * Runs `task` as `key` and clears the state when it settles, whether it resolves or throws (the\n * error reaches the caller). While another action runs it does nothing and resolves to undefined,\n * unless `replace` is set. The task receives a signal that aborts when this run stops counting:\n * `reset()`, a run that replaced it, or the component unmounting. Check `signal.aborted` after\n * each await before touching state, or pass the signal to `fetch`.\n */\n run<T>(key: K, task: (signal: AbortSignal) => T | Promise<T>, options?: PendingActionRunOptions): Promise<T | undefined>;\n /** Stops tracking the running action and aborts its signal, for example when the screen's data was replaced. */\n reset(): void;\n}\n\n/** Tracks the running action of a component. */\nexport function usePendingAction<K extends string = string>(): PendingAction<K> {\n const [current, setCurrent] = useState<K | null>(null);\n // State lands on the next render; the ref answers a second click in the same event loop turn.\n const active = useRef<AbortController | null>(null);\n useEffect(() => () => {\n active.current?.abort();\n active.current = null;\n }, []);\n const run = useCallback(async <T,>(\n key: K,\n task: (signal: AbortSignal) => T | Promise<T>,\n options?: PendingActionRunOptions,\n ): Promise<T | undefined> => {\n if (active.current && !options?.replace) return undefined;\n active.current?.abort();\n const controller = new AbortController();\n active.current = controller;\n setCurrent(key);\n try {\n return await task(controller.signal);\n } finally {\n if (active.current === controller) {\n active.current = null;\n setCurrent(null);\n }\n }\n }, []);\n const reset = useCallback(() => {\n active.current?.abort();\n active.current = null;\n setCurrent(null);\n }, []);\n return useMemo(() => ({\n current,\n busy: current !== null,\n is: (key: K) => current === key,\n run,\n reset,\n }), [current, run, reset]);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/selection.tsx","../src/overlays.tsx","../src/icon.tsx","../src/toast.tsx","../src/layout.tsx","../src/left-nav.tsx","../src/console-shell.tsx","../src/top-nav.tsx","../src/status-pill.tsx","../src/pending-action.ts"],"sourcesContent":["import { forwardRef, type ComponentProps, type ReactNode } from \"react\";\nimport { Tabs as ArkTabs, useTabsContext } from \"@ark-ui/react/tabs\";\nimport {\n RadioGroup as ArkRadioGroup,\n useRadioGroupContext,\n} from \"@ark-ui/react/radio-group\";\nimport { classes } from \"./controls\";\nexport interface TabsProps\n extends Omit<ComponentProps<typeof ArkTabs.Root>, \"onValueChange\"> {\n onValueChange?: (value: string) => void;\n unstyled?: boolean;\n}\nexport const Tabs = forwardRef<HTMLDivElement, TabsProps>(function Tabs(\n { onValueChange, unstyled, className, ...rest },\n ref\n) {\n return (\n <ArkTabs.Root\n {...rest}\n ref={ref}\n onValueChange={(details) => onValueChange?.(details.value)}\n className={classes(!unstyled && \"dds-tabs-root\", className)}\n />\n );\n});\nexport type TabProps = ComponentProps<typeof ArkTabs.Trigger> & {\n unstyled?: boolean;\n};\nexport type TabPanelProps = ComponentProps<typeof ArkTabs.Content>;\nexport const TabList = forwardRef<\n HTMLDivElement,\n ComponentProps<typeof ArkTabs.List> & { unstyled?: boolean }\n>(function TabList({ unstyled, className, ...rest }, ref) {\n return (\n <ArkTabs.List\n {...rest}\n ref={ref}\n className={classes(!unstyled && \"dds-tabs\", className)}\n />\n );\n});\nexport const Tab = forwardRef<HTMLButtonElement, TabProps>(function Tab(\n { unstyled, className, ...rest },\n ref\n) {\n return (\n <ArkTabs.Trigger\n {...rest}\n ref={ref}\n className={classes(!unstyled && \"dds-tab\", className)}\n />\n );\n});\nexport const TabPanel = forwardRef<HTMLDivElement, TabPanelProps>(\n function TabPanel({ value, style, ...rest }, ref) {\n const tabs = useTabsContext();\n const inactive = tabs.value !== value;\n return (\n <ArkTabs.Content\n {...rest}\n value={value}\n ref={ref}\n hidden={inactive}\n style={inactive ? { ...style, display: \"none\" } : style}\n />\n );\n }\n);\nfunction VisibleRadioInput({ option }: { option: RadioOption }) {\n const group = useRadioGroupContext();\n // Ark owns selection and roving focus; DDS displays the native radio.\n const {\n style: _,\n defaultChecked: __,\n ...inputProps\n } = group.getItemHiddenInputProps(option);\n return (\n <input\n {...inputProps}\n checked={group.value === option.value}\n onChange={() => {}}\n className=\"dds-check__input\"\n />\n );\n}\nexport interface RadioOption {\n value: string;\n label: ReactNode;\n disabled?: boolean;\n}\nexport interface RadioGroupProps\n extends Omit<\n ComponentProps<typeof ArkRadioGroup.Root>,\n \"onValueChange\" | \"children\"\n > {\n options: readonly RadioOption[];\n label: ReactNode;\n onValueChange?: (value: string) => void;\n children?: ReactNode;\n}\nexport const RadioGroup = forwardRef<HTMLDivElement, RadioGroupProps>(\n function RadioGroup(\n { options, label, onValueChange, className, children, ...rest },\n ref\n ) {\n return (\n <ArkRadioGroup.Root\n {...rest}\n ref={ref}\n onValueChange={(details) => {\n if (details.value !== null) onValueChange?.(details.value);\n }}\n className={classes(\"dds-radio-group\", className)}\n >\n <ArkRadioGroup.Label className=\"dds-field__label\">\n {label}\n </ArkRadioGroup.Label>\n {options.map((option) => (\n <ArkRadioGroup.Item\n key={option.value}\n value={option.value}\n disabled={option.disabled}\n className=\"dds-check\"\n >\n <VisibleRadioInput option={option} />\n <ArkRadioGroup.ItemText>{option.label}</ArkRadioGroup.ItemText>\n </ArkRadioGroup.Item>\n ))}\n {children}\n </ArkRadioGroup.Root>\n );\n }\n);\n","import {\n forwardRef,\n type ComponentProps,\n type ButtonHTMLAttributes,\n type ReactNode,\n} from \"react\";\nimport { Dialog as ArkDialog } from \"@ark-ui/react/dialog\";\nimport { Tooltip as ArkTooltip } from \"@ark-ui/react/tooltip\";\nimport { Portal } from \"@ark-ui/react/portal\";\nimport { classes } from \"./controls\";\nexport interface DialogFrameParts {\n title: ReactNode;\n description: ReactNode;\n children: ReactNode;\n actions: ReactNode;\n}\nexport interface DialogProps\n extends Omit<\n ComponentProps<typeof ArkDialog.Root>,\n \"children\" | \"onOpenChange\"\n > {\n title: ReactNode;\n description?: ReactNode;\n children: ReactNode;\n actions?: ReactNode;\n onOpenChange?: (open: boolean) => void;\n closeOnOutside?: boolean;\n portal?: boolean;\n className?: string;\n overlayClassName?: string;\n contentProps?: ComponentProps<typeof ArkDialog.Content>;\n initialFocus?: () => HTMLElement | null | undefined;\n finalFocus?: () => HTMLElement | null | undefined;\n frame?: (parts: DialogFrameParts) => ReactNode;\n unstyled?: boolean;\n}\nexport const Dialog = forwardRef<HTMLDivElement, DialogProps>(function Dialog(\n {\n title,\n description,\n children,\n actions,\n onOpenChange,\n closeOnOutside,\n portal = true,\n className,\n overlayClassName,\n contentProps,\n initialFocus,\n finalFocus,\n frame,\n unstyled,\n ...rest\n },\n ref\n) {\n const parts: DialogFrameParts = {\n title: (\n <ArkDialog.Title className={unstyled ? undefined : \"dds-dialog__title\"}>\n {title}\n </ArkDialog.Title>\n ),\n description: description && (\n <ArkDialog.Description\n className={unstyled ? undefined : \"dds-dialog__body\"}\n >\n {description}\n </ArkDialog.Description>\n ),\n children,\n actions: actions && (\n <div className={unstyled ? undefined : \"dds-dialog__actions\"}>\n {actions}\n </div>\n ),\n };\n const content = (\n <ArkDialog.Positioner\n className={classes(!unstyled && \"dds-dialog-overlay\", overlayClassName)}\n >\n <ArkDialog.Content\n {...contentProps}\n ref={ref}\n aria-describedby={\n description ? contentProps?.[\"aria-describedby\"] : undefined\n }\n className={classes(\n !unstyled && \"dds-dialog\",\n className,\n contentProps?.className\n )}\n >\n {frame ? (\n frame(parts)\n ) : (\n <>\n {parts.title}\n {parts.description}\n {children}\n {parts.actions}\n </>\n )}\n </ArkDialog.Content>\n </ArkDialog.Positioner>\n );\n return (\n <ArkDialog.Root\n {...rest}\n onOpenChange={(details) => onOpenChange?.(details.open)}\n closeOnInteractOutside={closeOnOutside ?? rest.closeOnInteractOutside}\n initialFocusEl={\n initialFocus ? () => initialFocus() ?? null : rest.initialFocusEl\n }\n finalFocusEl={finalFocus ? () => finalFocus() ?? null : rest.finalFocusEl}\n lazyMount\n unmountOnExit\n >\n {portal ? <Portal>{content}</Portal> : content}\n </ArkDialog.Root>\n );\n});\nexport type TooltipTriggerProps = ButtonHTMLAttributes<HTMLButtonElement>;\nexport interface TooltipProps\n extends Omit<\n ComponentProps<typeof ArkTooltip.Root>,\n \"children\" | \"onOpenChange\"\n > {\n content: ReactNode;\n children: ReactNode | ((props: TooltipTriggerProps) => ReactNode);\n onOpenChange?: (open: boolean) => void;\n className?: string;\n contentProps?: ComponentProps<typeof ArkTooltip.Content>;\n}\nexport function Tooltip({\n content,\n children,\n onOpenChange,\n className,\n contentProps,\n ...rest\n}: TooltipProps) {\n return (\n <ArkTooltip.Root\n openDelay={0}\n closeDelay={0}\n {...rest}\n onOpenChange={(details) => onOpenChange?.(details.open)}\n >\n <span className={classes(\"dds-tooltip\", className)}>\n {typeof children === \"function\" ? (\n <ArkTooltip.Context>\n {(api) => children(api.getTriggerProps())}\n </ArkTooltip.Context>\n ) : (\n <ArkTooltip.Trigger asChild>{children}</ArkTooltip.Trigger>\n )}\n <Portal>\n <ArkTooltip.Positioner>\n <ArkTooltip.Content\n {...contentProps}\n className={classes(\n \"dds-tooltip__bubble\",\n contentProps?.className\n )}\n >\n {content}\n </ArkTooltip.Content>\n </ArkTooltip.Positioner>\n </Portal>\n </span>\n </ArkTooltip.Root>\n );\n}\n","import { forwardRef, type SVGProps } from \"react\";\nimport { icons, directionPolicy, type DdsIconName } from \"@devslab/dds-icons\";\nimport { classes } from \"./controls\";\nexport interface IconProps\n extends Omit<SVGProps<SVGSVGElement>, \"name\" | \"children\"> {\n name: DdsIconName;\n label?: string;\n size?: number | string;\n directional?: boolean;\n}\nexport const Icon = forwardRef<SVGSVGElement, IconProps>(function Icon(\n { name, label, size = 24, directional, className, ...rest },\n ref\n) {\n const icon = icons[name];\n return (\n <svg\n {...rest}\n ref={ref}\n viewBox={icon.viewBox}\n width={size}\n height={size}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={icon.strokeWidth}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n role={label ? \"img\" : undefined}\n aria-label={label}\n aria-hidden={label ? undefined : true}\n className={classes(\n (directional ?? directionPolicy.mirrorInRtl.includes(name)) &&\n directionPolicy.cssClass,\n className\n )}\n >\n {label && <title>{label}</title>}\n <g dangerouslySetInnerHTML={{ __html: icon.body }} />\n </svg>\n );\n});\n","import {\n createContext,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n type ReactNode,\n} from \"react\";\nimport { Toast as ArkToast, Toaster, createToaster } from \"@ark-ui/react/toast\";\nimport { classes } from \"./controls\";\nexport type ToastTone = \"success\" | \"warning\" | \"danger\" | \"info\";\nexport interface ToastInput {\n message: ReactNode;\n tone?: ToastTone;\n duration?: number;\n}\nexport interface ToastRecord extends ToastInput {\n id: string;\n}\nexport interface ToastApi {\n show: (toast: ToastInput) => string;\n dismiss: (id: string) => void;\n clear: () => void;\n}\nexport interface ToastProviderProps {\n children: ReactNode;\n defaultDuration?: number;\n dismissLabel?: string | ((toast: ToastRecord) => string);\n regionLabel?: string;\n className?: string;\n}\nconst ToastContext = createContext<ToastApi | null>(null);\nexport function ToastProvider({\n children,\n defaultDuration = 5000,\n dismissLabel,\n regionLabel,\n className,\n}: ToastProviderProps) {\n const prefix = useId();\n const sequence = useRef(0);\n const toaster = useMemo(\n () =>\n createToaster({\n placement: \"bottom-end\",\n overlap: false,\n gap: 8,\n offsets: \"var(--dds-space-16)\",\n removeDelay: 0,\n hotkey: [\"DDS_NO_HOTKEY\"],\n }),\n []\n );\n const api = useMemo<ToastApi>(() => {\n return {\n show(input) {\n const id = `dds-toast-${prefix}-${++sequence.current}`;\n const duration = input.duration ?? defaultDuration;\n toaster.create({\n id,\n description: input.message,\n type: input.tone === \"danger\" ? \"error\" : input.tone ?? \"info\",\n duration: duration > 0 ? duration : Infinity,\n meta: { dds: { ...input, id } },\n });\n return id;\n },\n dismiss: (id) => toaster.remove(id),\n clear: () => toaster.remove(),\n };\n }, [toaster, prefix, defaultDuration]);\n useEffect(() => () => toaster.remove(), [toaster]);\n return (\n <ToastContext.Provider value={api}>\n {children}\n <Toaster\n toaster={toaster}\n label={regionLabel ?? \"\"}\n aria-label={regionLabel ?? \"\"}\n role={regionLabel ? \"region\" : \"presentation\"}\n className={classes(\"dds-toast-region\", className)}\n >\n {(toast) => {\n const record = toast.meta?.dds as ToastRecord;\n return (\n <ArkToast.Root\n className={classes(\n \"dds-toast\",\n `dds-toast--${record.tone ?? \"info\"}`\n )}\n role={record.tone === \"danger\" ? \"alert\" : \"status\"}\n >\n <ArkToast.Description>{toast.description}</ArkToast.Description>\n {dismissLabel && (\n <ArkToast.CloseTrigger\n className=\"dds-iconbtn dds-iconbtn--sm\"\n aria-label={\n typeof dismissLabel === \"function\"\n ? dismissLabel(record)\n : dismissLabel\n }\n >\n ×\n </ArkToast.CloseTrigger>\n )}\n </ArkToast.Root>\n );\n }}\n </Toaster>\n </ToastContext.Provider>\n );\n}\nexport function useToast(): ToastApi {\n const api = useContext(ToastContext);\n if (!api) throw new Error(\"useToast must be called inside <ToastProvider>\");\n return api;\n}\n","import {\n forwardRef,\n useEffect,\n useId,\n useRef,\n useState,\n type HTMLAttributes,\n type ReactNode,\n} from \"react\";\nimport { classes } from \"./controls\";\nexport interface LayoutProps extends Omit<\n HTMLAttributes<HTMLDivElement>,\n \"children\"\n> {\n navigationPosition?: \"left\" | \"top\";\n contentWidth?: \"workspace\" | \"form\" | \"settings\" | \"full\";\n labels: { skip: string; menuOpen: string; menuClose: string };\n header?: ReactNode;\n navigation?: ReactNode;\n railStart?: ReactNode;\n railEnd?: ReactNode;\n footer?: ReactNode;\n children: ReactNode;\n surface?: string;\n}\nexport const Layout = forwardRef<HTMLDivElement, LayoutProps>(function Layout(\n {\n navigationPosition = \"left\",\n contentWidth = \"workspace\",\n labels,\n header,\n navigation,\n railStart,\n railEnd,\n footer,\n children,\n surface,\n className,\n ...rest\n },\n ref,\n) {\n const id = useId(),\n railId = `dds-console-rail-${id}`,\n mainId = `dds-console-main-${id}`;\n const [open, setOpen] = useState(false),\n [hydrated, setHydrated] = useState(false);\n const toggle = useRef<HTMLButtonElement>(null),\n rail = useRef<HTMLElement>(null);\n function close() {\n setOpen(false);\n toggle.current?.focus();\n }\n useEffect(() => {\n setHydrated(true);\n if (typeof window.matchMedia !== \"function\") return;\n const media = window.matchMedia(\"(max-width: 56.25rem)\");\n const resize = () => {\n if (!media.matches) setOpen(false);\n };\n media.addEventListener(\"change\", resize);\n return () => media.removeEventListener(\"change\", resize);\n }, []);\n useEffect(() => {\n if (!open) return;\n const focusable = () =>\n [\n toggle.current,\n ...Array.from(\n rail.current?.querySelectorAll<HTMLElement>(\n 'a[href],button,summary,input,select,textarea,[tabindex=\"0\"]',\n ) ?? [],\n ),\n ].filter(\n (el): el is HTMLElement =>\n !!el &&\n !el.closest(\"[hidden]\") &&\n el.getClientRects().length > 0 &&\n getComputedStyle(el).visibility !== \"hidden\" &&\n !Array.from(\n rail.current?.querySelectorAll(\"details:not([open])\") ?? [],\n ).some(\n (details) =>\n details.contains(el) &&\n !details.querySelector(\"summary\")?.contains(el),\n ) &&\n !el.hasAttribute(\"disabled\"),\n );\n focusable()[1]?.focus();\n function key(event: KeyboardEvent) {\n if (event.key === \"Escape\") {\n event.preventDefault();\n close();\n }\n if (event.key === \"Tab\") {\n const items = focusable(),\n first = items[0],\n last = items.at(-1);\n if (event.shiftKey && document.activeElement === first) {\n event.preventDefault();\n last?.focus();\n } else if (!event.shiftKey && document.activeElement === last) {\n event.preventDefault();\n first?.focus();\n }\n }\n }\n document.addEventListener(\"keydown\", key);\n return () => {\n document.removeEventListener(\"keydown\", key);\n };\n }, [open]);\n return (\n <div\n {...rest}\n ref={ref}\n className={classes(\"dds-console-shell dds-layout\", className)}\n data-navigation-position={navigationPosition}\n data-surface={surface}\n data-hydrated={hydrated ? \"true\" : undefined}\n >\n <a className=\"dds-console-skip dds-visually-hidden\" href={`#${mainId}`}>\n {labels.skip}\n </a>\n <button\n ref={toggle}\n className=\"dds-console-rail__toggle\"\n type=\"button\"\n data-action=\"toggle-rail\"\n aria-controls={railId}\n aria-expanded={open}\n onClick={() => (open ? close() : setOpen(true))}\n >\n <span aria-hidden />\n <span className=\"dds-visually-hidden\">\n {open ? labels.menuClose : labels.menuOpen}\n </span>\n </button>\n <div\n className=\"dds-console-rail__scrim\"\n data-open={String(open)}\n onClick={close}\n />\n <aside\n ref={rail}\n id={railId}\n className=\"dds-console-rail dds-layout__navigation\"\n data-open={String(open)}\n onClick={(event) => {\n if (\n open &&\n event.target instanceof Element &&\n event.target.closest(\"a[href]\")\n )\n close();\n }}\n >\n {railStart}\n {navigation}\n {railEnd}\n </aside>\n <main\n id={mainId}\n className=\"dds-console-main dds-layout__main\"\n tabIndex={-1}\n >\n <div className=\"dds-layout__content\" data-width={contentWidth}>\n {header != null && (\n <header className=\"dds-layout__header\">{header}</header>\n )}\n {children}\n {footer != null && (\n <footer className=\"dds-layout__footer\">{footer}</footer>\n )}\n </div>\n </main>\n </div>\n );\n});\n","import { useId, useState, type ReactNode } from \"react\";\nexport interface ConsoleNavItem {\n id: string;\n href: string;\n label: string;\n /** Decorative icon; the label supplies the accessible name. */\n icon?: ReactNode;\n badge?: number;\n active?: boolean;\n}\nexport interface ConsoleNavGroup {\n /** Stable key for expansion state. Falls back to the group index. */\n id?: string;\n /** Opt in to a disclosure button; legacy groups remain expanded. */\n collapsible?: boolean;\n label: string;\n items: readonly ConsoleNavItem[];\n}\nexport interface LeftNavProps {\n surface: string;\n activePath: string;\n nav: readonly ConsoleNavGroup[];\n labels: { nav: string; badge: string };\n expandedGroups?: readonly string[];\n defaultExpandedGroups?: readonly string[];\n onExpandedGroupsChange?: (groupIds: string[]) => void;\n onNavigate?: () => void;\n}\nfunction isActive(path: string, item: ConsoleNavItem) {\n return (\n item.active ??\n (item.href.split(\"/\").filter(Boolean).length <= 1\n ? path === item.href\n : path === item.href || path.startsWith(`${item.href}/`))\n );\n}\nexport function LeftNav({\n surface,\n activePath,\n nav,\n labels,\n expandedGroups,\n defaultExpandedGroups,\n onExpandedGroupsChange,\n onNavigate,\n}: LeftNavProps) {\n const id = useId();\n const [internalExpandedGroups, setInternalExpandedGroups] = useState<\n readonly string[]\n >(\n () =>\n defaultExpandedGroups ??\n nav.flatMap((group, index) =>\n group.collapsible &&\n group.items.some((item) => isActive(activePath, item))\n ? [group.id ?? `group-${index}`]\n : [],\n ),\n );\n const expanded = expandedGroups ?? internalExpandedGroups;\n function toggleGroup(groupId: string) {\n const next = expanded.includes(groupId)\n ? expanded.filter((value) => value !== groupId)\n : [...expanded, groupId];\n if (expandedGroups === undefined) setInternalExpandedGroups(next);\n onExpandedGroupsChange?.(next);\n }\n return (\n <nav className=\"dds-console-rail__nav dds-left-nav\" aria-label={labels.nav}>\n {nav.map((group, index) => (\n <section\n key={group.id ?? index}\n data-collapsible={group.collapsible ? \"true\" : undefined}\n className=\"dds-console-rail__group\"\n aria-labelledby={`${id}-group-${index}`}\n >\n <h2\n id={`${id}-group-${index}`}\n className=\"dds-console-rail__group-label\"\n >\n {group.collapsible ? (\n <button\n type=\"button\"\n className=\"dds-console-rail__group-toggle\"\n aria-expanded={expanded.includes(group.id ?? `group-${index}`)}\n aria-controls={`${id}-group-items-${index}`}\n onClick={() => toggleGroup(group.id ?? `group-${index}`)}\n >\n <span>{group.label}</span>\n <span\n className=\"dds-console-rail__chevron\"\n aria-hidden=\"true\"\n />\n </button>\n ) : (\n group.label\n )}\n </h2>\n <ul\n id={`${id}-group-items-${index}`}\n hidden={\n group.collapsible &&\n !expanded.includes(group.id ?? `group-${index}`)\n }\n >\n {group.items.map((item) => (\n <li key={item.id}>\n <a\n className=\"dds-console-rail__item\"\n data-nav={`${surface}.${item.id}`}\n href={item.href}\n aria-current={isActive(activePath, item) ? \"page\" : undefined}\n onClick={onNavigate}\n >\n {item.icon != null ? (\n <span className=\"dds-console-rail__item-content\">\n <span\n className=\"dds-console-rail__item-icon\"\n aria-hidden=\"true\"\n >\n {item.icon}\n </span>\n <span>{item.label}</span>\n </span>\n ) : (\n <span>{item.label}</span>\n )}\n {item.badge !== undefined && item.badge > 0 && (\n <span\n className=\"dds-console-rail__badge\"\n aria-label={labels.badge.replace(\"{count}\", () =>\n String(item.badge),\n )}\n >\n {item.badge}\n </span>\n )}\n </a>\n </li>\n ))}\n </ul>\n </section>\n ))}\n </nav>\n );\n}\n","import { forwardRef } from \"react\";\nimport type { HTMLAttributes, ReactNode } from \"react\";\nimport { Layout } from \"./layout\";\nimport { LeftNav, type ConsoleNavGroup } from \"./left-nav\";\nexport type { ConsoleNavItem, ConsoleNavGroup } from \"./left-nav\";\nexport interface ConsoleShellLabels {\n skip: string;\n menuOpen: string;\n menuClose: string;\n nav: string;\n badge: string;\n}\nexport interface ConsoleHeader {\n eyebrow?: string;\n title: string;\n actions?: ReactNode;\n}\nexport interface ConsoleShellProps extends Omit<\n HTMLAttributes<HTMLDivElement>,\n \"children\" | \"context\"\n> {\n surface: string;\n activePath: string;\n brand: { href: string; name: string; mark: string };\n context?: readonly { label: string; value: string }[];\n nav?: readonly ConsoleNavGroup[];\n /** Supply a standalone LeftNav or custom navigation. */\n navigation?: ReactNode;\n expandedGroups?: readonly string[];\n defaultExpandedGroups?: readonly string[];\n onExpandedGroupsChange?: (groupIds: string[]) => void;\n labels: ConsoleShellLabels;\n header: ConsoleHeader;\n foot?: ReactNode;\n children: ReactNode;\n}\nexport const ConsoleShell = forwardRef<HTMLDivElement, ConsoleShellProps>(\n function ConsoleShell(\n {\n surface,\n activePath,\n brand,\n context,\n nav = [],\n navigation,\n expandedGroups,\n defaultExpandedGroups,\n onExpandedGroupsChange,\n labels,\n header,\n foot,\n children,\n ...rest\n },\n ref,\n ) {\n return (\n <Layout\n {...rest}\n ref={ref}\n surface={surface}\n labels={labels}\n railStart={\n <>\n <a className=\"dds-console-rail__brand\" href={brand.href}>\n <img src={brand.mark} alt=\"\" width={20} height={20} />\n <strong>{brand.name}</strong>\n </a>\n {context && context.length > 0 && (\n <dl className=\"dds-console-rail__context\">\n {context.map((row, index) => (\n <div key={index}>\n <dt>{row.label}</dt>\n <dd>{row.value}</dd>\n </div>\n ))}\n </dl>\n )}\n </>\n }\n navigation={\n navigation ?? (\n <LeftNav\n surface={surface}\n activePath={activePath}\n nav={nav}\n labels={labels}\n expandedGroups={expandedGroups}\n defaultExpandedGroups={defaultExpandedGroups}\n onExpandedGroupsChange={onExpandedGroupsChange}\n />\n )\n }\n railEnd={foot && <div className=\"dds-console-rail__foot\">{foot}</div>}\n header={\n <div className=\"dds-console-page-header\">\n <div className=\"dds-console-page-header__text\">\n {header.eyebrow && (\n <p className=\"dds-console-page-eyebrow\">{header.eyebrow}</p>\n )}\n <h1>{header.title}</h1>\n </div>\n {header.actions && (\n <div className=\"dds-console-page-header__actions\">\n {header.actions}\n </div>\n )}\n </div>\n }\n >\n {children}\n </Layout>\n );\n },\n);\n","import { useEffect, useRef } from \"react\";\nimport type { LeftNavProps } from \"./left-nav\";\nexport type TopNavProps = Pick<\n LeftNavProps,\n \"surface\" | \"activePath\" | \"nav\" | \"labels\" | \"onNavigate\"\n>;\nexport function TopNav({\n surface,\n activePath,\n nav,\n labels,\n onNavigate,\n}: TopNavProps) {\n const root = useRef<HTMLElement>(null);\n useEffect(() => {\n function outside(event: PointerEvent) {\n if (!root.current?.contains(event.target as Node))\n root.current\n ?.querySelectorAll(\"details[open]\")\n .forEach((el) => el.removeAttribute(\"open\"));\n }\n document.addEventListener(\"pointerdown\", outside);\n return () => document.removeEventListener(\"pointerdown\", outside);\n }, []);\n return (\n <nav\n ref={root}\n className=\"dds-top-nav\"\n aria-label={labels.nav}\n onKeyDown={(event) => {\n if (event.key !== \"Escape\") return;\n const details = (event.target as Element).closest(\"details\");\n if (details?.open) {\n event.preventDefault();\n event.stopPropagation();\n details.open = false;\n details.querySelector(\"summary\")?.focus();\n }\n }}\n >\n {nav.map((group, index) => (\n <details key={group.id ?? index} className=\"dds-top-nav__group\">\n <summary className=\"dds-top-nav__trigger\">{group.label}</summary>\n <ul className=\"dds-top-nav__items\">\n {group.items.map((item) => (\n <li key={item.id}>\n <a\n className=\"dds-top-nav__item\"\n data-nav={`${surface}.${item.id}`}\n href={item.href}\n aria-current={\n (item.active ??\n (activePath === item.href ||\n (item.href.split(\"/\").filter(Boolean).length > 1 &&\n activePath.startsWith(`${item.href}/`))))\n ? \"page\"\n : undefined\n }\n onClick={(event) => {\n event.currentTarget\n .closest(\"details\")\n ?.removeAttribute(\"open\");\n onNavigate?.();\n }}\n >\n {item.icon != null && (\n <span className=\"dds-top-nav__item-icon\" aria-hidden=\"true\">\n {item.icon}\n </span>\n )}\n <span>{item.label}</span>\n {item.badge != null && item.badge > 0 && (\n <span\n className=\"dds-console-rail__badge\"\n aria-label={labels.badge.replace(\"{count}\", () =>\n String(item.badge),\n )}\n >\n {item.badge}\n </span>\n )}\n </a>\n </li>\n ))}\n </ul>\n </details>\n ))}\n </nav>\n );\n}\n","export type StatusTone = \"success\" | \"warning\" | \"danger\" | \"info\" | \"brand\" | \"neutral\";\nexport function createStatusPill<D extends string>(config:{\n tones:Record<D,Record<string,StatusTone>>;\n label:(domain:D,value:string,locale:string)=>string|undefined;\n openDomains?:readonly NoInfer<D>[];\n}){\n const open=new Set<string>(config.openDomains??[]);\n return function StatusPill(props:{domain:D;value:string;locale:string}){\n const tone=config.tones[props.domain]?.[props.value];\n const label=config.label(props.domain,props.value,props.locale);\n if(!tone||!label){\n if(open.has(props.domain))return <code data-status={`${props.domain}.${props.value}`}>{props.value}</code>;\n throw new Error(!tone?`StatusPill: no tone for ${props.domain}.${props.value}`:`StatusPill: no label for ${props.domain}.${props.value}`);\n }\n return <span className={tone==='neutral'?'dds-badge':`dds-badge dds-badge--${tone}`} data-status={`${props.domain}.${props.value}`} data-tone={tone}>{label}</span>;\n };\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\n/** Options for one `run` call. */\nexport interface PendingActionRunOptions {\n /**\n * Start even while another action runs: that one is aborted and this one takes its place, so the\n * latest request wins (a list reload after typing, paging or sorting). Without it a second start\n * while one runs is ignored, which is what a button wants.\n */\n replace?: boolean;\n}\n\n/**\n * Which of a screen's actions is running. A screen with several buttons gives each one its own\n * key, so only the button that started the work shows progress, while every other control can\n * still be locked through `busy`. One shared flag for all the buttons spins every one of them.\n * The same contract as `createPendingAction` in `@devslab/dds-solid`, with values for accessors.\n */\nexport interface PendingAction<K extends string = string> {\n /** The key of the action now running, or null. */\n readonly current: K | null;\n /** True while any action runs: lock the other controls with it. */\n readonly busy: boolean;\n /** True while `key` is the running action: give that control its progress state. */\n is(key: K): boolean;\n /**\n * Runs `task` as `key` and clears the state when it settles, whether it resolves or throws (the\n * error reaches the caller). While another action runs it does nothing and resolves to undefined,\n * unless `replace` is set. The task receives a signal that aborts when this run stops counting:\n * `reset()`, a run that replaced it, or the component unmounting. Check `signal.aborted` after\n * each await before touching state, or pass the signal to `fetch`.\n */\n run<T>(key: K, task: (signal: AbortSignal) => T | Promise<T>, options?: PendingActionRunOptions): Promise<T | undefined>;\n /** Stops tracking the running action and aborts its signal, for example when the screen's data was replaced. */\n reset(): void;\n}\n\n/** Tracks the running action of a component. */\nexport function usePendingAction<K extends string = string>(): PendingAction<K> {\n const [current, setCurrent] = useState<K | null>(null);\n // State lands on the next render; the ref answers a second click in the same event loop turn.\n const active = useRef<AbortController | null>(null);\n useEffect(() => () => {\n active.current?.abort();\n active.current = null;\n }, []);\n const run = useCallback(async <T,>(\n key: K,\n task: (signal: AbortSignal) => T | Promise<T>,\n options?: PendingActionRunOptions,\n ): Promise<T | undefined> => {\n if (active.current && !options?.replace) return undefined;\n active.current?.abort();\n const controller = new AbortController();\n active.current = controller;\n setCurrent(key);\n try {\n return await task(controller.signal);\n } finally {\n if (active.current === controller) {\n active.current = null;\n setCurrent(null);\n }\n }\n }, []);\n const reset = useCallback(() => {\n active.current?.abort();\n active.current = null;\n setCurrent(null);\n }, []);\n return useMemo(() => ({\n current,\n busy: current !== null,\n is: (key: K) => current === key,\n run,\n reset,\n }), [current, run, reset]);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAYA,IAAa,KAAO,EAAsC,SACxD,EAAE,kBAAe,aAAU,cAAW,GAAG,KACzC,GACA;CACA,OACE,kBAAC,EAAQ,MAAT;EACE,GAAI;EACC;EACL,gBAAgB,MAAY,IAAgB,EAAQ,KAAK;EACzD,WAAW,EAAQ,CAAC,KAAY,iBAAiB,CAAS;CAC3D,CAAA;AAEL,CAAC,GAKY,KAAU,EAGrB,SAAiB,EAAE,aAAU,cAAW,GAAG,KAAQ,GAAK;CACxD,OACE,kBAAC,EAAQ,MAAT;EACE,GAAI;EACC;EACL,WAAW,EAAQ,CAAC,KAAY,YAAY,CAAS;CACtD,CAAA;AAEL,CAAC,GACY,KAAM,EAAwC,SACzD,EAAE,aAAU,cAAW,GAAG,KAC1B,GACA;CACA,OACE,kBAAC,EAAQ,SAAT;EACE,GAAI;EACC;EACL,WAAW,EAAQ,CAAC,KAAY,WAAW,CAAS;CACrD,CAAA;AAEL,CAAC,GACY,KAAW,EACtB,SAAkB,EAAE,UAAO,UAAO,GAAG,KAAQ,GAAK;CAEhD,IAAM,IADO,EACI,CAAA,CAAK,UAAU;CAChC,OACE,kBAAC,EAAQ,SAAT;EACE,GAAI;EACG;EACF;EACL,QAAQ;EACR,OAAO,IAAW;GAAE,GAAG;GAAO,SAAS;EAAO,IAAI;CACnD,CAAA;AAEL,CACF;AACA,SAAS,GAAkB,EAAE,aAAmC;CAC9D,IAAM,IAAQ,GAAqB,GAE7B,EACJ,OAAO,GACP,gBAAgB,GAChB,GAAG,MACD,EAAM,wBAAwB,CAAM;CACxC,OACE,kBAAC,SAAD;EACE,GAAI;EACJ,SAAS,EAAM,UAAU,EAAO;EAChC,gBAAgB,CAAC;EACjB,WAAU;CACX,CAAA;AAEL;AAgBA,IAAa,KAAa,EACxB,SACE,EAAE,YAAS,UAAO,kBAAe,cAAW,aAAU,GAAG,KACzD,GACA;CACA,OACE,kBAAC,EAAc,MAAf;EACE,GAAI;EACC;EACL,gBAAgB,MAAY;GAC1B,AAAI,EAAQ,UAAU,QAAM,IAAgB,EAAQ,KAAK;EAC3D;EACA,WAAW,EAAQ,mBAAmB,CAAS;EANjD,UAAA;GAQE,kBAAC,EAAc,OAAf;IAAqB,WAAU;IAC5B,UAAA;GACkB,CAAA;GACpB,EAAQ,KAAK,MACZ,kBAAC,EAAc,MAAf;IAEE,OAAO,EAAO;IACd,UAAU,EAAO;IACjB,WAAU;IAJZ,UAAA,CAME,kBAAC,IAAD,EAA2B,UAAS,CAAA,GACpC,kBAAC,EAAc,UAAf,EAAA,UAAyB,EAAO,MAA8B,CAAA,CAC5C;GAPb,GAAA,EAAO,KAOM,CACrB;GACA;EACiB;;AAExB,CACF,GChGa,KAAS,EAAwC,SAC5D,EACE,UACA,gBACA,aACA,YACA,iBACA,mBACA,YAAS,IACT,cACA,qBACA,iBACA,iBACA,eACA,UACA,aACA,GAAG,KAEL,GACA;CACA,IAAM,IAA0B;EAC9B,OACE,kBAAC,EAAU,OAAX;GAAiB,WAAW,IAAW,KAAA,IAAY;GAChD,UAAA;EACc,CAAA;EAEnB,aAAa,KACX,kBAAC,EAAU,aAAX;GACE,WAAW,IAAW,KAAA,IAAY;GAEjC,UAAA;EACoB,CAAA;EAEzB;EACA,SAAS,KACP,kBAAC,OAAD;GAAK,WAAW,IAAW,KAAA,IAAY;GACpC,UAAA;EACE,CAAA;CAET,GACM,IACJ,kBAAC,EAAU,YAAX;EACE,WAAW,EAAQ,CAAC,KAAY,sBAAsB,CAAgB;EAEtE,UAAA,kBAAC,EAAU,SAAX;GACE,GAAI;GACC;GACL,oBACE,IAAc,IAAe,sBAAsB,KAAA;GAErD,WAAW,EACT,CAAC,KAAY,cACb,GACA,GAAc,SAChB;GAEC,UAAA,IACC,EAAM,CAAK,IAEX,kBAAA,GAAA,EAAA,UAAA;IACG,EAAM;IACN,EAAM;IACN;IACA,EAAM;GACP,EAAA,CAAA;EAEa,CAAA;CACC,CAAA;CAExB,OACE,kBAAC,EAAU,MAAX;EACE,GAAI;EACJ,eAAe,MAAY,IAAe,EAAQ,IAAI;EACtD,wBAAwB,KAAkB,EAAK;EAC/C,gBACE,UAAqB,EAAa,KAAK,OAAO,EAAK;EAErD,cAAc,UAAmB,EAAW,KAAK,OAAO,EAAK;EAC7D,WAAA;EACA,eAAA;EAEC,UAAA,IAAS,kBAAC,GAAD,EAAA,UAAS,EAAgB,CAAA,IAAI;CACzB,CAAA;AAEpB,CAAC;AAaD,SAAgB,GAAQ,EACtB,YACA,aACA,iBACA,cACA,iBACA,GAAG,KACY;CACf,OACE,kBAAC,EAAW,MAAZ;EACE,WAAW;EACX,YAAY;EACZ,GAAI;EACJ,eAAe,MAAY,IAAe,EAAQ,IAAI;EAEtD,UAAA,kBAAC,QAAD;GAAM,WAAW,EAAQ,eAAe,CAAS;GAAjD,UAAA,CACG,OAAO,KAAa,aACnB,kBAAC,EAAW,SAAZ,EAAA,WACI,MAAQ,EAAS,EAAI,gBAAgB,CAAC,EACtB,CAAA,IAEpB,kBAAC,EAAW,SAAZ;IAAoB,SAAA;IAAS;GAA6B,CAAA,GAE5D,kBAAC,GAAD,EAAA,UACE,kBAAC,EAAW,YAAZ,EAAA,UACE,kBAAC,EAAW,SAAZ;IACE,GAAI;IACJ,WAAW,EACT,uBACA,GAAc,SAChB;IAEC,UAAA;GACiB,CAAA,EACC,CAAA,EACjB,CAAA,CACJ;;CACS,CAAA;AAErB;;;AClKA,IAAa,KAAO,EAAqC,SACvD,EAAE,SAAM,UAAO,UAAO,IAAI,gBAAa,cAAW,GAAG,KACrD,GACA;CACA,IAAM,IAAO,EAAM;CACnB,OACE,kBAAC,OAAD;EACE,GAAI;EACC;EACL,SAAS,EAAK;EACd,OAAO;EACP,QAAQ;EACR,MAAK;EACL,QAAO;EACP,aAAa,EAAK;EAClB,eAAc;EACd,gBAAe;EACf,MAAM,IAAQ,QAAQ,KAAA;EACtB,cAAY;EACZ,eAAa,MAAQ,KAAA;EACrB,WAAW,GACR,KAAe,EAAgB,YAAY,SAAS,CAAI,MACvD,EAAgB,UAClB,CACF;EAlBF,UAAA,CAoBG,KAAS,kBAAC,SAAD,EAAA,UAAQ,EAAa,CAAA,GAC/B,kBAAC,KAAD,EAAG,yBAAyB,EAAE,QAAQ,EAAK,KAAK,EAAI,CAAA,CACjD;;AAET,CAAC,GCRK,IAAe,EAA+B,IAAI;AACxD,SAAgB,GAAc,EAC5B,aACA,qBAAkB,KAClB,iBACA,gBACA,gBACqB;CACrB,IAAM,IAAS,EAAM,GACf,IAAW,EAAO,CAAC,GACnB,IAAU,QAEZ,GAAc;EACZ,WAAW;EACX,SAAS;EACT,KAAK;EACL,SAAS;EACT,aAAa;EACb,QAAQ,CAAC,eAAe;CAC1B,CAAC,GACH,CAAC,CACH,GACM,IAAM,SACH;EACL,KAAK,GAAO;GACV,IAAM,IAAK,aAAa,EAAO,GAAG,EAAE,EAAS,WACvC,IAAW,EAAM,YAAY;GAQnC,OAPA,EAAQ,OAAO;IACb;IACA,aAAa,EAAM;IACnB,MAAM,EAAM,SAAS,WAAW,UAAU,EAAM,QAAQ;IACxD,UAAU,IAAW,IAAI,IAAW;IACpC,MAAM,EAAE,KAAK;KAAE,GAAG;KAAO;IAAG,EAAE;GAChC,CAAC,GACM;EACT;EACA,UAAU,MAAO,EAAQ,OAAO,CAAE;EAClC,aAAa,EAAQ,OAAO;CAC9B,IACC;EAAC;EAAS;EAAQ;CAAe,CAAC;CAErC,OADA,cAAsB,EAAQ,OAAO,GAAG,CAAC,CAAO,CAAC,GAE/C,kBAAC,EAAa,UAAd;EAAuB,OAAO;EAA9B,UAAA,CACG,GACD,kBAAC,IAAD;GACW;GACT,OAAO,KAAe;GACtB,cAAY,KAAe;GAC3B,MAAM,IAAc,WAAW;GAC/B,WAAW,EAAQ,oBAAoB,CAAS;GAE9C,WAAA,MAAU;IACV,IAAM,IAAS,EAAM,MAAM;IAC3B,OACE,kBAAC,EAAS,MAAV;KACE,WAAW,EACT,aACA,cAAc,EAAO,QAAQ,QAC/B;KACA,MAAM,EAAO,SAAS,WAAW,UAAU;KAL7C,UAAA,CAOE,kBAAC,EAAS,aAAV,EAAA,UAAuB,EAAM,YAAkC,CAAA,GAC9D,KACC,kBAAC,EAAS,cAAV;MACE,WAAU;MACV,cACE,OAAO,KAAiB,aACpB,EAAa,CAAM,IACnB;MAEP,UAAA;KAEsB,CAAA,CAEZ;;GAEnB;EACO,CAAA,CACY;;AAE3B;AACA,SAAgB,KAAqB;CACnC,IAAM,IAAM,EAAW,CAAY;CACnC,IAAI,CAAC,GAAK,MAAU,MAAM,gDAAgD;CAC1E,OAAO;AACT;;;AC5FA,IAAa,IAAS,EAAwC,SAC5D,EACE,wBAAqB,QACrB,kBAAe,aACf,WACA,WACA,eACA,cACA,YACA,WACA,aACA,YACA,cACA,GAAG,KAEL,GACA;CACA,IAAM,IAAK,EAAM,GACf,IAAS,oBAAoB,KAC7B,IAAS,oBAAoB,KACzB,CAAC,GAAM,KAAW,EAAS,EAAK,GACpC,CAAC,GAAU,KAAe,EAAS,EAAK,GACpC,IAAS,EAA0B,IAAI,GAC3C,IAAO,EAAoB,IAAI;CACjC,SAAS,IAAQ;EAEf,AADA,EAAQ,EAAK,GACb,EAAO,SAAS,MAAM;CACxB;CA4DA,OA3DA,QAAgB;EAEd,IADA,EAAY,EAAI,GACZ,OAAO,OAAO,cAAe,YAAY;EAC7C,IAAM,IAAQ,OAAO,WAAW,uBAAuB,GACjD,UAAe;GACnB,AAAK,EAAM,WAAS,EAAQ,EAAK;EACnC;EAEA,OADA,EAAM,iBAAiB,UAAU,CAAM,SAC1B,EAAM,oBAAoB,UAAU,CAAM;CACzD,GAAG,CAAC,CAAC,GACL,QAAgB;EACd,IAAI,CAAC,GAAM;EACX,IAAM,UACJ,CACE,EAAO,SACP,GAAG,MAAM,KACP,EAAK,SAAS,iBACZ,+DACF,KAAK,CAAC,CACR,CACF,CAAC,CAAC,QACC,MACC,CAAC,CAAC,KACF,CAAC,EAAG,QAAQ,UAAU,KACtB,EAAG,eAAe,CAAC,CAAC,SAAS,KAC7B,iBAAiB,CAAE,CAAC,CAAC,eAAe,YACpC,CAAC,MAAM,KACL,EAAK,SAAS,iBAAiB,qBAAqB,KAAK,CAAC,CAC5D,CAAC,CAAC,MACC,MACC,EAAQ,SAAS,CAAE,KACnB,CAAC,EAAQ,cAAc,SAAS,CAAC,EAAE,SAAS,CAAE,CAClD,KACA,CAAC,EAAG,aAAa,UAAU,CAC/B;EACF,EAAU,CAAC,CAAC,EAAE,EAAE,MAAM;EACtB,SAAS,EAAI,GAAsB;GAKjC,IAJI,EAAM,QAAQ,aAChB,EAAM,eAAe,GACrB,EAAM,IAEJ,EAAM,QAAQ,OAAO;IACvB,IAAM,IAAQ,EAAU,GACtB,IAAQ,EAAM,IACd,IAAO,EAAM,GAAG,EAAE;IACpB,AAAI,EAAM,YAAY,SAAS,kBAAkB,KAC/C,EAAM,eAAe,GACrB,GAAM,MAAM,KACH,CAAC,EAAM,YAAY,SAAS,kBAAkB,MACvD,EAAM,eAAe,GACrB,GAAO,MAAM;GAEjB;EACF;EAEA,OADA,SAAS,iBAAiB,WAAW,CAAG,SAC3B;GACX,SAAS,oBAAoB,WAAW,CAAG;EAC7C;CACF,GAAG,CAAC,CAAI,CAAC,GAEP,kBAAC,OAAD;EACE,GAAI;EACC;EACL,WAAW,EAAQ,gCAAgC,CAAS;EAC5D,4BAA0B;EAC1B,gBAAc;EACd,iBAAe,IAAW,SAAS,KAAA;EANrC,UAAA;GAQE,kBAAC,KAAD;IAAG,WAAU;IAAuC,MAAM,IAAI;IAC3D,UAAA,EAAO;GACP,CAAA;GACH,kBAAC,UAAD;IACE,KAAK;IACL,WAAU;IACV,MAAK;IACL,eAAY;IACZ,iBAAe;IACf,iBAAe;IACf,eAAgB,IAAO,EAAM,IAAI,EAAQ,EAAI;IAP/C,UAAA,CASE,kBAAC,QAAD,EAAM,eAAA,GAAa,CAAA,GACnB,kBAAC,QAAD;KAAM,WAAU;KACb,UAAA,IAAO,EAAO,YAAY,EAAO;IAC9B,CAAA,CACA;;GACR,kBAAC,OAAD;IACE,WAAU;IACV,aAAW,OAAO,CAAI;IACtB,SAAS;GACV,CAAA;GACD,kBAAC,SAAD;IACE,KAAK;IACL,IAAI;IACJ,WAAU;IACV,aAAW,OAAO,CAAI;IACtB,UAAU,MAAU;KAClB,AACE,KACA,EAAM,kBAAkB,WACxB,EAAM,OAAO,QAAQ,SAAS,KAE9B,EAAM;IACV;IAZF,UAAA;KAcG;KACA;KACA;IACI;;GACP,kBAAC,QAAD;IACE,IAAI;IACJ,WAAU;IACV,UAAU;IAEV,UAAA,kBAAC,OAAD;KAAK,WAAU;KAAsB,cAAY;KAAjD,UAAA;MACG,KAAU,QACT,kBAAC,UAAD;OAAQ,WAAU;OAAsB,UAAA;MAAe,CAAA;MAExD;MACA,KAAU,QACT,kBAAC,UAAD;OAAQ,WAAU;OAAsB,UAAA;MAAe,CAAA;KAEtD;;GACD,CAAA;EACH;;AAET,CAAC;;;ACtJD,SAAS,EAAS,GAAc,GAAsB;CACpD,OACE,EAAK,WACJ,EAAK,KAAK,MAAM,GAAG,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,UAAU,IAC5C,MAAS,EAAK,OACd,MAAS,EAAK,QAAQ,EAAK,WAAW,GAAG,EAAK,KAAK,EAAE;AAE7D;AACA,SAAgB,EAAQ,EACtB,YACA,eACA,QACA,WACA,mBACA,0BACA,2BACA,iBACe;CACf,IAAM,IAAK,EAAM,GACX,CAAC,GAAwB,KAA6B,QAIxD,KACA,EAAI,SAAS,GAAO,MAClB,EAAM,eACN,EAAM,MAAM,MAAM,MAAS,EAAS,GAAY,CAAI,CAAC,IACjD,CAAC,EAAM,MAAM,SAAS,GAAO,IAC7B,CAAC,CACP,CACJ,GACM,IAAW,KAAkB;CACnC,SAAS,EAAY,GAAiB;EACpC,IAAM,IAAO,EAAS,SAAS,CAAO,IAClC,EAAS,QAAQ,MAAU,MAAU,CAAO,IAC5C,CAAC,GAAG,GAAU,CAAO;EAEzB,AADI,MAAmB,KAAA,KAAW,EAA0B,CAAI,GAChE,IAAyB,CAAI;CAC/B;CACA,OACE,kBAAC,OAAD;EAAK,WAAU;EAAqC,cAAY,EAAO;EACpE,UAAA,EAAI,KAAK,GAAO,MACf,kBAAC,WAAD;GAEE,oBAAkB,EAAM,cAAc,SAAS,KAAA;GAC/C,WAAU;GACV,mBAAiB,GAAG,EAAG,SAAS;GAJlC,UAAA,CAME,kBAAC,MAAD;IACE,IAAI,GAAG,EAAG,SAAS;IACnB,WAAU;IAET,UAAA,EAAM,cACL,kBAAC,UAAD;KACE,MAAK;KACL,WAAU;KACV,iBAAe,EAAS,SAAS,EAAM,MAAM,SAAS,GAAO;KAC7D,iBAAe,GAAG,EAAG,eAAe;KACpC,eAAe,EAAY,EAAM,MAAM,SAAS,GAAO;KALzD,UAAA,CAOE,kBAAC,QAAD,EAAA,UAAO,EAAM,MAAY,CAAA,GACzB,kBAAC,QAAD;MACE,WAAU;MACV,eAAY;KACb,CAAA,CACK;IAER,CAAA,IAAA,EAAM;GAEN,CAAA,GACJ,kBAAC,MAAD;IACE,IAAI,GAAG,EAAG,eAAe;IACzB,QACE,EAAM,eACN,CAAC,EAAS,SAAS,EAAM,MAAM,SAAS,GAAO;IAGhD,UAAA,EAAM,MAAM,KAAK,MAChB,kBAAC,MAAD,EAAA,UACE,kBAAC,KAAD;KACE,WAAU;KACV,YAAU,GAAG,EAAQ,GAAG,EAAK;KAC7B,MAAM,EAAK;KACX,gBAAc,EAAS,GAAY,CAAI,IAAI,SAAS,KAAA;KACpD,SAAS;KALX,UAAA,CAOG,EAAK,QAAQ,OAWZ,kBAAC,QAAD,EAAA,UAAO,EAAK,MAAY,CAAA,IAVxB,kBAAC,QAAD;MAAM,WAAU;MAAhB,UAAA,CACE,kBAAC,QAAD;OACE,WAAU;OACV,eAAY;OAEX,UAAA,EAAK;MACF,CAAA,GACN,kBAAC,QAAD,EAAA,UAAO,EAAK,MAAY,CAAA,CACpB;KAEN,CAAA,GAED,EAAK,UAAU,KAAA,KAAa,EAAK,QAAQ,KACxC,kBAAC,QAAD;MACE,WAAU;MACV,cAAY,EAAO,MAAM,QAAQ,iBAC/B,OAAO,EAAK,KAAK,CACnB;MAEC,UAAA,EAAK;KACF,CAAA,CAEP;IACD,CAAA,EAAA,GAhCK,EAAK,EAgCV,CACL;GACC,CAAA,CACG;EAtEF,GAAA,EAAM,MAAM,CAsEV,CACV;CACE,CAAA;AAET;;;AC7GA,IAAa,KAAe,EAC1B,SACE,EACE,YACA,eACA,UACA,YACA,SAAM,CAAC,GACP,eACA,mBACA,0BACA,2BACA,WACA,WACA,SACA,aACA,GAAG,KAEL,GACA;CACA,OACE,kBAAC,GAAD;EACE,GAAI;EACC;EACI;EACD;EACR,WACE,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,KAAD;GAAG,WAAU;GAA0B,MAAM,EAAM;GAAnD,UAAA,CACE,kBAAC,OAAD;IAAK,KAAK,EAAM;IAAM,KAAI;IAAG,OAAO;IAAI,QAAQ;GAAK,CAAA,GACrD,kBAAC,UAAD,EAAA,UAAS,EAAM,KAAa,CAAA,CAC3B;EACF,CAAA,GAAA,KAAW,EAAQ,SAAS,KAC3B,kBAAC,MAAD;GAAI,WAAU;GACX,UAAA,EAAQ,KAAK,GAAK,MACjB,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD,EAAA,UAAK,EAAI,MAAU,CAAA,GACnB,kBAAC,MAAD,EAAA,UAAK,EAAI,MAAU,CAAA,CAChB,EAAA,GAHK,CAGL,CACN;EACC,CAAA,CAEN,EAAA,CAAA;EAEJ,YACE,KACE,kBAAC,GAAD;GACW;GACG;GACP;GACG;GACQ;GACO;GACC;EACzB,CAAA;EAGL,SAAS,KAAQ,kBAAC,OAAD;GAAK,WAAU;GAA0B,UAAA;EAAU,CAAA;EACpE,QACE,kBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACE,kBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACG,EAAO,WACN,kBAAC,KAAD;KAAG,WAAU;KAA4B,UAAA,EAAO;IAAW,CAAA,GAE7D,kBAAC,MAAD,EAAA,UAAK,EAAO,MAAU,CAAA,CACnB;GACJ,CAAA,GAAA,EAAO,WACN,kBAAC,OAAD;IAAK,WAAU;IACZ,UAAA,EAAO;GACL,CAAA,CAEJ;;EAGN;CACK,CAAA;AAEZ,CACF;;;AC5GA,SAAgB,GAAO,EACrB,YACA,eACA,QACA,WACA,iBACc;CACd,IAAM,IAAO,EAAoB,IAAI;CAWrC,OAVA,QAAgB;EACd,SAAS,EAAQ,GAAqB;GACpC,AAAK,EAAK,SAAS,SAAS,EAAM,MAAc,KAC9C,EAAK,SACD,iBAAiB,eAAe,CAAC,CAClC,SAAS,MAAO,EAAG,gBAAgB,MAAM,CAAC;EACjD;EAEA,OADA,SAAS,iBAAiB,eAAe,CAAO,SACnC,SAAS,oBAAoB,eAAe,CAAO;CAClE,GAAG,CAAC,CAAC,GAEH,kBAAC,OAAD;EACE,KAAK;EACL,WAAU;EACV,cAAY,EAAO;EACnB,YAAY,MAAU;GACpB,IAAI,EAAM,QAAQ,UAAU;GAC5B,IAAM,IAAW,EAAM,OAAmB,QAAQ,SAAS;GAC3D,AAAI,GAAS,SACX,EAAM,eAAe,GACrB,EAAM,gBAAgB,GACtB,EAAQ,OAAO,IACf,EAAQ,cAAc,SAAS,CAAC,EAAE,MAAM;EAE5C;EAEC,UAAA,EAAI,KAAK,GAAO,MACf,kBAAC,WAAD;GAAiC,WAAU;GAA3C,UAAA,CACE,kBAAC,WAAD;IAAS,WAAU;IAAwB,UAAA,EAAM;GAAe,CAAA,GAChE,kBAAC,MAAD;IAAI,WAAU;IACX,UAAA,EAAM,MAAM,KAAK,MAChB,kBAAC,MAAD,EAAA,UACE,kBAAC,KAAD;KACE,WAAU;KACV,YAAU,GAAG,EAAQ,GAAG,EAAK;KAC7B,MAAM,EAAK;KACX,gBACG,EAAK,WACL,MAAe,EAAK,QAClB,EAAK,KAAK,MAAM,GAAG,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,SAAS,KAC7C,EAAW,WAAW,GAAG,EAAK,KAAK,EAAE,KACrC,SACA,KAAA;KAEN,UAAU,MAAU;MAIlB,AAHA,EAAM,cACH,QAAQ,SAAS,CAAC,EACjB,gBAAgB,MAAM,GAC1B,IAAa;KACf;KAjBF,UAAA;MAmBG,EAAK,QAAQ,QACZ,kBAAC,QAAD;OAAM,WAAU;OAAyB,eAAY;OAClD,UAAA,EAAK;MACF,CAAA;MAER,kBAAC,QAAD,EAAA,UAAO,EAAK,MAAY,CAAA;MACvB,EAAK,SAAS,QAAQ,EAAK,QAAQ,KAClC,kBAAC,QAAD;OACE,WAAU;OACV,cAAY,EAAO,MAAM,QAAQ,iBAC/B,OAAO,EAAK,KAAK,CACnB;OAEC,UAAA,EAAK;MACF,CAAA;KAEP;IACD,CAAA,EAAA,GArCK,EAAK,EAqCV,CACL;GACC,CAAA,CACG;EA5CK,GAAA,EAAM,MAAM,CA4CjB,CACV;CACE,CAAA;AAET;;;ACxFA,SAAgB,GAAmC,GAIjD;CACD,IAAM,IAAK,IAAI,IAAY,EAAO,eAAa,CAAC,CAAC;CACjD,OAAO,SAAoB,GAA4C;EACtE,IAAM,IAAK,EAAO,MAAM,EAAM,OAAO,GAAG,EAAM,QACxC,IAAM,EAAO,MAAM,EAAM,QAAO,EAAM,OAAM,EAAM,MAAM;EAC9D,IAAG,CAAC,KAAM,CAAC,GAAM;GAChB,IAAG,EAAK,IAAI,EAAM,MAAM,GAAE,OAAO,kBAAC,QAAD;IAAM,eAAa,GAAG,EAAM,OAAO,GAAG,EAAM;IAAU,UAAA,EAAM;GAAY,CAAA;GACzG,MAAU,MAAO,IAA8D,4BAA4B,EAAM,OAAO,GAAG,EAAM,UAA3G,2BAA2B,EAAM,OAAO,GAAG,EAAM,OAAiE;EACzI;EACA,OAAO,kBAAC,QAAD;GAAM,WAAW,MAAO,YAAU,cAAY,wBAAwB;GAAQ,eAAa,GAAG,EAAM,OAAO,GAAG,EAAM;GAAS,aAAW;GAAO,UAAA;EAAY,CAAA;CACnK;AACD;;;ACsBA,SAAgB,KAAgE;CAC9E,IAAM,CAAC,GAAS,KAAc,EAAmB,IAAI,GAE/C,IAAS,EAA+B,IAAI;CAClD,cAAsB;EAEpB,AADA,EAAO,SAAS,MAAM,GACtB,EAAO,UAAU;CACnB,GAAG,CAAC,CAAC;CACL,IAAM,IAAM,EAAY,OACtB,GACA,GACA,MAC2B;EAC3B,IAAI,EAAO,WAAW,CAAC,GAAS,SAAS;EACzC,EAAO,SAAS,MAAM;EACtB,IAAM,IAAa,IAAI,gBAAgB;EAEvC,AADA,EAAO,UAAU,GACjB,EAAW,CAAG;EACd,IAAI;GACF,OAAO,MAAM,EAAK,EAAW,MAAM;EACrC,UAAU;GACR,AAAI,EAAO,YAAY,MACrB,EAAO,UAAU,MACjB,EAAW,IAAI;EAEnB;CACF,GAAG,CAAC,CAAC,GACC,IAAQ,QAAkB;EAG9B,AAFA,EAAO,SAAS,MAAM,GACtB,EAAO,UAAU,MACjB,EAAW,IAAI;CACjB,GAAG,CAAC,CAAC;CACL,OAAO,SAAe;EACpB;EACA,MAAM,MAAY;EAClB,KAAK,MAAW,MAAY;EAC5B;EACA;CACF,IAAI;EAAC;EAAS;EAAK;CAAK,CAAC;AAC3B"}
|
package/dist/layout.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type HTMLAttributes, type ReactNode } from "react";
|
|
2
|
+
export interface LayoutProps extends Omit<HTMLAttributes<HTMLDivElement>, "children"> {
|
|
3
|
+
navigationPosition?: "left" | "top";
|
|
4
|
+
contentWidth?: "workspace" | "form" | "settings" | "full";
|
|
5
|
+
labels: {
|
|
6
|
+
skip: string;
|
|
7
|
+
menuOpen: string;
|
|
8
|
+
menuClose: string;
|
|
9
|
+
};
|
|
10
|
+
header?: ReactNode;
|
|
11
|
+
navigation?: ReactNode;
|
|
12
|
+
railStart?: ReactNode;
|
|
13
|
+
railEnd?: ReactNode;
|
|
14
|
+
footer?: ReactNode;
|
|
15
|
+
children: ReactNode;
|
|
16
|
+
surface?: string;
|
|
17
|
+
}
|
|
18
|
+
export declare const Layout: import("react").ForwardRefExoticComponent<LayoutProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
19
|
+
//# sourceMappingURL=layout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../src/layout.tsx"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,cAAc,EACnB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAEf,MAAM,WAAW,WAAY,SAAQ,IAAI,CACvC,cAAc,CAAC,cAAc,CAAC,EAC9B,UAAU,CACX;IACC,kBAAkB,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACpC,YAAY,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,UAAU,GAAG,MAAM,CAAC;IAC1D,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9D,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AACD,eAAO,MAAM,MAAM,wGAyJjB,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
export interface ConsoleNavItem {
|
|
3
|
+
id: string;
|
|
4
|
+
href: string;
|
|
5
|
+
label: string;
|
|
6
|
+
/** Decorative icon; the label supplies the accessible name. */
|
|
7
|
+
icon?: ReactNode;
|
|
8
|
+
badge?: number;
|
|
9
|
+
active?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface ConsoleNavGroup {
|
|
12
|
+
/** Stable key for expansion state. Falls back to the group index. */
|
|
13
|
+
id?: string;
|
|
14
|
+
/** Opt in to a disclosure button; legacy groups remain expanded. */
|
|
15
|
+
collapsible?: boolean;
|
|
16
|
+
label: string;
|
|
17
|
+
items: readonly ConsoleNavItem[];
|
|
18
|
+
}
|
|
19
|
+
export interface LeftNavProps {
|
|
20
|
+
surface: string;
|
|
21
|
+
activePath: string;
|
|
22
|
+
nav: readonly ConsoleNavGroup[];
|
|
23
|
+
labels: {
|
|
24
|
+
nav: string;
|
|
25
|
+
badge: string;
|
|
26
|
+
};
|
|
27
|
+
expandedGroups?: readonly string[];
|
|
28
|
+
defaultExpandedGroups?: readonly string[];
|
|
29
|
+
onExpandedGroupsChange?: (groupIds: string[]) => void;
|
|
30
|
+
onNavigate?: () => void;
|
|
31
|
+
}
|
|
32
|
+
export declare function LeftNav({ surface, activePath, nav, labels, expandedGroups, defaultExpandedGroups, onExpandedGroupsChange, onNavigate, }: LeftNavProps): import("react").JSX.Element;
|
|
33
|
+
//# sourceMappingURL=left-nav.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"left-nav.d.ts","sourceRoot":"","sources":["../src/left-nav.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACxD,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,+DAA+D;IAC/D,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AACD,MAAM,WAAW,eAAe;IAC9B,qEAAqE;IACrE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,oEAAoE;IACpE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,cAAc,EAAE,CAAC;CAClC;AACD,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,SAAS,eAAe,EAAE,CAAC;IAChC,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACvC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,qBAAqB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,sBAAsB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACtD,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB;AASD,wBAAgB,OAAO,CAAC,EACtB,OAAO,EACP,UAAU,EACV,GAAG,EACH,MAAM,EACN,cAAc,EACd,qBAAqB,EACrB,sBAAsB,EACtB,UAAU,GACX,EAAE,YAAY,+BAoGd"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { LeftNavProps } from "./left-nav";
|
|
2
|
+
export type TopNavProps = Pick<LeftNavProps, "surface" | "activePath" | "nav" | "labels" | "onNavigate">;
|
|
3
|
+
export declare function TopNav({ surface, activePath, nav, labels, onNavigate, }: TopNavProps): import("react").JSX.Element;
|
|
4
|
+
//# sourceMappingURL=top-nav.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"top-nav.d.ts","sourceRoot":"","sources":["../src/top-nav.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,MAAM,MAAM,WAAW,GAAG,IAAI,CAC5B,YAAY,EACZ,SAAS,GAAG,YAAY,GAAG,KAAK,GAAG,QAAQ,GAAG,YAAY,CAC3D,CAAC;AACF,wBAAgB,MAAM,CAAC,EACrB,OAAO,EACP,UAAU,EACV,GAAG,EACH,MAAM,EACN,UAAU,GACX,EAAE,WAAW,+BA6Eb"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devslab/dds-react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.29.1",
|
|
4
4
|
"description": "Accessible React primitives for the DevsLab Design System",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|
|
@@ -99,9 +99,9 @@
|
|
|
99
99
|
},
|
|
100
100
|
"dependencies": {
|
|
101
101
|
"@ark-ui/react": "5.39.3",
|
|
102
|
-
"@devslab/dds-css": "0.
|
|
103
|
-
"@devslab/dds-icons": "0.
|
|
104
|
-
"@devslab/dds-tokens": "0.
|
|
102
|
+
"@devslab/dds-css": "0.29.1",
|
|
103
|
+
"@devslab/dds-icons": "0.29.1",
|
|
104
|
+
"@devslab/dds-tokens": "0.29.1",
|
|
105
105
|
"@tanstack/react-virtual": "3.14.21"
|
|
106
106
|
},
|
|
107
107
|
"peerDependencies": {
|