@humain/ui 2.2.2 → 2.2.4

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 (85) hide show
  1. package/dist/components/templates/AppShell/AppShell.d.ts +5 -3
  2. package/dist/components/templates/AppShell/index.d.ts +1 -1
  3. package/dist/components/templates/AppSidebar/AppSidebar.constants.d.ts +4 -0
  4. package/dist/components/templates/AppSidebar/AppSidebar.d.ts +1 -0
  5. package/dist/index.js +19 -18
  6. package/dist/index152.js +1 -1
  7. package/dist/index152.js.map +1 -1
  8. package/dist/index173.js +1 -1
  9. package/dist/index173.js.map +1 -1
  10. package/dist/index184.js +1 -1
  11. package/dist/index184.js.map +1 -1
  12. package/dist/index217.js +6 -24
  13. package/dist/index217.js.map +1 -1
  14. package/dist/index218.js +20 -23
  15. package/dist/index218.js.map +1 -1
  16. package/dist/index219.js +20 -95
  17. package/dist/index219.js.map +1 -1
  18. package/dist/index220.js +92 -88
  19. package/dist/index220.js.map +1 -1
  20. package/dist/index221.js +97 -29
  21. package/dist/index221.js.map +1 -1
  22. package/dist/index222.js +24 -470
  23. package/dist/index222.js.map +1 -1
  24. package/dist/index223.js +450 -196
  25. package/dist/index223.js.map +1 -1
  26. package/dist/index224.js +199 -754
  27. package/dist/index224.js.map +1 -1
  28. package/dist/index225.js +777 -61
  29. package/dist/index225.js.map +1 -1
  30. package/dist/index226.js +58 -181
  31. package/dist/index226.js.map +1 -1
  32. package/dist/index227.js +175 -259
  33. package/dist/index227.js.map +1 -1
  34. package/dist/index228.js +246 -172
  35. package/dist/index228.js.map +1 -1
  36. package/dist/index229.js +195 -32
  37. package/dist/index229.js.map +1 -1
  38. package/dist/index230.js +12 -40
  39. package/dist/index230.js.map +1 -1
  40. package/dist/index231.js +23 -26
  41. package/dist/index231.js.map +1 -1
  42. package/dist/index232.js +45 -22
  43. package/dist/index232.js.map +1 -1
  44. package/dist/index233.js +27 -48
  45. package/dist/index233.js.map +1 -1
  46. package/dist/index234.js +52 -26
  47. package/dist/index234.js.map +1 -1
  48. package/dist/index235.js +40 -225
  49. package/dist/index235.js.map +1 -1
  50. package/dist/index236.js +217 -39
  51. package/dist/index236.js.map +1 -1
  52. package/dist/index237.js +50 -0
  53. package/dist/index237.js.map +1 -0
  54. package/dist/styles.css +1 -1
  55. package/dist/wc/AISource.js +46 -46
  56. package/dist/wc/AISource.js.map +1 -1
  57. package/dist/wc/AIToolCall.js +9 -9
  58. package/dist/wc/AIToolCall.js.map +1 -1
  59. package/dist/wc/{sidebar.js → AppSidebar.constants.js} +80 -78
  60. package/dist/wc/AppSidebar.constants.js.map +1 -0
  61. package/dist/wc/hf-app-shell.js +346 -343
  62. package/dist/wc/hf-app-shell.js.map +1 -1
  63. package/dist/wc/hf-app-sidebar.js +68 -65
  64. package/dist/wc/hf-app-sidebar.js.map +1 -1
  65. package/dist/wc/markdown-renderer.js +1 -1
  66. package/dist/wc/markdown-renderer.js.map +1 -1
  67. package/dist/wc-react/AISource.js +8 -8
  68. package/dist/wc-react/AISource.js.map +1 -1
  69. package/dist/wc-react/AIToolCall.js +42 -42
  70. package/dist/wc-react/AIToolCall.js.map +1 -1
  71. package/dist/wc-react/{sidebar.js → AppSidebar.constants.js} +89 -87
  72. package/dist/wc-react/AppSidebar.constants.js.map +1 -0
  73. package/dist/wc-react/hf-app-shell.js +383 -380
  74. package/dist/wc-react/hf-app-shell.js.map +1 -1
  75. package/dist/wc-react/hf-app-sidebar.js +72 -69
  76. package/dist/wc-react/hf-app-sidebar.js.map +1 -1
  77. package/dist/wc-react/markdown-renderer.js +1 -1
  78. package/dist/wc-react/markdown-renderer.js.map +1 -1
  79. package/package.json +1 -1
  80. package/skills/humain-ui/SKILL.md +1 -1
  81. package/skills/humain-ui-wc/SKILL.md +1 -1
  82. package/skills/humain-ui-wc.skill +0 -0
  83. package/skills/humain-ui.skill +0 -0
  84. package/dist/wc/sidebar.js.map +0 -1
  85. package/dist/wc-react/sidebar.js.map +0 -1
@@ -1,4 +1,5 @@
1
1
  import * as React from 'react';
2
+ import { APP_SIDEBAR_COLLAPSED_WIDTH, APP_SIDEBAR_EXPANDED_WIDTH } from '../AppSidebar/AppSidebar.constants';
2
3
  import { AppShellContent } from './AppShellContent.js';
3
4
  import { AppShellPanel, type AppShellPanelProps } from './AppShellPanel.js';
4
5
  export interface AppShellProps extends React.ComponentProps<'div'> {
@@ -45,14 +46,15 @@ declare namespace AppShellRoot {
45
46
  }
46
47
  export interface AppShellSidebarProps extends React.ComponentProps<'div'> {
47
48
  /**
48
- * Explicit width override — bypasses auto-detection.
49
+ * Explicit width override — bypasses auto-detection. Manual widths are
50
+ * protected by AppSidebar's canonical collapsed width to prevent clipping.
49
51
  * When omitted, the sidebar auto-sizes based on the child
50
52
  * SidebarProvider's expanded/collapsed state.
51
53
  */
52
54
  width?: string;
53
55
  /** Width when sidebar is expanded (auto mode only). @default '280px' */
54
56
  expandedWidth?: string;
55
- /** Width when sidebar is collapsed (auto mode only). @default '116px' */
57
+ /** Width when sidebar is collapsed (auto mode only). @default '68px' */
56
58
  collapsedWidth?: string;
57
59
  }
58
60
  /**
@@ -97,4 +99,4 @@ declare const AppShell: typeof AppShellRoot & {
97
99
  };
98
100
  export type { AppShellContentProps } from './AppShellContent.js';
99
101
  export type { AppShellPanelProps } from './AppShellPanel.js';
100
- export { AppShell, AppShellContent, AppShellHeader, AppShellPanel, AppShellRoot, AppShellSidebar, appShellBackgrounds, };
102
+ export { APP_SIDEBAR_COLLAPSED_WIDTH, APP_SIDEBAR_EXPANDED_WIDTH, AppShell, AppShellContent, AppShellHeader, AppShellPanel, AppShellRoot, AppShellSidebar, appShellBackgrounds, };
@@ -1,4 +1,4 @@
1
1
  export type { AppShellContentProps, AppShellHeaderProps, AppShellPanelProps, AppShellProps, AppShellSidebarProps, } from './AppShell.js';
2
- export { AppShell, AppShellContent, AppShellHeader, AppShellPanel, AppShellRoot, AppShellSidebar, appShellBackgrounds, } from './AppShell.js';
2
+ export { APP_SIDEBAR_COLLAPSED_WIDTH, APP_SIDEBAR_EXPANDED_WIDTH, AppShell, AppShellContent, AppShellHeader, AppShellPanel, AppShellRoot, AppShellSidebar, appShellBackgrounds, } from './AppShell.js';
3
3
  export type { AppShellContextValue, PanelExpansionInfo, PanelLayoutInfo, PanelPosition, } from './AppShellContext.js';
4
4
  export { PanelExpansionContext, PanelIndexContext, PanelLayoutContext, useAppShell, usePanelExpansion, } from './AppShellContext.js';
@@ -0,0 +1,4 @@
1
+ /** Canonical expanded width shared by AppSidebar and AppShell.Sidebar. */
2
+ export declare const APP_SIDEBAR_EXPANDED_WIDTH = "280px";
3
+ /** Canonical collapsed width shared by AppSidebar and AppShell.Sidebar. */
4
+ export declare const APP_SIDEBAR_COLLAPSED_WIDTH = "68px";
@@ -235,5 +235,6 @@ export declare const AppSidebar: typeof AppSidebarRoot & {
235
235
  Skeleton: typeof AppSidebarSkeleton;
236
236
  };
237
237
  export { MOBILE_BREAKPOINT, useIsMobile } from '../../../hooks/use-mobile.js';
238
+ export { APP_SIDEBAR_COLLAPSED_WIDTH, APP_SIDEBAR_EXPANDED_WIDTH, } from './AppSidebar.constants';
238
239
  export type { AppSidebarAccountProps as AccountProps, AppSidebarChatItemProps as ChatItemProps, AppSidebarChatListProps as ChatListProps, AppSidebarChatListSkeletonProps as ChatListSkeletonProps, AppSidebarNavItemProps as NavItemProps, AppSidebarNavProps as NavProps, AppSidebarNavSectionProps as NavSectionProps, AppSidebarNavSkeletonProps as NavSkeletonProps, AppSidebarNavSubProps as NavSubProps, AppSidebarSkeletonProps as SkeletonProps, AppSidebarSlotProps as SlotProps, };
239
240
  export { chatItemVariants, navItemVariants, Sidebar, SidebarAccountSkeleton, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInset, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarNavSkeleton, SidebarProvider, SidebarTrigger, useSidebar, };
package/dist/index.js CHANGED
@@ -139,21 +139,22 @@ import { Popover as PopoverCompound, PopoverDescription, PopoverHeader, PopoverP
139
139
  import { Sheet, SheetBackdrop as Backdrop$3, SheetBody as Body$1, SheetClose as Close$2, SheetDescription as Description$3, SheetDivider as Divider, SheetFooter as Footer$3, SheetHeader as Header$3, SheetPopup as Popup$4, SheetPortal as Portal$4, SheetRoot as Root$4, SheetSection as Section, SheetTitle as Title$3, SheetTrigger as Trigger$4, SheetViewport as Viewport$3 } from "./index212.js";
140
140
  import { MOBILE_BREAKPOINT, useIsMobile } from "./index215.js";
141
141
  import { Sidebar as SidebarCompound, SidebarAccountSkeleton, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInset, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarNavSkeleton, SidebarProvider, SidebarTrigger, useSidebar } from "./index216.js";
142
- import { PanelExpansionContext, PanelIndexContext, PanelLayoutContext, useAppShell, usePanelExpansion } from "./index217.js";
143
- import { AppShellContent } from "./index218.js";
144
- import { AppShellPanel } from "./index220.js";
145
- import { AppShell, AppShellHeader, AppShellRoot, AppShellSidebar, appShellBackgrounds } from "./index222.js";
146
- import { AppShellCard } from "./index223.js";
147
- import { AppSidebar, chatItemVariants, navItemVariants } from "./index224.js";
148
- import { PageBackground } from "./index225.js";
149
- import { AuthAsidePanel, AuthPageLayout, renderActionElement } from "./index226.js";
150
- import { NavAccountMenu, NavAccountMenuAccount, NavAccountMenuContent, NavAccountMenuFooter, NavAccountMenuHeader, NavAccountMenuItem, NavAccountMenuSection, NavAccountMenuSeparator, NavAccountMenuThemeSwitch, NavAccountMenuTrigger, navAccountMenuTriggerVariants as triggerVariants } from "./index227.js";
151
- import { ForgotPasswordPage } from "./index229.js";
152
- import { LoginPage } from "./index230.js";
153
- import { RegisterPage } from "./index231.js";
154
- import { ResetPasswordPage } from "./index232.js";
155
- import { TwoFactorAuthenticationPage } from "./index233.js";
156
- import { VerifyEmail as VerifyEmailPage } from "./index234.js";
157
- import { formatInteractionForLLM } from "./index235.js";
158
- import { useInteractionHandler } from "./index236.js";
159
- export { AIAsciiDiagram, AIChart, AIClarificationCard, AICodeBlock, AICodeBlockContent, AICodeBlockHeader, AIComponent, AIContainerCompound as AIContainer, AIContainerContext, AIContextIndicator, AIEmptyState, AIEmptyStateActions, AIEmptyStateDescription, AIEmptyStateIcon, AIEmptyStateRoot, AIEmptyStateSuggestionGrid, AIEmptyStateTitle, AIFeedbackBar, AIFeedbackIcons, AIForm, AIInput, AIInputActionBar, AIInputActions, AIInputAttachButton, AIInputFilePreview, AIInputLeadingIcon, AIInputRoot, AIInputSendButton, AIInputTextArea, AIInteractionContext, AIInteractionProvider, AILoadingDots, AIMermaidDiagram, AIMessage, AIMessageActions, AIMessageAttachmentPreview, AIMessageAttachments, AIMessageAvatar, AIMessageBubble, AIMessageContent, AIMessageCopyButton, AIMessageHeader, AIMessageListButton, AIMessageReactions, AIMessageRoot, AIMessageThumbsDown, AIMessageThumbsUp, AIMessageTypingIndicator, AIPromptSuggestion, AIPromptSuggestionCard, AIPromptSuggestionList, AIPulseText, AIQuickActions, AIReasoningBlock, AIReasoningContent, AIReasoningTrigger, AIResponseStream, AIScrollAnchor, AIScrollButton, AISelect, AISource, AISourceContent, AISourceList, AISourceTrigger, StepIcon as AIStepIcon, AIStepItem, AISteps, AISystemMessage, AISystemMessageBanner, AITable, AITextShimmer, AIThinkingBar, AIThinkingLoader, AIToolCall, AIToolCallHeader, AIToolCallList, AIToolRun, AITypingIndicator, AITypingText, AccordionCompound as Accordion, AccordionCardNamespace as AccordionCard, AccordionCardContent, AccordionCardEdit, AccordionCardHeader, AccordionCardTitle, AccordionCardTrigger, AccordionContent, AccordionItem, AccordionTrigger, ActionButton, ActivityFeed, ActivityFeedItem, AdvancedRating, Alert, AlertDescription, AlertDialog, Action as AlertDialogAction, Backdrop as AlertDialogBackdrop, Cancel as AlertDialogCancel, Description as AlertDialogDescription, Footer as AlertDialogFooter, Header as AlertDialogHeader, Media as AlertDialogMedia, Popup as AlertDialogPopup, Portal as AlertDialogPortal, Root as AlertDialogRoot, Title as AlertDialogTitle, Trigger as AlertDialogTrigger, Viewport as AlertDialogViewport, AlertTitle, AppShell, AppShellCard, AppShellContent, AppShellHeader, AppShellPanel, AppShellRoot, AppShellSidebar, AppSidebar, AreaChart, AuthAsidePanel, AuthPageLayout, Autocomplete, Avatar, AvatarGroup, Badge, BadgeDot, BarChart, BrandIcon, BreadcrumbCompound as Breadcrumb, BreadcrumbEllipsis, BreadcrumbHomeLink, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, Calendar, CalendarActions, CalendarContent, CalendarHeader, CalendarNavigation, CalendarSearch, CalendarTitle, CalendarViewSwitcher, Card, Carousel, CarouselNav, CarouselVisual, ChartCard, ChartLegend, Checkbox, CheckboxGroup, ClearButton, CodeSnippet, Collapsible, CollapsibleContent, CollapsibleTrigger, ComboboxContent, ComboboxGroup, ComboboxHeader, ComboboxItem, ComboboxMenu, ComboboxRoot, ComboboxSeparator, ComboboxShortcut, ComboboxTrigger, CommandMenu, CommandMenuFooter, CommandMenuGroupHeader, CommandMenuItem, CommandMenuPanel, CommandShortcutBadge, CompactActionButton, ContextMenu, CheckboxItem as ContextMenuCheckboxItem, Group as ContextMenuGroup, Item as ContextMenuItem, Label as ContextMenuLabel, Popup$1 as ContextMenuPopup, Portal$1 as ContextMenuPortal, RadioGroup as ContextMenuRadioGroup, RadioItem as ContextMenuRadioItem, Root$1 as ContextMenuRoot, Separator as ContextMenuSeparator, Shortcut as ContextMenuShortcut, Sub as ContextMenuSub, SubPopup as ContextMenuSubPopup, SubTrigger as ContextMenuSubTrigger, Trigger$1 as ContextMenuTrigger, CountdownTimer, DEFAULT_CHART_COLORS, DEFAULT_DONUT_COLORS, DEFAULT_PIE_COLORS, DataTable, DataTableActionsCell, DataTableAvatarCell, DataTableBadgesCell, DataTableCell, DataTableCellRoot, DataTableProgressCell, DataTableRatingCell, DataTableSparklineCell, DataTableSwitchCell, DataTableTextCell, DataTableToolbar, DataTableTrendCell, DateFilterButton, DatePicker, DateRangeFilterButton, DateRangePicker, Dialog, Action$1 as DialogAction, Backdrop$1 as DialogBackdrop, Body as DialogBody, Cancel$1 as DialogCancel, Close as DialogClose, Description$1 as DialogDescription, Footer$1 as DialogFooter, Header$1 as DialogHeader, HeaderContent as DialogHeaderContent, Icon as DialogIcon, Popup$2 as DialogPopup, Portal$2 as DialogPortal, Root$2 as DialogRoot, Title$1 as DialogTitle, Trigger$2 as DialogTrigger, Viewport$1 as DialogViewport, DisplayValue, DonutChart, Dot, DotCircleSpinner, Drawer, Backdrop$2 as DrawerBackdrop, Close$1 as DrawerClose, Description$2 as DrawerDescription, Footer$2 as DrawerFooter, Handle as DrawerHandle, Header$2 as DrawerHeader, Popup$3 as DrawerPopup, Portal$3 as DrawerPortal, Root$3 as DrawerRoot, Title$2 as DrawerTitle, Trigger$3 as DrawerTrigger, Viewport$2 as DrawerViewport, DropdownMenu, EmptyState, EmptyStateBackgroundPattern, EmptyStateIllustration, FadeText, FeaturedIcon, FeedbackButton, Field, FieldBottom, FieldBottomRight, FieldControl, FieldDescription, FieldError, FieldLabel, FieldTop, FieldTopRight, Fieldset, FileInput, FileTypeIcon, FileUpload, FileUploadArea, FileUploadItem, FooterNavIcon, FooterNavText, ForgotPasswordPage, Form, GroupingControls, History, HistoryValue, HorizontalBarChart, HoverCardCompound as HoverCard, HoverCardPopup, HoverCardTrigger, ICONS, InlineCTA, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, Item$1 as Item, KIND_TO_FILE, Kbd, KbdGroup, LineChart, LineSimpleSpinner, LineSpinner, LoadingIndicator, LoginPage, MAC_KEYS, MOBILE_BREAKPOINT, MetricCard, MetricChange, MetricItem, MetricMiniChart, NavAccountMenu, NavAccountMenuAccount, NavAccountMenuContent, NavAccountMenuFooter, NavAccountMenuHeader, NavAccountMenuItem, NavAccountMenuSection, NavAccountMenuSeparator, NavAccountMenuThemeSwitch, NavAccountMenuTrigger, NotificationPanel, NotificationPanelItem, NotificationSection, NumberInput, PageBackground, PageHeader, Pagination, PaginationDots, PanelExpansionContext, PanelIndexContext, PanelLayoutContext, PieChart, PopoverCompound as Popover, PopoverDescription, PopoverHeader, PopoverPopup, PopoverRoot, PopoverTitle, PopoverTrigger, Progress, RadarChart, RadialChart, RadioGroup$1 as RadioGroup, Rating, RegisterPage, ResetPasswordPage, ResizableHandle, ResizablePanel, ResizablePanelGroup, RichTextarea, RichTextareaToolbar, SIZE_MAP, ScrollArea, ScrollBar, SectionHeader, Select, SelectCompound, SelectGroup, SelectGroupLabel, SelectItem, SelectPopup, SelectRoot, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectTriggerIcon, SelectValue, Separator$1 as Separator, Sheet, Backdrop$3 as SheetBackdrop, Body$1 as SheetBody, Close$2 as SheetClose, Description$3 as SheetDescription, Divider as SheetDivider, Footer$3 as SheetFooter, Header$3 as SheetHeader, Popup$4 as SheetPopup, Portal$4 as SheetPortal, Root$4 as SheetRoot, Section as SheetSection, Title$3 as SheetTitle, Trigger$4 as SheetTrigger, Viewport$3 as SheetViewport, Shortcut$1 as Shortcut, SidebarCompound as Sidebar, SidebarAccountSkeleton, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInset, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarNavSkeleton, SidebarProvider, SidebarTrigger, Skeleton, Slider, SliderBase, SonnerItem, SortableHeader, SourceFavicon, SparklineChart, StatusIcon, StepsCompound as Steps, StepsItem, StepsSubtext, SubmitButton, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsIndicator, TabsList, TabsTrigger, TabsTriggerWithCount, Textarea, ThemeProvider, ThemeScript, ThinkingIndicator, TimePicker, ToastContent, Toaster, Toggle, ToggleGroup, ToggleGroupItem, ToolCallSection, ToolbarButton, ToolbarDivider, TooltipCompound as Tooltip, TooltipAvatar, TooltipBadge, TooltipContent, TooltipIcon, TooltipImage, TooltipPopup, TooltipProvider, TooltipRoot, TooltipSubtitle, TooltipTitle, TooltipTrigger, TwoFactorAuthenticationPage, TypewriterText, VerifyEmailPage as VerifyEmail, VerifyEmailPage, WIN_KEYS, WorkflowAddNode, WorkflowCircleNode, WorkflowComment, WorkflowConnection, WorkflowNode, WorkflowPort, activityFeedVariants, activityItemVariants, stepIconVariants as aiStepIconVariants, stepItemVariants as aiStepItemVariants, stepsContainerVariants as aiStepsContainerVariants, alertVariants, analyzePaste, appShellBackgrounds, areaChartVariants, arrowVariants, asciiDiagramVariants, asciiToSvg, badgeVariants, bannerVariants, barChartVariants, breadcrumbItemVariants, buttonVariants, chatItemVariants, cn, codeBlockVariants, codeSnippetVariants, comboboxContentVariants, comboboxTriggerVariants, contentVariants, createSelectColumn, dataTableCellVariants, dataTableHeaderCellVariants, dataTableRowVariants, dataTableVariants, defaultFooterHints, detectPasteKind, footerVariants as dialogFooterVariants, headerVariants as dialogHeaderVariants, iconVariants as dialogIconVariants, popupVariants as dialogPopupVariants, donutChartVariants, extensionColors, feedbackBarVariants, feedbackButtonVariants, fileInputSizeClasses, fileUploadAreaVariants, fileUploadItemVariants, formatInteractionForLLM, getThemeScript, historyEventCategoryConfig, historyHeaderActionConfig, horizontalBarChartVariants, indicatorVariants, inlineCTAVariants, sizeClasses as inputSizeClasses, stateClasses as inputStateClasses, inputVariants, isAsciiDiagram, itemVariants, kbdGroupVariants, kbdVariants, lineChartVariants, lineNumberVariants, loadingIndicatorVariants, loadingTextVariants, looksLikeAsciiDiagram, looksLikeSimpleAscii, mapKindToFile, messageBubbleVariants, messageVariants, metricCardVariants, metricChangeVariants, metricItemVariants, metricMiniChartVariants, triggerVariants as navAccountMenuTriggerVariants, navItemVariants, notificationDotVariants, notificationPanelVariants, pageHeaderVariants, paginationDotIndicatorVariants, paginationDotsVariants, pieChartVariants, progressVariants, promptSuggestionVariants, radarChartVariants, radialChartVariants, reasoningBlockVariants, renderActionElement, sanitizeKey, scrollButtonVariants, segmentVariants, shimmerPresets, shouldConvertPaste, sonnerToast, sourceVariants, statusIconVariants, stepConnectorVariants, stepIndicatorVariants, stepLabelVariants, stepSubtextVariants, systemMessageIconVariants, systemMessageVariants, tabsListVariants, tabsTriggerVariants, textShimmerVariants, toast, toggleVariants, toolCallVariants, tooltipVariants, tryAsciiToSvg, useAIInputContext, useAIInteraction, useAIMessageContext, useAccordionCard, useAppShell, useCalendarContext, useDataTable, useDropZone, useFieldContextOptional, useFieldControlProps, useInteractionHandler, useIsMobile, usePanelExpansion, useScrollToBottom, useSidebar, useTextStream, useTheme, useThemeOptional, validateAIToolRunSnapshot };
142
+ import { APP_SIDEBAR_COLLAPSED_WIDTH, APP_SIDEBAR_EXPANDED_WIDTH } from "./index217.js";
143
+ import { PanelExpansionContext, PanelIndexContext, PanelLayoutContext, useAppShell, usePanelExpansion } from "./index218.js";
144
+ import { AppShellContent } from "./index219.js";
145
+ import { AppShellPanel } from "./index221.js";
146
+ import { AppShell, AppShellHeader, AppShellRoot, AppShellSidebar, appShellBackgrounds } from "./index223.js";
147
+ import { AppShellCard } from "./index224.js";
148
+ import { AppSidebar, chatItemVariants, navItemVariants } from "./index225.js";
149
+ import { PageBackground } from "./index226.js";
150
+ import { AuthAsidePanel, AuthPageLayout, renderActionElement } from "./index227.js";
151
+ import { NavAccountMenu, NavAccountMenuAccount, NavAccountMenuContent, NavAccountMenuFooter, NavAccountMenuHeader, NavAccountMenuItem, NavAccountMenuSection, NavAccountMenuSeparator, NavAccountMenuThemeSwitch, NavAccountMenuTrigger, navAccountMenuTriggerVariants as triggerVariants } from "./index228.js";
152
+ import { ForgotPasswordPage } from "./index230.js";
153
+ import { LoginPage } from "./index231.js";
154
+ import { RegisterPage } from "./index232.js";
155
+ import { ResetPasswordPage } from "./index233.js";
156
+ import { TwoFactorAuthenticationPage } from "./index234.js";
157
+ import { VerifyEmail as VerifyEmailPage } from "./index235.js";
158
+ import { formatInteractionForLLM } from "./index236.js";
159
+ import { useInteractionHandler } from "./index237.js";
160
+ export { AIAsciiDiagram, AIChart, AIClarificationCard, AICodeBlock, AICodeBlockContent, AICodeBlockHeader, AIComponent, AIContainerCompound as AIContainer, AIContainerContext, AIContextIndicator, AIEmptyState, AIEmptyStateActions, AIEmptyStateDescription, AIEmptyStateIcon, AIEmptyStateRoot, AIEmptyStateSuggestionGrid, AIEmptyStateTitle, AIFeedbackBar, AIFeedbackIcons, AIForm, AIInput, AIInputActionBar, AIInputActions, AIInputAttachButton, AIInputFilePreview, AIInputLeadingIcon, AIInputRoot, AIInputSendButton, AIInputTextArea, AIInteractionContext, AIInteractionProvider, AILoadingDots, AIMermaidDiagram, AIMessage, AIMessageActions, AIMessageAttachmentPreview, AIMessageAttachments, AIMessageAvatar, AIMessageBubble, AIMessageContent, AIMessageCopyButton, AIMessageHeader, AIMessageListButton, AIMessageReactions, AIMessageRoot, AIMessageThumbsDown, AIMessageThumbsUp, AIMessageTypingIndicator, AIPromptSuggestion, AIPromptSuggestionCard, AIPromptSuggestionList, AIPulseText, AIQuickActions, AIReasoningBlock, AIReasoningContent, AIReasoningTrigger, AIResponseStream, AIScrollAnchor, AIScrollButton, AISelect, AISource, AISourceContent, AISourceList, AISourceTrigger, StepIcon as AIStepIcon, AIStepItem, AISteps, AISystemMessage, AISystemMessageBanner, AITable, AITextShimmer, AIThinkingBar, AIThinkingLoader, AIToolCall, AIToolCallHeader, AIToolCallList, AIToolRun, AITypingIndicator, AITypingText, APP_SIDEBAR_COLLAPSED_WIDTH, APP_SIDEBAR_EXPANDED_WIDTH, AccordionCompound as Accordion, AccordionCardNamespace as AccordionCard, AccordionCardContent, AccordionCardEdit, AccordionCardHeader, AccordionCardTitle, AccordionCardTrigger, AccordionContent, AccordionItem, AccordionTrigger, ActionButton, ActivityFeed, ActivityFeedItem, AdvancedRating, Alert, AlertDescription, AlertDialog, Action as AlertDialogAction, Backdrop as AlertDialogBackdrop, Cancel as AlertDialogCancel, Description as AlertDialogDescription, Footer as AlertDialogFooter, Header as AlertDialogHeader, Media as AlertDialogMedia, Popup as AlertDialogPopup, Portal as AlertDialogPortal, Root as AlertDialogRoot, Title as AlertDialogTitle, Trigger as AlertDialogTrigger, Viewport as AlertDialogViewport, AlertTitle, AppShell, AppShellCard, AppShellContent, AppShellHeader, AppShellPanel, AppShellRoot, AppShellSidebar, AppSidebar, AreaChart, AuthAsidePanel, AuthPageLayout, Autocomplete, Avatar, AvatarGroup, Badge, BadgeDot, BarChart, BrandIcon, BreadcrumbCompound as Breadcrumb, BreadcrumbEllipsis, BreadcrumbHomeLink, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, Calendar, CalendarActions, CalendarContent, CalendarHeader, CalendarNavigation, CalendarSearch, CalendarTitle, CalendarViewSwitcher, Card, Carousel, CarouselNav, CarouselVisual, ChartCard, ChartLegend, Checkbox, CheckboxGroup, ClearButton, CodeSnippet, Collapsible, CollapsibleContent, CollapsibleTrigger, ComboboxContent, ComboboxGroup, ComboboxHeader, ComboboxItem, ComboboxMenu, ComboboxRoot, ComboboxSeparator, ComboboxShortcut, ComboboxTrigger, CommandMenu, CommandMenuFooter, CommandMenuGroupHeader, CommandMenuItem, CommandMenuPanel, CommandShortcutBadge, CompactActionButton, ContextMenu, CheckboxItem as ContextMenuCheckboxItem, Group as ContextMenuGroup, Item as ContextMenuItem, Label as ContextMenuLabel, Popup$1 as ContextMenuPopup, Portal$1 as ContextMenuPortal, RadioGroup as ContextMenuRadioGroup, RadioItem as ContextMenuRadioItem, Root$1 as ContextMenuRoot, Separator as ContextMenuSeparator, Shortcut as ContextMenuShortcut, Sub as ContextMenuSub, SubPopup as ContextMenuSubPopup, SubTrigger as ContextMenuSubTrigger, Trigger$1 as ContextMenuTrigger, CountdownTimer, DEFAULT_CHART_COLORS, DEFAULT_DONUT_COLORS, DEFAULT_PIE_COLORS, DataTable, DataTableActionsCell, DataTableAvatarCell, DataTableBadgesCell, DataTableCell, DataTableCellRoot, DataTableProgressCell, DataTableRatingCell, DataTableSparklineCell, DataTableSwitchCell, DataTableTextCell, DataTableToolbar, DataTableTrendCell, DateFilterButton, DatePicker, DateRangeFilterButton, DateRangePicker, Dialog, Action$1 as DialogAction, Backdrop$1 as DialogBackdrop, Body as DialogBody, Cancel$1 as DialogCancel, Close as DialogClose, Description$1 as DialogDescription, Footer$1 as DialogFooter, Header$1 as DialogHeader, HeaderContent as DialogHeaderContent, Icon as DialogIcon, Popup$2 as DialogPopup, Portal$2 as DialogPortal, Root$2 as DialogRoot, Title$1 as DialogTitle, Trigger$2 as DialogTrigger, Viewport$1 as DialogViewport, DisplayValue, DonutChart, Dot, DotCircleSpinner, Drawer, Backdrop$2 as DrawerBackdrop, Close$1 as DrawerClose, Description$2 as DrawerDescription, Footer$2 as DrawerFooter, Handle as DrawerHandle, Header$2 as DrawerHeader, Popup$3 as DrawerPopup, Portal$3 as DrawerPortal, Root$3 as DrawerRoot, Title$2 as DrawerTitle, Trigger$3 as DrawerTrigger, Viewport$2 as DrawerViewport, DropdownMenu, EmptyState, EmptyStateBackgroundPattern, EmptyStateIllustration, FadeText, FeaturedIcon, FeedbackButton, Field, FieldBottom, FieldBottomRight, FieldControl, FieldDescription, FieldError, FieldLabel, FieldTop, FieldTopRight, Fieldset, FileInput, FileTypeIcon, FileUpload, FileUploadArea, FileUploadItem, FooterNavIcon, FooterNavText, ForgotPasswordPage, Form, GroupingControls, History, HistoryValue, HorizontalBarChart, HoverCardCompound as HoverCard, HoverCardPopup, HoverCardTrigger, ICONS, InlineCTA, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, Item$1 as Item, KIND_TO_FILE, Kbd, KbdGroup, LineChart, LineSimpleSpinner, LineSpinner, LoadingIndicator, LoginPage, MAC_KEYS, MOBILE_BREAKPOINT, MetricCard, MetricChange, MetricItem, MetricMiniChart, NavAccountMenu, NavAccountMenuAccount, NavAccountMenuContent, NavAccountMenuFooter, NavAccountMenuHeader, NavAccountMenuItem, NavAccountMenuSection, NavAccountMenuSeparator, NavAccountMenuThemeSwitch, NavAccountMenuTrigger, NotificationPanel, NotificationPanelItem, NotificationSection, NumberInput, PageBackground, PageHeader, Pagination, PaginationDots, PanelExpansionContext, PanelIndexContext, PanelLayoutContext, PieChart, PopoverCompound as Popover, PopoverDescription, PopoverHeader, PopoverPopup, PopoverRoot, PopoverTitle, PopoverTrigger, Progress, RadarChart, RadialChart, RadioGroup$1 as RadioGroup, Rating, RegisterPage, ResetPasswordPage, ResizableHandle, ResizablePanel, ResizablePanelGroup, RichTextarea, RichTextareaToolbar, SIZE_MAP, ScrollArea, ScrollBar, SectionHeader, Select, SelectCompound, SelectGroup, SelectGroupLabel, SelectItem, SelectPopup, SelectRoot, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectTriggerIcon, SelectValue, Separator$1 as Separator, Sheet, Backdrop$3 as SheetBackdrop, Body$1 as SheetBody, Close$2 as SheetClose, Description$3 as SheetDescription, Divider as SheetDivider, Footer$3 as SheetFooter, Header$3 as SheetHeader, Popup$4 as SheetPopup, Portal$4 as SheetPortal, Root$4 as SheetRoot, Section as SheetSection, Title$3 as SheetTitle, Trigger$4 as SheetTrigger, Viewport$3 as SheetViewport, Shortcut$1 as Shortcut, SidebarCompound as Sidebar, SidebarAccountSkeleton, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInset, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarNavSkeleton, SidebarProvider, SidebarTrigger, Skeleton, Slider, SliderBase, SonnerItem, SortableHeader, SourceFavicon, SparklineChart, StatusIcon, StepsCompound as Steps, StepsItem, StepsSubtext, SubmitButton, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsIndicator, TabsList, TabsTrigger, TabsTriggerWithCount, Textarea, ThemeProvider, ThemeScript, ThinkingIndicator, TimePicker, ToastContent, Toaster, Toggle, ToggleGroup, ToggleGroupItem, ToolCallSection, ToolbarButton, ToolbarDivider, TooltipCompound as Tooltip, TooltipAvatar, TooltipBadge, TooltipContent, TooltipIcon, TooltipImage, TooltipPopup, TooltipProvider, TooltipRoot, TooltipSubtitle, TooltipTitle, TooltipTrigger, TwoFactorAuthenticationPage, TypewriterText, VerifyEmailPage as VerifyEmail, VerifyEmailPage, WIN_KEYS, WorkflowAddNode, WorkflowCircleNode, WorkflowComment, WorkflowConnection, WorkflowNode, WorkflowPort, activityFeedVariants, activityItemVariants, stepIconVariants as aiStepIconVariants, stepItemVariants as aiStepItemVariants, stepsContainerVariants as aiStepsContainerVariants, alertVariants, analyzePaste, appShellBackgrounds, areaChartVariants, arrowVariants, asciiDiagramVariants, asciiToSvg, badgeVariants, bannerVariants, barChartVariants, breadcrumbItemVariants, buttonVariants, chatItemVariants, cn, codeBlockVariants, codeSnippetVariants, comboboxContentVariants, comboboxTriggerVariants, contentVariants, createSelectColumn, dataTableCellVariants, dataTableHeaderCellVariants, dataTableRowVariants, dataTableVariants, defaultFooterHints, detectPasteKind, footerVariants as dialogFooterVariants, headerVariants as dialogHeaderVariants, iconVariants as dialogIconVariants, popupVariants as dialogPopupVariants, donutChartVariants, extensionColors, feedbackBarVariants, feedbackButtonVariants, fileInputSizeClasses, fileUploadAreaVariants, fileUploadItemVariants, formatInteractionForLLM, getThemeScript, historyEventCategoryConfig, historyHeaderActionConfig, horizontalBarChartVariants, indicatorVariants, inlineCTAVariants, sizeClasses as inputSizeClasses, stateClasses as inputStateClasses, inputVariants, isAsciiDiagram, itemVariants, kbdGroupVariants, kbdVariants, lineChartVariants, lineNumberVariants, loadingIndicatorVariants, loadingTextVariants, looksLikeAsciiDiagram, looksLikeSimpleAscii, mapKindToFile, messageBubbleVariants, messageVariants, metricCardVariants, metricChangeVariants, metricItemVariants, metricMiniChartVariants, triggerVariants as navAccountMenuTriggerVariants, navItemVariants, notificationDotVariants, notificationPanelVariants, pageHeaderVariants, paginationDotIndicatorVariants, paginationDotsVariants, pieChartVariants, progressVariants, promptSuggestionVariants, radarChartVariants, radialChartVariants, reasoningBlockVariants, renderActionElement, sanitizeKey, scrollButtonVariants, segmentVariants, shimmerPresets, shouldConvertPaste, sonnerToast, sourceVariants, statusIconVariants, stepConnectorVariants, stepIndicatorVariants, stepLabelVariants, stepSubtextVariants, systemMessageIconVariants, systemMessageVariants, tabsListVariants, tabsTriggerVariants, textShimmerVariants, toast, toggleVariants, toolCallVariants, tooltipVariants, tryAsciiToSvg, useAIInputContext, useAIInteraction, useAIMessageContext, useAccordionCard, useAppShell, useCalendarContext, useDataTable, useDropZone, useFieldContextOptional, useFieldControlProps, useInteractionHandler, useIsMobile, usePanelExpansion, useScrollToBottom, useSidebar, useTextStream, useTheme, useThemeOptional, validateAIToolRunSnapshot };
package/dist/index152.js CHANGED
@@ -106,7 +106,7 @@ function createMarkdownComponents(variant) {
106
106
  ...props
107
107
  }),
108
108
  table: ({ className, children, ...props }) => /* @__PURE__ */ jsx("section", {
109
- className: "overflow-x-auto my-4 [overflow-wrap:normal] [&_a]:break-normal [&_a]:[overflow-wrap:normal] [&_code]:break-normal [&_code]:[overflow-wrap:normal] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring",
109
+ className: "not-prose overflow-x-auto my-4 [overflow-wrap:normal] [&_a]:break-normal [&_a]:[overflow-wrap:normal] [&_code]:break-normal [&_code]:[overflow-wrap:normal] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring",
110
110
  "aria-label": "Data table",
111
111
  tabIndex: 0,
112
112
  children: /* @__PURE__ */ jsx("table", {
@@ -1 +1 @@
1
- {"version":3,"file":"index152.js","names":[],"sources":["../src/components/organisms/ai/_shared/markdown-renderer.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport ReactMarkdown, { type Components } from 'react-markdown';\nimport rehypeKatex from 'rehype-katex';\nimport remarkGfm from 'remark-gfm';\nimport remarkMath from 'remark-math';\nimport type { PluggableList } from 'unified';\nimport { cn } from '@/lib/utils';\nimport { createCodeComponent } from './code-handler';\n\nconst remarkPlugins: PluggableList = [remarkGfm, remarkMath];\nconst rehypePlugins: PluggableList = [[rehypeKatex, { output: 'mathml' }]];\nconst markdownOverflowWrapClasses =\n 'min-w-0 max-w-full break-words [overflow-wrap:anywhere]';\n\n// =============================================================================\n// Variant-aware color mapping\n// =============================================================================\n\nimport type { MarkdownVariant } from './types';\n\nexport type { MarkdownVariant } from './types';\n\nconst variantColors = {\n heading: { default: 'text-foreground', inverted: 'text-primary-foreground' },\n body: {\n default: 'text-secondary-foreground',\n inverted: 'text-primary-foreground/90',\n },\n link: { default: 'text-primary', inverted: 'text-primary-foreground' },\n muted: {\n default: 'text-muted-foreground',\n inverted: 'text-primary-foreground/70',\n },\n faint: {\n default: 'text-text-quaternary',\n inverted: 'text-primary-foreground/50',\n },\n border: {\n default: 'border-border',\n inverted: 'border-primary-foreground/25',\n },\n bgMuted: { default: 'bg-muted', inverted: 'bg-primary-foreground/20' },\n} as const;\n\ntype ColorToken = keyof typeof variantColors;\n\nfunction vc(variant: MarkdownVariant, token: ColorToken): string {\n return variantColors[token][variant];\n}\n\n// =============================================================================\n// Create variant-aware component overrides for react-markdown\n// =============================================================================\n\nfunction createMarkdownComponents(\n variant: MarkdownVariant,\n): Partial<Components> {\n return {\n h1: ({ className, children, ...props }) => (\n <h1\n className={cn(\n 'text-display-xs font-bold mt-6 mb-4',\n markdownOverflowWrapClasses,\n vc(variant, 'heading'),\n className,\n )}\n {...props}\n >\n {children}\n </h1>\n ),\n h2: ({ className, children, ...props }) => (\n <h2\n className={cn(\n 'text-xl font-semibold mt-5 mb-3',\n markdownOverflowWrapClasses,\n vc(variant, 'heading'),\n className,\n )}\n {...props}\n >\n {children}\n </h2>\n ),\n h3: ({ className, children, ...props }) => (\n <h3\n className={cn(\n 'text-lg font-semibold mt-4 mb-2',\n markdownOverflowWrapClasses,\n vc(variant, 'heading'),\n className,\n )}\n {...props}\n >\n {children}\n </h3>\n ),\n h4: ({ className, children, ...props }) => (\n <h4\n className={cn(\n 'text-base font-semibold mt-3 mb-2',\n markdownOverflowWrapClasses,\n vc(variant, 'heading'),\n className,\n )}\n {...props}\n >\n {children}\n </h4>\n ),\n p: ({ className, children, ...props }) => (\n <p\n className={cn(\n 'text-base leading-relaxed mb-4',\n markdownOverflowWrapClasses,\n vc(variant, 'body'),\n className,\n )}\n {...props}\n >\n {children}\n </p>\n ),\n ul: ({ className, children, ...props }) => (\n <ul\n className={cn(\n 'list-disc list-inside mb-4 space-y-1',\n markdownOverflowWrapClasses,\n vc(variant, 'body'),\n className,\n )}\n {...props}\n >\n {children}\n </ul>\n ),\n ol: ({ className, children, ...props }) => (\n <ol\n className={cn(\n 'list-decimal list-inside mb-4 space-y-1',\n markdownOverflowWrapClasses,\n vc(variant, 'body'),\n className,\n )}\n {...props}\n >\n {children}\n </ol>\n ),\n li: ({ className, children, ...props }) => (\n <li\n className={cn(\n 'leading-relaxed',\n markdownOverflowWrapClasses,\n className,\n )}\n {...props}\n >\n {children}\n </li>\n ),\n a: ({ className, children, href, ...props }) => (\n <a\n href={href}\n className={cn(\n 'underline underline-offset-2 transition-colors focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring rounded-sm',\n markdownOverflowWrapClasses,\n vc(variant, 'link'),\n variant === 'default' && 'hover:text-primary',\n variant === 'inverted' && 'hover:text-primary-foreground',\n className,\n )}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n {...props}\n >\n {children}\n </a>\n ),\n blockquote: ({ className, children, ...props }) => (\n <blockquote\n className={cn(\n 'border-s-4 ps-4 py-2 my-4 italic',\n markdownOverflowWrapClasses,\n vc(variant, 'muted'),\n vc(variant, 'border'),\n className,\n )}\n {...props}\n >\n {children}\n </blockquote>\n ),\n code: createCodeComponent(variant),\n pre: ({ children }) => <>{children}</>,\n hr: ({ className, ...props }) => (\n <hr className={cn('my-6', vc(variant, 'border'), className)} {...props} />\n ),\n table: ({ className, children, ...props }) => (\n <section\n className=\"overflow-x-auto my-4 [overflow-wrap:normal] [&_a]:break-normal [&_a]:[overflow-wrap:normal] [&_code]:break-normal [&_code]:[overflow-wrap:normal] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring\"\n aria-label=\"Data table\"\n // biome-ignore lint/a11y/noNoninteractiveTabindex: Focusable scroll region satisfies axe scrollable-region-focusable.\n tabIndex={0}\n >\n <table\n className={cn(\n 'min-w-full border-collapse border [overflow-wrap:normal]',\n vc(variant, 'border'),\n variant === 'inverted' && '!bg-transparent',\n className,\n )}\n {...props}\n >\n {children}\n </table>\n </section>\n ),\n thead: ({ className, children, ...props }) => (\n <thead\n className={cn(\n variant === 'default' ? vc(variant, 'bgMuted') : '!bg-transparent',\n className,\n )}\n {...props}\n >\n {children}\n </thead>\n ),\n tbody: ({ className, children, ...props }) => (\n <tbody\n className={cn(\n variant === 'default'\n ? 'divide-y divide-border'\n : 'divide-y divide-primary-foreground/20',\n className,\n )}\n {...props}\n >\n {children}\n </tbody>\n ),\n tr: ({ children, ...props }) => <tr {...props}>{children}</tr>,\n th: ({ className, children, ...props }) => (\n <th\n className={cn(\n 'px-4 py-2 text-start text-sm font-semibold border',\n '[overflow-wrap:normal]',\n vc(variant, 'body'),\n vc(variant, 'border'),\n variant === 'inverted' && '!bg-transparent',\n className,\n )}\n {...props}\n >\n {children}\n </th>\n ),\n td: ({ className, children, ...props }) => (\n <td\n className={cn(\n 'px-4 py-2 text-sm border',\n '[overflow-wrap:normal]',\n vc(variant, 'body'),\n vc(variant, 'border'),\n variant === 'inverted' && '!bg-transparent',\n className,\n )}\n {...props}\n >\n {children}\n </td>\n ),\n strong: ({ className, children, ...props }) => (\n <strong\n className={cn(\n 'font-semibold',\n markdownOverflowWrapClasses,\n vc(variant, 'heading'),\n className,\n )}\n {...props}\n >\n {children}\n </strong>\n ),\n em: ({ className, children, ...props }) => (\n <em className={cn(markdownOverflowWrapClasses, className)} {...props}>\n {children}\n </em>\n ),\n del: ({ className, children, ...props }) => (\n <del\n className={cn(\n 'line-through',\n markdownOverflowWrapClasses,\n vc(variant, 'faint'),\n className,\n )}\n {...props}\n >\n {children}\n </del>\n ),\n img: ({ className, alt, src, ...props }) => (\n <img\n src={src}\n alt={alt}\n className={cn('max-w-full h-auto rounded-lg my-4', className)}\n loading=\"lazy\"\n {...props}\n />\n ),\n };\n}\n\n// =============================================================================\n// Component cache (at most 2 entries: 'default' and 'inverted')\n// =============================================================================\n\nconst componentCache = new Map<MarkdownVariant, Partial<Components>>();\n\nfunction getComponents(variant: MarkdownVariant): Partial<Components> {\n let cached = componentCache.get(variant);\n if (!cached) {\n cached = createMarkdownComponents(variant);\n componentCache.set(variant, cached);\n }\n return cached;\n}\n\n// =============================================================================\n// MarkdownRenderer\n// =============================================================================\n\nexport interface MarkdownRendererProps {\n /** Markdown content to render */\n children: string;\n /** Additional class name */\n className?: string;\n /** Color variant — 'inverted' for white text on colored backgrounds */\n variant?: MarkdownVariant;\n}\n\nconst MarkdownRenderer = React.memo(function MarkdownRenderer({\n children,\n className,\n variant = 'default',\n}: MarkdownRendererProps) {\n const components = getComponents(variant);\n\n return (\n <div\n data-slot=\"ai-markdown\"\n className={cn(\n 'prose prose-gray max-w-none',\n markdownOverflowWrapClasses,\n className,\n )}\n >\n <ReactMarkdown\n remarkPlugins={remarkPlugins}\n rehypePlugins={rehypePlugins}\n components={components}\n >\n {children}\n </ReactMarkdown>\n </div>\n );\n});\n\nMarkdownRenderer.displayName = 'MarkdownRenderer';\n\nexport { MarkdownRenderer };\n"],"mappings":"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"}
1
+ {"version":3,"file":"index152.js","names":[],"sources":["../src/components/organisms/ai/_shared/markdown-renderer.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport ReactMarkdown, { type Components } from 'react-markdown';\nimport rehypeKatex from 'rehype-katex';\nimport remarkGfm from 'remark-gfm';\nimport remarkMath from 'remark-math';\nimport type { PluggableList } from 'unified';\nimport { cn } from '@/lib/utils';\nimport { createCodeComponent } from './code-handler';\n\nconst remarkPlugins: PluggableList = [remarkGfm, remarkMath];\nconst rehypePlugins: PluggableList = [[rehypeKatex, { output: 'mathml' }]];\nconst markdownOverflowWrapClasses =\n 'min-w-0 max-w-full break-words [overflow-wrap:anywhere]';\n\n// =============================================================================\n// Variant-aware color mapping\n// =============================================================================\n\nimport type { MarkdownVariant } from './types';\n\nexport type { MarkdownVariant } from './types';\n\nconst variantColors = {\n heading: { default: 'text-foreground', inverted: 'text-primary-foreground' },\n body: {\n default: 'text-secondary-foreground',\n inverted: 'text-primary-foreground/90',\n },\n link: { default: 'text-primary', inverted: 'text-primary-foreground' },\n muted: {\n default: 'text-muted-foreground',\n inverted: 'text-primary-foreground/70',\n },\n faint: {\n default: 'text-text-quaternary',\n inverted: 'text-primary-foreground/50',\n },\n border: {\n default: 'border-border',\n inverted: 'border-primary-foreground/25',\n },\n bgMuted: { default: 'bg-muted', inverted: 'bg-primary-foreground/20' },\n} as const;\n\ntype ColorToken = keyof typeof variantColors;\n\nfunction vc(variant: MarkdownVariant, token: ColorToken): string {\n return variantColors[token][variant];\n}\n\n// =============================================================================\n// Create variant-aware component overrides for react-markdown\n// =============================================================================\n\nfunction createMarkdownComponents(\n variant: MarkdownVariant,\n): Partial<Components> {\n return {\n h1: ({ className, children, ...props }) => (\n <h1\n className={cn(\n 'text-display-xs font-bold mt-6 mb-4',\n markdownOverflowWrapClasses,\n vc(variant, 'heading'),\n className,\n )}\n {...props}\n >\n {children}\n </h1>\n ),\n h2: ({ className, children, ...props }) => (\n <h2\n className={cn(\n 'text-xl font-semibold mt-5 mb-3',\n markdownOverflowWrapClasses,\n vc(variant, 'heading'),\n className,\n )}\n {...props}\n >\n {children}\n </h2>\n ),\n h3: ({ className, children, ...props }) => (\n <h3\n className={cn(\n 'text-lg font-semibold mt-4 mb-2',\n markdownOverflowWrapClasses,\n vc(variant, 'heading'),\n className,\n )}\n {...props}\n >\n {children}\n </h3>\n ),\n h4: ({ className, children, ...props }) => (\n <h4\n className={cn(\n 'text-base font-semibold mt-3 mb-2',\n markdownOverflowWrapClasses,\n vc(variant, 'heading'),\n className,\n )}\n {...props}\n >\n {children}\n </h4>\n ),\n p: ({ className, children, ...props }) => (\n <p\n className={cn(\n 'text-base leading-relaxed mb-4',\n markdownOverflowWrapClasses,\n vc(variant, 'body'),\n className,\n )}\n {...props}\n >\n {children}\n </p>\n ),\n ul: ({ className, children, ...props }) => (\n <ul\n className={cn(\n 'list-disc list-inside mb-4 space-y-1',\n markdownOverflowWrapClasses,\n vc(variant, 'body'),\n className,\n )}\n {...props}\n >\n {children}\n </ul>\n ),\n ol: ({ className, children, ...props }) => (\n <ol\n className={cn(\n 'list-decimal list-inside mb-4 space-y-1',\n markdownOverflowWrapClasses,\n vc(variant, 'body'),\n className,\n )}\n {...props}\n >\n {children}\n </ol>\n ),\n li: ({ className, children, ...props }) => (\n <li\n className={cn(\n 'leading-relaxed',\n markdownOverflowWrapClasses,\n className,\n )}\n {...props}\n >\n {children}\n </li>\n ),\n a: ({ className, children, href, ...props }) => (\n <a\n href={href}\n className={cn(\n 'underline underline-offset-2 transition-colors focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring rounded-sm',\n markdownOverflowWrapClasses,\n vc(variant, 'link'),\n variant === 'default' && 'hover:text-primary',\n variant === 'inverted' && 'hover:text-primary-foreground',\n className,\n )}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n {...props}\n >\n {children}\n </a>\n ),\n blockquote: ({ className, children, ...props }) => (\n <blockquote\n className={cn(\n 'border-s-4 ps-4 py-2 my-4 italic',\n markdownOverflowWrapClasses,\n vc(variant, 'muted'),\n vc(variant, 'border'),\n className,\n )}\n {...props}\n >\n {children}\n </blockquote>\n ),\n code: createCodeComponent(variant),\n pre: ({ children }) => <>{children}</>,\n hr: ({ className, ...props }) => (\n <hr className={cn('my-6', vc(variant, 'border'), className)} {...props} />\n ),\n table: ({ className, children, ...props }) => (\n <section\n className=\"not-prose overflow-x-auto my-4 [overflow-wrap:normal] [&_a]:break-normal [&_a]:[overflow-wrap:normal] [&_code]:break-normal [&_code]:[overflow-wrap:normal] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring\"\n aria-label=\"Data table\"\n // biome-ignore lint/a11y/noNoninteractiveTabindex: Focusable scroll region satisfies axe scrollable-region-focusable.\n tabIndex={0}\n >\n <table\n className={cn(\n 'min-w-full border-collapse border [overflow-wrap:normal]',\n vc(variant, 'border'),\n variant === 'inverted' && '!bg-transparent',\n className,\n )}\n {...props}\n >\n {children}\n </table>\n </section>\n ),\n thead: ({ className, children, ...props }) => (\n <thead\n className={cn(\n variant === 'default' ? vc(variant, 'bgMuted') : '!bg-transparent',\n className,\n )}\n {...props}\n >\n {children}\n </thead>\n ),\n tbody: ({ className, children, ...props }) => (\n <tbody\n className={cn(\n variant === 'default'\n ? 'divide-y divide-border'\n : 'divide-y divide-primary-foreground/20',\n className,\n )}\n {...props}\n >\n {children}\n </tbody>\n ),\n tr: ({ children, ...props }) => <tr {...props}>{children}</tr>,\n th: ({ className, children, ...props }) => (\n <th\n className={cn(\n 'px-4 py-2 text-start text-sm font-semibold border',\n '[overflow-wrap:normal]',\n vc(variant, 'body'),\n vc(variant, 'border'),\n variant === 'inverted' && '!bg-transparent',\n className,\n )}\n {...props}\n >\n {children}\n </th>\n ),\n td: ({ className, children, ...props }) => (\n <td\n className={cn(\n 'px-4 py-2 text-sm border',\n '[overflow-wrap:normal]',\n vc(variant, 'body'),\n vc(variant, 'border'),\n variant === 'inverted' && '!bg-transparent',\n className,\n )}\n {...props}\n >\n {children}\n </td>\n ),\n strong: ({ className, children, ...props }) => (\n <strong\n className={cn(\n 'font-semibold',\n markdownOverflowWrapClasses,\n vc(variant, 'heading'),\n className,\n )}\n {...props}\n >\n {children}\n </strong>\n ),\n em: ({ className, children, ...props }) => (\n <em className={cn(markdownOverflowWrapClasses, className)} {...props}>\n {children}\n </em>\n ),\n del: ({ className, children, ...props }) => (\n <del\n className={cn(\n 'line-through',\n markdownOverflowWrapClasses,\n vc(variant, 'faint'),\n className,\n )}\n {...props}\n >\n {children}\n </del>\n ),\n img: ({ className, alt, src, ...props }) => (\n <img\n src={src}\n alt={alt}\n className={cn('max-w-full h-auto rounded-lg my-4', className)}\n loading=\"lazy\"\n {...props}\n />\n ),\n };\n}\n\n// =============================================================================\n// Component cache (at most 2 entries: 'default' and 'inverted')\n// =============================================================================\n\nconst componentCache = new Map<MarkdownVariant, Partial<Components>>();\n\nfunction getComponents(variant: MarkdownVariant): Partial<Components> {\n let cached = componentCache.get(variant);\n if (!cached) {\n cached = createMarkdownComponents(variant);\n componentCache.set(variant, cached);\n }\n return cached;\n}\n\n// =============================================================================\n// MarkdownRenderer\n// =============================================================================\n\nexport interface MarkdownRendererProps {\n /** Markdown content to render */\n children: string;\n /** Additional class name */\n className?: string;\n /** Color variant — 'inverted' for white text on colored backgrounds */\n variant?: MarkdownVariant;\n}\n\nconst MarkdownRenderer = React.memo(function MarkdownRenderer({\n children,\n className,\n variant = 'default',\n}: MarkdownRendererProps) {\n const components = getComponents(variant);\n\n return (\n <div\n data-slot=\"ai-markdown\"\n className={cn(\n 'prose prose-gray max-w-none',\n markdownOverflowWrapClasses,\n className,\n )}\n >\n <ReactMarkdown\n remarkPlugins={remarkPlugins}\n rehypePlugins={rehypePlugins}\n components={components}\n >\n {children}\n </ReactMarkdown>\n </div>\n );\n});\n\nMarkdownRenderer.displayName = 'MarkdownRenderer';\n\nexport { MarkdownRenderer };\n"],"mappings":"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"}
package/dist/index173.js CHANGED
@@ -9,7 +9,7 @@ var sourceVariants = cva("inline-flex items-center gap-1.5 transition-colors cur
9
9
  variants: { variant: {
10
10
  default: "text-sm text-primary hover:text-primary underline underline-offset-2 rounded-sm",
11
11
  pill: "px-2.5 py-1 rounded-full bg-accent hover:bg-surface-2 text-xs text-secondary-foreground delight-selection-press",
12
- minimal: "text-xs text-text-quaternary hover:text-secondary-foreground rounded-sm"
12
+ minimal: "text-xs text-secondary-foreground hover:text-foreground rounded-sm"
13
13
  } },
14
14
  defaultVariants: { variant: "default" }
15
15
  });
@@ -1 +1 @@
1
- {"version":3,"file":"index173.js","names":[],"sources":["../src/components/organisms/ai/AISource/AISource.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport { ExternalLink, Globe } from 'lucide-react';\nimport * as React from 'react';\nimport { Tooltip, TooltipPopup, TooltipTrigger } from '@/components/ui/tooltip';\nimport { cn } from '@/lib/utils';\n\n// =============================================================================\n// Variants\n// =============================================================================\n\nconst sourceVariants = cva(\n 'inline-flex items-center gap-1.5 transition-colors cursor-pointer focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring',\n {\n variants: {\n variant: {\n default:\n 'text-sm text-primary hover:text-primary underline underline-offset-2 rounded-sm',\n pill: 'px-2.5 py-1 rounded-full bg-accent hover:bg-surface-2 text-xs text-secondary-foreground delight-selection-press',\n minimal:\n 'text-xs text-text-quaternary hover:text-secondary-foreground rounded-sm',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n },\n);\n\nconst DEFAULT_MAX_VISIBLE_SOURCES = 3;\n\nfunction getMaxVisibleSources(maxVisible: number): number {\n return Number.isFinite(maxVisible) && maxVisible >= 0\n ? Math.floor(maxVisible)\n : DEFAULT_MAX_VISIBLE_SOURCES;\n}\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface SourceData {\n /** Source URL */\n url: string;\n /** Display title */\n title?: string;\n /** Source description */\n description?: string;\n /** Favicon URL */\n favicon?: string;\n /** Site name */\n siteName?: string;\n}\n\n// =============================================================================\n// Source Favicon\n// =============================================================================\n\ninterface SourceFaviconProps {\n url: string;\n favicon?: string;\n className?: string;\n}\n\nfunction SourceFavicon({ url, favicon, className }: SourceFaviconProps) {\n const [hasError, setHasError] = React.useState(false);\n\n // Generate favicon URL from domain if not provided\n const faviconUrl = React.useMemo(() => {\n if (favicon) return favicon;\n try {\n const domain = new URL(url).hostname;\n return `https://www.google.com/s2/favicons?domain=${domain}&sz=32`;\n } catch {\n return null;\n }\n }, [url, favicon]);\n\n if (!faviconUrl || hasError) {\n return <Globe className={cn('size-4 text-muted-foreground', className)} />;\n }\n\n return (\n <img\n src={faviconUrl}\n alt=\"\"\n className={cn(\n 'size-4 rounded delight-fade-in motion-reduce:!animate-none',\n className,\n )}\n onError={() => setHasError(true)}\n />\n );\n}\n\nSourceFavicon.displayName = 'SourceFavicon';\n\n// =============================================================================\n// Source Trigger (Clickable element)\n// =============================================================================\n\nexport interface AISourceTriggerProps\n extends VariantProps<typeof sourceVariants> {\n /** Source data */\n source: SourceData;\n /** Whether to show favicon */\n showFavicon?: boolean;\n /** Additional class name */\n className?: string;\n /** Click handler */\n onClick?: () => void;\n}\n\nfunction AISourceTrigger({\n source,\n variant,\n showFavicon = true,\n className,\n onClick,\n}: AISourceTriggerProps) {\n const displayText = source.title || source.siteName || source.url;\n\n const sharedClassName = cn(sourceVariants({ variant }), className);\n const sharedChildren = (\n <>\n {showFavicon && (\n <SourceFavicon url={source.url} favicon={source.favicon} />\n )}\n <span className=\"truncate max-w-[200px]\">{displayText}</span>\n {variant === 'default' && (\n <ExternalLink className=\"size-3 shrink-0\" aria-hidden=\"true\" />\n )}\n </>\n );\n\n // Render as <a> when navigating to URL (proper semantics)\n if (!onClick) {\n return (\n <a\n data-slot=\"ai-source-trigger\"\n href={source.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={sharedClassName}\n aria-label={`Source: ${displayText}`}\n >\n {sharedChildren}\n </a>\n );\n }\n\n // Render as <button> when custom click handler is provided\n return (\n <button\n type=\"button\"\n data-slot=\"ai-source-trigger\"\n onClick={onClick}\n className={sharedClassName}\n aria-label={`Source: ${displayText}`}\n >\n {sharedChildren}\n </button>\n );\n}\n\nAISourceTrigger.displayName = 'AISourceTrigger';\n\n// =============================================================================\n// Source Content (Tooltip/Popover content)\n// =============================================================================\n\nexport interface AISourceContentProps {\n /** Source data */\n source: SourceData;\n /** Additional class name */\n className?: string;\n}\n\nfunction AISourceContent({ source, className }: AISourceContentProps) {\n const domain = React.useMemo(() => {\n try {\n return new URL(source.url).hostname;\n } catch {\n return source.url;\n }\n }, [source.url]);\n\n return (\n <div className={cn('p-3 max-w-xs space-y-2', className)}>\n <div className=\"flex items-start gap-2\">\n <SourceFavicon\n url={source.url}\n favicon={source.favicon}\n className=\"mt-0.5\"\n />\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium text-foreground truncate\">\n {source.title || domain}\n </p>\n <p className=\"text-xs text-text-quaternary truncate\">{domain}</p>\n </div>\n </div>\n {source.description && (\n <p className=\"text-xs text-muted-foreground line-clamp-2\">\n {source.description}\n </p>\n )}\n <a\n href={source.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-1 text-xs text-primary hover:text-primary\"\n >\n Visit source\n <ExternalLink className=\"size-3\" />\n </a>\n </div>\n );\n}\n\nAISourceContent.displayName = 'AISourceContent';\n\n// =============================================================================\n// Main AISource Component (with built-in tooltip)\n// =============================================================================\n\nexport interface AISourceProps extends VariantProps<typeof sourceVariants> {\n /** Source data */\n source: SourceData;\n /** Whether to show favicon */\n showFavicon?: boolean;\n /** Whether to show tooltip on hover */\n showTooltip?: boolean;\n /** Additional class name */\n className?: string;\n}\n\nfunction AISource({\n source,\n variant,\n showFavicon = true,\n showTooltip = true,\n className,\n}: AISourceProps) {\n if (!showTooltip) {\n return (\n <span data-slot=\"ai-source\">\n <AISourceTrigger\n source={source}\n variant={variant}\n showFavicon={showFavicon}\n className={className}\n />\n </span>\n );\n }\n\n return (\n <Tooltip>\n <TooltipTrigger\n render={\n <span data-slot=\"ai-source\">\n <AISourceTrigger\n source={source}\n variant={variant}\n showFavicon={showFavicon}\n className={className}\n />\n </span>\n }\n />\n <TooltipPopup side=\"top\" className=\"p-0\">\n <AISourceContent source={source} />\n </TooltipPopup>\n </Tooltip>\n );\n}\n\nAISource.displayName = 'AISource';\n\n// =============================================================================\n// Source List Component\n// =============================================================================\n\nexport interface AISourceListProps {\n /** Array of sources */\n sources: SourceData[];\n /** Maximum sources to show before truncating */\n maxVisible?: number;\n /** Whether to show expanded list */\n showAll?: boolean;\n /** Callback when \"show more\" is clicked */\n onShowMore?: () => void;\n /** Additional class name */\n className?: string;\n}\n\nfunction AISourceList({\n sources,\n maxVisible = 3,\n showAll = false,\n onShowMore,\n className,\n}: AISourceListProps) {\n const safeMaxVisible = getMaxVisibleSources(maxVisible);\n const visibleSources = showAll ? sources : sources.slice(0, safeMaxVisible);\n const remainingCount = Math.max(0, sources.length - safeMaxVisible);\n\n return (\n <nav\n data-slot=\"ai-source-list\"\n aria-label=\"Sources\"\n className={cn('flex flex-wrap items-center gap-2', className)}\n >\n <span className=\"text-xs text-text-quaternary\">Sources:</span>\n {visibleSources.map((source, index) => (\n <span\n key={`${source.url}-${index}`}\n className=\"delight-stagger motion-reduce:!animate-none\"\n style={\n { '--delight-delay': `${index * 50}ms` } as React.CSSProperties\n }\n >\n <AISource source={source} variant=\"pill\" />\n </span>\n ))}\n {!showAll && remainingCount > 0 && (\n <button\n type=\"button\"\n onClick={onShowMore}\n aria-label={`Show ${remainingCount} more sources`}\n className=\"px-2.5 py-1 rounded-full bg-accent hover:bg-surface-2 text-xs text-secondary-foreground transition-colors focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring delight-selection-press\"\n >\n +{remainingCount} more\n </button>\n )}\n </nav>\n );\n}\n\nAISourceList.displayName = 'AISourceList';\n\nexport {\n AISource,\n AISourceContent,\n AISourceList,\n AISourceTrigger,\n SourceFavicon,\n sourceVariants,\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"index173.js","names":[],"sources":["../src/components/organisms/ai/AISource/AISource.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport { ExternalLink, Globe } from 'lucide-react';\nimport * as React from 'react';\nimport { Tooltip, TooltipPopup, TooltipTrigger } from '@/components/ui/tooltip';\nimport { cn } from '@/lib/utils';\n\n// =============================================================================\n// Variants\n// =============================================================================\n\nconst sourceVariants = cva(\n 'inline-flex items-center gap-1.5 transition-colors cursor-pointer focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring',\n {\n variants: {\n variant: {\n default:\n 'text-sm text-primary hover:text-primary underline underline-offset-2 rounded-sm',\n pill: 'px-2.5 py-1 rounded-full bg-accent hover:bg-surface-2 text-xs text-secondary-foreground delight-selection-press',\n minimal:\n 'text-xs text-secondary-foreground hover:text-foreground rounded-sm',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n },\n);\n\nconst DEFAULT_MAX_VISIBLE_SOURCES = 3;\n\nfunction getMaxVisibleSources(maxVisible: number): number {\n return Number.isFinite(maxVisible) && maxVisible >= 0\n ? Math.floor(maxVisible)\n : DEFAULT_MAX_VISIBLE_SOURCES;\n}\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface SourceData {\n /** Source URL */\n url: string;\n /** Display title */\n title?: string;\n /** Source description */\n description?: string;\n /** Favicon URL */\n favicon?: string;\n /** Site name */\n siteName?: string;\n}\n\n// =============================================================================\n// Source Favicon\n// =============================================================================\n\ninterface SourceFaviconProps {\n url: string;\n favicon?: string;\n className?: string;\n}\n\nfunction SourceFavicon({ url, favicon, className }: SourceFaviconProps) {\n const [hasError, setHasError] = React.useState(false);\n\n // Generate favicon URL from domain if not provided\n const faviconUrl = React.useMemo(() => {\n if (favicon) return favicon;\n try {\n const domain = new URL(url).hostname;\n return `https://www.google.com/s2/favicons?domain=${domain}&sz=32`;\n } catch {\n return null;\n }\n }, [url, favicon]);\n\n if (!faviconUrl || hasError) {\n return <Globe className={cn('size-4 text-muted-foreground', className)} />;\n }\n\n return (\n <img\n src={faviconUrl}\n alt=\"\"\n className={cn(\n 'size-4 rounded delight-fade-in motion-reduce:!animate-none',\n className,\n )}\n onError={() => setHasError(true)}\n />\n );\n}\n\nSourceFavicon.displayName = 'SourceFavicon';\n\n// =============================================================================\n// Source Trigger (Clickable element)\n// =============================================================================\n\nexport interface AISourceTriggerProps\n extends VariantProps<typeof sourceVariants> {\n /** Source data */\n source: SourceData;\n /** Whether to show favicon */\n showFavicon?: boolean;\n /** Additional class name */\n className?: string;\n /** Click handler */\n onClick?: () => void;\n}\n\nfunction AISourceTrigger({\n source,\n variant,\n showFavicon = true,\n className,\n onClick,\n}: AISourceTriggerProps) {\n const displayText = source.title || source.siteName || source.url;\n\n const sharedClassName = cn(sourceVariants({ variant }), className);\n const sharedChildren = (\n <>\n {showFavicon && (\n <SourceFavicon url={source.url} favicon={source.favicon} />\n )}\n <span className=\"truncate max-w-[200px]\">{displayText}</span>\n {variant === 'default' && (\n <ExternalLink className=\"size-3 shrink-0\" aria-hidden=\"true\" />\n )}\n </>\n );\n\n // Render as <a> when navigating to URL (proper semantics)\n if (!onClick) {\n return (\n <a\n data-slot=\"ai-source-trigger\"\n href={source.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={sharedClassName}\n aria-label={`Source: ${displayText}`}\n >\n {sharedChildren}\n </a>\n );\n }\n\n // Render as <button> when custom click handler is provided\n return (\n <button\n type=\"button\"\n data-slot=\"ai-source-trigger\"\n onClick={onClick}\n className={sharedClassName}\n aria-label={`Source: ${displayText}`}\n >\n {sharedChildren}\n </button>\n );\n}\n\nAISourceTrigger.displayName = 'AISourceTrigger';\n\n// =============================================================================\n// Source Content (Tooltip/Popover content)\n// =============================================================================\n\nexport interface AISourceContentProps {\n /** Source data */\n source: SourceData;\n /** Additional class name */\n className?: string;\n}\n\nfunction AISourceContent({ source, className }: AISourceContentProps) {\n const domain = React.useMemo(() => {\n try {\n return new URL(source.url).hostname;\n } catch {\n return source.url;\n }\n }, [source.url]);\n\n return (\n <div className={cn('p-3 max-w-xs space-y-2', className)}>\n <div className=\"flex items-start gap-2\">\n <SourceFavicon\n url={source.url}\n favicon={source.favicon}\n className=\"mt-0.5\"\n />\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium text-foreground truncate\">\n {source.title || domain}\n </p>\n <p className=\"text-xs text-text-quaternary truncate\">{domain}</p>\n </div>\n </div>\n {source.description && (\n <p className=\"text-xs text-muted-foreground line-clamp-2\">\n {source.description}\n </p>\n )}\n <a\n href={source.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-1 text-xs text-primary hover:text-primary\"\n >\n Visit source\n <ExternalLink className=\"size-3\" />\n </a>\n </div>\n );\n}\n\nAISourceContent.displayName = 'AISourceContent';\n\n// =============================================================================\n// Main AISource Component (with built-in tooltip)\n// =============================================================================\n\nexport interface AISourceProps extends VariantProps<typeof sourceVariants> {\n /** Source data */\n source: SourceData;\n /** Whether to show favicon */\n showFavicon?: boolean;\n /** Whether to show tooltip on hover */\n showTooltip?: boolean;\n /** Additional class name */\n className?: string;\n}\n\nfunction AISource({\n source,\n variant,\n showFavicon = true,\n showTooltip = true,\n className,\n}: AISourceProps) {\n if (!showTooltip) {\n return (\n <span data-slot=\"ai-source\">\n <AISourceTrigger\n source={source}\n variant={variant}\n showFavicon={showFavicon}\n className={className}\n />\n </span>\n );\n }\n\n return (\n <Tooltip>\n <TooltipTrigger\n render={\n <span data-slot=\"ai-source\">\n <AISourceTrigger\n source={source}\n variant={variant}\n showFavicon={showFavicon}\n className={className}\n />\n </span>\n }\n />\n <TooltipPopup side=\"top\" className=\"p-0\">\n <AISourceContent source={source} />\n </TooltipPopup>\n </Tooltip>\n );\n}\n\nAISource.displayName = 'AISource';\n\n// =============================================================================\n// Source List Component\n// =============================================================================\n\nexport interface AISourceListProps {\n /** Array of sources */\n sources: SourceData[];\n /** Maximum sources to show before truncating */\n maxVisible?: number;\n /** Whether to show expanded list */\n showAll?: boolean;\n /** Callback when \"show more\" is clicked */\n onShowMore?: () => void;\n /** Additional class name */\n className?: string;\n}\n\nfunction AISourceList({\n sources,\n maxVisible = 3,\n showAll = false,\n onShowMore,\n className,\n}: AISourceListProps) {\n const safeMaxVisible = getMaxVisibleSources(maxVisible);\n const visibleSources = showAll ? sources : sources.slice(0, safeMaxVisible);\n const remainingCount = Math.max(0, sources.length - safeMaxVisible);\n\n return (\n <nav\n data-slot=\"ai-source-list\"\n aria-label=\"Sources\"\n className={cn('flex flex-wrap items-center gap-2', className)}\n >\n <span className=\"text-xs text-text-quaternary\">Sources:</span>\n {visibleSources.map((source, index) => (\n <span\n key={`${source.url}-${index}`}\n className=\"delight-stagger motion-reduce:!animate-none\"\n style={\n { '--delight-delay': `${index * 50}ms` } as React.CSSProperties\n }\n >\n <AISource source={source} variant=\"pill\" />\n </span>\n ))}\n {!showAll && remainingCount > 0 && (\n <button\n type=\"button\"\n onClick={onShowMore}\n aria-label={`Show ${remainingCount} more sources`}\n className=\"px-2.5 py-1 rounded-full bg-accent hover:bg-surface-2 text-xs text-secondary-foreground transition-colors focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring delight-selection-press\"\n >\n +{remainingCount} more\n </button>\n )}\n </nav>\n );\n}\n\nAISourceList.displayName = 'AISourceList';\n\nexport {\n AISource,\n AISourceContent,\n AISourceList,\n AISourceTrigger,\n SourceFavicon,\n sourceVariants,\n};\n"],"mappings":"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"}
package/dist/index184.js CHANGED
@@ -52,7 +52,7 @@ function AIToolCallHeader({ toolName, status, isOpen, onToggle, className }) {
52
52
  className: "text-sm font-medium text-foreground",
53
53
  children: toolName
54
54
  }), /* @__PURE__ */ jsx("span", {
55
- className: "text-xs text-text-quaternary",
55
+ className: "text-xs text-secondary-foreground",
56
56
  children: {
57
57
  pending: "Pending",
58
58
  running: "Running...",
@@ -1 +1 @@
1
- {"version":3,"file":"index184.js","names":[],"sources":["../src/components/organisms/ai/AIToolCall/AIToolCall.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport {\n AlertCircle,\n Check,\n ChevronDown,\n ChevronRight,\n Clock,\n Code,\n Wrench,\n} from 'lucide-react';\nimport { AnimatePresence, motion } from 'motion/react';\nimport * as React from 'react';\nimport { AICodeBlock } from '@/components/organisms/ai/AICodeBlock';\nimport { useControllableState } from '@/hooks/use-controllable-state';\nimport { cn } from '@/lib/utils';\n\n// =============================================================================\n// Variants\n// =============================================================================\n\nconst toolCallVariants = cva(\n 'overflow-hidden rounded-xl border transition-colors',\n {\n variants: {\n status: {\n pending: 'border-border bg-muted',\n running: 'border-primary bg-primary/10',\n success: 'border-success/50 bg-success/10',\n error: 'border-destructive/50 bg-destructive/10',\n },\n },\n defaultVariants: {\n status: 'pending',\n },\n },\n);\n\nconst statusIconVariants = cva('size-4', {\n variants: {\n status: {\n pending: 'text-muted-foreground',\n running: 'text-primary animate-spin motion-reduce:animate-none',\n success: 'text-success',\n error: 'text-destructive',\n },\n },\n defaultVariants: {\n status: 'pending',\n },\n});\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport type ToolCallStatus = 'pending' | 'running' | 'success' | 'error';\n\nexport interface ToolCallPart {\n /** Unique tool call ID */\n toolCallId: string;\n /** Tool name */\n toolName: string;\n /** Tool input/arguments */\n args?: Record<string, unknown>;\n /** Tool output/result */\n result?: unknown;\n /** Tool status */\n status?: ToolCallStatus;\n /** Error message if status is error */\n error?: string;\n}\n\n// =============================================================================\n// Status Icon Component\n// =============================================================================\n\ninterface StatusIconProps {\n status: ToolCallStatus;\n className?: string;\n}\n\nfunction StatusIcon({ status, className }: StatusIconProps) {\n const iconClass = cn(statusIconVariants({ status }), className);\n\n switch (status) {\n case 'running':\n return <Clock className={iconClass} />;\n case 'success':\n return (\n <Check\n className={cn(\n iconClass,\n 'delight-check-bounce motion-reduce:!animate-none',\n )}\n />\n );\n case 'error':\n return (\n <AlertCircle\n className={cn(iconClass, 'delight-shake motion-reduce:!animate-none')}\n />\n );\n default:\n return <Wrench className={iconClass} />;\n }\n}\n\nStatusIcon.displayName = 'StatusIcon';\n\n// =============================================================================\n// Tool Call Header\n// =============================================================================\n\ninterface AIToolCallHeaderProps {\n toolName: string;\n status: ToolCallStatus;\n isOpen: boolean;\n onToggle: () => void;\n className?: string;\n}\n\nfunction AIToolCallHeader({\n toolName,\n status,\n isOpen,\n onToggle,\n className,\n}: AIToolCallHeaderProps) {\n const statusLabel = {\n pending: 'Pending',\n running: 'Running...',\n success: 'Completed',\n error: 'Failed',\n };\n\n return (\n <button\n type=\"button\"\n onClick={onToggle}\n aria-expanded={isOpen}\n className={cn(\n 'flex items-center justify-between w-full px-4 py-3 transition-colors hover:bg-foreground/5 focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-ring',\n className,\n )}\n >\n <div className=\"flex items-center gap-3\">\n <StatusIcon status={status} aria-hidden=\"true\" />\n <div className=\"flex flex-col items-start\">\n <span className=\"text-sm font-medium text-foreground\">\n {toolName}\n </span>\n <span className=\"text-xs text-text-quaternary\">\n {statusLabel[status]}\n </span>\n </div>\n </div>\n {isOpen ? (\n <ChevronDown\n className=\"size-4 text-muted-foreground\"\n aria-hidden=\"true\"\n />\n ) : (\n <ChevronRight\n className=\"size-4 text-muted-foreground rtl:rotate-180\"\n aria-hidden=\"true\"\n />\n )}\n </button>\n );\n}\n\nAIToolCallHeader.displayName = 'AIToolCallHeader';\n\n// =============================================================================\n// Tool Call Section\n// =============================================================================\n\ninterface ToolCallSectionProps {\n title: string;\n icon: React.ReactNode;\n children: React.ReactNode;\n className?: string;\n}\n\nfunction ToolCallSection({\n title,\n icon,\n children,\n className,\n}: ToolCallSectionProps) {\n return (\n <div className={cn('space-y-2', className)}>\n <div className=\"flex items-center gap-2 text-xs font-medium text-text-quaternary uppercase tracking-wide\">\n {icon}\n {title}\n </div>\n {children}\n </div>\n );\n}\n\nToolCallSection.displayName = 'ToolCallSection';\n\n// =============================================================================\n// Main AIToolCall Component\n// =============================================================================\n\nexport interface AIToolCallProps extends VariantProps<typeof toolCallVariants> {\n /** Tool call data */\n toolPart: ToolCallPart;\n /** Whether to expand by default */\n defaultOpen?: boolean;\n /** Controlled open state */\n open?: boolean;\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void;\n /** Additional class name */\n className?: string;\n}\n\nfunction formatValue(value: unknown): string {\n if (typeof value === 'string') return value;\n return JSON.stringify(value, null, 2);\n}\n\nfunction AIToolCall({\n toolPart,\n defaultOpen = false,\n open: controlledOpen,\n onOpenChange,\n className,\n}: AIToolCallProps) {\n const [isOpen, setIsOpen] = useControllableState({\n value: controlledOpen,\n defaultValue: defaultOpen,\n onChange: onOpenChange,\n });\n\n const status = toolPart.status || 'pending';\n\n const handleToggle = () => {\n setIsOpen(!isOpen);\n };\n\n return (\n <div\n data-slot=\"ai-tool-call\"\n className={cn(toolCallVariants({ status }), className)}\n >\n <AIToolCallHeader\n toolName={toolPart.toolName}\n status={status}\n isOpen={isOpen}\n onToggle={handleToggle}\n />\n\n <AnimatePresence>\n {isOpen && (\n <motion.div\n initial={{ height: 0, opacity: 0 }}\n animate={{ height: 'auto', opacity: 1 }}\n exit={{ height: 0, opacity: 0 }}\n transition={{ duration: 0.2 }}\n className=\"overflow-hidden\"\n >\n <div className=\"px-4 pb-4 space-y-4\">\n {/* Tool Call ID */}\n <div className=\"text-xs text-muted-foreground font-mono\">\n ID: {toolPart.toolCallId}\n </div>\n\n {/* Input Section */}\n {toolPart.args && Object.keys(toolPart.args).length > 0 && (\n <ToolCallSection\n title=\"Input\"\n icon={<Code className=\"size-3\" />}\n >\n <AICodeBlock\n code={formatValue(toolPart.args)}\n language=\"json\"\n showHeader={false}\n showCopyButton={true}\n size=\"sm\"\n />\n </ToolCallSection>\n )}\n\n {/* Output Section */}\n {toolPart.result !== undefined && (\n <ToolCallSection\n title=\"Output\"\n icon={<Code className=\"size-3\" />}\n >\n <AICodeBlock\n code={formatValue(toolPart.result)}\n language=\"json\"\n showHeader={false}\n showCopyButton={true}\n size=\"sm\"\n />\n </ToolCallSection>\n )}\n\n {/* Error Section */}\n {toolPart.error && (\n <div className=\"p-3 rounded-lg bg-destructive/20 border border-destructive/50\">\n <div className=\"flex items-start gap-2\">\n <AlertCircle className=\"size-4 text-destructive mt-0.5 shrink-0\" />\n <p className=\"text-sm text-destructive\">{toolPart.error}</p>\n </div>\n </div>\n )}\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n );\n}\n\nAIToolCall.displayName = 'AIToolCall';\n\n// =============================================================================\n// Tool Call List Component\n// =============================================================================\n\nexport interface AIToolCallListProps {\n /** Array of tool calls */\n toolCalls: readonly ToolCallPart[];\n /** Whether to expand all by default */\n defaultAllOpen?: boolean;\n /** Tool-call IDs to expand initially in uncontrolled mode */\n defaultOpenToolCallIds?: readonly string[];\n /** Controlled expanded tool-call IDs */\n openToolCallIds?: readonly string[];\n /** Called with expanded IDs in current tool-call order */\n onOpenToolCallIdsChange?: (ids: readonly string[]) => void;\n /** Additional class name */\n className?: string;\n}\n\nfunction normalizeOpenToolCallIds(\n ids: readonly string[],\n toolCalls: readonly ToolCallPart[],\n): string[] {\n const requested = new Set(ids);\n return toolCalls.flatMap((toolCall) =>\n requested.has(toolCall.toolCallId) ? [toolCall.toolCallId] : [],\n );\n}\n\nfunction areToolCallIdsEqual(\n left: readonly string[],\n right: readonly string[],\n): boolean {\n return (\n left.length === right.length &&\n left.every((id, index) => id === right[index])\n );\n}\n\nfunction AIToolCallList({\n toolCalls,\n defaultAllOpen = false,\n defaultOpenToolCallIds = [],\n openToolCallIds: controlledOpenToolCallIds,\n onOpenToolCallIdsChange,\n className,\n}: AIToolCallListProps) {\n const isControlled = controlledOpenToolCallIds !== undefined;\n const [uncontrolledOpenToolCallIds, setUncontrolledOpenToolCallIds] =\n React.useState<readonly string[]>(() =>\n normalizeOpenToolCallIds(\n defaultAllOpen\n ? toolCalls.map((toolCall) => toolCall.toolCallId)\n : defaultOpenToolCallIds,\n toolCalls,\n ),\n );\n const rawOpenToolCallIds = isControlled\n ? controlledOpenToolCallIds\n : uncontrolledOpenToolCallIds;\n const visibleOpenToolCallIds = normalizeOpenToolCallIds(\n rawOpenToolCallIds,\n toolCalls,\n );\n const openSet = new Set(visibleOpenToolCallIds);\n\n React.useLayoutEffect(() => {\n if (isControlled) return;\n setUncontrolledOpenToolCallIds((current) => {\n const normalized = normalizeOpenToolCallIds(current, toolCalls);\n return areToolCallIdsEqual(current, normalized) ? current : normalized;\n });\n }, [isControlled, toolCalls]);\n\n const setToolCallOpen = (toolCallId: string, open: boolean) => {\n const next = new Set(visibleOpenToolCallIds);\n if (open) next.add(toolCallId);\n else next.delete(toolCallId);\n const normalized = normalizeOpenToolCallIds([...next], toolCalls);\n if (!isControlled) {\n setUncontrolledOpenToolCallIds(normalized);\n }\n onOpenToolCallIdsChange?.([...normalized]);\n };\n\n return (\n <div data-slot=\"ai-tool-call-list\" className={cn('space-y-2', className)}>\n {toolCalls.map((toolCall) => (\n <AIToolCall\n key={toolCall.toolCallId}\n toolPart={toolCall}\n open={openSet.has(toolCall.toolCallId)}\n onOpenChange={(open) => setToolCallOpen(toolCall.toolCallId, open)}\n />\n ))}\n </div>\n );\n}\n\nAIToolCallList.displayName = 'AIToolCallList';\n\nexport {\n AIToolCall,\n AIToolCallHeader,\n AIToolCallList,\n StatusIcon,\n statusIconVariants,\n ToolCallSection,\n toolCallVariants,\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"index184.js","names":[],"sources":["../src/components/organisms/ai/AIToolCall/AIToolCall.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport {\n AlertCircle,\n Check,\n ChevronDown,\n ChevronRight,\n Clock,\n Code,\n Wrench,\n} from 'lucide-react';\nimport { AnimatePresence, motion } from 'motion/react';\nimport * as React from 'react';\nimport { AICodeBlock } from '@/components/organisms/ai/AICodeBlock';\nimport { useControllableState } from '@/hooks/use-controllable-state';\nimport { cn } from '@/lib/utils';\n\n// =============================================================================\n// Variants\n// =============================================================================\n\nconst toolCallVariants = cva(\n 'overflow-hidden rounded-xl border transition-colors',\n {\n variants: {\n status: {\n pending: 'border-border bg-muted',\n running: 'border-primary bg-primary/10',\n success: 'border-success/50 bg-success/10',\n error: 'border-destructive/50 bg-destructive/10',\n },\n },\n defaultVariants: {\n status: 'pending',\n },\n },\n);\n\nconst statusIconVariants = cva('size-4', {\n variants: {\n status: {\n pending: 'text-muted-foreground',\n running: 'text-primary animate-spin motion-reduce:animate-none',\n success: 'text-success',\n error: 'text-destructive',\n },\n },\n defaultVariants: {\n status: 'pending',\n },\n});\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport type ToolCallStatus = 'pending' | 'running' | 'success' | 'error';\n\nexport interface ToolCallPart {\n /** Unique tool call ID */\n toolCallId: string;\n /** Tool name */\n toolName: string;\n /** Tool input/arguments */\n args?: Record<string, unknown>;\n /** Tool output/result */\n result?: unknown;\n /** Tool status */\n status?: ToolCallStatus;\n /** Error message if status is error */\n error?: string;\n}\n\n// =============================================================================\n// Status Icon Component\n// =============================================================================\n\ninterface StatusIconProps {\n status: ToolCallStatus;\n className?: string;\n}\n\nfunction StatusIcon({ status, className }: StatusIconProps) {\n const iconClass = cn(statusIconVariants({ status }), className);\n\n switch (status) {\n case 'running':\n return <Clock className={iconClass} />;\n case 'success':\n return (\n <Check\n className={cn(\n iconClass,\n 'delight-check-bounce motion-reduce:!animate-none',\n )}\n />\n );\n case 'error':\n return (\n <AlertCircle\n className={cn(iconClass, 'delight-shake motion-reduce:!animate-none')}\n />\n );\n default:\n return <Wrench className={iconClass} />;\n }\n}\n\nStatusIcon.displayName = 'StatusIcon';\n\n// =============================================================================\n// Tool Call Header\n// =============================================================================\n\ninterface AIToolCallHeaderProps {\n toolName: string;\n status: ToolCallStatus;\n isOpen: boolean;\n onToggle: () => void;\n className?: string;\n}\n\nfunction AIToolCallHeader({\n toolName,\n status,\n isOpen,\n onToggle,\n className,\n}: AIToolCallHeaderProps) {\n const statusLabel = {\n pending: 'Pending',\n running: 'Running...',\n success: 'Completed',\n error: 'Failed',\n };\n\n return (\n <button\n type=\"button\"\n onClick={onToggle}\n aria-expanded={isOpen}\n className={cn(\n 'flex items-center justify-between w-full px-4 py-3 transition-colors hover:bg-foreground/5 focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-ring',\n className,\n )}\n >\n <div className=\"flex items-center gap-3\">\n <StatusIcon status={status} aria-hidden=\"true\" />\n <div className=\"flex flex-col items-start\">\n <span className=\"text-sm font-medium text-foreground\">\n {toolName}\n </span>\n <span className=\"text-xs text-secondary-foreground\">\n {statusLabel[status]}\n </span>\n </div>\n </div>\n {isOpen ? (\n <ChevronDown\n className=\"size-4 text-muted-foreground\"\n aria-hidden=\"true\"\n />\n ) : (\n <ChevronRight\n className=\"size-4 text-muted-foreground rtl:rotate-180\"\n aria-hidden=\"true\"\n />\n )}\n </button>\n );\n}\n\nAIToolCallHeader.displayName = 'AIToolCallHeader';\n\n// =============================================================================\n// Tool Call Section\n// =============================================================================\n\ninterface ToolCallSectionProps {\n title: string;\n icon: React.ReactNode;\n children: React.ReactNode;\n className?: string;\n}\n\nfunction ToolCallSection({\n title,\n icon,\n children,\n className,\n}: ToolCallSectionProps) {\n return (\n <div className={cn('space-y-2', className)}>\n <div className=\"flex items-center gap-2 text-xs font-medium text-text-quaternary uppercase tracking-wide\">\n {icon}\n {title}\n </div>\n {children}\n </div>\n );\n}\n\nToolCallSection.displayName = 'ToolCallSection';\n\n// =============================================================================\n// Main AIToolCall Component\n// =============================================================================\n\nexport interface AIToolCallProps extends VariantProps<typeof toolCallVariants> {\n /** Tool call data */\n toolPart: ToolCallPart;\n /** Whether to expand by default */\n defaultOpen?: boolean;\n /** Controlled open state */\n open?: boolean;\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void;\n /** Additional class name */\n className?: string;\n}\n\nfunction formatValue(value: unknown): string {\n if (typeof value === 'string') return value;\n return JSON.stringify(value, null, 2);\n}\n\nfunction AIToolCall({\n toolPart,\n defaultOpen = false,\n open: controlledOpen,\n onOpenChange,\n className,\n}: AIToolCallProps) {\n const [isOpen, setIsOpen] = useControllableState({\n value: controlledOpen,\n defaultValue: defaultOpen,\n onChange: onOpenChange,\n });\n\n const status = toolPart.status || 'pending';\n\n const handleToggle = () => {\n setIsOpen(!isOpen);\n };\n\n return (\n <div\n data-slot=\"ai-tool-call\"\n className={cn(toolCallVariants({ status }), className)}\n >\n <AIToolCallHeader\n toolName={toolPart.toolName}\n status={status}\n isOpen={isOpen}\n onToggle={handleToggle}\n />\n\n <AnimatePresence>\n {isOpen && (\n <motion.div\n initial={{ height: 0, opacity: 0 }}\n animate={{ height: 'auto', opacity: 1 }}\n exit={{ height: 0, opacity: 0 }}\n transition={{ duration: 0.2 }}\n className=\"overflow-hidden\"\n >\n <div className=\"px-4 pb-4 space-y-4\">\n {/* Tool Call ID */}\n <div className=\"text-xs text-muted-foreground font-mono\">\n ID: {toolPart.toolCallId}\n </div>\n\n {/* Input Section */}\n {toolPart.args && Object.keys(toolPart.args).length > 0 && (\n <ToolCallSection\n title=\"Input\"\n icon={<Code className=\"size-3\" />}\n >\n <AICodeBlock\n code={formatValue(toolPart.args)}\n language=\"json\"\n showHeader={false}\n showCopyButton={true}\n size=\"sm\"\n />\n </ToolCallSection>\n )}\n\n {/* Output Section */}\n {toolPart.result !== undefined && (\n <ToolCallSection\n title=\"Output\"\n icon={<Code className=\"size-3\" />}\n >\n <AICodeBlock\n code={formatValue(toolPart.result)}\n language=\"json\"\n showHeader={false}\n showCopyButton={true}\n size=\"sm\"\n />\n </ToolCallSection>\n )}\n\n {/* Error Section */}\n {toolPart.error && (\n <div className=\"p-3 rounded-lg bg-destructive/20 border border-destructive/50\">\n <div className=\"flex items-start gap-2\">\n <AlertCircle className=\"size-4 text-destructive mt-0.5 shrink-0\" />\n <p className=\"text-sm text-destructive\">{toolPart.error}</p>\n </div>\n </div>\n )}\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n );\n}\n\nAIToolCall.displayName = 'AIToolCall';\n\n// =============================================================================\n// Tool Call List Component\n// =============================================================================\n\nexport interface AIToolCallListProps {\n /** Array of tool calls */\n toolCalls: readonly ToolCallPart[];\n /** Whether to expand all by default */\n defaultAllOpen?: boolean;\n /** Tool-call IDs to expand initially in uncontrolled mode */\n defaultOpenToolCallIds?: readonly string[];\n /** Controlled expanded tool-call IDs */\n openToolCallIds?: readonly string[];\n /** Called with expanded IDs in current tool-call order */\n onOpenToolCallIdsChange?: (ids: readonly string[]) => void;\n /** Additional class name */\n className?: string;\n}\n\nfunction normalizeOpenToolCallIds(\n ids: readonly string[],\n toolCalls: readonly ToolCallPart[],\n): string[] {\n const requested = new Set(ids);\n return toolCalls.flatMap((toolCall) =>\n requested.has(toolCall.toolCallId) ? [toolCall.toolCallId] : [],\n );\n}\n\nfunction areToolCallIdsEqual(\n left: readonly string[],\n right: readonly string[],\n): boolean {\n return (\n left.length === right.length &&\n left.every((id, index) => id === right[index])\n );\n}\n\nfunction AIToolCallList({\n toolCalls,\n defaultAllOpen = false,\n defaultOpenToolCallIds = [],\n openToolCallIds: controlledOpenToolCallIds,\n onOpenToolCallIdsChange,\n className,\n}: AIToolCallListProps) {\n const isControlled = controlledOpenToolCallIds !== undefined;\n const [uncontrolledOpenToolCallIds, setUncontrolledOpenToolCallIds] =\n React.useState<readonly string[]>(() =>\n normalizeOpenToolCallIds(\n defaultAllOpen\n ? toolCalls.map((toolCall) => toolCall.toolCallId)\n : defaultOpenToolCallIds,\n toolCalls,\n ),\n );\n const rawOpenToolCallIds = isControlled\n ? controlledOpenToolCallIds\n : uncontrolledOpenToolCallIds;\n const visibleOpenToolCallIds = normalizeOpenToolCallIds(\n rawOpenToolCallIds,\n toolCalls,\n );\n const openSet = new Set(visibleOpenToolCallIds);\n\n React.useLayoutEffect(() => {\n if (isControlled) return;\n setUncontrolledOpenToolCallIds((current) => {\n const normalized = normalizeOpenToolCallIds(current, toolCalls);\n return areToolCallIdsEqual(current, normalized) ? current : normalized;\n });\n }, [isControlled, toolCalls]);\n\n const setToolCallOpen = (toolCallId: string, open: boolean) => {\n const next = new Set(visibleOpenToolCallIds);\n if (open) next.add(toolCallId);\n else next.delete(toolCallId);\n const normalized = normalizeOpenToolCallIds([...next], toolCalls);\n if (!isControlled) {\n setUncontrolledOpenToolCallIds(normalized);\n }\n onOpenToolCallIdsChange?.([...normalized]);\n };\n\n return (\n <div data-slot=\"ai-tool-call-list\" className={cn('space-y-2', className)}>\n {toolCalls.map((toolCall) => (\n <AIToolCall\n key={toolCall.toolCallId}\n toolPart={toolCall}\n open={openSet.has(toolCall.toolCallId)}\n onOpenChange={(open) => setToolCallOpen(toolCall.toolCallId, open)}\n />\n ))}\n </div>\n );\n}\n\nAIToolCallList.displayName = 'AIToolCallList';\n\nexport {\n AIToolCall,\n AIToolCallHeader,\n AIToolCallList,\n StatusIcon,\n statusIconVariants,\n ToolCallSection,\n toolCallVariants,\n};\n"],"mappings":"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"}
package/dist/index217.js CHANGED
@@ -1,27 +1,9 @@
1
- import * as React$1 from "react";
2
- //#region src/components/templates/AppShell/AppShellContext.ts
3
- var AppShellContext = React$1.createContext(null);
4
- /**
5
- * Read AppShell layout context. Returns null when used outside AppShell.Root.
6
- */
7
- function useAppShell() {
8
- return React$1.useContext(AppShellContext);
9
- }
10
- var AppShellProvider = AppShellContext.Provider;
11
- /**
12
- * Internal context for passing the panel index from Panel to Content.
13
- * Content reads this to determine its position in connected mode.
14
- */
15
- var PanelIndexContext = React$1.createContext(0);
16
- var PanelLayoutContext = React$1.createContext({
17
- visible: true,
18
- isMobile: false
19
- });
20
- var PanelExpansionContext = React$1.createContext(null);
21
- function usePanelExpansion() {
22
- return React$1.useContext(PanelExpansionContext);
23
- }
1
+ //#region src/components/templates/AppSidebar/AppSidebar.constants.ts
2
+ /** Canonical expanded width shared by AppSidebar and AppShell.Sidebar. */
3
+ var APP_SIDEBAR_EXPANDED_WIDTH = "280px";
4
+ /** Canonical collapsed width shared by AppSidebar and AppShell.Sidebar. */
5
+ var APP_SIDEBAR_COLLAPSED_WIDTH = "68px";
24
6
  //#endregion
25
- export { AppShellContext, AppShellProvider, PanelExpansionContext, PanelIndexContext, PanelLayoutContext, useAppShell, usePanelExpansion };
7
+ export { APP_SIDEBAR_COLLAPSED_WIDTH, APP_SIDEBAR_EXPANDED_WIDTH };
26
8
 
27
9
  //# sourceMappingURL=index217.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index217.js","names":[],"sources":["../src/components/templates/AppShell/AppShellContext.ts"],"sourcesContent":["import * as React from 'react';\n\nexport type PanelPosition = 'only' | 'first' | 'last';\n\nexport interface AppShellContextValue {\n /** Whether the shell is in connected (joined-edge) mode */\n connected: boolean;\n /** Number of visible Panel children */\n panelCount: number;\n /** Get the position of a panel by its index among visible panels */\n getPanelPosition: (index: number) => PanelPosition;\n}\n\nconst AppShellContext = React.createContext<AppShellContextValue | null>(null);\n\n/**\n * Read AppShell layout context. Returns null when used outside AppShell.Root.\n */\nfunction useAppShell(): AppShellContextValue | null {\n return React.useContext(AppShellContext);\n}\n\nconst AppShellProvider = AppShellContext.Provider;\n\n/**\n * Internal context for passing the panel index from Panel to Content.\n * Content reads this to determine its position in connected mode.\n */\nconst PanelIndexContext = React.createContext<number>(0);\n\n/**\n * Per-panel layout state provided by Root. Replaces cloneElement style injection.\n * Panel reads this to self-manage visibility, mobile sizing, and ARIA attributes.\n */\nexport interface PanelLayoutInfo {\n /** Whether this panel is visible (false = hidden overflow panel or non-expanded sibling) */\n visible: boolean;\n /** How hidden desktop panels should leave layout. Animated keeps the flex item in-flow briefly. */\n collapseMode?: 'animated' | 'removed';\n /** Whether we're in mobile viewport */\n isMobile: boolean;\n /** ARIA tab ID for tabpanel association (set when mobile tab bar is active) */\n tabId?: string;\n /** ARIA panel ID for tabpanel role (set when mobile tab bar is active) */\n panelId?: string;\n /** Whether Root owns panel sizing, such as through ResizablePanel */\n sizeManagedByRoot?: boolean;\n /** Root-owned expansion override */\n expanded?: boolean;\n /** Root-owned expansion change callback */\n onExpandedChange?: (expanded: boolean) => void;\n}\n\nconst PanelLayoutContext = React.createContext<PanelLayoutInfo>({\n visible: true,\n isMobile: false,\n});\n\nexport interface PanelExpansionInfo {\n expanded: boolean;\n onExpandedChange?: (expanded: boolean) => void;\n}\n\nconst PanelExpansionContext = React.createContext<PanelExpansionInfo | null>(\n null,\n);\n\nfunction usePanelExpansion(): PanelExpansionInfo | null {\n return React.useContext(PanelExpansionContext);\n}\n\nexport {\n AppShellContext,\n AppShellProvider,\n PanelExpansionContext,\n PanelIndexContext,\n PanelLayoutContext,\n useAppShell,\n usePanelExpansion,\n};\n"],"mappings":";;AAaA,IAAM,kBAAkB,QAAM,cAA2C,IAAI;;;;AAK7E,SAAS,cAA2C;CAClD,OAAO,QAAM,WAAW,eAAe;AACzC;AAEA,IAAM,mBAAmB,gBAAgB;;;;;AAMzC,IAAM,oBAAoB,QAAM,cAAsB,CAAC;AAyBvD,IAAM,qBAAqB,QAAM,cAA+B;CAC9D,SAAS;CACT,UAAU;AACZ,CAAC;AAOD,IAAM,wBAAwB,QAAM,cAClC,IACF;AAEA,SAAS,oBAA+C;CACtD,OAAO,QAAM,WAAW,qBAAqB;AAC/C"}
1
+ {"version":3,"file":"index217.js","names":[],"sources":["../src/components/templates/AppSidebar/AppSidebar.constants.ts"],"sourcesContent":["/** Canonical expanded width shared by AppSidebar and AppShell.Sidebar. */\nexport const APP_SIDEBAR_EXPANDED_WIDTH = '280px';\n\n/** Canonical collapsed width shared by AppSidebar and AppShell.Sidebar. */\nexport const APP_SIDEBAR_COLLAPSED_WIDTH = '68px';\n"],"mappings":";;AACA,IAAa,6BAA6B;;AAG1C,IAAa,8BAA8B"}
package/dist/index218.js CHANGED
@@ -1,30 +1,27 @@
1
- "use client";
2
- import { cn } from "./index2.js";
3
- import { PanelIndexContext, useAppShell } from "./index217.js";
4
1
  import * as React$1 from "react";
5
- import { jsx } from "react/jsx-runtime";
6
- //#region src/components/templates/AppShell/AppShellContent.tsx
2
+ //#region src/components/templates/AppShell/AppShellContext.ts
3
+ var AppShellContext = React$1.createContext(null);
7
4
  /**
8
- * Card wrapper providing Figma-designed visual treatment for panel content.
9
- * Solid background, shadow-sm elevation, rounded corners, subtle border.
10
- *
11
- * In connected mode, reads AppShellContext + PanelIndexContext to adapt
12
- * border-radius based on panel position (first/last/only).
5
+ * Read AppShell layout context. Returns null when used outside AppShell.Root.
13
6
  */
14
- function AppShellContent({ className, children, ...props }) {
15
- const context = useAppShell();
16
- const connected = context?.connected ?? false;
17
- const panelIndex = React$1.useContext(PanelIndexContext);
18
- const position = connected && context ? context.getPanelPosition(panelIndex) : null;
19
- return /* @__PURE__ */ jsx("div", {
20
- "data-slot": "app-shell-content",
21
- className: cn("flex flex-col h-full min-h-0 overflow-clip", "bg-background dark:bg-surface-1", "border border-border", "shadow-sm", !connected && "rounded-2xl", connected && position === "only" && "rounded-2xl", connected && position === "first" && ["rounded-ss-2xl rounded-es-2xl", "rounded-se-none rounded-ee-none"], connected && position === "last" && ["rounded-ss-none rounded-es-none", "rounded-se-2xl rounded-ee-2xl"], className),
22
- ...props,
23
- children
24
- });
7
+ function useAppShell() {
8
+ return React$1.useContext(AppShellContext);
9
+ }
10
+ var AppShellProvider = AppShellContext.Provider;
11
+ /**
12
+ * Internal context for passing the panel index from Panel to Content.
13
+ * Content reads this to determine its position in connected mode.
14
+ */
15
+ var PanelIndexContext = React$1.createContext(0);
16
+ var PanelLayoutContext = React$1.createContext({
17
+ visible: true,
18
+ isMobile: false
19
+ });
20
+ var PanelExpansionContext = React$1.createContext(null);
21
+ function usePanelExpansion() {
22
+ return React$1.useContext(PanelExpansionContext);
25
23
  }
26
- AppShellContent.displayName = "AppShell.Content";
27
24
  //#endregion
28
- export { AppShellContent };
25
+ export { AppShellContext, AppShellProvider, PanelExpansionContext, PanelIndexContext, PanelLayoutContext, useAppShell, usePanelExpansion };
29
26
 
30
27
  //# sourceMappingURL=index218.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index218.js","names":[],"sources":["../src/components/templates/AppShell/AppShellContent.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { cn } from '@/lib/utils';\nimport { PanelIndexContext, useAppShell } from './AppShellContext';\n\nexport interface AppShellContentProps extends React.ComponentProps<'div'> {}\n\n/**\n * Card wrapper providing Figma-designed visual treatment for panel content.\n * Solid background, shadow-sm elevation, rounded corners, subtle border.\n *\n * In connected mode, reads AppShellContext + PanelIndexContext to adapt\n * border-radius based on panel position (first/last/only).\n */\nfunction AppShellContent({\n className,\n children,\n ...props\n}: AppShellContentProps) {\n const context = useAppShell();\n const connected = context?.connected ?? false;\n\n // Read panel index from PanelIndexContext (set by Root via provider)\n const panelIndex = React.useContext(PanelIndexContext);\n const position =\n connected && context ? context.getPanelPosition(panelIndex) : null;\n\n return (\n <div\n data-slot=\"app-shell-content\"\n className={cn(\n // Core layout\n 'flex flex-col h-full min-h-0 overflow-clip',\n // Figma card styles\n 'bg-background dark:bg-surface-1',\n 'border border-border',\n 'shadow-sm',\n // Border radius: connected mode adapts per position\n !connected && 'rounded-2xl',\n connected && position === 'only' && 'rounded-2xl',\n connected &&\n position === 'first' && [\n 'rounded-ss-2xl rounded-es-2xl',\n 'rounded-se-none rounded-ee-none',\n ],\n connected &&\n position === 'last' && [\n 'rounded-ss-none rounded-es-none',\n 'rounded-se-2xl rounded-ee-2xl',\n ],\n className,\n )}\n {...props}\n >\n {children}\n </div>\n );\n}\n\nAppShellContent.displayName = 'AppShell.Content';\n\nexport { AppShellContent };\n"],"mappings":";;;;;;;;;;;;;AAeA,SAAS,gBAAgB,EACvB,WACA,UACA,GAAG,SACoB;CACvB,MAAM,UAAU,YAAY;CAC5B,MAAM,YAAY,SAAS,aAAa;CAGxC,MAAM,aAAa,QAAM,WAAW,iBAAiB;CACrD,MAAM,WACJ,aAAa,UAAU,QAAQ,iBAAiB,UAAU,IAAI;CAEhE,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAET,8CAEA,mCACA,wBACA,aAEA,CAAC,aAAa,eACd,aAAa,aAAa,UAAU,eACpC,aACE,aAAa,WAAW,CACtB,iCACA,iCACF,GACF,aACE,aAAa,UAAU,CACrB,mCACA,+BACF,GACF,SACF;EACA,GAAI;EAEH;CACE,CAAA;AAET;AAEA,gBAAgB,cAAc"}
1
+ {"version":3,"file":"index218.js","names":[],"sources":["../src/components/templates/AppShell/AppShellContext.ts"],"sourcesContent":["import * as React from 'react';\n\nexport type PanelPosition = 'only' | 'first' | 'last';\n\nexport interface AppShellContextValue {\n /** Whether the shell is in connected (joined-edge) mode */\n connected: boolean;\n /** Number of visible Panel children */\n panelCount: number;\n /** Get the position of a panel by its index among visible panels */\n getPanelPosition: (index: number) => PanelPosition;\n}\n\nconst AppShellContext = React.createContext<AppShellContextValue | null>(null);\n\n/**\n * Read AppShell layout context. Returns null when used outside AppShell.Root.\n */\nfunction useAppShell(): AppShellContextValue | null {\n return React.useContext(AppShellContext);\n}\n\nconst AppShellProvider = AppShellContext.Provider;\n\n/**\n * Internal context for passing the panel index from Panel to Content.\n * Content reads this to determine its position in connected mode.\n */\nconst PanelIndexContext = React.createContext<number>(0);\n\n/**\n * Per-panel layout state provided by Root. Replaces cloneElement style injection.\n * Panel reads this to self-manage visibility, mobile sizing, and ARIA attributes.\n */\nexport interface PanelLayoutInfo {\n /** Whether this panel is visible (false = hidden overflow panel or non-expanded sibling) */\n visible: boolean;\n /** How hidden desktop panels should leave layout. Animated keeps the flex item in-flow briefly. */\n collapseMode?: 'animated' | 'removed';\n /** Whether we're in mobile viewport */\n isMobile: boolean;\n /** ARIA tab ID for tabpanel association (set when mobile tab bar is active) */\n tabId?: string;\n /** ARIA panel ID for tabpanel role (set when mobile tab bar is active) */\n panelId?: string;\n /** Whether Root owns panel sizing, such as through ResizablePanel */\n sizeManagedByRoot?: boolean;\n /** Root-owned expansion override */\n expanded?: boolean;\n /** Root-owned expansion change callback */\n onExpandedChange?: (expanded: boolean) => void;\n}\n\nconst PanelLayoutContext = React.createContext<PanelLayoutInfo>({\n visible: true,\n isMobile: false,\n});\n\nexport interface PanelExpansionInfo {\n expanded: boolean;\n onExpandedChange?: (expanded: boolean) => void;\n}\n\nconst PanelExpansionContext = React.createContext<PanelExpansionInfo | null>(\n null,\n);\n\nfunction usePanelExpansion(): PanelExpansionInfo | null {\n return React.useContext(PanelExpansionContext);\n}\n\nexport {\n AppShellContext,\n AppShellProvider,\n PanelExpansionContext,\n PanelIndexContext,\n PanelLayoutContext,\n useAppShell,\n usePanelExpansion,\n};\n"],"mappings":";;AAaA,IAAM,kBAAkB,QAAM,cAA2C,IAAI;;;;AAK7E,SAAS,cAA2C;CAClD,OAAO,QAAM,WAAW,eAAe;AACzC;AAEA,IAAM,mBAAmB,gBAAgB;;;;;AAMzC,IAAM,oBAAoB,QAAM,cAAsB,CAAC;AAyBvD,IAAM,qBAAqB,QAAM,cAA+B;CAC9D,SAAS;CACT,UAAU;AACZ,CAAC;AAOD,IAAM,wBAAwB,QAAM,cAClC,IACF;AAEA,SAAS,oBAA+C;CACtD,OAAO,QAAM,WAAW,qBAAqB;AAC/C"}