@templatical/editor 0.16.2 → 0.16.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{AiFeatureMenu-DfTYyExg.js → AiFeatureMenu-CcGRd1xE.js} +1 -1
- package/dist/{CloudEditor-BQyZ_nFg.js → CloudEditor-CUIWUMp5.js} +6 -6
- package/dist/{CollaboratorBar-DeP7K-zk.js → CollaboratorBar-DmxqeBYZ.js} +1 -1
- package/dist/ColorPicker-Gs4BMVog.js +474 -0
- package/dist/{CountdownToolbar-nY9H0BKd.js → CountdownToolbar-92w1YySJ.js} +2 -2
- package/dist/{ModuleBrowserModal-CkeYw1e3.js → ModuleBrowserModal-DsehjLvh.js} +4 -4
- package/dist/{ModulePreviewCanvas-BIMFyYaa.js → ModulePreviewCanvas-BBfuS8VW.js} +1 -1
- package/dist/{NumberWithSuffix-BoZyUoNz.js → NumberWithSuffix-BxSRfI8b.js} +1 -1
- package/dist/{ParagraphEditor-DGsTFMxg.js → ParagraphEditor-vgvQxicC.js} +4 -4
- package/dist/{RichTextEditorContent-BB_n8vgB.js → RichTextEditorContent-Dza2oPvh.js} +1 -1
- package/dist/{SaveModuleDialog-Cypt_qOB.js → SaveModuleDialog-DNWGCHlS.js} +2 -2
- package/dist/{SnapshotHistory-DQTH8TCS.js → SnapshotHistory-BLmnNLg1.js} +2 -2
- package/dist/{TestEmailModal-DqxrL-U9.js → TestEmailModal-D6v1hgY2.js} +2 -2
- package/dist/{TitleEditor-DoGgnrcb.js → TitleEditor-DPdzOQpq.js} +2 -2
- package/dist/{TplModal-Ca-29YDD.js → TplModal-DObT0uxf.js} +1 -1
- package/dist/{blockTypeIcons-DVJXg5si.js → blockTypeIcons-B9f5fH_5.js} +1 -1
- package/dist/bundle-stats.json +6 -6
- package/dist/cdn/chunks/{AiFeatureMenu-roPglhox.js → AiFeatureMenu-CyUCHd9I.js} +8 -8
- package/dist/cdn/chunks/{AiFeatureMenu-roPglhox.js.map → AiFeatureMenu-CyUCHd9I.js.map} +1 -1
- package/dist/cdn/chunks/{BlockIssueBadge-DW_Tt7Wg.js → BlockIssueBadge-BAa_dI-c.js} +5 -5
- package/dist/cdn/chunks/{BlockIssueBadge-DW_Tt7Wg.js.map → BlockIssueBadge-BAa_dI-c.js.map} +1 -1
- package/dist/cdn/chunks/{CloudEditor-CX6y1k3C.js → CloudEditor-ClfgLU48.js} +159 -159
- package/dist/cdn/chunks/{CloudEditor-CX6y1k3C.js.map → CloudEditor-ClfgLU48.js.map} +1 -1
- package/dist/cdn/chunks/{CollaboratorBar-Dyrab63H.js → CollaboratorBar-DCc5SL0P.js} +3 -3
- package/dist/cdn/chunks/{CollaboratorBar-Dyrab63H.js.map → CollaboratorBar-DCc5SL0P.js.map} +1 -1
- package/dist/cdn/chunks/ColorPicker-Pi-1fR8c.js +471 -0
- package/dist/cdn/chunks/ColorPicker-Pi-1fR8c.js.map +1 -0
- package/dist/cdn/chunks/{CountdownBlock-Bul4tczj.js → CountdownBlock-Bj7aoBUU.js} +4 -4
- package/dist/cdn/chunks/{CountdownBlock-Bul4tczj.js.map → CountdownBlock-Bj7aoBUU.js.map} +1 -1
- package/dist/cdn/chunks/{CountdownToolbar-DYvATR0J.js → CountdownToolbar-B1oniVq1.js} +4 -4
- package/dist/cdn/chunks/{CountdownToolbar-DYvATR0J.js.map → CountdownToolbar-B1oniVq1.js.map} +1 -1
- package/dist/cdn/chunks/{IssuesPanel-BhHU-hq3.js → IssuesPanel-BXLVRo-c.js} +7 -7
- package/dist/cdn/chunks/{IssuesPanel-BhHU-hq3.js.map → IssuesPanel-BXLVRo-c.js.map} +1 -1
- package/dist/cdn/chunks/{ModuleBrowserModal-BGd5Ryyx.js → ModuleBrowserModal-C7BkJvzf.js} +6 -6
- package/dist/cdn/chunks/{ModuleBrowserModal-BGd5Ryyx.js.map → ModuleBrowserModal-C7BkJvzf.js.map} +1 -1
- package/dist/cdn/chunks/{ModulePreviewCanvas-Hx6SCCjB.js → ModulePreviewCanvas-BJn-ZHlC.js} +10 -10
- package/dist/cdn/chunks/{ModulePreviewCanvas-Hx6SCCjB.js.map → ModulePreviewCanvas-BJn-ZHlC.js.map} +1 -1
- package/dist/cdn/chunks/{NumberWithSuffix-BImuhc9K.js → NumberWithSuffix-CkOxH3F7.js} +2 -2
- package/dist/cdn/chunks/{NumberWithSuffix-BImuhc9K.js.map → NumberWithSuffix-CkOxH3F7.js.map} +1 -1
- package/dist/cdn/chunks/{ParagraphEditor-K2vENidm.js → ParagraphEditor-4cMKKC-V.js} +146 -146
- package/dist/cdn/chunks/{ParagraphEditor-K2vENidm.js.map → ParagraphEditor-4cMKKC-V.js.map} +1 -1
- package/dist/cdn/chunks/{RichTextEditorContent-B_w3u5lN.js → RichTextEditorContent-7RZe4tbj.js} +6 -6
- package/dist/cdn/chunks/{RichTextEditorContent-B_w3u5lN.js.map → RichTextEditorContent-7RZe4tbj.js.map} +1 -1
- package/dist/cdn/chunks/{SaveModuleDialog-Cw-182CB.js → SaveModuleDialog-mr9A4j6G.js} +4 -4
- package/dist/cdn/chunks/{SaveModuleDialog-Cw-182CB.js.map → SaveModuleDialog-mr9A4j6G.js.map} +1 -1
- package/dist/cdn/chunks/{TitleEditor-CUKlo_Zj.js → TitleEditor-Cqw2jvuc.js} +8 -8
- package/dist/cdn/chunks/{TitleEditor-CUKlo_Zj.js.map → TitleEditor-Cqw2jvuc.js.map} +1 -1
- package/dist/cdn/chunks/{blockTypeIcons-Cx1FAqL6.js → blockTypeIcons-B_xRBxSU.js} +8 -8
- package/dist/cdn/chunks/{blockTypeIcons-Cx1FAqL6.js.map → blockTypeIcons-B_xRBxSU.js.map} +1 -1
- package/dist/cdn/chunks/{extensions-DSxG2wYf.js → extensions-Btyx_IMf.js} +19 -19
- package/dist/cdn/chunks/{extensions-DSxG2wYf.js.map → extensions-Btyx_IMf.js.map} +1 -1
- package/dist/cdn/chunks/{features-C-cjT_8L.js → features-Dwb5aTLg.js} +18 -16
- package/dist/cdn/chunks/features-Dwb5aTLg.js.map +1 -0
- package/dist/cdn/chunks/{icons-ay0_fN-T.js → icons-Dhqh5lYQ.js} +2 -2
- package/dist/cdn/chunks/{icons-ay0_fN-T.js.map → icons-Dhqh5lYQ.js.map} +1 -1
- package/dist/cdn/chunks/{media-library-CkmqPdO4.js → media-library-DRodsf2D.js} +101 -101
- package/dist/cdn/chunks/{media-library-CkmqPdO4.js.map → media-library-DRodsf2D.js.map} +1 -1
- package/dist/cdn/chunks/{quality-CDNrMw2A.js → quality-A_V2Iqu_.js} +435 -435
- package/dist/cdn/chunks/{quality-CDNrMw2A.js.map → quality-A_V2Iqu_.js.map} +1 -1
- package/dist/cdn/chunks/{renderer-JQ91A09w.js → renderer-BM_-zceB.js} +11 -11
- package/dist/cdn/chunks/{renderer-JQ91A09w.js.map → renderer-BM_-zceB.js.map} +1 -1
- package/dist/cdn/chunks/{src-Cehu7Hqx.js → src-DSomxPI-.js} +4 -4
- package/dist/cdn/chunks/{src-Cehu7Hqx.js.map → src-DSomxPI-.js.map} +1 -1
- package/dist/cdn/chunks/{styles-DBjy3lz9.js → styles--UXn88wH.js} +829 -829
- package/dist/cdn/chunks/{styles-DBjy3lz9.js.map → styles--UXn88wH.js.map} +1 -1
- package/dist/cdn/editor.js +29 -29
- package/dist/{dist-CFOQvhSC.js → color-DhoxCSMv.js} +9 -1
- package/dist/{styles-mvx3k1hf.js → styles-CPt6RYEc.js} +6 -6
- package/dist/templatical-editor.js +3 -3
- package/dist/{useEditorCore-DtZkR7Vk.js → useEditorCore-CSfeEwCj.js} +196 -202
- package/package.json +7 -7
- package/dist/ColorPicker-CXAbjTaG.js +0 -446
- package/dist/cdn/chunks/ColorPicker-BggAWrc9.js +0 -443
- package/dist/cdn/chunks/ColorPicker-BggAWrc9.js.map +0 -1
- package/dist/cdn/chunks/features-C-cjT_8L.js.map +0 -1
package/dist/cdn/chunks/{SaveModuleDialog-Cw-182CB.js.map → SaveModuleDialog-mr9A4j6G.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SaveModuleDialog-Cw-182CB.js","names":[],"sources":["../../../src/cloud/components/SaveModuleDialog.vue","../../../src/cloud/components/SaveModuleDialog.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport TplModal from \"../../components/TplModal.vue\";\nimport { useI18n } from \"../../composables\";\nimport { useCloudI18nStrict } from \"../../composables\";\nimport {\n EDITOR_KEY,\n SAVED_MODULES_HEADLESS_KEY,\n requireInject,\n} from \"../../keys\";\nimport type { Block } from \"@templatical/types\";\nimport { LoaderCircle } from \"@lucide/vue\";\nimport { computed, ref, watch } from \"vue\";\n\nconst props = defineProps<{\n visible: boolean;\n preSelectedBlockId: string | null;\n}>();\n\nconst emit = defineEmits<{\n (e: \"close\"): void;\n (e: \"saved\"): void;\n}>();\n\nconst { t } = useI18n();\nconst { t: cloudT } = useCloudI18nStrict();\nconst editor = requireInject(EDITOR_KEY, \"SaveModuleDialog\");\nconst savedModules = requireInject(\n SAVED_MODULES_HEADLESS_KEY,\n \"SaveModuleDialog\",\n);\n\nconst moduleName = ref(\"\");\nconst selectedBlockIds = ref<Set<string>>(new Set());\nconst isSaving = ref(false);\nconst error = ref<string | null>(null);\n\nconst topLevelBlocks = computed(() => editor.content.value.blocks);\n\nfunction blockLabel(block: Block, index: number): string {\n const typeKey = block.type as keyof typeof t.blocks;\n const label = t.blocks[typeKey] ?? block.type;\n return `${label} ${index + 1}`;\n}\n\nwatch(\n () => props.visible,\n (visible) => {\n if (visible) {\n moduleName.value = \"\";\n error.value = null;\n selectedBlockIds.value = new Set(\n props.preSelectedBlockId ? [props.preSelectedBlockId] : [],\n );\n }\n },\n);\n\nfunction toggleBlock(blockId: string): void {\n const newSet = new Set(selectedBlockIds.value);\n if (newSet.has(blockId)) {\n newSet.delete(blockId);\n } else {\n newSet.add(blockId);\n }\n selectedBlockIds.value = newSet;\n}\n\nconst canSave = computed(\n () =>\n moduleName.value.trim().length > 0 &&\n selectedBlockIds.value.size > 0 &&\n !isSaving.value,\n);\n\nasync function handleSave(): Promise<void> {\n if (!canSave.value) return;\n\n isSaving.value = true;\n error.value = null;\n\n try {\n const selectedBlocks = topLevelBlocks.value.filter((b) =>\n selectedBlockIds.value.has(b.id),\n );\n await savedModules.createModule(moduleName.value.trim(), selectedBlocks);\n emit(\"saved\");\n emit(\"close\");\n } catch (err) {\n error.value = (err as Error).message;\n } finally {\n isSaving.value = false;\n }\n}\n\nfunction handleClose(): void {\n if (!isSaving.value) {\n emit(\"close\");\n }\n}\n\nfunction handleKeydown(event: KeyboardEvent): void {\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n handleSave();\n }\n if (event.key === \"Escape\") {\n handleClose();\n }\n}\n</script>\n\n<template>\n <TplModal :visible=\"visible\" @close=\"handleClose\" @keydown=\"handleKeydown\">\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n :aria-busy=\"isSaving\"\n aria-labelledby=\"tpl-save-module-title\"\n class=\"tpl-scale-in tpl:mx-4 tpl:w-full tpl:max-w-sm tpl:rounded-[var(--tpl-radius-lg)] tpl:p-5\"\n style=\"\n background-color: var(--tpl-bg-elevated);\n box-shadow: var(--tpl-shadow-xl);\n \"\n >\n <h3\n id=\"tpl-save-module-title\"\n class=\"tpl:mb-4 tpl:text-sm tpl:font-semibold tpl:text-[var(--tpl-text)]\"\n >\n {{ cloudT.modules.saveAsModule }}\n </h3>\n\n <!-- Module name -->\n <div class=\"tpl:mb-3\">\n <label\n class=\"tpl:mb-1.5 tpl:block tpl:text-sm tpl:font-medium tpl:text-[var(--tpl-text-muted)]\"\n >\n {{ cloudT.modules.moduleName }}\n </label>\n <input\n v-model=\"moduleName\"\n type=\"text\"\n :placeholder=\"cloudT.modules.moduleNamePlaceholder\"\n class=\"tpl:h-9 tpl:w-full tpl:rounded-md tpl:border tpl:px-3 tpl:py-1 tpl:text-sm tpl:shadow-xs tpl:outline-none tpl:border-[var(--tpl-border)] tpl:bg-[var(--tpl-bg)] tpl:text-[var(--tpl-text)]\"\n :disabled=\"isSaving\"\n />\n </div>\n\n <!-- Block selection -->\n <div class=\"tpl:mb-3\">\n <label\n class=\"tpl:mb-1.5 tpl:block tpl:text-sm tpl:font-medium tpl:text-[var(--tpl-text-muted)]\"\n >\n {{ cloudT.modules.selectBlocks }}\n </label>\n <div\n class=\"tpl:max-h-40 tpl:space-y-1 tpl:overflow-y-auto tpl:rounded-md tpl:border tpl:p-2 tpl:border-[var(--tpl-border)]\"\n >\n <label\n v-for=\"(block, index) in topLevelBlocks\"\n :key=\"block.id\"\n class=\"tpl:flex tpl:cursor-pointer tpl:items-center tpl:gap-2 tpl:rounded-sm tpl:px-2 tpl:py-1.5 tpl:text-sm tpl:transition-colors tpl:duration-100\"\n :style=\"{\n color: 'var(--tpl-text)',\n backgroundColor: selectedBlockIds.has(block.id)\n ? 'var(--tpl-primary-light)'\n : 'transparent',\n }\"\n >\n <input\n type=\"checkbox\"\n :checked=\"selectedBlockIds.has(block.id)\"\n class=\"tpl:accent-[var(--tpl-primary)]\"\n :disabled=\"isSaving\"\n @change=\"toggleBlock(block.id)\"\n />\n {{ blockLabel(block, index) }}\n </label>\n </div>\n </div>\n\n <!-- Error message -->\n <p\n v-if=\"error\"\n role=\"alert\"\n class=\"tpl:mb-3 tpl:text-xs tpl:text-[var(--tpl-danger)]\"\n >\n {{ error }}\n </p>\n\n <!-- Actions -->\n <div class=\"tpl:flex tpl:justify-end tpl:gap-2\">\n <button\n type=\"button\"\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:border tpl:px-3 tpl:py-1.5 tpl:text-sm tpl:font-medium tpl:shadow-xs tpl:transition-all tpl:duration-150 tpl:border-[var(--tpl-border)] tpl:text-[var(--tpl-text)] tpl:bg-[var(--tpl-bg)]\"\n :disabled=\"isSaving\"\n :class=\"{\n 'tpl:cursor-not-allowed tpl:opacity-50': isSaving,\n }\"\n @click=\"handleClose\"\n >\n {{ cloudT.modules.cancel }}\n </button>\n <button\n type=\"button\"\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:px-3 tpl:py-1.5 tpl:text-sm tpl:font-medium tpl:shadow-xs tpl:transition-all tpl:duration-150 tpl:hover:opacity-90 tpl:disabled:cursor-not-allowed tpl:disabled:opacity-50 tpl:bg-[var(--tpl-primary)] tpl:text-[var(--tpl-bg)]\"\n :disabled=\"!canSave\"\n @click=\"handleSave\"\n >\n <span v-if=\"isSaving\" class=\"tpl:flex tpl:items-center tpl:gap-1.5\">\n <LoaderCircle\n class=\"tpl:animate-spin\"\n :size=\"12\"\n :stroke-width=\"2\"\n />\n {{ cloudT.modules.saving }}\n </span>\n <span v-else>\n {{ cloudT.modules.save }}\n </span>\n </button>\n </div>\n </div>\n </TplModal>\n</template>\n","<script setup lang=\"ts\">\nimport TplModal from \"../../components/TplModal.vue\";\nimport { useI18n } from \"../../composables\";\nimport { useCloudI18nStrict } from \"../../composables\";\nimport {\n EDITOR_KEY,\n SAVED_MODULES_HEADLESS_KEY,\n requireInject,\n} from \"../../keys\";\nimport type { Block } from \"@templatical/types\";\nimport { LoaderCircle } from \"@lucide/vue\";\nimport { computed, ref, watch } from \"vue\";\n\nconst props = defineProps<{\n visible: boolean;\n preSelectedBlockId: string | null;\n}>();\n\nconst emit = defineEmits<{\n (e: \"close\"): void;\n (e: \"saved\"): void;\n}>();\n\nconst { t } = useI18n();\nconst { t: cloudT } = useCloudI18nStrict();\nconst editor = requireInject(EDITOR_KEY, \"SaveModuleDialog\");\nconst savedModules = requireInject(\n SAVED_MODULES_HEADLESS_KEY,\n \"SaveModuleDialog\",\n);\n\nconst moduleName = ref(\"\");\nconst selectedBlockIds = ref<Set<string>>(new Set());\nconst isSaving = ref(false);\nconst error = ref<string | null>(null);\n\nconst topLevelBlocks = computed(() => editor.content.value.blocks);\n\nfunction blockLabel(block: Block, index: number): string {\n const typeKey = block.type as keyof typeof t.blocks;\n const label = t.blocks[typeKey] ?? block.type;\n return `${label} ${index + 1}`;\n}\n\nwatch(\n () => props.visible,\n (visible) => {\n if (visible) {\n moduleName.value = \"\";\n error.value = null;\n selectedBlockIds.value = new Set(\n props.preSelectedBlockId ? [props.preSelectedBlockId] : [],\n );\n }\n },\n);\n\nfunction toggleBlock(blockId: string): void {\n const newSet = new Set(selectedBlockIds.value);\n if (newSet.has(blockId)) {\n newSet.delete(blockId);\n } else {\n newSet.add(blockId);\n }\n selectedBlockIds.value = newSet;\n}\n\nconst canSave = computed(\n () =>\n moduleName.value.trim().length > 0 &&\n selectedBlockIds.value.size > 0 &&\n !isSaving.value,\n);\n\nasync function handleSave(): Promise<void> {\n if (!canSave.value) return;\n\n isSaving.value = true;\n error.value = null;\n\n try {\n const selectedBlocks = topLevelBlocks.value.filter((b) =>\n selectedBlockIds.value.has(b.id),\n );\n await savedModules.createModule(moduleName.value.trim(), selectedBlocks);\n emit(\"saved\");\n emit(\"close\");\n } catch (err) {\n error.value = (err as Error).message;\n } finally {\n isSaving.value = false;\n }\n}\n\nfunction handleClose(): void {\n if (!isSaving.value) {\n emit(\"close\");\n }\n}\n\nfunction handleKeydown(event: KeyboardEvent): void {\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n handleSave();\n }\n if (event.key === \"Escape\") {\n handleClose();\n }\n}\n</script>\n\n<template>\n <TplModal :visible=\"visible\" @close=\"handleClose\" @keydown=\"handleKeydown\">\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n :aria-busy=\"isSaving\"\n aria-labelledby=\"tpl-save-module-title\"\n class=\"tpl-scale-in tpl:mx-4 tpl:w-full tpl:max-w-sm tpl:rounded-[var(--tpl-radius-lg)] tpl:p-5\"\n style=\"\n background-color: var(--tpl-bg-elevated);\n box-shadow: var(--tpl-shadow-xl);\n \"\n >\n <h3\n id=\"tpl-save-module-title\"\n class=\"tpl:mb-4 tpl:text-sm tpl:font-semibold tpl:text-[var(--tpl-text)]\"\n >\n {{ cloudT.modules.saveAsModule }}\n </h3>\n\n <!-- Module name -->\n <div class=\"tpl:mb-3\">\n <label\n class=\"tpl:mb-1.5 tpl:block tpl:text-sm tpl:font-medium tpl:text-[var(--tpl-text-muted)]\"\n >\n {{ cloudT.modules.moduleName }}\n </label>\n <input\n v-model=\"moduleName\"\n type=\"text\"\n :placeholder=\"cloudT.modules.moduleNamePlaceholder\"\n class=\"tpl:h-9 tpl:w-full tpl:rounded-md tpl:border tpl:px-3 tpl:py-1 tpl:text-sm tpl:shadow-xs tpl:outline-none tpl:border-[var(--tpl-border)] tpl:bg-[var(--tpl-bg)] tpl:text-[var(--tpl-text)]\"\n :disabled=\"isSaving\"\n />\n </div>\n\n <!-- Block selection -->\n <div class=\"tpl:mb-3\">\n <label\n class=\"tpl:mb-1.5 tpl:block tpl:text-sm tpl:font-medium tpl:text-[var(--tpl-text-muted)]\"\n >\n {{ cloudT.modules.selectBlocks }}\n </label>\n <div\n class=\"tpl:max-h-40 tpl:space-y-1 tpl:overflow-y-auto tpl:rounded-md tpl:border tpl:p-2 tpl:border-[var(--tpl-border)]\"\n >\n <label\n v-for=\"(block, index) in topLevelBlocks\"\n :key=\"block.id\"\n class=\"tpl:flex tpl:cursor-pointer tpl:items-center tpl:gap-2 tpl:rounded-sm tpl:px-2 tpl:py-1.5 tpl:text-sm tpl:transition-colors tpl:duration-100\"\n :style=\"{\n color: 'var(--tpl-text)',\n backgroundColor: selectedBlockIds.has(block.id)\n ? 'var(--tpl-primary-light)'\n : 'transparent',\n }\"\n >\n <input\n type=\"checkbox\"\n :checked=\"selectedBlockIds.has(block.id)\"\n class=\"tpl:accent-[var(--tpl-primary)]\"\n :disabled=\"isSaving\"\n @change=\"toggleBlock(block.id)\"\n />\n {{ blockLabel(block, index) }}\n </label>\n </div>\n </div>\n\n <!-- Error message -->\n <p\n v-if=\"error\"\n role=\"alert\"\n class=\"tpl:mb-3 tpl:text-xs tpl:text-[var(--tpl-danger)]\"\n >\n {{ error }}\n </p>\n\n <!-- Actions -->\n <div class=\"tpl:flex tpl:justify-end tpl:gap-2\">\n <button\n type=\"button\"\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:border tpl:px-3 tpl:py-1.5 tpl:text-sm tpl:font-medium tpl:shadow-xs tpl:transition-all tpl:duration-150 tpl:border-[var(--tpl-border)] tpl:text-[var(--tpl-text)] tpl:bg-[var(--tpl-bg)]\"\n :disabled=\"isSaving\"\n :class=\"{\n 'tpl:cursor-not-allowed tpl:opacity-50': isSaving,\n }\"\n @click=\"handleClose\"\n >\n {{ cloudT.modules.cancel }}\n </button>\n <button\n type=\"button\"\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:px-3 tpl:py-1.5 tpl:text-sm tpl:font-medium tpl:shadow-xs tpl:transition-all tpl:duration-150 tpl:hover:opacity-90 tpl:disabled:cursor-not-allowed tpl:disabled:opacity-50 tpl:bg-[var(--tpl-primary)] tpl:text-[var(--tpl-bg)]\"\n :disabled=\"!canSave\"\n @click=\"handleSave\"\n >\n <span v-if=\"isSaving\" class=\"tpl:flex tpl:items-center tpl:gap-1.5\">\n <LoaderCircle\n class=\"tpl:animate-spin\"\n :size=\"12\"\n :stroke-width=\"2\"\n />\n {{ cloudT.modules.saving }}\n </span>\n <span v-else>\n {{ cloudT.modules.save }}\n </span>\n </button>\n </div>\n </div>\n </TplModal>\n</template>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SaveModuleDialog-mr9A4j6G.js","names":[],"sources":["../../../src/cloud/components/SaveModuleDialog.vue","../../../src/cloud/components/SaveModuleDialog.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport TplModal from \"../../components/TplModal.vue\";\nimport { useI18n } from \"../../composables\";\nimport { useCloudI18nStrict } from \"../../composables\";\nimport {\n EDITOR_KEY,\n SAVED_MODULES_HEADLESS_KEY,\n requireInject,\n} from \"../../keys\";\nimport type { Block } from \"@templatical/types\";\nimport { LoaderCircle } from \"@lucide/vue\";\nimport { computed, ref, watch } from \"vue\";\n\nconst props = defineProps<{\n visible: boolean;\n preSelectedBlockId: string | null;\n}>();\n\nconst emit = defineEmits<{\n (e: \"close\"): void;\n (e: \"saved\"): void;\n}>();\n\nconst { t } = useI18n();\nconst { t: cloudT } = useCloudI18nStrict();\nconst editor = requireInject(EDITOR_KEY, \"SaveModuleDialog\");\nconst savedModules = requireInject(\n SAVED_MODULES_HEADLESS_KEY,\n \"SaveModuleDialog\",\n);\n\nconst moduleName = ref(\"\");\nconst selectedBlockIds = ref<Set<string>>(new Set());\nconst isSaving = ref(false);\nconst error = ref<string | null>(null);\n\nconst topLevelBlocks = computed(() => editor.content.value.blocks);\n\nfunction blockLabel(block: Block, index: number): string {\n const typeKey = block.type as keyof typeof t.blocks;\n const label = t.blocks[typeKey] ?? block.type;\n return `${label} ${index + 1}`;\n}\n\nwatch(\n () => props.visible,\n (visible) => {\n if (visible) {\n moduleName.value = \"\";\n error.value = null;\n selectedBlockIds.value = new Set(\n props.preSelectedBlockId ? [props.preSelectedBlockId] : [],\n );\n }\n },\n);\n\nfunction toggleBlock(blockId: string): void {\n const newSet = new Set(selectedBlockIds.value);\n if (newSet.has(blockId)) {\n newSet.delete(blockId);\n } else {\n newSet.add(blockId);\n }\n selectedBlockIds.value = newSet;\n}\n\nconst canSave = computed(\n () =>\n moduleName.value.trim().length > 0 &&\n selectedBlockIds.value.size > 0 &&\n !isSaving.value,\n);\n\nasync function handleSave(): Promise<void> {\n if (!canSave.value) return;\n\n isSaving.value = true;\n error.value = null;\n\n try {\n const selectedBlocks = topLevelBlocks.value.filter((b) =>\n selectedBlockIds.value.has(b.id),\n );\n await savedModules.createModule(moduleName.value.trim(), selectedBlocks);\n emit(\"saved\");\n emit(\"close\");\n } catch (err) {\n error.value = (err as Error).message;\n } finally {\n isSaving.value = false;\n }\n}\n\nfunction handleClose(): void {\n if (!isSaving.value) {\n emit(\"close\");\n }\n}\n\nfunction handleKeydown(event: KeyboardEvent): void {\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n handleSave();\n }\n if (event.key === \"Escape\") {\n handleClose();\n }\n}\n</script>\n\n<template>\n <TplModal :visible=\"visible\" @close=\"handleClose\" @keydown=\"handleKeydown\">\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n :aria-busy=\"isSaving\"\n aria-labelledby=\"tpl-save-module-title\"\n class=\"tpl-scale-in tpl:mx-4 tpl:w-full tpl:max-w-sm tpl:rounded-[var(--tpl-radius-lg)] tpl:p-5\"\n style=\"\n background-color: var(--tpl-bg-elevated);\n box-shadow: var(--tpl-shadow-xl);\n \"\n >\n <h3\n id=\"tpl-save-module-title\"\n class=\"tpl:mb-4 tpl:text-sm tpl:font-semibold tpl:text-[var(--tpl-text)]\"\n >\n {{ cloudT.modules.saveAsModule }}\n </h3>\n\n <!-- Module name -->\n <div class=\"tpl:mb-3\">\n <label\n class=\"tpl:mb-1.5 tpl:block tpl:text-sm tpl:font-medium tpl:text-[var(--tpl-text-muted)]\"\n >\n {{ cloudT.modules.moduleName }}\n </label>\n <input\n v-model=\"moduleName\"\n type=\"text\"\n :placeholder=\"cloudT.modules.moduleNamePlaceholder\"\n class=\"tpl:h-9 tpl:w-full tpl:rounded-md tpl:border tpl:px-3 tpl:py-1 tpl:text-sm tpl:shadow-xs tpl:outline-none tpl:border-[var(--tpl-border)] tpl:bg-[var(--tpl-bg)] tpl:text-[var(--tpl-text)]\"\n :disabled=\"isSaving\"\n />\n </div>\n\n <!-- Block selection -->\n <div class=\"tpl:mb-3\">\n <label\n class=\"tpl:mb-1.5 tpl:block tpl:text-sm tpl:font-medium tpl:text-[var(--tpl-text-muted)]\"\n >\n {{ cloudT.modules.selectBlocks }}\n </label>\n <div\n class=\"tpl:max-h-40 tpl:space-y-1 tpl:overflow-y-auto tpl:rounded-md tpl:border tpl:p-2 tpl:border-[var(--tpl-border)]\"\n >\n <label\n v-for=\"(block, index) in topLevelBlocks\"\n :key=\"block.id\"\n class=\"tpl:flex tpl:cursor-pointer tpl:items-center tpl:gap-2 tpl:rounded-sm tpl:px-2 tpl:py-1.5 tpl:text-sm tpl:transition-colors tpl:duration-100\"\n :style=\"{\n color: 'var(--tpl-text)',\n backgroundColor: selectedBlockIds.has(block.id)\n ? 'var(--tpl-primary-light)'\n : 'transparent',\n }\"\n >\n <input\n type=\"checkbox\"\n :checked=\"selectedBlockIds.has(block.id)\"\n class=\"tpl:accent-[var(--tpl-primary)]\"\n :disabled=\"isSaving\"\n @change=\"toggleBlock(block.id)\"\n />\n {{ blockLabel(block, index) }}\n </label>\n </div>\n </div>\n\n <!-- Error message -->\n <p\n v-if=\"error\"\n role=\"alert\"\n class=\"tpl:mb-3 tpl:text-xs tpl:text-[var(--tpl-danger)]\"\n >\n {{ error }}\n </p>\n\n <!-- Actions -->\n <div class=\"tpl:flex tpl:justify-end tpl:gap-2\">\n <button\n type=\"button\"\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:border tpl:px-3 tpl:py-1.5 tpl:text-sm tpl:font-medium tpl:shadow-xs tpl:transition-all tpl:duration-150 tpl:border-[var(--tpl-border)] tpl:text-[var(--tpl-text)] tpl:bg-[var(--tpl-bg)]\"\n :disabled=\"isSaving\"\n :class=\"{\n 'tpl:cursor-not-allowed tpl:opacity-50': isSaving,\n }\"\n @click=\"handleClose\"\n >\n {{ cloudT.modules.cancel }}\n </button>\n <button\n type=\"button\"\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:px-3 tpl:py-1.5 tpl:text-sm tpl:font-medium tpl:shadow-xs tpl:transition-all tpl:duration-150 tpl:hover:opacity-90 tpl:disabled:cursor-not-allowed tpl:disabled:opacity-50 tpl:bg-[var(--tpl-primary)] tpl:text-[var(--tpl-bg)]\"\n :disabled=\"!canSave\"\n @click=\"handleSave\"\n >\n <span v-if=\"isSaving\" class=\"tpl:flex tpl:items-center tpl:gap-1.5\">\n <LoaderCircle\n class=\"tpl:animate-spin\"\n :size=\"12\"\n :stroke-width=\"2\"\n />\n {{ cloudT.modules.saving }}\n </span>\n <span v-else>\n {{ cloudT.modules.save }}\n </span>\n </button>\n </div>\n </div>\n </TplModal>\n</template>\n","<script setup lang=\"ts\">\nimport TplModal from \"../../components/TplModal.vue\";\nimport { useI18n } from \"../../composables\";\nimport { useCloudI18nStrict } from \"../../composables\";\nimport {\n EDITOR_KEY,\n SAVED_MODULES_HEADLESS_KEY,\n requireInject,\n} from \"../../keys\";\nimport type { Block } from \"@templatical/types\";\nimport { LoaderCircle } from \"@lucide/vue\";\nimport { computed, ref, watch } from \"vue\";\n\nconst props = defineProps<{\n visible: boolean;\n preSelectedBlockId: string | null;\n}>();\n\nconst emit = defineEmits<{\n (e: \"close\"): void;\n (e: \"saved\"): void;\n}>();\n\nconst { t } = useI18n();\nconst { t: cloudT } = useCloudI18nStrict();\nconst editor = requireInject(EDITOR_KEY, \"SaveModuleDialog\");\nconst savedModules = requireInject(\n SAVED_MODULES_HEADLESS_KEY,\n \"SaveModuleDialog\",\n);\n\nconst moduleName = ref(\"\");\nconst selectedBlockIds = ref<Set<string>>(new Set());\nconst isSaving = ref(false);\nconst error = ref<string | null>(null);\n\nconst topLevelBlocks = computed(() => editor.content.value.blocks);\n\nfunction blockLabel(block: Block, index: number): string {\n const typeKey = block.type as keyof typeof t.blocks;\n const label = t.blocks[typeKey] ?? block.type;\n return `${label} ${index + 1}`;\n}\n\nwatch(\n () => props.visible,\n (visible) => {\n if (visible) {\n moduleName.value = \"\";\n error.value = null;\n selectedBlockIds.value = new Set(\n props.preSelectedBlockId ? [props.preSelectedBlockId] : [],\n );\n }\n },\n);\n\nfunction toggleBlock(blockId: string): void {\n const newSet = new Set(selectedBlockIds.value);\n if (newSet.has(blockId)) {\n newSet.delete(blockId);\n } else {\n newSet.add(blockId);\n }\n selectedBlockIds.value = newSet;\n}\n\nconst canSave = computed(\n () =>\n moduleName.value.trim().length > 0 &&\n selectedBlockIds.value.size > 0 &&\n !isSaving.value,\n);\n\nasync function handleSave(): Promise<void> {\n if (!canSave.value) return;\n\n isSaving.value = true;\n error.value = null;\n\n try {\n const selectedBlocks = topLevelBlocks.value.filter((b) =>\n selectedBlockIds.value.has(b.id),\n );\n await savedModules.createModule(moduleName.value.trim(), selectedBlocks);\n emit(\"saved\");\n emit(\"close\");\n } catch (err) {\n error.value = (err as Error).message;\n } finally {\n isSaving.value = false;\n }\n}\n\nfunction handleClose(): void {\n if (!isSaving.value) {\n emit(\"close\");\n }\n}\n\nfunction handleKeydown(event: KeyboardEvent): void {\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n handleSave();\n }\n if (event.key === \"Escape\") {\n handleClose();\n }\n}\n</script>\n\n<template>\n <TplModal :visible=\"visible\" @close=\"handleClose\" @keydown=\"handleKeydown\">\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n :aria-busy=\"isSaving\"\n aria-labelledby=\"tpl-save-module-title\"\n class=\"tpl-scale-in tpl:mx-4 tpl:w-full tpl:max-w-sm tpl:rounded-[var(--tpl-radius-lg)] tpl:p-5\"\n style=\"\n background-color: var(--tpl-bg-elevated);\n box-shadow: var(--tpl-shadow-xl);\n \"\n >\n <h3\n id=\"tpl-save-module-title\"\n class=\"tpl:mb-4 tpl:text-sm tpl:font-semibold tpl:text-[var(--tpl-text)]\"\n >\n {{ cloudT.modules.saveAsModule }}\n </h3>\n\n <!-- Module name -->\n <div class=\"tpl:mb-3\">\n <label\n class=\"tpl:mb-1.5 tpl:block tpl:text-sm tpl:font-medium tpl:text-[var(--tpl-text-muted)]\"\n >\n {{ cloudT.modules.moduleName }}\n </label>\n <input\n v-model=\"moduleName\"\n type=\"text\"\n :placeholder=\"cloudT.modules.moduleNamePlaceholder\"\n class=\"tpl:h-9 tpl:w-full tpl:rounded-md tpl:border tpl:px-3 tpl:py-1 tpl:text-sm tpl:shadow-xs tpl:outline-none tpl:border-[var(--tpl-border)] tpl:bg-[var(--tpl-bg)] tpl:text-[var(--tpl-text)]\"\n :disabled=\"isSaving\"\n />\n </div>\n\n <!-- Block selection -->\n <div class=\"tpl:mb-3\">\n <label\n class=\"tpl:mb-1.5 tpl:block tpl:text-sm tpl:font-medium tpl:text-[var(--tpl-text-muted)]\"\n >\n {{ cloudT.modules.selectBlocks }}\n </label>\n <div\n class=\"tpl:max-h-40 tpl:space-y-1 tpl:overflow-y-auto tpl:rounded-md tpl:border tpl:p-2 tpl:border-[var(--tpl-border)]\"\n >\n <label\n v-for=\"(block, index) in topLevelBlocks\"\n :key=\"block.id\"\n class=\"tpl:flex tpl:cursor-pointer tpl:items-center tpl:gap-2 tpl:rounded-sm tpl:px-2 tpl:py-1.5 tpl:text-sm tpl:transition-colors tpl:duration-100\"\n :style=\"{\n color: 'var(--tpl-text)',\n backgroundColor: selectedBlockIds.has(block.id)\n ? 'var(--tpl-primary-light)'\n : 'transparent',\n }\"\n >\n <input\n type=\"checkbox\"\n :checked=\"selectedBlockIds.has(block.id)\"\n class=\"tpl:accent-[var(--tpl-primary)]\"\n :disabled=\"isSaving\"\n @change=\"toggleBlock(block.id)\"\n />\n {{ blockLabel(block, index) }}\n </label>\n </div>\n </div>\n\n <!-- Error message -->\n <p\n v-if=\"error\"\n role=\"alert\"\n class=\"tpl:mb-3 tpl:text-xs tpl:text-[var(--tpl-danger)]\"\n >\n {{ error }}\n </p>\n\n <!-- Actions -->\n <div class=\"tpl:flex tpl:justify-end tpl:gap-2\">\n <button\n type=\"button\"\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:border tpl:px-3 tpl:py-1.5 tpl:text-sm tpl:font-medium tpl:shadow-xs tpl:transition-all tpl:duration-150 tpl:border-[var(--tpl-border)] tpl:text-[var(--tpl-text)] tpl:bg-[var(--tpl-bg)]\"\n :disabled=\"isSaving\"\n :class=\"{\n 'tpl:cursor-not-allowed tpl:opacity-50': isSaving,\n }\"\n @click=\"handleClose\"\n >\n {{ cloudT.modules.cancel }}\n </button>\n <button\n type=\"button\"\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:px-3 tpl:py-1.5 tpl:text-sm tpl:font-medium tpl:shadow-xs tpl:transition-all tpl:duration-150 tpl:hover:opacity-90 tpl:disabled:cursor-not-allowed tpl:disabled:opacity-50 tpl:bg-[var(--tpl-primary)] tpl:text-[var(--tpl-bg)]\"\n :disabled=\"!canSave\"\n @click=\"handleSave\"\n >\n <span v-if=\"isSaving\" class=\"tpl:flex tpl:items-center tpl:gap-1.5\">\n <LoaderCircle\n class=\"tpl:animate-spin\"\n :size=\"12\"\n :stroke-width=\"2\"\n />\n {{ cloudT.modules.saving }}\n </span>\n <span v-else>\n {{ cloudT.modules.save }}\n </span>\n </button>\n </div>\n </div>\n </TplModal>\n</template>\n"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { K as e, M as t, T as n, ct as r, d as i, f as a, g as o, h as s, it as c, m as l, ot as u, p as d, st as ee, u as f, v as p, x as m, y as h } from "./draggable-D840DIZB.js";
|
|
2
|
-
import {
|
|
3
|
-
import { B as ae, H as oe, X as se, Z as ce, b as x } from "./icons-
|
|
4
|
-
import { n as S, t as C } from "./RichTextEditorContent-
|
|
2
|
+
import { St as te, X as ne, Z as re, cn as g, en as _, k as v, tn as y, un as b, zt as ie } from "./features-Dwb5aTLg.js";
|
|
3
|
+
import { B as ae, H as oe, X as se, Z as ce, b as x } from "./icons-Dhqh5lYQ.js";
|
|
4
|
+
import { n as S, t as C } from "./RichTextEditorContent-7RZe4tbj.js";
|
|
5
5
|
//#region src/components/blocks/TitleEditor.vue?vue&type=script&setup=true&lang.ts
|
|
6
6
|
var w = { class: "tpl-text-editor-wrapper tpl:relative" }, T = ["data-tpl-theme", "aria-label"], E = ["aria-label", "title"], D = ["aria-label", "title"], O = ["aria-label", "title"], k = {
|
|
7
7
|
key: 0,
|
|
@@ -20,7 +20,7 @@ var w = { class: "tpl-text-editor-wrapper tpl:relative" }, T = ["data-tpl-theme"
|
|
|
20
20
|
},
|
|
21
21
|
emits: ["done"],
|
|
22
22
|
setup(m, { emit: P }) {
|
|
23
|
-
let F = m, I = P, L = n(
|
|
23
|
+
let F = m, I = P, L = n(g, null), R = n(b, null), z = v(), B = n(y, null), le = n(_, null), V = a(() => (B?.isOpen.value ?? !1) || (le?.isOpen.value ?? !1)), { t: H } = ie(), { editor: U, EditorContent: W, isLoading: G, initError: ue, retry: de, showLinkDialog: fe, linkUrl: K, linkColor: q, linkDialogRef: J, canRequestMergeTag: Y, canInsertLogicTag: X, openLinkDialog: Z, insertLink: pe, removeLink: me, closeLinkDialog: he, handleLinkKeydown: ge, handleAddMergeTag: Q, handleAddLogicTag: $ } = ne({
|
|
24
24
|
blockId: () => F.block.id,
|
|
25
25
|
blockContent: () => F.block.content,
|
|
26
26
|
onDone: () => I("done"),
|
|
@@ -30,7 +30,7 @@ var w = { class: "tpl-text-editor-wrapper tpl:relative" }, T = ["data-tpl-theme"
|
|
|
30
30
|
import("./tiptap-zpXk5mN4.js").then((e) => e.r),
|
|
31
31
|
import("./tiptap-zpXk5mN4.js").then((e) => e.i),
|
|
32
32
|
import("./tiptap-zpXk5mN4.js").then((e) => e.l),
|
|
33
|
-
import("./extensions-
|
|
33
|
+
import("./extensions-Btyx_IMf.js")
|
|
34
34
|
]);
|
|
35
35
|
return {
|
|
36
36
|
TiptapEditor: a,
|
|
@@ -47,7 +47,7 @@ var w = { class: "tpl-text-editor-wrapper tpl:relative" }, T = ["data-tpl-theme"
|
|
|
47
47
|
strike: !1,
|
|
48
48
|
link: !1
|
|
49
49
|
}),
|
|
50
|
-
|
|
50
|
+
re(c).configure({
|
|
51
51
|
openOnClick: !1,
|
|
52
52
|
HTMLAttributes: {
|
|
53
53
|
target: "_blank",
|
|
@@ -144,7 +144,7 @@ var w = { class: "tpl-text-editor-wrapper tpl:relative" }, T = ["data-tpl-theme"
|
|
|
144
144
|
size: 16,
|
|
145
145
|
"stroke-width": 2
|
|
146
146
|
}), p(" " + r(c(H).logicTag.insertShort), 1)], 8, M)) : s("", !0)
|
|
147
|
-
], 64)) : (t(), o("div", N, [h(c(
|
|
147
|
+
], 64)) : (t(), o("div", N, [h(c(te), {
|
|
148
148
|
class: "tpl-spinner",
|
|
149
149
|
size: 14,
|
|
150
150
|
"stroke-width": 2
|
|
@@ -192,4 +192,4 @@ var w = { class: "tpl-text-editor-wrapper tpl:relative" }, T = ["data-tpl-theme"
|
|
|
192
192
|
//#endregion
|
|
193
193
|
export { P as default };
|
|
194
194
|
|
|
195
|
-
//# sourceMappingURL=TitleEditor-
|
|
195
|
+
//# sourceMappingURL=TitleEditor-Cqw2jvuc.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TitleEditor-CUKlo_Zj.js","names":[],"sources":["../../../src/components/blocks/TitleEditor.vue","../../../src/components/blocks/TitleEditor.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { useI18n } from \"../../composables\";\nimport { useRichTextEditor } from \"../../composables/useRichTextEditor\";\nimport { usePopoverRoot } from \"../../composables/usePopoverRoot\";\nimport type { TitleBlock as TitleBlockType } from \"@templatical/types\";\nimport {\n Bold,\n Braces,\n Italic,\n Link,\n LoaderCircle,\n ScanLine,\n} from \"@lucide/vue\";\nimport { computed, inject } from \"vue\";\nimport {\n THEME_STYLES_KEY,\n UI_THEME_KEY,\n MERGE_TAG_PICKER_KEY,\n LOGIC_TAG_PICKER_KEY,\n} from \"../../keys\";\nimport RichTextLinkDialog from \"./RichTextLinkDialog.vue\";\nimport RichTextEditorContent from \"./RichTextEditorContent.vue\";\nimport { withLinkColor } from \"../../utils/linkColorExtension\";\n\nconst props = defineProps<{\n block: TitleBlockType;\n toolbarPosition: { top: number; left: number };\n}>();\n\nconst emit = defineEmits<{\n (e: \"done\"): void;\n}>();\n\nconst themeStyles = inject(THEME_STYLES_KEY, null);\nconst tplUiTheme = inject(UI_THEME_KEY, null);\nconst popoverRoot = usePopoverRoot();\n// Hide the floating toolbar while either built-in picker modal is open — see\n// ParagraphToolbar.vue for the same rationale.\nconst picker = inject(MERGE_TAG_PICKER_KEY, null);\nconst logicPicker = inject(LOGIC_TAG_PICKER_KEY, null);\nconst pickerIsOpen = computed(\n () => (picker?.isOpen.value ?? false) || (logicPicker?.isOpen.value ?? false),\n);\n\nconst { t } = useI18n();\n\nconst {\n editor,\n EditorContent,\n isLoading,\n initError,\n retry,\n showLinkDialog,\n linkUrl,\n linkColor,\n linkDialogRef,\n canRequestMergeTag,\n canInsertLogicTag,\n openLinkDialog,\n insertLink,\n removeLink,\n closeLinkDialog,\n handleLinkKeydown,\n handleAddMergeTag,\n handleAddLogicTag,\n} = useRichTextEditor({\n blockId: () => props.block.id,\n blockContent: () => props.block.content,\n onDone: () => emit(\"done\"),\n editorName: \"TitleEditor\",\n async loadExtensions({\n mergeTags,\n syntax,\n triggerChar,\n autocompleteEnabled,\n suggestionEmptyText,\n }) {\n const [\n { Editor: TiptapEditor, EditorContent: EC },\n { default: StarterKit },\n { default: LinkExt },\n { MergeTagNode, MergeTagSuggestion, LogicMergeTagNode },\n ] = await Promise.all([\n import(\"@tiptap/vue-3\"),\n import(\"@tiptap/starter-kit\"),\n import(\"@tiptap/extension-link\"),\n import(\"../../extensions\"),\n ]);\n\n return {\n TiptapEditor,\n EC,\n extensions: [\n StarterKit.configure({\n heading: false,\n codeBlock: false,\n blockquote: false,\n horizontalRule: false,\n bulletList: false,\n orderedList: false,\n listItem: false,\n strike: false,\n // StarterKit bundles @tiptap/extension-link (openOnClick: true).\n // Disable it so the LinkExt below (openOnClick: false) is the only\n // link extension — otherwise clicking a link while editing opens it.\n link: false,\n }),\n withLinkColor(LinkExt).configure({\n openOnClick: false,\n HTMLAttributes: {\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n },\n }),\n MergeTagNode.configure({ mergeTags, syntax }),\n LogicMergeTagNode.configure({ syntax }),\n ...(autocompleteEnabled && triggerChar && mergeTags.length > 0\n ? [\n MergeTagSuggestion.configure({\n mergeTags,\n char: triggerChar,\n emptyText: suggestionEmptyText,\n popoverRoot,\n }),\n ]\n : []),\n ],\n };\n },\n});\n</script>\n\n<template>\n <div class=\"tpl-text-editor-wrapper tpl:relative\">\n <Teleport v-if=\"popoverRoot && !pickerIsOpen\" :to=\"popoverRoot\">\n <div\n :data-tpl-theme=\"tplUiTheme\"\n role=\"toolbar\"\n :aria-label=\"t.titleEditor.toolbar\"\n class=\"tpl tpl-text-toolbar tpl:fixed tpl:z-popover tpl:flex tpl:items-center tpl:gap-1 tpl:rounded-lg tpl:border tpl:border-[var(--tpl-border)] tpl:bg-[var(--tpl-bg)] tpl:px-3 tpl:py-2 tpl:shadow-lg\"\n :style=\"{\n ...themeStyles,\n top: `${toolbarPosition.top}px`,\n left: `${toolbarPosition.left}px`,\n transform: 'translateY(-100%)',\n }\"\n >\n <template v-if=\"!isLoading && editor\">\n <!-- Bold -->\n <button\n type=\"button\"\n class=\"tpl-text-toolbar-btn\"\n :class=\"{\n 'tpl-text-toolbar-btn--active': editor?.isActive('bold'),\n }\"\n :aria-label=\"t.titleEditor.bold\"\n :title=\"t.titleEditor.bold\"\n @click=\"editor?.chain().focus().toggleBold().run()\"\n >\n <Bold :size=\"16\" :stroke-width=\"2.5\" />\n </button>\n <!-- Italic -->\n <button\n type=\"button\"\n class=\"tpl-text-toolbar-btn\"\n :class=\"{\n 'tpl-text-toolbar-btn--active': editor?.isActive('italic'),\n }\"\n :aria-label=\"t.titleEditor.italic\"\n :title=\"t.titleEditor.italic\"\n @click=\"editor?.chain().focus().toggleItalic().run()\"\n >\n <Italic :size=\"16\" :stroke-width=\"2\" />\n </button>\n <span\n class=\"tpl:mx-1.5 tpl:h-6 tpl:w-px tpl:bg-[var(--tpl-border)]\"\n aria-hidden=\"true\"\n ></span>\n <!-- Link -->\n <button\n type=\"button\"\n class=\"tpl-text-toolbar-btn\"\n :class=\"{\n 'tpl-text-toolbar-btn--active': editor?.isActive('link'),\n }\"\n :aria-label=\"t.titleEditor.addLink\"\n :title=\"t.titleEditor.addLink\"\n @click=\"openLinkDialog\"\n >\n <Link :size=\"16\" :stroke-width=\"2\" />\n </button>\n <!-- Add Merge Tag -->\n <span\n v-if=\"canRequestMergeTag\"\n class=\"tpl:mx-1.5 tpl:h-6 tpl:w-px tpl:bg-[var(--tpl-border)]\"\n ></span>\n <button\n v-if=\"canRequestMergeTag\"\n type=\"button\"\n class=\"tpl:flex tpl:h-8 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:gap-1.5 tpl:rounded tpl:border-none tpl:bg-transparent tpl:px-2.5 tpl:text-xs tpl:font-medium tpl:text-[var(--tpl-text)] tpl:transition-all tpl:duration-150 tpl:hover:bg-[var(--tpl-bg-active)]\"\n :aria-label=\"t.mergeTag.insert\"\n :title=\"t.mergeTag.insert\"\n @click=\"handleAddMergeTag\"\n >\n <ScanLine :size=\"16\" :stroke-width=\"2\" />\n {{ t.mergeTag.insertShort }}\n </button>\n <!-- Insert Logic -->\n <span\n v-if=\"canInsertLogicTag\"\n class=\"tpl:mx-1.5 tpl:h-6 tpl:w-px tpl:bg-[var(--tpl-border)]\"\n ></span>\n <button\n v-if=\"canInsertLogicTag\"\n type=\"button\"\n class=\"tpl:flex tpl:h-8 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:gap-1.5 tpl:rounded tpl:border-none tpl:bg-transparent tpl:px-2.5 tpl:text-xs tpl:font-medium tpl:text-[var(--tpl-text)] tpl:transition-all tpl:duration-150 tpl:hover:bg-[var(--tpl-bg-active)]\"\n :aria-label=\"t.logicTag.insert\"\n :title=\"t.logicTag.insert\"\n data-testid=\"insert-logic-button\"\n @click=\"handleAddLogicTag\"\n >\n <Braces :size=\"16\" :stroke-width=\"2\" />\n {{ t.logicTag.insertShort }}\n </button>\n </template>\n <template v-else>\n <div\n class=\"tpl:flex tpl:items-center tpl:gap-2 tpl:px-2 tpl:text-xs tpl:text-[var(--tpl-text-dim)]\"\n >\n <LoaderCircle class=\"tpl-spinner\" :size=\"14\" :stroke-width=\"2\" />\n {{ t.errors.editorLoading }}\n </div>\n </template>\n </div>\n </Teleport>\n\n <RichTextEditorContent\n :editor=\"editor\"\n :editor-content=\"EditorContent\"\n :is-loading=\"isLoading\"\n :init-error=\"initError\"\n @retry=\"retry\"\n />\n\n <RichTextLinkDialog\n :visible=\"showLinkDialog\"\n :is-editing-link=\"editor?.isActive('link') ?? false\"\n v-model:dialog-ref=\"linkDialogRef\"\n v-model:link-url=\"linkUrl\"\n v-model:link-color=\"linkColor\"\n @close=\"closeLinkDialog\"\n @insert=\"insertLink\"\n @remove=\"removeLink\"\n @keydown=\"handleLinkKeydown\"\n />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { useI18n } from \"../../composables\";\nimport { useRichTextEditor } from \"../../composables/useRichTextEditor\";\nimport { usePopoverRoot } from \"../../composables/usePopoverRoot\";\nimport type { TitleBlock as TitleBlockType } from \"@templatical/types\";\nimport {\n Bold,\n Braces,\n Italic,\n Link,\n LoaderCircle,\n ScanLine,\n} from \"@lucide/vue\";\nimport { computed, inject } from \"vue\";\nimport {\n THEME_STYLES_KEY,\n UI_THEME_KEY,\n MERGE_TAG_PICKER_KEY,\n LOGIC_TAG_PICKER_KEY,\n} from \"../../keys\";\nimport RichTextLinkDialog from \"./RichTextLinkDialog.vue\";\nimport RichTextEditorContent from \"./RichTextEditorContent.vue\";\nimport { withLinkColor } from \"../../utils/linkColorExtension\";\n\nconst props = defineProps<{\n block: TitleBlockType;\n toolbarPosition: { top: number; left: number };\n}>();\n\nconst emit = defineEmits<{\n (e: \"done\"): void;\n}>();\n\nconst themeStyles = inject(THEME_STYLES_KEY, null);\nconst tplUiTheme = inject(UI_THEME_KEY, null);\nconst popoverRoot = usePopoverRoot();\n// Hide the floating toolbar while either built-in picker modal is open — see\n// ParagraphToolbar.vue for the same rationale.\nconst picker = inject(MERGE_TAG_PICKER_KEY, null);\nconst logicPicker = inject(LOGIC_TAG_PICKER_KEY, null);\nconst pickerIsOpen = computed(\n () => (picker?.isOpen.value ?? false) || (logicPicker?.isOpen.value ?? false),\n);\n\nconst { t } = useI18n();\n\nconst {\n editor,\n EditorContent,\n isLoading,\n initError,\n retry,\n showLinkDialog,\n linkUrl,\n linkColor,\n linkDialogRef,\n canRequestMergeTag,\n canInsertLogicTag,\n openLinkDialog,\n insertLink,\n removeLink,\n closeLinkDialog,\n handleLinkKeydown,\n handleAddMergeTag,\n handleAddLogicTag,\n} = useRichTextEditor({\n blockId: () => props.block.id,\n blockContent: () => props.block.content,\n onDone: () => emit(\"done\"),\n editorName: \"TitleEditor\",\n async loadExtensions({\n mergeTags,\n syntax,\n triggerChar,\n autocompleteEnabled,\n suggestionEmptyText,\n }) {\n const [\n { Editor: TiptapEditor, EditorContent: EC },\n { default: StarterKit },\n { default: LinkExt },\n { MergeTagNode, MergeTagSuggestion, LogicMergeTagNode },\n ] = await Promise.all([\n import(\"@tiptap/vue-3\"),\n import(\"@tiptap/starter-kit\"),\n import(\"@tiptap/extension-link\"),\n import(\"../../extensions\"),\n ]);\n\n return {\n TiptapEditor,\n EC,\n extensions: [\n StarterKit.configure({\n heading: false,\n codeBlock: false,\n blockquote: false,\n horizontalRule: false,\n bulletList: false,\n orderedList: false,\n listItem: false,\n strike: false,\n // StarterKit bundles @tiptap/extension-link (openOnClick: true).\n // Disable it so the LinkExt below (openOnClick: false) is the only\n // link extension — otherwise clicking a link while editing opens it.\n link: false,\n }),\n withLinkColor(LinkExt).configure({\n openOnClick: false,\n HTMLAttributes: {\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n },\n }),\n MergeTagNode.configure({ mergeTags, syntax }),\n LogicMergeTagNode.configure({ syntax }),\n ...(autocompleteEnabled && triggerChar && mergeTags.length > 0\n ? [\n MergeTagSuggestion.configure({\n mergeTags,\n char: triggerChar,\n emptyText: suggestionEmptyText,\n popoverRoot,\n }),\n ]\n : []),\n ],\n };\n },\n});\n</script>\n\n<template>\n <div class=\"tpl-text-editor-wrapper tpl:relative\">\n <Teleport v-if=\"popoverRoot && !pickerIsOpen\" :to=\"popoverRoot\">\n <div\n :data-tpl-theme=\"tplUiTheme\"\n role=\"toolbar\"\n :aria-label=\"t.titleEditor.toolbar\"\n class=\"tpl tpl-text-toolbar tpl:fixed tpl:z-popover tpl:flex tpl:items-center tpl:gap-1 tpl:rounded-lg tpl:border tpl:border-[var(--tpl-border)] tpl:bg-[var(--tpl-bg)] tpl:px-3 tpl:py-2 tpl:shadow-lg\"\n :style=\"{\n ...themeStyles,\n top: `${toolbarPosition.top}px`,\n left: `${toolbarPosition.left}px`,\n transform: 'translateY(-100%)',\n }\"\n >\n <template v-if=\"!isLoading && editor\">\n <!-- Bold -->\n <button\n type=\"button\"\n class=\"tpl-text-toolbar-btn\"\n :class=\"{\n 'tpl-text-toolbar-btn--active': editor?.isActive('bold'),\n }\"\n :aria-label=\"t.titleEditor.bold\"\n :title=\"t.titleEditor.bold\"\n @click=\"editor?.chain().focus().toggleBold().run()\"\n >\n <Bold :size=\"16\" :stroke-width=\"2.5\" />\n </button>\n <!-- Italic -->\n <button\n type=\"button\"\n class=\"tpl-text-toolbar-btn\"\n :class=\"{\n 'tpl-text-toolbar-btn--active': editor?.isActive('italic'),\n }\"\n :aria-label=\"t.titleEditor.italic\"\n :title=\"t.titleEditor.italic\"\n @click=\"editor?.chain().focus().toggleItalic().run()\"\n >\n <Italic :size=\"16\" :stroke-width=\"2\" />\n </button>\n <span\n class=\"tpl:mx-1.5 tpl:h-6 tpl:w-px tpl:bg-[var(--tpl-border)]\"\n aria-hidden=\"true\"\n ></span>\n <!-- Link -->\n <button\n type=\"button\"\n class=\"tpl-text-toolbar-btn\"\n :class=\"{\n 'tpl-text-toolbar-btn--active': editor?.isActive('link'),\n }\"\n :aria-label=\"t.titleEditor.addLink\"\n :title=\"t.titleEditor.addLink\"\n @click=\"openLinkDialog\"\n >\n <Link :size=\"16\" :stroke-width=\"2\" />\n </button>\n <!-- Add Merge Tag -->\n <span\n v-if=\"canRequestMergeTag\"\n class=\"tpl:mx-1.5 tpl:h-6 tpl:w-px tpl:bg-[var(--tpl-border)]\"\n ></span>\n <button\n v-if=\"canRequestMergeTag\"\n type=\"button\"\n class=\"tpl:flex tpl:h-8 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:gap-1.5 tpl:rounded tpl:border-none tpl:bg-transparent tpl:px-2.5 tpl:text-xs tpl:font-medium tpl:text-[var(--tpl-text)] tpl:transition-all tpl:duration-150 tpl:hover:bg-[var(--tpl-bg-active)]\"\n :aria-label=\"t.mergeTag.insert\"\n :title=\"t.mergeTag.insert\"\n @click=\"handleAddMergeTag\"\n >\n <ScanLine :size=\"16\" :stroke-width=\"2\" />\n {{ t.mergeTag.insertShort }}\n </button>\n <!-- Insert Logic -->\n <span\n v-if=\"canInsertLogicTag\"\n class=\"tpl:mx-1.5 tpl:h-6 tpl:w-px tpl:bg-[var(--tpl-border)]\"\n ></span>\n <button\n v-if=\"canInsertLogicTag\"\n type=\"button\"\n class=\"tpl:flex tpl:h-8 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:gap-1.5 tpl:rounded tpl:border-none tpl:bg-transparent tpl:px-2.5 tpl:text-xs tpl:font-medium tpl:text-[var(--tpl-text)] tpl:transition-all tpl:duration-150 tpl:hover:bg-[var(--tpl-bg-active)]\"\n :aria-label=\"t.logicTag.insert\"\n :title=\"t.logicTag.insert\"\n data-testid=\"insert-logic-button\"\n @click=\"handleAddLogicTag\"\n >\n <Braces :size=\"16\" :stroke-width=\"2\" />\n {{ t.logicTag.insertShort }}\n </button>\n </template>\n <template v-else>\n <div\n class=\"tpl:flex tpl:items-center tpl:gap-2 tpl:px-2 tpl:text-xs tpl:text-[var(--tpl-text-dim)]\"\n >\n <LoaderCircle class=\"tpl-spinner\" :size=\"14\" :stroke-width=\"2\" />\n {{ t.errors.editorLoading }}\n </div>\n </template>\n </div>\n </Teleport>\n\n <RichTextEditorContent\n :editor=\"editor\"\n :editor-content=\"EditorContent\"\n :is-loading=\"isLoading\"\n :init-error=\"initError\"\n @retry=\"retry\"\n />\n\n <RichTextLinkDialog\n :visible=\"showLinkDialog\"\n :is-editing-link=\"editor?.isActive('link') ?? false\"\n v-model:dialog-ref=\"linkDialogRef\"\n v-model:link-url=\"linkUrl\"\n v-model:link-color=\"linkColor\"\n @close=\"closeLinkDialog\"\n @insert=\"insertLink\"\n @remove=\"removeLink\"\n @keydown=\"handleLinkKeydown\"\n />\n </div>\n</template>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TitleEditor-Cqw2jvuc.js","names":[],"sources":["../../../src/components/blocks/TitleEditor.vue","../../../src/components/blocks/TitleEditor.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { useI18n } from \"../../composables\";\nimport { useRichTextEditor } from \"../../composables/useRichTextEditor\";\nimport { usePopoverRoot } from \"../../composables/usePopoverRoot\";\nimport type { TitleBlock as TitleBlockType } from \"@templatical/types\";\nimport {\n Bold,\n Braces,\n Italic,\n Link,\n LoaderCircle,\n ScanLine,\n} from \"@lucide/vue\";\nimport { computed, inject } from \"vue\";\nimport {\n THEME_STYLES_KEY,\n UI_THEME_KEY,\n MERGE_TAG_PICKER_KEY,\n LOGIC_TAG_PICKER_KEY,\n} from \"../../keys\";\nimport RichTextLinkDialog from \"./RichTextLinkDialog.vue\";\nimport RichTextEditorContent from \"./RichTextEditorContent.vue\";\nimport { withLinkColor } from \"../../utils/linkColorExtension\";\n\nconst props = defineProps<{\n block: TitleBlockType;\n toolbarPosition: { top: number; left: number };\n}>();\n\nconst emit = defineEmits<{\n (e: \"done\"): void;\n}>();\n\nconst themeStyles = inject(THEME_STYLES_KEY, null);\nconst tplUiTheme = inject(UI_THEME_KEY, null);\nconst popoverRoot = usePopoverRoot();\n// Hide the floating toolbar while either built-in picker modal is open — see\n// ParagraphToolbar.vue for the same rationale.\nconst picker = inject(MERGE_TAG_PICKER_KEY, null);\nconst logicPicker = inject(LOGIC_TAG_PICKER_KEY, null);\nconst pickerIsOpen = computed(\n () => (picker?.isOpen.value ?? false) || (logicPicker?.isOpen.value ?? false),\n);\n\nconst { t } = useI18n();\n\nconst {\n editor,\n EditorContent,\n isLoading,\n initError,\n retry,\n showLinkDialog,\n linkUrl,\n linkColor,\n linkDialogRef,\n canRequestMergeTag,\n canInsertLogicTag,\n openLinkDialog,\n insertLink,\n removeLink,\n closeLinkDialog,\n handleLinkKeydown,\n handleAddMergeTag,\n handleAddLogicTag,\n} = useRichTextEditor({\n blockId: () => props.block.id,\n blockContent: () => props.block.content,\n onDone: () => emit(\"done\"),\n editorName: \"TitleEditor\",\n async loadExtensions({\n mergeTags,\n syntax,\n triggerChar,\n autocompleteEnabled,\n suggestionEmptyText,\n }) {\n const [\n { Editor: TiptapEditor, EditorContent: EC },\n { default: StarterKit },\n { default: LinkExt },\n { MergeTagNode, MergeTagSuggestion, LogicMergeTagNode },\n ] = await Promise.all([\n import(\"@tiptap/vue-3\"),\n import(\"@tiptap/starter-kit\"),\n import(\"@tiptap/extension-link\"),\n import(\"../../extensions\"),\n ]);\n\n return {\n TiptapEditor,\n EC,\n extensions: [\n StarterKit.configure({\n heading: false,\n codeBlock: false,\n blockquote: false,\n horizontalRule: false,\n bulletList: false,\n orderedList: false,\n listItem: false,\n strike: false,\n // StarterKit bundles @tiptap/extension-link (openOnClick: true).\n // Disable it so the LinkExt below (openOnClick: false) is the only\n // link extension — otherwise clicking a link while editing opens it.\n link: false,\n }),\n withLinkColor(LinkExt).configure({\n openOnClick: false,\n HTMLAttributes: {\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n },\n }),\n MergeTagNode.configure({ mergeTags, syntax }),\n LogicMergeTagNode.configure({ syntax }),\n ...(autocompleteEnabled && triggerChar && mergeTags.length > 0\n ? [\n MergeTagSuggestion.configure({\n mergeTags,\n char: triggerChar,\n emptyText: suggestionEmptyText,\n popoverRoot,\n }),\n ]\n : []),\n ],\n };\n },\n});\n</script>\n\n<template>\n <div class=\"tpl-text-editor-wrapper tpl:relative\">\n <Teleport v-if=\"popoverRoot && !pickerIsOpen\" :to=\"popoverRoot\">\n <div\n :data-tpl-theme=\"tplUiTheme\"\n role=\"toolbar\"\n :aria-label=\"t.titleEditor.toolbar\"\n class=\"tpl tpl-text-toolbar tpl:fixed tpl:z-popover tpl:flex tpl:items-center tpl:gap-1 tpl:rounded-lg tpl:border tpl:border-[var(--tpl-border)] tpl:bg-[var(--tpl-bg)] tpl:px-3 tpl:py-2 tpl:shadow-lg\"\n :style=\"{\n ...themeStyles,\n top: `${toolbarPosition.top}px`,\n left: `${toolbarPosition.left}px`,\n transform: 'translateY(-100%)',\n }\"\n >\n <template v-if=\"!isLoading && editor\">\n <!-- Bold -->\n <button\n type=\"button\"\n class=\"tpl-text-toolbar-btn\"\n :class=\"{\n 'tpl-text-toolbar-btn--active': editor?.isActive('bold'),\n }\"\n :aria-label=\"t.titleEditor.bold\"\n :title=\"t.titleEditor.bold\"\n @click=\"editor?.chain().focus().toggleBold().run()\"\n >\n <Bold :size=\"16\" :stroke-width=\"2.5\" />\n </button>\n <!-- Italic -->\n <button\n type=\"button\"\n class=\"tpl-text-toolbar-btn\"\n :class=\"{\n 'tpl-text-toolbar-btn--active': editor?.isActive('italic'),\n }\"\n :aria-label=\"t.titleEditor.italic\"\n :title=\"t.titleEditor.italic\"\n @click=\"editor?.chain().focus().toggleItalic().run()\"\n >\n <Italic :size=\"16\" :stroke-width=\"2\" />\n </button>\n <span\n class=\"tpl:mx-1.5 tpl:h-6 tpl:w-px tpl:bg-[var(--tpl-border)]\"\n aria-hidden=\"true\"\n ></span>\n <!-- Link -->\n <button\n type=\"button\"\n class=\"tpl-text-toolbar-btn\"\n :class=\"{\n 'tpl-text-toolbar-btn--active': editor?.isActive('link'),\n }\"\n :aria-label=\"t.titleEditor.addLink\"\n :title=\"t.titleEditor.addLink\"\n @click=\"openLinkDialog\"\n >\n <Link :size=\"16\" :stroke-width=\"2\" />\n </button>\n <!-- Add Merge Tag -->\n <span\n v-if=\"canRequestMergeTag\"\n class=\"tpl:mx-1.5 tpl:h-6 tpl:w-px tpl:bg-[var(--tpl-border)]\"\n ></span>\n <button\n v-if=\"canRequestMergeTag\"\n type=\"button\"\n class=\"tpl:flex tpl:h-8 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:gap-1.5 tpl:rounded tpl:border-none tpl:bg-transparent tpl:px-2.5 tpl:text-xs tpl:font-medium tpl:text-[var(--tpl-text)] tpl:transition-all tpl:duration-150 tpl:hover:bg-[var(--tpl-bg-active)]\"\n :aria-label=\"t.mergeTag.insert\"\n :title=\"t.mergeTag.insert\"\n @click=\"handleAddMergeTag\"\n >\n <ScanLine :size=\"16\" :stroke-width=\"2\" />\n {{ t.mergeTag.insertShort }}\n </button>\n <!-- Insert Logic -->\n <span\n v-if=\"canInsertLogicTag\"\n class=\"tpl:mx-1.5 tpl:h-6 tpl:w-px tpl:bg-[var(--tpl-border)]\"\n ></span>\n <button\n v-if=\"canInsertLogicTag\"\n type=\"button\"\n class=\"tpl:flex tpl:h-8 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:gap-1.5 tpl:rounded tpl:border-none tpl:bg-transparent tpl:px-2.5 tpl:text-xs tpl:font-medium tpl:text-[var(--tpl-text)] tpl:transition-all tpl:duration-150 tpl:hover:bg-[var(--tpl-bg-active)]\"\n :aria-label=\"t.logicTag.insert\"\n :title=\"t.logicTag.insert\"\n data-testid=\"insert-logic-button\"\n @click=\"handleAddLogicTag\"\n >\n <Braces :size=\"16\" :stroke-width=\"2\" />\n {{ t.logicTag.insertShort }}\n </button>\n </template>\n <template v-else>\n <div\n class=\"tpl:flex tpl:items-center tpl:gap-2 tpl:px-2 tpl:text-xs tpl:text-[var(--tpl-text-dim)]\"\n >\n <LoaderCircle class=\"tpl-spinner\" :size=\"14\" :stroke-width=\"2\" />\n {{ t.errors.editorLoading }}\n </div>\n </template>\n </div>\n </Teleport>\n\n <RichTextEditorContent\n :editor=\"editor\"\n :editor-content=\"EditorContent\"\n :is-loading=\"isLoading\"\n :init-error=\"initError\"\n @retry=\"retry\"\n />\n\n <RichTextLinkDialog\n :visible=\"showLinkDialog\"\n :is-editing-link=\"editor?.isActive('link') ?? false\"\n v-model:dialog-ref=\"linkDialogRef\"\n v-model:link-url=\"linkUrl\"\n v-model:link-color=\"linkColor\"\n @close=\"closeLinkDialog\"\n @insert=\"insertLink\"\n @remove=\"removeLink\"\n @keydown=\"handleLinkKeydown\"\n />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { useI18n } from \"../../composables\";\nimport { useRichTextEditor } from \"../../composables/useRichTextEditor\";\nimport { usePopoverRoot } from \"../../composables/usePopoverRoot\";\nimport type { TitleBlock as TitleBlockType } from \"@templatical/types\";\nimport {\n Bold,\n Braces,\n Italic,\n Link,\n LoaderCircle,\n ScanLine,\n} from \"@lucide/vue\";\nimport { computed, inject } from \"vue\";\nimport {\n THEME_STYLES_KEY,\n UI_THEME_KEY,\n MERGE_TAG_PICKER_KEY,\n LOGIC_TAG_PICKER_KEY,\n} from \"../../keys\";\nimport RichTextLinkDialog from \"./RichTextLinkDialog.vue\";\nimport RichTextEditorContent from \"./RichTextEditorContent.vue\";\nimport { withLinkColor } from \"../../utils/linkColorExtension\";\n\nconst props = defineProps<{\n block: TitleBlockType;\n toolbarPosition: { top: number; left: number };\n}>();\n\nconst emit = defineEmits<{\n (e: \"done\"): void;\n}>();\n\nconst themeStyles = inject(THEME_STYLES_KEY, null);\nconst tplUiTheme = inject(UI_THEME_KEY, null);\nconst popoverRoot = usePopoverRoot();\n// Hide the floating toolbar while either built-in picker modal is open — see\n// ParagraphToolbar.vue for the same rationale.\nconst picker = inject(MERGE_TAG_PICKER_KEY, null);\nconst logicPicker = inject(LOGIC_TAG_PICKER_KEY, null);\nconst pickerIsOpen = computed(\n () => (picker?.isOpen.value ?? false) || (logicPicker?.isOpen.value ?? false),\n);\n\nconst { t } = useI18n();\n\nconst {\n editor,\n EditorContent,\n isLoading,\n initError,\n retry,\n showLinkDialog,\n linkUrl,\n linkColor,\n linkDialogRef,\n canRequestMergeTag,\n canInsertLogicTag,\n openLinkDialog,\n insertLink,\n removeLink,\n closeLinkDialog,\n handleLinkKeydown,\n handleAddMergeTag,\n handleAddLogicTag,\n} = useRichTextEditor({\n blockId: () => props.block.id,\n blockContent: () => props.block.content,\n onDone: () => emit(\"done\"),\n editorName: \"TitleEditor\",\n async loadExtensions({\n mergeTags,\n syntax,\n triggerChar,\n autocompleteEnabled,\n suggestionEmptyText,\n }) {\n const [\n { Editor: TiptapEditor, EditorContent: EC },\n { default: StarterKit },\n { default: LinkExt },\n { MergeTagNode, MergeTagSuggestion, LogicMergeTagNode },\n ] = await Promise.all([\n import(\"@tiptap/vue-3\"),\n import(\"@tiptap/starter-kit\"),\n import(\"@tiptap/extension-link\"),\n import(\"../../extensions\"),\n ]);\n\n return {\n TiptapEditor,\n EC,\n extensions: [\n StarterKit.configure({\n heading: false,\n codeBlock: false,\n blockquote: false,\n horizontalRule: false,\n bulletList: false,\n orderedList: false,\n listItem: false,\n strike: false,\n // StarterKit bundles @tiptap/extension-link (openOnClick: true).\n // Disable it so the LinkExt below (openOnClick: false) is the only\n // link extension — otherwise clicking a link while editing opens it.\n link: false,\n }),\n withLinkColor(LinkExt).configure({\n openOnClick: false,\n HTMLAttributes: {\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n },\n }),\n MergeTagNode.configure({ mergeTags, syntax }),\n LogicMergeTagNode.configure({ syntax }),\n ...(autocompleteEnabled && triggerChar && mergeTags.length > 0\n ? [\n MergeTagSuggestion.configure({\n mergeTags,\n char: triggerChar,\n emptyText: suggestionEmptyText,\n popoverRoot,\n }),\n ]\n : []),\n ],\n };\n },\n});\n</script>\n\n<template>\n <div class=\"tpl-text-editor-wrapper tpl:relative\">\n <Teleport v-if=\"popoverRoot && !pickerIsOpen\" :to=\"popoverRoot\">\n <div\n :data-tpl-theme=\"tplUiTheme\"\n role=\"toolbar\"\n :aria-label=\"t.titleEditor.toolbar\"\n class=\"tpl tpl-text-toolbar tpl:fixed tpl:z-popover tpl:flex tpl:items-center tpl:gap-1 tpl:rounded-lg tpl:border tpl:border-[var(--tpl-border)] tpl:bg-[var(--tpl-bg)] tpl:px-3 tpl:py-2 tpl:shadow-lg\"\n :style=\"{\n ...themeStyles,\n top: `${toolbarPosition.top}px`,\n left: `${toolbarPosition.left}px`,\n transform: 'translateY(-100%)',\n }\"\n >\n <template v-if=\"!isLoading && editor\">\n <!-- Bold -->\n <button\n type=\"button\"\n class=\"tpl-text-toolbar-btn\"\n :class=\"{\n 'tpl-text-toolbar-btn--active': editor?.isActive('bold'),\n }\"\n :aria-label=\"t.titleEditor.bold\"\n :title=\"t.titleEditor.bold\"\n @click=\"editor?.chain().focus().toggleBold().run()\"\n >\n <Bold :size=\"16\" :stroke-width=\"2.5\" />\n </button>\n <!-- Italic -->\n <button\n type=\"button\"\n class=\"tpl-text-toolbar-btn\"\n :class=\"{\n 'tpl-text-toolbar-btn--active': editor?.isActive('italic'),\n }\"\n :aria-label=\"t.titleEditor.italic\"\n :title=\"t.titleEditor.italic\"\n @click=\"editor?.chain().focus().toggleItalic().run()\"\n >\n <Italic :size=\"16\" :stroke-width=\"2\" />\n </button>\n <span\n class=\"tpl:mx-1.5 tpl:h-6 tpl:w-px tpl:bg-[var(--tpl-border)]\"\n aria-hidden=\"true\"\n ></span>\n <!-- Link -->\n <button\n type=\"button\"\n class=\"tpl-text-toolbar-btn\"\n :class=\"{\n 'tpl-text-toolbar-btn--active': editor?.isActive('link'),\n }\"\n :aria-label=\"t.titleEditor.addLink\"\n :title=\"t.titleEditor.addLink\"\n @click=\"openLinkDialog\"\n >\n <Link :size=\"16\" :stroke-width=\"2\" />\n </button>\n <!-- Add Merge Tag -->\n <span\n v-if=\"canRequestMergeTag\"\n class=\"tpl:mx-1.5 tpl:h-6 tpl:w-px tpl:bg-[var(--tpl-border)]\"\n ></span>\n <button\n v-if=\"canRequestMergeTag\"\n type=\"button\"\n class=\"tpl:flex tpl:h-8 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:gap-1.5 tpl:rounded tpl:border-none tpl:bg-transparent tpl:px-2.5 tpl:text-xs tpl:font-medium tpl:text-[var(--tpl-text)] tpl:transition-all tpl:duration-150 tpl:hover:bg-[var(--tpl-bg-active)]\"\n :aria-label=\"t.mergeTag.insert\"\n :title=\"t.mergeTag.insert\"\n @click=\"handleAddMergeTag\"\n >\n <ScanLine :size=\"16\" :stroke-width=\"2\" />\n {{ t.mergeTag.insertShort }}\n </button>\n <!-- Insert Logic -->\n <span\n v-if=\"canInsertLogicTag\"\n class=\"tpl:mx-1.5 tpl:h-6 tpl:w-px tpl:bg-[var(--tpl-border)]\"\n ></span>\n <button\n v-if=\"canInsertLogicTag\"\n type=\"button\"\n class=\"tpl:flex tpl:h-8 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:gap-1.5 tpl:rounded tpl:border-none tpl:bg-transparent tpl:px-2.5 tpl:text-xs tpl:font-medium tpl:text-[var(--tpl-text)] tpl:transition-all tpl:duration-150 tpl:hover:bg-[var(--tpl-bg-active)]\"\n :aria-label=\"t.logicTag.insert\"\n :title=\"t.logicTag.insert\"\n data-testid=\"insert-logic-button\"\n @click=\"handleAddLogicTag\"\n >\n <Braces :size=\"16\" :stroke-width=\"2\" />\n {{ t.logicTag.insertShort }}\n </button>\n </template>\n <template v-else>\n <div\n class=\"tpl:flex tpl:items-center tpl:gap-2 tpl:px-2 tpl:text-xs tpl:text-[var(--tpl-text-dim)]\"\n >\n <LoaderCircle class=\"tpl-spinner\" :size=\"14\" :stroke-width=\"2\" />\n {{ t.errors.editorLoading }}\n </div>\n </template>\n </div>\n </Teleport>\n\n <RichTextEditorContent\n :editor=\"editor\"\n :editor-content=\"EditorContent\"\n :is-loading=\"isLoading\"\n :init-error=\"initError\"\n @retry=\"retry\"\n />\n\n <RichTextLinkDialog\n :visible=\"showLinkDialog\"\n :is-editing-link=\"editor?.isActive('link') ?? false\"\n v-model:dialog-ref=\"linkDialogRef\"\n v-model:link-url=\"linkUrl\"\n v-model:link-color=\"linkColor\"\n @close=\"closeLinkDialog\"\n @insert=\"insertLink\"\n @remove=\"removeLink\"\n @keydown=\"handleLinkKeydown\"\n />\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;EAwBA,IAAM,IAAQ,GAKR,IAAO,GAIP,IAAc,EAAO,GAAkB,IAAI,GAC3C,IAAa,EAAO,GAAc,IAAI,GACtC,IAAc,EAAe,GAG7B,IAAS,EAAO,GAAsB,IAAI,GAC1C,KAAc,EAAO,GAAsB,IAAI,GAC/C,IAAe,SACZ,GAAQ,OAAO,SAAS,QAAW,IAAa,OAAO,SAAS,GACzE,GAEM,EAAE,SAAM,GAAQ,GAEhB,EACJ,WACA,kBACA,cACA,eACA,WACA,oBACA,YACA,cACA,kBACA,uBACA,sBACA,mBACA,gBACA,gBACA,qBACA,uBACA,sBACA,yBACE,GAAkB;GACpB,eAAe,EAAM,MAAM;GAC3B,oBAAoB,EAAM,MAAM;GAChC,cAAc,EAAK,MAAM;GACzB,YAAY;GACZ,MAAM,eAAe,EACnB,cACA,WACA,gBACA,wBACA,0BACC;IACD,IAAM,CACJ,EAAE,QAAQ,GAAc,eAAe,KACvC,EAAE,SAAS,KACX,EAAE,SAAS,KACX,EAAE,iBAAc,uBAAoB,0BAClC,MAAM,QAAQ,IAAI;KACpB,OAAO,uBAAA,CAAA,MAAA,MAAA,EAAA,CAAA;KACP,OAAO,uBAAA,CAAA,MAAA,MAAA,EAAA,CAAA;KACP,OAAO,uBAAA,CAAA,MAAA,MAAA,EAAA,CAAA;KACP,OAAO;IACT,CAAC;IAED,OAAO;KACL;KACA;KACA,YAAY;MACV,EAAW,UAAU;OACnB,SAAS;OACT,WAAW;OACX,YAAY;OACZ,gBAAgB;OAChB,YAAY;OACZ,aAAa;OACb,UAAU;OACV,QAAQ;OAIR,MAAM;MACR,CAAC;MACD,GAAc,CAAO,CAAC,CAAC,UAAU;OAC/B,aAAa;OACb,gBAAgB;QACd,QAAQ;QACR,KAAK;OACP;MACF,CAAC;MACD,EAAa,UAAU;OAAE;OAAW;MAAO,CAAC;MAC5C,EAAkB,UAAU,EAAE,UAAO,CAAC;MACtC,GAAI,KAAuB,KAAe,EAAU,SAAS,IACzD,CACE,EAAmB,UAAU;OAC3B;OACA,MAAM;OACN,WAAW;OACX;MACF,CAAC,CACH,IACA,CAAC;KACP;IACF;GACF;EACF,CAAC;yBAIC,EA0HM,OA1HN,GA0HM;GAzHY,EAAA,CAAA,KAAW,CAAK,EAAA,SAAA,EAAA,GAAhC,EAoGW,GAAA;;IApGoC,IAAI,EAAA,CAAA;OACjD,EAkGM,OAAA;IAjGH,kBAAgB,EAAA,CAAA;IACjB,MAAK;IACJ,cAAY,EAAA,CAAA,CAAC,CAAC,YAAY;IAC3B,OAAM;IACL,OAAK,GAAA;QAAiB,EAAA,CAAA;aAA+B,EAAA,gBAAgB,IAAG;cAAyB,EAAA,gBAAgB,KAAI;;;QAOrG,EAAA,CAAA,KAAa,EAAA,CAAA,KAAA,EAAA,GAA9B,EA6EW,GAAA,EAAA,KAAA,EAAA,GAAA;IA3ET,EAWS,UAAA;KAVP,MAAK;KACL,OAAK,EAAA,CAAC,wBAAsB,EAAA,gCAC4B,EAAA,CAAA,CAAM,EAAE,SAAQ,MAAA,EAAA,CAAA,CAAA;KAGvE,cAAY,EAAA,CAAA,CAAC,CAAC,YAAY;KAC1B,OAAO,EAAA,CAAA,CAAC,CAAC,YAAY;KACrB,SAAK,AAAA,EAAA,QAAA,MAAE,EAAA,CAAA,CAAM,EAAE,MAAK,CAAA,CAAG,MAAK,CAAA,CAAG,WAAU,CAAA,CAAG,IAAG;QAEhD,EAAuC,EAAA,EAAA,GAAA;KAAhC,MAAM;KAAK,gBAAc;;IAGlC,EAWS,UAAA;KAVP,MAAK;KACL,OAAK,EAAA,CAAC,wBAAsB,EAAA,gCAC4B,EAAA,CAAA,CAAM,EAAE,SAAQ,QAAA,EAAA,CAAA,CAAA;KAGvE,cAAY,EAAA,CAAA,CAAC,CAAC,YAAY;KAC1B,OAAO,EAAA,CAAA,CAAC,CAAC,YAAY;KACrB,SAAK,AAAA,EAAA,QAAA,MAAE,EAAA,CAAA,CAAM,EAAE,MAAK,CAAA,CAAG,MAAK,CAAA,CAAG,aAAY,CAAA,CAAG,IAAG;QAElD,EAAuC,EAAA,EAAA,GAAA;KAA9B,MAAM;KAAK,gBAAc;;aAEpC,EAGQ,QAAA;KAFN,OAAM;KACN,eAAY;;IAGd,EAWS,UAAA;KAVP,MAAK;KACL,OAAK,EAAA,CAAC,wBAAsB,EAAA,gCAC4B,EAAA,CAAA,CAAM,EAAE,SAAQ,MAAA,EAAA,CAAA,CAAA;KAGvE,cAAY,EAAA,CAAA,CAAC,CAAC,YAAY;KAC1B,OAAO,EAAA,CAAA,CAAC,CAAC,YAAY;KACrB,SAAK,AAAA,EAAA,QAAA,GAAA,MAAE,EAAA,CAAA,KAAA,EAAA,CAAA,CAAA,CAAA,GAAA,CAAA;QAER,EAAqC,EAAA,EAAA,GAAA;KAA9B,MAAM;KAAK,gBAAc;;IAI1B,EAAA,CAAA,KAAA,EAAA,GADR,EAGQ,QAHR,CAGQ,KAAA,EAAA,IAAA,EAAA;IAEA,EAAA,CAAA,KAAA,EAAA,GADR,EAUS,UAAA;;KARP,MAAK;KACL,OAAM;KACL,cAAY,EAAA,CAAA,CAAC,CAAC,SAAS;KACvB,OAAO,EAAA,CAAA,CAAC,CAAC,SAAS;KAClB,SAAK,AAAA,EAAA,QAAA,GAAA,MAAE,EAAA,CAAA,KAAA,EAAA,CAAA,CAAA,CAAA,GAAA,CAAA;QAER,EAAyC,EAAA,CAAA,GAAA;KAA9B,MAAM;KAAK,gBAAc;UAAK,MACzC,EAAG,EAAA,CAAA,CAAC,CAAC,SAAS,WAAW,GAAA,CAAA,CAAA,GAAA,GAAA,CAAA,KAAA,EAAA,IAAA,EAAA;IAInB,EAAA,CAAA,KAAA,EAAA,GADR,EAGQ,QAHR,CAGQ,KAAA,EAAA,IAAA,EAAA;IAEA,EAAA,CAAA,KAAA,EAAA,GADR,EAWS,UAAA;;KATP,MAAK;KACL,OAAM;KACL,cAAY,EAAA,CAAA,CAAC,CAAC,SAAS;KACvB,OAAO,EAAA,CAAA,CAAC,CAAC,SAAS;KACnB,eAAY;KACX,SAAK,AAAA,EAAA,QAAA,GAAA,MAAE,EAAA,CAAA,KAAA,EAAA,CAAA,CAAA,CAAA,GAAA,CAAA;QAER,EAAuC,EAAA,EAAA,GAAA;KAA9B,MAAM;KAAK,gBAAc;UAAK,MACvC,EAAG,EAAA,CAAA,CAAC,CAAC,SAAS,WAAW,GAAA,CAAA,CAAA,GAAA,GAAA,CAAA,KAAA,EAAA,IAAA,EAAA;mBAI3B,EAKM,OALN,GAKM,CAFJ,EAAiE,EAAA,EAAA,GAAA;IAAnD,OAAM;IAAe,MAAM;IAAK,gBAAc;SAAK,MACjE,EAAG,EAAA,CAAA,CAAC,CAAC,OAAO,aAAa,GAAA,CAAA,CAAA,CAAA,EAAA,GAAA,IAAA,CAAA,CAAA,GAAA,GAAA,CAAA,IAAA,CAAA,KAAA,EAAA,IAAA,EAAA;GAMjC,EAME,GAAA;IALC,QAAQ,EAAA,CAAA;IACR,kBAAgB,EAAA,CAAA;IAChB,cAAY,EAAA,CAAA;IACZ,cAAY,EAAA,EAAA;IACZ,SAAO,EAAA,EAAA;;;;;;;;GAGV,EAUE,GAAA;IATC,SAAS,EAAA,EAAA;IACT,mBAAiB,EAAA,CAAA,CAAM,EAAE,SAAQ,MAAA,KAAA;IAC1B,cAAY,EAAA,CAAA;mDAAa,QAAA,IAAA;IACzB,YAAU,EAAA,CAAA;iDAAO,QAAA,IAAA;IACjB,cAAY,EAAA,CAAA;mDAAS,QAAA,IAAA;IAC5B,SAAO,EAAA,EAAA;IACP,UAAQ,EAAA,EAAA;IACR,UAAQ,EAAA,EAAA;IACR,WAAS,EAAA,EAAA"}
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { D as a, E as o, J as s, P as c, U as l, a as u, j as d, w as f } from "./icons-
|
|
1
|
+
import { bt as e, gt as t, kt as n, pt as r, wt as i } from "./features-Dwb5aTLg.js";
|
|
2
|
+
import { D as a, E as o, J as s, P as c, U as l, a as u, j as d, w as f } from "./icons-Dhqh5lYQ.js";
|
|
3
3
|
//#region src/utils/blockTypeIcons.ts
|
|
4
4
|
var p = {
|
|
5
5
|
section: s,
|
|
6
6
|
title: l,
|
|
7
7
|
paragraph: a,
|
|
8
|
-
image:
|
|
8
|
+
image: i,
|
|
9
9
|
button: f,
|
|
10
10
|
divider: c,
|
|
11
11
|
video: o,
|
|
12
|
-
social:
|
|
13
|
-
menu:
|
|
14
|
-
table:
|
|
12
|
+
social: t,
|
|
13
|
+
menu: e,
|
|
14
|
+
table: r,
|
|
15
15
|
spacer: d,
|
|
16
16
|
countdown: u,
|
|
17
|
-
html:
|
|
17
|
+
html: n
|
|
18
18
|
};
|
|
19
19
|
//#endregion
|
|
20
20
|
export { p as t };
|
|
21
21
|
|
|
22
|
-
//# sourceMappingURL=blockTypeIcons-
|
|
22
|
+
//# sourceMappingURL=blockTypeIcons-B_xRBxSU.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blockTypeIcons-
|
|
1
|
+
{"version":3,"file":"blockTypeIcons-B_xRBxSU.js","names":[],"sources":["../../../src/utils/blockTypeIcons.ts"],"sourcesContent":["import {\n Code,\n Columns3,\n Heading,\n Image,\n Minus,\n MoveVertical,\n Navigation,\n Pilcrow,\n Play,\n RectangleHorizontal,\n Share2,\n Table,\n Timer,\n} from \"@lucide/vue\";\nimport type { Component } from \"vue\";\n\nexport const blockTypeIcons: Record<string, Component> = {\n section: Columns3,\n title: Heading,\n paragraph: Pilcrow,\n image: Image,\n button: RectangleHorizontal,\n divider: Minus,\n video: Play,\n social: Share2,\n menu: Navigation,\n table: Table,\n spacer: MoveVertical,\n countdown: Timer,\n html: Code,\n};\n"],"mappings":";;;AAiBA,IAAa,IAA4C;CACvD,SAAS;CACT,OAAO;CACP,WAAW;CACX,OAAO;CACP,QAAQ;CACR,SAAS;CACT,OAAO;CACP,QAAQ;CACR,MAAM;CACN,OAAO;CACP,QAAQ;CACR,WAAW;CACX,MAAM;AACR"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { H as e, M as t, O as n, V as r, Z as i, c as a, ct as o, f as s, g as c, h as l, it as u, l as d, m as f, o as p, ot as m, p as h, st as g, x as _ } from "./draggable-D840DIZB.js";
|
|
2
|
-
import {
|
|
2
|
+
import { An as v, Dn as y, En as b, rt as x, wn as S, zt as C } from "./features-Dwb5aTLg.js";
|
|
3
3
|
import { _ as w, g as T, h as E, n as D, t as O, v as k, y as A } from "./tiptap-zpXk5mN4.js";
|
|
4
4
|
import { i as j, r as M, t as N } from "./MergeTagSuggestion-jesxS7An.js";
|
|
5
5
|
//#region src/extensions/FontSize.ts
|
|
@@ -83,9 +83,9 @@ var P = E.create({
|
|
|
83
83
|
updateAttributes: { type: Function }
|
|
84
84
|
},
|
|
85
85
|
setup(_) {
|
|
86
|
-
let
|
|
86
|
+
let y = _, { syntax: S } = x(), { t: w } = C(), T = s(() => v(y.node.attrs.value, S)), E = s(() => b(y.node.attrs.value, S)), D = i(!1), k = i(""), A = i(null), j = !1;
|
|
87
87
|
function M() {
|
|
88
|
-
k.value =
|
|
88
|
+
k.value = y.node.attrs.value, j = !1, D.value = !0, n(() => {
|
|
89
89
|
A.value?.focus(), A.value?.select();
|
|
90
90
|
});
|
|
91
91
|
}
|
|
@@ -97,9 +97,9 @@ var P = E.create({
|
|
|
97
97
|
D.value = !1;
|
|
98
98
|
return;
|
|
99
99
|
}
|
|
100
|
-
e !==
|
|
100
|
+
e !== y.node.attrs.value && y.updateAttributes({
|
|
101
101
|
value: e,
|
|
102
|
-
keyword:
|
|
102
|
+
keyword: v(e, S) ? b(e, S) : ""
|
|
103
103
|
}), D.value = !1;
|
|
104
104
|
}
|
|
105
105
|
function P(e) {
|
|
@@ -185,7 +185,7 @@ var U = w.create({
|
|
|
185
185
|
inline: !0,
|
|
186
186
|
atom: !0,
|
|
187
187
|
addOptions() {
|
|
188
|
-
return { syntax:
|
|
188
|
+
return { syntax: S.liquid };
|
|
189
189
|
},
|
|
190
190
|
addAttributes() {
|
|
191
191
|
return {
|
|
@@ -203,12 +203,12 @@ var U = w.create({
|
|
|
203
203
|
return [{ tag: "span[data-logic-merge-tag]" }];
|
|
204
204
|
},
|
|
205
205
|
renderHTML({ node: e, HTMLAttributes: t }) {
|
|
206
|
-
if (!
|
|
206
|
+
if (!v(e.attrs.value, this.options.syntax)) return [
|
|
207
207
|
"span",
|
|
208
208
|
{},
|
|
209
209
|
e.attrs.value
|
|
210
210
|
];
|
|
211
|
-
let n =
|
|
211
|
+
let n = b(e.attrs.value, this.options.syntax);
|
|
212
212
|
return [
|
|
213
213
|
"span",
|
|
214
214
|
A(t, {
|
|
@@ -232,8 +232,8 @@ var U = w.create({
|
|
|
232
232
|
find: RegExp(this.options.syntax.logic.source + "$", ""),
|
|
233
233
|
handler: ({ state: e, range: t, match: n }) => {
|
|
234
234
|
let r = n[0];
|
|
235
|
-
if (!
|
|
236
|
-
let i =
|
|
235
|
+
if (!v(r, this.options.syntax)) return;
|
|
236
|
+
let i = b(r, this.options.syntax), a = this.type.create({
|
|
237
237
|
value: r,
|
|
238
238
|
keyword: i
|
|
239
239
|
});
|
|
@@ -246,8 +246,8 @@ var U = w.create({
|
|
|
246
246
|
find: new RegExp(this.options.syntax.logic.source, "g"),
|
|
247
247
|
handler: ({ state: e, range: t, match: n }) => {
|
|
248
248
|
let r = n[0];
|
|
249
|
-
if (!
|
|
250
|
-
let i =
|
|
249
|
+
if (!v(r, this.options.syntax)) return;
|
|
250
|
+
let i = b(r, this.options.syntax), a = this.type.create({
|
|
251
251
|
value: r,
|
|
252
252
|
keyword: i
|
|
253
253
|
});
|
|
@@ -267,14 +267,14 @@ var U = w.create({
|
|
|
267
267
|
updateAttributes: { type: Function }
|
|
268
268
|
},
|
|
269
269
|
setup(l) {
|
|
270
|
-
let m = l, { getMergeTagLabel: g } =
|
|
270
|
+
let m = l, { getMergeTagLabel: g } = x(), { t: _ } = C(), v = s(() => g(m.node.attrs.value)), y = i(!1), b = i(""), S = i(null);
|
|
271
271
|
function w() {
|
|
272
|
-
|
|
272
|
+
b.value = m.node.attrs.value, y.value = !0, n(() => {
|
|
273
273
|
S.value?.focus(), S.value?.select();
|
|
274
274
|
});
|
|
275
275
|
}
|
|
276
276
|
function T() {
|
|
277
|
-
let e =
|
|
277
|
+
let e = b.value.trim();
|
|
278
278
|
e && e !== m.node.attrs.value && m.updateAttributes({
|
|
279
279
|
value: e,
|
|
280
280
|
label: g(e)
|
|
@@ -293,12 +293,12 @@ var U = w.create({
|
|
|
293
293
|
key: 0,
|
|
294
294
|
ref_key: "inputRef",
|
|
295
295
|
ref: S,
|
|
296
|
-
"onUpdate:modelValue": i[0] ||= (e) =>
|
|
296
|
+
"onUpdate:modelValue": i[0] ||= (e) => b.value = e,
|
|
297
297
|
type: "text",
|
|
298
298
|
class: "tpl:w-32 tpl:rounded tpl:border-none tpl:bg-transparent tpl:px-0.5 tpl:py-0 tpl:text-[1em] tpl:font-medium tpl:outline-none tpl:text-[var(--tpl-primary)]",
|
|
299
299
|
onBlur: T,
|
|
300
300
|
onKeydown: E
|
|
301
|
-
}, null, 544)), [[p,
|
|
301
|
+
}, null, 544)), [[p, b.value]]) : (t(), c("span", {
|
|
302
302
|
key: 1,
|
|
303
303
|
role: "button",
|
|
304
304
|
tabindex: "0",
|
|
@@ -343,7 +343,7 @@ var U = w.create({
|
|
|
343
343
|
addOptions() {
|
|
344
344
|
return {
|
|
345
345
|
mergeTags: [],
|
|
346
|
-
syntax:
|
|
346
|
+
syntax: S.liquid
|
|
347
347
|
};
|
|
348
348
|
},
|
|
349
349
|
addAttributes() {
|
|
@@ -418,4 +418,4 @@ var U = w.create({
|
|
|
418
418
|
//#endregion
|
|
419
419
|
export { P as FontSize, F as LetterSpacing, I as LineHeight, U as LogicMergeTagNode, q as MergeTagNode, N as MergeTagSuggestion, M as filterMergeTags, j as handleSuggestionKeyDown };
|
|
420
420
|
|
|
421
|
-
//# sourceMappingURL=extensions-
|
|
421
|
+
//# sourceMappingURL=extensions-Btyx_IMf.js.map
|