@quillmark/svelte 0.2.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.
Files changed (119) hide show
  1. package/NOTICE +6 -6
  2. package/README.md +3 -3
  3. package/THEMING.md +12 -8
  4. package/dist/core/address.d.ts +7 -7
  5. package/dist/core/address.js +6 -6
  6. package/dist/core/bloom.d.ts +3 -32
  7. package/dist/core/bloom.js +19 -51
  8. package/dist/core/codec/anchor.d.ts +1 -1
  9. package/dist/core/codec/anchor.js +1 -1
  10. package/dist/core/codec/atoms.d.ts +10 -0
  11. package/dist/core/codec/atoms.js +78 -0
  12. package/dist/core/codec/clipboard.d.ts +59 -0
  13. package/dist/core/codec/clipboard.js +202 -0
  14. package/dist/core/codec/code.d.ts +1 -1
  15. package/dist/core/codec/code.js +4 -4
  16. package/dist/core/codec/decode.d.ts +1 -1
  17. package/dist/core/codec/decode.js +8 -8
  18. package/dist/core/codec/encode.d.ts +4 -4
  19. package/dist/core/codec/encode.js +10 -10
  20. package/dist/core/codec/field.d.ts +21 -26
  21. package/dist/core/codec/field.js +33 -32
  22. package/dist/core/codec/index.js +5 -8
  23. package/dist/core/codec/inputrules.js +56 -18
  24. package/dist/core/codec/islands.d.ts +11 -7
  25. package/dist/core/codec/islands.js +16 -10
  26. package/dist/core/codec/keymap.d.ts +5 -6
  27. package/dist/core/codec/keymap.js +8 -7
  28. package/dist/core/codec/lists.d.ts +3 -3
  29. package/dist/core/codec/lists.js +32 -13
  30. package/dist/core/codec/marks.d.ts +1 -1
  31. package/dist/core/codec/marks.js +1 -1
  32. package/dist/core/codec/positions.js +1 -1
  33. package/dist/core/codec/prose.css +235 -221
  34. package/dist/core/codec/schema.js +4 -4
  35. package/dist/core/codec/slash.d.ts +39 -41
  36. package/dist/core/codec/slash.js +0 -0
  37. package/dist/core/codec/table-view.d.ts +12 -16
  38. package/dist/core/codec/table-view.js +488 -292
  39. package/dist/core/codec/table.d.ts +42 -15
  40. package/dist/core/codec/table.js +70 -26
  41. package/dist/core/errors.d.ts +5 -5
  42. package/dist/core/index.js +2 -2
  43. package/dist/core/lifecycle.js +1 -1
  44. package/dist/core/rebind.svelte.d.ts +2 -2
  45. package/dist/core/rebind.svelte.js +4 -4
  46. package/dist/core/teardown.d.ts +1 -1
  47. package/dist/core/teardown.js +1 -1
  48. package/dist/core/theme.css +170 -64
  49. package/dist/preset/index.css +1 -1
  50. package/dist/preset/recipes.css +31 -29
  51. package/dist/preset/scale.css +37 -26
  52. package/dist/preview/Preview.svelte +17 -27
  53. package/dist/preview/Preview.svelte.d.ts +4 -5
  54. package/dist/preview/bridge.js +6 -6
  55. package/dist/preview/controller.d.ts +8 -10
  56. package/dist/preview/controller.js +19 -44
  57. package/dist/preview/geometry.d.ts +8 -10
  58. package/dist/preview/geometry.js +8 -10
  59. package/dist/preview/index.js +4 -4
  60. package/dist/preview/paint.d.ts +1 -1
  61. package/dist/preview/paint.js +17 -19
  62. package/dist/visual/ArrayField.svelte +80 -66
  63. package/dist/visual/ArrayField.svelte.d.ts +1 -1
  64. package/dist/visual/BooleanField.svelte +8 -6
  65. package/dist/visual/BooleanField.svelte.d.ts +2 -2
  66. package/dist/visual/Card.svelte +160 -329
  67. package/dist/visual/Card.svelte.d.ts +2 -7
  68. package/dist/visual/CardControls.svelte +1 -1
  69. package/dist/visual/DateField.svelte +19 -19
  70. package/dist/visual/DateField.svelte.d.ts +3 -3
  71. package/dist/visual/DiagnosticList.svelte +1 -1
  72. package/dist/visual/EnumField.svelte +16 -16
  73. package/dist/visual/EnumField.svelte.d.ts +2 -2
  74. package/dist/visual/Field.svelte +128 -115
  75. package/dist/visual/Field.svelte.d.ts +1 -1
  76. package/dist/visual/FieldHint.svelte +24 -42
  77. package/dist/visual/FieldHint.svelte.d.ts +1 -1
  78. package/dist/visual/FieldLabel.svelte +8 -8
  79. package/dist/visual/FormatPopover.svelte +80 -35
  80. package/dist/visual/NumberField.svelte +5 -5
  81. package/dist/visual/NumberField.svelte.d.ts +1 -1
  82. package/dist/visual/ObjectField.svelte +9 -9
  83. package/dist/visual/ObjectField.svelte.d.ts +1 -1
  84. package/dist/visual/ProseArrayElement.svelte +11 -13
  85. package/dist/visual/ProseArrayElement.svelte.d.ts +1 -1
  86. package/dist/visual/ProseField.svelte +53 -87
  87. package/dist/visual/ProseField.svelte.d.ts +13 -19
  88. package/dist/visual/SlashMenu.svelte +42 -16
  89. package/dist/visual/TextField.svelte +5 -5
  90. package/dist/visual/TextField.svelte.d.ts +1 -1
  91. package/dist/visual/TipsCard.svelte +68 -56
  92. package/dist/visual/VisualEditor.svelte +6 -6
  93. package/dist/visual/VisualEditorInner.svelte +203 -290
  94. package/dist/visual/controls.css +74 -30
  95. package/dist/visual/diagnostics.d.ts +5 -5
  96. package/dist/visual/diagnostics.js +3 -3
  97. package/dist/visual/domid.js +3 -3
  98. package/dist/visual/ext.d.ts +1 -1
  99. package/dist/visual/ext.js +1 -1
  100. package/dist/visual/icons/nodes.d.ts +19 -0
  101. package/dist/visual/icons/nodes.js +13 -1
  102. package/dist/visual/index.js +4 -4
  103. package/dist/visual/leaves.d.ts +3 -3
  104. package/dist/visual/leaves.js +1 -1
  105. package/dist/visual/links.d.ts +24 -0
  106. package/dist/visual/links.js +67 -0
  107. package/dist/visual/props.d.ts +8 -8
  108. package/dist/visual/signals.d.ts +6 -6
  109. package/dist/visual/strings.d.ts +14 -19
  110. package/dist/visual/strings.js +5 -7
  111. package/dist/visual/structure.d.ts +24 -17
  112. package/dist/visual/structure.js +8 -8
  113. package/dist/visual/synced.svelte.d.ts +1 -1
  114. package/dist/visual/synced.svelte.js +4 -4
  115. package/dist/visual/tips.d.ts +2 -2
  116. package/dist/visual/tips.js +3 -3
  117. package/package.json +2 -2
  118. package/dist/preview/overlay.d.ts +0 -11
  119. package/dist/preview/overlay.js +0 -97
@@ -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
- CLEARS the channel in the Document, so the card is gone and does not reappear.
5
+ clears the channel in the Document, so the card is gone and does not reappear.
6
6
 
7
- The cursor is LOCAL state, not the channel. Advancing writes nothing: a per-tip
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 STRING is derived before the effect reads it, and that is load-bearing.
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,60 +81,68 @@
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="x" size={GLYPH} />
86
+ {t.strings.tipsDismiss} <Icon name="trash-2" size={GLYPH} />
89
87
  {:else}
90
- {t.strings.tipsNext} <Icon name="chevron-right" size={GLYPH} />
88
+ {t.strings.tipsNext} <Icon name="arrow-right" size={GLYPH} />
91
89
  {/if}
92
90
  </button>
93
91
  </div>
94
92
  </aside>
95
93
 
96
94
  <style>
97
- /* ATTACHED to `main`, not a block beside it: a square top pulled up by the radius,
95
+ /* Attached to `main`, not a block beside it: a square top pulled up by the radius,
98
96
  so its background fills the notches `main`'s rounded bottom corners cut and `main`
99
- paints over the rest. The seam is `main`'s own bottom hairline, and the two read as
100
- one block, which is what document-level guidance is: the main card's, not a card of
101
- its own. Still in-flow, one hairline, no lift, no fill beyond the card recipe. It
102
- reads as guidance rather than as a field by TONE and TYPE: the label rung in the
103
- muted label colour; not by a badge or an accent. It mints no token of its own;
104
- every value here is an existing dial.
97
+ paints over the rest. The two read as one block, which is what document-level
98
+ guidance is: the main card's, not a card of its own. Still in-flow, no edge, no
99
+ lift.
105
100
 
106
- The top inset takes the tuck back, so the space above the tip is the space below
107
- the foot.
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
- Leading is the reading rung, not the tight one the label SIZE would suggest: a
110
- tip is a passage that wraps, and the two axes are independent. */
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. */
111
107
  .qm-tips {
112
108
  margin-top: calc(var(--_qm-radius) * -1);
113
- border: var(--_qm-border-width) solid var(--_qm-border);
114
- border-radius: 0 0 var(--_qm-radius) var(--_qm-radius);
115
- padding: calc(var(--_qm-space-3) + var(--_qm-radius)) var(--_qm-space-3) var(--_qm-space-3);
116
- background: var(--_qm-surface-raised);
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);
111
+ background: var(--_qm-tips-surface);
117
112
  display: flex;
118
113
  flex-direction: column;
119
114
  gap: var(--_qm-space-2);
120
- font-size: var(--_qm-text-label);
115
+ font-family: var(--_qm-tips-font);
116
+ font-size: var(--_qm-text-body);
121
117
  line-height: var(--_qm-leading-body);
122
- color: var(--_qm-ink-label);
118
+ color: var(--_qm-tips-ink);
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
123
  }
124
124
  /* 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. Three
126
- rules restated from `core/codec/prose.css`, which is where they are argued and
127
- which cannot reach here: its selectors are scoped to `.ProseMirror` and a tip is
128
- not a view. The one deliberate divergence is the link, which takes no underline:
129
- a tip is not editable, so a hidden `href` costs its reader nothing. */
125
+ styles are `:global`: the compiler never sees these tags in the markup. Restated
126
+ from `core/codec/prose.css`, which is where they are argued and which cannot reach
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. */
130
131
  .qm-tips-body :global(p) {
131
132
  margin: 0;
132
133
  }
133
134
  .qm-tips-body :global(code) {
134
- font-family: var(--_qm-font-mono);
135
+ font-family: inherit;
136
+ font-size: inherit;
137
+ white-space: pre-wrap;
138
+ padding: 0 var(--_qm-space);
139
+ border-radius: var(--_qm-radius-inner);
140
+ background: var(--_qm-tips-fill);
141
+ color: var(--_qm-tips-ink-warm);
135
142
  }
136
143
  .qm-tips-body :global(a) {
137
144
  color: inherit;
145
+ text-decoration: underline;
138
146
  }
139
147
  .qm-tips-foot {
140
148
  display: flex;
@@ -145,47 +153,51 @@
145
153
  .qm-tips-dots {
146
154
  display: flex;
147
155
  align-items: center;
156
+ gap: var(--_qm-space-half);
148
157
  margin-right: auto;
149
158
  }
150
- /* Random access to the set, and the PITCH is the tap floor: 2.5.8's spacing
151
- exception measures centre distance, which is the number the floor already fixes,
152
- so a tighter row of dots buys nothing it does not immediately owe back. Target and
153
- mark are therefore not one rectangle (the floor is the button, the dot is drawn
154
- inside it), which is also why the hover reads on the mark rather than filling the
155
- box a `.qm-icon-btn` would. */
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. */
156
166
  .qm-tips-dot {
157
- display: flex;
158
- align-items: center;
159
- justify-content: center;
160
- box-sizing: border-box;
161
- min-width: var(--_qm-tap-min);
162
- min-height: var(--_qm-tap-min);
163
- border: none;
164
- background: transparent;
165
- cursor: pointer;
166
- }
167
- /* Three steps of ONE ink on the recede ladder (rest, hover, current), never a
168
- second hue and never a size: a dot that grew would move the row it sits in. */
169
- .qm-tips-dot::before {
170
- content: '';
167
+ box-sizing: content-box;
171
168
  width: 5px;
172
169
  height: 5px;
170
+ padding: var(--_qm-space-half);
171
+ border: none;
173
172
  border-radius: var(--_qm-radius-pill);
174
173
  background: currentColor;
174
+ background-clip: content-box;
175
175
  opacity: var(--_qm-opacity-idle);
176
+ cursor: pointer;
176
177
  transition: opacity var(--_qm-duration-fast) var(--_qm-ease-reverse);
177
178
  }
178
- .qm-tips-dot:hover::before {
179
+ .qm-tips-dot:hover {
179
180
  opacity: var(--_qm-opacity-muted);
180
181
  }
181
- .qm-tips-dot[aria-current='true']::before {
182
+ .qm-tips-dot[aria-current='true'] {
182
183
  opacity: 1;
183
184
  }
184
- /* Box and disabled state come from `.qm-icon-btn` (controls.css); the foot's
185
- button carries a label and so widens its inset and takes the meta type rung. */
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. */
186
190
  .qm-tips-action {
187
191
  padding: var(--_qm-space-half) var(--_qm-space-2);
188
- font-size: var(--_qm-text-label);
189
- color: var(--_qm-ink-label);
192
+ font-family: inherit;
193
+ font-size: inherit;
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);
190
202
  }
191
203
  </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
- IT IS A `{#key}`, NOT A RESEED. The state a swap invalidates is not one field:
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 PREVIOUS handle. Reseeding by hand means threading a generation
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,10 +16,10 @@
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 NOT part of the key: the schema is re-read on every derive, so a quill
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 WITHOUT a doc swap reports `rebind-ignored` rather than passing
22
+ quill swapped without a doc swap reports `rebind-ignored` rather than passing
23
23
  silently.
24
24
  -->
25
25
  <script lang="ts">
@@ -34,7 +34,7 @@
34
34
 
35
35
  let inner = $state<VisualEditorInner | undefined>();
36
36
 
37
- // The pair the CURRENT mount bound to. Re-read on each re-key rather than held
37
+ // The pair the current mount bound to. Re-read on each re-key rather than held
38
38
  // from the first mount: after a doc swap the incoming mount binds whatever quill
39
39
  // came with it, and comparing against the original would report a pairing that
40
40
  // is correct.
@@ -62,7 +62,7 @@
62
62
 
63
63
  // The instance surface, every member a pass-through to the live mount: a call
64
64
  // landing between a swap and the incoming mount is a no-op rather than a throw,
65
- // which is what lets a host hold ONE `bind:this` across two documents.
65
+ // which is what lets a host hold one `bind:this` across two documents.
66
66
 
67
67
  /** Land a preview pick: a caret where the payload carries one and the leaf can
68
68
  * spend it, an array element where the address names one, a focus otherwise. */