ResourcesWeekView
Week view with resource rows for scheduling across resources
Source
LLM docs
Docs
Package
Usage
ResourcesWeekView displays resources as rows and a full week of time slots as columns
with a two-level header showing day names and time labels. 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 { ResourcesWeekView } from '@mantine/schedule';
import { events, resources } from './data';
function Demo() {
const today = dayjs().format('YYYY-MM-DD');
const [date, setDate] = useState(today);
return (
<ResourcesWeekView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
startTime="08:00:00"
endTime="18:00:00"
startScrollDateTime={`${today} 08:00:00`}
/>
);
}All-day events
Events that span a whole day (start at 00:00:00 and end at the next day 00:00:00) are
rendered as full-width bars within their day column. Foreground all-day events are pinned to
the top of the column and stack when there are several; all-day events with
display: 'background' tint the whole day column.
import dayjs from 'dayjs';
import { useState } from 'react';
import { ResourcesWeekView } from '@mantine/schedule';
import { events, resources } from './data';
function Demo() {
const today = dayjs().format('YYYY-MM-DD');
const [date, setDate] = useState(today);
return (
<ResourcesWeekView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
startTime="08:00:00"
endTime="18:00:00"
startScrollDateTime={`${today} 08:00:00`}
/>
);
}Interactive background events
Set withInteractiveBackgroundEvents prop to make background events clickable. onEventClick
is called the same way as for regular events, use event.display === 'background' to tell them apart.
Interactive background events cover the time slots underneath them and cannot be dragged.
Last clicked: nothing yet
import dayjs from 'dayjs';
import { useState } from 'react';
import { Text } from '@mantine/core';
import { ResourcesWeekView, ScheduleEventData } from '@mantine/schedule';
import { events, resources } from './data';
function Demo() {
const today = dayjs().format('YYYY-MM-DD');
const [date, setDate] = useState(today);
const [clicked, setClicked] = useState<ScheduleEventData | null>(null);
return (
<>
<Text size="sm" mb="md">
Last clicked:{' '}
{clicked
? `${clicked.title} (${clicked.display === 'background' ? 'background' : 'regular'} event)`
: 'nothing yet'}
</Text>
<ResourcesWeekView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
withInteractiveBackgroundEvents
onEventClick={setClicked}
startTime="08:00:00"
endTime="18:00:00"
startScrollDateTime={`${today} 08:00:00`}
/>
</>
);
}Resizable background events
Set both withEventResize and withInteractiveBackgroundEvents to allow resizing
background events. All-day background events cannot be resized. To resize only regular
events, return false from canResizeEvent:
<ResourcesWeekView
withEventResize
withInteractiveBackgroundEvents
canResizeEvent={(event) => event.display !== 'background'}
/>Drag and drop
Enable drag and drop with withEventsDragAndDrop prop. The onEventDrop callback receives
the resourceId of the target resource, use it to update the event's resource.
Events can be dragged across both resources and days.
To reject a drop based on where the event lands, for example to prevent double booking, use
preventEventOverlap and canDropEvent, see drop validation.
In resource views, the event is checked against the events of the target resource.
import dayjs from 'dayjs';
import { useState } from 'react';
import { ResourcesWeekView, ScheduleEventData } from '@mantine/schedule';
import { events as initialEvents, resources } from './data';
function Demo() {
const today = dayjs().format('YYYY-MM-DD');
const [date, setDate] = useState(today);
const [events, setEvents] = useState<ScheduleEventData[]>(initialEvents);
return (
<ResourcesWeekView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
startTime="08:00:00"
endTime="18:00:00"
startScrollDateTime={`${today} 08:00:00`}
withEventsDragAndDrop
onEventDrop={({ eventId, newStart, newEnd, resourceId }) => {
setEvents((current) =>
current.map((event) =>
event.id === eventId
? { ...event, start: newStart, end: newEnd, resourceId }
: event
)
);
}}
/>
);
}Drag interval
By default, dragged events snap to intervalMinutes. Set eventDragInterval to use a different
step, for example to move events in 15-minute increments on a grid with 30-minute slots.
A ghost preview shows where the event will land:
import dayjs from 'dayjs';
import { useState } from 'react';
import { ResourcesWeekView, ScheduleEventData } from '@mantine/schedule';
import { events as initialEvents, resources } from './data';
function Demo() {
const today = dayjs().format('YYYY-MM-DD');
const [date, setDate] = useState(today);
const [events, setEvents] = useState<ScheduleEventData[]>(initialEvents);
return (
<ResourcesWeekView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
startTime="08:00:00"
endTime="18:00:00"
intervalMinutes={30}
eventDragInterval={15}
startScrollDateTime={`${today} 08:00:00`}
withEventsDragAndDrop
onEventDrop={({ eventId, newStart, newEnd, resourceId }) => {
setEvents((current) =>
current.map((event) =>
event.id === eventId
? { ...event, start: newStart, end: newEnd, resourceId }
: event
)
);
}}
/>
);
}Event form
Use onTimeSlotClick, onSlotDragEnd, and onEventClick callbacks to open a form
for creating or editing events. Combine with withDragSlotSelect to allow selecting
a time range by dragging across slots.
import dayjs from 'dayjs';
import { useState } from 'react';
import { Select } from '@mantine/core';
import { ResourcesWeekView, ScheduleEventData } from '@mantine/schedule';
import { EventData, EventForm } from './EventForm';
import { events as initialEvents, resources } from './data';
function Demo() {
const today = dayjs().format('YYYY-MM-DD');
const [date, setDate] = useState(today);
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: string,
slotEnd: string,
_e: 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: 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 (
<>
<ResourcesWeekView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
startTime="08:00:00"
endTime="18:00:00"
startScrollDateTime={`${today} 08: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>
</>
);
}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 { ResourcesWeekView } from '@mantine/schedule';
import { events, resources } from './data';
function Demo() {
const today = dayjs().format('YYYY-MM-DD');
const [date, setDate] = useState(today);
return (
<ResourcesWeekView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
startTime="09:00:00"
endTime="17:00:00"
intervalMinutes={30}
startScrollDateTime={`${today} 09:00:00`}
/>
);
}Multi-hour intervals
intervalMinutes accepts values that divide evenly into an hour (for example 15 or 30)
or whole numbers of hours (for example 120 or 240).
import dayjs from 'dayjs';
import { useState } from 'react';
import { SegmentedControl, Stack } from '@mantine/core';
import { ResourcesWeekView } from '@mantine/schedule';
import { events, resources } from './data';
function Demo() {
const today = dayjs().format('YYYY-MM-DD');
const [date, setDate] = useState(today);
const [intervalMinutes, setIntervalMinutes] = useState('240');
return (
<Stack>
<SegmentedControl
value={intervalMinutes}
onChange={setIntervalMinutes}
data={[
{ label: '1 hour', value: '60' },
{ label: '2 hours', value: '120' },
{ label: '4 hours', value: '240' },
]}
/>
<ResourcesWeekView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
startTime="08:00:00"
endTime="20:00:00"
intervalMinutes={Number(intervalMinutes)}
startScrollDateTime={`${today} 08:00:00`}
/>
</Stack>
);
}Current time indicator
Use withCurrentTimeIndicator to display a line at the current time. Set withCurrentTimeBubble={false}
to hide the time bubble label.
import dayjs from 'dayjs';
import { useState } from 'react';
import { ResourcesWeekView } from '@mantine/schedule';
import { events, resources } from './data';
function Demo() {
const [date, setDate] = useState(dayjs().format('YYYY-MM-DD'));
return (
<ResourcesWeekView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
startTime="00:00:00"
endTime="23:59:59"
withCurrentTimeIndicator
withCurrentTimeBubble={false}
/>
);
}Current time indicator in a different timezone
@mantine/schedule does not perform timezone conversions, the current time indicator
is positioned based on the user's local time. To display it in a different timezone, pass
a function that returns the current time to getCurrentTime prop. The example below uses
the dayjs timezone plugin:
import { useState } from 'react';
import dayjs from 'dayjs';
import timezone from 'dayjs/plugin/timezone';
import utc from 'dayjs/plugin/utc';
import { Select, Stack } from '@mantine/core';
import { ResourcesWeekView } from '@mantine/schedule';
import { getEvents, resources } from './data';
dayjs.extend(utc);
dayjs.extend(timezone);
const timezones = ['UTC', 'America/New_York', 'Europe/Berlin', 'Asia/Kolkata', 'Asia/Tokyo'];
function Demo() {
const [tz, setTz] = useState('UTC');
// getCurrentTime is called on every tick, so the indicator keeps updating
const getCurrentTime = () => dayjs().tz(tz).format('YYYY-MM-DD HH:mm:ss');
const currentDate = getCurrentTime().split(' ')[0];
return (
<Stack>
<Select
label="Display timezone"
data={timezones}
value={tz}
onChange={(value) => setTz(value!)}
allowDeselect={false}
/>
<ResourcesWeekView
date={currentDate}
resources={resources}
events={getEvents(currentDate)}
startScrollDateTime={dayjs(getCurrentTime()).subtract(2, 'hour').format('YYYY-MM-DD HH:mm:ss')}
getCurrentTime={getCurrentTime}
/>
</Stack>
);
}First day of week
Use firstDayOfWeek to set the first day of the week. Set weekdayFormat to customize
the day label format.
import dayjs from 'dayjs';
import { useState } from 'react';
import { ResourcesWeekView } from '@mantine/schedule';
import { events, resources } from './data';
function Demo() {
const [date, setDate] = useState(dayjs().format('YYYY-MM-DD'));
return (
<ResourcesWeekView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
startTime="08:00:00"
endTime="18:00:00"
firstDayOfWeek={0}
withWeekendDays
weekdayFormat="dddd D"
/>
);
}Custom week label
Use renderWeekLabel to fully customize the week label in the header.
Use weekLabelFormat instead if you only need to change the date format.
import dayjs from 'dayjs';
import { useState } from 'react';
import { ResourcesWeekView } from '@mantine/schedule';
import { events, resources } from './data';
function Demo() {
const [date, setDate] = useState(dayjs().format('YYYY-MM-DD'));
return (
<ResourcesWeekView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
startTime="08:00:00"
endTime="18:00:00"
renderWeekLabel={({ weekStart, weekEnd }) =>
`Week of ${dayjs(weekStart).format('MMM D')} – ${dayjs(weekEnd).format('MMM D, YYYY')}`
}
/>
);
}Business hours
Use highlightBusinessHours prop to visually distinguish business hours from non-business hours.
import dayjs from 'dayjs';
import { useState } from 'react';
import { ResourcesWeekView } from '@mantine/schedule';
import { events, resources } from './data';
function Demo() {
const today = dayjs().format('YYYY-MM-DD');
const [date, setDate] = useState(today);
return (
<ResourcesWeekView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
startTime="07:00:00"
endTime="20:00:00"
startScrollDateTime={`${today} 08:00:00`}
highlightBusinessHours
businessHours={['09:00:00', '17:00:00']}
/>
);
}Without weekend days
Set withWeekendDays={false} to hide weekend days from the view.
import dayjs from 'dayjs';
import { useState } from 'react';
import { ResourcesWeekView } from '@mantine/schedule';
import { events, resources } from './data';
function Demo() {
const today = dayjs().format('YYYY-MM-DD');
const [date, setDate] = useState(today);
return (
<ResourcesWeekView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
startTime="08:00:00"
endTime="18:00:00"
startScrollDateTime={`${today} 08:00:00`}
withWeekendDays={false}
/>
);
}Custom resource label
Use renderResourceLabel prop to customize how resource labels are rendered.
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 { ResourcesWeekView } from '@mantine/schedule';
import { events, resources } from './data';
function Demo() {
const today = dayjs().format('YYYY-MM-DD');
const [date, setDate] = useState(today);
return (
<ResourcesWeekView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
startTime="08:00:00"
endTime="18:00:00"
startScrollDateTime={`${today} 08: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 { ResourcesWeekView, 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 today = dayjs().format('YYYY-MM-DD');
const [date, setDate] = useState(today);
return (
<ResourcesWeekView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
groups={groups}
startTime="08:00:00"
endTime="18:00:00"
startScrollDateTime={`${today} 08:00:00`}
/>
);
}Custom event rendering
Use renderEvent prop to customize how events are rendered. The example below
shows event details in a hover card.
import { useState } from 'react';
import dayjs from 'dayjs';
import { HoverCard, UnstyledButton } from '@mantine/core';
import { ResourcesWeekView, ScheduleEventData } from '@mantine/schedule';
import { EventDetails } from './EventDetails';
import { events as initialEvents, resources } from './data';
function Demo() {
const today = dayjs().format('YYYY-MM-DD');
const [date, setDate] = useState(today);
const [events, setEvents] = useState<ScheduleEventData[]>(initialEvents);
return (
<ResourcesWeekView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
startTime="08:00:00"
endTime="18:00:00"
startScrollDateTime={`${today} 08: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>
)}
/>
);
}Recurring events
ResourcesWeekView automatically expands recurring events for the visible week. See Recurring events guide for full documentation.
import dayjs from 'dayjs';
import { useState } from 'react';
import { ResourcesWeekView } 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 (
<ResourcesWeekView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
startTime="08:00:00"
endTime="18:00:00"
startScrollDateTime={`${today} 08:00:00`}
/>
);
}Max events per time slot
Use maxEventsPerTimeSlot prop to limit the number of visible overlapping events per time slot.
The "+N more" indicator opens a popover with all events of the group, use moreEventsProps
to customize it.
import dayjs from 'dayjs';
import { useState } from 'react';
import { ResourcesWeekView, 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 (
<ResourcesWeekView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
startTime="08:00:00"
endTime="18:00:00"
startScrollDateTime={`${today} 08:00:00`}
maxEventsPerTimeSlot={2}
/>
);
}Localization
Use locale prop to set the locale for date formatting and labels prop to override
default labels.
import 'dayjs/locale/es';
import dayjs from 'dayjs';
import { useState } from 'react';
import { ResourcesWeekView } from '@mantine/schedule';
import { events, resources } from './data';
function Demo() {
const today = dayjs().format('YYYY-MM-DD');
const [date, setDate] = useState(today);
return (
<ResourcesWeekView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
startTime="08:00:00"
endTime="18:00:00"
startScrollDateTime={`${today} 08: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',
}}
/>
);
}Radius
Use radius prop to change the border radius of events.
import dayjs from 'dayjs';
import { useState } from 'react';
import { ResourcesWeekView } from '@mantine/schedule';
import { events, resources } from './data';
function Demo() {
const today = dayjs().format('YYYY-MM-DD');
const [date, setDate] = useState(today);
return (
<ResourcesWeekView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
startTime="08:00:00"
endTime="18:00:00"
startScrollDateTime={`${today} 08:00:00`}
radius="md"
/>
);
}Start scroll date time
Use startScrollDateTime prop to scroll to a specific time on mount.
import dayjs from 'dayjs';
import { useState } from 'react';
import { ResourcesWeekView } from '@mantine/schedule';
import { events, resources } from './data';
function Demo() {
const today = dayjs().format('YYYY-MM-DD');
const [date, setDate] = useState(today);
return (
<ResourcesWeekView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
startScrollDateTime={`${today} 10:00:00`}
/>
);
}Scroll area props
Use scrollAreaProps to pass props to the underlying ScrollArea component.
import dayjs from 'dayjs';
import { useState } from 'react';
import { ResourcesWeekView } from '@mantine/schedule';
import { events, resources } from './data';
function Demo() {
const today = dayjs().format('YYYY-MM-DD');
const [date, setDate] = useState(today);
return (
<ResourcesWeekView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
startTime="08:00:00"
endTime="18:00:00"
startScrollDateTime={`${today} 08:00:00`}
scrollAreaProps={{
scrollbarSize: 10,
offsetScrollbars: true,
}}
/>
);
}Event resize
Enable event resizing with withEventResize prop. Events can be resized by dragging their left or
right edges, onEventResize is called with the new start and end times.
To reject a resize based on the new range, use preventEventOverlap and canResizeEventTo, see
drop validation.
An event cannot be resized to span multiple days. Use canResizeEvent to control which events
can be resized.
import dayjs from 'dayjs';
import { useState } from 'react';
import { ResourcesWeekView, ScheduleEventData } from '@mantine/schedule';
import { events as initialEvents, resources } from './data';
function Demo() {
const today = dayjs().format('YYYY-MM-DD');
const [date, setDate] = useState(today);
const [events, setEvents] = useState<ScheduleEventData[]>(initialEvents);
return (
<ResourcesWeekView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
startTime="08:00:00"
endTime="18:00:00"
startScrollDateTime={`${today} 08:00:00`}
withEventResize
onEventResize={({ eventId, newStart, newEnd }) => {
setEvents((current) =>
current.map((event) =>
event.id === eventId
? { ...event, start: newStart, end: newEnd }
: event
)
);
}}
/>
);
}Resize interval
By default, resized events snap to intervalMinutes. Set eventResizeInterval to use a different
step, for example to resize events in 15-minute increments on a grid with 30-minute slots:
import dayjs from 'dayjs';
import { useState } from 'react';
import { ResourcesWeekView, ScheduleEventData } from '@mantine/schedule';
import { events as initialEvents, resources } from './data';
function Demo() {
const today = dayjs().format('YYYY-MM-DD');
const [date, setDate] = useState(today);
const [events, setEvents] = useState<ScheduleEventData[]>(initialEvents);
return (
<ResourcesWeekView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
startTime="08:00:00"
endTime="18:00:00"
intervalMinutes={30}
eventResizeInterval={15}
startScrollDateTime={`${today} 08:00:00`}
withEventResize
onEventResize={({ eventId, newStart, newEnd }) => {
setEvents((current) =>
current.map((event) =>
event.id === eventId
? { ...event, start: newStart, end: newEnd }
: event
)
);
}}
/>
);
}Static mode
Set mode="static" to disable all interactions.
import dayjs from 'dayjs';
import { useState } from 'react';
import { ResourcesWeekView } from '@mantine/schedule';
import { events, resources } from './data';
function Demo() {
const today = dayjs().format('YYYY-MM-DD');
const [date, setDate] = useState(today);
return (
<ResourcesWeekView
date={date}
onDateChange={setDate}
resources={resources}
events={events}
startTime="08:00:00"
endTime="18:00:00"
startScrollDateTime={`${today} 08:00:00`}
mode="static"
/>
);
}