@aswin.dev/editor 0.7.3 → 0.7.6
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/{AiChatSidebar-Dt5pvG5t.js → AiChatSidebar-DM2ri7KX.js} +1 -1
- package/dist/{AiFeatureMenu-BipxcGap.js → AiFeatureMenu-BrZBJ0R5.js} +1 -1
- package/dist/{CloudEditor-CnUX0IOW.js → CloudEditor-BRpzzfQn.js} +8 -8
- package/dist/{CollaboratorBar-NaaZTjbs.js → CollaboratorBar-DsRXj3Kn.js} +1 -1
- package/dist/CountdownToolbar-B9IAZzeV.js +194 -0
- package/dist/{DesignReferenceSidebar-CZg97bbj.js → DesignReferenceSidebar-B1iw3Bb7.js} +1 -1
- package/dist/{ModuleBrowserModal-D2EVdexc.js → ModuleBrowserModal-DVnd1dqR.js} +4 -4
- package/dist/{ModulePreviewCanvas-P3N-nxkU.js → ModulePreviewCanvas-D9jBAoBQ.js} +29 -29
- package/dist/{ParagraphEditor-BbRuKhWv.js → ParagraphEditor-CO3V0H_V.js} +7 -7
- package/dist/{SaveModuleDialog-DLZa3m3O.js → SaveModuleDialog-CboNFwIA.js} +2 -2
- package/dist/{NumberWithSuffix-CihczoAd.js → SlidingPillSelect-DfcBdJqN.js} +122 -106
- package/dist/{SnapshotHistory-Csg1_jXi.js → SnapshotHistory-C26pvPre.js} +1 -1
- package/dist/{TestEmailModal-m3okLbJz.js → TestEmailModal-B4OoUWb_.js} +2 -2
- package/dist/{TitleEditor-CtJIS5ER.js → TitleEditor-DU_QWG_m.js} +2 -2
- package/dist/{TplModal-CQCrKeKP.js → TplModal-Dr6Do8oU.js} +1 -1
- package/dist/{blockTypeIcons-Dah0pgt-.js → blockTypeIcons-cRDr36gk.js} +48 -30
- package/dist/bundle-stats.json +6 -6
- package/dist/cdn/chunks/{AccessibilityPanel-Bt_fD7QT.js → AccessibilityPanel-Csd47zqI.js} +9 -9
- package/dist/cdn/chunks/{AccessibilityPanel-Bt_fD7QT.js.map → AccessibilityPanel-Csd47zqI.js.map} +1 -1
- package/dist/cdn/chunks/{AiFeatureMenu-Bn-0rgfr.js → AiFeatureMenu-BlnZF5pf.js} +7 -7
- package/dist/cdn/chunks/{AiFeatureMenu-Bn-0rgfr.js.map → AiFeatureMenu-BlnZF5pf.js.map} +1 -1
- package/dist/cdn/chunks/{BlockA11yBadge-Cj18Iw0p.js → BlockA11yBadge-VY8NqI9n.js} +4 -4
- package/dist/cdn/chunks/{BlockA11yBadge-Cj18Iw0p.js.map → BlockA11yBadge-VY8NqI9n.js.map} +1 -1
- package/dist/cdn/chunks/{CloudEditor-56lVcdot.js → CloudEditor-D0TrKlva.js} +178 -178
- package/dist/cdn/chunks/{CloudEditor-56lVcdot.js.map → CloudEditor-D0TrKlva.js.map} +1 -1
- package/dist/cdn/chunks/{CollaboratorBar-B7DCV3xp.js → CollaboratorBar-BhMNTI_h.js} +3 -3
- package/dist/cdn/chunks/{CollaboratorBar-B7DCV3xp.js.map → CollaboratorBar-BhMNTI_h.js.map} +1 -1
- package/dist/cdn/chunks/CountdownToolbar-DsP6O1fl.js +196 -0
- package/dist/cdn/chunks/CountdownToolbar-DsP6O1fl.js.map +1 -0
- package/dist/cdn/chunks/{ModuleBrowserModal-CiIY7ZGv.js → ModuleBrowserModal-CpYPeiKv.js} +8 -8
- package/dist/cdn/chunks/{ModuleBrowserModal-CiIY7ZGv.js.map → ModuleBrowserModal-CpYPeiKv.js.map} +1 -1
- package/dist/cdn/chunks/{ModulePreviewCanvas-M7_OGV2m.js → ModulePreviewCanvas-BIYYnqUq.js} +24 -24
- package/dist/cdn/chunks/{ModulePreviewCanvas-M7_OGV2m.js.map → ModulePreviewCanvas-BIYYnqUq.js.map} +1 -1
- package/dist/cdn/chunks/{ParagraphEditor-1XJOpiLX.js → ParagraphEditor-ZV5SYYw8.js} +53 -53
- package/dist/cdn/chunks/{ParagraphEditor-1XJOpiLX.js.map → ParagraphEditor-ZV5SYYw8.js.map} +1 -1
- package/dist/cdn/chunks/{RichTextEditorContent-C2q8sbp2.js → RichTextEditorContent-Dx05ETtt.js} +4 -4
- package/dist/cdn/chunks/{RichTextEditorContent-C2q8sbp2.js.map → RichTextEditorContent-Dx05ETtt.js.map} +1 -1
- package/dist/cdn/chunks/{SaveModuleDialog-BNxh1jPT.js → SaveModuleDialog-DJEEK7Wb.js} +23 -23
- package/dist/cdn/chunks/{SaveModuleDialog-BNxh1jPT.js.map → SaveModuleDialog-DJEEK7Wb.js.map} +1 -1
- package/dist/cdn/chunks/{NumberWithSuffix-DfVBnsgc.js → SlidingPillSelect-BhPCkqVu.js} +132 -116
- package/dist/cdn/chunks/SlidingPillSelect-BhPCkqVu.js.map +1 -0
- package/dist/cdn/chunks/{TitleEditor-IF7VzLTk.js → TitleEditor-fu1A87Ld.js} +21 -21
- package/dist/cdn/chunks/{TitleEditor-IF7VzLTk.js.map → TitleEditor-fu1A87Ld.js.map} +1 -1
- package/dist/cdn/chunks/blockTypeIcons-CJirTS-q.js +25 -0
- package/dist/cdn/chunks/blockTypeIcons-CJirTS-q.js.map +1 -0
- package/dist/cdn/chunks/{de-B05yW8Gi.js → de-BsYijc0r.js} +49 -2
- package/dist/cdn/chunks/de-BsYijc0r.js.map +1 -0
- package/dist/cdn/chunks/{en-BII7695P.js → en-DMu9hPIC.js} +49 -2
- package/dist/cdn/chunks/en-DMu9hPIC.js.map +1 -0
- package/dist/cdn/chunks/{extensions-B0eT-yjf.js → extensions-BbFKsjyT.js} +26 -26
- package/dist/cdn/chunks/{extensions-B0eT-yjf.js.map → extensions-BbFKsjyT.js.map} +1 -1
- package/dist/cdn/chunks/{features-BrvE2Fzv.js → features-uApxwJMz.js} +1953 -1836
- package/dist/cdn/chunks/features-uApxwJMz.js.map +1 -0
- package/dist/cdn/chunks/{icons-C7wtAD8p.js → icons-DZb4EX9m.js} +26 -9
- package/dist/cdn/chunks/icons-DZb4EX9m.js.map +1 -0
- package/dist/cdn/chunks/{media-library-Cl5XuaKy.js → media-library-B3g52j8R.js} +529 -529
- package/dist/cdn/chunks/{media-library-Cl5XuaKy.js.map → media-library-B3g52j8R.js.map} +1 -1
- package/dist/cdn/chunks/{quality-Va91a3N8.js → quality-Ug5lFGHP.js} +288 -288
- package/dist/cdn/chunks/{quality-Va91a3N8.js.map → quality-Ug5lFGHP.js.map} +1 -1
- package/dist/cdn/chunks/{renderer-si0Zgxeb.js → renderer-jXCdXjV-.js} +19 -19
- package/dist/cdn/chunks/{renderer-si0Zgxeb.js.map → renderer-jXCdXjV-.js.map} +1 -1
- package/dist/cdn/chunks/{src-BLyYIbdZ.js → src-FMtH5ZvJ.js} +9 -9
- package/dist/cdn/chunks/{src-BLyYIbdZ.js.map → src-FMtH5ZvJ.js.map} +1 -1
- package/dist/cdn/chunks/{styles-C6BQLT9F.js → styles-Co9vw4ag.js} +1332 -1101
- package/dist/cdn/chunks/styles-Co9vw4ag.js.map +1 -0
- package/dist/cdn/chunks/{tiptap-D8whBv5F.js → tiptap-qXOh0vzV.js} +2 -2
- package/dist/cdn/chunks/{tiptap-D8whBv5F.js.map → tiptap-qXOh0vzV.js.map} +1 -1
- package/dist/cdn/editor.css +1 -1
- package/dist/cdn/editor.js +85 -85
- package/dist/cdn/editor.js.map +1 -1
- package/dist/{cloud-BoS0J0vs.js → cloud-COUuu_KE.js} +1 -1
- package/dist/{de-C74F9xK3.js → de-CR1qAkAm.js} +48 -1
- package/dist/{dist-C2grMquk.js → dist-DP82Y0rs.js} +155 -131
- package/dist/{en-B24jVTeO.js → en-jbnp1n6M.js} +48 -1
- package/dist/{extensions-DsmjHqBF.js → extensions-Bg22D6c8.js} +16 -16
- package/dist/index.d.ts +10 -10
- package/dist/style.css +1 -1
- package/dist/{styles-BMFMtR9R.js → styles-DgL0UYj0.js} +1456 -1225
- package/dist/templatical-editor.js +6 -6
- package/dist/{useEditorCore-CtNAo0uy.js → useEditorCore-CSlYQZWx.js} +1756 -1661
- package/dist/{useMergeTag-2vTcVpNo.js → useMergeTag-BVL3A4OO.js} +4 -4
- package/package.json +7 -7
- package/dist/CountdownToolbar-CbhSp_uq.js +0 -210
- package/dist/cdn/chunks/CountdownToolbar-BtaD3d3-.js +0 -212
- package/dist/cdn/chunks/CountdownToolbar-BtaD3d3-.js.map +0 -1
- package/dist/cdn/chunks/NumberWithSuffix-DfVBnsgc.js.map +0 -1
- package/dist/cdn/chunks/blockTypeIcons-tPBKQ8WC.js +0 -24
- package/dist/cdn/chunks/blockTypeIcons-tPBKQ8WC.js.map +0 -1
- package/dist/cdn/chunks/de-B05yW8Gi.js.map +0 -1
- package/dist/cdn/chunks/en-BII7695P.js.map +0 -1
- package/dist/cdn/chunks/features-BrvE2Fzv.js.map +0 -1
- package/dist/cdn/chunks/icons-C7wtAD8p.js.map +0 -1
- package/dist/cdn/chunks/styles-C6BQLT9F.js.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { C as e, I as t, P as n, _ as r, ct as i, dt as a, f as o, ft as s, g as c, h as l, m as u, v as d } from "./draggable-C-1_gch3.js";
|
|
2
|
-
import {
|
|
3
|
-
import { n as p, r as m } from "./icons-
|
|
2
|
+
import { it as f } from "./features-uApxwJMz.js";
|
|
3
|
+
import { n as p, r as m } from "./icons-DZb4EX9m.js";
|
|
4
4
|
import { t as h } from "./readableTextColor-DhoK4XiZ.js";
|
|
5
5
|
//#region src/cloud/components/CollaboratorBar.vue?vue&type=script&setup=true&lang.ts
|
|
6
6
|
var g = { class: "tpl-collaborator-bar tpl:flex tpl:items-center tpl:gap-2" }, _ = ["title"], v = {
|
|
@@ -48,4 +48,4 @@ var g = { class: "tpl-collaborator-bar tpl:flex tpl:items-center tpl:gap-2" }, _
|
|
|
48
48
|
//#endregion
|
|
49
49
|
export { S as default };
|
|
50
50
|
|
|
51
|
-
//# sourceMappingURL=CollaboratorBar-
|
|
51
|
+
//# sourceMappingURL=CollaboratorBar-BhMNTI_h.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CollaboratorBar-
|
|
1
|
+
{"version":3,"file":"CollaboratorBar-BhMNTI_h.js","names":[],"sources":["../../../src/cloud/components/CollaboratorBar.vue","../../../src/cloud/components/CollaboratorBar.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { Collaborator } from \"@aswin.dev/types\";\nimport { useCloudI18nStrict } from \"../../composables\";\nimport { Wifi, WifiOff } from \"@lucide/vue\";\nimport { computed } from \"vue\";\nimport { readableTextColor } from \"../../utils/readableTextColor\";\n\nconst props = defineProps<{\n collaborators: Collaborator[];\n isConnected: boolean;\n}>();\n\nconst { t: cloudT } = useCloudI18nStrict();\n\nconst maxVisible = 3;\n\nconst visibleCollaborators = computed(() =>\n props.collaborators.slice(0, maxVisible),\n);\n\nconst overflowCollaborators = computed(() =>\n props.collaborators.slice(maxVisible),\n);\n\nconst overflowCount = computed(() => overflowCollaborators.value.length);\n\nconst overflowNames = computed(() =>\n overflowCollaborators.value.map((c) => c.name).join(\"\\n\"),\n);\n\nfunction getInitials(name: string): string {\n const parts = name.trim().split(/\\s+/);\n if (parts.length >= 2) {\n return (\n parts[0].charAt(0) + parts[parts.length - 1].charAt(0)\n ).toUpperCase();\n }\n return name.charAt(0).toUpperCase();\n}\n</script>\n\n<template>\n <div class=\"tpl-collaborator-bar tpl:flex tpl:items-center tpl:gap-2\">\n <!-- Connection indicator -->\n <div\n class=\"tpl:flex tpl:items-center tpl:gap-1 tpl:text-[11px]\"\n :style=\"{\n color: isConnected ? 'var(--tpl-success)' : 'var(--tpl-text-muted)',\n }\"\n :title=\"\n isConnected\n ? cloudT.collaboration.connected\n : cloudT.collaboration.disconnected\n \"\n >\n <Wifi v-if=\"isConnected\" :size=\"12\" :stroke-width=\"2\" />\n <WifiOff v-else :size=\"12\" :stroke-width=\"2\" />\n </div>\n\n <!-- Avatar stack -->\n <div\n v-if=\"collaborators.length > 0\"\n class=\"tpl:flex tpl:items-center tpl:-space-x-1.5\"\n >\n <div\n v-for=\"collaborator in visibleCollaborators\"\n :key=\"collaborator.id\"\n class=\"tpl-collaborator-avatar tpl:relative tpl:flex tpl:size-6 tpl:items-center tpl:justify-center tpl:rounded-full tpl:border-2 tpl:text-[10px] tpl:font-bold tpl:transition-transform tpl:duration-150 tpl:hover:z-10 tpl:hover:scale-110 tpl:border-[var(--tpl-bg)]\"\n :style=\"{\n backgroundColor: collaborator.color,\n color: readableTextColor(collaborator.color),\n }\"\n :title=\"collaborator.name\"\n >\n {{ getInitials(collaborator.name) }}\n </div>\n <div\n v-if=\"overflowCount > 0\"\n class=\"tpl:relative tpl:flex tpl:size-6 tpl:items-center tpl:justify-center tpl:rounded-full tpl:border-2 tpl:text-[9px] tpl:font-bold tpl:border-[var(--tpl-bg)] tpl:bg-[var(--tpl-bg-hover)] tpl:text-[var(--tpl-text-muted)]\"\n :title=\"overflowNames\"\n >\n +{{ overflowCount }}\n </div>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport type { Collaborator } from \"@aswin.dev/types\";\nimport { useCloudI18nStrict } from \"../../composables\";\nimport { Wifi, WifiOff } from \"@lucide/vue\";\nimport { computed } from \"vue\";\nimport { readableTextColor } from \"../../utils/readableTextColor\";\n\nconst props = defineProps<{\n collaborators: Collaborator[];\n isConnected: boolean;\n}>();\n\nconst { t: cloudT } = useCloudI18nStrict();\n\nconst maxVisible = 3;\n\nconst visibleCollaborators = computed(() =>\n props.collaborators.slice(0, maxVisible),\n);\n\nconst overflowCollaborators = computed(() =>\n props.collaborators.slice(maxVisible),\n);\n\nconst overflowCount = computed(() => overflowCollaborators.value.length);\n\nconst overflowNames = computed(() =>\n overflowCollaborators.value.map((c) => c.name).join(\"\\n\"),\n);\n\nfunction getInitials(name: string): string {\n const parts = name.trim().split(/\\s+/);\n if (parts.length >= 2) {\n return (\n parts[0].charAt(0) + parts[parts.length - 1].charAt(0)\n ).toUpperCase();\n }\n return name.charAt(0).toUpperCase();\n}\n</script>\n\n<template>\n <div class=\"tpl-collaborator-bar tpl:flex tpl:items-center tpl:gap-2\">\n <!-- Connection indicator -->\n <div\n class=\"tpl:flex tpl:items-center tpl:gap-1 tpl:text-[11px]\"\n :style=\"{\n color: isConnected ? 'var(--tpl-success)' : 'var(--tpl-text-muted)',\n }\"\n :title=\"\n isConnected\n ? cloudT.collaboration.connected\n : cloudT.collaboration.disconnected\n \"\n >\n <Wifi v-if=\"isConnected\" :size=\"12\" :stroke-width=\"2\" />\n <WifiOff v-else :size=\"12\" :stroke-width=\"2\" />\n </div>\n\n <!-- Avatar stack -->\n <div\n v-if=\"collaborators.length > 0\"\n class=\"tpl:flex tpl:items-center tpl:-space-x-1.5\"\n >\n <div\n v-for=\"collaborator in visibleCollaborators\"\n :key=\"collaborator.id\"\n class=\"tpl-collaborator-avatar tpl:relative tpl:flex tpl:size-6 tpl:items-center tpl:justify-center tpl:rounded-full tpl:border-2 tpl:text-[10px] tpl:font-bold tpl:transition-transform tpl:duration-150 tpl:hover:z-10 tpl:hover:scale-110 tpl:border-[var(--tpl-bg)]\"\n :style=\"{\n backgroundColor: collaborator.color,\n color: readableTextColor(collaborator.color),\n }\"\n :title=\"collaborator.name\"\n >\n {{ getInitials(collaborator.name) }}\n </div>\n <div\n v-if=\"overflowCount > 0\"\n class=\"tpl:relative tpl:flex tpl:size-6 tpl:items-center tpl:justify-center tpl:rounded-full tpl:border-2 tpl:text-[9px] tpl:font-bold tpl:border-[var(--tpl-bg)] tpl:bg-[var(--tpl-bg-hover)] tpl:text-[var(--tpl-text-muted)]\"\n :title=\"overflowNames\"\n >\n +{{ overflowCount }}\n </div>\n </div>\n </div>\n</template>\n"],"mappings":";;;;;;;;iCAcM,IAAa;;;;;;;EAPnB,IAAM,IAAQ,GAKR,EAAE,GAAG,MAAW,GAAoB,EAIpC,IAAuB,QAC3B,EAAM,cAAc,MAAM,GAAG,EAAW,CACzC,EAEK,IAAwB,QAC5B,EAAM,cAAc,MAAM,EAAW,CACtC,EAEK,IAAgB,QAAe,EAAsB,MAAM,OAAO,EAElE,IAAgB,QACpB,EAAsB,MAAM,KAAK,MAAM,EAAE,KAAK,CAAC,KAAK,KAAK,CAC1D;EAED,SAAS,EAAY,GAAsB;GACzC,IAAM,IAAQ,EAAK,MAAM,CAAC,MAAM,MAAM;AAMtC,UALI,EAAM,UAAU,KAEhB,EAAM,GAAG,OAAO,EAAE,GAAG,EAAM,EAAM,SAAS,GAAG,OAAO,EAAC,EACrD,aAAa,GAEV,EAAK,OAAO,EAAE,CAAC,aAAa;;yBAKnC,EA0CM,OA1CN,GA0CM,CAxCJ,EAaM,OAAA;GAZJ,OAAM;GACL,OAAK,EAAA,EAAA,OAAmB,EAAA,cAAW,uBAAA,yBAAA,CAAA;GAGnC,OAAgB,EAAA,cAAwB,EAAA,EAAM,CAAC,cAAc,YAAsB,EAAA,EAAM,CAAC,cAAc;MAM7F,EAAA,eAAA,GAAA,EAAZ,EAAwD,EAAA,EAAA,EAAA;;GAA9B,MAAM;GAAK,gBAAc;cACnD,EAA+C,EAAA,EAAA,EAAA;;GAA9B,MAAM;GAAK,gBAAc;gBAKpC,EAAA,cAAc,SAAM,KAAA,GAAA,EAD5B,EAuBM,OAvBN,GAuBM,EAAA,EAAA,GAAA,EAnBJ,EAWM,GAAA,MAAA,EAVmB,EAAA,QAAhB,YADT,EAWM,OAAA;GATH,KAAK,EAAa;GACnB,OAAM;GACL,OAAK,EAAA;qBAA+B,EAAa;WAAwB,EAAA,EAAiB,CAAC,EAAa,MAAK;;GAI7G,OAAO,EAAa;OAElB,EAAY,EAAa,KAAI,CAAA,EAAA,IAAA,EAAA,WAG1B,EAAA,QAAa,KAAA,GAAA,EADrB,EAMM,OAAA;;GAJJ,OAAM;GACL,OAAO,EAAA;KACT,OACE,EAAG,EAAA,MAAa,EAAA,GAAA,EAAA,IAAA,EAAA,IAAA,GAAA,CAAA,CAAA,IAAA,EAAA,IAAA,GAAA,CAAA,CAAA"}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { C as e, I as t, P as n, W as r, ct as i, f as a, ft as o, g as s, h as c, m as l, ut as u, v as d, x as f } from "./draggable-C-1_gch3.js";
|
|
2
|
+
import { Vt as p } from "./features-uApxwJMz.js";
|
|
3
|
+
import { f as m } from "./styleConstants-DfcU8u_r.js";
|
|
4
|
+
import { a as h, i as g, n as _, r as v, t as y } from "./SlidingPillSelect-BhPCkqVu.js";
|
|
5
|
+
//#region src/components/toolbar/CountdownToolbar.vue?vue&type=script&setup=true&lang.ts
|
|
6
|
+
var b = ["value"], x = ["value"], S = ["value"], C = { class: "tpl:grid tpl:grid-cols-2 tpl:gap-2" }, w = ["value"], T = { value: "" }, E = ["value"], D = { class: "tpl:grid tpl:grid-cols-2 tpl:gap-3" }, O = { class: "tpl:grid tpl:grid-cols-2 tpl:gap-3" }, k = { class: "tpl:grid tpl:grid-cols-2 tpl:gap-2" }, A = [
|
|
7
|
+
"value",
|
|
8
|
+
"placeholder",
|
|
9
|
+
"onInput"
|
|
10
|
+
], j = ["value", "placeholder"], M = ["value"], N = /* @__PURE__ */ e({
|
|
11
|
+
__name: "CountdownToolbar",
|
|
12
|
+
props: {
|
|
13
|
+
block: {},
|
|
14
|
+
fontFamilies: {}
|
|
15
|
+
},
|
|
16
|
+
emits: ["update"],
|
|
17
|
+
setup(e, { emit: N }) {
|
|
18
|
+
let P = N, { t: F } = p(), I = [
|
|
19
|
+
"UTC",
|
|
20
|
+
"America/New_York",
|
|
21
|
+
"America/Chicago",
|
|
22
|
+
"America/Denver",
|
|
23
|
+
"America/Los_Angeles",
|
|
24
|
+
"Europe/London",
|
|
25
|
+
"Europe/Berlin",
|
|
26
|
+
"Europe/Paris",
|
|
27
|
+
"Europe/Moscow",
|
|
28
|
+
"Asia/Dubai",
|
|
29
|
+
"Asia/Kolkata",
|
|
30
|
+
"Asia/Shanghai",
|
|
31
|
+
"Asia/Tokyo",
|
|
32
|
+
"Australia/Sydney",
|
|
33
|
+
"Pacific/Auckland"
|
|
34
|
+
], L = [
|
|
35
|
+
{
|
|
36
|
+
value: ":",
|
|
37
|
+
label: ":"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
value: "-",
|
|
41
|
+
label: "-"
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
value: " ",
|
|
45
|
+
label: "␣"
|
|
46
|
+
}
|
|
47
|
+
], R = [
|
|
48
|
+
"Days",
|
|
49
|
+
"Hours",
|
|
50
|
+
"Minutes",
|
|
51
|
+
"Seconds"
|
|
52
|
+
], z = l(() => R.map((e) => ({
|
|
53
|
+
unit: e,
|
|
54
|
+
showKey: `show${e}`,
|
|
55
|
+
labelKey: `label${e}`,
|
|
56
|
+
translationKey: e.toLowerCase()
|
|
57
|
+
})));
|
|
58
|
+
function B(e, t) {
|
|
59
|
+
P("update", { [e]: t });
|
|
60
|
+
}
|
|
61
|
+
return (l, p) => (n(), d(a, null, [
|
|
62
|
+
f(v, { label: i(F).countdown.targetDate }, {
|
|
63
|
+
default: r(() => [c("input", {
|
|
64
|
+
type: "datetime-local",
|
|
65
|
+
class: u(i(m)),
|
|
66
|
+
value: e.block.targetDate,
|
|
67
|
+
onInput: p[0] ||= (e) => B("targetDate", e.target.value)
|
|
68
|
+
}, null, 42, b)]),
|
|
69
|
+
_: 1
|
|
70
|
+
}, 8, ["label"]),
|
|
71
|
+
f(v, { label: i(F).countdown.timezone }, {
|
|
72
|
+
default: r(() => [c("select", {
|
|
73
|
+
class: u(i(m)),
|
|
74
|
+
value: e.block.timezone,
|
|
75
|
+
onChange: p[1] ||= (e) => B("timezone", e.target.value)
|
|
76
|
+
}, [(n(), d(a, null, t(I, (e) => c("option", {
|
|
77
|
+
key: e,
|
|
78
|
+
value: e
|
|
79
|
+
}, o(e), 9, S)), 64))], 42, x)]),
|
|
80
|
+
_: 1
|
|
81
|
+
}, 8, ["label"]),
|
|
82
|
+
f(v, { label: i(F).countdown.display }, {
|
|
83
|
+
default: r(() => [c("div", C, [(n(!0), d(a, null, t(z.value, (t) => (n(), s(g, {
|
|
84
|
+
key: t.unit,
|
|
85
|
+
"model-value": e.block[t.showKey],
|
|
86
|
+
label: i(F).countdown[t.translationKey],
|
|
87
|
+
"onUpdate:modelValue": (e) => B(t.showKey, e)
|
|
88
|
+
}, null, 8, [
|
|
89
|
+
"model-value",
|
|
90
|
+
"label",
|
|
91
|
+
"onUpdate:modelValue"
|
|
92
|
+
]))), 128))])]),
|
|
93
|
+
_: 1
|
|
94
|
+
}, 8, ["label"]),
|
|
95
|
+
f(v, { label: i(F).countdown.separator }, {
|
|
96
|
+
default: r(() => [f(y, {
|
|
97
|
+
options: L,
|
|
98
|
+
"model-value": e.block.separator,
|
|
99
|
+
"onUpdate:modelValue": p[2] ||= (e) => B("separator", e)
|
|
100
|
+
}, null, 8, ["model-value"])]),
|
|
101
|
+
_: 1
|
|
102
|
+
}, 8, ["label"]),
|
|
103
|
+
f(v, { label: i(F).countdown.fontFamily }, {
|
|
104
|
+
default: r(() => [c("select", {
|
|
105
|
+
class: u(i(m)),
|
|
106
|
+
value: e.block.fontFamily || "",
|
|
107
|
+
onChange: p[3] ||= (e) => B("fontFamily", e.target.value || void 0)
|
|
108
|
+
}, [c("option", T, o(i(F).countdown.inheritFont), 1), (n(!0), d(a, null, t(e.fontFamilies, (e) => (n(), d("option", {
|
|
109
|
+
key: e.value,
|
|
110
|
+
value: e.value
|
|
111
|
+
}, o(e.label), 9, E))), 128))], 42, w)]),
|
|
112
|
+
_: 1
|
|
113
|
+
}, 8, ["label"]),
|
|
114
|
+
c("div", D, [f(v, { label: i(F).countdown.digitFontSize }, {
|
|
115
|
+
default: r(() => [f(_, {
|
|
116
|
+
"model-value": e.block.digitFontSize,
|
|
117
|
+
min: 12,
|
|
118
|
+
max: 72,
|
|
119
|
+
suffix: "px",
|
|
120
|
+
"onUpdate:modelValue": p[4] ||= (e) => B("digitFontSize", e)
|
|
121
|
+
}, null, 8, ["model-value"])]),
|
|
122
|
+
_: 1
|
|
123
|
+
}, 8, ["label"]), f(v, { label: i(F).countdown.labelFontSize }, {
|
|
124
|
+
default: r(() => [f(_, {
|
|
125
|
+
"model-value": e.block.labelFontSize,
|
|
126
|
+
min: 8,
|
|
127
|
+
max: 24,
|
|
128
|
+
suffix: "px",
|
|
129
|
+
"onUpdate:modelValue": p[5] ||= (e) => B("labelFontSize", e)
|
|
130
|
+
}, null, 8, ["model-value"])]),
|
|
131
|
+
_: 1
|
|
132
|
+
}, 8, ["label"])]),
|
|
133
|
+
c("div", O, [f(v, { label: i(F).countdown.digitColor }, {
|
|
134
|
+
default: r(() => [f(h, {
|
|
135
|
+
"model-value": e.block.digitColor,
|
|
136
|
+
"onUpdate:modelValue": p[6] ||= (e) => B("digitColor", e)
|
|
137
|
+
}, null, 8, ["model-value"])]),
|
|
138
|
+
_: 1
|
|
139
|
+
}, 8, ["label"]), f(v, { label: i(F).countdown.labelColor }, {
|
|
140
|
+
default: r(() => [f(h, {
|
|
141
|
+
"model-value": e.block.labelColor,
|
|
142
|
+
"onUpdate:modelValue": p[7] ||= (e) => B("labelColor", e)
|
|
143
|
+
}, null, 8, ["model-value"])]),
|
|
144
|
+
_: 1
|
|
145
|
+
}, 8, ["label"])]),
|
|
146
|
+
f(v, { label: i(F).countdown.background }, {
|
|
147
|
+
default: r(() => [f(h, {
|
|
148
|
+
"model-value": e.block.backgroundColor,
|
|
149
|
+
"onUpdate:modelValue": p[8] ||= (e) => B("backgroundColor", e)
|
|
150
|
+
}, null, 8, ["model-value"])]),
|
|
151
|
+
_: 1
|
|
152
|
+
}, 8, ["label"]),
|
|
153
|
+
f(v, { label: i(F).countdown.labels }, {
|
|
154
|
+
default: r(() => [c("div", k, [(n(!0), d(a, null, t(z.value, (t) => (n(), d("input", {
|
|
155
|
+
key: t.unit,
|
|
156
|
+
type: "text",
|
|
157
|
+
class: u(i(m)),
|
|
158
|
+
value: e.block[t.labelKey],
|
|
159
|
+
placeholder: i(F).countdown[t.translationKey],
|
|
160
|
+
onInput: (e) => B(t.labelKey, e.target.value)
|
|
161
|
+
}, null, 42, A))), 128))])]),
|
|
162
|
+
_: 1
|
|
163
|
+
}, 8, ["label"]),
|
|
164
|
+
f(v, { label: i(F).countdown.expiry }, {
|
|
165
|
+
default: r(() => [c("input", {
|
|
166
|
+
type: "text",
|
|
167
|
+
class: u(i(m)),
|
|
168
|
+
value: e.block.expiredMessage,
|
|
169
|
+
placeholder: i(F).countdown.expiredMessagePlaceholder,
|
|
170
|
+
onInput: p[9] ||= (e) => B("expiredMessage", e.target.value)
|
|
171
|
+
}, null, 42, j)]),
|
|
172
|
+
_: 1
|
|
173
|
+
}, 8, ["label"]),
|
|
174
|
+
f(v, { label: i(F).countdown.expiredImageUrl }, {
|
|
175
|
+
default: r(() => [c("input", {
|
|
176
|
+
type: "url",
|
|
177
|
+
class: u(i(m)),
|
|
178
|
+
value: e.block.expiredImageUrl,
|
|
179
|
+
placeholder: "https://...",
|
|
180
|
+
onInput: p[10] ||= (e) => B("expiredImageUrl", e.target.value)
|
|
181
|
+
}, null, 42, M)]),
|
|
182
|
+
_: 1
|
|
183
|
+
}, 8, ["label"]),
|
|
184
|
+
f(g, {
|
|
185
|
+
"model-value": e.block.hideOnExpiry,
|
|
186
|
+
label: i(F).countdown.hideOnExpiry,
|
|
187
|
+
class: "tpl:mb-3.5",
|
|
188
|
+
"onUpdate:modelValue": p[11] ||= (e) => B("hideOnExpiry", e)
|
|
189
|
+
}, null, 8, ["model-value", "label"])
|
|
190
|
+
], 64));
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
//#endregion
|
|
194
|
+
export { N as default };
|
|
195
|
+
|
|
196
|
+
//# sourceMappingURL=CountdownToolbar-DsP6O1fl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CountdownToolbar-DsP6O1fl.js","names":[],"sources":["../../../src/components/toolbar/CountdownToolbar.vue","../../../src/components/toolbar/CountdownToolbar.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport ColorPicker from \"../ColorPicker.vue\";\nimport SlidingPillSelect from \"../SlidingPillSelect.vue\";\nimport FieldRow from \"./FieldRow.vue\";\nimport CheckboxItem from \"./CheckboxItem.vue\";\nimport NumberWithSuffix from \"./NumberWithSuffix.vue\";\nimport { useI18n } from \"../../composables/useI18n\";\nimport { inputClass } from \"../../constants/styleConstants\";\nimport type { CountdownBlock } from \"@aswin.dev/types\";\nimport { computed } from \"vue\";\n\ndefineProps<{\n block: CountdownBlock;\n fontFamilies: Array<{ value: string; label: string }>;\n}>();\n\nconst emit = defineEmits<{\n (e: \"update\", updates: Partial<CountdownBlock>): void;\n}>();\n\nconst { t } = useI18n();\n\nconst TIMEZONES = [\n \"UTC\",\n \"America/New_York\",\n \"America/Chicago\",\n \"America/Denver\",\n \"America/Los_Angeles\",\n \"Europe/London\",\n \"Europe/Berlin\",\n \"Europe/Paris\",\n \"Europe/Moscow\",\n \"Asia/Dubai\",\n \"Asia/Kolkata\",\n \"Asia/Shanghai\",\n \"Asia/Tokyo\",\n \"Australia/Sydney\",\n \"Pacific/Auckland\",\n];\n\nconst SEPARATORS = [\n { value: \":\", label: \":\" },\n { value: \"-\", label: \"-\" },\n { value: \" \", label: \"␣\" },\n];\n\ntype UnitKey = \"Days\" | \"Hours\" | \"Minutes\" | \"Seconds\";\nconst UNITS: UnitKey[] = [\"Days\", \"Hours\", \"Minutes\", \"Seconds\"];\n\nconst unitItems = computed(() =>\n UNITS.map((unit) => ({\n unit,\n showKey: `show${unit}` as const,\n labelKey: `label${unit}` as const,\n translationKey: unit.toLowerCase() as\n | \"days\"\n | \"hours\"\n | \"minutes\"\n | \"seconds\",\n })),\n);\n\nfunction updateField(field: keyof CountdownBlock, value: unknown): void {\n emit(\"update\", { [field]: value } as Partial<CountdownBlock>);\n}\n</script>\n\n<template>\n <FieldRow :label=\"t.countdown.targetDate\">\n <input\n type=\"datetime-local\"\n :class=\"inputClass\"\n :value=\"block.targetDate\"\n @input=\"\n updateField('targetDate', ($event.target as HTMLInputElement).value)\n \"\n />\n </FieldRow>\n\n <FieldRow :label=\"t.countdown.timezone\">\n <select\n :class=\"inputClass\"\n :value=\"block.timezone\"\n @change=\"\n updateField('timezone', ($event.target as HTMLSelectElement).value)\n \"\n >\n <option v-for=\"tz in TIMEZONES\" :key=\"tz\" :value=\"tz\">{{ tz }}</option>\n </select>\n </FieldRow>\n\n <FieldRow :label=\"t.countdown.display\">\n <div class=\"tpl:grid tpl:grid-cols-2 tpl:gap-2\">\n <CheckboxItem\n v-for=\"item in unitItems\"\n :key=\"item.unit\"\n :model-value=\"block[item.showKey]\"\n :label=\"t.countdown[item.translationKey]\"\n @update:model-value=\"updateField(item.showKey, $event)\"\n />\n </div>\n </FieldRow>\n\n <FieldRow :label=\"t.countdown.separator\">\n <SlidingPillSelect\n :options=\"SEPARATORS\"\n :model-value=\"block.separator\"\n @update:model-value=\"updateField('separator', $event)\"\n />\n </FieldRow>\n\n <FieldRow :label=\"t.countdown.fontFamily\">\n <select\n :class=\"inputClass\"\n :value=\"block.fontFamily || ''\"\n @change=\"\n updateField(\n 'fontFamily',\n ($event.target as HTMLSelectElement).value || undefined,\n )\n \"\n >\n <option value=\"\">{{ t.countdown.inheritFont }}</option>\n <option\n v-for=\"font in fontFamilies\"\n :key=\"font.value\"\n :value=\"font.value\"\n >\n {{ font.label }}\n </option>\n </select>\n </FieldRow>\n\n <div class=\"tpl:grid tpl:grid-cols-2 tpl:gap-3\">\n <FieldRow :label=\"t.countdown.digitFontSize\">\n <NumberWithSuffix\n :model-value=\"block.digitFontSize\"\n :min=\"12\"\n :max=\"72\"\n suffix=\"px\"\n @update:model-value=\"updateField('digitFontSize', $event)\"\n />\n </FieldRow>\n <FieldRow :label=\"t.countdown.labelFontSize\">\n <NumberWithSuffix\n :model-value=\"block.labelFontSize\"\n :min=\"8\"\n :max=\"24\"\n suffix=\"px\"\n @update:model-value=\"updateField('labelFontSize', $event)\"\n />\n </FieldRow>\n </div>\n\n <div class=\"tpl:grid tpl:grid-cols-2 tpl:gap-3\">\n <FieldRow :label=\"t.countdown.digitColor\">\n <ColorPicker\n :model-value=\"block.digitColor\"\n @update:model-value=\"updateField('digitColor', $event)\"\n />\n </FieldRow>\n <FieldRow :label=\"t.countdown.labelColor\">\n <ColorPicker\n :model-value=\"block.labelColor\"\n @update:model-value=\"updateField('labelColor', $event)\"\n />\n </FieldRow>\n </div>\n\n <FieldRow :label=\"t.countdown.background\">\n <ColorPicker\n :model-value=\"block.backgroundColor\"\n @update:model-value=\"updateField('backgroundColor', $event)\"\n />\n </FieldRow>\n\n <FieldRow :label=\"t.countdown.labels\">\n <div class=\"tpl:grid tpl:grid-cols-2 tpl:gap-2\">\n <input\n v-for=\"item in unitItems\"\n :key=\"item.unit\"\n type=\"text\"\n :class=\"inputClass\"\n :value=\"block[item.labelKey]\"\n :placeholder=\"t.countdown[item.translationKey]\"\n @input=\"\n updateField(item.labelKey, ($event.target as HTMLInputElement).value)\n \"\n />\n </div>\n </FieldRow>\n\n <FieldRow :label=\"t.countdown.expiry\">\n <input\n type=\"text\"\n :class=\"inputClass\"\n :value=\"block.expiredMessage\"\n :placeholder=\"t.countdown.expiredMessagePlaceholder\"\n @input=\"\n updateField('expiredMessage', ($event.target as HTMLInputElement).value)\n \"\n />\n </FieldRow>\n\n <FieldRow :label=\"t.countdown.expiredImageUrl\">\n <input\n type=\"url\"\n :class=\"inputClass\"\n :value=\"block.expiredImageUrl\"\n placeholder=\"https://...\"\n @input=\"\n updateField(\n 'expiredImageUrl',\n ($event.target as HTMLInputElement).value,\n )\n \"\n />\n </FieldRow>\n\n <CheckboxItem\n :model-value=\"block.hideOnExpiry\"\n :label=\"t.countdown.hideOnExpiry\"\n class=\"tpl:mb-3.5\"\n @update:model-value=\"updateField('hideOnExpiry', $event)\"\n />\n</template>\n","<script setup lang=\"ts\">\nimport ColorPicker from \"../ColorPicker.vue\";\nimport SlidingPillSelect from \"../SlidingPillSelect.vue\";\nimport FieldRow from \"./FieldRow.vue\";\nimport CheckboxItem from \"./CheckboxItem.vue\";\nimport NumberWithSuffix from \"./NumberWithSuffix.vue\";\nimport { useI18n } from \"../../composables/useI18n\";\nimport { inputClass } from \"../../constants/styleConstants\";\nimport type { CountdownBlock } from \"@aswin.dev/types\";\nimport { computed } from \"vue\";\n\ndefineProps<{\n block: CountdownBlock;\n fontFamilies: Array<{ value: string; label: string }>;\n}>();\n\nconst emit = defineEmits<{\n (e: \"update\", updates: Partial<CountdownBlock>): void;\n}>();\n\nconst { t } = useI18n();\n\nconst TIMEZONES = [\n \"UTC\",\n \"America/New_York\",\n \"America/Chicago\",\n \"America/Denver\",\n \"America/Los_Angeles\",\n \"Europe/London\",\n \"Europe/Berlin\",\n \"Europe/Paris\",\n \"Europe/Moscow\",\n \"Asia/Dubai\",\n \"Asia/Kolkata\",\n \"Asia/Shanghai\",\n \"Asia/Tokyo\",\n \"Australia/Sydney\",\n \"Pacific/Auckland\",\n];\n\nconst SEPARATORS = [\n { value: \":\", label: \":\" },\n { value: \"-\", label: \"-\" },\n { value: \" \", label: \"␣\" },\n];\n\ntype UnitKey = \"Days\" | \"Hours\" | \"Minutes\" | \"Seconds\";\nconst UNITS: UnitKey[] = [\"Days\", \"Hours\", \"Minutes\", \"Seconds\"];\n\nconst unitItems = computed(() =>\n UNITS.map((unit) => ({\n unit,\n showKey: `show${unit}` as const,\n labelKey: `label${unit}` as const,\n translationKey: unit.toLowerCase() as\n | \"days\"\n | \"hours\"\n | \"minutes\"\n | \"seconds\",\n })),\n);\n\nfunction updateField(field: keyof CountdownBlock, value: unknown): void {\n emit(\"update\", { [field]: value } as Partial<CountdownBlock>);\n}\n</script>\n\n<template>\n <FieldRow :label=\"t.countdown.targetDate\">\n <input\n type=\"datetime-local\"\n :class=\"inputClass\"\n :value=\"block.targetDate\"\n @input=\"\n updateField('targetDate', ($event.target as HTMLInputElement).value)\n \"\n />\n </FieldRow>\n\n <FieldRow :label=\"t.countdown.timezone\">\n <select\n :class=\"inputClass\"\n :value=\"block.timezone\"\n @change=\"\n updateField('timezone', ($event.target as HTMLSelectElement).value)\n \"\n >\n <option v-for=\"tz in TIMEZONES\" :key=\"tz\" :value=\"tz\">{{ tz }}</option>\n </select>\n </FieldRow>\n\n <FieldRow :label=\"t.countdown.display\">\n <div class=\"tpl:grid tpl:grid-cols-2 tpl:gap-2\">\n <CheckboxItem\n v-for=\"item in unitItems\"\n :key=\"item.unit\"\n :model-value=\"block[item.showKey]\"\n :label=\"t.countdown[item.translationKey]\"\n @update:model-value=\"updateField(item.showKey, $event)\"\n />\n </div>\n </FieldRow>\n\n <FieldRow :label=\"t.countdown.separator\">\n <SlidingPillSelect\n :options=\"SEPARATORS\"\n :model-value=\"block.separator\"\n @update:model-value=\"updateField('separator', $event)\"\n />\n </FieldRow>\n\n <FieldRow :label=\"t.countdown.fontFamily\">\n <select\n :class=\"inputClass\"\n :value=\"block.fontFamily || ''\"\n @change=\"\n updateField(\n 'fontFamily',\n ($event.target as HTMLSelectElement).value || undefined,\n )\n \"\n >\n <option value=\"\">{{ t.countdown.inheritFont }}</option>\n <option\n v-for=\"font in fontFamilies\"\n :key=\"font.value\"\n :value=\"font.value\"\n >\n {{ font.label }}\n </option>\n </select>\n </FieldRow>\n\n <div class=\"tpl:grid tpl:grid-cols-2 tpl:gap-3\">\n <FieldRow :label=\"t.countdown.digitFontSize\">\n <NumberWithSuffix\n :model-value=\"block.digitFontSize\"\n :min=\"12\"\n :max=\"72\"\n suffix=\"px\"\n @update:model-value=\"updateField('digitFontSize', $event)\"\n />\n </FieldRow>\n <FieldRow :label=\"t.countdown.labelFontSize\">\n <NumberWithSuffix\n :model-value=\"block.labelFontSize\"\n :min=\"8\"\n :max=\"24\"\n suffix=\"px\"\n @update:model-value=\"updateField('labelFontSize', $event)\"\n />\n </FieldRow>\n </div>\n\n <div class=\"tpl:grid tpl:grid-cols-2 tpl:gap-3\">\n <FieldRow :label=\"t.countdown.digitColor\">\n <ColorPicker\n :model-value=\"block.digitColor\"\n @update:model-value=\"updateField('digitColor', $event)\"\n />\n </FieldRow>\n <FieldRow :label=\"t.countdown.labelColor\">\n <ColorPicker\n :model-value=\"block.labelColor\"\n @update:model-value=\"updateField('labelColor', $event)\"\n />\n </FieldRow>\n </div>\n\n <FieldRow :label=\"t.countdown.background\">\n <ColorPicker\n :model-value=\"block.backgroundColor\"\n @update:model-value=\"updateField('backgroundColor', $event)\"\n />\n </FieldRow>\n\n <FieldRow :label=\"t.countdown.labels\">\n <div class=\"tpl:grid tpl:grid-cols-2 tpl:gap-2\">\n <input\n v-for=\"item in unitItems\"\n :key=\"item.unit\"\n type=\"text\"\n :class=\"inputClass\"\n :value=\"block[item.labelKey]\"\n :placeholder=\"t.countdown[item.translationKey]\"\n @input=\"\n updateField(item.labelKey, ($event.target as HTMLInputElement).value)\n \"\n />\n </div>\n </FieldRow>\n\n <FieldRow :label=\"t.countdown.expiry\">\n <input\n type=\"text\"\n :class=\"inputClass\"\n :value=\"block.expiredMessage\"\n :placeholder=\"t.countdown.expiredMessagePlaceholder\"\n @input=\"\n updateField('expiredMessage', ($event.target as HTMLInputElement).value)\n \"\n />\n </FieldRow>\n\n <FieldRow :label=\"t.countdown.expiredImageUrl\">\n <input\n type=\"url\"\n :class=\"inputClass\"\n :value=\"block.expiredImageUrl\"\n placeholder=\"https://...\"\n @input=\"\n updateField(\n 'expiredImageUrl',\n ($event.target as HTMLInputElement).value,\n )\n \"\n />\n </FieldRow>\n\n <CheckboxItem\n :model-value=\"block.hideOnExpiry\"\n :label=\"t.countdown.hideOnExpiry\"\n class=\"tpl:mb-3.5\"\n @update:model-value=\"updateField('hideOnExpiry', $event)\"\n />\n</template>\n"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { C as e, G as t, H as n, I as r, P as i, S as a, W as ee, _ as te, c as ne, ct as o, d as s, dt as c, f as l, ft as u, g as d, h as f, m as p, s as re, tt as m, v as h, x as g, z as ie } from "./draggable-C-1_gch3.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { t as y } from "./blockTypeIcons-
|
|
2
|
+
import { Vt as ae, ct as oe, dn as _, en as se, ft as ce, i as le, it as ue, sn as de } from "./features-uApxwJMz.js";
|
|
3
|
+
import { C as fe, L as v } from "./icons-DZb4EX9m.js";
|
|
4
|
+
import { t as y } from "./blockTypeIcons-CJirTS-q.js";
|
|
5
5
|
//#region src/cloud/components/ModuleBrowserModal.vue?vue&type=script&setup=true&lang.ts
|
|
6
6
|
var pe = {
|
|
7
7
|
role: "dialog",
|
|
@@ -40,7 +40,7 @@ var pe = {
|
|
|
40
40
|
props: { visible: { type: Boolean } },
|
|
41
41
|
emits: ["close", "insert"],
|
|
42
42
|
setup(e, { emit: B }) {
|
|
43
|
-
let Te = e, V = B, Ee = a(() => import("./ModulePreviewCanvas-
|
|
43
|
+
let Te = e, V = B, Ee = a(() => import("./ModulePreviewCanvas-BIYYnqUq.js")), { t: De } = ae(), { t: H } = ue(), U = _(de, "ModuleBrowserModal"), W = _(se, "ModuleBrowserModal"), G = m(""), K = m(null), q = m(null), J = m("end"), Y = p(() => {
|
|
44
44
|
let e = U.modules.value;
|
|
45
45
|
if (!G.value) return e;
|
|
46
46
|
let t = G.value.toLowerCase();
|
|
@@ -102,7 +102,7 @@ var pe = {
|
|
|
102
102
|
function Me(e) {
|
|
103
103
|
e.key === "Escape" && $(), e.key === "Enter" && X.value && (e.preventDefault(), Q());
|
|
104
104
|
}
|
|
105
|
-
return (n, a) => (i(), d(
|
|
105
|
+
return (n, a) => (i(), d(le, {
|
|
106
106
|
visible: e.visible,
|
|
107
107
|
onClose: $,
|
|
108
108
|
onKeydown: Me
|
|
@@ -112,7 +112,7 @@ var pe = {
|
|
|
112
112
|
"aria-label": o(H).modules.close,
|
|
113
113
|
class: "tpl:cursor-pointer tpl:rounded-md tpl:border-none tpl:bg-transparent tpl:p-1 tpl:transition-colors tpl:duration-100 tpl:text-[var(--tpl-text-dim)]",
|
|
114
114
|
onClick: $
|
|
115
|
-
}, [g(o(
|
|
115
|
+
}, [g(o(oe), {
|
|
116
116
|
size: 16,
|
|
117
117
|
"stroke-width": 2
|
|
118
118
|
})], 8, x)]),
|
|
@@ -155,7 +155,7 @@ var pe = {
|
|
|
155
155
|
"aria-label": o(H).modules.delete,
|
|
156
156
|
title: o(H).modules.delete,
|
|
157
157
|
onClick: s((t) => q.value = e.id, ["stop"])
|
|
158
|
-
}, [g(o(
|
|
158
|
+
}, [g(o(ce), {
|
|
159
159
|
size: 12,
|
|
160
160
|
"stroke-width": 1.5
|
|
161
161
|
})], 8, I))
|
|
@@ -192,4 +192,4 @@ var pe = {
|
|
|
192
192
|
//#endregion
|
|
193
193
|
export { B as default };
|
|
194
194
|
|
|
195
|
-
//# sourceMappingURL=ModuleBrowserModal-
|
|
195
|
+
//# sourceMappingURL=ModuleBrowserModal-CpYPeiKv.js.map
|
package/dist/cdn/chunks/{ModuleBrowserModal-CiIY7ZGv.js.map → ModuleBrowserModal-CpYPeiKv.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ModuleBrowserModal-CiIY7ZGv.js","names":[],"sources":["../../../src/cloud/components/ModuleBrowserModal.vue","../../../src/cloud/components/ModuleBrowserModal.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport TplModal from \"./TplModal.vue\";\nimport { useI18n } from \"../../composables\";\nimport { useCloudI18nStrict } from \"../../composables\";\nimport { blockTypeIcons } from \"../../utils/blockTypeIcons\";\nimport {\n SAVED_MODULES_HEADLESS_KEY,\n EDITOR_KEY,\n requireInject,\n} from \"../../keys\";\nimport type { SavedModule } from \"@aswin.dev/types\";\nimport { Package, Search, Trash2, X } from \"@lucide/vue\";\nimport { computed, defineAsyncComponent, ref, watch } from \"vue\";\n\nconst props = defineProps<{\n visible: boolean;\n}>();\n\nconst emit = defineEmits<{\n (e: \"close\"): void;\n (e: \"insert\", module: SavedModule, insertIndex: number | undefined): void;\n}>();\n\nconst ModulePreviewCanvas = defineAsyncComponent(\n () => import(\"./ModulePreviewCanvas.vue\"),\n);\n\nconst { t } = useI18n();\nconst { t: cloudT } = useCloudI18nStrict();\nconst savedModules = requireInject(\n SAVED_MODULES_HEADLESS_KEY,\n \"ModuleBrowserModal\",\n);\nconst editor = requireInject(EDITOR_KEY, \"ModuleBrowserModal\");\n\nconst searchQuery = ref(\"\");\nconst selectedModuleId = ref<string | null>(null);\nconst confirmDeleteId = ref<string | null>(null);\n// 'end' = append, 'beginning' = index 0, or block id = after that block\nconst insertPosition = ref<string>(\"end\");\n\nconst filteredModules = computed(() => {\n const modules = savedModules.modules.value;\n if (!searchQuery.value) return modules;\n const query = searchQuery.value.toLowerCase();\n return modules.filter((m) => m.name.toLowerCase().includes(query));\n});\n\nconst selectedModule = computed(() => {\n if (!selectedModuleId.value) return null;\n return (\n savedModules.modules.value.find((m) => m.id === selectedModuleId.value) ??\n null\n );\n});\n\ninterface PositionOption {\n value: string;\n label: string;\n}\n\nconst positionOptions = computed<PositionOption[]>(() => {\n const options: PositionOption[] = [\n { value: \"beginning\", label: cloudT.modules.insertAtBeginning },\n ];\n const blocks = editor.content.value.blocks;\n for (let i = 0; i < blocks.length; i++) {\n const block = blocks[i];\n const typeKey = block.type as keyof typeof t.blocks;\n const label = t.blocks[typeKey] ?? block.type;\n options.push({\n value: block.id,\n label: cloudT.modules.insertAfterBlock.replace(\n \"{block}\",\n `${label} ${i + 1}`,\n ),\n });\n }\n options.push({ value: \"end\", label: cloudT.modules.insertAtEnd });\n return options;\n});\n\nconst resolvedInsertIndex = computed<number | undefined>(() => {\n if (insertPosition.value === \"end\") return undefined;\n if (insertPosition.value === \"beginning\") return 0;\n const blocks = editor.content.value.blocks;\n const idx = blocks.findIndex((b) => b.id === insertPosition.value);\n if (idx !== -1) return idx + 1;\n return undefined;\n});\n\nwatch(\n () => props.visible,\n (visible) => {\n if (visible) {\n searchQuery.value = \"\";\n selectedModuleId.value = null;\n confirmDeleteId.value = null;\n // Default to after selected block, or end\n const selectedId = editor.state.selectedBlockId;\n if (selectedId) {\n const idx = editor.content.value.blocks.findIndex(\n (b) => b.id === selectedId,\n );\n insertPosition.value = idx !== -1 ? selectedId : \"end\";\n } else {\n insertPosition.value = \"end\";\n }\n }\n },\n);\n\nfunction getModuleBlockTypeIcons(\n module: SavedModule,\n): { type: string; icon: unknown }[] {\n const icons: { type: string; icon: unknown }[] = [];\n const seen = new Set<string>();\n for (const block of module.content) {\n if (!seen.has(block.type) && blockTypeIcons[block.type]) {\n seen.add(block.type);\n icons.push({ type: block.type, icon: blockTypeIcons[block.type] });\n }\n if (icons.length >= 5) break;\n }\n return icons;\n}\n\nfunction getRemainingTypeCount(module: SavedModule): number {\n const types = new Set(module.content.map((b) => b.type));\n return Math.max(0, types.size - 5);\n}\n\nasync function handleDelete(moduleId: string): Promise<void> {\n try {\n await savedModules.deleteModule(moduleId);\n if (selectedModuleId.value === moduleId) {\n selectedModuleId.value = null;\n }\n } finally {\n confirmDeleteId.value = null;\n }\n}\n\nfunction handleInsert(): void {\n if (selectedModule.value) {\n emit(\"insert\", selectedModule.value, resolvedInsertIndex.value);\n }\n}\n\nfunction handleClose(): void {\n emit(\"close\");\n}\n\nfunction handleKeydown(event: KeyboardEvent): void {\n if (event.key === \"Escape\") {\n handleClose();\n }\n if (event.key === \"Enter\" && selectedModule.value) {\n event.preventDefault();\n handleInsert();\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-labelledby=\"tpl-module-browser-title\"\n class=\"tpl-scale-in tpl:mx-4 tpl:flex tpl:w-full tpl:max-w-[1000px] tpl:flex-col tpl:rounded-[var(--tpl-radius-lg)]\"\n style=\"\n background-color: var(--tpl-bg-elevated);\n box-shadow: var(--tpl-shadow-xl);\n max-height: 90vh;\n \"\n >\n <!-- Header -->\n <div\n class=\"tpl:flex tpl:items-center tpl:justify-between tpl:border-b tpl:px-5 tpl:py-4 tpl:border-[var(--tpl-border)]\"\n >\n <h3\n id=\"tpl-module-browser-title\"\n class=\"tpl:text-sm tpl:font-semibold tpl:text-[var(--tpl-text)]\"\n >\n {{ cloudT.modules.browse }}\n </h3>\n <button\n :aria-label=\"cloudT.modules.close\"\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:border-none tpl:bg-transparent tpl:p-1 tpl:transition-colors tpl:duration-100 tpl:text-[var(--tpl-text-dim)]\"\n @click=\"handleClose\"\n >\n <X :size=\"16\" :stroke-width=\"2\" />\n </button>\n </div>\n\n <!-- Body -->\n <div class=\"tpl:flex tpl:min-h-0 tpl:flex-1 tpl:overflow-hidden\">\n <!-- Left panel: module grid -->\n <div\n class=\"tpl:flex tpl:w-[300px] tpl:shrink-0 tpl:flex-col tpl:overflow-hidden\"\n >\n <!-- Search -->\n <div class=\"tpl:px-4 tpl:pt-4 tpl:pb-3\">\n <div class=\"tpl:relative\">\n <Search\n :size=\"14\"\n :stroke-width=\"2\"\n class=\"tpl:pointer-events-none tpl:absolute tpl:left-3 tpl:top-1/2 tpl:-translate-y-1/2 tpl:text-[var(--tpl-text-dim)]\"\n />\n <input\n v-model=\"searchQuery\"\n type=\"text\"\n :placeholder=\"cloudT.modules.search\"\n class=\"tpl:h-9 tpl:w-full tpl:rounded-md tpl:border tpl:pl-9 tpl:pr-3 tpl:text-sm tpl:outline-none tpl:border-[var(--tpl-border)] tpl:bg-[var(--tpl-bg)] tpl:text-[var(--tpl-text)]\"\n />\n </div>\n </div>\n\n <!-- Grid -->\n <div class=\"tpl:flex-1 tpl:overflow-y-auto tpl:px-4 tpl:pb-4\">\n <div\n v-if=\"filteredModules.length > 0\"\n class=\"tpl:flex tpl:flex-col tpl:gap-1\"\n >\n <button\n v-for=\"mod in filteredModules\"\n :key=\"mod.id\"\n type=\"button\"\n :aria-pressed=\"selectedModuleId === mod.id\"\n class=\"tpl:group/card tpl:w-full tpl:cursor-pointer tpl:rounded-[var(--tpl-radius-md)] tpl:border tpl:bg-transparent tpl:px-3 tpl:py-2 tpl:text-left tpl:transition-all tpl:duration-[120ms]\"\n :style=\"{\n borderColor:\n selectedModuleId === mod.id\n ? 'var(--tpl-primary)'\n : 'var(--tpl-border)',\n backgroundColor:\n selectedModuleId === mod.id\n ? 'var(--tpl-primary-light)'\n : 'transparent',\n }\"\n @click=\"selectedModuleId = mod.id\"\n >\n <div class=\"tpl:flex tpl:items-center tpl:gap-2\">\n <span\n class=\"tpl:flex-1 tpl:truncate tpl:text-xs tpl:font-semibold tpl:text-[var(--tpl-text)]\"\n >\n {{ mod.name }}\n </span>\n <span\n class=\"tpl:shrink-0 tpl:rounded-full tpl:px-1.5 tpl:py-0.5 tpl:text-[10px] tpl:font-medium tpl:bg-[var(--tpl-bg-hover)] tpl:text-[var(--tpl-text-muted)]\"\n >\n {{\n cloudT.modules.blockCount.replace(\n \"{count}\",\n String(mod.content.length),\n )\n }}\n </span>\n </div>\n <div class=\"tpl:mt-1 tpl:flex tpl:items-center tpl:gap-1\">\n <component\n :is=\"icon.icon\"\n v-for=\"icon in getModuleBlockTypeIcons(mod)\"\n :key=\"icon.type\"\n :size=\"14\"\n :stroke-width=\"1.5\"\n class=\"tpl:text-[var(--tpl-text-dim)]\"\n />\n <span\n v-if=\"getRemainingTypeCount(mod) > 0\"\n class=\"tpl:text-[10px] tpl:text-[var(--tpl-text-dim)]\"\n >\n +{{ getRemainingTypeCount(mod) }}\n </span>\n <button\n v-if=\"confirmDeleteId === mod.id\"\n :aria-label=\"cloudT.modules.deleteConfirm\"\n class=\"tpl:ml-auto tpl:cursor-pointer tpl:rounded-md tpl:border tpl:px-2 tpl:py-0.5 tpl:text-[10px] tpl:font-medium tpl:transition-colors tpl:duration-100 tpl:border-[var(--tpl-danger)] tpl:text-[var(--tpl-danger)]\"\n style=\"background-color: transparent\"\n @click.stop=\"handleDelete(mod.id)\"\n >\n {{ cloudT.modules.deleteConfirm }}\n </button>\n <button\n v-else\n class=\"tpl-module-delete-btn tpl:ml-auto tpl:cursor-pointer tpl:rounded-md tpl:border-none tpl:bg-transparent tpl:p-0.5 tpl:transition-colors tpl:duration-100 tpl:text-[var(--tpl-text-dim)]\"\n :aria-label=\"cloudT.modules.delete\"\n :title=\"cloudT.modules.delete\"\n @click.stop=\"confirmDeleteId = mod.id\"\n >\n <Trash2 :size=\"12\" :stroke-width=\"1.5\" />\n </button>\n </div>\n </button>\n </div>\n\n <!-- Empty state -->\n <div\n v-else\n class=\"tpl:flex tpl:flex-col tpl:items-center tpl:justify-center tpl:py-12\"\n >\n <Package\n :size=\"32\"\n :stroke-width=\"1\"\n class=\"tpl:text-[var(--tpl-text-dim)]\"\n />\n <p class=\"tpl:mt-2 tpl:text-xs tpl:text-[var(--tpl-text-dim)]\">\n {{\n searchQuery\n ? cloudT.modules.noModules\n : cloudT.modules.noModulesHint\n }}\n </p>\n </div>\n </div>\n </div>\n\n <!-- Right panel: preview -->\n <div\n class=\"tpl:flex tpl:flex-1 tpl:flex-col tpl:overflow-hidden tpl:border-l tpl:border-[var(--tpl-border)]\"\n >\n <div\n v-if=\"selectedModule\"\n class=\"tpl:flex tpl:flex-1 tpl:flex-col tpl:overflow-hidden\"\n >\n <!-- Visual preview -->\n <div class=\"tpl:flex-1 tpl:overflow-y-auto tpl:p-4\">\n <ModulePreviewCanvas :blocks=\"selectedModule.content\" />\n </div>\n </div>\n\n <!-- Empty preview state -->\n <div\n v-else\n class=\"tpl:flex tpl:flex-1 tpl:flex-col tpl:items-center tpl:justify-center tpl:px-4\"\n >\n <Package\n :size=\"32\"\n :stroke-width=\"1\"\n class=\"tpl:text-[var(--tpl-text-dim)]\"\n />\n <p\n class=\"tpl:mt-2 tpl:text-center tpl:text-xs tpl:text-[var(--tpl-text-dim)]\"\n >\n {{ cloudT.modules.selectToPreview }}\n </p>\n </div>\n </div>\n </div>\n\n <!-- Footer -->\n <div\n class=\"tpl:flex tpl:items-center tpl:justify-between tpl:border-t tpl:px-5 tpl:py-3 tpl:border-[var(--tpl-border)]\"\n >\n <div class=\"tpl:flex tpl:items-center tpl:gap-2\">\n <label\n class=\"tpl:shrink-0 tpl:text-xs tpl:text-[var(--tpl-text-dim)]\"\n >\n {{ cloudT.modules.insertPosition }}\n </label>\n <select\n v-model=\"insertPosition\"\n class=\"tpl:h-7 tpl:max-w-[220px] tpl:rounded-md tpl:border tpl:px-2 tpl:text-xs tpl:outline-none tpl:border-[var(--tpl-border)] tpl:bg-[var(--tpl-bg)] tpl:text-[var(--tpl-text)]\"\n >\n <option\n v-for=\"opt in positionOptions\"\n :key=\"opt.value\"\n :value=\"opt.value\"\n >\n {{ opt.label }}\n </option>\n </select>\n </div>\n <div class=\"tpl:flex 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 @click=\"handleClose\"\n >\n {{ cloudT.modules.close }}\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=\"!selectedModule\"\n @click=\"handleInsert\"\n >\n {{ cloudT.modules.insert }}\n </button>\n </div>\n </div>\n </div>\n </TplModal>\n</template>\n\n<style>\n.tpl-module-delete-btn:hover {\n color: var(--tpl-danger) !important;\n}\n</style>\n","<script setup lang=\"ts\">\nimport TplModal from \"./TplModal.vue\";\nimport { useI18n } from \"../../composables\";\nimport { useCloudI18nStrict } from \"../../composables\";\nimport { blockTypeIcons } from \"../../utils/blockTypeIcons\";\nimport {\n SAVED_MODULES_HEADLESS_KEY,\n EDITOR_KEY,\n requireInject,\n} from \"../../keys\";\nimport type { SavedModule } from \"@aswin.dev/types\";\nimport { Package, Search, Trash2, X } from \"@lucide/vue\";\nimport { computed, defineAsyncComponent, ref, watch } from \"vue\";\n\nconst props = defineProps<{\n visible: boolean;\n}>();\n\nconst emit = defineEmits<{\n (e: \"close\"): void;\n (e: \"insert\", module: SavedModule, insertIndex: number | undefined): void;\n}>();\n\nconst ModulePreviewCanvas = defineAsyncComponent(\n () => import(\"./ModulePreviewCanvas.vue\"),\n);\n\nconst { t } = useI18n();\nconst { t: cloudT } = useCloudI18nStrict();\nconst savedModules = requireInject(\n SAVED_MODULES_HEADLESS_KEY,\n \"ModuleBrowserModal\",\n);\nconst editor = requireInject(EDITOR_KEY, \"ModuleBrowserModal\");\n\nconst searchQuery = ref(\"\");\nconst selectedModuleId = ref<string | null>(null);\nconst confirmDeleteId = ref<string | null>(null);\n// 'end' = append, 'beginning' = index 0, or block id = after that block\nconst insertPosition = ref<string>(\"end\");\n\nconst filteredModules = computed(() => {\n const modules = savedModules.modules.value;\n if (!searchQuery.value) return modules;\n const query = searchQuery.value.toLowerCase();\n return modules.filter((m) => m.name.toLowerCase().includes(query));\n});\n\nconst selectedModule = computed(() => {\n if (!selectedModuleId.value) return null;\n return (\n savedModules.modules.value.find((m) => m.id === selectedModuleId.value) ??\n null\n );\n});\n\ninterface PositionOption {\n value: string;\n label: string;\n}\n\nconst positionOptions = computed<PositionOption[]>(() => {\n const options: PositionOption[] = [\n { value: \"beginning\", label: cloudT.modules.insertAtBeginning },\n ];\n const blocks = editor.content.value.blocks;\n for (let i = 0; i < blocks.length; i++) {\n const block = blocks[i];\n const typeKey = block.type as keyof typeof t.blocks;\n const label = t.blocks[typeKey] ?? block.type;\n options.push({\n value: block.id,\n label: cloudT.modules.insertAfterBlock.replace(\n \"{block}\",\n `${label} ${i + 1}`,\n ),\n });\n }\n options.push({ value: \"end\", label: cloudT.modules.insertAtEnd });\n return options;\n});\n\nconst resolvedInsertIndex = computed<number | undefined>(() => {\n if (insertPosition.value === \"end\") return undefined;\n if (insertPosition.value === \"beginning\") return 0;\n const blocks = editor.content.value.blocks;\n const idx = blocks.findIndex((b) => b.id === insertPosition.value);\n if (idx !== -1) return idx + 1;\n return undefined;\n});\n\nwatch(\n () => props.visible,\n (visible) => {\n if (visible) {\n searchQuery.value = \"\";\n selectedModuleId.value = null;\n confirmDeleteId.value = null;\n // Default to after selected block, or end\n const selectedId = editor.state.selectedBlockId;\n if (selectedId) {\n const idx = editor.content.value.blocks.findIndex(\n (b) => b.id === selectedId,\n );\n insertPosition.value = idx !== -1 ? selectedId : \"end\";\n } else {\n insertPosition.value = \"end\";\n }\n }\n },\n);\n\nfunction getModuleBlockTypeIcons(\n module: SavedModule,\n): { type: string; icon: unknown }[] {\n const icons: { type: string; icon: unknown }[] = [];\n const seen = new Set<string>();\n for (const block of module.content) {\n if (!seen.has(block.type) && blockTypeIcons[block.type]) {\n seen.add(block.type);\n icons.push({ type: block.type, icon: blockTypeIcons[block.type] });\n }\n if (icons.length >= 5) break;\n }\n return icons;\n}\n\nfunction getRemainingTypeCount(module: SavedModule): number {\n const types = new Set(module.content.map((b) => b.type));\n return Math.max(0, types.size - 5);\n}\n\nasync function handleDelete(moduleId: string): Promise<void> {\n try {\n await savedModules.deleteModule(moduleId);\n if (selectedModuleId.value === moduleId) {\n selectedModuleId.value = null;\n }\n } finally {\n confirmDeleteId.value = null;\n }\n}\n\nfunction handleInsert(): void {\n if (selectedModule.value) {\n emit(\"insert\", selectedModule.value, resolvedInsertIndex.value);\n }\n}\n\nfunction handleClose(): void {\n emit(\"close\");\n}\n\nfunction handleKeydown(event: KeyboardEvent): void {\n if (event.key === \"Escape\") {\n handleClose();\n }\n if (event.key === \"Enter\" && selectedModule.value) {\n event.preventDefault();\n handleInsert();\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-labelledby=\"tpl-module-browser-title\"\n class=\"tpl-scale-in tpl:mx-4 tpl:flex tpl:w-full tpl:max-w-[1000px] tpl:flex-col tpl:rounded-[var(--tpl-radius-lg)]\"\n style=\"\n background-color: var(--tpl-bg-elevated);\n box-shadow: var(--tpl-shadow-xl);\n max-height: 90vh;\n \"\n >\n <!-- Header -->\n <div\n class=\"tpl:flex tpl:items-center tpl:justify-between tpl:border-b tpl:px-5 tpl:py-4 tpl:border-[var(--tpl-border)]\"\n >\n <h3\n id=\"tpl-module-browser-title\"\n class=\"tpl:text-sm tpl:font-semibold tpl:text-[var(--tpl-text)]\"\n >\n {{ cloudT.modules.browse }}\n </h3>\n <button\n :aria-label=\"cloudT.modules.close\"\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:border-none tpl:bg-transparent tpl:p-1 tpl:transition-colors tpl:duration-100 tpl:text-[var(--tpl-text-dim)]\"\n @click=\"handleClose\"\n >\n <X :size=\"16\" :stroke-width=\"2\" />\n </button>\n </div>\n\n <!-- Body -->\n <div class=\"tpl:flex tpl:min-h-0 tpl:flex-1 tpl:overflow-hidden\">\n <!-- Left panel: module grid -->\n <div\n class=\"tpl:flex tpl:w-[300px] tpl:shrink-0 tpl:flex-col tpl:overflow-hidden\"\n >\n <!-- Search -->\n <div class=\"tpl:px-4 tpl:pt-4 tpl:pb-3\">\n <div class=\"tpl:relative\">\n <Search\n :size=\"14\"\n :stroke-width=\"2\"\n class=\"tpl:pointer-events-none tpl:absolute tpl:left-3 tpl:top-1/2 tpl:-translate-y-1/2 tpl:text-[var(--tpl-text-dim)]\"\n />\n <input\n v-model=\"searchQuery\"\n type=\"text\"\n :placeholder=\"cloudT.modules.search\"\n class=\"tpl:h-9 tpl:w-full tpl:rounded-md tpl:border tpl:pl-9 tpl:pr-3 tpl:text-sm tpl:outline-none tpl:border-[var(--tpl-border)] tpl:bg-[var(--tpl-bg)] tpl:text-[var(--tpl-text)]\"\n />\n </div>\n </div>\n\n <!-- Grid -->\n <div class=\"tpl:flex-1 tpl:overflow-y-auto tpl:px-4 tpl:pb-4\">\n <div\n v-if=\"filteredModules.length > 0\"\n class=\"tpl:flex tpl:flex-col tpl:gap-1\"\n >\n <button\n v-for=\"mod in filteredModules\"\n :key=\"mod.id\"\n type=\"button\"\n :aria-pressed=\"selectedModuleId === mod.id\"\n class=\"tpl:group/card tpl:w-full tpl:cursor-pointer tpl:rounded-[var(--tpl-radius-md)] tpl:border tpl:bg-transparent tpl:px-3 tpl:py-2 tpl:text-left tpl:transition-all tpl:duration-[120ms]\"\n :style=\"{\n borderColor:\n selectedModuleId === mod.id\n ? 'var(--tpl-primary)'\n : 'var(--tpl-border)',\n backgroundColor:\n selectedModuleId === mod.id\n ? 'var(--tpl-primary-light)'\n : 'transparent',\n }\"\n @click=\"selectedModuleId = mod.id\"\n >\n <div class=\"tpl:flex tpl:items-center tpl:gap-2\">\n <span\n class=\"tpl:flex-1 tpl:truncate tpl:text-xs tpl:font-semibold tpl:text-[var(--tpl-text)]\"\n >\n {{ mod.name }}\n </span>\n <span\n class=\"tpl:shrink-0 tpl:rounded-full tpl:px-1.5 tpl:py-0.5 tpl:text-[10px] tpl:font-medium tpl:bg-[var(--tpl-bg-hover)] tpl:text-[var(--tpl-text-muted)]\"\n >\n {{\n cloudT.modules.blockCount.replace(\n \"{count}\",\n String(mod.content.length),\n )\n }}\n </span>\n </div>\n <div class=\"tpl:mt-1 tpl:flex tpl:items-center tpl:gap-1\">\n <component\n :is=\"icon.icon\"\n v-for=\"icon in getModuleBlockTypeIcons(mod)\"\n :key=\"icon.type\"\n :size=\"14\"\n :stroke-width=\"1.5\"\n class=\"tpl:text-[var(--tpl-text-dim)]\"\n />\n <span\n v-if=\"getRemainingTypeCount(mod) > 0\"\n class=\"tpl:text-[10px] tpl:text-[var(--tpl-text-dim)]\"\n >\n +{{ getRemainingTypeCount(mod) }}\n </span>\n <button\n v-if=\"confirmDeleteId === mod.id\"\n :aria-label=\"cloudT.modules.deleteConfirm\"\n class=\"tpl:ml-auto tpl:cursor-pointer tpl:rounded-md tpl:border tpl:px-2 tpl:py-0.5 tpl:text-[10px] tpl:font-medium tpl:transition-colors tpl:duration-100 tpl:border-[var(--tpl-danger)] tpl:text-[var(--tpl-danger)]\"\n style=\"background-color: transparent\"\n @click.stop=\"handleDelete(mod.id)\"\n >\n {{ cloudT.modules.deleteConfirm }}\n </button>\n <button\n v-else\n class=\"tpl-module-delete-btn tpl:ml-auto tpl:cursor-pointer tpl:rounded-md tpl:border-none tpl:bg-transparent tpl:p-0.5 tpl:transition-colors tpl:duration-100 tpl:text-[var(--tpl-text-dim)]\"\n :aria-label=\"cloudT.modules.delete\"\n :title=\"cloudT.modules.delete\"\n @click.stop=\"confirmDeleteId = mod.id\"\n >\n <Trash2 :size=\"12\" :stroke-width=\"1.5\" />\n </button>\n </div>\n </button>\n </div>\n\n <!-- Empty state -->\n <div\n v-else\n class=\"tpl:flex tpl:flex-col tpl:items-center tpl:justify-center tpl:py-12\"\n >\n <Package\n :size=\"32\"\n :stroke-width=\"1\"\n class=\"tpl:text-[var(--tpl-text-dim)]\"\n />\n <p class=\"tpl:mt-2 tpl:text-xs tpl:text-[var(--tpl-text-dim)]\">\n {{\n searchQuery\n ? cloudT.modules.noModules\n : cloudT.modules.noModulesHint\n }}\n </p>\n </div>\n </div>\n </div>\n\n <!-- Right panel: preview -->\n <div\n class=\"tpl:flex tpl:flex-1 tpl:flex-col tpl:overflow-hidden tpl:border-l tpl:border-[var(--tpl-border)]\"\n >\n <div\n v-if=\"selectedModule\"\n class=\"tpl:flex tpl:flex-1 tpl:flex-col tpl:overflow-hidden\"\n >\n <!-- Visual preview -->\n <div class=\"tpl:flex-1 tpl:overflow-y-auto tpl:p-4\">\n <ModulePreviewCanvas :blocks=\"selectedModule.content\" />\n </div>\n </div>\n\n <!-- Empty preview state -->\n <div\n v-else\n class=\"tpl:flex tpl:flex-1 tpl:flex-col tpl:items-center tpl:justify-center tpl:px-4\"\n >\n <Package\n :size=\"32\"\n :stroke-width=\"1\"\n class=\"tpl:text-[var(--tpl-text-dim)]\"\n />\n <p\n class=\"tpl:mt-2 tpl:text-center tpl:text-xs tpl:text-[var(--tpl-text-dim)]\"\n >\n {{ cloudT.modules.selectToPreview }}\n </p>\n </div>\n </div>\n </div>\n\n <!-- Footer -->\n <div\n class=\"tpl:flex tpl:items-center tpl:justify-between tpl:border-t tpl:px-5 tpl:py-3 tpl:border-[var(--tpl-border)]\"\n >\n <div class=\"tpl:flex tpl:items-center tpl:gap-2\">\n <label\n class=\"tpl:shrink-0 tpl:text-xs tpl:text-[var(--tpl-text-dim)]\"\n >\n {{ cloudT.modules.insertPosition }}\n </label>\n <select\n v-model=\"insertPosition\"\n class=\"tpl:h-7 tpl:max-w-[220px] tpl:rounded-md tpl:border tpl:px-2 tpl:text-xs tpl:outline-none tpl:border-[var(--tpl-border)] tpl:bg-[var(--tpl-bg)] tpl:text-[var(--tpl-text)]\"\n >\n <option\n v-for=\"opt in positionOptions\"\n :key=\"opt.value\"\n :value=\"opt.value\"\n >\n {{ opt.label }}\n </option>\n </select>\n </div>\n <div class=\"tpl:flex 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 @click=\"handleClose\"\n >\n {{ cloudT.modules.close }}\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=\"!selectedModule\"\n @click=\"handleInsert\"\n >\n {{ cloudT.modules.insert }}\n </button>\n </div>\n </div>\n </div>\n </TplModal>\n</template>\n\n<style>\n.tpl-module-delete-btn:hover {\n color: var(--tpl-danger) !important;\n}\n</style>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ModuleBrowserModal-CpYPeiKv.js","names":[],"sources":["../../../src/cloud/components/ModuleBrowserModal.vue","../../../src/cloud/components/ModuleBrowserModal.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport TplModal from \"./TplModal.vue\";\nimport { useI18n } from \"../../composables\";\nimport { useCloudI18nStrict } from \"../../composables\";\nimport { blockTypeIcons } from \"../../utils/blockTypeIcons\";\nimport {\n SAVED_MODULES_HEADLESS_KEY,\n EDITOR_KEY,\n requireInject,\n} from \"../../keys\";\nimport type { SavedModule } from \"@aswin.dev/types\";\nimport { Package, Search, Trash2, X } from \"@lucide/vue\";\nimport { computed, defineAsyncComponent, ref, watch } from \"vue\";\n\nconst props = defineProps<{\n visible: boolean;\n}>();\n\nconst emit = defineEmits<{\n (e: \"close\"): void;\n (e: \"insert\", module: SavedModule, insertIndex: number | undefined): void;\n}>();\n\nconst ModulePreviewCanvas = defineAsyncComponent(\n () => import(\"./ModulePreviewCanvas.vue\"),\n);\n\nconst { t } = useI18n();\nconst { t: cloudT } = useCloudI18nStrict();\nconst savedModules = requireInject(\n SAVED_MODULES_HEADLESS_KEY,\n \"ModuleBrowserModal\",\n);\nconst editor = requireInject(EDITOR_KEY, \"ModuleBrowserModal\");\n\nconst searchQuery = ref(\"\");\nconst selectedModuleId = ref<string | null>(null);\nconst confirmDeleteId = ref<string | null>(null);\n// 'end' = append, 'beginning' = index 0, or block id = after that block\nconst insertPosition = ref<string>(\"end\");\n\nconst filteredModules = computed(() => {\n const modules = savedModules.modules.value;\n if (!searchQuery.value) return modules;\n const query = searchQuery.value.toLowerCase();\n return modules.filter((m) => m.name.toLowerCase().includes(query));\n});\n\nconst selectedModule = computed(() => {\n if (!selectedModuleId.value) return null;\n return (\n savedModules.modules.value.find((m) => m.id === selectedModuleId.value) ??\n null\n );\n});\n\ninterface PositionOption {\n value: string;\n label: string;\n}\n\nconst positionOptions = computed<PositionOption[]>(() => {\n const options: PositionOption[] = [\n { value: \"beginning\", label: cloudT.modules.insertAtBeginning },\n ];\n const blocks = editor.content.value.blocks;\n for (let i = 0; i < blocks.length; i++) {\n const block = blocks[i];\n const typeKey = block.type as keyof typeof t.blocks;\n const label = t.blocks[typeKey] ?? block.type;\n options.push({\n value: block.id,\n label: cloudT.modules.insertAfterBlock.replace(\n \"{block}\",\n `${label} ${i + 1}`,\n ),\n });\n }\n options.push({ value: \"end\", label: cloudT.modules.insertAtEnd });\n return options;\n});\n\nconst resolvedInsertIndex = computed<number | undefined>(() => {\n if (insertPosition.value === \"end\") return undefined;\n if (insertPosition.value === \"beginning\") return 0;\n const blocks = editor.content.value.blocks;\n const idx = blocks.findIndex((b) => b.id === insertPosition.value);\n if (idx !== -1) return idx + 1;\n return undefined;\n});\n\nwatch(\n () => props.visible,\n (visible) => {\n if (visible) {\n searchQuery.value = \"\";\n selectedModuleId.value = null;\n confirmDeleteId.value = null;\n // Default to after selected block, or end\n const selectedId = editor.state.selectedBlockId;\n if (selectedId) {\n const idx = editor.content.value.blocks.findIndex(\n (b) => b.id === selectedId,\n );\n insertPosition.value = idx !== -1 ? selectedId : \"end\";\n } else {\n insertPosition.value = \"end\";\n }\n }\n },\n);\n\nfunction getModuleBlockTypeIcons(\n module: SavedModule,\n): { type: string; icon: unknown }[] {\n const icons: { type: string; icon: unknown }[] = [];\n const seen = new Set<string>();\n for (const block of module.content) {\n if (!seen.has(block.type) && blockTypeIcons[block.type]) {\n seen.add(block.type);\n icons.push({ type: block.type, icon: blockTypeIcons[block.type] });\n }\n if (icons.length >= 5) break;\n }\n return icons;\n}\n\nfunction getRemainingTypeCount(module: SavedModule): number {\n const types = new Set(module.content.map((b) => b.type));\n return Math.max(0, types.size - 5);\n}\n\nasync function handleDelete(moduleId: string): Promise<void> {\n try {\n await savedModules.deleteModule(moduleId);\n if (selectedModuleId.value === moduleId) {\n selectedModuleId.value = null;\n }\n } finally {\n confirmDeleteId.value = null;\n }\n}\n\nfunction handleInsert(): void {\n if (selectedModule.value) {\n emit(\"insert\", selectedModule.value, resolvedInsertIndex.value);\n }\n}\n\nfunction handleClose(): void {\n emit(\"close\");\n}\n\nfunction handleKeydown(event: KeyboardEvent): void {\n if (event.key === \"Escape\") {\n handleClose();\n }\n if (event.key === \"Enter\" && selectedModule.value) {\n event.preventDefault();\n handleInsert();\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-labelledby=\"tpl-module-browser-title\"\n class=\"tpl-scale-in tpl:mx-4 tpl:flex tpl:w-full tpl:max-w-[1000px] tpl:flex-col tpl:rounded-[var(--tpl-radius-lg)]\"\n style=\"\n background-color: var(--tpl-bg-elevated);\n box-shadow: var(--tpl-shadow-xl);\n max-height: 90vh;\n \"\n >\n <!-- Header -->\n <div\n class=\"tpl:flex tpl:items-center tpl:justify-between tpl:border-b tpl:px-5 tpl:py-4 tpl:border-[var(--tpl-border)]\"\n >\n <h3\n id=\"tpl-module-browser-title\"\n class=\"tpl:text-sm tpl:font-semibold tpl:text-[var(--tpl-text)]\"\n >\n {{ cloudT.modules.browse }}\n </h3>\n <button\n :aria-label=\"cloudT.modules.close\"\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:border-none tpl:bg-transparent tpl:p-1 tpl:transition-colors tpl:duration-100 tpl:text-[var(--tpl-text-dim)]\"\n @click=\"handleClose\"\n >\n <X :size=\"16\" :stroke-width=\"2\" />\n </button>\n </div>\n\n <!-- Body -->\n <div class=\"tpl:flex tpl:min-h-0 tpl:flex-1 tpl:overflow-hidden\">\n <!-- Left panel: module grid -->\n <div\n class=\"tpl:flex tpl:w-[300px] tpl:shrink-0 tpl:flex-col tpl:overflow-hidden\"\n >\n <!-- Search -->\n <div class=\"tpl:px-4 tpl:pt-4 tpl:pb-3\">\n <div class=\"tpl:relative\">\n <Search\n :size=\"14\"\n :stroke-width=\"2\"\n class=\"tpl:pointer-events-none tpl:absolute tpl:left-3 tpl:top-1/2 tpl:-translate-y-1/2 tpl:text-[var(--tpl-text-dim)]\"\n />\n <input\n v-model=\"searchQuery\"\n type=\"text\"\n :placeholder=\"cloudT.modules.search\"\n class=\"tpl:h-9 tpl:w-full tpl:rounded-md tpl:border tpl:pl-9 tpl:pr-3 tpl:text-sm tpl:outline-none tpl:border-[var(--tpl-border)] tpl:bg-[var(--tpl-bg)] tpl:text-[var(--tpl-text)]\"\n />\n </div>\n </div>\n\n <!-- Grid -->\n <div class=\"tpl:flex-1 tpl:overflow-y-auto tpl:px-4 tpl:pb-4\">\n <div\n v-if=\"filteredModules.length > 0\"\n class=\"tpl:flex tpl:flex-col tpl:gap-1\"\n >\n <button\n v-for=\"mod in filteredModules\"\n :key=\"mod.id\"\n type=\"button\"\n :aria-pressed=\"selectedModuleId === mod.id\"\n class=\"tpl:group/card tpl:w-full tpl:cursor-pointer tpl:rounded-[var(--tpl-radius-md)] tpl:border tpl:bg-transparent tpl:px-3 tpl:py-2 tpl:text-left tpl:transition-all tpl:duration-[120ms]\"\n :style=\"{\n borderColor:\n selectedModuleId === mod.id\n ? 'var(--tpl-primary)'\n : 'var(--tpl-border)',\n backgroundColor:\n selectedModuleId === mod.id\n ? 'var(--tpl-primary-light)'\n : 'transparent',\n }\"\n @click=\"selectedModuleId = mod.id\"\n >\n <div class=\"tpl:flex tpl:items-center tpl:gap-2\">\n <span\n class=\"tpl:flex-1 tpl:truncate tpl:text-xs tpl:font-semibold tpl:text-[var(--tpl-text)]\"\n >\n {{ mod.name }}\n </span>\n <span\n class=\"tpl:shrink-0 tpl:rounded-full tpl:px-1.5 tpl:py-0.5 tpl:text-[10px] tpl:font-medium tpl:bg-[var(--tpl-bg-hover)] tpl:text-[var(--tpl-text-muted)]\"\n >\n {{\n cloudT.modules.blockCount.replace(\n \"{count}\",\n String(mod.content.length),\n )\n }}\n </span>\n </div>\n <div class=\"tpl:mt-1 tpl:flex tpl:items-center tpl:gap-1\">\n <component\n :is=\"icon.icon\"\n v-for=\"icon in getModuleBlockTypeIcons(mod)\"\n :key=\"icon.type\"\n :size=\"14\"\n :stroke-width=\"1.5\"\n class=\"tpl:text-[var(--tpl-text-dim)]\"\n />\n <span\n v-if=\"getRemainingTypeCount(mod) > 0\"\n class=\"tpl:text-[10px] tpl:text-[var(--tpl-text-dim)]\"\n >\n +{{ getRemainingTypeCount(mod) }}\n </span>\n <button\n v-if=\"confirmDeleteId === mod.id\"\n :aria-label=\"cloudT.modules.deleteConfirm\"\n class=\"tpl:ml-auto tpl:cursor-pointer tpl:rounded-md tpl:border tpl:px-2 tpl:py-0.5 tpl:text-[10px] tpl:font-medium tpl:transition-colors tpl:duration-100 tpl:border-[var(--tpl-danger)] tpl:text-[var(--tpl-danger)]\"\n style=\"background-color: transparent\"\n @click.stop=\"handleDelete(mod.id)\"\n >\n {{ cloudT.modules.deleteConfirm }}\n </button>\n <button\n v-else\n class=\"tpl-module-delete-btn tpl:ml-auto tpl:cursor-pointer tpl:rounded-md tpl:border-none tpl:bg-transparent tpl:p-0.5 tpl:transition-colors tpl:duration-100 tpl:text-[var(--tpl-text-dim)]\"\n :aria-label=\"cloudT.modules.delete\"\n :title=\"cloudT.modules.delete\"\n @click.stop=\"confirmDeleteId = mod.id\"\n >\n <Trash2 :size=\"12\" :stroke-width=\"1.5\" />\n </button>\n </div>\n </button>\n </div>\n\n <!-- Empty state -->\n <div\n v-else\n class=\"tpl:flex tpl:flex-col tpl:items-center tpl:justify-center tpl:py-12\"\n >\n <Package\n :size=\"32\"\n :stroke-width=\"1\"\n class=\"tpl:text-[var(--tpl-text-dim)]\"\n />\n <p class=\"tpl:mt-2 tpl:text-xs tpl:text-[var(--tpl-text-dim)]\">\n {{\n searchQuery\n ? cloudT.modules.noModules\n : cloudT.modules.noModulesHint\n }}\n </p>\n </div>\n </div>\n </div>\n\n <!-- Right panel: preview -->\n <div\n class=\"tpl:flex tpl:flex-1 tpl:flex-col tpl:overflow-hidden tpl:border-l tpl:border-[var(--tpl-border)]\"\n >\n <div\n v-if=\"selectedModule\"\n class=\"tpl:flex tpl:flex-1 tpl:flex-col tpl:overflow-hidden\"\n >\n <!-- Visual preview -->\n <div class=\"tpl:flex-1 tpl:overflow-y-auto tpl:p-4\">\n <ModulePreviewCanvas :blocks=\"selectedModule.content\" />\n </div>\n </div>\n\n <!-- Empty preview state -->\n <div\n v-else\n class=\"tpl:flex tpl:flex-1 tpl:flex-col tpl:items-center tpl:justify-center tpl:px-4\"\n >\n <Package\n :size=\"32\"\n :stroke-width=\"1\"\n class=\"tpl:text-[var(--tpl-text-dim)]\"\n />\n <p\n class=\"tpl:mt-2 tpl:text-center tpl:text-xs tpl:text-[var(--tpl-text-dim)]\"\n >\n {{ cloudT.modules.selectToPreview }}\n </p>\n </div>\n </div>\n </div>\n\n <!-- Footer -->\n <div\n class=\"tpl:flex tpl:items-center tpl:justify-between tpl:border-t tpl:px-5 tpl:py-3 tpl:border-[var(--tpl-border)]\"\n >\n <div class=\"tpl:flex tpl:items-center tpl:gap-2\">\n <label\n class=\"tpl:shrink-0 tpl:text-xs tpl:text-[var(--tpl-text-dim)]\"\n >\n {{ cloudT.modules.insertPosition }}\n </label>\n <select\n v-model=\"insertPosition\"\n class=\"tpl:h-7 tpl:max-w-[220px] tpl:rounded-md tpl:border tpl:px-2 tpl:text-xs tpl:outline-none tpl:border-[var(--tpl-border)] tpl:bg-[var(--tpl-bg)] tpl:text-[var(--tpl-text)]\"\n >\n <option\n v-for=\"opt in positionOptions\"\n :key=\"opt.value\"\n :value=\"opt.value\"\n >\n {{ opt.label }}\n </option>\n </select>\n </div>\n <div class=\"tpl:flex 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 @click=\"handleClose\"\n >\n {{ cloudT.modules.close }}\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=\"!selectedModule\"\n @click=\"handleInsert\"\n >\n {{ cloudT.modules.insert }}\n </button>\n </div>\n </div>\n </div>\n </TplModal>\n</template>\n\n<style>\n.tpl-module-delete-btn:hover {\n color: var(--tpl-danger) !important;\n}\n</style>\n","<script setup lang=\"ts\">\nimport TplModal from \"./TplModal.vue\";\nimport { useI18n } from \"../../composables\";\nimport { useCloudI18nStrict } from \"../../composables\";\nimport { blockTypeIcons } from \"../../utils/blockTypeIcons\";\nimport {\n SAVED_MODULES_HEADLESS_KEY,\n EDITOR_KEY,\n requireInject,\n} from \"../../keys\";\nimport type { SavedModule } from \"@aswin.dev/types\";\nimport { Package, Search, Trash2, X } from \"@lucide/vue\";\nimport { computed, defineAsyncComponent, ref, watch } from \"vue\";\n\nconst props = defineProps<{\n visible: boolean;\n}>();\n\nconst emit = defineEmits<{\n (e: \"close\"): void;\n (e: \"insert\", module: SavedModule, insertIndex: number | undefined): void;\n}>();\n\nconst ModulePreviewCanvas = defineAsyncComponent(\n () => import(\"./ModulePreviewCanvas.vue\"),\n);\n\nconst { t } = useI18n();\nconst { t: cloudT } = useCloudI18nStrict();\nconst savedModules = requireInject(\n SAVED_MODULES_HEADLESS_KEY,\n \"ModuleBrowserModal\",\n);\nconst editor = requireInject(EDITOR_KEY, \"ModuleBrowserModal\");\n\nconst searchQuery = ref(\"\");\nconst selectedModuleId = ref<string | null>(null);\nconst confirmDeleteId = ref<string | null>(null);\n// 'end' = append, 'beginning' = index 0, or block id = after that block\nconst insertPosition = ref<string>(\"end\");\n\nconst filteredModules = computed(() => {\n const modules = savedModules.modules.value;\n if (!searchQuery.value) return modules;\n const query = searchQuery.value.toLowerCase();\n return modules.filter((m) => m.name.toLowerCase().includes(query));\n});\n\nconst selectedModule = computed(() => {\n if (!selectedModuleId.value) return null;\n return (\n savedModules.modules.value.find((m) => m.id === selectedModuleId.value) ??\n null\n );\n});\n\ninterface PositionOption {\n value: string;\n label: string;\n}\n\nconst positionOptions = computed<PositionOption[]>(() => {\n const options: PositionOption[] = [\n { value: \"beginning\", label: cloudT.modules.insertAtBeginning },\n ];\n const blocks = editor.content.value.blocks;\n for (let i = 0; i < blocks.length; i++) {\n const block = blocks[i];\n const typeKey = block.type as keyof typeof t.blocks;\n const label = t.blocks[typeKey] ?? block.type;\n options.push({\n value: block.id,\n label: cloudT.modules.insertAfterBlock.replace(\n \"{block}\",\n `${label} ${i + 1}`,\n ),\n });\n }\n options.push({ value: \"end\", label: cloudT.modules.insertAtEnd });\n return options;\n});\n\nconst resolvedInsertIndex = computed<number | undefined>(() => {\n if (insertPosition.value === \"end\") return undefined;\n if (insertPosition.value === \"beginning\") return 0;\n const blocks = editor.content.value.blocks;\n const idx = blocks.findIndex((b) => b.id === insertPosition.value);\n if (idx !== -1) return idx + 1;\n return undefined;\n});\n\nwatch(\n () => props.visible,\n (visible) => {\n if (visible) {\n searchQuery.value = \"\";\n selectedModuleId.value = null;\n confirmDeleteId.value = null;\n // Default to after selected block, or end\n const selectedId = editor.state.selectedBlockId;\n if (selectedId) {\n const idx = editor.content.value.blocks.findIndex(\n (b) => b.id === selectedId,\n );\n insertPosition.value = idx !== -1 ? selectedId : \"end\";\n } else {\n insertPosition.value = \"end\";\n }\n }\n },\n);\n\nfunction getModuleBlockTypeIcons(\n module: SavedModule,\n): { type: string; icon: unknown }[] {\n const icons: { type: string; icon: unknown }[] = [];\n const seen = new Set<string>();\n for (const block of module.content) {\n if (!seen.has(block.type) && blockTypeIcons[block.type]) {\n seen.add(block.type);\n icons.push({ type: block.type, icon: blockTypeIcons[block.type] });\n }\n if (icons.length >= 5) break;\n }\n return icons;\n}\n\nfunction getRemainingTypeCount(module: SavedModule): number {\n const types = new Set(module.content.map((b) => b.type));\n return Math.max(0, types.size - 5);\n}\n\nasync function handleDelete(moduleId: string): Promise<void> {\n try {\n await savedModules.deleteModule(moduleId);\n if (selectedModuleId.value === moduleId) {\n selectedModuleId.value = null;\n }\n } finally {\n confirmDeleteId.value = null;\n }\n}\n\nfunction handleInsert(): void {\n if (selectedModule.value) {\n emit(\"insert\", selectedModule.value, resolvedInsertIndex.value);\n }\n}\n\nfunction handleClose(): void {\n emit(\"close\");\n}\n\nfunction handleKeydown(event: KeyboardEvent): void {\n if (event.key === \"Escape\") {\n handleClose();\n }\n if (event.key === \"Enter\" && selectedModule.value) {\n event.preventDefault();\n handleInsert();\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-labelledby=\"tpl-module-browser-title\"\n class=\"tpl-scale-in tpl:mx-4 tpl:flex tpl:w-full tpl:max-w-[1000px] tpl:flex-col tpl:rounded-[var(--tpl-radius-lg)]\"\n style=\"\n background-color: var(--tpl-bg-elevated);\n box-shadow: var(--tpl-shadow-xl);\n max-height: 90vh;\n \"\n >\n <!-- Header -->\n <div\n class=\"tpl:flex tpl:items-center tpl:justify-between tpl:border-b tpl:px-5 tpl:py-4 tpl:border-[var(--tpl-border)]\"\n >\n <h3\n id=\"tpl-module-browser-title\"\n class=\"tpl:text-sm tpl:font-semibold tpl:text-[var(--tpl-text)]\"\n >\n {{ cloudT.modules.browse }}\n </h3>\n <button\n :aria-label=\"cloudT.modules.close\"\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:border-none tpl:bg-transparent tpl:p-1 tpl:transition-colors tpl:duration-100 tpl:text-[var(--tpl-text-dim)]\"\n @click=\"handleClose\"\n >\n <X :size=\"16\" :stroke-width=\"2\" />\n </button>\n </div>\n\n <!-- Body -->\n <div class=\"tpl:flex tpl:min-h-0 tpl:flex-1 tpl:overflow-hidden\">\n <!-- Left panel: module grid -->\n <div\n class=\"tpl:flex tpl:w-[300px] tpl:shrink-0 tpl:flex-col tpl:overflow-hidden\"\n >\n <!-- Search -->\n <div class=\"tpl:px-4 tpl:pt-4 tpl:pb-3\">\n <div class=\"tpl:relative\">\n <Search\n :size=\"14\"\n :stroke-width=\"2\"\n class=\"tpl:pointer-events-none tpl:absolute tpl:left-3 tpl:top-1/2 tpl:-translate-y-1/2 tpl:text-[var(--tpl-text-dim)]\"\n />\n <input\n v-model=\"searchQuery\"\n type=\"text\"\n :placeholder=\"cloudT.modules.search\"\n class=\"tpl:h-9 tpl:w-full tpl:rounded-md tpl:border tpl:pl-9 tpl:pr-3 tpl:text-sm tpl:outline-none tpl:border-[var(--tpl-border)] tpl:bg-[var(--tpl-bg)] tpl:text-[var(--tpl-text)]\"\n />\n </div>\n </div>\n\n <!-- Grid -->\n <div class=\"tpl:flex-1 tpl:overflow-y-auto tpl:px-4 tpl:pb-4\">\n <div\n v-if=\"filteredModules.length > 0\"\n class=\"tpl:flex tpl:flex-col tpl:gap-1\"\n >\n <button\n v-for=\"mod in filteredModules\"\n :key=\"mod.id\"\n type=\"button\"\n :aria-pressed=\"selectedModuleId === mod.id\"\n class=\"tpl:group/card tpl:w-full tpl:cursor-pointer tpl:rounded-[var(--tpl-radius-md)] tpl:border tpl:bg-transparent tpl:px-3 tpl:py-2 tpl:text-left tpl:transition-all tpl:duration-[120ms]\"\n :style=\"{\n borderColor:\n selectedModuleId === mod.id\n ? 'var(--tpl-primary)'\n : 'var(--tpl-border)',\n backgroundColor:\n selectedModuleId === mod.id\n ? 'var(--tpl-primary-light)'\n : 'transparent',\n }\"\n @click=\"selectedModuleId = mod.id\"\n >\n <div class=\"tpl:flex tpl:items-center tpl:gap-2\">\n <span\n class=\"tpl:flex-1 tpl:truncate tpl:text-xs tpl:font-semibold tpl:text-[var(--tpl-text)]\"\n >\n {{ mod.name }}\n </span>\n <span\n class=\"tpl:shrink-0 tpl:rounded-full tpl:px-1.5 tpl:py-0.5 tpl:text-[10px] tpl:font-medium tpl:bg-[var(--tpl-bg-hover)] tpl:text-[var(--tpl-text-muted)]\"\n >\n {{\n cloudT.modules.blockCount.replace(\n \"{count}\",\n String(mod.content.length),\n )\n }}\n </span>\n </div>\n <div class=\"tpl:mt-1 tpl:flex tpl:items-center tpl:gap-1\">\n <component\n :is=\"icon.icon\"\n v-for=\"icon in getModuleBlockTypeIcons(mod)\"\n :key=\"icon.type\"\n :size=\"14\"\n :stroke-width=\"1.5\"\n class=\"tpl:text-[var(--tpl-text-dim)]\"\n />\n <span\n v-if=\"getRemainingTypeCount(mod) > 0\"\n class=\"tpl:text-[10px] tpl:text-[var(--tpl-text-dim)]\"\n >\n +{{ getRemainingTypeCount(mod) }}\n </span>\n <button\n v-if=\"confirmDeleteId === mod.id\"\n :aria-label=\"cloudT.modules.deleteConfirm\"\n class=\"tpl:ml-auto tpl:cursor-pointer tpl:rounded-md tpl:border tpl:px-2 tpl:py-0.5 tpl:text-[10px] tpl:font-medium tpl:transition-colors tpl:duration-100 tpl:border-[var(--tpl-danger)] tpl:text-[var(--tpl-danger)]\"\n style=\"background-color: transparent\"\n @click.stop=\"handleDelete(mod.id)\"\n >\n {{ cloudT.modules.deleteConfirm }}\n </button>\n <button\n v-else\n class=\"tpl-module-delete-btn tpl:ml-auto tpl:cursor-pointer tpl:rounded-md tpl:border-none tpl:bg-transparent tpl:p-0.5 tpl:transition-colors tpl:duration-100 tpl:text-[var(--tpl-text-dim)]\"\n :aria-label=\"cloudT.modules.delete\"\n :title=\"cloudT.modules.delete\"\n @click.stop=\"confirmDeleteId = mod.id\"\n >\n <Trash2 :size=\"12\" :stroke-width=\"1.5\" />\n </button>\n </div>\n </button>\n </div>\n\n <!-- Empty state -->\n <div\n v-else\n class=\"tpl:flex tpl:flex-col tpl:items-center tpl:justify-center tpl:py-12\"\n >\n <Package\n :size=\"32\"\n :stroke-width=\"1\"\n class=\"tpl:text-[var(--tpl-text-dim)]\"\n />\n <p class=\"tpl:mt-2 tpl:text-xs tpl:text-[var(--tpl-text-dim)]\">\n {{\n searchQuery\n ? cloudT.modules.noModules\n : cloudT.modules.noModulesHint\n }}\n </p>\n </div>\n </div>\n </div>\n\n <!-- Right panel: preview -->\n <div\n class=\"tpl:flex tpl:flex-1 tpl:flex-col tpl:overflow-hidden tpl:border-l tpl:border-[var(--tpl-border)]\"\n >\n <div\n v-if=\"selectedModule\"\n class=\"tpl:flex tpl:flex-1 tpl:flex-col tpl:overflow-hidden\"\n >\n <!-- Visual preview -->\n <div class=\"tpl:flex-1 tpl:overflow-y-auto tpl:p-4\">\n <ModulePreviewCanvas :blocks=\"selectedModule.content\" />\n </div>\n </div>\n\n <!-- Empty preview state -->\n <div\n v-else\n class=\"tpl:flex tpl:flex-1 tpl:flex-col tpl:items-center tpl:justify-center tpl:px-4\"\n >\n <Package\n :size=\"32\"\n :stroke-width=\"1\"\n class=\"tpl:text-[var(--tpl-text-dim)]\"\n />\n <p\n class=\"tpl:mt-2 tpl:text-center tpl:text-xs tpl:text-[var(--tpl-text-dim)]\"\n >\n {{ cloudT.modules.selectToPreview }}\n </p>\n </div>\n </div>\n </div>\n\n <!-- Footer -->\n <div\n class=\"tpl:flex tpl:items-center tpl:justify-between tpl:border-t tpl:px-5 tpl:py-3 tpl:border-[var(--tpl-border)]\"\n >\n <div class=\"tpl:flex tpl:items-center tpl:gap-2\">\n <label\n class=\"tpl:shrink-0 tpl:text-xs tpl:text-[var(--tpl-text-dim)]\"\n >\n {{ cloudT.modules.insertPosition }}\n </label>\n <select\n v-model=\"insertPosition\"\n class=\"tpl:h-7 tpl:max-w-[220px] tpl:rounded-md tpl:border tpl:px-2 tpl:text-xs tpl:outline-none tpl:border-[var(--tpl-border)] tpl:bg-[var(--tpl-bg)] tpl:text-[var(--tpl-text)]\"\n >\n <option\n v-for=\"opt in positionOptions\"\n :key=\"opt.value\"\n :value=\"opt.value\"\n >\n {{ opt.label }}\n </option>\n </select>\n </div>\n <div class=\"tpl:flex 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 @click=\"handleClose\"\n >\n {{ cloudT.modules.close }}\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=\"!selectedModule\"\n @click=\"handleInsert\"\n >\n {{ cloudT.modules.insert }}\n </button>\n </div>\n </div>\n </div>\n </TplModal>\n</template>\n\n<style>\n.tpl-module-delete-btn:hover {\n color: var(--tpl-danger) !important;\n}\n</style>\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { C as e, D as t, I as n, P as r, R as i, ct as a, dt as o, f as s, g as c, h as l, m as u, v as d, z as f } from "./draggable-C-1_gch3.js";
|
|
2
|
-
import { F as p, G as m, H as h, J as g, K as _,
|
|
2
|
+
import { F as p, G as m, H as h, J as g, K as _, M as v, N as y, P as b, R as x, Rt as S, U as C, W as w, Y as T, Z as E, j as D, q as O, qt as k, z as A } from "./features-uApxwJMz.js";
|
|
3
3
|
//#region src/components/blocks/PreviewSectionBlock.vue?vue&type=script&setup=true&lang.ts
|
|
4
4
|
var j = { class: "tpl:w-full" }, M = { class: "tpl:flex tpl:gap-0" }, N = /* @__PURE__ */ e({
|
|
5
5
|
name: "PreviewSectionBlock",
|
|
@@ -10,22 +10,22 @@ var j = { class: "tpl:w-full" }, M = { class: "tpl:flex tpl:gap-0" }, N = /* @__
|
|
|
10
10
|
},
|
|
11
11
|
setup(e) {
|
|
12
12
|
let N = {
|
|
13
|
-
title:
|
|
14
|
-
paragraph:
|
|
15
|
-
image:
|
|
16
|
-
video:
|
|
17
|
-
button:
|
|
13
|
+
title: v,
|
|
14
|
+
paragraph: w,
|
|
15
|
+
image: O,
|
|
16
|
+
video: D,
|
|
17
|
+
button: S,
|
|
18
18
|
input: _,
|
|
19
|
-
divider:
|
|
19
|
+
divider: T,
|
|
20
20
|
social: p,
|
|
21
21
|
menu: m,
|
|
22
|
-
table:
|
|
23
|
-
spacer:
|
|
22
|
+
table: y,
|
|
23
|
+
spacer: b,
|
|
24
24
|
html: g,
|
|
25
25
|
countdown: A,
|
|
26
|
-
form:
|
|
26
|
+
form: x,
|
|
27
27
|
custom: E
|
|
28
|
-
}, P = e, F = t(
|
|
28
|
+
}, P = e, F = t(k, null), I = u(() => {
|
|
29
29
|
switch (P.block.columns) {
|
|
30
30
|
case "2": return ["50%", "50%"];
|
|
31
31
|
case "3": return [
|
|
@@ -46,7 +46,7 @@ var j = { class: "tpl:w-full" }, M = { class: "tpl:flex tpl:gap-0" }, N = /* @__
|
|
|
46
46
|
return L.value[e] || [];
|
|
47
47
|
}
|
|
48
48
|
function z(e) {
|
|
49
|
-
return
|
|
49
|
+
return C(e, F, N);
|
|
50
50
|
}
|
|
51
51
|
return (e, t) => {
|
|
52
52
|
let u = i("PreviewSectionBlock", !0);
|
|
@@ -77,26 +77,26 @@ var j = { class: "tpl:w-full" }, M = { class: "tpl:flex tpl:gap-0" }, N = /* @__
|
|
|
77
77
|
__name: "ModulePreviewCanvas",
|
|
78
78
|
props: { blocks: {} },
|
|
79
79
|
setup(e) {
|
|
80
|
-
let i = t(
|
|
80
|
+
let i = t(k), l = {
|
|
81
81
|
section: N,
|
|
82
|
-
title:
|
|
83
|
-
paragraph:
|
|
84
|
-
image:
|
|
85
|
-
video:
|
|
86
|
-
button:
|
|
82
|
+
title: v,
|
|
83
|
+
paragraph: w,
|
|
84
|
+
image: O,
|
|
85
|
+
video: D,
|
|
86
|
+
button: S,
|
|
87
87
|
input: _,
|
|
88
|
-
divider:
|
|
88
|
+
divider: T,
|
|
89
89
|
social: p,
|
|
90
90
|
menu: m,
|
|
91
|
-
table:
|
|
92
|
-
spacer:
|
|
91
|
+
table: y,
|
|
92
|
+
spacer: b,
|
|
93
93
|
html: g,
|
|
94
94
|
countdown: A,
|
|
95
|
-
form:
|
|
95
|
+
form: x,
|
|
96
96
|
custom: E
|
|
97
97
|
};
|
|
98
98
|
function u(e) {
|
|
99
|
-
return
|
|
99
|
+
return C(e, i, l);
|
|
100
100
|
}
|
|
101
101
|
return (t, i) => (r(), d("div", P, [(r(!0), d(s, null, n(e.blocks, (e) => (r(), d("div", {
|
|
102
102
|
key: e.id,
|
|
@@ -110,4 +110,4 @@ var j = { class: "tpl:w-full" }, M = { class: "tpl:flex tpl:gap-0" }, N = /* @__
|
|
|
110
110
|
//#endregion
|
|
111
111
|
export { F as default };
|
|
112
112
|
|
|
113
|
-
//# sourceMappingURL=ModulePreviewCanvas-
|
|
113
|
+
//# sourceMappingURL=ModulePreviewCanvas-BIYYnqUq.js.map
|