WeekView
WeekView
독립형 스케줄 주간 뷰 컴포넌트예요. @mantine/schedule 패키지로 제공돼요.
출처: 문서
본문
사용법
WeekView는 시간 슬롯과 함께 일주일 전체의 이벤트를 표시해요. 종일(all-day) 이벤트, 겹치는 이벤트, 드래그 앤 드롭, 커스텀 시간 범위 등을 지원해요.
import dayjs from 'dayjs';
import { useState } from 'react';
import { WeekView } from '@mantine/schedule';
import { events } from './data';
function Demo() {
const [date, setDate] = useState(dayjs().format('YYYY-MM-DD'));
return <WeekView date={date} onDateChange={setDate} events={events} />;
}
제어된 날짜(Controlled date)
date와 onDateChange props로 WeekView가 표시하는 날짜를 외부에서 제어해요.
import { useState } from 'react';
import dayjs from 'dayjs';
import { WeekView } from '@mantine/schedule';
import { Button, Group, Text } from '@mantine/core';
import { events } from './data';
function Demo() {
const [date, setDate] = useState(dayjs().format('YYYY-MM-DD'));
const weekStart = dayjs(date).subtract((dayjs(date).day() + 6) % 7, 'day');
return (
<>
<Group>
<Button onClick={() => setDate(dayjs(date).subtract(1, 'week').format('YYYY-MM-DD HH:mm:ss'))}>
Previous Week
</Button>
<Text>{weekStart.format('MMM D')} – {weekStart.add(6, 'day').format('MMM D, YYYY')}</Text>
<Button onClick={() => setDate(dayjs(date).add(1, 'week').format('YYYY-MM-DD HH:mm:ss'))}>
Next Week
</Button>
</Group>
<WeekView date={date} onDateChange={setDate} events={events} />
</>
);
}
시간 범위
startTime과 endTime props로 표시할 시간 범위를 설정해요. 시간은 HH:mm:ss 형식이어야 해요.
import { WeekView } from '@mantine/schedule';
import { events } from './data';
function Demo() {
return (
<WeekView
startTime="09:00:00"
endTime="17:00:00"
events={events}
/>
);
}
시작 스크롤 시간
startScrollTime prop으로 초기 스크롤 위치를 특정 시간으로 설정해요. 값은 HH:mm:ss 형식이어야 해요. 뷰가 자정이 아니라 특정 시간(예: 업무 시작 시간)에 열리게 하고 싶을 때 유용해요.
import { useState } from 'react';
import { WeekView, ScheduleEventData } from '@mantine/schedule';
import { events as initialEvents } from './data';
function Demo() {
const [events, setEvents] = useState(initialEvents);
const handleEventDrop = ({ eventId, newStart, newEnd }: { eventId: string | number; newStart: string; newEnd: string }) => {
setEvents((prev) =>
prev.map((event) =>
event.id === eventId ? { ...event, start: newStart, end: newEnd } : event
)
);
};
return (
<WeekView
startScrollTime="09:00:00"
events={events}
onEventDrop={handleEventDrop}
/>
);
}
Interval minutes
intervalMinutes prop은 시간 슬롯의 세밀도를 제어해요. 기본은 60분이에요.
import { WeekView } from '@mantine/schedule';
import { events } from './data';
function Demo() {
return <WeekView intervalMinutes={30} events={events} />;
}
시간 미만 단위 그리드 라인
기본적으로 WeekView는 모든 시간 슬롯에 대해 그리드 라인을 표시해요. intervalMinutes가 60보다 작을 때 withSubHourGridLines={false}를 설정하면 이벤트 생성/크기 조절에는 더 작은 간격을 유지하면서 한 시간에 하나의 그리드 라인만 표시해요. Google Calendar 같이 이벤트는 15분이나 30분 단위로 스냅되지만 그리드는 한 시간 라인으로 깔끔하게 유지되는 레이아웃을 만들 때 유용해요.
import { useState } from 'react';
import dayjs from 'dayjs';
import { WeekView, ScheduleEventData } from '@mantine/schedule';
const today = dayjs().format('YYYY-MM-DD');
const tomorrow = dayjs().add(1, 'day').format('YYYY-MM-DD');
const initialEvents: ScheduleEventData[] = [
{ id: 1, title: 'Morning Standup', start: `${today} 09:00:00`, end: `${today} 09:30:00`, color: 'blue' },
{ id: 2, title: 'Team Meeting', start: `${tomorrow} 11:15:00`, end: `${tomorrow} 12:00:00`, color: 'green' },
{ id: 3, title: 'Code Review', start: `${today} 14:00:00`, end: `${today} 14:45:00`, color: 'violet' },
];
function Demo() {
const [events, setEvents] = useState(initialEvents);
const handleEventResize = ({ eventId, newStart, newEnd }: { eventId: string | number; newStart: string; newEnd: string }) => {
setEvents((prev) =>
prev.map((event) =>
event.id === eventId ? { ...event, start: newStart, end: newEnd } : event
)
);
};
// Events snap to 15 minutes increments, but only one grid line per hour is displayed
return (
<WeekView
intervalMinutes={15}
withSubHourGridLines={false}
events={events}
onEventResize={handleEventResize}
/>
);
}
주의 첫 번째 요일
firstDayOfWeek로 주가 시작하는 요일을 제어해요. 0은 일요일, 1은 월요일(기본) 등이에요.
import { WeekView } from '@mantine/schedule';
import { events } from './data';
function Demo() {
return <WeekView firstDayOfWeek={0} events={events} />;
}
요일 형식
weekdayFormat prop으로 요일 이름 표시를 커스터마이즈해요. dayjs 형식 문자열을 받아요.
import { WeekView } from '@mantine/schedule';
import { events } from './data';
function Demo() {
return <WeekView weekdayFormat="dd" events={events} />;
}
주말 없이
withWeekendDays={false}로 토요일과 일요일 열을 숨겨요.
import { WeekView } from '@mantine/schedule';
import { events } from './data';
function Demo() {
return <WeekView withWeekendDays={false} events={events} />;
}
오늘 강조
highlightToday로 오늘 열을 시각적으로 구분해요.
import { WeekView } from '@mantine/schedule';
import { events } from './data';
function Demo() {
return <WeekView highlightToday events={events} />;
}
주 번호 없이
withWeekNumber={false}로 왼쪽 위 모서리의 주 번호를 숨겨요.
import { WeekView } from '@mantine/schedule';
import { events } from './data';
function Demo() {
return <WeekView withWeekNumber={false} events={events} />;
}
현재 시간 표시기
withCurrentTimeIndicator로 오늘 열에 현재 시간을 보여주는 선을 표시해요.
import { WeekView } from '@mantine/schedule';
import { events } from './data';
function Demo() {
return <WeekView withCurrentTimeIndicator events={events} />;
}
현재 시간 표시기 강제
forceCurrentTimeIndicator로 다른 주를 보고 있을 때도 같은 요일에 현재 시간 표시기를 표시해요. 사용자에게 자신의 일정 대비 현재 시간 위치를 감지하게 해주므로 유용해요.
import { WeekView } from '@mantine/schedule';
import { events } from './data';
function Demo() {
return <WeekView date="2030-06-10" withCurrentTimeIndicator forceCurrentTimeIndicator events={events} />;
}
다른 시간대의 현재 시간 표시기
@mantine/schedule은 시간대에 구애받지 않는 YYYY-MM-DD HH:mm:ss 문자열과 함께 동작하며 자체적으로 어떤 시간대 변환도 수행하지 않아요. 기본적으로 현재 시간 표시기는 사용자의 로컬 시간을 기준으로 배치돼요.
다른 시간대에 표시기를 표시하려면 getCurrentTime prop을 사용해요. 이것은 현재 시간을 반환하는 함수이며 매 틱마다 호출되어 표시기가 자동으로 계속 업데이트돼요. 아래 예시에서는 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 { WeekView } from '@mantine/schedule';
import { getEvents } 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
data={timezones}
value={tz}
onChange={(value) => setTz(value!)}
allowDeselect={false}
/>
<WeekView date={currentDate} getCurrentTime={getCurrentTime} withCurrentTimeIndicator events={getEvents(currentDate)} />
</Stack>
);
}
종일 슬롯 없이
withAllDaySlots={false}로 상단의 종일 이벤트 섹션을 숨겨요.
import { WeekView } from '@mantine/schedule';
import { events } from './data';
function Demo() {
return <WeekView withAllDaySlots={false} events={events} />;
}
종일 이벤트
종일 이벤트는 주간 뷰 상단의 별도 섹션에 표시돼요. 자정을 넘거나 하루 전체를 덮는 이벤트는 자동으로 이 섹션에 배치돼요.
import dayjs from 'dayjs';
import { useState } from 'react';
import { WeekView, ScheduleEventData } from '@mantine/schedule';
const startOfWeek = dayjs().subtract((dayjs().day() + 6) % 7, 'day').format('YYYY-MM-DD');
const dayAfterStartOfWeek = dayjs(startOfWeek).add(1, 'day').format('YYYY-MM-DD');
const twoDaysAfter = dayjs(startOfWeek).add(2, 'day').format('YYYY-MM-DD');
const events: ScheduleEventData[] = [
{
id: 1,
title: 'Conference Day',
start: `${startOfWeek} 00:00:00`,
end: dayjs(startOfWeek).add(1, 'day').startOf('day').format('YYYY-MM-DD HH:mm:ss'),
color: 'red',
},
{
id: 4,
title: 'Morning Standup',
start: `${startOfWeek} 09:00:00`,
end: `${startOfWeek} 09:30:00`,
color: 'blue',
},
];
function Demo() {
const [date, setDate] = useState(dayjs().format('YYYY-MM-DD'));
return <WeekView date={date} onDateChange={setDate} events={events} />;
}
헤더 없이
withHeader={false}로 헤더 컨트롤을 숨겨요.
import { WeekView } from '@mantine/schedule';
import { events } from './data';
function Demo() {
return <WeekView withHeader={false} events={events} />;
}
뷰 변경 콜백
onViewChange 콜백을 사용해 사용자가 헤더 드롭다운에서 다른 뷰를 선택할 때 알림을 받아요.
import { useState } from 'react';
import dayjs from 'dayjs';
import { WeekView, ScheduleViewLevel } from '@mantine/schedule';
import { Text } from '@mantine/core';
import { events } from './data';
function Demo() {
const [date, setDate] = useState(dayjs().format('YYYY-MM-DD'));
const [view, setView] = useState('week');
return (
<>
<Text>Selected view: {view}</Text>
<WeekView date={date} onDateChange={setDate} onViewChange={setView} events={events} />
</>
);
}
커스텀 헤더
ScheduleHeader 복합 컴포넌트와 자신만의 컨트롤을 결합해 커스텀 헤더를 만들 수 있어요. 뷰에 withHeader={false}를 설정하고 헤더를 외부에서 구성해요.
import dayjs from 'dayjs';
import { useState } from 'react';
import {
DateStringValue,
getStartOfWeek,
ScheduleHeader,
WeekView,
} from '@mantine/schedule';
import { events } from './data';
function getWeekRangeLabel(date: DateStringValue) {
const start = dayjs(getStartOfWeek({ date, firstDayOfWeek: 1 }));
const end = start.add(6, 'day');
if (start.month() === end.month()) {
return `${start.format('MMM D')} – ${end.format('D, YYYY')}`;
}
return `${start.format('MMM D')} – ${end.format('MMM D, YYYY')}`;
}
function Demo() {
const [date, setDate] = useState(
dayjs().format('YYYY-MM-DD')
);
return (
<>
<ScheduleHeader>
<ScheduleHeader.ControlsGroup>
<ScheduleHeader.PrevButton onClick={() => setDate(dayjs(date).subtract(1, 'week').format('YYYY-MM-DD') as DateStringValue)} />
<ScheduleHeader.Level />
<ScheduleHeader.NextButton onClick={() => setDate(dayjs(date).add(1, 'week').format('YYYY-MM-DD') as DateStringValue)} />
</ScheduleHeader.ControlsGroup>
<ScheduleHeader.Label>{getWeekRangeLabel(date)}</ScheduleHeader.Label>
<ScheduleHeader.ControlsGroup>
<ScheduleHeader.TodayButton onClick={() => setDate(dayjs().format('YYYY-MM-DD') as DateStringValue)} />
<ScheduleHeader.ToggleButton onClick={() => window.print()}>Print</ScheduleHeader.ToggleButton>
</ScheduleHeader.ControlsGroup>
</ScheduleHeader>
<WeekView date={date} onDateChange={setDate} withHeader={false} events={events} />
</>
);
}
주 라벨 형식
weekLabelFormat prop으로 헤더의 주 범위 표시를 커스터마이즈해요.
import { WeekView } from '@mantine/schedule';
import { events } from './data';
function Demo() {
return <WeekView weekLabelFormat="MMMM D, YYYY" events={events} />;
}
슬롯 라벨 형식
slotLabelFormat prop은 시간 라벨의 형식을 제어해요.
import { WeekView } from '@mantine/schedule';
import { events } from './data';
function Demo() {
return <WeekView slotLabelFormat="h A" events={events} />;
}
슬롯 높이
slotHeight와 allDaySlotHeight props로 시간 슬롯과 종일 섹션의 높이를 커스터마이즈해요.
import { WeekView } from '@mantine/schedule';
import { events } from './data';
function Demo() {
return <WeekView slotHeight={80} allDaySlotHeight={80} events={events} />;
}
Radius
radius prop으로 이벤트의 테두리 반경을 커스터마이즈해요.
import dayjs from 'dayjs';
import { useState } from 'react';
import { WeekView } from '@mantine/schedule';
import { events } from './data';
function Demo() {
const [date, setDate] = useState(dayjs().format('YYYY-MM-DD'));
return <WeekView date={date} onDateChange={setDate} radius="sm" events={events} />;
}
업무 시간
highlightBusinessHours와 businessHours props로 업무 시간을 시각적으로 구분해요.
import { WeekView } from '@mantine/schedule';
import { events } from './data';
function Demo() {
return (
<WeekView
highlightBusinessHours
businessHours={{ startTime: '09:00:00', endTime: '17:00:00' }}
events={events}
/>
);
}
요일별 업무 시간
businessHours에 객체를 전달해 각 요일의 범위를 개별적으로 구성해요. 키는 요일 번호(0 – 일요일, 6 – 토요일)예요. 객체에서 누락되었거나 null로 설정된 요일은 완전히 업무 시간 밖으로 표시돼요:
import { WeekView } from '@mantine/schedule';
import { events } from './data';
function Demo() {
return (
<WeekView
highlightBusinessHours
businessHours={{
1: { startTime: '08:00:00', endTime: '18:00:00' },
2: { startTime: '08:00:00', endTime: '18:00:00' },
3: { startTime: '08:00:00', endTime: '18:00:00' },
4: { startTime: '08:00:00', endTime: '18:00:00' },
5: { startTime: '08:00:00', endTime: '18:00:00' },
6: null,
0: null,
}}
events={events}
/>
);
}
커스텀 시간 슬롯 props
getTimeSlotProps로 시간 범위에 기반해 개별 시간 슬롯에 커스텀 props를 추가해요. 이 함수는 YYYY-MM-DD HH:mm:ss 형식의 { start, end } 날짜시간 문자열을 받아 슬롯 요소에 펼쳐질 props 객체 또는 undefined를 반환해야 해요.
기본 9:00–17:00과 다른 커스텀 범위에 data-business-hours를 설정하거나 특정 슬롯에 커스텀 이벤트 핸들러를 붙일 때 유용해요. getTimeSlotProps가 반환한 onClick 같은 이벤트 핸들러는 내부 핸들러(onTimeSlotClick)와 합성되어, 서로 덮어쓰지 않고 둘 다 실행돼요.
겹치는 이벤트
여러 이벤트가 시간상 겹치면 자동으로 나란히 배치돼요.
Overlap mode
eventOverlapMode prop은 시간상 겹치는 이벤트가 가로 공간을 어떻게 공유할지 제어해요:
-
columns(기본) – 사용 가능한 너비가 겹치는 이벤트들 사이에 균등하게 나뉘어요. 모든 이벤트가 완전히 보이지만, 겹치는 이벤트가 많아질수록 각각은 더 좁아져요. -
cascade– 각 이벤트가 이전 이벤트에서 들여쓰기되어 그 위에 그려지며 그룹의 오른쪽 가장자리까지 확장돼요. 이벤트가 얼마나 많이 겹치든 읽을 수 있는 너비를 유지하되, 그 아래 이벤트를 가리게 돼요.
데이터가 정기적으로 큰 동시 이벤트 그룹을 만들 때 cascade를 선호해요. columns는 각 이벤트를 읽을 수 없는 가느다란 조각으로 줄일 수 있어요.
들여쓰기는 그룹이 커질수록 자동으로 줄어들어, 맨 위 이벤트는 항상 사용 가능한 너비의 최소 60%를 유지해요.
가려진 이벤트도 읽고 상호작용할 수 있어요: 포인터를 올려두면 가리는 이벤트 위로 올라오고 크기 조절 핸들도 닿을 수 있게 돼요. 키보드 사용자는 Tab으로 이벤트에 포커스를 주면 지연 없이 같은 결과를 얻어요.
eventOverlapRaiseDelay prop은 포인터가 이벤트 위에 머물러야 올라올 때까지의 시간(ms)을 제어해요. 기본 600은 그룹을 가로질러 특정 이벤트에 닿기 위해 이동할 때 지나치는 이벤트를 올리지 않을 만큼 길어요. 더 작은 값을 설정하면 가려진 이벤트가 더 빨리 나타나요.
드래그 앤 드롭
withDragDrop prop을 설정해 드래그 앤 드롭을 활성화해요. 이벤트를 다른 날짜와 시간으로 드래그할 수 있어요.
import { WeekView } from '@mantine/schedule';
import { events } from './data';
function Demo() {
return <WeekView withDragDrop events={events} />;
}
드래그 간격
기본적으로 이벤트는 드래그 앤 드롭으로 이동할 때 intervalMinutes에 스냅돼요. 드래그에 다른 스냅 단계를 사용하려면 eventDragInterval을 설정해요 – 예를 들어 30분 슬롯의 그리드에서 이벤트를 15분 단위로 이동할 수 있게요. 이벤트가 어디에 놓일지 고스트 미리보기가 보여요.
이벤트 크기 조절 제한
canDragEvent 콜백으로 드래그할 수 있는 이벤트를 제어해요. false를 반환하는 이벤트는 드래그할 수 없어요.
import { WeekView } from '@mantine/schedule';
import { useMantineColorScheme } from '@mantine/core';
import { events } from './data';
function Demo() {
return (
<WeekView
withDragDrop
canDragEvent={(event) => !event.payload?.locked}
events={events}
/>
);
}
외부 드래그 앤 드롭
외부 소스에서 이벤트를 드래그하는 것도 지원돼요.
양방향 드래그 앤 드롭
이벤트를 뷰 안팎으로 드래그하는 양방향 드래그 앤 드롭도 지원돼요.
이벤트 크기 조절
withEventResize prop을 설정해 이벤트 크기 조절을 활성화해요. 사용자가 이벤트의 위나 아래 가장자리를 드래그해 시작 또는 종료 시간을 조절할 수 있어요. onEventResize 콜백으로 크기 조절을 처리해요. canResizeEvent로 어떤 이벤트를 크기 조절할 수 있는지 제어해요.
import { WeekView } from '@mantine/schedule';
import { events } from './data';
function Demo() {
return <WeekView withEventResize events={events} />;
}
크기 조절 간격
기본적으로 이벤트는 크기 조절될 때 intervalMinutes에 스냅돼요. eventResizeInterval을 설정해 크기 조절에 다른 스냅 단계를 사용해요 – 예를 들어 30분 슬롯의 그리드에서 이벤트를 15분 단위로 크기 조절할 수 있게요.
크기 조절 이벤트 제한
canResizeEvent 콜백으로 크기 조절할 수 있는 이벤트를 제어할 수 있어요.
전체 이벤트 커스터마이즈
renderEvent prop으로 이벤트 렌더링을 완전히 커스터마이즈해요. 이 함수는 첫 번째 인자로 이벤트 데이터를 받고, 두 번째 인자로 이벤트 루트 요소에 전달될 모든 props(children 포함)를 받아요. HoverCard, Tooltip 또는 커스텀 래퍼 같은 커스텀 컴포넌트로 이벤트를 감쌀 수 있게 해줘요.
import { useState } from 'react';
import dayjs from 'dayjs';
import { WeekView } from '@mantine/schedule';
import { getStartOfWeek } from '@mantine/schedule';
function Demo() {
const [events, setEvents] = useState(eventData);
return (
<WeekView
withDragDrop
onEventDrop={({ eventId, newStart, newEnd }) => {
setEvents((current) =>
current.map((event) =>
event.id === eventId
? { ...event, start: dayjs(newStart).format('YYYY-MM-DD HH:mm:ss'), end: dayjs(newEnd).format('YYYY-MM-DD HH:mm:ss') }
: event
)
);
}}
renderEvent={(event, props) => (
<EventDetails event={event} {...props} />
)}
events={events}
/>
);
}
커스텀 이벤트 본문
renderEventBody prop으로 이벤트의 루트 요소를 대체하지 않고 이벤트 내부의 콘텐츠를 커스터마이즈해요.
반복 이벤트
WeekView는 보이는 주에 대해 반복 이벤트를 자동으로 확장해요. 자세한 문서는 Recurring events guide를 참고하세요.
import { WeekView } from '@mantine/schedule';
const events = [
{
id: 'weekly-sync-series',
title: 'Weekly sync (series)',
start: `${weekStart} 10:00:00`,
end: `${weekStart} 11:00:00`,
color: 'blue',
recurrence: {
rrule: 'FREQ=WEEKLY;BYDAY=MO,WE;COUNT=12',
exdate: [`${dayjs(weekStart).add(2, 'day').format('YYYY-MM-DD')} 10:00:00`],
},
},
];
function Demo() {
return <WeekView events={events} />;
}
배경 이벤트
배경 이벤트(background events)를 지원해요.
인터랙티브 배경 이벤트
withInteractiveBackgroundEvents prop을 설정해 배경 이벤트를 클릭 가능하게 만들어요. 배경 이벤트를 클릭하면 일반 이벤트와 마찬가지로 onEventClick이 이벤트 객체와 함께 호출돼요 – 핸들러에서 event.display === 'background'로 구분해요.
인터랙티브 배경 이벤트는 그 아래의 시간 슬롯을 덮는다는 점에 주의하세요: 그 범위의 클릭과 드래그-선택은 그리드 대신 이벤트로 가요. 인터랙티브 배경 이벤트는 여전히 드래그할 수 없어요.
import { WeekView } from '@mantine/schedule';
const events = [
{ id: 'out-of-office', title: 'Out of office', start: `${today} 12:00:00`, end: `${today} 16:00:00`, color: 'red', display: 'background' },
];
function Demo() {
const [clicked, setClicked] = useState(null);
return (
<>
<Text>
Last clicked:{' '}
{clicked ? `${clicked.title} (${clicked.display === 'background' ? 'background' : 'regular'} event)` : 'nothing yet'}
</Text>
<WeekView
withInteractiveBackgroundEvents
onEventClick={setClicked}
events={events}
/>
</>
);
}
크기 조절 가능한 배경 이벤트
withEventResize를 withInteractiveBackgroundEvents와 함께 설정하면 배경 이벤트가 위/아래 가장자리에 크기 조절 핸들을 렌더링해요. 핸들을 드래그하면 일반 이벤트와 같은 방식으로 onEventResize가 배경 이벤트와 함께 호출돼요 – 핸들러에서 event.display === 'background'로 구분해요.
종일 배경 이벤트는 절대 크기 조절할 수 없어요. 일반 이벤트는 크기 조절 가능하게 유지하면서 배경 이벤트를 고정하려면 canResizeEvent에서 false를 반환해요:
<WeekView
withEventResize
withInteractiveBackgroundEvents
canResizeEvent={(event) => event.display !== 'background'}
events={events}
/>
드래그 앤 드롭 차단이 있는 커스텀 배경 이벤트 스타일
Styles API로 배경 이벤트의 외관을 커스터마이즈하고 일반 이벤트를 차단된 시간 범위에 떨어뜨리는 것을 방지할 수 있어요. 이 예시는 대각선 빨간 선으로 주 전체의 점심 시간을 표시하고 배경 이벤트와 겹치는 드롭을 거부해요.
Agenda 뷰
WeekView의 드롭다운 뷰를 갤러리 뷰로 전환하듯 사용하는 Agenda 뷰가 지원돼요.
정적 모드
mode="static"으로 모든 상호작용을 비활성화해요.
현지화
locale prop으로 날짜 형식의 dayjs 로케일을 설정해요. labels prop과 결합해 모든 UI 텍스트를 번역해요.
import dayjs from 'dayjs';
import 'dayjs/locale/es';
import { useMantineColorScheme } from '@mantine/core';
import { WeekView } from '@mantine/schedule';
import { events } from './data';
import { labels } from './labels';
function Demo() {
const [date, setDate] = useState(dayjs().format('YYYY-MM-DD'));
return <WeekView locale="es" labels={labels} date={date} onDateChange={setDate} events={events} />;
}
이벤트 생성과 업데이트
withDragSlotSelect prop을 설정해 사용자가 시간 슬롯을 가로질러 드래그해 시간 범위를 선택하게 해요. 드래그가 끝나면 onSlotDragEnd 콜백이 범위의 시작·종료 날짜와 함께 호출돼요. 드래그는 단일 날짜 열로 제한돼요. onTimeSlotClick, onAllDaySlotClick, onEventClick 콜백과 결합하면 완전한 이벤트 생성·편집 경험을 만들 수 있어요.
import { WeekView } from '@mantine/schedule';
function Demo() {
const [date, setDate] = useState(dayjs().format('YYYY-MM-DD'));
const [events, setEvents] = useState(events);
const [formOpened, setFormOpened] = useState(false);
const [selectedEventData, setSelectedEventData] = useState(null);
const handleTimeSlotClick = ({ slotStart, slotEnd }: { slotStart: string; slotEnd: string }) => {
setSelectedEventData({ title: '', start: new Date(slotStart), end: new Date(slotEnd), color: 'blue' });
setFormOpened(true);
};
const handleAllDaySlotClick = (slotDate: string) => {
setSelectedEventData({ title: '', start: dayjs(slotDate).startOf('day').toDate(), end: dayjs(slotDate).endOf('day').toDate(), color: 'blue' });
setFormOpened(true);
};
const handleEventClick = (event: ScheduleEventData) => {
setSelectedEventData({ id: event.id, title: event.title, start: new Date(event.start), end: new Date(event.end), color: event.color || 'blue' });
setFormOpened(true);
};
return (
<WeekView
withDragSlotSelect
onSlotDragEnd={({ slotStart, slotEnd }) => handleTimeSlotClick({ slotStart, slotEnd })}
onTimeSlotClick={handleTimeSlotClick}
onAllDaySlotClick={handleAllDaySlotClick}
onEventClick={handleEventClick}
date={date}
onDateChange={setDate}
events={events}
/>
);
}
반응형 스타일
WeekView는 반응형 스타일을 지원해요.
접근성
WeekView는 접근성을 지원해요.