1
- import { Action , ControlledHighTable , Selection , State , initialState , reducer } from 'hightable'
2
- import { StrictMode , useMemo , useReducer } from 'react'
1
+ import { ControlledHighTable , HighTable , InternalAction , InternalState , Selection , SelectionAndAnchor , initialState , reducer } from 'hightable'
2
+ import { StrictMode , useMemo , useReducer , useState } from 'react'
3
3
import { data } from './data'
4
4
import './HighTable.css'
5
5
import './index.css'
6
6
7
+ type State = InternalState & SelectionAndAnchor
8
+
9
+ type Action = InternalAction
10
+ | ( { type : 'SET_SELECTION' } & SelectionAndAnchor )
11
+
7
12
// for demo purpose
8
13
function appReducer ( state : State , action : Action ) : State {
9
14
switch ( action . type ) {
@@ -21,6 +26,15 @@ export default function App() {
21
26
const columns = data . header
22
27
23
28
const [ state , dispatch ] = useReducer ( appReducer , initialState )
29
+ const [ selectable , setSelectable ] = useState ( false )
30
+
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
+
24
38
const { selection, orderBy } = state
25
39
const columnId = useMemo ( ( ) => {
26
40
if ( ! orderBy ) return undefined
@@ -60,27 +74,37 @@ export default function App() {
60
74
61
75
return < StrictMode >
62
76
< 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 >
77
+ < div style = { { padding : '0 1em 1em' } } >
78
+ < h2 > Hightable</ h2 >
79
+ { selectable && < p > The selection is enabled because onSelectionChange is set.</ p > }
80
+ { ! selectable && < p > The selection is disabled because onSelectionChange is undefined.</ p > }
81
+ < button onClick = { ( ) => { setSelectable ( selectable => ! selectable ) } } > { selectable ? 'Disable' : 'Enable' } selection</ button >
82
+ </ div >
83
+ < HighTable data = { data } cacheKey = 'demo' onSelectionChange = { selectable ? onSelectionChange : undefined } />
84
+ < div style = { { padding : '0 1em 1em' , borderTop : '1px solid #ccc' } } >
85
+ < h2 > ControlledHightable</ h2 >
86
+ < div style = { { padding : '0 1em' , marginBottom : '1em' } } >
87
+ < div style = { { display : 'grid' , gridTemplateColumns : '1fr 1fr' , gap : '1em' } } >
88
+ < div style = { { padding : '0 1em' , border : '1px solid #ccc' } } >
89
+ < h3 > Order by</ h3 >
90
+ < p > Column sort in ControlledHightable is controlled internally by clicking the column headers, and externally by the following button:</ p >
91
+ < button onClick = { onSortClick } > Sort the following column</ button >
92
+ < p > { columnId === undefined ? 'No sorted column' : 'Sorted by: "' + columns [ columnId ] + '"' } </ p >
93
+ </ div >
94
+ < div style = { { padding : '0 1em' , border : '1px solid #ccc' } } >
95
+ < h3 > Rows selection</ h3 >
96
+ { ! selectable && < p > The selection is disabled</ p > }
97
+ { selectable && < >
98
+ < 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 >
100
+ < p > selection: < code style = { { margin : '0.5em' , padding : '0.2em 0.5em' , backgroundColor : '#ddd' } } > { JSON . stringify ( selection ) } </ code > </ p >
101
+ < 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 >
102
+ </ > }
103
+ </ div >
80
104
</ div >
81
105
</ div >
82
106
</ div >
83
- < ControlledHighTable data = { data } cacheKey = 'demo' selectable state = { state } dispatch = { dispatch } />
107
+ < ControlledHighTable data = { data } cacheKey = 'demo' state = { state } dispatch = { dispatch } selectionAndAnchor = { selectionAndAnchor } setSelectionAndAnchor = { setSelectionAndAnchor } />
84
108
</ div >
85
109
</ StrictMode >
86
110
}
0 commit comments