Skip to content

Commit

Permalink
add setSelection to tableControl + add onOrderByChange and onSelectio…
Browse files Browse the repository at this point in the history
…nChange to Hightable
  • Loading branch information
severo committed Jan 16, 2025
1 parent b4d1945 commit a200d8a
Showing 1 changed file with 47 additions and 35 deletions.
82 changes: 47 additions & 35 deletions src/HighTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export {
wrapPromise,
} from './dataframe.js'
export { rowCache } from './rowCache.js'
export type { Selection } from './selection.js'
export { HighTable }

const rowHeight = 33 // row height px
Expand All @@ -37,6 +38,8 @@ interface TableProps {
focus?: boolean // focus table on mount? (default true)
tableControl?: TableControl // control the table from outside
selectable?: boolean // enable row selection (default false)
onOrderByChange?: (orderBy: string | undefined) => void
onSelectionChange?: (selection: Selection) => void
onDoubleClickCell?: MouseEventCellHandler
onMouseDownCell?: MouseEventCellHandler
onError?: (error: Error) => void
Expand Down Expand Up @@ -64,40 +67,6 @@ type Action =
| { type: 'DATA_CHANGED' }
| { type: 'SET_SELECTION', selection: Selection, anchor?: number }

function reducer(state: State, action: Action): State {
switch (action.type) {
case 'SET_ROWS':
return {
...state,
startIndex: action.start,
rows: action.rows,
invalidate: false,
hasCompleteRow: state.hasCompleteRow || action.hasCompleteRow,
}
case 'SET_COLUMN_WIDTH': {
const columnWidths = [...state.columnWidths]
columnWidths[action.columnIndex] = action.columnWidth
return { ...state, columnWidths }
}
case 'SET_COLUMN_WIDTHS':
return { ...state, columnWidths: action.columnWidths }
case 'SET_ORDER': {
if (state.orderBy === action.orderBy) {
return state
} else {
// the selection is relative to the order, and must be reset if the order changes
return { ...state, orderBy: action.orderBy, rows: [], selection: [], anchor: undefined }
}
}
case 'DATA_CHANGED':
return { ...state, invalidate: true, hasCompleteRow: false, selection: [], anchor: undefined }
case 'SET_SELECTION':
return { ...state, selection: action.selection, anchor: action.anchor }
default:
return state
}
}

const initialState: State = {
columnWidths: [],
startIndex: 0,
Expand All @@ -124,6 +93,8 @@ export default function HighTable({
focus = true,
tableControl,
selectable = false,
onOrderByChange,
onSelectionChange,
onDoubleClickCell,
onMouseDownCell,
onError = console.error,
Expand All @@ -136,6 +107,43 @@ export default function HighTable({
* startIndex lives in the table domain: it's the first virtual row to be rendered in HTML.
* data.rows(dataIndex, dataIndex + 1) is the same row as data.rows(tableIndex, tableIndex + 1, orderBy)
*/
function reducer(state: State, action: Action): State {
switch (action.type) {
case 'SET_ROWS':
return {
...state,
startIndex: action.start,
rows: action.rows,
invalidate: false,
hasCompleteRow: state.hasCompleteRow || action.hasCompleteRow,
}
case 'SET_COLUMN_WIDTH': {
const columnWidths = [...state.columnWidths]
columnWidths[action.columnIndex] = action.columnWidth
return { ...state, columnWidths }
}
case 'SET_COLUMN_WIDTHS':
return { ...state, columnWidths: action.columnWidths }
case 'SET_ORDER': {
onOrderByChange?.(action.orderBy)
onSelectionChange?.([])
if (state.orderBy === action.orderBy) {
return state
} else {
// the selection is relative to the order, and must be reset if the order changes
return { ...state, orderBy: action.orderBy, rows: [], selection: [], anchor: undefined }
}
}
case 'DATA_CHANGED':
onSelectionChange?.([])
return { ...state, invalidate: true, hasCompleteRow: false, selection: [], anchor: undefined }
case 'SET_SELECTION':
onSelectionChange?.(action.selection)
return { ...state, selection: action.selection, anchor: action.anchor }
default:
return state
}
}
const [state, dispatch] = useReducer(reducer, initialState)

const { anchor, columnWidths, startIndex, rows, orderBy, invalidate, hasCompleteRow, selection } = state
Expand Down Expand Up @@ -258,7 +266,7 @@ export default function HighTable({
return () => {
tableControl?.publisher.unsubscribe(dispatch)
}
}, [tableControl])
}, [tableControl, dispatch])

/**
* Validate row length
Expand Down Expand Up @@ -488,6 +496,7 @@ interface PubSub<T> extends Publisher<T> {
export interface TableControl {
publisher: Publisher<Action>
setOrderBy: (columnName: string) => void
setSelection: (selection: Selection) => void
}

function createPubSub<T>(): PubSub<T> {
Expand All @@ -514,5 +523,8 @@ export function createTableControl(): TableControl {
setOrderBy(columnName: string) {
publisher.publish({ type: 'SET_ORDER', orderBy: columnName })
},
setSelection(selection: Selection) {
publisher.publish({ type: 'SET_SELECTION', selection })
},
}
}

0 comments on commit a200d8a

Please sign in to comment.