@quillmark/svelte 0.21.0 → 0.23.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/NOTICE +6 -7
- package/README.md +1 -1
- package/dist/core/address.d.ts +6 -1
- package/dist/core/address.js +12 -3
- package/dist/core/bloom.d.ts +9 -4
- package/dist/core/bloom.js +18 -49
- package/dist/core/codec/atoms.d.ts +1 -1
- package/dist/core/codec/atoms.js +1 -1
- package/dist/core/codec/blocks.js +4 -2
- package/dist/core/codec/cap.d.ts +21 -0
- package/dist/core/codec/cap.js +63 -0
- package/dist/core/codec/code.d.ts +1 -1
- package/dist/core/codec/code.js +1 -1
- package/dist/core/codec/decode.d.ts +5 -5
- package/dist/core/codec/decode.js +18 -12
- package/dist/core/codec/encode.js +6 -1
- package/dist/core/codec/field.d.ts +22 -10
- package/dist/core/codec/field.js +54 -18
- package/dist/core/codec/index.d.ts +3 -1
- package/dist/core/codec/index.js +3 -2
- package/dist/core/codec/inputrules.js +1 -1
- package/dist/core/codec/lists.d.ts +3 -2
- package/dist/core/codec/lists.js +21 -5
- package/dist/core/codec/nesting.d.ts +20 -0
- package/dist/core/codec/nesting.js +62 -0
- package/dist/core/codec/prose.css +74 -20
- package/dist/core/codec/schema.d.ts +2 -2
- package/dist/core/codec/schema.js +16 -7
- package/dist/core/codec/table-copy.d.ts +17 -0
- package/dist/core/codec/table-copy.js +84 -0
- package/dist/core/codec/table-view.d.ts +1 -7
- package/dist/core/codec/table-view.js +70 -119
- package/dist/core/codec/table.d.ts +2 -9
- package/dist/core/codec/table.js +10 -19
- package/dist/core/codec/tasks.d.ts +19 -0
- package/dist/core/codec/tasks.js +140 -0
- package/dist/core/errors.d.ts +2 -2
- package/dist/visual/ArrayField.svelte +103 -63
- package/dist/visual/ArrayField.svelte.d.ts +0 -2
- package/dist/visual/Card.svelte +9 -3
- package/dist/visual/Card.svelte.d.ts +2 -2
- package/dist/visual/Field.svelte +33 -17
- package/dist/visual/Field.svelte.d.ts +4 -2
- package/dist/visual/FieldLabel.svelte +19 -33
- package/dist/visual/FieldLabel.svelte.d.ts +4 -2
- package/dist/visual/FormatPopover.svelte +54 -73
- package/dist/visual/MatrixField.svelte +18 -12
- package/dist/visual/NumberField.svelte +32 -3
- package/dist/visual/ObjectField.svelte +50 -22
- package/dist/visual/ObjectField.svelte.d.ts +6 -0
- package/dist/visual/ProseField.svelte +20 -14
- package/dist/visual/ProseField.svelte.d.ts +8 -2
- package/dist/visual/ProseValue.svelte +30 -19
- package/dist/visual/ProseValue.svelte.d.ts +7 -4
- package/dist/visual/TextField.svelte +3 -2
- package/dist/visual/TipsCard.svelte +5 -2
- package/dist/visual/VariantField.svelte +1 -1
- package/dist/visual/VariantField.svelte.d.ts +1 -1
- package/dist/visual/VisualEditorInner.svelte +13 -13
- package/dist/visual/controls.css +19 -1
- package/dist/visual/icons/nodes.d.ts +0 -21
- package/dist/visual/icons/nodes.js +1 -7
- package/dist/visual/leaves.d.ts +12 -9
- package/dist/visual/leaves.js +19 -0
- package/dist/visual/strings.d.ts +16 -5
- package/dist/visual/strings.js +17 -9
- package/dist/visual/structure.d.ts +26 -32
- package/dist/visual/structure.js +71 -53
- package/package.json +3 -3
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
type Landing
|
|
32
32
|
} from '../core/address.js';
|
|
33
33
|
import { errorMessage, reportError } from '../core/errors.js';
|
|
34
|
-
import {
|
|
34
|
+
import { bloom } from '../core/bloom.js';
|
|
35
35
|
import { createLifespan } from '../core/teardown.js';
|
|
36
36
|
import { spacePx } from '../core/rungs.js';
|
|
37
37
|
import type {
|
|
@@ -220,7 +220,7 @@
|
|
|
220
220
|
const card = addr.card;
|
|
221
221
|
return card != null ? { card, field: addr.field } : { field: addr.field };
|
|
222
222
|
}
|
|
223
|
-
function handleFocus(addr: Addr): void {
|
|
223
|
+
function handleFocus(addr: Addr, steps: readonly PathStep[] = []): void {
|
|
224
224
|
const plain = normalize(addr);
|
|
225
225
|
activeAddr = plain;
|
|
226
226
|
activeCardId = cardIdOf(plain);
|
|
@@ -228,7 +228,7 @@
|
|
|
228
228
|
// to at the offset it still names has to report again.
|
|
229
229
|
lastCaretField = undefined;
|
|
230
230
|
lastCaretPos = undefined;
|
|
231
|
-
const field = pathFor(plain);
|
|
231
|
+
const field = pathFor(plain, steps);
|
|
232
232
|
// Both halves or neither: a stale addr names no path and no live card.
|
|
233
233
|
if (field != null && activeCardId != null)
|
|
234
234
|
onActiveLeafChange?.({ field, cardId: activeCardId });
|
|
@@ -245,11 +245,11 @@
|
|
|
245
245
|
return model.cards.map((c) => c.kind);
|
|
246
246
|
}
|
|
247
247
|
/**
|
|
248
|
-
* A leaf's canonical `DocPath
|
|
249
|
-
* array (a stale addr: drop rather than mis-target).
|
|
248
|
+
* A leaf's canonical `DocPath`, `steps` down from the field. `undefined` for an
|
|
249
|
+
* address outside the live card array (a stale addr: drop rather than mis-target).
|
|
250
250
|
*/
|
|
251
|
-
function pathFor(addr: Addr): DocPath | undefined {
|
|
252
|
-
return fieldPathForAddr(addr, addr.card == null ? NO_KINDS : liveKinds());
|
|
251
|
+
function pathFor(addr: Addr, steps: readonly PathStep[] = []): DocPath | undefined {
|
|
252
|
+
return fieldPathForAddr(addr, addr.card == null ? NO_KINDS : liveKinds(), steps);
|
|
253
253
|
}
|
|
254
254
|
// The last place reported, so a caret that did not move is not news. A leaf fires
|
|
255
255
|
// one caret signal per transaction, and a transaction need not have moved the
|
|
@@ -736,10 +736,10 @@
|
|
|
736
736
|
// (where landing a caret changes nothing on screen) or one off-screen, where the
|
|
737
737
|
// browser's focus-scroll moves the page and leaves the caret to be hunted for.
|
|
738
738
|
const box = await land(found, at.granularity === 'segment' ? undefined : at.pos);
|
|
739
|
-
if (span.alive)
|
|
739
|
+
if (span.alive) bloom(box);
|
|
740
740
|
}
|
|
741
741
|
/** The active prose leaf: the formatting popover's observation seam. The active
|
|
742
|
-
* field's
|
|
742
|
+
* field's own leaf where it registered one, else the by-value leaf focused last
|
|
743
743
|
* under it (`leaves.ts`); `undefined` for a form control, which holds no marks to
|
|
744
744
|
* toggle. */
|
|
745
745
|
export function getActiveLeaf(): ActiveProse | undefined {
|
|
@@ -747,7 +747,7 @@
|
|
|
747
747
|
const card = activeAddr.card != null ? activeCardId : undefined;
|
|
748
748
|
const key = fieldKeyToString({ card, field: activeAddr.field });
|
|
749
749
|
const controller = leaves.prose(key);
|
|
750
|
-
if (controller) return { views: controller as FieldController & LeafViews
|
|
750
|
+
if (controller) return { views: controller as FieldController & LeafViews };
|
|
751
751
|
const views = leaves.value(key);
|
|
752
752
|
return views && { views };
|
|
753
753
|
}
|
|
@@ -826,7 +826,7 @@
|
|
|
826
826
|
const found = await revealLeaf(field);
|
|
827
827
|
if (!found) return missed(`no mounted field at ${field}`, field);
|
|
828
828
|
const box = await land(found, undefined);
|
|
829
|
-
if (span.alive)
|
|
829
|
+
if (span.alive) bloom(box);
|
|
830
830
|
}
|
|
831
831
|
/** Seed a card of `kind` and insert it at `at` (default: the end). Returns the new
|
|
832
832
|
* card's session key, or `undefined` when the quill seeds no card of that kind. */
|
|
@@ -995,7 +995,7 @@
|
|
|
995
995
|
{#if kinds.length === 1}
|
|
996
996
|
<button
|
|
997
997
|
type="button"
|
|
998
|
-
class="qm-add-btn qm-add-affordance qm-tap-floor"
|
|
998
|
+
class="qm-add-btn qm-add-affordance qm-tap-floor qm-focus-ring"
|
|
999
999
|
aria-label={marked ? undefined : merged.addCard}
|
|
1000
1000
|
onclick={() => addCard(atIndex, kinds[0], true)}
|
|
1001
1001
|
>{#if marked}{merged.addCard}{:else}<Icon name="plus" class="qm-add-glyph" />{/if}</button
|
|
@@ -1008,7 +1008,7 @@
|
|
|
1008
1008
|
rules below reach it through `:global`. -->
|
|
1009
1009
|
<DropdownMenu.Root>
|
|
1010
1010
|
<DropdownMenu.Trigger
|
|
1011
|
-
class="qm-add-btn qm-add-affordance qm-tap-floor"
|
|
1011
|
+
class="qm-add-btn qm-add-affordance qm-tap-floor qm-focus-ring"
|
|
1012
1012
|
aria-label={marked ? undefined : merged.addCard}
|
|
1013
1013
|
>{#if marked}{merged.addCard}{:else}<Icon
|
|
1014
1014
|
name="plus"
|
package/dist/visual/controls.css
CHANGED
|
@@ -267,6 +267,22 @@
|
|
|
267
267
|
transform: translate(-50%, -50%);
|
|
268
268
|
}
|
|
269
269
|
|
|
270
|
+
/* The arrival wash: a plane over the host's box at rest, which a landing plays
|
|
271
|
+
(`core/bloom.ts`). On the host from mount, because WebKit resizes a laid-out subgrid's
|
|
272
|
+
tracks when an out-of-flow box is added to it. */
|
|
273
|
+
:where(.qm-wash) {
|
|
274
|
+
position: relative;
|
|
275
|
+
}
|
|
276
|
+
:where(.qm-wash)::after {
|
|
277
|
+
content: '';
|
|
278
|
+
position: absolute;
|
|
279
|
+
inset: 0;
|
|
280
|
+
border-radius: inherit;
|
|
281
|
+
background: var(--_qm-accent-wash);
|
|
282
|
+
opacity: 0;
|
|
283
|
+
pointer-events: none;
|
|
284
|
+
}
|
|
285
|
+
|
|
270
286
|
/* The capacity ladder: how many tracks a grid of fields steps to, off the width of
|
|
271
287
|
the query container it stands in. One recipe, because three grids read it — a section's
|
|
272
288
|
fields (`Card.svelte`), a subform's properties (`ObjectField`), each over its own
|
|
@@ -311,7 +327,8 @@
|
|
|
311
327
|
highlight the keyboard cannot reach. It fills with the accent held rather than
|
|
312
328
|
the hover rung: the mark is a cursor a keyboard drives, so it has to read at a
|
|
313
329
|
glance from across the list, where a hover only has to confirm the pointer
|
|
314
|
-
already under it.
|
|
330
|
+
already under it. So the mark is the item's whole focus indicator, and the
|
|
331
|
+
outline a focused item would draw beside it is taken off.
|
|
315
332
|
|
|
316
333
|
The resting fill is the recipe's too: an item drawn on a `<button>` carries a UA
|
|
317
334
|
fill to take back, and a scoped block outranks this file, so a caller taking it
|
|
@@ -338,6 +355,7 @@
|
|
|
338
355
|
background: transparent;
|
|
339
356
|
cursor: pointer;
|
|
340
357
|
user-select: none;
|
|
358
|
+
outline: none;
|
|
341
359
|
}
|
|
342
360
|
:where(.qm-menu-item[data-highlighted]) {
|
|
343
361
|
background: var(--_qm-accent-tint);
|
|
@@ -87,27 +87,6 @@ export declare const ICONS: {
|
|
|
87
87
|
}], readonly ["path", {
|
|
88
88
|
readonly d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71";
|
|
89
89
|
}]];
|
|
90
|
-
readonly hash: readonly [readonly ["line", {
|
|
91
|
-
readonly x1: "4";
|
|
92
|
-
readonly x2: "20";
|
|
93
|
-
readonly y1: "9";
|
|
94
|
-
readonly y2: "9";
|
|
95
|
-
}], readonly ["line", {
|
|
96
|
-
readonly x1: "4";
|
|
97
|
-
readonly x2: "20";
|
|
98
|
-
readonly y1: "15";
|
|
99
|
-
readonly y2: "15";
|
|
100
|
-
}], readonly ["line", {
|
|
101
|
-
readonly x1: "10";
|
|
102
|
-
readonly x2: "8";
|
|
103
|
-
readonly y1: "3";
|
|
104
|
-
readonly y2: "21";
|
|
105
|
-
}], readonly ["line", {
|
|
106
|
-
readonly x1: "16";
|
|
107
|
-
readonly x2: "14";
|
|
108
|
-
readonly y1: "3";
|
|
109
|
-
readonly y2: "21";
|
|
110
|
-
}]];
|
|
111
90
|
readonly info: readonly [readonly ["circle", {
|
|
112
91
|
readonly cx: "12";
|
|
113
92
|
readonly cy: "12";
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
//
|
|
6
6
|
// Verbatim from lucide 1.28.0 — the version is stated because a glyph that drifts
|
|
7
7
|
// from upstream is otherwise invisible, and because the notices in `NOTICE` are the
|
|
8
|
-
// ones that release carries (ISC, and MIT for the Feather-derived
|
|
8
|
+
// ones that release carries (ISC, and MIT for the Feather-derived glyphs).
|
|
9
9
|
export const ICONS = {
|
|
10
10
|
'chevron-right': [['path', { d: 'm9 18 6-6-6-6' }]],
|
|
11
11
|
'arrow-right': [
|
|
@@ -45,12 +45,6 @@ export const ICONS = {
|
|
|
45
45
|
['path', { d: 'M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71' }],
|
|
46
46
|
['path', { d: 'M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71' }]
|
|
47
47
|
],
|
|
48
|
-
hash: [
|
|
49
|
-
['line', { x1: '4', x2: '20', y1: '9', y2: '9' }],
|
|
50
|
-
['line', { x1: '4', x2: '20', y1: '15', y2: '15' }],
|
|
51
|
-
['line', { x1: '10', x2: '8', y1: '3', y2: '21' }],
|
|
52
|
-
['line', { x1: '16', x2: '14', y1: '3', y2: '21' }]
|
|
53
|
-
],
|
|
54
48
|
info: [
|
|
55
49
|
['circle', { cx: '12', cy: '12', r: '10' }],
|
|
56
50
|
['path', { d: 'M12 16v-4' }],
|
package/dist/visual/leaves.d.ts
CHANGED
|
@@ -8,8 +8,8 @@ import type { FieldController, LeafViews } from '../core/codec/index.js';
|
|
|
8
8
|
*/
|
|
9
9
|
export type LandingBox = HTMLElement | undefined | Promise<HTMLElement | undefined>;
|
|
10
10
|
/**
|
|
11
|
-
* A mounted field's landing handle: focus it, and the
|
|
12
|
-
*
|
|
11
|
+
* A mounted field's landing handle: focus it, and the `.qm-wash` box the arrival wash
|
|
12
|
+
* plays over ({@link import('../core/bloom.js').bloom}).
|
|
13
13
|
*
|
|
14
14
|
* A `FieldController` is one, which is what lets the two lanes share a lookup; `Field`
|
|
15
15
|
* builds the same shape over a form control off the handoff a label click already
|
|
@@ -71,16 +71,19 @@ export interface LeafRegistry {
|
|
|
71
71
|
clear(): void;
|
|
72
72
|
}
|
|
73
73
|
export declare function createLeafRegistry(): LeafRegistry;
|
|
74
|
-
/**
|
|
75
|
-
*
|
|
76
|
-
* read from and a mark toggled at, and the controller where the leaf is a field's. A
|
|
77
|
-
* by-value leaf has none, its anchors being dropped on the parent's value write, so the
|
|
78
|
-
* anchor verbs the controller carries have nothing to act on there.
|
|
79
|
-
*/
|
|
74
|
+
/** The active prose leaf as the formatting popover reaches it: the views a selection is
|
|
75
|
+
* read from and a mark toggled at. */
|
|
80
76
|
export interface ActiveProse {
|
|
81
77
|
views: LeafViews;
|
|
82
|
-
controller?: FieldController;
|
|
83
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* The steps from a field's control box `root` down to the cell holding `target`, the
|
|
81
|
+
* reverse of {@link FieldControl.focusPath}: read off the marker each container rung
|
|
82
|
+
* stamps on the cell it draws, `data-qm-index` on an array's row and `data-qm-prop` on a
|
|
83
|
+
* key step (an object's property, a variant's cell, a matrix's member and an added
|
|
84
|
+
* item's title). `[]` for a target on the field's own control.
|
|
85
|
+
*/
|
|
86
|
+
export declare function stepsTo(target: EventTarget | null, root: Element): PathStep[];
|
|
84
87
|
/** The by-value lane with a field's key bound: what a leaf under that field announces
|
|
85
88
|
* itself through, knowing no key of its own. */
|
|
86
89
|
export interface ValueLeafSeat {
|
package/dist/visual/leaves.js
CHANGED
|
@@ -66,6 +66,25 @@ export function createLeafRegistry() {
|
|
|
66
66
|
}
|
|
67
67
|
};
|
|
68
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* The steps from a field's control box `root` down to the cell holding `target`, the
|
|
71
|
+
* reverse of {@link FieldControl.focusPath}: read off the marker each container rung
|
|
72
|
+
* stamps on the cell it draws, `data-qm-index` on an array's row and `data-qm-prop` on a
|
|
73
|
+
* key step (an object's property, a variant's cell, a matrix's member and an added
|
|
74
|
+
* item's title). `[]` for a target on the field's own control.
|
|
75
|
+
*/
|
|
76
|
+
export function stepsTo(target, root) {
|
|
77
|
+
const steps = [];
|
|
78
|
+
for (let el = target instanceof Element ? target : null; el && el !== root; el = el.parentElement) {
|
|
79
|
+
const index = el.getAttribute('data-qm-index');
|
|
80
|
+
const key = el.getAttribute('data-qm-prop');
|
|
81
|
+
if (index != null)
|
|
82
|
+
steps.push(Number(index));
|
|
83
|
+
else if (key != null)
|
|
84
|
+
steps.push(key);
|
|
85
|
+
}
|
|
86
|
+
return steps.reverse();
|
|
87
|
+
}
|
|
69
88
|
const SEAT = Symbol('qm-value-leaf');
|
|
70
89
|
/** Seat every by-value leaf under the calling field, at any depth of its containers. */
|
|
71
90
|
export function seatValueLeaves(seat) {
|
package/dist/visual/strings.d.ts
CHANGED
|
@@ -15,13 +15,13 @@ export interface VisualStrings extends TableChromeStrings, SlashStrings {
|
|
|
15
15
|
/** The card-title input's accessible name. */
|
|
16
16
|
cardTitle: string;
|
|
17
17
|
/** The trailing strip's visible words, which are also every strip's accessible
|
|
18
|
-
* name
|
|
18
|
+
* name. One string over
|
|
19
19
|
* one kind and many: the trigger seeds a card, and which kind is the menu's word
|
|
20
20
|
* to say or the schema's to have already settled. */
|
|
21
21
|
addCard: string;
|
|
22
22
|
arrayAdd: string;
|
|
23
23
|
arrayRemove: string;
|
|
24
|
-
/** The drag handle on an `object` row: its tooltip
|
|
24
|
+
/** The drag handle on an `object` row: its tooltip. */
|
|
25
25
|
arrayDrag: string;
|
|
26
26
|
/**
|
|
27
27
|
* A row control's accessible name, the action and the row it acts on: `Remove
|
|
@@ -35,6 +35,12 @@ export interface VisualStrings extends TableChromeStrings, SlashStrings {
|
|
|
35
35
|
* spells the separator.
|
|
36
36
|
*/
|
|
37
37
|
arrayCount: (count: number, max: number) => string;
|
|
38
|
+
/**
|
|
39
|
+
* The count beside the label of a `text` or `richtext` field declaring `max:`, the
|
|
40
|
+
* carrier of a keystroke the cap refuses: `12 / 40`. Parametric, so a translator
|
|
41
|
+
* spells the separator.
|
|
42
|
+
*/
|
|
43
|
+
textCount: (count: number, max: number) => string;
|
|
38
44
|
/**
|
|
39
45
|
* A collapsed array element with nothing to summarize itself by: the label and the
|
|
40
46
|
* 1-based index, which is what its accessible name already says. Parametric, so
|
|
@@ -59,8 +65,6 @@ export interface VisualStrings extends TableChromeStrings, SlashStrings {
|
|
|
59
65
|
/** The date field's toggle, pressed while the field holds `today`: the render
|
|
60
66
|
* date rather than a written one. */
|
|
61
67
|
dateToday: string;
|
|
62
|
-
/** The required marker's accessible name; the glyph itself is a `*`. */
|
|
63
|
-
fieldRequired: string;
|
|
64
68
|
/** What an unset optional cell (`t?`) ghosts at rest: the `none` it prints
|
|
65
69
|
* unanswered, in the product's words. */
|
|
66
70
|
optionalGhost: string;
|
|
@@ -75,7 +79,8 @@ export interface VisualStrings extends TableChromeStrings, SlashStrings {
|
|
|
75
79
|
formatStrikethrough: string;
|
|
76
80
|
formatCode: string;
|
|
77
81
|
formatLink: string;
|
|
78
|
-
/** The anchor button's accessible name.
|
|
82
|
+
/** The anchor button's accessible name. The popover withholds the button, so
|
|
83
|
+
* nothing draws this or the title below. */
|
|
79
84
|
formatAnchor: string;
|
|
80
85
|
/** Its hover title, which says what an anchor is; the name above only says what. */
|
|
81
86
|
formatAnchorTitle: string;
|
|
@@ -138,6 +143,12 @@ export interface VisualStrings extends TableChromeStrings, SlashStrings {
|
|
|
138
143
|
* diagnostic.
|
|
139
144
|
*/
|
|
140
145
|
export type FormatDiagnostic = (d: Diagnostic) => string | undefined;
|
|
146
|
+
/**
|
|
147
|
+
* A `Mod` chord as the writer's platform prints it: `⌘B` on Apple's, `Ctrl+B`
|
|
148
|
+
* elsewhere. The platform test is the one `prosemirror-keymap` resolves `Mod` by, so a
|
|
149
|
+
* tooltip names the chord the keymap binds.
|
|
150
|
+
*/
|
|
151
|
+
export declare function chord(key: string, platform?: string): string;
|
|
141
152
|
/** The package's English. Every key, so the merge below is total. */
|
|
142
153
|
export declare const DEFAULT_VISUAL_STRINGS: VisualStrings;
|
|
143
154
|
/** A consumer's wording: any subset, the rest the package's. */
|
package/dist/visual/strings.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// makes wording an override rather than a fork.
|
|
5
5
|
//
|
|
6
6
|
// Several of these are accessible names rather than decoration — the card
|
|
7
|
-
// controls, the add trigger
|
|
7
|
+
// controls, the add trigger — so an untranslated surface is
|
|
8
8
|
// not merely inconsistent, it reads the wrong language to a screen reader. That is
|
|
9
9
|
// why this exists as a seam and not as a list of literals to grep for.
|
|
10
10
|
//
|
|
@@ -14,11 +14,19 @@
|
|
|
14
14
|
//
|
|
15
15
|
// The strings reach the tree through context, not props. They are ambient,
|
|
16
16
|
// read-only, and wanted eight components deep (a card's controls, a field's
|
|
17
|
-
//
|
|
17
|
+
// optional ghost, the formatting popover, the tips card); threading them by hand
|
|
18
18
|
// would put a `strings` prop on every component between the root and each leaf,
|
|
19
19
|
// which is a prop that means nothing to any of them.
|
|
20
20
|
import { getContext, setContext } from 'svelte';
|
|
21
21
|
import { DEFAULT_SLASH_STRINGS, DEFAULT_TABLE_STRINGS } from '../core/codec/index.js';
|
|
22
|
+
/**
|
|
23
|
+
* A `Mod` chord as the writer's platform prints it: `⌘B` on Apple's, `Ctrl+B`
|
|
24
|
+
* elsewhere. The platform test is the one `prosemirror-keymap` resolves `Mod` by, so a
|
|
25
|
+
* tooltip names the chord the keymap binds.
|
|
26
|
+
*/
|
|
27
|
+
export function chord(key, platform = typeof navigator === 'undefined' ? '' : navigator.platform) {
|
|
28
|
+
return /Mac|iP(hone|[oa]d)/.test(platform) ? `⌘${key}` : `Ctrl+${key}`;
|
|
29
|
+
}
|
|
22
30
|
/** The package's English. Every key, so the merge below is total. */
|
|
23
31
|
export const DEFAULT_VISUAL_STRINGS = {
|
|
24
32
|
...DEFAULT_TABLE_STRINGS,
|
|
@@ -27,12 +35,13 @@ export const DEFAULT_VISUAL_STRINGS = {
|
|
|
27
35
|
cardMoveDown: 'Move down',
|
|
28
36
|
cardDelete: 'Delete card',
|
|
29
37
|
cardTitle: 'Card title',
|
|
30
|
-
addCard: '
|
|
38
|
+
addCard: 'Add card',
|
|
31
39
|
arrayAdd: '+ Add',
|
|
32
40
|
arrayRemove: 'Remove',
|
|
33
41
|
arrayDrag: 'Drag to move',
|
|
34
42
|
arrayRowAction: (action, row) => `${action} ${row}`,
|
|
35
43
|
arrayCount: (count, max) => `${count} / ${max}`,
|
|
44
|
+
textCount: (count, max) => `${count} / ${max}`,
|
|
36
45
|
elementUntitled: (label, index) => `${label} ${index}`,
|
|
37
46
|
enumUnsetTag: 'Default',
|
|
38
47
|
enumUnsetTagNone: 'Unset',
|
|
@@ -41,16 +50,15 @@ export const DEFAULT_VISUAL_STRINGS = {
|
|
|
41
50
|
matrixItemTitle: (list, index) => `${list ? `${list} item` : 'Item'} ${index}`,
|
|
42
51
|
matrixRemove: (title) => `Remove ${title}`,
|
|
43
52
|
dateToday: 'Today',
|
|
44
|
-
fieldRequired: 'required',
|
|
45
53
|
optionalGhost: 'None',
|
|
46
54
|
proseHeld: 'Holds more than this field can edit here.',
|
|
47
55
|
formatGroup: 'Formatting',
|
|
48
|
-
formatBold:
|
|
49
|
-
formatEmphasis:
|
|
50
|
-
formatUnderline:
|
|
56
|
+
formatBold: `Bold (${chord('B')})`,
|
|
57
|
+
formatEmphasis: `Italic (${chord('I')})`,
|
|
58
|
+
formatUnderline: `Underline (${chord('U')})`,
|
|
51
59
|
formatStrikethrough: 'Strikethrough',
|
|
52
60
|
formatCode: 'Code',
|
|
53
|
-
formatLink:
|
|
61
|
+
formatLink: `Link (${chord('K')})`,
|
|
54
62
|
formatAnchor: 'Anchor',
|
|
55
63
|
formatAnchorTitle: 'Anchor — an identity handle over the selection',
|
|
56
64
|
linkPlaceholder: 'https://…',
|
|
@@ -61,7 +69,7 @@ export const DEFAULT_VISUAL_STRINGS = {
|
|
|
61
69
|
tipsDismiss: 'Dismiss',
|
|
62
70
|
tipsNext: 'Next',
|
|
63
71
|
tipsDot: (index, count) => `Tip ${index} of ${count}`,
|
|
64
|
-
unknownKind: (kind) => `
|
|
72
|
+
unknownKind: (kind) => `Unknown card type ${kind}. Its content is kept.`,
|
|
65
73
|
retypeLabel: 'Change to',
|
|
66
74
|
retypePlaceholder: 'Choose a type…',
|
|
67
75
|
noCardKinds: 'This document declares no card types — delete this card to remove it.',
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type Content, type PathStep, type PayloadItem, type QuillCardSchema, type QuillFieldSchema, type QuillFieldType, type ResolvedField, type Resolved } from '@quillmark/wasm';
|
|
2
|
+
import type { TextCap } from '../core/codec/index.js';
|
|
2
3
|
/** The control a field type maps to (VISUAL_EDITOR §"Structure mirrors the schema"). */
|
|
3
4
|
export type ControlKind = 'prose' | 'text' | 'enum' | 'variant' | 'number' | 'boolean' | 'date' | 'array' | 'object' | 'matrix';
|
|
4
5
|
/** The container controls: the ones a nested address walks into and a deep
|
|
@@ -11,22 +12,17 @@ export interface FieldModel {
|
|
|
11
12
|
control: ControlKind;
|
|
12
13
|
/** `ui.group` (undefined = ungrouped). */
|
|
13
14
|
group: string | undefined;
|
|
14
|
-
/**
|
|
15
|
-
* guarantee: `placeFields` declines it for
|
|
15
|
+
/** Asks to share a row with adjacent compacts: `ui.compact` when declared, else
|
|
16
|
+
* {@link packsByDefault}. A request, not a guarantee: `placeFields` declines it for
|
|
17
|
+
* the shapes that grow (see `packable`). */
|
|
16
18
|
compact: boolean;
|
|
17
19
|
/** Display label: `title` when set, else the humanized field name. */
|
|
18
20
|
label: string;
|
|
19
21
|
/** Schema `description`: authoring help rendered beside the label,
|
|
20
22
|
* undefined when the field declares none. Chrome-only; never gates. */
|
|
21
23
|
description: string | undefined;
|
|
22
|
-
/**
|
|
23
|
-
*
|
|
24
|
-
* carries both it and a ghosted `default:`, that default being the whole of what
|
|
25
|
-
* retires the obligation. Persistent (schema-derived, survives filling). Label
|
|
26
|
-
* chrome only; never gates.
|
|
27
|
-
*/
|
|
28
|
-
required: boolean;
|
|
29
|
-
/** Prose-leaf flags (only meaningful when `control === 'prose'` / array items). */
|
|
24
|
+
/** Prose-leaf flags (only meaningful when `control === 'prose'` / array items):
|
|
25
|
+
* one line (`oneLine`), and the literal codec (`literalText`). */
|
|
30
26
|
inline: boolean;
|
|
31
27
|
plaintext: boolean;
|
|
32
28
|
}
|
|
@@ -161,6 +157,13 @@ export declare function optionalCell(f: QuillFieldSchema): boolean;
|
|
|
161
157
|
/** The type a cell's control reads: the declared one, an optional cell's `?` stripped.
|
|
162
158
|
* The `?` moves the render floor and nothing else, so every read of a type is this. */
|
|
163
159
|
export declare function baseType(f: QuillFieldSchema): QuillFieldType;
|
|
160
|
+
/** Whether a content field is one line: one paragraph, no container, no island. A `text`
|
|
161
|
+
* or `richtext` field is one line unless it declares `multiline: true`. */
|
|
162
|
+
export declare function oneLine(f: QuillFieldSchema): boolean;
|
|
163
|
+
/** Whether a content field's codec is the literal one, its value text with no marks: `text`. */
|
|
164
|
+
export declare function literalText(f: QuillFieldSchema): boolean;
|
|
165
|
+
/** The character cap a content field's `max:` declares, `undefined` on any other. */
|
|
166
|
+
export declare function textCap(f: QuillFieldSchema | undefined): TextCap | undefined;
|
|
164
167
|
/**
|
|
165
168
|
* A scalar `default:` as the text an unset control holds, where it prints: as
|
|
166
169
|
* declared, `undefined` for none, a blank or a non-scalar. A default of spaces prints
|
|
@@ -169,19 +172,19 @@ export declare function baseType(f: QuillFieldSchema): QuillFieldType;
|
|
|
169
172
|
export declare function printedText(v: unknown): string | undefined;
|
|
170
173
|
/**
|
|
171
174
|
* A declared content literal as the `Content` it holds: a `richtext` one's markdown
|
|
172
|
-
* imported, a `
|
|
175
|
+
* imported, a `text` one's text taken literally, one paragraph whose later lines
|
|
173
176
|
* continue it, as the literal codec reads a stored one. What a cell's static
|
|
174
177
|
* `default:` stands in its leaf as, where no resolved row reaches it. `undefined` for
|
|
175
178
|
* a blank or a non-scalar.
|
|
176
179
|
*/
|
|
177
180
|
export declare function declaredContent(v: unknown, markdown: boolean): Content | undefined;
|
|
178
|
-
/** A field's `{#each}` key: its name and what a mounted leaf reads once, its type
|
|
179
|
-
* `
|
|
180
|
-
* name remounts the field, where a kept leaf would commit on the old
|
|
181
|
+
/** A field's `{#each}` key: its name and what a mounted leaf reads once, its type,
|
|
182
|
+
* {@link oneLine} and `max:`, and its elements'. A retype or a quill swap that changes
|
|
183
|
+
* any of them under a name remounts the field, where a kept leaf would commit on the old
|
|
184
|
+
* schema. */
|
|
181
185
|
export declare function mountKey(name: string, f: QuillFieldSchema): string;
|
|
182
|
-
/** Map a field schema to its control
|
|
183
|
-
*
|
|
184
|
-
* element. */
|
|
186
|
+
/** Map a field schema to its control. An array's element control is this over `items`;
|
|
187
|
+
* a type this build does not know takes the text input. */
|
|
185
188
|
export declare function controlKind(f: QuillFieldSchema): ControlKind;
|
|
186
189
|
/** The discriminant cell of a variant container, off the boundary's own constant: it
|
|
187
190
|
* crosses inside untyped container data with no type to read it off, so a literal here
|
|
@@ -254,8 +257,8 @@ export declare function addedItems(matrix: QuillFieldSchema, map: Record<string,
|
|
|
254
257
|
*/
|
|
255
258
|
export declare function addedId(title: string, taken: (id: string) => boolean): string;
|
|
256
259
|
/** The `object` a matrix member is, for the schema walk: the declared columns, and an
|
|
257
|
-
* added item's `title` beside them. Composed here because the
|
|
258
|
-
* roster and the columns alone. */
|
|
260
|
+
* added item's `title`, a one-line `text` cell, beside them. Composed here because the
|
|
261
|
+
* boundary serializes the roster and the columns alone. */
|
|
259
262
|
export declare function matrixMemberSchema(matrix: QuillFieldSchema, id: string): QuillFieldSchema;
|
|
260
263
|
/**
|
|
261
264
|
* The schema at `steps` under `field`, or `undefined` where the schema declares no such
|
|
@@ -267,8 +270,7 @@ export declare function matrixMemberSchema(matrix: QuillFieldSchema, id: string)
|
|
|
267
270
|
*/
|
|
268
271
|
export declare function schemaAt(field: QuillFieldSchema, steps: readonly PathStep[]): QuillFieldSchema | undefined;
|
|
269
272
|
/** Whether a cell is one line tall by declaration: the shape a table column and a row
|
|
270
|
-
* summary can hold. A prose cell is one where it
|
|
271
|
-
* `plaintext` alike. */
|
|
273
|
+
* summary can hold. A prose cell is one where it is {@link oneLine}. */
|
|
272
274
|
export declare function shortCell(sub: QuillFieldSchema): boolean;
|
|
273
275
|
/** A collapsed row's own words ({@link firstShortText}); `undefined` while the row has
|
|
274
276
|
* nothing to say for itself. */
|
|
@@ -301,19 +303,11 @@ export declare function variantCells(schema: QuillFieldSchema, member: string |
|
|
|
301
303
|
* `undefined`.
|
|
302
304
|
*/
|
|
303
305
|
export declare function commitDiscriminant(value: Record<string, unknown> | undefined, member: string | undefined): Record<string, unknown> | undefined;
|
|
304
|
-
/**
|
|
305
|
-
* Whether the schema obliges a cell: `default:`'s absence, which is the whole of the
|
|
306
|
-
* obligation (DOCUMENT_MODEL). Exempt are the cells whose absence of one says nothing:
|
|
307
|
-
* a typed dictionary, since a namespace declares no `default:` at all and `validate`
|
|
308
|
-
* anchors obligation on the leaves under it; a matrix, whose blank is nothing held, a
|
|
309
|
-
* whole answer; and an optional cell, which can declare none, its unanswered render
|
|
310
|
-
* being `none`.
|
|
311
|
-
*/
|
|
312
|
-
export declare function obliged(schema: QuillFieldSchema): boolean;
|
|
313
306
|
/** `foo_bar` → `Foo bar`: the label fallback when a field declares no `title`. */
|
|
314
307
|
export declare function humanize(name: string): string;
|
|
315
|
-
/** Project a card schema's `fields` map (declaration = key order) into models.
|
|
316
|
-
|
|
308
|
+
/** Project a card schema's `fields` map (declaration = key order) into models. A
|
|
309
|
+
* card-level object's `properties` project the same way. */
|
|
310
|
+
export declare function fieldModels(cardSchema: Pick<QuillCardSchema, 'fields'>): FieldModel[];
|
|
317
311
|
/**
|
|
318
312
|
* Group-section order (VISUAL_EDITOR §"Structure mirrors the schema"): the schema's `ui.groups` registry
|
|
319
313
|
* key order when present: `QuillCardUi.groups` is a typed `Record` at the
|