Package

@mycrm-ui/react-table

React 19 / React 18에서 사용 가능한 고성능 테이블 컴포넌트입니다.

@mycrm-ui/react-table은 헤드리스(Headless) 라이브러리입니다. 소스코드를 그대로 사용하면 스타일이 적용되지 않은 상태로 렌더링됩니다. 문서의 미리보기는 이해를 돕기 위해 별도 스타일을 적용한 예시입니다.

table_chart

기본 사용

LLM GuideViewerMD

columns, data, rowKey만으로 기본 테이블을 렌더링합니다.

이름이메일역할
홍길동hong@example.com관리자
김철수kim@example.com사용자
이영희lee@example.com사용자
sort

정렬

LLM GuideViewerMD

단일 정렬과 멀티 정렬을 모두 지원합니다.

단일 정렬

이름이메일역할나이
김철수kim@example.com사용자28
홍길동hong@example.com관리자35
이영희lee@example.com사용자42

멀티 정렬

Shift를 누른 채 컬럼 헤더를 클릭하면 순서대로 멀티 정렬이 적용됩니다.

카테고리1브랜드가격2
노트북삼성1,500,000원
노트북LG1,500,000원
노트북삼성1,200,000원
모니터LG450,000원
모니터삼성450,000원
모니터LG320,000원
check_box

체크박스 선택

LLM GuideViewerMD

selection 옵션으로 체크박스 행 선택을 활성화합니다. 헤더의 체크박스로 전체 선택/해제가 가능합니다.

Key이름이메일역할
1홍길동hong@example.com관리자
2김철수kim@example.com사용자
3이영희lee@example.com사용자
4박민수park@example.com편집자
5최지은choi@example.com사용자

selectedKeys

[]
filter_alt

필터

LLM GuideViewerMD

컬럼 단위 필터를 제공합니다. filterType으로 텍스트, 셀렉트, 날짜 범위, 숫자 범위 필터를 선택할 수 있습니다.

이름이메일역할
홍길동hong@example.com관리자
김철수kim@example.com사용자
이영희lee@example.com사용자
박민수park@example.com편집자
최지은choi@example.com사용자

filterValues

{}
edit_note

행 삭제 / 추가

LLM GuideViewerMD

rowActions 옵션으로 행 삭제/추가를 지원합니다.

  • deletable: true — 각 행에 삭제 버튼 표시
  • adding: true + 컬럼의 insertable: true — 입력 필드가 자동 렌더링
  • selection과 조합하면 체크박스 선택 후 일괄 삭제 가능
  • classNamesaddRow · addInput · addConfirmBtn · addCancelBtn으로 추가 행 스타일 커스터마이징
Key이름이메일역할
1홍길동hong@example.com관리자
2김철수kim@example.com사용자
3이영희lee@example.com사용자
4박민수park@example.com편집자
5최지은choi@example.com사용자
edit

인라인 편집

LLM GuideViewerMD

editable: true인 컬럼의 셀을 클릭하면 인라인 편집 모드로 전환됩니다.

  • validate — 저장 전 유효성 검증, 실패 시 error props로 메시지 전달
  • onCellChange — 편집 완료(Enter / blur) 시 변경된 값 수신
  • editing.renderCell — 모든 editable 컬럼에 공통 적용되는 편집 UI
  • renderEditCell — 특정 컬럼만 개별 편집 UI 지정 (renderCell보다 우선)
Key이름이메일역할
1홍길동edithong@example.comedit관리자edit
2김철수editkim@example.comedit사용자edit
3이영희editlee@example.comedit사용자edit
4박민수editpark@example.comedit편집자edit
5최지은editchoi@example.comedit사용자edit
hourglass_empty

로딩 / 빈 상태

LLM GuideViewerMD

loading.enabledtrue이면 데이터 대신 shimmer 스켈레톤 행을 렌더링합니다.

  • rowCount — 스켈레톤 행 개수 (기본값 3)
  • render — 커스텀 스켈레톤 UI (생략 시 기본 shimmer 사용)
  • renderEmpty — 데이터가 없을 때 렌더링할 컴포넌트
Key이름이메일역할
1홍길동hong@example.com관리자
2김철수kim@example.com사용자
3이영희lee@example.com사용자
4박민수park@example.com편집자
5최지은choi@example.com사용자
view_list

가상 스크롤

LLM GuideViewerMD

대용량 데이터를 위한 가상 스크롤과 무한 로딩을 지원합니다.

  • scroll.virtual — 가상 스크롤 활성화 (DOM에 보이는 행만 렌더링)
  • scroll.rowHeight — 행 높이(px), 가상 스크롤 사용 시 필수
  • scroll.stickyHeader — 스크롤 시 헤더 고정
  • scroll.onLoadMore — 끝에 도달하면 호출되는 무한 스크롤 콜백
  • classNames.wrap — 고정 높이 + overflow-y: auto 또는 overflow-y: scroll 설정 필수

50 / 300개 로드됨

ID이름이메일부서상태
1이지은user1@example.com디자인휴직
2박예진user2@example.com마케팅수습
3최준서user3@example.com영업재직
4정도현user4@example.com인사휴직
5강현우user5@example.com재무수습
6조나연user6@example.com개발재직
7윤서연user7@example.com디자인휴직
8장수빈user8@example.com마케팅수습
9임태양user9@example.com영업재직
10김민준user10@example.com인사휴직
11이지은user11@example.com재무수습
12박예진user12@example.com개발재직
13최준서user13@example.com디자인휴직
14정도현user14@example.com마케팅수습
15강현우user15@example.com영업재직
16조나연user16@example.com인사휴직
17윤서연user17@example.com재무수습
18장수빈user18@example.com개발재직
view_column

컬럼 관리

LLM GuideViewerMD

컬럼 숨김, 순서 변경, 고정(pin), 리사이즈를 지원합니다. 헤더 메뉴에서 컬럼 관리 모달을 열고, 드래그로 순서를 변경할 수 있습니다.

이름
이메일
부서
직책
입사일
홍길동hong@example.com개발팀장2020-03-15
김철수kim@example.com디자인시니어2021-07-01
이영희lee@example.com마케팅매니저2019-11-20
박민수park@example.com개발주니어2023-01-10
최지은choi@example.com영업팀장2018-05-22

상태

hiddenKeys: []

order: []

pinned: {}

widths: {}

expand_more

확장 행

LLM GuideViewerMD

ExpandDef로 그룹(부모)과 자식 행을 구분하여 계층형 테이블을 구성합니다. 자식 행 선택, 삭제, 아이콘 커스터마이징을 지원하며 childExpandDef로 다단계 중첩도 가능합니다.

이름직책이메일
chevron_right개발본부 (2팀 · 5명)
chevron_right디자인본부 (1팀 · 2명)

상태

expandedKeys: []

selectedChildKeys: []

mouse

행 클릭 / 키보드 내비게이션

LLM GuideViewerMD
행 클릭 · 더블클릭 · ↑↓ 이동 · Enter로 직책 편집
이름부서직책 (편집 가능)상태
홍길동개발팀장재직
김철수개발시니어재직
이영희디자인팀장재직
박민준기획매니저휴직
최지은개발주니어재직

포커스 셀

없음

이벤트 로그

아직 이벤트가 없습니다.

content_copy

툴팁 / 복사

LLM GuideViewerMD

tooltip을 켜면 셀 호버 시 값이 툴팁으로 표시됩니다.copyable을 켜면 copyable: true인 열에서 우클릭 컨텍스트 메뉴가 열립니다.onCellCopy로 복사 이벤트를 수신하고, cellContextMenuItems로 메뉴 항목을 추가할 수 있습니다.

상품명·SKU 셀에 호버하면 툴팁이 표시됩니다. 우클릭하면 복사 메뉴가 열립니다.

상품명SKU카테고리가격
MacBook Pro 14인치 M3 Pro 칩 36GB RAM 512GB SSD
MBP-14-M3PRO-36-512
노트북2,990,000원
iPhone 15 Pro Max 256GB 티타늄 내추럴
IPH-15PROMAX-256-NT
스마트폰1,890,000원
iPad Air M2 256GB Wi-Fi + Cellular 스타라이트
IPA-M2-256-CELL-SL
태블릿1,149,000원
AirPods Pro 2세대 USB-C MagSafe 충전 케이스
APP-2G-USBC-MAGSAFE
이어폰359,000원
Apple Watch Ultra 2 49mm 티타늄 오션 밴드
AW-ULTRA2-49-OCEAN
스마트워치1,249,000원

복사 로그

아직 복사된 값이 없습니다.

menu

헤더 메뉴

LLM GuideViewerMD

headerMenuIcon을 지정하면 헤더 우상단에 아이콘 버튼이 표시됩니다. 클릭 시 headerMenuItems 드롭다운이 열립니다. columnManager를 함께 설정하면 컬럼 관리 항목이 자동으로 추가됩니다.

테이블 우상단의 ⋯ 아이콘을 클릭하면 헤더 메뉴가 열립니다.

이름역할부서점수
홍길동개발자개발팀92
김철수디자이너디자인팀88
이영희기획자기획팀95
박민준개발자개발팀78
최지수마케터마케팅팀84

마지막 실행 메뉴

없음
palette

CSS 커스터마이징

LLM GuideViewerMD

classNames prop으로 모든 시각적 요소에 className 슬롯이 제공됩니다. 아래에서 테마를 선택해 차이를 확인하세요.

이름역할부서점수
홍길동개발자개발팀92
김철수디자이너디자인팀88
이영희기획자기획팀95
박민준개발자개발팀78
최지수마케터마케팅팀84

적용된 classNames — 기본표준 패딩과 구분선

<Table
  columns={columns}
  data={data}
  rowKey={(row) => String(row.id)}
  // ...기타 props

  classNames={{
    table: "w-full text-sm",
    thead: "bg-surface-container-low text-on-surface-variant",
    th: "px-4 py-3 text-left font-semibold",
    tr: "border-t border-outline-variant/20 hover:bg-surface-container-lowest transition-colors",
    td: "px-4 py-3 text-on-surface",
  }}
/>
슬롯적용 요소관련 기능사용 예시
기본 레이아웃
wrap테이블 최외곽 div스크롤 컨테이너 (height + overflow-y 설정)height: 400px; overflow-y: auto
table<table>기본border-collapse: collapse; width: 100%
thead<thead>기본position: sticky; top: 0; background: #fff; z-index: 10
th<th> (헤더 셀)기본padding: 8px 16px; text-align: left; font-weight: 600
tbody<tbody>기본border-top: 1px solid #eee
tr<tr> (데이터 행)기본border-bottom: 1px solid #eee
td<td> (데이터 셀)기본padding: 8px 16px; font-size: 14px
정렬
sortPriority다중 정렬 우선순위 숫자정렬color: #3b82f6; font-size: 11px; margin-left: 4px
체크박스 선택
checkbox<input type='checkbox'>선택accent-color: #3b82f6; cursor: pointer
checkboxChecked체크된 상태의 체크박스선택outline: 2px solid #3b82f6
필터
filterRow필터 입력 행 <tr>필터background: #f5f5f5
filterCell필터 행의 <th>필터padding: 6px
filterInput텍스트 / 날짜 / 숫자 범위 <input>필터border: 1px solid #ccc; border-radius: 4px; padding: 4px 8px; width: 100%
filterSelectselect 필터 <select>필터border: 1px solid #ccc; border-radius: 4px; padding: 4px 8px
인라인 편집
tdEditing편집 중인 <td>인라인 편집outline: 2px solid #3b82f6; background: #eff6ff
editError편집 에러 메시지인라인 편집color: #ef4444; font-size: 12px; margin-top: 4px
tdFocused키보드 포커스된 <td>키보드 내비게이션background: rgba(99, 102, 241, 0.1)
행 삭제 / 추가
addRow새 행 추가 <tr>행 추가background: #f0fdf4
addInput추가 행의 입력 필드행 추가border: 1px solid #ccc; border-radius: 4px; padding: 4px 8px; width: 100%
addConfirmBtn추가 확인 버튼행 추가color: #16a34a; cursor: pointer
addCancelBtn추가 취소 버튼행 추가color: #9ca3af; cursor: pointer
헤더 메뉴
headerMenuBtn⋯ 버튼헤더 메뉴opacity: 0; transition: opacity 0.2s
headerMenuDropdown드롭다운 컨테이너헤더 메뉴box-shadow: 0 4px 12px rgba(0,0,0,.1); border-radius: 8px; background: #fff
headerMenuItem드롭다운 각 항목 <button>헤더 메뉴padding: 8px 16px; font-size: 14px; text-align: left; width: 100%
컬럼 관리
columnManagerBackdrop모달 배경 오버레이컬럼 관리background: rgba(0,0,0,.4); backdrop-filter: blur(4px)
columnManager모달 컨테이너컬럼 관리border-radius: 12px; box-shadow: 0 8px 32px rgba(0,0,0,.2); background: #fff; width: 320px
columnManagerHeader모달 헤더컬럼 관리display: flex; align-items: center; justify-content: space-between; border-bottom: 1px solid #eee; padding: 16px
columnManagerTitle모달 제목컬럼 관리font-weight: 700; font-size: 15px
columnManagerSelectAllBtn전체 선택 버튼컬럼 관리color: #3b82f6; font-size: 12px
columnManagerDeselectAllBtn전체 해제 버튼컬럼 관리color: #9ca3af; font-size: 12px
columnManagerCloseBtn닫기 버튼컬럼 관리color: #9ca3af; cursor: pointer
columnManagerBody모달 본문 (토글 목록 영역)컬럼 관리padding: 12px; max-height: 240px; overflow-y: auto
columnToggle컬럼 토글 항목컬럼 관리display: flex; align-items: center; gap: 8px; padding: 6px 0
columnToggleActive표시 중인 컬럼 토글컬럼 관리color: #3b82f6; font-weight: 500
columnToggleCheckbox토글 체크박스컬럼 관리accent-color: #3b82f6
컬럼 리사이즈 / 드래그 / 핀
resizeHandle리사이즈 핸들 div컬럼 리사이즈width: 4px; height: 100%; cursor: col-resize; background: #e5e7eb
thDragging드래그 중인 <th>컬럼 드래그 순서 변경opacity: 0.4
thDragOver드래그 오버된 <th>컬럼 드래그 순서 변경border-left: 2px solid #6366f1
thPinnedLeft좌측 고정 <th>컬럼 핀position: sticky; left: 0; background: #fff; box-shadow: 2px 0 4px rgba(0,0,0,.08)
thPinnedRight우측 고정 <th>컬럼 핀position: sticky; right: 0; background: #fff; box-shadow: -2px 0 4px rgba(0,0,0,.08)
tdPinnedLeft좌측 고정 <td>컬럼 핀position: sticky; left: 0; background: #fff
tdPinnedRight우측 고정 <td>컬럼 핀position: sticky; right: 0; background: #fff
컨텍스트 메뉴 / 툴팁 / 복사
contextMenu헤더 우클릭 컨텍스트 메뉴컬럼 핀 컨텍스트 메뉴border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,.1); background: #fff; padding: 4px 0
contextMenuItem컨텍스트 메뉴 항목컬럼 핀 컨텍스트 메뉴padding: 8px 16px; font-size: 14px; cursor: pointer; width: 100%
tooltip셀 호버 툴팁툴팁background: #1f2937; color: #fff; font-size: 12px; border-radius: 4px; padding: 4px 8px
cellCopyMenu셀 우클릭 복사 메뉴복사border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,.1); background: #fff
cellCopyMenuItem복사 메뉴 항목복사padding: 8px 16px; font-size: 14px; width: 100%
확장 행
groupRow그룹(부모) 행 <tr>확장 행background: #f5f5f5; font-weight: 600
groupCell그룹 행 <td>확장 행cursor: pointer; user-select: none
expandIcon펼치기 / 접기 아이콘확장 행transition: transform 0.2s
childRow자식 행 <tr>확장 행background: rgba(255,255,255,.5)
childTd자식 행 <td>확장 행padding: 8px 0
childIndent자식 행 들여쓰기 div확장 행width: 20px; flex-shrink: 0; border-left: 1px solid #e5e7eb
로딩 / 빈 상태 / 가상 스크롤
skeletonRow스켈레톤 행 <tr>로딩animation: pulse 1.5s ease-in-out infinite
skeletonCell스켈레톤 <td>로딩padding: 12px 16px
skeletonBar스켈레톤 바 (shimmer 애니메이션)로딩height: 16px; background: #e5e7eb; border-radius: 9999px
emptyRow빈 상태 행 <tr>빈 상태text-align: center
emptyCell빈 상태 <td>빈 상태padding: 80px 0; color: #9ca3af
loadMoreRow더 불러오기 행 <tr>가상 스크롤text-align: center
loadMoreCell더 불러오기 <td>가상 스크롤padding: 16px
sentinelRow무한 스크롤 감지 행가상 스크롤height: 1px; visibility: hidden
virtualPadding가상 스크롤 상·하단 패딩 행가상 스크롤background: transparent
settings

ColumnDef 옵션

LLM GuideViewerMD

ColumnDef의 전체 옵션 목록입니다.

const columns: ColumnDef<User>[] = [
  {
    key: 'name',
    label: '이름',
    render: (row) => row.name,
    width: '200px',
    minWidth: 80,
    sortable: true,
    filterType: 'text',
    filterOptions: [
      { label: '관리자', value: 'admin' },
    ],
    filterPlaceholder: '이름 검색...',
    editable: true,
    insertable: true,
    align: 'left',
    copyable: true,
    validate: (value) => value.trim() ? null : '필수 항목입니다.',
    renderEditCell: (props) => <CustomInput {...props} />,
    onValidationError: (error) => console.warn(error),
  },
]
옵션타입설명
keystring컬럼 고유 키
labelstring헤더 표시 텍스트
render(row) => ReactNode셀 렌더 함수
widthstringCSS 너비 (px, %)
minWidthnumber최소 너비 (px)
sortableboolean정렬 가능 여부
filterTypestringtext | select | dateRange | numberRange
filterOptions{ label: string; value: string }[]select 필터의 선택지 목록
filterPlaceholderstringtext 필터 입력창 placeholder
editableboolean인라인 편집 가능
insertableboolean행 추가 시 입력 가능
alignstringleft | center | right
copyableboolean셀 복사 가능
validate(value) => string | null편집 검증 함수
renderEditCell(props) => ReactNode커스텀 편집 셀 렌더러 (editing.renderCell보다 우선)
renderInsertCell(props) => ReactNode행 추가 시 커스텀 입력 셀 렌더러
onValidationError(error: string) => void검증 실패 시 콜백 — 설정 시 renderCell의 error props가 null이 됨