Skip to main content

Year View

This guide covers the year view - what it shows, how to turn it on, and how to tune its layout. Use it when users need a wide-angle look at twelve months at once.

The functionality is available in PRO Edition only

PRO

year view with twelve mini-month grids in a 3 by 4 block and dot markers on busy days

12-Month Overview

The year view is one of the seven built-in views. It renders the full calendar year as twelve mini-month grids in a 3 by 4 block. Each day cell gets a marker dot when an event falls on that day.

Key rules that shape the view:

  • Range: January 1 through December 31 of the active year. Prev/next steps by 1 year, "Today" jumps to the current year.
  • Scope: read-only. Drag, resize, drag-create, and click-to-create don't work here. Switch to day, week, or month to edit.
  • Marked days: the model scans every event against every month and stores the full event reference on each day it covers. A multi-day event marks every day it spans. The interval is half-open, so an event ending at midnight on day d doesn't mark day d.
  • Today highlight: the cell matching today's date gets a highlight automatically.
  • Week start: the layout uses the same weekStartDay as the month view, so changing the locale's calendar.weekStart shifts both views together.
  • Hover: hovering a marked day opens a tooltip listing that day's events. The default uses event.text; pass a tooltip component to render your own.

The view is PRO-only. The package pre-registers it, but it only shows up in the mode switcher when you list it in views.

Enabling Year View

The default views prop is ["day", "week", "month"]. Add "year" to expose the view in the mode switcher. Set view="year" to open on it.

import { Calendar } from "@svar-ui/react-calendar";

const events = [
{ id: 1, start: new Date(2025, 2, 10, 9), end: new Date(2025, 2, 10, 10), text: "Meeting" },
{ id: 2, start: new Date(2025, 2, 9), end: new Date(2025, 2, 12), text: "Conference" },
];

<Calendar
events={events}
view="year"
date={new Date(2025, 5, 15)}
views={["year", "day", "week", "month"]}
/>

The views order controls the order of buttons in the mode switcher. Put "year" first if you want it leading the switcher even when the calendar opens on a different view.

Localizing the Year Label

YearViewModel's getRangeLabel() returns the four-digit year. Month labels inside each mini-grid come from the yearMonthFormat locale key. Weekday headers follow weekStartDay. Wrap the calendar in <Locale> from @svar-ui/react-core to swap both at once.

import { useState, useMemo } from "react";
import { Locale } from "@svar-ui/react-core";
import { Calendar } from "@svar-ui/react-calendar";

const [sundayStart, setSundayStart] = useState(false);
const words = useMemo(() => ({ calendar: { weekStart: sundayStart ? 0 : 1 } }), [sundayStart]);

<Locale words={words}>
<Calendar events={events} view="year" date={date} views={["year", "day", "week", "month"]} />
</Locale>

Flipping weekStart re-aligns every month: day 1 lands on a different cell and the weekday header row reorders to match.

Custom Tooltip on Marked Days

Pass a React component to tooltip to replace the default hover label. In the year view the component receives { events } - plural, because a single day can carry multiple events.

import { Calendar } from "@svar-ui/react-calendar";
import YearTooltip from "./YearTooltip.jsx";

<Calendar events={events} view="year" date={date} views={["year", "month"]} tooltip={YearTooltip} />
// YearTooltip.jsx
function YearTooltip({ events }) {
return (
<ul>
{events.map(e => (
<li key={e.id}>{e.text}</li>
))}
</ul>
);
}

export default YearTooltip;

Custom Day Content

The year mode draws a built-in dot on marked days. Pass an eventContent component and branch on mode === "year-tooltip" to render your own marker instead.

import { Calendar } from "@svar-ui/react-calendar";
import YearDot from "./YearDot.jsx";

<Calendar events={events} view="year" date={date} views={["year", "month"]} eventContent={YearDot} />

The calendar reuses the same component across views - branch on mode if you also use it for "grid", "bars", "boxes", or "list".

Custom Cell Styling

Use cellCss to paint specific days inside the year grid. The callback receives a CellContext. Branch on view === "year" and read ctx.date.

import { Calendar } from "@svar-ui/react-calendar";

const cellCss = (ctx) => {
if (ctx.view !== "year" || !ctx.date) return "";
const day = ctx.date.getDay();
return day === 0 || day === 6 ? "weekend" : "";
};

<Calendar events={events} view="year" date={date} views={["year", "month"]} cellCss={cellCss} />
.weekend {
color: var(--wx-color-error);
}

Building a Custom Year Variant

For wider overviews - a fiscal year, a multi-year planner - subclass YearViewModel and register it under a new id with registerCalendarView. Override rangeStart, addRange, and getRangeLabel for the range you want. The section pipeline stays the same, so the twelve mini-month layout keeps working.

import { YearViewModel, registerCalendarView } from "@svar-ui/react-calendar";

class FiscalYearViewModel extends YearViewModel {
rangeStart(date: Date): Date {
// Fiscal year starts in April
const y = date.getMonth() < 3 ? date.getFullYear() - 1 : date.getFullYear();
return new Date(y, 3, 1);
}

addRange(date: Date, n: number): Date {
return new Date(date.getFullYear() + n, date.getMonth(), 1);
}

getRangeLabel(): string {
const y = this.startDate.getFullYear();
return `FY ${y}-${y + 1}`;
}
}

registerCalendarView("fiscal-year", FiscalYearViewModel);
<Calendar events={events} view="fiscal-year" date={date} views={["fiscal-year", "month"]} />

The base process() keeps producing the twelve-month layout - the subclass only shifts which year is in scope and how the toolbar labels it.