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

trpicker

v1.1.2

Published

基于 SVG 的圆形时间范围选择器,支持 24/12 小时制

Readme

trPicker — Circular Time Range Picker

English | 简体中文

Version: 1.1.2

An SVG-based circular time-range picker supporting 24-hour / 12-hour modes. Select a time range by dragging the handles.

Live Demo npm version npm downloads License: MIT

Picker popup


Quick start

Install

npm install trpicker

ES Module

import trPicker from 'trpicker';

const picker = new trPicker(document.getElementById('picker'), {
    hourCycle: 24,
    startMinute: 0,
    endMinute: 360,          // 06:00
    stepMinute: 10,
});

CommonJS

const trPicker = require('trpicker');

const picker = new trPicker(document.getElementById('picker'), {
    hourCycle: 24,
});

Browser <script> / CDN

The IIFE bundle exposes the global trPicker:

<!-- CDN (unpkg / jsdelivr) -->
<script src="https://unpkg.com/trpicker/dist/trpicker.iife.js"></script>
<!-- or -->
<script src="https://cdn.jsdelivr.net/npm/trpicker/dist/trpicker.iife.js"></script>
<!-- or locally -->
<script src="node_modules/trpicker/dist/trpicker.iife.js"></script>

<!-- 2. Container -->
<div id="picker" style="width:320px;height:320px;"></div>

<script>
const picker = new trPicker(document.getElementById('picker'), {
    hourCycle: 24,
    startMinute: 0,
    endMinute: 360,          // 06:00
    stepMinute: 10,
    onChange: (start, end) => {
        const fmt = m => `${String(Math.floor(m/60)).padStart(2,'0')}:${String(m%60).padStart(2,'0')}`;
        console.log(fmt(start), '-', fmt(end));
    },
});
</script>

Popup mode

<input type="text" id="trigger" readonly placeholder="Select a time range">

<script>
const picker = new trPicker(document.getElementById('trigger'), {
    hourCycle: 24,
    popup: true,
    onChange: (start, end) => {
        const fmt = m => `${String(Math.floor(m/60)).padStart(2,'0')}:${String(m%60).padStart(2,'0')}`;
        document.getElementById('trigger').value = `${fmt(start)} - ${fmt(end)}`;
    },
});
</script>

The popup panel is positioned directly below the trigger input by default, with a 4px gap. If the viewport does not leave enough space below, it automatically flips to appear above the input.

popupOffset (default 4) is a global appearance constant, not a constructor option. Adjust it before creating the picker: trPicker.APPEARANCE.popup.offset = 8;


Configuration options

| Option | Type | Default | Description | |--------|------|---------|-------------| | hourCycle | 12 \| 24 | 24 | Hour cycle | | startMinute | number | 0 | Initial start minute 0–1439 | | endMinute | number | 360 | Initial end minute 0–1439 | | startHour | number | — | Initial start hour (float, replaces startMinute) | | endHour | number | — | Initial end hour (float, replaces endMinute) | | stepMinute | number | 10 | Snap step (minutes) | | startColor | string | '#4f46e5' | Start handle color | | endColor | string | '#ef4444' | End handle color | | lineColor | string | '#28a050' | Arc color; 'gradient' for a gradient | | detailLevel | 'simple' \| 'detailed' | 'simple' | Dial tick detail level | | dialStyle | 'solid' \| 'metal' | 'solid' | Dial material style | | popup | boolean | false | Use popup mode | | popupAnimation | 'fade' \| 'drop' \| 'instant' | 'fade' | Popup animation | | popupBorderRadius | number | 16 | Popup panel corner radius (px) | | enableFineSlider | boolean | true | Show the fine slider | | enableModeSwitch | boolean | true | Show the 12/24H toggle in the UI | | enableStepAdjust | boolean | true | Show the step selector in the UI | | enableDetailAdjust | boolean | true | Show the detail toggle in the UI | | enableMinStep | boolean | true | Enforce a minimum interval >= stepMinute | | amText | string | 'AM' | AM label (12H) | | pmText | string | 'PM' | PM label (12H) | | onChange | fn(start, end) | — | Time change callback |


API

Methods

| Method | Description | |--------|-------------| | setStep(minute) | Change the snap step | | setStartColor(color) | Set the start color | | setEndColor(color) | Set the end color | | setLineColor(color) | Set the arc color; 'gradient' for a gradient | | setDetailLevel('simple'\|'detailed') | Switch the tick detail level | | setDialStyle('solid'\|'metal') | Switch the dial style | | setHourCycle(12\|24) | Switch the hour cycle | | getDateTimeValues(baseDate?) | Returns { startDay, endDay, durationMin } | | open() | Open the popup panel | | close() | Close the popup panel | | toggle() | Toggle the popup panel | | destroy() | Destroy the component and release resources |

Properties

| Property | Type | Description | |----------|------|-------------| | startMinute | number | Current start minute 0–1439 | | endMinute | number | Current end minute 0–1439 | | hourCycle | number | Current cycle 12 / 24 |


Styling

CSS class names are prefixed with trpicker-; override them to customize the appearance.

| Class | Purpose | |-------|---------| | .trpicker-popup | Popup panel container | | .trpicker-overlay | Popup overlay | | .trpicker-fine-slider | Fine slider | | .trpicker-hour | Dial numbers (defaults built-in as SVG attributes; override if needed) | | .trigger-input | Trigger input (defined by the consumer) |

The component does not touch the consumer's display styles. Format and update the UI yourself in the onChange callback.


Browser support

  • Modern browsers (Chrome, Firefox, Safari, Edge)
  • Requires SVG, Pointer Events, and Touch Events
  • IE 11 and below are not supported