קרוסלת המלצות

הכול נשען על scroll-snap של הדפדפן: החלקה, גלגלת, מקלדת ובלימה בנקודה עובדים מעצמם. הנקודות למטה רק קוראות את מצב הגלילה במקום לנהל אינדקס משלהן, ולכן הן לא מתנתקות מהמציאות אחרי החלקה ידנית. קרוסלת המלצות הוא רכיב מתוך רכיבים של כליקס. מה שמורידים הוא רכיב שלם, גם כ-HTML עצמאי וגם כרכיב React. אין ספרייה חיצונית, אין שלב בנייה, ואם כליקס ייעלם מחר הקוד ימשיך לעבוד.

רכיב · אמון · המלצות · בלי ספריות

<!-- קרוסלת המלצות — הוסיפו figure נוסף וכפתור נוסף באותו סדר -->
<style>
  .klix-tsl-track { display: flex; gap: 1rem; overflow-x: auto; padding-bottom: .5rem;
    scroll-snap-type: x mandatory; scrollbar-width: none }
  .klix-tsl-track::-webkit-scrollbar { display: none }
  .klix-tsl-track figure { flex: none; width: 17rem; margin: 0; padding: 1.25rem;
    border-radius: 1rem; background: #1e293b; scroll-snap-align: center }
  .klix-tsl-track blockquote { margin: 0; line-height: 1.7; color: #e2e8f0 }
  .klix-tsl-track figcaption { margin-top: .75rem; font-size: .85rem; color: #94a3b8 }
  .klix-tsl-dots { display: flex; justify-content: center; gap: .5rem; margin-top: .75rem }
  .klix-tsl-dots button { width: .55rem; height: .55rem; padding: 0; border: 0;
    border-radius: 999px; background: #475569; cursor: pointer }
  .klix-tsl-dots button[aria-current="true"] { background: #818cf8 }
</style>

<div class="klix-tsl">
  <div class="klix-tsl-track">
    <figure>
      <blockquote>הגיעו בזמן, סיימו בזמן, והמחיר היה בדיוק מה שסוכם.</blockquote>
      <figcaption>דנה כהן · בעלת עסק</figcaption>
    </figure>
    <figure>
      <blockquote>לקח יומיים והטלפון לא הפסיק לצלצל מאז.</blockquote>
      <figcaption>אבי לוי · מוסך</figcaption>
    </figure>
    <figure>
      <blockquote>הסבירו לי כל שלב בעברית פשוטה. סוף סוף.</blockquote>
      <figcaption>מירי שקד · קליניקה</figcaption>
    </figure>
  </div>
  <div class="klix-tsl-dots"></div>
</div>

<script>
(function () {
  var box = document.querySelector('.klix-tsl');
  if (!box) return;

  var track = box.querySelector('.klix-tsl-track');
  var dots = box.querySelector('.klix-tsl-dots');
  var items = track.querySelectorAll('figure');
  if (!items.length) return;

  items.forEach(function (_, i) {
    var b = document.createElement('button');
    b.type = 'button';
    b.setAttribute('aria-label', 'המלצה ' + (i + 1));
    b.addEventListener('click', function () {
      track.scrollTo({ left: (track.scrollWidth / items.length) * i, behavior: 'smooth' });
    });
    dots.appendChild(b);
  });

  function mark() {
    // המצב נקרא מהגלילה עצמה, ולכן הוא נכון גם אחרי החלקה ידנית או גלגלת
    var i = Math.round(Math.abs(track.scrollLeft) / (track.scrollWidth / items.length));
    dots.querySelectorAll('button').forEach(function (b, j) {
      b.setAttribute('aria-current', j === i ? 'true' : 'false');
    });
  }

  track.addEventListener('scroll', mark, { passive: true });
  mark();
})();
</script>