@o2vend/theme-cli 1.0.36 → 1.0.38

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 (90) hide show
  1. package/README.md +4 -0
  2. package/lib/lib/dev-server.js +344 -48
  3. package/lib/lib/liquid-engine.js +3 -1
  4. package/lib/lib/mock-data.js +473 -119
  5. package/lib/lib/widget-service.js +12 -4
  6. package/package.json +2 -2
  7. package/test-theme/assets/async-sections.js +32 -24
  8. package/test-theme/assets/cart-drawer.js +20 -22
  9. package/test-theme/assets/cart-manager.js +1 -15
  10. package/test-theme/assets/checkout-price-handler.js +12 -11
  11. package/test-theme/assets/checkout.css +1415 -0
  12. package/test-theme/assets/checkout.js +3174 -0
  13. package/test-theme/assets/components.css +178 -29
  14. package/test-theme/assets/delivery-zone.js +1 -1
  15. package/test-theme/assets/product-detail.css +1050 -0
  16. package/test-theme/assets/product-detail.js +2940 -0
  17. package/test-theme/assets/theme.css +95 -120
  18. package/test-theme/assets/theme.js +781 -186
  19. package/test-theme/layout/theme.liquid +91 -17
  20. package/test-theme/sections/content.liquid +64 -57
  21. package/test-theme/sections/footer-fallback.liquid +57 -7
  22. package/test-theme/sections/footer.liquid +63 -12
  23. package/test-theme/sections/header-fallback.liquid +41 -41
  24. package/test-theme/sections/header.liquid +41 -51
  25. package/test-theme/sections/hero-fallback.liquid +1 -1
  26. package/test-theme/sections/hero.liquid +159 -136
  27. package/test-theme/snippets/account-sidebar.liquid +121 -29
  28. package/test-theme/snippets/add-to-cart-modal.liquid +258 -206
  29. package/test-theme/snippets/breadcrumbs.liquid +98 -11
  30. package/test-theme/snippets/cart-drawer.liquid +93 -0
  31. package/test-theme/snippets/delivery-zone-city-selector.liquid +101 -15
  32. package/test-theme/snippets/delivery-zone-modal.liquid +529 -84
  33. package/test-theme/snippets/delivery-zone-search.liquid +104 -18
  34. package/test-theme/snippets/login-modal.liquid +269 -82
  35. package/test-theme/snippets/mega-menu.liquid +130 -43
  36. package/test-theme/snippets/news-thumbnail.liquid +120 -28
  37. package/test-theme/snippets/pagination.liquid +1 -1
  38. package/test-theme/snippets/price.liquid +100 -9
  39. package/test-theme/snippets/product-card-related.liquid +22 -4
  40. package/test-theme/snippets/product-card-simple.liquid +521 -25
  41. package/test-theme/snippets/product-card.liquid +145 -232
  42. package/test-theme/snippets/rating.liquid +100 -9
  43. package/test-theme/snippets/skeleton-collection-grid.liquid +94 -8
  44. package/test-theme/snippets/skeleton-product-card.liquid +102 -16
  45. package/test-theme/snippets/skeleton-product-grid.liquid +87 -1
  46. package/test-theme/snippets/social-sharing.liquid +133 -32
  47. package/test-theme/templates/account/dashboard.liquid +30 -0
  48. package/test-theme/templates/account/loyalty-redemption.liquid +29 -28
  49. package/test-theme/templates/account/loyalty.liquid +45 -43
  50. package/test-theme/templates/account/order-detail.liquid +15 -8
  51. package/test-theme/templates/account/orders.liquid +189 -35
  52. package/test-theme/templates/account/profile.liquid +509 -114
  53. package/test-theme/templates/account/register.liquid +18 -8
  54. package/test-theme/templates/account/return-orders.liquid +31 -30
  55. package/test-theme/templates/account/store-credit.liquid +27 -26
  56. package/test-theme/templates/account/subscriptions.liquid +22 -5
  57. package/test-theme/templates/account/wishlist.liquid +88 -19
  58. package/test-theme/templates/address-book.liquid +166 -69
  59. package/test-theme/templates/categories.liquid +90 -30
  60. package/test-theme/templates/checkout.liquid +137 -3834
  61. package/test-theme/templates/error.liquid +23 -21
  62. package/test-theme/templates/index.liquid +29 -0
  63. package/test-theme/templates/login.liquid +33 -6
  64. package/test-theme/templates/order-confirmation.liquid +67 -9
  65. package/test-theme/templates/page.liquid +418 -206
  66. package/test-theme/templates/product-detail.liquid +124 -3878
  67. package/test-theme/templates/products.liquid +155 -30
  68. package/test-theme/templates/search.liquid +739 -225
  69. package/test-theme/widgets/brand-carousel.liquid +102 -82
  70. package/test-theme/widgets/brand.liquid +78 -50
  71. package/test-theme/widgets/carousel.liquid +253 -121
  72. package/test-theme/widgets/category-list-carousel.liquid +32 -8
  73. package/test-theme/widgets/category-list.liquid +21 -6
  74. package/test-theme/widgets/category.liquid +104 -37
  75. package/test-theme/widgets/discount-time.liquid +326 -119
  76. package/test-theme/widgets/footer-menu.liquid +115 -23
  77. package/test-theme/widgets/footer.liquid +118 -5
  78. package/test-theme/widgets/gallery.liquid +29 -5
  79. package/test-theme/widgets/header-menu.liquid +25 -13
  80. package/test-theme/widgets/header.liquid +64 -26
  81. package/test-theme/widgets/html.liquid +29 -6
  82. package/test-theme/widgets/news.liquid +6 -0
  83. package/test-theme/widgets/product-canvas.liquid +20 -12
  84. package/test-theme/widgets/product-carousel.liquid +118 -56
  85. package/test-theme/widgets/shared/product-grid.liquid +12 -0
  86. package/test-theme/widgets/single-product.liquid +688 -250
  87. package/test-theme/widgets/spacebar-carousel.liquid +39 -10
  88. package/test-theme/widgets/spacebar.liquid +77 -6
  89. package/test-theme/widgets/splash.liquid +40 -30
  90. package/test-theme/widgets/testimonial-carousel.liquid +111 -67
@@ -8,11 +8,9 @@
8
8
  endcomment
9
9
 
10
10
  assign content_data = widget_data.content | default: widget.content
11
- assign testimonials = content_data | default: widget_data.testimonials
11
+ assign testimonials = content_data.items | default: content_data.Items | default: []
12
12
 
13
- if content_data.size > 0 and content_data.first.Title
14
- assign testimonials = content_data
15
- endif
13
+
16
14
 
17
15
  assign heading = widget_settings.title | default: 'What Our Customers Say'
18
16
  assign subtitle = widget_settings.subtitle
@@ -20,7 +18,15 @@
20
18
  assign text_color = widget_settings.textColor
21
19
  assign hide_dots = widget_settings.hideDot | default: false
22
20
  assign hide_arrows = widget_settings.hideArrow | default: false
23
- assign show_widget_title_raw = widget_settings.showWidgetTitle | default: 'Yes'
21
+ assign priority_count_raw = widget_settings.priorityCount | default: widget_settings.prioritizeCount | default: widget_settings.priority
22
+ assign priority_count = priority_count_raw | default: 1
23
+ if priority_count > 12
24
+ assign priority_count = 12
25
+ endif
26
+ if priority_count < 0
27
+ assign priority_count = 0
28
+ endif
29
+ assign show_widget_title_raw = widget_settings.showWidgetTitle | default: 'Yes'
24
30
  if show_widget_title_raw == null or show_widget_title_raw == blank or show_widget_title_raw == 'null'
25
31
  assign show_widget_title = true
26
32
  else
@@ -38,6 +44,10 @@
38
44
  assign widget_title_alignment = 'center'
39
45
  endif
40
46
  %}
47
+ {% assign is_hero_priority_widget = false %}
48
+ {% if is_hero_first == true or is_hero_first == 'true' or is_hero_first == 1 or is_hero_first == '1' %}
49
+ {% assign is_hero_priority_widget = true %}
50
+ {% endif %}
41
51
 
42
52
  <section class="widget widget-testimonial-carousel" data-widget-id="{{ widget.id }}" data-testimonial-carousel{% if background_color and background_color != blank and background_color != 'null' %} style="background-color: {{ background_color }};"{% endif %}>
43
53
  <div class="testimonial-carousel-container">
@@ -103,68 +113,61 @@
103
113
  {% elsif item.image and item.image != 'null' and item.image != blank %}
104
114
  {% assign item_image = item.image %}
105
115
  {% endif %}
116
+
117
+ {% comment %} Preload any slide image and background image for prioritized slides {% endcomment %}
118
+ {% if item_image and item_image != blank and forloop.index0 < priority_count and is_hero_priority_widget %}
119
+ {% if item_image contains 'http://' or item_image contains 'https://' %}
120
+ {% assign _preload_img = item_image %}
121
+ {% else %}
122
+ {% assign _preload_img = item_image | asset_url %}
123
+ {% endif %}
124
+ <link rel="preload" as="image" href="{{ _preload_img }}" fetchpriority="high">
125
+ {% endif %}
126
+
106
127
 
107
- <div class="testimonial-carousel-slide" data-slide-index="{{ forloop.index0 }}">
108
- <blockquote class="testimonial-card">
109
- <!-- Quote Icon -->
110
- <div class="testimonial-card__quote-icon">
111
- {% if item_icon_html and item_icon_html != 'null' and item_icon_html != blank %}
112
- {{ item_icon_html }}
113
- {% else %}
114
- <svg width="32" height="32" viewBox="0 0 24 24" fill="currentColor" opacity="0.15">
115
- <path d="M14.017 21v-7.391c0-5.704 3.731-9.57 8.983-10.609l.995 2.151c-2.432.917-3.995 3.638-3.995 5.849h4v10h-9.983zm-14.017 0v-7.391c0-5.704 3.748-9.57 9-10.609l.996 2.151c-2.433.917-3.996 3.638-3.996 5.849h3.983v10h-9.983z"/>
116
- </svg>
117
- {% endif %}
118
- </div>
119
-
120
- <!-- Rating Stars -->
121
- {% if item_rating and item_rating > 0 %}
122
- <div class="testimonial-card__rating">
123
- {% for i in (1..5) %}
124
- {% if i <= item_rating %}
125
- <svg class="star star--filled" width="18" height="18" viewBox="0 0 24 24" fill="currentColor">
126
- <path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/>
127
- </svg>
128
+
129
+ <div class="testimonial-carousel-slide{% if forloop.index0 < priority_count %} testimonial-carousel-slide--priority{% endif %}" data-slide-index="{{ forloop.index0 }}" {% if forloop.index0 < priority_count %}data-priority="high"{% endif %}>
130
+ <blockquote class="testimonial-card testimonial-card--revamped">
131
+ <div class="testimonial-card__body">
132
+ <div class="testimonial-card__meta">
133
+ <div class="testimonial-card__quote-icon">
134
+ {% if item_icon_html and item_icon_html != 'null' and item_icon_html != blank %}
135
+ {{ item_icon_html }}
128
136
  {% else %}
129
- <svg class="star star--empty" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
130
- <path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/>
137
+ <svg width="40" height="40" viewBox="0 0 24 24" fill="currentColor" opacity="0.06">
138
+ <path d="M14.017 21v-7.391c0-5.704 3.731-9.57 8.983-10.609l.995 2.151c-2.432.917-3.995 3.638-3.995 5.849h4v10h-9.983zm-14.017 0v-7.391c0-5.704 3.748-9.57 9-10.609l.996 2.151c-2.433.917-3.996 3.638-3.996 5.849h3.983v10h-9.983z"/>
131
139
  </svg>
132
140
  {% endif %}
133
- {% endfor %}
141
+ </div>
142
+
143
+ <h3 class="testimonial-card__title">{{ item_title }}</h3>
144
+
134
145
  </div>
135
- {% endif %}
136
-
137
- <!-- Title -->
138
- {% if item_title and item_title != blank %}
139
- <h3 class="testimonial-card__title">{{ item_title }}</h3>
140
- {% endif %}
146
+
141
147
 
142
- <!-- Quote/Description -->
143
- {% if item_description and item_description != blank %}
144
- <p class="testimonial-card__text">"{{ item_description }}"</p>
145
- {% endif %}
148
+ <p class="testimonial-card__text">{{ item_description }}</p>
146
149
 
147
- <!-- Author Info -->
150
+ </div>
151
+
148
152
  <footer class="testimonial-card__footer">
149
- {% if item_image and item_image != blank %}
150
- <div class="testimonial-card__avatar">
151
- <img src="{{ item_image }}" alt="{{ person_name }}" width="48" height="48" loading="lazy" onerror="this.style.display='none'; this.nextElementSibling.style.display='flex';">
152
- <span class="testimonial-card__avatar-fallback" style="display: none;">
153
- {{ person_name | slice: 0 | upcase }}
154
- </span>
155
- </div>
156
- {% elsif person_name and person_name != blank %}
157
- <div class="testimonial-card__avatar testimonial-card__avatar--initials">
158
- <span>{{ person_name | slice: 0 | upcase }}</span>
159
- </div>
160
- {% endif %}
161
-
162
- <div class="testimonial-card__author">
153
+ <div class="testimonial-card__author-avatar">
154
+ {% assign _initial_source = person_name | default: company_name %}
155
+ {% assign _initial = _initial_source | default: '' %}
156
+ {% assign _initial = _initial | slice: 0,1 | upcase %}
157
+ {% if item_image and item_image != blank %}
158
+ <img class="testimonial-card__avatar-img" src="{{ item_image }}" alt="{{ person_name }}" loading="{% if forloop.index0 < priority_count %}eager{% else %}lazy{% endif %}" {% if forloop.index0 < priority_count and is_hero_priority_widget %}fetchpriority="high"{% endif %} data-img-fallback="query:.testimonial-card__avatar-fallback--large">
159
+ <div class="testimonial-card__avatar-fallback--large" style="display:none;">{{ _initial }}</div>
160
+ {% else %}
161
+ <div class="testimonial-card__avatar-fallback--large" style="display:flex;">{{ _initial }}</div>
162
+ {% endif %}
163
+ </div>
164
+
165
+ <div class="testimonial-card__author-info">
163
166
  {% if person_name and person_name != blank %}
164
- <span class="testimonial-card__name">{{ person_name }}</span>
167
+ <div class="testimonial-card__name">{{ person_name }}</div>
165
168
  {% endif %}
166
169
  {% if company_name and company_name != blank %}
167
- <span class="testimonial-card__company">{{ company_name }}</span>
170
+ <div class="testimonial-card__company">{{ company_name }}</div>
168
171
  {% endif %}
169
172
  </div>
170
173
  </footer>
@@ -194,6 +197,24 @@
194
197
  </div>
195
198
 
196
199
  <style>
200
+ :root {
201
+ --testimonial-carousel-white: var(--color-white);
202
+ --testimonial-carousel-text: var(--color-text);
203
+ --testimonial-carousel-text-muted: var(--color-text-muted);
204
+ --testimonial-carousel-border: var(--color-border);
205
+ --testimonial-carousel-spacing-section: var(--spacing-section);
206
+ --testimonial-carousel-spacing-component: var(--spacing-component);
207
+ --testimonial-carousel-spacing-element: var(--spacing-element);
208
+ --testimonial-carousel-spacing-small: var(--spacing-small);
209
+ --testimonial-carousel-spacing-xsmall: var(--spacing-xsmall);
210
+ --testimonial-carousel-container-padding: var(--container-padding);
211
+ --testimonial-carousel-radius-full: var(--radius-full);
212
+ --testimonial-carousel-radius: var(--radius);
213
+ --testimonial-carousel-transition-fast: var(--transition-fast);
214
+ --testimonial-carousel-transition: var(--transition);
215
+ --testimonial-carousel-text-sm: var(--text-sm);
216
+ }
217
+
197
218
  /* Testimonial Carousel - Modern Design */
198
219
  .widget-testimonial-carousel {
199
220
  padding: 60px 0;
@@ -289,7 +310,6 @@
289
310
  border-radius: 50%;
290
311
  border: none;
291
312
  background: #fff;
292
- box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
293
313
  align-items: center;
294
314
  justify-content: center;
295
315
  cursor: pointer;
@@ -348,7 +368,6 @@
348
368
  background: #fff;
349
369
  border-radius: var(--border-radius-medium);
350
370
  padding: 28px;
351
- box-shadow: 0 4px 20px rgba(0, 0, 0, 0.06);
352
371
  margin: 0;
353
372
  height: 100%;
354
373
  display: flex;
@@ -358,7 +377,32 @@
358
377
 
359
378
  .widget-testimonial-carousel .testimonial-card:hover {
360
379
  transform: translateY(-4px);
361
- box-shadow: 0 12px 32px rgba(0, 0, 0, 0.1);
380
+ }
381
+
382
+ /* Revamped card styles */
383
+ .widget-testimonial-carousel .testimonial-card--revamped {
384
+ padding: 22px;
385
+ display: flex;
386
+ flex-direction: column;
387
+ gap: 12px;
388
+ border-left: 4px solid rgba(0,0,0,0.06);
389
+ box-shadow: 0 8px 24px rgba(0,0,0,0.04);
390
+ background: #fff;
391
+ }
392
+ .widget-testimonial-carousel .testimonial-card__body { padding-right: 8px; }
393
+ .widget-testimonial-carousel .testimonial-card__quote-icon { font-size: 36px; color: rgba(0,0,0,0.06); margin-bottom: 6px; }
394
+ .widget-testimonial-carousel .testimonial-card__rating--small { color: #fbbf24; font-size: 14px; margin-bottom: 6px; }
395
+ .widget-testimonial-carousel .testimonial-card__title { font-size: 18px; margin: 0 0 8px; }
396
+ .widget-testimonial-carousel .testimonial-card__text { font-size: 16px; color: #111; font-style: italic; margin: 0; }
397
+ .widget-testimonial-carousel .testimonial-card__footer { display: flex; align-items: center; gap: 12px; margin-top: 12px; }
398
+ .widget-testimonial-carousel .testimonial-card__author-avatar img { width: 64px; height: 64px; border-radius: 50%; object-fit: cover; box-shadow: 0 4px 12px rgba(0,0,0,0.06); }
399
+ .widget-testimonial-carousel .testimonial-card__avatar-fallback--large { width:64px; height:64px; border-radius:50%; display:flex; align-items:center; justify-content:center; background:linear-gradient(135deg,#667eea 0%,#764ba2 100%); color:#fff; font-weight:700; }
400
+ .widget-testimonial-carousel .testimonial-card__author-info .testimonial-card__name { font-weight: 700; }
401
+ .widget-testimonial-carousel .testimonial-card__author-info .testimonial-card__company { color: #6b7280; font-size: 13px; }
402
+ @media (max-width: 768px) {
403
+ .widget-testimonial-carousel .testimonial-card--revamped { padding: 18px }
404
+ .widget-testimonial-carousel .testimonial-card__author-avatar img { width:48px; height:48px }
405
+ .widget-testimonial-carousel .testimonial-card__avatar-fallback--large { width:48px; height:48px }
362
406
  }
363
407
 
364
408
  .widget-testimonial-carousel .testimonial-card__quote-icon {
@@ -575,7 +619,7 @@
575
619
  </style>
576
620
 
577
621
  <script>
578
- (function() {
622
+ (() => {
579
623
  if (document.readyState === 'loading') {
580
624
  document.addEventListener('DOMContentLoaded', initTestimonialCarousel);
581
625
  } else {
@@ -585,13 +629,13 @@
585
629
  function initTestimonialCarousel() {
586
630
  const widget = document.querySelector('[data-widget-id="{{ widget.id }}"][data-testimonial-carousel]');
587
631
  if (!widget) return;
588
-
589
- const track = widget.querySelector('[data-carousel-track]');
590
632
  const viewport = widget.querySelector('[data-carousel-viewport]');
591
- const prevBtns = widget.querySelectorAll('[data-carousel-prev]');
592
- const nextBtns = widget.querySelectorAll('[data-carousel-next]');
633
+ const track = widget.querySelector('[data-carousel-track]');
634
+ const slides = Array.from(widget.querySelectorAll('.testimonial-carousel-slide'));
635
+ const prevBtns = Array.from(widget.querySelectorAll('[data-carousel-prev]'));
636
+ const nextBtns = Array.from(widget.querySelectorAll('[data-carousel-next]'));
593
637
  const dotsContainer = widget.querySelector('[data-carousel-dots]');
594
- const slides = widget.querySelectorAll('.testimonial-carousel-slide');
638
+
595
639
 
596
640
  if (!track || slides.length === 0) return;
597
641
 
@@ -609,7 +653,7 @@
609
653
  }
610
654
 
611
655
  function getCurrentPage() {
612
- if (!track.scrollWidth || track.scrollWidth <= viewport.clientWidth) return 0;
656
+ if (!track.scrollWidth || !viewport || track.scrollWidth <= viewport.clientWidth) return 0;
613
657
  const scrollRatio = track.scrollLeft / (track.scrollWidth - viewport.clientWidth);
614
658
  return Math.round(scrollRatio * (getPageCount() - 1));
615
659
  }
@@ -640,7 +684,7 @@
640
684
 
641
685
  function updateArrows() {
642
686
  const atStart = track.scrollLeft <= 5;
643
- const atEnd = track.scrollLeft >= track.scrollWidth - viewport.clientWidth - 5;
687
+ const atEnd = !viewport ? true : (track.scrollLeft >= track.scrollWidth - viewport.clientWidth - 5);
644
688
 
645
689
  prevBtns.forEach(btn => btn.disabled = atStart);
646
690
  nextBtns.forEach(btn => btn.disabled = atEnd);