@olympusoss/canvas 2.20.1 → 3.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/README.md +69 -35
- package/package.json +45 -177
- package/src/cn.ts +3 -0
- package/src/index.ts +12 -603
- package/src/theme.ts +62 -0
- package/src/tokens.ts +11 -0
- package/styles/base.css +17 -0
- package/styles/canvas.css +77 -52
- package/styles/components/alert.css +66 -0
- package/styles/components/app-shell.css +46 -0
- package/styles/components/avatar.css +22 -0
- package/styles/components/badge.css +83 -0
- package/styles/components/breadcrumb.css +35 -0
- package/styles/components/button-group.css +23 -0
- package/styles/components/button.css +107 -0
- package/styles/components/calendar.css +73 -0
- package/styles/components/card.css +58 -0
- package/styles/components/checkbox.css +55 -0
- package/styles/components/code-block.css +18 -0
- package/styles/components/combobox.css +75 -0
- package/styles/components/command.css +94 -0
- package/styles/components/data-table.css +142 -0
- package/styles/components/dialog.css +72 -0
- package/styles/components/dropdown.css +54 -0
- package/styles/components/empty-state.css +17 -0
- package/styles/components/field.css +27 -0
- package/styles/components/filter-panel.css +58 -0
- package/styles/components/form.css +27 -0
- package/styles/components/icon.css +8 -0
- package/styles/components/input-group.css +45 -0
- package/styles/components/input.css +56 -0
- package/styles/components/kbd.css +15 -0
- package/styles/components/page-header.css +52 -0
- package/styles/components/pagination.css +48 -0
- package/styles/components/popover.css +14 -0
- package/styles/components/radio.css +28 -0
- package/styles/components/row-menu.css +69 -0
- package/styles/components/section-card.css +49 -0
- package/styles/components/select.css +57 -0
- package/styles/components/separator.css +32 -0
- package/styles/components/sheet.css +70 -0
- package/styles/components/sidebar.css +146 -0
- package/styles/components/skeleton.css +32 -0
- package/styles/components/spinner.css +26 -0
- package/styles/components/stat-card.css +71 -0
- package/styles/components/stepper.css +63 -0
- package/styles/components/switch.css +45 -0
- package/styles/components/tabs.css +40 -0
- package/styles/components/textarea.css +31 -0
- package/styles/components/toast.css +95 -0
- package/styles/components/tooltip.css +53 -0
- package/styles/components/topbar.css +24 -0
- package/styles/components/typography.css +105 -0
- package/styles/patterns/backdrops.css +35 -0
- package/styles/patterns/density.css +66 -0
- package/styles/patterns/focus.css +22 -0
- package/styles/patterns/glass.css +85 -0
- package/styles/patterns/high-contrast.css +70 -0
- package/styles/patterns/reduced-motion.css +12 -0
- package/styles/patterns/scrollbar.css +10 -0
- package/styles/reset.css +89 -0
- package/styles/tokens/colors.css +106 -0
- package/styles/tokens/motion.css +33 -0
- package/styles/tokens/radius.css +10 -0
- package/styles/tokens/shadows.css +35 -0
- package/styles/tokens/spacing.css +19 -0
- package/styles/tokens/typography.css +6 -0
- package/styles/tokens/z-index.css +12 -0
- package/styles/utilities/display.css +66 -0
- package/styles/utilities/flexbox.css +240 -0
- package/styles/utilities/gap.css +288 -0
- package/styles/utilities/grid.css +138 -0
- package/styles/utilities/position.css +78 -0
- package/styles/utilities/sizing.css +138 -0
- package/tsconfig.json +20 -21
- package/src/components/atoms/README.md +0 -11
- package/src/components/atoms/aspect-ratio.tsx +0 -32
- package/src/components/atoms/avatar.tsx +0 -98
- package/src/components/atoms/badge.tsx +0 -44
- package/src/components/atoms/brand-mark.tsx +0 -74
- package/src/components/atoms/button.tsx +0 -105
- package/src/components/atoms/checkbox.tsx +0 -63
- package/src/components/atoms/flex-box.tsx +0 -105
- package/src/components/atoms/icon.tsx +0 -34
- package/src/components/atoms/input.tsx +0 -92
- package/src/components/atoms/label.tsx +0 -41
- package/src/components/atoms/logo.tsx +0 -89
- package/src/components/atoms/progress.tsx +0 -55
- package/src/components/atoms/radio-group.tsx +0 -122
- package/src/components/atoms/scroll-area.tsx +0 -106
- package/src/components/atoms/section.tsx +0 -48
- package/src/components/atoms/separator.tsx +0 -45
- package/src/components/atoms/skeleton.tsx +0 -17
- package/src/components/atoms/slider.tsx +0 -93
- package/src/components/atoms/spinner.tsx +0 -47
- package/src/components/atoms/switch.tsx +0 -60
- package/src/components/atoms/textarea.tsx +0 -78
- package/src/components/atoms/toggle.tsx +0 -80
- package/src/components/charts/activity-heatmap.tsx +0 -186
- package/src/components/charts/axes.tsx +0 -21
- package/src/components/charts/chart-container.tsx +0 -254
- package/src/components/charts/chart-legend.tsx +0 -67
- package/src/components/charts/chart-tooltip.tsx +0 -161
- package/src/components/charts/chart-types.tsx +0 -49
- package/src/components/charts/containers.tsx +0 -11
- package/src/components/charts/data.tsx +0 -16
- package/src/components/charts/details.tsx +0 -25
- package/src/components/charts/dot-pulse.tsx +0 -61
- package/src/components/charts/gauge.tsx +0 -106
- package/src/components/charts/grids.tsx +0 -8
- package/src/components/charts/index.ts +0 -62
- package/src/components/charts/labeled-bar-list.tsx +0 -85
- package/src/components/charts/metric-breakdown.tsx +0 -316
- package/src/components/charts/references.tsx +0 -8
- package/src/components/charts/service-health-list.tsx +0 -85
- package/src/components/charts/sparkline-area.tsx +0 -80
- package/src/components/charts/sparkline.tsx +0 -52
- package/src/components/charts/stacked-bar.tsx +0 -104
- package/src/components/charts/text.tsx +0 -10
- package/src/components/charts/world-heat-map-inner.tsx +0 -317
- package/src/components/charts/world-heat-map.tsx +0 -184
- package/src/components/molecules/README.md +0 -12
- package/src/components/molecules/action-bar.tsx +0 -73
- package/src/components/molecules/activity-item.tsx +0 -74
- package/src/components/molecules/alert.tsx +0 -86
- package/src/components/molecules/animated-background.tsx +0 -92
- package/src/components/molecules/auth-shell.tsx +0 -95
- package/src/components/molecules/brand-lockup.tsx +0 -48
- package/src/components/molecules/breadcrumb.tsx +0 -157
- package/src/components/molecules/button-group.tsx +0 -104
- package/src/components/molecules/calendar.tsx +0 -217
- package/src/components/molecules/card.tsx +0 -102
- package/src/components/molecules/client-brand.tsx +0 -95
- package/src/components/molecules/code-block.tsx +0 -86
- package/src/components/molecules/countdown-button.tsx +0 -92
- package/src/components/molecules/empty-state.tsx +0 -56
- package/src/components/molecules/error-state.tsx +0 -42
- package/src/components/molecules/field-display.tsx +0 -35
- package/src/components/molecules/input-otp.tsx +0 -74
- package/src/components/molecules/launcher-card.tsx +0 -152
- package/src/components/molecules/loading-state.tsx +0 -36
- package/src/components/molecules/notification-item.tsx +0 -67
- package/src/components/molecules/notification-list.tsx +0 -45
- package/src/components/molecules/number-badge.tsx +0 -53
- package/src/components/molecules/or-separator.tsx +0 -38
- package/src/components/molecules/page-header.tsx +0 -88
- package/src/components/molecules/page-tabs.tsx +0 -94
- package/src/components/molecules/pagination.tsx +0 -150
- package/src/components/molecules/password-input.tsx +0 -83
- package/src/components/molecules/password-strength-meter.tsx +0 -104
- package/src/components/molecules/phone-input.tsx +0 -200
- package/src/components/molecules/search-bar.tsx +0 -64
- package/src/components/molecules/secret-field.tsx +0 -158
- package/src/components/molecules/section-card.tsx +0 -91
- package/src/components/molecules/social-buttons.tsx +0 -165
- package/src/components/molecules/stat-card.tsx +0 -100
- package/src/components/molecules/status-badge.tsx +0 -42
- package/src/components/molecules/stepper.tsx +0 -96
- package/src/components/molecules/table.tsx +0 -157
- package/src/components/molecules/terminal.tsx +0 -74
- package/src/components/molecules/toggle-group.tsx +0 -145
- package/src/components/molecules/tooltip.tsx +0 -155
- package/src/components/molecules/user-avatar-chip.tsx +0 -71
- package/src/components/organisms/README.md +0 -14
- package/src/components/organisms/accordion.tsx +0 -154
- package/src/components/organisms/alert-dialog.tsx +0 -277
- package/src/components/organisms/carousel.tsx +0 -244
- package/src/components/organisms/collapsible.tsx +0 -69
- package/src/components/organisms/command.tsx +0 -144
- package/src/components/organisms/context-menu.tsx +0 -339
- package/src/components/organisms/dashboard-grid.tsx +0 -369
- package/src/components/organisms/data-table.tsx +0 -330
- package/src/components/organisms/dialog.tsx +0 -312
- package/src/components/organisms/drawer.tsx +0 -123
- package/src/components/organisms/dropdown-menu.tsx +0 -440
- package/src/components/organisms/editors/code-editor.tsx +0 -144
- package/src/components/organisms/editors/index.ts +0 -4
- package/src/components/organisms/editors/markdown-editor.tsx +0 -153
- package/src/components/organisms/editors/markdown-renderer.ts +0 -27
- package/src/components/organisms/editors/prose-canvas-classes.ts +0 -45
- package/src/components/organisms/editors/rich-text-editor.tsx +0 -126
- package/src/components/organisms/editors/toolbar/md-toolbar.tsx +0 -129
- package/src/components/organisms/editors/toolbar/rte-toolbar.tsx +0 -211
- package/src/components/organisms/editors/toolbar/toolbar-shell.tsx +0 -45
- package/src/components/organisms/editors/use-codemirror-theme.ts +0 -61
- package/src/components/organisms/error-boundary.tsx +0 -61
- package/src/components/organisms/form.tsx +0 -174
- package/src/components/organisms/hover-card.tsx +0 -115
- package/src/components/organisms/menubar.tsx +0 -498
- package/src/components/organisms/navbar.tsx +0 -104
- package/src/components/organisms/navigation-menu.tsx +0 -235
- package/src/components/organisms/popover.tsx +0 -149
- package/src/components/organisms/resizable.tsx +0 -58
- package/src/components/organisms/schema-form.tsx +0 -232
- package/src/components/organisms/select.tsx +0 -309
- package/src/components/organisms/sheet.tsx +0 -265
- package/src/components/organisms/sidebar.tsx +0 -1040
- package/src/components/organisms/sonner.tsx +0 -96
- package/src/components/organisms/tabs.tsx +0 -133
- package/src/components/organisms/theme-provider.tsx +0 -101
- package/src/hooks/use-mobile.tsx +0 -19
- package/src/lib/portal-container.tsx +0 -35
- package/src/lib/utils.ts +0 -6
- package/src/native.ts +0 -23
- package/src/tokens/colors.ts +0 -91
- package/src/tokens/index.ts +0 -3
- package/src/tokens/spacing.ts +0 -55
- package/src/tokens/typography.ts +0 -27
- package/styles/dashboard-grid.css +0 -47
- package/styles/fonts/Roboto-VariableFont_wdth_wght.ttf +0 -0
- package/styles/glass.css +0 -171
- package/styles/leaflet.css +0 -13
- package/styles/tokens.css +0 -317
- package/tailwind.config.ts +0 -70
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
|
|
3
|
-
import { cn } from "../../lib/utils";
|
|
4
|
-
|
|
5
|
-
export interface FlexBoxProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
6
|
-
/**
|
|
7
|
-
* Maps to `flex-direction`.
|
|
8
|
-
* @default "row"
|
|
9
|
-
*/
|
|
10
|
-
direction?: "row" | "column";
|
|
11
|
-
/**
|
|
12
|
-
* Maps to `align-items`.
|
|
13
|
-
* @default "flex-start"
|
|
14
|
-
*/
|
|
15
|
-
align?: "flex-start" | "center" | "flex-end" | "stretch" | "baseline";
|
|
16
|
-
/**
|
|
17
|
-
* Maps to `justify-content`.
|
|
18
|
-
* @default "flex-start"
|
|
19
|
-
*/
|
|
20
|
-
justify?:
|
|
21
|
-
| "flex-start"
|
|
22
|
-
| "center"
|
|
23
|
-
| "flex-end"
|
|
24
|
-
| "space-between"
|
|
25
|
-
| "space-around"
|
|
26
|
-
| "space-evenly";
|
|
27
|
-
/** Tailwind gap step (0–6) or a raw CSS value. */
|
|
28
|
-
gap?: number | string;
|
|
29
|
-
/**
|
|
30
|
-
* Maps to `flex-wrap`. Pass `true` for `flex-wrap`, `false` for
|
|
31
|
-
* `flex-nowrap`.
|
|
32
|
-
* @default false
|
|
33
|
-
*/
|
|
34
|
-
wrap?: boolean;
|
|
35
|
-
children?: React.ReactNode;
|
|
36
|
-
className?: string;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const DIRECTION: Record<NonNullable<FlexBoxProps["direction"]>, string> = {
|
|
40
|
-
row: "flex-row",
|
|
41
|
-
column: "flex-col",
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
const ALIGN: Record<NonNullable<FlexBoxProps["align"]>, string> = {
|
|
45
|
-
"flex-start": "items-start",
|
|
46
|
-
center: "items-center",
|
|
47
|
-
"flex-end": "items-end",
|
|
48
|
-
stretch: "items-stretch",
|
|
49
|
-
baseline: "items-baseline",
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
const JUSTIFY: Record<NonNullable<FlexBoxProps["justify"]>, string> = {
|
|
53
|
-
"flex-start": "justify-start",
|
|
54
|
-
center: "justify-center",
|
|
55
|
-
"flex-end": "justify-end",
|
|
56
|
-
"space-between": "justify-between",
|
|
57
|
-
"space-around": "justify-around",
|
|
58
|
-
"space-evenly": "justify-evenly",
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
const GAP: Record<number, string> = {
|
|
62
|
-
0: "gap-0",
|
|
63
|
-
1: "gap-2",
|
|
64
|
-
2: "gap-4",
|
|
65
|
-
3: "gap-6",
|
|
66
|
-
4: "gap-8",
|
|
67
|
-
5: "gap-10",
|
|
68
|
-
6: "gap-12",
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
export const FlexBox = React.forwardRef<HTMLDivElement, FlexBoxProps>(
|
|
72
|
-
(
|
|
73
|
-
{
|
|
74
|
-
direction = "row",
|
|
75
|
-
align = "flex-start",
|
|
76
|
-
justify = "flex-start",
|
|
77
|
-
gap,
|
|
78
|
-
wrap = false,
|
|
79
|
-
className,
|
|
80
|
-
style,
|
|
81
|
-
...rest
|
|
82
|
-
},
|
|
83
|
-
ref,
|
|
84
|
-
) => {
|
|
85
|
-
const gapClass = typeof gap === "number" ? (GAP[gap] ?? "") : "";
|
|
86
|
-
const gapStyle = typeof gap === "string" ? { gap } : undefined;
|
|
87
|
-
return (
|
|
88
|
-
<div
|
|
89
|
-
ref={ref}
|
|
90
|
-
className={cn(
|
|
91
|
-
"flex",
|
|
92
|
-
DIRECTION[direction],
|
|
93
|
-
ALIGN[align],
|
|
94
|
-
JUSTIFY[justify],
|
|
95
|
-
gapClass,
|
|
96
|
-
wrap && "flex-wrap",
|
|
97
|
-
className,
|
|
98
|
-
)}
|
|
99
|
-
style={gapStyle ? { ...gapStyle, ...style } : style}
|
|
100
|
-
{...rest}
|
|
101
|
-
/>
|
|
102
|
-
);
|
|
103
|
-
},
|
|
104
|
-
);
|
|
105
|
-
FlexBox.displayName = "FlexBox";
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { icons, type LucideIcon } from "lucide-react";
|
|
2
|
-
import * as React from "react";
|
|
3
|
-
|
|
4
|
-
import { cn } from "../../lib/utils";
|
|
5
|
-
|
|
6
|
-
export type IconName = keyof typeof icons;
|
|
7
|
-
|
|
8
|
-
export const iconNames = Object.keys(icons) as IconName[];
|
|
9
|
-
|
|
10
|
-
export interface IconProps extends React.SVGAttributes<SVGSVGElement> {
|
|
11
|
-
/**
|
|
12
|
-
* Lucide icon name (PascalCase, e.g. `ChevronRight`, `Mail`). Only icons
|
|
13
|
-
* re-exported through `lucide-react` are valid.
|
|
14
|
-
*/
|
|
15
|
-
name: IconName;
|
|
16
|
-
/**
|
|
17
|
-
* Pixel size of the rendered SVG. Defaults to 16; pass any number to
|
|
18
|
-
* override (e.g. 20, 24).
|
|
19
|
-
* @default 16
|
|
20
|
-
*/
|
|
21
|
-
size?: number;
|
|
22
|
-
className?: string;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const Icon = React.forwardRef<SVGSVGElement, IconProps>(
|
|
26
|
-
({ name, size = 16, className, ...props }, ref) => {
|
|
27
|
-
const LucideIcon: LucideIcon = icons[name];
|
|
28
|
-
if (!LucideIcon) return null;
|
|
29
|
-
return <LucideIcon ref={ref} size={size} className={cn("shrink-0", className)} {...props} />;
|
|
30
|
-
},
|
|
31
|
-
);
|
|
32
|
-
Icon.displayName = "Icon";
|
|
33
|
-
|
|
34
|
-
export { Icon };
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
|
|
3
|
-
import { cn } from "../../lib/utils";
|
|
4
|
-
|
|
5
|
-
export interface InputProps extends React.ComponentProps<"input"> {
|
|
6
|
-
/**
|
|
7
|
-
* Native input type. Drives keyboard, validation, and on iOS the
|
|
8
|
-
* picker.
|
|
9
|
-
* @default "text"
|
|
10
|
-
*/
|
|
11
|
-
type?: React.HTMLInputTypeAttribute;
|
|
12
|
-
/**
|
|
13
|
-
* Controlled value. Pair with `onChange`. For uncontrolled inputs use
|
|
14
|
-
* `defaultValue` instead.
|
|
15
|
-
*/
|
|
16
|
-
value?: string | number | readonly string[];
|
|
17
|
-
/** Initial value for an uncontrolled input. Ignored if `value` is also passed. */
|
|
18
|
-
defaultValue?: string | number | readonly string[];
|
|
19
|
-
/** Hint text shown when the input is empty. Renders in `text-muted-foreground`. */
|
|
20
|
-
placeholder?: string;
|
|
21
|
-
/**
|
|
22
|
-
* Visually dims to 50% and blocks all input. Pair with `Label` so the
|
|
23
|
-
* dim cascades.
|
|
24
|
-
* @default false
|
|
25
|
-
*/
|
|
26
|
-
disabled?: boolean;
|
|
27
|
-
/**
|
|
28
|
-
* Selectable but not editable. Useful for displaying server-set values.
|
|
29
|
-
* @default false
|
|
30
|
-
*/
|
|
31
|
-
readOnly?: boolean;
|
|
32
|
-
/**
|
|
33
|
-
* Block native form submit unless the input has a value.
|
|
34
|
-
* @default false
|
|
35
|
-
*/
|
|
36
|
-
required?: boolean;
|
|
37
|
-
/** Form field name. Required when relying on uncontrolled native form submission. */
|
|
38
|
-
name?: string;
|
|
39
|
-
/** DOM id. Match this from `<Label htmlFor>` for screen-reader association. */
|
|
40
|
-
id?: string;
|
|
41
|
-
/** Browser autofill hint. See MDN for the full token list. */
|
|
42
|
-
autoComplete?: string;
|
|
43
|
-
/**
|
|
44
|
-
* Focus the input on mount. Use sparingly — surprises keyboard users.
|
|
45
|
-
* @default false
|
|
46
|
-
*/
|
|
47
|
-
autoFocus?: boolean;
|
|
48
|
-
/** Native HTML5 validation regex. Triggers `:invalid` if the value doesn't match. */
|
|
49
|
-
pattern?: string;
|
|
50
|
-
/** Character count limit for text inputs. */
|
|
51
|
-
maxLength?: number;
|
|
52
|
-
/** Minimum character count for text inputs. */
|
|
53
|
-
minLength?: number;
|
|
54
|
-
/** Numeric / date lower bound. Honoured by `type="number"` / `"date"` / `"time"` / `"range"`. */
|
|
55
|
-
min?: string | number;
|
|
56
|
-
/** Numeric / date upper bound. */
|
|
57
|
-
max?: string | number;
|
|
58
|
-
/** Step increment for `number` / `range` / `date` types. */
|
|
59
|
-
step?: string | number;
|
|
60
|
-
/** Fires on every keystroke. Read `e.target.value`. Required if you pass `value`. */
|
|
61
|
-
onChange?: React.ChangeEventHandler<HTMLInputElement>;
|
|
62
|
-
/** Focus event. Common for focus-driven typeahead lookups. */
|
|
63
|
-
onFocus?: React.FocusEventHandler<HTMLInputElement>;
|
|
64
|
-
/** Blur event. Common for blur-validation. */
|
|
65
|
-
onBlur?: React.FocusEventHandler<HTMLInputElement>;
|
|
66
|
-
className?: string;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Styled wrapper around the native `<input>` — 36px tall, rounded-md, 1px
|
|
71
|
-
* border, transparent background, canvas focus ring. Forwards every native
|
|
72
|
-
* input attribute through to the underlying element.
|
|
73
|
-
*/
|
|
74
|
-
const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
|
75
|
-
({ className, type, ...props }, ref) => {
|
|
76
|
-
return (
|
|
77
|
-
<input
|
|
78
|
-
type={type}
|
|
79
|
-
data-slot="input"
|
|
80
|
-
className={cn(
|
|
81
|
-
"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
|
82
|
-
className,
|
|
83
|
-
)}
|
|
84
|
-
ref={ref}
|
|
85
|
-
{...props}
|
|
86
|
-
/>
|
|
87
|
-
);
|
|
88
|
-
},
|
|
89
|
-
);
|
|
90
|
-
Input.displayName = "Input";
|
|
91
|
-
|
|
92
|
-
export { Input };
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import * as LabelPrimitive from "@radix-ui/react-label";
|
|
4
|
-
import { cva, type VariantProps } from "class-variance-authority";
|
|
5
|
-
import * as React from "react";
|
|
6
|
-
|
|
7
|
-
import { cn } from "../../lib/utils";
|
|
8
|
-
|
|
9
|
-
const labelVariants = cva(
|
|
10
|
-
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
|
|
11
|
-
);
|
|
12
|
-
|
|
13
|
-
export interface LabelProps
|
|
14
|
-
extends React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root>,
|
|
15
|
-
VariantProps<typeof labelVariants> {
|
|
16
|
-
/**
|
|
17
|
-
* ID of the form control this label describes. Sets `for` on the
|
|
18
|
-
* underlying `<label>` so screen readers and click-to-focus work.
|
|
19
|
-
* Match this with the input's `id`.
|
|
20
|
-
*/
|
|
21
|
-
htmlFor?: string;
|
|
22
|
-
/**
|
|
23
|
-
* Render as a Radix Slot — forwards props onto the immediate child
|
|
24
|
-
* element instead of rendering a wrapper `<label>`.
|
|
25
|
-
* @default false
|
|
26
|
-
*/
|
|
27
|
-
asChild?: boolean;
|
|
28
|
-
/** Label text. Can include nested elements (icons, helper text). */
|
|
29
|
-
children?: React.ReactNode;
|
|
30
|
-
/** Tailwind / CSS classes merged onto the label via `cn()`. */
|
|
31
|
-
className?: string;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const Label = React.forwardRef<React.ElementRef<typeof LabelPrimitive.Root>, LabelProps>(
|
|
35
|
-
({ className, ...props }, ref) => (
|
|
36
|
-
<LabelPrimitive.Root ref={ref} className={cn(labelVariants(), className)} {...props} />
|
|
37
|
-
),
|
|
38
|
-
);
|
|
39
|
-
Label.displayName = LabelPrimitive.Root.displayName;
|
|
40
|
-
|
|
41
|
-
export { Label };
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import * as React from "react";
|
|
4
|
-
|
|
5
|
-
import { cn } from "../../lib/utils";
|
|
6
|
-
|
|
7
|
-
export interface LogoProps extends React.HTMLAttributes<HTMLElement> {
|
|
8
|
-
/**
|
|
9
|
-
* Custom logo image. When provided, renders an `<img>` instead of the
|
|
10
|
-
* default Olympus ring mark. Apps consuming canvas pass their own brand
|
|
11
|
-
* here.
|
|
12
|
-
*/
|
|
13
|
-
src?: string;
|
|
14
|
-
/** Alt text for the custom-image variant. Required when `src` is set. */
|
|
15
|
-
alt?: string;
|
|
16
|
-
/** Pixel size for the custom-image variant only. Default 24. */
|
|
17
|
-
size?: number;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const OlympusRing = React.forwardRef<SVGSVGElement, React.SVGAttributes<SVGSVGElement>>(
|
|
21
|
-
({ className, ...props }, ref) => {
|
|
22
|
-
const gradientId = React.useId();
|
|
23
|
-
return (
|
|
24
|
-
<svg
|
|
25
|
-
ref={ref}
|
|
26
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
27
|
-
viewBox="0 0 440 736"
|
|
28
|
-
className={className}
|
|
29
|
-
{...props}
|
|
30
|
-
>
|
|
31
|
-
<defs>
|
|
32
|
-
<linearGradient id={gradientId} x1="1" y1="1" x2="0" y2="0">
|
|
33
|
-
<stop offset="0%" stopColor="#1E40AF" />
|
|
34
|
-
<stop offset="100%" stopColor="#60A5FA" />
|
|
35
|
-
</linearGradient>
|
|
36
|
-
</defs>
|
|
37
|
-
<g transform="translate(220, 368) rotate(90) translate(-700, -510)">
|
|
38
|
-
<path
|
|
39
|
-
fill={`url(#${gradientId})`}
|
|
40
|
-
fillRule="evenodd"
|
|
41
|
-
d="M 552 300 H 848 A 210 210 0 0 1 1058 510 A 210 210 0 0 1 848 720 H 552 A 210 210 0 0 1 342 510 A 210 210 0 0 1 552 300 Z M 582 386 H 818 A 124 124 0 0 1 942 510 A 124 124 0 0 1 818 634 H 582 A 124 124 0 0 1 458 510 A 124 124 0 0 1 582 386 Z"
|
|
42
|
-
/>
|
|
43
|
-
</g>
|
|
44
|
-
</svg>
|
|
45
|
-
);
|
|
46
|
-
},
|
|
47
|
-
);
|
|
48
|
-
OlympusRing.displayName = "Logo.OlympusRing";
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Brand-agnostic logo slot.
|
|
52
|
-
*
|
|
53
|
-
* - With no `src`: renders the Olympus gradient-ring mark (the canonical
|
|
54
|
-
* brand mark — viewBox 0 0 440 736, blue-gradient stadium). Size via
|
|
55
|
-
* `className` (e.g. `className="h-10 w-auto"`) — the SVG honours its
|
|
56
|
-
* non-square viewBox aspect ratio.
|
|
57
|
-
* - With `src`: renders an `<img>` so consumers can drop in their own brand.
|
|
58
|
-
*
|
|
59
|
-
* The deprecated sideways-O ellipse mark and `showText` wordmark lockup
|
|
60
|
-
* have been removed. Use `<BrandLockup logo={…} productName="…" />` for
|
|
61
|
-
* the lockup.
|
|
62
|
-
*/
|
|
63
|
-
const Logo = React.forwardRef<HTMLElement, LogoProps>(
|
|
64
|
-
({ src, alt = "", size = 24, className, ...props }, ref) => {
|
|
65
|
-
if (src) {
|
|
66
|
-
return (
|
|
67
|
-
<img
|
|
68
|
-
ref={ref as React.Ref<HTMLImageElement>}
|
|
69
|
-
src={src}
|
|
70
|
-
alt={alt}
|
|
71
|
-
width={size}
|
|
72
|
-
height={size}
|
|
73
|
-
className={cn("shrink-0", className)}
|
|
74
|
-
{...(props as React.ImgHTMLAttributes<HTMLImageElement>)}
|
|
75
|
-
/>
|
|
76
|
-
);
|
|
77
|
-
}
|
|
78
|
-
return (
|
|
79
|
-
<OlympusRing
|
|
80
|
-
ref={ref as React.Ref<SVGSVGElement>}
|
|
81
|
-
className={className}
|
|
82
|
-
{...(props as React.SVGAttributes<SVGSVGElement>)}
|
|
83
|
-
/>
|
|
84
|
-
);
|
|
85
|
-
},
|
|
86
|
-
);
|
|
87
|
-
Logo.displayName = "Logo";
|
|
88
|
-
|
|
89
|
-
export { Logo };
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import * as ProgressPrimitive from "@radix-ui/react-progress";
|
|
4
|
-
import * as React from "react";
|
|
5
|
-
|
|
6
|
-
import { cn } from "../../lib/utils";
|
|
7
|
-
|
|
8
|
-
export interface ProgressProps
|
|
9
|
-
extends React.ComponentPropsWithoutRef<typeof ProgressPrimitive.Root> {
|
|
10
|
-
/**
|
|
11
|
-
* Current progress as a number between `0` and `max`. When `null` the
|
|
12
|
-
* indicator renders in indeterminate mode (Radix's default
|
|
13
|
-
* loading-spinner-style fill).
|
|
14
|
-
* @default null
|
|
15
|
-
*/
|
|
16
|
-
value?: number | null;
|
|
17
|
-
/**
|
|
18
|
-
* Maximum value the progress can reach. The fill width is
|
|
19
|
-
* `value / max * 100%`.
|
|
20
|
-
* @default 100
|
|
21
|
-
*/
|
|
22
|
-
max?: number;
|
|
23
|
-
/**
|
|
24
|
-
* Function that returns the accessible label announcing the current
|
|
25
|
-
* value to screen readers. Defaults to `"X%"`.
|
|
26
|
-
*/
|
|
27
|
-
getValueLabel?: (value: number, max: number) => string;
|
|
28
|
-
/**
|
|
29
|
-
* Render as a Radix Slot — forwards props onto the immediate child
|
|
30
|
-
* element instead of rendering a wrapper `<div>`.
|
|
31
|
-
* @default false
|
|
32
|
-
*/
|
|
33
|
-
asChild?: boolean;
|
|
34
|
-
/** Tailwind / CSS classes merged onto the track via `cn()`. */
|
|
35
|
-
className?: string;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const Progress = React.forwardRef<React.ElementRef<typeof ProgressPrimitive.Root>, ProgressProps>(
|
|
39
|
-
({ className, value, ...props }, ref) => (
|
|
40
|
-
<ProgressPrimitive.Root
|
|
41
|
-
ref={ref}
|
|
42
|
-
className={cn("relative h-2 w-full overflow-hidden rounded-full bg-primary/20", className)}
|
|
43
|
-
value={value}
|
|
44
|
-
{...props}
|
|
45
|
-
>
|
|
46
|
-
<ProgressPrimitive.Indicator
|
|
47
|
-
className="h-full w-full flex-1 bg-primary transition-all"
|
|
48
|
-
style={{ transform: `translateX(-${100 - (value || 0)}%)` }}
|
|
49
|
-
/>
|
|
50
|
-
</ProgressPrimitive.Root>
|
|
51
|
-
),
|
|
52
|
-
);
|
|
53
|
-
Progress.displayName = ProgressPrimitive.Root.displayName;
|
|
54
|
-
|
|
55
|
-
export { Progress };
|
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import * as RadioGroupPrimitive from "@radix-ui/react-radio-group";
|
|
4
|
-
import { Circle } from "lucide-react";
|
|
5
|
-
import * as React from "react";
|
|
6
|
-
|
|
7
|
-
import { cn } from "../../lib/utils";
|
|
8
|
-
|
|
9
|
-
export interface RadioGroupProps
|
|
10
|
-
extends React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root> {
|
|
11
|
-
/**
|
|
12
|
-
* Controlled selected value. Pair with `onValueChange`. Match the
|
|
13
|
-
* `value` of one of the child `<RadioGroupItem>`s.
|
|
14
|
-
*/
|
|
15
|
-
value?: string;
|
|
16
|
-
/**
|
|
17
|
-
* Initial selected value for uncontrolled usage. Ignored if `value` is
|
|
18
|
-
* also passed.
|
|
19
|
-
*/
|
|
20
|
-
defaultValue?: string;
|
|
21
|
-
/** Fires when the user picks a different option. */
|
|
22
|
-
onValueChange?: (value: string) => void;
|
|
23
|
-
/**
|
|
24
|
-
* Disables every radio in the group.
|
|
25
|
-
* @default false
|
|
26
|
-
*/
|
|
27
|
-
disabled?: boolean;
|
|
28
|
-
/**
|
|
29
|
-
* Required for native form submission — at least one option must be
|
|
30
|
-
* selected.
|
|
31
|
-
* @default false
|
|
32
|
-
*/
|
|
33
|
-
required?: boolean;
|
|
34
|
-
/** Form field name. Required when relying on uncontrolled native form submission. */
|
|
35
|
-
name?: string;
|
|
36
|
-
/**
|
|
37
|
-
* Layout direction of the radios.
|
|
38
|
-
* @default "vertical"
|
|
39
|
-
*/
|
|
40
|
-
orientation?: "horizontal" | "vertical";
|
|
41
|
-
/**
|
|
42
|
-
* Reading direction of the group. Affects keyboard arrow navigation.
|
|
43
|
-
* @default "ltr"
|
|
44
|
-
*/
|
|
45
|
-
dir?: "ltr" | "rtl";
|
|
46
|
-
/**
|
|
47
|
-
* When true, arrow-key navigation wraps from the last item back to the
|
|
48
|
-
* first.
|
|
49
|
-
* @default true
|
|
50
|
-
*/
|
|
51
|
-
loop?: boolean;
|
|
52
|
-
/**
|
|
53
|
-
* Render as a Radix Slot — forwards props onto the immediate child
|
|
54
|
-
* element instead of rendering a wrapper `<div>`.
|
|
55
|
-
* @default false
|
|
56
|
-
*/
|
|
57
|
-
asChild?: boolean;
|
|
58
|
-
/** A flat list of `<RadioGroupItem>`s. */
|
|
59
|
-
children?: React.ReactNode;
|
|
60
|
-
/** Tailwind / CSS classes merged onto the group via `cn()`. */
|
|
61
|
-
className?: string;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const RadioGroup = React.forwardRef<
|
|
65
|
-
React.ElementRef<typeof RadioGroupPrimitive.Root>,
|
|
66
|
-
RadioGroupProps
|
|
67
|
-
>(({ className, ...props }, ref) => {
|
|
68
|
-
return <RadioGroupPrimitive.Root className={cn("grid gap-2", className)} {...props} ref={ref} />;
|
|
69
|
-
});
|
|
70
|
-
RadioGroup.displayName = RadioGroupPrimitive.Root.displayName;
|
|
71
|
-
|
|
72
|
-
export interface RadioGroupItemProps
|
|
73
|
-
extends React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item> {
|
|
74
|
-
/**
|
|
75
|
-
* Value reported when this radio is selected. Required — must match
|
|
76
|
-
* the parent `<RadioGroup>`'s `value` for selection to register.
|
|
77
|
-
*/
|
|
78
|
-
value: string;
|
|
79
|
-
/**
|
|
80
|
-
* Disables only this radio.
|
|
81
|
-
* @default false
|
|
82
|
-
*/
|
|
83
|
-
disabled?: boolean;
|
|
84
|
-
/**
|
|
85
|
-
* Required for native form submission.
|
|
86
|
-
* @default false
|
|
87
|
-
*/
|
|
88
|
-
required?: boolean;
|
|
89
|
-
/**
|
|
90
|
-
* Render as a Radix Slot — forwards props onto the immediate child
|
|
91
|
-
* element instead of rendering a wrapper `<button>`.
|
|
92
|
-
* @default false
|
|
93
|
-
*/
|
|
94
|
-
asChild?: boolean;
|
|
95
|
-
/** Optional inner content (visual only — Radix provides the indicator). */
|
|
96
|
-
children?: React.ReactNode;
|
|
97
|
-
/** Tailwind / CSS classes merged onto the radio button via `cn()`. */
|
|
98
|
-
className?: string;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
const RadioGroupItem = React.forwardRef<
|
|
102
|
-
React.ElementRef<typeof RadioGroupPrimitive.Item>,
|
|
103
|
-
RadioGroupItemProps
|
|
104
|
-
>(({ className, ...props }, ref) => {
|
|
105
|
-
return (
|
|
106
|
-
<RadioGroupPrimitive.Item
|
|
107
|
-
ref={ref}
|
|
108
|
-
className={cn(
|
|
109
|
-
"aspect-square h-4 w-4 rounded-full border border-primary text-primary shadow focus:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
|
|
110
|
-
className,
|
|
111
|
-
)}
|
|
112
|
-
{...props}
|
|
113
|
-
>
|
|
114
|
-
<RadioGroupPrimitive.Indicator className="flex items-center justify-center">
|
|
115
|
-
<Circle className="h-3.5 w-3.5 fill-primary" />
|
|
116
|
-
</RadioGroupPrimitive.Indicator>
|
|
117
|
-
</RadioGroupPrimitive.Item>
|
|
118
|
-
);
|
|
119
|
-
});
|
|
120
|
-
RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName;
|
|
121
|
-
|
|
122
|
-
export { RadioGroup, RadioGroupItem };
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
|
|
4
|
-
import * as React from "react";
|
|
5
|
-
|
|
6
|
-
import { cn } from "../../lib/utils";
|
|
7
|
-
|
|
8
|
-
export interface ScrollAreaProps
|
|
9
|
-
extends React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root> {
|
|
10
|
-
/**
|
|
11
|
-
* When the scrollbar is shown:
|
|
12
|
-
* - `"hover"` reveals on hover and 600ms after scroll
|
|
13
|
-
* - `"scroll"` reveals only while scrolling
|
|
14
|
-
* - `"auto"` defers to OS conventions (always-visible on Linux/Win)
|
|
15
|
-
* - `"always"` keeps the scrollbar visible at all times
|
|
16
|
-
* @default "hover"
|
|
17
|
-
*/
|
|
18
|
-
type?: "auto" | "always" | "scroll" | "hover";
|
|
19
|
-
/**
|
|
20
|
-
* How long the scrollbar lingers after scroll/hover ends, in ms. Only
|
|
21
|
-
* applies when `type` is `"hover"` or `"scroll"`.
|
|
22
|
-
* @default 600
|
|
23
|
-
*/
|
|
24
|
-
scrollHideDelay?: number;
|
|
25
|
-
/**
|
|
26
|
-
* Reading direction. Affects which side the vertical scrollbar lives on.
|
|
27
|
-
* @default "ltr"
|
|
28
|
-
*/
|
|
29
|
-
dir?: "ltr" | "rtl";
|
|
30
|
-
/**
|
|
31
|
-
* Render as a Radix Slot — forwards props onto the immediate child
|
|
32
|
-
* element instead of rendering a wrapper `<div>`.
|
|
33
|
-
* @default false
|
|
34
|
-
*/
|
|
35
|
-
asChild?: boolean;
|
|
36
|
-
/** Scrollable content. */
|
|
37
|
-
children?: React.ReactNode;
|
|
38
|
-
/**
|
|
39
|
-
* Tailwind / CSS classes merged onto the root via `cn()`. Set the
|
|
40
|
-
* height/max-height here so the scroll area knows when to scroll.
|
|
41
|
-
*/
|
|
42
|
-
className?: string;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const ScrollArea = React.forwardRef<
|
|
46
|
-
React.ElementRef<typeof ScrollAreaPrimitive.Root>,
|
|
47
|
-
ScrollAreaProps
|
|
48
|
-
>(({ className, children, ...props }, ref) => (
|
|
49
|
-
<ScrollAreaPrimitive.Root
|
|
50
|
-
ref={ref}
|
|
51
|
-
className={cn("relative overflow-hidden", className)}
|
|
52
|
-
{...props}
|
|
53
|
-
>
|
|
54
|
-
<ScrollAreaPrimitive.Viewport className="h-full w-full rounded-[inherit]">
|
|
55
|
-
{children}
|
|
56
|
-
</ScrollAreaPrimitive.Viewport>
|
|
57
|
-
<ScrollBar />
|
|
58
|
-
<ScrollAreaPrimitive.Corner />
|
|
59
|
-
</ScrollAreaPrimitive.Root>
|
|
60
|
-
));
|
|
61
|
-
ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;
|
|
62
|
-
|
|
63
|
-
export interface ScrollBarProps
|
|
64
|
-
extends React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar> {
|
|
65
|
-
/**
|
|
66
|
-
* Which axis the scrollbar controls.
|
|
67
|
-
* @default "vertical"
|
|
68
|
-
*/
|
|
69
|
-
orientation?: "horizontal" | "vertical";
|
|
70
|
-
/**
|
|
71
|
-
* Force the scrollbar to mount even when it's not needed (no overflow).
|
|
72
|
-
* Pair with a CSS animation that fades in/out based on `data-state`.
|
|
73
|
-
* @default false
|
|
74
|
-
*/
|
|
75
|
-
forceMount?: true;
|
|
76
|
-
/**
|
|
77
|
-
* Render as a Radix Slot — forwards props onto the immediate child
|
|
78
|
-
* element instead of rendering a wrapper `<div>`.
|
|
79
|
-
* @default false
|
|
80
|
-
*/
|
|
81
|
-
asChild?: boolean;
|
|
82
|
-
/** Tailwind / CSS classes merged onto the scrollbar via `cn()`. */
|
|
83
|
-
className?: string;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
const ScrollBar = React.forwardRef<
|
|
87
|
-
React.ElementRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>,
|
|
88
|
-
ScrollBarProps
|
|
89
|
-
>(({ className, orientation = "vertical", ...props }, ref) => (
|
|
90
|
-
<ScrollAreaPrimitive.ScrollAreaScrollbar
|
|
91
|
-
ref={ref}
|
|
92
|
-
orientation={orientation}
|
|
93
|
-
className={cn(
|
|
94
|
-
"flex touch-none select-none transition-colors",
|
|
95
|
-
orientation === "vertical" && "h-full w-2.5 border-l border-l-transparent p-[1px]",
|
|
96
|
-
orientation === "horizontal" && "h-2.5 flex-col border-t border-t-transparent p-[1px]",
|
|
97
|
-
className,
|
|
98
|
-
)}
|
|
99
|
-
{...props}
|
|
100
|
-
>
|
|
101
|
-
<ScrollAreaPrimitive.ScrollAreaThumb className="relative flex-1 rounded-full bg-border" />
|
|
102
|
-
</ScrollAreaPrimitive.ScrollAreaScrollbar>
|
|
103
|
-
));
|
|
104
|
-
ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName;
|
|
105
|
-
|
|
106
|
-
export { ScrollArea, ScrollBar };
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
|
|
3
|
-
import { cn } from "../../lib/utils";
|
|
4
|
-
|
|
5
|
-
export interface SectionProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
6
|
-
/**
|
|
7
|
-
* Vertical-rhythm step applied as `space-y-*` between immediate children.
|
|
8
|
-
* Maps to Tailwind's spacing scale: `0` = 0, `1` = 8px, `2` = 16px,
|
|
9
|
-
* `3` = 24px, `4` = 32px, `5` = 40px, `6` = 48px.
|
|
10
|
-
* @default 3
|
|
11
|
-
*/
|
|
12
|
-
spacing?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
|
|
13
|
-
/** Section content — typically a heading + body, or stacked cards. */
|
|
14
|
-
children?: React.ReactNode;
|
|
15
|
-
/** Tailwind / CSS classes merged onto the root `<div>` via `cn()`. */
|
|
16
|
-
className?: string;
|
|
17
|
-
/** DOM id, useful when linked to from a `<Label>` or anchor `#hash`. */
|
|
18
|
-
id?: string;
|
|
19
|
-
/**
|
|
20
|
-
* ARIA role override. Pass `"region"` (paired with `aria-label` /
|
|
21
|
-
* `aria-labelledby`) when the section should be a navigable landmark
|
|
22
|
-
* for screen-reader users.
|
|
23
|
-
*/
|
|
24
|
-
role?: React.AriaRole;
|
|
25
|
-
/** Accessible label for landmark-role sections. */
|
|
26
|
-
"aria-label"?: string;
|
|
27
|
-
/** ID of an element that labels the section (e.g. its heading). */
|
|
28
|
-
"aria-labelledby"?: string;
|
|
29
|
-
/** ID of an element that describes the section. */
|
|
30
|
-
"aria-describedby"?: string;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const SPACING: Record<number, string> = {
|
|
34
|
-
0: "space-y-0",
|
|
35
|
-
1: "space-y-2",
|
|
36
|
-
2: "space-y-4",
|
|
37
|
-
3: "space-y-6",
|
|
38
|
-
4: "space-y-8",
|
|
39
|
-
5: "space-y-10",
|
|
40
|
-
6: "space-y-12",
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
export const Section = React.forwardRef<HTMLDivElement, SectionProps>(
|
|
44
|
-
({ spacing = 3, className, ...rest }, ref) => (
|
|
45
|
-
<div ref={ref} className={cn(SPACING[spacing] ?? "space-y-6", className)} {...rest} />
|
|
46
|
-
),
|
|
47
|
-
);
|
|
48
|
-
Section.displayName = "Section";
|