Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | 27x | import { cloneElement, useEffect, useRef, useState } from 'react';
import isEqual from 'lodash/isEqual';
import { useResizeDetector } from 'react-resize-detector';
import { debounce } from 'lodash';
const useResponsiveButtonGroupSizing = ({
id,
buttons = [],
}) => {
const eventString = 'responsive-button-group-loaded' + (id ? `-${id}` : '');
const loadedEvent = new Event(eventString);
const isMounted = useRef(false);
useEffect(() => {
isMounted.current = true;
return () => {
isMounted.current = false;
};
}, []);
// Set up size measuring to be able to do fullWidth if and only if the button is too small for the container.
// This way when the button is too _large_ for the container, we can measure it properly
const { ref: containerRef, width: containerWidth } = useResizeDetector();
const [cachedSizeArray, setCachedSizeArray] = useState([]);
const [sizeArray, setSizeArray] = useState([]);
// We also need to set up a ref for each of the buttons
// to measure the size of each one, we can then use that for choosing where to break later.
const refArray = buttons.map((_button, index) => {
return (node) => {
if (node !== null) {
const newSizeArray = sizeArray.slice(0, index)
.concat([node?.clientWidth ?? 0])
.concat(sizeArray.slice(index + 1));
if (!isEqual(sizeArray, newSizeArray)) {
setSizeArray(newSizeArray);
}
}
};
});
const [ready, setReady] = useState(false);
// eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(debounce(() => {
if (isMounted.current) {
if (!cachedSizeArray?.length && sizeArray?.length) {
setCachedSizeArray(sizeArray);
setReady(true);
document.dispatchEvent(loadedEvent);
}
}
}, 150), [cachedSizeArray, sizeArray]);
const returnButtons = buttons?.map((button, index) => {
return cloneElement(button, { ref: refArray?.[index] });
});
return {
buttons: returnButtons,
cachedSizeArray,
containerRef,
containerWidth,
ready,
sizeArray
};
};
export default useResponsiveButtonGroupSizing;
|