Upsell

<div class="c-upsell">

    <div class="c-upsell__type">
        <p class="c-upsell__name">Lavaggio autovettura</p>
        <p class="c-upsell__mobile-price">8,00 € - 24,00 €</p>
    </div>

    <div class="c-upsell__details">
        <div class="c-upsell__price">
            <div class="c-upsell__price-item">
                <div class="label">Prezzo min.</div>
                <div class="value">8,00 €</div>
            </div>
            <div class="c-upsell__price-item">
                <div class="label">Prezzo max.</div>
                <div class="value">24,00 €</div>
            </div>
        </div>

        <div class="c-upsell__toggle-block">
            <button class="c-button c-upsell__toggle-btn" data-upsell-toggle aria-pressed="false">
                Prenota servizio
            </button>
            <span class="c-rounded-label c-rounded-label--positive c-rounded-label--small js-upsell-booked-label" style="display: none;" aria-live="polite" role="status">
                Prenotato
            </span>
            <button type="button" class="c-button c-button--ghost c-upsell__delete-btn" aria-label="Elimina servizio" data-upsell-delete style="display: none;">
                <svg class="c-icon--16">
                    <use xlink:href="#ic-trash"></use>
                </svg> </button>
        </div>
    </div>

</div>
<div class="c-upsell{{#if modifier}} {{modifier}}{{/if}}">
  
  <div class="c-upsell__type">
    <p class="c-upsell__name">{{{ name }}}</p>
    <p class="c-upsell__mobile-price">{{price-item.[0].value}}{{#if price-item.[1]}} - {{price-item.[1].value}}{{/if}}</p>
  </div>

  <div class="c-upsell__details">
    <div class="c-upsell__price">
      {{#each price-item}}
      <div class="c-upsell__price-item">
        <div class="label">{{ label }}</div>
        <div class="value">{{ value }}</div>
      </div>
      {{/each}}
    </div>

    <div class="c-upsell__toggle-block">
      <button 
        class="c-button c-upsell__toggle-btn" 
        data-upsell-toggle
        aria-pressed="false">
        {{{ btn-toggle.text }}}
      </button>
      <span 
        class="c-rounded-label c-rounded-label--positive c-rounded-label--small js-upsell-booked-label"
        style="display: none;"
        aria-live="polite"
        role="status">
        {{{ rounded-label.text }}}
      </span>
      <button type="button" 
        class="c-button c-button--ghost c-upsell__delete-btn" 
        aria-label="{{ btn-delete.aria-label }}"
        data-upsell-delete 
        style="display: none;">
        {{> @icon btn-delete.icon }}
      </button>
    </div>
  </div>

</div>
{
  "name": "Lavaggio autovettura",
  "price-item": [
    {
      "label": "Prezzo min.",
      "value": "8,00 €"
    },
    {
      "label": "Prezzo max.",
      "value": "24,00 €"
    }
  ],
  "btn-toggle": {
    "text": "Prenota servizio"
  },
  "rounded-label": {
    "text": "Prenotato"
  },
  "btn-delete": {
    "aria-label": "Elimina servizio",
    "icon": {
      "symbol": "ic-trash",
      "class": "c-icon--16"
    }
  }
}
  • Content:
    .c-upsell {
      display: flex;
      align-items: center;
      gap: remify(16px);
      justify-content: space-between;
    }
    
    .c-upsell__name {
      @include font-scale(level-2, bold);
      color: primary(night, 100);
    }
    
    .c-upsell__toggle-btn {
      padding: remify(6px) remify(12px);
      @include font-scale(level-1, bold);
      border-radius: remify(8px);
    }
    
    .c-upsell__toggle-btn.is-active {
      display: none;
    }
    
    .c-upsell__delete-btn {
      padding: remify(8px) remify(12px);
      border-radius: remify(8px);
      display: flex;
      align-items: center;
      justify-content: center;
      width: remify(32px);
      aspect-ratio: 1 / 1;
      padding: 0;
    } 
    
    .c-upsell__toggle-block {
      display: flex;
      align-items: center;
      justify-content: flex-end;
      flex: 1 0 remify(140px);
    }
    
    .c-upsell__details,
    .c-upsell__price {
      display: flex;
      align-items: center;
    }
    
    .c-upsell__details {
      gap: remify(32px);
    }
    
    .c-upsell__price {
      display: none;
      gap: remify(16px);
      
      @include min-screen(bp(tablet)) {
        display: flex;
      }
    }
    
    .c-upsell__mobile-price {
      @include font-scale(level-2, bold);
      color: secondary(text, 100);
    
      @include min-screen(bp(tablet)) {
        display: none;
      }
    }
    
    
    .c-upsell__price-item {
      display: flex;
      color: secondary(text, 100);
      align-items: baseline;
      gap: remify(4px);
    }
    
    .c-upsell__price-item .label {
      @include font-scale(level-1);
      text-transform: uppercase;
    }
    
    .c-upsell__price-item .value {
      @include font-scale(level-4, bold);
    }
  • URL: /components/raw/upsell/_upsell.scss
  • Filesystem Path: src/views/02-molecules/upsell/_upsell.scss
  • Size: 1.4 KB
  • Content:
    (() => {
      const initUpsell = () => {
        const upsellComponents = document.querySelectorAll('.c-upsell');
    
        upsellComponents.forEach(upsell => {
          const toggleBtn = upsell.querySelector('[data-upsell-toggle]');
          const deleteBtn = upsell.querySelector('[data-upsell-delete]');
          const bookedText = upsell.querySelector('.js-upsell-booked-label');
    
          if (!toggleBtn || !deleteBtn || !bookedText) return;
    
          const handleToggle = () => {
            toggleBtn.classList.add('is-active');
            toggleBtn.setAttribute('aria-pressed', 'true');
            bookedText.style.display = 'inline-flex';
            deleteBtn.style.display = 'inline-flex';
            deleteBtn.focus();
          };
    
          const handleDelete = () => {
            toggleBtn.classList.remove('is-active');
            toggleBtn.setAttribute('aria-pressed', 'false');
            bookedText.style.display = 'none';
            deleteBtn.style.display = 'none';
            toggleBtn.focus();
          };
    
          toggleBtn.addEventListener('click', handleToggle);
          deleteBtn.addEventListener('click', handleDelete);
    
          // Gestione della tastiera
          toggleBtn.addEventListener('keydown', (e) => {
            if (e.key === 'Enter' || e.key === ' ') {
              e.preventDefault();
              handleToggle();
            }
          });
    
          deleteBtn.addEventListener('keydown', (e) => {
            if (e.key === 'Enter' || e.key === ' ') {
              e.preventDefault();
              handleDelete();
            }
          });
        });
      };
    
      // Inizializza solo quando il DOM è pronto
      if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', initUpsell);
      } else {
        initUpsell();
      }
    })(); 
  • URL: /components/raw/upsell/upsell.js
  • Filesystem Path: src/views/02-molecules/upsell/upsell.js
  • Size: 1.7 KB

No notes defined.