@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.
Files changed (69) hide show
  1. package/NOTICE +6 -7
  2. package/README.md +1 -1
  3. package/dist/core/address.d.ts +6 -1
  4. package/dist/core/address.js +12 -3
  5. package/dist/core/bloom.d.ts +9 -4
  6. package/dist/core/bloom.js +18 -49
  7. package/dist/core/codec/atoms.d.ts +1 -1
  8. package/dist/core/codec/atoms.js +1 -1
  9. package/dist/core/codec/blocks.js +4 -2
  10. package/dist/core/codec/cap.d.ts +21 -0
  11. package/dist/core/codec/cap.js +63 -0
  12. package/dist/core/codec/code.d.ts +1 -1
  13. package/dist/core/codec/code.js +1 -1
  14. package/dist/core/codec/decode.d.ts +5 -5
  15. package/dist/core/codec/decode.js +18 -12
  16. package/dist/core/codec/encode.js +6 -1
  17. package/dist/core/codec/field.d.ts +22 -10
  18. package/dist/core/codec/field.js +54 -18
  19. package/dist/core/codec/index.d.ts +3 -1
  20. package/dist/core/codec/index.js +3 -2
  21. package/dist/core/codec/inputrules.js +1 -1
  22. package/dist/core/codec/lists.d.ts +3 -2
  23. package/dist/core/codec/lists.js +21 -5
  24. package/dist/core/codec/nesting.d.ts +20 -0
  25. package/dist/core/codec/nesting.js +62 -0
  26. package/dist/core/codec/prose.css +74 -20
  27. package/dist/core/codec/schema.d.ts +2 -2
  28. package/dist/core/codec/schema.js +16 -7
  29. package/dist/core/codec/table-copy.d.ts +17 -0
  30. package/dist/core/codec/table-copy.js +84 -0
  31. package/dist/core/codec/table-view.d.ts +1 -7
  32. package/dist/core/codec/table-view.js +70 -119
  33. package/dist/core/codec/table.d.ts +2 -9
  34. package/dist/core/codec/table.js +10 -19
  35. package/dist/core/codec/tasks.d.ts +19 -0
  36. package/dist/core/codec/tasks.js +140 -0
  37. package/dist/core/errors.d.ts +2 -2
  38. package/dist/visual/ArrayField.svelte +103 -63
  39. package/dist/visual/ArrayField.svelte.d.ts +0 -2
  40. package/dist/visual/Card.svelte +9 -3
  41. package/dist/visual/Card.svelte.d.ts +2 -2
  42. package/dist/visual/Field.svelte +33 -17
  43. package/dist/visual/Field.svelte.d.ts +4 -2
  44. package/dist/visual/FieldLabel.svelte +19 -33
  45. package/dist/visual/FieldLabel.svelte.d.ts +4 -2
  46. package/dist/visual/FormatPopover.svelte +54 -73
  47. package/dist/visual/MatrixField.svelte +18 -12
  48. package/dist/visual/NumberField.svelte +32 -3
  49. package/dist/visual/ObjectField.svelte +50 -22
  50. package/dist/visual/ObjectField.svelte.d.ts +6 -0
  51. package/dist/visual/ProseField.svelte +20 -14
  52. package/dist/visual/ProseField.svelte.d.ts +8 -2
  53. package/dist/visual/ProseValue.svelte +30 -19
  54. package/dist/visual/ProseValue.svelte.d.ts +7 -4
  55. package/dist/visual/TextField.svelte +3 -2
  56. package/dist/visual/TipsCard.svelte +5 -2
  57. package/dist/visual/VariantField.svelte +1 -1
  58. package/dist/visual/VariantField.svelte.d.ts +1 -1
  59. package/dist/visual/VisualEditorInner.svelte +13 -13
  60. package/dist/visual/controls.css +19 -1
  61. package/dist/visual/icons/nodes.d.ts +0 -21
  62. package/dist/visual/icons/nodes.js +1 -7
  63. package/dist/visual/leaves.d.ts +12 -9
  64. package/dist/visual/leaves.js +19 -0
  65. package/dist/visual/strings.d.ts +16 -5
  66. package/dist/visual/strings.js +17 -9
  67. package/dist/visual/structure.d.ts +26 -32
  68. package/dist/visual/structure.js +71 -53
  69. package/package.json +3 -3
@@ -84,6 +84,21 @@ export function optionalCell(f) {
84
84
  export function baseType(f) {
85
85
  return (optionalCell(f) ? f.type.slice(0, -1) : f.type);
86
86
  }
87
+ /** Whether a content field is one line: one paragraph, no container, no island. A `text`
88
+ * or `richtext` field is one line unless it declares `multiline: true`. */
89
+ export function oneLine(f) {
90
+ return f.multiline !== true;
91
+ }
92
+ /** Whether a content field's codec is the literal one, its value text with no marks: `text`. */
93
+ export function literalText(f) {
94
+ return baseType(f) === 'text';
95
+ }
96
+ /** The character cap a content field's `max:` declares, `undefined` on any other. */
97
+ export function textCap(f) {
98
+ if (f?.max == null || controlKind(f) !== 'prose')
99
+ return undefined;
100
+ return { max: f.max, trimEnd: literalText(f) && oneLine(f) };
101
+ }
87
102
  /**
88
103
  * A scalar `default:` as the text an unset control holds, where it prints: as
89
104
  * declared, `undefined` for none, a blank or a non-scalar. A default of spaces prints
@@ -95,7 +110,7 @@ export function printedText(v) {
95
110
  }
96
111
  /**
97
112
  * A declared content literal as the `Content` it holds: a `richtext` one's markdown
98
- * imported, a `plaintext` one's text taken literally, one paragraph whose later lines
113
+ * imported, a `text` one's text taken literally, one paragraph whose later lines
99
114
  * continue it, as the literal codec reads a stored one. What a cell's static
100
115
  * `default:` stands in its leaf as, where no resolved row reaches it. `undefined` for
101
116
  * a blank or a non-scalar.
@@ -117,26 +132,33 @@ export function declaredContent(v, markdown) {
117
132
  islands: []
118
133
  };
119
134
  }
120
- /** A field's `{#each}` key: its name and what a mounted leaf reads once, its type and
121
- * `inline` and its elements'. A retype or a quill swap that changes any of them under a
122
- * name remounts the field, where a kept leaf would commit on the old schema. */
135
+ /** A field's `{#each}` key: its name and what a mounted leaf reads once, its type,
136
+ * {@link oneLine} and `max:`, and its elements'. A retype or a quill swap that changes
137
+ * any of them under a name remounts the field, where a kept leaf would commit on the old
138
+ * schema. */
123
139
  export function mountKey(name, f) {
124
- return `${name}\u0000${f.type}\u0000${f.inline === true}\u0000${f.items?.type ?? ''}\u0000${f.items?.inline === true}`;
125
- }
126
- /** Map a field schema to its control (precedence: prose › enum › text › …).
127
- * An array's element control is this over `items`: a missing `items` is a text
128
- * element. */
140
+ const items = f.items;
141
+ return [
142
+ name,
143
+ f.type,
144
+ oneLine(f),
145
+ f.max ?? '',
146
+ items?.type ?? '',
147
+ items ? oneLine(items) : '',
148
+ items?.max ?? ''
149
+ ].join('\u0000');
150
+ }
151
+ /** Map a field schema to its control. An array's element control is this over `items`;
152
+ * a type this build does not know takes the text input. */
129
153
  export function controlKind(f) {
130
154
  switch (baseType(f)) {
131
155
  case 'richtext':
132
- case 'plaintext':
156
+ case 'text':
133
157
  return 'prose';
134
158
  case 'enum':
135
159
  // `variants:` is the one key that changes a field's resting shape (canon
136
160
  // `SCHEMAS.md`): with it the field rests as a container, without it a bare string.
137
161
  return f.variants ? 'variant' : 'enum';
138
- case 'string':
139
- return 'text';
140
162
  case 'number':
141
163
  case 'integer':
142
164
  return 'number';
@@ -300,13 +322,13 @@ export function addedId(title, taken) {
300
322
  return `${base}_${n}`;
301
323
  }
302
324
  /** The `object` a matrix member is, for the schema walk: the declared columns, and an
303
- * added item's `title` beside them. Composed here because the boundary serializes the
304
- * roster and the columns alone. */
325
+ * added item's `title`, a one-line `text` cell, beside them. Composed here because the
326
+ * boundary serializes the roster and the columns alone. */
305
327
  export function matrixMemberSchema(matrix, id) {
306
328
  const columns = matrix.properties ?? {};
307
329
  return {
308
330
  type: 'object',
309
- properties: onRoster(matrix, id) ? columns : { [MATRIX_TITLE]: { type: 'string' }, ...columns }
331
+ properties: onRoster(matrix, id) ? columns : { [MATRIX_TITLE]: { type: 'text' }, ...columns }
310
332
  };
311
333
  }
312
334
  // ── The schema walk ──────────────────────────────────────────────────────────
@@ -330,7 +352,7 @@ export function schemaAt(field, steps) {
330
352
  /** What an array declaring no `items` holds, the walk's copy of the element control
331
353
  * {@link controlKind} names for one: a text element, so an index into such an array is
332
354
  * a place and not a refusal. */
333
- const UNDECLARED_ELEMENT = { type: 'string' };
355
+ const UNDECLARED_ELEMENT = { type: 'text' };
334
356
  function stepInto(schema, step) {
335
357
  switch (controlKind(schema)) {
336
358
  case 'array':
@@ -361,17 +383,16 @@ function stepInto(schema, step) {
361
383
  }
362
384
  // ── Row summaries and layouts ────────────────────────────────────────────────
363
385
  /** Whether a cell is one line tall by declaration: the shape a table column and a row
364
- * summary can hold. A prose cell is one where it declares `inline`, `richtext` or
365
- * `plaintext` alike. */
386
+ * summary can hold. A prose cell is one where it is {@link oneLine}. */
366
387
  export function shortCell(sub) {
367
388
  const kind = controlKind(sub);
368
389
  if (kind === 'prose')
369
- return !!sub.inline;
390
+ return oneLine(sub);
370
391
  return (kind === 'text' || kind === 'enum' || kind === 'number' || kind === 'boolean' || kind === 'date');
371
392
  }
372
393
  /**
373
- * The first short text cell's words — the first `string`, or inline `richtext` /
374
- * `plaintext`, in declaration order — read through {@link titleText}; `undefined` where
394
+ * The first short text cell's words — the first one-line `text` or `richtext`, in
395
+ * declaration order — read through {@link titleText}; `undefined` where
375
396
  * there is no such cell or it is empty. The cell is picked by the schema alone, so an
376
397
  * instance is named by one cell whatever the others hold. What names an instance from
377
398
  * its own values: a collapsed row, and a card whose kind declares no `title`.
@@ -435,39 +456,36 @@ export function commitDiscriminant(value, member) {
435
456
  delete next[VARIANT_DISCRIMINANT];
436
457
  return Object.keys(next).length ? next : undefined;
437
458
  }
438
- /**
439
- * Whether the schema obliges a cell: `default:`'s absence, which is the whole of the
440
- * obligation (DOCUMENT_MODEL). Exempt are the cells whose absence of one says nothing:
441
- * a typed dictionary, since a namespace declares no `default:` at all and `validate`
442
- * anchors obligation on the leaves under it; a matrix, whose blank is nothing held, a
443
- * whole answer; and an optional cell, which can declare none, its unanswered render
444
- * being `none`.
445
- */
446
- export function obliged(schema) {
447
- return (schema.type !== 'object' &&
448
- schema.type !== 'matrix' &&
449
- !optionalCell(schema) &&
450
- schema.default === undefined);
451
- }
452
459
  /** `foo_bar` → `Foo bar`: the label fallback when a field declares no `title`. */
453
460
  export function humanize(name) {
454
461
  const spaced = name.replace(/_/g, ' ').trim();
455
462
  return spaced ? spaced[0].toUpperCase() + spaced.slice(1) : spaced;
456
463
  }
457
- /** Project a card schema's `fields` map (declaration = key order) into models. */
464
+ /**
465
+ * Whether a field asks to share a row when its `ui.compact` is undeclared: a control
466
+ * whose type bounds its width. Text never does, its type saying nothing of whether a
467
+ * value is a rank or a subject line, so a short text field asks with `compact: true`.
468
+ */
469
+ function packsByDefault(control) {
470
+ return control === 'date' || control === 'enum' || control === 'number' || control === 'boolean';
471
+ }
472
+ /** Project a card schema's `fields` map (declaration = key order) into models. A
473
+ * card-level object's `properties` project the same way. */
458
474
  export function fieldModels(cardSchema) {
459
- return Object.entries(cardSchema.fields).map(([name, schema]) => ({
460
- name,
461
- schema,
462
- control: controlKind(schema),
463
- group: schema.ui?.group,
464
- compact: !!schema.ui?.compact,
465
- label: schema.title ?? humanize(name),
466
- description: schema.description,
467
- required: obliged(schema),
468
- inline: !!schema.inline,
469
- plaintext: baseType(schema) === 'plaintext'
470
- }));
475
+ return Object.entries(cardSchema.fields).map(([name, schema]) => {
476
+ const control = controlKind(schema);
477
+ return {
478
+ name,
479
+ schema,
480
+ control,
481
+ group: schema.ui?.group,
482
+ compact: schema.ui?.compact ?? packsByDefault(control),
483
+ label: schema.title ?? humanize(name),
484
+ description: schema.description,
485
+ inline: oneLine(schema),
486
+ plaintext: literalText(schema)
487
+ };
488
+ });
471
489
  }
472
490
  /**
473
491
  * Group-section order (VISUAL_EDITOR §"Structure mirrors the schema"): the schema's `ui.groups` registry
@@ -543,12 +561,12 @@ export function initialExpandedGroup(sections) {
543
561
  return sections.find((s) => s.group != null)?.group ?? null;
544
562
  }
545
563
  /**
546
- * Whether a field can share a row. `ui.compact` asks; a shape declines when the
564
+ * Whether a field can share a row. `compact` asks; a shape declines when the
547
565
  * document sets its height, because a row is as tall as its tallest cell and the cell
548
- * beside it does not grow in step: an object nests a whole field set, block richtext
549
- * (`inline` absent) holds paragraphs, and an array holds however many elements the
550
- * document carries. Any of them stands its neighbour in a column of whitespace. An
551
- * inline prose leaf is one line tall and packs like any scalar.
566
+ * beside it does not grow in step: an object nests a whole field set, a multiline prose
567
+ * leaf holds paragraphs or lines, and an array holds however many elements the
568
+ * document carries. Any of them stands its neighbour in a column of whitespace. A
569
+ * one-line prose leaf packs like any scalar.
552
570
  *
553
571
  * A variant declines for the same reason one step further in: its height is the live
554
572
  * world's cell count, so it is set by a pick rather than only by the document, and a
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quillmark/svelte",
3
- "version": "0.21.0",
3
+ "version": "0.23.0",
4
4
  "description": "Editor, live-preview and source surfaces over a Quillmark WASM session.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -23,7 +23,7 @@
23
23
  "author": "Quillmark Contributors",
24
24
  "type": "module",
25
25
  "engines": {
26
- "node": ">=24"
26
+ "node": ">=22"
27
27
  },
28
28
  "svelte": "./dist/index.js",
29
29
  "types": "./dist/index.d.ts",
@@ -69,7 +69,7 @@
69
69
  "check": "svelte-check --tsconfig ./tsconfig.json --fail-on-warnings"
70
70
  },
71
71
  "peerDependencies": {
72
- "@quillmark/wasm": ">=0.125.0-0",
72
+ "@quillmark/wasm": ">=0.126.0-0",
73
73
  "svelte": "^5.33.0"
74
74
  },
75
75
  "dependencies": {