11import raf from 'rc-util/lib/raf' ;
2- import type React from 'react' ;
3- import { useEffect , useRef , useState } from 'react' ;
2+ import React , { useEffect , useRef , useState } from 'react' ;
43import type { TabOffset } from '../interface' ;
54
65export type GetIndicatorSize = number | ( ( origin : number ) => number ) ;
76
8- export type UseIndicator = ( options : {
7+ interface UseIndicatorOptions {
98 activeTabOffset : TabOffset ;
109 horizontal : boolean ;
1110 rtl : boolean ;
1211 indicatorSize : GetIndicatorSize ;
13- } ) => {
14- style : React . CSSProperties ;
15- } ;
12+ indicatorAlign : 'start' | 'center' | 'end' ;
13+ }
1614
17- const useIndicator : UseIndicator = ( { activeTabOffset, horizontal, rtl, indicatorSize } ) => {
15+ const useIndicator = ( options : UseIndicatorOptions ) => {
16+ const { activeTabOffset, horizontal, rtl, indicatorSize, indicatorAlign } = options ;
1817 const [ inkStyle , setInkStyle ] = useState < React . CSSProperties > ( ) ;
1918 const inkBarRafRef = useRef < number > ( ) ;
2019
21- const getLength = ( origin : number ) => {
22- if ( typeof indicatorSize === 'function' ) {
23- return indicatorSize ( origin ) ;
24- }
25- if ( typeof indicatorSize === 'number' ) {
26- return indicatorSize ;
27- }
28- return origin ;
29- } ;
20+ const getLength = React . useCallback (
21+ ( origin : number ) => {
22+ if ( typeof indicatorSize === 'function' ) {
23+ return indicatorSize ( origin ) ;
24+ }
25+ if ( typeof indicatorSize === 'number' ) {
26+ return indicatorSize ;
27+ }
28+ return origin ;
29+ } ,
30+ [ indicatorSize ] ,
31+ ) ;
3032
3133 // Delay set ink style to avoid remove tab blink
3234 function cleanInkBarRaf ( ) {
@@ -38,18 +40,32 @@ const useIndicator: UseIndicator = ({ activeTabOffset, horizontal, rtl, indicato
3840
3941 if ( activeTabOffset ) {
4042 if ( horizontal ) {
41- if ( rtl ) {
42- newInkStyle . right = activeTabOffset . right + activeTabOffset . width / 2 ;
43- newInkStyle . transform = 'translateX(50%)' ;
44- } else {
45- newInkStyle . left = activeTabOffset . left + activeTabOffset . width / 2 ;
46- newInkStyle . transform = 'translateX(-50%)' ;
47- }
4843 newInkStyle . width = getLength ( activeTabOffset . width ) ;
44+ const key = rtl ? 'right' : 'left' ;
45+ if ( indicatorAlign === 'start' ) {
46+ newInkStyle [ key ] = activeTabOffset [ key ] ;
47+ }
48+ if ( indicatorAlign === 'center' ) {
49+ newInkStyle [ key ] = activeTabOffset [ key ] + activeTabOffset . width / 2 ;
50+ newInkStyle . transform = rtl ? 'translateX(50%)' : 'translateX(-50%)' ;
51+ }
52+ if ( indicatorAlign === 'end' ) {
53+ newInkStyle [ key ] = activeTabOffset [ key ] + activeTabOffset . width ;
54+ newInkStyle . transform = 'translateX(-100%)' ;
55+ }
4956 } else {
50- newInkStyle . top = activeTabOffset . top + activeTabOffset . height / 2 ;
51- newInkStyle . transform = 'translateY(-50%)' ;
5257 newInkStyle . height = getLength ( activeTabOffset . height ) ;
58+ if ( indicatorAlign === 'start' ) {
59+ newInkStyle . top = activeTabOffset . top ;
60+ }
61+ if ( indicatorAlign === 'center' ) {
62+ newInkStyle . top = activeTabOffset . top + activeTabOffset . height / 2 ;
63+ newInkStyle . transform = 'translateY(-50%)' ;
64+ }
65+ if ( indicatorAlign === 'end' ) {
66+ newInkStyle . top = activeTabOffset . top + activeTabOffset . height ;
67+ newInkStyle . transform = 'translateY(-100%)' ;
68+ }
5369 }
5470 }
5571
@@ -59,11 +75,9 @@ const useIndicator: UseIndicator = ({ activeTabOffset, horizontal, rtl, indicato
5975 } ) ;
6076
6177 return cleanInkBarRaf ;
62- } , [ activeTabOffset , horizontal , rtl , indicatorSize ] ) ;
78+ } , [ activeTabOffset , horizontal , rtl , indicatorSize , indicatorAlign , getLength ] ) ;
6379
64- return {
65- style : inkStyle ,
66- } ;
80+ return { style : inkStyle } ;
6781} ;
6882
6983export default useIndicator ;
0 commit comments