@g1cloud/page-builder-editor 1.0.0-alpha.37 → 1.0.0-alpha.38

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.
@@ -208,6 +208,10 @@
208
208
  }
209
209
 
210
210
  .pb-part-add-modal {
211
+ .section-title {
212
+ font-weight: 700;
213
+ }
214
+
211
215
  .group {
212
216
 
213
217
  .part {
package/css/page.scss CHANGED
@@ -17,6 +17,12 @@ body {
17
17
  overflow: hidden;
18
18
  }
19
19
 
20
+ .font-icon {
21
+ font-family: "Material Symbols Outlined", monospace;
22
+ font-size: 1rem;
23
+ max-width: 1em;
24
+ }
25
+
20
26
  .pb-position-mark {
21
27
  background-color: #ff3333;
22
28
  opacity: 0.5;
@@ -62,6 +68,8 @@ body {
62
68
  }
63
69
 
64
70
  > i {
71
+ font-family: "Material Symbols Outlined", monospace;
72
+ font-style: normal;
65
73
  vertical-align: middle;
66
74
  position: absolute;
67
75
  top: 50%;
@@ -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-D1WOGghM.js";
3
+ import { P as PbColorPicker } from "./index-DsIuGIwL.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-D1WOGghM.js";
3
+ import { u as usePageBuilderEditor } from "./index-DsIuGIwL.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,5 +1,5 @@
1
1
  import { defineComponent, openBlock, createElementBlock, createElementVNode, toDisplayString } from "vue";
2
- import { u as usePageBuilderEditor } from "./index-D1WOGghM.js";
2
+ import { u as usePageBuilderEditor } from "./index-DsIuGIwL.js";
3
3
  import { useModal } from "@g1cloud/bluesea";
4
4
  const _hoisted_1 = { class: "property-editor property-editor-image flex-align-center" };
5
5
  const _hoisted_2 = { class: "title" };
@@ -1,6 +1,6 @@
1
1
  import { defineComponent, computed, openBlock, createElementBlock, createElementVNode, toDisplayString, createBlock, unref } from "vue";
2
2
  import { BSMultiLangTextArea, BSTextArea } from "@g1cloud/bluesea";
3
- import { u as usePageBuilderEditor } from "./index-D1WOGghM.js";
3
+ import { u as usePageBuilderEditor } from "./index-DsIuGIwL.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"];
@@ -1,6 +1,6 @@
1
1
  import { defineComponent, computed, openBlock, createElementBlock, createElementVNode, toDisplayString, createBlock, unref } from "vue";
2
2
  import { BSMultiLangTextInput, BSTextInput } from "@g1cloud/bluesea";
3
- import { u as usePageBuilderEditor } from "./index-D1WOGghM.js";
3
+ import { u as usePageBuilderEditor } from "./index-DsIuGIwL.js";
4
4
  const _hoisted_1 = { class: "property-editor property-editor-text flex-align-center" };
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 } from "vue";
2
2
  import { useModal } from "@g1cloud/bluesea";
3
- import { s as selectYoutubeVideo } from "./index-D1WOGghM.js";
3
+ import { s as selectYoutubeVideo } from "./index-DsIuGIwL.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,12 +1,13 @@
1
1
  import { defineComponent, computed, openBlock, createBlock, unref, withCtx, createElementVNode, createElementBlock, Fragment, renderList, toDisplayString } from "vue";
2
2
  import { useModalHandle, BSModalFrame } from "@g1cloud/bluesea";
3
- import { w as widgetPartDefinitions } from "./index-D1WOGghM.js";
3
+ import { w as widgetPartDefinitions } from "./index-DsIuGIwL.js";
4
4
  const _hoisted_1 = { class: "bs-layout-vertical pb-part-add-modal" };
5
5
  const _hoisted_2 = { class: "bs-layout-horizontal-wrap ml-16 mb-8 gap-8" };
6
6
  const _hoisted_3 = ["onClick", "textContent"];
7
7
  const _hoisted_4 = { class: "group mb-16" };
8
- const _hoisted_5 = { class: "bs-layout-horizontal-wrap ml-16 mb-8 gap-8" };
9
- const _hoisted_6 = ["onClick", "textContent"];
8
+ const _hoisted_5 = ["textContent"];
9
+ const _hoisted_6 = { class: "bs-layout-horizontal-wrap ml-16 mb-8 gap-8" };
10
+ const _hoisted_7 = ["onClick", "textContent"];
10
11
  const _sfc_main = /* @__PURE__ */ defineComponent({
11
12
  __name: "PbWidgetAddModal",
12
13
  props: {
@@ -25,7 +26,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
25
26
  modalHandle.close();
26
27
  };
27
28
  return (_ctx, _cache) => {
28
- return openBlock(), createBlock(unref(BSModalFrame), { title: "Add Block/Widget" }, {
29
+ return openBlock(), createBlock(unref(BSModalFrame), { title: "Add Widget" }, {
29
30
  default: withCtx(() => [
30
31
  createElementVNode("div", _hoisted_1, [
31
32
  (openBlock(true), createElementBlock(Fragment, null, renderList(unref(widgetPartDefinitions), (group) => {
@@ -34,14 +35,14 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
34
35
  class: "group mb-16"
35
36
  }, [
36
37
  _cache[0] || (_cache[0] = createElementVNode("div", {
37
- class: "mb-8",
38
+ class: "mb-8 section-title",
38
39
  textContent: "Basic Widgets"
39
40
  }, null, -1)),
40
41
  createElementVNode("div", _hoisted_2, [
41
42
  (openBlock(true), createElementBlock(Fragment, null, renderList(group.partDefinitions, (part) => {
42
43
  return openBlock(), createElementBlock("div", {
43
44
  key: part.partName,
44
- class: "part",
45
+ class: "part w-200",
45
46
  onClick: ($event) => select(part),
46
47
  textContent: toDisplayString(part.caption)
47
48
  }, null, 8, _hoisted_3);
@@ -49,22 +50,24 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
49
50
  ])
50
51
  ]);
51
52
  }), 128)),
52
- createElementVNode("div", _hoisted_4, [
53
- _cache[1] || (_cache[1] = createElementVNode("div", {
54
- class: "mb-8",
55
- textContent: "Custom Widgets"
56
- }, null, -1)),
57
- createElementVNode("div", _hoisted_5, [
58
- (openBlock(true), createElementBlock(Fragment, null, renderList(customWidgets.value, (part) => {
59
- return openBlock(), createElementBlock("div", {
60
- key: part.partName,
61
- class: "part",
62
- onClick: ($event) => select(part),
63
- textContent: toDisplayString(part.caption)
64
- }, null, 8, _hoisted_6);
65
- }), 128))
66
- ])
67
- ])
53
+ (openBlock(true), createElementBlock(Fragment, null, renderList(customWidgets.value, (group) => {
54
+ return openBlock(), createElementBlock("div", _hoisted_4, [
55
+ createElementVNode("div", {
56
+ class: "mb-8 section-title",
57
+ textContent: toDisplayString(group.caption)
58
+ }, null, 8, _hoisted_5),
59
+ createElementVNode("div", _hoisted_6, [
60
+ (openBlock(true), createElementBlock(Fragment, null, renderList(group.partDefinitions, (part) => {
61
+ return openBlock(), createElementBlock("div", {
62
+ key: part.partName,
63
+ class: "part w-200",
64
+ onClick: ($event) => select(part),
65
+ textContent: toDisplayString(part.caption)
66
+ }, null, 8, _hoisted_7);
67
+ }), 128))
68
+ ])
69
+ ]);
70
+ }), 256))
68
71
  ])
69
72
  ]),
70
73
  _: 1
@@ -8145,15 +8145,15 @@ class PartManager {
8145
8145
  const defaultPartPropertyEditors = () => {
8146
8146
  return {
8147
8147
  "readonly-text": () => defineAsyncComponent(() => import("./PbPropertyEditorReadonlyText-Dgp_AVOD.js")),
8148
- "text": () => defineAsyncComponent(() => import("./PbPropertyEditorText-DYFsKLw3.js")),
8148
+ "text": () => defineAsyncComponent(() => import("./PbPropertyEditorText-Dv0fJMe9.js")),
8149
8149
  "number": () => defineAsyncComponent(() => import("./PbPropertyEditorNumber-TTgo0zbQ.js")),
8150
8150
  "boolean": () => defineAsyncComponent(() => import("./PbPropertyEditorBoolean-C7-iSAtn.js")),
8151
- "multiline-text": () => defineAsyncComponent(() => import("./PbPropertyEditorMultilineText-D06TJqWF.js")),
8151
+ "multiline-text": () => defineAsyncComponent(() => import("./PbPropertyEditorMultilineText-CNr5khDs.js")),
8152
8152
  "select": () => defineAsyncComponent(() => import("./PbPropertyEditorSelect-CWedbXJI.js")),
8153
- "color": () => defineAsyncComponent(() => import("./PbPropertyEditorColor-Dk0MS-6z.js")),
8154
- "image": () => defineAsyncComponent(() => import("./PbPropertyEditorImage-zMooa_HL.js")),
8155
- "html": () => defineAsyncComponent(() => import("./PbPropertyEditorHtml-DASXlPF1.js")),
8156
- "youtube": () => defineAsyncComponent(() => import("./PbPropertyEditorYoutube-CT1pn88F.js"))
8153
+ "color": () => defineAsyncComponent(() => import("./PbPropertyEditorColor-w19UyXyL.js")),
8154
+ "image": () => defineAsyncComponent(() => import("./PbPropertyEditorImage-C5nERuUJ.js")),
8155
+ "html": () => defineAsyncComponent(() => import("./PbPropertyEditorHtml-DXWHj2CD.js")),
8156
+ "youtube": () => defineAsyncComponent(() => import("./PbPropertyEditorYoutube-DrPrai1y.js"))
8157
8157
  };
8158
8158
  };
8159
8159
  const getPropertyValueOfParts = (parts, propertyName) => {
@@ -12487,7 +12487,7 @@ __publicField(_OpenAddWidgetModalCommand, "COMMAND_ID", "OpenAddWidgetModal");
12487
12487
  let OpenAddWidgetModalCommand = _OpenAddWidgetModalCommand;
12488
12488
  const openWidgetAddModal = (modal, args, callback) => {
12489
12489
  modal.openModal({
12490
- component: defineAsyncComponent(() => import("./PbWidgetAddModal-CuuohgRc.js")),
12490
+ component: defineAsyncComponent(() => import("./PbWidgetAddModal-D3QjBrfz.js")),
12491
12491
  style: {
12492
12492
  width: "80%",
12493
12493
  height: "80%",
@@ -13713,7 +13713,6 @@ class PageBuilderEditorImpl {
13713
13713
  __publicField(this, "locale", ref("en"));
13714
13714
  __publicField(this, "locales", ref(["en"]));
13715
13715
  __publicField(this, "customWidgets", []);
13716
- __publicField(this, "watchers", {});
13717
13716
  __publicField(this, "providers", {});
13718
13717
  __publicField(this, "externalCssLinks", []);
13719
13718
  __publicField(this, "externalCssContent", "");
@@ -13755,22 +13754,28 @@ class PageBuilderEditorImpl {
13755
13754
  registerCustomPlugin(plugin) {
13756
13755
  if (plugin.widgets) {
13757
13756
  const partDefinitions2 = {};
13758
- plugin.widgets.forEach((v) => {
13759
- const w = { ...v };
13760
- w.partType = "Widget";
13761
- w.creator = () => _sfc_main$q;
13762
- w.propertyGroups = [...w.propertyGroups, ...defaultWidgetPropertyGroups()];
13763
- partDefinitions2[v.partName] = w;
13764
- const found = this.customWidgets.find((x) => x.partName === v.partName);
13765
- if (!found) {
13766
- this.customWidgets.push(w);
13757
+ plugin.widgets.forEach((group) => {
13758
+ if (group.partDefinitions && group.partDefinitions.length) {
13759
+ const g = {
13760
+ groupName: group.groupName,
13761
+ caption: group.caption,
13762
+ partDefinitions: []
13763
+ };
13764
+ group.partDefinitions.forEach((part) => {
13765
+ const p = { ...part };
13766
+ p.partType = "Widget";
13767
+ p.creator = () => _sfc_main$q;
13768
+ p.propertyGroups = [...p.propertyGroups, ...defaultWidgetPropertyGroups()];
13769
+ partDefinitions2[p.partName] = p;
13770
+ g.partDefinitions.push(p);
13771
+ });
13772
+ if (g.partDefinitions && g.partDefinitions.length) {
13773
+ this.customWidgets.push(g);
13774
+ }
13767
13775
  }
13768
13776
  });
13769
13777
  this.partManager.registerPartDefinitions(partDefinitions2);
13770
13778
  }
13771
- if (plugin.watchers) {
13772
- this.watchers = { ...this.providers, ...plugin.watchers };
13773
- }
13774
13779
  if (plugin.providers) {
13775
13780
  this.providers = { ...this.providers, ...plugin.providers };
13776
13781
  }
@@ -14508,7 +14513,7 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
14508
14513
  };
14509
14514
  }
14510
14515
  });
14511
- const canvasStyle = '.pb-page-wrapper {\n margin: 0 auto;\n padding: 0;\n}\n\n.pb-page {\n display: flex;\n flex-direction: column;\n align-items: center;\n width: 100%;\n padding-bottom: 100px;\n background-position: 50% 50%;\n background-repeat: no-repeat;\n background-size: cover;\n}\n\n.pb-page .pb-page-content {\n display: flex;\n flex-direction: column;\n width: 100%;\n}\n\n.pb-page .pb-page-content.selected::before {\n content: "";\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n border: 2px solid #4998f8;\n z-index: 999;\n pointer-events: none;\n}\n\n.pb-page * {\n box-sizing: border-box;\n}\n\n.pb-add-widget-button {\n width: 100%;\n height: 100%;\n min-height: 200px;\n position: relative;\n}\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\n.pb-add-widget-button button:hover {\n background-color: #eeeeee;\n}\n\n.pb-add-widget-button .icon {\n font-size: 1rem;\n vertical-align: middle;\n}\n\n.pb-add-widget-button .text {\n font-size: 1rem;\n vertical-align: middle;\n margin-left: 0.4rem;\n}\n\n.pb-section {\n display: flex;\n position: relative;\n width: 100%;\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\n.pb-section:hover:not(:has(.pb-block:hover)) {\n background-color: #f0f0f0;\n}\n\n.pb-section.selected::before {\n content: "";\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n border: 2px solid #4998f8;\n z-index: 999;\n pointer-events: none;\n}\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\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\n.pb-section-static .pb-widget {\n outline: none;\n}\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\n.pb-block:hover:not(:has(.pb-widget:hover)) {\n background-color: #f0f0f0;\n}\n\n.pb-block.selected::before {\n content: "";\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n border: 2px solid #4998f8;\n z-index: 999;\n pointer-events: none;\n}\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 pointer-events: auto !important;\n}\n\n.pb-widget * {\n pointer-events: none;\n}\n\n.pb-widget.selected::before {\n content: "";\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n border: 2px solid #4998f8;\n z-index: 999;\n pointer-events: none;\n}\n\n.pb-widget .children {\n position: absolute;\n width: 100%;\n height: 100%;\n}\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 pointer-events: auto !important;\n}\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 pointer-events: auto !important;\n}\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\n.pb-widget .children {\n position: absolute;\n width: 100%;\n height: 100%;\n}\n\n.pb-text-widget {\n width: 100%;\n height: fit-content;\n}\n\n.pb-text-widget .text {\n color: #333;\n}\n\n.pb-text-widget .placeholder {\n padding: 4px 0;\n font-size: 18px;\n text-align: center;\n color: #999;\n}\n\n.pb-image-widget {\n width: 100%;\n}\n\n.pb-image-widget .image {\n width: 100%;\n}\n\n.pb-image-widget .placeholder {\n height: 100px;\n background-color: #eee;\n text-align: center;\n}\n\n.pb-image-widget .placeholder span {\n font-size: 40px;\n color: #999;\n line-height: 100px;\n vertical-align: middle;\n}\n\n.pb-html-widget {\n width: 100%;\n height: fit-content;\n}\n\n.pb-html-widget .placeholder {\n padding: 4px 0;\n font-size: 18px;\n text-align: center;\n color: #999;\n}\n\n.pb-iframe-widget {\n width: 100%;\n height: fit-content;\n}\n\n.pb-iframe-widget .placeholder {\n padding: 4px 0;\n font-size: 18px;\n text-align: center;\n color: #999;\n}\n\n.pb-youtube-widget {\n width: 100%;\n}\n\n.pb-youtube-widget .youtube {\n width: 100%;\n height: 100%;\n}\n\n.pb-youtube-widget .placeholder {\n height: 100px;\n background-color: #eee;\n text-align: center;\n}\n\n.pb-youtube-widget .placeholder span {\n font-size: 40px;\n color: #999;\n line-height: 100px;\n vertical-align: middle;\n}\n\n.pb-container-widget {\n width: 100%;\n}\n\n.pb-container-widget .placeholder {\n height: 100px;\n background-color: #eee;\n text-align: center;\n}\n\n.pb-container-widget .placeholder span {\n font-size: 40px;\n color: #999;\n line-height: 100px;\n vertical-align: middle;\n}\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\n.pb-product-list-widget .product-wrapper {\n width: 25%;\n}\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\n.pb-product-list-widget .product-wrapper img {\n width: 100%;\n}\n\n.pb-product-list-widget .product-wrapper .name {\n margin-top: 8px;\n font-size: 14px;\n}\n\n.pb-product-list-widget .product-wrapper .price {\n margin-top: 8px;\n font-size: 14px;\n font-weight: bold;\n}\n\n.pb-product-list-widget .product-wrapper .empty {\n height: 200px;\n background-color: #eee;\n text-align: center;\n}\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\n@media (max-width: 768px) {\n .pb-product-list-widget .product-wrapper {\n width: 50%;\n }\n}\n\n.mobile .pb-product-list-widget .product-wrapper {\n width: 50%;\n}\n\n.pb-login-widget {\n height: 200px;\n text-align: center;\n}\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\n.font-icon {\n font-family: Material Symbols Outlined, monospace;\n font-size: 1rem;\n max-width: 1em;\n}\n\nbody {\n margin: 0;\n padding: 0;\n background-color: #aaa;\n overflow: hidden;\n}\n\n.pb-position-mark {\n background-color: #ff3333;\n opacity: 0.5;\n border-radius: 2px;\n}\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\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\n.pb-add-section-handle.bottom {\n bottom: -32px;\n}\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\n.pb-add-section-handle > i {\n vertical-align: middle;\n position: absolute;\n top: 50%;\n left: 0;\n font-size: 2rem;\n transform: translate(-50%, -50%);\n opacity: 0.2;\n}';
14516
+ const canvasStyle = '.pb-page-wrapper {\n margin: 0 auto;\n padding: 0;\n}\n\n.pb-page {\n display: flex;\n flex-direction: column;\n align-items: center;\n width: 100%;\n padding-bottom: 100px;\n background-position: 50% 50%;\n background-repeat: no-repeat;\n background-size: cover;\n}\n\n.pb-page .pb-page-content {\n display: flex;\n flex-direction: column;\n width: 100%;\n}\n\n.pb-page .pb-page-content.selected::before {\n content: "";\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n border: 2px solid #4998f8;\n z-index: 999;\n pointer-events: none;\n}\n\n.pb-page * {\n box-sizing: border-box;\n}\n\n.pb-add-widget-button {\n width: 100%;\n height: 100%;\n min-height: 200px;\n position: relative;\n}\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\n.pb-add-widget-button button:hover {\n background-color: #eeeeee;\n}\n\n.pb-add-widget-button .icon {\n font-size: 1rem;\n vertical-align: middle;\n}\n\n.pb-add-widget-button .text {\n font-size: 1rem;\n vertical-align: middle;\n margin-left: 0.4rem;\n}\n\n.pb-section {\n display: flex;\n position: relative;\n width: 100%;\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\n.pb-section:hover:not(:has(.pb-block:hover)) {\n background-color: #f0f0f0;\n}\n\n.pb-section.selected::before {\n content: "";\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n border: 2px solid #4998f8;\n z-index: 999;\n pointer-events: none;\n}\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\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\n.pb-section-static .pb-widget {\n outline: none;\n}\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\n.pb-block:hover:not(:has(.pb-widget:hover)) {\n background-color: #f0f0f0;\n}\n\n.pb-block.selected::before {\n content: "";\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n border: 2px solid #4998f8;\n z-index: 999;\n pointer-events: none;\n}\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 pointer-events: auto !important;\n}\n\n.pb-widget * {\n pointer-events: none;\n}\n\n.pb-widget.selected::before {\n content: "";\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n border: 2px solid #4998f8;\n z-index: 999;\n pointer-events: none;\n}\n\n.pb-widget .children {\n position: absolute;\n width: 100%;\n height: 100%;\n}\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 pointer-events: auto !important;\n}\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 pointer-events: auto !important;\n}\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\n.pb-widget .children {\n position: absolute;\n width: 100%;\n height: 100%;\n}\n\n.pb-text-widget {\n width: 100%;\n height: fit-content;\n}\n\n.pb-text-widget .text {\n color: #333;\n}\n\n.pb-text-widget .placeholder {\n padding: 4px 0;\n font-size: 18px;\n text-align: center;\n color: #999;\n}\n\n.pb-image-widget {\n width: 100%;\n}\n\n.pb-image-widget .image {\n width: 100%;\n}\n\n.pb-image-widget .placeholder {\n height: 100px;\n background-color: #eee;\n text-align: center;\n}\n\n.pb-image-widget .placeholder span {\n font-size: 40px;\n color: #999;\n line-height: 100px;\n vertical-align: middle;\n}\n\n.pb-html-widget {\n width: 100%;\n height: fit-content;\n}\n\n.pb-html-widget .placeholder {\n padding: 4px 0;\n font-size: 18px;\n text-align: center;\n color: #999;\n}\n\n.pb-iframe-widget {\n width: 100%;\n height: fit-content;\n}\n\n.pb-iframe-widget .placeholder {\n padding: 4px 0;\n font-size: 18px;\n text-align: center;\n color: #999;\n}\n\n.pb-youtube-widget {\n width: 100%;\n}\n\n.pb-youtube-widget .youtube {\n width: 100%;\n height: 100%;\n}\n\n.pb-youtube-widget .placeholder {\n height: 100px;\n background-color: #eee;\n text-align: center;\n}\n\n.pb-youtube-widget .placeholder span {\n font-size: 40px;\n color: #999;\n line-height: 100px;\n vertical-align: middle;\n}\n\n.pb-container-widget {\n width: 100%;\n}\n\n.pb-container-widget .placeholder {\n height: 100px;\n background-color: #eee;\n text-align: center;\n}\n\n.pb-container-widget .placeholder span {\n font-size: 40px;\n color: #999;\n line-height: 100px;\n vertical-align: middle;\n}\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\n.pb-product-list-widget .product-wrapper {\n width: 25%;\n}\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\n.pb-product-list-widget .product-wrapper img {\n width: 100%;\n}\n\n.pb-product-list-widget .product-wrapper .name {\n margin-top: 8px;\n font-size: 14px;\n}\n\n.pb-product-list-widget .product-wrapper .price {\n margin-top: 8px;\n font-size: 14px;\n font-weight: bold;\n}\n\n.pb-product-list-widget .product-wrapper .empty {\n height: 200px;\n background-color: #eee;\n text-align: center;\n}\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\n@media (max-width: 768px) {\n .pb-product-list-widget .product-wrapper {\n width: 50%;\n }\n}\n\n.mobile .pb-product-list-widget .product-wrapper {\n width: 50%;\n}\n\n.pb-login-widget {\n height: 200px;\n text-align: center;\n}\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\n.font-icon {\n font-family: Material Symbols Outlined, monospace;\n font-size: 1rem;\n max-width: 1em;\n}\n\nbody {\n margin: 0;\n padding: 0;\n background-color: #aaa;\n overflow: hidden;\n}\n\n.font-icon {\n font-family: "Material Symbols Outlined", monospace;\n font-size: 1rem;\n max-width: 1em;\n}\n\n.pb-position-mark {\n background-color: #ff3333;\n opacity: 0.5;\n border-radius: 2px;\n}\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\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\n.pb-add-section-handle.bottom {\n bottom: -32px;\n}\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\n.pb-add-section-handle > i {\n font-family: "Material Symbols Outlined", monospace;\n font-style: normal;\n vertical-align: middle;\n position: absolute;\n top: 50%;\n left: 0;\n font-size: 2rem;\n transform: translate(-50%, -50%);\n opacity: 0.2;\n}';
14512
14517
  const _hoisted_1$2 = ["width"];
14513
14518
  const _sfc_main$2 = /* @__PURE__ */ defineComponent({
14514
14519
  __name: "PbPageFrame",
@@ -14533,6 +14538,9 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
14533
14538
  const head = (_e = (_d = iframeRef.value) == null ? void 0 : _d.contentWindow) == null ? void 0 : _e.document.head;
14534
14539
  head.innerHTML = `
14535
14540
  <meta charset="UTF-8"/>
14541
+ <link
14542
+ href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&display=block"
14543
+ rel="stylesheet"/>
14536
14544
  ${externalCss}
14537
14545
  <style>${canvasStyle}</style>
14538
14546
  `;
package/dist/index.d.ts CHANGED
@@ -1,7 +1,8 @@
1
+ import { PartDefinition, PartDefinitionGroup } from './model/part-definintion.ts';
1
2
  import { PartProperty } from './model/part-property.ts';
2
3
 
3
4
  export { default as PageBuilderEditor } from './PageBuilderEditor.vue';
4
- export type { PartProperty };
5
+ export type { PartProperty, PartDefinitionGroup, PartDefinition };
5
6
  export * from './model/event';
6
7
  export * from './model/plugin';
7
8
  export * from '@g1cloud/page-builder-viewer';
@@ -1,4 +1,4 @@
1
- import { PartDefinition } from './part-definintion.ts';
1
+ import { PartDefinitionGroup } from './part-definintion.ts';
2
2
  import { ContextMenuRegistry, ContextMenuRegistryImpl, KeyHandlers, PageBuilderContext, PageBuilderContextImpl } from './context.ts';
3
3
  import { ToolButtonRegistry } from './toolbar.ts';
4
4
  import { PageBuilderPlugin } from './plugin.ts';
@@ -36,7 +36,7 @@ export interface PageBuilderEditor extends PageBuilder {
36
36
  setLocales(locales?: string[]): void;
37
37
  makeSingleScreen(screenToKeep: number): void;
38
38
  makeMultipleScreen(): void;
39
- getCustomWidgets(): PartDefinition[];
39
+ getCustomWidgets(): PartDefinitionGroup[];
40
40
  getProvider(name: string): (args?: any, callback?: (result?: any) => void) => unknown;
41
41
  extractMedia(part: IPart): string[];
42
42
  }
@@ -53,8 +53,7 @@ export declare class PageBuilderEditorImpl implements PageBuilderEditor {
53
53
  scale: Ref<number>;
54
54
  locale: Ref<string>;
55
55
  locales: Ref<string[]>;
56
- customWidgets: PartDefinition[];
57
- watchers: Record<string, unknown>;
56
+ customWidgets: PartDefinitionGroup[];
58
57
  providers: Record<string, unknown>;
59
58
  externalCssLinks: string[];
60
59
  externalCssContent: string;
@@ -73,7 +72,7 @@ export declare class PageBuilderEditorImpl implements PageBuilderEditor {
73
72
  zoom(scale: number): void;
74
73
  makeSingleScreen(screenToKeep: number): void;
75
74
  makeMultipleScreen(): void;
76
- getCustomWidgets(): PartDefinition[];
75
+ getCustomWidgets(): PartDefinitionGroup[];
77
76
  extractMedia(part: IPart): string[];
78
77
  getExternalCss(): string;
79
78
  private extractMediaFromPart;
@@ -1,4 +1,4 @@
1
- import { B, b, M, c, d, e, _, a, f, g, h, i, j, k, l, m, n, R, o, S, p, W, q, r, t, v, x, y, z, A, C } from "./index-D1WOGghM.js";
1
+ import { B, b, M, c, d, e, _, a, f, g, h, i, j, k, l, m, n, R, o, S, p, W, q, r, t, v, x, y, z, A, C } from "./index-DsIuGIwL.js";
2
2
  export {
3
3
  B as BLOCK_TYPE,
4
4
  b as Block,
@@ -9253,7 +9253,7 @@ ${_html.style}
9253
9253
  const _hoisted_4$d = { class: "bg-gray-100 py-5 rounded-8" };
9254
9254
  const _hoisted_5$7 = { class: "text-center" };
9255
9255
  const _hoisted_6$7 = { class: "bs-layout-horizontal justify-content-center align-items-center" };
9256
- const _hoisted_7$6 = { class: "text-center" };
9256
+ const _hoisted_7$7 = { class: "text-center" };
9257
9257
  const _sfc_main$y = /* @__PURE__ */ vue.defineComponent({
9258
9258
  __name: "PbPropertyGroupEditorPosition",
9259
9259
  props: {
@@ -9316,7 +9316,7 @@ ${_html.style}
9316
9316
  "onUpdate:modelValue": updateRight
9317
9317
  }, null, 8, ["model-value"])
9318
9318
  ]),
9319
- vue.createElementVNode("div", _hoisted_7$6, [
9319
+ vue.createElementVNode("div", _hoisted_7$7, [
9320
9320
  vue.createVNode(vue.unref(bluesea.BSTextInput), {
9321
9321
  "model-value": bottom.value,
9322
9322
  class: "ml-4",
@@ -9338,7 +9338,7 @@ ${_html.style}
9338
9338
  const _hoisted_4$c = { class: "flex-align-center mt-12" };
9339
9339
  const _hoisted_5$6 = { class: "flex-grow-1 bs-layout-horizontal" };
9340
9340
  const _hoisted_6$6 = { class: "flex-align-center mt-12" };
9341
- const _hoisted_7$5 = { class: "flex-grow-1 bs-layout-horizontal" };
9341
+ const _hoisted_7$6 = { class: "flex-grow-1 bs-layout-horizontal" };
9342
9342
  const _sfc_main$x = /* @__PURE__ */ vue.defineComponent({
9343
9343
  __name: "PbPropertyGroupEditorSize",
9344
9344
  props: {
@@ -9410,7 +9410,7 @@ ${_html.style}
9410
9410
  _cache[2] || (_cache[2] = vue.createElementVNode("div", { class: "title" }, [
9411
9411
  vue.createElementVNode("label", { textContent: "Min Size" })
9412
9412
  ], -1)),
9413
- vue.createElementVNode("div", _hoisted_7$5, [
9413
+ vue.createElementVNode("div", _hoisted_7$6, [
9414
9414
  vue.createVNode(vue.unref(bluesea.BSTextInput), {
9415
9415
  "model-value": minWidth.value,
9416
9416
  class: "flex-grow-1 mr-2",
@@ -11133,7 +11133,7 @@ ${_html.style}
11133
11133
  class: "vc-sketch-alpha-wrap"
11134
11134
  };
11135
11135
  const _hoisted_6$5 = { class: "vc-sketch-color-wrap" };
11136
- const _hoisted_7$4 = ["aria-label"];
11136
+ const _hoisted_7$5 = ["aria-label"];
11137
11137
  const _hoisted_8$2 = {
11138
11138
  key: 0,
11139
11139
  class: "vc-sketch-field"
@@ -11193,7 +11193,7 @@ ${_html.style}
11193
11193
  "aria-label": `Current color is ${$options.activeColor}`,
11194
11194
  class: "vc-sketch-active-color",
11195
11195
  style: vue.normalizeStyle({ background: $options.activeColor })
11196
- }, null, 12, _hoisted_7$4),
11196
+ }, null, 12, _hoisted_7$5),
11197
11197
  vue.createVNode(_component_Checkboard)
11198
11198
  ])
11199
11199
  ]),
@@ -11455,7 +11455,7 @@ ${_html.style}
11455
11455
  const _hoisted_4$6 = { class: "color" };
11456
11456
  const _hoisted_5$4 = { class: "mt-8" };
11457
11457
  const _hoisted_6$4 = { class: "flex-grow-1 mt-4" };
11458
- const _hoisted_7$3 = { class: "bg-gray-100 py-5 rounded-8" };
11458
+ const _hoisted_7$4 = { class: "bg-gray-100 py-5 rounded-8" };
11459
11459
  const _hoisted_8$1 = { class: "text-center" };
11460
11460
  const _hoisted_9 = { class: "bs-layout-horizontal justify-content-center align-items-center" };
11461
11461
  const _hoisted_10 = { class: "text-center" };
@@ -11534,7 +11534,7 @@ ${_html.style}
11534
11534
  vue.createElementVNode("label", { textContent: "Border Width" })
11535
11535
  ], -1)),
11536
11536
  vue.createElementVNode("div", _hoisted_6$4, [
11537
- vue.createElementVNode("div", _hoisted_7$3, [
11537
+ vue.createElementVNode("div", _hoisted_7$4, [
11538
11538
  vue.createElementVNode("div", _hoisted_8$1, [
11539
11539
  vue.createVNode(vue.unref(bluesea.BSTextInput), {
11540
11540
  "model-value": borderTopWidth.value,
@@ -11630,7 +11630,7 @@ ${_html.style}
11630
11630
  const _hoisted_4$5 = { class: "bg-gray-100 py-5 rounded-8" };
11631
11631
  const _hoisted_5$3 = { class: "text-center" };
11632
11632
  const _hoisted_6$3 = { class: "bs-layout-horizontal justify-content-center align-items-center" };
11633
- const _hoisted_7$2 = { class: "text-center" };
11633
+ const _hoisted_7$3 = { class: "text-center" };
11634
11634
  const _sfc_main$t = /* @__PURE__ */ vue.defineComponent({
11635
11635
  __name: "PbPropertyGroupEditorMargin",
11636
11636
  props: {
@@ -11693,7 +11693,7 @@ ${_html.style}
11693
11693
  "onUpdate:modelValue": updateRight
11694
11694
  }, null, 8, ["model-value"])
11695
11695
  ]),
11696
- vue.createElementVNode("div", _hoisted_7$2, [
11696
+ vue.createElementVNode("div", _hoisted_7$3, [
11697
11697
  vue.createVNode(vue.unref(bluesea.BSTextInput), {
11698
11698
  "model-value": bottom.value,
11699
11699
  class: "ml-4",
@@ -11715,7 +11715,7 @@ ${_html.style}
11715
11715
  const _hoisted_4$4 = { class: "bg-gray-100 py-5 rounded-8" };
11716
11716
  const _hoisted_5$2 = { class: "text-center" };
11717
11717
  const _hoisted_6$2 = { class: "bs-layout-horizontal justify-content-center align-items-center" };
11718
- const _hoisted_7$1 = { class: "text-center" };
11718
+ const _hoisted_7$2 = { class: "text-center" };
11719
11719
  const _sfc_main$s = /* @__PURE__ */ vue.defineComponent({
11720
11720
  __name: "PbPropertyGroupEditorPadding",
11721
11721
  props: {
@@ -11778,7 +11778,7 @@ ${_html.style}
11778
11778
  "onUpdate:modelValue": updateRight
11779
11779
  }, null, 8, ["model-value"])
11780
11780
  ]),
11781
- vue.createElementVNode("div", _hoisted_7$1, [
11781
+ vue.createElementVNode("div", _hoisted_7$2, [
11782
11782
  vue.createVNode(vue.unref(bluesea.BSTextInput), {
11783
11783
  "model-value": bottom.value,
11784
11784
  class: "ml-4",
@@ -13714,7 +13714,6 @@ ${_html.style}
13714
13714
  __publicField(this, "locale", vue.ref("en"));
13715
13715
  __publicField(this, "locales", vue.ref(["en"]));
13716
13716
  __publicField(this, "customWidgets", []);
13717
- __publicField(this, "watchers", {});
13718
13717
  __publicField(this, "providers", {});
13719
13718
  __publicField(this, "externalCssLinks", []);
13720
13719
  __publicField(this, "externalCssContent", "");
@@ -13756,22 +13755,28 @@ ${_html.style}
13756
13755
  registerCustomPlugin(plugin) {
13757
13756
  if (plugin.widgets) {
13758
13757
  const partDefinitions2 = {};
13759
- plugin.widgets.forEach((v) => {
13760
- const w = { ...v };
13761
- w.partType = "Widget";
13762
- w.creator = () => _sfc_main$E;
13763
- w.propertyGroups = [...w.propertyGroups, ...defaultWidgetPropertyGroups()];
13764
- partDefinitions2[v.partName] = w;
13765
- const found = this.customWidgets.find((x) => x.partName === v.partName);
13766
- if (!found) {
13767
- this.customWidgets.push(w);
13758
+ plugin.widgets.forEach((group) => {
13759
+ if (group.partDefinitions && group.partDefinitions.length) {
13760
+ const g = {
13761
+ groupName: group.groupName,
13762
+ caption: group.caption,
13763
+ partDefinitions: []
13764
+ };
13765
+ group.partDefinitions.forEach((part) => {
13766
+ const p = { ...part };
13767
+ p.partType = "Widget";
13768
+ p.creator = () => _sfc_main$E;
13769
+ p.propertyGroups = [...p.propertyGroups, ...defaultWidgetPropertyGroups()];
13770
+ partDefinitions2[p.partName] = p;
13771
+ g.partDefinitions.push(p);
13772
+ });
13773
+ if (g.partDefinitions && g.partDefinitions.length) {
13774
+ this.customWidgets.push(g);
13775
+ }
13768
13776
  }
13769
13777
  });
13770
13778
  this.partManager.registerPartDefinitions(partDefinitions2);
13771
13779
  }
13772
- if (plugin.watchers) {
13773
- this.watchers = { ...this.providers, ...plugin.watchers };
13774
- }
13775
13780
  if (plugin.providers) {
13776
13781
  this.providers = { ...this.providers, ...plugin.providers };
13777
13782
  }
@@ -14509,7 +14514,7 @@ ${_html.style}
14509
14514
  };
14510
14515
  }
14511
14516
  });
14512
- const canvasStyle = '.pb-page-wrapper {\n margin: 0 auto;\n padding: 0;\n}\n\n.pb-page {\n display: flex;\n flex-direction: column;\n align-items: center;\n width: 100%;\n padding-bottom: 100px;\n background-position: 50% 50%;\n background-repeat: no-repeat;\n background-size: cover;\n}\n\n.pb-page .pb-page-content {\n display: flex;\n flex-direction: column;\n width: 100%;\n}\n\n.pb-page .pb-page-content.selected::before {\n content: "";\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n border: 2px solid #4998f8;\n z-index: 999;\n pointer-events: none;\n}\n\n.pb-page * {\n box-sizing: border-box;\n}\n\n.pb-add-widget-button {\n width: 100%;\n height: 100%;\n min-height: 200px;\n position: relative;\n}\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\n.pb-add-widget-button button:hover {\n background-color: #eeeeee;\n}\n\n.pb-add-widget-button .icon {\n font-size: 1rem;\n vertical-align: middle;\n}\n\n.pb-add-widget-button .text {\n font-size: 1rem;\n vertical-align: middle;\n margin-left: 0.4rem;\n}\n\n.pb-section {\n display: flex;\n position: relative;\n width: 100%;\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\n.pb-section:hover:not(:has(.pb-block:hover)) {\n background-color: #f0f0f0;\n}\n\n.pb-section.selected::before {\n content: "";\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n border: 2px solid #4998f8;\n z-index: 999;\n pointer-events: none;\n}\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\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\n.pb-section-static .pb-widget {\n outline: none;\n}\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\n.pb-block:hover:not(:has(.pb-widget:hover)) {\n background-color: #f0f0f0;\n}\n\n.pb-block.selected::before {\n content: "";\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n border: 2px solid #4998f8;\n z-index: 999;\n pointer-events: none;\n}\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 pointer-events: auto !important;\n}\n\n.pb-widget * {\n pointer-events: none;\n}\n\n.pb-widget.selected::before {\n content: "";\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n border: 2px solid #4998f8;\n z-index: 999;\n pointer-events: none;\n}\n\n.pb-widget .children {\n position: absolute;\n width: 100%;\n height: 100%;\n}\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 pointer-events: auto !important;\n}\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 pointer-events: auto !important;\n}\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\n.pb-widget .children {\n position: absolute;\n width: 100%;\n height: 100%;\n}\n\n.pb-text-widget {\n width: 100%;\n height: fit-content;\n}\n\n.pb-text-widget .text {\n color: #333;\n}\n\n.pb-text-widget .placeholder {\n padding: 4px 0;\n font-size: 18px;\n text-align: center;\n color: #999;\n}\n\n.pb-image-widget {\n width: 100%;\n}\n\n.pb-image-widget .image {\n width: 100%;\n}\n\n.pb-image-widget .placeholder {\n height: 100px;\n background-color: #eee;\n text-align: center;\n}\n\n.pb-image-widget .placeholder span {\n font-size: 40px;\n color: #999;\n line-height: 100px;\n vertical-align: middle;\n}\n\n.pb-html-widget {\n width: 100%;\n height: fit-content;\n}\n\n.pb-html-widget .placeholder {\n padding: 4px 0;\n font-size: 18px;\n text-align: center;\n color: #999;\n}\n\n.pb-iframe-widget {\n width: 100%;\n height: fit-content;\n}\n\n.pb-iframe-widget .placeholder {\n padding: 4px 0;\n font-size: 18px;\n text-align: center;\n color: #999;\n}\n\n.pb-youtube-widget {\n width: 100%;\n}\n\n.pb-youtube-widget .youtube {\n width: 100%;\n height: 100%;\n}\n\n.pb-youtube-widget .placeholder {\n height: 100px;\n background-color: #eee;\n text-align: center;\n}\n\n.pb-youtube-widget .placeholder span {\n font-size: 40px;\n color: #999;\n line-height: 100px;\n vertical-align: middle;\n}\n\n.pb-container-widget {\n width: 100%;\n}\n\n.pb-container-widget .placeholder {\n height: 100px;\n background-color: #eee;\n text-align: center;\n}\n\n.pb-container-widget .placeholder span {\n font-size: 40px;\n color: #999;\n line-height: 100px;\n vertical-align: middle;\n}\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\n.pb-product-list-widget .product-wrapper {\n width: 25%;\n}\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\n.pb-product-list-widget .product-wrapper img {\n width: 100%;\n}\n\n.pb-product-list-widget .product-wrapper .name {\n margin-top: 8px;\n font-size: 14px;\n}\n\n.pb-product-list-widget .product-wrapper .price {\n margin-top: 8px;\n font-size: 14px;\n font-weight: bold;\n}\n\n.pb-product-list-widget .product-wrapper .empty {\n height: 200px;\n background-color: #eee;\n text-align: center;\n}\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\n@media (max-width: 768px) {\n .pb-product-list-widget .product-wrapper {\n width: 50%;\n }\n}\n\n.mobile .pb-product-list-widget .product-wrapper {\n width: 50%;\n}\n\n.pb-login-widget {\n height: 200px;\n text-align: center;\n}\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\n.font-icon {\n font-family: Material Symbols Outlined, monospace;\n font-size: 1rem;\n max-width: 1em;\n}\n\nbody {\n margin: 0;\n padding: 0;\n background-color: #aaa;\n overflow: hidden;\n}\n\n.pb-position-mark {\n background-color: #ff3333;\n opacity: 0.5;\n border-radius: 2px;\n}\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\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\n.pb-add-section-handle.bottom {\n bottom: -32px;\n}\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\n.pb-add-section-handle > i {\n vertical-align: middle;\n position: absolute;\n top: 50%;\n left: 0;\n font-size: 2rem;\n transform: translate(-50%, -50%);\n opacity: 0.2;\n}';
14517
+ const canvasStyle = '.pb-page-wrapper {\n margin: 0 auto;\n padding: 0;\n}\n\n.pb-page {\n display: flex;\n flex-direction: column;\n align-items: center;\n width: 100%;\n padding-bottom: 100px;\n background-position: 50% 50%;\n background-repeat: no-repeat;\n background-size: cover;\n}\n\n.pb-page .pb-page-content {\n display: flex;\n flex-direction: column;\n width: 100%;\n}\n\n.pb-page .pb-page-content.selected::before {\n content: "";\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n border: 2px solid #4998f8;\n z-index: 999;\n pointer-events: none;\n}\n\n.pb-page * {\n box-sizing: border-box;\n}\n\n.pb-add-widget-button {\n width: 100%;\n height: 100%;\n min-height: 200px;\n position: relative;\n}\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\n.pb-add-widget-button button:hover {\n background-color: #eeeeee;\n}\n\n.pb-add-widget-button .icon {\n font-size: 1rem;\n vertical-align: middle;\n}\n\n.pb-add-widget-button .text {\n font-size: 1rem;\n vertical-align: middle;\n margin-left: 0.4rem;\n}\n\n.pb-section {\n display: flex;\n position: relative;\n width: 100%;\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\n.pb-section:hover:not(:has(.pb-block:hover)) {\n background-color: #f0f0f0;\n}\n\n.pb-section.selected::before {\n content: "";\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n border: 2px solid #4998f8;\n z-index: 999;\n pointer-events: none;\n}\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\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\n.pb-section-static .pb-widget {\n outline: none;\n}\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\n.pb-block:hover:not(:has(.pb-widget:hover)) {\n background-color: #f0f0f0;\n}\n\n.pb-block.selected::before {\n content: "";\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n border: 2px solid #4998f8;\n z-index: 999;\n pointer-events: none;\n}\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 pointer-events: auto !important;\n}\n\n.pb-widget * {\n pointer-events: none;\n}\n\n.pb-widget.selected::before {\n content: "";\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n border: 2px solid #4998f8;\n z-index: 999;\n pointer-events: none;\n}\n\n.pb-widget .children {\n position: absolute;\n width: 100%;\n height: 100%;\n}\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 pointer-events: auto !important;\n}\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 pointer-events: auto !important;\n}\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\n.pb-widget .children {\n position: absolute;\n width: 100%;\n height: 100%;\n}\n\n.pb-text-widget {\n width: 100%;\n height: fit-content;\n}\n\n.pb-text-widget .text {\n color: #333;\n}\n\n.pb-text-widget .placeholder {\n padding: 4px 0;\n font-size: 18px;\n text-align: center;\n color: #999;\n}\n\n.pb-image-widget {\n width: 100%;\n}\n\n.pb-image-widget .image {\n width: 100%;\n}\n\n.pb-image-widget .placeholder {\n height: 100px;\n background-color: #eee;\n text-align: center;\n}\n\n.pb-image-widget .placeholder span {\n font-size: 40px;\n color: #999;\n line-height: 100px;\n vertical-align: middle;\n}\n\n.pb-html-widget {\n width: 100%;\n height: fit-content;\n}\n\n.pb-html-widget .placeholder {\n padding: 4px 0;\n font-size: 18px;\n text-align: center;\n color: #999;\n}\n\n.pb-iframe-widget {\n width: 100%;\n height: fit-content;\n}\n\n.pb-iframe-widget .placeholder {\n padding: 4px 0;\n font-size: 18px;\n text-align: center;\n color: #999;\n}\n\n.pb-youtube-widget {\n width: 100%;\n}\n\n.pb-youtube-widget .youtube {\n width: 100%;\n height: 100%;\n}\n\n.pb-youtube-widget .placeholder {\n height: 100px;\n background-color: #eee;\n text-align: center;\n}\n\n.pb-youtube-widget .placeholder span {\n font-size: 40px;\n color: #999;\n line-height: 100px;\n vertical-align: middle;\n}\n\n.pb-container-widget {\n width: 100%;\n}\n\n.pb-container-widget .placeholder {\n height: 100px;\n background-color: #eee;\n text-align: center;\n}\n\n.pb-container-widget .placeholder span {\n font-size: 40px;\n color: #999;\n line-height: 100px;\n vertical-align: middle;\n}\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\n.pb-product-list-widget .product-wrapper {\n width: 25%;\n}\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\n.pb-product-list-widget .product-wrapper img {\n width: 100%;\n}\n\n.pb-product-list-widget .product-wrapper .name {\n margin-top: 8px;\n font-size: 14px;\n}\n\n.pb-product-list-widget .product-wrapper .price {\n margin-top: 8px;\n font-size: 14px;\n font-weight: bold;\n}\n\n.pb-product-list-widget .product-wrapper .empty {\n height: 200px;\n background-color: #eee;\n text-align: center;\n}\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\n@media (max-width: 768px) {\n .pb-product-list-widget .product-wrapper {\n width: 50%;\n }\n}\n\n.mobile .pb-product-list-widget .product-wrapper {\n width: 50%;\n}\n\n.pb-login-widget {\n height: 200px;\n text-align: center;\n}\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\n.font-icon {\n font-family: Material Symbols Outlined, monospace;\n font-size: 1rem;\n max-width: 1em;\n}\n\nbody {\n margin: 0;\n padding: 0;\n background-color: #aaa;\n overflow: hidden;\n}\n\n.font-icon {\n font-family: "Material Symbols Outlined", monospace;\n font-size: 1rem;\n max-width: 1em;\n}\n\n.pb-position-mark {\n background-color: #ff3333;\n opacity: 0.5;\n border-radius: 2px;\n}\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\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\n.pb-add-section-handle.bottom {\n bottom: -32px;\n}\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\n.pb-add-section-handle > i {\n font-family: "Material Symbols Outlined", monospace;\n font-style: normal;\n vertical-align: middle;\n position: absolute;\n top: 50%;\n left: 0;\n font-size: 2rem;\n transform: translate(-50%, -50%);\n opacity: 0.2;\n}';
14513
14518
  const _hoisted_1$g = ["width"];
14514
14519
  const _sfc_main$g = /* @__PURE__ */ vue.defineComponent({
14515
14520
  __name: "PbPageFrame",
@@ -14534,6 +14539,9 @@ ${_html.style}
14534
14539
  const head = (_e = (_d = iframeRef.value) == null ? void 0 : _d.contentWindow) == null ? void 0 : _e.document.head;
14535
14540
  head.innerHTML = `
14536
14541
  <meta charset="UTF-8"/>
14542
+ <link
14543
+ href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&display=block"
14544
+ rel="stylesheet"/>
14537
14545
  ${externalCss}
14538
14546
  <style>${canvasStyle}</style>
14539
14547
  `;
@@ -15262,8 +15270,9 @@ ${_html.style}
15262
15270
  const _hoisted_2$2 = { class: "bs-layout-horizontal-wrap ml-16 mb-8 gap-8" };
15263
15271
  const _hoisted_3$1 = ["onClick", "textContent"];
15264
15272
  const _hoisted_4$1 = { class: "group mb-16" };
15265
- const _hoisted_5$1 = { class: "bs-layout-horizontal-wrap ml-16 mb-8 gap-8" };
15266
- const _hoisted_6$1 = ["onClick", "textContent"];
15273
+ const _hoisted_5$1 = ["textContent"];
15274
+ const _hoisted_6$1 = { class: "bs-layout-horizontal-wrap ml-16 mb-8 gap-8" };
15275
+ const _hoisted_7$1 = ["onClick", "textContent"];
15267
15276
  const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({
15268
15277
  __name: "PbWidgetAddModal",
15269
15278
  props: {
@@ -15282,7 +15291,7 @@ ${_html.style}
15282
15291
  modalHandle.close();
15283
15292
  };
15284
15293
  return (_ctx, _cache) => {
15285
- return vue.openBlock(), vue.createBlock(vue.unref(bluesea.BSModalFrame), { title: "Add Block/Widget" }, {
15294
+ return vue.openBlock(), vue.createBlock(vue.unref(bluesea.BSModalFrame), { title: "Add Widget" }, {
15286
15295
  default: vue.withCtx(() => [
15287
15296
  vue.createElementVNode("div", _hoisted_1$2, [
15288
15297
  (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(vue.unref(widgetPartDefinitions), (group) => {
@@ -15291,14 +15300,14 @@ ${_html.style}
15291
15300
  class: "group mb-16"
15292
15301
  }, [
15293
15302
  _cache[0] || (_cache[0] = vue.createElementVNode("div", {
15294
- class: "mb-8",
15303
+ class: "mb-8 section-title",
15295
15304
  textContent: "Basic Widgets"
15296
15305
  }, null, -1)),
15297
15306
  vue.createElementVNode("div", _hoisted_2$2, [
15298
15307
  (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(group.partDefinitions, (part) => {
15299
15308
  return vue.openBlock(), vue.createElementBlock("div", {
15300
15309
  key: part.partName,
15301
- class: "part",
15310
+ class: "part w-200",
15302
15311
  onClick: ($event) => select(part),
15303
15312
  textContent: vue.toDisplayString(part.caption)
15304
15313
  }, null, 8, _hoisted_3$1);
@@ -15306,22 +15315,24 @@ ${_html.style}
15306
15315
  ])
15307
15316
  ]);
15308
15317
  }), 128)),
15309
- vue.createElementVNode("div", _hoisted_4$1, [
15310
- _cache[1] || (_cache[1] = vue.createElementVNode("div", {
15311
- class: "mb-8",
15312
- textContent: "Custom Widgets"
15313
- }, null, -1)),
15314
- vue.createElementVNode("div", _hoisted_5$1, [
15315
- (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(customWidgets.value, (part) => {
15316
- return vue.openBlock(), vue.createElementBlock("div", {
15317
- key: part.partName,
15318
- class: "part",
15319
- onClick: ($event) => select(part),
15320
- textContent: vue.toDisplayString(part.caption)
15321
- }, null, 8, _hoisted_6$1);
15322
- }), 128))
15323
- ])
15324
- ])
15318
+ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(customWidgets.value, (group) => {
15319
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_4$1, [
15320
+ vue.createElementVNode("div", {
15321
+ class: "mb-8 section-title",
15322
+ textContent: vue.toDisplayString(group.caption)
15323
+ }, null, 8, _hoisted_5$1),
15324
+ vue.createElementVNode("div", _hoisted_6$1, [
15325
+ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(group.partDefinitions, (part) => {
15326
+ return vue.openBlock(), vue.createElementBlock("div", {
15327
+ key: part.partName,
15328
+ class: "part w-200",
15329
+ onClick: ($event) => select(part),
15330
+ textContent: vue.toDisplayString(part.caption)
15331
+ }, null, 8, _hoisted_7$1);
15332
+ }), 128))
15333
+ ])
15334
+ ]);
15335
+ }), 256))
15325
15336
  ])
15326
15337
  ]),
15327
15338
  _: 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.37",
4
+ "version": "1.0.0-alpha.38",
5
5
  "engins": {
6
6
  "node": ">= 20.0.0"
7
7
  },
@@ -30,7 +30,7 @@
30
30
  "vue-router": "^4.4.3",
31
31
  "vue3-click-away": "^1.2.4",
32
32
  "yjs": "^13.6.14",
33
- "@g1cloud/page-builder-viewer": "1.0.0-alpha.37"
33
+ "@g1cloud/page-builder-viewer": "1.0.0-alpha.38"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@types/node": "^20.12.7",