@@ -9,6 +9,9 @@ type ThumbReact = {
9
9
left : number ;
10
10
right : number ;
11
11
width : number ;
12
+ top : number ;
13
+ bottom : number ;
14
+ height : number ;
12
15
} | null ;
13
16
14
17
export interface MotionThumbInterface {
@@ -20,23 +23,53 @@ export interface MotionThumbInterface {
20
23
onMotionStart : VoidFunction ;
21
24
onMotionEnd : VoidFunction ;
22
25
direction ?: 'ltr' | 'rtl' ;
26
+ vertical ?: boolean ;
23
27
}
24
28
25
29
const calcThumbStyle = (
26
30
targetElement : HTMLElement | null | undefined ,
27
- ) : ThumbReact =>
28
- targetElement
29
- ? {
30
- left : targetElement . offsetLeft ,
31
- right :
32
- ( targetElement . parentElement ! . clientWidth as number ) -
33
- targetElement . clientWidth -
34
- targetElement . offsetLeft ,
35
- width : targetElement . clientWidth ,
36
- }
37
- : null ;
31
+ vertical ?: boolean ,
32
+ ) : ThumbReact => {
33
+ if ( ! targetElement ) return null ;
34
+
35
+ const style : ThumbReact = {
36
+ left : targetElement . offsetLeft ,
37
+ right :
38
+ ( targetElement . parentElement ! . clientWidth as number ) -
39
+ targetElement . clientWidth -
40
+ targetElement . offsetLeft ,
41
+ width : targetElement . clientWidth ,
42
+ top : targetElement . offsetTop ,
43
+ bottom :
44
+ ( targetElement . parentElement ! . clientHeight as number ) -
45
+ targetElement . clientHeight -
46
+ targetElement . offsetTop ,
47
+ height : targetElement . clientHeight ,
48
+ } ;
49
+
50
+ if ( vertical ) {
51
+ // Adjusts positioning and size for vertical layout by setting horizontal properties to 0 and using vertical properties from the style object.
52
+ return {
53
+ left : 0 ,
54
+ right : 0 ,
55
+ width : 0 ,
56
+ top : style . top ,
57
+ bottom : style . bottom ,
58
+ height : style . height ,
59
+ } ;
60
+ }
61
+
62
+ return {
63
+ left : style . left ,
64
+ right : style . right ,
65
+ width : style . width ,
66
+ top : 0 ,
67
+ bottom : 0 ,
68
+ height : 0 ,
69
+ } ;
70
+ } ;
38
71
39
- const toPX = ( value : number ) =>
72
+ const toPX = ( value : number | undefined ) : string | undefined =>
40
73
value !== undefined ? `${ value } px` : undefined ;
41
74
42
75
export default function MotionThumb ( props : MotionThumbInterface ) {
@@ -49,6 +82,7 @@ export default function MotionThumb(props: MotionThumbInterface) {
49
82
onMotionStart,
50
83
onMotionEnd,
51
84
direction,
85
+ vertical = false ,
52
86
} = props ;
53
87
54
88
const thumbRef = React . useRef < HTMLDivElement > ( null ) ;
@@ -57,11 +91,9 @@ export default function MotionThumb(props: MotionThumbInterface) {
57
91
// =========================== Effect ===========================
58
92
const findValueElement = ( val : SegmentedValue ) => {
59
93
const index = getValueIndex ( val ) ;
60
-
61
94
const ele = containerRef . current ?. querySelectorAll < HTMLDivElement > (
62
95
`.${ prefixCls } -item` ,
63
96
) [ index ] ;
64
-
65
97
return ele ?. offsetParent && ele ;
66
98
} ;
67
99
@@ -73,8 +105,8 @@ export default function MotionThumb(props: MotionThumbInterface) {
73
105
const prev = findValueElement ( prevValue ) ;
74
106
const next = findValueElement ( value ) ;
75
107
76
- const calcPrevStyle = calcThumbStyle ( prev ) ;
77
- const calcNextStyle = calcThumbStyle ( next ) ;
108
+ const calcPrevStyle = calcThumbStyle ( prev , vertical ) ;
109
+ const calcNextStyle = calcThumbStyle ( next , vertical ) ;
78
110
79
111
setPrevValue ( value ) ;
80
112
setPrevStyle ( calcPrevStyle ) ;
@@ -88,34 +120,59 @@ export default function MotionThumb(props: MotionThumbInterface) {
88
120
}
89
121
} , [ value ] ) ;
90
122
91
- const thumbStart = React . useMemo (
92
- ( ) =>
93
- direction === 'rtl'
94
- ? toPX ( - ( prevStyle ?. right as number ) )
95
- : toPX ( prevStyle ?. left as number ) ,
96
- [ direction , prevStyle ] ,
97
- ) ;
98
- const thumbActive = React . useMemo (
99
- ( ) =>
100
- direction === 'rtl'
101
- ? toPX ( - ( nextStyle ?. right as number ) )
102
- : toPX ( nextStyle ?. left as number ) ,
103
- [ direction , nextStyle ] ,
104
- ) ;
123
+ const thumbStart = React . useMemo ( ( ) => {
124
+ if ( vertical ) {
125
+ return toPX ( prevStyle ?. top ?? 0 ) ;
126
+ }
127
+
128
+ if ( direction === 'rtl' ) {
129
+ return toPX ( - ( prevStyle ?. right as number ) ) ;
130
+ }
131
+
132
+ return toPX ( prevStyle ?. left as number ) ;
133
+ } , [ vertical , direction , prevStyle ] ) ;
134
+
135
+ const thumbActive = React . useMemo ( ( ) => {
136
+ if ( vertical ) {
137
+ return toPX ( nextStyle ?. top ?? 0 ) ;
138
+ }
139
+
140
+ if ( direction === 'rtl' ) {
141
+ return toPX ( - ( nextStyle ?. right as number ) ) ;
142
+ }
143
+
144
+ return toPX ( nextStyle ?. left as number ) ;
145
+ } , [ vertical , direction , nextStyle ] ) ;
105
146
106
147
// =========================== Motion ===========================
107
148
const onAppearStart = ( ) => {
149
+ if ( vertical ) {
150
+ return {
151
+ transform : 'translateY(var(--thumb-start-top))' ,
152
+ height : 'var(--thumb-start-height)' ,
153
+ } ;
154
+ }
155
+
108
156
return {
109
- transform : ` translateX(var(--thumb-start-left))` ,
110
- width : ` var(--thumb-start-width)` ,
157
+ transform : ' translateX(var(--thumb-start-left))' ,
158
+ width : ' var(--thumb-start-width)' ,
111
159
} ;
112
160
} ;
161
+
113
162
const onAppearActive = ( ) => {
163
+ if ( vertical ) {
164
+ return {
165
+ transform : 'translateY(var(--thumb-active-top))' ,
166
+ height : 'var(--thumb-active-height)' ,
167
+ } ;
168
+ }
169
+
114
170
return {
115
- transform : ` translateX(var(--thumb-active-left))` ,
116
- width : ` var(--thumb-active-width)` ,
171
+ transform : ' translateX(var(--thumb-active-left))' ,
172
+ width : ' var(--thumb-active-width)' ,
117
173
} ;
118
174
} ;
175
+
119
176
const onVisibleChanged = ( ) => {
120
177
setPrevStyle ( null ) ;
121
178
setNextStyle ( null ) ;
@@ -144,6 +201,10 @@ export default function MotionThumb(props: MotionThumbInterface) {
144
201
'--thumb-start-width' : toPX ( prevStyle ?. width ) ,
145
202
'--thumb-active-left' : thumbActive ,
146
203
'--thumb-active-width' : toPX ( nextStyle ?. width ) ,
204
+ '--thumb-start-top' : thumbStart ,
205
+ '--thumb-start-height' : toPX ( prevStyle ?. height ) ,
206
+ '--thumb-active-top' : thumbActive ,
207
+ '--thumb-active-height' : toPX ( nextStyle ?. height ) ,
147
208
} as React . CSSProperties ;
148
209
149
210
// It's little ugly which should be refactor when @umi/test update to latest jsdom
0 commit comments