@borisj74/bv-ds 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (310) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +94 -0
  3. package/dist/index.cjs +33885 -0
  4. package/dist/index.d.cts +2715 -0
  5. package/dist/index.d.ts +2715 -0
  6. package/dist/index.js +33717 -0
  7. package/package.json +67 -0
  8. package/src/components/ActivityFeed/ActivityFeed.tsx +48 -0
  9. package/src/components/ActivityFeed/index.ts +2 -0
  10. package/src/components/ActivityGauge/ActivityGauge.tsx +155 -0
  11. package/src/components/ActivityGauge/index.ts +7 -0
  12. package/src/components/AdvancedFilterBar/AdvancedFilterBar.tsx +80 -0
  13. package/src/components/AdvancedFilterBar/index.ts +2 -0
  14. package/src/components/Alert/Alert.tsx +210 -0
  15. package/src/components/Alert/index.ts +2 -0
  16. package/src/components/Avatar/Avatar.tsx +111 -0
  17. package/src/components/Avatar/index.ts +2 -0
  18. package/src/components/AvatarAddButton/AvatarAddButton.tsx +65 -0
  19. package/src/components/AvatarAddButton/index.ts +5 -0
  20. package/src/components/AvatarGroup/AvatarGroup.tsx +79 -0
  21. package/src/components/AvatarGroup/index.ts +6 -0
  22. package/src/components/AvatarLabelGroup/AvatarLabelGroup.tsx +62 -0
  23. package/src/components/AvatarLabelGroup/index.ts +5 -0
  24. package/src/components/AvatarProfilePhoto/AvatarProfilePhoto.tsx +117 -0
  25. package/src/components/AvatarProfilePhoto/index.ts +5 -0
  26. package/src/components/Badge/ColorBadge.tsx +36 -0
  27. package/src/components/Badge/ModernBadge.tsx +38 -0
  28. package/src/components/Badge/PillBadge.tsx +36 -0
  29. package/src/components/Badge/badgeShared.tsx +139 -0
  30. package/src/components/Badge/index.ts +7 -0
  31. package/src/components/BadgeCloseX/BadgeCloseX.tsx +64 -0
  32. package/src/components/BadgeCloseX/index.ts +2 -0
  33. package/src/components/BadgeGroup/BadgeGroup.tsx +61 -0
  34. package/src/components/BadgeGroup/index.ts +7 -0
  35. package/src/components/BreadcrumbButtonBase/BreadcrumbButtonBase.tsx +75 -0
  36. package/src/components/BreadcrumbButtonBase/index.ts +5 -0
  37. package/src/components/Breadcrumbs/Breadcrumbs.tsx +62 -0
  38. package/src/components/Breadcrumbs/index.ts +2 -0
  39. package/src/components/Button/Button.tsx +71 -0
  40. package/src/components/Button/index.ts +2 -0
  41. package/src/components/ButtonCloseX/ButtonCloseX.tsx +54 -0
  42. package/src/components/ButtonCloseX/index.ts +2 -0
  43. package/src/components/ButtonDestructive/ButtonDestructive.tsx +67 -0
  44. package/src/components/ButtonDestructive/index.ts +6 -0
  45. package/src/components/ButtonGroup/ButtonGroup.tsx +28 -0
  46. package/src/components/ButtonGroup/index.ts +2 -0
  47. package/src/components/ButtonGroupSegment/ButtonGroupSegment.tsx +54 -0
  48. package/src/components/ButtonGroupSegment/index.ts +5 -0
  49. package/src/components/ButtonUtility/ButtonUtility.tsx +67 -0
  50. package/src/components/ButtonUtility/index.ts +6 -0
  51. package/src/components/CalendarCell/CalendarCell.tsx +82 -0
  52. package/src/components/CalendarCell/index.ts +2 -0
  53. package/src/components/CalendarCellDayWeekView/CalendarCellDayWeekView.tsx +56 -0
  54. package/src/components/CalendarCellDayWeekView/index.ts +2 -0
  55. package/src/components/CalendarColumnHeader/CalendarColumnHeader.tsx +45 -0
  56. package/src/components/CalendarColumnHeader/index.ts +5 -0
  57. package/src/components/CalendarDateIcon/CalendarDateIcon.tsx +25 -0
  58. package/src/components/CalendarDateIcon/index.ts +2 -0
  59. package/src/components/CalendarEvent/CalendarEvent.tsx +76 -0
  60. package/src/components/CalendarEvent/index.ts +2 -0
  61. package/src/components/CalendarEventDayWeekView/CalendarEventDayWeekView.tsx +76 -0
  62. package/src/components/CalendarEventDayWeekView/index.ts +2 -0
  63. package/src/components/CalendarHeader/CalendarHeader.tsx +47 -0
  64. package/src/components/CalendarHeader/index.ts +2 -0
  65. package/src/components/CalendarRowLabel/CalendarRowLabel.tsx +21 -0
  66. package/src/components/CalendarRowLabel/index.ts +2 -0
  67. package/src/components/CalendarTimemarker/CalendarTimemarker.tsx +46 -0
  68. package/src/components/CalendarTimemarker/index.ts +5 -0
  69. package/src/components/CalendarViewDropdown/CalendarViewDropdown.tsx +101 -0
  70. package/src/components/CalendarViewDropdown/index.ts +6 -0
  71. package/src/components/CardHeader/CardHeader.tsx +57 -0
  72. package/src/components/CardHeader/index.ts +2 -0
  73. package/src/components/CarouselArrow/CarouselArrow.tsx +47 -0
  74. package/src/components/CarouselArrow/index.ts +6 -0
  75. package/src/components/CarouselImage/CarouselImage.tsx +60 -0
  76. package/src/components/CarouselImage/index.ts +2 -0
  77. package/src/components/Change/Change.tsx +73 -0
  78. package/src/components/Change/index.ts +2 -0
  79. package/src/components/ChartLegend/ChartLegend.tsx +38 -0
  80. package/src/components/ChartLegend/index.ts +2 -0
  81. package/src/components/ChartMarker/ChartMarker.tsx +54 -0
  82. package/src/components/ChartMarker/index.ts +2 -0
  83. package/src/components/ChartMini/ChartMini.tsx +86 -0
  84. package/src/components/ChartMini/index.ts +2 -0
  85. package/src/components/ChartTooltip/ChartTooltip.tsx +44 -0
  86. package/src/components/ChartTooltip/index.ts +2 -0
  87. package/src/components/Checkbox/Checkbox.tsx +65 -0
  88. package/src/components/Checkbox/checkboxBase.tsx +81 -0
  89. package/src/components/Checkbox/index.ts +3 -0
  90. package/src/components/CodeSnippet/CodeSnippet.tsx +94 -0
  91. package/src/components/CodeSnippet/index.ts +2 -0
  92. package/src/components/CodeSnippetTabs/CodeSnippetTabs.tsx +44 -0
  93. package/src/components/CodeSnippetTabs/index.ts +2 -0
  94. package/src/components/CommandBar/CommandBar.tsx +80 -0
  95. package/src/components/CommandBar/index.ts +2 -0
  96. package/src/components/CommandBarFooter/CommandBarFooter.tsx +125 -0
  97. package/src/components/CommandBarFooter/index.ts +5 -0
  98. package/src/components/CommandBarMenuSection/CommandBarMenuSection.tsx +28 -0
  99. package/src/components/CommandBarMenuSection/index.ts +2 -0
  100. package/src/components/CommandBarNavigationIcon/CommandBarNavigationIcon.tsx +47 -0
  101. package/src/components/CommandBarNavigationIcon/index.ts +2 -0
  102. package/src/components/CommandDropdownMenuItem/CommandDropdownMenuItem.tsx +51 -0
  103. package/src/components/CommandDropdownMenuItem/index.ts +2 -0
  104. package/src/components/CommandInput/CommandInput.tsx +74 -0
  105. package/src/components/CommandInput/index.ts +2 -0
  106. package/src/components/CommandShortcut/CommandShortcut.tsx +26 -0
  107. package/src/components/CommandShortcut/index.ts +2 -0
  108. package/src/components/ContentDivider/ContentDivider.tsx +80 -0
  109. package/src/components/ContentDivider/index.ts +6 -0
  110. package/src/components/ContentFeatureText/ContentFeatureText.tsx +60 -0
  111. package/src/components/ContentFeatureText/index.ts +5 -0
  112. package/src/components/ContentHeading/ContentHeading.tsx +43 -0
  113. package/src/components/ContentHeading/index.ts +5 -0
  114. package/src/components/ContentParagraph/ContentParagraph.tsx +39 -0
  115. package/src/components/ContentParagraph/index.ts +5 -0
  116. package/src/components/ContentQuote/ContentQuote.tsx +114 -0
  117. package/src/components/ContentQuote/index.ts +6 -0
  118. package/src/components/ContentRule/ContentRule.tsx +31 -0
  119. package/src/components/ContentRule/index.ts +2 -0
  120. package/src/components/ContextMenu/ContextMenu.tsx +67 -0
  121. package/src/components/ContextMenu/index.ts +7 -0
  122. package/src/components/ContextMenu/useContextMenu.ts +41 -0
  123. package/src/components/DatePickerCell/DatePickerCell.tsx +77 -0
  124. package/src/components/DatePickerCell/index.ts +2 -0
  125. package/src/components/DatePickerListItem/DatePickerListItem.tsx +39 -0
  126. package/src/components/DatePickerListItem/index.ts +2 -0
  127. package/src/components/DatePickerMenu/DatePickerMenu.tsx +131 -0
  128. package/src/components/DatePickerMenu/index.ts +2 -0
  129. package/src/components/DropdownAccountListItem/DropdownAccountListItem.tsx +69 -0
  130. package/src/components/DropdownAccountListItem/index.ts +2 -0
  131. package/src/components/DropdownMenuFooter/DropdownMenuFooter.tsx +50 -0
  132. package/src/components/DropdownMenuFooter/index.ts +5 -0
  133. package/src/components/DropdownMenuHeader/DropdownMenuHeader.tsx +93 -0
  134. package/src/components/DropdownMenuHeader/index.ts +5 -0
  135. package/src/components/DropdownMenuItemInsetIcon/DropdownMenuItemInsetIcon.tsx +89 -0
  136. package/src/components/DropdownMenuItemInsetIcon/index.ts +5 -0
  137. package/src/components/DropdownMenuListItem/DropdownMenuListItem.tsx +84 -0
  138. package/src/components/DropdownMenuListItem/index.ts +2 -0
  139. package/src/components/EmptyState/EmptyState.tsx +65 -0
  140. package/src/components/EmptyState/index.ts +2 -0
  141. package/src/components/FeedItemBase/FeedItemBase.tsx +135 -0
  142. package/src/components/FeedItemBase/index.ts +2 -0
  143. package/src/components/FileUpload/FileUpload.tsx +112 -0
  144. package/src/components/FileUpload/index.ts +2 -0
  145. package/src/components/FileUploadBase/FileUploadBase.tsx +69 -0
  146. package/src/components/FileUploadBase/index.ts +2 -0
  147. package/src/components/FileUploadItemBase/FileUploadItemBase.tsx +190 -0
  148. package/src/components/FileUploadItemBase/index.ts +7 -0
  149. package/src/components/FilterBar/FilterBar.tsx +62 -0
  150. package/src/components/FilterBar/index.ts +2 -0
  151. package/src/components/FilterTabs/FilterTabs.tsx +41 -0
  152. package/src/components/FilterTabs/index.ts +2 -0
  153. package/src/components/FiltersDropdownMenu/FiltersDropdownMenu.tsx +104 -0
  154. package/src/components/FiltersDropdownMenu/index.ts +2 -0
  155. package/src/components/FiltersSlideoutMenu/FiltersSlideoutMenu.tsx +71 -0
  156. package/src/components/FiltersSlideoutMenu/index.ts +2 -0
  157. package/src/components/HeaderNavigation/HeaderNavigation.tsx +178 -0
  158. package/src/components/HeaderNavigation/index.ts +6 -0
  159. package/src/components/HelpIcon/HelpIcon.tsx +49 -0
  160. package/src/components/HelpIcon/index.ts +2 -0
  161. package/src/components/InputField/InputField.tsx +108 -0
  162. package/src/components/InputField/index.ts +3 -0
  163. package/src/components/InputField/inputFieldShared.tsx +68 -0
  164. package/src/components/LeadingInputField/LeadingInputField.tsx +60 -0
  165. package/src/components/LeadingInputField/index.ts +2 -0
  166. package/src/components/LineAndBarChart/LineAndBarChart.tsx +96 -0
  167. package/src/components/LineAndBarChart/index.ts +2 -0
  168. package/src/components/LinkMessage/LinkMessage.tsx +52 -0
  169. package/src/components/LinkMessage/index.ts +2 -0
  170. package/src/components/LoadingIndicator/LoadingIndicator.tsx +108 -0
  171. package/src/components/LoadingIndicator/index.ts +6 -0
  172. package/src/components/MediaMessage/MediaMessage.tsx +109 -0
  173. package/src/components/MediaMessage/index.ts +2 -0
  174. package/src/components/MegaInputFieldBase/MegaInputFieldBase.tsx +49 -0
  175. package/src/components/MegaInputFieldBase/index.ts +5 -0
  176. package/src/components/Message/Message.tsx +85 -0
  177. package/src/components/Message/index.ts +3 -0
  178. package/src/components/Message/messageShared.tsx +73 -0
  179. package/src/components/MessageAction/MessageAction.tsx +221 -0
  180. package/src/components/MessageAction/index.ts +2 -0
  181. package/src/components/MessageActionButton/MessageActionButton.tsx +36 -0
  182. package/src/components/MessageActionButton/index.ts +2 -0
  183. package/src/components/MessageActionPanel/MessageActionPanel.tsx +36 -0
  184. package/src/components/MessageActionPanel/index.ts +2 -0
  185. package/src/components/MessageReaction/MessageReaction.tsx +37 -0
  186. package/src/components/MessageReaction/index.ts +2 -0
  187. package/src/components/MessageStatusIcon/MessageStatusIcon.tsx +54 -0
  188. package/src/components/MessageStatusIcon/index.ts +2 -0
  189. package/src/components/MetricItem/MetricItem.tsx +147 -0
  190. package/src/components/MetricItem/index.ts +2 -0
  191. package/src/components/ModalActions/ModalActions.tsx +57 -0
  192. package/src/components/ModalActions/index.ts +2 -0
  193. package/src/components/ModalHeader/ModalHeader.tsx +99 -0
  194. package/src/components/ModalHeader/index.ts +2 -0
  195. package/src/components/MultiSelect/MultiSelect.tsx +118 -0
  196. package/src/components/MultiSelect/index.ts +2 -0
  197. package/src/components/NavAccountCard/NavAccountCard.tsx +124 -0
  198. package/src/components/NavAccountCard/index.ts +2 -0
  199. package/src/components/NavAccountCardMenuItem/NavAccountCardMenuItem.tsx +101 -0
  200. package/src/components/NavAccountCardMenuItem/index.ts +5 -0
  201. package/src/components/NavButton/NavButton.tsx +50 -0
  202. package/src/components/NavButton/index.ts +2 -0
  203. package/src/components/NavFeaturedCard/NavFeaturedCard.tsx +82 -0
  204. package/src/components/NavFeaturedCard/index.ts +2 -0
  205. package/src/components/NavItemBase/NavItemBase.tsx +79 -0
  206. package/src/components/NavItemBase/index.ts +2 -0
  207. package/src/components/NavItemDropdownBase/NavItemDropdownBase.tsx +74 -0
  208. package/src/components/NavItemDropdownBase/index.ts +2 -0
  209. package/src/components/NavMenuButton/NavMenuButton.tsx +47 -0
  210. package/src/components/NavMenuButton/index.ts +2 -0
  211. package/src/components/Notification/Notification.tsx +102 -0
  212. package/src/components/Notification/index.ts +2 -0
  213. package/src/components/NumberInput/NumberInput.tsx +114 -0
  214. package/src/components/NumberInput/index.ts +2 -0
  215. package/src/components/PageHeader/PageHeader.tsx +88 -0
  216. package/src/components/PageHeader/index.ts +2 -0
  217. package/src/components/Pagination/Pagination.tsx +124 -0
  218. package/src/components/Pagination/index.ts +2 -0
  219. package/src/components/PaginationButtonGroupBase/PaginationButtonGroupBase.tsx +69 -0
  220. package/src/components/PaginationButtonGroupBase/index.ts +5 -0
  221. package/src/components/PaginationCards/PaginationCards.tsx +72 -0
  222. package/src/components/PaginationCards/index.ts +2 -0
  223. package/src/components/PaginationDotGroup/PaginationDotGroup.tsx +66 -0
  224. package/src/components/PaginationDotGroup/index.ts +2 -0
  225. package/src/components/PaginationDotIndicator/PaginationDotIndicator.tsx +39 -0
  226. package/src/components/PaginationDotIndicator/index.ts +6 -0
  227. package/src/components/PaginationNumberBase/PaginationNumberBase.tsx +42 -0
  228. package/src/components/PaginationNumberBase/index.ts +5 -0
  229. package/src/components/PieChart/PieChart.tsx +73 -0
  230. package/src/components/PieChart/index.ts +2 -0
  231. package/src/components/ProgressBar/ProgressBar.tsx +75 -0
  232. package/src/components/ProgressBar/index.ts +2 -0
  233. package/src/components/ProgressCircle/ProgressCircle.tsx +89 -0
  234. package/src/components/ProgressCircle/index.ts +6 -0
  235. package/src/components/RadarChart/RadarChart.tsx +62 -0
  236. package/src/components/RadarChart/index.ts +2 -0
  237. package/src/components/Radio/Radio.tsx +55 -0
  238. package/src/components/Radio/index.ts +2 -0
  239. package/src/components/RadioGroup/RadioGroup.tsx +54 -0
  240. package/src/components/RadioGroup/index.ts +2 -0
  241. package/src/components/RadioGroupItem/RadioGroupItem.tsx +118 -0
  242. package/src/components/RadioGroupItem/index.ts +6 -0
  243. package/src/components/SectionFooter/SectionFooter.tsx +40 -0
  244. package/src/components/SectionFooter/index.ts +2 -0
  245. package/src/components/SectionHeader/SectionHeader.tsx +44 -0
  246. package/src/components/SectionHeader/index.ts +2 -0
  247. package/src/components/SectionLabel/SectionLabel.tsx +51 -0
  248. package/src/components/SectionLabel/index.ts +2 -0
  249. package/src/components/Select/Select.tsx +121 -0
  250. package/src/components/Select/index.ts +2 -0
  251. package/src/components/SelectMenuItem/SelectMenuItem.tsx +85 -0
  252. package/src/components/SelectMenuItem/index.ts +2 -0
  253. package/src/components/SidebarNavigation/SidebarNavigation.tsx +100 -0
  254. package/src/components/SidebarNavigation/index.ts +2 -0
  255. package/src/components/SlideOutMenuHeader/SlideOutMenuHeader.tsx +56 -0
  256. package/src/components/SlideOutMenuHeader/index.ts +2 -0
  257. package/src/components/Slider/Slider.tsx +125 -0
  258. package/src/components/Slider/index.ts +2 -0
  259. package/src/components/SocialButton/SocialButton.tsx +88 -0
  260. package/src/components/SocialButton/index.ts +2 -0
  261. package/src/components/StatusIcon/StatusIcon.tsx +75 -0
  262. package/src/components/StatusIcon/index.ts +2 -0
  263. package/src/components/StepBase/StepBase.tsx +90 -0
  264. package/src/components/StepBase/index.ts +2 -0
  265. package/src/components/StepIconBase/StepIconBase.tsx +65 -0
  266. package/src/components/StepIconBase/index.ts +7 -0
  267. package/src/components/TabButtonBase/TabButtonBase.tsx +88 -0
  268. package/src/components/TabButtonBase/index.ts +2 -0
  269. package/src/components/TableCell/TableCell.tsx +44 -0
  270. package/src/components/TableCell/index.ts +2 -0
  271. package/src/components/TableHeaderCell/TableHeaderCell.tsx +34 -0
  272. package/src/components/TableHeaderCell/index.ts +2 -0
  273. package/src/components/TableHeaderLabel/TableHeaderLabel.tsx +37 -0
  274. package/src/components/TableHeaderLabel/index.ts +2 -0
  275. package/src/components/Tabs/Tabs.tsx +80 -0
  276. package/src/components/Tabs/index.ts +2 -0
  277. package/src/components/Tag/Tag.tsx +91 -0
  278. package/src/components/Tag/index.ts +2 -0
  279. package/src/components/TagsInputField/TagsInputField.tsx +90 -0
  280. package/src/components/TagsInputField/index.ts +2 -0
  281. package/src/components/TextEditorToolbar/TextEditorToolbar.tsx +33 -0
  282. package/src/components/TextEditorToolbar/index.ts +2 -0
  283. package/src/components/TextEditorTooltip/TextEditorTooltip.tsx +28 -0
  284. package/src/components/TextEditorTooltip/index.ts +2 -0
  285. package/src/components/TextareaInputField/TextareaInputField.tsx +45 -0
  286. package/src/components/TextareaInputField/index.ts +2 -0
  287. package/src/components/Toggle/Toggle.tsx +87 -0
  288. package/src/components/Toggle/index.ts +2 -0
  289. package/src/components/Tooltip/Tooltip.tsx +59 -0
  290. package/src/components/Tooltip/index.ts +2 -0
  291. package/src/components/TrailingInputField/TrailingInputField.tsx +62 -0
  292. package/src/components/TrailingInputField/index.ts +2 -0
  293. package/src/components/TreeView/TreeView.tsx +86 -0
  294. package/src/components/TreeView/index.ts +2 -0
  295. package/src/components/TreeViewConnector/TreeViewConnector.tsx +36 -0
  296. package/src/components/TreeViewConnector/index.ts +2 -0
  297. package/src/components/TreeViewItem/TreeViewItem.tsx +111 -0
  298. package/src/components/TreeViewItem/index.ts +2 -0
  299. package/src/components/VerificationCodeInput/VerificationCodeInput.tsx +114 -0
  300. package/src/components/VerificationCodeInput/index.ts +2 -0
  301. package/src/illustrations/BoxIllustration.tsx +13 -0
  302. package/src/illustrations/CloudIllustration.tsx +18 -0
  303. package/src/illustrations/CreditCardIllustration.tsx +13 -0
  304. package/src/illustrations/DocumentsIllustration.tsx +13 -0
  305. package/src/illustrations/index.ts +4 -0
  306. package/src/index.ts +147 -0
  307. package/src/internal/chartTheme.ts +30 -0
  308. package/src/internal/ringBase.tsx +82 -0
  309. package/src/styles.css +3 -0
  310. package/tailwind-preset.js +295 -0
@@ -0,0 +1,108 @@
1
+ import type { ReactNode } from "react";
2
+ import clsx from "clsx";
3
+
4
+ export type LoadingIndicatorStyle = "line-simple" | "line-spinner" | "dot-circle";
5
+ export type LoadingIndicatorSize = "sm" | "md" | "lg" | "xl";
6
+
7
+ export interface LoadingIndicatorProps {
8
+ /** Spinner style. */
9
+ variant?: LoadingIndicatorStyle;
10
+ /** Size scale. md = 48px (verified); sm/lg/xl inferred. */
11
+ size?: LoadingIndicatorSize;
12
+ /** Optional supporting text below the spinner (e.g. "Loading..."). */
13
+ label?: ReactNode;
14
+ className?: string;
15
+ }
16
+
17
+ // md = 48px verified from Figma; sm/lg/xl inferred from the size ramp.
18
+ const sizePx: Record<LoadingIndicatorSize, number> = { sm: 32, md: 48, lg: 64, xl: 80 };
19
+ const borderPx: Record<LoadingIndicatorSize, number> = { sm: 3, md: 4, lg: 5, xl: 6 };
20
+
21
+ function DotCircle({ px }: { px: number }) {
22
+ const dot = Math.max(3, Math.round(px / 8));
23
+ return (
24
+ <span
25
+ className="relative inline-block animate-spin"
26
+ style={{ width: px, height: px, animationDuration: "1.2s" }}
27
+ >
28
+ {Array.from({ length: 12 }).map((_, i) => (
29
+ <span
30
+ key={i}
31
+ className="absolute left-1/2 top-0 rounded-full bg-fg-brand-primary"
32
+ style={{
33
+ width: dot,
34
+ height: dot,
35
+ marginLeft: -dot / 2,
36
+ transformOrigin: `${dot / 2}px ${px / 2}px`,
37
+ transform: `rotate(${i * 30}deg)`,
38
+ opacity: (i + 1) / 12,
39
+ }}
40
+ />
41
+ ))}
42
+ </span>
43
+ );
44
+ }
45
+
46
+ /**
47
+ * Spinner / loading indicator. `line-simple` and `line-spinner` are stroked
48
+ * rings (spinner uses a round cap); `dot-circle` is a ring of fading dots.
49
+ * Rendered with CSS animation rather than the Figma image asset.
50
+ */
51
+ export function LoadingIndicator({
52
+ variant = "line-simple",
53
+ size = "md",
54
+ label,
55
+ className,
56
+ }: LoadingIndicatorProps) {
57
+ const px = sizePx[size];
58
+
59
+ let spinner: ReactNode;
60
+ if (variant === "dot-circle") {
61
+ spinner = <DotCircle px={px} />;
62
+ } else {
63
+ const stroke = borderPx[size];
64
+ const r = (px - stroke) / 2;
65
+ const c = 2 * Math.PI * r;
66
+ spinner = (
67
+ <svg
68
+ className="animate-spin"
69
+ style={{ width: px, height: px, animationDuration: "0.9s" }}
70
+ viewBox={`0 0 ${px} ${px}`}
71
+ role="presentation"
72
+ >
73
+ <circle
74
+ cx={px / 2}
75
+ cy={px / 2}
76
+ r={r}
77
+ fill="none"
78
+ className="stroke-bg-quaternary"
79
+ strokeWidth={stroke}
80
+ />
81
+ <circle
82
+ cx={px / 2}
83
+ cy={px / 2}
84
+ r={r}
85
+ fill="none"
86
+ className="stroke-fg-brand-primary"
87
+ strokeWidth={stroke}
88
+ strokeDasharray={c}
89
+ strokeDashoffset={c * 0.75}
90
+ strokeLinecap={variant === "line-spinner" ? "round" : "butt"}
91
+ />
92
+ </svg>
93
+ );
94
+ }
95
+
96
+ return (
97
+ <div
98
+ role="status"
99
+ aria-live="polite"
100
+ className={clsx("inline-flex flex-col items-center gap-xl font-body", className)}
101
+ >
102
+ {spinner}
103
+ {label ? (
104
+ <span className="text-sm font-medium text-text-secondary">{label}</span>
105
+ ) : null}
106
+ </div>
107
+ );
108
+ }
@@ -0,0 +1,6 @@
1
+ export { LoadingIndicator } from "./LoadingIndicator";
2
+ export type {
3
+ LoadingIndicatorProps,
4
+ LoadingIndicatorStyle,
5
+ LoadingIndicatorSize,
6
+ } from "./LoadingIndicator";
@@ -0,0 +1,109 @@
1
+ import type { ReactNode } from "react";
2
+ import clsx from "clsx";
3
+ import { MessageShell, bubbleClasses } from "../Message/messageShared";
4
+
5
+ export type MediaMessageType = "file" | "audio" | "video" | "image";
6
+
7
+ export interface MediaMessageProps {
8
+ /** Attachment kind. */
9
+ type?: MediaMessageType;
10
+ /** File name (file/audio/video). */
11
+ fileName?: ReactNode;
12
+ /** Supporting line — size / duration. */
13
+ meta?: ReactNode;
14
+ /** Short extension label for the file-type icon (file type). */
15
+ fileExt?: string;
16
+ /** Image/video poster source. */
17
+ src?: string;
18
+ author?: ReactNode;
19
+ time?: ReactNode;
20
+ avatar?: ReactNode;
21
+ sent?: boolean;
22
+ reactions?: ReactNode;
23
+ className?: string;
24
+ }
25
+
26
+ function FileTypeIcon({ ext }: { ext: string }) {
27
+ return (
28
+ <span className="relative flex h-10 w-8 shrink-0 items-end justify-center rounded-[2px] border border-border-secondary bg-bg-primary">
29
+ <span className="mb-1 rounded-[2px] bg-utility-brand-600 px-1 py-[2px] text-[10px] font-bold text-text-white">
30
+ {ext}
31
+ </span>
32
+ </span>
33
+ );
34
+ }
35
+
36
+ function PlayButton() {
37
+ return (
38
+ <span className="flex size-10 shrink-0 items-center justify-center rounded-full bg-bg-brand-solid text-text-white">
39
+ <svg viewBox="0 0 16 16" fill="currentColor" className="size-4" aria-hidden>
40
+ <path d="M4 2.5v11l9-5.5-9-5.5Z" />
41
+ </svg>
42
+ </span>
43
+ );
44
+ }
45
+
46
+ /** A chat message carrying an attachment — file, audio, video, or image. */
47
+ export function MediaMessage({
48
+ type = "file",
49
+ fileName,
50
+ meta,
51
+ fileExt = "JPG",
52
+ src,
53
+ author,
54
+ time,
55
+ avatar,
56
+ sent = false,
57
+ reactions,
58
+ className,
59
+ }: MediaMessageProps) {
60
+ let bubble: ReactNode;
61
+ if (type === "image") {
62
+ bubble = (
63
+ <div className={clsx(bubbleClasses(sent, "white"))}>
64
+ {src ? <img src={src} alt={typeof fileName === "string" ? fileName : ""} className="block w-full object-cover" /> : null}
65
+ </div>
66
+ );
67
+ } else if (type === "video") {
68
+ bubble = (
69
+ <div className={clsx(bubbleClasses(sent, "white"), "relative")}>
70
+ {src ? <img src={src} alt="" className="block w-full object-cover" /> : null}
71
+ <span className="absolute inset-0 flex items-center justify-center">
72
+ <PlayButton />
73
+ </span>
74
+ </div>
75
+ );
76
+ } else if (type === "audio") {
77
+ bubble = (
78
+ <div className={clsx(bubbleClasses(sent, "white"), "flex items-center gap-md p-lg")}>
79
+ <PlayButton />
80
+ <span className="flex h-6 flex-1 items-center gap-[2px]">
81
+ {Array.from({ length: 24 }).map((_, i) => (
82
+ <span
83
+ key={i}
84
+ className="w-[2px] rounded-full bg-bg-quaternary"
85
+ style={{ height: `${30 + Math.abs(Math.sin(i)) * 70}%` }}
86
+ />
87
+ ))}
88
+ </span>
89
+ {meta ? <span className="shrink-0 text-sm text-text-tertiary">{meta}</span> : null}
90
+ </div>
91
+ );
92
+ } else {
93
+ bubble = (
94
+ <div className={clsx(bubbleClasses(sent, "white"), "flex items-start gap-lg p-lg")}>
95
+ <FileTypeIcon ext={fileExt} />
96
+ <span className="flex min-w-0 flex-col">
97
+ <span className="truncate text-sm font-medium text-text-secondary">{fileName}</span>
98
+ {meta ? <span className="text-sm font-normal text-text-tertiary">{meta}</span> : null}
99
+ </span>
100
+ </div>
101
+ );
102
+ }
103
+
104
+ return (
105
+ <MessageShell author={author} time={time} avatar={avatar} sent={sent} reactions={reactions} className={className}>
106
+ {bubble}
107
+ </MessageShell>
108
+ );
109
+ }
@@ -0,0 +1,2 @@
1
+ export { MediaMessage } from "./MediaMessage";
2
+ export type { MediaMessageProps, MediaMessageType } from "./MediaMessage";
@@ -0,0 +1,49 @@
1
+ import type { InputHTMLAttributes } from "react";
2
+ import clsx from "clsx";
3
+
4
+ export type MegaInputFieldBaseSize = "sm" | "md" | "lg";
5
+
6
+ export interface MegaInputFieldBaseProps
7
+ extends Omit<InputHTMLAttributes<HTMLInputElement>, "size"> {
8
+ size?: MegaInputFieldBaseSize;
9
+ /** Error styling. */
10
+ destructive?: boolean;
11
+ }
12
+
13
+ const sizeClasses: Record<MegaInputFieldBaseSize, string> = {
14
+ sm: "size-16 rounded-lg text-display-lg",
15
+ md: "size-20 rounded-xl text-display-lg",
16
+ lg: "size-24 rounded-xl text-display-xl",
17
+ };
18
+
19
+ /**
20
+ * A single large character/code-entry cell (one digit per box) used to compose
21
+ * OTP / verification inputs. `Size` (sm/md/lg) × states (placeholder/focused/
22
+ * filled/disabled/error) — focus & fill are native; pass `destructive` for error.
23
+ */
24
+ export function MegaInputFieldBase({
25
+ size = "md",
26
+ destructive,
27
+ disabled,
28
+ className,
29
+ ...rest
30
+ }: MegaInputFieldBaseProps) {
31
+ return (
32
+ <input
33
+ inputMode="numeric"
34
+ maxLength={1}
35
+ disabled={disabled}
36
+ className={clsx(
37
+ "border bg-bg-primary text-center font-display font-medium shadow-xs outline-none",
38
+ "placeholder:text-text-placeholder placeholder:opacity-40",
39
+ sizeClasses[size],
40
+ destructive
41
+ ? "border-border-error-subtle text-text-error-primary"
42
+ : "border-border-primary text-text-brand-tertiary-alt focus:border-border-brand focus:ring-2 focus:ring-border-brand focus:ring-offset-2 focus:ring-offset-bg-primary",
43
+ disabled && "pointer-events-none opacity-50",
44
+ className,
45
+ )}
46
+ {...rest}
47
+ />
48
+ );
49
+ }
@@ -0,0 +1,5 @@
1
+ export { MegaInputFieldBase } from "./MegaInputFieldBase";
2
+ export type {
3
+ MegaInputFieldBaseProps,
4
+ MegaInputFieldBaseSize,
5
+ } from "./MegaInputFieldBase";
@@ -0,0 +1,85 @@
1
+ import type { ReactNode } from "react";
2
+ import clsx from "clsx";
3
+ import { MessageShell, bubbleClasses } from "./messageShared";
4
+
5
+ export type MessageType = "message" | "reply" | "writing";
6
+
7
+ export interface MessageProps {
8
+ /** Bubble variant. */
9
+ type?: MessageType;
10
+ /** Message body text. */
11
+ children?: ReactNode;
12
+ /** Quoted text shown above the body for `type="reply"`. */
13
+ replyTo?: ReactNode;
14
+ author?: ReactNode;
15
+ time?: ReactNode;
16
+ avatar?: ReactNode;
17
+ sent?: boolean;
18
+ /** Reaction chips (compose MessageReaction). */
19
+ reactions?: ReactNode;
20
+ className?: string;
21
+ }
22
+
23
+ function WritingDots() {
24
+ return (
25
+ <span className="flex items-center gap-xs px-xs py-1">
26
+ {[0, 1, 2].map((i) => (
27
+ <span
28
+ key={i}
29
+ className="size-1 animate-bounce rounded-full bg-fg-quaternary"
30
+ style={{ animationDelay: `${i * 0.15}s` }}
31
+ />
32
+ ))}
33
+ </span>
34
+ );
35
+ }
36
+
37
+ /**
38
+ * A text chat bubble. `type` covers a plain message, a reply (with a quoted
39
+ * line), and the writing/typing indicator. Use `sent` for own messages
40
+ * (right-aligned, brand bubble).
41
+ */
42
+ export function Message({
43
+ type = "message",
44
+ children,
45
+ replyTo,
46
+ author,
47
+ time,
48
+ avatar,
49
+ sent = false,
50
+ reactions,
51
+ className,
52
+ }: MessageProps) {
53
+ const tone = sent ? "brand" : "secondary";
54
+
55
+ return (
56
+ <MessageShell
57
+ author={author}
58
+ time={time}
59
+ avatar={avatar}
60
+ sent={sent}
61
+ reactions={type === "writing" ? undefined : reactions}
62
+ className={className}
63
+ >
64
+ {type === "writing" ? (
65
+ <div className={clsx(bubbleClasses(sent, "secondary"), "px-md py-md")}>
66
+ <WritingDots />
67
+ </div>
68
+ ) : (
69
+ <div className={clsx(bubbleClasses(sent, tone), "flex flex-col gap-xs px-lg py-md text-md")}>
70
+ {type === "reply" && replyTo ? (
71
+ <span
72
+ className={clsx(
73
+ "border-l-2 pl-md text-sm",
74
+ sent ? "border-white/40 text-text-white/80" : "border-border-secondary text-text-tertiary",
75
+ )}
76
+ >
77
+ {replyTo}
78
+ </span>
79
+ ) : null}
80
+ <span className="font-normal">{children}</span>
81
+ </div>
82
+ )}
83
+ </MessageShell>
84
+ );
85
+ }
@@ -0,0 +1,3 @@
1
+ export { Message } from "./Message";
2
+ export type { MessageProps, MessageType } from "./Message";
3
+ export type { MessageBubbleTone } from "./messageShared";
@@ -0,0 +1,73 @@
1
+ import type { ReactNode } from "react";
2
+ import clsx from "clsx";
3
+
4
+ // Shared layout for the Message family (Message / MediaMessage / LinkMessage).
5
+ // PRIVATE — not exported from the barrel.
6
+
7
+ export type MessageBubbleTone = "secondary" | "white" | "brand";
8
+
9
+ export interface MessageShellProps {
10
+ /** Author name. */
11
+ author?: ReactNode;
12
+ /** Timestamp. */
13
+ time?: ReactNode;
14
+ /** Avatar node (32px). */
15
+ avatar?: ReactNode;
16
+ /** Sent (own) message → right-aligned. */
17
+ sent?: boolean;
18
+ /** Reaction chips row (compose MessageReaction). */
19
+ reactions?: ReactNode;
20
+ /** The bubble content. */
21
+ children: ReactNode;
22
+ className?: string;
23
+ }
24
+
25
+ /** Bubble container classes — tone + sent-aware corner. */
26
+ export function bubbleClasses(sent: boolean, tone: MessageBubbleTone) {
27
+ return clsx(
28
+ "overflow-hidden rounded-md border",
29
+ sent ? "rounded-tr-none" : "rounded-tl-none",
30
+ tone === "brand" && "border-transparent bg-bg-brand-solid text-text-white",
31
+ tone === "secondary" && "border-border-secondary bg-bg-secondary text-text-primary",
32
+ tone === "white" && "border-border-secondary bg-bg-primary text-text-primary",
33
+ );
34
+ }
35
+
36
+ /** Avatar + name/time header + bubble + reactions, with sent alignment. */
37
+ export function MessageShell({
38
+ author,
39
+ time,
40
+ avatar,
41
+ sent = false,
42
+ reactions,
43
+ children,
44
+ className,
45
+ }: MessageShellProps) {
46
+ return (
47
+ <div
48
+ className={clsx(
49
+ "flex w-[360px] max-w-full items-start gap-lg font-body",
50
+ sent && "flex-row-reverse",
51
+ className,
52
+ )}
53
+ >
54
+ {avatar ? <div className="shrink-0">{avatar}</div> : null}
55
+ <div className={clsx("flex min-w-0 flex-1 flex-col gap-sm", sent && "items-end")}>
56
+ {author || time ? (
57
+ <div className={clsx("flex w-full items-center gap-md", sent && "flex-row-reverse")}>
58
+ <span className="min-w-0 flex-1 truncate text-sm font-medium text-text-secondary">
59
+ {author}
60
+ </span>
61
+ {time ? (
62
+ <span className="shrink-0 text-xs font-normal text-text-tertiary">{time}</span>
63
+ ) : null}
64
+ </div>
65
+ ) : null}
66
+ {children}
67
+ {reactions ? (
68
+ <div className="flex w-full items-center justify-end gap-xs">{reactions}</div>
69
+ ) : null}
70
+ </div>
71
+ </div>
72
+ );
73
+ }
@@ -0,0 +1,221 @@
1
+ import {
2
+ type HTMLAttributes,
3
+ type ReactNode,
4
+ type TextareaHTMLAttributes,
5
+ } from "react";
6
+ import clsx from "clsx";
7
+
8
+ export type MessageActionType = "minimal" | "textarea" | "advanced";
9
+
10
+ export interface MessageActionProps
11
+ extends Omit<HTMLAttributes<HTMLDivElement>, "onChange"> {
12
+ /** minimal = single-line + send · textarea = multiline composer · advanced = AI prompt box */
13
+ type?: MessageActionType;
14
+ /** Controlled value of the input/textarea. */
15
+ value?: string;
16
+ onValueChange?: (value: string) => void;
17
+ /** Fired when the send affordance is activated. */
18
+ onSend?: () => void;
19
+ placeholder?: string;
20
+ /** Advanced only — left-side author chip (avatar + name). */
21
+ author?: ReactNode;
22
+ textareaProps?: TextareaHTMLAttributes<HTMLTextAreaElement>;
23
+ }
24
+
25
+ /* --- minimal inline icons (currentColor, 16/20px) ------------------------- */
26
+ const Send = ({ className }: { className?: string }) => (
27
+ <svg className={className} viewBox="0 0 20 20" fill="none" aria-hidden>
28
+ <path
29
+ d="M17.5 2.5 9.17 10.83M17.5 2.5l-5.3 15-3.03-6.67L2.5 7.8l15-5.3Z"
30
+ stroke="currentColor"
31
+ strokeWidth="1.67"
32
+ strokeLinecap="round"
33
+ strokeLinejoin="round"
34
+ />
35
+ </svg>
36
+ );
37
+ const Attach = ({ className }: { className?: string }) => (
38
+ <svg className={className} viewBox="0 0 16 16" fill="none" aria-hidden>
39
+ <path
40
+ d="M14 7.33 8.07 13.26a3.33 3.33 0 0 1-4.71-4.71l5.93-5.93a2.22 2.22 0 1 1 3.14 3.14l-5.94 5.93a1.11 1.11 0 0 1-1.57-1.57l5.48-5.47"
41
+ stroke="currentColor"
42
+ strokeWidth="1.33"
43
+ strokeLinecap="round"
44
+ strokeLinejoin="round"
45
+ />
46
+ </svg>
47
+ );
48
+ const Smile = ({ className }: { className?: string }) => (
49
+ <svg className={className} viewBox="0 0 16 16" fill="none" aria-hidden>
50
+ <path
51
+ d="M5.33 9.33s1 1.34 2.67 1.34S10.67 9.33 10.67 9.33M6 6h.01M10 6h.01M14.67 8A6.67 6.67 0 1 1 1.33 8a6.67 6.67 0 0 1 13.34 0Z"
52
+ stroke="currentColor"
53
+ strokeWidth="1.33"
54
+ strokeLinecap="round"
55
+ strokeLinejoin="round"
56
+ />
57
+ </svg>
58
+ );
59
+ const Mic = ({ className }: { className?: string }) => (
60
+ <svg className={className} viewBox="0 0 16 16" fill="none" aria-hidden>
61
+ <path
62
+ d="M8 1.33A2 2 0 0 0 6 3.33V8a2 2 0 1 0 4 0V3.33a2 2 0 0 0-2-2ZM12.67 6.67V8A4.67 4.67 0 0 1 3.33 8V6.67M8 12.67v2"
63
+ stroke="currentColor"
64
+ strokeWidth="1.33"
65
+ strokeLinecap="round"
66
+ strokeLinejoin="round"
67
+ />
68
+ </svg>
69
+ );
70
+ const Italic = ({ className }: { className?: string }) => (
71
+ <svg className={className} viewBox="0 0 16 16" fill="none" aria-hidden>
72
+ <path
73
+ d="M9.33 3.33H6.67M9.33 12.67H6.67M10 3.33 6 12.67"
74
+ stroke="currentColor"
75
+ strokeWidth="1.33"
76
+ strokeLinecap="round"
77
+ strokeLinejoin="round"
78
+ />
79
+ </svg>
80
+ );
81
+ const Chevron = ({ className }: { className?: string }) => (
82
+ <svg className={className} viewBox="0 0 12 12" fill="none" aria-hidden>
83
+ <path
84
+ d="m3 4.5 3 3 3-3"
85
+ stroke="currentColor"
86
+ strokeWidth="1.5"
87
+ strokeLinecap="round"
88
+ strokeLinejoin="round"
89
+ />
90
+ </svg>
91
+ );
92
+
93
+ const utilityBtn =
94
+ "flex items-center justify-center rounded-sm p-sm text-fg-quaternary transition-colors hover:text-fg-quaternary-hover";
95
+ const inputBox =
96
+ "w-full border border-border-primary bg-bg-primary text-text-placeholder shadow-xs outline-none placeholder:text-text-placeholder";
97
+
98
+ /**
99
+ * Message composer. Three layouts off `type`:
100
+ * - **minimal** — single-line field + square send button (row).
101
+ * - **textarea** — multiline box, attach/emoji + brand Send pinned bottom-right,
102
+ * record button top-right.
103
+ * - **advanced** — AI prompt box on `bg-secondary`; author chip + Shortcuts/Attach
104
+ * footer, mic top-right, resize handle.
105
+ *
106
+ * Renders real `<input>`/`<textarea>` (controlled via `value`/`onValueChange`);
107
+ * icons are inline SVG so the package ships no remote asset deps.
108
+ */
109
+ export function MessageAction({
110
+ type = "minimal",
111
+ value,
112
+ onValueChange,
113
+ onSend,
114
+ placeholder,
115
+ author,
116
+ textareaProps,
117
+ className,
118
+ ...rest
119
+ }: MessageActionProps) {
120
+ const ph = placeholder ?? (type === "advanced" ? "Ask me anything..." : "Message");
121
+
122
+ if (type === "minimal") {
123
+ return (
124
+ <div className={clsx("flex w-[360px] items-start gap-lg", className)} {...rest}>
125
+ <input
126
+ value={value}
127
+ onChange={(e) => onValueChange?.(e.target.value)}
128
+ placeholder={ph}
129
+ className={clsx(inputBox, "rounded-md px-3.5 py-2.5 text-md")}
130
+ />
131
+ <button
132
+ type="button"
133
+ onClick={onSend}
134
+ aria-label="Send"
135
+ className="flex items-center justify-center rounded-md border border-border-primary bg-bg-primary p-lg text-fg-quaternary shadow-xs transition-colors hover:text-fg-quaternary-hover"
136
+ >
137
+ <Send className="size-5" />
138
+ </button>
139
+ </div>
140
+ );
141
+ }
142
+
143
+ if (type === "textarea") {
144
+ return (
145
+ <div className={clsx("relative flex h-32 w-[360px] flex-col", className)} {...rest}>
146
+ <textarea
147
+ value={value}
148
+ onChange={(e) => onValueChange?.(e.target.value)}
149
+ placeholder={ph}
150
+ {...textareaProps}
151
+ className={clsx(inputBox, "h-full resize-none rounded-md px-3.5 py-3 text-md")}
152
+ />
153
+ <button type="button" aria-label="Record" className={clsx(utilityBtn, "absolute right-2 top-2")}>
154
+ <Mic className="size-4" />
155
+ </button>
156
+ <div className="absolute bottom-2 right-3.5 flex items-center gap-md">
157
+ <div className="flex items-center gap-xxs">
158
+ <button type="button" aria-label="Attach" className={utilityBtn}>
159
+ <Attach className="size-4" />
160
+ </button>
161
+ <button type="button" aria-label="Emoji" className={utilityBtn}>
162
+ <Smile className="size-4" />
163
+ </button>
164
+ </div>
165
+ <button
166
+ type="button"
167
+ onClick={onSend}
168
+ className="text-sm font-semibold text-text-brand-secondary"
169
+ >
170
+ Send
171
+ </button>
172
+ </div>
173
+ </div>
174
+ );
175
+ }
176
+
177
+ // advanced
178
+ return (
179
+ <div
180
+ className={clsx(
181
+ "relative flex h-40 w-[360px] flex-col rounded-xl border border-border-secondary bg-bg-secondary",
182
+ className,
183
+ )}
184
+ {...rest}
185
+ >
186
+ <textarea
187
+ value={value}
188
+ onChange={(e) => onValueChange?.(e.target.value)}
189
+ placeholder={ph}
190
+ {...textareaProps}
191
+ className={clsx(inputBox, "flex-1 resize-none rounded-xl px-3.5 py-3 text-md")}
192
+ />
193
+ <button type="button" aria-label="Record" className={clsx(utilityBtn, "absolute right-[7px] top-[7px]")}>
194
+ <Mic className="size-4" />
195
+ </button>
196
+ <div className="flex items-center gap-lg px-lg py-md">
197
+ <div className="flex flex-1 items-center">
198
+ {author ?? (
199
+ <div className="flex items-center gap-xs">
200
+ <span className="size-4 rounded-full bg-bg-tertiary" />
201
+ <span className="flex items-center gap-xxs text-xs font-semibold text-text-tertiary">
202
+ Olivia
203
+ <Chevron className="size-3" />
204
+ </span>
205
+ </div>
206
+ )}
207
+ </div>
208
+ <div className="flex items-center gap-lg text-text-tertiary">
209
+ <span className="flex items-center gap-xs text-xs font-semibold">
210
+ <Italic className="size-4" />
211
+ Shortcuts
212
+ </span>
213
+ <span className="flex items-center gap-xs text-xs font-semibold">
214
+ <Attach className="size-4" />
215
+ Attach
216
+ </span>
217
+ </div>
218
+ </div>
219
+ </div>
220
+ );
221
+ }
@@ -0,0 +1,2 @@
1
+ export { MessageAction } from "./MessageAction";
2
+ export type { MessageActionProps, MessageActionType } from "./MessageAction";