Skip to content
bahtuiv0.18.8

<baht-calendar>

A read-only calendar, Outlook- and Teams-style: month, week and day views of events, with holidays and freezes (marks) shaded. It never edits anything: a click on an event fires baht-event-open, and moving to another day or view fires baht-navigate with the days now shown, so the host fetches what to draw. calendarRange(view, date) gives the same days for the first fetch. Overlapping events sit side by side; a month cell shows three, then “+N more”.

Work calendar

<baht-calendar date="2026-11-11" label="Work calendar"></baht-calendar>

<script>
  const el = document.querySelector('baht-calendar');
  el.events = [
    {
      "id": "a",
      "title": "Approve CHG-6",
      "start": "2026-11-11T02:00:00Z",
      "end": "2026-11-11T03:00:00Z",
      "tone": "primary",
      "meta": "From Bank"
    },
    {
      "id": "b",
      "title": "Deploy · Core banking",
      "start": "2026-11-11T02:30:00Z",
      "end": "2026-11-11T05:00:00Z",
      "tone": "carbon",
      "meta": "APPSVR01"
    },
    {
      "id": "c",
      "title": "Due · SCR-1",
      "start": "2026-11-12T08:00:00Z",
      "tone": "danger",
      "outline": true
    },
    {
      "id": "d",
      "title": "Offsite",
      "start": "2026-11-13",
      "allDay": true
    }
  ];
  el.marks = [
    {
      "date": "2026-11-13",
      "label": "Bank holiday",
      "kind": "off"
    },
    {
      "date": "2026-11-14",
      "label": "Month-end freeze",
      "kind": "freeze"
    }
  ];
</script>
import { calendarRange } from 'bank20baht-ui';
const cal = document.querySelector('baht-calendar');
const load = async ({ from, to }) => {
cal.events = await fetchEvents(from, to); // [{ id, title, start, end?, allDay?, tone?, meta?, outline?, done? }]
cal.marks = await fetchHolidays(from, to); // [{ date, label, kind: 'off' | 'freeze' }]
};
load(calendarRange(cal.view, cal.date));
cal.addEventListener('baht-navigate', (e) => load(e.detail));
cal.addEventListener('baht-event-open', (e) => openRecord(e.detail.id));

start is an ISO instant, or YYYY-MM-DD for an all-day event, whose end is its last day (included). An event with no end is a point (a deadline), drawn half an hour long. tone is one of primary, carbon, neutral, warning, danger, success; outline draws it dashed.

NameTypeDefaultDescription
viewCalendarView'week'month, week or day
datestring''A day the view shows, YYYY-MM-DD; empty for today
eventsJSCalendarEvent[][]{ id, title, start, end?, allDay?, tone?, meta?, outline?, done? }
marksJSCalendarMark[][]Days to shade: { date, label, kind: 'off' | 'freeze' }
labelstring''Accessible name
todaystring''Today, YYYY-MM-DD; empty for the real today
week-startnumber11 Monday, 0 Sunday
localestring'en-GB'Locale for day and month names
first-hournumber7.5Hour the time grid opens scrolled to
EventdetailDescription
baht-event-open{ id, event }An event was clicked
baht-navigate{ view, date, from, to }The view or the days shown changed
nameCustomEvent