harebear-ui 0.3.0 → 0.5.0
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/admin/app-shell.d.ts +12 -5
- package/dist/components/admin/app-shell.js +51 -55
- package/dist/components/admin/sidebar-layout.d.ts +41 -0
- package/dist/components/admin/sidebar-layout.js +104 -0
- package/dist/components/admin/user-menu.d.ts +22 -0
- package/dist/components/admin/user-menu.js +82 -0
- package/dist/components/ai/chat-shell.d.ts +7 -4
- package/dist/components/ai/chat-shell.js +36 -105
- package/dist/index.d.ts +3 -1
- package/dist/index.js +3 -1
- package/docs/COMPONENTS.md +36 -5
- package/llms.txt +1 -1
- package/package.json +1 -1
- package/skills/harebear-ui/SKILL.md +2 -2
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { SidebarLayoutProps } from "./sidebar-layout.js";
|
|
1
2
|
import * as React from "react";
|
|
2
3
|
export interface AppNavItem {
|
|
3
4
|
label: string;
|
|
@@ -29,22 +30,28 @@ declare function AppBrand({ name, subtitle, icon, action, className, ...props }:
|
|
|
29
30
|
export interface AppShellProps {
|
|
30
31
|
/** Sidebar header content, usually <AppBrand />. */
|
|
31
32
|
brand?: React.ReactNode;
|
|
33
|
+
/** Under the brand, e.g. a primary "New" button. */
|
|
34
|
+
sidebarActions?: React.ReactNode;
|
|
32
35
|
nav?: AppNavSection[];
|
|
33
|
-
/** Extra sidebar content under the nav (e.g. a usage card). */
|
|
36
|
+
/** Extra sidebar content under the nav (e.g. a usage card). Hidden in the icon rail. */
|
|
34
37
|
sidebarExtra?: React.ReactNode;
|
|
35
|
-
/** Sidebar bottom content, usually <
|
|
38
|
+
/** Sidebar bottom content, usually <UserMenu />. */
|
|
36
39
|
sidebarFooter?: React.ReactNode;
|
|
37
40
|
/** Top bar content inside the main area (search, actions). */
|
|
38
41
|
header?: React.ReactNode;
|
|
39
42
|
/** Component used for nav links. Default "a". Pass Next.js Link or React Router Link. */
|
|
40
43
|
linkComponent?: React.ElementType;
|
|
44
|
+
/** How the sidebar collapses on desktop. Default "icon": a collapse button shrinks it to an icon rail. */
|
|
45
|
+
collapsible?: SidebarLayoutProps["collapsible"];
|
|
46
|
+
/** Remember the sidebar's expanded or collapsed state in localStorage under this key. */
|
|
47
|
+
storageKey?: string;
|
|
41
48
|
defaultOpen?: boolean;
|
|
42
49
|
className?: string;
|
|
43
50
|
children?: React.ReactNode;
|
|
44
51
|
}
|
|
45
52
|
/**
|
|
46
|
-
* Full admin layout:
|
|
47
|
-
*
|
|
53
|
+
* Full admin layout on SidebarLayout: nav sidebar that collapses to an icon rail (a sheet on mobile) + main column.
|
|
54
|
+
* Nav items show their label as a tooltip in the rail. Drop to SidebarLayout or the Sidebar primitives for anything custom.
|
|
48
55
|
*/
|
|
49
|
-
declare function AppShell({ brand, nav, sidebarExtra, sidebarFooter, header, linkComponent: Link, defaultOpen, className, children }: AppShellProps): React.JSX.Element;
|
|
56
|
+
declare function AppShell({ brand, sidebarActions, nav, sidebarExtra, sidebarFooter, header, linkComponent: Link, collapsible, storageKey, defaultOpen, className, children }: AppShellProps): React.JSX.Element;
|
|
50
57
|
export { AppBrand, AppShell };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
|
+
import { SidebarLayout } from "./sidebar-layout.js";
|
|
2
3
|
import { Badge } from "../ui/badge.js";
|
|
3
|
-
import {
|
|
4
|
+
import { SidebarGroup, SidebarGroupLabel, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarTrigger } from "../ui/sidebar.js";
|
|
4
5
|
import { cn } from "../../lib/utils.js";
|
|
5
6
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
6
7
|
// src/components/admin/app-shell.tsx
|
|
@@ -36,75 +37,70 @@ function AppBrand({ name, subtitle, icon, action, className, ...props }) {
|
|
|
36
37
|
});
|
|
37
38
|
}
|
|
38
39
|
/**
|
|
39
|
-
* Full admin layout:
|
|
40
|
-
*
|
|
40
|
+
* Full admin layout on SidebarLayout: nav sidebar that collapses to an icon rail (a sheet on mobile) + main column.
|
|
41
|
+
* Nav items show their label as a tooltip in the rail. Drop to SidebarLayout or the Sidebar primitives for anything custom.
|
|
41
42
|
*/
|
|
42
|
-
function AppShell({ brand, nav = [], sidebarExtra, sidebarFooter, header, linkComponent: Link = "a", defaultOpen = true, className, children }) {
|
|
43
|
-
return /* @__PURE__ */ jsxs(
|
|
43
|
+
function AppShell({ brand, sidebarActions, nav = [], sidebarExtra, sidebarFooter, header, linkComponent: Link = "a", collapsible, storageKey, defaultOpen = true, className, children }) {
|
|
44
|
+
return /* @__PURE__ */ jsxs(SidebarLayout, {
|
|
45
|
+
brand,
|
|
46
|
+
sidebarActions,
|
|
47
|
+
sidebarFooter,
|
|
48
|
+
collapsible,
|
|
49
|
+
storageKey,
|
|
44
50
|
defaultOpen,
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
children: item.href ? /* @__PURE__ */ jsxs(Link, {
|
|
63
|
-
href: item.href,
|
|
64
|
-
children: [
|
|
65
|
-
item.icon,
|
|
66
|
-
/* @__PURE__ */ jsx("span", {
|
|
67
|
-
className: "flex-1",
|
|
68
|
-
children: item.label
|
|
69
|
-
}),
|
|
70
|
-
item.badge !== void 0 && /* @__PURE__ */ jsx(NavBadge, { children: item.badge })
|
|
71
|
-
]
|
|
72
|
-
}) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
51
|
+
width: "15.75rem",
|
|
52
|
+
className,
|
|
53
|
+
sidebar: /* @__PURE__ */ jsxs("div", {
|
|
54
|
+
className: "flex flex-1 flex-col gap-5",
|
|
55
|
+
children: [nav.map((section, i) => /* @__PURE__ */ jsxs(SidebarGroup, { children: [section.label && /* @__PURE__ */ jsx(SidebarGroupLabel, {
|
|
56
|
+
className: "text-xs font-medium",
|
|
57
|
+
children: section.label
|
|
58
|
+
}), /* @__PURE__ */ jsx(SidebarMenu, {
|
|
59
|
+
className: "gap-1 group-data-[collapsible=icon]:items-center",
|
|
60
|
+
children: section.items.map((item) => /* @__PURE__ */ jsx(SidebarMenuItem, { children: /* @__PURE__ */ jsx(SidebarMenuButton, {
|
|
61
|
+
asChild: !!item.href,
|
|
62
|
+
isActive: item.active,
|
|
63
|
+
onClick: item.onSelect,
|
|
64
|
+
tooltip: item.label,
|
|
65
|
+
children: item.href ? /* @__PURE__ */ jsxs(Link, {
|
|
66
|
+
href: item.href,
|
|
67
|
+
children: [
|
|
73
68
|
item.icon,
|
|
74
69
|
/* @__PURE__ */ jsx("span", {
|
|
75
70
|
className: "flex-1",
|
|
76
71
|
children: item.label
|
|
77
72
|
}),
|
|
78
73
|
item.badge !== void 0 && /* @__PURE__ */ jsx(NavBadge, { children: item.badge })
|
|
79
|
-
]
|
|
80
|
-
})
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
})
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
children: [header !== void 0 && /* @__PURE__ */ jsxs("header", {
|
|
93
|
-
"data-slot": "app-header",
|
|
94
|
-
className: "flex flex-wrap items-center gap-3 px-4 pt-5 md:px-8",
|
|
95
|
-
children: [/* @__PURE__ */ jsx(SidebarTrigger, { className: "md:hidden" }), header]
|
|
96
|
-
}), /* @__PURE__ */ jsx("div", {
|
|
97
|
-
"data-slot": "app-content",
|
|
98
|
-
className: "flex min-w-0 flex-col gap-7 px-4 pt-7 pb-12 md:px-8",
|
|
99
|
-
children
|
|
74
|
+
]
|
|
75
|
+
}) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
76
|
+
item.icon,
|
|
77
|
+
/* @__PURE__ */ jsx("span", {
|
|
78
|
+
className: "flex-1",
|
|
79
|
+
children: item.label
|
|
80
|
+
}),
|
|
81
|
+
item.badge !== void 0 && /* @__PURE__ */ jsx(NavBadge, { children: item.badge })
|
|
82
|
+
] })
|
|
83
|
+
}) }, item.label))
|
|
84
|
+
})] }, section.label ?? i)), sidebarExtra && /* @__PURE__ */ jsx("div", {
|
|
85
|
+
className: "mt-auto px-2 group-data-[collapsible=icon]:hidden",
|
|
86
|
+
children: sidebarExtra
|
|
100
87
|
})]
|
|
88
|
+
}),
|
|
89
|
+
children: [header !== void 0 && /* @__PURE__ */ jsxs("header", {
|
|
90
|
+
"data-slot": "app-header",
|
|
91
|
+
className: "flex flex-wrap items-center gap-3 px-4 pt-5 md:px-8",
|
|
92
|
+
children: [/* @__PURE__ */ jsx(SidebarTrigger, { className: "md:hidden" }), header]
|
|
93
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
94
|
+
"data-slot": "app-content",
|
|
95
|
+
className: "flex min-w-0 flex-col gap-7 px-4 pt-7 pb-12 md:px-8",
|
|
96
|
+
children
|
|
101
97
|
})]
|
|
102
98
|
});
|
|
103
99
|
}
|
|
104
100
|
function NavBadge({ children }) {
|
|
105
101
|
return /* @__PURE__ */ jsx(Badge, {
|
|
106
102
|
variant: "soft",
|
|
107
|
-
className: "h-5 px-2",
|
|
103
|
+
className: "h-5 px-2 group-data-[collapsible=icon]:hidden",
|
|
108
104
|
children
|
|
109
105
|
});
|
|
110
106
|
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
export interface SidebarLayoutProps {
|
|
3
|
+
/** Sidebar top, usually <AppBrand />. Collapses to its logo tile in the icon rail. */
|
|
4
|
+
brand?: React.ReactNode;
|
|
5
|
+
/** Under the brand, e.g. <NewConversationButton /> or a search box. Should cope with the icon rail. */
|
|
6
|
+
sidebarActions?: React.ReactNode;
|
|
7
|
+
/** Scrolling sidebar body: nav menus, <ConversationList />… */
|
|
8
|
+
sidebar?: React.ReactNode;
|
|
9
|
+
/** Sidebar bottom, usually <UserMenu />. */
|
|
10
|
+
sidebarFooter?: React.ReactNode;
|
|
11
|
+
/**
|
|
12
|
+
* - "icon" (default): a collapse button shrinks the sidebar to an icon rail on desktop.
|
|
13
|
+
* - "offcanvas": the sidebar can be hidden entirely (toggle it with a SidebarTrigger).
|
|
14
|
+
* - "none": always expanded on desktop.
|
|
15
|
+
* On mobile the sidebar is always a sheet opened with a SidebarTrigger.
|
|
16
|
+
*/
|
|
17
|
+
collapsible?: "icon" | "offcanvas" | "none";
|
|
18
|
+
/** Remember the expanded or collapsed state in localStorage under this key. */
|
|
19
|
+
storageKey?: string;
|
|
20
|
+
/** Expanded at first (when nothing is stored). Default true. */
|
|
21
|
+
defaultOpen?: boolean;
|
|
22
|
+
/** Expanded sidebar width. Default "16rem". The icon rail is 4.25rem. */
|
|
23
|
+
width?: string;
|
|
24
|
+
/** Classes for the main column (a SidebarInset). */
|
|
25
|
+
className?: string;
|
|
26
|
+
/** The main column. */
|
|
27
|
+
children?: React.ReactNode;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* The base app layout: a sidebar (brand, actions, body, footer) that collapses to an icon rail on desktop and is a
|
|
31
|
+
* sheet on mobile, next to the main column. AppShell and ChatShell are built on it; use it directly for other layouts.
|
|
32
|
+
*/
|
|
33
|
+
declare function SidebarLayout({ brand, sidebarActions, sidebar, sidebarFooter, collapsible, storageKey, defaultOpen, width, className, children }: SidebarLayoutProps): React.JSX.Element;
|
|
34
|
+
/**
|
|
35
|
+
* Collapse / expand control for a desktop sidebar with an icon rail, with a tooltip. Renders nothing on mobile,
|
|
36
|
+
* where the sidebar is a sheet. SidebarLayout includes one; use it in custom Sidebar layouts.
|
|
37
|
+
*/
|
|
38
|
+
declare function SidebarCollapseButton({ className }: {
|
|
39
|
+
className?: string;
|
|
40
|
+
}): React.JSX.Element | null;
|
|
41
|
+
export { SidebarCollapseButton, SidebarLayout };
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Button } from "../ui/button.js";
|
|
3
|
+
import { Sidebar, SidebarContent, SidebarFooter, SidebarHeader, SidebarInset, SidebarProvider, useSidebar } from "../ui/sidebar.js";
|
|
4
|
+
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "../ui/tooltip.js";
|
|
5
|
+
import { cn } from "../../lib/utils.js";
|
|
6
|
+
import * as React from "react";
|
|
7
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
import { PanelLeftCloseIcon, PanelLeftOpenIcon } from "lucide-react";
|
|
9
|
+
// src/components/admin/sidebar-layout.tsx
|
|
10
|
+
function readStored(key) {
|
|
11
|
+
try {
|
|
12
|
+
const v = window.localStorage.getItem(key);
|
|
13
|
+
return v === null ? null : v !== "collapsed";
|
|
14
|
+
} catch {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
const useIsomorphicLayoutEffect = typeof window === "undefined" ? React.useEffect : React.useLayoutEffect;
|
|
19
|
+
/**
|
|
20
|
+
* The base app layout: a sidebar (brand, actions, body, footer) that collapses to an icon rail on desktop and is a
|
|
21
|
+
* sheet on mobile, next to the main column. AppShell and ChatShell are built on it; use it directly for other layouts.
|
|
22
|
+
*/
|
|
23
|
+
function SidebarLayout({ brand, sidebarActions, sidebar, sidebarFooter, collapsible = "icon", storageKey, defaultOpen = true, width = "16rem", className, children }) {
|
|
24
|
+
const [open, setOpen] = React.useState(defaultOpen);
|
|
25
|
+
useIsomorphicLayoutEffect(() => {
|
|
26
|
+
if (!storageKey) return;
|
|
27
|
+
const stored = readStored(storageKey);
|
|
28
|
+
if (stored !== null) setOpen(stored);
|
|
29
|
+
}, [storageKey]);
|
|
30
|
+
const onOpenChange = (next) => {
|
|
31
|
+
setOpen(next);
|
|
32
|
+
if (!storageKey) return;
|
|
33
|
+
try {
|
|
34
|
+
window.localStorage.setItem(storageKey, next ? "open" : "collapsed");
|
|
35
|
+
} catch {}
|
|
36
|
+
};
|
|
37
|
+
return /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs(SidebarProvider, {
|
|
38
|
+
open: collapsible === "none" ? true : open,
|
|
39
|
+
onOpenChange,
|
|
40
|
+
style: {
|
|
41
|
+
"--sidebar-width": width,
|
|
42
|
+
"--sidebar-width-icon": "4.25rem"
|
|
43
|
+
},
|
|
44
|
+
children: [/* @__PURE__ */ jsxs(Sidebar, {
|
|
45
|
+
collapsible: collapsible === "none" ? "offcanvas" : collapsible,
|
|
46
|
+
"data-slot": "sidebar-layout-sidebar",
|
|
47
|
+
children: [
|
|
48
|
+
/* @__PURE__ */ jsxs(SidebarHeader, {
|
|
49
|
+
className: "gap-5 px-3.5 pt-[max(1.25rem,env(safe-area-inset-top))] group-data-[collapsible=icon]:items-center group-data-[collapsible=icon]:gap-3 group-data-[collapsible=icon]:px-0",
|
|
50
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
51
|
+
className: "flex min-w-0 items-center gap-2 group-data-[collapsible=icon]:flex-col group-data-[collapsible=icon]:gap-3",
|
|
52
|
+
children: [brand && /* @__PURE__ */ jsx("div", {
|
|
53
|
+
className: "min-w-0 flex-1 pl-2 group-data-[collapsible=icon]:pl-0",
|
|
54
|
+
children: brand
|
|
55
|
+
}), collapsible === "icon" && /* @__PURE__ */ jsx(SidebarCollapseButton, {})]
|
|
56
|
+
}), sidebarActions && /* @__PURE__ */ jsx("div", {
|
|
57
|
+
className: "flex flex-col gap-2.5 group-data-[collapsible=icon]:items-center",
|
|
58
|
+
children: sidebarActions
|
|
59
|
+
})]
|
|
60
|
+
}),
|
|
61
|
+
/* @__PURE__ */ jsx(SidebarContent, {
|
|
62
|
+
className: "px-3.5 pt-2 group-data-[collapsible=icon]:px-0",
|
|
63
|
+
children: sidebar
|
|
64
|
+
}),
|
|
65
|
+
sidebarFooter && /* @__PURE__ */ jsx(SidebarFooter, {
|
|
66
|
+
className: "px-3.5 pb-[max(1.25rem,env(safe-area-inset-bottom))] group-data-[collapsible=icon]:px-0",
|
|
67
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
68
|
+
className: "px-2 group-data-[collapsible=icon]:px-0 has-data-[slot=user-menu-trigger]:px-0",
|
|
69
|
+
children: sidebarFooter
|
|
70
|
+
})
|
|
71
|
+
})
|
|
72
|
+
]
|
|
73
|
+
}), /* @__PURE__ */ jsx(SidebarInset, {
|
|
74
|
+
"data-slot": "sidebar-layout",
|
|
75
|
+
className: cn("min-w-0", className),
|
|
76
|
+
children
|
|
77
|
+
})]
|
|
78
|
+
}) });
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Collapse / expand control for a desktop sidebar with an icon rail, with a tooltip. Renders nothing on mobile,
|
|
82
|
+
* where the sidebar is a sheet. SidebarLayout includes one; use it in custom Sidebar layouts.
|
|
83
|
+
*/
|
|
84
|
+
function SidebarCollapseButton({ className }) {
|
|
85
|
+
const { state, isMobile, toggleSidebar } = useSidebar();
|
|
86
|
+
if (isMobile) return null;
|
|
87
|
+
const label = state === "collapsed" ? "Expand sidebar" : "Collapse sidebar";
|
|
88
|
+
return /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
|
|
89
|
+
asChild: true,
|
|
90
|
+
children: /* @__PURE__ */ jsx(Button, {
|
|
91
|
+
"data-slot": "sidebar-collapse-button",
|
|
92
|
+
variant: "ghost",
|
|
93
|
+
size: state === "collapsed" ? "icon" : "icon-sm",
|
|
94
|
+
"aria-label": label,
|
|
95
|
+
onClick: toggleSidebar,
|
|
96
|
+
className,
|
|
97
|
+
children: state === "collapsed" ? /* @__PURE__ */ jsx(PanelLeftOpenIcon, {}) : /* @__PURE__ */ jsx(PanelLeftCloseIcon, {})
|
|
98
|
+
})
|
|
99
|
+
}), /* @__PURE__ */ jsx(TooltipContent, {
|
|
100
|
+
side: "right",
|
|
101
|
+
children: label
|
|
102
|
+
})] });
|
|
103
|
+
}
|
|
104
|
+
export { SidebarCollapseButton, SidebarLayout };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
export interface UserMenuProps {
|
|
3
|
+
name: string;
|
|
4
|
+
/** Second line, e.g. the email or "Signed in". */
|
|
5
|
+
subtitle?: React.ReactNode;
|
|
6
|
+
avatarUrl?: string;
|
|
7
|
+
/** Extra items between the header and the theme choice, e.g. a Settings DropdownMenuItem. */
|
|
8
|
+
children?: React.ReactNode;
|
|
9
|
+
/** Show the Light / Dark / System choice. Default true. Needs ThemeProvider. */
|
|
10
|
+
themeSwitch?: boolean;
|
|
11
|
+
/** Adds a Sign out item at the bottom. */
|
|
12
|
+
onSignOut?: () => void;
|
|
13
|
+
/** Default "Sign out". */
|
|
14
|
+
signOutLabel?: React.ReactNode;
|
|
15
|
+
className?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* The signed-in user as a menu button, for a sidebar footer or top bar: theme choice, app items such as
|
|
19
|
+
* Settings, and sign out. In a sidebar icon rail the trigger is just the avatar and the menu opens to the side.
|
|
20
|
+
*/
|
|
21
|
+
declare function UserMenu({ name, subtitle, avatarUrl, children, themeSwitch, onSignOut, signOutLabel, className }: UserMenuProps): React.JSX.Element;
|
|
22
|
+
export { UserMenu };
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { UserChip } from "./user-chip.js";
|
|
3
|
+
import { useTheme } from "../theme/theme-provider.js";
|
|
4
|
+
import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuTrigger } from "../ui/dropdown-menu.js";
|
|
5
|
+
import { useSidebarOptional } from "../ui/sidebar.js";
|
|
6
|
+
import { cn } from "../../lib/utils.js";
|
|
7
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
import { ChevronsUpDownIcon, LogOutIcon, MonitorIcon, MoonIcon, SunIcon } from "lucide-react";
|
|
9
|
+
// src/components/admin/user-menu.tsx
|
|
10
|
+
const themes = [
|
|
11
|
+
{
|
|
12
|
+
mode: "light",
|
|
13
|
+
label: "Light",
|
|
14
|
+
icon: /* @__PURE__ */ jsx(SunIcon, {})
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
mode: "dark",
|
|
18
|
+
label: "Dark",
|
|
19
|
+
icon: /* @__PURE__ */ jsx(MoonIcon, {})
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
mode: "system",
|
|
23
|
+
label: "System",
|
|
24
|
+
icon: /* @__PURE__ */ jsx(MonitorIcon, {})
|
|
25
|
+
}
|
|
26
|
+
];
|
|
27
|
+
/**
|
|
28
|
+
* The signed-in user as a menu button, for a sidebar footer or top bar: theme choice, app items such as
|
|
29
|
+
* Settings, and sign out. In a sidebar icon rail the trigger is just the avatar and the menu opens to the side.
|
|
30
|
+
*/
|
|
31
|
+
function UserMenu({ name, subtitle, avatarUrl, children, themeSwitch = true, onSignOut, signOutLabel = "Sign out", className }) {
|
|
32
|
+
const { mode, setMode } = useTheme();
|
|
33
|
+
const sidebar = useSidebarOptional();
|
|
34
|
+
const rail = sidebar?.state === "collapsed" && !sidebar.isMobile;
|
|
35
|
+
return /* @__PURE__ */ jsxs(DropdownMenu, { children: [/* @__PURE__ */ jsxs(DropdownMenuTrigger, {
|
|
36
|
+
"data-slot": "user-menu-trigger",
|
|
37
|
+
"aria-label": `Account menu for ${name}`,
|
|
38
|
+
className: cn("flex w-full min-w-0 items-center gap-2 rounded-lg px-2 py-1.5 text-left transition-colors outline-none hover:bg-muted focus-visible:ring-2 focus-visible:ring-ring/40 data-[state=open]:bg-muted group-data-[collapsible=icon]:mx-auto group-data-[collapsible=icon]:size-10 group-data-[collapsible=icon]:justify-center group-data-[collapsible=icon]:rounded-full group-data-[collapsible=icon]:p-0", className),
|
|
39
|
+
children: [/* @__PURE__ */ jsx(UserChip, {
|
|
40
|
+
name,
|
|
41
|
+
subtitle,
|
|
42
|
+
avatarUrl,
|
|
43
|
+
className: "flex-1"
|
|
44
|
+
}), /* @__PURE__ */ jsx(ChevronsUpDownIcon, { className: "size-4 shrink-0 text-muted-foreground group-data-[collapsible=icon]:hidden" })]
|
|
45
|
+
}), /* @__PURE__ */ jsxs(DropdownMenuContent, {
|
|
46
|
+
"data-slot": "user-menu",
|
|
47
|
+
side: rail ? "right" : "top",
|
|
48
|
+
align: rail ? "end" : "start",
|
|
49
|
+
className: "w-(--radix-dropdown-menu-trigger-width) min-w-60",
|
|
50
|
+
children: [
|
|
51
|
+
/* @__PURE__ */ jsxs(DropdownMenuLabel, {
|
|
52
|
+
className: "flex min-w-0 flex-col font-normal",
|
|
53
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
54
|
+
className: "truncate font-medium text-foreground",
|
|
55
|
+
children: name
|
|
56
|
+
}), subtitle && /* @__PURE__ */ jsx("span", {
|
|
57
|
+
className: "truncate text-xs text-muted-foreground",
|
|
58
|
+
children: subtitle
|
|
59
|
+
})]
|
|
60
|
+
}),
|
|
61
|
+
children && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(DropdownMenuSeparator, {}), /* @__PURE__ */ jsx(DropdownMenuGroup, { children })] }),
|
|
62
|
+
themeSwitch && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
63
|
+
/* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
|
|
64
|
+
/* @__PURE__ */ jsx(DropdownMenuLabel, { children: "Theme" }),
|
|
65
|
+
/* @__PURE__ */ jsx(DropdownMenuRadioGroup, {
|
|
66
|
+
value: mode,
|
|
67
|
+
onValueChange: (v) => setMode(v),
|
|
68
|
+
children: themes.map((t) => /* @__PURE__ */ jsxs(DropdownMenuRadioItem, {
|
|
69
|
+
value: t.mode,
|
|
70
|
+
onSelect: (e) => e.preventDefault(),
|
|
71
|
+
children: [t.icon, t.label]
|
|
72
|
+
}, t.mode))
|
|
73
|
+
})
|
|
74
|
+
] }),
|
|
75
|
+
onSignOut && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(DropdownMenuSeparator, {}), /* @__PURE__ */ jsxs(DropdownMenuItem, {
|
|
76
|
+
onSelect: onSignOut,
|
|
77
|
+
children: [/* @__PURE__ */ jsx(LogOutIcon, {}), signOutLabel]
|
|
78
|
+
})] })
|
|
79
|
+
]
|
|
80
|
+
})] });
|
|
81
|
+
}
|
|
82
|
+
export { UserMenu };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { SidebarLayoutProps } from "../admin/sidebar-layout.js";
|
|
1
2
|
import * as React from "react";
|
|
2
3
|
export interface ChatShellProps {
|
|
3
4
|
/** Sidebar top, usually <AppBrand />. Collapses to its logo tile in the icon rail. */
|
|
@@ -6,7 +7,7 @@ export interface ChatShellProps {
|
|
|
6
7
|
sidebarActions?: React.ReactNode;
|
|
7
8
|
/** Scrolling sidebar body, usually <ConversationList />. Hidden in the icon rail. */
|
|
8
9
|
sidebar?: React.ReactNode;
|
|
9
|
-
/** Sidebar bottom, usually <UserChip /> with a ThemeToggle as its action. */
|
|
10
|
+
/** Sidebar bottom, usually <UserMenu /> (or a <UserChip /> with a ThemeToggle as its action). */
|
|
10
11
|
sidebarFooter?: React.ReactNode;
|
|
11
12
|
/** Right-hand panel, e.g. Cards with details about the open conversation. Inline at 1280px and up, a sheet below. */
|
|
12
13
|
details?: React.ReactNode;
|
|
@@ -14,6 +15,8 @@ export interface ChatShellProps {
|
|
|
14
15
|
detailsTitle?: string;
|
|
15
16
|
/** Show the details panel at first on wide screens. Default true. */
|
|
16
17
|
defaultDetailsOpen?: boolean;
|
|
18
|
+
/** How the sidebar collapses on desktop. Default "icon" (an icon rail). See SidebarLayout. */
|
|
19
|
+
collapsible?: SidebarLayoutProps["collapsible"];
|
|
17
20
|
/** Remember the sidebar's expanded or collapsed state in localStorage under this key. */
|
|
18
21
|
storageKey?: string;
|
|
19
22
|
/** Sidebar expanded at first (when nothing is stored). Default true. */
|
|
@@ -23,10 +26,10 @@ export interface ChatShellProps {
|
|
|
23
26
|
children: React.ReactNode;
|
|
24
27
|
}
|
|
25
28
|
/**
|
|
26
|
-
* Full-height chat app layout:
|
|
27
|
-
* column,
|
|
29
|
+
* Full-height chat app layout: SidebarLayout (sidebar with an icon rail, a sheet on mobile) around the chat
|
|
30
|
+
* column, plus an optional details panel. Put a ChatPanel inside.
|
|
28
31
|
*/
|
|
29
|
-
declare function ChatShell({ brand, sidebarActions, sidebar, sidebarFooter, details, detailsTitle, defaultDetailsOpen, storageKey, defaultOpen, className, children }: ChatShellProps): React.JSX.Element;
|
|
32
|
+
declare function ChatShell({ brand, sidebarActions, sidebar, sidebarFooter, details, detailsTitle, defaultDetailsOpen, collapsible, storageKey, defaultOpen, className, children }: ChatShellProps): React.JSX.Element;
|
|
30
33
|
export interface ChatPanelProps extends Omit<React.ComponentProps<"section">, "title"> {
|
|
31
34
|
/** Conversation title. */
|
|
32
35
|
title?: React.ReactNode;
|
|
@@ -1,45 +1,23 @@
|
|
|
1
1
|
"use client";
|
|
2
|
+
import { SidebarLayout } from "../admin/sidebar-layout.js";
|
|
2
3
|
import { ChatThread } from "./chat.js";
|
|
3
4
|
import { Alert, AlertDescription } from "../ui/alert.js";
|
|
4
5
|
import { Button } from "../ui/button.js";
|
|
5
6
|
import { Sheet, SheetContent, SheetHeader, SheetTitle } from "../ui/sheet.js";
|
|
6
|
-
import {
|
|
7
|
-
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "../ui/tooltip.js";
|
|
7
|
+
import { SidebarTrigger, useSidebarOptional } from "../ui/sidebar.js";
|
|
8
8
|
import { useMediaQuery } from "../../hooks/use-media-query.js";
|
|
9
9
|
import { cn } from "../../lib/utils.js";
|
|
10
10
|
import * as React from "react";
|
|
11
11
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
12
|
-
import {
|
|
12
|
+
import { PanelRightIcon, TriangleAlertIcon } from "lucide-react";
|
|
13
13
|
// src/components/ai/chat-shell.tsx
|
|
14
14
|
const WIDE = "(min-width: 1280px)";
|
|
15
15
|
const ChatShellContext = React.createContext(null);
|
|
16
|
-
function readStored(key) {
|
|
17
|
-
try {
|
|
18
|
-
const v = window.localStorage.getItem(key);
|
|
19
|
-
return v === null ? null : v !== "collapsed";
|
|
20
|
-
} catch {
|
|
21
|
-
return null;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
const useIsomorphicLayoutEffect = typeof window === "undefined" ? React.useEffect : React.useLayoutEffect;
|
|
25
16
|
/**
|
|
26
|
-
* Full-height chat app layout:
|
|
27
|
-
* column,
|
|
17
|
+
* Full-height chat app layout: SidebarLayout (sidebar with an icon rail, a sheet on mobile) around the chat
|
|
18
|
+
* column, plus an optional details panel. Put a ChatPanel inside.
|
|
28
19
|
*/
|
|
29
|
-
function ChatShell({ brand, sidebarActions, sidebar, sidebarFooter, details, detailsTitle = "Details", defaultDetailsOpen = true, storageKey, defaultOpen = true, className, children }) {
|
|
30
|
-
const [open, setOpen] = React.useState(defaultOpen);
|
|
31
|
-
useIsomorphicLayoutEffect(() => {
|
|
32
|
-
if (!storageKey) return;
|
|
33
|
-
const stored = readStored(storageKey);
|
|
34
|
-
if (stored !== null) setOpen(stored);
|
|
35
|
-
}, [storageKey]);
|
|
36
|
-
const onOpenChange = (next) => {
|
|
37
|
-
setOpen(next);
|
|
38
|
-
if (!storageKey) return;
|
|
39
|
-
try {
|
|
40
|
-
window.localStorage.setItem(storageKey, next ? "open" : "collapsed");
|
|
41
|
-
} catch {}
|
|
42
|
-
};
|
|
20
|
+
function ChatShell({ brand, sidebarActions, sidebar, sidebarFooter, details, detailsTitle = "Details", defaultDetailsOpen = true, collapsible, storageKey, defaultOpen = true, className, children }) {
|
|
43
21
|
const wide = useMediaQuery(WIDE);
|
|
44
22
|
const [inline, setInline] = React.useState(defaultDetailsOpen);
|
|
45
23
|
const [sheet, setSheet] = React.useState(false);
|
|
@@ -55,90 +33,43 @@ function ChatShell({ brand, sidebarActions, sidebar, sidebarFooter, details, det
|
|
|
55
33
|
inline,
|
|
56
34
|
sheet
|
|
57
35
|
]);
|
|
58
|
-
return /* @__PURE__ */ jsx(
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
36
|
+
return /* @__PURE__ */ jsx(SidebarLayout, {
|
|
37
|
+
brand,
|
|
38
|
+
sidebarActions,
|
|
39
|
+
sidebar,
|
|
40
|
+
sidebarFooter,
|
|
41
|
+
collapsible,
|
|
42
|
+
storageKey,
|
|
43
|
+
defaultOpen,
|
|
44
|
+
width: "17rem",
|
|
45
|
+
className: cn("h-dvh overflow-hidden", className),
|
|
65
46
|
children: /* @__PURE__ */ jsxs(ChatShellContext.Provider, {
|
|
66
47
|
value: ctx,
|
|
67
|
-
children: [/* @__PURE__ */ jsxs(
|
|
68
|
-
collapsible: "icon",
|
|
69
|
-
children: [
|
|
70
|
-
/* @__PURE__ */ jsxs(SidebarHeader, {
|
|
71
|
-
className: "gap-5 px-3.5 pt-[max(1.25rem,env(safe-area-inset-top))] group-data-[collapsible=icon]:items-center group-data-[collapsible=icon]:gap-3 group-data-[collapsible=icon]:px-0",
|
|
72
|
-
children: [/* @__PURE__ */ jsxs("div", {
|
|
73
|
-
className: "flex min-w-0 items-center gap-2 group-data-[collapsible=icon]:flex-col group-data-[collapsible=icon]:gap-3",
|
|
74
|
-
children: [brand && /* @__PURE__ */ jsx("div", {
|
|
75
|
-
className: "min-w-0 flex-1 pl-2 group-data-[collapsible=icon]:pl-0",
|
|
76
|
-
children: brand
|
|
77
|
-
}), /* @__PURE__ */ jsx(SidebarCollapseButton, {})]
|
|
78
|
-
}), sidebarActions && /* @__PURE__ */ jsx("div", {
|
|
79
|
-
className: "flex flex-col gap-2.5 group-data-[collapsible=icon]:items-center",
|
|
80
|
-
children: sidebarActions
|
|
81
|
-
})]
|
|
82
|
-
}),
|
|
83
|
-
/* @__PURE__ */ jsx(SidebarContent, {
|
|
84
|
-
className: "px-3.5 pt-2",
|
|
85
|
-
children: sidebar
|
|
86
|
-
}),
|
|
87
|
-
sidebarFooter && /* @__PURE__ */ jsx(SidebarFooter, {
|
|
88
|
-
className: "px-3.5 pb-[max(1.25rem,env(safe-area-inset-bottom))] group-data-[collapsible=icon]:px-0",
|
|
89
|
-
children: /* @__PURE__ */ jsx("div", {
|
|
90
|
-
className: "px-2 group-data-[collapsible=icon]:px-0",
|
|
91
|
-
children: sidebarFooter
|
|
92
|
-
})
|
|
93
|
-
})
|
|
94
|
-
]
|
|
95
|
-
}), /* @__PURE__ */ jsxs(SidebarInset, {
|
|
48
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
96
49
|
"data-slot": "chat-shell",
|
|
97
|
-
className:
|
|
98
|
-
children: [/* @__PURE__ */
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
50
|
+
className: "flex h-full min-h-0 gap-3 p-2 sm:p-3 md:pl-0",
|
|
51
|
+
children: [children, hasDetails && wide && inline && /* @__PURE__ */ jsx("aside", {
|
|
52
|
+
"data-slot": "chat-shell-details",
|
|
53
|
+
"aria-label": detailsTitle,
|
|
54
|
+
className: "flex w-75 shrink-0 flex-col gap-3 overflow-y-auto",
|
|
55
|
+
children: details
|
|
56
|
+
})]
|
|
57
|
+
}), hasDetails && !wide && /* @__PURE__ */ jsx(Sheet, {
|
|
58
|
+
open: sheet,
|
|
59
|
+
onOpenChange: setSheet,
|
|
60
|
+
children: /* @__PURE__ */ jsxs(SheetContent, {
|
|
61
|
+
className: "overflow-y-auto bg-background p-4",
|
|
62
|
+
children: [/* @__PURE__ */ jsx(SheetHeader, {
|
|
63
|
+
className: "p-0",
|
|
64
|
+
children: /* @__PURE__ */ jsx(SheetTitle, { children: detailsTitle })
|
|
65
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
66
|
+
className: "flex flex-col gap-3",
|
|
104
67
|
children: details
|
|
105
68
|
})]
|
|
106
|
-
})
|
|
107
|
-
open: sheet,
|
|
108
|
-
onOpenChange: setSheet,
|
|
109
|
-
children: /* @__PURE__ */ jsxs(SheetContent, {
|
|
110
|
-
className: "overflow-y-auto bg-background p-4",
|
|
111
|
-
children: [/* @__PURE__ */ jsx(SheetHeader, {
|
|
112
|
-
className: "p-0",
|
|
113
|
-
children: /* @__PURE__ */ jsx(SheetTitle, { children: detailsTitle })
|
|
114
|
-
}), /* @__PURE__ */ jsx("div", {
|
|
115
|
-
className: "flex flex-col gap-3",
|
|
116
|
-
children: details
|
|
117
|
-
})]
|
|
118
|
-
})
|
|
119
|
-
})]
|
|
69
|
+
})
|
|
120
70
|
})]
|
|
121
71
|
})
|
|
122
|
-
})
|
|
123
|
-
}
|
|
124
|
-
/** Collapse / expand control for the desktop sidebar, with a tooltip. Hidden on mobile, where the sidebar is a sheet. */
|
|
125
|
-
function SidebarCollapseButton() {
|
|
126
|
-
const { state, isMobile, toggleSidebar } = useSidebar();
|
|
127
|
-
if (isMobile) return null;
|
|
128
|
-
const label = state === "collapsed" ? "Expand sidebar" : "Collapse sidebar";
|
|
129
|
-
return /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
|
|
130
|
-
asChild: true,
|
|
131
|
-
children: /* @__PURE__ */ jsx(Button, {
|
|
132
|
-
variant: "ghost",
|
|
133
|
-
size: state === "collapsed" ? "icon" : "icon-sm",
|
|
134
|
-
"aria-label": label,
|
|
135
|
-
onClick: toggleSidebar,
|
|
136
|
-
children: state === "collapsed" ? /* @__PURE__ */ jsx(PanelLeftOpenIcon, {}) : /* @__PURE__ */ jsx(PanelLeftCloseIcon, {})
|
|
137
|
-
})
|
|
138
|
-
}), /* @__PURE__ */ jsx(TooltipContent, {
|
|
139
|
-
side: "right",
|
|
140
|
-
children: label
|
|
141
|
-
})] });
|
|
72
|
+
});
|
|
142
73
|
}
|
|
143
74
|
/**
|
|
144
75
|
* The chat column as a card: header, optional notice, scrolling thread, composer. Inside ChatShell it adds the
|
package/dist/index.d.ts
CHANGED
|
@@ -72,11 +72,13 @@ import { KeyValueGrid, KeyValueItem } from "./components/admin/key-value-grid.js
|
|
|
72
72
|
import { LinkTile, LinkTileProps } from "./components/admin/link-tile.js";
|
|
73
73
|
import { PageHeader, PageHeaderProps } from "./components/admin/page-header.js";
|
|
74
74
|
import { SearchInput, SearchInputProps } from "./components/admin/search-input.js";
|
|
75
|
+
import { SidebarCollapseButton, SidebarLayout, SidebarLayoutProps } from "./components/admin/sidebar-layout.js";
|
|
75
76
|
import { StatCard, StatCardProps } from "./components/admin/stat-card.js";
|
|
76
77
|
import { StatusBadge, StatusBadgeProps, StatusDot, StatusDotProps, StatusTone } from "./components/admin/status.js";
|
|
77
78
|
import { Timeline, TimelineItem } from "./components/admin/timeline.js";
|
|
78
79
|
import { UsageMeter, UsageMeterProps } from "./components/admin/usage-meter.js";
|
|
79
80
|
import { UserChip, UserChipProps, initials } from "./components/admin/user-chip.js";
|
|
81
|
+
import { UserMenu, UserMenuProps } from "./components/admin/user-menu.js";
|
|
80
82
|
import { BarList, BarListItem } from "./components/data/bar-list.js";
|
|
81
83
|
import { DataTable, DataTableColumnDef, DataTableFeatures, DataTableProps, createDataTableColumnHelper, dataTableFeatures } from "./components/data/data-table.js";
|
|
82
84
|
import { Sparkline, SparklineProps, smoothPath } from "./components/data/sparkline.js";
|
|
@@ -97,4 +99,4 @@ import { useMediaQuery } from "./hooks/use-media-query.js";
|
|
|
97
99
|
import { useIsMobile } from "./hooks/use-mobile.js";
|
|
98
100
|
import { highlightCode, loadHighlighter } from "./lib/highlighter.js";
|
|
99
101
|
import { cn } from "./lib/utils.js";
|
|
100
|
-
export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, ActivityFeed, type ActivityItem, Alert, AlertAction, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogMedia, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AppBrand, type AppBrandProps, type AppNavItem, type AppNavSection, AppShell, type AppShellProps, AppleIcon, ApprovalCard, type ApprovalCardProps, ApprovalResult, type ApprovalResultProps, AspectRatio, AssistantAvatar, Attachment, AttachmentAction, AttachmentActions, AttachmentContent, AttachmentDescription, AttachmentGroup, AttachmentMedia, AttachmentTitle, AttachmentTrigger, AuthLayout, type AuthLayoutProps, type AuthProvider, Avatar, AvatarBadge, AvatarFallback, AvatarGroup, AvatarGroupCount, AvatarImage, Badge, BarList, type BarListItem, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Bubble, BubbleContent, BubbleGroup, BubbleReactions, Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, Calendar, CalendarDayButton, Callout, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Carousel, type CarouselApi, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious, type ChartConfig, ChartContainer, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent, ChatMessage, type ChatMessageProps, ChatPanel, type ChatPanelProps, ChatShell, type ChatShellProps, ChatThread, type ChatThreadProps, Checkbox, CodeBlock, CodeBlockActions, CodeBlockContent, CodeBlockCopyButton, CodeBlockFooter, CodeBlockHeader, CodeBlockLine, CodeBlockTitle, CodeSnippet, type CodeSnippetProps, Collapsible, CollapsibleContent, CollapsibleTrigger, Combobox, ComboboxChip, ComboboxChips, ComboboxChipsInput, ComboboxCollection, ComboboxContent, ComboboxEmpty, ComboboxGroup, ComboboxInput, ComboboxItem, ComboboxLabel, ComboboxList, ComboboxSeparator, ComboboxTrigger, ComboboxValue, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, ConfirmDialog, type ConfirmDialogProps, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, type Conversation, type ConversationGroup, ConversationList, type ConversationListProps, CopyField, type CopyFieldProps, DataTable, type DataTableColumnDef, type DataTableFeatures, type DataTableProps, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DirectionProvider, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle, Field, FieldContent, FieldDescription, FieldError, FieldGroup, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTitle, GitHubIcon, GoogleIcon, HoverCard, HoverCardContent, HoverCardTrigger, InlineCode, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, Item, ItemActions, ItemContent, ItemDescription, ItemFooter, ItemGroup, ItemHeader, ItemMedia, ItemSeparator, ItemTitle, Kbd, KbdGroup, KeyValueGrid, type KeyValueItem, Label, LinkTile, type LinkTileProps, LoginForm, type LoginFormProps, type LoginValues, Marker, MarkerContent, MarkerIcon, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, Message, MessageActions, type MessageActionsProps, MessageAvatar, MessageContent, MessageFooter, MessageGroup, MessageHeader, MessageScroller, MessageScrollerButton, MessageScrollerContent, MessageScrollerItem, MessageScrollerProvider, MessageScrollerViewport, type ModelOption, ModelPicker, type ModelPickerProps, NativeSelect, NativeSelectOptGroup, NativeSelectOption, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, NewConversationButton, type NewConversationButtonProps, PageHeader, type PageHeaderProps, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, Popover, PopoverAnchor, PopoverContent, PopoverDescription, PopoverHeader, PopoverTitle, PopoverTrigger, Progress, PromptInput, PromptInputChip, type PromptInputChipProps, type PromptInputProps, PromptInputSelect, type PromptInputSelectOption, type PromptInputSelectProps, Prose, Questionnaire, QuestionnaireActions, QuestionnaireChoice, QuestionnaireChoiceDescription, QuestionnaireChoices, QuestionnaireDescription, QuestionnaireError, QuestionnaireInput, QuestionnaireItem, QuestionnaireNext, QuestionnairePrevious, QuestionnaireProgress, QuestionnaireSkip, QuestionnaireSubmit, QuestionnaireTitle, RadioGroup, RadioGroupItem, ResizableHandle, ResizablePanel, ResizablePanelGroup, type ResolvedThemeMode, ScrollArea, ScrollBar, SearchInput, type SearchInputProps, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, SignupForm, type SignupFormProps, type SignupValues, Skeleton, Slider, Sparkline, type SparklineProps, Spinner, StatCard, type StatCardProps, StatusBadge, type StatusBadgeProps, type StatusBarDatum, StatusBars, type StatusBarsProps, StatusDot, type StatusDotProps, type StatusTone, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, type ThemeContextValue, type ThemeMode, ThemeProvider, type ThemeProviderProps, ThemeScript, ThemeToggle, Timeline, type TimelineItem, Toaster, Toggle, ToggleGroup, ToggleGroupItem, ToolCall, type ToolCallProps, ToolGroup, type ToolGroupProps, type ToolStatus, ToolStatusIcon, ToolStep, type ToolStepProps, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, Trace, TraceCollapsible, TraceCollapsibleContent, TraceCollapsibleTrigger, TraceDescription, TraceIcon, TraceLine, TraceTitle, TrendChart, type TrendChartProps, TrendLegend, type TrendSeries, TypingIndicator, type TypingIndicatorProps, UsageMeter, type UsageMeterProps, UserChip, type UserChipProps, badgeVariants, buttonGroupVariants, buttonVariants, cn, createDataTableColumnHelper, dataTableFeatures, groupByDate, highlightCode, initials, loadHighlighter, markerVariants, navigationMenuTriggerStyle, smoothPath, tabsListVariants, toggleVariants, useCarousel, useComboboxAnchor, useCopyToClipboard, useDirection, useHighlightedCode, useIsMobile, useMediaQuery, useMessageScroller, useMessageScrollerScrollable, useMessageScrollerVisibility, useSidebar, useSidebarOptional, useTheme };
|
|
102
|
+
export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, ActivityFeed, type ActivityItem, Alert, AlertAction, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogMedia, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AppBrand, type AppBrandProps, type AppNavItem, type AppNavSection, AppShell, type AppShellProps, AppleIcon, ApprovalCard, type ApprovalCardProps, ApprovalResult, type ApprovalResultProps, AspectRatio, AssistantAvatar, Attachment, AttachmentAction, AttachmentActions, AttachmentContent, AttachmentDescription, AttachmentGroup, AttachmentMedia, AttachmentTitle, AttachmentTrigger, AuthLayout, type AuthLayoutProps, type AuthProvider, Avatar, AvatarBadge, AvatarFallback, AvatarGroup, AvatarGroupCount, AvatarImage, Badge, BarList, type BarListItem, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Bubble, BubbleContent, BubbleGroup, BubbleReactions, Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, Calendar, CalendarDayButton, Callout, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Carousel, type CarouselApi, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious, type ChartConfig, ChartContainer, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent, ChatMessage, type ChatMessageProps, ChatPanel, type ChatPanelProps, ChatShell, type ChatShellProps, ChatThread, type ChatThreadProps, Checkbox, CodeBlock, CodeBlockActions, CodeBlockContent, CodeBlockCopyButton, CodeBlockFooter, CodeBlockHeader, CodeBlockLine, CodeBlockTitle, CodeSnippet, type CodeSnippetProps, Collapsible, CollapsibleContent, CollapsibleTrigger, Combobox, ComboboxChip, ComboboxChips, ComboboxChipsInput, ComboboxCollection, ComboboxContent, ComboboxEmpty, ComboboxGroup, ComboboxInput, ComboboxItem, ComboboxLabel, ComboboxList, ComboboxSeparator, ComboboxTrigger, ComboboxValue, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, ConfirmDialog, type ConfirmDialogProps, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, type Conversation, type ConversationGroup, ConversationList, type ConversationListProps, CopyField, type CopyFieldProps, DataTable, type DataTableColumnDef, type DataTableFeatures, type DataTableProps, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DirectionProvider, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle, Field, FieldContent, FieldDescription, FieldError, FieldGroup, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTitle, GitHubIcon, GoogleIcon, HoverCard, HoverCardContent, HoverCardTrigger, InlineCode, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, Item, ItemActions, ItemContent, ItemDescription, ItemFooter, ItemGroup, ItemHeader, ItemMedia, ItemSeparator, ItemTitle, Kbd, KbdGroup, KeyValueGrid, type KeyValueItem, Label, LinkTile, type LinkTileProps, LoginForm, type LoginFormProps, type LoginValues, Marker, MarkerContent, MarkerIcon, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, Message, MessageActions, type MessageActionsProps, MessageAvatar, MessageContent, MessageFooter, MessageGroup, MessageHeader, MessageScroller, MessageScrollerButton, MessageScrollerContent, MessageScrollerItem, MessageScrollerProvider, MessageScrollerViewport, type ModelOption, ModelPicker, type ModelPickerProps, NativeSelect, NativeSelectOptGroup, NativeSelectOption, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, NewConversationButton, type NewConversationButtonProps, PageHeader, type PageHeaderProps, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, Popover, PopoverAnchor, PopoverContent, PopoverDescription, PopoverHeader, PopoverTitle, PopoverTrigger, Progress, PromptInput, PromptInputChip, type PromptInputChipProps, type PromptInputProps, PromptInputSelect, type PromptInputSelectOption, type PromptInputSelectProps, Prose, Questionnaire, QuestionnaireActions, QuestionnaireChoice, QuestionnaireChoiceDescription, QuestionnaireChoices, QuestionnaireDescription, QuestionnaireError, QuestionnaireInput, QuestionnaireItem, QuestionnaireNext, QuestionnairePrevious, QuestionnaireProgress, QuestionnaireSkip, QuestionnaireSubmit, QuestionnaireTitle, RadioGroup, RadioGroupItem, ResizableHandle, ResizablePanel, ResizablePanelGroup, type ResolvedThemeMode, ScrollArea, ScrollBar, SearchInput, type SearchInputProps, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, Sidebar, SidebarCollapseButton, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarLayout, type SidebarLayoutProps, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, SignupForm, type SignupFormProps, type SignupValues, Skeleton, Slider, Sparkline, type SparklineProps, Spinner, StatCard, type StatCardProps, StatusBadge, type StatusBadgeProps, type StatusBarDatum, StatusBars, type StatusBarsProps, StatusDot, type StatusDotProps, type StatusTone, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, type ThemeContextValue, type ThemeMode, ThemeProvider, type ThemeProviderProps, ThemeScript, ThemeToggle, Timeline, type TimelineItem, Toaster, Toggle, ToggleGroup, ToggleGroupItem, ToolCall, type ToolCallProps, ToolGroup, type ToolGroupProps, type ToolStatus, ToolStatusIcon, ToolStep, type ToolStepProps, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, Trace, TraceCollapsible, TraceCollapsibleContent, TraceCollapsibleTrigger, TraceDescription, TraceIcon, TraceLine, TraceTitle, TrendChart, type TrendChartProps, TrendLegend, type TrendSeries, TypingIndicator, type TypingIndicatorProps, UsageMeter, type UsageMeterProps, UserChip, type UserChipProps, UserMenu, type UserMenuProps, badgeVariants, buttonGroupVariants, buttonVariants, cn, createDataTableColumnHelper, dataTableFeatures, groupByDate, highlightCode, initials, loadHighlighter, markerVariants, navigationMenuTriggerStyle, smoothPath, tabsListVariants, toggleVariants, useCarousel, useComboboxAnchor, useCopyToClipboard, useDirection, useHighlightedCode, useIsMobile, useMediaQuery, useMessageScroller, useMessageScrollerScrollable, useMessageScrollerVisibility, useSidebar, useSidebarOptional, useTheme };
|
package/dist/index.js
CHANGED
|
@@ -72,11 +72,13 @@ import { KeyValueGrid } from "./components/admin/key-value-grid.js";
|
|
|
72
72
|
import { LinkTile } from "./components/admin/link-tile.js";
|
|
73
73
|
import { PageHeader } from "./components/admin/page-header.js";
|
|
74
74
|
import { SearchInput } from "./components/admin/search-input.js";
|
|
75
|
+
import { SidebarCollapseButton, SidebarLayout } from "./components/admin/sidebar-layout.js";
|
|
75
76
|
import { StatCard } from "./components/admin/stat-card.js";
|
|
76
77
|
import { StatusBadge, StatusDot } from "./components/admin/status.js";
|
|
77
78
|
import { Timeline } from "./components/admin/timeline.js";
|
|
78
79
|
import { UsageMeter } from "./components/admin/usage-meter.js";
|
|
79
80
|
import { UserChip, initials } from "./components/admin/user-chip.js";
|
|
81
|
+
import { UserMenu } from "./components/admin/user-menu.js";
|
|
80
82
|
import { BarList } from "./components/data/bar-list.js";
|
|
81
83
|
import { DataTable, createDataTableColumnHelper, dataTableFeatures } from "./components/data/data-table.js";
|
|
82
84
|
import { Sparkline, smoothPath } from "./components/data/sparkline.js";
|
|
@@ -97,4 +99,4 @@ import { useMediaQuery } from "./hooks/use-media-query.js";
|
|
|
97
99
|
import { useIsMobile } from "./hooks/use-mobile.js";
|
|
98
100
|
import { highlightCode, loadHighlighter } from "./lib/highlighter.js";
|
|
99
101
|
import { cn } from "./lib/utils.js";
|
|
100
|
-
export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, ActivityFeed, Alert, AlertAction, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogMedia, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AppBrand, AppShell, AppleIcon, ApprovalCard, ApprovalResult, AspectRatio, AssistantAvatar, Attachment, AttachmentAction, AttachmentActions, AttachmentContent, AttachmentDescription, AttachmentGroup, AttachmentMedia, AttachmentTitle, AttachmentTrigger, AuthLayout, Avatar, AvatarBadge, AvatarFallback, AvatarGroup, AvatarGroupCount, AvatarImage, Badge, BarList, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Bubble, BubbleContent, BubbleGroup, BubbleReactions, Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, Calendar, CalendarDayButton, Callout, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious, ChartContainer, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent, ChatMessage, ChatPanel, ChatShell, ChatThread, Checkbox, CodeBlock, CodeBlockActions, CodeBlockContent, CodeBlockCopyButton, CodeBlockFooter, CodeBlockHeader, CodeBlockLine, CodeBlockTitle, CodeSnippet, Collapsible, CollapsibleContent, CollapsibleTrigger, Combobox, ComboboxChip, ComboboxChips, ComboboxChipsInput, ComboboxCollection, ComboboxContent, ComboboxEmpty, ComboboxGroup, ComboboxInput, ComboboxItem, ComboboxLabel, ComboboxList, ComboboxSeparator, ComboboxTrigger, ComboboxValue, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, ConfirmDialog, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, ConversationList, CopyField, DataTable, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DirectionProvider, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle, Field, FieldContent, FieldDescription, FieldError, FieldGroup, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTitle, GitHubIcon, GoogleIcon, HoverCard, HoverCardContent, HoverCardTrigger, InlineCode, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, Item, ItemActions, ItemContent, ItemDescription, ItemFooter, ItemGroup, ItemHeader, ItemMedia, ItemSeparator, ItemTitle, Kbd, KbdGroup, KeyValueGrid, Label, LinkTile, LoginForm, Marker, MarkerContent, MarkerIcon, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, Message, MessageActions, MessageAvatar, MessageContent, MessageFooter, MessageGroup, MessageHeader, MessageScroller, MessageScrollerButton, MessageScrollerContent, MessageScrollerItem, MessageScrollerProvider, MessageScrollerViewport, ModelPicker, NativeSelect, NativeSelectOptGroup, NativeSelectOption, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, NewConversationButton, PageHeader, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, Popover, PopoverAnchor, PopoverContent, PopoverDescription, PopoverHeader, PopoverTitle, PopoverTrigger, Progress, PromptInput, PromptInputChip, PromptInputSelect, Prose, Questionnaire, QuestionnaireActions, QuestionnaireChoice, QuestionnaireChoiceDescription, QuestionnaireChoices, QuestionnaireDescription, QuestionnaireError, QuestionnaireInput, QuestionnaireItem, QuestionnaireNext, QuestionnairePrevious, QuestionnaireProgress, QuestionnaireSkip, QuestionnaireSubmit, QuestionnaireTitle, RadioGroup, RadioGroupItem, ResizableHandle, ResizablePanel, ResizablePanelGroup, ScrollArea, ScrollBar, SearchInput, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, SignupForm, Skeleton, Slider, Sparkline, Spinner, StatCard, StatusBadge, StatusBars, StatusDot, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, ThemeProvider, ThemeScript, ThemeToggle, Timeline, Toaster, Toggle, ToggleGroup, ToggleGroupItem, ToolCall, ToolGroup, ToolStatusIcon, ToolStep, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, Trace, TraceCollapsible, TraceCollapsibleContent, TraceCollapsibleTrigger, TraceDescription, TraceIcon, TraceLine, TraceTitle, TrendChart, TrendLegend, TypingIndicator, UsageMeter, UserChip, badgeVariants, buttonGroupVariants, buttonVariants, cn, createDataTableColumnHelper, dataTableFeatures, groupByDate, highlightCode, initials, loadHighlighter, markerVariants, navigationMenuTriggerStyle, smoothPath, tabsListVariants, toggleVariants, useCarousel, useComboboxAnchor, useCopyToClipboard, useDirection, useHighlightedCode, useIsMobile, useMediaQuery, useMessageScroller, useMessageScrollerScrollable, useMessageScrollerVisibility, useSidebar, useSidebarOptional, useTheme };
|
|
102
|
+
export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, ActivityFeed, Alert, AlertAction, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogMedia, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AppBrand, AppShell, AppleIcon, ApprovalCard, ApprovalResult, AspectRatio, AssistantAvatar, Attachment, AttachmentAction, AttachmentActions, AttachmentContent, AttachmentDescription, AttachmentGroup, AttachmentMedia, AttachmentTitle, AttachmentTrigger, AuthLayout, Avatar, AvatarBadge, AvatarFallback, AvatarGroup, AvatarGroupCount, AvatarImage, Badge, BarList, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Bubble, BubbleContent, BubbleGroup, BubbleReactions, Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, Calendar, CalendarDayButton, Callout, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious, ChartContainer, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent, ChatMessage, ChatPanel, ChatShell, ChatThread, Checkbox, CodeBlock, CodeBlockActions, CodeBlockContent, CodeBlockCopyButton, CodeBlockFooter, CodeBlockHeader, CodeBlockLine, CodeBlockTitle, CodeSnippet, Collapsible, CollapsibleContent, CollapsibleTrigger, Combobox, ComboboxChip, ComboboxChips, ComboboxChipsInput, ComboboxCollection, ComboboxContent, ComboboxEmpty, ComboboxGroup, ComboboxInput, ComboboxItem, ComboboxLabel, ComboboxList, ComboboxSeparator, ComboboxTrigger, ComboboxValue, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, ConfirmDialog, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, ConversationList, CopyField, DataTable, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DirectionProvider, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle, Field, FieldContent, FieldDescription, FieldError, FieldGroup, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTitle, GitHubIcon, GoogleIcon, HoverCard, HoverCardContent, HoverCardTrigger, InlineCode, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, Item, ItemActions, ItemContent, ItemDescription, ItemFooter, ItemGroup, ItemHeader, ItemMedia, ItemSeparator, ItemTitle, Kbd, KbdGroup, KeyValueGrid, Label, LinkTile, LoginForm, Marker, MarkerContent, MarkerIcon, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, Message, MessageActions, MessageAvatar, MessageContent, MessageFooter, MessageGroup, MessageHeader, MessageScroller, MessageScrollerButton, MessageScrollerContent, MessageScrollerItem, MessageScrollerProvider, MessageScrollerViewport, ModelPicker, NativeSelect, NativeSelectOptGroup, NativeSelectOption, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, NewConversationButton, PageHeader, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, Popover, PopoverAnchor, PopoverContent, PopoverDescription, PopoverHeader, PopoverTitle, PopoverTrigger, Progress, PromptInput, PromptInputChip, PromptInputSelect, Prose, Questionnaire, QuestionnaireActions, QuestionnaireChoice, QuestionnaireChoiceDescription, QuestionnaireChoices, QuestionnaireDescription, QuestionnaireError, QuestionnaireInput, QuestionnaireItem, QuestionnaireNext, QuestionnairePrevious, QuestionnaireProgress, QuestionnaireSkip, QuestionnaireSubmit, QuestionnaireTitle, RadioGroup, RadioGroupItem, ResizableHandle, ResizablePanel, ResizablePanelGroup, ScrollArea, ScrollBar, SearchInput, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, Sidebar, SidebarCollapseButton, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarLayout, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, SignupForm, Skeleton, Slider, Sparkline, Spinner, StatCard, StatusBadge, StatusBars, StatusDot, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, ThemeProvider, ThemeScript, ThemeToggle, Timeline, Toaster, Toggle, ToggleGroup, ToggleGroupItem, ToolCall, ToolGroup, ToolStatusIcon, ToolStep, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, Trace, TraceCollapsible, TraceCollapsibleContent, TraceCollapsibleTrigger, TraceDescription, TraceIcon, TraceLine, TraceTitle, TrendChart, TrendLegend, TypingIndicator, UsageMeter, UserChip, UserMenu, badgeVariants, buttonGroupVariants, buttonVariants, cn, createDataTableColumnHelper, dataTableFeatures, groupByDate, highlightCode, initials, loadHighlighter, markerVariants, navigationMenuTriggerStyle, smoothPath, tabsListVariants, toggleVariants, useCarousel, useComboboxAnchor, useCopyToClipboard, useDirection, useHighlightedCode, useIsMobile, useMediaQuery, useMessageScroller, useMessageScrollerScrollable, useMessageScrollerVisibility, useSidebar, useSidebarOptional, useTheme };
|
package/docs/COMPONENTS.md
CHANGED
|
@@ -105,11 +105,29 @@ Every component in the shadcn registry is included. (shadcn's `form` item is an
|
|
|
105
105
|
|
|
106
106
|
## Admin and layout
|
|
107
107
|
|
|
108
|
+
### `SidebarLayout`, `SidebarCollapseButton`
|
|
109
|
+
|
|
110
|
+
The base layout every shell is built on: a sidebar (brand, actions, scrolling body, footer) next to the main column. On desktop a collapse button shrinks the sidebar to an icon rail (logo tile, icon actions, avatar); on mobile it is a sheet opened with a `SidebarTrigger`. Harebear parts adapt to the rail by themselves (`AppBrand`, `UserChip`, `UserMenu`, `NewConversationButton`, `SearchInput`, `ConversationList`, nav `SidebarMenuButton`s with `tooltip`).
|
|
111
|
+
|
|
112
|
+
Props: `brand?`, `sidebarActions?`, `sidebar?` (body), `sidebarFooter?`, `collapsible?` (`"icon"` default, `"offcanvas"` hides it entirely, `"none"` always expanded on desktop), `storageKey?` (remember collapsed state in localStorage, applied after hydration so SSR matches), `defaultOpen?`, `width?` (default `"16rem"`; the rail is `4.25rem`), `className?` (main column), `children` (main column).
|
|
113
|
+
`SidebarCollapseButton`: the collapse/expand button with a tooltip, for custom `Sidebar` layouts. Renders nothing on mobile.
|
|
114
|
+
|
|
115
|
+
```tsx
|
|
116
|
+
;<SidebarLayout
|
|
117
|
+
storageKey="app-sidebar"
|
|
118
|
+
brand={<AppBrand name="Console" icon={<SparklesIcon />} />}
|
|
119
|
+
sidebar={<MyNav />}
|
|
120
|
+
sidebarFooter={<UserMenu name={user.name} onSignOut={signOut} />}
|
|
121
|
+
>
|
|
122
|
+
<MyPage />
|
|
123
|
+
</SidebarLayout>
|
|
124
|
+
```
|
|
125
|
+
|
|
108
126
|
### `AppShell`
|
|
109
127
|
|
|
110
|
-
|
|
128
|
+
Admin layout on `SidebarLayout`: nav sidebar that collapses to an icon rail (nav items show their label as a tooltip there; badges and `sidebarExtra` hide) plus a main column with a top bar.
|
|
111
129
|
|
|
112
|
-
Props: `brand` (node, usually `AppBrand`), `nav: AppNavSection[]`, `sidebarExtra` (node under the nav), `sidebarFooter` (node, usually `
|
|
130
|
+
Props: `brand` (node, usually `AppBrand`), `sidebarActions?`, `nav: AppNavSection[]`, `sidebarExtra` (node under the nav), `sidebarFooter` (node, usually `UserMenu`), `header` (top bar content), `linkComponent` (e.g. Next.js `Link`; default `"a"`), `collapsible?` (default `"icon"`), `storageKey?`, `defaultOpen`, `children` (page content, laid out in a column with 28px gaps).
|
|
113
131
|
|
|
114
132
|
`AppNavSection = { label?: string; items: AppNavItem[] }`
|
|
115
133
|
`AppNavItem = { label: string; icon?: ReactNode; href?: string; onSelect?: () => void; active?: boolean; badge?: ReactNode }`
|
|
@@ -195,6 +213,19 @@ Label-over-value pairs as a `<dl>`. Props: `items: { label; value }[]`, `columns
|
|
|
195
213
|
|
|
196
214
|
Avatar + name + subtitle. Props: `name`, `subtitle?`, `avatarUrl?`, `action?`, `size?`. In a sidebar icon rail only the avatar shows. Also exports `initials(name)`.
|
|
197
215
|
|
|
216
|
+
### `UserMenu`
|
|
217
|
+
|
|
218
|
+
The signed-in user as a menu button (sidebar footer or top bar). The menu has a header, your items (`children`, e.g. a Settings `DropdownMenuItem`), a Light / Dark / System theme choice, and Sign out. In a sidebar icon rail the trigger is just the avatar and the menu opens to the side. Props: `name`, `subtitle?`, `avatarUrl?`, `children?`, `themeSwitch?` (default true, needs `ThemeProvider`), `onSignOut?`, `signOutLabel?`.
|
|
219
|
+
|
|
220
|
+
```tsx
|
|
221
|
+
;<UserMenu name={email} subtitle="Signed in" onSignOut={signOut}>
|
|
222
|
+
<DropdownMenuItem onSelect={() => setSettingsOpen(true)}>
|
|
223
|
+
<SettingsIcon />
|
|
224
|
+
Settings
|
|
225
|
+
</DropdownMenuItem>
|
|
226
|
+
</UserMenu>
|
|
227
|
+
```
|
|
228
|
+
|
|
198
229
|
### `ConfirmDialog`
|
|
199
230
|
|
|
200
231
|
Controlled "are you sure" dialog. Props: `open`, `onOpenChange`, `title`, `description?`, `confirmLabel?`, `cancelLabel?`, `destructive?` (red confirm), `onConfirm`.
|
|
@@ -257,11 +288,11 @@ Mini bar history (pings, uptime). Props: `data: (number | { value; tone?; label?
|
|
|
257
288
|
|
|
258
289
|
## AI and chat
|
|
259
290
|
|
|
260
|
-
A chat screen is `ChatShell` (sidebar with `AppBrand`, `NewConversationButton`, `ConversationList`, `
|
|
291
|
+
A chat screen is `ChatShell` (sidebar with `AppBrand`, `NewConversationButton`, `ConversationList`, `UserMenu`; optional details panel) around a `ChatPanel` (header, thread, `PromptInput`). Agent apps add `ToolGroup`/`ToolStep` for tool calls and `ApprovalCard`/`ApprovalResult` for permission prompts. See `playground/screens/chat.tsx` and `playground/screens/agent.tsx`.
|
|
261
292
|
|
|
262
293
|
### `ChatShell`
|
|
263
294
|
|
|
264
|
-
Full-height chat layout
|
|
295
|
+
Full-height chat layout on `SidebarLayout`, so the sidebar collapses to an icon rail on desktop (logo, actions, expand button, avatar) and is a sheet on mobile. Props: `brand?`, `sidebarActions?` (stays in the rail), `sidebar?` (hidden in the rail), `sidebarFooter?`, `collapsible?`, `details?` (right panel: inline at 1280px and up, a sheet below; `ChatPanel` gets a toggle button), `detailsTitle?` (default "Details"), `defaultDetailsOpen?`, `storageKey?` (remember collapsed state in localStorage), `defaultOpen?`, `children` (a `ChatPanel`). Includes a `TooltipProvider`.
|
|
265
296
|
|
|
266
297
|
```tsx
|
|
267
298
|
;<ChatShell
|
|
@@ -269,7 +300,7 @@ Full-height chat layout. The sidebar collapses to an icon rail on desktop (logo,
|
|
|
269
300
|
brand={<AppBrand name="netadmin" subtitle="Home network agent" icon={<TerminalIcon />} />}
|
|
270
301
|
sidebarActions={<NewConversationButton onClick={newChat} />}
|
|
271
302
|
sidebar={<ConversationList groups={groupByDate(chats, (c) => c.updated, toRow)} activeId={id} onSelect={open} />}
|
|
272
|
-
sidebarFooter={<
|
|
303
|
+
sidebarFooter={<UserMenu name={email} subtitle="Signed in" onSignOut={signOut} />}
|
|
273
304
|
details={<Card size="sm">…</Card>}
|
|
274
305
|
detailsTitle="Conversation details"
|
|
275
306
|
>
|
package/llms.txt
CHANGED
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
## Component index
|
|
28
28
|
|
|
29
29
|
Theme: ThemeProvider, useTheme, ThemeToggle, ThemeScript
|
|
30
|
-
Layout/admin: AppShell, AppBrand, PageHeader, StatCard, SearchInput, StatusDot, StatusBadge, UsageMeter, ActivityFeed, Timeline, KeyValueGrid, UserChip, Callout, LinkTile, ConfirmDialog, CopyField
|
|
30
|
+
Layout/admin: SidebarLayout, SidebarCollapseButton, AppShell, AppBrand, PageHeader, StatCard, SearchInput, StatusDot, StatusBadge, UsageMeter, ActivityFeed, Timeline, KeyValueGrid, UserChip, UserMenu, Callout, LinkTile, ConfirmDialog, CopyField
|
|
31
31
|
Data: DataTable, createDataTableColumnHelper, TrendChart, TrendLegend, BarList, Sparkline, StatusBars
|
|
32
32
|
AI/chat composites: ChatShell, ChatPanel, ChatThread, ChatMessage, AssistantAvatar, MessageActions, PromptInput, PromptInputChip, PromptInputSelect, ModelPicker, ConversationList, NewConversationButton, groupByDate, ToolCall, ToolGroup, ToolStep, ToolStatusIcon, ApprovalCard, ApprovalResult, TypingIndicator, CodeSnippet, InlineCode, Prose
|
|
33
33
|
AI/chat primitives (shadcn): Message, Bubble, MessageScroller, Attachment, Trace, Marker, Questionnaire, CodeBlock
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "harebear-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Opinionated, pre-themed shadcn/ui component library for React 19 + Tailwind CSS v4. Admin, data, and AI chat building blocks, ready for agents.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Harrison Milbradt",
|
|
@@ -22,9 +22,9 @@ This project uses `harebear-ui` for all UI. Its theme, tokens, and components ar
|
|
|
22
22
|
- Status uses a tone prop: `success | warning | danger | info | neutral` (StatusBadge, StatusDot, Timeline, StatusBars, LinkTile).
|
|
23
23
|
- Icons are lucide-react elements passed as nodes: `icon={<UsersIcon />}`. Icon-only buttons need `aria-label`.
|
|
24
24
|
- Compose `className` with `cn()` from harebear-ui.
|
|
25
|
-
- Lay out pages as columns of `Card`s with `gap-5`, page sections with `gap-7`. Use `PageHeader` for page titles and `AppShell` for sidebar apps.
|
|
25
|
+
- Lay out pages as columns of `Card`s with `gap-5`, page sections with `gap-7`. Use `PageHeader` for page titles and `AppShell` for sidebar apps. Every shell (`AppShell`, `ChatShell`) is built on `SidebarLayout`, which gives the collapsible icon rail; use it directly for other sidebar layouts instead of the raw Sidebar primitives.
|
|
26
26
|
- DataTable columns: define with `createDataTableColumnHelper<Row>()` at module scope, pass `getRowId`.
|
|
27
|
-
- Chat apps: `ChatShell` (sidebar: `AppBrand`, `NewConversationButton`, `ConversationList` + `groupByDate`, `
|
|
27
|
+
- Chat apps: `ChatShell` (sidebar: `AppBrand`, `NewConversationButton`, `ConversationList` + `groupByDate`, `UserMenu`; optional `details` panel) around a `ChatPanel` (title, actions, `notice`, `composer`). Don't hand-build the sidebar, rail or panel.
|
|
28
28
|
- Chat content: `ChatMessage role="user" | "assistant"`; render model output inside `Prose`; composer is `PromptInput` (+ `PromptInputChip`, `PromptInputSelect`); code is `CodeSnippet`; agent tool calls are `ToolGroup`/`ToolStep` (or the lighter `Trace`); permission prompts are `ApprovalCard`/`ApprovalResult`; working state is `TypingIndicator label`; clarifying questions are `Questionnaire`.
|
|
29
29
|
- Notices: `Alert variant="warning" | "success" | "info" | "destructive"`. Confirmations: `ConfirmDialog`. Copyable IDs: `CopyField`. Live status: `StatusDot`/`StatusBadge` with `pulse`.
|
|
30
30
|
- If you need a className to fix spacing, color, wrapping or borders on a harebear component, that is a library gap: report it instead of overriding.
|