npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

use-snap-slider

v0.1.4

Published

React hook to manage css snap sliders

Downloads

196

Readme

use-snap-slider

React hook / Vanilla JS to manage scroll-state for CSS Scroll Snap

Gives you states and actions for CSS Scroll Snap sliders:

  • count:number - total pages
  • countDelta:number - total slides, for 1/1 width slides the same as count
  • index:number - current page index
  • indexDelto:number - current slide index, for 1/1 width slides the same as index
  • prevEnabled:boolean - can go to previous slide
  • nextEnabled:boolean - can go to next slide
  • goPrev() - scroll to previous slide
  • goNext() - scroll to next slide
  • jumpTo(index:number) - go to a spesified slide

Usage

npm i use-snap-slider

Basic usage (react)

In your react component:

See a more complete react-example here

import React, { useRef } from 'react'
import { useSnapSlider } from 'use-snap-slider'

export function MySlider () {
  const ref = useRef<HTMLDivElement | null>(null)
  const slides = [1,2]
  // Passing inital count avoid extra render, for best lighthouse score, pass the same count as you show on mobile
  const {index, count, jumpTo, goPrev, goNext, prevEnabled, nextEnabled} = useSnapSlider(ref, slides.length)
  const pages = Array.from(Array(count).keys())
  return (
    <div>
      <div className="flex scroll-smooth snap-x snap-mandatory overflow-x-auto" ref={ref}>
        {slides.map((slide) => (
          <div key={slide} className="flex snap-start shrink-0 w-full md:w-1/2">
            Slide {slide}
          </div>
        ))}
      </div>
      <nav aria-label="Pages navigation">
        {pages.map((page) => (
          <button onClick={() => jumpTo(page)} disabled={page === index}>{page + 1}</button>
        ))}
      </nav>
      <nav aria-label="Prev / Next navigation">
        <button onClick={goPrev} disabled={!prevEnabled}>Prev</button>
        <button onClick={goNext} disabled={!nextEnabled}>Next</button>
      </nav>
    </div>
  )
}

Basic usage (vanilla javascript)

See a more complete vanilla javascript example here

import { createSnapSlider } from 'use-snap-slider/dist/snap-slider'

function createSnapSliderVanilla(element: HTMLElement) {
  const { jumpTo, goNext, goPrev, subscribe } = createSnapSlider({
    element,
    count: count,
    index: 0,
  })
  subscribe((state) => {
    // Update UI with sate
  })
  document.querySelector('.prev-btn')?.addEventListener('click', goPrev)
  document.querySelector('.next-btn')?.addEventListener('click', goNext)
}
// Expose globally
window.createSnapSliderVanilla = createSnapSliderVanilla

API

useSnapSlider react hook

import { useSnapSlider } from 'use-snap-slider'

const {
  index: number,
  // If displaying multiple slides on the same page, this will be slide at left position
  indexDelta: number,
  // Count of pages
  count: number,
  countDelta: number,
  prevEnabled: boolean,
  nextEnabled: boolean,
  jumpTo: (index: number) => void,
  goNext: () => void,
  goPrev: () => void,
} = useSnapSlider(
  ref: MutableRefObject<HTMLDivElement | null>,
  // Pass inital count
  count?: number = 1,
  // Pass inital index
  index?: number = 0,
  // onPrev / next buttons go to end / start 
  circular = false,
  // Will reset index on change of count, but pass something here to force a reset even if count dont change
  countHash?: string | number
)

createSnapSlider vanilla js function

import { createSnapSlider } from 'use-snap-slider/dist/snap-slider'

const {
  // Removes event listner for window.resize and element.scroll
  destroy: () => void,
  // Get current state
  getState: () => TSnapSliderStateFull,
  // Go to slide index
  jumpTo: (index?: number, indexDelta?: number) => void,
  goNext: () => void,
  goPrev: () => void,
  // Subscribe to updates
  subscribe: (fn: TSnapListner) => () => void,
  // Set element at later stage
  setElement: (el: HTMLElement) => void,
  // Updates count and countDelta, call if you change inner slides
  calculate: () => void,
  // Should subscribe return a inital publish after subscribing
  initalSubscriptionPublish: boolean = true
} = createSnapSlider({
  element: HTMLDivElement | null,
  count?:number = 1,
  countDelta?:number,
  index?:number = 0,
  circular?:boolean,
  indexDelta?:number,
  itemSelector?:string = ':scope > *',
})

Adding nessesary styles

This library only delivers javascript for handle the state, you will need to make your own component for complete solution. See examples in this repo:

TailwindCSS

See also tailwinds own documentation for scroll snap

<div class="flex scroll-smooth snap-x snap-mandatory overflow-x-auto">
  <div class="flex snap-start shrink-0">
    Slide 1
  </div>
  <div class="flex snap-start shrink-0">
    Slide 2
  </div>
</div>

Basic css

<style>
.css-slider {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  -webkit-overflow-scrolling: touch;
}
.css-slider::-webkit-scrollbar {
  display: none;
}
.css-slider-item {
  display: flex;
  scroll-snap-align: start;
  flex-shrink: 0;
}
.css-slider-item-half {
  width: 50%;
}
</style>
<!-- Markup -->
<div class="css-slider">
  <div class="css-slider-item css-slider-item-half">
    Slide 1
  </div>
  <div class="css-slider-item css-slider-item-half">
    Slide 2
  </div>
</div>