@olympusoss/canvas 2.16.0 → 2.18.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@olympusoss/canvas",
3
- "version": "2.16.0",
3
+ "version": "2.18.0",
4
4
  "type": "module",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -10,7 +10,7 @@ const buttonVariants = cva(
10
10
  variants: {
11
11
  variant: {
12
12
  default: "bg-primary text-primary-foreground shadow hover:bg-primary/90",
13
- destructive: "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
13
+ destructive: "bg-destructive text-destructive-foreground shadow hover:bg-destructive/90",
14
14
  outline:
15
15
  "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
16
16
  secondary: "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
@@ -40,7 +40,13 @@ export interface AlertProps
40
40
 
41
41
  const Alert = React.forwardRef<HTMLDivElement, AlertProps>(
42
42
  ({ className, variant, ...props }, ref) => (
43
- <div ref={ref} role="alert" className={cn(alertVariants({ variant }), className)} {...props} />
43
+ <div
44
+ ref={ref}
45
+ role="alert"
46
+ data-slot="alert"
47
+ className={cn(alertVariants({ variant }), className)}
48
+ {...props}
49
+ />
44
50
  ),
45
51
  );
46
52
  Alert.displayName = "Alert";
@@ -44,6 +44,7 @@ function Calendar({
44
44
  return (
45
45
  <DayPicker
46
46
  showOutsideDays={showOutsideDays}
47
+ data-slot="calendar"
47
48
  className={cn(
48
49
  "bg-background group/calendar p-4 [--cell-size:2rem] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent",
49
50
  String.raw`rtl:**:[.rdp-button\_next>svg]:rotate-180`,
@@ -23,6 +23,7 @@ const Terminal = React.forwardRef<HTMLDivElement, TerminalProps>(
23
23
  ({ title, children, className, ...props }, ref) => (
24
24
  <div
25
25
  ref={ref}
26
+ data-slot="terminal"
26
27
  className={cn(
27
28
  "overflow-hidden rounded-xl border border-border shadow-[0_30px_60px_-20px_rgb(0_0_0/0.35)]",
28
29
  className,
@@ -136,6 +136,7 @@ const TooltipContent = React.forwardRef<
136
136
  <TooltipPrimitive.Portal container={container ?? undefined}>
137
137
  <TooltipPrimitive.Content
138
138
  ref={ref}
139
+ data-slot="tooltip-content"
139
140
  sideOffset={sideOffset}
140
141
  className={cn(
141
142
  "z-50 max-w-xs overflow-hidden rounded-md border border-border/50 bg-popover px-2 py-1 text-[11px] font-medium text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-1 data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1 data-[side=top]:slide-in-from-bottom-1 origin-[var(--radix-tooltip-content-transform-origin)]",
@@ -79,7 +79,12 @@ const AccordionItem = React.forwardRef<
79
79
  React.ElementRef<typeof AccordionPrimitive.Item>,
80
80
  AccordionItemProps
81
81
  >(({ className, ...props }, ref) => (
82
- <AccordionPrimitive.Item ref={ref} className={cn("border-b", className)} {...props} />
82
+ <AccordionPrimitive.Item
83
+ ref={ref}
84
+ data-slot="accordion-item"
85
+ className={cn("border-b", className)}
86
+ {...props}
87
+ />
83
88
  ));
84
89
  AccordionItem.displayName = "AccordionItem";
85
90
 
@@ -123,6 +123,7 @@ const AlertDialogContent = React.forwardRef<
123
123
  <AlertDialogOverlay />
124
124
  <AlertDialogPrimitive.Content
125
125
  ref={ref}
126
+ data-slot="alert-dialog-content"
126
127
  className={cn(
127
128
  "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border border-border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%]",
128
129
  className,
@@ -14,6 +14,7 @@ const Command = React.forwardRef<
14
14
  >(({ className, ...props }, ref) => (
15
15
  <CommandPrimitive
16
16
  ref={ref}
17
+ data-slot="command"
17
18
  className={cn(
18
19
  "flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground",
19
20
  className,
@@ -127,6 +127,7 @@ const ContextMenuSubContent = React.forwardRef<
127
127
  >(({ className, ...props }, ref) => (
128
128
  <ContextMenuPrimitive.SubContent
129
129
  ref={ref}
130
+ data-slot="context-menu-sub-content"
130
131
  className={cn(
131
132
  "z-50 min-w-[8rem] overflow-hidden rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[var(--radix-context-menu-content-transform-origin)]",
132
133
  className,
@@ -161,6 +162,7 @@ const ContextMenuContent = React.forwardRef<
161
162
  <ContextMenuPrimitive.Portal container={container ?? undefined}>
162
163
  <ContextMenuPrimitive.Content
163
164
  ref={ref}
165
+ data-slot="context-menu-content"
164
166
  className={cn(
165
167
  "z-50 max-h-[var(--radix-context-menu-content-available-height)] min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[var(--radix-context-menu-content-transform-origin)]",
166
168
  className,
@@ -191,6 +191,7 @@ const DialogContent = React.forwardRef<
191
191
  <DialogOverlay />
192
192
  <DialogPrimitive.Content
193
193
  ref={ref}
194
+ data-slot="dialog-content"
194
195
  className={cn(
195
196
  "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border border-border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%]",
196
197
  className,
@@ -163,6 +163,7 @@ const DropdownMenuSubContent = React.forwardRef<
163
163
  >(({ className, ...props }, ref) => (
164
164
  <DropdownMenuPrimitive.SubContent
165
165
  ref={ref}
166
+ data-slot="dropdown-menu-sub-content"
166
167
  className={cn(
167
168
  "z-50 min-w-[8rem] overflow-hidden rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[var(--radix-dropdown-menu-content-transform-origin)]",
168
169
  className,
@@ -227,6 +228,7 @@ const DropdownMenuContent = React.forwardRef<
227
228
  <DropdownMenuPrimitive.Portal container={container ?? undefined}>
228
229
  <DropdownMenuPrimitive.Content
229
230
  ref={ref}
231
+ data-slot="dropdown-menu-content"
230
232
  sideOffset={sideOffset}
231
233
  className={cn(
232
234
  "z-50 max-h-[var(--radix-dropdown-menu-content-available-height)] min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md",
@@ -100,6 +100,7 @@ const HoverCardContent = React.forwardRef<
100
100
  >(({ className, align = "center", sideOffset = 4, ...props }, ref) => (
101
101
  <HoverCardPrimitive.Content
102
102
  ref={ref}
103
+ data-slot="hover-card-content"
103
104
  align={align}
104
105
  sideOffset={sideOffset}
105
106
  className={cn(
@@ -33,6 +33,7 @@ const Menubar = React.forwardRef<React.ElementRef<typeof MenubarPrimitive.Root>,
33
33
  ({ className, ...props }, ref) => (
34
34
  <MenubarPrimitive.Root
35
35
  ref={ref}
36
+ data-slot="menubar"
36
37
  className={cn(
37
38
  "flex h-9 items-center space-x-1 rounded-md border border-border bg-background p-1 shadow-sm",
38
39
  className,
@@ -216,6 +217,7 @@ const MenubarSubContent = React.forwardRef<
216
217
  >(({ className, ...props }, ref) => (
217
218
  <MenubarPrimitive.SubContent
218
219
  ref={ref}
220
+ data-slot="menubar-sub-content"
219
221
  className={cn(
220
222
  "z-50 min-w-[8rem] overflow-hidden rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[var(--radix-menubar-content-transform-origin)]",
221
223
  className,
@@ -279,6 +281,7 @@ const MenubarContent = React.forwardRef<
279
281
  <MenubarPrimitive.Portal container={container ?? undefined}>
280
282
  <MenubarPrimitive.Content
281
283
  ref={ref}
284
+ data-slot="menubar-content"
282
285
  align={align}
283
286
  alignOffset={alignOffset}
284
287
  sideOffset={sideOffset}
@@ -185,6 +185,7 @@ const NavigationMenuViewport = React.forwardRef<
185
185
  >(({ className, ...props }, ref) => (
186
186
  <div className={cn("absolute left-0 top-full flex justify-center")}>
187
187
  <NavigationMenuPrimitive.Viewport
188
+ data-slot="navigation-menu-viewport"
188
189
  className={cn(
189
190
  "origin-top-center relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded-md border border-border bg-popover text-popover-foreground shadow data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90 md:w-[var(--radix-navigation-menu-viewport-width)]",
190
191
  className,
@@ -187,6 +187,7 @@ const SelectContent = React.forwardRef<
187
187
  <SelectPrimitive.Portal container={container ?? undefined}>
188
188
  <SelectPrimitive.Content
189
189
  ref={ref}
190
+ data-slot="select-content"
190
191
  className={cn(
191
192
  "relative z-50 max-h-[var(--radix-select-content-available-height)] min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-md border border-border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[var(--radix-select-content-transform-origin)]",
192
193
  position === "popper" &&
@@ -53,6 +53,7 @@ const TabsList = React.forwardRef<React.ElementRef<typeof TabsPrimitive.List>, T
53
53
  ({ className, ...props }, ref) => (
54
54
  <TabsPrimitive.List
55
55
  ref={ref}
56
+ data-slot="tabs-list"
56
57
  className={cn(
57
58
  "inline-flex h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground",
58
59
  className,
package/styles/glass.css CHANGED
@@ -72,7 +72,9 @@
72
72
  /* ──────────────────────────────────────────────────────────────
73
73
  * Frosted-pane mixin. Same translucent fill, blur, and refractive
74
74
  * highlight on every load-bearing surface so the whole layout
75
- * reads as one stack of glass panes.
75
+ * reads as one stack of glass panes. Includes cards, chrome,
76
+ * dialogs, dropdown panels, popovers, tooltips, alerts, calendar,
77
+ * terminal, menubar, navigation-menu, tabs list.
76
78
  * ──────────────────────────────────────────────────────────── */
77
79
  html[data-surface="glass"] [data-slot="card"],
78
80
  html[data-surface="glass"] [data-slot="sidebar"],
@@ -81,7 +83,24 @@
81
83
  html[data-surface="glass"] [data-slot="empty-state"],
82
84
  html[data-surface="glass"] [data-slot="popover-content"],
83
85
  html[data-surface="glass"] [data-slot="sheet-content"],
84
- html[data-surface="glass"] [data-slot="drawer-content"] {
86
+ html[data-surface="glass"] [data-slot="drawer-content"],
87
+ html[data-surface="glass"] [data-slot="alert"],
88
+ html[data-surface="glass"] [data-slot="alert-dialog-content"],
89
+ html[data-surface="glass"] [data-slot="dialog-content"],
90
+ html[data-surface="glass"] [data-slot="dropdown-menu-content"],
91
+ html[data-surface="glass"] [data-slot="dropdown-menu-sub-content"],
92
+ html[data-surface="glass"] [data-slot="context-menu-content"],
93
+ html[data-surface="glass"] [data-slot="context-menu-sub-content"],
94
+ html[data-surface="glass"] [data-slot="hover-card-content"],
95
+ html[data-surface="glass"] [data-slot="select-content"],
96
+ html[data-surface="glass"] [data-slot="menubar"],
97
+ html[data-surface="glass"] [data-slot="menubar-content"],
98
+ html[data-surface="glass"] [data-slot="menubar-sub-content"],
99
+ html[data-surface="glass"] [data-slot="navigation-menu-viewport"],
100
+ html[data-surface="glass"] [data-slot="tooltip-content"],
101
+ html[data-surface="glass"] [data-slot="command"],
102
+ html[data-surface="glass"] [data-slot="calendar"],
103
+ html[data-surface="glass"] [data-slot="terminal"] {
85
104
  background: hsl(var(--glass-tint) / var(--glass-tint-alpha));
86
105
  backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
87
106
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
@@ -117,21 +136,42 @@
117
136
  background: hsl(var(--glass-border) / var(--glass-border-alpha));
118
137
  }
119
138
 
120
- /* Inputs, kbd, codeblock — frosted to match. Less blur than full panes
121
- * so dense form rows stay readable. */
139
+ /* Inputs, kbd, codeblock, tabs list — frosted to match. Less blur
140
+ * than full panes so dense form rows stay readable. */
122
141
  html[data-surface="glass"] [data-slot="input"],
123
- html[data-surface="glass"] [data-slot="code-block"] {
142
+ html[data-surface="glass"] [data-slot="code-block"],
143
+ html[data-surface="glass"] [data-slot="tabs-list"] {
124
144
  background: hsl(var(--glass-tint) / 0.35);
125
145
  border-color: hsl(var(--glass-border) / var(--glass-border-alpha));
126
146
  backdrop-filter: blur(8px);
127
147
  -webkit-backdrop-filter: blur(8px);
128
148
  }
129
149
 
130
- /* Popovers/sheets/drawersslightly more opaque so the content stays
131
- * legible against the body aurora. */
150
+ /* Accordion items use only a bottom border re-tint that border so it
151
+ * tracks the glass palette instead of the solid border token. */
152
+ html[data-surface="glass"] [data-slot="accordion-item"] {
153
+ border-bottom-color: hsl(var(--glass-border) / var(--glass-border-alpha));
154
+ }
155
+
156
+ /* Popovers / sheets / drawers / dialog-like panels — slightly more
157
+ * opaque so the content stays legible against the body aurora.
158
+ * Overrides the base translucent fill from the frosted-pane block. */
132
159
  html[data-surface="glass"] [data-slot="popover-content"],
133
160
  html[data-surface="glass"] [data-slot="sheet-content"],
134
- html[data-surface="glass"] [data-slot="drawer-content"] {
161
+ html[data-surface="glass"] [data-slot="drawer-content"],
162
+ html[data-surface="glass"] [data-slot="alert-dialog-content"],
163
+ html[data-surface="glass"] [data-slot="dialog-content"],
164
+ html[data-surface="glass"] [data-slot="dropdown-menu-content"],
165
+ html[data-surface="glass"] [data-slot="dropdown-menu-sub-content"],
166
+ html[data-surface="glass"] [data-slot="context-menu-content"],
167
+ html[data-surface="glass"] [data-slot="context-menu-sub-content"],
168
+ html[data-surface="glass"] [data-slot="hover-card-content"],
169
+ html[data-surface="glass"] [data-slot="select-content"],
170
+ html[data-surface="glass"] [data-slot="menubar-content"],
171
+ html[data-surface="glass"] [data-slot="menubar-sub-content"],
172
+ html[data-surface="glass"] [data-slot="navigation-menu-viewport"],
173
+ html[data-surface="glass"] [data-slot="tooltip-content"],
174
+ html[data-surface="glass"] [data-slot="command"] {
135
175
  background: hsl(var(--glass-tint) / 0.85);
136
176
  }
137
177
  }
package/styles/tokens.css CHANGED
@@ -259,6 +259,32 @@
259
259
  --color-stat-purple: hsl(var(--stat-purple));
260
260
  --color-stat-destructive: hsl(var(--stat-destructive));
261
261
  --color-stat-amber: hsl(var(--stat-amber));
262
+
263
+ /* ── Shadow scale (per handoff canvas.css) ──────────────────
264
+ * Two base tones, both single-layer at the small end:
265
+ * - `2xs` / `xs` / `sm`: 0 1px 2px / 5% — inputs, outline /
266
+ * secondary buttons (matches handoff `.input` and
267
+ * `.btn-outline` / `.btn-secondary`).
268
+ * - DEFAULT (`shadow`): 0 1px 3px / 8% — cards and primary /
269
+ * destructive buttons (matches handoff `.card`,
270
+ * `.btn-default`, `.btn-destructive`).
271
+ * - `md` / `lg` / `xl`: two-layer stacks softened to 8% / 6%
272
+ * opacity so popovers, dialogs, and drawers sit on the same
273
+ * depth ramp as cards instead of feeling heavier (Tailwind
274
+ * defaults use 10%).
275
+ * - `inner`: keeps Tailwind default (no handoff override).
276
+ *
277
+ * Overriding the @theme tokens propagates through every Canvas
278
+ * component class (`shadow-sm`, `shadow-md`, etc.) without
279
+ * touching component sources.
280
+ */
281
+ --shadow-2xs: 0 1px 2px 0 rgb(0 0 0 / 0.05);
282
+ --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.05);
283
+ --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
284
+ --shadow: 0 1px 3px 0 rgb(0 0 0 / 0.08);
285
+ --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.08), 0 2px 4px -2px rgb(0 0 0 / 0.06);
286
+ --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.08), 0 4px 6px -4px rgb(0 0 0 / 0.06);
287
+ --shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.08), 0 8px 10px -6px rgb(0 0 0 / 0.06);
262
288
  }
263
289
 
264
290
  @keyframes orb-float-1 {