@flikk/ui 1.0.0-beta.14 → 1.0.0-beta.15

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 (254) hide show
  1. package/dist/components/ai/CodeBlock/CodeBlock.theme.js +1 -1
  2. package/dist/components/ai/PromptInput/PromptInput.js +3 -1
  3. package/dist/components/ai/PromptSuggestions/PromptSuggestion.theme.js +4 -4
  4. package/dist/components/ai/StreamingResponse/StreamingResponse.js +6 -0
  5. package/dist/components/ai/ThinkingIndicator/ThinkingIndicator.js +3 -14
  6. package/dist/components/ai/index.d.ts +0 -5
  7. package/dist/components/ai/index.js +8 -4
  8. package/dist/components/charts/DonutChart/DonutChart.js +1 -1
  9. package/dist/components/charts/DonutChart/MultiSegmentDonutChart.js +1 -1
  10. package/dist/components/charts/shared/ChartLegend/ChartLegend.types.d.ts +13 -1
  11. package/dist/components/charts/shared/ChartLegend/ChartLegendContent.js +1 -1
  12. package/dist/components/charts/shared/ChartTooltip/ChartTooltip.types.d.ts +13 -2
  13. package/dist/components/core/Accordion/AccordionItem.js +1 -1
  14. package/dist/components/core/Accordion/AccordionTrigger.js +1 -1
  15. package/dist/components/core/Alert/Alert.animations.d.ts +11 -0
  16. package/dist/components/core/Alert/Alert.animations.js +44 -0
  17. package/dist/components/core/Alert/Alert.js +16 -3
  18. package/dist/components/core/Avatar/Avatar.js +12 -7
  19. package/dist/components/core/Avatar/Avatar.theme.d.ts +4 -6
  20. package/dist/components/core/Avatar/Avatar.theme.js +22 -12
  21. package/dist/components/core/Avatar/Avatar.types.d.ts +9 -0
  22. package/dist/components/core/AvatarGroup/AvatarGroup.animations.js +2 -2
  23. package/dist/components/core/AvatarGroup/AvatarGroup.js +1 -2
  24. package/dist/components/core/AvatarGroup/AvatarGroup.theme.js +1 -1
  25. package/dist/components/core/Badge/Badge.animations.js +1 -1
  26. package/dist/components/core/Badge/Badge.js +23 -47
  27. package/dist/components/core/Badge/Badge.theme.js +48 -62
  28. package/dist/components/core/Badge/Badge.types.d.ts +5 -29
  29. package/dist/components/core/Button/Button.js +2 -2
  30. package/dist/components/core/Button/Button.theme.js +2 -2
  31. package/dist/components/core/ButtonGroup/ButtonGroup.theme.js +6 -6
  32. package/dist/components/core/ButtonGroup/ButtonGroupText.js +1 -3
  33. package/dist/components/core/Calendar/Calendar.js +29 -3
  34. package/dist/components/core/Calendar/Calendar.theme.js +11 -7
  35. package/dist/components/core/Calendar/Calendar.types.d.ts +3 -0
  36. package/dist/components/core/Carousel/CarouselBody.js +0 -1
  37. package/dist/components/core/CommandPalette/CommandItem.js +1 -1
  38. package/dist/components/core/CommandPalette/CommandPalette.js +6 -4
  39. package/dist/components/core/CommandPalette/CommandPalette.theme.js +1 -0
  40. package/dist/components/core/CommandPalette/CommandPalette.types.d.ts +6 -0
  41. package/dist/components/core/ContextMenu/ContextMenu.js +5 -4
  42. package/dist/components/core/ContextMenu/ContextMenuTrigger.js +5 -6
  43. package/dist/components/core/Drawer/Drawer.d.ts +1 -1
  44. package/dist/components/core/Drawer/Drawer.js +25 -2
  45. package/dist/components/core/Drawer/Drawer.theme.js +2 -2
  46. package/dist/components/core/Drawer/Drawer.types.d.ts +6 -0
  47. package/dist/components/core/Dropdown/Dropdown.d.ts +1 -1
  48. package/dist/components/core/Dropdown/Dropdown.js +5 -1
  49. package/dist/components/core/Dropdown/Dropdown.types.d.ts +1 -0
  50. package/dist/components/core/Dropdown/DropdownItem.js +1 -1
  51. package/dist/components/core/Dropdown/DropdownMenu.js +4 -4
  52. package/dist/components/core/Dropdown/DropdownSection.js +1 -1
  53. package/dist/components/core/Dropdown/DropdownSeparator.js +1 -1
  54. package/dist/components/core/Dropdown/DropdownTrigger.d.ts +6 -1
  55. package/dist/components/core/Dropdown/DropdownTrigger.js +10 -8
  56. package/dist/components/core/Kbd/Kbd.theme.js +3 -3
  57. package/dist/components/core/Link/Link.js +3 -1
  58. package/dist/components/core/Message/Message.d.ts +9 -0
  59. package/dist/components/core/Message/Message.js +44 -3
  60. package/dist/components/core/Message/Message.theme.js +22 -0
  61. package/dist/components/core/Message/Message.types.d.ts +115 -0
  62. package/dist/components/core/Message/MessageAudio.d.ts +8 -0
  63. package/dist/components/core/Message/MessageAudio.js +11 -0
  64. package/dist/components/core/Message/MessageContext.d.ts +3 -1
  65. package/dist/components/core/Message/MessageDateDivider.d.ts +6 -0
  66. package/dist/components/core/Message/MessageDateDivider.js +10 -0
  67. package/dist/components/core/Message/MessageFile.d.ts +9 -0
  68. package/dist/components/core/Message/MessageFile.js +15 -0
  69. package/dist/components/core/Message/MessageImage.d.ts +11 -0
  70. package/dist/components/core/Message/MessageImage.js +13 -0
  71. package/dist/components/core/Message/MessageLink.d.ts +10 -0
  72. package/dist/components/core/Message/MessageLink.js +15 -0
  73. package/dist/components/core/Message/MessageReactions.d.ts +8 -0
  74. package/dist/components/core/Message/MessageReactions.js +12 -0
  75. package/dist/components/core/Message/MessageReply.d.ts +8 -0
  76. package/dist/components/core/Message/MessageReply.js +10 -0
  77. package/dist/components/core/Message/MessageSenderName.d.ts +6 -0
  78. package/dist/components/core/Message/MessageSenderName.js +10 -0
  79. package/dist/components/core/Message/MessageStatusIndicator.d.ts +9 -0
  80. package/dist/components/core/Message/MessageStatusIndicator.js +45 -0
  81. package/dist/components/core/Message/index.d.ts +19 -1
  82. package/dist/components/core/Modal/Modal.animations.d.ts +1 -0
  83. package/dist/components/core/Modal/Modal.animations.js +14 -11
  84. package/dist/components/core/Pagination/Pagination.theme.js +1 -1
  85. package/dist/components/core/Popover/Popover.d.ts +1 -1
  86. package/dist/components/core/Popover/PopoverBody.js +2 -2
  87. package/dist/components/core/Popover/PopoverTrigger.d.ts +1 -1
  88. package/dist/components/core/Popover/PopoverTrigger.js +11 -11
  89. package/dist/components/core/Progress/Progress.d.ts +9 -8
  90. package/dist/components/core/Progress/Progress.js +16 -16
  91. package/dist/components/core/Progress/Progress.theme.js +5 -16
  92. package/dist/components/core/Progress/Progress.types.d.ts +2 -20
  93. package/dist/components/core/Progress/index.d.ts +1 -1
  94. package/dist/components/core/ScrollArea/ScrollArea.js +49 -7
  95. package/dist/components/core/ScrollArea/ScrollArea.types.d.ts +12 -3
  96. package/dist/components/core/ScrollArea/index.d.ts +1 -1
  97. package/dist/components/core/Segmented/SegmentedItem.js +1 -1
  98. package/dist/components/core/Sidebar/Sidebar.js +2 -1
  99. package/dist/components/core/Sidebar/SidebarMobileTrigger.js +2 -1
  100. package/dist/components/core/Sidebar/SidebarToggle.js +2 -1
  101. package/dist/components/core/Sidebar/SidebarUserProfile.js +1 -1
  102. package/dist/components/core/SocialIcon/SocialIcon.js +1 -1
  103. package/dist/components/core/Sortable/Sortable.js +2 -2
  104. package/dist/components/core/Sortable/Sortable.theme.js +1 -1
  105. package/dist/components/core/Sortable/Sortable.types.d.ts +7 -5
  106. package/dist/components/core/Tabs/TabsBody.js +1 -1
  107. package/dist/components/core/Tabs/TabsTrigger.js +1 -1
  108. package/dist/components/core/Tag/Tag.js +2 -2
  109. package/dist/components/core/Toast/Toast.d.ts +2 -2
  110. package/dist/components/core/Toast/Toast.js +30 -21
  111. package/dist/components/core/Toast/Toast.theme.js +4 -9
  112. package/dist/components/core/Toast/Toast.types.d.ts +4 -21
  113. package/dist/components/core/Toast/index.d.ts +1 -1
  114. package/dist/components/core/Tooltip/Tooltip.js +1 -1
  115. package/dist/components/core/Tooltip/Tooltip.theme.js +1 -1
  116. package/dist/components/core/index.js +9 -0
  117. package/dist/components/data-display/GanttChart/GanttChart.types.d.ts +2 -2
  118. package/dist/components/data-display/Table/Table.types.d.ts +8 -8
  119. package/dist/components/effects/CustomCursor/CustomCursor.js +2 -2
  120. package/dist/components/effects/GlassSurface/GlassSurface.d.ts +1 -1
  121. package/dist/components/effects/GlassSurface/GlassSurface.js +12 -4
  122. package/dist/components/effects/InteractiveCharacters/InteractiveCharacters.animations.d.ts +39 -0
  123. package/dist/components/effects/InteractiveCharacters/InteractiveCharacters.animations.js +98 -0
  124. package/dist/components/effects/InteractiveCharacters/InteractiveCharacters.d.ts +3 -0
  125. package/dist/components/effects/InteractiveCharacters/InteractiveCharacters.js +104 -0
  126. package/dist/components/effects/InteractiveCharacters/InteractiveCharacters.types.d.ts +30 -0
  127. package/dist/components/effects/InteractiveCharacters/characters/BlobCharacter.d.ts +3 -0
  128. package/dist/components/effects/InteractiveCharacters/characters/BlobCharacter.js +36 -0
  129. package/dist/components/effects/InteractiveCharacters/characters/SmallCharacter.d.ts +3 -0
  130. package/dist/components/effects/InteractiveCharacters/characters/SmallCharacter.js +36 -0
  131. package/dist/components/effects/InteractiveCharacters/characters/TallCharacter.d.ts +3 -0
  132. package/dist/components/effects/InteractiveCharacters/characters/TallCharacter.js +37 -0
  133. package/dist/components/effects/InteractiveCharacters/hooks/useBlink.d.ts +14 -0
  134. package/dist/components/effects/InteractiveCharacters/hooks/useBlink.js +41 -0
  135. package/dist/components/effects/InteractiveCharacters/hooks/useIdleAnimation.d.ts +25 -0
  136. package/dist/components/effects/InteractiveCharacters/hooks/useIdleAnimation.js +84 -0
  137. package/dist/components/effects/InteractiveCharacters/hooks/useMouseTracking.d.ts +18 -0
  138. package/dist/components/effects/InteractiveCharacters/hooks/useMouseTracking.js +35 -0
  139. package/dist/components/effects/InteractiveCharacters/index.d.ts +2 -0
  140. package/dist/components/effects/MorphingText/MorphingText.d.ts +1 -1
  141. package/dist/components/effects/MorphingText/MorphingText.js +6 -5
  142. package/dist/components/effects/Neumorphic/InsetCircleButton.d.ts +9 -0
  143. package/dist/components/effects/Neumorphic/InsetCircleButton.js +10 -0
  144. package/dist/components/effects/Neumorphic/InsetPill.d.ts +7 -0
  145. package/dist/components/effects/Neumorphic/InsetPill.js +7 -0
  146. package/dist/components/effects/Neumorphic/index.d.ts +4 -0
  147. package/dist/components/effects/NoiseOverlay/NoiseOverlay.d.ts +1 -1
  148. package/dist/components/effects/NoiseOverlay/NoiseOverlay.js +4 -4
  149. package/dist/components/effects/Overlay/Overlay.js +6 -4
  150. package/dist/components/effects/PageTransition/PageTransition.animations.d.ts +8 -0
  151. package/dist/components/effects/PageTransition/PageTransition.animations.js +53 -0
  152. package/dist/components/effects/PageTransition/PageTransition.d.ts +3 -0
  153. package/dist/components/effects/PageTransition/PageTransition.js +71 -0
  154. package/dist/components/effects/PageTransition/PageTransition.types.d.ts +15 -0
  155. package/dist/components/effects/PageTransition/index.d.ts +2 -0
  156. package/dist/components/effects/index.d.ts +6 -0
  157. package/dist/components/effects/index.js +4 -0
  158. package/dist/components/forms/Checkbox/Checkbox.animations.d.ts +14 -0
  159. package/dist/components/forms/Checkbox/Checkbox.animations.js +53 -0
  160. package/dist/components/forms/Checkbox/Checkbox.js +4 -2
  161. package/dist/components/forms/Checkbox/Checkbox.theme.js +3 -3
  162. package/dist/components/forms/ColorPicker/ColorPicker.types.d.ts +1 -1
  163. package/dist/components/forms/ColorPicker/ColorPickerBody.js +3 -3
  164. package/dist/components/forms/Combobox/Combobox.js +5 -3
  165. package/dist/components/forms/DatePicker/DatePickerBody.js +1 -1
  166. package/dist/components/forms/DateRangePicker/DateRangePicker.animations.d.ts +1 -0
  167. package/dist/components/forms/DateRangePicker/DateRangePicker.d.ts +37 -0
  168. package/dist/components/forms/DateRangePicker/DateRangePicker.js +110 -0
  169. package/dist/components/forms/DateRangePicker/DateRangePicker.theme.d.ts +5 -0
  170. package/dist/components/forms/DateRangePicker/DateRangePicker.theme.js +52 -0
  171. package/dist/components/forms/DateRangePicker/DateRangePicker.types.d.ts +154 -0
  172. package/dist/components/forms/DateRangePicker/DateRangePickerBody.d.ts +6 -0
  173. package/dist/components/forms/DateRangePicker/DateRangePickerBody.js +208 -0
  174. package/dist/components/forms/DateRangePicker/DateRangePickerPresets.d.ts +6 -0
  175. package/dist/components/forms/DateRangePicker/DateRangePickerPresets.js +41 -0
  176. package/dist/components/forms/DateRangePicker/DateRangePickerTrigger.d.ts +6 -0
  177. package/dist/components/forms/DateRangePicker/DateRangePickerTrigger.js +32 -0
  178. package/dist/components/forms/DateRangePicker/dateRangePresets.d.ts +5 -0
  179. package/dist/components/forms/DateRangePicker/dateRangePresets.js +59 -0
  180. package/dist/components/forms/DateRangePicker/index.d.ts +4 -0
  181. package/dist/components/forms/FileUpload/FileUploadProgress.animations.d.ts +36 -0
  182. package/dist/components/forms/FileUpload/FileUploadProgress.animations.js +22 -0
  183. package/dist/components/forms/FileUpload/FileUploadProgress.d.ts +3 -0
  184. package/dist/components/forms/FileUpload/FileUploadProgress.js +111 -0
  185. package/dist/components/forms/FileUpload/FileUploadProgress.theme.d.ts +19 -0
  186. package/dist/components/forms/FileUpload/FileUploadProgress.theme.js +27 -0
  187. package/dist/components/forms/FileUpload/FileUploadProgress.types.d.ts +33 -0
  188. package/dist/components/forms/FileUpload/index.d.ts +3 -0
  189. package/dist/components/forms/Input/Input.js +8 -13
  190. package/dist/components/forms/Input/Input.types.d.ts +6 -0
  191. package/dist/components/forms/InputAddress/InputAddress.theme.js +1 -1
  192. package/dist/components/forms/InputCounter/InputCounter.js +1 -1
  193. package/dist/components/forms/InputCreditCard/InputCreditCard.theme.js +1 -1
  194. package/dist/components/forms/InputOTP/InputOTP.theme.js +1 -1
  195. package/dist/components/forms/Radio/Radio.animations.d.ts +10 -0
  196. package/dist/components/forms/Radio/Radio.animations.js +33 -0
  197. package/dist/components/forms/Radio/Radio.js +11 -2
  198. package/dist/components/forms/Radio/Radio.theme.js +3 -3
  199. package/dist/components/forms/RichTextEditor/RichTextEditor.js +13 -4
  200. package/dist/components/forms/RichTextEditor/RichTextEditor.theme.js +2 -2
  201. package/dist/components/forms/RichTextEditor/RichTextEditor.types.d.ts +11 -0
  202. package/dist/components/forms/Select/Select.d.ts +1 -1
  203. package/dist/components/forms/Select/Select.js +7 -7
  204. package/dist/components/forms/Select/Select.types.d.ts +3 -3
  205. package/dist/components/forms/SelectableCard/SelectableCard.js +1 -1
  206. package/dist/components/forms/Slider/Slider.theme.js +1 -1
  207. package/dist/components/forms/Switch/Switch.theme.js +3 -3
  208. package/dist/components/forms/forms.theme.js +1 -1
  209. package/dist/components/forms/index.d.ts +6 -0
  210. package/dist/components/forms/index.js +8 -0
  211. package/dist/hooks/index.d.ts +1 -0
  212. package/dist/hooks/useMediaQuery.d.ts +5 -0
  213. package/dist/hooks/useMediaQuery.js +21 -0
  214. package/dist/index.js +21 -0
  215. package/dist/styles.css +1 -1
  216. package/dist/utils/dateUtils.js +56 -5
  217. package/dist/utils/formatUtils.d.ts +10 -0
  218. package/dist/utils/formatUtils.js +24 -0
  219. package/dist/utils/index.d.ts +1 -1
  220. package/package.json +12 -4
  221. package/src/global.scss +319 -39
  222. package/src/styles/theme.css +105 -16
  223. package/src/theme-plugin.css +13 -0
  224. package/dist/components/ai/ApprovalCard/ApprovalCard.d.ts +0 -3
  225. package/dist/components/ai/ApprovalCard/ApprovalCard.js +0 -16
  226. package/dist/components/ai/ApprovalCard/ApprovalCard.theme.d.ts +0 -13
  227. package/dist/components/ai/ApprovalCard/ApprovalCard.theme.js +0 -15
  228. package/dist/components/ai/ApprovalCard/ApprovalCard.types.d.ts +0 -43
  229. package/dist/components/ai/ApprovalCard/index.d.ts +0 -2
  230. package/dist/components/ai/MessageHistory/MessageHistory.d.ts +0 -18
  231. package/dist/components/ai/MessageHistory/MessageHistory.js +0 -98
  232. package/dist/components/ai/MessageHistory/MessageHistory.theme.d.ts +0 -2
  233. package/dist/components/ai/MessageHistory/MessageHistory.theme.js +0 -8
  234. package/dist/components/ai/MessageHistory/MessageHistory.types.d.ts +0 -94
  235. package/dist/components/ai/MessageHistory/index.d.ts +0 -3
  236. package/dist/icons/Icon.d.ts +0 -24
  237. package/dist/icons/Icon.js +0 -30
  238. package/dist/icons/Index.d.ts +0 -16
  239. package/dist/icons/core/ChevronUpDown.d.ts +0 -1
  240. package/dist/icons/core/ChevronUpDown.js +0 -7
  241. package/dist/icons/core/DollarIcon.d.ts +0 -1
  242. package/dist/icons/core/DollarIcon.js +0 -5
  243. package/dist/icons/core/LockIcon.d.ts +0 -1
  244. package/dist/icons/core/LockIcon.js +0 -5
  245. package/dist/icons/core/MinusIcon.d.ts +0 -1
  246. package/dist/icons/core/MinusIcon.js +0 -7
  247. package/dist/icons/core/PlusIcon.d.ts +0 -1
  248. package/dist/icons/core/PlusIcon.js +0 -7
  249. package/dist/icons/core/SearchIcon.d.ts +0 -1
  250. package/dist/icons/core/SearchIcon.js +0 -7
  251. package/dist/icons/core/TickIcon.d.ts +0 -1
  252. package/dist/icons/core/TickIcon.js +0 -5
  253. package/dist/icons/core/User.d.ts +0 -1
  254. package/dist/utils/useClickOutside.d.ts +0 -1
@@ -126,7 +126,7 @@ const CommandItem = ({ command, index, isHighlighted, contentStart, contentEnd,
126
126
  }
127
127
  return null;
128
128
  };
129
- return (jsxs("div", { "data-command-index": index, "data-highlighted": isHighlighted, "data-disabled": command.disabled || false, className: cn(theme.commandItem, className), onClick: handleClick, onMouseEnter: handleMouseEnter, children: [finalContentStart && (jsx("div", { className: "flex-shrink-0", children: finalContentStart })), jsxs("div", { className: "flex-1 min-w-0", children: [jsx("div", { className: "text-base truncate", children: command.label }), command.subtitle && (jsx("div", { className: "text-base opacity-70 truncate mt-0", children: command.subtitle }))] }), renderContentEnd()] }));
129
+ return (jsxs("div", { "data-command-index": index, "data-highlighted": isHighlighted, "data-disabled": command.disabled || false, className: cn(theme.commandItem, className), role: "option", "aria-selected": isHighlighted, "aria-disabled": command.disabled || false, onClick: handleClick, onMouseEnter: handleMouseEnter, children: [finalContentStart && (jsx("div", { className: "flex-shrink-0", children: finalContentStart })), jsxs("div", { className: "flex-1 min-w-0", children: [jsx("div", { className: "text-base truncate", children: command.label }), command.subtitle && (jsx("div", { className: "text-base opacity-70 truncate mt-0", children: command.subtitle }))] }), renderContentEnd()] }));
130
130
  };
131
131
 
132
132
  export { CommandItem };
@@ -6,6 +6,8 @@ import { cn } from '../../../utils/cn.js';
6
6
  import { MagnifyingGlassIcon } from '@heroicons/react/24/outline';
7
7
  import { CommandItem } from './CommandItem.js';
8
8
  import { Overlay } from '../../effects/Overlay/Overlay.js';
9
+ import { ScrollArea } from '../ScrollArea/ScrollArea.js';
10
+ import '../ScrollArea/smooth/SmoothScrollEngine.js';
9
11
 
10
12
  /**
11
13
  * Default filter function for commands
@@ -77,7 +79,7 @@ const groupCommandsByCategory = (commands) => {
77
79
  * />
78
80
  * ```
79
81
  */
80
- const CommandPalette = React__default.forwardRef(({ isOpen, onClose, commands = [], placeholder = "Type a command or search...", emptyMessage = "No results found.", maxHeight = "400px", className = "", overlayClassName = "", theme: themeOverrides, grouped = false, onSearchChange, filterFunction = defaultFilterFunction, closeOnOverlayClick = true, closeOnEsc = true, }, ref) => {
82
+ const CommandPalette = React__default.forwardRef(({ isOpen, onClose, commands = [], placeholder = "Type a command or search...", emptyMessage = "No results found.", maxHeight = "400px", className = "", overlayClassName = "", theme: themeOverrides, grouped = false, onSearchChange, filterFunction = defaultFilterFunction, closeOnOverlayClick = true, closeOnEsc = true, footer, footerClassName, }, ref) => {
81
83
  // Merge theme with overrides
82
84
  const theme = useMemo(() => ({ ...commandPaletteTheme, ...(themeOverrides || {}) }), [themeOverrides]);
83
85
  // State
@@ -195,7 +197,7 @@ const CommandPalette = React__default.forwardRef(({ isOpen, onClose, commands =
195
197
  // Render commands list
196
198
  const renderCommandsList = () => {
197
199
  if (flatFilteredCommands.length === 0) {
198
- return jsx("div", { className: theme.emptyState, children: emptyMessage });
200
+ return jsx("div", { className: theme.emptyState, "aria-live": "polite", children: emptyMessage });
199
201
  }
200
202
  // If grouped, render with group labels
201
203
  if (isGroupedCommands(displayCommands)) {
@@ -212,9 +214,9 @@ const CommandPalette = React__default.forwardRef(({ isOpen, onClose, commands =
212
214
  return (jsxs(Overlay, { ref: ref, isOpen: isOpen, onClose: onClose, closeOnOverlayClick: closeOnOverlayClick, closeOnEsc: closeOnEsc, position: "top", overlayClassName: overlayClassName, contentClassName: cn(theme.container, className), animations: {
213
215
  overlay: overlayAnimations,
214
216
  content: containerAnimations,
215
- }, children: [jsx("div", { className: theme.searchWrapper, children: jsxs("div", { className: "flex items-center gap-3", children: [jsx(MagnifyingGlassIcon, { className: "w-5 h-5 text-[var(--color-text-muted)]", strokeWidth: 2 }), jsx("input", { ref: searchInputRef, type: "text", className: theme.searchInput, placeholder: placeholder, value: searchValue, onChange: handleSearchChange, autoComplete: "off", autoCorrect: "off", spellCheck: false })] }) }), jsx("div", { ref: listContainerRef, className: "overflow-y-auto overscroll-contain px-1", style: {
217
+ }, children: [jsx("div", { className: theme.searchWrapper, children: jsxs("div", { className: "flex items-center gap-3", children: [jsx(MagnifyingGlassIcon, { className: "w-5 h-5 text-[var(--color-text-muted)]", strokeWidth: 2 }), jsx("input", { ref: searchInputRef, type: "text", className: theme.searchInput, placeholder: placeholder, value: searchValue, onChange: handleSearchChange, autoComplete: "off", autoCorrect: "off", spellCheck: false, "aria-label": "Search commands" })] }) }), jsx(ScrollArea, { ref: listContainerRef, type: "hover", className: "overscroll-contain px-1", style: {
216
218
  maxHeight: typeof maxHeight === "number" ? `${maxHeight}px` : maxHeight,
217
- }, children: renderCommandsList() })] }));
219
+ }, children: jsx("div", { role: "listbox", "aria-label": "Commands", children: renderCommandsList() }) }), footer && (jsx("div", { className: cn(theme.footer, footerClassName), children: footer }))] }));
218
220
  });
219
221
  CommandPalette.displayName = "CommandPalette";
220
222
 
@@ -25,6 +25,7 @@ const commandPaletteTheme = {
25
25
  "dark:data-[highlighted=true]:bg-[var(--color-primary-600)]",
26
26
  emptyState: "px-4 py-12 text-center text-base text-[var(--color-text-muted)] " +
27
27
  "dark:text-[var(--color-neutral-500)]",
28
+ footer: "border-t border-[var(--color-border)] px-4 py-2 text-sm text-[var(--color-text-muted)]font-medium",
28
29
  };
29
30
 
30
31
  export { commandPaletteTheme };
@@ -67,6 +67,10 @@ export interface CommandPaletteProps {
67
67
  closeOnOverlayClick?: boolean;
68
68
  /** Whether pressing Escape should close the palette (default: true) */
69
69
  closeOnEsc?: boolean;
70
+ /** Footer content rendered below the command list (e.g., keyboard hints) */
71
+ footer?: React.ReactNode;
72
+ /** Additional class name for the footer */
73
+ footerClassName?: string;
70
74
  }
71
75
  /**
72
76
  * Theme overrides for the CommandPalette component
@@ -86,4 +90,6 @@ export interface CommandPaletteThemeOverrides {
86
90
  commandItem?: string;
87
91
  /** Style for empty state */
88
92
  emptyState?: string;
93
+ /** Style for the footer area */
94
+ footer?: string;
89
95
  }
@@ -39,11 +39,12 @@ const ContextMenuRoot = ({ children, className, onOpenChange, theme: themeOverri
39
39
  const handleOpenChange = useCallback((value) => {
40
40
  setIsOpen(value);
41
41
  onOpenChange === null || onOpenChange === void 0 ? void 0 : onOpenChange(value);
42
- // Get cursor position from trigger element when opening
42
+ // Get cursor position from trigger element data attributes when opening
43
43
  if (value && triggerRef.current) {
44
- const storedPosition = triggerRef.current.__cursorPosition;
45
- if (storedPosition) {
46
- setCursorPosition(storedPosition);
44
+ const x = triggerRef.current.dataset.cursorX;
45
+ const y = triggerRef.current.dataset.cursorY;
46
+ if (x && y) {
47
+ setCursorPosition({ x: Number(x), y: Number(y) });
47
48
  }
48
49
  }
49
50
  }, [onOpenChange]);
@@ -14,11 +14,10 @@ const ContextMenuTrigger = React__default.forwardRef(({ children, className, dis
14
14
  // Prevent default browser context menu
15
15
  e.preventDefault();
16
16
  e.stopPropagation();
17
- // Store cursor position BEFORE opening menu
18
- e.currentTarget.__cursorPosition = {
19
- x: e.clientX,
20
- y: e.clientY,
21
- };
17
+ // Store cursor position on trigger element via data attributes
18
+ const target = e.currentTarget;
19
+ target.dataset.cursorX = String(e.clientX);
20
+ target.dataset.cursorY = String(e.clientY);
22
21
  // Now open the menu with position available
23
22
  onOpenChange(true);
24
23
  }, [disabled, onOpenChange]);
@@ -44,6 +43,6 @@ const ContextMenuTrigger = React__default.forwardRef(({ children, className, dis
44
43
  "data-disabled": disabled,
45
44
  });
46
45
  });
47
- ContextMenuTrigger.displayName = "ContextMenuTrigger";
46
+ ContextMenuTrigger.displayName = "ContextMenu.Trigger";
48
47
 
49
48
  export { ContextMenuTrigger };
@@ -1,7 +1,7 @@
1
1
  import { DrawerProps, DrawerContextValue } from "./Drawer.types";
2
2
  export declare const useDrawerContext: () => DrawerContextValue;
3
3
  export declare const Drawer: {
4
- ({ isOpen, onClose, title, subtitle, icon, position, size, closeOnOverlayClick, closeOnEsc, showCloseButton, children, className, theme: themeOverrides, scale, ...props }: DrawerProps): import("react/jsx-runtime").JSX.Element;
4
+ ({ isOpen, onClose, title, subtitle, icon, position, size, closeOnOverlayClick, closeOnEsc, showCloseButton, children, className, theme: themeOverrides, scale, closeOnBack, ...props }: DrawerProps): import("react/jsx-runtime").JSX.Element;
5
5
  displayName: string;
6
6
  } & {
7
7
  Header: {
@@ -1,5 +1,5 @@
1
1
  import { jsx, jsxs } from 'react/jsx-runtime';
2
- import React__default, { createContext, useId, useMemo, useContext } from 'react';
2
+ import React__default, { createContext, useId, useMemo, useRef, useEffect, useContext } from 'react';
3
3
  import { cn } from '../../../utils/cn.js';
4
4
  import { useScaleBackground } from '../../../hooks/useScaleBackground.js';
5
5
  import { Overlay } from '../../effects/Overlay/Overlay.js';
@@ -11,6 +11,27 @@ import { DrawerSubtitle } from './DrawerSubtitle.js';
11
11
  import { DrawerBody } from './DrawerBody.js';
12
12
  import { DrawerFooter } from './DrawerFooter.js';
13
13
 
14
+ /** Manages browser history so the back button closes the drawer instead of navigating. */
15
+ function useCloseOnBack(isOpen, onClose, enabled) {
16
+ const closedByPopstate = useRef(false);
17
+ useEffect(() => {
18
+ if (!enabled || !isOpen)
19
+ return;
20
+ closedByPopstate.current = false;
21
+ history.pushState({ flikDrawer: true }, "");
22
+ const handlePopstate = () => {
23
+ closedByPopstate.current = true;
24
+ onClose();
25
+ };
26
+ window.addEventListener("popstate", handlePopstate);
27
+ return () => {
28
+ window.removeEventListener("popstate", handlePopstate);
29
+ if (!closedByPopstate.current) {
30
+ history.back();
31
+ }
32
+ };
33
+ }, [isOpen, onClose, enabled]);
34
+ }
14
35
  // Create context for Drawer components
15
36
  const DrawerContext = createContext(undefined);
16
37
  const useDrawerContext = () => {
@@ -19,7 +40,9 @@ const useDrawerContext = () => {
19
40
  throw new Error("Drawer compound components must be used within <Drawer>");
20
41
  return ctx;
21
42
  };
22
- const DrawerRoot = ({ isOpen, onClose, title, subtitle, icon, position = "right", size = "md", closeOnOverlayClick = true, closeOnEsc = true, showCloseButton = true, children, className, theme: themeOverrides, scale = 0.94, ...props }) => {
43
+ const DrawerRoot = ({ isOpen, onClose, title, subtitle, icon, position = "right", size = "md", closeOnOverlayClick = true, closeOnEsc = true, showCloseButton = true, children, className, theme: themeOverrides, scale = 0.94, closeOnBack = false, ...props }) => {
44
+ // Close drawer on browser back button
45
+ useCloseOnBack(isOpen, onClose, closeOnBack);
23
46
  // iOS-style scale background effect
24
47
  useScaleBackground({ isOpen, scale, position });
25
48
  // Generate unique IDs for ARIA linkage
@@ -11,8 +11,8 @@ const drawerTheme = {
11
11
  title: "text-lg font-semibold leading-6 text-[var(--color-text-primary)]",
12
12
  subtitle: "text-base text-[var(--color-text-secondary)] mt-0.5",
13
13
  body: "flex-1 overflow-y-auto p-4",
14
- footer: "flex items-center justify-end gap-3 p-4 border-t border-[var(--color-border)] shrink-0 " +
15
- "dark:border-[var(--color-border)]",
14
+ footer: "flex items-center justify-end gap-3 p-4 py-3 border-t border-[var(--color-border)] shrink-0 " +
15
+ "",
16
16
  };
17
17
  // Position variants with margin support
18
18
  const drawerPositionVariantsWithMargin = {
@@ -62,6 +62,12 @@ export interface DrawerProps extends Omit<React.HTMLAttributes<HTMLDivElement>,
62
62
  * @default 0.94
63
63
  */
64
64
  scale?: number;
65
+ /**
66
+ * When enabled, pressing the browser back button closes the drawer
67
+ * instead of navigating away. Useful for mobile-like UX.
68
+ * @default false
69
+ */
70
+ closeOnBack?: boolean;
65
71
  }
66
72
  export interface DrawerHeaderProps extends React.HTMLAttributes<HTMLDivElement> {
67
73
  children: React.ReactNode;
@@ -5,7 +5,7 @@ export declare const Dropdown: {
5
5
  displayName: string;
6
6
  } & {
7
7
  Trigger: {
8
- ({ children, className }: import("./Dropdown.types").DropdownTriggerProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>;
8
+ ({ children, className }: import("./Dropdown.types").DropdownTriggerProps): React.ReactElement<import("./DropdownTrigger").TriggerChildProps, string | React.JSXElementConstructor<any>>;
9
9
  displayName: string;
10
10
  };
11
11
  Menu: React.ForwardRefExoticComponent<import("./Dropdown.types").DropdownMenuProps & React.RefAttributes<HTMLDivElement>>;
@@ -1,5 +1,5 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
- import { useState, useRef, useCallback } from 'react';
2
+ import { useState, useRef, useId, useCallback } from 'react';
3
3
  import { cn } from '../../../utils/cn.js';
4
4
  import { DropdownContext } from './DropdownContext.js';
5
5
  import { DropdownTrigger } from './DropdownTrigger.js';
@@ -41,6 +41,9 @@ const DropdownRoot = ({ children, className, isOpen: controlledIsOpen, defaultIs
41
41
  // Refs for positioning
42
42
  const triggerRef = useRef(null);
43
43
  const menuRef = useRef(null);
44
+ // Generate a stable menu ID for aria-controls
45
+ const generatedMenuId = useId();
46
+ const menuId = `dropdown-menu-${generatedMenuId}`;
44
47
  // Handle open state changes
45
48
  const handleOpenChange = useCallback((value) => {
46
49
  if (!isControlledOpen) {
@@ -68,6 +71,7 @@ const DropdownRoot = ({ children, className, isOpen: controlledIsOpen, defaultIs
68
71
  onOpenChange: handleOpenChange,
69
72
  triggerRef,
70
73
  menuRef,
74
+ menuId,
71
75
  placement,
72
76
  offset,
73
77
  closeOnSelect,
@@ -7,6 +7,7 @@ export interface DropdownContextValue {
7
7
  onOpenChange: (isOpen: boolean) => void;
8
8
  triggerRef: React.RefObject<HTMLElement | null>;
9
9
  menuRef: React.RefObject<HTMLDivElement | null>;
10
+ menuId: string;
10
11
  placement: DropdownPlacement;
11
12
  offset: number;
12
13
  closeOnSelect: boolean;
@@ -69,6 +69,6 @@ const DropdownItem = React__default.forwardRef(({ itemKey, children, className,
69
69
  focusStyle: theme.itemFocusStyle,
70
70
  }, ...props, children: children }));
71
71
  });
72
- DropdownItem.displayName = "DropdownItem";
72
+ DropdownItem.displayName = "Dropdown.Item";
73
73
 
74
74
  export { DropdownItem };
@@ -41,7 +41,7 @@ const useDarkMode = () => {
41
41
  * DropdownMenu component - renders the menu with keyboard navigation
42
42
  */
43
43
  const DropdownMenu = React__default.forwardRef(({ children, className, animation = true, portal = true, horizontal = false, "aria-label": ariaLabel, ...props }, ref) => {
44
- const { isOpen, onOpenChange, triggerRef, menuRef, placement, offset, theme, } = useDropdownContext();
44
+ const { isOpen, onOpenChange, triggerRef, menuRef, menuId, placement, offset, theme, } = useDropdownContext();
45
45
  // Detect dark mode for portal content
46
46
  const isDarkMode = useDarkMode();
47
47
  const isClient = useIsClient();
@@ -54,7 +54,7 @@ const DropdownMenu = React__default.forwardRef(({ children, className, animation
54
54
  const { position, cssVariables, contentRef: portalContentRef, } = useSelectPortal({
55
55
  triggerRef,
56
56
  isOpen: isOpen || false,
57
- placement: placement,
57
+ placement,
58
58
  offset: offset || 4,
59
59
  autoWidth: false,
60
60
  stickyTracking: true,
@@ -208,7 +208,7 @@ const DropdownMenu = React__default.forwardRef(({ children, className, animation
208
208
  ...cssVariables,
209
209
  top: `${position.top}px`,
210
210
  left: `${position.left}px`,
211
- }, role: "menu", "aria-label": ariaLabel || "Menu", "aria-orientation": horizontal ? "horizontal" : "vertical", tabIndex: -1, onKeyDown: handleKeyDown, variants: shouldReduceMotion || !animation ? {} : menuVariants, initial: shouldReduceMotion || !animation ? undefined : "hidden", animate: shouldReduceMotion || !animation ? undefined : "visible", exit: shouldReduceMotion || !animation ? undefined : "exit", transition: shouldReduceMotion || !animation
211
+ }, id: menuId, role: "menu", "aria-label": ariaLabel || "Menu", "aria-orientation": horizontal ? "horizontal" : "vertical", tabIndex: -1, onKeyDown: handleKeyDown, variants: shouldReduceMotion || !animation ? {} : menuVariants, initial: shouldReduceMotion || !animation ? undefined : "hidden", animate: shouldReduceMotion || !animation ? undefined : "visible", exit: shouldReduceMotion || !animation ? undefined : "exit", transition: shouldReduceMotion || !animation
212
212
  ? { duration: 0 }
213
213
  : {
214
214
  type: "spring",
@@ -221,6 +221,6 @@ const DropdownMenu = React__default.forwardRef(({ children, className, animation
221
221
  }
222
222
  return menuContent;
223
223
  });
224
- DropdownMenu.displayName = "DropdownMenu";
224
+ DropdownMenu.displayName = "Dropdown.Menu";
225
225
 
226
226
  export { DropdownMenu };
@@ -12,6 +12,6 @@ const DropdownSection = React__default.forwardRef(({ children, className, title,
12
12
  ? jsx("div", { className: theme.sectionTitleStyle, role: "presentation", children: title })
13
13
  : title), children] })] }));
14
14
  });
15
- DropdownSection.displayName = "DropdownSection";
15
+ DropdownSection.displayName = "Dropdown.Section";
16
16
 
17
17
  export { DropdownSection };
@@ -10,6 +10,6 @@ const DropdownSeparator = React__default.forwardRef(({ className, ...props }, re
10
10
  const { theme } = useDropdownContext();
11
11
  return (jsx("div", { ref: ref, role: "separator", className: cn(theme.separatorStyle, className), ...props }));
12
12
  });
13
- DropdownSeparator.displayName = "DropdownSeparator";
13
+ DropdownSeparator.displayName = "Dropdown.Separator";
14
14
 
15
15
  export { DropdownSeparator };
@@ -1,9 +1,14 @@
1
1
  import React from "react";
2
2
  import { DropdownTriggerProps } from "./Dropdown.types";
3
+ export interface TriggerChildProps {
4
+ className?: string;
5
+ onClick?: (e: React.MouseEvent) => void;
6
+ ref?: React.Ref<HTMLElement>;
7
+ }
3
8
  /**
4
9
  * DropdownTrigger component - wraps the trigger element
5
10
  */
6
11
  export declare const DropdownTrigger: {
7
- ({ children, className }: DropdownTriggerProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>;
12
+ ({ children, className }: DropdownTriggerProps): React.ReactElement<TriggerChildProps, string | React.JSXElementConstructor<any>>;
8
13
  displayName: string;
9
14
  };
@@ -6,16 +6,17 @@ import { useDropdownContext } from './DropdownContext.js';
6
6
  */
7
7
  const DropdownTrigger = ({ children, className }) => {
8
8
  var _a;
9
- const { isOpen, onOpenChange, triggerRef } = useDropdownContext();
9
+ const { isOpen, onOpenChange, triggerRef, menuId } = useDropdownContext();
10
10
  const handleClick = useCallback(() => {
11
11
  onOpenChange(!isOpen);
12
12
  }, [isOpen, onOpenChange]);
13
+ const childElement = children;
13
14
  // Clone the child element and add our props
14
- const trigger = React__default.cloneElement(children, {
15
+ const trigger = React__default.cloneElement(childElement, {
15
16
  ref: (el) => {
16
17
  triggerRef.current = el;
17
18
  // Preserve any existing ref from the child
18
- const childRef = children.ref;
19
+ const childRef = childElement.ref;
19
20
  if (typeof childRef === "function") {
20
21
  childRef(el);
21
22
  }
@@ -24,21 +25,22 @@ const DropdownTrigger = ({ children, className }) => {
24
25
  }
25
26
  },
26
27
  onClick: (e) => {
28
+ var _a;
27
29
  // Call our handler
28
30
  handleClick();
29
31
  // Preserve any existing onClick from the child
30
- const childProps = children.props;
31
- if (childProps === null || childProps === void 0 ? void 0 : childProps.onClick) {
32
- childProps.onClick(e);
32
+ if ((_a = childElement.props) === null || _a === void 0 ? void 0 : _a.onClick) {
33
+ childElement.props.onClick(e);
33
34
  }
34
35
  },
35
36
  "aria-expanded": isOpen,
36
37
  "aria-haspopup": "menu",
38
+ "aria-controls": isOpen ? menuId : undefined,
37
39
  "data-state": isOpen ? "open" : "closed",
38
- className: className || ((_a = children.props) === null || _a === void 0 ? void 0 : _a.className),
40
+ className: className || ((_a = childElement.props) === null || _a === void 0 ? void 0 : _a.className),
39
41
  });
40
42
  return trigger;
41
43
  };
42
- DropdownTrigger.displayName = "DropdownTrigger";
44
+ DropdownTrigger.displayName = "Dropdown.Trigger";
43
45
 
44
46
  export { DropdownTrigger };
@@ -2,10 +2,10 @@
2
2
  * Default theme configuration for Kbd component
3
3
  */
4
4
  const kbdTheme = {
5
- baseStyle: 'inline-flex items-center justify-center font-sans font-medium rounded-[calc(var(--radius-base)*0.75)] bg-neutral-100 border border-[var(--color-border)] text-[var(--color-text-secondary)] glass-effect',
5
+ baseStyle: 'inline-flex items-center justify-center leading-none font-sans font-medium rounded-[calc(var(--radius-base)*0.75)] bg-[var(--color-background-secondary)] border border-[var(--color-border)] text-[var(--color-text-secondary)] glass-effect',
6
6
  sizes: {
7
- sm: 'text-sm px-1 py-0.5 min-w-[1.25rem]',
8
- md: 'text-base px-1.5 py-0.5 min-w-[1.5rem]',
7
+ sm: 'text-xs px-1 min-w-5 h-5',
8
+ md: 'text-sm px-1.5 min-w-6 h-6',
9
9
  },
10
10
  separatorStyle: 'text-[var(--color-text-muted)] text-sm',
11
11
  };
@@ -4,7 +4,9 @@ import { useReducedMotion, motion } from 'motion/react';
4
4
  import { buttonTheme } from '../Button/Button.theme.js';
5
5
  import { cn } from '../../../utils/cn.js';
6
6
 
7
- const Link = React__default.forwardRef(({ children, className = "", size = "inherit", disabled = false, href, ...props }, ref) => {
7
+ const Link = React__default.forwardRef(({ children, className = "", size = "inherit", disabled = false, href,
8
+ // Destructure motion-conflicting props to avoid type issues
9
+ onAnimationStart: _onAnimationStart, onAnimationEnd: _onAnimationEnd, onDrag: _onDrag, onDragStart: _onDragStart, onDragEnd: _onDragEnd, ...props }, ref) => {
8
10
  const shouldReduceMotion = useReducedMotion();
9
11
  const color = "primary"; // Default to primary, can be overridden by className
10
12
  // A link is essentially a button with variant="link"
@@ -6,4 +6,13 @@ export declare const Message: React.ForwardRefExoticComponent<MessageProps & Rea
6
6
  Actions: React.ForwardRefExoticComponent<import("./MessageActions").MessageActionsProps & React.RefAttributes<HTMLDivElement>>;
7
7
  Timestamp: React.ForwardRefExoticComponent<import("./MessageTimestamp").MessageTimestampProps & React.RefAttributes<HTMLDivElement>>;
8
8
  List: React.ForwardRefExoticComponent<import("./MessageList.types").MessageListProps & React.RefAttributes<import("..").ScrollAreaRef>>;
9
+ Status: React.FC<import("./MessageStatusIndicator").MessageStatusIndicatorProps>;
10
+ SenderName: React.FC<import("./MessageSenderName").MessageSenderNameProps>;
11
+ File: React.FC<import("./MessageFile").MessageFileProps>;
12
+ Image: React.FC<import("./MessageImage").MessageImageProps>;
13
+ Audio: React.FC<import("./MessageAudio").MessageAudioProps>;
14
+ Link: React.FC<import("./MessageLink").MessageLinkProps>;
15
+ Reply: React.FC<import("./MessageReply").MessageReplyProps>;
16
+ Reactions: React.FC<import("./MessageReactions").MessageReactionsProps>;
17
+ DateDivider: React.FC<import("./MessageDateDivider").MessageDateDividerProps>;
9
18
  };
@@ -14,6 +14,15 @@ import { MessageActions } from './MessageActions.js';
14
14
  import { MessageTimestamp } from './MessageTimestamp.js';
15
15
  import { MessageList } from './MessageList.js';
16
16
  import { TypeWriter } from './TypeWriter.js';
17
+ import { MessageStatusIndicator } from './MessageStatusIndicator.js';
18
+ import { MessageSenderName } from './MessageSenderName.js';
19
+ import { MessageFile } from './MessageFile.js';
20
+ import { MessageImage } from './MessageImage.js';
21
+ import { MessageAudio } from './MessageAudio.js';
22
+ import { MessageLink } from './MessageLink.js';
23
+ import { MessageReply } from './MessageReply.js';
24
+ import { MessageReactions } from './MessageReactions.js';
25
+ import { MessageDateDivider } from './MessageDateDivider.js';
17
26
 
18
27
  const MessageFooter = ({ isStreaming, streamingIndicator, showTimestamp, timestamp, actions, timestampStyle, streamingIndicatorStyle, actionsContainerStyle, variant, }) => {
19
28
  if (isStreaming) {
@@ -32,7 +41,26 @@ const MessageFooter = ({ isStreaming, streamingIndicator, showTimestamp, timesta
32
41
  ? timestamp
33
42
  : timestamp.toISOString(), className: "select-none", children: formatTimestamp(timestamp) }) })), actions && jsx("div", { className: cn(actionsContainerStyle), children: actions })] }));
34
43
  };
35
- const MessageRoot = React__default.forwardRef(({ role, variant: variantProp, content, timestamp, avatar, showTimestamp = false, isStreaming = false, streamingIndicator, typingSpeed = 100, actions, onCopy, onRegenerate, showActions, className, theme: customTheme = {}, children, ...props }, ref) => {
44
+ /**
45
+ * Renders attachment sub-components based on attachment type
46
+ */
47
+ const AttachmentsList = ({ attachments, containerClassName }) => {
48
+ return (jsx("div", { className: cn(messageTheme.attachmentContainerStyle, containerClassName), children: attachments.map((attachment, index) => {
49
+ switch (attachment.type) {
50
+ case "file":
51
+ return (jsx(MessageFile, { name: attachment.name, url: attachment.url, size: attachment.size }, index));
52
+ case "image":
53
+ return (jsx(MessageImage, { src: attachment.url, thumbnailUrl: attachment.thumbnailUrl, name: attachment.name, size: attachment.size }, index));
54
+ case "audio":
55
+ return (jsx(MessageAudio, { name: attachment.name, duration: attachment.duration }, index));
56
+ case "link":
57
+ return (jsx(MessageLink, { url: attachment.url, thumbnailUrl: attachment.thumbnailUrl, title: attachment.name, description: attachment.description, domain: attachment.domain }, index));
58
+ default:
59
+ return null;
60
+ }
61
+ }) }));
62
+ };
63
+ const MessageRoot = React__default.forwardRef(({ role, variant: variantProp, content, timestamp, avatar, showTimestamp = false, isStreaming = false, streamingIndicator, typingSpeed = 100, actions, onCopy, onRegenerate, showActions, status, readAt, onRetry, attachments, reactions, onReactionClick, replyTo, sender, isGrouped, className, theme: customTheme = {}, children, ...props }, ref) => {
36
64
  var _a, _b, _c, _d, _e, _f, _g, _h;
37
65
  // Determine the variant: role takes precedence over variant prop
38
66
  let variant;
@@ -57,7 +85,9 @@ const MessageRoot = React__default.forwardRef(({ role, variant: variantProp, con
57
85
  variant,
58
86
  isStreaming,
59
87
  typingSpeed,
60
- }), [role, variant, isStreaming, typingSpeed]);
88
+ status,
89
+ isGrouped,
90
+ }), [role, variant, isStreaming, typingSpeed, status, isGrouped]);
61
91
  const messageContent = content;
62
92
  // Determine if we should show default actions
63
93
  const shouldShowDefaultActions = showActions !== false &&
@@ -100,7 +130,9 @@ const MessageRoot = React__default.forwardRef(({ role, variant: variantProp, con
100
130
  if (variant === "system") {
101
131
  return (jsx("div", { ref: ref, className: cn("w-full max-w-full", className), "data-variant": "system", "data-role": role, ...props, children: jsxs("div", { className: containerStyle, children: [jsx("div", { className: bubbleStyle, children: typeof renderedContent === "string" ? (jsx("p", { className: "text-base", children: renderedContent })) : (renderedContent) }), jsx(MessageFooter, { isStreaming: isStreaming, streamingIndicator: streamingIndicator, showTimestamp: showTimestamp, timestamp: timestamp, actions: undefined, timestampStyle: timestampStyle, streamingIndicatorStyle: cn(messageTheme.streamingIndicatorStyle, customTheme.streamingIndicatorStyle), actionsContainerStyle: undefined, variant: "system" })] }) }));
102
132
  }
103
- return (jsx("div", { ref: ref, className: cn("w-full max-w-full group", className), "data-variant": variant, "data-role": role, ...props, children: jsxs("div", { className: containerStyle, children: [avatar && (jsx("div", { className: "flex-shrink-0", children: jsx(Avatar, { src: avatar.src, name: avatar.name, fallback: avatar.fallback, size: "xs" }) })), jsxs("div", { className: cn("flex flex-col", variant === "sender" ? "items-end" : "items-start"), children: [jsx("div", { className: bubbleStyle, children: typeof renderedContent === "string" ? (jsx("p", { className: "break-words", children: renderedContent })) : (renderedContent) }), jsx(MessageFooter, { isStreaming: isStreaming, streamingIndicator: streamingIndicator, showTimestamp: showTimestamp, timestamp: timestamp, actions: finalActions, timestampStyle: timestampStyle, streamingIndicatorStyle: cn(messageTheme.streamingIndicatorStyle, customTheme.streamingIndicatorStyle), actionsContainerStyle: cn(messageTheme.actionsContainerStyle, customTheme.actionsContainerStyle), variant: variant })] })] }) }));
133
+ const showAvatar = avatar && !isGrouped;
134
+ const showSenderName = (sender === null || sender === void 0 ? void 0 : sender.name) && variant === "receiver" && !isGrouped;
135
+ return (jsxs("div", { ref: ref, className: cn("w-full max-w-full group", className), "data-variant": variant, "data-role": role, ...props, children: [jsxs("div", { className: containerStyle, children: [showAvatar ? (jsx("div", { className: "flex-shrink-0", children: jsx(Avatar, { src: avatar.src, name: avatar.name, fallback: avatar.fallback, size: "xs" }) })) : isGrouped && avatar ? (jsx("div", { className: "flex-shrink-0 size-8" })) : null, jsxs("div", { className: cn("flex flex-col", variant === "sender" ? "items-end" : "items-start"), children: [showSenderName && jsx(MessageSenderName, { name: sender.name }), jsxs("div", { className: bubbleStyle, children: [replyTo && (jsx(MessageReply, { name: replyTo.name, content: replyTo.content, avatar: replyTo.avatar })), typeof renderedContent === "string" ? (jsx("p", { className: "break-words", children: renderedContent })) : (renderedContent), attachments && attachments.length > 0 && (jsx(AttachmentsList, { attachments: attachments, containerClassName: customTheme.attachmentContainerStyle }))] }), jsx(MessageFooter, { isStreaming: isStreaming, streamingIndicator: streamingIndicator, showTimestamp: showTimestamp, timestamp: timestamp, actions: finalActions, timestampStyle: timestampStyle, streamingIndicatorStyle: cn(messageTheme.streamingIndicatorStyle, customTheme.streamingIndicatorStyle), actionsContainerStyle: cn(messageTheme.actionsContainerStyle, customTheme.actionsContainerStyle), variant: variant }), status && variant === "sender" && (jsx(MessageStatusIndicator, { status: status, readAt: readAt, onRetry: onRetry, className: cn(variant === "sender" ? "self-end mr-1" : "self-start ml-1", customTheme.statusStyle) }))] })] }), reactions && reactions.length > 0 && (jsx("div", { className: cn("mt-0.5", avatar && !isGrouped ? "ml-11" : "", variant === "sender" ? "flex justify-end mr-1" : ""), children: jsx(MessageReactions, { reactions: reactions, onReactionClick: onReactionClick, className: customTheme.reactionsContainerStyle }) }))] }));
104
136
  });
105
137
  MessageRoot.displayName = "Message";
106
138
  // Attach compound components
@@ -110,6 +142,15 @@ const Message = Object.assign(MessageRoot, {
110
142
  Actions: MessageActions,
111
143
  Timestamp: MessageTimestamp,
112
144
  List: MessageList,
145
+ Status: MessageStatusIndicator,
146
+ SenderName: MessageSenderName,
147
+ File: MessageFile,
148
+ Image: MessageImage,
149
+ Audio: MessageAudio,
150
+ Link: MessageLink,
151
+ Reply: MessageReply,
152
+ Reactions: MessageReactions,
153
+ DateDivider: MessageDateDivider,
113
154
  });
114
155
 
115
156
  export { Message };
@@ -39,6 +39,28 @@ const messageTheme = {
39
39
  streamingIndicatorStyle: "flex items-center gap-1 text-[var(--color-text-placeholder)] text-sm " +
40
40
  "dark:text-[var(--color-neutral-500)]",
41
41
  actionsContainerStyle: "flex items-start gap-3",
42
+ // Status styles
43
+ statusStyle: "flex items-center gap-1 text-xs mt-1",
44
+ statusSending: "text-[var(--color-text-placeholder)] animate-pulse",
45
+ statusSent: "text-[var(--color-text-placeholder)]",
46
+ statusDelivered: "text-[var(--color-text-placeholder)]",
47
+ statusRead: "text-[var(--color-primary)]",
48
+ statusFailed: "text-[var(--color-danger)]",
49
+ // Attachment styles
50
+ attachmentContainerStyle: "flex flex-col gap-2 mt-2",
51
+ fileStyle: "flex items-center gap-3 rounded-lg border border-[var(--color-border)] bg-[var(--color-background-secondary)] px-3 py-2.5 text-sm",
52
+ imageStyle: "rounded-lg overflow-hidden max-w-xs",
53
+ audioStyle: "flex items-center gap-3 rounded-lg border border-[var(--color-border)] bg-[var(--color-background-secondary)] px-3 py-2.5 text-sm",
54
+ linkStyle: "flex flex-col rounded-lg border border-[var(--color-border)] overflow-hidden text-sm max-w-xs",
55
+ // Reactions styles
56
+ reactionsContainerStyle: "flex flex-wrap items-center gap-1.5 mt-1.5",
57
+ reactionPillStyle: "inline-flex items-center gap-1 rounded-full border border-[var(--color-border)] bg-[var(--color-background-secondary)] px-2 py-0.5 text-xs cursor-pointer transition-colors hover:bg-[var(--color-background-tertiary)]",
58
+ reactionPillActiveStyle: "border-[var(--color-primary-200)] bg-[var(--color-primary-50)] text-[var(--color-primary)]",
59
+ // Reply/quote styles
60
+ replyStyle: "border-l-2 border-[var(--color-border)] pl-2.5 mb-2 text-xs text-[var(--color-text-muted)]",
61
+ // Grouping styles
62
+ dateDividerStyle: "flex items-center gap-3 text-xs text-[var(--color-text-muted)] select-none",
63
+ senderNameStyle: "text-xs font-medium text-[var(--color-text-secondary)] mb-1 pl-1",
42
64
  };
43
65
 
44
66
  export { messageTheme };