ResourcesDayView
Day view with resource columns for scheduling across resources
Source
LLM docs
Docs
Package
Usage
ResourcesDayView displays resources as rows and time slots as columns. Each row represents
a resource (e.g., conference room, person, equipment) and shows events assigned to that
resource via the resourceId property on event data.
import dayjs from 'dayjs';
import { useState } from 'react';
import { ResourcesDayView } from '@mantine/schedule';
import { events, resources } from './data';
function Demo() {
const [date, setDate] = useState(dayjs().format('YYYY-MM-DD'));
return (
<ResourcesDayView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
startTime="08:00:00"
endTime="18:00:00"
/>
);
}All-day events
Events that span the entire day (start at 00:00:00 and end at the next day 00:00:00)
are rendered as full-width bars. Foreground all-day events are pinned to the top of the
resource row and stack when there are several; all-day events with display: 'background'
tint the whole row.
import dayjs from 'dayjs';
import { useState } from 'react';
import { ResourcesDayView } from '@mantine/schedule';
import { events, resources } from './data';
function Demo() {
const [date, setDate] = useState(dayjs().format('YYYY-MM-DD'));
return (
<ResourcesDayView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
startTime="08:00:00"
endTime="18:00:00"
/>
);
}Time range and intervals
Use startTime, endTime and intervalMinutes props to control the visible time range
and slot granularity.
import dayjs from 'dayjs';
import { useState } from 'react';
import { ResourcesDayView } from '@mantine/schedule';
import { events, resources } from './data';
function Demo() {
const [date, setDate] = useState(dayjs().format('YYYY-MM-DD'));
return (
<ResourcesDayView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
startTime="09:00:00"
endTime="17:00:00"
intervalMinutes={30}
/>
);
}Start scroll time
Use startScrollTime prop to set the initial horizontal scroll position to a specific time.
The value should be in HH:mm:ss format.
import dayjs from 'dayjs';
import { useState } from 'react';
import { ResourcesDayView } from '@mantine/schedule';
import { events, resources } from './data';
function Demo() {
const [date, setDate] = useState(dayjs().format('YYYY-MM-DD'));
return (
<ResourcesDayView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
startTime="00:00:00"
endTime="23:59:00"
startScrollTime="12:00:00"
/>
);
}Slot width and row height
Use slotWidth to control the width of each time slot column and rowHeight to control
the height of each resource row.
import dayjs from 'dayjs';
import { useState } from 'react';
import { ResourcesDayView } from '@mantine/schedule';
import { events, resources } from './data';
function Demo() {
const [date, setDate] = useState(dayjs().format('YYYY-MM-DD'));
return (
<ResourcesDayView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
startTime="08:00:00"
endTime="18:00:00"
slotWidth={120}
rowHeight={80}
/>
);
}Custom resource label
Use renderResourceLabel prop to customize the resource label rendering in the left column.
Meeting room: Tokyo
Floor 2
Meeting room: Paris
Floor 2
Meeting room: New York
Floor 2
Meeting room: London
Floor 2
import dayjs from 'dayjs';
import { useState } from 'react';
import { Stack, Text } from '@mantine/core';
import { ResourcesDayView } from '@mantine/schedule';
import { events, resources } from './data';
function Demo() {
const [date, setDate] = useState(dayjs().format('YYYY-MM-DD'));
return (
<ResourcesDayView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
startTime="08:00:00"
endTime="18:00:00"
renderResourceLabel={(resource) => (
<Stack gap={2} align="flex-start">
<Text size="sm" fw={600}>{resource.label}</Text>
<Text size="xs" c="dimmed">Floor 2</Text>
</Stack>
)}
/>
);
}Resource groups
Use groups prop to group resources under labeled headers. The group labels are displayed
as a column to the left of resource labels, spanning vertically across their resources.
Use renderGroupLabel to customize group label rendering and groupLabelWidth to control
the group column width.
import dayjs from 'dayjs';
import { useState } from 'react';
import { ResourcesDayView, ScheduleResourceGroup } from '@mantine/schedule';
import { events } from './data';
const resources = [
{ id: 'tokyo', label: 'Meeting room: Tokyo' },
{ id: 'paris', label: 'Meeting room: Paris' },
{ id: 'new-york', label: 'Meeting room: New York' },
{ id: 'london', label: 'Meeting room: London' },
{ id: 'overflow', label: 'Overflow room' },
];
const groups: ScheduleResourceGroup[] = [
{ label: 'Floor 1', resourceIds: ['tokyo', 'paris'] },
{ label: 'Floor 2', resourceIds: ['new-york', 'london'] },
];
function Demo() {
const [date, setDate] = useState(dayjs().format('YYYY-MM-DD'));
return (
<ResourcesDayView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
groups={groups}
startTime="08:00:00"
endTime="18:00:00"
/>
);
}Custom event rendering
Use renderEvent prop to fully customize event rendering.
import { useState } from 'react';
import dayjs from 'dayjs';
import { HoverCard, UnstyledButton } from '@mantine/core';
import { ResourcesDayView, ScheduleEventData } from '@mantine/schedule';
import { EventDetails } from './EventDetails';
import { events as initialEvents, resources } from './data';
function Demo() {
const [date, setDate] = useState(dayjs().format('YYYY-MM-DD'));
const [events, setEvents] = useState<ScheduleEventData[]>(initialEvents);
return (
<ResourcesDayView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
startTime="08:00:00"
endTime="18:00:00"
withEventsDragAndDrop
onEventDrop={({ eventId, newStart, newEnd, resourceId }) => {
setEvents((current) =>
current.map((event) =>
event.id === eventId
? { ...event, start: newStart, end: newEnd, resourceId }
: event
)
);
}}
renderEvent={(event, props) => (
<HoverCard width={280} position="bottom" closeDelay={0} transitionProps={{ duration: 0 }}>
<HoverCard.Target>
<UnstyledButton {...props} />
</HoverCard.Target>
<HoverCard.Dropdown>
<EventDetails event={event} />
</HoverCard.Dropdown>
</HoverCard>
)}
/>
);
}Drag and drop
Enable cross-resource drag and drop with withEventsDragAndDrop prop. The onEventDrop callback
receives the target resourceId as the fifth argument, allowing you to update the event's resource
assignment.
import dayjs from 'dayjs';
import { useState } from 'react';
import { ResourcesDayView, ScheduleEventData } from '@mantine/schedule';
import { events as initialEvents, resources } from './data';
function Demo() {
const [date, setDate] = useState(dayjs().format('YYYY-MM-DD'));
const [events, setEvents] = useState<ScheduleEventData[]>(initialEvents);
return (
<ResourcesDayView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
startTime="08:00:00"
endTime="18:00:00"
withEventsDragAndDrop
onEventDrop={({ eventId, newStart, newEnd, resourceId }) => {
setEvents((current) =>
current.map((event) =>
event.id === eventId
? { ...event, start: newStart, end: newEnd, resourceId }
: event
)
);
}}
/>
);
}External drag and drop
You can drag external items onto the schedule using onExternalEventDrop prop.
Drag to schedule
Quick Sync
30 min
Workshop
120 min
One-on-One
60 min
import { useRef, useState } from 'react';
import dayjs from 'dayjs';
import { Box, Grid, Text } from '@mantine/core';
import { ResourcesDayView, ScheduleEventData } from '@mantine/schedule';
const today = dayjs().format('YYYY-MM-DD');
const resources = [
{ id: 'tokyo', label: 'Tokyo' },
{ id: 'paris', label: 'Paris' },
{ id: 'new-york', label: 'New York' },
{ id: 'london', label: 'London' },
];
const sidebarItems = [
{ title: 'Quick Sync', duration: 30, color: 'teal' },
{ title: 'Workshop', duration: 120, color: 'orange' },
{ title: 'One-on-One', duration: 60, color: 'violet' },
];
function Demo() {
const [date, setDate] = useState(dayjs().format('YYYY-MM-DD'));
const [events, setEvents] = useState<ScheduleEventData[]>([]);
const nextId = useRef(1);
const handleExternalDrop = ({
dataTransfer,
dropDateTime,
resourceId,
}: {
dataTransfer: DataTransfer;
dropDateTime: string;
resourceId?: string | number;
}) => {
const raw = dataTransfer.getData('text/plain');
if (!raw) {
return;
}
const data = JSON.parse(raw);
const start = dayjs(dropDateTime);
const end = start.add(data.duration, 'minutes');
setEvents((prev) => [
...prev,
{
id: nextId.current++,
title: data.title,
start: start.format('YYYY-MM-DD HH:mm:ss'),
end: end.format('YYYY-MM-DD HH:mm:ss'),
color: data.color,
resourceId,
},
]);
};
const handleEventDrop = ({
eventId,
newStart,
newEnd,
resourceId,
}: {
eventId: string | number;
newStart: string;
newEnd: string;
event: ScheduleEventData;
resourceId?: string | number;
}) => {
setEvents((prev) =>
prev.map((event) =>
event.id === eventId ? { ...event, start: newStart, end: newEnd, resourceId } : event
)
);
};
return (
<Grid>
<Grid.Col span={{ base: 12, sm: 3 }}>
<Text fw={500} mb="xs">Drag to schedule</Text>
{sidebarItems.map((item) => (
<Box
key={item.title}
draggable
onDragStart={(e) => {
e.dataTransfer.setData('text/plain', JSON.stringify(item));
e.dataTransfer.effectAllowed = 'copy';
}}
style={{
padding: '8px 12px',
marginBottom: 8,
borderRadius: 4,
cursor: 'grab',
backgroundColor: `var(--mantine-color-${item.color}-light)`,
color: `var(--mantine-color-${item.color}-light-color)`,
}}
>
<Text size="sm" fw={500}>{item.title}</Text>
<Text size="xs">{item.duration} min</Text>
</Box>
))}
</Grid.Col>
<Grid.Col span={{ base: 12, sm: 9 }}>
<ResourcesDayView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
startTime="08:00:00"
endTime="18:00:00"
withEventsDragAndDrop
onEventDrop={handleEventDrop}
onExternalEventDrop={handleExternalDrop}
/>
</Grid.Col>
</Grid>
);
}Bidirectional drag and drop
Events can be dragged both within the schedule and to an external area.
Unscheduled
Quick Sync
30 min
Workshop
120 min
One-on-One
60 min
import { useRef, useState } from 'react';
import dayjs from 'dayjs';
import { Box, Grid, Text } from '@mantine/core';
import { ResourcesDayView, ScheduleEventData } from '@mantine/schedule';
const today = dayjs().format('YYYY-MM-DD');
const resources = [
{ id: 'tokyo', label: 'Tokyo' },
{ id: 'paris', label: 'Paris' },
{ id: 'new-york', label: 'New York' },
{ id: 'london', label: 'London' },
];
interface SidebarItem {
title: string;
duration: number;
color: string;
}
const initialSidebarItems: SidebarItem[] = [
{ title: 'Quick Sync', duration: 30, color: 'teal' },
{ title: 'Workshop', duration: 120, color: 'orange' },
{ title: 'One-on-One', duration: 60, color: 'violet' },
];
function Demo() {
const [date, setDate] = useState(dayjs().format('YYYY-MM-DD'));
const [sidebarItems, setSidebarItems] = useState(initialSidebarItems);
const [events, setEvents] = useState<ScheduleEventData[]>([]);
const [sidebarHighlight, setSidebarHighlight] = useState(false);
const nextId = useRef(1);
const handleExternalDrop = ({
dataTransfer,
dropDateTime,
resourceId,
}: {
dataTransfer: DataTransfer;
dropDateTime: string;
resourceId?: string | number;
}) => {
const raw = dataTransfer.getData('text/plain');
if (!raw) {
return;
}
const data = JSON.parse(raw);
const start = dayjs(dropDateTime);
const end = start.add(data.duration, 'minutes');
setEvents((prev) => [
...prev,
{
id: nextId.current++,
title: data.title,
start: start.format('YYYY-MM-DD HH:mm:ss'),
end: end.format('YYYY-MM-DD HH:mm:ss'),
color: data.color,
resourceId,
},
]);
setSidebarItems((prev) => prev.filter((item) => item.title !== data.title));
};
const handleEventDrop = ({
eventId,
newStart,
newEnd,
resourceId,
}: {
eventId: string | number;
newStart: string;
newEnd: string;
event: ScheduleEventData;
resourceId?: string | number;
}) => {
setEvents((prev) =>
prev.map((event) =>
event.id === eventId ? { ...event, start: newStart, end: newEnd, resourceId } : event
)
);
};
const handleSidebarDrop = (e: React.DragEvent) => {
e.preventDefault();
setSidebarHighlight(false);
const raw = e.dataTransfer.getData('application/json');
if (!raw) {
return;
}
const { eventId } = JSON.parse(raw);
const event = events.find((ev) => String(ev.id) === String(eventId));
if (!event) {
return;
}
const duration = dayjs(event.end).diff(dayjs(event.start), 'minutes');
setSidebarItems((prev) => [
...prev,
{ title: event.title, duration, color: event.color || 'blue' },
]);
setEvents((prev) => prev.filter((ev) => ev.id !== event.id));
};
return (
<Grid>
<Grid.Col span={{ base: 12, sm: 3 }}>
<Box
onDragOver={(e) => {
e.preventDefault();
e.dataTransfer.dropEffect = 'move';
setSidebarHighlight(true);
}}
onDragLeave={() => setSidebarHighlight(false)}
onDrop={handleSidebarDrop}
style={{
padding: 8,
borderRadius: 8,
border: sidebarHighlight
? '2px dashed var(--mantine-color-blue-5)'
: '2px dashed transparent',
transition: 'border-color 150ms',
}}
>
<Text fw={500} mb="xs">Unscheduled</Text>
{sidebarItems.map((item) => (
<Box
key={item.title}
draggable
onDragStart={(e) => {
e.dataTransfer.setData('text/plain', JSON.stringify(item));
e.dataTransfer.effectAllowed = 'copy';
}}
style={{
padding: '8px 12px',
marginBottom: 8,
borderRadius: 4,
cursor: 'grab',
backgroundColor: `var(--mantine-color-${item.color}-light)`,
color: `var(--mantine-color-${item.color}-light-color)`,
}}
>
<Text size="sm" fw={500}>{item.title}</Text>
<Text size="xs">{item.duration} min</Text>
</Box>
))}
{sidebarItems.length === 0 && (
<Text size="xs" c="dimmed">Drag events here to unschedule</Text>
)}
</Box>
</Grid.Col>
<Grid.Col span={{ base: 12, sm: 9 }}>
<ResourcesDayView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
startTime="08:00:00"
endTime="18:00:00"
withEventsDragAndDrop
onEventDrop={handleEventDrop}
onExternalEventDrop={handleExternalDrop}
/>
</Grid.Col>
</Grid>
);
}Event resize
Enable event resizing with withEventResize prop. Events can be resized by dragging
their left or right edges.
import dayjs from 'dayjs';
import { useState } from 'react';
import { ResourcesDayView, ScheduleEventData } from '@mantine/schedule';
import { events as initialEvents, resources } from './data';
function Demo() {
const [date, setDate] = useState(dayjs().format('YYYY-MM-DD'));
const [events, setEvents] = useState<ScheduleEventData[]>(initialEvents);
return (
<ResourcesDayView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
startTime="08:00:00"
endTime="18:00:00"
withEventResize
onEventResize={({ eventId, newStart, newEnd }) => {
setEvents((current) =>
current.map((event) =>
event.id === eventId
? { ...event, start: newStart, end: newEnd }
: event
)
);
}}
/>
);
}Event form
Click on a time slot or drag to select a range to create a new event. Click on an existing event to edit it.
import dayjs from 'dayjs';
import { useState } from 'react';
import { Select } from '@mantine/core';
import { ResourcesDayView, ScheduleEventData } from '@mantine/schedule';
import { EventData, EventForm } from './EventForm';
import { events as initialEvents, resources } from './data';
function Demo() {
const [date, setDate] = useState(dayjs().format('YYYY-MM-DD'));
const [events, setEvents] = useState<ScheduleEventData[]>(initialEvents);
const [formOpened, setFormOpened] = useState(false);
const [selectedEventData, setSelectedEventData] = useState<EventData | null>(null);
const [selectedResourceId, setSelectedResourceId] = useState<string | null>(
String(resources[0].id)
);
const handleTimeSlotClick = ({
slotStart,
slotEnd,
resourceId,
}: {
slotStart: string;
slotEnd: string;
nativeEvent: React.MouseEvent;
resourceId?: string | number;
}) => {
setSelectedResourceId(resourceId ? String(resourceId) : String(resources[0].id));
setSelectedEventData({
title: '',
start: new Date(slotStart),
end: new Date(slotEnd),
color: 'blue',
});
setFormOpened(true);
};
const handleEventClick = (event: ScheduleEventData) => {
setSelectedResourceId(event.resourceId ? String(event.resourceId) : String(resources[0].id));
setSelectedEventData({
id: event.id,
title: event.title,
start: new Date(event.start),
end: new Date(event.end),
color: event.color || 'blue',
});
setFormOpened(true);
};
const handleSubmit = (values: EventData) => {
if (values.id) {
setEvents((prev) =>
prev.map((event) =>
event.id === values.id
? {
...event,
title: values.title,
start: dayjs(values.start).format('YYYY-MM-DD HH:mm:ss'),
end: dayjs(values.end).format('YYYY-MM-DD HH:mm:ss'),
color: values.color || 'blue',
resourceId: selectedResourceId || resources[0].id,
}
: event
)
);
} else {
setEvents((prev) => [
...prev,
{
id: Date.now(),
title: values.title,
start: dayjs(values.start).format('YYYY-MM-DD HH:mm:ss'),
end: dayjs(values.end).format('YYYY-MM-DD HH:mm:ss'),
color: values.color || 'blue',
resourceId: selectedResourceId || resources[0].id,
},
]);
}
};
const handleSlotDragEnd = ({
rangeStart,
rangeEnd,
resourceId,
}: {
rangeStart: string;
rangeEnd: string;
resourceId?: string | number;
}) => {
setSelectedResourceId(resourceId ? String(resourceId) : String(resources[0].id));
setSelectedEventData({
title: '',
start: new Date(rangeStart),
end: new Date(rangeEnd),
color: 'blue',
});
setFormOpened(true);
};
const handleDeleteEvent = () => {
if (selectedEventData?.id) {
setEvents((prev) => prev.filter((event) => event.id !== selectedEventData.id));
}
};
return (
<>
<ResourcesDayView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
startTime="08:00:00"
endTime="18:00:00"
withDragSlotSelect
onTimeSlotClick={handleTimeSlotClick}
onSlotDragEnd={handleSlotDragEnd}
onEventClick={handleEventClick}
/>
<EventForm
opened={formOpened}
onClose={() => setFormOpened(false)}
onExitTransitionEnd={() => setSelectedEventData(null)}
values={selectedEventData}
onSubmit={handleSubmit}
onDelete={selectedEventData?.id ? handleDeleteEvent : undefined}
>
<Select
label="Conference Room"
placeholder="Select a room"
radius="md"
data={resources.map((r) => ({ value: String(r.id), label: String(r.label) }))}
value={selectedResourceId}
onChange={setSelectedResourceId}
/>
</EventForm>
</>
);
}Business hours
Use highlightBusinessHours prop to visually distinguish business hours from non-business hours
across all time slot columns.
import dayjs from 'dayjs';
import { useState } from 'react';
import { ResourcesDayView } from '@mantine/schedule';
import { events, resources } from './data';
function Demo() {
const [date, setDate] = useState(dayjs().format('YYYY-MM-DD'));
return (
<ResourcesDayView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
startTime="07:00:00"
endTime="20:00:00"
highlightBusinessHours
businessHours={['09:00:00', '17:00:00']}
/>
);
}Current time indicator
Use withCurrentTimeIndicator to display a line at the current time. Set withCurrentTimeBubble={false}
to hide the time bubble label.
import { ResourcesDayView } from '@mantine/schedule';
import { events, resources } from './data';
function Demo() {
return (
<ResourcesDayView
date={new Date()}
resources={resources}
events={events}
withCurrentTimeIndicator
withCurrentTimeBubble={false}
/>
);
}Event permissions
Use canDragEvent and canResizeEvent to control which events can be dragged or resized.
Events with payload.locked set to true cannot be moved or resized.
import { useState } from 'react';
import dayjs from 'dayjs';
import { ResourcesDayView, ScheduleEventData } from '@mantine/schedule';
const today = dayjs().format('YYYY-MM-DD');
const resources = [
{ id: 'tokyo', label: 'Meeting room: Tokyo' },
{ id: 'paris', label: 'Meeting room: Paris' },
{ id: 'new-york', label: 'Meeting room: New York' },
];
const initialEvents: ScheduleEventData[] = [
{
id: 1,
title: 'Draggable & Resizable',
start: `${today} 09:00:00`,
end: `${today} 10:00:00`,
color: 'blue',
resourceId: 'tokyo',
},
{
id: 2,
title: 'Locked Event',
start: `${today} 11:00:00`,
end: `${today} 12:00:00`,
color: 'gray',
resourceId: 'paris',
payload: { locked: true },
},
{
id: 3,
title: 'Another Movable',
start: `${today} 14:00:00`,
end: `${today} 15:00:00`,
color: 'green',
resourceId: 'new-york',
},
];
function Demo() {
const [events, setEvents] = useState(initialEvents);
const handleEventDrop = ({
eventId,
newStart,
newEnd,
resourceId,
}: {
eventId: string | number;
newStart: string;
newEnd: string;
event: ScheduleEventData;
resourceId?: string | number;
}) => {
setEvents((prev) =>
prev.map((event) =>
event.id === eventId ? { ...event, start: newStart, end: newEnd, resourceId } : event
)
);
};
const handleEventResize = ({ eventId, newStart, newEnd }: { eventId: string | number; newStart: string; newEnd: string; event: ScheduleEventData }) => {
setEvents((prev) =>
prev.map((event) =>
event.id === eventId ? { ...event, start: newStart, end: newEnd } : event
)
);
};
return (
<ResourcesDayView
date={new Date()}
resources={resources}
events={events}
startTime="08:00:00"
endTime="18:00:00"
withEventsDragAndDrop
withEventResize
onEventDrop={handleEventDrop}
onEventResize={handleEventResize}
canDragEvent={(event) => !event.payload?.locked}
canResizeEvent={(event) => !event.payload?.locked}
/>
);
}Recurring events
ResourcesDayView automatically expands recurring events for the visible day. See Recurring events guide for full documentation.
import dayjs from 'dayjs';
import { useState } from 'react';
import { ResourcesDayView } from '@mantine/schedule';
const today = dayjs().format('YYYY-MM-DD');
const resources = [
{ id: 'tokyo', label: 'Meeting room: Tokyo' },
{ id: 'paris', label: 'Meeting room: Paris' },
];
const events = [
{
id: 'daily-sync-series',
title: 'Daily sync (series)',
start: `${dayjs(today).subtract(2, 'day').format('YYYY-MM-DD')} 09:00:00`,
end: `${dayjs(today).subtract(2, 'day').format('YYYY-MM-DD')} 11:00:00`,
color: 'blue',
resourceId: 'tokyo',
recurrence: {
rrule: 'FREQ=DAILY;COUNT=10',
exdate: [`${today} 09:00:00`],
},
},
{
id: 'daily-sync-override',
title: 'Daily sync (moved today)',
start: `${today} 14:00:00`,
end: `${today} 16:00:00`,
color: 'grape',
resourceId: 'tokyo',
recurringEventId: 'daily-sync-series',
recurrenceId: `${today} 09:00:00`,
},
{
id: 'one-off',
title: 'One-off planning',
start: `${today} 11:00:00`,
end: `${today} 13:00:00`,
color: 'green',
resourceId: 'paris',
},
];
function Demo() {
const [date, setDate] = useState(today);
return (
<ResourcesDayView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
startTime="08:00:00"
endTime="18:00:00"
/>
);
}Max events per time slot
Use maxEventsPerTimeSlot prop to limit the number of visible overlapping events per time slot.
When events exceed the limit, a "+N more" indicator is displayed. Clicking the indicator opens
a popover with all events in the group. Use moreEventsProps to customize the popover behavior.
import dayjs from 'dayjs';
import { useState } from 'react';
import { ResourcesDayView, ScheduleEventData, ScheduleResourceData } from '@mantine/schedule';
const today = dayjs().format('YYYY-MM-DD');
const resources: ScheduleResourceData[] = [
{ id: 'tokyo', label: 'Meeting room: Tokyo' },
{ id: 'paris', label: 'Meeting room: Paris' },
];
const events: ScheduleEventData[] = [
// ... many overlapping events per resource
];
function Demo() {
const [date, setDate] = useState(dayjs().format('YYYY-MM-DD'));
return (
<ResourcesDayView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
startTime="08:00:00"
endTime="18:00:00"
maxEventsPerTimeSlot={2}
/>
);
}Radius
import dayjs from 'dayjs';
import { useState } from 'react';
import { ResourcesDayView } from '@mantine/schedule';
import { events, resources } from './data';
function Demo() {
const [date, setDate] = useState(dayjs().format('YYYY-MM-DD'));
return (
<ResourcesDayView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
startTime="08:00:00"
endTime="18:00:00"
radius="md"
/>
);
}Scroll area props
Use scrollAreaProps to customize the scroll area, for example to increase the scrollbar size
and offset scrollbars.
import dayjs from 'dayjs';
import { useState } from 'react';
import { ResourcesDayView } from '@mantine/schedule';
import { events, resources } from './data';
function Demo() {
const [date, setDate] = useState(dayjs().format('YYYY-MM-DD'));
return (
<ResourcesDayView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
startTime="00:00:00"
endTime="23:59:00"
scrollAreaProps={{
scrollbarSize: 10,
offsetScrollbars: true,
type: 'always',
scrollbars: 'x',
}}
/>
);
}Localization
Use locale prop to change the date formatting locale, slotLabelFormat for time format,
and labels to override UI labels.
import 'dayjs/locale/es';
import dayjs from 'dayjs';
import { useState } from 'react';
import { ResourcesDayView } from '@mantine/schedule';
import { events, resources } from './data';
function Demo() {
const [date, setDate] = useState(dayjs().format('YYYY-MM-DD'));
return (
<ResourcesDayView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
startTime="08:00:00"
endTime="18:00:00"
locale="es"
labels={{
day: 'Día',
week: 'Semana',
month: 'Mes',
year: 'Año',
allDay: 'Todo el día',
timeSlot: 'Franja horaria',
today: 'Hoy',
previous: 'Anterior',
next: 'Siguiente',
resources: 'Recursos',
}}
/>
);
}Static mode
Set mode="static" to disable all interactions. Events and time slots become non-interactive,
useful for display-only views.
import dayjs from 'dayjs';
import { useState } from 'react';
import { ResourcesDayView } from '@mantine/schedule';
import { events, resources } from './data';
function Demo() {
const [date, setDate] = useState(dayjs().format('YYYY-MM-DD'));
return (
<ResourcesDayView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
startTime="08:00:00"
endTime="18:00:00"
mode="static"
/>
);
}