All projects

Taqwim

BetaSince 2024MIT

Hijri dates, and one calendar for five frameworks.

Hijri date utilities for the Umm al-Qura, Islamic Civil and Islamic TBLA calendars, and an accessible calendar component. The calendar’s behaviour is written once as a framework-independent state machine, with bindings for Vue, React, Svelte, Solid and Angular.

Taqwim documentation home with a live Hijri calendar

The problem

The Umm al-Qura calendar uses a table of dates; arithmetic shortcuts can land on the wrong day. Building a calendar separately for each framework also duplicates selection, paging and keyboard logic.

Date conversion and formatting

ts
import { formatHijriDate, toGregorian, toHijri } from '@taqwim/core'

toHijri(new Date('2024-03-11'))
// => { hy: 1445, hm: 9, hd: 1 }

toGregorian({ hy: 1445, hm: 9, hd: 1 })
// => Mon Mar 11 2024

formatHijriDate({ hy: 1445, hm: 9, hd: 1 }, 'iYYYY/iMM/iDD', 'ar')
// => ١٤٤٥/٠٩/٠١

The default Umm al-Qura conversion is table-driven and covers 1343 to 1500 AH, 1924 to 2077 CE. Outside that range it throws a HijriRangeError instead of returning a silently wrong date. Islamic Civil and Islamic TBLA are optional strategies you import and pass explicitly, and business-day arithmetic defaults to a Friday and Saturday weekend, overridable per call.

One state machine, five frameworks

Grid building, selection, paging and keyboard navigation live in one framework-independent state machine. It also defines the data-* and aria-* attributes used by the Vue, React, Svelte, Solid and Angular bindings. A fix in this shared core can be made once for all five bindings. The end-to-end suite checks the rendered DOM.

vue
<script setup lang="ts">
import { HijriCalendar } from '@taqwim/vue-styled'
import { ref } from 'vue'

const date = ref()
</script>

<template>
  <HijriCalendar v-model="date" theme="islamic" locale="ar" dir="rtl" />
</template>

Each framework gets a headless package with the behaviour and ARIA attributes, and a styled package built from its public parts. The thirteen packages are released together under one version.

Theming

Thirty-three themes sit on a custom-property contract and are selected with data-taqwim-theme, not by importing another stylesheet. One page can host several, and switching at runtime is a state change.

Accessibility

The calendar uses role="grid" and a roving tabindex. Tab enters and leaves the grid; arrow keys move between dates, with navigation mirrored under dir="rtl". Unit tests check the bundled themes' contrast against WCAG AA thresholds, and axe checks the rendered calendar end to end.

One known gap: Angular is not yet covered by the end-to-end suite.

A closer look

Thirty-three themes, two directions

Screens of the published calendar, captured from the documentation site.

Language

Theme

Taqwim calendar, Islamic theme, English, left to right