1
0
Эх сурвалжийг харах

fix: tabs add scrollActiveTabItemIntoView to componentDidMount (#2787)

YannLynn 6 сар өмнө
parent
commit
44b19ef61f

+ 7 - 0
cypress/e2e/tabs.spec.js

@@ -107,4 +107,11 @@ describe('tabs', () => {
         cy.get('.semi-button').eq(1).trigger('mouseover');
         cy.get('.semi-dropdown-content .semi-dropdown-item').should('not.exist');
     });
+
+    it('activeTab is within the viewport after collapse Tabs did mount', () => {
+        cy.visit('http://127.0.0.1:6006/iframe.html?id=tabs--collapse-scroll-into-view-demo&args=&viewMode=story');
+
+        cy.wait(500);
+        cy.get('.semi-tabs-tab').contains('Tab-9').should('exist').and('be.visible');
+    });
 });

+ 11 - 3
packages/semi-ui/tabs/TabBar.tsx

@@ -58,6 +58,14 @@ class TabBar extends React.Component<TabBarProps, TabBarState> {
     componentDidMount() {
         this.setState({
             uuid: getUuidv4(),
+        }, () => {
+            // Perform the scroll in the setState callback to ensure the uuid is updated to the DOM
+            if (this.props.collapsible) {
+                // Add a small delay to ensure the DOM is fully rendered
+                requestAnimationFrame(() => {
+                    this.scrollActiveTabItemIntoView();
+                });
+            }
         });
     }
 
@@ -227,7 +235,7 @@ class TabBar extends React.Component<TabBarProps, TabBarState> {
         const icon = index === 0 ? <IconChevronLeft/> : <IconChevronRight/>;
         const overflowNode = this.renderCollapse(item, icon, pos);
         if (this.props.renderArrow) {
-            return this.props.renderArrow(item, pos, ()=>this.handleArrowClick(item, pos), overflowNode);
+            return this.props.renderArrow(item, pos, () => this.handleArrowClick(item, pos), overflowNode);
         }
         return overflowNode;
     });
@@ -248,9 +256,9 @@ class TabBar extends React.Component<TabBarProps, TabBarState> {
                 renderMode="scroll"
                 className={`${cssClasses.TABS_BAR}-overflow-list`}
                 visibleItemRenderer={this.renderTabItem as any}
-                onVisibleStateChange={(visibleMap)=>{
+                onVisibleStateChange={(visibleMap) => {
                     const visibleMapWithItemKey: Map<string, boolean> = new Map();
-                    visibleMap.forEach((v, k )=>{
+                    visibleMap.forEach((v, k ) => {
                         visibleMapWithItemKey.set(this._getItemKeyByBarItemKey(k), v);
                     });
                     this.props.onVisibleTabsChange?.(visibleMapWithItemKey);

+ 32 - 0
packages/semi-ui/tabs/_story/tabs.stories.jsx

@@ -1156,3 +1156,35 @@ export const DynamicShowArrow = () => {
       </Tabs>
   );
 };
+
+export const CollapseScrollIntoViewDemo = () => {
+  const [activeKey, setActiveKey] = useState('Tab-9');
+  return (
+    <div>
+      <h4>need to scroll into view</h4>
+      <Tabs
+        style={{ width: 250, margin: '20px' }}
+        type="card"
+        collapsible
+        activeKey={activeKey}
+        onChange={(e) => {
+          setActiveKey(e)
+        }}
+      >
+        {[...Array(10).keys()].map(i => (
+          <TabPane tab={`Tab-${i}`} itemKey={`Tab-${i}`} key={i}>content of tab {i}</TabPane>
+        ))}
+      </Tabs>
+      <h4>No need to scroll into view</h4>
+      <Tabs
+        style={{ width: 250, margin: '20px' }}
+        type="card"
+        collapsible
+      >
+        {[...Array(10).keys()].map(i => (
+          <TabPane tab={`Tab-normal-${i}`} itemKey={`Tab-normal-${i}`} key={i}>content of tab {i}</TabPane>
+        ))}
+      </Tabs>
+    </div>
+  )
+}