@olympusoss/canvas 2.20.2 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (214) hide show
  1. package/README.md +73 -35
  2. package/package.json +46 -177
  3. package/src/cn.ts +3 -0
  4. package/src/index.ts +12 -603
  5. package/src/theme.ts +62 -0
  6. package/src/tokens.ts +11 -0
  7. package/styles/atoms/avatar.css +22 -0
  8. package/styles/atoms/badge.css +83 -0
  9. package/styles/atoms/breadcrumb.css +35 -0
  10. package/styles/atoms/button-group.css +23 -0
  11. package/styles/atoms/button.css +107 -0
  12. package/styles/atoms/checkbox.css +55 -0
  13. package/styles/atoms/combobox.css +75 -0
  14. package/styles/atoms/dropdown.css +54 -0
  15. package/styles/atoms/icon.css +8 -0
  16. package/styles/atoms/input-group.css +45 -0
  17. package/styles/atoms/input.css +56 -0
  18. package/styles/atoms/kbd.css +15 -0
  19. package/styles/atoms/pagination.css +48 -0
  20. package/styles/atoms/popover.css +14 -0
  21. package/styles/atoms/radio.css +28 -0
  22. package/styles/atoms/select.css +57 -0
  23. package/styles/atoms/separator.css +32 -0
  24. package/styles/atoms/skeleton.css +32 -0
  25. package/styles/atoms/spinner.css +26 -0
  26. package/styles/atoms/switch.css +45 -0
  27. package/styles/atoms/textarea.css +31 -0
  28. package/styles/atoms/tooltip.css +53 -0
  29. package/styles/atoms/typography.css +105 -0
  30. package/styles/base.css +17 -0
  31. package/styles/canvas.css +77 -52
  32. package/styles/molecules/alert.css +66 -0
  33. package/styles/molecules/card.css +58 -0
  34. package/styles/molecules/code-block.css +18 -0
  35. package/styles/molecules/empty-state.css +17 -0
  36. package/styles/molecules/field.css +27 -0
  37. package/styles/molecules/form.css +27 -0
  38. package/styles/molecules/page-header.css +52 -0
  39. package/styles/molecules/section-card.css +49 -0
  40. package/styles/molecules/stat-card.css +71 -0
  41. package/styles/molecules/toast.css +95 -0
  42. package/styles/organisms/app-shell.css +46 -0
  43. package/styles/organisms/calendar.css +73 -0
  44. package/styles/organisms/command.css +94 -0
  45. package/styles/organisms/data-table.css +142 -0
  46. package/styles/organisms/dialog.css +72 -0
  47. package/styles/organisms/filter-panel.css +58 -0
  48. package/styles/organisms/row-menu.css +69 -0
  49. package/styles/organisms/sheet.css +70 -0
  50. package/styles/organisms/sidebar.css +146 -0
  51. package/styles/organisms/stepper.css +63 -0
  52. package/styles/organisms/tabs.css +40 -0
  53. package/styles/organisms/topbar.css +24 -0
  54. package/styles/patterns/backdrops.css +35 -0
  55. package/styles/patterns/density.css +66 -0
  56. package/styles/patterns/focus.css +22 -0
  57. package/styles/patterns/glass.css +85 -0
  58. package/styles/patterns/high-contrast.css +70 -0
  59. package/styles/patterns/reduced-motion.css +12 -0
  60. package/styles/patterns/scrollbar.css +10 -0
  61. package/styles/reset.css +89 -0
  62. package/styles/tokens/colors.css +106 -0
  63. package/styles/tokens/motion.css +33 -0
  64. package/styles/tokens/radius.css +10 -0
  65. package/styles/tokens/shadows.css +35 -0
  66. package/styles/tokens/spacing.css +19 -0
  67. package/styles/tokens/typography.css +6 -0
  68. package/styles/tokens/z-index.css +12 -0
  69. package/styles/utilities/display.css +66 -0
  70. package/styles/utilities/flexbox.css +240 -0
  71. package/styles/utilities/gap.css +288 -0
  72. package/styles/utilities/grid.css +138 -0
  73. package/styles/utilities/position.css +78 -0
  74. package/styles/utilities/sizing.css +138 -0
  75. package/tsconfig.json +20 -21
  76. package/src/components/atoms/README.md +0 -11
  77. package/src/components/atoms/aspect-ratio.tsx +0 -32
  78. package/src/components/atoms/avatar.tsx +0 -98
  79. package/src/components/atoms/badge.tsx +0 -44
  80. package/src/components/atoms/brand-mark.tsx +0 -74
  81. package/src/components/atoms/button.tsx +0 -105
  82. package/src/components/atoms/checkbox.tsx +0 -63
  83. package/src/components/atoms/flex-box.tsx +0 -105
  84. package/src/components/atoms/icon.tsx +0 -34
  85. package/src/components/atoms/input.tsx +0 -92
  86. package/src/components/atoms/label.tsx +0 -41
  87. package/src/components/atoms/logo.tsx +0 -89
  88. package/src/components/atoms/progress.tsx +0 -55
  89. package/src/components/atoms/radio-group.tsx +0 -122
  90. package/src/components/atoms/scroll-area.tsx +0 -106
  91. package/src/components/atoms/section.tsx +0 -48
  92. package/src/components/atoms/separator.tsx +0 -45
  93. package/src/components/atoms/skeleton.tsx +0 -17
  94. package/src/components/atoms/slider.tsx +0 -93
  95. package/src/components/atoms/spinner.tsx +0 -47
  96. package/src/components/atoms/switch.tsx +0 -60
  97. package/src/components/atoms/textarea.tsx +0 -78
  98. package/src/components/atoms/toggle.tsx +0 -80
  99. package/src/components/charts/activity-heatmap.tsx +0 -186
  100. package/src/components/charts/axes.tsx +0 -21
  101. package/src/components/charts/chart-container.tsx +0 -254
  102. package/src/components/charts/chart-legend.tsx +0 -67
  103. package/src/components/charts/chart-tooltip.tsx +0 -161
  104. package/src/components/charts/chart-types.tsx +0 -49
  105. package/src/components/charts/containers.tsx +0 -11
  106. package/src/components/charts/data.tsx +0 -16
  107. package/src/components/charts/details.tsx +0 -25
  108. package/src/components/charts/dot-pulse.tsx +0 -61
  109. package/src/components/charts/gauge.tsx +0 -106
  110. package/src/components/charts/grids.tsx +0 -8
  111. package/src/components/charts/index.ts +0 -62
  112. package/src/components/charts/labeled-bar-list.tsx +0 -85
  113. package/src/components/charts/metric-breakdown.tsx +0 -316
  114. package/src/components/charts/references.tsx +0 -8
  115. package/src/components/charts/service-health-list.tsx +0 -85
  116. package/src/components/charts/sparkline-area.tsx +0 -80
  117. package/src/components/charts/sparkline.tsx +0 -52
  118. package/src/components/charts/stacked-bar.tsx +0 -104
  119. package/src/components/charts/text.tsx +0 -10
  120. package/src/components/charts/world-heat-map-inner.tsx +0 -317
  121. package/src/components/charts/world-heat-map.tsx +0 -184
  122. package/src/components/molecules/README.md +0 -12
  123. package/src/components/molecules/action-bar.tsx +0 -73
  124. package/src/components/molecules/activity-item.tsx +0 -74
  125. package/src/components/molecules/alert.tsx +0 -86
  126. package/src/components/molecules/animated-background.tsx +0 -92
  127. package/src/components/molecules/auth-shell.tsx +0 -95
  128. package/src/components/molecules/brand-lockup.tsx +0 -48
  129. package/src/components/molecules/breadcrumb.tsx +0 -157
  130. package/src/components/molecules/button-group.tsx +0 -104
  131. package/src/components/molecules/calendar.tsx +0 -217
  132. package/src/components/molecules/card.tsx +0 -102
  133. package/src/components/molecules/client-brand.tsx +0 -95
  134. package/src/components/molecules/code-block.tsx +0 -86
  135. package/src/components/molecules/countdown-button.tsx +0 -92
  136. package/src/components/molecules/empty-state.tsx +0 -56
  137. package/src/components/molecules/error-state.tsx +0 -42
  138. package/src/components/molecules/field-display.tsx +0 -35
  139. package/src/components/molecules/input-otp.tsx +0 -74
  140. package/src/components/molecules/launcher-card.tsx +0 -152
  141. package/src/components/molecules/loading-state.tsx +0 -36
  142. package/src/components/molecules/notification-item.tsx +0 -67
  143. package/src/components/molecules/notification-list.tsx +0 -45
  144. package/src/components/molecules/number-badge.tsx +0 -53
  145. package/src/components/molecules/or-separator.tsx +0 -38
  146. package/src/components/molecules/page-header.tsx +0 -88
  147. package/src/components/molecules/page-tabs.tsx +0 -94
  148. package/src/components/molecules/pagination.tsx +0 -150
  149. package/src/components/molecules/password-input.tsx +0 -83
  150. package/src/components/molecules/password-strength-meter.tsx +0 -104
  151. package/src/components/molecules/phone-input.tsx +0 -200
  152. package/src/components/molecules/search-bar.tsx +0 -64
  153. package/src/components/molecules/secret-field.tsx +0 -158
  154. package/src/components/molecules/section-card.tsx +0 -91
  155. package/src/components/molecules/social-buttons.tsx +0 -165
  156. package/src/components/molecules/stat-card.tsx +0 -100
  157. package/src/components/molecules/status-badge.tsx +0 -42
  158. package/src/components/molecules/stepper.tsx +0 -96
  159. package/src/components/molecules/table.tsx +0 -157
  160. package/src/components/molecules/terminal.tsx +0 -74
  161. package/src/components/molecules/toggle-group.tsx +0 -145
  162. package/src/components/molecules/tooltip.tsx +0 -155
  163. package/src/components/molecules/user-avatar-chip.tsx +0 -71
  164. package/src/components/organisms/README.md +0 -14
  165. package/src/components/organisms/accordion.tsx +0 -154
  166. package/src/components/organisms/alert-dialog.tsx +0 -277
  167. package/src/components/organisms/carousel.tsx +0 -244
  168. package/src/components/organisms/collapsible.tsx +0 -69
  169. package/src/components/organisms/command.tsx +0 -144
  170. package/src/components/organisms/context-menu.tsx +0 -339
  171. package/src/components/organisms/dashboard-grid.tsx +0 -369
  172. package/src/components/organisms/data-table.tsx +0 -330
  173. package/src/components/organisms/dialog.tsx +0 -312
  174. package/src/components/organisms/drawer.tsx +0 -123
  175. package/src/components/organisms/dropdown-menu.tsx +0 -440
  176. package/src/components/organisms/editors/code-editor.tsx +0 -144
  177. package/src/components/organisms/editors/index.ts +0 -4
  178. package/src/components/organisms/editors/markdown-editor.tsx +0 -153
  179. package/src/components/organisms/editors/markdown-renderer.ts +0 -27
  180. package/src/components/organisms/editors/prose-canvas-classes.ts +0 -45
  181. package/src/components/organisms/editors/rich-text-editor.tsx +0 -126
  182. package/src/components/organisms/editors/toolbar/md-toolbar.tsx +0 -129
  183. package/src/components/organisms/editors/toolbar/rte-toolbar.tsx +0 -211
  184. package/src/components/organisms/editors/toolbar/toolbar-shell.tsx +0 -45
  185. package/src/components/organisms/editors/use-codemirror-theme.ts +0 -61
  186. package/src/components/organisms/error-boundary.tsx +0 -61
  187. package/src/components/organisms/form.tsx +0 -174
  188. package/src/components/organisms/hover-card.tsx +0 -115
  189. package/src/components/organisms/menubar.tsx +0 -498
  190. package/src/components/organisms/navbar.tsx +0 -104
  191. package/src/components/organisms/navigation-menu.tsx +0 -235
  192. package/src/components/organisms/popover.tsx +0 -149
  193. package/src/components/organisms/resizable.tsx +0 -58
  194. package/src/components/organisms/schema-form.tsx +0 -232
  195. package/src/components/organisms/select.tsx +0 -309
  196. package/src/components/organisms/sheet.tsx +0 -265
  197. package/src/components/organisms/sidebar.tsx +0 -1040
  198. package/src/components/organisms/sonner.tsx +0 -96
  199. package/src/components/organisms/tabs.tsx +0 -133
  200. package/src/components/organisms/theme-provider.tsx +0 -101
  201. package/src/hooks/use-mobile.tsx +0 -19
  202. package/src/lib/portal-container.tsx +0 -35
  203. package/src/lib/utils.ts +0 -6
  204. package/src/native.ts +0 -23
  205. package/src/tokens/colors.ts +0 -91
  206. package/src/tokens/index.ts +0 -3
  207. package/src/tokens/spacing.ts +0 -55
  208. package/src/tokens/typography.ts +0 -27
  209. package/styles/dashboard-grid.css +0 -47
  210. package/styles/fonts/Roboto-VariableFont_wdth_wght.ttf +0 -0
  211. package/styles/glass.css +0 -175
  212. package/styles/leaflet.css +0 -13
  213. package/styles/tokens.css +0 -317
  214. 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";