레퍼런스

상세 렌더러

`renderDetail`의 타입인 `GanttDetailRenderer`와 `GanttDetailRenderProps`예요

renderDetail은 상세 패널의 본문을 대체하는 render prop이에요. 타입은 @jaeungkim/gantt-chart에서 가져와요. 동작과 실제 예제는 상세 패널을 참고하세요.

import type {
  GanttDetailRenderer,
  GanttDetailRenderProps,
  Task,
} from '@jaeungkim/gantt-chart';

Task와 TaskTransformed는 Task와 작업 타입에, GanttScaleKey는 배율과 테마 타입에 정리돼 있어요. ReactNode는 react의 타입이에요.

GanttDetailRenderer

src/shared/types.ts
/** `renderDetail` 오버라이드에 전달되는 props */
export interface GanttDetailRenderProps {
  task: TaskTransformed;
  /** 패널을 닫아요 - 직접 만든 닫기 컨트롤에 연결하세요 */
  close: () => void;
  scale: GanttScaleKey;
  /**
   * 차트의 일반 확정 경로(스토어, 그다음 `onTasksChange`)로 열린 작업을 패치해요.
   * 그래서 커스텀 본문이 비제어 모드에서 편집을 확정할 수 있어요. 권한 검사는 전혀
   * 하지 않아요 - 규칙은 커스텀 본문이 직접 지켜야 해요.
   */
  update: (patch: Partial<Omit<Task, 'id'>>) => void;
}

export type GanttDetailRenderer = (props: GanttDetailRenderProps) => ReactNode;

필드

필드타입값
taskTaskTransformed지금 열린 작업이에요. 차트가 변환한 형태 그대로예요
close() => void패널을 닫아요. 내장 닫기 버튼이 호출하는 함수와 같아요
scaleGanttScaleKey현재 선택된 배율이에요
update(patch: Partial<Omit<Task, 'id'>>) => void차트가 편집을 확정하는 경로로 열린 작업을 패치해요

예제

const renderDetail: GanttDetailRenderer = ({ task, close, scale, update }) => (
  <>
    <button type="button" onClick={close} aria-label="Close task details">
      Close
    </button>
    <h2>{task.name}</h2>
    <p>
      {task.startDate.slice(0, 10)} to {task.endDate.slice(0, 10)} ({scale})
    </p>
    <button type="button" onClick={() => update({ progress: 100 })}>
      Mark done
    </button>
  </>
);

제약

렌더러가 채우는 것은 패널의 자식 노드예요. 펼쳐 넘길 props 묶음은 따로 없어요. 렌더러를 받는 prop은 이것 하나예요.

  • <aside class="gantt-detail" role="complementary" aria-label="Task details"> 요소는 차트가 직접 렌더링해요. 너비는 --gantt-detail-width 커스텀 속성(320px)이 정해요. 렌더러는 너비를 바꾸지 않아요.
  • 커스텀 본문을 넘기면 내장 닫기 버튼도 함께 사라져요. close는 그 버튼이 호출하던 함수와 같아요. Escape는 본문에 닫기 컨트롤이 없어도 페이지 어디에서나 패널을 닫아요.
  • null이나 undefined를 반환하면 기본 본문이 아니라 빈 패널이 렌더링돼요.
  • showDetail을 생략하면 렌더러를 넘기는 것만으로 패널이 켜져요. showDetail={false}를 직접 지정하면 그대로 꺼진 채로 남아요.
  • 렌더러는 항상 작업을 하나 받아요. 패널을 닫아도 바로 언마운트되지는 않아요. 패널은 200ms 닫기 트랜지션 동안 마지막 작업을 유지해요. transitionend가 발생하지 않으면 400ms 타이머가 그 작업을 놓아줘요. 그래서 마운트 사이드 이펙트가 있는 본문은 패널이 닫히는 동안 렌더를 몇 번 더 거쳐요. <aside>는 그 트랜지션이 끝난 뒤에 DOM에서 사라져요.
  • update는 내장 본문의 입력란과 같은 경로로 편집을 확정해요. 스토어에 먼저 반영하고 onTasksChange를 호출해요. 비제어 모드에서도 앱이 tasks를 다시 넘길 필요가 없어요.
  • update는 자체 검사를 하지 않아요. 상호작용 플래그와 날짜 범위 제한, 진행률 정규화는 내장 본문에만 적용돼요. 여기로 넘긴 패치는 스토어와 onTasksChange에 그대로 도달하니 필요한 규칙은 커스텀 본문에서 직접 검사하세요.
  • 타입에 id가 없어서 패치로 작업의 id는 바꿀 수 없어요. 패치는 항상 열린 작업에 적용돼요.
  • 기본 본문은 이름과 날짜, 기간을 보여줘요. 진행률과 선행 작업은 값이 있을 때만 나타나요. 행을 더하거나 캡션을 번역하는 prop은 없어요. 나머지 필드는 렌더러로만 패널에 넣을 수 있어요.

여기 나온 모든 prop은 GanttProps에 정리돼 있어요.