how can pass instance of swiper to another swiper as thumbs in Qwikjs

69 Views Asked by At

I created a Swiper component in Qwik and it works perfectly. but when I use two swiper together to handle thums swiper, I have a problem with pass instance of thumb swiper to the main swiper . I receive a swiper instance through the onSwiper event.

swiper component

import {
  component$,
  Slot,
  useStyles$,
  useVisibleTask$,
} from '@builder.io/qwik';
import SwiperConfig from './SwiperConfig';
import Swiper from 'swiper';
import {
  Autoplay,
  EffectCoverflow,
  EffectFade,
  HashNavigation,
  Navigation,
  Pagination,
  Thumbs,
} from 'swiper/modules';
import swiperStyles from 'swiper/css?inline';
import paginationStyle from 'swiper/css/pagination?inline';
import navigationStyle from 'swiper/css/navigation?inline';
import coverflowStyle from 'swiper/css/effect-coverflow?inline';
import fadeEffectStyle from 'swiper/css/effect-fade?inline';
import 'swiper/css/free-mode?inline';

const SwiperElement = component$(
  ({
    config,
    containerClass,
    name,
    navigation: NavigationElements,
    paginationClass,
  }) => {
    if (!name) {
      return (
        <div class="bg-red-800 text-white p-10">Swiper name is not defined</div>
      );
    }

    const {
      modules,
      navigation,
      onSwiper: OnSwiper,
      pagination,
      thumbs,
      ...rest
    } = config || {};

    useStyles$(paginationStyle);
    useStyles$(navigationStyle);
    useStyles$(swiperStyles);
    useStyles$(coverflowStyle);
    useStyles$(fadeEffectStyle);

    useVisibleTask$(
      () => {
        const mergedConfig = {
          ...SwiperConfig,
          modules: [
            Autoplay,
            EffectCoverflow,
            EffectFade,
            HashNavigation,
            Navigation,
            Pagination,
            Thumbs,
          ],
          hashNavigation: {
            watchState: true,
          },
          ...(pagination &&
            Object.keys(pagination)?.length > 0 && {
              pagination: {
                ...pagination,
              },
            }),
          ...(navigation &&
            Object.keys(navigation)?.length > 0 && {
              navigation: {
                nextEl: '.swiper-button-next',
                prevEl: '.swiper-button-prev',
                ...navigation,
              },
            }),
          ...rest,
        };
        const swiperElement = document.querySelectorAll(`.${name}`);
        if (swiperElement.length > 1) {
          throw `More than one element is named ${name}. Swiper can not find the intended element. Use unique names for your sliders.`;
        }
        const swiperInstance = new Swiper(`.${name}`, mergedConfig);
        if (OnSwiper) {
          OnSwiper(swiperInstance);
        }
      },
      {
        strategy: 'document-idle',
      }
    );

    return (
      <div class={`w-full swiper relative ${name} ${containerClass}`}>
        <div class={`swiper-wrapper`}>
          <Slot />
        </div>
        {NavigationElements && <NavigationElements />}
        {paginationClass && (
          <div class={`swiper-pagination ${paginationClass}`}></div>
        )}
      </div>
    );
  }
);

export default SwiperElement;

it's my index page . On this page, I can log it and view swiper instance but can not pass it to another swiper

import {
  $,
  component$,
  useSignal,
  noSerialize,
  useStyles$,
  useVisibleTask$,
} from '@builder.io/qwik';

import SwiperElement from '~/components/swiper/SwiperElement';

import SwiperSlide from '~/components/swiper/SwiperSlide';

const images = [
  'https://swiperjs.com/demos/images/nature-1.jpg',
  'https://swiperjs.com/demos/images/nature-2.jpg',
  'https://swiperjs.com/demos/images/nature-3.jpg',
  'https://swiperjs.com/demos/images/nature-4.jpg',
];

export default component$(() => {
  const thumbSwiperInstance = useSignal(null);

  const onSwiper = $((swiper) => {
    console.log('swiper instance', swiper);
    thumbSwiperInstance = swiper;
    // thumbSwiperInstance.value = swiper;
  });

  return (
    <div>
      <SwiperElement
        name="main-swiper"
        containerClass="main-swiper"
        config={{
          slidesPerView: 1,
          thumbs: {
            swiper: thumbSwiperInstance.value,
          },
        }}
      >
        {images.map((image) => (
          <SwiperSlide>
            <img src={image} with="100%" height="100%" />
          </SwiperSlide>
        ))}
      </SwiperElement>
      <SwiperElement
        name="thumbs-swiper"
        config={{
          onSwiper: onSwiper,
          slidesPerView: 3,
          spaceBetween: 20,
        }}
      >
        {images.map((image) => (
          <SwiperSlide>
            <img src={image} with="100%" height="100%" />
          </SwiperSlide>
        ))}
      </SwiperElement>
    </div>
  );
});

how can I do this? MRE

0

There are 0 best solutions below