@o2vend/theme-cli 1.0.32

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 (116) hide show
  1. package/README.md +425 -0
  2. package/assets/Logo_o2vend.png +0 -0
  3. package/assets/favicon.png +0 -0
  4. package/assets/logo-white.png +0 -0
  5. package/bin/o2vend +42 -0
  6. package/config/widget-map.json +50 -0
  7. package/lib/commands/check.js +201 -0
  8. package/lib/commands/generate.js +33 -0
  9. package/lib/commands/init.js +214 -0
  10. package/lib/commands/optimize.js +216 -0
  11. package/lib/commands/package.js +208 -0
  12. package/lib/commands/serve.js +105 -0
  13. package/lib/commands/validate.js +191 -0
  14. package/lib/lib/api-client.js +357 -0
  15. package/lib/lib/dev-server.js +2618 -0
  16. package/lib/lib/file-watcher.js +80 -0
  17. package/lib/lib/hot-reload.js +106 -0
  18. package/lib/lib/liquid-engine.js +822 -0
  19. package/lib/lib/liquid-filters.js +671 -0
  20. package/lib/lib/mock-api-server.js +989 -0
  21. package/lib/lib/mock-data.js +1468 -0
  22. package/lib/lib/widget-service.js +321 -0
  23. package/package.json +70 -0
  24. package/test-theme/README.md +27 -0
  25. package/test-theme/assets/async-sections.js +446 -0
  26. package/test-theme/assets/cart-drawer.js +463 -0
  27. package/test-theme/assets/cart-manager.js +223 -0
  28. package/test-theme/assets/checkout-price-handler.js +368 -0
  29. package/test-theme/assets/components.css +4629 -0
  30. package/test-theme/assets/delivery-zone.css +299 -0
  31. package/test-theme/assets/delivery-zone.js +396 -0
  32. package/test-theme/assets/logo.png +0 -0
  33. package/test-theme/assets/sections.css +48 -0
  34. package/test-theme/assets/theme.css +3500 -0
  35. package/test-theme/assets/theme.js +3745 -0
  36. package/test-theme/config/settings_data.json +292 -0
  37. package/test-theme/config/settings_schema.json +1050 -0
  38. package/test-theme/layout/theme.liquid +195 -0
  39. package/test-theme/locales/en.default.json +260 -0
  40. package/test-theme/sections/content-fallback.liquid +53 -0
  41. package/test-theme/sections/content.liquid +57 -0
  42. package/test-theme/sections/footer-fallback.liquid +328 -0
  43. package/test-theme/sections/footer.liquid +278 -0
  44. package/test-theme/sections/header-fallback.liquid +1805 -0
  45. package/test-theme/sections/header.liquid +1145 -0
  46. package/test-theme/sections/hero-fallback.liquid +212 -0
  47. package/test-theme/sections/hero.liquid +136 -0
  48. package/test-theme/snippets/account-sidebar.liquid +200 -0
  49. package/test-theme/snippets/add-to-cart-modal.liquid +484 -0
  50. package/test-theme/snippets/breadcrumbs.liquid +134 -0
  51. package/test-theme/snippets/cart-drawer.liquid +467 -0
  52. package/test-theme/snippets/delivery-zone-city-selector.liquid +79 -0
  53. package/test-theme/snippets/delivery-zone-modal.liquid +337 -0
  54. package/test-theme/snippets/delivery-zone-search.liquid +78 -0
  55. package/test-theme/snippets/icon.liquid +105 -0
  56. package/test-theme/snippets/login-modal.liquid +346 -0
  57. package/test-theme/snippets/mega-menu.liquid +812 -0
  58. package/test-theme/snippets/news-thumbnail.liquid +187 -0
  59. package/test-theme/snippets/pagination.liquid +120 -0
  60. package/test-theme/snippets/price.liquid +92 -0
  61. package/test-theme/snippets/product-card-related.liquid +78 -0
  62. package/test-theme/snippets/product-card-simple.liquid +41 -0
  63. package/test-theme/snippets/product-card.liquid +697 -0
  64. package/test-theme/snippets/rating.liquid +85 -0
  65. package/test-theme/snippets/skeleton-collection-grid.liquid +114 -0
  66. package/test-theme/snippets/skeleton-product-card.liquid +124 -0
  67. package/test-theme/snippets/skeleton-product-grid.liquid +34 -0
  68. package/test-theme/snippets/social-sharing.liquid +185 -0
  69. package/test-theme/templates/account/dashboard.liquid +401 -0
  70. package/test-theme/templates/account/loyalty-redemption.liquid +405 -0
  71. package/test-theme/templates/account/loyalty.liquid +588 -0
  72. package/test-theme/templates/account/order-detail.liquid +230 -0
  73. package/test-theme/templates/account/orders.liquid +349 -0
  74. package/test-theme/templates/account/profile.liquid +758 -0
  75. package/test-theme/templates/account/register.liquid +232 -0
  76. package/test-theme/templates/account/return-orders.liquid +348 -0
  77. package/test-theme/templates/account/store-credit.liquid +464 -0
  78. package/test-theme/templates/account/subscriptions.liquid +601 -0
  79. package/test-theme/templates/account/wishlist.liquid +419 -0
  80. package/test-theme/templates/address-book.liquid +1092 -0
  81. package/test-theme/templates/categories.liquid +452 -0
  82. package/test-theme/templates/checkout.liquid +4511 -0
  83. package/test-theme/templates/error.liquid +384 -0
  84. package/test-theme/templates/index.liquid +11 -0
  85. package/test-theme/templates/login.liquid +185 -0
  86. package/test-theme/templates/order-confirmation.liquid +720 -0
  87. package/test-theme/templates/page.liquid +297 -0
  88. package/test-theme/templates/product-detail.liquid +4363 -0
  89. package/test-theme/templates/products.liquid +518 -0
  90. package/test-theme/templates/search.liquid +922 -0
  91. package/test-theme/theme.json.example +19 -0
  92. package/test-theme/widgets/brand-carousel.liquid +676 -0
  93. package/test-theme/widgets/brand.liquid +245 -0
  94. package/test-theme/widgets/carousel.liquid +843 -0
  95. package/test-theme/widgets/category-list-carousel.liquid +656 -0
  96. package/test-theme/widgets/category-list.liquid +340 -0
  97. package/test-theme/widgets/category.liquid +475 -0
  98. package/test-theme/widgets/discount-time.liquid +176 -0
  99. package/test-theme/widgets/footer-menu.liquid +695 -0
  100. package/test-theme/widgets/footer.liquid +179 -0
  101. package/test-theme/widgets/gallery.liquid +271 -0
  102. package/test-theme/widgets/header-menu.liquid +932 -0
  103. package/test-theme/widgets/header.liquid +159 -0
  104. package/test-theme/widgets/html.liquid +214 -0
  105. package/test-theme/widgets/news.liquid +217 -0
  106. package/test-theme/widgets/product-canvas.liquid +235 -0
  107. package/test-theme/widgets/product-carousel.liquid +502 -0
  108. package/test-theme/widgets/product.liquid +45 -0
  109. package/test-theme/widgets/recently-viewed.liquid +26 -0
  110. package/test-theme/widgets/shared/product-grid.liquid +339 -0
  111. package/test-theme/widgets/simple-product.liquid +42 -0
  112. package/test-theme/widgets/single-product.liquid +610 -0
  113. package/test-theme/widgets/spacebar-carousel.liquid +663 -0
  114. package/test-theme/widgets/spacebar.liquid +279 -0
  115. package/test-theme/widgets/splash.liquid +378 -0
  116. package/test-theme/widgets/testimonial-carousel.liquid +709 -0
@@ -0,0 +1,235 @@
1
+ {% liquid
2
+ assign widget_settings = widget.settings
3
+ assign widget_data = widget.data
4
+
5
+ comment
6
+ Static Widget: Content comes from widget_data.content (Items array with X, Y, TargetUrl)
7
+ Settings come from widget_settings
8
+ endcomment
9
+
10
+ assign content_data = widget_data.content | default: widget.content
11
+ assign items = content_data.Items | default: content_data.items | default: widget_data.Items | default: widget_data.items
12
+ assign image_url = widget_settings.imageUrl | default: widget_settings.ImageUrl | default: content_data.ImageUrl | default: content_data.imageUrl
13
+ assign show_container = widget_settings.showContainer | default: content_data.ShowContainer | default: 'Default'
14
+ assign show_bottom_margin = widget_settings.showWidgetBottomMargin | default: content_data.ShowWidgetBottomMargin | default: 'Default'
15
+ assign background_color = widget_settings.backgroundColor | default: widget_settings.BackgroundColor | default: content_data.BackgroundColor | default: content_data.backgroundColor
16
+ %}
17
+
18
+ {% if image_url and image_url != blank and image_url != 'null' %}
19
+ {% liquid
20
+ assign bottom_margin_class = 'm-b-25'
21
+ if show_bottom_margin == 'No' or show_bottom_margin == null or show_bottom_margin == 'null'
22
+ assign bottom_margin_class = 'm-b-0'
23
+ elsif show_bottom_margin == 'Yes' or show_bottom_margin == 'Default'
24
+ assign bottom_margin_class = 'm-b-25'
25
+ endif
26
+
27
+ comment
28
+ Container logic based on section and ShowContainer:
29
+ - section == "hero" + ShowContainer == "No" or ("Default"/null in hero) → no container
30
+ - section != "hero" + ShowContainer == ("Default"/null) or ShowContainer == "Yes" → with container
31
+ - ShowContainer == "No" → no container
32
+ - ShowContainer == "Yes" → with container
33
+ endcomment
34
+ assign widget_section = widget.section | default: 'hero'
35
+ assign use_container = true
36
+
37
+ if show_container == 'No'
38
+ assign use_container = false
39
+ else
40
+ if show_container == 'Yes'
41
+ assign use_container = true
42
+ else
43
+ if widget_section == 'hero'
44
+ assign use_container = false
45
+ else
46
+ assign use_container = true
47
+ endif
48
+ endif
49
+ endif
50
+ %}
51
+
52
+ <section class="widget widget-product-canvas" data-widget-id="{{ widget.id }}"{% if background_color and background_color != blank and background_color != 'null' %} style="background-color: {{ background_color }};"{% endif %}>
53
+ {% if use_container %}
54
+ <div class="container canvas {{ bottom_margin_class }} fade-in-animation">
55
+ {% else %}
56
+ <div class="{{ bottom_margin_class }}">
57
+ <div class="canvas fade-in-animation">
58
+ {% endif %}
59
+
60
+ {% if image_url contains 'http://' or image_url contains 'https://' %}
61
+ {% assign image_src = image_url %}
62
+ {% else %}
63
+ {% assign image_src = image_url | asset_url %}
64
+ {% endif %}
65
+
66
+ <img src="{{ image_src }}" alt="{{ widget_settings.title | default: 'Product Canvas' | default: 'Canvas' }}" width="1200" height="800" loading="lazy" style="height: auto;">
67
+
68
+ {% if items and items.size > 0 %}
69
+ {% for item in items %}
70
+ {% assign item_x = item.X | default: item.x | default: 0 %}
71
+ {% assign item_y = item.Y | default: item.y | default: 0 %}
72
+ {% assign item_url = item.TargetUrl | default: item.targetUrl | default: item.Url | default: item.url | default: '#' %}
73
+
74
+ <a style="left: {{ item_x }}%; top: {{ item_y }}%;" class="anchor-icon pulse-grow-on-hover" href="{{ item_url }}" target="_blank" aria-label="Product link {{ forloop.index }}">
75
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="transform: rotate(90deg);">
76
+ <path d="M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z"></path>
77
+ <line x1="7" y1="7" x2="7.01" y2="7"></line>
78
+ </svg>
79
+ </a>
80
+ {% endfor %}
81
+ {% endif %}
82
+
83
+ {% if use_container %}
84
+ </div>
85
+ {% else %}
86
+ </div>
87
+ </div>
88
+ {% endif %}
89
+ </section>
90
+
91
+ <style>
92
+ /* Product Canvas Widget */
93
+ .widget-product-canvas {
94
+ width: 100%;
95
+ padding: 0;
96
+ }
97
+
98
+ .widget-product-canvas .canvas {
99
+ position: relative;
100
+ width: 100%;
101
+ max-width: 100%;
102
+ margin: 0 auto;
103
+ overflow: hidden;
104
+ }
105
+
106
+ .widget-product-canvas .canvas img {
107
+ width: 100%;
108
+ height: auto;
109
+ display: block;
110
+ object-fit: contain;
111
+ border-radius: var(--border-radius-medium);
112
+ }
113
+
114
+ /* Anchor Icons - Positioned at X%, Y% */
115
+ .widget-product-canvas .anchor-icon {
116
+ position: absolute;
117
+ display: flex;
118
+ align-items: center;
119
+ justify-content: center;
120
+ width: 48px;
121
+ height: 48px;
122
+ background: rgba(255, 255, 255, 0.9);
123
+ border: 2px solid {{ settings.color_text }};
124
+ border-radius: 50%;
125
+ color: {{ settings.color_text }};
126
+ text-decoration: none;
127
+ transition: all 0.3s ease;
128
+ z-index: 10;
129
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
130
+ }
131
+
132
+ .widget-product-canvas .anchor-icon svg {
133
+ width: 20px;
134
+ height: 20px;
135
+ }
136
+
137
+ .widget-product-canvas .anchor-icon:hover {
138
+ background: {{ settings.color_text }};
139
+ color: {{ settings.color_background }};
140
+ transform: scale(1.15);
141
+ box-shadow: 0 6px 20px rgba(0, 0, 0, 0.25);
142
+ }
143
+
144
+ /* Pulse Grow on Hover Animation */
145
+ .pulse-grow-on-hover {
146
+ animation: pulse 2s infinite;
147
+ }
148
+
149
+ @keyframes pulse {
150
+ 0%, 100% {
151
+ transform: scale(1);
152
+ opacity: 1;
153
+ }
154
+ 50% {
155
+ transform: scale(1.05);
156
+ opacity: 0.9;
157
+ }
158
+ }
159
+
160
+ .pulse-grow-on-hover:hover {
161
+ animation: none;
162
+ }
163
+
164
+ /* Fade In Animation */
165
+ .fade-in-animation {
166
+ animation: fadeIn 0.6s ease-in;
167
+ }
168
+
169
+ @keyframes fadeIn {
170
+ from {
171
+ opacity: 0;
172
+ transform: translateY(20px);
173
+ }
174
+ to {
175
+ opacity: 1;
176
+ transform: translateY(0);
177
+ }
178
+ }
179
+
180
+ /* Bottom Margin Classes */
181
+ .m-b-25 {
182
+ margin-bottom: 25px;
183
+ }
184
+
185
+ .m-b-0 {
186
+ margin-bottom: 0;
187
+ }
188
+
189
+ /* Container */
190
+ .widget-product-canvas .container {
191
+ max-width: {{ settings.container_width }}px;
192
+ margin: 0 auto;
193
+ padding: 0 {{ settings.container_padding }}px;
194
+ }
195
+
196
+ /* Mobile Responsive */
197
+ @media (max-width: 768px) {
198
+ .widget-product-canvas .anchor-icon {
199
+ width: 40px;
200
+ height: 40px;
201
+ }
202
+
203
+ .widget-product-canvas .anchor-icon svg {
204
+ width: 16px;
205
+ height: 16px;
206
+ }
207
+
208
+ .widget-product-canvas .container {
209
+ padding: 0 {{ settings.spacing_element }}px;
210
+ }
211
+ }
212
+
213
+ @media (max-width: 480px) {
214
+ .widget-product-canvas .anchor-icon {
215
+ width: 36px;
216
+ height: 36px;
217
+ }
218
+
219
+ .widget-product-canvas .anchor-icon svg {
220
+ width: 14px;
221
+ height: 14px;
222
+ }
223
+
224
+ .widget-product-canvas .container {
225
+ padding: 0 {{ settings.spacing_small }}px;
226
+ }
227
+ }
228
+ </style>
229
+ {% else %}
230
+ <section class="widget widget-product-canvas widget-product-canvas--empty" data-widget-id="{{ widget.id }}">
231
+ <div class="widget-empty" style="padding: {{ settings.spacing_section }}px {{ settings.container_padding }}px; text-align: center;">
232
+ <p style="color: {{ settings.color_text_muted }}; margin: 0;">{{ widget_settings.empty_state | default: 'Please configure an image URL for the product canvas.' }}</p>
233
+ </div>
234
+ </section>
235
+ {% endif %}