@@ -80,17 +80,97 @@ function Table(props){_classCallCheck(this,Table);var _this3=_possibleConstructo
8080props ) ) ;
8181_this3 . state = {
8282aggrow :props . aggrow ,
83- viewport :{ top :0 , height :100 } } ; return _this3 ;
83+ viewport :{ top :0 , height :100 } ,
84+ cursor :0 } ; return _this3 ;
8485
8586} _createClass ( Table , [ { key :'scroll' , value :function scroll (
8687
8788e ) {
8889var viewport = e . target ;
8990var top = Math . floor ( ( viewport . scrollTop - viewport . clientHeight * 1.0 ) / rowHeight ) ;
9091var height = Math . ceil ( viewport . clientHeight * 3.0 / rowHeight ) ;
91- this . state . viewport . top = top ;
92- this . state . viewport . height = height ;
93- this . forceUpdate ( ) ;
92+ if ( top !== this . state . viewport . top || height !== this . state . viewport . height ) {
93+ this . setState ( { viewport :{ top :top , height :height } } ) ;
94+ }
95+ } } , { key :'_contractRow' , value :function _contractRow (
96+
97+ row ) {
98+ var newCursor = this . state . cursor ;
99+ if ( newCursor > row . top && newCursor < row . top + row . height ) { // in contracted section
100+ newCursor = row . top ;
101+ } else if ( newCursor >= row . top + row . height ) { // below contracted section
102+ newCursor -= row . height - 1 ;
103+ }
104+ this . state . aggrow . contract ( row ) ;
105+ this . setState ( { cursor :newCursor } ) ;
106+ } } , { key :'_expandRow' , value :function _expandRow (
107+
108+ row ) {
109+ var newCursor = this . state . cursor ;
110+ this . state . aggrow . expand ( row ) ;
111+ if ( newCursor > row . top ) { // below expanded section
112+ newCursor += row . height - 1 ;
113+ }
114+ this . setState ( { cursor :newCursor } ) ;
115+ } } , { key :'_keepCursorInViewport' , value :function _keepCursorInViewport ( )
116+
117+
118+
119+ {
120+ if ( this . _scrollDiv ) {
121+ var cursor = this . state . cursor ;
122+ var scrollDiv = this . _scrollDiv ;
123+ if ( cursor * rowHeight < scrollDiv . scrollTop + scrollDiv . clientHeight * 0.1 ) {
124+ scrollDiv . scrollTop = cursor * rowHeight - scrollDiv . clientHeight * 0.1 ;
125+ } else if ( ( cursor + 1 ) * rowHeight > scrollDiv . scrollTop + scrollDiv . clientHeight * 0.9 ) {
126+ scrollDiv . scrollTop = ( cursor + 1 ) * rowHeight - scrollDiv . clientHeight * 0.9 ;
127+ }
128+ }
129+ } } , { key :'keydown' , value :function keydown (
130+
131+ e ) {
132+ var aggrow = this . state . aggrow ;
133+ var cursor = this . state . cursor ;
134+ var row = aggrow . getRows ( cursor , 1 ) [ 0 ] ;
135+ switch ( e . keyCode ) {
136+ case 38 :// up
137+ if ( cursor > 0 ) {
138+ this . setState ( { cursor :cursor - 1 } ) ;
139+ this . _keepCursorInViewport ( ) ;
140+ }
141+ e . preventDefault ( ) ;
142+ break ;
143+ case 40 :// down
144+ if ( cursor < aggrow . getHeight ( ) - 1 ) {
145+ this . setState ( { cursor :cursor + 1 } ) ;
146+ this . _keepCursorInViewport ( ) ;
147+ }
148+ e . preventDefault ( ) ;
149+ break ;
150+ case 37 :// left
151+ if ( aggrow . canContract ( row ) ) {
152+ this . _contractRow ( row ) ;
153+ } else if ( aggrow . getRowIndent ( row ) > 0 ) {
154+ var indent = aggrow . getRowIndent ( row ) - 1 ;
155+ while ( aggrow . getRowIndent ( row ) > indent ) {
156+ cursor -- ;
157+ row = aggrow . getRows ( cursor , 1 ) [ 0 ] ;
158+ }
159+ this . setState ( { cursor :cursor } ) ;
160+ this . _keepCursorInViewport ( ) ;
161+ }
162+ e . preventDefault ( ) ;
163+ break ;
164+ case 39 :// right
165+ if ( aggrow . canExpand ( row ) ) {
166+ this . _expandRow ( row ) ;
167+ } else if ( cursor < aggrow . getHeight ( ) - 1 ) {
168+ this . setState ( { cursor :cursor + 1 } ) ;
169+ this . _keepCursorInViewport ( ) ;
170+ }
171+ e . preventDefault ( ) ;
172+ break ; }
173+
94174} } , { key :'dropAggregator' , value :function dropAggregator (
95175
96176s , d ) {
@@ -114,7 +194,7 @@ dIndex--;
114194active . splice ( sIndex , 1 ) ;
115195active . splice ( dIndex , 0 , dragged ) ;
116196aggrow . setActiveAggregators ( active ) ;
117- this . forceUpdate ( ) ;
197+ this . setState ( { cursor : 0 } ) ;
118198} else if ( s . startsWith ( 'expander:active:' ) ) {
119199var _sIndex = parseInt ( s . substr ( 16 ) , 10 ) ;
120200var _dIndex = - 1 ;
@@ -133,7 +213,7 @@ _dIndex--;
133213_active . splice ( _sIndex , 1 ) ;
134214_active . splice ( _dIndex , 0 , _dragged ) ;
135215aggrow . setActiveExpanders ( _active ) ;
136- this . forceUpdate ( ) ;
216+ this . setState ( { cursor : 0 } ) ;
137217}
138218} } , { key :'render' , value :function render ( )
139219
@@ -218,11 +298,14 @@ borderBottom:'2px solid black'}},
218298
219299headers ) ,
220300
221- React . createElement ( 'div' , { style :{
301+ React . createElement ( 'div' , {
302+ style :{
222303width :'100%' ,
223304flexGrow :'1' ,
224305overflow :'scroll' } ,
225- onScroll :function onScroll ( e ) { return _this4 . scroll ( e ) ; } } ,
306+
307+ onScroll :function onScroll ( e ) { return _this4 . scroll ( e ) ; } ,
308+ ref :function ref ( div ) { _this4 . _scrollDiv = div ; } } ,
226309React . createElement ( 'div' , { style :{ position :'relative' } } ,
227310this . renderVirtualizedRows ( ) ) ) ) ) ;
228311
@@ -259,6 +342,9 @@ var aggregates=aggrow.getActiveAggregators();
259342if ( row . parent !== null && row . parent . expander % 2 === 0 ) {
260343bg = 'white' ;
261344}
345+ if ( row . top === this . state . cursor ) {
346+ bg = 'lightblue' ;
347+ }
262348for ( var i = 0 ; i < aggregates . length ; i ++ ) {
263349var aggregate = aggrow . getRowAggregate ( row , i ) ;
264350columns . push (
@@ -288,42 +374,76 @@ flexShrink:'0'}}));
288374
289375
290376if ( aggrow . canExpand ( row ) ) {
291- rowText += '+' ;
377+ columns . push (
378+ React . createElement ( 'div' , {
379+ style :{
380+ marginLeft :indent . toString ( ) + 'px' ,
381+ flexShrink :'0' ,
382+ width :'12px' ,
383+ textAlign :'center' ,
384+ border :'1px solid gray' } ,
385+
386+ onClick :function onClick ( ) { return _this6 . _expandRow ( row ) ; } } , '+' ) ) ;
387+
388+
292389} else if ( aggrow . canContract ( row ) ) {
293- rowText += '-' ;
390+ columns . push (
391+ React . createElement ( 'div' , {
392+ style :{
393+ marginLeft :indent . toString ( ) + 'px' ,
394+ flexShrink :'0' ,
395+ width :'12px' ,
396+ textAlign :'center' ,
397+ border :'1px solid gray' } ,
398+
399+ onClick :function onClick ( ) { return _this6 . _contractRow ( row ) ; } } , '-' ) ) ;
400+
401+
294402} else {
295- rowText += ' ' ;
403+ columns . push (
404+ React . createElement ( 'div' , {
405+ style :{
406+ marginLeft :indent . toString ( ) + 'px' } } ) ) ;
407+
408+
409+
296410}
297411rowText += aggrow . getRowLabel ( row ) ;
298412columns . push (
299413React . createElement ( 'div' , { style :{
300- marginLeft :indent . toString ( ) + 'px' ,
301414flexShrink :'0' ,
302- whiteSpace :'nowrap' } } ,
415+ whiteSpace :'nowrap' ,
416+ marginRight :'20px' } } ,
303417
304418rowText ) ) ;
305419
306420
307421return (
308- React . createElement ( 'div' , { style :{
422+ React . createElement ( 'div' , {
423+ key :row . top ,
424+ style :{
309425position :'absolute' ,
310426height :( rowHeight - 1 ) . toString ( ) + 'px' ,
311427top :( rowHeight * row . top ) . toString ( ) + 'px' ,
312428display :'flex' ,
313429flexDirection :'row' ,
430+ alignItems :'center' ,
314431backgroundColor :bg ,
315432borderBottom :'1px solid gray' } ,
316433
317434onClick :function onClick ( ) {
318- if ( aggrow . canExpand ( row ) ) {
319- aggrow . expand ( row ) ;
320- _this6 . forceUpdate ( ) ;
321- } else if ( aggrow . canContract ( row ) ) {
322- aggrow . contract ( row ) ;
323- _this6 . forceUpdate ( ) ;
324- }
435+ _this6 . setState ( { cursor :row . top } ) ;
325436} } ,
326437columns ) ) ;
327438
328439
440+ } } , { key :'componentDidMount' , value :function componentDidMount ( )
441+
442+ {
443+ this . keydown = this . keydown . bind ( this ) ;
444+ document . body . addEventListener ( 'keydown' , this . keydown ) ;
445+ } } , { key :'componentWillUnmount' , value :function componentWillUnmount ( )
446+
447+ {
448+ document . body . removeEventListener ( 'keydown' , this . keydown ) ;
329449} } ] ) ; return Table ; } ( React . Component ) ; // @generated
0 commit comments