@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,168 @@
1
+ import { Fragment, useEffect, useMemo, useRef, type MouseEvent } from 'react';
2
+
3
+ import * as classes from './SlashCommandMenu.css';
4
+ import { UnstyledButton } from '../../mantine';
5
+ import { FormattingToolbar } from '../RichText/FormattingToolbar';
6
+ import { Text } from '../Typography';
7
+
8
+ import type { SlashCommand } from './types';
9
+ import type { FormattingToolbarCommand } from '../RichText/formattingTypes';
10
+ import type { Editor, Range } from '@tiptap/react';
11
+
12
+ export interface SlashCommandMenuProps {
13
+ editor: Editor;
14
+ /**
15
+ * Range of the `/<query>` token. Toolbar buttons delete this before applying
16
+ * formatting, and field commands receive it on `run()`.
17
+ */
18
+ range: Range;
19
+ /** Active query (text after the slash). */
20
+ query: string;
21
+ /** Filtered, group-bucketed field commands. */
22
+ commands: SlashCommand[];
23
+ /** Toolbar formatting commands. */
24
+ toolbarCommands: FormattingToolbarCommand[];
25
+ /** Highlighted index into the visible list. */
26
+ highlightedIndex: number;
27
+ onHighlightChange: (index: number) => void;
28
+ /** Selected via keyboard or click — runs the command and closes the menu. */
29
+ onSelect: (command: SlashCommand) => void;
30
+ /**
31
+ * Notifies the parent of the visible field-command list so keyboard nav
32
+ * (which is bubbled from the editor, not from focusable buttons) knows
33
+ * how big the list is.
34
+ */
35
+ onVisibleCommandsChange: (commandIds: string[]) => void;
36
+ ariaLabel?: string;
37
+ }
38
+
39
+ /**
40
+ * The popup that opens after the user types `/`. Layout follows the
41
+ * Option B Figma frame: slim icon toolbar header → hint row → grouped
42
+ * command list.
43
+ */
44
+ export function SlashCommandMenu({
45
+ editor,
46
+ range,
47
+ query,
48
+ commands,
49
+ toolbarCommands,
50
+ highlightedIndex,
51
+ onHighlightChange,
52
+ onSelect,
53
+ onVisibleCommandsChange,
54
+ ariaLabel = 'Slash menu',
55
+ }: SlashCommandMenuProps) {
56
+ const lastIdsRef = useRef<string[]>([]);
57
+ useEffect(() => {
58
+ const ids = commands.map(c => c.id);
59
+ const prev = lastIdsRef.current;
60
+ const sameLength = prev.length === ids.length;
61
+ const allMatch = sameLength && ids.every((id, i) => prev[i] === id);
62
+ if (!allMatch) {
63
+ lastIdsRef.current = ids;
64
+ onVisibleCommandsChange(ids);
65
+ }
66
+ }, [commands, onVisibleCommandsChange]);
67
+
68
+ const showToolbar = toolbarCommands.length > 0;
69
+ const showHint = showToolbar && query.trim().length === 0;
70
+
71
+ // Bucket the command list by `group` so we can render section headers.
72
+ const grouped = useMemo(() => {
73
+ const buckets: Array<{ group: string; items: SlashCommand[] }> = [];
74
+ const indexByGroup = new Map<string, number>();
75
+ for (const cmd of commands) {
76
+ let bucketIdx = indexByGroup.get(cmd.group);
77
+ if (bucketIdx == null) {
78
+ bucketIdx = buckets.length;
79
+ indexByGroup.set(cmd.group, bucketIdx);
80
+ buckets.push({ group: cmd.group, items: [] });
81
+ }
82
+ buckets[bucketIdx].items.push(cmd);
83
+ }
84
+ return buckets;
85
+ }, [commands]);
86
+
87
+ // Track the running visible index so each row knows whether it's the
88
+ // keyboard cursor's current target.
89
+ let visibleIndex = -1;
90
+
91
+ return (
92
+ <div className={classes.container} role="dialog" aria-label={ariaLabel}>
93
+ {showToolbar ? (
94
+ <FormattingToolbar
95
+ editor={editor}
96
+ range={range}
97
+ commands={toolbarCommands}
98
+ dimmed={query.trim().length > 0}
99
+ />
100
+ ) : null}
101
+
102
+ {showHint ? (
103
+ <div className={classes.hintRow}>
104
+ <Text variant="caption2">
105
+ Type <kbd>##</kbd> for H2, <kbd>-</kbd> for bullet, <kbd>⌘B</kbd>{' '}
106
+ bold
107
+ </Text>
108
+ </div>
109
+ ) : null}
110
+
111
+ {commands.length === 0 ? (
112
+ <div className={classes.emptyState}>
113
+ <Text variant="caption2">No matching commands</Text>
114
+ </div>
115
+ ) : (
116
+ <div role="listbox" className={classes.list}>
117
+ {grouped.map(bucket => (
118
+ <Fragment key={bucket.group}>
119
+ <div className={classes.sectionHeader}>
120
+ <Text variant="smallCaps">{bucket.group}</Text>
121
+ </div>
122
+ {bucket.items.map(cmd => {
123
+ visibleIndex += 1;
124
+ const idx = visibleIndex;
125
+ const isActive = idx === highlightedIndex;
126
+ const isDisabled = Boolean(cmd.disabled);
127
+ const Icon = cmd.icon;
128
+ return (
129
+ <UnstyledButton
130
+ key={cmd.id}
131
+ role="option"
132
+ aria-selected={isActive}
133
+ aria-disabled={isDisabled}
134
+ disabled={isDisabled}
135
+ className={`${classes.item} ${isActive ? classes.itemActive : ''}`.trim()}
136
+ onMouseDown={(e: MouseEvent) => e.preventDefault()}
137
+ onMouseEnter={() => onHighlightChange(idx)}
138
+ onClick={() => {
139
+ if (!isDisabled) onSelect(cmd);
140
+ }}
141
+ >
142
+ <span className={classes.itemLabel}>
143
+ <span className={classes.itemIcon} aria-hidden>
144
+ <Icon size={14} />
145
+ </span>
146
+ <Text variant="caption1.strong">{cmd.label}</Text>
147
+ </span>
148
+ {isDisabled && cmd.disabledHint ? (
149
+ <Text variant="caption2" className={classes.itemHint}>
150
+ {cmd.disabledHint}
151
+ </Text>
152
+ ) : cmd.shortcut ? (
153
+ <span className={classes.itemShortcut}>
154
+ <Text variant="caption2" c="text.subdued.default">
155
+ {cmd.shortcut}
156
+ </Text>
157
+ </span>
158
+ ) : null}
159
+ </UnstyledButton>
160
+ );
161
+ })}
162
+ </Fragment>
163
+ ))}
164
+ </div>
165
+ )}
166
+ </div>
167
+ );
168
+ }
@@ -0,0 +1,81 @@
1
+ import { style } from '@vanilla-extract/css';
2
+
3
+ import { tokens } from '../../theme/themeContract.css';
4
+
5
+ export const root = style({
6
+ position: 'relative',
7
+ display: 'flex',
8
+ flexDirection: 'column',
9
+ width: '100%',
10
+ });
11
+
12
+ /**
13
+ * Base editor surface — no chrome of its own. Consumers like
14
+ * `ActionItemQuickCreate` already wrap the editor in a card so the editor
15
+ * staying transparent avoids the doubled-border visual the user reported.
16
+ */
17
+ export const editorSurface = style({
18
+ position: 'relative',
19
+ color: tokens.color.text.default,
20
+ selectors: {
21
+ '&[data-disabled="true"]': {
22
+ cursor: 'not-allowed',
23
+ opacity: 0.7,
24
+ },
25
+ },
26
+ });
27
+
28
+ /**
29
+ * Optional self-contained variant — renders an input-style box around the
30
+ * editor for screens where the editor stands on its own (Storybook, future
31
+ * surfaces). Opt in via `variant="bordered"`.
32
+ */
33
+ export const editorSurfaceBordered = style({
34
+ borderRadius: tokens.radius.md,
35
+ background: tokens.color.background.input,
36
+ border: `1px solid ${tokens.color.stroke.subduedDefault}`,
37
+ padding: `${tokens.spacing.xs} ${tokens.spacing.sm}`,
38
+ selectors: {
39
+ '&[data-focused="true"]': {
40
+ borderColor: tokens.color.stroke.focusDefault,
41
+ },
42
+ '&[data-error="true"]': {
43
+ borderColor: tokens.color.stroke.dangerDefault,
44
+ },
45
+ '&[data-disabled="true"]': {
46
+ background: tokens.color.background.disabledDefault,
47
+ },
48
+ },
49
+ });
50
+
51
+ export const errorMessage = style({
52
+ marginTop: tokens.spacing['3xs'],
53
+ color: tokens.color.text.dangerDefault,
54
+ });
55
+
56
+ /**
57
+ * Container for the popup. Positioned absolutely below the editor surface so
58
+ * it aligns with the slash anchor without needing a portal — keeps focus
59
+ * inside the editor's contenteditable.
60
+ */
61
+ export const menuLayer = style({
62
+ position: 'absolute',
63
+ left: 0,
64
+ right: 0,
65
+ top: '100%',
66
+ zIndex: 30,
67
+ pointerEvents: 'none',
68
+ });
69
+
70
+ export const menuLayerActive = style({
71
+ pointerEvents: 'auto',
72
+ });
73
+
74
+ /**
75
+ * All element-level prose styling (headings, lists, code, blockquote,
76
+ * marks, placeholder) lives in `richTextProse.css.ts` and is applied
77
+ * via the shared `prose` class on the editor surface. Keep this file
78
+ * focused on container chrome (border, focus state, error state,
79
+ * popup positioning) so the editor and `RichTextView` stay visually
80
+ * in sync by construction.
81
+ */