Skip to content

Commit

Permalink
fix(Tabs): handle activation mode scrolling in separate `useIsomorphi…
Browse files Browse the repository at this point in the history
…cEffect`s (#17920)

* docs(Tabs): format comments

* fix(Tabs): add scrollTabIntoView method

* fix(Tabs): handle activation modes in separate `useIsomorphicEffect`s
  • Loading branch information
emyarod authored Nov 6, 2024
1 parent aa67ac9 commit 277de23
Showing 1 changed file with 44 additions and 28 deletions.
72 changes: 44 additions & 28 deletions packages/react/src/components/Tabs/Tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,40 @@ function TabList({
}
}

/**
* Scroll the tab into view if it is not already visible
* @param tab - The tab to scroll into view
* @returns {void}
*/
function scrollTabIntoView(tab) {
if (!isScrollable || !ref.current) {
return;
}
if (tab) {
// The width of the "scroll buttons"
const { width: tabWidth } = tab.getBoundingClientRect();

// The start and end position of the selected tab
const start = tab.offsetLeft;
const end = tab.offsetLeft + tabWidth;

// The start and end of the visible area for the tabs
const visibleStart = ref.current.scrollLeft + buttonWidth;
const visibleEnd =
ref.current.scrollLeft + ref.current.clientWidth - buttonWidth;

// The beginning of the tab is clipped and not visible
if (start < visibleStart) {
setScrollLeft(start - buttonWidth);
}

// The end of the tab is clipped and not visible
if (end > visibleEnd) {
setScrollLeft(end + buttonWidth - ref.current.clientWidth);
}
}
}

useEffectOnce(() => {
const tab = tabs.current[selectedIndex];
if (scrollIntoView && tab) {
Expand Down Expand Up @@ -606,13 +640,13 @@ function TabList({

useIsomorphicEffect(() => {
if (ref.current) {
//adding 1 in calculation for firefox support
// adding 1 in calculation for firefox support
setIsScrollable(ref.current.scrollWidth > ref.current.clientWidth + 1);
}

function handler() {
if (ref.current) {
//adding 1 in calculation for firefox support
// adding 1 in calculation for firefox support
setIsScrollable(ref.current.scrollWidth > ref.current.clientWidth + 1);
}
}
Expand All @@ -632,39 +666,21 @@ function TabList({
}
}, [scrollLeft]);

// scroll manual tabs when active index changes (focus outline movement)
useIsomorphicEffect(() => {
if (!isScrollable || !ref.current) {
return;
}

const tab =
activation === 'manual'
? tabs.current[activeIndex]
: tabs.current[selectedIndex];
if (tab) {
// The width of the "scroll buttons"

// The start and end position of the selected tab
const { width: tabWidth } = tab.getBoundingClientRect();
const start = tab.offsetLeft;
const end = tab.offsetLeft + tabWidth;

// The start and end of the visible area for the tabs
const visibleStart = ref.current.scrollLeft + buttonWidth;
const visibleEnd =
ref.current.scrollLeft + ref.current.clientWidth - buttonWidth;

// The beginning of the tab is clipped and not visible
if (start < visibleStart) {
setScrollLeft(start - buttonWidth);
}
scrollTabIntoView(tab);
}, [activation, activeIndex]);

// The end of the tab is clipped and not visible
if (end > visibleEnd) {
setScrollLeft(end + buttonWidth - ref.current.clientWidth);
}
}
}, [activation, activeIndex, selectedIndex, isScrollable, children]);
// scroll tabs when selected index changes
useIsomorphicEffect(() => {
const tab = tabs.current[selectedIndex];
scrollTabIntoView(tab);
}, [selectedIndex, isScrollable, children]);

usePressable(previousButton, {
onPress({ longPress }) {
Expand Down

0 comments on commit 277de23

Please sign in to comment.