@humain/ui 2.2.2 → 2.2.3
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/components/templates/AppShell/AppShell.d.ts +4 -2
- package/dist/components/templates/AppShell/index.d.ts +1 -1
- package/dist/components/templates/AppSidebar/AppSidebar.constants.d.ts +4 -0
- package/dist/components/templates/AppSidebar/AppSidebar.d.ts +1 -0
- package/dist/index.js +19 -18
- package/dist/index217.js +6 -24
- package/dist/index217.js.map +1 -1
- package/dist/index218.js +20 -23
- package/dist/index218.js.map +1 -1
- package/dist/index219.js +20 -95
- package/dist/index219.js.map +1 -1
- package/dist/index220.js +92 -88
- package/dist/index220.js.map +1 -1
- package/dist/index221.js +97 -29
- package/dist/index221.js.map +1 -1
- package/dist/index222.js +24 -470
- package/dist/index222.js.map +1 -1
- package/dist/index223.js +450 -196
- package/dist/index223.js.map +1 -1
- package/dist/index224.js +199 -754
- package/dist/index224.js.map +1 -1
- package/dist/index225.js +777 -61
- package/dist/index225.js.map +1 -1
- package/dist/index226.js +58 -181
- package/dist/index226.js.map +1 -1
- package/dist/index227.js +175 -259
- package/dist/index227.js.map +1 -1
- package/dist/index228.js +246 -172
- package/dist/index228.js.map +1 -1
- package/dist/index229.js +195 -32
- package/dist/index229.js.map +1 -1
- package/dist/index230.js +12 -40
- package/dist/index230.js.map +1 -1
- package/dist/index231.js +23 -26
- package/dist/index231.js.map +1 -1
- package/dist/index232.js +45 -22
- package/dist/index232.js.map +1 -1
- package/dist/index233.js +27 -48
- package/dist/index233.js.map +1 -1
- package/dist/index234.js +52 -26
- package/dist/index234.js.map +1 -1
- package/dist/index235.js +40 -225
- package/dist/index235.js.map +1 -1
- package/dist/index236.js +217 -39
- package/dist/index236.js.map +1 -1
- package/dist/index237.js +50 -0
- package/dist/index237.js.map +1 -0
- package/dist/styles.css +1 -1
- package/dist/wc/{sidebar.js → AppSidebar.constants.js} +80 -78
- package/dist/wc/AppSidebar.constants.js.map +1 -0
- package/dist/wc/hf-app-shell.js +346 -343
- package/dist/wc/hf-app-shell.js.map +1 -1
- package/dist/wc/hf-app-sidebar.js +65 -62
- package/dist/wc/hf-app-sidebar.js.map +1 -1
- package/dist/wc-react/{sidebar.js → AppSidebar.constants.js} +89 -87
- package/dist/wc-react/AppSidebar.constants.js.map +1 -0
- package/dist/wc-react/hf-app-shell.js +383 -380
- package/dist/wc-react/hf-app-shell.js.map +1 -1
- package/dist/wc-react/hf-app-sidebar.js +69 -66
- package/dist/wc-react/hf-app-sidebar.js.map +1 -1
- package/package.json +1 -1
- package/skills/humain-ui/SKILL.md +1 -1
- package/skills/humain-ui-wc/SKILL.md +1 -1
- package/skills/humain-ui-wc.skill +0 -0
- package/skills/humain-ui.skill +0 -0
- package/dist/wc/sidebar.js.map +0 -1
- package/dist/wc-react/sidebar.js.map +0 -1
package/dist/index224.js
CHANGED
|
@@ -1,784 +1,229 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn } from "./index2.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { PopoverPopup, PopoverRoot, PopoverTrigger } from "./index211.js";
|
|
9
|
-
import { MOBILE_BREAKPOINT, useIsMobile } from "./index215.js";
|
|
10
|
-
import { Sidebar as SidebarCompound, SidebarAccountSkeleton, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInset, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarNavSkeleton, SidebarProvider, SidebarTrigger, useSidebar } from "./index216.js";
|
|
11
|
-
import { cva } from "class-variance-authority";
|
|
12
|
-
import { ChevronRight, MessageCircle, PanelLeftClose, PanelLeftOpen } from "lucide-react";
|
|
3
|
+
import { Button } from "./index5.js";
|
|
4
|
+
import { DropdownMenu } from "./index192.js";
|
|
5
|
+
import { usePanelExpansion } from "./index218.js";
|
|
6
|
+
import { AppShellContent } from "./index219.js";
|
|
7
|
+
import { EllipsisVertical, Maximize2, Minimize2 } from "lucide-react";
|
|
13
8
|
import * as React$1 from "react";
|
|
14
|
-
import {
|
|
15
|
-
//#region src/components/templates/
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
function isAppSidebarImplicitSlotComponent(value) {
|
|
43
|
-
return (typeof value === "function" || typeof value === "object" && value !== null) && APP_SIDEBAR_IMPLICIT_SLOT in value;
|
|
44
|
-
}
|
|
45
|
-
function getAppSidebarImplicitSlot(childType) {
|
|
46
|
-
if (isAppSidebarImplicitSlotComponent(childType)) return childType[APP_SIDEBAR_IMPLICIT_SLOT];
|
|
47
|
-
if (typeof childType === "object" && childType !== null) {
|
|
48
|
-
const wrappedComponent = childType;
|
|
49
|
-
return getAppSidebarImplicitSlot(wrappedComponent.type) ?? getAppSidebarImplicitSlot(wrappedComponent.render);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
function useSlotChildren(children) {
|
|
53
|
-
return React$1.useMemo(() => {
|
|
54
|
-
const result = {
|
|
55
|
-
header: [],
|
|
56
|
-
content: [],
|
|
57
|
-
footer: [],
|
|
58
|
-
explicitHeader: null,
|
|
59
|
-
explicitContent: null,
|
|
60
|
-
explicitFooter: null
|
|
61
|
-
};
|
|
62
|
-
React$1.Children.forEach(children, (child) => {
|
|
63
|
-
if (!React$1.isValidElement(child)) return;
|
|
64
|
-
const childType = child.type;
|
|
65
|
-
if (childType === AppSidebarHeader) {
|
|
66
|
-
result.explicitHeader = child;
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
if (childType === AppSidebarContent) {
|
|
70
|
-
result.explicitContent = child;
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
if (childType === AppSidebarFooter) {
|
|
74
|
-
result.explicitFooter = child;
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
const implicitSlot = getAppSidebarImplicitSlot(childType);
|
|
78
|
-
if (implicitSlot === "header") result.header.push(child);
|
|
79
|
-
else if (implicitSlot === "content") result.content.push(child);
|
|
80
|
-
else if (implicitSlot === "footer") result.footer.push(child);
|
|
81
|
-
else result.content.push(child);
|
|
82
|
-
});
|
|
83
|
-
return result;
|
|
84
|
-
}, [children]);
|
|
85
|
-
}
|
|
86
|
-
var AppSidebarLayoutContext = React$1.createContext({ side: "left" });
|
|
87
|
-
function useAppSidebarLayout() {
|
|
88
|
-
return React$1.useContext(AppSidebarLayoutContext);
|
|
89
|
-
}
|
|
90
|
-
function getAppSidebarDirection(element) {
|
|
91
|
-
const win = element?.ownerDocument.defaultView;
|
|
92
|
-
if (!element || !win) return "ltr";
|
|
93
|
-
return win.getComputedStyle(element).direction === "rtl" ? "rtl" : "ltr";
|
|
94
|
-
}
|
|
95
|
-
function normalizeAppSidebarDirection(dir) {
|
|
96
|
-
return dir === "rtl" || dir === "ltr" ? dir : void 0;
|
|
97
|
-
}
|
|
98
|
-
function getAppSidebarSideFromDirection(direction) {
|
|
99
|
-
return direction === "rtl" ? "right" : "left";
|
|
100
|
-
}
|
|
101
|
-
function getAppSidebarDirectionTargets(element) {
|
|
102
|
-
const targets = /* @__PURE__ */ new Set();
|
|
103
|
-
let current = element;
|
|
104
|
-
while (current) {
|
|
105
|
-
targets.add(current);
|
|
106
|
-
if (current === element.ownerDocument.documentElement) break;
|
|
107
|
-
current = current.parentElement;
|
|
108
|
-
}
|
|
109
|
-
targets.add(element.ownerDocument.documentElement);
|
|
110
|
-
if (element.ownerDocument.body) targets.add(element.ownerDocument.body);
|
|
111
|
-
return Array.from(targets);
|
|
112
|
-
}
|
|
113
|
-
function useResolvedAppSidebarSide({ containerRef, explicitDir, explicitSide }) {
|
|
114
|
-
const [detectedDirection, setDetectedDirection] = React$1.useState(() => normalizeAppSidebarDirection(explicitDir) ?? "ltr");
|
|
115
|
-
React$1.useEffect(() => {
|
|
116
|
-
if (explicitSide) return;
|
|
117
|
-
const normalizedExplicitDir = normalizeAppSidebarDirection(explicitDir);
|
|
118
|
-
if (normalizedExplicitDir) {
|
|
119
|
-
setDetectedDirection((current) => current === normalizedExplicitDir ? current : normalizedExplicitDir);
|
|
9
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
10
|
+
//#region src/components/templates/AppShellCard/AppShellCard.tsx
|
|
11
|
+
var HEADER_TYPE = "AppShellCard.Header";
|
|
12
|
+
var TOOLBAR_TYPE = "AppShellCard.Toolbar";
|
|
13
|
+
var ACTIONS_TYPE = "AppShellCard.Actions";
|
|
14
|
+
var MENU_TYPE = "AppShellCard.Menu";
|
|
15
|
+
var TITLE_TYPE = "AppShellCard.Title";
|
|
16
|
+
function getAppShellCardType(child) {
|
|
17
|
+
if (!child.type || typeof child.type === "string") return;
|
|
18
|
+
return child.type.__appShellCardType;
|
|
19
|
+
}
|
|
20
|
+
function assignAppShellCardType(component, type) {
|
|
21
|
+
component.__appShellCardType = type;
|
|
22
|
+
return component;
|
|
23
|
+
}
|
|
24
|
+
function getNodeText(node) {
|
|
25
|
+
if (typeof node === "string" || typeof node === "number") return String(node);
|
|
26
|
+
if (Array.isArray(node)) return node.map(getNodeText).join("");
|
|
27
|
+
if (React$1.isValidElement(node)) return getNodeText(node.props.children);
|
|
28
|
+
return "";
|
|
29
|
+
}
|
|
30
|
+
function getTitleText(node) {
|
|
31
|
+
let titleText = "";
|
|
32
|
+
React$1.Children.forEach(node, (child) => {
|
|
33
|
+
if (titleText || !React$1.isValidElement(child)) return;
|
|
34
|
+
if (getAppShellCardType(child) === TITLE_TYPE) {
|
|
35
|
+
titleText = getNodeText(child.props.children).trim();
|
|
120
36
|
return;
|
|
121
37
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
38
|
+
titleText = getTitleText(child.props.children);
|
|
39
|
+
});
|
|
40
|
+
return titleText;
|
|
41
|
+
}
|
|
42
|
+
var appShellCardBodyPaddingClasses = {
|
|
43
|
+
none: "",
|
|
44
|
+
md: "p-4 sm:p-6"
|
|
45
|
+
};
|
|
46
|
+
var appShellCardElevationClasses = {
|
|
47
|
+
none: "shadow-none",
|
|
48
|
+
"2xs": "shadow-2xs",
|
|
49
|
+
xs: "shadow-xs",
|
|
50
|
+
sm: "shadow-sm",
|
|
51
|
+
md: "shadow-md",
|
|
52
|
+
lg: "shadow-lg",
|
|
53
|
+
xl: "shadow-xl",
|
|
54
|
+
"2xl": "shadow-2xl"
|
|
55
|
+
};
|
|
56
|
+
var appShellCardToolbarClassName = "flex shrink-0 items-center gap-4 overflow-hidden border-b border-border px-4 py-3 sm:gap-6 sm:p-6";
|
|
57
|
+
var AppShellCardRoot = React$1.forwardRef(function AppShellCardRoot({ className, bodyPadding = "md", elevation = "md", bodyClassName, bodyAriaLabel, inset = false, children, ...props }, ref) {
|
|
58
|
+
const expansion = usePanelExpansion();
|
|
59
|
+
const menuId = React$1.useId();
|
|
60
|
+
const bodyRef = React$1.useRef(null);
|
|
61
|
+
React$1.useEffect(() => {
|
|
62
|
+
const el = bodyRef.current;
|
|
63
|
+
if (!el) return;
|
|
64
|
+
const update = () => {
|
|
65
|
+
const hasOverflow = el.scrollHeight > el.clientHeight;
|
|
66
|
+
const top = hasOverflow && el.scrollTop > 0 ? "1" : "0";
|
|
67
|
+
const bottom = hasOverflow && el.scrollTop + el.clientHeight < el.scrollHeight - 1 ? "1" : "0";
|
|
68
|
+
if (el.style.getPropertyValue("--scroll-t") !== top) el.style.setProperty("--scroll-t", top);
|
|
69
|
+
if (el.style.getPropertyValue("--scroll-b") !== bottom) el.style.setProperty("--scroll-b", bottom);
|
|
128
70
|
};
|
|
129
|
-
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
177
|
-
"data-slot": "app-sidebar-logo",
|
|
178
|
-
className: cn("flex h-[52px] items-center justify-between gap-2 rounded-md p-2", className),
|
|
71
|
+
el.addEventListener("scroll", update, { passive: true });
|
|
72
|
+
const OwnerResizeObserver = el.ownerDocument.defaultView?.ResizeObserver;
|
|
73
|
+
const observer = OwnerResizeObserver ? new OwnerResizeObserver(update) : null;
|
|
74
|
+
observer?.observe(el);
|
|
75
|
+
update();
|
|
76
|
+
return () => {
|
|
77
|
+
el.removeEventListener("scroll", update);
|
|
78
|
+
observer?.disconnect();
|
|
79
|
+
};
|
|
80
|
+
}, []);
|
|
81
|
+
let toolbarSlot = null;
|
|
82
|
+
let headerSlot = null;
|
|
83
|
+
let actionsSlot = null;
|
|
84
|
+
let menuSlot = null;
|
|
85
|
+
const toolbarChildren = [];
|
|
86
|
+
const bodyChildren = [];
|
|
87
|
+
for (const child of React$1.Children.toArray(children)) {
|
|
88
|
+
if (!React$1.isValidElement(child)) {
|
|
89
|
+
bodyChildren.push(child);
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
const type = getAppShellCardType(child);
|
|
93
|
+
if (type === HEADER_TYPE) headerSlot = child;
|
|
94
|
+
else if (type === TOOLBAR_TYPE) toolbarSlot = child;
|
|
95
|
+
else if (type === ACTIONS_TYPE) actionsSlot = child;
|
|
96
|
+
else if (type === MENU_TYPE) menuSlot = child;
|
|
97
|
+
else bodyChildren.push(child);
|
|
98
|
+
}
|
|
99
|
+
if (toolbarSlot) for (const child of React$1.Children.toArray(toolbarSlot.props.children)) {
|
|
100
|
+
if (!React$1.isValidElement(child)) {
|
|
101
|
+
toolbarChildren.push(child);
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
const type = getAppShellCardType(child);
|
|
105
|
+
if (type === HEADER_TYPE) headerSlot = child;
|
|
106
|
+
else if (type === ACTIONS_TYPE) actionsSlot = child;
|
|
107
|
+
else if (type === MENU_TYPE) menuSlot = child;
|
|
108
|
+
else toolbarChildren.push(child);
|
|
109
|
+
}
|
|
110
|
+
const hasToolbar = toolbarSlot || headerSlot || actionsSlot || menuSlot || toolbarChildren.length > 0 || expansion?.onExpandedChange;
|
|
111
|
+
const titleText = headerSlot ? getTitleText(headerSlot) : "";
|
|
112
|
+
const resolvedBodyAriaLabel = bodyAriaLabel ?? (titleText ? `${titleText} content` : "Card content");
|
|
113
|
+
const { children: _toolbarSlotChildren, className: toolbarClassName, ...toolbarProps } = toolbarSlot?.props ?? {};
|
|
114
|
+
return /* @__PURE__ */ jsxs(AppShellContent, {
|
|
115
|
+
ref,
|
|
116
|
+
"data-slot": "app-shell-card",
|
|
117
|
+
className: cn(appShellCardElevationClasses[elevation], "transition-[margin] duration-300 ease-[cubic-bezier(0.16,1,0.3,1)]", inset && !expansion?.expanded ? "mx-5 my-10" : "m-0", className),
|
|
179
118
|
...props,
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
119
|
+
children: [hasToolbar && /* @__PURE__ */ jsxs("div", {
|
|
120
|
+
role: "toolbar",
|
|
121
|
+
"aria-label": "Card actions",
|
|
122
|
+
...toolbarProps,
|
|
123
|
+
"data-slot": "app-shell-card-toolbar",
|
|
124
|
+
className: cn(appShellCardToolbarClassName, toolbarClassName),
|
|
125
|
+
children: [
|
|
126
|
+
headerSlot,
|
|
127
|
+
toolbarChildren,
|
|
128
|
+
actionsSlot,
|
|
129
|
+
menuSlot && /* @__PURE__ */ jsxs(DropdownMenu, { children: [/* @__PURE__ */ jsx(DropdownMenu.Trigger, { render: /* @__PURE__ */ jsx(Button, {
|
|
130
|
+
appearance: "ghost",
|
|
131
|
+
size: "icon",
|
|
132
|
+
"aria-label": "More options",
|
|
133
|
+
children: /* @__PURE__ */ jsx(EllipsisVertical, { className: "size-5" })
|
|
134
|
+
}) }), /* @__PURE__ */ jsx(DropdownMenu.Popup, {
|
|
135
|
+
id: `${menuId}-popup`,
|
|
136
|
+
align: "end",
|
|
137
|
+
sideOffset: 4,
|
|
138
|
+
children: menuSlot.props.children
|
|
139
|
+
})] }),
|
|
140
|
+
expansion?.onExpandedChange && /* @__PURE__ */ jsx(Button, {
|
|
141
|
+
appearance: "ghost",
|
|
142
|
+
size: "icon",
|
|
143
|
+
onClick: () => expansion.onExpandedChange?.(!expansion.expanded),
|
|
144
|
+
"aria-label": expansion.expanded ? "Minimize panel" : "Maximize panel",
|
|
145
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
146
|
+
className: "delight-fade-in inline-flex",
|
|
147
|
+
children: expansion.expanded ? /* @__PURE__ */ jsx(Minimize2, { className: "size-5" }) : /* @__PURE__ */ jsx(Maximize2, { className: "size-5" })
|
|
148
|
+
}, String(expansion.expanded))
|
|
149
|
+
})
|
|
150
|
+
]
|
|
151
|
+
}), /* @__PURE__ */ jsx("section", {
|
|
152
|
+
ref: bodyRef,
|
|
153
|
+
"data-slot": "app-shell-card-body",
|
|
154
|
+
"aria-label": resolvedBodyAriaLabel || "Card content",
|
|
155
|
+
tabIndex: 0,
|
|
156
|
+
className: cn("delight-scroll-shadow flex-1 min-h-0 overflow-auto focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring rounded-b-[inherit]", appShellCardBodyPaddingClasses[bodyPadding], bodyClassName),
|
|
157
|
+
children: bodyChildren
|
|
202
158
|
})]
|
|
203
159
|
});
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
function
|
|
160
|
+
});
|
|
161
|
+
AppShellCardRoot.displayName = "AppShellCard";
|
|
162
|
+
function AppShellCardToolbar({ className, children, ...props }) {
|
|
207
163
|
return /* @__PURE__ */ jsx("div", {
|
|
208
|
-
"data-slot": "app-
|
|
209
|
-
|
|
164
|
+
"data-slot": "app-shell-card-toolbar",
|
|
165
|
+
role: "toolbar",
|
|
166
|
+
"aria-label": "Card actions",
|
|
167
|
+
className: cn(appShellCardToolbarClassName, className),
|
|
168
|
+
...props,
|
|
210
169
|
children
|
|
211
170
|
});
|
|
212
171
|
}
|
|
213
|
-
|
|
214
|
-
|
|
172
|
+
AppShellCardToolbar.displayName = "AppShellCard.Toolbar";
|
|
173
|
+
assignAppShellCardType(AppShellCardToolbar, TOOLBAR_TYPE);
|
|
174
|
+
function AppShellCardHeader({ className, children, ...props }) {
|
|
215
175
|
return /* @__PURE__ */ jsx("div", {
|
|
216
|
-
"data-slot": "app-
|
|
217
|
-
className,
|
|
176
|
+
"data-slot": "app-shell-card-header",
|
|
177
|
+
className: cn("flex min-w-0 flex-1 flex-col justify-center", className),
|
|
178
|
+
...props,
|
|
218
179
|
children
|
|
219
180
|
});
|
|
220
181
|
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
182
|
+
AppShellCardHeader.displayName = "AppShellCard.Header";
|
|
183
|
+
assignAppShellCardType(AppShellCardHeader, HEADER_TYPE);
|
|
184
|
+
function AppShellCardTitle({ className, children, ...props }) {
|
|
185
|
+
return /* @__PURE__ */ jsx("h3", {
|
|
186
|
+
"data-slot": "app-shell-card-title",
|
|
187
|
+
className: cn("text-lg font-semibold leading-7 text-foreground", className),
|
|
188
|
+
...props,
|
|
226
189
|
children
|
|
227
190
|
});
|
|
228
191
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
"data-slot": "app-sidebar-nav",
|
|
237
|
-
className: cn("shrink-0 p-0 group-data-[collapsible=icon]:w-auto", className),
|
|
238
|
-
children: /* @__PURE__ */ jsx(SidebarGroupContent, { children: /* @__PURE__ */ jsx("nav", {
|
|
239
|
-
"aria-label": ariaLabel,
|
|
240
|
-
children: menuContent
|
|
241
|
-
}) })
|
|
242
|
-
});
|
|
243
|
-
}
|
|
244
|
-
AppSidebarNav.displayName = "AppSidebar.Nav";
|
|
245
|
-
markAppSidebarImplicitSlot(AppSidebarNav, "content");
|
|
246
|
-
function AppSidebarNavSection({ label, className }) {
|
|
247
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
248
|
-
"data-slot": "app-sidebar-nav-section",
|
|
249
|
-
role: "separator",
|
|
250
|
-
"aria-label": label,
|
|
251
|
-
className: cn("py-2 group-data-[collapsible=icon]:w-[52px]", className),
|
|
252
|
-
children: [/* @__PURE__ */ jsx("div", {
|
|
253
|
-
className: "flex h-8 items-center px-2 group-data-[collapsible=icon]:hidden",
|
|
254
|
-
children: /* @__PURE__ */ jsx("span", {
|
|
255
|
-
className: "text-xs font-medium text-sidebar-foreground/80",
|
|
256
|
-
children: label
|
|
257
|
-
})
|
|
258
|
-
}), /* @__PURE__ */ jsxs("div", {
|
|
259
|
-
className: "hidden py-2 group-data-[collapsible=icon]:block",
|
|
260
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
261
|
-
className: "sr-only",
|
|
262
|
-
children: label
|
|
263
|
-
}), /* @__PURE__ */ jsx(Separator, { className: "mx-auto w-full" })]
|
|
264
|
-
})]
|
|
265
|
-
});
|
|
266
|
-
}
|
|
267
|
-
AppSidebarNavSection.displayName = "AppSidebar.NavSection";
|
|
268
|
-
var navItemVariants = cva("relative flex w-full items-center gap-1.5 rounded-lg px-2 py-2 text-sm font-normal transition-[color,background-color] duration-200 ease-smooth motion-reduce:transition-none", {
|
|
269
|
-
variants: { state: {
|
|
270
|
-
default: "text-sidebar-foreground hover:bg-sidebar-accent",
|
|
271
|
-
active: "bg-primary/10 text-sidebar-foreground"
|
|
272
|
-
} },
|
|
273
|
-
defaultVariants: { state: "default" }
|
|
274
|
-
});
|
|
275
|
-
function AppSidebarNavItem({ icon, label, isActive = false, badge, onClick, href, className, children }) {
|
|
276
|
-
const { state, containerRef } = useSidebar();
|
|
277
|
-
const { side: sidebarSide } = useAppSidebarLayout();
|
|
278
|
-
const isCollapsed = state === "collapsed";
|
|
279
|
-
const hasChildren = React$1.Children.count(children) > 0;
|
|
280
|
-
const hasActiveChild = React$1.Children.toArray(children).some((child) => React$1.isValidElement(child) && child.props.isActive === true);
|
|
281
|
-
const isHighlighted = isActive || hasActiveChild;
|
|
282
|
-
const [isOpen, setIsOpen] = React$1.useState(isHighlighted && hasChildren);
|
|
283
|
-
const subNavId = React$1.useId();
|
|
284
|
-
const floatingSide = sidebarSide === "right" ? "left" : "right";
|
|
285
|
-
const flyoutPanelBackground = "linear-gradient(108deg, var(--opacity-white-87) 0.5219%, var(--opacity-white-75) 98.419%)";
|
|
286
|
-
const flyoutFrameEdgeClassName = sidebarSide === "right" ? "justify-end rounded-l-xl rounded-r-none" : "justify-start rounded-r-xl rounded-l-none";
|
|
287
|
-
const flyoutPanelEdgeClassName = sidebarSide === "right" ? "rounded-l-xl" : "rounded-r-xl";
|
|
288
|
-
const flyoutAnchor = React$1.useMemo(() => ({ getBoundingClientRect: () => {
|
|
289
|
-
const container = containerRef.current;
|
|
290
|
-
const rect = container?.getBoundingClientRect();
|
|
291
|
-
const viewportHeight = (container?.ownerDocument.defaultView)?.innerHeight ?? rect?.height ?? 0;
|
|
292
|
-
const x = rect ? sidebarSide === "right" ? rect.left : rect.right : 0;
|
|
293
|
-
return {
|
|
294
|
-
x,
|
|
295
|
-
y: 0,
|
|
296
|
-
top: 0,
|
|
297
|
-
right: x,
|
|
298
|
-
bottom: viewportHeight,
|
|
299
|
-
left: x,
|
|
300
|
-
width: 0,
|
|
301
|
-
height: viewportHeight
|
|
302
|
-
};
|
|
303
|
-
} }), [containerRef, sidebarSide]);
|
|
304
|
-
React$1.useEffect(() => {
|
|
305
|
-
if (isHighlighted && hasChildren) setIsOpen(true);
|
|
306
|
-
}, [isHighlighted, hasChildren]);
|
|
307
|
-
const accessibleLabel = formatAccessibleLabel(label, badge);
|
|
308
|
-
const iconElement = /* @__PURE__ */ jsx("span", {
|
|
309
|
-
"data-slot": "nav-icon",
|
|
310
|
-
className: "flex shrink-0 items-center p-0.5 [&>svg]:size-4",
|
|
311
|
-
children: icon
|
|
312
|
-
});
|
|
313
|
-
const labelElement = /* @__PURE__ */ jsx("span", {
|
|
314
|
-
className: "flex-1 text-start group-data-[collapsible=icon]:hidden",
|
|
315
|
-
children: label
|
|
316
|
-
});
|
|
317
|
-
const badgeElement = badge != null && /* @__PURE__ */ jsx(Badge, {
|
|
318
|
-
size: "sm",
|
|
319
|
-
variant: "soft",
|
|
320
|
-
color: "primary",
|
|
321
|
-
className: "px-1.5 group-data-[collapsible=icon]:hidden",
|
|
322
|
-
"aria-hidden": "true",
|
|
323
|
-
children: badge
|
|
324
|
-
});
|
|
325
|
-
const chevronElement = hasChildren && /* @__PURE__ */ jsx(ChevronRight, {
|
|
326
|
-
"aria-hidden": "true",
|
|
327
|
-
className: cn("size-4 shrink-0 text-muted-foreground transition-transform duration-200 ease-smooth group-data-[collapsible=icon]:hidden motion-reduce:transition-none", isOpen ? "rotate-90" : "rtl:rotate-180", isHighlighted && isOpen && "text-primary")
|
|
328
|
-
});
|
|
329
|
-
const itemClassName = cn(navItemVariants({ state: isHighlighted ? "active" : "default" }), "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring", "min-h-11 group-data-[collapsible=icon]:justify-center group-data-[collapsible=icon]:px-0 group-data-[collapsible=icon]:py-2 group-data-[collapsible=icon]:w-11 group-data-[collapsible=icon]:h-11", className);
|
|
330
|
-
const ariaProps = isActive ? { "aria-current": "page" } : {};
|
|
331
|
-
if (isCollapsed) {
|
|
332
|
-
const collapsedIconElement = /* @__PURE__ */ jsx("span", {
|
|
333
|
-
"data-slot": "nav-icon",
|
|
334
|
-
className: "flex shrink-0 items-center justify-center p-0.5 [&>svg]:size-4",
|
|
335
|
-
children: icon
|
|
336
|
-
});
|
|
337
|
-
const triggerElement = href ? /* @__PURE__ */ jsx("a", {
|
|
338
|
-
href,
|
|
339
|
-
className: cn(itemClassName),
|
|
340
|
-
"aria-label": accessibleLabel,
|
|
341
|
-
...ariaProps,
|
|
342
|
-
"data-slot": "app-sidebar-nav-item",
|
|
343
|
-
children: collapsedIconElement
|
|
344
|
-
}) : /* @__PURE__ */ jsx("button", {
|
|
345
|
-
type: "button",
|
|
346
|
-
onClick: hasChildren ? () => setIsOpen(!isOpen) : onClick,
|
|
347
|
-
className: cn(itemClassName, "cursor-pointer"),
|
|
348
|
-
"aria-label": accessibleLabel,
|
|
349
|
-
...ariaProps,
|
|
350
|
-
"data-slot": "app-sidebar-nav-item",
|
|
351
|
-
children: collapsedIconElement
|
|
352
|
-
});
|
|
353
|
-
if (!hasChildren) {
|
|
354
|
-
if (!label) return triggerElement;
|
|
355
|
-
return /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, { render: triggerElement }), /* @__PURE__ */ jsx(TooltipPopup, {
|
|
356
|
-
side: floatingSide,
|
|
357
|
-
sideOffset: 8,
|
|
358
|
-
children: label
|
|
359
|
-
})] });
|
|
360
|
-
}
|
|
361
|
-
return /* @__PURE__ */ jsxs(PopoverRoot, { children: [/* @__PURE__ */ jsx(PopoverTrigger, {
|
|
362
|
-
className: cn(itemClassName, "cursor-pointer"),
|
|
363
|
-
"aria-label": accessibleLabel,
|
|
364
|
-
"data-slot": "app-sidebar-nav-item",
|
|
365
|
-
children: collapsedIconElement
|
|
366
|
-
}), /* @__PURE__ */ jsx(PopoverPopup, {
|
|
367
|
-
side: floatingSide,
|
|
368
|
-
align: "start",
|
|
369
|
-
sideOffset: 0,
|
|
370
|
-
alignOffset: 0,
|
|
371
|
-
anchor: flyoutAnchor,
|
|
372
|
-
collisionAvoidance: {
|
|
373
|
-
side: "none",
|
|
374
|
-
align: "none",
|
|
375
|
-
fallbackAxisSide: "none"
|
|
376
|
-
},
|
|
377
|
-
positionMethod: "fixed",
|
|
378
|
-
"aria-label": `${label} sub-navigation`,
|
|
379
|
-
style: { "--app-sidebar-flyout-panel-bg": flyoutPanelBackground },
|
|
380
|
-
className: cn("flex h-[var(--anchor-height)] w-[276px] border-0 bg-transparent p-0 ring-0 shadow-none", "overflow-clip", flyoutFrameEdgeClassName),
|
|
381
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
382
|
-
className: cn("flex h-full w-64 flex-col gap-0.5 overflow-y-auto p-3 shadow-[var(--shadow-hover-card)]", "supports-backdrop-filter:backdrop-blur-[60px] [background-image:var(--app-sidebar-flyout-panel-bg)] delight-tooltip-stagger", flyoutPanelEdgeClassName),
|
|
383
|
-
"data-slot": "app-sidebar-nav-flyout-panel",
|
|
384
|
-
role: "group",
|
|
385
|
-
"aria-label": label,
|
|
386
|
-
children: [/* @__PURE__ */ jsx("p", {
|
|
387
|
-
className: "px-2 pb-2 pt-1 text-xs font-semibold text-primary opacity-70",
|
|
388
|
-
"aria-hidden": "true",
|
|
389
|
-
children: label
|
|
390
|
-
}), children]
|
|
391
|
-
})
|
|
392
|
-
})] });
|
|
393
|
-
}
|
|
394
|
-
const handleClick = () => {
|
|
395
|
-
if (hasChildren) setIsOpen(!isOpen);
|
|
396
|
-
onClick?.();
|
|
397
|
-
};
|
|
398
|
-
const mainElement = href && !hasChildren ? /* @__PURE__ */ jsxs("a", {
|
|
399
|
-
href,
|
|
400
|
-
className: itemClassName,
|
|
401
|
-
"aria-label": accessibleLabel,
|
|
402
|
-
...ariaProps,
|
|
403
|
-
"data-slot": "app-sidebar-nav-item",
|
|
404
|
-
children: [
|
|
405
|
-
iconElement,
|
|
406
|
-
labelElement,
|
|
407
|
-
badgeElement,
|
|
408
|
-
chevronElement
|
|
409
|
-
]
|
|
410
|
-
}) : /* @__PURE__ */ jsxs("button", {
|
|
411
|
-
type: "button",
|
|
412
|
-
onClick: handleClick,
|
|
413
|
-
className: cn(itemClassName, "cursor-pointer"),
|
|
414
|
-
"aria-label": accessibleLabel,
|
|
415
|
-
"aria-expanded": hasChildren ? isOpen : void 0,
|
|
416
|
-
"aria-controls": hasChildren ? subNavId : void 0,
|
|
417
|
-
...ariaProps,
|
|
418
|
-
"data-slot": "app-sidebar-nav-item",
|
|
419
|
-
children: [
|
|
420
|
-
iconElement,
|
|
421
|
-
labelElement,
|
|
422
|
-
badgeElement,
|
|
423
|
-
chevronElement
|
|
424
|
-
]
|
|
425
|
-
});
|
|
426
|
-
if (!hasChildren) return mainElement;
|
|
427
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [mainElement, isOpen && /* @__PURE__ */ jsx("ul", {
|
|
428
|
-
id: subNavId,
|
|
429
|
-
role: "group",
|
|
430
|
-
"aria-label": `${label} sub-navigation`,
|
|
431
|
-
className: "ms-4 flex flex-col items-start border-s border-sidebar-border py-1 ps-2",
|
|
192
|
+
AppShellCardTitle.displayName = "AppShellCard.Title";
|
|
193
|
+
assignAppShellCardType(AppShellCardTitle, TITLE_TYPE);
|
|
194
|
+
function AppShellCardSubtitle({ className, children, ...props }) {
|
|
195
|
+
return /* @__PURE__ */ jsx("p", {
|
|
196
|
+
"data-slot": "app-shell-card-subtitle",
|
|
197
|
+
className: cn("text-sm leading-5 text-secondary-foreground", className),
|
|
198
|
+
...props,
|
|
432
199
|
children
|
|
433
|
-
})] });
|
|
434
|
-
}
|
|
435
|
-
AppSidebarNavItem.displayName = "AppSidebar.NavItem";
|
|
436
|
-
function AppSidebarNavSub({ label, badge, isActive = false, href, onClick, className }) {
|
|
437
|
-
const accessibleLabel = formatAccessibleLabel(label, badge);
|
|
438
|
-
const itemClassName = cn(navItemVariants({ state: isActive ? "active" : "default" }), "min-h-11 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring", "transition-[color,background-color,transform] ltr:hover:translate-x-0.5 rtl:hover:-translate-x-0.5 motion-reduce:ltr:hover:translate-x-0 motion-reduce:rtl:hover:translate-x-0", className);
|
|
439
|
-
const ariaProps = isActive ? { "aria-current": "page" } : {};
|
|
440
|
-
const content = /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
|
|
441
|
-
className: "flex-1 text-start",
|
|
442
|
-
children: label
|
|
443
|
-
}), badge != null && /* @__PURE__ */ jsx(Badge, {
|
|
444
|
-
size: "sm",
|
|
445
|
-
variant: "soft",
|
|
446
|
-
color: "primary",
|
|
447
|
-
className: "px-1.5",
|
|
448
|
-
"aria-hidden": "true",
|
|
449
|
-
children: badge
|
|
450
|
-
})] });
|
|
451
|
-
if (href) return /* @__PURE__ */ jsx("a", {
|
|
452
|
-
href,
|
|
453
|
-
className: itemClassName,
|
|
454
|
-
"aria-label": accessibleLabel,
|
|
455
|
-
...ariaProps,
|
|
456
|
-
"data-slot": "app-sidebar-nav-sub",
|
|
457
|
-
children: content
|
|
458
|
-
});
|
|
459
|
-
return /* @__PURE__ */ jsx("button", {
|
|
460
|
-
type: "button",
|
|
461
|
-
onClick,
|
|
462
|
-
className: cn(itemClassName, "cursor-pointer delight-selection-press"),
|
|
463
|
-
"aria-label": accessibleLabel,
|
|
464
|
-
...ariaProps,
|
|
465
|
-
"data-slot": "app-sidebar-nav-sub",
|
|
466
|
-
children: content
|
|
467
|
-
});
|
|
468
|
-
}
|
|
469
|
-
AppSidebarNavSub.displayName = "AppSidebar.NavSub";
|
|
470
|
-
function AppSidebarNavSkeleton({ count = 3, className }) {
|
|
471
|
-
const skeletonCount = getSkeletonCount(count, 3);
|
|
472
|
-
return /* @__PURE__ */ jsx(SidebarGroup, {
|
|
473
|
-
className: cn("shrink-0 p-0 group-data-[collapsible=icon]:w-auto", className),
|
|
474
|
-
children: /* @__PURE__ */ jsx(SidebarGroupContent, { children: /* @__PURE__ */ jsx(SidebarMenu, {
|
|
475
|
-
className: "gap-0.5 group-data-[collapsible=icon]:items-center group-data-[collapsible=icon]:gap-2",
|
|
476
|
-
children: Array.from({ length: skeletonCount }).map((_, i) => /* @__PURE__ */ jsx(SidebarMenuItem, { children: /* @__PURE__ */ jsx(SidebarNavSkeleton, {}) }, `nav-skeleton-${i}`))
|
|
477
|
-
}) })
|
|
478
200
|
});
|
|
479
201
|
}
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
function AppSidebarChatList({ label = "Recent Chats", children, className }) {
|
|
483
|
-
const { state } = useSidebar();
|
|
484
|
-
if (state === "collapsed") return null;
|
|
485
|
-
return /* @__PURE__ */ jsxs(SidebarGroup, {
|
|
486
|
-
"data-slot": "app-sidebar-chat-list",
|
|
487
|
-
className: cn("mt-4 flex min-h-0 flex-1 flex-col p-0", className),
|
|
488
|
-
children: [/* @__PURE__ */ jsx(SidebarGroupLabel, {
|
|
489
|
-
className: "shrink-0 px-3 py-1 text-xs font-bold text-muted-foreground",
|
|
490
|
-
children: label
|
|
491
|
-
}), /* @__PURE__ */ jsx(SidebarGroupContent, {
|
|
492
|
-
className: "flex-1 overflow-hidden",
|
|
493
|
-
children: /* @__PURE__ */ jsx("div", {
|
|
494
|
-
className: "flex h-full flex-col overflow-y-auto pb-5 rounded-md focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring",
|
|
495
|
-
tabIndex: 0,
|
|
496
|
-
role: "list",
|
|
497
|
-
"aria-label": label,
|
|
498
|
-
children
|
|
499
|
-
})
|
|
500
|
-
})]
|
|
501
|
-
});
|
|
502
|
-
}
|
|
503
|
-
AppSidebarChatList.displayName = "AppSidebar.ChatList";
|
|
504
|
-
markAppSidebarImplicitSlot(AppSidebarChatList, "content");
|
|
505
|
-
var chatItemVariants = cva("flex w-full items-center justify-between gap-2 rounded-md px-3 py-2 min-h-11 transition-[color,background-color,transform] duration-200 ease-smooth cursor-pointer motion-reduce:transition-none ltr:hover:translate-x-0.5 rtl:hover:-translate-x-0.5 motion-reduce:ltr:hover:translate-x-0 motion-reduce:rtl:hover:translate-x-0", {
|
|
506
|
-
variants: { state: {
|
|
507
|
-
default: "hover:bg-muted",
|
|
508
|
-
hover: "bg-muted",
|
|
509
|
-
selected: "bg-primary/10"
|
|
510
|
-
} },
|
|
511
|
-
defaultVariants: { state: "default" }
|
|
512
|
-
});
|
|
513
|
-
function AppSidebarChatItem({ title, time, icon, isSelected = false, onClick, onContextMenu, className }) {
|
|
514
|
-
const { state } = useSidebar();
|
|
515
|
-
const { side: sidebarSide } = useAppSidebarLayout();
|
|
516
|
-
const isCollapsed = state === "collapsed";
|
|
517
|
-
const tooltipSide = sidebarSide === "right" ? "left" : "right";
|
|
518
|
-
if (isCollapsed) {
|
|
519
|
-
const collapsedButton = /* @__PURE__ */ jsx("button", {
|
|
520
|
-
type: "button",
|
|
521
|
-
onClick,
|
|
522
|
-
onContextMenu,
|
|
523
|
-
"data-slot": "app-sidebar-chat-item",
|
|
524
|
-
"aria-label": title || void 0,
|
|
525
|
-
className: cn("flex size-11 items-center justify-center rounded-md transition-colors duration-200 ease-smooth motion-reduce:transition-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring", isSelected ? "bg-primary/10" : "hover:bg-muted", className),
|
|
526
|
-
children: icon || /* @__PURE__ */ jsx(MessageCircle, { className: "size-5 text-secondary-foreground" })
|
|
527
|
-
});
|
|
528
|
-
if (!title && !time) return collapsedButton;
|
|
529
|
-
return /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, { render: collapsedButton }), /* @__PURE__ */ jsx(TooltipPopup, {
|
|
530
|
-
side: tooltipSide,
|
|
531
|
-
sideOffset: 8,
|
|
532
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
533
|
-
className: "flex flex-col",
|
|
534
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
535
|
-
className: "font-medium",
|
|
536
|
-
children: title
|
|
537
|
-
}), time && /* @__PURE__ */ jsx("span", {
|
|
538
|
-
className: "text-xs text-muted-foreground",
|
|
539
|
-
children: time
|
|
540
|
-
})]
|
|
541
|
-
})
|
|
542
|
-
})] });
|
|
543
|
-
}
|
|
202
|
+
AppShellCardSubtitle.displayName = "AppShellCard.Subtitle";
|
|
203
|
+
function AppShellCardActions({ className, children, ...props }) {
|
|
544
204
|
return /* @__PURE__ */ jsx("div", {
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
onContextMenu,
|
|
550
|
-
"data-slot": "app-sidebar-chat-item",
|
|
551
|
-
"aria-label": title,
|
|
552
|
-
className: cn(chatItemVariants({ state: isSelected ? "selected" : "default" }), "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring", className),
|
|
553
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
554
|
-
className: "text-base font-semibold text-secondary-foreground truncate",
|
|
555
|
-
children: title
|
|
556
|
-
}), time && /* @__PURE__ */ jsx("span", {
|
|
557
|
-
className: "text-xs font-normal text-muted-foreground shrink-0",
|
|
558
|
-
children: time
|
|
559
|
-
})]
|
|
560
|
-
})
|
|
561
|
-
});
|
|
562
|
-
}
|
|
563
|
-
AppSidebarChatItem.displayName = "AppSidebar.ChatItem";
|
|
564
|
-
function AppSidebarChatListSkeleton({ count = 5, label = "Recent Chats", className }) {
|
|
565
|
-
const skeletonCount = getSkeletonCount(count, 5);
|
|
566
|
-
return /* @__PURE__ */ jsxs(SidebarGroup, {
|
|
567
|
-
className: cn("mt-4 flex min-h-0 flex-1 flex-col p-0 group-data-[collapsible=icon]:hidden", className),
|
|
568
|
-
children: [/* @__PURE__ */ jsx(SidebarGroupLabel, {
|
|
569
|
-
className: "shrink-0 px-3 py-1 text-xs font-bold text-muted-foreground",
|
|
570
|
-
children: label
|
|
571
|
-
}), /* @__PURE__ */ jsx(SidebarGroupContent, {
|
|
572
|
-
className: "flex-1 overflow-hidden",
|
|
573
|
-
children: /* @__PURE__ */ jsx("div", {
|
|
574
|
-
className: "flex h-full flex-col overflow-y-auto pb-5",
|
|
575
|
-
children: Array.from({ length: skeletonCount }).map((_, i) => /* @__PURE__ */ jsx(SidebarMenuSkeleton, {}, `chat-skeleton-${i}`))
|
|
576
|
-
})
|
|
577
|
-
})]
|
|
578
|
-
});
|
|
579
|
-
}
|
|
580
|
-
AppSidebarChatListSkeleton.displayName = "AppSidebar.ChatListSkeleton";
|
|
581
|
-
markAppSidebarImplicitSlot(AppSidebarChatListSkeleton, "content");
|
|
582
|
-
function AppSidebarAccount({ name, subtitle, avatarSrc, isOnline = false, onExpand, className }) {
|
|
583
|
-
const { state } = useSidebar();
|
|
584
|
-
const { side: sidebarSide } = useAppSidebarLayout();
|
|
585
|
-
const isCollapsed = state === "collapsed";
|
|
586
|
-
const tooltipSide = sidebarSide === "right" ? "left" : "right";
|
|
587
|
-
if (isCollapsed) {
|
|
588
|
-
const avatarButton = /* @__PURE__ */ jsx("button", {
|
|
589
|
-
type: "button",
|
|
590
|
-
onClick: onExpand,
|
|
591
|
-
"data-slot": "app-sidebar-account",
|
|
592
|
-
"aria-label": name ? `${name} account menu` : "Account menu",
|
|
593
|
-
"aria-haspopup": "true",
|
|
594
|
-
className: cn("flex min-h-11 min-w-11 items-center justify-center rounded-lg transition-opacity duration-200 ease-smooth hover:opacity-80 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring motion-reduce:transition-none", className),
|
|
595
|
-
children: /* @__PURE__ */ jsx(Avatar, {
|
|
596
|
-
src: avatarSrc,
|
|
597
|
-
alt: name,
|
|
598
|
-
fallback: name,
|
|
599
|
-
size: "sm",
|
|
600
|
-
className: "size-[42px]",
|
|
601
|
-
indicator: isOnline ? "online" : void 0
|
|
602
|
-
})
|
|
603
|
-
});
|
|
604
|
-
if (!name && !subtitle) return avatarButton;
|
|
605
|
-
return /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, { render: avatarButton }), /* @__PURE__ */ jsx(TooltipPopup, {
|
|
606
|
-
side: tooltipSide,
|
|
607
|
-
sideOffset: 8,
|
|
608
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
609
|
-
className: "flex flex-col",
|
|
610
|
-
children: [name && /* @__PURE__ */ jsx("span", {
|
|
611
|
-
className: "font-medium",
|
|
612
|
-
children: name
|
|
613
|
-
}), subtitle && /* @__PURE__ */ jsx("span", {
|
|
614
|
-
className: "text-xs text-muted-foreground",
|
|
615
|
-
children: subtitle
|
|
616
|
-
})]
|
|
617
|
-
})
|
|
618
|
-
})] });
|
|
619
|
-
}
|
|
620
|
-
return /* @__PURE__ */ jsxs("button", {
|
|
621
|
-
type: "button",
|
|
622
|
-
onClick: onExpand,
|
|
623
|
-
"data-slot": "app-sidebar-account",
|
|
624
|
-
"aria-label": name ? `${name} account menu` : "Account menu",
|
|
625
|
-
"aria-haspopup": "true",
|
|
626
|
-
className: cn("flex w-full items-center gap-1.5 rounded-lg px-1 py-2 transition-colors duration-200 ease-smooth hover:bg-sidebar-accent focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring motion-reduce:transition-none", className),
|
|
627
|
-
children: [/* @__PURE__ */ jsx(Avatar, {
|
|
628
|
-
src: avatarSrc,
|
|
629
|
-
alt: name,
|
|
630
|
-
fallback: name,
|
|
631
|
-
size: "sm",
|
|
632
|
-
className: "size-[42px]",
|
|
633
|
-
indicator: isOnline ? "online" : void 0
|
|
634
|
-
}), /* @__PURE__ */ jsxs("div", {
|
|
635
|
-
className: "flex flex-1 flex-col items-start overflow-hidden",
|
|
636
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
637
|
-
className: "w-full truncate text-start text-sm font-medium text-sidebar-foreground",
|
|
638
|
-
children: name
|
|
639
|
-
}), subtitle && /* @__PURE__ */ jsx("span", {
|
|
640
|
-
className: "w-full truncate text-start text-xs font-light text-sidebar-foreground",
|
|
641
|
-
children: subtitle
|
|
642
|
-
})]
|
|
643
|
-
})]
|
|
644
|
-
});
|
|
645
|
-
}
|
|
646
|
-
AppSidebarAccount.displayName = "AppSidebar.Account";
|
|
647
|
-
markAppSidebarImplicitSlot(AppSidebarAccount, "footer");
|
|
648
|
-
function AppSidebarAccountSkeleton({ className }) {
|
|
649
|
-
return /* @__PURE__ */ jsx(SidebarAccountSkeleton, { className });
|
|
650
|
-
}
|
|
651
|
-
AppSidebarAccountSkeleton.displayName = "AppSidebar.AccountSkeleton";
|
|
652
|
-
markAppSidebarImplicitSlot(AppSidebarAccountSkeleton, "footer");
|
|
653
|
-
function AppSidebarSkeleton({ navCount = 4, chatCount = 5, logo, compactedLogo, collapsible = "icon", side, rounded = false, sidebarBgColor, className }) {
|
|
654
|
-
const { state, containerRef } = useSidebar();
|
|
655
|
-
const isCollapsed = state === "collapsed";
|
|
656
|
-
const resolvedSide = useResolvedAppSidebarSide({
|
|
657
|
-
containerRef,
|
|
658
|
-
explicitSide: side
|
|
659
|
-
});
|
|
660
|
-
const bgClass = getSidebarBgClass(isCollapsed, sidebarBgColor);
|
|
661
|
-
return /* @__PURE__ */ jsx(SidebarCompound, {
|
|
662
|
-
collapsible,
|
|
663
|
-
side: resolvedSide,
|
|
664
|
-
width: APP_SIDEBAR_WIDTH,
|
|
665
|
-
collapsedWidth: APP_SIDEBAR_COLLAPSED_WIDTH,
|
|
666
|
-
className: cn("bg-transparent", className),
|
|
667
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
668
|
-
"data-slot": "app-sidebar-surface",
|
|
669
|
-
className: getSidebarSurfaceClass({
|
|
670
|
-
isCollapsed,
|
|
671
|
-
side: resolvedSide,
|
|
672
|
-
rounded,
|
|
673
|
-
backgroundClass: bgClass
|
|
674
|
-
}),
|
|
675
|
-
children: [
|
|
676
|
-
/* @__PURE__ */ jsx(SidebarHeader, {
|
|
677
|
-
className: "h-[68px] w-full p-2",
|
|
678
|
-
children: /* @__PURE__ */ jsx(AppSidebarLogo, {
|
|
679
|
-
logo,
|
|
680
|
-
compactedLogo
|
|
681
|
-
})
|
|
682
|
-
}),
|
|
683
|
-
/* @__PURE__ */ jsxs(SidebarContent, {
|
|
684
|
-
className: "flex w-full flex-col gap-0 overflow-hidden pt-3 group-data-[collapsible=icon]:items-center",
|
|
685
|
-
children: [/* @__PURE__ */ jsx(AppSidebarNavSkeleton, { count: navCount }), /* @__PURE__ */ jsx(AppSidebarChatListSkeleton, { count: chatCount })]
|
|
686
|
-
}),
|
|
687
|
-
/* @__PURE__ */ jsx(SidebarFooter, {
|
|
688
|
-
className: "w-full gap-0 p-0 group-data-[collapsible=icon]:items-center",
|
|
689
|
-
children: /* @__PURE__ */ jsx(AppSidebarAccountSkeleton, {})
|
|
690
|
-
})
|
|
691
|
-
]
|
|
692
|
-
})
|
|
693
|
-
});
|
|
694
|
-
}
|
|
695
|
-
AppSidebarSkeleton.displayName = "AppSidebar.Skeleton";
|
|
696
|
-
/**
|
|
697
|
-
* AppSidebar is a full-featured application sidebar with navigation, chat list, and account sections.
|
|
698
|
-
* Supports collapsible modes with a unified logo toggle and loading skeletons.
|
|
699
|
-
*
|
|
700
|
-
* @llms Full-featured app sidebar with nav, chat list, account, collapsible modes
|
|
701
|
-
* @example
|
|
702
|
-
* ```tsx
|
|
703
|
-
* <AppSidebar logo={<Logo />} collapsible="icon">
|
|
704
|
-
* <AppSidebar.Nav>
|
|
705
|
-
* <AppSidebar.NavItem icon={<Home />} label="Home" isActive />
|
|
706
|
-
* </AppSidebar.Nav>
|
|
707
|
-
* <AppSidebar.ChatList>
|
|
708
|
-
* <AppSidebar.ChatItem title="Chat 1" />
|
|
709
|
-
* </AppSidebar.ChatList>
|
|
710
|
-
* <AppSidebar.Account name="User" subtitle="user@example.com" />
|
|
711
|
-
* </AppSidebar>
|
|
712
|
-
* ```
|
|
713
|
-
*/
|
|
714
|
-
function AppSidebarRoot({ logo, compactedLogo, logoSubtext, collapsible = "icon", side, rounded = false, sidebarBgColor, className, children, dir, ...props }) {
|
|
715
|
-
const { state, containerRef } = useSidebar();
|
|
716
|
-
const isCollapsed = state === "collapsed";
|
|
717
|
-
const resolvedSide = useResolvedAppSidebarSide({
|
|
718
|
-
containerRef,
|
|
719
|
-
explicitDir: dir,
|
|
720
|
-
explicitSide: side
|
|
721
|
-
});
|
|
722
|
-
const bgClass = getSidebarBgClass(isCollapsed, sidebarBgColor);
|
|
723
|
-
const slots = useSlotChildren(children);
|
|
724
|
-
return /* @__PURE__ */ jsx(AppSidebarLayoutContext.Provider, {
|
|
725
|
-
value: { side: resolvedSide },
|
|
726
|
-
children: /* @__PURE__ */ jsx(SidebarCompound, {
|
|
727
|
-
collapsible,
|
|
728
|
-
side: resolvedSide,
|
|
729
|
-
width: APP_SIDEBAR_WIDTH,
|
|
730
|
-
collapsedWidth: APP_SIDEBAR_COLLAPSED_WIDTH,
|
|
731
|
-
dir,
|
|
732
|
-
className: cn("bg-transparent", className),
|
|
733
|
-
...props,
|
|
734
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
735
|
-
"data-slot": "app-sidebar-surface",
|
|
736
|
-
className: getSidebarSurfaceClass({
|
|
737
|
-
isCollapsed,
|
|
738
|
-
side: resolvedSide,
|
|
739
|
-
rounded,
|
|
740
|
-
backgroundClass: bgClass
|
|
741
|
-
}),
|
|
742
|
-
children: [
|
|
743
|
-
/* @__PURE__ */ jsx(SidebarHeader, {
|
|
744
|
-
className: "h-[68px] w-full p-2",
|
|
745
|
-
children: /* @__PURE__ */ jsx(AppSidebarLogo, {
|
|
746
|
-
logo,
|
|
747
|
-
compactedLogo,
|
|
748
|
-
subtext: logoSubtext
|
|
749
|
-
})
|
|
750
|
-
}),
|
|
751
|
-
/* @__PURE__ */ jsx(SidebarContent, {
|
|
752
|
-
className: "flex w-full flex-col gap-0 overflow-hidden pt-3 group-data-[collapsible=icon]:items-center",
|
|
753
|
-
children: slots.explicitContent ? slots.explicitContent.props.children : slots.content
|
|
754
|
-
}),
|
|
755
|
-
/* @__PURE__ */ jsx(SidebarFooter, {
|
|
756
|
-
className: "w-full gap-0 p-0 group-data-[collapsible=icon]:items-center",
|
|
757
|
-
children: slots.explicitFooter ? slots.explicitFooter.props.children : slots.footer
|
|
758
|
-
})
|
|
759
|
-
]
|
|
760
|
-
})
|
|
761
|
-
})
|
|
205
|
+
"data-slot": "app-shell-card-actions",
|
|
206
|
+
className: cn("flex shrink-0 items-center gap-2", className),
|
|
207
|
+
...props,
|
|
208
|
+
children
|
|
762
209
|
});
|
|
763
210
|
}
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
AccountSkeleton: AppSidebarAccountSkeleton,
|
|
779
|
-
Skeleton: AppSidebarSkeleton
|
|
211
|
+
AppShellCardActions.displayName = "AppShellCard.Actions";
|
|
212
|
+
assignAppShellCardType(AppShellCardActions, ACTIONS_TYPE);
|
|
213
|
+
function AppShellCardMenu({ children }) {
|
|
214
|
+
return children;
|
|
215
|
+
}
|
|
216
|
+
AppShellCardMenu.displayName = "AppShellCard.Menu";
|
|
217
|
+
assignAppShellCardType(AppShellCardMenu, MENU_TYPE);
|
|
218
|
+
var AppShellCard = Object.assign(AppShellCardRoot, {
|
|
219
|
+
Toolbar: AppShellCardToolbar,
|
|
220
|
+
Header: AppShellCardHeader,
|
|
221
|
+
Title: AppShellCardTitle,
|
|
222
|
+
Subtitle: AppShellCardSubtitle,
|
|
223
|
+
Actions: AppShellCardActions,
|
|
224
|
+
Menu: AppShellCardMenu
|
|
780
225
|
});
|
|
781
226
|
//#endregion
|
|
782
|
-
export {
|
|
227
|
+
export { AppShellCard, AppShellCardActions, AppShellCardHeader, AppShellCardMenu, AppShellCardRoot, AppShellCardSubtitle, AppShellCardTitle, AppShellCardToolbar };
|
|
783
228
|
|
|
784
229
|
//# sourceMappingURL=index224.js.map
|