Skip to content

Commit

Permalink
refactor: refactor indicator props (#695)
Browse files Browse the repository at this point in the history
* refactor: refactor indicator props

* update demo

* test: fix test case
  • Loading branch information
li-jia-nan authored Jan 4, 2024
1 parent ba563b4 commit 28b061b
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 47 deletions.
18 changes: 6 additions & 12 deletions docs/examples/indicator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,38 +26,32 @@ export default () => (
<Tabs
tabPosition="top"
items={items}
indicatorSize={origin => origin - 20}
indicatorAlign="start"
indicator={{ size: origin => origin - 20, align: 'start' }}
/>
<Tabs
tabPosition="top"
items={items}
indicatorSize={origin => origin - 20}
indicatorAlign="center"
indicator={{ size: origin => origin - 20, align: 'center' }}
/>
<Tabs
tabPosition="top"
items={items}
indicatorSize={origin => origin - 20}
indicatorAlign="end"
indicator={{ size: origin => origin - 20, align: 'end' }}
/>
<Tabs
tabPosition="left"
items={items}
indicatorSize={origin => origin - 20}
indicatorAlign="start"
indicator={{ size: origin => origin - 20, align: 'start' }}
/>
<Tabs
tabPosition="left"
items={items}
indicatorSize={origin => origin - 20}
indicatorAlign="center"
indicator={{ size: origin => origin - 20, align: 'center' }}
/>
<Tabs
tabPosition="left"
items={items}
indicatorSize={origin => origin - 20}
indicatorAlign="end"
indicator={{ size: origin => origin - 20, align: 'end' }}
/>
</>
);
20 changes: 16 additions & 4 deletions src/TabNavList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,13 @@ export interface TabNavListProps {
children?: (node: React.ReactElement) => React.ReactElement;
getPopupContainer?: (node: HTMLElement) => HTMLElement;
popupClassName?: string;

/** @deprecated Use `indicator={ size: ... }` instead */
indicatorSize?: GetIndicatorSize;
indicatorAlign?: 'start' | 'center' | 'end';
indicator?: {
size?: GetIndicatorSize;
align?: 'start' | 'center' | 'end';
};
}

const getTabSize = (tab: HTMLElement, containerRect: { x: number; y: number }) => {
Expand Down Expand Up @@ -107,8 +112,13 @@ const TabNavList = React.forwardRef<HTMLDivElement, TabNavListProps>((props, ref
onTabClick,
onTabScroll,
indicatorSize,
indicatorAlign,
indicator,
} = props;

const mergedIndicatorSize = indicator?.size || indicatorSize;

const mergedIndicatorAlign = indicator?.align || 'center';

const { prefixCls, tabs } = React.useContext(TabContext);
const containerRef = useRef<HTMLDivElement>(null);
const extraLeftRef = useRef<HTMLDivElement>(null);
Expand Down Expand Up @@ -396,8 +406,10 @@ const TabNavList = React.forwardRef<HTMLDivElement, TabNavListProps>((props, ref
activeTabOffset,
horizontal: tabPositionTopOrBottom,
rtl,
indicatorSize,
indicatorAlign,
indicator: {
size: mergedIndicatorSize,
align: mergedIndicatorAlign,
},
});

// ========================= Effect ========================
Expand Down
11 changes: 7 additions & 4 deletions src/Tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,12 @@ export interface TabsProps

popupClassName?: string;

// Indicator
/** @deprecated Use `indicator={ size: ... }` instead */
indicatorSize?: GetIndicatorSize;
indicatorAlign?: 'start' | 'center' | 'end';
indicator?: {
size?: GetIndicatorSize;
align?: 'start' | 'center' | 'end';
};
}

const Tabs = React.forwardRef<HTMLDivElement, TabsProps>((props, ref) => {
Expand Down Expand Up @@ -101,7 +104,7 @@ const Tabs = React.forwardRef<HTMLDivElement, TabsProps>((props, ref) => {
getPopupContainer,
popupClassName,
indicatorSize,
indicatorAlign = 'center',
indicator,
...restProps
} = props;
const tabs = React.useMemo<Tab[]>(
Expand Down Expand Up @@ -186,7 +189,7 @@ const Tabs = React.forwardRef<HTMLDivElement, TabsProps>((props, ref) => {
getPopupContainer,
popupClassName,
indicatorSize,
indicatorAlign,
indicator,
};

return (
Expand Down
32 changes: 17 additions & 15 deletions src/hooks/useIndicator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,28 @@ interface UseIndicatorOptions {
activeTabOffset: TabOffset;
horizontal: boolean;
rtl: boolean;
indicatorSize: GetIndicatorSize;
indicatorAlign: 'start' | 'center' | 'end';
indicator?: {
size?: GetIndicatorSize;
align?: 'start' | 'center' | 'end';
};
}

const useIndicator = (options: UseIndicatorOptions) => {
const { activeTabOffset, horizontal, rtl, indicatorSize, indicatorAlign } = options;
const { activeTabOffset, horizontal, rtl, indicator } = options;
const [inkStyle, setInkStyle] = useState<React.CSSProperties>();
const inkBarRafRef = useRef<number>();

const getLength = React.useCallback(
(origin: number) => {
if (typeof indicatorSize === 'function') {
return indicatorSize(origin);
if (typeof indicator?.size === 'function') {
return indicator?.size(origin);
}
if (typeof indicatorSize === 'number') {
return indicatorSize;
if (typeof indicator?.size === 'number') {
return indicator?.size;
}
return origin;
},
[indicatorSize],
[indicator],
);

// Delay set ink style to avoid remove tab blink
Expand All @@ -42,27 +44,27 @@ const useIndicator = (options: UseIndicatorOptions) => {
if (horizontal) {
newInkStyle.width = getLength(activeTabOffset.width);
const key = rtl ? 'right' : 'left';
if (indicatorAlign === 'start') {
if (indicator?.align === 'start') {
newInkStyle[key] = activeTabOffset[key];
}
if (indicatorAlign === 'center') {
if (indicator?.align === 'center') {
newInkStyle[key] = activeTabOffset[key] + activeTabOffset.width / 2;
newInkStyle.transform = rtl ? 'translateX(50%)' : 'translateX(-50%)';
}
if (indicatorAlign === 'end') {
if (indicator?.align === 'end') {
newInkStyle[key] = activeTabOffset[key] + activeTabOffset.width;
newInkStyle.transform = 'translateX(-100%)';
}
} else {
newInkStyle.height = getLength(activeTabOffset.height);
if (indicatorAlign === 'start') {
if (indicator?.align === 'start') {
newInkStyle.top = activeTabOffset.top;
}
if (indicatorAlign === 'center') {
if (indicator?.align === 'center') {
newInkStyle.top = activeTabOffset.top + activeTabOffset.height / 2;
newInkStyle.transform = 'translateY(-50%)';
}
if (indicatorAlign === 'end') {
if (indicator?.align === 'end') {
newInkStyle.top = activeTabOffset.top + activeTabOffset.height;
newInkStyle.transform = 'translateY(-100%)';
}
Expand All @@ -75,7 +77,7 @@ const useIndicator = (options: UseIndicatorOptions) => {
});

return cleanInkBarRaf;
}, [activeTabOffset, horizontal, rtl, indicatorSize, indicatorAlign, getLength]);
}, [activeTabOffset, horizontal, rtl, indicator?.align, getLength]);

return { style: inkStyle };
};
Expand Down
18 changes: 6 additions & 12 deletions tests/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -653,22 +653,19 @@ describe('Tabs.Basic', () => {
const { container: startContainer } = render(
<Tabs
items={[{ key: 'test', label: 'test', icon: 'test' }]}
indicatorSize={origin => origin - 10}
indicatorAlign="start"
indicator={{ size: origin => origin - 20, align: 'start' }}
/>,
);
const { container: centerContainer } = render(
<Tabs
items={[{ key: 'test', label: 'test', icon: 'test' }]}
indicatorSize={origin => origin - 10}
indicatorAlign="center"
indicator={{ size: origin => origin - 20, align: 'center' }}
/>,
);
const { container: endContainer } = render(
<Tabs
items={[{ key: 'test', label: 'test', icon: 'test' }]}
indicatorSize={origin => origin - 10}
indicatorAlign="end"
indicator={{ size: origin => origin - 20, align: 'end' }}
/>,
);

Expand All @@ -689,24 +686,21 @@ describe('Tabs.Basic', () => {
<Tabs
tabPosition="left"
items={[{ key: 'test', label: 'test', icon: 'test' }]}
indicatorSize={origin => origin - 10}
indicatorAlign="start"
indicator={{ size: origin => origin - 20, align: 'start' }}
/>,
);
const { container: centerContainer } = render(
<Tabs
tabPosition="left"
items={[{ key: 'test', label: 'test', icon: 'test' }]}
indicatorSize={origin => origin - 10}
indicatorAlign="center"
indicator={{ size: origin => origin - 20, align: 'center' }}
/>,
);
const { container: endContainer } = render(
<Tabs
tabPosition="left"
items={[{ key: 'test', label: 'test', icon: 'test' }]}
indicatorSize={origin => origin - 10}
indicatorAlign="end"
indicator={{ size: origin => origin - 20, align: 'end' }}
/>,
);

Expand Down

1 comment on commit 28b061b

@vercel
Copy link

@vercel vercel bot commented on 28b061b Jan 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

tabs – ./

tabs-git-master-react-component.vercel.app
tabs-react-component.vercel.app

Please sign in to comment.