Skip to content

Commit 937c5f5

Browse files
committed
use ControlledHighTable
1 parent 1054cc8 commit 937c5f5

File tree

2 files changed

+87
-84
lines changed

2 files changed

+87
-84
lines changed

apps/hightable-demo/src/App.tsx

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import { Action, ControlledHighTable, Selection, State, initialState, reducer } from 'hightable'
2+
import { StrictMode, useMemo, useReducer } from 'react'
3+
import { data } from './data'
4+
import './HighTable.css'
5+
import './index.css'
6+
7+
// for demo purpose
8+
function appReducer(state: State, action: Action): State {
9+
switch (action.type) {
10+
case 'SET_SELECTION':
11+
// do something special for the "SET_SELECTION" action
12+
console.log('SET_SELECTION', action.selection)
13+
return { ...state, selection: action.selection, anchor: action.anchor }
14+
default:
15+
// use the hightable reducer function for the rest of the actions
16+
return reducer(state, action)
17+
}
18+
}
19+
20+
export default function App() {
21+
const columns = data.header
22+
23+
const [state, dispatch] = useReducer(appReducer, initialState)
24+
const { selection, orderBy } = state
25+
const columnId = useMemo(() => {
26+
if (!orderBy) return undefined
27+
const id = columns.indexOf(orderBy)
28+
return id === -1 ? undefined : id
29+
}, [columns, orderBy])
30+
31+
function onSortClick() {
32+
const nextId = ((columnId ?? -1) + 1) % columns.length
33+
dispatch({ type: 'SET_ORDER', orderBy: columns[nextId] })
34+
}
35+
function onSelectionClick() {
36+
const newSelection = selection.map(({ start, end }) => ({ start: start + 1, end: end + 1 }))
37+
dispatch({ type: 'SET_SELECTION', selection: newSelection, anchor: undefined })
38+
}
39+
function getSelectionCount(selection: Selection) {
40+
return selection.reduce((acc: number, { start, end }) => acc + end - start, 0)
41+
}
42+
function getFirstRows(selection: Selection, max = 5) {
43+
const indexes: string[] = []
44+
let rangeIdx = 0
45+
while (indexes.length < max && rangeIdx < selection.length) {
46+
const { start, end } = selection[rangeIdx]
47+
let rowIdx = start
48+
while (indexes.length < max && rowIdx < end) {
49+
indexes.push(rowIdx.toString())
50+
rowIdx++
51+
}
52+
rangeIdx++
53+
}
54+
if (indexes.length === max) {
55+
indexes.pop()
56+
indexes.push('...')
57+
}
58+
return indexes
59+
}
60+
61+
return <StrictMode>
62+
<div style={{ display: 'flex', flexDirection: 'column', width: '100%' }}>
63+
<div style={{ padding: '1em' }}>
64+
<h2>Hightable demo</h2>
65+
66+
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '1em' }}>
67+
<div style={{ padding: '1em', border: '1px solid #ccc' }}>
68+
<h3>Order by</h3>
69+
<p>Click the button to sort the table by the next column</p>
70+
<button onClick={onSortClick}>Sort the following column</button>
71+
<p>Column ID: {columnId}</p>
72+
<p>{columnId === undefined ? 'No sorted column' : 'Column name: "' + columns[columnId] + '"'}</p>
73+
</div>
74+
<div style={{ padding: '1em', border: '1px solid #ccc' }}>
75+
<h3>Rows selection</h3>
76+
<p>Click the button to delete the selected rows</p>
77+
<button onClick={onSelectionClick}>Move the selection down by one row</button>
78+
<p>selection: <code style={{ margin: '0.5em', padding: '0.2em 0.5em', backgroundColor: '#ddd' }}>{JSON.stringify(selection)}</code></p>
79+
<p>{getSelectionCount(selection)} selected rows: {getFirstRows(selection).map(index => <code key={index} style={{ margin: '0.5em', padding: '0.2em 0.5em', backgroundColor: '#ddd' }}>{index}</code>)}</p>
80+
</div>
81+
</div>
82+
</div>
83+
<ControlledHighTable data={data} cacheKey='demo' selectable state={state} dispatch={dispatch} />
84+
</div>
85+
</StrictMode>
86+
}

apps/hightable-demo/src/main.tsx

Lines changed: 1 addition & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,8 @@
1-
import { createTableControl, HighTable, Selection } from 'hightable'
2-
import { StrictMode, useState } from 'react'
31
import ReactDOM from 'react-dom/client'
4-
import { data } from './data'
2+
import App from './App.js'
53
import './HighTable.css'
64
import './index.css'
75

86
const app = document.getElementById('app')
97
if (!app) throw new Error('missing app element')
10-
11-
function App() {
12-
const tableControl = createTableControl()
13-
const columns = data.header
14-
15-
const [columnId, setColumnId] = useState<number | undefined>()
16-
const [selection, setSelection] = useState<Selection>([])
17-
18-
function onOrderByChange(orderBy: string | undefined) {
19-
console.log("New value for orderBy: " + orderBy)
20-
if (!orderBy) {
21-
setColumnId(undefined)
22-
return
23-
}
24-
const id = columns.indexOf(orderBy)
25-
if (id === -1) {
26-
setColumnId(undefined)
27-
}
28-
setColumnId(id)
29-
}
30-
function onSelectionChange(selection: Selection) {
31-
setSelection(selection)
32-
}
33-
34-
function onSortClick() {
35-
const nextId = ((columnId ?? -1) + 1) % columns.length
36-
tableControl.setOrderBy(columns[nextId])
37-
}
38-
function onSelectionClick() {
39-
const newSelection = selection.map(({start, end}) => ({start: start + 1, end: end + 1}))
40-
tableControl.setSelection(newSelection)
41-
}
42-
function getSelectionCount(selection: Selection) {
43-
return selection.reduce((acc: number, {start, end}) => acc + end - start, 0)
44-
}
45-
function getFirstRows(selection: Selection, max = 5) {
46-
const indexes: string[] = []
47-
let rangeIdx = 0
48-
while (indexes.length < max && rangeIdx < selection.length) {
49-
const {start, end} = selection[rangeIdx]
50-
let rowIdx = start
51-
while (indexes.length < max && rowIdx < end) {
52-
indexes.push(rowIdx.toString())
53-
rowIdx++
54-
}
55-
rangeIdx++
56-
}
57-
if (indexes.length === max) {
58-
indexes.pop()
59-
indexes.push('...')
60-
}
61-
return indexes
62-
}
63-
64-
return (<StrictMode>
65-
<div style={{display: 'flex', flexDirection: 'column', width: '100%'}}>
66-
<div style={{padding: '1em'}}>
67-
<h2>Hightable demo</h2>
68-
69-
<div style={{display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '1em'}}>
70-
<div style={{padding: '1em', border: '1px solid #ccc'}}>
71-
<h3>Order by</h3>
72-
<p>Click the button to sort the table by the next column</p>
73-
<button onClick={onSortClick}>Sort the following column</button>
74-
<p>Column ID: {columnId}</p>
75-
<p>{columnId === undefined ? 'No sorted column': ('Column name: "' + columns[columnId] + '"')}</p>
76-
</div>
77-
<div style={{padding: '1em', border: '1px solid #ccc'}}>
78-
<h3>Rows selection</h3>
79-
<p>Click the button to delete the selected rows</p>
80-
<button onClick={onSelectionClick}>Move the selection down by one row</button>
81-
<p>selection: <code style={{margin: '0.5em', padding: '0.2em 0.5em', backgroundColor: '#ddd'}}>{JSON.stringify(selection)}</code></p>
82-
<p>{getSelectionCount(selection)} selected rows: {getFirstRows(selection).map(index => <code style={{margin: '0.5em', padding: '0.2em 0.5em', backgroundColor: '#ddd'}}>{index}</code>)}</p>
83-
</div>
84-
</div>
85-
</div>
86-
<HighTable data={data} cacheKey='demo' selectable tableControl={tableControl} onOrderByChange={onOrderByChange} onSelectionChange={onSelectionChange} />
87-
</div>
88-
</StrictMode>)
89-
}
90-
918
ReactDOM.createRoot(app).render(<App></App>)

0 commit comments

Comments
 (0)