@myissue/vue-website-page-builder 3.3.64 → 3.3.65

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/README.md +147 -126
  2. package/dist/logo/mybuilder_new_lowercase.svg +17558 -0
  3. package/dist/vue-website-page-builder.css +1 -1
  4. package/dist/vue-website-page-builder.js +7326 -6943
  5. package/dist/vue-website-page-builder.umd.cjs +54 -51
  6. package/package.json +2 -2
  7. package/src/Components/DemoUnsplash.vue +1 -4
  8. package/src/Components/PageBuilder/EditorMenu/Editables/BackgroundColorEditor.vue +2 -1
  9. package/src/Components/PageBuilder/EditorMenu/Editables/BorderRadius.vue +18 -5
  10. package/src/Components/PageBuilder/EditorMenu/Editables/Borders.vue +6 -4
  11. package/src/Components/PageBuilder/EditorMenu/Editables/ClassEditor.vue +2 -1
  12. package/src/Components/PageBuilder/EditorMenu/Editables/EditGetElement.vue +5 -5
  13. package/src/Components/PageBuilder/EditorMenu/Editables/ManageBackgroundOpacity.vue +7 -8
  14. package/src/Components/PageBuilder/EditorMenu/Editables/ManageOpacity.vue +2 -2
  15. package/src/Components/PageBuilder/EditorMenu/Editables/Margin.vue +4 -2
  16. package/src/Components/PageBuilder/EditorMenu/Editables/Padding.vue +4 -2
  17. package/src/Components/PageBuilder/EditorMenu/Editables/StyleEditor.vue +115 -0
  18. package/src/Components/PageBuilder/EditorMenu/Editables/TextColorEditor.vue +2 -1
  19. package/src/Components/PageBuilder/EditorMenu/Editables/Typography.vue +14 -7
  20. package/src/Components/PageBuilder/EditorMenu/RightSidebarEditor.vue +56 -64
  21. package/src/Components/PageBuilder/ToolbarOption/ToolbarOption.vue +10 -7
  22. package/src/PageBuilder/PageBuilder.vue +89 -63
  23. package/src/PageBuilder/Preview.vue +25 -9
  24. package/src/composables/extractCleanHTMLFromPageBuilder.ts +4 -3
  25. package/src/css/app.css +10 -70
  26. package/src/services/LocalStorageManager.ts +1 -162
  27. package/src/services/PageBuilderService.ts +584 -265
  28. package/src/stores/page-builder-state.ts +8 -0
  29. package/src/tests/PageBuilderTest.vue +20 -19
  30. package/src/tests/componentsArray.test.json +3 -3
  31. package/src/types/index.ts +10 -2
  32. package/src/utils/html-elements/component.ts +10 -10
@@ -2,6 +2,7 @@
2
2
  import { computed, ref, watch, nextTick } from 'vue'
3
3
  import { sharedPageBuilderStore } from '../../../stores/shared-store'
4
4
  import ClassEditor from './Editables/ClassEditor.vue'
5
+ import StyleEditor from './Editables/StyleEditor.vue'
5
6
  import ImageEditor from './Editables/ImageEditor.vue'
6
7
  import OpacityEditor from './Editables/OpacityEditor.vue'
7
8
  import Typography from './Editables/Typography.vue'
@@ -22,12 +23,11 @@ import ModalBuilder from '../../../Components/Modals/ModalBuilder.vue'
22
23
  import { extractCleanHTMLFromPageBuilder } from '../../../composables/extractCleanHTMLFromPageBuilder'
23
24
 
24
25
  const pageBuilderService = getPageBuilder()
25
- // Use shared store instance
26
26
  const pageBuilderStateStore = sharedPageBuilderStore
27
27
 
28
- // emit
29
- const emit = defineEmits(['closeEditor'])
28
+ defineEmits(['closeEditor'])
30
29
 
30
+ const isLoadingPageStyles = ref(null)
31
31
  const getComponents = computed(() => {
32
32
  return pageBuilderStateStore.getComponents
33
33
  })
@@ -35,7 +35,6 @@ const getElement = computed(() => {
35
35
  return pageBuilderStateStore.getElement
36
36
  })
37
37
 
38
- // Get tagName of element
39
38
  const elementTag = computed(() => {
40
39
  return getElement.value?.tagName
41
40
  })
@@ -106,15 +105,8 @@ const handleUpdatePageStyles = async function () {
106
105
  await pageBuilderService.globalPageStyles()
107
106
  }
108
107
 
109
- const clearClassesFromPage = async function () {
110
- await pageBuilderService.clearClassesFromPage()
111
- }
112
-
113
- const clearInlineStylesFromPagee = async function () {
114
- await pageBuilderService.clearInlineStylesFromPagee()
115
- }
116
-
117
108
  const handleCloseGlobalPageStyles = async function () {
109
+ isLoadingPageStyles.value = true
118
110
  await pageBuilderService.handleManualSave()
119
111
 
120
112
  // Remove global highlight if present
@@ -124,6 +116,7 @@ const handleCloseGlobalPageStyles = async function () {
124
116
  }
125
117
 
126
118
  showModalGlobalPageStyles.value = false
119
+ isLoadingPageStyles.value = false
127
120
  }
128
121
  </script>
129
122
 
@@ -146,7 +139,7 @@ const handleCloseGlobalPageStyles = async function () {
146
139
  </div>
147
140
 
148
141
  <div
149
- v
142
+ v-if="!showModalGlobalPageStyles"
150
143
  ref="scrollContainer"
151
144
  @scroll="onScroll"
152
145
  class="pbx-pl-3 pbx-pr-3 pbx-mb-4 pbx-overflow-y-scroll"
@@ -180,6 +173,9 @@ const handleCloseGlobalPageStyles = async function () {
180
173
  <article class="pbx-my-1 pbx-bg-white">
181
174
  <ClassEditor></ClassEditor>
182
175
  </article>
176
+ <article class="pbx-my-1 pbx-bg-white">
177
+ <StyleEditor></StyleEditor>
178
+ </article>
183
179
  </div>
184
180
 
185
181
  <!-- Global Page Styles -->
@@ -227,63 +223,59 @@ const handleCloseGlobalPageStyles = async function () {
227
223
 
228
224
  <ModalBuilder
229
225
  maxWidth="md"
230
- minHeight="pbx-h-[90vh]"
226
+ minHeight="pbx-min-h-[65vh] pbx-max-h-[65vh]"
231
227
  :showModalBuilder="showModalGlobalPageStyles"
232
228
  title="Global Page Styles"
233
229
  @closeMainModalBuilder="handleCloseGlobalPageStyles"
234
230
  >
235
- <div class="pbx-min-h-[90vh] pbx-flex pbx-flex-col pbx-gap-2 pbx-pt-4 pbx-pb-2">
236
- <p class="pbx-myPrimaryParagraph">
237
- Apply styles that affect the entire page. These settings include global font family, text
238
- color, background color, and other universal styles that apply to all sections.
239
- </p>
240
- <article class="pbx-my-1 pbx-bg-gray-100">
241
- <Typography></Typography>
242
- </article>
243
- <article class="pbx-my-1 pbx-bg-gray-100">
244
- <TextColorEditor :globalPageLayout="true"></TextColorEditor>
245
- </article>
246
- <article class="pbx-my-1 pbx-bg-gray-100">
247
- <BackgroundColorEditor :globalPageLayout="true"></BackgroundColorEditor>
248
- </article>
249
- <article class="pbx-my-1 pbx-bg-gray-100">
250
- <Padding> </Padding>
251
- </article>
252
- <article class="pbx-my-1 pbx-bg-gray-100">
253
- <Margin> </Margin>
254
- </article>
255
- <article class="pbx-my-1 pbx-bg-gray-100">
256
- <BorderRadius></BorderRadius>
257
- </article>
258
- <article class="pbx-my-1 pbx-bg-gray-100">
259
- <Borders></Borders>
260
- </article>
261
- <article class="pbx-my-1 pbx-bg-gray-100">
262
- <ClassEditor></ClassEditor>
263
- </article>
264
- </div>
265
- <label class="pbx-myPrimaryInputLabel pbx-my-4">
266
- Choose an action to clean up your page:
267
- </label>
268
- <div
269
- class="pbx-border-0 pbx-border-solid pbx-border-t pbx-border-gray-200 pbx-mt-4 pbx-flex pbx-items-center pbx-justify-end"
270
- >
271
- <div class="pbx-py-4 pbx-flex sm:pbx-justify-end pbx-justify-center">
272
- <div
273
- class="sm:pbx-grid-cols-1 sm:pbx-items-end sm:pbx-justify-end pbx-flex sm:pbx-flex-row pbx-flex-col pbx-myPrimaryGap sm:pbx-w-5/6 pbx-w-full pbx-mt-4"
274
- >
275
- <!-- Button: Clear all CSS classes -->
276
- <button @click="clearClassesFromPage" class="pbx-myPrimaryButton" type="button">
277
- Clear All CSS Classes
278
- </button>
279
-
280
- <!-- Button: Clear all inline styles -->
281
- <button @click="clearInlineStylesFromPagee" class="pbx-myPrimaryButton" type="button">
282
- Clear All Inline Styles
283
- </button>
231
+ <div class="pbx-flex pbx-flex-col pbx-gap-2 pbx-pt-4 pbx-pb-2">
232
+ <div v-if="isLoadingPageStyles">
233
+ <div class="pbx-flex pbx-items-center pbx-my-2 pbx-py-4 pbx-px-2 pbx-justify-center">
234
+ <div
235
+ class="pbx-inline-block pbx-h-8 pbx-w-8 pbx-animate-spin pbx-rounded-full pbx-border-4 pbx-border-solid pbx-border-current pbx-border-r-transparent pbx-align-[-0.125em] motion-reduce:pbx-animate-[spin_1.5s_linear_infinite]"
236
+ >
237
+ <span
238
+ class="!pbx-absolute !pbx-m-px !pbx-h-px !pbx-w-px !pbx-overflow-hidden !pbx-whitespace-nowrap !pbx-border-0 !pbx-p-0 !pbx-[clip:rect(0,0,0,0)]"
239
+ >Loading...</span
240
+ >
241
+ </div>
242
+ </div>
243
+ </div>
244
+ <div v-if="!isLoadingPageStyles && showModalGlobalPageStyles" class="pbx-pb-12">
245
+ <div>
246
+ <p class="pbx-myPrimaryParagraph">
247
+ Apply styles that affect the entire page. These settings include global font family,
248
+ text color, background color, and other universal styles that apply to all sections.
249
+ </p>
250
+ <article class="pbx-my-1 pbx-bg-gray-100">
251
+ <Typography></Typography>
252
+ </article>
253
+ <article class="pbx-my-1 pbx-bg-gray-100">
254
+ <TextColorEditor :globalPageLayout="true"></TextColorEditor>
255
+ </article>
256
+ <article class="pbx-my-1 pbx-bg-gray-100">
257
+ <BackgroundColorEditor :globalPageLayout="true"></BackgroundColorEditor>
258
+ </article>
259
+ <article class="pbx-my-1 pbx-bg-gray-100">
260
+ <Padding> </Padding>
261
+ </article>
262
+ <article class="pbx-my-1 pbx-bg-gray-100">
263
+ <Margin> </Margin>
264
+ </article>
265
+ <article class="pbx-my-1 pbx-bg-gray-100">
266
+ <BorderRadius></BorderRadius>
267
+ </article>
268
+ <article class="pbx-my-1 pbx-bg-gray-100">
269
+ <Borders></Borders>
270
+ </article>
271
+ <article class="pbx-my-1 pbx-bg-gray-100">
272
+ <ClassEditor></ClassEditor>
273
+ </article>
274
+ <article class="pbx-my-1 pbx-bg-gray-100">
275
+ <StyleEditor></StyleEditor>
276
+ </article>
284
277
  </div>
285
278
  </div>
286
- <!--v-if-->
287
279
  </div>
288
280
  </ModalBuilder>
289
281
  </div>
@@ -35,7 +35,7 @@ const firstModalButtonFunctionDynamicModalBuilder = ref(null)
35
35
  const secondModalButtonFunctionDynamicModalBuilder = ref(null)
36
36
  const thirdModalButtonFunctionDynamicModalBuilder = ref(null)
37
37
 
38
- const deleteAllComponentsFromDOM = function () {
38
+ const handleDeleteComponentsFromDOM = function () {
39
39
  showModalDeleteAllComponents.value = true
40
40
  typeModal.value = 'delete'
41
41
  gridColumnModal.value = 2
@@ -53,11 +53,10 @@ const deleteAllComponentsFromDOM = function () {
53
53
  // handle click
54
54
  thirdModalButtonFunctionDynamicModalBuilder.value = async function () {
55
55
  isDeletingLayout.value = true
56
- pageBuilderService.deleteAllComponentsFromDOM()
57
56
  await pageBuilderService.clearHtmlSelection()
58
- await pageBuilderService.removeCurrentComponentsFromLocalStorage()
59
-
57
+ await pageBuilderService.handleFormSubmission()
60
58
  await delay(500)
59
+
61
60
  showModalDeleteAllComponents.value = false
62
61
  isDeletingLayout.value = false
63
62
  }
@@ -113,7 +112,9 @@ const openHTMLSettings = function () {
113
112
  getPageBuilderConfig.userForPageBuilder.name[0]
114
113
  }}
115
114
  </div>
116
- <div class="pbx-hidden pbx-text-xs pbx-h-8 lg:pbx-flex pbx-items-center pbx-font-normal">
115
+ <div
116
+ class="pbx-hidden pbx-text-xs pbx-h-8 lg:pbx-flex pbx-items-center pbx-font-normal w-max break-keep"
117
+ >
117
118
  {{ getPageBuilderConfig.userForPageBuilder.name }}
118
119
  </div>
119
120
  </div>
@@ -141,7 +142,9 @@ const openHTMLSettings = function () {
141
142
  class="pbx-block pbx-inset-0 pbx-object-top pbx-h-8 pbx-min-h-8 pbx-max-h-8 pbx-w-8 pbx-min-w-8 pbx-max-w-8 pbx-object-cover pbx-rounded-full"
142
143
  />
143
144
  </div>
144
- <div class="pbx-hidden pbx-text-xs pbx-h-8 lg:pbx-flex pbx-items-center pbx-font-normal">
145
+ <div
146
+ class="pbx-hidden pbx-text-xs pbx-h-8 lg:pbx-flex pbx-items-center pbx-font-normal w-max break-keep"
147
+ >
145
148
  {{ getPageBuilderConfig.userForPageBuilder.name }}
146
149
  </div>
147
150
  </div>
@@ -185,7 +188,7 @@ const openHTMLSettings = function () {
185
188
 
186
189
  <!-- Delete Layout Start -->
187
190
  <button
188
- @click="deleteAllComponentsFromDOM"
191
+ @click="handleDeleteComponentsFromDOM"
189
192
  class="pbx-myPrimaryDeleteButton pbx-text-xs pbx-font-normal"
190
193
  type="button"
191
194
  >
@@ -34,6 +34,10 @@ const props = defineProps({
34
34
  type: Boolean,
35
35
  default: false,
36
36
  },
37
+ showPublishButton: {
38
+ type: Boolean,
39
+ default: false,
40
+ },
37
41
  })
38
42
 
39
43
  // Use shared Pinia instance for PageBuilder package
@@ -49,11 +53,15 @@ provide('internalPinia', internalPinia)
49
53
  provide('CustomMediaComponent', props.CustomMediaLibraryComponent)
50
54
  provide('CustomBuilderComponents', props.CustomBuilderComponents)
51
55
 
52
- const emit = defineEmits(['handleClosePageBuilder'])
56
+ const emit = defineEmits(['handleClosePageBuilder', 'handlePublishPageBuilder'])
53
57
 
54
58
  const closePageBuilder = function () {
55
59
  emit('handleClosePageBuilder')
56
60
  }
61
+ const closePublish = function () {
62
+ pageBuilderService.handleManualSave()
63
+ emit('handlePublishPageBuilder')
64
+ }
57
65
 
58
66
  // Provide modal close function for custom components
59
67
  const closeAddComponentModal = () => {
@@ -185,8 +193,6 @@ const handleSelectComponent = function (componentObject) {
185
193
  pageBuilderStateStore.setComponent(componentObject)
186
194
  }
187
195
 
188
- const draggableZone = ref(null)
189
-
190
196
  const getIsLoadingGlobal = computed(() => {
191
197
  return pageBuilderStateStore.getIsLoadingGlobal
192
198
  })
@@ -292,10 +298,10 @@ let lastToolbarTop = null
292
298
 
293
299
  function updatePanelPosition() {
294
300
  const container = pbxToolBar.value
295
- const editToolbar = container && container.querySelector('#editToolbar')
301
+ const editToolbarElement = container && container.querySelector('#pbxEditToolbar')
296
302
  const restored = getRestoredElement.value
297
303
 
298
- if (!container || !editToolbar) return
304
+ if (!container || !editToolbarElement) return
299
305
 
300
306
  const selected = container.querySelector('[selected]')
301
307
 
@@ -304,33 +310,41 @@ function updatePanelPosition() {
304
310
  const containerRect = container.getBoundingClientRect()
305
311
 
306
312
  const left =
307
- selectedRect.left - containerRect.left + selectedRect.width / 2 - editToolbar.offsetWidth / 2
313
+ selectedRect.left -
314
+ containerRect.left +
315
+ selectedRect.width / 2 -
316
+ editToolbarElement.offsetWidth / 2
308
317
 
309
318
  const GAP = 20 // px
310
319
  const proposedTop =
311
- selectedRect.top - containerRect.top + container.scrollTop - editToolbar.offsetHeight - GAP
320
+ selectedRect.top -
321
+ containerRect.top +
322
+ container.scrollTop -
323
+ editToolbarElement.offsetHeight -
324
+ GAP
312
325
 
313
326
  const top = Math.max(0, proposedTop)
314
327
 
315
- editToolbar.style.position = 'absolute'
316
- editToolbar.style.left = `${left}px`
317
- editToolbar.style.top = `${top}px`
318
- editToolbar.classList.add('is-visible')
328
+ editToolbarElement.style.position = 'absolute'
329
+ editToolbarElement.style.left = `${left}px`
330
+ editToolbarElement.style.top = `${top}px`
331
+ editToolbarElement.classList.add('is-visible')
319
332
 
320
333
  lastToolbarLeft = left
321
334
  lastToolbarTop = top
322
335
  } else if (restored && lastToolbarLeft !== null && lastToolbarTop !== null) {
323
- editToolbar.style.position = 'absolute'
324
- editToolbar.style.left = `${lastToolbarLeft}px`
325
- editToolbar.style.top = `${lastToolbarTop}px`
326
- editToolbar.classList.add('is-visible')
336
+ editToolbarElement.style.position = 'absolute'
337
+ editToolbarElement.style.left = `${lastToolbarLeft}px`
338
+ editToolbarElement.style.top = `${lastToolbarTop}px`
339
+ editToolbarElement.classList.add('is-visible')
327
340
  } else {
328
- editToolbar.classList.remove('is-visible')
341
+ editToolbarElement.classList.remove('is-visible')
329
342
  }
330
343
  }
331
344
 
332
345
  onMounted(async () => {
333
- await pageBuilderService.completeBuilderInitialization()
346
+ // await delay(2000)
347
+ await pageBuilderService.completeBuilderInitialization(undefined, true)
334
348
 
335
349
  updatePanelPosition()
336
350
 
@@ -602,7 +616,7 @@ onMounted(async () => {
602
616
  "
603
617
  >
604
618
  <div
605
- class="pbx-flex pbx-items-center pbx-justify-center pbx-gap-2 pbx-border-0 pbx-border-solid pbx-border-r pbx-border-gray-200 lg:pbx-pr-6"
619
+ class="pbx-flex pbx-items-center pbx-justify-center pbx-gap-2 pbx-border-gray-200"
606
620
  >
607
621
  <span class="lg:pbx-block pbx-hidden">
608
622
  <div class="pbx-whitespace-nowrap pbx-cursor-pointer">Add new Components</div>
@@ -656,18 +670,40 @@ onMounted(async () => {
656
670
  </div>
657
671
  </div>
658
672
  </div>
659
- <!-- Options # Start -->
660
- <div
661
- @click.self="
662
- async () => {
663
- await pageBuilderService.clearHtmlSelection()
664
- }
665
- "
666
- class="pbx-flex pbx-items-center pbx-py-2 pbx-min-h-20 pbx-max-h-20 pbx-w-full"
667
- :class="[showCloseButton ? 'pbx-justify-between' : 'pbx-justify-end']"
668
- >
669
- <ToolbarOption></ToolbarOption>
670
- <template v-if="showCloseButton">
673
+
674
+ <div class="pbx-flex gap-2 pbx-items-center">
675
+ <!-- Options # Start -->
676
+ <div
677
+ @click.self="
678
+ async () => {
679
+ await pageBuilderService.clearHtmlSelection()
680
+ }
681
+ "
682
+ class="pbx-flex pbx-items-center pbx-py-2 pbx-min-h-20 pbx-max-h-20 pbx-w-full"
683
+ :class="[showCloseButton ? 'pbx-justify-between' : 'pbx-justify-end']"
684
+ >
685
+ <ToolbarOption></ToolbarOption>
686
+ </div>
687
+ <!-- Options # Start -->
688
+ </div>
689
+ <!-- Close & Publish buttons start -->
690
+ <template v-if="showPublishButton">
691
+ <div class="pbx-ml-2">
692
+ <button
693
+ class="pbx-myPrimaryButton"
694
+ @click="
695
+ async () => {
696
+ closePublish()
697
+ await pageBuilderService.clearHtmlSelection()
698
+ }
699
+ "
700
+ >
701
+ Publish
702
+ </button>
703
+ </div>
704
+ </template>
705
+ <template v-if="showCloseButton">
706
+ <div class="pbx-ml-2">
671
707
  <button
672
708
  class="pbx-h-10 pbx-w-10 pbx-flex-end pbx-cursor-pointer pbx-rounded-full pbx-flex pbx-items-center pbx-border-none pbx-justify-center pbx-bg-gray-50 pbx-aspect-square hover:pbx-bg-myPrimaryLinkColor hover:pbx-text-white hover:pbx-fill-white focus-visible:pbx-ring-0"
673
709
  @click="
@@ -679,9 +715,10 @@ onMounted(async () => {
679
715
  >
680
716
  <span class="material-symbols-outlined"> close </span>
681
717
  </button>
682
- </template>
683
- </div>
684
- <!-- Options # Start -->
718
+ </div>
719
+ </template>
720
+
721
+ <!-- Close & Publish buttons end -->
685
722
  </div>
686
723
 
687
724
  <!-- Top Layout Save And Reset Area - End -->
@@ -728,12 +765,11 @@ onMounted(async () => {
728
765
  :class="{ 'pbx-mr-2': !getMenuRight, '': getMenuRight }"
729
766
  >
730
767
  <div
731
- id="editToolbar"
732
- class="pbx-z-30 lg:pbx-mx-20 pbx-flex pbx-gap-2 pbx-justify-center pbx-min-w-72 pbx-items-center pbx-rounded-full pbx-px-4 pbx-bg-red-200 pbx-h-0"
768
+ id="pbxEditToolbar"
769
+ class="pbx-z-30 lg:pbx-mx-20 pbx-flex pbx-gap-2 pbx-justify-center pbx-items-center pbx-rounded pbx-px-4 pbx-bg-red-200 pbx-h-0"
733
770
  style="
734
771
  box-shadow: 0 0 0 10px oklch(86.9% 0.005 56.366);
735
772
  background: oklch(86.9% 0.005 56.366);
736
- border-radius: 9999px;
737
773
  "
738
774
  >
739
775
  <template v-if="getElement">
@@ -751,26 +787,14 @@ onMounted(async () => {
751
787
  </div>
752
788
  <!-- Element Popover toolbar end -->
753
789
 
754
- <div
755
- id="contains-pagebuilder"
756
- class="pbx-pl-4 pbx-pr-4 pbx-pb-4 pbx-pt-1 pbx-h-full pbx-overflow-y-auto"
757
- >
758
- <div id="pagebuilder" class="pbx-text-black pbx-font-sans">
759
- <div ref="draggableZone">
760
- <!-- Added Components to DOM # start -->
761
- <div
762
- v-for="component in getComponents"
763
- :key="component.id"
764
- id="page-builder-editor-editable-area"
765
- class="pbx-bg-white pbx-grow"
766
- >
767
- <div @mouseup="handleSelectComponent(component)" class="pbx-relative group">
768
- <div v-html="component.html_code"></div>
769
- </div>
770
- </div>
771
- <!-- Added Components to DOM # end -->
772
- </div>
773
- </div>
790
+ <div id="pagebuilder" class="pbx-text-black pbx-font-sans">
791
+ <template v-for="component in getComponents" :key="component.id">
792
+ <section
793
+ v-if="component.html_code"
794
+ v-html="component.html_code"
795
+ @mouseup="handleSelectComponent(component)"
796
+ ></section>
797
+ </template>
774
798
  </div>
775
799
  </main>
776
800
 
@@ -781,7 +805,7 @@ onMounted(async () => {
781
805
  await pageBuilderService.clearHtmlSelection()
782
806
  }
783
807
  "
784
- class="pbx-min-w-[3.5rem] pbx-pt-7 pbx-pb-2 pbx-ml-2 pbx-border-l-solid pbx-border-gray-200"
808
+ class="pbx-min-w-[3rem] pbx-pt-6 pbx-pb-2"
785
809
  >
786
810
  <div
787
811
  @click.self="
@@ -789,15 +813,16 @@ onMounted(async () => {
789
813
  await pageBuilderService.clearHtmlSelection()
790
814
  }
791
815
  "
792
- class="pbx-flex pbx-items-center pbx-justify-center pbx-gap-4"
816
+ class="pbx-flex pbx-flex-col pbx-items-center pbx-justify-center pbx-gap-2"
793
817
  >
794
818
  <button
795
- type="button"
796
819
  v-if="!getMenuRight"
797
820
  @click="pageBuilderStateStore.setMenuRight(true)"
798
- class="pbx-h-10 pbx-w-10 pbx-cursor-pointer pbx-rounded-full pbx-flex pbx-items-center pbx-border-none pbx-justify-center pbx-bg-gray-50 pbx-aspect-square hover:pbx-bg-myPrimaryLinkColor hover:pbx-text-white focus-visible:pbx-ring-0"
821
+ type="button"
822
+ class="pbx-mySecondaryButton"
799
823
  >
800
- <span class="material-symbols-outlined"> palette </span>
824
+ <span class="material-symbols-outlined"> view_sidebar </span>
825
+ <span> Tools </span>
801
826
  </button>
802
827
  </div>
803
828
  </div>
@@ -806,15 +831,16 @@ onMounted(async () => {
806
831
  aria-label="Menu"
807
832
  id="pagebuilder-right-area"
808
833
  :class="{
809
- 'pbx-w-0': !getMenuRight,
834
+ 'pbx-w-0 pbx-mr-0': !getMenuRight,
810
835
  'pbx-w-80 pbx-mr-2 pbx-bg-myPrimaryLightGrayColor pbx-items-stretch': getMenuRight,
811
836
  }"
812
- class="pbx-duration-300 pbx-z-20 pbx-flex-shrink-0 pbx-overflow-hidden pbx-shadow-sm pbx-rounded-l-2xl pbx-h-[100vh]"
837
+ class="pbx-duration-100 pbx-z-20 pbx-flex-shrink-0 pbx-overflow-hidden pbx-shadow-sm pbx-rounded-l-2xl pbx-h-[100vh]"
813
838
  >
814
839
  <RightSidebarEditor @closeEditor="pageBuilderStateStore.setMenuRight(false)">
815
840
  </RightSidebarEditor>
816
841
  </aside>
817
842
  </div>
843
+
818
844
  <div
819
845
  class="pbx-flex pbx-items-center pbx-justify-center pbx-p-4 pbx-border-0 pbx-border-t pbx-border-t-gray-200 pbx-border-solid lg:pbx-mx-10"
820
846
  >
@@ -1,13 +1,14 @@
1
1
  <script setup>
2
- import { ref } from 'vue'
2
+ import { ref, watchEffect } from 'vue'
3
3
 
4
- defineProps({
4
+ const props = defineProps({
5
5
  mobile: {
6
6
  type: Boolean,
7
7
  },
8
8
  })
9
9
 
10
10
  const htmlPage = ref('')
11
+ const iframeRef = ref(null)
11
12
 
12
13
  const previewData = localStorage.getItem('preview')
13
14
 
@@ -20,6 +21,23 @@ if (previewData) {
20
21
  htmlPage.value = ''
21
22
  }
22
23
  }
24
+
25
+ watchEffect(() => {
26
+ if (props.mobile && iframeRef.value && htmlPage.value) {
27
+ const iframe = iframeRef.value
28
+ const doc = iframe.contentWindow.document
29
+ doc.open()
30
+ doc.write(
31
+ `<!DOCTYPE html><html><head><meta name="viewport" content="width=device-width, initial-scale=1.0"></head><body>${htmlPage.value}</body></html>`,
32
+ )
33
+ doc.close()
34
+
35
+ // Copy stylesheets
36
+ document.querySelectorAll('link[rel="stylesheet"], style').forEach((node) => {
37
+ doc.head.appendChild(node.cloneNode(true))
38
+ })
39
+ }
40
+ })
23
41
  </script>
24
42
 
25
43
  <template>
@@ -36,13 +54,11 @@ if (previewData) {
36
54
  </template>
37
55
  <template v-if="mobile">
38
56
  <div>
39
- <div
40
- class="pbx-text-black pbx-w-full pbx-inset-x-0 pbx-h-[90vh] pbx-bg-white pbx-overflow-x-scroll lg:pbx-pt-2 pbx-pt-2"
41
- >
42
- <div id="page-builder-editor">
43
- <div class="" v-html="htmlPage"></div>
44
- </div>
45
- </div>
57
+ <iframe
58
+ ref="iframeRef"
59
+ class="pbx-mx-auto pbx-w-full pbx-bg-white pbx-shadow-lg pbx-h-[80vh] pbx-border-0"
60
+ src="about:blank"
61
+ ></iframe>
46
62
  </div>
47
63
  </template>
48
64
  </template>
@@ -25,14 +25,15 @@ export function extractCleanHTMLFromPageBuilder(
25
25
  }
26
26
  })
27
27
 
28
- if (config && config.pageSettings && typeof config.pageSettings.imageUrlPrefix === 'string') {
29
- const imageUrlPrefix = config.pageSettings.imageUrlPrefix
28
+ if (config && config && typeof config.imageUrlPrefix === 'string') {
29
+ const imageUrlPrefix = config.imageUrlPrefix
30
30
  const imgs = clone.querySelectorAll<HTMLImageElement>('img')
31
31
  imgs.forEach((img) => {
32
32
  const src = img.getAttribute('src') || ''
33
33
  if (
34
34
  !src.startsWith('http') &&
35
- imageUrlPrefix && // extra safety
35
+ // extra safety
36
+ imageUrlPrefix &&
36
37
  !src.startsWith(imageUrlPrefix)
37
38
  ) {
38
39
  img.setAttribute('src', imageUrlPrefix + src.replace(/^\/+/, ''))