Skip to content

Commit

Permalink
use ControlledHighTable
Browse files Browse the repository at this point in the history
  • Loading branch information
severo committed Jan 9, 2025
1 parent 1054cc8 commit 937c5f5
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 84 deletions.
86 changes: 86 additions & 0 deletions apps/hightable-demo/src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { Action, ControlledHighTable, Selection, State, initialState, reducer } from 'hightable'
import { StrictMode, useMemo, useReducer } from 'react'
import { data } from './data'
import './HighTable.css'
import './index.css'

// for demo purpose
function appReducer(state: State, action: Action): State {
switch (action.type) {
case 'SET_SELECTION':
// do something special for the "SET_SELECTION" action
console.log('SET_SELECTION', action.selection)
return { ...state, selection: action.selection, anchor: action.anchor }
default:
// use the hightable reducer function for the rest of the actions
return reducer(state, action)
}
}

export default function App() {
const columns = data.header

const [state, dispatch] = useReducer(appReducer, initialState)
const { selection, orderBy } = state
const columnId = useMemo(() => {
if (!orderBy) return undefined
const id = columns.indexOf(orderBy)
return id === -1 ? undefined : id
}, [columns, orderBy])

function onSortClick() {
const nextId = ((columnId ?? -1) + 1) % columns.length
dispatch({ type: 'SET_ORDER', orderBy: columns[nextId] })
}
function onSelectionClick() {
const newSelection = selection.map(({ start, end }) => ({ start: start + 1, end: end + 1 }))
dispatch({ type: 'SET_SELECTION', selection: newSelection, anchor: undefined })
}
function getSelectionCount(selection: Selection) {
return selection.reduce((acc: number, { start, end }) => acc + end - start, 0)
}
function getFirstRows(selection: Selection, max = 5) {
const indexes: string[] = []
let rangeIdx = 0
while (indexes.length < max && rangeIdx < selection.length) {
const { start, end } = selection[rangeIdx]
let rowIdx = start
while (indexes.length < max && rowIdx < end) {
indexes.push(rowIdx.toString())
rowIdx++
}
rangeIdx++
}
if (indexes.length === max) {
indexes.pop()
indexes.push('...')
}
return indexes
}

return <StrictMode>
<div style={{ display: 'flex', flexDirection: 'column', width: '100%' }}>
<div style={{ padding: '1em' }}>
<h2>Hightable demo</h2>

<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '1em' }}>
<div style={{ padding: '1em', border: '1px solid #ccc' }}>
<h3>Order by</h3>
<p>Click the button to sort the table by the next column</p>
<button onClick={onSortClick}>Sort the following column</button>
<p>Column ID: {columnId}</p>
<p>{columnId === undefined ? 'No sorted column' : 'Column name: "' + columns[columnId] + '"'}</p>
</div>
<div style={{ padding: '1em', border: '1px solid #ccc' }}>
<h3>Rows selection</h3>
<p>Click the button to delete the selected rows</p>
<button onClick={onSelectionClick}>Move the selection down by one row</button>
<p>selection: <code style={{ margin: '0.5em', padding: '0.2em 0.5em', backgroundColor: '#ddd' }}>{JSON.stringify(selection)}</code></p>
<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>
</div>
</div>
</div>
<ControlledHighTable data={data} cacheKey='demo' selectable state={state} dispatch={dispatch} />
</div>
</StrictMode>
}
85 changes: 1 addition & 84 deletions apps/hightable-demo/src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,91 +1,8 @@
import { createTableControl, HighTable, Selection } from 'hightable'
import { StrictMode, useState } from 'react'
import ReactDOM from 'react-dom/client'
import { data } from './data'
import App from './App.js'
import './HighTable.css'
import './index.css'

const app = document.getElementById('app')
if (!app) throw new Error('missing app element')

function App() {
const tableControl = createTableControl()
const columns = data.header

const [columnId, setColumnId] = useState<number | undefined>()
const [selection, setSelection] = useState<Selection>([])

function onOrderByChange(orderBy: string | undefined) {
console.log("New value for orderBy: " + orderBy)
if (!orderBy) {
setColumnId(undefined)
return
}
const id = columns.indexOf(orderBy)
if (id === -1) {
setColumnId(undefined)
}
setColumnId(id)
}
function onSelectionChange(selection: Selection) {
setSelection(selection)
}

function onSortClick() {
const nextId = ((columnId ?? -1) + 1) % columns.length
tableControl.setOrderBy(columns[nextId])
}
function onSelectionClick() {
const newSelection = selection.map(({start, end}) => ({start: start + 1, end: end + 1}))
tableControl.setSelection(newSelection)
}
function getSelectionCount(selection: Selection) {
return selection.reduce((acc: number, {start, end}) => acc + end - start, 0)
}
function getFirstRows(selection: Selection, max = 5) {
const indexes: string[] = []
let rangeIdx = 0
while (indexes.length < max && rangeIdx < selection.length) {
const {start, end} = selection[rangeIdx]
let rowIdx = start
while (indexes.length < max && rowIdx < end) {
indexes.push(rowIdx.toString())
rowIdx++
}
rangeIdx++
}
if (indexes.length === max) {
indexes.pop()
indexes.push('...')
}
return indexes
}

return (<StrictMode>
<div style={{display: 'flex', flexDirection: 'column', width: '100%'}}>
<div style={{padding: '1em'}}>
<h2>Hightable demo</h2>

<div style={{display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '1em'}}>
<div style={{padding: '1em', border: '1px solid #ccc'}}>
<h3>Order by</h3>
<p>Click the button to sort the table by the next column</p>
<button onClick={onSortClick}>Sort the following column</button>
<p>Column ID: {columnId}</p>
<p>{columnId === undefined ? 'No sorted column': ('Column name: "' + columns[columnId] + '"')}</p>
</div>
<div style={{padding: '1em', border: '1px solid #ccc'}}>
<h3>Rows selection</h3>
<p>Click the button to delete the selected rows</p>
<button onClick={onSelectionClick}>Move the selection down by one row</button>
<p>selection: <code style={{margin: '0.5em', padding: '0.2em 0.5em', backgroundColor: '#ddd'}}>{JSON.stringify(selection)}</code></p>
<p>{getSelectionCount(selection)} selected rows: {getFirstRows(selection).map(index => <code style={{margin: '0.5em', padding: '0.2em 0.5em', backgroundColor: '#ddd'}}>{index}</code>)}</p>
</div>
</div>
</div>
<HighTable data={data} cacheKey='demo' selectable tableControl={tableControl} onOrderByChange={onOrderByChange} onSelectionChange={onSelectionChange} />
</div>
</StrictMode>)
}

ReactDOM.createRoot(app).render(<App></App>)

0 comments on commit 937c5f5

Please sign in to comment.