Skip to content

Commit

Permalink
Address feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
ellatrix committed Jan 23, 2023
1 parent 2850793 commit fc91518
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -237,9 +237,8 @@ function BlockPopoverInbetween( {
props.className
) }
resize={ false }
overlay={ true }
flip={ false }
placement="bottom-start"
placement="overlay"
variant="unstyled"
>
<div className="block-editor-block-popover__inbetween-container">
Expand Down
9 changes: 7 additions & 2 deletions packages/block-editor/src/components/iframe/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,11 @@ function Iframe( {
return '<!doctype html>' + renderToString( styleAssets );
}, [] );

// We need to counter the margin created by scaling the iframe. If the scale
// is e.g. 0.45, then the top + bottom margin is 0.55 (1 - scale). Just the
// top or bottom margin is 0.55 / 2 ((1 - scale) / 2).
const marginFromScaling = ( contentHeight * ( 1 - scale ) ) / 2;

return (
<>
{ tabIndex >= 0 && before }
Expand All @@ -249,10 +254,10 @@ function Iframe( {
...props.style,
height: expand ? contentHeight : props.style?.height,
marginTop: scale
? -( ( contentHeight * ( 1 - scale ) ) / 2 ) + frameSize
? -marginFromScaling + frameSize
: props.style?.marginTop,
marginBottom: scale
? -( ( contentHeight * ( 1 - scale ) ) / 2 ) + frameSize
? -marginFromScaling + frameSize
: props.style?.marginBottom,
transform: scale
? `scale( ${ scale } )`
Expand Down
34 changes: 6 additions & 28 deletions packages/components/src/popover/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ import type {
PopoverAnchorRefTopBottom,
} from './types';
import { limitShift as customLimitShift } from './limit-shift';
import { overlayMiddlewares } from './overlay-middlewares';

/**
* Name of slot in which popover should fill.
Expand Down Expand Up @@ -183,7 +184,6 @@ const UnforwardedPopover = (
resize = true,
shift = false,
variant,
overlay = false,

// Deprecated props
__unstableForcePosition,
Expand Down Expand Up @@ -271,16 +271,9 @@ const UnforwardedPopover = (
const frameOffsetRef = useRef( getFrameOffset( referenceOwnerDocument ) );

const middleware = [
...( placementProp === 'overlay' ? overlayMiddlewares() : [] ),
// Custom middleware which adjusts the popover's position by taking into
// account the offset of the anchor's iframe (if any) compared to the page.
overlay
? {
name: 'overlay',
fn( { rects }: MiddlewareArguments ) {
return rects.reference;
},
}
: undefined,
{
name: 'frameOffset',
fn( { x, y }: MiddlewareArguments ) {
Expand Down Expand Up @@ -321,24 +314,6 @@ const UnforwardedPopover = (
},
} )
: undefined,
overlay
? size( {
apply( { rects } ) {
const { firstElementChild } =
refs.floating.current ?? {};

// Only HTMLElement instances have the `style` property.
if ( ! ( firstElementChild instanceof HTMLElement ) )
return;

// Reduce the height of the popover to the available space.
Object.assign( firstElementChild.style, {
width: `${ rects.reference.width }px`,
height: `${ rects.reference.height }px`,
} );
},
} )
: undefined,
shift
? shiftMiddleware( {
crossAxis: true,
Expand Down Expand Up @@ -390,7 +365,10 @@ const UnforwardedPopover = (
placement: computedPlacement,
middlewareData: { arrow: arrowData },
} = useFloating( {
placement: normalizedPlacementFromProps,
placement:
( normalizedPlacementFromProps === 'overlay'
? undefined
: normalizedPlacementFromProps ) || 'bottom',
middleware,
whileElementsMounted: ( referenceParam, floatingParam, updateParam ) =>
autoUpdate( referenceParam, floatingParam, updateParam, {
Expand Down
29 changes: 29 additions & 0 deletions packages/components/src/popover/overlay-middlewares.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* External dependencies
*/
import { size, MiddlewareArguments } from '@floating-ui/react-dom';

export function overlayMiddlewares() {
return [
{
name: 'overlay',
fn( { rects }: MiddlewareArguments ) {
return rects.reference;
},
},
size( {
apply( { rects, elements } ) {
const { firstElementChild } = elements.floating ?? {};

// Only HTMLElement instances have the `style` property.
if ( ! ( firstElementChild instanceof HTMLElement ) ) return;

// Reduce the height of the popover to the available space.
Object.assign( firstElementChild.style, {
width: `${ rects.reference.width }px`,
height: `${ rects.reference.height }px`,
} );
},
} ),
];
}
6 changes: 4 additions & 2 deletions packages/components/src/popover/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ type DomRectWithOwnerDocument = DOMRect & {
ownerDocument?: Document;
};

type PopoverPlacement = Placement | 'overlay';

export type AnimatedWrapperProps = {
placement: Placement;
placement: PopoverPlacement;
shouldAnimate?: boolean;
};

Expand Down Expand Up @@ -111,7 +113,7 @@ export type PopoverProps = {
*
* @default 'bottom-start'
*/
placement?: Placement;
placement?: PopoverPlacement;
/**
* Legacy way to specify the popover's position with respect to its anchor.
* _Note: this prop is deprecated. Use the `placement` prop instead._
Expand Down
29 changes: 19 additions & 10 deletions packages/components/src/popover/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ const PLACEMENT_TO_ANIMATION_ORIGIN: Record<
left: { originX: 1, originY: 0.5 }, // open from middle, right
'left-start': { originX: 1, originY: 0 }, // open from top, right
'left-end': { originX: 1, originY: 1 }, // open from bottom, right
overlay: { originX: 0.5, originY: 0.5 }, // open from center, center
};

/**
Expand Down Expand Up @@ -157,13 +158,21 @@ export const getFrameOffset = (
return { x: iframeRect.left, y: iframeRect.top };
};

export const getFrameScale = ( document?: Document ): number => {
export const getFrameScale = (
document?: Document
): {
x: number;
y: number;
} => {
const frameElement = document?.defaultView?.frameElement as HTMLElement;
if ( ! frameElement ) {
return 1;
return { x: 1, y: 1 };
}
const transform = frameElement.style.transform;
return parseFloat( transform.replace( /scale\((\d+\.?\d*)\)/, '$1' ) );
const rect = frameElement.getBoundingClientRect();
return {
x: rect.width / frameElement.offsetWidth,
y: rect.height / frameElement.offsetHeight,
};
};

export const getReferenceOwnerDocument = ( {
Expand Down Expand Up @@ -228,7 +237,7 @@ export const getReferenceElement = ( {
'anchorRef' | 'anchorRect' | 'getAnchorRect' | 'anchor'
> & {
fallbackReferenceElement: Element | null;
scale: number;
scale: { x: number; y: number };
} ): ReferenceType | null => {
let referenceElement = null;

Expand Down Expand Up @@ -290,17 +299,17 @@ export const getReferenceElement = ( {
referenceElement = fallbackReferenceElement.parentElement;
}

if ( referenceElement && scale !== 1 ) {
if ( referenceElement && ( scale.x !== 1 || scale.y !== 1 ) ) {
// If the popover is inside an iframe, the coordinates of the
// reference element need to be scaled to match the iframe's scale.
const rect = referenceElement.getBoundingClientRect();
referenceElement = {
getBoundingClientRect() {
return new window.DOMRect(
rect.x * scale,
rect.y * scale,
rect.width * scale,
rect.height * scale
rect.x * scale.x,
rect.y * scale.y,
rect.width * scale.x,
rect.height * scale.y
);
},
};
Expand Down

0 comments on commit fc91518

Please sign in to comment.