1- import { ControlledHighTable , HighTable , InternalAction , InternalState , Selection , SelectionAndAnchor , initialState , reducer } from 'hightable'
2- import { StrictMode , useMemo , useReducer , useState } from 'react'
1+ import { HighTable , OrderBy , Selection } from 'hightable'
2+ import { StrictMode , useMemo , useState } from 'react'
33import { data } from './data'
4- import './HighTable.css'
5- import './index.css'
6-
7- type State = InternalState & SelectionAndAnchor
8-
9- type Action = InternalAction
10- | ( { type : 'SET_SELECTION' } & SelectionAndAnchor )
11-
12- // for demo purpose
13- function appReducer ( state : State , action : Action ) : State {
14- switch ( action . type ) {
15- case 'SET_SELECTION' :
16- // do something special for the "SET_SELECTION" action
17- console . log ( 'SET_SELECTION' , action . selection )
18- return { ...state , selection : action . selection , anchor : action . anchor }
19- default :
20- // use the hightable reducer function for the rest of the actions
21- return reducer ( state , action )
22- }
23- }
244
255export default function App ( ) {
266 const columns = data . header
277
28- const [ state , dispatch ] = useReducer ( appReducer , initialState )
29- const [ selectable , setSelectable ] = useState ( false )
8+ const [ selectable , setSelectable ] = useState ( true )
9+ const [ selection , setSelection ] = useState < Selection > ( { ranges : [ ] } )
10+ const [ orderBy , setOrderBy ] = useState < OrderBy > ( { } )
11+ const { column } = orderBy
3012
31- const selectionAndAnchor = selectable ? { selection : state . selection , anchor : state . anchor } : undefined
32- const setSelectionAndAnchor = selectable ? ( selectionAndAnchor : SelectionAndAnchor ) => { dispatch ( { type : 'SET_SELECTION' , ...selectionAndAnchor } ) } : undefined
33-
34- function onSelectionChange ( selection : Selection ) {
35- dispatch ( { type : 'SET_SELECTION' , selection } )
36- }
37-
38- const { selection, orderBy } = state
3913 const columnId = useMemo ( ( ) => {
40- if ( ! orderBy ) return undefined
41- const id = columns . indexOf ( orderBy )
14+ if ( ! column ) return undefined
15+ const id = columns . indexOf ( column )
4216 return id === - 1 ? undefined : id
43- } , [ columns , orderBy ] )
17+ } , [ columns , column ] )
4418
4519 function onSortClick ( ) {
4620 const nextId = ( ( columnId ?? - 1 ) + 1 ) % columns . length
47- dispatch ( { type : 'SET_ORDER' , orderBy : columns [ nextId ] } )
21+ setOrderBy ( { column : columns [ nextId ] } )
4822 }
49- function onSelectionClick ( ) {
50- const newSelection = selection . map ( ( { start, end } ) => ( { start : start + 1 , end : end + 1 } ) )
51- dispatch ( { type : 'SET_SELECTION' , selection : newSelection , anchor : undefined } )
23+ function onSelectionIncrementClick ( ) {
24+ const newSelection = {
25+ ranges : selection . ranges . map ( ( { start, end } ) => ( { start : start + 1 , end : end + 1 } ) ) ,
26+ anchor : selection . anchor !== undefined ? selection . anchor + 1 : undefined ,
27+ }
28+ setSelection ( newSelection )
5229 }
5330 function getSelectionCount ( selection : Selection ) {
54- return selection . reduce ( ( acc : number , { start, end } ) => acc + end - start , 0 )
31+ return selection . ranges . reduce ( ( acc : number , { start, end } ) => acc + end - start , 0 )
5532 }
5633 function getFirstRows ( selection : Selection , max = 5 ) {
5734 const indexes : string [ ] = [ ]
5835 let rangeIdx = 0
59- while ( indexes . length < max && rangeIdx < selection . length ) {
60- const { start, end } = selection [ rangeIdx ]
36+ while ( indexes . length < max && rangeIdx < selection . ranges . length ) {
37+ const { start, end } = selection . ranges [ rangeIdx ]
6138 let rowIdx = start
6239 while ( indexes . length < max && rowIdx < end ) {
6340 indexes . push ( rowIdx . toString ( ) )
@@ -75,14 +52,14 @@ export default function App() {
7552 return < StrictMode >
7653 < div style = { { display : 'flex' , flexDirection : 'column' , width : '100%' } } >
7754 < div style = { { padding : '0 1em 1em' } } >
78- < h2 > Hightable</ h2 >
79- { selectable && < p > The selection is enabled because onSelectionChange is set .</ p > }
55+ < h2 > Uncontrolled selection and sort in Hightable</ h2 >
56+ { selectable && < p > The rows selection in this table is enabled, and the component is "uncontrolled" (it has a local state) .</ p > }
8057 { ! selectable && < p > The selection is disabled because onSelectionChange is undefined.</ p > }
8158 < button onClick = { ( ) => { setSelectable ( selectable => ! selectable ) } } > { selectable ? 'Disable' : 'Enable' } selection</ button >
8259 </ div >
83- < HighTable data = { data } cacheKey = 'demo' onSelectionChange = { selectable ? onSelectionChange : undefined } />
60+ < HighTable data = { data } cacheKey = 'demo' onSelectionChange = { selectable ? setSelection : undefined } />
8461 < div style = { { padding : '0 1em 1em' , borderTop : '1px solid #ccc' } } >
85- < h2 > ControlledHightable </ h2 >
62+ < h2 > Controlled selection and sort in Hightable </ h2 >
8663 < div style = { { padding : '0 1em' , marginBottom : '1em' } } >
8764 < div style = { { display : 'grid' , gridTemplateColumns : '1fr 1fr' , gap : '1em' } } >
8865 < div style = { { padding : '0 1em' , border : '1px solid #ccc' } } >
@@ -96,15 +73,15 @@ export default function App() {
9673 { ! selectable && < p > The selection is disabled</ p > }
9774 { selectable && < >
9875 < p > The selection is controlled internally by (shift) clicking the left column, and externally by mirroring changes from HighTable and by the following button:</ p >
99- < button onClick = { onSelectionClick } > Move the selection down by one row</ button >
76+ < button onClick = { onSelectionIncrementClick } > Move the selection down by one row</ button >
10077 < p > selection: < code style = { { margin : '0.5em' , padding : '0.2em 0.5em' , backgroundColor : '#ddd' } } > { JSON . stringify ( selection ) } </ code > </ p >
10178 < 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 >
10279 </ > }
10380 </ div >
10481 </ div >
10582 </ div >
10683 </ div >
107- < ControlledHighTable data = { data } cacheKey = 'demo' state = { state } dispatch = { dispatch } selectionAndAnchor = { selectionAndAnchor } setSelectionAndAnchor = { setSelectionAndAnchor } />
84+ < HighTable data = { data } cacheKey = 'demo' selection = { selection } onSelectionChange = { selectable ? setSelection : undefined } orderBy = { orderBy } onOrderByChange = { setOrderBy } />
10885 </ div >
10986 </ StrictMode >
11087}
0 commit comments