@olympusoss/canvas 2.14.0 → 2.16.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/package.json +1 -1
- package/src/components/atoms/input.tsx +1 -0
- package/src/components/molecules/card.tsx +1 -0
- package/src/components/molecules/code-block.tsx +1 -0
- package/src/components/molecules/empty-state.tsx +1 -0
- package/src/components/molecules/section-card.tsx +1 -1
- package/src/components/organisms/data-table.tsx +1 -1
- package/src/components/organisms/drawer.tsx +1 -0
- package/src/components/organisms/popover.tsx +1 -0
- package/src/components/organisms/sheet.tsx +1 -0
- package/src/components/organisms/sidebar.tsx +2 -0
- package/styles/fonts/Roboto-VariableFont_wdth_wght.ttf +0 -0
- package/styles/glass.css +137 -0
- package/styles/tokens.css +18 -2
package/package.json
CHANGED
|
@@ -76,6 +76,7 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
|
|
76
76
|
return (
|
|
77
77
|
<input
|
|
78
78
|
type={type}
|
|
79
|
+
data-slot="input"
|
|
79
80
|
className={cn(
|
|
80
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",
|
|
81
82
|
className,
|
|
@@ -15,6 +15,7 @@ export interface CardProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
|
15
15
|
const Card = React.forwardRef<HTMLDivElement, CardProps>(({ className, ...props }, ref) => (
|
|
16
16
|
<div
|
|
17
17
|
ref={ref}
|
|
18
|
+
data-slot="card"
|
|
18
19
|
className={cn("rounded-xl border border-border bg-card text-card-foreground shadow", className)}
|
|
19
20
|
{...props}
|
|
20
21
|
/>
|
|
@@ -61,7 +61,7 @@ export function SectionCard({
|
|
|
61
61
|
</div>
|
|
62
62
|
{resolvedActions && <div className="flex items-center gap-2">{resolvedActions}</div>}
|
|
63
63
|
</CardHeader>
|
|
64
|
-
<div className="mx-5 mb-3.5 h-px bg-border" />
|
|
64
|
+
<div data-slot="card-divider" className="mx-5 mb-3.5 h-px bg-border" />
|
|
65
65
|
</>
|
|
66
66
|
)}
|
|
67
67
|
<CardContent className={cn(padding ? "px-5 pb-[18px] pt-0" : "p-0")}>
|
|
@@ -237,7 +237,7 @@ function DataTable<TData>({
|
|
|
237
237
|
</div>
|
|
238
238
|
)}
|
|
239
239
|
|
|
240
|
-
<div className="rounded-md border border-border">
|
|
240
|
+
<div data-slot="data-table" className="rounded-md border border-border">
|
|
241
241
|
<Table>
|
|
242
242
|
<TableHeader>
|
|
243
243
|
{table.getHeaderGroups().map((headerGroup) => (
|
|
@@ -60,6 +60,7 @@ const DrawerContent = React.forwardRef<
|
|
|
60
60
|
<DrawerOverlay />
|
|
61
61
|
<DrawerPrimitive.Content
|
|
62
62
|
ref={ref}
|
|
63
|
+
data-slot="drawer-content"
|
|
63
64
|
className={cn(
|
|
64
65
|
"fixed inset-x-0 bottom-0 z-50 mt-24 flex h-auto flex-col rounded-t-[10px] border border-border bg-background",
|
|
65
66
|
className,
|
|
@@ -209,6 +209,7 @@ const Sidebar = React.forwardRef<HTMLDivElement, SidebarProps>(
|
|
|
209
209
|
if (collapsible === "none") {
|
|
210
210
|
return (
|
|
211
211
|
<div
|
|
212
|
+
data-slot="sidebar"
|
|
212
213
|
className={cn(
|
|
213
214
|
"flex h-full w-[var(--sidebar-width)] flex-col bg-sidebar text-sidebar-foreground",
|
|
214
215
|
className,
|
|
@@ -281,6 +282,7 @@ const Sidebar = React.forwardRef<HTMLDivElement, SidebarProps>(
|
|
|
281
282
|
>
|
|
282
283
|
<div
|
|
283
284
|
data-sidebar="sidebar"
|
|
285
|
+
data-slot="sidebar"
|
|
284
286
|
className="flex h-full w-full flex-col bg-sidebar group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:border-sidebar-border group-data-[variant=floating]:shadow"
|
|
285
287
|
>
|
|
286
288
|
{children}
|
|
Binary file
|
package/styles/glass.css
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/* ---------- Glass surface mode ----------
|
|
2
|
+
*
|
|
3
|
+
* Activated by `html[data-surface="glass"]`. The conceit: an aurora-tinted
|
|
4
|
+
* backdrop shows through every chrome surface (sidebar, topbar, cards,
|
|
5
|
+
* tables) via `backdrop-filter: blur(...)`. Surfaces become tinted glass,
|
|
6
|
+
* with a low-alpha card color so the page palette bleeds through, plus a
|
|
7
|
+
* 1-px inner highlight on the top edge to suggest a refractive lip.
|
|
8
|
+
* Borders drop to white/black at low alpha so the layout reads as layered
|
|
9
|
+
* panes rather than rectangles drawn on flat paint.
|
|
10
|
+
*
|
|
11
|
+
* Two palettes:
|
|
12
|
+
* - Light: pastel peach + sky + lavender washes on near-white
|
|
13
|
+
* - Dark : deep indigo + violet + teal washes on near-black
|
|
14
|
+
*
|
|
15
|
+
* Surfaces opt in via `data-slot` attributes already present on Canvas
|
|
16
|
+
* components (`card`, `sidebar`, `data-table`, `input`, `popover-content`,
|
|
17
|
+
* `sheet-content`, `drawer-content`, `empty-state`, `code-block`). Consumer
|
|
18
|
+
* apps activate the mode by toggling the `data-surface` attribute on
|
|
19
|
+
* `<html>` (e.g. `document.documentElement.dataset.surface = "glass"`).
|
|
20
|
+
*
|
|
21
|
+
* Mirrors the Athena design handoff's `app.css` glass block; do not
|
|
22
|
+
* tighten these values without checking against the handoff bundle.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
@layer base {
|
|
26
|
+
html[data-surface="glass"] {
|
|
27
|
+
--glass-tint: 0 0% 100%; /* card tint base */
|
|
28
|
+
--glass-tint-alpha: 0.55;
|
|
29
|
+
--glass-border: 0 0% 100%;
|
|
30
|
+
--glass-border-alpha: 0.45;
|
|
31
|
+
--glass-highlight: 0 0% 100%;
|
|
32
|
+
--glass-highlight-alpha: 0.55;
|
|
33
|
+
--glass-shadow: 220 30% 20%;
|
|
34
|
+
--glass-blur: 18px;
|
|
35
|
+
--glass-saturate: 140%;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
html[data-surface="glass"].dark {
|
|
39
|
+
--glass-tint: 222 22% 18%;
|
|
40
|
+
--glass-tint-alpha: 0.55;
|
|
41
|
+
--glass-border: 0 0% 100%;
|
|
42
|
+
--glass-border-alpha: 0.1;
|
|
43
|
+
--glass-highlight: 0 0% 100%;
|
|
44
|
+
--glass-highlight-alpha: 0.1;
|
|
45
|
+
--glass-shadow: 222 60% 4%;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/* ──────────────────────────────────────────────────────────────
|
|
49
|
+
* Aurora backdrop — three soft radial washes anchored to body so
|
|
50
|
+
* they remain stable across route changes and ignore the inner
|
|
51
|
+
* shell's flat fill. The surfaces above are translucent so this
|
|
52
|
+
* is what users actually see "through" the glass.
|
|
53
|
+
* ──────────────────────────────────────────────────────────── */
|
|
54
|
+
html[data-surface="glass"] body {
|
|
55
|
+
background:
|
|
56
|
+
radial-gradient(60% 50% at 12% 10%, hsl(28 100% 80% / 0.55), transparent 60%),
|
|
57
|
+
radial-gradient(55% 55% at 88% 8%, hsl(210 100% 78% / 0.55), transparent 60%),
|
|
58
|
+
radial-gradient(70% 60% at 50% 100%, hsl(270 90% 82% / 0.45), transparent 65%),
|
|
59
|
+
hsl(220 30% 97%);
|
|
60
|
+
background-attachment: fixed;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
html[data-surface="glass"].dark body {
|
|
64
|
+
background:
|
|
65
|
+
radial-gradient(55% 50% at 10% 8%, hsl(245 90% 60% / 0.4), transparent 60%),
|
|
66
|
+
radial-gradient(50% 55% at 92% 12%, hsl(280 85% 55% / 0.35), transparent 60%),
|
|
67
|
+
radial-gradient(70% 60% at 50% 100%, hsl(190 90% 45% / 0.28), transparent 70%),
|
|
68
|
+
hsl(222 30% 6%);
|
|
69
|
+
background-attachment: fixed;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/* ──────────────────────────────────────────────────────────────
|
|
73
|
+
* Frosted-pane mixin. Same translucent fill, blur, and refractive
|
|
74
|
+
* highlight on every load-bearing surface so the whole layout
|
|
75
|
+
* reads as one stack of glass panes.
|
|
76
|
+
* ──────────────────────────────────────────────────────────── */
|
|
77
|
+
html[data-surface="glass"] [data-slot="card"],
|
|
78
|
+
html[data-surface="glass"] [data-slot="sidebar"],
|
|
79
|
+
html[data-surface="glass"] [data-slot="topbar"],
|
|
80
|
+
html[data-surface="glass"] [data-slot="data-table"],
|
|
81
|
+
html[data-surface="glass"] [data-slot="empty-state"],
|
|
82
|
+
html[data-surface="glass"] [data-slot="popover-content"],
|
|
83
|
+
html[data-surface="glass"] [data-slot="sheet-content"],
|
|
84
|
+
html[data-surface="glass"] [data-slot="drawer-content"] {
|
|
85
|
+
background: hsl(var(--glass-tint) / var(--glass-tint-alpha));
|
|
86
|
+
backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
|
|
87
|
+
-webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
|
|
88
|
+
border-color: hsl(var(--glass-border) / var(--glass-border-alpha));
|
|
89
|
+
box-shadow:
|
|
90
|
+
inset 0 1px 0 hsl(var(--glass-highlight) / var(--glass-highlight-alpha)),
|
|
91
|
+
0 1px 2px hsl(var(--glass-shadow) / 0.06),
|
|
92
|
+
0 8px 24px -12px hsl(var(--glass-shadow) / 0.18);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/* Sidebar and topbar take a slightly less-opaque tint so they
|
|
96
|
+
* read as chrome rather than content cards. */
|
|
97
|
+
html[data-surface="glass"] [data-slot="sidebar"],
|
|
98
|
+
html[data-surface="glass"] [data-slot="topbar"] {
|
|
99
|
+
background: hsl(var(--glass-tint) / calc(var(--glass-tint-alpha) - 0.1));
|
|
100
|
+
border-color: hsl(var(--glass-border) / var(--glass-border-alpha));
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/* DataTable internal rules — header tint, row separators, hover. */
|
|
104
|
+
html[data-surface="glass"] [data-slot="data-table"] thead tr {
|
|
105
|
+
background: hsl(var(--glass-highlight) / 0.1);
|
|
106
|
+
border-bottom: 1px solid hsl(var(--glass-border) / var(--glass-border-alpha));
|
|
107
|
+
}
|
|
108
|
+
html[data-surface="glass"] [data-slot="data-table"] tbody tr {
|
|
109
|
+
border-bottom: 1px solid hsl(var(--glass-border) / calc(var(--glass-border-alpha) - 0.2));
|
|
110
|
+
}
|
|
111
|
+
html[data-surface="glass"] [data-slot="data-table"] tbody tr:hover {
|
|
112
|
+
background: hsl(var(--glass-highlight) / 0.1);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/* SectionCard divider matches the border tone. */
|
|
116
|
+
html[data-surface="glass"] [data-slot="card"] [data-slot="card-divider"] {
|
|
117
|
+
background: hsl(var(--glass-border) / var(--glass-border-alpha));
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/* Inputs, kbd, codeblock — frosted to match. Less blur than full panes
|
|
121
|
+
* so dense form rows stay readable. */
|
|
122
|
+
html[data-surface="glass"] [data-slot="input"],
|
|
123
|
+
html[data-surface="glass"] [data-slot="code-block"] {
|
|
124
|
+
background: hsl(var(--glass-tint) / 0.35);
|
|
125
|
+
border-color: hsl(var(--glass-border) / var(--glass-border-alpha));
|
|
126
|
+
backdrop-filter: blur(8px);
|
|
127
|
+
-webkit-backdrop-filter: blur(8px);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/* Popovers/sheets/drawers — slightly more opaque so the content stays
|
|
131
|
+
* legible against the body aurora. */
|
|
132
|
+
html[data-surface="glass"] [data-slot="popover-content"],
|
|
133
|
+
html[data-surface="glass"] [data-slot="sheet-content"],
|
|
134
|
+
html[data-surface="glass"] [data-slot="drawer-content"] {
|
|
135
|
+
background: hsl(var(--glass-tint) / 0.85);
|
|
136
|
+
}
|
|
137
|
+
}
|
package/styles/tokens.css
CHANGED
|
@@ -12,9 +12,25 @@
|
|
|
12
12
|
* v4's `@theme inline { --color-sidebar: var(--sidebar) }` mapping so
|
|
13
13
|
* `bg-sidebar` / `text-sidebar-foreground` utilities resolve.
|
|
14
14
|
*
|
|
15
|
-
* Typography canonical:
|
|
15
|
+
* Typography canonical (per handoff): Roboto for surfaces with Inter as a
|
|
16
|
+
* fallback while a consumer migrates, JetBrains Mono for code. The Roboto
|
|
17
|
+
* variable font is self-hosted at ./fonts/Roboto-VariableFont_wdth_wght.ttf
|
|
18
|
+
* and ships with the package (covered by the `styles` files entry).
|
|
16
19
|
*/
|
|
17
20
|
|
|
21
|
+
/* Roboto variable font, self-hosted. Same axis range as the handoff
|
|
22
|
+
* (wght 100–900, wdth 75–100). JetBrains Mono is NOT loaded here:
|
|
23
|
+
* consumer apps own how they pull it in (e.g. Next.js `next/font/google`)
|
|
24
|
+
* so Canvas does not introduce an external @import dependency. */
|
|
25
|
+
@font-face {
|
|
26
|
+
font-family: "Roboto";
|
|
27
|
+
src: url("./fonts/Roboto-VariableFont_wdth_wght.ttf") format("truetype-variations");
|
|
28
|
+
font-weight: 100 900;
|
|
29
|
+
font-stretch: 75% 100%;
|
|
30
|
+
font-style: normal;
|
|
31
|
+
font-display: swap;
|
|
32
|
+
}
|
|
33
|
+
|
|
18
34
|
@layer base {
|
|
19
35
|
:root {
|
|
20
36
|
/* ── Base palette (light) ───────────────────────────────────
|
|
@@ -76,7 +92,7 @@
|
|
|
76
92
|
--stat-amber: 38 92% 50%; /* #f59e0b */
|
|
77
93
|
|
|
78
94
|
/* ── Typography ────────────────────────────────────────────── */
|
|
79
|
-
--font-sans: "Inter", system-ui, -apple-system, sans-serif;
|
|
95
|
+
--font-sans: "Roboto", "Inter", system-ui, -apple-system, sans-serif;
|
|
80
96
|
--font-mono: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
|
81
97
|
|
|
82
98
|
/* ── Letter-spacing scale ──────────────────────────────────── *
|