@myissue/vue-website-page-builder 3.0.1
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/LICENSE +21 -0
- package/README.md +470 -0
- package/dist/android-chrome-192x192.png +0 -0
- package/dist/android-chrome-512x512.png +0 -0
- package/dist/apple-touch-icon.png +0 -0
- package/dist/browserconfig.xml +9 -0
- package/dist/components.json +36 -0
- package/dist/favicon-16x16.png +0 -0
- package/dist/favicon-32x32.png +0 -0
- package/dist/favicon.ico +0 -0
- package/dist/home/features.jpg +0 -0
- package/dist/home/page-builder-example.jpg +0 -0
- package/dist/logo/logo.svg +49 -0
- package/dist/mstile-310x150.png +0 -0
- package/dist/mstile-310x310.png +0 -0
- package/dist/page-builder/2-images-text-top.png +0 -0
- package/dist/page-builder/2-images.png +0 -0
- package/dist/page-builder/3-images.png +0 -0
- package/dist/page-builder/6-images.png +0 -0
- package/dist/page-builder/image.png +0 -0
- package/dist/page-builder/placeholder.jpg +0 -0
- package/dist/page-builder/two-vertical-images.png +0 -0
- package/dist/placeholder_image.jpg +0 -0
- package/dist/robots.txt +2 -0
- package/dist/vue-website-page-builder.css +1 -0
- package/dist/vue-website-page-builder.js +24794 -0
- package/dist/vue-website-page-builder.umd.cjs +195 -0
- package/package.json +99 -0
- package/src/App.vue +122 -0
- package/src/Components/Homepage/Footer.vue +42 -0
- package/src/Components/Homepage/HomeSection.vue +540 -0
- package/src/Components/Homepage/Navbar.vue +30 -0
- package/src/Components/Layouts/FullWidthElement.vue +34 -0
- package/src/Components/Loaders/FullScreenSpinner.vue +13 -0
- package/src/Components/Loaders/SmallUniversalSpinner.vue +26 -0
- package/src/Components/MediaLibrary/SidebarUnsplash.vue +40 -0
- package/src/Components/MediaLibrary/Unsplash.vue +306 -0
- package/src/Components/Modals/DynamicModal.vue +476 -0
- package/src/Components/Modals/MediaLibraryModal.vue +418 -0
- package/src/Components/Modals/Modal.vue +102 -0
- package/src/Components/Modals/PageBuilderModal.vue +233 -0
- package/src/Components/Modals/PageBuilderPreviewModal.vue +123 -0
- package/src/Components/PageBuilder/DropdownsPlusToggles/OptionsDropdown.vue +202 -0
- package/src/Components/PageBuilder/DropdownsPlusToggles/SaveDesign.vue +7 -0
- package/src/Components/PageBuilder/EditorMenu/Editables/BackgroundColorEditor.vue +91 -0
- package/src/Components/PageBuilder/EditorMenu/Editables/BorderRadius.vue +163 -0
- package/src/Components/PageBuilder/EditorMenu/Editables/Borders.vue +164 -0
- package/src/Components/PageBuilder/EditorMenu/Editables/ClassEditor.vue +80 -0
- package/src/Components/PageBuilder/EditorMenu/Editables/ComponentTopMenu.vue +93 -0
- package/src/Components/PageBuilder/EditorMenu/Editables/DeleteElement.vue +42 -0
- package/src/Components/PageBuilder/EditorMenu/Editables/EditGetElement.vue +338 -0
- package/src/Components/PageBuilder/EditorMenu/Editables/ElementEditor.vue +58 -0
- package/src/Components/PageBuilder/EditorMenu/Editables/ImageEditor.vue +82 -0
- package/src/Components/PageBuilder/EditorMenu/Editables/LinkEditor.vue +301 -0
- package/src/Components/PageBuilder/EditorMenu/Editables/ManageBackgroundOpacity.vue +109 -0
- package/src/Components/PageBuilder/EditorMenu/Editables/ManageOpacity.vue +107 -0
- package/src/Components/PageBuilder/EditorMenu/Editables/OpacityEditor.vue +16 -0
- package/src/Components/PageBuilder/EditorMenu/Editables/PaddingPlusMargin.vue +134 -0
- package/src/Components/PageBuilder/EditorMenu/Editables/TextColorEditor.vue +91 -0
- package/src/Components/PageBuilder/EditorMenu/Editables/Typography.vue +199 -0
- package/src/Components/PageBuilder/EditorMenu/EditorAccordion.vue +42 -0
- package/src/Components/PageBuilder/EditorMenu/RightSidebarEditor.vue +113 -0
- package/src/Components/PageBuilder/Settings/AdvancedPageBuilderSettings.vue +229 -0
- package/src/Components/PageBuilder/Settings/PageBuilderSettings.vue +101 -0
- package/src/Components/PageBuilder/Slidebars/SlideOverRight.vue +91 -0
- package/src/Components/PageBuilder/Slidebars/SlideOverRightParent.vue +91 -0
- package/src/Components/Search/SearchComponents.vue +259 -0
- package/src/Components/TipTap/TipTap.vue +32 -0
- package/src/Components/TipTap/TipTapInput.vue +325 -0
- package/src/PageBuilder/PageBuilder.vue +347 -0
- package/src/PageBuilder/Preview.vue +24 -0
- package/src/composables/PageBuilder.ts +1483 -0
- package/src/composables/delay.ts +5 -0
- package/src/composables/extract-text-content-html.ts +34 -0
- package/src/composables/isObject.ts +6 -0
- package/src/composables/usePromise.ts +10 -0
- package/src/composables/vueFetch.ts +278 -0
- package/src/css/app.css +614 -0
- package/src/index.ts +16 -0
- package/src/main.ts +11 -0
- package/src/stores/media-library.ts +34 -0
- package/src/stores/page-builder-state.ts +461 -0
- package/src/stores/unsplash.ts +107 -0
- package/src/stores/user.ts +30 -0
- package/src/types/global.d.ts +49 -0
- package/src/utils/builder/compiledCSS.ts +2205 -0
- package/src/utils/builder/html-doc-declaration-with-components.ts +7 -0
- package/src/utils/builder/html-elements/componentHelpers.ts +101 -0
- package/src/utils/builder/tailwaind-colors.ts +503 -0
- package/src/utils/builder/tailwind-border-radius.ts +67 -0
- package/src/utils/builder/tailwind-border-style-width-color.ts +272 -0
- package/src/utils/builder/tailwind-font-sizes.ts +76 -0
- package/src/utils/builder/tailwind-font-styles.ts +24 -0
- package/src/utils/builder/tailwind-opacities.ts +45 -0
- package/src/utils/builder/tailwind-padding-margin.ts +159 -0
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { computed, ref } from 'vue'
|
|
3
|
+
import DynamicModal from '@/Components/Modals/DynamicModal.vue'
|
|
4
|
+
import TipTapInput from '@/Components/TipTap/TipTapInput.vue'
|
|
5
|
+
import PageBuilder from '@/composables/PageBuilder.ts'
|
|
6
|
+
import MediaLibraryModal from '@/Components/Modals/MediaLibraryModal.vue'
|
|
7
|
+
import TextColorEditor from '@/Components/PageBuilder/EditorMenu/Editables/TextColorEditor.vue'
|
|
8
|
+
import BackgroundColorEditor from '@/Components/PageBuilder/EditorMenu/Editables/BackgroundColorEditor.vue'
|
|
9
|
+
import { usePageBuilderStateStore } from '@/stores/page-builder-state'
|
|
10
|
+
import { useMediaLibraryStore } from '@/stores/media-library'
|
|
11
|
+
|
|
12
|
+
const mediaLibraryStore = useMediaLibraryStore()
|
|
13
|
+
const pageBuilderStateStore = usePageBuilderStateStore()
|
|
14
|
+
const pageBuilder = new PageBuilder(pageBuilderStateStore, mediaLibraryStore)
|
|
15
|
+
const getElement = computed(() => {
|
|
16
|
+
return pageBuilderStateStore.getElement
|
|
17
|
+
})
|
|
18
|
+
const getShowModalTipTap = computed(() => {
|
|
19
|
+
const result = pageBuilderStateStore.getShowModalTipTap
|
|
20
|
+
|
|
21
|
+
if (result) {
|
|
22
|
+
handleModalPreviewTiptap()
|
|
23
|
+
}
|
|
24
|
+
return result
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
const getRestoredElement = computed(() => {
|
|
28
|
+
return pageBuilderStateStore.getRestoredElement
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
const getComponent = computed(() => {
|
|
32
|
+
return pageBuilderStateStore.getComponent
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
// hanlde Tip Tap modal
|
|
36
|
+
const typeModal = ref('')
|
|
37
|
+
const gridColumnModal = ref(Number(1))
|
|
38
|
+
const titleModal = ref('')
|
|
39
|
+
const descriptionModal = ref('')
|
|
40
|
+
const firstButtonModal = ref('')
|
|
41
|
+
const secondButtonModal = ref(null)
|
|
42
|
+
const thirdButtonModal = ref(null)
|
|
43
|
+
// set dynamic modal handle functions
|
|
44
|
+
const firstModalButtonFunction = ref(null)
|
|
45
|
+
const secondModalButtonFunction = ref(null)
|
|
46
|
+
const thirdModalButtonFunction = ref(null)
|
|
47
|
+
|
|
48
|
+
const handleModalPreviewTiptap = function () {
|
|
49
|
+
pageBuilderStateStore.setShowModalTipTap(true)
|
|
50
|
+
|
|
51
|
+
typeModal.value = 'success'
|
|
52
|
+
gridColumnModal.value = 2
|
|
53
|
+
titleModal.value = 'Manage Content'
|
|
54
|
+
descriptionModal.value = null
|
|
55
|
+
firstButtonModal.value = null
|
|
56
|
+
secondButtonModal.value = null
|
|
57
|
+
thirdButtonModal.value = 'Save'
|
|
58
|
+
|
|
59
|
+
// handle click
|
|
60
|
+
|
|
61
|
+
firstModalButtonFunction.value = function () {
|
|
62
|
+
pageBuilderStateStore.setShowModalTipTap(false)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
thirdModalButtonFunction.value = function () {
|
|
66
|
+
pageBuilderStateStore.setShowModalTipTap(false)
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// handle image
|
|
71
|
+
// get current image from store
|
|
72
|
+
const getBasePrimaryImage = computed(() => {
|
|
73
|
+
return pageBuilderStateStore.getBasePrimaryImage
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
const isLoading = ref(false)
|
|
77
|
+
//
|
|
78
|
+
// use media library
|
|
79
|
+
const showMediaLibraryModal = ref(false)
|
|
80
|
+
// modal content
|
|
81
|
+
const titleMedia = ref('')
|
|
82
|
+
const descriptionMedia = ref('')
|
|
83
|
+
const firstButtonMedia = ref('')
|
|
84
|
+
const secondButtonMedia = ref(null)
|
|
85
|
+
const thirdButtonMedia = ref(null)
|
|
86
|
+
// set dynamic modal handle functions
|
|
87
|
+
const firstMediaButtonFunction = ref(null)
|
|
88
|
+
const secondMediaButtonFunction = ref(null)
|
|
89
|
+
const thirdMediaButtonFunction = ref(null)
|
|
90
|
+
|
|
91
|
+
const handleAddImage = function () {
|
|
92
|
+
// open modal to true
|
|
93
|
+
showMediaLibraryModal.value = true
|
|
94
|
+
|
|
95
|
+
// set media library modal standards
|
|
96
|
+
titleMedia.value = `Media Library`
|
|
97
|
+
descriptionMedia.value = null
|
|
98
|
+
firstButtonMedia.value = 'Close'
|
|
99
|
+
secondButtonMedia.value = 'Select image'
|
|
100
|
+
|
|
101
|
+
// handle click
|
|
102
|
+
firstMediaButtonFunction.value = function () {
|
|
103
|
+
// close media library modal
|
|
104
|
+
showMediaLibraryModal.value = false
|
|
105
|
+
}
|
|
106
|
+
//
|
|
107
|
+
// handle click
|
|
108
|
+
secondMediaButtonFunction.value = function () {
|
|
109
|
+
isLoading.value = true
|
|
110
|
+
pageBuilder.updateBasePrimaryImage({ type: 'unsplash' })
|
|
111
|
+
|
|
112
|
+
// close media library modal
|
|
113
|
+
showMediaLibraryModal.value = false
|
|
114
|
+
isLoading.value = false
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Logic for Video Iframe
|
|
119
|
+
|
|
120
|
+
const urlError = ref(null)
|
|
121
|
+
const iframeSrc = ref('')
|
|
122
|
+
const showModalIframeSrc = ref(false)
|
|
123
|
+
|
|
124
|
+
const validateURL = function () {
|
|
125
|
+
// initial value
|
|
126
|
+
urlError.value = null
|
|
127
|
+
|
|
128
|
+
// url validation
|
|
129
|
+
const urlRegex = /^https?:\/\//
|
|
130
|
+
const isValidURL = ref(true)
|
|
131
|
+
isValidURL.value = urlRegex.test(iframeSrc.value)
|
|
132
|
+
|
|
133
|
+
// cancelled
|
|
134
|
+
if (isValidURL.value === false) {
|
|
135
|
+
urlError.value =
|
|
136
|
+
"The provided URL is invalid. Please ensure that it begins with 'https://' for proper formatting and security."
|
|
137
|
+
return true
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return false
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const handleModalIframeSrc = function () {
|
|
144
|
+
urlError.value = null
|
|
145
|
+
|
|
146
|
+
const iframeSrcValue =
|
|
147
|
+
getElement.value &&
|
|
148
|
+
getElement.value.firstElementChild?.tagName === 'IFRAME' &&
|
|
149
|
+
getElement.value.firstElementChild.hasAttribute('src') &&
|
|
150
|
+
getElement.value.firstElementChild.getAttribute('src').trim() !== ''
|
|
151
|
+
? getElement.value.firstElementChild.src
|
|
152
|
+
: ''
|
|
153
|
+
|
|
154
|
+
iframeSrc.value = iframeSrcValue
|
|
155
|
+
//
|
|
156
|
+
//
|
|
157
|
+
// open modal to true
|
|
158
|
+
showModalIframeSrc.value = true
|
|
159
|
+
|
|
160
|
+
typeModal.value = 'success'
|
|
161
|
+
gridColumnModal.value = 2
|
|
162
|
+
titleModal.value = 'Add video url'
|
|
163
|
+
descriptionModal.value = null
|
|
164
|
+
firstButtonModal.value = 'Close'
|
|
165
|
+
secondButtonModal.value = 'Save'
|
|
166
|
+
thirdButtonModal.value = null
|
|
167
|
+
|
|
168
|
+
// handle click
|
|
169
|
+
firstModalButtonFunction.value = function () {
|
|
170
|
+
showModalIframeSrc.value = false
|
|
171
|
+
}
|
|
172
|
+
// handle click
|
|
173
|
+
secondModalButtonFunction.value = function () {
|
|
174
|
+
const isNotValidated = validateURL()
|
|
175
|
+
if (isNotValidated) {
|
|
176
|
+
return
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (
|
|
180
|
+
getElement.value &&
|
|
181
|
+
getElement.value.firstElementChild &&
|
|
182
|
+
getElement.value.firstElementChild.tagName === 'IFRAME'
|
|
183
|
+
) {
|
|
184
|
+
// Set the src attribute
|
|
185
|
+
|
|
186
|
+
// replace watch with embed
|
|
187
|
+
iframeSrc.value = iframeSrc.value.replace('watch?v=', 'embed/')
|
|
188
|
+
|
|
189
|
+
// Remove dynamic parameters (&ab_channel, &list, &start_radio)
|
|
190
|
+
iframeSrc.value = iframeSrc.value
|
|
191
|
+
.replace(/&ab_channel=[^&]*/, '')
|
|
192
|
+
.replace(/&list=[^&]*/, '')
|
|
193
|
+
.replace(/&start_radio=[^&]*/, '')
|
|
194
|
+
.replace(/&t=[^&]*/, '') // Remove the 't' parameter (time)
|
|
195
|
+
|
|
196
|
+
getElement.value.firstElementChild.src = iframeSrc.value
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
showModalIframeSrc.value = false
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
</script>
|
|
203
|
+
<template>
|
|
204
|
+
<DynamicModal
|
|
205
|
+
:show="showModalIframeSrc"
|
|
206
|
+
maxWidth="2xl"
|
|
207
|
+
:type="typeModal"
|
|
208
|
+
:gridColumnAmount="gridColumnModal"
|
|
209
|
+
:title="titleModal"
|
|
210
|
+
:description="descriptionModal"
|
|
211
|
+
:firstButtonText="firstButtonModal"
|
|
212
|
+
:secondButtonText="secondButtonModal"
|
|
213
|
+
:thirdButtonText="thirdButtonModal"
|
|
214
|
+
@firstModalButtonFunction="firstModalButtonFunction"
|
|
215
|
+
@secondModalButtonFunction="secondModalButtonFunction"
|
|
216
|
+
@thirdModalButtonFunction="thirdModalButtonFunction"
|
|
217
|
+
>
|
|
218
|
+
<header></header>
|
|
219
|
+
<main>
|
|
220
|
+
<div class="myInputGroup">
|
|
221
|
+
<div class="myPrimaryFormOrganizationHeaderDescriptionSection">
|
|
222
|
+
<div class="myPrimaryFormOrganizationHeader">
|
|
223
|
+
<label for="video" class="myPrimaryInputLabel">Video url:</label>
|
|
224
|
+
<input v-model="iframeSrc" type="text" class="myPrimaryInput" name="video" />
|
|
225
|
+
<div v-if="urlError" class="min-h-[2.5rem] flex items-center justify-start">
|
|
226
|
+
<p class="myPrimaryInputError mt-2 mb-0 py-0 self-start">
|
|
227
|
+
{{ urlError }}
|
|
228
|
+
</p>
|
|
229
|
+
</div>
|
|
230
|
+
</div>
|
|
231
|
+
</div>
|
|
232
|
+
</div>
|
|
233
|
+
</main>
|
|
234
|
+
</DynamicModal>
|
|
235
|
+
<DynamicModal
|
|
236
|
+
:simpleModal="true"
|
|
237
|
+
:show="getShowModalTipTap"
|
|
238
|
+
maxWidth="5xl"
|
|
239
|
+
:type="typeModal"
|
|
240
|
+
:gridColumnAmount="gridColumnModal"
|
|
241
|
+
:title="titleModal"
|
|
242
|
+
:description="descriptionModal"
|
|
243
|
+
:firstButtonText="firstButtonModal"
|
|
244
|
+
:secondButtonText="secondButtonModal"
|
|
245
|
+
:thirdButtonText="thirdButtonModal"
|
|
246
|
+
@firstModalButtonFunction="firstModalButtonFunction"
|
|
247
|
+
@secondModalButtonFunction="secondModalButtonFunction"
|
|
248
|
+
@thirdModalButtonFunction="thirdModalButtonFunction"
|
|
249
|
+
>
|
|
250
|
+
<header></header>
|
|
251
|
+
<main class="overflow-y-auto">
|
|
252
|
+
<TipTapInput></TipTapInput>
|
|
253
|
+
</main>
|
|
254
|
+
</DynamicModal>
|
|
255
|
+
|
|
256
|
+
<MediaLibraryModal
|
|
257
|
+
:open="showMediaLibraryModal"
|
|
258
|
+
:title="titleMedia"
|
|
259
|
+
:description="descriptionMedia"
|
|
260
|
+
:firstButtonText="firstButtonMedia"
|
|
261
|
+
:secondButtonText="secondButtonMedia"
|
|
262
|
+
:thirdButtonText="thirdButtonMedia"
|
|
263
|
+
@firstMediaButtonFunction="firstMediaButtonFunction"
|
|
264
|
+
@secondMediaButtonFunction="secondMediaButtonFunction"
|
|
265
|
+
@thirdMediaButtonFunction="thirdMediaButtonFunction"
|
|
266
|
+
>
|
|
267
|
+
</MediaLibraryModal>
|
|
268
|
+
|
|
269
|
+
<div
|
|
270
|
+
class="z-20 py-1 px-2 h-20 flex items-center justify-center mt-2 mx-2 border-b border-myPrimaryLightGrayColor"
|
|
271
|
+
>
|
|
272
|
+
<div class="flex items-center justify-center divide-x divide-gray-200 py-1">
|
|
273
|
+
<template v-if="pageBuilder.ElOrFirstChildIsIframe()">
|
|
274
|
+
<div class="px-2 flex items-center justify-start gap-2">
|
|
275
|
+
<button
|
|
276
|
+
@click="handleModalIframeSrc"
|
|
277
|
+
type="button"
|
|
278
|
+
class="text-[12.5px] gap-2 text-nowrap pl-2 pr-3 w-full h-10 cursor-pointer rounded-full flex items-center border-none justify-center bg-gray-50 hover:bg-myPrimaryLinkColor hover:text-white focus-visible:ring-0"
|
|
279
|
+
>
|
|
280
|
+
<span class="material-symbols-outlined"> play_circle </span>
|
|
281
|
+
<span>Add YouTube</span>
|
|
282
|
+
</button>
|
|
283
|
+
</div>
|
|
284
|
+
</template>
|
|
285
|
+
|
|
286
|
+
<template
|
|
287
|
+
v-if="pageBuilder.selectedElementIsValidText() && !pageBuilder.ElOrFirstChildIsIframe()"
|
|
288
|
+
>
|
|
289
|
+
<div class="px-2 flex items-center justify-start gap-2">
|
|
290
|
+
<button
|
|
291
|
+
@click="handleModalPreviewTiptap"
|
|
292
|
+
type="button"
|
|
293
|
+
class="text-[12.5px] gap-2 text-nowrap pl-2 pr-3 w-full h-10 cursor-pointer rounded-full flex items-center border-none justify-center bg-gray-50 hover:bg-myPrimaryLinkColor hover:text-white focus-visible:ring-0"
|
|
294
|
+
>
|
|
295
|
+
<span class="material-symbols-outlined"> edit </span>
|
|
296
|
+
<span>Edit text</span>
|
|
297
|
+
</button>
|
|
298
|
+
</div>
|
|
299
|
+
<div class="px-2">
|
|
300
|
+
<TextColorEditor></TextColorEditor>
|
|
301
|
+
</div>
|
|
302
|
+
</template>
|
|
303
|
+
|
|
304
|
+
<template
|
|
305
|
+
v-if="
|
|
306
|
+
getElement &&
|
|
307
|
+
getComponent &&
|
|
308
|
+
getBasePrimaryImage !== null &&
|
|
309
|
+
!pageBuilder.ElOrFirstChildIsIframe()
|
|
310
|
+
"
|
|
311
|
+
>
|
|
312
|
+
<div class="px-2 flex items-center justify-start gap-2">
|
|
313
|
+
<button
|
|
314
|
+
@click="handleAddImage"
|
|
315
|
+
type="button"
|
|
316
|
+
class="text-[12.5px] gap-2 text-nowrap pl-2 pr-3 w-full h-10 cursor-pointer rounded-full flex items-center border-none justify-center bg-gray-50 hover:bg-myPrimaryLinkColor hover:text-white focus-visible:ring-0"
|
|
317
|
+
>
|
|
318
|
+
<span class="material-symbols-outlined"> add_photo_alternate </span>
|
|
319
|
+
<span>Update image</span>
|
|
320
|
+
</button>
|
|
321
|
+
</div>
|
|
322
|
+
</template>
|
|
323
|
+
|
|
324
|
+
<template
|
|
325
|
+
v-if="
|
|
326
|
+
getElement &&
|
|
327
|
+
Object.keys(getElement).length !== 0 &&
|
|
328
|
+
!getBasePrimaryImage &&
|
|
329
|
+
!pageBuilder.ElOrFirstChildIsIframe()
|
|
330
|
+
"
|
|
331
|
+
>
|
|
332
|
+
<div class="px-2">
|
|
333
|
+
<BackgroundColorEditor></BackgroundColorEditor>
|
|
334
|
+
</div>
|
|
335
|
+
</template>
|
|
336
|
+
</div>
|
|
337
|
+
</div>
|
|
338
|
+
</template>
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { usePageBuilderStateStore } from '@/stores/page-builder-state'
|
|
3
|
+
import PageBuilder from '@/composables/PageBuilder.ts'
|
|
4
|
+
|
|
5
|
+
const pageBuilderStateStore = usePageBuilderStateStore()
|
|
6
|
+
|
|
7
|
+
import { computed } from 'vue'
|
|
8
|
+
|
|
9
|
+
const pageBuilder = new PageBuilder(pageBuilderStateStore)
|
|
10
|
+
|
|
11
|
+
import EditorAccordion from '@/Components/PageBuilder/EditorMenu/EditorAccordion.vue'
|
|
12
|
+
|
|
13
|
+
const getElement = computed(() => {
|
|
14
|
+
return pageBuilderStateStore.getElement
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
const getRestoredElement = computed(() => {
|
|
18
|
+
return pageBuilderStateStore.getRestoredElement
|
|
19
|
+
})
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<template>
|
|
23
|
+
<EditorAccordion>
|
|
24
|
+
<template #title>Element Editor</template>
|
|
25
|
+
<template #content>
|
|
26
|
+
<div class="flex flex-row flex-wrap gap-2 mt-2"></div>
|
|
27
|
+
<div>
|
|
28
|
+
<!-- delete & restore element # start -->
|
|
29
|
+
<template v-if="getRestoredElement">
|
|
30
|
+
<div class="px-2 flex items-center justify-start gap-2">
|
|
31
|
+
<button
|
|
32
|
+
@click="pageBuilder.handleRestoreElement"
|
|
33
|
+
type="button"
|
|
34
|
+
class="text-[12.5px] gap-2 text-nowrap pl-2 pr-3 w-full h-10 cursor-pointer rounded-full flex items-center border-none justify-center bg-gray-50 hover:bg-myPrimaryLinkColor hover:text-white focus-visible:ring-0"
|
|
35
|
+
>
|
|
36
|
+
<span class="material-symbols-outlined"> undo </span>
|
|
37
|
+
<span>Undo</span>
|
|
38
|
+
</button>
|
|
39
|
+
</div>
|
|
40
|
+
</template>
|
|
41
|
+
|
|
42
|
+
<template v-if="getElement && !getRestoredElement">
|
|
43
|
+
<div class="px-2 flex items-center justify-start gap-2">
|
|
44
|
+
<button
|
|
45
|
+
@click="pageBuilder.handleDeleteElement"
|
|
46
|
+
type="button"
|
|
47
|
+
class="text-[12.5px] gap-2 text-nowrap pl-2 pr-3 w-full h-10 cursor-pointer rounded-full flex items-center border-none justify-center bg-gray-50 hover:text-white focus-visible:ring-0 hover:bg-myPrimaryErrorColor"
|
|
48
|
+
>
|
|
49
|
+
<span class="material-symbols-outlined"> delete </span>
|
|
50
|
+
<span class="hover:text-white">Delete element</span>
|
|
51
|
+
</button>
|
|
52
|
+
</div>
|
|
53
|
+
</template>
|
|
54
|
+
<!-- delete & restore element # end -->
|
|
55
|
+
</div>
|
|
56
|
+
</template>
|
|
57
|
+
</EditorAccordion>
|
|
58
|
+
</template>
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { computed, watch, ref } from 'vue'
|
|
3
|
+
import EditorAccordion from '@/Components/PageBuilder/EditorMenu/EditorAccordion.vue'
|
|
4
|
+
import MediaLibraryModal from '@/Components/Modals/MediaLibraryModal.vue'
|
|
5
|
+
import PageBuilder from '@/composables/PageBuilder.ts'
|
|
6
|
+
import { usePageBuilderStateStore } from '@/stores/page-builder-state'
|
|
7
|
+
import { useMediaLibraryStore } from '@/stores/media-library'
|
|
8
|
+
|
|
9
|
+
const mediaLibraryStore = useMediaLibraryStore()
|
|
10
|
+
const pageBuilderStateStore = usePageBuilderStateStore()
|
|
11
|
+
const pageBuilder = new PageBuilder(pageBuilderStateStore, mediaLibraryStore)
|
|
12
|
+
const isLoading = ref(false)
|
|
13
|
+
|
|
14
|
+
// use media library
|
|
15
|
+
const showMediaLibraryModal = ref(false)
|
|
16
|
+
// modal content
|
|
17
|
+
const titleMedia = ref('')
|
|
18
|
+
const descriptionMedia = ref('')
|
|
19
|
+
const firstButtonMedia = ref('')
|
|
20
|
+
const secondButtonMedia = ref(null)
|
|
21
|
+
const thirdButtonMedia = ref(null)
|
|
22
|
+
// set dynamic modal handle functions
|
|
23
|
+
const firstMediaButtonFunction = ref(null)
|
|
24
|
+
const secondMediaButtonFunction = ref(null)
|
|
25
|
+
const thirdMediaButtonFunction = ref(null)
|
|
26
|
+
|
|
27
|
+
// get current image from store
|
|
28
|
+
const getBasePrimaryImage = computed(() => {
|
|
29
|
+
return pageBuilderStateStore.getBasePrimaryImage
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
const handleAddImage = function () {
|
|
33
|
+
// open modal to true
|
|
34
|
+
showMediaLibraryModal.value = true
|
|
35
|
+
|
|
36
|
+
// set media library modal standards
|
|
37
|
+
titleMedia.value = `Media Library`
|
|
38
|
+
descriptionMedia.value = null
|
|
39
|
+
firstButtonMedia.value = 'Close'
|
|
40
|
+
secondButtonMedia.value = 'Select image'
|
|
41
|
+
|
|
42
|
+
// handle click
|
|
43
|
+
firstMediaButtonFunction.value = function () {
|
|
44
|
+
// close media library modal
|
|
45
|
+
showMediaLibraryModal.value = false
|
|
46
|
+
}
|
|
47
|
+
//
|
|
48
|
+
// handle click
|
|
49
|
+
secondMediaButtonFunction.value = function () {
|
|
50
|
+
isLoading.value = true
|
|
51
|
+
pageBuilder.updateBasePrimaryImage({ type: 'unsplash' })
|
|
52
|
+
|
|
53
|
+
// close media library modal
|
|
54
|
+
showMediaLibraryModal.value = false
|
|
55
|
+
isLoading.value = false
|
|
56
|
+
}
|
|
57
|
+
//
|
|
58
|
+
// end modal
|
|
59
|
+
}
|
|
60
|
+
</script>
|
|
61
|
+
<template>
|
|
62
|
+
<div v-if="getBasePrimaryImage !== null">
|
|
63
|
+
<img
|
|
64
|
+
class="object-cover object-center w-full cursor-pointer"
|
|
65
|
+
:src="getBasePrimaryImage"
|
|
66
|
+
@click="handleAddImage"
|
|
67
|
+
alt="image"
|
|
68
|
+
/>
|
|
69
|
+
</div>
|
|
70
|
+
<MediaLibraryModal
|
|
71
|
+
:open="showMediaLibraryModal"
|
|
72
|
+
:title="titleMedia"
|
|
73
|
+
:description="descriptionMedia"
|
|
74
|
+
:firstButtonText="firstButtonMedia"
|
|
75
|
+
:secondButtonText="secondButtonMedia"
|
|
76
|
+
:thirdButtonText="thirdButtonMedia"
|
|
77
|
+
@firstMediaButtonFunction="firstMediaButtonFunction"
|
|
78
|
+
@secondMediaButtonFunction="secondMediaButtonFunction"
|
|
79
|
+
@thirdMediaButtonFunction="thirdMediaButtonFunction"
|
|
80
|
+
>
|
|
81
|
+
</MediaLibraryModal>
|
|
82
|
+
</template>
|