@aswin.dev/editor 0.6.3 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/README.md +3 -3
  2. package/dist/AccessibilityPanel-COL6Wm7p.js +108 -0
  3. package/dist/AiChatSidebar-DWGPVtvC.js +229 -0
  4. package/dist/AiFeatureMenu-duUFSfDf.js +63 -0
  5. package/dist/BlockA11yBadge-Qs6HtXid.js +34 -0
  6. package/dist/CloudEditor-CFldoCOb.js +1207 -0
  7. package/dist/CollaboratorBar-Bw-lbt61.js +95 -0
  8. package/dist/CommentsSidebar-BaD5F53-.js +436 -0
  9. package/dist/CountdownBlock-DaYGxKqo.js +92 -0
  10. package/dist/CountdownToolbar-Dg4F8MTk.js +210 -0
  11. package/dist/DesignReferenceSidebar-BSH7uNP_.js +276 -0
  12. package/dist/LoadingTrack-Ba2pfF57.js +10 -0
  13. package/dist/ModuleBrowserModal-6phxZSKI.js +206 -0
  14. package/dist/ModulePreviewCanvas-BW8L3eQX.js +108 -0
  15. package/dist/NumberWithSuffix-BpUzQOJt.js +422 -0
  16. package/dist/ParagraphEditor-DNSzAB-I.js +695 -0
  17. package/dist/RichTextEditorContent-CrqPQdnk.js +137 -0
  18. package/dist/SaveModuleDialog-zMQTpez7.js +123 -0
  19. package/dist/SnapshotHistory-Do-A5rYU.js +122 -0
  20. package/dist/TemplateScoringPanel-CS7o62zS.js +256 -0
  21. package/dist/TestEmailModal-DGj_9V1u.js +94 -0
  22. package/dist/TitleEditor-C7IDnAoS.js +172 -0
  23. package/dist/TplModal-BAsVzcTb.js +44 -0
  24. package/dist/_plugin-vue_export-helper-BVAJ4lgT.js +8 -0
  25. package/dist/accessibility-BU09xZrQ.js +27 -0
  26. package/dist/blockTypeIcons-C6LDKvmd.js +140 -0
  27. package/dist/bundle-stats.json +10 -0
  28. package/dist/check-DJrpDKO_.js +7 -0
  29. package/dist/chevron-down-C5oBUhT8.js +7 -0
  30. package/dist/chevron-right-BqCptpdp.js +10 -0
  31. package/dist/circle-alert-ZQQc98HC.js +25 -0
  32. package/dist/clock-ik2pRJKG.js +12 -0
  33. package/dist/cloud-6ZmAvF0j.js +1791 -0
  34. package/dist/createLucideIcon-ClREiSx3.js +43 -0
  35. package/dist/de-DWcgp-7T.js +729 -0
  36. package/dist/de-GOtR9DwW.js +207 -0
  37. package/dist/dist-BUzw1buG.js +35 -0
  38. package/dist/dist-BZyY-SS4.js +74 -0
  39. package/dist/dist-BadNx4qo.js +5 -0
  40. package/dist/dist-BesOh2mk.js +35 -0
  41. package/dist/dist-Bz3M4RXG.js +2082 -0
  42. package/dist/dist-C04s_fLA.js +563 -0
  43. package/dist/dist-C3T2AKtB.js +776 -0
  44. package/dist/dist-C9ckKEZL.js +519 -0
  45. package/dist/dist-CBItRG-Z.js +47 -0
  46. package/dist/dist-COSzWQUs.js +5 -0
  47. package/dist/dist-CivF9P8b.js +382 -0
  48. package/dist/dist-DXa1uAMh.js +10658 -0
  49. package/dist/dist-DtiDUrX-.js +189 -0
  50. package/dist/dist-Dzt5foyL.js +61 -0
  51. package/dist/emojiData-DrBuvEoP.js +17 -0
  52. package/dist/en-Cxd4fhNm.js +729 -0
  53. package/dist/en-dFFQVzNn.js +207 -0
  54. package/dist/extensions-D__hOlV1.js +799 -0
  55. package/dist/formatRelativeTime-BhhO8yCl.js +12 -0
  56. package/dist/image-up-DT7gcJLN.js +23 -0
  57. package/dist/index.d.ts +352 -0
  58. package/dist/info-BSPGcsSM.js +19 -0
  59. package/dist/keys-CvX8D-8C.js +10 -0
  60. package/dist/liquid.browser-BvCyLQII.js +3277 -0
  61. package/dist/loader-circle-Balo8p3d.js +7 -0
  62. package/dist/message-circle-B39qAHxs.js +7 -0
  63. package/dist/pencil-BZJPNYWR.js +10 -0
  64. package/dist/readableTextColor-DVuzNX1y.js +30 -0
  65. package/dist/refresh-cw-DwDqGUM0.js +29 -0
  66. package/dist/rolldown-runtime-BZGGJVDF.js +20 -0
  67. package/dist/scan-line-CzfFJO1o.js +25 -0
  68. package/dist/send-D2eSo4GH.js +10 -0
  69. package/dist/shield-check-jkpgcC0-.js +10 -0
  70. package/dist/sparkles-Chm5CZfb.js +23 -0
  71. package/dist/style.css +2 -0
  72. package/dist/styleConstants-34eUKPOZ.js +55 -0
  73. package/dist/styles-B4tjX5SP.js +5224 -0
  74. package/dist/templatical-editor.js +312 -0
  75. package/dist/text-align-start-CzBnJsW8.js +43 -0
  76. package/dist/timeouts-BSGxjuUF.js +4 -0
  77. package/dist/trash-2-CtK2apEH.js +25 -0
  78. package/dist/triangle-alert-KpDVNbpn.js +17 -0
  79. package/dist/useCloudI18n-DOKSZql1.js +23 -0
  80. package/dist/useEditorCore-wslttMH-.js +9517 -0
  81. package/dist/useI18n-C2xQZ6K9.js +17 -0
  82. package/dist/useMergeTag-DX0XG5V9.js +34 -0
  83. package/dist/vue.runtime.esm-bundler-CjauPXjj.js +5775 -0
  84. package/dist/x-BkaOMosX.js +10 -0
  85. package/package.json +10 -10
package/README.md CHANGED
@@ -20,13 +20,13 @@ The visual editor for [Templatical](https://github.com/templatical/sdk) — an o
20
20
  npm install @aswin.dev/editor
21
21
  ```
22
22
 
23
- `@templatical/renderer` is an optional peer — install it only if you need to convert templates to MJML. The two common cases are:
23
+ `@aswin.dev/renderer` is an optional peer — install it only if you need to convert templates to MJML. The two common cases are:
24
24
 
25
25
  - **In the browser, alongside the editor**, when you call `editor.toMjml()` to export from the user's session.
26
26
  - **In Node.js (or another runtime)**, when you only have stored template JSON and want to convert it to MJML server-side. You don't need the editor for this — install just the renderer.
27
27
 
28
28
  ```bash
29
- npm install @templatical/renderer
29
+ npm install @aswin.dev/renderer
30
30
  ```
31
31
 
32
32
  If you call `editor.toMjml()` without the renderer installed, it throws a clear error naming the missing package.
@@ -44,7 +44,7 @@ const editor = await init({
44
44
  },
45
45
  });
46
46
 
47
- // Render to MJML when sending email — async; requires @templatical/renderer
47
+ // Render to MJML when sending email — async; requires @aswin.dev/renderer
48
48
  const mjml = await editor.toMjml();
49
49
 
50
50
  // Always unmount when removing the editor (cleans up listeners + DOM)
@@ -0,0 +1,108 @@
1
+ import { At as e, C as t, D as n, F as r, Ft as i, N as a, R as o, _ as s, b as c, f as l, g as u, h as d, m as f, st as p, v as m, x as h } from "./vue.runtime.esm-bundler-CjauPXjj.js";
2
+ import { m as g, t as _ } from "./keys-CvX8D-8C.js";
3
+ import { t as v } from "./useI18n-C2xQZ6K9.js";
4
+ import { t as y } from "./createLucideIcon-ClREiSx3.js";
5
+ import { t as b } from "./accessibility-BU09xZrQ.js";
6
+ import { t as x } from "./circle-alert-ZQQc98HC.js";
7
+ import { t as S } from "./info-BSPGcsSM.js";
8
+ import { t as C } from "./triangle-alert-KpDVNbpn.js";
9
+ var w = y("arrow-right", [["path", {
10
+ d: "M5 12h14",
11
+ key: "1ays0h"
12
+ }], ["path", {
13
+ d: "m12 5 7 7-7 7",
14
+ key: "xquz4c"
15
+ }]]), T = y("wrench", [["path", {
16
+ d: "M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z",
17
+ key: "1ngwbx"
18
+ }]]), E = { class: "tpl:flex tpl:flex-col tpl:gap-4 tpl:p-4" }, D = { class: "tpl:flex tpl:items-center tpl:gap-2" }, O = { class: "tpl:m-0 tpl:text-sm tpl:font-semibold tpl:text-[var(--tpl-text)]" }, k = ["title"], A = {
19
+ key: 0,
20
+ class: "tpl:text-xs tpl:text-[var(--tpl-text-muted)]"
21
+ }, j = {
22
+ key: 1,
23
+ class: "tpl:rounded-md tpl:border tpl:border-[var(--tpl-border)] tpl:bg-[var(--tpl-bg)] tpl:p-3 tpl:text-xs tpl:text-[var(--tpl-text-muted)]"
24
+ }, M = { class: "tpl:ml-auto tpl:font-normal tpl:opacity-70" }, N = {
25
+ key: 1,
26
+ class: "tpl:m-0 tpl:mb-3 tpl:flex tpl:list-none tpl:flex-col tpl:gap-2 tpl:p-0"
27
+ }, P = { class: "tpl:m-0 tpl:mb-2 tpl:text-xs tpl:text-[var(--tpl-text)]" }, F = { class: "tpl:m-0 tpl:mb-2 tpl:font-mono tpl:text-[10px] tpl:text-[var(--tpl-text-dim)]" }, I = { class: "tpl:flex tpl:gap-1.5" }, L = ["onClick"], R = ["title", "onClick"], z = /* @__PURE__ */ t({
28
+ __name: "AccessibilityPanel",
29
+ setup(t) {
30
+ let { t: y, format: z } = v(), B = n(_, null), V = n(g, null), H = f(() => (B?.issues.value ?? []).filter((e) => e.severity === "error")), U = f(() => (B?.issues.value ?? []).filter((e) => e.severity === "warning")), W = f(() => (B?.issues.value ?? []).filter((e) => e.severity === "info")), G = f(() => H.value.length + U.value.length + W.value.length);
31
+ function K(e) {
32
+ V && e.blockId && V.selectBlock(e.blockId);
33
+ }
34
+ function q(e) {
35
+ B?.applyFix(e);
36
+ }
37
+ return (t, n) => (a(), m("div", E, [d("header", D, [
38
+ h(p(b), {
39
+ size: 16,
40
+ "stroke-width": 1.5
41
+ }),
42
+ d("h3", O, i(p(y).accessibility.panelTitle), 1),
43
+ G.value > 0 ? (a(), m("span", {
44
+ key: 0,
45
+ class: "tpl:ml-auto tpl:rounded-full tpl:bg-[var(--tpl-bg-hover)] tpl:px-2 tpl:py-0.5 tpl:text-[11px] tpl:text-[var(--tpl-text-muted)]",
46
+ title: p(z)(p(y).accessibility.issueCountTooltip, { count: G.value })
47
+ }, i(G.value), 9, k)) : s("", !0)
48
+ ]), !p(B) || p(B).unavailable.value ? (a(), m("div", A)) : G.value === 0 ? (a(), m("div", j, i(p(y).accessibility.emptyState), 1)) : (a(!0), m(l, { key: 2 }, r([
49
+ {
50
+ key: "errors",
51
+ title: p(y).accessibility.groupErrors,
52
+ icon: p(x),
53
+ items: H.value,
54
+ tone: "tpl:text-[var(--tpl-danger)]"
55
+ },
56
+ {
57
+ key: "warnings",
58
+ title: p(y).accessibility.groupWarnings,
59
+ icon: p(C),
60
+ items: U.value,
61
+ tone: "tpl:text-[var(--tpl-warning)]"
62
+ },
63
+ {
64
+ key: "info",
65
+ title: p(y).accessibility.groupInfo,
66
+ icon: p(S),
67
+ items: W.value,
68
+ tone: "tpl:text-[var(--tpl-text-muted)]"
69
+ }
70
+ ], (t) => (a(), m("section", { key: t.key }, [t.items.length > 0 ? (a(), m("header", {
71
+ key: 0,
72
+ class: e(["tpl:mb-2 tpl:flex tpl:items-center tpl:gap-1.5 tpl:text-[11px] tpl:font-semibold tpl:uppercase tpl:tracking-wide", t.tone])
73
+ }, [
74
+ (a(), u(o(t.icon), {
75
+ size: 12,
76
+ "stroke-width": 2
77
+ })),
78
+ c(" " + i(t.title) + " ", 1),
79
+ d("span", M, i(t.items.length), 1)
80
+ ], 2)) : s("", !0), t.items.length > 0 ? (a(), m("ul", N, [(a(!0), m(l, null, r(t.items, (e) => (a(), m("li", {
81
+ key: `${e.ruleId}-${e.blockId ?? "template"}`,
82
+ class: "tpl:rounded-md tpl:border tpl:border-[var(--tpl-border)] tpl:bg-[var(--tpl-bg)] tpl:p-3"
83
+ }, [
84
+ d("p", P, i(e.message), 1),
85
+ d("p", F, i(e.ruleId), 1),
86
+ d("div", I, [e.blockId ? (a(), m("button", {
87
+ key: 0,
88
+ type: "button",
89
+ class: "tpl:flex tpl:items-center tpl:gap-1 tpl:rounded-md tpl:border tpl:border-[var(--tpl-border)] tpl:bg-[var(--tpl-bg-hover)] tpl:px-2 tpl:py-1 tpl:text-[11px] tpl:font-medium tpl:text-[var(--tpl-text)]",
90
+ onClick: (t) => K(e)
91
+ }, [h(p(w), {
92
+ size: 10,
93
+ "stroke-width": 2
94
+ }), c(" " + i(p(y).accessibility.jump), 1)], 8, L)) : s("", !0), e.fix ? (a(), m("button", {
95
+ key: 1,
96
+ type: "button",
97
+ class: "tpl:flex tpl:items-center tpl:gap-1 tpl:rounded-md tpl:bg-[var(--tpl-primary)] tpl:px-2 tpl:py-1 tpl:text-[11px] tpl:font-medium tpl:text-white",
98
+ title: e.fix.description,
99
+ onClick: (t) => q(e)
100
+ }, [h(p(T), {
101
+ size: 10,
102
+ "stroke-width": 2
103
+ }), c(" " + i(p(y).accessibility.fix), 1)], 8, R)) : s("", !0)])
104
+ ]))), 128))])) : s("", !0)]))), 128))]));
105
+ }
106
+ });
107
+ //#endregion
108
+ export { z as default };
@@ -0,0 +1,229 @@
1
+ import { A as e, At as t, C as n, D as r, F as i, Ft as a, N as o, U as ee, V as s, W as te, _ as c, b as l, c as ne, et as u, f as d, g as f, h as p, k as re, st as m, t as ie, v as h, x as g } from "./vue.runtime.esm-bundler-CjauPXjj.js";
2
+ import { c as ae, l as oe } from "./dist-CivF9P8b.js";
3
+ import { A as _, i as se, l as v, m as ce, y as le } from "./keys-CvX8D-8C.js";
4
+ import { t as y } from "./createLucideIcon-ClREiSx3.js";
5
+ import { t as b } from "./circle-alert-ZQQc98HC.js";
6
+ import { t as ue } from "./loader-circle-Balo8p3d.js";
7
+ import { t as de } from "./send-D2eSo4GH.js";
8
+ import { t as x } from "./sparkles-Chm5CZfb.js";
9
+ import { t as fe } from "./trash-2-CtK2apEH.js";
10
+ import { t as pe } from "./x-BkaOMosX.js";
11
+ import { t as S } from "./LoadingTrack-Ba2pfF57.js";
12
+ import { t as C } from "./_plugin-vue_export-helper-BVAJ4lgT.js";
13
+ import { i as w } from "./cloud-6ZmAvF0j.js";
14
+ var T = y("redo-2", [["path", {
15
+ d: "m15 14 5-5-5-5",
16
+ key: "12vg1m"
17
+ }], ["path", {
18
+ d: "M20 9H9.5A5.5 5.5 0 0 0 4 14.5A5.5 5.5 0 0 0 9.5 20H13",
19
+ key: "6uklza"
20
+ }]]), E = y("undo-2", [["path", {
21
+ d: "M9 14 4 9l5-5",
22
+ key: "102s5s"
23
+ }], ["path", {
24
+ d: "M4 9h10.5a5.5 5.5 0 0 1 5.5 5.5a5.5 5.5 0 0 1-5.5 5.5H11",
25
+ key: "f3b9sd"
26
+ }]]);
27
+ //#endregion
28
+ //#region src/composables/useAliveFlag.ts
29
+ function D() {
30
+ let t = { alive: !0 };
31
+ return e(() => {
32
+ t.alive = !1;
33
+ }), t;
34
+ }
35
+ //#endregion
36
+ //#region src/cloud/components/AiChatSidebar.vue?vue&type=script&setup=true&lang.ts
37
+ var O = {
38
+ key: 0,
39
+ class: "tpl-ai-sidebar tpl:absolute tpl:top-14 tpl:right-0 tpl:bottom-0 tpl:z-panel tpl:flex tpl:w-[360px] tpl:flex-col tpl:border-l tpl:border-[var(--tpl-border)] tpl:bg-[var(--tpl-bg-elevated)]"
40
+ }, k = { class: "tpl:flex tpl:items-center tpl:justify-between tpl:border-b tpl:border-[var(--tpl-border)] tpl:px-4 tpl:py-3" }, A = { class: "tpl:flex tpl:items-center tpl:gap-1.5 tpl:text-sm tpl:font-medium tpl:text-[var(--tpl-primary)]" }, j = { class: "tpl:flex tpl:items-center tpl:gap-1" }, M = ["title"], N = { class: "tpl:relative tpl:flex tpl:min-h-0 tpl:flex-1 tpl:flex-col" }, P = {
41
+ key: 0,
42
+ class: "tpl:flex tpl:h-full tpl:flex-col tpl:items-center tpl:justify-center tpl:gap-3 tpl:text-center"
43
+ }, F = { class: "tpl:text-sm tpl:text-[var(--tpl-text-muted)]" }, I = {
44
+ key: 1,
45
+ class: "tpl:flex tpl:h-full tpl:flex-col tpl:items-center tpl:justify-center tpl:gap-3 tpl:text-center"
46
+ }, L = { class: "tpl:max-w-[240px] tpl:text-sm tpl:text-[var(--tpl-text-muted)]" }, R = {
47
+ key: 2,
48
+ class: "tpl:flex tpl:flex-col tpl:gap-4"
49
+ }, z = {
50
+ key: 0,
51
+ class: "tpl:self-end tpl:rounded-[var(--tpl-radius-sm)] tpl:px-3.5 tpl:py-2.5 tpl:text-sm",
52
+ style: {
53
+ "background-color": "var(--tpl-primary-light)",
54
+ color: "var(--tpl-text)",
55
+ "max-width": "85%",
56
+ "box-shadow": "var(--tpl-shadow)"
57
+ }
58
+ }, B = {
59
+ key: 1,
60
+ class: "tpl:flex tpl:flex-col tpl:gap-2"
61
+ }, me = {
62
+ key: 1,
63
+ class: "tpl:rounded-[var(--tpl-radius-sm)] tpl:px-3.5 tpl:py-2.5 tpl:text-sm tpl:whitespace-pre-wrap",
64
+ style: {
65
+ "max-width": "85%",
66
+ "background-color": "var(--tpl-bg)",
67
+ color: "var(--tpl-text)",
68
+ "box-shadow": "var(--tpl-shadow)"
69
+ }
70
+ }, he = {
71
+ key: 0,
72
+ class: "tpl:mx-3 tpl:mb-2 tpl:flex tpl:items-start tpl:gap-2 tpl:rounded-lg tpl:px-3 tpl:py-2 tpl:text-xs",
73
+ style: {
74
+ "background-color": "var(--tpl-danger-light)",
75
+ color: "var(--tpl-danger)"
76
+ }
77
+ }, ge = {
78
+ key: 1,
79
+ class: "tpl:absolute tpl:right-0 tpl:bottom-0 tpl:left-0 tpl:z-10 tpl:px-3 tpl:pb-3",
80
+ style: {
81
+ "background-color": "color-mix(\n in srgb,\n var(--tpl-bg) 50%,\n transparent\n )",
82
+ "backdrop-filter": "blur(2px)"
83
+ }
84
+ }, _e = { class: "tpl:flex tpl:flex-col tpl:gap-1.5" }, ve = ["onClick"], ye = { class: "tpl:border-t tpl:p-3 tpl:border-[var(--tpl-border)]" }, be = { class: "tpl-ai-input-wrapper tpl:flex tpl:items-end tpl:gap-2 tpl:rounded-[var(--tpl-radius)] tpl:border tpl:px-3 tpl:py-2 tpl:border-[var(--tpl-border)] tpl:bg-[var(--tpl-bg)]" }, xe = ["placeholder", "disabled"], Se = ["disabled"], Ce = { class: "tpl:m-0 tpl:px-1 tpl:pt-2 tpl:text-center tpl:text-[11px] tpl:text-[var(--tpl-text-dim)]" }, V = /* @__PURE__ */ C(/* @__PURE__ */ n({
85
+ __name: "AiChatSidebar",
86
+ props: {
87
+ visible: { type: Boolean },
88
+ onApply: { type: Function }
89
+ },
90
+ emits: ["close"],
91
+ setup(e, { emit: n }) {
92
+ let y = e, C = n, V = _(v, "AiChatSidebar"), H = _(ce, "AiChatSidebar"), we = _(se, "AiChatSidebar"), U = r(le, []), W = D(), G = w({
93
+ authManager: we,
94
+ getTemplateId: () => H.state.template?.id ?? null,
95
+ onApply: y.onApply,
96
+ onError: void 0
97
+ }), K = u(""), q = u(null), J = u(!1), Y = u(0), { pause: X, resume: Te } = ae(() => {
98
+ let e = G.suggestions.value?.length ?? 0;
99
+ Y.value < e ? Y.value++ : X();
100
+ }, 150, { immediate: !1 }), { start: Ee } = oe(() => Te(), 100, { immediate: !1 });
101
+ s(() => G.suggestions.value?.length ?? 0, (e) => {
102
+ if (X(), e === 0) {
103
+ Y.value = 0;
104
+ return;
105
+ }
106
+ Y.value = 0, Ee();
107
+ });
108
+ function Z() {
109
+ re(() => {
110
+ q.value && (q.value.scrollTop = q.value.scrollHeight);
111
+ });
112
+ }
113
+ s(() => G.messages.value?.length ?? 0, () => Z()), s(() => y.visible, async (e) => {
114
+ if (e && !J.value) {
115
+ if (J.value = !0, await G.loadConversation(), !W.alive) return;
116
+ (G.messages.value?.length ?? 0) === 0 && H.content.value.blocks.length === 0 && G.loadSuggestions(H.content.value, U);
117
+ }
118
+ });
119
+ async function Q() {
120
+ let e = K.value.trim();
121
+ !e || G.isGenerating.value || (K.value = "", G.error.value = null, G.failedPrompt.value = null, Z(), await G.sendPrompt(e, H.content.value, U), W.alive && (G.failedPrompt.value && (K.value = G.failedPrompt.value), Z()));
122
+ }
123
+ function $(e) {
124
+ return e.replace(/```json[\s\S]*?```/g, "").replace(/```json[\s\S]*/g, "").trim();
125
+ }
126
+ function De(e) {
127
+ X(), K.value = e, Q();
128
+ }
129
+ function Oe(e) {
130
+ e.key === "Enter" && !e.shiftKey && (e.preventDefault(), Q());
131
+ }
132
+ return (n, r) => (o(), f(ie, {
133
+ "enter-active-class": "tpl-ai-slide-enter-active",
134
+ "enter-from-class": "tpl:translate-x-full",
135
+ "enter-to-class": "tpl:translate-x-0",
136
+ "leave-active-class": "tpl-ai-slide-leave-active",
137
+ "leave-from-class": "tpl:translate-x-0",
138
+ "leave-to-class": "tpl:translate-x-full"
139
+ }, {
140
+ default: ee(() => [e.visible ? (o(), h("div", O, [
141
+ p("div", k, [p("div", A, [g(m(x), {
142
+ size: 13,
143
+ "stroke-width": 2
144
+ }), p("span", null, a(m(V).aiChat.title), 1)]), p("div", j, [(m(G).messages.value?.length ?? 0) > 0 ? (o(), h("button", {
145
+ key: 0,
146
+ class: "tpl:rounded-md tpl:p-0.5 tpl:transition-colors tpl:duration-150 tpl:text-[var(--tpl-text-muted)]",
147
+ title: m(V).aiChat.clear,
148
+ onClick: r[0] ||= (e) => m(G).clearChat()
149
+ }, [g(m(fe), {
150
+ size: 14,
151
+ "stroke-width": 2
152
+ })], 8, M)) : c("", !0), p("button", {
153
+ class: "tpl:rounded-md tpl:p-0.5 tpl:transition-colors tpl:duration-150 tpl:text-[var(--tpl-text-muted)]",
154
+ onClick: r[1] ||= (e) => C("close")
155
+ }, [g(m(pe), {
156
+ size: 14,
157
+ "stroke-width": 2
158
+ })])])]),
159
+ p("div", N, [
160
+ p("div", {
161
+ ref_key: "messagesContainer",
162
+ ref: q,
163
+ class: "tpl:flex-1 tpl:overflow-y-auto tpl:p-4"
164
+ }, [m(G).isLoadingHistory.value ? (o(), h("div", P, [g(m(ue), {
165
+ class: "tpl-spinner tpl:text-[var(--tpl-text-muted)]",
166
+ size: 24,
167
+ "stroke-width": 2
168
+ }), p("p", F, a(m(V).aiChat.loadingHistory), 1)])) : (m(G).messages.value?.length ?? 0) === 0 ? (o(), h("div", I, [g(m(x), {
169
+ size: 32,
170
+ "stroke-width": 1.5,
171
+ class: "tpl:text-[var(--tpl-text-dim)]"
172
+ }), p("p", L, a(m(V).aiChat.placeholder), 1)])) : (o(), h("div", R, [(o(!0), h(d, null, i(m(G).messages.value, (e, t) => (o(), h("div", {
173
+ key: e.id,
174
+ class: "tpl:flex tpl:flex-col tpl:gap-2"
175
+ }, [e.role === "user" ? (o(), h("div", z, a(e.content), 1)) : (o(), h("div", B, [!$(e.content) && m(G).isGenerating.value && t === (m(G).messages.value?.length ?? 0) - 1 ? (o(), f(S, { key: 0 })) : (o(), h("div", me, a($(e.content) || m(V).aiChat.applied), 1)), e.id === m(G).lastApplyMessageId.value && !m(G).isGenerating.value ? (o(), h("button", {
176
+ key: 2,
177
+ class: "tpl:inline-flex tpl:items-center tpl:gap-1.5 tpl:self-start tpl:rounded-md tpl:border tpl:px-2.5 tpl:py-1.5 tpl:text-xs tpl:font-medium tpl:transition-all tpl:duration-150",
178
+ style: {
179
+ "border-color": "var(--tpl-border)",
180
+ color: "var(--tpl-text-muted)",
181
+ "background-color": "transparent"
182
+ },
183
+ onClick: r[2] ||= (e) => m(G).toggleLastRevert()
184
+ }, [m(G).isLastChangeReverted.value ? (o(), h(d, { key: 0 }, [g(m(T), {
185
+ size: 12,
186
+ "stroke-width": 2
187
+ }), l(" " + a(m(V).aiChat.reapply), 1)], 64)) : (o(), h(d, { key: 1 }, [g(m(E), {
188
+ size: 12,
189
+ "stroke-width": 2
190
+ }), l(" " + a(m(V).aiChat.revert), 1)], 64))])) : c("", !0)]))]))), 128))]))], 512),
191
+ m(G).error.value ? (o(), h("div", he, [g(m(b), {
192
+ size: 14,
193
+ "stroke-width": 2,
194
+ class: "tpl:mt-0.5 tpl:shrink-0"
195
+ }), p("span", null, a(m(G).error.value === "ai_apply_failed" ? m(V).aiChat.applyFailed : m(V).aiChat.error), 1)])) : c("", !0),
196
+ (m(G).suggestions.value?.length ?? 0) > 0 ? (o(), h("div", ge, [p("div", _e, [(o(!0), h(d, null, i(m(G).suggestions.value ?? [], (e, n) => (o(), h("button", {
197
+ key: n,
198
+ class: t(["tpl-suggestion-btn tpl:cursor-pointer tpl:rounded-[var(--tpl-radius-sm)] tpl:border tpl:px-3 tpl:py-2 tpl:text-left tpl:text-xs tpl:leading-snug tpl:transition-all tpl:duration-300 tpl:ease-out", (m(G).suggestions.value?.length ?? 0) - 1 - n < Y.value ? "tpl:translate-y-0 tpl:opacity-100" : "tpl:pointer-events-none tpl:-translate-y-2 tpl:opacity-0"]),
199
+ style: {
200
+ "border-color": "var(--tpl-border)",
201
+ color: "var(--tpl-primary)",
202
+ "background-color": "var(--tpl-bg)",
203
+ "box-shadow": "var(--tpl-shadow)"
204
+ },
205
+ onClick: (t) => De(e)
206
+ }, a(e), 11, ve))), 128))])])) : c("", !0)
207
+ ]),
208
+ p("div", ye, [p("div", be, [te(p("textarea", {
209
+ "onUpdate:modelValue": r[3] ||= (e) => K.value = e,
210
+ class: "tpl:max-h-32 tpl:min-h-[64px] tpl:flex-1 tpl:resize-none tpl:border-none tpl:bg-transparent tpl:font-sans tpl:text-sm tpl:outline-none tpl:text-[var(--tpl-text)]",
211
+ placeholder: m(V).aiChat.inputPlaceholder,
212
+ disabled: m(G).isGenerating.value,
213
+ rows: "3",
214
+ onKeydown: Oe
215
+ }, null, 40, xe), [[ne, K.value]]), p("button", {
216
+ class: "tpl-ai-send-btn tpl:flex tpl:shrink-0 tpl:items-center tpl:justify-center tpl:rounded-md tpl:p-1.5 tpl:transition-all tpl:duration-150 tpl:disabled:opacity-40 tpl:text-[var(--tpl-primary)]",
217
+ disabled: !K.value.trim() || m(G).isGenerating.value,
218
+ onClick: Q
219
+ }, [g(m(de), {
220
+ size: 16,
221
+ "stroke-width": 2
222
+ })], 8, Se)]), p("p", Ce, a(m(V).aiMenu.disclaimer), 1)])
223
+ ])) : c("", !0)]),
224
+ _: 1
225
+ }));
226
+ }
227
+ }), [["__scopeId", "data-v-384b60d9"]]);
228
+ //#endregion
229
+ export { V as default };
@@ -0,0 +1,63 @@
1
+ import { C as e, F as t, Ft as n, N as r, R as i, f as a, g as o, h as s, jt as c, m as l, v as u } from "./vue.runtime.esm-bundler-CjauPXjj.js";
2
+ import "./useEditorCore-wslttMH-.js";
3
+ import { A as d, n as f } from "./keys-CvX8D-8C.js";
4
+ import { t as p } from "./image-up-DT7gcJLN.js";
5
+ import { t as m } from "./shield-check-jkpgcC0-.js";
6
+ import { t as h } from "./sparkles-Chm5CZfb.js";
7
+ import { t as g } from "./_plugin-vue_export-helper-BVAJ4lgT.js";
8
+ import { n as _ } from "./useCloudI18n-DOKSZql1.js";
9
+ //#region src/cloud/components/AiFeatureMenu.vue?vue&type=script&setup=true&lang.ts
10
+ var v = {
11
+ class: "tpl-ai-feature-menu tpl:w-[280px] tpl:overflow-hidden tpl:rounded-[var(--tpl-radius)] tpl:py-1 tpl:bg-[var(--tpl-bg-elevated)] tpl:border tpl:border-[var(--tpl-border)] tpl:shadow-[var(--tpl-shadow-lg)]",
12
+ style: {
13
+ "backdrop-filter": "blur(8px)",
14
+ "-webkit-backdrop-filter": "blur(8px)"
15
+ }
16
+ }, y = ["onClick"], b = { class: "tpl:flex tpl:min-w-0 tpl:flex-col tpl:gap-0.5" }, x = { class: "tpl:text-sm tpl:font-medium tpl:text-[var(--tpl-text)]" }, S = { class: "tpl:text-xs tpl:leading-snug tpl:text-[var(--tpl-text-muted)]" }, C = /* @__PURE__ */ g(/* @__PURE__ */ e({
17
+ __name: "AiFeatureMenu",
18
+ props: { activeFeature: {} },
19
+ emits: ["select"],
20
+ setup(e, { emit: g }) {
21
+ let C = g, { t: w } = _(), T = d(f, "AiFeatureMenu"), E = {
22
+ "ai-chat": "chat",
23
+ "design-reference": "designToTemplate",
24
+ scoring: "scoring"
25
+ }, D = [
26
+ {
27
+ key: "ai-chat",
28
+ icon: h
29
+ },
30
+ {
31
+ key: "design-reference",
32
+ icon: p
33
+ },
34
+ {
35
+ key: "scoring",
36
+ icon: m
37
+ }
38
+ ], O = l(() => D.filter((e) => T.isFeatureEnabled(E[e.key])));
39
+ function k(e) {
40
+ return e === "ai-chat" ? w.aiMenu.aiAssistant : e === "design-reference" ? w.aiMenu.designToTemplate : w.aiMenu.templateScore;
41
+ }
42
+ function A(e) {
43
+ return e === "ai-chat" ? w.aiMenu.aiAssistantDesc : e === "design-reference" ? w.aiMenu.designToTemplateDesc : w.aiMenu.templateScoreDesc;
44
+ }
45
+ return (l, d) => (r(), u("div", v, [(r(!0), u(a, null, t(O.value, (t) => (r(), u("button", {
46
+ key: t.key,
47
+ class: "tpl-ai-feature-menu-item tpl:flex tpl:w-full tpl:cursor-pointer tpl:items-start tpl:gap-3 tpl:border-none tpl:px-3 tpl:py-2.5 tpl:text-left tpl:transition-colors tpl:duration-100",
48
+ style: c({ backgroundColor: e.activeFeature === t.key ? "var(--tpl-primary-light)" : "transparent" }),
49
+ onClick: (e) => C("select", t.key)
50
+ }, [s("div", {
51
+ class: "tpl:mt-0.5 tpl:flex tpl:size-7 tpl:shrink-0 tpl:items-center tpl:justify-center tpl:rounded-[var(--tpl-radius-sm)]",
52
+ style: c({
53
+ backgroundColor: e.activeFeature === t.key ? "var(--tpl-primary)" : "var(--tpl-bg-active)",
54
+ color: e.activeFeature === t.key ? "var(--tpl-bg)" : "var(--tpl-text-muted)"
55
+ })
56
+ }, [(r(), o(i(t.icon), {
57
+ size: 15,
58
+ "stroke-width": 2
59
+ }))], 4), s("div", b, [s("span", x, n(k(t.key)), 1), s("span", S, n(A(t.key)), 1)])], 12, y))), 128))]));
60
+ }
61
+ }), [["__scopeId", "data-v-98d85462"]]);
62
+ //#endregion
63
+ export { C as default };
@@ -0,0 +1,34 @@
1
+ import { At as e, C as t, D as n, N as r, _ as i, g as a, m as o, st as s, v as c } from "./vue.runtime.esm-bundler-CjauPXjj.js";
2
+ import { t as l } from "./keys-CvX8D-8C.js";
3
+ import { t as u } from "./useI18n-C2xQZ6K9.js";
4
+ import { t as d } from "./circle-alert-ZQQc98HC.js";
5
+ import { t as f } from "./triangle-alert-KpDVNbpn.js";
6
+ //#region src/components/canvas/BlockA11yBadge.vue?vue&type=script&setup=true&lang.ts
7
+ var p = ["title", "aria-label"], m = /* @__PURE__ */ t({
8
+ __name: "BlockA11yBadge",
9
+ props: { blockId: {} },
10
+ setup(t) {
11
+ let m = t, { t: h } = u(), g = n(l, null), _ = o(() => (g?.issues.value ?? []).filter((e) => e.blockId === m.blockId)), v = o(() => _.value.some((e) => e.severity === "error") ? "error" : _.value.some((e) => e.severity === "warning") ? "warning" : null), y = o(() => v.value === "error" ? h.accessibility.badgeError : h.accessibility.badgeWarning);
12
+ return (t, n) => v.value ? (r(), c("span", {
13
+ key: 0,
14
+ class: e(["tpl:absolute tpl:top-1 tpl:right-1 tpl:z-10 tpl:flex tpl:size-5 tpl:items-center tpl:justify-center tpl:rounded-full tpl:bg-[var(--tpl-bg)] tpl:shadow-[var(--tpl-shadow-sm)] tpl:ring-1 tpl:ring-[var(--tpl-border)]", v.value === "error" ? "tpl:text-[var(--tpl-danger)]" : "tpl:text-[var(--tpl-warning)]"]),
15
+ title: y.value,
16
+ "aria-label": y.value,
17
+ role: "img"
18
+ }, [v.value === "error" ? (r(), a(s(d), {
19
+ key: 0,
20
+ size: 14,
21
+ "stroke-width": 2.25,
22
+ fill: "currentColor",
23
+ stroke: "var(--tpl-bg)"
24
+ })) : (r(), a(s(f), {
25
+ key: 1,
26
+ size: 14,
27
+ "stroke-width": 2.25,
28
+ fill: "currentColor",
29
+ stroke: "var(--tpl-bg)"
30
+ }))], 10, p)) : i("", !0);
31
+ }
32
+ });
33
+ //#endregion
34
+ export { m as default };