@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,96 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import { useTheme } from "next-themes";
|
|
4
|
-
import { Toaster as Sonner, toast } from "sonner";
|
|
5
|
-
|
|
6
|
-
type ToasterPropsBase = React.ComponentProps<typeof Sonner>;
|
|
7
|
-
|
|
8
|
-
export interface ToasterProps extends ToasterPropsBase {
|
|
9
|
-
/**
|
|
10
|
-
* Where toasts stack.
|
|
11
|
-
* @default "bottom-right"
|
|
12
|
-
*/
|
|
13
|
-
position?:
|
|
14
|
-
| "top-left"
|
|
15
|
-
| "top-center"
|
|
16
|
-
| "top-right"
|
|
17
|
-
| "bottom-left"
|
|
18
|
-
| "bottom-center"
|
|
19
|
-
| "bottom-right";
|
|
20
|
-
/**
|
|
21
|
-
* Toast colour scheme. Defaults to inheriting from `next-themes`.
|
|
22
|
-
* @default "system"
|
|
23
|
-
*/
|
|
24
|
-
theme?: "light" | "dark" | "system";
|
|
25
|
-
/**
|
|
26
|
-
* Make toasts rich-coloured by default — success/error/warning tints.
|
|
27
|
-
* @default false
|
|
28
|
-
*/
|
|
29
|
-
richColors?: boolean;
|
|
30
|
-
/**
|
|
31
|
-
* Show a close button on every toast.
|
|
32
|
-
* @default false
|
|
33
|
-
*/
|
|
34
|
-
closeButton?: boolean;
|
|
35
|
-
/**
|
|
36
|
-
* How long toasts stay visible (ms).
|
|
37
|
-
* @default 4000
|
|
38
|
-
*/
|
|
39
|
-
duration?: number;
|
|
40
|
-
/**
|
|
41
|
-
* Visual gap between stacked toasts (px).
|
|
42
|
-
* @default 14
|
|
43
|
-
*/
|
|
44
|
-
gap?: number;
|
|
45
|
-
/**
|
|
46
|
-
* Maximum number of toasts visible at once.
|
|
47
|
-
* @default 3
|
|
48
|
-
*/
|
|
49
|
-
visibleToasts?: number;
|
|
50
|
-
/**
|
|
51
|
-
* Hide the toaster's offset region — useful when you want toasts to
|
|
52
|
-
* butt against the viewport edge.
|
|
53
|
-
* @default 32
|
|
54
|
-
*/
|
|
55
|
-
offset?: string | number;
|
|
56
|
-
/**
|
|
57
|
-
* Pause toast timers when the user hovers any toast.
|
|
58
|
-
* @default true
|
|
59
|
-
*/
|
|
60
|
-
pauseWhenPageIsHidden?: boolean;
|
|
61
|
-
/**
|
|
62
|
-
* Reading direction.
|
|
63
|
-
* @default "ltr"
|
|
64
|
-
*/
|
|
65
|
-
dir?: "ltr" | "rtl" | "auto";
|
|
66
|
-
/** Tailwind / CSS classes merged onto the toaster region. */
|
|
67
|
-
className?: string;
|
|
68
|
-
/**
|
|
69
|
-
* Default toast options applied to every toast (className,
|
|
70
|
-
* descriptionClassName, etc.). See sonner docs for the full list.
|
|
71
|
-
*/
|
|
72
|
-
toastOptions?: ToasterPropsBase["toastOptions"];
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const Toaster = ({ ...props }: ToasterProps) => {
|
|
76
|
-
const { theme = "system" } = useTheme();
|
|
77
|
-
|
|
78
|
-
return (
|
|
79
|
-
<Sonner
|
|
80
|
-
theme={theme as ToasterProps["theme"]}
|
|
81
|
-
className="toaster group"
|
|
82
|
-
toastOptions={{
|
|
83
|
-
classNames: {
|
|
84
|
-
toast:
|
|
85
|
-
"group toast group-[.toaster]:bg-background group-[.toaster]:text-foreground group-[.toaster]:border-border group-[.toaster]:shadow-lg",
|
|
86
|
-
description: "group-[.toast]:text-muted-foreground",
|
|
87
|
-
actionButton: "group-[.toast]:bg-primary group-[.toast]:text-primary-foreground",
|
|
88
|
-
cancelButton: "group-[.toast]:bg-muted group-[.toast]:text-muted-foreground",
|
|
89
|
-
},
|
|
90
|
-
}}
|
|
91
|
-
{...props}
|
|
92
|
-
/>
|
|
93
|
-
);
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
export { Toaster, toast };
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import * as TabsPrimitive from "@radix-ui/react-tabs";
|
|
4
|
-
import * as React from "react";
|
|
5
|
-
|
|
6
|
-
import { cn } from "../../lib/utils";
|
|
7
|
-
|
|
8
|
-
export interface TabsProps extends React.ComponentProps<typeof TabsPrimitive.Root> {
|
|
9
|
-
/** Controlled active tab value. Pair with `onValueChange`. */
|
|
10
|
-
value?: string;
|
|
11
|
-
/** Initial active tab for uncontrolled usage. */
|
|
12
|
-
defaultValue?: string;
|
|
13
|
-
/** Fires when the user switches tabs. */
|
|
14
|
-
onValueChange?: (value: string) => void;
|
|
15
|
-
/**
|
|
16
|
-
* Tab orientation. Affects keyboard arrow navigation.
|
|
17
|
-
* @default "horizontal"
|
|
18
|
-
*/
|
|
19
|
-
orientation?: "horizontal" | "vertical";
|
|
20
|
-
/**
|
|
21
|
-
* Reading direction.
|
|
22
|
-
* @default "ltr"
|
|
23
|
-
*/
|
|
24
|
-
dir?: "ltr" | "rtl";
|
|
25
|
-
/**
|
|
26
|
-
* When and how content is activated.
|
|
27
|
-
* - `automatic` activates on focus (best for tabs that load fast)
|
|
28
|
-
* - `manual` requires Enter/Space (best for tabs that fetch data)
|
|
29
|
-
* @default "automatic"
|
|
30
|
-
*/
|
|
31
|
-
activationMode?: "automatic" | "manual";
|
|
32
|
-
/** TabsList + TabsContent siblings. */
|
|
33
|
-
children?: React.ReactNode;
|
|
34
|
-
className?: string;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const Tabs = TabsPrimitive.Root as React.FC<TabsProps>;
|
|
38
|
-
|
|
39
|
-
export interface TabsListProps extends React.ComponentPropsWithoutRef<typeof TabsPrimitive.List> {
|
|
40
|
-
/** When true, hold-to-skip-disabled-tabs is on. */
|
|
41
|
-
loop?: boolean;
|
|
42
|
-
/**
|
|
43
|
-
* Render as a Radix Slot.
|
|
44
|
-
* @default false
|
|
45
|
-
*/
|
|
46
|
-
asChild?: boolean;
|
|
47
|
-
/** A flat list of `<TabsTrigger>`s. */
|
|
48
|
-
children?: React.ReactNode;
|
|
49
|
-
className?: string;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const TabsList = React.forwardRef<React.ElementRef<typeof TabsPrimitive.List>, TabsListProps>(
|
|
53
|
-
({ className, ...props }, ref) => (
|
|
54
|
-
<TabsPrimitive.List
|
|
55
|
-
ref={ref}
|
|
56
|
-
data-slot="tabs-list"
|
|
57
|
-
className={cn(
|
|
58
|
-
"inline-flex h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground",
|
|
59
|
-
className,
|
|
60
|
-
)}
|
|
61
|
-
{...props}
|
|
62
|
-
/>
|
|
63
|
-
),
|
|
64
|
-
);
|
|
65
|
-
TabsList.displayName = TabsPrimitive.List.displayName;
|
|
66
|
-
|
|
67
|
-
export interface TabsTriggerProps
|
|
68
|
-
extends React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger> {
|
|
69
|
-
/** Required — value of the tab this trigger activates. Match with `<TabsContent value>`. */
|
|
70
|
-
value: string;
|
|
71
|
-
/** Disable this tab. */
|
|
72
|
-
disabled?: boolean;
|
|
73
|
-
/**
|
|
74
|
-
* Render as a Radix Slot.
|
|
75
|
-
* @default false
|
|
76
|
-
*/
|
|
77
|
-
asChild?: boolean;
|
|
78
|
-
/** Tab label. */
|
|
79
|
-
children?: React.ReactNode;
|
|
80
|
-
className?: string;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const TabsTrigger = React.forwardRef<
|
|
84
|
-
React.ElementRef<typeof TabsPrimitive.Trigger>,
|
|
85
|
-
TabsTriggerProps
|
|
86
|
-
>(({ className, ...props }, ref) => (
|
|
87
|
-
<TabsPrimitive.Trigger
|
|
88
|
-
ref={ref}
|
|
89
|
-
className={cn(
|
|
90
|
-
"inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow",
|
|
91
|
-
className,
|
|
92
|
-
)}
|
|
93
|
-
{...props}
|
|
94
|
-
/>
|
|
95
|
-
));
|
|
96
|
-
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
|
|
97
|
-
|
|
98
|
-
export interface TabsContentProps
|
|
99
|
-
extends React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content> {
|
|
100
|
-
/** Required — matches the `value` of a `<TabsTrigger>`. */
|
|
101
|
-
value: string;
|
|
102
|
-
/**
|
|
103
|
-
* Force the content to mount even when not active. Useful for
|
|
104
|
-
* preserving form state across tab switches.
|
|
105
|
-
* @default false
|
|
106
|
-
*/
|
|
107
|
-
forceMount?: true;
|
|
108
|
-
/**
|
|
109
|
-
* Render as a Radix Slot.
|
|
110
|
-
* @default false
|
|
111
|
-
*/
|
|
112
|
-
asChild?: boolean;
|
|
113
|
-
/** Tab pane body. */
|
|
114
|
-
children?: React.ReactNode;
|
|
115
|
-
className?: string;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
const TabsContent = React.forwardRef<
|
|
119
|
-
React.ElementRef<typeof TabsPrimitive.Content>,
|
|
120
|
-
TabsContentProps
|
|
121
|
-
>(({ className, ...props }, ref) => (
|
|
122
|
-
<TabsPrimitive.Content
|
|
123
|
-
ref={ref}
|
|
124
|
-
className={cn(
|
|
125
|
-
"mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
126
|
-
className,
|
|
127
|
-
)}
|
|
128
|
-
{...props}
|
|
129
|
-
/>
|
|
130
|
-
));
|
|
131
|
-
TabsContent.displayName = TabsPrimitive.Content.displayName;
|
|
132
|
-
|
|
133
|
-
export { Tabs, TabsContent, TabsList, TabsTrigger };
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import * as React from "react";
|
|
4
|
-
|
|
5
|
-
export type Theme = "light" | "dark" | "system";
|
|
6
|
-
export type ResolvedTheme = "light" | "dark";
|
|
7
|
-
|
|
8
|
-
interface ThemeContextValue {
|
|
9
|
-
theme: Theme;
|
|
10
|
-
resolvedTheme: ResolvedTheme;
|
|
11
|
-
setTheme: (theme: Theme) => void;
|
|
12
|
-
toggleTheme: () => void;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const ThemeContext = React.createContext<ThemeContextValue | null>(null);
|
|
16
|
-
|
|
17
|
-
export interface ThemeProviderProps {
|
|
18
|
-
defaultTheme?: Theme;
|
|
19
|
-
/** localStorage key. Default: `"olympus-theme"`. */
|
|
20
|
-
storageKey?: string;
|
|
21
|
-
/** Skip DOM/storage side effects (useful for SSR/tests). */
|
|
22
|
-
disableTransitionOnChange?: boolean;
|
|
23
|
-
children: React.ReactNode;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function systemTheme(): ResolvedTheme {
|
|
27
|
-
/* c8 ignore next -- SSR guard: window is always defined in jsdom tests */
|
|
28
|
-
if (typeof window === "undefined") return "light";
|
|
29
|
-
return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function resolve(theme: Theme): ResolvedTheme {
|
|
33
|
-
return theme === "system" ? systemTheme() : theme;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export function ThemeProvider({
|
|
37
|
-
defaultTheme = "system",
|
|
38
|
-
storageKey = "olympus-theme",
|
|
39
|
-
children,
|
|
40
|
-
}: ThemeProviderProps) {
|
|
41
|
-
const [theme, setThemeState] = React.useState<Theme>(defaultTheme);
|
|
42
|
-
const [resolvedTheme, setResolvedTheme] = React.useState<ResolvedTheme>(() =>
|
|
43
|
-
resolve(defaultTheme),
|
|
44
|
-
);
|
|
45
|
-
|
|
46
|
-
// On mount: read storage and apply.
|
|
47
|
-
React.useEffect(() => {
|
|
48
|
-
/* c8 ignore next -- SSR guard: window is always defined in jsdom tests */
|
|
49
|
-
if (typeof window === "undefined") return;
|
|
50
|
-
const stored = window.localStorage.getItem(storageKey) as Theme | null;
|
|
51
|
-
const initial = stored ?? defaultTheme;
|
|
52
|
-
setThemeState(initial);
|
|
53
|
-
setResolvedTheme(resolve(initial));
|
|
54
|
-
}, [defaultTheme, storageKey]);
|
|
55
|
-
|
|
56
|
-
// Apply the resolved theme to <html> and persist.
|
|
57
|
-
React.useEffect(() => {
|
|
58
|
-
/* c8 ignore next -- SSR guard: document is always defined in jsdom tests */
|
|
59
|
-
if (typeof document === "undefined") return;
|
|
60
|
-
const root = document.documentElement;
|
|
61
|
-
if (resolvedTheme === "dark") root.classList.add("dark");
|
|
62
|
-
else root.classList.remove("dark");
|
|
63
|
-
/* c8 ignore next -- SSR guard: window is always defined in jsdom tests */
|
|
64
|
-
if (typeof window !== "undefined") {
|
|
65
|
-
window.localStorage.setItem(storageKey, theme);
|
|
66
|
-
}
|
|
67
|
-
}, [theme, resolvedTheme, storageKey]);
|
|
68
|
-
|
|
69
|
-
// Respond to system preference changes when theme === "system".
|
|
70
|
-
React.useEffect(() => {
|
|
71
|
-
if (theme !== "system" || typeof window === "undefined") return;
|
|
72
|
-
const mq = window.matchMedia("(prefers-color-scheme: dark)");
|
|
73
|
-
const listener = () => setResolvedTheme(mq.matches ? "dark" : "light");
|
|
74
|
-
mq.addEventListener("change", listener);
|
|
75
|
-
return () => mq.removeEventListener("change", listener);
|
|
76
|
-
}, [theme]);
|
|
77
|
-
|
|
78
|
-
const setTheme = React.useCallback((t: Theme) => {
|
|
79
|
-
setThemeState(t);
|
|
80
|
-
setResolvedTheme(resolve(t));
|
|
81
|
-
}, []);
|
|
82
|
-
|
|
83
|
-
const toggleTheme = React.useCallback(() => {
|
|
84
|
-
setTheme(resolvedTheme === "dark" ? "light" : "dark");
|
|
85
|
-
}, [resolvedTheme, setTheme]);
|
|
86
|
-
|
|
87
|
-
const value = React.useMemo<ThemeContextValue>(
|
|
88
|
-
() => ({ theme, resolvedTheme, setTheme, toggleTheme }),
|
|
89
|
-
[theme, resolvedTheme, setTheme, toggleTheme],
|
|
90
|
-
);
|
|
91
|
-
|
|
92
|
-
return <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
export function useTheme(): ThemeContextValue {
|
|
96
|
-
const ctx = React.useContext(ThemeContext);
|
|
97
|
-
if (!ctx) throw new Error("useTheme must be used within a <ThemeProvider>");
|
|
98
|
-
return ctx;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
ThemeProvider.displayName = "ThemeProvider";
|
package/src/hooks/use-mobile.tsx
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
|
|
3
|
-
const MOBILE_BREAKPOINT = 768;
|
|
4
|
-
|
|
5
|
-
export function useIsMobile() {
|
|
6
|
-
const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined);
|
|
7
|
-
|
|
8
|
-
React.useEffect(() => {
|
|
9
|
-
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
|
|
10
|
-
const onChange = () => {
|
|
11
|
-
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
|
12
|
-
};
|
|
13
|
-
mql.addEventListener("change", onChange);
|
|
14
|
-
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
|
15
|
-
return () => mql.removeEventListener("change", onChange);
|
|
16
|
-
}, []);
|
|
17
|
-
|
|
18
|
-
return !!isMobile;
|
|
19
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import * as React from "react";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Where Radix-portalled UI (Select, DropdownMenu, Popover, Dialog, Tooltip,
|
|
7
|
-
* etc.) should mount. Defaults to `undefined`, which lets each Radix Portal
|
|
8
|
-
* fall back to its built-in default (`document.body`).
|
|
9
|
-
*
|
|
10
|
-
* Apps that render canvas inside iframes (e.g. the docs site's example
|
|
11
|
-
* previews) override this with the iframe's body so the portalled content
|
|
12
|
-
* stays in the same document as the trigger — without that, Radix's
|
|
13
|
-
* outside-click detection treats the iframe boundary as "outside" and the
|
|
14
|
-
* dropdown closes the moment it opens.
|
|
15
|
-
*/
|
|
16
|
-
const PortalContainerContext = React.createContext<HTMLElement | null | undefined>(undefined);
|
|
17
|
-
|
|
18
|
-
export interface PortalContainerProviderProps {
|
|
19
|
-
value: HTMLElement | null | undefined;
|
|
20
|
-
children: React.ReactNode;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export function PortalContainerProvider({ value, children }: PortalContainerProviderProps) {
|
|
24
|
-
return (
|
|
25
|
-
<PortalContainerContext.Provider value={value}>{children}</PortalContainerContext.Provider>
|
|
26
|
-
);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Read the current portal container. Returns `undefined` if no provider is
|
|
31
|
-
* mounted (Radix falls back to its default).
|
|
32
|
-
*/
|
|
33
|
-
export function usePortalContainer(): HTMLElement | null | undefined {
|
|
34
|
-
return React.useContext(PortalContainerContext);
|
|
35
|
-
}
|
package/src/lib/utils.ts
DELETED
package/src/native.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* React Native entry point.
|
|
3
|
-
*
|
|
4
|
-
* Currently exports only platform-agnostic tokens and types.
|
|
5
|
-
* When an RN app is built, add .native.tsx component implementations
|
|
6
|
-
* alongside the web components and export them here.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
export type { ButtonProps } from "./components/atoms/button";
|
|
10
|
-
// Types only (no DOM dependencies)
|
|
11
|
-
export type { IconName, IconProps } from "./components/atoms/icon";
|
|
12
|
-
export type { CodeBlockProps } from "./components/molecules/code-block";
|
|
13
|
-
export type { EmptyStateProps } from "./components/molecules/empty-state";
|
|
14
|
-
export type { ErrorStateProps } from "./components/molecules/error-state";
|
|
15
|
-
export type { FieldDisplayProps } from "./components/molecules/field-display";
|
|
16
|
-
export type { LoadingStateProps } from "./components/molecules/loading-state";
|
|
17
|
-
export type { SearchBarProps } from "./components/molecules/search-bar";
|
|
18
|
-
export type { StatusBadgeProps } from "./components/molecules/status-badge";
|
|
19
|
-
export type { DataTableColumn, DataTableProps } from "./components/organisms/data-table";
|
|
20
|
-
// Design tokens (shared with web)
|
|
21
|
-
export { colors, hslToString, hslToVar } from "./tokens/colors";
|
|
22
|
-
export { defaultRadius, radius, spacing } from "./tokens/spacing";
|
|
23
|
-
export { fontFamily, fontSize, fontWeight } from "./tokens/typography";
|
package/src/tokens/colors.ts
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* shadcn/ui default color tokens — platform-agnostic.
|
|
3
|
-
* Used by both web (via CSS custom properties) and React Native (via NativeWind/direct).
|
|
4
|
-
*
|
|
5
|
-
* Values are HSL arrays [h, s%, l%] matching the shadcn zinc/neutral theme.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
export const colors = {
|
|
9
|
-
light: {
|
|
10
|
-
background: [0, 0, 100],
|
|
11
|
-
foreground: [240, 10, 3.9],
|
|
12
|
-
card: [0, 0, 100],
|
|
13
|
-
cardForeground: [240, 10, 3.9],
|
|
14
|
-
popover: [0, 0, 100],
|
|
15
|
-
popoverForeground: [240, 10, 3.9],
|
|
16
|
-
primary: [240, 5.9, 10],
|
|
17
|
-
primaryForeground: [0, 0, 98],
|
|
18
|
-
secondary: [240, 4.8, 95.9],
|
|
19
|
-
secondaryForeground: [240, 5.9, 10],
|
|
20
|
-
muted: [240, 4.8, 95.9],
|
|
21
|
-
mutedForeground: [240, 3.8, 46.1],
|
|
22
|
-
accent: [240, 4.8, 95.9],
|
|
23
|
-
accentForeground: [240, 5.9, 10],
|
|
24
|
-
destructive: [0, 84.2, 60.2],
|
|
25
|
-
destructiveForeground: [0, 0, 98],
|
|
26
|
-
border: [240, 5.9, 90],
|
|
27
|
-
input: [240, 5.9, 90],
|
|
28
|
-
ring: [240, 5.9, 10],
|
|
29
|
-
chart1: [12, 76, 61],
|
|
30
|
-
chart2: [173, 58, 39],
|
|
31
|
-
chart3: [197, 37, 24],
|
|
32
|
-
chart4: [43, 74, 66],
|
|
33
|
-
chart5: [27, 87, 67],
|
|
34
|
-
sidebar: {
|
|
35
|
-
background: [230, 25, 97],
|
|
36
|
-
foreground: [230, 15, 40],
|
|
37
|
-
primary: [230, 45, 25],
|
|
38
|
-
primaryForeground: [0, 0, 98],
|
|
39
|
-
accent: [230, 40, 92],
|
|
40
|
-
accentForeground: [230, 45, 25],
|
|
41
|
-
border: [230, 20, 90],
|
|
42
|
-
ring: [217.2, 91.2, 59.8],
|
|
43
|
-
},
|
|
44
|
-
},
|
|
45
|
-
dark: {
|
|
46
|
-
background: [240, 10, 3.9],
|
|
47
|
-
foreground: [0, 0, 98],
|
|
48
|
-
card: [240, 10, 3.9],
|
|
49
|
-
cardForeground: [0, 0, 98],
|
|
50
|
-
popover: [240, 10, 3.9],
|
|
51
|
-
popoverForeground: [0, 0, 98],
|
|
52
|
-
primary: [0, 0, 98],
|
|
53
|
-
primaryForeground: [240, 5.9, 10],
|
|
54
|
-
secondary: [240, 3.7, 15.9],
|
|
55
|
-
secondaryForeground: [0, 0, 98],
|
|
56
|
-
muted: [240, 3.7, 15.9],
|
|
57
|
-
mutedForeground: [240, 5, 64.9],
|
|
58
|
-
accent: [240, 3.7, 15.9],
|
|
59
|
-
accentForeground: [0, 0, 98],
|
|
60
|
-
destructive: [0, 62.8, 30.6],
|
|
61
|
-
destructiveForeground: [0, 0, 98],
|
|
62
|
-
border: [240, 3.7, 15.9],
|
|
63
|
-
input: [240, 3.7, 15.9],
|
|
64
|
-
ring: [240, 4.9, 83.9],
|
|
65
|
-
chart1: [220, 70, 50],
|
|
66
|
-
chart2: [160, 60, 45],
|
|
67
|
-
chart3: [30, 80, 55],
|
|
68
|
-
chart4: [280, 65, 60],
|
|
69
|
-
chart5: [340, 75, 55],
|
|
70
|
-
sidebar: {
|
|
71
|
-
background: [230, 12, 10],
|
|
72
|
-
foreground: [230, 8, 80],
|
|
73
|
-
primary: [217, 91, 65],
|
|
74
|
-
primaryForeground: [0, 0, 100],
|
|
75
|
-
accent: [230, 25, 22],
|
|
76
|
-
accentForeground: [230, 60, 88],
|
|
77
|
-
border: [230, 8, 18],
|
|
78
|
-
ring: [217.2, 91.2, 59.8],
|
|
79
|
-
},
|
|
80
|
-
},
|
|
81
|
-
} as const;
|
|
82
|
-
|
|
83
|
-
/** Convert an HSL tuple to a CSS-compatible string */
|
|
84
|
-
export function hslToString(hsl: readonly [number, number, number]): string {
|
|
85
|
-
return `hsl(${hsl[0]} ${hsl[1]}% ${hsl[2]}%)`;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/** Convert an HSL tuple to the space-separated format used in CSS variables */
|
|
89
|
-
export function hslToVar(hsl: readonly [number, number, number]): string {
|
|
90
|
-
return `${hsl[0]} ${hsl[1]}% ${hsl[2]}%`;
|
|
91
|
-
}
|
package/src/tokens/index.ts
DELETED
package/src/tokens/spacing.ts
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Olympus spacing scale — platform-agnostic design tokens.
|
|
3
|
-
* Values in pixels, convertible to rem (web) or dp (React Native).
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
export const spacing = {
|
|
7
|
-
0: 0,
|
|
8
|
-
0.5: 2,
|
|
9
|
-
1: 4,
|
|
10
|
-
1.5: 6,
|
|
11
|
-
2: 8,
|
|
12
|
-
2.5: 10,
|
|
13
|
-
3: 12,
|
|
14
|
-
3.5: 14,
|
|
15
|
-
4: 16,
|
|
16
|
-
5: 20,
|
|
17
|
-
6: 24,
|
|
18
|
-
7: 28,
|
|
19
|
-
8: 32,
|
|
20
|
-
9: 36,
|
|
21
|
-
10: 40,
|
|
22
|
-
11: 44,
|
|
23
|
-
12: 48,
|
|
24
|
-
14: 56,
|
|
25
|
-
16: 64,
|
|
26
|
-
20: 80,
|
|
27
|
-
24: 96,
|
|
28
|
-
28: 112,
|
|
29
|
-
32: 128,
|
|
30
|
-
36: 144,
|
|
31
|
-
40: 160,
|
|
32
|
-
44: 176,
|
|
33
|
-
48: 192,
|
|
34
|
-
52: 208,
|
|
35
|
-
56: 224,
|
|
36
|
-
60: 240,
|
|
37
|
-
64: 256,
|
|
38
|
-
72: 288,
|
|
39
|
-
80: 320,
|
|
40
|
-
96: 384,
|
|
41
|
-
} as const;
|
|
42
|
-
|
|
43
|
-
export const radius = {
|
|
44
|
-
none: 0,
|
|
45
|
-
sm: 4,
|
|
46
|
-
md: 6,
|
|
47
|
-
lg: 8,
|
|
48
|
-
xl: 12,
|
|
49
|
-
"2xl": 16,
|
|
50
|
-
"3xl": 24,
|
|
51
|
-
full: 9999,
|
|
52
|
-
} as const;
|
|
53
|
-
|
|
54
|
-
/** Default border radius used across components (0.5rem = 8px) */
|
|
55
|
-
export const defaultRadius = "0.5rem";
|
package/src/tokens/typography.ts
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Olympus typography tokens — platform-agnostic design tokens.
|
|
3
|
-
* Font families, sizes, weights, and line heights.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
export const fontFamily = {
|
|
7
|
-
sans: ["Inter", "system-ui", "-apple-system", "sans-serif"],
|
|
8
|
-
mono: ["JetBrains Mono", "Fira Code", "monospace"],
|
|
9
|
-
} as const;
|
|
10
|
-
|
|
11
|
-
export const fontSize = {
|
|
12
|
-
xs: { size: 12, lineHeight: 16 },
|
|
13
|
-
sm: { size: 14, lineHeight: 20 },
|
|
14
|
-
base: { size: 16, lineHeight: 24 },
|
|
15
|
-
lg: { size: 18, lineHeight: 28 },
|
|
16
|
-
xl: { size: 20, lineHeight: 28 },
|
|
17
|
-
"2xl": { size: 24, lineHeight: 32 },
|
|
18
|
-
"3xl": { size: 30, lineHeight: 36 },
|
|
19
|
-
"4xl": { size: 36, lineHeight: 40 },
|
|
20
|
-
} as const;
|
|
21
|
-
|
|
22
|
-
export const fontWeight = {
|
|
23
|
-
normal: 400,
|
|
24
|
-
medium: 500,
|
|
25
|
-
semibold: 600,
|
|
26
|
-
bold: 700,
|
|
27
|
-
} as const;
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Re-export of react-grid-layout's base stylesheets.
|
|
3
|
-
*
|
|
4
|
-
* Consumers of `<DashboardGrid>` import this once at app entry:
|
|
5
|
-
*
|
|
6
|
-
* import "@olympusoss/canvas/styles/dashboard-grid.css";
|
|
7
|
-
*
|
|
8
|
-
* The actual imports resolve through the consumer's bundler. Both
|
|
9
|
-
* `react-grid-layout` and `react-resizable` are direct dependencies of
|
|
10
|
-
* canvas; if either isn't installed (e.g. peer-only consumer) the @import
|
|
11
|
-
* errors at build time, which is the right signal.
|
|
12
|
-
*
|
|
13
|
-
* On top of the lib's stock styles, the rules below recolour the placeholder
|
|
14
|
-
* (drop-target hint) and resize handles to match canvas tokens — the lib
|
|
15
|
-
* defaults are bright red / blue and don't fit the design system.
|
|
16
|
-
*/
|
|
17
|
-
@import "react-grid-layout/css/styles.css";
|
|
18
|
-
@import "react-resizable/css/styles.css";
|
|
19
|
-
|
|
20
|
-
.react-grid-item.react-grid-placeholder {
|
|
21
|
-
background: hsl(var(--accent));
|
|
22
|
-
opacity: 0.45;
|
|
23
|
-
border-radius: 0.75rem;
|
|
24
|
-
transition-property: transform;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
.react-grid-item > .react-resizable-handle {
|
|
28
|
-
opacity: 0;
|
|
29
|
-
transition: opacity 150ms ease;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
.react-grid-item:hover > .react-resizable-handle,
|
|
33
|
-
.react-grid-item.react-draggable-dragging > .react-resizable-handle {
|
|
34
|
-
opacity: 1;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/* Recolour the corner glyph the lib draws via ::after */
|
|
38
|
-
.react-grid-item > .react-resizable-handle::after {
|
|
39
|
-
border-color: hsl(var(--muted-foreground));
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/* When DashboardGrid is in view-mode (`editing=false`) we hide handles
|
|
43
|
-
* entirely — the cursor never tells the user "you can resize this".
|
|
44
|
-
*/
|
|
45
|
-
[data-dashboard-grid-editing="false"] .react-grid-item > .react-resizable-handle {
|
|
46
|
-
display: none;
|
|
47
|
-
}
|
|
Binary file
|