@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":"notification-center.js","names":[],"sources":["../../src/shell/notification-center.tsx"],"sourcesContent":["'use client'\n\n/**\n * NotificationCenter -- Popover-based notification panel.\n *\n * Props-driven: accepts notifications array and callbacks instead of\n * reading from Zustand stores or using Remix useNavigate.\n */\nimport { IconBell, IconChecks, IconInbox, IconX } from '@tabler/icons-react'\nimport { motion, useReducedMotion } from 'framer-motion'\nimport * as React from 'react'\nimport { useCallback,useRef } from 'react'\n\nimport { useIsMobile } from '../hooks/use-mobile'\nimport { Icon } from '../ui/icon'\nimport { formatRelativeTime } from '../ui/lib/date-utils'\nimport { durations } from '../ui/lib/motion'\nimport { cn } from '../ui/lib/utils'\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '../ui/popover'\nimport {\n Sheet,\n SheetContent,\n SheetTitle,\n SheetTrigger,\n} from '../ui/sheet'\nimport { Spinner } from '../ui/spinner'\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from '../ui/tooltip'\n\n// -----------------------------------------------------------------------\n// Types\n// -----------------------------------------------------------------------\n\nexport interface NotificationAction {\n /** Button label */\n label: string\n /** Visual style — 'primary' is filled, 'default' is ghost, 'danger' is red ghost */\n variant?: 'primary' | 'default' | 'danger'\n /** Called when the action button is clicked. Receives the notification id. */\n onClick: (id: string) => void\n}\n\nexport interface Notification {\n id: string\n title: string\n body?: string | null\n tier: 'INFO' | 'IMPORTANT' | 'CRITICAL'\n isRead: boolean\n createdAt: string\n entityType?: string | null\n entityId?: string | null\n projectId?: string | null\n project?: { title: string } | null\n /** Inline action buttons (e.g. Approve / Deny). Max 2–3 recommended. */\n actions?: NotificationAction[]\n}\n\nexport interface NotificationCenterProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** List of notifications to display */\n notifications?: Notification[]\n /** Count of unread notifications (derived from notifications if not provided) */\n unreadCount?: number\n /** Whether the popover is open (controlled mode) */\n open?: boolean\n /** Called when the popover open state changes */\n onOpenChange?: (open: boolean) => void\n /** Whether more notifications are loading */\n isLoading?: boolean\n /** Whether there are more notifications to fetch */\n hasMore?: boolean\n /** Called when the user scrolls near the bottom to load more */\n onFetchMore?: () => void\n /** Called to mark a single notification as read */\n onMarkRead?: (id: string) => void\n /** Called to mark all notifications as read */\n onMarkAllRead?: () => void\n /** Called when the user clicks a notification (e.g., navigate to entity) */\n onNavigate?: (path: string) => void\n /** Resolve a notification to a navigation path. Return null if no navigation. */\n getNotificationRoute?: (notification: Notification) => string | null\n /** Additional actions rendered in the header (e.g., settings button) */\n headerActions?: React.ReactNode\n /** Custom empty state to display when there are no notifications */\n emptyState?: React.ReactNode\n /** Content rendered below the notification list as a footer */\n footerSlot?: React.ReactNode\n /** Called when the user dismisses a notification. Renders an X button per row when provided. */\n onDismiss?: (id: string) => void\n /** Additional className for the popover content container */\n popoverClassName?: string\n /** Additional className */\n className?: string\n}\n\n// -----------------------------------------------------------------------\n// Helpers\n// -----------------------------------------------------------------------\n\n\nfunction isSameDay(a: Date, b: Date): boolean {\n return (\n a.getFullYear() === b.getFullYear() &&\n a.getMonth() === b.getMonth() &&\n a.getDate() === b.getDate()\n )\n}\n\nfunction getDateGroup(dateStr: string): string {\n const date = new Date(dateStr)\n const today = new Date()\n const yesterday = new Date()\n yesterday.setDate(today.getDate() - 1)\n\n if (isSameDay(date, today)) return 'Today'\n if (isSameDay(date, yesterday)) return 'Yesterday'\n return 'Earlier'\n}\n\nconst TIER_COLORS: Record<string, string> = {\n INFO: 'bg-info-9',\n IMPORTANT: 'bg-warning-9',\n CRITICAL: 'bg-error-9',\n}\n\n// -----------------------------------------------------------------------\n// NotificationItem (internal)\n// -----------------------------------------------------------------------\n\nfunction NotificationItem({\n notification,\n onRead,\n onNavigate,\n getRoute,\n onDismiss,\n}: {\n notification: Notification\n onRead: (id: string) => void\n onNavigate: (path: string) => void\n getRoute: (notification: Notification) => string | null\n onDismiss?: (id: string) => void\n}) {\n const route = getRoute(notification)\n\n const handleClick = () => {\n if (!notification.isRead) {\n onRead(notification.id)\n }\n if (route) {\n onNavigate(route)\n }\n }\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n handleClick()\n }\n }\n\n return (\n <div\n role=\"button\"\n tabIndex={0}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n className={cn(\n 'group relative flex w-full cursor-pointer items-start gap-ds-04 px-ds-05 py-ds-04 text-left transition-colors duration-fast-02 ease-productive-standard',\n 'hover:bg-surface-raised',\n !notification.isRead && 'bg-accent-1',\n )}\n >\n {/* Tier dot — doubles as read/unread marker */}\n <div className=\"mt-ds-02b flex shrink-0\">\n <span\n className={cn(\n 'h-[8px] w-[8px] rounded-pill transition-opacity duration-fast-02 ease-productive-standard',\n TIER_COLORS[notification.tier] || TIER_COLORS.INFO,\n notification.isRead ? 'opacity-20' : 'opacity-100',\n )}\n />\n </div>\n\n {/* Content */}\n <div className=\"min-w-0 flex-1\">\n <p\n className={cn(\n 'truncate text-ds-md text-surface-fg',\n !notification.isRead && 'font-semibold',\n )}\n >\n {notification.title}\n </p>\n {notification.body && (\n <p className=\"mt-ds-01 line-clamp-2 text-ds-sm text-surface-fg-subtle\">\n {notification.body}\n </p>\n )}\n <div className=\"mt-ds-02 flex items-center gap-ds-03\">\n <span className=\"text-ds-sm text-surface-fg-subtle\">\n {formatRelativeTime(notification.createdAt)}\n </span>\n {notification.project && (\n <>\n <span className=\"text-surface-fg-subtle\">\n &middot;\n </span>\n <span className=\"truncate text-ds-sm text-surface-fg-subtle\">\n {notification.project.title}\n </span>\n </>\n )}\n </div>\n\n {/* Inline actions */}\n {notification.actions && notification.actions.length > 0 && (\n <div className=\"mt-ds-03 flex items-center gap-ds-02\">\n {notification.actions.map((action) => (\n <button\n key={action.label}\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation()\n action.onClick(notification.id)\n }}\n onKeyDown={(e) => e.stopPropagation()}\n className={cn(\n 'rounded-control px-ds-03 py-ds-01 text-ds-sm font-medium transition-colors duration-fast-02 ease-productive-standard',\n action.variant === 'primary'\n ? 'bg-accent-9 text-accent-fg hover:bg-accent-10'\n : action.variant === 'danger'\n ? 'text-error-11 hover:bg-error-3'\n : 'text-surface-fg-muted hover:bg-surface-raised-hover',\n )}\n >\n {action.label}\n </button>\n ))}\n </div>\n )}\n </div>\n\n {/* Dismiss button */}\n {onDismiss && (\n <button\n type=\"button\"\n aria-label={`Dismiss notification: ${notification.title}`}\n onClick={(e) => {\n e.stopPropagation()\n onDismiss(notification.id)\n }}\n onKeyDown={(e) => e.stopPropagation()}\n className=\"absolute right-ds-03 top-ds-03 hidden rounded-control-inner p-ds-01 text-surface-fg-subtle transition-[color,background-color,opacity] duration-fast-01 ease-productive-standard hover:bg-surface-raised-hover hover:text-surface-fg-muted group-hover:flex group-focus-within:flex\"\n >\n <Icon icon={IconX} size=\"sm\" />\n </button>\n )}\n </div>\n )\n}\n\n// -----------------------------------------------------------------------\n// NotificationCenter\n// -----------------------------------------------------------------------\n\nconst NotificationCenter = React.forwardRef<HTMLButtonElement, NotificationCenterProps>(\n (\n {\n notifications = [],\n unreadCount: unreadCountProp,\n open,\n onOpenChange,\n isLoading = false,\n hasMore = false,\n onFetchMore,\n onMarkRead,\n onMarkAllRead,\n onNavigate,\n getNotificationRoute,\n onDismiss,\n headerActions,\n emptyState,\n footerSlot,\n popoverClassName,\n className,\n ...props\n },\n ref,\n ) => {\n const scrollRef = useRef<HTMLDivElement>(null)\n const prefersReducedMotion = useReducedMotion()\n const isMobile = useIsMobile()\n\n const unreadCount =\n unreadCountProp ?? notifications.filter((n) => !n.isRead).length\n\n const getRoute = getNotificationRoute ?? (() => null)\n\n const handleNavigate = useCallback(\n (path: string) => {\n onOpenChange?.(false)\n onNavigate?.(path)\n },\n [onNavigate, onOpenChange],\n )\n\n const handleMarkRead = useCallback(\n (id: string) => {\n onMarkRead?.(id)\n },\n [onMarkRead],\n )\n\n const handleScroll = useCallback(() => {\n const el = scrollRef.current\n if (!el || isLoading || !hasMore) return\n if (el.scrollTop + el.clientHeight >= el.scrollHeight - 50) {\n onFetchMore?.()\n }\n }, [isLoading, hasMore, onFetchMore])\n\n // Group notifications by date\n const grouped = notifications.reduce<Record<string, Notification[]>>(\n (acc, n) => {\n const group = getDateGroup(n.createdAt)\n if (!acc[group]) acc[group] = []\n acc[group].push(n)\n return acc\n },\n {},\n )\n\n const groupOrder = ['Today', 'Yesterday', 'Earlier']\n\n // -- Shared panel content (used in both Popover and Sheet) --\n const panelContent = (\n <>\n {/* Header */}\n <div className=\"flex items-center justify-between border-b border-surface-border-strong px-ds-05 py-ds-04\">\n <div className=\"flex items-center gap-ds-03\">\n {/* On mobile the SheetTitle provides the accessible heading; on desktop use h3 */}\n {!isMobile && (\n <h3 className=\"text-ds-md font-semibold text-surface-fg\">\n Notifications\n </h3>\n )}\n {unreadCount > 0 && (\n <span className=\"flex h-5 min-w-5 items-center justify-center rounded-pill bg-accent-2 px-ds-02b text-ds-sm font-semibold text-accent-11\">\n {unreadCount}\n </span>\n )}\n </div>\n <div className=\"flex items-center gap-ds-03\">\n {unreadCount > 0 && onMarkAllRead && (\n <button\n type=\"button\"\n onClick={onMarkAllRead}\n className=\"flex items-center gap-ds-02 text-ds-sm text-surface-fg-subtle transition-colors hover:text-accent-11\"\n >\n <Icon icon={IconChecks} size=\"sm\" />\n Mark all read\n </button>\n )}\n {headerActions}\n </div>\n </div>\n\n {/* Notification list */}\n <div\n ref={scrollRef}\n onScroll={handleScroll}\n className={cn('overflow-y-auto', isMobile ? 'max-h-[60vh]' : 'max-h-[420px]')}\n >\n {notifications.length === 0 ? (\n emptyState || (\n <div className=\"flex flex-col items-center justify-center px-ds-05 py-ds-09\">\n <div className=\"flex h-ds-lg w-ds-lg items-center justify-center rounded-pill bg-surface-raised\">\n <Icon icon={IconInbox} size=\"lg\" className=\"text-surface-fg-subtle\" />\n </div>\n <p className=\"mt-ds-04 text-ds-md text-surface-fg-subtle\">\n No notifications yet\n </p>\n <p className=\"mt-ds-02 text-ds-sm text-surface-fg-subtle\">\n You&apos;re all caught up!\n </p>\n </div>\n )\n ) : (\n groupOrder.map((group) => {\n const items = grouped[group]\n if (!items || items.length === 0) return null\n return (\n <div key={group}>\n <div className=\"sticky top-0 z-raised bg-surface-overlay px-ds-05 py-ds-02b\">\n <span className=\"text-ds-sm font-medium text-surface-fg-subtle\">\n {group}\n </span>\n </div>\n {items.map((notification, index) => (\n <motion.div\n key={notification.id}\n initial={prefersReducedMotion ? undefined : { opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={prefersReducedMotion ? { duration: 0 } : { delay: index * 0.03 }}\n >\n <NotificationItem\n notification={notification}\n onRead={handleMarkRead}\n onNavigate={handleNavigate}\n getRoute={getRoute}\n onDismiss={onDismiss}\n />\n </motion.div>\n ))}\n </div>\n )\n })\n )}\n\n {isLoading && (\n <div className=\"flex items-center justify-center py-ds-05\">\n <Spinner />\n </div>\n )}\n </div>\n {footerSlot && (\n <div className=\"border-t border-surface-border-strong px-ds-05 py-ds-03\">\n {footerSlot}\n </div>\n )}\n </>\n )\n\n // -- Trigger button (shared between both modes) --\n const triggerButton = (\n <button\n {...props}\n ref={ref}\n aria-label={unreadCount > 0 ? `Notifications, ${unreadCount} unread` : 'Notifications'}\n className={cn(\n 'relative flex h-ds-sm-plus w-ds-sm-plus items-center justify-center rounded-pill border border-surface-border-strong bg-surface-raised text-surface-fg-muted transition-colors ease-productive-standard hover:bg-surface-raised-hover',\n className,\n )}\n >\n <Icon icon={IconBell} size=\"sm\" />\n {unreadCount > 0 && (\n <motion.span\n initial={{ rotate: 0 }}\n animate={prefersReducedMotion ? undefined : { rotate: [0, -3, 3, -1, 1, 0] }}\n transition={prefersReducedMotion ? { duration: 0 } : { duration: durations.slow01, ease: 'easeInOut' }}\n className=\"absolute -right-ds-01 -top-ds-01 flex h-4 min-w-4 items-center justify-center rounded-pill bg-accent-9 px-ds-02 text-ds-xs font-semibold text-accent-fg\"\n >\n {unreadCount > 99 ? '99+' : unreadCount}\n </motion.span>\n )}\n </button>\n )\n\n // -- Mobile: render in a bottom Sheet --\n if (isMobile) {\n return (\n <Sheet open={open} onOpenChange={onOpenChange}>\n <Tooltip>\n <TooltipTrigger asChild>\n <SheetTrigger asChild>\n {triggerButton}\n </SheetTrigger>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\" align=\"center\">\n Notifications\n </TooltipContent>\n </Tooltip>\n\n <SheetContent side=\"bottom\" className={cn('p-0', popoverClassName)} responsive={false}>\n <SheetTitle className=\"px-ds-05 pt-ds-04 text-ds-md font-semibold text-surface-fg\">\n Notifications\n </SheetTitle>\n {panelContent}\n </SheetContent>\n </Sheet>\n )\n }\n\n // -- Desktop: render in a Popover --\n return (\n <Popover open={open} onOpenChange={onOpenChange}>\n <Tooltip>\n <TooltipTrigger asChild>\n <PopoverTrigger asChild>\n {triggerButton}\n </PopoverTrigger>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\" align=\"center\">\n Notifications\n </TooltipContent>\n </Tooltip>\n\n <PopoverContent\n className={cn(\n 'w-[380px] rounded-overlay-lg bg-surface-overlay p-0 shadow-floating',\n popoverClassName,\n )}\n sideOffset={8}\n align=\"end\"\n >\n {panelContent}\n </PopoverContent>\n </Popover>\n )\n },\n)\nNotificationCenter.displayName = 'NotificationCenter'\n\nexport { NotificationCenter }\n"],"mappings":"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"}
1
+ {"version":3,"file":"notification-center.js","names":[],"sources":["../../src/shell/notification-center.tsx"],"sourcesContent":["'use client'\n\n/**\n * NotificationCenter -- Popover-based notification panel.\n *\n * Props-driven: accepts notifications array and callbacks instead of\n * reading from Zustand stores or using Remix useNavigate.\n */\nimport { IconBell, IconChecks, IconInbox, IconX } from '@tabler/icons-react'\nimport { motion, useReducedMotion } from 'framer-motion'\nimport * as React from 'react'\nimport { useCallback,useRef } from 'react'\n\nimport { useIsMobile } from '../hooks/use-mobile'\nimport { Button } from '../ui/button'\nimport { Icon } from '../ui/icon'\nimport { formatRelativeTime } from '../ui/lib/date-utils'\nimport { durations } from '../ui/lib/motion'\nimport { cn } from '../ui/lib/utils'\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '../ui/popover'\nimport {\n Sheet,\n SheetContent,\n SheetTitle,\n SheetTrigger,\n} from '../ui/sheet'\nimport { Spinner } from '../ui/spinner'\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 NotificationAction {\n /** Button label */\n label: string\n /** Visual style — 'primary' is filled, 'default' is ghost, 'danger' is red ghost */\n variant?: 'primary' | 'default' | 'danger'\n /** Called when the action button is clicked. Receives the notification id. */\n onClick: (id: string) => void\n}\n\nexport interface Notification {\n id: string\n title: string\n body?: string | null\n tier: 'INFO' | 'IMPORTANT' | 'CRITICAL'\n isRead: boolean\n createdAt: string\n entityType?: string | null\n entityId?: string | null\n projectId?: string | null\n project?: { title: string } | null\n /** Inline action buttons (e.g. Approve / Deny). Max 2–3 recommended. */\n actions?: NotificationAction[]\n}\n\nexport interface NotificationCenterProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** List of notifications to display */\n notifications?: Notification[]\n /** Count of unread notifications (derived from notifications if not provided) */\n unreadCount?: number\n /** Whether the popover is open (controlled mode) */\n open?: boolean\n /** Called when the popover open state changes */\n onOpenChange?: (open: boolean) => void\n /** Whether more notifications are loading */\n isLoading?: boolean\n /** Whether there are more notifications to fetch */\n hasMore?: boolean\n /** Called when the user scrolls near the bottom to load more */\n onFetchMore?: () => void\n /** Called to mark a single notification as read */\n onMarkRead?: (id: string) => void\n /** Called to mark all notifications as read */\n onMarkAllRead?: () => void\n /** Called when the user clicks a notification (e.g., navigate to entity) */\n onNavigate?: (path: string) => void\n /** Resolve a notification to a navigation path. Return null if no navigation. */\n getNotificationRoute?: (notification: Notification) => string | null\n /** Additional actions rendered in the header (e.g., settings button) */\n headerActions?: React.ReactNode\n /** Custom empty state to display when there are no notifications */\n emptyState?: React.ReactNode\n /** Content rendered below the notification list as a footer */\n footerSlot?: React.ReactNode\n /** Called when the user dismisses a notification. Renders an X button per row when provided. */\n onDismiss?: (id: string) => void\n /** Additional className for the popover content container */\n popoverClassName?: string\n /** Additional className */\n className?: string\n}\n\n// -----------------------------------------------------------------------\n// Helpers\n// -----------------------------------------------------------------------\n\n\nfunction isSameDay(a: Date, b: Date): boolean {\n return (\n a.getFullYear() === b.getFullYear() &&\n a.getMonth() === b.getMonth() &&\n a.getDate() === b.getDate()\n )\n}\n\nfunction getDateGroup(dateStr: string): string {\n const date = new Date(dateStr)\n const today = new Date()\n const yesterday = new Date()\n yesterday.setDate(today.getDate() - 1)\n\n if (isSameDay(date, today)) return 'Today'\n if (isSameDay(date, yesterday)) return 'Yesterday'\n return 'Earlier'\n}\n\nconst TIER_COLORS: Record<string, string> = {\n INFO: 'bg-info-9',\n IMPORTANT: 'bg-warning-9',\n CRITICAL: 'bg-error-9',\n}\n\n// -----------------------------------------------------------------------\n// NotificationItem (internal)\n// -----------------------------------------------------------------------\n\nfunction NotificationItem({\n notification,\n onRead,\n onNavigate,\n getRoute,\n onDismiss,\n}: {\n notification: Notification\n onRead: (id: string) => void\n onNavigate: (path: string) => void\n getRoute: (notification: Notification) => string | null\n onDismiss?: (id: string) => void\n}) {\n const route = getRoute(notification)\n\n const handleClick = () => {\n if (!notification.isRead) {\n onRead(notification.id)\n }\n if (route) {\n onNavigate(route)\n }\n }\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n handleClick()\n }\n }\n\n return (\n <div\n role=\"button\"\n tabIndex={0}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n className={cn(\n 'group relative flex w-full cursor-pointer items-start gap-ds-04 px-ds-05 py-ds-04 text-left transition-colors duration-fast-02 ease-productive-standard',\n 'hover:bg-surface-raised',\n !notification.isRead && 'bg-accent-1',\n )}\n >\n {/* Tier dot — doubles as read/unread marker */}\n <div className=\"mt-ds-02b flex shrink-0\">\n <span\n className={cn(\n 'h-[8px] w-[8px] rounded-pill transition-opacity duration-fast-02 ease-productive-standard',\n TIER_COLORS[notification.tier] || TIER_COLORS.INFO,\n notification.isRead ? 'opacity-20' : 'opacity-100',\n )}\n />\n </div>\n\n {/* Content */}\n <div className=\"min-w-0 flex-1\">\n <TruncatedText\n as=\"p\"\n className={cn(\n 'text-ds-md text-surface-fg',\n !notification.isRead && 'font-semibold',\n )}\n >\n {notification.title}\n </TruncatedText>\n {notification.body && (\n <p className=\"mt-ds-01 line-clamp-2 text-ds-sm text-surface-fg-subtle\">\n {notification.body}\n </p>\n )}\n <div className=\"mt-ds-02 flex items-center gap-ds-03\">\n <span className=\"text-ds-sm text-surface-fg-subtle\">\n {formatRelativeTime(notification.createdAt)}\n </span>\n {notification.project && (\n <>\n <span className=\"text-surface-fg-subtle\">\n &middot;\n </span>\n <TruncatedText className=\"text-ds-sm text-surface-fg-subtle\">\n {notification.project.title}\n </TruncatedText>\n </>\n )}\n </div>\n\n {/* Inline actions */}\n {notification.actions && notification.actions.length > 0 && (\n <div className=\"mt-ds-03 flex items-center gap-ds-02\">\n {notification.actions.map((action) => (\n <Button\n key={action.label}\n size=\"sm\"\n variant={action.variant === 'primary' ? 'solid' : 'ghost'}\n color={action.variant === 'danger' ? 'error' : 'accent'}\n onClick={(e) => {\n e.stopPropagation()\n action.onClick(notification.id)\n }}\n onKeyDown={(e) => e.stopPropagation()}\n >\n {action.label}\n </Button>\n ))}\n </div>\n )}\n </div>\n\n {/* Dismiss button */}\n {onDismiss && (\n <button\n type=\"button\"\n aria-label={`Dismiss notification: ${notification.title}`}\n onClick={(e) => {\n e.stopPropagation()\n onDismiss(notification.id)\n }}\n onKeyDown={(e) => e.stopPropagation()}\n className=\"absolute right-ds-03 top-ds-03 hidden rounded-control-inner p-ds-01 text-surface-fg-subtle transition-[color,background-color,opacity] duration-fast-01 ease-productive-standard hover:bg-surface-raised-hover hover:text-surface-fg-muted group-hover:flex group-focus-within:flex\"\n >\n <Icon icon={IconX} size=\"sm\" />\n </button>\n )}\n </div>\n )\n}\n\n// -----------------------------------------------------------------------\n// NotificationCenter\n// -----------------------------------------------------------------------\n\nconst NotificationCenter = React.forwardRef<HTMLButtonElement, NotificationCenterProps>(\n (\n {\n notifications = [],\n unreadCount: unreadCountProp,\n open,\n onOpenChange,\n isLoading = false,\n hasMore = false,\n onFetchMore,\n onMarkRead,\n onMarkAllRead,\n onNavigate,\n getNotificationRoute,\n onDismiss,\n headerActions,\n emptyState,\n footerSlot,\n popoverClassName,\n className,\n ...props\n },\n ref,\n ) => {\n const scrollRef = useRef<HTMLDivElement>(null)\n const prefersReducedMotion = useReducedMotion()\n const isMobile = useIsMobile()\n\n const unreadCount =\n unreadCountProp ?? notifications.filter((n) => !n.isRead).length\n\n const getRoute = getNotificationRoute ?? (() => null)\n\n const handleNavigate = useCallback(\n (path: string) => {\n onOpenChange?.(false)\n onNavigate?.(path)\n },\n [onNavigate, onOpenChange],\n )\n\n const handleMarkRead = useCallback(\n (id: string) => {\n onMarkRead?.(id)\n },\n [onMarkRead],\n )\n\n const handleScroll = useCallback(() => {\n const el = scrollRef.current\n if (!el || isLoading || !hasMore) return\n if (el.scrollTop + el.clientHeight >= el.scrollHeight - 50) {\n onFetchMore?.()\n }\n }, [isLoading, hasMore, onFetchMore])\n\n // Group notifications by date\n const grouped = notifications.reduce<Record<string, Notification[]>>(\n (acc, n) => {\n const group = getDateGroup(n.createdAt)\n if (!acc[group]) acc[group] = []\n acc[group].push(n)\n return acc\n },\n {},\n )\n\n const groupOrder = ['Today', 'Yesterday', 'Earlier']\n\n // -- Shared panel content (used in both Popover and Sheet) --\n const panelContent = (\n <>\n {/* Header */}\n <div className=\"flex items-center justify-between border-b border-surface-border-strong px-ds-05 py-ds-04\">\n <div className=\"flex items-center gap-ds-03\">\n {/* On mobile the SheetTitle provides the accessible heading; on desktop use h3 */}\n {!isMobile && (\n <h3 className=\"text-ds-md font-semibold text-surface-fg\">\n Notifications\n </h3>\n )}\n {unreadCount > 0 && (\n <span className=\"flex h-5 min-w-5 items-center justify-center rounded-pill bg-accent-2 px-ds-02b text-ds-sm font-semibold text-accent-11\">\n {unreadCount}\n </span>\n )}\n </div>\n <div className=\"flex items-center gap-ds-03\">\n {unreadCount > 0 && onMarkAllRead && (\n <button\n type=\"button\"\n onClick={onMarkAllRead}\n className=\"flex items-center gap-ds-02 text-ds-sm text-surface-fg-subtle transition-colors hover:text-accent-11\"\n >\n <Icon icon={IconChecks} size=\"sm\" />\n Mark all read\n </button>\n )}\n {headerActions}\n </div>\n </div>\n\n {/* Notification list */}\n <div\n ref={scrollRef}\n onScroll={handleScroll}\n className={cn('overflow-y-auto', isMobile ? 'max-h-[60vh]' : 'max-h-[420px]')}\n >\n {notifications.length === 0 ? (\n emptyState || (\n <div className=\"flex flex-col items-center justify-center px-ds-05 py-ds-09\">\n <div className=\"flex h-ds-lg w-ds-lg items-center justify-center rounded-pill bg-surface-raised\">\n <Icon icon={IconInbox} size=\"lg\" className=\"text-surface-fg-subtle\" />\n </div>\n <p className=\"mt-ds-04 text-ds-md text-surface-fg-subtle\">\n No notifications yet\n </p>\n <p className=\"mt-ds-02 text-ds-sm text-surface-fg-subtle\">\n You&apos;re all caught up!\n </p>\n </div>\n )\n ) : (\n groupOrder.map((group) => {\n const items = grouped[group]\n if (!items || items.length === 0) return null\n return (\n <div key={group}>\n <div className=\"sticky top-0 z-raised bg-surface-overlay px-ds-05 py-ds-02b\">\n <span className=\"text-ds-sm font-medium text-surface-fg-subtle\">\n {group}\n </span>\n </div>\n {items.map((notification, index) => (\n <motion.div\n key={notification.id}\n initial={prefersReducedMotion ? undefined : { opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={prefersReducedMotion ? { duration: 0 } : { delay: index * 0.03 }}\n >\n <NotificationItem\n notification={notification}\n onRead={handleMarkRead}\n onNavigate={handleNavigate}\n getRoute={getRoute}\n onDismiss={onDismiss}\n />\n </motion.div>\n ))}\n </div>\n )\n })\n )}\n\n {isLoading && (\n <div className=\"flex items-center justify-center py-ds-05\">\n <Spinner />\n </div>\n )}\n </div>\n {footerSlot && (\n <div className=\"border-t border-surface-border-strong px-ds-05 py-ds-03\">\n {footerSlot}\n </div>\n )}\n </>\n )\n\n // -- Trigger button (shared between both modes) --\n const triggerButton = (\n <button\n {...props}\n ref={ref}\n aria-label={unreadCount > 0 ? `Notifications, ${unreadCount} unread` : 'Notifications'}\n className={cn(\n 'relative flex h-ds-sm-plus w-ds-sm-plus items-center justify-center rounded-pill border border-surface-border-strong bg-surface-raised text-surface-fg-muted transition-colors ease-productive-standard hover:bg-surface-raised-hover',\n className,\n )}\n >\n <Icon icon={IconBell} size=\"sm\" />\n {unreadCount > 0 && (\n <motion.span\n initial={{ rotate: 0 }}\n animate={prefersReducedMotion ? undefined : { rotate: [0, -3, 3, -1, 1, 0] }}\n transition={prefersReducedMotion ? { duration: 0 } : { duration: durations.slow01, ease: 'easeInOut' }}\n className=\"absolute -right-ds-01 -top-ds-01 flex h-4 min-w-4 items-center justify-center rounded-pill bg-accent-9 px-ds-02 text-ds-xs font-semibold text-accent-fg\"\n >\n {unreadCount > 99 ? '99+' : unreadCount}\n </motion.span>\n )}\n </button>\n )\n\n // -- Mobile: render in a bottom Sheet --\n if (isMobile) {\n return (\n <Sheet open={open} onOpenChange={onOpenChange}>\n <Tooltip>\n <TooltipTrigger asChild>\n <SheetTrigger asChild>\n {triggerButton}\n </SheetTrigger>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\" align=\"center\">\n Notifications\n </TooltipContent>\n </Tooltip>\n\n <SheetContent side=\"bottom\" className={cn('p-0', popoverClassName)} responsive={false}>\n <SheetTitle className=\"px-ds-05 pt-ds-04 text-ds-md font-semibold text-surface-fg\">\n Notifications\n </SheetTitle>\n {panelContent}\n </SheetContent>\n </Sheet>\n )\n }\n\n // -- Desktop: render in a Popover --\n return (\n <Popover open={open} onOpenChange={onOpenChange}>\n <Tooltip>\n <TooltipTrigger asChild>\n <PopoverTrigger asChild>\n {triggerButton}\n </PopoverTrigger>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\" align=\"center\">\n Notifications\n </TooltipContent>\n </Tooltip>\n\n <PopoverContent\n className={cn(\n 'w-[380px] rounded-overlay-lg bg-surface-overlay p-0 shadow-floating',\n popoverClassName,\n )}\n sideOffset={8}\n align=\"end\"\n >\n {panelContent}\n </PopoverContent>\n </Popover>\n )\n },\n)\nNotificationCenter.displayName = 'NotificationCenter'\n\nexport { NotificationCenter }\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"sidebar.d.ts","sourceRoot":"","sources":["../../src/shell/sidebar.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sidebar.d.ts","sourceRoot":"","sources":["../../src/shell/sidebar.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AACH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAU9B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AA4BrD,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,8CAA8C;IAC9C,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,uDAAuD;IACvD,IAAI,EAAE,SAAS,CAAA;IACf,uEAAuE;IACvE,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACvB,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,UAAU,EAAE,CAAA;IACvB,qFAAqF;IACrF,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB;AAED,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,OAAO,EAAE,CAAA;IAChB,mEAAmE;IACnE,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CACzB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,YAAY;IAC3B,yBAAyB;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,uEAAuE;IACvE,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,iDAAiD;IACjD,MAAM,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;KAAE,CAAA;IAC/D,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;CACvB;AAED,MAAM,WAAW,mBAAmB;IAClC,kEAAkE;IAClE,KAAK,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC9C,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IAClD,kDAAkD;IAClD,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACtB,uDAAuD;IACvD,KAAK,CAAC,EAAE,YAAY,CAAA;CACrB;AAED,MAAM,WAAW,eACf,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IAC5C,yEAAyE;IACzE,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,uDAAuD;IACvD,IAAI,CAAC,EAAE,WAAW,GAAG,IAAI,CAAA;IACzB,kEAAkE;IAClE,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAA;IACtB,+DAA+D;IAC/D,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACtB,yDAAyD;IACzD,WAAW,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACpD,mEAAmE;IACnE,MAAM,CAAC,EAAE,mBAAmB,CAAA;IAC5B,0DAA0D;IAC1D,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC5B,qDAAqD;IACrD,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC/B,gEAAgE;IAChE,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,uFAAuF;IACvF,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS,GAAG,IAAI,CAAA;IAC5F,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;OAIG;IACH,aAAa,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,MAAM,CAAA;CAC5C;AAgMD,QAAA,MAAM,UAAU,wFAmOf,CAAA;AAGD,OAAO,EAAE,UAAU,EAAE,CAAA"}
@@ -3,15 +3,17 @@ import { IconProvider as e } from "../ui/icon-context.js";
3
3
  import { cn as t } from "../ui/lib/utils.js";
4
4
  import { Avatar as n, AvatarFallback as r, AvatarImage as i } from "../ui/avatar.js";
5
5
  import { t as a } from "../_chunks/normalize-icon.js";
6
- import { Collapsible as o, CollapsibleContent as s, CollapsibleTrigger as c } from "../ui/collapsible.js";
7
- import { n as l } from "../_chunks/link-context.js";
8
- import { Sidebar as u, SidebarContent as d, SidebarFooter as f, SidebarGroup as p, SidebarGroupAction as m, SidebarGroupContent as h, SidebarGroupLabel as g, SidebarHeader as _, SidebarMenu as v, SidebarMenuBadge as y, SidebarMenuButton as b, SidebarMenuItem as x, SidebarMenuSub as S, SidebarMenuSubButton as C, SidebarMenuSubItem as w, SidebarSeparator as T } from "../ui/sidebar.js";
6
+ import { Button as o } from "../ui/button.js";
7
+ import { Collapsible as s, CollapsibleContent as c, CollapsibleTrigger as l } from "../ui/collapsible.js";
8
+ import { TruncatedText as u } from "../ui/truncated-text.js";
9
+ import { n as d } from "../_chunks/link-context.js";
10
+ import { Sidebar as f, SidebarContent as p, SidebarFooter as m, SidebarGroup as h, SidebarGroupAction as g, SidebarGroupContent as _, SidebarGroupLabel as v, SidebarHeader as y, SidebarMenu as b, SidebarMenuBadge as x, SidebarMenuButton as S, SidebarMenuItem as C, SidebarMenuSub as w, SidebarMenuSubButton as T, SidebarMenuSubItem as E, SidebarSeparator as D } from "../ui/sidebar.js";
9
11
  import "./link-context.js";
10
- import * as E from "react";
11
- import { Fragment as D, jsx as O, jsxs as k } from "react/jsx-runtime";
12
+ import * as O from "react";
13
+ import { Fragment as k, jsx as A, jsxs as j } from "react/jsx-runtime";
12
14
  //#region src/shell/sidebar.tsx
13
- function A({ className: e }) {
14
- return /* @__PURE__ */ O("svg", {
15
+ function M({ className: e }) {
16
+ return /* @__PURE__ */ A("svg", {
15
17
  xmlns: "http://www.w3.org/2000/svg",
16
18
  width: "16",
17
19
  height: "16",
@@ -22,11 +24,11 @@ function A({ className: e }) {
22
24
  strokeLinecap: "round",
23
25
  strokeLinejoin: "round",
24
26
  className: e,
25
- children: /* @__PURE__ */ O("path", { d: "m9 18 6-6-6-6" })
27
+ children: /* @__PURE__ */ A("path", { d: "m9 18 6-6-6-6" })
26
28
  });
27
29
  }
28
- function j({ className: e }) {
29
- return /* @__PURE__ */ k("svg", {
30
+ function N({ className: e }) {
31
+ return /* @__PURE__ */ j("svg", {
30
32
  xmlns: "http://www.w3.org/2000/svg",
31
33
  width: "16",
32
34
  height: "16",
@@ -37,233 +39,246 @@ function j({ className: e }) {
37
39
  strokeLinecap: "round",
38
40
  strokeLinejoin: "round",
39
41
  className: e,
40
- children: [/* @__PURE__ */ O("path", { d: "M18 6 6 18" }), /* @__PURE__ */ O("path", { d: "m6 6 12 12" })]
42
+ children: [/* @__PURE__ */ A("path", { d: "M18 6 6 18" }), /* @__PURE__ */ A("path", { d: "m6 6 12 12" })]
41
43
  });
42
44
  }
43
- var M = "relative gap-ds-04 rounded-[var(--ds-sidebar-item-radius,var(--radius-control))] px-ds-04 py-ds-03 transition-colors duration-fast-02", N = {
45
+ var P = "relative gap-ds-04 rounded-[var(--ds-sidebar-item-radius,var(--radius-control))] px-ds-04 py-ds-03 transition-colors duration-fast-02", F = {
44
46
  sm: "var(--radius-control-inner)",
45
47
  md: "var(--radius-control)",
46
48
  lg: "var(--radius-surface)",
47
49
  pill: "var(--radius-pill)"
48
- }, P = "bg-accent-2 text-accent-11 font-medium", F = "text-surface-fg-subtle hover:bg-surface-raised-hover hover:text-surface-fg";
49
- function I({ item: n, isActive: r, isPathActive: i }) {
50
- let u = l(), d = n.badge == null ? null : typeof n.badge == "number" && n.badge > 99 ? "99+" : String(n.badge);
50
+ }, I = "bg-accent-2 text-accent-11 font-medium", L = "text-surface-fg-subtle hover:bg-surface-raised-hover hover:text-surface-fg";
51
+ function R({ item: n, isActive: r, isPathActive: i }) {
52
+ let o = d(), u = n.badge == null ? null : typeof n.badge == "number" && n.badge > 99 ? "99+" : String(n.badge);
51
53
  if (n.children && n.children.length > 0) {
52
- let l = n.children.some((e) => i(e.href, e.exact));
53
- return /* @__PURE__ */ O(o, {
54
- defaultOpen: l || r || (n.defaultOpen ?? !1),
54
+ let d = n.children.some((e) => i(e.href, e.exact));
55
+ return /* @__PURE__ */ A(s, {
56
+ defaultOpen: d || r || (n.defaultOpen ?? !1),
55
57
  className: "group/collapsible",
56
- children: /* @__PURE__ */ k(x, { children: [/* @__PURE__ */ k("div", {
58
+ children: /* @__PURE__ */ j(C, { children: [/* @__PURE__ */ j("div", {
57
59
  className: "relative",
58
60
  children: [
59
- /* @__PURE__ */ O(b, {
61
+ /* @__PURE__ */ A(S, {
60
62
  asChild: !0,
61
- isActive: r || l,
63
+ isActive: r || d,
62
64
  tooltip: n.title,
63
- className: t(M, r || l ? P : F),
64
- children: /* @__PURE__ */ k(u, {
65
+ className: t(P, r || d ? I : L),
66
+ children: /* @__PURE__ */ j(o, {
65
67
  href: n.href,
66
68
  "aria-label": n.title,
67
69
  "aria-current": r ? "page" : void 0,
68
- children: [/* @__PURE__ */ O("span", {
70
+ className: "min-w-0",
71
+ children: [/* @__PURE__ */ A("span", {
69
72
  className: "[&>svg]:h-ico-md [&>svg]:w-ico-md shrink-0",
70
73
  "aria-hidden": "true",
71
- children: /* @__PURE__ */ O(e, {
74
+ children: /* @__PURE__ */ A(e, {
72
75
  size: "md",
73
76
  children: a(n.icon)
74
77
  })
75
- }), /* @__PURE__ */ O("span", {
76
- className: "text-ds-base",
78
+ }), /* @__PURE__ */ A("span", {
79
+ className: "text-ds-base truncate",
77
80
  children: n.title
78
81
  })]
79
82
  })
80
83
  }),
81
- d && /* @__PURE__ */ O(y, { children: d }),
82
- /* @__PURE__ */ O(c, {
84
+ u && /* @__PURE__ */ A(x, { children: u }),
85
+ /* @__PURE__ */ A(l, {
83
86
  asChild: !0,
84
- children: /* @__PURE__ */ O("button", {
87
+ children: /* @__PURE__ */ A("button", {
85
88
  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",
86
89
  "aria-label": `Toggle ${n.title}`,
87
- children: /* @__PURE__ */ O(A, { className: "h-4 w-4 transition-transform duration-fast-02 ease-productive-standard group-data-[state=open]/collapsible:rotate-90" })
90
+ children: /* @__PURE__ */ A(M, { className: "h-4 w-4 transition-transform duration-fast-02 ease-productive-standard group-data-[state=open]/collapsible:rotate-90" })
88
91
  })
89
92
  })
90
93
  ]
91
- }), /* @__PURE__ */ O(s, { children: /* @__PURE__ */ O(S, { children: n.children.map((t) => {
94
+ }), /* @__PURE__ */ A(c, { children: /* @__PURE__ */ A(w, { children: n.children.map((t) => {
92
95
  let n = i(t.href, t.exact);
93
- return /* @__PURE__ */ O(w, { children: /* @__PURE__ */ O(C, {
96
+ return /* @__PURE__ */ A(E, { children: /* @__PURE__ */ A(T, {
94
97
  asChild: !0,
95
98
  isActive: n,
96
- children: /* @__PURE__ */ k(u, {
99
+ children: /* @__PURE__ */ j(o, {
97
100
  href: t.href,
98
101
  "aria-current": n ? "page" : void 0,
99
- children: [t.icon && /* @__PURE__ */ O("span", {
102
+ className: "min-w-0",
103
+ children: [t.icon && /* @__PURE__ */ A("span", {
100
104
  className: "[&>svg]:h-ico-sm [&>svg]:w-ico-sm shrink-0",
101
105
  "aria-hidden": "true",
102
- children: /* @__PURE__ */ O(e, {
106
+ children: /* @__PURE__ */ A(e, {
103
107
  size: "sm",
104
108
  children: a(t.icon)
105
109
  })
106
- }), /* @__PURE__ */ O("span", { children: t.title })]
110
+ }), /* @__PURE__ */ A("span", {
111
+ className: "truncate",
112
+ children: t.title
113
+ })]
107
114
  })
108
115
  }) }, t.href);
109
116
  }) }) })] })
110
117
  });
111
118
  }
112
- return /* @__PURE__ */ k(x, { children: [/* @__PURE__ */ O(b, {
119
+ return /* @__PURE__ */ j(C, { children: [/* @__PURE__ */ A(S, {
113
120
  asChild: !0,
114
121
  isActive: r,
115
122
  tooltip: n.title,
116
- className: t(M, r ? P : F),
117
- children: /* @__PURE__ */ k(u, {
123
+ className: t(P, r ? I : L),
124
+ children: /* @__PURE__ */ j(o, {
118
125
  href: n.href,
119
126
  "aria-label": n.title,
120
127
  "aria-current": r ? "page" : void 0,
121
- children: [/* @__PURE__ */ O("span", {
128
+ className: "min-w-0",
129
+ children: [/* @__PURE__ */ A("span", {
122
130
  className: "[&>svg]:h-ico-md [&>svg]:w-ico-md shrink-0",
123
131
  "aria-hidden": "true",
124
- children: /* @__PURE__ */ O(e, {
132
+ children: /* @__PURE__ */ A(e, {
125
133
  size: "md",
126
134
  children: a(n.icon)
127
135
  })
128
- }), /* @__PURE__ */ O("span", {
129
- className: "text-ds-base",
136
+ }), /* @__PURE__ */ A("span", {
137
+ className: "text-ds-base truncate",
130
138
  children: n.title
131
139
  })]
132
140
  })
133
- }), d && /* @__PURE__ */ O(y, { children: d })] });
141
+ }), u && /* @__PURE__ */ A(x, { children: u })] });
134
142
  }
135
- var L = E.forwardRef(({ currentPath: o = "/", user: s, navGroups: c = [], logo: y, headerSlot: b, preFooterSlot: x, preFooterClassName: S, footerLinks: C = [], footer: w, renderItem: A, className: M, navItemRadius: P, style: F, ...L }, R) => {
136
- let z = l(), B = (e, t = !1) => t || e === "/" ? o === e : o.startsWith(e);
137
- return /* @__PURE__ */ k(u, {
138
- ...L,
139
- ref: R,
143
+ var z = O.forwardRef(({ currentPath: s = "/", user: c, navGroups: l = [], logo: x, headerSlot: S, preFooterSlot: C, preFooterClassName: w, footerLinks: T = [], footer: E, renderItem: M, className: P, navItemRadius: I, style: L, ...z }, B) => {
144
+ let V = d(), H = (e, t = !1) => t || e === "/" ? s === e : s.startsWith(e);
145
+ return /* @__PURE__ */ j(f, {
146
+ ...z,
147
+ ref: B,
140
148
  "aria-label": "Main navigation",
141
- style: P ? {
142
- "--ds-sidebar-item-radius": N[P],
143
- ...F
144
- } : F,
145
- className: t("z-raised hidden h-full flex-col border-r border-surface-border-strong bg-surface-raised md:flex", M),
149
+ style: I ? {
150
+ "--ds-sidebar-item-radius": F[I],
151
+ ...L
152
+ } : L,
153
+ className: t("z-raised hidden h-full flex-col border-r border-surface-border-strong bg-surface-raised md:flex", P),
146
154
  children: [
147
- /* @__PURE__ */ O(_, {
155
+ /* @__PURE__ */ A(y, {
148
156
  className: "px-ds-06 py-ds-06",
149
- children: y ?? /* @__PURE__ */ O("span", {
157
+ children: x ?? /* @__PURE__ */ A("span", {
150
158
  className: "text-ds-lg font-semibold text-surface-fg",
151
159
  children: "Logo"
152
160
  })
153
161
  }),
154
- s && /* @__PURE__ */ k("div", {
162
+ c && /* @__PURE__ */ j("div", {
155
163
  className: "flex items-center gap-ds-04 px-ds-06 pb-ds-05",
156
- children: [/* @__PURE__ */ k(n, {
164
+ children: [/* @__PURE__ */ j(n, {
157
165
  className: "h-ds-sm-plus w-ds-sm-plus",
158
- children: [s.image ? /* @__PURE__ */ O(i, {
159
- src: s.image,
160
- alt: s.name
161
- }) : null, /* @__PURE__ */ O(r, {
166
+ children: [c.image ? /* @__PURE__ */ A(i, {
167
+ src: c.image,
168
+ alt: c.name
169
+ }) : null, /* @__PURE__ */ A(r, {
162
170
  className: "bg-surface-raised-hover text-surface-fg",
163
- children: s.name?.charAt(0).toUpperCase()
171
+ children: c.name?.charAt(0).toUpperCase()
164
172
  })]
165
- }), /* @__PURE__ */ k("div", {
173
+ }), /* @__PURE__ */ j("div", {
166
174
  className: "flex min-w-0 flex-col",
167
- children: [/* @__PURE__ */ O("span", {
168
- className: "truncate text-ds-md text-surface-fg",
169
- children: s.name
170
- }), /* @__PURE__ */ O("span", {
171
- className: "truncate text-ds-sm text-surface-fg-subtle",
172
- children: s.designation || s.role
175
+ children: [/* @__PURE__ */ A(u, {
176
+ className: "text-ds-md text-surface-fg",
177
+ children: c.name ?? ""
178
+ }), /* @__PURE__ */ A(u, {
179
+ className: "text-ds-sm text-surface-fg-subtle",
180
+ children: c.designation || c.role || ""
173
181
  })]
174
182
  })]
175
183
  }),
176
- /* @__PURE__ */ O(T, {}),
177
- b && /* @__PURE__ */ k(D, { children: [b, /* @__PURE__ */ O(T, {})] }),
178
- /* @__PURE__ */ O(d, {
184
+ /* @__PURE__ */ A(D, {}),
185
+ S && /* @__PURE__ */ j(k, { children: [S, /* @__PURE__ */ A(D, {})] }),
186
+ /* @__PURE__ */ A(p, {
179
187
  className: "no-scrollbar px-ds-04",
180
- children: c.map((e, t) => /* @__PURE__ */ k("div", { children: [t > 0 && /* @__PURE__ */ O(T, {}), /* @__PURE__ */ k(p, { children: [
181
- /* @__PURE__ */ O(g, {
188
+ children: l.map((e, t) => /* @__PURE__ */ j("div", { children: [t > 0 && /* @__PURE__ */ A(D, {}), /* @__PURE__ */ j(h, { children: [
189
+ /* @__PURE__ */ A(v, {
182
190
  className: "px-ds-04 text-ds-sm text-surface-fg-subtle",
183
191
  children: e.label
184
192
  }),
185
- e.action && /* @__PURE__ */ O(m, {
193
+ e.action && /* @__PURE__ */ A(g, {
186
194
  asChild: !0,
187
195
  children: e.action
188
196
  }),
189
- /* @__PURE__ */ O(h, { children: /* @__PURE__ */ O(v, { children: e.items.map((e) => {
190
- let t = () => /* @__PURE__ */ O(I, {
197
+ /* @__PURE__ */ A(_, { children: /* @__PURE__ */ A(b, { children: e.items.map((e) => {
198
+ let t = () => /* @__PURE__ */ A(R, {
191
199
  item: e,
192
- isActive: B(e.href, e.exact),
193
- isPathActive: B
200
+ isActive: H(e.href, e.exact),
201
+ isPathActive: H
194
202
  });
195
- if (A) {
196
- let n = A(e, t);
197
- if (n !== null) return /* @__PURE__ */ O(E.Fragment, { children: n }, e.href);
203
+ if (M) {
204
+ let n = M(e, t);
205
+ if (n !== null) return /* @__PURE__ */ A(O.Fragment, { children: n }, e.href);
198
206
  }
199
- return /* @__PURE__ */ O(E.Fragment, { children: t() }, e.href);
207
+ return /* @__PURE__ */ A(O.Fragment, { children: t() }, e.href);
200
208
  }) }) })
201
209
  ] })] }, e.label))
202
210
  }),
203
- x && /* @__PURE__ */ k(D, { children: [/* @__PURE__ */ O(T, {}), /* @__PURE__ */ O("div", {
204
- className: S,
205
- children: x
211
+ C && /* @__PURE__ */ j(k, { children: [/* @__PURE__ */ A(D, {}), /* @__PURE__ */ A("div", {
212
+ className: w,
213
+ children: C
206
214
  })] }),
207
- w ? /* @__PURE__ */ k(f, {
215
+ E ? /* @__PURE__ */ j(m, {
208
216
  className: "gap-ds-03 px-ds-06 py-ds-05",
209
217
  children: [
210
- w.slot && /* @__PURE__ */ O("div", { children: w.slot }),
211
- w.promo && /* @__PURE__ */ k("div", {
218
+ E.slot && /* @__PURE__ */ A("div", { children: E.slot }),
219
+ E.promo && /* @__PURE__ */ j("div", {
212
220
  className: "relative rounded-surface bg-surface-raised p-ds-04 shadow-raised",
213
- children: [w.promo.onDismiss && /* @__PURE__ */ O("button", {
214
- onClick: w.promo.onDismiss,
221
+ children: [E.promo.onDismiss && /* @__PURE__ */ A("button", {
222
+ onClick: E.promo.onDismiss,
215
223
  "aria-label": "Dismiss",
216
224
  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",
217
- children: /* @__PURE__ */ O(j, { className: "h-3.5 w-3.5" })
218
- }), /* @__PURE__ */ k("div", {
225
+ children: /* @__PURE__ */ A(N, { className: "h-3.5 w-3.5" })
226
+ }), /* @__PURE__ */ j("div", {
219
227
  className: "flex flex-col gap-ds-03",
220
- children: [w.promo.icon && /* @__PURE__ */ O("span", {
228
+ children: [E.promo.icon && /* @__PURE__ */ A("span", {
221
229
  className: "text-accent-11 [&>svg]:h-ico-md [&>svg]:w-ico-md",
222
230
  "aria-hidden": "true",
223
- children: /* @__PURE__ */ O(e, {
231
+ children: /* @__PURE__ */ A(e, {
224
232
  size: "md",
225
- children: a(w.promo.icon)
233
+ children: a(E.promo.icon)
226
234
  })
227
- }), /* @__PURE__ */ k("div", {
235
+ }), /* @__PURE__ */ j("div", {
228
236
  className: "flex min-w-0 flex-col gap-ds-03",
229
- children: [/* @__PURE__ */ O("p", {
230
- className: "text-ds-sm text-surface-fg",
231
- children: w.promo.text
232
- }), w.promo.action && (w.promo.action.href ? /* @__PURE__ */ O(z, {
233
- href: w.promo.action.href,
234
- onClick: w.promo.action.onClick,
235
- 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",
236
- children: w.promo.action.label
237
- }) : /* @__PURE__ */ O("button", {
238
- onClick: w.promo.action.onClick,
239
- 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",
240
- children: w.promo.action.label
237
+ children: [/* @__PURE__ */ A("p", {
238
+ className: "text-ds-sm text-surface-fg line-clamp-2",
239
+ children: E.promo.text
240
+ }), E.promo.action && (E.promo.action.href ? /* @__PURE__ */ A(o, {
241
+ asChild: !0,
242
+ variant: "solid",
243
+ size: "sm",
244
+ className: "self-start",
245
+ children: /* @__PURE__ */ A(V, {
246
+ href: E.promo.action.href,
247
+ onClick: E.promo.action.onClick,
248
+ children: E.promo.action.label
249
+ })
250
+ }) : /* @__PURE__ */ A(o, {
251
+ variant: "solid",
252
+ size: "sm",
253
+ className: "self-start",
254
+ onClick: E.promo.action.onClick,
255
+ children: E.promo.action.label
241
256
  }))]
242
257
  })]
243
258
  })]
244
259
  }),
245
- (w.links?.length || w.version) && /* @__PURE__ */ k("div", {
260
+ (E.links?.length || E.version) && /* @__PURE__ */ j("div", {
246
261
  className: "flex items-center gap-ds-03 text-ds-sm text-surface-fg-subtle",
247
262
  children: [
248
- w.links?.map((e, t) => /* @__PURE__ */ k(E.Fragment, { children: [t > 0 && /* @__PURE__ */ O("span", { children: "·" }), /* @__PURE__ */ O(z, {
263
+ E.links?.map((e, t) => /* @__PURE__ */ j(O.Fragment, { children: [t > 0 && /* @__PURE__ */ A("span", { children: "·" }), /* @__PURE__ */ A(V, {
249
264
  className: "transition-colors hover:text-accent-11",
250
265
  href: e.href,
251
266
  children: e.label
252
267
  })] }, e.href)),
253
- w.links?.length && w.version && /* @__PURE__ */ O("span", { children: "·" }),
254
- w.version && (typeof w.version == "string" ? /* @__PURE__ */ O("span", { children: w.version }) : /* @__PURE__ */ O(z, {
268
+ E.links?.length && E.version && /* @__PURE__ */ A("span", { children: "·" }),
269
+ E.version && (typeof E.version == "string" ? /* @__PURE__ */ A("span", { children: E.version }) : /* @__PURE__ */ A(V, {
255
270
  className: "transition-colors hover:text-accent-11",
256
- href: w.version.href,
257
- children: w.version.label
271
+ href: E.version.href,
272
+ children: E.version.label
258
273
  }))
259
274
  ]
260
275
  })
261
276
  ]
262
- }) : C.length > 0 ? /* @__PURE__ */ O(f, {
277
+ }) : T.length > 0 ? /* @__PURE__ */ A(m, {
263
278
  className: "px-ds-06 py-ds-05",
264
- children: /* @__PURE__ */ O("div", {
279
+ children: /* @__PURE__ */ A("div", {
265
280
  className: "flex items-center gap-ds-03 text-ds-sm text-surface-fg-subtle",
266
- children: C.map((e, t) => /* @__PURE__ */ k(E.Fragment, { children: [t > 0 && /* @__PURE__ */ O("span", { children: "·" }), /* @__PURE__ */ O(z, {
281
+ children: T.map((e, t) => /* @__PURE__ */ j(O.Fragment, { children: [t > 0 && /* @__PURE__ */ A("span", { children: "·" }), /* @__PURE__ */ A(V, {
267
282
  className: "transition-colors hover:text-accent-11",
268
283
  href: e.href,
269
284
  children: e.label
@@ -273,6 +288,6 @@ var L = E.forwardRef(({ currentPath: o = "/", user: s, navGroups: c = [], logo:
273
288
  ]
274
289
  });
275
290
  });
276
- L.displayName = "AppSidebar";
291
+ z.displayName = "AppSidebar";
277
292
  //#endregion
278
- export { L as AppSidebar };
293
+ export { z as AppSidebar };