@myissue/vue-website-page-builder 3.0.21 → 3.0.23

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.21",
3
+ "version": "v3.0.23",
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",
@@ -3,9 +3,10 @@ import componentHelpers from '../../utils/html-elements/componentHelpers'
3
3
  import components from '../../utils/html-elements/component'
4
4
  import PageBuilderClass from '../../composables/PageBuilderClass'
5
5
  import { usePageBuilderModal } from '../../composables/usePageBuilderModal'
6
+ import { generateComponentPreview } from '../../utils/componentPreviews'
6
7
  import type { ComponentObject, PageBuilderStateStore, MediaLibraryStore } from '../../types'
7
8
 
8
- import { inject } from 'vue'
9
+ import { inject, ref } from 'vue'
9
10
 
10
11
  // Get stores from parent PageBuilder component
11
12
  const pageBuilderStateStore = inject<PageBuilderStateStore>('pageBuilderStateStore')
@@ -16,6 +17,9 @@ const { closeAddComponentModal } = usePageBuilderModal()
16
17
 
17
18
  const pageBuilderClass = new PageBuilderClass(pageBuilderStateStore!, mediaLibraryStore!)
18
19
 
20
+ // Track image loading states
21
+ const imageLoadingStates = ref<Record<string, boolean>>({})
22
+
19
23
  // Super simple component addition with professional modal closing!
20
24
  const handleDropComponent = function (componentObject: ComponentObject) {
21
25
  pageBuilderClass.addComponent(componentObject)
@@ -30,6 +34,28 @@ const convertToComponentObject = function (comp: any): ComponentObject {
30
34
  title: comp.title,
31
35
  }
32
36
  }
37
+
38
+ // Handle image load errors
39
+ const handleImageError = (event: Event, title: string) => {
40
+ const img = event.target as HTMLImageElement
41
+ const container = img.parentElement
42
+ if (container) {
43
+ // Generate and set SVG preview
44
+ const svgPreview = generateComponentPreview(title)
45
+ container.innerHTML = `<div class="w-full h-full flex items-center justify-center">${svgPreview}</div>`
46
+ }
47
+ }
48
+
49
+ // Check if we should show SVG preview instead of image
50
+ const shouldShowSvgPreview = (comp: any) => {
51
+ // Always show SVG preview for better reliability
52
+ return true
53
+ }
54
+
55
+ // Get SVG preview for component
56
+ const getSvgPreview = (title: string) => {
57
+ return generateComponentPreview(title)
58
+ }
33
59
  </script>
34
60
 
35
61
  <style scoped>
@@ -72,13 +98,11 @@ const convertToComponentObject = function (comp: any): ComponentObject {
72
98
  <div
73
99
  class="overflow-hidden whitespace-pre-line flex-1 h-auto border-b border-gray-200 lg:py-10 py-8 px-2"
74
100
  >
75
- <img
76
- v-if="comp.cover_image"
77
- :src="comp.cover_image"
78
- :alt="comp.title"
79
- class="max-h-72 cursor-pointer object-contain bg-white mx-auto"
80
- />
81
- <div v-else class="text-gray-500">{{ comp.title }}</div>
101
+ <!-- Use SVG preview instead of external images -->
102
+ <div
103
+ class="max-h-72 cursor-pointer bg-white mx-auto flex items-center justify-center"
104
+ v-html="getSvgPreview(comp.title)"
105
+ ></div>
82
106
  </div>
83
107
  <div class="p-3">
84
108
  <h4 class="myPrimaryParagraph text-sm font-normal">{{ comp.title }}</h4>
@@ -241,7 +241,10 @@ onMounted(async () => {
241
241
  <Preview></Preview>
242
242
  </PageBuilderPreviewModal>
243
243
 
244
- <div class="w-full inset-x-0 h-[90vh] z-10 bg-white overflow-x-scroll lg:pt-2 pt-2">
244
+ <div
245
+ id="builder-container"
246
+ class="w-full inset-x-0 h-[90vh] z-10 bg-white overflow-x-scroll lg:pt-2 pt-2"
247
+ >
245
248
  <!-- Save laylout # start -->
246
249
  <div class="p-4 m-8 bg-stone-200 rounded-lg">
247
250
  <div
package/src/css/app.css CHANGED
@@ -1,4 +1,6 @@
1
- /* Google Material Icons - Auto-loaded for vue-website-page-builder */
1
+ /* Google Fonts - Auto-loaded for vue-website-page-builder */
2
+ @import url('https://fonts.googleapis.com/css2?family=Jost:ital,wght@0,100;0,200;0,300;0,400;0,500;1,100;1,200;1,300;1,400;1,500&display=swap');
3
+ @import url('https://fonts.googleapis.com/css2?family=Cormorant:ital,wght@0,300;0,400;0,500;0,600;1,300;1,400;1,500;1,600&display=swap');
2
4
  @import url('https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0');
3
5
 
4
6
  @tailwind base;
@@ -504,13 +506,11 @@ h3 {
504
506
  /* CSS for content inside page builder # start */
505
507
  #page-builder-editor-editable-area a {
506
508
  pointer-events: none;
507
- /* display: block;
508
- width: 100%; */
509
509
  }
510
510
 
511
511
  #page-builder-editor-editable-area #youtube-video::before {
512
512
  content: 'Select video element';
513
- font-family: 'Jost';
513
+ font-family: 'Jost', sans-serif;
514
514
  display: inline-block;
515
515
  margin-right: 8px;
516
516
  vertical-align: middle;
@@ -574,6 +574,9 @@ h3 {
574
574
  --dp-common-transition: all 0.1s ease-in; /*Generic transition applied on buttons and calendar cells*/
575
575
  }
576
576
 
577
+ #builder-container {
578
+ font-family: 'Jost', sans-serif;
579
+ }
577
580
  .dp__action_row {
578
581
  display: flex !important;
579
582
  align-items: center !important;
@@ -0,0 +1,170 @@
1
+ // Component Preview Generator
2
+ // Generates SVG previews for components to avoid external image dependencies
3
+
4
+ export interface ComponentPreviewConfig {
5
+ title: string
6
+ svg: string
7
+ description?: string
8
+ }
9
+
10
+ export const generateComponentPreview = (title: string): string => {
11
+ const previewConfigs: Record<string, ComponentPreviewConfig> = {
12
+ 'Single Image': {
13
+ title: 'Single Image',
14
+ svg: `
15
+ <svg viewBox="0 0 200 150" class="w-full h-full">
16
+ <rect x="20" y="20" width="160" height="110" fill="#f3f4f6" stroke="#d1d5db" stroke-width="2" rx="8"/>
17
+ <rect x="40" y="40" width="120" height="70" fill="#e5e7eb" rx="4"/>
18
+ <circle cx="70" cy="60" r="8" fill="#9ca3af"/>
19
+ <path d="M85 75 L95 65 L110 80 L125 70 L135 85" stroke="#9ca3af" stroke-width="2" fill="none"/>
20
+ <text x="100" y="125" text-anchor="middle" fill="#6b7280" font-size="12">Single Image</text>
21
+ </svg>
22
+ `,
23
+ },
24
+ '2 vertical images': {
25
+ title: '2 Vertical Images',
26
+ svg: `
27
+ <svg viewBox="0 0 200 150" class="w-full h-full">
28
+ <rect x="10" y="20" width="70" height="110" fill="#f3f4f6" stroke="#d1d5db" stroke-width="2" rx="8"/>
29
+ <rect x="120" y="20" width="70" height="110" fill="#f3f4f6" stroke="#d1d5db" stroke-width="2" rx="8"/>
30
+ <rect x="20" y="30" width="50" height="90" fill="#e5e7eb" rx="4"/>
31
+ <rect x="130" y="30" width="50" height="90" fill="#e5e7eb" rx="4"/>
32
+ <text x="100" y="145" text-anchor="middle" fill="#6b7280" font-size="10">2 Vertical Images</text>
33
+ </svg>
34
+ `,
35
+ },
36
+ '2 images': {
37
+ title: '2 Images',
38
+ svg: `
39
+ <svg viewBox="0 0 200 150" class="w-full h-full">
40
+ <rect x="20" y="30" width="70" height="70" fill="#f3f4f6" stroke="#d1d5db" stroke-width="2" rx="8"/>
41
+ <rect x="110" y="30" width="70" height="70" fill="#f3f4f6" stroke="#d1d5db" stroke-width="2" rx="8"/>
42
+ <rect x="30" y="40" width="50" height="50" fill="#e5e7eb" rx="4"/>
43
+ <rect x="120" y="40" width="50" height="50" fill="#e5e7eb" rx="4"/>
44
+ <text x="100" y="125" text-anchor="middle" fill="#6b7280" font-size="12">2 Images</text>
45
+ </svg>
46
+ `,
47
+ },
48
+ '3 images': {
49
+ title: '3 Images',
50
+ svg: `
51
+ <svg viewBox="0 0 200 150" class="w-full h-full">
52
+ <rect x="10" y="30" width="50" height="50" fill="#f3f4f6" stroke="#d1d5db" stroke-width="2" rx="6"/>
53
+ <rect x="75" y="30" width="50" height="50" fill="#f3f4f6" stroke="#d1d5db" stroke-width="2" rx="6"/>
54
+ <rect x="140" y="30" width="50" height="50" fill="#f3f4f6" stroke="#d1d5db" stroke-width="2" rx="6"/>
55
+ <text x="100" y="110" text-anchor="middle" fill="#6b7280" font-size="12">3 Images</text>
56
+ </svg>
57
+ `,
58
+ },
59
+ '6 Images Grid': {
60
+ title: '6 Images Grid',
61
+ svg: `
62
+ <svg viewBox="0 0 200 150" class="w-full h-full">
63
+ <rect x="20" y="20" width="45" height="35" fill="#f3f4f6" stroke="#d1d5db" stroke-width="1" rx="4"/>
64
+ <rect x="77" y="20" width="45" height="35" fill="#f3f4f6" stroke="#d1d5db" stroke-width="1" rx="4"/>
65
+ <rect x="135" y="20" width="45" height="35" fill="#f3f4f6" stroke="#d1d5db" stroke-width="1" rx="4"/>
66
+ <rect x="20" y="67" width="45" height="35" fill="#f3f4f6" stroke="#d1d5db" stroke-width="1" rx="4"/>
67
+ <rect x="77" y="67" width="45" height="35" fill="#f3f4f6" stroke="#d1d5db" stroke-width="1" rx="4"/>
68
+ <rect x="135" y="67" width="45" height="35" fill="#f3f4f6" stroke="#d1d5db" stroke-width="1" rx="4"/>
69
+ <text x="100" y="125" text-anchor="middle" fill="#6b7280" font-size="10">6 Images Grid</text>
70
+ </svg>
71
+ `,
72
+ },
73
+ 'Two Images With Right Text Top': {
74
+ title: 'Images + Text',
75
+ svg: `
76
+ <svg viewBox="0 0 200 150" class="w-full h-full">
77
+ <rect x="20" y="20" width="35" height="35" fill="#f3f4f6" stroke="#d1d5db" stroke-width="2" rx="4"/>
78
+ <rect x="20" y="65" width="35" height="35" fill="#f3f4f6" stroke="#d1d5db" stroke-width="2" rx="4"/>
79
+ <rect x="70" y="25" width="110" height="8" fill="#e5e7eb" rx="4"/>
80
+ <rect x="70" y="40" width="90" height="6" fill="#f3f4f6" rx="3"/>
81
+ <rect x="70" y="50" width="100" height="6" fill="#f3f4f6" rx="3"/>
82
+ <rect x="70" y="60" width="80" height="6" fill="#f3f4f6" rx="3"/>
83
+ <text x="100" y="130" text-anchor="middle" fill="#6b7280" font-size="10">Images + Text</text>
84
+ </svg>
85
+ `,
86
+ },
87
+ '3 Vertical Images': {
88
+ title: '3 Vertical Images',
89
+ svg: `
90
+ <svg viewBox="0 0 200 150" class="w-full h-full">
91
+ <rect x="15" y="20" width="45" height="80" fill="#f3f4f6" stroke="#d1d5db" stroke-width="2" rx="6"/>
92
+ <rect x="77" y="20" width="45" height="80" fill="#f3f4f6" stroke="#d1d5db" stroke-width="2" rx="6"/>
93
+ <rect x="140" y="20" width="45" height="80" fill="#f3f4f6" stroke="#d1d5db" stroke-width="2" rx="6"/>
94
+ <text x="100" y="125" text-anchor="middle" fill="#6b7280" font-size="10">3 Vertical Images</text>
95
+ </svg>
96
+ `,
97
+ },
98
+ 'Link Button': {
99
+ title: 'Link Button',
100
+ svg: `
101
+ <svg viewBox="0 0 200 150" class="w-full h-full">
102
+ <rect x="50" y="60" width="100" height="30" fill="#3b82f6" stroke="#2563eb" stroke-width="2" rx="15"/>
103
+ <text x="100" y="78" text-anchor="middle" fill="white" font-size="12" font-weight="500">Link Button</text>
104
+ <path d="M75 75 L80 70 M80 70 L80 80 M80 70 L70 70" stroke="white" stroke-width="2" fill="none"/>
105
+ <text x="100" y="110" text-anchor="middle" fill="#6b7280" font-size="10">Link Button</text>
106
+ </svg>
107
+ `,
108
+ },
109
+ '4 Images With Text': {
110
+ title: '4 Images + Text',
111
+ svg: `
112
+ <svg viewBox="0 0 200 150" class="w-full h-full">
113
+ <rect x="15" y="15" width="35" height="25" fill="#f3f4f6" stroke="#d1d5db" stroke-width="1" rx="3"/>
114
+ <rect x="60" y="15" width="35" height="25" fill="#f3f4f6" stroke="#d1d5db" stroke-width="1" rx="3"/>
115
+ <rect x="105" y="15" width="35" height="25" fill="#f3f4f6" stroke="#d1d5db" stroke-width="1" rx="3"/>
116
+ <rect x="150" y="15" width="35" height="25" fill="#f3f4f6" stroke="#d1d5db" stroke-width="1" rx="3"/>
117
+ <rect x="15" y="45" width="35" height="4" fill="#e5e7eb" rx="2"/>
118
+ <rect x="60" y="45" width="35" height="4" fill="#e5e7eb" rx="2"/>
119
+ <rect x="105" y="45" width="35" height="4" fill="#e5e7eb" rx="2"/>
120
+ <rect x="150" y="45" width="35" height="4" fill="#e5e7eb" rx="2"/>
121
+ <text x="100" y="70" text-anchor="middle" fill="#6b7280" font-size="9">4 Images + Text</text>
122
+ </svg>
123
+ `,
124
+ },
125
+ '3 Images With Text': {
126
+ title: '3 Images + Text',
127
+ svg: `
128
+ <svg viewBox="0 0 200 150" class="w-full h-full">
129
+ <rect x="25" y="20" width="40" height="30" fill="#f3f4f6" stroke="#d1d5db" stroke-width="1" rx="4"/>
130
+ <rect x="80" y="20" width="40" height="30" fill="#f3f4f6" stroke="#d1d5db" stroke-width="1" rx="4"/>
131
+ <rect x="135" y="20" width="40" height="30" fill="#f3f4f6" stroke="#d1d5db" stroke-width="1" rx="4"/>
132
+ <rect x="25" y="55" width="40" height="5" fill="#e5e7eb" rx="2"/>
133
+ <rect x="80" y="55" width="40" height="5" fill="#e5e7eb" rx="2"/>
134
+ <rect x="135" y="55" width="40" height="5" fill="#e5e7eb" rx="2"/>
135
+ <text x="100" y="85" text-anchor="middle" fill="#6b7280" font-size="10">3 Images + Text</text>
136
+ </svg>
137
+ `,
138
+ },
139
+ '2 Images With Text': {
140
+ title: '2 Images + Text',
141
+ svg: `
142
+ <svg viewBox="0 0 200 150" class="w-full h-full">
143
+ <rect x="40" y="25" width="50" height="40" fill="#f3f4f6" stroke="#d1d5db" stroke-width="2" rx="6"/>
144
+ <rect x="110" y="25" width="50" height="40" fill="#f3f4f6" stroke="#d1d5db" stroke-width="2" rx="6"/>
145
+ <rect x="40" y="75" width="50" height="6" fill="#e5e7eb" rx="3"/>
146
+ <rect x="110" y="75" width="50" height="6" fill="#e5e7eb" rx="3"/>
147
+ <text x="100" y="105" text-anchor="middle" fill="#6b7280" font-size="10">2 Images + Text</text>
148
+ </svg>
149
+ `,
150
+ },
151
+ }
152
+
153
+ const config = previewConfigs[title]
154
+ if (config) {
155
+ return config.svg
156
+ }
157
+
158
+ // Default fallback preview
159
+ return `
160
+ <svg viewBox="0 0 200 150" class="w-full h-full">
161
+ <rect x="20" y="20" width="160" height="110" fill="#f9fafb" stroke="#e5e7eb" stroke-width="2" rx="8" stroke-dasharray="5,5"/>
162
+ <text x="100" y="70" text-anchor="middle" fill="#6b7280" font-size="14" font-weight="500">${title}</text>
163
+ <text x="100" y="90" text-anchor="middle" fill="#9ca3af" font-size="10">Component Preview</text>
164
+ </svg>
165
+ `
166
+ }
167
+
168
+ export default {
169
+ generateComponentPreview,
170
+ }