# useDocyrusCalendar URL: /docs/native/hooks/use-docyrus-calendar Calendar backed by a Docyrus data source. Detects the date, title, color, description and user fields, turns records into events, and wires create, update, delete and drag to the API. ## Installation ```bash pnpm dlx @docyrus/cli add @docyrus/rn-hooks-use-docyrus-calendar ``` **Dependencies:** - [@docyrus/api-client](https://www.npmjs.com/package/@docyrus/api-client) - [@docyrus/app-utils](https://www.npmjs.com/package/@docyrus/app-utils) - [@tanstack/react-query](https://tanstack.com/query/latest) This is a port of the web hook with the same signature. It builds on [`useDocyrusDataGrid`](/docs/native/hooks/use-docyrus-data-grid), which supplies saved views, the toolbar, filters, search and field metadata. Its own items query then requests only the columns the calendar needs. `calendarProviderProps` is ready to spread onto the native [rn-calendar](/docs/native/docyrus/calendar), which supports all eight views (including `year-timeline`, `quarter` and `13weeks`). It passes: - `isRefreshing` (from `itemsQuery.isFetching`) - the timeline options - the user `filterItems` - `onEventCreate` / `onEventUpdate` / `onEventDelete` / `onEventDrop`, each calling the Docyrus API With `enableDateRangeFilter`, the query adds an overlap rule (`start <= rangeEnd AND end >= rangeStart`) and refetches whenever the visible range changes. The hook needs an authenticated `RestApiClient` and a `QueryClientProvider` above it. ## Usage ```tsx import { useDocyrusClient } from '@docyrus/signin/react-native'; import { Calendar } from '@/components/docyrus-native/calendar'; import { useDocyrusCalendar } from '@/hooks/docyrus-native/use-docyrus-calendar'; export function EventsCalendar() { const client = useDocyrusClient(); const cal = useDocyrusCalendar({ client: client!, appSlug: 'base', dataSourceSlug: 'event', startDateFieldSlug: 'start_date', endDateFieldSlug: 'end_date', titleFieldSlug: 'subject', descriptionFieldSlug: 'description', enableDateRangeFilter: true, persistState: true }); // Render a skeleton only on the very first load — passing `isLoading` on // every refetch would unmount the calendar and reset its view + date. if (!cal.hasLoadedOnce) return null; return ( <> {cal.toolbar} ); } ``` ## API Reference ### Options (`UseDocyrusCalendarOptions`) Extends every [`useDocyrusDataGrid`](/docs/native/hooks/use-docyrus-data-grid) option except `data`, `enableItemsQuery`, `showSelectColumn`, `enableRowMarkers` and `collection`, which the calendar owns. | Prop | Type | Default | Description | |------|------|---------|-------------| | `client` | `RestApiClient` | — | Authenticated Docyrus API client (required) | | `appSlug` | `string` | — | App slug (required) | | `dataSourceSlug` | `string` | — | Data source slug (required) | | `collection` | `DocyrusCalendarCollection` | — | Custom `list` / `create` / `update` / `delete` adapter | | `startDateFieldSlug` | `string` | first `field-date` / `field-dateTime` | Event start field | | `endDateFieldSlug` | `string` | `end_date`, `end_time`, `due_date`, … or the second date field | Event end field | | `titleFieldSlug` | `string` | `name`, `title`, `label`, `subject`, … | Event title field | | `colorFieldSlug` | `string` | `color` / `colour` | Event color field | | `descriptionFieldSlug` | `string` | `description`, `notes`, `content`, … | Event description field | | `userFieldSlug` | `string` | first user field, then `record_owner` | User field that fills the user filter | | `colorMap` | `Record` | — | Maps field values to event colors | | `defaultEventDurationMinutes` | `number` | `60` | Event length when the end date is missing | | `getEvent` | `(item, context) => DocyrusCalendarEvent \| null` | — | Replaces the built-in event builder. Return `null` to skip a record | | `defaultView` | `TCalendarView` | `'month'` | Initial view | | `enableDateRangeFilter` | `boolean` | `false` | Limits the query to the visible range. Native wires `onVisibleRangeChange` for you | | `timelineMaxLanes` | `number` | `3` | Lanes shown in each timeline row before `+N more` | | `defaultYearTimelineMode` | `'continuous' \| 'single'` | `'continuous'` | Initial pagination mode of the year timeline | | `defaultQuarterMode` | `'continuous' \| 'single'` | `'continuous'` | Initial pagination mode of the quarter view | | `staleTime` | `number` | `30000` | React Query stale time in ms | | `enableGroupMenu` | `boolean` | `false` | Shows the group menu in the grid toolbar | | `enableRowHeightMenu` | `boolean` | `false` | Shows the row-height menu in the grid toolbar | | `enableDisplayMenu` | `boolean` | `false` | Shows the display menu in the grid toolbar | | `onReload` | `() => void` | — | Called after a toolbar reload | | `persistState` | `boolean \| { storage?: 'session' \| 'local'; key?: string }` | — | Saves the grid's view parameters for each saved view | ### Result (`UseDocyrusCalendarResult`) | Key | Type | Description | |-----|------|-------------| | `calendarProviderProps` | `Omit` | Ready to spread onto `` / `` | | `events` | `DocyrusCalendarEvent[]` | Transformed events | | `users` | `IUser[]` | Unique event users | | `filterItems` | `CalendarFilterItem[]` | User filter items | | `items` | `TData[]` | Raw records | | `startDateField` / `endDateField` / `titleField` / `colorField` / `descriptionField` / `userField` | `DataSourceField \| null` | Resolved fields | | `hasDateField` | `boolean` | Whether a start-date field was found | | `requestedColumns` | `string` | `columns` sent to the items endpoint | | `resolvedListParams` | `DocyrusDataGridListParams` | Full query payload | | `createRecord` | `(start, end, extra?) => Promise` | Creates a record | | `updateRecord` | `(recordId, data) => Promise` | Updates a record | | `deleteRecord` | `(recordId) => Promise` | Deletes a record | | `moveRecord` | `(recordId, newStart, newEnd) => Promise` | Updates the start and end fields | | `visibleRange` / `setVisibleRange` | `{ start: Date; end: Date } \| null` / setter | The range that drives the date-range filter | | `isLoading` / `isFetching` / `hasLoadedOnce` | `boolean` | Loading flags | | `error` | `Error \| null` | Error from the schema or items request | | `reload` | `() => void` | Refetches the schema and the items | | `table` / `toolbar` / `views` / `fields` / `dataSource` / `activeViewId` / `setActiveViewId` | — | Passed through from `useDocyrusDataGrid` | ## Native deltas - `toolbar` / `table` come from the native `useDocyrusDataGrid`, which stacks the toolbar for small screens. - With `enableDateRangeFilter`, `calendarProviderProps.onVisibleRangeChange` is already wired to `setVisibleRange`. On web you wire it yourself. Pass your own `onVisibleRangeChange` after the spread to override it. Identical ranges are ignored. - The items query keeps the previous result while a new range loads (`keepPreviousData`). Navigating shows the `isRefreshing` spinner over the current events instead of clearing the calendar. ## Type Exports | Type | Description | |------|-------------| | `UseDocyrusCalendarOptions` | Hook options | | `UseDocyrusCalendarResult` | Hook result | | `DocyrusCalendarEvent` | `IEvent` plus `recordId` and `item` | | `DocyrusCalendarCollection` | Collection adapter | | `DocyrusCalendarEventBuilderContext` | Context passed to `getEvent` | | `IEvent`, `IUser`, `TCalendarView`, `TEventColor`, `CalendarFilterItem` | Re-exported calendar types |