@withpotter/pages-admin 0.13.0-next.71 → 0.13.0-next.73
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/dist/admin/_shell/nav-fold.js +14 -0
- package/dist/admin/_shell/nav-fold.js.map +1 -0
- package/dist/admin/_shell/nav-group.js +62 -0
- package/dist/admin/_shell/nav-group.js.map +1 -0
- package/dist/admin/_shell/sidebar.js +11 -14
- package/dist/admin/_shell/sidebar.js.map +1 -1
- package/dist/admin/_shell/sidebar.module.css +44 -0
- package/dist/admin/_shell/use-group-fold.js +50 -0
- package/dist/admin/_shell/use-group-fold.js.map +1 -0
- package/package.json +4 -4
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const FOLDABLE_GROUPS = /* @__PURE__ */ new Set([
|
|
2
|
+
"Workspaces",
|
|
3
|
+
"Operations",
|
|
4
|
+
"Inbox",
|
|
5
|
+
"Platform"
|
|
6
|
+
]);
|
|
7
|
+
const foldsGroup = (label, rows, collapsed) => label !== null && FOLDABLE_GROUPS.has(label) && rows > 1 && !collapsed;
|
|
8
|
+
const isGroupClosed = (folded, label, containsActive) => !containsActive && folded[label] === true;
|
|
9
|
+
export {
|
|
10
|
+
FOLDABLE_GROUPS,
|
|
11
|
+
foldsGroup,
|
|
12
|
+
isGroupClosed
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=nav-fold.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/admin/_shell/nav-fold.ts"],"sourcesContent":["/**\n * Which sidebar groups can fold, and which are folded. Pure, so it is tested\n * without a browser. The merchant rail's NavSection follows the same rules.\n */\n\n/** Folded groups by label; a group not listed is open. */\nexport type FoldMap = Record<string, boolean>;\n\n/** The groups that fold; every other group keeps its plain heading. */\nexport const FOLDABLE_GROUPS: ReadonlySet<string> = new Set([\n 'Workspaces',\n 'Operations',\n 'Inbox',\n 'Platform',\n]);\n\n/**\n * A group folds only when it is one of those, has more than one row to hide,\n * and the rail is wide: the icon-only rail has no headings to press.\n */\nexport const foldsGroup = (\n label: string | null,\n rows: number,\n collapsed: boolean,\n): label is string =>\n label !== null && FOLDABLE_GROUPS.has(label) && rows > 1 && !collapsed;\n\n/**\n * Folded by the admin's choice, except while the group owns the current page:\n * shut, the page you are on would have no lit row anywhere in the nav.\n */\nexport const isGroupClosed = (\n folded: FoldMap,\n label: string,\n containsActive: boolean,\n) => !containsActive && folded[label] === true;\n"],"mappings":"AASO,MAAM,kBAAuC,oBAAI,IAAI;AAAA,EAC1D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAMM,MAAM,aAAa,CACxB,OACA,MACA,cAEA,UAAU,QAAQ,gBAAgB,IAAI,KAAK,KAAK,OAAO,KAAK,CAAC;AAMxD,MAAM,gBAAgB,CAC3B,QACA,OACA,mBACG,CAAC,kBAAkB,OAAO,KAAK,MAAM;","names":[]}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { ChevronDown } from "lucide-react";
|
|
4
|
+
import { isActive } from "./nav-filter";
|
|
5
|
+
import { foldsGroup } from "./nav-fold";
|
|
6
|
+
import { NavRow } from "./nav-row";
|
|
7
|
+
import { useGroupFold } from "./use-group-fold";
|
|
8
|
+
import styles from "./sidebar.module.css";
|
|
9
|
+
function NavGroupView({
|
|
10
|
+
group,
|
|
11
|
+
pathname,
|
|
12
|
+
collapsed,
|
|
13
|
+
canSupport
|
|
14
|
+
}) {
|
|
15
|
+
const { label, items } = group;
|
|
16
|
+
const containsActive = items.some((item) => isActive(item, pathname));
|
|
17
|
+
const { closed, toggle } = useGroupFold(label ?? "", containsActive);
|
|
18
|
+
const folds = foldsGroup(label, items.length, collapsed);
|
|
19
|
+
const rows = items.map((item) => /* @__PURE__ */ jsx(
|
|
20
|
+
NavRow,
|
|
21
|
+
{
|
|
22
|
+
item,
|
|
23
|
+
active: isActive(item, pathname),
|
|
24
|
+
collapsed,
|
|
25
|
+
canSupport
|
|
26
|
+
},
|
|
27
|
+
item.href
|
|
28
|
+
));
|
|
29
|
+
if (!folds)
|
|
30
|
+
return /* @__PURE__ */ jsxs("div", { className: styles.group, children: [
|
|
31
|
+
label && /* @__PURE__ */ jsx("div", { className: styles.groupLabel, children: label }),
|
|
32
|
+
rows
|
|
33
|
+
] });
|
|
34
|
+
return /* @__PURE__ */ jsxs("div", { className: styles.group, children: [
|
|
35
|
+
/* @__PURE__ */ jsxs(
|
|
36
|
+
"button",
|
|
37
|
+
{
|
|
38
|
+
type: "button",
|
|
39
|
+
className: `${styles.groupLabel} ${styles.groupToggle}`,
|
|
40
|
+
"aria-expanded": !closed,
|
|
41
|
+
onClick: toggle,
|
|
42
|
+
children: [
|
|
43
|
+
/* @__PURE__ */ jsx("span", { children: label }),
|
|
44
|
+
/* @__PURE__ */ jsx(
|
|
45
|
+
ChevronDown,
|
|
46
|
+
{
|
|
47
|
+
size: 14,
|
|
48
|
+
className: styles.groupChevron,
|
|
49
|
+
"data-closed": closed,
|
|
50
|
+
"aria-hidden": true
|
|
51
|
+
}
|
|
52
|
+
)
|
|
53
|
+
]
|
|
54
|
+
}
|
|
55
|
+
),
|
|
56
|
+
!closed && rows
|
|
57
|
+
] });
|
|
58
|
+
}
|
|
59
|
+
export {
|
|
60
|
+
NavGroupView
|
|
61
|
+
};
|
|
62
|
+
//# sourceMappingURL=nav-group.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/admin/_shell/nav-group.tsx"],"sourcesContent":["'use client';\n\nimport { ChevronDown } from 'lucide-react';\nimport type { NavGroup } from './nav-config';\nimport { isActive } from './nav-filter';\nimport { foldsGroup } from './nav-fold';\nimport { NavRow } from './nav-row';\nimport { useGroupFold } from './use-group-fold';\nimport styles from './sidebar.module.css';\n\n/**\n * One sidebar group. With a heading and more than one row, the heading is a\n * button that folds the rows away; the choice is remembered. The group that\n * holds the current page stays open, and the icon-only rail shows every row.\n */\nexport function NavGroupView({\n group,\n pathname,\n collapsed,\n canSupport,\n}: {\n group: NavGroup;\n pathname: string;\n collapsed: boolean;\n canSupport: boolean;\n}) {\n const { label, items } = group;\n const containsActive = items.some((item) => isActive(item, pathname));\n const { closed, toggle } = useGroupFold(label ?? '', containsActive);\n const folds = foldsGroup(label, items.length, collapsed);\n\n const rows = items.map((item) => (\n <NavRow\n key={item.href}\n item={item}\n active={isActive(item, pathname)}\n collapsed={collapsed}\n canSupport={canSupport}\n />\n ));\n\n if (!folds)\n return (\n <div className={styles.group}>\n {label && <div className={styles.groupLabel}>{label}</div>}\n {rows}\n </div>\n );\n\n return (\n <div className={styles.group}>\n <button\n type=\"button\"\n className={`${styles.groupLabel} ${styles.groupToggle}`}\n aria-expanded={!closed}\n onClick={toggle}\n >\n <span>{label}</span>\n <ChevronDown\n size={14}\n className={styles.groupChevron}\n data-closed={closed}\n aria-hidden\n />\n </button>\n {/* Not drawn while folded: the hover glide measures every row it finds. */}\n {!closed && rows}\n </div>\n );\n}\n"],"mappings":";AAgCI,cAWE,YAXF;AA9BJ,SAAS,mBAAmB;AAE5B,SAAS,gBAAgB;AACzB,SAAS,kBAAkB;AAC3B,SAAS,cAAc;AACvB,SAAS,oBAAoB;AAC7B,OAAO,YAAY;AAOZ,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKG;AACD,QAAM,EAAE,OAAO,MAAM,IAAI;AACzB,QAAM,iBAAiB,MAAM,KAAK,CAAC,SAAS,SAAS,MAAM,QAAQ,CAAC;AACpE,QAAM,EAAE,QAAQ,OAAO,IAAI,aAAa,SAAS,IAAI,cAAc;AACnE,QAAM,QAAQ,WAAW,OAAO,MAAM,QAAQ,SAAS;AAEvD,QAAM,OAAO,MAAM,IAAI,CAAC,SACtB;AAAA,IAAC;AAAA;AAAA,MAEC;AAAA,MACA,QAAQ,SAAS,MAAM,QAAQ;AAAA,MAC/B;AAAA,MACA;AAAA;AAAA,IAJK,KAAK;AAAA,EAKZ,CACD;AAED,MAAI,CAAC;AACH,WACE,qBAAC,SAAI,WAAW,OAAO,OACpB;AAAA,eAAS,oBAAC,SAAI,WAAW,OAAO,YAAa,iBAAM;AAAA,MACnD;AAAA,OACH;AAGJ,SACE,qBAAC,SAAI,WAAW,OAAO,OACrB;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAW,GAAG,OAAO,UAAU,IAAI,OAAO,WAAW;AAAA,QACrD,iBAAe,CAAC;AAAA,QAChB,SAAS;AAAA,QAET;AAAA,8BAAC,UAAM,iBAAM;AAAA,UACb;AAAA,YAAC;AAAA;AAAA,cACC,MAAM;AAAA,cACN,WAAW,OAAO;AAAA,cAClB,eAAa;AAAA,cACb,eAAW;AAAA;AAAA,UACb;AAAA;AAAA;AAAA,IACF;AAAA,IAEC,CAAC,UAAU;AAAA,KACd;AAEJ;","names":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { isActive } from "./nav-filter";
|
|
4
|
-
import {
|
|
4
|
+
import { NavGroupView } from "./nav-group";
|
|
5
5
|
import { SidebarFooter } from "./sidebar-footer";
|
|
6
6
|
import { useFluidHover } from "./use-fluid-hover";
|
|
7
7
|
import { UserMenu } from "./user-menu";
|
|
@@ -44,19 +44,16 @@ function Sidebar({
|
|
|
44
44
|
} : void 0
|
|
45
45
|
}
|
|
46
46
|
),
|
|
47
|
-
navGroups.map((group, index) => /* @__PURE__ */
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
item.href
|
|
58
|
-
))
|
|
59
|
-
] }, group.label ?? index))
|
|
47
|
+
navGroups.map((group, index) => /* @__PURE__ */ jsx(
|
|
48
|
+
NavGroupView,
|
|
49
|
+
{
|
|
50
|
+
group,
|
|
51
|
+
pathname,
|
|
52
|
+
collapsed,
|
|
53
|
+
canSupport
|
|
54
|
+
},
|
|
55
|
+
group.label ?? index
|
|
56
|
+
))
|
|
60
57
|
]
|
|
61
58
|
}
|
|
62
59
|
),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/admin/_shell/sidebar.tsx"],"sourcesContent":["'use client';\n\nimport type { NavGroup } from './nav-config';\nimport { isActive } from './nav-filter';\nimport {
|
|
1
|
+
{"version":3,"sources":["../../../src/admin/_shell/sidebar.tsx"],"sourcesContent":["'use client';\n\nimport type { NavGroup } from './nav-config';\nimport { isActive } from './nav-filter';\nimport { NavGroupView } from './nav-group';\nimport { SidebarFooter } from './sidebar-footer';\nimport { useFluidHover } from './use-fluid-hover';\nimport { UserMenu } from './user-menu';\nimport styles from './sidebar.module.css';\n\n/** Settings lives in the pinned foot, beside the theme switch. */\nconst FOOT_HREF = '/admin/settings';\n\nexport function Sidebar({\n groups,\n pathname,\n canSupport,\n collapsed,\n email,\n role,\n onSearch,\n}: {\n groups: NavGroup[];\n pathname: string;\n canSupport: boolean;\n collapsed: boolean;\n email: string;\n role: string;\n onSearch: () => void;\n}) {\n const hover = useFluidHover();\n const settings = groups\n .flatMap((group) => group.items)\n .find((item) => item.href === FOOT_HREF);\n const navGroups = groups\n .map((group) => ({\n ...group,\n items: group.items.filter((item) => item.href !== FOOT_HREF),\n }))\n .filter((group) => group.items.length);\n\n return (\n <aside className={styles.sidebar} data-collapsed={collapsed}>\n <UserMenu email={email} role={role} collapsed={collapsed} />\n\n <nav\n className={styles.nav}\n aria-label=\"Admin\"\n onPointerMove={hover.onPointerMove}\n onPointerLeave={hover.onPointerLeave}\n >\n <span\n aria-hidden\n className={styles.glide}\n data-visible={Boolean(hover.rect)}\n style={\n hover.rect\n ? {\n transform: `translateY(${hover.rect.top}px)`,\n height: hover.rect.height,\n }\n : undefined\n }\n />\n {navGroups.map((group, index) => (\n <NavGroupView\n key={group.label ?? index}\n group={group}\n pathname={pathname}\n collapsed={collapsed}\n canSupport={canSupport}\n />\n ))}\n </nav>\n\n <SidebarFooter\n collapsed={collapsed}\n showSettings={Boolean(settings)}\n settingsActive={settings ? isActive(settings, pathname) : false}\n onSearch={onSearch}\n />\n </aside>\n );\n}\n"],"mappings":";AA2CM,cAEA,YAFA;AAxCN,SAAS,gBAAgB;AACzB,SAAS,oBAAoB;AAC7B,SAAS,qBAAqB;AAC9B,SAAS,qBAAqB;AAC9B,SAAS,gBAAgB;AACzB,OAAO,YAAY;AAGnB,MAAM,YAAY;AAEX,SAAS,QAAQ;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAQG;AACD,QAAM,QAAQ,cAAc;AAC5B,QAAM,WAAW,OACd,QAAQ,CAAC,UAAU,MAAM,KAAK,EAC9B,KAAK,CAAC,SAAS,KAAK,SAAS,SAAS;AACzC,QAAM,YAAY,OACf,IAAI,CAAC,WAAW;AAAA,IACf,GAAG;AAAA,IACH,OAAO,MAAM,MAAM,OAAO,CAAC,SAAS,KAAK,SAAS,SAAS;AAAA,EAC7D,EAAE,EACD,OAAO,CAAC,UAAU,MAAM,MAAM,MAAM;AAEvC,SACE,qBAAC,WAAM,WAAW,OAAO,SAAS,kBAAgB,WAChD;AAAA,wBAAC,YAAS,OAAc,MAAY,WAAsB;AAAA,IAE1D;AAAA,MAAC;AAAA;AAAA,QACC,WAAW,OAAO;AAAA,QAClB,cAAW;AAAA,QACX,eAAe,MAAM;AAAA,QACrB,gBAAgB,MAAM;AAAA,QAEtB;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,eAAW;AAAA,cACX,WAAW,OAAO;AAAA,cAClB,gBAAc,QAAQ,MAAM,IAAI;AAAA,cAChC,OACE,MAAM,OACF;AAAA,gBACE,WAAW,cAAc,MAAM,KAAK,GAAG;AAAA,gBACvC,QAAQ,MAAM,KAAK;AAAA,cACrB,IACA;AAAA;AAAA,UAER;AAAA,UACC,UAAU,IAAI,CAAC,OAAO,UACrB;AAAA,YAAC;AAAA;AAAA,cAEC;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA;AAAA,YAJK,MAAM,SAAS;AAAA,UAKtB,CACD;AAAA;AAAA;AAAA,IACH;AAAA,IAEA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,cAAc,QAAQ,QAAQ;AAAA,QAC9B,gBAAgB,WAAW,SAAS,UAAU,QAAQ,IAAI;AAAA,QAC1D;AAAA;AAAA,IACF;AAAA,KACF;AAEJ;","names":[]}
|
|
@@ -64,6 +64,50 @@
|
|
|
64
64
|
white-space: nowrap;
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
+
/* A heading that folds its group: the label's look, as a button. */
|
|
68
|
+
.groupToggle {
|
|
69
|
+
display: flex;
|
|
70
|
+
align-items: center;
|
|
71
|
+
justify-content: space-between;
|
|
72
|
+
width: 100%;
|
|
73
|
+
padding-right: 8px;
|
|
74
|
+
border: 0;
|
|
75
|
+
background: none;
|
|
76
|
+
font-family: inherit;
|
|
77
|
+
text-align: left;
|
|
78
|
+
cursor: pointer;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.groupToggle:hover {
|
|
82
|
+
color: var(--text-secondary);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.groupToggle:focus-visible {
|
|
86
|
+
outline: 2px solid var(--focus-ring);
|
|
87
|
+
outline-offset: 1px;
|
|
88
|
+
border-radius: 6px;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.groupChevron {
|
|
92
|
+
flex: none;
|
|
93
|
+
opacity: 0;
|
|
94
|
+
transition:
|
|
95
|
+
opacity var(--adm-fast),
|
|
96
|
+
transform var(--adm-fast);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.groupToggle:hover .groupChevron,
|
|
100
|
+
.groupToggle:focus-visible .groupChevron {
|
|
101
|
+
opacity: 1;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/* A folded group always shows its chevron: otherwise the only sign that rows
|
|
105
|
+
are hidden is their absence. */
|
|
106
|
+
.groupChevron[data-closed='true'] {
|
|
107
|
+
opacity: 1;
|
|
108
|
+
transform: rotate(-90deg);
|
|
109
|
+
}
|
|
110
|
+
|
|
67
111
|
.link {
|
|
68
112
|
position: relative;
|
|
69
113
|
display: flex;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useCallback, useSyncExternalStore } from "react";
|
|
3
|
+
import { isGroupClosed } from "./nav-fold";
|
|
4
|
+
const STORAGE_KEY = "pb_admin_nav_closed";
|
|
5
|
+
let closedCache = {};
|
|
6
|
+
let closedRaw = null;
|
|
7
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
8
|
+
function readClosed() {
|
|
9
|
+
if (typeof window === "undefined") return closedCache;
|
|
10
|
+
let raw = null;
|
|
11
|
+
try {
|
|
12
|
+
raw = localStorage.getItem(STORAGE_KEY);
|
|
13
|
+
} catch {
|
|
14
|
+
return closedCache;
|
|
15
|
+
}
|
|
16
|
+
if (raw !== closedRaw) {
|
|
17
|
+
closedRaw = raw;
|
|
18
|
+
try {
|
|
19
|
+
closedCache = raw ? JSON.parse(raw) : {};
|
|
20
|
+
} catch {
|
|
21
|
+
closedCache = {};
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return closedCache;
|
|
25
|
+
}
|
|
26
|
+
const serverSnapshot = () => closedCache;
|
|
27
|
+
function subscribe(fn) {
|
|
28
|
+
listeners.add(fn);
|
|
29
|
+
return () => listeners.delete(fn);
|
|
30
|
+
}
|
|
31
|
+
function setClosed(label, closed) {
|
|
32
|
+
const next = { ...readClosed(), [label]: closed };
|
|
33
|
+
try {
|
|
34
|
+
localStorage.setItem(STORAGE_KEY, JSON.stringify(next));
|
|
35
|
+
} catch {
|
|
36
|
+
}
|
|
37
|
+
closedRaw = JSON.stringify(next);
|
|
38
|
+
closedCache = next;
|
|
39
|
+
listeners.forEach((fn) => fn());
|
|
40
|
+
}
|
|
41
|
+
function useGroupFold(label, containsActive) {
|
|
42
|
+
const folded = useSyncExternalStore(subscribe, readClosed, serverSnapshot);
|
|
43
|
+
const closed = isGroupClosed(folded, label, containsActive);
|
|
44
|
+
const toggle = useCallback(() => setClosed(label, !closed), [label, closed]);
|
|
45
|
+
return { closed, toggle };
|
|
46
|
+
}
|
|
47
|
+
export {
|
|
48
|
+
useGroupFold
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=use-group-fold.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/admin/_shell/use-group-fold.ts"],"sourcesContent":["'use client';\n\nimport { useCallback, useSyncExternalStore } from 'react';\nimport { isGroupClosed, type FoldMap } from './nav-fold';\n\nconst STORAGE_KEY = 'pb_admin_nav_closed';\n\n/**\n * Which groups the admin has folded away, as an external store. localStorage\n * does not exist while the server renders, so reading it into state would\n * mismatch the HTML; useSyncExternalStore is built for this (the merchant\n * rail's NavSection does the same).\n */\nlet closedCache: FoldMap = {};\nlet closedRaw: string | null = null;\nconst listeners = new Set<() => void>();\n\nfunction readClosed(): FoldMap {\n if (typeof window === 'undefined') return closedCache;\n\n let raw: string | null = null;\n\n try {\n raw = localStorage.getItem(STORAGE_KEY);\n } catch {\n return closedCache;\n }\n\n // Cached by raw string so the snapshot is stable between renders; a fresh\n // object every call makes useSyncExternalStore loop.\n if (raw !== closedRaw) {\n closedRaw = raw;\n\n try {\n closedCache = raw ? JSON.parse(raw) : {};\n } catch {\n closedCache = {};\n }\n }\n\n return closedCache;\n}\n\n/** The server has no localStorage, so nothing is folded on first paint. */\nconst serverSnapshot = () => closedCache;\n\nfunction subscribe(fn: () => void) {\n listeners.add(fn);\n\n return () => listeners.delete(fn);\n}\n\nfunction setClosed(label: string, closed: boolean) {\n const next = { ...readClosed(), [label]: closed };\n\n try {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(next));\n } catch {\n /* private mode: the choice just won't survive the visit */\n }\n\n closedRaw = JSON.stringify(next);\n closedCache = next;\n listeners.forEach((fn) => fn());\n}\n\nexport function useGroupFold(label: string, containsActive: boolean) {\n const folded = useSyncExternalStore(subscribe, readClosed, serverSnapshot);\n const closed = isGroupClosed(folded, label, containsActive);\n const toggle = useCallback(() => setClosed(label, !closed), [label, closed]);\n\n return { closed, toggle };\n}\n"],"mappings":";AAEA,SAAS,aAAa,4BAA4B;AAClD,SAAS,qBAAmC;AAE5C,MAAM,cAAc;AAQpB,IAAI,cAAuB,CAAC;AAC5B,IAAI,YAA2B;AAC/B,MAAM,YAAY,oBAAI,IAAgB;AAEtC,SAAS,aAAsB;AAC7B,MAAI,OAAO,WAAW,YAAa,QAAO;AAE1C,MAAI,MAAqB;AAEzB,MAAI;AACF,UAAM,aAAa,QAAQ,WAAW;AAAA,EACxC,QAAQ;AACN,WAAO;AAAA,EACT;AAIA,MAAI,QAAQ,WAAW;AACrB,gBAAY;AAEZ,QAAI;AACF,oBAAc,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;AAAA,IACzC,QAAQ;AACN,oBAAc,CAAC;AAAA,IACjB;AAAA,EACF;AAEA,SAAO;AACT;AAGA,MAAM,iBAAiB,MAAM;AAE7B,SAAS,UAAU,IAAgB;AACjC,YAAU,IAAI,EAAE;AAEhB,SAAO,MAAM,UAAU,OAAO,EAAE;AAClC;AAEA,SAAS,UAAU,OAAe,QAAiB;AACjD,QAAM,OAAO,EAAE,GAAG,WAAW,GAAG,CAAC,KAAK,GAAG,OAAO;AAEhD,MAAI;AACF,iBAAa,QAAQ,aAAa,KAAK,UAAU,IAAI,CAAC;AAAA,EACxD,QAAQ;AAAA,EAER;AAEA,cAAY,KAAK,UAAU,IAAI;AAC/B,gBAAc;AACd,YAAU,QAAQ,CAAC,OAAO,GAAG,CAAC;AAChC;AAEO,SAAS,aAAa,OAAe,gBAAyB;AACnE,QAAM,SAAS,qBAAqB,WAAW,YAAY,cAAc;AACzE,QAAM,SAAS,cAAc,QAAQ,OAAO,cAAc;AAC1D,QAAM,SAAS,YAAY,MAAM,UAAU,OAAO,CAAC,MAAM,GAAG,CAAC,OAAO,MAAM,CAAC;AAE3E,SAAO,EAAE,QAAQ,OAAO;AAC1B;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@withpotter/pages-admin",
|
|
3
|
-
"version": "0.13.0-next.
|
|
3
|
+
"version": "0.13.0-next.73",
|
|
4
4
|
"description": "Box console platform-admin routes: overview, revenue, accounts, tenants, admins, roles, audit.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -31,9 +31,9 @@
|
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@radix-ui/react-popover": "^1.1.23",
|
|
33
33
|
"@tanstack/react-query": "^5.90.20",
|
|
34
|
-
"@withpotter/lib": "^0.13.0-next.
|
|
35
|
-
"@withpotter/platform-admin": "^0.13.0-next.
|
|
36
|
-
"@withpotter/ui-kit": "^0.13.0-next.
|
|
34
|
+
"@withpotter/lib": "^0.13.0-next.73",
|
|
35
|
+
"@withpotter/platform-admin": "^0.13.0-next.73",
|
|
36
|
+
"@withpotter/ui-kit": "^0.13.0-next.73",
|
|
37
37
|
"lucide-react": "^0.562.0",
|
|
38
38
|
"motion": "^12.42.2"
|
|
39
39
|
},
|