Skip to content
weftGitHub

YearView

Twelve small months with a dot for how busy each day was.

SourcePackage @weft-js/warp

Preview

tsx
import { YearView } from '@weft-js/warp'import type { CalEvent } from '@weft-js/warp-core'export function Deploys() {  return (    <YearView counts={DEPLOYS_BY_DAY} events={TEAM_EVENTS} label="Deploys in 2026" year={2026} today={TODAY} locale="en-GB" firstDayOfWeek={1} direct={false} />  )}const TODAY = '2026-11-03'const TEAM_EVENTS: CalEvent[] = [  { id: 'e1', title: 'Platform standup', start: '2026-11-02T09:00', end: '2026-11-02T09:15', cal: 1, recurrence: 'FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR', location: 'Room Atlas', attendees: ['Mara Lindqvist', 'Jun Tanaka'] },  { id: 'e2', title: 'Platform standup', start: '2026-11-03T09:00', end: '2026-11-03T09:15', cal: 1, recurrence: 'FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR', location: 'Room Atlas', attendees: ['Mara Lindqvist', 'Jun Tanaka'] },  { id: 'e3', title: 'Checkout review', start: '2026-11-03T10:00', end: '2026-11-03T11:00', cal: 2, video: true, attendees: ['Priya Raman', 'Tomás Oliveira', 'Mara Lindqvist'] },  { id: 'e4', title: 'Incident review: mobile-bff', start: '2026-11-03T13:00', end: '2026-11-03T13:45', cal: 4, video: true, location: 'Room Birch', attendees: ['Sam Okafor', 'Inés Vidal', 'Jun Tanaka'] },  { id: 'e5', title: 'Ranking v2 handover', start: '2026-11-03T15:00', end: '2026-11-03T16:00', cal: 3, location: 'Room Cedar', attendees: ['Lena Fischer', 'Noor Haddad'] },  { id: 'e6', title: 'Priya out of office', start: '2026-11-03', end: '2026-11-03', allDay: true, cal: 6 },  { id: 'e7', title: 'Release 2026.11', start: '2026-11-04T11:00', end: '2026-11-04T12:00', cal: 5, attendees: ['Mara Lindqvist', 'Jun Tanaka', 'Tomás Oliveira'] },  { id: 'e8', title: 'Design crit', start: '2026-11-04T14:00', end: '2026-11-04T15:00', cal: 2, tentative: true, video: true },  { id: 'e9', title: 'Cost review', start: '2026-11-05T10:00', end: '2026-11-05T11:00', cal: 1, recurrence: 'FREQ=MONTHLY', attendees: ['Mara Lindqvist', 'Lena Fischer'] },  { id: 'e10', title: 'On-call handover', start: '2026-11-06T16:00', end: '2026-11-06T16:30', cal: 1, recurrence: 'FREQ=WEEKLY', video: true },]const DEPLOYS_BY_DAY: Record<string, number> = Object.fromEntries(  Array.from({ length: 307 }, (_, i) => {    const day = new Date(Date.UTC(2026, 0, 1 + i))    const weekend = day.getUTCDay() % 6 === 0    return [day.toISOString().slice(0, 10), weekend ? (i % 5 === 0 ? 1 : 0) : 1 + ((i * 7) % 9)] as const  }).filter(([, n]) => n > 0),)

Installation

npm install @weft-js/warp

Usage

tsx
import { YearView } from '@weft-js/warp'<YearView counts={DEPLOYS_BY_DAY} events={TEAM_EVENTS} label="Deploys in 2026" year={2026} today={TODAY} locale="en-GB" firstDayOfWeek={1} direct={false} />

When to use

Use it for

  • Seeing a year at a glance
  • Jumping to a day or month

Accessibility

Arrowkeys
Move between days, across months
Enter
Opens the day
M
Opens the month
T
Goes to today
  • All twelve months share one tab stop.

API Reference

PropTypeDefaultDescription
countsRecord<string, number>—Each day's number, keyed by date.
labelstring—Names the section when the year is not enough.
eventsCalEvent[]—Events for the picked day's detail.
yearnumber—The year on show.
todaystring—Pins today's date, for server rendering and tests. The browser's clock otherwise.
localestring—The language and region used to format values.
hourCyclestring—h12 for AM and PM, h23 for a 24-hour clock. The locale's otherwise.
firstDayOfWeeknumber—The day each month's rows start on, 0 for Sunday to 6. The locale's otherwise.
openDay((iso: `${number}-${number}-${number}`) => boolean | void)—Open a day yourself. Return true when you did.
openMonth((iso: `${number}-${number}-${number}`) => boolean | void)—Open a month yourself. Return true when you did.
directbooleantrueOpens a day right away. Off, a pick shows the detail first.
EventTypeDefaultDescription
onYearChange((y: number) => void)—Called with the new year when you page.

Parts

Every element carries a stable name, so you can style it from your own CSS: [data-scope="year"] [data-part="month-title"]

month-titletoolbartitlelegenddotsmonthsyear-monthnumdetail

RelatedAgenda