@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.
Files changed (278) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +4 -3
  3. package/dist/adapters/anchors.d.ts +80 -0
  4. package/dist/adapters/anchors.js +270 -0
  5. package/dist/adapters/anchors.js.map +1 -0
  6. package/dist/adapters/comments/client.d.ts +64 -0
  7. package/dist/adapters/comments/client.js +536 -0
  8. package/dist/adapters/comments/client.js.map +1 -0
  9. package/dist/adapters/comments/drizzle.d.ts +430 -0
  10. package/dist/adapters/comments/drizzle.js +236 -0
  11. package/dist/adapters/comments/drizzle.js.map +1 -0
  12. package/dist/adapters/comments/errors.d.ts +9 -0
  13. package/dist/adapters/comments/errors.js +19 -0
  14. package/dist/adapters/comments/errors.js.map +1 -0
  15. package/dist/adapters/comments/json.d.ts +19 -0
  16. package/dist/adapters/comments/json.js +94 -0
  17. package/dist/adapters/comments/json.js.map +1 -0
  18. package/dist/adapters/comments/record.js +78 -0
  19. package/dist/adapters/comments/record.js.map +1 -0
  20. package/dist/adapters/comments/server.d.ts +23 -0
  21. package/dist/adapters/comments/server.js +102 -0
  22. package/dist/adapters/comments/server.js.map +1 -0
  23. package/dist/adapters/comments/types.d.ts +109 -0
  24. package/dist/adapters/documents.js +108 -0
  25. package/dist/adapters/documents.js.map +1 -0
  26. package/dist/adapters/drizzle.d.ts +293 -0
  27. package/dist/adapters/drizzle.js +157 -0
  28. package/dist/adapters/drizzle.js.map +1 -0
  29. package/dist/adapters/files.js +30 -0
  30. package/dist/adapters/files.js.map +1 -0
  31. package/dist/adapters/forge.d.ts +58 -0
  32. package/dist/adapters/forge.js +91 -0
  33. package/dist/adapters/forge.js.map +1 -0
  34. package/dist/adapters/index.d.ts +13 -0
  35. package/dist/adapters/index.js +0 -0
  36. package/dist/adapters/json.d.ts +24 -0
  37. package/dist/adapters/json.js +128 -0
  38. package/dist/adapters/json.js.map +1 -0
  39. package/dist/adapters/nitro.d.ts +61 -0
  40. package/dist/adapters/nitro.js +212 -0
  41. package/dist/adapters/nitro.js.map +1 -0
  42. package/dist/adapters/routes.js +16 -0
  43. package/dist/adapters/routes.js.map +1 -0
  44. package/dist/adapters/shared.d.ts +37 -0
  45. package/dist/adapters/shared.js +32 -0
  46. package/dist/adapters/shared.js.map +1 -0
  47. package/dist/adapters/vue.d.ts +67 -0
  48. package/dist/adapters/vue.js +187 -0
  49. package/dist/adapters/vue.js.map +1 -0
  50. package/dist/code/CodeSurface.vue.d.ts +3 -3
  51. package/dist/core/doc-anchors.d.ts +5 -0
  52. package/dist/core/doc-anchors.js +4 -3
  53. package/dist/core/doc-anchors.js.map +1 -1
  54. package/dist/core/editor-ui.js +57 -1
  55. package/dist/core/editor-ui.js.map +1 -1
  56. package/dist/core/surface-session.js +139 -0
  57. package/dist/core/surface-session.js.map +1 -0
  58. package/dist/document/DocumentSurface.d.ts +1 -1
  59. package/dist/document/DocumentSurface.vue.d.ts +3 -3
  60. package/dist/features/ai/agent-op-review.d.ts +2 -2
  61. package/dist/features/ai/agent-op-review.js.map +1 -1
  62. package/dist/features/ai/agent-ops.d.ts +1 -1
  63. package/dist/features/ai/agent-ops.js +9 -6
  64. package/dist/features/ai/agent-ops.js.map +1 -1
  65. package/dist/features/ai/ai-apply.d.ts +1 -1
  66. package/dist/features/ai/ai-review.js +10 -1
  67. package/dist/features/ai/ai-review.js.map +1 -1
  68. package/dist/features/ai/components/AiSelectionMenu.js +78 -252
  69. package/dist/features/ai/components/AiSelectionMenu.js.map +1 -1
  70. package/dist/features/ai/components/AiSelectionMenu.vue.d.ts +2 -1
  71. package/dist/features/ai/components/AiSidebar.js +2 -2
  72. package/dist/features/ai/components/DocumentChatAnswer.js +1 -1
  73. package/dist/features/ai/components/DocumentChatOps.js +1 -0
  74. package/dist/features/ai/components/DocumentChatOps.js.map +1 -1
  75. package/dist/features/ai/components/ModelQuickSwitch.js +1 -1
  76. package/dist/features/ai/components/SettingsAiTab.js +1 -1
  77. package/dist/features/ai/components/SettingsModelProfiles.js +1 -1
  78. package/dist/features/ai/document-chat.d.ts +3 -2
  79. package/dist/features/ai/document-chat.js +16 -19
  80. package/dist/features/ai/document-chat.js.map +1 -1
  81. package/dist/features/ai/index.d.ts +5 -3
  82. package/dist/features/ai/index.js +4 -2
  83. package/dist/features/ai/protocol/agent-ops.d.ts +22 -17
  84. package/dist/features/ai/protocol/agent-ops.js +65 -39
  85. package/dist/features/ai/protocol/agent-ops.js.map +1 -1
  86. package/dist/features/ai/protocol/block-lines.d.ts +89 -0
  87. package/dist/features/ai/protocol/block-lines.js +177 -0
  88. package/dist/features/ai/protocol/block-lines.js.map +1 -0
  89. package/dist/features/ai/protocol/chat.js +10 -10
  90. package/dist/features/ai/protocol/chat.js.map +1 -1
  91. package/dist/features/ai/protocol/index.d.ts +3 -2
  92. package/dist/features/ai/protocol/index.js +3 -2
  93. package/dist/features/ai/react/AiSelectionMenu.d.ts +3 -2
  94. package/dist/features/ai/react/AiSelectionMenu.js +64 -255
  95. package/dist/features/ai/react/AiSelectionMenu.js.map +1 -1
  96. package/dist/features/ai/react/AiSidebar.js +2 -2
  97. package/dist/features/ai/react/DocumentChatAnswer.js +1 -1
  98. package/dist/features/ai/react/DocumentChatOps.js +1 -0
  99. package/dist/features/ai/react/DocumentChatOps.js.map +1 -1
  100. package/dist/features/ai/react/ModelQuickSwitch.js +1 -1
  101. package/dist/features/ai/react/SettingsAiTab.js +1 -1
  102. package/dist/features/ai/react/SettingsModelProfiles.js +1 -1
  103. package/dist/features/ai/react/use-ai-selection-flow.js +34 -0
  104. package/dist/features/ai/react/use-ai-selection-flow.js.map +1 -0
  105. package/dist/features/ai/selection-flow.d.ts +133 -0
  106. package/dist/features/ai/selection-flow.js +283 -0
  107. package/dist/features/ai/selection-flow.js.map +1 -0
  108. package/dist/features/ai/use-ai-assistant.d.ts +1 -1
  109. package/dist/features/ai/use-document-chat.d.ts +1 -1
  110. package/dist/features/authors/components/AuthorColorsPanel.js +1 -1
  111. package/dist/features/authors/feature.js +1 -1
  112. package/dist/features/authors/index.js +1 -1
  113. package/dist/features/authors/react/AuthorColorsPanel.js +1 -1
  114. package/dist/features/comments/components/CommentBubble.js +1 -1
  115. package/dist/features/comments/components/CommentComposer.js +1 -1
  116. package/dist/features/comments/components/CommentThreadView.js +5 -2
  117. package/dist/features/comments/components/CommentThreadView.js.map +1 -1
  118. package/dist/features/comments/components/CommentsMargin.js +108 -230
  119. package/dist/features/comments/components/CommentsMargin.js.map +1 -1
  120. package/dist/features/comments/components/CommentsOverlay.js +1 -1
  121. package/dist/features/comments/feature.js +1 -1
  122. package/dist/features/comments/index.d.ts +4 -2
  123. package/dist/features/comments/index.js +4 -2
  124. package/dist/features/comments/margin-controller.d.ts +44 -0
  125. package/dist/features/comments/margin-controller.js +132 -0
  126. package/dist/features/comments/margin-controller.js.map +1 -0
  127. package/dist/features/comments/margin-layout.d.ts +55 -0
  128. package/dist/features/comments/margin-layout.js +79 -0
  129. package/dist/features/comments/margin-layout.js.map +1 -0
  130. package/dist/features/comments/model.d.ts +8 -0
  131. package/dist/features/comments/model.js +60 -34
  132. package/dist/features/comments/model.js.map +1 -1
  133. package/dist/features/comments/react/CommentBubble.js +1 -1
  134. package/dist/features/comments/react/CommentComposer.js +1 -1
  135. package/dist/features/comments/react/CommentThreadView.js +2 -2
  136. package/dist/features/comments/react/CommentThreadView.js.map +1 -1
  137. package/dist/features/comments/react/CommentsMargin.d.ts +0 -5
  138. package/dist/features/comments/react/CommentsMargin.js +85 -251
  139. package/dist/features/comments/react/CommentsMargin.js.map +1 -1
  140. package/dist/features/comments/react/CommentsOverlay.js +1 -1
  141. package/dist/features/comments/react/use-comments.js +1 -1
  142. package/dist/features/comments/react/use-margin-layout.js +45 -0
  143. package/dist/features/comments/react/use-margin-layout.js.map +1 -0
  144. package/dist/features/comments/react.d.ts +1 -1
  145. package/dist/features/comments/schema.d.ts +23 -0
  146. package/dist/features/comments/schema.js.map +1 -1
  147. package/dist/features/comments/snapshot-equality.js +40 -0
  148. package/dist/features/comments/snapshot-equality.js.map +1 -0
  149. package/dist/features/comments/thread-anchor.js +33 -0
  150. package/dist/features/comments/thread-anchor.js.map +1 -0
  151. package/dist/features/comments/use-comments.d.ts +3 -1
  152. package/dist/features/comments/use-comments.js +1 -0
  153. package/dist/features/comments/use-comments.js.map +1 -1
  154. package/dist/features/comments/use-margin-layout.js +29 -0
  155. package/dist/features/comments/use-margin-layout.js.map +1 -0
  156. package/dist/features/comments/vue.d.ts +1 -1
  157. package/dist/features/composites/accepted-children.d.ts +21 -0
  158. package/dist/features/composites/accepted-children.js +126 -0
  159. package/dist/features/composites/accepted-children.js.map +1 -0
  160. package/dist/features/composites/components/CompositeDetails.js +1 -1
  161. package/dist/features/composites/components/CompositeInspector.js +38 -164
  162. package/dist/features/composites/components/CompositeInspector.js.map +1 -1
  163. package/dist/features/composites/feature.d.ts +2 -1
  164. package/dist/features/composites/feature.js +8 -2
  165. package/dist/features/composites/feature.js.map +1 -1
  166. package/dist/features/composites/index.d.ts +5 -3
  167. package/dist/features/composites/index.js +8 -6
  168. package/dist/features/composites/inspector-model.d.ts +97 -0
  169. package/dist/features/composites/inspector-model.js +255 -0
  170. package/dist/features/composites/inspector-model.js.map +1 -0
  171. package/dist/features/composites/kinds.d.ts +11 -0
  172. package/dist/features/composites/kinds.js +17 -2
  173. package/dist/features/composites/kinds.js.map +1 -1
  174. package/dist/features/composites/outline.d.ts +18 -5
  175. package/dist/features/composites/outline.js +44 -12
  176. package/dist/features/composites/outline.js.map +1 -1
  177. package/dist/features/composites/react/CompositeDetails.js +1 -1
  178. package/dist/features/composites/react/CompositeInspector.d.ts +1 -1
  179. package/dist/features/composites/react/CompositeInspector.js +21 -180
  180. package/dist/features/composites/react/CompositeInspector.js.map +1 -1
  181. package/dist/features/composites/react/CompositeStatusMenu.d.ts +1 -1
  182. package/dist/features/composites/react/CompositeView.js +1 -1
  183. package/dist/features/composites/react/use-composite-inspector.js +29 -0
  184. package/dist/features/composites/react/use-composite-inspector.js.map +1 -0
  185. package/dist/features/composites/schema.d.ts +2 -2
  186. package/dist/features/composites/schema.js +2 -2
  187. package/dist/features/composites/schema.js.map +1 -1
  188. package/dist/features/composites/use-composite-anchors.d.ts +1 -1
  189. package/dist/features/composites/use-composite-inspector.js +41 -0
  190. package/dist/features/composites/use-composite-inspector.js.map +1 -0
  191. package/dist/features/composites/use-composite-rows.d.ts +1 -1
  192. package/dist/features/media/index.d.ts +1 -1
  193. package/dist/features/media/vue.d.ts +1 -1
  194. package/dist/features/mentions/index.d.ts +3 -3
  195. package/dist/features/mentions/index.js +3 -3
  196. package/dist/features/mentions/schema.d.ts +1 -1
  197. package/dist/features/mentions/schema.js +1 -1
  198. package/dist/features/themes/index.d.ts +1 -1
  199. package/dist/features/themes/index.js +1 -1
  200. package/dist/features/transcript/feature.js +1 -1
  201. package/dist/features/transcript/index.js +2 -2
  202. package/dist/i18n/de/ai.js +2 -0
  203. package/dist/i18n/de/ai.js.map +1 -1
  204. package/dist/i18n/de/composites.js +8 -1
  205. package/dist/i18n/de/composites.js.map +1 -1
  206. package/dist/i18n/de/tree.js +14 -1
  207. package/dist/i18n/de/tree.js.map +1 -1
  208. package/dist/i18n/de.d.ts +22 -0
  209. package/dist/i18n/en/ai.js +2 -0
  210. package/dist/i18n/en/ai.js.map +1 -1
  211. package/dist/i18n/en/composites.js +8 -1
  212. package/dist/i18n/en/composites.js.map +1 -1
  213. package/dist/i18n/en/tree.js +14 -1
  214. package/dist/i18n/en/tree.js.map +1 -1
  215. package/dist/integrations/composite-ai/composite-fill.js +2 -2
  216. package/dist/integrations/composite-ai/composite-summary.js +2 -2
  217. package/dist/integrations/composite-ai/index.js +2 -2
  218. package/dist/integrations/transcript-ai/transcript-cleanup.js +1 -1
  219. package/dist/markdown/MarkdownSurface.d.ts +1 -1
  220. package/dist/markdown/MarkdownSurface.js +2 -2
  221. package/dist/markdown/MarkdownSurface.vue.d.ts +7 -7
  222. package/dist/markdown/index.d.ts +2 -2
  223. package/dist/nuxt/runtime/server/routes/collab/[id].js +1 -1
  224. package/dist/react/EditorSurface.d.ts +1 -1
  225. package/dist/react/EditorSurface.js +43 -149
  226. package/dist/react/EditorSurface.js.map +1 -1
  227. package/dist/react/EditorToolbar.js +3 -40
  228. package/dist/react/EditorToolbar.js.map +1 -1
  229. package/dist/schema/advanced.js +2 -2
  230. package/dist/server/adapter.d.ts +2 -2
  231. package/dist/server/collab.js +1 -1
  232. package/dist/server/handlers/ai.d.ts +4 -2
  233. package/dist/server/handlers/ai.js +11 -9
  234. package/dist/server/handlers/ai.js.map +1 -1
  235. package/dist/server/handlers/context.d.ts +1 -1
  236. package/dist/server/handlers/editor.d.ts +1 -1
  237. package/dist/server/handlers/editor.js +2 -2
  238. package/dist/server/host.d.ts +1 -1
  239. package/dist/server/index.d.ts +2 -2
  240. package/dist/settings/index.d.ts +1 -1
  241. package/dist/styles/tokens.css +1 -1
  242. package/dist/tree/DocumentTree.js +159 -387
  243. package/dist/tree/DocumentTree.js.map +1 -1
  244. package/dist/tree/drop-rules.js +37 -0
  245. package/dist/tree/drop-rules.js.map +1 -0
  246. package/dist/tree/react/DocumentTree.d.ts +2 -2
  247. package/dist/tree/react/DocumentTree.js +135 -397
  248. package/dist/tree/react/DocumentTree.js.map +1 -1
  249. package/dist/tree/react/use-tree-model.js +129 -0
  250. package/dist/tree/react/use-tree-model.js.map +1 -0
  251. package/dist/tree/react.js +1 -1
  252. package/dist/tree/tree-host.js +100 -0
  253. package/dist/tree/tree-host.js.map +1 -0
  254. package/dist/tree/tree-items.js +22 -43
  255. package/dist/tree/tree-items.js.map +1 -1
  256. package/dist/tree/tree-model.js +580 -0
  257. package/dist/tree/tree-model.js.map +1 -0
  258. package/dist/tree/tree-rows.js +77 -0
  259. package/dist/tree/tree-rows.js.map +1 -0
  260. package/dist/tree/use-tree-model.js +94 -0
  261. package/dist/tree/use-tree-model.js.map +1 -0
  262. package/dist/tree/vue.js +1 -1
  263. package/dist/vue/AdvancedEditor.vue.d.ts +4 -4
  264. package/dist/vue/SimpleEditor.vue.d.ts +2 -2
  265. package/dist/vue/components/EditorSurface.js +27 -87
  266. package/dist/vue/components/EditorSurface.js.map +1 -1
  267. package/dist/vue/components/EditorSurface.vue.d.ts +4 -4
  268. package/dist/vue/components/EditorToolbar.js +7 -44
  269. package/dist/vue/components/EditorToolbar.js.map +1 -1
  270. package/dist/vue/context.d.ts +1 -1
  271. package/dist/vue/context.js +1 -1
  272. package/dist/vue/context.js.map +1 -1
  273. package/dist/vue/use-editor-ui.d.ts +1 -1
  274. package/dist/vue/use-notifier.d.ts +1 -1
  275. package/docs/integration.md +97 -4
  276. package/docs/llms.md +9 -1
  277. package/docs/usage.md +10 -5
  278. package/package.json +67 -5
@@ -1 +1 @@
1
- {"version":3,"file":"DocumentTree.js","names":["_useModel","outlineItems","buildOutlineItems","filterKinds","filterKindsFor","isDraggable","isDraggableItem","_openBlock","_createElementBlock","_createVNode","_unref","_createCommentVNode","_withKeys","_toDisplayString","_createBlock","_withCtx","_createElementVNode","_normalizeClass","_withModifiers","_Fragment","_renderSlot"],"sources":["../../src/tree/DocumentTree.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { DropdownItem } from '../vue/kit/types'\nimport { useUiKit } from '../vue/kit/use-ui-kit'\nimport type { Editor } from '@tiptap/core'\nimport { computed, ref, shallowRef, watch } from 'vue'\nimport { useEditorSettings } from '../vue/settings'\nimport { compositeJSON, type CompositeKind, compositeKindsOf, moveBlockInto } from '../features/composites'\nimport { pickFiles } from '../features/media'\nimport { useFileImport } from '../features/media/vue'\nimport { revealBlockInEditor } from '../outline'\nimport type { DocumentStore } from './store'\nimport {\n ancestorKeys,\n applyNodeFilters,\n canDrop,\n collectFolderPaths,\n collectKeys,\n collectParentKeys,\n compositeInsertPos,\n DRAG_MIME,\n type DragPayload,\n dragPayloadOf,\n EMPTY_OUTLINE,\n filterKinds as filterKindsFor,\n folderItem,\n folderNamesIn,\n holdsComposites,\n isDraggable as isDraggableItem,\n joinPath,\n type Outline,\n outlineItems as buildOutlineItems,\n parentPath,\n readOutline,\n type TreeItem,\n VIRTUAL_ROOT,\n virtualRootItem,\n} from './tree-items'\nimport { remapFolderPath } from './folder-paths'\nimport { useStoreRef } from '../vue/store-ref'\nimport { useEditorI18n } from '../vue/use-editor-i18n'\nimport { useTreeView } from './tree-view'\n\n// File browser of a document store: a „Dokumente“ root with folders and documents. Every `store` method reports its own\n// failure before it rejects, so the `.catch(() => undefined)`s below only stop the flow.\n\nconst props = defineProps<{\n /** Where documents and folders live; the host implements it (see `DocumentStore`). */\n store: DocumentStore\n /** Editor of the open document (its outline is listed under the document); `undefined` while none is mounted. */\n editor: Editor | undefined\n}>()\n\ndefineSlots<{\n /** Host actions on a document row, rendered next to its delete button (e.g. a download link). */\n 'document-actions'?: (props: { id: string, title: string }) => unknown\n}>()\n\n/** The folder new documents, folders and host imports go to. Reset to `''` when it is deleted or moved away. */\nconst selectedFolder = defineModel<string>('selectedFolder', { default: '' })\n\nconst { expanded, nodeFilters, model } = useTreeView()\nconst { expand } = model\nconst { t } = useEditorI18n()\nconst { importFiles } = useFileImport(() => props.editor)\nconst { settings } = useEditorSettings()\nconst { Button: UButton, DropdownMenu: UDropdownMenu, Icon: UIcon, Input: UInput, Tree: UTree, notifier } = useUiKit()\nconst notify = notifier()\n\nconst tree = useStoreRef(() => props.store.tree)\nconst storedDocuments = useStoreRef(() => props.store.documents)\nconst documents = computed(() => storedDocuments.value ?? [])\nconst activeId = useStoreRef(() => props.store.activeId)\nconst editor = computed(() => props.editor)\n\n// --- items -----------------------------------------------------------------------------------------------------\n\n/** Virtual mode: block ID of the selected `folder`/`document` composite; `null` = the document itself. */\nconst virtualTarget = ref<string | null>(null)\n\nfunction selectItem(item: TreeItem) {\n if (renamingKey.value === item.key) return\n if (item.key === VIRTUAL_ROOT) {\n virtualTarget.value = null\n return\n }\n if (item.type === 'document') {\n selectedFolder.value = item.folder ?? ''\n void props.store.open(item.id!).catch(() => undefined)\n } else {\n selectedFolder.value = item.path ?? ''\n }\n}\n\nconst fsItems = computed<TreeItem[]>(() => (tree.value ? [folderItem(tree.value, activeId.value, outlineItems.value, selectItem)] : []))\nconst isEmpty = computed(() => !virtual.value && !!tree.value && !tree.value.folders.length && !tree.value.documents.length)\n\n// Virtual mode: the open document is the root, its `folder`/`document` composites (and all others) the tree below it.\nconst virtualRoot = computed<TreeItem>(() => virtualRootItem(documents.value.find(d => d.id === activeId.value)?.title ?? t('tree.rootFallback'), outlineItems.value, selectItem))\nconst unfilteredItems = computed<TreeItem[]>(() => (virtual.value ? [virtualRoot.value] : fsItems.value))\nconst items = computed<TreeItem[]>(() => applyNodeFilters(unfilteredItems.value, nodeFilters.value))\n\n// --- outline of the open document ------------------------------------------------------------------------------\n\nconst showKindToolbar = computed(() => settings.value.blocks.structure === 'composite' && !!editor.value)\nconst kinds = computed(() => (editor.value ? compositeKindsOf(editor.value) : []))\n/**\n * What is loaded decides the view: a composite file (open document, composite structure) is the drawer's single root\n * when the `blocks.treeRoot` setting says so; otherwise (no document open, headings structure, or nesting files in\n * folders allowed) the drawer shows the folders of the store.\n */\nconst virtual = computed(() => settings.value.blocks.treeRoot === 'file' && settings.value.blocks.structure === 'composite' && !!editor.value)\nwatch(virtual, isVirtual => isVirtual && expand([VIRTUAL_ROOT]), { immediate: true })\n\n// Read from the editor on demand (not inside a computed: the editor's state is reactive and would re-run it on every\n// selection change) and refreshed, debounced, when the document changes.\nconst outline = shallowRef<Outline>(EMPTY_OUTLINE)\n\nfunction refreshOutline() {\n outline.value = readOutline(editor.value, settings.value.blocks.structure, t)\n}\n\nconst OUTLINE_DEBOUNCE_MS = 150\nlet outlineTimer: ReturnType<typeof setTimeout> | undefined\n\nwatch(editor, (instance, _previous, onCleanup) => {\n refreshOutline()\n if (!instance) return\n const onUpdate = () => {\n clearTimeout(outlineTimer)\n outlineTimer = setTimeout(refreshOutline, OUTLINE_DEBOUNCE_MS)\n }\n instance.on('update', onUpdate)\n onCleanup(() => {\n clearTimeout(outlineTimer)\n instance.off('update', onUpdate)\n })\n}, { immediate: true })\nwatch(() => settings.value.blocks.structure, refreshOutline)\n\nfunction selectOutline(item: TreeItem) {\n revealOutlineItem(item)\n if (virtual.value && item.blockId && (item.kind === 'folder' || item.kind === 'document')) virtualTarget.value = item.blockId\n}\n\nfunction revealOutlineItem(item: TreeItem) {\n if (editor.value && !editor.value.isDestroyed) revealBlockInEditor(editor.value, { id: item.blockId ?? null, pos: item.pos! })\n}\n\nconst outlineItems = computed<TreeItem[]>(() => buildOutlineItems(outline.value.nodes as Parameters<typeof buildOutlineItems>[0], kinds.value, selectOutline))\n\n// Outline entries start open: only the ones the user closed are remembered (session only), the rest of the open state\n// is the shared `expanded` list.\nconst collapsedOutline = ref<string[]>([])\nconst outlineParentKeys = computed(() => collectParentKeys(outlineItems.value, []))\n\nconst treeExpanded = computed({\n get: () => [...expanded.value, ...outlineParentKeys.value.filter(key => !collapsedOutline.value.includes(key))],\n set: (value) => {\n const open = new Set(value)\n expanded.value = value.filter(key => !outlineParentKeys.value.includes(key))\n collapsedOutline.value = outlineParentKeys.value.filter(key => !open.has(key))\n },\n})\n\n// Folders and the root toggle through the tree's own row click; documents and outline entries (whose row click opens\n// or reveals) toggle through their chevron.\nfunction onChevronClick(event: Event, item: TreeItem) {\n if (item.type === 'root' || item.type === 'folder') return\n event.stopPropagation()\n if (item.type === 'composite' || item.type === 'heading') {\n collapsedOutline.value = collapsedOutline.value.includes(item.key)\n ? collapsedOutline.value.filter(key => key !== item.key)\n : [...collapsedOutline.value, item.key]\n return\n }\n expanded.value = expanded.value.includes(item.key)\n ? expanded.value.filter(key => key !== item.key)\n : [...expanded.value, item.key]\n}\n\n// --- filters ---------------------------------------------------------------------------------------------------\n\n/** The kinds `item`'s filter can hide below it. */\nconst filterKinds = (item: TreeItem): readonly CompositeKind[] =>\n filterKindsFor(item, { structure: settings.value.blocks.structure, activeId: activeId.value, kinds: kinds.value, t })\n\nconst hiddenBelow = (item: TreeItem) => nodeFilters.value[item.key] ?? []\nconst isFiltered = (item: TreeItem) => hiddenBelow(item).length > 0\nconst showFilter = (item: TreeItem) =>\n filterKinds(item).length > 0 && (item.type === 'root' || item.type === 'folder' || !!item.children?.length || isFiltered(item))\n\nfunction filterMenu(item: TreeItem): DropdownItem[][] {\n const hidden = hiddenBelow(item)\n const groups: DropdownItem[][] = [[\n { type: 'label', label: t('tree.filter.show') },\n ...filterKinds(item).map<DropdownItem>(kind => ({\n label: kind.label,\n icon: kind.icon,\n type: 'checkbox',\n checked: !hidden.includes(kind.id),\n onUpdateChecked: visible => model.setKindHidden(item.key, kind.id, !visible),\n // Stay open: several kinds are usually toggled in one go.\n onSelect: event => event.preventDefault(),\n })),\n ]]\n if (hidden.length) groups.push([{ label: t('tree.filter.reset'), icon: 'i-lucide-filter-x', onSelect: () => model.clearFilter(item.key) }])\n return groups\n}\n\n// Filters of items that no longer exist (deleted documents, Bausteine) are ignored, so „Filter zurücksetzen“ only shows\n// while something visible is filtered.\nconst hasFilters = computed(() => {\n const keys = collectKeys(unfilteredItems.value, new Set())\n return Object.entries(nodeFilters.value).some(([key, hidden]) => hidden.length > 0 && keys.has(key))\n})\n\n// A selected folder that was deleted or moved away falls back to the root.\nwatch(tree, (value) => {\n if (!value) return\n const paths = new Set<string>()\n collectFolderPaths(value, paths)\n if (!paths.has(selectedFolder.value)) selectedFolder.value = ''\n})\n\n// --- expansion -------------------------------------------------------------------------------------------------\n\n// Opening a document (also by URL, or after a move) shows it: its folders open and its folder becomes the selected one.\nconst activeFolder = computed(() => documents.value.find(d => d.id === activeId.value)?.folder)\nwatch(activeFolder, (folder) => {\n expand(ancestorKeys(folder ?? ''))\n if (folder !== undefined) selectedFolder.value = folder\n}, { immediate: true })\n// The open document shows its outline.\nwatch(activeId, id => id && expand([`doc:${id}`]), { immediate: true })\n\n/** A folder moved from `from` to `to`: its open/selected state follows it. */\nfunction followFolderMove(from: string, to: string) {\n model.followFolderMove(from, to)\n selectedFolder.value = remapFolderPath(selectedFolder.value, from, to)\n expand(ancestorKeys(parentPath(to)))\n}\n\n// --- creating ----------------------------------------------------------------------------------------------------\n\n/** Makes a composite's children visible in the outline again. */\nfunction openOutline(blockId: string) {\n collapsedOutline.value = collapsedOutline.value.filter(key => key !== `outline:${blockId}`)\n}\n\nasync function importIntoComposite(blockId: string | null) {\n const files = await pickFiles('*/*')\n const instance = editor.value\n if (!files.length || !instance || instance.isDestroyed) return\n await importFiles(instance, files, compositeInsertPos(instance, blockId))\n if (blockId) openOutline(blockId)\n}\n\nfunction createCompositeFolder(blockId: string | null) {\n const instance = editor.value\n if (!instance || instance.isDestroyed) return\n const pos = compositeInsertPos(instance, blockId)\n // The caret goes into the new composite's title: one level in, then the text inside it.\n instance.chain().insertContentAt(pos, compositeJSON('folder')).setTextSelection(pos + 2).focus().scrollIntoView().run()\n if (blockId) openOutline(blockId)\n}\n\nasync function createDocumentIn(folder: string) {\n selectedFolder.value = folder\n const doc = await props.store.create(undefined, folder).catch(() => undefined)\n if (!doc) return\n expand(ancestorKeys(folder))\n await props.store.open(doc.id).catch(() => undefined)\n}\n\nconst creatingFolder = ref(false)\nconst folderDraft = ref('')\n/** Folder path the folder being named is created in. */\nconst folderParent = ref('')\n\nconst folderError = computed(() => (folderDraft.value.trim() ? props.store.validateName(folderDraft.value, folderNamesIn(tree.value, folderParent.value)) : null))\n\nfunction startCreateFolder(parent: string) {\n selectedFolder.value = parent\n folderParent.value = parent\n folderDraft.value = ''\n creatingFolder.value = true\n}\n\nasync function commitCreateFolder() {\n if (!creatingFolder.value) return\n if (!folderDraft.value.trim()) {\n creatingFolder.value = false\n return\n }\n // An invalid name keeps the field open with its inline error.\n if (folderError.value) return\n creatingFolder.value = false\n const parent = folderParent.value\n const created = await props.store.createFolder(joinPath(parent, folderDraft.value.trim())).then(() => true, () => false)\n if (created) expand(ancestorKeys(parent))\n}\n\n// --- + menu ----------------------------------------------------------------------------------------------------\n\n/**\n * What can be created below `item`: folders of the store take documents and sub-folders, the open file (as the root or\n * as a document row) and its Ordner/Dokument composites take Ordner and imported Dokument Bausteine. Other rows take\n * nothing. Folders also list „Umbenennen“ here: renaming a document happens in the editor's title field.\n */\nfunction addMenu(item: TreeItem): DropdownItem[][] {\n const groups: DropdownItem[][] = []\n if (item.key !== VIRTUAL_ROOT && (item.type === 'root' || item.type === 'folder')) {\n const path = item.path!\n groups.push([\n { label: t('tree.menu.newDocument'), icon: 'i-lucide-file-plus', onSelect: () => void createDocumentIn(path) },\n { label: item.type === 'root' ? t('tree.menu.newFolder') : t('tree.menu.newSubfolder'), icon: 'i-lucide-folder-plus', onSelect: () => startCreateFolder(path) },\n ])\n } else if (holdsComposites(item, { structure: settings.value.blocks.structure, editor: editor.value, activeId: activeId.value })) {\n const blockId = item.blockId ?? null\n groups.push([\n { label: t('tree.menu.newCompositeFolder'), icon: 'i-lucide-folder-plus', onSelect: () => { createCompositeFolder(blockId); if (!blockId) expand([item.key]) } },\n { label: t('tree.menu.importFile'), icon: 'i-lucide-file-up', onSelect: () => { void importIntoComposite(blockId); if (!blockId) expand([item.key]) } },\n ])\n }\n if (item.type === 'folder') groups.push([{ label: t('tree.menu.rename'), icon: 'i-lucide-pencil', onSelect: () => startRename(item) }])\n return groups\n}\n\n// --- rename (folders; a document is renamed in the editor's title field) ---------------------------------------------\n\nconst renamingKey = ref<string | null>(null)\nconst renamingItem = shallowRef<TreeItem | null>(null)\nconst renameDraft = ref('')\n\nfunction startRename(item: TreeItem) {\n renamingItem.value = item\n renamingKey.value = item.key\n renameDraft.value = item.label\n}\n\nconst renameError = computed(() => {\n const item = renamingItem.value\n if (!item || renamingKey.value === null || renameDraft.value.trim() === item.label) return null\n return props.store.validateName(renameDraft.value, folderNamesIn(tree.value, parentPath(item.path!), item.path))\n})\n\nfunction cancelRename() {\n renamingKey.value = null\n renamingItem.value = null\n}\n\nfunction onRenameBlur() {\n if (renamingKey.value === null) return\n if (renameError.value) {\n notify({ title: t('tree.folder.renameFailed'), description: renameError.value, kind: 'warning', icon: 'i-lucide-circle-alert' })\n cancelRename()\n return\n }\n return commitRename()\n}\n\nasync function commitRename() {\n const item = renamingItem.value\n if (!item || renamingKey.value === null) return\n // An invalid name keeps the field open with its inline error.\n if (renameError.value) return\n const name = renameDraft.value.trim()\n cancelRename()\n if (name === item.label) return\n const to = joinPath(parentPath(item.path!), name)\n const moved = await props.store.moveFolder(item.path!, to).then(() => true, () => false)\n if (moved) followFolderMove(item.path!, to)\n}\n\n// --- delete ----------------------------------------------------------------------------------------------------\n\nasync function removeWithUndo(id: string, folder: string) {\n // The store leaves an open document and waits for its page teardown (which destroys its collaboration provider)\n // before it deletes.\n const removed = await props.store.remove(id, folder).catch(() => undefined)\n if (!removed) return\n notify({\n title: t('tree.removed'),\n description: removed.title,\n icon: 'i-lucide-trash-2',\n action: { label: t('tree.undo'), onClick: () => restore(removed) },\n })\n}\n\nasync function restore(removed: { restore: () => Promise<{ id: string }> }) {\n const restored = await removed.restore().catch(() => undefined)\n if (restored) await props.store.open(restored.id).catch(() => undefined)\n}\n\nfunction removeItem(item: TreeItem) {\n if (item.type === 'document') return removeWithUndo(item.id!, item.folder ?? '')\n // The server refuses non-empty folders; the toast then reads „Ordner ist nicht leer“.\n return props.store.removeFolder(item.path!).catch(() => undefined)\n}\n\n// --- drag & drop -----------------------------------------------------------------------------------------------\n\nconst dragging = ref<DragPayload | null>(null)\nconst dropKey = ref<string | null>(null)\n\nfunction isDraggable(item: TreeItem) {\n return renamingKey.value !== item.key && isDraggableItem(item, virtual.value)\n}\n\nfunction onDragStart(event: DragEvent, item: TreeItem) {\n if (!isDraggable(item) || !event.dataTransfer) return event.preventDefault()\n const payload = dragPayloadOf(item)\n dragging.value = payload\n event.dataTransfer.setData(DRAG_MIME, JSON.stringify(payload))\n event.dataTransfer.effectAllowed = 'move'\n}\n\nfunction onDragOver(event: DragEvent, item: TreeItem) {\n if (!canDrop(dragging.value, item, { virtual: virtual.value, editor: editor.value })) return\n event.preventDefault()\n if (event.dataTransfer) event.dataTransfer.dropEffect = 'move'\n dropKey.value = item.key\n}\n\nfunction onDragLeave(event: DragEvent, item: TreeItem) {\n if (dropKey.value === item.key && !(event.currentTarget as Node).contains(event.relatedTarget as Node | null)) dropKey.value = null\n}\n\nfunction endDrag() {\n dragging.value = null\n dropKey.value = null\n}\n\nasync function onDrop(event: DragEvent, target: TreeItem) {\n const raw = event.dataTransfer?.getData(DRAG_MIME)\n endDrag()\n if (!raw) return\n event.preventDefault()\n const source = JSON.parse(raw) as DragPayload\n if (!canDrop(source, target, { virtual: virtual.value, editor: editor.value })) return\n if (source.type === 'composite') {\n const instance = editor.value\n const targetId = target.key === VIRTUAL_ROOT ? null : target.blockId!\n if (instance && moveBlockInto(instance, source.blockId, targetId) && targetId) openOutline(targetId)\n return\n }\n const targetPath = target.path!\n if (source.type === 'document') {\n const moved = await props.store.move(source.id!, targetPath).then(() => true, () => false)\n if (moved) expand(ancestorKeys(targetPath))\n return\n }\n const to = joinPath(targetPath, source.path.slice(source.path.lastIndexOf('/') + 1))\n const moved = await props.store.moveFolder(source.path, to).then(() => true, () => false)\n if (moved) followFolderMove(source.path, to)\n}\n</script>\n\n<template>\n <div class=\"flex flex-col gap-2\">\n <div v-if=\"hasFilters\" class=\"flex items-center\">\n <UButton\n icon=\"i-lucide-filter-x\"\n :label=\"t('tree.filter.reset')\"\n size=\"xs\"\n color=\"neutral\"\n variant=\"subtle\"\n @click=\"model.clearAllFilters\"\n />\n </div>\n\n <div v-if=\"creatingFolder\" class=\"flex flex-col gap-1\">\n <UInput\n v-model=\"folderDraft\"\n size=\"sm\"\n autofocus\n :color=\"folderError ? 'error' : undefined\"\n :highlight=\"!!folderError\"\n :placeholder=\"folderParent ? t('tree.folder.placeholderIn', { parent: folderParent }) : t('tree.folder.placeholder')\"\n :aria-label=\"t('tree.folder.name')\"\n :aria-invalid=\"!!folderError\"\n @keydown.enter=\"commitCreateFolder\"\n @keydown.esc=\"creatingFolder = false\"\n @blur=\"creatingFolder = false\"\n />\n <p v-if=\"folderError\" class=\"px-0.5 text-xs text-[var(--sk-danger)]\" role=\"alert\">\n {{ folderError }}\n </p>\n </div>\n\n <p v-if=\"!tree && !virtual\" class=\"px-2.5 py-1.5 text-sm text-[var(--sk-muted)]\">\n {{ tree === null ? t('tree.loadFailed') : t('tree.loading') }}\n </p>\n\n <UTree\n v-else\n v-model:expanded=\"treeExpanded\"\n :items=\"items\"\n :get-key=\"(item: TreeItem) => item.key\"\n size=\"sm\"\n :aria-label=\"t('tree.aria')\"\n >\n <template #item-wrapper=\"{ item, expanded: isOpen }: { item: TreeItem, expanded: boolean }\">\n <div\n class=\"group flex w-full cursor-pointer items-center gap-1.5 rounded-md px-2 py-1 text-sm select-none hover:bg-[color-mix(in_oklab,var(--sk-bg-elevated)_60%,transparent)]\"\n :class=\"[\n item.id !== undefined && item.id === activeId && 'bg-[color-mix(in_oklab,var(--sk-primary)_10%,transparent)] font-medium text-[var(--sk-primary)]',\n item.type !== 'document' && item.path === selectedFolder && 'bg-[var(--sk-bg-elevated)]',\n virtual && (item.key === VIRTUAL_ROOT ? virtualTarget === null : !!item.blockId && item.blockId === virtualTarget) && 'bg-[var(--sk-bg-elevated)]',\n dropKey === item.key && 'ring-1 ring-[var(--sk-primary)]',\n ]\"\n :draggable=\"isDraggable(item)\"\n @dragstart=\"onDragStart($event, item)\"\n @dragover=\"onDragOver($event, item)\"\n @dragleave=\"onDragLeave($event, item)\"\n @drop=\"onDrop($event, item)\"\n @dragend=\"endDrag\"\n >\n <UIcon\n v-if=\"item.type === 'root' || item.type === 'folder' || item.children?.length\"\n name=\"i-lucide-chevron-right\"\n class=\"size-3.5 shrink-0 text-[var(--sk-muted)] transition-transform\"\n :class=\"isOpen && 'rotate-90'\"\n @click=\"onChevronClick($event, item)\"\n />\n <span v-else-if=\"item.type === 'composite' || item.type === 'heading'\" class=\"size-3.5 shrink-0\" />\n <UIcon :name=\"item.icon\" class=\"size-4 shrink-0\" />\n\n <div v-if=\"renamingKey === item.key\" class=\"flex min-w-0 flex-1 flex-col gap-0.5\">\n <UInput\n v-model=\"renameDraft\"\n size=\"xs\"\n class=\"min-w-0\"\n autofocus\n :color=\"renameError ? 'error' : undefined\"\n :highlight=\"!!renameError\"\n :aria-label=\"t('tree.folder.name')\"\n :aria-invalid=\"!!renameError\"\n @focus=\"($event.target as HTMLInputElement).select()\"\n @click.stop\n @keydown.stop\n @keydown.enter=\"commitRename\"\n @keydown.esc=\"cancelRename\"\n @blur=\"onRenameBlur\"\n />\n <p v-if=\"renameError\" class=\"text-xs text-[var(--sk-danger)]\" role=\"alert\" @click.stop>\n {{ renameError }}\n </p>\n </div>\n <template v-else>\n <span class=\"min-w-0 flex-1 truncate\" :title=\"item.label\">{{ item.label }}</span>\n <UIcon\n v-if=\"item.hasSummary\"\n name=\"i-lucide-text-quote\"\n class=\"size-3.5 shrink-0 text-[var(--sk-muted)]\"\n :title=\"t('tree.summary')\"\n />\n <div class=\"flex shrink-0\" @click.stop>\n <UDropdownMenu v-if=\"showFilter(item)\" :items=\"filterMenu(item)\" :content=\"{ align: 'start' }\">\n <UButton\n icon=\"i-lucide-filter\"\n size=\"xs\"\n :color=\"isFiltered(item) ? 'primary' : 'neutral'\"\n :variant=\"isFiltered(item) ? 'soft' : 'ghost'\"\n :class=\"!isFiltered(item) && 'opacity-0 transition-opacity group-hover:opacity-100 group-focus-within:opacity-100 data-[state=open]:opacity-100'\"\n :title=\"t('tree.filter.title')\"\n :aria-label=\"t('tree.filter.title')\"\n />\n </UDropdownMenu>\n <div class=\"flex opacity-0 transition-opacity group-hover:opacity-100 group-focus-within:opacity-100 has-data-[state=open]:opacity-100\">\n <UDropdownMenu v-if=\"addMenu(item).length\" :items=\"addMenu(item)\" :content=\"{ align: 'start', onCloseAutoFocus: (event: Event) => event.preventDefault() }\">\n <UButton\n icon=\"i-lucide-plus\"\n size=\"xs\"\n color=\"neutral\"\n variant=\"ghost\"\n :title=\"t('tree.add')\"\n :aria-label=\"t('tree.add')\"\n />\n </UDropdownMenu>\n <slot v-if=\"item.type === 'document'\" name=\"document-actions\" :id=\"item.id!\" :title=\"item.label\" />\n <UButton\n v-if=\"item.type === 'document' || item.type === 'folder'\"\n icon=\"i-lucide-trash-2\"\n size=\"xs\"\n color=\"error\"\n variant=\"ghost\"\n :aria-label=\"t('tree.delete')\"\n loading-auto\n @click=\"removeItem(item)\"\n />\n </div>\n </div>\n </template>\n </div>\n </template>\n </UTree>\n\n <p v-if=\"isEmpty\" class=\"px-2.5 py-1.5 text-sm text-[var(--sk-muted)]\">\n {{ t('tree.empty') }}\n </p>\n </div>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"DocumentTree.js","names":["_useModel","_openBlock","_createElementBlock","_createVNode","_unref","_withKeys","_createSlots","_withCtx","_createCommentVNode","_toDisplayString","_createBlock","_createElementVNode","_normalizeClass","_withModifiers","_Fragment","_createTextVNode","_renderSlot"],"sources":["../../src/tree/DocumentTree.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { Editor } from '@tiptap/core'\nimport type { DropdownItem } from '../vue/kit/types'\nimport { useUiKit } from '../vue/kit/use-ui-kit'\nimport { useEditorI18n } from '../vue/use-editor-i18n'\nimport type { DocumentStore } from './store'\nimport { DRAG_MIME, type TreeItem } from './tree-items'\nimport { rowOf } from './tree-model'\nimport { useTreeModel } from './use-tree-model'\n\n// File browser of a document store: a „Dokumente“ root with folders and documents. It only renders the `TreeModel` (see\n// `tree-model.ts`), which owns what is open, filtered, selected, dragged and renamed; the React twin renders the same model.\n\nconst props = defineProps<{\n /** Where documents and folders live; the host implements it (see `DocumentStore`). */\n store: DocumentStore\n /** Editor of the open document (its outline is listed under the document); `undefined` while none is mounted. */\n editor: Editor | undefined\n}>()\n\ndefineSlots<{\n /** Host actions on a document row, rendered next to its delete button (e.g. a download link). */\n 'document-actions'?: (props: { id: string, title: string }) => unknown\n}>()\n\n/** The folder new documents, folders and host imports go to. Reset to `''` when it is deleted or moved away. */\nconst selectedFolder = defineModel<string>('selectedFolder', { default: '' })\n\nconst { t } = useEditorI18n()\nconst { Button: UButton, DropdownMenu: UDropdownMenu, Icon: UIcon, Input: UInput, Tree: UTree } = useUiKit()\nconst { model, state } = useTreeModel({ store: () => props.store, editor: () => props.editor, selectedFolder })\n\nconst row = (item: TreeItem) => rowOf(state.value, item, t)\n\n/** Why dropping the drag on `item` is refused, while the pointer is over it. */\nfunction refusal(item: TreeItem): string | null {\n const drop = row(item).drop\n return drop && !drop.ok ? drop.reason : null\n}\n\n/** UTree reports the keys of the rows it wants open; the model decides what that changes. */\nfunction onExpanded(next: string[]) {\n const wanted = new Set(next)\n const open = new Set(state.value.view.open)\n for (const key of wanted) if (!open.has(key)) model.value.setOpen(key, true)\n for (const key of open) if (!wanted.has(key)) model.value.setOpen(key, false)\n}\n\n/** The label split around the part the title filter matched, `null` when it did not match here. */\nfunction labelParts(item: TreeItem): [string, string, string] | null {\n const match = row(item).match\n if (!match) return null\n const [at, length] = match\n return [item.label.slice(0, at), item.label.slice(at, at + length), item.label.slice(at + length)]\n}\n\n// Folders and the root toggle through the tree's own row click; documents and outline entries (whose row click opens or\n// reveals) toggle through their chevron.\nfunction onChevronClick(event: Event, item: TreeItem) {\n if (item.type === 'root' || item.type === 'folder') return\n event.stopPropagation()\n model.value.toggle(item.key)\n}\n\nfunction filterMenu(item: TreeItem): DropdownItem[][] {\n const { filterKinds, hiddenKinds } = row(item)\n const groups: DropdownItem[][] = [[\n { type: 'label', label: t('tree.filter.show') },\n ...filterKinds.map<DropdownItem>(kind => ({\n label: kind.label,\n icon: kind.icon,\n type: 'checkbox',\n checked: !hiddenKinds.includes(kind.id),\n onUpdateChecked: visible => model.value.setKindHidden(item.key, kind.id, !visible),\n // Stay open: several kinds are usually toggled in one go.\n onSelect: event => event.preventDefault(),\n })),\n ]]\n if (hiddenKinds.length) groups.push([{ label: t('tree.filter.reset'), icon: 'i-lucide-filter-x', onSelect: () => model.value.clearFilter(item.key) }])\n return groups\n}\n\nfunction addMenu(item: TreeItem): DropdownItem[][] {\n return model.value.addMenu(item).map(group => group.map(entry => ({ label: entry.label, icon: entry.icon, onSelect: entry.run })))\n}\n\n// --- drag & drop -----------------------------------------------------------------------------------------------\n\nfunction onDragStart(event: DragEvent, item: TreeItem) {\n const payload = model.value.dragStart(item)\n if (!payload) return event.preventDefault()\n if (!event.dataTransfer) return model.value.dragEnd()\n event.dataTransfer.setData(DRAG_MIME, JSON.stringify(payload))\n event.dataTransfer.effectAllowed = 'move'\n}\n\nfunction onDragOver(event: DragEvent, item: TreeItem) {\n const verdict = model.value.dragOver(item)\n if (!verdict) return\n // Only an allowed target takes the drop; over a refused one the browser shows „not allowed“ and the row shows why.\n if (verdict.ok) event.preventDefault()\n if (event.dataTransfer) event.dataTransfer.dropEffect = verdict.ok ? 'move' : 'none'\n}\n\nfunction onDragLeave(event: DragEvent, item: TreeItem) {\n if (!(event.currentTarget as Node).contains(event.relatedTarget as Node | null)) model.value.dragLeave(item)\n}\n\nfunction onDrop(event: DragEvent, item: TreeItem) {\n if (!state.value.drag) return\n event.preventDefault()\n return model.value.drop(item)\n}\n</script>\n\n<template>\n <div class=\"flex flex-col gap-2\">\n <UInput\n :model-value=\"state.filterText\"\n icon=\"i-lucide-search\"\n size=\"sm\"\n :placeholder=\"t('tree.filterText.placeholder')\"\n :aria-label=\"t('tree.filterText.placeholder')\"\n @update:model-value=\"model.setFilterText($event)\"\n @keydown.esc=\"model.setFilterText('')\"\n >\n <template v-if=\"state.filterText\" #trailing>\n <UButton\n icon=\"i-lucide-x\"\n size=\"xs\"\n color=\"neutral\"\n variant=\"link\"\n :aria-label=\"t('tree.filterText.clear')\"\n @click=\"model.setFilterText('')\"\n />\n </template>\n </UInput>\n\n <div v-if=\"state.view.hasKindFilters\" class=\"flex items-center\">\n <UButton\n icon=\"i-lucide-filter-x\"\n :label=\"t('tree.filter.reset')\"\n size=\"xs\"\n color=\"neutral\"\n variant=\"subtle\"\n @click=\"model.clearAllFilters\"\n />\n </div>\n\n <div v-if=\"state.creatingFolder\" class=\"flex flex-col gap-1\">\n <UInput\n :model-value=\"state.creatingFolder.draft\"\n size=\"sm\"\n autofocus\n :color=\"state.creatingFolder.error ? 'error' : undefined\"\n :highlight=\"!!state.creatingFolder.error\"\n :placeholder=\"state.creatingFolder.parent ? t('tree.folder.placeholderIn', { parent: state.creatingFolder.parent }) : t('tree.folder.placeholder')\"\n :aria-label=\"t('tree.folder.name')\"\n :aria-invalid=\"!!state.creatingFolder.error\"\n @update:model-value=\"model.setFolderDraft($event)\"\n @keydown.enter=\"model.commitCreateFolder\"\n @keydown.esc=\"model.cancelCreateFolder\"\n @blur=\"model.cancelCreateFolder\"\n />\n <p v-if=\"state.creatingFolder.error\" class=\"px-0.5 text-xs text-[var(--sk-danger)]\" role=\"alert\">\n {{ state.creatingFolder.error }}\n </p>\n </div>\n\n <p v-if=\"!state.tree && !state.virtual\" class=\"px-2.5 py-1.5 text-sm text-[var(--sk-muted)]\">\n {{ state.tree === null ? t('tree.loadFailed') : t('tree.loading') }}\n </p>\n\n <UTree\n v-else\n :expanded=\"state.view.open\"\n :items=\"state.view.items\"\n :get-key=\"(item: TreeItem) => item.key\"\n size=\"sm\"\n :aria-label=\"t('tree.aria')\"\n @update:expanded=\"onExpanded\"\n >\n <template #item-wrapper=\"{ item }: { item: TreeItem }\">\n <div class=\"w-full\">\n <div\n class=\"group flex w-full cursor-pointer items-center gap-1.5 rounded-md px-2 py-1 text-sm select-none hover:bg-[color-mix(in_oklab,var(--sk-bg-elevated)_60%,transparent)]\"\n :class=\"[\n row(item).active && 'bg-[color-mix(in_oklab,var(--sk-primary)_10%,transparent)] font-medium text-[var(--sk-primary)]',\n row(item).selected && 'bg-[var(--sk-bg-elevated)]',\n row(item).drop?.ok && 'ring-1 ring-[var(--sk-primary)]',\n refusal(item) && 'bg-[color-mix(in_oklab,var(--sk-danger)_10%,transparent)] ring-1 ring-[var(--sk-danger)]',\n ]\"\n :draggable=\"model.isDraggable(item)\"\n @dragstart=\"onDragStart($event, item)\"\n @dragover=\"onDragOver($event, item)\"\n @dragleave=\"onDragLeave($event, item)\"\n @drop=\"onDrop($event, item)\"\n @dragend=\"model.dragEnd\"\n >\n <UIcon\n v-if=\"row(item).expandable\"\n name=\"i-lucide-chevron-right\"\n class=\"size-3.5 shrink-0 text-[var(--sk-muted)] transition-transform\"\n :class=\"row(item).open && 'rotate-90'\"\n @click=\"onChevronClick($event, item)\"\n />\n <span v-else-if=\"item.type === 'composite' || item.type === 'heading'\" class=\"size-3.5 shrink-0\" />\n <UIcon :name=\"item.icon\" class=\"size-4 shrink-0\" />\n\n <div v-if=\"row(item).renaming\" class=\"flex min-w-0 flex-1 flex-col gap-0.5\">\n <UInput\n :model-value=\"row(item).renaming!.draft\"\n size=\"xs\"\n class=\"min-w-0\"\n autofocus\n :color=\"row(item).renaming!.error ? 'error' : undefined\"\n :highlight=\"!!row(item).renaming!.error\"\n :aria-label=\"t('tree.folder.name')\"\n :aria-invalid=\"!!row(item).renaming!.error\"\n @update:model-value=\"model.setRenameDraft($event)\"\n @focus=\"($event.target as HTMLInputElement).select()\"\n @click.stop\n @keydown.stop\n @keydown.enter=\"model.commitRename\"\n @keydown.esc=\"model.cancelRename\"\n @blur=\"model.blurRename\"\n />\n <p v-if=\"row(item).renaming!.error\" class=\"text-xs text-[var(--sk-danger)]\" role=\"alert\" @click.stop>\n {{ row(item).renaming!.error }}\n </p>\n </div>\n <template v-else>\n <span class=\"min-w-0 flex-1 truncate\" :title=\"item.label\">\n <template v-if=\"labelParts(item)\">{{ labelParts(item)![0] }}<mark class=\"rounded-sm bg-[color-mix(in_oklab,var(--sk-primary)_20%,transparent)] text-inherit\">{{ labelParts(item)![1] }}</mark>{{ labelParts(item)![2] }}</template>\n <template v-else>{{ item.label }}</template>\n </span>\n <UIcon\n v-if=\"item.hasSummary\"\n name=\"i-lucide-text-quote\"\n class=\"size-3.5 shrink-0 text-[var(--sk-muted)]\"\n :title=\"t('tree.summary')\"\n />\n <div class=\"flex shrink-0\" @click.stop>\n <UDropdownMenu v-if=\"row(item).showFilter\" :items=\"filterMenu(item)\" :content=\"{ align: 'start' }\">\n <UButton\n icon=\"i-lucide-filter\"\n size=\"xs\"\n :color=\"row(item).hiddenKinds.length ? 'primary' : 'neutral'\"\n :variant=\"row(item).hiddenKinds.length ? 'soft' : 'ghost'\"\n :class=\"!row(item).hiddenKinds.length && 'opacity-0 transition-opacity group-hover:opacity-100 group-focus-within:opacity-100 data-[state=open]:opacity-100'\"\n :title=\"t('tree.filter.title')\"\n :aria-label=\"t('tree.filter.title')\"\n />\n </UDropdownMenu>\n <div class=\"flex opacity-0 transition-opacity group-hover:opacity-100 group-focus-within:opacity-100 has-data-[state=open]:opacity-100\">\n <UDropdownMenu v-if=\"addMenu(item).length\" :items=\"addMenu(item)\" :content=\"{ align: 'start', onCloseAutoFocus: (event: Event) => event.preventDefault() }\">\n <UButton\n icon=\"i-lucide-plus\"\n size=\"xs\"\n color=\"neutral\"\n variant=\"ghost\"\n :title=\"t('tree.add')\"\n :aria-label=\"t('tree.add')\"\n />\n </UDropdownMenu>\n <slot v-if=\"item.type === 'document'\" name=\"document-actions\" :id=\"item.id!\" :title=\"item.label\" />\n <UButton\n v-if=\"item.type === 'document' || item.type === 'folder'\"\n icon=\"i-lucide-trash-2\"\n size=\"xs\"\n color=\"error\"\n variant=\"ghost\"\n :aria-label=\"t('tree.delete')\"\n loading-auto\n @click=\"model.remove(item)\"\n />\n </div>\n </div>\n </template>\n </div>\n <p v-if=\"refusal(item)\" class=\"px-2 pt-0.5 text-xs text-[var(--sk-danger)]\" role=\"status\">\n {{ refusal(item) }}\n </p>\n </div>\n </template>\n </UTree>\n\n <p v-if=\"state.view.noMatches\" class=\"px-2.5 py-1.5 text-sm text-[var(--sk-muted)]\">\n {{ t('tree.noMatches') }}\n </p>\n <p v-if=\"state.view.isEmpty\" class=\"px-2.5 py-1.5 text-sm text-[var(--sk-muted)]\">\n {{ t('tree.empty') }}\n </p>\n </div>\n</template>\n"],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import { parentPath } from "./tree-items.js";
2
+ //#region src/tree/drop-rules.ts
3
+ const ok = { ok: true };
4
+ const refuse = (reason) => ({
5
+ ok: false,
6
+ reason
7
+ });
8
+ /**
9
+ * Whether `source` may be dropped on `target`.
10
+ * - A Baustein (virtual mode) goes on the document root or on a Baustein: the Baustein kinds' accepted children decide.
11
+ * - A document goes on the root or a folder of the store, unless it lives there already.
12
+ * - A folder goes on the root or a folder, unless that is itself, one of its sub-folders or its current parent.
13
+ */
14
+ function dropVerdict(source, target, env) {
15
+ const { t } = env;
16
+ if (!source) return refuse(t("tree.drop.nothing"));
17
+ if (source.type === "composite") return blockVerdict(source.blockId, target, env);
18
+ if (env.virtual) return refuse(t("tree.drop.noDocumentMove"));
19
+ if (target.type !== "root" && target.type !== "folder") return refuse(t("tree.drop.foldersOnly"));
20
+ const targetPath = target.path;
21
+ if (source.type === "document") return source.path === targetPath ? refuse(t("tree.drop.documentInFolder")) : ok;
22
+ if (targetPath === source.path || targetPath.startsWith(`${source.path}/`)) return refuse(t("tree.drop.folderIntoSelf"));
23
+ if (parentPath(source.path) === targetPath) return refuse(t("tree.drop.folderInFolder"));
24
+ return ok;
25
+ }
26
+ function blockVerdict(blockId, target, env) {
27
+ const { t } = env;
28
+ if (!env.virtual || !env.moveVerdict) return refuse(t("tree.drop.blocksOnlyInDocument"));
29
+ if (target.key === "vroot") return env.moveVerdict(blockId, null);
30
+ if (target.type !== "composite") return refuse(t("tree.drop.noBlocksHere"));
31
+ if (!target.blockId) return refuse(t("tree.drop.blockWithoutId"));
32
+ return env.moveVerdict(blockId, target.blockId);
33
+ }
34
+ //#endregion
35
+ export { dropVerdict };
36
+
37
+ //# sourceMappingURL=drop-rules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drop-rules.js","names":[],"sources":["../../src/tree/drop-rules.ts"],"sourcesContent":["import type { MoveVerdict } from '../features/composites'\nimport type { Translate } from '../i18n'\nimport { type DragPayload, parentPath, type TreeItem, VIRTUAL_ROOT } from './tree-items'\n\n// The drop rules of the document tree as one pure function: no state, no editor, no store. Where the open document\n// decides (the Baustein kinds' accepted children), the caller passes that rule in.\n\n/** Whether a drop may happen; a refusal carries a short sentence (in the language of the `t` that judged it) the tree shows under the target. */\nexport type DropVerdict = { ok: true } | { ok: false, reason: string }\n\n/** What `dropVerdict` needs from the outside. */\nexport interface DropEnv {\n /** The tree shows the open document as its root (Bausteine can be moved); otherwise it shows the store's folders. */\n virtual: boolean\n /**\n * Whether block `id` may move into the Baustein `targetId` (`null` = the end of the document), judged on the live\n * editor (`moveIntoVerdict`). `undefined` while no editor is mounted.\n */\n moveVerdict: ((id: string, targetId: string | null) => MoveVerdict) | undefined\n /** Words the refusals of this file's rules; the reasons of `moveVerdict` come already worded. */\n t: Translate\n}\n\nconst ok: DropVerdict = { ok: true }\nconst refuse = (reason: string): DropVerdict => ({ ok: false, reason })\n\n/**\n * Whether `source` may be dropped on `target`.\n * - A Baustein (virtual mode) goes on the document root or on a Baustein: the Baustein kinds' accepted children decide.\n * - A document goes on the root or a folder of the store, unless it lives there already.\n * - A folder goes on the root or a folder, unless that is itself, one of its sub-folders or its current parent.\n */\nexport function dropVerdict(source: DragPayload | null, target: TreeItem, env: DropEnv): DropVerdict {\n const { t } = env\n if (!source) return refuse(t('tree.drop.nothing'))\n if (source.type === 'composite') return blockVerdict(source.blockId, target, env)\n if (env.virtual) return refuse(t('tree.drop.noDocumentMove'))\n if (target.type !== 'root' && target.type !== 'folder') return refuse(t('tree.drop.foldersOnly'))\n const targetPath = target.path!\n if (source.type === 'document') return source.path === targetPath ? refuse(t('tree.drop.documentInFolder')) : ok\n if (targetPath === source.path || targetPath.startsWith(`${source.path}/`)) return refuse(t('tree.drop.folderIntoSelf'))\n if (parentPath(source.path) === targetPath) return refuse(t('tree.drop.folderInFolder'))\n return ok\n}\n\nfunction blockVerdict(blockId: string, target: TreeItem, env: DropEnv): DropVerdict {\n const { t } = env\n if (!env.virtual || !env.moveVerdict) return refuse(t('tree.drop.blocksOnlyInDocument'))\n if (target.key === VIRTUAL_ROOT) return env.moveVerdict(blockId, null)\n if (target.type !== 'composite') return refuse(t('tree.drop.noBlocksHere'))\n if (!target.blockId) return refuse(t('tree.drop.blockWithoutId'))\n return env.moveVerdict(blockId, target.blockId)\n}\n"],"mappings":";;AAuBA,MAAM,KAAkB,EAAE,IAAI,KAAK;AACnC,MAAM,UAAU,YAAiC;CAAE,IAAI;CAAO;AAAO;;;;;;;AAQrE,SAAgB,YAAY,QAA4B,QAAkB,KAA2B;CACnG,MAAM,EAAE,MAAM;CACd,IAAI,CAAC,QAAQ,OAAO,OAAO,EAAE,mBAAmB,CAAC;CACjD,IAAI,OAAO,SAAS,aAAa,OAAO,aAAa,OAAO,SAAS,QAAQ,GAAG;CAChF,IAAI,IAAI,SAAS,OAAO,OAAO,EAAE,0BAA0B,CAAC;CAC5D,IAAI,OAAO,SAAS,UAAU,OAAO,SAAS,UAAU,OAAO,OAAO,EAAE,uBAAuB,CAAC;CAChG,MAAM,aAAa,OAAO;CAC1B,IAAI,OAAO,SAAS,YAAY,OAAO,OAAO,SAAS,aAAa,OAAO,EAAE,4BAA4B,CAAC,IAAI;CAC9G,IAAI,eAAe,OAAO,QAAQ,WAAW,WAAW,GAAG,OAAO,KAAK,EAAE,GAAG,OAAO,OAAO,EAAE,0BAA0B,CAAC;CACvH,IAAI,WAAW,OAAO,IAAI,MAAM,YAAY,OAAO,OAAO,EAAE,0BAA0B,CAAC;CACvF,OAAO;AACT;AAEA,SAAS,aAAa,SAAiB,QAAkB,KAA2B;CAClF,MAAM,EAAE,MAAM;CACd,IAAI,CAAC,IAAI,WAAW,CAAC,IAAI,aAAa,OAAO,OAAO,EAAE,gCAAgC,CAAC;CACvF,IAAI,OAAO,QAAA,SAAsB,OAAO,IAAI,YAAY,SAAS,IAAI;CACrE,IAAI,OAAO,SAAS,aAAa,OAAO,OAAO,EAAE,wBAAwB,CAAC;CAC1E,IAAI,CAAC,OAAO,SAAS,OAAO,OAAO,EAAE,0BAA0B,CAAC;CAChE,OAAO,IAAI,YAAY,SAAS,OAAO,OAAO;AAChD"}
@@ -1,6 +1,6 @@
1
1
  import { DocumentStore } from "../store.js";
2
- import { ReactNode } from "react";
3
2
  import { Editor } from "@tiptap/core";
3
+ import { ReactNode } from "react";
4
4
  //#region src/tree/react/DocumentTree.d.ts
5
5
  /** Props of `DocumentTree`. */
6
6
  export interface DocumentTreeProps {
@@ -19,6 +19,6 @@ export interface DocumentTreeProps {
19
19
  className?: string;
20
20
  }
21
21
  /** The file browser of a document store: folders and documents with their drag and drop, the open document's outline below it. */
22
- export declare function DocumentTree({ store, editor, selectedFolder: controlledFolder, onSelectedFolderChange, documentActions, className }: DocumentTreeProps): import("react").JSX.Element;
22
+ export declare function DocumentTree({ store, editor, selectedFolder, onSelectedFolderChange, documentActions, className }: DocumentTreeProps): import("react").JSX.Element | null;
23
23
  //#endregion
24
24
  //# sourceMappingURL=DocumentTree.d.ts.map