@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,124 @@
1
+ import { type HTMLAttributes, type ReactNode } from "react";
2
+ import clsx from "clsx";
3
+
4
+ export type NavAccountCardVariant = "simple" | "card";
5
+
6
+ export interface NavAccountCardProps
7
+ extends Omit<HTMLAttributes<HTMLDivElement>, "title"> {
8
+ /** `simple` = inline row + sign-out button · `card` = boxed trigger that opens a menu. */
9
+ variant?: NavAccountCardVariant;
10
+ /** card only — whether the dropdown menu is shown. */
11
+ open?: boolean;
12
+ avatar?: ReactNode;
13
+ name?: ReactNode;
14
+ email?: ReactNode;
15
+ /** card only — toggles the dropdown (fires on trigger click). */
16
+ onToggle?: () => void;
17
+ /** simple only — sign-out button handler. */
18
+ onSignOut?: () => void;
19
+ /**
20
+ * card + open — dropdown content. Compose `NavAccountCardMenuItem` rows,
21
+ * dividers and an add-account / sign-out footer here.
22
+ */
23
+ menu?: ReactNode;
24
+ }
25
+
26
+ const ChevronSelector = () => (
27
+ <svg viewBox="0 0 16 16" fill="none" className="size-4" aria-hidden>
28
+ <path d="M5 6l3-3 3 3M5 10l3 3 3-3" stroke="currentColor" strokeWidth="1.33" strokeLinecap="round" strokeLinejoin="round" />
29
+ </svg>
30
+ );
31
+
32
+ const LogOut = () => (
33
+ <svg viewBox="0 0 16 16" fill="none" className="size-4" aria-hidden>
34
+ <path
35
+ d="M10.67 11.33 14 8m0 0-3.33-3.33M14 8H6M6 2H4.67c-.93 0-1.4 0-1.76.18-.31.16-.57.42-.73.73C2 3.27 2 3.73 2 4.67v6.66c0 .94 0 1.4.18 1.76.16.31.42.57.73.73.36.18.83.18 1.76.18H6"
36
+ stroke="currentColor"
37
+ strokeWidth="1.33"
38
+ strokeLinecap="round"
39
+ strokeLinejoin="round"
40
+ />
41
+ </svg>
42
+ );
43
+
44
+ const AvatarLabel = ({ avatar, name, email }: { avatar?: ReactNode; name?: ReactNode; email?: ReactNode }) => (
45
+ <div className="flex min-w-0 flex-1 items-center gap-md">
46
+ {avatar && <span className="shrink-0">{avatar}</span>}
47
+ <div className="flex min-w-0 flex-col text-left">
48
+ <span className="truncate text-sm font-semibold text-text-primary">{name}</span>
49
+ <span className="truncate text-sm text-text-tertiary">{email}</span>
50
+ </div>
51
+ </div>
52
+ );
53
+
54
+ /**
55
+ * Account switcher for the bottom of a sidebar. `simple` renders an inline row
56
+ * with a sign-out button; `card` renders a boxed trigger that, when `open`,
57
+ * reveals a dropdown (the `menu` slot — compose `NavAccountCardMenuItem` rows).
58
+ *
59
+ * The active account is marked with `bg-brand-solid` (the radio inside the
60
+ * account menu items). Note: Figma opens the desktop menu as a right-side
61
+ * flyout; this opens it above the trigger (`bottom-full`) — a layout
62
+ * simplification (see figma-map). Width defaults to 280px; override via
63
+ * `className` for mobile (256px).
64
+ */
65
+ export function NavAccountCard({
66
+ variant = "card",
67
+ open = false,
68
+ avatar,
69
+ name,
70
+ email,
71
+ onToggle,
72
+ onSignOut,
73
+ menu,
74
+ className,
75
+ ...rest
76
+ }: NavAccountCardProps) {
77
+ if (variant === "simple") {
78
+ return (
79
+ <div
80
+ className={clsx(
81
+ "relative flex w-[280px] items-start gap-xl border-t border-border-secondary px-md pt-2xl",
82
+ className,
83
+ )}
84
+ {...rest}
85
+ >
86
+ <AvatarLabel avatar={avatar} name={name} email={email} />
87
+ <button
88
+ type="button"
89
+ onClick={onSignOut}
90
+ aria-label="Sign out"
91
+ className="absolute right-0 top-[15px] flex items-center justify-center rounded-sm p-sm text-fg-quaternary transition-colors hover:text-fg-quaternary-hover"
92
+ >
93
+ <LogOut />
94
+ </button>
95
+ </div>
96
+ );
97
+ }
98
+
99
+ return (
100
+ <div className={clsx("relative w-[280px]", className)} {...rest}>
101
+ <button
102
+ type="button"
103
+ onClick={onToggle}
104
+ className="relative flex w-full items-start gap-xl rounded-xl border border-border-secondary bg-bg-primary-alt p-lg text-left shadow-xs"
105
+ >
106
+ <AvatarLabel avatar={avatar} name={name} email={email} />
107
+ <span
108
+ className={clsx(
109
+ "absolute right-[7px] top-[7px] flex items-center justify-center rounded-sm p-sm text-fg-quaternary",
110
+ open && "bg-bg-primary-hover",
111
+ )}
112
+ >
113
+ <ChevronSelector />
114
+ </span>
115
+ </button>
116
+
117
+ {open && (
118
+ <div className="absolute bottom-full left-0 z-10 mb-2 w-full overflow-hidden rounded-xl border border-border-secondary-alt bg-bg-secondary-alt shadow-lg">
119
+ {menu}
120
+ </div>
121
+ )}
122
+ </div>
123
+ );
124
+ }
@@ -0,0 +1,2 @@
1
+ export { NavAccountCard } from "./NavAccountCard";
2
+ export type { NavAccountCardProps, NavAccountCardVariant } from "./NavAccountCard";
@@ -0,0 +1,101 @@
1
+ import { type ButtonHTMLAttributes, type ReactNode } from "react";
2
+ import clsx from "clsx";
3
+
4
+ export type NavAccountCardMenuItemType = "menu-item" | "account";
5
+
6
+ export interface NavAccountCardMenuItemProps
7
+ extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, "name" | "type"> {
8
+ /** `menu-item` = icon + label (+ shortcut) · `account` = avatar + name/email + radio. */
9
+ type?: NavAccountCardMenuItemType;
10
+ /** Marks the row as the active account / current item (radio filled, hover bg). */
11
+ current?: boolean;
12
+ /** menu-item: leading icon (20px). */
13
+ icon?: ReactNode;
14
+ /** menu-item: row label. */
15
+ label?: ReactNode;
16
+ /** menu-item: trailing keyboard-shortcut chip. */
17
+ shortcut?: ReactNode;
18
+ /** account: avatar slot (40px). */
19
+ avatar?: ReactNode;
20
+ /** account: display name. */
21
+ name?: ReactNode;
22
+ /** account: secondary line (email). */
23
+ email?: ReactNode;
24
+ }
25
+
26
+ /**
27
+ * A single row inside `NavAccountCard`'s dropdown. Two shapes:
28
+ * - `menu-item` — icon + label + optional shortcut chip (View profile, Settings…).
29
+ * - `account` — avatar + name/email with a radio indicator; `current` fills the
30
+ * radio with `bg-brand-solid` (the active-account marker).
31
+ */
32
+ export function NavAccountCardMenuItem({
33
+ type = "menu-item",
34
+ current = false,
35
+ icon,
36
+ label,
37
+ shortcut,
38
+ avatar,
39
+ name,
40
+ email,
41
+ className,
42
+ ...rest
43
+ }: NavAccountCardMenuItemProps) {
44
+ return (
45
+ <button
46
+ type="button"
47
+ className={clsx(
48
+ "flex w-full items-center px-sm text-left",
49
+ className,
50
+ )}
51
+ {...rest}
52
+ >
53
+ <div
54
+ className={clsx(
55
+ "flex min-w-0 flex-1 items-center gap-lg overflow-hidden rounded-sm p-md transition-colors",
56
+ current ? "bg-bg-primary-hover" : "hover:bg-bg-primary-hover",
57
+ )}
58
+ >
59
+ {type === "menu-item" ? (
60
+ <>
61
+ <div className="flex min-w-0 flex-1 items-center gap-md">
62
+ {icon && (
63
+ <span className="flex size-5 shrink-0 items-center justify-center text-fg-quaternary [&>svg]:size-5">
64
+ {icon}
65
+ </span>
66
+ )}
67
+ <span className="min-w-0 flex-1 text-sm font-semibold text-text-secondary">
68
+ {label}
69
+ </span>
70
+ </div>
71
+ {shortcut && (
72
+ <span className="shrink-0 rounded-xs border border-border-secondary px-xs py-px text-xs font-medium text-text-tertiary">
73
+ {shortcut}
74
+ </span>
75
+ )}
76
+ </>
77
+ ) : (
78
+ <>
79
+ <div className="flex min-w-0 flex-1 items-center gap-md">
80
+ {avatar && <span className="shrink-0">{avatar}</span>}
81
+ <span className="flex min-w-0 flex-col">
82
+ <span className="truncate text-sm font-semibold text-text-primary">{name}</span>
83
+ <span className="truncate text-sm text-text-tertiary">{email}</span>
84
+ </span>
85
+ </div>
86
+ <span
87
+ className={clsx(
88
+ "flex size-4 shrink-0 items-center justify-center rounded-full",
89
+ current
90
+ ? "bg-bg-brand-solid"
91
+ : "border border-border-primary",
92
+ )}
93
+ >
94
+ {current && <span className="size-1.5 rounded-full bg-fg-white" />}
95
+ </span>
96
+ </>
97
+ )}
98
+ </div>
99
+ </button>
100
+ );
101
+ }
@@ -0,0 +1,5 @@
1
+ export { NavAccountCardMenuItem } from "./NavAccountCardMenuItem";
2
+ export type {
3
+ NavAccountCardMenuItemProps,
4
+ NavAccountCardMenuItemType,
5
+ } from "./NavAccountCardMenuItem";
@@ -0,0 +1,50 @@
1
+ import { type ButtonHTMLAttributes, type ReactNode } from "react";
2
+ import clsx from "clsx";
3
+
4
+ export interface NavButtonProps
5
+ extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, "children"> {
6
+ /** Active route — applies the selected (`bg-secondary`) background. */
7
+ current?: boolean;
8
+ /** Render only the leading icon (square button). */
9
+ iconOnly?: boolean;
10
+ /** Leading icon (20px). */
11
+ icon?: ReactNode;
12
+ /** Label text (hidden when `iconOnly`). */
13
+ children?: ReactNode;
14
+ }
15
+
16
+ /**
17
+ * Header-nav button (the horizontal top-bar variant, distinct from the sidebar
18
+ * `NavItemBase`). Pill shape; `current` marks the active route. Focus ring uses
19
+ * the brand focus colour.
20
+ */
21
+ export function NavButton({
22
+ current = false,
23
+ iconOnly = false,
24
+ icon,
25
+ children,
26
+ className,
27
+ type = "button",
28
+ ...rest
29
+ }: NavButtonProps) {
30
+ return (
31
+ <button
32
+ type={type}
33
+ className={clsx(
34
+ "inline-flex items-center justify-center gap-xs overflow-hidden rounded-sm text-sm font-semibold text-text-secondary outline-none transition-colors",
35
+ "focus-visible:ring-2 focus-visible:ring-utility-brand-500 focus-visible:ring-offset-2",
36
+ iconOnly ? "p-md" : "px-md py-sm",
37
+ current ? "bg-bg-secondary hover:bg-bg-secondary-hover" : "hover:bg-bg-primary-hover",
38
+ className,
39
+ )}
40
+ {...rest}
41
+ >
42
+ {icon && (
43
+ <span className="flex size-5 shrink-0 items-center justify-center [&>svg]:size-5">
44
+ {icon}
45
+ </span>
46
+ )}
47
+ {!iconOnly && <span className="px-xxs">{children}</span>}
48
+ </button>
49
+ );
50
+ }
@@ -0,0 +1,2 @@
1
+ export { NavButton } from "./NavButton";
2
+ export type { NavButtonProps } from "./NavButton";
@@ -0,0 +1,82 @@
1
+ import { type HTMLAttributes, type ReactNode } from "react";
2
+ import clsx from "clsx";
3
+
4
+ export interface NavFeaturedCardProps
5
+ extends Omit<HTMLAttributes<HTMLDivElement>, "title"> {
6
+ /** Featured-icon / media slot rendered at the top. */
7
+ icon?: ReactNode;
8
+ title?: ReactNode;
9
+ subtitle?: ReactNode;
10
+ /** Body content — progress bar, list, QR code, input, etc. */
11
+ children?: ReactNode;
12
+ /** CTA row — compose Button(s) / link buttons. */
13
+ action?: ReactNode;
14
+ /** Bordered surface (`bg-primary` + border) vs subtle (`bg-secondary`). */
15
+ bordered?: boolean;
16
+ /** Renders an x-close button top-right. */
17
+ onClose?: () => void;
18
+ }
19
+
20
+ const XClose = () => (
21
+ <svg viewBox="0 0 20 20" fill="none" className="size-5" aria-hidden>
22
+ <path d="M15 5 5 15M5 5l10 10" stroke="currentColor" strokeWidth="1.67" strokeLinecap="round" strokeLinejoin="round" />
23
+ </svg>
24
+ );
25
+
26
+ /**
27
+ * Featured card for the bottom of a sidebar — a generic shell, not 13 variants.
28
+ * The Figma `Type` set (Progress bar, Upgrade CTA, Message, Current projects,
29
+ * QR code, …) is expressed by filling the slots: `icon` / `title` / `subtitle`
30
+ * for the header, `children` for the body (progress bar, list, QR, input…), and
31
+ * `action` for the CTA row. See the stories for the 12 type recipes.
32
+ */
33
+ export function NavFeaturedCard({
34
+ icon,
35
+ title,
36
+ subtitle,
37
+ children,
38
+ action,
39
+ bordered = false,
40
+ onClose,
41
+ className,
42
+ ...rest
43
+ }: NavFeaturedCardProps) {
44
+ const hasHeader = icon || title || subtitle;
45
+ return (
46
+ <div
47
+ className={clsx(
48
+ "relative flex w-[248px] flex-col gap-xl rounded-xl p-xl",
49
+ bordered ? "border border-border-secondary bg-bg-primary" : "bg-bg-secondary",
50
+ className,
51
+ )}
52
+ {...rest}
53
+ >
54
+ {onClose && (
55
+ <button
56
+ type="button"
57
+ onClick={onClose}
58
+ aria-label="Dismiss"
59
+ className="absolute right-1 top-1 flex size-9 items-center justify-center rounded-md text-fg-quaternary transition-colors hover:text-fg-quaternary-hover"
60
+ >
61
+ <XClose />
62
+ </button>
63
+ )}
64
+
65
+ {hasHeader && (
66
+ <div className="flex flex-col gap-xs">
67
+ {icon && <div className="shrink-0">{icon}</div>}
68
+ {(title || subtitle) && (
69
+ <div className="flex flex-col gap-xs pr-3xl">
70
+ {title && <p className="text-sm font-semibold text-text-primary">{title}</p>}
71
+ {subtitle && <p className="text-sm text-text-tertiary">{subtitle}</p>}
72
+ </div>
73
+ )}
74
+ </div>
75
+ )}
76
+
77
+ {children}
78
+
79
+ {action && <div className="flex items-center gap-lg">{action}</div>}
80
+ </div>
81
+ );
82
+ }
@@ -0,0 +1,2 @@
1
+ export { NavFeaturedCard } from "./NavFeaturedCard";
2
+ export type { NavFeaturedCardProps } from "./NavFeaturedCard";
@@ -0,0 +1,79 @@
1
+ import { type ButtonHTMLAttributes, type ReactNode } from "react";
2
+ import clsx from "clsx";
3
+
4
+ export interface NavItemBaseProps
5
+ extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, "children"> {
6
+ /** Active route — selected (`bg-secondary`) background. */
7
+ current?: boolean;
8
+ /** Leading icon (20px). */
9
+ icon?: ReactNode;
10
+ label?: ReactNode;
11
+ /** Leading status dot (8px, success green). */
12
+ dot?: boolean;
13
+ /** Trailing count badge — pass a number/string. */
14
+ badge?: ReactNode;
15
+ /** Trailing chevron (for expandable groups). */
16
+ trailingChevron?: boolean;
17
+ }
18
+
19
+ const ChevronDown = () => (
20
+ <svg viewBox="0 0 16 16" fill="none" className="size-4" aria-hidden>
21
+ <path d="M4 6l4 4 4-4" stroke="currentColor" strokeWidth="1.33" strokeLinecap="round" strokeLinejoin="round" />
22
+ </svg>
23
+ );
24
+
25
+ /**
26
+ * Base sidebar nav link (272px). `current` selects it; optional leading `dot`,
27
+ * leading `icon`, trailing count `badge`, and `trailingChevron`. Brand focus ring.
28
+ */
29
+ export function NavItemBase({
30
+ current = false,
31
+ icon,
32
+ label,
33
+ dot = false,
34
+ badge,
35
+ trailingChevron = false,
36
+ className,
37
+ type = "button",
38
+ ...rest
39
+ }: NavItemBaseProps) {
40
+ return (
41
+ <button
42
+ type={type}
43
+ className={clsx(
44
+ "flex w-[272px] items-center rounded-sm outline-none focus-visible:ring-2 focus-visible:ring-utility-brand-500 focus-visible:ring-offset-2",
45
+ className,
46
+ )}
47
+ {...rest}
48
+ >
49
+ <div
50
+ className={clsx(
51
+ "flex max-h-9 flex-1 items-center gap-lg rounded-sm p-md transition-colors",
52
+ current ? "bg-bg-secondary" : "hover:bg-bg-primary-hover",
53
+ )}
54
+ >
55
+ <div className="flex min-w-0 flex-1 items-center gap-md">
56
+ {dot && <span className="size-2 shrink-0 rounded-full bg-fg-success-secondary" />}
57
+ {icon && (
58
+ <span className="flex size-5 shrink-0 items-center justify-center text-fg-quaternary [&>svg]:size-5">
59
+ {icon}
60
+ </span>
61
+ )}
62
+ <span className="min-w-0 flex-1 truncate text-left text-sm font-semibold text-text-secondary">
63
+ {label}
64
+ </span>
65
+ </div>
66
+ {badge != null && (
67
+ <span className="shrink-0 rounded-full border border-utility-neutral-200 bg-utility-neutral-50 px-md py-xxs text-xs font-medium text-utility-neutral-700">
68
+ {badge}
69
+ </span>
70
+ )}
71
+ {trailingChevron && (
72
+ <span className="shrink-0 text-fg-quaternary">
73
+ <ChevronDown />
74
+ </span>
75
+ )}
76
+ </div>
77
+ </button>
78
+ );
79
+ }
@@ -0,0 +1,2 @@
1
+ export { NavItemBase } from "./NavItemBase";
2
+ export type { NavItemBaseProps } from "./NavItemBase";
@@ -0,0 +1,74 @@
1
+ import { type ButtonHTMLAttributes, type ReactNode } from "react";
2
+ import clsx from "clsx";
3
+
4
+ export interface NavItemDropdownBaseProps
5
+ extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, "children"> {
6
+ /** Active group — selected (`bg-secondary`) background on the trigger. */
7
+ current?: boolean;
8
+ /** Expanded state — reveals the submenu. */
9
+ open?: boolean;
10
+ /** Trigger icon (20px). */
11
+ icon?: ReactNode;
12
+ label?: ReactNode;
13
+ /** Toggles open/closed. */
14
+ onToggle?: () => void;
15
+ /** Submenu rows (rendered when `open`) — compose indented `NavItemBase`s. */
16
+ children?: ReactNode;
17
+ }
18
+
19
+ const Chevron = ({ up }: { up?: boolean }) => (
20
+ <svg viewBox="0 0 16 16" fill="none" className="size-4" aria-hidden>
21
+ <path d={up ? "M4 10l4-4 4 4" : "M4 6l4 4 4-4"} stroke="currentColor" strokeWidth="1.33" strokeLinecap="round" strokeLinejoin="round" />
22
+ </svg>
23
+ );
24
+
25
+ /**
26
+ * Expandable sidebar nav group (272px). The trigger mirrors `NavItemBase`; when
27
+ * `open`, `children` (indented submenu rows) render below with a chevron flip.
28
+ */
29
+ export function NavItemDropdownBase({
30
+ current = false,
31
+ open = false,
32
+ icon,
33
+ label,
34
+ onToggle,
35
+ children,
36
+ className,
37
+ type = "button",
38
+ ...rest
39
+ }: NavItemDropdownBaseProps) {
40
+ return (
41
+ <div className={clsx("flex w-[272px] flex-col", className)}>
42
+ <button
43
+ type={type}
44
+ onClick={onToggle}
45
+ className="flex items-center rounded-sm outline-none focus-visible:ring-2 focus-visible:ring-utility-brand-500 focus-visible:ring-offset-2"
46
+ {...rest}
47
+ >
48
+ <div
49
+ className={clsx(
50
+ "flex max-h-9 flex-1 items-center gap-lg rounded-sm p-md transition-colors",
51
+ current ? "bg-bg-secondary" : "hover:bg-bg-primary-hover",
52
+ )}
53
+ >
54
+ <div className="flex min-w-0 flex-1 items-center gap-md">
55
+ {icon && (
56
+ <span className="flex size-5 shrink-0 items-center justify-center text-fg-quaternary [&>svg]:size-5">
57
+ {icon}
58
+ </span>
59
+ )}
60
+ <span className="min-w-0 flex-1 truncate text-left text-sm font-semibold text-text-secondary">
61
+ {label}
62
+ </span>
63
+ </div>
64
+ <span className="shrink-0 text-fg-quaternary">
65
+ <Chevron up={open} />
66
+ </span>
67
+ </div>
68
+ </button>
69
+ {open && (
70
+ <div className="flex flex-col pb-xs">{children}</div>
71
+ )}
72
+ </div>
73
+ );
74
+ }
@@ -0,0 +1,2 @@
1
+ export { NavItemDropdownBase } from "./NavItemDropdownBase";
2
+ export type { NavItemDropdownBaseProps } from "./NavItemDropdownBase";
@@ -0,0 +1,47 @@
1
+ import { type ButtonHTMLAttributes } from "react";
2
+ import clsx from "clsx";
3
+
4
+ export interface NavMenuButtonProps
5
+ extends ButtonHTMLAttributes<HTMLButtonElement> {
6
+ /** Open state — swaps the hamburger for an x-close icon. */
7
+ opened?: boolean;
8
+ }
9
+
10
+ const Menu = () => (
11
+ <svg viewBox="0 0 20 20" fill="none" className="size-5" aria-hidden>
12
+ <path d="M2.5 10h15M2.5 5h15M2.5 15h15" stroke="currentColor" strokeWidth="1.67" strokeLinecap="round" strokeLinejoin="round" />
13
+ </svg>
14
+ );
15
+
16
+ const XClose = () => (
17
+ <svg viewBox="0 0 20 20" fill="none" className="size-5" aria-hidden>
18
+ <path d="M15 5 5 15M5 5l10 10" stroke="currentColor" strokeWidth="1.67" strokeLinecap="round" strokeLinejoin="round" />
19
+ </svg>
20
+ );
21
+
22
+ /**
23
+ * Hamburger / collapse toggle for the mobile header & sidebar. Shows the
24
+ * hamburger when closed, an x-close (dimmed) when `opened`. Brand focus ring.
25
+ */
26
+ export function NavMenuButton({
27
+ opened = false,
28
+ className,
29
+ type = "button",
30
+ ...rest
31
+ }: NavMenuButtonProps) {
32
+ return (
33
+ <button
34
+ type={type}
35
+ aria-label={opened ? "Close menu" : "Open menu"}
36
+ aria-expanded={opened}
37
+ className={clsx(
38
+ "flex items-center justify-center rounded-md p-md text-fg-secondary outline-none transition-colors",
39
+ "hover:bg-bg-primary-hover focus-visible:ring-2 focus-visible:ring-utility-brand-500 focus-visible:ring-offset-2",
40
+ className,
41
+ )}
42
+ {...rest}
43
+ >
44
+ {opened ? <span className="opacity-70"><XClose /></span> : <Menu />}
45
+ </button>
46
+ );
47
+ }
@@ -0,0 +1,2 @@
1
+ export { NavMenuButton } from "./NavMenuButton";
2
+ export type { NavMenuButtonProps } from "./NavMenuButton";