UNPKG

react-merge-table

Version:

React component for auto-merging rowspan/colspan in HTML tables

211 lines (152 loc) β€’ 6.54 kB
# 🧩 React Merge Table **React Merge Table**λŠ” Reactμ—μ„œ `<table>`을 μ‹œλ§¨ν‹±ν•˜κ²Œ κ΅¬μ„±ν•˜λ©΄μ„œ, μ…€ 병합(`rowspan`, `colspan`)을 μžλ™μœΌλ‘œ μ²˜λ¦¬ν•΄μ£ΌλŠ” κ²½λŸ‰ μ»΄ν¬λ„ŒνŠΈμž…λ‹ˆλ‹€. > `rowspan`, `colspan`, 쑰건뢀 `<td>` λ Œλ”λ§μ— μ§€μΉ˜μ…¨λ‚˜μš”? > 데이터λ₯Ό μž‘μ„±ν•˜κΈ°λ§Œ ν•˜λ©΄ 병합은 이 μ»΄ν¬λ„ŒνŠΈκ°€ μ•Œμ•„μ„œ μ²˜λ¦¬ν•©λ‹ˆλ‹€. --- ## βœ… μ™œ React Merge Table을 써야 ν•˜λ‚˜μš”? κΈ°μ‘΄ `div` 기반 ν…Œμ΄λΈ” κ΅¬ν˜„κ³Ό 달리, 이 μ»΄ν¬λ„ŒνŠΈλŠ” **`<table>`\*\*\*\*, ****`<thead>`****, ****`<tbody>`****, ****`<td>`**** λ“± μ‹œλ§¨ν‹±ν•œ HTML νƒœκ·Έλ₯Ό κ·ΈλŒ€λ‘œ μ‚¬μš©**ν•©λ‹ˆλ‹€. 이둜 인해 λ‹€μŒκ³Ό 같은 이점을 얻을 수 μžˆμŠ΅λ‹ˆλ‹€: * μ ‘κ·Όμ„±κ³Ό SEO에 μœ λ¦¬ν•œ HTML ꡬ쑰 * λ°˜λ³΅λ˜λŠ” κ°’ μžλ™ 병합 (rowspan/colspan) * 직관적인 문법과 μ΅œμ†Œν•œμ˜ μ„€μ • * 각 μ—΄ 별 μ»€μŠ€ν…€ λ Œλ”λ§ 지원 --- ## πŸ” 라이브 데λͺ¨ πŸ‘‰ [GitHub Pagesμ—μ„œ μ²΄ν—˜ν•˜κΈ°](https://pukkok.github.io/react-merge-table/) --- ## πŸš€ λΉ λ₯Έ 예제 λ‹€μŒμ€ `MergeTable`을 μ‚¬μš©ν•˜λŠ” κ°€μž₯ κ°„λ‹¨ν•œ ν˜•νƒœμ˜ μ˜ˆμ œμž…λ‹ˆλ‹€. `columnRenderers`λ₯Ό 톡해 νŠΉμ • μ—΄ λ˜λŠ” ν–‰, μ…€ μœ„μΉ˜μ— 따라 λ‹€μ–‘ν•œ μ»΄ν¬λ„ŒνŠΈλ₯Ό λ Œλ”λ§ν•  수 μžˆμŠ΅λ‹ˆλ‹€. ```tsx import React from 'react' import { MergeTable, TableHeader, TableBody, Cell } from 'react-merge-table' import './example.css' const headers = ['Grade', 'Subject', 'Exam', 'Date', 'Period', 'Score'] const rows = [ ['Grade 1', 'Math', 'Midterm', 'April 10', 'Period 1', 95], ['$', 'Korean', 'Midterm', ['April 11', 'April 12'], 'Period 2', 87], ['$', 'English', 'Final', 'June 15', 'Period 1', 91], ['Grade 2', 'Math', 'Midterm', 'April 12', 'Period 1', 80], ['$', 'Korean', '~', 'April 13', 'Period 2', 85], ['$', 'English', '~', 'April 14', 'Period 3', 89] ] export default function App() { return ( <MergeTable> <TableHeader headers={headers} /> <TableBody rows={rows} columnRenderers={{ 0: (cell: Cell) => <strong>{cell.content.label}</strong>, 1: (cell: Cell) => cell.rowIndex === 2 ? <input type="text" defaultValue={String(cell.content.label)} /> : <p>{cell.content.label}</p>, 3: (cell: Cell) => cell.hasMultiple ? ( <div style={{ display: 'flex', gap: '4px', justifyContent: 'center' }}> {cell.contents.map((v) => ( <button key={v.key} className="example-button" onClick={() => alert(v.label)} > {v.label} </button> ))} </div> ) : ( <em>{cell.content.label}</em> ), 5: (cell: Cell) => <span style={{ fontWeight: 600 }}>{cell.content.label}점</span> }} /> </MergeTable> ) } ``` --- ## 🧠 병합 기호 문법 | 기호 | 의미 | | ---------- | -------------------- | | `$` | μœ„μͺ½ μ…€κ³Ό 병합 (↓ rowspan) | | `~` | μ™Όμͺ½ μ…€κ³Ό 병합 (β†’ colspan) | | `$$`, `~~` | `$`, `~` 기호 자체 좜λ ₯ | πŸ’‘ μ •ν™•νžˆ `$` λ˜λŠ” `~`인 경우만 병합 μ²˜λ¦¬λ©λ‹ˆλ‹€. `'$100'`, `'가격~10%'` 같은 값은 일반 λ¬Έμžμ—΄λ‘œ μ²˜λ¦¬λ©λ‹ˆλ‹€. ## 🧾 `hasMultiple`, `content`, `contents` μ„€λͺ… React Merge Table의 μ…€(Cell) κ°μ²΄λŠ” λ³‘ν•©μ΄λ‚˜ λ Œλ”λ§μ— ν•„μš”ν•œ 정보λ₯Ό λ‹€μŒκ³Ό 같은 속성에 λ‹΄κ³  μžˆμŠ΅λ‹ˆλ‹€: ### πŸ”Ή `content` * 단일 μ…€ 값일 경우 λ Œλ”λ§μ— μ‚¬μš©λ˜λŠ” κ°μ²΄μž…λ‹ˆλ‹€. * ν˜•μ‹: `{ key: string, label: string | number }` ``` cell.content.label // 화면에 좜λ ₯ν•  κ°’ cell.content.key // 고유 μ‹λ³„μž (병합 및 λ¦¬λ Œλ”λ§μ— μ‚¬μš©) ``` ### πŸ”Ή `contents` * 셀에 μ—¬λŸ¬ 값을 λ°°μ—΄λ‘œ ν‘œμ‹œν•΄μ•Ό ν•  경우 μ‚¬μš©λ©λ‹ˆλ‹€. * `Array<{ key, label }>` ν˜•μ‹μœΌλ‘œ μžλ™ μ •κ·œν™”λ˜λ©°, 예: `['A', 'B']` β†’ `[ { key: '0', label: 'A' }, { key: '1', label: 'B' } ]` ### πŸ”Ή `hasMultiple` * 셀이 닀쀑 κ°’(`contents`)을 κ°€μ‘ŒλŠ”μ§€ μ—¬λΆ€λ₯Ό λ‚˜νƒ€λ‚΄λŠ” booleanμž…λ‹ˆλ‹€. * λ Œλ”λ§μ—μ„œ λ²„νŠΌ 리슀트, 볡수 ν•­λͺ© UI λ“±μœΌλ‘œ ν™œμš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€. ``` cell.hasMultiple ? cell.contents.map(...) : cell.content.label ``` μ΄λŸ¬ν•œ ꡬ쑰λ₯Ό 톡해 columnRenderersμ—μ„œ μœ μ—°ν•˜κ³  μœ„μΉ˜ 기반 쑰건 λΆ„κΈ°κΉŒμ§€ μ²˜λ¦¬ν•  수 μžˆμŠ΅λ‹ˆλ‹€. μ§€μ›ν•˜λŠ” 데이터 ν˜•μ‹μ€ λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€: ### 헀더 ν˜•μ‹ * `string | number` * `{ key: string, label: string | number }` ```tsx const headers = [ 'ν•™λ…„', { key: 'subject', label: 'κ³Όλͺ©' }, '점수' ] ``` ### ν–‰ ν˜•μ‹ * `CellValue[]` (κΈ°λ³Έ λ°°μ—΄ ν˜•μ‹) * `{ key: string, data: CellValue[] }` (ν–‰ μ‹λ³„μš© ν‚€ 포함) ```tsx const rows = [ ['1ν•™λ…„', 'μˆ˜ν•™', 95], ['$', 'μ˜μ–΄', 90], { key: 'g2-row', data: [ { key: 'g2', label: '2ν•™λ…„' }, 'κ³Όν•™', 88 ] } ] ``` ### μ…€ κ°’ ν˜•μ‹ * `string | number` * `{ key, label }` * `Array<string | number>` * `Array<{ key, label }>` – 닀쀑 μ…€ 좜λ ₯용 μžλ™μœΌλ‘œ μ •κ·œν™”λ˜μ–΄ 병합, ν‘œμ‹œ, μ»€μŠ€ν…€ λ Œλ”λ§ λͺ¨λ‘ μ§€μ›λ©λ‹ˆλ‹€. --- ## 🎨 μŠ€νƒ€μΌ μ œμ–΄: `defaultStyle` 기본적으둜 `<table>`, `<th>`, `<td>`에 κ°€λ²Όμš΄ μŠ€νƒ€μΌμ΄ μ μš©λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€. 직접 μŠ€νƒ€μΌλ§μ„ μ›ν•œλ‹€λ©΄ `defaultStyle={false}`둜 λΉ„ν™œμ„±ν™”ν•  수 μžˆμŠ΅λ‹ˆλ‹€: ```tsx <MergeTable defaultStyle={false}> <TableHeader headers={headers} defaultStyle={false} /> <TableBody rows={rows} defaultStyle={false} /> </MergeTable> ``` 클래슀 기반 λ””μžμΈ μ‹œμŠ€ν…œ, CSS λͺ¨λ“ˆ λ“± 자유둭게 μŠ€νƒ€μΌμ„ μ μš©ν•˜μ„Έμš”. --- ## πŸ“¦ μ„€μΉ˜ μ΅œμ‹  버전 μ„€μΉ˜: ```bash npm install react-merge-table ``` ### πŸ”„ `auto-merge-table`μ—μ„œ λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ν•˜κΈ° 이 νŒ¨ν‚€μ§€λŠ” 이전에 [`auto-merge-table`](https://www.npmjs.com/package/auto-merge-table)[μ΄λΌλŠ” 이](https://www.npmjs.com/package/auto-merge-table)λ¦„μœΌλ‘œ λ°°ν¬λ˜μ—ˆμœΌλ©°, ν˜„μž¬λŠ” deprecated λ˜μ—ˆμŠ΅λ‹ˆλ‹€. κΈ°μ‘΄ μ‚¬μš©μžλΌλ©΄ λ‹€μŒ λͺ…λ Ήμ–΄λ‘œ 이전 버전을 μ œκ±°ν•˜κ³  μƒˆ νŒ¨ν‚€μ§€λ₯Ό μ„€μΉ˜ν•˜μ„Έμš”: ```bash npm uninstall auto-merge-table npm install react-merge-table ```