@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.
- package/README.md +425 -0
- package/assets/Logo_o2vend.png +0 -0
- package/assets/favicon.png +0 -0
- package/assets/logo-white.png +0 -0
- package/bin/o2vend +42 -0
- package/config/widget-map.json +50 -0
- package/lib/commands/check.js +201 -0
- package/lib/commands/generate.js +33 -0
- package/lib/commands/init.js +214 -0
- package/lib/commands/optimize.js +216 -0
- package/lib/commands/package.js +208 -0
- package/lib/commands/serve.js +105 -0
- package/lib/commands/validate.js +191 -0
- package/lib/lib/api-client.js +357 -0
- package/lib/lib/dev-server.js +2618 -0
- package/lib/lib/file-watcher.js +80 -0
- package/lib/lib/hot-reload.js +106 -0
- package/lib/lib/liquid-engine.js +822 -0
- package/lib/lib/liquid-filters.js +671 -0
- package/lib/lib/mock-api-server.js +989 -0
- package/lib/lib/mock-data.js +1468 -0
- package/lib/lib/widget-service.js +321 -0
- package/package.json +70 -0
- package/test-theme/README.md +27 -0
- package/test-theme/assets/async-sections.js +446 -0
- package/test-theme/assets/cart-drawer.js +463 -0
- package/test-theme/assets/cart-manager.js +223 -0
- package/test-theme/assets/checkout-price-handler.js +368 -0
- package/test-theme/assets/components.css +4629 -0
- package/test-theme/assets/delivery-zone.css +299 -0
- package/test-theme/assets/delivery-zone.js +396 -0
- package/test-theme/assets/logo.png +0 -0
- package/test-theme/assets/sections.css +48 -0
- package/test-theme/assets/theme.css +3500 -0
- package/test-theme/assets/theme.js +3745 -0
- package/test-theme/config/settings_data.json +292 -0
- package/test-theme/config/settings_schema.json +1050 -0
- package/test-theme/layout/theme.liquid +195 -0
- package/test-theme/locales/en.default.json +260 -0
- package/test-theme/sections/content-fallback.liquid +53 -0
- package/test-theme/sections/content.liquid +57 -0
- package/test-theme/sections/footer-fallback.liquid +328 -0
- package/test-theme/sections/footer.liquid +278 -0
- package/test-theme/sections/header-fallback.liquid +1805 -0
- package/test-theme/sections/header.liquid +1145 -0
- package/test-theme/sections/hero-fallback.liquid +212 -0
- package/test-theme/sections/hero.liquid +136 -0
- package/test-theme/snippets/account-sidebar.liquid +200 -0
- package/test-theme/snippets/add-to-cart-modal.liquid +484 -0
- package/test-theme/snippets/breadcrumbs.liquid +134 -0
- package/test-theme/snippets/cart-drawer.liquid +467 -0
- package/test-theme/snippets/delivery-zone-city-selector.liquid +79 -0
- package/test-theme/snippets/delivery-zone-modal.liquid +337 -0
- package/test-theme/snippets/delivery-zone-search.liquid +78 -0
- package/test-theme/snippets/icon.liquid +105 -0
- package/test-theme/snippets/login-modal.liquid +346 -0
- package/test-theme/snippets/mega-menu.liquid +812 -0
- package/test-theme/snippets/news-thumbnail.liquid +187 -0
- package/test-theme/snippets/pagination.liquid +120 -0
- package/test-theme/snippets/price.liquid +92 -0
- package/test-theme/snippets/product-card-related.liquid +78 -0
- package/test-theme/snippets/product-card-simple.liquid +41 -0
- package/test-theme/snippets/product-card.liquid +697 -0
- package/test-theme/snippets/rating.liquid +85 -0
- package/test-theme/snippets/skeleton-collection-grid.liquid +114 -0
- package/test-theme/snippets/skeleton-product-card.liquid +124 -0
- package/test-theme/snippets/skeleton-product-grid.liquid +34 -0
- package/test-theme/snippets/social-sharing.liquid +185 -0
- package/test-theme/templates/account/dashboard.liquid +401 -0
- package/test-theme/templates/account/loyalty-redemption.liquid +405 -0
- package/test-theme/templates/account/loyalty.liquid +588 -0
- package/test-theme/templates/account/order-detail.liquid +230 -0
- package/test-theme/templates/account/orders.liquid +349 -0
- package/test-theme/templates/account/profile.liquid +758 -0
- package/test-theme/templates/account/register.liquid +232 -0
- package/test-theme/templates/account/return-orders.liquid +348 -0
- package/test-theme/templates/account/store-credit.liquid +464 -0
- package/test-theme/templates/account/subscriptions.liquid +601 -0
- package/test-theme/templates/account/wishlist.liquid +419 -0
- package/test-theme/templates/address-book.liquid +1092 -0
- package/test-theme/templates/categories.liquid +452 -0
- package/test-theme/templates/checkout.liquid +4511 -0
- package/test-theme/templates/error.liquid +384 -0
- package/test-theme/templates/index.liquid +11 -0
- package/test-theme/templates/login.liquid +185 -0
- package/test-theme/templates/order-confirmation.liquid +720 -0
- package/test-theme/templates/page.liquid +297 -0
- package/test-theme/templates/product-detail.liquid +4363 -0
- package/test-theme/templates/products.liquid +518 -0
- package/test-theme/templates/search.liquid +922 -0
- package/test-theme/theme.json.example +19 -0
- package/test-theme/widgets/brand-carousel.liquid +676 -0
- package/test-theme/widgets/brand.liquid +245 -0
- package/test-theme/widgets/carousel.liquid +843 -0
- package/test-theme/widgets/category-list-carousel.liquid +656 -0
- package/test-theme/widgets/category-list.liquid +340 -0
- package/test-theme/widgets/category.liquid +475 -0
- package/test-theme/widgets/discount-time.liquid +176 -0
- package/test-theme/widgets/footer-menu.liquid +695 -0
- package/test-theme/widgets/footer.liquid +179 -0
- package/test-theme/widgets/gallery.liquid +271 -0
- package/test-theme/widgets/header-menu.liquid +932 -0
- package/test-theme/widgets/header.liquid +159 -0
- package/test-theme/widgets/html.liquid +214 -0
- package/test-theme/widgets/news.liquid +217 -0
- package/test-theme/widgets/product-canvas.liquid +235 -0
- package/test-theme/widgets/product-carousel.liquid +502 -0
- package/test-theme/widgets/product.liquid +45 -0
- package/test-theme/widgets/recently-viewed.liquid +26 -0
- package/test-theme/widgets/shared/product-grid.liquid +339 -0
- package/test-theme/widgets/simple-product.liquid +42 -0
- package/test-theme/widgets/single-product.liquid +610 -0
- package/test-theme/widgets/spacebar-carousel.liquid +663 -0
- package/test-theme/widgets/spacebar.liquid +279 -0
- package/test-theme/widgets/splash.liquid +378 -0
- 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 %}
|