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