@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,149 @@
1
+ import type { ReactNode } from 'react';
2
+
3
+ import { Flex, Modal, type ModalProps } from '@mantine/core';
4
+
5
+ import { Button } from '../Button';
6
+ import { Text } from '../Typography';
7
+
8
+ export interface ConfirmationModalProps extends Omit<
9
+ ModalProps,
10
+ 'children' | 'onClose'
11
+ > {
12
+ /**
13
+ * Modal title (displayed in header)
14
+ */
15
+ title: string;
16
+ /**
17
+ * Modal description/message
18
+ */
19
+ description: string | ReactNode;
20
+ /**
21
+ * Confirm button label
22
+ * @default "Confirm"
23
+ */
24
+ confirmLabel?: string;
25
+ /**
26
+ * Cancel button label
27
+ * @default "Cancel"
28
+ */
29
+ cancelLabel?: string;
30
+ /**
31
+ * Callback when confirm is clicked
32
+ */
33
+ onConfirm: () => void;
34
+ /**
35
+ * Callback when cancel is clicked or modal is closed (via X button or overlay click).
36
+ * This automatically maps to the modal's onClose handler.
37
+ */
38
+ onCancel: () => void;
39
+ /**
40
+ * Variant of the confirmation dialog
41
+ * @default "default"
42
+ */
43
+ variant?: 'default' | 'destructive';
44
+ /**
45
+ * Whether the confirm button is loading
46
+ * @default false
47
+ */
48
+ confirmLoading?: boolean;
49
+ /**
50
+ * Left section of the confirm button
51
+ */
52
+ confirmButtonLeftSection?: ReactNode;
53
+ /**
54
+ * Whether the confirm button is disabled
55
+ * @default false
56
+ */
57
+ confirmDisabled?: boolean;
58
+ }
59
+
60
+ /**
61
+ * ConfirmationModal Component
62
+ *
63
+ * A reusable confirmation dialog for user actions requiring explicit confirmation.
64
+ * Supports both general confirmations (default variant) and critical/destructive actions (destructive variant).
65
+ * Follows Figma Dialog pattern with header, body, and footer.
66
+ *
67
+ * @example
68
+ * ```tsx
69
+ * // Default variant for general confirmations
70
+ * <ConfirmationModal
71
+ * opened={opened}
72
+ * title="Update Agent"
73
+ * description="Update the agent on 3 devices to the latest version?"
74
+ * confirmLabel="Update Agent"
75
+ * onConfirm={handleUpdate}
76
+ * onCancel={close}
77
+ * />
78
+ *
79
+ * // Destructive variant for critical actions
80
+ * <ConfirmationModal
81
+ * opened={opened}
82
+ * title="Delete Device"
83
+ * description="This action cannot be undone."
84
+ * confirmLabel="Delete"
85
+ * onConfirm={handleDelete}
86
+ * onCancel={close}
87
+ * variant="destructive"
88
+ * />
89
+ * ```
90
+ */
91
+ export function ConfirmationModal({
92
+ title,
93
+ description,
94
+ confirmLabel = 'Confirm',
95
+ cancelLabel = 'Cancel',
96
+ onConfirm,
97
+ onCancel,
98
+ variant = 'default',
99
+ confirmLoading = false,
100
+ confirmButtonLeftSection,
101
+ confirmDisabled = false,
102
+ ...modalProps
103
+ }: ConfirmationModalProps) {
104
+ const isDestructive = variant === 'destructive';
105
+
106
+ return (
107
+ <Modal
108
+ {...modalProps}
109
+ title={title}
110
+ onClose={onCancel}
111
+ centered
112
+ padding="xl"
113
+ radius="xl"
114
+ size="md"
115
+ withCloseButton
116
+ >
117
+ <Flex direction="column" gap="xl">
118
+ {/* Description */}
119
+ {typeof description === 'string' ? (
120
+ <Text variant="caption1" c="text.subdued.default">
121
+ {description}
122
+ </Text>
123
+ ) : (
124
+ description
125
+ )}
126
+
127
+ {/* Actions */}
128
+ <Flex gap="xs" justify="flex-end">
129
+ <Button
130
+ variant="outline"
131
+ onClick={onCancel}
132
+ disabled={confirmLoading}
133
+ >
134
+ {cancelLabel}
135
+ </Button>
136
+ <Button
137
+ variant={isDestructive ? 'destructive' : 'primary'}
138
+ onClick={onConfirm}
139
+ loading={confirmLoading}
140
+ disabled={confirmDisabled}
141
+ leftSection={confirmButtonLeftSection}
142
+ >
143
+ {confirmLabel}
144
+ </Button>
145
+ </Flex>
146
+ </Flex>
147
+ </Modal>
148
+ );
149
+ }
@@ -0,0 +1,2 @@
1
+ export { ConfirmationModal } from './ConfirmationModal';
2
+ export type { ConfirmationModalProps } from './ConfirmationModal';
@@ -0,0 +1,132 @@
1
+ import {
2
+ cloneElement,
3
+ useEffect,
4
+ useRef,
5
+ useState,
6
+ type MouseEvent,
7
+ type ReactElement,
8
+ } from 'react';
9
+
10
+ import { Tooltip, type TooltipProps } from '@mantine/core';
11
+
12
+ type SupportedChildProps = {
13
+ onClick?: (event: MouseEvent<HTMLElement>) => void;
14
+ 'aria-label'?: string;
15
+ };
16
+
17
+ export interface ConfirmationTooltipProps {
18
+ /**
19
+ * Interactive element that triggers confirmation.
20
+ */
21
+ children: ReactElement<SupportedChildProps>;
22
+ /**
23
+ * Tooltip label shown while confirmed.
24
+ * @default 'Copied'
25
+ */
26
+ label?: TooltipProps['label'];
27
+ /**
28
+ * Confirmation visibility duration in milliseconds.
29
+ * @default 1500
30
+ */
31
+ durationMs?: number;
32
+ /**
33
+ * Optional aria-label to apply while confirmation is visible.
34
+ */
35
+ confirmedAriaLabel?: string;
36
+ /**
37
+ * Tooltip position relative to the child.
38
+ * @default 'top'
39
+ */
40
+ position?: TooltipProps['position'];
41
+ /**
42
+ * Whether to show a tooltip arrow.
43
+ * @default true
44
+ */
45
+ withArrow?: TooltipProps['withArrow'];
46
+ /**
47
+ * Tooltip color token.
48
+ * @default 'dark'
49
+ */
50
+ color?: TooltipProps['color'];
51
+ /**
52
+ * Whether tooltip should render inside a portal.
53
+ */
54
+ withinPortal?: TooltipProps['withinPortal'];
55
+ /**
56
+ * Tooltip transition configuration.
57
+ */
58
+ transitionProps?: TooltipProps['transitionProps'];
59
+ /**
60
+ * Disables the confirmation behavior.
61
+ * Child click still fires as normal.
62
+ * @default false
63
+ */
64
+ disabled?: boolean;
65
+ }
66
+
67
+ /**
68
+ * Wraps any clickable child and shows a short-lived confirmation tooltip after click.
69
+ */
70
+ export function ConfirmationTooltip({
71
+ children,
72
+ label = 'Copied',
73
+ durationMs = 1500,
74
+ confirmedAriaLabel,
75
+ position = 'top',
76
+ withArrow = false,
77
+ color = 'dark',
78
+ withinPortal,
79
+ transitionProps,
80
+ disabled = false,
81
+ }: ConfirmationTooltipProps) {
82
+ const [isConfirmed, setIsConfirmed] = useState(false);
83
+ const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
84
+
85
+ const clearConfirmationTimeout = () => {
86
+ if (!timeoutRef.current) return;
87
+ clearTimeout(timeoutRef.current);
88
+ timeoutRef.current = null;
89
+ };
90
+
91
+ useEffect(
92
+ () => () => {
93
+ clearConfirmationTimeout();
94
+ },
95
+ [],
96
+ );
97
+
98
+ const handleClick = (event: MouseEvent<HTMLElement>) => {
99
+ children.props.onClick?.(event);
100
+
101
+ if (disabled) return;
102
+
103
+ setIsConfirmed(true);
104
+ clearConfirmationTimeout();
105
+ timeoutRef.current = setTimeout(() => {
106
+ setIsConfirmed(false);
107
+ timeoutRef.current = null;
108
+ }, durationMs);
109
+ };
110
+
111
+ const originalAriaLabel = children.props['aria-label'];
112
+ const clonedChild = cloneElement(children, {
113
+ onClick: handleClick,
114
+ ...(confirmedAriaLabel
115
+ ? { 'aria-label': isConfirmed ? confirmedAriaLabel : originalAriaLabel }
116
+ : {}),
117
+ });
118
+
119
+ return (
120
+ <Tooltip
121
+ label={label}
122
+ opened={!disabled && isConfirmed}
123
+ position={position}
124
+ withArrow={withArrow}
125
+ color={color}
126
+ withinPortal={withinPortal}
127
+ transitionProps={transitionProps}
128
+ >
129
+ {clonedChild}
130
+ </Tooltip>
131
+ );
132
+ }
@@ -0,0 +1,2 @@
1
+ export { ConfirmationTooltip } from './ConfirmationTooltip';
2
+ export type { ConfirmationTooltipProps } from './ConfirmationTooltip';
@@ -0,0 +1,33 @@
1
+ import figma from '@figma/code-connect';
2
+
3
+ import { DataDialog } from './DataDialog';
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
+ DataDialog,
15
+ 'https://www.figma.com/design/VCLfybgU3OaUUPrQdBaVmP/LM-Design-System?node-id=151%3A12298',
16
+ {
17
+ props: {
18
+ // No matching props could be found for these Figma properties:
19
+ // "showError": figma.boolean('ShowError'),
20
+ // "type": figma.enum('Type', {
21
+ // "Desktop": "desktop",
22
+ // "Desktop Scrollable": "desktop-scrollable",
23
+ // "Mobile": "mobile",
24
+ // "Mobile Full Screen Scrollable": "mobile-full-screen-scrollable"
25
+ // })
26
+ },
27
+ example: _props => (
28
+ <DataDialog open onOpenChange={() => {}} title="Dialog title">
29
+ Dialog content
30
+ </DataDialog>
31
+ ),
32
+ }
33
+ );
@@ -0,0 +1,46 @@
1
+ import type { CSSProperties, ReactNode } from 'react';
2
+
3
+ import { Modal } from '@mantine/core';
4
+
5
+ import { textStyleVariants } from '../tokens';
6
+
7
+ import { Text } from './Typography';
8
+
9
+ export interface DataDialogProps {
10
+ open: boolean;
11
+ onOpenChange: (open: boolean) => void;
12
+ title: string;
13
+ description?: string;
14
+ children: ReactNode;
15
+ }
16
+
17
+ const titleStyle: CSSProperties = textStyleVariants.heading4;
18
+
19
+ /**
20
+ * DataDialog component for displaying detailed data in a modal
21
+ * Wraps Mantine Modal with a consistent API
22
+ */
23
+ export function DataDialog({
24
+ open,
25
+ onOpenChange,
26
+ title,
27
+ description,
28
+ children,
29
+ }: DataDialogProps) {
30
+ return (
31
+ <Modal
32
+ opened={open}
33
+ onClose={() => onOpenChange(false)}
34
+ title={<span style={titleStyle}>{title}</span>}
35
+ size="md"
36
+ centered
37
+ >
38
+ {description && (
39
+ <Text variant="caption1" c="text.subdued.default" mb="md">
40
+ {description}
41
+ </Text>
42
+ )}
43
+ {children}
44
+ </Modal>
45
+ );
46
+ }