@quillmark/svelte 0.3.0 → 0.3.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/NOTICE +6 -6
- package/README.md +1 -1
- package/THEMING.md +1 -1
- package/dist/core/bloom.d.ts +1 -30
- package/dist/core/bloom.js +13 -45
- package/dist/core/codec/prose.css +5 -6
- package/dist/core/theme.css +32 -16
- package/dist/preset/scale.css +4 -4
- package/dist/preview/Preview.svelte +6 -18
- package/dist/preview/Preview.svelte.d.ts +2 -3
- package/dist/preview/bridge.js +2 -2
- package/dist/preview/controller.d.ts +8 -10
- package/dist/preview/controller.js +16 -41
- package/dist/preview/geometry.d.ts +7 -9
- package/dist/preview/geometry.js +7 -9
- package/dist/preview/index.js +1 -1
- package/dist/preview/paint.d.ts +1 -1
- package/dist/preview/paint.js +5 -5
- package/dist/visual/Card.svelte +33 -28
- package/dist/visual/Card.svelte.d.ts +0 -1
- package/dist/visual/ProseField.svelte +17 -20
- package/dist/visual/ProseField.svelte.d.ts +1 -2
- package/dist/visual/TipsCard.svelte +49 -52
- package/dist/visual/VisualEditorInner.svelte +126 -206
- package/dist/visual/icons/nodes.d.ts +16 -0
- package/dist/visual/icons/nodes.js +11 -0
- package/package.json +2 -2
- package/dist/preview/overlay.d.ts +0 -11
- package/dist/preview/overlay.js +0 -97
package/dist/preview/geometry.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* An address's boxes: `fieldBoxes`'s union, else its own `regions()` rects, else the
|
|
3
|
-
* rects of everything under it.
|
|
4
|
-
*
|
|
5
|
-
* responsibilities").
|
|
3
|
+
* rects of everything under it. What the scroll reads, so an address `regions()`
|
|
4
|
+
* names is never one the preview cannot place (PREVIEW.md §"Two responsibilities").
|
|
6
5
|
*
|
|
7
6
|
* `fieldBoxes` answers `[]` for a scalar reference the plate places without tracking
|
|
8
7
|
* its content and for a `richtext[]` element; runtime.d.ts says what such a field's
|
|
@@ -20,8 +19,8 @@ export function boxesForField(field, boxes, regions) {
|
|
|
20
19
|
}
|
|
21
20
|
/**
|
|
22
21
|
* Forward: a PDF-pt rect -> CSS % of the page box. Percent positioning tracks
|
|
23
|
-
* the page's displayed size across DPR and container resize for free
|
|
24
|
-
*
|
|
22
|
+
* the page's displayed size across DPR and container resize for free, so the
|
|
23
|
+
* scroll's measurement needs no zoom or DPR term of its own (bridge.ts).
|
|
25
24
|
*/
|
|
26
25
|
export function rectToPercent(rect, pageSize) {
|
|
27
26
|
const [x0, y0, x1, y1] = rect;
|
|
@@ -34,10 +33,9 @@ export function rectToPercent(rect, pageSize) {
|
|
|
34
33
|
};
|
|
35
34
|
}
|
|
36
35
|
/**
|
|
37
|
-
* Position `el` absolutely at `pct` (the % rect this module produces)
|
|
38
|
-
* `PercentRect` → `element.style` write,
|
|
39
|
-
* the
|
|
40
|
-
* The caller sets any box chrome (border, background) on top.
|
|
36
|
+
* Position `el` absolutely at `pct` (the % rect this module produces): the one
|
|
37
|
+
* `PercentRect` → `element.style` write, so the positioning convention lives beside
|
|
38
|
+
* the transform that produces it rather than at the caller placing a marker.
|
|
41
39
|
*/
|
|
42
40
|
export function applyPercentRect(el, pct) {
|
|
43
41
|
Object.assign(el.style, {
|
package/dist/preview/index.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// (the codec, the VisualEditor) so a `@quillmark/preview` promotion stays a
|
|
6
6
|
// re-export, not a refactor: it may reach `/core` (the shared WASM boundary) and
|
|
7
7
|
// nothing else. Enforced by `check:deps`, which walks the subpath's import graph.
|
|
8
|
-
// The theme derivation, which the page slots
|
|
8
|
+
// The theme derivation, which the page slots read through `var()`.
|
|
9
9
|
// Imported at the barrel because a subpath is what a consumer gets: this surface
|
|
10
10
|
// reaches modules inside `core/` and never its entry, so a sheet hanging off that
|
|
11
11
|
// entry arrives only for a consumer importing `/core` for some other reason. The
|
package/dist/preview/paint.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { LiveSession, PageSize } from '@quillmark/wasm';
|
|
2
|
-
/** One page's DOM slot: the box
|
|
2
|
+
/** One page's DOM slot: the box bridge.ts measures against, plus its cached geometry. */
|
|
3
3
|
export interface PageSlot {
|
|
4
4
|
readonly page: number;
|
|
5
5
|
readonly size: PageSize;
|
package/dist/preview/paint.js
CHANGED
|
@@ -36,9 +36,9 @@ onPaintError) {
|
|
|
36
36
|
// The sheet is a plane and the desk is the one under it: paper sits at
|
|
37
37
|
// `--_qm-surface` and the container paints `--_qm-surface-sunken`, so the
|
|
38
38
|
// edge is where two tones meet and no stroke is drawn around it
|
|
39
|
-
// (ARCHITECTURE §Styling). It leaves the
|
|
40
|
-
//
|
|
41
|
-
//
|
|
39
|
+
// (ARCHITECTURE §Styling). It leaves the no-ink rule untouched, since a
|
|
40
|
+
// boundary that is not painted is not a mark on the page (PREVIEW §"Two
|
|
41
|
+
// responsibilities"). `border-box` costs nothing here and keeps a slot a
|
|
42
42
|
// consumer insets from measuring wider than its paper.
|
|
43
43
|
const el = document.createElement('div');
|
|
44
44
|
el.className = 'qm-page';
|
|
@@ -151,7 +151,7 @@ onPaintError) {
|
|
|
151
151
|
slots[i] = { ...slots[i], size };
|
|
152
152
|
// Keep the page box's shape in step with the re-read size: a recompile
|
|
153
153
|
// can change a page's dimensions without changing the count, and every
|
|
154
|
-
// %-space
|
|
154
|
+
// %-space click/scroll transform assumes box shape matches PageSize.
|
|
155
155
|
slots[i].el.style.aspectRatio = `${size.widthPt} / ${size.heightPt}`;
|
|
156
156
|
}
|
|
157
157
|
}
|
|
@@ -164,7 +164,7 @@ onPaintError) {
|
|
|
164
164
|
// Every paint freezes `canvas.style.width/height` to the box width at that
|
|
165
165
|
// paint (paintSlot). A page that stays mounted while the container's CSS width
|
|
166
166
|
// or `devicePixelRatio` shifts would otherwise keep a stale raster the %-space
|
|
167
|
-
//
|
|
167
|
+
// click/scroll math silently drifts off of: the box tracks the container, the
|
|
168
168
|
// ink does not. Two observers close the gap by repainting mounted pages from
|
|
169
169
|
// their current box; canvases are `position:absolute`, so a repaint can't feed
|
|
170
170
|
// back into layout (and thus can't re-trigger the resize observer).
|
package/dist/visual/Card.svelte
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
<!--
|
|
2
|
-
One card block
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
re-targets its commits without a remount.
|
|
2
|
+
One card block, its fields grouped by `ui.group`/`ui.compact`. `main` is headerless
|
|
3
|
+
and takes no controls. Every prose leaf takes a parent-built live address, so a card
|
|
4
|
+
reorder re-targets its commits without a remount.
|
|
6
5
|
-->
|
|
7
6
|
<script lang="ts">
|
|
8
7
|
import { wording } from './strings.js';
|
|
@@ -43,7 +42,6 @@
|
|
|
43
42
|
card: CardModel;
|
|
44
43
|
doc: Document;
|
|
45
44
|
quill: Quill;
|
|
46
|
-
index: number;
|
|
47
45
|
isFirst: boolean;
|
|
48
46
|
isLast: boolean;
|
|
49
47
|
kinds: string[];
|
|
@@ -61,7 +59,6 @@
|
|
|
61
59
|
card,
|
|
62
60
|
doc,
|
|
63
61
|
quill,
|
|
64
|
-
index,
|
|
65
62
|
isFirst,
|
|
66
63
|
isLast,
|
|
67
64
|
kinds,
|
|
@@ -91,8 +88,8 @@
|
|
|
91
88
|
(e.currentTarget as HTMLInputElement).select();
|
|
92
89
|
}
|
|
93
90
|
// A press on an unfocused title would place a caret on mouseup, collapsing the
|
|
94
|
-
// focus-time select-all.
|
|
95
|
-
//
|
|
91
|
+
// focus-time select-all. A press while already focused stays normal, so clicking
|
|
92
|
+
// mid-title to place the caret still works.
|
|
96
93
|
function onTitleMousedown(e: MouseEvent): void {
|
|
97
94
|
const el = e.currentTarget as HTMLInputElement;
|
|
98
95
|
if (document.activeElement !== el) {
|
|
@@ -100,9 +97,8 @@
|
|
|
100
97
|
el.focus();
|
|
101
98
|
}
|
|
102
99
|
}
|
|
103
|
-
// A press on the region's empty width enters the title edit
|
|
104
|
-
//
|
|
105
|
-
// to `onTitleMousedown`, which owns the already-focused caret-placement case.
|
|
100
|
+
// A press on the region's empty width enters the title edit, and starts no text
|
|
101
|
+
// selection on the wrapper. A press on the input itself is `onTitleMousedown`'s.
|
|
106
102
|
function onRenameMousedown(e: MouseEvent): void {
|
|
107
103
|
const input = (e.currentTarget as HTMLElement).querySelector('input');
|
|
108
104
|
if (!input || e.target === input) return;
|
|
@@ -136,10 +132,10 @@
|
|
|
136
132
|
// paint as a single stroke of twice the width.
|
|
137
133
|
const hasMeta = $derived(ungrouped.length > 0 || grouped.length > 0);
|
|
138
134
|
|
|
139
|
-
//
|
|
140
|
-
//
|
|
141
|
-
//
|
|
142
|
-
//
|
|
135
|
+
// Seeded once from the card's shape. Card is keyed by stable id, so this survives the
|
|
136
|
+
// VisualEditor re-derive that reassigns `card` and resets only on a remount. Not
|
|
137
|
+
// reconciled to later section changes: a retype is the one reshape, and the open
|
|
138
|
+
// group stays where it still exists.
|
|
143
139
|
// svelte-ignore state_referenced_locally
|
|
144
140
|
let expanded = $state<string | null>(initialExpandedGroup(card.sections));
|
|
145
141
|
let headers = $state<Record<string, HTMLButtonElement | undefined>>({});
|
|
@@ -162,10 +158,10 @@
|
|
|
162
158
|
}
|
|
163
159
|
|
|
164
160
|
/**
|
|
165
|
-
* Open the group holding leaf `key
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
*
|
|
161
|
+
* Open the group holding leaf `key`: a caret placed in a collapsed panel does not
|
|
162
|
+
* land at all. `VisualEditor.setCaret` calls this on every card and then waits a
|
|
163
|
+
* flush before landing, since `inert` clears when the panel renders open, not when
|
|
164
|
+
* `expanded` is assigned.
|
|
169
165
|
*
|
|
170
166
|
* A call, not a prop: a reveal is an event, and modelling it as state needs a
|
|
171
167
|
* fresh-identity wrapper to re-fire and an `untrack` to keep the per-keystroke
|
|
@@ -232,11 +228,10 @@
|
|
|
232
228
|
{/if}
|
|
233
229
|
|
|
234
230
|
<div class="qm-card-body">
|
|
235
|
-
<!--
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
empty wrapper between the two rules would collapse them onto each other. -->
|
|
231
|
+
<!-- One element whose top and bottom edges are the bracket's two horizontals.
|
|
232
|
+
Anchored here rather than on the header and on the accordion so an open section's
|
|
233
|
+
vertical reaches them, and so a card with no groups still terminates above its
|
|
234
|
+
body. -->
|
|
240
235
|
{#if hasMeta}
|
|
241
236
|
<div
|
|
242
237
|
class="qm-card-meta"
|
|
@@ -442,13 +437,17 @@
|
|
|
442
437
|
}
|
|
443
438
|
/* Autosize: the ::after mirrors the text into the same grid cell as the input, so the
|
|
444
439
|
overlaid input tracks its content width. Both carry the same nothing for a box model
|
|
445
|
-
and inherit the same type tokens, which is what makes the two measure alike.
|
|
440
|
+
and inherit the same type tokens, which is what makes the two measure alike.
|
|
441
|
+
|
|
442
|
+
The type is the group header's, down to the ink and its hover step below: a card
|
|
443
|
+
title and a section header both name a block of fields, so they read as one register
|
|
444
|
+
and what ranks them is position rather than a size step. */
|
|
446
445
|
.qm-card-title-sizer {
|
|
447
446
|
display: inline-grid;
|
|
448
447
|
align-items: center;
|
|
449
448
|
min-width: 0;
|
|
450
449
|
max-width: 100%;
|
|
451
|
-
font-size: var(--_qm-text-
|
|
450
|
+
font-size: var(--_qm-text-body);
|
|
452
451
|
font-weight: var(--_qm-weight-mid);
|
|
453
452
|
line-height: var(--_qm-leading-tight);
|
|
454
453
|
font-family: inherit;
|
|
@@ -620,11 +619,17 @@
|
|
|
620
619
|
The clip box takes the inline inset, which costs a shut panel no height and holds the
|
|
621
620
|
queried width still. The block inset goes on the content, where a `0fr` track clips
|
|
622
621
|
it: declared one box out it collapses the content but not itself, and stands under a
|
|
623
|
-
shut header as dead space. Neither is animated, and neither is qualified by open.
|
|
622
|
+
shut header as dead space. Neither is animated, and neither is qualified by open.
|
|
623
|
+
|
|
624
|
+
A field ends on the clip box at the end edge, where no inset hides its ring the way
|
|
625
|
+
the start edge's does. The pad carries the clip past it and the margin takes the same
|
|
626
|
+
distance back, so the width the fields are packed and queried at is unmoved. */
|
|
624
627
|
.qm-group-panel-inner {
|
|
625
628
|
min-height: 0;
|
|
626
629
|
overflow: hidden;
|
|
627
630
|
padding-inline-start: var(--_qm-space-4);
|
|
631
|
+
padding-inline-end: var(--_qm-ring-reach);
|
|
632
|
+
margin-inline-end: calc(-1 * var(--_qm-ring-reach));
|
|
628
633
|
}
|
|
629
634
|
.qm-group-panel-inner > .qm-fields {
|
|
630
635
|
padding-block: var(--_qm-space-2);
|
|
@@ -641,7 +646,7 @@
|
|
|
641
646
|
}
|
|
642
647
|
/* One typographic role with the editable title above. */
|
|
643
648
|
.qm-card-title-static {
|
|
644
|
-
font-size: var(--_qm-text-
|
|
649
|
+
font-size: var(--_qm-text-body);
|
|
645
650
|
font-weight: var(--_qm-weight-mid);
|
|
646
651
|
line-height: var(--_qm-leading-tight);
|
|
647
652
|
color: var(--_qm-ink-label);
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
<!--
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
with the caret riding the untouched view.
|
|
2
|
+
A Svelte mount of the codec's `createField` (VISUAL_EDITOR §Surface), which owns the
|
|
3
|
+
PM state, the history and the per-keystroke commit, leaving this wrapper wiring and
|
|
4
|
+
registration. `addr` is a live object the parent builds, so a card reorder re-targets
|
|
5
|
+
this leaf's commits with the caret riding the untouched view.
|
|
7
6
|
-->
|
|
8
7
|
<script lang="ts">
|
|
9
8
|
import { onMount } from 'svelte';
|
|
@@ -41,8 +40,7 @@
|
|
|
41
40
|
/** Ghost shown on the empty leaf: an inline leaf's resolved `default:` or
|
|
42
41
|
* nothing, a body's always text (`resolveBodyGhost`). */
|
|
43
42
|
placeholder?: string;
|
|
44
|
-
/**
|
|
45
|
-
* visible as one. */
|
|
43
|
+
/** Registry identity, stamped on the DOM node so a remount is visible as one. */
|
|
46
44
|
leafKey: string;
|
|
47
45
|
onFocus?: (addr: Addr) => void;
|
|
48
46
|
onCaretMove?: (addr: Addr, pos: number) => void;
|
|
@@ -79,9 +77,9 @@
|
|
|
79
77
|
// locale swap reaches a mounted table without remounting the leaf and losing the caret.
|
|
80
78
|
const t = wording();
|
|
81
79
|
|
|
82
|
-
/**
|
|
83
|
-
* the
|
|
84
|
-
*
|
|
80
|
+
/** Pushed by the leaf's trigger plugin: the menu is the leaf's surface rather than
|
|
81
|
+
* the shell's (VISUAL_EDITOR §Chrome). A constrained leaf never receives one, the
|
|
82
|
+
* trigger mounting on the block schema alone. */
|
|
85
83
|
let slash: SlashState | undefined = $state();
|
|
86
84
|
|
|
87
85
|
// The codec's own schema predicate (`createField`: `plaintext` implies `inline`), so
|
|
@@ -91,8 +89,8 @@
|
|
|
91
89
|
|
|
92
90
|
let controller: FieldController | undefined;
|
|
93
91
|
|
|
94
|
-
/**
|
|
95
|
-
*
|
|
92
|
+
/** What the label's click calls. The controller's focus, not the container's, which
|
|
93
|
+
* leaves the PM selection unplaced. */
|
|
96
94
|
export function focus(): void {
|
|
97
95
|
controller?.focus();
|
|
98
96
|
}
|
|
@@ -153,16 +151,15 @@
|
|
|
153
151
|
/* Containing block for the arrival wash's inset child (`core/bloom.ts`). */
|
|
154
152
|
position: relative;
|
|
155
153
|
}
|
|
156
|
-
/* A leaf the inline schema does not constrain
|
|
157
|
-
|
|
158
|
-
|
|
154
|
+
/* A leaf the inline schema does not constrain grows, and opens at one line box: the
|
|
155
|
+
empty leaf is the height its first line will take, so the first keystroke displaces
|
|
156
|
+
nothing below it. `1em`, not a size rung, which is the rule below's to name.
|
|
159
157
|
|
|
160
|
-
On the editable rather than on the wrapper, which is what makes
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
the end of it. */
|
|
158
|
+
On the editable rather than on the wrapper, which is what makes that line part of the
|
|
159
|
+
body: height the wrapper holds is height outside the `contenteditable`, where a press
|
|
160
|
+
lands no caret. */
|
|
164
161
|
.qm-prose-block :global(.ProseMirror) {
|
|
165
|
-
min-height: calc(1em * var(--_qm-leading-body)
|
|
162
|
+
min-height: calc(1em * var(--_qm-leading-body));
|
|
166
163
|
}
|
|
167
164
|
/* Paper, and the withheld box is what says so. Not `block` alone: `inline` is the
|
|
168
165
|
quill's to declare, so a schema omitting it on a richtext field puts a block leaf in
|
|
@@ -28,8 +28,7 @@ interface Props {
|
|
|
28
28
|
/** Ghost shown on the empty leaf: an inline leaf's resolved `default:` or
|
|
29
29
|
* nothing, a body's always text (`resolveBodyGhost`). */
|
|
30
30
|
placeholder?: string;
|
|
31
|
-
/**
|
|
32
|
-
* visible as one. */
|
|
31
|
+
/** Registry identity, stamped on the DOM node so a remount is visible as one. */
|
|
33
32
|
leafKey: string;
|
|
34
33
|
onFocus?: (addr: Addr) => void;
|
|
35
34
|
onCaretMove?: (addr: Addr, pos: number) => void;
|
|
@@ -81,13 +81,11 @@
|
|
|
81
81
|
{/each}
|
|
82
82
|
</div>
|
|
83
83
|
{/if}
|
|
84
|
-
<!-- One button, and its action is where the cursor stands: the set is walked,
|
|
85
|
-
and its end is the exit. -->
|
|
86
84
|
<button type="button" class="qm-icon-btn qm-tips-action" onclick={advance}>
|
|
87
85
|
{#if isLast}
|
|
88
|
-
{t.strings.tipsDismiss} <Icon name="
|
|
86
|
+
{t.strings.tipsDismiss} <Icon name="trash-2" size={GLYPH} />
|
|
89
87
|
{:else}
|
|
90
|
-
{t.strings.tipsNext} <Icon name="
|
|
88
|
+
{t.strings.tipsNext} <Icon name="arrow-right" size={GLYPH} />
|
|
91
89
|
{/if}
|
|
92
90
|
</button>
|
|
93
91
|
</div>
|
|
@@ -100,41 +98,36 @@
|
|
|
100
98
|
guidance is: the main card's, not a card of its own. Still in-flow, no edge, no
|
|
101
99
|
lift.
|
|
102
100
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
document. Both come off the tips rungs (`core/theme.css`), which are mixes over
|
|
106
|
-
the surface and the ink the consumer already tuned, so the card cannot end up less
|
|
107
|
-
legible than the editor around it.
|
|
101
|
+
The bottom corners take the inner rung where the card above takes the outer: a slip
|
|
102
|
+
is cut crisper than the thing it is tucked under, at every setting of the dial.
|
|
108
103
|
|
|
109
|
-
The
|
|
110
|
-
the foot
|
|
111
|
-
|
|
112
|
-
The reading rungs, size and leading both: a tip is a passage that wraps, so it
|
|
113
|
-
takes the size a field's value is read at rather than the label rung a line of
|
|
114
|
-
chrome would take. */
|
|
104
|
+
The insets are asymmetric so the ink is not: the top takes the tuck back, and the
|
|
105
|
+
bottom gives up a rung to the foot's control, whose box stands on the tap floor
|
|
106
|
+
rather than on its own one-line label. */
|
|
115
107
|
.qm-tips {
|
|
116
108
|
margin-top: calc(var(--_qm-radius) * -1);
|
|
117
|
-
border-radius: 0 0 var(--_qm-radius) var(--_qm-radius);
|
|
118
|
-
padding: calc(var(--_qm-space-3) + var(--_qm-radius)) var(--_qm-space-3) var(--_qm-space-
|
|
109
|
+
border-radius: 0 0 var(--_qm-radius-inner) var(--_qm-radius-inner);
|
|
110
|
+
padding: calc(var(--_qm-space-3) + var(--_qm-radius)) var(--_qm-space-3) var(--_qm-space-2);
|
|
119
111
|
background: var(--_qm-tips-surface);
|
|
120
112
|
display: flex;
|
|
121
113
|
flex-direction: column;
|
|
122
114
|
gap: var(--_qm-space-2);
|
|
123
|
-
font-family: var(--_qm-font
|
|
115
|
+
font-family: var(--_qm-tips-font);
|
|
124
116
|
font-size: var(--_qm-text-body);
|
|
125
117
|
line-height: var(--_qm-leading-body);
|
|
126
118
|
color: var(--_qm-tips-ink);
|
|
127
119
|
}
|
|
120
|
+
/* One line held open, so the foot does not step up under a shorter tip. */
|
|
121
|
+
.qm-tips-body {
|
|
122
|
+
min-height: calc(var(--_qm-leading-body) * 1em);
|
|
123
|
+
}
|
|
128
124
|
/* The rendered tip is injected DOM (the codec's `toDOM` output), so its element
|
|
129
125
|
styles are `:global`: the compiler never sees these tags in the markup. Restated
|
|
130
126
|
from `core/codec/prose.css`, which is where they are argued and which cannot reach
|
|
131
|
-
here: its selectors are scoped to `.ProseMirror` and a tip is not a view.
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
already the card's own and a token like `- ` has nothing else to set it apart.
|
|
136
|
-
`pre-wrap` is what keeps the significant space inside such a token: collapsed, the
|
|
137
|
-
chip closes on the word after it. */
|
|
127
|
+
here: its selectors are scoped to `.ProseMirror` and a tip is not a view. The one
|
|
128
|
+
divergence: `code` takes a chip and a warmer ink where a leaf gives it a face, the
|
|
129
|
+
face here being the card's own already. `pre-wrap` keeps the significant space
|
|
130
|
+
inside a token like `- `; collapsed, the chip closes on the word after it. */
|
|
138
131
|
.qm-tips-body :global(p) {
|
|
139
132
|
margin: 0;
|
|
140
133
|
}
|
|
@@ -142,12 +135,14 @@
|
|
|
142
135
|
font-family: inherit;
|
|
143
136
|
font-size: inherit;
|
|
144
137
|
white-space: pre-wrap;
|
|
145
|
-
padding: 0 var(--_qm-space
|
|
138
|
+
padding: 0 var(--_qm-space);
|
|
146
139
|
border-radius: var(--_qm-radius-inner);
|
|
147
|
-
background: var(--_qm-tips-
|
|
140
|
+
background: var(--_qm-tips-fill);
|
|
141
|
+
color: var(--_qm-tips-ink-warm);
|
|
148
142
|
}
|
|
149
143
|
.qm-tips-body :global(a) {
|
|
150
144
|
color: inherit;
|
|
145
|
+
text-decoration: underline;
|
|
151
146
|
}
|
|
152
147
|
.qm-tips-foot {
|
|
153
148
|
display: flex;
|
|
@@ -158,49 +153,51 @@
|
|
|
158
153
|
.qm-tips-dots {
|
|
159
154
|
display: flex;
|
|
160
155
|
align-items: center;
|
|
156
|
+
gap: var(--_qm-space-half);
|
|
161
157
|
margin-right: auto;
|
|
162
158
|
}
|
|
163
|
-
/* Random access to the set,
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
159
|
+
/* Random access to the set, drawn as one cluster: a row of marks spaced to the tap
|
|
160
|
+
floor reads as a row of controls. So the target is the mark plus its padding, under
|
|
161
|
+
the floor, which 2.5.8 allows on the equivalent-control exception rather than on
|
|
162
|
+
the spacing one — the foot's button clears the floor and walks the whole set from
|
|
163
|
+
the tip the card opens on, so no tip is reachable only by a dot. State is three
|
|
164
|
+
steps of one ink on the recede ladder, never a second hue and never a size: a dot
|
|
165
|
+
that grew would move the row it sits in. */
|
|
169
166
|
.qm-tips-dot {
|
|
170
|
-
|
|
171
|
-
align-items: center;
|
|
172
|
-
justify-content: center;
|
|
173
|
-
box-sizing: border-box;
|
|
174
|
-
min-width: var(--_qm-tap-min);
|
|
175
|
-
min-height: var(--_qm-tap-min);
|
|
176
|
-
border: none;
|
|
177
|
-
background: transparent;
|
|
178
|
-
cursor: pointer;
|
|
179
|
-
}
|
|
180
|
-
/* Three steps of one ink on the recede ladder (rest, hover, current), never a
|
|
181
|
-
second hue and never a size: a dot that grew would move the row it sits in. */
|
|
182
|
-
.qm-tips-dot::before {
|
|
183
|
-
content: '';
|
|
167
|
+
box-sizing: content-box;
|
|
184
168
|
width: 5px;
|
|
185
169
|
height: 5px;
|
|
170
|
+
padding: var(--_qm-space-half);
|
|
171
|
+
border: none;
|
|
186
172
|
border-radius: var(--_qm-radius-pill);
|
|
187
173
|
background: currentColor;
|
|
174
|
+
background-clip: content-box;
|
|
188
175
|
opacity: var(--_qm-opacity-idle);
|
|
176
|
+
cursor: pointer;
|
|
189
177
|
transition: opacity var(--_qm-duration-fast) var(--_qm-ease-reverse);
|
|
190
178
|
}
|
|
191
|
-
.qm-tips-dot:hover
|
|
179
|
+
.qm-tips-dot:hover {
|
|
192
180
|
opacity: var(--_qm-opacity-muted);
|
|
193
181
|
}
|
|
194
|
-
.qm-tips-dot[aria-current='true']
|
|
182
|
+
.qm-tips-dot[aria-current='true'] {
|
|
195
183
|
opacity: 1;
|
|
196
184
|
}
|
|
197
|
-
/* Box and disabled state come from `.qm-icon-btn` (controls.css);
|
|
198
|
-
|
|
199
|
-
|
|
185
|
+
/* Box and disabled state come from `.qm-icon-btn` (controls.css); what this
|
|
186
|
+
overrides is everything the family sets for a glyph among callers of its own
|
|
187
|
+
colour, a labelled control on a warm card wanting none of it. The hover included:
|
|
188
|
+
the family's neutral step would read as lent from the document above. Unlayered,
|
|
189
|
+
so it beats the base rule without out-specifying it. */
|
|
200
190
|
.qm-tips-action {
|
|
201
191
|
padding: var(--_qm-space-half) var(--_qm-space-2);
|
|
202
192
|
font-family: inherit;
|
|
203
193
|
font-size: inherit;
|
|
204
194
|
color: inherit;
|
|
195
|
+
transition:
|
|
196
|
+
color var(--_qm-duration-fast) var(--_qm-ease-reverse),
|
|
197
|
+
background-color var(--_qm-duration-fast) var(--_qm-ease-reverse);
|
|
198
|
+
}
|
|
199
|
+
.qm-tips-action:hover {
|
|
200
|
+
color: var(--_qm-tips-ink-warm);
|
|
201
|
+
background: var(--_qm-tips-fill);
|
|
205
202
|
}
|
|
206
203
|
</style>
|