0

I am using the Swiper Element (WebComponent) within a React component. The components I am building are for a real estate agency, and I need to include multiple carousels on the page, each with different designs.

Initially, I successfully styled the pagination icons of the first carousel by using the injectStyles method and targeting the .swiper-pagination-bullet.swiper-pagination-bullet-active-main class. However, when I attempted to style a second carousel, the styles were not being applied. Despite trying various approaches, none of them seemed to work. It appears that the second carousel was inheriting the styles from the first component, or not even showing, which is causing the issue.

The documentation says:

"Due to Swiper web components realisation, same styles are injected in two places:

global scope (will be added to document ) shadow DOM If you need to add styles to shadow DOM scope, you can use injectStyles or injectStylesUrls parameters, e.g."

But it is not clear how to prevent that.

I managed to change the color of the second carousel changing the css variable, but I would like to know how to make the styles work using the injectStyles.

CODE FOR THE FIRST CAROUSEL:

import React, { useRef, useEffect } from 'react';
import { register } from 'swiper/element/bundle';
import ArticleCardContainer from './ArticleCard';

import { ArrowRight, ArrowLeft } from './Icons';

register();

export const PropertiesNewsCarousel = () => {
  const { articles } = Homeflow.get('latestPropertyNews');
  const isBackgroundWhite = Homeflow.get('isBackgroundWhite').is_background_white;

  const swiperElRef = useRef(null);

  //  Swiper Element web components - css to overide shadown down styles
  const navigationStyles = {
    position: 'static',
    height: '14px',
    marginTop: '0 !important',
    width: 'calc(var(--swiper-navigation-size) / 44 * 27)',
    zIndex: 10,
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
  };

  useEffect(() => {
    const swiperContainer = swiperElRef.current;

    const params = {
      grabCursor: true,
      // Default parameters
      slidesPerView: 1,
      spaceBetween: 40,
      // Responsive breakpoints
      breakpoints: {
        // small screens
        640: {
          slidesPerView: 1,
          spaceBetween: 40,
        },
        // medium screens
        768: {
          slidesPerView: 2,
          spaceBetween: 50,
        },
        // normal laptop screens
        1024: {
          slidesPerView: 3,
          spaceBetween: 60,
        },
      },
      mousewheel: {
        forceToAxis: true,
      },
      paginationClickable: true,
      pagination: {
        el: '.property-news-swiper-paginations',
        dynamicBullets: true,
        clickable: true,
        dynamicMainBullets: 3,
      },
      navigation: {
        nextEl: '.property-news-swiper-button-next',
        prevEl: '.property-news-swiper-button-prev',
      },
      injectStyles: [
        `
        .property-news-swiper-paginations .swiper-pagination-bullet,
        .property-news-swiper-paginations .swiper-pagination-bullet-active-prev,
        .property-news-swiper-paginations .swiper-pagination-bullet-active-next,
        .property-news-swiper-paginations .swiper-pagination-bullet-active-prev-prev,
        .property-news-swiper-paginations .swiper-pagination-bullet-active-next-next {
            background-color: transparent;
          }

          .property-news-swiper-paginations .swiper-pagination-bullet.swiper-pagination-bullet-active-main {
            width: 10px;
            height: 10px;
            background-color: ${isBackgroundWhite ? '#002844' : '#fff'};
          }

          .swiper-pagination {
            bottom: -60px !important;
          }

          .property-news-swiper-paginations {
            margin: 44px auto 0;
            transform: translateX(0) !important;
          }

          .property-news-swiper-button-next.swiper-button-disabled,
          .property-news-swiper-button-prev.swiper-button-disabled {
            opacity: .35;
            cursor: auto;
            pointer-events: none;
          }
      `,
      ],
    };

    Object.assign(swiperContainer, params);
    swiperContainer.initialize();
  }, []);

  return (
    <section className="swiper-section">
      <swiper-container
        ref={swiperElRef}
        init="false"
        id="swiper-container"
        class="swiper-1"
      >
        {articles?.map(article => (
          <swiper-slide key={article?.slug}>
            <ArticleCardContainer imageUrl={article?.image} title={article?.title} articleUrl={`/articles/${article?.slug}`} />
          </swiper-slide>
        ))}
      </swiper-container>

      {/* Boolet points pagination */}
      <div className="property-news-swiper-paginations" />

      {/* isBackgroundWhite type String */}

      {/* Arrows navigation */}
      <div className={`${isBackgroundWhite ? 'swiper-buttons-box' : 'swiper-buttons-box-primary'}`}>
        <section className={`${isBackgroundWhite ? 'swiper-buttons-box__section' : 'swiper-buttons-box-primary__section'}`}>
          <div className="property-news-swiper-button-prev" style={navigationStyles}>
            <ArrowLeft className={`${isBackgroundWhite ? 'swiper-buttons-box__section-arrow' : 'swiper-buttons-box-primary__section-arrow'}`} />
          </div>
          <div className="property-news-swiper-button-next" style={navigationStyles}>
            <ArrowRight className={`${isBackgroundWhite ? 'swiper-buttons-box__section-arrow' : 'swiper-buttons-box-primary__section-arrow'}`} />
          </div>
        </section>
      </div>
    </section>
  );
};

export default PropertiesNewsCarousel;

CODE FOR THE SECOND CAROUSEL

import React, { useRef, useEffect } from 'react';
import { uniqueKey } from 'homeflowjs';
import { register } from 'swiper/element/bundle';

register();

const PromoBoxesCarousel = () => {
  const promoCardsData = Homeflow.get('promoCards').promo_cards_data;

  const swiperElRef = useRef(null);

  //  Swiper Element web components - css to overide shadown down styles
  const paginationStyles = {
    display: 'flex',
    justifyContent: 'center',
    alignItems: 'center',
    height: '15px',
    transform: 'translateX(0)',
  };

  useEffect(() => {
    const swiperContainer = swiperElRef.current;
    const params = {
      grabCursor: true,
      // Default parameters
      slidesPerView: 1,
      spaceBetween: 10,
      // Responsive breakpoints
      breakpoints: {
        // small screens
        640: {
          slidesPerView: 1,
        },
        // medium screens
        768: {
          slidesPerView: 3,
        },
        // small laptop screens
        1024: {
          slidesPerView: 4,
        },
        // normal laptop screens
        1400: {
          slidesPerView: 5,
        },
      },
      mousewheel: {
        forceToAxis: true,
      },
      paginationClickable: true,
      pagination: {
        el: '.promo-swiper-paginations',
        dynamicBullets: true,
        clickable: true,
        dynamicMainBullets: 3,
      },
      injectStyles: [
        `
        .promo-swiper-paginations .swiper-pagination-bullet,
        .promo-swiper-paginations .swiper-pagination-bullet-active-prev,
        .promo-swiper-paginations .swiper-pagination-bullet-active-next,
        .promo-swiper-paginations .swiper-pagination-bullet-active-prev-prev,
        .promo-swiper-paginations .swiper-pagination-bullet-active-next-next {
            background-color: transparent;
          }

          .promo-swiper-paginations span.swiper-pagination-bullet.swiper-pagination-bullet-active.swiper-pagination-bullet-active-main {
            width: 10px;
            height: 10px;
            background-color: #fff;
          }

          .swiper-pagination {
            bottom: -60px !important;
          }

          .promo-swiper-paginations {
            margin: 44px auto 0;
            transform: translateX(0) !important;
          }
      `,
      ],
    };

    Object.assign(swiperContainer, params);
    swiperContainer.initialize();
  }, []);

  return (
    <section className="swiper-section">
      <swiper-container
        ref={swiperElRef}
        init="false"
        id="swiper-promo-container"
        class="swiper-2"
      >
        {promoCardsData?.map(card => (
          <swiper-slide key={uniqueKey()}>
            <section className="promo-boxes__item" style={{ backgroundImage: `url(${card.image_url})` }}>
              <div className="promo-boxes__item-content">
                <h2 className="promo-boxes__item-content-title">{ card.title }</h2>
                <a className="promo-boxes__item-content-mob-btn" href={card.button_url}>{ card.button_title }</a>

                <div className="promo-boxes__item-content-box">
                  <p className="promo-boxes__item-content-text">{ card.content }</p>
                  <a className="promo-boxes__item-content-button" href={card.button_url}>{ card.button_title }</a>
                </div>
              </div>
            </section>
          </swiper-slide>
        ))}
      </swiper-container>

      {/* Boolet points pagination */}
      <div className="promo-paginations-box">
        <div className="promo-swiper-paginations" style={{ ...paginationStyles, '--swiper-pagination-color': 'white' }} />
      </div>
    </section>
  );
};

export default PromoBoxesCarousel;

I tried to styles pagination on the carousels, I expected the changes in one carousel would not afect the other.

Marcos Riani
  • 1
  • 1
  • 2

0 Answers0