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

@hewarge/calendar-core

v1.0.0

Published

Hewarge multi-calendar core with Gregorian database-safe output and a framework-free modal date-picker API.

Readme

@hewarge/calendar-core

A framework-free multi-calendar date engine with an embeddable RTL modal date picker.

Hewarge is designed to be used as a library, not as a standalone date-picker page. You connect it to one or more <input> elements and the picker opens as a modal when the user focuses or clicks an input.

Features

  • Gregorian, Jalali, Kurdish and Hijri calendar support
  • Calendar conversion through a shared JDN-based core
  • Immutable DateValue API
  • Date arithmetic and comparisons
  • Framework-free modal date picker
  • RTL Kurdish-first UI
  • Empty inputs open on today's date
  • Manual year/month/day editing
  • Today button writes today's date and closes the modal
  • Per-input past/future date restrictions
  • Explicit minDate / maxDate boundaries
  • Responsive desktop modal and mobile bottom-sheet behavior
  • Backdrop, close button and Escape dismissal
  • Keyboard focus trapping
  • No runtime dependencies
  • Node built-in test runner; Vitest is not required

Requirements

  • Node.js 18+ for the package development/test environment
  • A modern browser for the date-picker UI

The published package has no runtime npm dependencies.

Install

npm install @hewarge/calendar-core

Quick start: Date Picker

HTML:

<input
  id="birthDate"
  type="text"
  placeholder="بەروار هەڵبژێرە"
  autocomplete="off"
>

JavaScript:

import { createDatePicker } from '@hewarge/calendar-core/picker';
import '@hewarge/calendar-core/picker/css';

const input = document.querySelector('#birthDate');

const picker = createDatePicker(input, {
  calendar: 'kurdish',
  format: 'YYYY/MM/DD'
});

input.addEventListener('hewarge:change', (event) => {
  console.log(event.detail.date);
  console.log(event.detail.gregorian);
});

The picker is attached to the input. It does not navigate to another page.

Auto-attach multiple inputs

<input
  data-hewarge-datepicker
  data-calendar="kurdish"
  data-format="YYYY/MM/DD"
>

<input
  data-hewarge-datepicker
  data-calendar="gregorian"
  data-format="YYYY-MM-DD"
>
import { attachDatePickers } from '@hewarge/calendar-core/picker';
import '@hewarge/calendar-core/picker/css';

attachDatePickers(document);

Date restrictions

Each input can have its own allowed range.

Only past dates

createDatePicker(input, {
  calendar: 'kurdish',
  direction: 'past',
  pastMonths: 6
});

Only future dates

createDatePicker(input, {
  calendar: 'kurdish',
  direction: 'future',
  futureYears: 2
});

Exact boundaries

createDatePicker(input, {
  calendar: 'kurdish',
  minDate: { year: 2726, month: 1, day: 1 },
  maxDate: { year: 2727, month: 12, day: 29 }
});

direction accepts both, past, or future.

Date Picker options

| Option | Type | Default | Description | |---|---|---:|---| | calendar | string | kurdish | Calendar used by the input/picker | | locale | string | ku | UI locale identifier | | format | string | YYYY/MM/DD | Input display format | | weekStart | number | 6 | First weekday index: 0=Sunday … 6=Saturday | | closeOnSelect | boolean | true | Close after selecting a day | | clearable | boolean | true | Show Clear action | | todayButton | boolean | true | Show Today action | | keyboard | boolean | true | Enable input keyboard handling | | inputValue | boolean | true | Write selected value into the input | | direction | both \| past \| future | both | Allowed side of today | | pastYears | number | null | null | Past range in years | | futureYears | number | null | null | Future range in years | | pastMonths | number | null | null | Past range in months | | futureMonths | number | null | null | Future range in months | | minDate | object | null | null | Explicit minimum {year,month,day} | | maxDate | object | null | null | Explicit maximum {year,month,day} |

Explicit minDate and maxDate are interpreted in the configured calendar.

HTML data attributes

The auto-attach API maps options to data-* attributes. For example:

<input
  data-hewarge-datepicker
  data-calendar="kurdish"
  data-format="YYYY/MM/DD"
  data-direction="future"
  data-future-years="1"
>

Events

hewarge:change

Fired after a valid date is selected or the Today action is used.

input.addEventListener('hewarge:change', (event) => {
  const detail = event.detail;

  console.log(detail.calendar);
  console.log(detail.date);
  console.log(detail.gregorian);
  console.log(detail.jalali);
  console.log(detail.kurdish);
  console.log(detail.hijri);
});

hewarge:clear

Fired when the user clears the input.

input.addEventListener('hewarge:clear', (event) => {
  console.log(event.detail.calendar);
});

Date Core API

import { HewargeDate } from '@hewarge/calendar-core';

const date = HewargeDate.fromGregorian(2026, 9, 7);

console.log(date.toKurdish());
// { year: 2726, month: 6, day: 16 }

console.log(date.toJalali());
// { year: 1405, month: 6, day: 16 }

Create dates

HewargeDate.from('kurdish', 2726, 6, 16);
HewargeDate.fromGregorian(2026, 9, 7);
HewargeDate.fromJalali(1405, 6, 16);
HewargeDate.fromKurdish(2726, 6, 16);
HewargeDate.fromHijri(1448, 3, 24);
HewargeDate.today();

Convert

const date = HewargeDate.fromGregorian(2026, 9, 7);

const kurdish = date.convert('kurdish');
const jalali = date.convert('jalali');
const hijri = date.convert('hijri');

Date operations

All operations return a new immutable date value.

date.add({ days: 10 });
date.add({ weeks: 2 });
date.add({ months: 1 });
date.add({ years: 1 });
date.subtract({ days: 3 });

date.isBefore(other);
date.isAfter(other);
date.isSame(other);
date.equals(other);

date.startOf('month');
date.endOf('month');
date.startOf('year');
date.endOf('year');

Date metadata

date.dayOfWeek;
date.dayOfYear;
date.daysInMonth;
date.isLeapYear;
date.toJdn();

Calendar IDs

kurdish
gregorian
jalali
hijri

Package exports

@hewarge/calendar-core
@hewarge/calendar-core/picker
@hewarge/calendar-core/picker/css

The core export contains the calendar/date API. The picker export contains the embeddable modal UI API. The CSS export contains the picker styles.

Testing

This project uses Node's built-in test runner, so Vitest is not required to run the package tests.

npm test

Local demo

npm run dev

Then open:

http://localhost:5177

Publishing

Before the first publish:

npm login
npm whoami
npm pack --dry-run
npm publish --access public

@hewarge/calendar-core is a scoped package. Scoped public packages need --access public on their initial direct publish. See docs/PUBLISHING.md for the complete checklist.

License

MIT

Database-safe Gregorian output

The Date Picker separates display value from storage value. The selected calendar controls what the user sees in the visible input, while the canonical value exposed to the application is always Gregorian YYYY-MM-DD.

For example, with the Kurdish calendar:

Visible input: 16/6/2726
Storage/API:   2026-09-07

The change event exposes both values:

input.addEventListener('hewarge:change', (event) => {
  console.log(event.detail.value);        // 16/6/2726
  console.log(event.detail.storageValue);  // 2026-09-07
  console.log(event.detail.gregorianValue); // 2026-09-07
  console.log(event.detail.kurdish.year);  // 2726
});

For direct form submission, use a hidden storage input:

<input id="birth-display" data-hewarge-datepicker name="birth_display">
<input id="birth-storage" type="hidden" name="birth_date">
createDatePicker(document.querySelector('#birth-display'), {
  calendar: 'kurdish',
  storageInput: '#birth-storage'
});

The hidden field receives 2026-09-07, while the visible input keeps the Kurdish date. You can also use storageName: 'birth_date' to let the picker create the hidden field automatically, or autoStorage: true when the visible input already has a name.

Mobile Wheel Date Picker

On screens up to 600px, the default UI becomes a touch-first bottom-sheet Wheel Date Picker with separate year, month and day wheels. The desktop UI remains a calendar/grid picker.

You can force a mode with:

createDatePicker(input, {
  calendar: 'kurdish',
  mobileMode: 'wheel'
});

Available values are auto, wheel, and calendar.

Converting a Gregorian database value

If a database returns 2026-09-07, pass it directly to the dedicated conversion function you need:

import {
  gregorianToKurdish,
  gregorianToJalali,
  gregorianToHijri
} from '@hewarge/calendar-core';

const dbDate = '2026-09-07';

const kurdish = gregorianToKurdish(dbDate);
const jalali = gregorianToJalali(dbDate);
const hijri = gregorianToHijri(dbDate);

console.log(kurdish.year);        // 2726
console.log(kurdish.month);       // 6
console.log(kurdish.day);         // 16
console.log(kurdish.dayMonthYear); // 16/6/2726

Each conversion result contains both separate fields and ready-to-use strings:

result.year
result.month
result.day
result.yearMonthDay
result.yearMonthDayPadded
result.dayMonthYear
result.dayMonthYearPadded

The conversion helpers also accept a JavaScript Date or { year, month, day } Gregorian object.

Hijri conversion in this package is the implemented arithmetic/civil Hijri algorithm. It should not be treated as a local moon-sighting declaration.