('end');
+
+ return (
+ <>
+
+
+ Start
+ setScrollPosition(e.target.value as ScrollPosition)}
+ />
+
+
+ Center
+ setScrollPosition(e.target.value as ScrollPosition)}
+ />
+
+
+ End
+ setScrollPosition(e.target.value as ScrollPosition)}
+ />
+
+
+ Auto
+ setScrollPosition(e.target.value as ScrollPosition)}
+ />
+
+
+
+
+
+
+
+
+
+ >
+ );
+};
diff --git a/src/TabNavList/index.tsx b/src/TabNavList/index.tsx
index e51553af..c71e5ff1 100644
--- a/src/TabNavList/index.tsx
+++ b/src/TabNavList/index.tsx
@@ -19,6 +19,7 @@ import type {
MoreProps,
OnTabScroll,
RenderTabBar,
+ ScrollPosition,
SizeInfo,
TabBarExtraContent,
TabPosition,
@@ -55,6 +56,7 @@ export interface TabNavListProps {
size?: GetIndicatorSize;
align?: 'start' | 'center' | 'end';
};
+ scrollPosition?: ScrollPosition;
}
const getTabSize = (tab: HTMLElement, containerRect: { left: number; top: number }) => {
@@ -104,6 +106,7 @@ const TabNavList = React.forwardRef((props, ref
editable,
locale,
tabPosition,
+ scrollPosition,
tabBarGutter,
children,
onTabClick,
@@ -150,7 +153,8 @@ const TabNavList = React.forwardRef((props, ref
const addSizeValue = getUnitValue(addSize, tabPositionTopOrBottom);
const operationSizeValue = getUnitValue(operationSize, tabPositionTopOrBottom);
- const needScroll = Math.floor(containerExcludeExtraSizeValue) < Math.floor(tabContentSizeValue + addSizeValue);
+ const needScroll =
+ Math.floor(containerExcludeExtraSizeValue) < Math.floor(tabContentSizeValue + addSizeValue);
const visibleTabContentValue = needScroll
? containerExcludeExtraSizeValue - operationSizeValue
: containerExcludeExtraSizeValue - addSizeValue;
@@ -264,19 +268,36 @@ const TabNavList = React.forwardRef((props, ref
// ============ Align with top & bottom ============
let newTransform = transformLeft;
- // RTL
if (rtl) {
- if (tabOffset.right < transformLeft) {
+ // RTL logic
+ if (scrollPosition === 'auto') {
+ if (tabOffset.right < transformLeft) {
+ newTransform = tabOffset.right;
+ } else if (tabOffset.right + tabOffset.width > transformLeft + visibleTabContentValue) {
+ newTransform = tabOffset.right + tabOffset.width - visibleTabContentValue;
+ }
+ } else if (scrollPosition === 'start') {
newTransform = tabOffset.right;
- } else if (tabOffset.right + tabOffset.width > transformLeft + visibleTabContentValue) {
+ } else if (scrollPosition === 'end') {
newTransform = tabOffset.right + tabOffset.width - visibleTabContentValue;
+ } else if (scrollPosition === 'center') {
+ newTransform = tabOffset.right + tabOffset.width / 2 - visibleTabContentValue / 2;
+ }
+ } else {
+ // LTR logic
+ if (scrollPosition === 'auto') {
+ if (tabOffset.left < -transformLeft) {
+ newTransform = -tabOffset.left;
+ } else if (tabOffset.left + tabOffset.width > -transformLeft + visibleTabContentValue) {
+ newTransform = -(tabOffset.left + tabOffset.width - visibleTabContentValue);
+ }
+ } else if (scrollPosition === 'start') {
+ newTransform = -tabOffset.left;
+ } else if (scrollPosition === 'end') {
+ newTransform = -(tabOffset.left + tabOffset.width - visibleTabContentValue);
+ } else if (scrollPosition === 'center') {
+ newTransform = -(tabOffset.left + tabOffset.width / 2 - visibleTabContentValue / 2);
}
- }
- // LTR
- else if (tabOffset.left < -transformLeft) {
- newTransform = -tabOffset.left;
- } else if (tabOffset.left + tabOffset.width > -transformLeft + visibleTabContentValue) {
- newTransform = -(tabOffset.left + tabOffset.width - visibleTabContentValue);
}
setTransformTop(0);
@@ -285,10 +306,18 @@ const TabNavList = React.forwardRef((props, ref
// ============ Align with left & right ============
let newTransform = transformTop;
- if (tabOffset.top < -transformTop) {
+ if (scrollPosition === 'auto') {
+ if (tabOffset.top < -transformTop) {
+ newTransform = -tabOffset.top;
+ } else if (tabOffset.top + tabOffset.height > -transformTop + visibleTabContentValue) {
+ newTransform = -(tabOffset.top + tabOffset.height - visibleTabContentValue);
+ }
+ } else if (scrollPosition === 'start') {
newTransform = -tabOffset.top;
- } else if (tabOffset.top + tabOffset.height > -transformTop + visibleTabContentValue) {
+ } else if (scrollPosition === 'end') {
newTransform = -(tabOffset.top + tabOffset.height - visibleTabContentValue);
+ } else if (scrollPosition === 'center') {
+ newTransform = -(tabOffset.top + tabOffset.height / 2 - visibleTabContentValue / 2);
}
setTransformLeft(0);
@@ -323,7 +352,6 @@ const TabNavList = React.forwardRef((props, ref
onTabClick(key, e);
}}
onFocus={() => {
- scrollToTab(key);
doLockAnimation();
if (!tabsWrapperRef.current) {
return;
@@ -411,6 +439,7 @@ const TabNavList = React.forwardRef((props, ref
stringify(activeTabOffset),
stringify(tabOffsets as any),
tabPositionTopOrBottom,
+ scrollPosition,
]);
// Should recalculate when rtl changed
diff --git a/src/Tabs.tsx b/src/Tabs.tsx
index 7d6df768..e4febb2c 100644
--- a/src/Tabs.tsx
+++ b/src/Tabs.tsx
@@ -15,6 +15,7 @@ import type {
MoreProps,
OnTabScroll,
RenderTabBar,
+ ScrollPosition,
Tab,
TabBarExtraContent,
TabPosition,
@@ -72,6 +73,8 @@ export interface TabsProps
size?: GetIndicatorSize;
align?: 'start' | 'center' | 'end';
};
+
+ scrollPosition?: ScrollPosition;
}
const Tabs = React.forwardRef((props, ref) => {
@@ -99,6 +102,7 @@ const Tabs = React.forwardRef((props, ref) => {
getPopupContainer,
popupClassName,
indicator,
+ scrollPosition = 'auto',
...restProps
} = props;
const tabs = React.useMemo(
@@ -182,6 +186,7 @@ const Tabs = React.forwardRef((props, ref) => {
getPopupContainer,
popupClassName,
indicator,
+ scrollPosition,
};
return (
diff --git a/src/interface.ts b/src/interface.ts
index ea7958af..878fc61f 100644
--- a/src/interface.ts
+++ b/src/interface.ts
@@ -1,15 +1,15 @@
+import type { DropdownProps } from 'rc-dropdown/lib/Dropdown';
import type { CSSMotionProps } from 'rc-motion';
import type React from 'react';
import type { TabNavListProps } from './TabNavList';
import type { TabPaneProps } from './TabPanelList/TabPane';
-import { DropdownProps } from 'rc-dropdown/lib/Dropdown';
export type TriggerProps = {
trigger?: 'hover' | 'click';
-}
+};
export type moreIcon = React.ReactNode;
export type MoreProps = {
- icon?: moreIcon,
+ icon?: moreIcon;
} & Omit;
export type SizeInfo = [width: number, height: number];
@@ -45,7 +45,7 @@ type RenderTabBarProps = {
mobile: boolean;
editable: EditableConfig;
locale: TabsLocale;
- more: MoreProps,
+ more: MoreProps;
tabBarGutter: number;
onTabClick: (key: string, e: React.MouseEvent | React.KeyboardEvent) => void;
onTabScroll: OnTabScroll;
@@ -89,3 +89,5 @@ export type TabBarExtraPosition = 'left' | 'right';
export type TabBarExtraMap = Partial>;
export type TabBarExtraContent = React.ReactNode | TabBarExtraMap;
+
+export type ScrollPosition = 'start' | 'end' | 'center' | 'auto';