Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

馃毃鈿狅笍 Important Announcement 鈿狅笍馃毃 #55

Open
cpreston321 opened this issue Apr 10, 2023 · 11 comments 路 May be fixed by #109
Open

馃毃鈿狅笍 Important Announcement 鈿狅笍馃毃 #55

cpreston321 opened this issue Apr 10, 2023 · 11 comments 路 May be fixed by #109

Comments

@cpreston321
Copy link
Owner

cpreston321 commented Apr 10, 2023

Update 11-29-2023

Please test and try out the new swiper element release.

Note

This is still a work in progress as the api and helper compostables might change.

# npm
npm install nuxt-swiper@next

# yarn
yarn add nuxt-swiper@next

#pnpm
pnpm add nuxt-swiper@next

#bun
bun add nuxt-swiper@next
  • Pull request info here
  • Update docs here

image

Moving forward Swiper.js is moving to web components. Removing support for Vue/React libraries in favor of web components. This means that nuxt-swiper will be obsolete in the coming months for the swiper/vue package. This means that if you see any bugs within the swiper/vue modules it's most likely it will not be fixed 馃檨

So what does this mean?

Well this means that I will have to a totally re-write to support swiper/elements, Which in this case -- I really don't know if there is really any benefit of doing so when you can just import the element straight to your project to work out of the box. When creating nuxt-swiper I wanted to make it easier setting up swiper.js for my various personal projects and it worked for what I needed.


In the recent months I have been receiving issues that are non related to nuxt-swiper itself, as it makes swiper.js easier to work with all the great things Nuxt provides which is Auto Imports, Typescript types and the plug n' play module system it has. I've have been trying to help many people with there problems but some are just beyond my capabilities to fix since I do not maintain the swiper/core.

So I would love to discuss potentially implementing swiper/elements but I would love to talk to the community to see if it something that is even feasible to do. I appreciate everyone that has supported and starred the project! It means the world! Please feel free to discuss what you think below.

Links:

  • Swiper Elements: Here
  • Swiper Vue: Here

Thanks,
CP 馃挌

@cpreston321 cpreston321 pinned this issue Apr 10, 2023
@FranciscoKloganB
Copy link

I have no experience with Web Components, but what happens to TypeScript, do we go back to vanilla JavaScript when interacting with these?

Does it mean, we need also need go back to manually importing, every Module/CSS file that we want, explicitly?

Thanks for sharing.

Copy link
Owner Author

@FranciscoKloganB

Hey 馃憢! I will have to look into as I never worked with web components with Typescript but I think it's possible still but I just have to see how it works. I will let you know.

Technically yes but I could re-write the package to include the web components in this package so you wouldn't have to import manually. I just have to figure it out if it's even useful for everyone to make the change!

Thanks,
CP

@NnicanBuak
Copy link

@cpreston321

Should we leave nuxt-swiper on the stable version of Swiper 8 which will still support Vue components or start a new branch with a module that will work with the new Swiper and will also provide a wrapper for the WebComponents?

I do not know what it is, but from the example code looks like the same as the usual components

Copy link
Owner Author

cpreston321 commented Apr 12, 2023

Hey @NnicanBuak!

I think the current version of Swiper 9 is best bet to keep bugs limited but knowing we are going to lose support for the main package will come will drawbacks including bugs which I don't control. I think we can keep it on Swiper 9 until compatibility is lost.

I do think it's feasible to do a major version bump to then support elements out of the box. I am going to look more into it to see if there is a way implement typescript types. If so that might be the best route.

@FranciscoKloganB
Copy link

I can try to gather as much information as I can, but I mostly a backend developer playing "the frontend world". 馃槄

If I find relevant information, I will share it here.

@FranciscoKloganB
Copy link

FranciscoKloganB commented Apr 24, 2023

Have not been able to figure out much but here are the things that are "obvious" after trying to migrate from this package to web-components solution. There is way more boilerplate involved. Somethings about the web-components API appear a bit less straightforward.

Here is a list of a few things I had to do.

  • Like in "vanilla" Swiper, we must load styles for desired modules explicitly. However, there is a caveat, they must be injected globally and also a value to injectStylesUrls key in SwiperOptions. The only way I found to do this was to create an array that pulled Swiper module styles I have interest in containing strings pointing to cdn.jsdelivr.net, passing them to useHead and also to <swiper-container>.
  • Must pre-render swiper-container on the server, otherwise, onMounted hook does not find swiper-container when doing the querySelector invocation when Hydrating on the client.
    • Optionally render a dummy swiper-slide on the server to avoid content shift later.
  • Must add the property <swiper-container :init="false" /> to prevent swiper initialization until parameters are merged (this approach is required whenever we use breakpoints or add modules to the SwiperOptions object.
    • To merge the parameters an onMounted hook routine is required, to find the swiper-container HTML element and merge our SwiperObjects with it.
    • We can now call the queried element initialize function. At this point Swiper starts working more or less like before.
      • issue: the function initialize is not recognized by TypeScript so we need to declare a union type or use any 馃槩
  • Must call register (only once - still need to figure out the best place to do this)
  • Typescript not fully supported at the WebComponent level (e.g., within the we get (property) SwiperSlide: any)

    The code snippets below are only a fraction of the pain I had to go truth to migrate my carousel (which was rather "simple") to web-components (and I am still losing my scrollbar and pagination components when going from small screens to big screens).

    // nuxt.config.ts
    /**
    * @see https://vuejs.org/guide/extras/web-components.html#using-custom-elements-in-vue
    * @see https://nuxt.com/docs/api/configuration/nuxt-config#compileroptions-1
    */
      vue: {
        compilerOptions: {
          isCustomElement: (tag: string) =>
            ['swiper-container', 'swiper-slide'].includes(tag),
        },
      },
    // composables/useSwiper.ts
    export function useSwiper(
      options: SwiperOptions,
      moduleStylesUrls: Readonly<string[]> = []
    ) {
      const swiperContainerRef = ref<HTMLElement>()
    
      register()
    
      useHead({
        link: moduleStylesUrls.map((url) => ({
          href: url,
          rel: 'stylesheet',
          type: 'text/css',
        })),
      })
    
      onMounted(() => {
        /**
         * @see https://swiperjs.com/element#core-version-and-modules
         * @see https://swiperjs.com/element#parameters-as-props
         */
    
        if (swiperContainerRef.value) {
          const swiperContainerEl = swiperContainerRef.value as HTMLElement & {
            initialize: () => void
          }
    
          Object.assign(swiperContainerEl, options)
    
          swiperContainerEl.initialize()
        } else {
          throw createError({
            message: `Could not create carousel. Missing DOM element <swiper-container />.`,
            statusCode: 500,
            statusMessage: `Internal Server Error`,
          })
        }
      })
    
      return swiperContainerRef
    }
    // components/HomeCarousel.vue
    <script>
    const swiperStylesCdnUrl = [
      'https://cdn.jsdelivr.net/npm/swiper@9.2.4/modules/autoplay/autoplay.min.css',
      'https://cdn.jsdelivr.net/npm/swiper@9.2.4/modules/pagination/pagination.min.css',
      'https://cdn.jsdelivr.net/npm/swiper@9.2.4/modules/scrollbar/scrollbar.min.css',
    ] as const
    
    const paginationEnabled = ref(true)
    const scrollbarEnabled = ref(true)
    
    const swiperOptions = reactive<SwiperOptions>({
      ...otherSwiperOptionsNotReallyRelevantForTheExample,
      injectStylesUrls: [...swiperStylesCdnUrl],
      modules: [Autoplay, Pagination, Scrollbar],
    })
    
    const swiperContainerRef = useSwiper(swiperOptions, swiperStylesCdnUrl)
    
    ...otherStuff
    </script>
    
    <template>
      <div>
        <div>
          <swiper-container ref="swiperContainerRef" :init="false">
            <HomeCarouselSlideList :items="items" :carousel-height="carouselHeight" />
          </swiper-container>
        </div>
        <div class="mt-1 space-y-4">
          <div v-show="scrollbarEnabled" class="swiper-scrollbar"></div>
          <div v-show="paginationEnabled" class="swiper-pagination"></div>
        </div>
      </div>
    </template>

@cpreston321
Copy link
Owner Author

Hello all!

I have been working on a new branch that contains this work, but it seems that there is still some on going issues with swiper elements to make the full implementation.

Branch: https://github.com/cpreston321/nuxt-swiper/tree/feat/elements

@cpreston321
Copy link
Owner Author

@FranciscoKloganB Thanks again for initial research on how to best implement native web-components! 馃檹馃徏

I really do appreciate the community helping me out it means the world.

Thanks,
CP 馃殌

@FranciscoKloganB
Copy link

FranciscoKloganB commented Jul 11, 2023

I've actually updated the pseudo-code below to modify the useSwiper composable. By using an Vue ref and assigning it to <swiper-container ref="swiperContainerRef" :init="false"> my Swiper stopped breaking as I navigated across pages. It was also a problem that only happened in development, but no longer does. :)

The update still does not contemplate the "singleton register"

Good luck with the implementation! I hope my poc was useful in anyway.

@NeekoDev
Copy link

Any news about elements branch? :)

@cpreston321
Copy link
Owner Author

@NeekoDev Yes! I got it working last week you can check it out here: https://github.com/cpreston321/nuxt-swiper/tree/feat/elements 馃榾

While testing there are some modules like creative-effects not working with elements which seems to be upstream issue. I will submit an issue here soon. I also want a clean way to implement bundled vs base (meaning you have to import the styles and modules you want to enable on each instance of swiper). I also wanted to create some composables to help reference a swiper instance like how the current vue implementation.

In the meantime I am setting up a edge releases for elements so we can test in the mean time while keeping the current release as is. This will be good for reporting bugs etc.

Thanks,
CP 馃殌

@cpreston321 cpreston321 linked a pull request Nov 28, 2023 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants