diff --git a/apps/calendar/src/components/timeGrid/gridLines.tsx b/apps/calendar/src/components/timeGrid/gridLines.tsx
index 6bf22e1d5..a143c7bef 100644
--- a/apps/calendar/src/components/timeGrid/gridLines.tsx
+++ b/apps/calendar/src/components/timeGrid/gridLines.tsx
@@ -3,6 +3,7 @@ import { memo } from 'preact/compat';
import { useTheme } from '@src/contexts/themeStore';
import { cls, toPercent } from '@src/helpers/css';
+import { getTimeSteps } from '@src/time/datetime';
import type { TimeGridRow } from '@t/grid';
import type { ThemeState } from '@t/theme';
@@ -19,12 +20,17 @@ export const GridLines = memo(function GridLines({
}: {
timeGridRows: TimeGridRow[];
}) {
+ const { STEPS } = getTimeSteps(timeGridRows);
const { halfHourLineBorder, hourLineBorder } = useTheme(gridLineBorderSelector);
+ let count = 1;
+
return (
- {timeGridRows.map((time, index) => {
- const isUpperLine = index % 2 === 0;
+ {timeGridRows.map((time) => {
+ count = count === STEPS + 1 ? 1 : count;
+ const isUpperLine = count !== STEPS;
+ count += 1;
return (
timeGridRows.filter((_, index) => index % 2 === 0 || index === timeGridRows.length - 1),
- [timeGridRows]
+ () =>
+ timeGridRows.filter((_, index) => index % STEPS === 0 || index === timeGridRows.length - 1),
+ [timeGridRows, STEPS]
);
const hourRowsPropsMapper = useCallback(
(row: TimeGridRow, index: number, diffFromPrimaryTimezone?: number) => {
diff --git a/apps/calendar/src/components/timeGrid/timeGrid.spec.tsx b/apps/calendar/src/components/timeGrid/timeGrid.spec.tsx
index efe616913..a850c3e0d 100644
--- a/apps/calendar/src/components/timeGrid/timeGrid.spec.tsx
+++ b/apps/calendar/src/components/timeGrid/timeGrid.spec.tsx
@@ -34,6 +34,7 @@ describe('Showing Current Time Indicator', () => {
const timeGridData = createTimeGridData(weekDatesIncludingBaseDate, {
hourStart: 0,
hourEnd: 24,
+ timeStep: [0,30]
});
// When
@@ -50,7 +51,7 @@ describe('Showing Current Time Indicator', () => {
startDayOfWeek: 0,
workweek: false,
});
- const timeGridData = createTimeGridData(weekDatesBeforeBaseDate, { hourStart: 0, hourEnd: 24 });
+ const timeGridData = createTimeGridData(weekDatesBeforeBaseDate, { hourStart: 0, hourEnd: 24, timeStep: [0,30] });
// When
render();
@@ -69,6 +70,7 @@ describe('Showing Current Time Indicator', () => {
const timeGridData = createTimeGridData(weekDatesIncludingBaseDate, {
hourStart: 0,
hourEnd: 24,
+ timeStep: [0,30]
});
// When
@@ -88,6 +90,7 @@ describe('Showing Current Time Indicator', () => {
const timeGridData = createTimeGridData(weekDatesIncludingBaseDate, {
hourStart: 0,
hourEnd: 24,
+ timeStep: [0,30]
});
// When
@@ -113,6 +116,7 @@ describe('Showing Current Time Indicator', () => {
const timeGridData = createTimeGridData(weekDatesIncludingBaseDate, {
hourStart: 0,
hourEnd: 24,
+ timeStep: [0,30]
});
const oneHourHeightPercent = timeGridData.rows[0].height * 2;
const initialTop = 50;
diff --git a/apps/calendar/src/components/view/day.tsx b/apps/calendar/src/components/view/day.tsx
index be97c3a77..1e2223007 100644
--- a/apps/calendar/src/components/view/day.tsx
+++ b/apps/calendar/src/components/view/day.tsx
@@ -58,8 +58,16 @@ export function Day() {
const [timePanel, setTimePanelRef] = useDOMNode();
const weekOptions = options.week as Required;
- const { narrowWeekend, startDayOfWeek, workweek, hourStart, hourEnd, eventView, taskView } =
- weekOptions;
+ const {
+ narrowWeekend,
+ startDayOfWeek,
+ workweek,
+ hourStart,
+ hourEnd,
+ eventView,
+ taskView,
+ timeStep,
+ } = weekOptions;
const days = useMemo(() => [renderDate], [renderDate]);
const dayNames = getDayNames(days, options.week?.dayNames ?? []);
const { rowStyleInfo, cellWidthMap } = getRowStyleInfo(
@@ -95,8 +103,9 @@ export function Day() {
hourStart,
hourEnd,
narrowWeekend,
+ timeStep,
}),
- [days, hourEnd, hourStart, narrowWeekend]
+ [days, hourEnd, hourStart, narrowWeekend, timeStep]
);
const activePanels = getActivePanels(taskView, eventView);
const gridRows = activePanels.map((key) => {
diff --git a/apps/calendar/src/components/view/week.tsx b/apps/calendar/src/components/view/week.tsx
index 9ed24ddf0..afa27f096 100644
--- a/apps/calendar/src/components/view/week.tsx
+++ b/apps/calendar/src/components/view/week.tsx
@@ -59,8 +59,16 @@ export function Week() {
const [timePanel, setTimePanelRef] = useDOMNode();
const weekOptions = options.week as Required;
- const { narrowWeekend, startDayOfWeek, workweek, hourStart, hourEnd, eventView, taskView } =
- weekOptions;
+ const {
+ narrowWeekend,
+ startDayOfWeek,
+ workweek,
+ hourStart,
+ hourEnd,
+ eventView,
+ taskView,
+ timeStep,
+ } = weekOptions;
const weekDates = useMemo(() => getWeekDates(renderDate, weekOptions), [renderDate, weekOptions]);
const dayNames = getDayNames(weekDates, options.week?.dayNames ?? []);
const { rowStyleInfo, cellWidthMap } = getRowStyleInfo(
@@ -96,8 +104,9 @@ export function Week() {
hourStart,
hourEnd,
narrowWeekend,
+ timeStep,
}),
- [hourEnd, hourStart, narrowWeekend, weekDates]
+ [hourEnd, hourStart, narrowWeekend, weekDates, timeStep]
);
const activePanels = getActivePanels(taskView, eventView);
diff --git a/apps/calendar/src/css/events/time.css b/apps/calendar/src/css/events/time.css
index 47d0aa6cc..b1ab14c67 100644
--- a/apps/calendar/src/css/events/time.css
+++ b/apps/calendar/src/css/events/time.css
@@ -2,6 +2,7 @@
position: absolute;
overflow: hidden;
cursor: pointer;
+ min-height: 17px;
}
.event-time .travel-time,
diff --git a/apps/calendar/src/css/timegrid/column.css b/apps/calendar/src/css/timegrid/column.css
index 45ca3f9d5..e04da9638 100644
--- a/apps/calendar/src/css/timegrid/column.css
+++ b/apps/calendar/src/css/timegrid/column.css
@@ -12,6 +12,7 @@
right: 10px;
left: 1px;
padding: 3px;
+ min-height: 26px;
}
.column .grid-selection .grid-selection-label {
diff --git a/apps/calendar/src/factory/__snapshots__/calendarCore.spec.tsx.snap b/apps/calendar/src/factory/__snapshots__/calendarCore.spec.tsx.snap
index 50601a84e..dda3e41a0 100644
--- a/apps/calendar/src/factory/__snapshots__/calendarCore.spec.tsx.snap
+++ b/apps/calendar/src/factory/__snapshots__/calendarCore.spec.tsx.snap
@@ -208,6 +208,10 @@ Object {
"showTimezoneCollapseButton": false,
"startDayOfWeek": 0,
"taskView": true,
+ "timeStep": Array [
+ 0,
+ 30,
+ ],
"timezonesCollapsed": false,
"workweek": false,
},
diff --git a/apps/calendar/src/helpers/grid.spec.ts b/apps/calendar/src/helpers/grid.spec.ts
index 89971a031..544c2da8c 100644
--- a/apps/calendar/src/helpers/grid.spec.ts
+++ b/apps/calendar/src/helpers/grid.spec.ts
@@ -502,22 +502,25 @@ describe('getColumnStyles', () => {
describe('createTimeGridData', () => {
function assertTimeGridDataRows(
expectedRows: TimeGridRow[],
- options: { hourStart: number; hourEnd: number }
+ options: { hourStart: number; hourEnd: number, timeStep: number[] }
) {
- const steps = (options.hourEnd - options.hourStart) * 2;
+ const timeStep = options.timeStep;
+ const steps = (options.hourEnd - options.hourStart) * timeStep.length;
const expectedRowHeight = 100 / steps;
+ let count = 0;
expect(expectedRows).toHaveLength(steps);
range(steps).forEach((step, index) => {
- const isOdd = index % 2 === 1;
- const hour = options.hourStart + Math.floor(step / 2);
+ count = count === timeStep.length ? 0 : count;
+ const hour = options.hourStart + Math.floor(step / timeStep.length);
expect(expectedRows[index]).toEqual({
top: expectedRowHeight * index,
height: expectedRowHeight,
- startTime: `${hour}:${isOdd ? '30' : '00'}`.padStart(5, '0'),
- endTime: (isOdd ? `${hour + 1}:00` : `${hour}:30`).padStart(5, '0'),
+ startTime: `${hour}:${timeStep[count] != 0 ? timeStep[count] : '00'}`.padStart(5, '0'),
+ endTime: (count === (timeStep.length - 1) ? `${hour + 1}:00` : `${hour}:` + timeStep[count+1]).padStart(5, '0'),
});
+ count++;
});
}
@@ -526,7 +529,7 @@ describe('createTimeGridData', () => {
const rows = getWeekDates(new TZDate('2021-01-28T00:00:00'), {
startDayOfWeek: Day.SUN,
});
- const options = { hourStart: 0, hourEnd: 24 };
+ const options = { hourStart: 0, hourEnd: 24, timeStep: [0,30] };
// When
const result = createTimeGridData(rows, options);
@@ -541,7 +544,7 @@ describe('createTimeGridData', () => {
const rows = getWeekDates(new TZDate('2021-01-28T00:00:00'), {
startDayOfWeek: Day.SUN,
});
- const options = { hourStart: 0, hourEnd: 12 };
+ const options = { hourStart: 0, hourEnd: 12, timeStep: [0,30] };
// When
const result = createTimeGridData(rows, options);
@@ -556,7 +559,7 @@ describe('createTimeGridData', () => {
const rows = getWeekDates(new TZDate('2021-01-28T00:00:00'), {
startDayOfWeek: Day.SUN,
});
- const options = { hourStart: 12, hourEnd: 24 };
+ const options = { hourStart: 12, hourEnd: 24, timeStep: [0,30] };
// When
const result = createTimeGridData(rows, options);
@@ -572,7 +575,7 @@ describe('createTimeGridData', () => {
const rows = getWeekDates(new TZDate('2021-01-28T00:00:00'), {
startDayOfWeek: Day.SUN,
});
- const options = { hourStart: 0, hourEnd: 24, narrowWeekend };
+ const options = { hourStart: 0, hourEnd: 24, narrowWeekend, timeStep: [0,30] };
// When
const result = createTimeGridData(rows, options);
diff --git a/apps/calendar/src/helpers/grid.ts b/apps/calendar/src/helpers/grid.ts
index 73c51565c..cbdaa6d52 100644
--- a/apps/calendar/src/helpers/grid.ts
+++ b/apps/calendar/src/helpers/grid.ts
@@ -422,20 +422,25 @@ export function createTimeGridData(
hourStart: number;
hourEnd: number;
narrowWeekend?: boolean;
+ timeStep: number[];
}
): TimeGridData {
const columns = getColumnsData(datesOfWeek, options.narrowWeekend ?? false);
-
- const steps = (options.hourEnd - options.hourStart) * 2;
+ const { timeStep } = options;
+ const steps = (options.hourEnd - options.hourStart) * timeStep.length;
const baseHeight = 100 / steps;
+ let count = 0;
const rows = range(steps).map((step, index) => {
- const isOdd = index % 2 === 1;
- const hour = options.hourStart + Math.floor(step / 2);
- const startTime = `${hour}:${isOdd ? '30' : '00'}`.padStart(5, '0') as FormattedTimeString;
- const endTime = (isOdd ? `${hour + 1}:00` : `${hour}:30`).padStart(
+ count = count === timeStep.length ? 0 : count;
+ const hour = options.hourStart + Math.floor(step / timeStep.length);
+ const startTime = `${hour}:${timeStep[count] !== 0 ? timeStep[count] : '00'}`.padStart(
5,
'0'
) as FormattedTimeString;
+ const endTime = (
+ count === timeStep.length - 1 ? `${hour + 1}:00` : `${hour}:${timeStep[count + 1]}`
+ ).padStart(5, '0') as FormattedTimeString;
+ count += 1;
return {
top: baseHeight * index,
diff --git a/apps/calendar/src/hooks/gridSelection/useGridSelection.spec.tsx b/apps/calendar/src/hooks/gridSelection/useGridSelection.spec.tsx
index 64caa29b4..00c3dd534 100644
--- a/apps/calendar/src/hooks/gridSelection/useGridSelection.spec.tsx
+++ b/apps/calendar/src/hooks/gridSelection/useGridSelection.spec.tsx
@@ -372,7 +372,7 @@ describe('useGridSelection', () => {
workweek: false,
});
- const timeGridData = createTimeGridData(weekDates, { hourStart: 0, hourEnd: 24 });
+ const timeGridData = createTimeGridData(weekDates, { hourStart: 0, hourEnd: 24, timeStep: [0,30] });
describe('Opening popup', () => {
it('should open event form popup after dragging when the `useFormPopup` option is enabled', () => {
diff --git a/apps/calendar/src/hooks/timeGrid/useTimeGridEventMove.spec.tsx b/apps/calendar/src/hooks/timeGrid/useTimeGridEventMove.spec.tsx
index 2f1602fbd..3857fef5e 100644
--- a/apps/calendar/src/hooks/timeGrid/useTimeGridEventMove.spec.tsx
+++ b/apps/calendar/src/hooks/timeGrid/useTimeGridEventMove.spec.tsx
@@ -21,7 +21,7 @@ describe('useTimeGridEventMove', () => {
const rows = getWeekDates(createDate(2021, 2, 14), {
startDayOfWeek: Day.SUN,
});
- const timeGridData = createTimeGridData(rows, { hourStart: 0, hourEnd: 24 });
+ const timeGridData = createTimeGridData(rows, { hourStart: 0, hourEnd: 24, timeStep: [0,30] });
const DEFAULT_CONTAINER_WIDTH = 70;
const DEFAULT_CONTAINER_HEIGHT = 480;
diff --git a/apps/calendar/src/hooks/timeGrid/useTimeGridEventMove.ts b/apps/calendar/src/hooks/timeGrid/useTimeGridEventMove.ts
index a137d5401..ae0bbe375 100644
--- a/apps/calendar/src/hooks/timeGrid/useTimeGridEventMove.ts
+++ b/apps/calendar/src/hooks/timeGrid/useTimeGridEventMove.ts
@@ -7,19 +7,17 @@ import { useCurrentPointerPositionInGrid } from '@src/hooks/event/useCurrentPoin
import { useDraggingEvent } from '@src/hooks/event/useDraggingEvent';
import type EventUIModel from '@src/model/eventUIModel';
import type TZDate from '@src/time/date';
-import { addMilliseconds, addMinutes, MS_PER_DAY, MS_PER_THIRTY_MINUTES } from '@src/time/datetime';
+import { addMilliseconds, addMinutes, getTimeSteps, MS_PER_DAY } from '@src/time/datetime';
import { isNil, isPresent } from '@src/utils/type';
import type { GridPosition, GridPositionFinder, TimeGridData } from '@t/grid';
import type { CalendarState } from '@t/store';
-const THIRTY_MINUTES = 30;
-
-function getCurrentIndexByTime(time: TZDate, hourStart: number) {
+function getCurrentIndexByTime(time: TZDate, hourStart: number, STEP_MINUTES: number) {
const hour = time.getHours() - hourStart;
const minutes = time.getMinutes();
- return hour * 2 + Math.floor(minutes / THIRTY_MINUTES);
+ return hour * (60 / STEP_MINUTES) + Math.floor(minutes / STEP_MINUTES);
}
function getMovingEventPosition({
@@ -35,9 +33,10 @@ function getMovingEventPosition({
timeGridDataRows: TimeGridData['rows'];
currentDate: TZDate;
}) {
+ const { STEP_MINUTES, MS_PER_STEP_MINUTES } = getTimeSteps(timeGridDataRows);
const rowHeight = timeGridDataRows[0].height;
const maxHeight = rowHeight * timeGridDataRows.length;
- const millisecondsDiff = rowDiff * MS_PER_THIRTY_MINUTES + columnDiff * MS_PER_DAY;
+ const millisecondsDiff = rowDiff * MS_PER_STEP_MINUTES + columnDiff * MS_PER_DAY;
const hourStart = Number(timeGridDataRows[0].startTime.split(':')[0]);
const { goingDuration = 0, comingDuration = 0 } = draggingEvent.model;
@@ -45,8 +44,11 @@ function getMovingEventPosition({
const comingEnd = addMinutes(draggingEvent.getEnds(), comingDuration);
const nextStart = addMilliseconds(goingStart, millisecondsDiff);
const nextEnd = addMilliseconds(comingEnd, millisecondsDiff);
- const startIndex = Math.max(getCurrentIndexByTime(nextStart, hourStart), 0);
- const endIndex = Math.min(getCurrentIndexByTime(nextEnd, hourStart), timeGridDataRows.length - 1);
+ const startIndex = Math.max(getCurrentIndexByTime(nextStart, hourStart, STEP_MINUTES), 0);
+ const endIndex = Math.min(
+ getCurrentIndexByTime(nextEnd, hourStart, STEP_MINUTES),
+ timeGridDataRows.length - 1
+ );
const isStartAtPrevDate =
nextStart.getFullYear() < currentDate.getFullYear() ||
@@ -74,6 +76,7 @@ export function useTimeGridEventMove({
gridPositionFinder: GridPositionFinder;
timeGridData: TimeGridData;
}) {
+ const { MS_PER_STEP_MINUTES } = getTimeSteps(timeGridData.rows);
const initX = useStore(initXSelector);
const initY = useStore(initYSelector);
@@ -126,9 +129,9 @@ export function useTimeGridEventMove({
return addMilliseconds(
startDateTime,
- gridDiff.rowDiff * MS_PER_THIRTY_MINUTES + gridDiff.columnDiff * MS_PER_DAY
+ gridDiff.rowDiff * MS_PER_STEP_MINUTES + gridDiff.columnDiff * MS_PER_DAY
);
- }, [gridDiff, startDateTime]);
+ }, [gridDiff, startDateTime, MS_PER_STEP_MINUTES]);
const movingEvent = useMemo(() => {
if (isNil(draggingEvent) || isNil(currentGridPos) || isNil(gridDiff)) {
diff --git a/apps/calendar/src/hooks/timeGrid/useTimeGridEventResize.ts b/apps/calendar/src/hooks/timeGrid/useTimeGridEventResize.ts
index 165c8a546..4a3c01660 100644
--- a/apps/calendar/src/hooks/timeGrid/useTimeGridEventResize.ts
+++ b/apps/calendar/src/hooks/timeGrid/useTimeGridEventResize.ts
@@ -8,7 +8,7 @@ import { useCurrentPointerPositionInGrid } from '@src/hooks/event/useCurrentPoin
import { useDraggingEvent } from '@src/hooks/event/useDraggingEvent';
import type EventUIModel from '@src/model/eventUIModel';
import type TZDate from '@src/time/date';
-import { addMinutes, max, setTimeStrToDate } from '@src/time/datetime';
+import { addMinutes, getTimeSteps, max, setTimeStrToDate } from '@src/time/datetime';
import { findLastIndex } from '@src/utils/array';
import { isNil, isPresent } from '@src/utils/type';
@@ -198,7 +198,8 @@ export function useTimeGridEventResize({
),
-comingDuration
);
- const minEndDate = addMinutes(resizingStartUIModel.getStarts(), 30);
+ const { STEP_MINUTES } = getTimeSteps(timeGridData.rows);
+ const minEndDate = addMinutes(resizingStartUIModel.getStarts(), STEP_MINUTES);
eventBus.fire('beforeUpdateEvent', {
event: resizingStartUIModel.model.toEventObject(),
diff --git a/apps/calendar/src/slices/options.ts b/apps/calendar/src/slices/options.ts
index cf980834d..61484b968 100644
--- a/apps/calendar/src/slices/options.ts
+++ b/apps/calendar/src/slices/options.ts
@@ -65,6 +65,7 @@ function initializeWeekOptions(weekOptions: Options['week'] = {}): CalendarWeekO
eventView: true,
taskView: true,
collapseDuplicateEvents: false,
+ timeStep: [0, 30],
...weekOptions,
};
diff --git a/apps/calendar/src/time/datetime.ts b/apps/calendar/src/time/datetime.ts
index ec89da0b2..20ed10bab 100644
--- a/apps/calendar/src/time/datetime.ts
+++ b/apps/calendar/src/time/datetime.ts
@@ -6,6 +6,7 @@ import { fill } from '@src/utils/array';
import { InvalidDateTimeFormatError } from '@src/utils/error';
import type { TimeUnit } from '@t/events';
+import type { TimeGridRow } from '@t/grid';
import type { CellStyle, FormattedTimeString } from '@t/time/datetime';
export enum Day {
@@ -117,9 +118,25 @@ export const MS_PER_MINUTES = 60000;
* The number of milliseconds 20 minutes for event min duration
*/
export const MS_EVENT_MIN_DURATION = 20 * MS_PER_MINUTES;
-export const MS_PER_THIRTY_MINUTES = 30 * 60 * 1000;
export const SIXTY_SECONDS = 60;
+/**
+ * Returns the minutes, milliseconds, and step count from the timeGridRow
+ * @param timeGridRows
+ * @returns Object
+ */
+export function getTimeSteps(timeGridRows: TimeGridRow[]) {
+ const hourStart = Number(timeGridRows[0].startTime.split(':', 1));
+ const hourEnd = Number(timeGridRows[timeGridRows.length - 1].endTime.split(':', 1));
+ const STEPS = timeGridRows.length / (hourEnd - hourStart);
+ const STEP_MINUTES = 60 / STEPS;
+ return {
+ STEPS,
+ STEP_MINUTES,
+ MS_PER_STEP_MINUTES: STEP_MINUTES * 60 * 1000,
+ };
+}
+
/**
* Return formatted string as basis of supplied string.
*
diff --git a/apps/calendar/src/types/options.ts b/apps/calendar/src/types/options.ts
index 073908f0c..ebbefa497 100644
--- a/apps/calendar/src/types/options.ts
+++ b/apps/calendar/src/types/options.ts
@@ -30,6 +30,7 @@ export interface WeekOptions {
eventView?: boolean | EventView[];
taskView?: boolean | TaskView[];
collapseDuplicateEvents?: boolean | Partial;
+ timeStep?: number[];
}
export interface MonthOptions {
diff --git a/apps/calendar/stories/column.stories.tsx b/apps/calendar/stories/column.stories.tsx
index bf40f3946..5dede431e 100644
--- a/apps/calendar/stories/column.stories.tsx
+++ b/apps/calendar/stories/column.stories.tsx
@@ -25,7 +25,7 @@ function Wrapper({ children }: PropsWithChildren) {
function getTimeGridData() {
const now = new TZDate();
const weekDates = getWeekDates(now, { startDayOfWeek: 0, workweek: false });
- return createTimeGridData(weekDates, { hourStart: 0, hourEnd: 24 });
+ return createTimeGridData(weekDates, { hourStart: 0, hourEnd: 24, timeStep: [0,30] });
}
const Template: StoryFn> = (args) => (
diff --git a/apps/calendar/stories/e2e/week.stories.tsx b/apps/calendar/stories/e2e/week.stories.tsx
index 3590d1467..cd15d1dd2 100644
--- a/apps/calendar/stories/e2e/week.stories.tsx
+++ b/apps/calendar/stories/e2e/week.stories.tsx
@@ -59,6 +59,18 @@ HourStartOption.args = {
},
};
+export const TimeStepOption = Template.bind({});
+TimeStepOption.args = {
+ ...Template.args,
+ options: {
+ ...Template.args.options,
+ week: {
+ timeStep: [0,15,30,45],
+ showNowIndicator: false,
+ }
+ }
+}
+
export const DifferentPrimaryTimezone = Template.bind({});
DifferentPrimaryTimezone.args = {
...Template.args,
diff --git a/apps/calendar/stories/timegrid.stories.tsx b/apps/calendar/stories/timegrid.stories.tsx
index e49f32504..339954a65 100644
--- a/apps/calendar/stories/timegrid.stories.tsx
+++ b/apps/calendar/stories/timegrid.stories.tsx
@@ -86,7 +86,7 @@ function getEvents() {
function getTimeGridData() {
const now = new TZDate();
const weekDates = getWeekDates(now, { startDayOfWeek: 0, workweek: false });
- return createTimeGridData(weekDates, { hourStart: 0, hourEnd: 24 });
+ return createTimeGridData(weekDates, { hourStart: 0, hourEnd: 24, timeStep: [0,30] });
}
type TimeGridProps = ComponentProps;
diff --git a/docs/assets/options_week-timeStep-after.png b/docs/assets/options_week-timeStep-after.png
new file mode 100644
index 000000000..f407714e7
Binary files /dev/null and b/docs/assets/options_week-timeStep-after.png differ
diff --git a/docs/assets/options_week-timeStep-before.png b/docs/assets/options_week-timeStep-before.png
new file mode 100644
index 000000000..407ba15bb
Binary files /dev/null and b/docs/assets/options_week-timeStep-before.png differ
diff --git a/docs/en/apis/options.md b/docs/en/apis/options.md
index 82669b760..f6e37a873 100644
--- a/docs/en/apis/options.md
+++ b/docs/en/apis/options.md
@@ -173,6 +173,7 @@ interface WeekOptions {
eventView?: boolean | EventView[];
taskView?: boolean | TaskView[];
collapseDuplicateEvents?: boolean | CollapseDuplicateEvents;
+ timeStep?: number[];
}
```
@@ -190,6 +191,7 @@ const DEFAULT_WEEK_OPTIONS = {
eventView: true,
taskView: true,
collapseDuplicateEvents: false,
+ timeStep: [0,30],
};
```
@@ -478,6 +480,26 @@ calendar.setOptions({
[⬆ Back to the list](#week)
+### week.timeStep
+
+- Type: `number[]`
+- Default: `[0,30]`
+
+You can specify in increments of how many minutes the selection in the calendar (weekly and daily view) will be allowed, as well as the movement and adjustment of event times.
+
+```js
+calendar.setOptions({
+ week: {
+ timeStep: [0,15,30,45],
+ },
+});
+```
+| Default | Example |
+| ----------------------------------------------------------------------- | ---------------------------------------------------------------------- |
+|  |  |
+
+[⬆️ Back to the list](#week)
+
### month
- Type: `MonthOptions`