@ecsplico/editor 2.0.0 → 2.1.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/CHANGELOG.md +18 -0
- package/README.md +4 -3
- package/dist/adapters/anchors.d.ts +80 -0
- package/dist/adapters/anchors.js +270 -0
- package/dist/adapters/anchors.js.map +1 -0
- package/dist/adapters/comments/client.d.ts +64 -0
- package/dist/adapters/comments/client.js +536 -0
- package/dist/adapters/comments/client.js.map +1 -0
- package/dist/adapters/comments/drizzle.d.ts +430 -0
- package/dist/adapters/comments/drizzle.js +236 -0
- package/dist/adapters/comments/drizzle.js.map +1 -0
- package/dist/adapters/comments/errors.d.ts +9 -0
- package/dist/adapters/comments/errors.js +19 -0
- package/dist/adapters/comments/errors.js.map +1 -0
- package/dist/adapters/comments/json.d.ts +19 -0
- package/dist/adapters/comments/json.js +94 -0
- package/dist/adapters/comments/json.js.map +1 -0
- package/dist/adapters/comments/record.js +78 -0
- package/dist/adapters/comments/record.js.map +1 -0
- package/dist/adapters/comments/server.d.ts +23 -0
- package/dist/adapters/comments/server.js +102 -0
- package/dist/adapters/comments/server.js.map +1 -0
- package/dist/adapters/comments/types.d.ts +109 -0
- package/dist/adapters/documents.js +108 -0
- package/dist/adapters/documents.js.map +1 -0
- package/dist/adapters/drizzle.d.ts +293 -0
- package/dist/adapters/drizzle.js +157 -0
- package/dist/adapters/drizzle.js.map +1 -0
- package/dist/adapters/files.js +30 -0
- package/dist/adapters/files.js.map +1 -0
- package/dist/adapters/forge.d.ts +58 -0
- package/dist/adapters/forge.js +91 -0
- package/dist/adapters/forge.js.map +1 -0
- package/dist/adapters/index.d.ts +13 -0
- package/dist/adapters/index.js +0 -0
- package/dist/adapters/json.d.ts +24 -0
- package/dist/adapters/json.js +128 -0
- package/dist/adapters/json.js.map +1 -0
- package/dist/adapters/nitro.d.ts +61 -0
- package/dist/adapters/nitro.js +212 -0
- package/dist/adapters/nitro.js.map +1 -0
- package/dist/adapters/routes.js +16 -0
- package/dist/adapters/routes.js.map +1 -0
- package/dist/adapters/shared.d.ts +37 -0
- package/dist/adapters/shared.js +32 -0
- package/dist/adapters/shared.js.map +1 -0
- package/dist/adapters/vue.d.ts +67 -0
- package/dist/adapters/vue.js +187 -0
- package/dist/adapters/vue.js.map +1 -0
- package/dist/code/CodeSurface.vue.d.ts +3 -3
- package/dist/core/doc-anchors.d.ts +5 -0
- package/dist/core/doc-anchors.js +4 -3
- package/dist/core/doc-anchors.js.map +1 -1
- package/dist/core/editor-ui.js +57 -1
- package/dist/core/editor-ui.js.map +1 -1
- package/dist/core/surface-session.js +139 -0
- package/dist/core/surface-session.js.map +1 -0
- package/dist/document/DocumentSurface.d.ts +1 -1
- package/dist/document/DocumentSurface.vue.d.ts +3 -3
- package/dist/features/ai/agent-op-review.d.ts +2 -2
- package/dist/features/ai/agent-op-review.js.map +1 -1
- package/dist/features/ai/agent-ops.d.ts +1 -1
- package/dist/features/ai/agent-ops.js +9 -6
- package/dist/features/ai/agent-ops.js.map +1 -1
- package/dist/features/ai/ai-apply.d.ts +1 -1
- package/dist/features/ai/ai-review.js +10 -1
- package/dist/features/ai/ai-review.js.map +1 -1
- package/dist/features/ai/components/AiSelectionMenu.js +78 -252
- package/dist/features/ai/components/AiSelectionMenu.js.map +1 -1
- package/dist/features/ai/components/AiSelectionMenu.vue.d.ts +2 -1
- package/dist/features/ai/components/AiSidebar.js +2 -2
- package/dist/features/ai/components/DocumentChatAnswer.js +1 -1
- package/dist/features/ai/components/DocumentChatOps.js +1 -0
- package/dist/features/ai/components/DocumentChatOps.js.map +1 -1
- package/dist/features/ai/components/ModelQuickSwitch.js +1 -1
- package/dist/features/ai/components/SettingsAiTab.js +1 -1
- package/dist/features/ai/components/SettingsModelProfiles.js +1 -1
- package/dist/features/ai/document-chat.d.ts +3 -2
- package/dist/features/ai/document-chat.js +16 -19
- package/dist/features/ai/document-chat.js.map +1 -1
- package/dist/features/ai/index.d.ts +5 -3
- package/dist/features/ai/index.js +4 -2
- package/dist/features/ai/protocol/agent-ops.d.ts +22 -17
- package/dist/features/ai/protocol/agent-ops.js +65 -39
- package/dist/features/ai/protocol/agent-ops.js.map +1 -1
- package/dist/features/ai/protocol/block-lines.d.ts +89 -0
- package/dist/features/ai/protocol/block-lines.js +177 -0
- package/dist/features/ai/protocol/block-lines.js.map +1 -0
- package/dist/features/ai/protocol/chat.js +10 -10
- package/dist/features/ai/protocol/chat.js.map +1 -1
- package/dist/features/ai/protocol/index.d.ts +3 -2
- package/dist/features/ai/protocol/index.js +3 -2
- package/dist/features/ai/react/AiSelectionMenu.d.ts +3 -2
- package/dist/features/ai/react/AiSelectionMenu.js +64 -255
- package/dist/features/ai/react/AiSelectionMenu.js.map +1 -1
- package/dist/features/ai/react/AiSidebar.js +2 -2
- package/dist/features/ai/react/DocumentChatAnswer.js +1 -1
- package/dist/features/ai/react/DocumentChatOps.js +1 -0
- package/dist/features/ai/react/DocumentChatOps.js.map +1 -1
- package/dist/features/ai/react/ModelQuickSwitch.js +1 -1
- package/dist/features/ai/react/SettingsAiTab.js +1 -1
- package/dist/features/ai/react/SettingsModelProfiles.js +1 -1
- package/dist/features/ai/react/use-ai-selection-flow.js +34 -0
- package/dist/features/ai/react/use-ai-selection-flow.js.map +1 -0
- package/dist/features/ai/selection-flow.d.ts +133 -0
- package/dist/features/ai/selection-flow.js +283 -0
- package/dist/features/ai/selection-flow.js.map +1 -0
- package/dist/features/ai/use-ai-assistant.d.ts +1 -1
- package/dist/features/ai/use-document-chat.d.ts +1 -1
- package/dist/features/authors/components/AuthorColorsPanel.js +1 -1
- package/dist/features/authors/feature.js +1 -1
- package/dist/features/authors/index.js +1 -1
- package/dist/features/authors/react/AuthorColorsPanel.js +1 -1
- package/dist/features/comments/components/CommentBubble.js +1 -1
- package/dist/features/comments/components/CommentComposer.js +1 -1
- package/dist/features/comments/components/CommentThreadView.js +5 -2
- package/dist/features/comments/components/CommentThreadView.js.map +1 -1
- package/dist/features/comments/components/CommentsMargin.js +108 -230
- package/dist/features/comments/components/CommentsMargin.js.map +1 -1
- package/dist/features/comments/components/CommentsOverlay.js +1 -1
- package/dist/features/comments/feature.js +1 -1
- package/dist/features/comments/index.d.ts +4 -2
- package/dist/features/comments/index.js +4 -2
- package/dist/features/comments/margin-controller.d.ts +44 -0
- package/dist/features/comments/margin-controller.js +132 -0
- package/dist/features/comments/margin-controller.js.map +1 -0
- package/dist/features/comments/margin-layout.d.ts +55 -0
- package/dist/features/comments/margin-layout.js +79 -0
- package/dist/features/comments/margin-layout.js.map +1 -0
- package/dist/features/comments/model.d.ts +8 -0
- package/dist/features/comments/model.js +60 -34
- package/dist/features/comments/model.js.map +1 -1
- package/dist/features/comments/react/CommentBubble.js +1 -1
- package/dist/features/comments/react/CommentComposer.js +1 -1
- package/dist/features/comments/react/CommentThreadView.js +2 -2
- package/dist/features/comments/react/CommentThreadView.js.map +1 -1
- package/dist/features/comments/react/CommentsMargin.d.ts +0 -5
- package/dist/features/comments/react/CommentsMargin.js +85 -251
- package/dist/features/comments/react/CommentsMargin.js.map +1 -1
- package/dist/features/comments/react/CommentsOverlay.js +1 -1
- package/dist/features/comments/react/use-comments.js +1 -1
- package/dist/features/comments/react/use-margin-layout.js +45 -0
- package/dist/features/comments/react/use-margin-layout.js.map +1 -0
- package/dist/features/comments/react.d.ts +1 -1
- package/dist/features/comments/schema.d.ts +23 -0
- package/dist/features/comments/schema.js.map +1 -1
- package/dist/features/comments/snapshot-equality.js +40 -0
- package/dist/features/comments/snapshot-equality.js.map +1 -0
- package/dist/features/comments/thread-anchor.js +33 -0
- package/dist/features/comments/thread-anchor.js.map +1 -0
- package/dist/features/comments/use-comments.d.ts +3 -1
- package/dist/features/comments/use-comments.js +1 -0
- package/dist/features/comments/use-comments.js.map +1 -1
- package/dist/features/comments/use-margin-layout.js +29 -0
- package/dist/features/comments/use-margin-layout.js.map +1 -0
- package/dist/features/comments/vue.d.ts +1 -1
- package/dist/features/composites/accepted-children.d.ts +21 -0
- package/dist/features/composites/accepted-children.js +126 -0
- package/dist/features/composites/accepted-children.js.map +1 -0
- package/dist/features/composites/components/CompositeDetails.js +1 -1
- package/dist/features/composites/components/CompositeInspector.js +38 -164
- package/dist/features/composites/components/CompositeInspector.js.map +1 -1
- package/dist/features/composites/feature.d.ts +2 -1
- package/dist/features/composites/feature.js +8 -2
- package/dist/features/composites/feature.js.map +1 -1
- package/dist/features/composites/index.d.ts +5 -3
- package/dist/features/composites/index.js +8 -6
- package/dist/features/composites/inspector-model.d.ts +97 -0
- package/dist/features/composites/inspector-model.js +255 -0
- package/dist/features/composites/inspector-model.js.map +1 -0
- package/dist/features/composites/kinds.d.ts +11 -0
- package/dist/features/composites/kinds.js +17 -2
- package/dist/features/composites/kinds.js.map +1 -1
- package/dist/features/composites/outline.d.ts +18 -5
- package/dist/features/composites/outline.js +44 -12
- package/dist/features/composites/outline.js.map +1 -1
- package/dist/features/composites/react/CompositeDetails.js +1 -1
- package/dist/features/composites/react/CompositeInspector.d.ts +1 -1
- package/dist/features/composites/react/CompositeInspector.js +21 -180
- package/dist/features/composites/react/CompositeInspector.js.map +1 -1
- package/dist/features/composites/react/CompositeStatusMenu.d.ts +1 -1
- package/dist/features/composites/react/CompositeView.js +1 -1
- package/dist/features/composites/react/use-composite-inspector.js +29 -0
- package/dist/features/composites/react/use-composite-inspector.js.map +1 -0
- package/dist/features/composites/schema.d.ts +2 -2
- package/dist/features/composites/schema.js +2 -2
- package/dist/features/composites/schema.js.map +1 -1
- package/dist/features/composites/use-composite-anchors.d.ts +1 -1
- package/dist/features/composites/use-composite-inspector.js +41 -0
- package/dist/features/composites/use-composite-inspector.js.map +1 -0
- package/dist/features/composites/use-composite-rows.d.ts +1 -1
- package/dist/features/media/index.d.ts +1 -1
- package/dist/features/media/vue.d.ts +1 -1
- package/dist/features/mentions/index.d.ts +3 -3
- package/dist/features/mentions/index.js +3 -3
- package/dist/features/mentions/schema.d.ts +1 -1
- package/dist/features/mentions/schema.js +1 -1
- package/dist/features/themes/index.d.ts +1 -1
- package/dist/features/themes/index.js +1 -1
- package/dist/features/transcript/feature.js +1 -1
- package/dist/features/transcript/index.js +2 -2
- package/dist/i18n/de/ai.js +2 -0
- package/dist/i18n/de/ai.js.map +1 -1
- package/dist/i18n/de/composites.js +8 -1
- package/dist/i18n/de/composites.js.map +1 -1
- package/dist/i18n/de/tree.js +14 -1
- package/dist/i18n/de/tree.js.map +1 -1
- package/dist/i18n/de.d.ts +22 -0
- package/dist/i18n/en/ai.js +2 -0
- package/dist/i18n/en/ai.js.map +1 -1
- package/dist/i18n/en/composites.js +8 -1
- package/dist/i18n/en/composites.js.map +1 -1
- package/dist/i18n/en/tree.js +14 -1
- package/dist/i18n/en/tree.js.map +1 -1
- package/dist/integrations/composite-ai/composite-fill.js +2 -2
- package/dist/integrations/composite-ai/composite-summary.js +2 -2
- package/dist/integrations/composite-ai/index.js +2 -2
- package/dist/integrations/transcript-ai/transcript-cleanup.js +1 -1
- package/dist/markdown/MarkdownSurface.d.ts +1 -1
- package/dist/markdown/MarkdownSurface.js +2 -2
- package/dist/markdown/MarkdownSurface.vue.d.ts +7 -7
- package/dist/markdown/index.d.ts +2 -2
- package/dist/nuxt/runtime/server/routes/collab/[id].js +1 -1
- package/dist/react/EditorSurface.d.ts +1 -1
- package/dist/react/EditorSurface.js +43 -149
- package/dist/react/EditorSurface.js.map +1 -1
- package/dist/react/EditorToolbar.js +3 -40
- package/dist/react/EditorToolbar.js.map +1 -1
- package/dist/schema/advanced.js +2 -2
- package/dist/server/adapter.d.ts +2 -2
- package/dist/server/collab.js +1 -1
- package/dist/server/handlers/ai.d.ts +4 -2
- package/dist/server/handlers/ai.js +11 -9
- package/dist/server/handlers/ai.js.map +1 -1
- package/dist/server/handlers/context.d.ts +1 -1
- package/dist/server/handlers/editor.d.ts +1 -1
- package/dist/server/handlers/editor.js +2 -2
- package/dist/server/host.d.ts +1 -1
- package/dist/server/index.d.ts +2 -2
- package/dist/settings/index.d.ts +1 -1
- package/dist/styles/tokens.css +1 -1
- package/dist/tree/DocumentTree.js +159 -387
- package/dist/tree/DocumentTree.js.map +1 -1
- package/dist/tree/drop-rules.js +37 -0
- package/dist/tree/drop-rules.js.map +1 -0
- package/dist/tree/react/DocumentTree.d.ts +2 -2
- package/dist/tree/react/DocumentTree.js +135 -397
- package/dist/tree/react/DocumentTree.js.map +1 -1
- package/dist/tree/react/use-tree-model.js +129 -0
- package/dist/tree/react/use-tree-model.js.map +1 -0
- package/dist/tree/react.js +1 -1
- package/dist/tree/tree-host.js +100 -0
- package/dist/tree/tree-host.js.map +1 -0
- package/dist/tree/tree-items.js +22 -43
- package/dist/tree/tree-items.js.map +1 -1
- package/dist/tree/tree-model.js +580 -0
- package/dist/tree/tree-model.js.map +1 -0
- package/dist/tree/tree-rows.js +77 -0
- package/dist/tree/tree-rows.js.map +1 -0
- package/dist/tree/use-tree-model.js +94 -0
- package/dist/tree/use-tree-model.js.map +1 -0
- package/dist/tree/vue.js +1 -1
- package/dist/vue/AdvancedEditor.vue.d.ts +4 -4
- package/dist/vue/SimpleEditor.vue.d.ts +2 -2
- package/dist/vue/components/EditorSurface.js +27 -87
- package/dist/vue/components/EditorSurface.js.map +1 -1
- package/dist/vue/components/EditorSurface.vue.d.ts +4 -4
- package/dist/vue/components/EditorToolbar.js +7 -44
- package/dist/vue/components/EditorToolbar.js.map +1 -1
- package/dist/vue/context.d.ts +1 -1
- package/dist/vue/context.js +1 -1
- package/dist/vue/context.js.map +1 -1
- package/dist/vue/use-editor-ui.d.ts +1 -1
- package/dist/vue/use-notifier.d.ts +1 -1
- package/docs/integration.md +97 -4
- package/docs/llms.md +9 -1
- package/docs/usage.md +10 -5
- package/package.json +67 -5
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
import { metadataOf } from "../../../core/metadata.js";
|
|
2
|
-
import { METADATA_LIST } from "../../../core/metadata-types.js";
|
|
3
1
|
import { useUiKit } from "../../../vue/kit/use-ui-kit.js";
|
|
4
2
|
import { useEditorI18n } from "../../../vue/use-editor-i18n.js";
|
|
5
|
-
import { compositeKindsOf } from "../nodes.js";
|
|
6
|
-
import { compositeDescriptionText, compositeOfRow, setCompositeDescription, setCompositeMetaField, setCompositeTags } from "../rows.js";
|
|
7
3
|
import { normalizeTagName } from "../../../core/tag-name.js";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
4
|
+
import { compositeFieldText } from "../inspector-model.js";
|
|
5
|
+
import { useCompositeInspector } from "../use-composite-inspector.js";
|
|
6
|
+
import { Fragment, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, normalizeClass, normalizeStyle, openBlock, renderList, renderSlot, toDisplayString, unref, useId, withCtx } from "vue";
|
|
10
7
|
//#region src/features/composites/components/CompositeInspector.vue
|
|
11
8
|
const _hoisted_1 = ["aria-label"];
|
|
12
9
|
const _hoisted_2 = ["aria-labelledby"];
|
|
@@ -70,150 +67,24 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
70
67
|
const props = __props;
|
|
71
68
|
const { Badge: UBadge, FormField: UFormField, Icon: UIcon, Input: UInput, InputMenu: UInputMenu, Select: USelect, Textarea: UTextarea } = useUiKit();
|
|
72
69
|
const { t } = useEditorI18n();
|
|
73
|
-
const { rows, tags, kinds, mentions, focused } =
|
|
74
|
-
const
|
|
75
|
-
watch(() => props.documentFocused, (focused) => {
|
|
76
|
-
if (focused) caretIn.value = "document";
|
|
77
|
-
}, { immediate: true });
|
|
78
|
-
const section = computed(() => caretIn.value === "editor" && focused.value ? "composite" : "document");
|
|
79
|
-
const editable = shallowRef(true);
|
|
80
|
-
watch(() => props.editor, (instance, _previous, onCleanup) => {
|
|
81
|
-
editable.value = instance?.isEditable ?? false;
|
|
82
|
-
if (!instance) return;
|
|
83
|
-
const sync = () => {
|
|
84
|
-
editable.value = instance.isEditable;
|
|
85
|
-
};
|
|
86
|
-
const toEditor = () => {
|
|
87
|
-
caretIn.value = "editor";
|
|
88
|
-
};
|
|
89
|
-
instance.on("transaction", sync);
|
|
90
|
-
instance.on("focus", toEditor);
|
|
91
|
-
onCleanup(() => {
|
|
92
|
-
instance.off("transaction", sync);
|
|
93
|
-
instance.off("focus", toEditor);
|
|
94
|
-
});
|
|
95
|
-
}, { immediate: true });
|
|
96
|
-
const summarized = computed(() => rows.value.filter((row) => row.description.trim()).length);
|
|
70
|
+
const { inspector, section, editable, draft, searchTerm, tagItems, kindOptions, summarized, hasSummary, rows, tags, kinds, mentions, focused } = useCompositeInspector(() => props.editor, () => props.documentFocused);
|
|
71
|
+
const uid = useId();
|
|
97
72
|
const HEX_COLOR = /^#[0-9a-f]{3,8}$/i;
|
|
98
73
|
const mentionStyle = (color) => ({ "--mention-color": color && HEX_COLOR.test(color) ? color : "var(--sk-primary)" });
|
|
99
|
-
const kindItems = computed(() => props.editor ? compositeKindsOf(props.editor).map((kind) => ({
|
|
100
|
-
value: kind.id,
|
|
101
|
-
label: kind.label,
|
|
102
|
-
icon: kind.icon
|
|
103
|
-
})) : []);
|
|
104
74
|
function onKind(kind) {
|
|
105
|
-
|
|
106
|
-
const row = focused.value;
|
|
107
|
-
const found = instance && row ? compositeOfRow(instance.state.doc, row) : null;
|
|
108
|
-
if (typeof kind !== "string" || !instance || !found || kind === row?.kind) return;
|
|
109
|
-
instance.commands.setCompositeKind(kind, found.pos);
|
|
110
|
-
}
|
|
111
|
-
const draft = ref("");
|
|
112
|
-
let base = "";
|
|
113
|
-
let dirty = false;
|
|
114
|
-
let pendingRow = null;
|
|
115
|
-
let timer;
|
|
116
|
-
function loadDescription() {
|
|
117
|
-
dirty = false;
|
|
118
|
-
pendingRow = null;
|
|
119
|
-
base = focused.value?.description ?? "";
|
|
120
|
-
draft.value = base;
|
|
121
|
-
}
|
|
122
|
-
/** Writes the pending draft; `false` when there was nothing to write or a peer changed the description first. */
|
|
123
|
-
function commitDescription() {
|
|
124
|
-
clearTimeout(timer);
|
|
125
|
-
if (!dirty || !pendingRow) return false;
|
|
126
|
-
dirty = false;
|
|
127
|
-
const row = pendingRow;
|
|
128
|
-
pendingRow = null;
|
|
129
|
-
const instance = props.editor;
|
|
130
|
-
if (!instance || instance.isDestroyed || !instance.isEditable) return false;
|
|
131
|
-
if (!setCompositeDescription(instance, row, draft.value, base)) return false;
|
|
132
|
-
base = compositeDescriptionText(draft.value);
|
|
133
|
-
return true;
|
|
75
|
+
if (typeof kind === "string") inspector.value.setKind(kind);
|
|
134
76
|
}
|
|
135
77
|
function onDescriptionInput(value) {
|
|
136
|
-
|
|
137
|
-
dirty = true;
|
|
138
|
-
pendingRow ??= focused.value;
|
|
139
|
-
clearTimeout(timer);
|
|
140
|
-
timer = setTimeout(commitDescription, 600);
|
|
141
|
-
}
|
|
142
|
-
function onDescriptionBlur() {
|
|
143
|
-
if (commitDescription()) draft.value = base;
|
|
144
|
-
else loadDescription();
|
|
145
|
-
}
|
|
146
|
-
watch(() => focused.value?.key, () => {
|
|
147
|
-
commitDescription();
|
|
148
|
-
loadDescription();
|
|
149
|
-
}, { immediate: true });
|
|
150
|
-
watch(() => focused.value?.description, (description) => {
|
|
151
|
-
if (dirty) {
|
|
152
|
-
if (description !== base && !commitDescription()) loadDescription();
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
if (description !== base) loadDescription();
|
|
156
|
-
});
|
|
157
|
-
onBeforeUnmount(commitDescription);
|
|
158
|
-
watch(section, (next, previous) => {
|
|
159
|
-
if (previous === "composite" && next !== "composite") commitDescription();
|
|
160
|
-
});
|
|
161
|
-
const uid = useId();
|
|
162
|
-
const term = ref("");
|
|
163
|
-
const tagItems = ref([]);
|
|
164
|
-
let searchTimer;
|
|
165
|
-
let pendingSearch;
|
|
166
|
-
function scheduleSearch() {
|
|
167
|
-
clearTimeout(searchTimer);
|
|
168
|
-
searchTimer = setTimeout(async () => {
|
|
169
|
-
const instance = props.editor;
|
|
170
|
-
if (!instance) return;
|
|
171
|
-
pendingSearch?.abort();
|
|
172
|
-
const controller = pendingSearch = new AbortController();
|
|
173
|
-
try {
|
|
174
|
-
const found = await metadataOf(instance).search(METADATA_LIST.hashtags, {
|
|
175
|
-
query: term.value,
|
|
176
|
-
editor: instance,
|
|
177
|
-
signal: controller.signal
|
|
178
|
-
});
|
|
179
|
-
if (!controller.signal.aborted) tagItems.value = found.map((item) => item.label);
|
|
180
|
-
} catch (error) {
|
|
181
|
-
if (!controller.signal.aborted) console.warn("Tag-Vorschläge konnten nicht geladen werden", error);
|
|
182
|
-
}
|
|
183
|
-
}, 150);
|
|
78
|
+
inspector.value.inputDescription(typeof value === "string" ? value : "");
|
|
184
79
|
}
|
|
185
|
-
watch(term, scheduleSearch);
|
|
186
|
-
onBeforeUnmount(() => {
|
|
187
|
-
clearTimeout(searchTimer);
|
|
188
|
-
pendingSearch?.abort();
|
|
189
|
-
});
|
|
190
80
|
function onTags(value) {
|
|
191
|
-
|
|
192
|
-
}
|
|
193
|
-
function onCreateTag(raw) {
|
|
194
|
-
const row = focused.value;
|
|
195
|
-
const name = normalizeTagName(raw);
|
|
196
|
-
term.value = "";
|
|
197
|
-
if (!props.editor || !row || !name || row.tags.includes(name)) return;
|
|
198
|
-
setCompositeTags(props.editor, row, [...row.tags, name]);
|
|
199
|
-
if (!tagItems.value.includes(name)) metadataOf(props.editor).create(METADATA_LIST.hashtags, {
|
|
200
|
-
id: name,
|
|
201
|
-
label: name
|
|
202
|
-
});
|
|
203
|
-
}
|
|
204
|
-
function fieldText(field) {
|
|
205
|
-
const value = focused.value?.meta[field.key];
|
|
206
|
-
return typeof value === "string" || typeof value === "number" ? String(value) : "";
|
|
81
|
+
inspector.value.setTags(Array.isArray(value) ? value.filter((tag) => typeof tag === "string") : []);
|
|
207
82
|
}
|
|
208
|
-
function onField(field, value) {
|
|
209
|
-
if (props.editor?.isEditable && focused.value) setCompositeMetaField(props.editor, focused.value, field.key, value);
|
|
210
|
-
}
|
|
211
|
-
const hasSummary = computed(() => !!focused.value?.description.trim());
|
|
212
83
|
return (_ctx, _cache) => {
|
|
213
84
|
return openBlock(), createElementBlock("aside", {
|
|
214
85
|
class: "flex h-full min-h-0 flex-col overflow-y-auto text-sm",
|
|
215
86
|
"aria-label": unref(t)("composites.inspector.label")
|
|
216
|
-
}, [section
|
|
87
|
+
}, [unref(section) === "document" ? (openBlock(), createElementBlock("section", {
|
|
217
88
|
key: 0,
|
|
218
89
|
class: "flex-1 p-4",
|
|
219
90
|
"aria-labelledby": `${unref(uid)}-document`
|
|
@@ -235,7 +106,7 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
235
106
|
createElementVNode("span", _hoisted_9, toDisplayString(kind.count), 1)
|
|
236
107
|
]);
|
|
237
108
|
}), 128)), createElementVNode("span", _hoisted_10, toDisplayString(unref(t)("composites.inspector.summarized", {
|
|
238
|
-
n: summarized
|
|
109
|
+
n: unref(summarized),
|
|
239
110
|
total: unref(rows).length
|
|
240
111
|
})), 1)])) : (openBlock(), createElementBlock("dd", _hoisted_11, toDisplayString(unref(t)("composites.inspector.none")), 1)),
|
|
241
112
|
createElementVNode("dt", _hoisted_12, toDisplayString(unref(t)("composites.tags.label")), 1),
|
|
@@ -255,7 +126,7 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
255
126
|
key: mention.id,
|
|
256
127
|
class: "inline-flex max-w-full items-center gap-1.5 truncate rounded-sm px-1.5 py-0.5 text-xs font-medium text-[var(--sk-fg-highlighted)]",
|
|
257
128
|
style: normalizeStyle([mentionStyle(mention.color), { background: "color-mix(in oklab, var(--mention-color) 15%, transparent)" }])
|
|
258
|
-
}, [_cache[
|
|
129
|
+
}, [_cache[1] || (_cache[1] = createElementVNode("span", {
|
|
259
130
|
class: "size-1.5 shrink-0 rounded-full",
|
|
260
131
|
style: { background: "var(--mention-color)" }
|
|
261
132
|
}, null, -1)), createElementVNode("span", _hoisted_17, "@" + toDisplayString(mention.label), 1)], 4);
|
|
@@ -277,11 +148,11 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
277
148
|
}, {
|
|
278
149
|
default: withCtx(() => [createVNode(unref(USelect), {
|
|
279
150
|
"model-value": unref(focused).kind,
|
|
280
|
-
items:
|
|
151
|
+
items: unref(kindOptions),
|
|
281
152
|
size: "sm",
|
|
282
153
|
class: "w-full",
|
|
283
154
|
"aria-label": unref(t)("composites.kind.select"),
|
|
284
|
-
disabled: !editable
|
|
155
|
+
disabled: !unref(editable),
|
|
285
156
|
"onUpdate:modelValue": onKind
|
|
286
157
|
}, null, 8, [
|
|
287
158
|
"model-value",
|
|
@@ -294,7 +165,7 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
294
165
|
createVNode(unref(UFormField), {
|
|
295
166
|
label: unref(t)("composites.inspector.title"),
|
|
296
167
|
size: "sm",
|
|
297
|
-
help: editable
|
|
168
|
+
help: unref(editable) ? unref(t)("composites.inspector.titleHelp") : void 0
|
|
298
169
|
}, {
|
|
299
170
|
default: withCtx(() => [createElementVNode("p", {
|
|
300
171
|
class: normalizeClass(["min-h-6 truncate leading-6", unref(focused).title ? "text-[var(--sk-fg-highlighted)]" : "text-[var(--sk-fg-dimmed)]"]),
|
|
@@ -308,7 +179,7 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
308
179
|
help: unref(focused).descriptionTextOnly ? void 0 : unref(t)("composites.inspector.descriptionHelp")
|
|
309
180
|
}, {
|
|
310
181
|
default: withCtx(() => [createVNode(unref(UTextarea), {
|
|
311
|
-
"model-value": draft
|
|
182
|
+
"model-value": unref(draft),
|
|
312
183
|
autoresize: "",
|
|
313
184
|
rows: 3,
|
|
314
185
|
maxrows: 10,
|
|
@@ -316,14 +187,15 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
316
187
|
class: "w-full",
|
|
317
188
|
placeholder: unref(t)("composites.inspector.description"),
|
|
318
189
|
"aria-label": unref(t)("composites.inspector.description"),
|
|
319
|
-
readonly: !editable
|
|
190
|
+
readonly: !unref(editable) || !unref(focused).descriptionTextOnly,
|
|
320
191
|
"onUpdate:modelValue": onDescriptionInput,
|
|
321
|
-
onBlur:
|
|
192
|
+
onBlur: unref(inspector).blurDescription
|
|
322
193
|
}, null, 8, [
|
|
323
194
|
"model-value",
|
|
324
195
|
"placeholder",
|
|
325
196
|
"aria-label",
|
|
326
|
-
"readonly"
|
|
197
|
+
"readonly",
|
|
198
|
+
"onBlur"
|
|
327
199
|
])]),
|
|
328
200
|
_: 1
|
|
329
201
|
}, 8, ["label", "help"]),
|
|
@@ -332,25 +204,25 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
332
204
|
size: "sm"
|
|
333
205
|
}, {
|
|
334
206
|
default: withCtx(() => [createCommentVNode(" `position` is required in the object form: InputMenu renders the create row only for 'top' or 'bottom'. "), createVNode(unref(UInputMenu), {
|
|
335
|
-
"search-term":
|
|
336
|
-
"onUpdate:searchTerm": _cache[0] || (_cache[0] = ($event) => term.value = $event),
|
|
207
|
+
"search-term": unref(searchTerm),
|
|
337
208
|
multiple: "",
|
|
338
209
|
"create-item": {
|
|
339
210
|
position: "bottom",
|
|
340
211
|
when: "always"
|
|
341
212
|
},
|
|
342
213
|
"model-value": unref(focused).tags,
|
|
343
|
-
items: tagItems
|
|
214
|
+
items: unref(tagItems),
|
|
344
215
|
"ignore-filter": "",
|
|
345
216
|
placeholder: unref(t)("composites.tags.label"),
|
|
346
217
|
"aria-label": unref(t)("composites.tags.label"),
|
|
347
218
|
size: "sm",
|
|
348
219
|
icon: "i-lucide-hash",
|
|
349
220
|
class: "w-full",
|
|
350
|
-
disabled: !editable
|
|
221
|
+
disabled: !unref(editable),
|
|
351
222
|
"onUpdate:modelValue": onTags,
|
|
352
|
-
"onUpdate:
|
|
353
|
-
|
|
223
|
+
"onUpdate:searchTerm": unref(inspector).setSearchTerm,
|
|
224
|
+
"onUpdate:open": _cache[0] || (_cache[0] = (isOpen) => isOpen && unref(inspector).searchTags()),
|
|
225
|
+
onCreate: unref(inspector).createTag
|
|
354
226
|
}, {
|
|
355
227
|
"create-item-label": withCtx(({ item }) => [createTextVNode(toDisplayString(unref(t)("composites.tags.create", { tag: unref(normalizeTagName)(item) || item })), 1)]),
|
|
356
228
|
_: 1
|
|
@@ -360,7 +232,9 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
360
232
|
"items",
|
|
361
233
|
"placeholder",
|
|
362
234
|
"aria-label",
|
|
363
|
-
"disabled"
|
|
235
|
+
"disabled",
|
|
236
|
+
"onUpdate:searchTerm",
|
|
237
|
+
"onCreate"
|
|
364
238
|
])]),
|
|
365
239
|
_: 1
|
|
366
240
|
}, 8, ["label"]),
|
|
@@ -372,14 +246,14 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
372
246
|
}, {
|
|
373
247
|
default: withCtx(() => [field.type === "select" ? (openBlock(), createBlock(unref(USelect), {
|
|
374
248
|
key: 0,
|
|
375
|
-
"model-value":
|
|
249
|
+
"model-value": unref(compositeFieldText)(unref(focused), field) || void 0,
|
|
376
250
|
items: field.options ?? [],
|
|
377
251
|
"aria-label": field.label,
|
|
378
252
|
placeholder: "–",
|
|
379
253
|
size: "sm",
|
|
380
254
|
class: "w-full",
|
|
381
|
-
disabled: !editable
|
|
382
|
-
"onUpdate:modelValue": (value) =>
|
|
255
|
+
disabled: !unref(editable),
|
|
256
|
+
"onUpdate:modelValue": (value) => unref(inspector).setField(field, value)
|
|
383
257
|
}, null, 8, [
|
|
384
258
|
"model-value",
|
|
385
259
|
"items",
|
|
@@ -388,15 +262,15 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
388
262
|
"onUpdate:modelValue"
|
|
389
263
|
])) : field.type === "textarea" ? (openBlock(), createBlock(unref(UTextarea), {
|
|
390
264
|
key: 1,
|
|
391
|
-
"model-value":
|
|
265
|
+
"model-value": unref(compositeFieldText)(unref(focused), field),
|
|
392
266
|
"aria-label": field.label,
|
|
393
267
|
autoresize: "",
|
|
394
268
|
rows: 2,
|
|
395
269
|
maxrows: 8,
|
|
396
270
|
size: "sm",
|
|
397
271
|
class: "w-full",
|
|
398
|
-
readonly: !editable
|
|
399
|
-
"onUpdate:modelValue": (value) =>
|
|
272
|
+
readonly: !unref(editable),
|
|
273
|
+
"onUpdate:modelValue": (value) => unref(inspector).setField(field, value)
|
|
400
274
|
}, null, 8, [
|
|
401
275
|
"model-value",
|
|
402
276
|
"aria-label",
|
|
@@ -404,13 +278,13 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
404
278
|
"onUpdate:modelValue"
|
|
405
279
|
])) : (openBlock(), createBlock(unref(UInput), {
|
|
406
280
|
key: 2,
|
|
407
|
-
"model-value":
|
|
281
|
+
"model-value": unref(compositeFieldText)(unref(focused), field),
|
|
408
282
|
type: field.type,
|
|
409
283
|
"aria-label": field.label,
|
|
410
284
|
size: "sm",
|
|
411
285
|
class: "w-full",
|
|
412
|
-
readonly: !editable
|
|
413
|
-
"onUpdate:modelValue": (value) =>
|
|
286
|
+
readonly: !unref(editable),
|
|
287
|
+
"onUpdate:modelValue": (value) => unref(inspector).setField(field, value)
|
|
414
288
|
}, null, 8, [
|
|
415
289
|
"model-value",
|
|
416
290
|
"type",
|
|
@@ -427,7 +301,7 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
427
301
|
class: "size-4 shrink-0 text-[var(--sk-muted)]"
|
|
428
302
|
}),
|
|
429
303
|
createElementVNode("span", _hoisted_23, toDisplayString(unref(t)("composites.inspector.aiStatus")), 1),
|
|
430
|
-
createElementVNode("span", { class: normalizeClass(["ml-auto inline-flex items-center gap-1.5", hasSummary
|
|
304
|
+
createElementVNode("span", { class: normalizeClass(["ml-auto inline-flex items-center gap-1.5", unref(hasSummary) ? "text-[var(--sk-fg-highlighted)]" : "text-[var(--sk-fg-dimmed)]"]) }, [createElementVNode("span", { class: normalizeClass(["size-2 rounded-full", unref(hasSummary) ? "bg-[var(--sk-success)]" : "bg-[var(--sk-bg-accented)]"]) }, null, 2), createTextVNode(" " + toDisplayString(unref(hasSummary) ? unref(t)("composites.inspector.summaryPresent") : unref(t)("composites.inspector.summaryMissing")), 1)], 2)
|
|
431
305
|
])
|
|
432
306
|
]))], 8, _hoisted_19)) : createCommentVNode("v-if", true)], 8, _hoisted_1);
|
|
433
307
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CompositeInspector.js","names":["_openBlock","_createElementBlock","_unref","_createElementVNode","_toDisplayString","_renderSlot","_Fragment","_renderList","_createVNode","_createBlock","_normalizeStyle","_withCtx","_normalizeClass","_createCommentVNode","_createTextVNode"],"sources":["../../../../src/features/composites/components/CompositeInspector.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { Editor } from '@tiptap/core'\nimport { computed, onBeforeUnmount, ref, shallowRef, useId, watch } from 'vue'\nimport { metadataOf } from '../../../core/metadata'\nimport { METADATA_LIST } from '../../../core/metadata-types'\nimport { normalizeTagName } from '../../../core/tag-name'\nimport { useUiKit } from '../../../vue/kit/use-ui-kit'\nimport { useEditorI18n } from '../../../vue/use-editor-i18n'\nimport type { CompositeMetaField } from '../kinds'\nimport { compositeKindsOf } from '../nodes'\nimport { compositeDescriptionText, compositeOfRow, type CompositeRow, setCompositeDescription, setCompositeMetaField, setCompositeTags } from '../rows'\nimport { useCompositeRows } from '../use-composite-rows'\n\n/**\n * Side panel with the metadata of the document *or* of the Baustein under the caret — one at a time — connected to\n * `editor`. Fills the height of its container and scrolls on its own; the width comes from the host. Open/close is\n * the host's business. The `document` slot carries host-provided document facts (title, folder, dates, presence) at\n * the top of the „Dokument“ section: render them as a `<dl>` with the same grid as below to look native.\n *\n * The „Baustein“ section shows while the caret is in a Baustein of the editor; the „Dokument“ section shows before\n * the editor was ever focused, while the caret is in editor text outside any Baustein, and while `documentFocused`.\n * `documentFocused`: the host's document-level input (its title field) has the focus. While it is true the panel\n * shows the „Dokument“ section and keeps showing it after the input blurs, until the caret returns to the editor.\n */\nconst props = defineProps<{ editor?: Editor, documentFocused?: boolean }>()\n\nconst { Badge: UBadge, FormField: UFormField, Icon: UIcon, Input: UInput, InputMenu: UInputMenu, Select: USelect, Textarea: UTextarea } = useUiKit()\nconst { t } = useEditorI18n()\n\ndefineSlots<{\n /** Document facts known to the host only, rendered above the facts derived from the editor. */\n document?: () => unknown\n}>()\n\nconst { rows, tags, kinds, mentions, focused } = useCompositeRows(() => props.editor)\n\n// Where the caret was last: the host's document input or the editor. The panel keeps its section while it is clicked.\nconst caretIn = shallowRef<'document' | 'editor'>('document')\n// Only the rising edge switches; a blur of the host's input changes nothing.\nwatch(() => props.documentFocused, (focused) => {\n if (focused) caretIn.value = 'document'\n}, { immediate: true })\n// A deleted Baustein (`focused` null) falls back to the document section.\nconst section = computed<'document' | 'composite'>(() => caretIn.value === 'editor' && focused.value ? 'composite' : 'document')\n\n// `isEditable` is not reactive: follow it on every transaction (`EditorSurface` dispatches one after `setEditable`).\nconst editable = shallowRef(true)\nwatch(() => props.editor, (instance, _previous, onCleanup) => {\n editable.value = instance?.isEditable ?? false\n if (!instance) return\n const sync = () => {\n editable.value = instance.isEditable\n }\n const toEditor = () => {\n caretIn.value = 'editor'\n }\n instance.on('transaction', sync)\n // Only `focus`, not `selectionUpdate`: a collaboration sync can move the selection while the host's input has the focus.\n instance.on('focus', toEditor)\n onCleanup(() => {\n instance.off('transaction', sync)\n instance.off('focus', toEditor)\n })\n}, { immediate: true })\n\n// --- Dokument ---\nconst summarized = computed(() => rows.value.filter(row => row.description.trim()).length)\nconst HEX_COLOR = /^#[0-9a-f]{3,8}$/i\n// Same tint as the chip in the document (`--mention-color`), only invalid colors fall back to the primary color.\nconst mentionStyle = (color: string | null) => ({ '--mention-color': color && HEX_COLOR.test(color) ? color : 'var(--sk-primary)' })\n\n// --- Baustein: kind ---\nconst kindItems = computed(() => props.editor\n ? compositeKindsOf(props.editor).map(kind => ({ value: kind.id, label: kind.label, icon: kind.icon }))\n : [])\n\nfunction onKind(kind: unknown) {\n const instance = props.editor\n const row = focused.value\n const found = instance && row ? compositeOfRow(instance.state.doc, row) : null\n if (typeof kind !== 'string' || !instance || !found || kind === row?.kind) return\n instance.commands.setCompositeKind(kind, found.pos)\n}\n\n// --- Baustein: description ---\n// Local draft, committed 600 ms after typing pauses and on blur, so the re-read of the document never overwrites\n// the text (and moves the caret) while it is edited. `base` is the document text the draft started from: the write\n// only lands while the description still holds it, so a peer's change made meanwhile is never replaced.\nconst draft = ref('')\nlet base = ''\nlet dirty = false\nlet pendingRow: CompositeRow | null = null\nlet timer: ReturnType<typeof setTimeout> | undefined\n\nfunction loadDescription() {\n dirty = false\n pendingRow = null\n base = focused.value?.description ?? ''\n draft.value = base\n}\n\n/** Writes the pending draft; `false` when there was nothing to write or a peer changed the description first. */\nfunction commitDescription(): boolean {\n clearTimeout(timer)\n if (!dirty || !pendingRow) return false\n dirty = false\n const row = pendingRow\n pendingRow = null\n const instance = props.editor\n if (!instance || instance.isDestroyed || !instance.isEditable) return false\n if (!setCompositeDescription(instance, row, draft.value, base)) return false\n base = compositeDescriptionText(draft.value)\n return true\n}\n\nfunction onDescriptionInput(value: unknown) {\n draft.value = typeof value === 'string' ? value : ''\n dirty = true\n pendingRow ??= focused.value\n clearTimeout(timer)\n timer = setTimeout(commitDescription, 600)\n}\n\n// Show the text the document holds now: the normalized draft after a write, the live text otherwise (also after a\n// write refused because a peer changed the description first).\nfunction onDescriptionBlur() {\n if (commitDescription()) draft.value = base\n else loadDescription()\n}\n\n// Another Baustein: commit the draft of the previous one first (pre-flush: `draft` still holds its text), then load.\nwatch(() => focused.value?.key, () => {\n commitDescription()\n loadDescription()\n}, { immediate: true })\n// Every change of the description reaches an untouched draft, also while the textarea has focus. A draft with\n// unsaved typing keeps it; if a peer changed the description meanwhile, its commit is refused and the peer's text\n// is loaded instead.\nwatch(() => focused.value?.description, (description) => {\n if (dirty) {\n if (description !== base && !commitDescription()) loadDescription()\n return\n }\n if (description !== base) loadDescription()\n})\nonBeforeUnmount(commitDescription)\n// Leaving the Baustein section: commit the draft typed in the panel.\nwatch(section, (next, previous) => {\n if (previous === 'composite' && next !== 'composite') commitDescription()\n})\n\nconst uid = useId()\n\n// --- Baustein: tags (same behavior as `CompositeTagsEditor.vue`) ---\nconst term = ref('')\nconst tagItems = ref<string[]>([])\nlet searchTimer: ReturnType<typeof setTimeout> | undefined\nlet pendingSearch: AbortController | undefined\n\nfunction scheduleSearch() {\n clearTimeout(searchTimer)\n searchTimer = setTimeout(async () => {\n const instance = props.editor\n if (!instance) return\n pendingSearch?.abort()\n const controller = pendingSearch = new AbortController()\n try {\n const found = await metadataOf(instance).search(METADATA_LIST.hashtags, { query: term.value, editor: instance, signal: controller.signal })\n if (!controller.signal.aborted) tagItems.value = found.map(item => item.label)\n }\n catch (error) {\n if (!controller.signal.aborted) console.warn('Tag-Vorschläge konnten nicht geladen werden', error)\n }\n }, 150)\n}\nwatch(term, scheduleSearch)\nonBeforeUnmount(() => {\n clearTimeout(searchTimer)\n pendingSearch?.abort()\n})\n\nfunction onTags(value: unknown) {\n if (props.editor && focused.value) setCompositeTags(props.editor, focused.value, Array.isArray(value) ? value.filter((tag): tag is string => typeof tag === 'string') : [])\n}\n\n// „Neu Tag“ → `neu-tag`. A name that normalizes to an already chosen tag is ignored; only unknown names are reported as created.\nfunction onCreateTag(raw: string) {\n const row = focused.value\n const name = normalizeTagName(raw)\n term.value = ''\n if (!props.editor || !row || !name || row.tags.includes(name)) return\n setCompositeTags(props.editor, row, [...row.tags, name])\n if (!tagItems.value.includes(name)) metadataOf(props.editor).create(METADATA_LIST.hashtags, { id: name, label: name })\n}\n\n// --- Baustein: fields ---\nfunction fieldText(field: CompositeMetaField): string {\n const value = focused.value?.meta[field.key]\n return typeof value === 'string' || typeof value === 'number' ? String(value) : ''\n}\n\nfunction onField(field: CompositeMetaField, value: unknown) {\n if (props.editor?.isEditable && focused.value) setCompositeMetaField(props.editor, focused.value, field.key, value)\n}\n\nconst hasSummary = computed(() => !!focused.value?.description.trim())\n</script>\n\n<template>\n <aside class=\"flex h-full min-h-0 flex-col overflow-y-auto text-sm\" :aria-label=\"t('composites.inspector.label')\">\n <section v-if=\"section === 'document'\" class=\"flex-1 p-4\" :aria-labelledby=\"`${uid}-document`\">\n <h2 :id=\"`${uid}-document`\" class=\"mb-3 text-sm font-semibold text-[var(--sk-fg-highlighted)]\">\n {{ t('composites.inspector.document') }}\n </h2>\n <div class=\"flex flex-col gap-y-2\">\n <slot name=\"document\" />\n <dl class=\"grid grid-cols-[6.5rem_minmax(0,1fr)] items-start gap-x-3 gap-y-2\">\n <dt class=\"min-h-6 leading-6 text-[var(--sk-muted)]\">\n {{ t('composites.inspector.composites') }}\n </dt>\n <dd v-if=\"kinds.length\" class=\"m-0 flex min-w-0 flex-col gap-y-1\">\n <span v-for=\"kind in kinds\" :key=\"kind.id\" class=\"flex min-h-6 min-w-0 items-center gap-2\">\n <UIcon :name=\"kind.icon\" class=\"size-4 shrink-0 text-[var(--sk-muted)]\" />\n <span class=\"min-w-0 flex-1 truncate text-[var(--sk-fg-highlighted)]\">{{ kind.label }}</span>\n <span class=\"tabular-nums text-[var(--sk-muted)]\">{{ kind.count }}</span>\n </span>\n <span class=\"min-h-6 leading-6 tabular-nums text-[var(--sk-muted)]\">\n {{ t('composites.inspector.summarized', { n: summarized, total: rows.length }) }}\n </span>\n </dd>\n <dd v-else class=\"m-0 min-h-6 leading-6 text-[var(--sk-fg-dimmed)]\">\n {{ t('composites.inspector.none') }}\n </dd>\n\n <dt class=\"min-h-6 leading-6 text-[var(--sk-muted)]\">\n {{ t('composites.tags.label') }}\n </dt>\n <dd v-if=\"tags.length\" class=\"m-0 flex min-w-0 flex-wrap items-center gap-1\">\n <UBadge v-for=\"tag in tags\" :key=\"tag\" color=\"neutral\" variant=\"subtle\" size=\"sm\" :label=\"`#${tag}`\" class=\"max-w-full\" />\n </dd>\n <dd v-else class=\"m-0 min-h-6 leading-6 text-[var(--sk-fg-dimmed)]\">\n {{ t('composites.inspector.none') }}\n </dd>\n\n <dt class=\"min-h-6 leading-6 text-[var(--sk-muted)]\">\n {{ t('composites.inspector.mentions') }}\n </dt>\n <dd v-if=\"mentions.length\" class=\"m-0 flex min-w-0 flex-wrap items-center gap-1\">\n <span\n v-for=\"mention in mentions\"\n :key=\"mention.id\"\n class=\"inline-flex max-w-full items-center gap-1.5 truncate rounded-sm px-1.5 py-0.5 text-xs font-medium text-[var(--sk-fg-highlighted)]\"\n :style=\"[mentionStyle(mention.color), { background: 'color-mix(in oklab, var(--mention-color) 15%, transparent)' }]\"\n >\n <span class=\"size-1.5 shrink-0 rounded-full\" :style=\"{ background: 'var(--mention-color)' }\" />\n <span class=\"truncate\">@{{ mention.label }}</span>\n </span>\n </dd>\n <dd v-else class=\"m-0 min-h-6 leading-6 text-[var(--sk-fg-dimmed)]\">\n {{ t('composites.inspector.none') }}\n </dd>\n </dl>\n </div>\n </section>\n <section v-else-if=\"focused\" class=\"flex-1 p-4\" :aria-labelledby=\"`${uid}-composite`\">\n <h2 :id=\"`${uid}-composite`\" class=\"mb-3 text-sm font-semibold text-[var(--sk-fg-highlighted)]\">\n {{ t('composites.inspector.composite') }}\n </h2>\n\n <div :key=\"focused.key\" class=\"flex flex-col gap-3\">\n <UFormField :label=\"t('composites.inspector.kind')\" size=\"sm\">\n <USelect\n :model-value=\"focused.kind\"\n :items=\"kindItems\"\n size=\"sm\"\n class=\"w-full\"\n :aria-label=\"t('composites.kind.select')\"\n :disabled=\"!editable\"\n @update:model-value=\"onKind\"\n />\n </UFormField>\n\n <UFormField :label=\"t('composites.inspector.title')\" size=\"sm\" :help=\"editable ? t('composites.inspector.titleHelp') : undefined\">\n <p class=\"min-h-6 truncate leading-6\" :class=\"focused.title ? 'text-[var(--sk-fg-highlighted)]' : 'text-[var(--sk-fg-dimmed)]'\" :title=\"focused.title\">\n {{ focused.title || t('composites.inspector.untitled') }}\n </p>\n </UFormField>\n\n <UFormField\n :label=\"t('composites.inspector.description')\"\n size=\"sm\"\n :help=\"focused.descriptionTextOnly ? undefined : t('composites.inspector.descriptionHelp')\"\n >\n <UTextarea\n :model-value=\"draft\"\n autoresize\n :rows=\"3\"\n :maxrows=\"10\"\n size=\"sm\"\n class=\"w-full\"\n :placeholder=\"t('composites.inspector.description')\"\n :aria-label=\"t('composites.inspector.description')\"\n :readonly=\"!editable || !focused.descriptionTextOnly\"\n @update:model-value=\"onDescriptionInput\"\n @blur=\"onDescriptionBlur\"\n />\n </UFormField>\n\n <UFormField :label=\"t('composites.tags.label')\" size=\"sm\">\n <!-- `position` is required in the object form: InputMenu renders the create row only for 'top' or 'bottom'. -->\n <UInputMenu\n v-model:search-term=\"term\"\n multiple\n :create-item=\"{ position: 'bottom', when: 'always' }\"\n :model-value=\"focused.tags\"\n :items=\"tagItems\"\n ignore-filter\n :placeholder=\"t('composites.tags.label')\"\n :aria-label=\"t('composites.tags.label')\"\n size=\"sm\"\n icon=\"i-lucide-hash\"\n class=\"w-full\"\n :disabled=\"!editable\"\n @update:model-value=\"onTags\"\n @update:open=\"(isOpen: boolean) => isOpen && scheduleSearch()\"\n @create=\"onCreateTag\"\n >\n <template #create-item-label=\"{ item }: { item: string }\">\n {{ t('composites.tags.create', { tag: normalizeTagName(item) || item }) }}\n </template>\n </UInputMenu>\n </UFormField>\n\n <UFormField v-for=\"field in focused.fields\" :key=\"field.key\" :label=\"field.label\" size=\"sm\">\n <USelect\n v-if=\"field.type === 'select'\"\n :model-value=\"fieldText(field) || undefined\"\n :items=\"field.options ?? []\"\n :aria-label=\"field.label\"\n placeholder=\"–\"\n size=\"sm\"\n class=\"w-full\"\n :disabled=\"!editable\"\n @update:model-value=\"(value: unknown) => onField(field, value)\"\n />\n <UTextarea\n v-else-if=\"field.type === 'textarea'\"\n :model-value=\"fieldText(field)\"\n :aria-label=\"field.label\"\n autoresize\n :rows=\"2\"\n :maxrows=\"8\"\n size=\"sm\"\n class=\"w-full\"\n :readonly=\"!editable\"\n @update:model-value=\"(value: unknown) => onField(field, value)\"\n />\n <UInput\n v-else\n :model-value=\"fieldText(field)\"\n :type=\"field.type\"\n :aria-label=\"field.label\"\n size=\"sm\"\n class=\"w-full\"\n :readonly=\"!editable\"\n @update:model-value=\"(value: unknown) => onField(field, value)\"\n />\n </UFormField>\n\n <div class=\"flex items-center gap-2 border-t border-[var(--sk-border)] pt-3\">\n <UIcon name=\"i-lucide-sparkles\" class=\"size-4 shrink-0 text-[var(--sk-muted)]\" />\n <span class=\"text-[var(--sk-muted)]\">{{ t('composites.inspector.aiStatus') }}</span>\n <span class=\"ml-auto inline-flex items-center gap-1.5\" :class=\"hasSummary ? 'text-[var(--sk-fg-highlighted)]' : 'text-[var(--sk-fg-dimmed)]'\">\n <span class=\"size-2 rounded-full\" :class=\"hasSummary ? 'bg-[var(--sk-success)]' : 'bg-[var(--sk-bg-accented)]'\" />\n {{ hasSummary ? t('composites.inspector.summaryPresent') : t('composites.inspector.summaryMissing') }}\n </span>\n </div>\n </div>\n </section>\n </aside>\n</template>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CompositeInspector.js","names":["_openBlock","_createElementBlock","_unref","_createElementVNode","_toDisplayString","_renderSlot","_Fragment","_renderList","_createVNode","_createBlock","_normalizeStyle","_withCtx","_normalizeClass","_createCommentVNode","_createTextVNode"],"sources":["../../../../src/features/composites/components/CompositeInspector.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { Editor } from '@tiptap/core'\nimport { useId } from 'vue'\nimport { normalizeTagName } from '../../../core/tag-name'\nimport { useUiKit } from '../../../vue/kit/use-ui-kit'\nimport { useEditorI18n } from '../../../vue/use-editor-i18n'\nimport { compositeFieldText } from '../inspector-model'\nimport { useCompositeInspector } from '../use-composite-inspector'\n\n/**\n * Side panel with the metadata of the document *or* of the Baustein under the caret — one at a time — connected to\n * `editor`. Fills the height of its container and scrolls on its own; the width comes from the host. Open/close is\n * the host's business. The `document` slot carries host-provided document facts (title, folder, dates, presence) at\n * the top of the „Dokument“ section: render them as a `<dl>` with the same grid as below to look native.\n *\n * The „Baustein“ section shows while the caret is in a Baustein of the editor; the „Dokument“ section shows before\n * the editor was ever focused, while the caret is in editor text outside any Baustein, and while `documentFocused`.\n * `documentFocused`: the host's document-level input (its title field) has the focus. While it is true the panel\n * shows the „Dokument“ section and keeps showing it after the input blurs, until the caret returns to the editor.\n */\nconst props = defineProps<{ editor?: Editor, documentFocused?: boolean }>()\n\nconst { Badge: UBadge, FormField: UFormField, Icon: UIcon, Input: UInput, InputMenu: UInputMenu, Select: USelect, Textarea: UTextarea } = useUiKit()\nconst { t } = useEditorI18n()\n\ndefineSlots<{\n /** Document facts known to the host only, rendered above the facts derived from the editor. */\n document?: () => unknown\n}>()\n\nconst { inspector, section, editable, draft, searchTerm, tagItems, kindOptions, summarized, hasSummary, rows, tags, kinds, mentions, focused } = useCompositeInspector(() => props.editor, () => props.documentFocused)\n\nconst uid = useId()\n\nconst HEX_COLOR = /^#[0-9a-f]{3,8}$/i\n// Same tint as the chip in the document (`--mention-color`), only invalid colors fall back to the primary color.\nconst mentionStyle = (color: string | null) => ({ '--mention-color': color && HEX_COLOR.test(color) ? color : 'var(--sk-primary)' })\n\n// The Nuxt UI inputs emit loosely typed values; the model takes strings.\nfunction onKind(kind: unknown) {\n if (typeof kind === 'string') inspector.value.setKind(kind)\n}\n\nfunction onDescriptionInput(value: unknown) {\n inspector.value.inputDescription(typeof value === 'string' ? value : '')\n}\n\nfunction onTags(value: unknown) {\n inspector.value.setTags(Array.isArray(value) ? value.filter((tag): tag is string => typeof tag === 'string') : [])\n}\n</script>\n\n<template>\n <aside class=\"flex h-full min-h-0 flex-col overflow-y-auto text-sm\" :aria-label=\"t('composites.inspector.label')\">\n <section v-if=\"section === 'document'\" class=\"flex-1 p-4\" :aria-labelledby=\"`${uid}-document`\">\n <h2 :id=\"`${uid}-document`\" class=\"mb-3 text-sm font-semibold text-[var(--sk-fg-highlighted)]\">\n {{ t('composites.inspector.document') }}\n </h2>\n <div class=\"flex flex-col gap-y-2\">\n <slot name=\"document\" />\n <dl class=\"grid grid-cols-[6.5rem_minmax(0,1fr)] items-start gap-x-3 gap-y-2\">\n <dt class=\"min-h-6 leading-6 text-[var(--sk-muted)]\">\n {{ t('composites.inspector.composites') }}\n </dt>\n <dd v-if=\"kinds.length\" class=\"m-0 flex min-w-0 flex-col gap-y-1\">\n <span v-for=\"kind in kinds\" :key=\"kind.id\" class=\"flex min-h-6 min-w-0 items-center gap-2\">\n <UIcon :name=\"kind.icon\" class=\"size-4 shrink-0 text-[var(--sk-muted)]\" />\n <span class=\"min-w-0 flex-1 truncate text-[var(--sk-fg-highlighted)]\">{{ kind.label }}</span>\n <span class=\"tabular-nums text-[var(--sk-muted)]\">{{ kind.count }}</span>\n </span>\n <span class=\"min-h-6 leading-6 tabular-nums text-[var(--sk-muted)]\">\n {{ t('composites.inspector.summarized', { n: summarized, total: rows.length }) }}\n </span>\n </dd>\n <dd v-else class=\"m-0 min-h-6 leading-6 text-[var(--sk-fg-dimmed)]\">\n {{ t('composites.inspector.none') }}\n </dd>\n\n <dt class=\"min-h-6 leading-6 text-[var(--sk-muted)]\">\n {{ t('composites.tags.label') }}\n </dt>\n <dd v-if=\"tags.length\" class=\"m-0 flex min-w-0 flex-wrap items-center gap-1\">\n <UBadge v-for=\"tag in tags\" :key=\"tag\" color=\"neutral\" variant=\"subtle\" size=\"sm\" :label=\"`#${tag}`\" class=\"max-w-full\" />\n </dd>\n <dd v-else class=\"m-0 min-h-6 leading-6 text-[var(--sk-fg-dimmed)]\">\n {{ t('composites.inspector.none') }}\n </dd>\n\n <dt class=\"min-h-6 leading-6 text-[var(--sk-muted)]\">\n {{ t('composites.inspector.mentions') }}\n </dt>\n <dd v-if=\"mentions.length\" class=\"m-0 flex min-w-0 flex-wrap items-center gap-1\">\n <span\n v-for=\"mention in mentions\"\n :key=\"mention.id\"\n class=\"inline-flex max-w-full items-center gap-1.5 truncate rounded-sm px-1.5 py-0.5 text-xs font-medium text-[var(--sk-fg-highlighted)]\"\n :style=\"[mentionStyle(mention.color), { background: 'color-mix(in oklab, var(--mention-color) 15%, transparent)' }]\"\n >\n <span class=\"size-1.5 shrink-0 rounded-full\" :style=\"{ background: 'var(--mention-color)' }\" />\n <span class=\"truncate\">@{{ mention.label }}</span>\n </span>\n </dd>\n <dd v-else class=\"m-0 min-h-6 leading-6 text-[var(--sk-fg-dimmed)]\">\n {{ t('composites.inspector.none') }}\n </dd>\n </dl>\n </div>\n </section>\n <section v-else-if=\"focused\" class=\"flex-1 p-4\" :aria-labelledby=\"`${uid}-composite`\">\n <h2 :id=\"`${uid}-composite`\" class=\"mb-3 text-sm font-semibold text-[var(--sk-fg-highlighted)]\">\n {{ t('composites.inspector.composite') }}\n </h2>\n\n <div :key=\"focused.key\" class=\"flex flex-col gap-3\">\n <UFormField :label=\"t('composites.inspector.kind')\" size=\"sm\">\n <USelect\n :model-value=\"focused.kind\"\n :items=\"kindOptions\"\n size=\"sm\"\n class=\"w-full\"\n :aria-label=\"t('composites.kind.select')\"\n :disabled=\"!editable\"\n @update:model-value=\"onKind\"\n />\n </UFormField>\n\n <UFormField :label=\"t('composites.inspector.title')\" size=\"sm\" :help=\"editable ? t('composites.inspector.titleHelp') : undefined\">\n <p class=\"min-h-6 truncate leading-6\" :class=\"focused.title ? 'text-[var(--sk-fg-highlighted)]' : 'text-[var(--sk-fg-dimmed)]'\" :title=\"focused.title\">\n {{ focused.title || t('composites.inspector.untitled') }}\n </p>\n </UFormField>\n\n <UFormField\n :label=\"t('composites.inspector.description')\"\n size=\"sm\"\n :help=\"focused.descriptionTextOnly ? undefined : t('composites.inspector.descriptionHelp')\"\n >\n <UTextarea\n :model-value=\"draft\"\n autoresize\n :rows=\"3\"\n :maxrows=\"10\"\n size=\"sm\"\n class=\"w-full\"\n :placeholder=\"t('composites.inspector.description')\"\n :aria-label=\"t('composites.inspector.description')\"\n :readonly=\"!editable || !focused.descriptionTextOnly\"\n @update:model-value=\"onDescriptionInput\"\n @blur=\"inspector.blurDescription\"\n />\n </UFormField>\n\n <UFormField :label=\"t('composites.tags.label')\" size=\"sm\">\n <!-- `position` is required in the object form: InputMenu renders the create row only for 'top' or 'bottom'. -->\n <UInputMenu\n :search-term=\"searchTerm\"\n multiple\n :create-item=\"{ position: 'bottom', when: 'always' }\"\n :model-value=\"focused.tags\"\n :items=\"tagItems\"\n ignore-filter\n :placeholder=\"t('composites.tags.label')\"\n :aria-label=\"t('composites.tags.label')\"\n size=\"sm\"\n icon=\"i-lucide-hash\"\n class=\"w-full\"\n :disabled=\"!editable\"\n @update:model-value=\"onTags\"\n @update:search-term=\"inspector.setSearchTerm\"\n @update:open=\"(isOpen: boolean) => isOpen && inspector.searchTags()\"\n @create=\"inspector.createTag\"\n >\n <template #create-item-label=\"{ item }: { item: string }\">\n {{ t('composites.tags.create', { tag: normalizeTagName(item) || item }) }}\n </template>\n </UInputMenu>\n </UFormField>\n\n <UFormField v-for=\"field in focused.fields\" :key=\"field.key\" :label=\"field.label\" size=\"sm\">\n <USelect\n v-if=\"field.type === 'select'\"\n :model-value=\"compositeFieldText(focused, field) || undefined\"\n :items=\"field.options ?? []\"\n :aria-label=\"field.label\"\n placeholder=\"–\"\n size=\"sm\"\n class=\"w-full\"\n :disabled=\"!editable\"\n @update:model-value=\"(value: unknown) => inspector.setField(field, value)\"\n />\n <UTextarea\n v-else-if=\"field.type === 'textarea'\"\n :model-value=\"compositeFieldText(focused, field)\"\n :aria-label=\"field.label\"\n autoresize\n :rows=\"2\"\n :maxrows=\"8\"\n size=\"sm\"\n class=\"w-full\"\n :readonly=\"!editable\"\n @update:model-value=\"(value: unknown) => inspector.setField(field, value)\"\n />\n <UInput\n v-else\n :model-value=\"compositeFieldText(focused, field)\"\n :type=\"field.type\"\n :aria-label=\"field.label\"\n size=\"sm\"\n class=\"w-full\"\n :readonly=\"!editable\"\n @update:model-value=\"(value: unknown) => inspector.setField(field, value)\"\n />\n </UFormField>\n\n <div class=\"flex items-center gap-2 border-t border-[var(--sk-border)] pt-3\">\n <UIcon name=\"i-lucide-sparkles\" class=\"size-4 shrink-0 text-[var(--sk-muted)]\" />\n <span class=\"text-[var(--sk-muted)]\">{{ t('composites.inspector.aiStatus') }}</span>\n <span class=\"ml-auto inline-flex items-center gap-1.5\" :class=\"hasSummary ? 'text-[var(--sk-fg-highlighted)]' : 'text-[var(--sk-fg-dimmed)]'\">\n <span class=\"size-2 rounded-full\" :class=\"hasSummary ? 'bg-[var(--sk-success)]' : 'bg-[var(--sk-bg-accented)]'\" />\n {{ hasSummary ? t('composites.inspector.summaryPresent') : t('composites.inspector.summaryMissing') }}\n </span>\n </div>\n </div>\n </section>\n </aside>\n</template>\n"],"mappings":"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"}
|
|
@@ -22,7 +22,8 @@ export interface CompositeFeatureOptions {
|
|
|
22
22
|
* „Gliederung umwandeln“), `/` commands, the conversion providers (wrap into / switch kind of / unwrap composites),
|
|
23
23
|
* Markdown `:::` fences, legacy `section` migration, the preferred-structure setting and its `editing` settings tab,
|
|
24
24
|
* the chips on each title line (status, tags) and the details popover on the kind icon (the binding's `chrome` overlay), and
|
|
25
|
-
* the AI view of kinds and structure
|
|
25
|
+
* the AI view of kinds and structure, and the kinds' accepted children (`AcceptedChildren`: an edit that nests a Baustein
|
|
26
|
+
* into one that does not accept its kind is refused with a notice). Contributes the `parseMarkdown`,
|
|
26
27
|
* `structure` and `migrateContent` stages. Imports no AI, media or transcript code.
|
|
27
28
|
*/
|
|
28
29
|
export declare function compositeFeatureCore<C>(ui: CompositesUi<C>, options?: CompositeFeatureOptions): EditorFeature<C>;
|
|
@@ -9,6 +9,7 @@ import { structureBlocks } from "./heading-composites.js";
|
|
|
9
9
|
import { CompositeDescriptionNode, CompositeTitleNode, compositeKindsOf } from "./nodes.js";
|
|
10
10
|
import { compositeConversions } from "./convert.js";
|
|
11
11
|
import { migrateLegacyContent } from "./legacy.js";
|
|
12
|
+
import { AcceptedChildren } from "./accepted-children.js";
|
|
12
13
|
import { documentCompositeMarkdown, markdownFileName } from "./markdown-export.js";
|
|
13
14
|
import { compositeNodes } from "./node-views.js";
|
|
14
15
|
import { Structure, structureOf } from "./structure.js";
|
|
@@ -21,7 +22,8 @@ const STRUCTURE_STAGE_LEVEL = 2;
|
|
|
21
22
|
* „Gliederung umwandeln“), `/` commands, the conversion providers (wrap into / switch kind of / unwrap composites),
|
|
22
23
|
* Markdown `:::` fences, legacy `section` migration, the preferred-structure setting and its `editing` settings tab,
|
|
23
24
|
* the chips on each title line (status, tags) and the details popover on the kind icon (the binding's `chrome` overlay), and
|
|
24
|
-
* the AI view of kinds and structure
|
|
25
|
+
* the AI view of kinds and structure, and the kinds' accepted children (`AcceptedChildren`: an edit that nests a Baustein
|
|
26
|
+
* into one that does not accept its kind is refused with a notice). Contributes the `parseMarkdown`,
|
|
25
27
|
* `structure` and `migrateContent` stages. Imports no AI, media or transcript code.
|
|
26
28
|
*/
|
|
27
29
|
function compositeFeatureCore(ui, options = {}) {
|
|
@@ -34,7 +36,11 @@ function compositeFeatureCore(ui, options = {}) {
|
|
|
34
36
|
CompositeTitleNode,
|
|
35
37
|
CompositeDescriptionNode,
|
|
36
38
|
CompositeTags,
|
|
37
|
-
Structure.configure({ mode: () => ctx.settings.get().blocks.structure })
|
|
39
|
+
Structure.configure({ mode: () => ctx.settings.get().blocks.structure }),
|
|
40
|
+
AcceptedChildren.configure({
|
|
41
|
+
notify: ctx.notify,
|
|
42
|
+
t: ctx.t
|
|
43
|
+
})
|
|
38
44
|
],
|
|
39
45
|
toolbar: (ctx) => [{
|
|
40
46
|
id: "composites",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature.js","names":[],"sources":["../../../src/features/composites/feature.ts"],"sourcesContent":["import type { ChainedCommands, Editor } from '@tiptap/core'\nimport type { EditorFeature, FeatureContext, MenuItem, SlashCommandItem, ToolbarItem } from '../../core'\nimport { abilitiesAtSelection, downloadText, editorEntryOf, settingsTabsOf } from '../../core'\nimport type { Translate } from '../../i18n'\nimport { ABILITY } from '../../core/schema'\nimport { compositeConversions } from './convert'\nimport { blocksFromMarkdown } from './fences'\nimport { structureBlocks } from './heading-composites'\nimport { type CompositeKind, compositeKind, defaultCompositeKinds } from './kinds'\nimport { migrateLegacyContent } from './legacy'\nimport { documentCompositeMarkdown, markdownFileName } from './markdown-export'\nimport { type CompositeNodeViews, compositeNodes } from './node-views'\nimport { CompositeDescriptionNode, CompositeTitleNode, compositeKindsOf } from './nodes'\nimport { Structure, structureOf } from './structure'\nimport { STRUCTURE_MODE_KEYS } from './structure-mode'\n\n/** What a framework binding supplies to the composites feature. */\nexport interface CompositesUi<C> {\n /** The chips on each title line and the details popover on the kind icon; mounted as an overlay. */\n chrome: C\n /** The „Bearbeiten“ settings tab; receives `{ kinds }` as props. */\n settingsTab: C\n /** The composite block view of the framework. */\n nodeViews: CompositeNodeViews\n}\n\n/** Options of `compositeFeature`. */\nexport interface CompositeFeatureOptions {\n /** The composite kinds („Bausteine“) offered in the editor, with their own labels (default: `defaultCompositeKinds(t)`, the built-in kinds in the editor's language); read once. */\n kinds?: readonly CompositeKind[]\n}\n\n/** Heading level the structure stage starts at when it turns composites into headings (below the document title). */\nconst STRUCTURE_STAGE_LEVEL = 2\n\n/**\n * Composites („Bausteine“): the node family with its node views, the toolbar group (insert, „In Baustein umwandeln“,\n * „Gliederung umwandeln“), `/` commands, the conversion providers (wrap into / switch kind of / unwrap composites),\n * Markdown `:::` fences, legacy `section` migration, the preferred-structure setting and its `editing` settings tab,\n * the chips on each title line (status, tags) and the details popover on the kind icon (the binding's `chrome` overlay), and\n * the AI view of kinds and structure. Contributes the `parseMarkdown`,\n * `structure` and `migrateContent` stages. Imports no AI, media or transcript code.\n */\nexport function compositeFeatureCore<C>(ui: CompositesUi<C>, options: CompositeFeatureOptions = {}): EditorFeature<C> {\n // Host kinds keep their labels; the built-in ones are produced from the context's translator (memoized per `t`).\n const kindsOf = (ctx: { t: Translate }) => options.kinds ?? defaultCompositeKinds(ctx.t)\n const { Composite, CompositeTags } = compositeNodes(ui.nodeViews)\n return {\n id: 'composites',\n extensions: ctx => [\n Composite.configure({ kinds: kindsOf(ctx) }),\n CompositeTitleNode,\n CompositeDescriptionNode,\n CompositeTags,\n Structure.configure({ mode: () => ctx.settings.get().blocks.structure }),\n ],\n toolbar: ctx => [{\n id: 'composites',\n order: 60,\n items: compositeToolbarItems(ctx, kindsOf(ctx)),\n }],\n slashCommands: ctx => compositeSlashCommands(ctx, kindsOf(ctx)),\n blockActions: ctx => [{\n id: 'document-export',\n label: ctx.t('composites.blockAction.export'),\n icon: 'i-lucide-download',\n ability: ABILITY.compositeExport,\n order: 400,\n isVisible: ({ node }) => node.attrs.kind === 'document',\n run: ({ editor, node }) => downloadText(markdownFileName(node), documentCompositeMarkdown(editor, node)),\n }],\n overlays: [ui.chrome],\n settingsTabs: ctx => [{ id: 'editing', label: ctx.t('composites.tab'), icon: 'i-lucide-pencil', component: ui.settingsTab, props: { kinds: kindsOf(ctx) } }],\n blocks: {\n parseMarkdown: (editor, markdown) => blocksFromMarkdown(md => editor.markdown!.parse(md), markdown, compositeKindsOf(editor)),\n structure: (editor, blocks) => {\n const { schema } = editor\n return structureBlocks(schema, blocks.map(block => schema.nodeFromJSON(block)), structureOf(editor), STRUCTURE_STAGE_LEVEL, compositeKindsOf(editor)).map(node => node.toJSON())\n },\n migrateContent: migrateLegacyContent,\n },\n conversions: compositeConversions(options.kinds),\n aiContext: editor => ({\n kinds: compositeKindsOf(editor).map(({ id, label, fields, ai }) => ({ id, label, fields, ...(ai?.purpose && { purpose: ai.purpose }) })),\n structure: structureOf(editor),\n }),\n }\n}\n\nfunction compositeSlashCommands({ settings, t }: FeatureContext, kinds: readonly CompositeKind[]): SlashCommandItem[] {\n const insert = (kind: string) => (editor: Editor) => editor.commands.insertComposite(kind)\n const group = (recursive: boolean) => (editor: Editor) => {\n const { editing, blocks } = settings.get()\n return editor.commands.convertHeadingsToComposites({ recursive, scope: editing.headingConversionScope, kind: blocks.defaultKind })\n }\n const flatten = (recursive: boolean) => (editor: Editor) => editor.commands.convertCompositesToHeadings({ recursive, scope: settings.get().editing.headingConversionScope })\n return [\n { id: 'abschnitt', label: t('composites.slash.section'), icon: 'i-lucide-layers', ability: ABILITY.composite, run: insert('section') },\n ...kinds.filter(kind => kind.id !== 'section').map((kind): SlashCommandItem => (\n { id: kind.id, label: kind.label, icon: kind.icon, ability: ABILITY.composite, run: insert(kind.id) }\n )),\n { id: 'gliedern', label: t('composites.slash.group'), icon: 'i-lucide-layers', ability: ABILITY.composite, run: group(false) },\n { id: 'gliedern-alle', label: t('composites.slash.groupAll'), icon: 'i-lucide-list-tree', ability: ABILITY.composite, run: group(true) },\n { id: 'aufloesen', label: t('composites.slash.flatten'), icon: 'i-lucide-heading', ability: ABILITY.headings, run: flatten(false) },\n { id: 'aufloesen-alle', label: t('composites.slash.flattenAll'), icon: 'i-lucide-align-left', ability: ABILITY.headings, run: flatten(true) },\n ]\n}\n\n/**\n * The toolbar group beside the inserts: the default kind's insert button (it follows the setting, so label/icon/shortcut\n * are getters read at render time), „In Baustein umwandeln“ (one entry per kind for the caret's block) and „Gliederung\n * umwandeln“ (headings <-> composites in both directions, the preferred structure's direction first).\n */\nfunction compositeToolbarItems<C>({ settings, t }: FeatureContext, kinds: readonly CompositeKind[]): ToolbarItem<C>[] {\n const defaultKind = () => compositeKind(kinds, settings.get().blocks.defaultKind)\n const insert = (chain: ChainedCommands) => chain.insertComposite(defaultKind().id)\n const scope = () => settings.get().editing.headingConversionScope\n\n const canGroup = (editor: Editor, recursive: boolean) => editor.can().convertHeadingsToComposites({ recursive, scope: scope(), kind: settings.get().blocks.defaultKind })\n const canFlatten = (editor: Editor, recursive: boolean) => editor.can().convertCompositesToHeadings({ recursive, scope: scope() })\n\n function kindItems(editor: Editor): MenuItem[] {\n return [\n { type: 'label', label: t('composites.menu.kindHeading') },\n ...compositeKindsOf(editor).map((kind): MenuItem => {\n const target = { type: 'composite', kind: kind.id } as const\n return { label: kind.label, icon: kind.icon, disabled: !editor.can().convertBlockTo(target), onSelect: () => editor.chain().focus().convertBlockTo(target).run() }\n }),\n ]\n }\n\n function structureItems(editor: Editor): MenuItem[] {\n const structure = settings.get().blocks.structure\n const abilities = abilitiesAtSelection(editor)\n const composite = abilities.has(ABILITY.composite)\n const headings = abilities.has(ABILITY.headings)\n const run = (command: () => boolean) => () => void command()\n const sep: MenuItem = { type: 'separator' }\n const toComposites: MenuItem[] = [\n { type: 'label', label: t('composites.menu.toComposites') },\n { label: t('composites.menu.toComposites.top'), description: t('composites.menu.toComposites.top.description'), icon: 'i-lucide-layers', disabled: !composite || !canGroup(editor, false), onSelect: run(() => editor.chain().focus().convertHeadingsToComposites({ recursive: false, scope: scope(), kind: settings.get().blocks.defaultKind }).run()) },\n { label: t('composites.menu.toComposites.all'), description: t('composites.menu.toComposites.all.description'), icon: 'i-lucide-list-tree', disabled: !composite || !canGroup(editor, true), onSelect: run(() => editor.chain().focus().convertHeadingsToComposites({ recursive: true, scope: scope(), kind: settings.get().blocks.defaultKind }).run()) },\n ]\n const toHeadings: MenuItem[] = [\n { type: 'label', label: t('composites.menu.toHeadings') },\n { label: t('composites.menu.toHeadings.top'), description: t('composites.menu.toHeadings.top.description'), icon: 'i-lucide-heading', disabled: !headings || !canFlatten(editor, false), onSelect: run(() => editor.chain().focus().convertCompositesToHeadings({ recursive: false, scope: scope() }).run()) },\n { label: t('composites.menu.toHeadings.all'), description: t('composites.menu.toHeadings.all.description'), icon: 'i-lucide-align-left', disabled: !headings || !canFlatten(editor, true), onSelect: run(() => editor.chain().focus().convertCompositesToHeadings({ recursive: true, scope: scope() }).run()) },\n ]\n const entry = editorEntryOf(editor)\n // The settings entry exists only while some feature contributes a tab to open.\n const settingsEntry: MenuItem[] = entry && settingsTabsOf(entry.preset, entry.ctx.app).length\n ? [sep, { label: t('composites.menu.settings'), icon: 'i-lucide-settings-2', onSelect: () => entry.ui.openSettings('editing') }]\n : []\n return [\n { type: 'label', label: t('composites.menu.preferred', { mode: t(STRUCTURE_MODE_KEYS[structure].labelKey) }) },\n ...(structure === 'composite' ? [...toComposites, sep, ...toHeadings] : [...toHeadings, sep, ...toComposites]),\n ...settingsEntry,\n ]\n }\n\n return [\n {\n id: 'insert',\n order: 10,\n // Getters: the default kind arrives with the server settings; the toolbar reads them at render time.\n get icon() { return defaultKind().icon },\n get label() { return defaultKind().label },\n // Mod-Shift-a (CompositeNode) always inserts a `section`, so only then is it shown as the shortcut.\n get kbds() { return defaultKind().id === 'section' ? ['meta', 'shift', 'a'] : undefined },\n ability: ABILITY.composite,\n disabled: editor => !insert(editor.can().chain()).run(),\n run: (editor) => { insert(editor.chain().focus()).run() },\n },\n {\n id: 'to-kind',\n order: 20,\n icon: 'i-lucide-replace',\n label: t('composites.toolbar.toKind'),\n ability: ABILITY.composite,\n disabled: editor => kindItems(editor).every(item => item.type === 'label' || item.disabled),\n menu: kindItems,\n },\n {\n id: 'structure',\n order: 30,\n icon: 'i-lucide-list-tree',\n label: t('composites.toolbar.structure'),\n disabled: editor => !canGroup(editor, true) && !canFlatten(editor, true),\n menu: structureItems,\n },\n ]\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"feature.js","names":[],"sources":["../../../src/features/composites/feature.ts"],"sourcesContent":["import type { ChainedCommands, Editor } from '@tiptap/core'\nimport type { EditorFeature, FeatureContext, MenuItem, SlashCommandItem, ToolbarItem } from '../../core'\nimport { abilitiesAtSelection, downloadText, editorEntryOf, settingsTabsOf } from '../../core'\nimport type { Translate } from '../../i18n'\nimport { ABILITY } from '../../core/schema'\nimport { AcceptedChildren } from './accepted-children'\nimport { compositeConversions } from './convert'\nimport { blocksFromMarkdown } from './fences'\nimport { structureBlocks } from './heading-composites'\nimport { type CompositeKind, compositeKind, defaultCompositeKinds } from './kinds'\nimport { migrateLegacyContent } from './legacy'\nimport { documentCompositeMarkdown, markdownFileName } from './markdown-export'\nimport { type CompositeNodeViews, compositeNodes } from './node-views'\nimport { CompositeDescriptionNode, CompositeTitleNode, compositeKindsOf } from './nodes'\nimport { Structure, structureOf } from './structure'\nimport { STRUCTURE_MODE_KEYS } from './structure-mode'\n\n/** What a framework binding supplies to the composites feature. */\nexport interface CompositesUi<C> {\n /** The chips on each title line and the details popover on the kind icon; mounted as an overlay. */\n chrome: C\n /** The „Bearbeiten“ settings tab; receives `{ kinds }` as props. */\n settingsTab: C\n /** The composite block view of the framework. */\n nodeViews: CompositeNodeViews\n}\n\n/** Options of `compositeFeature`. */\nexport interface CompositeFeatureOptions {\n /** The composite kinds („Bausteine“) offered in the editor, with their own labels (default: `defaultCompositeKinds(t)`, the built-in kinds in the editor's language); read once. */\n kinds?: readonly CompositeKind[]\n}\n\n/** Heading level the structure stage starts at when it turns composites into headings (below the document title). */\nconst STRUCTURE_STAGE_LEVEL = 2\n\n/**\n * Composites („Bausteine“): the node family with its node views, the toolbar group (insert, „In Baustein umwandeln“,\n * „Gliederung umwandeln“), `/` commands, the conversion providers (wrap into / switch kind of / unwrap composites),\n * Markdown `:::` fences, legacy `section` migration, the preferred-structure setting and its `editing` settings tab,\n * the chips on each title line (status, tags) and the details popover on the kind icon (the binding's `chrome` overlay), and\n * the AI view of kinds and structure, and the kinds' accepted children (`AcceptedChildren`: an edit that nests a Baustein\n * into one that does not accept its kind is refused with a notice). Contributes the `parseMarkdown`,\n * `structure` and `migrateContent` stages. Imports no AI, media or transcript code.\n */\nexport function compositeFeatureCore<C>(ui: CompositesUi<C>, options: CompositeFeatureOptions = {}): EditorFeature<C> {\n // Host kinds keep their labels; the built-in ones are produced from the context's translator (memoized per `t`).\n const kindsOf = (ctx: { t: Translate }) => options.kinds ?? defaultCompositeKinds(ctx.t)\n const { Composite, CompositeTags } = compositeNodes(ui.nodeViews)\n return {\n id: 'composites',\n extensions: ctx => [\n Composite.configure({ kinds: kindsOf(ctx) }),\n CompositeTitleNode,\n CompositeDescriptionNode,\n CompositeTags,\n Structure.configure({ mode: () => ctx.settings.get().blocks.structure }),\n AcceptedChildren.configure({ notify: ctx.notify, t: ctx.t }),\n ],\n toolbar: ctx => [{\n id: 'composites',\n order: 60,\n items: compositeToolbarItems(ctx, kindsOf(ctx)),\n }],\n slashCommands: ctx => compositeSlashCommands(ctx, kindsOf(ctx)),\n blockActions: ctx => [{\n id: 'document-export',\n label: ctx.t('composites.blockAction.export'),\n icon: 'i-lucide-download',\n ability: ABILITY.compositeExport,\n order: 400,\n isVisible: ({ node }) => node.attrs.kind === 'document',\n run: ({ editor, node }) => downloadText(markdownFileName(node), documentCompositeMarkdown(editor, node)),\n }],\n overlays: [ui.chrome],\n settingsTabs: ctx => [{ id: 'editing', label: ctx.t('composites.tab'), icon: 'i-lucide-pencil', component: ui.settingsTab, props: { kinds: kindsOf(ctx) } }],\n blocks: {\n parseMarkdown: (editor, markdown) => blocksFromMarkdown(md => editor.markdown!.parse(md), markdown, compositeKindsOf(editor)),\n structure: (editor, blocks) => {\n const { schema } = editor\n return structureBlocks(schema, blocks.map(block => schema.nodeFromJSON(block)), structureOf(editor), STRUCTURE_STAGE_LEVEL, compositeKindsOf(editor)).map(node => node.toJSON())\n },\n migrateContent: migrateLegacyContent,\n },\n conversions: compositeConversions(options.kinds),\n aiContext: editor => ({\n kinds: compositeKindsOf(editor).map(({ id, label, fields, ai }) => ({ id, label, fields, ...(ai?.purpose && { purpose: ai.purpose }) })),\n structure: structureOf(editor),\n }),\n }\n}\n\nfunction compositeSlashCommands({ settings, t }: FeatureContext, kinds: readonly CompositeKind[]): SlashCommandItem[] {\n const insert = (kind: string) => (editor: Editor) => editor.commands.insertComposite(kind)\n const group = (recursive: boolean) => (editor: Editor) => {\n const { editing, blocks } = settings.get()\n return editor.commands.convertHeadingsToComposites({ recursive, scope: editing.headingConversionScope, kind: blocks.defaultKind })\n }\n const flatten = (recursive: boolean) => (editor: Editor) => editor.commands.convertCompositesToHeadings({ recursive, scope: settings.get().editing.headingConversionScope })\n return [\n { id: 'abschnitt', label: t('composites.slash.section'), icon: 'i-lucide-layers', ability: ABILITY.composite, run: insert('section') },\n ...kinds.filter(kind => kind.id !== 'section').map((kind): SlashCommandItem => (\n { id: kind.id, label: kind.label, icon: kind.icon, ability: ABILITY.composite, run: insert(kind.id) }\n )),\n { id: 'gliedern', label: t('composites.slash.group'), icon: 'i-lucide-layers', ability: ABILITY.composite, run: group(false) },\n { id: 'gliedern-alle', label: t('composites.slash.groupAll'), icon: 'i-lucide-list-tree', ability: ABILITY.composite, run: group(true) },\n { id: 'aufloesen', label: t('composites.slash.flatten'), icon: 'i-lucide-heading', ability: ABILITY.headings, run: flatten(false) },\n { id: 'aufloesen-alle', label: t('composites.slash.flattenAll'), icon: 'i-lucide-align-left', ability: ABILITY.headings, run: flatten(true) },\n ]\n}\n\n/**\n * The toolbar group beside the inserts: the default kind's insert button (it follows the setting, so label/icon/shortcut\n * are getters read at render time), „In Baustein umwandeln“ (one entry per kind for the caret's block) and „Gliederung\n * umwandeln“ (headings <-> composites in both directions, the preferred structure's direction first).\n */\nfunction compositeToolbarItems<C>({ settings, t }: FeatureContext, kinds: readonly CompositeKind[]): ToolbarItem<C>[] {\n const defaultKind = () => compositeKind(kinds, settings.get().blocks.defaultKind)\n const insert = (chain: ChainedCommands) => chain.insertComposite(defaultKind().id)\n const scope = () => settings.get().editing.headingConversionScope\n\n const canGroup = (editor: Editor, recursive: boolean) => editor.can().convertHeadingsToComposites({ recursive, scope: scope(), kind: settings.get().blocks.defaultKind })\n const canFlatten = (editor: Editor, recursive: boolean) => editor.can().convertCompositesToHeadings({ recursive, scope: scope() })\n\n function kindItems(editor: Editor): MenuItem[] {\n return [\n { type: 'label', label: t('composites.menu.kindHeading') },\n ...compositeKindsOf(editor).map((kind): MenuItem => {\n const target = { type: 'composite', kind: kind.id } as const\n return { label: kind.label, icon: kind.icon, disabled: !editor.can().convertBlockTo(target), onSelect: () => editor.chain().focus().convertBlockTo(target).run() }\n }),\n ]\n }\n\n function structureItems(editor: Editor): MenuItem[] {\n const structure = settings.get().blocks.structure\n const abilities = abilitiesAtSelection(editor)\n const composite = abilities.has(ABILITY.composite)\n const headings = abilities.has(ABILITY.headings)\n const run = (command: () => boolean) => () => void command()\n const sep: MenuItem = { type: 'separator' }\n const toComposites: MenuItem[] = [\n { type: 'label', label: t('composites.menu.toComposites') },\n { label: t('composites.menu.toComposites.top'), description: t('composites.menu.toComposites.top.description'), icon: 'i-lucide-layers', disabled: !composite || !canGroup(editor, false), onSelect: run(() => editor.chain().focus().convertHeadingsToComposites({ recursive: false, scope: scope(), kind: settings.get().blocks.defaultKind }).run()) },\n { label: t('composites.menu.toComposites.all'), description: t('composites.menu.toComposites.all.description'), icon: 'i-lucide-list-tree', disabled: !composite || !canGroup(editor, true), onSelect: run(() => editor.chain().focus().convertHeadingsToComposites({ recursive: true, scope: scope(), kind: settings.get().blocks.defaultKind }).run()) },\n ]\n const toHeadings: MenuItem[] = [\n { type: 'label', label: t('composites.menu.toHeadings') },\n { label: t('composites.menu.toHeadings.top'), description: t('composites.menu.toHeadings.top.description'), icon: 'i-lucide-heading', disabled: !headings || !canFlatten(editor, false), onSelect: run(() => editor.chain().focus().convertCompositesToHeadings({ recursive: false, scope: scope() }).run()) },\n { label: t('composites.menu.toHeadings.all'), description: t('composites.menu.toHeadings.all.description'), icon: 'i-lucide-align-left', disabled: !headings || !canFlatten(editor, true), onSelect: run(() => editor.chain().focus().convertCompositesToHeadings({ recursive: true, scope: scope() }).run()) },\n ]\n const entry = editorEntryOf(editor)\n // The settings entry exists only while some feature contributes a tab to open.\n const settingsEntry: MenuItem[] = entry && settingsTabsOf(entry.preset, entry.ctx.app).length\n ? [sep, { label: t('composites.menu.settings'), icon: 'i-lucide-settings-2', onSelect: () => entry.ui.openSettings('editing') }]\n : []\n return [\n { type: 'label', label: t('composites.menu.preferred', { mode: t(STRUCTURE_MODE_KEYS[structure].labelKey) }) },\n ...(structure === 'composite' ? [...toComposites, sep, ...toHeadings] : [...toHeadings, sep, ...toComposites]),\n ...settingsEntry,\n ]\n }\n\n return [\n {\n id: 'insert',\n order: 10,\n // Getters: the default kind arrives with the server settings; the toolbar reads them at render time.\n get icon() { return defaultKind().icon },\n get label() { return defaultKind().label },\n // Mod-Shift-a (CompositeNode) always inserts a `section`, so only then is it shown as the shortcut.\n get kbds() { return defaultKind().id === 'section' ? ['meta', 'shift', 'a'] : undefined },\n ability: ABILITY.composite,\n disabled: editor => !insert(editor.can().chain()).run(),\n run: (editor) => { insert(editor.chain().focus()).run() },\n },\n {\n id: 'to-kind',\n order: 20,\n icon: 'i-lucide-replace',\n label: t('composites.toolbar.toKind'),\n ability: ABILITY.composite,\n disabled: editor => kindItems(editor).every(item => item.type === 'label' || item.disabled),\n menu: kindItems,\n },\n {\n id: 'structure',\n order: 30,\n icon: 'i-lucide-list-tree',\n label: t('composites.toolbar.structure'),\n disabled: editor => !canGroup(editor, true) && !canFlatten(editor, true),\n menu: structureItems,\n },\n ]\n}\n"],"mappings":"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"}
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { CompositeAiBrief, compositeAiBrief } from "./ai-brief.js";
|
|
2
|
-
import { CompositeKind, CompositeKindAi, CompositeMetaField, compositeKind, defaultCompositeKinds } from "./kinds.js";
|
|
2
|
+
import { CompositeKind, CompositeKindAi, CompositeMetaField, compositeKind, defaultCompositeKinds, kindAccepts } from "./kinds.js";
|
|
3
3
|
import { CompositeMention, CompositeRow, compositeDescriptionText, compositeMetaWith, compositeOfRow, compositeRowAt, compositeRows, setCompositeDescription, setCompositeMetaField, setCompositeTags } from "./rows.js";
|
|
4
4
|
import { CompositeAnchor, CompositeAnchorsHandle, CompositeFrame, compositeSectionOf, observeCompositeAnchors } from "./anchors.js";
|
|
5
5
|
import { COMPOSITE_CHROME_COUNT, CompositeDescriptionNode, CompositeNode, CompositeOptions, CompositeStorage, CompositeTagsNode, CompositeTitleNode, compositeJSON, compositeKindsOf } from "./nodes.js";
|
|
6
6
|
import { CompositeNodeViews, compositeNodes } from "./node-views.js";
|
|
7
7
|
import { CompositeFeatureOptions, CompositesUi, compositeFeatureCore } from "./feature.js";
|
|
8
8
|
import { documentCompositeMarkdown, headingsMarkdown, markdownFileName } from "./markdown-export.js";
|
|
9
|
-
import { OutlineNode, canMoveBlockInto, compositeOutline, moveBlockInto } from "./outline.js";
|
|
9
|
+
import { MoveVerdict, OutlineNode, canMoveBlockInto, compositeOutline, moveBlockInto, moveIntoVerdict } from "./outline.js";
|
|
10
|
+
import { AcceptedChildren, AcceptedChildrenOptions } from "./accepted-children.js";
|
|
10
11
|
import { CompositeKindCount, CompositeRowsHandle, CompositeRowsState, createCompositeRows } from "./rows-model.js";
|
|
12
|
+
import { CompositeInspector, CompositeInspectorSection, CompositeInspectorState, CompositeKindOption, compositeFieldText, createCompositeInspector } from "./inspector-model.js";
|
|
11
13
|
import { Structure, StructureStorage, structureOf } from "./structure.js";
|
|
12
14
|
import { STRUCTURE_MODE_KEYS } from "./structure-mode.js";
|
|
13
15
|
import { TREE_ROOT_KEYS } from "./tree-root.js";
|
|
@@ -17,4 +19,4 @@ import { blocksFromMarkdown, compositeFence, compositeFromMarkdown } from "./fen
|
|
|
17
19
|
import { compositeChromeBlocks, flattenCompositesToHeadings, groupHeadingsIntoComposites, headingGroupRange, structureBlocks } from "./heading-composites.js";
|
|
18
20
|
import { LEGACY_COMPOSITE_NODE, migrateLegacyContent } from "./legacy.js";
|
|
19
21
|
import { compositeSchemaExtensions } from "./schema.js";
|
|
20
|
-
export { COMPOSITE_CHROME_COUNT, type CompositeAiBrief, type CompositeAnchor, type CompositeAnchorsHandle, CompositeDescriptionNode, type CompositeFeatureOptions, type CompositeFence, type CompositeFrame, type CompositeKind, type CompositeKindAi, type CompositeKindCount, type CompositeMention, type CompositeMetaField, CompositeNode, type CompositeNodeViews, type CompositeOptions, type CompositeRow, type CompositeRowsHandle, type CompositeRowsState, type CompositeStorage, CompositeTagsNode, CompositeTitleNode, type CompositesUi, type FenceSegment, LEGACY_COMPOSITE_NODE, type OutlineNode, STRUCTURE_MODE_KEYS, Structure, type StructureStorage, TREE_ROOT_KEYS, blocksFromMarkdown, canMoveBlockInto, compositeAiBrief, compositeChromeBlocks, compositeConversions, compositeDescriptionText, compositeFeatureCore, compositeFence, compositeFromMarkdown, compositeJSON, compositeKind, compositeKindsOf, compositeMetaWith, compositeNodes, compositeOfRow, compositeOutline, compositeRowAt, compositeRows, compositeSchemaExtensions, compositeSectionOf, convertCompositeBlocks, createCompositeRows, defaultCompositeKinds, documentCompositeMarkdown, flattenCompositesToHeadings, groupHeadingsIntoComposites, headingGroupRange, headingsMarkdown, markdownFileName, migrateLegacyContent, moveBlockInto, observeCompositeAnchors, setCompositeDescription, setCompositeMetaField, setCompositeTags, splitCompositeFences, structureBlocks as structureCompositeBlocks, structureOf };
|
|
22
|
+
export { AcceptedChildren, type AcceptedChildrenOptions, COMPOSITE_CHROME_COUNT, type CompositeAiBrief, type CompositeAnchor, type CompositeAnchorsHandle, CompositeDescriptionNode, type CompositeFeatureOptions, type CompositeFence, type CompositeFrame, type CompositeInspector, type CompositeInspectorSection, type CompositeInspectorState, type CompositeKind, type CompositeKindAi, type CompositeKindCount, type CompositeKindOption, type CompositeMention, type CompositeMetaField, CompositeNode, type CompositeNodeViews, type CompositeOptions, type CompositeRow, type CompositeRowsHandle, type CompositeRowsState, type CompositeStorage, CompositeTagsNode, CompositeTitleNode, type CompositesUi, type FenceSegment, LEGACY_COMPOSITE_NODE, type MoveVerdict, type OutlineNode, STRUCTURE_MODE_KEYS, Structure, type StructureStorage, TREE_ROOT_KEYS, blocksFromMarkdown, canMoveBlockInto, compositeAiBrief, compositeChromeBlocks, compositeConversions, compositeDescriptionText, compositeFeatureCore, compositeFence, compositeFieldText, compositeFromMarkdown, compositeJSON, compositeKind, compositeKindsOf, compositeMetaWith, compositeNodes, compositeOfRow, compositeOutline, compositeRowAt, compositeRows, compositeSchemaExtensions, compositeSectionOf, convertCompositeBlocks, createCompositeInspector, createCompositeRows, defaultCompositeKinds, documentCompositeMarkdown, flattenCompositesToHeadings, groupHeadingsIntoComposites, headingGroupRange, headingsMarkdown, kindAccepts, markdownFileName, migrateLegacyContent, moveBlockInto, moveIntoVerdict, observeCompositeAnchors, setCompositeDescription, setCompositeMetaField, setCompositeTags, splitCompositeFences, structureBlocks as structureCompositeBlocks, structureOf };
|