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 🙏

© 2026 – Pkg Stats / Ryan Hefner

react-wheel-scroller

v0.1.10

Published

React wheel-scroller pickers: calendar, datetime, range and select.

Readme

react-wheel-scroller

npm version bundle size downloads types license

Touch-friendly wheel-scroller pickers for React — date, time, datetime, calendar, date-range, and select. Spinner-style controls you drop into forms, filters, or mobile bottom-sheets, with per-component subpaths so you only bundle the picker you use.

Features

  • Six pickers, one library. WsSelect, WsDate, WsTime, WsDatetime, WsCalendar, and WsRange (start/end) cover most date/time and list-selection needs.
  • Import only what you use. Per-component subpaths (/calendar, /datetime, /range, /select) keep bundles tight; sideEffects is scoped to presets and styles so tree-shaking stays effective.
  • Inline or overlay. display renders a picker inline, as a bottom sheet, bubble, centered modal, or top bar — the same component, positioned to fit.
  • Desktop & touch. touchUi toggles the touch-optimized layout; mouse-wheel and drag both work.
  • Controlled or uncontrolled. Use value/defaultValue with onChange/onSet, or drive it imperatively through the instance API (getVal() / setVal()).
  • Rich select. Single, multiple, or N-of, with grouping, live filtering, counters, and local or remote (url) data sources.
  • Theming & i18n. themeVariant (auto / light / dark), custom theme, rtl, and per-label text props for full localization.
  • Dual ESM + CJS, full TypeScript types. Ships .d.ts for every entry point plus a precompiled stylesheet — no build-time Sass required.
  • React 18 & 19 compatible. react >= 18 peer dependency.

Install

npm add react-wheel-scroller
# or: pnpm add react-wheel-scroller / yarn add react-wheel-scroller

react >= 18 is a peer dependency. Import the stylesheet once at your app root:

import 'react-wheel-scroller/styles.css';

Quickstart

import { WsSelect } from 'react-wheel-scroller/select';
import 'react-wheel-scroller/styles.css';

export function PriorityPicker() {
  return (
    <WsSelect
      data={['Low', 'Medium', 'High']}
      value="Medium"
      onSet={(_event, inst) => console.log(inst.getVal())}
    />
  );
}

Import a component from its subpath for the tightest bundle; import styles.css once, anywhere above your pickers.

Entry points

| Import | Exports | | --- | --- | | react-wheel-scroller | WsCalendar, WsDatetime, WsDate, WsTime, WsRange, WsRangeStart, WsRangeEnd, WsSelect + prop types | | react-wheel-scroller/calendar | WsCalendar | | react-wheel-scroller/datetime | WsDatetime, WsDate, WsTime | | react-wheel-scroller/range | WsRange, WsRangeStart, WsRangeEnd | | react-wheel-scroller/select | WsSelect | | react-wheel-scroller/styles.css | precompiled stylesheet (import once) |

Components

import { WsSelect } from 'react-wheel-scroller/select';

// Simple string list
<WsSelect data={['Low', 'Medium', 'High']} value="Medium" />

// Objects, grouped, multi-select, filterable, with a selection counter
<WsSelect
  data={[
    { text: 'Alice', value: 1, group: 'Team A' },
    { text: 'Bob',   value: 2, group: 'Team B' },
  ]}
  dataText="text"
  dataValue="value"
  dataGroup="group"
  group
  select="multiple"
  filter
  counter
  onSet={(_event, inst) => console.log(inst.getVal())}
/>

// Remote data source
<WsSelect
  data={{ url: '/api/users', dataType: 'json', remoteFilter: true }}
  dataText="name"
  dataValue="id"
  filter
/>

select accepts 'single', 'multiple', or a number (N-of). Provide options as a string/object array via data, as <option> children, or from a remote url.

import { useState } from 'react';
import { WsDate, WsTime, WsDatetime } from 'react-wheel-scroller/datetime';

function BirthdayField() {
  const [date, setDate] = useState<Date>();
  return (
    <WsDate
      value={date}
      min={new Date(2000, 0, 1)}
      max={new Date()}
      returnFormat="jsdate"
      onSet={(_event, inst) => setDate(inst.getVal())}
    />
  );
}

// 5-minute time steps, 24h format
<WsTime steps={{ minute: 5 }} timeFormat="HH:ii" />

// Combined date + time as a bottom sheet on touch devices
<WsDatetime
  dateFormat="YYYY-MM-DD"
  timeFormat="HH:ii"
  display="bottom"
  touchUi
/>

returnFormat controls the value shape read back from getVal(): 'jsdate', 'iso8601', 'locale', or 'moment'. Bound the range with min / max.

import { WsCalendar } from 'react-wheel-scroller/calendar';

// Inline single-date grid
<WsCalendar
  controls={['calendar']}
  display="inline"
  firstDay={1}
  onSetDate={(_event, inst) => console.log(inst.getVal())}
/>

// Multi-select with marked days
<WsCalendar
  controls={['calendar']}
  select="multiple"
  marked={[new Date(2026, 6, 4), new Date(2026, 6, 15)]}
/>

// Date + time in one picker
<WsCalendar controls={['calendar', 'time']} />

controls composes the picker from 'calendar', 'date', and 'time'. select takes 'single', 'multiple', or a number; selectType switches between 'day' and 'week' selection.

import { WsRange, WsRangeStart, WsRangeEnd } from 'react-wheel-scroller/range';

// Two labelled inputs, opens as a bottom sheet
<WsRange controls={['calendar']} display="bottom" fromText="Check in" toText="Check out">
  <WsRangeStart placeholder="From" />
  <WsRangeEnd placeholder="To" />
</WsRange>

// Single input, inline, with a min/max span
<WsRange controls={['calendar']} display="inline" minRange={1} maxRange={30} />

Nest WsRangeStart / WsRangeEnd to bind two of your own inputs; omit them and WsRange renders (or adopts) a single input. minRange / maxRange constrain the selectable span.

Styling

The package ships a precompiled stylesheet — import it once at your app root:

import 'react-wheel-scroller/styles.css';

Adjust the color scheme per-picker with themeVariant ('auto' follows the OS), a custom theme, or rtl for right-to-left layouts.

Common props

Shared across the pickers (each component adds its own on top):

| Prop | Type | Purpose | | --- | --- | --- | | value / defaultValue | picker-specific | controlled / initial value | | onChange | (event, inst) => void | fires while the wheel moves | | onSet | (event, inst) => void | fires on confirm — read inst.getVal() | | display | 'inline' \| 'bottom' \| 'center' \| 'top' \| 'bubble' | placement / presentation | | touchUi | boolean | touch-optimized UI | | themeVariant | 'auto' \| 'light' \| 'dark' | color scheme | | disabled / readOnly | boolean | interaction state | | min / max | Date \| string \| number | date/time bounds | | returnFormat | 'iso8601' \| 'jsdate' \| 'locale' \| 'moment' | value shape from getVal() |

Full type definitions ship with the package (.d.ts per entry point).

Scripts

  • pnpm build — dual ESM+CJS + .d.ts (tsup) and dist/wheel-select.css (sass)
  • pnpm typecheck / pnpm lint / pnpm test

Support

If react-wheel-scroller saves you time, consider sponsoring continued maintenance:

GitHub Sponsors monobank Jar

Even a one-time tip is appreciated — it pays for issue triage, version bumps, and the next feature.

License

MIT © Nazarii Kovtun