@myissue/vue-website-page-builder 3.3.95 → 3.3.97
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/dist/style.css +1 -1
- package/dist/vue-website-page-builder.js +6633 -6483
- package/dist/vue-website-page-builder.umd.cjs +41 -41
- package/package.json +1 -1
- package/src/Components/PageBuilder/EditorMenu/Editables/ComponentTopMenu.vue +18 -3
- package/src/Components/PageBuilder/EditorMenu/Editables/EditGetElement.vue +0 -4
- package/src/Components/PageBuilder/EditorMenu/RightSidebarEditor.vue +0 -1
- package/src/Components/PageBuilder/UndoRedo/UndoRedo.vue +87 -0
- package/src/PageBuilder/PageBuilder.vue +18 -34
- package/src/css/style.css +29 -0
- package/src/services/LocalStorageManager.ts +25 -1
- package/src/services/PageBuilderService.ts +194 -58
- package/src/stores/page-builder-state.ts +14 -24
- package/src/tests/DefaultComponents/DefaultBuilderComponents.vue +1 -1
- package/src/tests/pageBuilderService.test.ts +110 -11
- package/src/Components/PageBuilder/EditorMenu/Editables/DeleteElement.vue +0 -42
- package/src/Components/PageBuilder/EditorMenu/Editables/ElementEditor.vue +0 -62
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import DynamicModalBuilder from '../../../Modals/DynamicModalBuilder.vue'
|
|
3
|
-
import { ref } from 'vue'
|
|
3
|
+
import { ref, computed } from 'vue'
|
|
4
4
|
import { getPageBuilder } from '../../../../composables/builderInstance'
|
|
5
5
|
import { useTranslations } from '../../../../composables/useTranslations'
|
|
6
6
|
|
|
@@ -22,6 +22,9 @@ const firstModalButtonFunctionDynamicModalBuilder = ref(null)
|
|
|
22
22
|
const secondModalButtonFunctionDynamicModalBuilder = ref(null)
|
|
23
23
|
const thirdModalButtonFunctionDynamicModalBuilder = ref(null)
|
|
24
24
|
|
|
25
|
+
const canMoveUp = computed(() => pageBuilderService.canMoveUp())
|
|
26
|
+
const canMoveDown = computed(() => pageBuilderService.canMoveDown())
|
|
27
|
+
|
|
25
28
|
// remove component
|
|
26
29
|
const handleDelete = function () {
|
|
27
30
|
showModalDeleteComponent.value = true
|
|
@@ -78,14 +81,26 @@ const handleDelete = function () {
|
|
|
78
81
|
<button
|
|
79
82
|
type="button"
|
|
80
83
|
@click="pageBuilderService.reorderComponent(-1)"
|
|
81
|
-
|
|
84
|
+
:disabled="!canMoveUp"
|
|
85
|
+
class="pbx-h-10 pbx-w-10 pbx-rounded-full pbx-flex pbx-items-center pbx-border-none pbx-justify-center pbx-bg-gray-50 pbx-aspect-square pbx-text-black"
|
|
86
|
+
:class="[
|
|
87
|
+
canMoveUp
|
|
88
|
+
? 'hover:pbx-bg-myPrimaryLinkColor hover:pbx-text-white focus-visible:pbx-ring-0'
|
|
89
|
+
: 'pbx-cursor-not-allowed pbx-bg-opacity-20 hover:pbx-bg-gray-200',
|
|
90
|
+
]"
|
|
82
91
|
>
|
|
83
92
|
<span class="material-symbols-outlined"> move_up </span>
|
|
84
93
|
</button>
|
|
85
94
|
<button
|
|
86
95
|
type="button"
|
|
87
96
|
@click="pageBuilderService.reorderComponent(1)"
|
|
88
|
-
|
|
97
|
+
:disabled="!canMoveDown"
|
|
98
|
+
class="pbx-h-10 pbx-w-10 pbx-rounded-full pbx-flex pbx-items-center pbx-border-none pbx-justify-center pbx-bg-gray-50 pbx-aspect-square pbx-text-black"
|
|
99
|
+
:class="[
|
|
100
|
+
canMoveDown
|
|
101
|
+
? 'hover:pbx-bg-myPrimaryLinkColor hover:pbx-text-white focus-visible:pbx-ring-0'
|
|
102
|
+
: 'pbx-cursor-not-allowed pbx-bg-opacity-20 hover:pbx-bg-gray-200',
|
|
103
|
+
]"
|
|
89
104
|
>
|
|
90
105
|
<span class="material-symbols-outlined"> move_down </span>
|
|
91
106
|
</button>
|
|
@@ -188,10 +188,6 @@ const handleModalIframeSrc = function () {
|
|
|
188
188
|
showModalIframeSrc.value = false
|
|
189
189
|
}
|
|
190
190
|
}
|
|
191
|
-
|
|
192
|
-
const getRestoredElement = computed(() => {
|
|
193
|
-
return pageBuilderStateStore.getRestoredElement
|
|
194
|
-
})
|
|
195
191
|
</script>
|
|
196
192
|
<template v-if="getElement">
|
|
197
193
|
<div>
|
|
@@ -15,7 +15,6 @@ import Borders from './Editables/Borders.vue'
|
|
|
15
15
|
import LinkEditor from './Editables/LinkEditor.vue'
|
|
16
16
|
import TipTap from '../../TipTap/TipTap.vue'
|
|
17
17
|
import EditGetElement from './Editables/EditGetElement.vue'
|
|
18
|
-
import ElementEditor from './Editables/ElementEditor.vue'
|
|
19
18
|
import HTMLEditor from './Editables/HTMLEditor.vue'
|
|
20
19
|
import { getPageBuilder } from '../../../composables/builderInstance'
|
|
21
20
|
import EditorAccordion from '../EditorMenu/EditorAccordion.vue'
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed, ref } from 'vue'
|
|
3
|
+
import { sharedPageBuilderStore } from '../../../stores/shared-store'
|
|
4
|
+
import GlobalLoader from '../../../Components/Loaders/GlobalLoader.vue'
|
|
5
|
+
import { getPageBuilder } from '../../../composables/builderInstance'
|
|
6
|
+
|
|
7
|
+
const pageBuilderService = getPageBuilder()
|
|
8
|
+
|
|
9
|
+
const emit = defineEmits(['toolbar-hide-request'])
|
|
10
|
+
|
|
11
|
+
// Use shared store instance
|
|
12
|
+
const pageBuilderStateStore = sharedPageBuilderStore
|
|
13
|
+
|
|
14
|
+
const getIsLoadingGlobal = computed(() => {
|
|
15
|
+
return pageBuilderStateStore.getIsLoadingGlobal
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
const historyIndex = computed(() => pageBuilderStateStore.getHistoryIndex)
|
|
19
|
+
const historyLength = computed(() => pageBuilderStateStore.getHistoryLength)
|
|
20
|
+
|
|
21
|
+
const canUndo = computed(() => historyIndex.value > 0)
|
|
22
|
+
const canRedo = computed(() => historyIndex.value < historyLength.value - 1)
|
|
23
|
+
|
|
24
|
+
const handleUndo = async function () {
|
|
25
|
+
if (canUndo.value) {
|
|
26
|
+
// Emit event to hide toolbar
|
|
27
|
+
emit('toolbar-hide-request')
|
|
28
|
+
await pageBuilderService.undo()
|
|
29
|
+
await pageBuilderService.clearHtmlSelection()
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const handleRedo = async function () {
|
|
34
|
+
if (canRedo.value) {
|
|
35
|
+
// Emit event to hide toolbar
|
|
36
|
+
emit('toolbar-hide-request')
|
|
37
|
+
await pageBuilderService.redo()
|
|
38
|
+
await pageBuilderService.clearHtmlSelection()
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
</script>
|
|
42
|
+
|
|
43
|
+
<template>
|
|
44
|
+
<GlobalLoader v-if="getIsLoadingGlobal"></GlobalLoader>
|
|
45
|
+
<div
|
|
46
|
+
@click="
|
|
47
|
+
async () => {
|
|
48
|
+
await pageBuilderService.clearHtmlSelection()
|
|
49
|
+
}
|
|
50
|
+
"
|
|
51
|
+
class="pbx-flex-1 pbx-flex pbx-justify-center pbx-items-center pbx-py-2 pbx-w-full gap-1"
|
|
52
|
+
>
|
|
53
|
+
<!-- Undo Start -->
|
|
54
|
+
<button @click="handleUndo" type="button" :disabled="!canUndo">
|
|
55
|
+
<div
|
|
56
|
+
class="pbx-h-10 pbx-w-10 pbx-rounded-full pbx-flex pbx-items-center pbx-border-none pbx-justify-center pbx-bg-gray-50 pbx-aspect-square pbx-text-black hover:pbx-text-white"
|
|
57
|
+
:class="[
|
|
58
|
+
canUndo
|
|
59
|
+
? 'pbx-cursor-pointer hover:pbx-bg-myPrimaryLinkColor focus-visible:pbx-ring-0'
|
|
60
|
+
: 'pbx-cursor-not-allowed pbx-bg-opacity-20 hover:pbx-bg-gray-200',
|
|
61
|
+
]"
|
|
62
|
+
>
|
|
63
|
+
<span class="material-symbols-outlined"> undo </span>
|
|
64
|
+
</div>
|
|
65
|
+
</button>
|
|
66
|
+
<!-- Undo End -->
|
|
67
|
+
<div
|
|
68
|
+
class="pbx-text-xs pbx-text-gray-600 pbx-mx-2 pbx-py-3 pbx-px-2 pbx-border-solid pbx-border pbx-border-gray-200 pbx-rounded-full"
|
|
69
|
+
>
|
|
70
|
+
{{ historyIndex + 1 }}/{{ historyLength }}
|
|
71
|
+
</div>
|
|
72
|
+
<!-- Redo Start -->
|
|
73
|
+
<button @click="handleRedo" type="button" :disabled="!canRedo">
|
|
74
|
+
<div
|
|
75
|
+
class="pbx-h-10 pbx-w-10 pbx-rounded-full pbx-flex pbx-items-center pbx-border-none pbx-justify-center pbx-bg-gray-50 pbx-aspect-square pbx-text-black hover:pbx-text-white"
|
|
76
|
+
:class="[
|
|
77
|
+
canRedo
|
|
78
|
+
? 'pbx-cursor-pointer hover:pbx-bg-myPrimaryLinkColor focus-visible:pbx-ring-0'
|
|
79
|
+
: 'pbx-cursor-not-allowed pbx-bg-opacity-20 hover:pbx-bg-gray-200',
|
|
80
|
+
]"
|
|
81
|
+
>
|
|
82
|
+
<span class="material-symbols-outlined"> redo </span>
|
|
83
|
+
</div>
|
|
84
|
+
</button>
|
|
85
|
+
<!-- Redo End -->
|
|
86
|
+
</div>
|
|
87
|
+
</template>
|
|
@@ -14,6 +14,7 @@ import DynamicModalBuilder from '../Components/Modals/DynamicModalBuilder.vue'
|
|
|
14
14
|
import GlobalLoader from '../Components/Loaders/GlobalLoader.vue'
|
|
15
15
|
import { useTranslations } from '../composables/useTranslations'
|
|
16
16
|
import { getPageBuilder } from '../composables/builderInstance'
|
|
17
|
+
import UndoRedo from '../Components/PageBuilder/UndoRedo/UndoRedo.vue'
|
|
17
18
|
const pageBuilderService = getPageBuilder()
|
|
18
19
|
/**
|
|
19
20
|
* Props for PageBuilder component
|
|
@@ -167,10 +168,6 @@ const getElement = computed(() => {
|
|
|
167
168
|
return pageBuilderStateStore.getElement
|
|
168
169
|
})
|
|
169
170
|
|
|
170
|
-
const getRestoredElement = computed(() => {
|
|
171
|
-
return pageBuilderStateStore.getRestoredElement
|
|
172
|
-
})
|
|
173
|
-
|
|
174
171
|
const getComponents = computed(() => {
|
|
175
172
|
return pageBuilderStateStore.getComponents
|
|
176
173
|
})
|
|
@@ -323,15 +320,19 @@ const ensureBuilderInitialized = function () {
|
|
|
323
320
|
}
|
|
324
321
|
}
|
|
325
322
|
|
|
326
|
-
const
|
|
323
|
+
const pbxBuilderWrapper = ref(null)
|
|
327
324
|
|
|
328
|
-
|
|
329
|
-
|
|
325
|
+
const hideToolbar = function () {
|
|
326
|
+
const toolbar = document.querySelector('#pbxEditToolbar')
|
|
327
|
+
if (toolbar) {
|
|
328
|
+
toolbar.classList.remove('is-visible')
|
|
329
|
+
toolbar.removeAttribute('style')
|
|
330
|
+
}
|
|
331
|
+
}
|
|
330
332
|
|
|
331
333
|
function updatePanelPosition() {
|
|
332
|
-
const container =
|
|
334
|
+
const container = pbxBuilderWrapper.value
|
|
333
335
|
const editToolbarElement = container && container.querySelector('#pbxEditToolbar')
|
|
334
|
-
const restored = getRestoredElement.value
|
|
335
336
|
|
|
336
337
|
if (!container || !editToolbarElement) return
|
|
337
338
|
|
|
@@ -361,16 +362,9 @@ function updatePanelPosition() {
|
|
|
361
362
|
editToolbarElement.style.left = `${left}px`
|
|
362
363
|
editToolbarElement.style.top = `${top}px`
|
|
363
364
|
editToolbarElement.classList.add('is-visible')
|
|
364
|
-
|
|
365
|
-
lastToolbarLeft = left
|
|
366
|
-
lastToolbarTop = top
|
|
367
|
-
} else if (restored && lastToolbarLeft !== null && lastToolbarTop !== null) {
|
|
368
|
-
editToolbarElement.style.position = 'absolute'
|
|
369
|
-
editToolbarElement.style.left = `${lastToolbarLeft}px`
|
|
370
|
-
editToolbarElement.style.top = `${lastToolbarTop}px`
|
|
371
|
-
editToolbarElement.classList.add('is-visible')
|
|
372
365
|
} else {
|
|
373
366
|
editToolbarElement.classList.remove('is-visible')
|
|
367
|
+
editToolbarElement.removeAttribute('style') // Ensure all styles are removed
|
|
374
368
|
}
|
|
375
369
|
}
|
|
376
370
|
|
|
@@ -399,7 +393,7 @@ onMounted(async () => {
|
|
|
399
393
|
updatePanelPosition()
|
|
400
394
|
|
|
401
395
|
// Set up MutationObserver and event listeners
|
|
402
|
-
const container =
|
|
396
|
+
const container = pbxBuilderWrapper.value
|
|
403
397
|
if (!container) return
|
|
404
398
|
|
|
405
399
|
const observer = new MutationObserver(updatePanelPosition)
|
|
@@ -538,6 +532,8 @@ onMounted(async () => {
|
|
|
538
532
|
</template>
|
|
539
533
|
<!-- Logo # end -->
|
|
540
534
|
|
|
535
|
+
<UndoRedo @toolbar-hide-request="hideToolbar"></UndoRedo>
|
|
536
|
+
|
|
541
537
|
<div
|
|
542
538
|
@click.self="
|
|
543
539
|
async () => {
|
|
@@ -866,30 +862,18 @@ onMounted(async () => {
|
|
|
866
862
|
<!-- Left Menu End -->
|
|
867
863
|
|
|
868
864
|
<main
|
|
869
|
-
ref="
|
|
870
|
-
|
|
865
|
+
ref="pbxBuilderWrapper"
|
|
866
|
+
id="page-builder-wrapper"
|
|
867
|
+
class="pbx-transition-all pbx-duration-300 pbx-font-sans pbx-p-1 pbx-flex pbx-flex-col pbx-grow pbx-rounded-tr-2xl pbx-rounded-tl-2xl pbx-border-solid pbx-border pbx-border-gray-200 pbx-items-stretch pbx-text-black pbx-h-[100vh] pbx-overflow-y-scroll pbx-relative pbx-pt-14"
|
|
871
868
|
:class="[getMenuRight ? 'pbx-w-full' : 'pbx-w-full']"
|
|
872
869
|
>
|
|
873
870
|
<div
|
|
874
871
|
id="pbxEditToolbar"
|
|
875
872
|
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"
|
|
876
|
-
style="
|
|
877
|
-
box-shadow: 0 0 0 10px oklch(86.9% 0.005 56.366);
|
|
878
|
-
background: oklch(86.9% 0.005 56.366);
|
|
879
|
-
"
|
|
880
873
|
>
|
|
881
874
|
<template v-if="getElement">
|
|
882
875
|
<EditGetElement></EditGetElement>
|
|
883
876
|
</template>
|
|
884
|
-
<template v-if="getRestoredElement">
|
|
885
|
-
<button
|
|
886
|
-
@click="pageBuilderService.restoreDeletedElementToDOM"
|
|
887
|
-
type="button"
|
|
888
|
-
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-aspect-square hover:pbx-bg-gray-100 hover:pbx-fill-white pbx-bg-gray-200 focus-visible:pbx-ring-0"
|
|
889
|
-
>
|
|
890
|
-
<span class="material-symbols-outlined"> undo </span>
|
|
891
|
-
</button>
|
|
892
|
-
</template>
|
|
893
877
|
</div>
|
|
894
878
|
<!-- Element Popover toolbar end -->
|
|
895
879
|
|
|
@@ -926,7 +910,7 @@ onMounted(async () => {
|
|
|
926
910
|
await pageBuilderService.clearHtmlSelection()
|
|
927
911
|
}
|
|
928
912
|
"
|
|
929
|
-
class="pbx-w-
|
|
913
|
+
class="pbx-w-18 pbx-bg-myPrimaryLightGrayColor pbx-pt-5 pbx-z-20 pbx-flex-shrink-0 pbx-overflow-hidden pbx-border-0 pbx-border-solid pbx-border-l-0 pbx-border-l-gray-600 pbx-rounded-l-2xl pbx-h-[100vh] pbx-pl-2 pbx-pr-2"
|
|
930
914
|
>
|
|
931
915
|
<div
|
|
932
916
|
@click.self="
|
package/src/css/style.css
CHANGED
|
@@ -395,11 +395,14 @@
|
|
|
395
395
|
padding-right: 1rem;
|
|
396
396
|
padding-left: 1rem;
|
|
397
397
|
height: 2.2rem;
|
|
398
|
+
box-shadow: 0 0 0 10px oklch(86.9% 0.005 56.366);
|
|
399
|
+
background: oklch(86.9% 0.005 56.366);
|
|
398
400
|
}
|
|
399
401
|
|
|
400
402
|
/* CSS for content inside page builder # start */
|
|
401
403
|
#pagebuilder {
|
|
402
404
|
position: relative;
|
|
405
|
+
max-height: 100%;
|
|
403
406
|
}
|
|
404
407
|
#pagebuilder a {
|
|
405
408
|
pointer-events: none;
|
|
@@ -475,3 +478,29 @@
|
|
|
475
478
|
list-style: disc !important;
|
|
476
479
|
padding: 0rem;
|
|
477
480
|
}
|
|
481
|
+
|
|
482
|
+
.pbx-reorder-highlight {
|
|
483
|
+
animation: pbx-reorder-flash 0.4s ease-in-out;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
@keyframes pbx-reorder-flash {
|
|
487
|
+
0% {
|
|
488
|
+
box-shadow: 0 0 0 0px rgba(66, 153, 225, 0.7);
|
|
489
|
+
transform: scale(1);
|
|
490
|
+
opacity: 1;
|
|
491
|
+
}
|
|
492
|
+
50% {
|
|
493
|
+
box-shadow: 0 0 0 10px rgba(66, 153, 225, 0);
|
|
494
|
+
transform: scale(0.2); /* Even more shrink */
|
|
495
|
+
opacity: 0.8;
|
|
496
|
+
}
|
|
497
|
+
100% {
|
|
498
|
+
box-shadow: 0 0 0 0px rgba(66, 153, 225, 0);
|
|
499
|
+
transform: scale(1);
|
|
500
|
+
opacity: 1;
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
.pbx-sibling-highlight {
|
|
505
|
+
border: 2px dashed #4299e1; /* Blue dashed border */
|
|
506
|
+
}
|
|
@@ -1 +1,25 @@
|
|
|
1
|
-
export class LocalStorageManager {
|
|
1
|
+
export class LocalStorageManager {
|
|
2
|
+
private static readonly HISTORY_KEY_SUFFIX = '-history'
|
|
3
|
+
private static readonly MAX_HISTORY_SIZE = 10
|
|
4
|
+
|
|
5
|
+
public static getHistory(baseKey: string): any[] {
|
|
6
|
+
const historyKey = baseKey + this.HISTORY_KEY_SUFFIX
|
|
7
|
+
const historyJson = localStorage.getItem(historyKey)
|
|
8
|
+
return historyJson ? JSON.parse(historyJson) : []
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
public static addToHistory(baseKey: string, data: any) {
|
|
12
|
+
const historyKey = baseKey + this.HISTORY_KEY_SUFFIX
|
|
13
|
+
let history = this.getHistory(baseKey)
|
|
14
|
+
history.push(data)
|
|
15
|
+
if (history.length > this.MAX_HISTORY_SIZE) {
|
|
16
|
+
history = history.slice(history.length - this.MAX_HISTORY_SIZE)
|
|
17
|
+
}
|
|
18
|
+
localStorage.setItem(historyKey, JSON.stringify(history))
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
public static clearHistory(baseKey: string) {
|
|
22
|
+
const historyKey = baseKey + this.HISTORY_KEY_SUFFIX
|
|
23
|
+
localStorage.removeItem(historyKey)
|
|
24
|
+
}
|
|
25
|
+
}
|