<div class="c-foldable-banner c-foldable-banner--carousel">

    <div class="c-foldable-banner__wrapper" id="foldable-banner">
        <section class="c-scrolling-banner " aria-label="Promozioni" aria-roledescription="carousel">

            <div class="jsScrollingBanner owl-carousel">
                <div class="c-scrolling-banner__slide u-bg-color-sky-120">
                    <div class="c-scrolling-banner__image">
                        <img src="../../images/svgs/stk_write_us.svg" alt="" width="60">
                    </div>
                    <div class="c-scrolling-banner__text">
                        <p>Lorem ipsum dolor sit amet, <strong>consectetur adipiscing</strong> elit sed do.</p>
                    </div>
                    <div class="c-scrolling-banner__cta"><a href="#" class="c-link c-link--white c-link--small">
                            Iscriviti
                        </a></div>
                </div>
                <div class="c-scrolling-banner__slide u-bg-color-night-100">
                    <div class="c-scrolling-banner__image">
                        <img src="../../images/svgs/stk_write_us.svg" alt="" width="60">
                    </div>
                    <div class="c-scrolling-banner__text">
                        <p><strong>Ut enim ad minim</strong> veniam, quis nostrud exercitation ullamco.</p>
                    </div>
                </div>
                <div class="c-scrolling-banner__slide u-bg-color-sun-120 u-color-night-120">
                    <div class="c-scrolling-banner__image">
                        <img src="../../images/svgs/stk_write_us.svg" alt="" width="60">
                    </div>
                    <div class="c-scrolling-banner__text">
                        <p><strong>Duis aute irure</strong> dolor in reprehenderit in voluptate velit.</p>
                    </div>
                    <div class="c-scrolling-banner__cta"><a href="#" class="c-link c-link--white c-link--small">
                            Scopri le offerte
                        </a></div>
                </div>
            </div>

        </section>
        <button class="c-foldable-banner__close-btn js-foldable-banner-close-btn" aria-controls="foldable-banner" aria-expanded="true">
            <svg class="c-icon c-icon--24 u-color-basic-white-100" role="presentation">
                <use xlink:href="#ic_close_black_24px"></use>
            </svg> </button>
    </div>

    <button class="c-foldable-banner__open-btn js-foldable-banner-open-btn" aria-controls="foldable-banner" aria-expanded="true">
        <svg class="c-icon c-icon--18 u-color-basic-white-100" role="presentation">
            <use xlink:href="#ic_expand_more_black_24px"></use>
        </svg> </button>

</div>
<div class="c-foldable-banner c-foldable-banner--carousel{{#if modifier}} {{ modifier }}{{/if}}">

  <div class="c-foldable-banner__wrapper" id="foldable-banner">
    {{> @scrolling-banner }}
    <button class="c-foldable-banner__close-btn js-foldable-banner-close-btn" aria-controls="foldable-banner" aria-expanded="true">
      {{> @icon icn-close }}
    </button>
  </div>

  <button class="c-foldable-banner__open-btn js-foldable-banner-open-btn" aria-controls="foldable-banner" aria-expanded="true">
    {{> @icon icn-open }}
  </button>

</div>
{
  "img": {
    "src": "/images/svgs/stk_write_us.svg"
  },
  "text": "<p>Per aggiornamenti in tempo reale sul proprio volo e informazioni sui nostri servizi, è disponibile la chat su <a href=\"#\">Whatsapp</a>, al numero <a href=\"+390516479615\"><strong>+39 0516479615</strong></a>, oppure la chat su <a href=\"\">Messenger</a>.</p>",
  "icn-close": {
    "symbol": "ic_close_black_24px",
    "class": "c-icon c-icon--24 u-color-basic-white-100"
  },
  "icn-open": {
    "symbol": "ic_expand_more_black_24px",
    "class": "c-icon c-icon--18 u-color-basic-white-100"
  },
  "ariaLabel": "Promozioni",
  "slides": [
    {
      "cssClass": "u-bg-color-sky-120",
      "img": {
        "src": "/images/svgs/stk_write_us.svg"
      },
      "text": "<p>Lorem ipsum dolor sit amet, <strong>consectetur adipiscing</strong> elit sed do.</p>",
      "cta": {
        "text": "Iscriviti",
        "url": "#",
        "modifier": "c-link c-link--white c-link--small"
      }
    },
    {
      "cssClass": "u-bg-color-night-100",
      "img": {
        "src": "/images/svgs/stk_write_us.svg"
      },
      "text": "<p><strong>Ut enim ad minim</strong> veniam, quis nostrud exercitation ullamco.</p>"
    },
    {
      "cssClass": "u-bg-color-sun-120 u-color-night-120",
      "img": {
        "src": "/images/svgs/stk_write_us.svg"
      },
      "text": "<p><strong>Duis aute irure</strong> dolor in reprehenderit in voluptate velit.</p>",
      "cta": {
        "text": "Scopri le offerte",
        "url": "#",
        "modifier": "c-link c-link--white c-link--small"
      }
    }
  ]
}
  • Content:
    .c-foldable-banner {
      background-color: primary(sky, 120);
      position: relative;
    
      &.is-collapsed {
        border-top: none;
      }
    
    }
    
    /*------------------------------------*\
      CAROUSEL VARIANT
      Il wrapper ospita lo scrolling-banner (carosello) al posto di immagine+testo.
      Sfondo e padding restano quelli base del __wrapper (un solo livello).
    \*------------------------------------*/
    .c-foldable-banner--carousel {
    
      // Il wrapper non ha padding/max-width propri: i colori delle slide
      // riempiono il banner edge-to-edge (padding interno alla slide).
      .c-foldable-banner__wrapper {
        display: block;
        max-width: none;
        margin-inline: 0;
        padding: 0;
        position: relative;
      }
    
      .c-scrolling-banner {
        width: 100%;
      }
    
      // Pulsante di chiusura in overlay sopra al carosello.
      .c-foldable-banner__close-btn {
        position: absolute;
        top: 0;
        right: 0;
        z-index: 2;
      }
    
    }
    
    /*------------------------------------*\
      COLLAPSED STATE
    \*------------------------------------*/
    .c-foldable-banner.is-collapsed {
    
      .c-foldable-banner__wrapper {
        display: none;
      }
    
      .c-foldable-banner__open-btn {
        display: flex;
      }
    
    }
    
    // Variante carousel: in chiusura NON usiamo display:none (che azzererebbe
    // le larghezze calcolate da Owl, richiedendo un refresh alla riapertura →
    // glitch di altezza). Collassiamo l'altezza tenendo il wrapper renderizzato,
    // così Owl resta sempre misurato e la riapertura è immediata e stabile.
    .c-foldable-banner--carousel.is-collapsed {
    
      .c-foldable-banner__wrapper {
        display: block;
        height: 0;
        overflow: hidden;
      }
    
    }
    /*------------------------------------*\
      END COLLAPSED STATE
    \*------------------------------------*/
    
    
    .c-foldable-banner__wrapper {
      max-width: remify(900px);
      margin-inline: auto;
      gap: remify(16px);
      align-items: center;
      padding: remify(16px);
      display: flex;
    
      @include min-screen(bp(tablet)) {
        padding: remify(24px) remify(16px);
      }
    }
    
    .c-foldable-banner__image {
      display: none;
    
      @include min-screen(bp(phablet)) {
        display: block;
      }
    
    }
    
    .c-foldable-banner__text {
      @include font-scale(level-1-5);
      color: secondary(basic-white, 100);
    
      @include min-screen(bp(tablet)) {
        @include font-scale(level-2);
      }
    
      a {
        color: currentColor;
      }
    }
    
    .c-foldable-banner__close-btn {
      width: remify(44px);
      aspect-ratio: 1;
      background-color: transparent;
      border: none;
      cursor: pointer;
    }
    
    .c-foldable-banner__open-btn {
      display: none;
      position: absolute;
      left: 50%;
      bottom: -20px;
      transform: translateX(-50%);
      background-color: primary(sky, 120);
      border: none;
      align-items: center;
      justify-content: center;
      width: remify(48px);
      border-radius: 0 0 remify(8px) remify(8px);
      cursor: pointer;
      z-index: $z-Index-foldable-open-btn;
    }
  • URL: /components/raw/foldable-banner/_foldable-banner.scss
  • Filesystem Path: src/views/02-molecules/foldable-banner/_foldable-banner.scss
  • Size: 2.8 KB
  • Content:
    // foldable-banner.js
    (() => {
      document.addEventListener('DOMContentLoaded', () => {
        const BANNER_SELECTOR = '.c-foldable-banner';
        const banners = document.querySelectorAll(BANNER_SELECTOR);
    
        if (!banners.length) return; // nessun banner → esce subito
    
        const getFocusable = (root) =>
          root.querySelectorAll(
            'a[href], button, input, select, textarea, details summary, [tabindex]:not([tabindex="-1"])'
          );
    
        banners.forEach((banner) => {
          const wrapper  = banner.querySelector('.c-foldable-banner__wrapper');
          const btnClose = banner.querySelector('.js-foldable-banner-close-btn');
          const btnOpen  = banner.querySelector('.js-foldable-banner-open-btn');
    
          if (!wrapper || !btnClose || !btnOpen) return;
    
          let isOpen = true; // stato iniziale: aperto
    
          const setFocusability = (enabled) => {
            const focusables = Array.from(getFocusable(wrapper));
            focusables.forEach((el) => {
              if (el === btnClose) return;
              if (!enabled) {
                if (el.hasAttribute('tabindex')) el.dataset.prevTabindex = el.getAttribute('tabindex');
                el.setAttribute('tabindex', '-1');
              } else {
                if (el.dataset.prevTabindex != null) {
                  el.setAttribute('tabindex', el.dataset.prevTabindex);
                  delete el.dataset.prevTabindex;
                } else {
                  el.removeAttribute('tabindex');
                }
              }
            });
          };
    
          const applyState = () => {
            banner.classList.toggle('is-collapsed', !isOpen);
            wrapper.setAttribute('aria-hidden', String(!isOpen));
            // entrambi i pulsanti devono avere aria-expanded uguale
            btnClose.setAttribute('aria-expanded', String(isOpen));
            btnOpen.setAttribute('aria-expanded', String(isOpen));
            setFocusability(isOpen);
          };
    
          const open = () => {
            if (isOpen) return;
            isOpen = true;
            applyState();
            btnClose.focus();
          };
    
          const close = () => {
            if (!isOpen) return;
            isOpen = false;
            applyState();
            btnOpen.focus();
          };
    
          btnClose.addEventListener('click', (e) => {
            e.preventDefault();
            close();
          });
    
          btnOpen.addEventListener('click', (e) => {
            e.preventDefault();
            open();
          });
    
          banner.addEventListener('keydown', (e) => {
            if (e.key === 'Escape' && isOpen) {
              e.stopPropagation();
              close();
            }
          });
    
          // inizializza stato coerente con HTML (aperto)
          applyState();
        });
      });
    })();
    
  • URL: /components/raw/foldable-banner/foldable-banner.js
  • Filesystem Path: src/views/02-molecules/foldable-banner/foldable-banner.js
  • Size: 2.6 KB

No notes defined.