@ecsplico/editor 3.6.0 → 4.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 +73 -0
- package/dist/adapters/direct-ai.d.ts +4 -4
- package/dist/adapters/direct-ai.js +2 -2
- package/dist/adapters/direct-ai.js.map +1 -1
- package/dist/adapters/document-state.d.ts +1 -1
- package/dist/adapters/document-state.js.map +1 -1
- package/dist/adapters/forge.d.ts +2 -2
- package/dist/adapters/forge.js.map +1 -1
- package/dist/adapters/nitro.d.ts +11 -3
- package/dist/adapters/nitro.js +3 -1
- package/dist/adapters/nitro.js.map +1 -1
- package/dist/adapters/shared.d.ts +6 -6
- package/dist/adapters/shared.js.map +1 -1
- package/dist/code/CodeSurface.vue.d.ts +3 -3
- package/dist/config/index.d.ts +14 -14
- package/dist/config/index.js +8 -8
- package/dist/config/index.js.map +1 -1
- package/dist/core/backend-types.d.ts +3 -3
- package/dist/core/backend-types.js.map +1 -1
- package/dist/core/backend.d.ts +4 -4
- package/dist/core/backend.js.map +1 -1
- package/dist/core/block-convert.d.ts +1 -1
- package/dist/core/block-convert.js +5 -5
- package/dist/core/block-convert.js.map +1 -1
- package/dist/core/block-transfer.d.ts +8 -4
- package/dist/core/block-transfer.js +23 -14
- package/dist/core/block-transfer.js.map +1 -1
- package/dist/core/capabilities.d.ts +113 -0
- package/dist/core/capabilities.js +155 -0
- package/dist/core/capabilities.js.map +1 -0
- package/dist/core/command-types.d.ts +1 -1
- package/dist/core/context.js.map +1 -1
- package/dist/core/convert.d.ts +5 -5
- package/dist/core/convert.js +5 -5
- package/dist/core/convert.js.map +1 -1
- package/dist/core/core-feature.js +1 -1
- package/dist/core/define-editor.d.ts +2 -2
- package/dist/core/define-editor.js +34 -6
- package/dist/core/define-editor.js.map +1 -1
- package/dist/core/derivation.d.ts +119 -0
- package/dist/core/derivation.js +187 -0
- package/dist/core/derivation.js.map +1 -0
- package/dist/core/derive.d.ts +61 -0
- package/dist/core/derive.js +69 -0
- package/dist/core/derive.js.map +1 -0
- package/dist/core/extension-points.d.ts +16 -0
- package/dist/core/feature-context.d.ts +5 -1
- package/dist/core/feature-context.js +10 -3
- package/dist/core/feature-context.js.map +1 -1
- package/dist/core/feature.d.ts +41 -19
- package/dist/core/feature.js.map +1 -1
- package/dist/core/fences.js +1 -1
- package/dist/core/fences.js.map +1 -1
- package/dist/core/index.d.ts +6 -2
- package/dist/core/index.js +5 -1
- package/dist/core/pipeline.d.ts +14 -5
- package/dist/core/pipeline.js +19 -7
- package/dist/core/pipeline.js.map +1 -1
- package/dist/core/properties.d.ts +22 -0
- package/dist/core/properties.js +17 -0
- package/dist/core/properties.js.map +1 -0
- package/dist/core/schema/block-ids.js +5 -5
- package/dist/core/schema/block-ids.js.map +1 -1
- package/dist/core/schema/index.d.ts +2 -1
- package/dist/core/schema/index.js +2 -1
- package/dist/core/schema/index.js.map +1 -1
- package/dist/core/schema/opaque-fence.d.ts +4 -4
- package/dist/core/schema/opaque-fence.js +7 -7
- package/dist/core/schema/opaque-fence.js.map +1 -1
- package/dist/core/schema/persisted-names.d.ts +58 -0
- package/dist/core/schema/persisted-names.js +96 -0
- package/dist/core/schema/persisted-names.js.map +1 -0
- package/dist/core/toolbar-items.js +1 -1
- package/dist/core/toolbar-items.js.map +1 -1
- package/dist/core/util.js +5 -1
- package/dist/core/util.js.map +1 -1
- package/dist/document/DocumentSurface.vue.d.ts +3 -3
- package/dist/features/ai/agent-ops.js +1 -1
- package/dist/features/ai/ai-review.js +1 -1
- package/dist/features/ai/assistant.d.ts +4 -4
- package/dist/features/ai/assistant.js +1 -1
- package/dist/features/ai/assistant.js.map +1 -1
- package/dist/features/ai/components/AiSelectionMenu.js +1 -1
- package/dist/features/ai/components/AiSelectionMenu.js.map +1 -1
- package/dist/features/ai/components/ModelQuickSwitch.js +7 -7
- package/dist/features/ai/components/ModelQuickSwitch.js.map +1 -1
- package/dist/features/ai/components/ModelQuickSwitch.vue.d.ts +4 -4
- package/dist/features/ai/components/SettingsAiTab.js +8 -8
- package/dist/features/ai/components/SettingsAiTab.js.map +1 -1
- package/dist/features/ai/components/SettingsModelProfiles.js +1 -1
- package/dist/features/ai/components/SettingsModelProfiles.js.map +1 -1
- package/dist/features/ai/document-chat-model.d.ts +2 -2
- package/dist/features/ai/document-chat-model.js +5 -5
- package/dist/features/ai/document-chat-model.js.map +1 -1
- package/dist/features/ai/document-chat.js +2 -2
- package/dist/features/ai/document-chat.js.map +1 -1
- package/dist/features/ai/feature.d.ts +2 -2
- package/dist/features/ai/feature.js +2 -2
- package/dist/features/ai/feature.js.map +1 -1
- package/dist/features/ai/ghost-autocomplete.d.ts +4 -4
- package/dist/features/ai/ghost-autocomplete.js +1 -1
- package/dist/features/ai/ghost-autocomplete.js.map +1 -1
- package/dist/features/ai/index.d.ts +3 -3
- package/dist/features/ai/index.js +2 -2
- package/dist/features/ai/model-profiles.d.ts +9 -9
- package/dist/features/ai/model-profiles.js +13 -13
- package/dist/features/ai/model-profiles.js.map +1 -1
- package/dist/features/ai/protocol/agent-ops.d.ts +2 -2
- package/dist/features/ai/protocol/agent-ops.js +1 -1
- package/dist/features/ai/protocol/agent-ops.js.map +1 -1
- package/dist/features/ai/protocol/block-lines.d.ts +7 -7
- package/dist/features/ai/protocol/block-lines.js +10 -10
- package/dist/features/ai/protocol/block-lines.js.map +1 -1
- package/dist/features/ai/protocol/chat.d.ts +5 -5
- package/dist/features/ai/protocol/chat.js +12 -12
- package/dist/features/ai/protocol/chat.js.map +1 -1
- package/dist/features/ai/protocol/generate.d.ts +1 -1
- package/dist/features/ai/protocol/generate.js +1 -1
- package/dist/features/ai/protocol/generate.js.map +1 -1
- package/dist/features/ai/protocol/index.d.ts +3 -3
- package/dist/features/ai/protocol/index.js +2 -2
- package/dist/features/ai/protocol/models.d.ts +3 -3
- package/dist/features/ai/protocol/models.js +3 -3
- package/dist/features/ai/protocol/models.js.map +1 -1
- package/dist/features/ai/protocol/schemas.d.ts +1 -1
- package/dist/features/ai/protocol/schemas.js +1 -1
- package/dist/features/ai/protocol/schemas.js.map +1 -1
- package/dist/features/ai/protocol/tasks.d.ts +5 -5
- package/dist/features/ai/protocol/tasks.js +12 -12
- package/dist/features/ai/protocol/tasks.js.map +1 -1
- package/dist/features/ai/react/AiSelectionMenu.js.map +1 -1
- package/dist/features/ai/react/ModelQuickSwitch.d.ts +4 -4
- package/dist/features/ai/react/ModelQuickSwitch.js +6 -6
- package/dist/features/ai/react/ModelQuickSwitch.js.map +1 -1
- package/dist/features/ai/react/SettingsAiTab.d.ts +1 -1
- package/dist/features/ai/react/SettingsAiTab.js +8 -8
- package/dist/features/ai/react/SettingsAiTab.js.map +1 -1
- package/dist/features/ai/react/SettingsModelProfiles.d.ts +1 -1
- package/dist/features/ai/react/SettingsModelProfiles.js +1 -1
- package/dist/features/ai/react/SettingsModelProfiles.js.map +1 -1
- package/dist/features/ai/react/use-ai-assistant.d.ts +1 -1
- package/dist/features/ai/react/use-ai-assistant.js +1 -1
- package/dist/features/ai/react/use-ai-assistant.js.map +1 -1
- package/dist/features/ai/react/use-model-profiles.d.ts +5 -5
- package/dist/features/ai/react/use-model-profiles.js +2 -2
- package/dist/features/ai/react/use-model-profiles.js.map +1 -1
- package/dist/features/ai/use-ai-assistant.d.ts +1 -1
- package/dist/features/ai/use-ai-assistant.js +1 -1
- package/dist/features/ai/use-ai-assistant.js.map +1 -1
- package/dist/features/ai/use-model-profiles.d.ts +4 -4
- package/dist/features/ai/use-model-profiles.js +2 -2
- package/dist/features/ai/use-model-profiles.js.map +1 -1
- package/dist/features/block-ui/block-actions.d.ts +8 -4
- package/dist/features/block-ui/block-actions.js +38 -22
- package/dist/features/block-ui/block-actions.js.map +1 -1
- package/dist/features/block-ui/block-target.d.ts +29 -0
- package/dist/features/block-ui/block-target.js +63 -0
- package/dist/features/block-ui/block-target.js.map +1 -0
- package/dist/features/block-ui/components/BlockHandles.js +3 -3
- package/dist/features/block-ui/components/BlockHandles.js.map +1 -1
- package/dist/features/block-ui/components/BlockUi.js +11 -23
- package/dist/features/block-ui/components/BlockUi.js.map +1 -1
- package/dist/features/block-ui/feature.d.ts +3 -2
- package/dist/features/block-ui/feature.js +3 -2
- package/dist/features/block-ui/feature.js.map +1 -1
- package/dist/features/block-ui/handle-geometry.js +12 -23
- package/dist/features/block-ui/handle-geometry.js.map +1 -1
- package/dist/features/block-ui/index.d.ts +2 -1
- package/dist/features/block-ui/index.js +2 -1
- package/dist/features/block-ui/react/BlockHandles.d.ts +1 -1
- package/dist/features/block-ui/react/BlockHandles.js +4 -4
- package/dist/features/block-ui/react/BlockHandles.js.map +1 -1
- package/dist/features/block-ui/react/BlockUi.js +13 -25
- package/dist/features/block-ui/react/BlockUi.js.map +1 -1
- package/dist/features/comments/model.js +1 -1
- package/dist/features/composites/accepted-children.d.ts +5 -4
- package/dist/features/composites/accepted-children.js +26 -26
- package/dist/features/composites/accepted-children.js.map +1 -1
- package/dist/features/composites/ai-brief.d.ts +4 -4
- package/dist/features/composites/ai-brief.js +14 -12
- package/dist/features/composites/ai-brief.js.map +1 -1
- package/dist/features/composites/anchors.d.ts +1 -1
- package/dist/features/composites/anchors.js.map +1 -1
- package/dist/features/composites/baskets.d.ts +1 -1
- package/dist/features/composites/baskets.js.map +1 -1
- package/dist/features/composites/bibliography-command.d.ts +1 -1
- package/dist/features/composites/bibliography-form.js +1 -1
- package/dist/features/composites/bibliography-form.js.map +1 -1
- package/dist/features/composites/bibliography.js.map +1 -1
- package/dist/features/composites/block-types-json.d.ts +38 -0
- package/dist/features/composites/block-types-json.js +122 -0
- package/dist/features/composites/block-types-json.js.map +1 -0
- package/dist/features/composites/block-types.d.ts +119 -0
- package/dist/features/composites/block-types.js +343 -0
- package/dist/features/composites/block-types.js.map +1 -0
- package/dist/features/composites/capabilities.js +109 -0
- package/dist/features/composites/capabilities.js.map +1 -0
- package/dist/features/composites/components/BibliographyEditor.js +5 -5
- package/dist/features/composites/components/BibliographyEditor.js.map +1 -1
- package/dist/features/composites/components/CompositeBasketMenu.js +2 -2
- package/dist/features/composites/components/CompositeBasketMenu.js.map +1 -1
- package/dist/features/composites/components/CompositeChrome.js +18 -8
- package/dist/features/composites/components/CompositeChrome.js.map +1 -1
- package/dist/features/composites/components/CompositeChrome.vue.d.ts +1 -1
- package/dist/features/composites/components/CompositeDetails.js +11 -10
- package/dist/features/composites/components/CompositeDetails.js.map +1 -1
- package/dist/features/composites/components/CompositeDetails.vue.d.ts +1 -1
- package/dist/features/composites/components/CompositeFieldEditor.js +7 -7
- package/dist/features/composites/components/CompositeFieldEditor.js.map +1 -1
- package/dist/features/composites/components/CompositeFieldEditor.vue.d.ts +5 -5
- package/dist/features/composites/components/CompositeInspector.js +136 -113
- package/dist/features/composites/components/CompositeInspector.js.map +1 -1
- package/dist/features/composites/components/CompositeInspector.vue.d.ts +3 -3
- package/dist/features/composites/components/CompositeStatusMenu.js +2 -2
- package/dist/features/composites/components/CompositeStatusMenu.js.map +1 -1
- package/dist/features/composites/components/CompositeSummaryEditor.js +1 -1
- package/dist/features/composites/components/CompositeSummaryEditor.js.map +1 -1
- package/dist/features/composites/components/CompositeSummaryEditor.vue.d.ts +1 -1
- package/dist/features/composites/components/CompositeTable.js +2 -2
- package/dist/features/composites/components/CompositeTable.js.map +1 -1
- package/dist/features/composites/components/CompositeTagsEditor.js +1 -1
- package/dist/features/composites/components/CompositeTagsEditor.js.map +1 -1
- package/dist/features/composites/components/CompositeTagsEditor.vue.d.ts +1 -1
- package/dist/features/composites/components/CompositeView.js +19 -17
- package/dist/features/composites/components/CompositeView.js.map +1 -1
- package/dist/features/composites/components/DerivationBadge.js +15 -6
- package/dist/features/composites/components/DerivationBadge.js.map +1 -1
- package/dist/features/composites/components/FocusChip.js +1 -1
- package/dist/features/composites/components/FocusChip.js.map +1 -1
- package/dist/features/composites/components/FocusChip.vue.d.ts +1 -1
- package/dist/features/composites/components/ReferenceFieldSelect.js +3 -3
- package/dist/features/composites/components/ReferenceFieldSelect.js.map +1 -1
- package/dist/features/composites/components/ReferenceView.js +1 -1
- package/dist/features/composites/components/ReferenceView.js.map +1 -1
- package/dist/features/composites/components/SettingsEditingTab.js +18 -18
- package/dist/features/composites/components/SettingsEditingTab.js.map +1 -1
- package/dist/features/composites/components/SettingsEditingTab.vue.d.ts +3 -3
- package/dist/features/composites/convert.d.ts +4 -4
- package/dist/features/composites/convert.js +27 -28
- package/dist/features/composites/convert.js.map +1 -1
- package/dist/features/composites/derived-chrome.js +34 -28
- package/dist/features/composites/derived-chrome.js.map +1 -1
- package/dist/features/composites/editing-settings-keys.js +6 -6
- package/dist/features/composites/editing-settings-keys.js.map +1 -1
- package/dist/features/composites/feature.d.ts +10 -10
- package/dist/features/composites/feature.js +58 -46
- package/dist/features/composites/feature.js.map +1 -1
- package/dist/features/composites/fences.d.ts +3 -3
- package/dist/features/composites/fences.js +18 -13
- package/dist/features/composites/fences.js.map +1 -1
- package/dist/features/composites/focus.d.ts +10 -10
- package/dist/features/composites/focus.js +11 -11
- package/dist/features/composites/focus.js.map +1 -1
- package/dist/features/composites/heading-composites.d.ts +5 -5
- package/dist/features/composites/heading-composites.js +13 -16
- package/dist/features/composites/heading-composites.js.map +1 -1
- package/dist/features/composites/index.d.ts +20 -18
- package/dist/features/composites/index.js +9 -7
- package/dist/features/composites/inspector-model.d.ts +45 -22
- package/dist/features/composites/inspector-model.js +53 -14
- package/dist/features/composites/inspector-model.js.map +1 -1
- package/dist/features/composites/legacy.d.ts +5 -4
- package/dist/features/composites/legacy.js +16 -23
- package/dist/features/composites/legacy.js.map +1 -1
- package/dist/features/composites/markdown-export.js +3 -3
- package/dist/features/composites/markdown-export.js.map +1 -1
- package/dist/features/composites/merge.d.ts +8 -8
- package/dist/features/composites/merge.js +23 -22
- package/dist/features/composites/merge.js.map +1 -1
- package/dist/features/composites/meta-display.js +5 -5
- package/dist/features/composites/meta-display.js.map +1 -1
- package/dist/features/composites/meta-keys.d.ts +5 -5
- package/dist/features/composites/meta-keys.js +8 -8
- package/dist/features/composites/meta-keys.js.map +1 -1
- package/dist/features/composites/node-views.d.ts +3 -3
- package/dist/features/composites/node-views.js +2 -2
- package/dist/features/composites/node-views.js.map +1 -1
- package/dist/features/composites/nodes.d.ts +13 -13
- package/dist/features/composites/nodes.js +100 -77
- package/dist/features/composites/nodes.js.map +1 -1
- package/dist/features/composites/outline.d.ts +15 -12
- package/dist/features/composites/outline.js +24 -21
- package/dist/features/composites/outline.js.map +1 -1
- package/dist/features/composites/properties.d.ts +51 -0
- package/dist/features/composites/properties.js +89 -0
- package/dist/features/composites/properties.js.map +1 -0
- package/dist/features/composites/react/BibliographyEditor.js +5 -5
- package/dist/features/composites/react/BibliographyEditor.js.map +1 -1
- package/dist/features/composites/react/CompositeBasketMenu.js +2 -2
- package/dist/features/composites/react/CompositeBasketMenu.js.map +1 -1
- package/dist/features/composites/react/CompositeChrome.d.ts +1 -1
- package/dist/features/composites/react/CompositeChrome.js +15 -6
- package/dist/features/composites/react/CompositeChrome.js.map +1 -1
- package/dist/features/composites/react/CompositeDetails.d.ts +1 -1
- package/dist/features/composites/react/CompositeDetails.js +11 -10
- package/dist/features/composites/react/CompositeDetails.js.map +1 -1
- package/dist/features/composites/react/CompositeFieldEditor.d.ts +5 -5
- package/dist/features/composites/react/CompositeFieldEditor.js +6 -6
- package/dist/features/composites/react/CompositeFieldEditor.js.map +1 -1
- package/dist/features/composites/react/CompositeInspector.d.ts +3 -3
- package/dist/features/composites/react/CompositeInspector.js +142 -128
- package/dist/features/composites/react/CompositeInspector.js.map +1 -1
- package/dist/features/composites/react/CompositeStatusMenu.js +2 -2
- package/dist/features/composites/react/CompositeStatusMenu.js.map +1 -1
- package/dist/features/composites/react/CompositeSummaryEditor.d.ts +1 -1
- package/dist/features/composites/react/CompositeSummaryEditor.js +1 -1
- package/dist/features/composites/react/CompositeSummaryEditor.js.map +1 -1
- package/dist/features/composites/react/CompositeTable.d.ts +1 -1
- package/dist/features/composites/react/CompositeTable.js +3 -3
- package/dist/features/composites/react/CompositeTable.js.map +1 -1
- package/dist/features/composites/react/CompositeTagsEditor.d.ts +1 -1
- package/dist/features/composites/react/CompositeTagsEditor.js +1 -1
- package/dist/features/composites/react/CompositeTagsEditor.js.map +1 -1
- package/dist/features/composites/react/CompositeView.js +17 -15
- package/dist/features/composites/react/CompositeView.js.map +1 -1
- package/dist/features/composites/react/DerivationBadge.js +13 -4
- package/dist/features/composites/react/DerivationBadge.js.map +1 -1
- package/dist/features/composites/react/FocusChip.d.ts +1 -1
- package/dist/features/composites/react/FocusChip.js +1 -1
- package/dist/features/composites/react/FocusChip.js.map +1 -1
- package/dist/features/composites/react/ReferenceFieldSelect.js +3 -3
- package/dist/features/composites/react/ReferenceFieldSelect.js.map +1 -1
- package/dist/features/composites/react/ReferenceView.d.ts +1 -1
- package/dist/features/composites/react/ReferenceView.js +1 -1
- package/dist/features/composites/react/ReferenceView.js.map +1 -1
- package/dist/features/composites/react/SettingsEditingTab.d.ts +4 -4
- package/dist/features/composites/react/SettingsEditingTab.js +20 -20
- package/dist/features/composites/react/SettingsEditingTab.js.map +1 -1
- package/dist/features/composites/react.js +1 -1
- package/dist/features/composites/react.js.map +1 -1
- package/dist/features/composites/reference-ai.js +1 -1
- package/dist/features/composites/reference-ai.js.map +1 -1
- package/dist/features/composites/reference-label.d.ts +3 -3
- package/dist/features/composites/reference-label.js +6 -6
- package/dist/features/composites/reference-label.js.map +1 -1
- package/dist/features/composites/reference-suggestion.d.ts +1 -1
- package/dist/features/composites/reference-suggestion.js +3 -3
- package/dist/features/composites/reference-suggestion.js.map +1 -1
- package/dist/features/composites/reference-text.d.ts +2 -2
- package/dist/features/composites/reference-text.js +4 -4
- package/dist/features/composites/reference-text.js.map +1 -1
- package/dist/features/composites/reference.d.ts +3 -3
- package/dist/features/composites/reference.js +1 -1
- package/dist/features/composites/reference.js.map +1 -1
- package/dist/features/composites/reveal-source.d.ts +3 -3
- package/dist/features/composites/reveal-source.js +6 -6
- package/dist/features/composites/reveal-source.js.map +1 -1
- package/dist/features/composites/rows-model.d.ts +2 -2
- package/dist/features/composites/rows-model.js +4 -3
- package/dist/features/composites/rows-model.js.map +1 -1
- package/dist/features/composites/rows.d.ts +16 -28
- package/dist/features/composites/rows.js +20 -54
- package/dist/features/composites/rows.js.map +1 -1
- package/dist/features/composites/schema.d.ts +12 -11
- package/dist/features/composites/schema.js +10 -9
- package/dist/features/composites/schema.js.map +1 -1
- package/dist/features/composites/source.d.ts +20 -0
- package/dist/features/composites/source.js +40 -0
- package/dist/features/composites/source.js.map +1 -0
- package/dist/features/composites/split.d.ts +11 -11
- package/dist/features/composites/split.js +20 -20
- package/dist/features/composites/split.js.map +1 -1
- package/dist/features/composites/structure-mode.js +3 -3
- package/dist/features/composites/structure-mode.js.map +1 -1
- package/dist/features/composites/table-model.js +2 -2
- package/dist/features/composites/table-model.js.map +1 -1
- package/dist/features/composites/use-composite-inspector.js +3 -1
- package/dist/features/composites/use-composite-inspector.js.map +1 -1
- package/dist/features/composites/use-composite-rows.d.ts +2 -2
- package/dist/features/composites/use-composite-rows.js.map +1 -1
- package/dist/features/composites/vue.js +1 -1
- package/dist/features/composites/vue.js.map +1 -1
- package/dist/features/image-studio/components/ImageStudioDialog.js +150 -87
- package/dist/features/image-studio/components/ImageStudioDialog.js.map +1 -1
- package/dist/features/image-studio/components/ImageStudioDialog.vue.d.ts +5 -1
- package/dist/features/image-studio/components/ImageStudioLibraryPanel.js +186 -0
- package/dist/features/image-studio/components/ImageStudioLibraryPanel.js.map +1 -0
- package/dist/features/image-studio/components/ImageStudioLibraryTile.js +134 -0
- package/dist/features/image-studio/components/ImageStudioLibraryTile.js.map +1 -0
- package/dist/features/image-studio/components/ImageStudioView.js.map +1 -1
- package/dist/features/image-studio/feature.d.ts +1 -1
- package/dist/features/image-studio/feature.js +1 -1
- package/dist/features/image-studio/feature.js.map +1 -1
- package/dist/features/image-studio/index.d.ts +3 -2
- package/dist/features/image-studio/index.js +2 -2
- package/dist/features/image-studio/library.d.ts +35 -0
- package/dist/features/image-studio/node-core.d.ts +3 -3
- package/dist/features/image-studio/node-core.js +1 -1
- package/dist/features/image-studio/node-core.js.map +1 -1
- package/dist/features/image-studio/node-store.d.ts +1 -1
- package/dist/features/image-studio/node-store.js +1 -1
- package/dist/features/image-studio/node-store.js.map +1 -1
- package/dist/features/image-studio/react/ImageStudioDialog.d.ts +1 -1
- package/dist/features/image-studio/react/ImageStudioDialog.js +46 -5
- package/dist/features/image-studio/react/ImageStudioDialog.js.map +1 -1
- package/dist/features/image-studio/react/ImageStudioLibraryPanel.js +141 -0
- package/dist/features/image-studio/react/ImageStudioLibraryPanel.js.map +1 -0
- package/dist/features/image-studio/react/ImageStudioLibraryTile.js +105 -0
- package/dist/features/image-studio/react/ImageStudioLibraryTile.js.map +1 -0
- package/dist/features/image-studio/react/ImageStudioView.js +1 -1
- package/dist/features/image-studio/react/ImageStudioView.js.map +1 -1
- package/dist/features/image-studio/react/store.d.ts +8 -3
- package/dist/features/image-studio/react/store.js.map +1 -1
- package/dist/features/image-studio/react.d.ts +4 -3
- package/dist/features/image-studio/react.js +3 -3
- package/dist/features/image-studio/react.js.map +1 -1
- package/dist/features/image-studio/schema.d.ts +1 -1
- package/dist/features/image-studio/schema.js +1 -1
- package/dist/features/image-studio/schema.js.map +1 -1
- package/dist/features/image-studio/state.d.ts +8 -3
- package/dist/features/image-studio/state.js +11 -3
- package/dist/features/image-studio/state.js.map +1 -1
- package/dist/features/image-studio/store.d.ts +8 -3
- package/dist/features/image-studio/vue.d.ts +4 -3
- package/dist/features/image-studio/vue.js +3 -3
- package/dist/features/image-studio/vue.js.map +1 -1
- package/dist/features/mentions/tag.js +2 -1
- package/dist/features/mentions/tag.js.map +1 -1
- package/dist/features/themes/components/SettingsAppearanceTab.js +1 -1
- package/dist/features/themes/components/SettingsAppearanceTab.js.map +1 -1
- package/dist/features/themes/feature.d.ts +1 -1
- package/dist/features/themes/feature.js.map +1 -1
- package/dist/features/themes/react/SettingsAppearanceTab.d.ts +1 -1
- package/dist/features/themes/react/SettingsAppearanceTab.js +1 -1
- package/dist/features/themes/react/SettingsAppearanceTab.js.map +1 -1
- package/dist/features/themes/theme-runtime.js +1 -1
- package/dist/features/themes/theme-runtime.js.map +1 -1
- package/dist/features/transcript/TranscriptSegmentView.js +1 -1
- package/dist/features/transcript/TranscriptSegmentView.js.map +1 -1
- package/dist/features/transcript/react/TranscriptSegmentView.js +1 -1
- package/dist/features/transcript/react/TranscriptSegmentView.js.map +1 -1
- package/dist/features/transcript/segment-node.js.map +1 -1
- package/dist/features/transfer/feature.js +1 -1
- package/dist/features/transfer/feature.js.map +1 -1
- package/dist/features/transfer/transforms.d.ts +4 -4
- package/dist/features/transfer/transforms.js +12 -12
- package/dist/features/transfer/transforms.js.map +1 -1
- package/dist/i18n/de/ai.js +4 -4
- package/dist/i18n/de/ai.js.map +1 -1
- package/dist/i18n/de/authors.js +1 -1
- package/dist/i18n/de/authors.js.map +1 -1
- package/dist/i18n/de/comments.js +1 -1
- package/dist/i18n/de/comments.js.map +1 -1
- package/dist/i18n/de/composites.js +62 -59
- package/dist/i18n/de/composites.js.map +1 -1
- package/dist/i18n/de/image-studio.js +11 -2
- package/dist/i18n/de/image-studio.js.map +1 -1
- package/dist/i18n/de/integrations.js +20 -20
- package/dist/i18n/de/integrations.js.map +1 -1
- package/dist/i18n/de/markdown.js +1 -1
- package/dist/i18n/de/markdown.js.map +1 -1
- package/dist/i18n/de/palette.js +1 -1
- package/dist/i18n/de/palette.js.map +1 -1
- package/dist/i18n/de/themes.js +3 -3
- package/dist/i18n/de/themes.js.map +1 -1
- package/dist/i18n/de/transfer.js +2 -2
- package/dist/i18n/de/transfer.js.map +1 -1
- package/dist/i18n/de/tree.js +6 -6
- package/dist/i18n/de/tree.js.map +1 -1
- package/dist/i18n/de.d.ts +110 -98
- package/dist/i18n/en/ai.js +2 -2
- package/dist/i18n/en/ai.js.map +1 -1
- package/dist/i18n/en/composites.js +64 -61
- package/dist/i18n/en/composites.js.map +1 -1
- package/dist/i18n/en/image-studio.js +9 -0
- package/dist/i18n/en/image-studio.js.map +1 -1
- package/dist/i18n/en/integrations.js +9 -9
- package/dist/i18n/en/integrations.js.map +1 -1
- package/dist/i18n/en/markdown.js +1 -1
- package/dist/i18n/en/markdown.js.map +1 -1
- package/dist/i18n/en/palette.js +1 -1
- package/dist/i18n/en/palette.js.map +1 -1
- package/dist/i18n/en/themes.js +4 -4
- package/dist/i18n/en/themes.js.map +1 -1
- package/dist/i18n/en/tree.js +5 -5
- package/dist/i18n/en/tree.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/integrations/composite-ai/bibliography-fetch.d.ts +6 -6
- package/dist/integrations/composite-ai/bibliography-fetch.js +19 -19
- package/dist/integrations/composite-ai/bibliography-fetch.js.map +1 -1
- package/dist/integrations/composite-ai/composite-fill.d.ts +4 -4
- package/dist/integrations/composite-ai/composite-fill.js +5 -5
- package/dist/integrations/composite-ai/composite-fill.js.map +1 -1
- package/dist/integrations/composite-ai/composite-summary.d.ts +2 -2
- package/dist/integrations/composite-ai/composite-summary.js +5 -5
- package/dist/integrations/composite-ai/composite-summary.js.map +1 -1
- package/dist/integrations/composite-ai/derive.d.ts +17 -17
- package/dist/integrations/composite-ai/derive.js +27 -26
- package/dist/integrations/composite-ai/derive.js.map +1 -1
- package/dist/integrations/composite-ai/index.d.ts +14 -15
- package/dist/integrations/composite-ai/index.js +98 -77
- package/dist/integrations/composite-ai/index.js.map +1 -1
- package/dist/integrations/composite-ai/outline-sanitize.d.ts +1 -1
- package/dist/integrations/composite-ai/outline-sanitize.js +1 -1
- package/dist/integrations/composite-ai/outline-sanitize.js.map +1 -1
- package/dist/integrations/composite-ai/rendition.d.ts +9 -9
- package/dist/integrations/composite-ai/rendition.js +27 -27
- package/dist/integrations/composite-ai/rendition.js.map +1 -1
- package/dist/integrations/composite-ai/split.d.ts +8 -8
- package/dist/integrations/composite-ai/split.js +12 -12
- package/dist/integrations/composite-ai/split.js.map +1 -1
- package/dist/integrations/composite-ai/transfer-transforms.d.ts +2 -2
- package/dist/integrations/composite-ai/transfer-transforms.js +11 -11
- package/dist/integrations/composite-ai/transfer-transforms.js.map +1 -1
- package/dist/integrations/composite-media/index.d.ts +4 -3
- package/dist/integrations/composite-media/index.js +20 -14
- package/dist/integrations/composite-media/index.js.map +1 -1
- package/dist/markdown/MarkdownSurface.vue.d.ts +7 -7
- package/dist/markdown/document.js +1 -1
- package/dist/markdown/document.js.map +1 -1
- package/dist/nuxt/module.d.ts +48 -24
- package/dist/nuxt/module.js.map +1 -1
- package/dist/nuxt/runtime/server/plugins/editor-server.js +3 -2
- package/dist/nuxt/runtime/server/plugins/editor-server.js.map +1 -1
- package/dist/presets/compose.d.ts +6 -6
- package/dist/presets/compose.js +7 -4
- package/dist/presets/compose.js.map +1 -1
- package/dist/react/AdvancedEditor.d.ts +2 -2
- package/dist/react/AdvancedEditor.js +1 -1
- package/dist/react/AdvancedEditor.js.map +1 -1
- package/dist/react/compose.d.ts +1 -1
- package/dist/react/compose.js +1 -1
- package/dist/react/compose.js.map +1 -1
- package/dist/react/composed-surface.d.ts +5 -5
- package/dist/react/composed-surface.js +2 -2
- package/dist/react/composed-surface.js.map +1 -1
- package/dist/server/ai.d.ts +7 -7
- package/dist/server/ai.js +1 -1
- package/dist/server/ai.js.map +1 -1
- package/dist/server/auth.d.ts +1 -1
- package/dist/server/collab-state.d.ts +1 -1
- package/dist/server/collab-state.js.map +1 -1
- package/dist/server/collab.d.ts +4 -4
- package/dist/server/collab.js +22 -17
- package/dist/server/collab.js.map +1 -1
- package/dist/server/handlers/ai.d.ts +9 -6
- package/dist/server/handlers/ai.js +13 -17
- package/dist/server/handlers/ai.js.map +1 -1
- package/dist/server/handlers/context.d.ts +4 -0
- package/dist/server/handlers/context.js.map +1 -1
- package/dist/server/handlers/editor.d.ts +33 -32
- package/dist/server/handlers/editor.js +13 -8
- package/dist/server/handlers/editor.js.map +1 -1
- package/dist/server/handlers/images.d.ts +1 -1
- package/dist/server/handlers/images.js +1 -1
- package/dist/server/handlers/images.js.map +1 -1
- package/dist/server/host.d.ts +4 -0
- package/dist/server/host.js +10 -2
- package/dist/server/host.js.map +1 -1
- package/dist/server/index.d.ts +3 -3
- package/dist/server/ports.d.ts +8 -8
- package/dist/server/ports.js.map +1 -1
- package/dist/settings/index.d.ts +20 -19
- package/dist/settings/index.js +25 -24
- package/dist/settings/index.js.map +1 -1
- package/dist/settings/migrate.d.ts +18 -0
- package/dist/settings/migrate.js +46 -0
- package/dist/settings/migrate.js.map +1 -0
- package/dist/settings/values.d.ts +12 -12
- package/dist/settings/values.js +11 -11
- package/dist/settings/values.js.map +1 -1
- package/dist/styles/composites.css +10 -10
- package/dist/tree/DocumentTree.js +12 -5
- package/dist/tree/DocumentTree.js.map +1 -1
- package/dist/tree/drop-rules.js +5 -5
- package/dist/tree/drop-rules.js.map +1 -1
- package/dist/tree/react/DocumentTree.js +14 -5
- package/dist/tree/react/DocumentTree.js.map +1 -1
- package/dist/tree/tree-host.js +5 -5
- package/dist/tree/tree-host.js.map +1 -1
- package/dist/tree/tree-items.js +34 -28
- package/dist/tree/tree-items.js.map +1 -1
- package/dist/tree/tree-model.js +16 -16
- package/dist/tree/tree-model.js.map +1 -1
- package/dist/tree/tree-rows.js +2 -2
- package/dist/tree/tree-rows.js.map +1 -1
- package/dist/tree/tree-view-model.d.ts +2 -2
- package/dist/tree/tree-view-model.js.map +1 -1
- package/dist/vue/AdvancedEditor.js +2 -2
- package/dist/vue/AdvancedEditor.js.map +1 -1
- package/dist/vue/AdvancedEditor.vue.d.ts +10 -10
- package/dist/vue/SimpleEditor.vue.d.ts +4 -4
- package/dist/vue/components/EditorSurface.vue.d.ts +4 -4
- package/dist/vue/compose.d.ts +1 -1
- package/dist/vue/compose.js +1 -1
- package/dist/vue/compose.js.map +1 -1
- package/package.json +1 -1
- package/dist/features/composites/derivation.d.ts +0 -62
- package/dist/features/composites/derivation.js +0 -102
- package/dist/features/composites/derivation.js.map +0 -1
- package/dist/features/composites/kinds.d.ts +0 -89
- package/dist/features/composites/kinds.js +0 -285
- package/dist/features/composites/kinds.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CompositeTable.js","names":[],"sources":["../../../../src/features/composites/react/CompositeTable.tsx"],"sourcesContent":["import type { Editor } from '@tiptap/core'\nimport { useMemo, useState } from 'react'\nimport { Icon } from '../../../react/Icon'\nimport { Badge } from '../../../react/ui/badge'\nimport { Button } from '../../../react/ui/button'\nimport { Input } from '../../../react/ui/input'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../../../react/ui/select'\nimport { TableBody, TableCell, TableHead, TableHeader, TableRow } from '../../../react/ui/table'\nimport { cn } from '../../../react/ui/utils'\nimport { useEditorI18n } from '../../../react/use-editor-i18n'\nimport { compositeKindsOf } from '../nodes'\nimport type { CompositeRow } from '../rows'\nimport { columnSpecsOf, type FieldContext, FILTER_ALL, fieldColumnsOf, fieldOf, fieldText, hasText, isLongText, sortRows, toggled } from '../table-model'\nimport { useCompositeRows } from './use-composite-rows'\n\n// All Bausteine of an editor's document as a sortable, filterable table. Columns beyond the fixed ones derive from the\n// meta fields of the kinds present in the document, so a host kind with fields gets its columns without code changes.\n// The column specs, cell text and sorting are the framework-free `table-model`, shared with the Vue table.\n\n/** The table of an editor's Bausteine: sortable columns, filters by kind, tag and select fields, a text search; `onSelect` receives the clicked row. */\nexport function CompositeTable({ editor, onSelect, className }: {\n editor?: Editor\n onSelect?: (row: CompositeRow) => void\n className?: string\n}) {\n const { rows, tags, kinds } = useCompositeRows(editor)\n\n const { t } = useEditorI18n()\n // `reference` cells resolve their target in the document; re-read whenever the rows change.\n const fieldContext = useMemo<FieldContext | undefined>(() => (editor ? { doc: editor.state.doc, kinds: compositeKindsOf(editor), t } : undefined), [editor, rows, t])\n const fieldColumns = useMemo(() => fieldColumnsOf(rows, kinds, fieldContext), [rows, kinds, fieldContext])\n const specs = useMemo(() => columnSpecsOf(fieldColumns, t), [fieldColumns, t])\n\n const [search, setSearch] = useState('')\n const [pickedKinds, setPickedKinds] = useState<string[]>([])\n const [pickedTags, setPickedTags] = useState<string[]>([])\n const [pickedOptions, setPickedOptions] = useState<Record<string, string>>({})\n\n /** One select per `select` field in use; its choices are the union of the options of all kinds that have the key. */\n const selectFilters = useMemo(() => fieldColumns.flatMap((column) => {\n if (column.field.type !== 'select') return []\n const options = new Map<string, string>()\n for (const row of rows) {\n for (const option of fieldOf(row, column.field.key)?.options ?? []) if (!options.has(option.value)) options.set(option.value, option.label)\n }\n return [{\n key: column.field.key,\n label: column.field.label,\n items: [{ label: t('composites.table.filter.all'), value: FILTER_ALL }, ...[...options].map(([value, label]) => ({ label, value }))],\n }]\n }), [fieldColumns, rows, t])\n\n // A kind, tag or option that vanished from the document can no longer be unpicked in the UI, so it must not filter either.\n const activeKinds = useMemo(() => pickedKinds.filter(id => kinds.some(kind => kind.id === id)), [pickedKinds, kinds])\n const activeTags = useMemo(() => pickedTags.filter(tag => tags.includes(tag)), [pickedTags, tags])\n const activeOptions = useMemo(() => selectFilters.flatMap((filter) => {\n const value = pickedOptions[filter.key]\n return value && filter.items.some(item => item.value === value && value !== FILTER_ALL) ? [[filter.key, value] as const] : []\n }), [selectFilters, pickedOptions])\n const needle = search.trim().toLowerCase()\n const filterActive = activeKinds.length > 0 || activeTags.length > 0 || activeOptions.length > 0 || needle !== ''\n\n function resetFilters() {\n setSearch('')\n setPickedKinds([])\n setPickedTags([])\n setPickedOptions({})\n }\n\n const filtered = useMemo(() => rows.filter((row) => {\n if (activeKinds.length && !activeKinds.includes(row.kind)) return false\n if (activeTags.length && !activeTags.every(tag => row.tags.includes(tag))) return false\n if (activeOptions.some(([key, value]) => row.meta[key] !== value)) return false\n if (needle) {\n const haystack = `${row.title}\\n${row.description}\\n${row.tags.map(tag => `#${tag}`).join(' ')}`.toLowerCase()\n if (!haystack.includes(needle)) return false\n }\n return true\n }), [rows, activeKinds, activeTags, activeOptions, needle])\n\n // --- Sorting (client side, over the filtered rows) ---\n\n const [sorting, setSorting] = useState<{ id: string, desc: boolean } | null>(null)\n const activeSort = useMemo(() => {\n const spec = sorting && specs.find(item => item.id === sorting.id)\n return sorting && spec ? { id: sorting.id, desc: sorting.desc, sort: spec.sort } : null\n }, [sorting, specs])\n\n /** Header click cycles ascending → descending → unsorted. */\n function cycleSort(id: string) {\n setSorting(current => current?.id !== id ? { id, desc: false } : current.desc ? null : { id, desc: true })\n }\n const sortIcon = (id: string) => {\n if (sorting?.id !== id) return 'i-lucide-chevrons-up-down'\n return sorting.desc ? 'i-lucide-arrow-down' : 'i-lucide-arrow-up'\n }\n\n const sorted = useMemo(() => activeSort ? sortRows(filtered, activeSort.sort, activeSort.desc) : filtered, [filtered, activeSort])\n\n const countLabel = t(rows.length === 1 ? 'composites.table.count.one' : 'composites.table.count.other', { n: sorted.length, total: rows.length })\n const columnCount = specs.length\n\n return (\n <section className={cn('flex min-h-0 flex-col gap-3', className)} aria-label={t('composites.table.label')}>\n {!rows.length\n ? (\n <div className=\"mx-auto flex max-w-sm flex-1 flex-col items-center justify-center gap-2 py-16 text-center\">\n <Icon name=\"i-lucide-table-2\" className=\"size-8 text-muted-foreground/70\" />\n <p className=\"text-sm font-medium text-foreground\">\n {t('composites.table.emptyTitle')}\n </p>\n <p className=\"text-sm text-muted-foreground\">\n {t('composites.table.emptyText')}\n </p>\n </div>\n )\n : (\n <>\n <div className=\"flex flex-col gap-2\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <div className=\"relative w-64\">\n <Icon name=\"i-lucide-search\" className=\"pointer-events-none absolute top-1/2 left-2.5 size-4 -translate-y-1/2 text-muted-foreground\" />\n <Input\n value={search}\n onChange={event => setSearch(event.target.value)}\n className={cn('h-7 pl-8 text-sm', search && 'pr-8')}\n placeholder={t('composites.table.search.placeholder')}\n aria-label={t('composites.table.search.label')}\n />\n {search && (\n <Button\n variant=\"ghost\"\n size=\"icon-xs\"\n className=\"absolute top-1/2 right-1 -translate-y-1/2\"\n aria-label={t('composites.table.search.clear')}\n onClick={() => setSearch('')}\n >\n <Icon name=\"i-lucide-x\" />\n </Button>\n )}\n </div>\n\n {selectFilters.map(filter => (\n <div key={filter.key} className=\"flex items-center gap-1.5\">\n <span className=\"text-sm text-muted-foreground\" aria-hidden=\"true\">{filter.label}</span>\n <Select\n value={pickedOptions[filter.key] ?? FILTER_ALL}\n onValueChange={value => setPickedOptions({ ...pickedOptions, [filter.key]: String(value) })}\n >\n <SelectTrigger size=\"sm\" className=\"w-36\" aria-label={filter.label}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {filter.items.map(item => <SelectItem key={item.value} value={item.value}>{item.label}</SelectItem>)}\n </SelectContent>\n </Select>\n </div>\n ))}\n\n {filterActive && (\n <Button size=\"sm\" variant=\"ghost\" onClick={resetFilters}>\n <Icon name=\"i-lucide-filter-x\" />\n {t('composites.table.filter.reset')}\n </Button>\n )}\n <span className=\"ml-auto text-xs text-muted-foreground tabular-nums\" role=\"status\">{countLabel}</span>\n </div>\n\n {kinds.length > 1 && (\n <div className=\"flex flex-wrap items-center gap-1\" role=\"group\" aria-label={t('composites.table.filter.byKind')}>\n {kinds.map(kind => (\n <Button\n key={kind.id}\n size=\"xs\"\n variant={activeKinds.includes(kind.id) ? 'default' : 'outline'}\n aria-pressed={activeKinds.includes(kind.id)}\n onClick={() => setPickedKinds(toggled(pickedKinds, kind.id))}\n >\n <Icon name={kind.icon} />\n {kind.label}\n </Button>\n ))}\n </div>\n )}\n\n {tags.length > 0 && (\n <div className=\"flex flex-wrap items-center gap-1\" role=\"group\" aria-label={t('composites.table.filter.byTag')}>\n {tags.map(tag => (\n <Button\n key={tag}\n size=\"xs\"\n variant={activeTags.includes(tag) ? 'default' : 'outline'}\n aria-pressed={activeTags.includes(tag)}\n onClick={() => setPickedTags(toggled(pickedTags, tag))}\n >\n {`#${tag}`}\n </Button>\n ))}\n </div>\n )}\n </div>\n\n {/* Own scroll container instead of `<Table>`'s: the sticky header needs the element that scrolls vertically. */}\n <div className=\"min-h-0 flex-1 overflow-auto rounded-md border border-border\">\n <table data-slot=\"table\" className=\"w-full caption-bottom text-sm\">\n <TableHeader className=\"sticky top-0 z-10 bg-background\">\n <TableRow className=\"hover:bg-transparent\">\n {specs.map(spec => (\n <TableHead\n key={spec.id}\n className={cn('h-auto px-3 py-2 text-sm', spec.id === 'title' && 'min-w-56', spec.align === 'end' && 'text-right')}\n aria-sort={activeSort?.id === spec.id ? (activeSort.desc ? 'descending' : 'ascending') : 'none'}\n >\n <button\n type=\"button\"\n className=\"-mx-1.5 inline-flex cursor-pointer items-center gap-1 rounded px-1.5 py-0.5 font-semibold hover:bg-muted focus-visible:outline-2 focus-visible:outline-primary\"\n onClick={() => cycleSort(spec.id)}\n >\n {spec.label}\n <Icon name={sortIcon(spec.id)} className={cn('size-3.5', activeSort?.id === spec.id ? 'text-foreground' : 'text-muted-foreground/70')} />\n </button>\n </TableHead>\n ))}\n </TableRow>\n </TableHeader>\n <TableBody>\n {sorted.length === 0\n ? (\n <TableRow className=\"hover:bg-transparent\">\n <TableCell colSpan={columnCount} className=\"px-3 py-2 text-muted-foreground\">\n <div className=\"flex flex-col items-center gap-2 py-6\">\n <p className=\"text-sm text-muted-foreground\">\n {t('composites.table.filter.noMatch')}\n </p>\n <Button size=\"sm\" variant=\"outline\" onClick={resetFilters}>\n <Icon name=\"i-lucide-filter-x\" />\n {t('composites.table.filter.reset')}\n </Button>\n </div>\n </TableCell>\n </TableRow>\n )\n : sorted.map(row => (\n <TableRow key={row.key} className=\"cursor-pointer\" onClick={() => onSelect?.(row)}>\n {specs.map((spec) => {\n const cellClass = cn('px-3 py-2 text-muted-foreground', spec.align === 'end' && 'text-right')\n if (spec.id === 'title') {\n return (\n <TableCell key={spec.id} className={cellClass}>\n <div className=\"flex min-w-0 items-center gap-1.5\" style={{ paddingLeft: `${row.depth * 1.25}rem` }}>\n <Icon name={row.icon} className=\"size-4 shrink-0 text-muted-foreground\" />\n {hasText(row.title)\n ? <span className=\"truncate font-medium text-foreground\">{row.title}</span>\n : <span className=\"truncate text-muted-foreground\">{t('composites.untitled')}</span>}\n </div>\n </TableCell>\n )\n }\n if (spec.id === 'kind') return <TableCell key={spec.id} className={cellClass}>{row.kindLabel}</TableCell>\n if (spec.id === 'tags') {\n return (\n <TableCell key={spec.id} className={cellClass}>\n {row.tags.length\n ? (\n <div className=\"flex flex-wrap gap-1\">\n {row.tags.map(tag => <Badge key={tag} variant=\"secondary\">{`#${tag}`}</Badge>)}\n </div>\n )\n : (\n <>\n <span className=\"text-muted-foreground/70\" aria-hidden=\"true\">–</span>\n <span className=\"sr-only\">{t('composites.table.noTags')}</span>\n </>\n )}\n </TableCell>\n )\n }\n if (spec.id === 'summary') {\n return (\n <TableCell key={spec.id} className={cellClass}>\n {hasText(row.description)\n ? (\n <>\n <span className=\"inline-block size-2 rounded-full bg-primary\" aria-hidden=\"true\" title={row.description} />\n <span className=\"sr-only\">{t('composites.table.summaryPresent')}</span>\n </>\n )\n : (\n <>\n <span className=\"text-muted-foreground/70\" aria-hidden=\"true\">–</span>\n <span className=\"sr-only\">{t('composites.summary.none')}</span>\n </>\n )}\n </TableCell>\n )\n }\n const column = fieldColumns.find(item => item.id === spec.id)\n if (!column) return <TableCell key={spec.id} className={cellClass} />\n const text = fieldText(row, column.field.key, fieldContext)\n return (\n <TableCell key={spec.id} className={cellClass}>\n {text\n ? (\n <span\n className={cn('block', (column.field.type === 'number' || column.field.type === 'date') && 'tabular-nums', isLongText(column.field) && 'max-w-64 truncate')}\n title={isLongText(column.field) ? text : undefined}\n >\n {text}\n </span>\n )\n : (\n <>\n <span className=\"text-muted-foreground/70\" aria-hidden=\"true\">–</span>\n <span className=\"sr-only\">{t('composites.table.noValue')}</span>\n </>\n )}\n </TableCell>\n )\n })}\n </TableRow>\n ))}\n </TableBody>\n </table>\n </div>\n </>\n )}\n </section>\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CompositeTable.js","names":[],"sources":["../../../../src/features/composites/react/CompositeTable.tsx"],"sourcesContent":["import type { Editor } from '@tiptap/core'\nimport { useMemo, useState } from 'react'\nimport { Icon } from '../../../react/Icon'\nimport { Badge } from '../../../react/ui/badge'\nimport { Button } from '../../../react/ui/button'\nimport { Input } from '../../../react/ui/input'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../../../react/ui/select'\nimport { TableBody, TableCell, TableHead, TableHeader, TableRow } from '../../../react/ui/table'\nimport { cn } from '../../../react/ui/utils'\nimport { useEditorI18n } from '../../../react/use-editor-i18n'\nimport { blockTypesOf } from '../nodes'\nimport type { CompositeRow } from '../rows'\nimport { columnSpecsOf, type FieldContext, FILTER_ALL, fieldColumnsOf, fieldOf, fieldText, hasText, isLongText, sortRows, toggled } from '../table-model'\nimport { useCompositeRows } from './use-composite-rows'\n\n// All Typed blocks of an editor's document as a sortable, filterable table. Columns beyond the fixed ones derive from the\n// meta fields of the kinds present in the document, so a host kind with fields gets its columns without code changes.\n// The column specs, cell text and sorting are the framework-free `table-model`, shared with the Vue table.\n\n/** The table of an editor's Typed blocks: sortable columns, filters by Block type, tag and select fields, a text search; `onSelect` receives the clicked row. */\nexport function CompositeTable({ editor, onSelect, className }: {\n editor?: Editor\n onSelect?: (row: CompositeRow) => void\n className?: string\n}) {\n const { rows, tags, kinds } = useCompositeRows(editor)\n\n const { t } = useEditorI18n()\n // `reference` cells resolve their target in the document; re-read whenever the rows change.\n const fieldContext = useMemo<FieldContext | undefined>(() => (editor ? { doc: editor.state.doc, kinds: blockTypesOf(editor), t } : undefined), [editor, rows, t])\n const fieldColumns = useMemo(() => fieldColumnsOf(rows, kinds, fieldContext), [rows, kinds, fieldContext])\n const specs = useMemo(() => columnSpecsOf(fieldColumns, t), [fieldColumns, t])\n\n const [search, setSearch] = useState('')\n const [pickedKinds, setPickedKinds] = useState<string[]>([])\n const [pickedTags, setPickedTags] = useState<string[]>([])\n const [pickedOptions, setPickedOptions] = useState<Record<string, string>>({})\n\n /** One select per `select` field in use; its choices are the union of the options of all kinds that have the key. */\n const selectFilters = useMemo(() => fieldColumns.flatMap((column) => {\n if (column.field.type !== 'select') return []\n const options = new Map<string, string>()\n for (const row of rows) {\n for (const option of fieldOf(row, column.field.key)?.options ?? []) if (!options.has(option.value)) options.set(option.value, option.label)\n }\n return [{\n key: column.field.key,\n label: column.field.label,\n items: [{ label: t('composites.table.filter.all'), value: FILTER_ALL }, ...[...options].map(([value, label]) => ({ label, value }))],\n }]\n }), [fieldColumns, rows, t])\n\n // A kind, tag or option that vanished from the document can no longer be unpicked in the UI, so it must not filter either.\n const activeKinds = useMemo(() => pickedKinds.filter(id => kinds.some(kind => kind.id === id)), [pickedKinds, kinds])\n const activeTags = useMemo(() => pickedTags.filter(tag => tags.includes(tag)), [pickedTags, tags])\n const activeOptions = useMemo(() => selectFilters.flatMap((filter) => {\n const value = pickedOptions[filter.key]\n return value && filter.items.some(item => item.value === value && value !== FILTER_ALL) ? [[filter.key, value] as const] : []\n }), [selectFilters, pickedOptions])\n const needle = search.trim().toLowerCase()\n const filterActive = activeKinds.length > 0 || activeTags.length > 0 || activeOptions.length > 0 || needle !== ''\n\n function resetFilters() {\n setSearch('')\n setPickedKinds([])\n setPickedTags([])\n setPickedOptions({})\n }\n\n const filtered = useMemo(() => rows.filter((row) => {\n if (activeKinds.length && !activeKinds.includes(row.kind)) return false\n if (activeTags.length && !activeTags.every(tag => row.tags.includes(tag))) return false\n if (activeOptions.some(([key, value]) => row.meta[key] !== value)) return false\n if (needle) {\n const haystack = `${row.title}\\n${row.description}\\n${row.tags.map(tag => `#${tag}`).join(' ')}`.toLowerCase()\n if (!haystack.includes(needle)) return false\n }\n return true\n }), [rows, activeKinds, activeTags, activeOptions, needle])\n\n // --- Sorting (client side, over the filtered rows) ---\n\n const [sorting, setSorting] = useState<{ id: string, desc: boolean } | null>(null)\n const activeSort = useMemo(() => {\n const spec = sorting && specs.find(item => item.id === sorting.id)\n return sorting && spec ? { id: sorting.id, desc: sorting.desc, sort: spec.sort } : null\n }, [sorting, specs])\n\n /** Header click cycles ascending → descending → unsorted. */\n function cycleSort(id: string) {\n setSorting(current => current?.id !== id ? { id, desc: false } : current.desc ? null : { id, desc: true })\n }\n const sortIcon = (id: string) => {\n if (sorting?.id !== id) return 'i-lucide-chevrons-up-down'\n return sorting.desc ? 'i-lucide-arrow-down' : 'i-lucide-arrow-up'\n }\n\n const sorted = useMemo(() => activeSort ? sortRows(filtered, activeSort.sort, activeSort.desc) : filtered, [filtered, activeSort])\n\n const countLabel = t(rows.length === 1 ? 'composites.table.count.one' : 'composites.table.count.other', { n: sorted.length, total: rows.length })\n const columnCount = specs.length\n\n return (\n <section className={cn('flex min-h-0 flex-col gap-3', className)} aria-label={t('composites.table.label')}>\n {!rows.length\n ? (\n <div className=\"mx-auto flex max-w-sm flex-1 flex-col items-center justify-center gap-2 py-16 text-center\">\n <Icon name=\"i-lucide-table-2\" className=\"size-8 text-muted-foreground/70\" />\n <p className=\"text-sm font-medium text-foreground\">\n {t('composites.table.emptyTitle')}\n </p>\n <p className=\"text-sm text-muted-foreground\">\n {t('composites.table.emptyText')}\n </p>\n </div>\n )\n : (\n <>\n <div className=\"flex flex-col gap-2\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <div className=\"relative w-64\">\n <Icon name=\"i-lucide-search\" className=\"pointer-events-none absolute top-1/2 left-2.5 size-4 -translate-y-1/2 text-muted-foreground\" />\n <Input\n value={search}\n onChange={event => setSearch(event.target.value)}\n className={cn('h-7 pl-8 text-sm', search && 'pr-8')}\n placeholder={t('composites.table.search.placeholder')}\n aria-label={t('composites.table.search.label')}\n />\n {search && (\n <Button\n variant=\"ghost\"\n size=\"icon-xs\"\n className=\"absolute top-1/2 right-1 -translate-y-1/2\"\n aria-label={t('composites.table.search.clear')}\n onClick={() => setSearch('')}\n >\n <Icon name=\"i-lucide-x\" />\n </Button>\n )}\n </div>\n\n {selectFilters.map(filter => (\n <div key={filter.key} className=\"flex items-center gap-1.5\">\n <span className=\"text-sm text-muted-foreground\" aria-hidden=\"true\">{filter.label}</span>\n <Select\n value={pickedOptions[filter.key] ?? FILTER_ALL}\n onValueChange={value => setPickedOptions({ ...pickedOptions, [filter.key]: String(value) })}\n >\n <SelectTrigger size=\"sm\" className=\"w-36\" aria-label={filter.label}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {filter.items.map(item => <SelectItem key={item.value} value={item.value}>{item.label}</SelectItem>)}\n </SelectContent>\n </Select>\n </div>\n ))}\n\n {filterActive && (\n <Button size=\"sm\" variant=\"ghost\" onClick={resetFilters}>\n <Icon name=\"i-lucide-filter-x\" />\n {t('composites.table.filter.reset')}\n </Button>\n )}\n <span className=\"ml-auto text-xs text-muted-foreground tabular-nums\" role=\"status\">{countLabel}</span>\n </div>\n\n {kinds.length > 1 && (\n <div className=\"flex flex-wrap items-center gap-1\" role=\"group\" aria-label={t('composites.table.filter.byKind')}>\n {kinds.map(kind => (\n <Button\n key={kind.id}\n size=\"xs\"\n variant={activeKinds.includes(kind.id) ? 'default' : 'outline'}\n aria-pressed={activeKinds.includes(kind.id)}\n onClick={() => setPickedKinds(toggled(pickedKinds, kind.id))}\n >\n <Icon name={kind.icon} />\n {kind.label}\n </Button>\n ))}\n </div>\n )}\n\n {tags.length > 0 && (\n <div className=\"flex flex-wrap items-center gap-1\" role=\"group\" aria-label={t('composites.table.filter.byTag')}>\n {tags.map(tag => (\n <Button\n key={tag}\n size=\"xs\"\n variant={activeTags.includes(tag) ? 'default' : 'outline'}\n aria-pressed={activeTags.includes(tag)}\n onClick={() => setPickedTags(toggled(pickedTags, tag))}\n >\n {`#${tag}`}\n </Button>\n ))}\n </div>\n )}\n </div>\n\n {/* Own scroll container instead of `<Table>`'s: the sticky header needs the element that scrolls vertically. */}\n <div className=\"min-h-0 flex-1 overflow-auto rounded-md border border-border\">\n <table data-slot=\"table\" className=\"w-full caption-bottom text-sm\">\n <TableHeader className=\"sticky top-0 z-10 bg-background\">\n <TableRow className=\"hover:bg-transparent\">\n {specs.map(spec => (\n <TableHead\n key={spec.id}\n className={cn('h-auto px-3 py-2 text-sm', spec.id === 'title' && 'min-w-56', spec.align === 'end' && 'text-right')}\n aria-sort={activeSort?.id === spec.id ? (activeSort.desc ? 'descending' : 'ascending') : 'none'}\n >\n <button\n type=\"button\"\n className=\"-mx-1.5 inline-flex cursor-pointer items-center gap-1 rounded px-1.5 py-0.5 font-semibold hover:bg-muted focus-visible:outline-2 focus-visible:outline-primary\"\n onClick={() => cycleSort(spec.id)}\n >\n {spec.label}\n <Icon name={sortIcon(spec.id)} className={cn('size-3.5', activeSort?.id === spec.id ? 'text-foreground' : 'text-muted-foreground/70')} />\n </button>\n </TableHead>\n ))}\n </TableRow>\n </TableHeader>\n <TableBody>\n {sorted.length === 0\n ? (\n <TableRow className=\"hover:bg-transparent\">\n <TableCell colSpan={columnCount} className=\"px-3 py-2 text-muted-foreground\">\n <div className=\"flex flex-col items-center gap-2 py-6\">\n <p className=\"text-sm text-muted-foreground\">\n {t('composites.table.filter.noMatch')}\n </p>\n <Button size=\"sm\" variant=\"outline\" onClick={resetFilters}>\n <Icon name=\"i-lucide-filter-x\" />\n {t('composites.table.filter.reset')}\n </Button>\n </div>\n </TableCell>\n </TableRow>\n )\n : sorted.map(row => (\n <TableRow key={row.key} className=\"cursor-pointer\" onClick={() => onSelect?.(row)}>\n {specs.map((spec) => {\n const cellClass = cn('px-3 py-2 text-muted-foreground', spec.align === 'end' && 'text-right')\n if (spec.id === 'title') {\n return (\n <TableCell key={spec.id} className={cellClass}>\n <div className=\"flex min-w-0 items-center gap-1.5\" style={{ paddingLeft: `${row.depth * 1.25}rem` }}>\n <Icon name={row.icon} className=\"size-4 shrink-0 text-muted-foreground\" />\n {hasText(row.title)\n ? <span className=\"truncate font-medium text-foreground\">{row.title}</span>\n : <span className=\"truncate text-muted-foreground\">{t('composites.untitled')}</span>}\n </div>\n </TableCell>\n )\n }\n if (spec.id === 'kind') return <TableCell key={spec.id} className={cellClass}>{row.kindLabel}</TableCell>\n if (spec.id === 'tags') {\n return (\n <TableCell key={spec.id} className={cellClass}>\n {row.tags.length\n ? (\n <div className=\"flex flex-wrap gap-1\">\n {row.tags.map(tag => <Badge key={tag} variant=\"secondary\">{`#${tag}`}</Badge>)}\n </div>\n )\n : (\n <>\n <span className=\"text-muted-foreground/70\" aria-hidden=\"true\">–</span>\n <span className=\"sr-only\">{t('composites.table.noTags')}</span>\n </>\n )}\n </TableCell>\n )\n }\n if (spec.id === 'summary') {\n return (\n <TableCell key={spec.id} className={cellClass}>\n {hasText(row.description)\n ? (\n <>\n <span className=\"inline-block size-2 rounded-full bg-primary\" aria-hidden=\"true\" title={row.description} />\n <span className=\"sr-only\">{t('composites.table.summaryPresent')}</span>\n </>\n )\n : (\n <>\n <span className=\"text-muted-foreground/70\" aria-hidden=\"true\">–</span>\n <span className=\"sr-only\">{t('composites.summary.none')}</span>\n </>\n )}\n </TableCell>\n )\n }\n const column = fieldColumns.find(item => item.id === spec.id)\n if (!column) return <TableCell key={spec.id} className={cellClass} />\n const text = fieldText(row, column.field.key, fieldContext)\n return (\n <TableCell key={spec.id} className={cellClass}>\n {text\n ? (\n <span\n className={cn('block', (column.field.type === 'number' || column.field.type === 'date') && 'tabular-nums', isLongText(column.field) && 'max-w-64 truncate')}\n title={isLongText(column.field) ? text : undefined}\n >\n {text}\n </span>\n )\n : (\n <>\n <span className=\"text-muted-foreground/70\" aria-hidden=\"true\">–</span>\n <span className=\"sr-only\">{t('composites.table.noValue')}</span>\n </>\n )}\n </TableCell>\n )\n })}\n </TableRow>\n ))}\n </TableBody>\n </table>\n </div>\n </>\n )}\n </section>\n )\n}\n"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { CompositeRow } from "../rows.js";
|
|
2
2
|
import { Editor } from "@tiptap/core";
|
|
3
3
|
//#region src/features/composites/react/CompositeTagsEditor.d.ts
|
|
4
|
-
/** Tags of one
|
|
4
|
+
/** Tags of one Typed block as an input menu with suggestions from the metadata registry, writing through `setCompositeTags`. */
|
|
5
5
|
export declare function CompositeTagsEditor({ editor, row }: {
|
|
6
6
|
editor: Editor;
|
|
7
7
|
row: CompositeRow;
|
|
@@ -10,7 +10,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
10
10
|
//#region src/features/composites/react/CompositeTagsEditor.tsx
|
|
11
11
|
/** Value of the „erstellen“ row of the list; suggestions use `tag:<name>`. */
|
|
12
12
|
const CREATE = "__create__";
|
|
13
|
-
/** Tags of one
|
|
13
|
+
/** Tags of one Typed block as an input menu with suggestions from the metadata registry, writing through `setCompositeTags`. */
|
|
14
14
|
function CompositeTagsEditor({ editor, row }) {
|
|
15
15
|
const { t } = useEditorI18n();
|
|
16
16
|
const [term, setTerm] = useState("");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CompositeTagsEditor.js","names":[],"sources":["../../../../src/features/composites/react/CompositeTagsEditor.tsx"],"sourcesContent":["import type { Editor } from '@tiptap/core'\nimport { useEffect, useRef, useState } from 'react'\nimport { METADATA_LIST, metadataOf } from '../../../core'\nimport { normalizeTagName } from '../../../core/tag-name'\nimport { Icon } from '../../../react/Icon'\nimport { Command, CommandInput, CommandItem, CommandList } from '../../../react/ui/command'\nimport { useEditorI18n } from '../../../react/use-editor-i18n'\nimport { type CompositeRow, setCompositeTags } from '../rows'\n\n/** Value of the „erstellen“ row of the list; suggestions use `tag:<name>`. */\nconst CREATE = '__create__'\n\n/** Tags of one
|
|
1
|
+
{"version":3,"file":"CompositeTagsEditor.js","names":[],"sources":["../../../../src/features/composites/react/CompositeTagsEditor.tsx"],"sourcesContent":["import type { Editor } from '@tiptap/core'\nimport { useEffect, useRef, useState } from 'react'\nimport { METADATA_LIST, metadataOf } from '../../../core'\nimport { normalizeTagName } from '../../../core/tag-name'\nimport { Icon } from '../../../react/Icon'\nimport { Command, CommandInput, CommandItem, CommandList } from '../../../react/ui/command'\nimport { useEditorI18n } from '../../../react/use-editor-i18n'\nimport { type CompositeRow, setCompositeTags } from '../rows'\n\n/** Value of the „erstellen“ row of the list; suggestions use `tag:<name>`. */\nconst CREATE = '__create__'\n\n/** Tags of one Typed block as an input menu with suggestions from the metadata registry, writing through `setCompositeTags`. */\nexport function CompositeTagsEditor({ editor, row }: { editor: Editor, row: CompositeRow }) {\n const { t } = useEditorI18n()\n const [term, setTerm] = useState('')\n const [items, setItems] = useState<string[]>([])\n // Set once the arrow keys moved the highlight into the list: until then Enter creates the typed tag.\n const navigated = useRef(false)\n\n // Suggestions are loaded when the list opens and 150 ms after typing pauses; a newer search aborts the older one.\n useEffect(() => {\n const controller = new AbortController()\n const timer = window.setTimeout(async () => {\n try {\n const found = await metadataOf(editor).search(METADATA_LIST.hashtags, { query: term, editor, signal: controller.signal })\n if (!controller.signal.aborted) setItems(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 return () => {\n window.clearTimeout(timer)\n controller.abort()\n }\n }, [editor, term])\n\n function onTerm(value: string) {\n setTerm(value)\n navigated.current = false\n }\n\n // Picking a suggestion toggles it: set tags are removed again.\n function toggle(tag: string) {\n setCompositeTags(editor, row, row.tags.includes(tag) ? row.tags.filter(candidate => candidate !== tag) : [...row.tags, tag])\n }\n\n function remove(tag: string) {\n setCompositeTags(editor, row, row.tags.filter(candidate => candidate !== tag))\n }\n\n // „Neu Tag“ → `neu-tag`; a name that is already set is ignored.\n function onCreate(raw: string) {\n const name = normalizeTagName(raw)\n onTerm('')\n if (!name || row.tags.includes(name)) return\n setCompositeTags(editor, row, [...row.tags, name])\n if (!items.includes(name)) metadataOf(editor).create(METADATA_LIST.hashtags, { id: name, label: name })\n }\n\n const query = term.trim()\n\n return (\n <div className=\"flex w-full flex-col gap-1.5\">\n {row.tags.length > 0 && (\n <ul className=\"flex flex-wrap gap-1\" aria-label={t('composites.tags.label')}>\n {row.tags.map(tag => (\n <li key={tag} className=\"inline-flex h-5 max-w-full items-center gap-0.5 rounded-sm bg-muted px-1.5 text-xs leading-none text-foreground\">\n <span className=\"truncate\">{tag}</span>\n <button\n type=\"button\"\n className=\"flex size-4 shrink-0 items-center justify-center rounded-sm text-muted-foreground transition-colors hover:bg-background hover:text-foreground focus-visible:outline-2 focus-visible:outline-primary\"\n aria-label={t('composites.tag.remove', { tag })}\n onClick={() => remove(tag)}\n >\n <Icon name=\"i-lucide-x\" className=\"size-3\" />\n </button>\n </li>\n ))}\n </ul>\n )}\n <Command shouldFilter={false} className=\"h-auto overflow-visible bg-transparent p-0\">\n <CommandInput\n value={term}\n onValueChange={onTerm}\n placeholder={t('composites.tags.placeholder')}\n aria-label={t('composites.tags.label')}\n onKeyDown={(event) => {\n if (event.nativeEvent.isComposing) return\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') navigated.current = true\n else if (event.key === 'Enter' && query && !navigated.current) {\n // The list highlights its first suggestion; typed text is created instead, unless the user moved in the list.\n event.preventDefault()\n onCreate(term)\n }\n // Backspace in the empty field removes the last tag.\n if (event.key === 'Backspace' && !term && row.tags.length > 0) {\n setCompositeTags(editor, row, row.tags.slice(0, -1))\n }\n }}\n />\n <CommandList>\n {items.map(tag => (\n <CommandItem\n key={tag}\n value={`tag:${tag}`}\n data-checked={row.tags.includes(tag)}\n onSelect={() => toggle(tag)}\n >\n <Icon name=\"i-lucide-hash\" className=\"size-3.5 text-muted-foreground\" />\n <span className=\"truncate\">{tag}</span>\n </CommandItem>\n ))}\n {query && (\n <CommandItem value={CREATE} onSelect={() => onCreate(term)}>\n <Icon name=\"i-lucide-plus\" className=\"size-3.5 text-muted-foreground\" />\n {t('composites.tags.create', { tag: normalizeTagName(term) || term })}\n </CommandItem>\n )}\n </CommandList>\n </Command>\n </div>\n )\n}\n"],"mappings":"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"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { derivationOf } from "
|
|
4
|
-
import {
|
|
1
|
+
import { capabilityDataOf } from "../../../core/capabilities.js";
|
|
2
|
+
import { TYPED_BLOCK_CLASS } from "../../../core/schema/persisted-names.js";
|
|
3
|
+
import { derivationOf } from "../../../core/derivation.js";
|
|
4
|
+
import { blockTypeOf } from "../block-types.js";
|
|
5
|
+
import { titleHiddenOf } from "../baskets.js";
|
|
6
|
+
import { blockTypesOf, compositeBasketsOf } from "../nodes.js";
|
|
5
7
|
import { cn } from "../../../react/ui/utils.js";
|
|
6
8
|
import { useStore } from "../../../react/use-store.js";
|
|
7
9
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -11,28 +13,28 @@ import { NodeViewContent, NodeViewWrapper } from "@tiptap/react";
|
|
|
11
13
|
const cssString = (text) => `"${text.replace(/["\\]/g, "\\$&").replace(/\n/g, "\\a ")}"`;
|
|
12
14
|
/** The composite block: the section with its content. The kind icon is drawn by the composite chrome overlay. */
|
|
13
15
|
function CompositeView({ editor, node, selected }) {
|
|
14
|
-
const kind =
|
|
15
|
-
const expanded = useStore(editor.storage.
|
|
16
|
+
const kind = blockTypeOf(blockTypesOf(editor), String(node.attrs.blockType));
|
|
17
|
+
const expanded = useStore(editor.storage.typedBlock.expanded);
|
|
16
18
|
const id = node.attrs.id;
|
|
17
19
|
const collapsed = typeof id === "string" && id !== "" && derivationOf(node) !== null && !expanded.has(id);
|
|
18
|
-
const basket =
|
|
20
|
+
const basket = capabilityDataOf(editor, node, "basket");
|
|
19
21
|
const basketColor = compositeBasketsOf(editor).find((candidate) => candidate.id === basket)?.color;
|
|
20
|
-
const
|
|
21
|
-
const revealedTitles = useStore(editor.storage.
|
|
22
|
+
const blockTypeTone = kind.chrome?.tone || void 0;
|
|
23
|
+
const revealedTitles = useStore(editor.storage.typedBlock.revealedTitles);
|
|
22
24
|
const titleHidden = titleHiddenOf(node) && !(typeof id === "string" && revealedTitles.has(id));
|
|
23
25
|
const placeholderVars = {
|
|
24
|
-
"--composite-title-placeholder": cssString(kind.titlePlaceholder),
|
|
26
|
+
"--composite-title-placeholder": cssString(kind.titlePlaceholder ?? ""),
|
|
25
27
|
...basketColor ? { "--sk-basket-color": basketColor } : {},
|
|
26
|
-
...
|
|
28
|
+
...blockTypeTone ? { "--sk-block-type-tone": blockTypeTone } : {}
|
|
27
29
|
};
|
|
28
30
|
return /* @__PURE__ */ jsxs(NodeViewWrapper, {
|
|
29
31
|
as: "section",
|
|
30
|
-
className: cn(
|
|
31
|
-
"data-type": "
|
|
32
|
-
"data-
|
|
32
|
+
className: cn(TYPED_BLOCK_CLASS, collapsed && "is-collapsed", selected && "is-selected rounded-md ring-1 ring-primary"),
|
|
33
|
+
"data-type": "typedBlock",
|
|
34
|
+
"data-block-type": node.attrs.blockType,
|
|
33
35
|
"data-id": node.attrs.id || void 0,
|
|
34
36
|
"data-basket": basket ?? void 0,
|
|
35
|
-
"data-
|
|
37
|
+
"data-block-type-tone": blockTypeTone ? "" : void 0,
|
|
36
38
|
"data-title-hidden": titleHidden ? "" : void 0,
|
|
37
39
|
style: placeholderVars,
|
|
38
40
|
children: [/* @__PURE__ */ jsx("span", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CompositeView.js","names":[],"sources":["../../../../src/features/composites/react/CompositeView.tsx"],"sourcesContent":["import { NodeViewContent, NodeViewWrapper, type NodeViewProps } from '@tiptap/react'\nimport type { CSSProperties } from 'react'\nimport { cn } from '../../../react/ui/utils'\nimport {
|
|
1
|
+
{"version":3,"file":"CompositeView.js","names":[],"sources":["../../../../src/features/composites/react/CompositeView.tsx"],"sourcesContent":["import { NodeViewContent, NodeViewWrapper, type NodeViewProps } from '@tiptap/react'\nimport type { CSSProperties } from 'react'\nimport { cn } from '../../../react/ui/utils'\nimport { capabilityDataOf } from '../../../core/capabilities'\nimport { titleHiddenOf } from '../baskets'\nimport { blockTypeOf } from '../block-types'\nimport { useStore } from '../../../react/use-store'\nimport { TYPED_BLOCK_CLASS } from '../../../core/schema/persisted-names'\nimport { derivationOf } from '../../../core/derivation'\nimport { compositeBasketsOf, blockTypesOf } from '../nodes'\n\n/** `text` as a CSS string literal (for `content:`). */\nconst cssString = (text: string) => `\"${text.replace(/[\"\\\\]/g, '\\\\$&').replace(/\\n/g, '\\\\a ')}\"`\n\n/** The composite block: the section with its content. The kind icon is drawn by the composite chrome overlay. */\nexport function CompositeView({ editor, node, selected }: NodeViewProps) {\n const kind = blockTypeOf(blockTypesOf(editor), String(node.attrs.blockType))\n // A derived Typed block (one with a `meta.derivation`) shows collapsed to a faded preview until it is opened; the content\n // stays laid out (CSS clips it), so editing positions are unaffected. The chrome's chevron and a caret inside open it.\n const expanded = useStore(editor.storage.typedBlock.expanded)\n const id: unknown = node.attrs.id\n const collapsed = typeof id === 'string' && id !== '' && derivationOf(node) !== null && !expanded.has(id)\n // Colour basket (`meta.basket`): `data-basket` carries the id, the stripe takes the basket's colour from `--sk-basket-color`.\n const basket = capabilityDataOf<string>(editor, node, 'basket')\n const basketColor = compositeBasketsOf(editor).find(candidate => candidate.id === basket)?.color\n // Block type tone (`BlockType.chrome.tone`): `data-block-type-tone` marks the wrapper, the surface reads the colour from `--sk-block-type-tone`.\n const blockTypeTone = kind.chrome?.tone || undefined\n // A hidden title (`meta.titleHidden`) stays hidden until a caret enters it (`revealedTitles`, see `CompositeNode`).\n const revealedTitles = useStore(editor.storage.typedBlock.revealedTitles)\n const titleHidden = titleHiddenOf(node) && !(typeof id === 'string' && revealedTitles.has(id))\n // Placeholder of the empty title (composites.css `content: var(…)`); a nested composite sets its own.\n const placeholderVars = {\n '--composite-title-placeholder': cssString(kind.titlePlaceholder ?? ''),\n ...(basketColor ? { '--sk-basket-color': basketColor } : {}),\n ...(blockTypeTone ? { '--sk-block-type-tone': blockTypeTone } : {}),\n } as CSSProperties\n return (\n <NodeViewWrapper\n as=\"section\"\n className={cn(TYPED_BLOCK_CLASS, collapsed && 'is-collapsed', selected && 'is-selected rounded-md ring-1 ring-primary')}\n data-type=\"typedBlock\"\n data-block-type={node.attrs.blockType}\n data-id={node.attrs.id || undefined}\n data-basket={basket ?? undefined}\n data-block-type-tone={blockTypeTone ? '' : undefined}\n data-title-hidden={titleHidden ? '' : undefined}\n style={placeholderVars}\n >\n {/* Anchor of the kind icon on the left border: it only takes the icon's place and size. The composite chrome overlay\n measures it and draws the icon as the button that opens the details popover and drags the composite. */}\n <span className=\"composite__toggle\" contentEditable={false} aria-hidden=\"true\" />\n <NodeViewContent className=\"composite__content\" />\n </NodeViewWrapper>\n )\n}\n"],"mappings":";;;;;;;;;;;;AAYA,MAAM,aAAa,SAAiB,IAAI,KAAK,QAAQ,UAAU,MAAM,CAAC,CAAC,QAAQ,OAAO,MAAM,EAAE;;AAG9F,SAAgB,cAAc,EAAE,QAAQ,MAAM,YAA2B;CACvE,MAAM,OAAO,YAAY,aAAa,MAAM,GAAG,OAAO,KAAK,MAAM,SAAS,CAAC;CAG3E,MAAM,WAAW,SAAS,OAAO,QAAQ,WAAW,QAAQ;CAC5D,MAAM,KAAc,KAAK,MAAM;CAC/B,MAAM,YAAY,OAAO,OAAO,YAAY,OAAO,MAAM,aAAa,IAAI,MAAM,QAAQ,CAAC,SAAS,IAAI,EAAE;CAExG,MAAM,SAAS,iBAAyB,QAAQ,MAAM,QAAQ;CAC9D,MAAM,cAAc,mBAAmB,MAAM,CAAC,CAAC,MAAK,cAAa,UAAU,OAAO,MAAM,CAAC,EAAE;CAE3F,MAAM,gBAAgB,KAAK,QAAQ,QAAQ,KAAA;CAE3C,MAAM,iBAAiB,SAAS,OAAO,QAAQ,WAAW,cAAc;CACxE,MAAM,cAAc,cAAc,IAAI,KAAK,EAAE,OAAO,OAAO,YAAY,eAAe,IAAI,EAAE;CAE5F,MAAM,kBAAkB;EACtB,iCAAiC,UAAU,KAAK,oBAAoB,EAAE;EACtE,GAAI,cAAc,EAAE,qBAAqB,YAAY,IAAI,CAAC;EAC1D,GAAI,gBAAgB,EAAE,wBAAwB,cAAc,IAAI,CAAC;CACnE;CACA,OACE,qBAAC,iBAAD;EACE,IAAG;EACH,WAAW,GAAG,mBAAmB,aAAa,gBAAgB,YAAY,4CAA4C;EACtH,aAAU;EACV,mBAAiB,KAAK,MAAM;EAC5B,WAAS,KAAK,MAAM,MAAM,KAAA;EAC1B,eAAa,UAAU,KAAA;EACvB,wBAAsB,gBAAgB,KAAK,KAAA;EAC3C,qBAAmB,cAAc,KAAK,KAAA;EACtC,OAAO;EATT,UAAA,CAaE,oBAAC,QAAD;GAAM,WAAU;GAAoB,iBAAiB;GAAO,eAAY;EAAQ,CAAA,GAChF,oBAAC,iBAAD,EAAiB,WAAU,qBAAsB,CAAA,CAClC;;AAErB"}
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import { derivationOf } from "
|
|
1
|
+
import { derivationOf } from "../../../core/derivation.js";
|
|
2
2
|
import { useEditorI18n } from "../../../react/use-editor-i18n.js";
|
|
3
3
|
import { cn } from "../../../react/ui/utils.js";
|
|
4
4
|
import { Icon } from "../../../react/Icon.js";
|
|
5
|
-
import { derivationDetailsOf, derivationIsForeign, derivationMethodLabel } from "../derived-chrome.js";
|
|
5
|
+
import { derivationDetailsOf, derivationIsForeign, derivationMethodLabel, isSourceMissing } from "../derived-chrome.js";
|
|
6
6
|
import { formatDate } from "../meta-display.js";
|
|
7
7
|
import { useMemo } from "react";
|
|
8
8
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
9
9
|
//#region src/features/composites/react/DerivationBadge.tsx
|
|
10
10
|
const CHIP = "inline-flex h-5 shrink-0 items-center gap-1 rounded-sm px-1.5 text-xs leading-none whitespace-nowrap";
|
|
11
11
|
/**
|
|
12
|
-
* Where a derived
|
|
12
|
+
* Where a derived Typed block comes from. Compact (the `derivation` field type): the „abgeleitet“ badge with method and
|
|
13
13
|
* date. `detailed` (the details card): also the model, whether the source changed („Quelle geändert“), whether the body
|
|
14
14
|
* was edited since it was generated („bearbeitet“) and a link to the stored raw output. The detailed variant hashes
|
|
15
|
-
* the body, so it belongs only where one
|
|
15
|
+
* the body, so it belongs only where one Typed block is shown.
|
|
16
16
|
*/
|
|
17
17
|
function DerivationBadge({ editor, node, detailed }) {
|
|
18
18
|
const { t } = useEditorI18n();
|
|
@@ -25,6 +25,7 @@ function DerivationBadge({ editor, node, detailed }) {
|
|
|
25
25
|
if (!derivation) return null;
|
|
26
26
|
const method = derivationMethodLabel(t, derivation.method);
|
|
27
27
|
const foreign = derivationIsForeign(editor, derivation);
|
|
28
|
+
const sourceMissing = isSourceMissing(editor, node);
|
|
28
29
|
const created = derivation.createdAt ? formatDate(derivation.createdAt) : "";
|
|
29
30
|
if (!detailed) return /* @__PURE__ */ jsxs("div", {
|
|
30
31
|
className: "flex min-w-0 items-center gap-1.5 text-xs text-muted-foreground",
|
|
@@ -37,6 +38,7 @@ function DerivationBadge({ editor, node, detailed }) {
|
|
|
37
38
|
t("composites.derivation.badge"),
|
|
38
39
|
method,
|
|
39
40
|
foreign ? t("composites.derivation.foreign") : "",
|
|
41
|
+
sourceMissing ? t("composites.derivation.sourceMissing") : "",
|
|
40
42
|
created
|
|
41
43
|
].filter(Boolean).join(" · ")
|
|
42
44
|
})]
|
|
@@ -62,6 +64,13 @@ function DerivationBadge({ editor, node, detailed }) {
|
|
|
62
64
|
className: "size-3.5"
|
|
63
65
|
}), t("composites.derivation.foreign")]
|
|
64
66
|
}),
|
|
67
|
+
details.sourceMissing && /* @__PURE__ */ jsxs("span", {
|
|
68
|
+
className: cn(CHIP, "text-(--sk-warning)"),
|
|
69
|
+
children: [/* @__PURE__ */ jsx(Icon, {
|
|
70
|
+
name: "i-lucide-unlink",
|
|
71
|
+
className: "size-3.5"
|
|
72
|
+
}), t("composites.derivation.sourceMissing")]
|
|
73
|
+
}),
|
|
65
74
|
details.stale && /* @__PURE__ */ jsxs("span", {
|
|
66
75
|
className: cn(CHIP, "text-(--sk-warning)"),
|
|
67
76
|
children: [/* @__PURE__ */ jsx(Icon, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DerivationBadge.js","names":[],"sources":["../../../../src/features/composites/react/DerivationBadge.tsx"],"sourcesContent":["import type { Editor } from '@tiptap/core'\nimport type { Node as ProseMirrorNode } from '@tiptap/pm/model'\nimport { useMemo } from 'react'\nimport { Icon } from '../../../react/Icon'\nimport { cn } from '../../../react/ui/utils'\nimport { useEditorI18n } from '../../../react/use-editor-i18n'\nimport { derivationOf } from '
|
|
1
|
+
{"version":3,"file":"DerivationBadge.js","names":[],"sources":["../../../../src/features/composites/react/DerivationBadge.tsx"],"sourcesContent":["import type { Editor } from '@tiptap/core'\nimport type { Node as ProseMirrorNode } from '@tiptap/pm/model'\nimport { useMemo } from 'react'\nimport { Icon } from '../../../react/Icon'\nimport { cn } from '../../../react/ui/utils'\nimport { useEditorI18n } from '../../../react/use-editor-i18n'\nimport { derivationOf } from '../../../core/derivation'\nimport { derivationDetailsOf, derivationIsForeign, derivationMethodLabel, isSourceMissing } from '../derived-chrome'\nimport { formatDate } from '../meta-display'\n\nconst CHIP = 'inline-flex h-5 shrink-0 items-center gap-1 rounded-sm px-1.5 text-xs leading-none whitespace-nowrap'\n\n/**\n * Where a derived Typed block comes from. Compact (the `derivation` field type): the „abgeleitet“ badge with method and\n * date. `detailed` (the details card): also the model, whether the source changed („Quelle geändert“), whether the body\n * was edited since it was generated („bearbeitet“) and a link to the stored raw output. The detailed variant hashes\n * the body, so it belongs only where one Typed block is shown.\n */\nexport function DerivationBadge({ editor, node, detailed }: { editor: Editor, node: ProseMirrorNode, detailed?: boolean }) {\n const { t } = useEditorI18n()\n const derivation = derivationOf(node)\n const details = useMemo(() => detailed ? derivationDetailsOf(editor, node) : null, [detailed, editor, node])\n if (!derivation) return null\n const method = derivationMethodLabel(t, derivation.method)\n const foreign = derivationIsForeign(editor, derivation)\n const sourceMissing = isSourceMissing(editor, node)\n const created = derivation.createdAt ? formatDate(derivation.createdAt) : ''\n\n if (!detailed) {\n return (\n <div className=\"flex min-w-0 items-center gap-1.5 text-xs text-muted-foreground\">\n <Icon name=\"i-lucide-git-branch\" className=\"size-3.5 shrink-0\" />\n <span className=\"truncate\">{[t('composites.derivation.badge'), method, foreign ? t('composites.derivation.foreign') : '', sourceMissing ? t('composites.derivation.sourceMissing') : '', created].filter(Boolean).join(' · ')}</span>\n </div>\n )\n }\n if (!details) return null\n\n return (\n <div className=\"flex flex-col gap-1.5 rounded-md p-2 text-xs ring-1 ring-border\">\n <div className=\"flex flex-wrap items-center gap-1\">\n <span className={cn(CHIP, 'text-muted-foreground')}>\n <Icon name=\"i-lucide-git-branch\" className=\"size-3.5\" />{t('composites.derivation.badge')}\n </span>\n {details.foreign && (\n <span className={cn(CHIP, 'text-muted-foreground')}>\n <Icon name=\"i-lucide-file-symlink\" className=\"size-3.5\" />{t('composites.derivation.foreign')}\n </span>\n )}\n {details.sourceMissing && (\n <span className={cn(CHIP, 'text-(--sk-warning)')}>\n <Icon name=\"i-lucide-unlink\" className=\"size-3.5\" />{t('composites.derivation.sourceMissing')}\n </span>\n )}\n {details.stale && (\n <span className={cn(CHIP, 'text-(--sk-warning)')}>\n <Icon name=\"i-lucide-triangle-alert\" className=\"size-3.5\" />{t('composites.derivation.stale')}\n </span>\n )}\n {details.edited && (\n <span className={cn(CHIP, 'text-muted-foreground')}>\n <Icon name=\"i-lucide-pencil\" className=\"size-3.5\" />{t('composites.derivation.edited')}\n </span>\n )}\n </div>\n <dl className=\"grid grid-cols-[auto_1fr] gap-x-2 gap-y-0.5\">\n <dt className=\"text-muted-foreground\">{t('composites.derivation.method')}</dt>\n <dd className=\"truncate text-foreground\">{method}</dd>\n {derivation.model && (\n <>\n <dt className=\"text-muted-foreground\">{t('composites.derivation.model')}</dt>\n <dd className=\"truncate text-foreground\" title={derivation.model}>{derivation.model}</dd>\n </>\n )}\n {created && (\n <>\n <dt className=\"text-muted-foreground\">{t('composites.derivation.createdAt')}</dt>\n <dd className=\"text-foreground\">{created}</dd>\n </>\n )}\n </dl>\n {details.outputUrl && (\n <a href={details.outputUrl} target=\"_blank\" rel=\"noopener\" className=\"inline-flex w-fit items-center gap-1 text-primary hover:underline\">\n <Icon name=\"i-lucide-external-link\" className=\"size-3.5\" />{t('composites.derivation.openOutput')}\n </a>\n )}\n </div>\n )\n}\n"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Editor } from "@tiptap/core";
|
|
2
2
|
//#region src/features/composites/react/FocusChip.d.ts
|
|
3
3
|
/**
|
|
4
|
-
* Focus mode indicator (mounted by the composites feature): while a
|
|
4
|
+
* Focus mode indicator (mounted by the composites feature): while a Typed block is focused (`focusComposite`) a small chip
|
|
5
5
|
* fixed at the bottom of the surface names it and leaves focus mode.
|
|
6
6
|
*/
|
|
7
7
|
export declare function FocusChip({ editor }: {
|
|
@@ -7,7 +7,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
7
7
|
import { useEditorState } from "@tiptap/react";
|
|
8
8
|
//#region src/features/composites/react/FocusChip.tsx
|
|
9
9
|
/**
|
|
10
|
-
* Focus mode indicator (mounted by the composites feature): while a
|
|
10
|
+
* Focus mode indicator (mounted by the composites feature): while a Typed block is focused (`focusComposite`) a small chip
|
|
11
11
|
* fixed at the bottom of the surface names it and leaves focus mode.
|
|
12
12
|
*/
|
|
13
13
|
function FocusChip({ editor }) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FocusChip.js","names":[],"sources":["../../../../src/features/composites/react/FocusChip.tsx"],"sourcesContent":["import type { Editor } from '@tiptap/core'\nimport { useEditorState } from '@tiptap/react'\nimport { findBlockById } from '../../../core/schema'\nimport { Icon } from '../../../react/Icon'\nimport { Button } from '../../../react/ui/button'\nimport { useEditorI18n } from '../../../react/use-editor-i18n'\nimport { compositeFocusOf } from '../focus'\n\n/**\n * Focus mode indicator (mounted by the composites feature): while a
|
|
1
|
+
{"version":3,"file":"FocusChip.js","names":[],"sources":["../../../../src/features/composites/react/FocusChip.tsx"],"sourcesContent":["import type { Editor } from '@tiptap/core'\nimport { useEditorState } from '@tiptap/react'\nimport { findBlockById } from '../../../core/schema'\nimport { Icon } from '../../../react/Icon'\nimport { Button } from '../../../react/ui/button'\nimport { useEditorI18n } from '../../../react/use-editor-i18n'\nimport { compositeFocusOf } from '../focus'\n\n/**\n * Focus mode indicator (mounted by the composites feature): while a Typed block is focused (`focusComposite`) a small chip\n * fixed at the bottom of the surface names it and leaves focus mode.\n */\nexport function FocusChip({ editor }: { editor: Editor }) {\n const { t } = useEditorI18n()\n const title = useEditorState({\n editor,\n selector: ({ editor: current }) => {\n if (current.isDestroyed) return null\n const id = compositeFocusOf(current.state)\n const found = id ? findBlockById(current.state.doc, id) : null\n return found ? found.node.child(0).textContent.trim() || t('composites.untitled') : null\n },\n })\n if (title === null) return null\n return (\n <div\n className=\"fixed bottom-4 left-1/2 z-20 flex max-w-[90vw] -translate-x-1/2 items-center gap-2 rounded-full border border-border bg-background py-1 pl-3 pr-1 shadow-lg\"\n role=\"status\"\n >\n <Icon name=\"i-lucide-focus\" className=\"shrink-0 text-primary\" />\n <span className=\"truncate text-sm\">{t('composites.focus.chip', { title })}</span>\n <Button size=\"xs\" variant=\"ghost\" aria-label={t('composites.focus.leave')} onClick={() => editor.commands.focusComposite(null)}>\n <Icon name=\"i-lucide-x\" />\n {t('composites.focus.release')}\n </Button>\n </div>\n )\n}\n"],"mappings":";;;;;;;;;;;;AAYA,SAAgB,UAAU,EAAE,UAA8B;CACxD,MAAM,EAAE,MAAM,cAAc;CAC5B,MAAM,QAAQ,eAAe;EAC3B;EACA,WAAW,EAAE,QAAQ,cAAc;GACjC,IAAI,QAAQ,aAAa,OAAO;GAChC,MAAM,KAAK,iBAAiB,QAAQ,KAAK;GACzC,MAAM,QAAQ,KAAK,cAAc,QAAQ,MAAM,KAAK,EAAE,IAAI;GAC1D,OAAO,QAAQ,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,YAAY,KAAK,KAAK,EAAE,qBAAqB,IAAI;EACtF;CACF,CAAC;CACD,IAAI,UAAU,MAAM,OAAO;CAC3B,OACE,qBAAC,OAAD;EACE,WAAU;EACV,MAAK;EAFP,UAAA;GAIE,oBAAC,MAAD;IAAM,MAAK;IAAiB,WAAU;GAAyB,CAAA;GAC/D,oBAAC,QAAD;IAAM,WAAU;IAAoB,UAAA,EAAE,yBAAyB,EAAE,MAAM,CAAC;GAAQ,CAAA;GAChF,qBAAC,QAAD;IAAQ,MAAK;IAAK,SAAQ;IAAQ,cAAY,EAAE,wBAAwB;IAAG,eAAe,OAAO,SAAS,eAAe,IAAI;IAA7H,UAAA,CACE,oBAAC,MAAD,EAAM,MAAK,aAAc,CAAA,GACxB,EAAE,0BAA0B,CACvB;;EACL;;AAET"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { setBlockProperty } from "../properties.js";
|
|
1
2
|
import { useEditorI18n } from "../../../react/use-editor-i18n.js";
|
|
2
3
|
import { cn } from "../../../react/ui/utils.js";
|
|
3
4
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "../../../react/ui/select.js";
|
|
4
|
-
import { setCompositeMetaField } from "../rows.js";
|
|
5
5
|
import { metaText } from "../meta-display.js";
|
|
6
6
|
import { useCompositeRows } from "./use-composite-rows.js";
|
|
7
7
|
import { useMemo } from "react";
|
|
@@ -14,7 +14,7 @@ const SELECT_SIZE = {
|
|
|
14
14
|
sm: "data-[size=sm]:h-7",
|
|
15
15
|
md: ""
|
|
16
16
|
};
|
|
17
|
-
/** The select of a `reference` field: the other
|
|
17
|
+
/** The select of a `reference` field: the other Typed blocks of the document (with a block ID, of the field's target Block types) by title. */
|
|
18
18
|
function ReferenceFieldSelect({ editor, row, field, disabled, size = "sm" }) {
|
|
19
19
|
const { t } = useEditorI18n();
|
|
20
20
|
const { rows } = useCompositeRows(editor);
|
|
@@ -30,7 +30,7 @@ function ReferenceFieldSelect({ editor, row, field, disabled, size = "sm" }) {
|
|
|
30
30
|
]);
|
|
31
31
|
return /* @__PURE__ */ jsxs(Select, {
|
|
32
32
|
value: stored,
|
|
33
|
-
onValueChange: (value) =>
|
|
33
|
+
onValueChange: (value) => setBlockProperty(editor, row, field.key, value === NONE ? "" : value),
|
|
34
34
|
disabled,
|
|
35
35
|
children: [/* @__PURE__ */ jsx(SelectTrigger, {
|
|
36
36
|
size: "sm",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReferenceFieldSelect.js","names":[],"sources":["../../../../src/features/composites/react/ReferenceFieldSelect.tsx"],"sourcesContent":["import type { Editor } from '@tiptap/core'\nimport { useMemo } from 'react'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../../../react/ui/select'\nimport { cn } from '../../../react/ui/utils'\nimport { useEditorI18n } from '../../../react/use-editor-i18n'\nimport type {
|
|
1
|
+
{"version":3,"file":"ReferenceFieldSelect.js","names":[],"sources":["../../../../src/features/composites/react/ReferenceFieldSelect.tsx"],"sourcesContent":["import type { Editor } from '@tiptap/core'\nimport { useMemo } from 'react'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../../../react/ui/select'\nimport { cn } from '../../../react/ui/utils'\nimport { useEditorI18n } from '../../../react/use-editor-i18n'\nimport type { PropertyDefinition } from '../../../core/properties'\nimport { metaText } from '../meta-display'\nimport { type BlockProperties, setBlockProperty } from '../properties'\nimport { useCompositeRows } from './use-composite-rows'\n\n/** Radix Select has no empty-string value: the \"no reference\" item travels as this sentinel. */\nconst NONE = '__none__'\n\nconst SELECT_SIZE = {\n xs: 'data-[size=sm]:h-6 text-xs',\n sm: 'data-[size=sm]:h-7',\n md: '',\n}\n\n/** The select of a `reference` field: the other Typed blocks of the document (with a block ID, of the field's target Block types) by title. */\nexport function ReferenceFieldSelect({ editor, row, field, disabled, size = 'sm' }: {\n editor: Editor\n row: BlockProperties\n field: PropertyDefinition\n disabled?: boolean\n size?: 'xs' | 'sm' | 'md'\n}) {\n const { t } = useEditorI18n()\n const { rows } = useCompositeRows(editor)\n const stored = metaText(row, field)\n const options = useMemo(() => rows\n .filter(candidate => candidate.id !== null && candidate.id !== row.id && (!field.targets || field.targets.includes(candidate.kind)))\n .map(candidate => ({ label: `${candidate.title.trim() || t('composites.inspector.untitled')} · ${candidate.kindLabel}`, value: candidate.id as string })), [rows, row.id, field.targets, t])\n\n return (\n <Select value={stored} onValueChange={value => setBlockProperty(editor, row, field.key, value === NONE ? '' : value)} disabled={disabled}>\n <SelectTrigger size=\"sm\" className={cn('w-full', SELECT_SIZE[size])} aria-label={field.label}>\n <SelectValue placeholder={t('composites.field.choose', { field: field.label })} />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={NONE}>{t('composites.field.none')}</SelectItem>\n {options.map(option => (\n <SelectItem key={option.value} value={option.value}>{option.label}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n )\n}\n"],"mappings":";;;;;;;;;;AAWA,MAAM,OAAO;AAEb,MAAM,cAAc;CAClB,IAAI;CACJ,IAAI;CACJ,IAAI;AACN;;AAGA,SAAgB,qBAAqB,EAAE,QAAQ,KAAK,OAAO,UAAU,OAAO,QAMzE;CACD,MAAM,EAAE,MAAM,cAAc;CAC5B,MAAM,EAAE,SAAS,iBAAiB,MAAM;CACxC,MAAM,SAAS,SAAS,KAAK,KAAK;CAClC,MAAM,UAAU,cAAc,KAC3B,QAAO,cAAa,UAAU,OAAO,QAAQ,UAAU,OAAO,IAAI,OAAO,CAAC,MAAM,WAAW,MAAM,QAAQ,SAAS,UAAU,IAAI,EAAE,CAAC,CACnI,KAAI,eAAc;EAAE,OAAO,GAAG,UAAU,MAAM,KAAK,KAAK,EAAE,+BAA+B,EAAE,KAAK,UAAU;EAAa,OAAO,UAAU;CAAa,EAAE,GAAG;EAAC;EAAM,IAAI;EAAI,MAAM;EAAS;CAAC,CAAC;CAE7L,OACE,qBAAC,QAAD;EAAQ,OAAO;EAAQ,gBAAe,UAAS,iBAAiB,QAAQ,KAAK,MAAM,KAAK,UAAU,OAAO,KAAK,KAAK;EAAa;EAAhI,UAAA,CACE,oBAAC,eAAD;GAAe,MAAK;GAAK,WAAW,GAAG,UAAU,YAAY,KAAK;GAAG,cAAY,MAAM;GACrF,UAAA,oBAAC,aAAD,EAAa,aAAa,EAAE,2BAA2B,EAAE,OAAO,MAAM,MAAM,CAAC,EAAI,CAAA;EACpE,CAAA,GACf,qBAAC,eAAD,EAAA,UAAA,CACE,oBAAC,YAAD;GAAY,OAAO;GAAO,UAAA,EAAE,uBAAuB;EAAc,CAAA,GAChE,QAAQ,KAAI,WACX,oBAAC,YAAD;GAA+B,OAAO,OAAO;GAAQ,UAAA,OAAO;EAAkB,GAA7D,OAAO,KAAsD,CAC/E,CACY,EAAA,CAAA,CACT;;AAEZ"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { NodeViewProps } from "@tiptap/react";
|
|
2
2
|
//#region src/features/composites/react/ReferenceView.d.ts
|
|
3
3
|
/**
|
|
4
|
-
* The `reference` chip: the live short citation (or title) of the
|
|
4
|
+
* The `reference` chip: the live short citation (or title) of the Typed block it points at, followed by its locator.
|
|
5
5
|
* A click reveals the target and, with a locator, opens its source there (page of a PDF, time of a recording); a
|
|
6
6
|
* target that no longer exists shows a greyed „gone“ label. Double click or right click opens a popover to set the
|
|
7
7
|
* locator („Stelle“) in an editable editor.
|
|
@@ -9,7 +9,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
9
9
|
import { NodeViewWrapper } from "@tiptap/react";
|
|
10
10
|
//#region src/features/composites/react/ReferenceView.tsx
|
|
11
11
|
/**
|
|
12
|
-
* The `reference` chip: the live short citation (or title) of the
|
|
12
|
+
* The `reference` chip: the live short citation (or title) of the Typed block it points at, followed by its locator.
|
|
13
13
|
* A click reveals the target and, with a locator, opens its source there (page of a PDF, time of a recording); a
|
|
14
14
|
* target that no longer exists shows a greyed „gone“ label. Double click or right click opens a popover to set the
|
|
15
15
|
* locator („Stelle“) in an editable editor.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReferenceView.js","names":[],"sources":["../../../../src/features/composites/react/ReferenceView.tsx"],"sourcesContent":["import { NodeViewWrapper, type NodeViewProps } from '@tiptap/react'\nimport { type MouseEvent, useEffect, useState } from 'react'\nimport { Input } from '../../../react/ui/input'\nimport { Popover, PopoverAnchor, PopoverContent } from '../../../react/ui/popover'\nimport { cn } from '../../../react/ui/utils'\nimport { useEditorI18n } from '../../../react/use-editor-i18n'\nimport { referenceAttrsOf, resolveReference } from '../reference-label'\nimport { revealSource } from '../reveal-source'\n\n/**\n * The `reference` chip: the live short citation (or title) of the
|
|
1
|
+
{"version":3,"file":"ReferenceView.js","names":[],"sources":["../../../../src/features/composites/react/ReferenceView.tsx"],"sourcesContent":["import { NodeViewWrapper, type NodeViewProps } from '@tiptap/react'\nimport { type MouseEvent, useEffect, useState } from 'react'\nimport { Input } from '../../../react/ui/input'\nimport { Popover, PopoverAnchor, PopoverContent } from '../../../react/ui/popover'\nimport { cn } from '../../../react/ui/utils'\nimport { useEditorI18n } from '../../../react/use-editor-i18n'\nimport { referenceAttrsOf, resolveReference } from '../reference-label'\nimport { revealSource } from '../reveal-source'\n\n/**\n * The `reference` chip: the live short citation (or title) of the Typed block it points at, followed by its locator.\n * A click reveals the target and, with a locator, opens its source there (page of a PDF, time of a recording); a\n * target that no longer exists shows a greyed „gone“ label. Double click or right click opens a popover to set the\n * locator („Stelle“) in an editable editor.\n */\nexport function ReferenceView({ editor, node, selected, getPos }: NodeViewProps) {\n const { t } = useEditorI18n()\n const [resolved, setResolved] = useState(() => resolveReference(editor, referenceAttrsOf(node)))\n const [open, setOpen] = useState(false)\n const [draft, setDraft] = useState('')\n const target = String(node.attrs.target)\n const locator = typeof node.attrs.locator === 'string' ? node.attrs.locator : ''\n\n // The target's title and bibliography edits change the label: re-resolve after document changes, once per frame.\n useEffect(() => {\n let frame = 0\n const resolve = () => {\n if (editor.isDestroyed) return\n const next = resolveReference(editor, { target, label: String(node.attrs.label ?? '') })\n setResolved(current => (next.label === current.label && next.title === current.title && next.gone === current.gone ? current : next))\n }\n const schedule = () => {\n cancelAnimationFrame(frame)\n frame = requestAnimationFrame(resolve)\n }\n resolve()\n editor.on('update', schedule)\n return () => {\n cancelAnimationFrame(frame)\n editor.off('update', schedule)\n }\n }, [editor, target, node.attrs.label])\n\n const label = resolved.gone ? t('composites.reference.gone') : resolved.label\n const text = locator && !resolved.gone ? `${label}, ${locator}` : label\n\n function onClick() {\n if (!editor.commands.revealBlock(target)) return\n if (locator) revealSource(editor, target, locator)\n }\n\n function openLocator() {\n if (!editor.isEditable) return\n setDraft(locator)\n setOpen(true)\n }\n\n function commit() {\n setOpen(false)\n const pos = getPos()\n if (typeof pos !== 'number' || draft.trim() === locator) return\n editor.commands.setReferenceLocator(pos, draft)\n }\n\n return (\n <NodeViewWrapper\n as=\"span\"\n className={cn('reference', resolved.gone && 'is-gone', selected && 'is-selected')}\n data-type=\"reference\"\n data-target={target}\n title={resolved.gone ? undefined : resolved.title}\n role=\"link\"\n onClick={onClick}\n onDoubleClick={(event: MouseEvent) => {\n event.preventDefault()\n openLocator()\n }}\n onContextMenu={(event: MouseEvent) => {\n event.preventDefault()\n openLocator()\n }}\n >\n <Popover open={open} onOpenChange={(value) => { if (!value) commit() }}>\n <PopoverAnchor asChild>\n <span>{text}</span>\n </PopoverAnchor>\n <PopoverContent\n align=\"start\"\n side=\"bottom\"\n className=\"w-56 p-2\"\n onCloseAutoFocus={event => event.preventDefault()}\n >\n <Input\n value={draft}\n className=\"h-7 w-full text-xs\"\n placeholder={t('composites.reference.locatorPlaceholder')}\n aria-label={t('composites.reference.locator')}\n onChange={event => setDraft(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') {\n event.preventDefault()\n commit()\n }\n }}\n />\n </PopoverContent>\n </Popover>\n </NodeViewWrapper>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAeA,SAAgB,cAAc,EAAE,QAAQ,MAAM,UAAU,UAAyB;CAC/E,MAAM,EAAE,MAAM,cAAc;CAC5B,MAAM,CAAC,UAAU,eAAe,eAAe,iBAAiB,QAAQ,iBAAiB,IAAI,CAAC,CAAC;CAC/F,MAAM,CAAC,MAAM,WAAW,SAAS,KAAK;CACtC,MAAM,CAAC,OAAO,YAAY,SAAS,EAAE;CACrC,MAAM,SAAS,OAAO,KAAK,MAAM,MAAM;CACvC,MAAM,UAAU,OAAO,KAAK,MAAM,YAAY,WAAW,KAAK,MAAM,UAAU;CAG9E,gBAAgB;EACd,IAAI,QAAQ;EACZ,MAAM,gBAAgB;GACpB,IAAI,OAAO,aAAa;GACxB,MAAM,OAAO,iBAAiB,QAAQ;IAAE;IAAQ,OAAO,OAAO,KAAK,MAAM,SAAS,EAAE;GAAE,CAAC;GACvF,aAAY,YAAY,KAAK,UAAU,QAAQ,SAAS,KAAK,UAAU,QAAQ,SAAS,KAAK,SAAS,QAAQ,OAAO,UAAU,IAAK;EACtI;EACA,MAAM,iBAAiB;GACrB,qBAAqB,KAAK;GAC1B,QAAQ,sBAAsB,OAAO;EACvC;EACA,QAAQ;EACR,OAAO,GAAG,UAAU,QAAQ;EAC5B,aAAa;GACX,qBAAqB,KAAK;GAC1B,OAAO,IAAI,UAAU,QAAQ;EAC/B;CACF,GAAG;EAAC;EAAQ;EAAQ,KAAK,MAAM;CAAK,CAAC;CAErC,MAAM,QAAQ,SAAS,OAAO,EAAE,2BAA2B,IAAI,SAAS;CACxE,MAAM,OAAO,WAAW,CAAC,SAAS,OAAO,GAAG,MAAM,IAAI,YAAY;CAElE,SAAS,UAAU;EACjB,IAAI,CAAC,OAAO,SAAS,YAAY,MAAM,GAAG;EAC1C,IAAI,SAAS,aAAa,QAAQ,QAAQ,OAAO;CACnD;CAEA,SAAS,cAAc;EACrB,IAAI,CAAC,OAAO,YAAY;EACxB,SAAS,OAAO;EAChB,QAAQ,IAAI;CACd;CAEA,SAAS,SAAS;EAChB,QAAQ,KAAK;EACb,MAAM,MAAM,OAAO;EACnB,IAAI,OAAO,QAAQ,YAAY,MAAM,KAAK,MAAM,SAAS;EACzD,OAAO,SAAS,oBAAoB,KAAK,KAAK;CAChD;CAEA,OACE,oBAAC,iBAAD;EACE,IAAG;EACH,WAAW,GAAG,aAAa,SAAS,QAAQ,WAAW,YAAY,aAAa;EAChF,aAAU;EACV,eAAa;EACb,OAAO,SAAS,OAAO,KAAA,IAAY,SAAS;EAC5C,MAAK;EACI;EACT,gBAAgB,UAAsB;GACpC,MAAM,eAAe;GACrB,YAAY;EACd;EACA,gBAAgB,UAAsB;GACpC,MAAM,eAAe;GACrB,YAAY;EACd;EAEA,UAAA,qBAAC,SAAD;GAAe;GAAM,eAAe,UAAU;IAAE,IAAI,CAAC,OAAO,OAAO;GAAE;GAArE,UAAA,CACE,oBAAC,eAAD;IAAe,SAAA;IACb,UAAA,oBAAC,QAAD,EAAA,UAAO,KAAW,CAAA;GACL,CAAA,GACf,oBAAC,gBAAD;IACE,OAAM;IACN,MAAK;IACL,WAAU;IACV,mBAAkB,UAAS,MAAM,eAAe;IAEhD,UAAA,oBAAC,OAAD;KACE,OAAO;KACP,WAAU;KACV,aAAa,EAAE,yCAAyC;KACxD,cAAY,EAAE,8BAA8B;KAC5C,WAAU,UAAS,SAAS,MAAM,OAAO,KAAK;KAC9C,YAAY,UAAU;MACpB,IAAI,MAAM,QAAQ,SAAS;OACzB,MAAM,eAAe;OACrB,OAAO;MACT;KACF;IACD,CAAA;GACa,CAAA,CACT;;CACM,CAAA;AAErB"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BlockType } from "../block-types.js";
|
|
2
2
|
//#region src/features/composites/react/SettingsEditingTab.d.ts
|
|
3
|
-
/** „Bearbeiten“: Gliederung (structure mode, conversion scope),
|
|
4
|
-
export declare function SettingsEditingTab({
|
|
5
|
-
|
|
3
|
+
/** „Bearbeiten“: Gliederung (structure mode, conversion scope), Typed blocks defaults and the visibility of the block handles. */
|
|
4
|
+
export declare function SettingsEditingTab({ blockTypes }: {
|
|
5
|
+
blockTypes: readonly BlockType[];
|
|
6
6
|
}): import("react").JSX.Element;
|
|
7
7
|
//#endregion
|
|
8
8
|
//# sourceMappingURL=SettingsEditingTab.d.ts.map
|