zz-shopify-components 0.34.1-beta.21 → 0.34.1-beta.22

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.
@@ -173,7 +173,6 @@ if (!customElements.get('zz-video-popup')) {
173
173
  this.popup = null;
174
174
  }
175
175
 
176
-
177
176
  connectedCallback() {
178
177
  this.querySelectorAll('.togglePopup').forEach((el) => {
179
178
  el.addEventListener('click', (event) => {
@@ -184,8 +183,6 @@ if (!customElements.get('zz-video-popup')) {
184
183
  });
185
184
  });
186
185
  this.popup = this.querySelector('.popup');
187
-
188
-
189
186
  }
190
187
 
191
188
  disconnectedCallback() {
@@ -226,7 +223,7 @@ if (!customElements.get('zz-video-popup')) {
226
223
  backdropFilter: 'blur(30px)',
227
224
  onComplete: () => {
228
225
  const videos = this.popup.querySelectorAll('video');
229
- videos.forEach(video => {
226
+ videos.forEach((video) => {
230
227
  if (window.getComputedStyle(video).display !== 'none') {
231
228
  video.play();
232
229
  }
@@ -246,7 +243,7 @@ if (!customElements.get('zz-video-popup')) {
246
243
  onComplete: () => {
247
244
  this.popup.classList.add('!tw-hidden');
248
245
  const videos = this.popup.querySelectorAll('video');
249
- videos.forEach(video => {
246
+ videos.forEach((video) => {
250
247
  if (video) {
251
248
  video.pause();
252
249
  }
@@ -261,7 +258,6 @@ if (!customElements.get('zz-video-popup')) {
261
258
  customElements.define('zz-video-popup', ZZVideoPopup);
262
259
  }
263
260
 
264
-
265
261
  if (!customElements.get('zz-video-handler')) {
266
262
  class ZZVideoHandler extends HTMLElement {
267
263
  constructor() {
@@ -310,7 +306,6 @@ if (!customElements.get('zz-video-handler')) {
310
306
  customElements.define('zz-video-handler', ZZVideoHandler);
311
307
  }
312
308
 
313
-
314
309
  /**
315
310
  * Toast 组件
316
311
  */
@@ -430,9 +425,11 @@ if (!customElements.get('zz-video-handler')) {
430
425
  function isSafari() {
431
426
  const ua = navigator.userAgent;
432
427
  // 包含 Safari / WebKit,且不包含 Chrome / CriOS / FxiOS / Android
433
- return /Safari/.test(ua)
434
- && /AppleWebKit/.test(ua)
435
- && !/CriOS|FxiOS|Chrome|Edg|OPR/.test(ua);
428
+ return (
429
+ /Safari/.test(ua) &&
430
+ /AppleWebKit/.test(ua) &&
431
+ !/CriOS|FxiOS|Chrome|Edg|OPR/.test(ua)
432
+ );
436
433
  }
437
434
 
438
435
  function isSafari26() {
@@ -442,8 +439,6 @@ if (!customElements.get('zz-video-handler')) {
442
439
  return /Version\/26\./.test(ua);
443
440
  }
444
441
 
445
-
446
-
447
442
  function lockBodyScroll() {
448
443
  if (isSafari26()) {
449
444
  scrollTop = window.scrollY;
@@ -506,11 +501,10 @@ document.addEventListener('DOMContentLoaded', (event) => {
506
501
  entries.forEach((entry) => {
507
502
  const el = entry.target;
508
503
  if (entry.isIntersecting) {
509
-
510
504
  } else {
511
505
  if (el.classList.contains('zz-card-animate-list')) {
512
506
  // 重置所有
513
- el.querySelectorAll('.zz-card-inner').forEach(card => {
507
+ el.querySelectorAll('.zz-card-inner').forEach((card) => {
514
508
  card.classList.remove('is-active');
515
509
  });
516
510
  }
@@ -518,47 +512,48 @@ document.addEventListener('DOMContentLoaded', (event) => {
518
512
  });
519
513
  });
520
514
 
521
-
522
515
  if (!isDesktop) {
523
516
  const switchCard = document.querySelectorAll('.product-switch-card');
524
517
  // 监听所有的switchCard 当它完全出现屏幕中时候,定时2秒切换成背景图。移出屏幕时候恢复
525
518
 
526
519
  if (switchCard.length > 0) {
527
520
  const switchTimers = new Map(); // 存储每个卡片的定时器
528
-
529
- const switchCardObserver = new IntersectionObserver((entries) => {
530
- entries.forEach((entry) => {
531
- const card = entry.target;
532
- console.log('switchCardObserver')
533
- if (entry.isIntersecting && entry.intersectionRatio >= 0.8) {
534
- // 完全出现在屏幕中,2秒后切换成背景图
535
- const timer = setInterval(() => {
536
- if (card.classList.contains('switchCard')) {
537
- card.classList.remove('switchCard');
538
- } else {
539
- card.classList.add('switchCard');
521
+
522
+ const switchCardObserver = new IntersectionObserver(
523
+ (entries) => {
524
+ entries.forEach((entry) => {
525
+ const card = entry.target;
526
+ console.log('switchCardObserver');
527
+ if (entry.isIntersecting && entry.intersectionRatio >= 0.8) {
528
+ // 完全出现在屏幕中,2秒后切换成背景图
529
+ const timer = setInterval(() => {
530
+ if (card.classList.contains('switchCard')) {
531
+ card.classList.remove('switchCard');
532
+ } else {
533
+ card.classList.add('switchCard');
534
+ }
535
+ }, 2000);
536
+ switchTimers.set(card, timer);
537
+ } else {
538
+ // 移出屏幕,恢复原状
539
+ const timer = switchTimers.get(card);
540
+ if (timer) {
541
+ clearInterval(timer);
542
+ switchTimers.delete(card);
540
543
  }
541
- }, 2000);
542
- switchTimers.set(card, timer);
543
- } else {
544
- // 移出屏幕,恢复原状
545
- const timer = switchTimers.get(card);
546
- if (timer) {
547
- clearInterval(timer);
548
- switchTimers.delete(card);
544
+ card.classList.remove('switchCard');
549
545
  }
550
- card.classList.remove('switchCard');
551
- }
552
- });
553
- }, {
554
- threshold: [0.2, 0.8] // 监听0%、99%和100%的可见度
555
- });
556
-
557
- switchCard.forEach(card => {
546
+ });
547
+ },
548
+ {
549
+ threshold: [0.2, 0.8], // 监听0%、99%和100%的可见度
550
+ }
551
+ );
552
+
553
+ switchCard.forEach((card) => {
558
554
  switchCardObserver.observe(card);
559
555
  });
560
556
  }
561
-
562
557
  }
563
558
 
564
559
  // 处理统一的定位脚本
@@ -568,17 +563,17 @@ document.addEventListener('DOMContentLoaded', (event) => {
568
563
  if (positionTrigger) {
569
564
  const selector = positionTrigger.getAttribute('data-zz-module-target');
570
565
  if (selector) {
571
- const target = document.querySelector(`[data-zz-module-name="${selector}"]`);
572
- const headerHeight = 50;
573
- const offsetTop = target.offsetTop - headerHeight;
574
- window.scrollTo(0, offsetTop);
575
-
566
+ const target = document.querySelector(
567
+ `[data-zz-module-name="${selector}"]`
568
+ );
569
+ const headerHeight = 50;
570
+ const offsetTop = target.offsetTop - headerHeight;
571
+ window.scrollTo(0, offsetTop);
576
572
  }
577
573
  return;
578
574
  }
579
575
  });
580
576
 
581
-
582
577
  // zz-card-animate-text.liquid
583
578
  const cardListGroup = document.querySelectorAll('.zz-card-animate-list');
584
579
  cardListGroup.forEach((list) => {
@@ -591,7 +586,7 @@ document.addEventListener('DOMContentLoaded', (event) => {
591
586
  console.log('click card item');
592
587
 
593
588
  // 重置所有
594
- list.querySelectorAll('.zz-card-inner').forEach(el => {
589
+ list.querySelectorAll('.zz-card-inner').forEach((el) => {
595
590
  el.classList.remove('is-active');
596
591
  });
597
592
 
@@ -599,8 +594,89 @@ document.addEventListener('DOMContentLoaded', (event) => {
599
594
  item.classList.add('is-active');
600
595
  });
601
596
  compIntersectionObserver.observe(list);
602
-
603
597
  });
598
+ });
599
+
600
+ if (!customElements.get('zz-normal-modal')) {
601
+ class ZZNormalModal extends HTMLElement {
602
+ constructor() {
603
+ super();
604
+ this.handleOverlayClick = this.handleOverlayClick.bind(this);
605
+ this.handleDocumentKeydown = this.handleDocumentKeydown.bind(this);
606
+ this.handleCloseClick = this.handleCloseClick.bind(this);
607
+ }
608
+
609
+ connectedCallback() {
610
+ this.dialogContent = this.querySelector('[data-modal-content]');
611
+ this.overlay = this.querySelector('[data-modal-overlay]');
612
+ this.closeButton = this.querySelector('[data-modal-close]');
604
613
 
614
+ if (this.overlay) {
615
+ this.overlay.addEventListener('click', this.handleOverlayClick);
616
+ }
617
+
618
+ if (this.closeButton) {
619
+ this.closeButton.addEventListener('click', this.handleCloseClick);
620
+ }
621
+ }
605
622
 
606
- });
623
+ disconnectedCallback() {
624
+ if (this.overlay) {
625
+ this.overlay.removeEventListener('click', this.handleOverlayClick);
626
+ }
627
+
628
+ if (this.closeButton) {
629
+ this.closeButton.removeEventListener('click', this.handleCloseClick);
630
+ }
631
+
632
+ document.removeEventListener('keydown', this.handleDocumentKeydown);
633
+ }
634
+
635
+ show() {
636
+ this.previousActiveElement = document.activeElement;
637
+ this.dialogContent.classList.add('is-open');
638
+ this.overlay.classList.add('is-open');
639
+ this.setAttribute('aria-hidden', 'false');
640
+ window.zzLockBodyScroll && window.zzLockBodyScroll();
641
+ document.addEventListener('keydown', this.handleDocumentKeydown);
642
+
643
+ requestAnimationFrame(() => {
644
+ if (this.dialogContent) {
645
+ this.dialogContent.focus();
646
+ }
647
+ });
648
+ }
649
+
650
+ hide() {
651
+ this.dialogContent.classList.remove('is-open');
652
+ this.overlay.classList.remove('is-open');
653
+ this.setAttribute('aria-hidden', 'true');
654
+ window.zzUnlockBodyScroll && window.zzUnlockBodyScroll();
655
+ document.removeEventListener('keydown', this.handleDocumentKeydown);
656
+
657
+ if (
658
+ this.previousActiveElement &&
659
+ typeof this.previousActiveElement.focus === 'function'
660
+ ) {
661
+ this.previousActiveElement.focus();
662
+ }
663
+ }
664
+
665
+ handleOverlayClick() {
666
+ this.hide();
667
+ }
668
+
669
+ handleCloseClick() {
670
+ console.log('click-close');
671
+ this.hide();
672
+ }
673
+
674
+ handleDocumentKeydown(event) {
675
+ if (event.key === 'Escape') {
676
+ this.hide();
677
+ }
678
+ }
679
+ }
680
+
681
+ customElements.define('zz-normal-modal', ZZNormalModal);
682
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zz-shopify-components",
3
- "version": "0.34.1-beta.21",
3
+ "version": "0.34.1-beta.22",
4
4
  "description": "Reusable Shopify components for theme projects",
5
5
  "keywords": [
6
6
  "shopify",
@@ -41,12 +41,23 @@
41
41
  "default": 24,
42
42
  "info": "单位:px"
43
43
  },
44
+ {
45
+ "type": "richtext",
46
+ "id": "title",
47
+ "label": "标题",
48
+ "info": "没有就不填写"
49
+ },
50
+ {
51
+ "type": "richtext",
52
+ "id": "title_mb",
53
+ "label": "标题移动端",
54
+ "info": "没有就不填写"
55
+ },
44
56
  ],
45
57
  "blocks": [
46
58
  {
47
59
  "type": "comment",
48
60
  "name": "comment",
49
- "limit": 3,
50
61
  "settings": [
51
62
  {
52
63
  "type": "select",
@@ -131,30 +142,54 @@
131
142
  }
132
143
  {% endschema %}
133
144
 
134
- <div class='user-spokes-section lg:tw-w-[85.3906vw] xl:tw-w-[1093px] lg:tw-mx-auto'>
135
- <div class='voc-item-list max-lg:tw-px-[20px] tw-flex lg:tw-justify-between max-lg:tw-overflow-x-auto tw-gap-[8px] lg:tw-gap-[20px] slow-reveal'>
136
- {% for block in section.blocks %}
137
- <div class='comment-box lg:tw-w-[351px] tw-flex tw-flex-col'>
138
- <div class='comment-item lg:tw-w-[351px] lg:tw-h-[468px]'>
139
- {% render 'zz-spoke',
140
- bg_color: 'rgba(0,0,0,0.04)',
141
- class_name: 'max-lg:tw-bg-[#F5F5F6]',
142
- pc_image: block.settings.pc_image,
143
- pc_video: block.settings.pc_video,
144
- mb_image: block.settings.mb_image,
145
- mb_video: block.settings.mb_video,
146
- pc_media_pos: block.settings.pc_media_pos,
147
- mb_media_pos: block.settings.mb_media_pos,
148
- user_name: block.settings.username,
149
- user_avatar: block.settings.avatar,
150
- user_account: block.settings.account,
151
- content: block.settings.content,
152
- name_class: 'tw-text-black max-lg:tw-text-[10px] lg:tw-text-[14px]',
153
- content_class: 'voc-text-content max-lg:tw-text-[10px] lg:tw-text-[14px] tw-text-black/70 lg:tw-text-black/60 max-lg:tw-leading-[1.2] tw-line-clamp-8 lg:tw-line-clamp-6'
154
- %}
145
+ {%- assign desktop_slider_enabled = false -%}
146
+ {%- if section.blocks.size > 3 -%}
147
+ {%- assign desktop_slider_enabled = true -%}
148
+ {%- endif -%}
149
+ <div class='user-spokes-section{% if desktop_slider_enabled %} voc-slider-active{% else %} lg:tw-w-[90vw] xl:tw-w-[1220px] lg:tw-mx-auto{% endif %}'>
150
+ {% if section.settings.title != blank %}
151
+ <div class='tw-flex tw-justify-center tw-mb-[30px] lg:tw-mb-[72px]'>
152
+ {% render 'zz-h3',
153
+ title: section.settings.title,
154
+ title_mb: section.settings.mb_title | default: section.settings.title,
155
+ class_name: 'tw-text-center'
156
+
157
+ %}
158
+ </div>
159
+ {% endif %}
160
+ <div class='tw-relative'>
161
+ <div class='voc-item-list max-lg:tw-px-[20px] tw-flex tw-gap-[8px] lg:tw-gap-[20px] slow-reveal{% if desktop_slider_enabled %} voc-item-list--desktop-slider{% else %} lg:tw-justify-center{% endif %}' data-voc-list>
162
+ {% for block in section.blocks %}
163
+ <div class='comment-box lg:tw-w-[351px] tw-flex tw-flex-col'>
164
+ <div class='comment-item lg:tw-w-[351px] lg:tw-h-[468px]'>
165
+ {% render 'zz-spoke',
166
+ bg_color: 'rgba(0,0,0,0.04)',
167
+ class_name: 'max-lg:tw-bg-[#F5F5F6]',
168
+ pc_image: block.settings.pc_image,
169
+ pc_video: block.settings.pc_video,
170
+ mb_image: block.settings.mb_image,
171
+ mb_video: block.settings.mb_video,
172
+ pc_media_pos: block.settings.pc_media_pos,
173
+ mb_media_pos: block.settings.mb_media_pos,
174
+ user_name: block.settings.username,
175
+ user_avatar: block.settings.avatar,
176
+ user_account: block.settings.account,
177
+ content: block.settings.content,
178
+ name_class: 'tw-text-black max-lg:tw-text-[10px] lg:tw-text-[14px]',
179
+ content_class: 'voc-text-content max-lg:tw-text-[10px] lg:tw-text-[14px] tw-text-black/70 lg:tw-text-black/60 max-lg:tw-leading-[1.2] tw-line-clamp-8 lg:tw-line-clamp-6'
180
+ %}
181
+ </div>
155
182
  </div>
156
- </div>
157
- {% endfor %}
183
+ {% endfor %}
184
+ </div>
185
+ {% if desktop_slider_enabled %}
186
+ <button type='button' class='voc-slider-button voc-slider-button--prev' data-voc-prev aria-label='Previous comments'>
187
+ {% render 'zz-prev-next-blur-icon', type: 'prev', color_type: 'light' %}
188
+ </button>
189
+ <button type='button' class='voc-slider-button voc-slider-button--next' data-voc-next aria-label='Next comments'>
190
+ {% render 'zz-prev-next-blur-icon', type: 'next', color_type: 'light' %}
191
+ </button>
192
+ {% endif %}
158
193
  </div>
159
194
  </div>
160
195
 
@@ -171,46 +206,48 @@
171
206
  #shopify-section-{{section.id}} .zz-spoke-block-media img{
172
207
  height: 100%;
173
208
  }
174
-
175
- .voc-item-list {
176
- -webkit-overflow-scrolling: touch; /* 移动端流畅滚动(可选) */
177
- scrollbar-width: none; /* Firefox */
178
- -ms-overflow-style: none; /* IE 和 Edge */
209
+ #shopify-section-{{section.id}} .voc-item-list {
210
+ -webkit-overflow-scrolling: touch;
211
+ scrollbar-width: none;
212
+ -ms-overflow-style: none;
179
213
  }
180
- .voc-item-list::-webkit-scrollbar {
181
- width: 0px; /* 隐藏滚动条 */
214
+ #shopify-section-{{section.id}} .voc-item-list::-webkit-scrollbar {
215
+ width: 0px;
216
+ display: none;
182
217
  }
183
- .voc-item-list::-webkit-scrollbar {
218
+ #shopify-section-{{section.id}} .voc-slider-button {
184
219
  display: none;
185
220
  }
186
221
  @media screen and (max-width: 1023px) {
222
+ #shopify-section-{{section.id}} .voc-item-list {
223
+ overflow-x: auto;
224
+ }
187
225
  #shopify-section-{{section.id}} .comment-box .comment-item {
188
226
  width: 168px;
189
-
190
227
  }
191
-
192
- #shopify-section-{{section.id}} .comment-box {
193
- width: 168px;
194
- height: 380px;
195
- }
196
- #shopify-section-{{section.id}} .comment-box .zz-spoke-block-media {
197
- height: 221px;
198
- }
199
- #shopify-section-{{section.id}} .comment-box .zz-spoke-block-content {
200
- box-sizing: border-box;
201
- height: 160px;
202
- }
203
-
204
-
205
-
228
+ #shopify-section-{{section.id}} .comment-box {
229
+ width: 168px;
230
+ height: 380px;
231
+ }
232
+ #shopify-section-{{section.id}} .comment-box .zz-spoke-block-media {
233
+ height: 221px;
234
+ }
235
+ #shopify-section-{{section.id}} .comment-box .zz-spoke-block-content {
236
+ box-sizing: border-box;
237
+ height: 160px;
238
+ }
206
239
  }
207
240
  @media (min-width: 1024px) {
208
241
  #shopify-section-{{section.id}} {
209
242
  padding-top: {{ section.settings.padding_top }}px;
210
243
  padding-bottom: {{ section.settings.padding_bottom }}px;
211
244
  }
245
+ #shopify-section-{{section.id}} .user-spokes-section {
246
+ width: 100%;
247
+ }
212
248
  #shopify-section-{{section.id}} .comment-box {
213
249
  height: 688px;
250
+ flex: 0 0 auto;
214
251
  }
215
252
  #shopify-section-{{section.id}} .comment-box .zz-spoke-block-media {
216
253
  height: 468px;
@@ -218,9 +255,53 @@
218
255
  #shopify-section-{{section.id}} .comment-box .zz-spoke-block-content {
219
256
  height: 210px;
220
257
  }
258
+ #shopify-section-{{section.id}} .voc-item-list--desktop-slider {
259
+ overflow-x: auto;
260
+ justify-content: flex-start;
261
+ scroll-behavior: smooth;
262
+ {% comment %} scroll-snap-type: x proximity; {% endcomment %}
263
+ width: 100vw;
264
+ max-width: 100vw;
265
+ {% comment %} padding-right: 5vw; {% endcomment %}
266
+ {% comment %} padding-left: 5vw; {% endcomment %}
267
+ box-sizing: border-box;
268
+ }
269
+ #shopify-section-{{section.id}} .voc-item-list--desktop-slider::before, #shopify-section-{{section.id}} .voc-item-list--desktop-slider::after {
270
+ content: '';
271
+ flex-shrink: 0;
272
+ width: 5vw;
273
+ }
274
+ #shopify-section-{{section.id}} .voc-item-list--desktop-slider .comment-box {
275
+ scroll-snap-align: start;
276
+ }
277
+ #shopify-section-{{section.id}} .voc-slider-button {
278
+ position: absolute;
279
+ top: 50%;
280
+ z-index: 2;
281
+ display: inline-flex;
282
+ align-items: center;
283
+ justify-content: center;
284
+ transform: translateY(-50%);
285
+ border: 0;
286
+ background: transparent;
287
+ padding: 0;
288
+ cursor: pointer;
289
+ }
290
+ #shopify-section-{{section.id}} .voc-slider-button[disabled] {
291
+ opacity: 0;
292
+ visibility: hidden;
293
+ pointer-events: none;
294
+ cursor: default;
295
+ }
296
+ #shopify-section-{{section.id}} .voc-slider-button--prev {
297
+ left: 16px;
298
+ }
299
+ #shopify-section-{{section.id}} .voc-slider-button--next {
300
+ right: 16px;
301
+ }
221
302
  }
222
- @media (min-width: 1024px) and (max-width: 1280px) {
223
- #shopify-section-{{section.id}} .user-spokes-section {
303
+ @media (min-width: 1024px) and (max-width: 1279px) {
304
+ #shopify-section-{{section.id}} .user-spokes-section:not(.voc-slider-active) {
224
305
  width: 85.3906vw;
225
306
  }
226
307
  #shopify-section-{{section.id}} .comment-box {
@@ -236,4 +317,63 @@
236
317
  height: 36.5625vw;
237
318
  }
238
319
  }
320
+ @media (min-width: 1280px) {
321
+ #shopify-section-{{section.id}} .voc-item-list--desktop-slider {
322
+ {% comment %} padding-left: calc((100vw - 1220px) / 2); {% endcomment %}
323
+ {% comment %} padding-right: calc((100vw - 1220px) / 2); {% endcomment %}
324
+ }
325
+ #shopify-section-{{section.id}} .voc-item-list--desktop-slider::after, #shopify-section-{{section.id}} .voc-item-list--desktop-slider::before {
326
+ content: '';
327
+ flex-shrink: 0;
328
+ width: calc((100vw - 1220px) / 2);
329
+ }
330
+ }
239
331
  </style>
332
+
333
+ <script>
334
+ document.addEventListener('DOMContentLoaded', () => {
335
+ const sectionRoot = document.getElementById('shopify-section-{{section.id}}');
336
+ if (!sectionRoot || window.innerWidth < 1024) return;
337
+
338
+ const list = sectionRoot.querySelector('[data-voc-list]');
339
+ const prevButton = sectionRoot.querySelector('[data-voc-prev]');
340
+ const nextButton = sectionRoot.querySelector('[data-voc-next]');
341
+ if (!list || !prevButton || !nextButton) return;
342
+
343
+ const getScrollAmount = () => {
344
+ const firstCard = list.querySelector('.comment-box');
345
+ if (!firstCard) return list.clientWidth;
346
+ const styles = window.getComputedStyle(list);
347
+ const gap = Number.parseFloat(styles.columnGap || styles.gap || '0') || 0;
348
+ return firstCard.getBoundingClientRect().width + gap;
349
+ };
350
+
351
+ const updateButtonState = () => {
352
+ const maxScrollLeft = Math.max(list.scrollWidth - list.clientWidth, 0);
353
+ const currentScrollLeft = Math.max(list.scrollLeft, 0);
354
+ prevButton.disabled = currentScrollLeft <= 2;
355
+ nextButton.disabled = currentScrollLeft >= maxScrollLeft - 2;
356
+ };
357
+
358
+ const scrollList = (direction) => {
359
+ list.scrollBy({
360
+ left: getScrollAmount() * direction,
361
+ behavior: 'smooth',
362
+ });
363
+ };
364
+
365
+ prevButton.addEventListener('click', () => {
366
+ if (prevButton.disabled) return;
367
+ scrollList(-1);
368
+ });
369
+
370
+ nextButton.addEventListener('click', () => {
371
+ if (nextButton.disabled) return;
372
+ scrollList(1);
373
+ });
374
+
375
+ list.addEventListener('scroll', updateButtonState, { passive: true });
376
+ window.addEventListener('resize', updateButtonState);
377
+ updateButtonState();
378
+ });
379
+ </script>
@@ -64,15 +64,29 @@ size:按钮尺寸
64
64
 
65
65
  {% else %}
66
66
 
67
- <button
68
- class="zz-btn zz-btn-{{ btn_type }} zz-btn-{{ btn_color }} zz-btn-shape-{{ shape }} zz-btn-{{ btn_size }} {% if width == 'full' %} tw-w-full {% endif %} {{ width }} {{ class_name }}"
69
- {% if modal_id != blank %} data-zz-modal-target="#{{ modal_id }}" {% endif %}
70
- {% if btn_id != blank %} id="{{ btn_id }}" data-track-zz-element="{{ btn_id }}" {% endif %}
71
- {% if backdrop_filter %}
72
- style="backdrop-filter: blur(12px);background: #FFFFFF0F;"
67
+ {% if btn_type == 'link' %}
68
+ <a href="{{ href | default: '#' }}"
69
+ {% if modal_id != blank %} data-zz-modal-target="#{{ modal_id }}" {% endif %}
70
+ {% if btn_id != blank %} id="{{ btn_id }}" data-track-zz-element="{{ btn_id }}" {% endif %}
71
+ class="zz-btn-link tw-text-[#378DDD] tw-inline-flex tw-items-center tw-text-[12px] lg:tw-text-[14px] tw-no-underline zz-btn-link-{{ btn_size }} {% if width == 'full' %} tw-w-full {% endif %} {{ class_name }}">
72
+ <span class="zz-btn-text">{{ text }}</span>
73
+ {% if postfix_icon %}<span class="zz-btn-icon" style="margin-left: {{ icon_left_margin }}px; margin-right: {{ icon_right_margin }}px;">
74
+ {% render 'zz-icon', icon_name: postfix_icon, icon_size: icon_size %}
75
+ </span>{% endif %}
76
+ </a>
77
+ {% else %}
78
+ <button
79
+ class="zz-btn zz-btn-{{ btn_type }} zz-btn-{{ btn_color }} zz-btn-shape-{{ shape }} zz-btn-{{ btn_size }} {% if width == 'full' %} tw-w-full {% endif %} {{ width }} {{ class_name }}"
80
+ {% if modal_id != blank %} data-zz-modal-target="#{{ modal_id }}" {% endif %}
81
+ {% if btn_id != blank %} id="{{ btn_id }}" data-track-zz-element="{{ btn_id }}" {% endif %}
82
+ {% if backdrop_filter %}
83
+ style="backdrop-filter: blur(12px);background: #FFFFFF0F;"
84
+ {% endif %}
85
+ >
86
+ {% if icon %}<span class="zz-btn-icon">{{ icon }}</span>{% endif %}
87
+ <span class="zz-btn-text">{{ text }}</span>
88
+ </button>
89
+
73
90
  {% endif %}
74
- >
75
- {% if icon %}<span class="zz-btn-icon">{{ icon }}</span>{% endif %}
76
- <span class="zz-btn-text">{{ text }}</span>
77
- </button>
91
+
78
92
  {% endif %}