이벤트 대화상자

DayFlow에는 별도 설정 없이도 완결된 이벤트 관리 경험을 제공하는 강력한 내장 이벤트 대화상자가 들어 있습니다. 직관적인 인터페이스로 이벤트를 만들고, 수정하고, 삭제할 수 있습니다.

내장 반복 편집기

이벤트를 편집할 수 있는 경우 기본 플로팅 상세 패널과 모달 대화상자에 동일한 반복 편집기가 표시됩니다.

  • 반복에서는 반복 안 함, 매일, 매주, 매월, 매년, 사용자 지정을 선택할 수 있습니다.
  • 사용자 지정은 빈도와 간격을 선택하고, 주간 규칙에서는 하나 이상의 요일을 고를 수 있는 별도 대화상자를 엽니다.
  • 반복 종료는 없음, 지정한 날짜 또는 지정한 횟수 이후로 설정할 수 있습니다.

반복 설정은 이벤트의 meta.recurringmeta.recurrenceRule에 저장됩니다. 월 뷰는 지원되는 규칙을 표시 범위의 반복 이벤트로 확장하고, 시간이 지정된 이벤트를 캘린더에 설정된 시간대의 시작 시각순으로 정렬합니다. 현재 생성된 반복 이벤트를 수정하거나 삭제하면 전체 시리즈에 적용되며, 한 번의 반복만 수정하는 기능은 아직 지원되지 않습니다.

import { Temporal } from 'temporal-polyfill';

const weeklyReview = {
  id: 'review',
  title: '디자인 리뷰',
  start: Temporal.PlainDateTime.from('2026-08-26T09:30'),
  end: Temporal.PlainDateTime.from('2026-08-26T10:30'),
  meta: {
    recurring: true,
    recurrenceRule: 'FREQ=WEEKLY;INTERVAL=2;BYDAY=MO,WE;COUNT=10',
  },
};

사용법

DayFlow는 기본적으로 내장 플로팅 상세 패널을 렌더링합니다. 대신 내장 모달 대화상자를 쓰려면 useCalendarApp에서 useEventDetailDialog를 켜고 DayFlowCalendar를 평소처럼 렌더링하세요.

import { useCalendarApp, DayFlowCalendar } from '@dayflow/react';

const calendar = useCalendarApp({
  views: [...],
  useEventDetailDialog: true,
});

<DayFlowCalendar calendar={calendar} />;
<template>
  <DayFlowCalendar :calendar="calendar" />
</template>

<script setup>
import { DayFlowCalendar, useCalendarApp } from '@dayflow/vue';

const calendar = useCalendarApp({
  views: [...],
  useEventDetailDialog: true,
});
</script>
import { Component } from '@angular/core';
import { DayFlowCalendarModule } from '@dayflow/angular';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [DayFlowCalendarModule],
  template: `<dayflow-calendar [calendar]="calendar"></dayflow-calendar>`
})
export class AppComponent {
  calendar = {
    views: [...],
    useEventDetailDialog: true,
  };
}
<script>
  import { DayFlowCalendar, useCalendarApp } from '@dayflow/svelte';

  const calendar = useCalendarApp({
    views: [...],
    useEventDetailDialog: true,
  });
</script>

<DayFlowCalendar {calendar} />

커스터마이징

대화상자 UI 교체하기

eventDetailDialog 슬롯을 사용하면 DayFlow의 열기·닫기 상태 관리는 그대로 두고 직접 만든 대화상자 컴포넌트로 교체할 수 있습니다. useCalendarApp 설정에 useEventDetailDialog: true가 필요합니다.

// 1. Enable dialog mode in the calendar config
const calendar = useCalendarApp({
  views: [...],
  useEventDetailDialog: true,
});

// 2. Provide your own dialog via the slot
<DayFlowCalendar
  calendar={calendar}
  eventDetailDialog={({ event, isOpen, onClose }) => (
    <MyDialog isOpen={isOpen} onClose={onClose}>
      <EventForm event={event} />
    </MyDialog>
  )}
/>
<template>
  <DayFlowCalendar :calendar="calendar">
    <template #eventDetailDialog="{ event, isOpen, onClose }">
      <MyDialog :isOpen="isOpen" @close="onClose()">
        <EventForm :event="event" />
      </MyDialog>
    </template>
  </DayFlowCalendar>
</template>

<script setup>
import { DayFlowCalendar, useCalendarApp } from '@dayflow/vue';
import MyDialog from './MyDialog.vue';
import EventForm from './EventForm.vue';

const calendar = useCalendarApp({
  views: [...],
  useEventDetailDialog: true,
});
</script>
<!-- app.component.html -->
<dayflow-calendar
  [calendar]="calendar"
  [eventDetailDialog]="dialog"
>
</dayflow-calendar>

<ng-template #dialog let-args>
  <my-dialog [isOpen]="args.isOpen" (close)="args.onClose()">
    <event-form [event]="args.event"></event-form>
  </my-dialog>
</ng-template>
<DayFlowCalendar {calendar} eventDetailDialog={MyCustomDialog} />

<!-- MyCustomDialog.svelte -->
<script lang="ts">
  import type { EventDetailDialogSlotArgs } from '@dayflow/core';
  import MyDialog from './MyDialog.svelte';
  import EventForm from './EventForm.svelte';

  let { event, isOpen, onClose } = $props<EventDetailDialogSlotArgs>();
</script>

<MyDialog {isOpen} {onClose}>
  <EventForm {event} />
</MyDialog>

내장 패널 사용하지 않기

애플리케이션이 콜백이나 전역 상태로 제어하는 자체 모달에서 이벤트 상세를 관리한다면, useCalendarApp 설정에 useEventDetailPanel: false를 지정해 내장 플로팅 패널을 완전히 끌 수 있습니다:

import { useCalendarApp, DayFlowCalendar } from '@dayflow/react';

const calendar = useCalendarApp({
  // ...
  useEventDetailPanel: false,
});

<DayFlowCalendar calendar={calendar} />;
<template>
  <DayFlowCalendar :calendar="calendar" />
</template>

<script setup>
import { DayFlowCalendar, useCalendarApp } from '@dayflow/vue';

const calendar = useCalendarApp({
  // ...
  useEventDetailPanel: false,
});
</script>
import { Component } from '@angular/core';
import { DayFlowCalendarModule } from '@dayflow/angular';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [DayFlowCalendarModule],
  template: `<dayflow-calendar [calendar]="calendar"></dayflow-calendar>`
})
export class AppComponent {
  calendar = {
    // ...
    useEventDetailPanel: false,
  };
}
<script>
  import { DayFlowCalendar, useCalendarApp } from '@dayflow/svelte';

  const calendar = useCalendarApp({
    // ...
    useEventDetailPanel: false,
  });
</script>

<DayFlowCalendar {calendar} />

이 방식은 React, Vue, Svelte, Angular 어댑터에서 모두 동일하게 동작합니다.