@xenterprises/nuxt-x-marketing 1.0.3 → 1.1.0

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.
Files changed (62) hide show
  1. package/README.md +130 -11
  2. package/app/components/X/Mark/CodeBlock/index.vue +19 -7
  3. package/app/components/X/Mark/Divider/Glow.vue +25 -19
  4. package/app/components/X/Mark/Section/Stitch.vue +45 -31
  5. package/app/composables/{useParallax.ts → useParallax.js} +6 -7
  6. package/app/composables/{useScrollReveal.ts → useScrollReveal.js} +4 -4
  7. package/package.json +1 -1
  8. package/.claude/settings.local.json +0 -8
  9. package/.nuxtrc +0 -1
  10. package/.playground/app.config.ts +0 -74
  11. package/.playground/app.vue +0 -269
  12. package/.playground/components/AppFooter.vue +0 -103
  13. package/.playground/components/AppHeader.vue +0 -41
  14. package/.playground/components/CodeExample.vue +0 -70
  15. package/.playground/components/ComponentPlayground.vue +0 -117
  16. package/.playground/components/DocsHeader.vue +0 -19
  17. package/.playground/layouts/default.vue +0 -15
  18. package/.playground/layouts/docs-layout.vue +0 -161
  19. package/.playground/layouts/docs.vue +0 -11
  20. package/.playground/nuxt.config.ts +0 -17
  21. package/.playground/pages/blog/author.vue +0 -145
  22. package/.playground/pages/blog/card.vue +0 -149
  23. package/.playground/pages/blog/cta.vue +0 -131
  24. package/.playground/pages/blog/detail.vue +0 -471
  25. package/.playground/pages/blog/list.vue +0 -261
  26. package/.playground/pages/blog/navigation.vue +0 -228
  27. package/.playground/pages/blog/sidebar.vue +0 -279
  28. package/.playground/pages/config.vue +0 -289
  29. package/.playground/pages/content/comparison.vue +0 -253
  30. package/.playground/pages/content/cta.vue +0 -245
  31. package/.playground/pages/content/features.vue +0 -217
  32. package/.playground/pages/content/newsletter-section.vue +0 -260
  33. package/.playground/pages/content/newsletter.vue +0 -200
  34. package/.playground/pages/content/pricing.vue +0 -335
  35. package/.playground/pages/content/testimonials.vue +0 -188
  36. package/.playground/pages/hero.vue +0 -257
  37. package/.playground/pages/index.vue +0 -381
  38. package/.playground/pages/layout/footer.vue +0 -210
  39. package/.playground/pages/layout/legal-footer.vue +0 -121
  40. package/.playground/pages/layout/navbar.vue +0 -285
  41. package/.playground/pages/layout/section.vue +0 -266
  42. package/.playground/pages/layout/x-legal.vue +0 -199
  43. package/.playground/pages/modals/feature-modal.vue +0 -320
  44. package/.playground/pages/modals/image-lightbox.vue +0 -277
  45. package/.playground/pages/modals/video-modal.vue +0 -222
  46. package/.playground/pages/notifications/announcement-bar.vue +0 -164
  47. package/.playground/pages/notifications/cookie-banner.vue +0 -210
  48. package/.playground/pages/notifications/cookie-toast.vue +0 -143
  49. package/.playground/pages/notifications/gdpr.vue +0 -276
  50. package/.playground/pages/notifications/social-proof-toast.vue +0 -515
  51. package/.playground/pages/ui/badge.vue +0 -161
  52. package/.playground/pages/ui/bg-pattern.vue +0 -177
  53. package/.playground/pages/ui/glass-card.vue +0 -179
  54. package/.playground/pages/ui/glow-divider.vue +0 -179
  55. package/.playground/pages/ui/promo-card.vue +0 -259
  56. package/.playground/pages/ui/section-stitch.vue +0 -411
  57. package/.playground/pages/utilities/back-to-top.vue +0 -153
  58. package/.playground/pages/utilities/popup-chat.vue +0 -224
  59. package/componentList.json +0 -2129
  60. package/screenshots/playground-home.png +0 -0
  61. package/tsconfig.json +0 -3
  62. /package/app/composables/{useXBlog.ts → useXBlog.js} +0 -0
@@ -1,320 +0,0 @@
1
- <template>
2
- <div class="min-h-screen">
3
- <div class="bg-white dark:bg-neutral-900 border-b border-neutral-200 dark:border-neutral-800 px-8 py-6">
4
- <h1 class="text-2xl font-bold text-neutral-900 dark:text-white">Feature Modal</h1>
5
- <p class="mt-2 text-neutral-600 dark:text-neutral-400">Full-screen scrollable modal for detailed feature showcases with Apple-style presentation.</p>
6
- </div>
7
-
8
- <div class="p-8 space-y-12">
9
- <!-- Demo Trigger -->
10
- <section>
11
- <h2 class="text-lg font-semibold mb-4">Feature Showcase Modal</h2>
12
- <p class="text-sm text-neutral-500 mb-4">Opens a full-screen scrollable presentation with hero, content blocks, and CTA.</p>
13
- <XMarkModalFeature
14
- :hero="hero"
15
- :blocks="blocks"
16
- :cta="cta"
17
- :button="{ label: 'Explore Feature', size: 'lg', icon: 'i-lucide-maximize-2' }"
18
- @cta-click="handleCtaClick"
19
- />
20
- </section>
21
-
22
- <!-- Button Object -->
23
- <section>
24
- <h2 class="text-lg font-semibold mb-4">Button Object</h2>
25
- <p class="text-sm text-neutral-500 mb-4">Configure the trigger button with a single object prop.</p>
26
- <div class="flex flex-wrap gap-4">
27
- <XMarkModalFeature
28
- :hero="hero"
29
- :blocks="blocks"
30
- :button="{ label: 'Learn More', color: 'primary' }"
31
- />
32
- <XMarkModalFeature
33
- :hero="hero"
34
- :blocks="blocks"
35
- :button="{ label: 'View Details', color: 'secondary', variant: 'outline' }"
36
- />
37
- <XMarkModalFeature
38
- :hero="hero"
39
- :blocks="blocks"
40
- :button="{ label: 'Explore', color: 'neutral', size: 'lg', icon: 'i-lucide-sparkles' }"
41
- />
42
- </div>
43
- </section>
44
-
45
- <!-- Custom Trigger -->
46
- <section>
47
- <h2 class="text-lg font-semibold mb-4">Custom Trigger (Slot)</h2>
48
- <p class="text-sm text-neutral-500 mb-4">Use the default slot for a completely custom trigger.</p>
49
- <XMarkModalFeature
50
- :hero="hero"
51
- :blocks="blocks"
52
- :cta="cta"
53
- >
54
- <UButton size="xl" label="Advanced Analytics" leading-icon="i-lucide-layers" trailing-icon="i-lucide-arrow-right" />
55
- </XMarkModalFeature>
56
- </section>
57
-
58
- <!-- Block Types -->
59
- <section>
60
- <h2 class="text-lg font-semibold mb-4">Available Block Types</h2>
61
- <div class="grid md:grid-cols-3 gap-6">
62
- <article class="p-6 rounded-lg bg-neutral-100 dark:bg-neutral-800">
63
- <h3 class="font-semibold mb-2">Image Block</h3>
64
- <p class="text-sm text-neutral-600 dark:text-neutral-400">Full-screen image section</p>
65
- <pre class="mt-4 text-xs bg-neutral-200 dark:bg-neutral-700 p-2 rounded overflow-x-auto"><code>{
66
- type: 'image',
67
- image: 'url',
68
- alt: 'description'
69
- }</code></pre>
70
- </article>
71
- <article class="p-6 rounded-lg bg-neutral-100 dark:bg-neutral-800">
72
- <h3 class="font-semibold mb-2">Text Block</h3>
73
- <p class="text-sm text-neutral-600 dark:text-neutral-400">Centered text content</p>
74
- <pre class="mt-4 text-xs bg-neutral-200 dark:bg-neutral-700 p-2 rounded overflow-x-auto"><code>{
75
- type: 'text',
76
- title: 'Heading',
77
- body: 'Content...',
78
- bg: 'bg-white'
79
- }</code></pre>
80
- </article>
81
- <article class="p-6 rounded-lg bg-neutral-100 dark:bg-neutral-800">
82
- <h3 class="font-semibold mb-2">Split Block</h3>
83
- <p class="text-sm text-neutral-600 dark:text-neutral-400">Image + text side by side</p>
84
- <pre class="mt-4 text-xs bg-neutral-200 dark:bg-neutral-700 p-2 rounded overflow-x-auto"><code>{
85
- type: 'split',
86
- title: 'Feature',
87
- body: 'Details...',
88
- image: 'url',
89
- imagePosition: 'left',
90
- features: [...]
91
- }</code></pre>
92
- </article>
93
- </div>
94
- </section>
95
-
96
- <!-- Props -->
97
- <section>
98
- <h2 class="text-lg font-semibold mb-4">Props</h2>
99
- <table class="w-full text-sm">
100
- <thead>
101
- <tr class="border-b border-neutral-200 dark:border-neutral-700">
102
- <th class="text-left py-3 px-4">Prop</th>
103
- <th class="text-left py-3 px-4">Type</th>
104
- <th class="text-left py-3 px-4">Default</th>
105
- <th class="text-left py-3 px-4">Description</th>
106
- </tr>
107
- </thead>
108
- <tbody class="divide-y divide-neutral-200 dark:divide-neutral-700">
109
- <tr><td class="py-3 px-4 font-mono text-xs">hero</td><td class="py-3 px-4">Object</td><td class="py-3 px-4">null</td><td class="py-3 px-4">Hero section { image, title, subtitle }</td></tr>
110
- <tr><td class="py-3 px-4 font-mono text-xs">blocks</td><td class="py-3 px-4">Array</td><td class="py-3 px-4">[]</td><td class="py-3 px-4">Array of content blocks</td></tr>
111
- <tr><td class="py-3 px-4 font-mono text-xs">cta</td><td class="py-3 px-4">Object</td><td class="py-3 px-4">null</td><td class="py-3 px-4">CTA section { title, subtitle, button, bg }</td></tr>
112
- <tr><td class="py-3 px-4 font-mono text-xs">button</td><td class="py-3 px-4">Object</td><td class="py-3 px-4">{}</td><td class="py-3 px-4">{ label, color, variant, size, icon }</td></tr>
113
- </tbody>
114
- </table>
115
- </section>
116
-
117
- <!-- Button Object Properties -->
118
- <section>
119
- <h2 class="text-lg font-semibold mb-4">Button Object Properties</h2>
120
- <table class="w-full text-sm">
121
- <thead>
122
- <tr class="border-b border-neutral-200 dark:border-neutral-700">
123
- <th class="text-left py-3 px-4">Property</th>
124
- <th class="text-left py-3 px-4">Type</th>
125
- <th class="text-left py-3 px-4">Default</th>
126
- </tr>
127
- </thead>
128
- <tbody class="divide-y divide-neutral-200 dark:divide-neutral-700">
129
- <tr><td class="py-3 px-4 font-mono text-xs">label</td><td class="py-3 px-4">String</td><td class="py-3 px-4">'Learn More'</td></tr>
130
- <tr><td class="py-3 px-4 font-mono text-xs">color</td><td class="py-3 px-4">String</td><td class="py-3 px-4">'primary'</td></tr>
131
- <tr><td class="py-3 px-4 font-mono text-xs">variant</td><td class="py-3 px-4">String</td><td class="py-3 px-4">'solid'</td></tr>
132
- <tr><td class="py-3 px-4 font-mono text-xs">size</td><td class="py-3 px-4">String</td><td class="py-3 px-4">'md'</td></tr>
133
- <tr><td class="py-3 px-4 font-mono text-xs">icon</td><td class="py-3 px-4">String</td><td class="py-3 px-4">''</td></tr>
134
- </tbody>
135
- </table>
136
- </section>
137
-
138
- <!-- Hero Configuration -->
139
- <section>
140
- <h2 class="text-lg font-semibold mb-4">Hero Configuration</h2>
141
- <pre class="bg-neutral-100 dark:bg-neutral-800 p-4 rounded-lg text-sm overflow-x-auto"><code>hero: {
142
- image: 'https://example.com/hero.jpg',
143
- title: 'Feature Name',
144
- subtitle: 'Feature description'
145
- }</code></pre>
146
- </section>
147
-
148
- <!-- Blocks Configuration -->
149
- <section>
150
- <h2 class="text-lg font-semibold mb-4">Blocks Configuration</h2>
151
- <pre class="bg-neutral-100 dark:bg-neutral-800 p-4 rounded-lg text-sm overflow-x-auto"><code>blocks: [
152
- // Full-width image
153
- {
154
- type: 'image',
155
- image: 'https://example.com/showcase.jpg',
156
- alt: 'Feature showcase'
157
- },
158
-
159
- // Centered text section
160
- {
161
- type: 'text',
162
- title: 'Section Title',
163
- body: 'Detailed explanation of the feature...',
164
- bg: 'bg-neutral-50' // Optional background class
165
- },
166
-
167
- // Split layout with image
168
- {
169
- type: 'split',
170
- title: 'Feature Highlight',
171
- body: 'Description of this specific feature...',
172
- image: 'https://example.com/feature.jpg',
173
- imagePosition: 'left', // 'left' or 'right'
174
- features: [ // Optional bullet points
175
- 'Benefit one',
176
- 'Benefit two',
177
- 'Benefit three'
178
- ],
179
- bg: 'bg-white'
180
- }
181
- ]</code></pre>
182
- </section>
183
-
184
- <!-- CTA Configuration -->
185
- <section>
186
- <h2 class="text-lg font-semibold mb-4">CTA Configuration</h2>
187
- <pre class="bg-neutral-100 dark:bg-neutral-800 p-4 rounded-lg text-sm overflow-x-auto"><code>cta: {
188
- title: 'Ready to get started?',
189
- subtitle: 'Join thousands of satisfied customers',
190
- button: { label: 'Start Free Trial', color: 'primary' },
191
- bg: 'bg-neutral-950' // Optional background class
192
- }</code></pre>
193
- </section>
194
-
195
- <!-- Events -->
196
- <section>
197
- <h2 class="text-lg font-semibold mb-4">Events</h2>
198
- <table class="w-full text-sm">
199
- <thead>
200
- <tr class="border-b border-neutral-200 dark:border-neutral-700">
201
- <th class="text-left py-3 px-4">Event</th>
202
- <th class="text-left py-3 px-4">Description</th>
203
- </tr>
204
- </thead>
205
- <tbody class="divide-y divide-neutral-200 dark:divide-neutral-700">
206
- <tr><td class="py-3 px-4 font-mono text-xs">@open</td><td class="py-3 px-4">Emitted when modal opens</td></tr>
207
- <tr><td class="py-3 px-4 font-mono text-xs">@close</td><td class="py-3 px-4">Emitted when modal closes</td></tr>
208
- <tr><td class="py-3 px-4 font-mono text-xs">@cta-click</td><td class="py-3 px-4">Emitted when CTA button is clicked</td></tr>
209
- </tbody>
210
- </table>
211
- </section>
212
-
213
- <!-- Code Example -->
214
- <section>
215
- <h2 class="text-lg font-semibold mb-4">Code Example</h2>
216
- <CodeExample title="Feature Modal Usage" :code="codeExample" />
217
- </section>
218
- </div>
219
- </div>
220
- </template>
221
-
222
- <script setup>
223
- const codeExample = `<!-- With button trigger (object) -->
224
- <XMarkModalFeature
225
- :hero="{
226
- image: '/images/hero.jpg',
227
- title: 'Advanced Analytics',
228
- subtitle: 'Gain deep insights into your data'
229
- }"
230
- :blocks="[
231
- { type: 'text', title: 'Overview', body: 'Description...' },
232
- { type: 'image', image: '/showcase.jpg', alt: 'Feature showcase' },
233
- {
234
- type: 'split',
235
- title: 'Key Feature',
236
- body: 'Feature details...',
237
- image: '/feature.jpg',
238
- imagePosition: 'right',
239
- features: ['Benefit 1', 'Benefit 2', 'Benefit 3']
240
- }
241
- ]"
242
- :cta="{
243
- title: 'Ready to start?',
244
- subtitle: 'Free 14-day trial',
245
- button: { label: 'Start Free Trial', color: 'primary' }
246
- }"
247
- :button="{ label: 'Learn More', size: 'lg', icon: 'i-lucide-maximize-2' }"
248
- @cta-click="handleCtaClick"
249
- />
250
-
251
- <!-- Custom trigger (slot) -->
252
- <XMarkModalFeature :hero="hero" :blocks="blocks">
253
- <UButton size="lg" label="Explore Feature" leading-icon="i-lucide-layers" />
254
- </XMarkModalFeature>
255
-
256
- <!-- Minimal (no hero/CTA) -->
257
- <XMarkModalFeature
258
- :blocks="blocks"
259
- :button="{ label: 'View Feature' }"
260
- />`
261
-
262
- const hero = {
263
- image: 'https://images.unsplash.com/photo-1451187580459-43490279c0fa?w=1920&h=1080&fit=crop',
264
- title: 'Advanced Analytics',
265
- subtitle: 'Gain deep insights into your data with powerful visualization tools'
266
- }
267
-
268
- const blocks = [
269
- {
270
- type: 'text',
271
- title: 'Understand Your Data Like Never Before',
272
- body: 'Our analytics platform transforms raw data into actionable insights. With real-time dashboards and customizable reports, you can make data-driven decisions faster than ever before.',
273
- bg: 'bg-white dark:bg-neutral-950'
274
- },
275
- {
276
- type: 'image',
277
- image: 'https://images.unsplash.com/photo-1551288049-bebda4e38f71?w=1920&h=1080&fit=crop',
278
- alt: 'Analytics dashboard'
279
- },
280
- {
281
- type: 'split',
282
- title: 'Real-Time Monitoring',
283
- body: 'Track your key metrics as they happen. Our real-time monitoring system ensures you never miss an important trend or anomaly.',
284
- image: 'https://images.unsplash.com/photo-1460925895917-afdab827c52f?w=800&h=600&fit=crop',
285
- imagePosition: 'right',
286
- features: [
287
- 'Live data streaming',
288
- 'Customizable alerts',
289
- 'Trend detection',
290
- 'Anomaly identification'
291
- ],
292
- bg: 'bg-neutral-50 dark:bg-neutral-900'
293
- },
294
- {
295
- type: 'split',
296
- title: 'Powerful Reporting',
297
- body: 'Generate beautiful, shareable reports with just a few clicks. Export to PDF, Excel, or share via link with your team.',
298
- image: 'https://images.unsplash.com/photo-1551434678-e076c223a692?w=800&h=600&fit=crop',
299
- imagePosition: 'left',
300
- features: [
301
- 'Automated report generation',
302
- 'Custom branding options',
303
- 'Scheduled delivery',
304
- 'Interactive charts'
305
- ],
306
- bg: 'bg-white dark:bg-neutral-950'
307
- }
308
- ]
309
-
310
- const cta = {
311
- title: 'Ready to Transform Your Data?',
312
- subtitle: 'Start your free 14-day trial today. No credit card required.',
313
- button: { label: 'Start Free Trial', color: 'primary' },
314
- bg: 'bg-primary-600'
315
- }
316
-
317
- const handleCtaClick = () => {
318
- console.log('CTA clicked!')
319
- }
320
- </script>
@@ -1,277 +0,0 @@
1
- <template>
2
- <div class="min-h-screen">
3
- <div class="bg-white dark:bg-neutral-900 border-b border-neutral-200 dark:border-neutral-800 px-8 py-6">
4
- <h1 class="text-2xl font-bold text-neutral-900 dark:text-white">Image Lightbox</h1>
5
- <p class="mt-2 text-neutral-600 dark:text-neutral-400">Full-screen image viewer with gallery navigation.</p>
6
- </div>
7
-
8
- <div class="p-8 space-y-12">
9
- <!-- Single Image -->
10
- <section>
11
- <h2 class="text-lg font-semibold mb-4">Single Image</h2>
12
- <p class="text-sm text-neutral-500 mb-4">Click to open lightbox</p>
13
- <button
14
- class="rounded-xl overflow-hidden cursor-zoom-in"
15
- @click="openSingle"
16
- >
17
- <img
18
- :src="singleImage[0].src"
19
- :alt="singleImage[0].alt"
20
- class="w-80 h-60 object-cover hover:opacity-90 transition-opacity"
21
- />
22
- </button>
23
- <XMarkModalImage
24
- v-model="singleOpen"
25
- :images="singleImage"
26
- />
27
- </section>
28
-
29
- <!-- Gallery Grid -->
30
- <section>
31
- <h2 class="text-lg font-semibold mb-4">Gallery with Navigation</h2>
32
- <p class="text-sm text-neutral-500 mb-4">Click any image to open gallery. Use arrows or keyboard to navigate.</p>
33
- <div class="grid grid-cols-4 gap-4">
34
- <button
35
- v-for="(image, index) in galleryImages"
36
- :key="index"
37
- class="rounded-lg overflow-hidden aspect-square cursor-zoom-in"
38
- @click="openGallery(index)"
39
- >
40
- <img
41
- :src="image.src"
42
- :alt="image.alt"
43
- class="w-full h-full object-cover hover:opacity-90 transition-opacity"
44
- />
45
- </button>
46
- </div>
47
- <XMarkModalImage
48
- v-model="galleryOpen"
49
- :images="galleryImages"
50
- :start-index="galleryIndex"
51
- :has-counter="true"
52
- />
53
- </section>
54
-
55
- <!-- With Thumbnails -->
56
- <section>
57
- <h2 class="text-lg font-semibold mb-4">With Thumbnail Navigation</h2>
58
- <div class="grid grid-cols-6 gap-2">
59
- <button
60
- v-for="(image, index) in thumbnailImages"
61
- :key="index"
62
- class="rounded-lg overflow-hidden aspect-square cursor-zoom-in"
63
- @click="openThumbnails(index)"
64
- >
65
- <img
66
- :src="image.src"
67
- :alt="image.alt"
68
- class="w-full h-full object-cover hover:opacity-90 transition-opacity"
69
- />
70
- </button>
71
- </div>
72
- <XMarkModalImage
73
- v-model="thumbnailOpen"
74
- :images="thumbnailImages"
75
- :start-index="thumbnailIndex"
76
- :has-counter="true"
77
- :has-thumbnails="true"
78
- />
79
- </section>
80
-
81
- <!-- With Captions -->
82
- <section>
83
- <h2 class="text-lg font-semibold mb-4">With Captions</h2>
84
- <div class="flex gap-4">
85
- <button
86
- v-for="(image, index) in captionImages"
87
- :key="index"
88
- class="rounded-lg overflow-hidden w-48 h-32 cursor-zoom-in"
89
- @click="openCaptions(index)"
90
- >
91
- <img
92
- :src="image.src"
93
- :alt="image.alt"
94
- class="w-full h-full object-cover hover:opacity-90 transition-opacity"
95
- />
96
- </button>
97
- </div>
98
- <XMarkModalImage
99
- v-model="captionOpen"
100
- :images="captionImages"
101
- :start-index="captionIndex"
102
- />
103
- </section>
104
-
105
- <!-- Props -->
106
- <section>
107
- <h2 class="text-lg font-semibold mb-4">Props</h2>
108
- <div class="overflow-x-auto">
109
- <table class="w-full text-sm">
110
- <thead>
111
- <tr class="border-b border-neutral-200 dark:border-neutral-700">
112
- <th class="text-left py-3 px-4 font-medium">Prop</th>
113
- <th class="text-left py-3 px-4 font-medium">Type</th>
114
- <th class="text-left py-3 px-4 font-medium">Default</th>
115
- <th class="text-left py-3 px-4 font-medium">Description</th>
116
- </tr>
117
- </thead>
118
- <tbody class="divide-y divide-neutral-200 dark:divide-neutral-700">
119
- <tr>
120
- <td class="py-3 px-4 font-mono text-xs">v-model</td>
121
- <td class="py-3 px-4">Boolean</td>
122
- <td class="py-3 px-4">false</td>
123
- <td class="py-3 px-4 text-neutral-600 dark:text-neutral-400">Lightbox visibility state</td>
124
- </tr>
125
- <tr>
126
- <td class="py-3 px-4 font-mono text-xs">images</td>
127
- <td class="py-3 px-4">Array</td>
128
- <td class="py-3 px-4">[]</td>
129
- <td class="py-3 px-4 text-neutral-600 dark:text-neutral-400">Array of { src, alt, caption? }</td>
130
- </tr>
131
- <tr>
132
- <td class="py-3 px-4 font-mono text-xs">startIndex</td>
133
- <td class="py-3 px-4">Number</td>
134
- <td class="py-3 px-4">0</td>
135
- <td class="py-3 px-4 text-neutral-600 dark:text-neutral-400">Starting image index for gallery</td>
136
- </tr>
137
- <tr>
138
- <td class="py-3 px-4 font-mono text-xs">hasCounter</td>
139
- <td class="py-3 px-4">Boolean</td>
140
- <td class="py-3 px-4">true</td>
141
- <td class="py-3 px-4 text-neutral-600 dark:text-neutral-400">Show image counter (1/5)</td>
142
- </tr>
143
- <tr>
144
- <td class="py-3 px-4 font-mono text-xs">hasThumbnails</td>
145
- <td class="py-3 px-4">Boolean</td>
146
- <td class="py-3 px-4">false</td>
147
- <td class="py-3 px-4 text-neutral-600 dark:text-neutral-400">Show thumbnail navigation strip</td>
148
- </tr>
149
- </tbody>
150
- </table>
151
- </div>
152
- </section>
153
-
154
- <!-- Image Object -->
155
- <section>
156
- <h2 class="text-lg font-semibold mb-4">Image Object Structure</h2>
157
- <pre class="bg-neutral-100 dark:bg-neutral-800 p-4 rounded-lg text-sm overflow-x-auto"><code>{
158
- src: 'https://example.com/image.jpg', // Required
159
- alt: 'Image description', // Required
160
- caption: 'Optional caption text' // Optional
161
- }</code></pre>
162
- </section>
163
-
164
- <!-- Keyboard Navigation -->
165
- <section>
166
- <h2 class="text-lg font-semibold mb-4">Keyboard Navigation</h2>
167
- <div class="grid md:grid-cols-3 gap-4">
168
- <div class="p-4 rounded-lg bg-neutral-100 dark:bg-neutral-800 text-center">
169
- <kbd class="px-2 py-1 bg-neutral-200 dark:bg-neutral-700 rounded text-sm">Arrow Left</kbd>
170
- <p class="mt-2 text-sm text-neutral-600 dark:text-neutral-400">Previous image</p>
171
- </div>
172
- <div class="p-4 rounded-lg bg-neutral-100 dark:bg-neutral-800 text-center">
173
- <kbd class="px-2 py-1 bg-neutral-200 dark:bg-neutral-700 rounded text-sm">Arrow Right</kbd>
174
- <p class="mt-2 text-sm text-neutral-600 dark:text-neutral-400">Next image</p>
175
- </div>
176
- <div class="p-4 rounded-lg bg-neutral-100 dark:bg-neutral-800 text-center">
177
- <kbd class="px-2 py-1 bg-neutral-200 dark:bg-neutral-700 rounded text-sm">Escape</kbd>
178
- <p class="mt-2 text-sm text-neutral-600 dark:text-neutral-400">Close lightbox</p>
179
- </div>
180
- </div>
181
- </section>
182
-
183
- <!-- Code Example -->
184
- <section>
185
- <h2 class="text-lg font-semibold mb-4">Code Example</h2>
186
- <CodeExample title="Image Lightbox Usage" :code="codeExample" />
187
- </section>
188
- </div>
189
- </div>
190
- </template>
191
-
192
- <script setup>
193
- const codeExample = `<!-- Single image -->
194
- <button @click="lightboxOpen = true">
195
- <img :src="images[0].src" :alt="images[0].alt" />
196
- </button>
197
- <XMarkModalImage
198
- v-model="lightboxOpen"
199
- :images="images"
200
- />
201
-
202
- <!-- Gallery with thumbnails -->
203
- <div class="grid grid-cols-4 gap-4">
204
- <button
205
- v-for="(image, index) in images"
206
- :key="index"
207
- @click="openGallery(index)"
208
- >
209
- <img :src="image.src" :alt="image.alt" />
210
- </button>
211
- </div>
212
- <XMarkModalImage
213
- v-model="galleryOpen"
214
- :images="images"
215
- :start-index="startIndex"
216
- :has-counter="true"
217
- :has-thumbnails="true"
218
- />
219
-
220
- <!-- Image data structure -->
221
- const images = [
222
- { src: 'https://...', alt: 'Image 1', caption: 'Optional caption' },
223
- { src: 'https://...', alt: 'Image 2' }
224
- ]`
225
-
226
- const singleOpen = ref(false)
227
- const singleImage = [
228
- { src: 'https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=1200&h=800&fit=crop', alt: 'Mountain landscape' }
229
- ]
230
-
231
- const openSingle = () => {
232
- singleOpen.value = true
233
- }
234
-
235
- const galleryOpen = ref(false)
236
- const galleryIndex = ref(0)
237
- const galleryImages = [
238
- { src: 'https://images.unsplash.com/photo-1469474968028-56623f02e42e?w=1200&h=800&fit=crop', alt: 'Nature 1' },
239
- { src: 'https://images.unsplash.com/photo-1447752875215-b2761acb3c5d?w=1200&h=800&fit=crop', alt: 'Nature 2' },
240
- { src: 'https://images.unsplash.com/photo-1433086966358-54859d0ed716?w=1200&h=800&fit=crop', alt: 'Nature 3' },
241
- { src: 'https://images.unsplash.com/photo-1501854140801-50d01698950b?w=1200&h=800&fit=crop', alt: 'Nature 4' }
242
- ]
243
-
244
- const openGallery = (index) => {
245
- galleryIndex.value = index
246
- galleryOpen.value = true
247
- }
248
-
249
- const thumbnailOpen = ref(false)
250
- const thumbnailIndex = ref(0)
251
- const thumbnailImages = [
252
- { src: 'https://images.unsplash.com/photo-1519681393784-d120267933ba?w=1200&h=800&fit=crop', alt: 'Mountain 1' },
253
- { src: 'https://images.unsplash.com/photo-1464822759023-fed622ff2c3b?w=1200&h=800&fit=crop', alt: 'Mountain 2' },
254
- { src: 'https://images.unsplash.com/photo-1486870591958-9b9d0d1dda99?w=1200&h=800&fit=crop', alt: 'Mountain 3' },
255
- { src: 'https://images.unsplash.com/photo-1454496522488-7a8e488e8606?w=1200&h=800&fit=crop', alt: 'Mountain 4' },
256
- { src: 'https://images.unsplash.com/photo-1470071459604-3b5ec3a7fe05?w=1200&h=800&fit=crop', alt: 'Mountain 5' },
257
- { src: 'https://images.unsplash.com/photo-1472214103451-9374bd1c798e?w=1200&h=800&fit=crop', alt: 'Mountain 6' }
258
- ]
259
-
260
- const openThumbnails = (index) => {
261
- thumbnailIndex.value = index
262
- thumbnailOpen.value = true
263
- }
264
-
265
- const captionOpen = ref(false)
266
- const captionIndex = ref(0)
267
- const captionImages = [
268
- { src: 'https://images.unsplash.com/photo-1551524164-687a55dd1126?w=1200&h=800&fit=crop', alt: 'Architecture 1', caption: 'Modern Architecture in Downtown' },
269
- { src: 'https://images.unsplash.com/photo-1487958449943-2429e8be8625?w=1200&h=800&fit=crop', alt: 'Architecture 2', caption: 'Glass and Steel Office Building' },
270
- { src: 'https://images.unsplash.com/photo-1479839672679-a46483c0e7c8?w=1200&h=800&fit=crop', alt: 'Architecture 3', caption: 'Historic Church Exterior' }
271
- ]
272
-
273
- const openCaptions = (index) => {
274
- captionIndex.value = index
275
- captionOpen.value = true
276
- }
277
- </script>