@xenterprises/nuxt-x-marketing 1.0.2 → 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.
- package/README.md +130 -11
- package/app/components/X/Mark/CodeBlock/index.vue +19 -7
- package/app/components/X/Mark/Divider/Glow.vue +25 -19
- package/app/components/X/Mark/Section/Stitch.vue +45 -31
- package/app/composables/{useParallax.ts → useParallax.js} +6 -7
- package/app/composables/{useScrollReveal.ts → useScrollReveal.js} +4 -4
- package/nuxt.config.ts +1 -11
- package/package.json +1 -1
- package/.claude/settings.local.json +0 -23
- package/.nuxtrc +0 -1
- package/.playground/app.config.ts +0 -74
- package/.playground/app.vue +0 -269
- package/.playground/components/AppFooter.vue +0 -103
- package/.playground/components/AppHeader.vue +0 -41
- package/.playground/components/CodeExample.vue +0 -70
- package/.playground/components/ComponentPlayground.vue +0 -117
- package/.playground/components/DocsHeader.vue +0 -19
- package/.playground/layouts/default.vue +0 -15
- package/.playground/layouts/docs-layout.vue +0 -161
- package/.playground/layouts/docs.vue +0 -11
- package/.playground/nuxt.config.ts +0 -5
- package/.playground/package-lock.json +0 -6
- package/.playground/pages/blog/author.vue +0 -145
- package/.playground/pages/blog/card.vue +0 -149
- package/.playground/pages/blog/cta.vue +0 -131
- package/.playground/pages/blog/detail.vue +0 -471
- package/.playground/pages/blog/list.vue +0 -261
- package/.playground/pages/blog/navigation.vue +0 -228
- package/.playground/pages/blog/sidebar.vue +0 -279
- package/.playground/pages/config.vue +0 -289
- package/.playground/pages/content/comparison.vue +0 -253
- package/.playground/pages/content/cta.vue +0 -245
- package/.playground/pages/content/features.vue +0 -217
- package/.playground/pages/content/newsletter-section.vue +0 -260
- package/.playground/pages/content/newsletter.vue +0 -200
- package/.playground/pages/content/pricing.vue +0 -335
- package/.playground/pages/content/testimonials.vue +0 -188
- package/.playground/pages/hero.vue +0 -257
- package/.playground/pages/index.vue +0 -381
- package/.playground/pages/layout/footer.vue +0 -210
- package/.playground/pages/layout/legal-footer.vue +0 -121
- package/.playground/pages/layout/navbar.vue +0 -285
- package/.playground/pages/layout/section.vue +0 -266
- package/.playground/pages/layout/x-legal.vue +0 -199
- package/.playground/pages/modals/feature-modal.vue +0 -320
- package/.playground/pages/modals/image-lightbox.vue +0 -277
- package/.playground/pages/modals/video-modal.vue +0 -222
- package/.playground/pages/notifications/announcement-bar.vue +0 -164
- package/.playground/pages/notifications/cookie-banner.vue +0 -210
- package/.playground/pages/notifications/cookie-toast.vue +0 -143
- package/.playground/pages/notifications/gdpr.vue +0 -276
- package/.playground/pages/notifications/social-proof-toast.vue +0 -515
- package/.playground/pages/ui/badge.vue +0 -161
- package/.playground/pages/ui/bg-pattern.vue +0 -177
- package/.playground/pages/ui/glass-card.vue +0 -179
- package/.playground/pages/ui/glow-divider.vue +0 -179
- package/.playground/pages/ui/promo-card.vue +0 -259
- package/.playground/pages/ui/section-stitch.vue +0 -411
- package/.playground/pages/utilities/back-to-top.vue +0 -153
- package/.playground/pages/utilities/popup-chat.vue +0 -224
- package/componentList.json +0 -2129
- package/screenshots/playground-home.png +0 -0
- package/tsconfig.json +0 -3
- /package/app/composables/{useXBlog.ts → useXBlog.js} +0 -0
|
@@ -1,222 +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">Video Modal</h1>
|
|
5
|
-
<p class="mt-2 text-neutral-600 dark:text-neutral-400">Cinematic video modal with built-in triggers, multiple sizes, and dark overlay.</p>
|
|
6
|
-
</div>
|
|
7
|
-
|
|
8
|
-
<div class="p-8 space-y-12">
|
|
9
|
-
<!-- Thumbnail Trigger -->
|
|
10
|
-
<section>
|
|
11
|
-
<h2 class="text-lg font-semibold mb-4">Thumbnail Trigger</h2>
|
|
12
|
-
<p class="text-sm text-neutral-500 mb-4">Click the thumbnail to open the video modal. Play button overlay is automatic.</p>
|
|
13
|
-
<div class="max-w-lg">
|
|
14
|
-
<XMarkModalVideo
|
|
15
|
-
src="https://www.youtube.com/watch?v=dQw4w9WgXcQ"
|
|
16
|
-
thumbnail="https://images.unsplash.com/photo-1611162617474-5b21e879e113?w=600&h=340&fit=crop"
|
|
17
|
-
title="Sample YouTube Video"
|
|
18
|
-
description="YouTube videos are automatically embedded with autoplay support."
|
|
19
|
-
/>
|
|
20
|
-
</div>
|
|
21
|
-
</section>
|
|
22
|
-
|
|
23
|
-
<!-- Modal Sizes -->
|
|
24
|
-
<section>
|
|
25
|
-
<h2 class="text-lg font-semibold mb-4">Modal Sizes</h2>
|
|
26
|
-
<p class="text-sm text-neutral-500 mb-4">Control the modal width with the size prop.</p>
|
|
27
|
-
<div class="flex flex-wrap gap-4">
|
|
28
|
-
<XMarkModalVideo
|
|
29
|
-
src="https://www.youtube.com/watch?v=dQw4w9WgXcQ"
|
|
30
|
-
size="2xl"
|
|
31
|
-
:button="{ label: 'Size 2xl' }"
|
|
32
|
-
/>
|
|
33
|
-
<XMarkModalVideo
|
|
34
|
-
src="https://www.youtube.com/watch?v=dQw4w9WgXcQ"
|
|
35
|
-
size="4xl"
|
|
36
|
-
:button="{ label: 'Size 4xl (default)' }"
|
|
37
|
-
/>
|
|
38
|
-
<XMarkModalVideo
|
|
39
|
-
src="https://www.youtube.com/watch?v=dQw4w9WgXcQ"
|
|
40
|
-
size="6xl"
|
|
41
|
-
:button="{ label: 'Size 6xl' }"
|
|
42
|
-
/>
|
|
43
|
-
<XMarkModalVideo
|
|
44
|
-
src="https://www.youtube.com/watch?v=dQw4w9WgXcQ"
|
|
45
|
-
size="full"
|
|
46
|
-
:button="{ label: 'Size full (95vw)' }"
|
|
47
|
-
/>
|
|
48
|
-
</div>
|
|
49
|
-
</section>
|
|
50
|
-
|
|
51
|
-
<!-- Button Object -->
|
|
52
|
-
<section>
|
|
53
|
-
<h2 class="text-lg font-semibold mb-4">Button Object</h2>
|
|
54
|
-
<p class="text-sm text-neutral-500 mb-4">Configure the trigger button with a single object prop.</p>
|
|
55
|
-
<div class="flex flex-wrap gap-4">
|
|
56
|
-
<XMarkModalVideo
|
|
57
|
-
src="https://vimeo.com/76979871"
|
|
58
|
-
title="Vimeo Video"
|
|
59
|
-
:button="{ label: 'Watch Vimeo', color: 'primary' }"
|
|
60
|
-
/>
|
|
61
|
-
<XMarkModalVideo
|
|
62
|
-
src="https://www.youtube.com/watch?v=dQw4w9WgXcQ"
|
|
63
|
-
:button="{ label: 'Play Video', color: 'secondary', variant: 'outline' }"
|
|
64
|
-
/>
|
|
65
|
-
<XMarkModalVideo
|
|
66
|
-
src="https://www.w3schools.com/html/mov_bbb.mp4"
|
|
67
|
-
title="Direct Video"
|
|
68
|
-
:button="{ label: 'View Demo', color: 'neutral', size: 'lg', icon: 'i-lucide-video' }"
|
|
69
|
-
:autoplay="false"
|
|
70
|
-
/>
|
|
71
|
-
</div>
|
|
72
|
-
</section>
|
|
73
|
-
|
|
74
|
-
<!-- Custom Trigger -->
|
|
75
|
-
<section>
|
|
76
|
-
<h2 class="text-lg font-semibold mb-4">Custom Trigger (Slot)</h2>
|
|
77
|
-
<p class="text-sm text-neutral-500 mb-4">Use the default slot for a completely custom trigger.</p>
|
|
78
|
-
<XMarkModalVideo
|
|
79
|
-
src="https://www.youtube.com/watch?v=dQw4w9WgXcQ"
|
|
80
|
-
title="Custom Trigger Demo"
|
|
81
|
-
size="5xl"
|
|
82
|
-
>
|
|
83
|
-
<UButton size="lg" label="Watch the Demo" leading-icon="i-lucide-play" />
|
|
84
|
-
</XMarkModalVideo>
|
|
85
|
-
</section>
|
|
86
|
-
|
|
87
|
-
<!-- Minimal (No Title) -->
|
|
88
|
-
<section>
|
|
89
|
-
<h2 class="text-lg font-semibold mb-4">Minimal Modal (No Footer)</h2>
|
|
90
|
-
<p class="text-sm text-neutral-500 mb-4">Omit title/description for a clean, video-only modal.</p>
|
|
91
|
-
<XMarkModalVideo
|
|
92
|
-
src="https://www.youtube.com/watch?v=dQw4w9WgXcQ"
|
|
93
|
-
:button="{ label: 'Clean Modal', variant: 'subtle' }"
|
|
94
|
-
/>
|
|
95
|
-
</section>
|
|
96
|
-
|
|
97
|
-
<!-- Props -->
|
|
98
|
-
<section>
|
|
99
|
-
<h2 class="text-lg font-semibold mb-4">Props</h2>
|
|
100
|
-
<table class="w-full text-sm">
|
|
101
|
-
<thead>
|
|
102
|
-
<tr class="border-b border-neutral-200 dark:border-neutral-700">
|
|
103
|
-
<th class="text-left py-3 px-4">Prop</th>
|
|
104
|
-
<th class="text-left py-3 px-4">Type</th>
|
|
105
|
-
<th class="text-left py-3 px-4">Default</th>
|
|
106
|
-
<th class="text-left py-3 px-4">Description</th>
|
|
107
|
-
</tr>
|
|
108
|
-
</thead>
|
|
109
|
-
<tbody class="divide-y divide-neutral-200 dark:divide-neutral-700">
|
|
110
|
-
<tr><td class="py-3 px-4 font-mono text-xs">src</td><td class="py-3 px-4">String</td><td class="py-3 px-4">required</td><td class="py-3 px-4">Video URL (YouTube, Vimeo, or direct)</td></tr>
|
|
111
|
-
<tr><td class="py-3 px-4 font-mono text-xs">thumbnail</td><td class="py-3 px-4">String</td><td class="py-3 px-4">''</td><td class="py-3 px-4">Thumbnail image (shows image with play button)</td></tr>
|
|
112
|
-
<tr><td class="py-3 px-4 font-mono text-xs">title</td><td class="py-3 px-4">String</td><td class="py-3 px-4">''</td><td class="py-3 px-4">Video title (shown in footer)</td></tr>
|
|
113
|
-
<tr><td class="py-3 px-4 font-mono text-xs">description</td><td class="py-3 px-4">String</td><td class="py-3 px-4">''</td><td class="py-3 px-4">Video description (shown in footer)</td></tr>
|
|
114
|
-
<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">'4xl'</td><td class="py-3 px-4">lg, xl, 2xl, 3xl, 4xl, 5xl, 6xl, 7xl, full</td></tr>
|
|
115
|
-
<tr><td class="py-3 px-4 font-mono text-xs">autoplay</td><td class="py-3 px-4">Boolean</td><td class="py-3 px-4">true</td><td class="py-3 px-4">Autoplay when modal opens</td></tr>
|
|
116
|
-
<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>
|
|
117
|
-
<tr><td class="py-3 px-4 font-mono text-xs">poster</td><td class="py-3 px-4">String</td><td class="py-3 px-4">''</td><td class="py-3 px-4">Poster image for direct videos</td></tr>
|
|
118
|
-
<tr><td class="py-3 px-4 font-mono text-xs">captions</td><td class="py-3 px-4">String</td><td class="py-3 px-4">''</td><td class="py-3 px-4">Captions file URL</td></tr>
|
|
119
|
-
</tbody>
|
|
120
|
-
</table>
|
|
121
|
-
</section>
|
|
122
|
-
|
|
123
|
-
<!-- Button Object -->
|
|
124
|
-
<section>
|
|
125
|
-
<h2 class="text-lg font-semibold mb-4">Button Object Properties</h2>
|
|
126
|
-
<table class="w-full text-sm">
|
|
127
|
-
<thead>
|
|
128
|
-
<tr class="border-b border-neutral-200 dark:border-neutral-700">
|
|
129
|
-
<th class="text-left py-3 px-4">Property</th>
|
|
130
|
-
<th class="text-left py-3 px-4">Type</th>
|
|
131
|
-
<th class="text-left py-3 px-4">Default</th>
|
|
132
|
-
</tr>
|
|
133
|
-
</thead>
|
|
134
|
-
<tbody class="divide-y divide-neutral-200 dark:divide-neutral-700">
|
|
135
|
-
<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">'Watch Video'</td></tr>
|
|
136
|
-
<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>
|
|
137
|
-
<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>
|
|
138
|
-
<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>
|
|
139
|
-
<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">'i-lucide-play'</td></tr>
|
|
140
|
-
</tbody>
|
|
141
|
-
</table>
|
|
142
|
-
</section>
|
|
143
|
-
|
|
144
|
-
<!-- Supported Formats -->
|
|
145
|
-
<section>
|
|
146
|
-
<h2 class="text-lg font-semibold mb-4">Supported Video Sources</h2>
|
|
147
|
-
<div class="grid md:grid-cols-3 gap-4">
|
|
148
|
-
<div class="p-4 rounded-lg bg-neutral-100 dark:bg-neutral-800">
|
|
149
|
-
<h3 class="font-medium mb-2">YouTube</h3>
|
|
150
|
-
<ul class="text-sm text-neutral-600 dark:text-neutral-400 space-y-1">
|
|
151
|
-
<li>youtube.com/watch?v=...</li>
|
|
152
|
-
<li>youtu.be/...</li>
|
|
153
|
-
<li>youtube.com/embed/...</li>
|
|
154
|
-
</ul>
|
|
155
|
-
</div>
|
|
156
|
-
<div class="p-4 rounded-lg bg-neutral-100 dark:bg-neutral-800">
|
|
157
|
-
<h3 class="font-medium mb-2">Vimeo</h3>
|
|
158
|
-
<ul class="text-sm text-neutral-600 dark:text-neutral-400 space-y-1">
|
|
159
|
-
<li>vimeo.com/12345</li>
|
|
160
|
-
</ul>
|
|
161
|
-
</div>
|
|
162
|
-
<div class="p-4 rounded-lg bg-neutral-100 dark:bg-neutral-800">
|
|
163
|
-
<h3 class="font-medium mb-2">Direct</h3>
|
|
164
|
-
<ul class="text-sm text-neutral-600 dark:text-neutral-400 space-y-1">
|
|
165
|
-
<li>.mp4, .webm, .ogg</li>
|
|
166
|
-
<li>Any direct video URL</li>
|
|
167
|
-
</ul>
|
|
168
|
-
</div>
|
|
169
|
-
</div>
|
|
170
|
-
</section>
|
|
171
|
-
|
|
172
|
-
<!-- Code Example -->
|
|
173
|
-
<section>
|
|
174
|
-
<h2 class="text-lg font-semibold mb-4">Code Example</h2>
|
|
175
|
-
<CodeExample title="Video Modal Usage" :code="codeExample" />
|
|
176
|
-
</section>
|
|
177
|
-
</div>
|
|
178
|
-
</div>
|
|
179
|
-
</template>
|
|
180
|
-
|
|
181
|
-
<script setup>
|
|
182
|
-
const codeExample = `<!-- With thumbnail trigger -->
|
|
183
|
-
<XMarkModalVideo
|
|
184
|
-
src="https://www.youtube.com/watch?v=dQw4w9WgXcQ"
|
|
185
|
-
thumbnail="/images/video-thumb.jpg"
|
|
186
|
-
title="Product Demo"
|
|
187
|
-
description="Watch our 3-minute overview."
|
|
188
|
-
size="5xl"
|
|
189
|
-
/>
|
|
190
|
-
|
|
191
|
-
<!-- With button trigger (object) -->
|
|
192
|
-
<XMarkModalVideo
|
|
193
|
-
src="https://vimeo.com/76979871"
|
|
194
|
-
title="Customer Story"
|
|
195
|
-
:button="{
|
|
196
|
-
label: 'Watch Video',
|
|
197
|
-
color: 'primary',
|
|
198
|
-
variant: 'solid',
|
|
199
|
-
size: 'lg',
|
|
200
|
-
icon: 'i-lucide-play'
|
|
201
|
-
}"
|
|
202
|
-
/>
|
|
203
|
-
|
|
204
|
-
<!-- Large modal size -->
|
|
205
|
-
<XMarkModalVideo
|
|
206
|
-
src="https://www.youtube.com/watch?v=..."
|
|
207
|
-
size="full"
|
|
208
|
-
:button="{ label: 'Full Screen' }"
|
|
209
|
-
/>
|
|
210
|
-
|
|
211
|
-
<!-- Custom trigger (slot) -->
|
|
212
|
-
<XMarkModalVideo src="https://www.youtube.com/watch?v=...">
|
|
213
|
-
<UButton size="lg" label="Watch Video" leading-icon="i-lucide-play" />
|
|
214
|
-
</XMarkModalVideo>
|
|
215
|
-
|
|
216
|
-
<!-- Minimal (no footer) -->
|
|
217
|
-
<XMarkModalVideo
|
|
218
|
-
src="/videos/demo.mp4"
|
|
219
|
-
:button="{ label: 'Play' }"
|
|
220
|
-
:autoplay="false"
|
|
221
|
-
/>`
|
|
222
|
-
</script>
|
|
@@ -1,164 +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">Announcement Bar</h1>
|
|
5
|
-
<p class="mt-2 text-neutral-600 dark:text-neutral-400">Top-of-page banner for announcements and promotions.</p>
|
|
6
|
-
</div>
|
|
7
|
-
|
|
8
|
-
<div class="p-8 space-y-12">
|
|
9
|
-
<!-- Demo Bars -->
|
|
10
|
-
<section>
|
|
11
|
-
<h2 class="text-lg font-semibold mb-4">Variants</h2>
|
|
12
|
-
<p class="text-sm text-neutral-500 mb-4">Click the buttons to show different announcement bar styles</p>
|
|
13
|
-
<div class="flex flex-wrap gap-3 mb-6">
|
|
14
|
-
<UButton @click="showBar('primary')">Primary</UButton>
|
|
15
|
-
<UButton color="neutral" @click="showBar('neutral')">Neutral</UButton>
|
|
16
|
-
<UButton color="success" @click="showBar('success')">Success</UButton>
|
|
17
|
-
<UButton color="warning" @click="showBar('warning')">Warning</UButton>
|
|
18
|
-
<UButton color="error" @click="showBar('error')">Error</UButton>
|
|
19
|
-
</div>
|
|
20
|
-
|
|
21
|
-
<!-- Demo Container -->
|
|
22
|
-
<div class="relative bg-neutral-100 dark:bg-neutral-800 rounded-lg overflow-hidden min-h-[200px]">
|
|
23
|
-
<XMarkLayoutAnnouncementBar
|
|
24
|
-
v-if="activeBar"
|
|
25
|
-
:message="barConfig.message"
|
|
26
|
-
:badge="barConfig.badge"
|
|
27
|
-
:icon="barConfig.icon"
|
|
28
|
-
:link="barConfig.link"
|
|
29
|
-
:link-text="barConfig.linkText"
|
|
30
|
-
:variant="activeBar"
|
|
31
|
-
:dismissible="true"
|
|
32
|
-
storage-key=""
|
|
33
|
-
@dismiss="activeBar = null"
|
|
34
|
-
/>
|
|
35
|
-
<div class="p-8 pt-16">
|
|
36
|
-
<p class="text-neutral-600 dark:text-neutral-400">Page content below announcement bar</p>
|
|
37
|
-
</div>
|
|
38
|
-
</div>
|
|
39
|
-
</section>
|
|
40
|
-
|
|
41
|
-
<!-- With Icon and Badge -->
|
|
42
|
-
<section>
|
|
43
|
-
<h2 class="text-lg font-semibold mb-4">With Icon and Badge</h2>
|
|
44
|
-
<div class="relative bg-neutral-100 dark:bg-neutral-800 rounded-lg overflow-hidden">
|
|
45
|
-
<XMarkLayoutAnnouncementBar
|
|
46
|
-
message="Join us for our annual conference next month"
|
|
47
|
-
badge="NEW"
|
|
48
|
-
icon="i-lucide-calendar"
|
|
49
|
-
link="#"
|
|
50
|
-
link-text="Register now"
|
|
51
|
-
variant="primary"
|
|
52
|
-
:dismissible="false"
|
|
53
|
-
storage-key=""
|
|
54
|
-
/>
|
|
55
|
-
</div>
|
|
56
|
-
</section>
|
|
57
|
-
|
|
58
|
-
<!-- Simple Version -->
|
|
59
|
-
<section>
|
|
60
|
-
<h2 class="text-lg font-semibold mb-4">Simple Message</h2>
|
|
61
|
-
<div class="relative bg-neutral-100 dark:bg-neutral-800 rounded-lg overflow-hidden">
|
|
62
|
-
<XMarkLayoutAnnouncementBar
|
|
63
|
-
message="Free shipping on orders over $50"
|
|
64
|
-
variant="neutral"
|
|
65
|
-
:dismissible="false"
|
|
66
|
-
storage-key=""
|
|
67
|
-
/>
|
|
68
|
-
</div>
|
|
69
|
-
</section>
|
|
70
|
-
|
|
71
|
-
<!-- Props -->
|
|
72
|
-
<section>
|
|
73
|
-
<h2 class="text-lg font-semibold mb-4">Props</h2>
|
|
74
|
-
<table class="w-full text-sm">
|
|
75
|
-
<thead>
|
|
76
|
-
<tr class="border-b border-neutral-200 dark:border-neutral-700">
|
|
77
|
-
<th class="text-left py-3 px-4">Prop</th>
|
|
78
|
-
<th class="text-left py-3 px-4">Type</th>
|
|
79
|
-
<th class="text-left py-3 px-4">Default</th>
|
|
80
|
-
<th class="text-left py-3 px-4">Description</th>
|
|
81
|
-
</tr>
|
|
82
|
-
</thead>
|
|
83
|
-
<tbody class="divide-y divide-neutral-200 dark:divide-neutral-700">
|
|
84
|
-
<tr><td class="py-3 px-4 font-mono text-xs">message</td><td class="py-3 px-4">String</td><td class="py-3 px-4">required</td><td class="py-3 px-4">Main message text</td></tr>
|
|
85
|
-
<tr><td class="py-3 px-4 font-mono text-xs">badge</td><td class="py-3 px-4">String</td><td class="py-3 px-4">''</td><td class="py-3 px-4">Optional badge before message</td></tr>
|
|
86
|
-
<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><td class="py-3 px-4">Icon name (Lucide)</td></tr>
|
|
87
|
-
<tr><td class="py-3 px-4 font-mono text-xs">link</td><td class="py-3 px-4">String</td><td class="py-3 px-4">''</td><td class="py-3 px-4">CTA link URL</td></tr>
|
|
88
|
-
<tr><td class="py-3 px-4 font-mono text-xs">linkText</td><td class="py-3 px-4">String</td><td class="py-3 px-4">Learn more</td><td class="py-3 px-4">CTA link text</td></tr>
|
|
89
|
-
<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">primary</td><td class="py-3 px-4">primary, neutral, success, warning, error</td></tr>
|
|
90
|
-
<tr><td class="py-3 px-4 font-mono text-xs">dismissible</td><td class="py-3 px-4">Boolean</td><td class="py-3 px-4">true</td><td class="py-3 px-4">Show close button</td></tr>
|
|
91
|
-
<tr><td class="py-3 px-4 font-mono text-xs">storageKey</td><td class="py-3 px-4">String</td><td class="py-3 px-4">announcement-dismissed</td><td class="py-3 px-4">LocalStorage key for dismissed state</td></tr>
|
|
92
|
-
</tbody>
|
|
93
|
-
</table>
|
|
94
|
-
</section>
|
|
95
|
-
|
|
96
|
-
<!-- Events -->
|
|
97
|
-
<section>
|
|
98
|
-
<h2 class="text-lg font-semibold mb-4">Events</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">Event</th>
|
|
103
|
-
<th class="text-left py-3 px-4">Description</th>
|
|
104
|
-
</tr>
|
|
105
|
-
</thead>
|
|
106
|
-
<tbody class="divide-y divide-neutral-200 dark:divide-neutral-700">
|
|
107
|
-
<tr><td class="py-3 px-4 font-mono text-xs">@dismiss</td><td class="py-3 px-4">Emitted when user dismisses the bar</td></tr>
|
|
108
|
-
</tbody>
|
|
109
|
-
</table>
|
|
110
|
-
</section>
|
|
111
|
-
|
|
112
|
-
<!-- Code Example -->
|
|
113
|
-
<section>
|
|
114
|
-
<h2 class="text-lg font-semibold mb-4">Code Example</h2>
|
|
115
|
-
<CodeExample title="Announcement Bar Usage" :code="codeExample" />
|
|
116
|
-
</section>
|
|
117
|
-
</div>
|
|
118
|
-
</div>
|
|
119
|
-
</template>
|
|
120
|
-
|
|
121
|
-
<script setup>
|
|
122
|
-
const codeExample = `<!-- Basic announcement -->
|
|
123
|
-
<XMarkLayoutAnnouncementBar
|
|
124
|
-
message="Free shipping on orders over $50"
|
|
125
|
-
variant="neutral"
|
|
126
|
-
/>
|
|
127
|
-
|
|
128
|
-
<!-- Full featured with icon and link -->
|
|
129
|
-
<XMarkLayoutAnnouncementBar
|
|
130
|
-
message="Our Black Friday sale is now live!"
|
|
131
|
-
badge="SALE"
|
|
132
|
-
icon="i-lucide-percent"
|
|
133
|
-
link="/sale"
|
|
134
|
-
link-text="Shop now"
|
|
135
|
-
variant="primary"
|
|
136
|
-
:dismissible="true"
|
|
137
|
-
storage-key="black-friday-2024"
|
|
138
|
-
@dismiss="handleDismiss"
|
|
139
|
-
/>
|
|
140
|
-
|
|
141
|
-
<!-- Variants: primary, neutral, success, warning, error -->
|
|
142
|
-
<XMarkLayoutAnnouncementBar
|
|
143
|
-
message="Your order has been shipped!"
|
|
144
|
-
variant="success"
|
|
145
|
-
icon="i-lucide-package"
|
|
146
|
-
/>`
|
|
147
|
-
|
|
148
|
-
const activeBar = ref('primary')
|
|
149
|
-
|
|
150
|
-
const barConfig = {
|
|
151
|
-
message: 'Our Black Friday sale is now live!',
|
|
152
|
-
badge: 'SALE',
|
|
153
|
-
icon: 'i-lucide-percent',
|
|
154
|
-
link: '#',
|
|
155
|
-
linkText: 'Shop now'
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
const showBar = (variant) => {
|
|
159
|
-
activeBar.value = null
|
|
160
|
-
setTimeout(() => {
|
|
161
|
-
activeBar.value = variant
|
|
162
|
-
}, 100)
|
|
163
|
-
}
|
|
164
|
-
</script>
|
|
@@ -1,210 +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">Cookie Banner</h1>
|
|
5
|
-
<p class="mt-2 text-neutral-600 dark:text-neutral-400">Bottom cookie consent banner with accept/reject options.</p>
|
|
6
|
-
</div>
|
|
7
|
-
|
|
8
|
-
<div class="p-8 space-y-12">
|
|
9
|
-
<!-- Demo -->
|
|
10
|
-
<section>
|
|
11
|
-
<h2 class="text-lg font-semibold mb-4">Cookie Banner Demo</h2>
|
|
12
|
-
<p class="text-sm text-neutral-500 mb-4">Click the button to show the cookie banner (appears at bottom of page)</p>
|
|
13
|
-
<div class="flex gap-3">
|
|
14
|
-
<UButton @click="showBanner">Show Cookie Banner</UButton>
|
|
15
|
-
<UButton color="neutral" variant="outline" @click="resetConsent">Reset Consent</UButton>
|
|
16
|
-
</div>
|
|
17
|
-
</section>
|
|
18
|
-
|
|
19
|
-
<!-- Preview -->
|
|
20
|
-
<section>
|
|
21
|
-
<h2 class="text-lg font-semibold mb-4">Preview</h2>
|
|
22
|
-
<div class="relative bg-neutral-100 dark:bg-neutral-800 rounded-lg p-6 min-h-[300px]">
|
|
23
|
-
<p class="text-neutral-600 dark:text-neutral-400 mb-4">The banner appears at the bottom of the viewport:</p>
|
|
24
|
-
<!-- Static preview -->
|
|
25
|
-
<div class="absolute bottom-4 left-4 right-4">
|
|
26
|
-
<div class="bg-white dark:bg-neutral-900 rounded-xl shadow-2xl border border-neutral-200 dark:border-neutral-700 p-6">
|
|
27
|
-
<div class="flex flex-col lg:flex-row lg:items-center gap-4">
|
|
28
|
-
<div class="flex-1">
|
|
29
|
-
<h4 class="font-semibold">We use cookies</h4>
|
|
30
|
-
<p class="text-sm text-neutral-500 mt-1">
|
|
31
|
-
We use cookies to improve your experience on our site.
|
|
32
|
-
<NuxtLink to="#" class="text-primary-500 hover:underline">Learn more</NuxtLink>
|
|
33
|
-
</p>
|
|
34
|
-
</div>
|
|
35
|
-
<div class="flex flex-wrap gap-3">
|
|
36
|
-
<UButton variant="outline">Reject All</UButton>
|
|
37
|
-
<UButton>Accept All</UButton>
|
|
38
|
-
</div>
|
|
39
|
-
</div>
|
|
40
|
-
</div>
|
|
41
|
-
</div>
|
|
42
|
-
</div>
|
|
43
|
-
</section>
|
|
44
|
-
|
|
45
|
-
<!-- With Customize -->
|
|
46
|
-
<section>
|
|
47
|
-
<h2 class="text-lg font-semibold mb-4">With Customize Button</h2>
|
|
48
|
-
<UButton @click="showCustomizableBanner">Show with Customize Option</UButton>
|
|
49
|
-
<p class="text-sm text-neutral-500 mt-2">Includes a "Customize" button that can open GDPR preferences modal</p>
|
|
50
|
-
</section>
|
|
51
|
-
|
|
52
|
-
<!-- Props -->
|
|
53
|
-
<section>
|
|
54
|
-
<h2 class="text-lg font-semibold mb-4">Props</h2>
|
|
55
|
-
<table class="w-full text-sm">
|
|
56
|
-
<thead>
|
|
57
|
-
<tr class="border-b border-neutral-200 dark:border-neutral-700">
|
|
58
|
-
<th class="text-left py-3 px-4">Prop</th>
|
|
59
|
-
<th class="text-left py-3 px-4">Type</th>
|
|
60
|
-
<th class="text-left py-3 px-4">Default</th>
|
|
61
|
-
<th class="text-left py-3 px-4">Description</th>
|
|
62
|
-
</tr>
|
|
63
|
-
</thead>
|
|
64
|
-
<tbody class="divide-y divide-neutral-200 dark:divide-neutral-700">
|
|
65
|
-
<tr><td class="py-3 px-4 font-mono text-xs">title</td><td class="py-3 px-4">String</td><td class="py-3 px-4">We use cookies</td><td class="py-3 px-4">Banner title</td></tr>
|
|
66
|
-
<tr><td class="py-3 px-4 font-mono text-xs">message</td><td class="py-3 px-4">String</td><td class="py-3 px-4">We use cookies to...</td><td class="py-3 px-4">Banner message</td></tr>
|
|
67
|
-
<tr><td class="py-3 px-4 font-mono text-xs">policyLink</td><td class="py-3 px-4">String</td><td class="py-3 px-4">/privacy</td><td class="py-3 px-4">Privacy policy URL</td></tr>
|
|
68
|
-
<tr><td class="py-3 px-4 font-mono text-xs">policyLabel</td><td class="py-3 px-4">String</td><td class="py-3 px-4">Learn more</td><td class="py-3 px-4">Privacy link text</td></tr>
|
|
69
|
-
<tr><td class="py-3 px-4 font-mono text-xs">hasCustomize</td><td class="py-3 px-4">Boolean</td><td class="py-3 px-4">false</td><td class="py-3 px-4">Show customize button</td></tr>
|
|
70
|
-
<tr><td class="py-3 px-4 font-mono text-xs">hasReject</td><td class="py-3 px-4">Boolean</td><td class="py-3 px-4">true</td><td class="py-3 px-4">Show reject button</td></tr>
|
|
71
|
-
<tr><td class="py-3 px-4 font-mono text-xs">storageKey</td><td class="py-3 px-4">String</td><td class="py-3 px-4">cookie-consent</td><td class="py-3 px-4">LocalStorage key</td></tr>
|
|
72
|
-
</tbody>
|
|
73
|
-
</table>
|
|
74
|
-
</section>
|
|
75
|
-
|
|
76
|
-
<!-- Events -->
|
|
77
|
-
<section>
|
|
78
|
-
<h2 class="text-lg font-semibold mb-4">Events</h2>
|
|
79
|
-
<table class="w-full text-sm">
|
|
80
|
-
<thead>
|
|
81
|
-
<tr class="border-b border-neutral-200 dark:border-neutral-700">
|
|
82
|
-
<th class="text-left py-3 px-4">Event</th>
|
|
83
|
-
<th class="text-left py-3 px-4">Description</th>
|
|
84
|
-
</tr>
|
|
85
|
-
</thead>
|
|
86
|
-
<tbody class="divide-y divide-neutral-200 dark:divide-neutral-700">
|
|
87
|
-
<tr><td class="py-3 px-4 font-mono text-xs">@accept</td><td class="py-3 px-4">Emitted when user accepts all cookies</td></tr>
|
|
88
|
-
<tr><td class="py-3 px-4 font-mono text-xs">@reject</td><td class="py-3 px-4">Emitted when user rejects cookies</td></tr>
|
|
89
|
-
<tr><td class="py-3 px-4 font-mono text-xs">@customize</td><td class="py-3 px-4">Emitted when user clicks customize</td></tr>
|
|
90
|
-
</tbody>
|
|
91
|
-
</table>
|
|
92
|
-
</section>
|
|
93
|
-
|
|
94
|
-
<!-- Code Example -->
|
|
95
|
-
<section>
|
|
96
|
-
<h2 class="text-lg font-semibold mb-4">Code Example</h2>
|
|
97
|
-
<CodeExample title="Cookie Banner Usage" :code="codeExample" />
|
|
98
|
-
</section>
|
|
99
|
-
</div>
|
|
100
|
-
|
|
101
|
-
<!-- Actual Banner Components -->
|
|
102
|
-
<XMarkPrivacyCookieBanner
|
|
103
|
-
v-if="bannerVisible"
|
|
104
|
-
title="We use cookies"
|
|
105
|
-
message="We use cookies to improve your experience on our site."
|
|
106
|
-
policy-link="/privacy"
|
|
107
|
-
:has-customize="false"
|
|
108
|
-
:has-reject="true"
|
|
109
|
-
storage-key="demo-cookie-consent"
|
|
110
|
-
@accept="handleAccept"
|
|
111
|
-
@reject="handleReject"
|
|
112
|
-
/>
|
|
113
|
-
|
|
114
|
-
<XMarkPrivacyCookieBanner
|
|
115
|
-
v-if="customizableBannerVisible"
|
|
116
|
-
title="Cookie Preferences"
|
|
117
|
-
message="We use cookies to personalize content and analyze traffic."
|
|
118
|
-
:has-customize="true"
|
|
119
|
-
:has-reject="true"
|
|
120
|
-
storage-key="demo-customizable-consent"
|
|
121
|
-
@accept="handleAccept"
|
|
122
|
-
@reject="handleReject"
|
|
123
|
-
@customize="handleCustomize"
|
|
124
|
-
/>
|
|
125
|
-
</div>
|
|
126
|
-
</template>
|
|
127
|
-
|
|
128
|
-
<script setup>
|
|
129
|
-
const codeExample = `<!-- Basic cookie banner -->
|
|
130
|
-
<XMarkPrivacyCookieBanner
|
|
131
|
-
title="We use cookies"
|
|
132
|
-
message="We use cookies to improve your experience."
|
|
133
|
-
policy-link="/privacy"
|
|
134
|
-
@accept="handleAccept"
|
|
135
|
-
@reject="handleReject"
|
|
136
|
-
/>
|
|
137
|
-
|
|
138
|
-
<!-- With customize option -->
|
|
139
|
-
<XMarkPrivacyCookieBanner
|
|
140
|
-
title="Cookie Preferences"
|
|
141
|
-
message="We use cookies to personalize content."
|
|
142
|
-
:has-customize="true"
|
|
143
|
-
:has-reject="true"
|
|
144
|
-
storage-key="cookie-consent"
|
|
145
|
-
@accept="handleAccept"
|
|
146
|
-
@reject="handleReject"
|
|
147
|
-
@customize="openGDPRModal"
|
|
148
|
-
/>
|
|
149
|
-
|
|
150
|
-
<!-- In your layout -->
|
|
151
|
-
<template>
|
|
152
|
-
<div>
|
|
153
|
-
<NuxtPage />
|
|
154
|
-
<XMarkPrivacyCookieBanner
|
|
155
|
-
@accept="enableAnalytics"
|
|
156
|
-
@customize="gdprModalOpen = true"
|
|
157
|
-
/>
|
|
158
|
-
<XMarkPrivacyGDPR v-model="gdprModalOpen" />
|
|
159
|
-
</div>
|
|
160
|
-
</template>`
|
|
161
|
-
|
|
162
|
-
const bannerVisible = ref(false)
|
|
163
|
-
const customizableBannerVisible = ref(false)
|
|
164
|
-
|
|
165
|
-
const showBanner = () => {
|
|
166
|
-
localStorage.removeItem('demo-cookie-consent')
|
|
167
|
-
bannerVisible.value = true
|
|
168
|
-
// Force re-render by toggling
|
|
169
|
-
nextTick(() => {
|
|
170
|
-
bannerVisible.value = false
|
|
171
|
-
nextTick(() => {
|
|
172
|
-
bannerVisible.value = true
|
|
173
|
-
})
|
|
174
|
-
})
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
const showCustomizableBanner = () => {
|
|
178
|
-
localStorage.removeItem('demo-customizable-consent')
|
|
179
|
-
customizableBannerVisible.value = true
|
|
180
|
-
nextTick(() => {
|
|
181
|
-
customizableBannerVisible.value = false
|
|
182
|
-
nextTick(() => {
|
|
183
|
-
customizableBannerVisible.value = true
|
|
184
|
-
})
|
|
185
|
-
})
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
const resetConsent = () => {
|
|
189
|
-
localStorage.removeItem('demo-cookie-consent')
|
|
190
|
-
localStorage.removeItem('demo-customizable-consent')
|
|
191
|
-
bannerVisible.value = false
|
|
192
|
-
customizableBannerVisible.value = false
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
const handleAccept = () => {
|
|
196
|
-
console.log('Cookies accepted')
|
|
197
|
-
bannerVisible.value = false
|
|
198
|
-
customizableBannerVisible.value = false
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
const handleReject = () => {
|
|
202
|
-
console.log('Cookies rejected')
|
|
203
|
-
bannerVisible.value = false
|
|
204
|
-
customizableBannerVisible.value = false
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
const handleCustomize = () => {
|
|
208
|
-
console.log('Open GDPR preferences modal')
|
|
209
|
-
}
|
|
210
|
-
</script>
|