@humain/ui 2.2.2 → 2.2.4

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.
Files changed (85) hide show
  1. package/dist/components/templates/AppShell/AppShell.d.ts +5 -3
  2. package/dist/components/templates/AppShell/index.d.ts +1 -1
  3. package/dist/components/templates/AppSidebar/AppSidebar.constants.d.ts +4 -0
  4. package/dist/components/templates/AppSidebar/AppSidebar.d.ts +1 -0
  5. package/dist/index.js +19 -18
  6. package/dist/index152.js +1 -1
  7. package/dist/index152.js.map +1 -1
  8. package/dist/index173.js +1 -1
  9. package/dist/index173.js.map +1 -1
  10. package/dist/index184.js +1 -1
  11. package/dist/index184.js.map +1 -1
  12. package/dist/index217.js +6 -24
  13. package/dist/index217.js.map +1 -1
  14. package/dist/index218.js +20 -23
  15. package/dist/index218.js.map +1 -1
  16. package/dist/index219.js +20 -95
  17. package/dist/index219.js.map +1 -1
  18. package/dist/index220.js +92 -88
  19. package/dist/index220.js.map +1 -1
  20. package/dist/index221.js +97 -29
  21. package/dist/index221.js.map +1 -1
  22. package/dist/index222.js +24 -470
  23. package/dist/index222.js.map +1 -1
  24. package/dist/index223.js +450 -196
  25. package/dist/index223.js.map +1 -1
  26. package/dist/index224.js +199 -754
  27. package/dist/index224.js.map +1 -1
  28. package/dist/index225.js +777 -61
  29. package/dist/index225.js.map +1 -1
  30. package/dist/index226.js +58 -181
  31. package/dist/index226.js.map +1 -1
  32. package/dist/index227.js +175 -259
  33. package/dist/index227.js.map +1 -1
  34. package/dist/index228.js +246 -172
  35. package/dist/index228.js.map +1 -1
  36. package/dist/index229.js +195 -32
  37. package/dist/index229.js.map +1 -1
  38. package/dist/index230.js +12 -40
  39. package/dist/index230.js.map +1 -1
  40. package/dist/index231.js +23 -26
  41. package/dist/index231.js.map +1 -1
  42. package/dist/index232.js +45 -22
  43. package/dist/index232.js.map +1 -1
  44. package/dist/index233.js +27 -48
  45. package/dist/index233.js.map +1 -1
  46. package/dist/index234.js +52 -26
  47. package/dist/index234.js.map +1 -1
  48. package/dist/index235.js +40 -225
  49. package/dist/index235.js.map +1 -1
  50. package/dist/index236.js +217 -39
  51. package/dist/index236.js.map +1 -1
  52. package/dist/index237.js +50 -0
  53. package/dist/index237.js.map +1 -0
  54. package/dist/styles.css +1 -1
  55. package/dist/wc/AISource.js +46 -46
  56. package/dist/wc/AISource.js.map +1 -1
  57. package/dist/wc/AIToolCall.js +9 -9
  58. package/dist/wc/AIToolCall.js.map +1 -1
  59. package/dist/wc/{sidebar.js → AppSidebar.constants.js} +80 -78
  60. package/dist/wc/AppSidebar.constants.js.map +1 -0
  61. package/dist/wc/hf-app-shell.js +346 -343
  62. package/dist/wc/hf-app-shell.js.map +1 -1
  63. package/dist/wc/hf-app-sidebar.js +68 -65
  64. package/dist/wc/hf-app-sidebar.js.map +1 -1
  65. package/dist/wc/markdown-renderer.js +1 -1
  66. package/dist/wc/markdown-renderer.js.map +1 -1
  67. package/dist/wc-react/AISource.js +8 -8
  68. package/dist/wc-react/AISource.js.map +1 -1
  69. package/dist/wc-react/AIToolCall.js +42 -42
  70. package/dist/wc-react/AIToolCall.js.map +1 -1
  71. package/dist/wc-react/{sidebar.js → AppSidebar.constants.js} +89 -87
  72. package/dist/wc-react/AppSidebar.constants.js.map +1 -0
  73. package/dist/wc-react/hf-app-shell.js +383 -380
  74. package/dist/wc-react/hf-app-shell.js.map +1 -1
  75. package/dist/wc-react/hf-app-sidebar.js +72 -69
  76. package/dist/wc-react/hf-app-sidebar.js.map +1 -1
  77. package/dist/wc-react/markdown-renderer.js +1 -1
  78. package/dist/wc-react/markdown-renderer.js.map +1 -1
  79. package/package.json +1 -1
  80. package/skills/humain-ui/SKILL.md +1 -1
  81. package/skills/humain-ui-wc/SKILL.md +1 -1
  82. package/skills/humain-ui-wc.skill +0 -0
  83. package/skills/humain-ui.skill +0 -0
  84. package/dist/wc/sidebar.js.map +0 -1
  85. 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 { Badge } from "./index11.js";
4
- import { Separator } from "./index48.js";
5
- import { Avatar } from "./index72.js";
6
- import { BrandIcon } from "./index73.js";
7
- import { Tooltip, TooltipPopup, TooltipTrigger } from "./index121.js";
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 { 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
- var APP_SIDEBAR_WIDTH = "280px";
22
- var APP_SIDEBAR_COLLAPSED_WIDTH = "116px";
23
- function formatAccessibleLabel(label, badge) {
24
- if (badge == null) return label;
25
- return `${label}, ${typeof badge === "number" ? `${badge} ${badge === 1 ? "item" : "items"}` : badge}`;
26
- }
27
- function getSidebarBgClass(isCollapsed, sidebarBgColor) {
28
- return isCollapsed ? "bg-transparent" : sidebarBgColor ?? "bg-[var(--sidebar)]";
29
- }
30
- function getSidebarSurfaceClass({ isCollapsed, side, rounded, backgroundClass }) {
31
- return cn("flex h-full min-h-0 flex-col items-center pb-4 pt-6", isCollapsed ? "w-full px-6" : ["w-[calc(100%-0.75rem)] px-3", side === "left" ? "mr-3 self-start" : "ml-3 self-end"], backgroundClass, rounded && (side === "left" ? "rounded-r-lg" : "rounded-l-lg"));
32
- }
33
- function getSkeletonCount(count, fallback) {
34
- return typeof count === "number" && Number.isFinite(count) && count >= 0 ? Math.floor(count) : fallback;
35
- }
36
- var APP_SIDEBAR_IMPLICIT_SLOT = Symbol("AppSidebarImplicitSlot");
37
- function markAppSidebarImplicitSlot(component, slot) {
38
- const slottedComponent = component;
39
- slottedComponent[APP_SIDEBAR_IMPLICIT_SLOT] = slot;
40
- return slottedComponent;
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
- const container = containerRef.current;
123
- const win = container?.ownerDocument.defaultView;
124
- if (!container || !win) return;
125
- const detectDirection = () => {
126
- const nextDirection = getAppSidebarDirection(container);
127
- setDetectedDirection((current) => current === nextDirection ? current : nextDirection);
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
- detectDirection();
130
- const Observer = win.MutationObserver;
131
- if (!Observer) return;
132
- const observer = new Observer(detectDirection);
133
- for (const target of getAppSidebarDirectionTargets(container)) observer.observe(target, {
134
- attributes: true,
135
- attributeFilter: [
136
- "dir",
137
- "class",
138
- "style"
139
- ]
140
- });
141
- return () => observer.disconnect();
142
- }, [
143
- containerRef,
144
- explicitDir,
145
- explicitSide
146
- ]);
147
- return explicitSide ?? getAppSidebarSideFromDirection(detectedDirection);
148
- }
149
- var DEFAULT_COMPACTED_LOGO = /* @__PURE__ */ jsx("span", {
150
- className: "flex size-9 items-center justify-center rounded-lg bg-primary text-primary-foreground",
151
- children: /* @__PURE__ */ jsx(BrandIcon, {
152
- icon: "mark",
153
- size: "sm"
154
- })
155
- });
156
- function AppSidebarLogo({ logo, compactedLogo, subtext, className, ...props }) {
157
- const { state, toggleSidebar } = useSidebar();
158
- const isCollapsed = state === "collapsed";
159
- const effectiveCompactedLogo = compactedLogo ?? DEFAULT_COMPACTED_LOGO;
160
- if (isCollapsed) return /* @__PURE__ */ jsx("div", {
161
- "data-slot": "app-sidebar-logo",
162
- className: cn("flex items-center justify-center", className),
163
- ...props,
164
- dir: "ltr",
165
- children: /* @__PURE__ */ jsxs("button", {
166
- type: "button",
167
- onClick: toggleSidebar,
168
- className: "group/logo relative flex size-[52px] items-center justify-center rounded-md p-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",
169
- "aria-label": "Expand sidebar",
170
- children: [/* @__PURE__ */ jsx("span", {
171
- className: "transition-opacity duration-200 ease-smooth group-hover/logo:opacity-0 motion-reduce:transition-none",
172
- children: effectiveCompactedLogo
173
- }), /* @__PURE__ */ jsx(PanelLeftOpen, { className: "absolute size-5 opacity-0 transition-opacity duration-200 ease-smooth group-hover/logo:opacity-100 motion-reduce:transition-none" })]
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
- dir: "ltr",
181
- children: [/* @__PURE__ */ jsxs("div", {
182
- className: "flex min-w-0 flex-col gap-0",
183
- children: [/* @__PURE__ */ jsx("div", {
184
- className: "flex items-center gap-2",
185
- children: logo || /* @__PURE__ */ jsxs(Fragment, { children: [DEFAULT_COMPACTED_LOGO, /* @__PURE__ */ jsx("span", {
186
- className: "text-lg font-semibold tracking-tight text-foreground",
187
- children: "HUMAIN"
188
- })] })
189
- }), subtext && /* @__PURE__ */ jsx("p", {
190
- className: "text-sm text-sidebar-foreground",
191
- children: subtext
192
- })]
193
- }), /* @__PURE__ */ jsx("button", {
194
- type: "button",
195
- onClick: toggleSidebar,
196
- className: "relative flex size-9 items-center justify-center rounded-lg text-sidebar-foreground transition-colors duration-200 ease-smooth hover:bg-sidebar-accent hover:text-foreground focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring motion-reduce:transition-none after:absolute after:-inset-1",
197
- "aria-label": "Collapse sidebar",
198
- children: /* @__PURE__ */ jsx(PanelLeftClose, {
199
- "aria-hidden": "true",
200
- className: "size-5"
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
- AppSidebarLogo.displayName = "AppSidebar.Logo";
206
- function AppSidebarHeader({ children, className }) {
160
+ });
161
+ AppShellCardRoot.displayName = "AppShellCard";
162
+ function AppShellCardToolbar({ className, children, ...props }) {
207
163
  return /* @__PURE__ */ jsx("div", {
208
- "data-slot": "app-sidebar-header",
209
- className,
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
- AppSidebarHeader.displayName = "AppSidebar.Header";
214
- function AppSidebarContent({ children, className }) {
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-sidebar-content",
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
- AppSidebarContent.displayName = "AppSidebar.Content";
222
- function AppSidebarFooter({ children, className }) {
223
- return /* @__PURE__ */ jsx("div", {
224
- "data-slot": "app-sidebar-footer",
225
- className,
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
- AppSidebarFooter.displayName = "AppSidebar.Footer";
230
- function AppSidebarNav({ children, "aria-label": ariaLabel = "Sidebar navigation", className }) {
231
- const menuContent = /* @__PURE__ */ jsx(SidebarMenu, {
232
- className: "gap-0.5 group-data-[collapsible=icon]:items-center group-data-[collapsible=icon]:gap-1",
233
- children: React$1.Children.map(children, (child) => /* @__PURE__ */ jsx(SidebarMenuItem, { children: child }))
234
- });
235
- return /* @__PURE__ */ jsx(SidebarGroup, {
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
- AppSidebarNavSkeleton.displayName = "AppSidebar.NavSkeleton";
481
- markAppSidebarImplicitSlot(AppSidebarNavSkeleton, "content");
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
- role: "listitem",
546
- children: /* @__PURE__ */ jsxs("button", {
547
- type: "button",
548
- onClick,
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
- AppSidebarRoot.displayName = "AppSidebar";
765
- var AppSidebar = Object.assign(AppSidebarRoot, {
766
- Header: AppSidebarHeader,
767
- Content: AppSidebarContent,
768
- Footer: AppSidebarFooter,
769
- Nav: AppSidebarNav,
770
- NavSection: AppSidebarNavSection,
771
- NavItem: AppSidebarNavItem,
772
- NavSub: AppSidebarNavSub,
773
- NavSkeleton: AppSidebarNavSkeleton,
774
- ChatList: AppSidebarChatList,
775
- ChatItem: AppSidebarChatItem,
776
- ChatListSkeleton: AppSidebarChatListSkeleton,
777
- Account: AppSidebarAccount,
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 { 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 };
227
+ export { AppShellCard, AppShellCardActions, AppShellCardHeader, AppShellCardMenu, AppShellCardRoot, AppShellCardSubtitle, AppShellCardTitle, AppShellCardToolbar };
783
228
 
784
229
  //# sourceMappingURL=index224.js.map