@olympusoss/canvas 2.20.2 → 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.
Files changed (214) hide show
  1. package/README.md +69 -35
  2. package/package.json +45 -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/base.css +17 -0
  8. package/styles/canvas.css +77 -52
  9. package/styles/components/alert.css +66 -0
  10. package/styles/components/app-shell.css +46 -0
  11. package/styles/components/avatar.css +22 -0
  12. package/styles/components/badge.css +83 -0
  13. package/styles/components/breadcrumb.css +35 -0
  14. package/styles/components/button-group.css +23 -0
  15. package/styles/components/button.css +107 -0
  16. package/styles/components/calendar.css +73 -0
  17. package/styles/components/card.css +58 -0
  18. package/styles/components/checkbox.css +55 -0
  19. package/styles/components/code-block.css +18 -0
  20. package/styles/components/combobox.css +75 -0
  21. package/styles/components/command.css +94 -0
  22. package/styles/components/data-table.css +142 -0
  23. package/styles/components/dialog.css +72 -0
  24. package/styles/components/dropdown.css +54 -0
  25. package/styles/components/empty-state.css +17 -0
  26. package/styles/components/field.css +27 -0
  27. package/styles/components/filter-panel.css +58 -0
  28. package/styles/components/form.css +27 -0
  29. package/styles/components/icon.css +8 -0
  30. package/styles/components/input-group.css +45 -0
  31. package/styles/components/input.css +56 -0
  32. package/styles/components/kbd.css +15 -0
  33. package/styles/components/page-header.css +52 -0
  34. package/styles/components/pagination.css +48 -0
  35. package/styles/components/popover.css +14 -0
  36. package/styles/components/radio.css +28 -0
  37. package/styles/components/row-menu.css +69 -0
  38. package/styles/components/section-card.css +49 -0
  39. package/styles/components/select.css +57 -0
  40. package/styles/components/separator.css +32 -0
  41. package/styles/components/sheet.css +70 -0
  42. package/styles/components/sidebar.css +146 -0
  43. package/styles/components/skeleton.css +32 -0
  44. package/styles/components/spinner.css +26 -0
  45. package/styles/components/stat-card.css +71 -0
  46. package/styles/components/stepper.css +63 -0
  47. package/styles/components/switch.css +45 -0
  48. package/styles/components/tabs.css +40 -0
  49. package/styles/components/textarea.css +31 -0
  50. package/styles/components/toast.css +95 -0
  51. package/styles/components/tooltip.css +53 -0
  52. package/styles/components/topbar.css +24 -0
  53. package/styles/components/typography.css +105 -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,100 +0,0 @@
1
- import { ArrowDown, ArrowUp } from "lucide-react";
2
- import type * as React from "react";
3
-
4
- import { cn } from "../../lib/utils";
5
- import { Card, CardContent } from "./card";
6
-
7
- export interface StatCardProps {
8
- title: string;
9
- value: React.ReactNode;
10
- icon?: React.ReactNode;
11
- colorVariant?: "primary" | "blue" | "purple" | "success" | "warning" | "amber" | "destructive";
12
- /** Optional delta line shown under the value (e.g. "+4.2%"). */
13
- delta?: React.ReactNode;
14
- /** Tone for the delta — `up` is green, `down` is red, `neutral` is muted. */
15
- deltaTone?: "up" | "down" | "neutral";
16
- /** Caption shown next to the delta (e.g. "vs. last 7d"). */
17
- deltaCaption?: React.ReactNode;
18
- /**
19
- * When `true` (default) and `delta` is a string, prepend an ArrowUp /
20
- * ArrowDown icon based on `deltaTone`. Pass `false` to opt out, or pass
21
- * `delta` as ReactNode to fully control rendering yourself.
22
- */
23
- deltaArrow?: boolean;
24
- /** Optional content rendered below the delta row (e.g. a sparkline or mini chart). */
25
- children?: React.ReactNode;
26
- className?: string;
27
- }
28
-
29
- const COLOR: Record<NonNullable<StatCardProps["colorVariant"]>, string> = {
30
- primary: "bg-primary/10 text-primary",
31
- blue: "bg-[hsl(var(--stat-blue)/0.1)] text-[hsl(var(--stat-blue))]",
32
- purple: "bg-[hsl(var(--stat-purple)/0.1)] text-[hsl(var(--stat-purple))]",
33
- success: "bg-[hsl(var(--stat-success)/0.1)] text-[hsl(var(--stat-success))]",
34
- warning: "bg-[hsl(var(--stat-amber)/0.1)] text-[hsl(var(--stat-amber))]",
35
- amber: "bg-[hsl(var(--stat-amber)/0.1)] text-[hsl(var(--stat-amber))]",
36
- destructive: "bg-[hsl(var(--stat-destructive)/0.1)] text-[hsl(var(--stat-destructive))]",
37
- };
38
-
39
- const DELTA_TONE: Record<NonNullable<StatCardProps["deltaTone"]>, string> = {
40
- up: "text-green-600 dark:text-green-500",
41
- down: "text-red-600 dark:text-red-500",
42
- neutral: "text-muted-foreground",
43
- };
44
-
45
- export function StatCard({
46
- title,
47
- value,
48
- icon,
49
- colorVariant = "primary",
50
- delta,
51
- deltaTone = "up",
52
- deltaCaption,
53
- deltaArrow = true,
54
- children,
55
- className,
56
- }: StatCardProps) {
57
- const showArrow = deltaArrow && typeof delta === "string" && deltaTone !== "neutral";
58
- const ArrowGlyph = deltaTone === "down" ? ArrowDown : ArrowUp;
59
- return (
60
- <Card className={className}>
61
- <CardContent className="p-5">
62
- <div className="flex items-start justify-between gap-3">
63
- <div className="min-w-0 flex-1">
64
- <p className="truncate text-[13px] font-medium text-muted-foreground">{title}</p>
65
- <p className="mt-1 text-[28px] font-semibold leading-tight tracking-[-0.02em]">
66
- {value}
67
- </p>
68
- </div>
69
- {icon && (
70
- <div
71
- className={cn(
72
- "flex h-9 w-9 shrink-0 items-center justify-center rounded-lg",
73
- COLOR[colorVariant],
74
- )}
75
- >
76
- {icon}
77
- </div>
78
- )}
79
- </div>
80
- {delta != null && (
81
- <div className="mt-3 flex items-center gap-1.5 text-xs">
82
- <span
83
- className={cn(
84
- "inline-flex items-center gap-0.5 font-mono font-medium",
85
- DELTA_TONE[deltaTone],
86
- )}
87
- >
88
- {showArrow && <ArrowGlyph className="h-3 w-3" aria-hidden />}
89
- {delta}
90
- </span>
91
- {deltaCaption != null && <span className="text-muted-foreground">{deltaCaption}</span>}
92
- </div>
93
- )}
94
- {children != null && <div className="mt-3">{children}</div>}
95
- </CardContent>
96
- </Card>
97
- );
98
- }
99
-
100
- StatCard.displayName = "StatCard";
@@ -1,42 +0,0 @@
1
- import { cva, type VariantProps } from "class-variance-authority";
2
- import * as React from "react";
3
-
4
- import { cn } from "../../lib/utils";
5
-
6
- const statusBadgeVariants = cva(
7
- "inline-flex items-center gap-1.5 rounded-full px-2.5 py-0.5 text-xs font-medium",
8
- {
9
- variants: {
10
- status: {
11
- success: "bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400",
12
- warning: "bg-yellow-100 text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-400",
13
- error: "bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-400",
14
- info: "bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-400",
15
- neutral: "bg-muted text-muted-foreground",
16
- },
17
- },
18
- defaultVariants: {
19
- status: "neutral",
20
- },
21
- },
22
- );
23
-
24
- export interface StatusBadgeProps
25
- extends React.HTMLAttributes<HTMLSpanElement>,
26
- VariantProps<typeof statusBadgeVariants> {
27
- dot?: boolean;
28
- }
29
-
30
- const StatusBadge = React.forwardRef<HTMLSpanElement, StatusBadgeProps>(
31
- ({ status, dot = true, className, children, ...props }, ref) => {
32
- return (
33
- <span ref={ref} className={cn(statusBadgeVariants({ status }), className)} {...props}>
34
- {dot && <span className="h-1.5 w-1.5 rounded-full bg-current" />}
35
- {children}
36
- </span>
37
- );
38
- },
39
- );
40
- StatusBadge.displayName = "StatusBadge";
41
-
42
- export { StatusBadge, statusBadgeVariants };
@@ -1,96 +0,0 @@
1
- "use client";
2
-
3
- import type * as React from "react";
4
-
5
- import { cn } from "../../lib/utils";
6
- import { Icon } from "../atoms/icon";
7
-
8
- export type StepStatus = "pending" | "active" | "complete" | "error";
9
-
10
- export interface StepperStep {
11
- id: string;
12
- label: string;
13
- status: StepStatus;
14
- /** Optional icon override (atoms/icon IconName or React node). */
15
- icon?: React.ReactNode;
16
- disabled?: boolean;
17
- }
18
-
19
- export interface StepperProps {
20
- steps: StepperStep[];
21
- orientation?: "horizontal" | "vertical";
22
- onStepClick?: (id: string) => void;
23
- className?: string;
24
- }
25
-
26
- const STATUS_STYLES: Record<StepStatus, { dot: string; label: string }> = {
27
- pending: {
28
- dot: "border-muted-foreground/30 text-muted-foreground",
29
- label: "text-muted-foreground",
30
- },
31
- active: {
32
- dot: "border-primary bg-primary text-primary-foreground",
33
- label: "text-foreground font-medium",
34
- },
35
- complete: {
36
- dot: "border-green-500 bg-green-500 text-white",
37
- label: "text-foreground",
38
- },
39
- error: {
40
- dot: "border-destructive bg-destructive text-destructive-foreground",
41
- label: "text-destructive",
42
- },
43
- };
44
-
45
- export function Stepper({ steps, orientation = "vertical", onStepClick, className }: StepperProps) {
46
- const vertical = orientation === "vertical";
47
- return (
48
- <ol
49
- className={cn("flex", vertical ? "flex-col gap-1" : "flex-row items-center gap-2", className)}
50
- >
51
- {steps.map((step, i) => {
52
- const styles = STATUS_STYLES[step.status];
53
- const clickable = !!onStepClick && !step.disabled;
54
- return (
55
- <li key={step.id} className={cn("flex items-center gap-3", vertical ? "py-2" : "flex-1")}>
56
- <button
57
- type="button"
58
- disabled={!clickable}
59
- onClick={() => clickable && onStepClick(step.id)}
60
- className={cn(
61
- "flex items-center gap-3 rounded-md transition-colors",
62
- vertical && "w-full px-2 py-1 text-left",
63
- clickable && "hover:bg-accent/50",
64
- )}
65
- >
66
- <span
67
- className={cn(
68
- "flex h-6 w-6 shrink-0 items-center justify-center rounded-full border border-border text-xs",
69
- styles.dot,
70
- )}
71
- >
72
- {step.icon ? (
73
- typeof step.icon === "string" ? (
74
- <Icon name={step.icon as never} className="h-3.5 w-3.5" />
75
- ) : (
76
- step.icon
77
- )
78
- ) : step.status === "complete" ? (
79
- <Icon name="Check" className="h-3.5 w-3.5" />
80
- ) : step.status === "error" ? (
81
- <Icon name="X" className="h-3.5 w-3.5" />
82
- ) : (
83
- i + 1
84
- )}
85
- </span>
86
- <span className={cn("text-sm", styles.label)}>{step.label}</span>
87
- </button>
88
- {!vertical && i < steps.length - 1 && <span className="mx-2 h-px flex-1 bg-border" />}
89
- </li>
90
- );
91
- })}
92
- </ol>
93
- );
94
- }
95
-
96
- Stepper.displayName = "Stepper";
@@ -1,157 +0,0 @@
1
- import * as React from "react";
2
-
3
- import { cn } from "../../lib/utils";
4
-
5
- export interface TableProps extends React.HTMLAttributes<HTMLTableElement> {
6
- /** `<TableHeader>` + `<TableBody>` + optional `<TableFooter>` + optional `<TableCaption>`. */
7
- children?: React.ReactNode;
8
- /** Tailwind / CSS classes merged onto the `<table>` via `cn()`. */
9
- className?: string;
10
- }
11
-
12
- const Table = React.forwardRef<HTMLTableElement, TableProps>(({ className, ...props }, ref) => (
13
- <div className="relative w-full overflow-auto">
14
- <table ref={ref} className={cn("w-full caption-bottom text-sm", className)} {...props} />
15
- </div>
16
- ));
17
- Table.displayName = "Table";
18
-
19
- export interface TableHeaderProps extends React.HTMLAttributes<HTMLTableSectionElement> {
20
- /** A single `<TableRow>` of `<TableHead>` cells. */
21
- children?: React.ReactNode;
22
- /** Tailwind / CSS classes merged onto the `<thead>` via `cn()`. */
23
- className?: string;
24
- }
25
-
26
- const TableHeader = React.forwardRef<HTMLTableSectionElement, TableHeaderProps>(
27
- ({ className, ...props }, ref) => (
28
- <thead ref={ref} className={cn("[&_tr]:border-b", className)} {...props} />
29
- ),
30
- );
31
- TableHeader.displayName = "TableHeader";
32
-
33
- export interface TableBodyProps extends React.HTMLAttributes<HTMLTableSectionElement> {
34
- /** A list of `<TableRow>`s of `<TableCell>`s. */
35
- children?: React.ReactNode;
36
- /** Tailwind / CSS classes merged onto the `<tbody>` via `cn()`. */
37
- className?: string;
38
- }
39
-
40
- const TableBody = React.forwardRef<HTMLTableSectionElement, TableBodyProps>(
41
- ({ className, ...props }, ref) => (
42
- <tbody ref={ref} className={cn("[&_tr:last-child]:border-0", className)} {...props} />
43
- ),
44
- );
45
- TableBody.displayName = "TableBody";
46
-
47
- export interface TableFooterProps extends React.HTMLAttributes<HTMLTableSectionElement> {
48
- /** A `<TableRow>` of summary `<TableCell>`s (totals, etc.). */
49
- children?: React.ReactNode;
50
- /** Tailwind / CSS classes merged onto the `<tfoot>` via `cn()`. */
51
- className?: string;
52
- }
53
-
54
- const TableFooter = React.forwardRef<HTMLTableSectionElement, TableFooterProps>(
55
- ({ className, ...props }, ref) => (
56
- <tfoot
57
- ref={ref}
58
- className={cn("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0", className)}
59
- {...props}
60
- />
61
- ),
62
- );
63
- TableFooter.displayName = "TableFooter";
64
-
65
- export interface TableRowProps extends React.HTMLAttributes<HTMLTableRowElement> {
66
- /** `<TableHead>` or `<TableCell>` children. */
67
- children?: React.ReactNode;
68
- /** Tailwind / CSS classes merged onto the `<tr>` via `cn()`. */
69
- className?: string;
70
- /**
71
- * Optional data-state — pass `"selected"` to highlight selected rows
72
- * (e.g. checkbox-driven multi-select tables). Mirrors Radix's pattern.
73
- */
74
- "data-state"?: "selected";
75
- }
76
-
77
- const TableRow = React.forwardRef<HTMLTableRowElement, TableRowProps>(
78
- ({ className, ...props }, ref) => (
79
- <tr
80
- ref={ref}
81
- className={cn(
82
- "border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted",
83
- className,
84
- )}
85
- {...props}
86
- />
87
- ),
88
- );
89
- TableRow.displayName = "TableRow";
90
-
91
- export interface TableHeadProps extends React.ThHTMLAttributes<HTMLTableCellElement> {
92
- /** Column header text. */
93
- children?: React.ReactNode;
94
- /** Tailwind / CSS classes merged onto the `<th>` via `cn()`. */
95
- className?: string;
96
- /** Number of columns this header spans. */
97
- colSpan?: number;
98
- /** Number of rows this header spans. */
99
- rowSpan?: number;
100
- /** Scope of the header — `"col"` (default) or `"row"` for row-headers. */
101
- scope?: "col" | "row" | "rowgroup" | "colgroup";
102
- }
103
-
104
- const TableHead = React.forwardRef<HTMLTableCellElement, TableHeadProps>(
105
- ({ className, ...props }, ref) => (
106
- <th
107
- ref={ref}
108
- className={cn(
109
- "h-10 px-2 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
110
- className,
111
- )}
112
- {...props}
113
- />
114
- ),
115
- );
116
- TableHead.displayName = "TableHead";
117
-
118
- export interface TableCellProps extends React.TdHTMLAttributes<HTMLTableCellElement> {
119
- /** Cell content. */
120
- children?: React.ReactNode;
121
- /** Tailwind / CSS classes merged onto the `<td>` via `cn()`. */
122
- className?: string;
123
- /** Number of columns this cell spans. */
124
- colSpan?: number;
125
- /** Number of rows this cell spans. */
126
- rowSpan?: number;
127
- }
128
-
129
- const TableCell = React.forwardRef<HTMLTableCellElement, TableCellProps>(
130
- ({ className, ...props }, ref) => (
131
- <td
132
- ref={ref}
133
- className={cn(
134
- "p-2 align-middle [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
135
- className,
136
- )}
137
- {...props}
138
- />
139
- ),
140
- );
141
- TableCell.displayName = "TableCell";
142
-
143
- export interface TableCaptionProps extends React.HTMLAttributes<HTMLTableCaptionElement> {
144
- /** A short label describing the table — read by screen readers. */
145
- children?: React.ReactNode;
146
- /** Tailwind / CSS classes merged onto the `<caption>` via `cn()`. */
147
- className?: string;
148
- }
149
-
150
- const TableCaption = React.forwardRef<HTMLTableCaptionElement, TableCaptionProps>(
151
- ({ className, ...props }, ref) => (
152
- <caption ref={ref} className={cn("mt-4 text-sm text-muted-foreground", className)} {...props} />
153
- ),
154
- );
155
- TableCaption.displayName = "TableCaption";
156
-
157
- export { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow };
@@ -1,74 +0,0 @@
1
- // molecules: can import tokens/, lib/utils, atoms/.
2
- import * as React from "react";
3
-
4
- import { cn } from "../../lib/utils";
5
-
6
- export interface TerminalProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "title"> {
7
- /**
8
- * Optional label rendered in the macOS-style chrome strip, next to the
9
- * traffic-light dots. Typical use: a working directory + command
10
- * (e.g. `~/Olympus · octl`).
11
- */
12
- title?: React.ReactNode;
13
- /**
14
- * Terminal body. Renders inside a `<pre>` with mono font and 1.7 line
15
- * height. Free-form — drop plain text, ANSI-coloured `<span>`s, or any
16
- * inline highlights you want.
17
- */
18
- children: React.ReactNode;
19
- className?: string;
20
- }
21
-
22
- const Terminal = React.forwardRef<HTMLDivElement, TerminalProps>(
23
- ({ title, children, className, ...props }, ref) => (
24
- <div
25
- ref={ref}
26
- data-slot="terminal"
27
- className={cn(
28
- "overflow-hidden rounded-xl border border-border shadow-[0_30px_60px_-20px_rgb(0_0_0/0.35)]",
29
- className,
30
- )}
31
- style={{ background: "#0a0a0b" }}
32
- {...props}
33
- >
34
- <div
35
- className="flex items-center gap-1.5 px-3"
36
- style={{
37
- height: 32,
38
- background: "#141417",
39
- borderBottom: "1px solid #222",
40
- }}
41
- >
42
- <span
43
- aria-hidden="true"
44
- className="inline-block h-2.5 w-2.5 rounded-full"
45
- style={{ background: "#ff5f57" }}
46
- />
47
- <span
48
- aria-hidden="true"
49
- className="inline-block h-2.5 w-2.5 rounded-full"
50
- style={{ background: "#febc2e" }}
51
- />
52
- <span
53
- aria-hidden="true"
54
- className="inline-block h-2.5 w-2.5 rounded-full"
55
- style={{ background: "#28c840" }}
56
- />
57
- {title != null && (
58
- <span className="ml-2.5 font-mono text-[11px]" style={{ color: "#6b7280" }}>
59
- {title}
60
- </span>
61
- )}
62
- </div>
63
- <pre
64
- className="m-0 overflow-x-auto p-5 font-mono text-[12.5px] leading-[1.7]"
65
- style={{ color: "#e4e4e7" }}
66
- >
67
- {children}
68
- </pre>
69
- </div>
70
- ),
71
- );
72
- Terminal.displayName = "Terminal";
73
-
74
- export { Terminal };
@@ -1,145 +0,0 @@
1
- "use client";
2
-
3
- import * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group";
4
- import type { VariantProps } from "class-variance-authority";
5
- import * as React from "react";
6
-
7
- import { cn } from "../../lib/utils";
8
- import { toggleVariants } from "../atoms/toggle";
9
-
10
- const ToggleGroupContext = React.createContext<VariantProps<typeof toggleVariants>>({
11
- size: "default",
12
- variant: "default",
13
- });
14
-
15
- export interface ToggleGroupProps {
16
- /**
17
- * Selection mode. `"single"` allows one item active at a time;
18
- * `"multiple"` allows independent toggles.
19
- */
20
- type: "single" | "multiple";
21
- /**
22
- * Controlled value. For `type="single"` it's a string; for
23
- * `type="multiple"` it's an array of strings.
24
- */
25
- value?: string | string[];
26
- /** Initial value for uncontrolled usage. */
27
- defaultValue?: string | string[];
28
- /** Fires when the user toggles an item. */
29
- onValueChange?: (value: string & string[]) => void;
30
- /**
31
- * Disable every toggle in the group.
32
- * @default false
33
- */
34
- disabled?: boolean;
35
- /**
36
- * Layout direction.
37
- * @default "horizontal"
38
- */
39
- orientation?: "horizontal" | "vertical";
40
- /**
41
- * Reading direction. Affects keyboard arrow navigation.
42
- * @default "ltr"
43
- */
44
- dir?: "ltr" | "rtl";
45
- /**
46
- * When true, arrow-key navigation wraps from the last item to the first.
47
- * @default true
48
- */
49
- loop?: boolean;
50
- /**
51
- * Filled vs outlined preset (inherits from `<Toggle>`).
52
- * @default "default"
53
- */
54
- variant?: "default" | "outline";
55
- /**
56
- * Size preset (inherits from `<Toggle>`).
57
- * @default "default"
58
- */
59
- size?: "default" | "sm" | "lg";
60
- /**
61
- * Render as a Radix Slot — forwards props onto the immediate child.
62
- * @default false
63
- */
64
- asChild?: boolean;
65
- /** A flat list of `<ToggleGroupItem>`s. */
66
- children?: React.ReactNode;
67
- /** Tailwind / CSS classes merged onto the group via `cn()`. */
68
- className?: string;
69
- }
70
-
71
- const ToggleGroupImpl = React.forwardRef<
72
- React.ElementRef<typeof ToggleGroupPrimitive.Root>,
73
- ToggleGroupProps
74
- >(({ className, variant, size, children, ...props }, ref) => (
75
- <ToggleGroupPrimitive.Root
76
- ref={ref}
77
- {...(props as React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Root>)}
78
- className={cn("flex items-center justify-center gap-1", className)}
79
- >
80
- <ToggleGroupContext.Provider value={{ variant, size }}>{children}</ToggleGroupContext.Provider>
81
- </ToggleGroupPrimitive.Root>
82
- ));
83
-
84
- ToggleGroupImpl.displayName = ToggleGroupPrimitive.Root.displayName;
85
-
86
- const ToggleGroup = ToggleGroupImpl as React.ForwardRefExoticComponent<
87
- ToggleGroupProps & React.RefAttributes<HTMLDivElement>
88
- >;
89
-
90
- export interface ToggleGroupItemProps
91
- extends React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Item>,
92
- VariantProps<typeof toggleVariants> {
93
- /** Required — value reported when this toggle is active. */
94
- value: string;
95
- /**
96
- * Disable only this toggle.
97
- * @default false
98
- */
99
- disabled?: boolean;
100
- /**
101
- * Filled vs outlined. Defaults to inheriting from the parent
102
- * `<ToggleGroup>`.
103
- */
104
- variant?: "default" | "outline";
105
- /**
106
- * Size preset. Defaults to inheriting from the parent `<ToggleGroup>`.
107
- */
108
- size?: "default" | "sm" | "lg";
109
- /**
110
- * Render as a Radix Slot — forwards props onto the immediate child.
111
- * @default false
112
- */
113
- asChild?: boolean;
114
- /** Toggle label or icon. */
115
- children?: React.ReactNode;
116
- /** Tailwind / CSS classes merged onto the toggle via `cn()`. */
117
- className?: string;
118
- }
119
-
120
- const ToggleGroupItem = React.forwardRef<
121
- React.ElementRef<typeof ToggleGroupPrimitive.Item>,
122
- ToggleGroupItemProps
123
- >(({ className, children, variant, size, ...props }, ref) => {
124
- const context = React.useContext(ToggleGroupContext);
125
-
126
- return (
127
- <ToggleGroupPrimitive.Item
128
- ref={ref}
129
- className={cn(
130
- toggleVariants({
131
- variant: context.variant || variant,
132
- size: context.size || size,
133
- }),
134
- className,
135
- )}
136
- {...props}
137
- >
138
- {children}
139
- </ToggleGroupPrimitive.Item>
140
- );
141
- });
142
-
143
- ToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName;
144
-
145
- export { ToggleGroup, ToggleGroupItem };