@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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@myissue/vue-website-page-builder",
3
- "version": "3.3.95",
3
+ "version": "3.3.97",
4
4
  "description": "Vue 3 page builder component with drag & drop functionality.",
5
5
  "type": "module",
6
6
  "main": "./dist/vue-website-page-builder.umd.cjs",
@@ -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
- 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 pbx-text-black hover:pbx-text-white"
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
- 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 pbx-text-black hover:pbx-text-white"
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 pbxToolBar = ref(null)
323
+ const pbxBuilderWrapper = ref(null)
327
324
 
328
- let lastToolbarLeft = null
329
- let lastToolbarTop = null
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 = pbxToolBar.value
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 = pbxToolBar.value
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="pbxToolBar"
870
- 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-auto"
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-16 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"
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
+ }