@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,337 @@
1
+ {% comment %}
2
+ Delivery Zone Selection Modal
3
+ Supports three modes: Zipcode (with/without search), City, AutoDetect
4
+ {% endcomment %}
5
+
6
+ <div class="delivery-zone-modal" id="delivery-zone-modal" aria-hidden="true" data-show-modal="{{ deliveryZone.showModal }}">
7
+ <div class="delivery-zone-overlay" data-zone-overlay></div>
8
+ <div class="delivery-zone-panel" role="dialog" aria-label="Select delivery location">
9
+ <header class="delivery-zone-header">
10
+ <h3 class="delivery-zone-title">Enter pincode for delivery location</h3>
11
+ <button class="delivery-zone-close" aria-label="Close" data-zone-close>
12
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
13
+ <line x1="18" y1="6" x2="6" y2="18"></line>
14
+ <line x1="6" y1="6" x2="18" y2="18"></line>
15
+ </svg>
16
+ </button>
17
+ </header>
18
+
19
+ <div class="delivery-zone-content">
20
+ <form class="delivery-zone-form" id="delivery-zone-form">
21
+ {% if deliveryZone.mode == 0 %}
22
+ {% comment %} Zipcode Mode {% endcomment %}
23
+ {% if deliveryZone.zipcodeSearchEnabled %}
24
+ {% include 'snippets/delivery-zone-search' %}
25
+ {% else %}
26
+ <div class="delivery-zone-input-group">
27
+ <input
28
+ type="text"
29
+ id="delivery-zone-zipcode"
30
+ name="zipcode"
31
+ class="delivery-zone-input"
32
+ placeholder="Enter Location"
33
+ value="{{ deliveryZone.defaultZipcode }}"
34
+ required
35
+ maxlength="10">
36
+ <svg class="delivery-zone-search-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
37
+ <circle cx="11" cy="11" r="8"></circle>
38
+ <path d="m21 21-4.35-4.35"></path>
39
+ </svg>
40
+ </div>
41
+ {% endif %}
42
+ {% elsif deliveryZone.mode == 1 %}
43
+ {% comment %} City Mode {% endcomment %}
44
+ {% include 'snippets/delivery-zone-city-selector' %}
45
+ {% elsif deliveryZone.mode == 2 %}
46
+ {% comment %} AutoDetect Mode {% endcomment %}
47
+ <div class="delivery-zone-autodetect">
48
+ <button type="button" class="btn btn-primary btn-lg delivery-zone-detect-btn" id="detect-location-btn">
49
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
50
+ <path d="M12 2v20M2 12h20"/>
51
+ </svg>
52
+ Detect My Location
53
+ </button>
54
+ <div class="delivery-zone-or-divider">
55
+ <span>OR</span>
56
+ </div>
57
+ <div class="delivery-zone-input-group">
58
+ <input
59
+ type="text"
60
+ id="delivery-zone-zipcode"
61
+ name="zipcode"
62
+ class="delivery-zone-input"
63
+ placeholder="Enter Location"
64
+ value="{{ deliveryZone.defaultZipcode }}">
65
+ <svg class="delivery-zone-search-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
66
+ <circle cx="11" cy="11" r="8"></circle>
67
+ <path d="m21 21-4.35-4.35"></path>
68
+ </svg>
69
+ </div>
70
+ </div>
71
+ {% endif %}
72
+
73
+ {% if deliveryZone.current %}
74
+ <div class="delivery-zone-current">
75
+ <p class="delivery-zone-current-label">Current location:</p>
76
+ <p class="delivery-zone-current-value">
77
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
78
+ <path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"></path>
79
+ <circle cx="12" cy="10" r="3"></circle>
80
+ </svg>
81
+ {{ deliveryZone.current.zoneName }} {{ deliveryZone.current.zipcode }}
82
+ </p>
83
+ </div>
84
+ {% endif %}
85
+
86
+ <div class="delivery-zone-error" id="delivery-zone-error" style="display: none;"></div>
87
+
88
+ <div class="delivery-zone-actions">
89
+ <button type="submit" class="btn btn-primary btn-lg delivery-zone-submit">
90
+ Continue
91
+ </button>
92
+ </div>
93
+ </form>
94
+ </div>
95
+
96
+ <div class="delivery-zone-loading" id="delivery-zone-loading" style="display: none;">
97
+ <div class="spinner"></div>
98
+ <p>Loading...</p>
99
+ </div>
100
+ </div>
101
+ </div>
102
+
103
+ <style>
104
+ .delivery-zone-modal {
105
+ position: fixed;
106
+ inset: 0;
107
+ z-index: 9999;
108
+ display: none;
109
+ }
110
+
111
+ .delivery-zone-modal.active {
112
+ display: flex;
113
+ align-items: center;
114
+ justify-content: center;
115
+ }
116
+
117
+ .delivery-zone-overlay {
118
+ position: absolute;
119
+ inset: 0;
120
+ background: rgba(0, 0, 0, 0.5);
121
+ backdrop-filter: blur(4px);
122
+ }
123
+
124
+ .delivery-zone-panel {
125
+ position: relative;
126
+ background: white;
127
+ border-radius: 16px;
128
+ box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
129
+ width: 90%;
130
+ max-width: 500px;
131
+ max-height: 90vh;
132
+ overflow: hidden;
133
+ display: flex;
134
+ flex-direction: column;
135
+ }
136
+
137
+ .delivery-zone-header {
138
+ display: flex;
139
+ align-items: center;
140
+ justify-content: space-between;
141
+ padding: 24px;
142
+ border-bottom: 1px solid #e5e7eb;
143
+ }
144
+
145
+ .delivery-zone-title {
146
+ margin: 0;
147
+ font-size: 20px;
148
+ font-weight: 600;
149
+ color: #111827;
150
+ }
151
+
152
+ .delivery-zone-close {
153
+ background: none;
154
+ border: none;
155
+ cursor: pointer;
156
+ color: #6b7280;
157
+ padding: 4px;
158
+ display: flex;
159
+ align-items: center;
160
+ justify-content: center;
161
+ }
162
+
163
+ .delivery-zone-close:hover {
164
+ color: #111827;
165
+ }
166
+
167
+ .delivery-zone-content {
168
+ padding: 24px;
169
+ overflow-y: auto;
170
+ }
171
+
172
+ .delivery-zone-form {
173
+ display: flex;
174
+ flex-direction: column;
175
+ gap: 20px;
176
+ }
177
+
178
+ .delivery-zone-input-group {
179
+ position: relative;
180
+ display: flex;
181
+ align-items: center;
182
+ }
183
+
184
+ .delivery-zone-input {
185
+ width: 100%;
186
+ padding: 14px 48px 14px 20px;
187
+ border: 2px solid #a78bfa;
188
+ border-radius: 12px;
189
+ font-size: 16px;
190
+ transition: all 0.2s ease;
191
+ background: white;
192
+ }
193
+
194
+ .delivery-zone-input:focus {
195
+ outline: none;
196
+ border-color: #7c3aed;
197
+ box-shadow: 0 0 0 3px rgba(124, 58, 237, 0.1);
198
+ }
199
+
200
+ .delivery-zone-search-icon {
201
+ position: absolute;
202
+ right: 16px;
203
+ color: #a78bfa;
204
+ pointer-events: none;
205
+ }
206
+
207
+ .delivery-zone-autodetect {
208
+ display: flex;
209
+ flex-direction: column;
210
+ gap: 16px;
211
+ }
212
+
213
+ .delivery-zone-detect-btn {
214
+ display: flex;
215
+ align-items: center;
216
+ justify-content: center;
217
+ gap: 8px;
218
+ width: 100%;
219
+ padding: 14px;
220
+ font-size: 16px;
221
+ }
222
+
223
+ .delivery-zone-or-divider {
224
+ display: flex;
225
+ align-items: center;
226
+ gap: 12px;
227
+ text-transform: uppercase;
228
+ font-size: 12px;
229
+ font-weight: 600;
230
+ color: #6b7280;
231
+ text-align: center;
232
+ }
233
+
234
+ .delivery-zone-or-divider::before,
235
+ .delivery-zone-or-divider::after {
236
+ content: '';
237
+ flex: 1;
238
+ height: 1px;
239
+ background: #e5e7eb;
240
+ }
241
+
242
+ .delivery-zone-current {
243
+ padding: 16px;
244
+ background: #f3f4f6;
245
+ border-radius: 8px;
246
+ display: flex;
247
+ flex-direction: column;
248
+ gap: 4px;
249
+ }
250
+
251
+ .delivery-zone-current-label {
252
+ margin: 0;
253
+ font-size: 12px;
254
+ color: #6b7280;
255
+ text-transform: uppercase;
256
+ font-weight: 600;
257
+ }
258
+
259
+ .delivery-zone-current-value {
260
+ margin: 0;
261
+ font-size: 14px;
262
+ color: #111827;
263
+ font-weight: 600;
264
+ display: flex;
265
+ align-items: center;
266
+ gap: 8px;
267
+ }
268
+
269
+ .delivery-zone-error {
270
+ padding: 12px 16px;
271
+ background: #fef2f2;
272
+ border: 1px solid #fecaca;
273
+ border-radius: 8px;
274
+ color: #991b1b;
275
+ font-size: 14px;
276
+ }
277
+
278
+ .delivery-zone-actions {
279
+ display: flex;
280
+ gap: 12px;
281
+ }
282
+
283
+ .delivery-zone-submit {
284
+ flex: 1;
285
+ padding: 14px;
286
+ font-size: 16px;
287
+ font-weight: 600;
288
+ }
289
+
290
+ .delivery-zone-loading {
291
+ position: absolute;
292
+ inset: 0;
293
+ background: rgba(255, 255, 255, 0.95);
294
+ display: flex;
295
+ flex-direction: column;
296
+ align-items: center;
297
+ justify-content: center;
298
+ gap: 16px;
299
+ }
300
+
301
+ .spinner {
302
+ width: 40px;
303
+ height: 40px;
304
+ border: 4px solid #e5e7eb;
305
+ border-top-color: #a78bfa;
306
+ border-radius: 50%;
307
+ animation: spin 0.8s linear infinite;
308
+ }
309
+
310
+ @keyframes spin {
311
+ to { transform: rotate(360deg); }
312
+ }
313
+
314
+ /* Mobile responsive */
315
+ @media (max-width: 640px) {
316
+ .delivery-zone-panel {
317
+ width: 100%;
318
+ max-width: 100%;
319
+ border-radius: 0;
320
+ height: 100%;
321
+ max-height: 100%;
322
+ }
323
+
324
+ .delivery-zone-header {
325
+ padding: 16px;
326
+ }
327
+
328
+ .delivery-zone-content {
329
+ padding: 16px;
330
+ }
331
+
332
+ .delivery-zone-title {
333
+ font-size: 18px;
334
+ }
335
+ }
336
+ </style>
337
+
@@ -0,0 +1,78 @@
1
+ {% comment %}
2
+ Delivery Zone Zipcode Search with Autocomplete
3
+ {% endcomment %}
4
+
5
+ <div class="delivery-zone-search-container">
6
+ <input
7
+ type="text"
8
+ id="delivery-zone-zipcode"
9
+ name="zipcode"
10
+ class="delivery-zone-input"
11
+ placeholder="Enter Location"
12
+ value="{{ deliveryZone.defaultZipcode }}"
13
+ autocomplete="off"
14
+ required
15
+ maxlength="10">
16
+
17
+ <div class="delivery-zone-search-results" id="delivery-zone-search-results" style="display: none;"></div>
18
+ </div>
19
+
20
+ <style>
21
+ .delivery-zone-search-container {
22
+ position: relative;
23
+ width: 100%;
24
+ }
25
+
26
+ .delivery-zone-search-results {
27
+ position: absolute;
28
+ top: 100%;
29
+ left: 0;
30
+ right: 0;
31
+ margin-top: 4px;
32
+ background: white;
33
+ border: 2px solid #e5e7eb;
34
+ border-radius: 8px;
35
+ box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
36
+ max-height: 300px;
37
+ overflow-y: auto;
38
+ z-index: 10;
39
+ }
40
+
41
+ .delivery-zone-search-result {
42
+ padding: 12px 16px;
43
+ cursor: pointer;
44
+ transition: background-color 0.2s ease;
45
+ border-bottom: 1px solid #f3f4f6;
46
+ }
47
+
48
+ .delivery-zone-search-result:last-child {
49
+ border-bottom: none;
50
+ }
51
+
52
+ .delivery-zone-search-result:hover {
53
+ background-color: #f9fafb;
54
+ }
55
+
56
+ .delivery-zone-search-result.active {
57
+ background-color: #f3f4f6;
58
+ }
59
+
60
+ .delivery-zone-result-zipcode {
61
+ font-weight: 600;
62
+ color: #111827;
63
+ margin-bottom: 2px;
64
+ }
65
+
66
+ .delivery-zone-result-details {
67
+ font-size: 12px;
68
+ color: #6b7280;
69
+ }
70
+
71
+ .delivery-zone-search-empty {
72
+ padding: 16px;
73
+ text-align: center;
74
+ color: #6b7280;
75
+ font-size: 14px;
76
+ }
77
+ </style>
78
+
@@ -0,0 +1,105 @@
1
+ {% comment %}
2
+ Icon Component - Modern 2026 Theme
3
+ Supports Heroicons 2.0 outline and solid styles
4
+
5
+ Parameters:
6
+ - name: Icon name (required) - e.g., 'cart', 'search', 'menu', 'heart'
7
+ - size: Icon size in pixels or rem (optional, default: 20)
8
+ - stroke_width: Stroke width (optional, default: 2)
9
+ - class: Additional CSS classes (optional)
10
+ - style: Icon style - 'outline' or 'solid' (optional, default: 'outline')
11
+ - aria_hidden: Hide from screen readers (optional, default: true for decorative icons)
12
+ - aria_label: Accessible label (optional, required if aria_hidden is false)
13
+ {% endcomment %}
14
+
15
+ {% assign icon_name = name | default: 'help' | downcase %}
16
+ {% assign icon_size = size | default: 20 %}
17
+ {% assign icon_stroke_width = stroke_width | default: 2 %}
18
+ {% assign icon_style = style | default: 'outline' %}
19
+ {% assign icon_class = class | default: '' %}
20
+ {% assign icon_aria_hidden = aria_hidden | default: true %}
21
+ {% assign icon_aria_label = aria_label | default: '' %}
22
+
23
+ {% assign size_unit = 'px' %}
24
+ {% if icon_size contains 'rem' or icon_size contains 'em' %}
25
+ {% assign size_unit = '' %}
26
+ {% endif %}
27
+
28
+ {% comment %} Icon mapping - Heroicons 2.0 Outline Icons {% endcomment %}
29
+ {% case icon_name %}
30
+ {% when 'cart', 'shopping-cart', 'shopping-bag' %}
31
+ {% if icon_style == 'solid' %}
32
+ {% capture icon_content %}<path fill-rule="evenodd" d="M2.25 2.25a.75.75 0 0 0 0 1.5h1.306c.183 0 .348.1.465.25l1.956 2.692a.75.75 0 0 1-.5 1.108H2.25a.75.75 0 0 0 0 1.5h9.75a.75.75 0 0 0 0-1.5H6.96l-1.456-2.008a.75.75 0 0 1-.465-.25H2.25ZM9 12a3 3 0 1 0 6 0 3 3 0 0 0-6 0Zm-1.5 1.5a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0Z" clip-rule="evenodd"/>{% endcapture %}
33
+ {% else %}
34
+ {% capture icon_content %}<path stroke-linecap="round" stroke-linejoin="round" d="M2.25 3h1.386c.51 0 .955.343 1.087.835l.383 1.437M7.5 14.25a3 3 0 0 0-3 3h15.75m-12.75-3h11.218c1.121-2.3 2.1-4.684 2.924-7.138a60.114 60.114 0 0 0-16.536-1.84M7.5 14.25 5.106 5.272M6 20.25a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0Zm12.75 0a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0Z"/>{% endcapture %}
35
+ {% endif %}
36
+ {% when 'search', 'magnifying-glass' %}
37
+ {% capture icon_content %}<path stroke-linecap="round" stroke-linejoin="round" d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z"/>{% endcapture %}
38
+ {% when 'menu', 'bars-3', 'hamburger' %}
39
+ {% capture icon_content %}<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5"/>{% endcapture %}
40
+ {% when 'x', 'close', 'times' %}
41
+ {% capture icon_content %}<path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12"/>{% endcapture %}
42
+ {% when 'heart', 'favorite', 'wishlist' %}
43
+ {% if icon_style == 'solid' %}
44
+ {% capture icon_content %}<path d="M11.645 20.91l-.007-.003-.022-.012a15.247 15.247 0 0 1-.383-.218 25.18 25.18 0 0 1-4.244-3.17C4.688 15.36 2.25 12.174 2.25 8.25 2.25 5.322 4.714 3 7.688 3A5.5 5.5 0 0 1 12 5.052 5.5 5.5 0 0 1 16.313 3c2.973 0 5.437 2.322 5.437 5.25 0 3.925-2.438 7.111-4.739 9.256a25.175 25.175 0 0 1-4.244 3.17 15.247 15.247 0 0 1-.383.219l-.022.012-.007.004-.003.001a.752.752 0 0 1-.704 0l-.003-.001Z"/>{% endcapture %}
45
+ {% else %}
46
+ {% capture icon_content %}<path stroke-linecap="round" stroke-linejoin="round" d="M21 8.25c0-2.485-2.099-4.5-4.688-4.5-1.935 0-3.597 1.126-4.312 2.733-.715-1.607-2.377-2.733-4.313-2.733C5.1 3.75 3 5.765 3 8.25c0 7.22 9 12 9 12s9-4.78 9-12Z"/>{% endcapture %}
47
+ {% endif %}
48
+ {% when 'user', 'account', 'person' %}
49
+ {% capture icon_content %}<path stroke-linecap="round" stroke-linejoin="round" d="M15.75 6a3.75 3.75 0 1 1-7.5 0 3.75 3.75 0 0 1 7.5 0ZM4.501 20.118a7.5 7.5 0 0 1 14.998 0A17.933 17.933 0 0 1 12 21.75c-2.676 0-5.216-.584-7.499-1.632Z"/>{% endcapture %}
50
+ {% when 'check', 'checkmark', 'tick' %}
51
+ {% capture icon_content %}<path stroke-linecap="round" stroke-linejoin="round" d="m4.5 12.75 6 6 9-13.5"/>{% endcapture %}
52
+ {% when 'arrow-left', 'chevron-left' %}
53
+ {% capture icon_content %}<path stroke-linecap="round" stroke-linejoin="round" d="M10.5 19.5 3 12m0 0 7.5-7.5M3 12h18"/>{% endcapture %}
54
+ {% when 'arrow-right', 'chevron-right' %}
55
+ {% capture icon_content %}<path stroke-linecap="round" stroke-linejoin="round" d="M13.5 4.5 21 12m0 0-7.5 7.5M21 12H3"/>{% endcapture %}
56
+ {% when 'arrow-up', 'chevron-up' %}
57
+ {% capture icon_content %}<path stroke-linecap="round" stroke-linejoin="round" d="m4.5 15.75 7.5-7.5 7.5 7.5"/>{% endcapture %}
58
+ {% when 'arrow-down', 'chevron-down' %}
59
+ {% capture icon_content %}<path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5"/>{% endcapture %}
60
+ {% when 'star', 'rating' %}
61
+ {% if icon_style == 'solid' %}
62
+ {% capture icon_content %}<path fill-rule="evenodd" d="M10.788 3.21c.448-1.077 1.976-1.077 2.424 0l2.082 5.006 5.404.434c1.164.093 1.636 1.545.749 2.305l-4.117 3.527 1.257 5.273c.271 1.136-.964 2.033-1.96 1.425L12 18.354 7.373 21.18c-.996.608-2.231-.29-1.96-1.425l1.257-5.273-4.117-3.527c-.887-.76-.415-2.212.749-2.305l5.404-.434 2.082-5.005Z" clip-rule="evenodd"/>{% endcapture %}
63
+ {% else %}
64
+ {% capture icon_content %}<path stroke-linecap="round" stroke-linejoin="round" d="M11.48 3.499a.562.562 0 0 1 1.04 0l2.125 5.111a.563.563 0 0 0 .475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a.563.563 0 0 0-.182.557l1.285 5.385a.562.562 0 0 1-.84.61l-4.725-2.885a.562.562 0 0 0-.586 0L6.982 20.54a.562.562 0 0 1-.84-.61l1.285-5.386a.562.562 0 0 0-.182-.557l-4.204-3.602a.562.562 0 0 1 .321-.988l5.518-.442a.563.563 0 0 0 .475-.345L11.48 3.5Z"/>{% endcapture %}
65
+ {% endif %}
66
+ {% when 'filter' %}
67
+ {% capture icon_content %}<path stroke-linecap="round" stroke-linejoin="round" d="M12 3c2.755 0 5.455.232 8.083.678.533.09.917.556.917 1.096v1.044a2.25 2.25 0 0 1-.659 1.591l-5.432 5.432a2.25 2.25 0 0 0-.659 1.591v2.927a2.25 2.25 0 0 1-1.244 2.013L9.75 21v-6.568a2.25 2.25 0 0 0-.659-1.591L3.659 7.409A2.25 2.25 0 0 1 3 5.818V4.774c0-.54.384-1.006.917-1.096A48.32 48.32 0 0 1 12 3Z"/>{% endcapture %}
68
+ {% when 'tag', 'price-tag' %}
69
+ {% capture icon_content %}<path stroke-linecap="round" stroke-linejoin="round" d="M9.568 3H5.25A2.25 2.25 0 0 0 3 5.25v4.318c0 .597.237 1.17.659 1.591l9.582 9.581c.699.699 1.78.872 2.607.33a18.095 18.095 0 0 0 5.223-5.223c.542-.827.369-1.908-.33-2.607L11.16 3.66A2.25 2.25 0 0 0 9.568 3Z"/>{% endcapture %}
70
+ {% when 'minus', 'remove' %}
71
+ {% capture icon_content %}<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 12h16.5"/>{% endcapture %}
72
+ {% when 'plus', 'add' %}
73
+ {% capture icon_content %}<path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15"/>{% endcapture %}
74
+ {% when 'trash', 'delete' %}
75
+ {% capture icon_content %}<path stroke-linecap="round" stroke-linejoin="round" d="m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0"/>{% endcapture %}
76
+ {% when 'home' %}
77
+ {% capture icon_content %}<path stroke-linecap="round" stroke-linejoin="round" d="m2.25 12 8.954-8.955c.44-.439 1.152-.439 1.591 0L21.75 12M4.5 9.75v10.125c0 .621.504 1.125 1.125 1.125H9.75v-4.875c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21h4.125c.621 0 1.125-.504 1.125-1.125V9.75M8.25 21h8.25"/>{% endcapture %}
78
+ {% when 'loading', 'spinner' %}
79
+ {% capture icon_content %}<path stroke-linecap="round" stroke-linejoin="round" d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0 3.181 3.183a8.25 8.25 0 0 0 13.803-3.7M4.031 9.865a8.25 8.25 0 0 1 13.803-3.7l3.181 3.182m0-4.991v4.99"/>{% endcapture %}
80
+ {% else %}
81
+ {% comment %} Default help/question mark icon {% endcomment %}
82
+ {% capture icon_content %}<path stroke-linecap="round" stroke-linejoin="round" d="M9.879 7.519c1.171-1.025 3.071-1.025 4.242 0 1.172 1.025 1.172 2.687 0 3.712-.203.179-.43.326-.67.442-.745.361-1.45.999-1.45 1.827v.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9 5.25h.008v.008H12v-.008Z"/>{% endcapture %}
83
+ {% endcase %}
84
+
85
+ <svg
86
+ xmlns="http://www.w3.org/2000/svg"
87
+ fill="{% if icon_style == 'solid' %}currentColor{% else %}none{% endif %}"
88
+ viewBox="0 0 24 24"
89
+ stroke-width="{{ icon_stroke_width }}"
90
+ stroke="{% if icon_style == 'solid' %}none{% else %}currentColor{% endif %}"
91
+ width="{{ icon_size }}{{ size_unit }}"
92
+ height="{{ icon_size }}{{ size_unit }}"
93
+ class="icon icon-{{ icon_name }} {{ icon_class }}"
94
+ {% if icon_aria_hidden %}
95
+ aria-hidden="true"
96
+ {% else %}
97
+ {% if icon_aria_label != blank %}
98
+ aria-label="{{ icon_aria_label }}"
99
+ role="img"
100
+ {% endif %}
101
+ {% endif %}>
102
+ {{ icon_content }}
103
+ </svg>
104
+
105
+