@devalok/shilp-sutra 0.43.0 → 0.44.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.
Files changed (90) hide show
  1. package/MIGRATION.md +46 -0
  2. package/dist/_chunks/chat.js +163 -162
  3. package/dist/_chunks/chat.js.map +1 -1
  4. package/dist/_chunks/mention-suggestion.js +34 -32
  5. package/dist/_chunks/mention-suggestion.js.map +1 -1
  6. package/dist/_chunks/oauth-button.js +102 -97
  7. package/dist/_chunks/oauth-button.js.map +1 -1
  8. package/dist/_chunks/tree-view.js +1 -1
  9. package/dist/_chunks/tree-view.js.map +1 -1
  10. package/dist/ai/command-bar.js.map +1 -1
  11. package/dist/composed/command-palette.js +3 -3
  12. package/dist/composed/command-palette.js.map +1 -1
  13. package/dist/composed/content-card.d.ts +6 -0
  14. package/dist/composed/content-card.d.ts.map +1 -1
  15. package/dist/composed/content-card.js.map +1 -1
  16. package/dist/composed/extensions/file-attachment.d.ts.map +1 -1
  17. package/dist/composed/file-preview/audio-preview.d.ts.map +1 -1
  18. package/dist/composed/file-preview.d.ts.map +1 -1
  19. package/dist/composed/file-preview.js +146 -142
  20. package/dist/composed/file-preview.js.map +1 -1
  21. package/dist/composed/filter-bar.js +5 -2
  22. package/dist/composed/filter-bar.js.map +1 -1
  23. package/dist/composed/master-detail.js +1 -1
  24. package/dist/composed/master-detail.js.map +1 -1
  25. package/dist/composed/page-header.js +1 -1
  26. package/dist/composed/page-header.js.map +1 -1
  27. package/dist/composed/rich-chat-input/attachment-strip.d.ts.map +1 -1
  28. package/dist/composed/rich-chat-input/audio-player.d.ts.map +1 -1
  29. package/dist/composed/rich-chat-input/schedule-send.d.ts.map +1 -1
  30. package/dist/composed/rich-chat-input.js +595 -586
  31. package/dist/composed/rich-chat-input.js.map +1 -1
  32. package/dist/composed/rich-text-editor.d.ts.map +1 -1
  33. package/dist/composed/rich-text-editor.js +164 -162
  34. package/dist/composed/rich-text-editor.js.map +1 -1
  35. package/dist/hooks/index.d.ts +2 -2
  36. package/dist/hooks/index.d.ts.map +1 -1
  37. package/dist/shell/notification-center.d.ts.map +1 -1
  38. package/dist/shell/notification-center.js +101 -97
  39. package/dist/shell/notification-center.js.map +1 -1
  40. package/dist/shell/sidebar.d.ts.map +1 -1
  41. package/dist/shell/sidebar.js +137 -122
  42. package/dist/shell/sidebar.js.map +1 -1
  43. package/dist/shell/top-bar.d.ts.map +1 -1
  44. package/dist/shell/top-bar.js +86 -83
  45. package/dist/shell/top-bar.js.map +1 -1
  46. package/dist/tokens/semantic.css +1 -0
  47. package/dist/ui/avatar.js +1 -1
  48. package/dist/ui/avatar.js.map +1 -1
  49. package/dist/ui/breadcrumb.js +2 -2
  50. package/dist/ui/breadcrumb.js.map +1 -1
  51. package/dist/ui/button.js.map +1 -1
  52. package/dist/ui/card.d.ts +82 -7
  53. package/dist/ui/card.d.ts.map +1 -1
  54. package/dist/ui/card.js +74 -108
  55. package/dist/ui/card.js.map +1 -1
  56. package/dist/ui/chat/message.d.ts.map +1 -1
  57. package/dist/ui/combobox.js +2 -2
  58. package/dist/ui/combobox.js.map +1 -1
  59. package/dist/ui/dropdown-menu.js +9 -3
  60. package/dist/ui/dropdown-menu.js.map +1 -1
  61. package/dist/ui/index.d.ts +2 -1
  62. package/dist/ui/index.d.ts.map +1 -1
  63. package/dist/ui/index.js +58 -57
  64. package/dist/ui/index.js.map +1 -1
  65. package/dist/ui/menubar.js +9 -3
  66. package/dist/ui/menubar.js.map +1 -1
  67. package/dist/ui/oauth-button/oauth-button.d.ts.map +1 -1
  68. package/dist/ui/select.js +5 -2
  69. package/dist/ui/select.js.map +1 -1
  70. package/dist/ui/sidebar.js +73 -73
  71. package/dist/ui/sidebar.js.map +1 -1
  72. package/dist/ui/stat-card.d.ts +8 -5
  73. package/dist/ui/stat-card.d.ts.map +1 -1
  74. package/dist/ui/stat-card.js +168 -150
  75. package/dist/ui/stat-card.js.map +1 -1
  76. package/dist/ui/tabs.d.ts.map +1 -1
  77. package/dist/ui/tabs.js +5 -2
  78. package/dist/ui/tabs.js.map +1 -1
  79. package/dist/ui/truncated-text.d.ts +37 -0
  80. package/dist/ui/truncated-text.d.ts.map +1 -0
  81. package/dist/ui/truncated-text.js +53 -0
  82. package/dist/ui/truncated-text.js.map +1 -0
  83. package/docs/components/ui/card.md +13 -4
  84. package/docs/components/ui/stat-card.md +7 -2
  85. package/docs/components/ui/truncated-text.md +49 -0
  86. package/llms-full.txt +70 -7
  87. package/make-kit/components/card.md +14 -4
  88. package/package.json +1 -1
  89. package/skill/SKILL.md +1 -1
  90. package/skill/references/components-full.md +70 -7
@@ -1 +1 @@
1
- {"version":3,"file":"sidebar.js","names":[],"sources":["../../src/shell/sidebar.tsx"],"sourcesContent":["'use client'\n\n/**\n * AppSidebar -- Application-layer sidebar built on the Sidebar primitive.\n *\n * Design-system token migration (2026-02-28):\n * All V1 colour tokens have been replaced with semantic design-system tokens.\n * Typography classes replaced with Tailwind equivalents.\n *\n * Props-driven: accepts user info, currentPath, and navItems instead of\n * reading from Remix hooks or Zustand stores.\n */\nimport * as React from 'react'\n\nimport { Avatar, AvatarFallback, AvatarImage } from '../ui/avatar'\nimport { IconProvider } from '../ui/icon-context'\nimport type { IconInput } from '../ui/lib/icon-input'\nimport { normalizeIcon } from '../ui/lib/normalize-icon'\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from '../ui/collapsible'\nimport { cn } from '../ui/lib/utils'\nimport {\n Sidebar as ShadcnSidebar,\n SidebarContent,\n SidebarFooter,\n SidebarGroup,\n SidebarGroupAction,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarHeader,\n SidebarMenu,\n SidebarMenuBadge,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n SidebarSeparator,\n} from '../ui/sidebar'\nimport { useLink } from './link-context'\n\n// -----------------------------------------------------------------------\n// Types\n// -----------------------------------------------------------------------\n\nexport interface NavSubItem {\n title: string\n href: string\n /** Optional icon. Accepts any `IconInput`. */\n icon?: IconInput\n exact?: boolean\n}\n\nexport interface NavItem {\n title: string\n href: string\n /** Icon for this nav item. Accepts any `IconInput`. */\n icon: IconInput\n /** When true, the route matches only when the path is exactly equal */\n exact?: boolean\n /** Badge rendered on the right side of the nav item */\n badge?: string | number\n /** Optional child items — renders as collapsible sub-list with chevron */\n children?: NavSubItem[]\n /** Whether the collapsible is open by default. Auto-opens when a child is active. */\n defaultOpen?: boolean\n}\n\nexport interface NavGroup {\n label: string\n items: NavItem[]\n /** Action rendered next to the group label (e.g., a \"+\" button) */\n action?: React.ReactNode\n}\n\nexport interface SidebarUser {\n name: string\n email?: string\n image?: string | null\n designation?: string\n role?: string\n}\n\nexport interface SidebarPromo {\n /** Promo message text */\n text: string\n /** Optional icon rendered before the text. Accepts any `IconInput`. */\n icon?: IconInput\n /** Action button rendered in the promo banner */\n action?: { label: string; href?: string; onClick?: () => void }\n /** When provided, renders a dismiss (X) button that calls this handler */\n onDismiss?: () => void\n}\n\nexport interface SidebarFooterConfig {\n /** Legal/utility links rendered as a row separated by dividers */\n links?: Array<{ label: string; href: string }>\n /** Version or build info text (or link) rendered inline after links */\n version?: string | { label: string; href: string }\n /** Custom content rendered above the links row */\n slot?: React.ReactNode\n /** Promo/upsell banner rendered above the links row */\n promo?: SidebarPromo\n}\n\nexport interface AppSidebarProps\n extends React.HTMLAttributes<HTMLDivElement> {\n /** Currently active pathname -- used to highlight the active nav item */\n currentPath?: string\n /** User information displayed in the sidebar header */\n user?: SidebarUser | null\n /** Primary navigation groups rendered in the main content area */\n navGroups?: NavGroup[]\n /** Optional logo element. Falls back to a text placeholder. */\n logo?: React.ReactNode\n /** Footer links rendered at the bottom of the sidebar */\n footerLinks?: Array<{ label: string; href: string }>\n /** Structured footer config (takes precedence over footerLinks) */\n footer?: SidebarFooterConfig\n /** Content rendered between user header and navigation */\n headerSlot?: React.ReactNode\n /** Content rendered between navigation and footer */\n preFooterSlot?: React.ReactNode\n /** className applied to the wrapper div around preFooterSlot */\n preFooterClassName?: string\n /** Override rendering for specific nav items. Return null to use default rendering. */\n renderItem?: (item: NavItem, defaultRender: () => React.ReactNode) => React.ReactNode | null\n /** Additional className for the root sidebar element */\n className?: string\n /**\n * Corner radius of nav items (composable). @default 'md' (control radius, ~6px).\n * `'lg'` restores the previous rounder look; `'sm'` is tighter; `'pill'` is fully rounded.\n * Sets the `--ds-sidebar-item-radius` CSS var, so you can also override it via `className`/`style`.\n */\n navItemRadius?: 'sm' | 'md' | 'lg' | 'pill'\n}\n\n// -----------------------------------------------------------------------\n// ChevronRight (inline SVG icon for collapsible toggle)\n// -----------------------------------------------------------------------\n\nfunction ChevronRight({ className }: { className?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n >\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n )\n}\n\nfunction CloseIcon({ className }: { className?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n )\n}\n\n// -----------------------------------------------------------------------\n// Shared styles\n// -----------------------------------------------------------------------\n\n// Radius is composable via the `navItemRadius` prop (sets --ds-sidebar-item-radius).\n// Default is the control radius (~6px) — surface (10px) read as over-rounded blobs.\nconst navItemBase =\n 'relative gap-ds-04 rounded-[var(--ds-sidebar-item-radius,var(--radius-control))] px-ds-04 py-ds-03 transition-colors duration-fast-02'\nconst NAV_ITEM_RADIUS = {\n sm: 'var(--radius-control-inner)',\n md: 'var(--radius-control)',\n lg: 'var(--radius-surface)',\n pill: 'var(--radius-pill)',\n} as const\n// Active = tinted surface + accent text + weight. No accent rail — the tint and\n// colour already signal \"you are here\"; a stripe on top is doubled accent (AI tell).\nconst navItemActive = 'bg-accent-2 text-accent-11 font-medium'\nconst navItemInactive = 'text-surface-fg-subtle hover:bg-surface-raised-hover hover:text-surface-fg'\n\n// -----------------------------------------------------------------------\n// NavLink (internal)\n// -----------------------------------------------------------------------\n\nfunction NavLink({\n item,\n isActive,\n isPathActive,\n}: {\n item: NavItem\n isActive: boolean\n isPathActive: (path: string, exact?: boolean) => boolean\n}) {\n const Link = useLink()\n const badgeContent =\n item.badge != null\n ? typeof item.badge === 'number' && item.badge > 99\n ? '99+'\n : String(item.badge)\n : null\n\n // S9: Collapsible children\n if (item.children && item.children.length > 0) {\n const hasActiveChild = item.children.some((child) =>\n isPathActive(child.href, child.exact),\n )\n const shouldOpen = hasActiveChild || isActive || (item.defaultOpen ?? false)\n\n return (\n <Collapsible defaultOpen={shouldOpen} className=\"group/collapsible\">\n <SidebarMenuItem>\n {/* Button row — chevron is anchored here, not on the full <li> */}\n <div className=\"relative\">\n <SidebarMenuButton\n asChild\n isActive={isActive || hasActiveChild}\n tooltip={item.title}\n className={cn(\n navItemBase,\n isActive || hasActiveChild ? navItemActive : navItemInactive,\n )}\n >\n <Link\n href={item.href}\n aria-label={item.title}\n aria-current={isActive ? 'page' : undefined}\n >\n <span className=\"[&>svg]:h-ico-md [&>svg]:w-ico-md shrink-0\" aria-hidden=\"true\">\n <IconProvider size=\"md\">{normalizeIcon(item.icon)}</IconProvider>\n </span>\n <span className=\"text-ds-base\">{item.title}</span>\n </Link>\n </SidebarMenuButton>\n {badgeContent && <SidebarMenuBadge>{badgeContent}</SidebarMenuBadge>}\n <CollapsibleTrigger asChild>\n <button\n className=\"absolute right-ds-02 top-1/2 flex h-5 w-5 -translate-y-1/2 items-center justify-center rounded-control text-surface-fg-subtle transition-colors hover:bg-surface-raised-hover hover:text-surface-fg group-data-[collapsible=icon]:hidden\"\n aria-label={`Toggle ${item.title}`}\n >\n <ChevronRight className=\"h-4 w-4 transition-transform duration-fast-02 ease-productive-standard group-data-[state=open]/collapsible:rotate-90\" />\n </button>\n </CollapsibleTrigger>\n </div>\n <CollapsibleContent>\n <SidebarMenuSub>\n {item.children.map((child) => {\n const childActive = isPathActive(child.href, child.exact)\n return (\n <SidebarMenuSubItem key={child.href}>\n <SidebarMenuSubButton\n asChild\n isActive={childActive}\n >\n <Link\n href={child.href}\n aria-current={childActive ? 'page' : undefined}\n >\n {child.icon && (\n <span className=\"[&>svg]:h-ico-sm [&>svg]:w-ico-sm shrink-0\" aria-hidden=\"true\">\n <IconProvider size=\"sm\">{normalizeIcon(child.icon)}</IconProvider>\n </span>\n )}\n <span>{child.title}</span>\n </Link>\n </SidebarMenuSubButton>\n </SidebarMenuSubItem>\n )\n })}\n </SidebarMenuSub>\n </CollapsibleContent>\n </SidebarMenuItem>\n </Collapsible>\n )\n }\n\n // Default: flat nav item\n return (\n <SidebarMenuItem>\n <SidebarMenuButton\n asChild\n isActive={isActive}\n tooltip={item.title}\n className={cn(\n navItemBase,\n isActive ? navItemActive : navItemInactive,\n )}\n >\n <Link\n href={item.href}\n aria-label={item.title}\n aria-current={isActive ? 'page' : undefined}\n >\n <span className=\"[&>svg]:h-ico-md [&>svg]:w-ico-md shrink-0\" aria-hidden=\"true\"><IconProvider size=\"md\">{normalizeIcon(item.icon)}</IconProvider></span>\n <span className=\"text-ds-base\">{item.title}</span>\n </Link>\n </SidebarMenuButton>\n {badgeContent && <SidebarMenuBadge>{badgeContent}</SidebarMenuBadge>}\n </SidebarMenuItem>\n )\n}\n\n// -----------------------------------------------------------------------\n// AppSidebar\n// -----------------------------------------------------------------------\n\nconst AppSidebar = React.forwardRef<HTMLDivElement, AppSidebarProps>(\n (\n {\n currentPath = '/',\n user,\n navGroups = [],\n logo,\n headerSlot,\n preFooterSlot,\n preFooterClassName,\n footerLinks = [],\n footer,\n renderItem,\n className,\n navItemRadius,\n style,\n ...props\n },\n ref,\n ) => {\n const Link = useLink()\n const isActive = (path: string, exact = false) => {\n if (exact || path === '/') {\n return currentPath === path\n }\n return currentPath.startsWith(path)\n }\n\n return (\n <ShadcnSidebar\n {...props}\n ref={ref}\n aria-label=\"Main navigation\"\n style={\n navItemRadius\n ? ({ '--ds-sidebar-item-radius': NAV_ITEM_RADIUS[navItemRadius], ...style } as React.CSSProperties)\n : style\n }\n className={cn(\n 'z-raised hidden h-full flex-col border-r border-surface-border-strong bg-surface-raised md:flex',\n className,\n )}\n >\n {/* Logo Header */}\n <SidebarHeader className=\"px-ds-06 py-ds-06\">\n {logo ?? (\n <span className=\"text-ds-lg font-semibold text-surface-fg\">\n Logo\n </span>\n )}\n </SidebarHeader>\n\n {/* User Info */}\n {user && (\n <div className=\"flex items-center gap-ds-04 px-ds-06 pb-ds-05\">\n <Avatar className=\"h-ds-sm-plus w-ds-sm-plus\">\n {user.image ? (\n <AvatarImage src={user.image} alt={user.name} />\n ) : null}\n <AvatarFallback className=\"bg-surface-raised-hover text-surface-fg\">\n {user.name?.charAt(0).toUpperCase()}\n </AvatarFallback>\n </Avatar>\n <div className=\"flex min-w-0 flex-col\">\n <span className=\"truncate text-ds-md text-surface-fg\">\n {user.name}\n </span>\n <span className=\"truncate text-ds-sm text-surface-fg-subtle\">\n {user.designation || user.role}\n </span>\n </div>\n </div>\n )}\n\n <SidebarSeparator />\n\n {/* Header Slot (S13) */}\n {headerSlot && (\n <>\n {headerSlot}\n <SidebarSeparator />\n </>\n )}\n\n {/* Navigation Groups */}\n <SidebarContent className=\"no-scrollbar px-ds-04\">\n {navGroups.map((group, idx) => (\n <div key={group.label}>\n {idx > 0 && <SidebarSeparator />}\n <SidebarGroup>\n <SidebarGroupLabel className=\"px-ds-04 text-ds-sm text-surface-fg-subtle\">\n {group.label}\n </SidebarGroupLabel>\n {group.action && (\n <SidebarGroupAction asChild>{group.action}</SidebarGroupAction>\n )}\n <SidebarGroupContent>\n <SidebarMenu>\n {group.items.map((item) => {\n const defaultRender = () => (\n <NavLink\n item={item}\n isActive={isActive(item.href, item.exact)}\n isPathActive={isActive}\n />\n )\n\n if (renderItem) {\n const custom = renderItem(item, defaultRender)\n if (custom !== null) {\n return <React.Fragment key={item.href}>{custom}</React.Fragment>\n }\n }\n\n return <React.Fragment key={item.href}>{defaultRender()}</React.Fragment>\n })}\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n </div>\n ))}\n </SidebarContent>\n\n {/* Pre-Footer Slot (S13) */}\n {preFooterSlot && (\n <>\n <SidebarSeparator />\n <div className={preFooterClassName}>\n {preFooterSlot}\n </div>\n </>\n )}\n\n {/* Footer */}\n {footer ? (\n <SidebarFooter className=\"gap-ds-03 px-ds-06 py-ds-05\">\n {footer.slot && <div>{footer.slot}</div>}\n\n {/* Promo banner */}\n {footer.promo && (\n <div className=\"relative rounded-surface bg-surface-raised p-ds-04 shadow-raised\">\n {footer.promo.onDismiss && (\n <button\n onClick={footer.promo.onDismiss}\n aria-label=\"Dismiss\"\n className=\"absolute right-ds-02 top-ds-02 flex h-5 w-5 items-center justify-center rounded-control text-surface-fg-subtle transition-colors hover:bg-surface-raised-hover hover:text-surface-fg\"\n >\n <CloseIcon className=\"h-3.5 w-3.5\" />\n </button>\n )}\n <div className=\"flex flex-col gap-ds-03\">\n {footer.promo.icon && (\n <span className=\"text-accent-11 [&>svg]:h-ico-md [&>svg]:w-ico-md\" aria-hidden=\"true\">\n <IconProvider size=\"md\">{normalizeIcon(footer.promo.icon)}</IconProvider>\n </span>\n )}\n <div className=\"flex min-w-0 flex-col gap-ds-03\">\n <p className=\"text-ds-sm text-surface-fg\">{footer.promo.text}</p>\n {footer.promo.action && (\n footer.promo.action.href ? (\n <Link\n href={footer.promo.action.href}\n onClick={footer.promo.action.onClick}\n className=\"inline-flex self-start rounded-control bg-accent-9 px-ds-04 py-ds-02 text-ds-sm font-medium text-accent-fg transition-colors hover:bg-accent-10\"\n >\n {footer.promo.action.label}\n </Link>\n ) : (\n <button\n onClick={footer.promo.action.onClick}\n className=\"inline-flex self-start rounded-control bg-accent-9 px-ds-04 py-ds-02 text-ds-sm font-medium text-accent-fg transition-colors hover:bg-accent-10\"\n >\n {footer.promo.action.label}\n </button>\n )\n )}\n </div>\n </div>\n </div>\n )}\n\n {/* Links + version on same line */}\n {(footer.links?.length || footer.version) && (\n <div className=\"flex items-center gap-ds-03 text-ds-sm text-surface-fg-subtle\">\n {footer.links?.map((link, i) => (\n <React.Fragment key={link.href}>\n {i > 0 && <span>·</span>}\n <Link\n className=\"transition-colors hover:text-accent-11\"\n href={link.href}\n >\n {link.label}\n </Link>\n </React.Fragment>\n ))}\n {footer.links?.length && footer.version && <span>·</span>}\n {footer.version && (\n typeof footer.version === 'string'\n ? <span>{footer.version}</span>\n : <Link className=\"transition-colors hover:text-accent-11\" href={footer.version.href}>{footer.version.label}</Link>\n )}\n </div>\n )}\n </SidebarFooter>\n ) : footerLinks.length > 0 ? (\n <SidebarFooter className=\"px-ds-06 py-ds-05\">\n <div className=\"flex items-center gap-ds-03 text-ds-sm text-surface-fg-subtle\">\n {footerLinks.map((link, i) => (\n <React.Fragment key={link.href}>\n {i > 0 && <span>·</span>}\n <Link\n className=\"transition-colors hover:text-accent-11\"\n href={link.href}\n >\n {link.label}\n </Link>\n </React.Fragment>\n ))}\n </div>\n </SidebarFooter>\n ) : null}\n </ShadcnSidebar>\n )\n },\n)\nAppSidebar.displayName = 'AppSidebar'\n\nexport { AppSidebar }\n"],"mappings":"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"}
1
+ {"version":3,"file":"sidebar.js","names":[],"sources":["../../src/shell/sidebar.tsx"],"sourcesContent":["'use client'\n\n/**\n * AppSidebar -- Application-layer sidebar built on the Sidebar primitive.\n *\n * Design-system token migration (2026-02-28):\n * All V1 colour tokens have been replaced with semantic design-system tokens.\n * Typography classes replaced with Tailwind equivalents.\n *\n * Props-driven: accepts user info, currentPath, and navItems instead of\n * reading from Remix hooks or Zustand stores.\n */\nimport * as React from 'react'\n\nimport { Avatar, AvatarFallback, AvatarImage } from '../ui/avatar'\nimport { Button } from '../ui/button'\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from '../ui/collapsible'\nimport { IconProvider } from '../ui/icon-context'\nimport type { IconInput } from '../ui/lib/icon-input'\nimport { normalizeIcon } from '../ui/lib/normalize-icon'\nimport { cn } from '../ui/lib/utils'\nimport {\n Sidebar as ShadcnSidebar,\n SidebarContent,\n SidebarFooter,\n SidebarGroup,\n SidebarGroupAction,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarHeader,\n SidebarMenu,\n SidebarMenuBadge,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n SidebarSeparator,\n} from '../ui/sidebar'\nimport { TruncatedText } from '../ui/truncated-text'\nimport { useLink } from './link-context'\n\n// -----------------------------------------------------------------------\n// Types\n// -----------------------------------------------------------------------\n\nexport interface NavSubItem {\n title: string\n href: string\n /** Optional icon. Accepts any `IconInput`. */\n icon?: IconInput\n exact?: boolean\n}\n\nexport interface NavItem {\n title: string\n href: string\n /** Icon for this nav item. Accepts any `IconInput`. */\n icon: IconInput\n /** When true, the route matches only when the path is exactly equal */\n exact?: boolean\n /** Badge rendered on the right side of the nav item */\n badge?: string | number\n /** Optional child items — renders as collapsible sub-list with chevron */\n children?: NavSubItem[]\n /** Whether the collapsible is open by default. Auto-opens when a child is active. */\n defaultOpen?: boolean\n}\n\nexport interface NavGroup {\n label: string\n items: NavItem[]\n /** Action rendered next to the group label (e.g., a \"+\" button) */\n action?: React.ReactNode\n}\n\nexport interface SidebarUser {\n name: string\n email?: string\n image?: string | null\n designation?: string\n role?: string\n}\n\nexport interface SidebarPromo {\n /** Promo message text */\n text: string\n /** Optional icon rendered before the text. Accepts any `IconInput`. */\n icon?: IconInput\n /** Action button rendered in the promo banner */\n action?: { label: string; href?: string; onClick?: () => void }\n /** When provided, renders a dismiss (X) button that calls this handler */\n onDismiss?: () => void\n}\n\nexport interface SidebarFooterConfig {\n /** Legal/utility links rendered as a row separated by dividers */\n links?: Array<{ label: string; href: string }>\n /** Version or build info text (or link) rendered inline after links */\n version?: string | { label: string; href: string }\n /** Custom content rendered above the links row */\n slot?: React.ReactNode\n /** Promo/upsell banner rendered above the links row */\n promo?: SidebarPromo\n}\n\nexport interface AppSidebarProps\n extends React.HTMLAttributes<HTMLDivElement> {\n /** Currently active pathname -- used to highlight the active nav item */\n currentPath?: string\n /** User information displayed in the sidebar header */\n user?: SidebarUser | null\n /** Primary navigation groups rendered in the main content area */\n navGroups?: NavGroup[]\n /** Optional logo element. Falls back to a text placeholder. */\n logo?: React.ReactNode\n /** Footer links rendered at the bottom of the sidebar */\n footerLinks?: Array<{ label: string; href: string }>\n /** Structured footer config (takes precedence over footerLinks) */\n footer?: SidebarFooterConfig\n /** Content rendered between user header and navigation */\n headerSlot?: React.ReactNode\n /** Content rendered between navigation and footer */\n preFooterSlot?: React.ReactNode\n /** className applied to the wrapper div around preFooterSlot */\n preFooterClassName?: string\n /** Override rendering for specific nav items. Return null to use default rendering. */\n renderItem?: (item: NavItem, defaultRender: () => React.ReactNode) => React.ReactNode | null\n /** Additional className for the root sidebar element */\n className?: string\n /**\n * Corner radius of nav items (composable). @default 'md' (control radius, ~6px).\n * `'lg'` restores the previous rounder look; `'sm'` is tighter; `'pill'` is fully rounded.\n * Sets the `--ds-sidebar-item-radius` CSS var, so you can also override it via `className`/`style`.\n */\n navItemRadius?: 'sm' | 'md' | 'lg' | 'pill'\n}\n\n// -----------------------------------------------------------------------\n// ChevronRight (inline SVG icon for collapsible toggle)\n// -----------------------------------------------------------------------\n\nfunction ChevronRight({ className }: { className?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n >\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n )\n}\n\nfunction CloseIcon({ className }: { className?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n )\n}\n\n// -----------------------------------------------------------------------\n// Shared styles\n// -----------------------------------------------------------------------\n\n// Radius is composable via the `navItemRadius` prop (sets --ds-sidebar-item-radius).\n// Default is the control radius (~6px) — surface (10px) read as over-rounded blobs.\nconst navItemBase =\n 'relative gap-ds-04 rounded-[var(--ds-sidebar-item-radius,var(--radius-control))] px-ds-04 py-ds-03 transition-colors duration-fast-02'\nconst NAV_ITEM_RADIUS = {\n sm: 'var(--radius-control-inner)',\n md: 'var(--radius-control)',\n lg: 'var(--radius-surface)',\n pill: 'var(--radius-pill)',\n} as const\n// Active = tinted surface + accent text + weight. No accent rail — the tint and\n// colour already signal \"you are here\"; a stripe on top is doubled accent (AI tell).\nconst navItemActive = 'bg-accent-2 text-accent-11 font-medium'\nconst navItemInactive = 'text-surface-fg-subtle hover:bg-surface-raised-hover hover:text-surface-fg'\n\n// -----------------------------------------------------------------------\n// NavLink (internal)\n// -----------------------------------------------------------------------\n\nfunction NavLink({\n item,\n isActive,\n isPathActive,\n}: {\n item: NavItem\n isActive: boolean\n isPathActive: (path: string, exact?: boolean) => boolean\n}) {\n const Link = useLink()\n const badgeContent =\n item.badge != null\n ? typeof item.badge === 'number' && item.badge > 99\n ? '99+'\n : String(item.badge)\n : null\n\n // S9: Collapsible children\n if (item.children && item.children.length > 0) {\n const hasActiveChild = item.children.some((child) =>\n isPathActive(child.href, child.exact),\n )\n const shouldOpen = hasActiveChild || isActive || (item.defaultOpen ?? false)\n\n return (\n <Collapsible defaultOpen={shouldOpen} className=\"group/collapsible\">\n <SidebarMenuItem>\n {/* Button row — chevron is anchored here, not on the full <li> */}\n <div className=\"relative\">\n <SidebarMenuButton\n asChild\n isActive={isActive || hasActiveChild}\n tooltip={item.title}\n className={cn(\n navItemBase,\n isActive || hasActiveChild ? navItemActive : navItemInactive,\n )}\n >\n <Link\n href={item.href}\n aria-label={item.title}\n aria-current={isActive ? 'page' : undefined}\n className=\"min-w-0\"\n >\n <span className=\"[&>svg]:h-ico-md [&>svg]:w-ico-md shrink-0\" aria-hidden=\"true\">\n <IconProvider size=\"md\">{normalizeIcon(item.icon)}</IconProvider>\n </span>\n <span className=\"text-ds-base truncate\">{item.title}</span>\n </Link>\n </SidebarMenuButton>\n {badgeContent && <SidebarMenuBadge>{badgeContent}</SidebarMenuBadge>}\n <CollapsibleTrigger asChild>\n <button\n className=\"absolute right-ds-02 top-1/2 flex h-5 w-5 -translate-y-1/2 items-center justify-center rounded-control text-surface-fg-subtle transition-colors hover:bg-surface-raised-hover hover:text-surface-fg group-data-[collapsible=icon]:hidden\"\n aria-label={`Toggle ${item.title}`}\n >\n <ChevronRight className=\"h-4 w-4 transition-transform duration-fast-02 ease-productive-standard group-data-[state=open]/collapsible:rotate-90\" />\n </button>\n </CollapsibleTrigger>\n </div>\n <CollapsibleContent>\n <SidebarMenuSub>\n {item.children.map((child) => {\n const childActive = isPathActive(child.href, child.exact)\n return (\n <SidebarMenuSubItem key={child.href}>\n <SidebarMenuSubButton\n asChild\n isActive={childActive}\n >\n <Link\n href={child.href}\n aria-current={childActive ? 'page' : undefined}\n className=\"min-w-0\"\n >\n {child.icon && (\n <span className=\"[&>svg]:h-ico-sm [&>svg]:w-ico-sm shrink-0\" aria-hidden=\"true\">\n <IconProvider size=\"sm\">{normalizeIcon(child.icon)}</IconProvider>\n </span>\n )}\n <span className=\"truncate\">{child.title}</span>\n </Link>\n </SidebarMenuSubButton>\n </SidebarMenuSubItem>\n )\n })}\n </SidebarMenuSub>\n </CollapsibleContent>\n </SidebarMenuItem>\n </Collapsible>\n )\n }\n\n // Default: flat nav item\n return (\n <SidebarMenuItem>\n <SidebarMenuButton\n asChild\n isActive={isActive}\n tooltip={item.title}\n className={cn(\n navItemBase,\n isActive ? navItemActive : navItemInactive,\n )}\n >\n <Link\n href={item.href}\n aria-label={item.title}\n aria-current={isActive ? 'page' : undefined}\n className=\"min-w-0\"\n >\n <span className=\"[&>svg]:h-ico-md [&>svg]:w-ico-md shrink-0\" aria-hidden=\"true\"><IconProvider size=\"md\">{normalizeIcon(item.icon)}</IconProvider></span>\n <span className=\"text-ds-base truncate\">{item.title}</span>\n </Link>\n </SidebarMenuButton>\n {badgeContent && <SidebarMenuBadge>{badgeContent}</SidebarMenuBadge>}\n </SidebarMenuItem>\n )\n}\n\n// -----------------------------------------------------------------------\n// AppSidebar\n// -----------------------------------------------------------------------\n\nconst AppSidebar = React.forwardRef<HTMLDivElement, AppSidebarProps>(\n (\n {\n currentPath = '/',\n user,\n navGroups = [],\n logo,\n headerSlot,\n preFooterSlot,\n preFooterClassName,\n footerLinks = [],\n footer,\n renderItem,\n className,\n navItemRadius,\n style,\n ...props\n },\n ref,\n ) => {\n const Link = useLink()\n const isActive = (path: string, exact = false) => {\n if (exact || path === '/') {\n return currentPath === path\n }\n return currentPath.startsWith(path)\n }\n\n return (\n <ShadcnSidebar\n {...props}\n ref={ref}\n aria-label=\"Main navigation\"\n style={\n navItemRadius\n ? ({ '--ds-sidebar-item-radius': NAV_ITEM_RADIUS[navItemRadius], ...style } as React.CSSProperties)\n : style\n }\n className={cn(\n 'z-raised hidden h-full flex-col border-r border-surface-border-strong bg-surface-raised md:flex',\n className,\n )}\n >\n {/* Logo Header */}\n <SidebarHeader className=\"px-ds-06 py-ds-06\">\n {logo ?? (\n <span className=\"text-ds-lg font-semibold text-surface-fg\">\n Logo\n </span>\n )}\n </SidebarHeader>\n\n {/* User Info */}\n {user && (\n <div className=\"flex items-center gap-ds-04 px-ds-06 pb-ds-05\">\n <Avatar className=\"h-ds-sm-plus w-ds-sm-plus\">\n {user.image ? (\n <AvatarImage src={user.image} alt={user.name} />\n ) : null}\n <AvatarFallback className=\"bg-surface-raised-hover text-surface-fg\">\n {user.name?.charAt(0).toUpperCase()}\n </AvatarFallback>\n </Avatar>\n <div className=\"flex min-w-0 flex-col\">\n <TruncatedText className=\"text-ds-md text-surface-fg\">\n {user.name ?? ''}\n </TruncatedText>\n <TruncatedText className=\"text-ds-sm text-surface-fg-subtle\">\n {user.designation || user.role || ''}\n </TruncatedText>\n </div>\n </div>\n )}\n\n <SidebarSeparator />\n\n {/* Header Slot (S13) */}\n {headerSlot && (\n <>\n {headerSlot}\n <SidebarSeparator />\n </>\n )}\n\n {/* Navigation Groups */}\n <SidebarContent className=\"no-scrollbar px-ds-04\">\n {navGroups.map((group, idx) => (\n <div key={group.label}>\n {idx > 0 && <SidebarSeparator />}\n <SidebarGroup>\n <SidebarGroupLabel className=\"px-ds-04 text-ds-sm text-surface-fg-subtle\">\n {group.label}\n </SidebarGroupLabel>\n {group.action && (\n <SidebarGroupAction asChild>{group.action}</SidebarGroupAction>\n )}\n <SidebarGroupContent>\n <SidebarMenu>\n {group.items.map((item) => {\n const defaultRender = () => (\n <NavLink\n item={item}\n isActive={isActive(item.href, item.exact)}\n isPathActive={isActive}\n />\n )\n\n if (renderItem) {\n const custom = renderItem(item, defaultRender)\n if (custom !== null) {\n return <React.Fragment key={item.href}>{custom}</React.Fragment>\n }\n }\n\n return <React.Fragment key={item.href}>{defaultRender()}</React.Fragment>\n })}\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n </div>\n ))}\n </SidebarContent>\n\n {/* Pre-Footer Slot (S13) */}\n {preFooterSlot && (\n <>\n <SidebarSeparator />\n <div className={preFooterClassName}>\n {preFooterSlot}\n </div>\n </>\n )}\n\n {/* Footer */}\n {footer ? (\n <SidebarFooter className=\"gap-ds-03 px-ds-06 py-ds-05\">\n {footer.slot && <div>{footer.slot}</div>}\n\n {/* Promo banner */}\n {footer.promo && (\n <div className=\"relative rounded-surface bg-surface-raised p-ds-04 shadow-raised\">\n {footer.promo.onDismiss && (\n <button\n onClick={footer.promo.onDismiss}\n aria-label=\"Dismiss\"\n className=\"absolute right-ds-02 top-ds-02 flex h-5 w-5 items-center justify-center rounded-control text-surface-fg-subtle transition-colors hover:bg-surface-raised-hover hover:text-surface-fg\"\n >\n <CloseIcon className=\"h-3.5 w-3.5\" />\n </button>\n )}\n <div className=\"flex flex-col gap-ds-03\">\n {footer.promo.icon && (\n <span className=\"text-accent-11 [&>svg]:h-ico-md [&>svg]:w-ico-md\" aria-hidden=\"true\">\n <IconProvider size=\"md\">{normalizeIcon(footer.promo.icon)}</IconProvider>\n </span>\n )}\n <div className=\"flex min-w-0 flex-col gap-ds-03\">\n <p className=\"text-ds-sm text-surface-fg line-clamp-2\">{footer.promo.text}</p>\n {footer.promo.action && (\n footer.promo.action.href ? (\n <Button asChild variant=\"solid\" size=\"sm\" className=\"self-start\">\n <Link\n href={footer.promo.action.href}\n onClick={footer.promo.action.onClick}\n >\n {footer.promo.action.label}\n </Link>\n </Button>\n ) : (\n <Button\n variant=\"solid\"\n size=\"sm\"\n className=\"self-start\"\n onClick={footer.promo.action.onClick}\n >\n {footer.promo.action.label}\n </Button>\n )\n )}\n </div>\n </div>\n </div>\n )}\n\n {/* Links + version on same line */}\n {(footer.links?.length || footer.version) && (\n <div className=\"flex items-center gap-ds-03 text-ds-sm text-surface-fg-subtle\">\n {footer.links?.map((link, i) => (\n <React.Fragment key={link.href}>\n {i > 0 && <span>·</span>}\n <Link\n className=\"transition-colors hover:text-accent-11\"\n href={link.href}\n >\n {link.label}\n </Link>\n </React.Fragment>\n ))}\n {footer.links?.length && footer.version && <span>·</span>}\n {footer.version && (\n typeof footer.version === 'string'\n ? <span>{footer.version}</span>\n : <Link className=\"transition-colors hover:text-accent-11\" href={footer.version.href}>{footer.version.label}</Link>\n )}\n </div>\n )}\n </SidebarFooter>\n ) : footerLinks.length > 0 ? (\n <SidebarFooter className=\"px-ds-06 py-ds-05\">\n <div className=\"flex items-center gap-ds-03 text-ds-sm text-surface-fg-subtle\">\n {footerLinks.map((link, i) => (\n <React.Fragment key={link.href}>\n {i > 0 && <span>·</span>}\n <Link\n className=\"transition-colors hover:text-accent-11\"\n href={link.href}\n >\n {link.label}\n </Link>\n </React.Fragment>\n ))}\n </div>\n </SidebarFooter>\n ) : null}\n </ShadcnSidebar>\n )\n },\n)\nAppSidebar.displayName = 'AppSidebar'\n\nexport { AppSidebar }\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"top-bar.d.ts","sourceRoot":"","sources":["../../src/shell/top-bar.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAa9B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAarD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,oBAAoB;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,8CAA8C;IAC9C,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,2CAA2C;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,2BAA2B;IAC3B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,0CAA0C;IAC1C,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,sEAAsE;IACtE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,+DAA+D;IAC/D,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;IACxB,mCAAmC;IACnC,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAMD,UAAU,eAAgB,SAAQ,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC;IACjE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAgCD,UAAU,eAAgB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IACpE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B;AAmBD,UAAU,iBAAkB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IACtE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B;AAmBD,UAAU,gBAAiB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IACrE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B;AAmBD,QAAA,MAAM,MAAM;;;;CAIF,CAAA;AAEV,UAAU,kBAAmB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IACvE,GAAG,CAAC,EAAE,MAAM,OAAO,MAAM,CAAA;IACzB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B;AAmBD,UAAU,qBACR,SAAQ,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC;IACrD,IAAI,EAAE,SAAS,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;CAChB;AAkCD,UAAU,gBAAiB,SAAQ,KAAK,CAAC,cAAc,CAAC,kBAAkB,CAAC;IACzE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B;AAsBD,UAAU,mBAAmB;IAC3B,IAAI,EAAE,UAAU,CAAA;IAChB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IACnC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,aAAa,CAAC,EAAE,YAAY,EAAE,CAAA;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAiJD,MAAM,MAAM,WAAW,GAAG,eAAe,CAAA;AAEzC,QAAA,MAAM,MAAM;;;;;;;;CAQV,CAAA;AAEF,OAAO,EAAE,MAAM,EAAE,CAAA"}
1
+ {"version":3,"file":"top-bar.d.ts","sourceRoot":"","sources":["../../src/shell/top-bar.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAa9B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAcrD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,oBAAoB;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,8CAA8C;IAC9C,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,2CAA2C;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,2BAA2B;IAC3B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,0CAA0C;IAC1C,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,sEAAsE;IACtE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,+DAA+D;IAC/D,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;IACxB,mCAAmC;IACnC,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAMD,UAAU,eAAgB,SAAQ,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC;IACjE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAgCD,UAAU,eAAgB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IACpE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B;AAmBD,UAAU,iBAAkB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IACtE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B;AAmBD,UAAU,gBAAiB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IACrE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B;AAmBD,QAAA,MAAM,MAAM;;;;CAIF,CAAA;AAEV,UAAU,kBAAmB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IACvE,GAAG,CAAC,EAAE,MAAM,OAAO,MAAM,CAAA;IACzB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B;AAmBD,UAAU,qBACR,SAAQ,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC;IACrD,IAAI,EAAE,SAAS,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;CAChB;AAkCD,UAAU,gBAAiB,SAAQ,KAAK,CAAC,cAAc,CAAC,kBAAkB,CAAC;IACzE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B;AAsBD,UAAU,mBAAmB;IAC3B,IAAI,EAAE,UAAU,CAAA;IAChB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IACnC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,aAAa,CAAC,EAAE,YAAY,EAAE,CAAA;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAmJD,MAAM,MAAM,WAAW,GAAG,eAAe,CAAA;AAEzC,QAAA,MAAM,MAAM;;;;;;;;CAQV,CAAA;AAEF,OAAO,EAAE,MAAM,EAAE,CAAA"}
@@ -6,192 +6,195 @@ import { Avatar as r, AvatarFallback as i, AvatarImage as a } from "../ui/avatar
6
6
  import { t as o } from "../_chunks/normalize-icon.js";
7
7
  import { DropdownMenu as s, DropdownMenuContent as c, DropdownMenuItem as l, DropdownMenuSeparator as u, DropdownMenuTrigger as d } from "../ui/dropdown-menu.js";
8
8
  import { Tooltip as f, TooltipContent as p, TooltipTrigger as m } from "../ui/tooltip.js";
9
- import { useColorMode as h } from "../hooks/use-color-mode.js";
10
- import * as g from "react";
11
- import { Fragment as _, jsx as v, jsxs as y } from "react/jsx-runtime";
12
- import { IconLogout as b, IconMoon as x, IconSun as S, IconUser as C } from "@tabler/icons-react";
9
+ import { TruncatedText as h } from "../ui/truncated-text.js";
10
+ import { useColorMode as g } from "../hooks/use-color-mode.js";
11
+ import * as _ from "react";
12
+ import { Fragment as v, jsx as y, jsxs as b } from "react/jsx-runtime";
13
+ import { IconLogout as x, IconMoon as S, IconSun as C, IconUser as w } from "@tabler/icons-react";
13
14
  //#region src/shell/top-bar.tsx
14
- var w = g.forwardRef(({ className: e, children: n, ...r }, i) => {
15
- let a = g.Children.toArray(n).some((e) => g.isValidElement(e) && e.type === E);
16
- return /* @__PURE__ */ v("header", {
15
+ var T = _.forwardRef(({ className: e, children: n, ...r }, i) => {
16
+ let a = _.Children.toArray(n).some((e) => _.isValidElement(e) && e.type === D);
17
+ return /* @__PURE__ */ y("header", {
17
18
  ...r,
18
19
  ref: i,
19
20
  className: t("z-sticky w-full border-b border-surface-border-strong bg-surface-raised px-ds-05 py-ds-04 md:px-ds-06", a ? "grid grid-cols-[1fr_auto_1fr] items-center" : "flex items-center", e),
20
21
  children: n
21
22
  });
22
23
  });
23
- w.displayName = "TopBar";
24
- var T = g.forwardRef(({ className: e, children: n, ...r }, i) => /* @__PURE__ */ v("div", {
24
+ T.displayName = "TopBar";
25
+ var E = _.forwardRef(({ className: e, children: n, ...r }, i) => /* @__PURE__ */ y("div", {
25
26
  ref: i,
26
27
  className: t("flex items-center gap-ds-04", e),
27
28
  ...r,
28
29
  children: n
29
30
  }));
30
- T.displayName = "TopBar.Left";
31
- var E = g.forwardRef(({ className: e, children: n, ...r }, i) => /* @__PURE__ */ v("div", {
31
+ E.displayName = "TopBar.Left";
32
+ var D = _.forwardRef(({ className: e, children: n, ...r }, i) => /* @__PURE__ */ y("div", {
32
33
  ref: i,
33
34
  className: t("flex items-center justify-center px-ds-04", e),
34
35
  ...r,
35
36
  children: n
36
37
  }));
37
- E.displayName = "TopBar.Center";
38
- var D = g.forwardRef(({ className: e, children: n, ...r }, i) => /* @__PURE__ */ v("div", {
38
+ D.displayName = "TopBar.Center";
39
+ var O = _.forwardRef(({ className: e, children: n, ...r }, i) => /* @__PURE__ */ y("div", {
39
40
  ref: i,
40
41
  className: t("ml-auto flex items-center gap-ds-04", e),
41
42
  ...r,
42
43
  children: n
43
44
  }));
44
- D.displayName = "TopBar.Right";
45
- var O = {
45
+ O.displayName = "TopBar.Right";
46
+ var k = {
46
47
  tight: "gap-ds-02",
47
48
  default: "gap-ds-04",
48
49
  loose: "gap-ds-06"
49
- }, k = g.forwardRef(({ gap: e = "default", className: n, children: r, ...i }, a) => /* @__PURE__ */ v("div", {
50
+ }, A = _.forwardRef(({ gap: e = "default", className: n, children: r, ...i }, a) => /* @__PURE__ */ y("div", {
50
51
  ref: a,
51
- className: t("flex items-center", O[e], n),
52
+ className: t("flex items-center", k[e], n),
52
53
  ...i,
53
54
  children: r
54
55
  }));
55
- k.displayName = "TopBar.Section";
56
- var A = g.forwardRef(({ icon: n, tooltip: r, className: i, ...a }, s) => /* @__PURE__ */ y(f, { children: [/* @__PURE__ */ v(m, {
56
+ A.displayName = "TopBar.Section";
57
+ var j = _.forwardRef(({ icon: n, tooltip: r, className: i, ...a }, s) => /* @__PURE__ */ b(f, { children: [/* @__PURE__ */ y(m, {
57
58
  asChild: !0,
58
- children: /* @__PURE__ */ v("button", {
59
+ children: /* @__PURE__ */ y("button", {
59
60
  ref: s,
60
61
  type: "button",
61
62
  "aria-label": r,
62
63
  className: t("flex h-ds-sm-plus w-ds-sm-plus items-center justify-center rounded-pill border border-surface-border-strong bg-surface-raised-hover text-surface-fg-muted transition-[color,background-color,border-color,transform] hover:bg-surface-raised-active active:scale-90 duration-fast-01 ease-productive-standard", i),
63
64
  ...a,
64
- children: /* @__PURE__ */ v("span", {
65
+ children: /* @__PURE__ */ y("span", {
65
66
  className: "[&>svg]:h-ico-sm [&>svg]:w-ico-sm",
66
67
  "aria-hidden": "true",
67
- children: /* @__PURE__ */ v(e, {
68
+ children: /* @__PURE__ */ y(e, {
68
69
  size: "sm",
69
70
  children: o(n)
70
71
  })
71
72
  })
72
73
  })
73
- }), /* @__PURE__ */ v(p, {
74
+ }), /* @__PURE__ */ y(p, {
74
75
  side: "bottom",
75
76
  align: "center",
76
77
  children: r
77
78
  })] }));
78
- A.displayName = "TopBar.IconButton";
79
- var j = g.forwardRef(({ className: e, children: n, ...r }, i) => /* @__PURE__ */ v("h2", {
79
+ j.displayName = "TopBar.IconButton";
80
+ var M = _.forwardRef(({ className: e, children: n, ...r }, i) => /* @__PURE__ */ y("h2", {
80
81
  ref: i,
81
82
  className: t("hidden text-ds-lg text-surface-fg md:block", e),
82
83
  ...r,
83
84
  children: n
84
85
  }));
85
- j.displayName = "TopBar.Title";
86
- var M = g.forwardRef(({ user: w, onNavigate: T, onLogout: E, userMenuItems: D, className: O }, k) => {
87
- let { colorMode: A, toggleColorMode: j } = h();
88
- return /* @__PURE__ */ y(s, { children: [/* @__PURE__ */ y(f, { children: [/* @__PURE__ */ v(m, {
86
+ M.displayName = "TopBar.Title";
87
+ var N = _.forwardRef(({ user: T, onNavigate: E, onLogout: D, userMenuItems: O, className: k }, A) => {
88
+ let { colorMode: j, toggleColorMode: M } = g();
89
+ return /* @__PURE__ */ b(s, { children: [/* @__PURE__ */ b(f, { children: [/* @__PURE__ */ y(m, {
89
90
  asChild: !0,
90
- children: /* @__PURE__ */ v(d, {
91
+ children: /* @__PURE__ */ y(d, {
91
92
  asChild: !0,
92
- children: /* @__PURE__ */ v("button", {
93
- ref: k,
93
+ children: /* @__PURE__ */ y("button", {
94
+ ref: A,
94
95
  type: "button",
95
- className: t("flex items-center gap-ds-03 outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9 focus-visible:ring-offset-2", O),
96
- children: /* @__PURE__ */ y(r, {
96
+ className: t("flex items-center gap-ds-03 outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9 focus-visible:ring-offset-2", k),
97
+ children: /* @__PURE__ */ b(r, {
97
98
  className: "h-ds-sm-plus w-ds-sm-plus cursor-pointer",
98
- children: [w.image ? /* @__PURE__ */ v(a, {
99
- src: w.image,
100
- alt: w.name
101
- }) : null, /* @__PURE__ */ v(i, {
99
+ children: [T.image ? /* @__PURE__ */ y(a, {
100
+ src: T.image,
101
+ alt: T.name
102
+ }) : null, /* @__PURE__ */ y(i, {
102
103
  className: "bg-surface-raised-hover text-surface-fg",
103
- children: w.name?.charAt(0).toUpperCase()
104
+ children: T.name?.charAt(0).toUpperCase()
104
105
  })]
105
106
  })
106
107
  })
107
108
  })
108
- }), /* @__PURE__ */ v(p, {
109
+ }), /* @__PURE__ */ y(p, {
109
110
  side: "bottom",
110
111
  align: "center",
111
112
  children: "User Menu"
112
- })] }), /* @__PURE__ */ y(c, {
113
+ })] }), /* @__PURE__ */ b(c, {
113
114
  className: "w-[200px] rounded-overlay-lg bg-surface-overlay p-0 shadow-floating",
114
115
  sideOffset: 8,
115
116
  align: "end",
116
117
  children: [
117
- /* @__PURE__ */ y("div", {
118
+ /* @__PURE__ */ b("div", {
118
119
  className: "border-b border-surface-border-strong px-ds-05 py-ds-04",
119
- children: [/* @__PURE__ */ v("p", {
120
+ children: [/* @__PURE__ */ y("p", {
120
121
  className: "text-ds-md text-surface-fg",
121
- children: w.name
122
- }), w.email && /* @__PURE__ */ v("p", {
123
- className: "text-ds-sm text-surface-fg-subtle truncate",
124
- children: w.email
122
+ children: T.name
123
+ }), T.email && /* @__PURE__ */ y(h, {
124
+ as: "p",
125
+ mode: "middle",
126
+ className: "text-ds-sm text-surface-fg-subtle",
127
+ children: T.email
125
128
  })]
126
129
  }),
127
- /* @__PURE__ */ y(l, {
130
+ /* @__PURE__ */ b(l, {
128
131
  className: "flex w-full cursor-pointer items-center gap-ds-03 px-ds-05 py-ds-04 hover:bg-surface-raised",
129
- onClick: () => T?.("/profile"),
130
- children: [/* @__PURE__ */ v(n, {
131
- icon: C,
132
+ onClick: () => E?.("/profile"),
133
+ children: [/* @__PURE__ */ y(n, {
134
+ icon: w,
132
135
  size: "sm",
133
136
  className: "text-surface-fg-muted"
134
- }), /* @__PURE__ */ v("span", {
137
+ }), /* @__PURE__ */ y("span", {
135
138
  className: "text-ds-md text-surface-fg-muted",
136
139
  children: "Profile"
137
140
  })]
138
141
  }),
139
- D?.map((n, r) => {
142
+ O?.map((n, r) => {
140
143
  let i = n.color ? {
141
144
  error: "text-error-11",
142
145
  success: "text-success-11",
143
146
  warning: "text-warning-11",
144
147
  info: "text-info-11"
145
148
  }[n.color] ?? "text-surface-fg-muted" : "text-surface-fg-muted";
146
- return /* @__PURE__ */ y(g.Fragment, { children: [n.separator && /* @__PURE__ */ v(u, { className: "bg-surface-border" }), /* @__PURE__ */ y(l, {
149
+ return /* @__PURE__ */ b(_.Fragment, { children: [n.separator && /* @__PURE__ */ y(u, { className: "bg-surface-border" }), /* @__PURE__ */ b(l, {
147
150
  className: t("flex w-full cursor-pointer items-center gap-ds-03 px-ds-05 py-ds-04 hover:bg-surface-raised", n.disabled && "pointer-events-none opacity-action-disabled"),
148
151
  disabled: n.disabled,
149
152
  onClick: () => {
150
- n.disabled || (n.onClick ? n.onClick() : n.href && T?.(n.href));
153
+ n.disabled || (n.onClick ? n.onClick() : n.href && E?.(n.href));
151
154
  },
152
155
  children: [
153
- n.icon && /* @__PURE__ */ v("span", {
156
+ n.icon && /* @__PURE__ */ y("span", {
154
157
  className: t("[&>svg]:h-ico-sm [&>svg]:w-ico-sm", i),
155
- children: /* @__PURE__ */ v(e, {
158
+ children: /* @__PURE__ */ y(e, {
156
159
  size: "sm",
157
160
  children: o(n.icon)
158
161
  })
159
162
  }),
160
- /* @__PURE__ */ v("span", {
163
+ /* @__PURE__ */ y("span", {
161
164
  className: t("text-ds-md", i),
162
165
  children: n.label
163
166
  }),
164
- n.badge != null && n.badge !== !1 && (typeof n.badge == "string" ? /* @__PURE__ */ v("span", {
167
+ n.badge != null && n.badge !== !1 && (typeof n.badge == "string" ? /* @__PURE__ */ y("span", {
165
168
  className: "ml-auto inline-flex h-[18px] min-w-[18px] items-center justify-center rounded-pill bg-error-9 px-ds-02 text-[10px] font-semibold leading-none text-error-fg",
166
169
  children: n.badge
167
- }) : /* @__PURE__ */ v("span", { className: "ml-auto h-[8px] w-[8px] rounded-pill bg-error-9" }))
170
+ }) : /* @__PURE__ */ y("span", { className: "ml-auto h-[8px] w-[8px] rounded-pill bg-error-9" }))
168
171
  ]
169
172
  })] }, n.label + r);
170
173
  }),
171
- /* @__PURE__ */ y(l, {
174
+ /* @__PURE__ */ b(l, {
172
175
  className: "flex w-full cursor-pointer items-center gap-ds-03 px-ds-05 py-ds-04 hover:bg-surface-raised",
173
- onClick: j,
174
- children: [A === "dark" ? /* @__PURE__ */ v(n, {
175
- icon: S,
176
+ onClick: M,
177
+ children: [j === "dark" ? /* @__PURE__ */ y(n, {
178
+ icon: C,
176
179
  size: "sm",
177
180
  className: "text-surface-fg-muted"
178
- }) : /* @__PURE__ */ v(n, {
179
- icon: x,
181
+ }) : /* @__PURE__ */ y(n, {
182
+ icon: S,
180
183
  size: "sm",
181
184
  className: "text-surface-fg-muted"
182
- }), /* @__PURE__ */ v("span", {
185
+ }), /* @__PURE__ */ y("span", {
183
186
  className: "text-ds-md text-surface-fg-muted",
184
- children: A === "dark" ? "Light Mode" : "Dark Mode"
187
+ children: j === "dark" ? "Light Mode" : "Dark Mode"
185
188
  })]
186
189
  }),
187
- E && /* @__PURE__ */ y(_, { children: [/* @__PURE__ */ v(u, { className: "bg-surface-border" }), /* @__PURE__ */ y(l, {
190
+ D && /* @__PURE__ */ b(v, { children: [/* @__PURE__ */ y(u, { className: "bg-surface-border" }), /* @__PURE__ */ b(l, {
188
191
  className: "flex w-full cursor-pointer items-center gap-ds-03 px-ds-05 py-ds-04 hover:bg-surface-raised",
189
- onClick: E,
190
- children: [/* @__PURE__ */ v(n, {
191
- icon: b,
192
+ onClick: D,
193
+ children: [/* @__PURE__ */ y(n, {
194
+ icon: x,
192
195
  size: "sm",
193
196
  className: "text-error-11"
194
- }), /* @__PURE__ */ v("span", {
197
+ }), /* @__PURE__ */ y("span", {
195
198
  className: "text-ds-md text-error-11",
196
199
  children: "Logout"
197
200
  })]
@@ -199,15 +202,15 @@ var M = g.forwardRef(({ user: w, onNavigate: T, onLogout: E, userMenuItems: D, c
199
202
  ]
200
203
  })] });
201
204
  });
202
- M.displayName = "TopBar.UserMenu";
203
- var N = Object.assign(w, {
204
- Left: T,
205
- Center: E,
206
- Right: D,
207
- Section: k,
208
- IconButton: A,
209
- Title: j,
210
- UserMenu: M
205
+ N.displayName = "TopBar.UserMenu";
206
+ var P = Object.assign(T, {
207
+ Left: E,
208
+ Center: D,
209
+ Right: O,
210
+ Section: A,
211
+ IconButton: j,
212
+ Title: M,
213
+ UserMenu: N
211
214
  });
212
215
  //#endregion
213
- export { N as TopBar };
216
+ export { P as TopBar };
@@ -1 +1 @@
1
- {"version":3,"file":"top-bar.js","names":[],"sources":["../../src/shell/top-bar.tsx"],"sourcesContent":["'use client'\n\n/**\n * TopBar v2 — Composition-based application top bar.\n *\n * Subcomponents: TopBar.Left, TopBar.Center, TopBar.Right,\n * TopBar.Section, TopBar.IconButton, TopBar.Title, TopBar.UserMenu.\n */\nimport { IconLogout, IconMoon, IconSun,IconUser } from '@tabler/icons-react'\nimport * as React from 'react'\n\nimport { useColorMode } from '../hooks/use-color-mode'\nimport { Avatar, AvatarFallback, AvatarImage } from '../ui/avatar'\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '../ui/dropdown-menu'\nimport { Icon } from '../ui/icon'\nimport { IconProvider } from '../ui/icon-context'\nimport type { IconInput } from '../ui/lib/icon-input'\nimport { normalizeIcon } from '../ui/lib/normalize-icon'\nimport { cn } from '../ui/lib/utils'\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from '../ui/tooltip'\n\n// -----------------------------------------------------------------------\n// Types\n// -----------------------------------------------------------------------\n\nexport interface TopBarUser {\n name: string\n email?: string\n image?: string | null\n}\n\nexport interface UserMenuItem {\n /** Display label */\n label: string\n /** Optional icon. Accepts any `IconInput`. */\n icon?: IconInput\n /** Navigate via onNavigate when clicked */\n href?: string\n /** Custom click handler */\n onClick?: () => void\n /** Render a separator before this item */\n separator?: boolean\n /** Text color semantic token (e.g. \"error\") — maps to text-{color} */\n color?: string\n /** Badge content — string for count, true for dot indicator */\n badge?: string | boolean\n /** Whether the item is disabled */\n disabled?: boolean\n}\n\n// -----------------------------------------------------------------------\n// TopBar (root)\n// -----------------------------------------------------------------------\n\ninterface TopBarRootProps extends React.HTMLAttributes<HTMLElement> {\n children: React.ReactNode\n className?: string\n}\n\nconst TopBarRoot = React.forwardRef<HTMLElement, TopBarRootProps>(\n ({ className, children, ...props }, ref) => {\n // Detect if a Center zone is present to switch to grid layout\n const hasCenter = React.Children.toArray(children).some(\n (child) => React.isValidElement(child) && child.type === TopBarCenter,\n )\n\n return (\n <header\n {...props}\n ref={ref}\n className={cn(\n 'z-sticky w-full border-b border-surface-border-strong bg-surface-raised px-ds-05 py-ds-04 md:px-ds-06',\n hasCenter\n ? 'grid grid-cols-[1fr_auto_1fr] items-center'\n : 'flex items-center',\n className,\n )}\n >\n {children}\n </header>\n )\n },\n)\nTopBarRoot.displayName = 'TopBar'\n\n// -----------------------------------------------------------------------\n// TopBar.Left\n// -----------------------------------------------------------------------\n\ninterface TopBarLeftProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode\n}\n\nconst TopBarLeft = React.forwardRef<HTMLDivElement, TopBarLeftProps>(\n ({ className, children, ...props }, ref) => (\n <div\n ref={ref}\n className={cn('flex items-center gap-ds-04', className)}\n {...props}\n >\n {children}\n </div>\n ),\n)\nTopBarLeft.displayName = 'TopBar.Left'\n\n// -----------------------------------------------------------------------\n// TopBar.Center\n// -----------------------------------------------------------------------\n\ninterface TopBarCenterProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode\n}\n\nconst TopBarCenter = React.forwardRef<HTMLDivElement, TopBarCenterProps>(\n ({ className, children, ...props }, ref) => (\n <div\n ref={ref}\n className={cn('flex items-center justify-center px-ds-04', className)}\n {...props}\n >\n {children}\n </div>\n ),\n)\nTopBarCenter.displayName = 'TopBar.Center'\n\n// -----------------------------------------------------------------------\n// TopBar.Right\n// -----------------------------------------------------------------------\n\ninterface TopBarRightProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode\n}\n\nconst TopBarRight = React.forwardRef<HTMLDivElement, TopBarRightProps>(\n ({ className, children, ...props }, ref) => (\n <div\n ref={ref}\n className={cn('ml-auto flex items-center gap-ds-04', className)}\n {...props}\n >\n {children}\n </div>\n ),\n)\nTopBarRight.displayName = 'TopBar.Right'\n\n// -----------------------------------------------------------------------\n// TopBar.Section\n// -----------------------------------------------------------------------\n\nconst gapMap = {\n tight: 'gap-ds-02',\n default: 'gap-ds-04',\n loose: 'gap-ds-06',\n} as const\n\ninterface TopBarSectionProps extends React.HTMLAttributes<HTMLDivElement> {\n gap?: keyof typeof gapMap\n children: React.ReactNode\n}\n\nconst TopBarSection = React.forwardRef<HTMLDivElement, TopBarSectionProps>(\n ({ gap = 'default', className, children, ...props }, ref) => (\n <div\n ref={ref}\n className={cn('flex items-center', gapMap[gap], className)}\n {...props}\n >\n {children}\n </div>\n ),\n)\nTopBarSection.displayName = 'TopBar.Section'\n\n// -----------------------------------------------------------------------\n// TopBar.IconButton\n// -----------------------------------------------------------------------\n\ninterface TopBarIconButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n icon: IconInput\n tooltip: string\n}\n\nconst TopBarIconButton = React.forwardRef<\n HTMLButtonElement,\n TopBarIconButtonProps\n>(({ icon, tooltip, className, ...props }, ref) => (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n ref={ref}\n type=\"button\"\n aria-label={tooltip}\n className={cn(\n 'flex h-ds-sm-plus w-ds-sm-plus items-center justify-center rounded-pill border border-surface-border-strong bg-surface-raised-hover text-surface-fg-muted transition-[color,background-color,border-color,transform] hover:bg-surface-raised-active active:scale-90 duration-fast-01 ease-productive-standard',\n className,\n )}\n {...props}\n >\n <span className=\"[&>svg]:h-ico-sm [&>svg]:w-ico-sm\" aria-hidden=\"true\">\n <IconProvider size=\"sm\">{normalizeIcon(icon)}</IconProvider>\n </span>\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\" align=\"center\">\n {tooltip}\n </TooltipContent>\n </Tooltip>\n))\nTopBarIconButton.displayName = 'TopBar.IconButton'\n\n// -----------------------------------------------------------------------\n// TopBar.Title\n// -----------------------------------------------------------------------\n\ninterface TopBarTitleProps extends React.HTMLAttributes<HTMLHeadingElement> {\n children: React.ReactNode\n}\n\nconst TopBarTitle = React.forwardRef<HTMLHeadingElement, TopBarTitleProps>(\n ({ className, children, ...props }, ref) => (\n <h2\n ref={ref}\n className={cn(\n 'hidden text-ds-lg text-surface-fg md:block',\n className,\n )}\n {...props}\n >\n {children}\n </h2>\n ),\n)\nTopBarTitle.displayName = 'TopBar.Title'\n\n// -----------------------------------------------------------------------\n// TopBar.UserMenu\n// -----------------------------------------------------------------------\n\ninterface TopBarUserMenuProps {\n user: TopBarUser\n onNavigate?: (path: string) => void\n onLogout?: () => void\n userMenuItems?: UserMenuItem[]\n className?: string\n}\n\nconst TopBarUserMenu = React.forwardRef<HTMLButtonElement, TopBarUserMenuProps>(\n ({ user, onNavigate, onLogout, userMenuItems, className }, ref) => {\n const { colorMode, toggleColorMode } = useColorMode()\n\n return (\n <DropdownMenu>\n <Tooltip>\n <TooltipTrigger asChild>\n <DropdownMenuTrigger asChild>\n <button\n ref={ref}\n type=\"button\"\n className={cn('flex items-center gap-ds-03 outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9 focus-visible:ring-offset-2', className)}\n >\n <Avatar className=\"h-ds-sm-plus w-ds-sm-plus cursor-pointer\">\n {user.image ? (\n <AvatarImage src={user.image} alt={user.name} />\n ) : null}\n <AvatarFallback className=\"bg-surface-raised-hover text-surface-fg\">\n {user.name?.charAt(0).toUpperCase()}\n </AvatarFallback>\n </Avatar>\n </button>\n </DropdownMenuTrigger>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\" align=\"center\">\n User Menu\n </TooltipContent>\n </Tooltip>\n\n <DropdownMenuContent\n className=\"w-[200px] rounded-overlay-lg bg-surface-overlay p-0 shadow-floating\"\n sideOffset={8}\n align=\"end\"\n >\n {/* User Info */}\n <div className=\"border-b border-surface-border-strong px-ds-05 py-ds-04\">\n <p className=\"text-ds-md text-surface-fg\">{user.name}</p>\n {user.email && (\n <p className=\"text-ds-sm text-surface-fg-subtle truncate\">{user.email}</p>\n )}\n </div>\n\n <DropdownMenuItem\n className=\"flex w-full cursor-pointer items-center gap-ds-03 px-ds-05 py-ds-04 hover:bg-surface-raised\"\n onClick={() => onNavigate?.('/profile')}\n >\n <Icon icon={IconUser} size=\"sm\" className=\"text-surface-fg-muted\" />\n <span className=\"text-ds-md text-surface-fg-muted\">Profile</span>\n </DropdownMenuItem>\n\n {/* Custom user menu items */}\n {userMenuItems?.map((item, index) => {\n const colorMap: Record<string, string> = {\n error: 'text-error-11',\n success: 'text-success-11',\n warning: 'text-warning-11',\n info: 'text-info-11',\n }\n const textColor = item.color\n ? (colorMap[item.color] ?? 'text-surface-fg-muted')\n : 'text-surface-fg-muted'\n return (\n <React.Fragment key={item.label + index}>\n {item.separator && (\n <DropdownMenuSeparator className=\"bg-surface-border\" />\n )}\n <DropdownMenuItem\n className={cn(\n 'flex w-full cursor-pointer items-center gap-ds-03 px-ds-05 py-ds-04 hover:bg-surface-raised',\n item.disabled && 'pointer-events-none opacity-action-disabled',\n )}\n disabled={item.disabled}\n onClick={() => {\n if (item.disabled) return\n if (item.onClick) item.onClick()\n else if (item.href) onNavigate?.(item.href)\n }}\n >\n {item.icon && (\n <span\n className={cn(\n '[&>svg]:h-ico-sm [&>svg]:w-ico-sm',\n textColor,\n )}\n >\n <IconProvider size=\"sm\">{normalizeIcon(item.icon)}</IconProvider>\n </span>\n )}\n <span className={cn('text-ds-md', textColor)}>\n {item.label}\n </span>\n {item.badge != null &&\n item.badge !== false &&\n (typeof item.badge === 'string' ? (\n <span className=\"ml-auto inline-flex h-[18px] min-w-[18px] items-center justify-center rounded-pill bg-error-9 px-ds-02 text-[10px] font-semibold leading-none text-error-fg\">\n {item.badge}\n </span>\n ) : (\n <span className=\"ml-auto h-[8px] w-[8px] rounded-pill bg-error-9\" />\n ))}\n </DropdownMenuItem>\n </React.Fragment>\n )\n })}\n\n <DropdownMenuItem\n className=\"flex w-full cursor-pointer items-center gap-ds-03 px-ds-05 py-ds-04 hover:bg-surface-raised\"\n onClick={toggleColorMode}\n >\n {colorMode === 'dark' ? (\n <Icon icon={IconSun} size=\"sm\" className=\"text-surface-fg-muted\" />\n ) : (\n <Icon icon={IconMoon} size=\"sm\" className=\"text-surface-fg-muted\" />\n )}\n <span className=\"text-ds-md text-surface-fg-muted\">\n {colorMode === 'dark' ? 'Light Mode' : 'Dark Mode'}\n </span>\n </DropdownMenuItem>\n\n {onLogout && (\n <>\n <DropdownMenuSeparator className=\"bg-surface-border\" />\n <DropdownMenuItem\n className=\"flex w-full cursor-pointer items-center gap-ds-03 px-ds-05 py-ds-04 hover:bg-surface-raised\"\n onClick={onLogout}\n >\n <Icon icon={IconLogout} size=\"sm\" className=\"text-error-11\" />\n <span className=\"text-ds-md text-error-11\">Logout</span>\n </DropdownMenuItem>\n </>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n )\n },\n)\nTopBarUserMenu.displayName = 'TopBar.UserMenu'\n\n// -----------------------------------------------------------------------\n// Compound export\n// -----------------------------------------------------------------------\n\nexport type TopBarProps = TopBarRootProps\n\nconst TopBar = Object.assign(TopBarRoot, {\n Left: TopBarLeft,\n Center: TopBarCenter,\n Right: TopBarRight,\n Section: TopBarSection,\n IconButton: TopBarIconButton,\n Title: TopBarTitle,\n UserMenu: TopBarUserMenu,\n})\n\nexport { TopBar }\n"],"mappings":"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"}
1
+ {"version":3,"file":"top-bar.js","names":[],"sources":["../../src/shell/top-bar.tsx"],"sourcesContent":["'use client'\n\n/**\n * TopBar v2 — Composition-based application top bar.\n *\n * Subcomponents: TopBar.Left, TopBar.Center, TopBar.Right,\n * TopBar.Section, TopBar.IconButton, TopBar.Title, TopBar.UserMenu.\n */\nimport { IconLogout, IconMoon, IconSun,IconUser } from '@tabler/icons-react'\nimport * as React from 'react'\n\nimport { useColorMode } from '../hooks/use-color-mode'\nimport { Avatar, AvatarFallback, AvatarImage } from '../ui/avatar'\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '../ui/dropdown-menu'\nimport { Icon } from '../ui/icon'\nimport { IconProvider } from '../ui/icon-context'\nimport type { IconInput } from '../ui/lib/icon-input'\nimport { normalizeIcon } from '../ui/lib/normalize-icon'\nimport { cn } from '../ui/lib/utils'\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from '../ui/tooltip'\nimport { TruncatedText } from '../ui/truncated-text'\n\n// -----------------------------------------------------------------------\n// Types\n// -----------------------------------------------------------------------\n\nexport interface TopBarUser {\n name: string\n email?: string\n image?: string | null\n}\n\nexport interface UserMenuItem {\n /** Display label */\n label: string\n /** Optional icon. Accepts any `IconInput`. */\n icon?: IconInput\n /** Navigate via onNavigate when clicked */\n href?: string\n /** Custom click handler */\n onClick?: () => void\n /** Render a separator before this item */\n separator?: boolean\n /** Text color semantic token (e.g. \"error\") — maps to text-{color} */\n color?: string\n /** Badge content — string for count, true for dot indicator */\n badge?: string | boolean\n /** Whether the item is disabled */\n disabled?: boolean\n}\n\n// -----------------------------------------------------------------------\n// TopBar (root)\n// -----------------------------------------------------------------------\n\ninterface TopBarRootProps extends React.HTMLAttributes<HTMLElement> {\n children: React.ReactNode\n className?: string\n}\n\nconst TopBarRoot = React.forwardRef<HTMLElement, TopBarRootProps>(\n ({ className, children, ...props }, ref) => {\n // Detect if a Center zone is present to switch to grid layout\n const hasCenter = React.Children.toArray(children).some(\n (child) => React.isValidElement(child) && child.type === TopBarCenter,\n )\n\n return (\n <header\n {...props}\n ref={ref}\n className={cn(\n 'z-sticky w-full border-b border-surface-border-strong bg-surface-raised px-ds-05 py-ds-04 md:px-ds-06',\n hasCenter\n ? 'grid grid-cols-[1fr_auto_1fr] items-center'\n : 'flex items-center',\n className,\n )}\n >\n {children}\n </header>\n )\n },\n)\nTopBarRoot.displayName = 'TopBar'\n\n// -----------------------------------------------------------------------\n// TopBar.Left\n// -----------------------------------------------------------------------\n\ninterface TopBarLeftProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode\n}\n\nconst TopBarLeft = React.forwardRef<HTMLDivElement, TopBarLeftProps>(\n ({ className, children, ...props }, ref) => (\n <div\n ref={ref}\n className={cn('flex items-center gap-ds-04', className)}\n {...props}\n >\n {children}\n </div>\n ),\n)\nTopBarLeft.displayName = 'TopBar.Left'\n\n// -----------------------------------------------------------------------\n// TopBar.Center\n// -----------------------------------------------------------------------\n\ninterface TopBarCenterProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode\n}\n\nconst TopBarCenter = React.forwardRef<HTMLDivElement, TopBarCenterProps>(\n ({ className, children, ...props }, ref) => (\n <div\n ref={ref}\n className={cn('flex items-center justify-center px-ds-04', className)}\n {...props}\n >\n {children}\n </div>\n ),\n)\nTopBarCenter.displayName = 'TopBar.Center'\n\n// -----------------------------------------------------------------------\n// TopBar.Right\n// -----------------------------------------------------------------------\n\ninterface TopBarRightProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode\n}\n\nconst TopBarRight = React.forwardRef<HTMLDivElement, TopBarRightProps>(\n ({ className, children, ...props }, ref) => (\n <div\n ref={ref}\n className={cn('ml-auto flex items-center gap-ds-04', className)}\n {...props}\n >\n {children}\n </div>\n ),\n)\nTopBarRight.displayName = 'TopBar.Right'\n\n// -----------------------------------------------------------------------\n// TopBar.Section\n// -----------------------------------------------------------------------\n\nconst gapMap = {\n tight: 'gap-ds-02',\n default: 'gap-ds-04',\n loose: 'gap-ds-06',\n} as const\n\ninterface TopBarSectionProps extends React.HTMLAttributes<HTMLDivElement> {\n gap?: keyof typeof gapMap\n children: React.ReactNode\n}\n\nconst TopBarSection = React.forwardRef<HTMLDivElement, TopBarSectionProps>(\n ({ gap = 'default', className, children, ...props }, ref) => (\n <div\n ref={ref}\n className={cn('flex items-center', gapMap[gap], className)}\n {...props}\n >\n {children}\n </div>\n ),\n)\nTopBarSection.displayName = 'TopBar.Section'\n\n// -----------------------------------------------------------------------\n// TopBar.IconButton\n// -----------------------------------------------------------------------\n\ninterface TopBarIconButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n icon: IconInput\n tooltip: string\n}\n\nconst TopBarIconButton = React.forwardRef<\n HTMLButtonElement,\n TopBarIconButtonProps\n>(({ icon, tooltip, className, ...props }, ref) => (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n ref={ref}\n type=\"button\"\n aria-label={tooltip}\n className={cn(\n 'flex h-ds-sm-plus w-ds-sm-plus items-center justify-center rounded-pill border border-surface-border-strong bg-surface-raised-hover text-surface-fg-muted transition-[color,background-color,border-color,transform] hover:bg-surface-raised-active active:scale-90 duration-fast-01 ease-productive-standard',\n className,\n )}\n {...props}\n >\n <span className=\"[&>svg]:h-ico-sm [&>svg]:w-ico-sm\" aria-hidden=\"true\">\n <IconProvider size=\"sm\">{normalizeIcon(icon)}</IconProvider>\n </span>\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\" align=\"center\">\n {tooltip}\n </TooltipContent>\n </Tooltip>\n))\nTopBarIconButton.displayName = 'TopBar.IconButton'\n\n// -----------------------------------------------------------------------\n// TopBar.Title\n// -----------------------------------------------------------------------\n\ninterface TopBarTitleProps extends React.HTMLAttributes<HTMLHeadingElement> {\n children: React.ReactNode\n}\n\nconst TopBarTitle = React.forwardRef<HTMLHeadingElement, TopBarTitleProps>(\n ({ className, children, ...props }, ref) => (\n <h2\n ref={ref}\n className={cn(\n 'hidden text-ds-lg text-surface-fg md:block',\n className,\n )}\n {...props}\n >\n {children}\n </h2>\n ),\n)\nTopBarTitle.displayName = 'TopBar.Title'\n\n// -----------------------------------------------------------------------\n// TopBar.UserMenu\n// -----------------------------------------------------------------------\n\ninterface TopBarUserMenuProps {\n user: TopBarUser\n onNavigate?: (path: string) => void\n onLogout?: () => void\n userMenuItems?: UserMenuItem[]\n className?: string\n}\n\nconst TopBarUserMenu = React.forwardRef<HTMLButtonElement, TopBarUserMenuProps>(\n ({ user, onNavigate, onLogout, userMenuItems, className }, ref) => {\n const { colorMode, toggleColorMode } = useColorMode()\n\n return (\n <DropdownMenu>\n <Tooltip>\n <TooltipTrigger asChild>\n <DropdownMenuTrigger asChild>\n <button\n ref={ref}\n type=\"button\"\n className={cn('flex items-center gap-ds-03 outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9 focus-visible:ring-offset-2', className)}\n >\n <Avatar className=\"h-ds-sm-plus w-ds-sm-plus cursor-pointer\">\n {user.image ? (\n <AvatarImage src={user.image} alt={user.name} />\n ) : null}\n <AvatarFallback className=\"bg-surface-raised-hover text-surface-fg\">\n {user.name?.charAt(0).toUpperCase()}\n </AvatarFallback>\n </Avatar>\n </button>\n </DropdownMenuTrigger>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\" align=\"center\">\n User Menu\n </TooltipContent>\n </Tooltip>\n\n <DropdownMenuContent\n className=\"w-[200px] rounded-overlay-lg bg-surface-overlay p-0 shadow-floating\"\n sideOffset={8}\n align=\"end\"\n >\n {/* User Info */}\n <div className=\"border-b border-surface-border-strong px-ds-05 py-ds-04\">\n <p className=\"text-ds-md text-surface-fg\">{user.name}</p>\n {user.email && (\n <TruncatedText as=\"p\" mode=\"middle\" className=\"text-ds-sm text-surface-fg-subtle\">\n {user.email}\n </TruncatedText>\n )}\n </div>\n\n <DropdownMenuItem\n className=\"flex w-full cursor-pointer items-center gap-ds-03 px-ds-05 py-ds-04 hover:bg-surface-raised\"\n onClick={() => onNavigate?.('/profile')}\n >\n <Icon icon={IconUser} size=\"sm\" className=\"text-surface-fg-muted\" />\n <span className=\"text-ds-md text-surface-fg-muted\">Profile</span>\n </DropdownMenuItem>\n\n {/* Custom user menu items */}\n {userMenuItems?.map((item, index) => {\n const colorMap: Record<string, string> = {\n error: 'text-error-11',\n success: 'text-success-11',\n warning: 'text-warning-11',\n info: 'text-info-11',\n }\n const textColor = item.color\n ? (colorMap[item.color] ?? 'text-surface-fg-muted')\n : 'text-surface-fg-muted'\n return (\n <React.Fragment key={item.label + index}>\n {item.separator && (\n <DropdownMenuSeparator className=\"bg-surface-border\" />\n )}\n <DropdownMenuItem\n className={cn(\n 'flex w-full cursor-pointer items-center gap-ds-03 px-ds-05 py-ds-04 hover:bg-surface-raised',\n item.disabled && 'pointer-events-none opacity-action-disabled',\n )}\n disabled={item.disabled}\n onClick={() => {\n if (item.disabled) return\n if (item.onClick) item.onClick()\n else if (item.href) onNavigate?.(item.href)\n }}\n >\n {item.icon && (\n <span\n className={cn(\n '[&>svg]:h-ico-sm [&>svg]:w-ico-sm',\n textColor,\n )}\n >\n <IconProvider size=\"sm\">{normalizeIcon(item.icon)}</IconProvider>\n </span>\n )}\n <span className={cn('text-ds-md', textColor)}>\n {item.label}\n </span>\n {item.badge != null &&\n item.badge !== false &&\n (typeof item.badge === 'string' ? (\n <span className=\"ml-auto inline-flex h-[18px] min-w-[18px] items-center justify-center rounded-pill bg-error-9 px-ds-02 text-[10px] font-semibold leading-none text-error-fg\">\n {item.badge}\n </span>\n ) : (\n <span className=\"ml-auto h-[8px] w-[8px] rounded-pill bg-error-9\" />\n ))}\n </DropdownMenuItem>\n </React.Fragment>\n )\n })}\n\n <DropdownMenuItem\n className=\"flex w-full cursor-pointer items-center gap-ds-03 px-ds-05 py-ds-04 hover:bg-surface-raised\"\n onClick={toggleColorMode}\n >\n {colorMode === 'dark' ? (\n <Icon icon={IconSun} size=\"sm\" className=\"text-surface-fg-muted\" />\n ) : (\n <Icon icon={IconMoon} size=\"sm\" className=\"text-surface-fg-muted\" />\n )}\n <span className=\"text-ds-md text-surface-fg-muted\">\n {colorMode === 'dark' ? 'Light Mode' : 'Dark Mode'}\n </span>\n </DropdownMenuItem>\n\n {onLogout && (\n <>\n <DropdownMenuSeparator className=\"bg-surface-border\" />\n <DropdownMenuItem\n className=\"flex w-full cursor-pointer items-center gap-ds-03 px-ds-05 py-ds-04 hover:bg-surface-raised\"\n onClick={onLogout}\n >\n <Icon icon={IconLogout} size=\"sm\" className=\"text-error-11\" />\n <span className=\"text-ds-md text-error-11\">Logout</span>\n </DropdownMenuItem>\n </>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n )\n },\n)\nTopBarUserMenu.displayName = 'TopBar.UserMenu'\n\n// -----------------------------------------------------------------------\n// Compound export\n// -----------------------------------------------------------------------\n\nexport type TopBarProps = TopBarRootProps\n\nconst TopBar = Object.assign(TopBarRoot, {\n Left: TopBarLeft,\n Center: TopBarCenter,\n Right: TopBarRight,\n Section: TopBarSection,\n IconButton: TopBarIconButton,\n Title: TopBarTitle,\n UserMenu: TopBarUserMenu,\n})\n\nexport { TopBar }\n"],"mappings":"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"}
@@ -67,6 +67,7 @@
67
67
  TW4 namespace: --text-* → text-* utility.
68
68
  We use the `ds-` prefix to avoid collision with consumer's own
69
69
  text sizes (TW4 default supplies text-xs, text-sm, etc.). */
70
+ --text-ds-2xs: 0.5625rem; /* 9px — micro labels (avatar xs, corner pills); below xs */
70
71
  --text-ds-xs: 0.625rem; /* 10px */
71
72
  --text-ds-sm: 0.75rem; /* 12px */
72
73
  --text-ds-md: 0.875rem; /* 14px */
package/dist/ui/avatar.js CHANGED
@@ -51,7 +51,7 @@ var u = o.createContext("circle"), d = o.createContext("md"), f = i("relative fl
51
51
  square: "rounded-none",
52
52
  rounded: "rounded-control"
53
53
  }, v = {
54
- xs: "text-[9px]",
54
+ xs: "text-ds-2xs",
55
55
  sm: "text-ds-xs",
56
56
  md: "text-ds-sm",
57
57
  lg: "text-ds-md",