fixed the issue by removing the useRect, and putting in a resize event, going to try and make the code cleaner by removing all that logic and putting it in a hook.
This commit is contained in:
Asad Umar 2022-01-28 20:03:06 +05:00 committed by Thomas Zarebczan
parent fd1ee4f43c
commit e4abc7ef41
2 changed files with 50 additions and 6 deletions

View file

@ -8,7 +8,6 @@ import {
TabPanel as ReachTabPanel, TabPanel as ReachTabPanel,
} from '@reach/tabs'; } from '@reach/tabs';
import classnames from 'classnames'; import classnames from 'classnames';
import { useRect } from '@reach/rect';
// Tabs are a compound component // Tabs are a compound component
// The components are used individually, but they will still interact and share state // The components are used individually, but they will still interact and share state
@ -33,7 +32,7 @@ import { useRect } from '@reach/rect';
type TabsProps = { type TabsProps = {
index?: number, index?: number,
onChange?: number => void, onChange?: (number) => void,
children: Array<React$Node>, children: Array<React$Node>,
}; };
@ -43,10 +42,25 @@ const AnimatedContext = createContext<any>();
function Tabs(props: TabsProps) { function Tabs(props: TabsProps) {
// Store the position of the selected Tab so we can animate the "active" bar to its position // Store the position of the selected Tab so we can animate the "active" bar to its position
const [selectedRect, setSelectedRect] = useState(null); const [selectedRect, setSelectedRect] = useState(null);
const [tabsRect, setTabsRect] = React.useState();
// Create a ref of the parent element so we can measure the relative "left" for the bar for the child Tab's // Create a ref of the parent element so we can measure the relative "left" for the bar for the child Tab's
const tabsRef = useRef(); // Don't observe as its going to re-render when the window size changes anyway
const tabsRect = useRect(tabsRef); const tabsRef = useRef<Element | void | null>();
function changeWindowSize() {
if (tabsRef.current) {
setTabsRect(tabsRef.current.getBoundingClientRect() || undefined);
}
}
React.useEffect(() => {
window.addEventListener('resize', changeWindowSize);
return () => {
window.removeEventListener('resize', changeWindowSize);
};
}, []);
const tabLabels = props.children[0]; const tabLabels = props.children[0];
const tabContent = props.children[1]; const tabContent = props.children[1];
@ -91,10 +105,25 @@ function Tab(props: TabProps) {
// @reach/tabs provides an `isSelected` prop // @reach/tabs provides an `isSelected` prop
// We could also useContext to read it manually // We could also useContext to read it manually
const { isSelected } = props; const { isSelected } = props;
const [rect, setRect] = React.useState();
function changeWindowSize() {
if (ref.current) {
setRect(ref.current.getBoundingClientRect() || undefined);
}
}
React.useEffect(() => {
window.addEventListener('resize', changeWindowSize);
return () => {
window.removeEventListener('resize', changeWindowSize);
};
}, []);
// Each tab measures itself // Each tab measures itself
const ref = useRef(); // Don't observe as its going to re-render when the window size changes anyway
const rect = useRect(ref, isSelected); const ref = useRef<Element | void | null>();
// and calls up to the parent when it becomes selected // and calls up to the parent when it becomes selected
// we useLayoutEffect to avoid flicker // we useLayoutEffect to avoid flicker

View file

@ -0,0 +1,15 @@
import { useEffect } from 'react';
export function useOnResize(cb) {
useEffect(() => {
function handleResize() {
cb();
}
window.addEventListener('resize', handleResize);
handleResize();
return () => window.removeEventListener('resize', handleResize);
}, [cb]);
}