Browse Source

fix(tabs): Fixed the issue where the overflow tab did not scroll into view when the activeKey changed(#2239) (#2241)

Elvis 1 year ago
parent
commit
08c76a5b7b
2 changed files with 56 additions and 8 deletions
  1. 19 7
      packages/semi-ui/tabs/TabBar.tsx
  2. 37 1
      packages/semi-ui/tabs/_story/tabs.stories.jsx

+ 19 - 7
packages/semi-ui/tabs/TabBar.tsx

@@ -58,6 +58,14 @@ class TabBar extends React.Component<TabBarProps, TabBarState> {
             uuid: getUuidv4(),
         });
     }
+    
+    componentDidUpdate(prevProps) {
+        if (prevProps.activeKey !== this.props.activeKey) {
+            if (this.props.collapsible) {
+                this.scrollActiveTabItemIntoView()
+            }
+        }
+    }
 
     renderIcon(icon: ReactNode): ReactNode {
         return (
@@ -89,11 +97,6 @@ class TabBar extends React.Component<TabBarProps, TabBarState> {
 
     handleItemClick = (itemKey: string, e: MouseEvent<Element>): void => {
         this.props.onTabClick(itemKey, e);
-        if (this.props.collapsible) {
-            const key = this._getItemKey(itemKey);
-            const tabItem = document.querySelector(`[data-uuid="${this.state.uuid}"] .${cssClasses.TABS_TAB}[data-scrollkey="${key}"]`);
-            tabItem.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'nearest' });
-        }
     };
 
     handleKeyDown = (event: React.KeyboardEvent, itemKey: string, closable: boolean) => {
@@ -119,6 +122,16 @@ class TabBar extends React.Component<TabBarProps, TabBarState> {
         );
     };
 
+    scrollTabItemIntoViewByKey = (key: string, logicalPosition: ScrollLogicalPosition = 'nearest') => {
+        const tabItem = document.querySelector(`[data-uuid="${this.state.uuid}"] .${cssClasses.TABS_TAB}[data-scrollkey="${key}"]`);
+        tabItem?.scrollIntoView({ behavior: 'smooth', block: logicalPosition, inline: logicalPosition });
+    }
+
+    scrollActiveTabItemIntoView = (logicalPosition?: ScrollLogicalPosition) => {
+        const key = this._getItemKey(this.props.activeKey);
+        this.scrollTabItemIntoViewByKey(key, logicalPosition)
+    }
+
     renderTabComponents = (list: Array<PlainTab>): Array<ReactNode> => list.map(panel => this.renderTabItem(panel));
 
     handleArrowClick = (items: Array<OverflowItem>, pos: 'start' | 'end'): void => {
@@ -127,8 +140,7 @@ class TabBar extends React.Component<TabBarProps, TabBarState> {
             return;
         }
         const key = this._getItemKey(lastItem.itemKey);
-        const tabItem = document.querySelector(`[data-uuid="${this.state.uuid}"] .${cssClasses.TABS_TAB}[data-scrollkey="${key}"]`);
-        tabItem.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'nearest' });
+        this.scrollTabItemIntoViewByKey(key)
     };
 
     renderCollapse = (items: Array<OverflowItem>, icon: ReactNode, pos: 'start' | 'end'): ReactNode => {

+ 37 - 1
packages/semi-ui/tabs/_story/tabs.stories.jsx

@@ -1002,4 +1002,40 @@ export const IconStyle = () => {
         </TabPane>
     </Tabs>
   )
-}
+}
+
+export const Fix2239 = () => {
+  const [activeKey, setActiveKey] = useState('tab-0')
+  
+  return (
+    <div>
+      The overflow tab will also 'scrollIntoView' when the 'activeKey' changes.
+      <Tabs
+        style={{
+          width: '500px',
+          margin: '20px',
+        }}
+        type="card"
+        activeKey={activeKey}
+        collapsible
+        onChange={(e) => {
+          setActiveKey(e)
+        }}
+      >
+        {[...Array(10).keys()].map(i => (
+          <TabPane tab={`Tab-${i}`} itemKey={`tab-${i}`} key={i}>content of tab {i}</TabPane>
+        ))}
+      </Tabs>
+      <Button onClick={() => { setActiveKey('tab-0') }}>
+        To Tab-0
+      </Button>
+      <Button onClick={() => { setActiveKey('tab-7') }}>
+        To Tab-7
+      </Button>
+    </div>
+  );
+}
+
+Fix2239.story = {
+  name: 'Fix 2239',
+};