@signal9/era-ui 31.0.0 → 32.0.1
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/CHANGELOG.md +20 -0
- package/dist/ai/artifact/artifact.svelte +1 -1
- package/dist/ai/web-preview/web-preview.svelte +1 -1
- package/dist/ai/workflow/node.svelte +1 -1
- package/dist/docs/css-utilities.js +2 -2
- package/dist/era-ui.css +1 -1
- package/dist/generated-docs/llms-full.txt +61 -22
- package/dist/generated-docs/llms.txt +4 -1
- package/dist/generated-docs/manifest.json +41 -8
- package/dist/generated-docs/utilities.json +36 -6
- package/dist/generated-docs/utilities.md +57 -21
- package/dist/os/notification-center.svelte +1 -1
- package/dist/os/pane.svelte +3 -13
- package/dist/os/taskbar.svelte +1 -1
- package/dist/os/toast.svelte +1 -1
- package/dist/styles/index.css +42 -21
- package/dist/styles/motion.css +1 -1
- package/dist/styles/prose.css +1 -1
- package/dist/styles/surfaces/bevel.css +16 -19
- package/dist/styles/surfaces/contract.css +50 -0
- package/dist/styles/surfaces/flat.css +27 -0
- package/dist/styles/surfaces/glass.css +11 -8
- package/dist/ui/alert-dialog/alert-dialog-content.svelte +1 -1
- package/dist/ui/button/button.svelte +1 -0
- package/dist/ui/button/variants.d.ts +3 -3
- package/dist/ui/button/variants.js +3 -3
- package/dist/ui/card/card.svelte +4 -4
- package/dist/ui/card/card.svelte.d.ts +3 -3
- package/dist/ui/combobox/combobox-content.svelte +1 -1
- package/dist/ui/command/command-root.svelte +3 -3
- package/dist/ui/command-bar/command-bar.svelte +3 -3
- package/dist/ui/context-menu/context-menu-content.svelte +1 -4
- package/dist/ui/context-menu/context-menu-sub-content.svelte +1 -4
- package/dist/ui/date-picker/date-picker-content.svelte +1 -1
- package/dist/ui/date-range-picker/date-range-picker-content.svelte +1 -1
- package/dist/ui/dialog/dialog-content.svelte +1 -1
- package/dist/ui/dialog/dialog-header.svelte +1 -1
- package/dist/ui/dropdown-menu/dropdown-menu-content.svelte +1 -1
- package/dist/ui/dropdown-menu/dropdown-menu-sub-content.svelte +1 -4
- package/dist/ui/link-preview/link-preview-content.svelte +1 -1
- package/dist/ui/menubar/menubar-content.svelte +1 -1
- package/dist/ui/menubar/menubar-sub-content.svelte +1 -4
- package/dist/ui/meter/meter.svelte +1 -2
- package/dist/ui/nav/nav-item.svelte +1 -0
- package/dist/ui/pane/pane-close.svelte +7 -26
- package/dist/ui/pane/pane-root.svelte +1 -1
- package/dist/ui/popover/popover-content.svelte +1 -1
- package/dist/ui/provider/surfaces.d.ts +1 -1
- package/dist/ui/provider/surfaces.js +1 -1
- package/dist/ui/select/select-content.svelte +1 -1
- package/dist/ui/sheet/sheet-content.svelte +1 -1
- package/dist/ui/sheet/sheet-content.svelte.d.ts +1 -1
- package/dist/ui/switch/switch.svelte +1 -1
- package/dist/ui/toggle-group/toggle-group-item.svelte +1 -1
- package/dist/ui/toggle-group/toggle-group-item.svelte.d.ts +3 -3
- package/dist/ui/tooltip/tooltip-content.svelte +1 -1
- package/dist/ui/video-player/video-player.svelte +2 -2
- package/dist/utils/tw-merge-config.d.ts +3 -1
- package/dist/utils/tw-merge-config.js +2 -2
- package/package.json +2 -1
- package/skill/SKILL.md +9 -4
- package/dist/styles/surfaces/base.css +0 -257
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Era UI — material contract
|
|
3
|
+
*
|
|
4
|
+
* Components choose a MATERIAL ROLE; surface implementations provide values.
|
|
5
|
+
* This file contains only relationships shared by every implementation and the
|
|
6
|
+
* global consumers of those values. It deliberately contains no flat, glass,
|
|
7
|
+
* or bevel palette and no component selector.
|
|
8
|
+
*
|
|
9
|
+
* Required primitives (enforced by check:surfaces):
|
|
10
|
+
* paint --era-surface-bg, --era-surface-bg-elevated, --era-field-bg
|
|
11
|
+
* relief --era-shadow, --era-shadow-lg
|
|
12
|
+
* interaction --era-highlight, --era-fill, full/compact press travel
|
|
13
|
+
* frame --era-divider-color, --era-panel-inset, --era-backdrop-filter
|
|
14
|
+
* environment --era-border-color, --era-overlay-bg
|
|
15
|
+
* selection --era-selection-bg/fg/shadow
|
|
16
|
+
*
|
|
17
|
+
* Derived values remain live var() expressions so a nested surface re-resolves
|
|
18
|
+
* them from its own primitives. A surface overrides a derived value only when
|
|
19
|
+
* its material genuinely needs a different treatment.
|
|
20
|
+
*/
|
|
21
|
+
:root,
|
|
22
|
+
[data-surface] {
|
|
23
|
+
--era-divider-faded: color-mix(in oklch, var(--era-divider-color) 40%, transparent);
|
|
24
|
+
--era-field-highlight: color-mix(in oklch, var(--era-field-bg) 96%, var(--color-bright));
|
|
25
|
+
--era-shadow-well: var(--era-shadow);
|
|
26
|
+
--era-shadow-pressed: var(--era-shadow);
|
|
27
|
+
--era-highlight-shadow: var(--era-shadow);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/* Radius re-derives per element because density/corners may change without a
|
|
31
|
+
* new surface boundary. No surface-specific derived shadow belongs here. */
|
|
32
|
+
* {
|
|
33
|
+
--era-item-rd: max(0px, calc(var(--era-rd-control) - var(--era-panel-inset)));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
::selection {
|
|
37
|
+
background-color: var(--era-selection-bg);
|
|
38
|
+
color: var(--era-selection-fg);
|
|
39
|
+
text-shadow: var(--era-selection-shadow);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* Translucent materials become opaque without changing component markup. */
|
|
43
|
+
@media (prefers-reduced-transparency: reduce) {
|
|
44
|
+
:root,
|
|
45
|
+
[data-surface] {
|
|
46
|
+
--era-highlight: var(--color-hover);
|
|
47
|
+
--era-fill: var(--color-hover);
|
|
48
|
+
--era-backdrop-filter: none;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/* Flat — solid tone steps with no relief chrome. */
|
|
2
|
+
:root,
|
|
3
|
+
[data-surface='flat'] {
|
|
4
|
+
--era-border-color: transparent;
|
|
5
|
+
--era-divider-color: var(--color-border);
|
|
6
|
+
--era-surface-bg: var(--color-2);
|
|
7
|
+
/* A symmetric tone step separates floating content without drawing an edge. */
|
|
8
|
+
--era-surface-bg-elevated: color-mix(in oklch, var(--era-surface-bg) 94%, var(--color-bright));
|
|
9
|
+
--era-field-bg: var(--color-hover);
|
|
10
|
+
--era-shadow: none;
|
|
11
|
+
--era-shadow-lg: none;
|
|
12
|
+
--era-highlight: light-dark(
|
|
13
|
+
color-mix(in oklch, var(--color-bright) 9%, transparent),
|
|
14
|
+
color-mix(in oklch, var(--color-bright) 8%, transparent)
|
|
15
|
+
);
|
|
16
|
+
--era-fill: var(--era-highlight);
|
|
17
|
+
--era-press-sink-x: 0px;
|
|
18
|
+
--era-press-sink-y: 0px;
|
|
19
|
+
--era-press-sink-compact-x: 0px;
|
|
20
|
+
--era-press-sink-compact-y: 0px;
|
|
21
|
+
--era-panel-inset: 0px;
|
|
22
|
+
--era-overlay-bg: color-mix(in oklch, var(--color-1) 60%, transparent);
|
|
23
|
+
--era-backdrop-filter: none;
|
|
24
|
+
--era-selection-bg: var(--color-bright);
|
|
25
|
+
--era-selection-fg: var(--color-1);
|
|
26
|
+
--era-selection-shadow: none;
|
|
27
|
+
}
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
* treatment (macOS-style) so row highlights never touch the rim or arcs.
|
|
17
17
|
*/
|
|
18
18
|
[data-surface='glass'] {
|
|
19
|
+
--era-border-color: transparent;
|
|
19
20
|
--era-divider-color: light-dark(
|
|
20
21
|
color-mix(in oklch, var(--color-bright) 12%, transparent),
|
|
21
22
|
color-mix(in oklch, var(--color-bright) 8%, transparent)
|
|
@@ -33,13 +34,13 @@
|
|
|
33
34
|
color-mix(in oklch, var(--color-3) 85%, transparent)
|
|
34
35
|
);
|
|
35
36
|
|
|
36
|
-
/* The same tone the
|
|
37
|
+
/* The same tone the flat implementation defines, held at 72% so the frost still reads
|
|
37
38
|
* through it — the material is the point. Restated rather than inherited
|
|
38
39
|
* because a surface cannot reference the token it is overriding.
|
|
39
40
|
* Light mode is why a field needs its own value here at all: at the panel's
|
|
40
41
|
* own opacity it measured 1.00:1 against its backdrop, i.e. exactly nothing.
|
|
41
42
|
*
|
|
42
|
-
* --era-field-highlight is NOT restated: the
|
|
43
|
+
* --era-field-highlight is NOT restated: the contract derives it against
|
|
43
44
|
* --era-field-bg, so it picks this value up and stays translucent. */
|
|
44
45
|
--era-field-bg: color-mix(in oklch, var(--color-hover) 72%, transparent);
|
|
45
46
|
|
|
@@ -89,6 +90,10 @@
|
|
|
89
90
|
* surface invented). Its highlight was always a wash, so pills inside lit
|
|
90
91
|
* containers were never at risk here. */
|
|
91
92
|
--era-fill: var(--color-hover);
|
|
93
|
+
--era-press-sink-x: 0px;
|
|
94
|
+
--era-press-sink-y: 0px;
|
|
95
|
+
--era-press-sink-compact-x: 0px;
|
|
96
|
+
--era-press-sink-compact-y: 0px;
|
|
92
97
|
--era-highlight-shadow:
|
|
93
98
|
inset 1.5px 1.5px 0 -1px
|
|
94
99
|
light-dark(
|
|
@@ -127,10 +132,9 @@
|
|
|
127
132
|
);
|
|
128
133
|
|
|
129
134
|
--era-panel-inset: 2px;
|
|
130
|
-
--era-
|
|
131
|
-
/* Blur alone reads muddy/gray; saturation restores the backdrop's color
|
|
132
|
-
|
|
133
|
-
--era-saturate: 180%;
|
|
135
|
+
--era-overlay-bg: color-mix(in oklch, var(--color-1) 60%, transparent);
|
|
136
|
+
/* Blur alone reads muddy/gray; saturation restores the backdrop's color. */
|
|
137
|
+
--era-backdrop-filter: blur(20px) saturate(180%);
|
|
134
138
|
}
|
|
135
139
|
|
|
136
140
|
/* Accessibility — honor reduced-transparency: solid fills, no filter,
|
|
@@ -139,8 +143,7 @@
|
|
|
139
143
|
[data-surface='glass'] {
|
|
140
144
|
--era-surface-bg: var(--color-2);
|
|
141
145
|
--era-surface-bg-elevated: var(--color-3);
|
|
142
|
-
--era-
|
|
143
|
-
--era-saturate: 100%;
|
|
146
|
+
--era-backdrop-filter: none;
|
|
144
147
|
/* The field goes solid with everything else — it was left translucent
|
|
145
148
|
* here, so a field kept frosting over its backdrop on the one setting
|
|
146
149
|
* that asks for no frost. */
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
bind:ref
|
|
33
33
|
{...relay?.attrs}
|
|
34
34
|
class={cn(
|
|
35
|
-
'fixed top-1/2 left-1/2 z-overlay flex max-h-[85dvh] w-full max-w-md -translate-x-1/2 -translate-y-1/2 flex-col gap-gutter overflow-y-auto rounded-bar
|
|
35
|
+
'fixed top-1/2 left-1/2 z-overlay flex max-h-[85dvh] w-full max-w-md -translate-x-1/2 -translate-y-1/2 flex-col gap-gutter overflow-y-auto rounded-bar material-panel p-card',
|
|
36
36
|
className
|
|
37
37
|
)}
|
|
38
38
|
{...restProps}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export declare const buttonVariants: import("tailwind-variants").TVReturnType<{
|
|
2
2
|
variant: {
|
|
3
|
-
filled: "flex justify-center shadow-sm hover:shadow-highlight
|
|
3
|
+
filled: "pressable flex justify-center shadow-sm hover:shadow-highlight";
|
|
4
4
|
link: "inline era-link [line-height:inherit]";
|
|
5
5
|
};
|
|
6
6
|
tone: {
|
|
@@ -25,7 +25,7 @@ export declare const buttonVariants: import("tailwind-variants").TVReturnType<{
|
|
|
25
25
|
};
|
|
26
26
|
}, undefined, "items-center gap-gutter text-body era-interactive leading-none", {
|
|
27
27
|
variant: {
|
|
28
|
-
filled: "flex justify-center shadow-sm hover:shadow-highlight
|
|
28
|
+
filled: "pressable flex justify-center shadow-sm hover:shadow-highlight";
|
|
29
29
|
link: "inline era-link [line-height:inherit]";
|
|
30
30
|
};
|
|
31
31
|
tone: {
|
|
@@ -50,7 +50,7 @@ export declare const buttonVariants: import("tailwind-variants").TVReturnType<{
|
|
|
50
50
|
};
|
|
51
51
|
}, undefined, import("tailwind-variants").TVReturnTypeLike<{
|
|
52
52
|
variant: {
|
|
53
|
-
filled: "flex justify-center shadow-sm hover:shadow-highlight
|
|
53
|
+
filled: "pressable flex justify-center shadow-sm hover:shadow-highlight";
|
|
54
54
|
link: "inline era-link [line-height:inherit]";
|
|
55
55
|
};
|
|
56
56
|
tone: {
|
|
@@ -9,10 +9,10 @@ export const buttonVariants = tv({
|
|
|
9
9
|
// The active: press treatment is inert outside the bevel surface —
|
|
10
10
|
// flat/glass define --era-shadow-pressed as the resting shadow and 0px
|
|
11
11
|
// sinks. Bevel inverts the chisel and sinks the CONTENT straight down
|
|
12
|
-
// (
|
|
12
|
+
// (`pressable` targets the one content-wrapper span from
|
|
13
13
|
// button.svelte) so the icon AND label depress together like a keycap
|
|
14
14
|
// while the frame holds still.
|
|
15
|
-
filled: 'flex justify-center shadow-sm hover:shadow-highlight
|
|
15
|
+
filled: 'pressable flex justify-center shadow-sm hover:shadow-highlight',
|
|
16
16
|
// THE LINK VARIANT IS era-link, not a second implementation of it.
|
|
17
17
|
// It used to hand-roll `underline-offset-2 hover:underline`, which is a
|
|
18
18
|
// different link from the one `era-link` defines for prose: no underline
|
|
@@ -55,7 +55,7 @@ export const buttonVariants = tv({
|
|
|
55
55
|
{
|
|
56
56
|
variant: 'filled',
|
|
57
57
|
size: 'icon',
|
|
58
|
-
class: 'min-w-icon tier-icon'
|
|
58
|
+
class: 'min-w-icon tier-icon [--era-press-effective-x:var(--era-press-sink-compact-x)] [--era-press-effective-y:var(--era-press-sink-compact-y)]'
|
|
59
59
|
},
|
|
60
60
|
// filled insets; icon buttons go square instead. When an icon is present,
|
|
61
61
|
// gap widens to match the wall inset so the icon sits in rhythm with it.
|
package/dist/ui/card/card.svelte
CHANGED
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
// was: the even-gap law, broken by default, in the component that
|
|
33
33
|
// bounds more consumer content than any other.
|
|
34
34
|
sectioned: { true: 'p-0', false: 'p-card' },
|
|
35
|
-
// A CARD YOU CAN PRESS DEPRESSES.
|
|
35
|
+
// A CARD YOU CAN PRESS DEPRESSES. The pressed material is on every
|
|
36
36
|
// other era control and was missing here, so a pressable card was the
|
|
37
37
|
// one thing in the library that lit up on hover and then did nothing
|
|
38
38
|
// under the finger — on bevel, where the pressed face is an inverted
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
// consumer children separately would pull a card's sections apart, while no
|
|
44
44
|
// wrapper leaves the frame depressed around stationary ink.
|
|
45
45
|
interactive: {
|
|
46
|
-
true: 'cursor-pointer hover:bg-highlight hover:shadow-highlight focus-visible:bg-highlight
|
|
46
|
+
true: 'pressable cursor-pointer hover:bg-highlight hover:shadow-highlight focus-visible:bg-highlight era-interactive aria-disabled:cursor-not-allowed aria-disabled:opacity-50'
|
|
47
47
|
}
|
|
48
48
|
},
|
|
49
49
|
defaultVariants: { tone: 'elevated', sectioned: false, interactive: false }
|
|
@@ -191,7 +191,7 @@
|
|
|
191
191
|
class={cn(cardVariants({ tone, sectioned, interactive: true }), className)}
|
|
192
192
|
{...restProps}
|
|
193
193
|
>
|
|
194
|
-
<div data-card-content>{@render body()}</div>
|
|
194
|
+
<div data-card-content data-era-press-content>{@render body()}</div>
|
|
195
195
|
</a>
|
|
196
196
|
<!-- eslint-enable svelte/no-navigation-without-resolve -->
|
|
197
197
|
{:else if onclick != null}
|
|
@@ -211,7 +211,7 @@
|
|
|
211
211
|
class={cn(cardVariants({ tone, sectioned, interactive: true }), className)}
|
|
212
212
|
{...restProps}
|
|
213
213
|
>
|
|
214
|
-
<div data-card-content>{@render body()}</div>
|
|
214
|
+
<div data-card-content data-era-press-content>{@render body()}</div>
|
|
215
215
|
</button>
|
|
216
216
|
{:else}
|
|
217
217
|
<div
|
|
@@ -10,7 +10,7 @@ export declare const cardVariants: import("tailwind-variants").TVReturnType<{
|
|
|
10
10
|
false: "p-card";
|
|
11
11
|
};
|
|
12
12
|
interactive: {
|
|
13
|
-
true: "cursor-pointer hover:bg-highlight hover:shadow-highlight focus-visible:bg-highlight
|
|
13
|
+
true: "pressable cursor-pointer hover:bg-highlight hover:shadow-highlight focus-visible:bg-highlight era-interactive aria-disabled:cursor-not-allowed aria-disabled:opacity-50";
|
|
14
14
|
};
|
|
15
15
|
}, undefined, "block w-full rounded-bar text-left text-fg", {
|
|
16
16
|
tone: {
|
|
@@ -24,7 +24,7 @@ export declare const cardVariants: import("tailwind-variants").TVReturnType<{
|
|
|
24
24
|
false: "p-card";
|
|
25
25
|
};
|
|
26
26
|
interactive: {
|
|
27
|
-
true: "cursor-pointer hover:bg-highlight hover:shadow-highlight focus-visible:bg-highlight
|
|
27
|
+
true: "pressable cursor-pointer hover:bg-highlight hover:shadow-highlight focus-visible:bg-highlight era-interactive aria-disabled:cursor-not-allowed aria-disabled:opacity-50";
|
|
28
28
|
};
|
|
29
29
|
}, undefined, import("tailwind-variants").TVReturnTypeLike<{
|
|
30
30
|
tone: {
|
|
@@ -38,7 +38,7 @@ export declare const cardVariants: import("tailwind-variants").TVReturnType<{
|
|
|
38
38
|
false: "p-card";
|
|
39
39
|
};
|
|
40
40
|
interactive: {
|
|
41
|
-
true: "cursor-pointer hover:bg-highlight hover:shadow-highlight focus-visible:bg-highlight
|
|
41
|
+
true: "pressable cursor-pointer hover:bg-highlight hover:shadow-highlight focus-visible:bg-highlight era-interactive aria-disabled:cursor-not-allowed aria-disabled:opacity-50";
|
|
42
42
|
};
|
|
43
43
|
}, undefined>>;
|
|
44
44
|
import type { Snippet } from 'svelte';
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
bind:ref
|
|
16
16
|
align="start"
|
|
17
17
|
class={cn(
|
|
18
|
-
'z-overlay w-max min-w-(--bits-combobox-anchor-width) overflow-hidden rounded-control
|
|
18
|
+
'z-overlay w-max min-w-(--bits-combobox-anchor-width) overflow-hidden rounded-control material-popover p-menu data-[side=bottom]:rounded-t-none data-[side=top]:rounded-b-none',
|
|
19
19
|
className
|
|
20
20
|
)}
|
|
21
21
|
{sideOffset}
|
|
@@ -21,14 +21,14 @@
|
|
|
21
21
|
bind:value
|
|
22
22
|
class={cn(
|
|
23
23
|
'flex flex-col gap-gutter',
|
|
24
|
-
//
|
|
25
|
-
//
|
|
24
|
+
// material-panel, like every persistent floating surface: opaque on flat/
|
|
25
|
+
// bevel and frosted on glass without naming an implementation here.
|
|
26
26
|
!bare &&
|
|
27
27
|
// The panel is unbounded chrome; its bounded command rows carry their own
|
|
28
28
|
// control tier rather than inheriting geometry from this ancestor.
|
|
29
29
|
// No border: --era-shadow-lg is the edge on every surface, and a border
|
|
30
30
|
// alongside it draws two hairlines of the same colour on flat.
|
|
31
|
-
'overflow-hidden rounded-bar
|
|
31
|
+
'overflow-hidden rounded-bar material-panel p-gutter',
|
|
32
32
|
className
|
|
33
33
|
)}
|
|
34
34
|
{...restProps}
|
|
@@ -186,8 +186,8 @@
|
|
|
186
186
|
|
|
187
187
|
<!-- The terminal command bar: a bare prompt line, not a floating palette. The
|
|
188
188
|
dropdown anchors under it with no radius (a full-width sheet, like the shell
|
|
189
|
-
it mirrors), but its chrome is surface-adaptive via
|
|
190
|
-
|
|
189
|
+
it mirrors), but its chrome is surface-adaptive via material-popover:
|
|
190
|
+
a tone step on flat, the chisel frame
|
|
191
191
|
on bevel, frost on glass — so it reads as "dedicated" on every surface, not
|
|
192
192
|
an undifferentiated rectangle.
|
|
193
193
|
|
|
@@ -273,7 +273,7 @@
|
|
|
273
273
|
role="listbox"
|
|
274
274
|
tabindex="-1"
|
|
275
275
|
aria-label="Commands"
|
|
276
|
-
class="absolute top-full left-0 z-overlay max-h-64 w-full overflow-x-hidden overflow-y-auto
|
|
276
|
+
class="absolute top-full left-0 z-overlay max-h-64 w-full overflow-x-hidden overflow-y-auto material-popover"
|
|
277
277
|
onmousedown={(e) => e.preventDefault()}
|
|
278
278
|
>
|
|
279
279
|
{#if !filtered.length}
|
|
@@ -24,10 +24,7 @@
|
|
|
24
24
|
// anchor bar (the reference terminal look) — while glass and bevel keep the
|
|
25
25
|
// 2px frame that stops a full-width highlight from breaking their chrome.
|
|
26
26
|
// A fixed gutter was tried here and rejected: it padded flat menus too.
|
|
27
|
-
class={cn(
|
|
28
|
-
'z-overlay w-max overflow-hidden rounded-control bg-elevated p-menu shadow-lg glass-blur',
|
|
29
|
-
className
|
|
30
|
-
)}
|
|
27
|
+
class={cn('z-overlay w-max overflow-hidden rounded-control material-popover p-menu', className)}
|
|
31
28
|
{sideOffset}
|
|
32
29
|
{...restProps}
|
|
33
30
|
>
|
|
@@ -18,10 +18,7 @@
|
|
|
18
18
|
<ContextMenu.SubContent
|
|
19
19
|
bind:ref
|
|
20
20
|
{...relay?.attrs}
|
|
21
|
-
class={cn(
|
|
22
|
-
'z-overlay w-max overflow-hidden rounded-control bg-elevated p-menu shadow-lg glass-blur',
|
|
23
|
-
className
|
|
24
|
-
)}
|
|
21
|
+
class={cn('z-overlay w-max overflow-hidden rounded-control material-popover p-menu', className)}
|
|
25
22
|
{sideOffset}
|
|
26
23
|
{...restProps}
|
|
27
24
|
>
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
<DatePicker.Content
|
|
15
15
|
bind:ref
|
|
16
16
|
align="start"
|
|
17
|
-
class={cn('z-overlay rounded-bar
|
|
17
|
+
class={cn('z-overlay rounded-bar material-popover p-content', className)}
|
|
18
18
|
{sideOffset}
|
|
19
19
|
{...restProps}
|
|
20
20
|
>
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
<DateRangePicker.Content
|
|
15
15
|
bind:ref
|
|
16
16
|
align="start"
|
|
17
|
-
class={cn('z-overlay rounded-bar
|
|
17
|
+
class={cn('z-overlay rounded-bar material-popover p-content', className)}
|
|
18
18
|
{sideOffset}
|
|
19
19
|
{...restProps}
|
|
20
20
|
>
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
{...relay?.attrs}
|
|
76
76
|
class={cn(
|
|
77
77
|
relay?.schemeClass,
|
|
78
|
-
'fixed top-1/2 left-1/2 z-overlay flex max-h-[85dvh] w-full max-w-md -translate-x-1/2 -translate-y-1/2 flex-col
|
|
78
|
+
'fixed top-1/2 left-1/2 z-overlay flex max-h-[85dvh] w-full max-w-md -translate-x-1/2 -translate-y-1/2 flex-col material-panel',
|
|
79
79
|
// No header: the panel itself is the body, so the panel scrolls.
|
|
80
80
|
header ? 'rounded-control' : 'gap-gutter overflow-y-auto rounded-bar p-card',
|
|
81
81
|
className
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
· the leading side at --era-inset-control: a title has no corner to nest, so
|
|
25
25
|
it takes the text inset, the same asymmetry the pane and the
|
|
26
26
|
Conversations row document
|
|
27
|
-
· the × is the dismiss family's:
|
|
27
|
+
· the × is the dismiss family's: a pill-tier `Dialog.Close` whose tier
|
|
28
28
|
default IS the 12px ink, destructive like Pane.Close
|
|
29
29
|
|
|
30
30
|
Rendered flush by Dialog.Content / Sheet.Content when passed as their
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
// floating menu, like the context menu it should match: full radius, a
|
|
34
34
|
// gutter of air, shadow doing the separating.
|
|
35
35
|
class={cn(
|
|
36
|
-
'z-overlay w-max min-w-(--bits-dropdown-menu-anchor-width) overflow-hidden rounded-control
|
|
36
|
+
'z-overlay w-max min-w-(--bits-dropdown-menu-anchor-width) overflow-hidden rounded-control material-popover p-menu',
|
|
37
37
|
className
|
|
38
38
|
)}
|
|
39
39
|
{sideOffset}
|
|
@@ -18,10 +18,7 @@
|
|
|
18
18
|
<DropdownMenu.SubContent
|
|
19
19
|
bind:ref
|
|
20
20
|
{...relay?.attrs}
|
|
21
|
-
class={cn(
|
|
22
|
-
'z-overlay w-max overflow-hidden rounded-control bg-elevated p-menu shadow-lg glass-blur',
|
|
23
|
-
className
|
|
24
|
-
)}
|
|
21
|
+
class={cn('z-overlay w-max overflow-hidden rounded-control material-popover p-menu', className)}
|
|
25
22
|
{sideOffset}
|
|
26
23
|
{...restProps}
|
|
27
24
|
>
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
bind:ref
|
|
20
20
|
{...relay?.attrs}
|
|
21
21
|
class={cn(
|
|
22
|
-
'z-overlay max-w-xs rounded-control
|
|
22
|
+
'z-overlay max-w-xs rounded-control material-popover p-inset-control text-body',
|
|
23
23
|
className
|
|
24
24
|
)}
|
|
25
25
|
{sideOffset}
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
// floating menu, like the context menu it should match: full radius, a
|
|
34
34
|
// gutter of air, shadow doing the separating.
|
|
35
35
|
class={cn(
|
|
36
|
-
'z-overlay w-max min-w-(--bits-menubar-menu-anchor-width) overflow-hidden rounded-control
|
|
36
|
+
'z-overlay w-max min-w-(--bits-menubar-menu-anchor-width) overflow-hidden rounded-control material-popover p-menu',
|
|
37
37
|
className
|
|
38
38
|
)}
|
|
39
39
|
{sideOffset}
|
|
@@ -18,10 +18,7 @@
|
|
|
18
18
|
<Menubar.SubContent
|
|
19
19
|
bind:ref
|
|
20
20
|
{...relay?.attrs}
|
|
21
|
-
class={cn(
|
|
22
|
-
'z-overlay w-max overflow-hidden rounded-control bg-elevated p-menu shadow-lg glass-blur',
|
|
23
|
-
className
|
|
24
|
-
)}
|
|
21
|
+
class={cn('z-overlay w-max overflow-hidden rounded-control material-popover p-menu', className)}
|
|
25
22
|
{sideOffset}
|
|
26
23
|
{...restProps}
|
|
27
24
|
>
|
|
@@ -239,8 +239,7 @@
|
|
|
239
239
|
THE ORDER IS CURRENTLY UNOBSERVABLE, and that is worth knowing rather
|
|
240
240
|
than discovering. Swapping these two changes no pixel: the buffer is
|
|
241
241
|
the fill's OWN paint at 30%, and the same colour composited over
|
|
242
|
-
itself is that colour.
|
|
243
|
-
meter-buffer.spec.ts, which stayed green. So the order is kept for
|
|
242
|
+
itself is that colour. A control swap was pixel-identical. So the order is kept for
|
|
244
243
|
correctness — it is what makes the contract true for any future paint
|
|
245
244
|
that is not derived from the fill — and not because a test can see it.
|
|
246
245
|
Do not read the passing spec as covering it.
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
import type { HTMLButtonAttributes } from 'svelte/elements';
|
|
3
3
|
import { Button } from '../button';
|
|
4
4
|
import X from '@lucide/svelte/icons/x';
|
|
5
|
-
import { cn } from '../../utils/index.js';
|
|
6
5
|
|
|
7
6
|
let {
|
|
8
7
|
ref = $bindable(null),
|
|
@@ -13,42 +12,24 @@
|
|
|
13
12
|
} = $props();
|
|
14
13
|
</script>
|
|
15
14
|
|
|
16
|
-
<!-- A raw icon Button (size="pill" = h-pill
|
|
15
|
+
<!-- A raw icon Button (size="pill" = h-pill), a tight SQUARE. No
|
|
17
16
|
data-pane-control: it stays in the drag zone, so a press-and-drag moves the
|
|
18
17
|
pane while a clean click still closes (neodrag starts a drag only on
|
|
19
18
|
movement and suppresses the trailing click after a real drag). Its natural
|
|
20
|
-
|
|
19
|
+
pill radius is what the PANE's corner radius conforms to (see Pane.Root),
|
|
21
20
|
not the other way round.
|
|
22
21
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
visibly lighter than the reference terminal app's close button, 14 reads
|
|
28
|
-
heavier — and a close button is the one control in the chrome you must be
|
|
29
|
-
able to hit and read at a glance, so a pixel of it is worth an exception.
|
|
30
|
-
|
|
31
|
-
sp+5 is 13/15/17/21, matching that app's 13px at dense, and the pad it
|
|
32
|
-
leaves is a constant 2.5px at EVERY mode, so the exception is uniform rather
|
|
33
|
-
than one hand-picked number.
|
|
34
|
-
|
|
35
|
-
The pad being fractional costs nothing for this glyph in particular: an ×
|
|
36
|
-
is two DIAGONAL strokes, which the rasteriser antialiases wherever the box
|
|
37
|
-
lands, so pixel alignment buys no crispness (it would for the minimize −,
|
|
38
|
-
which is axis-aligned — that one stays on the ladder). If a second component
|
|
39
|
-
ever wants this size, it graduates from a calc here to a token in
|
|
40
|
-
density.css.
|
|
41
|
-
|
|
42
|
-
Written as [&_svg]: because that is the selector Button's icon variant uses —
|
|
43
|
-
a bare size-* on the <X> loses to it, which is why an earlier class there had
|
|
44
|
-
no effect at all. -->
|
|
22
|
+
The Button's pill glyph tier is exactly 6px smaller than its pill box:
|
|
23
|
+
18px around 12px at dense, and the same difference at every density. That
|
|
24
|
+
leaves a whole-pixel 3px inset on all four sides without a pane-specific
|
|
25
|
+
size exception. -->
|
|
45
26
|
<Button
|
|
46
27
|
bind:ref
|
|
47
28
|
icon
|
|
48
29
|
size="pill"
|
|
49
30
|
tone="destructive"
|
|
50
31
|
aria-label="Close"
|
|
51
|
-
class={
|
|
32
|
+
class={className}
|
|
52
33
|
{...restProps}
|
|
53
34
|
>
|
|
54
35
|
<X />
|
|
@@ -532,7 +532,7 @@
|
|
|
532
532
|
// outward, and paint containment clips them).
|
|
533
533
|
// The pane is unbounded chrome. Bounded descendants carry their own tier;
|
|
534
534
|
// no inherited radius is allowed to rewrite a row from the outside in.
|
|
535
|
-
'group/pane absolute isolate flex flex-col rounded-control border border-divider
|
|
535
|
+
'group/pane absolute isolate flex flex-col rounded-control border border-divider material-popover [contain:layout_style]',
|
|
536
536
|
// Auto-size to content until an explicit size is set (by the grip or a preset).
|
|
537
537
|
size ? '' : 'w-max',
|
|
538
538
|
// While Ctrl is held the whole pane is grabbable: a grab cursor hints it, and
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
// floating menu, like the context menu it should match: full radius, a
|
|
23
23
|
// gutter of air, shadow doing the separating.
|
|
24
24
|
class={cn(
|
|
25
|
-
'z-overlay w-max min-w-(--bits-popover-anchor-width) overflow-hidden rounded-control
|
|
25
|
+
'z-overlay w-max min-w-(--bits-popover-anchor-width) overflow-hidden rounded-control material-popover p-card',
|
|
26
26
|
className
|
|
27
27
|
)}
|
|
28
28
|
{sideOffset}
|
|
@@ -22,7 +22,7 @@ export declare const surfaceRegistry: {
|
|
|
22
22
|
readonly flat: {
|
|
23
23
|
readonly label: "Flat";
|
|
24
24
|
readonly description: "Solid fills, no chrome — the quiet default.";
|
|
25
|
-
readonly css: "
|
|
25
|
+
readonly css: "flat.css";
|
|
26
26
|
};
|
|
27
27
|
readonly glass: {
|
|
28
28
|
readonly label: "Glass";
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
// 2px frame that stops a full-width highlight from breaking their chrome.
|
|
30
30
|
// A fixed gutter was tried here and rejected: it padded flat menus too.
|
|
31
31
|
class={cn(
|
|
32
|
-
'z-overlay w-max min-w-(--bits-select-anchor-width) overflow-hidden rounded-control
|
|
32
|
+
'z-overlay w-max min-w-(--bits-select-anchor-width) overflow-hidden rounded-control material-popover p-menu data-[side=bottom]:rounded-t-none data-[side=top]:rounded-b-none',
|
|
33
33
|
className
|
|
34
34
|
)}
|
|
35
35
|
{sideOffset}
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
// the viewport boundary, so only the open edge is visible and it was the
|
|
12
12
|
// thick one.
|
|
13
13
|
export const sheetVariants = tv({
|
|
14
|
-
base: 'fixed z-overlay flex flex-col
|
|
14
|
+
base: 'fixed z-overlay material-panel flex flex-col',
|
|
15
15
|
variants: {
|
|
16
16
|
// The two axes meet at the corners: the SIDE picks which corners are
|
|
17
17
|
// detached from the screen edge, the HEADER picks their radius. Stated
|
|
@@ -17,7 +17,7 @@ export declare const sheetVariants: import("tailwind-variants").TVReturnType<{
|
|
|
17
17
|
true: "[--sheet-rd:var(--era-rd-control)]";
|
|
18
18
|
false: "[--sheet-rd:var(--era-rd-bar)] gap-gutter overflow-y-auto p-card";
|
|
19
19
|
};
|
|
20
|
-
}, undefined, "fixed z-overlay flex flex-col
|
|
20
|
+
}, undefined, "fixed z-overlay material-panel flex flex-col", {
|
|
21
21
|
side: {
|
|
22
22
|
top: "inset-x-0 top-0 max-h-[85dvh] rounded-b-(--sheet-rd)";
|
|
23
23
|
bottom: "inset-x-0 bottom-0 max-h-[85dvh] rounded-t-(--sheet-rd)";
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
may retune the feel by overriding --era-ease in its [data-surface]
|
|
42
42
|
block; a surface wanting a different STRATEGY (e.g. glass crossfade
|
|
43
43
|
vs bevel track-slide) scopes a rule to its own surface — see the
|
|
44
|
-
|
|
44
|
+
material contract in surfaces/contract.css. -->
|
|
45
45
|
<Switch.Thumb
|
|
46
46
|
class="pointer-events-none block tier-icon w-icon -translate-x-[calc(var(--era-h-icon)/2)] bg-fg transition-transform duration-base ease-base data-[state=checked]:translate-x-[calc(var(--era-h-icon)/2)] data-[state=checked]:bg-2"
|
|
47
47
|
/>
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
variants: {
|
|
15
15
|
variant: {
|
|
16
16
|
plain:
|
|
17
|
-
'min-w-control tier-control px-inset-control shadow-sm hover:shadow-highlight
|
|
17
|
+
'pressable min-w-control tier-control px-inset-control shadow-sm hover:shadow-highlight',
|
|
18
18
|
segmented: 'min-w-chip tier-chip px-inset-chip'
|
|
19
19
|
}
|
|
20
20
|
},
|