@g1cloud/page-builder-editor 1.0.0-alpha.11 → 1.0.0-alpha.13

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.
@@ -243,18 +243,21 @@
243
243
 
244
244
  .tags {
245
245
  height: 60%;
246
+
247
+ .content {
248
+ overflow-y: auto;
249
+ }
246
250
  }
247
251
 
248
252
  .style {
249
253
  height: 40%;
250
- }
251
254
 
252
- .bs-code-editor {
253
- height: 100%;
255
+ .content {
256
+ overflow-y: auto;
257
+ }
254
258
  }
255
259
 
256
- textarea {
257
- width: 100%;
260
+ .bs-code-editor {
258
261
  height: 100%;
259
262
  }
260
263
  }
@@ -0,0 +1,131 @@
1
+ import { defineComponent, ref, computed, openBlock, createBlock, unref, withCtx, createElementVNode, createVNode, createSlots, renderList } from "vue";
2
+ import { useModalHandle, BSModalFrame, BSTabSheet, BSCodeEditor } from "@g1cloud/bluesea";
3
+ const _hoisted_1 = { class: "bs-layout-vertical flex-grow-1 h-full" };
4
+ const _hoisted_2 = { class: "bs-layout-horizontal h-full pt-8" };
5
+ const _hoisted_3 = { class: "preview flex-grow-1" };
6
+ const _hoisted_4 = { class: "bs-layout-vertical w-full h-full" };
7
+ const _hoisted_5 = /* @__PURE__ */ createElementVNode("div", { class: "title pb-4" }, "Preview", -1);
8
+ const _hoisted_6 = ["innerHTML"];
9
+ const _hoisted_7 = { class: "editor bs-layout-vertical pl-8" };
10
+ const _hoisted_8 = { class: "tags bs-layout-vertical w-full" };
11
+ const _hoisted_9 = /* @__PURE__ */ createElementVNode("div", { class: "title pb-4" }, "HTML", -1);
12
+ const _hoisted_10 = { class: "content flex-grow-1" };
13
+ const _hoisted_11 = { class: "style bs-layout-vertical w-full pt-8" };
14
+ const _hoisted_12 = /* @__PURE__ */ createElementVNode("div", { class: "title pb-4" }, "Style", -1);
15
+ const _hoisted_13 = { class: "content flex-grow-1" };
16
+ const _sfc_main = /* @__PURE__ */ defineComponent({
17
+ __name: "HtmlEditorModal",
18
+ props: {
19
+ html: {},
20
+ locales: {},
21
+ localeTabs: {}
22
+ },
23
+ emits: ["updateHtml"],
24
+ setup(__props, { emit: __emit }) {
25
+ const props = __props;
26
+ const emit = __emit;
27
+ const tabId = ref(props.localeTabs && props.localeTabs[0].tabId);
28
+ const modalHandle = useModalHandle();
29
+ const html = ref(props.html || {});
30
+ const preview = computed(() => {
31
+ var _a;
32
+ let data = {};
33
+ (_a = props.locales) == null ? void 0 : _a.forEach((locale) => {
34
+ const _html = html.value[locale] || { tags: "", style: "" };
35
+ data[locale] = _html.tags ? `${_html.tags}
36
+ <style>${_html.style}</style>` : "";
37
+ });
38
+ return data;
39
+ });
40
+ const updateTags = (locale, value) => {
41
+ if (!html.value)
42
+ html.value = {};
43
+ if (!html.value[locale])
44
+ html.value[locale] = {};
45
+ html.value[locale].tags = value;
46
+ };
47
+ const updateStyle = (locale, value) => {
48
+ if (!html.value)
49
+ html.value = {};
50
+ if (!html.value[locale])
51
+ html.value[locale] = {};
52
+ html.value[locale].style = value;
53
+ };
54
+ const ok = () => {
55
+ emit("updateHtml", html.value);
56
+ modalHandle.close();
57
+ };
58
+ return (_ctx, _cache) => {
59
+ return openBlock(), createBlock(unref(BSModalFrame), {
60
+ class: "pb-html-editor-modal",
61
+ title: "HTML Editor"
62
+ }, {
63
+ default: withCtx(() => [
64
+ createElementVNode("div", _hoisted_1, [
65
+ createVNode(unref(BSTabSheet), {
66
+ "tab-id": tabId.value,
67
+ "onUpdate:tabId": _cache[0] || (_cache[0] = ($event) => tabId.value = $event),
68
+ tabs: _ctx.localeTabs,
69
+ class: "flex-grow-1"
70
+ }, createSlots({ _: 2 }, [
71
+ renderList(_ctx.locales, (locale) => {
72
+ return {
73
+ name: `tab-${locale}`,
74
+ fn: withCtx(() => [
75
+ createElementVNode("div", _hoisted_2, [
76
+ createElementVNode("div", _hoisted_3, [
77
+ createElementVNode("div", _hoisted_4, [
78
+ _hoisted_5,
79
+ createElementVNode("div", {
80
+ class: "content flex-grow-1",
81
+ innerHTML: preview.value[locale]
82
+ }, null, 8, _hoisted_6)
83
+ ])
84
+ ]),
85
+ createElementVNode("div", _hoisted_7, [
86
+ createElementVNode("div", _hoisted_8, [
87
+ _hoisted_9,
88
+ createElementVNode("div", _hoisted_10, [
89
+ createVNode(unref(BSCodeEditor), {
90
+ "model-value": (html.value[locale] || {}).tags,
91
+ "editor-height": "100%",
92
+ lang: "html",
93
+ "onUpdate:modelValue": (value) => updateTags(locale, value)
94
+ }, null, 8, ["model-value", "onUpdate:modelValue"])
95
+ ])
96
+ ]),
97
+ createElementVNode("div", _hoisted_11, [
98
+ _hoisted_12,
99
+ createElementVNode("div", _hoisted_13, [
100
+ createVNode(unref(BSCodeEditor), {
101
+ "model-value": (html.value[locale] || {}).style,
102
+ "editor-height": "100%",
103
+ lang: "css",
104
+ "onUpdate:modelValue": (value) => updateStyle(locale, value)
105
+ }, null, 8, ["model-value", "onUpdate:modelValue"])
106
+ ])
107
+ ])
108
+ ])
109
+ ])
110
+ ])
111
+ };
112
+ })
113
+ ]), 1032, ["tab-id", "tabs"])
114
+ ])
115
+ ]),
116
+ buttons: withCtx(() => [
117
+ createElementVNode("div", { class: "bs-layout-horizontal justify-content-center" }, [
118
+ createElementVNode("button", {
119
+ class: "mr-4",
120
+ onClick: ok
121
+ }, "OK")
122
+ ])
123
+ ]),
124
+ _: 1
125
+ });
126
+ };
127
+ }
128
+ });
129
+ export {
130
+ _sfc_main as default
131
+ };
@@ -3,7 +3,8 @@ declare const _default: import('vue').DefineComponent<__VLS_TypePropsToRuntimePr
3
3
  title?: string | undefined;
4
4
  editMode?: string | undefined;
5
5
  pageContent?: any;
6
- language?: string | undefined;
6
+ locales?: string[] | undefined;
7
+ locale?: string | undefined;
7
8
  }>, {
8
9
  getLocalDesignPartContent: () => any[] | undefined;
9
10
  }, unknown, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<__VLS_TypePropsToRuntimeProps<{
@@ -11,7 +12,8 @@ declare const _default: import('vue').DefineComponent<__VLS_TypePropsToRuntimePr
11
12
  title?: string | undefined;
12
13
  editMode?: string | undefined;
13
14
  pageContent?: any;
14
- language?: string | undefined;
15
+ locales?: string[] | undefined;
16
+ locale?: string | undefined;
15
17
  }>>>, {}, {}>;
16
18
  export default _default;
17
19
  type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
@@ -1,6 +1,6 @@
1
1
  import { defineComponent, openBlock, createElementBlock, createElementVNode, toDisplayString, createVNode, unref } from "vue";
2
2
  import { BSTextInput } from "@g1cloud/bluesea";
3
- import { P as PbColorPicker } from "./index-DdC6jCrv.js";
3
+ import { P as PbColorPicker } from "./index-CmE7SdtL.js";
4
4
  const _hoisted_1 = { class: "property-editor property-editor-color" };
5
5
  const _hoisted_2 = { class: "title" };
6
6
  const _hoisted_3 = ["textContent"];
@@ -1,6 +1,6 @@
1
1
  import { defineComponent, openBlock, createElementBlock, createElementVNode, toDisplayString, defineAsyncComponent } from "vue";
2
2
  import { useModal } from "@g1cloud/bluesea";
3
- import { u as usePageBuilderEditor } from "./index-DdC6jCrv.js";
3
+ import { u as usePageBuilderEditor } from "./index-CmE7SdtL.js";
4
4
  const _hoisted_1 = { class: "property-editor property-editor-image flex-align-center" };
5
5
  const _hoisted_2 = { class: "title" };
6
6
  const _hoisted_3 = ["textContent"];
@@ -17,13 +17,10 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
17
17
  const pageBuilder = usePageBuilderEditor();
18
18
  const emit = __emit;
19
19
  const editHtml = () => {
20
- const language = pageBuilder.getLanguage();
21
- let html;
22
- if (props.value && typeof props.value === "object") {
23
- html = props.value[language];
24
- }
20
+ const locales = pageBuilder.getLocales();
21
+ const localeTabs = locales.map((v) => ({ tabId: `tab-${v}`, caption: v }));
25
22
  modal.openModal({
26
- component: defineAsyncComponent(() => import("./HtmlEditorModal-B2wOdZTD.js")),
23
+ component: defineAsyncComponent(() => import("./HtmlEditorModal-CRzp6l55.js")),
27
24
  style: {
28
25
  width: "80%",
29
26
  height: "80%",
@@ -31,16 +28,13 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
31
28
  minHeight: "400px"
32
29
  },
33
30
  bind: {
34
- html
31
+ html: JSON.parse(JSON.stringify(props.value || {})),
32
+ locales,
33
+ localeTabs
35
34
  },
36
35
  on: {
37
- updateHtml: (html2) => {
38
- const language2 = pageBuilder.getLanguage();
39
- const value = {
40
- ...props.value || {},
41
- [language2]: html2
42
- };
43
- emit("update-property-value", { html: value });
36
+ updateHtml: (html) => {
37
+ emit("update-property-value", { html });
44
38
  }
45
39
  }
46
40
  });
@@ -1,6 +1,6 @@
1
1
  import { defineComponent, openBlock, createElementBlock, createElementVNode, toDisplayString } from "vue";
2
2
  import { useModal } from "@g1cloud/bluesea";
3
- import { u as usePageBuilderEditor, a as PageBuilderEditorEvent } from "./index-DdC6jCrv.js";
3
+ import { u as usePageBuilderEditor, a as PageBuilderEditorEvent } from "./index-CmE7SdtL.js";
4
4
  const _hoisted_1 = { class: "property-editor property-editor-image flex-align-center" };
5
5
  const _hoisted_2 = { class: "title" };
6
6
  const _hoisted_3 = ["textContent"];
@@ -1,6 +1,6 @@
1
- import { defineComponent, computed, openBlock, createElementBlock, createElementVNode, toDisplayString, createVNode, unref } from "vue";
2
- import { BSTextArea } from "@g1cloud/bluesea";
3
- import { u as usePageBuilderEditor } from "./index-DdC6jCrv.js";
1
+ import { defineComponent, computed, openBlock, createElementBlock, createElementVNode, toDisplayString, createBlock, unref } from "vue";
2
+ import { BSMultiLangTextArea, BSTextArea } from "@g1cloud/bluesea";
3
+ import { u as usePageBuilderEditor } from "./index-CmE7SdtL.js";
4
4
  const _hoisted_1 = { class: "property-editor property-editor-multiline-text" };
5
5
  const _hoisted_2 = { class: "title" };
6
6
  const _hoisted_3 = ["textContent"];
@@ -14,29 +14,21 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
14
14
  setup(__props, { emit: __emit }) {
15
15
  const props = __props;
16
16
  const emit = __emit;
17
- const emitUpdatePropertyValue = (value) => {
18
- const properties = {};
19
- if (props.value && typeof props.value === "object") {
20
- properties[props.property.propertyName] = {
21
- ...props.value,
22
- [language.value]: value
23
- };
24
- } else {
25
- properties[props.property.propertyName] = {
26
- [language.value]: value
27
- };
28
- }
29
- emit("update-property-value", properties);
30
- };
31
17
  const pageBuilder = usePageBuilderEditor();
32
- const language = computed(() => pageBuilder.language.value);
18
+ const locales = computed(() => pageBuilder.getLocales());
33
19
  const text = computed({
34
20
  get() {
35
- return props.value && typeof props.value === "object" ? props.value[language.value] : "";
21
+ return props.value;
36
22
  },
37
- set() {
23
+ // @ts-ignore
24
+ set(value) {
38
25
  }
39
26
  });
27
+ const emitUpdatePropertyValue = (value) => {
28
+ const properties = {};
29
+ properties[props.property.propertyName] = value;
30
+ emit("update-property-value", properties);
31
+ };
40
32
  return (_ctx, _cache) => {
41
33
  return openBlock(), createElementBlock("div", _hoisted_1, [
42
34
  createElementVNode("div", _hoisted_2, [
@@ -45,16 +37,26 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
45
37
  }, null, 8, _hoisted_3)
46
38
  ]),
47
39
  createElementVNode("div", null, [
48
- createVNode(unref(BSTextArea), {
40
+ _ctx.property.multiLang ? (openBlock(), createBlock(unref(BSMultiLangTextArea), {
41
+ key: 0,
49
42
  modelValue: text.value,
50
43
  "onUpdate:modelValue": [
51
44
  _cache[0] || (_cache[0] = ($event) => text.value = $event),
52
45
  emitUpdatePropertyValue
53
46
  ],
54
- prefix: language.value,
47
+ locales: locales.value,
48
+ height: "60px",
49
+ width: "100%"
50
+ }, null, 8, ["modelValue", "locales"])) : (openBlock(), createBlock(unref(BSTextArea), {
51
+ key: 1,
52
+ modelValue: text.value,
53
+ "onUpdate:modelValue": [
54
+ _cache[1] || (_cache[1] = ($event) => text.value = $event),
55
+ emitUpdatePropertyValue
56
+ ],
55
57
  height: "60px",
56
58
  width: "100%"
57
- }, null, 8, ["modelValue", "prefix"])
59
+ }, null, 8, ["modelValue"]))
58
60
  ])
59
61
  ]);
60
62
  };
@@ -1,6 +1,6 @@
1
1
  import { defineComponent, openBlock, createElementBlock, createElementVNode, toDisplayString } from "vue";
2
2
  import { useModal } from "@g1cloud/bluesea";
3
- import { u as usePageBuilderEditor, a as PageBuilderEditorEvent } from "./index-DdC6jCrv.js";
3
+ import { u as usePageBuilderEditor, a as PageBuilderEditorEvent } from "./index-CmE7SdtL.js";
4
4
  const _hoisted_1 = { class: "property-editor property-editor-product flex-align-center" };
5
5
  const _hoisted_2 = { class: "title" };
6
6
  const _hoisted_3 = ["textContent"];
@@ -1,15 +1,17 @@
1
- type Html = {
2
- tags: string;
3
- style: string;
4
- };
1
+ import { TabEntry } from '@g1cloud/bluesea';
2
+
5
3
  declare const _default: import('vue').DefineComponent<__VLS_TypePropsToRuntimeProps<{
6
- html?: Html | undefined;
4
+ html?: Record<string, unknown> | undefined;
5
+ locales?: string[] | undefined;
6
+ localeTabs?: TabEntry[] | undefined;
7
7
  }>, {}, unknown, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
8
- updateHtml: (html: Html) => void;
8
+ updateHtml: (html: Record<string, unknown>) => void;
9
9
  }, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<__VLS_TypePropsToRuntimeProps<{
10
- html?: Html | undefined;
10
+ html?: Record<string, unknown> | undefined;
11
+ locales?: string[] | undefined;
12
+ localeTabs?: TabEntry[] | undefined;
11
13
  }>>> & {
12
- onUpdateHtml?: ((html: Html) => any) | undefined;
14
+ onUpdateHtml?: ((html: Record<string, unknown>) => any) | undefined;
13
15
  }, {}, {}>;
14
16
  export default _default;
15
17
  type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
@@ -1,14 +1,15 @@
1
1
  import { MultiLangText } from '@g1cloud/page-builder-viewer';
2
2
  import { PartProperty } from '../../../model/part-property.ts';
3
+ import { MultiLangString } from '@g1cloud/bluesea';
3
4
 
4
5
  declare const _default: import('vue').DefineComponent<__VLS_TypePropsToRuntimeProps<{
5
6
  property: PartProperty;
6
- value?: MultiLangText | undefined;
7
+ value?: MultiLangString | undefined;
7
8
  }>, {}, unknown, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
8
9
  "update-property-value": (properties: Record<string, MultiLangText>) => void;
9
10
  }, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<__VLS_TypePropsToRuntimeProps<{
10
11
  property: PartProperty;
11
- value?: MultiLangText | undefined;
12
+ value?: MultiLangString | undefined;
12
13
  }>>> & {
13
14
  "onUpdate-property-value"?: ((properties: Record<string, MultiLangText>) => any) | undefined;
14
15
  }, {}, {}>;
@@ -7060,7 +7060,7 @@ const _sfc_main$4$1 = /* @__PURE__ */ defineComponent({
7060
7060
  if (typeof props.part.properties.text === "string") {
7061
7061
  return true;
7062
7062
  } else {
7063
- return !props.part.properties.text[pageBuilder.language.value];
7063
+ return !props.part.properties.text[pageBuilder.locale.value];
7064
7064
  }
7065
7065
  } else {
7066
7066
  return true;
@@ -7076,7 +7076,7 @@ const _sfc_main$4$1 = /* @__PURE__ */ defineComponent({
7076
7076
  return "Empty text";
7077
7077
  }
7078
7078
  } else {
7079
- const t = props.part.properties.text[pageBuilder.language.value];
7079
+ const t = props.part.properties.text[pageBuilder.locale.value];
7080
7080
  if (props.viewMode) {
7081
7081
  return t || "";
7082
7082
  } else {
@@ -7125,11 +7125,14 @@ const _sfc_main$3$1 = /* @__PURE__ */ defineComponent({
7125
7125
  return;
7126
7126
  if (typeof html2 !== "object")
7127
7127
  return;
7128
- const language = pageBuilder.language.value;
7128
+ const language = pageBuilder.locale.value;
7129
7129
  let _html = html2[language];
7130
7130
  if (!_html && html2.tags) {
7131
7131
  _html = html2;
7132
7132
  }
7133
+ if (!_html) {
7134
+ return "";
7135
+ }
7133
7136
  return `${_html.tags}
7134
7137
  <style>
7135
7138
  ${_html.style}
@@ -7312,14 +7315,14 @@ class PageBuilderViewerImpl {
7312
7315
  constructor() {
7313
7316
  __publicField2(this, "instanceId");
7314
7317
  __publicField2(this, "model");
7315
- __publicField2(this, "language", ref("en"));
7318
+ __publicField2(this, "locale", ref("en"));
7316
7319
  this.model = new Model$1();
7317
7320
  }
7318
- getLanguage() {
7319
- return this.language.value;
7321
+ getLocale() {
7322
+ return this.locale.value;
7320
7323
  }
7321
- setLanguage(language) {
7322
- this.language.value = language || "en";
7324
+ setLocale(locale) {
7325
+ this.locale.value = locale || "en";
7323
7326
  }
7324
7327
  render(pageContent) {
7325
7328
  const rootPart = new RootPart();
@@ -7442,7 +7445,7 @@ const _sfc_main$q = /* @__PURE__ */ defineComponent({
7442
7445
  const props = __props;
7443
7446
  const pageBuilderViewer = createPageBuilderViewer();
7444
7447
  pageBuilderViewer.instanceId = props.instanceId;
7445
- pageBuilderViewer.setLanguage(props.language);
7448
+ pageBuilderViewer.setLocale(props.language);
7446
7449
  providePageBuilderViewer(pageBuilderViewer);
7447
7450
  providePageBuilder(pageBuilderViewer);
7448
7451
  const page = computed(() => pageBuilderViewer.model.rootPart.value.children && pageBuilderViewer.model.rootPart.value.children[props.isMobilePage ? 0 : 1]);
@@ -8063,12 +8066,12 @@ const defaultPartPropertyEditors = () => {
8063
8066
  return {
8064
8067
  "readonly-text": () => defineAsyncComponent(() => import("./PbPropertyEditorReadonlyText-Dgp_AVOD.js")),
8065
8068
  "text": () => defineAsyncComponent(() => import("./PbPropertyEditorText-BWOKvwD9.js")),
8066
- "multiline-text": () => defineAsyncComponent(() => import("./PbPropertyEditorMultilineText-BN2Q1P1o.js")),
8069
+ "multiline-text": () => defineAsyncComponent(() => import("./PbPropertyEditorMultilineText-DtQgTGo7.js")),
8067
8070
  "select": () => defineAsyncComponent(() => import("./PbPropertyEditorSelect-CWedbXJI.js")),
8068
- "color": () => defineAsyncComponent(() => import("./PbPropertyEditorColor-D3brNT4U.js")),
8069
- "image": () => defineAsyncComponent(() => import("./PbPropertyEditorImage-BB25lcTu.js")),
8070
- "html": () => defineAsyncComponent(() => import("./PbPropertyEditorHtml-D--QgdEp.js")),
8071
- "product": () => defineAsyncComponent(() => import("./PbPropertyEditorProduct-CBk2DLhW.js"))
8071
+ "color": () => defineAsyncComponent(() => import("./PbPropertyEditorColor-CTMG6AE0.js")),
8072
+ "image": () => defineAsyncComponent(() => import("./PbPropertyEditorImage-CwzqZPij.js")),
8073
+ "html": () => defineAsyncComponent(() => import("./PbPropertyEditorHtml-CH9j33dZ.js")),
8074
+ "product": () => defineAsyncComponent(() => import("./PbPropertyEditorProduct-BHpPwsjx.js"))
8072
8075
  };
8073
8076
  };
8074
8077
  const getPropertyValueOfParts = (parts, propertyName) => {
@@ -12043,7 +12046,8 @@ const widgets = [
12043
12046
  caption: "Text",
12044
12047
  propertyType: "multiline-text",
12045
12048
  params: "",
12046
- localized: true
12049
+ localized: true,
12050
+ multiLang: true
12047
12051
  },
12048
12052
  {
12049
12053
  propertyName: "fontSize",
@@ -12111,7 +12115,8 @@ const widgets = [
12111
12115
  caption: "HTML",
12112
12116
  propertyType: "html",
12113
12117
  params: "",
12114
- localized: true
12118
+ localized: true,
12119
+ multiLang: true
12115
12120
  }
12116
12121
  ]
12117
12122
  },
@@ -13364,18 +13369,25 @@ class PageBuilderEditorImpl {
13364
13369
  __publicField(this, "title");
13365
13370
  __publicField(this, "editMode");
13366
13371
  __publicField(this, "scale", ref(1));
13367
- __publicField(this, "language", ref("en"));
13372
+ __publicField(this, "locale", ref("en"));
13373
+ __publicField(this, "locales", ref(["en"]));
13368
13374
  this.model = new Model2();
13369
13375
  this.context = new PageBuilderContextImpl(this);
13370
13376
  this.editMode = "free";
13371
13377
  this.scale.value = 1;
13372
13378
  this.initPlugins();
13373
13379
  }
13374
- getLanguage() {
13375
- return this.language.value;
13380
+ getLocale() {
13381
+ return this.locale.value;
13376
13382
  }
13377
- setLanguage(language) {
13378
- this.language.value = language || "en";
13383
+ setLocale(locale) {
13384
+ this.locale.value = locale || "en";
13385
+ }
13386
+ getLocales() {
13387
+ return this.locales.value;
13388
+ }
13389
+ setLocales(locales) {
13390
+ this.locales.value = locales || ["en"];
13379
13391
  }
13380
13392
  registerPlugin(plugin) {
13381
13393
  if (plugin.partDefinitions)
@@ -13395,7 +13407,7 @@ class PageBuilderEditorImpl {
13395
13407
  }
13396
13408
  initData(content) {
13397
13409
  this.model.rootPart.pageBuilderId = this.instanceId;
13398
- this.model.rootPart.language = this.language.value;
13410
+ this.model.rootPart.language = this.locale.value;
13399
13411
  let parts;
13400
13412
  if (content) {
13401
13413
  for (const p of content) {
@@ -13568,7 +13580,7 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
13568
13580
  };
13569
13581
  }
13570
13582
  });
13571
- const canvasStyle = '.pb-page {\n margin: 0 auto;\n margin-top: 20px;\n background-position: 50% 50%;\n background-repeat: no-repeat;\n background-size: cover;\n}\n.pb-page .pb-page-content.selected {\n outline: 2px solid #4998f8;\n outline-offset: 5px;\n}\n.pb-page * {\n box-sizing: border-box;\n}\n.pb-add-widget-button {\n width: 100%;\n height: 100%;\n min-height: 200px;\n position: relative;\n}\n.pb-add-widget-button button {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n padding: 8px;\n background: none;\n border: none;\n cursor: pointer;\n}\n.pb-add-widget-button button:hover {\n background-color: #eeeeee;\n}\n.pb-add-widget-button .icon {\n font-size: 1rem;\n vertical-align: middle;\n}\n.pb-add-widget-button .text {\n font-size: 1rem;\n vertical-align: middle;\n margin-left: 0.4rem;\n}\n.pb-section {\n position: relative;\n background-position: 50% 50%;\n background-repeat: no-repeat;\n background-size: cover;\n outline: 1px dashed #ccc;\n background-color: #fff;\n}\n.pb-section:hover:not(:has(.pb-block:hover)) {\n background-color: #f0f0f0;\n}\n.pb-section.selected {\n outline: 1px solid #e67e22;\n outline-offset: 1px;\n z-index: 999;\n}\n.pb-section.pb-section-static {\n width: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n pointer-events: none;\n}\n.pb-section.pb-section-static:after {\n content: "";\n position: absolute;\n left: 0;\n right: 0;\n top: 0;\n bottom: 0;\n background-color: rgba(0, 0, 0, 0.2);\n}\n.pb-section-static .pb-widget {\n outline: none;\n}\n.pb-block {\n display: flex;\n min-width: 1px;\n position: relative;\n background-position: 50% 50%;\n background-repeat: no-repeat;\n background-size: cover;\n width: 100%;\n outline: 1px dashed #ccc;\n}\n.pb-block:hover:not(:has(.pb-widget:hover)) {\n background-color: #f0f0f0;\n}\n.pb-block.selected {\n outline: 1px solid #8e44ad;\n outline-offset: 1px;\n z-index: 999;\n}\n.pb-widget {\n position: relative;\n outline: 1px dashed #ccc;\n background-position: 50% 50%;\n background-repeat: no-repeat;\n background-size: cover;\n}\n.pb-widget.selected {\n outline: 2px solid #27ae60;\n outline-offset: 1px;\n z-index: 999;\n}\n.pb-widget .children {\n position: absolute;\n width: 100%;\n height: 100%;\n}\n.pb-widget .pan-handle {\n position: absolute;\n left: -6px;\n top: -6px;\n width: 12px;\n height: 12px;\n background-color: #27ae60;\n cursor: move;\n}\n.pb-widget .resize-handle {\n position: absolute;\n right: -6px;\n bottom: -6px;\n width: 12px;\n height: 12px;\n background-color: #27ae60;\n cursor: nwse-resize;\n}\n.pb-widget {\n position: relative;\n background-position: 50% 50%;\n background-repeat: no-repeat;\n background-size: cover;\n width: 100%;\n}\n.pb-widget .children {\n position: absolute;\n width: 100%;\n height: 100%;\n}\n.pb-text-widget {\n width: 100%;\n height: fit-content;\n}\n.pb-text-widget .text {\n color: #333;\n}\n.pb-text-widget.empty .text {\n color: #999;\n}\n.pb-image-widget {\n width: 100%;\n}\n.pb-image-widget .image {\n width: 100%;\n}\n.pb-image-widget .empty {\n height: 100px;\n background-color: #eee;\n text-align: center;\n}\n.pb-image-widget .empty span {\n font-size: 40px;\n color: #999;\n line-height: 100px;\n vertical-align: middle;\n}\n.pb-html-widget {\n width: 100%;\n height: fit-content;\n}\n.pb-html-widget.empty {\n padding: 4px 0;\n font-size: 18px;\n color: #999;\n}\n.pb-product-list-widget {\n width: 100%;\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n justify-content: flex-start;\n align-items: center;\n}\n.pb-product-list-widget .product-wrapper {\n width: 25%;\n}\n.pb-product-list-widget .product-wrapper .product {\n width: 95%;\n margin: 0 auto;\n padding-top: 8px;\n padding-bottom: 8px;\n}\n.pb-product-list-widget .product-wrapper img {\n width: 100%;\n}\n.pb-product-list-widget .product-wrapper .name {\n margin-top: 8px;\n font-size: 14px;\n}\n.pb-product-list-widget .product-wrapper .price {\n margin-top: 8px;\n font-size: 14px;\n font-weight: bold;\n}\n.pb-product-list-widget .product-wrapper .empty {\n height: 200px;\n background-color: #eee;\n text-align: center;\n}\n.pb-product-list-widget .product-wrapper .empty span {\n font-size: 40px;\n color: #999;\n line-height: 200px;\n vertical-align: middle;\n}\n@media (max-width: 768px) {\n .pb-product-list-widget .product-wrapper {\n width: 50%;\n }\n}\n.mobile .pb-product-list-widget .product-wrapper {\n width: 50%;\n}\n.pb-login-widget {\n height: 200px;\n text-align: center;\n}\n.pb-login-widget h3 {\n font-size: 32px;\n font-weight: bold;\n color: #ccc;\n line-height: 200px;\n vertical-align: middle;\n}\n.font-icon {\n font-family: Material Symbols Outlined, monospace;\n font-size: 1rem;\n max-width: 1em;\n}\nhtml, body {\n font-family: Noto Sans, Noto Sans KR, Noto Sans JP, Arial, sans-serif;\n font-size: 12px;\n}\nbody {\n background-color: white;\n height: 100%;\n margin: 0;\n}\n.pb-canvas-wrapper {\n padding: 32px 40px 56px 40px;\n height: 100%;\n background-color: #aaa;\n overflow: auto;\n}\n.pb-canvas-wrapper .pb-canvas {\n display: flex;\n flex-direction: row;\n transform-origin: top left;\n width: fit-content;\n min-width: 40px;\n min-height: 40px;\n margin: 0 auto;\n}\n.pb-position-mark {\n background-color: #ff3333;\n opacity: 0.5;\n border-radius: 2px;\n}\n.pb-add-section-handle {\n position: relative;\n text-align: center;\n cursor: pointer;\n z-index: 5;\n height: 0;\n}\n.pb-add-section-handle.top::before, .pb-add-section-handle.bottom::before, .pb-add-section-handle.middle::before {\n content: "";\n position: absolute;\n left: 0;\n right: 0;\n top: 0;\n opacity: 0;\n pointer-events: none;\n}\n.pb-add-section-handle.bottom {\n left: 50%;\n bottom: -32px;\n}\n.pb-add-section-handle:hover.top::before, .pb-add-section-handle:hover.bottom::before, .pb-add-section-handle:hover.middle::before,\n.pb-add-section-handle:hover > i {\n opacity: 1;\n}\n.pb-add-section-handle > i {\n vertical-align: middle;\n position: absolute;\n top: 50%;\n left: -20px;\n font-size: 2rem;\n transform: translate(-50%, -50%);\n opacity: 0.2;\n}\n.pb-button {\n background: none;\n border: none;\n cursor: pointer;\n vertical-align: middle;\n}\n.pb-guideline {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n pointer-events: none;\n}\n.pb-guideline.selected {\n z-index: 3;\n}\n.pb-guideline.preselect {\n z-index: 4;\n}';
13583
+ const canvasStyle = '.pb-page {\n margin: 0 auto;\n margin-top: 20px;\n background-position: 50% 50%;\n background-repeat: no-repeat;\n background-size: cover;\n}\n.pb-page .pb-page-content.selected {\n outline: 2px solid #4998f8;\n outline-offset: 5px;\n}\n.pb-page * {\n box-sizing: border-box;\n}\n.pb-add-widget-button {\n width: 100%;\n height: 100%;\n min-height: 200px;\n position: relative;\n}\n.pb-add-widget-button button {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n padding: 8px;\n background: none;\n border: none;\n cursor: pointer;\n}\n.pb-add-widget-button button:hover {\n background-color: #eeeeee;\n}\n.pb-add-widget-button .icon {\n font-size: 1rem;\n vertical-align: middle;\n}\n.pb-add-widget-button .text {\n font-size: 1rem;\n vertical-align: middle;\n margin-left: 0.4rem;\n}\n.pb-section {\n position: relative;\n background-position: 50% 50%;\n background-repeat: no-repeat;\n background-size: cover;\n outline: 1px dashed #ccc;\n background-color: #fff;\n}\n.pb-section:hover:not(:has(.pb-block:hover)) {\n background-color: #f0f0f0;\n}\n.pb-section.selected {\n outline: 1px solid #e67e22;\n outline-offset: 1px;\n z-index: 999;\n}\n.pb-section.pb-section-static {\n width: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n pointer-events: none;\n}\n.pb-section.pb-section-static:after {\n content: "";\n position: absolute;\n left: 0;\n right: 0;\n top: 0;\n bottom: 0;\n background-color: rgba(0, 0, 0, 0.2);\n}\n.pb-section-static .pb-widget {\n outline: none;\n}\n.pb-block {\n display: flex;\n min-width: 1px;\n position: relative;\n background-position: 50% 50%;\n background-repeat: no-repeat;\n background-size: cover;\n width: 100%;\n outline: 1px dashed #ccc;\n}\n.pb-block:hover:not(:has(.pb-widget:hover)) {\n background-color: #f0f0f0;\n}\n.pb-block.selected {\n outline: 1px solid #8e44ad;\n outline-offset: 1px;\n z-index: 999;\n}\n.pb-widget {\n position: relative;\n outline: 1px dashed #ccc;\n background-position: 50% 50%;\n background-repeat: no-repeat;\n background-size: cover;\n}\n.pb-widget.selected {\n outline: 2px solid #27ae60;\n outline-offset: 1px;\n z-index: 999;\n}\n.pb-widget .children {\n position: absolute;\n width: 100%;\n height: 100%;\n}\n.pb-widget .pan-handle {\n position: absolute;\n left: -6px;\n top: -6px;\n width: 12px;\n height: 12px;\n background-color: #27ae60;\n cursor: move;\n}\n.pb-widget .resize-handle {\n position: absolute;\n right: -6px;\n bottom: -6px;\n width: 12px;\n height: 12px;\n background-color: #27ae60;\n cursor: nwse-resize;\n}\n.pb-widget {\n position: relative;\n background-position: 50% 50%;\n background-repeat: no-repeat;\n background-size: cover;\n width: 100%;\n}\n.pb-widget .children {\n position: absolute;\n width: 100%;\n height: 100%;\n}\n.pb-text-widget {\n width: 100%;\n height: fit-content;\n}\n.pb-text-widget .text {\n color: #333;\n}\n.pb-text-widget.empty .text {\n color: #999;\n}\n.pb-image-widget {\n width: 100%;\n}\n.pb-image-widget .image {\n width: 100%;\n}\n.pb-image-widget .empty {\n height: 100px;\n background-color: #eee;\n text-align: center;\n}\n.pb-image-widget .empty span {\n font-size: 40px;\n color: #999;\n line-height: 100px;\n vertical-align: middle;\n}\n.pb-html-widget {\n width: 100%;\n height: fit-content;\n}\n.pb-html-widget.empty {\n padding: 4px 0;\n font-size: 18px;\n color: #999;\n}\n.pb-product-list-widget {\n width: 100%;\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n justify-content: flex-start;\n align-items: center;\n}\n.pb-product-list-widget .product-wrapper {\n width: 25%;\n}\n.pb-product-list-widget .product-wrapper .product {\n width: 95%;\n margin: 0 auto;\n padding-top: 8px;\n padding-bottom: 8px;\n}\n.pb-product-list-widget .product-wrapper img {\n width: 100%;\n}\n.pb-product-list-widget .product-wrapper .name {\n margin-top: 8px;\n font-size: 14px;\n}\n.pb-product-list-widget .product-wrapper .price {\n margin-top: 8px;\n font-size: 14px;\n font-weight: bold;\n}\n.pb-product-list-widget .product-wrapper .empty {\n height: 200px;\n background-color: #eee;\n text-align: center;\n}\n.pb-product-list-widget .product-wrapper .empty span {\n font-size: 40px;\n color: #999;\n line-height: 200px;\n vertical-align: middle;\n}\n@media (max-width: 768px) {\n .pb-product-list-widget .product-wrapper {\n width: 50%;\n }\n}\n.mobile .pb-product-list-widget .product-wrapper {\n width: 50%;\n}\n.pb-login-widget {\n height: 200px;\n text-align: center;\n}\n.pb-login-widget h3 {\n padding: 0;\n margin: 0;\n font-size: 32px;\n font-weight: bold;\n color: #ccc;\n line-height: 200px;\n vertical-align: middle;\n}\n.font-icon {\n font-family: Material Symbols Outlined, monospace;\n font-size: 1rem;\n max-width: 1em;\n}\nhtml, body {\n font-family: Noto Sans, Noto Sans KR, Noto Sans JP, Arial, sans-serif;\n font-size: 12px;\n}\nbody {\n background-color: white;\n height: 100%;\n margin: 0;\n}\n.pb-canvas-wrapper {\n padding: 32px 40px 56px 40px;\n height: 100%;\n background-color: #aaa;\n overflow: auto;\n}\n.pb-canvas-wrapper .pb-canvas {\n display: flex;\n flex-direction: row;\n transform-origin: top left;\n width: fit-content;\n min-width: 40px;\n min-height: 40px;\n margin: 0 auto;\n}\n.pb-position-mark {\n background-color: #ff3333;\n opacity: 0.5;\n border-radius: 2px;\n}\n.pb-add-section-handle {\n position: relative;\n text-align: center;\n cursor: pointer;\n z-index: 5;\n height: 0;\n}\n.pb-add-section-handle.top::before, .pb-add-section-handle.bottom::before, .pb-add-section-handle.middle::before {\n content: "";\n position: absolute;\n left: 0;\n right: 0;\n top: 0;\n opacity: 0;\n pointer-events: none;\n}\n.pb-add-section-handle.bottom {\n left: 50%;\n bottom: -32px;\n}\n.pb-add-section-handle:hover.top::before, .pb-add-section-handle:hover.bottom::before, .pb-add-section-handle:hover.middle::before,\n.pb-add-section-handle:hover > i {\n opacity: 1;\n}\n.pb-add-section-handle > i {\n vertical-align: middle;\n position: absolute;\n top: 50%;\n left: -20px;\n font-size: 2rem;\n transform: translate(-50%, -50%);\n opacity: 0.2;\n}\n.pb-button {\n background: none;\n border: none;\n cursor: pointer;\n vertical-align: middle;\n}\n.pb-guideline {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n pointer-events: none;\n}\n.pb-guideline.selected {\n z-index: 3;\n}\n.pb-guideline.preselect {\n z-index: 4;\n}';
13572
13584
  const _hoisted_1$9 = { class: "pb-canvas-frame" };
13573
13585
  const _sfc_main$b = /* @__PURE__ */ defineComponent({
13574
13586
  __name: "PbCanvasFrame",
@@ -14232,7 +14244,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
14232
14244
  title: {},
14233
14245
  editMode: {},
14234
14246
  pageContent: {},
14235
- language: {}
14247
+ locales: {},
14248
+ locale: {}
14236
14249
  },
14237
14250
  setup(__props, { expose: __expose }) {
14238
14251
  const props = __props;
@@ -14241,8 +14254,10 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
14241
14254
  pageBuilderEditor.instanceId = props.instanceId;
14242
14255
  pageBuilderEditor.title = props.title;
14243
14256
  pageBuilderEditor.editMode = props.editMode || "free";
14244
- if (props.language)
14245
- pageBuilderEditor.setLanguage(props.language);
14257
+ if (props.locales)
14258
+ pageBuilderEditor.setLocales(props.locales);
14259
+ if (props.locale)
14260
+ pageBuilderEditor.setLocale(props.locale);
14246
14261
  pageBuilderEditor.registerPlugin({
14247
14262
  // TODO
14248
14263
  commands: createDefaultCommands(modal)
@@ -14251,8 +14266,11 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
14251
14266
  providePageBuilder(pageBuilderEditor);
14252
14267
  onMounted(() => pageBuilderEditor.initData(props.pageContent));
14253
14268
  watch(() => props.pageContent, (pageContent) => pageContent && pageBuilderEditor.initData(pageContent));
14254
- watch(() => props.language, (language) => {
14255
- pageBuilderEditor.setLanguage(language);
14269
+ watch(() => props.locale, (locale) => {
14270
+ pageBuilderEditor.setLocale(locale);
14271
+ });
14272
+ watch(() => props.locales, (locales) => {
14273
+ pageBuilderEditor.setLocales(locales);
14256
14274
  });
14257
14275
  const colorHistory = ref([]);
14258
14276
  provide("colorHistory", colorHistory);
@@ -25,11 +25,14 @@ export interface PageBuilderEditor extends PageBuilder {
25
25
  title?: string;
26
26
  editMode: PageBuilderEditMode;
27
27
  scale: Ref<number>;
28
+ locales: Ref<string[]>;
28
29
  registerPlugin(plugin: PageBuilderPlugin): void;
29
30
  initData(content?: any): void;
30
31
  undo(): void;
31
32
  redo(): void;
32
33
  zoom(scale: number): void;
34
+ getLocales(): string[];
35
+ setLocales(locales?: string[]): void;
33
36
  }
34
37
  export declare class PageBuilderEditorImpl implements PageBuilderEditor {
35
38
  instanceId?: string;
@@ -43,10 +46,13 @@ export declare class PageBuilderEditorImpl implements PageBuilderEditor {
43
46
  title?: string;
44
47
  editMode: PageBuilderEditMode;
45
48
  scale: Ref<number>;
46
- language: Ref<string>;
49
+ locale: Ref<string>;
50
+ locales: Ref<string[]>;
47
51
  constructor();
48
- getLanguage(): string;
49
- setLanguage(language?: string): void;
52
+ getLocale(): string;
53
+ setLocale(locale?: string): void;
54
+ getLocales(): string[];
55
+ setLocales(locales?: string[]): void;
50
56
  registerPlugin(plugin: PageBuilderPlugin): void;
51
57
  initData(content?: any[]): void;
52
58
  undo(): void;
@@ -10,6 +10,7 @@ export type PartProperty = {
10
10
  params?: any;
11
11
  propertyEditor?: PartPropertyEditor;
12
12
  localized?: boolean;
13
+ multiLang?: boolean;
13
14
  };
14
15
  export type PartPropertyGroupEditor = (group: PartPropertyGroup, parts: IPart[]) => Component | undefined;
15
16
  export type PartPropertyGroup = {
@@ -1,4 +1,4 @@
1
- import { B, b, M, c, d, e, _, a, f, g, h, i, j, k, l, R, m, S, n, W, o, p, q, r, s, t, v, w } from "./index-DdC6jCrv.js";
1
+ import { B, b, M, c, d, e, _, a, f, g, h, i, j, k, l, R, m, S, n, W, o, p, q, r, s, t, v, w } from "./index-CmE7SdtL.js";
2
2
  export {
3
3
  B as BLOCK_TYPE,
4
4
  b as Block,
@@ -7062,7 +7062,7 @@ var __publicField = (obj, key, value) => {
7062
7062
  if (typeof props.part.properties.text === "string") {
7063
7063
  return true;
7064
7064
  } else {
7065
- return !props.part.properties.text[pageBuilder.language.value];
7065
+ return !props.part.properties.text[pageBuilder.locale.value];
7066
7066
  }
7067
7067
  } else {
7068
7068
  return true;
@@ -7078,7 +7078,7 @@ var __publicField = (obj, key, value) => {
7078
7078
  return "Empty text";
7079
7079
  }
7080
7080
  } else {
7081
- const t = props.part.properties.text[pageBuilder.language.value];
7081
+ const t = props.part.properties.text[pageBuilder.locale.value];
7082
7082
  if (props.viewMode) {
7083
7083
  return t || "";
7084
7084
  } else {
@@ -7127,11 +7127,14 @@ var __publicField = (obj, key, value) => {
7127
7127
  return;
7128
7128
  if (typeof html2 !== "object")
7129
7129
  return;
7130
- const language = pageBuilder.language.value;
7130
+ const language = pageBuilder.locale.value;
7131
7131
  let _html = html2[language];
7132
7132
  if (!_html && html2.tags) {
7133
7133
  _html = html2;
7134
7134
  }
7135
+ if (!_html) {
7136
+ return "";
7137
+ }
7135
7138
  return `${_html.tags}
7136
7139
  <style>
7137
7140
  ${_html.style}
@@ -7314,14 +7317,14 @@ ${_html.style}
7314
7317
  constructor() {
7315
7318
  __publicField2(this, "instanceId");
7316
7319
  __publicField2(this, "model");
7317
- __publicField2(this, "language", vue.ref("en"));
7320
+ __publicField2(this, "locale", vue.ref("en"));
7318
7321
  this.model = new Model$1();
7319
7322
  }
7320
- getLanguage() {
7321
- return this.language.value;
7323
+ getLocale() {
7324
+ return this.locale.value;
7322
7325
  }
7323
- setLanguage(language) {
7324
- this.language.value = language || "en";
7326
+ setLocale(locale) {
7327
+ this.locale.value = locale || "en";
7325
7328
  }
7326
7329
  render(pageContent) {
7327
7330
  const rootPart = new RootPart();
@@ -7444,7 +7447,7 @@ ${_html.style}
7444
7447
  const props = __props;
7445
7448
  const pageBuilderViewer = createPageBuilderViewer();
7446
7449
  pageBuilderViewer.instanceId = props.instanceId;
7447
- pageBuilderViewer.setLanguage(props.language);
7450
+ pageBuilderViewer.setLocale(props.language);
7448
7451
  providePageBuilderViewer(pageBuilderViewer);
7449
7452
  providePageBuilder(pageBuilderViewer);
7450
7453
  const page = vue.computed(() => pageBuilderViewer.model.rootPart.value.children && pageBuilderViewer.model.rootPart.value.children[props.isMobilePage ? 0 : 1]);
@@ -12045,7 +12048,8 @@ ${_html.style}
12045
12048
  caption: "Text",
12046
12049
  propertyType: "multiline-text",
12047
12050
  params: "",
12048
- localized: true
12051
+ localized: true,
12052
+ multiLang: true
12049
12053
  },
12050
12054
  {
12051
12055
  propertyName: "fontSize",
@@ -12113,7 +12117,8 @@ ${_html.style}
12113
12117
  caption: "HTML",
12114
12118
  propertyType: "html",
12115
12119
  params: "",
12116
- localized: true
12120
+ localized: true,
12121
+ multiLang: true
12117
12122
  }
12118
12123
  ]
12119
12124
  },
@@ -13366,18 +13371,25 @@ ${_html.style}
13366
13371
  __publicField(this, "title");
13367
13372
  __publicField(this, "editMode");
13368
13373
  __publicField(this, "scale", vue.ref(1));
13369
- __publicField(this, "language", vue.ref("en"));
13374
+ __publicField(this, "locale", vue.ref("en"));
13375
+ __publicField(this, "locales", vue.ref(["en"]));
13370
13376
  this.model = new Model();
13371
13377
  this.context = new PageBuilderContextImpl(this);
13372
13378
  this.editMode = "free";
13373
13379
  this.scale.value = 1;
13374
13380
  this.initPlugins();
13375
13381
  }
13376
- getLanguage() {
13377
- return this.language.value;
13382
+ getLocale() {
13383
+ return this.locale.value;
13384
+ }
13385
+ setLocale(locale) {
13386
+ this.locale.value = locale || "en";
13387
+ }
13388
+ getLocales() {
13389
+ return this.locales.value;
13378
13390
  }
13379
- setLanguage(language) {
13380
- this.language.value = language || "en";
13391
+ setLocales(locales) {
13392
+ this.locales.value = locales || ["en"];
13381
13393
  }
13382
13394
  registerPlugin(plugin) {
13383
13395
  if (plugin.partDefinitions)
@@ -13397,7 +13409,7 @@ ${_html.style}
13397
13409
  }
13398
13410
  initData(content) {
13399
13411
  this.model.rootPart.pageBuilderId = this.instanceId;
13400
- this.model.rootPart.language = this.language.value;
13412
+ this.model.rootPart.language = this.locale.value;
13401
13413
  let parts;
13402
13414
  if (content) {
13403
13415
  for (const p of content) {
@@ -13570,7 +13582,7 @@ ${_html.style}
13570
13582
  };
13571
13583
  }
13572
13584
  });
13573
- const canvasStyle = '.pb-page {\n margin: 0 auto;\n margin-top: 20px;\n background-position: 50% 50%;\n background-repeat: no-repeat;\n background-size: cover;\n}\n.pb-page .pb-page-content.selected {\n outline: 2px solid #4998f8;\n outline-offset: 5px;\n}\n.pb-page * {\n box-sizing: border-box;\n}\n.pb-add-widget-button {\n width: 100%;\n height: 100%;\n min-height: 200px;\n position: relative;\n}\n.pb-add-widget-button button {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n padding: 8px;\n background: none;\n border: none;\n cursor: pointer;\n}\n.pb-add-widget-button button:hover {\n background-color: #eeeeee;\n}\n.pb-add-widget-button .icon {\n font-size: 1rem;\n vertical-align: middle;\n}\n.pb-add-widget-button .text {\n font-size: 1rem;\n vertical-align: middle;\n margin-left: 0.4rem;\n}\n.pb-section {\n position: relative;\n background-position: 50% 50%;\n background-repeat: no-repeat;\n background-size: cover;\n outline: 1px dashed #ccc;\n background-color: #fff;\n}\n.pb-section:hover:not(:has(.pb-block:hover)) {\n background-color: #f0f0f0;\n}\n.pb-section.selected {\n outline: 1px solid #e67e22;\n outline-offset: 1px;\n z-index: 999;\n}\n.pb-section.pb-section-static {\n width: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n pointer-events: none;\n}\n.pb-section.pb-section-static:after {\n content: "";\n position: absolute;\n left: 0;\n right: 0;\n top: 0;\n bottom: 0;\n background-color: rgba(0, 0, 0, 0.2);\n}\n.pb-section-static .pb-widget {\n outline: none;\n}\n.pb-block {\n display: flex;\n min-width: 1px;\n position: relative;\n background-position: 50% 50%;\n background-repeat: no-repeat;\n background-size: cover;\n width: 100%;\n outline: 1px dashed #ccc;\n}\n.pb-block:hover:not(:has(.pb-widget:hover)) {\n background-color: #f0f0f0;\n}\n.pb-block.selected {\n outline: 1px solid #8e44ad;\n outline-offset: 1px;\n z-index: 999;\n}\n.pb-widget {\n position: relative;\n outline: 1px dashed #ccc;\n background-position: 50% 50%;\n background-repeat: no-repeat;\n background-size: cover;\n}\n.pb-widget.selected {\n outline: 2px solid #27ae60;\n outline-offset: 1px;\n z-index: 999;\n}\n.pb-widget .children {\n position: absolute;\n width: 100%;\n height: 100%;\n}\n.pb-widget .pan-handle {\n position: absolute;\n left: -6px;\n top: -6px;\n width: 12px;\n height: 12px;\n background-color: #27ae60;\n cursor: move;\n}\n.pb-widget .resize-handle {\n position: absolute;\n right: -6px;\n bottom: -6px;\n width: 12px;\n height: 12px;\n background-color: #27ae60;\n cursor: nwse-resize;\n}\n.pb-widget {\n position: relative;\n background-position: 50% 50%;\n background-repeat: no-repeat;\n background-size: cover;\n width: 100%;\n}\n.pb-widget .children {\n position: absolute;\n width: 100%;\n height: 100%;\n}\n.pb-text-widget {\n width: 100%;\n height: fit-content;\n}\n.pb-text-widget .text {\n color: #333;\n}\n.pb-text-widget.empty .text {\n color: #999;\n}\n.pb-image-widget {\n width: 100%;\n}\n.pb-image-widget .image {\n width: 100%;\n}\n.pb-image-widget .empty {\n height: 100px;\n background-color: #eee;\n text-align: center;\n}\n.pb-image-widget .empty span {\n font-size: 40px;\n color: #999;\n line-height: 100px;\n vertical-align: middle;\n}\n.pb-html-widget {\n width: 100%;\n height: fit-content;\n}\n.pb-html-widget.empty {\n padding: 4px 0;\n font-size: 18px;\n color: #999;\n}\n.pb-product-list-widget {\n width: 100%;\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n justify-content: flex-start;\n align-items: center;\n}\n.pb-product-list-widget .product-wrapper {\n width: 25%;\n}\n.pb-product-list-widget .product-wrapper .product {\n width: 95%;\n margin: 0 auto;\n padding-top: 8px;\n padding-bottom: 8px;\n}\n.pb-product-list-widget .product-wrapper img {\n width: 100%;\n}\n.pb-product-list-widget .product-wrapper .name {\n margin-top: 8px;\n font-size: 14px;\n}\n.pb-product-list-widget .product-wrapper .price {\n margin-top: 8px;\n font-size: 14px;\n font-weight: bold;\n}\n.pb-product-list-widget .product-wrapper .empty {\n height: 200px;\n background-color: #eee;\n text-align: center;\n}\n.pb-product-list-widget .product-wrapper .empty span {\n font-size: 40px;\n color: #999;\n line-height: 200px;\n vertical-align: middle;\n}\n@media (max-width: 768px) {\n .pb-product-list-widget .product-wrapper {\n width: 50%;\n }\n}\n.mobile .pb-product-list-widget .product-wrapper {\n width: 50%;\n}\n.pb-login-widget {\n height: 200px;\n text-align: center;\n}\n.pb-login-widget h3 {\n font-size: 32px;\n font-weight: bold;\n color: #ccc;\n line-height: 200px;\n vertical-align: middle;\n}\n.font-icon {\n font-family: Material Symbols Outlined, monospace;\n font-size: 1rem;\n max-width: 1em;\n}\nhtml, body {\n font-family: Noto Sans, Noto Sans KR, Noto Sans JP, Arial, sans-serif;\n font-size: 12px;\n}\nbody {\n background-color: white;\n height: 100%;\n margin: 0;\n}\n.pb-canvas-wrapper {\n padding: 32px 40px 56px 40px;\n height: 100%;\n background-color: #aaa;\n overflow: auto;\n}\n.pb-canvas-wrapper .pb-canvas {\n display: flex;\n flex-direction: row;\n transform-origin: top left;\n width: fit-content;\n min-width: 40px;\n min-height: 40px;\n margin: 0 auto;\n}\n.pb-position-mark {\n background-color: #ff3333;\n opacity: 0.5;\n border-radius: 2px;\n}\n.pb-add-section-handle {\n position: relative;\n text-align: center;\n cursor: pointer;\n z-index: 5;\n height: 0;\n}\n.pb-add-section-handle.top::before, .pb-add-section-handle.bottom::before, .pb-add-section-handle.middle::before {\n content: "";\n position: absolute;\n left: 0;\n right: 0;\n top: 0;\n opacity: 0;\n pointer-events: none;\n}\n.pb-add-section-handle.bottom {\n left: 50%;\n bottom: -32px;\n}\n.pb-add-section-handle:hover.top::before, .pb-add-section-handle:hover.bottom::before, .pb-add-section-handle:hover.middle::before,\n.pb-add-section-handle:hover > i {\n opacity: 1;\n}\n.pb-add-section-handle > i {\n vertical-align: middle;\n position: absolute;\n top: 50%;\n left: -20px;\n font-size: 2rem;\n transform: translate(-50%, -50%);\n opacity: 0.2;\n}\n.pb-button {\n background: none;\n border: none;\n cursor: pointer;\n vertical-align: middle;\n}\n.pb-guideline {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n pointer-events: none;\n}\n.pb-guideline.selected {\n z-index: 3;\n}\n.pb-guideline.preselect {\n z-index: 4;\n}';
13585
+ const canvasStyle = '.pb-page {\n margin: 0 auto;\n margin-top: 20px;\n background-position: 50% 50%;\n background-repeat: no-repeat;\n background-size: cover;\n}\n.pb-page .pb-page-content.selected {\n outline: 2px solid #4998f8;\n outline-offset: 5px;\n}\n.pb-page * {\n box-sizing: border-box;\n}\n.pb-add-widget-button {\n width: 100%;\n height: 100%;\n min-height: 200px;\n position: relative;\n}\n.pb-add-widget-button button {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n padding: 8px;\n background: none;\n border: none;\n cursor: pointer;\n}\n.pb-add-widget-button button:hover {\n background-color: #eeeeee;\n}\n.pb-add-widget-button .icon {\n font-size: 1rem;\n vertical-align: middle;\n}\n.pb-add-widget-button .text {\n font-size: 1rem;\n vertical-align: middle;\n margin-left: 0.4rem;\n}\n.pb-section {\n position: relative;\n background-position: 50% 50%;\n background-repeat: no-repeat;\n background-size: cover;\n outline: 1px dashed #ccc;\n background-color: #fff;\n}\n.pb-section:hover:not(:has(.pb-block:hover)) {\n background-color: #f0f0f0;\n}\n.pb-section.selected {\n outline: 1px solid #e67e22;\n outline-offset: 1px;\n z-index: 999;\n}\n.pb-section.pb-section-static {\n width: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n pointer-events: none;\n}\n.pb-section.pb-section-static:after {\n content: "";\n position: absolute;\n left: 0;\n right: 0;\n top: 0;\n bottom: 0;\n background-color: rgba(0, 0, 0, 0.2);\n}\n.pb-section-static .pb-widget {\n outline: none;\n}\n.pb-block {\n display: flex;\n min-width: 1px;\n position: relative;\n background-position: 50% 50%;\n background-repeat: no-repeat;\n background-size: cover;\n width: 100%;\n outline: 1px dashed #ccc;\n}\n.pb-block:hover:not(:has(.pb-widget:hover)) {\n background-color: #f0f0f0;\n}\n.pb-block.selected {\n outline: 1px solid #8e44ad;\n outline-offset: 1px;\n z-index: 999;\n}\n.pb-widget {\n position: relative;\n outline: 1px dashed #ccc;\n background-position: 50% 50%;\n background-repeat: no-repeat;\n background-size: cover;\n}\n.pb-widget.selected {\n outline: 2px solid #27ae60;\n outline-offset: 1px;\n z-index: 999;\n}\n.pb-widget .children {\n position: absolute;\n width: 100%;\n height: 100%;\n}\n.pb-widget .pan-handle {\n position: absolute;\n left: -6px;\n top: -6px;\n width: 12px;\n height: 12px;\n background-color: #27ae60;\n cursor: move;\n}\n.pb-widget .resize-handle {\n position: absolute;\n right: -6px;\n bottom: -6px;\n width: 12px;\n height: 12px;\n background-color: #27ae60;\n cursor: nwse-resize;\n}\n.pb-widget {\n position: relative;\n background-position: 50% 50%;\n background-repeat: no-repeat;\n background-size: cover;\n width: 100%;\n}\n.pb-widget .children {\n position: absolute;\n width: 100%;\n height: 100%;\n}\n.pb-text-widget {\n width: 100%;\n height: fit-content;\n}\n.pb-text-widget .text {\n color: #333;\n}\n.pb-text-widget.empty .text {\n color: #999;\n}\n.pb-image-widget {\n width: 100%;\n}\n.pb-image-widget .image {\n width: 100%;\n}\n.pb-image-widget .empty {\n height: 100px;\n background-color: #eee;\n text-align: center;\n}\n.pb-image-widget .empty span {\n font-size: 40px;\n color: #999;\n line-height: 100px;\n vertical-align: middle;\n}\n.pb-html-widget {\n width: 100%;\n height: fit-content;\n}\n.pb-html-widget.empty {\n padding: 4px 0;\n font-size: 18px;\n color: #999;\n}\n.pb-product-list-widget {\n width: 100%;\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n justify-content: flex-start;\n align-items: center;\n}\n.pb-product-list-widget .product-wrapper {\n width: 25%;\n}\n.pb-product-list-widget .product-wrapper .product {\n width: 95%;\n margin: 0 auto;\n padding-top: 8px;\n padding-bottom: 8px;\n}\n.pb-product-list-widget .product-wrapper img {\n width: 100%;\n}\n.pb-product-list-widget .product-wrapper .name {\n margin-top: 8px;\n font-size: 14px;\n}\n.pb-product-list-widget .product-wrapper .price {\n margin-top: 8px;\n font-size: 14px;\n font-weight: bold;\n}\n.pb-product-list-widget .product-wrapper .empty {\n height: 200px;\n background-color: #eee;\n text-align: center;\n}\n.pb-product-list-widget .product-wrapper .empty span {\n font-size: 40px;\n color: #999;\n line-height: 200px;\n vertical-align: middle;\n}\n@media (max-width: 768px) {\n .pb-product-list-widget .product-wrapper {\n width: 50%;\n }\n}\n.mobile .pb-product-list-widget .product-wrapper {\n width: 50%;\n}\n.pb-login-widget {\n height: 200px;\n text-align: center;\n}\n.pb-login-widget h3 {\n padding: 0;\n margin: 0;\n font-size: 32px;\n font-weight: bold;\n color: #ccc;\n line-height: 200px;\n vertical-align: middle;\n}\n.font-icon {\n font-family: Material Symbols Outlined, monospace;\n font-size: 1rem;\n max-width: 1em;\n}\nhtml, body {\n font-family: Noto Sans, Noto Sans KR, Noto Sans JP, Arial, sans-serif;\n font-size: 12px;\n}\nbody {\n background-color: white;\n height: 100%;\n margin: 0;\n}\n.pb-canvas-wrapper {\n padding: 32px 40px 56px 40px;\n height: 100%;\n background-color: #aaa;\n overflow: auto;\n}\n.pb-canvas-wrapper .pb-canvas {\n display: flex;\n flex-direction: row;\n transform-origin: top left;\n width: fit-content;\n min-width: 40px;\n min-height: 40px;\n margin: 0 auto;\n}\n.pb-position-mark {\n background-color: #ff3333;\n opacity: 0.5;\n border-radius: 2px;\n}\n.pb-add-section-handle {\n position: relative;\n text-align: center;\n cursor: pointer;\n z-index: 5;\n height: 0;\n}\n.pb-add-section-handle.top::before, .pb-add-section-handle.bottom::before, .pb-add-section-handle.middle::before {\n content: "";\n position: absolute;\n left: 0;\n right: 0;\n top: 0;\n opacity: 0;\n pointer-events: none;\n}\n.pb-add-section-handle.bottom {\n left: 50%;\n bottom: -32px;\n}\n.pb-add-section-handle:hover.top::before, .pb-add-section-handle:hover.bottom::before, .pb-add-section-handle:hover.middle::before,\n.pb-add-section-handle:hover > i {\n opacity: 1;\n}\n.pb-add-section-handle > i {\n vertical-align: middle;\n position: absolute;\n top: 50%;\n left: -20px;\n font-size: 2rem;\n transform: translate(-50%, -50%);\n opacity: 0.2;\n}\n.pb-button {\n background: none;\n border: none;\n cursor: pointer;\n vertical-align: middle;\n}\n.pb-guideline {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n pointer-events: none;\n}\n.pb-guideline.selected {\n z-index: 3;\n}\n.pb-guideline.preselect {\n z-index: 4;\n}';
13574
13586
  const _hoisted_1$k = { class: "pb-canvas-frame" };
13575
13587
  const _sfc_main$m = /* @__PURE__ */ vue.defineComponent({
13576
13588
  __name: "PbCanvasFrame",
@@ -14234,7 +14246,8 @@ ${_html.style}
14234
14246
  title: {},
14235
14247
  editMode: {},
14236
14248
  pageContent: {},
14237
- language: {}
14249
+ locales: {},
14250
+ locale: {}
14238
14251
  },
14239
14252
  setup(__props, { expose: __expose }) {
14240
14253
  const props = __props;
@@ -14243,8 +14256,10 @@ ${_html.style}
14243
14256
  pageBuilderEditor.instanceId = props.instanceId;
14244
14257
  pageBuilderEditor.title = props.title;
14245
14258
  pageBuilderEditor.editMode = props.editMode || "free";
14246
- if (props.language)
14247
- pageBuilderEditor.setLanguage(props.language);
14259
+ if (props.locales)
14260
+ pageBuilderEditor.setLocales(props.locales);
14261
+ if (props.locale)
14262
+ pageBuilderEditor.setLocale(props.locale);
14248
14263
  pageBuilderEditor.registerPlugin({
14249
14264
  // TODO
14250
14265
  commands: createDefaultCommands(modal)
@@ -14253,8 +14268,11 @@ ${_html.style}
14253
14268
  providePageBuilder(pageBuilderEditor);
14254
14269
  vue.onMounted(() => pageBuilderEditor.initData(props.pageContent));
14255
14270
  vue.watch(() => props.pageContent, (pageContent) => pageContent && pageBuilderEditor.initData(pageContent));
14256
- vue.watch(() => props.language, (language) => {
14257
- pageBuilderEditor.setLanguage(language);
14271
+ vue.watch(() => props.locale, (locale) => {
14272
+ pageBuilderEditor.setLocale(locale);
14273
+ });
14274
+ vue.watch(() => props.locales, (locales) => {
14275
+ pageBuilderEditor.setLocales(locales);
14258
14276
  });
14259
14277
  const colorHistory = vue.ref([]);
14260
14278
  vue.provide("colorHistory", colorHistory);
@@ -14406,29 +14424,21 @@ ${_html.style}
14406
14424
  setup(__props, { emit: __emit }) {
14407
14425
  const props = __props;
14408
14426
  const emit = __emit;
14409
- const emitUpdatePropertyValue = (value) => {
14410
- const properties = {};
14411
- if (props.value && typeof props.value === "object") {
14412
- properties[props.property.propertyName] = {
14413
- ...props.value,
14414
- [language.value]: value
14415
- };
14416
- } else {
14417
- properties[props.property.propertyName] = {
14418
- [language.value]: value
14419
- };
14420
- }
14421
- emit("update-property-value", properties);
14422
- };
14423
14427
  const pageBuilder = usePageBuilderEditor();
14424
- const language = vue.computed(() => pageBuilder.language.value);
14428
+ const locales = vue.computed(() => pageBuilder.getLocales());
14425
14429
  const text = vue.computed({
14426
14430
  get() {
14427
- return props.value && typeof props.value === "object" ? props.value[language.value] : "";
14431
+ return props.value;
14428
14432
  },
14429
- set() {
14433
+ // @ts-ignore
14434
+ set(value) {
14430
14435
  }
14431
14436
  });
14437
+ const emitUpdatePropertyValue = (value) => {
14438
+ const properties = {};
14439
+ properties[props.property.propertyName] = value;
14440
+ emit("update-property-value", properties);
14441
+ };
14432
14442
  return (_ctx, _cache) => {
14433
14443
  return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$8, [
14434
14444
  vue.createElementVNode("div", _hoisted_2$8, [
@@ -14437,16 +14447,26 @@ ${_html.style}
14437
14447
  }, null, 8, _hoisted_3$8)
14438
14448
  ]),
14439
14449
  vue.createElementVNode("div", null, [
14440
- vue.createVNode(vue.unref(bluesea.BSTextArea), {
14450
+ _ctx.property.multiLang ? (vue.openBlock(), vue.createBlock(vue.unref(bluesea.BSMultiLangTextArea), {
14451
+ key: 0,
14441
14452
  modelValue: text.value,
14442
14453
  "onUpdate:modelValue": [
14443
14454
  _cache[0] || (_cache[0] = ($event) => text.value = $event),
14444
14455
  emitUpdatePropertyValue
14445
14456
  ],
14446
- prefix: language.value,
14457
+ locales: locales.value,
14447
14458
  height: "60px",
14448
14459
  width: "100%"
14449
- }, null, 8, ["modelValue", "prefix"])
14460
+ }, null, 8, ["modelValue", "locales"])) : (vue.openBlock(), vue.createBlock(vue.unref(bluesea.BSTextArea), {
14461
+ key: 1,
14462
+ modelValue: text.value,
14463
+ "onUpdate:modelValue": [
14464
+ _cache[1] || (_cache[1] = ($event) => text.value = $event),
14465
+ emitUpdatePropertyValue
14466
+ ],
14467
+ height: "60px",
14468
+ width: "100%"
14469
+ }, null, 8, ["modelValue"]))
14450
14470
  ])
14451
14471
  ]);
14452
14472
  };
@@ -14610,11 +14630,8 @@ ${_html.style}
14610
14630
  const pageBuilder = usePageBuilderEditor();
14611
14631
  const emit = __emit;
14612
14632
  const editHtml = () => {
14613
- const language = pageBuilder.getLanguage();
14614
- let html;
14615
- if (props.value && typeof props.value === "object") {
14616
- html = props.value[language];
14617
- }
14633
+ const locales = pageBuilder.getLocales();
14634
+ const localeTabs = locales.map((v) => ({ tabId: `tab-${v}`, caption: v }));
14618
14635
  modal.openModal({
14619
14636
  component: vue.defineAsyncComponent(() => Promise.resolve().then(() => HtmlEditorModal)),
14620
14637
  style: {
@@ -14624,16 +14641,13 @@ ${_html.style}
14624
14641
  minHeight: "400px"
14625
14642
  },
14626
14643
  bind: {
14627
- html
14644
+ html: JSON.parse(JSON.stringify(props.value || {})),
14645
+ locales,
14646
+ localeTabs
14628
14647
  },
14629
14648
  on: {
14630
- updateHtml: (html2) => {
14631
- const language2 = pageBuilder.getLanguage();
14632
- const value = {
14633
- ...props.value || {},
14634
- [language2]: html2
14635
- };
14636
- emit("update-property-value", { html: value });
14649
+ updateHtml: (html) => {
14650
+ emit("update-property-value", { html });
14637
14651
  }
14638
14652
  }
14639
14653
  });
@@ -14806,8 +14820,8 @@ ${_html.style}
14806
14820
  __proto__: null,
14807
14821
  default: _sfc_main$1
14808
14822
  }, Symbol.toStringTag, { value: "Module" }));
14809
- const _hoisted_1 = { class: "bs-layout-vertical pb-html-editor-modal flex-grow-1 h-full" };
14810
- const _hoisted_2 = { class: "bs-layout-horizontal flex-grow-1" };
14823
+ const _hoisted_1 = { class: "bs-layout-vertical flex-grow-1 h-full" };
14824
+ const _hoisted_2 = { class: "bs-layout-horizontal h-full pt-8" };
14811
14825
  const _hoisted_3 = { class: "preview flex-grow-1" };
14812
14826
  const _hoisted_4 = { class: "bs-layout-vertical w-full h-full" };
14813
14827
  const _hoisted_5 = /* @__PURE__ */ vue.createElementVNode("div", { class: "title pb-4" }, "Preview", -1);
@@ -14822,76 +14836,109 @@ ${_html.style}
14822
14836
  const _sfc_main = /* @__PURE__ */ vue.defineComponent({
14823
14837
  __name: "HtmlEditorModal",
14824
14838
  props: {
14825
- html: {}
14839
+ html: {},
14840
+ locales: {},
14841
+ localeTabs: {}
14826
14842
  },
14827
14843
  emits: ["updateHtml"],
14828
14844
  setup(__props, { emit: __emit }) {
14829
- var _a, _b;
14830
14845
  const props = __props;
14831
14846
  const emit = __emit;
14847
+ const tabId = vue.ref(props.localeTabs && props.localeTabs[0].tabId);
14832
14848
  const modalHandle = bluesea.useModalHandle();
14833
- const tags = vue.ref(((_a = props.html) == null ? void 0 : _a.tags) || "");
14834
- const style = vue.ref(((_b = props.html) == null ? void 0 : _b.style) || "");
14835
- const html = vue.computed(() => `${tags.value || ""}
14836
- <style>${style.value || ""}</style>`);
14837
- const updateTags = (value) => {
14838
- tags.value = value;
14839
- };
14840
- const updateStyle = (value) => {
14841
- style.value = value;
14849
+ const html = vue.ref(props.html || {});
14850
+ const preview = vue.computed(() => {
14851
+ var _a;
14852
+ let data = {};
14853
+ (_a = props.locales) == null ? void 0 : _a.forEach((locale) => {
14854
+ const _html = html.value[locale] || { tags: "", style: "" };
14855
+ data[locale] = _html.tags ? `${_html.tags}
14856
+ <style>${_html.style}</style>` : "";
14857
+ });
14858
+ return data;
14859
+ });
14860
+ const updateTags = (locale, value) => {
14861
+ if (!html.value)
14862
+ html.value = {};
14863
+ if (!html.value[locale])
14864
+ html.value[locale] = {};
14865
+ html.value[locale].tags = value;
14866
+ };
14867
+ const updateStyle = (locale, value) => {
14868
+ if (!html.value)
14869
+ html.value = {};
14870
+ if (!html.value[locale])
14871
+ html.value[locale] = {};
14872
+ html.value[locale].style = value;
14842
14873
  };
14843
14874
  const ok = () => {
14844
- emit("updateHtml", {
14845
- tags: tags.value || "",
14846
- style: style.value || ""
14847
- });
14875
+ emit("updateHtml", html.value);
14848
14876
  modalHandle.close();
14849
14877
  };
14850
14878
  return (_ctx, _cache) => {
14851
- return vue.openBlock(), vue.createBlock(vue.unref(bluesea.BSModalFrame), { title: "HTML Editor" }, {
14879
+ return vue.openBlock(), vue.createBlock(vue.unref(bluesea.BSModalFrame), {
14880
+ class: "pb-html-editor-modal",
14881
+ title: "HTML Editor"
14882
+ }, {
14852
14883
  default: vue.withCtx(() => [
14853
14884
  vue.createElementVNode("div", _hoisted_1, [
14854
- vue.createElementVNode("div", _hoisted_2, [
14855
- vue.createElementVNode("div", _hoisted_3, [
14856
- vue.createElementVNode("div", _hoisted_4, [
14857
- _hoisted_5,
14858
- vue.createElementVNode("div", {
14859
- class: "content flex-grow-1",
14860
- innerHTML: html.value
14861
- }, null, 8, _hoisted_6)
14862
- ])
14863
- ]),
14864
- vue.createElementVNode("div", _hoisted_7, [
14865
- vue.createElementVNode("div", _hoisted_8, [
14866
- _hoisted_9,
14867
- vue.createElementVNode("div", _hoisted_10, [
14868
- vue.createVNode(vue.unref(bluesea.BSCodeEditor), {
14869
- "model-value": tags.value,
14870
- "editor-height": "100%",
14871
- lang: "html",
14872
- "onUpdate:modelValue": updateTags
14873
- }, null, 8, ["model-value"])
14874
- ])
14875
- ]),
14876
- vue.createElementVNode("div", _hoisted_11, [
14877
- _hoisted_12,
14878
- vue.createElementVNode("div", _hoisted_13, [
14879
- vue.createVNode(vue.unref(bluesea.BSCodeEditor), {
14880
- "model-value": style.value,
14881
- "editor-height": "100%",
14882
- lang: "css",
14883
- "onUpdate:modelValue": updateStyle
14884
- }, null, 8, ["model-value"])
14885
+ vue.createVNode(vue.unref(bluesea.BSTabSheet), {
14886
+ "tab-id": tabId.value,
14887
+ "onUpdate:tabId": _cache[0] || (_cache[0] = ($event) => tabId.value = $event),
14888
+ tabs: _ctx.localeTabs,
14889
+ class: "flex-grow-1"
14890
+ }, vue.createSlots({ _: 2 }, [
14891
+ vue.renderList(_ctx.locales, (locale) => {
14892
+ return {
14893
+ name: `tab-${locale}`,
14894
+ fn: vue.withCtx(() => [
14895
+ vue.createElementVNode("div", _hoisted_2, [
14896
+ vue.createElementVNode("div", _hoisted_3, [
14897
+ vue.createElementVNode("div", _hoisted_4, [
14898
+ _hoisted_5,
14899
+ vue.createElementVNode("div", {
14900
+ class: "content flex-grow-1",
14901
+ innerHTML: preview.value[locale]
14902
+ }, null, 8, _hoisted_6)
14903
+ ])
14904
+ ]),
14905
+ vue.createElementVNode("div", _hoisted_7, [
14906
+ vue.createElementVNode("div", _hoisted_8, [
14907
+ _hoisted_9,
14908
+ vue.createElementVNode("div", _hoisted_10, [
14909
+ vue.createVNode(vue.unref(bluesea.BSCodeEditor), {
14910
+ "model-value": (html.value[locale] || {}).tags,
14911
+ "editor-height": "100%",
14912
+ lang: "html",
14913
+ "onUpdate:modelValue": (value) => updateTags(locale, value)
14914
+ }, null, 8, ["model-value", "onUpdate:modelValue"])
14915
+ ])
14916
+ ]),
14917
+ vue.createElementVNode("div", _hoisted_11, [
14918
+ _hoisted_12,
14919
+ vue.createElementVNode("div", _hoisted_13, [
14920
+ vue.createVNode(vue.unref(bluesea.BSCodeEditor), {
14921
+ "model-value": (html.value[locale] || {}).style,
14922
+ "editor-height": "100%",
14923
+ lang: "css",
14924
+ "onUpdate:modelValue": (value) => updateStyle(locale, value)
14925
+ }, null, 8, ["model-value", "onUpdate:modelValue"])
14926
+ ])
14927
+ ])
14928
+ ])
14929
+ ])
14885
14930
  ])
14886
- ])
14887
- ])
14888
- ]),
14889
- vue.createElementVNode("div", { class: "buttons pt-24" }, [
14890
- vue.createElementVNode("button", {
14891
- class: "mr-4",
14892
- onClick: ok
14893
- }, "OK")
14894
- ])
14931
+ };
14932
+ })
14933
+ ]), 1032, ["tab-id", "tabs"])
14934
+ ])
14935
+ ]),
14936
+ buttons: vue.withCtx(() => [
14937
+ vue.createElementVNode("div", { class: "bs-layout-horizontal justify-content-center" }, [
14938
+ vue.createElementVNode("button", {
14939
+ class: "mr-4",
14940
+ onClick: ok
14941
+ }, "OK")
14895
14942
  ])
14896
14943
  ]),
14897
14944
  _: 1
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@g1cloud/page-builder-editor",
3
3
  "private": false,
4
- "version": "1.0.0-alpha.11",
4
+ "version": "1.0.0-alpha.13",
5
5
  "engins": {
6
6
  "node": ">= 20.0.0"
7
7
  },
@@ -28,7 +28,7 @@
28
28
  "vue-router": "^4.3.2",
29
29
  "vue3-click-away": "^1.2.4",
30
30
  "yjs": "^13.6.14",
31
- "@g1cloud/page-builder-viewer": "1.0.0-alpha.11"
31
+ "@g1cloud/page-builder-viewer": "1.0.0-alpha.13"
32
32
  },
33
33
  "devDependencies": {
34
34
  "@types/node": "^20.12.7",
@@ -1,98 +0,0 @@
1
- import { defineComponent, ref, computed, openBlock, createBlock, unref, withCtx, createElementVNode, createVNode } from "vue";
2
- import { useModalHandle, BSModalFrame, BSCodeEditor } from "@g1cloud/bluesea";
3
- const _hoisted_1 = { class: "bs-layout-vertical pb-html-editor-modal flex-grow-1 h-full" };
4
- const _hoisted_2 = { class: "bs-layout-horizontal flex-grow-1" };
5
- const _hoisted_3 = { class: "preview flex-grow-1" };
6
- const _hoisted_4 = { class: "bs-layout-vertical w-full h-full" };
7
- const _hoisted_5 = /* @__PURE__ */ createElementVNode("div", { class: "title pb-4" }, "Preview", -1);
8
- const _hoisted_6 = ["innerHTML"];
9
- const _hoisted_7 = { class: "editor bs-layout-vertical pl-8" };
10
- const _hoisted_8 = { class: "tags bs-layout-vertical w-full" };
11
- const _hoisted_9 = /* @__PURE__ */ createElementVNode("div", { class: "title pb-4" }, "HTML", -1);
12
- const _hoisted_10 = { class: "content flex-grow-1" };
13
- const _hoisted_11 = { class: "style bs-layout-vertical w-full pt-8" };
14
- const _hoisted_12 = /* @__PURE__ */ createElementVNode("div", { class: "title pb-4" }, "Style", -1);
15
- const _hoisted_13 = { class: "content flex-grow-1" };
16
- const _sfc_main = /* @__PURE__ */ defineComponent({
17
- __name: "HtmlEditorModal",
18
- props: {
19
- html: {}
20
- },
21
- emits: ["updateHtml"],
22
- setup(__props, { emit: __emit }) {
23
- var _a, _b;
24
- const props = __props;
25
- const emit = __emit;
26
- const modalHandle = useModalHandle();
27
- const tags = ref(((_a = props.html) == null ? void 0 : _a.tags) || "");
28
- const style = ref(((_b = props.html) == null ? void 0 : _b.style) || "");
29
- const html = computed(() => `${tags.value || ""}
30
- <style>${style.value || ""}</style>`);
31
- const updateTags = (value) => {
32
- tags.value = value;
33
- };
34
- const updateStyle = (value) => {
35
- style.value = value;
36
- };
37
- const ok = () => {
38
- emit("updateHtml", {
39
- tags: tags.value || "",
40
- style: style.value || ""
41
- });
42
- modalHandle.close();
43
- };
44
- return (_ctx, _cache) => {
45
- return openBlock(), createBlock(unref(BSModalFrame), { title: "HTML Editor" }, {
46
- default: withCtx(() => [
47
- createElementVNode("div", _hoisted_1, [
48
- createElementVNode("div", _hoisted_2, [
49
- createElementVNode("div", _hoisted_3, [
50
- createElementVNode("div", _hoisted_4, [
51
- _hoisted_5,
52
- createElementVNode("div", {
53
- class: "content flex-grow-1",
54
- innerHTML: html.value
55
- }, null, 8, _hoisted_6)
56
- ])
57
- ]),
58
- createElementVNode("div", _hoisted_7, [
59
- createElementVNode("div", _hoisted_8, [
60
- _hoisted_9,
61
- createElementVNode("div", _hoisted_10, [
62
- createVNode(unref(BSCodeEditor), {
63
- "model-value": tags.value,
64
- "editor-height": "100%",
65
- lang: "html",
66
- "onUpdate:modelValue": updateTags
67
- }, null, 8, ["model-value"])
68
- ])
69
- ]),
70
- createElementVNode("div", _hoisted_11, [
71
- _hoisted_12,
72
- createElementVNode("div", _hoisted_13, [
73
- createVNode(unref(BSCodeEditor), {
74
- "model-value": style.value,
75
- "editor-height": "100%",
76
- lang: "css",
77
- "onUpdate:modelValue": updateStyle
78
- }, null, 8, ["model-value"])
79
- ])
80
- ])
81
- ])
82
- ]),
83
- createElementVNode("div", { class: "buttons pt-24" }, [
84
- createElementVNode("button", {
85
- class: "mr-4",
86
- onClick: ok
87
- }, "OK")
88
- ])
89
- ])
90
- ]),
91
- _: 1
92
- });
93
- };
94
- }
95
- });
96
- export {
97
- _sfc_main as default
98
- };