@g1cloud/page-builder-editor 1.0.0-alpha.100 → 1.0.0-alpha.101

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.
@@ -1,6 +1,6 @@
1
1
  import { defineComponent, openBlock, createElementBlock, createElementVNode, withDirectives, unref, createVNode } from "vue";
2
2
  import { vT, BSTextInput } from "@g1cloud/bluesea";
3
- import { P as PbColorPicker } from "./index-gTlPRaWE.js";
3
+ import { P as PbColorPicker } from "./index-SyHEuk0H.js";
4
4
  const _hoisted_1 = { class: "property-editor property-editor-color" };
5
5
  const _hoisted_2 = { class: "title" };
6
6
  const _hoisted_3 = { class: "bs-layout-horizontal flex-align-center color" };
@@ -1,6 +1,6 @@
1
1
  import { defineComponent, openBlock, createElementBlock, createElementVNode, withDirectives, unref, createVNode } from "vue";
2
2
  import { vT, BSTextInput } from "@g1cloud/bluesea";
3
- import { t as toCssLength } from "./index-gTlPRaWE.js";
3
+ import { t as toCssLength } from "./index-SyHEuk0H.js";
4
4
  const _hoisted_1 = { class: "property-editor property-editor-number flex-align-center" };
5
5
  const _hoisted_2 = { class: "title" };
6
6
  const _sfc_main = /* @__PURE__ */ defineComponent({
@@ -1,6 +1,6 @@
1
1
  import { defineComponent, openBlock, createElementBlock, createElementVNode, withDirectives, unref, createTextVNode, defineAsyncComponent } from "vue";
2
2
  import { useModal, vT } from "@g1cloud/bluesea";
3
- import { u as usePageBuilderEditor } from "./index-gTlPRaWE.js";
3
+ import { u as usePageBuilderEditor } from "./index-SyHEuk0H.js";
4
4
  const _hoisted_1 = { class: "property-editor property-editor-html flex-align-center" };
5
5
  const _hoisted_2 = { class: "title" };
6
6
  const _sfc_main = /* @__PURE__ */ defineComponent({
@@ -1,5 +1,5 @@
1
1
  import { defineComponent, computed, openBlock, createElementBlock, createElementVNode, withDirectives, unref, createTextVNode, toDisplayString, createVNode, createCommentVNode, Fragment } from "vue";
2
- import { u as usePageBuilderEditor, C as ChangePropertyCommand } from "./index-gTlPRaWE.js";
2
+ import { u as usePageBuilderEditor, C as ChangePropertyCommand } from "./index-SyHEuk0H.js";
3
3
  import { useModal, vT, BSButton, BSMultiLangTextInput, showNotification } from "@g1cloud/bluesea";
4
4
  const _hoisted_1 = { class: "property-editor property-editor-image" };
5
5
  const _hoisted_2 = { class: "title" };
@@ -1,6 +1,6 @@
1
1
  import { defineComponent, computed, openBlock, createElementBlock, createElementVNode, withDirectives, unref, createBlock } from "vue";
2
2
  import { vT, BSMultiLangTextArea, BSTextArea } from "@g1cloud/bluesea";
3
- import { u as usePageBuilderEditor } from "./index-gTlPRaWE.js";
3
+ import { u as usePageBuilderEditor } from "./index-SyHEuk0H.js";
4
4
  const _hoisted_1 = { class: "property-editor property-editor-multiline-text" };
5
5
  const _hoisted_2 = { class: "title" };
6
6
  const _sfc_main = /* @__PURE__ */ defineComponent({
@@ -1,6 +1,6 @@
1
1
  import { defineComponent, computed, openBlock, createElementBlock, createElementVNode, withDirectives, unref, createBlock } from "vue";
2
2
  import { vT, BSMultiLangTextInput, BSTextInput } from "@g1cloud/bluesea";
3
- import { u as usePageBuilderEditor } from "./index-gTlPRaWE.js";
3
+ import { u as usePageBuilderEditor } from "./index-SyHEuk0H.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 _sfc_main = /* @__PURE__ */ defineComponent({
@@ -1,6 +1,6 @@
1
1
  import { defineComponent, openBlock, createElementBlock, createElementVNode, withDirectives, unref, createTextVNode, toDisplayString, createVNode, createCommentVNode } from "vue";
2
2
  import { useModal, vT, BSButton } from "@g1cloud/bluesea";
3
- import { s as selectYoutubeVideo } from "./index-gTlPRaWE.js";
3
+ import { s as selectYoutubeVideo } from "./index-SyHEuk0H.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 = {
@@ -19,11 +19,15 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
19
19
  const modal = useModal();
20
20
  const emit = __emit;
21
21
  const clearVideo = () => {
22
- emit("update-property-value", { url: "" });
22
+ emit("update-property-value", { url: "", aspectRatio: "" });
23
23
  };
24
24
  const selectVideo = () => {
25
- selectYoutubeVideo(modal, props.value, (url) => {
26
- emit("update-property-value", { url: url || "" });
25
+ selectYoutubeVideo(modal, props.value, (url, aspectRatio) => {
26
+ const properties = { url: url || "" };
27
+ if (aspectRatio) {
28
+ properties.aspectRatio = aspectRatio;
29
+ }
30
+ emit("update-property-value", properties);
27
31
  });
28
32
  };
29
33
  return (_ctx, _cache) => {
@@ -1,6 +1,6 @@
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-gTlPRaWE.js";
3
+ import { w as widgetPartDefinitions } from "./index-SyHEuk0H.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"];
@@ -0,0 +1,117 @@
1
+ import { defineComponent, ref, onMounted, openBlock, createBlock, unref, withCtx, createElementVNode, withDirectives, createVNode, normalizeStyle, createCommentVNode } from "vue";
2
+ import { useModalHandle, BSModalFrame, vT, BSTextInput } from "@g1cloud/bluesea";
3
+ import YouTube from "vue3-youtube";
4
+ import { _ as _export_sfc } from "./index-SyHEuk0H.js";
5
+ const _hoisted_1 = { class: "bs-layout-vertical flex-grow-1 h-full" };
6
+ const _hoisted_2 = { class: "pt-8" };
7
+ const _hoisted_3 = { class: "bs-layout-horizontal justify-content-center" };
8
+ const _sfc_main = /* @__PURE__ */ defineComponent({
9
+ __name: "PbYoutubeModal",
10
+ props: {
11
+ url: {}
12
+ },
13
+ emits: ["selectUrl"],
14
+ setup(__props, { emit: __emit }) {
15
+ const props = __props;
16
+ const emit = __emit;
17
+ const modalHandle = useModalHandle();
18
+ const previewContainer = ref();
19
+ const url = ref(props.url);
20
+ const aspectRatio = ref();
21
+ const previewWidth = ref(480);
22
+ const previewHeight = ref(360);
23
+ const fetchAspectRatio = async (videoUrl) => {
24
+ try {
25
+ const oembedUrl = `https://www.youtube.com/oembed?url=${encodeURIComponent(videoUrl)}&format=json`;
26
+ const response = await fetch(oembedUrl);
27
+ if (!response.ok) return;
28
+ const data = await response.json();
29
+ if (data.width && data.height) {
30
+ aspectRatio.value = `${data.width}/${data.height}`;
31
+ previewHeight.value = Math.round(previewWidth.value * data.height / data.width);
32
+ }
33
+ } catch {
34
+ }
35
+ };
36
+ const updateUrl = (value) => {
37
+ url.value = value;
38
+ aspectRatio.value = void 0;
39
+ if (value) {
40
+ fetchAspectRatio(value);
41
+ }
42
+ };
43
+ if (props.url) {
44
+ fetchAspectRatio(props.url);
45
+ }
46
+ const measureContainer = () => {
47
+ var _a;
48
+ const w = (_a = previewContainer.value) == null ? void 0 : _a.clientWidth;
49
+ if (w && w > 0) {
50
+ previewWidth.value = w;
51
+ previewHeight.value = Math.round(w * 9 / 16);
52
+ return true;
53
+ }
54
+ return false;
55
+ };
56
+ onMounted(() => {
57
+ if (!measureContainer()) {
58
+ requestAnimationFrame(() => measureContainer());
59
+ }
60
+ });
61
+ const ok = () => {
62
+ emit("selectUrl", url.value, aspectRatio.value);
63
+ modalHandle.close();
64
+ };
65
+ return (_ctx, _cache) => {
66
+ return openBlock(), createBlock(unref(BSModalFrame), {
67
+ title: { key: "pb.modal.youtube.title" },
68
+ class: "pb-youtube-modal"
69
+ }, {
70
+ default: withCtx(() => [
71
+ createElementVNode("div", _hoisted_1, [
72
+ withDirectives(createElementVNode("div", null, null, 512), [
73
+ [unref(vT), { key: "pb.modal.youtube.url" }]
74
+ ]),
75
+ createVNode(unref(BSTextInput), {
76
+ "model-value": url.value,
77
+ width: "100%",
78
+ "onUpdate:modelValue": updateUrl
79
+ }, null, 8, ["model-value"]),
80
+ withDirectives(createElementVNode("div", _hoisted_2, null, 512), [
81
+ [unref(vT), { key: "pb.modal.youtube.preview" }]
82
+ ]),
83
+ createElementVNode("div", {
84
+ ref_key: "previewContainer",
85
+ ref: previewContainer,
86
+ class: "preview-container border-w-1 border border-gray",
87
+ style: normalizeStyle({ minHeight: url.value ? void 0 : "300px", overflow: "hidden" })
88
+ }, [
89
+ url.value ? (openBlock(), createBlock(unref(YouTube), {
90
+ key: 0,
91
+ ref: "youtube",
92
+ src: url.value,
93
+ width: previewWidth.value,
94
+ height: previewHeight.value
95
+ }, null, 8, ["src", "width", "height"])) : createCommentVNode("", true)
96
+ ], 4)
97
+ ])
98
+ ]),
99
+ buttons: withCtx(() => [
100
+ createElementVNode("div", _hoisted_3, [
101
+ withDirectives(createElementVNode("button", {
102
+ class: "mr-4",
103
+ onClick: ok
104
+ }, null, 512), [
105
+ [unref(vT), { key: "pb.button.ok" }]
106
+ ])
107
+ ])
108
+ ]),
109
+ _: 1
110
+ });
111
+ };
112
+ }
113
+ });
114
+ const PbYoutubeModal = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-c0ba6980"]]);
115
+ export {
116
+ PbYoutubeModal as default
117
+ };
@@ -1,11 +1,11 @@
1
1
  declare const _default: import('vue').DefineComponent<import('vue').ExtractPropTypes<__VLS_TypePropsToRuntimeProps<{
2
2
  url?: string | undefined;
3
3
  }>>, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
4
- selectUrl: (url: string | undefined) => void;
4
+ selectUrl: (url: string | undefined, aspectRatio?: string | undefined) => void;
5
5
  }, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<__VLS_TypePropsToRuntimeProps<{
6
6
  url?: string | undefined;
7
7
  }>>> & Readonly<{
8
- onSelectUrl?: ((url: string | undefined) => any) | undefined;
8
+ onSelectUrl?: ((url: string | undefined, aspectRatio?: string | undefined) => any) | undefined;
9
9
  }>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
10
10
  export default _default;
11
11
  type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
@@ -1,7 +1,7 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
- import { ref, defineComponent, computed, openBlock, createElementBlock, Fragment, createBlock as createBlock$1, resolveDynamicComponent, withCtx, createElementVNode, normalizeStyle, createCommentVNode, toDisplayString, watch, onMounted, onBeforeUnmount, unref, provide, inject, renderList, normalizeProps, mergeProps, normalizeClass, withDirectives, vShow, reactive, defineAsyncComponent, createVNode, resolveComponent, vModelText, resolveDirective, withModifiers, renderSlot, guardReactiveProps, createTextVNode, markRaw, toHandlers, Teleport } from "vue";
4
+ import { ref, defineComponent, computed, openBlock, createElementBlock, Fragment, createBlock as createBlock$1, resolveDynamicComponent, withCtx, createElementVNode, normalizeStyle, createCommentVNode, toDisplayString, watch, onMounted, onBeforeUnmount, provide, inject, unref, renderList, normalizeProps, mergeProps, normalizeClass, withDirectives, vShow, reactive, defineAsyncComponent, createVNode, resolveComponent, vModelText, resolveDirective, withModifiers, renderSlot, guardReactiveProps, createTextVNode, markRaw, toHandlers, Teleport } from "vue";
5
5
  import { notNull, vT, BSTextInput, vClickOutside, useModal, BSButton, BSMultiLangTextInput, BSSelect, showNotification, BSTree, useContextMenu, i18n, BSHorizontalLayoutResizer } from "@g1cloud/bluesea";
6
6
  import YouTube from "vue3-youtube";
7
7
  const create$5 = () => /* @__PURE__ */ new Map();
@@ -7568,16 +7568,36 @@ const _sfc_main$4$1 = /* @__PURE__ */ defineComponent({
7568
7568
  },
7569
7569
  setup(__props) {
7570
7570
  const props = __props;
7571
- const style = computed(() => {
7571
+ const container = ref();
7572
+ const containerWidth = ref(640);
7573
+ const aspectRatio = computed(() => {
7572
7574
  var _a;
7573
- return {
7574
- aspectRatio: (_a = props.part.properties) == null ? void 0 : _a.aspectRatio
7575
- };
7575
+ const raw = (_a = props.part.properties) == null ? void 0 : _a.aspectRatio;
7576
+ if (!raw) return 16 / 9;
7577
+ const parts = raw.split("/");
7578
+ if (parts.length === 2) {
7579
+ const w = Number(parts[0]);
7580
+ const h = Number(parts[1]);
7581
+ if (w > 0 && h > 0) return w / h;
7582
+ }
7583
+ return 16 / 9;
7576
7584
  });
7585
+ const playerHeight = computed(() => Math.round(containerWidth.value / aspectRatio.value));
7586
+ const updateWidth = () => {
7587
+ if (container.value) {
7588
+ containerWidth.value = container.value.clientWidth;
7589
+ }
7590
+ };
7591
+ let resizeObserver;
7577
7592
  const onReady = () => {
7578
7593
  };
7579
7594
  const isYTReady = ref(false);
7580
7595
  onMounted(() => {
7596
+ if (container.value) {
7597
+ updateWidth();
7598
+ resizeObserver = new ResizeObserver(updateWidth);
7599
+ resizeObserver.observe(container.value);
7600
+ }
7581
7601
  const interval = setInterval(() => {
7582
7602
  try {
7583
7603
  if (window && window.YT && window.YT.Player) {
@@ -7588,6 +7608,9 @@ const _sfc_main$4$1 = /* @__PURE__ */ defineComponent({
7588
7608
  }
7589
7609
  }, 500);
7590
7610
  });
7611
+ onBeforeUnmount(() => {
7612
+ resizeObserver == null ? void 0 : resizeObserver.disconnect();
7613
+ });
7591
7614
  return (_ctx, _cache) => {
7592
7615
  var _a, _b;
7593
7616
  return openBlock(), createElementBlock(Fragment, null, [
@@ -7596,25 +7619,36 @@ const _sfc_main$4$1 = /* @__PURE__ */ defineComponent({
7596
7619
  class: "optanon-category-C0004",
7597
7620
  src: "https://www.youtube.com/iframe_api"
7598
7621
  })),
7599
- ((_a = _ctx.part.properties) == null ? void 0 : _a.url) ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
7622
+ ((_a = _ctx.part.properties) == null ? void 0 : _a.url) ? (openBlock(), createElementBlock("div", {
7623
+ key: 0,
7624
+ ref_key: "container",
7625
+ ref: container,
7626
+ class: "youtube-container"
7627
+ }, [
7600
7628
  isYTReady.value ? (openBlock(), createBlock$1(unref(YouTube), {
7601
7629
  key: 0,
7602
7630
  ref: "youtube",
7603
7631
  host: "https://www.youtube-nocookie.com",
7604
7632
  src: ((_b = _ctx.part.properties) == null ? void 0 : _b.url) || "",
7605
- style: normalizeStyle(style.value),
7606
- class: "youtube",
7607
- height: "100%",
7608
- width: "100%",
7633
+ width: containerWidth.value,
7634
+ height: playerHeight.value,
7609
7635
  onReady
7610
- }, null, 8, ["src", "style"])) : createCommentVNode("", true)
7611
- ], 64)) : _ctx.placeholder ? (openBlock(), createElementBlock("div", _hoisted_1$3$1, _cache[0] || (_cache[0] = [
7636
+ }, null, 8, ["src", "width", "height"])) : createCommentVNode("", true)
7637
+ ], 512)) : _ctx.placeholder ? (openBlock(), createElementBlock("div", _hoisted_1$3$1, _cache[0] || (_cache[0] = [
7612
7638
  createElementVNode("span", { class: "font-icon" }, "live_tv", -1)
7613
7639
  ]))) : createCommentVNode("", true)
7614
7640
  ], 64);
7615
7641
  };
7616
7642
  }
7617
7643
  });
7644
+ const _export_sfc$1 = (sfc, props) => {
7645
+ const target = sfc.__vccOpts || sfc;
7646
+ for (const [key, val] of props) {
7647
+ target[key] = val;
7648
+ }
7649
+ return target;
7650
+ };
7651
+ const PbYoutubeWidget = /* @__PURE__ */ _export_sfc$1(_sfc_main$4$1, [["__scopeId", "data-v-675477df"]]);
7618
7652
  const defaultPartDefinitions = {
7619
7653
  "Section": {
7620
7654
  partType: "Section",
@@ -7656,7 +7690,7 @@ const defaultPartDefinitions = {
7656
7690
  partType: "Widget",
7657
7691
  partName: "YoutubeWidget",
7658
7692
  className: "pb-youtube-widget",
7659
- creator: () => _sfc_main$4$1
7693
+ creator: () => PbYoutubeWidget
7660
7694
  }
7661
7695
  /*
7662
7696
  * BSP에서 사용안함
@@ -8594,16 +8628,16 @@ class PartManager {
8594
8628
  const defaultPartPropertyEditors = () => {
8595
8629
  return {
8596
8630
  "readonly-text": () => defineAsyncComponent(() => import("./PbPropertyEditorReadonlyText-BJ5qx69O.js")),
8597
- "text": () => defineAsyncComponent(() => import("./PbPropertyEditorText-C7Tr7KGc.js")),
8631
+ "text": () => defineAsyncComponent(() => import("./PbPropertyEditorText-mWOJ1KrX.js")),
8598
8632
  "number": () => defineAsyncComponent(() => import("./PbPropertyEditorNumber-B76ArSb5.js")),
8599
8633
  "boolean": () => defineAsyncComponent(() => import("./PbPropertyEditorBoolean-c5CNiTpt.js")),
8600
- "multiline-text": () => defineAsyncComponent(() => import("./PbPropertyEditorMultilineText-gDifsouH.js")),
8634
+ "multiline-text": () => defineAsyncComponent(() => import("./PbPropertyEditorMultilineText-Bp2vUVha.js")),
8601
8635
  "select": () => defineAsyncComponent(() => import("./PbPropertyEditorSelect-B5sfulvx.js")),
8602
- "css-length": () => defineAsyncComponent(() => import("./PbPropertyEditorCssLength-BimevQPh.js")),
8603
- "color": () => defineAsyncComponent(() => import("./PbPropertyEditorColor-CwgsFX20.js")),
8604
- "image": () => defineAsyncComponent(() => import("./PbPropertyEditorImage-Bn9LMbEK.js")),
8605
- "html": () => defineAsyncComponent(() => import("./PbPropertyEditorHtml-Dq5TqAEK.js")),
8606
- "youtube": () => defineAsyncComponent(() => import("./PbPropertyEditorYoutube-Ci8_jXBk.js"))
8636
+ "css-length": () => defineAsyncComponent(() => import("./PbPropertyEditorCssLength-s--C0dHZ.js")),
8637
+ "color": () => defineAsyncComponent(() => import("./PbPropertyEditorColor-BsPFj_3N.js")),
8638
+ "image": () => defineAsyncComponent(() => import("./PbPropertyEditorImage-DbbK_0WV.js")),
8639
+ "html": () => defineAsyncComponent(() => import("./PbPropertyEditorHtml-WoyBfORQ.js")),
8640
+ "youtube": () => defineAsyncComponent(() => import("./PbPropertyEditorYoutube-BCiZmiWV.js"))
8607
8641
  };
8608
8642
  };
8609
8643
  const getPropertyValueOfParts = (parts, propertyName) => {
@@ -8623,7 +8657,7 @@ const isCursorInElement = (event, element) => {
8623
8657
  };
8624
8658
  const selectYoutubeVideo = (modal, url, callback) => {
8625
8659
  modal.openModal({
8626
- component: defineAsyncComponent(() => import("./PbYoutubeModal-CU8sClMD.js")),
8660
+ component: defineAsyncComponent(() => import("./PbYoutubeModal-BaL5gsKK.js")),
8627
8661
  style: {
8628
8662
  minWidth: "500px",
8629
8663
  minHeight: "400px"
@@ -8632,9 +8666,9 @@ const selectYoutubeVideo = (modal, url, callback) => {
8632
8666
  url
8633
8667
  },
8634
8668
  on: {
8635
- selectUrl: (url2) => {
8669
+ selectUrl: (url2, aspectRatio) => {
8636
8670
  if (callback) {
8637
- callback(url2);
8671
+ callback(url2, aspectRatio);
8638
8672
  }
8639
8673
  }
8640
8674
  }
@@ -13281,17 +13315,16 @@ const widgets = [
13281
13315
  propertyName: "aspectRatio",
13282
13316
  caption: "pb.prop.aspectRatio",
13283
13317
  propertyType: "text",
13284
- params: ""
13318
+ params: "",
13319
+ readonly: true
13285
13320
  }
13286
13321
  ]
13287
13322
  },
13288
13323
  ...defaultWidgetPropertyGroups()
13289
13324
  ],
13290
- initialProperties: {
13291
- aspectRatio: "16/9"
13292
- },
13325
+ initialProperties: {},
13293
13326
  allowsChild: () => false,
13294
- creator: () => _sfc_main$4$1
13327
+ creator: () => PbYoutubeWidget
13295
13328
  }
13296
13329
  /*
13297
13330
  * BSP에서 사용안함
@@ -13402,7 +13435,7 @@ __publicField(_OpenAddWidgetModalCommand, "COMMAND_ID", "OpenAddWidgetModal");
13402
13435
  let OpenAddWidgetModalCommand = _OpenAddWidgetModalCommand;
13403
13436
  const openWidgetAddModal = (modal, args, callback) => {
13404
13437
  modal.openModal({
13405
- component: defineAsyncComponent(() => import("./PbWidgetAddModal-BdTUeERo.js")),
13438
+ component: defineAsyncComponent(() => import("./PbWidgetAddModal-0p7a4pVO.js")),
13406
13439
  style: {
13407
13440
  width: "80%",
13408
13441
  height: "80%",
@@ -17561,41 +17594,42 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
17561
17594
  }
17562
17595
  });
17563
17596
  export {
17564
- providePageBuilderViewer as A,
17597
+ providePageBuilder as A,
17565
17598
  BLOCK_TYPE$1 as B,
17566
17599
  ChangePropertyCommand as C,
17567
- usePageBuilder as D,
17568
- usePageBuilderViewer as E,
17600
+ providePageBuilderViewer as D,
17601
+ usePageBuilder as E,
17602
+ usePageBuilderViewer as F,
17569
17603
  Model$1 as M,
17570
17604
  PbColorPicker as P,
17571
17605
  ROOT_TYPE$1 as R,
17572
17606
  SECTION_TYPE$1 as S,
17573
17607
  WIDGET_TYPE$1 as W,
17574
- _sfc_main as _,
17575
- PageBuilderEditorEvent as a,
17576
- Block as b,
17577
- PAGE_BUILDER_KEY as c,
17578
- PAGE_TYPE$1 as d,
17579
- Page as e,
17580
- _sfc_main$2$1 as f,
17581
- Part as g,
17582
- _sfc_main$1$1 as h,
17583
- _sfc_main$q as i,
17584
- _sfc_main$6$1 as j,
17585
- _sfc_main$5$1 as k,
17586
- _sfc_main$8$1 as l,
17587
- _sfc_main$7$1 as m,
17588
- _sfc_main$4$1 as n,
17589
- RootPart as o,
17590
- Section as p,
17591
- Widget as q,
17592
- createPageBuilderViewer as r,
17608
+ _export_sfc as _,
17609
+ _sfc_main as a,
17610
+ PageBuilderEditorEvent as b,
17611
+ Block as c,
17612
+ PAGE_BUILDER_KEY as d,
17613
+ PAGE_TYPE$1 as e,
17614
+ Page as f,
17615
+ _sfc_main$2$1 as g,
17616
+ Part as h,
17617
+ _sfc_main$1$1 as i,
17618
+ _sfc_main$q as j,
17619
+ _sfc_main$6$1 as k,
17620
+ _sfc_main$5$1 as l,
17621
+ _sfc_main$8$1 as m,
17622
+ _sfc_main$7$1 as n,
17623
+ PbYoutubeWidget as o,
17624
+ RootPart as p,
17625
+ Section as q,
17626
+ Widget as r,
17593
17627
  selectYoutubeVideo as s,
17594
17628
  toCssLength as t,
17595
17629
  usePageBuilderEditor as u,
17596
- createPartComponent as v,
17630
+ createPageBuilderViewer as v,
17597
17631
  widgetPartDefinitions as w,
17598
- createPartComponents as x,
17599
- getPartClassName as y,
17600
- providePageBuilder as z
17632
+ createPartComponent as x,
17633
+ createPartComponents as y,
17634
+ getPartClassName as z
17601
17635
  };
@@ -4,4 +4,4 @@ import { IPart, MultiLangText } from '@g1cloud/page-builder-viewer';
4
4
  export declare const getPropertyValueOfParts: (parts: IPart[], propertyName: string) => MultiLangText | undefined;
5
5
  export declare const isCursorInElement: (event: MouseEvent, element: Element) => boolean;
6
6
  export declare const extractCommonStylesFromProperties: (properties: Record<string, string>) => Record<string, unknown>;
7
- export declare const selectYoutubeVideo: (modal: BSModal, url?: string, callback?: (url?: string) => void) => void;
7
+ export declare const selectYoutubeVideo: (modal: BSModal, url?: string, callback?: (url?: string, aspectRatio?: string) => void) => void;
@@ -1,34 +1,34 @@
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, v, x, y, z, A, D, E } from "./index-gTlPRaWE.js";
1
+ import { B, c, M, d, e, f, a, b, g, h, i, j, k, l, m, n, o, R, p, S, q, W, r, v, x, y, z, A, D, E, F } from "./index-SyHEuk0H.js";
2
2
  export {
3
3
  B as BLOCK_TYPE,
4
- b as Block,
4
+ c as Block,
5
5
  M as Model,
6
- c as PAGE_BUILDER_KEY,
7
- d as PAGE_TYPE,
8
- e as Page,
9
- _ as PageBuilderEditor,
10
- a as PageBuilderEditorEvent,
11
- f as PageBuilderViewer,
12
- g as Part,
13
- h as PbContainerWidget,
14
- i as PbCustomWidget,
15
- j as PbHtmlWidget,
16
- k as PbIframeWidget,
17
- l as PbMediaWidget,
18
- m as PbTextWidget,
19
- n as PbYoutubeWidget,
6
+ d as PAGE_BUILDER_KEY,
7
+ e as PAGE_TYPE,
8
+ f as Page,
9
+ a as PageBuilderEditor,
10
+ b as PageBuilderEditorEvent,
11
+ g as PageBuilderViewer,
12
+ h as Part,
13
+ i as PbContainerWidget,
14
+ j as PbCustomWidget,
15
+ k as PbHtmlWidget,
16
+ l as PbIframeWidget,
17
+ m as PbMediaWidget,
18
+ n as PbTextWidget,
19
+ o as PbYoutubeWidget,
20
20
  R as ROOT_TYPE,
21
- o as RootPart,
21
+ p as RootPart,
22
22
  S as SECTION_TYPE,
23
- p as Section,
23
+ q as Section,
24
24
  W as WIDGET_TYPE,
25
- q as Widget,
26
- r as createPageBuilderViewer,
27
- v as createPartComponent,
28
- x as createPartComponents,
29
- y as getPartClassName,
30
- z as providePageBuilder,
31
- A as providePageBuilderViewer,
32
- D as usePageBuilder,
33
- E as usePageBuilderViewer
25
+ r as Widget,
26
+ v as createPageBuilderViewer,
27
+ x as createPartComponent,
28
+ y as createPartComponents,
29
+ z as getPartClassName,
30
+ A as providePageBuilder,
31
+ D as providePageBuilderViewer,
32
+ E as usePageBuilder,
33
+ F as usePageBuilderViewer
34
34
  };
@@ -7135,7 +7135,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7135
7135
  const _hoisted_1$7$1 = ["href", "target"];
7136
7136
  const _hoisted_2$3$1 = ["alt", "src"];
7137
7137
  const _hoisted_3$l = ["alt", "src"];
7138
- const _hoisted_4$f = ["alt", "src"];
7138
+ const _hoisted_4$e = ["alt", "src"];
7139
7139
  const _hoisted_5$b = ["alt", "src"];
7140
7140
  const _hoisted_6$a = ["poster"];
7141
7141
  const _hoisted_7$9 = ["src"];
@@ -7231,7 +7231,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7231
7231
  src: ((_a2 = _ctx.part.properties) == null ? void 0 : _a2.media).fileUrl,
7232
7232
  style: vue.normalizeStyle(style.value),
7233
7233
  class: "image"
7234
- }, null, 12, _hoisted_4$f)
7234
+ }, null, 12, _hoisted_4$e)
7235
7235
  ];
7236
7236
  }),
7237
7237
  _: 1
@@ -7569,16 +7569,36 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7569
7569
  },
7570
7570
  setup(__props) {
7571
7571
  const props = __props;
7572
- const style = vue.computed(() => {
7572
+ const container = vue.ref();
7573
+ const containerWidth = vue.ref(640);
7574
+ const aspectRatio = vue.computed(() => {
7573
7575
  var _a;
7574
- return {
7575
- aspectRatio: (_a = props.part.properties) == null ? void 0 : _a.aspectRatio
7576
- };
7576
+ const raw = (_a = props.part.properties) == null ? void 0 : _a.aspectRatio;
7577
+ if (!raw) return 16 / 9;
7578
+ const parts = raw.split("/");
7579
+ if (parts.length === 2) {
7580
+ const w = Number(parts[0]);
7581
+ const h = Number(parts[1]);
7582
+ if (w > 0 && h > 0) return w / h;
7583
+ }
7584
+ return 16 / 9;
7577
7585
  });
7586
+ const playerHeight = vue.computed(() => Math.round(containerWidth.value / aspectRatio.value));
7587
+ const updateWidth = () => {
7588
+ if (container.value) {
7589
+ containerWidth.value = container.value.clientWidth;
7590
+ }
7591
+ };
7592
+ let resizeObserver;
7578
7593
  const onReady = () => {
7579
7594
  };
7580
7595
  const isYTReady = vue.ref(false);
7581
7596
  vue.onMounted(() => {
7597
+ if (container.value) {
7598
+ updateWidth();
7599
+ resizeObserver = new ResizeObserver(updateWidth);
7600
+ resizeObserver.observe(container.value);
7601
+ }
7582
7602
  const interval = setInterval(() => {
7583
7603
  try {
7584
7604
  if (window && window.YT && window.YT.Player) {
@@ -7589,6 +7609,9 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7589
7609
  }
7590
7610
  }, 500);
7591
7611
  });
7612
+ vue.onBeforeUnmount(() => {
7613
+ resizeObserver == null ? void 0 : resizeObserver.disconnect();
7614
+ });
7592
7615
  return (_ctx, _cache) => {
7593
7616
  var _a, _b;
7594
7617
  return vue.openBlock(), vue.createElementBlock(vue.Fragment, null, [
@@ -7597,25 +7620,36 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7597
7620
  class: "optanon-category-C0004",
7598
7621
  src: "https://www.youtube.com/iframe_api"
7599
7622
  })),
7600
- ((_a = _ctx.part.properties) == null ? void 0 : _a.url) ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 0 }, [
7623
+ ((_a = _ctx.part.properties) == null ? void 0 : _a.url) ? (vue.openBlock(), vue.createElementBlock("div", {
7624
+ key: 0,
7625
+ ref_key: "container",
7626
+ ref: container,
7627
+ class: "youtube-container"
7628
+ }, [
7601
7629
  isYTReady.value ? (vue.openBlock(), vue.createBlock(vue.unref(YouTube), {
7602
7630
  key: 0,
7603
7631
  ref: "youtube",
7604
7632
  host: "https://www.youtube-nocookie.com",
7605
7633
  src: ((_b = _ctx.part.properties) == null ? void 0 : _b.url) || "",
7606
- style: vue.normalizeStyle(style.value),
7607
- class: "youtube",
7608
- height: "100%",
7609
- width: "100%",
7634
+ width: containerWidth.value,
7635
+ height: playerHeight.value,
7610
7636
  onReady
7611
- }, null, 8, ["src", "style"])) : vue.createCommentVNode("", true)
7612
- ], 64)) : _ctx.placeholder ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$3$1, _cache[0] || (_cache[0] = [
7637
+ }, null, 8, ["src", "width", "height"])) : vue.createCommentVNode("", true)
7638
+ ], 512)) : _ctx.placeholder ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$3$1, _cache[0] || (_cache[0] = [
7613
7639
  vue.createElementVNode("span", { class: "font-icon" }, "live_tv", -1)
7614
7640
  ]))) : vue.createCommentVNode("", true)
7615
7641
  ], 64);
7616
7642
  };
7617
7643
  }
7618
7644
  });
7645
+ const _export_sfc$1 = (sfc, props) => {
7646
+ const target = sfc.__vccOpts || sfc;
7647
+ for (const [key, val] of props) {
7648
+ target[key] = val;
7649
+ }
7650
+ return target;
7651
+ };
7652
+ const PbYoutubeWidget = /* @__PURE__ */ _export_sfc$1(_sfc_main$4$1, [["__scopeId", "data-v-675477df"]]);
7619
7653
  const defaultPartDefinitions = {
7620
7654
  "Section": {
7621
7655
  partType: "Section",
@@ -7657,7 +7691,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7657
7691
  partType: "Widget",
7658
7692
  partName: "YoutubeWidget",
7659
7693
  className: "pb-youtube-widget",
7660
- creator: () => _sfc_main$4$1
7694
+ creator: () => PbYoutubeWidget
7661
7695
  }
7662
7696
  /*
7663
7697
  * BSP에서 사용안함
@@ -8624,7 +8658,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
8624
8658
  };
8625
8659
  const selectYoutubeVideo = (modal, url, callback) => {
8626
8660
  modal.openModal({
8627
- component: vue.defineAsyncComponent(() => Promise.resolve().then(() => PbYoutubeModal)),
8661
+ component: vue.defineAsyncComponent(() => Promise.resolve().then(() => PbYoutubeModal$1)),
8628
8662
  style: {
8629
8663
  minWidth: "500px",
8630
8664
  minHeight: "400px"
@@ -8633,9 +8667,9 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
8633
8667
  url
8634
8668
  },
8635
8669
  on: {
8636
- selectUrl: (url2) => {
8670
+ selectUrl: (url2, aspectRatio) => {
8637
8671
  if (callback) {
8638
- callback(url2);
8672
+ callback(url2, aspectRatio);
8639
8673
  }
8640
8674
  }
8641
8675
  }
@@ -9826,7 +9860,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
9826
9860
  const _hoisted_1$D = { class: "group-editor group-editor-position" };
9827
9861
  const _hoisted_2$u = { class: "flex-align-center" };
9828
9862
  const _hoisted_3$k = { class: "title" };
9829
- const _hoisted_4$e = { class: "flex-grow-1" };
9863
+ const _hoisted_4$d = { class: "flex-grow-1" };
9830
9864
  const _hoisted_5$a = { class: "bg-gray-100 py-5 rounded-8" };
9831
9865
  const _hoisted_6$9 = { class: "text-center" };
9832
9866
  const _hoisted_7$8 = { class: "bs-layout-horizontal justify-content-center align-items-center" };
@@ -9862,7 +9896,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
9862
9896
  [vue.unref(bluesea.vT), { key: "pb.prop.position" }]
9863
9897
  ])
9864
9898
  ]),
9865
- vue.createElementVNode("div", _hoisted_4$e, [
9899
+ vue.createElementVNode("div", _hoisted_4$d, [
9866
9900
  vue.createElementVNode("div", _hoisted_5$a, [
9867
9901
  vue.createElementVNode("div", _hoisted_6$9, [
9868
9902
  vue.createVNode(vue.unref(bluesea.BSTextInput), {
@@ -9914,7 +9948,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
9914
9948
  const _hoisted_1$C = { class: "group-editor group-editor-size" };
9915
9949
  const _hoisted_2$t = { class: "flex-align-center" };
9916
9950
  const _hoisted_3$j = { class: "title" };
9917
- const _hoisted_4$d = { class: "flex-grow-1 bs-layout-horizontal" };
9951
+ const _hoisted_4$c = { class: "flex-grow-1 bs-layout-horizontal" };
9918
9952
  const _hoisted_5$9 = { class: "flex-align-center mt-12" };
9919
9953
  const _hoisted_6$8 = { class: "title" };
9920
9954
  const _hoisted_7$7 = { class: "flex-grow-1 bs-layout-horizontal" };
@@ -9956,7 +9990,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
9956
9990
  [vue.unref(bluesea.vT), { key: "pb.prop.size" }]
9957
9991
  ])
9958
9992
  ]),
9959
- vue.createElementVNode("div", _hoisted_4$d, [
9993
+ vue.createElementVNode("div", _hoisted_4$c, [
9960
9994
  vue.createVNode(vue.unref(bluesea.BSTextInput), {
9961
9995
  "model-value": width.value,
9962
9996
  class: "flex-grow-1 mr-2",
@@ -10182,7 +10216,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
10182
10216
  -1
10183
10217
  /* HOISTED */
10184
10218
  );
10185
- const _hoisted_4$c = [
10219
+ const _hoisted_4$b = [
10186
10220
  _hoisted_3$i
10187
10221
  ];
10188
10222
  function render$4(_ctx, _cache, $props, $setup, $data, $options) {
@@ -10217,7 +10251,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
10217
10251
  class: "vc-alpha-pointer",
10218
10252
  style: vue.normalizeStyle({ left: `${$options.colors.a * 100}%` })
10219
10253
  },
10220
- _hoisted_4$c,
10254
+ _hoisted_4$b,
10221
10255
  4
10222
10256
  /* STYLE */
10223
10257
  )
@@ -11294,7 +11328,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
11294
11328
  const _hoisted_1$A = { class: "vc-editable-input" };
11295
11329
  const _hoisted_2$r = ["aria-labelledby"];
11296
11330
  const _hoisted_3$h = ["id", "for"];
11297
- const _hoisted_4$b = { class: "vc-input__desc" };
11331
+ const _hoisted_4$a = { class: "vc-input__desc" };
11298
11332
  function render$3(_ctx, _cache, $props, $setup, $data, $options) {
11299
11333
  return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$A, [
11300
11334
  vue.withDirectives(vue.createElementVNode("input", {
@@ -11314,7 +11348,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
11314
11348
  }, vue.toDisplayString($options.labelSpanText), 9, _hoisted_3$h),
11315
11349
  vue.createElementVNode(
11316
11350
  "span",
11317
- _hoisted_4$b,
11351
+ _hoisted_4$a,
11318
11352
  vue.toDisplayString($props.desc),
11319
11353
  1
11320
11354
  /* TEXT */
@@ -11412,7 +11446,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
11412
11446
  -1
11413
11447
  /* HOISTED */
11414
11448
  );
11415
- const _hoisted_4$a = [
11449
+ const _hoisted_4$9 = [
11416
11450
  _hoisted_3$g
11417
11451
  ];
11418
11452
  function render$2(_ctx, _cache, $props, $setup, $data, $options) {
@@ -11435,7 +11469,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
11435
11469
  class: "vc-saturation-pointer",
11436
11470
  style: vue.normalizeStyle({ top: $options.pointerTop, left: $options.pointerLeft })
11437
11471
  },
11438
- _hoisted_4$a,
11472
+ _hoisted_4$9,
11439
11473
  4
11440
11474
  /* STYLE */
11441
11475
  )
@@ -11715,7 +11749,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
11715
11749
  const _hoisted_1$x = { class: "vc-sketch-saturation-wrap" };
11716
11750
  const _hoisted_2$o = { class: "vc-sketch-controls" };
11717
11751
  const _hoisted_3$e = { class: "vc-sketch-sliders" };
11718
- const _hoisted_4$9 = { class: "vc-sketch-hue-wrap" };
11752
+ const _hoisted_4$8 = { class: "vc-sketch-hue-wrap" };
11719
11753
  const _hoisted_5$8 = {
11720
11754
  key: 0,
11721
11755
  class: "vc-sketch-alpha-wrap"
@@ -11763,7 +11797,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
11763
11797
  ]),
11764
11798
  vue.createElementVNode("div", _hoisted_2$o, [
11765
11799
  vue.createElementVNode("div", _hoisted_3$e, [
11766
- vue.createElementVNode("div", _hoisted_4$9, [
11800
+ vue.createElementVNode("div", _hoisted_4$8, [
11767
11801
  vue.createVNode(_component_Hue, {
11768
11802
  value: _ctx.colors,
11769
11803
  onChange: $options.childChange
@@ -11968,7 +12002,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
11968
12002
  const _hoisted_1$v = { class: "group-editor group-editor-background" };
11969
12003
  const _hoisted_2$m = { class: "flex-align-center" };
11970
12004
  const _hoisted_3$d = { class: "title" };
11971
- const _hoisted_4$8 = { class: "color" };
12005
+ const _hoisted_4$7 = { class: "color" };
11972
12006
  const _hoisted_5$7 = { class: "image mt-4" };
11973
12007
  const _hoisted_6$6 = {
11974
12008
  key: 0,
@@ -12018,7 +12052,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
12018
12052
  ])
12019
12053
  ]),
12020
12054
  vue.createElementVNode("div", null, [
12021
- vue.createElementVNode("div", _hoisted_4$8, [
12055
+ vue.createElementVNode("div", _hoisted_4$7, [
12022
12056
  vue.withDirectives(vue.createElementVNode("label", null, null, 512), [
12023
12057
  [vue.unref(bluesea.vT), { key: "pb.prop.color" }]
12024
12058
  ]),
@@ -12088,7 +12122,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
12088
12122
  const _hoisted_1$u = { class: "group-editor group-editor-border" };
12089
12123
  const _hoisted_2$l = { class: "flex-align-center" };
12090
12124
  const _hoisted_3$c = { class: "title" };
12091
- const _hoisted_4$7 = { class: "" };
12125
+ const _hoisted_4$6 = { class: "" };
12092
12126
  const _hoisted_5$6 = { class: "sub-title" };
12093
12127
  const _hoisted_6$5 = { class: "color" };
12094
12128
  const _hoisted_7$5 = { class: "mt-8" };
@@ -12149,7 +12183,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
12149
12183
  [vue.unref(bluesea.vT), { key: "pb.prop.border" }]
12150
12184
  ])
12151
12185
  ]),
12152
- vue.createElementVNode("div", _hoisted_4$7, [
12186
+ vue.createElementVNode("div", _hoisted_4$6, [
12153
12187
  vue.createElementVNode("div", _hoisted_5$6, [
12154
12188
  vue.withDirectives(vue.createElementVNode("label", null, null, 512), [
12155
12189
  [vue.unref(bluesea.vT), { key: "pb.prop.borderColor" }]
@@ -12275,7 +12309,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
12275
12309
  const _hoisted_1$t = { class: "group-editor group-editor-margin" };
12276
12310
  const _hoisted_2$k = { class: "flex-align-center" };
12277
12311
  const _hoisted_3$b = { class: "title" };
12278
- const _hoisted_4$6 = { class: "flex-grow-1" };
12312
+ const _hoisted_4$5 = { class: "flex-grow-1" };
12279
12313
  const _hoisted_5$5 = { class: "bg-gray-100 py-5 rounded-8" };
12280
12314
  const _hoisted_6$4 = { class: "text-center" };
12281
12315
  const _hoisted_7$4 = { class: "bs-layout-horizontal justify-content-center align-items-center" };
@@ -12311,7 +12345,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
12311
12345
  [vue.unref(bluesea.vT), { key: "pb.prop.margin" }]
12312
12346
  ])
12313
12347
  ]),
12314
- vue.createElementVNode("div", _hoisted_4$6, [
12348
+ vue.createElementVNode("div", _hoisted_4$5, [
12315
12349
  vue.createElementVNode("div", _hoisted_5$5, [
12316
12350
  vue.createElementVNode("div", _hoisted_6$4, [
12317
12351
  vue.createVNode(vue.unref(bluesea.BSTextInput), {
@@ -12363,7 +12397,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
12363
12397
  const _hoisted_1$s = { class: "group-editor group-editor-padding" };
12364
12398
  const _hoisted_2$j = { class: "flex-align-center" };
12365
12399
  const _hoisted_3$a = { class: "title" };
12366
- const _hoisted_4$5 = { class: "flex-grow-1" };
12400
+ const _hoisted_4$4 = { class: "flex-grow-1" };
12367
12401
  const _hoisted_5$4 = { class: "bg-gray-100 py-5 rounded-8" };
12368
12402
  const _hoisted_6$3 = { class: "text-center" };
12369
12403
  const _hoisted_7$3 = { class: "bs-layout-horizontal justify-content-center align-items-center" };
@@ -12399,7 +12433,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
12399
12433
  [vue.unref(bluesea.vT), { key: "pb.prop.padding" }]
12400
12434
  ])
12401
12435
  ]),
12402
- vue.createElementVNode("div", _hoisted_4$5, [
12436
+ vue.createElementVNode("div", _hoisted_4$4, [
12403
12437
  vue.createElementVNode("div", _hoisted_5$4, [
12404
12438
  vue.createElementVNode("div", _hoisted_6$3, [
12405
12439
  vue.createVNode(vue.unref(bluesea.BSTextInput), {
@@ -12834,7 +12868,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
12834
12868
  key: 0,
12835
12869
  class: "title mt-12"
12836
12870
  };
12837
- const _hoisted_4$4 = { class: "url mt-8" };
12871
+ const _hoisted_4$3 = { class: "url mt-8" };
12838
12872
  const _hoisted_5$3 = { class: "title mt-12" };
12839
12873
  const _hoisted_6$2 = { class: "title mt-12" };
12840
12874
  const _hoisted_7$2 = { class: "title mt-12" };
@@ -12926,7 +12960,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
12926
12960
  ]),
12927
12961
  ((_a = media.value) == null ? void 0 : _a.fileUrl) ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_3$9, [
12928
12962
  _cache[4] || (_cache[4] = vue.createElementVNode("label", null, "URL", -1)),
12929
- vue.createElementVNode("div", _hoisted_4$4, [
12963
+ vue.createElementVNode("div", _hoisted_4$3, [
12930
12964
  vue.createTextVNode(vue.toDisplayString((_b = media.value) == null ? void 0 : _b.fileUrl) + " ", 1),
12931
12965
  vue.withDirectives(vue.createVNode(vue.unref(bluesea.BSButton), {
12932
12966
  class: "border-0 mb-2 px-1",
@@ -13282,17 +13316,16 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
13282
13316
  propertyName: "aspectRatio",
13283
13317
  caption: "pb.prop.aspectRatio",
13284
13318
  propertyType: "text",
13285
- params: ""
13319
+ params: "",
13320
+ readonly: true
13286
13321
  }
13287
13322
  ]
13288
13323
  },
13289
13324
  ...defaultWidgetPropertyGroups()
13290
13325
  ],
13291
- initialProperties: {
13292
- aspectRatio: "16/9"
13293
- },
13326
+ initialProperties: {},
13294
13327
  allowsChild: () => false,
13295
- creator: () => _sfc_main$4$1
13328
+ creator: () => PbYoutubeWidget
13296
13329
  }
13297
13330
  /*
13298
13331
  * BSP에서 사용안함
@@ -17928,7 +17961,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
17928
17961
  key: 0,
17929
17962
  class: "title mt-12"
17930
17963
  };
17931
- const _hoisted_4$3 = { class: "mt-8" };
17964
+ const _hoisted_4$2 = { class: "mt-8" };
17932
17965
  const _hoisted_5$2 = { class: "title mt-12" };
17933
17966
  const _sfc_main$6 = /* @__PURE__ */ vue.defineComponent({
17934
17967
  __name: "PbPropertyEditorImage",
@@ -17991,7 +18024,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
17991
18024
  ]),
17992
18025
  ((_a = media.value) == null ? void 0 : _a.fileUrl) ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_3$5, [
17993
18026
  _cache[0] || (_cache[0] = vue.createElementVNode("label", null, "URL", -1)),
17994
- vue.createElementVNode("div", _hoisted_4$3, [
18027
+ vue.createElementVNode("div", _hoisted_4$2, [
17995
18028
  vue.createTextVNode(vue.toDisplayString((_b = media.value) == null ? void 0 : _b.fileUrl) + " ", 1),
17996
18029
  vue.withDirectives(vue.createVNode(vue.unref(bluesea.BSButton), {
17997
18030
  class: "border-0 mb-2 px-1",
@@ -18120,11 +18153,15 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
18120
18153
  const modal = bluesea.useModal();
18121
18154
  const emit = __emit;
18122
18155
  const clearVideo = () => {
18123
- emit("update-property-value", { url: "" });
18156
+ emit("update-property-value", { url: "", aspectRatio: "" });
18124
18157
  };
18125
18158
  const selectVideo = () => {
18126
- selectYoutubeVideo(modal, props.value, (url) => {
18127
- emit("update-property-value", { url: url || "" });
18159
+ selectYoutubeVideo(modal, props.value, (url, aspectRatio) => {
18160
+ const properties = { url: url || "" };
18161
+ if (aspectRatio) {
18162
+ properties.aspectRatio = aspectRatio;
18163
+ }
18164
+ emit("update-property-value", properties);
18128
18165
  });
18129
18166
  };
18130
18167
  return (_ctx, _cache) => {
@@ -18164,8 +18201,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
18164
18201
  }, Symbol.toStringTag, { value: "Module" }));
18165
18202
  const _hoisted_1$3 = { class: "bs-layout-vertical flex-grow-1 h-full" };
18166
18203
  const _hoisted_2$3 = { class: "pt-8" };
18167
- const _hoisted_3$3 = { class: "w-480 h-360 border-w-1 border border-gray" };
18168
- const _hoisted_4$2 = { class: "bs-layout-horizontal justify-content-center" };
18204
+ const _hoisted_3$3 = { class: "bs-layout-horizontal justify-content-center" };
18169
18205
  const _sfc_main$3 = /* @__PURE__ */ vue.defineComponent({
18170
18206
  __name: "PbYoutubeModal",
18171
18207
  props: {
@@ -18176,12 +18212,51 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
18176
18212
  const props = __props;
18177
18213
  const emit = __emit;
18178
18214
  const modalHandle = bluesea.useModalHandle();
18215
+ const previewContainer = vue.ref();
18179
18216
  const url = vue.ref(props.url);
18217
+ const aspectRatio = vue.ref();
18218
+ const previewWidth = vue.ref(480);
18219
+ const previewHeight = vue.ref(360);
18220
+ const fetchAspectRatio = async (videoUrl) => {
18221
+ try {
18222
+ const oembedUrl = `https://www.youtube.com/oembed?url=${encodeURIComponent(videoUrl)}&format=json`;
18223
+ const response = await fetch(oembedUrl);
18224
+ if (!response.ok) return;
18225
+ const data = await response.json();
18226
+ if (data.width && data.height) {
18227
+ aspectRatio.value = `${data.width}/${data.height}`;
18228
+ previewHeight.value = Math.round(previewWidth.value * data.height / data.width);
18229
+ }
18230
+ } catch {
18231
+ }
18232
+ };
18180
18233
  const updateUrl = (value) => {
18181
18234
  url.value = value;
18235
+ aspectRatio.value = void 0;
18236
+ if (value) {
18237
+ fetchAspectRatio(value);
18238
+ }
18239
+ };
18240
+ if (props.url) {
18241
+ fetchAspectRatio(props.url);
18242
+ }
18243
+ const measureContainer = () => {
18244
+ var _a;
18245
+ const w = (_a = previewContainer.value) == null ? void 0 : _a.clientWidth;
18246
+ if (w && w > 0) {
18247
+ previewWidth.value = w;
18248
+ previewHeight.value = Math.round(w * 9 / 16);
18249
+ return true;
18250
+ }
18251
+ return false;
18182
18252
  };
18253
+ vue.onMounted(() => {
18254
+ if (!measureContainer()) {
18255
+ requestAnimationFrame(() => measureContainer());
18256
+ }
18257
+ });
18183
18258
  const ok = () => {
18184
- emit("selectUrl", url.value);
18259
+ emit("selectUrl", url.value, aspectRatio.value);
18185
18260
  modalHandle.close();
18186
18261
  };
18187
18262
  return (_ctx, _cache) => {
@@ -18202,20 +18277,24 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
18202
18277
  vue.withDirectives(vue.createElementVNode("div", _hoisted_2$3, null, 512), [
18203
18278
  [vue.unref(bluesea.vT), { key: "pb.modal.youtube.preview" }]
18204
18279
  ]),
18205
- vue.createElementVNode("div", _hoisted_3$3, [
18280
+ vue.createElementVNode("div", {
18281
+ ref_key: "previewContainer",
18282
+ ref: previewContainer,
18283
+ class: "preview-container border-w-1 border border-gray",
18284
+ style: vue.normalizeStyle({ minHeight: url.value ? void 0 : "300px", overflow: "hidden" })
18285
+ }, [
18206
18286
  url.value ? (vue.openBlock(), vue.createBlock(vue.unref(YouTube), {
18207
18287
  key: 0,
18208
18288
  ref: "youtube",
18209
18289
  src: url.value,
18210
- class: "youtube",
18211
- height: "360",
18212
- width: "480"
18213
- }, null, 8, ["src"])) : vue.createCommentVNode("", true)
18214
- ])
18290
+ width: previewWidth.value,
18291
+ height: previewHeight.value
18292
+ }, null, 8, ["src", "width", "height"])) : vue.createCommentVNode("", true)
18293
+ ], 4)
18215
18294
  ])
18216
18295
  ]),
18217
18296
  buttons: vue.withCtx(() => [
18218
- vue.createElementVNode("div", _hoisted_4$2, [
18297
+ vue.createElementVNode("div", _hoisted_3$3, [
18219
18298
  vue.withDirectives(vue.createElementVNode("button", {
18220
18299
  class: "mr-4",
18221
18300
  onClick: ok
@@ -18229,9 +18308,10 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
18229
18308
  };
18230
18309
  }
18231
18310
  });
18232
- const PbYoutubeModal = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
18311
+ const PbYoutubeModal = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-c0ba6980"]]);
18312
+ const PbYoutubeModal$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
18233
18313
  __proto__: null,
18234
- default: _sfc_main$3
18314
+ default: PbYoutubeModal
18235
18315
  }, Symbol.toStringTag, { value: "Module" }));
18236
18316
  const _hoisted_1$2 = { class: "bs-layout-vertical pb-part-add-modal" };
18237
18317
  const _hoisted_2$2 = { class: "bs-layout-horizontal-wrap ml-16 mb-8 gap-8" };
@@ -18586,7 +18666,7 @@ ${_html.tags}` : "";
18586
18666
  exports2.PbIframeWidget = _sfc_main$5$1;
18587
18667
  exports2.PbMediaWidget = _sfc_main$8$1;
18588
18668
  exports2.PbTextWidget = _sfc_main$7$1;
18589
- exports2.PbYoutubeWidget = _sfc_main$4$1;
18669
+ exports2.PbYoutubeWidget = PbYoutubeWidget;
18590
18670
  exports2.ROOT_TYPE = ROOT_TYPE$1;
18591
18671
  exports2.RootPart = RootPart;
18592
18672
  exports2.SECTION_TYPE = SECTION_TYPE$1;
package/dist/style.css CHANGED
@@ -385,4 +385,9 @@
385
385
  line-height: 1;
386
386
  height: 28px;
387
387
  background-color: var(--primary);
388
- }
388
+ }
389
+ .preview-container[data-v-c0ba6980] {
390
+ width: 100%;
391
+ min-height: 300px;
392
+ overflow: hidden;
393
+ }
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.100",
4
+ "version": "1.0.0-alpha.101",
5
5
  "engins": {
6
6
  "node": ">= 20.0.0"
7
7
  },
@@ -31,7 +31,7 @@
31
31
  "vue-router": "^4.4.3",
32
32
  "vue3-click-away": "^1.2.4",
33
33
  "yjs": "^13.6.14",
34
- "@g1cloud/page-builder-viewer": "1.0.0-alpha.100"
34
+ "@g1cloud/page-builder-viewer": "1.0.0-alpha.101"
35
35
  },
36
36
  "devDependencies": {
37
37
  "@types/node": "^20.12.7",
@@ -1,73 +0,0 @@
1
- import { defineComponent, ref, openBlock, createBlock, unref, withCtx, createElementVNode, withDirectives, createVNode, createCommentVNode } from "vue";
2
- import { useModalHandle, BSModalFrame, vT, BSTextInput } from "@g1cloud/bluesea";
3
- import YouTube from "vue3-youtube";
4
- const _hoisted_1 = { class: "bs-layout-vertical flex-grow-1 h-full" };
5
- const _hoisted_2 = { class: "pt-8" };
6
- const _hoisted_3 = { class: "w-480 h-360 border-w-1 border border-gray" };
7
- const _hoisted_4 = { class: "bs-layout-horizontal justify-content-center" };
8
- const _sfc_main = /* @__PURE__ */ defineComponent({
9
- __name: "PbYoutubeModal",
10
- props: {
11
- url: {}
12
- },
13
- emits: ["selectUrl"],
14
- setup(__props, { emit: __emit }) {
15
- const props = __props;
16
- const emit = __emit;
17
- const modalHandle = useModalHandle();
18
- const url = ref(props.url);
19
- const updateUrl = (value) => {
20
- url.value = value;
21
- };
22
- const ok = () => {
23
- emit("selectUrl", url.value);
24
- modalHandle.close();
25
- };
26
- return (_ctx, _cache) => {
27
- return openBlock(), createBlock(unref(BSModalFrame), {
28
- title: { key: "pb.modal.youtube.title" },
29
- class: "pb-youtube-modal"
30
- }, {
31
- default: withCtx(() => [
32
- createElementVNode("div", _hoisted_1, [
33
- withDirectives(createElementVNode("div", null, null, 512), [
34
- [unref(vT), { key: "pb.modal.youtube.url" }]
35
- ]),
36
- createVNode(unref(BSTextInput), {
37
- "model-value": url.value,
38
- width: "100%",
39
- "onUpdate:modelValue": updateUrl
40
- }, null, 8, ["model-value"]),
41
- withDirectives(createElementVNode("div", _hoisted_2, null, 512), [
42
- [unref(vT), { key: "pb.modal.youtube.preview" }]
43
- ]),
44
- createElementVNode("div", _hoisted_3, [
45
- url.value ? (openBlock(), createBlock(unref(YouTube), {
46
- key: 0,
47
- ref: "youtube",
48
- src: url.value,
49
- class: "youtube",
50
- height: "360",
51
- width: "480"
52
- }, null, 8, ["src"])) : createCommentVNode("", true)
53
- ])
54
- ])
55
- ]),
56
- buttons: withCtx(() => [
57
- createElementVNode("div", _hoisted_4, [
58
- withDirectives(createElementVNode("button", {
59
- class: "mr-4",
60
- onClick: ok
61
- }, null, 512), [
62
- [unref(vT), { key: "pb.button.ok" }]
63
- ])
64
- ])
65
- ]),
66
- _: 1
67
- });
68
- };
69
- }
70
- });
71
- export {
72
- _sfc_main as default
73
- };