@handled-ai/design-system 0.18.16 → 0.18.18
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/charts/chart.d.ts +1 -1
- package/dist/components/quick-action-sidebar-nav.d.ts +1 -0
- package/dist/components/quick-action-sidebar-nav.js +5 -2
- package/dist/components/quick-action-sidebar-nav.js.map +1 -1
- package/package.json +5 -1
- package/src/components/__tests__/quick-action-sidebar-nav.test.tsx +81 -0
- package/src/components/quick-action-sidebar-nav.tsx +3 -1
package/dist/charts/chart.d.ts
CHANGED
|
@@ -48,7 +48,7 @@ declare function ChartTooltipContent({ active, payload, className, indicator, hi
|
|
|
48
48
|
labelClassName?: string;
|
|
49
49
|
color?: string;
|
|
50
50
|
}): React.JSX.Element | null;
|
|
51
|
-
declare const ChartLegend:
|
|
51
|
+
declare const ChartLegend: React.MemoExoticComponent<(outsideProps: RechartsPrimitive.LegendProps) => React.ReactPortal | null>;
|
|
52
52
|
type LegendPayloadItem = {
|
|
53
53
|
value?: string;
|
|
54
54
|
dataKey?: string;
|
|
@@ -54,7 +54,7 @@ import {
|
|
|
54
54
|
Users
|
|
55
55
|
} from "lucide-react";
|
|
56
56
|
import { cn } from "../lib/utils.js";
|
|
57
|
-
import { Avatar, AvatarFallback } from "./avatar.js";
|
|
57
|
+
import { Avatar, AvatarFallback, AvatarImage } from "./avatar.js";
|
|
58
58
|
import {
|
|
59
59
|
DropdownMenu,
|
|
60
60
|
DropdownMenuContent,
|
|
@@ -502,7 +502,10 @@ function QuickActionSidebarNav(_a) {
|
|
|
502
502
|
isCollapsed ? "justify-center p-1" : "p-2 gap-3"
|
|
503
503
|
),
|
|
504
504
|
children: [
|
|
505
|
-
/* @__PURE__ */
|
|
505
|
+
/* @__PURE__ */ jsxs(Avatar, { className: "h-8 w-8 rounded-md", children: [
|
|
506
|
+
user.avatarUrl ? /* @__PURE__ */ jsx(AvatarImage, { src: user.avatarUrl, alt: user.name, className: "rounded-md" }) : null,
|
|
507
|
+
/* @__PURE__ */ jsx(AvatarFallback, { className: "rounded-md bg-primary/10 text-primary text-xs font-medium", children: initials })
|
|
508
|
+
] }),
|
|
506
509
|
!isCollapsed && /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-start flex-1 truncate", children: [
|
|
507
510
|
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium leading-none truncate", children: user.name }),
|
|
508
511
|
/* @__PURE__ */ jsx("span", { className: "text-xs text-sidebar-foreground/50 truncate mt-0.5", children: user.email })
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/quick-action-sidebar-nav.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport {\n Activity,\n BarChart2,\n Building,\n ChevronDown,\n Code,\n Inbox,\n Link as LinkIcon,\n LogOut,\n MessageSquare,\n MoreHorizontal,\n MoreVertical,\n PanelLeftClose,\n PanelLeftOpen,\n Plus,\n Search,\n Settings,\n Users,\n} from \"lucide-react\"\n\nimport { cn } from \"../lib/utils\"\nimport { Avatar, AvatarFallback } from \"./avatar\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"./dropdown-menu\"\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from \"./tooltip\"\nimport { QuickActionModal, type QuickActionTaskDraft, type QuickActionTemplate } from \"./quick-action-modal\"\n\nexport interface SidebarNavItem {\n id: string\n label: string\n icon: React.ComponentType<{ className?: string }>\n children?: SidebarNavItem[]\n}\n\nexport interface SidebarNavSection {\n title?: string\n /** Optional icon shown to the left of the section title (expanded sidebars only). */\n titleIconUrl?: string\n /**\n * Size of the title icon. Default `\"sm\"` (14px).\n * - `\"sm\"`: 14px, opacity 70 — secondary/decorative use\n * - `\"md\"`: 20px, opacity 90\n * - `\"lg\"`: 24px, full opacity — when the section icon is the primary brand mark\n */\n titleIconSize?: \"sm\" | \"md\" | \"lg\"\n items: SidebarNavItem[]\n moreItems?: SidebarNavItem[]\n}\n\nconst SECTION_TITLE_ICON_SIZE_CLASSES: Record<\n NonNullable<SidebarNavSection[\"titleIconSize\"]>,\n string\n> = {\n sm: \"h-3.5 w-3.5 opacity-70\",\n md: \"h-5 w-5 opacity-90\",\n lg: \"h-6 w-6\",\n}\n\nexport interface SidebarUserProfile {\n name: string\n email: string\n initials?: string\n}\n\nexport interface UserMenuItem {\n id: string\n label: string\n icon: React.ComponentType<{ className?: string }>\n destructive?: boolean\n}\n\nexport type ActiveVariant = \"default\" | \"gradient\"\n\ninterface QuickActionSidebarNavProps extends React.ComponentProps<\"aside\"> {\n brandLabel?: string\n brandSubtitle?: string\n brandImage?: string\n hideQuickAction?: boolean\n navSections?: SidebarNavSection[]\n activeItemId?: string\n activeVariant?: ActiveVariant\n onNavigate?: (itemId: string) => void\n user?: SidebarUserProfile\n userMenuItems?: UserMenuItem[]\n onUserMenuAction?: (itemId: string) => void\n onCreateTask?: (draft: QuickActionTaskDraft) => void\n defaultCollapsed?: boolean\n quickActionTemplates?: QuickActionTemplate[]\n quickActionTitle?: string\n quickActionDescription?: string\n onQuickActionClick?: () => void\n}\n\nconst DEFAULT_NAV_SECTIONS: SidebarNavSection[] = [\n {\n items: [\n { id: \"home\", label: \"Home\", icon: Inbox },\n { id: \"inbox\", label: \"Inbox\", icon: Inbox },\n ],\n },\n {\n title: \"Focus\",\n items: [\n { id: \"inbox\", label: \"Unibox\", icon: Inbox },\n { id: \"accounts\", label: \"My Accounts\", icon: Building },\n { id: \"activity\", label: \"Activity\", icon: Activity },\n { id: \"dashboard\", label: \"Insights\", icon: BarChart2 },\n ],\n moreItems: [\n { id: \"search\", label: \"Search\", icon: Search },\n ],\n },\n {\n title: \"Assistant\",\n items: [\n { id: \"new-chat\", label: \"New chat\", icon: Plus },\n { id: \"chats\", label: \"Chats\", icon: MessageSquare },\n ],\n },\n {\n title: \"Your Teams\",\n items: [\n { id: \"team-a\", label: \"Team A\", icon: Users },\n { id: \"team-b\", label: \"Team B\", icon: Users },\n ],\n moreItems: [\n { id: \"more-teams\", label: \"More\", icon: MoreHorizontal },\n ],\n },\n]\n\nconst DEFAULT_USER: SidebarUserProfile = {\n name: \"John Doe\",\n email: \"jdoe@acmeco.com\",\n initials: \"JD\",\n}\n\nconst DEFAULT_USER_MENU: UserMenuItem[] = [\n { id: \"settings\", label: \"Settings\", icon: Settings },\n { id: \"dev\", label: \"Dev\", icon: Code },\n { id: \"integrations\", label: \"Integrations\", icon: LinkIcon },\n { id: \"sign-out\", label: \"Sign out\", icon: LogOut, destructive: true },\n]\n\nfunction NavItemRow({\n item,\n isActive,\n isCollapsed,\n activeVariant = \"default\",\n onClick,\n onNavigate,\n activeItemId,\n expandedItems,\n onToggleExpand,\n depth = 0,\n}: {\n item: SidebarNavItem\n isActive: boolean\n isCollapsed: boolean\n activeVariant?: ActiveVariant\n onClick?: () => void\n onNavigate?: (id: string) => void\n activeItemId?: string\n expandedItems?: Record<string, boolean>\n onToggleExpand?: (itemId: string) => void\n depth?: number\n}) {\n const activeClasses =\n activeVariant === \"gradient\"\n ? \"bg-gradient-to-r from-primary/10 to-transparent text-primary\"\n : \"bg-sidebar-accent text-sidebar-accent-foreground\"\n\n const iconActiveClasses =\n activeVariant === \"gradient\" ? \"text-primary\" : \"\"\n\n const hasChildren = item.children && item.children.length > 0\n const isExpanded = expandedItems?.[item.id] ?? false\n\n const content = (\n <div>\n <div className=\"flex items-center\">\n <button\n type=\"button\"\n onClick={onClick}\n className={cn(\n \"flex flex-1 items-center gap-3 rounded-lg text-sm font-medium transition-colors\",\n isCollapsed ? \"justify-center p-2\" : \"px-3 py-2\",\n isActive\n ? activeClasses\n : \"text-sidebar-foreground/70 hover:text-sidebar-foreground hover:bg-sidebar-accent\",\n )}\n style={depth > 0 && !isCollapsed ? { paddingLeft: `${0.75 + depth * 1}rem` } : undefined}\n >\n <item.icon className={cn(\"shrink-0\", isCollapsed ? \"w-5 h-5\" : \"w-4 h-4\", isActive && iconActiveClasses)} />\n {!isCollapsed && <span className=\"flex-1 truncate text-left\">{item.label}</span>}\n </button>\n {hasChildren && !isCollapsed && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation()\n onToggleExpand?.(item.id)\n }}\n className=\"p-1 mr-1 rounded text-sidebar-foreground/40 hover:text-sidebar-foreground hover:bg-sidebar-accent transition-colors\"\n >\n <ChevronDown\n className={cn(\n \"w-3.5 h-3.5 transition-transform duration-200\",\n !isExpanded && \"-rotate-90\",\n )}\n />\n </button>\n )}\n </div>\n {hasChildren && !isCollapsed && isExpanded && (\n <div className=\"space-y-0.5\">\n {item.children!.map((child) => (\n <NavItemRow\n key={child.id}\n item={child}\n isActive={activeItemId === child.id}\n isCollapsed={isCollapsed}\n activeVariant={activeVariant}\n activeItemId={activeItemId}\n onClick={() => onNavigate?.(child.id)}\n onNavigate={onNavigate}\n expandedItems={expandedItems}\n onToggleExpand={onToggleExpand}\n depth={depth + 1}\n />\n ))}\n </div>\n )}\n </div>\n )\n\n if (isCollapsed) {\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={onClick}\n className={cn(\n \"flex w-full items-center gap-3 rounded-lg text-sm font-medium transition-colors\",\n \"justify-center p-2\",\n isActive\n ? activeClasses\n : \"text-sidebar-foreground/70 hover:text-sidebar-foreground hover:bg-sidebar-accent\",\n )}\n >\n <item.icon className={cn(\"shrink-0 w-5 h-5\", isActive && iconActiveClasses)} />\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"right\">{item.label}</TooltipContent>\n </Tooltip>\n )\n }\n\n return content\n}\n\nfunction NavSection({\n section,\n activeItemId,\n isCollapsed,\n activeVariant = \"default\",\n onNavigate,\n}: {\n section: SidebarNavSection\n activeItemId?: string\n isCollapsed: boolean\n activeVariant?: ActiveVariant\n onNavigate?: (id: string) => void\n}) {\n const [isExpanded, setIsExpanded] = React.useState(true)\n const [expandedItems, setExpandedItems] = React.useState<Record<string, boolean>>({})\n const hasTitle = !isCollapsed && section.title\n\n const handleToggleExpand = React.useCallback((itemId: string) => {\n setExpandedItems((prev) => ({ ...prev, [itemId]: !prev[itemId] }))\n }, [])\n\n return (\n <div className=\"px-3 py-2\">\n {hasTitle && (\n <button\n type=\"button\"\n onClick={() => setIsExpanded(!isExpanded)}\n className=\"flex w-full items-center justify-between mb-1 px-3 group cursor-pointer\"\n >\n <span className=\"flex items-center gap-1.5 min-w-0\">\n {section.titleIconUrl && (\n <img\n src={section.titleIconUrl}\n alt=\"\"\n aria-hidden=\"true\"\n className={cn(\n \"shrink-0 object-contain\",\n SECTION_TITLE_ICON_SIZE_CLASSES[section.titleIconSize ?? \"sm\"],\n )}\n />\n )}\n <span className=\"text-xs font-bold tracking-widest text-sidebar-foreground/50 uppercase truncate\">\n {section.title}\n </span>\n </span>\n <ChevronDown\n className={cn(\n \"w-3 h-3 text-sidebar-foreground/40 transition-transform duration-200\",\n !isExpanded && \"-rotate-90\",\n )}\n />\n </button>\n )}\n {(isExpanded || isCollapsed || !section.title) && (\n <div className=\"space-y-0.5\">\n {section.items.map((item) => (\n <NavItemRow\n key={item.id}\n item={item}\n isActive={activeItemId === item.id}\n isCollapsed={isCollapsed}\n activeVariant={activeVariant}\n activeItemId={activeItemId}\n onClick={() => onNavigate?.(item.id)}\n onNavigate={onNavigate}\n expandedItems={expandedItems}\n onToggleExpand={handleToggleExpand}\n />\n ))}\n {!isCollapsed && section.moreItems && section.moreItems.length > 0 && (\n <DropdownMenu>\n <DropdownMenuTrigger className=\"flex items-center gap-3 w-full px-3 py-2 rounded-lg text-sm font-medium text-sidebar-foreground/70 hover:text-sidebar-foreground hover:bg-sidebar-accent transition-colors outline-none\">\n <MoreHorizontal className=\"shrink-0 w-4 h-4\" />\n <span className=\"flex-1 text-left\">More</span>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" side=\"bottom\" className=\"w-48\">\n {section.moreItems.map((item) => (\n <DropdownMenuItem\n key={item.id}\n onClick={() => onNavigate?.(item.id)}\n className=\"cursor-pointer\"\n >\n <item.icon className=\"mr-2 w-4 h-4 text-muted-foreground\" />\n <span>{item.label}</span>\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n {isCollapsed &&\n section.moreItems?.map((item) => (\n <NavItemRow\n key={item.id}\n item={item}\n isActive={activeItemId === item.id}\n isCollapsed={isCollapsed}\n activeVariant={activeVariant}\n onClick={() => onNavigate?.(item.id)}\n />\n ))}\n </div>\n )}\n </div>\n )\n}\n\nexport function QuickActionSidebarNav({\n className,\n brandLabel = \"ACME CO\",\n brandSubtitle = \"Placeholder\",\n brandImage,\n hideQuickAction,\n navSections = DEFAULT_NAV_SECTIONS,\n activeItemId = \"inbox\",\n activeVariant = \"default\",\n onNavigate,\n user = DEFAULT_USER,\n userMenuItems = DEFAULT_USER_MENU,\n onUserMenuAction,\n onCreateTask,\n defaultCollapsed = false,\n quickActionTemplates,\n quickActionTitle,\n quickActionDescription,\n onQuickActionClick,\n ...props\n}: QuickActionSidebarNavProps) {\n const [isQuickActionOpen, setIsQuickActionOpen] = React.useState(false)\n const [isCollapsed, setIsCollapsed] = React.useState(defaultCollapsed)\n\n const initials =\n user.initials ??\n (user.name\n ? user.name.charAt(0).toUpperCase()\n : user.email\n ? user.email.charAt(0).toUpperCase()\n : \"U\")\n\n return (\n <TooltipProvider delayDuration={0}>\n <aside\n className={cn(\n \"flex h-full flex-col overflow-hidden bg-sidebar text-sidebar-foreground border-r border-sidebar-border transition-all duration-200\",\n isCollapsed ? \"w-16\" : \"w-64\",\n className,\n )}\n {...props}\n >\n {/* Header */}\n <div\n className={cn(\n \"relative flex shrink-0 items-center border-b border-sidebar-border\",\n isCollapsed ? \"justify-center h-16 px-2\" : \"px-6 py-4\",\n )}\n >\n {!isCollapsed && (\n <div className=\"flex items-center gap-2.5 pr-8\">\n {brandImage ? (\n <img src={brandImage} alt={brandLabel} className=\"h-10 object-contain\" />\n ) : (\n <>\n <div className=\"flex h-6 w-6 items-center justify-center rounded-full bg-sidebar-foreground text-sidebar\">\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" className=\"w-3.5 h-3.5\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n </svg>\n </div>\n <div className=\"flex flex-col gap-0.5\">\n <span className=\"text-sm font-bold tracking-tight\">\n {brandLabel}\n </span>\n {brandSubtitle && (\n <span className=\"text-[10px] font-medium text-sidebar-foreground/50 uppercase tracking-wide\">\n {brandSubtitle}\n </span>\n )}\n </div>\n </>\n )}\n </div>\n )}\n\n <button\n type=\"button\"\n onClick={() => setIsCollapsed(!isCollapsed)}\n className={cn(\n \"p-1.5 rounded-md text-sidebar-foreground/50 hover:text-sidebar-foreground hover:bg-sidebar-accent transition-colors\",\n isCollapsed ? \"\" : \"absolute right-5 top-1/2 -translate-y-1/2\",\n )}\n title={isCollapsed ? \"Expand sidebar\" : \"Collapse sidebar\"}\n >\n {isCollapsed ? (\n <PanelLeftOpen className=\"w-4 h-4\" />\n ) : (\n <PanelLeftClose className=\"w-4 h-4\" />\n )}\n </button>\n </div>\n\n {/* Navigation */}\n <div className=\"flex-1 overflow-y-auto overflow-x-hidden py-3 space-y-1\">\n {navSections.map((section, idx) => (\n <React.Fragment key={section.title ?? idx}>\n {idx > 0 && <div className=\"mx-4 my-2 border-t border-sidebar-border\" />}\n <NavSection\n section={section}\n activeItemId={activeItemId}\n isCollapsed={isCollapsed}\n activeVariant={activeVariant}\n onNavigate={onNavigate}\n />\n </React.Fragment>\n ))}\n </div>\n\n {!hideQuickAction && (\n <div className={cn(\"px-3 pb-3\", isCollapsed ? \"hidden\" : \"block\")}>\n <button\n type=\"button\"\n onClick={() => {\n if (onQuickActionClick) {\n onQuickActionClick();\n } else {\n setIsQuickActionOpen(true);\n }\n }}\n className=\"w-full flex items-center justify-between px-3 py-2.5 rounded-lg border border-sidebar-border bg-sidebar-primary text-sidebar-primary-foreground hover:bg-sidebar-primary/90 transition-colors group shadow-sm\"\n >\n <div className=\"flex items-center gap-2\">\n <svg\n className=\"w-4 h-4 text-sidebar-primary-foreground/80 group-hover:text-sidebar-primary-foreground transition-colors\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M13 10V3L4 14h7v7l9-11h-7z\"\n />\n </svg>\n <span className=\"text-sm font-medium\">Quick Action</span>\n </div>\n <kbd className=\"hidden sm:inline-flex items-center gap-0.5 px-1.5 py-0.5 text-[11px] font-mono rounded bg-sidebar-primary-foreground/20 text-sidebar-primary-foreground\">\n <span className=\"text-xs\">⌘</span>K\n </kbd>\n </button>\n </div>\n )}\n\n {isCollapsed && !hideQuickAction && (\n <div className=\"px-2 pb-3\">\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={() => {\n if (onQuickActionClick) {\n onQuickActionClick();\n } else {\n setIsQuickActionOpen(true);\n }\n }}\n className=\"flex w-full items-center justify-center rounded-lg bg-sidebar-primary p-2.5 text-sidebar-primary-foreground shadow-sm transition-colors hover:bg-sidebar-primary/90\"\n title=\"Quick Action (⌘K)\"\n >\n <svg\n className=\"w-5 h-5\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M13 10V3L4 14h7v7l9-11h-7z\"\n />\n </svg>\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"right\">Quick Action (⌘K)</TooltipContent>\n </Tooltip>\n </div>\n )}\n\n {/* User Profile Footer */}\n <div className=\"p-3 border-t border-sidebar-border shrink-0\">\n <DropdownMenu>\n <DropdownMenuTrigger\n className={cn(\n \"flex items-center w-full rounded-lg hover:bg-sidebar-accent transition-colors outline-none\",\n isCollapsed ? \"justify-center p-1\" : \"p-2 gap-3\",\n )}\n >\n <Avatar className=\"h-8 w-8 rounded-md\">\n <AvatarFallback className=\"rounded-md bg-primary/10 text-primary text-xs font-medium\">\n {initials}\n </AvatarFallback>\n </Avatar>\n\n {!isCollapsed && (\n <div className=\"flex flex-col items-start flex-1 truncate\">\n <span className=\"text-sm font-medium leading-none truncate\">\n {user.name}\n </span>\n <span className=\"text-xs text-sidebar-foreground/50 truncate mt-0.5\">\n {user.email}\n </span>\n </div>\n )}\n\n {!isCollapsed && (\n <MoreVertical className=\"w-4 h-4 text-sidebar-foreground/50 shrink-0\" />\n )}\n </DropdownMenuTrigger>\n\n <DropdownMenuContent align=\"end\" side=\"right\" sideOffset={8} className=\"w-56\">\n <DropdownMenuLabel className=\"font-normal\">\n <div className=\"flex flex-col space-y-1\">\n <p className=\"text-sm font-medium leading-none\">{user.name}</p>\n <p className=\"text-xs leading-none text-muted-foreground\">{user.email}</p>\n </div>\n </DropdownMenuLabel>\n <DropdownMenuSeparator />\n {userMenuItems.map((item, idx) => {\n const showSepBefore = item.destructive && idx > 0\n return (\n <React.Fragment key={item.id}>\n {showSepBefore && <DropdownMenuSeparator />}\n <DropdownMenuItem\n onClick={() => onUserMenuAction?.(item.id)}\n className={cn(\n \"cursor-pointer\",\n item.destructive && \"text-destructive focus:text-destructive\",\n )}\n >\n <item.icon className=\"mr-2 h-4 w-4\" />\n <span>{item.label}</span>\n </DropdownMenuItem>\n </React.Fragment>\n )\n })}\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n </aside>\n\n {!hideQuickAction && !onQuickActionClick && (\n <QuickActionModal\n open={isQuickActionOpen}\n onOpenChange={setIsQuickActionOpen}\n onCreateTask={onCreateTask}\n templates={quickActionTemplates}\n title={quickActionTitle}\n description={quickActionDescription}\n />\n )}\n </TooltipProvider>\n )\n}\n"],"mappings":"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","names":["_a"]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/quick-action-sidebar-nav.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport {\n Activity,\n BarChart2,\n Building,\n ChevronDown,\n Code,\n Inbox,\n Link as LinkIcon,\n LogOut,\n MessageSquare,\n MoreHorizontal,\n MoreVertical,\n PanelLeftClose,\n PanelLeftOpen,\n Plus,\n Search,\n Settings,\n Users,\n} from \"lucide-react\"\n\nimport { cn } from \"../lib/utils\"\nimport { Avatar, AvatarFallback, AvatarImage } from \"./avatar\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"./dropdown-menu\"\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from \"./tooltip\"\nimport { QuickActionModal, type QuickActionTaskDraft, type QuickActionTemplate } from \"./quick-action-modal\"\n\nexport interface SidebarNavItem {\n id: string\n label: string\n icon: React.ComponentType<{ className?: string }>\n children?: SidebarNavItem[]\n}\n\nexport interface SidebarNavSection {\n title?: string\n /** Optional icon shown to the left of the section title (expanded sidebars only). */\n titleIconUrl?: string\n /**\n * Size of the title icon. Default `\"sm\"` (14px).\n * - `\"sm\"`: 14px, opacity 70 — secondary/decorative use\n * - `\"md\"`: 20px, opacity 90\n * - `\"lg\"`: 24px, full opacity — when the section icon is the primary brand mark\n */\n titleIconSize?: \"sm\" | \"md\" | \"lg\"\n items: SidebarNavItem[]\n moreItems?: SidebarNavItem[]\n}\n\nconst SECTION_TITLE_ICON_SIZE_CLASSES: Record<\n NonNullable<SidebarNavSection[\"titleIconSize\"]>,\n string\n> = {\n sm: \"h-3.5 w-3.5 opacity-70\",\n md: \"h-5 w-5 opacity-90\",\n lg: \"h-6 w-6\",\n}\n\nexport interface SidebarUserProfile {\n name: string\n email: string\n initials?: string\n avatarUrl?: string | null\n}\n\nexport interface UserMenuItem {\n id: string\n label: string\n icon: React.ComponentType<{ className?: string }>\n destructive?: boolean\n}\n\nexport type ActiveVariant = \"default\" | \"gradient\"\n\ninterface QuickActionSidebarNavProps extends React.ComponentProps<\"aside\"> {\n brandLabel?: string\n brandSubtitle?: string\n brandImage?: string\n hideQuickAction?: boolean\n navSections?: SidebarNavSection[]\n activeItemId?: string\n activeVariant?: ActiveVariant\n onNavigate?: (itemId: string) => void\n user?: SidebarUserProfile\n userMenuItems?: UserMenuItem[]\n onUserMenuAction?: (itemId: string) => void\n onCreateTask?: (draft: QuickActionTaskDraft) => void\n defaultCollapsed?: boolean\n quickActionTemplates?: QuickActionTemplate[]\n quickActionTitle?: string\n quickActionDescription?: string\n onQuickActionClick?: () => void\n}\n\nconst DEFAULT_NAV_SECTIONS: SidebarNavSection[] = [\n {\n items: [\n { id: \"home\", label: \"Home\", icon: Inbox },\n { id: \"inbox\", label: \"Inbox\", icon: Inbox },\n ],\n },\n {\n title: \"Focus\",\n items: [\n { id: \"inbox\", label: \"Unibox\", icon: Inbox },\n { id: \"accounts\", label: \"My Accounts\", icon: Building },\n { id: \"activity\", label: \"Activity\", icon: Activity },\n { id: \"dashboard\", label: \"Insights\", icon: BarChart2 },\n ],\n moreItems: [\n { id: \"search\", label: \"Search\", icon: Search },\n ],\n },\n {\n title: \"Assistant\",\n items: [\n { id: \"new-chat\", label: \"New chat\", icon: Plus },\n { id: \"chats\", label: \"Chats\", icon: MessageSquare },\n ],\n },\n {\n title: \"Your Teams\",\n items: [\n { id: \"team-a\", label: \"Team A\", icon: Users },\n { id: \"team-b\", label: \"Team B\", icon: Users },\n ],\n moreItems: [\n { id: \"more-teams\", label: \"More\", icon: MoreHorizontal },\n ],\n },\n]\n\nconst DEFAULT_USER: SidebarUserProfile = {\n name: \"John Doe\",\n email: \"jdoe@acmeco.com\",\n initials: \"JD\",\n}\n\nconst DEFAULT_USER_MENU: UserMenuItem[] = [\n { id: \"settings\", label: \"Settings\", icon: Settings },\n { id: \"dev\", label: \"Dev\", icon: Code },\n { id: \"integrations\", label: \"Integrations\", icon: LinkIcon },\n { id: \"sign-out\", label: \"Sign out\", icon: LogOut, destructive: true },\n]\n\nfunction NavItemRow({\n item,\n isActive,\n isCollapsed,\n activeVariant = \"default\",\n onClick,\n onNavigate,\n activeItemId,\n expandedItems,\n onToggleExpand,\n depth = 0,\n}: {\n item: SidebarNavItem\n isActive: boolean\n isCollapsed: boolean\n activeVariant?: ActiveVariant\n onClick?: () => void\n onNavigate?: (id: string) => void\n activeItemId?: string\n expandedItems?: Record<string, boolean>\n onToggleExpand?: (itemId: string) => void\n depth?: number\n}) {\n const activeClasses =\n activeVariant === \"gradient\"\n ? \"bg-gradient-to-r from-primary/10 to-transparent text-primary\"\n : \"bg-sidebar-accent text-sidebar-accent-foreground\"\n\n const iconActiveClasses =\n activeVariant === \"gradient\" ? \"text-primary\" : \"\"\n\n const hasChildren = item.children && item.children.length > 0\n const isExpanded = expandedItems?.[item.id] ?? false\n\n const content = (\n <div>\n <div className=\"flex items-center\">\n <button\n type=\"button\"\n onClick={onClick}\n className={cn(\n \"flex flex-1 items-center gap-3 rounded-lg text-sm font-medium transition-colors\",\n isCollapsed ? \"justify-center p-2\" : \"px-3 py-2\",\n isActive\n ? activeClasses\n : \"text-sidebar-foreground/70 hover:text-sidebar-foreground hover:bg-sidebar-accent\",\n )}\n style={depth > 0 && !isCollapsed ? { paddingLeft: `${0.75 + depth * 1}rem` } : undefined}\n >\n <item.icon className={cn(\"shrink-0\", isCollapsed ? \"w-5 h-5\" : \"w-4 h-4\", isActive && iconActiveClasses)} />\n {!isCollapsed && <span className=\"flex-1 truncate text-left\">{item.label}</span>}\n </button>\n {hasChildren && !isCollapsed && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation()\n onToggleExpand?.(item.id)\n }}\n className=\"p-1 mr-1 rounded text-sidebar-foreground/40 hover:text-sidebar-foreground hover:bg-sidebar-accent transition-colors\"\n >\n <ChevronDown\n className={cn(\n \"w-3.5 h-3.5 transition-transform duration-200\",\n !isExpanded && \"-rotate-90\",\n )}\n />\n </button>\n )}\n </div>\n {hasChildren && !isCollapsed && isExpanded && (\n <div className=\"space-y-0.5\">\n {item.children!.map((child) => (\n <NavItemRow\n key={child.id}\n item={child}\n isActive={activeItemId === child.id}\n isCollapsed={isCollapsed}\n activeVariant={activeVariant}\n activeItemId={activeItemId}\n onClick={() => onNavigate?.(child.id)}\n onNavigate={onNavigate}\n expandedItems={expandedItems}\n onToggleExpand={onToggleExpand}\n depth={depth + 1}\n />\n ))}\n </div>\n )}\n </div>\n )\n\n if (isCollapsed) {\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={onClick}\n className={cn(\n \"flex w-full items-center gap-3 rounded-lg text-sm font-medium transition-colors\",\n \"justify-center p-2\",\n isActive\n ? activeClasses\n : \"text-sidebar-foreground/70 hover:text-sidebar-foreground hover:bg-sidebar-accent\",\n )}\n >\n <item.icon className={cn(\"shrink-0 w-5 h-5\", isActive && iconActiveClasses)} />\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"right\">{item.label}</TooltipContent>\n </Tooltip>\n )\n }\n\n return content\n}\n\nfunction NavSection({\n section,\n activeItemId,\n isCollapsed,\n activeVariant = \"default\",\n onNavigate,\n}: {\n section: SidebarNavSection\n activeItemId?: string\n isCollapsed: boolean\n activeVariant?: ActiveVariant\n onNavigate?: (id: string) => void\n}) {\n const [isExpanded, setIsExpanded] = React.useState(true)\n const [expandedItems, setExpandedItems] = React.useState<Record<string, boolean>>({})\n const hasTitle = !isCollapsed && section.title\n\n const handleToggleExpand = React.useCallback((itemId: string) => {\n setExpandedItems((prev) => ({ ...prev, [itemId]: !prev[itemId] }))\n }, [])\n\n return (\n <div className=\"px-3 py-2\">\n {hasTitle && (\n <button\n type=\"button\"\n onClick={() => setIsExpanded(!isExpanded)}\n className=\"flex w-full items-center justify-between mb-1 px-3 group cursor-pointer\"\n >\n <span className=\"flex items-center gap-1.5 min-w-0\">\n {section.titleIconUrl && (\n <img\n src={section.titleIconUrl}\n alt=\"\"\n aria-hidden=\"true\"\n className={cn(\n \"shrink-0 object-contain\",\n SECTION_TITLE_ICON_SIZE_CLASSES[section.titleIconSize ?? \"sm\"],\n )}\n />\n )}\n <span className=\"text-xs font-bold tracking-widest text-sidebar-foreground/50 uppercase truncate\">\n {section.title}\n </span>\n </span>\n <ChevronDown\n className={cn(\n \"w-3 h-3 text-sidebar-foreground/40 transition-transform duration-200\",\n !isExpanded && \"-rotate-90\",\n )}\n />\n </button>\n )}\n {(isExpanded || isCollapsed || !section.title) && (\n <div className=\"space-y-0.5\">\n {section.items.map((item) => (\n <NavItemRow\n key={item.id}\n item={item}\n isActive={activeItemId === item.id}\n isCollapsed={isCollapsed}\n activeVariant={activeVariant}\n activeItemId={activeItemId}\n onClick={() => onNavigate?.(item.id)}\n onNavigate={onNavigate}\n expandedItems={expandedItems}\n onToggleExpand={handleToggleExpand}\n />\n ))}\n {!isCollapsed && section.moreItems && section.moreItems.length > 0 && (\n <DropdownMenu>\n <DropdownMenuTrigger className=\"flex items-center gap-3 w-full px-3 py-2 rounded-lg text-sm font-medium text-sidebar-foreground/70 hover:text-sidebar-foreground hover:bg-sidebar-accent transition-colors outline-none\">\n <MoreHorizontal className=\"shrink-0 w-4 h-4\" />\n <span className=\"flex-1 text-left\">More</span>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" side=\"bottom\" className=\"w-48\">\n {section.moreItems.map((item) => (\n <DropdownMenuItem\n key={item.id}\n onClick={() => onNavigate?.(item.id)}\n className=\"cursor-pointer\"\n >\n <item.icon className=\"mr-2 w-4 h-4 text-muted-foreground\" />\n <span>{item.label}</span>\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n {isCollapsed &&\n section.moreItems?.map((item) => (\n <NavItemRow\n key={item.id}\n item={item}\n isActive={activeItemId === item.id}\n isCollapsed={isCollapsed}\n activeVariant={activeVariant}\n onClick={() => onNavigate?.(item.id)}\n />\n ))}\n </div>\n )}\n </div>\n )\n}\n\nexport function QuickActionSidebarNav({\n className,\n brandLabel = \"ACME CO\",\n brandSubtitle = \"Placeholder\",\n brandImage,\n hideQuickAction,\n navSections = DEFAULT_NAV_SECTIONS,\n activeItemId = \"inbox\",\n activeVariant = \"default\",\n onNavigate,\n user = DEFAULT_USER,\n userMenuItems = DEFAULT_USER_MENU,\n onUserMenuAction,\n onCreateTask,\n defaultCollapsed = false,\n quickActionTemplates,\n quickActionTitle,\n quickActionDescription,\n onQuickActionClick,\n ...props\n}: QuickActionSidebarNavProps) {\n const [isQuickActionOpen, setIsQuickActionOpen] = React.useState(false)\n const [isCollapsed, setIsCollapsed] = React.useState(defaultCollapsed)\n\n const initials =\n user.initials ??\n (user.name\n ? user.name.charAt(0).toUpperCase()\n : user.email\n ? user.email.charAt(0).toUpperCase()\n : \"U\")\n\n return (\n <TooltipProvider delayDuration={0}>\n <aside\n className={cn(\n \"flex h-full flex-col overflow-hidden bg-sidebar text-sidebar-foreground border-r border-sidebar-border transition-all duration-200\",\n isCollapsed ? \"w-16\" : \"w-64\",\n className,\n )}\n {...props}\n >\n {/* Header */}\n <div\n className={cn(\n \"relative flex shrink-0 items-center border-b border-sidebar-border\",\n isCollapsed ? \"justify-center h-16 px-2\" : \"px-6 py-4\",\n )}\n >\n {!isCollapsed && (\n <div className=\"flex items-center gap-2.5 pr-8\">\n {brandImage ? (\n <img src={brandImage} alt={brandLabel} className=\"h-10 object-contain\" />\n ) : (\n <>\n <div className=\"flex h-6 w-6 items-center justify-center rounded-full bg-sidebar-foreground text-sidebar\">\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" className=\"w-3.5 h-3.5\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n </svg>\n </div>\n <div className=\"flex flex-col gap-0.5\">\n <span className=\"text-sm font-bold tracking-tight\">\n {brandLabel}\n </span>\n {brandSubtitle && (\n <span className=\"text-[10px] font-medium text-sidebar-foreground/50 uppercase tracking-wide\">\n {brandSubtitle}\n </span>\n )}\n </div>\n </>\n )}\n </div>\n )}\n\n <button\n type=\"button\"\n onClick={() => setIsCollapsed(!isCollapsed)}\n className={cn(\n \"p-1.5 rounded-md text-sidebar-foreground/50 hover:text-sidebar-foreground hover:bg-sidebar-accent transition-colors\",\n isCollapsed ? \"\" : \"absolute right-5 top-1/2 -translate-y-1/2\",\n )}\n title={isCollapsed ? \"Expand sidebar\" : \"Collapse sidebar\"}\n >\n {isCollapsed ? (\n <PanelLeftOpen className=\"w-4 h-4\" />\n ) : (\n <PanelLeftClose className=\"w-4 h-4\" />\n )}\n </button>\n </div>\n\n {/* Navigation */}\n <div className=\"flex-1 overflow-y-auto overflow-x-hidden py-3 space-y-1\">\n {navSections.map((section, idx) => (\n <React.Fragment key={section.title ?? idx}>\n {idx > 0 && <div className=\"mx-4 my-2 border-t border-sidebar-border\" />}\n <NavSection\n section={section}\n activeItemId={activeItemId}\n isCollapsed={isCollapsed}\n activeVariant={activeVariant}\n onNavigate={onNavigate}\n />\n </React.Fragment>\n ))}\n </div>\n\n {!hideQuickAction && (\n <div className={cn(\"px-3 pb-3\", isCollapsed ? \"hidden\" : \"block\")}>\n <button\n type=\"button\"\n onClick={() => {\n if (onQuickActionClick) {\n onQuickActionClick();\n } else {\n setIsQuickActionOpen(true);\n }\n }}\n className=\"w-full flex items-center justify-between px-3 py-2.5 rounded-lg border border-sidebar-border bg-sidebar-primary text-sidebar-primary-foreground hover:bg-sidebar-primary/90 transition-colors group shadow-sm\"\n >\n <div className=\"flex items-center gap-2\">\n <svg\n className=\"w-4 h-4 text-sidebar-primary-foreground/80 group-hover:text-sidebar-primary-foreground transition-colors\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M13 10V3L4 14h7v7l9-11h-7z\"\n />\n </svg>\n <span className=\"text-sm font-medium\">Quick Action</span>\n </div>\n <kbd className=\"hidden sm:inline-flex items-center gap-0.5 px-1.5 py-0.5 text-[11px] font-mono rounded bg-sidebar-primary-foreground/20 text-sidebar-primary-foreground\">\n <span className=\"text-xs\">⌘</span>K\n </kbd>\n </button>\n </div>\n )}\n\n {isCollapsed && !hideQuickAction && (\n <div className=\"px-2 pb-3\">\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={() => {\n if (onQuickActionClick) {\n onQuickActionClick();\n } else {\n setIsQuickActionOpen(true);\n }\n }}\n className=\"flex w-full items-center justify-center rounded-lg bg-sidebar-primary p-2.5 text-sidebar-primary-foreground shadow-sm transition-colors hover:bg-sidebar-primary/90\"\n title=\"Quick Action (⌘K)\"\n >\n <svg\n className=\"w-5 h-5\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M13 10V3L4 14h7v7l9-11h-7z\"\n />\n </svg>\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"right\">Quick Action (⌘K)</TooltipContent>\n </Tooltip>\n </div>\n )}\n\n {/* User Profile Footer */}\n <div className=\"p-3 border-t border-sidebar-border shrink-0\">\n <DropdownMenu>\n <DropdownMenuTrigger\n className={cn(\n \"flex items-center w-full rounded-lg hover:bg-sidebar-accent transition-colors outline-none\",\n isCollapsed ? \"justify-center p-1\" : \"p-2 gap-3\",\n )}\n >\n <Avatar className=\"h-8 w-8 rounded-md\">\n {user.avatarUrl ? <AvatarImage src={user.avatarUrl} alt={user.name} className=\"rounded-md\" /> : null}\n <AvatarFallback className=\"rounded-md bg-primary/10 text-primary text-xs font-medium\">\n {initials}\n </AvatarFallback>\n </Avatar>\n\n {!isCollapsed && (\n <div className=\"flex flex-col items-start flex-1 truncate\">\n <span className=\"text-sm font-medium leading-none truncate\">\n {user.name}\n </span>\n <span className=\"text-xs text-sidebar-foreground/50 truncate mt-0.5\">\n {user.email}\n </span>\n </div>\n )}\n\n {!isCollapsed && (\n <MoreVertical className=\"w-4 h-4 text-sidebar-foreground/50 shrink-0\" />\n )}\n </DropdownMenuTrigger>\n\n <DropdownMenuContent align=\"end\" side=\"right\" sideOffset={8} className=\"w-56\">\n <DropdownMenuLabel className=\"font-normal\">\n <div className=\"flex flex-col space-y-1\">\n <p className=\"text-sm font-medium leading-none\">{user.name}</p>\n <p className=\"text-xs leading-none text-muted-foreground\">{user.email}</p>\n </div>\n </DropdownMenuLabel>\n <DropdownMenuSeparator />\n {userMenuItems.map((item, idx) => {\n const showSepBefore = item.destructive && idx > 0\n return (\n <React.Fragment key={item.id}>\n {showSepBefore && <DropdownMenuSeparator />}\n <DropdownMenuItem\n onClick={() => onUserMenuAction?.(item.id)}\n className={cn(\n \"cursor-pointer\",\n item.destructive && \"text-destructive focus:text-destructive\",\n )}\n >\n <item.icon className=\"mr-2 h-4 w-4\" />\n <span>{item.label}</span>\n </DropdownMenuItem>\n </React.Fragment>\n )\n })}\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n </aside>\n\n {!hideQuickAction && !onQuickActionClick && (\n <QuickActionModal\n open={isQuickActionOpen}\n onOpenChange={setIsQuickActionOpen}\n onCreateTask={onCreateTask}\n templates={quickActionTemplates}\n title={quickActionTitle}\n description={quickActionDescription}\n />\n )}\n </TooltipProvider>\n )\n}\n"],"mappings":"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","names":["_a"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@handled-ai/design-system",
|
|
3
|
-
"version": "0.18.
|
|
3
|
+
"version": "0.18.18",
|
|
4
4
|
"description": "Handled UI component library (shadcn-style, New York)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"packageManager": "pnpm@9.12.0",
|
|
@@ -155,6 +155,8 @@
|
|
|
155
155
|
},
|
|
156
156
|
"devDependencies": {
|
|
157
157
|
"@eslint/eslintrc": "^3.3.1",
|
|
158
|
+
"@nivo/core": "^0.99.0",
|
|
159
|
+
"@nivo/sankey": "^0.99.0",
|
|
158
160
|
"@react-three/drei": "^10.7.7",
|
|
159
161
|
"@react-three/fiber": "^9.5.0",
|
|
160
162
|
"@tailwindcss/postcss": "^4.1.11",
|
|
@@ -171,9 +173,11 @@
|
|
|
171
173
|
"eslint": "^9.32.0",
|
|
172
174
|
"eslint-config-next": "15.3.1",
|
|
173
175
|
"happy-dom": "^20.9.0",
|
|
176
|
+
"lucide-react": "^1.17.0",
|
|
174
177
|
"next": "15.5.9",
|
|
175
178
|
"react": "19.1.0",
|
|
176
179
|
"react-dom": "19.1.0",
|
|
180
|
+
"recharts": "^3.8.1",
|
|
177
181
|
"shadcn": "^3.0.0",
|
|
178
182
|
"tailwindcss": "^4.1.11",
|
|
179
183
|
"three": "^0.183.1",
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { render, screen, waitFor } from "@testing-library/react"
|
|
2
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"
|
|
3
|
+
|
|
4
|
+
import { QuickActionSidebarNav } from "../quick-action-sidebar-nav"
|
|
5
|
+
|
|
6
|
+
const baseUser = {
|
|
7
|
+
name: "Jane Smith",
|
|
8
|
+
email: "jane@example.com",
|
|
9
|
+
initials: "JS",
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Radix `AvatarImage` only mounts the underlying <img> once the image has
|
|
14
|
+
* successfully loaded. It probes the source by constructing a `new Image()`
|
|
15
|
+
* and listening for its `load` event. happy-dom never fires that event for a
|
|
16
|
+
* real network request, so we stub `Image` to immediately report success.
|
|
17
|
+
*/
|
|
18
|
+
describe("QuickActionSidebarNav footer avatar", () => {
|
|
19
|
+
beforeEach(() => {
|
|
20
|
+
class MockImage {
|
|
21
|
+
private listeners: Record<string, Array<() => void>> = {}
|
|
22
|
+
onload: (() => void) | null = null
|
|
23
|
+
onerror: (() => void) | null = null
|
|
24
|
+
referrerPolicy = ""
|
|
25
|
+
crossOrigin: string | null = null
|
|
26
|
+
private _src = ""
|
|
27
|
+
addEventListener(type: string, cb: () => void) {
|
|
28
|
+
;(this.listeners[type] ??= []).push(cb)
|
|
29
|
+
}
|
|
30
|
+
removeEventListener(type: string, cb: () => void) {
|
|
31
|
+
this.listeners[type] = (this.listeners[type] ?? []).filter((fn) => fn !== cb)
|
|
32
|
+
}
|
|
33
|
+
set src(value: string) {
|
|
34
|
+
this._src = value
|
|
35
|
+
// Simulate a successful async load.
|
|
36
|
+
queueMicrotask(() => {
|
|
37
|
+
this.onload?.()
|
|
38
|
+
for (const cb of this.listeners["load"] ?? []) cb()
|
|
39
|
+
})
|
|
40
|
+
}
|
|
41
|
+
get src() {
|
|
42
|
+
return this._src
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
vi.stubGlobal("Image", MockImage)
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
afterEach(() => {
|
|
49
|
+
vi.unstubAllGlobals()
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
it("renders an AvatarImage with the correct src when user.avatarUrl is provided", async () => {
|
|
53
|
+
const { container } = render(
|
|
54
|
+
<QuickActionSidebarNav user={{ ...baseUser, avatarUrl: "https://example.com/avatar.png" }} />
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
await waitFor(() => {
|
|
58
|
+
expect(container.querySelector('[data-slot="avatar-image"]')).not.toBeNull()
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
const image = container.querySelector('[data-slot="avatar-image"]')
|
|
62
|
+
expect(image?.getAttribute("src")).toBe("https://example.com/avatar.png")
|
|
63
|
+
expect(image?.getAttribute("alt")).toBe("Jane Smith")
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
it("renders no AvatarImage and shows initials when user.avatarUrl is undefined", () => {
|
|
67
|
+
const { container } = render(<QuickActionSidebarNav user={baseUser} />)
|
|
68
|
+
|
|
69
|
+
expect(container.querySelector('[data-slot="avatar-image"]')).toBeNull()
|
|
70
|
+
expect(screen.getByText("JS")).not.toBeNull()
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
it("renders no AvatarImage and shows initials when user.avatarUrl is null", () => {
|
|
74
|
+
const { container } = render(
|
|
75
|
+
<QuickActionSidebarNav user={{ ...baseUser, avatarUrl: null }} />
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
expect(container.querySelector('[data-slot="avatar-image"]')).toBeNull()
|
|
79
|
+
expect(screen.getByText("JS")).not.toBeNull()
|
|
80
|
+
})
|
|
81
|
+
})
|
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
} from "lucide-react"
|
|
23
23
|
|
|
24
24
|
import { cn } from "../lib/utils"
|
|
25
|
-
import { Avatar, AvatarFallback } from "./avatar"
|
|
25
|
+
import { Avatar, AvatarFallback, AvatarImage } from "./avatar"
|
|
26
26
|
import {
|
|
27
27
|
DropdownMenu,
|
|
28
28
|
DropdownMenuContent,
|
|
@@ -74,6 +74,7 @@ export interface SidebarUserProfile {
|
|
|
74
74
|
name: string
|
|
75
75
|
email: string
|
|
76
76
|
initials?: string
|
|
77
|
+
avatarUrl?: string | null
|
|
77
78
|
}
|
|
78
79
|
|
|
79
80
|
export interface UserMenuItem {
|
|
@@ -570,6 +571,7 @@ export function QuickActionSidebarNav({
|
|
|
570
571
|
)}
|
|
571
572
|
>
|
|
572
573
|
<Avatar className="h-8 w-8 rounded-md">
|
|
574
|
+
{user.avatarUrl ? <AvatarImage src={user.avatarUrl} alt={user.name} className="rounded-md" /> : null}
|
|
573
575
|
<AvatarFallback className="rounded-md bg-primary/10 text-primary text-xs font-medium">
|
|
574
576
|
{initials}
|
|
575
577
|
</AvatarFallback>
|