@threadlabs/looma 0.29.7 → 0.29.9

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.
@@ -1,7 +1,7 @@
1
1
  import type { NodeViewRenderer } from "@tiptap/core";
2
2
  /**
3
3
  * Draws an editor callout with Looma's Callout, so it looks the same as a callout in any page.
4
- * @lifecycle ProseMirror owns the content DOM inside Callout's slot; destroying the view
5
- * releases its Vue app.
4
+ * @lifecycle ProseMirror owns the content DOM in Callout's slot and sets the tone and heading as the
5
+ * node changes. Callout disconnects once ProseMirror removes the view's element.
6
6
  */
7
7
  export declare const calloutNodeView: NodeViewRenderer;
@@ -0,0 +1,8 @@
1
+ import type { NodeViewRenderer } from "@tiptap/core";
2
+ /**
3
+ * A pointer-sized document divider drawn by Separator, selectable while the editor is editable.
4
+ * @lifecycle The editor owns the node and its deletion. Separator connects while ProseMirror keeps its
5
+ * element in the document and disconnects once ProseMirror removes it; destroying the view stops
6
+ * following the editor's editability.
7
+ */
8
+ export declare const dividerNodeView: NodeViewRenderer;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@threadlabs/looma",
3
- "version": "0.29.7",
3
+ "version": "0.29.9",
4
4
  "type": "module",
5
5
  "description": "Looma components as HTML, Vue, and plain DOM, with design tokens.",
6
6
  "license": "MIT",
@@ -10965,4 +10965,239 @@ html[data-ui-input-modality="touch"]
10965
10965
  width: 3px;
10966
10966
  background: var(--ui-affordance-direct-color, var(--ui-accent-solid, #5b55d6));
10967
10967
  }
10968
+ /* Generated by HTML Next 1.0.0-alpha.55. Do not edit. */
10969
+ @supports (-moz-appearance: none) {
10970
+ :where([data-component], [data-slotted]) { --html-next-scope-owner: boundary; }
10971
+ :where([data-slotted]:not([data-component])) { --html-next-scope-owner: projected !important; }
10972
+ }
10973
+ @supports (-moz-appearance: none) {
10974
+ [data-component~="ui-separator"] { --html-next-scope-owner: "ui-separator" !important; }
10975
+ }
10976
+ @scope ([data-component~="ui-separator"]) to ([data-component], [data-slotted]) {
10977
+ /* This component's hooks style the element they are set on, and never a nested one. */
10978
+ @property --ui-separator-color {
10979
+ syntax: "*";
10980
+ inherits: false;
10981
+ }
10982
+
10983
+ /* The root is the hr, so the rules name :host; a bare hr matches only a descendant. */
10984
+ :scope:where([data-component~="ui-separator"]) {
10985
+ box-sizing: border-box;
10986
+ align-self: stretch;
10987
+ margin: 0;
10988
+ border: 0;
10989
+ border-block-start: var(--ui-border-width) solid var(--ui-separator-color, var(--_separator-color, var(--ui-border-divider)));
10990
+ }
10991
+
10992
+ :scope:where([data-component~="ui-separator"])[data-ui-separator-state~="emphasis=strong"] {
10993
+ --_separator-color: var(--ui-border-strong);
10994
+ }
10995
+
10996
+ :scope:where([data-component~="ui-separator"])[aria-orientation="vertical"] {
10997
+ block-size: auto;
10998
+ border-block-start: 0;
10999
+ border-inline-start: var(--ui-border-width) solid var(--ui-separator-color, var(--_separator-color, var(--ui-border-divider)));
11000
+ }
11001
+
11002
+ :scope:where([data-component~="ui-separator"])[data-ui-separator-state~="selectable"] {
11003
+ min-block-size: var(--ui-control-size-sm);
11004
+ border: 0;
11005
+ background: linear-gradient(var(--ui-separator-color, var(--ui-border-divider)), var(--ui-separator-color, var(--ui-border-divider))) center / 100%
11006
+ var(--ui-border-width) no-repeat;
11007
+ cursor: pointer;
11008
+ }
11009
+ :scope:where([data-component~="ui-separator"])[data-ui-separator-state~="selectable"]:hover {
11010
+ background-color: var(--ui-surface-hover);
11011
+ }
11012
+ :scope:where([data-component~="ui-separator"])[data-ui-separator-state~="selected"] {
11013
+ outline: var(--ui-focus-width) solid var(--ui-focus-ring);
11014
+ outline-offset: var(--ui-focus-width);
11015
+ border-radius: var(--ui-radius-sm);
11016
+ }
11017
+ }
11018
+ @scope ([data-component~="ui-separator"]) to ([data-component]) {
11019
+ /* This component's hooks style the element they are set on, and never a nested one. */
11020
+
11021
+ /* The root is the hr, so the rules name :host; a bare hr matches only a descendant. */
11022
+ }
11023
+ /* Generated by HTML Next 1.0.0-alpha.55. Do not edit. */
11024
+ @supports (-moz-appearance: none) {
11025
+ :where([data-component], [data-slotted]) { --html-next-scope-owner: boundary; }
11026
+ :where([data-slotted]:not([data-component])) { --html-next-scope-owner: projected !important; }
11027
+ }
11028
+ @supports (-moz-appearance: none) {
11029
+ [data-component~="ui-callout"] { --html-next-scope-owner: "ui-callout" !important; }
11030
+ }
11031
+ @scope ([data-component~="ui-callout"]) to ([data-component], [data-slotted]) {
11032
+ /* This component's hooks style the element they are set on, and never a nested one. */
11033
+ @property --ui-callout-border {
11034
+ syntax: "*";
11035
+ inherits: false;
11036
+ }
11037
+ @property --ui-callout-border-width {
11038
+ syntax: "*";
11039
+ inherits: false;
11040
+ }
11041
+ @property --ui-callout-gap {
11042
+ syntax: "*";
11043
+ inherits: false;
11044
+ }
11045
+ @property --ui-callout-icon {
11046
+ syntax: "*";
11047
+ inherits: false;
11048
+ }
11049
+ @property --ui-callout-icon-column {
11050
+ syntax: "*";
11051
+ inherits: false;
11052
+ }
11053
+ @property --ui-callout-icon-size {
11054
+ syntax: "*";
11055
+ inherits: false;
11056
+ }
11057
+ @property --ui-callout-leading-border-width {
11058
+ syntax: "*";
11059
+ inherits: false;
11060
+ }
11061
+ @property --ui-callout-padding-block {
11062
+ syntax: "*";
11063
+ inherits: false;
11064
+ }
11065
+ @property --ui-callout-padding-inline {
11066
+ syntax: "*";
11067
+ inherits: false;
11068
+ }
11069
+ @property --ui-callout-surface {
11070
+ syntax: "*";
11071
+ inherits: false;
11072
+ }
11073
+ @property --ui-callout-text {
11074
+ syntax: "*";
11075
+ inherits: false;
11076
+ }
11077
+
11078
+ :scope:where([data-component~="ui-callout"]) {
11079
+ /* Hooks do not inherit, so the parts below read them from the root. */
11080
+ --_ui-callout-icon-column: var(--ui-callout-icon-column);
11081
+ --_ui-callout-icon: var(--ui-callout-icon);
11082
+ --_ui-callout-icon-size: var(--ui-callout-icon-size);
11083
+
11084
+ --_callout-surface: var(--ui-info-soft);
11085
+ --_ui-selection-context-surface: light-dark(
11086
+ oklch(from var(--ui-callout-surface, var(--_callout-surface)) calc(l - 0.045) calc(max(c, min(0.045, c * 3))) h),
11087
+ oklch(from var(--ui-callout-surface, var(--_callout-surface)) calc(l + 0.045) calc(max(c, min(0.045, c * 3))) h)
11088
+ );
11089
+ --_ui-selection-context-border: light-dark(
11090
+ oklch(from var(--ui-callout-surface, var(--_callout-surface)) calc(l - 0.085) calc(max(c, min(0.045, c * 3))) h),
11091
+ oklch(from var(--ui-callout-surface, var(--_callout-surface)) calc(l + 0.085) calc(max(c, min(0.045, c * 3))) h)
11092
+ );
11093
+ --_ui-selection-context-text: var(--ui-text-primary);
11094
+
11095
+ --_callout-border: var(--ui-info-solid);
11096
+ --_callout-icon: var(--ui-info-solid);
11097
+
11098
+ display: grid;
11099
+ grid-template-columns: var(--ui-callout-icon-column, 1.125rem) minmax(0, 1fr);
11100
+ gap: var(--ui-callout-gap, calc(var(--ui-space-2) * 0.75));
11101
+ align-items: start;
11102
+ max-width: 100%;
11103
+ padding-block: var(--ui-callout-padding-block, var(--ui-space-2));
11104
+ padding-inline-start: var(--ui-callout-padding-inline, var(--ui-space-2));
11105
+ padding-inline-end: var(--ui-callout-padding-inline, var(--ui-space-3));
11106
+ border: var(--ui-callout-border-width, var(--ui-border-width)) solid
11107
+ color-mix(in srgb, var(--ui-callout-border, var(--_callout-border)) 35%, transparent);
11108
+ border-inline-start: var(--ui-callout-leading-border-width, var(--ui-callout-border-width, var(--ui-border-width))) solid
11109
+ color-mix(in srgb, var(--ui-callout-border, var(--_callout-border)) 35%, transparent);
11110
+ border-radius: var(--ui-radius-md);
11111
+ background: var(--ui-callout-surface, var(--_callout-surface));
11112
+ color: var(--ui-callout-text, var(--ui-text-primary));
11113
+ font-family: var(--ui-font-family-sans);
11114
+ font-size: var(--ui-font-size-sm);
11115
+ font-weight: var(--ui-font-normal);
11116
+ line-height: var(--ui-line-height-md);
11117
+ }
11118
+
11119
+ /* One line box tall, so the icon centres on the first line of text. */
11120
+ .icon {
11121
+ display: grid;
11122
+ place-items: center;
11123
+ inline-size: var(--_ui-callout-icon-column, 1.125rem);
11124
+ block-size: 1lh;
11125
+ color: var(--_ui-callout-icon, var(--_callout-icon));
11126
+ }
11127
+
11128
+ .icon svg {
11129
+ inline-size: var(--_ui-callout-icon-size, 1.125rem);
11130
+ block-size: var(--_ui-callout-icon-size, 1.125rem);
11131
+ }
11132
+
11133
+ .content {
11134
+ min-inline-size: 0;
11135
+ }
11136
+
11137
+ .heading {
11138
+ display: block;
11139
+ font-weight: var(--ui-font-semibold);
11140
+ }
11141
+
11142
+ :scope:where([data-component~="ui-callout"])[data-ui-callout-state~="tone=neutral"], :scope:where([data-component~="ui-callout"])[data-ui-callout-state~="tone=note"] {
11143
+ --_ui-selection-context-surface: initial;
11144
+ --_ui-selection-context-border: initial;
11145
+ --_ui-selection-context-text: initial;
11146
+ --_callout-surface: var(--ui-surface-muted);
11147
+ --_callout-border: var(--ui-border-strong);
11148
+ --_callout-icon: var(--ui-text-secondary);
11149
+ }
11150
+
11151
+ :scope:where([data-component~="ui-callout"])[data-ui-callout-state~="tone=tip"] {
11152
+ --_callout-surface: var(--ui-success-soft);
11153
+ --_callout-border: var(--ui-success-solid);
11154
+ --_callout-icon: var(--ui-success-solid);
11155
+ }
11156
+
11157
+ :scope:where([data-component~="ui-callout"])[data-ui-callout-state~="tone=important"] {
11158
+ --_callout-surface: var(--ui-accent-soft);
11159
+ --_callout-border: var(--ui-accent-solid);
11160
+ --_callout-icon: var(--ui-accent-solid);
11161
+ }
11162
+
11163
+ :scope:where([data-component~="ui-callout"])[data-ui-callout-state~="tone=warning"] {
11164
+ --_callout-surface: var(--ui-warning-soft);
11165
+ --_callout-border: var(--ui-warning-solid);
11166
+ --_callout-icon: var(--ui-warning-solid);
11167
+ }
11168
+
11169
+ :scope:where([data-component~="ui-callout"])[data-ui-callout-state~="tone=success"] {
11170
+ --_callout-surface: var(--ui-success-soft);
11171
+ --_callout-border: var(--ui-success-solid);
11172
+ --_callout-icon: var(--ui-success-solid);
11173
+ }
11174
+
11175
+ :scope:where([data-component~="ui-callout"])[data-ui-callout-state~="tone=danger"], :scope:where([data-component~="ui-callout"])[data-ui-callout-state~="tone=caution"] {
11176
+ --_callout-surface: var(--ui-danger-soft);
11177
+ --_callout-border: var(--ui-danger-solid);
11178
+ --_callout-icon: var(--ui-danger-solid);
11179
+ }
11180
+
11181
+ /* A link in the callout's text is underlined, so it reads as a link by more than colour. */
11182
+
11183
+ /* A component that sets its display still honours the hidden attribute on its root. */
11184
+ :scope:where([data-component~="ui-callout"])[hidden] {
11185
+ display: none;
11186
+ }
11187
+ }
11188
+ @scope ([data-component~="ui-callout"]) to ([data-component]) {
11189
+ /* This component's hooks style the element they are set on, and never a nested one. */
11190
+
11191
+ /* One line box tall, so the icon centres on the first line of text. */
11192
+
11193
+ /* A link in the callout's text is underlined, so it reads as a link by more than colour. */
11194
+ .content :where([data-slotted], [data-slotted] *):is(a) {
11195
+ color: var(--ui-accent-active);
11196
+ text-decoration: underline;
11197
+ text-decoration-thickness: 0.06em;
11198
+ text-underline-offset: 0.18em;
11199
+ }
11200
+
11201
+ /* A component that sets its display still honours the hidden attribute on its root. */
11202
+ }
10968
11203
  /*$vite$:1*/
@@ -1,15 +1,17 @@
1
1
  import { computed, createApp, defineComponent, h, nextTick, onBeforeUnmount, onMounted, onUpdated, reactive, ref, shallowRef, useId, watch } from "vue";
2
2
  import { DEFAULT_MENTION_RESULT_LIMIT, LOOMA_ICONS, createLoomaMentionExtension, createLoomaSlashCommandExtension, getActiveTableUiState, getDefaultEditorExtensions, getDefaultSlashCommands, getTableOfContentsEntries, getVisualViewportRect, handleTableAction, handleTableOverlayAction, measureTableOverlayGeometry, normalizeActiveTableColumnWidths, normalizeTableOfContentsConfig } from "@threadlabs/looma/editor";
3
- import { Button, Callout, Card, Checkbox, Cluster, Disclosure, EditorBlockActions, EditorChipEditor, EditorCodeLanguage, EditorImageToolbar, EditorInsertTableGrid, EditorLinkCard, EditorLinkForm, EditorMentionMenu, EditorMentionMenuItem, EditorSlashMenu, EditorSlashMenuGroup, EditorSlashMenuItem, EditorSurface, EditorTableContextMenu, EditorTableOverlay, EditorTableToolbar, EditorToolbar, FormField, Icon, IconButton, Image, Input, List, Menu, MenuItem, Popover, Separator, Stack, StatusMessage, Text, Tooltip } from "@threadlabs/looma/vue";
3
+ import { Button, Card, Checkbox, Cluster, Disclosure, EditorBlockActions, EditorChipEditor, EditorCodeLanguage, EditorImageToolbar, EditorInsertTableGrid, EditorLinkCard, EditorLinkForm, EditorMentionMenu, EditorMentionMenuItem, EditorSlashMenu, EditorSlashMenuGroup, EditorSlashMenuItem, EditorSurface, EditorTableContextMenu, EditorTableOverlay, EditorTableToolbar, EditorToolbar, FormField, Icon, IconButton, Image, Input, List, Menu, MenuItem, Popover, Stack, StatusMessage, Text, Tooltip } from "@threadlabs/looma/vue";
4
4
  import { Editor, Extension, Node as Node$1, getText, getTextSerializersFromSchema, isNodeSelection, mergeAttributes, nodeInputRule, posToDOMRect } from "@tiptap/core";
5
5
  import { Editor as Editor$1 } from "@tiptap/vue-3";
6
6
  import { AllSelection, NodeSelection, Plugin, PluginKey, TextSelection } from "@tiptap/pm/state";
7
7
  import { Decoration, DecorationSet } from "@tiptap/pm/view";
8
8
  import { createLowlight } from "lowlight";
9
+ import { RequestEvent, updateComponentProps } from "@nextwebwg/html-next/runtime";
9
10
  import "@tiptap/pm/tables";
10
11
  import "@tiptap/pm/transform";
11
12
  import { closeHistory } from "@tiptap/pm/history";
12
13
  import { DOMParser, DOMSerializer, Fragment as Fragment$1 } from "@tiptap/pm/model";
14
+ import { acceptProps, attachGeneratedController, buildTemplate, checkBoolean, checkFormat, checkString, clearRegion, dispose, fillSlot, formatOf, hostState, keywordFormat, manageProps, project, toAttribute, toText, truthy, writeAttribute } from "@nextwebwg/html-next/generated-runtime";
13
15
  export * from "@threadlabs/looma/editor";
14
16
  //#region src/vue/editor/primitives.ts
15
17
  /** Each Vue editor component's element tag, for tooling that enumerates them. */
@@ -1224,179 +1226,6 @@ function createImageUploads(options) {
1224
1226
  };
1225
1227
  }
1226
1228
  //#endregion
1227
- //#region ../../node_modules/.pnpm/@nextwebwg+html-next@1.0.0-alpha.55/node_modules/@nextwebwg/html-next/dist/requests.js
1228
- /**
1229
- * Requests: behavior a component asks its consumer for, answered through a native event's
1230
- * `respondWith` (https://nextwebwg.org/declarative-components/javascript#requests).
1231
- *
1232
- * Every HTML Next bundle on a page (the live runtime, compiled modules and framework helpers) keeps
1233
- * its requests in one record on the document, so any consumer answers any component, and one
1234
- * document listener relays late responders. Converted framework components carry this module's
1235
- * source (scripts/generate-literal-source.ts), so it imports nothing.
1236
- */
1237
- var ports = /* @__PURE__ */ new WeakMap();
1238
- var port = (event) => {
1239
- let found = ports.get(event);
1240
- if (found === void 0) ports.set(event, found = {});
1241
- return found;
1242
- };
1243
- /**
1244
- * A request as its responders receive it: the nearest one answers with `respondWith`. Its static
1245
- * `respond`, `request` and `hasResponder` are how code without a `host` takes part
1246
- * (https://nextwebwg.org/declarative-components/javascript#outside-a-controller). They never read
1247
- * `this`, so `const { respond, request, hasResponder } = RequestEvent` works.
1248
- */
1249
- var RequestEvent = class extends CustomEvent {
1250
- /** Aborts when the asker no longer needs the answer, or its component disconnects. */
1251
- signal;
1252
- constructor(type, init) {
1253
- super(type, init);
1254
- this.signal = init.signal;
1255
- }
1256
- /** Answer the request with a value or a promise of one; the event stops propagating. */
1257
- respondWith(answer) {
1258
- const recorded = port(this);
1259
- if (this.eventPhase === 0 || recorded.a !== void 0) throw new DOMException(recorded.a === void 0 ? "A request is answered while it is dispatched." : "The request already has an answer.", "InvalidStateError");
1260
- recorded.a = [answer];
1261
- this.stopImmediatePropagation();
1262
- }
1263
- /** Report progress to the asker while the request is pending. */
1264
- progress(loaded, total) {
1265
- const report = this.signal.aborted ? void 0 : ports.get(this)?.p;
1266
- try {
1267
- report?.(loaded, total);
1268
- } catch (error) {
1269
- reportError(error);
1270
- }
1271
- }
1272
- /**
1273
- * Answers `name` requests that reach `target` with `answer`, records it as a known responder, then
1274
- * announces it so a component whose request went unanswered can ask again. Returns a function that
1275
- * removes it.
1276
- */
1277
- static respond(target, name, answer) {
1278
- const listener = (event) => {
1279
- if ("respondWith" in event) answerRequest(event, answer);
1280
- };
1281
- target.addEventListener(name, listener);
1282
- const forget = knownResponder(target, name);
1283
- target.dispatchEvent(new CustomEvent("responder", {
1284
- bubbles: true,
1285
- detail: { name }
1286
- }));
1287
- return () => {
1288
- target.removeEventListener(name, listener);
1289
- forget();
1290
- };
1291
- }
1292
- /**
1293
- * Asks `name` at `target` with the request steps `host.request` uses, with no declaration to check
1294
- * the detail or the answer against, no connection signal, and nothing remembered for late responders.
1295
- */
1296
- static request(target, name, detail, options) {
1297
- return dispatchRequest(target, target.nodeType ? target : null, name, detail ?? null, options?.signal ?? new AbortController().signal, options?.progress);
1298
- }
1299
- /** Whether a known responder for `name` is on the path a request from `target` takes, now. */
1300
- static hasResponder(target, name) {
1301
- return knownCount(target, name) > 0;
1302
- }
1303
- };
1304
- /** Answers a request event with a responder function, as `RequestEvent.respond` and framework function props do. */
1305
- function answerRequest(event, responder) {
1306
- const request = event;
1307
- request.respondWith(responder(request.detail, {
1308
- signal: request.signal,
1309
- progress: (loaded, total) => request.progress(loaded, total)
1310
- }));
1311
- }
1312
- var runtimeKey = Symbol.for("@nextwebwg/html-next.runtime.v1");
1313
- var documentRecord = (document) => document[runtimeKey] ??= {};
1314
- /** A target's document: a node's owner, a window's document, or a target outside the DOM itself. */
1315
- var recordOf = (target) => documentRecord(target.nodeType === 9 ? target : target.ownerDocument ?? target.document ?? target);
1316
- var requestState = (record) => record.requests ??= { g: /* @__PURE__ */ new WeakMap() };
1317
- /**
1318
- * Records a responder for `name` on `target` that `hasResponder` can see, until the returned function
1319
- * runs. `own` counts the entries a controller's `host.on` adds on its own root, which its own
1320
- * `host.hasResponder` does not count.
1321
- */
1322
- function knownResponder(target, name, own) {
1323
- const record = recordOf(target);
1324
- const known = record.k ??= /* @__PURE__ */ new WeakMap();
1325
- const names = known.get(target) ?? known.set(target, []).get(target);
1326
- const change = (add) => {
1327
- for (const list of own === void 0 ? [names] : [names, own]) if (add) list.push(name);
1328
- else list.splice(list.indexOf(name), 1);
1329
- record.w?.forEach((changed) => changed(name));
1330
- };
1331
- change(true);
1332
- let held = true;
1333
- return () => {
1334
- if (held) {
1335
- held = false;
1336
- change(false);
1337
- }
1338
- };
1339
- }
1340
- /** The next object on a composed event's path: an assigned slot, a parent, a shadow host, the window. */
1341
- var parentOf = (node) => node.nodeType === 9 ? node.defaultView : node.nodeType === 11 ? node.host : node.nodeType ? node.assignedSlot ?? node.parentNode : null;
1342
- /** How many of `names` are `name`. */
1343
- var countOf = (names, name) => names?.filter((known) => known === name).length ?? 0;
1344
- /** How many known responders for `name` are on the path a request from `target` takes. */
1345
- function knownCount(target, name) {
1346
- const known = recordOf(target).k;
1347
- let count = 0;
1348
- if (known !== void 0) for (let node = target; node; node = parentOf(node)) count += countOf(known.get(node), name);
1349
- return count;
1350
- }
1351
- /** Settles with `value`, or rejects with the signal's reason when it aborts first; a late value is discarded. */
1352
- function settle(value, signal) {
1353
- return new Promise((resolve, reject) => {
1354
- const abort = () => reject(signal.reason);
1355
- if (signal.aborted) abort();
1356
- signal.addEventListener("abort", abort, { once: true });
1357
- Promise.resolve(value).then((result) => {
1358
- signal.removeEventListener("abort", abort);
1359
- resolve(result);
1360
- }, (error) => {
1361
- signal.removeEventListener("abort", abort);
1362
- reject(error);
1363
- });
1364
- });
1365
- }
1366
- /**
1367
- * The request steps every asker shares: wait for the controllers of components at `from` and around
1368
- * it, dispatch the `RequestEvent` at `target`, and settle with the answer, or `null` when nobody
1369
- * answered. `answered` hears, during the dispatch, whether anyone did.
1370
- */
1371
- async function dispatchRequest(target, from, name, detail, signal, progress, answered) {
1372
- signal.throwIfAborted();
1373
- const state = requestState(recordOf(target));
1374
- for (;;) {
1375
- const waits = [];
1376
- for (let node = from; node !== null; node = node.parentNode ?? node.host ?? null) {
1377
- const gate = state.g.get(node);
1378
- if (gate !== void 0) waits.push(gate);
1379
- }
1380
- if (waits.length === 0) break;
1381
- await settle(Promise.all(waits), signal);
1382
- }
1383
- const event = new RequestEvent(name, {
1384
- detail,
1385
- signal,
1386
- bubbles: true,
1387
- composed: true
1388
- });
1389
- const recorded = port(event);
1390
- recorded.p = progress;
1391
- target.dispatchEvent(event);
1392
- answered?.(recorded.a !== void 0);
1393
- try {
1394
- return recorded.a === void 0 ? null : await settle(recorded.a[0], signal);
1395
- } finally {
1396
- recorded.p = void 0;
1397
- }
1398
- }
1399
- //#endregion
1400
1229
  //#region src/editor/requests.ts
1401
1230
  /** Answers a request event with a responder function, as an HTML Next framework function prop does. */
1402
1231
  function respondWithFunction(event, responder) {
@@ -3345,82 +3174,629 @@ var expandNodeView = ({ editor, node, getPos }) => {
3345
3174
  };
3346
3175
  };
3347
3176
  //#endregion
3348
- //#region src/vue/editor/divider.ts
3349
- /** A pointer-sized document divider using the shared separator's selected state.
3350
- * @lifecycle The editor owns the node and deletion; destroying the view releases
3351
- * its Vue app and editability subscription.
3177
+ //#region vanilla/UiSeparator.js
3178
+ var S$1 = {
3179
+ n: [],
3180
+ t: [],
3181
+ f: import.meta.url,
3182
+ g: "ui-separator"
3183
+ };
3184
+ var D$1 = {
3185
+ g: "ui-separator",
3186
+ props: {
3187
+ "emphasis": {
3188
+ "required": false,
3189
+ "values": ["normal", "strong"],
3190
+ "default": "normal",
3191
+ c: checkFormat("keyword", keywordFormat),
3192
+ t: "keyword",
3193
+ j: 0,
3194
+ m: [
3195
+ "p",
3196
+ formatOf(keywordFormat),
3197
+ false
3198
+ ]
3199
+ },
3200
+ "orientation": {
3201
+ "required": false,
3202
+ "values": ["horizontal", "vertical"],
3203
+ "default": "horizontal",
3204
+ c: checkFormat("keyword", keywordFormat),
3205
+ t: "keyword",
3206
+ j: 0,
3207
+ m: [
3208
+ "p",
3209
+ formatOf(keywordFormat),
3210
+ false
3211
+ ]
3212
+ },
3213
+ "selectable": {
3214
+ "required": false,
3215
+ "default": false,
3216
+ c: checkBoolean,
3217
+ t: "boolean",
3218
+ j: 0,
3219
+ m: "b"
3220
+ },
3221
+ "selected": {
3222
+ "required": false,
3223
+ "default": false,
3224
+ c: checkBoolean,
3225
+ t: "boolean",
3226
+ j: 0,
3227
+ m: "b"
3228
+ }
3229
+ }
3230
+ };
3231
+ function createUiSeparator(options = {}, html) {
3232
+ const { attributes = {}, children = [], slots = {}, ...componentProps } = options;
3233
+ const element = document.createElement("hr");
3234
+ for (const [name, value] of Object.entries(attributes)) {
3235
+ if (value === null || value === void 0 || value === false) continue;
3236
+ element.setAttribute(name, value === true ? "" : String(value));
3237
+ }
3238
+ element.setAttribute("data-component", "ui-separator");
3239
+ const v = [
3240
+ null,
3241
+ null,
3242
+ null,
3243
+ null
3244
+ ];
3245
+ const B = acceptProps(element, D$1, S$1.n, v, componentProps, [], html);
3246
+ const p0 = (r, c, d) => {
3247
+ if (c & 1073741826) {
3248
+ const x0 = v[1];
3249
+ const s0 = toAttribute(x0, "aria-orientation");
3250
+ if (s0 !== r.v0) writeAttribute(r.n, "aria-orientation", r.v0 = s0);
3251
+ }
3252
+ if (c & 13) {
3253
+ const s1 = hostState([
3254
+ "emphasis",
3255
+ "selectable",
3256
+ "selected"
3257
+ ], [
3258
+ v[0],
3259
+ v[2],
3260
+ v[3]
3261
+ ]);
3262
+ if (s1 !== r.v1) writeAttribute(r.n, "data-ui-separator-state", (r.v1 = s1) === "" ? null : s1);
3263
+ }
3264
+ };
3265
+ const R = {
3266
+ n: element,
3267
+ v0: void 0,
3268
+ v1: void 0
3269
+ };
3270
+ const I = { B };
3271
+ attachGeneratedController(element, S$1, v, ((c, d) => p0(R, c, d)), void 0, void 0, I);
3272
+ manageProps(I);
3273
+ return element;
3274
+ }
3275
+ //#endregion
3276
+ //#region src/editor/node-views/divider.ts
3277
+ /**
3278
+ * A pointer-sized document divider drawn by Separator, selectable while the editor is editable.
3279
+ * @lifecycle The editor owns the node and its deletion. Separator connects while ProseMirror keeps its
3280
+ * element in the document and disconnects once ProseMirror removes it; destroying the view stops
3281
+ * following the editor's editability.
3352
3282
  */
3353
3283
  var dividerNodeView = ({ editor, getPos }) => {
3354
- const mount = document.createElement("div");
3355
- const selected = ref(false);
3356
- const editable = ref(editor.isEditable);
3357
- const refresh = () => {
3358
- editable.value = editor.isEditable;
3359
- };
3360
- const app = createApp({ render: () => h(Separator, {
3361
- selectable: editable.value,
3362
- selected: editable.value && selected.value,
3363
- contenteditable: "false",
3364
- onClick: () => {
3365
- const position = getPos();
3366
- if (!editor.isEditable || typeof position !== "number") return;
3367
- editor.view.dispatch(editor.state.tr.setSelection(NodeSelection.create(editor.state.doc, position)));
3368
- editor.view.focus();
3369
- }
3370
- }) });
3371
- app.mount(mount);
3372
- const dom = mount.firstElementChild;
3373
- editor.on("update", refresh);
3284
+ let selected = false;
3285
+ const dom = createUiSeparator({
3286
+ selectable: editor.isEditable,
3287
+ attributes: { contenteditable: "false" }
3288
+ });
3289
+ const render = () => updateComponentProps(dom, {
3290
+ selectable: editor.isEditable,
3291
+ selected: editor.isEditable && selected
3292
+ });
3293
+ dom.addEventListener("click", () => {
3294
+ const position = getPos();
3295
+ if (!editor.isEditable || typeof position !== "number") return;
3296
+ editor.view.dispatch(editor.state.tr.setSelection(NodeSelection.create(editor.state.doc, position)));
3297
+ editor.view.focus();
3298
+ });
3299
+ editor.on("update", render);
3374
3300
  return {
3375
3301
  dom,
3376
3302
  selectNode() {
3377
- selected.value = true;
3303
+ selected = true;
3304
+ render();
3378
3305
  },
3379
3306
  deselectNode() {
3380
- selected.value = false;
3307
+ selected = false;
3308
+ render();
3381
3309
  },
3382
3310
  stopEvent: () => false,
3383
3311
  ignoreMutation: (mutation) => mutation.type !== "selection",
3384
3312
  destroy() {
3385
- editor.off("update", refresh);
3386
- app.unmount();
3313
+ editor.off("update", render);
3387
3314
  }
3388
3315
  };
3389
3316
  };
3390
3317
  //#endregion
3391
- //#region src/vue/editor/callout.ts
3318
+ //#region vanilla/UiCallout.js
3319
+ var T0 = [
3320
+ "",
3321
+ [],
3322
+ "\n ",
3323
+ [
3324
+ "span",
3325
+ [
3326
+ "class",
3327
+ "icon",
3328
+ "aria-hidden",
3329
+ "true"
3330
+ ],
3331
+ "\n ",
3332
+ 1,
3333
+ "\n ",
3334
+ 1,
3335
+ "\n ",
3336
+ 1,
3337
+ "\n ",
3338
+ 1,
3339
+ "\n ",
3340
+ 1,
3341
+ "\n ",
3342
+ 1,
3343
+ "\n ",
3344
+ 1,
3345
+ "\n "
3346
+ ],
3347
+ "\n ",
3348
+ [
3349
+ "div",
3350
+ ["class", "content"],
3351
+ "\n ",
3352
+ 1,
3353
+ "\n ",
3354
+ 4,
3355
+ "\n "
3356
+ ],
3357
+ "\n "
3358
+ ];
3359
+ var T1 = [
3360
+ "svg",
3361
+ [
3362
+ "viewBox",
3363
+ "0 0 24 24",
3364
+ "fill",
3365
+ "none",
3366
+ "stroke",
3367
+ "currentColor",
3368
+ "stroke-width",
3369
+ "2",
3370
+ "stroke-linecap",
3371
+ "round",
3372
+ "stroke-linejoin",
3373
+ "round"
3374
+ ],
3375
+ ["circle", [
3376
+ "cx",
3377
+ "12",
3378
+ "cy",
3379
+ "12",
3380
+ "r",
3381
+ "10"
3382
+ ]],
3383
+ ["path", ["d", "M12 16v-4"]],
3384
+ ["path", ["d", "M12 8h.01"]]
3385
+ ];
3386
+ var T2 = [
3387
+ "svg",
3388
+ [
3389
+ "viewBox",
3390
+ "0 0 24 24",
3391
+ "fill",
3392
+ "none",
3393
+ "stroke",
3394
+ "currentColor",
3395
+ "stroke-width",
3396
+ "2",
3397
+ "stroke-linecap",
3398
+ "round",
3399
+ "stroke-linejoin",
3400
+ "round"
3401
+ ],
3402
+ ["path", ["d", "M13.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8.5L13.5 2Z"]],
3403
+ ["path", ["d", "M13 2v7h7"]],
3404
+ ["path", ["d", "m9.5 17.5 4-4 2 2-4 4H9.5v-2Z"]]
3405
+ ];
3406
+ var T3 = [
3407
+ "svg",
3408
+ [
3409
+ "viewBox",
3410
+ "0 0 24 24",
3411
+ "fill",
3412
+ "none",
3413
+ "stroke",
3414
+ "currentColor",
3415
+ "stroke-width",
3416
+ "2",
3417
+ "stroke-linecap",
3418
+ "round",
3419
+ "stroke-linejoin",
3420
+ "round"
3421
+ ],
3422
+ ["path", ["d", "M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5"]],
3423
+ ["path", ["d", "M9 18h6"]],
3424
+ ["path", ["d", "M10 22h4"]]
3425
+ ];
3426
+ var T4 = [
3427
+ "svg",
3428
+ [
3429
+ "viewBox",
3430
+ "0 0 24 24",
3431
+ "fill",
3432
+ "none",
3433
+ "stroke",
3434
+ "currentColor",
3435
+ "stroke-width",
3436
+ "2",
3437
+ "stroke-linecap",
3438
+ "round",
3439
+ "stroke-linejoin",
3440
+ "round"
3441
+ ],
3442
+ ["path", ["d", "M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z"]],
3443
+ ["path", ["d", "M12 15h.01"]],
3444
+ ["path", ["d", "M12 7v4"]]
3445
+ ];
3446
+ var T5 = [
3447
+ "svg",
3448
+ [
3449
+ "viewBox",
3450
+ "0 0 24 24",
3451
+ "fill",
3452
+ "none",
3453
+ "stroke",
3454
+ "currentColor",
3455
+ "stroke-width",
3456
+ "2",
3457
+ "stroke-linecap",
3458
+ "round",
3459
+ "stroke-linejoin",
3460
+ "round"
3461
+ ],
3462
+ ["path", ["d", "m21.73 18-8-14a2 2 0 0 0-3.46 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z"]],
3463
+ ["path", ["d", "M12 9v4"]],
3464
+ ["path", ["d", "M12 17h.01"]]
3465
+ ];
3466
+ var T6 = [
3467
+ "svg",
3468
+ [
3469
+ "viewBox",
3470
+ "0 0 24 24",
3471
+ "fill",
3472
+ "none",
3473
+ "stroke",
3474
+ "currentColor",
3475
+ "stroke-width",
3476
+ "2",
3477
+ "stroke-linecap",
3478
+ "round",
3479
+ "stroke-linejoin",
3480
+ "round"
3481
+ ],
3482
+ ["circle", [
3483
+ "cx",
3484
+ "12",
3485
+ "cy",
3486
+ "12",
3487
+ "r",
3488
+ "10"
3489
+ ]],
3490
+ ["path", ["d", "m9 12 2 2 4-4"]]
3491
+ ];
3492
+ var T7 = [
3493
+ "svg",
3494
+ [
3495
+ "viewBox",
3496
+ "0 0 24 24",
3497
+ "fill",
3498
+ "none",
3499
+ "stroke",
3500
+ "currentColor",
3501
+ "stroke-width",
3502
+ "2",
3503
+ "stroke-linecap",
3504
+ "round",
3505
+ "stroke-linejoin",
3506
+ "round"
3507
+ ],
3508
+ ["circle", [
3509
+ "cx",
3510
+ "12",
3511
+ "cy",
3512
+ "12",
3513
+ "r",
3514
+ "10"
3515
+ ]],
3516
+ ["path", ["d", "m15 9-6 6"]],
3517
+ ["path", ["d", "m9 9 6 6"]]
3518
+ ];
3519
+ var T8 = [
3520
+ "strong",
3521
+ ["class", "heading"],
3522
+ 0
3523
+ ];
3524
+ var T9 = ["", []];
3525
+ var P0;
3526
+ var P1;
3527
+ var P2;
3528
+ var P3;
3529
+ var P4;
3530
+ var P5;
3531
+ var P6;
3532
+ var P7;
3533
+ var P8;
3534
+ var P9;
3535
+ var S = {
3536
+ n: [],
3537
+ t: [],
3538
+ f: import.meta.url,
3539
+ g: "ui-callout"
3540
+ };
3541
+ var D = {
3542
+ g: "ui-callout",
3543
+ props: {
3544
+ "heading": {
3545
+ "required": false,
3546
+ "default": "",
3547
+ c: checkString,
3548
+ t: "string",
3549
+ j: 0,
3550
+ m: "s"
3551
+ },
3552
+ "tone": {
3553
+ "required": false,
3554
+ "values": [
3555
+ "info",
3556
+ "neutral",
3557
+ "note",
3558
+ "tip",
3559
+ "important",
3560
+ "warning",
3561
+ "caution",
3562
+ "success",
3563
+ "danger"
3564
+ ],
3565
+ "default": "info",
3566
+ c: checkFormat("keyword", keywordFormat),
3567
+ t: "keyword",
3568
+ j: 0,
3569
+ m: [
3570
+ "p",
3571
+ formatOf(keywordFormat),
3572
+ false
3573
+ ]
3574
+ }
3575
+ }
3576
+ };
3577
+ function createUiCallout(options = {}, html) {
3578
+ const { attributes = {}, children = [], slots = {}, ...componentProps } = options;
3579
+ const element = document.createElement("div");
3580
+ for (const [name, value] of Object.entries(attributes)) {
3581
+ if (value === null || value === void 0 || value === false) continue;
3582
+ element.setAttribute(name, value === true ? "" : String(value));
3583
+ }
3584
+ if (!element.hasAttribute("role")) element.setAttribute("role", "note");
3585
+ element.setAttribute("data-component", "ui-callout");
3586
+ element.append((P0 ??= buildTemplate(T0)).cloneNode(true));
3587
+ const v = [null, null];
3588
+ const B = acceptProps(element, D, S.n, v, componentProps, [], html);
3589
+ const m1 = (d) => {
3590
+ return { n: (P1 ??= buildTemplate(T1)).cloneNode(true) };
3591
+ };
3592
+ const m2 = (d) => {
3593
+ return { n: (P2 ??= buildTemplate(T2)).cloneNode(true) };
3594
+ };
3595
+ const m3 = (d) => {
3596
+ return { n: (P3 ??= buildTemplate(T3)).cloneNode(true) };
3597
+ };
3598
+ const m4 = (d) => {
3599
+ return { n: (P4 ??= buildTemplate(T4)).cloneNode(true) };
3600
+ };
3601
+ const m5 = (d) => {
3602
+ return { n: (P5 ??= buildTemplate(T5)).cloneNode(true) };
3603
+ };
3604
+ const m6 = (d) => {
3605
+ return { n: (P6 ??= buildTemplate(T6)).cloneNode(true) };
3606
+ };
3607
+ const m7 = (d) => {
3608
+ return { n: (P7 ??= buildTemplate(T7)).cloneNode(true) };
3609
+ };
3610
+ const m8 = (d) => {
3611
+ const n = (P8 ??= buildTemplate(T8)).cloneNode(true);
3612
+ const r = {
3613
+ n,
3614
+ a0: n.firstChild,
3615
+ v0: ""
3616
+ };
3617
+ p8(r, -1, d);
3618
+ return r;
3619
+ };
3620
+ const p8 = (r, c, d) => {
3621
+ if (c & 1) {
3622
+ const x0 = v[0];
3623
+ const s0 = toText(x0);
3624
+ if (s0 !== r.v0) r.a0.data = r.v0 = s0;
3625
+ }
3626
+ };
3627
+ const m9 = (d) => {
3628
+ return { n: (P9 ??= buildTemplate(T9)).cloneNode(true) };
3629
+ };
3630
+ const p0 = (r, c, d) => {
3631
+ if (c & 2) {
3632
+ const s0 = hostState(["tone"], [v[1]]);
3633
+ if (s0 !== r.v0) writeAttribute(r.n, "data-ui-callout-state", (r.v0 = s0) === "" ? null : s0);
3634
+ }
3635
+ if (c & 2 && !(v[1] === "info") !== !r.b0) {
3636
+ if (r.b0) {
3637
+ r.b0 = void 0;
3638
+ clearRegion(r.a0, r.e0);
3639
+ } else {
3640
+ r.b0 = m1(d);
3641
+ r.e0.before(r.b0.n);
3642
+ }
3643
+ } else if (r.b0 !== void 0) r.b0;
3644
+ if (c & 2 && !(v[1] === "neutral" || v[1] === "note") !== !r.b1) {
3645
+ if (r.b1) {
3646
+ r.b1 = void 0;
3647
+ clearRegion(r.a1, r.e1);
3648
+ } else {
3649
+ r.b1 = m2(d);
3650
+ r.e1.before(r.b1.n);
3651
+ }
3652
+ } else if (r.b1 !== void 0) r.b1;
3653
+ if (c & 2 && !(v[1] === "tip") !== !r.b2) {
3654
+ if (r.b2) {
3655
+ r.b2 = void 0;
3656
+ clearRegion(r.a2, r.e2);
3657
+ } else {
3658
+ r.b2 = m3(d);
3659
+ r.e2.before(r.b2.n);
3660
+ }
3661
+ } else if (r.b2 !== void 0) r.b2;
3662
+ if (c & 2 && !(v[1] === "important") !== !r.b3) {
3663
+ if (r.b3) {
3664
+ r.b3 = void 0;
3665
+ clearRegion(r.a3, r.e3);
3666
+ } else {
3667
+ r.b3 = m4(d);
3668
+ r.e3.before(r.b3.n);
3669
+ }
3670
+ } else if (r.b3 !== void 0) r.b3;
3671
+ if (c & 2 && !(v[1] === "warning") !== !r.b4) {
3672
+ if (r.b4) {
3673
+ r.b4 = void 0;
3674
+ clearRegion(r.a4, r.e4);
3675
+ } else {
3676
+ r.b4 = m5(d);
3677
+ r.e4.before(r.b4.n);
3678
+ }
3679
+ } else if (r.b4 !== void 0) r.b4;
3680
+ if (c & 2 && !(v[1] === "success") !== !r.b5) {
3681
+ if (r.b5) {
3682
+ r.b5 = void 0;
3683
+ clearRegion(r.a5, r.e5);
3684
+ } else {
3685
+ r.b5 = m6(d);
3686
+ r.e5.before(r.b5.n);
3687
+ }
3688
+ } else if (r.b5 !== void 0) r.b5;
3689
+ if (c & 2 && !(v[1] === "danger" || v[1] === "caution") !== !r.b6) {
3690
+ if (r.b6) {
3691
+ r.b6 = void 0;
3692
+ clearRegion(r.a6, r.e6);
3693
+ } else {
3694
+ r.b6 = m7(d);
3695
+ r.e6.before(r.b6.n);
3696
+ }
3697
+ } else if (r.b6 !== void 0) r.b6;
3698
+ if (c & 1 && !truthy(v[0]) !== !r.b7) {
3699
+ if (r.b7) {
3700
+ r.b7 = void 0;
3701
+ clearRegion(r.a7, r.e7);
3702
+ } else {
3703
+ r.b7 = m8(d);
3704
+ r.e7.before(r.b7.n);
3705
+ }
3706
+ } else if (r.b7 !== void 0) p8(r.b7, c, d);
3707
+ if (r.f8 === void 0) {
3708
+ r.f8 = 1;
3709
+ const at = fillSlot(r.a8, r.e8, "", J, false, void 0, d);
3710
+ if (Array.isArray(at)) (r.z ??= []).push(() => {
3711
+ at[0].l.delete(at[1]);
3712
+ dispose(at[1]);
3713
+ });
3714
+ else if (at !== void 0) {
3715
+ r.b8 = m9(d);
3716
+ at.before(r.b8.n);
3717
+ }
3718
+ } else if (r.b8 !== void 0) r.b8;
3719
+ };
3720
+ const t0 = element.firstChild.nextSibling;
3721
+ const t1 = t0.firstChild.nextSibling;
3722
+ const t2 = t1.nextSibling.nextSibling.nextSibling;
3723
+ const t3 = t2.nextSibling.nextSibling.nextSibling;
3724
+ const t4 = t3.nextSibling.nextSibling.nextSibling;
3725
+ const t5 = t4.nextSibling.nextSibling.nextSibling;
3726
+ const t6 = t5.nextSibling.nextSibling.nextSibling;
3727
+ const t7 = t6.nextSibling.nextSibling.nextSibling;
3728
+ const t9 = t0.nextSibling.nextSibling.firstChild.nextSibling;
3729
+ const t10 = t9.nextSibling.nextSibling.nextSibling;
3730
+ const R = {
3731
+ n: element,
3732
+ v0: void 0,
3733
+ a0: t1,
3734
+ e0: t1.nextSibling,
3735
+ b0: void 0,
3736
+ a1: t2,
3737
+ e1: t2.nextSibling,
3738
+ b1: void 0,
3739
+ a2: t3,
3740
+ e2: t3.nextSibling,
3741
+ b2: void 0,
3742
+ a3: t4,
3743
+ e3: t4.nextSibling,
3744
+ b3: void 0,
3745
+ a4: t5,
3746
+ e4: t5.nextSibling,
3747
+ b4: void 0,
3748
+ a5: t6,
3749
+ e5: t6.nextSibling,
3750
+ b5: void 0,
3751
+ a6: t7,
3752
+ e6: t7.nextSibling,
3753
+ b6: void 0,
3754
+ a7: t9,
3755
+ e7: t9.nextSibling,
3756
+ b7: void 0,
3757
+ a8: t10,
3758
+ e8: t10.nextSibling,
3759
+ b8: void 0,
3760
+ f8: void 0
3761
+ };
3762
+ const I = { B };
3763
+ const J = project(I, children, slots);
3764
+ attachGeneratedController(element, S, v, ((c, d) => p0(R, c, d)), void 0, void 0, I);
3765
+ manageProps(I);
3766
+ return element;
3767
+ }
3768
+ //#endregion
3769
+ //#region src/editor/node-views/callout.ts
3770
+ var calloutProps = (node) => ({
3771
+ tone: node.attrs.tone,
3772
+ heading: node.attrs.heading || void 0
3773
+ });
3392
3774
  /**
3393
3775
  * Draws an editor callout with Looma's Callout, so it looks the same as a callout in any page.
3394
- * @lifecycle ProseMirror owns the content DOM inside Callout's slot; destroying the view
3395
- * releases its Vue app.
3776
+ * @lifecycle ProseMirror owns the content DOM in Callout's slot and sets the tone and heading as the
3777
+ * node changes. Callout disconnects once ProseMirror removes the view's element.
3396
3778
  */
3397
3779
  var calloutNodeView = ({ node }) => {
3398
3780
  const dom = document.createElement("div");
3399
3781
  dom.dataset.loomaCallout = "";
3400
- const current = shallowRef(node);
3401
- let contentDOM;
3402
- const app = createApp({ render: () => h(Callout, {
3403
- tone: current.value.attrs.tone,
3404
- heading: current.value.attrs.heading || void 0
3405
- }, () => h("div", {
3406
- "data-looma-callout-body": "",
3407
- ref: (element) => {
3408
- if (element) contentDOM = element;
3409
- }
3410
- })) });
3411
- app.mount(dom);
3782
+ const contentDOM = document.createElement("div");
3783
+ contentDOM.dataset.loomaCalloutBody = "";
3784
+ const callout = createUiCallout({
3785
+ ...calloutProps(node),
3786
+ children: [contentDOM]
3787
+ });
3788
+ dom.append(callout);
3789
+ let current = node;
3412
3790
  return {
3413
3791
  dom,
3414
3792
  contentDOM,
3415
3793
  update(next) {
3416
- if (next.type !== current.value.type) return false;
3417
- current.value = next;
3794
+ if (next.type !== current.type) return false;
3795
+ current = next;
3796
+ updateComponentProps(callout, calloutProps(next));
3418
3797
  return true;
3419
3798
  },
3420
- ignoreMutation: (mutation) => mutation.type !== "selection" && !contentDOM.contains(mutation.target),
3421
- destroy() {
3422
- app.unmount();
3423
- }
3799
+ ignoreMutation: (mutation) => mutation.type !== "selection" && !contentDOM.contains(mutation.target)
3424
3800
  };
3425
3801
  };
3426
3802
  //#endregion
@@ -1,6 +0,0 @@
1
- import type { NodeViewRenderer } from "@tiptap/core";
2
- /** A pointer-sized document divider using the shared separator's selected state.
3
- * @lifecycle The editor owns the node and deletion; destroying the view releases
4
- * its Vue app and editability subscription.
5
- */
6
- export declare const dividerNodeView: NodeViewRenderer;