@myissue/vue-website-page-builder 3.3.64 → 3.3.67
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.
- package/README.md +216 -129
- package/dist/logo/mybuilder_new_lowercase.svg +17558 -0
- package/dist/vue-website-page-builder.css +1 -1
- package/dist/vue-website-page-builder.js +16345 -13089
- package/dist/vue-website-page-builder.umd.cjs +78 -54
- package/package.json +3 -2
- package/src/Components/DemoUnsplash.vue +1 -4
- package/src/Components/PageBuilder/EditorMenu/Editables/BackgroundColorEditor.vue +4 -3
- package/src/Components/PageBuilder/EditorMenu/Editables/BorderRadius.vue +32 -13
- package/src/Components/PageBuilder/EditorMenu/Editables/Borders.vue +12 -8
- package/src/Components/PageBuilder/EditorMenu/Editables/ClassEditor.vue +10 -8
- package/src/Components/PageBuilder/EditorMenu/Editables/EditGetElement.vue +5 -5
- package/src/Components/PageBuilder/EditorMenu/Editables/ManageBackgroundOpacity.vue +12 -9
- package/src/Components/PageBuilder/EditorMenu/Editables/ManageOpacity.vue +6 -4
- package/src/Components/PageBuilder/EditorMenu/Editables/Margin.vue +11 -5
- package/src/Components/PageBuilder/EditorMenu/Editables/OpacityEditor.vue +1 -1
- package/src/Components/PageBuilder/EditorMenu/Editables/Padding.vue +11 -5
- package/src/Components/PageBuilder/EditorMenu/Editables/StyleEditor.vue +116 -0
- package/src/Components/PageBuilder/EditorMenu/Editables/TextColorEditor.vue +2 -1
- package/src/Components/PageBuilder/EditorMenu/Editables/Typography.vue +32 -9
- package/src/Components/PageBuilder/EditorMenu/RightSidebarEditor.vue +63 -74
- package/src/Components/PageBuilder/Settings/PageBuilderSettings.vue +3 -3
- package/src/Components/PageBuilder/ToolbarOption/ToolbarOption.vue +14 -11
- package/src/PageBuilder/PageBuilder.vue +169 -65
- package/src/PageBuilder/Preview.vue +25 -9
- package/src/composables/builderInstance.ts +3 -2
- package/src/composables/extractCleanHTMLFromPageBuilder.ts +4 -3
- package/src/css/app.css +10 -70
- package/src/i18n.ts +28 -0
- package/src/locales/ar.json +136 -0
- package/src/locales/de.json +136 -0
- package/src/locales/en.json +136 -0
- package/src/locales/es.json +136 -0
- package/src/locales/fr.json +136 -0
- package/src/locales/hi.json +136 -0
- package/src/locales/ja.json +136 -0
- package/src/locales/pt.json +136 -0
- package/src/locales/ru.json +136 -0
- package/src/locales/zh-Hans.json +136 -0
- package/src/main.ts +10 -5
- package/src/services/LocalStorageManager.ts +1 -162
- package/src/services/PageBuilderService.ts +730 -290
- package/src/stores/page-builder-state.ts +8 -0
- package/src/tests/PageBuilderTest.vue +41 -70
- package/src/tests/componentsArray.test.json +3 -3
- package/src/tests/pageBuilderService.test.ts +7 -1
- package/src/types/index.ts +17 -3
- package/src/utils/html-elements/component.ts +10 -10
|
@@ -13,6 +13,8 @@ import { useDebounce } from '../composables/useDebounce.ts'
|
|
|
13
13
|
import DynamicModalBuilder from '../Components/Modals/DynamicModalBuilder.vue'
|
|
14
14
|
import GlobalLoader from '../Components/Loaders/GlobalLoader.vue'
|
|
15
15
|
import { getPageBuilder } from '../composables/builderInstance'
|
|
16
|
+
import { useI18n } from 'vue-i18n'
|
|
17
|
+
|
|
16
18
|
const pageBuilderService = getPageBuilder()
|
|
17
19
|
/**
|
|
18
20
|
* Props for PageBuilder component
|
|
@@ -34,6 +36,10 @@ const props = defineProps({
|
|
|
34
36
|
type: Boolean,
|
|
35
37
|
default: false,
|
|
36
38
|
},
|
|
39
|
+
showPublishButton: {
|
|
40
|
+
type: Boolean,
|
|
41
|
+
default: false,
|
|
42
|
+
},
|
|
37
43
|
})
|
|
38
44
|
|
|
39
45
|
// Use shared Pinia instance for PageBuilder package
|
|
@@ -49,11 +55,15 @@ provide('internalPinia', internalPinia)
|
|
|
49
55
|
provide('CustomMediaComponent', props.CustomMediaLibraryComponent)
|
|
50
56
|
provide('CustomBuilderComponents', props.CustomBuilderComponents)
|
|
51
57
|
|
|
52
|
-
const emit = defineEmits(['handleClosePageBuilder'])
|
|
58
|
+
const emit = defineEmits(['handleClosePageBuilder', 'handlePublishPageBuilder'])
|
|
53
59
|
|
|
54
60
|
const closePageBuilder = function () {
|
|
55
61
|
emit('handleClosePageBuilder')
|
|
56
62
|
}
|
|
63
|
+
const closePublish = function () {
|
|
64
|
+
pageBuilderService.handleManualSave()
|
|
65
|
+
emit('handlePublishPageBuilder')
|
|
66
|
+
}
|
|
57
67
|
|
|
58
68
|
// Provide modal close function for custom components
|
|
59
69
|
const closeAddComponentModal = () => {
|
|
@@ -141,6 +151,28 @@ const getHasLocalDraftForUpdate = computed(() => {
|
|
|
141
151
|
return pageBuilderStateStore.getHasLocalDraftForUpdate
|
|
142
152
|
})
|
|
143
153
|
|
|
154
|
+
const { locale } = useI18n()
|
|
155
|
+
|
|
156
|
+
watch(locale, (newLocale) => {
|
|
157
|
+
const config = pageBuilderStateStore.getPageBuilderConfig
|
|
158
|
+
if (config && config.userSettings && config.userSettings.language) {
|
|
159
|
+
// Update the store with a full config (if you want to update the store)
|
|
160
|
+
const updatedConfig = {
|
|
161
|
+
...config,
|
|
162
|
+
userSettings: {
|
|
163
|
+
...config.userSettings,
|
|
164
|
+
language: {
|
|
165
|
+
...config.userSettings.language,
|
|
166
|
+
default: newLocale,
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
pageBuilderStateStore.setPageBuilderConfig(updatedConfig)
|
|
172
|
+
pageBuilderService.saveBuilderConfigToLocalStorage(updatedConfig)
|
|
173
|
+
}
|
|
174
|
+
})
|
|
175
|
+
|
|
144
176
|
watch(getHasLocalDraftForUpdate, (newVal) => {
|
|
145
177
|
if (newVal) {
|
|
146
178
|
handlerRumeEditingForUpdate()
|
|
@@ -185,8 +217,6 @@ const handleSelectComponent = function (componentObject) {
|
|
|
185
217
|
pageBuilderStateStore.setComponent(componentObject)
|
|
186
218
|
}
|
|
187
219
|
|
|
188
|
-
const draggableZone = ref(null)
|
|
189
|
-
|
|
190
220
|
const getIsLoadingGlobal = computed(() => {
|
|
191
221
|
return pageBuilderStateStore.getIsLoadingGlobal
|
|
192
222
|
})
|
|
@@ -292,10 +322,10 @@ let lastToolbarTop = null
|
|
|
292
322
|
|
|
293
323
|
function updatePanelPosition() {
|
|
294
324
|
const container = pbxToolBar.value
|
|
295
|
-
const
|
|
325
|
+
const editToolbarElement = container && container.querySelector('#pbxEditToolbar')
|
|
296
326
|
const restored = getRestoredElement.value
|
|
297
327
|
|
|
298
|
-
if (!container || !
|
|
328
|
+
if (!container || !editToolbarElement) return
|
|
299
329
|
|
|
300
330
|
const selected = container.querySelector('[selected]')
|
|
301
331
|
|
|
@@ -304,33 +334,41 @@ function updatePanelPosition() {
|
|
|
304
334
|
const containerRect = container.getBoundingClientRect()
|
|
305
335
|
|
|
306
336
|
const left =
|
|
307
|
-
selectedRect.left -
|
|
337
|
+
selectedRect.left -
|
|
338
|
+
containerRect.left +
|
|
339
|
+
selectedRect.width / 2 -
|
|
340
|
+
editToolbarElement.offsetWidth / 2
|
|
308
341
|
|
|
309
342
|
const GAP = 20 // px
|
|
310
343
|
const proposedTop =
|
|
311
|
-
selectedRect.top -
|
|
344
|
+
selectedRect.top -
|
|
345
|
+
containerRect.top +
|
|
346
|
+
container.scrollTop -
|
|
347
|
+
editToolbarElement.offsetHeight -
|
|
348
|
+
GAP
|
|
312
349
|
|
|
313
350
|
const top = Math.max(0, proposedTop)
|
|
314
351
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
352
|
+
editToolbarElement.style.position = 'absolute'
|
|
353
|
+
editToolbarElement.style.left = `${left}px`
|
|
354
|
+
editToolbarElement.style.top = `${top}px`
|
|
355
|
+
editToolbarElement.classList.add('is-visible')
|
|
319
356
|
|
|
320
357
|
lastToolbarLeft = left
|
|
321
358
|
lastToolbarTop = top
|
|
322
359
|
} else if (restored && lastToolbarLeft !== null && lastToolbarTop !== null) {
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
360
|
+
editToolbarElement.style.position = 'absolute'
|
|
361
|
+
editToolbarElement.style.left = `${lastToolbarLeft}px`
|
|
362
|
+
editToolbarElement.style.top = `${lastToolbarTop}px`
|
|
363
|
+
editToolbarElement.classList.add('is-visible')
|
|
327
364
|
} else {
|
|
328
|
-
|
|
365
|
+
editToolbarElement.classList.remove('is-visible')
|
|
329
366
|
}
|
|
330
367
|
}
|
|
331
368
|
|
|
332
369
|
onMounted(async () => {
|
|
333
|
-
await
|
|
370
|
+
// await delay(2000)
|
|
371
|
+
await pageBuilderService.completeBuilderInitialization(undefined, true)
|
|
334
372
|
|
|
335
373
|
updatePanelPosition()
|
|
336
374
|
|
|
@@ -525,7 +563,7 @@ onMounted(async () => {
|
|
|
525
563
|
></span>
|
|
526
564
|
</span>
|
|
527
565
|
</div>
|
|
528
|
-
<div>
|
|
566
|
+
<div>{{ $t('button.save') }}</div>
|
|
529
567
|
</button>
|
|
530
568
|
<!-- Save End -->
|
|
531
569
|
|
|
@@ -568,7 +606,7 @@ onMounted(async () => {
|
|
|
568
606
|
</span>
|
|
569
607
|
</div>
|
|
570
608
|
<div class="lg:pbx-block pbx-hidden">
|
|
571
|
-
<span>
|
|
609
|
+
<span>{{ $t('button.resetPage') }}</span>
|
|
572
610
|
</div>
|
|
573
611
|
</button>
|
|
574
612
|
</template>
|
|
@@ -602,10 +640,12 @@ onMounted(async () => {
|
|
|
602
640
|
"
|
|
603
641
|
>
|
|
604
642
|
<div
|
|
605
|
-
class="pbx-flex pbx-items-center pbx-justify-center pbx-gap-2 pbx-border-
|
|
643
|
+
class="pbx-flex pbx-items-center pbx-justify-center pbx-gap-2 pbx-border-gray-200"
|
|
606
644
|
>
|
|
607
645
|
<span class="lg:pbx-block pbx-hidden">
|
|
608
|
-
<div class="pbx-whitespace-nowrap pbx-cursor-pointer">
|
|
646
|
+
<div class="pbx-whitespace-nowrap pbx-cursor-pointer">
|
|
647
|
+
{{ $t('button.addComponents') }}
|
|
648
|
+
</div>
|
|
609
649
|
</span>
|
|
610
650
|
<span
|
|
611
651
|
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"
|
|
@@ -656,18 +696,92 @@ onMounted(async () => {
|
|
|
656
696
|
</div>
|
|
657
697
|
</div>
|
|
658
698
|
</div>
|
|
659
|
-
|
|
660
|
-
<div
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
699
|
+
|
|
700
|
+
<div class="pbx-flex gap-2 pbx-items-center">
|
|
701
|
+
<!-- Options # Start -->
|
|
702
|
+
<div
|
|
703
|
+
@click.self="
|
|
704
|
+
async () => {
|
|
705
|
+
await pageBuilderService.clearHtmlSelection()
|
|
706
|
+
}
|
|
707
|
+
"
|
|
708
|
+
class="pbx-flex pbx-items-center pbx-py-2 pbx-min-h-20 pbx-max-h-20 pbx-w-full"
|
|
709
|
+
:class="[showCloseButton ? 'pbx-justify-between' : 'pbx-justify-end']"
|
|
710
|
+
>
|
|
711
|
+
<ToolbarOption></ToolbarOption>
|
|
712
|
+
</div>
|
|
713
|
+
<!-- Options # Start -->
|
|
714
|
+
</div>
|
|
715
|
+
<!-- Close & Publish buttons start -->
|
|
716
|
+
<template v-if="showPublishButton">
|
|
717
|
+
<div class="pbx-ml-2">
|
|
718
|
+
<button
|
|
719
|
+
class="pbx-myPrimaryButton"
|
|
720
|
+
@click="
|
|
721
|
+
async () => {
|
|
722
|
+
closePublish()
|
|
723
|
+
await pageBuilderService.clearHtmlSelection()
|
|
724
|
+
}
|
|
725
|
+
"
|
|
726
|
+
>
|
|
727
|
+
{{ $t('button.publish') }}
|
|
728
|
+
</button>
|
|
729
|
+
</div>
|
|
730
|
+
</template>
|
|
731
|
+
<!-- Select language -->
|
|
732
|
+
<template
|
|
733
|
+
v-if="
|
|
734
|
+
getPageBuilderConfig &&
|
|
735
|
+
getPageBuilderConfig.userSettings &&
|
|
736
|
+
getPageBuilderConfig.userSettings.language &&
|
|
737
|
+
!getPageBuilderConfig.userSettings.language.disableLanguageDropDown
|
|
665
738
|
"
|
|
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
739
|
>
|
|
669
|
-
<
|
|
670
|
-
|
|
740
|
+
<template
|
|
741
|
+
v-if="
|
|
742
|
+
getPageBuilderConfig &&
|
|
743
|
+
getPageBuilderConfig.userSettings &&
|
|
744
|
+
getPageBuilderConfig.userSettings.language
|
|
745
|
+
"
|
|
746
|
+
>
|
|
747
|
+
<div class="pbx-flex pbx-justify-center pbx-items-center pbx-ml-2">
|
|
748
|
+
<select
|
|
749
|
+
class="pbx-myPrimarySelect pbx-min-w-20 pbx-max-w-2pbx-min-w-20 pbx-w-max"
|
|
750
|
+
v-model="$i18n.locale"
|
|
751
|
+
>
|
|
752
|
+
<template
|
|
753
|
+
v-if="
|
|
754
|
+
Array.isArray(getPageBuilderConfig.userSettings.language.enable) &&
|
|
755
|
+
getPageBuilderConfig.userSettings.language.enable.length >= 1
|
|
756
|
+
"
|
|
757
|
+
>
|
|
758
|
+
<template
|
|
759
|
+
v-for="lang in pageBuilderService
|
|
760
|
+
.availableLanguage()
|
|
761
|
+
.filter((l) => getPageBuilderConfig.userSettings.language.enable.includes(l))"
|
|
762
|
+
:key="lang"
|
|
763
|
+
>
|
|
764
|
+
<option :value="lang">{{ lang }}</option>
|
|
765
|
+
</template>
|
|
766
|
+
</template>
|
|
767
|
+
<template
|
|
768
|
+
v-if="
|
|
769
|
+
!getPageBuilderConfig.userSettings.language.enable ||
|
|
770
|
+
(Array.isArray(getPageBuilderConfig.userSettings.language.enable) &&
|
|
771
|
+
getPageBuilderConfig.userSettings.language.enable.length === 0)
|
|
772
|
+
"
|
|
773
|
+
>
|
|
774
|
+
<template v-for="lang in pageBuilderService.availableLanguage()" :key="lang">
|
|
775
|
+
<option :value="lang">{{ lang }}</option>
|
|
776
|
+
</template>
|
|
777
|
+
</template>
|
|
778
|
+
</select>
|
|
779
|
+
</div>
|
|
780
|
+
</template>
|
|
781
|
+
</template>
|
|
782
|
+
|
|
783
|
+
<template v-if="showCloseButton">
|
|
784
|
+
<div class="pbx-ml-2">
|
|
671
785
|
<button
|
|
672
786
|
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
787
|
@click="
|
|
@@ -679,9 +793,10 @@ onMounted(async () => {
|
|
|
679
793
|
>
|
|
680
794
|
<span class="material-symbols-outlined"> close </span>
|
|
681
795
|
</button>
|
|
682
|
-
</
|
|
683
|
-
</
|
|
684
|
-
|
|
796
|
+
</div>
|
|
797
|
+
</template>
|
|
798
|
+
|
|
799
|
+
<!-- Close & Publish buttons end -->
|
|
685
800
|
</div>
|
|
686
801
|
|
|
687
802
|
<!-- Top Layout Save And Reset Area - End -->
|
|
@@ -728,12 +843,11 @@ onMounted(async () => {
|
|
|
728
843
|
:class="{ 'pbx-mr-2': !getMenuRight, '': getMenuRight }"
|
|
729
844
|
>
|
|
730
845
|
<div
|
|
731
|
-
id="
|
|
732
|
-
class="pbx-z-30 lg:pbx-mx-20 pbx-flex pbx-gap-2 pbx-justify-center pbx-
|
|
846
|
+
id="pbxEditToolbar"
|
|
847
|
+
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
848
|
style="
|
|
734
849
|
box-shadow: 0 0 0 10px oklch(86.9% 0.005 56.366);
|
|
735
850
|
background: oklch(86.9% 0.005 56.366);
|
|
736
|
-
border-radius: 9999px;
|
|
737
851
|
"
|
|
738
852
|
>
|
|
739
853
|
<template v-if="getElement">
|
|
@@ -751,26 +865,14 @@ onMounted(async () => {
|
|
|
751
865
|
</div>
|
|
752
866
|
<!-- Element Popover toolbar end -->
|
|
753
867
|
|
|
754
|
-
<div
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
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>
|
|
868
|
+
<div id="pagebuilder" class="pbx-text-black pbx-font-sans">
|
|
869
|
+
<template v-for="component in getComponents" :key="component.id">
|
|
870
|
+
<section
|
|
871
|
+
v-if="component.html_code"
|
|
872
|
+
v-html="component.html_code"
|
|
873
|
+
@mouseup="handleSelectComponent(component)"
|
|
874
|
+
></section>
|
|
875
|
+
</template>
|
|
774
876
|
</div>
|
|
775
877
|
</main>
|
|
776
878
|
|
|
@@ -781,7 +883,7 @@ onMounted(async () => {
|
|
|
781
883
|
await pageBuilderService.clearHtmlSelection()
|
|
782
884
|
}
|
|
783
885
|
"
|
|
784
|
-
class="pbx-min-w-[
|
|
886
|
+
class="pbx-min-w-[3rem] pbx-pt-6 pbx-pb-2"
|
|
785
887
|
>
|
|
786
888
|
<div
|
|
787
889
|
@click.self="
|
|
@@ -789,15 +891,16 @@ onMounted(async () => {
|
|
|
789
891
|
await pageBuilderService.clearHtmlSelection()
|
|
790
892
|
}
|
|
791
893
|
"
|
|
792
|
-
class="pbx-flex pbx-items-center pbx-justify-center pbx-gap-
|
|
894
|
+
class="pbx-flex pbx-flex-col pbx-items-center pbx-justify-center pbx-gap-2"
|
|
793
895
|
>
|
|
794
896
|
<button
|
|
795
|
-
type="button"
|
|
796
897
|
v-if="!getMenuRight"
|
|
797
898
|
@click="pageBuilderStateStore.setMenuRight(true)"
|
|
798
|
-
|
|
899
|
+
type="button"
|
|
900
|
+
class="pbx-mySecondaryButton"
|
|
799
901
|
>
|
|
800
|
-
<span class="material-symbols-outlined">
|
|
902
|
+
<span class="material-symbols-outlined"> view_sidebar </span>
|
|
903
|
+
<span> Tools </span>
|
|
801
904
|
</button>
|
|
802
905
|
</div>
|
|
803
906
|
</div>
|
|
@@ -806,15 +909,16 @@ onMounted(async () => {
|
|
|
806
909
|
aria-label="Menu"
|
|
807
910
|
id="pagebuilder-right-area"
|
|
808
911
|
:class="{
|
|
809
|
-
'pbx-w-0': !getMenuRight,
|
|
912
|
+
'pbx-w-0 pbx-mr-0': !getMenuRight,
|
|
810
913
|
'pbx-w-80 pbx-mr-2 pbx-bg-myPrimaryLightGrayColor pbx-items-stretch': getMenuRight,
|
|
811
914
|
}"
|
|
812
|
-
class="pbx-duration-
|
|
915
|
+
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
916
|
>
|
|
814
917
|
<RightSidebarEditor @closeEditor="pageBuilderStateStore.setMenuRight(false)">
|
|
815
918
|
</RightSidebarEditor>
|
|
816
919
|
</aside>
|
|
817
920
|
</div>
|
|
921
|
+
|
|
818
922
|
<div
|
|
819
923
|
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
924
|
>
|
|
@@ -828,7 +932,7 @@ onMounted(async () => {
|
|
|
828
932
|
class="pbx-flex pbx-items-center pbx-justify-center pbx-gap-2 pbx-cursor-pointer"
|
|
829
933
|
>
|
|
830
934
|
<span class="lg:pbx-block pbx-hidden">
|
|
831
|
-
<div class="pbx-whitespace-nowrap">
|
|
935
|
+
<div class="pbx-whitespace-nowrap">{{ $t('button.addComponentsToBottom') }}</div>
|
|
832
936
|
</span>
|
|
833
937
|
<div class="pbx-flex pbx-gap-2 pbx-items-center pbx-justify-center">
|
|
834
938
|
<button
|
|
@@ -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
|
-
<
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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>
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
// builderInstance.ts
|
|
2
2
|
import { PageBuilderService } from '../services/PageBuilderService'
|
|
3
|
+
import type { I18n } from 'vue-i18n'
|
|
3
4
|
import { sharedPageBuilderStore } from '../stores/shared-store'
|
|
4
5
|
|
|
5
6
|
// Singleton instance
|
|
6
7
|
let instance: PageBuilderService | null = null
|
|
7
8
|
|
|
8
9
|
// Used to create and store the single instance
|
|
9
|
-
export function initPageBuilder(): PageBuilderService {
|
|
10
|
+
export function initPageBuilder(i18n: I18n): PageBuilderService {
|
|
10
11
|
if (!instance) {
|
|
11
12
|
const pageBuilderStateStore = sharedPageBuilderStore
|
|
12
|
-
instance = new PageBuilderService(pageBuilderStateStore)
|
|
13
|
+
instance = new PageBuilderService(pageBuilderStateStore, i18n)
|
|
13
14
|
}
|
|
14
15
|
return instance
|
|
15
16
|
}
|
|
@@ -25,14 +25,15 @@ export function extractCleanHTMLFromPageBuilder(
|
|
|
25
25
|
}
|
|
26
26
|
})
|
|
27
27
|
|
|
28
|
-
if (config && config
|
|
29
|
-
const imageUrlPrefix = config.
|
|
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
|
-
|
|
35
|
+
// extra safety
|
|
36
|
+
imageUrlPrefix &&
|
|
36
37
|
!src.startsWith(imageUrlPrefix)
|
|
37
38
|
) {
|
|
38
39
|
img.setAttribute('src', imageUrlPrefix + src.replace(/^\/+/, ''))
|
package/src/css/app.css
CHANGED
|
@@ -384,33 +384,10 @@
|
|
|
384
384
|
margin-left: 1em; /* Adjust this value as needed */
|
|
385
385
|
}
|
|
386
386
|
|
|
387
|
-
#
|
|
388
|
-
border-radius: 9999px;
|
|
389
|
-
position: absolute;
|
|
390
|
-
opacity: 0;
|
|
391
|
-
pointer-events: none;
|
|
392
|
-
transform: translateY(1rem);
|
|
393
|
-
transition:
|
|
394
|
-
opacity 0.3s cubic-bezier(0.4, 0, 0.2, 1),
|
|
395
|
-
transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
396
|
-
box-shadow:
|
|
397
|
-
0 8px 24px rgba(0, 0, 0, 0.08),
|
|
398
|
-
0 1.5px 4px rgba(0, 0, 0, 0.06);
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
[selected]:hover #settingsPanel,
|
|
402
|
-
[selected]:focus-within #settingsPanel {
|
|
403
|
-
opacity: 1;
|
|
404
|
-
pointer-events: auto;
|
|
405
|
-
transform: translateY(0);
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
#editToolbar {
|
|
387
|
+
#pbxEditToolbar {
|
|
409
388
|
opacity: 0;
|
|
410
389
|
pointer-events: none;
|
|
411
390
|
transform: translateY(0.1rem) scale(0.1);
|
|
412
|
-
|
|
413
|
-
border-radius: 9999px;
|
|
414
391
|
transition:
|
|
415
392
|
left 0.3s cubic-bezier(0.4, 0, 0.2, 1),
|
|
416
393
|
top 0.3s cubic-bezier(0.4, 0, 0.2, 1),
|
|
@@ -422,28 +399,23 @@
|
|
|
422
399
|
border-radius 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
423
400
|
}
|
|
424
401
|
|
|
425
|
-
#
|
|
402
|
+
#pbxEditToolbar.is-visible {
|
|
426
403
|
opacity: 1;
|
|
427
404
|
pointer-events: auto;
|
|
428
405
|
transform: translateY(0) scale(1);
|
|
429
|
-
min-width:
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
#contains-pagebuilder {
|
|
436
|
-
position: relative; /* make this the positioning context for absolute children */
|
|
437
|
-
overflow-y: auto;
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
.smooth-transition {
|
|
441
|
-
transition: opacity 0.3s ease-in-out;
|
|
406
|
+
min-width: 4rem;
|
|
407
|
+
padding-right: 1rem;
|
|
408
|
+
padding-left: 1rem;
|
|
409
|
+
height: 2.2rem;
|
|
442
410
|
}
|
|
443
411
|
|
|
444
412
|
/* Manage P, Link, H1, H2 # end */
|
|
445
413
|
|
|
446
414
|
/* CSS for content inside page builder # start */
|
|
415
|
+
#pagebuilder {
|
|
416
|
+
position: relative;
|
|
417
|
+
overflow-y: auto;
|
|
418
|
+
}
|
|
447
419
|
#pagebuilder a {
|
|
448
420
|
pointer-events: none;
|
|
449
421
|
}
|
|
@@ -519,38 +491,6 @@
|
|
|
519
491
|
padding: 0rem;
|
|
520
492
|
}
|
|
521
493
|
|
|
522
|
-
/* Add overflow-x property to enable horizontal scrollbar */
|
|
523
|
-
.scrollable {
|
|
524
|
-
overflow-x: auto;
|
|
525
|
-
overflow-y: auto;
|
|
526
|
-
/* Add any other desired styles for the scrollable element */
|
|
527
|
-
}
|
|
528
|
-
/* Scrollbar Styles - end */
|
|
529
|
-
|
|
530
|
-
/* Scrollbar Styles - start */
|
|
531
|
-
/* Firefox */
|
|
532
|
-
* {
|
|
533
|
-
scrollbar-width: thin;
|
|
534
|
-
scrollbar-color: black transparent;
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
*::-webkit-scrollbar-track {
|
|
538
|
-
background: transparent;
|
|
539
|
-
border-radius: 25px;
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
/* Chrome, Edge, and Safari */
|
|
543
|
-
*::-webkit-scrollbar {
|
|
544
|
-
width: 6px;
|
|
545
|
-
height: 6px; /* Add height for horizontal scrollbar */
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
*::-webkit-scrollbar-thumb {
|
|
549
|
-
background-color: black;
|
|
550
|
-
border-radius: 25px;
|
|
551
|
-
border: none;
|
|
552
|
-
}
|
|
553
|
-
|
|
554
494
|
#pagebuilder[data-global-selected] {
|
|
555
495
|
outline: 4px dashed #b91010 !important;
|
|
556
496
|
outline-offset: -2px !important;
|
package/src/i18n.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { createI18n } from 'vue-i18n'
|
|
2
|
+
|
|
3
|
+
// Function to load all locale messages from JSON files
|
|
4
|
+
async function loadLocaleMessages() {
|
|
5
|
+
const locales = import.meta.glob('./locales/*.json')
|
|
6
|
+
const messages: Record<string, object> = {}
|
|
7
|
+
for (const path in locales) {
|
|
8
|
+
const matched = path.match(/([A-Za-z0-9-_]+)\.json$/i)
|
|
9
|
+
if (matched && matched.length > 1) {
|
|
10
|
+
const locale = matched[1]
|
|
11
|
+
const module = (await locales[path]()) as { default: object }
|
|
12
|
+
messages[locale] = module.default
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return messages
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Use this in main.ts: const i18n = await setupI18n()
|
|
19
|
+
export async function setupI18n() {
|
|
20
|
+
const messages = await loadLocaleMessages()
|
|
21
|
+
return createI18n({
|
|
22
|
+
legacy: false, // you must set `false`, to use Composition API
|
|
23
|
+
locale: 'en', // set locale
|
|
24
|
+
fallbackLocale: 'en', // set fallback locale
|
|
25
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
26
|
+
messages: messages as any, // typecast to satisfy vue-i18n
|
|
27
|
+
})
|
|
28
|
+
}
|