Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Remove react resize detector #2912

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion packages/cloud-cognitive/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@
"immutability-helper": "^3.1.1",
"react-dnd": "^15.1.2",
"react-dnd-html5-backend": "^15.1.3",
"react-resize-detector": "^7.1.2",
"react-table": "^7.8.0",
"react-window": "^1.8.7"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

// Import portions of React that are needed.
import React, { useState, useRef, useEffect } from 'react';
import { useResizeDetector } from 'react-resize-detector';
import { useResizeObserver } from '../../global/js/hooks/useResizeObserver';

// Other standard imports.
import PropTypes from 'prop-types';
Expand Down Expand Up @@ -88,7 +88,7 @@ export let AboutModal = React.forwardRef(
}, [bodyRef]);

// Detect resize of the ModalBody to recalculate whether scrolling is enabled
useResizeDetector({ onResize: handleResize, targetRef: bodyRef });
useResizeObserver(bodyRef, { callback: handleResize });

return (
<ComposedModal
Expand Down
32 changes: 11 additions & 21 deletions packages/cloud-cognitive/src/components/ActionBar/ActionBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import React, { useEffect, useState, useRef } from 'react';
import PropTypes from 'prop-types';
import cx from 'classnames';
import { pkg } from '../../settings';
import { useResizeDetector } from 'react-resize-detector';
import { useResizeObserver } from '../../global/js/hooks/useResizeObserver';

// Carbon and package components we use.
import { Button } from '@carbon/react';
Expand Down Expand Up @@ -56,6 +56,9 @@ export let ActionBar = React.forwardRef(
const sizingRef = useRef(null);
const sizes = useRef({});

const backupRef = useRef();
const localRef = ref || backupRef;

// create hidden sizing items
useEffect(() => {
// Hidden action bar and items used to calculate sizes
Expand Down Expand Up @@ -187,33 +190,20 @@ export let ActionBar = React.forwardRef(
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [maxVisible, hiddenSizingItems]);

/* istanbul ignore next */ // not sure how to fake window resize
// /* istanbul ignore next */ // not sure how to fake window resize
const handleResize = () => {
// width is the space available for all action bar items horizontally
// the action bar items are squares so the height should be one item wide
/* istanbul ignore next */ // not sure how to fake window resize
checkFullyVisibleItems();
};

/* istanbul ignore next */ // not sure how to fake window resize
const handleActionBarItemsResize = () => {
// when the hidden sizing items change size
/* istanbul ignore next */ // not sure how to fake window resize
/* istanbul ignore next */
// not sure how to fake window resize
checkFullyVisibleItems();
};

useResizeDetector({
onResize: handleActionBarItemsResize,
targetRef: sizingRef,
});

const { ref: outerRef } = useResizeDetector({
onResize: handleResize,
targetRef: ref,
});
// // resize of the items
useResizeObserver(sizingRef, { callback: handleResize });
useResizeObserver(localRef, { callback: handleResize });

return (
<div {...rest} className={cx([blockClass, className])} ref={outerRef}>
<div {...rest} className={cx([blockClass, className])} ref={localRef}>
{hiddenSizingItems}

<div
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import React, { useState, useEffect, useRef } from 'react';
// Other standard imports.
import PropTypes from 'prop-types';
import cx from 'classnames';
import { useResizeDetector } from 'react-resize-detector';
import { useResizeObserver } from '../../global/js/hooks/useResizeObserver';

// Carbon and package components we use.
import {
Expand Down Expand Up @@ -268,27 +268,16 @@ export let BreadcrumbWithOverflow = ({
checkFullyVisibleBreadcrumbItems();
};

/* istanbul ignore next */ // not sure how to test resize
const handleBreadcrumbItemsResize = () => {
/* istanbul ignore next */ // not sure how to test resize
checkFullyVisibleBreadcrumbItems();
};

let backItem = breadcrumbs[breadcrumbs.length - 1];
/* istanbul ignore if */ // not sure how to test media queries
if (backItem.isCurrentPage) {
backItem = breadcrumbs[breadcrumbs.length - 2];
}

useResizeDetector({
onResize: handleBreadcrumbItemsResize,
targetRef: sizingContainerRef,
});

useResizeDetector({
onResize: handleResize,
targetRef: breadcrumbItemWithOverflow,
});
// container resize
useResizeObserver(sizingContainerRef, { callback: handleResize });
// item resize
useResizeObserver(breadcrumbItemWithOverflow, { callback: handleResize });

return (
<div
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import React, { useEffect, useState, useRef } from 'react';
import PropTypes from 'prop-types';

import cx from 'classnames';
import { useResizeDetector } from 'react-resize-detector';
import { useResizeObserver } from '../../global/js/hooks/useResizeObserver';
import { ButtonSet, Button, usePrefix } from '@carbon/react';
import { ButtonMenu, ButtonMenuItem } from '../ButtonMenu';

Expand Down Expand Up @@ -131,21 +131,13 @@ export const ButtonSetWithOverflow = ({
);
});

useResizeDetector({
onResize: checkFullyVisibleItems,
targetRef: sizingContainerRefSet,
useResizeObserver(sizingContainerRefSet, {
callback: checkFullyVisibleItems,
});

useResizeDetector({
onResize: checkFullyVisibleItems,
targetRef: sizingContainerRefCombo,
});

useResizeDetector({
onResize: checkFullyVisibleItems,
targetRef: spaceAvailableRef,
handleWidth: true,
useResizeObserver(sizingContainerRefCombo, {
callback: checkFullyVisibleItems,
});
useResizeObserver(spaceAvailableRef, { callback: checkFullyVisibleItems });

return (
<div
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
* LICENSE file in the root directory of this source tree.
*/

import React, { useEffect, useState } from 'react';
import React, { useEffect, useRef, useState } from 'react';
import { Add, OverflowMenuVertical } from '@carbon/react/icons';
import {
TableToolbar,
TableBatchActions,
TableBatchAction,
} from '@carbon/react';
import { useResizeDetector } from 'react-resize-detector';
import { useResizeObserver } from '../../../global/js/hooks/useResizeObserver';
import { ButtonMenu, ButtonMenuItem } from '../../ButtonMenu';
import { pkg, carbon } from '../../../settings';
import cx from 'classnames';
Expand Down Expand Up @@ -155,7 +155,8 @@ const DatagridBatchActionsToolbar = (datagridState, width, ref) => {
};

const DatagridToolbar = (datagridState) => {
const { width, ref } = useResizeDetector();
const ref = useRef(null);
const { width } = useResizeObserver(ref);
const { DatagridActions, DatagridBatchActions, batchActions, rowSize } =
datagridState;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { TableBody } from '@carbon/react';
import { pkg } from '../../../settings';
import DatagridHead from './DatagridHead';
import { px } from '@carbon/layout';
import { useResizeDetector } from 'react-resize-detector';
import { useResizeObserver } from '../../../global/js/hooks/useResizeObserver';

const blockClass = `${pkg.prefix}--datagrid`;

Expand Down Expand Up @@ -52,7 +52,7 @@ const DatagridVirtualBody = (datagridState) => {
gridRefElement.style.width = gridRefElement?.clientWidth;
};

useResizeDetector({ onResize: handleVirtualGridResize, targetRef: gridRef });
useResizeObserver(gridRef, { callback: handleVirtualGridResize });

const syncScroll = (e) => {
const virtualBody = e.target;
Expand Down
16 changes: 5 additions & 11 deletions packages/cloud-cognitive/src/components/PageHeader/PageHeader.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import React, { useEffect, useRef, useState } from 'react';
import PropTypes from 'prop-types';
import { spacing10, baseFontSize } from '@carbon/layout';
import cx from 'classnames';
import { useResizeDetector } from 'react-resize-detector';
import { useResizeObserver } from '../../global/js/hooks/useResizeObserver';

import { FlexGrid, Column, Row, Button, Tag } from '@carbon/react';
import { breakpoints } from '@carbon/layout';
Expand Down Expand Up @@ -162,7 +162,7 @@ export let PageHeader = React.forwardRef(
};

/* istanbul ignore next */
const handleResizeActionBarColumn = (width) => {
const handleResizeActionBarColumn = ({ width }) => {
/* don't know how to test resize */
/* istanbul ignore next */
setActionBarColumnWidth(width);
Expand Down Expand Up @@ -448,17 +448,11 @@ export let PageHeader = React.forwardRef(
}
}, [collapseHeader, metrics.headerOffset, metrics.headerTopValue]);

useResizeDetector({
onResize: handleResizeActionBarColumn,
targetRef: sizingContainerRef,
handleWidth: true,
useResizeObserver(sizingContainerRef, {
callback: handleResizeActionBarColumn,
});

useResizeDetector({
onResize: handleResize,
targetRef: headerRef,
handleHeight: true,
});
useResizeObserver(headerRef, { callback: handleResize });

// Determine what form of title to display in the breadcrumb
let breadcrumbItemForTitle = utilGetBreadcrumbItemForTitle(
Expand Down
10 changes: 3 additions & 7 deletions packages/cloud-cognitive/src/components/SidePanel/SidePanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { motion, AnimatePresence } from 'framer-motion';
// Other standard imports.
import PropTypes from 'prop-types';
import cx from 'classnames';
import { useResizeDetector } from 'react-resize-detector';
import { useResizeObserver } from '../../global/js/hooks/useResizeObserver';
import { moderate02 } from '@carbon/motion';

import { getDevtoolsProps } from '../../global/js/utils/devtools';
Expand Down Expand Up @@ -169,7 +169,7 @@ export let SidePanel = React.forwardRef(
}, [labelText, title]);

/* istanbul ignore next */
const handleResize = (width, height) => {
const handleResize = ({ height }) => {
setPanelHeight(height);
const sidePanelOuter = document.querySelector(`#${blockClass}-outer`);
const actionsContainer = getActionsContainerElement();
Expand Down Expand Up @@ -686,11 +686,7 @@ export let SidePanel = React.forwardRef(

const contentRef = ref || sidePanelRef;

useResizeDetector({
handleHeight: true,
onResize: handleResize,
targetRef: contentRef,
});
useResizeObserver(contentRef, { callback: handleResize });

return (
<AnimatePresence>
Expand Down
12 changes: 3 additions & 9 deletions packages/cloud-cognitive/src/components/TagSet/TagSet.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import cx from 'classnames';
import { TagSetOverflow } from './TagSetOverflow';
import { TagSetModal } from './TagSetModal';
import { Tag } from '@carbon/react';
import { useResizeDetector } from 'react-resize-detector';
import { useResizeObserver } from '../../global/js/hooks/useResizeObserver';

import { getDevtoolsProps } from '../../global/js/utils/devtools';
import { prepareProps, isRequiredIf } from '../../global/js/utils/props-helper';
Expand Down Expand Up @@ -217,15 +217,9 @@ export let TagSet = React.forwardRef(
setShowAllModalOpen(false);
};

useResizeDetector({
onResize: handleSizerTagsResize,
targetRef: sizingContainerRef,
});
useResizeObserver(sizingContainerRef, { callback: handleSizerTagsResize });

useResizeDetector({
onResize: handleResize,
targetRef: tagSetRef,
});
useResizeObserver(tagSetRef, { callback: handleResize });

return (
<div
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// Import portions of React that are needed.
import React, { useEffect, useState, useRef } from 'react';
import { createPortal } from 'react-dom';
import { useResizeDetector } from 'react-resize-detector';
import { useResizeObserver } from '../../global/js/hooks/useResizeObserver';

// Other standard imports.
import PropTypes from 'prop-types';
Expand Down Expand Up @@ -102,8 +102,9 @@ export const TearsheetShell = React.forwardRef(
}, [portalTargetIn]);

const localRef = useRef();
const resizer = useRef(null);
const modalRef = ref || localRef;
const { width, ref: resizer } = useResizeDetector({ handleHeight: false });
const { width } = useResizeObserver(resizer);

const wide = size === 'wide';

Expand Down
73 changes: 73 additions & 0 deletions packages/cloud-cognitive/src/global/js/hooks/useResizeObserver.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/**
* Copyright IBM Corp. 2023, 2023
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/
import { useRef, useState, useLayoutEffect } from 'react';

export const useResizeObserver = (
ref,
options = { callback: null, throttleInterval: 0 }
) => {
const { callback, throttleInterval } = options;
const [width, setWidth] = useState(0);
const [height, setHeight] = useState(0);
const throttleTimeout = useRef(null);
const entriesToHandle = useRef(null);

useLayoutEffect(() => {
if (!ref?.current) {
return;
}

const doCallbacks = () => {
if (!ref?.current || !Array.isArray(entriesToHandle?.current)) {
return;
}

const entry = entriesToHandle.current[0];

setWidth(entry.contentRect.width);
setHeight(entry.contentRect.height);

throttleTimeout.current = null;

callback && callback(entry.contentRect);
};

let observer = new ResizeObserver((entries) => {
// always update entriesToHandle
entriesToHandle.current = entries;

if (throttleInterval) {
// if a throttleInterval check for running timeout
if (throttleTimeout.current === null) {
// no live timeout set entries to handle and move on

// set up throttle
throttleTimeout.current = setTimeout(() => {
// do callbacks
doCallbacks();
// reset throttle
throttleTimeout.current = null;
}, throttleInterval);
}
} else {
// no throttle do callbacks every time
doCallbacks();
}
});

// observe all refs passed
observer.observe(ref.current);

return () => {
observer.disconnect();
observer = null;
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [ref, options]);

return { width, height };
};
Loading