@xenterprises/nuxt-x-marketing 0.0.23 → 1.0.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 (115) hide show
  1. package/.claude/settings.local.json +22 -0
  2. package/.playground/app.config.ts +44 -45
  3. package/.playground/app.vue +263 -0
  4. package/.playground/components/AppFooter.vue +103 -0
  5. package/.playground/components/AppHeader.vue +41 -0
  6. package/.playground/components/CodeExample.vue +70 -0
  7. package/.playground/components/ComponentPlayground.vue +117 -0
  8. package/.playground/components/DocsHeader.vue +19 -0
  9. package/.playground/layouts/default.vue +13 -3
  10. package/.playground/layouts/docs-layout.vue +161 -0
  11. package/.playground/layouts/docs.vue +11 -0
  12. package/.playground/package-lock.json +6 -0
  13. package/.playground/pages/blog/author.vue +145 -0
  14. package/.playground/pages/blog/card.vue +149 -0
  15. package/.playground/pages/blog/cta.vue +131 -0
  16. package/.playground/pages/blog/detail.vue +379 -0
  17. package/.playground/pages/blog/list.vue +261 -0
  18. package/.playground/pages/blog/navigation.vue +228 -0
  19. package/.playground/pages/blog/sidebar.vue +279 -0
  20. package/.playground/pages/config.vue +289 -0
  21. package/.playground/pages/content/comparison.vue +253 -0
  22. package/.playground/pages/content/cta.vue +245 -0
  23. package/.playground/pages/content/features.vue +217 -0
  24. package/.playground/pages/content/newsletter-section.vue +260 -0
  25. package/.playground/pages/content/newsletter.vue +200 -0
  26. package/.playground/pages/content/pricing.vue +335 -0
  27. package/.playground/pages/content/testimonials.vue +188 -0
  28. package/.playground/pages/hero.vue +257 -0
  29. package/.playground/pages/index.vue +379 -2
  30. package/.playground/pages/layout/footer.vue +210 -0
  31. package/.playground/pages/layout/legal-footer.vue +121 -0
  32. package/.playground/pages/layout/navbar.vue +285 -0
  33. package/.playground/pages/layout/section.vue +266 -0
  34. package/.playground/pages/layout/x-legal.vue +199 -0
  35. package/.playground/pages/modals/feature-modal.vue +320 -0
  36. package/.playground/pages/modals/image-lightbox.vue +277 -0
  37. package/.playground/pages/modals/video-modal.vue +222 -0
  38. package/.playground/pages/notifications/announcement-bar.vue +164 -0
  39. package/.playground/pages/notifications/cookie-banner.vue +210 -0
  40. package/.playground/pages/notifications/cookie-toast.vue +143 -0
  41. package/.playground/pages/notifications/gdpr.vue +276 -0
  42. package/.playground/pages/notifications/social-proof-toast.vue +255 -0
  43. package/.playground/pages/ui/badge.vue +161 -0
  44. package/.playground/pages/ui/bg-pattern.vue +177 -0
  45. package/.playground/pages/ui/glass-card.vue +179 -0
  46. package/.playground/pages/ui/glow-divider.vue +179 -0
  47. package/.playground/pages/ui/promo-card.vue +259 -0
  48. package/.playground/pages/ui/section-stitch.vue +411 -0
  49. package/.playground/pages/utilities/back-to-top.vue +153 -0
  50. package/.playground/pages/utilities/popup-chat.vue +224 -0
  51. package/README.md +799 -164
  52. package/app/app.config.ts +88 -2
  53. package/app/app.vue +106 -11
  54. package/app/assets/css/x-marketing.css +668 -0
  55. package/app/components/X/Footer/XLegal/index.vue +63 -26
  56. package/app/components/X/Footer/index.vue +89 -89
  57. package/app/components/X/Header/App.vue +63 -0
  58. package/app/components/X/Mark/Blog/Author.vue +170 -0
  59. package/app/components/X/Mark/Blog/CTANewsletter.vue +197 -0
  60. package/app/components/X/Mark/Blog/Card.vue +117 -0
  61. package/app/components/X/Mark/Blog/Detail.vue +240 -0
  62. package/app/components/X/Mark/Blog/List.vue +156 -0
  63. package/app/components/X/Mark/Blog/Navigation.vue +100 -0
  64. package/app/components/X/Mark/Blog/Sidebar.vue +160 -0
  65. package/app/components/X/Mark/Button/BackToTop.vue +99 -0
  66. package/app/components/X/Mark/CTA/index.vue +294 -0
  67. package/app/components/X/Mark/Card/Glass.vue +64 -0
  68. package/app/components/X/Mark/Card/Promo.vue +164 -0
  69. package/app/components/X/Mark/Divider/Glow.vue +113 -0
  70. package/app/components/X/Mark/Features/index.vue +194 -0
  71. package/app/components/X/Mark/Hero/index.vue +217 -0
  72. package/app/components/X/Mark/Layout/AnnouncementBar.vue +139 -0
  73. package/app/components/X/Mark/Layout/Footer.vue +160 -0
  74. package/app/components/X/Mark/Layout/FooterLegal.vue +42 -0
  75. package/app/components/X/Mark/Layout/Navbar.vue +267 -0
  76. package/app/components/X/Mark/Modal/Chat.vue +151 -0
  77. package/app/components/X/Mark/Modal/Feature.vue +197 -0
  78. package/app/components/X/Mark/Modal/Image.vue +226 -0
  79. package/app/components/X/Mark/Modal/Video.vue +203 -0
  80. package/app/components/X/Mark/Modal/index.vue +133 -0
  81. package/app/components/X/Mark/Newsletter/Form.vue +174 -0
  82. package/app/components/X/Mark/Pattern/Bg.vue +86 -0
  83. package/app/components/X/Mark/Pricing/Comparison.vue +126 -0
  84. package/app/components/X/Mark/Pricing/Plans.vue +181 -0
  85. package/app/components/X/Mark/Privacy/CookieBanner.vue +112 -0
  86. package/app/components/X/Mark/Privacy/CookieToast.vue +43 -0
  87. package/app/components/X/Mark/Privacy/GDPR.vue +245 -0
  88. package/app/components/X/Mark/Section/Newsletter.vue +183 -0
  89. package/app/components/X/Mark/Section/Stitch.vue +156 -0
  90. package/app/components/X/Mark/Section/index.vue +151 -0
  91. package/app/components/X/Mark/SocialProof/Badge.vue +102 -0
  92. package/app/components/X/Mark/SocialProof/Testimonials.vue +326 -0
  93. package/app/components/X/Mark/SocialProof/Toast.vue +136 -0
  94. package/app/components/X/Mark/_archive/Pattern/Background.vue +83 -0
  95. package/app/components/X/Mark/_archive/Pattern/CheckBg.vue +35 -0
  96. package/app/components/X/Mark/_archive/Pattern/CircuitBg.vue +41 -0
  97. package/app/components/X/Mark/_archive/Pattern/DotsBg.vue +35 -0
  98. package/app/components/X/Mark/_archive/Pattern/GlowDivider.vue +86 -0
  99. package/app/components/X/Mark/_archive/Pattern/HexBg.vue +35 -0
  100. package/app/components/X/Mark/_archive/Pattern/PlaidBg.vue +47 -0
  101. package/app/components/X/Mark/_archive/Pattern/SectionStitch.vue +168 -0
  102. package/app/components/X/Mark/_archive/Pattern/WaveBg.vue +41 -0
  103. package/app/components/X/_archive/Newsletter/Form.vue +123 -0
  104. package/app/components/X/_archive/Newsletter/Section.vue +131 -0
  105. package/app/composables/useParallax.ts +124 -0
  106. package/app/composables/useScrollReveal.ts +92 -0
  107. package/app/pages/index.vue +210 -0
  108. package/app/plugins/marketing.client.ts +13 -0
  109. package/app/types/marketing.d.ts +268 -0
  110. package/componentList.json +511 -0
  111. package/nuxt.config.ts +6 -13
  112. package/package.json +21 -9
  113. package/.editorconfig +0 -12
  114. package/app/assets/css/main.css +0 -2
  115. package/app/components/X/Marketing/Sections/EmailSubscription/index.vue +0 -129
@@ -0,0 +1,511 @@
1
+ {
2
+ "components": [
3
+ {
4
+ "name": "XMarkBlogAuthor",
5
+ "file": "Blog/Author.vue",
6
+ "category": "Blog",
7
+ "props": [
8
+ { "name": "author", "type": "Object", "default": null, "required": true },
9
+ { "name": "variant", "type": "String", "default": "inline", "required": false, "options": ["inline", "sm", "full", "card"] }
10
+ ]
11
+ },
12
+ {
13
+ "name": "XMarkBlogCard",
14
+ "file": "Blog/Card.vue",
15
+ "category": "Blog",
16
+ "props": [
17
+ { "name": "post", "type": "Object", "default": null, "required": true },
18
+ { "name": "hasCategory", "type": "Boolean", "default": true, "required": false },
19
+ { "name": "hasAuthor", "type": "Boolean", "default": true, "required": false },
20
+ { "name": "hasExcerpt", "type": "Boolean", "default": true, "required": false },
21
+ { "name": "button", "type": "Object", "default": null, "required": false }
22
+ ]
23
+ },
24
+ {
25
+ "name": "XMarkBlogCTANewsletter",
26
+ "file": "Blog/CTANewsletter.vue",
27
+ "category": "Blog",
28
+ "props": [
29
+ { "name": "title", "type": "String", "default": "Subscribe to our newsletter", "required": false },
30
+ { "name": "description", "type": "String", "default": "Get the latest posts delivered right to your inbox.", "required": false },
31
+ { "name": "button", "type": "Object", "default": "{ label: 'Subscribe' }", "required": false },
32
+ { "name": "placeholder", "type": "String", "default": "Enter your email", "required": false },
33
+ { "name": "variant", "type": "String", "default": "default", "required": false, "options": ["default", "featured", "inline", "compact"] },
34
+ { "name": "icon", "type": "String", "default": "i-lucide-mail", "required": false },
35
+ { "name": "hasPrivacy", "type": "Boolean", "default": true, "required": false },
36
+ { "name": "privacyText", "type": "String", "default": "No spam. Unsubscribe anytime.", "required": false },
37
+ { "name": "successMessage", "type": "String", "default": "Thanks for subscribing!", "required": false }
38
+ ],
39
+ "events": [
40
+ { "name": "submit", "payload": "String", "description": "Emitted with email address when form is submitted" }
41
+ ]
42
+ },
43
+ {
44
+ "name": "XMarkBlogDetail",
45
+ "file": "Blog/Detail.vue",
46
+ "category": "Blog",
47
+ "props": [
48
+ { "name": "post", "type": "Object", "default": null, "required": true },
49
+ { "name": "previousPost", "type": "Object", "default": null, "required": false },
50
+ { "name": "nextPost", "type": "Object", "default": null, "required": false },
51
+ { "name": "toc", "type": "Array", "default": "[]", "required": false }
52
+ ]
53
+ },
54
+ {
55
+ "name": "XMarkBlogList",
56
+ "file": "Blog/List.vue",
57
+ "category": "Blog",
58
+ "props": [
59
+ { "name": "posts", "type": "Array", "default": null, "required": true },
60
+ { "name": "columns", "type": "Number", "default": 3, "required": false, "options": [1, 2, 3] },
61
+ { "name": "perPage", "type": "Number", "default": 9, "required": false },
62
+ { "name": "hasFilters", "type": "Boolean", "default": false, "required": false },
63
+ { "name": "hasCategories", "type": "Boolean", "default": true, "required": false },
64
+ { "name": "hasAuthors", "type": "Boolean", "default": true, "required": false },
65
+ { "name": "categories", "type": "Array", "default": "[]", "required": false },
66
+ { "name": "cardButton", "type": "Object", "default": null, "required": false }
67
+ ]
68
+ },
69
+ {
70
+ "name": "XMarkBlogNavigation",
71
+ "file": "Blog/Navigation.vue",
72
+ "category": "Blog",
73
+ "props": [
74
+ { "name": "previous", "type": "Object", "default": null, "required": false },
75
+ { "name": "next", "type": "Object", "default": null, "required": false },
76
+ { "name": "basePath", "type": "String", "default": "/blog", "required": false },
77
+ { "name": "previousLabel", "type": "String", "default": "Previous", "required": false },
78
+ { "name": "nextLabel", "type": "String", "default": "Next", "required": false }
79
+ ]
80
+ },
81
+ {
82
+ "name": "XMarkBlogSidebar",
83
+ "file": "Blog/Sidebar.vue",
84
+ "category": "Blog",
85
+ "props": [
86
+ { "name": "hasSearch", "type": "Boolean", "default": true, "required": false },
87
+ { "name": "categories", "type": "Array", "default": "[]", "required": false },
88
+ { "name": "tags", "type": "Array", "default": "[]", "required": false },
89
+ { "name": "recentPosts", "type": "Array", "default": "[]", "required": false },
90
+ { "name": "categoryBasePath", "type": "String", "default": "/blog/category", "required": false },
91
+ { "name": "tagBasePath", "type": "String", "default": "/blog/tag", "required": false },
92
+ { "name": "hasCta", "type": "Boolean", "default": true, "required": false }
93
+ ],
94
+ "events": [
95
+ { "name": "search", "payload": "String", "description": "Emitted when user presses Enter in search input" }
96
+ ]
97
+ },
98
+ {
99
+ "name": "XMarkButtonBackToTop",
100
+ "file": "Button/BackToTop.vue",
101
+ "category": "Button",
102
+ "props": [
103
+ { "name": "threshold", "type": "Number", "default": 400, "required": false },
104
+ { "name": "position", "type": "String", "default": "bottom-right", "required": false, "options": ["bottom-right", "bottom-left", "bottom-center"] },
105
+ { "name": "variant", "type": "String", "default": "primary", "required": false, "options": ["primary", "neutral", "glass"] },
106
+ { "name": "icon", "type": "String", "default": "i-lucide-arrow-up", "required": false },
107
+ { "name": "label", "type": "String", "default": "Back to top", "required": false },
108
+ { "name": "smooth", "type": "Boolean", "default": true, "required": false }
109
+ ]
110
+ },
111
+ {
112
+ "name": "XMarkCardGlass",
113
+ "file": "Card/Glass.vue",
114
+ "category": "Card",
115
+ "props": [
116
+ { "name": "title", "type": "String", "default": "", "required": false },
117
+ { "name": "subtitle", "type": "String", "default": "", "required": false },
118
+ { "name": "size", "type": "String", "default": "md", "required": false, "options": ["xs", "sm", "md", "lg", "xl"] },
119
+ { "name": "glow", "type": "Boolean", "default": false, "required": false }
120
+ ]
121
+ },
122
+ {
123
+ "name": "XMarkCardPromo",
124
+ "file": "Card/Promo.vue",
125
+ "category": "Card",
126
+ "props": [
127
+ { "name": "to", "type": "String", "default": "", "required": false },
128
+ { "name": "img", "type": "Object", "default": null, "required": true },
129
+ { "name": "title", "type": "String", "default": null, "required": true },
130
+ { "name": "badge", "type": "String", "default": "", "required": false },
131
+ { "name": "button", "type": "Object", "default": null, "required": false },
132
+ { "name": "align", "type": "String", "default": "bottomLeft", "required": false, "options": ["bottomLeft", "bottomRight", "bottomCenter", "topLeft"] },
133
+ { "name": "overlay", "type": "String", "default": "gradient", "required": false, "options": ["light", "heavy", "gradient"] },
134
+ { "name": "hoverable", "type": "Boolean", "default": true, "required": false }
135
+ ]
136
+ },
137
+ {
138
+ "name": "XMarkCTA",
139
+ "file": "CTA/index.vue",
140
+ "category": "CTA",
141
+ "props": [
142
+ { "name": "eyebrow", "type": "String", "default": "", "required": false },
143
+ { "name": "title", "type": "String", "default": null, "required": true },
144
+ { "name": "description", "type": "String", "default": "", "required": false },
145
+ { "name": "icon", "type": "String", "default": "", "required": false },
146
+ { "name": "buttons", "type": "Array", "default": "[]", "required": false },
147
+ { "name": "variant", "type": "String", "default": "default", "required": false, "options": ["default", "centered", "inline", "stacked"] },
148
+ { "name": "background", "type": "String", "default": "subtle", "required": false, "options": ["subtle", "bold", "gradient", "none"] },
149
+ { "name": "size", "type": "String", "default": "md", "required": false, "options": ["sm", "md", "lg"] }
150
+ ]
151
+ },
152
+ {
153
+ "name": "XMarkDividerGlow",
154
+ "file": "Divider/Glow.vue",
155
+ "category": "Divider",
156
+ "props": [
157
+ { "name": "glow", "type": "Boolean", "default": true, "required": false },
158
+ { "name": "color", "type": "String", "default": "primary", "required": false, "options": ["primary", "neutral", "white"] },
159
+ { "name": "intensity", "type": "String", "default": "medium", "required": false, "options": ["subtle", "medium", "strong"] },
160
+ { "name": "spacing", "type": "String", "default": "md", "required": false, "options": ["sm", "md", "lg"] },
161
+ { "name": "fade", "type": "Boolean", "default": false, "required": false }
162
+ ]
163
+ },
164
+ {
165
+ "name": "XMarkFeatures",
166
+ "file": "Features/index.vue",
167
+ "category": "Features",
168
+ "props": [
169
+ { "name": "features", "type": "Array", "default": null, "required": true },
170
+ { "name": "layout", "type": "String", "default": "grid", "required": false, "options": ["grid", "list", "alternating"] },
171
+ { "name": "columns", "type": "Number", "default": 3, "required": false, "options": [2, 3, 4] }
172
+ ]
173
+ },
174
+ {
175
+ "name": "XMarkHero",
176
+ "file": "Hero/index.vue",
177
+ "category": "Hero",
178
+ "props": [
179
+ { "name": "img", "type": "Object", "default": null, "required": false },
180
+ { "name": "video", "type": "Object", "default": null, "required": false },
181
+ { "name": "overlay", "type": "String", "default": "gradient", "required": false, "options": ["light", "heavy", "gradient", "none"] },
182
+ { "name": "eyebrow", "type": "String", "default": "", "required": false },
183
+ { "name": "title", "type": "String", "default": null, "required": true },
184
+ { "name": "subtitle", "type": "String", "default": "", "required": false },
185
+ { "name": "buttons", "type": "Array", "default": "[]", "required": false },
186
+ { "name": "align", "type": "String", "default": "left", "required": false, "options": ["left", "center", "right"] },
187
+ { "name": "verticalAlign", "type": "String", "default": "center", "required": false, "options": ["center", "bottom"] },
188
+ { "name": "hasScrollIndicator", "type": "Boolean", "default": true, "required": false },
189
+ { "name": "includeNavPadding", "type": "Boolean", "default": false, "required": false }
190
+ ]
191
+ },
192
+ {
193
+ "name": "XMarkLayoutAnnouncementBar",
194
+ "file": "Layout/AnnouncementBar.vue",
195
+ "category": "Layout",
196
+ "props": [
197
+ { "name": "message", "type": "String", "default": null, "required": true },
198
+ { "name": "badge", "type": "String", "default": "", "required": false },
199
+ { "name": "icon", "type": "String", "default": "", "required": false },
200
+ { "name": "link", "type": "String", "default": "", "required": false },
201
+ { "name": "linkText", "type": "String", "default": "Learn more", "required": false },
202
+ { "name": "variant", "type": "String", "default": "primary", "required": false, "options": ["primary", "neutral", "success", "warning", "error"] },
203
+ { "name": "dismissible", "type": "Boolean", "default": true, "required": false },
204
+ { "name": "storageKey", "type": "String", "default": "announcement-dismissed", "required": false }
205
+ ]
206
+ },
207
+ {
208
+ "name": "XMarkLayoutFooter",
209
+ "file": "Layout/Footer.vue",
210
+ "category": "Layout",
211
+ "props": [
212
+ { "name": "logo", "type": "Object", "default": null, "required": false },
213
+ { "name": "description", "type": "String", "default": "", "required": false },
214
+ { "name": "social", "type": "Array", "default": "[]", "required": false },
215
+ { "name": "columns", "type": "Array", "default": "[]", "required": false },
216
+ { "name": "legalLinks", "type": "Array", "default": "[]", "required": false },
217
+ { "name": "copyright", "type": "String", "default": "© {year} All rights reserved.", "required": false },
218
+ { "name": "hasNewsletter", "type": "Boolean", "default": false, "required": false },
219
+ { "name": "newsletterTitle", "type": "String", "default": "Subscribe to our newsletter", "required": false },
220
+ { "name": "newsletterDescription", "type": "String", "default": "Get the latest updates and news.", "required": false }
221
+ ]
222
+ },
223
+ {
224
+ "name": "XMarkLayoutFooterLegal",
225
+ "file": "Layout/FooterLegal.vue",
226
+ "category": "Layout",
227
+ "props": [
228
+ { "name": "copyright", "type": "String", "default": "© {year} All rights reserved.", "required": false },
229
+ { "name": "links", "type": "Array", "default": "[{ label: 'Privacy Policy', to: '/privacy' }, ...]", "required": false }
230
+ ]
231
+ },
232
+ {
233
+ "name": "XMarkLayoutNavbar",
234
+ "file": "Layout/Navbar.vue",
235
+ "category": "Layout",
236
+ "props": [
237
+ { "name": "transparent", "type": "Boolean", "default": true, "required": false },
238
+ { "name": "links", "type": "Array", "default": null, "required": false },
239
+ { "name": "logo", "type": "Object", "default": null, "required": false },
240
+ { "name": "scrollThreshold", "type": "Number", "default": 100, "required": false },
241
+ { "name": "buttons", "type": "Array", "default": null, "required": false }
242
+ ]
243
+ },
244
+ {
245
+ "name": "XMarkModalChat",
246
+ "file": "Modal/Chat.vue",
247
+ "category": "Modal",
248
+ "props": [
249
+ { "name": "modelValue", "type": "Boolean", "default": false, "required": false },
250
+ { "name": "avatar", "type": "String", "default": "", "required": false },
251
+ { "name": "name", "type": "String", "default": null, "required": true },
252
+ { "name": "message", "type": "String", "default": null, "required": true },
253
+ { "name": "online", "type": "Boolean", "default": true, "required": false },
254
+ { "name": "actionText", "type": "String", "default": "", "required": false },
255
+ { "name": "autoDismiss", "type": "Number", "default": 0, "required": false },
256
+ { "name": "delay", "type": "Number", "default": 3000, "required": false }
257
+ ],
258
+ "events": [
259
+ { "name": "update:modelValue", "payload": "Boolean", "description": "Emitted when visibility changes" },
260
+ { "name": "action", "payload": null, "description": "Emitted when action button is clicked" }
261
+ ]
262
+ },
263
+ {
264
+ "name": "XMarkModalFeature",
265
+ "file": "Modal/Feature.vue",
266
+ "category": "Modal",
267
+ "props": [
268
+ { "name": "modelValue", "type": "Boolean", "default": false, "required": false },
269
+ { "name": "hero", "type": "Object", "default": null, "required": false },
270
+ { "name": "blocks", "type": "Array", "default": null, "required": true },
271
+ { "name": "cta", "type": "Object", "default": null, "required": false }
272
+ ],
273
+ "events": [
274
+ { "name": "update:modelValue", "payload": "Boolean", "description": "Emitted when modal visibility changes" }
275
+ ]
276
+ },
277
+ {
278
+ "name": "XMarkModalImage",
279
+ "file": "Modal/Image.vue",
280
+ "category": "Modal",
281
+ "props": [
282
+ { "name": "modelValue", "type": "Boolean", "default": false, "required": false },
283
+ { "name": "images", "type": "Array", "default": "[]", "required": false },
284
+ { "name": "startIndex", "type": "Number", "default": 0, "required": false },
285
+ { "name": "hasCounter", "type": "Boolean", "default": true, "required": false },
286
+ { "name": "hasThumbnails", "type": "Boolean", "default": false, "required": false }
287
+ ],
288
+ "events": [
289
+ { "name": "update:modelValue", "payload": "Boolean", "description": "Emitted when modal visibility changes" }
290
+ ]
291
+ },
292
+ {
293
+ "name": "XMarkModalVideo",
294
+ "file": "Modal/Video.vue",
295
+ "category": "Modal",
296
+ "props": [
297
+ { "name": "modelValue", "type": "Boolean", "default": false, "required": false },
298
+ { "name": "src", "type": "String", "default": null, "required": true },
299
+ { "name": "poster", "type": "String", "default": "", "required": false },
300
+ { "name": "title", "type": "String", "default": "", "required": false },
301
+ { "name": "description", "type": "String", "default": "", "required": false },
302
+ { "name": "autoplay", "type": "Boolean", "default": true, "required": false },
303
+ { "name": "captions", "type": "String", "default": "", "required": false },
304
+ { "name": "captionsLang", "type": "String", "default": "en", "required": false },
305
+ { "name": "captionsLabel", "type": "String", "default": "English", "required": false }
306
+ ],
307
+ "events": [
308
+ { "name": "update:modelValue", "payload": "Boolean", "description": "Emitted when modal visibility changes" }
309
+ ]
310
+ },
311
+ {
312
+ "name": "XMarkNewsletterForm",
313
+ "file": "Newsletter/Form.vue",
314
+ "category": "Newsletter",
315
+ "props": [
316
+ { "name": "title", "type": "String", "default": "Subscribe to our newsletter", "required": false },
317
+ { "name": "description", "type": "String", "default": "", "required": false },
318
+ { "name": "button", "type": "Object", "default": "{ label: 'Subscribe' }", "required": false },
319
+ { "name": "variant", "type": "String", "default": "default", "required": false, "options": ["default", "inline", "card", "compact"] },
320
+ { "name": "hasPrivacy", "type": "Boolean", "default": true, "required": false }
321
+ ],
322
+ "events": [
323
+ { "name": "submit", "payload": "String", "description": "Emitted with email address when form is submitted" }
324
+ ]
325
+ },
326
+ {
327
+ "name": "XMarkPatternBg",
328
+ "file": "Pattern/Bg.vue",
329
+ "category": "Pattern",
330
+ "props": [
331
+ { "name": "pattern", "type": "String", "default": "dots", "required": false, "options": ["dots", "grid", "diagonal", "topography", "circuit", "waves", "plaid", "diagonalPlaid", "hexagons", "triangles", "crosses", "zigzag", "diamonds"] },
332
+ { "name": "opacity", "type": "Number", "default": 0.05, "required": false },
333
+ { "name": "color", "type": "String", "default": "auto", "required": false },
334
+ { "name": "fade", "type": "Boolean", "default": true, "required": false }
335
+ ]
336
+ },
337
+ {
338
+ "name": "XMarkPricingComparison",
339
+ "file": "Pricing/Comparison.vue",
340
+ "category": "Pricing",
341
+ "description": "Wraps UPricingTable with marketing enhancements like social proof badges",
342
+ "props": [
343
+ { "name": "plans", "type": "Array", "default": null, "required": true, "description": "Array of { id, name, price?, description?, highlighted?, button? }" },
344
+ { "name": "featureGroups", "type": "Array", "default": null, "required": true, "description": "Array of { name?, features: [{ name, values: { [planId]: boolean|string } }] }" },
345
+ { "name": "caption", "type": "String", "default": null, "required": false, "description": "Caption displayed above the table" },
346
+ { "name": "badges", "type": "Array", "default": "[]", "required": false, "description": "Social proof badge presets or custom badges" },
347
+ { "name": "badgesPosition", "type": "String", "default": "bottom", "required": false, "options": ["top", "bottom"] },
348
+ { "name": "badgesAlign", "type": "String", "default": "center", "required": false, "options": ["left", "center", "right"] }
349
+ ],
350
+ "events": [
351
+ { "name": "select", "payload": "Object", "description": "Emitted with plan object when CTA is clicked" }
352
+ ]
353
+ },
354
+ {
355
+ "name": "XMarkPricingPlans",
356
+ "file": "Pricing/Plans.vue",
357
+ "category": "Pricing",
358
+ "description": "Wraps UPricingPlans with billing toggle and social proof badges",
359
+ "props": [
360
+ { "name": "plans", "type": "Array", "default": null, "required": true, "description": "Array of plan objects { name, description, price, features, button, popular? }" },
361
+ { "name": "highlighted", "type": "String", "default": "", "required": false, "description": "Plan name to highlight (alternative to popular: true)" },
362
+ { "name": "hasBillingToggle", "type": "Boolean", "default": false, "required": false, "description": "Show monthly/yearly toggle" },
363
+ { "name": "yearlyDiscount", "type": "Number", "default": 20, "required": false, "description": "Yearly discount percentage to display" },
364
+ { "name": "scale", "type": "Boolean", "default": false, "required": false, "description": "Scale effect on highlighted plan" },
365
+ { "name": "compact", "type": "Boolean", "default": false, "required": false, "description": "No gap between plans" },
366
+ { "name": "variant", "type": "String", "default": null, "required": false, "options": ["soft", "solid", "outline", "subtle"] },
367
+ { "name": "badges", "type": "Array", "default": "[]", "required": false, "description": "Social proof badge presets or custom badges" },
368
+ { "name": "badgesPosition", "type": "String", "default": "bottom", "required": false, "options": ["top", "bottom"] },
369
+ { "name": "badgesAlign", "type": "String", "default": "center", "required": false, "options": ["left", "center", "right"] }
370
+ ],
371
+ "events": [
372
+ { "name": "select", "payload": "Object", "description": "Emitted with plan object when CTA is clicked" }
373
+ ]
374
+ },
375
+ {
376
+ "name": "XMarkPrivacyCookieBanner",
377
+ "file": "Privacy/CookieBanner.vue",
378
+ "category": "Privacy",
379
+ "props": [
380
+ { "name": "title", "type": "String", "default": "We use cookies", "required": false },
381
+ { "name": "message", "type": "String", "default": "We use cookies to improve your experience on our site.", "required": false },
382
+ { "name": "policyLink", "type": "String", "default": "/privacy", "required": false },
383
+ { "name": "policyLabel", "type": "String", "default": "Learn more", "required": false },
384
+ { "name": "hasCustomize", "type": "Boolean", "default": false, "required": false },
385
+ { "name": "hasReject", "type": "Boolean", "default": true, "required": false },
386
+ { "name": "storageKey", "type": "String", "default": "cookie-consent", "required": false }
387
+ ],
388
+ "events": [
389
+ { "name": "accept", "payload": null, "description": "Emitted when user clicks Accept All" },
390
+ { "name": "reject", "payload": null, "description": "Emitted when user clicks Reject All" },
391
+ { "name": "customize", "payload": null, "description": "Emitted when user clicks Customize" }
392
+ ]
393
+ },
394
+ {
395
+ "name": "XMarkPrivacyCookieToast",
396
+ "file": "Privacy/CookieToast.vue",
397
+ "category": "Privacy",
398
+ "props": []
399
+ },
400
+ {
401
+ "name": "XMarkPrivacyGDPR",
402
+ "file": "Privacy/GDPR.vue",
403
+ "category": "Privacy",
404
+ "props": [
405
+ { "name": "modelValue", "type": "Boolean", "default": false, "required": false },
406
+ { "name": "title", "type": "String", "default": "Privacy Preferences", "required": false },
407
+ { "name": "description", "type": "String", "default": "We use cookies to enhance your browsing experience. You can choose which categories to allow.", "required": false },
408
+ { "name": "categories", "type": "Array", "default": "[{ id, name, description, required }, ...]", "required": false },
409
+ { "name": "privacyLink", "type": "String", "default": "/privacy", "required": false },
410
+ { "name": "cookieLink", "type": "String", "default": "/cookies", "required": false },
411
+ { "name": "storageKey", "type": "String", "default": "gdpr-preferences", "required": false }
412
+ ],
413
+ "events": [
414
+ { "name": "update:modelValue", "payload": "Boolean", "description": "Emitted when modal visibility changes" },
415
+ { "name": "accept", "payload": null, "description": "Emitted when user clicks Accept All" },
416
+ { "name": "reject", "payload": null, "description": "Emitted when user clicks Reject All" },
417
+ { "name": "save", "payload": "Object", "description": "Emitted with preferences { categoryId: boolean, ... }" }
418
+ ]
419
+ },
420
+ {
421
+ "name": "XMarkSection",
422
+ "file": "Section/index.vue",
423
+ "category": "Section",
424
+ "props": [
425
+ { "name": "bg", "type": "String", "default": "default", "required": false, "options": ["default", "subtle", "elevated", "bold", "transparent"] },
426
+ { "name": "background", "type": "String", "default": null, "required": false },
427
+ { "name": "color", "type": "String", "default": "", "required": false },
428
+ { "name": "bgImage", "type": "String", "default": "", "required": false },
429
+ { "name": "bgImageAlt", "type": "String", "default": "", "required": false },
430
+ { "name": "bgImageOverlay", "type": "String", "default": "", "required": false, "options": ["", "light", "heavy", "gradient"] },
431
+ { "name": "bgImagePosition", "type": "String", "default": "object-center", "required": false },
432
+ { "name": "pattern", "type": "String", "default": "", "required": false, "options": ["", "dots", "grid", "diagonal", "topography", "circuit", "waves"] },
433
+ { "name": "patternOpacity", "type": "Number", "default": 0.05, "required": false },
434
+ { "name": "padding", "type": "String", "default": "lg", "required": false, "options": ["none", "xs", "sm", "md", "lg", "xl"] },
435
+ { "name": "container", "type": "String", "default": "lg", "required": false, "options": ["sm", "md", "lg", "xl", "full", "none"] },
436
+ { "name": "parallax", "type": "Boolean", "default": false, "required": false },
437
+ { "name": "parallaxSpeed", "type": "Number", "default": 0.3, "required": false }
438
+ ]
439
+ },
440
+ {
441
+ "name": "XMarkSectionNewsletter",
442
+ "file": "Section/Newsletter.vue",
443
+ "category": "Section",
444
+ "props": [
445
+ { "name": "title", "type": "String", "default": "Subscribe to our newsletter", "required": false },
446
+ { "name": "description", "type": "String", "default": "Get the latest news and updates.", "required": false },
447
+ { "name": "placeholder", "type": "String", "default": "Enter your email", "required": false },
448
+ { "name": "button", "type": "Object", "default": "{ label: 'Subscribe' }", "required": false },
449
+ { "name": "hasPrivacy", "type": "Boolean", "default": true, "required": false },
450
+ { "name": "privacyText", "type": "String", "default": "No spam. Unsubscribe anytime.", "required": false },
451
+ { "name": "successMessage", "type": "String", "default": "Thanks for subscribing!", "required": false },
452
+ { "name": "variant", "type": "String", "default": "dark", "required": false, "options": ["dark", "light"] },
453
+ { "name": "pattern", "type": "String", "default": null, "required": false, "options": ["dots", "grid", "diagonal", "topography", "circuit", "waves"] },
454
+ { "name": "patternOpacity", "type": "Number", "default": 0.05, "required": false },
455
+ { "name": "resetDelay", "type": "Number", "default": 5000, "required": false }
456
+ ],
457
+ "events": [
458
+ { "name": "submit", "payload": "String", "description": "Emitted with email address when form is submitted" }
459
+ ]
460
+ },
461
+ {
462
+ "name": "XMarkSectionStitch",
463
+ "file": "Section/Stitch.vue",
464
+ "category": "Section",
465
+ "props": [
466
+ { "name": "variant", "type": "String", "default": "angle", "required": false, "options": ["angle", "wave", "curve", "triangle", "zigzag"] },
467
+ { "name": "topColor", "type": "String", "default": "rgb(243 244 246)", "required": false },
468
+ { "name": "bottomColor", "type": "String", "default": "rgb(249 250 251)", "required": false },
469
+ { "name": "height", "type": "String", "default": "md", "required": false, "options": ["sm", "md", "lg", "xl"] },
470
+ { "name": "flip", "type": "Boolean", "default": false, "required": false },
471
+ { "name": "glow", "type": "Boolean", "default": false, "required": false },
472
+ { "name": "glowColor", "type": "String", "default": "rgba(99, 102, 241, 0.5)", "required": false }
473
+ ]
474
+ },
475
+ {
476
+ "name": "XMarkSocialProofBadge",
477
+ "file": "SocialProof/Badge.vue",
478
+ "category": "SocialProof",
479
+ "props": [
480
+ { "name": "preset", "type": "String", "default": "", "required": false, "options": ["no-credit-card", "cancel-anytime", "free-trial", "secure", "support", "setup", "gdpr", "money-back"] },
481
+ { "name": "icon", "type": "String", "default": "", "required": false },
482
+ { "name": "label", "type": "String", "default": "", "required": false },
483
+ { "name": "variant", "type": "String", "default": "default", "required": false, "options": ["default", "subtle", "outline", "text", "text-muted"] }
484
+ ]
485
+ },
486
+ {
487
+ "name": "XMarkSocialProofTestimonials",
488
+ "file": "SocialProof/Testimonials.vue",
489
+ "category": "SocialProof",
490
+ "props": [
491
+ { "name": "testimonials", "type": "Array", "default": null, "required": true },
492
+ { "name": "layout", "type": "String", "default": "featured", "required": false, "options": ["featured", "grid", "carousel"] },
493
+ { "name": "hasStars", "type": "Boolean", "default": true, "required": false },
494
+ { "name": "autoplay", "type": "Boolean", "default": true, "required": false },
495
+ { "name": "interval", "type": "Number", "default": 5000, "required": false }
496
+ ]
497
+ },
498
+ {
499
+ "name": "XMarkSocialProofToast",
500
+ "file": "SocialProof/Toast.vue",
501
+ "category": "SocialProof",
502
+ "props": [
503
+ { "name": "notifications", "type": "Array", "default": null, "required": true },
504
+ { "name": "interval", "type": "Number", "default": 4000, "required": false },
505
+ { "name": "initialDelay", "type": "Number", "default": 5000, "required": false },
506
+ { "name": "displayDuration", "type": "Number", "default": 3000, "required": false },
507
+ { "name": "placement", "type": "String", "default": "bottomLeft", "required": false, "options": ["topLeft", "topRight", "bottomLeft", "bottomRight"] }
508
+ ]
509
+ }
510
+ ]
511
+ }
package/nuxt.config.ts CHANGED
@@ -1,22 +1,15 @@
1
1
  // https://nuxt.com/docs/api/configuration/nuxt-config
2
- import tailwindcss from "@tailwindcss/vite";
3
- import { fileURLToPath } from 'url';
4
- import { dirname, resolve } from 'path';
2
+ import { resolve } from "path";
3
+
5
4
  export default defineNuxtConfig({
6
- compatibilityDate: "2024-04-03",
5
+ compatibilityDate: "2026-01-04",
7
6
  ssr: true,
8
7
  devtools: { enabled: process.env.NODE_ENV === "development" },
9
8
  runtimeConfig: {
10
9
  public: {
11
- BUILDERIO_KEY: "",
10
+
12
11
  },
13
12
  },
14
- modules: ["@nuxt/ui", "@nuxtjs/seo", "@nuxt/image"],
15
- css: [resolve(__dirname, 'app/assets/css/main.css')],
16
- ui: {
17
- icons: ["heroicons", "simple-icons"],
18
- },
19
- vite: {
20
- plugins: [tailwindcss()],
21
- },
13
+ modules: ["@nuxt/ui"],
14
+ css: [resolve(__dirname, "app/assets/css/x-marketing.css")],
22
15
  });
package/package.json CHANGED
@@ -1,28 +1,40 @@
1
1
  {
2
2
  "name": "@xenterprises/nuxt-x-marketing",
3
3
  "type": "module",
4
- "version": "0.0.23",
4
+ "version": "1.0.0",
5
5
  "main": "./nuxt.config.ts",
6
6
  "scripts": {
7
7
  "dev": "nuxi dev .playground",
8
8
  "dev:prepare": "nuxt prepare .playground",
9
9
  "build": "nuxt build .playground",
10
10
  "generate": "nuxt generate .playground",
11
- "preview": "nuxt preview .playground"
11
+ "preview": "nuxt preview .playground",
12
+ "test": "npm run test:unit && npm run test:e2e",
13
+ "test:unit": "vitest run --config test/vitest.config.js",
14
+ "test:unit:watch": "vitest --config test/vitest.config.js",
15
+ "test:unit:coverage": "vitest run --config test/vitest.config.js --coverage",
16
+ "test:e2e": "playwright test --config test/playwright.config.js",
17
+ "test:e2e:ui": "playwright test --config test/playwright.config.js --ui",
18
+ "test:e2e:headed": "playwright test --config test/playwright.config.js --headed",
19
+ "test:visual": "playwright test --config test/playwright.config.js visual-regression",
20
+ "test:visual:update": "playwright test --config test/playwright.config.js visual-regression --update-snapshots"
12
21
  },
13
22
  "devDependencies": {
23
+ "@axe-core/playwright": "^4.8.4",
24
+ "@iconify-json/lucide": "^1.2.82",
25
+ "@playwright/test": "^1.41.1",
26
+ "@vitejs/plugin-vue": "^5.0.3",
27
+ "@vitest/coverage-v8": "^2.1.8",
28
+ "@vue/test-utils": "^2.4.4",
29
+ "happy-dom": "^13.3.8",
14
30
  "nuxt": "^4.2.1",
15
31
  "typescript": "^5.6.3",
32
+ "vitest": "^2.1.8",
16
33
  "vue": "latest"
17
34
  },
18
35
  "dependencies": {
19
- "@marker.io/browser": "^0.19.0",
20
- "@nuxt/image": "^2.0.0",
21
- "@nuxt/ui": "^4.0.0",
22
- "@nuxtjs/seo": "^3.2.2",
23
- "@tailwindcss/vite": "^4.1.17",
24
- "simple-icons": "^13.15.0",
25
- "tailwindcss": "^4.1.17",
36
+ "@marker.io/browser": "^0.20.2",
37
+ "@nuxt/ui": "^4.3.0",
26
38
  "zod": "^3.23.8"
27
39
  }
28
40
  }
package/.editorconfig DELETED
@@ -1,12 +0,0 @@
1
- root = true
2
-
3
- [*]
4
- indent_size = 2
5
- indent_style = space
6
- end_of_line = lf
7
- charset = utf-8
8
- trim_trailing_whitespace = true
9
- insert_final_newline = true
10
-
11
- [*.md]
12
- trim_trailing_whitespace = false
@@ -1,2 +0,0 @@
1
- @import "tailwindcss";
2
- @import "@nuxt/ui";