react-merge-table
Version:
React component for auto-merging rowspan/colspan in HTML tables
211 lines (152 loc) β’ 6.54 kB
Markdown
# π§© 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
```