Docs
Views

Calendar

Show dated records as a month, week or list calendar.

Calendar is an optional registry item, so the table keeps no calendar dependency until you install it. Records become all-day events on a month, week or list layout, built with FullCalendar and themed to match shadcn.

Install and enable

npx shadcn@latest add https://table.yayaw.app/r/yayaw-table-calendar.json

This installs @fullcalendar/react and temporal-polyfill and adds the files under components/ui/yayaw-table-calendar/. Pass the renderer and list "calendar" in displayModes:

calendar-enable.tsx
import { calendarRenderer } from "@/components/ui/yayaw-table-calendar/calendar-renderer";

<DataTable
  displayModeRenderers={{ calendar: calendarRenderer }}
  // ...
/>;
npx shadcn-vue@latest add https://table.yayaw.app/r/yayaw-table-vue-calendar.json

This installs @fullcalendar/vue3 and temporal-polyfill and adds the files under components/ui/yayaw-table-vue/calendar/. Pass the renderer and list "calendar" in displayModes:

calendar-enable.vue
<script setup lang="ts">
import { calendarRenderer } from "@/components/ui/yayaw-table-vue/calendar/calendar-renderer";
</script>

<template>
  <YayawDataTable :display-mode-renderers="{ calendar: calendarRenderer }" />
</template>

Without a passed renderer, "calendar" is not offered even if listed in displayModes, and a link asking for it falls back to the default mode. displayModeRenderers is a general mechanism for optional display modes; Calendar is its first one.

Try the calendar

The preview passes calendarRenderer in displayModeRenderers and shows each project from its start to its end date, colored by status. Drag an event to another day or stretch its end to update the record, or click an empty day to create a project on that date. Use Month, Week and List in the calendar's toolbar. The preview uses the store-opening projects shared by every view guide; see the example setup for project-config.ts and the in-memory host.

Expand ↗

Sample data. Changes stay in this preview.

Expand ↗

Sample data. Changes stay in this preview.

Configuration

Describe the calendar with table.calendar. All options are optional; unset ones fall back to the first date column, the first non-date column, and the defaults below.

calendar-config.ts
export const calendarConfig = defineTableConfig({
  ...productConfig,
  table: {
    ...productConfig.table,
    displayModes: ["table", "calendar"],
    calendar: {
      dateColumn: "startDate",
      endColumn: "endDate",
      titleColumn: "name",
      colorColumn: "status",
      layout: "month",
    },
  },
});
OptionDefaultDescription
dateColumnFirst date columnStart date of the event.
endColumnNoneInclusive end date; without it, events last one day.
titleColumnFirst non-date columnColumn used as the event title.
colorColumnNoneColors events with that column's tag colors.
layout"month""month", "week" or "list".
weekStartsOn1 (Monday)First day of the week, 0 (Sunday) to 6 (Saturday).
showWeekendstrueShow Saturday and Sunday.
allowDragUpdatetrueDrag an event to another day. Needs actions.update and edit permission on the row (canEditRow).
allowResizetrueStretch an event to change its end. Needs endColumn.
allowCreatetrueClick a day to create a record on it. Needs actions.create.

Calendar settings

Open View → Card settings to choose the date, end date, title and color columns, the layout, the first day of the week, weekends, drag, resize and create. The Month/Week/List buttons and previous/today/next sit in the calendar's own toolbar, beside its title. Choices are saved with views and in the <tableId>-calendar URL key, for example ?projects-display=calendar&projects-calendar={"layout":"list"}.

Moving and creating events

Dragging an event to a new day calls actions.update(id, patch) with the date column, shifting the end column by the same duration when there is one; the event returns to its place if the update fails. A date stored as YYYY-MM-DD stays date-only after a move, and an ISO timestamp keeps its time of day.

Clicking a day opens the create form with the date, and the end date when configured, already filled in. Clicking an event behaves like clicking a table row: it follows rowClickMode (details, edit, link or onRowActivate).

Server data

The calendar needs every row in the visible range, not only the current page. It calls actions.list with the usual search, filters and sorting, plus a scope:

{ kind: "dateRange", field: "startDate", endField: "endDate", from: "2026-09-01", to: "2026-09-30" }

from and to are local calendar days, both inclusive. A server that filters by the scope answers meta: { scope: "applied" }; otherwise the table filters the loaded rows itself, which still works but transfers more data. A minimal server-side check:

const overlaps = (row) =>
  row[scope.field] <= scope.to &&
  (row[scope.endField ?? scope.field] ?? row[scope.field]) >= scope.from;

Loading is capped; a notice appears when only part of the matching records is shown.

Translations

React keys live under views.calendar.* (previous, next, today, layout, month, week, list, dateColumn, endColumn, titleColumn, colorColumn, none, weekStartsOn, monday, sunday, saturday, showWeekends, allowDragUpdate, allowResize, allowCreate, on, off, noDateColumn, truncated) plus views.display.calendar. Vue uses the same names under calendar.* and display.calendar. Every key is optional and keeps its built-in English or French wording when left out; French FullCalendar text is used whenever the locale starts with fr.

Theme

The calendar maps FullCalendar's classic theme to the shadcn tokens (background, border, muted, primary, and so on), so it follows light and dark mode like the rest of the table.