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

@c0ffee_39/react-cool-scroll

v1.0.1

Published

Simple, user-friendly, cross-platform and adaptive scrolling. Customize as you want, use a lot of flexible settings and enjoy the pleasant UI/UX of a custom scroll ⚙️✨🎨

Downloads

15

Readme

React-custom-scroll 🚀

Simple, user-friendly, cross-platform and adaptive scrolling. Customize as you want, use a lot of flexible settings and enjoy the pleasant UI/UX of a custom scroll ⚙️✨🎨

Basic usage

Minimal code example

Let's say we render lots of cards inside some parent.

In your component

"use client"; // For NextJS
import classes from "./MyComp.module.scss";
import CustomScroll, { useScrollSetup } from "@c0ffee_39/react-custom-scroll";

export function MyComp() {
  const [ancestorRef, childrenRef, translateX, setTranslateX] = useScrollSetup<
    HTMLDivElement,
    HTMLDivElement
  >();

  return (
    <div className={classes.parentWrapper} ref={ancestorRef}>
      <div
        className={classes.childrenWrapper}
        ref={childrenRef}
        style={{
          transform: `translateX(${translateX}px)`,
        }}
      >
        <Card />
        <Card />
        <Card />
        ...
        <Card />
      </div>
      <CustomScroll
        ancestorRef={ancestorRef.current}
        childrenRef={childrenRef.current}
        scrollLength={100}
        setTranslate={setTranslateX}
      />
    </div>
  );
}

Then, add to parent element overflow: hidden and width: max-content to children

.parentWrapper {
  overflow: hidden;
}
.childrenWrapper {
  width: max-content;
}

Default direction is horizontal. To change this, use direction="vertical" prop. There is no need to change anything else.

Congratulations🥳! You got a beautiful custom scroll with default styles🌟🎨

Default scroll

Explanation

You need to import useScrollSetup hook, adding <Parent_HTML_Element_Type, Children_HTML_Element_Type> to generic (just skip this in pure javascript). Then, import <CustomScroll/> component.

❗️Error

You can place <CustomScroll/> wherever you want, but not inside childrenRef element. Otherwise, you'll end up with endlessly growing recursive errors in the browser console

useScrollSetup returns 4 variables. Hang ancestorRef on your parent element, childrenRef - on scrollable child. translate you must add as

style={{
  transform: `translateX(${translateX}px)`,
}}

to your childrenWrapper.

You need add width: max-content to your childrenRef element because it should be equal to the width of scrollable content

<CustomScroll/> accepts 4 required props - ancestorRef, childrenRef, scrollLength and setTranslate.

ancestorRef, childrenRef and setTranslate are used for under-the-hood logic and must be used as specified.

Sensitivity

Sensitivity is indicated by only one parameter - an essential property scrollLength. It's defined in pixels, and literally mean the length of scroll.

👍Success

Setting scrollLength prop, scrolling speed and sensitivity will adjust to the length automatically

Default behaviour

By default, scroll works like this:

  • Enabled scrolls: wheel, drag, drag the scroll by pressing the left mouse button, swipe in mobile devices. You can disable dragging by drag prop. Other mechanics сan't be disabled
  • Scroll is always visible, you can change this by visible prop
  • cursor: grab on children element, and grabbing while you grab
    • You can safely set any cursor value on childrenElement or inner elements, and it'll work correctly. For example, set cursor: pointer to <Card/> element. Then, between <Card/>s cursor'll be grab, and while dragging cursor'll be grabbing even over <Card/>. You can change this behaviour by drag prop
  • Default scroll styles is like in Styles API Reference. You can change this by styles prop
  • direction="horizontal"

Full customization

<CustomScroll/> can accept option prop children. For example, let's replace our boring scroll to porsche

<CustomScroll
  ancestorRef={ancestorRef.current}
  childrenRef={childrenRef.current}
  scrollLength={276}
  setTranslate={setTranslateX}
  styles={{
    wrapper: {
      transform: "translateY(-40px)", // Unnecessary, added for beauty
    },
  }}
>
  <Image src={PorscheImg} alt="" />
</CustomScroll>

Porsche scroll

You can add any layout as children as you want.

🚧Warning

You still need to pass the required scrollLength prop, and its width must match your layout to work correctly

API

<CustomScroll/>

Props

ancestorRef

ancestorRef prop is taken from useCustomScroll hook and used in under-the-hood logic for binding parentEl to scroll. Must be used only as specified.

childrenRef

childrenRef prop is taken from useCustomScroll hook and used in under-the-hood logic for binding childrenEl to scroll. Must be used only as specified.

setTranslate

setTranslate prop is taken from useCustomScroll hook and used as a callback function for translate updating. Must be used only as specified.

scrollLength

Accepts value in pixels and adjust sensitivity. See Sensitivity section.

direction

Accepts 'horizontal' | 'vertical'. Default is horizontal

visible

Accepts 'visible' | 'onHover' | 'none'. Defaults to visible

  • visible. Scroll is always visible
  • onHover.
    • Desktop. Scroll visible only while hovering on children element
    • Mobile. Scroll visible on touchstart event, while scrolling and disappear after 1 second afrer scroll ending
  • none. Scroll is always invisible, but all mechanics are working

drag

drag prop have a type

type dragType = {
  draggable: boolean;
  showGrabCursor?: boolean;
};

draggable: you can disable draggable mechanic. Default to true.

showGrabCursor: default to true. You can disable cursor: grab while hovering on childrenEl. But, while dragging, cursor: grabbing will still be active.

styles

styles prop have a type

type stylesType = {
  wrapper?: CSSProperties;
  scroll?: CSSProperties;
};

The markup of scroll looks simplistically like this

<>
  <div className={classes.wrapper}>
    <div className={classes.scroll}></div>
  </div>
</>

<div> with scroll class is scroll element itself. <div> with wrapper class is a scroll wrapper, the element within which the scroll moves, and you can freely adjust it.

You can add all styles as you want to this objects.

Default styles

background: transparent for wrapper and

.scroll {
  border-radius: 4px;
  background: #b3b3b3;
  height: 4px;
  width: 4px;
}

for scroll.

children

See Full customization section.

useCustomScroll hook

useCustomScroll hook must take generic - <Parent_HTML_Element_Type, Children_HTML_Element_Type>. In example in Basic usage section it's <HTMLDivElement, HTMLDivElement>

It returns following variables:

ancestorRef

See <CustomScroll/> API section

childrenRef

See <CustomScroll/> API section

translate

translate is reactive (useState) value that used to update transform property on children element, by which scroll effect created. Its updating is completely controlled by the built-in logic, and it should be used only as specified, and in no other way.

Usage

<div
  className={classes.childrenWrapper}
  ref={childrenRef}
  style={{
    transform: `translateX(${translateX}px)`,
  }}
>
  ...
</div>

setTranslate

See <CustomScroll/> API section