@abraca/nuxt 2.11.0 → 2.13.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/dist/module.json +1 -1
- package/dist/module.mjs +7 -0
- package/dist/runtime/components/ADocPickerModal.d.vue.ts +31 -0
- package/dist/runtime/components/ADocPickerModal.vue +191 -0
- package/dist/runtime/components/ADocPickerModal.vue.d.ts +31 -0
- package/dist/runtime/components/ADocumentTree.vue +65 -0
- package/dist/runtime/components/AEditor.d.vue.ts +17 -10
- package/dist/runtime/components/AEditor.vue +232 -164
- package/dist/runtime/components/AEditor.vue.d.ts +17 -10
- package/dist/runtime/components/ANodePanel.d.vue.ts +9 -1
- package/dist/runtime/components/ANodePanel.vue +547 -473
- package/dist/runtime/components/ANodePanel.vue.d.ts +9 -1
- package/dist/runtime/components/ATagsEditor.d.vue.ts +19 -0
- package/dist/runtime/components/ATagsEditor.vue +60 -0
- package/dist/runtime/components/ATagsEditor.vue.d.ts +19 -0
- package/dist/runtime/components/aware/AMedia.d.vue.ts +1 -1
- package/dist/runtime/components/aware/AMedia.vue.d.ts +1 -1
- package/dist/runtime/components/chat/AChatInput.d.vue.ts +11 -6
- package/dist/runtime/components/chat/AChatInput.vue +33 -2
- package/dist/runtime/components/chat/AChatInput.vue.d.ts +11 -6
- package/dist/runtime/components/chat/AChatList.d.vue.ts +12 -0
- package/dist/runtime/components/chat/AChatList.vue +76 -32
- package/dist/runtime/components/chat/AChatList.vue.d.ts +12 -0
- package/dist/runtime/components/chat/AChatMessages.d.vue.ts +4 -0
- package/dist/runtime/components/chat/AChatMessages.vue +57 -4
- package/dist/runtime/components/chat/AChatMessages.vue.d.ts +4 -0
- package/dist/runtime/components/chat/AChatPanel.d.vue.ts +6 -2
- package/dist/runtime/components/chat/AChatPanel.vue +17 -1
- package/dist/runtime/components/chat/AChatPanel.vue.d.ts +6 -2
- package/dist/runtime/components/chat/ANodeChatPanel.vue +1 -1
- package/dist/runtime/components/docs/ADocsSearch.d.vue.ts +1 -1
- package/dist/runtime/components/docs/ADocsSearch.vue.d.ts +1 -1
- package/dist/runtime/components/renderers/AChartRenderer.client.d.vue.ts +17 -0
- package/dist/runtime/components/renderers/AChartRenderer.client.vue +622 -0
- package/dist/runtime/components/renderers/AChartRenderer.client.vue.d.ts +17 -0
- package/dist/runtime/components/renderers/AGraphRenderer.vue +64 -15
- package/dist/runtime/components/renderers/calendar/ACalendarToolbar.d.vue.ts +2 -2
- package/dist/runtime/components/renderers/calendar/ACalendarToolbar.vue.d.ts +2 -2
- package/dist/runtime/components/renderers/media/MediaTransportBar.d.vue.ts +2 -2
- package/dist/runtime/components/renderers/media/MediaTransportBar.vue.d.ts +2 -2
- package/dist/runtime/components/renderers/sheets/ASheetsGrid.d.vue.ts +2 -2
- package/dist/runtime/components/renderers/sheets/ASheetsGrid.vue.d.ts +2 -2
- package/dist/runtime/components/settings/ASettingsAppearancePanel.d.vue.ts +3 -0
- package/dist/runtime/components/settings/ASettingsAppearancePanel.vue +67 -0
- package/dist/runtime/components/settings/ASettingsAppearancePanel.vue.d.ts +3 -0
- package/dist/runtime/components/settings/ASettingsGroup.d.vue.ts +24 -0
- package/dist/runtime/components/settings/ASettingsGroup.vue +31 -0
- package/dist/runtime/components/settings/ASettingsGroup.vue.d.ts +24 -0
- package/dist/runtime/components/settings/ASettingsModal.vue +84 -53
- package/dist/runtime/components/settings/ASettingsPlaceholder.d.vue.ts +20 -0
- package/dist/runtime/components/settings/ASettingsPlaceholder.vue +32 -0
- package/dist/runtime/components/settings/ASettingsPlaceholder.vue.d.ts +20 -0
- package/dist/runtime/components/settings/ASettingsRow.d.vue.ts +34 -0
- package/dist/runtime/components/settings/ASettingsRow.vue +34 -0
- package/dist/runtime/components/settings/ASettingsRow.vue.d.ts +34 -0
- package/dist/runtime/components/settings/sections.d.ts +37 -0
- package/dist/runtime/components/settings/sections.js +45 -0
- package/dist/runtime/components/shell/AUserMenu.d.vue.ts +2 -2
- package/dist/runtime/components/shell/AUserMenu.vue.d.ts +2 -2
- package/dist/runtime/components/shell/AUserProfilePopover.d.vue.ts +1 -1
- package/dist/runtime/components/shell/AUserProfilePopover.vue.d.ts +1 -1
- package/dist/runtime/composables/useChat.d.ts +22 -1
- package/dist/runtime/composables/useChat.js +79 -8
- package/dist/runtime/composables/useNodeContextMenu.d.ts +4 -0
- package/dist/runtime/composables/useNodeContextMenu.js +18 -0
- package/dist/runtime/composables/useSettingsModal.d.ts +1 -1
- package/dist/runtime/locale.d.ts +8 -0
- package/dist/runtime/locale.js +9 -1
- package/dist/runtime/utils/chatContent.d.ts +20 -2
- package/dist/runtime/utils/chatContent.js +20 -1
- package/dist/runtime/utils/docTypes.js +43 -0
- package/dist/runtime/utils/titleSync.d.ts +130 -0
- package/dist/runtime/utils/titleSync.js +53 -0
- package/package.json +11 -1
|
@@ -5,8 +5,11 @@ import { Fragment } from "@tiptap/pm/model";
|
|
|
5
5
|
import { useSyncedMap } from "../composables/useYDoc";
|
|
6
6
|
import { resolveDocType, GEO_TYPE_META_SCHEMAS } from "../utils/docTypes";
|
|
7
7
|
import { schemaFieldToAttrs, userFieldToAttrs } from "../extensions/meta-field";
|
|
8
|
+
import { decideTitleSync, setHeaderText as applyHeaderText, UNTITLED } from "../utils/titleSync";
|
|
8
9
|
import { useEditor } from "../composables/useEditor";
|
|
9
10
|
import { useDocTree } from "../composables/useDocTree";
|
|
11
|
+
import { useDocBreadcrumb } from "../composables/useDocBreadcrumb";
|
|
12
|
+
import { useDocSlugs } from "../composables/useDocSlugs";
|
|
10
13
|
import { useEditorToolbar } from "../composables/useEditorToolbar";
|
|
11
14
|
import { useEditorSuggestions } from "../composables/useEditorSuggestions";
|
|
12
15
|
import { useEditorDragHandle } from "../composables/useEditorDragHandle";
|
|
@@ -28,7 +31,8 @@ const props = defineProps({
|
|
|
28
31
|
parentType: { type: String, required: false },
|
|
29
32
|
metaSchema: { type: Array, required: false },
|
|
30
33
|
variant: { type: String, required: false, default: "doc" },
|
|
31
|
-
showSourceToggle: { type: Boolean, required: false, default: false }
|
|
34
|
+
showSourceToggle: { type: Boolean, required: false, default: false },
|
|
35
|
+
showBreadcrumb: { type: Boolean, required: false, default: true }
|
|
32
36
|
});
|
|
33
37
|
const viewMode = ref("rich");
|
|
34
38
|
const emit = defineEmits(["ready", "update", "rename", "updateMeta"]);
|
|
@@ -167,79 +171,93 @@ function initDocumentMeta(ed) {
|
|
|
167
171
|
metaInitDone = true;
|
|
168
172
|
}
|
|
169
173
|
let syncingFromEditor = false;
|
|
170
|
-
|
|
174
|
+
let lastSyncedLabel = null;
|
|
171
175
|
function getHeaderText(ed) {
|
|
172
176
|
const first = ed.state.doc.firstChild;
|
|
173
177
|
if (!first || first.type.name !== "documentHeader") return "";
|
|
174
178
|
return first.textContent;
|
|
175
179
|
}
|
|
176
|
-
function
|
|
177
|
-
|
|
178
|
-
if (!first || first.type.name !== "documentHeader") return;
|
|
179
|
-
if (first.textContent === text) return;
|
|
180
|
-
const { tr, schema } = ed.state;
|
|
181
|
-
const to = 1 + first.content.size;
|
|
182
|
-
if (text) {
|
|
183
|
-
tr.replaceWith(1, to, schema.text(text));
|
|
184
|
-
} else {
|
|
185
|
-
tr.delete(1, to);
|
|
186
|
-
}
|
|
187
|
-
ed.view.dispatch(tr);
|
|
180
|
+
function currentTreeLabel() {
|
|
181
|
+
return _treeMap.data[props.docId]?.label ?? props.docLabel ?? "";
|
|
188
182
|
}
|
|
189
|
-
function
|
|
190
|
-
const
|
|
191
|
-
|
|
192
|
-
|
|
183
|
+
function writeTreeLabel(label) {
|
|
184
|
+
const e = _treeMap.data[props.docId];
|
|
185
|
+
const next = label || UNTITLED;
|
|
186
|
+
if (!e || e.label === next) return;
|
|
193
187
|
syncingFromEditor = true;
|
|
194
|
-
|
|
188
|
+
lastSyncedLabel = next;
|
|
189
|
+
_treeMap.set(props.docId, { ...e, label: next, updatedAt: Date.now() });
|
|
190
|
+
emit("rename", next);
|
|
195
191
|
nextTick(() => {
|
|
196
192
|
syncingFromEditor = false;
|
|
197
193
|
});
|
|
198
194
|
}
|
|
195
|
+
function syncHeader(ed, isRemoteUpdate, initialSyncDone) {
|
|
196
|
+
const action = decideTitleSync({
|
|
197
|
+
headerText: getHeaderText(ed),
|
|
198
|
+
treeLabel: currentTreeLabel(),
|
|
199
|
+
isRemoteUpdate,
|
|
200
|
+
initialSyncDone
|
|
201
|
+
});
|
|
202
|
+
if (action.kind === "noop") return;
|
|
203
|
+
if (action.kind === "header-from-tree") {
|
|
204
|
+
applyHeaderText(ed, action.text);
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
writeTreeLabel(action.label);
|
|
208
|
+
}
|
|
199
209
|
watchEffect((onCleanup) => {
|
|
200
210
|
const ed = editorRef.value?.editor;
|
|
201
211
|
if (!ed || !ready.value) return;
|
|
202
212
|
let initialSyncDone = false;
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
213
|
+
let headerTimer = null;
|
|
214
|
+
const runSync = (isRemote) => {
|
|
215
|
+
const wasInitial = !initialSyncDone;
|
|
216
|
+
if (wasInitial) initialSyncDone = true;
|
|
217
|
+
syncHeader(ed, isRemote, !wasInitial);
|
|
218
|
+
};
|
|
219
|
+
function onUpdate({ transaction }) {
|
|
220
|
+
const isRemote = !!transaction?.getMeta?.("y-sync$")?.isChangeOrigin;
|
|
221
|
+
initDocumentMeta(ed);
|
|
222
|
+
if (isRemote || !initialSyncDone) {
|
|
223
|
+
if (headerTimer) {
|
|
224
|
+
clearTimeout(headerTimer);
|
|
225
|
+
headerTimer = null;
|
|
215
226
|
}
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
227
|
+
runSync(isRemote);
|
|
228
|
+
} else {
|
|
229
|
+
if (headerTimer) clearTimeout(headerTimer);
|
|
230
|
+
headerTimer = setTimeout(() => {
|
|
231
|
+
headerTimer = null;
|
|
232
|
+
runSync(false);
|
|
233
|
+
}, 200);
|
|
222
234
|
}
|
|
223
235
|
}
|
|
224
|
-
function onUpdate() {
|
|
225
|
-
syncHeaderToTree(ed);
|
|
226
|
-
initDocumentMeta(ed);
|
|
227
|
-
}
|
|
228
236
|
nextTick(() => {
|
|
229
|
-
|
|
237
|
+
runSync(false);
|
|
230
238
|
initDocumentMeta(ed);
|
|
231
239
|
});
|
|
232
240
|
ed.on("update", onUpdate);
|
|
233
|
-
onCleanup(() =>
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
if (newLabel === _lastEmittedHeader.value) return;
|
|
238
|
-
if (!_treeMap.lastUpdateLocal.value) return;
|
|
239
|
-
const ed = editorRef.value?.editor;
|
|
240
|
-
if (!ed || !ready.value) return;
|
|
241
|
-
setHeaderText(ed, newLabel || "");
|
|
241
|
+
onCleanup(() => {
|
|
242
|
+
if (headerTimer) clearTimeout(headerTimer);
|
|
243
|
+
ed.off("update", onUpdate);
|
|
244
|
+
});
|
|
242
245
|
});
|
|
246
|
+
watch(
|
|
247
|
+
() => _treeMap.data[props.docId]?.label ?? props.docLabel,
|
|
248
|
+
(newLabel) => {
|
|
249
|
+
if (syncingFromEditor) return;
|
|
250
|
+
if (lastSyncedLabel !== null && newLabel === lastSyncedLabel) {
|
|
251
|
+
lastSyncedLabel = null;
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
lastSyncedLabel = null;
|
|
255
|
+
if (newLabel === void 0 || newLabel === "" || newLabel === UNTITLED) return;
|
|
256
|
+
const ed = editorRef.value?.editor;
|
|
257
|
+
if (!ed || !ready.value) return;
|
|
258
|
+
applyHeaderText(ed, newLabel);
|
|
259
|
+
}
|
|
260
|
+
);
|
|
243
261
|
function insertNode(editor, type, attrs, content) {
|
|
244
262
|
const node = { type, attrs };
|
|
245
263
|
if (content) node.content = content;
|
|
@@ -357,6 +375,11 @@ const editorHandlers = {
|
|
|
357
375
|
const _mentionItems = computed(
|
|
358
376
|
() => registry.getAllMentionProviders().flatMap((p) => p.label ? [p] : [])
|
|
359
377
|
);
|
|
378
|
+
const { items: _breadcrumbItems } = useDocBreadcrumb(() => props.docId);
|
|
379
|
+
const { getDocUrl } = useDocSlugs();
|
|
380
|
+
const ancestorChain = computed(
|
|
381
|
+
() => _breadcrumbItems.value.slice(0, -1).map((a) => ({ ...a, to: getDocUrl(a.id) }))
|
|
382
|
+
);
|
|
360
383
|
function onPlusClick(e, onClick) {
|
|
361
384
|
e.stopPropagation();
|
|
362
385
|
onClick();
|
|
@@ -387,7 +410,10 @@ function onPlusClick(e, onClick) {
|
|
|
387
410
|
>
|
|
388
411
|
<div class="aeditor-source-toolbar">
|
|
389
412
|
<span class="aeditor-source-toolbar__label">
|
|
390
|
-
<UIcon
|
|
413
|
+
<UIcon
|
|
414
|
+
name="i-lucide-code-xml"
|
|
415
|
+
class="size-3.5"
|
|
416
|
+
/>
|
|
391
417
|
XML source — read-only mirror of <code>getXmlFragment('default')</code>
|
|
392
418
|
</span>
|
|
393
419
|
<UButton
|
|
@@ -408,136 +434,178 @@ function onPlusClick(e, onClick) {
|
|
|
408
434
|
/>
|
|
409
435
|
</div>
|
|
410
436
|
|
|
411
|
-
|
|
437
|
+
<!-- Editor canvas: ancestor breadcrumb (cou-sh parity) + the TipTap editor,
|
|
438
|
+
stacked in one scroll container (the parent's overflow class falls
|
|
439
|
+
through to this wrapper). -->
|
|
440
|
+
<div
|
|
412
441
|
v-else
|
|
413
|
-
|
|
414
|
-
ref="editorRef"
|
|
415
|
-
v-slot="{ editor }"
|
|
416
|
-
v-model="model"
|
|
417
|
-
:content-type="contentType"
|
|
418
|
-
:editable="editable"
|
|
419
|
-
:extensions="extensions"
|
|
420
|
-
:starter-kit="{ undoRedo: false, codeBlock: false, document: false }"
|
|
421
|
-
:handlers="editorHandlers"
|
|
422
|
-
:placeholder="placeholder"
|
|
423
|
-
@update:model-value="emit('update', $event)"
|
|
442
|
+
class="aeditor-canvas"
|
|
424
443
|
>
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
class="aeditor-
|
|
429
|
-
icon="i-lucide-code-xml"
|
|
430
|
-
size="xs"
|
|
431
|
-
variant="ghost"
|
|
432
|
-
color="neutral"
|
|
433
|
-
:title="'View XML source'"
|
|
434
|
-
@click="viewMode = 'source'"
|
|
435
|
-
/>
|
|
436
|
-
<!-- Default slot: app can override entire editor content -->
|
|
437
|
-
<slot
|
|
438
|
-
:editor="editor"
|
|
439
|
-
:connected-users="connectedUsers"
|
|
440
|
-
:ready="ready"
|
|
444
|
+
<nav
|
|
445
|
+
v-if="showBreadcrumb && ancestorChain.length"
|
|
446
|
+
aria-label="Breadcrumb"
|
|
447
|
+
class="aeditor-breadcrumb"
|
|
441
448
|
>
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
layout="bubble"
|
|
451
|
-
:should-show="({ view, state }) => view.hasFocus() && !state.selection.empty"
|
|
452
|
-
>
|
|
453
|
-
<template #link>
|
|
454
|
-
<slot
|
|
455
|
-
name="link"
|
|
456
|
-
:editor="editor"
|
|
457
|
-
>
|
|
458
|
-
<ALinkPopover :editor="editor" />
|
|
459
|
-
</slot>
|
|
460
|
-
</template>
|
|
461
|
-
<template #doc-link>
|
|
462
|
-
<slot
|
|
463
|
-
name="doc-link"
|
|
464
|
-
:editor="editor"
|
|
449
|
+
<ol class="flex items-center gap-0.5 min-w-0">
|
|
450
|
+
<template
|
|
451
|
+
v-for="(ancestor, idx) in ancestorChain"
|
|
452
|
+
:key="ancestor.id"
|
|
453
|
+
>
|
|
454
|
+
<li
|
|
455
|
+
v-if="idx > 0"
|
|
456
|
+
class="flex shrink-0"
|
|
465
457
|
>
|
|
466
|
-
<
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
458
|
+
<UIcon
|
|
459
|
+
name="i-lucide-chevron-right"
|
|
460
|
+
class="size-4 text-(--ui-text-dimmed)"
|
|
461
|
+
/>
|
|
462
|
+
</li>
|
|
463
|
+
<li class="flex min-w-0">
|
|
464
|
+
<ULink
|
|
465
|
+
:to="ancestor.to"
|
|
466
|
+
class="flex items-center gap-1.5 px-1.5 py-0.5 rounded-md text-sm text-(--ui-text-muted) font-medium hover:bg-(--ui-bg-elevated)/60 hover:text-(--ui-text) transition-colors min-w-0 select-none"
|
|
467
|
+
>
|
|
468
|
+
<UIcon
|
|
469
|
+
:name="ancestor.icon"
|
|
470
|
+
class="size-4 shrink-0"
|
|
471
|
+
/>
|
|
472
|
+
<span class="truncate">{{ ancestor.label }}</span>
|
|
473
|
+
</ULink>
|
|
474
|
+
</li>
|
|
474
475
|
</template>
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
name="send-to-chat"
|
|
478
|
-
:editor="editor"
|
|
479
|
-
/>
|
|
480
|
-
</template>
|
|
481
|
-
</UEditorToolbar>
|
|
476
|
+
</ol>
|
|
477
|
+
</nav>
|
|
482
478
|
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
479
|
+
<UEditor
|
|
480
|
+
ref="editorRef"
|
|
481
|
+
v-slot="{ editor }"
|
|
482
|
+
v-model="model"
|
|
483
|
+
:class="{ 'prose-variant': variant === 'prose' }"
|
|
484
|
+
:content-type="contentType"
|
|
485
|
+
:editable="editable"
|
|
486
|
+
:extensions="extensions"
|
|
487
|
+
:starter-kit="{ undoRedo: false, codeBlock: false, document: false }"
|
|
488
|
+
:handlers="editorHandlers"
|
|
489
|
+
:placeholder="placeholder"
|
|
490
|
+
@update:model-value="emit('update', $event)"
|
|
491
|
+
>
|
|
492
|
+
<!-- Floating source-view toggle (opt-in via :show-source-toggle="true") -->
|
|
493
|
+
<UButton
|
|
494
|
+
v-if="showSourceToggle"
|
|
495
|
+
class="aeditor-source-toggle"
|
|
496
|
+
icon="i-lucide-code-xml"
|
|
497
|
+
size="xs"
|
|
498
|
+
variant="ghost"
|
|
499
|
+
color="neutral"
|
|
500
|
+
:title="'View XML source'"
|
|
501
|
+
@click="viewMode = 'source'"
|
|
488
502
|
/>
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
<UEditorEmojiMenu
|
|
503
|
+
<!-- Default slot: app can override entire editor content -->
|
|
504
|
+
<slot
|
|
492
505
|
:editor="editor"
|
|
493
|
-
:
|
|
494
|
-
|
|
506
|
+
:connected-users="connectedUsers"
|
|
507
|
+
:ready="ready"
|
|
508
|
+
>
|
|
509
|
+
<!-- ── Bubble toolbar (appears when text is selected) ─────────────── -->
|
|
510
|
+
<!-- 4 named slots are forwarded to consumers:
|
|
511
|
+
#link / #doc-link — defaulted to ALinkPopover / ADocLinkPopover
|
|
512
|
+
#create-child-doc / #send-to-chat — empty by default; app-defined -->
|
|
513
|
+
<UEditorToolbar
|
|
514
|
+
v-if="showToolbar"
|
|
515
|
+
:editor="editor"
|
|
516
|
+
:items="toolbarItems"
|
|
517
|
+
layout="bubble"
|
|
518
|
+
:should-show="({ view, state }) => view.hasFocus() && !state.selection.empty"
|
|
519
|
+
>
|
|
520
|
+
<template #link>
|
|
521
|
+
<slot
|
|
522
|
+
name="link"
|
|
523
|
+
:editor="editor"
|
|
524
|
+
>
|
|
525
|
+
<ALinkPopover :editor="editor" />
|
|
526
|
+
</slot>
|
|
527
|
+
</template>
|
|
528
|
+
<template #doc-link>
|
|
529
|
+
<slot
|
|
530
|
+
name="doc-link"
|
|
531
|
+
:editor="editor"
|
|
532
|
+
>
|
|
533
|
+
<ADocLinkPopover :editor="editor" />
|
|
534
|
+
</slot>
|
|
535
|
+
</template>
|
|
536
|
+
<template #create-child-doc>
|
|
537
|
+
<slot
|
|
538
|
+
name="create-child-doc"
|
|
539
|
+
:editor="editor"
|
|
540
|
+
/>
|
|
541
|
+
</template>
|
|
542
|
+
<template #send-to-chat>
|
|
543
|
+
<slot
|
|
544
|
+
name="send-to-chat"
|
|
545
|
+
:editor="editor"
|
|
546
|
+
/>
|
|
547
|
+
</template>
|
|
548
|
+
</UEditorToolbar>
|
|
495
549
|
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
550
|
+
<!-- ── Slash command menu ──────────────────────────────────────────── -->
|
|
551
|
+
<UEditorSuggestionMenu
|
|
552
|
+
v-if="showSuggestionMenu"
|
|
553
|
+
:editor="editor"
|
|
554
|
+
:items="suggestionItems"
|
|
555
|
+
/>
|
|
501
556
|
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
color="neutral"
|
|
513
|
-
variant="ghost"
|
|
514
|
-
size="sm"
|
|
515
|
-
:class="ui.handle()"
|
|
516
|
-
@click="(e) => onPlusClick(e, onClick)"
|
|
557
|
+
<!-- ── Emoji menu (`:` trigger) ───────────────────────────────────── -->
|
|
558
|
+
<UEditorEmojiMenu
|
|
559
|
+
:editor="editor"
|
|
560
|
+
:items="emojiItems"
|
|
561
|
+
/>
|
|
562
|
+
|
|
563
|
+
<!-- ── Mention menu (`@` trigger) — users + docs + plugin providers ── -->
|
|
564
|
+
<UEditorMentionMenu
|
|
565
|
+
:editor="editor"
|
|
566
|
+
:items="mentionItems"
|
|
517
567
|
/>
|
|
518
568
|
|
|
519
|
-
<!--
|
|
520
|
-
<
|
|
521
|
-
v-
|
|
522
|
-
|
|
523
|
-
:
|
|
524
|
-
|
|
525
|
-
:ui="{ content: 'w-48', label: 'text-xs' }"
|
|
526
|
-
@update:open="(v) => editor.chain().setMeta('lockDragHandle', v).run()"
|
|
569
|
+
<!-- ── Drag handle — plus button + grip dropdown ───────────────────── -->
|
|
570
|
+
<UEditorDragHandle
|
|
571
|
+
v-if="showDragHandle"
|
|
572
|
+
v-slot="{ ui, onClick }"
|
|
573
|
+
:editor="editor"
|
|
574
|
+
@node-change="dragHandle.onNodeChange"
|
|
527
575
|
>
|
|
576
|
+
<!-- Plus: insert block via slash menu -->
|
|
528
577
|
<UButton
|
|
578
|
+
icon="i-lucide-plus"
|
|
529
579
|
color="neutral"
|
|
530
580
|
variant="ghost"
|
|
531
|
-
:active-variant="'soft'"
|
|
532
581
|
size="sm"
|
|
533
|
-
icon="i-lucide-grip-vertical"
|
|
534
|
-
:active="open"
|
|
535
582
|
:class="ui.handle()"
|
|
583
|
+
@click="(e) => onPlusClick(e, onClick)"
|
|
536
584
|
/>
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
585
|
+
|
|
586
|
+
<!-- Grip: block context menu -->
|
|
587
|
+
<UDropdownMenu
|
|
588
|
+
v-slot="{ open }"
|
|
589
|
+
:modal="false"
|
|
590
|
+
:items="dragHandle.getItems(editor)"
|
|
591
|
+
:content="{ side: 'left' }"
|
|
592
|
+
:ui="{ content: 'w-48', label: 'text-xs' }"
|
|
593
|
+
@update:open="(v) => editor.chain().setMeta('lockDragHandle', v).run()"
|
|
594
|
+
>
|
|
595
|
+
<UButton
|
|
596
|
+
color="neutral"
|
|
597
|
+
variant="ghost"
|
|
598
|
+
:active-variant="'soft'"
|
|
599
|
+
size="sm"
|
|
600
|
+
icon="i-lucide-grip-vertical"
|
|
601
|
+
:active="open"
|
|
602
|
+
:class="ui.handle()"
|
|
603
|
+
/>
|
|
604
|
+
</UDropdownMenu>
|
|
605
|
+
</UEditorDragHandle>
|
|
606
|
+
</slot>
|
|
607
|
+
</UEditor>
|
|
608
|
+
</div>
|
|
541
609
|
|
|
542
610
|
<template #fallback>
|
|
543
611
|
<div
|
|
@@ -553,5 +621,5 @@ function onPlusClick(e, onClick) {
|
|
|
553
621
|
</template>
|
|
554
622
|
|
|
555
623
|
<style scoped>
|
|
556
|
-
.prose-variant :deep(.tiptap){color:var(--ui-text);font-family:ui-serif,Georgia,Cambria,Times New Roman,Times,serif;font-size:1.0625rem;line-height:1.75}.prose-variant :deep(.tiptap p){margin-bottom:1em;margin-top:0}.prose-variant :deep(.tiptap h1),.prose-variant :deep(.tiptap h2),.prose-variant :deep(.tiptap h3),.prose-variant :deep(.tiptap h4){font-family:ui-serif,Georgia,Cambria,Times New Roman,Times,serif;letter-spacing:-.01em;line-height:1.25;margin-bottom:.5em;margin-top:1.75em}.prose-variant :deep(.tiptap h1){font-size:2rem;font-weight:700}.prose-variant :deep(.tiptap h2){font-size:1.5rem;font-weight:700}.prose-variant :deep(.tiptap h3){font-size:1.25rem;font-weight:600}.prose-variant :deep(.tiptap blockquote){border-left:3px solid var(--ui-border);color:var(--ui-text-muted);font-style:italic;margin-left:0;padding-left:1em}.prose-variant :deep(.tiptap ol),.prose-variant :deep(.tiptap ul){margin-bottom:1em;padding-left:1.5em}.prose-variant :deep(.tiptap .document-header){font-family:ui-serif,Georgia,Cambria,Times New Roman,Times,serif;font-size:2.75rem;font-weight:700;letter-spacing:-.02em;line-height:1.15;margin-bottom:1.5rem}.aeditor-source-wrap{display:flex;flex:1 1 0;flex-direction:column;min-height:0}.aeditor-source-toolbar{align-items:center;background:var(--ui-bg);border-bottom:1px solid var(--ui-border);display:flex;flex-shrink:0;justify-content:space-between;padding:.375rem .75rem}.aeditor-source-toolbar__label{align-items:center;color:var(--ui-text-muted);display:inline-flex;font-size:.75rem;gap:.375rem}.aeditor-source-toolbar__label code{background:var(--ui-bg-elevated);border:1px solid var(--ui-border);border-radius:var(--ui-radius);font-family:ui-monospace,SF Mono,Menlo,Monaco,Consolas,monospace;font-size:.7rem;padding:.05rem .3rem}.aeditor-source-toggle{opacity:.6;position:absolute;right:.375rem;top:.375rem;transition:opacity .12s ease;z-index:5}.aeditor-source-toggle:hover{opacity:1}
|
|
624
|
+
.aeditor-canvas{display:flex;flex-direction:column;min-height:0}.aeditor-breadcrumb{flex-shrink:0;padding:.75rem 1rem 0}@media (min-width:640px){.aeditor-breadcrumb{padding-left:1.5rem;padding-right:1.5rem}}.prose-variant :deep(.tiptap){color:var(--ui-text);font-family:ui-serif,Georgia,Cambria,Times New Roman,Times,serif;font-size:1.0625rem;line-height:1.75}.prose-variant :deep(.tiptap p){margin-bottom:1em;margin-top:0}.prose-variant :deep(.tiptap h1),.prose-variant :deep(.tiptap h2),.prose-variant :deep(.tiptap h3),.prose-variant :deep(.tiptap h4){font-family:ui-serif,Georgia,Cambria,Times New Roman,Times,serif;letter-spacing:-.01em;line-height:1.25;margin-bottom:.5em;margin-top:1.75em}.prose-variant :deep(.tiptap h1){font-size:2rem;font-weight:700}.prose-variant :deep(.tiptap h2){font-size:1.5rem;font-weight:700}.prose-variant :deep(.tiptap h3){font-size:1.25rem;font-weight:600}.prose-variant :deep(.tiptap blockquote){border-left:3px solid var(--ui-border);color:var(--ui-text-muted);font-style:italic;margin-left:0;padding-left:1em}.prose-variant :deep(.tiptap ol),.prose-variant :deep(.tiptap ul){margin-bottom:1em;padding-left:1.5em}.prose-variant :deep(.tiptap .document-header){font-family:ui-serif,Georgia,Cambria,Times New Roman,Times,serif;font-size:2.75rem;font-weight:700;letter-spacing:-.02em;line-height:1.15;margin-bottom:1.5rem}.aeditor-source-wrap{display:flex;flex:1 1 0;flex-direction:column;min-height:0}.aeditor-source-toolbar{align-items:center;background:var(--ui-bg);border-bottom:1px solid var(--ui-border);display:flex;flex-shrink:0;justify-content:space-between;padding:.375rem .75rem}.aeditor-source-toolbar__label{align-items:center;color:var(--ui-text-muted);display:inline-flex;font-size:.75rem;gap:.375rem}.aeditor-source-toolbar__label code{background:var(--ui-bg-elevated);border:1px solid var(--ui-border);border-radius:var(--ui-radius);font-family:ui-monospace,SF Mono,Menlo,Monaco,Consolas,monospace;font-size:.7rem;padding:.05rem .3rem}.aeditor-source-toggle{opacity:.6;position:absolute;right:.375rem;top:.375rem;transition:opacity .12s ease;z-index:5}.aeditor-source-toggle:hover{opacity:1}
|
|
557
625
|
</style>
|
|
@@ -35,12 +35,18 @@ type __VLS_Props = {
|
|
|
35
35
|
* Useful for inspecting CRDT state during development. Default: false.
|
|
36
36
|
*/
|
|
37
37
|
showSourceToggle?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Show the in-canvas ancestor breadcrumb above the document (matching
|
|
40
|
+
* cou-sh's DocRenderer). Only renders when the doc actually has ancestors,
|
|
41
|
+
* so root/space docs show nothing. Set false for embeds/previews.
|
|
42
|
+
*/
|
|
43
|
+
showBreadcrumb?: boolean;
|
|
38
44
|
};
|
|
39
45
|
type __VLS_ModelProps = {
|
|
40
46
|
modelValue?: any;
|
|
41
47
|
};
|
|
42
48
|
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
43
|
-
declare var
|
|
49
|
+
declare var __VLS_58: {
|
|
44
50
|
editor: any;
|
|
45
51
|
connectedUsers: {
|
|
46
52
|
name: string;
|
|
@@ -49,25 +55,25 @@ declare var __VLS_42: {
|
|
|
49
55
|
docId?: string | undefined;
|
|
50
56
|
}[];
|
|
51
57
|
ready: boolean;
|
|
52
|
-
},
|
|
58
|
+
}, __VLS_67: {
|
|
53
59
|
editor: any;
|
|
54
|
-
},
|
|
60
|
+
}, __VLS_75: {
|
|
55
61
|
editor: any;
|
|
56
|
-
},
|
|
62
|
+
}, __VLS_83: {
|
|
57
63
|
editor: any;
|
|
58
|
-
},
|
|
64
|
+
}, __VLS_86: {
|
|
59
65
|
editor: any;
|
|
60
66
|
};
|
|
61
67
|
type __VLS_Slots = {} & {
|
|
62
|
-
default?: (props: typeof
|
|
68
|
+
default?: (props: typeof __VLS_58) => any;
|
|
63
69
|
} & {
|
|
64
|
-
link?: (props: typeof
|
|
70
|
+
link?: (props: typeof __VLS_67) => any;
|
|
65
71
|
} & {
|
|
66
|
-
'doc-link'?: (props: typeof
|
|
72
|
+
'doc-link'?: (props: typeof __VLS_75) => any;
|
|
67
73
|
} & {
|
|
68
|
-
'create-child-doc'?: (props: typeof
|
|
74
|
+
'create-child-doc'?: (props: typeof __VLS_83) => any;
|
|
69
75
|
} & {
|
|
70
|
-
'send-to-chat'?: (props: typeof
|
|
76
|
+
'send-to-chat'?: (props: typeof __VLS_86) => any;
|
|
71
77
|
};
|
|
72
78
|
declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
73
79
|
editor: import("vue").ComputedRef<any>;
|
|
@@ -91,6 +97,7 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
|
91
97
|
showDragHandle: boolean;
|
|
92
98
|
variant: "doc" | "prose";
|
|
93
99
|
showSourceToggle: boolean;
|
|
100
|
+
showBreadcrumb: boolean;
|
|
94
101
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
95
102
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
96
103
|
declare const _default: typeof __VLS_export;
|
|
@@ -16,12 +16,20 @@ type __VLS_Props = {
|
|
|
16
16
|
* slots are unaffected.
|
|
17
17
|
*/
|
|
18
18
|
tabs?: Array<'editor' | 'properties' | 'chat' | 'settings' | 'serverSettings'>;
|
|
19
|
+
/**
|
|
20
|
+
* Build the URL the "open as full page" (expand) button navigates to.
|
|
21
|
+
* Defaults to a slug-aware path derived from the configured `docBasePath`
|
|
22
|
+
* (`useDocSlugs().getDocUrl`), which resolves to the doc's slug when it has
|
|
23
|
+
* one and falls back to the raw id. Override to target a custom route shape.
|
|
24
|
+
*/
|
|
25
|
+
docHref?: (id: string) => string;
|
|
19
26
|
};
|
|
20
27
|
declare var __VLS_11: {
|
|
21
28
|
nodeId: string | null;
|
|
22
|
-
nodeLabel:
|
|
29
|
+
nodeLabel: any;
|
|
23
30
|
editor: any;
|
|
24
31
|
meta: DocPageMeta;
|
|
32
|
+
activeTab: string;
|
|
25
33
|
docTypeDef: import("../utils/docTypes.js").DocTypeDefinition;
|
|
26
34
|
};
|
|
27
35
|
type __VLS_Slots = {} & {
|