harebear-ui 0.4.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.
@@ -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 <UserChip />. */
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: collapsible sidebar (sheet on mobile) + main column.
47
- * Built on the Sidebar primitives; drop to those for anything custom.
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 { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupLabel, SidebarHeader, SidebarInset, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarProvider, SidebarTrigger } from "../ui/sidebar.js";
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: collapsible sidebar (sheet on mobile) + main column.
40
- * Built on the Sidebar primitives; drop to those for anything custom.
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(SidebarProvider, {
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
- style: { "--sidebar-width": "15.75rem" },
46
- children: [/* @__PURE__ */ jsxs(Sidebar, { children: [
47
- brand && /* @__PURE__ */ jsx(SidebarHeader, {
48
- className: "px-4 pt-6 pb-2",
49
- children: brand
50
- }),
51
- /* @__PURE__ */ jsxs(SidebarContent, {
52
- className: "gap-5 px-2",
53
- children: [nav.map((section, i) => /* @__PURE__ */ jsxs(SidebarGroup, { children: [section.label && /* @__PURE__ */ jsx(SidebarGroupLabel, {
54
- className: "text-xs font-medium",
55
- children: section.label
56
- }), /* @__PURE__ */ jsx(SidebarMenu, {
57
- className: "gap-1",
58
- children: section.items.map((item) => /* @__PURE__ */ jsx(SidebarMenuItem, { children: /* @__PURE__ */ jsx(SidebarMenuButton, {
59
- asChild: !!item.href,
60
- isActive: item.active,
61
- onClick: item.onSelect,
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
- }) }, item.label))
81
- })] }, section.label ?? i)), sidebarExtra && /* @__PURE__ */ jsx("div", {
82
- className: "mt-auto px-2",
83
- children: sidebarExtra
84
- })]
85
- }),
86
- sidebarFooter && /* @__PURE__ */ jsx(SidebarFooter, {
87
- className: "px-4 pb-6",
88
- children: sidebarFooter
89
- })
90
- ] }), /* @__PURE__ */ jsxs(SidebarInset, {
91
- className: cn("min-w-0", className),
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 };
@@ -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. */
@@ -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: a sidebar that collapses to an icon rail (a sheet on mobile), the main chat
27
- * column, and an optional details panel. Put a ChatPanel inside.
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 { Sidebar, SidebarContent, SidebarFooter, SidebarHeader, SidebarInset, SidebarProvider, SidebarTrigger, useSidebar, useSidebarOptional } from "../ui/sidebar.js";
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 { PanelLeftCloseIcon, PanelLeftOpenIcon, PanelRightIcon, TriangleAlertIcon } from "lucide-react";
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: a sidebar that collapses to an icon rail (a sheet on mobile), the main chat
27
- * column, and an optional details panel. Put a ChatPanel inside.
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(TooltipProvider, { children: /* @__PURE__ */ jsx(SidebarProvider, {
59
- open,
60
- onOpenChange,
61
- style: {
62
- "--sidebar-width": "17rem",
63
- "--sidebar-width-icon": "4.25rem"
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(Sidebar, {
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 has-data-[slot=user-menu-trigger]: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: cn("h-dvh min-w-0 overflow-hidden", className),
98
- children: [/* @__PURE__ */ jsxs("div", {
99
- className: "flex h-full min-h-0 gap-3 p-2 sm:p-3 md:pl-0",
100
- children: [children, hasDetails && wide && inline && /* @__PURE__ */ jsx("aside", {
101
- "data-slot": "chat-shell-details",
102
- "aria-label": detailsTitle,
103
- className: "flex w-75 shrink-0 flex-col gap-3 overflow-y-auto",
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
- }), hasDetails && !wide && /* @__PURE__ */ jsx(Sheet, {
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,6 +72,7 @@ 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";
@@ -98,4 +99,4 @@ import { useMediaQuery } from "./hooks/use-media-query.js";
98
99
  import { useIsMobile } from "./hooks/use-mobile.js";
99
100
  import { highlightCode, loadHighlighter } from "./lib/highlighter.js";
100
101
  import { cn } from "./lib/utils.js";
101
- 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, 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 };
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,6 +72,7 @@ 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";
@@ -98,4 +99,4 @@ import { useMediaQuery } from "./hooks/use-media-query.js";
98
99
  import { useIsMobile } from "./hooks/use-mobile.js";
99
100
  import { highlightCode, loadHighlighter } from "./lib/highlighter.js";
100
101
  import { cn } from "./lib/utils.js";
101
- 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, 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 };
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 };
@@ -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
- Full app layout: collapsible sidebar (a sheet on mobile) plus a main column with a top bar.
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 `UserChip`), `header` (top bar content), `linkComponent` (e.g. Next.js `Link`; default `"a"`), `defaultOpen`, `children` (page content, laid out in a column with 28px gaps).
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 }`
@@ -274,7 +292,7 @@ A chat screen is `ChatShell` (sidebar with `AppBrand`, `NewConversationButton`,
274
292
 
275
293
  ### `ChatShell`
276
294
 
277
- Full-height chat layout. 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?`, `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`.
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`.
278
296
 
279
297
  ```tsx
280
298
  ;<ChatShell
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, UserMenu, 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.4.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,7 +22,7 @@ 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
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`.