@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,39 @@
1
+ import type { ReactNode } from "react";
2
+ import clsx from "clsx";
3
+
4
+ export type ContentParagraphSize = "sm" | "md" | "lg" | "xl";
5
+
6
+ export interface ContentParagraphProps {
7
+ /** Type scale. */
8
+ size?: ContentParagraphSize;
9
+ children: ReactNode;
10
+ className?: string;
11
+ }
12
+
13
+ // lg verified = text-lg (18/28); sm/md/xl follow the body ramp
14
+ // (sm→text-sm, md→text-md, xl→text-xl) — inferred, not individually pulled.
15
+ const sizeClasses: Record<ContentParagraphSize, string> = {
16
+ sm: "text-sm",
17
+ md: "text-md",
18
+ lg: "text-lg",
19
+ xl: "text-xl",
20
+ };
21
+
22
+ /** Long-form content paragraph (article/marketing body copy). */
23
+ export function ContentParagraph({
24
+ size = "md",
25
+ children,
26
+ className,
27
+ }: ContentParagraphProps) {
28
+ return (
29
+ <p
30
+ className={clsx(
31
+ "font-body font-normal text-text-tertiary",
32
+ sizeClasses[size],
33
+ className,
34
+ )}
35
+ >
36
+ {children}
37
+ </p>
38
+ );
39
+ }
@@ -0,0 +1,5 @@
1
+ export { ContentParagraph } from "./ContentParagraph";
2
+ export type {
3
+ ContentParagraphProps,
4
+ ContentParagraphSize,
5
+ } from "./ContentParagraph";
@@ -0,0 +1,114 @@
1
+ import type { ReactNode } from "react";
2
+ import clsx from "clsx";
3
+
4
+ export type ContentQuoteAlign = "left" | "center";
5
+ export type ContentQuoteSize = "sm" | "md" | "lg" | "xl" | "2xl";
6
+
7
+ export interface ContentQuoteProps {
8
+ /** The quotation text. */
9
+ quote: ReactNode;
10
+ /** Left-bordered (default) or centred layout. */
11
+ align?: ContentQuoteAlign;
12
+ /** Quote type scale. */
13
+ size?: ContentQuoteSize;
14
+ /** Author avatar — compose an Avatar. */
15
+ avatar?: ReactNode;
16
+ /** Author name. */
17
+ authorName?: ReactNode;
18
+ /** Author role / supporting line. */
19
+ authorRole?: ReactNode;
20
+ className?: string;
21
+ }
22
+
23
+ // md verified = text-lg (18/28). sm/lg/xl/2xl inferred from the type scale.
24
+ const quoteSizeClasses: Record<ContentQuoteSize, string> = {
25
+ sm: "text-md",
26
+ md: "text-lg",
27
+ lg: "text-xl",
28
+ xl: "text-display-xs",
29
+ "2xl": "text-display-sm",
30
+ };
31
+
32
+ /** Author block (avatar + name + role). */
33
+ function Author({
34
+ avatar,
35
+ authorName,
36
+ authorRole,
37
+ center,
38
+ }: {
39
+ avatar?: ReactNode;
40
+ authorName?: ReactNode;
41
+ authorRole?: ReactNode;
42
+ center?: boolean;
43
+ }) {
44
+ if (!avatar && !authorName && !authorRole) return null;
45
+ return (
46
+ <div
47
+ className={clsx(
48
+ "flex gap-md",
49
+ center ? "flex-col items-center" : "items-center",
50
+ )}
51
+ >
52
+ {avatar ? <div className="shrink-0">{avatar}</div> : null}
53
+ <div className={clsx("flex flex-col", center && "items-center text-center")}>
54
+ {authorName ? (
55
+ <span className="text-sm font-semibold text-text-primary">
56
+ {authorName}
57
+ </span>
58
+ ) : null}
59
+ {authorRole ? (
60
+ <span className="text-sm font-normal text-text-tertiary">
61
+ {authorRole}
62
+ </span>
63
+ ) : null}
64
+ </div>
65
+ </div>
66
+ );
67
+ }
68
+
69
+ /** Long-form pull quote with optional author attribution. */
70
+ export function ContentQuote({
71
+ quote,
72
+ align = "left",
73
+ size = "md",
74
+ avatar,
75
+ authorName,
76
+ authorRole,
77
+ className,
78
+ }: ContentQuoteProps) {
79
+ const quoteText = (
80
+ <p
81
+ className={clsx(
82
+ "font-body font-medium italic text-text-primary",
83
+ quoteSizeClasses[size],
84
+ align === "center" && "text-center",
85
+ )}
86
+ >
87
+ {quote}
88
+ </p>
89
+ );
90
+
91
+ if (align === "center") {
92
+ return (
93
+ <div className={clsx("flex flex-col items-center gap-2xl font-body", className)}>
94
+ {quoteText}
95
+ <Author
96
+ avatar={avatar}
97
+ authorName={authorName}
98
+ authorRole={authorRole}
99
+ center
100
+ />
101
+ </div>
102
+ );
103
+ }
104
+
105
+ return (
106
+ <div className={clsx("flex items-stretch gap-2xl font-body", className)}>
107
+ <span className="w-0.5 shrink-0 self-stretch bg-border-secondary" aria-hidden />
108
+ <div className="flex min-w-0 flex-1 flex-col gap-3xl py-md">
109
+ {quoteText}
110
+ <Author avatar={avatar} authorName={authorName} authorRole={authorRole} />
111
+ </div>
112
+ </div>
113
+ );
114
+ }
@@ -0,0 +1,6 @@
1
+ export { ContentQuote } from "./ContentQuote";
2
+ export type {
3
+ ContentQuoteProps,
4
+ ContentQuoteAlign,
5
+ ContentQuoteSize,
6
+ } from "./ContentQuote";
@@ -0,0 +1,31 @@
1
+ import clsx from "clsx";
2
+
3
+ export type ContentRuleSize = "sm" | "md" | "lg" | "xl" | "2xl";
4
+
5
+ export interface ContentRuleProps {
6
+ /** Controls the vertical breathing room around the rule. */
7
+ size?: ContentRuleSize;
8
+ className?: string;
9
+ }
10
+
11
+ // Vertical padding ramp. md verified (32px each side); others inferred.
12
+ const sizePadding: Record<ContentRuleSize, string> = {
13
+ sm: "py-3xl", // 24px
14
+ md: "py-4xl", // 32px
15
+ lg: "py-5xl", // 40px
16
+ xl: "py-6xl", // 48px
17
+ "2xl": "py-7xl", // 64px
18
+ };
19
+
20
+ /**
21
+ * A plain full-width horizontal rule for separating blocks of long-form
22
+ * content. Distinct from `ContentDivider`, which carries a centred
23
+ * label/button. `size` sets the surrounding vertical spacing.
24
+ */
25
+ export function ContentRule({ size = "md", className }: ContentRuleProps) {
26
+ return (
27
+ <div className={clsx("w-full", sizePadding[size], className)}>
28
+ <hr className="border-0 border-t border-border-secondary" />
29
+ </div>
30
+ );
31
+ }
@@ -0,0 +1,2 @@
1
+ export { ContentRule } from "./ContentRule";
2
+ export type { ContentRuleProps, ContentRuleSize } from "./ContentRule";
@@ -0,0 +1,67 @@
1
+ import { useEffect, useRef } from "react";
2
+ import type { ReactNode } from "react";
3
+ import clsx from "clsx";
4
+
5
+ export interface ContextMenuProps {
6
+ /** Whether the menu is visible. */
7
+ open: boolean;
8
+ /** Viewport x of the right-click (from useContextMenu). */
9
+ x: number;
10
+ /** Viewport y of the right-click (from useContextMenu). */
11
+ y: number;
12
+ /** Called on outside-click or Escape. */
13
+ onClose: () => void;
14
+ /** Menu rows — typically DropdownMenuListItem elements. */
15
+ children: ReactNode;
16
+ className?: string;
17
+ }
18
+
19
+ /**
20
+ * A thin positioned panel for right-click menus. Reuses the dropdown panel
21
+ * tokens (shadow-lg, border-secondary-alt, radius-md) and renders whatever
22
+ * rows you pass — compose DropdownMenuListItem children; it does NOT
23
+ * reimplement list items. Pair with `useContextMenu`.
24
+ */
25
+ export function ContextMenu({
26
+ open,
27
+ x,
28
+ y,
29
+ onClose,
30
+ children,
31
+ className,
32
+ }: ContextMenuProps) {
33
+ const ref = useRef<HTMLDivElement>(null);
34
+
35
+ useEffect(() => {
36
+ if (!open) return;
37
+ const onPointerDown = (e: PointerEvent) => {
38
+ if (ref.current && !ref.current.contains(e.target as Node)) onClose();
39
+ };
40
+ const onKeyDown = (e: KeyboardEvent) => {
41
+ if (e.key === "Escape") onClose();
42
+ };
43
+ document.addEventListener("pointerdown", onPointerDown);
44
+ document.addEventListener("keydown", onKeyDown);
45
+ return () => {
46
+ document.removeEventListener("pointerdown", onPointerDown);
47
+ document.removeEventListener("keydown", onKeyDown);
48
+ };
49
+ }, [open, onClose]);
50
+
51
+ if (!open) return null;
52
+
53
+ return (
54
+ <div
55
+ ref={ref}
56
+ role="menu"
57
+ style={{ position: "fixed", top: y, left: x }}
58
+ className={clsx(
59
+ "z-50 flex min-w-[216px] flex-col py-xs",
60
+ "rounded-md border border-border-secondary-alt bg-bg-primary font-body shadow-lg",
61
+ className,
62
+ )}
63
+ >
64
+ {children}
65
+ </div>
66
+ );
67
+ }
@@ -0,0 +1,7 @@
1
+ export { ContextMenu } from "./ContextMenu";
2
+ export type { ContextMenuProps } from "./ContextMenu";
3
+ export { useContextMenu } from "./useContextMenu";
4
+ export type {
5
+ UseContextMenuReturn,
6
+ ContextMenuState,
7
+ } from "./useContextMenu";
@@ -0,0 +1,41 @@
1
+ import { useCallback, useState } from "react";
2
+
3
+ export interface ContextMenuState {
4
+ open: boolean;
5
+ x: number;
6
+ y: number;
7
+ }
8
+
9
+ export interface UseContextMenuReturn extends ContextMenuState {
10
+ /** Attach to the element that should open the menu on right-click. */
11
+ onContextMenu: (e: { preventDefault: () => void; clientX: number; clientY: number }) => void;
12
+ /** Close the menu. */
13
+ close: () => void;
14
+ }
15
+
16
+ /**
17
+ * Captures right-click position and manages open state for a ContextMenu.
18
+ *
19
+ * ```tsx
20
+ * const menu = useContextMenu();
21
+ * <div onContextMenu={menu.onContextMenu}>…</div>
22
+ * <ContextMenu open={menu.open} x={menu.x} y={menu.y} onClose={menu.close}>
23
+ * <DropdownMenuListItem>Cut</DropdownMenuListItem>
24
+ * </ContextMenu>
25
+ * ```
26
+ */
27
+ export function useContextMenu(): UseContextMenuReturn {
28
+ const [state, setState] = useState<ContextMenuState>({ open: false, x: 0, y: 0 });
29
+
30
+ const onContextMenu = useCallback(
31
+ (e: { preventDefault: () => void; clientX: number; clientY: number }) => {
32
+ e.preventDefault();
33
+ setState({ open: true, x: e.clientX, y: e.clientY });
34
+ },
35
+ [],
36
+ );
37
+
38
+ const close = useCallback(() => setState((s) => ({ ...s, open: false })), []);
39
+
40
+ return { ...state, onContextMenu, close };
41
+ }
@@ -0,0 +1,77 @@
1
+ import type { ButtonHTMLAttributes, ReactNode } from "react";
2
+ import clsx from "clsx";
3
+
4
+ export type DatePickerCellType = "default" | "active" | "selected" | "today";
5
+
6
+ export interface DatePickerCellProps
7
+ extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, "type"> {
8
+ /** Day number (or any short label). */
9
+ date: ReactNode;
10
+ /** Visual role of the cell within the calendar grid. */
11
+ cellType?: DatePickerCellType;
12
+ /** Shows the small "has events" dot under the date. */
13
+ hasDot?: boolean;
14
+ /** Range-fill connector on the left edge (cell is mid/end of a range). */
15
+ leftConnector?: boolean;
16
+ /** Range-fill connector on the right edge (cell is start/mid of a range). */
17
+ rightConnector?: boolean;
18
+ }
19
+
20
+ const cellClasses: Record<DatePickerCellType, string> = {
21
+ default: "text-text-secondary hover:bg-bg-primary-hover hover:text-text-secondary-hover",
22
+ active: "bg-bg-secondary font-medium text-text-secondary hover:bg-bg-secondary-hover",
23
+ today: "bg-bg-secondary font-medium text-text-secondary hover:bg-bg-secondary-hover",
24
+ selected: "bg-bg-brand-solid font-medium text-text-white hover:bg-bg-brand-solid-hover",
25
+ };
26
+
27
+ /**
28
+ * A single day cell in the date-picker calendar grid. Distinct from the
29
+ * Calendar page's own `CalendarCell` — this one is round, supports range
30
+ * connectors, and a selected (brand-filled) state.
31
+ */
32
+ export function DatePickerCell({
33
+ date,
34
+ cellType = "default",
35
+ hasDot = false,
36
+ leftConnector = false,
37
+ rightConnector = false,
38
+ disabled = false,
39
+ className,
40
+ ...rest
41
+ }: DatePickerCellProps) {
42
+ const isRange = cellType !== "default";
43
+ return (
44
+ <div className="relative size-10">
45
+ {isRange && leftConnector ? (
46
+ <span className="absolute left-0 top-0 h-10 w-1/2 bg-bg-secondary" aria-hidden />
47
+ ) : null}
48
+ {isRange && rightConnector ? (
49
+ <span className="absolute right-0 top-0 h-10 w-1/2 bg-bg-secondary" aria-hidden />
50
+ ) : null}
51
+ <button
52
+ type="button"
53
+ disabled={disabled}
54
+ className={clsx(
55
+ "relative flex size-10 items-center justify-center rounded-full text-sm font-body",
56
+ "outline-none transition-colors",
57
+ "focus-visible:ring-2 focus-visible:ring-border-brand focus-visible:ring-offset-2 focus-visible:ring-offset-bg-primary",
58
+ cellClasses[cellType],
59
+ disabled && "pointer-events-none opacity-50",
60
+ className,
61
+ )}
62
+ {...rest}
63
+ >
64
+ {date}
65
+ {hasDot ? (
66
+ <span
67
+ className={clsx(
68
+ "absolute bottom-1 left-1/2 size-[5px] -translate-x-1/2 rounded-full",
69
+ cellType === "selected" ? "bg-text-white" : "bg-bg-brand-solid",
70
+ )}
71
+ aria-hidden
72
+ />
73
+ ) : null}
74
+ </button>
75
+ </div>
76
+ );
77
+ }
@@ -0,0 +1,2 @@
1
+ export { DatePickerCell } from "./DatePickerCell";
2
+ export type { DatePickerCellProps, DatePickerCellType } from "./DatePickerCell";
@@ -0,0 +1,39 @@
1
+ import type { ButtonHTMLAttributes, ReactNode } from "react";
2
+ import clsx from "clsx";
3
+
4
+ export interface DatePickerListItemProps
5
+ extends ButtonHTMLAttributes<HTMLButtonElement> {
6
+ /** Marks the item as the current selection (filled background). */
7
+ selected?: boolean;
8
+ children: ReactNode;
9
+ }
10
+
11
+ /**
12
+ * A selectable row in a date-picker preset list (e.g. "Today", "Last 7 days").
13
+ * Hover and focus are handled natively; pass `selected` for the active row.
14
+ */
15
+ export function DatePickerListItem({
16
+ selected = false,
17
+ children,
18
+ className,
19
+ ...rest
20
+ }: DatePickerListItemProps) {
21
+ return (
22
+ <button
23
+ type="button"
24
+ aria-pressed={selected}
25
+ className={clsx(
26
+ "flex w-[160px] items-center overflow-hidden rounded-sm px-lg py-md text-left font-body text-sm font-medium",
27
+ "outline-none transition-colors",
28
+ "focus-visible:ring-2 focus-visible:ring-border-brand focus-visible:ring-offset-2 focus-visible:ring-offset-bg-primary",
29
+ selected
30
+ ? "bg-bg-secondary text-text-secondary-hover hover:bg-bg-secondary-hover"
31
+ : "text-text-secondary hover:bg-bg-primary-hover hover:text-text-secondary-hover",
32
+ className,
33
+ )}
34
+ {...rest}
35
+ >
36
+ {children}
37
+ </button>
38
+ );
39
+ }
@@ -0,0 +1,2 @@
1
+ export { DatePickerListItem } from "./DatePickerListItem";
2
+ export type { DatePickerListItemProps } from "./DatePickerListItem";
@@ -0,0 +1,131 @@
1
+ import type { ReactNode } from "react";
2
+ import clsx from "clsx";
3
+
4
+ export interface DatePickerMenuProps {
5
+ /** Current month label, e.g. "January 2027". */
6
+ monthLabel: ReactNode;
7
+ /** Previous-month handler. */
8
+ onPrevMonth?: () => void;
9
+ /** Next-month handler. */
10
+ onNextMonth?: () => void;
11
+ /** Weekday column headers. Defaults to Mo–Su. */
12
+ weekdays?: string[];
13
+ /**
14
+ * Optional row above the grid (e.g. a date input + "Today" button).
15
+ * Compose your own controls here.
16
+ */
17
+ toolbar?: ReactNode;
18
+ /** The day grid — typically 35–42 DatePickerCell elements. */
19
+ children: ReactNode;
20
+ /** Cancel handler (renders the footer when set with onApply). */
21
+ onCancel?: () => void;
22
+ /** Apply handler (renders the footer when set with onCancel). */
23
+ onApply?: () => void;
24
+ cancelLabel?: ReactNode;
25
+ applyLabel?: ReactNode;
26
+ className?: string;
27
+ }
28
+
29
+ const defaultWeekdays = ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"];
30
+
31
+ function Chevron({ left }: { left?: boolean }) {
32
+ return (
33
+ <svg viewBox="0 0 20 20" fill="none" className="size-5" aria-hidden>
34
+ <path
35
+ d={left ? "M12.5 15 7.5 10l5-5" : "M7.5 5l5 5-5 5"}
36
+ stroke="currentColor"
37
+ strokeWidth="1.667"
38
+ strokeLinecap="round"
39
+ strokeLinejoin="round"
40
+ />
41
+ </svg>
42
+ );
43
+ }
44
+
45
+ function NavButton({
46
+ left,
47
+ onClick,
48
+ }: {
49
+ left?: boolean;
50
+ onClick?: () => void;
51
+ }) {
52
+ return (
53
+ <button
54
+ type="button"
55
+ onClick={onClick}
56
+ aria-label={left ? "Previous month" : "Next month"}
57
+ className="flex size-8 items-center justify-center rounded-sm text-fg-quaternary outline-none transition-colors hover:bg-bg-primary-hover hover:text-fg-quaternary-hover focus-visible:ring-2 focus-visible:ring-border-brand"
58
+ >
59
+ <Chevron left={left} />
60
+ </button>
61
+ );
62
+ }
63
+
64
+ /**
65
+ * The calendar panel of a date picker — month navigation, weekday header,
66
+ * a day grid (compose DatePickerCell children), and optional toolbar/footer.
67
+ * Date math is the consumer's responsibility; this renders the chrome.
68
+ */
69
+ export function DatePickerMenu({
70
+ monthLabel,
71
+ onPrevMonth,
72
+ onNextMonth,
73
+ weekdays = defaultWeekdays,
74
+ toolbar,
75
+ children,
76
+ onCancel,
77
+ onApply,
78
+ cancelLabel = "Cancel",
79
+ applyLabel = "Apply",
80
+ className,
81
+ }: DatePickerMenuProps) {
82
+ const showFooter = Boolean(onCancel || onApply);
83
+ return (
84
+ <div
85
+ className={clsx(
86
+ "w-[328px] overflow-hidden rounded-2xl border border-border-secondary-alt bg-bg-primary font-body shadow-xl",
87
+ className,
88
+ )}
89
+ >
90
+ <div className="flex flex-col gap-xl px-3xl py-2xl">
91
+ <div className="flex items-center justify-between">
92
+ <NavButton left onClick={onPrevMonth} />
93
+ <span className="text-sm font-semibold text-text-secondary">
94
+ {monthLabel}
95
+ </span>
96
+ <NavButton onClick={onNextMonth} />
97
+ </div>
98
+ {toolbar}
99
+ <div className="flex flex-wrap gap-y-xs">
100
+ {weekdays.map((wd) => (
101
+ <span
102
+ key={wd}
103
+ className="flex size-10 items-center justify-center text-sm font-medium text-text-secondary"
104
+ >
105
+ {wd}
106
+ </span>
107
+ ))}
108
+ {children}
109
+ </div>
110
+ </div>
111
+ {showFooter ? (
112
+ <div className="flex gap-lg border-t border-border-secondary p-xl">
113
+ <button
114
+ type="button"
115
+ onClick={onCancel}
116
+ className="flex-1 rounded-md border border-border-primary bg-bg-primary px-lg py-md text-sm font-semibold text-text-secondary shadow-xs"
117
+ >
118
+ {cancelLabel}
119
+ </button>
120
+ <button
121
+ type="button"
122
+ onClick={onApply}
123
+ className="flex-1 rounded-md bg-bg-brand-solid px-lg py-md text-sm font-semibold text-text-white shadow-xs"
124
+ >
125
+ {applyLabel}
126
+ </button>
127
+ </div>
128
+ ) : null}
129
+ </div>
130
+ );
131
+ }
@@ -0,0 +1,2 @@
1
+ export { DatePickerMenu } from "./DatePickerMenu";
2
+ export type { DatePickerMenuProps } from "./DatePickerMenu";
@@ -0,0 +1,69 @@
1
+ import type { ButtonHTMLAttributes, ReactNode } from "react";
2
+ import clsx from "clsx";
3
+
4
+ export interface DropdownAccountListItemProps
5
+ extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, "name"> {
6
+ /** Square avatar (compose an avatar/image). */
7
+ avatar?: ReactNode;
8
+ /** Account name. */
9
+ name: ReactNode;
10
+ /** Account email / supporting line. */
11
+ email?: ReactNode;
12
+ /** Whether this account is the active selection (filled radio). */
13
+ selected?: boolean;
14
+ }
15
+
16
+ /**
17
+ * An account-switcher row for a dropdown menu — square avatar, name + email,
18
+ * and a trailing radio indicator. Hover handled natively.
19
+ */
20
+ export function DropdownAccountListItem({
21
+ avatar,
22
+ name,
23
+ email,
24
+ selected = false,
25
+ className,
26
+ ...rest
27
+ }: DropdownAccountListItemProps) {
28
+ return (
29
+ <button
30
+ type="button"
31
+ role="menuitemradio"
32
+ aria-checked={selected}
33
+ className={clsx(
34
+ "flex w-full items-start gap-sm rounded-md p-md text-left font-body",
35
+ "outline-none transition-colors hover:bg-bg-primary-hover",
36
+ "focus-visible:ring-2 focus-visible:ring-border-brand",
37
+ className,
38
+ )}
39
+ {...rest}
40
+ >
41
+ {avatar ? (
42
+ <span className="flex size-9 shrink-0 items-center justify-center overflow-hidden rounded-lg border-[0.5px] border-border-secondary bg-bg-primary p-[2px] shadow-md">
43
+ <span className="size-8 overflow-hidden rounded-md">{avatar}</span>
44
+ </span>
45
+ ) : null}
46
+ <span className="flex min-w-0 flex-1 flex-col">
47
+ <span className="truncate text-sm font-semibold text-text-primary">
48
+ {name}
49
+ </span>
50
+ {email ? (
51
+ <span className="truncate text-sm font-normal text-text-tertiary">
52
+ {email}
53
+ </span>
54
+ ) : null}
55
+ </span>
56
+ <span
57
+ className={clsx(
58
+ "mt-px flex size-4 shrink-0 items-center justify-center rounded-full border",
59
+ selected ? "border-border-brand" : "border-border-primary",
60
+ )}
61
+ aria-hidden
62
+ >
63
+ {selected ? (
64
+ <span className="size-1.5 rounded-full bg-fg-brand-primary" />
65
+ ) : null}
66
+ </span>
67
+ </button>
68
+ );
69
+ }
@@ -0,0 +1,2 @@
1
+ export { DropdownAccountListItem } from "./DropdownAccountListItem";
2
+ export type { DropdownAccountListItemProps } from "./DropdownAccountListItem";