@signal9/era-ui 3.17.1 → 4.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.
- package/dist/era-ui.css +1 -1
- package/dist/generated-docs/llms-full.txt +1 -1
- package/dist/generated-docs/manifest.json +1 -1
- package/dist/generated-docs/pane.md +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +5 -0
- package/dist/os/desktop.svelte +25 -25
- package/dist/os/desktop.svelte.d.ts +3 -3
- package/dist/os/index.d.ts +3 -3
- package/dist/os/index.js +5 -5
- package/dist/os/layers.d.ts +4 -4
- package/dist/os/layers.js +4 -4
- package/dist/os/notification-center.svelte +4 -4
- package/dist/os/{wm.svelte.d.ts → pane-manager.svelte.d.ts} +50 -50
- package/dist/os/{wm.svelte.js → pane-manager.svelte.js} +49 -49
- package/dist/os/{window.svelte → pane.svelte} +35 -34
- package/dist/os/pane.svelte.d.ts +8 -0
- package/dist/os/taskbar.svelte +38 -38
- package/dist/os/taskbar.svelte.d.ts +6 -6
- package/dist/os/workspace-storage.svelte.d.ts +5 -5
- package/dist/os/workspace-storage.svelte.js +15 -15
- package/dist/styles/surfaces/base.css +22 -0
- package/dist/styles/surfaces/glass.css +11 -0
- package/dist/ui/combobox/combobox-input.svelte +1 -1
- package/dist/ui/command/command-input.svelte +2 -2
- package/dist/ui/date-field/date-field-input.svelte +1 -1
- package/dist/ui/date-picker/date-picker-input.svelte +1 -1
- package/dist/ui/date-range-field/date-range-field-input.svelte +1 -1
- package/dist/ui/date-range-picker/date-range-picker-input.svelte +1 -1
- package/dist/ui/input/input.svelte +1 -1
- package/dist/ui/input/input.svelte.d.ts +3 -3
- package/dist/ui/input/textarea.svelte +1 -1
- package/dist/ui/pane/pane.svelte +2 -2
- package/dist/ui/time-field/time-field-input.svelte +1 -1
- package/dist/ui/time-range-field/time-range-field-input.svelte +1 -1
- package/dist/ui/video-player/video-player.svelte +1 -1
- package/package.json +1 -1
- package/dist/os/window.svelte.d.ts +0 -7
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type PaneManager } from './pane-manager.svelte.js';
|
|
2
2
|
export declare const WORKSPACE_STORAGE_KEY = "era-ui:workspace";
|
|
3
3
|
/**
|
|
4
4
|
* Read a saved snapshot and apply it. Returns whether anything was restored.
|
|
@@ -7,9 +7,9 @@ export declare const WORKSPACE_STORAGE_KEY = "era-ui:workspace";
|
|
|
7
7
|
* seed (localStorage), so a reload is exact and a brand-new tab still opens on
|
|
8
8
|
* your most recent arrangement.
|
|
9
9
|
*/
|
|
10
|
-
export declare function loadWorkspace(
|
|
10
|
+
export declare function loadWorkspace(pm: PaneManager, key?: string): boolean;
|
|
11
11
|
/** Write the current desktop to both stores. Returns false if neither accepted it. */
|
|
12
|
-
export declare function saveWorkspace(
|
|
12
|
+
export declare function saveWorkspace(pm: PaneManager, key?: string): boolean;
|
|
13
13
|
/** Forget the layout — this tab's and the shared seed. */
|
|
14
14
|
export declare function clearWorkspace(key?: string): void;
|
|
15
15
|
/**
|
|
@@ -19,12 +19,12 @@ export declare function clearWorkspace(key?: string): void;
|
|
|
19
19
|
* component context). The load is synchronous and happens immediately, before
|
|
20
20
|
* the first paint.
|
|
21
21
|
*
|
|
22
|
-
* Writes are debounced: dragging a
|
|
22
|
+
* Writes are debounced: dragging a pane mutates `pos` on every pointer move,
|
|
23
23
|
* and serialising the whole desktop per frame would be pointless work. The
|
|
24
24
|
* trailing write always lands because the effect's teardown flushes a pending
|
|
25
25
|
* timer.
|
|
26
26
|
*/
|
|
27
|
-
export declare function persistWorkspace(
|
|
27
|
+
export declare function persistWorkspace(pm: PaneManager, options?: {
|
|
28
28
|
key?: string;
|
|
29
29
|
debounce?: number;
|
|
30
30
|
}): {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* WHERE IT IS STORED, AND WHY IT IS TWO PLACES
|
|
5
5
|
* --------------------------------------------
|
|
6
|
-
* A
|
|
6
|
+
* A pane layout is VIEW state, not document state — the same kind of thing as
|
|
7
7
|
* scroll position. Nobody expects scrolling one tab to scroll another, and the
|
|
8
8
|
* same holds here: two tabs of the same app are two workspaces, not two views of
|
|
9
9
|
* one workspace. That observation decides the whole design.
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
* The alternatives, and why not:
|
|
26
26
|
*
|
|
27
27
|
* `storage` event / BroadcastChannel — mirror every tab to one shared layout.
|
|
28
|
-
* Both work, and both are wrong HERE: dragging a
|
|
28
|
+
* Both work, and both are wrong HERE: dragging a pane in one tab would move
|
|
29
29
|
* it in the other. That is the correct design for a synced setting (theme,
|
|
30
30
|
* auth), not for a workspace.
|
|
31
31
|
* Web Locks leader election — `navigator.locks.request()` held forever elects
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
* The payload is a few kB of JSON that must be read BEFORE the first paint, which
|
|
41
41
|
* rules out every modern alternative, because they are all async: IndexedDB,
|
|
42
42
|
* OPFS, and Storage Buckets alike would paint an empty desktop and pop the
|
|
43
|
-
*
|
|
43
|
+
* panes in a frame later. Synchronous access is the feature here, not the
|
|
44
44
|
* compromise. Their real strengths do not apply either — OPFS is for large or
|
|
45
45
|
* binary files with read/write handles, and Storage Buckets exists for per-bucket
|
|
46
46
|
* eviction policy across several competing stores (and is Chromium-only). One
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
* once, non-blocking, and a refusal is harmless.
|
|
52
52
|
*/
|
|
53
53
|
import { untrack } from 'svelte';
|
|
54
|
-
import { readSnapshot } from './
|
|
54
|
+
import { readSnapshot } from './pane-manager.svelte.js';
|
|
55
55
|
export const WORKSPACE_STORAGE_KEY = 'era-ui:workspace';
|
|
56
56
|
/** Both stores, newest-first: this tab's own layout, then the new-tab seed. */
|
|
57
57
|
function stores() {
|
|
@@ -79,7 +79,7 @@ function stores() {
|
|
|
79
79
|
* seed (localStorage), so a reload is exact and a brand-new tab still opens on
|
|
80
80
|
* your most recent arrangement.
|
|
81
81
|
*/
|
|
82
|
-
export function loadWorkspace(
|
|
82
|
+
export function loadWorkspace(pm, key = WORKSPACE_STORAGE_KEY) {
|
|
83
83
|
for (const store of stores()) {
|
|
84
84
|
let raw = null;
|
|
85
85
|
try {
|
|
@@ -95,14 +95,14 @@ export function loadWorkspace(wm, key = WORKSPACE_STORAGE_KEY) {
|
|
|
95
95
|
const snapshot = readSnapshot(raw);
|
|
96
96
|
if (!snapshot)
|
|
97
97
|
continue;
|
|
98
|
-
|
|
98
|
+
pm.applySnapshot(snapshot);
|
|
99
99
|
return true;
|
|
100
100
|
}
|
|
101
101
|
return false;
|
|
102
102
|
}
|
|
103
103
|
/** Write the current desktop to both stores. Returns false if neither accepted it. */
|
|
104
|
-
export function saveWorkspace(
|
|
105
|
-
const json = JSON.stringify(
|
|
104
|
+
export function saveWorkspace(pm, key = WORKSPACE_STORAGE_KEY) {
|
|
105
|
+
const json = JSON.stringify(pm.snapshot());
|
|
106
106
|
let ok = false;
|
|
107
107
|
for (const store of stores()) {
|
|
108
108
|
try {
|
|
@@ -135,22 +135,22 @@ export function clearWorkspace(key = WORKSPACE_STORAGE_KEY) {
|
|
|
135
135
|
* component context). The load is synchronous and happens immediately, before
|
|
136
136
|
* the first paint.
|
|
137
137
|
*
|
|
138
|
-
* Writes are debounced: dragging a
|
|
138
|
+
* Writes are debounced: dragging a pane mutates `pos` on every pointer move,
|
|
139
139
|
* and serialising the whole desktop per frame would be pointless work. The
|
|
140
140
|
* trailing write always lands because the effect's teardown flushes a pending
|
|
141
141
|
* timer.
|
|
142
142
|
*/
|
|
143
|
-
export function persistWorkspace(
|
|
143
|
+
export function persistWorkspace(pm, options = {}) {
|
|
144
144
|
const key = options.key ?? WORKSPACE_STORAGE_KEY;
|
|
145
145
|
const wait = options.debounce ?? 400;
|
|
146
|
-
const restored = loadWorkspace(
|
|
146
|
+
const restored = loadWorkspace(pm, key);
|
|
147
147
|
// Fire-and-forget: a refusal (or an engine without the API) just leaves the
|
|
148
148
|
// default best-effort behaviour.
|
|
149
149
|
void navigator?.storage?.persist?.().catch(() => { });
|
|
150
150
|
$effect(() => {
|
|
151
151
|
// Touch what a snapshot is made of, so the effect re-runs when any of it
|
|
152
152
|
// changes. Reading these is the subscription.
|
|
153
|
-
|
|
153
|
+
pm.panes.forEach((w) => {
|
|
154
154
|
void w.pos.x;
|
|
155
155
|
void w.pos.y;
|
|
156
156
|
void w.size?.width;
|
|
@@ -161,12 +161,12 @@ export function persistWorkspace(wm, options = {}) {
|
|
|
161
161
|
void w.workspaceId;
|
|
162
162
|
void w.props;
|
|
163
163
|
});
|
|
164
|
-
void
|
|
165
|
-
void
|
|
164
|
+
void pm.workspaces.length;
|
|
165
|
+
void pm.activeWorkspaceId;
|
|
166
166
|
const timer = setTimeout(() => {
|
|
167
167
|
// untrack: snapshot() reads the same state this effect depends on, and
|
|
168
168
|
// re-reading it inside would re-subscribe on every write.
|
|
169
|
-
untrack(() => saveWorkspace(
|
|
169
|
+
untrack(() => saveWorkspace(pm, key));
|
|
170
170
|
}, wait);
|
|
171
171
|
return () => clearTimeout(timer);
|
|
172
172
|
});
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
* ==============
|
|
29
29
|
*
|
|
30
30
|
* --era-surface-bg / -elevated surface fills (resting / raised tier)
|
|
31
|
+
* --era-field-bg the RECESSED tier — a text field's resting fill
|
|
31
32
|
* --era-shadow / --era-shadow-lg resting edge chrome (controls / floating)
|
|
32
33
|
* --era-shadow-well recessed container (inputs, tracks, checks)
|
|
33
34
|
* --era-shadow-pressed a control's :active or latched face
|
|
@@ -64,6 +65,27 @@
|
|
|
64
65
|
/* Same-element default: tracks --era-surface-bg unless a surface splits
|
|
65
66
|
* the tiers (glass is the only one that does). */
|
|
66
67
|
--era-surface-bg-elevated: var(--era-surface-bg);
|
|
68
|
+
/* The third fill tier, and the one that was missing. A field is RECESSED, so
|
|
69
|
+
* it was reaching for -elevated (the RAISED tier) and relying on
|
|
70
|
+
* --era-shadow-well to sell the depth — which works on a surface that has
|
|
71
|
+
* shadows and does nothing at all on flat. Measured before this token
|
|
72
|
+
* existed: a resting input sat at 1.06:1 against its backdrop on flat and
|
|
73
|
+
* bevel dark, and at 1.00:1 on glass light. Invisible until you touched it.
|
|
74
|
+
*
|
|
75
|
+
* Expressed as a perceptual STEP from the page toward the text, not as a
|
|
76
|
+
* scale index, and that distinction is the whole reason this reads evenly.
|
|
77
|
+
* The 12-step scale is not symmetric about its ends: --color-3 sits ΔL 0.09
|
|
78
|
+
* from the page in dark but ΔL 0.21 in light, so the same token that looked
|
|
79
|
+
* right on a dark page rendered a heavy grey slab on a light one. Mixing a
|
|
80
|
+
* fixed 16% of the foreground into the page gives ΔL ≈ 0.11 in BOTH modes —
|
|
81
|
+
* one expression, no light-dark() branch, and it stays correct if the scale
|
|
82
|
+
* is ever retuned.
|
|
83
|
+
*
|
|
84
|
+
* Toward the TEXT rather than "darker": in light mode a well genuinely is
|
|
85
|
+
* darker, but on a dark page nothing can be, so depth is carried by
|
|
86
|
+
* separation rather than by shade. Mixing toward the foreground gets both
|
|
87
|
+
* directions for free. */
|
|
88
|
+
--era-field-bg: color-mix(in oklch, var(--color-1) 84%, var(--color-fg));
|
|
67
89
|
--era-shadow: none;
|
|
68
90
|
--era-shadow-lg: none;
|
|
69
91
|
--era-shadow-well: var(--era-shadow);
|
|
@@ -33,6 +33,17 @@
|
|
|
33
33
|
color-mix(in oklch, var(--color-3) 85%, transparent)
|
|
34
34
|
);
|
|
35
35
|
|
|
36
|
+
/* The same perceptual step the base defines, held at 72% so the frost still
|
|
37
|
+
* reads through it — the material is the point. Restated rather than
|
|
38
|
+
* inherited because a surface cannot reference the token it is overriding.
|
|
39
|
+
* Light mode is why a field needs its own value here at all: at the panel's
|
|
40
|
+
* own opacity it measured 1.00:1 against its backdrop, i.e. exactly nothing. */
|
|
41
|
+
--era-field-bg: color-mix(
|
|
42
|
+
in oklch,
|
|
43
|
+
color-mix(in oklch, var(--color-1) 84%, var(--color-fg)) 72%,
|
|
44
|
+
transparent
|
|
45
|
+
);
|
|
46
|
+
|
|
36
47
|
--era-shadow:
|
|
37
48
|
inset 1.5px 1.5px 0 -1px
|
|
38
49
|
light-dark(
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<Combobox.Input
|
|
9
9
|
bind:ref
|
|
10
10
|
class={cn(
|
|
11
|
-
'flex h-(--era-h-md) w-full era-interactive rounded-(--era-rd-md) bg-(--era-
|
|
11
|
+
'flex h-(--era-h-md) w-full era-interactive rounded-(--era-rd-md) bg-(--era-field-bg) px-(--era-field-px) text-body text-fg shadow-(--era-shadow-well) placeholder:text-muted hover:bg-(--era-highlight) focus:bg-(--era-highlight) data-[state=open]:rounded-b-none data-[state=open]:shadow-(--era-shadow-pressed)',
|
|
12
12
|
className
|
|
13
13
|
)}
|
|
14
14
|
{...restProps}
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
{@const Icon = icon}
|
|
21
21
|
<div
|
|
22
22
|
class={cn(
|
|
23
|
-
'flex h-(--era-h-md) w-full era-interactive items-center gap-(--era-gap) rounded-(--era-rd-md) bg-(--era-
|
|
23
|
+
'flex h-(--era-h-md) w-full era-interactive items-center gap-(--era-gap) rounded-(--era-rd-md) bg-(--era-field-bg) px-(--era-field-px) text-body era-text-trim text-fg shadow-(--era-shadow-well) focus-within:bg-(--era-highlight) hover:bg-(--era-highlight)',
|
|
24
24
|
className
|
|
25
25
|
)}
|
|
26
26
|
>
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
bind:ref
|
|
38
38
|
bind:value
|
|
39
39
|
class={cn(
|
|
40
|
-
'flex h-(--era-h-md) w-full era-interactive rounded-(--era-rd-md) bg-(--era-
|
|
40
|
+
'flex h-(--era-h-md) w-full era-interactive rounded-(--era-rd-md) bg-(--era-field-bg) px-(--era-field-px) text-body text-fg shadow-(--era-shadow-well) placeholder:text-muted hover:bg-(--era-highlight) focus:bg-(--era-highlight)',
|
|
41
41
|
className
|
|
42
42
|
)}
|
|
43
43
|
{...restProps}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<DateField.Input
|
|
9
9
|
bind:ref
|
|
10
10
|
class={cn(
|
|
11
|
-
'flex h-(--era-h-md) w-full items-center rounded-(--era-rd-md) bg-(--era-
|
|
11
|
+
'flex h-(--era-h-md) w-full items-center rounded-(--era-rd-md) bg-(--era-field-bg) px-(--era-field-px) text-body text-fg shadow-(--era-shadow-well) focus-within:bg-(--era-highlight) hover:bg-(--era-highlight) disabled:opacity-50 data-[invalid]:text-destructive',
|
|
12
12
|
className
|
|
13
13
|
)}
|
|
14
14
|
{...restProps}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<DatePicker.Input
|
|
9
9
|
bind:ref
|
|
10
10
|
class={cn(
|
|
11
|
-
'flex h-(--era-h-md) w-full items-center rounded-(--era-rd-md) bg-(--era-
|
|
11
|
+
'flex h-(--era-h-md) w-full items-center rounded-(--era-rd-md) bg-(--era-field-bg) ps-(--era-inset-md) pe-(--era-px-md) text-body text-fg shadow-(--era-shadow-well) focus-within:bg-(--era-highlight) hover:bg-(--era-highlight) disabled:opacity-50 data-[invalid]:text-destructive',
|
|
12
12
|
className
|
|
13
13
|
)}
|
|
14
14
|
{...restProps}
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
<DateRangeField.Input
|
|
13
13
|
bind:ref
|
|
14
14
|
class={cn(
|
|
15
|
-
'flex h-(--era-h-md) w-full items-center rounded-(--era-rd-md) bg-(--era-
|
|
15
|
+
'flex h-(--era-h-md) w-full items-center rounded-(--era-rd-md) bg-(--era-field-bg) px-(--era-field-px) text-body text-fg shadow-(--era-shadow-well) focus-within:bg-(--era-highlight) hover:bg-(--era-highlight) disabled:opacity-50 data-[invalid]:text-destructive',
|
|
16
16
|
className
|
|
17
17
|
)}
|
|
18
18
|
{...restProps}
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
<DateRangePicker.Input
|
|
13
13
|
bind:ref
|
|
14
14
|
class={cn(
|
|
15
|
-
'flex h-(--era-h-md) items-center rounded-(--era-rd-md) bg-(--era-
|
|
15
|
+
'flex h-(--era-h-md) items-center rounded-(--era-rd-md) bg-(--era-field-bg) ps-(--era-inset-md) pe-(--era-px-md) text-body text-fg shadow-(--era-shadow-well) focus-within:bg-(--era-highlight) hover:bg-(--era-highlight) disabled:opacity-50 data-[invalid]:text-destructive',
|
|
16
16
|
className
|
|
17
17
|
)}
|
|
18
18
|
{...restProps}
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
*/
|
|
22
22
|
bare: {
|
|
23
23
|
false:
|
|
24
|
-
'h-(--era-h-md) rounded-(--era-rd-md) bg-(--era-
|
|
24
|
+
'h-(--era-h-md) rounded-(--era-rd-md) bg-(--era-field-bg) px-(--era-field-px) shadow-(--era-shadow-well) hover:bg-(--era-highlight) focus-within:bg-(--era-highlight) focus:bg-(--era-highlight)',
|
|
25
25
|
// h-full, NOT the md tier: a bare input's container IS the field, so it
|
|
26
26
|
// takes that container's height. Keeping h-md here made a bare input
|
|
27
27
|
// inside an h-md Bar overflow it by the bar's border — a −0.5px gap,
|
|
@@ -15,7 +15,7 @@ export declare const inputVariants: import("tailwind-variants").TVReturnType<{
|
|
|
15
15
|
* edge to edge so the two have no gap between them.
|
|
16
16
|
*/
|
|
17
17
|
bare: {
|
|
18
|
-
false: "h-(--era-h-md) rounded-(--era-rd-md) bg-(--era-
|
|
18
|
+
false: "h-(--era-h-md) rounded-(--era-rd-md) bg-(--era-field-bg) px-(--era-field-px) shadow-(--era-shadow-well) hover:bg-(--era-highlight) focus-within:bg-(--era-highlight) focus:bg-(--era-highlight)";
|
|
19
19
|
true: "h-full bg-transparent px-0 shadow-none";
|
|
20
20
|
};
|
|
21
21
|
}, undefined, "flex w-full era-interactive text-body text-fg", {
|
|
@@ -27,7 +27,7 @@ export declare const inputVariants: import("tailwind-variants").TVReturnType<{
|
|
|
27
27
|
* edge to edge so the two have no gap between them.
|
|
28
28
|
*/
|
|
29
29
|
bare: {
|
|
30
|
-
false: "h-(--era-h-md) rounded-(--era-rd-md) bg-(--era-
|
|
30
|
+
false: "h-(--era-h-md) rounded-(--era-rd-md) bg-(--era-field-bg) px-(--era-field-px) shadow-(--era-shadow-well) hover:bg-(--era-highlight) focus-within:bg-(--era-highlight) focus:bg-(--era-highlight)";
|
|
31
31
|
true: "h-full bg-transparent px-0 shadow-none";
|
|
32
32
|
};
|
|
33
33
|
}, undefined, import("tailwind-variants").TVReturnTypeLike<{
|
|
@@ -39,7 +39,7 @@ export declare const inputVariants: import("tailwind-variants").TVReturnType<{
|
|
|
39
39
|
* edge to edge so the two have no gap between them.
|
|
40
40
|
*/
|
|
41
41
|
bare: {
|
|
42
|
-
false: "h-(--era-h-md) rounded-(--era-rd-md) bg-(--era-
|
|
42
|
+
false: "h-(--era-h-md) rounded-(--era-rd-md) bg-(--era-field-bg) px-(--era-field-px) shadow-(--era-shadow-well) hover:bg-(--era-highlight) focus-within:bg-(--era-highlight) focus:bg-(--era-highlight)";
|
|
43
43
|
true: "h-full bg-transparent px-0 shadow-none";
|
|
44
44
|
};
|
|
45
45
|
}, undefined>>;
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
bind:this={ref}
|
|
17
17
|
bind:value
|
|
18
18
|
class={cn(
|
|
19
|
-
'flex min-h-(--era-h-md) w-full era-interactive resize-y rounded-(--era-rd-md) bg-(--era-
|
|
19
|
+
'flex min-h-(--era-h-md) w-full era-interactive resize-y rounded-(--era-rd-md) bg-(--era-field-bg) px-(--era-field-px) py-(--era-inset-md) text-body text-fg shadow-(--era-shadow-well) placeholder:text-muted hover:bg-(--era-highlight) focus:bg-(--era-highlight)',
|
|
20
20
|
className
|
|
21
21
|
)}
|
|
22
22
|
{...restProps}
|
package/dist/ui/pane/pane.svelte
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import Handle from './pane-handle.svelte';
|
|
8
8
|
import Content from './pane-content.svelte';
|
|
9
9
|
import Close from './pane-close.svelte';
|
|
10
|
-
import
|
|
10
|
+
import AppPane from '@lucide/svelte/icons/app-window';
|
|
11
11
|
|
|
12
12
|
let {
|
|
13
13
|
ref = $bindable(null),
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
size = $bindable(null),
|
|
16
16
|
resizable = false,
|
|
17
17
|
title,
|
|
18
|
-
icon =
|
|
18
|
+
icon = AppPane,
|
|
19
19
|
disabled = false,
|
|
20
20
|
plugins = [],
|
|
21
21
|
onDragStart,
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<TimeField.Input
|
|
9
9
|
bind:ref
|
|
10
10
|
class={cn(
|
|
11
|
-
'flex h-(--era-h-md) w-full items-center rounded-(--era-rd-md) bg-(--era-
|
|
11
|
+
'flex h-(--era-h-md) w-full items-center rounded-(--era-rd-md) bg-(--era-field-bg) px-(--era-field-px) text-body text-fg shadow-(--era-shadow-well) focus-within:bg-(--era-highlight) hover:bg-(--era-highlight) disabled:opacity-50 data-[invalid]:text-destructive',
|
|
12
12
|
className
|
|
13
13
|
)}
|
|
14
14
|
{...restProps}
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
<TimeRangeField.Input
|
|
13
13
|
bind:ref
|
|
14
14
|
class={cn(
|
|
15
|
-
'flex h-(--era-h-md) w-full items-center rounded-(--era-rd-md) bg-(--era-
|
|
15
|
+
'flex h-(--era-h-md) w-full items-center rounded-(--era-rd-md) bg-(--era-field-bg) px-(--era-field-px) text-body text-fg shadow-(--era-shadow-well) focus-within:bg-(--era-highlight) hover:bg-(--era-highlight) disabled:opacity-50 data-[invalid]:text-destructive',
|
|
16
16
|
className
|
|
17
17
|
)}
|
|
18
18
|
{...restProps}
|
|
@@ -791,7 +791,7 @@
|
|
|
791
791
|
|
|
792
792
|
const playLabel = $derived(ended ? 'Replay' : paused ? 'Play' : 'Pause');
|
|
793
793
|
const muteLabel = $derived(mutedState || volumeState === 0 ? 'Unmute' : 'Mute');
|
|
794
|
-
// Prefer seekable.end when smaller than duration (HLS live
|
|
794
|
+
// Prefer seekable.end when smaller than duration (HLS live panes); fall
|
|
795
795
|
// back to duration for VOD where the engine may report seekable === duration.
|
|
796
796
|
const timeMax = $derived(
|
|
797
797
|
seekableEnd > 0 && seekableEnd < (duration || Infinity)
|
package/package.json
CHANGED