@quillmark/svelte 0.1.1 → 0.3.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/README.md +16 -12
- package/THEMING.md +48 -25
- package/dist/core/address.d.ts +42 -7
- package/dist/core/address.js +49 -21
- package/dist/core/bloom.d.ts +5 -5
- package/dist/core/bloom.js +8 -8
- package/dist/core/codec/anchor.d.ts +1 -1
- package/dist/core/codec/anchor.js +1 -1
- package/dist/core/codec/atoms.d.ts +10 -0
- package/dist/core/codec/atoms.js +78 -0
- package/dist/core/codec/clipboard.d.ts +59 -0
- package/dist/core/codec/clipboard.js +202 -0
- package/dist/core/codec/code.d.ts +1 -1
- package/dist/core/codec/code.js +4 -4
- package/dist/core/codec/decode.d.ts +1 -1
- package/dist/core/codec/decode.js +8 -8
- package/dist/core/codec/encode.d.ts +4 -4
- package/dist/core/codec/encode.js +14 -11
- package/dist/core/codec/field.d.ts +22 -27
- package/dist/core/codec/field.js +33 -32
- package/dist/core/codec/index.js +5 -8
- package/dist/core/codec/inputrules.js +56 -18
- package/dist/core/codec/islands.d.ts +11 -7
- package/dist/core/codec/islands.js +16 -10
- package/dist/core/codec/keymap.d.ts +5 -6
- package/dist/core/codec/keymap.js +8 -7
- package/dist/core/codec/lists.d.ts +3 -3
- package/dist/core/codec/lists.js +32 -13
- package/dist/core/codec/marks.d.ts +1 -1
- package/dist/core/codec/marks.js +1 -1
- package/dist/core/codec/positions.js +1 -1
- package/dist/core/codec/prose.css +266 -228
- package/dist/core/codec/schema.js +4 -4
- package/dist/core/codec/slash.d.ts +39 -41
- package/dist/core/codec/slash.js +0 -0
- package/dist/core/codec/table-view.d.ts +12 -16
- package/dist/core/codec/table-view.js +488 -292
- package/dist/core/codec/table.d.ts +42 -15
- package/dist/core/codec/table.js +73 -27
- package/dist/core/errors.d.ts +17 -7
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.js +6 -5
- package/dist/core/lifecycle.d.ts +21 -5
- package/dist/core/lifecycle.js +34 -8
- package/dist/core/rebind.svelte.d.ts +18 -4
- package/dist/core/rebind.svelte.js +30 -12
- package/dist/core/teardown.d.ts +1 -1
- package/dist/core/teardown.js +1 -1
- package/dist/core/theme.css +173 -58
- package/dist/preset/index.css +1 -1
- package/dist/preset/recipes.css +79 -30
- package/dist/preset/scale.css +40 -28
- package/dist/preview/Preview.svelte +22 -19
- package/dist/preview/Preview.svelte.d.ts +8 -8
- package/dist/preview/bridge.d.ts +6 -4
- package/dist/preview/bridge.js +19 -9
- package/dist/preview/controller.d.ts +13 -6
- package/dist/preview/controller.js +8 -5
- package/dist/preview/geometry.d.ts +17 -2
- package/dist/preview/geometry.js +21 -1
- package/dist/preview/index.d.ts +1 -0
- package/dist/preview/index.js +9 -2
- package/dist/preview/overlay.d.ts +2 -1
- package/dist/preview/overlay.js +26 -11
- package/dist/preview/paint.js +19 -17
- package/dist/visual/ArrayField.svelte +103 -83
- package/dist/visual/ArrayField.svelte.d.ts +5 -4
- package/dist/visual/BooleanField.svelte +8 -6
- package/dist/visual/BooleanField.svelte.d.ts +2 -2
- package/dist/visual/Card.svelte +161 -333
- package/dist/visual/Card.svelte.d.ts +5 -4
- package/dist/visual/CardControls.svelte +1 -1
- package/dist/visual/DateField.svelte +19 -19
- package/dist/visual/DateField.svelte.d.ts +3 -3
- package/dist/visual/DiagnosticList.svelte +2 -2
- package/dist/visual/EnumField.svelte +48 -28
- package/dist/visual/EnumField.svelte.d.ts +5 -4
- package/dist/visual/Field.svelte +207 -132
- package/dist/visual/Field.svelte.d.ts +11 -7
- package/dist/visual/FieldHint.svelte +79 -48
- package/dist/visual/FieldHint.svelte.d.ts +1 -1
- package/dist/visual/FieldLabel.svelte +8 -8
- package/dist/visual/FormatPopover.svelte +82 -35
- package/dist/visual/NumberField.svelte +5 -5
- package/dist/visual/NumberField.svelte.d.ts +1 -1
- package/dist/visual/ObjectField.svelte +28 -9
- package/dist/visual/ObjectField.svelte.d.ts +4 -2
- package/dist/visual/ProseArrayElement.svelte +12 -19
- package/dist/visual/ProseArrayElement.svelte.d.ts +1 -2
- package/dist/visual/ProseField.svelte +62 -85
- package/dist/visual/ProseField.svelte.d.ts +14 -17
- package/dist/visual/SlashMenu.svelte +42 -16
- package/dist/visual/TextField.svelte +5 -5
- package/dist/visual/TextField.svelte.d.ts +1 -1
- package/dist/visual/TipsCard.svelte +43 -28
- package/dist/visual/VisualEditor.svelte +18 -19
- package/dist/visual/VisualEditor.svelte.d.ts +2 -3
- package/dist/visual/VisualEditorInner.svelte +251 -184
- package/dist/visual/VisualEditorInner.svelte.d.ts +2 -3
- package/dist/visual/controls.css +85 -38
- package/dist/visual/diagnostics.d.ts +13 -21
- package/dist/visual/diagnostics.js +7 -19
- package/dist/visual/domid.js +3 -3
- package/dist/visual/ext.d.ts +1 -1
- package/dist/visual/ext.js +1 -1
- package/dist/visual/icons/nodes.d.ts +3 -0
- package/dist/visual/icons/nodes.js +2 -1
- package/dist/visual/index.d.ts +1 -0
- package/dist/visual/index.js +10 -3
- package/dist/visual/leaves.d.ts +47 -0
- package/dist/visual/leaves.js +31 -0
- package/dist/visual/links.d.ts +24 -0
- package/dist/visual/links.js +67 -0
- package/dist/visual/props.d.ts +33 -12
- package/dist/visual/signals.d.ts +6 -6
- package/dist/visual/strings.d.ts +14 -19
- package/dist/visual/strings.js +5 -7
- package/dist/visual/structure.d.ts +24 -17
- package/dist/visual/structure.js +8 -8
- package/dist/visual/synced.svelte.d.ts +1 -1
- package/dist/visual/synced.svelte.js +4 -4
- package/dist/visual/tips.d.ts +4 -2
- package/dist/visual/tips.js +7 -4
- package/package.json +2 -2
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
<!--
|
|
2
|
-
A `string` field → text input. Commits a non-empty edit
|
|
2
|
+
A `string` field → text input. Commits a non-empty edit live (on input) via the
|
|
3
3
|
parent's typed `writer.set`, so the preview tracks typing. A cleared field is the
|
|
4
|
-
|
|
4
|
+
unset rung of the commitment ladder (VISUAL_EDITOR §"Structure mirrors the schema"): it
|
|
5
5
|
commits `undefined` (the parent removes the field, ghosted `default:` renders):
|
|
6
|
-
but at `change` (blur),
|
|
6
|
+
but at `change` (blur), not per keystroke, so select-all-and-retype doesn't flash
|
|
7
7
|
the field through its default between the delete and the first typed char.
|
|
8
|
-
Trade-off (recorded in VISUAL_EDITOR): an explicit empty string
|
|
8
|
+
Trade-off (recorded in VISUAL_EDITOR): an explicit empty string over a non-empty
|
|
9
9
|
default is inexpressible from the UI: clear and unset collapse to one gesture.
|
|
10
10
|
-->
|
|
11
11
|
<script lang="ts">
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
interface Props {
|
|
16
16
|
value: string | undefined;
|
|
17
17
|
placeholder?: string;
|
|
18
|
-
/** Accessible name for an input
|
|
18
|
+
/** Accessible name for an input nothing else names: an array element, whose
|
|
19
19
|
* name is the field label plus its 1-based index. A field's own input takes
|
|
20
20
|
* `id` instead and is named by the `<label for>` beside it. */
|
|
21
21
|
label?: string;
|
|
@@ -2,7 +2,7 @@ import './controls.css';
|
|
|
2
2
|
interface Props {
|
|
3
3
|
value: string | undefined;
|
|
4
4
|
placeholder?: string;
|
|
5
|
-
/** Accessible name for an input
|
|
5
|
+
/** Accessible name for an input nothing else names: an array element, whose
|
|
6
6
|
* name is the field label plus its 1-based index. A field's own input takes
|
|
7
7
|
* `id` instead and is named by the `<label for>` beside it. */
|
|
8
8
|
label?: string;
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
The ephemeral tips card. Renders the
|
|
3
3
|
`$ext.editor.tips` channel one tip at a time: dots reach any tip in the set, and the
|
|
4
4
|
foot's one button advances until the last, where it becomes the dismiss. Dismissal
|
|
5
|
-
|
|
5
|
+
clears the channel in the Document, so the card is gone and does not reappear.
|
|
6
6
|
|
|
7
|
-
The cursor is
|
|
7
|
+
The cursor is local state, not the channel. Advancing writes nothing: a per-tip
|
|
8
8
|
write would round-trip the boundary, re-derive the card tree, and dirty the
|
|
9
9
|
document (firing a consumer's autosave) on what is a read gesture. Exactly one
|
|
10
10
|
write happens, at dismissal, and this component unmounts with it, so the cursor
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
const index = $derived(Math.min(cursor, tips.length - 1));
|
|
41
41
|
const isLast = $derived(index >= tips.length - 1);
|
|
42
42
|
|
|
43
|
-
// The tip
|
|
43
|
+
// The tip string is derived before the effect reads it, and that is load-bearing.
|
|
44
44
|
// Reading `tips[index]` inside the effect makes the parent's `model` derive the
|
|
45
45
|
// dependency (a fresh object every `revision` bump) so the effect would re-run
|
|
46
46
|
// on every unrelated commit, re-crossing the WASM boundary and rebuilding this
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
{/each}
|
|
82
82
|
</div>
|
|
83
83
|
{/if}
|
|
84
|
-
<!--
|
|
84
|
+
<!-- One button, and its action is where the cursor stands: the set is walked,
|
|
85
85
|
and its end is the exit. -->
|
|
86
86
|
<button type="button" class="qm-icon-btn qm-tips-action" onclick={advance}>
|
|
87
87
|
{#if isLast}
|
|
@@ -94,44 +94,57 @@
|
|
|
94
94
|
</aside>
|
|
95
95
|
|
|
96
96
|
<style>
|
|
97
|
-
/*
|
|
97
|
+
/* Attached to `main`, not a block beside it: a square top pulled up by the radius,
|
|
98
98
|
so its background fills the notches `main`'s rounded bottom corners cut and `main`
|
|
99
|
-
paints over the rest. The
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
99
|
+
paints over the rest. The two read as one block, which is what document-level
|
|
100
|
+
guidance is: the main card's, not a card of its own. Still in-flow, no edge, no
|
|
101
|
+
lift.
|
|
102
|
+
|
|
103
|
+
A typewritten slip, and that is the whole of the treatment: the monospace face and
|
|
104
|
+
a warmth over the card's own surface, which together say draft rather than
|
|
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.
|
|
105
108
|
|
|
106
109
|
The top inset takes the tuck back, so the space above the tip is the space below
|
|
107
110
|
the foot.
|
|
108
111
|
|
|
109
|
-
|
|
110
|
-
|
|
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. */
|
|
111
115
|
.qm-tips {
|
|
112
116
|
margin-top: calc(var(--_qm-radius) * -1);
|
|
113
|
-
border: var(--_qm-border-width) solid var(--_qm-border);
|
|
114
117
|
border-radius: 0 0 var(--_qm-radius) var(--_qm-radius);
|
|
115
118
|
padding: calc(var(--_qm-space-3) + var(--_qm-radius)) var(--_qm-space-3) var(--_qm-space-3);
|
|
116
|
-
background: var(--_qm-surface
|
|
119
|
+
background: var(--_qm-tips-surface);
|
|
117
120
|
display: flex;
|
|
118
121
|
flex-direction: column;
|
|
119
122
|
gap: var(--_qm-space-2);
|
|
120
|
-
font-
|
|
123
|
+
font-family: var(--_qm-font-mono);
|
|
124
|
+
font-size: var(--_qm-text-body);
|
|
121
125
|
line-height: var(--_qm-leading-body);
|
|
122
|
-
color: var(--_qm-ink
|
|
126
|
+
color: var(--_qm-tips-ink);
|
|
123
127
|
}
|
|
124
128
|
/* The rendered tip is injected DOM (the codec's `toDOM` output), so its element
|
|
125
|
-
styles are `:global`: the compiler never sees these tags in the markup.
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
129
|
+
styles are `:global`: the compiler never sees these tags in the markup. Restated
|
|
130
|
+
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. Two
|
|
132
|
+
deliberate divergences, and both follow from the card being read rather than
|
|
133
|
+
edited: the link takes no underline, since a hidden `href` costs its reader
|
|
134
|
+
nothing; and `code` takes a chip where a leaf gives it a face, since the face is
|
|
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. */
|
|
130
138
|
.qm-tips-body :global(p) {
|
|
131
139
|
margin: 0;
|
|
132
140
|
}
|
|
133
141
|
.qm-tips-body :global(code) {
|
|
134
|
-
font-family:
|
|
142
|
+
font-family: inherit;
|
|
143
|
+
font-size: inherit;
|
|
144
|
+
white-space: pre-wrap;
|
|
145
|
+
padding: 0 var(--_qm-space-half);
|
|
146
|
+
border-radius: var(--_qm-radius-inner);
|
|
147
|
+
background: var(--_qm-tips-chip);
|
|
135
148
|
}
|
|
136
149
|
.qm-tips-body :global(a) {
|
|
137
150
|
color: inherit;
|
|
@@ -147,7 +160,7 @@
|
|
|
147
160
|
align-items: center;
|
|
148
161
|
margin-right: auto;
|
|
149
162
|
}
|
|
150
|
-
/* Random access to the set, and the
|
|
163
|
+
/* Random access to the set, and the pitch is the tap floor: 2.5.8's spacing
|
|
151
164
|
exception measures centre distance, which is the number the floor already fixes,
|
|
152
165
|
so a tighter row of dots buys nothing it does not immediately owe back. Target and
|
|
153
166
|
mark are therefore not one rectangle (the floor is the button, the dot is drawn
|
|
@@ -164,7 +177,7 @@
|
|
|
164
177
|
background: transparent;
|
|
165
178
|
cursor: pointer;
|
|
166
179
|
}
|
|
167
|
-
/* Three steps of
|
|
180
|
+
/* Three steps of one ink on the recede ladder (rest, hover, current), never a
|
|
168
181
|
second hue and never a size: a dot that grew would move the row it sits in. */
|
|
169
182
|
.qm-tips-dot::before {
|
|
170
183
|
content: '';
|
|
@@ -182,10 +195,12 @@
|
|
|
182
195
|
opacity: 1;
|
|
183
196
|
}
|
|
184
197
|
/* Box and disabled state come from `.qm-icon-btn` (controls.css); the foot's
|
|
185
|
-
button carries a label
|
|
198
|
+
button carries a label, so it widens its inset and stays on the card's own type
|
|
199
|
+
and ink rather than the family's body rung and the callers' own colours. */
|
|
186
200
|
.qm-tips-action {
|
|
187
201
|
padding: var(--_qm-space-half) var(--_qm-space-2);
|
|
188
|
-
font-
|
|
189
|
-
|
|
202
|
+
font-family: inherit;
|
|
203
|
+
font-size: inherit;
|
|
204
|
+
color: inherit;
|
|
190
205
|
}
|
|
191
206
|
</style>
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
`doc` prop remounts the editor under it, so a consumer holding one mount across
|
|
4
4
|
two documents gets a surface that names the live handle.
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
It is A `{#key}`, not A reseed. The state a swap invalidates is not one field:
|
|
7
7
|
composable cards key on session id, the main card is keyed on nothing, and each
|
|
8
8
|
prose leaf mounts once per stable leaf key with `createField` closing over the
|
|
9
9
|
`doc` it mounted against — so after an in-place swap the main card's leaves
|
|
10
|
-
commit to the
|
|
10
|
+
commit to the previous handle. Reseeding by hand means threading a generation
|
|
11
11
|
token through every leaf key and resetting the id state, the commit-error map,
|
|
12
12
|
the active address, the leaf registry, the card refs and any pending scroll,
|
|
13
13
|
which is a remount spelled out one field at a time. This spells it as one.
|
|
@@ -16,17 +16,16 @@
|
|
|
16
16
|
unregisters, cancels its pending ticks, and only then releases, so a continuation
|
|
17
17
|
awaiting a flush across the swap runs against nothing.
|
|
18
18
|
|
|
19
|
-
`quill` is
|
|
19
|
+
`quill` is not part of the key: the schema is re-read on every derive, so a quill
|
|
20
20
|
swap re-projects correctly on its own, and keying on it would throw away a card
|
|
21
21
|
tree that did not need rebuilding. What it cannot do is re-mount the leaves, so a
|
|
22
|
-
quill swapped
|
|
22
|
+
quill swapped without a doc swap reports `rebind-ignored` rather than passing
|
|
23
23
|
silently.
|
|
24
24
|
-->
|
|
25
25
|
<script lang="ts">
|
|
26
26
|
import { untrack } from 'svelte';
|
|
27
|
-
import {
|
|
28
|
-
import type {
|
|
29
|
-
import type { DocPath } from '../core/address.js';
|
|
27
|
+
import { reportRebindIgnored } from '../core/rebind.svelte.js';
|
|
28
|
+
import type { DocPath, Landing } from '../core/address.js';
|
|
30
29
|
import type { CardId } from './signals.js';
|
|
31
30
|
import type { VisualEditorProps } from './props.js';
|
|
32
31
|
import VisualEditorInner from './VisualEditorInner.svelte';
|
|
@@ -35,7 +34,7 @@
|
|
|
35
34
|
|
|
36
35
|
let inner = $state<VisualEditorInner | undefined>();
|
|
37
36
|
|
|
38
|
-
// The pair the
|
|
37
|
+
// The pair the current mount bound to. Re-read on each re-key rather than held
|
|
39
38
|
// from the first mount: after a doc swap the incoming mount binds whatever quill
|
|
40
39
|
// came with it, and comparing against the original would report a pairing that
|
|
41
40
|
// is correct.
|
|
@@ -54,24 +53,24 @@
|
|
|
54
53
|
}
|
|
55
54
|
if (quill === boundQuill || reported) return;
|
|
56
55
|
reported = true;
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
'quill swapped in place; the mounted leaves still commit against the quill this doc mounted with. Swap the doc with it, or remount the editor, to rebind.'
|
|
62
|
-
});
|
|
56
|
+
reportRebindIgnored(
|
|
57
|
+
props.onError,
|
|
58
|
+
'quill swapped in place; the mounted leaves still commit against the quill this doc mounted with. Swap the doc with it, or remount the editor, to rebind.'
|
|
59
|
+
);
|
|
63
60
|
});
|
|
64
61
|
});
|
|
65
62
|
|
|
66
63
|
// The instance surface, every member a pass-through to the live mount: a call
|
|
67
64
|
// landing between a swap and the incoming mount is a no-op rather than a throw,
|
|
68
|
-
// which is what lets a host hold
|
|
65
|
+
// which is what lets a host hold one `bind:this` across two documents.
|
|
69
66
|
|
|
70
|
-
/**
|
|
71
|
-
|
|
72
|
-
|
|
67
|
+
/** Land a preview pick: a caret where the payload carries one and the leaf can
|
|
68
|
+
* spend it, an array element where the address names one, a focus otherwise. */
|
|
69
|
+
export async function setCaret(at: Landing): Promise<void> {
|
|
70
|
+
await inner?.setCaret(at);
|
|
73
71
|
}
|
|
74
|
-
/** Reveal and focus the
|
|
72
|
+
/** Reveal and focus the field at `field` — any mounted one — without placing a
|
|
73
|
+
* caret inside it. */
|
|
75
74
|
export async function focusField(field: DocPath): Promise<void> {
|
|
76
75
|
await inner?.focusField(field);
|
|
77
76
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { DocPath } from '../core/address.js';
|
|
1
|
+
import type { DocPath, Landing } from '../core/address.js';
|
|
3
2
|
import type { CardId } from './signals.js';
|
|
4
3
|
import type { VisualEditorProps } from './props.js';
|
|
5
4
|
declare const VisualEditor: import("svelte").Component<VisualEditorProps, {
|
|
6
|
-
setCaret: (
|
|
5
|
+
setCaret: (at: Landing) => Promise<void>;
|
|
7
6
|
focusField: (field: DocPath) => Promise<void>;
|
|
8
7
|
insertCard: (kind: string, at?: number) => CardId | undefined;
|
|
9
8
|
removeCard: (cardId: CardId) => void;
|