@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,61 @@
1
+ import type { ReactNode } from "react";
2
+ import clsx from "clsx";
3
+ import { PillBadge } from "../Badge";
4
+ import { ModernBadge } from "../Badge";
5
+ import type { BadgeColor } from "../Badge";
6
+
7
+ export type BadgeGroupSize = "md" | "lg";
8
+ export type BadgeGroupType = "pill" | "modern";
9
+ export type BadgeGroupBadgePosition = "leading" | "trailing";
10
+
11
+ export interface BadgeGroupProps {
12
+ /** Text inside the inner coloured badge (e.g. "New feature"). */
13
+ badgeLabel: string;
14
+ /** The main label alongside the badge. */
15
+ children: ReactNode;
16
+ color?: BadgeColor;
17
+ size?: BadgeGroupSize;
18
+ /** Inner badge style. */
19
+ type?: BadgeGroupType;
20
+ /** Whether the badge sits before or after the label. */
21
+ badgePosition?: BadgeGroupBadgePosition;
22
+ className?: string;
23
+ }
24
+
25
+ const sizeClasses: Record<BadgeGroupSize, string> = {
26
+ md: "py-xxs pl-xxs pr-lg text-sm gap-md",
27
+ lg: "py-xs pl-xs pr-xl text-sm gap-md",
28
+ };
29
+
30
+ export function BadgeGroup({
31
+ badgeLabel,
32
+ children,
33
+ color = "brand",
34
+ size = "md",
35
+ type = "pill",
36
+ badgePosition = "leading",
37
+ className,
38
+ }: BadgeGroupProps) {
39
+ const InnerBadge = type === "modern" ? ModernBadge : PillBadge;
40
+ const badge = (
41
+ <InnerBadge color={color} size="sm">
42
+ {badgeLabel}
43
+ </InnerBadge>
44
+ );
45
+ const trailing = badgePosition === "trailing";
46
+
47
+ return (
48
+ <span
49
+ className={clsx(
50
+ "inline-flex items-center rounded-full border border-border-primary bg-bg-primary font-medium text-text-secondary shadow-xs font-body",
51
+ // mirror the asymmetric padding when the badge is trailing
52
+ trailing && "flex-row-reverse pl-lg pr-xxs",
53
+ sizeClasses[size],
54
+ className,
55
+ )}
56
+ >
57
+ {badge}
58
+ <span>{children}</span>
59
+ </span>
60
+ );
61
+ }
@@ -0,0 +1,7 @@
1
+ export { BadgeGroup } from "./BadgeGroup";
2
+ export type {
3
+ BadgeGroupProps,
4
+ BadgeGroupSize,
5
+ BadgeGroupType,
6
+ BadgeGroupBadgePosition,
7
+ } from "./BadgeGroup";
@@ -0,0 +1,75 @@
1
+ import type { ReactNode, MouseEventHandler } from "react";
2
+ import clsx from "clsx";
3
+
4
+ export type BreadcrumbButtonType = "text" | "button";
5
+
6
+ export interface BreadcrumbButtonBaseProps {
7
+ /** Crumb label. Optional for an icon-only (home) crumb. */
8
+ children?: ReactNode;
9
+ /** Leading icon (e.g. a home glyph for the root crumb). */
10
+ icon?: ReactNode;
11
+ type?: BreadcrumbButtonType;
12
+ /** Marks the active/last crumb (brand colour, aria-current). */
13
+ current?: boolean;
14
+ /** Renders as an anchor when set, otherwise a button. */
15
+ href?: string;
16
+ onClick?: MouseEventHandler<HTMLElement>;
17
+ className?: string;
18
+ }
19
+
20
+ export function BreadcrumbButtonBase({
21
+ children,
22
+ icon,
23
+ type = "text",
24
+ current = false,
25
+ href,
26
+ onClick,
27
+ className,
28
+ }: BreadcrumbButtonBaseProps) {
29
+ const classes = clsx(
30
+ "inline-flex items-center gap-md text-sm font-semibold font-body transition-colors",
31
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-brand focus-visible:ring-offset-2 focus-visible:ring-offset-bg-primary",
32
+ type === "button" && "rounded-sm px-md py-xs",
33
+ current
34
+ ? clsx(
35
+ "text-text-brand-secondary",
36
+ type === "button" && "bg-bg-brand-primary",
37
+ )
38
+ : clsx(
39
+ "text-text-quaternary hover:text-text-tertiary-hover",
40
+ type === "button" && "hover:bg-bg-primary-hover",
41
+ ),
42
+ className,
43
+ );
44
+
45
+ const content = (
46
+ <>
47
+ {icon ? <span className="shrink-0">{icon}</span> : null}
48
+ {children}
49
+ </>
50
+ );
51
+
52
+ if (href) {
53
+ return (
54
+ <a
55
+ href={href}
56
+ onClick={onClick}
57
+ aria-current={current ? "page" : undefined}
58
+ className={classes}
59
+ >
60
+ {content}
61
+ </a>
62
+ );
63
+ }
64
+
65
+ return (
66
+ <button
67
+ type="button"
68
+ onClick={onClick}
69
+ aria-current={current ? "page" : undefined}
70
+ className={classes}
71
+ >
72
+ {content}
73
+ </button>
74
+ );
75
+ }
@@ -0,0 +1,5 @@
1
+ export { BreadcrumbButtonBase } from "./BreadcrumbButtonBase";
2
+ export type {
3
+ BreadcrumbButtonBaseProps,
4
+ BreadcrumbButtonType,
5
+ } from "./BreadcrumbButtonBase";
@@ -0,0 +1,62 @@
1
+ import { Children, isValidElement } from "react";
2
+ import type { ReactNode } from "react";
3
+ import clsx from "clsx";
4
+
5
+ export type BreadcrumbsDivider = "slash" | "chevron";
6
+
7
+ export interface BreadcrumbsProps {
8
+ /** Separator between crumbs. */
9
+ divider?: BreadcrumbsDivider;
10
+ /** Crumb items — typically `BreadcrumbButtonBase` instances. */
11
+ children: ReactNode;
12
+ className?: string;
13
+ }
14
+
15
+ function Slash() {
16
+ return (
17
+ <span className="text-sm text-text-quaternary" aria-hidden>
18
+ /
19
+ </span>
20
+ );
21
+ }
22
+
23
+ function Chevron() {
24
+ return (
25
+ <svg
26
+ viewBox="0 0 16 16"
27
+ fill="none"
28
+ className="size-4 text-fg-quaternary"
29
+ aria-hidden
30
+ >
31
+ <path
32
+ d="m6 12 4-4-4-4"
33
+ stroke="currentColor"
34
+ strokeWidth="1.333"
35
+ strokeLinecap="round"
36
+ strokeLinejoin="round"
37
+ />
38
+ </svg>
39
+ );
40
+ }
41
+
42
+ export function Breadcrumbs({
43
+ divider = "slash",
44
+ children,
45
+ className,
46
+ }: BreadcrumbsProps) {
47
+ const items = Children.toArray(children).filter(isValidElement);
48
+ const Sep = divider === "chevron" ? Chevron : Slash;
49
+
50
+ return (
51
+ <nav aria-label="Breadcrumb" className={clsx("font-body", className)}>
52
+ <ol className="flex items-center gap-md">
53
+ {items.map((child, index) => (
54
+ <li key={child.key ?? index} className="flex items-center gap-md">
55
+ {index > 0 ? <Sep /> : null}
56
+ {child}
57
+ </li>
58
+ ))}
59
+ </ol>
60
+ </nav>
61
+ );
62
+ }
@@ -0,0 +1,2 @@
1
+ export { Breadcrumbs } from "./Breadcrumbs";
2
+ export type { BreadcrumbsProps, BreadcrumbsDivider } from "./Breadcrumbs";
@@ -0,0 +1,71 @@
1
+ import type { ButtonHTMLAttributes } from "react";
2
+ import clsx from "clsx";
3
+
4
+ export type ButtonHierarchy =
5
+ | "Primary"
6
+ | "Secondary"
7
+ | "Tertiary"
8
+ | "Link color"
9
+ | "Link gray";
10
+ export type ButtonSize = "xs" | "sm" | "md" | "lg" | "xl";
11
+
12
+ export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
13
+ hierarchy?: ButtonHierarchy;
14
+ size?: ButtonSize;
15
+ loading?: boolean;
16
+ }
17
+
18
+ // NOTE: this is a placeholder implementation to verify the build/Storybook
19
+ // pipeline end-to-end. The figma-to-react skill should overwrite this with
20
+ // the full per-hierarchy/per-size token mapping from design.md §3 (all 5
21
+ // sizes, all 5 hierarchies, skeuomorphic shadow stack on Primary/Secondary).
22
+ //
23
+ // Padding values below use Tailwind arbitrary values ([14px], [10px], etc)
24
+ // rather than the spacing-* scale on purpose — design.md §3 confirms the
25
+ // real Figma component uses raw px at md/lg/xl, not the nearest token.
26
+ // Don't "fix" these to spacing-md/spacing-lg; that would silently diverge
27
+ // from the source design.
28
+
29
+ const hierarchyClasses: Record<ButtonHierarchy, string> = {
30
+ Primary:
31
+ "bg-brand-solid text-white border-2 border-white/[0.12] hover:bg-bg-brand-solid-hover",
32
+ Secondary: "bg-bg-primary text-text-secondary border border-border-primary",
33
+ Tertiary: "bg-transparent text-text-tertiary border-0",
34
+ "Link color": "bg-transparent text-text-brand-secondary border-0 p-0",
35
+ "Link gray": "bg-transparent text-text-tertiary border-0 p-0",
36
+ };
37
+
38
+ const sizeClasses: Record<ButtonSize, string> = {
39
+ xs: "px-[10px] py-sm text-xs",
40
+ sm: "px-lg py-md text-xs",
41
+ md: "px-[14px] py-[10px] text-sm",
42
+ lg: "px-xl py-[10px] text-md",
43
+ xl: "px-[18px] py-lg text-md",
44
+ };
45
+
46
+ export function Button({
47
+ hierarchy = "Primary",
48
+ size = "md",
49
+ loading = false,
50
+ disabled,
51
+ className,
52
+ children,
53
+ ...rest
54
+ }: ButtonProps) {
55
+ return (
56
+ <button
57
+ className={clsx(
58
+ "font-body font-semibold rounded-md cursor-pointer transition-colors",
59
+ "disabled:opacity-50 disabled:cursor-not-allowed",
60
+ hierarchyClasses[hierarchy],
61
+ sizeClasses[size],
62
+ className,
63
+ )}
64
+ disabled={disabled || loading}
65
+ aria-disabled={disabled || loading}
66
+ {...rest}
67
+ >
68
+ {loading ? "Loading…" : children}
69
+ </button>
70
+ );
71
+ }
@@ -0,0 +1,2 @@
1
+ export { Button } from "./Button";
2
+ export type { ButtonProps } from "./Button";
@@ -0,0 +1,54 @@
1
+ import type { ButtonHTMLAttributes } from "react";
2
+ import clsx from "clsx";
3
+
4
+ export type ButtonCloseXSize = "sm" | "md" | "lg";
5
+
6
+ export interface ButtonCloseXProps
7
+ extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, "size"> {
8
+ size?: ButtonCloseXSize;
9
+ /** Use the light-on-dark treatment (Figma `Dark background=True`). */
10
+ onDark?: boolean;
11
+ /** Accessible label (defaults to "Close"). */
12
+ label?: string;
13
+ }
14
+
15
+ const sizeClass: Record<ButtonCloseXSize, string> = {
16
+ sm: "p-xs", // 4px
17
+ md: "p-sm", // 6px
18
+ lg: "p-md", // 8px
19
+ };
20
+
21
+ export function ButtonCloseX({
22
+ size = "md",
23
+ onDark = false,
24
+ label = "Close",
25
+ className,
26
+ ...rest
27
+ }: ButtonCloseXProps) {
28
+ return (
29
+ <button
30
+ type="button"
31
+ aria-label={label}
32
+ className={clsx(
33
+ "inline-flex items-center justify-center rounded-md transition-colors",
34
+ onDark
35
+ ? "text-fg-white hover:bg-white/10"
36
+ : "text-fg-quaternary hover:bg-bg-primary-hover hover:text-fg-quaternary-hover",
37
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-brand focus-visible:ring-offset-2 focus-visible:ring-offset-bg-primary",
38
+ sizeClass[size],
39
+ className,
40
+ )}
41
+ {...rest}
42
+ >
43
+ <svg viewBox="0 0 20 20" fill="none" className="size-5" aria-hidden>
44
+ <path
45
+ d="m15 5-10 10M5 5l10 10"
46
+ stroke="currentColor"
47
+ strokeWidth="1.667"
48
+ strokeLinecap="round"
49
+ strokeLinejoin="round"
50
+ />
51
+ </svg>
52
+ </button>
53
+ );
54
+ }
@@ -0,0 +1,2 @@
1
+ export { ButtonCloseX } from "./ButtonCloseX";
2
+ export type { ButtonCloseXProps, ButtonCloseXSize } from "./ButtonCloseX";
@@ -0,0 +1,67 @@
1
+ import type { ButtonHTMLAttributes } from "react";
2
+ import clsx from "clsx";
3
+
4
+ export type ButtonDestructiveHierarchy =
5
+ | "Primary"
6
+ | "Secondary"
7
+ | "Tertiary"
8
+ | "Link";
9
+ export type ButtonDestructiveSize = "xs" | "sm" | "md" | "lg" | "xl";
10
+
11
+ export interface ButtonDestructiveProps
12
+ extends ButtonHTMLAttributes<HTMLButtonElement> {
13
+ hierarchy?: ButtonDestructiveHierarchy;
14
+ size?: ButtonDestructiveSize;
15
+ loading?: boolean;
16
+ }
17
+
18
+ // Destructive palette (design.md §3 / Figma Button destructive 6218:85578).
19
+ // Primary/Secondary carry the skeuomorphic shadow stack; focus ring is the
20
+ // error ring (border-error).
21
+ const hierarchyClasses: Record<ButtonDestructiveHierarchy, string> = {
22
+ Primary:
23
+ "bg-error-solid text-white border-2 border-white/[0.12] shadow-skeuomorphic hover:bg-error-solid-hover",
24
+ Secondary:
25
+ "bg-bg-primary text-text-error-primary border border-border-error-subtle shadow-skeuomorphic hover:bg-bg-error-primary",
26
+ Tertiary:
27
+ "bg-transparent text-text-error-primary border-0 hover:bg-bg-error-primary",
28
+ Link: "bg-transparent text-text-error-primary border-0 p-0 hover:text-text-error-primary",
29
+ };
30
+
31
+ // Padding mirrors Button.tsx — raw px at md/lg/xl per design.md §3, not the
32
+ // nearest spacing token. Don't "fix" these.
33
+ const sizeClasses: Record<ButtonDestructiveSize, string> = {
34
+ xs: "px-[10px] py-sm text-xs",
35
+ sm: "px-lg py-md text-xs",
36
+ md: "px-[14px] py-[10px] text-sm",
37
+ lg: "px-xl py-[10px] text-md",
38
+ xl: "px-[18px] py-lg text-md",
39
+ };
40
+
41
+ export function ButtonDestructive({
42
+ hierarchy = "Primary",
43
+ size = "md",
44
+ loading = false,
45
+ disabled,
46
+ className,
47
+ children,
48
+ ...rest
49
+ }: ButtonDestructiveProps) {
50
+ return (
51
+ <button
52
+ className={clsx(
53
+ "font-body font-semibold rounded-md cursor-pointer transition-colors",
54
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-error focus-visible:ring-offset-2 focus-visible:ring-offset-bg-primary",
55
+ "disabled:opacity-50 disabled:cursor-not-allowed",
56
+ hierarchyClasses[hierarchy],
57
+ hierarchy === "Link" ? "" : sizeClasses[size],
58
+ className,
59
+ )}
60
+ disabled={disabled || loading}
61
+ aria-disabled={disabled || loading}
62
+ {...rest}
63
+ >
64
+ {loading ? "Loading…" : children}
65
+ </button>
66
+ );
67
+ }
@@ -0,0 +1,6 @@
1
+ export { ButtonDestructive } from "./ButtonDestructive";
2
+ export type {
3
+ ButtonDestructiveProps,
4
+ ButtonDestructiveHierarchy,
5
+ ButtonDestructiveSize,
6
+ } from "./ButtonDestructive";
@@ -0,0 +1,28 @@
1
+ import type { ReactNode } from "react";
2
+ import clsx from "clsx";
3
+
4
+ export interface ButtonGroupProps {
5
+ /** Segments — typically `ButtonGroupSegment` instances. */
6
+ children: ReactNode;
7
+ className?: string;
8
+ }
9
+
10
+ /**
11
+ * Segmented-control wrapper. Supplies the shared outer border, rounded ends,
12
+ * and the dividers between segments — segments themselves render borderless.
13
+ */
14
+ export function ButtonGroup({ children, className }: ButtonGroupProps) {
15
+ return (
16
+ <div
17
+ role="group"
18
+ className={clsx(
19
+ "inline-flex overflow-hidden rounded-md border border-border-primary bg-bg-primary shadow-xs",
20
+ "[&>*:first-child]:rounded-l-md [&>*:last-child]:rounded-r-md",
21
+ "[&>*+*]:border-l [&>*+*]:border-border-primary",
22
+ className,
23
+ )}
24
+ >
25
+ {children}
26
+ </div>
27
+ );
28
+ }
@@ -0,0 +1,2 @@
1
+ export { ButtonGroup } from "./ButtonGroup";
2
+ export type { ButtonGroupProps } from "./ButtonGroup";
@@ -0,0 +1,54 @@
1
+ import type { ButtonHTMLAttributes, ReactNode } from "react";
2
+ import clsx from "clsx";
3
+
4
+ export type ButtonGroupSegmentSize = "sm" | "md";
5
+
6
+ export interface ButtonGroupSegmentProps
7
+ extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, "size"> {
8
+ size?: ButtonGroupSegmentSize;
9
+ /** Active/pressed segment. */
10
+ current?: boolean;
11
+ /** Leading icon (or the only content for an icon-only segment). */
12
+ icon?: ReactNode;
13
+ /** Leading success dot. */
14
+ dot?: boolean;
15
+ }
16
+
17
+ const sizeClasses: Record<ButtonGroupSegmentSize, string> = {
18
+ sm: "px-lg py-md text-sm",
19
+ md: "px-[14px] py-[10px] text-sm",
20
+ };
21
+
22
+ export function ButtonGroupSegment({
23
+ size = "sm",
24
+ current = false,
25
+ icon,
26
+ dot = false,
27
+ children,
28
+ className,
29
+ ...rest
30
+ }: ButtonGroupSegmentProps) {
31
+ return (
32
+ <button
33
+ type="button"
34
+ aria-pressed={current}
35
+ className={clsx(
36
+ "relative inline-flex items-center gap-md font-body font-semibold transition-colors",
37
+ "focus-visible:outline-none focus-visible:z-10 focus-visible:ring-2 focus-visible:ring-border-brand",
38
+ "disabled:opacity-50 disabled:cursor-not-allowed",
39
+ current
40
+ ? "bg-bg-secondary text-text-secondary-hover"
41
+ : "bg-bg-primary text-text-secondary hover:bg-bg-primary-hover",
42
+ sizeClasses[size],
43
+ className,
44
+ )}
45
+ {...rest}
46
+ >
47
+ {dot ? (
48
+ <span className="size-2 shrink-0 rounded-full bg-fg-success-secondary" aria-hidden />
49
+ ) : null}
50
+ {icon ? <span className="shrink-0">{icon}</span> : null}
51
+ {children}
52
+ </button>
53
+ );
54
+ }
@@ -0,0 +1,5 @@
1
+ export { ButtonGroupSegment } from "./ButtonGroupSegment";
2
+ export type {
3
+ ButtonGroupSegmentProps,
4
+ ButtonGroupSegmentSize,
5
+ } from "./ButtonGroupSegment";
@@ -0,0 +1,67 @@
1
+ import type { ButtonHTMLAttributes, ReactNode } from "react";
2
+ import clsx from "clsx";
3
+
4
+ export type ButtonUtilitySize = "xs" | "sm";
5
+ export type ButtonUtilityVariant = "outline" | "ghost";
6
+
7
+ export interface ButtonUtilityProps
8
+ extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, "size"> {
9
+ /** Required icon glyph. */
10
+ icon: ReactNode;
11
+ /** Accessible label (also used as the tooltip when `tooltip` is true). */
12
+ label: string;
13
+ size?: ButtonUtilitySize;
14
+ variant?: ButtonUtilityVariant;
15
+ /** Show the hover/focus tooltip bubble. */
16
+ tooltip?: boolean;
17
+ }
18
+
19
+ const sizeClasses: Record<ButtonUtilitySize, string> = {
20
+ xs: "p-xs rounded-sm", // 4px / radius-sm
21
+ sm: "p-sm rounded-md", // 6px / radius-md
22
+ };
23
+
24
+ const variantClasses: Record<ButtonUtilityVariant, string> = {
25
+ outline:
26
+ "bg-bg-primary border border-border-primary text-fg-quaternary shadow-skeuomorphic hover:bg-bg-primary-hover hover:text-fg-quaternary-hover",
27
+ ghost:
28
+ "bg-transparent text-fg-quaternary hover:bg-bg-primary-hover hover:text-fg-quaternary-hover",
29
+ };
30
+
31
+ export function ButtonUtility({
32
+ icon,
33
+ label,
34
+ size = "sm",
35
+ variant = "outline",
36
+ tooltip = false,
37
+ className,
38
+ ...rest
39
+ }: ButtonUtilityProps) {
40
+ return (
41
+ <span className="group relative inline-flex">
42
+ <button
43
+ type="button"
44
+ aria-label={label}
45
+ className={clsx(
46
+ "inline-flex items-center justify-center transition-colors",
47
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-brand focus-visible:ring-offset-2 focus-visible:ring-offset-bg-primary",
48
+ "disabled:opacity-50 disabled:cursor-not-allowed",
49
+ variantClasses[variant],
50
+ sizeClasses[size],
51
+ className,
52
+ )}
53
+ {...rest}
54
+ >
55
+ <span className="[&>svg]:size-5">{icon}</span>
56
+ </button>
57
+ {tooltip ? (
58
+ <span
59
+ role="tooltip"
60
+ className="pointer-events-none absolute bottom-full left-1/2 mb-xs -translate-x-1/2 whitespace-nowrap rounded-md bg-bg-primary-solid px-md py-xs text-xs font-semibold text-text-white opacity-0 shadow-lg transition-opacity group-hover:opacity-100 group-focus-within:opacity-100"
61
+ >
62
+ {label}
63
+ </span>
64
+ ) : null}
65
+ </span>
66
+ );
67
+ }
@@ -0,0 +1,6 @@
1
+ export { ButtonUtility } from "./ButtonUtility";
2
+ export type {
3
+ ButtonUtilityProps,
4
+ ButtonUtilitySize,
5
+ ButtonUtilityVariant,
6
+ } from "./ButtonUtility";
@@ -0,0 +1,82 @@
1
+ import type { ReactNode } from "react";
2
+ import clsx from "clsx";
3
+
4
+ export interface CalendarCellProps {
5
+ /** Day-of-month number. */
6
+ date: string | number;
7
+ /** Event chips for this day — typically `CalendarEvent` instances. */
8
+ children?: ReactNode;
9
+ /** "+N more" overflow count shown beneath the events. */
10
+ moreCount?: number;
11
+ /** Other-month / disabled styling. */
12
+ muted?: boolean;
13
+ /** Marks today (date number in brand). */
14
+ current?: boolean;
15
+ /** Renders a hover "+" add button bottom-right. */
16
+ onAdd?: () => void;
17
+ className?: string;
18
+ }
19
+
20
+ function PlusIcon() {
21
+ return (
22
+ <svg viewBox="0 0 20 20" fill="none" className="size-4" aria-hidden>
23
+ <path
24
+ d="M10 4.167v11.666M4.167 10h11.666"
25
+ stroke="currentColor"
26
+ strokeWidth="1.667"
27
+ strokeLinecap="round"
28
+ strokeLinejoin="round"
29
+ />
30
+ </svg>
31
+ );
32
+ }
33
+
34
+ /** A single day cell in the month grid. Composes CalendarEvent chips. */
35
+ export function CalendarCell({
36
+ date,
37
+ children,
38
+ moreCount,
39
+ muted = false,
40
+ current = false,
41
+ onAdd,
42
+ className,
43
+ }: CalendarCellProps) {
44
+ return (
45
+ <div
46
+ className={clsx(
47
+ "group relative flex min-h-[120px] flex-col gap-xs bg-bg-primary p-md font-body",
48
+ muted && "bg-bg-secondary",
49
+ className,
50
+ )}
51
+ >
52
+ <span
53
+ className={clsx(
54
+ "text-xs font-semibold",
55
+ current
56
+ ? "text-text-brand-secondary"
57
+ : muted
58
+ ? "text-text-quaternary"
59
+ : "text-text-secondary",
60
+ )}
61
+ >
62
+ {date}
63
+ </span>
64
+ {children ? <div className="flex flex-col gap-xs">{children}</div> : null}
65
+ {moreCount && moreCount > 0 ? (
66
+ <span className="text-xs font-medium text-text-tertiary">
67
+ {moreCount} more…
68
+ </span>
69
+ ) : null}
70
+ {onAdd ? (
71
+ <button
72
+ type="button"
73
+ onClick={onAdd}
74
+ aria-label="Add event"
75
+ className="absolute bottom-md right-md hidden rounded-md border border-border-primary bg-bg-primary p-xs text-fg-quaternary shadow-xs transition-colors hover:bg-bg-primary-hover group-hover:flex focus-visible:flex focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-brand"
76
+ >
77
+ <PlusIcon />
78
+ </button>
79
+ ) : null}
80
+ </div>
81
+ );
82
+ }
@@ -0,0 +1,2 @@
1
+ export { CalendarCell } from "./CalendarCell";
2
+ export type { CalendarCellProps } from "./CalendarCell";