Skip to content
Closed
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
65 changes: 29 additions & 36 deletions packages/block-editor/src/components/block-pattern-setup/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,7 @@ const BlockPatternSetup = ( {
const [ showBlank, setShowBlank ] = useState( false );
const { replaceBlock } = useDispatch( blockEditorStore );
const patterns = usePatternsSetup( clientId, blockName, filterPatternsFn );
const [
contentResizeListener,
{ height: contentHeight },
] = useResizeObserver();
const { height: contentHeight, ref } = useResizeObserver( {} );

if ( ! patterns?.length || showBlank ) {
return startBlankComponent;
Expand All @@ -174,38 +171,34 @@ const BlockPatternSetup = ( {
}
: undefined;
return (
<>
{ contentResizeListener }
<div
className={ `block-editor-block-pattern-setup view-mode-${ viewMode }` }
>
<SetupContent
viewMode={ viewMode }
activeSlide={ activeSlide }
patterns={ patterns }
onBlockPatternSelect={ onPatternSelectCallback }
height={ contentHeight - 2 * 60 }
/>
<SetupToolbar
viewMode={ viewMode }
setViewMode={ setViewMode }
activeSlide={ activeSlide }
totalSlides={ patterns.length }
handleNext={ () => {
setActiveSlide( ( active ) => active + 1 );
} }
handlePrevious={ () => {
setActiveSlide( ( active ) => active - 1 );
} }
onBlockPatternSelect={ () => {
onPatternSelectCallback(
patterns[ activeSlide ].blocks
);
} }
onStartBlank={ onStartBlank }
/>
</div>
</>
<div
ref={ ref }
className={ `block-editor-block-pattern-setup view-mode-${ viewMode }` }
>
<SetupContent
viewMode={ viewMode }
activeSlide={ activeSlide }
patterns={ patterns }
onBlockPatternSelect={ onPatternSelectCallback }
height={ contentHeight - 2 * 60 }
/>
<SetupToolbar
viewMode={ viewMode }
setViewMode={ setViewMode }
activeSlide={ activeSlide }
totalSlides={ patterns.length }
handleNext={ () => {
setActiveSlide( ( active ) => active + 1 );
} }
handlePrevious={ () => {
setActiveSlide( ( active ) => active - 1 );
} }
onBlockPatternSelect={ () => {
onPatternSelectCallback( patterns[ activeSlide ].blocks );
} }
onStartBlank={ onStartBlank }
/>
</div>
);
};

Expand Down
13 changes: 7 additions & 6 deletions packages/block-editor/src/components/block-preview/auto.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,9 @@ function AutoBlockPreview( {
__experimentalPadding,
__experimentalMinHeight,
} ) {
const [
containerResizeListener,
{ width: containerWidth },
] = useResizeObserver();
const { width: containerWidth, ref: containerRef } = useResizeObserver(
{}
);
const [
contentResizeListener,
{ height: contentHeight },
Expand Down Expand Up @@ -61,8 +60,10 @@ function AutoBlockPreview( {
const scale = containerWidth / viewportWidth;

return (
<div className="block-editor-block-preview__container">
{ containerResizeListener }
<div
className="block-editor-block-preview__container"
ref={ containerRef }
>
<Disabled
className="block-editor-block-preview__content"
style={ {
Expand Down
5 changes: 2 additions & 3 deletions packages/components/src/placeholder/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ function Placeholder( {
isColumnLayout,
...additionalProps
} ) {
const [ resizeListener, { width } ] = useResizeObserver();
const { width, ref } = useResizeObserver( {} );

// Since `useResizeObserver` will report a width of `null` until after the
// first render, avoid applying any modifier classes until width is known.
Expand All @@ -61,8 +61,7 @@ function Placeholder( {
'is-column-layout': isColumnLayout,
} );
return (
<div { ...additionalProps } className={ classes }>
{ resizeListener }
<div ref={ ref } { ...additionalProps } className={ classes }>
{ notices }
{ preview && (
<div className="components-placeholder__preview">
Expand Down
12 changes: 9 additions & 3 deletions packages/components/src/resizable-box/resize-tooltip/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type { Ref, ForwardedRef } from 'react';
* WordPress dependencies
*/
import { forwardRef } from '@wordpress/element';
import { useMergeRefs } from '@wordpress/compose';

/**
* Internal dependencies
Expand Down Expand Up @@ -45,21 +46,26 @@ function ResizeTooltip(
}: ResizeTooltipProps,
ref: ForwardedRef< HTMLDivElement >
): JSX.Element | null {
const { label, resizeListener } = useResizeLabel( {
const { label, resizableRef } = useResizeLabel( {
axis,
fadeTimeout,
onResize,
showPx,
position,
} );
const mergedRef = useMergeRefs( [ ref, resizableRef ] );

if ( ! isVisible ) return null;

const classes = classnames( 'components-resize-tooltip', className );

return (
<Root aria-hidden="true" className={ classes } ref={ ref } { ...props }>
{ resizeListener }
<Root
aria-hidden="true"
className={ classes }
ref={ mergedRef }
{ ...props }
>
<Label
aria-hidden={ props[ 'aria-hidden' ] }
label={ label }
Expand Down
10 changes: 5 additions & 5 deletions packages/components/src/resizable-box/resize-tooltip/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* External dependencies
*/
import { noop } from 'lodash';
import type { RefCallback } from 'react';

/**
* WordPress dependencies
Expand All @@ -23,8 +24,8 @@ export type Position = typeof POSITIONS[ keyof typeof POSITIONS ];
interface UseResizeLabelProps {
/** The label value. */
label?: string;
/** Element to be rendered for resize listening events. */
resizeListener: JSX.Element;
/** Element ref to listen to resize listening events. */
resizableRef: RefCallback< HTMLDivElement >;
}

interface UseResizeLabelArgs {
Expand Down Expand Up @@ -59,7 +60,7 @@ export function useResizeLabel( {
* The width/height values derive from this special useResizeObserver hook.
* This custom hook uses the ResizeObserver API to listen for resize events.
*/
const [ resizeListener, sizes ] = useResizeObserver();
const { width, height, ref: resizableRef } = useResizeObserver( {} );

/*
* Indicates if the x/y axis is preferred.
Expand All @@ -79,7 +80,6 @@ export function useResizeLabel( {
* Cached dimension values to check for width/height updates from the
* sizes property from useResizeAware()
*/
const { width, height } = sizes;
const heightRef = useRef( height );
const widthRef = useRef( width );

Expand Down Expand Up @@ -162,7 +162,7 @@ export function useResizeLabel( {

return {
label,
resizeListener,
resizableRef,
};
}

Expand Down
8 changes: 2 additions & 6 deletions packages/components/src/responsive-wrapper/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,7 @@ function ResponsiveWrapper( {
children,
isInline = false,
} ) {
const [
containerResizeListener,
{ width: containerWidth },
] = useResizeObserver();
const { ref, width: containerWidth } = useResizeObserver( {} );
if ( Children.count( children ) !== 1 ) {
return null;
}
Expand All @@ -30,8 +27,7 @@ function ResponsiveWrapper( {
};
const TagName = isInline ? 'span' : 'div';
return (
<TagName className="components-responsive-wrapper">
{ containerResizeListener }
<TagName ref={ ref } className="components-responsive-wrapper">
<TagName style={ imageStyle } />
{ cloneElement( children, {
className: classnames(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ function ToggleGroupControl(
} = useContextSystem( props, 'ToggleGroupControl' );
const cx = useCx();
const containerRef = useRef();
const [ resizeListener, sizes ] = useResizeObserver();
const { width, ref: resizeRef } = useResizeObserver( {} );
const baseId = useInstanceId(
ToggleGroupControl,
'toggle-group-control'
Expand Down Expand Up @@ -108,13 +108,16 @@ function ToggleGroupControl(
as={ View }
className={ classes }
{ ...otherProps }
ref={ useMergeRefs( [ containerRef, forwardedRef ] ) }
ref={ useMergeRefs( [
containerRef,
forwardedRef,
resizeRef,
] ) }
>
{ resizeListener }
<ToggleGroupControlBackdrop
{ ...radio }
containerRef={ containerRef }
containerWidth={ sizes.width }
containerWidth={ width }
isAdaptiveWidth={ isAdaptiveWidth }
/>
{ children }
Expand Down
13 changes: 6 additions & 7 deletions packages/compose/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -453,17 +453,16 @@ _Usage_

```js
const App = () => {
const [ resizeListener, sizes ] = useResizeObserver();
const { width, height, ref } = useResizeObserver( {} );

return (
<div>
{ resizeListener }
Your content here
</div>
);
return <div ref={ ref }>Your content here</div>;
};
```

_Parameters_

- _opts_ `Object`: - Options for the hook.

### useThrottle

Throttles a function with Lodash's `throttle`. A new throttled function will
Expand Down
37 changes: 23 additions & 14 deletions packages/compose/src/hooks/use-resize-observer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ import type { WPElement } from '@wordpress/element';

type SubscriberCleanup = () => void;
type SubscriberResponse = SubscriberCleanup | void;
type UseResizeObserverConfig< T > = {
ref?: RefObject< T > | T | null | undefined;
onResize?: ResizeHandler;
box?: ResizeObserverBoxOptions;
round?: RoundingFunction;
};

// This of course could've been more streamlined with internal state instead of
// refs, but then host hooks / components could not opt out of renders.
Expand Down Expand Up @@ -169,12 +175,7 @@ const extractSize = (
type RoundingFunction = ( n: number ) => number;

function useResizeObserver< T extends HTMLElement >(
opts: {
ref?: RefObject< T > | T | null | undefined;
onResize?: ResizeHandler;
box?: ResizeObserverBoxOptions;
round?: RoundingFunction;
} = {}
opts: UseResizeObserverConfig< T > = {}
): HookResponse< T > {
// Saving the callback as a ref. With this, I don't need to put onResize in the
// effect dep array, and just passing in an anonymous function without memoising
Expand Down Expand Up @@ -322,25 +323,33 @@ function useResizeObserver< T extends HTMLElement >(
*
* ```js
* const App = () => {
* const [ resizeListener, sizes ] = useResizeObserver();
* const { width, height, ref } = useResizeObserver( {} );
*
* return (
* <div>
* { resizeListener }
* <div ref={ ref }>
* Your content here
* </div>
* );
* };
* ```
*
* @param {Object} opts - Options for the hook.
*/
export default function useResizeAware(): [
WPElement,
{ width: number | null; height: number | null }
] {
const { ref, width, height } = useResizeObserver();
export default function useResizeAware< T extends HTMLDivElement >(
opts?: UseResizeObserverConfig< T >
):
| [ WPElement, { width: number | null; height: number | null } ]
| HookResponse< T > {
const ret = useResizeObserver( opts );
const { ref, width, height } = ret;
const sizes = useMemo( () => {
return { width: width ?? null, height: height ?? null };
}, [ width, height ] );

if ( opts ) {
return ret;
}

const resizeListener = (
<div
style={ {
Expand Down