@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.
- package/.ai/rules/date-handling.md +39 -0
- package/.ai/rules/figma-design-system.md +372 -0
- package/.ai/rules/figma-lm-design-system-keys.md +680 -0
- package/.ai/rules/file-extensions.md +13 -0
- package/.ai/rules/modal-confirmation-mutation.md +56 -0
- package/.ai/rules/react-hooks.md +29 -0
- package/.ai/rules/styling.md +83 -0
- package/AGENTS.md +37 -0
- package/README.md +125 -0
- package/figma.config.json +9 -0
- package/package.json +127 -0
- package/scripts/install-ai-rules.mjs +136 -0
- package/src/ThemeProvider.tsx +57 -0
- package/src/charts.ts +32 -0
- package/src/components/ActionCard/ActionCard.css.ts +60 -0
- package/src/components/ActionCard/ActionCard.tsx +154 -0
- package/src/components/ActionCard/index.ts +2 -0
- package/src/components/Anchor/Anchor.tsx +47 -0
- package/src/components/Anchor/index.ts +2 -0
- package/src/components/AppliedFiltersManagerBar/AppliedFiltersManagerBar.tsx +105 -0
- package/src/components/AppliedFiltersManagerBar/FilterBadge.css.ts +23 -0
- package/src/components/AppliedFiltersManagerBar/FilterBadge.tsx +50 -0
- package/src/components/AppliedFiltersManagerBar/index.ts +5 -0
- package/src/components/Badge/Badge.css.ts +72 -0
- package/src/components/Badge/Badge.figma.tsx +43 -0
- package/src/components/Badge/Badge.tsx +159 -0
- package/src/components/Badge/index.ts +2 -0
- package/src/components/BreadCrumb/BreadCrumb.tsx +62 -0
- package/src/components/BreadCrumb/index.ts +2 -0
- package/src/components/BulkActionBar/BulkActionBar.css.ts +26 -0
- package/src/components/BulkActionBar/BulkActionBar.tsx +164 -0
- package/src/components/BulkActionBar/index.ts +2 -0
- package/src/components/Button/Button.css.ts +272 -0
- package/src/components/Button/Button.figma.tsx +74 -0
- package/src/components/Button/Button.tsx +84 -0
- package/src/components/Button/index.ts +2 -0
- package/src/components/Charts/ChartTooltip.figma.tsx +33 -0
- package/src/components/Charts/ChartTooltip.tsx +101 -0
- package/src/components/Charts/MiniBarSparkline.tsx +75 -0
- package/src/components/Charts/StackedPatternBarChart.tsx +494 -0
- package/src/components/Charts/TrendAreaChart.css.ts +23 -0
- package/src/components/Charts/TrendAreaChart.tsx +210 -0
- package/src/components/Charts/index.ts +12 -0
- package/src/components/CodePanel/CodePanel.css.ts +113 -0
- package/src/components/CodePanel/CodePanel.tsx +121 -0
- package/src/components/CodePanel/index.ts +2 -0
- package/src/components/CommentComposer/CommentComposer.css.ts +60 -0
- package/src/components/CommentComposer/CommentComposer.tsx +181 -0
- package/src/components/CommentComposer/index.ts +2 -0
- package/src/components/ConfirmationModal/ConfirmationModal.tsx +149 -0
- package/src/components/ConfirmationModal/index.ts +2 -0
- package/src/components/ConfirmationTooltip/ConfirmationTooltip.tsx +132 -0
- package/src/components/ConfirmationTooltip/index.ts +2 -0
- package/src/components/DataDialog.figma.tsx +33 -0
- package/src/components/DataDialog.tsx +46 -0
- package/src/components/DataTable/DataTable.tsx +1042 -0
- package/src/components/DataTable/RowExpandToggle.tsx +105 -0
- package/src/components/DataTable/RowGroupHeader.tsx +190 -0
- package/src/components/DataTable/createActionsColumn.tsx +86 -0
- package/src/components/DataTable/index.ts +25 -0
- package/src/components/DatePicker/CustomRangePicker.tsx +59 -0
- package/src/components/DatePicker/DateInput.tsx +329 -0
- package/src/components/DatePicker/DateNavigator.tsx +486 -0
- package/src/components/DatePicker/DatePicker.tsx +242 -0
- package/src/components/DatePicker/MonthlyRangePicker.tsx +231 -0
- package/src/components/DatePicker/QuarterlyRangePicker.tsx +224 -0
- package/src/components/DatePicker/QuickPicksSidebar.tsx +242 -0
- package/src/components/DatePicker/YearlyRangePicker.tsx +171 -0
- package/src/components/DatePicker/index.ts +7 -0
- package/src/components/DatePicker/types.ts +12 -0
- package/src/components/DesignSystemPrimitives/FluidGrid.tsx +44 -0
- package/src/components/DesignSystemPrimitives/InteractivePrimitives.tsx +177 -0
- package/src/components/DesignSystemPrimitives/LayoutPrimitives.tsx +220 -0
- package/src/components/DesignSystemPrimitives/LayoutPrimitives.types.tsx +15 -0
- package/src/components/DesignSystemPrimitives/SurfacePrimitives.tsx +46 -0
- package/src/components/DesignSystemPrimitives/index.ts +55 -0
- package/src/components/Details/Details.css.ts +74 -0
- package/src/components/Details/Details.tsx +140 -0
- package/src/components/Details/index.ts +2 -0
- package/src/components/DownloadCard/DownloadCard.css.ts +22 -0
- package/src/components/DownloadCard/DownloadCard.tsx +63 -0
- package/src/components/DownloadCard/index.ts +2 -0
- package/src/components/Drawer/Drawer.css.ts +32 -0
- package/src/components/Drawer/Drawer.tsx +236 -0
- package/src/components/Drawer/hooks/useDetailDrawer.ts +61 -0
- package/src/components/Drawer/hooks/useDetailDrawerNavigation.ts +125 -0
- package/src/components/Drawer/hooks/useDetailDrawerNavigationContext.ts +66 -0
- package/src/components/EditableRichText/EditableRichText.css.ts +72 -0
- package/src/components/EditableRichText/EditableRichText.tsx +324 -0
- package/src/components/EditableRichText/index.ts +2 -0
- package/src/components/EditableSelect/EditableSelect.css.ts +62 -0
- package/src/components/EditableSelect/EditableSelect.tsx +224 -0
- package/src/components/EditableSelect/index.ts +2 -0
- package/src/components/EditableText/EditableText.tsx +377 -0
- package/src/components/EditableText/index.ts +2 -0
- package/src/components/EmptyState/EmptyState.figma.tsx +33 -0
- package/src/components/EmptyState/EmptyState.tsx +230 -0
- package/src/components/EmptyState/index.ts +2 -0
- package/src/components/ErrorBoundary.tsx +135 -0
- package/src/components/ErrorState/ErrorState.tsx +197 -0
- package/src/components/ErrorState/index.ts +2 -0
- package/src/components/FeatureCard.tsx +42 -0
- package/src/components/FilterMenu/FilterMenu.figma.tsx +30 -0
- package/src/components/FilterMenu/FilterMenu.tsx +198 -0
- package/src/components/FilterMenu/FilterSubMenuTypes/BooleanFilterSubmenu.tsx +46 -0
- package/src/components/FilterMenu/FilterSubMenuTypes/SearchableFilterSubmenu.tsx +239 -0
- package/src/components/FilterMenu/FilterSubMenuTypes/index.ts +8 -0
- package/src/components/FilterMenu/defaultFilterSchemas.ts +63 -0
- package/src/components/FilterMenu/helpers.ts +115 -0
- package/src/components/FilterMenu/index.ts +35 -0
- package/src/components/FilterMenu/types.ts +101 -0
- package/src/components/IconButton/IconButton.css.ts +272 -0
- package/src/components/IconButton/IconButton.figma.tsx +47 -0
- package/src/components/IconButton/IconButton.tsx +72 -0
- package/src/components/IconButton/README.md +230 -0
- package/src/components/IconButton/index.ts +2 -0
- package/src/components/InfiniteScrollSentinel.tsx +86 -0
- package/src/components/InfiniteScrollTrigger.tsx +78 -0
- package/src/components/InfoCard.figma.tsx +47 -0
- package/src/components/InfoCard.tsx +216 -0
- package/src/components/KbdHint/KbdHint.tsx +23 -0
- package/src/components/KbdHint/index.ts +2 -0
- package/src/components/LabeledField/LabeledField.tsx +21 -0
- package/src/components/LabeledField/index.ts +2 -0
- package/src/components/LookupSelect/LookupSelect.css.ts +149 -0
- package/src/components/LookupSelect/LookupSelect.tsx +325 -0
- package/src/components/LookupSelect/index.ts +2 -0
- package/src/components/Menu/Menu.css.ts +89 -0
- package/src/components/Menu/Menu.tsx +105 -0
- package/src/components/Menu/index.ts +2 -0
- package/src/components/MessageBox/MessageBox.tsx +168 -0
- package/src/components/MessageBox/index.ts +2 -0
- package/src/components/MetricDisplay/MetricDisplay.tsx +55 -0
- package/src/components/MetricDisplay/index.ts +1 -0
- package/src/components/MultiSelect/MultiSelect.tsx +278 -0
- package/src/components/MultiSelect/index.ts +2 -0
- package/src/components/Notifications/Notifications.tsx +12 -0
- package/src/components/Notifications/README.md +93 -0
- package/src/components/Notifications/index.ts +4 -0
- package/src/components/Notifications/showToast.tsx +100 -0
- package/src/components/PropertyRow/PropertyRow.tsx +96 -0
- package/src/components/PropertyRow/index.ts +2 -0
- package/src/components/RadioTile/RadioTile.tsx +253 -0
- package/src/components/RadioTile/index.ts +2 -0
- package/src/components/RichText/FormattingToolbar.css.ts +69 -0
- package/src/components/RichText/FormattingToolbar.tsx +112 -0
- package/src/components/RichText/RichTextInline.css.ts +54 -0
- package/src/components/RichText/RichTextInline.tsx +318 -0
- package/src/components/RichText/formattingCommands.ts +181 -0
- package/src/components/RichText/formattingTypes.ts +34 -0
- package/src/components/RichText/index.ts +49 -0
- package/src/components/RichText/richTextExtensions.ts +111 -0
- package/src/components/RichText/richTextHelpers.ts +65 -0
- package/src/components/RichText/richTextImage.ts +253 -0
- package/src/components/RichText/richTextImageHandlers.ts +244 -0
- package/src/components/RichText/richTextProse.css.ts +261 -0
- package/src/components/RichTextEditor/RichTextEditor.css.ts +82 -0
- package/src/components/RichTextEditor/RichTextEditor.tsx +204 -0
- package/src/components/RichTextEditor/index.ts +2 -0
- package/src/components/RichTextView/RichTextView.css.ts +11 -0
- package/src/components/RichTextView/RichTextView.tsx +114 -0
- package/src/components/RichTextView/index.ts +2 -0
- package/src/components/Schedule/Schedule.tsx +35 -0
- package/src/components/SchedulePicker/SchedulePicker.css.ts +42 -0
- package/src/components/SchedulePicker/SchedulePicker.tsx +130 -0
- package/src/components/SchedulePicker/index.ts +2 -0
- package/src/components/SearchableList/types.ts +30 -0
- package/src/components/SearchableSubMenu/SearchableSubMenu.css.ts +25 -0
- package/src/components/SearchableSubMenu/SearchableSubMenu.tsx +139 -0
- package/src/components/SearchableSubMenu/index.ts +2 -0
- package/src/components/Select/README.md +114 -0
- package/src/components/Select/Select.css.ts +110 -0
- package/src/components/Select/Select.tsx +133 -0
- package/src/components/Select/index.ts +2 -0
- package/src/components/SelectCreatable/SelectCreatable.css.ts +16 -0
- package/src/components/SelectCreatable/SelectCreatable.tsx +203 -0
- package/src/components/SelectCreatable/index.ts +2 -0
- package/src/components/SettingsCard/SettingsCard.tsx +98 -0
- package/src/components/SettingsCard/index.ts +2 -0
- package/src/components/Sidebar/Sidebar.css.ts +91 -0
- package/src/components/Sidebar/Sidebar.tsx +129 -0
- package/src/components/Sidebar/index.ts +5 -0
- package/src/components/SimpleList/SimpleList.css.ts +12 -0
- package/src/components/SimpleList/SimpleList.tsx +44 -0
- package/src/components/SimpleList/index.ts +2 -0
- package/src/components/SimpleTable/SimpleTable.tsx +296 -0
- package/src/components/SimpleTable/index.ts +2 -0
- package/src/components/SlashRichTextEditor/SelectionBubbleMenu.css.ts +62 -0
- package/src/components/SlashRichTextEditor/SelectionBubbleMenu.tsx +85 -0
- package/src/components/SlashRichTextEditor/SlashCommandMenu.css.ts +124 -0
- package/src/components/SlashRichTextEditor/SlashCommandMenu.tsx +168 -0
- package/src/components/SlashRichTextEditor/SlashRichTextEditor.css.ts +81 -0
- package/src/components/SlashRichTextEditor/SlashRichTextEditor.tsx +538 -0
- package/src/components/SlashRichTextEditor/SlashSuggestionExtension.ts +48 -0
- package/src/components/SlashRichTextEditor/index.ts +13 -0
- package/src/components/SlashRichTextEditor/types.ts +48 -0
- package/src/components/StatCard/StatCard.css.ts +70 -0
- package/src/components/StatCard/StatCard.tsx +201 -0
- package/src/components/StatCard/index.ts +1 -0
- package/src/components/StatusBadge/StatusBadge.tsx +70 -0
- package/src/components/StatusBadge/index.ts +2 -0
- package/src/components/StatusIndicator/StatusIndicator.tsx +67 -0
- package/src/components/StatusIndicator/index.ts +6 -0
- package/src/components/SubNavigation/SubNavigation.css.ts +72 -0
- package/src/components/SubNavigation/SubNavigation.tsx +104 -0
- package/src/components/SubNavigation/index.ts +2 -0
- package/src/components/SuspenseLoader.tsx +22 -0
- package/src/components/Table/SortableColumnHeader.tsx +99 -0
- package/src/components/Table/TableSkeletonRows.figma.tsx +22 -0
- package/src/components/Table/TableSkeletonRows.tsx +113 -0
- package/src/components/Table/index.ts +9 -0
- package/src/components/TableActionsMenu.tsx +58 -0
- package/src/components/TableCard.tsx +29 -0
- package/src/components/TableContainer/TableContainer.tsx +86 -0
- package/src/components/TableContainer/index.ts +2 -0
- package/src/components/TableControlBar/TableControlBar.tsx +156 -0
- package/src/components/TableControlBar/TableSelectionButton.tsx +57 -0
- package/src/components/TableControlBar/index.ts +13 -0
- package/src/components/TableControlBar/useTableControlBar.tsx +314 -0
- package/src/components/TableSelection/TableSelection.tsx +43 -0
- package/src/components/TableSelection/index.ts +5 -0
- package/src/components/Tabs/README.md +76 -0
- package/src/components/Tabs/Tabs.css.ts +54 -0
- package/src/components/Tabs/Tabs.figma.tsx +47 -0
- package/src/components/Tabs/Tabs.tsx +96 -0
- package/src/components/Tabs/index.ts +8 -0
- package/src/components/TextInput/README.md +98 -0
- package/src/components/TextInput/SearchTextInput.figma.tsx +22 -0
- package/src/components/TextInput/SearchTextInput.tsx +150 -0
- package/src/components/TextInput/TextInput.figma.tsx +44 -0
- package/src/components/TextInput/TextInput.tsx +42 -0
- package/src/components/TextInput/index.ts +4 -0
- package/src/components/ThemeSwitcher.figma.tsx +28 -0
- package/src/components/ThemeSwitcher.tsx +69 -0
- package/src/components/TrendBadge/TrendBadge.tsx +76 -0
- package/src/components/TrendBadge/index.ts +2 -0
- package/src/components/TruncatedText.tsx +115 -0
- package/src/components/Typography/Text.tsx +74 -0
- package/src/components/Typography/Title.tsx +100 -0
- package/src/components/Typography/index.ts +4 -0
- package/src/geist-fonts.ts +48 -0
- package/src/hooks/index.ts +31 -0
- package/src/hooks/useFilters.ts +152 -0
- package/src/hooks/useInfiniteScroll.ts +62 -0
- package/src/hooks/usePlatform.ts +33 -0
- package/src/hooks/useServerTable.ts +495 -0
- package/src/hooks/useTableSelection.ts +102 -0
- package/src/hooks/useTableSort.ts +259 -0
- package/src/index.ts +483 -0
- package/src/mantine.ts +25 -0
- package/src/theme/mantineVars.ts +12 -0
- package/src/theme/themeContract.css.ts +131 -0
- package/src/theme/themeVars.ts +31 -0
- package/src/theme.ts +168 -0
- package/src/tokens/color-types.ts +107 -0
- package/src/tokens/colors.ts +243 -0
- package/src/tokens/index.ts +14 -0
- package/src/tokens/radius.ts +17 -0
- package/src/tokens/semantic-colors.ts +224 -0
- package/src/tokens/semantic-tokens-css.ts +53 -0
- package/src/tokens/shadows.ts +11 -0
- package/src/tokens/spacing.ts +20 -0
- package/src/tokens/text-styles.ts +179 -0
- package/src/tokens/typography.ts +40 -0
- package/src/tokens/zIndex.ts +27 -0
- package/src/types/mantine-theme.d.ts +17 -0
- package/src/types/tanstack-table.d.ts +22 -0
- package/src/utils/avatar.ts +150 -0
- package/src/utils/chartHelpers.ts +53 -0
- package/src/utils/color-props.ts +77 -0
- package/src/utils/createDesignComponent.tsx +104 -0
- package/src/utils/nestFlatRows.ts +111 -0
- package/src/utils/withStaticComponents.ts +6 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Design System Layout Primitives
|
|
3
|
+
*
|
|
4
|
+
* Wrapped versions of Mantine layout components with type-safe color props.
|
|
5
|
+
* These replace the direct Mantine re-exports to enforce design system tokens.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { Children, Fragment, type ReactElement } from 'react';
|
|
9
|
+
|
|
10
|
+
import {
|
|
11
|
+
Box as MantineBox,
|
|
12
|
+
Center as MantineCenter,
|
|
13
|
+
factory,
|
|
14
|
+
type Factory,
|
|
15
|
+
Flex as MantineFlex,
|
|
16
|
+
Grid as MantineGrid,
|
|
17
|
+
Group as MantineGroup,
|
|
18
|
+
polymorphicFactory,
|
|
19
|
+
type PolymorphicFactory,
|
|
20
|
+
SimpleGrid as MantineSimpleGrid,
|
|
21
|
+
Stack as MantineStack,
|
|
22
|
+
type BoxProps as MantineBoxProps,
|
|
23
|
+
type CenterProps as MantineCenterProps,
|
|
24
|
+
type FlexProps as MantineFlexProps,
|
|
25
|
+
type GridCssVariables as MantineGridCssVariables,
|
|
26
|
+
type GridProps as MantineGridProps,
|
|
27
|
+
type GridStylesNames as MantineGridStylesNames,
|
|
28
|
+
type GroupProps as MantineGroupProps,
|
|
29
|
+
type SimpleGridProps as MantineSimpleGridProps,
|
|
30
|
+
type StackProps as MantineStackProps,
|
|
31
|
+
} from '@mantine/core';
|
|
32
|
+
|
|
33
|
+
import { Divider } from './InteractivePrimitives';
|
|
34
|
+
import { resolveColorToken } from '../../utils/color-props';
|
|
35
|
+
import {
|
|
36
|
+
createDesignComponent,
|
|
37
|
+
type WithDesignColors,
|
|
38
|
+
} from '../../utils/createDesignComponent';
|
|
39
|
+
import { withStaticComponents } from '../../utils/withStaticComponents';
|
|
40
|
+
|
|
41
|
+
import type { StrokeColor } from '../../tokens/color-types';
|
|
42
|
+
|
|
43
|
+
// Layout primitives - all use the standard DesignSystemColorProps (c, bg, borderColor)
|
|
44
|
+
export const Box = createDesignComponent<
|
|
45
|
+
MantineBoxProps,
|
|
46
|
+
'div',
|
|
47
|
+
HTMLDivElement
|
|
48
|
+
>(MantineBox, 'Box');
|
|
49
|
+
export const Flex = createDesignComponent<
|
|
50
|
+
MantineFlexProps,
|
|
51
|
+
'div',
|
|
52
|
+
HTMLDivElement
|
|
53
|
+
>(MantineFlex, 'Flex');
|
|
54
|
+
|
|
55
|
+
export type StackProps = WithDesignColors<MantineStackProps> & {
|
|
56
|
+
/**
|
|
57
|
+
* Render a divider line between direct children (skipped after the last)
|
|
58
|
+
* so a list of items reads as separated rows without each child having to
|
|
59
|
+
* know its own position. Pass `true` for the default subtle stroke or a
|
|
60
|
+
* `StrokeColor` token to customize the colour.
|
|
61
|
+
*
|
|
62
|
+
* Implemented by interleaving Mantine `<Divider />` elements between
|
|
63
|
+
* children so the Stack's `gap` applies symmetrically on both sides — the
|
|
64
|
+
* line lands in the middle of the gutter rather than flush against one row.
|
|
65
|
+
*
|
|
66
|
+
* The interleaved nodes are plain `<div role="separator">` elements, which
|
|
67
|
+
* is fine for the default `<div>` Stack and any flex container that
|
|
68
|
+
* accepts arbitrary children. If you set `component` to a semantic list
|
|
69
|
+
* container (`ul`, `ol`, `dl`, `menu`) we leave the divider off — non-list
|
|
70
|
+
* children inside those wrappers are invalid HTML. A dev-mode warning is
|
|
71
|
+
* emitted so the misuse is caught at the call site.
|
|
72
|
+
*/
|
|
73
|
+
divider?: boolean | StrokeColor;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
// Stacks rendered as semantic list containers reject the divider prop — see
|
|
77
|
+
// the `divider` JSDoc above for why.
|
|
78
|
+
const LIST_LIKE_COMPONENTS = new Set(['ul', 'ol', 'dl', 'menu']);
|
|
79
|
+
|
|
80
|
+
function isListLikeComponent(component: unknown): boolean {
|
|
81
|
+
return typeof component === 'string' && LIST_LIKE_COMPONENTS.has(component);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
type StackFactory = PolymorphicFactory<{
|
|
85
|
+
props: StackProps;
|
|
86
|
+
defaultComponent: 'div';
|
|
87
|
+
defaultRef: HTMLDivElement;
|
|
88
|
+
}>;
|
|
89
|
+
|
|
90
|
+
export const Stack = polymorphicFactory<StackFactory>(
|
|
91
|
+
({ c, bg, borderColor, divider, children, ref, ...rest }) => {
|
|
92
|
+
const resolvedProps: Record<string, unknown> = { ...rest, ref };
|
|
93
|
+
|
|
94
|
+
const resolvedC = resolveColorToken(c);
|
|
95
|
+
if (resolvedC !== undefined) {
|
|
96
|
+
resolvedProps.c = resolvedC;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const resolvedBg = resolveColorToken(bg);
|
|
100
|
+
if (resolvedBg !== undefined) {
|
|
101
|
+
resolvedProps.bg = resolvedBg;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (borderColor) {
|
|
105
|
+
const resolvedBorderColor = resolveColorToken(borderColor);
|
|
106
|
+
resolvedProps.bd = `1px solid ${resolvedBorderColor}`;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const stackComponent = (rest as { component?: unknown }).component;
|
|
110
|
+
|
|
111
|
+
if (!divider) {
|
|
112
|
+
return <MantineStack {...resolvedProps}>{children}</MantineStack>;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (isListLikeComponent(stackComponent)) {
|
|
116
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
117
|
+
// eslint-disable-next-line no-console
|
|
118
|
+
console.warn(
|
|
119
|
+
`<Stack divider> ignored: cannot interleave <Divider /> between <li> children inside <${String(
|
|
120
|
+
stackComponent,
|
|
121
|
+
)}>. Render the list manually or wrap each item in its own bordered row.`,
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
return <MantineStack {...resolvedProps}>{children}</MantineStack>;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const dividerColor: StrokeColor =
|
|
128
|
+
divider === true ? 'stroke.subdued.default' : divider;
|
|
129
|
+
|
|
130
|
+
// `Children.toArray` filters out null/false/undefined and assigns stable
|
|
131
|
+
// keys, so conditional children don't end up with extra dividers around
|
|
132
|
+
// empty slots.
|
|
133
|
+
const items = Children.toArray(children);
|
|
134
|
+
|
|
135
|
+
return (
|
|
136
|
+
<MantineStack {...resolvedProps}>
|
|
137
|
+
{items.map((child, idx) => {
|
|
138
|
+
const childKey =
|
|
139
|
+
(child as ReactElement).key != null
|
|
140
|
+
? (child as ReactElement).key
|
|
141
|
+
: `stack-item-${idx}`;
|
|
142
|
+
return (
|
|
143
|
+
<Fragment key={childKey}>
|
|
144
|
+
{child}
|
|
145
|
+
{idx < items.length - 1 ? <Divider color={dividerColor} /> : null}
|
|
146
|
+
</Fragment>
|
|
147
|
+
);
|
|
148
|
+
})}
|
|
149
|
+
</MantineStack>
|
|
150
|
+
);
|
|
151
|
+
},
|
|
152
|
+
);
|
|
153
|
+
Stack.displayName = 'Stack';
|
|
154
|
+
export const Group = createDesignComponent<
|
|
155
|
+
MantineGroupProps,
|
|
156
|
+
'div',
|
|
157
|
+
HTMLDivElement
|
|
158
|
+
>(MantineGroup, 'Group');
|
|
159
|
+
export const SimpleGrid = createDesignComponent<
|
|
160
|
+
MantineSimpleGridProps,
|
|
161
|
+
'div',
|
|
162
|
+
HTMLDivElement
|
|
163
|
+
>(MantineSimpleGrid, 'SimpleGrid');
|
|
164
|
+
export const Center = createDesignComponent<
|
|
165
|
+
MantineCenterProps,
|
|
166
|
+
'div',
|
|
167
|
+
HTMLDivElement
|
|
168
|
+
>(MantineCenter, 'Center');
|
|
169
|
+
|
|
170
|
+
// Grid needs special handling to preserve Grid.Col compound component
|
|
171
|
+
export type GridProps = WithDesignColors<MantineGridProps> & {
|
|
172
|
+
gap?: MantineGridProps['gap'];
|
|
173
|
+
rowGap?: MantineGridProps['rowGap'];
|
|
174
|
+
columnGap?: MantineGridProps['columnGap'];
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
type DesignGridFactory = Factory<{
|
|
178
|
+
props: GridProps;
|
|
179
|
+
ref: HTMLDivElement;
|
|
180
|
+
stylesNames: MantineGridStylesNames;
|
|
181
|
+
vars: MantineGridCssVariables;
|
|
182
|
+
staticComponents: {
|
|
183
|
+
Col: typeof MantineGrid.Col;
|
|
184
|
+
};
|
|
185
|
+
}>;
|
|
186
|
+
|
|
187
|
+
const GridRoot = factory<DesignGridFactory>(
|
|
188
|
+
({ c, bg, borderColor, ref, ...rest }) => {
|
|
189
|
+
const resolvedProps: Record<string, unknown> = { ...rest, ref };
|
|
190
|
+
|
|
191
|
+
const resolvedC = resolveColorToken(c);
|
|
192
|
+
if (resolvedC !== undefined) {
|
|
193
|
+
resolvedProps.c = resolvedC;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const resolvedBg = resolveColorToken(bg);
|
|
197
|
+
if (resolvedBg !== undefined) {
|
|
198
|
+
resolvedProps.bg = resolvedBg;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (borderColor) {
|
|
202
|
+
const resolvedBorderColor = resolveColorToken(borderColor);
|
|
203
|
+
resolvedProps.bd = `1px solid ${resolvedBorderColor}`;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return <MantineGrid {...resolvedProps} />;
|
|
207
|
+
},
|
|
208
|
+
);
|
|
209
|
+
|
|
210
|
+
GridRoot.displayName = 'Grid';
|
|
211
|
+
|
|
212
|
+
export const Grid = withStaticComponents(GridRoot, { Col: MantineGrid.Col });
|
|
213
|
+
|
|
214
|
+
// Export prop types for consumers (StackProps is exported above with the
|
|
215
|
+
// `divider` prop so its definition stays next to the wrapped Stack component).
|
|
216
|
+
export type BoxProps = WithDesignColors<MantineBoxProps>;
|
|
217
|
+
export type FlexProps = WithDesignColors<MantineFlexProps>;
|
|
218
|
+
export type GroupProps = WithDesignColors<MantineGroupProps>;
|
|
219
|
+
export type SimpleGridProps = WithDesignColors<MantineSimpleGridProps>;
|
|
220
|
+
export type CenterProps = WithDesignColors<MantineCenterProps>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Grid, Group, SimpleGrid, Stack } from './LayoutPrimitives';
|
|
2
|
+
|
|
3
|
+
void (
|
|
4
|
+
<>
|
|
5
|
+
<Grid gap="sm" rowGap="xs" columnGap="md" grow>
|
|
6
|
+
<Grid.Col span="content">Column</Grid.Col>
|
|
7
|
+
</Grid>
|
|
8
|
+
<Group gap="sm">Grouped content</Group>
|
|
9
|
+
<Stack gap="md">Stacked content</Stack>
|
|
10
|
+
<SimpleGrid spacing="sm" verticalSpacing="lg" cols={2}>
|
|
11
|
+
<div>One</div>
|
|
12
|
+
<div>Two</div>
|
|
13
|
+
</SimpleGrid>
|
|
14
|
+
</>
|
|
15
|
+
);
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Design System Surface Primitives
|
|
3
|
+
*
|
|
4
|
+
* Wrapped versions of Mantine surface/container components with type-safe color props.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
Card as MantineCard,
|
|
9
|
+
Container as MantineContainer,
|
|
10
|
+
Paper as MantinePaper,
|
|
11
|
+
type CardProps as MantineCardProps,
|
|
12
|
+
type ContainerProps as MantineContainerProps,
|
|
13
|
+
type PaperProps as MantinePaperProps,
|
|
14
|
+
} from '@mantine/core';
|
|
15
|
+
|
|
16
|
+
import {
|
|
17
|
+
createDesignComponent,
|
|
18
|
+
type WithDesignColors,
|
|
19
|
+
} from '../../utils/createDesignComponent';
|
|
20
|
+
import { withStaticComponents } from '../../utils/withStaticComponents';
|
|
21
|
+
|
|
22
|
+
// Surface primitives
|
|
23
|
+
export const Paper = createDesignComponent<
|
|
24
|
+
MantinePaperProps,
|
|
25
|
+
'div',
|
|
26
|
+
HTMLDivElement
|
|
27
|
+
>(MantinePaper, 'Paper');
|
|
28
|
+
export const Container = createDesignComponent<
|
|
29
|
+
MantineContainerProps,
|
|
30
|
+
'div',
|
|
31
|
+
HTMLDivElement
|
|
32
|
+
>(MantineContainer, 'Container');
|
|
33
|
+
|
|
34
|
+
// Card needs special handling to preserve Card.Section compound component
|
|
35
|
+
const CardBase = createDesignComponent<MantineCardProps, 'div', HTMLDivElement>(
|
|
36
|
+
MantineCard,
|
|
37
|
+
'Card',
|
|
38
|
+
);
|
|
39
|
+
export const Card = withStaticComponents(CardBase, {
|
|
40
|
+
Section: MantineCard.Section,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// Export prop types for consumers
|
|
44
|
+
export type CardProps = WithDesignColors<MantineCardProps>;
|
|
45
|
+
export type PaperProps = WithDesignColors<MantinePaperProps>;
|
|
46
|
+
export type ContainerProps = WithDesignColors<MantineContainerProps>;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Menu } from '../Menu';
|
|
2
|
+
|
|
3
|
+
// Design System Primitives - wrapped Mantine components with typed color props
|
|
4
|
+
|
|
5
|
+
// Layout primitives
|
|
6
|
+
export { FluidGrid } from './FluidGrid';
|
|
7
|
+
export type { FluidGridProps } from './FluidGrid';
|
|
8
|
+
export {
|
|
9
|
+
Box,
|
|
10
|
+
Center,
|
|
11
|
+
Flex,
|
|
12
|
+
Grid,
|
|
13
|
+
Group,
|
|
14
|
+
SimpleGrid,
|
|
15
|
+
Stack,
|
|
16
|
+
} from './LayoutPrimitives';
|
|
17
|
+
export type {
|
|
18
|
+
BoxProps,
|
|
19
|
+
CenterProps,
|
|
20
|
+
FlexProps,
|
|
21
|
+
GridProps,
|
|
22
|
+
GroupProps,
|
|
23
|
+
SimpleGridProps,
|
|
24
|
+
StackProps,
|
|
25
|
+
} from './LayoutPrimitives';
|
|
26
|
+
|
|
27
|
+
// Surface primitives
|
|
28
|
+
export { Card, Container, Paper } from './SurfacePrimitives';
|
|
29
|
+
export type {
|
|
30
|
+
CardProps,
|
|
31
|
+
ContainerProps,
|
|
32
|
+
PaperProps,
|
|
33
|
+
} from './SurfacePrimitives';
|
|
34
|
+
export { Menu };
|
|
35
|
+
|
|
36
|
+
export const MenuItem: typeof Menu.Item = Menu.Item;
|
|
37
|
+
export type { MenuItemProps, MenuItemVariant, MenuProps } from '../Menu';
|
|
38
|
+
|
|
39
|
+
// Interactive primitives
|
|
40
|
+
export {
|
|
41
|
+
Alert,
|
|
42
|
+
Avatar,
|
|
43
|
+
Divider,
|
|
44
|
+
Loader,
|
|
45
|
+
NavLink,
|
|
46
|
+
Switch,
|
|
47
|
+
} from './InteractivePrimitives';
|
|
48
|
+
export type {
|
|
49
|
+
AlertProps,
|
|
50
|
+
AvatarProps,
|
|
51
|
+
DividerProps,
|
|
52
|
+
LoaderProps,
|
|
53
|
+
NavLinkProps,
|
|
54
|
+
SwitchProps,
|
|
55
|
+
} from './InteractivePrimitives';
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Details / Summary component styles – vanilla-extract with semantic design tokens
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { style } from '@vanilla-extract/css';
|
|
6
|
+
|
|
7
|
+
import { mantineVars } from '../../theme/mantineVars';
|
|
8
|
+
import { tokens } from '../../theme/themeContract.css';
|
|
9
|
+
|
|
10
|
+
export const details = style({
|
|
11
|
+
overflow: 'hidden',
|
|
12
|
+
width: '100%',
|
|
13
|
+
border: `1px solid ${tokens.color.stroke.subduedDefault}`,
|
|
14
|
+
borderRadius: tokens.radius.lg,
|
|
15
|
+
selectors: {
|
|
16
|
+
[`${mantineVars.darkSelector} &`]: {
|
|
17
|
+
backgroundColor: tokens.color.background.default,
|
|
18
|
+
borderColor: tokens.color.stroke.default,
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
export const summary = style({
|
|
24
|
+
cursor: 'pointer',
|
|
25
|
+
listStyle: 'none',
|
|
26
|
+
minHeight: 0,
|
|
27
|
+
selectors: {
|
|
28
|
+
'&:focus-visible': {
|
|
29
|
+
outline: `2px solid ${tokens.color.stroke.primaryDefault}`,
|
|
30
|
+
outlineOffset: '4px',
|
|
31
|
+
borderRadius: tokens.radius.sm,
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
export const chevronWrapper = style({
|
|
37
|
+
display: 'inline-flex',
|
|
38
|
+
alignItems: 'center',
|
|
39
|
+
justifyContent: 'center',
|
|
40
|
+
flexShrink: 0,
|
|
41
|
+
minWidth: 34,
|
|
42
|
+
minHeight: 34,
|
|
43
|
+
color: tokens.color.text.subduedDefault,
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
export const chevronIcon = style({
|
|
47
|
+
flexShrink: 0,
|
|
48
|
+
transition: 'transform 0.2s ease',
|
|
49
|
+
selectors: {
|
|
50
|
+
[`${details}[open] &`]: {
|
|
51
|
+
transform: 'rotate(90deg)',
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
export const summaryContent = style({
|
|
57
|
+
flex: 1,
|
|
58
|
+
minWidth: 0,
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
export const actions = style({
|
|
62
|
+
flexShrink: 0,
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
export const contentWrapper = style({
|
|
66
|
+
borderTop: `1px solid ${tokens.color.stroke.default}`,
|
|
67
|
+
selectors: {
|
|
68
|
+
[`${mantineVars.darkSelector} &`]: {
|
|
69
|
+
borderTopColor: tokens.color.stroke.default,
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
export const content = style({});
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { useState, type CSSProperties, type ReactNode } from 'react';
|
|
2
|
+
|
|
3
|
+
import { ChevronRight } from 'lucide-react';
|
|
4
|
+
|
|
5
|
+
import { Box, Flex, type BoxProps } from '../DesignSystemPrimitives';
|
|
6
|
+
import * as classes from './Details.css';
|
|
7
|
+
|
|
8
|
+
export interface DetailsProps {
|
|
9
|
+
/** Content of the summary row (title, subtitle, etc.) */
|
|
10
|
+
summary: ReactNode;
|
|
11
|
+
/** Expandable content shown when open */
|
|
12
|
+
children: ReactNode;
|
|
13
|
+
/** Optional action icons rendered on the far right of the summary row */
|
|
14
|
+
actions?: ReactNode;
|
|
15
|
+
/** Whether the details start expanded (uncontrolled) */
|
|
16
|
+
defaultOpen?: boolean;
|
|
17
|
+
/** Controlled open state */
|
|
18
|
+
open?: boolean;
|
|
19
|
+
/** Callback when open state changes (use with controlled `open`) */
|
|
20
|
+
onOpenChange?: (open: boolean) => void;
|
|
21
|
+
/** Optional background color using the same Mantine-style prop shape as layout primitives */
|
|
22
|
+
bg?: BoxProps['bg'];
|
|
23
|
+
/** Optional border override using Mantine's `bd` prop format */
|
|
24
|
+
bd?: BoxProps['bd'];
|
|
25
|
+
/** Optional border radius override using Mantine's `bdrs` prop format */
|
|
26
|
+
bdrs?: BoxProps['bdrs'];
|
|
27
|
+
/** Optional padding override using Mantine's `p` prop format */
|
|
28
|
+
p?: BoxProps['p'];
|
|
29
|
+
/** Hide the built-in chevron when the summary provides its own icon */
|
|
30
|
+
hideChevron?: boolean;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Disclosure widget using native <details> and <summary> per W3C spec.
|
|
35
|
+
* Summary row shows a chevron (right when closed, down when open), summary content,
|
|
36
|
+
* and optional actions on the far right. When expanded, a divider and content
|
|
37
|
+
* area are shown; the border encloses the full block.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```tsx
|
|
41
|
+
* <Details
|
|
42
|
+
* summary={<><Text variant="body1.stronger">Sales Department</Text><Text variant="caption1" c="text.subdued.default">21 Members</Text></>}
|
|
43
|
+
* actions={<IconButton variant="ghost" size="sm" aria-label="More"><MoreVertical /></IconButton>}
|
|
44
|
+
* >
|
|
45
|
+
* <Stack gap="md">...</Stack>
|
|
46
|
+
* </Details>
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export function Details({
|
|
50
|
+
summary,
|
|
51
|
+
children,
|
|
52
|
+
actions,
|
|
53
|
+
defaultOpen,
|
|
54
|
+
open: controlledOpen,
|
|
55
|
+
onOpenChange,
|
|
56
|
+
bg,
|
|
57
|
+
p = 'md',
|
|
58
|
+
bd,
|
|
59
|
+
bdrs,
|
|
60
|
+
hideChevron = false,
|
|
61
|
+
}: DetailsProps) {
|
|
62
|
+
const isControlled = controlledOpen !== undefined;
|
|
63
|
+
const [uncontrolledOpen, setUncontrolledOpen] = useState(
|
|
64
|
+
defaultOpen ?? false,
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
const handleToggle = (e: React.ToggleEvent<HTMLDetailsElement>) => {
|
|
68
|
+
const nextOpen = e.currentTarget.open;
|
|
69
|
+
|
|
70
|
+
if (isControlled) {
|
|
71
|
+
e.preventDefault();
|
|
72
|
+
onOpenChange?.(!controlledOpen);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
setUncontrolledOpen(nextOpen);
|
|
77
|
+
onOpenChange?.(nextOpen);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const contentWrapperStyle: CSSProperties | undefined =
|
|
81
|
+
typeof bd === 'string' || typeof bd === 'number'
|
|
82
|
+
? { borderTop: bd }
|
|
83
|
+
: undefined;
|
|
84
|
+
|
|
85
|
+
return (
|
|
86
|
+
<Box
|
|
87
|
+
component="details"
|
|
88
|
+
className={classes.details}
|
|
89
|
+
open={isControlled ? controlledOpen : uncontrolledOpen}
|
|
90
|
+
onToggle={handleToggle}
|
|
91
|
+
bg={bg}
|
|
92
|
+
bd={bd}
|
|
93
|
+
bdrs={bdrs}
|
|
94
|
+
w="100%"
|
|
95
|
+
>
|
|
96
|
+
<Flex
|
|
97
|
+
component="summary"
|
|
98
|
+
align="center"
|
|
99
|
+
gap="xs"
|
|
100
|
+
p="xs"
|
|
101
|
+
className={classes.summary}
|
|
102
|
+
>
|
|
103
|
+
{!hideChevron ? (
|
|
104
|
+
<Flex
|
|
105
|
+
component="span"
|
|
106
|
+
align="center"
|
|
107
|
+
justify="center"
|
|
108
|
+
className={classes.chevronWrapper}
|
|
109
|
+
aria-hidden
|
|
110
|
+
data-testid="details-chevron"
|
|
111
|
+
>
|
|
112
|
+
<ChevronRight size={16} className={classes.chevronIcon} />
|
|
113
|
+
</Flex>
|
|
114
|
+
) : null}
|
|
115
|
+
<Box component="span" className={classes.summaryContent}>
|
|
116
|
+
{summary}
|
|
117
|
+
</Box>
|
|
118
|
+
{actions != null ? (
|
|
119
|
+
<Flex
|
|
120
|
+
component="span"
|
|
121
|
+
align="center"
|
|
122
|
+
gap="xs"
|
|
123
|
+
className={classes.actions}
|
|
124
|
+
>
|
|
125
|
+
{actions}
|
|
126
|
+
</Flex>
|
|
127
|
+
) : null}
|
|
128
|
+
</Flex>
|
|
129
|
+
<Box
|
|
130
|
+
component="div"
|
|
131
|
+
className={classes.contentWrapper}
|
|
132
|
+
style={contentWrapperStyle}
|
|
133
|
+
>
|
|
134
|
+
<Box component="div" p={p} className={classes.content}>
|
|
135
|
+
{children}
|
|
136
|
+
</Box>
|
|
137
|
+
</Box>
|
|
138
|
+
</Box>
|
|
139
|
+
);
|
|
140
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DownloadCard component styles – vanilla-extract with semantic design tokens
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { style } from '@vanilla-extract/css';
|
|
6
|
+
|
|
7
|
+
import { mantineVars } from '../../theme/mantineVars';
|
|
8
|
+
import { tokens } from '../../theme/themeContract.css';
|
|
9
|
+
|
|
10
|
+
export const container = style({
|
|
11
|
+
backgroundColor: tokens.color.background.default,
|
|
12
|
+
border: `1px solid ${tokens.color.stroke.default}`,
|
|
13
|
+
borderRadius: tokens.radius.lg,
|
|
14
|
+
padding: `${tokens.spacing.xs} ${tokens.spacing.md}`,
|
|
15
|
+
width: '100%',
|
|
16
|
+
selectors: {
|
|
17
|
+
[`${mantineVars.darkSelector} &`]: {
|
|
18
|
+
backgroundColor: tokens.color.background.default,
|
|
19
|
+
borderColor: tokens.color.stroke.default,
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
});
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { Download } from 'lucide-react';
|
|
2
|
+
|
|
3
|
+
import { Box, Flex } from '@mantine/core';
|
|
4
|
+
|
|
5
|
+
import { IconButton } from '../IconButton';
|
|
6
|
+
import { Text } from '../Typography';
|
|
7
|
+
import * as classes from './DownloadCard.css';
|
|
8
|
+
|
|
9
|
+
export interface DownloadCardProps {
|
|
10
|
+
/** Platform name (e.g., "Windows", "MacOS") */
|
|
11
|
+
platform: string;
|
|
12
|
+
/** Version information (e.g., "Latest (1.4.2)") */
|
|
13
|
+
version: string;
|
|
14
|
+
/** Callback when download button is clicked */
|
|
15
|
+
onDownload?: () => void;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* DownloadCard component for displaying downloadable installers.
|
|
20
|
+
*
|
|
21
|
+
* Features:
|
|
22
|
+
* - Platform name with medium font weight
|
|
23
|
+
* - Version information with muted color
|
|
24
|
+
* - Download icon button
|
|
25
|
+
* - White background with border
|
|
26
|
+
* - Horizontal layout with space-between
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```tsx
|
|
30
|
+
* <DownloadCard
|
|
31
|
+
* platform="Windows"
|
|
32
|
+
* version="Latest (1.4.2)"
|
|
33
|
+
* onDownload={() => console.log('Download Windows installer')}
|
|
34
|
+
* />
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export function DownloadCard({
|
|
38
|
+
platform,
|
|
39
|
+
version,
|
|
40
|
+
onDownload,
|
|
41
|
+
}: DownloadCardProps) {
|
|
42
|
+
return (
|
|
43
|
+
<Box className={classes.container}>
|
|
44
|
+
<Flex justify="space-between" align="center" w="100%">
|
|
45
|
+
<Flex direction="column" gap="3xs">
|
|
46
|
+
<Text variant="body1.strong">{platform}</Text>
|
|
47
|
+
<Text variant="caption1" c="text.subdued.default">
|
|
48
|
+
{version}
|
|
49
|
+
</Text>
|
|
50
|
+
</Flex>
|
|
51
|
+
|
|
52
|
+
<IconButton
|
|
53
|
+
variant="outline"
|
|
54
|
+
size="md"
|
|
55
|
+
onClick={onDownload}
|
|
56
|
+
aria-label={`Download ${platform}`}
|
|
57
|
+
>
|
|
58
|
+
<Download size={16} />
|
|
59
|
+
</IconButton>
|
|
60
|
+
</Flex>
|
|
61
|
+
</Box>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Drawer component styles – vanilla-extract
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { style } from '@vanilla-extract/css';
|
|
6
|
+
|
|
7
|
+
import { tokens } from '../../theme/themeContract.css';
|
|
8
|
+
import { zIndex } from '../../tokens';
|
|
9
|
+
|
|
10
|
+
export const resizeHandle = style({
|
|
11
|
+
position: 'absolute',
|
|
12
|
+
left: -5,
|
|
13
|
+
top: 0,
|
|
14
|
+
bottom: 0,
|
|
15
|
+
width: 10,
|
|
16
|
+
zIndex: zIndex.resizeHandle,
|
|
17
|
+
background: 'transparent',
|
|
18
|
+
cursor: 'ew-resize',
|
|
19
|
+
transition: 'background 0.2s',
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
export const resizing = style({
|
|
23
|
+
cursor: 'col-resize',
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
export const stickyHeader = style({
|
|
27
|
+
position: 'sticky',
|
|
28
|
+
top: `calc(${tokens.spacing.lg} * -1)`,
|
|
29
|
+
marginTop: `calc(${tokens.spacing.lg} * -1)`,
|
|
30
|
+
zIndex: zIndex.app,
|
|
31
|
+
backgroundColor: tokens.color.background.default,
|
|
32
|
+
});
|