@myissue/vue-website-page-builder 3.0.32 → 3.0.34

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": "v3.0.32",
3
+ "version": "v3.0.34",
4
4
  "description": "🚧 DEVELOPMENT VERSION - Vue.js page builder component with drag & drop functionality. Not ready for production use.",
5
5
  "type": "module",
6
6
  "main": "./dist/vue-website-page-builder.umd.cjs",
@@ -7,7 +7,7 @@ import {
7
7
  TransitionRoot,
8
8
  } from '@headlessui/vue'
9
9
  import { provide } from 'vue'
10
- import NoneCustomMediaLibraryComponent from '@/Components/PageBuilder/NoneCustomMediaLibraryComponent.vue'
10
+ import NoneCustomMediaLibraryComponent from '@/Components/PageBuilder/DemoContent/NoneCustomMediaLibraryComponent.vue'
11
11
 
12
12
  const props = defineProps({
13
13
  title: {
@@ -23,6 +23,7 @@ defineProps({
23
23
  },
24
24
  })
25
25
 
26
+ const pageBuilderStateStore = usePageBuilderStateStore(internalPinia)
26
27
  const emit = defineEmits(['firstPageBuilderPreviewModalButton'])
27
28
 
28
29
  // first button function
@@ -38,8 +39,6 @@ const handleEscapeKey = function () {
38
39
  firstButton()
39
40
  }
40
41
 
41
- const pageBuilderStateStore = usePageBuilderStateStore(internalPinia)
42
-
43
42
  const getPageBuilderLogo = computed(() => {
44
43
  return pageBuilderStateStore.getPageBuilderLogo
45
44
  })
@@ -1,23 +1,24 @@
1
1
  <script setup lang="ts">
2
- import componentHelpers from '../../utils/html-elements/componentHelpers'
3
- import components from '../../utils/html-elements/component'
4
- import PageBuilderClass from '../../composables/PageBuilderClass'
5
- import { usePageBuilderModal } from '../../composables/usePageBuilderModal'
6
- import { generateComponentPreview } from '../../utils/componentPreviews'
7
- import type { ComponentObject, PageBuilderStateStore } from '../../types'
2
+ import componentHelpers from '../../../utils/html-elements/componentHelpers'
3
+ import components from '../../../utils/html-elements/component'
4
+ import PageBuilderClass from '../../../composables/PageBuilderClass'
5
+ import { usePageBuilderModal } from '../../../composables/usePageBuilderModal'
6
+ import { generateComponentPreview } from '../../../utils/componentPreviews'
7
+ import type { ComponentObject } from '../../../types'
8
+ import { usePageBuilderStateStore } from '../../../stores/page-builder-state'
9
+ import type { Pinia } from 'pinia'
8
10
 
9
- import { inject, ref } from 'vue'
11
+ import { inject } from 'vue'
10
12
 
11
- // Get stores from parent PageBuilder component
12
- const pageBuilderStateStore = inject<PageBuilderStateStore>('pageBuilderStateStore')
13
+ // Get store from parent PageBuilder component
14
+ const internalPinia = inject('internalPinia') as Pinia
13
15
 
14
16
  // Get modal close function
15
17
  const { closeAddComponentModal } = usePageBuilderModal()
16
18
 
17
- const pageBuilderClass = new PageBuilderClass(pageBuilderStateStore!)
19
+ const pageBuilderStateStore = usePageBuilderStateStore(internalPinia)
18
20
 
19
- // Track image loading states
20
- const imageLoadingStates = ref<Record<string, boolean>>({})
21
+ const pageBuilderClass = new PageBuilderClass(pageBuilderStateStore)
21
22
 
22
23
  // Super simple component addition with professional modal closing!
23
24
  const handleDropComponent = function (componentObject: ComponentObject) {
@@ -74,8 +75,8 @@ const getSvgPreview = (title: string) => {
74
75
  @click="handleDropComponent(helper)"
75
76
  >
76
77
  <div class="max-h-72 cursor-pointer object-contain bg-white mx-auto">
77
- <div class="mr-2" v-html="helper.icon"></div>
78
- <h4 class="myPrimaryParagraph text-sm font-normal">{{ helper.title }}</h4>
78
+ <div v-if="false" class="mr-2" v-html="helper.icon"></div>
79
+ <h4 class="myPrimaryParagraph text-base font-medium">{{ helper.title }}</h4>
79
80
  </div>
80
81
  <div class="myPrimaryParagraph text-xs font-normal pt-2">
81
82
  Click to add {{ helper.title.toLowerCase() }} component
@@ -1,6 +1,6 @@
1
1
  <script setup>
2
2
  import Modal from '@/Components/Modals/Modal.vue'
3
- import NoneCustomSearchComponent from '@/Components/PageBuilder/NoneCustomSearchComponent.vue'
3
+ import NoneCustomSearchComponent from '@/Components/PageBuilder/DemoContent/NoneCustomSearchComponent.vue'
4
4
 
5
5
  const props = defineProps({
6
6
  firstButtonText: {
@@ -400,7 +400,7 @@ onMounted(async () => {
400
400
  >
401
401
  <div class="flex items-center justify-center gap-2">
402
402
  <span class="lg:block hidden">
403
- <div>Add new Elements</div>
403
+ <div>Add new Components</div>
404
404
  </span>
405
405
  <span
406
406
  class="h-10 w-10 cursor-pointer rounded-full flex items-center border-none justify-center bg-gray-50 aspect-square hover:bg-myPrimaryLinkColor hover:text-white focus-visible:ring-0"
@@ -438,12 +438,12 @@ onMounted(async () => {
438
438
  @click="pageBuilderStateStore.setMenuRight(true)"
439
439
  >
440
440
  <div class="flex items-center justify-center gap-2">
441
- <span class="lg:block hidden"> Design </span>
441
+ <span class="lg:block hidden"> Styling </span>
442
442
 
443
443
  <span
444
444
  class="h-10 w-10 cursor-pointer rounded-full flex items-center border-none justify-center bg-gray-50 aspect-square hover:bg-myPrimaryLinkColor hover:text-white focus-visible:ring-0"
445
445
  >
446
- <span class="myMediumIcon material-symbols-outlined"> palette </span>
446
+ <span class="myMediumIcon material-symbols-outlined"> tune </span>
447
447
  </span>
448
448
  </div>
449
449
  </button>
@@ -482,7 +482,7 @@ onMounted(async () => {
482
482
  >
483
483
  <div class="flex items-center justify-center gap-2 font-medium cursor-pointer">
484
484
  <span class="lg:block hidden">
485
- <div>Add new Elements</div>
485
+ <div>Add new Components</div>
486
486
  </span>
487
487
  </div>
488
488
 
@@ -492,7 +492,7 @@ onMounted(async () => {
492
492
  class="myPrimaryButton flex items-center gap-2 justify-center"
493
493
  >
494
494
  <span class="myMediumIcon material-symbols-outlined"> interests </span>
495
- Add new Elements
495
+ Add new Components
496
496
  </button>
497
497
  </div>
498
498
  </div>
@@ -92,7 +92,7 @@ const componentHelpers: ComponentHelper[] = [
92
92
  title: 'Link',
93
93
  icon: `
94
94
  <span class="material-symbols-outlined">
95
- horizontal_rule
95
+ link
96
96
  </span>
97
97
  `,
98
98
  },
@@ -1,30 +0,0 @@
1
- <script setup>
2
- const emit = defineEmits(['handleButton']);
3
-
4
- // first button function
5
- const handleButton = function () {
6
- emit('handleButton');
7
- };
8
- </script>
9
-
10
- <template>
11
- <nav
12
- class="px-6 py-6 mx-auto flex items-center justify-between bg-gray-50 px-4 lg:h-[10vh] h-[16vh]"
13
- aria-label="Global"
14
- >
15
- <img
16
- class="h-6"
17
- src="/logo/logo.svg"
18
- alt="Logo"
19
- />
20
-
21
- <div class="flex lg:gap-x-12 myPrimaryGap">
22
- <p
23
- @click="handleButton"
24
- class="text-lg font-medium text-myPrimaryDarkGrayColor flex gap-2 items-center cursor-pointer"
25
- >
26
- Start Builder
27
- </p>
28
- </div>
29
- </nav>
30
- </template>
@@ -1,33 +0,0 @@
1
- <script setup>
2
- import { ref, computed, onMounted, inject } from 'vue'
3
-
4
- // Get consolidated store from parent PageBuilder component
5
- const pageBuilderStateStore = inject('pageBuilderStateStore')
6
-
7
- const getCurrentImage = computed(() => {
8
- return pageBuilderStateStore.getCurrentImage
9
- })
10
- </script>
11
-
12
- <template>
13
- <!-- Loading # end -->
14
- <div v-if="getCurrentImage && getCurrentImage.src" class="pb-6 space-y-6">
15
- <img
16
- class="mx-auto block w-full object-cover object-center cursor-pointer"
17
- :src="`${getCurrentImage.src}`"
18
- alt="file"
19
- />
20
-
21
- <div class="md:px-3 px-2">
22
- <div>
23
- <h3 class="font-normal text-gray-900">Information</h3>
24
- <dl class="mt-2 border-t border-b border-gray-200 divide-y divide-gray-200">
25
- <div class="py-3 flex justify-between text-sm font-normal items-center">
26
- <dt class="text-gray-500">From</dt>
27
- <dd class="text-gray-900">Unsplash</dd>
28
- </div>
29
- </dl>
30
- </div>
31
- </div>
32
- </div>
33
- </template>
@@ -1,265 +0,0 @@
1
- <script setup>
2
- import { ref, computed, onMounted, inject } from 'vue'
3
- import { useUnsplashStore } from '@/stores/unsplash'
4
-
5
- // Get stores from parent PageBuilder component
6
- const unsplashStore = useUnsplashStore()
7
- const searchQuery = ref('')
8
- const currentPage = ref(1)
9
- const orientation = ref(null)
10
-
11
- const getSearchTerm = computed(() => {
12
- return unsplashStore.getSearchTerm
13
- })
14
- // unspalsh images
15
- const getUnsplashImages = computed(() => {
16
- return unsplashStore.getUnsplashImages
17
- })
18
-
19
- const handleImageClick = function (file) {
20
- pageBuilderStateStore.setCurrentImage({ src: file })
21
- pageBuilderStateStore.setCurrentPreviewImage(null)
22
- }
23
-
24
- // search by orientation
25
- const searchByOrientation = function (orientationParameter) {
26
- // check if search term length is more than 0
27
- if (getSearchTerm.value.length > 0 && orientation.value !== orientationParameter) {
28
- orientation.value = orientationParameter
29
- currentPage.value = 1
30
- searchUnsplash()
31
- }
32
- }
33
- //
34
- // load images for previous page
35
- const previousPage = function () {
36
- searchUnsplash()
37
- }
38
-
39
- // load images for next page
40
- const nextPage = function () {
41
- searchUnsplash()
42
- }
43
- //
44
- //
45
- // search images
46
- const searchUnsplash = function () {
47
- if (
48
- getUnsplashImages.value &&
49
- getUnsplashImages.value.fetchedMedia &&
50
- Array.isArray(getUnsplashImages.value.fetchedMedia.results) &&
51
- getUnsplashImages.value.fetchedMedia.results.length === 0
52
- ) {
53
- currentPage.value = 1
54
- }
55
-
56
- // set values in store
57
-
58
- localStorage.setItem('unsplash-query', searchQuery.value)
59
-
60
- unsplashStore.setSearchTerm(searchQuery.value)
61
- unsplashStore.setCurrentPageNumber(currentPage.value)
62
- unsplashStore.setOrientationValue(orientation.value)
63
- unsplashStore.setLoadUnsplashImages({
64
- searchTerm: getSearchTerm.value,
65
- currentPage: currentPage.value,
66
- orientation: orientation.value,
67
- })
68
- }
69
-
70
- // on mounted
71
- onMounted(() => {
72
- if (localStorage.getItem('unsplash-query') && localStorage.getItem('unsplash-query').length > 0) {
73
- unsplashStore.setSearchTerm(localStorage.getItem('unsplash-query'))
74
- searchQuery.value = localStorage.getItem('unsplash-query')
75
- searchUnsplash()
76
- } else {
77
- searchQuery.value = 'Magazine'
78
- searchUnsplash()
79
- }
80
- })
81
- </script>
82
-
83
- <template>
84
- <div>
85
- <form @submit.prevent="searchUnsplash">
86
- <label
87
- for="default-search"
88
- class="mb-2 text-sm font-normal text-gray-900 sr-only dark:text-gray-300"
89
- >Search</label
90
- >
91
-
92
- <div class="mysearchBarWithOptions">
93
- <div class="relative w-full">
94
- <div class="flex absolute inset-y-0 left-0 items-center pl-3 pointer-events-none">
95
- <span class="material-symbols-outlined"> search </span>
96
- </div>
97
- <input
98
- type="search"
99
- id="search_query"
100
- v-model="searchQuery"
101
- class="myPrimarySearchInput"
102
- autocomplete="off"
103
- placeholder="Search..."
104
- />
105
- </div>
106
-
107
- <button type="submit" class="myPrimaryButton">Search</button>
108
- </div>
109
- </form>
110
-
111
- <div
112
- v-if="
113
- getUnsplashImages &&
114
- !getUnsplashImages.isLoading &&
115
- getUnsplashImages.isError &&
116
- !getUnsplashImages.isSuccess
117
- "
118
- >
119
- <p class="myPrimaryParagraphError">{{ getUnsplashImages.error }}</p>
120
- </div>
121
-
122
- <div
123
- v-if="
124
- getUnsplashImages &&
125
- getUnsplashImages.fetchedMedia &&
126
- getUnsplashImages.fetchedMedia.results &&
127
- !getUnsplashImages.isLoading &&
128
- !getUnsplashImages.isError
129
- "
130
- class="mt-2"
131
- >
132
- <div class="flex lg:justify-between justify-end items-center gap-2 py-2 mb-1">
133
- <div class="lg:flex hidden justify-left items-center gap-2">
134
- <button
135
- @click="searchByOrientation('landscape')"
136
- type="button"
137
- class="myPrimaryTag"
138
- :class="{
139
- 'bg-myPrimaryBrandColor text-white': orientation === 'landscape',
140
- '': orientation !== 'landscape',
141
- }"
142
- >
143
- Landscape
144
- </button>
145
- <button
146
- @click="searchByOrientation('portrait')"
147
- type="button"
148
- class="myPrimaryTag"
149
- :class="{
150
- 'bg-myPrimaryBrandColor text-white': orientation === 'portrait',
151
- '': orientation !== 'portrait',
152
- }"
153
- >
154
- Portrait
155
- </button>
156
- <button
157
- @click="searchByOrientation('squarish')"
158
- type="button"
159
- class="myPrimaryTag"
160
- :class="{
161
- 'bg-myPrimaryBrandColor text-white': orientation === 'squarish',
162
- '': orientation !== 'squarish',
163
- }"
164
- >
165
- Squarish
166
- </button>
167
-
168
- <svg
169
- @click="searchByOrientation(null)"
170
- xmlns="http://www.w3.org/2000/svg"
171
- fill="none"
172
- viewBox="0 0 24 24"
173
- stroke-width="2"
174
- stroke="currentColor"
175
- class="w-4 h-4 cursor-pointer"
176
- >
177
- <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
178
- </svg>
179
- </div>
180
-
181
- <nav class="flex items-center gap-2 justify-start" aria-label="Pagination">
182
- <p class="myPrimaryParagraph text-xs italic">
183
- Total pages {{ getUnsplashImages.fetchedMedia.total_pages }}
184
- </p>
185
- <p class="myPrimaryParagraph text-xs italic">
186
- Images {{ getUnsplashImages.fetchedMedia.total }}
187
- </p>
188
- <div class="flex flex-1 justify-between sm:justify-end items-center gap-2">
189
- <span
190
- v-if="currentPage !== 1"
191
- class="myPrimaryParagraph text-xs italic pr-2 pl-1 cursor-pointer underline"
192
- @click="nextPage((currentPage = 1))"
193
- >
194
- First page
195
- </span>
196
- </div>
197
- <button
198
- v-if="currentPage > 1"
199
- :disabled="currentPage < 1"
200
- class="myPrimaryButton"
201
- @click="previousPage(currentPage--)"
202
- >
203
- {{ `Prev ${currentPage > 0 ? currentPage - 1 : currentPage - 1}` }}
204
- </button>
205
-
206
- <span class="myPrimaryTag p-2.5">
207
- {{ currentPage }}
208
- </span>
209
- <button
210
- :disabled="currentPage >= getUnsplashImages.fetchedMedia.total_pages"
211
- class="myPrimaryButton"
212
- :class="{
213
- 'opacity-50': currentPage >= getUnsplashImages.fetchedMedia.total_pages,
214
- }"
215
- @click="nextPage(currentPage++)"
216
- >
217
- {{ `Next ${currentPage > 0 ? currentPage + 1 : currentPage + 1}` }}
218
- </button>
219
- </nav>
220
- </div>
221
-
222
- <div
223
- class="overflow-y-scroll pr-1 rounded-lg md:min-h-[25.5rem] md:max-h-[25.5em] min-h-[12rem] max-h-[12rem]"
224
- >
225
- <div class="grid md:grid-cols-6 sm:grid-cols-4 grid-cols-2 gap-2">
226
- <div
227
- v-for="image in getUnsplashImages.fetchedMedia.results"
228
- :key="image.id"
229
- @click="handleImageClick(image.urls.regular)"
230
- class="border border-myPrimaryLightGrayColor rounded-lg px-2 p-2 cursor-pointer bg-gray-50"
231
- >
232
- <img
233
- :alt="image.user.name"
234
- class="group aspect-w-10 aspect-h-7 block w-full overflow-hidden rounded-lg bg-gray-100 focus-within:ring-2 focus-within:ring-myPrimaryBrandColor focus-within:ring-offset-2 focus-within:ring-offset-gray-100 cursor-pointer"
235
- :src="image.urls.thumb"
236
- />
237
- <p class="myPrimaryParagraph text-xs font-normal mt-2">By: {{ image.user.name }}</p>
238
- </div>
239
- </div>
240
-
241
- <div v-if="getUnsplashImages.fetchedMedia.results.length < 1">
242
- <p class="myPrimaryParagraph py-4 px-4">
243
- <span v-if="currentPage === 1"> We did not find any images. Make a new search. </span>
244
- <span v-if="currentPage > 1" @click="nextPage(1)" class="myPrimaryLink">
245
- No results on current page. Navigate to First Page.
246
- </span>
247
- </p>
248
- </div>
249
- </div>
250
- </div>
251
-
252
- <div v-if="getUnsplashImages && getUnsplashImages.isLoading && !getUnsplashImages.isError">
253
- <div class="flex items-center justify-center mt-4">
254
- <div
255
- class="inline-block h-8 w-8 animate-spin rounded-full border-4 border-solid border-current border-r-transparent align-[-0.125em] motion-reduce:animate-[spin_1.5s_linear_infinite]"
256
- >
257
- <span
258
- class="!absolute !-m-px !h-px !w-px !overflow-hidden !whitespace-nowrap !border-0 !p-0 ![clip:rect(0,0,0,0)]"
259
- >Loading...</span
260
- >
261
- </div>
262
- </div>
263
- </div>
264
- </div>
265
- </template>
@@ -1,7 +0,0 @@
1
- <script setup>
2
- import { ref, computed, inject } from 'vue'
3
- import PageBuilderClass from '@/composables/PageBuilderClass.ts'
4
-
5
- // Get stores from parent PageBuilder component
6
- const pageBuilderStateStore = inject('pageBuilderStateStore')
7
- </script>
@@ -1,7 +0,0 @@
1
- <template>
2
- <div>
3
- <button class="myPrimaryButton">
4
- <p>Save</p>
5
- </button>
6
- </div>
7
- </template>
@@ -1,8 +0,0 @@
1
- <script setup>
2
- import { ref, onMounted, inject } from 'vue'
3
- import { Switch } from '@headlessui/vue'
4
- import Modal from '@/Components/Modals/Modal.vue'
5
-
6
- // Get stores from parent PageBuilder component
7
- const pageBuilderStateStore = inject('pageBuilderStateStore')
8
- </script>
@@ -1,34 +0,0 @@
1
- const extractAllTextContent = (html: string, maxLength: number): string => {
2
- const parser = new DOMParser()
3
- const doc = parser.parseFromString(html, 'text/html')
4
-
5
- // Extract content from all elements and insert space after each dot
6
- const allElements = doc.body.querySelectorAll('*')
7
- const contentArray = Array.from(allElements).map(
8
- (element) => element.textContent?.trim().replace(/\./g, '. ') || '',
9
- )
10
-
11
- // Join the extracted content into a single string
12
- let content = contentArray.join(' ')
13
- content = content.replace(/\s+/g, ' ')
14
-
15
- // Limit the content to the first maxLength characters
16
- content = content.slice(0, maxLength)
17
-
18
- return content
19
- }
20
-
21
- export const extractTextContentHTML = function extractTextContentHTML(
22
- html: string | null | undefined,
23
- maxLength: number,
24
- postType: string = 'Page',
25
- ): string {
26
- if (html) {
27
- // Extract all text content
28
- const extractedContent = extractAllTextContent(html, maxLength)
29
-
30
- return extractedContent ? extractedContent : `Fashion & Jobs | ${postType}`
31
- } else {
32
- return `Fashion & Jobs | ${postType}`
33
- }
34
- }