@scalepad/ui 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 (273) hide show
  1. package/.ai/rules/date-handling.md +39 -0
  2. package/.ai/rules/figma-design-system.md +372 -0
  3. package/.ai/rules/figma-lm-design-system-keys.md +680 -0
  4. package/.ai/rules/file-extensions.md +13 -0
  5. package/.ai/rules/modal-confirmation-mutation.md +56 -0
  6. package/.ai/rules/react-hooks.md +29 -0
  7. package/.ai/rules/styling.md +83 -0
  8. package/AGENTS.md +37 -0
  9. package/README.md +125 -0
  10. package/figma.config.json +9 -0
  11. package/package.json +127 -0
  12. package/scripts/install-ai-rules.mjs +136 -0
  13. package/src/ThemeProvider.tsx +57 -0
  14. package/src/charts.ts +32 -0
  15. package/src/components/ActionCard/ActionCard.css.ts +60 -0
  16. package/src/components/ActionCard/ActionCard.tsx +154 -0
  17. package/src/components/ActionCard/index.ts +2 -0
  18. package/src/components/Anchor/Anchor.tsx +47 -0
  19. package/src/components/Anchor/index.ts +2 -0
  20. package/src/components/AppliedFiltersManagerBar/AppliedFiltersManagerBar.tsx +105 -0
  21. package/src/components/AppliedFiltersManagerBar/FilterBadge.css.ts +23 -0
  22. package/src/components/AppliedFiltersManagerBar/FilterBadge.tsx +50 -0
  23. package/src/components/AppliedFiltersManagerBar/index.ts +5 -0
  24. package/src/components/Badge/Badge.css.ts +72 -0
  25. package/src/components/Badge/Badge.figma.tsx +43 -0
  26. package/src/components/Badge/Badge.tsx +159 -0
  27. package/src/components/Badge/index.ts +2 -0
  28. package/src/components/BreadCrumb/BreadCrumb.tsx +62 -0
  29. package/src/components/BreadCrumb/index.ts +2 -0
  30. package/src/components/BulkActionBar/BulkActionBar.css.ts +26 -0
  31. package/src/components/BulkActionBar/BulkActionBar.tsx +164 -0
  32. package/src/components/BulkActionBar/index.ts +2 -0
  33. package/src/components/Button/Button.css.ts +272 -0
  34. package/src/components/Button/Button.figma.tsx +74 -0
  35. package/src/components/Button/Button.tsx +84 -0
  36. package/src/components/Button/index.ts +2 -0
  37. package/src/components/Charts/ChartTooltip.figma.tsx +33 -0
  38. package/src/components/Charts/ChartTooltip.tsx +101 -0
  39. package/src/components/Charts/MiniBarSparkline.tsx +75 -0
  40. package/src/components/Charts/StackedPatternBarChart.tsx +494 -0
  41. package/src/components/Charts/TrendAreaChart.css.ts +23 -0
  42. package/src/components/Charts/TrendAreaChart.tsx +210 -0
  43. package/src/components/Charts/index.ts +12 -0
  44. package/src/components/CodePanel/CodePanel.css.ts +113 -0
  45. package/src/components/CodePanel/CodePanel.tsx +121 -0
  46. package/src/components/CodePanel/index.ts +2 -0
  47. package/src/components/CommentComposer/CommentComposer.css.ts +60 -0
  48. package/src/components/CommentComposer/CommentComposer.tsx +181 -0
  49. package/src/components/CommentComposer/index.ts +2 -0
  50. package/src/components/ConfirmationModal/ConfirmationModal.tsx +149 -0
  51. package/src/components/ConfirmationModal/index.ts +2 -0
  52. package/src/components/ConfirmationTooltip/ConfirmationTooltip.tsx +132 -0
  53. package/src/components/ConfirmationTooltip/index.ts +2 -0
  54. package/src/components/DataDialog.figma.tsx +33 -0
  55. package/src/components/DataDialog.tsx +46 -0
  56. package/src/components/DataTable/DataTable.tsx +1042 -0
  57. package/src/components/DataTable/RowExpandToggle.tsx +105 -0
  58. package/src/components/DataTable/RowGroupHeader.tsx +190 -0
  59. package/src/components/DataTable/createActionsColumn.tsx +86 -0
  60. package/src/components/DataTable/index.ts +25 -0
  61. package/src/components/DatePicker/CustomRangePicker.tsx +59 -0
  62. package/src/components/DatePicker/DateInput.tsx +329 -0
  63. package/src/components/DatePicker/DateNavigator.tsx +486 -0
  64. package/src/components/DatePicker/DatePicker.tsx +242 -0
  65. package/src/components/DatePicker/MonthlyRangePicker.tsx +231 -0
  66. package/src/components/DatePicker/QuarterlyRangePicker.tsx +224 -0
  67. package/src/components/DatePicker/QuickPicksSidebar.tsx +242 -0
  68. package/src/components/DatePicker/YearlyRangePicker.tsx +171 -0
  69. package/src/components/DatePicker/index.ts +7 -0
  70. package/src/components/DatePicker/types.ts +12 -0
  71. package/src/components/DesignSystemPrimitives/FluidGrid.tsx +44 -0
  72. package/src/components/DesignSystemPrimitives/InteractivePrimitives.tsx +177 -0
  73. package/src/components/DesignSystemPrimitives/LayoutPrimitives.tsx +220 -0
  74. package/src/components/DesignSystemPrimitives/LayoutPrimitives.types.tsx +15 -0
  75. package/src/components/DesignSystemPrimitives/SurfacePrimitives.tsx +46 -0
  76. package/src/components/DesignSystemPrimitives/index.ts +55 -0
  77. package/src/components/Details/Details.css.ts +74 -0
  78. package/src/components/Details/Details.tsx +140 -0
  79. package/src/components/Details/index.ts +2 -0
  80. package/src/components/DownloadCard/DownloadCard.css.ts +22 -0
  81. package/src/components/DownloadCard/DownloadCard.tsx +63 -0
  82. package/src/components/DownloadCard/index.ts +2 -0
  83. package/src/components/Drawer/Drawer.css.ts +32 -0
  84. package/src/components/Drawer/Drawer.tsx +236 -0
  85. package/src/components/Drawer/hooks/useDetailDrawer.ts +61 -0
  86. package/src/components/Drawer/hooks/useDetailDrawerNavigation.ts +125 -0
  87. package/src/components/Drawer/hooks/useDetailDrawerNavigationContext.ts +66 -0
  88. package/src/components/EditableRichText/EditableRichText.css.ts +72 -0
  89. package/src/components/EditableRichText/EditableRichText.tsx +324 -0
  90. package/src/components/EditableRichText/index.ts +2 -0
  91. package/src/components/EditableSelect/EditableSelect.css.ts +62 -0
  92. package/src/components/EditableSelect/EditableSelect.tsx +224 -0
  93. package/src/components/EditableSelect/index.ts +2 -0
  94. package/src/components/EditableText/EditableText.tsx +377 -0
  95. package/src/components/EditableText/index.ts +2 -0
  96. package/src/components/EmptyState/EmptyState.figma.tsx +33 -0
  97. package/src/components/EmptyState/EmptyState.tsx +230 -0
  98. package/src/components/EmptyState/index.ts +2 -0
  99. package/src/components/ErrorBoundary.tsx +135 -0
  100. package/src/components/ErrorState/ErrorState.tsx +197 -0
  101. package/src/components/ErrorState/index.ts +2 -0
  102. package/src/components/FeatureCard.tsx +42 -0
  103. package/src/components/FilterMenu/FilterMenu.figma.tsx +30 -0
  104. package/src/components/FilterMenu/FilterMenu.tsx +198 -0
  105. package/src/components/FilterMenu/FilterSubMenuTypes/BooleanFilterSubmenu.tsx +46 -0
  106. package/src/components/FilterMenu/FilterSubMenuTypes/SearchableFilterSubmenu.tsx +239 -0
  107. package/src/components/FilterMenu/FilterSubMenuTypes/index.ts +8 -0
  108. package/src/components/FilterMenu/defaultFilterSchemas.ts +63 -0
  109. package/src/components/FilterMenu/helpers.ts +115 -0
  110. package/src/components/FilterMenu/index.ts +35 -0
  111. package/src/components/FilterMenu/types.ts +101 -0
  112. package/src/components/IconButton/IconButton.css.ts +272 -0
  113. package/src/components/IconButton/IconButton.figma.tsx +47 -0
  114. package/src/components/IconButton/IconButton.tsx +72 -0
  115. package/src/components/IconButton/README.md +230 -0
  116. package/src/components/IconButton/index.ts +2 -0
  117. package/src/components/InfiniteScrollSentinel.tsx +86 -0
  118. package/src/components/InfiniteScrollTrigger.tsx +78 -0
  119. package/src/components/InfoCard.figma.tsx +47 -0
  120. package/src/components/InfoCard.tsx +216 -0
  121. package/src/components/KbdHint/KbdHint.tsx +23 -0
  122. package/src/components/KbdHint/index.ts +2 -0
  123. package/src/components/LabeledField/LabeledField.tsx +21 -0
  124. package/src/components/LabeledField/index.ts +2 -0
  125. package/src/components/LookupSelect/LookupSelect.css.ts +149 -0
  126. package/src/components/LookupSelect/LookupSelect.tsx +325 -0
  127. package/src/components/LookupSelect/index.ts +2 -0
  128. package/src/components/Menu/Menu.css.ts +89 -0
  129. package/src/components/Menu/Menu.tsx +105 -0
  130. package/src/components/Menu/index.ts +2 -0
  131. package/src/components/MessageBox/MessageBox.tsx +168 -0
  132. package/src/components/MessageBox/index.ts +2 -0
  133. package/src/components/MetricDisplay/MetricDisplay.tsx +55 -0
  134. package/src/components/MetricDisplay/index.ts +1 -0
  135. package/src/components/MultiSelect/MultiSelect.tsx +278 -0
  136. package/src/components/MultiSelect/index.ts +2 -0
  137. package/src/components/Notifications/Notifications.tsx +12 -0
  138. package/src/components/Notifications/README.md +93 -0
  139. package/src/components/Notifications/index.ts +4 -0
  140. package/src/components/Notifications/showToast.tsx +100 -0
  141. package/src/components/PropertyRow/PropertyRow.tsx +96 -0
  142. package/src/components/PropertyRow/index.ts +2 -0
  143. package/src/components/RadioTile/RadioTile.tsx +253 -0
  144. package/src/components/RadioTile/index.ts +2 -0
  145. package/src/components/RichText/FormattingToolbar.css.ts +69 -0
  146. package/src/components/RichText/FormattingToolbar.tsx +112 -0
  147. package/src/components/RichText/RichTextInline.css.ts +54 -0
  148. package/src/components/RichText/RichTextInline.tsx +318 -0
  149. package/src/components/RichText/formattingCommands.ts +181 -0
  150. package/src/components/RichText/formattingTypes.ts +34 -0
  151. package/src/components/RichText/index.ts +49 -0
  152. package/src/components/RichText/richTextExtensions.ts +111 -0
  153. package/src/components/RichText/richTextHelpers.ts +65 -0
  154. package/src/components/RichText/richTextImage.ts +253 -0
  155. package/src/components/RichText/richTextImageHandlers.ts +244 -0
  156. package/src/components/RichText/richTextProse.css.ts +261 -0
  157. package/src/components/RichTextEditor/RichTextEditor.css.ts +82 -0
  158. package/src/components/RichTextEditor/RichTextEditor.tsx +204 -0
  159. package/src/components/RichTextEditor/index.ts +2 -0
  160. package/src/components/RichTextView/RichTextView.css.ts +11 -0
  161. package/src/components/RichTextView/RichTextView.tsx +114 -0
  162. package/src/components/RichTextView/index.ts +2 -0
  163. package/src/components/Schedule/Schedule.tsx +35 -0
  164. package/src/components/SchedulePicker/SchedulePicker.css.ts +42 -0
  165. package/src/components/SchedulePicker/SchedulePicker.tsx +130 -0
  166. package/src/components/SchedulePicker/index.ts +2 -0
  167. package/src/components/SearchableList/types.ts +30 -0
  168. package/src/components/SearchableSubMenu/SearchableSubMenu.css.ts +25 -0
  169. package/src/components/SearchableSubMenu/SearchableSubMenu.tsx +139 -0
  170. package/src/components/SearchableSubMenu/index.ts +2 -0
  171. package/src/components/Select/README.md +114 -0
  172. package/src/components/Select/Select.css.ts +110 -0
  173. package/src/components/Select/Select.tsx +133 -0
  174. package/src/components/Select/index.ts +2 -0
  175. package/src/components/SelectCreatable/SelectCreatable.css.ts +16 -0
  176. package/src/components/SelectCreatable/SelectCreatable.tsx +203 -0
  177. package/src/components/SelectCreatable/index.ts +2 -0
  178. package/src/components/SettingsCard/SettingsCard.tsx +98 -0
  179. package/src/components/SettingsCard/index.ts +2 -0
  180. package/src/components/Sidebar/Sidebar.css.ts +91 -0
  181. package/src/components/Sidebar/Sidebar.tsx +129 -0
  182. package/src/components/Sidebar/index.ts +5 -0
  183. package/src/components/SimpleList/SimpleList.css.ts +12 -0
  184. package/src/components/SimpleList/SimpleList.tsx +44 -0
  185. package/src/components/SimpleList/index.ts +2 -0
  186. package/src/components/SimpleTable/SimpleTable.tsx +296 -0
  187. package/src/components/SimpleTable/index.ts +2 -0
  188. package/src/components/SlashRichTextEditor/SelectionBubbleMenu.css.ts +62 -0
  189. package/src/components/SlashRichTextEditor/SelectionBubbleMenu.tsx +85 -0
  190. package/src/components/SlashRichTextEditor/SlashCommandMenu.css.ts +124 -0
  191. package/src/components/SlashRichTextEditor/SlashCommandMenu.tsx +168 -0
  192. package/src/components/SlashRichTextEditor/SlashRichTextEditor.css.ts +81 -0
  193. package/src/components/SlashRichTextEditor/SlashRichTextEditor.tsx +538 -0
  194. package/src/components/SlashRichTextEditor/SlashSuggestionExtension.ts +48 -0
  195. package/src/components/SlashRichTextEditor/index.ts +13 -0
  196. package/src/components/SlashRichTextEditor/types.ts +48 -0
  197. package/src/components/StatCard/StatCard.css.ts +70 -0
  198. package/src/components/StatCard/StatCard.tsx +201 -0
  199. package/src/components/StatCard/index.ts +1 -0
  200. package/src/components/StatusBadge/StatusBadge.tsx +70 -0
  201. package/src/components/StatusBadge/index.ts +2 -0
  202. package/src/components/StatusIndicator/StatusIndicator.tsx +67 -0
  203. package/src/components/StatusIndicator/index.ts +6 -0
  204. package/src/components/SubNavigation/SubNavigation.css.ts +72 -0
  205. package/src/components/SubNavigation/SubNavigation.tsx +104 -0
  206. package/src/components/SubNavigation/index.ts +2 -0
  207. package/src/components/SuspenseLoader.tsx +22 -0
  208. package/src/components/Table/SortableColumnHeader.tsx +99 -0
  209. package/src/components/Table/TableSkeletonRows.figma.tsx +22 -0
  210. package/src/components/Table/TableSkeletonRows.tsx +113 -0
  211. package/src/components/Table/index.ts +9 -0
  212. package/src/components/TableActionsMenu.tsx +58 -0
  213. package/src/components/TableCard.tsx +29 -0
  214. package/src/components/TableContainer/TableContainer.tsx +86 -0
  215. package/src/components/TableContainer/index.ts +2 -0
  216. package/src/components/TableControlBar/TableControlBar.tsx +156 -0
  217. package/src/components/TableControlBar/TableSelectionButton.tsx +57 -0
  218. package/src/components/TableControlBar/index.ts +13 -0
  219. package/src/components/TableControlBar/useTableControlBar.tsx +314 -0
  220. package/src/components/TableSelection/TableSelection.tsx +43 -0
  221. package/src/components/TableSelection/index.ts +5 -0
  222. package/src/components/Tabs/README.md +76 -0
  223. package/src/components/Tabs/Tabs.css.ts +54 -0
  224. package/src/components/Tabs/Tabs.figma.tsx +47 -0
  225. package/src/components/Tabs/Tabs.tsx +96 -0
  226. package/src/components/Tabs/index.ts +8 -0
  227. package/src/components/TextInput/README.md +98 -0
  228. package/src/components/TextInput/SearchTextInput.figma.tsx +22 -0
  229. package/src/components/TextInput/SearchTextInput.tsx +150 -0
  230. package/src/components/TextInput/TextInput.figma.tsx +44 -0
  231. package/src/components/TextInput/TextInput.tsx +42 -0
  232. package/src/components/TextInput/index.ts +4 -0
  233. package/src/components/ThemeSwitcher.figma.tsx +28 -0
  234. package/src/components/ThemeSwitcher.tsx +69 -0
  235. package/src/components/TrendBadge/TrendBadge.tsx +76 -0
  236. package/src/components/TrendBadge/index.ts +2 -0
  237. package/src/components/TruncatedText.tsx +115 -0
  238. package/src/components/Typography/Text.tsx +74 -0
  239. package/src/components/Typography/Title.tsx +100 -0
  240. package/src/components/Typography/index.ts +4 -0
  241. package/src/geist-fonts.ts +48 -0
  242. package/src/hooks/index.ts +31 -0
  243. package/src/hooks/useFilters.ts +152 -0
  244. package/src/hooks/useInfiniteScroll.ts +62 -0
  245. package/src/hooks/usePlatform.ts +33 -0
  246. package/src/hooks/useServerTable.ts +495 -0
  247. package/src/hooks/useTableSelection.ts +102 -0
  248. package/src/hooks/useTableSort.ts +259 -0
  249. package/src/index.ts +483 -0
  250. package/src/mantine.ts +25 -0
  251. package/src/theme/mantineVars.ts +12 -0
  252. package/src/theme/themeContract.css.ts +131 -0
  253. package/src/theme/themeVars.ts +31 -0
  254. package/src/theme.ts +168 -0
  255. package/src/tokens/color-types.ts +107 -0
  256. package/src/tokens/colors.ts +243 -0
  257. package/src/tokens/index.ts +14 -0
  258. package/src/tokens/radius.ts +17 -0
  259. package/src/tokens/semantic-colors.ts +224 -0
  260. package/src/tokens/semantic-tokens-css.ts +53 -0
  261. package/src/tokens/shadows.ts +11 -0
  262. package/src/tokens/spacing.ts +20 -0
  263. package/src/tokens/text-styles.ts +179 -0
  264. package/src/tokens/typography.ts +40 -0
  265. package/src/tokens/zIndex.ts +27 -0
  266. package/src/types/mantine-theme.d.ts +17 -0
  267. package/src/types/tanstack-table.d.ts +22 -0
  268. package/src/utils/avatar.ts +150 -0
  269. package/src/utils/chartHelpers.ts +53 -0
  270. package/src/utils/color-props.ts +77 -0
  271. package/src/utils/createDesignComponent.tsx +104 -0
  272. package/src/utils/nestFlatRows.ts +111 -0
  273. package/src/utils/withStaticComponents.ts +6 -0
@@ -0,0 +1,74 @@
1
+ import figma from '@figma/code-connect';
2
+
3
+ import { Button } from './Button';
4
+
5
+ /**
6
+ * -- This file was auto-generated by Code Connect --
7
+ * None of your props could be automatically mapped to Figma properties.
8
+ * You should update the `props` object to include a mapping from your
9
+ * code props to Figma properties, and update the `example` function to
10
+ * return the code example you'd like to see in Figma
11
+ */
12
+
13
+ figma.connect(
14
+ Button,
15
+ 'https://www.figma.com/design/VCLfybgU3OaUUPrQdBaVmP/LM-Design-System?node-id=9%3A1071',
16
+ {
17
+ props: {
18
+ variant: figma.enum('Variant', {
19
+ Primary: 'primary',
20
+ Secondary: 'secondary',
21
+ Outline: 'outline',
22
+ Ghost: 'ghost',
23
+ Destructive: 'destructive',
24
+ 'Outline Inverse': 'outline-inverse',
25
+ }),
26
+ roundness: figma.enum('Roundness', {
27
+ Default: 'default',
28
+ Round: 'round',
29
+ }),
30
+ size: figma.enum('Size', {
31
+ md: 'md',
32
+ lg: 'lg',
33
+ sm: 'sm',
34
+ xs: 'xs',
35
+ }),
36
+ // No matching props could be found for these Figma properties:
37
+ // "showLeftIcon": figma.boolean('Show left icon'),
38
+ // "showRightIcon": figma.boolean('Show right icon'),
39
+ // "leftIcon": figma.instance('⮑ Left Content'),
40
+ // "rightIcon": figma.instance('⮑ Right Content'),
41
+ // "roundness": figma.enum('Roundness', {
42
+ // "Default": "default",
43
+ // "Round": "round"
44
+ // }),
45
+ // "variant": figma.enum('Variant', {
46
+ // "Primary": "primary",
47
+ // "Secondary": "secondary",
48
+ // "Outline": "outline",
49
+ // "Ghost": "ghost",
50
+ // "Destructive": "destructive",
51
+ // "Ghost Muted": "ghost-muted"
52
+ // }),
53
+ // "size": figma.enum('Size', {
54
+ // "Regular": "regular",
55
+ // "Large": "large",
56
+ // "Small": "small",
57
+ // "Mini": "mini"
58
+ // }),
59
+ // "state": figma.enum('State', {
60
+ // "Default": "default",
61
+ // "Hover & Active": "hover---active",
62
+ // "Focus": "focus",
63
+ // "Disabled": "disabled"
64
+ // })
65
+ },
66
+ example: props => (
67
+ <Button
68
+ variant={props.variant}
69
+ roundness={props.roundness}
70
+ size={props.size}
71
+ />
72
+ ),
73
+ },
74
+ );
@@ -0,0 +1,84 @@
1
+ import { forwardRef } from 'react';
2
+
3
+ import {
4
+ createPolymorphicComponent,
5
+ Button as MantineButton,
6
+ type ButtonProps as MantineButtonProps,
7
+ } from '@mantine/core';
8
+
9
+ import * as classes from './Button.css';
10
+
11
+ export type ButtonVariants =
12
+ | 'primary'
13
+ | 'secondary'
14
+ | 'tertiary'
15
+ | 'outline'
16
+ | 'outline-inverse'
17
+ | 'ghost'
18
+ | 'ghost-muted'
19
+ | 'destructive';
20
+
21
+ export interface ButtonProps extends MantineButtonProps {
22
+ /** Button variant from Figma design system */
23
+ variant?: ButtonVariants;
24
+ roundness?: 'default' | 'round';
25
+ }
26
+
27
+ const ButtonBase = forwardRef<HTMLButtonElement, ButtonProps>(
28
+ ({ variant = 'primary', className, ...props }, ref) => {
29
+ // Map our custom variants to Mantine variants
30
+ let $variant: 'filled' | 'outline' | 'subtle' = 'filled';
31
+ let $color = props.color;
32
+ let customClassName = className;
33
+
34
+ if (variant === 'primary') {
35
+ $variant = 'filled';
36
+ $color = 'dark';
37
+ customClassName = `${classes.primaryButton}${className ? ` ${className}` : ''}`;
38
+ } else if (variant === 'secondary') {
39
+ $variant = 'filled';
40
+ $color = 'gray';
41
+ customClassName = `${classes.secondaryButton}${className ? ` ${className}` : ''}`;
42
+ } else if (variant === 'tertiary') {
43
+ $variant = 'filled';
44
+ customClassName = `${classes.tertiaryButton}${className ? ` ${className}` : ''}`;
45
+ } else if (variant === 'destructive') {
46
+ $variant = 'filled';
47
+ $color = 'red';
48
+ customClassName = `${classes.destructiveButton}${className ? ` ${className}` : ''}`;
49
+ } else if (variant === 'outline') {
50
+ $variant = 'outline';
51
+ customClassName = `${classes.outlineButton}${className ? ` ${className}` : ''}`;
52
+ } else if (variant === 'ghost') {
53
+ $variant = 'subtle';
54
+ customClassName = `${classes.ghostButton}${className ? ` ${className}` : ''}`;
55
+ } else if (variant === 'ghost-muted') {
56
+ $variant = 'subtle';
57
+ customClassName = `${classes.ghostMutedButton}${className ? ` ${className}` : ''}`;
58
+ } else if (variant === 'outline-inverse') {
59
+ $variant = 'outline';
60
+ $color = 'white';
61
+ customClassName = `${classes.outlineInverseButton}${className ? ` ${className}` : ''}`;
62
+ }
63
+
64
+ return (
65
+ <MantineButton
66
+ ref={ref}
67
+ variant={$variant}
68
+ color={$color}
69
+ className={customClassName}
70
+ {...props}
71
+ radius={props.roundness === 'round' ? 'full' : 'lg'}
72
+ fz={props.fz ?? 'sm'}
73
+ lh={props.lh ?? 21}
74
+ fw={props.fw ?? 600}
75
+ />
76
+ );
77
+ },
78
+ );
79
+
80
+ ButtonBase.displayName = 'Button';
81
+
82
+ export const Button = createPolymorphicComponent<'button', ButtonProps>(
83
+ ButtonBase,
84
+ );
@@ -0,0 +1,2 @@
1
+ export { Button } from './Button';
2
+ export type { ButtonProps } from './Button';
@@ -0,0 +1,33 @@
1
+ import figma from '@figma/code-connect';
2
+
3
+ import { ChartTooltip } from './ChartTooltip';
4
+
5
+ /**
6
+ * -- This file was auto-generated by Code Connect --
7
+ * None of your props could be automatically mapped to Figma properties.
8
+ * You should update the `props` object to include a mapping from your
9
+ * code props to Figma properties, and update the `example` function to
10
+ * return the code example you'd like to see in Figma
11
+ */
12
+
13
+ figma.connect(
14
+ ChartTooltip,
15
+ 'https://www.figma.com/design/VCLfybgU3OaUUPrQdBaVmP/LM-Design-System?node-id=133%3A14788',
16
+ {
17
+ props: {
18
+ // No matching props could be found for these Figma properties:
19
+ // "side": figma.enum('Side', {
20
+ // "Top": "top",
21
+ // "Bottom": "bottom",
22
+ // "Left": "left",
23
+ // "Right": "right"
24
+ // })
25
+ },
26
+ example: _props => (
27
+ <ChartTooltip
28
+ active
29
+ payload={[{ value: 42, payload: { date: '2026-04-08', value: 42 } }]}
30
+ />
31
+ ),
32
+ },
33
+ );
@@ -0,0 +1,101 @@
1
+ import { Box, Flex } from '@mantine/core';
2
+
3
+ import { toDate } from '@scalepad/ui-utils/date';
4
+
5
+ import { tokens } from '../../theme/themeContract.css';
6
+ import { Text } from '../Typography';
7
+ import * as classes from './TrendAreaChart.css';
8
+
9
+ /**
10
+ * Payload item from recharts tooltip
11
+ */
12
+ interface TooltipPayloadItem {
13
+ value?: number;
14
+ payload: {
15
+ date: string;
16
+ value: number;
17
+ };
18
+ }
19
+
20
+ export interface ChartTooltipProps {
21
+ /**
22
+ * Whether the tooltip is active/visible (passed by recharts)
23
+ */
24
+ active?: boolean;
25
+ /**
26
+ * Payload data from recharts (passed by recharts)
27
+ */
28
+ payload?: TooltipPayloadItem[];
29
+ /**
30
+ * Label for the value in tooltip (e.g., "Users", "Minutes")
31
+ */
32
+ valueLabel?: string;
33
+ /**
34
+ * Optional formatter for tooltip values
35
+ */
36
+ formatValue?: (value: number) => string;
37
+ /**
38
+ * Optional formatter for date labels
39
+ */
40
+ formatDate?: (date: string) => string;
41
+ /**
42
+ * Color for the indicator dot
43
+ */
44
+ color?: string;
45
+ }
46
+
47
+ /**
48
+ * Custom tooltip component for TrendAreaChart
49
+ * Matches Figma design with white background, border, and consistent typography
50
+ */
51
+ export function ChartTooltip({
52
+ active,
53
+ payload,
54
+ valueLabel = 'Value',
55
+ formatValue,
56
+ formatDate,
57
+ color = tokens.color.stroke.primaryDefault,
58
+ }: ChartTooltipProps) {
59
+ if (!active || !payload || !payload.length) {
60
+ return null;
61
+ }
62
+
63
+ const data = payload[0];
64
+ const date = data.payload.date as string;
65
+ const value = data.value as number;
66
+
67
+ // Format date - default to "Mon DD, YYYY" format
68
+ const formattedDate = formatDate
69
+ ? formatDate(date)
70
+ : toDate(date).toLocaleDateString('en-US', {
71
+ month: 'short',
72
+ day: 'numeric',
73
+ year: 'numeric',
74
+ });
75
+
76
+ // Format value - default to number with comma separators
77
+ const formattedValue = formatValue
78
+ ? formatValue(value)
79
+ : value.toLocaleString();
80
+
81
+ return (
82
+ <Box className={classes.tooltip}>
83
+ {/* Date header */}
84
+ <Text variant="caption2.stronger" mb="xs">
85
+ {formattedDate}
86
+ </Text>
87
+
88
+ {/* Value row with color dot */}
89
+ <Flex gap="xs" align="center">
90
+ <Box
91
+ className={classes.tooltipDot}
92
+ style={{ backgroundColor: color }}
93
+ />
94
+ <Text variant="caption2" c="text.subdued.default" style={{ flex: 1 }}>
95
+ {valueLabel}
96
+ </Text>
97
+ <Text variant="caption2.stronger">{formattedValue}</Text>
98
+ </Flex>
99
+ </Box>
100
+ );
101
+ }
@@ -0,0 +1,75 @@
1
+ import { Bar, BarChart, ResponsiveContainer } from 'recharts';
2
+
3
+ import { tokens } from '../../theme/themeContract.css';
4
+
5
+ export type SparklineTone = 'success' | 'destructive' | 'neutral';
6
+
7
+ export interface MiniBarSparklineProps {
8
+ /**
9
+ * Series of numeric values rendered left-to-right as bars.
10
+ */
11
+ data: number[];
12
+ /**
13
+ * Width in pixels.
14
+ * @default 100
15
+ */
16
+ width?: number;
17
+ /**
18
+ * Height in pixels.
19
+ * @default 28
20
+ */
21
+ height?: number;
22
+ /**
23
+ * Explicit bar color. Takes precedence over `tone`.
24
+ */
25
+ color?: string;
26
+ /**
27
+ * Semantic tone used to pick a default bar color. Ignored if `color` is set.
28
+ * @default 'success'
29
+ */
30
+ tone?: SparklineTone;
31
+ /**
32
+ * Accessible label for screen readers.
33
+ */
34
+ ariaLabel?: string;
35
+ }
36
+
37
+ const toneColors: Record<SparklineTone, string> = {
38
+ success: tokens.color.background.successFilled,
39
+ destructive: tokens.color.background.dangerFilled,
40
+ neutral: tokens.color.background.subduedFilled,
41
+ };
42
+
43
+ /**
44
+ * MiniBarSparkline — compact inline bar chart with no axes, grid, or tooltip.
45
+ * Designed to live inside a StatCard footer alongside a TrendBadge.
46
+ */
47
+ export function MiniBarSparkline({
48
+ data,
49
+ width = 100,
50
+ height = 28,
51
+ color,
52
+ tone = 'success',
53
+ ariaLabel,
54
+ }: MiniBarSparklineProps) {
55
+ const fill = color ?? toneColors[tone];
56
+ const chartData = data.map((value, index) => ({ index, value }));
57
+
58
+ return (
59
+ <div
60
+ role="img"
61
+ aria-label={ariaLabel}
62
+ style={{ width, height, lineHeight: 0 }}
63
+ >
64
+ <ResponsiveContainer width="100%" height="100%">
65
+ <BarChart
66
+ data={chartData}
67
+ margin={{ top: 0, right: 0, left: 0, bottom: 0 }}
68
+ barCategoryGap={2}
69
+ >
70
+ <Bar dataKey="value" fill={fill} radius={[2, 2, 0, 0]} />
71
+ </BarChart>
72
+ </ResponsiveContainer>
73
+ </div>
74
+ );
75
+ }