콘텐츠로 이동
Data Table사용 가이드

행 설정과 이동

comins-table@0.2.2

아래 Playground 경로는 해당 모듈 저장소에서 개발 서버를 실행한 뒤 사용하는 로컬 경로입니다. 현재 문서 사이트의 실행 링크는 아닙니다.

Row interaction은 React event prop으로 받습니다. 이벤트 payload는 event, row, index를 포함합니다.

<CominsTable
columns={[{ field: "name", label: "Name" }]}
data={data}
getRowId={(row) => row.id}
onClickRow={({ row }) => console.log("click", row.id, row.index)}
onContextMenuRow={({ event, row }) => {
event.preventDefault();
openMenu(row.id);
}}
onDoubleClickRow={({ row }) => console.log("double", row.id)}
onKeyDownRow={({ event, row }) => console.log(event.key, row.id)}
rowProps={{
className: (row) => (row.role === "Owner" ? "row-owner" : undefined),
disabled: (row) => row.locked === true,
draggable: (row) => row.locked !== true,
style: (row) => (row.active ? { background: "#2f0f5f" } : undefined),
}}
/>

기본 clipboard={false}의 Row copy/paste는 focused row에서 Ctrl+C, Ctrl+V로 동작하며 paste mode는 insert-after입니다. Row 위치 이동은 cell range drag와 충돌하지 않도록 첫 번째 cell 안의 Row drag handle을 기준으로 수행합니다.

onBeforeRowDrag, onRowDrag, onAfterDragRow는 onChangeData 또는 Cross-Table Coordinator의 model 소유권을 변경하지 않고 handle gesture를 관찰하고 제어합니다.

  • onBeforeRowDrag(payload)는 pointer listener 등록 전에 실행합니다. false를 반환하면 gesture를 시작하지 않으며 이후 callback도 호출하지 않습니다.
  • onRowDrag(payload)는 raw pointer move마다 실행하지 않고 CominsRowDragTarget의 identity 또는 validity가 바뀔 때만 실행합니다.
  • onAfterDragRow(payload)는 시작된 gesture마다 정확히 한 번 실행하며 CominsRowDragResult (moved, cancelled, rejected)와 CominsRowDragReason (drop, unchanged, invalid-target, duplicate-id, escape, blur 등)을 전달합니다.

CominsBeforeRowDragPayload, CominsRowDragPayload, CominsAfterDragRowPayload는 typed source Row, 선택적인 source Group/Table identity, pointer event와 target identity를 유지합니다. 같은 Table, 다른 Group, Cross-Table Row gesture가 같은 lifecycle 계약을 사용하지만 Cross-Table model 변경은 계속 Coordinator가 소유합니다.

rowProps.draggable은 0.1.11부터 기본값이 false입니다. true 또는 Row별로 true를 반환하는 함수를 지정하면 핸들을 표시하고 이동을 활성화합니다. 비활성·잠금·미지원 Row에는 핸들을 표시하지 않습니다. rowProps.disabled는 row와 cell interaction 전체를 차단하고, rowProps.draggable은 row 이동 gesture만 차단합니다. 비활성 row의 기본 배경과 글자색은 theme CSS 변수 --comins-table-row-disabled-background, --comins-table-row-disabled-color로 조정합니다.

<CominsTable
columns={columns}
data={data}
getRowId={(row) => row.id}
rowProps={{
disabled: (row) => row.status === "archived",
draggable: (row) => row.status !== "locked",
}}
/>

setMoveTargetRow(targetIdx, sourceIdx)는 현재 화면에 보이는 row index 기준으로 source row를 target 위치로 이동합니다. sort가 적용된 상태에서는 sort를 해제한 뒤 이동 결과를 data 순서에 반영합니다.

const tableRef = useRef<CominsTableRef<PersonRow>>(null);
tableRef.current?.setMoveTargetRow(2, 0);

/api/ref (/api/ref) live 예제는 setMoveTargetRow(2, 0)이 active sort를 해제하고 visible Row 이동 결과를 controlled onChangeData로 반영하는 흐름을 보여줍니다.

기본 rowSelectionOnClick={true}의 선택 기준:

  • 최초 렌더링 시 row selection은 없습니다.
  • 일반 click은 단일 row를 선택합니다.
  • Ctrl 또는 Cmd click은 row 선택을 toggle합니다.
  • Shift click은 마지막 active row부터 클릭한 row까지 visible range를 선택합니다.
  • Sort 이후에도 selection은 row id 기준으로 유지됩니다.
  • data 배열이 교체되면 selection은 초기화됩니다.
  • 이미 선택된 row를 우클릭하면 현재 단일/다중 selection을 유지합니다.
  • 선택되지 않은 row를 우클릭하면 해당 row를 단독 선택합니다. Cell context menu도 같은 Row 정책을 적용한 뒤 Cell focus를 갱신합니다.
  • 선택 row에는 data-selected-row="true"와 comins-row-selected class가 적용됩니다.
  • 기본 playground 스타일은 선택 row의 tr에 COMINS mint 배경색을 적용하고, td 배경은 투명하게 둡니다.
  • Row styling playground는 rowProps.className과 rowProps.style.background를 함께 사용해 기본 테마와 확실히 다른 배경, 글자색, font, border를 보여줍니다.
  • Context menu 예제는 선택한 row/cell data object와 선택 0/1/N에 따른 조회·추가·수정·삭제 활성화 상태를 보여줍니다.
  • Row drag handle은 Row 이동 전용 gesture이며, 같은 column의 cell drag는 range selection으로만 처리합니다.
선택 Row 수 조회 (View) 추가 (Create) 수정 (Update) 삭제 (Delete)
0 활성 활성 비활성 비활성
1 활성 활성 활성 활성
N 활성 활성 비활성 활성

메뉴 실행 결과는 Playground Alert에 표시됩니다. Create는 새 Row를 추가하고 Delete는 선택한 Row를 예제 데이터에서 삭제합니다. View와 Update는 선택한 동작을 안내합니다.

Playground 검증 기준:

  • Tr Row 예제는 row click, double click, context menu, keyboard event가 각각 어떤 callback을 발생시키는지 inline Alert로 보여줍니다.
  • Row drag 중에는 이동할 위치를 보여주는 placeholder를 표시합니다.
  • Row drag 검증은 drag handle을 source로 사용하고, cell drag가 row reorder로 해석되지 않는지 함께 확인합니다.
  • Selection 검증은 내부 state가 아니라 tr의 DOM attribute와 computed CSS를 기준으로 합니다.
  • Row selection 관련 작업은 initial no-selection, single selection, Ctrl/Cmd toggle, Shift range, sort 후 유지, data 교체 시 초기화를 각각 증거로 남깁니다.
  • 사용자가 selection 색상 또는 초기화 문제를 지적한 경우 browser proof에는 selected row의 data-selected-row, background-color, 관련 event 결과를 포함합니다.

columnFiltering을 설정하면 일부만 보일 수 있는 projection에서 이동 의미가 모호하므로 Row Drag와 setMoveTargetRow를 비활성화합니다. 지원되는 Row Grouping 결합의 Group Drag는 별도 Group-model operation으로 유지합니다.

rowSelectionOnClick={false}이면 Cell 조작 중에도 Row 선택을 유지합니다. getSelectedRows, getSelectedCells, getSelection으로 Row 데이터·Cell 값·선택 ID를 각각 조회합니다. Viewport 선택 setter는 절대 인덱스를 받고 미로딩 Row를 건너뛰며 Row 이동은 지원하지 않습니다. Selection을 참고합니다. Tree 이동은 별도 treeRowDrag 설정과 Tree lifecycle payload 타입을 사용하며 Tree Grid에 설명합니다.

Row 또는 Group을 현재 보이는 Table의 위·아래 가장자리로 드래그하면 해당 Table이 자동 스크롤됩니다. 가상화된 Row가 새로 표시될 때도 드롭 대상을 다시 계산하며, 드롭 또는 취소하면 스크롤을 중단합니다. 데이터 기반의 고정 Row ID를 사용합니다. 일반 Row의 내부 이동에는 onChangeData가 필수가 아니며, 옵션만 바뀌는 렌더링에서는 이동 순서를 유지합니다. 외부 상태 동기화가 필요할 때 콜백을 연결하며, 새로운 data 배열을 전달하면 내부 데이터를 교체합니다. Viewport Datasource는 Row Drag를 지원하지 않습니다.


실행 가능한 대표 예제 · 배포 기준 원본 가이드