@signal9/era-ui 6.0.0 → 8.0.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/ai/prompt-input/prompt-input-textarea.svelte +1 -2
- package/dist/ai/reasoning/reasoning.svelte +4 -0
- package/dist/apps/notes/note-editor.svelte +7 -364
- package/dist/apps/notes/note-editor.svelte.d.ts +1 -0
- package/dist/era-ui.css +1 -1
- package/dist/generated-docs/llms-full.txt +21 -2
- package/dist/generated-docs/llms.txt +21 -2
- package/dist/index.d.ts +34 -5
- package/dist/index.js +42 -8
- package/dist/os/workspace-storage.svelte.js +1 -1
- package/dist/styles/index.css +23 -13
- package/dist/styles/prose.css +384 -0
- package/dist/styles/video-player.css +27 -0
- package/dist/ui/calendar/calendar-root.svelte.d.ts +1 -1
- package/dist/ui/date-field/date-field-root.svelte.d.ts +1 -1
- package/dist/ui/date-picker/date-picker-root.svelte.d.ts +1 -1
- package/dist/ui/date-range-field/date-range-field-root.svelte.d.ts +1 -1
- package/dist/ui/date-range-picker/date-range-picker-root.svelte.d.ts +1 -1
- package/dist/ui/input/textarea.svelte +1 -2
- package/dist/ui/time-field/time-field-root.svelte.d.ts +1 -1
- package/dist/ui/time-range-field/time-range-field-root.svelte.d.ts +1 -1
- package/dist/ui/video-player/video-player.svelte +3 -1
- package/package.json +137 -53
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,35 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
/**
|
|
2
|
+
* The SYSTEM layer — and deliberately nothing else.
|
|
3
|
+
*
|
|
4
|
+
* This used to be `export * from './ui/index.js'` plus the OS and AI
|
|
5
|
+
* namespaces: one import that could reach every component in the library. A
|
|
6
|
+
* barrel like that is a guarantee that the whole graph is reachable, and
|
|
7
|
+
* reachable is what matters — `import { Button } from '@signal9/era-ui'` put
|
|
8
|
+
* vidstack (4MB, needed by exactly one component nobody was rendering) into the
|
|
9
|
+
* module graph, where a production bundler MIGHT prove it away and a dev server
|
|
10
|
+
* pre-bundles it regardless. Selectivity that depends on a bundler proving
|
|
11
|
+
* purity is not selectivity; it is luck with good tooling.
|
|
12
|
+
*
|
|
13
|
+
* So the root now carries only what is genuinely cross-cutting and weightless:
|
|
14
|
+
* the class utilities every consumer composes with, the keybinding helpers, and
|
|
15
|
+
* the AXIS REGISTRY plus `Mode` — the design system's own contract, the thing
|
|
16
|
+
* you reach for to set up density/surface/corners/font/motion for a subtree.
|
|
17
|
+
* None of it imports a component; none of it imports a third-party runtime
|
|
18
|
+
* beyond clsx / tailwind-merge / tailwind-variants.
|
|
19
|
+
*
|
|
20
|
+
* Everything else is one import away, at its own entry point:
|
|
21
|
+
*
|
|
22
|
+
* import { Button } from '@signal9/era-ui/button';
|
|
23
|
+
* import * as Select from '@signal9/era-ui/select';
|
|
24
|
+
* import { Swarm } from '@signal9/era-ui/ai/swarm';
|
|
25
|
+
* import { Desktop } from '@signal9/era-ui/os';
|
|
26
|
+
* import { Notes } from '@signal9/era-ui/apps/notes';
|
|
27
|
+
* import { runAudit } from '@signal9/era-ui/audit';
|
|
28
|
+
*
|
|
29
|
+
* The `./*` wildcard in package.json means a new component is importable the
|
|
30
|
+
* moment it exists, with no export map to maintain — and it means no component
|
|
31
|
+
* can ever be pulled in by accident, because nothing re-exports them together.
|
|
32
|
+
*/
|
|
6
33
|
export { cn, tv, hotkeys, keys, parseKeybinding, matchKeyBindingPress, createKeybindingsHandler, formatKeybinding, isApplePlatform, modKey, type KeyBindingMap, type KeyBindingPress, type KeyBindingOptions, type PartProps, type VariantProps } from './utils/index.js';
|
|
34
|
+
export { modes, defaultMode, surfaces, defaultSurface, surfaceRegistry, corners, defaultCorners, fonts, defaultFont, motions, defaultMotion, axisRegistry, axisKeys, type Mode, type Surface, type SurfaceMeta, type Corners, type Font, type Motion, type AxisKey, type AxisMeta, type AxisLevel } from './ui/provider/index.js';
|
|
35
|
+
export { Mode as ModeProvider } from './ui/mode/index.js';
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,43 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
/**
|
|
2
|
+
* The SYSTEM layer — and deliberately nothing else.
|
|
3
|
+
*
|
|
4
|
+
* This used to be `export * from './ui/index.js'` plus the OS and AI
|
|
5
|
+
* namespaces: one import that could reach every component in the library. A
|
|
6
|
+
* barrel like that is a guarantee that the whole graph is reachable, and
|
|
7
|
+
* reachable is what matters — `import { Button } from '@signal9/era-ui'` put
|
|
8
|
+
* vidstack (4MB, needed by exactly one component nobody was rendering) into the
|
|
9
|
+
* module graph, where a production bundler MIGHT prove it away and a dev server
|
|
10
|
+
* pre-bundles it regardless. Selectivity that depends on a bundler proving
|
|
11
|
+
* purity is not selectivity; it is luck with good tooling.
|
|
12
|
+
*
|
|
13
|
+
* So the root now carries only what is genuinely cross-cutting and weightless:
|
|
14
|
+
* the class utilities every consumer composes with, the keybinding helpers, and
|
|
15
|
+
* the AXIS REGISTRY plus `Mode` — the design system's own contract, the thing
|
|
16
|
+
* you reach for to set up density/surface/corners/font/motion for a subtree.
|
|
17
|
+
* None of it imports a component; none of it imports a third-party runtime
|
|
18
|
+
* beyond clsx / tailwind-merge / tailwind-variants.
|
|
19
|
+
*
|
|
20
|
+
* Everything else is one import away, at its own entry point:
|
|
21
|
+
*
|
|
22
|
+
* import { Button } from '@signal9/era-ui/button';
|
|
23
|
+
* import * as Select from '@signal9/era-ui/select';
|
|
24
|
+
* import { Swarm } from '@signal9/era-ui/ai/swarm';
|
|
25
|
+
* import { Desktop } from '@signal9/era-ui/os';
|
|
26
|
+
* import { Notes } from '@signal9/era-ui/apps/notes';
|
|
27
|
+
* import { runAudit } from '@signal9/era-ui/audit';
|
|
28
|
+
*
|
|
29
|
+
* The `./*` wildcard in package.json means a new component is importable the
|
|
30
|
+
* moment it exists, with no export map to maintain — and it means no component
|
|
31
|
+
* can ever be pulled in by accident, because nothing re-exports them together.
|
|
32
|
+
*/
|
|
33
|
+
/* The composition utilities: `cn` for class merging (era-aware — it knows the
|
|
34
|
+
* tier/radius/shadow scales), `tv` for variants, and the keybinding layer. */
|
|
9
35
|
export { cn, tv, hotkeys, keys, parseKeybinding, matchKeyBindingPress, createKeybindingsHandler, formatKeybinding, isApplePlatform, modKey } from './utils/index.js';
|
|
36
|
+
/* The axis contract — the five orthogonal display axes, their levels, their
|
|
37
|
+
* defaults, and the registry that drives every picker built on top of them.
|
|
38
|
+
* Pure data: no component, no DOM, no dependency. */
|
|
39
|
+
export { modes, defaultMode, surfaces, defaultSurface, surfaceRegistry, corners, defaultCorners, fonts, defaultFont, motions, defaultMotion, axisRegistry, axisKeys } from './ui/provider/index.js';
|
|
40
|
+
/* `Mode` applies those axes (plus optional accent overrides) to a subtree. It
|
|
41
|
+
* is the one component that belongs here: it configures the system rather than
|
|
42
|
+
* being a piece of UI, and it imports nothing but types. */
|
|
43
|
+
export { Mode as ModeProvider } from './ui/mode/index.js';
|
package/dist/styles/index.css
CHANGED
|
@@ -11,21 +11,31 @@
|
|
|
11
11
|
@import './surfaces/bevel.css';
|
|
12
12
|
@import './typography.css';
|
|
13
13
|
|
|
14
|
-
/*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
14
|
+
/* WHAT IS NOT HERE: vidstack's stylesheets, which the VideoPlayer needs and
|
|
15
|
+
* nothing else does. They were imported right here, so every consumer of this
|
|
16
|
+
* file paid 46KB — 37% of the built stylesheet — for a component almost none of
|
|
17
|
+
* them render. They now live in ./video-player.css, published as
|
|
18
|
+
* `@signal9/era-ui/styles/video-player`, and only a consumer using the player
|
|
19
|
+
* imports them.
|
|
20
|
+
*
|
|
21
|
+
* The split is by DEPENDENCY WEIGHT, not by layer, and that is deliberate.
|
|
22
|
+
* Tailwind utilities DEDUPE — 60-odd components share one small vocabulary of
|
|
23
|
+
* flex/h-md/items-center, so scanning every layer below costs almost nothing
|
|
24
|
+
* and cannot be forgotten. Third-party CSS is the opposite: it is unshared,
|
|
25
|
+
* heavy, and belongs to exactly one component. Split what is unshared; keep
|
|
26
|
+
* what is shared whole. */
|
|
26
27
|
|
|
27
|
-
/*
|
|
28
|
+
/* Scan every SHIPPED layer for utility classes, not just ui.
|
|
29
|
+
*
|
|
30
|
+
* This read `@source '../ui'` alone, so a consumer on the source-CSS path got
|
|
31
|
+
* no utilities generated for any ai/, os/ or apps/ component — those rendered
|
|
32
|
+
* structurally correct and completely unstyled, silently. The scan follows the
|
|
33
|
+
* package's layers so that adding a layer means adding a line here, and
|
|
34
|
+
* nothing else. */
|
|
28
35
|
@source '../ui';
|
|
36
|
+
@source '../ai';
|
|
37
|
+
@source '../os';
|
|
38
|
+
@source '../apps';
|
|
29
39
|
|
|
30
40
|
/* Lucide icons use an SVG presentation attribute for stroke width by default.
|
|
31
41
|
* Set it from an Era token globally so every imported Lucide component tracks
|
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* NOTE PROSE — the document styling for a TipTap editor on era's tokens.
|
|
3
|
+
*
|
|
4
|
+
* Every rule hangs off `.era-notes-prose`, so it applies to any editor you put
|
|
5
|
+
* that class on: `NoteEditor` sets it itself, and a hand-rolled TipTap instance
|
|
6
|
+
* gets the same typography by adding the class and importing this file.
|
|
7
|
+
*
|
|
8
|
+
* It used to live in note-editor.svelte's <style> block, which made it
|
|
9
|
+
* unreachable: Svelte scopes a component's styles, so the built rule was
|
|
10
|
+
* `.era-notes-prose.svelte-r0lddw` and the class did nothing on anyone else's
|
|
11
|
+
* element. 364 lines of document typography — headings, code blocks with
|
|
12
|
+
* highlight.js tokens, task lists, tables, details, the first-line optical
|
|
13
|
+
* inset — were effectively private to one component. Now they are
|
|
14
|
+
* `@signal9/era-ui/styles/prose`.
|
|
15
|
+
*
|
|
16
|
+
* NoteEditor imports this itself, so mounting it still needs no CSS ceremony.
|
|
17
|
+
* Import it directly only when you are building your own editor.
|
|
18
|
+
*
|
|
19
|
+
* Everything is expressed in era tokens, so a document tracks the density,
|
|
20
|
+
* theme, surface, corners and font axes exactly like the chrome around it.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/*
|
|
24
|
+
* TipTap renders headless: the editable element it creates carries `.tiptap`,
|
|
25
|
+
* so every rule here is scoped to that inside this component's wrapper.
|
|
26
|
+
*
|
|
27
|
+
* Vertical rhythm is ONE value — --era-gap, the library's inter-element gap —
|
|
28
|
+
* on every block's bottom margin. A document then breathes at exactly the
|
|
29
|
+
* pace the surrounding chrome does, and loosens with density along with it.
|
|
30
|
+
*
|
|
31
|
+
* Font family is deliberately absent: the [data-font] axis sets it globally
|
|
32
|
+
* (with !important, by design), so anything declared here would either lose
|
|
33
|
+
* or break the axis promise.
|
|
34
|
+
*/
|
|
35
|
+
.era-notes-prose .tiptap {
|
|
36
|
+
outline: none;
|
|
37
|
+
min-height: 100%;
|
|
38
|
+
font-size: var(--era-text);
|
|
39
|
+
line-height: 1.6;
|
|
40
|
+
color: var(--color-fg);
|
|
41
|
+
|
|
42
|
+
/*
|
|
43
|
+
* The first line's half-leading is not padding, but it reads as padding.
|
|
44
|
+
*
|
|
45
|
+
* line-height 1.6 puts ~8px of empty box above the first glyph's cap, on
|
|
46
|
+
* top of the container's 8px inset — so the document opened 16px from the
|
|
47
|
+
* top and 8px from the left, an asymmetry that grows with the first
|
|
48
|
+
* block's font size (a note starting with a heading was the worst case).
|
|
49
|
+
*
|
|
50
|
+
* Trimming the block-start to the cap edge makes the ink itself sit on the
|
|
51
|
+
* container's inset, so the first thing you read has the same space above
|
|
52
|
+
* it as beside it, whatever block it happens to be. This is the block half
|
|
53
|
+
* of what era-text-trim does for single-line controls; only the START is
|
|
54
|
+
* trimmed, because the editor scrolls and trimming the end would put the
|
|
55
|
+
* last line's descenders past the scrollable area.
|
|
56
|
+
*
|
|
57
|
+
* Firefox has no text-box yet and keeps the untrimmed leading — the same
|
|
58
|
+
* graceful degradation era-text-trim already ships with.
|
|
59
|
+
*/
|
|
60
|
+
text-box-trim: trim-start;
|
|
61
|
+
text-box-edge: cap alphabetic;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/* The optical half of the trim. cap trimming is EXACT — the cap sits on the
|
|
65
|
+
* container inset to the pixel — but the LEFT side isn't: glyphs start with
|
|
66
|
+
* their side bearing (~0.07em of ink-free space inside the line box), so a
|
|
67
|
+
* geometrically-equal corner read top-tight. The first block gets that same
|
|
68
|
+
* allowance back as margin, in em so a heading's compensation scales with
|
|
69
|
+
* the heading — the corner then MEASURES slightly uneven and finally LOOKS
|
|
70
|
+
* even, which is the order optics always wins in.
|
|
71
|
+
*
|
|
72
|
+
* 0.22em, not the ~0.07em side-bearing alone: a first line is usually a
|
|
73
|
+
* heavy cap or a heading, and dense ink right at a boundary needs more
|
|
74
|
+
* room than a light vertical stem to feel equally far from it — the same
|
|
75
|
+
* reason display type sets its top margin above geometric equality. Tuned
|
|
76
|
+
* by eye against the left inset. */
|
|
77
|
+
.era-notes-prose .tiptap > :first-child {
|
|
78
|
+
margin-top: 0.22em;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/* FALLBACK for engines without text-box (Firefox): the trim above silently
|
|
82
|
+
* disappears there, and the first line opened ~0.47em too low (measured:
|
|
83
|
+
* cap 16.4px from the top against 8px from the left, dense/mono) — the
|
|
84
|
+
* exact asymmetry the trim exists to remove. Approximate the same cut with
|
|
85
|
+
* a negative first-block margin: -0.45em is the first line's half-leading
|
|
86
|
+
* (0.3em at line-height 1.6) plus the ascent-above-cap of the ui stacks
|
|
87
|
+
* (~0.15-0.17em). In em on purpose — it scales with the FIRST BLOCK's own
|
|
88
|
+
* size, so a note opening on an h1 and one opening on a paragraph both
|
|
89
|
+
* land their cap on the container inset, which one padding value could
|
|
90
|
+
* never do for both (the reference terminal app's pt-1 is this same idea,
|
|
91
|
+
* tuned only for paragraphs). The margin collapses up through .tiptap and
|
|
92
|
+
* stops at the scroll container's padding, which is where it should act.
|
|
93
|
+
* Within ~1px of the trimmed geometry; engines with text-box never match
|
|
94
|
+
* this block and keep the exact version. */
|
|
95
|
+
@supports not ((text-box-trim: trim-start) and (text-box-edge: cap alphabetic)) {
|
|
96
|
+
.era-notes-prose .tiptap > :first-child {
|
|
97
|
+
/* -0.45em of untrimmed leading, plus the same +0.22em optical
|
|
98
|
+
* allowance the trimmed path adds above. */
|
|
99
|
+
margin-top: -0.23em;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/* Placeholder, via @tiptap/extension-placeholder */
|
|
104
|
+
.era-notes-prose .tiptap p.is-editor-empty:first-child::before {
|
|
105
|
+
content: attr(data-placeholder);
|
|
106
|
+
float: left;
|
|
107
|
+
height: 0;
|
|
108
|
+
color: var(--color-muted);
|
|
109
|
+
pointer-events: none;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/* Typography */
|
|
113
|
+
.era-notes-prose .tiptap p {
|
|
114
|
+
margin: 0 0 var(--era-gap);
|
|
115
|
+
}
|
|
116
|
+
.era-notes-prose .tiptap p:last-child {
|
|
117
|
+
margin-bottom: 0;
|
|
118
|
+
}
|
|
119
|
+
.era-notes-prose .tiptap h1 {
|
|
120
|
+
font-size: 1.5em;
|
|
121
|
+
}
|
|
122
|
+
.era-notes-prose .tiptap h2 {
|
|
123
|
+
font-size: 1.25em;
|
|
124
|
+
}
|
|
125
|
+
.era-notes-prose .tiptap h3 {
|
|
126
|
+
font-size: 1.1em;
|
|
127
|
+
}
|
|
128
|
+
.era-notes-prose .tiptap h1,
|
|
129
|
+
.era-notes-prose .tiptap h2,
|
|
130
|
+
.era-notes-prose .tiptap h3 {
|
|
131
|
+
margin: 0 0 var(--era-gap);
|
|
132
|
+
font-weight: 600;
|
|
133
|
+
line-height: 1.6;
|
|
134
|
+
color: var(--color-bright);
|
|
135
|
+
}
|
|
136
|
+
.era-notes-prose .tiptap strong {
|
|
137
|
+
font-weight: 600;
|
|
138
|
+
color: var(--color-bright);
|
|
139
|
+
}
|
|
140
|
+
.era-notes-prose .tiptap em {
|
|
141
|
+
font-style: italic;
|
|
142
|
+
}
|
|
143
|
+
.era-notes-prose .tiptap s {
|
|
144
|
+
text-decoration: line-through;
|
|
145
|
+
text-decoration-thickness: 0.5px;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/* Code — inline chips take the xxs radius, blocks the lg one a Card uses. */
|
|
149
|
+
.era-notes-prose .tiptap code {
|
|
150
|
+
padding: 1px var(--era-inset-xxs);
|
|
151
|
+
border-radius: var(--era-rd-xxs);
|
|
152
|
+
background: var(--era-surface-bg-elevated);
|
|
153
|
+
}
|
|
154
|
+
.era-notes-prose .tiptap pre {
|
|
155
|
+
overflow-x: auto;
|
|
156
|
+
margin: 0 0 var(--era-gap);
|
|
157
|
+
padding: var(--era-inset-md);
|
|
158
|
+
border-radius: var(--era-rd-lg);
|
|
159
|
+
background: var(--color-surface);
|
|
160
|
+
box-shadow: var(--era-shadow);
|
|
161
|
+
}
|
|
162
|
+
.era-notes-prose .tiptap pre code {
|
|
163
|
+
padding: 0;
|
|
164
|
+
border-radius: 0;
|
|
165
|
+
background: transparent;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/* Syntax highlighting — the neutral scale, so it themes with everything else. */
|
|
169
|
+
.era-notes-prose .tiptap pre .hljs-keyword,
|
|
170
|
+
.era-notes-prose .tiptap pre .hljs-built_in {
|
|
171
|
+
color: var(--color-9);
|
|
172
|
+
}
|
|
173
|
+
.era-notes-prose .tiptap pre .hljs-string,
|
|
174
|
+
.era-notes-prose .tiptap pre .hljs-regexp {
|
|
175
|
+
color: var(--color-10);
|
|
176
|
+
}
|
|
177
|
+
.era-notes-prose .tiptap pre .hljs-number,
|
|
178
|
+
.era-notes-prose .tiptap pre .hljs-literal,
|
|
179
|
+
.era-notes-prose .tiptap pre .hljs-type,
|
|
180
|
+
.era-notes-prose .tiptap pre .hljs-class {
|
|
181
|
+
color: var(--color-11);
|
|
182
|
+
}
|
|
183
|
+
.era-notes-prose .tiptap pre .hljs-comment {
|
|
184
|
+
color: var(--color-8);
|
|
185
|
+
}
|
|
186
|
+
.era-notes-prose .tiptap pre .hljs-function,
|
|
187
|
+
.era-notes-prose .tiptap pre .hljs-title {
|
|
188
|
+
font-weight: 600;
|
|
189
|
+
color: var(--color-9);
|
|
190
|
+
}
|
|
191
|
+
.era-notes-prose .tiptap pre .hljs-variable,
|
|
192
|
+
.era-notes-prose .tiptap pre .hljs-attr {
|
|
193
|
+
color: var(--color-12);
|
|
194
|
+
}
|
|
195
|
+
.era-notes-prose .tiptap pre .hljs-params {
|
|
196
|
+
color: var(--color-11);
|
|
197
|
+
}
|
|
198
|
+
.era-notes-prose .tiptap pre .hljs-meta,
|
|
199
|
+
.era-notes-prose .tiptap pre .hljs-tag {
|
|
200
|
+
color: var(--color-10);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/* Blockquote */
|
|
204
|
+
.era-notes-prose .tiptap blockquote {
|
|
205
|
+
margin: 0 0 var(--era-gap);
|
|
206
|
+
padding-left: var(--era-inset-md);
|
|
207
|
+
border-left: 2px solid var(--era-divider-color);
|
|
208
|
+
color: var(--color-muted);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/* Lists */
|
|
212
|
+
.era-notes-prose .tiptap li,
|
|
213
|
+
.era-notes-prose .tiptap li p,
|
|
214
|
+
.era-notes-prose .tiptap ul,
|
|
215
|
+
.era-notes-prose .tiptap ol {
|
|
216
|
+
margin: 0;
|
|
217
|
+
}
|
|
218
|
+
.era-notes-prose .tiptap ul {
|
|
219
|
+
padding-left: 1.4em;
|
|
220
|
+
list-style-type: disc;
|
|
221
|
+
}
|
|
222
|
+
.era-notes-prose .tiptap ol {
|
|
223
|
+
padding-left: 1.9em;
|
|
224
|
+
list-style-type: decimal;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/* Task list — a checkbox styled like era's Checkbox, at the icon tier. */
|
|
228
|
+
.era-notes-prose .tiptap .task-list {
|
|
229
|
+
padding-left: 0;
|
|
230
|
+
list-style: none;
|
|
231
|
+
}
|
|
232
|
+
.era-notes-prose .tiptap .task-item {
|
|
233
|
+
display: flex;
|
|
234
|
+
gap: var(--era-gap);
|
|
235
|
+
}
|
|
236
|
+
.era-notes-prose .tiptap .task-item label {
|
|
237
|
+
/* Match the line box so the box centres against the first line of text. */
|
|
238
|
+
display: flex;
|
|
239
|
+
align-items: center;
|
|
240
|
+
height: calc(var(--era-text) * 1.6);
|
|
241
|
+
}
|
|
242
|
+
.era-notes-prose .tiptap .task-item input[type='checkbox'] {
|
|
243
|
+
flex-shrink: 0;
|
|
244
|
+
width: calc(var(--era-h-xs) - 4px);
|
|
245
|
+
height: calc(var(--era-h-xs) - 4px);
|
|
246
|
+
border-radius: var(--era-rd-xs);
|
|
247
|
+
background: var(--era-surface-bg-elevated);
|
|
248
|
+
box-shadow: var(--era-shadow-well);
|
|
249
|
+
appearance: none;
|
|
250
|
+
cursor: pointer;
|
|
251
|
+
transition:
|
|
252
|
+
background var(--era-duration) var(--era-ease),
|
|
253
|
+
box-shadow var(--era-duration) var(--era-ease);
|
|
254
|
+
}
|
|
255
|
+
.era-notes-prose .tiptap .task-item input[type='checkbox']:hover {
|
|
256
|
+
background: var(--era-highlight);
|
|
257
|
+
}
|
|
258
|
+
.era-notes-prose .tiptap .task-item input[type='checkbox']:checked {
|
|
259
|
+
background: var(--color-primary);
|
|
260
|
+
box-shadow: var(--era-shadow-pressed);
|
|
261
|
+
}
|
|
262
|
+
.era-notes-prose .tiptap .task-item[data-checked='true'] > div > p {
|
|
263
|
+
color: var(--color-muted);
|
|
264
|
+
text-decoration: line-through;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/* Horizontal rule */
|
|
268
|
+
.era-notes-prose .tiptap hr {
|
|
269
|
+
margin: var(--era-gap) 0;
|
|
270
|
+
border: none;
|
|
271
|
+
border-top: 1px solid var(--era-divider-color);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/* Links — the era-link recipe, inlined because ProseMirror owns this DOM. */
|
|
275
|
+
.era-notes-prose .tiptap a {
|
|
276
|
+
color: var(--color-link);
|
|
277
|
+
text-decoration-line: underline;
|
|
278
|
+
text-decoration-color: color-mix(in oklch, currentColor 30%, transparent);
|
|
279
|
+
text-underline-offset: 0.2em;
|
|
280
|
+
cursor: pointer;
|
|
281
|
+
transition: text-decoration-color var(--era-duration) var(--era-ease);
|
|
282
|
+
}
|
|
283
|
+
.era-notes-prose .tiptap a:hover {
|
|
284
|
+
text-decoration-color: currentColor;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/* Highlight — the warning token PAIR, not a wash of it.
|
|
288
|
+
*
|
|
289
|
+
* This was a 25% warning tint with `color: inherit`, which is two problems at
|
|
290
|
+
* once: at 25% the mark barely separates from the page, and pushing the alpha
|
|
291
|
+
* up to fix that puts light body text on yellow, which is worse. The pair
|
|
292
|
+
* exists for exactly this — warning-fg is dark in EVERY mode by design
|
|
293
|
+
* (see themes.css: yellow cannot carry light text), so a solid fill reads as
|
|
294
|
+
* a real highlighter and the text on it stays legible in both modes. */
|
|
295
|
+
.era-notes-prose .tiptap mark {
|
|
296
|
+
padding: 1px 0;
|
|
297
|
+
background: var(--color-warning);
|
|
298
|
+
color: var(--color-warning-fg);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/* Table */
|
|
302
|
+
.era-notes-prose .tiptap .note-table {
|
|
303
|
+
width: 100%;
|
|
304
|
+
margin: 0 0 var(--era-gap);
|
|
305
|
+
border-collapse: collapse;
|
|
306
|
+
table-layout: fixed;
|
|
307
|
+
}
|
|
308
|
+
.era-notes-prose .tiptap .note-table td,
|
|
309
|
+
.era-notes-prose .tiptap .note-table th {
|
|
310
|
+
padding: var(--era-inset-sm) var(--era-inset-md);
|
|
311
|
+
border: 1px solid var(--era-divider-color);
|
|
312
|
+
text-align: left;
|
|
313
|
+
vertical-align: top;
|
|
314
|
+
}
|
|
315
|
+
.era-notes-prose .tiptap .note-table th {
|
|
316
|
+
background: var(--color-surface);
|
|
317
|
+
font-weight: 600;
|
|
318
|
+
color: var(--color-bright);
|
|
319
|
+
}
|
|
320
|
+
.era-notes-prose .tiptap .note-table td > p,
|
|
321
|
+
.era-notes-prose .tiptap .note-table th > p {
|
|
322
|
+
margin: 0;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/* Details (collapsible) */
|
|
326
|
+
.era-notes-prose .tiptap details {
|
|
327
|
+
margin: 0 0 var(--era-gap);
|
|
328
|
+
padding: var(--era-inset-sm) var(--era-inset-md);
|
|
329
|
+
border-radius: var(--era-rd-md);
|
|
330
|
+
background: var(--era-surface-bg-elevated);
|
|
331
|
+
box-shadow: var(--era-shadow);
|
|
332
|
+
}
|
|
333
|
+
.era-notes-prose .tiptap details summary {
|
|
334
|
+
font-weight: 600;
|
|
335
|
+
color: var(--color-bright);
|
|
336
|
+
cursor: pointer;
|
|
337
|
+
}
|
|
338
|
+
.era-notes-prose .tiptap details > div {
|
|
339
|
+
margin-top: var(--era-gap);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/* Image */
|
|
343
|
+
.era-notes-prose .tiptap img {
|
|
344
|
+
max-width: 100%;
|
|
345
|
+
height: auto;
|
|
346
|
+
border-radius: var(--era-rd-md);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/*
|
|
350
|
+
* ProseMirror ships hardcoded selection colours (#8cf outlines, a black gap
|
|
351
|
+
* cursor, rgba(200,200,255,.4) cell selection, #adf resize handles). Each is
|
|
352
|
+
* overridden here or the editor shows chrome from a different design system.
|
|
353
|
+
*/
|
|
354
|
+
.era-notes-prose .tiptap .ProseMirror-selectednode {
|
|
355
|
+
outline: 2px solid var(--color-primary);
|
|
356
|
+
}
|
|
357
|
+
.era-notes-prose .tiptap li.ProseMirror-selectednode {
|
|
358
|
+
outline: none;
|
|
359
|
+
}
|
|
360
|
+
.era-notes-prose .tiptap li.ProseMirror-selectednode::after {
|
|
361
|
+
border-color: var(--color-primary);
|
|
362
|
+
}
|
|
363
|
+
.era-notes-prose .ProseMirror-gapcursor::after {
|
|
364
|
+
border-top-color: var(--color-primary);
|
|
365
|
+
}
|
|
366
|
+
.era-notes-prose .tiptap .selectedCell::after {
|
|
367
|
+
background: var(--era-highlight);
|
|
368
|
+
}
|
|
369
|
+
.era-notes-prose .tiptap .column-resize-handle {
|
|
370
|
+
background-color: var(--color-primary);
|
|
371
|
+
}
|
|
372
|
+
/* NO ::selection rule here, deliberately.
|
|
373
|
+
*
|
|
374
|
+
* era owns text selection as a surface token contract — --era-selection-bg /
|
|
375
|
+
* -fg / -shadow (surfaces/base.css), which is how flat gets inverse video,
|
|
376
|
+
* glass a glowing wash, and bevel an opaque accent bar. This file used to
|
|
377
|
+
* override it with `background: var(--color-4)` and no `color`, which threw
|
|
378
|
+
* all of that away AND left body text on a mid-scale grey: the band barely
|
|
379
|
+
* separated from the page and the glyphs sat on top of it at whatever
|
|
380
|
+
* contrast happened to fall out. Dropping the override restores both the
|
|
381
|
+
* contrast (bright fill, --color-1 glyphs) and the per-surface treatment.
|
|
382
|
+
*
|
|
383
|
+
* The ProseMirror overrides above are still needed — those replace hardcoded
|
|
384
|
+
* library chrome that no era token would otherwise reach. */
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* VideoPlayer's third-party stylesheets — vidstack's base layout plus the
|
|
3
|
+
* slider/button/menu primitives the component composes.
|
|
4
|
+
*
|
|
5
|
+
* Split out of index.css because it is 46KB that only one component needs:
|
|
6
|
+
* imported there, every consumer paid 37% of the built stylesheet for a player
|
|
7
|
+
* they never mounted. Everything here is scoped internally by vidstack to
|
|
8
|
+
* `:where(media-player)`, so it affects nothing outside a player subtree —
|
|
9
|
+
* which is exactly why it can be omitted safely.
|
|
10
|
+
*
|
|
11
|
+
* Import alongside the core stylesheet when (and only when) you render
|
|
12
|
+
* `VideoPlayer`:
|
|
13
|
+
*
|
|
14
|
+
* import '@signal9/era-ui/styles'; // always
|
|
15
|
+
* import '@signal9/era-ui/styles/video-player'; // only with the player
|
|
16
|
+
*
|
|
17
|
+
* Era's own token theming is applied on the component via CSS variables, not
|
|
18
|
+
* here, so this file is pure vendor CSS and needs no era imports.
|
|
19
|
+
*/
|
|
20
|
+
@import 'vidstack/styles/base.css';
|
|
21
|
+
@import 'vidstack/styles/ui/buttons.css';
|
|
22
|
+
@import 'vidstack/styles/ui/sliders.css';
|
|
23
|
+
@import 'vidstack/styles/ui/buffering.css';
|
|
24
|
+
@import 'vidstack/styles/ui/captions.css';
|
|
25
|
+
@import 'vidstack/styles/ui/live.css';
|
|
26
|
+
@import 'vidstack/styles/ui/menus.css';
|
|
27
|
+
@import 'vidstack/styles/ui/tooltips.css';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { Calendar } from 'bits-ui';
|
|
2
|
-
declare const CalendarRoot: import("svelte").Component<Calendar.RootProps, {}, "
|
|
2
|
+
declare const CalendarRoot: import("svelte").Component<Calendar.RootProps, {}, "placeholder" | "value" | "ref">;
|
|
3
3
|
type CalendarRoot = ReturnType<typeof CalendarRoot>;
|
|
4
4
|
export default CalendarRoot;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
declare const DateFieldRoot: import("svelte").Component<import("bits-ui").DateFieldRootPropsWithoutHTML, {}, "
|
|
1
|
+
declare const DateFieldRoot: import("svelte").Component<import("bits-ui").DateFieldRootPropsWithoutHTML, {}, "placeholder" | "value">;
|
|
2
2
|
type DateFieldRoot = ReturnType<typeof DateFieldRoot>;
|
|
3
3
|
export default DateFieldRoot;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
declare const DatePickerRoot: import("svelte").Component<import("bits-ui").DatePickerRootPropsWithoutHTML, {}, "
|
|
1
|
+
declare const DatePickerRoot: import("svelte").Component<import("bits-ui").DatePickerRootPropsWithoutHTML, {}, "placeholder" | "value" | "open">;
|
|
2
2
|
type DatePickerRoot = ReturnType<typeof DatePickerRoot>;
|
|
3
3
|
export default DatePickerRoot;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { DateRangeField } from 'bits-ui';
|
|
2
|
-
declare const DateRangeFieldRoot: import("svelte").Component<DateRangeField.RootProps, {}, "
|
|
2
|
+
declare const DateRangeFieldRoot: import("svelte").Component<DateRangeField.RootProps, {}, "placeholder" | "value" | "ref">;
|
|
3
3
|
type DateRangeFieldRoot = ReturnType<typeof DateRangeFieldRoot>;
|
|
4
4
|
export default DateRangeFieldRoot;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { DateRangePicker } from 'bits-ui';
|
|
2
|
-
declare const DateRangePickerRoot: import("svelte").Component<DateRangePicker.RootProps, {}, "
|
|
2
|
+
declare const DateRangePickerRoot: import("svelte").Component<DateRangePicker.RootProps, {}, "placeholder" | "value" | "open">;
|
|
3
3
|
type DateRangePickerRoot = ReturnType<typeof DateRangePickerRoot>;
|
|
4
4
|
export default DateRangePickerRoot;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { TimeField } from 'bits-ui';
|
|
2
|
-
declare const TimeFieldRoot: import("svelte").Component<TimeField.RootProps, {}, "
|
|
2
|
+
declare const TimeFieldRoot: import("svelte").Component<TimeField.RootProps, {}, "placeholder" | "value">;
|
|
3
3
|
type TimeFieldRoot = ReturnType<typeof TimeFieldRoot>;
|
|
4
4
|
export default TimeFieldRoot;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { TimeRangeField } from 'bits-ui';
|
|
2
|
-
declare const TimeRangeFieldRoot: import("svelte").Component<TimeRangeField.RootProps, {}, "
|
|
2
|
+
declare const TimeRangeFieldRoot: import("svelte").Component<TimeRangeField.RootProps, {}, "placeholder" | "value" | "ref">;
|
|
3
3
|
type TimeRangeFieldRoot = ReturnType<typeof TimeRangeFieldRoot>;
|
|
4
4
|
export default TimeRangeFieldRoot;
|
|
@@ -548,7 +548,9 @@
|
|
|
548
548
|
function handleSeekKeydown(e: KeyboardEvent) {
|
|
549
549
|
if (seekDisabled) return;
|
|
550
550
|
const base = readMediaTime() ?? currentTime;
|
|
551
|
-
|
|
551
|
+
// No initialiser: every arm below either assigns or returns, so one here
|
|
552
|
+
// would be dead — and eslint's no-useless-assignment says so.
|
|
553
|
+
let next: number;
|
|
552
554
|
switch (e.key) {
|
|
553
555
|
case 'ArrowLeft':
|
|
554
556
|
case 'ArrowDown':
|