@@ -6,7 +6,7 @@ import Icon from '../../icon';
6
6
import Overlay from '../../overlay' ;
7
7
import Menu from '../../menu' ;
8
8
import Animate from '../../animate' ;
9
- import { events , KEYCODE } from '../../util' ;
9
+ import { events , KEYCODE , dom } from '../../util' ;
10
10
import {
11
11
triggerEvents ,
12
12
getOffsetLT ,
@@ -42,8 +42,7 @@ class Nav extends React.Component {
42
42
constructor ( props , context ) {
43
43
super ( props , context ) ;
44
44
this . state = {
45
- next : false ,
46
- prev : false ,
45
+ showBtn : false ,
47
46
dropdownTabs : [ ] ,
48
47
} ;
49
48
this . offset = 0 ;
@@ -54,22 +53,17 @@ class Nav extends React.Component {
54
53
55
54
ctx . setSlideBtn ( ) ;
56
55
ctx . getDropdownItems ( this . props ) ;
57
- // 此处通过延时处理,屏蔽动画带来的定位不准确问题(由于要支持ie9,因此无法使用transitionend)
58
- clearTimeout ( ctx . scrollTimer ) ;
59
- ctx . scrollTimer = setTimeout ( ( ) => {
60
- ctx . scrollToActiveTab ( ) ;
61
- } , 400 ) ;
62
-
63
56
events . on ( window , 'resize' , this . onWindowResized ) ;
64
57
}
65
58
66
59
componentDidUpdate ( ) {
67
60
const ctx = this ;
68
-
69
- clearTimeout ( ctx . slideTimer ) ;
70
- ctx . slideTimer = setTimeout ( ( ) => {
71
- ctx . setSlideBtn ( ) ;
72
- } , 200 ) ;
61
+ // 此处通过延时处理,屏蔽动画带来的定位不准确问题(由于要支持ie9,因此无法使用transitionend)
62
+ clearTimeout ( ctx . scrollTimer ) ;
63
+ ctx . scrollTimer = setTimeout ( ( ) => {
64
+ ctx . scrollToActiveTab ( ) ;
65
+ } , 410 ) ; // transition-duration is set to be .4s, wait for the transition finishes before re-calc
66
+ ctx . setSlideBtn ( ) ;
73
67
if (
74
68
this . activeTab &&
75
69
findDOMNode ( this ) . contains ( document . activeElement )
@@ -89,7 +83,7 @@ class Nav extends React.Component {
89
83
* @param {bool } setActive need to check the active status or not
90
84
*/
91
85
setOffset ( target , checkSlideBtn = true , setActive = true ) {
92
- const { tabPosition } = this . props ;
86
+ const { tabPosition, rtl } = this . props ;
93
87
const navWH = getOffsetWH ( this . nav , tabPosition ) ;
94
88
const wrapperWH = getOffsetWH ( this . wrapper ) ;
95
89
@@ -107,15 +101,14 @@ class Nav extends React.Component {
107
101
const activeTabOffset =
108
102
getOffsetLT ( this . activeTab ) + relativeOffset ;
109
103
const wrapperOffset = getOffsetLT ( this . wrapper ) ;
110
-
111
- if (
112
- // active tab partially in visible zone
113
- wrapperOffset + wrapperWH < activeTabOffset + activeTabWH &&
114
- activeTabOffset < wrapperOffset + wrapperWH
115
- ) {
116
- target -= // Move more to make active tab totally in visible zone
117
- activeTabOffset + activeTabWH - ( wrapperOffset + wrapperWH ) ;
118
- }
104
+ target = this . _adjustTarget (
105
+ wrapperOffset ,
106
+ wrapperWH ,
107
+ activeTabWH ,
108
+ activeTabOffset ,
109
+ rtl ,
110
+ target
111
+ ) ;
119
112
}
120
113
121
114
if ( this . offset !== target ) {
@@ -171,6 +164,65 @@ class Nav extends React.Component {
171
164
}
172
165
}
173
166
167
+ _adjustTarget (
168
+ wrapperOffset ,
169
+ wrapperWH ,
170
+ activeTabWH ,
171
+ activeTabOffset ,
172
+ rtl ,
173
+ target
174
+ ) {
175
+ if (
176
+ // active tab covers wrapper right edge
177
+ wrapperOffset + wrapperWH < activeTabOffset + activeTabWH &&
178
+ activeTabOffset < wrapperOffset + wrapperWH
179
+ ) {
180
+ if ( rtl ) {
181
+ target += // Move more to make active tab totally in visible zone
182
+ activeTabOffset + activeTabWH - ( wrapperOffset + wrapperWH ) ;
183
+ } else {
184
+ target -=
185
+ activeTabOffset +
186
+ activeTabWH -
187
+ ( wrapperOffset + wrapperWH ) +
188
+ 1 ;
189
+ }
190
+
191
+ return target ;
192
+ }
193
+ if (
194
+ // active tab covers wrapper left edge
195
+ wrapperOffset < activeTabOffset + activeTabWH &&
196
+ activeTabOffset < wrapperOffset
197
+ ) {
198
+ if ( rtl ) {
199
+ target -= wrapperOffset - activeTabOffset + 1 ;
200
+ } else {
201
+ target += wrapperOffset - activeTabOffset ;
202
+ }
203
+ return target ;
204
+ }
205
+ return target ;
206
+ }
207
+
208
+ _setBtnStyle ( prev , next ) {
209
+ if ( this . prevBtn && this . nextBtn ) {
210
+ const cls = 'disabled' ;
211
+ this . prevBtn . disabled = ! prev ;
212
+ this . nextBtn . disabled = ! next ;
213
+ if ( prev ) {
214
+ dom . removeClass ( this . prevBtn , cls ) ;
215
+ } else {
216
+ dom . addClass ( this . prevBtn , cls ) ;
217
+ }
218
+ if ( next ) {
219
+ dom . removeClass ( this . nextBtn , cls ) ;
220
+ } else {
221
+ dom . addClass ( this . nextBtn , cls ) ;
222
+ }
223
+ }
224
+ }
225
+
174
226
setSlideBtn ( ) {
175
227
const { tabPosition } = this . props ;
176
228
@@ -185,7 +237,6 @@ class Nav extends React.Component {
185
237
if ( minOffset >= 0 || navWH <= navbarWH ) {
186
238
next = false ;
187
239
prev = false ;
188
- this . setOffset ( 0 , false ) ; // no need to check slide again since this call is invoked from inside setSlideBtn
189
240
} else if ( this . offset < 0 && this . offset <= minOffset ) {
190
241
prev = true ;
191
242
next = false ;
@@ -196,12 +247,12 @@ class Nav extends React.Component {
196
247
prev = true ;
197
248
next = true ;
198
249
}
199
-
200
- if ( next !== this . state . next || prev !== this . state . prev ) {
250
+ if ( ( prev || next ) !== this . state . showBtn ) {
201
251
this . setState ( {
202
- next,
203
- prev,
252
+ showBtn : prev || next ,
204
253
} ) ;
254
+ } else {
255
+ this . _setBtnStyle ( prev , next ) ;
205
256
}
206
257
}
207
258
@@ -343,15 +394,7 @@ class Nav extends React.Component {
343
394
) {
344
395
return ;
345
396
}
346
- // if (activeTabOffset < wrapperOffset) {
347
- // target += wrapperOffset - activeTabOffset;
348
- // this.setOffset(target);
349
- // }
350
- if ( wrapperOffset + wrapperWH < activeTabOffset + activeTabWH ) {
351
- target -=
352
- activeTabOffset + activeTabWH - ( wrapperOffset + wrapperWH ) ;
353
- this . setOffset ( target , true , false ) ;
354
- }
397
+ this . setOffset ( target , true , true ) ;
355
398
} ;
356
399
357
400
onPrevClick = ( ) => {
@@ -480,6 +523,14 @@ class Nav extends React.Component {
480
523
this . activeTab = ref ;
481
524
} ;
482
525
526
+ prevBtnHandler = ref => {
527
+ this . prevBtn = findDOMNode ( ref ) ;
528
+ } ;
529
+
530
+ nextBtnHandler = ref => {
531
+ this . nextBtn = findDOMNode ( ref ) ;
532
+ } ;
533
+
483
534
render ( ) {
484
535
const {
485
536
prefix,
@@ -498,39 +549,32 @@ class Nav extends React.Component {
498
549
let prevButton ;
499
550
let restButton ;
500
551
501
- const showNextPrev = state . prev || state . next ;
552
+ const showNextPrev = state . showBtn ;
502
553
503
554
if (
504
555
excessMode === 'dropdown' &&
505
- state . next &&
556
+ showNextPrev &&
506
557
state . dropdownTabs . length
507
558
) {
508
559
restButton = this . renderDropdownTabs ( state . dropdownTabs ) ;
509
560
prevButton = null ;
510
561
nextButton = null ;
511
562
} else if ( showNextPrev ) {
512
- const prevBtnCls = classnames ( {
513
- [ `${ prefix } tabs-btn-prev` ] : 1 ,
514
- disabled : ! state . prev ,
515
- } ) ;
516
- const nextBtnCls = classnames ( {
517
- [ `${ prefix } tabs-btn-next` ] : 1 ,
518
- disabled : ! state . next ,
519
- } ) ;
520
-
521
563
prevButton = (
522
564
< button
523
- onClick = { state . prev ? this . onPrevClick : noop }
524
- className = { prevBtnCls }
565
+ onClick = { this . onPrevClick }
566
+ className = { `${ prefix } tabs-btn-prev` }
567
+ ref = { this . prevBtnHandler }
525
568
>
526
569
< Icon rtl = { rtl } type = "arrow-left" />
527
570
</ button >
528
571
) ;
529
572
530
573
nextButton = (
531
574
< button
532
- onClick = { state . next ? this . onNextClick : noop }
533
- className = { nextBtnCls }
575
+ onClick = { this . onNextClick }
576
+ className = { `${ prefix } tabs-btn-next` }
577
+ ref = { this . nextBtnHandler }
534
578
>
535
579
< Icon rtl = { rtl } type = "arrow-right" />
536
580
</ button >
0 commit comments