### Run Development Server
Source: https://github.com/dayflow-js/calendar/blob/main/website/README.md
Use these commands to start the development server for your Next.js application. Ensure you have Node.js and npm, pnpm, or yarn installed.
```bash
npm run dev
# or
pnpm dev
# or
yarn dev
```
--------------------------------
### Start CalDAV Proxy with Environment Variables
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs/caldav/caldav.mdx
Example command to launch the Node.js CalDAV proxy server. Ensure that the CalDAV server URL, username, and password are provided as environment variables.
```bash
CALDAV_BASE_URL=https://caldav.icloud.com \
CALDAV_USERNAME=alice@icloud.com \
CALDAV_PASSWORD=xxxx-xxxx-xxxx-xxxx \
node proxy.mjs
```
--------------------------------
### Run create-dayflow CLI with pnpm
Source: https://github.com/dayflow-js/calendar/blob/main/packages/create-dayflow/README.md
Initiate the DayFlow setup wizard using pnpm. This command ensures the correct adapter and plugins are installed for your project.
```bash
pnpm dlx create-dayflow
```
--------------------------------
### Advanced Calendar Configuration Example
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs/introduction/use-calendar-app.mdx
An advanced example demonstrating the integration of multiple views, custom calendars, plugins, and callbacks for a comprehensive calendar application setup.
```tsx
import {
useCalendarApp,
DayFlowCalendar,
createMonthView,
createWeekView,
ViewType,
} from '@dayflow/react'; // or '@dayflow/vue', '@dayflow/svelte', '@dayflow/angular'
import { createSidebarPlugin } from '@dayflow/plugin-sidebar';
import '@dayflow/core/dist/styles.css';
const calendars = [
{
id: 'work',
name: 'Work',
colors: {
eventColor: '#2563eb',
eventSelectedColor: '#1d4ed8',
lineColor: '#1e40af',
textColor: '#ffffff',
},
},
{
id: 'personal',
name: 'Personal',
colors: {
eventColor: '#f97316',
eventSelectedColor: '#ea580c',
lineColor: '#c2410c',
textColor: '#ffffff',
},
},
];
export function AdvancedCalendar() {
const calendar = useCalendarApp({
views: [createMonthView(), createWeekView()],
defaultView: ViewType.WEEK,
initialDate: new Date('2024-10-01'),
events: [],
calendars,
defaultCalendar: 'work',
switcherMode: 'select',
callbacks: {
onEventUpdate: event => api.events.update(event),
onVisibleRangeChange: (start, end, reason) =>
preloadVisibleRange(start, end, reason),
},
plugins: [
createSidebarPlugin({
width: 280,
initialCollapsed: false,
}),
],
useEventDetailDialog: true,
});
return ;
}
```
--------------------------------
### Start Development Server
Source: https://github.com/dayflow-js/calendar/blob/main/CONTRIBUTING.md
Navigate to the core package and start the development server using pnpm. The application will be available at http://localhost:5529.
```bash
cd packages/core
pnpm run dev
```
--------------------------------
### CalDAV Configuration for Backend
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs/caldav/overview.mdx
Configuration examples for different CalDAV providers. These environment variables should be kept on the backend and not sent to the browser. Specific providers may have recommended setup methods.
```bash
# iCloud
CALDAV_BASE_URL=https://caldav.icloud.com/
CALDAV_USERNAME=alice@icloud.com
CALDAV_PASSWORD=xxxx-xxxx-xxxx-xxxx
# Nextcloud
# CALDAV_BASE_URL=https://nextcloud.example.com/remote.php/dav/
# CALDAV_USERNAME=alice
# CALDAV_PASSWORD=nextcloud-app-password
# Radicale
# CALDAV_BASE_URL=https://radicale.example.com/
# Fastmail
# CALDAV_BASE_URL=https://caldav.fastmail.com/dav/
```
--------------------------------
### Install Project Dependencies
Source: https://github.com/dayflow-js/calendar/blob/main/CONTRIBUTING.md
Install all necessary project dependencies using pnpm. This command should be run after cloning the repository.
```bash
pnpm install
```
--------------------------------
### Start Proxy Server
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs/caldav/google-sync.mdx
Command to start the Node.js proxy server for testing with a provided access token.
```bash
# Quick test with an access token
GOOGLE_ACCESS_TOKEN=ya29.xxx node proxy.mjs
```
--------------------------------
### Advanced Calendar Configuration Example
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs-zh/introduction/use-calendar-app.mdx
An example demonstrating advanced setup of the DayFlow Calendar with multiple views, custom calendars, plugins like the sidebar, and event callbacks. This configuration is suitable for complex application requirements.
```tsx
import {
useCalendarApp,
DayFlowCalendar,
createMonthView,
createWeekView,
ViewType,
} from '@dayflow/react'; // or '@dayflow/vue', '@dayflow/svelte', '@dayflow/angular'
import { createSidebarPlugin } from '@dayflow/plugin-sidebar';
import '@dayflow/core/dist/styles.css';
const calendars = [
{
id: 'work',
name: '工作',
colors: {
eventColor: '#2563eb',
eventSelectedColor: '#1d4ed8',
lineColor: '#1e40af',
textColor: '#ffffff',
},
},
{
id: 'personal',
name: '个人',
colors: {
eventColor: '#f97316',
eventSelectedColor: '#ea580c',
lineColor: '#c2410c',
textColor: '#ffffff',
},
},
];
export function AdvancedCalendar() {
const calendar = useCalendarApp({
views: [createMonthView(), createWeekView()],
defaultView: ViewType.WEEK,
initialDate: new Date('2024-10-01'),
events: [],
calendars,
defaultCalendar: 'work',
switcherMode: 'select',
callbacks: {
onEventUpdate: event => api.events.update(event),
onVisibleRangeChange: (start, end, reason) =>
preloadVisibleRange(start, end, reason),
},
plugins: [
createSidebarPlugin({
width: 280,
initialCollapsed: false,
}),
],
useEventDetailDialog: true,
});
return ;
}
```
--------------------------------
### Install Drag & Drop Plugin
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs/plugins/drag.mdx
Install the plugin using your preferred package manager.
```bash
```
--------------------------------
### Basic Usage Example
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs/ui/context-menu.mdx
Demonstrates how to render the ContextMenu at the cursor position captured from a 'contextmenu' event.
```APIDOC
## Basic Usage
Render `ContextMenu` at the cursor position captured from a `contextmenu` event.
### Code Example
```tsx
import { useState } from 'react';
import {
ContextMenu,
ContextMenuItem,
ContextMenuSeparator,
} from '@dayflow/ui-context-menu';
function MyComponent() {
const [menu, setMenu] = useState<{ x: number; y: number } | null>(null);
const handleContextMenu = (e: React.MouseEvent) => {
e.preventDefault();
setMenu({ x: e.clientX, y: e.clientY });
};
return (
Right-click here
{menu && (
setMenu(null)}>
console.log('Edit')}>Edit
console.log('Copy')}>Copy
console.log('Delete')} danger>
Delete
)}
);
}
```
```
--------------------------------
### Quick Start: Initialize Google Sync
Source: https://github.com/dayflow-js/calendar/blob/main/packages/caldav/google-sync/README.md
Demonstrates the basic setup for integrating Google Calendar sync into a DayFlow application. Requires creating an adapter with a base URL and fetch implementation, then attaching the sync controller to the DayFlow app.
```typescript
import {
attachGoogleSyncToDayFlow,
createGoogleSync,
createGoogleSyncAdapter,
} from '@dayflow/google-sync';
const adapter = createGoogleSyncAdapter({
baseUrl: '/api/google-calendar',
fetch,
});
const sync = createGoogleSync(adapter);
const controller = attachGoogleSyncToDayFlow(calendar.app, sync);
await controller.start();
```
--------------------------------
### Start the CalDAV Proxy
Source: https://github.com/dayflow-js/calendar/blob/main/examples/caldav-proxy/README.md
Launches the Node.js CalDAV proxy server.
```sh
node proxy.mjs
# CalDAV proxy listening on http://localhost:3001/api/caldav
```
--------------------------------
### Install DayFlow Pro Packages
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs/introduction/pro-installation.mdx
Install the purchased DayFlow Pro packages using your package manager after configuring the private registry.
```bash
pnpm add @dayflow-pro/license @dayflow-pro/resource-grid
```
--------------------------------
### Run create-dayflow CLI with npx
Source: https://github.com/dayflow-js/calendar/blob/main/packages/create-dayflow/README.md
Use this command to initiate the interactive setup wizard for DayFlow in your project's root directory.
```bash
npx create-dayflow
```
--------------------------------
### Start DayFlow Application
Source: https://github.com/dayflow-js/calendar/blob/main/examples/sync-connectivity/README.md
Start the DayFlow core application in development mode using pnpm.
```sh
pnpm --filter @dayflow/core dev
```
--------------------------------
### Start the Proxy Server
Source: https://github.com/dayflow-js/calendar/blob/main/examples/sync-connectivity/README.md
Run the local Node.js proxy server to handle calendar API requests.
```sh
node examples/sync-connectivity/proxy.mjs
```
--------------------------------
### Commit Message Examples
Source: https://github.com/dayflow-js/calendar/blob/main/CONTRIBUTING.md
Examples of commit messages following the project's prefix convention for features and bug fixes.
```bash
feat: add drag-and-drop event support
fix: resolve timezone offset issue in calendar view
```
--------------------------------
### Browser Backend Proxy Example
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs/caldav/overview.mdx
This example demonstrates how the browser communicates with your backend proxy, which then forwards requests to the CalDAV API. The DayFlow sync engine uses an authenticated fetch function provided by your backend.
```typescript
const adapter = createCalDAVAdapter({
calendarHomeUrl: 'https://caldav.example.com/calendars/alice/',
fetch: (url, init) =>
fetch('/api/caldav-proxy', {
method: 'POST',
body: JSON.stringify({ url, init }),
}),
});
```
--------------------------------
### Run create-dayflow CLI with bun
Source: https://github.com/dayflow-js/calendar/blob/main/packages/create-dayflow/README.md
Launch the DayFlow interactive setup using the bun runtime. This wizard helps in selecting DayFlow plugins and configuring necessary styles.
```bash
bun x create-dayflow
```
--------------------------------
### Context Menu with Labels and Icons
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs/ui/context-menu.mdx
Example showcasing how to use labels and icons within the context menu items.
```APIDOC
## With Labels and Icons
```tsx
Actions
} onClick={() => onEdit()}>
Edit Event
} onClick={() => onDuplicate()}>
Duplicate
} onClick={() => onDelete()} danger>
Delete
```
```
--------------------------------
### Quick Start: Basic Calendar Integration
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs/introduction/use-calendar-app.mdx
Demonstrates how to initialize and render a basic DayFlow calendar using the useCalendarApp hook with month and week views.
```tsx
import {
useCalendarApp,
DayFlowCalendar,
createMonthView,
createWeekView,
ViewType,
} from '@dayflow/react'; // or '@dayflow/vue', '@dayflow/svelte', '@dayflow/angular'
import '@dayflow/core/dist/styles.css';
export function TeamCalendar() {
const calendar = useCalendarApp({
views: [createMonthView(), createWeekView()],
defaultView: ViewType.MONTH,
initialDate: new Date(),
events: [],
});
return ;
}
```
--------------------------------
### Nested Submenus Example
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs/ui/context-menu.mdx
Demonstrates how to create nested submenus using `ContextMenuSub`, `ContextMenuSubTrigger`, and `ContextMenuSubContent`.
```APIDOC
## Nested Submenus
Wrap items with `ContextMenuSub` to create hover-triggered submenus. The submenu automatically repositions itself to avoid viewport overflow.
### Code Example
```tsx
onEdit()}>Edit
Move to
onMove('work')}>Work
onMove('personal')}>Personal
onDelete()}>Delete
```
```
--------------------------------
### Quick Start: Configure Switcher Mode
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs/features/switcher-mode.mdx
Demonstrates how to set the `switcherMode` to 'select' for a compact header view. The default mode is 'buttons'.
```tsx
import {
useCalendarApp,
DayFlowCalendar,
createMonthView,
} from '@dayflow/react';
const calendar = useCalendarApp({
views: [createMonthView()],
switcherMode: 'select', // default switcherMode: 'buttons'
});
;
```
--------------------------------
### Start CalDAV Controller
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs/caldav/caldav.mdx
Initiates the CalDAV controller to discover remote calendars, load initial events, and subscribe to DayFlow changes. Ensure the controller is started before interacting with CalDAV data.
```typescript
// Discover remote calendars, load initial events, and subscribe to DayFlow changes
await controller.start();
```
--------------------------------
### Backend Proxy: Node.js HTTP Server Example
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs/caldav/google-sync.mdx
This Node.js example demonstrates a basic HTTP server acting as a proxy for the Google Calendar API. It handles token refreshing and forwards requests, injecting the Authorization header.
```js
// proxy.mjs (Node.js example)
import { createServer } from 'node:http';
const {
GOOGLE_ACCESS_TOKEN,
GOOGLE_CLIENT_ID,
GOOGLE_CLIENT_SECRET,
GOOGLE_REFRESH_TOKEN,
PORT = '3002',
} = process.env;
const GOOGLE_API_BASE = 'https://www.googleapis.com/calendar/v3';
const ALLOWED_METHODS = new Set(['GET', 'POST', 'PUT', 'PATCH', 'DELETE']);
let cachedToken = GOOGLE_ACCESS_TOKEN
? { token: GOOGLE_ACCESS_TOKEN, expiresAt: Infinity }
: null;
async function getAccessToken() {
if (cachedToken && cachedToken.expiresAt > Date.now() + 30_000) {
return cachedToken.token;
}
const res = await fetch('https://oauth2.googleapis.com/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
client_id: GOOGLE_CLIENT_ID,
client_secret: GOOGLE_CLIENT_SECRET,
refresh_token: GOOGLE_REFRESH_TOKEN,
grant_type: 'refresh_token',
}),
});
const data = await res.json();
cachedToken = {
token: data.access_token,
expiresAt: Date.now() + data.expires_in * 1000,
};
return cachedToken.token;
}
createServer(async (req, res) => {
const upstreamPath = req.url.replace(/^\/api\/google-calendar/, '');
const upstreamUrl = `${GOOGLE_API_BASE}${upstreamPath}`;
if (!ALLOWED_METHODS.has(req.method)) {
res.writeHead(405);
res.end();
return;
}
const chunks = [];
for await (const chunk of req) chunks.push(chunk);
const body =
req.method === 'GET' || req.method === 'DELETE'
? undefined
: Buffer.concat(chunks).toString();
const token = await getAccessToken();
const upstream = await fetch(upstreamUrl, {
method: req.method,
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`,
...(req.headers['if-match']
? { 'If-Match': req.headers['if-match'] }
: {}),
},
body,
});
const responseBody = upstream.status === 204 ? '' : await upstream.text();
res.writeHead(upstream.status, { 'Content-Type': 'application/json' });
res.end(responseBody);
}).listen(Number(PORT));
```
--------------------------------
### Run create-dayflow CLI with yarn
Source: https://github.com/dayflow-js/calendar/blob/main/packages/create-dayflow/README.md
Execute the create-dayflow setup wizard with yarn. It assists in configuring DayFlow components, including framework adapters and optional Tailwind CSS integration.
```bash
yarn dlx create-dayflow
```
--------------------------------
### Basic Dark Mode Setup
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs/features/dark-mode.mdx
Enable dark mode by setting the `theme.mode` configuration to 'dark' when initializing the calendar.
```APIDOC
## Basic Dark Mode Setup
### Description
Enable dark mode by setting the `theme.mode` configuration to 'dark' when initializing the calendar.
### Configuration
```typescript
interface ThemeConfig {
mode: 'light' | 'dark' | 'auto';
}
const calendar = useCalendarApp({
theme: {
mode: 'dark',
},
});
```
```
--------------------------------
### Color Picker Integration
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs/ui/context-menu.mdx
Example of integrating the `ContextMenuColorPicker` for selecting calendar colors.
```APIDOC
## Color Picker
`ContextMenuColorPicker` renders a row of preset swatches and an optional "Custom Color" action.
### Code Example
```tsx
Calendar Color
{
updateCalendarColor(color);
onClose();
}}
onCustomColor={() => openColorDialog()}
customColorLabel='Custom color...'
/>
```
```
--------------------------------
### Quick Start: Initialize CalDAV Adapter and Sync
Source: https://github.com/dayflow-js/calendar/blob/main/packages/caldav/core/README.md
Sets up the CalDAV adapter, sync engine, and attaches it to a DayFlow calendar application. Requires a custom fetch implementation for proxying requests.
```typescript
import {
attachCalDAVToDayFlow,
createCalDAVAdapter,
createCalDAVSync,
createNamespacedCalDAVEventId,
mapCalDAVEventToDayFlow,
} from '@dayflow/caldav';
const adapter = createCalDAVAdapter({
calendarHomeUrl: '/calendars/alice/',
fetch: (url, init) =>
fetch('/api/caldav-proxy', {
method: 'POST',
body: JSON.stringify({ url, init }),
}),
});
const sync = createCalDAVSync({
adapter,
storage,
// Optional: split broad visible-range REPORTs into smaller windows.
rangeChunkDays: 31,
});
const controller = attachCalDAVToDayFlow(calendar.app, sync, {
writable: true,
refreshOnVisibleRangeChange: true,
maxConcurrentCalendars: 4,
createEventId: createNamespacedCalDAVEventId,
eventMode: {
recurring: 'read-only',
},
});
await controller.start();
```
--------------------------------
### Create a Custom Calendar Plugin
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs/plugins/overview.mdx
Implement the `CalendarPlugin` interface to create custom plugins. The `install` function is called with the `CalendarApp` instance, allowing you to extend its functionality.
```tsx
import { CalendarPlugin, ICalendarApp } from '@dayflow/core';
export const myPlugin: CalendarPlugin = {
name: 'my-custom-plugin',
install(app: ICalendarApp) {
console.log('Plugin installed!');
// Extend app functionality here
},
};
```
--------------------------------
### Token Injection: Backend Proxy Setup
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs/caldav/google-sync.mdx
Configure `createGoogleSyncAdapter` with a `baseUrl` pointing to your backend proxy when tokens are managed server-side. This is recommended for production to avoid exposing tokens in the browser.
```ts
const adapter = createGoogleSyncAdapter({
baseUrl: '/api/google-calendar',
// No getToken needed — your proxy injects Authorization
});
```
--------------------------------
### Minimal Non-Tailwind CSS Setup
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs/guides/theme-customization.mdx
Import DayFlow's full CSS bundle for projects not using Tailwind. This bundle includes a CSS reset.
```css
/* app.css — for non-Tailwind projects */
@import '@dayflow/core/dist/styles.css';
```
--------------------------------
### Initialize Sidebar Plugin
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs/plugins/sidebar.mdx
Import and create an instance of the sidebar plugin. Configure options like width and the create calendar mode. This snippet shows basic setup for React.
```tsx
import { useCalendarApp, DayFlowCalendar } from '@dayflow/react'; // or '@dayflow/vue', '@dayflow/svelte', '@dayflow/angular'
import { createSidebarPlugin } from '@dayflow/plugin-sidebar';
function MyCalendar() {
const sidebarPlugin = createSidebarPlugin({
width: 280,
createCalendarMode: 'modal',
});
const calendar = useCalendarApp({
views: [
/* your views */
],
plugins: [sidebarPlugin],
});
return ;
}
```
--------------------------------
### Multi-Calendar Events Example
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs/introduction/events.mdx
Demonstrates how to assign an event to multiple calendars using `calendarIds`. Events with multiple calendars have distinct visual indicators.
```tsx
import { createEvent, useCalendarApp, createWeekView } from '@dayflow/react';
// This event belongs to both "team" and "marketing" calendars
const sharedEvent = createEvent({
id: 'shared-1',
title: 'Company All-Hands',
start: new Date(2024, 9, 15, 10, 0),
end: new Date(2024, 9, 15, 11, 30),
calendarIds: ['team', 'marketing'], // multi-calendar
});
// All-day event spanning three calendars
const crossCalendarDay = {
id: 'shared-2',
title: 'Team Offsite',
start: Temporal.PlainDate.from('2024-10-20'),
end: Temporal.PlainDate.from('2024-10-22'),
allDay: true,
calendarIds: ['team', 'personal', 'travel'],
};
const calendars = [
{
id: 'team',
name: 'Team',
colors: {
eventColor: '#3b82f6',
lineColor: '#3b82f6',
eventSelectedColor: '#2563eb',
textColor: '#fff',
},
isVisible: true,
},
{
id: 'marketing',
name: 'Marketing',
colors: {
eventColor: '#f59e0b',
lineColor: '#f59e0b',
eventSelectedColor: '#d97706',
textColor: '#fff',
},
isVisible: true,
},
{
id: 'personal',
name: 'Personal',
colors: {
eventColor: '#10b981',
lineColor: '#10b981',
eventSelectedColor: '#059669',
textColor: '#fff',
},
isVisible: true,
},
{
id: 'travel',
name: 'Travel',
colors: {
eventColor: '#8b5cf6',
lineColor: '#8b5cf6',
eventSelectedColor: '#7c3aed',
textColor: '#fff',
},
isVisible: true,
},
];
const calendar = useCalendarApp({
views: [createWeekView()],
events: [sharedEvent, crossCalendarDay],
calendars,
});
```
--------------------------------
### Initialize DayFlow Calendar with Month View
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs/introduction/views.mdx
Set up the DayFlow Calendar component using the Month View. This example shows basic initialization with views and default view settings.
```tsx
import {
useCalendarApp,
DayFlowCalendar,
createMonthView,
ViewType,
} from '@dayflow/react'; // or '@dayflow/vue', '@dayflow/svelte', '@dayflow/angular'
function MyCalendar() {
const calendar = useCalendarApp({
views: [createMonthView()],
defaultView: ViewType.MONTH,
initialDate: new Date(),
});
return ;
}
```
--------------------------------
### Basic DayFlow Calendar Initialization
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs/introduction/index.mdx
Initialize the DayFlow Calendar with views, plugins, calendar definitions, and initial events. This setup is suitable for basic calendar integration.
```javascript
const calendar = useCalendarApp({
views: [createDayView(), createWeekView(), createMonthView()],
plugins: [createDragPlugin(), createEventsPlugin()],
calendars: [
{
id: 'work',
name: 'Work',
colors: {
lineColor: '#2563eb',
eventColor: '#dbeafe',
eventSelectedColor: '#bfdbfe',
textColor: '#1e3a8a',
},
},
],
events: [
createEvent({
id: '1',
title: 'Team Meeting',
start: new Date(2025, 10, 15, 10, 0),
end: new Date(2025, 10, 15, 11, 0),
calendarId: 'work',
}),
createAllDayEvent({
id: '2',
title: 'Conference',
start: new Date(2025, 10, 20),
calendarId: 'work',
}),
],
initialDate: new Date(),
});
```
--------------------------------
### Configure Private npm Registry
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs/introduction/pro-installation.mdx
Add your DayFlow Pro npm token to your `.npmrc` file to enable installation of private packages. Ensure the `DAYFLOW_PRO_NPM_TOKEN` environment variable is set.
```ini
@dayflow-pro:registry=https://gitlab.com/api/v4/projects/81880038/packages/npm/
//gitlab.com/api/v4/projects/81880038/packages/npm/:_authToken=${DAYFLOW_PRO_NPM_TOKEN}
```
--------------------------------
### CalDAV Controller API
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs/caldav/caldav.mdx
API for controlling the CalDAV synchronization process, including starting, stopping, refreshing, and getting sync status.
```APIDOC
## Controller API
### Description
API for controlling the CalDAV synchronization process, including starting, stopping, refreshing, and getting sync status.
### Methods
- **`controller.start()`**
- Description: Discover remote calendars, load initial events, and subscribe to DayFlow changes.
- Usage: `await controller.start();`
- **`controller.stop()`**
- Description: Unsubscribe all listeners (does not clear DayFlow state).
- Usage: `controller.stop();`
- **`controller.refresh(options?: { calendarId?: string; range?: { start: Date; end: Date } })`**
- Description: Re-sync calendars. Can be used to re-sync all calendars, a specific calendar, or with an explicit date range.
- Usage:
- `await controller.refresh();` (Re-sync all calendars using the last known visible range)
- `await controller.refresh({ calendarId: 'my-calendar-id' });` (Re-sync a specific calendar)
- `await controller.refresh({ range: { start: new Date('2025-01-01'), end: new Date('2025-02-01') } });` (Re-sync with an explicit date range)
- **`controller.getStatus()`**
- Description: Get current sync status.
- Returns: `{ state: 'idle' | 'syncing' | 'error', lastSyncedAt?: Date, error?: unknown }`
- Usage: `const status = controller.getStatus();`
```
--------------------------------
### Use Pro Packages in React Component
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs/introduction/pro-installation.mdx
Integrate DayFlow Pro packages, such as the resource grid view, into your React application after installation and license registration. This example demonstrates creating and using a resource grid view within a DayFlow Calendar component.
```tsx
import { DayFlowCalendar, useCalendarApp } from '@dayflow/react';
import { createResourceGridView } from '@dayflow-pro/resource-grid';
function App() {
const calendar = useCalendarApp({
views: [
createResourceGridView({
mode: 'resourceView',
resources: [
{ id: 'room-a', title: 'Room A' },
{ id: 'room-b', title: 'Room B' },
],
}),
],
});
return ;
}
```
--------------------------------
### Initialize Keyboard Shortcuts Plugin
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs/plugins/keyboard-shortcuts.mdx
Import and create the keyboard shortcuts plugin, optionally providing configuration. This is typically done within the `useCalendarApp` hook.
```tsx
import { useCalendarApp, DayFlowCalendar } from '@dayflow/react';
import { createKeyboardShortcutsPlugin } from '@dayflow/plugin-keyboard-shortcuts';
function MyCalendar() {
const calendar = useCalendarApp({
// ...
plugins: [
createKeyboardShortcutsPlugin({
// Optional configuration
}),
],
});
return ;
}
```
--------------------------------
### Install Latest Dayflow Core
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/blog/v2.0.3.mdx
Update to the latest version of @dayflow/core to use the new Year View features. This command installs the most recent stable release.
```bash
npm install @dayflow/core@latest
```
--------------------------------
### Quick Start: Initialize Google Sync in React
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs/caldav/google-sync.mdx
This snippet shows how to initialize and attach the Google Sync controller to a DayFlow calendar instance within a React component. It handles starting and stopping the sync process and logging status changes and errors.
```tsx
import { useRef, useEffect, useState } from 'react';
import {
DayFlowCalendar,
useCalendarApp,
createMonthView,
} from '@dayflow/react';
import {
attachGoogleSyncToDayFlow,
createGoogleSync,
createGoogleSyncAdapter,
type GoogleDayFlowController,
type GoogleSyncStatus,
} from '@dayflow/google-sync';
function MyCalendar() {
const calendar = useCalendarApp({
views: [createMonthView()],
calendars: [],
events: [],
});
const controllerRef = useRef(null);
const [syncStatus, setSyncStatus] = useState({
state: 'idle',
});
useEffect(() => {
if (controllerRef.current) return;
const adapter = createGoogleSyncAdapter({
baseUrl: '/api/google-calendar',
});
const sync = createGoogleSync(adapter);
const controller = attachGoogleSyncToDayFlow(calendar.app, sync, {
writable: true,
onStatusChange: setSyncStatus,
onWriteError: (error, ctx) =>
console.error(`[google-sync] ${ctx.action} failed:`, error.message),
onSyncComplete: delta => {
console.log(
`Sync done: +${delta.events.added} ~${delta.events.updated} -${delta.events.deleted}`
);
},
});
controllerRef.current = controller;
controller.start();
return () => {
controller.stop();
controllerRef.current = null;
};
}, [calendar.app]);
return ;
}
```
--------------------------------
### Quick Start: Initialize Outlook Sync in React
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs/caldav/outlook-sync.mdx
This snippet demonstrates how to initialize and attach the Outlook sync controller within a React component. It sets up the adapter, creates the sync instance, and attaches it to the DayFlow calendar app, starting the sync process.
```tsx
import { useRef, useEffect, useState } from 'react';
import {
DayFlowCalendar,
useCalendarApp,
createMonthView,
} from '@dayflow/react';
import {
attachOutlookSyncToDayFlow,
createOutlookSync,
createOutlookSyncAdapter,
type OutlookDayFlowController,
type OutlookSyncStatus,
} from '@dayflow/outlook-sync';
function MyCalendar() {
const calendar = useCalendarApp({
views: [createMonthView()],
calendars: [],
events: [],
});
const controllerRef = useRef(null);
const [syncStatus, setSyncStatus] = useState({
state: 'idle',
});
useEffect(() => {
if (controllerRef.current) return;
const adapter = createOutlookSyncAdapter({
baseUrl: '/api/outlook-calendar',
});
const sync = createOutlookSync(adapter);
const controller = attachOutlookSyncToDayFlow(calendar.app, sync, {
writable: true,
onStatusChange: setSyncStatus,
onWriteError: (error, ctx) =>
console.error(`[outlook-sync] ${ctx.action} failed:`, error.message),
onSyncComplete: delta => {
console.log(
`Sync done: +${delta.events.added} ~${delta.events.updated} -${delta.events.deleted}`
);
},
});
controllerRef.current = controller;
controller.start();
return () => {
controller.stop();
controllerRef.current = null;
};
}, [calendar.app]);
return ;
}
```
--------------------------------
### DayFlow Controller API for Google Sync
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs/caldav/google-sync.mdx
Demonstrates essential controller methods for managing Google Calendar synchronization, including starting, stopping, and refreshing sync operations. Use `start()` to initiate sync, `stop()` to halt it, and `refresh()` to re-sync calendars or specific events.
```typescript
// Load calendars, sync initial events, and subscribe to visible-range and event changes
await controller.start();
// Unsubscribe all listeners
controller.stop();
// Re-sync all calendars for the current visible range
await controller.refresh();
// Re-sync a specific calendar
await controller.refresh({ calendarId: 'primary' });
// Re-sync with an explicit range
await controller.refresh({
calendarId: 'primary',
range: { start: new Date('2025-01-01'), end: new Date('2025-02-01') },
});
// Current sync state
const status = controller.getStatus();
```
--------------------------------
### Nextcloud CalDAV Discovery Flow
Source: https://github.com/dayflow-js/calendar/blob/main/examples/caldav-proxy/README.md
Demonstrates how to discover the calendar home set using a PROPFIND request with cURL.
```sh
curl -u alice:app-token \
-X PROPFIND \
-H "Depth: 0" \
-H "Content-Type: application/xml" \
https://nextcloud.example.com/dav/principals/users/alice/ \
--data ''
```
--------------------------------
### Quick Start: Integrate CalDAV with DayFlow React Calendar
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs/caldav/caldav.mdx
This snippet shows how to initialize and attach a CalDAV adapter to a DayFlow calendar in a React application. It includes setting up the adapter with a proxy fetch, creating a sync engine, and starting the synchronization process. Ensure a '/api/caldav-proxy' endpoint is available to handle CalDAV requests.
```tsx
import { useRef, useEffect } from 'react';
import {
DayFlowCalendar,
useCalendarApp,
createMonthView,
} from '@dayflow/react';
import {
attachCalDAVToDayFlow,
createCalDAVAdapter,
createCalDAVSync,
type CalDAVDayFlowController,
} from '@dayflow/caldav';
function MyCalendar() {
const calendar = useCalendarApp({
views: [createMonthView()],
calendars: [],
events: [],
});
const controllerRef = useRef(null);
useEffect(() => {
if (controllerRef.current) return;
const adapter = createCalDAVAdapter({
calendarHomeUrl: 'https://caldav.example.com/calendars/alice/',
fetch: (url, init) =>
fetch('/api/caldav-proxy', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ url, init }),
}),
});
const sync = createCalDAVSync({ adapter });
const controller = attachCalDAVToDayFlow(calendar.app, sync, {
writable: true,
maxConcurrentCalendars: 4,
onSyncComplete: delta => {
console.log(
`Sync done: +${delta.events.added} ~${delta.events.updated} -${delta.events.deleted}`
);
},
});
controllerRef.current = controller;
controller.start();
return () => {
controller.stop();
controllerRef.current = null;
};
}, [calendar.app]);
return ;
}
```
--------------------------------
### CalDAV Provider Presets for Adapter Creation
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs/caldav/caldav.mdx
This snippet demonstrates using built-in presets to simplify the creation of CalDAV adapters for common providers like iCloud, Nextcloud, Radicale, and Fastmail. For iCloud, dynamic discovery is mandatory. Ensure your `fetch` function handles authentication and CORS proxying if necessary.
```ts
import {
ICLOUD_CALDAV_SERVER,
createCalDAVAdapterFromServer,
nextcloudConfig,
radicaleConfig,
fastmailConfig,
createCalDAVAdapter,
} from '@dayflow/caldav';
// iCloud — must always discover dynamically
const icloudAdapter = await createCalDAVAdapterFromServer(
ICLOUD_CALDAV_SERVER,
{ fetch: proxiedFetch }
);
// Nextcloud
const nextcloudAdapter = createCalDAVAdapter({
...nextcloudConfig('https://nextcloud.example.com', 'alice'),
fetch: proxiedFetch,
});
// Radicale
const radicaleAdapter = createCalDAVAdapter({
...radicaleConfig('https://radicale.example.com', 'alice'),
fetch: proxiedFetch,
});
// Fastmail
const fastmailAdapter = createCalDAVAdapter({
...fastmailConfig('https://caldav.fastmail.com/dav', 'alice@fastmail.com'),
fetch: proxiedFetch,
});
```
--------------------------------
### Disabled Context Menu Item
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs/ui/context-menu.mdx
Example showing how to disable a context menu item based on a condition.
```APIDOC
## Disabled Items
```tsx
onPaste()} disabled={!hasClipboard}>
Paste
```
```
--------------------------------
### Get Events
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs/introduction/events.mdx
Retrieve all events currently managed by the calendar instance or access the current state of events directly.
```tsx
// Get all events
const events = calendar.getEvents();
// Get current events from state
const { events } = calendar;
```
--------------------------------
### Basic Resource Grid Usage
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs/introduction/resource-grid.mdx
Demonstrates how to set up the DayFlow Calendar with the resource grid view, defining resources and basic view configurations.
```tsx
import { DayFlowCalendar, useCalendarApp } from '@dayflow/react';
import { createResourceGridView } from '@dayflow/pro/resource-grid';
function App() {
const calendar = useCalendarApp({
views: [
createResourceGridView({
mode: 'resourceView',
resources: [
{ id: 'room-a', title: 'Room A' },
{ id: 'room-b', title: 'Room B' },
],
visibleDays: 3,
hourHeight: 72,
firstHour: 8,
lastHour: 20,
}),
],
});
return ;
}
```
--------------------------------
### CalDAV Adapter Creation with Server Discovery
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs/caldav/caldav.mdx
Use `createCalDAVAdapterFromServer` for servers like iCloud that require dynamic discovery of the calendar home URL. This function performs the necessary PROPFIND requests in a single step. The `fetch` function must be provided to handle the actual HTTP requests, including authentication.
```ts
import {
createCalDAVAdapterFromServer,
ICLOUD_CALDAV_SERVER,
} from '@dayflow/caldav';
const adapter = await createCalDAVAdapterFromServer(ICLOUD_CALDAV_SERVER, {
fetch: proxiedFetch,
});
```
--------------------------------
### createCalDAVAdapterFromServer Options
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs/caldav/caldav.mdx
Options for creating a CalDAV adapter from a server URL, performing internal discovery.
```APIDOC
## `createCalDAVAdapterFromServer` Options
### Description
Options for creating a CalDAV adapter from a server URL, performing internal discovery. Performs discovery internally and returns a ready `CalDAVAdapter`.
### Parameters
- **`serverUrl`** (string) - Required - CalDAV server root URL (e.g. `ICLOUD_CALDAV_SERVER`).
- **`options`** (object) - Required - Same as `createCalDAVAdapter` options, minus `calendarHomeUrl`.
```
--------------------------------
### Controller API Usage
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs/caldav/outlook-sync.mdx
Demonstrates essential controller methods for managing Outlook calendar synchronization, including starting, stopping, and refreshing calendars.
```typescript
// Load calendars, sync initial events, and subscribe to changes
await controller.start();
```
```typescript
// Unsubscribe all listeners
controller.stop();
```
```typescript
// Re-sync all calendars for the current visible range
await controller.refresh();
```
```typescript
// Re-sync a specific calendar
await controller.refresh({ calendarId: 'AAMk...' });
```
```typescript
// Re-sync with an explicit range
await controller.refresh({
range: { start: new Date('2025-01-01'), end: new Date('2025-02-01') },
});
```
```typescript
// Current sync state
const status = controller.getStatus();
```
--------------------------------
### Initialize and Use Drag Plugin
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs/plugins/drag.mdx
Initialize the drag plugin with desired configurations and add it to the calendar's plugins array. This enables drag, resize, and create functionalities.
```typescript
import { useCalendarApp, ViewType } from '@dayflow/react'; // or '@dayflow/vue', '@dayflow/svelte', '@dayflow/angular'
import { createDragPlugin } from '@dayflow/plugin-drag';
function MyCalendar() {
const dragPlugin = createDragPlugin({
enableDrag: true,
enableResize: true,
enableCreate: true,
onEventDrop: (updated, original) => {
console.log('Event moved:', updated);
},
onEventResize: (updated, original) => {
console.log('Event resized:', updated);
},
});
const calendar = useCalendarApp({
// ... views
plugins: [dragPlugin],
});
// ...
}
```
--------------------------------
### Milestone Event Configuration
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs/introduction/resource-timeline.mdx
Define an event as a milestone by setting its start and end dates to be equal. This configuration is used to automatically render events as milestones.
```tsx
const milestone = {
id: 'release-gate',
title: 'Release approval',
start: new Date(2026, 4, 14, 10, 0),
end: new Date(2026, 4, 14, 10, 0),
resourceId: 'eng-bob',
};
```
--------------------------------
### Custom All-Day Event Sorting
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs/introduction/use-calendar-app.mdx
Provide a custom comparator function to control the order of all-day events. This example sorts events alphabetically by title.
```tsx
const calendar = useCalendarApp({
allDaySortComparator: (a, b) => a.title.localeCompare(b.title),
});
```
--------------------------------
### Radicale CalDAV Configuration
Source: https://github.com/dayflow-js/calendar/blob/main/examples/caldav-proxy/README.md
Sets the base URL for Radicale and the calendar home URL for client-side integration. Notes on read-only defaults are provided.
```text
CALDAV_BASE_URL=https://radicale.example.com
```
```typescript
const CALENDAR_HOME_URL = '/alice/';
```
--------------------------------
### Override Specific i18n Messages
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/blog/v1.7.mdx
Provide custom messages to the DayFlowCalendar component to override specific terms in the current locale. This example overrides 'today' and 'newEvent'.
```tsx
const customMessages = {
today: 'Today!',
newEvent: 'New Appointment',
// ... override other keys
};
return ;
```
--------------------------------
### CalDAV Proxy Architecture
Source: https://github.com/dayflow-js/calendar/blob/main/examples/caldav-proxy/README.md
Illustrates the request flow from the browser through the backend proxy to the CalDAV server, highlighting where credentials are injected.
```text
Browser (DayFlow + @dayflow/caldav)
→ POST /api/caldav { url, init } (no auth)
↓
Backend proxy (proxy.mjs)
→ PROPFIND https://nextcloud.example.com/dav/...
+ Authorization: Basic ... (credentials injected here)
↓
CalDAV server
```
--------------------------------
### Set Locale with Language Code String
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/blog/v1.7.mdx
Initialize the calendar app with a language code string to use built-in translations. Example uses Japanese ('ja').
```typescript
const calendar = useCalendarApp({
// ... other config
locale: 'ja', // Set locale to Japanese
});
```
--------------------------------
### Programmatic Theme Changes
Source: https://github.com/dayflow-js/calendar/blob/main/website/content/docs/introduction/use-calendar-app.mdx
Control the calendar's theme programmatically. You can get the current theme, set a new theme, and subscribe to theme change events.
```javascript
// Get current theme
const currentTheme = calendar.app.getTheme();
// Set theme
calendar.app.setTheme('dark');
// Subscribe to theme changes
calendar.app.subscribeThemeChange(theme => {
console.log('Theme changed to:', theme);
});
```