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

@agencecinq/calendar

v1.0.0

Published

Accessible date / range picker as a lightweight Web Component.

Readme

@agencecinq/calendar

Accessible date / range picker as a lightweight Web Component (<cinq-calendar>).

Markup and CSS are yours — the package fills the grid and handles selection. Aligned with the WAI-ARIA Authoring Practices date picker grid.

Inspired by @19h47/calendar.

Installation

pnpm add @agencecinq/calendar

Markup

Required hooks:

| Selector | Role | | -------- | ---- | | <cinq-calendar> | Host element | | .js-previous / .js-next | Month navigation (optional) | | .js-title | Month / year label; click advances to the next month (same as .js-next) | | .js-days | Weekday headers row | | .js-body | Day cells | | .js-day | Day button (generated) |

<cinq-calendar locale="fr" deselect>
  <header>
    <button type="button" class="js-previous" aria-label="Previous month">Previous</button>
    <button type="button" class="js-title" id="calendar-label" aria-live="polite"></button>
    <button type="button" class="js-next" aria-label="Next month">Next</button>
  </header>
  <table role="grid" aria-labelledby="calendar-label">
    <thead>
      <tr class="js-days"></tr>
    </thead>
    <tbody class="js-body"></tbody>
  </table>
</cinq-calendar>

Usage

import "@agencecinq/calendar";
import { EVENTS } from "@agencecinq/utils";

const el = document.querySelector("cinq-calendar");

el.addEventListener(EVENTS.CALENDAR_CHANGE, ({ detail }) => {
  // detail.values → string[] (`YYYY-MM-DD`)
  console.log(detail.values);
});

Importing the package registers the custom element. The calendar mounts on connectedCallback — no manual init() is required.

HTML is the source of truth. Provide role="grid", aria-labelledby, aria-live on the title, and aria-label on nav buttons yourself.

Single date

<cinq-calendar single deselect>…</cinq-calendar>

Date range

<cinq-calendar single="false">…</cinq-calendar>

Locale & week start

locale drives labels via Intl. Week start defaults from the locale (weekInfo); pass first-day to override.

<cinq-calendar locale="fr">…</cinq-calendar>
<!-- fr → week starts Monday -->

<cinq-calendar locale="en" first-day="1">…</cinq-calendar>
<!-- force Monday despite en -->

Update at runtime:

import { getWeekStart } from "@agencecinq/calendar";

el.options.locale = "ja";
el.options.firstDay = getWeekStart("ja");
el.render();

Custom labels

el.options.days = ["Dim", "Lun", "Mar", "Mer", "Jeu", "Ven", "Sam"];
el.options.months = [
  "Janvier", "Février", "Mars", "Avril", "Mai", "Juin",
  "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre",
];
el.render();

Cell hook

Override renderInner to enrich or rebuild each day cell. Keep .js-day and data-day.

el.renderInner = (inner, date) => {
  const button = inner.querySelector(".js-day");
  if (!button) return;

  button.classList.add("MyDay");
  button.innerHTML = `<time datetime="${date.toISOString().slice(0, 10)}">${date.getDate()}</time>`;
};

Attributes

| Attribute | Description | | --------- | ----------- | | locale / data-locale | BCP 47 locale for title and weekday/month labels | | single | Single date (true, default) vs range (false) | | deselect | Allow clearing the selection in single mode | | allow-past | Allow selecting past dates | | first-day | Week start (0=Sun … 6=Sat); defaults from locale | | button-class | Extra classes on day buttons | | name | Forwarded in calendar:change detail | | data-month | Initial month (011) | | data-year | Initial year | | data-picked-dates | JSON array of YYYY-MM-DD days to preselect |

Keyboard (focus in the grid)

| Key | Action | | --- | ------ | | Arrow keys | Move by day / week (crosses months) | | Home / End | First / last day of the week | | Page Up / Page Down | Previous / next month | | Shift + Page Up / Down | Previous / next year | | Enter / Space | Select the focused day |

Events

Dispatched on the host <cinq-calendar> (bubble). Constants live on @agencecinq/utils EVENTS:

| Event | Constant | Detail | | ----- | -------- | ------ | | calendar:change | CALENDAR_CHANGE | { values: string[], name?: string } |

API

| Method / property | Description | | ----------------- | ----------- | | options | Runtime options object | | picked | Selected days as YYYY-MM-DD | | current | Viewed { month, year, day } | | render() | Rebuild the grid | | move(deltaMonths) | Navigate by months | | destroy() | Detach listeners and clear the grid | | renderInner(inner, date) | Per-cell hook (override) |

Exported helpers: getWeekStart, toDayString, fromDayString.

Build setup

pnpm -C packages/calendar build

Acknowledgments