Getting started
Taqwim is a set of packages, not one. Pick the pair that matches your framework: a headless package for behaviour and accessibility, and a styled package if you want it to look like a calendar out of the box.
This is the real component from the real package — the same one the code below installs. The buttons above the page switch every example on it, this one included.
nothing yet Tab into the grid, then use the arrow keys, Home/End, PageUp/PageDown (with Shift for years) and Enter to select. Under dir="rtl" the horizontal keys mirror.
nothing yetTab into the grid, then use the arrow keys, Home/End, PageUp/PageDown (with Shift for years) and Enter to select. Under dir="rtl" the horizontal keys mirror.
nothing yetTab into the grid, then use the arrow keys, Home/End, PageUp/PageDown (with Shift for years) and Enter to select. Under dir="rtl" the horizontal keys mirror.
nothing yetTab into the grid, then use the arrow keys, Home/End, PageUp/PageDown (with Shift for years) and Enter to select. Under dir="rtl" the horizontal keys mirror.
No live Angular island here. @analogjs/vite-plugin-angular does not compile an Angular app under Vite 8, which is the same gap that keeps Angular out of the default end-to-end run.
The adapter itself is built and type-checked by ngc with strictTemplates on every change, and playground/angular runs with pnpm --filter taqwim-playground-angular dev.
Install
Section titled “Install”pnpm add @taqwim/vue-styled@alphapnpm add @taqwim/react-styled@alphapnpm add @taqwim/svelte-styled@alphapnpm add @taqwim/solid-styled@alphapnpm add @taqwim/angular-styled@alphaEach styled package pulls in its headless sibling and @taqwim/themes, so that
is the only dependency you need to add.
Render a calendar
Section titled “Render a calendar”<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>import { HijriCalendar } from '@taqwim/react-styled'import { useState } from 'react'
export function Example() { const [date, setDate] = useState()
return <HijriCalendar value={date} onValueChange={setDate} theme="islamic" locale="ar" dir="rtl" />}<script lang="ts"> import { HijriCalendar } from '@taqwim/svelte-styled'
let date = $state()</script>
<HijriCalendar value={date} onValueChange={next => (date = next)} theme="islamic" locale="ar" dir="rtl" />import { HijriCalendar } from '@taqwim/solid-styled'import { createSignal } from 'solid-js'
export function Example() { const [date, setDate] = createSignal()
return <HijriCalendar value={date()} onValueChange={setDate} theme="islamic" locale="ar" dir="rtl" />}import { HijriCalendar } from '@taqwim/angular-styled'import { Component, signal } from '@angular/core'
@Component({ standalone: true, imports: [HijriCalendar], template: ` <taqwim-hijri-calendar [value]="date()" (valueChange)="date.set($event)" theme="islamic" locale="ar" dir="rtl" /> `,})export class Example { readonly date = signal(undefined)}The date picker
Section titled “The date picker”HijriDatePicker is the same calendar behind a text input. It is single-select
by design: the input holds one formatted date.
nothing yet With editable on, the input accepts 1446-09-01 or 01/09/1446. Text it cannot parse reverts to the last good value rather than clearing the selection. The trigger is a combobox: Enter opens the popup, Escape closes it and returns focus.
nothing yetWith editable on, the input accepts 1446-09-01 or 01/09/1446. Text it cannot parse reverts to the last good value rather than clearing the selection. The trigger is a combobox: Enter opens the popup, Escape closes it and returns focus.
nothing yetWith editable on, the input accepts 1446-09-01 or 01/09/1446. Text it cannot
parse reverts to the last good value rather than clearing the selection. The trigger is a combobox: Enter opens the popup, Escape closes it and returns focus.
nothing yetWith editable on, the input accepts 1446-09-01 or 01/09/1446. Text it cannot parse reverts to the last good value rather than clearing the selection. The trigger is a combobox: Enter opens the popup, Escape closes it and returns focus.
No live Angular island here — @analogjs/vite-plugin-angular does not compile an Angular app under Vite 8. Run playground/angular locally to try<taqwim-hijri-datepicker>.
Just the date maths
Section titled “Just the date maths”If you only need conversion and arithmetic — on a server, say — @taqwim/core
has no framework dependency and no DOM.
pnpm add @taqwim/core@alphaimport { toHijri, toGregorian, addHijriMonths, formatHijriDate } from '@taqwim/core'
const today = toHijri(new Date()) // { hy: 1447, hm: 2, hd: 14 }const later = addHijriMonths(today, 3)
formatHijriDate(later, 'iD iMMMM iYYYY', 'ar')toGregorian(later) // a Date at local midnightConversion covers 1343–1500 AH (1924–2077 CE), the range the Umm al-Qura
table defines. Outside it, Taqwim throws HijriRangeError rather than returning
a quietly wrong date.
Dates without a calendar covers the rest of that package: arithmetic, business days, comparison, parsing and locale-aware formatting.
Build your own markup
Section titled “Build your own markup”The styled packages are composed entirely from public headless parts. When you need different markup, drop to those — see your framework’s page under Frameworks for the full compound surface.