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

Components: Avoid wrapping div for Slot #7231

Closed
wants to merge 2 commits into from
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
Original file line number Diff line number Diff line change
@@ -1,57 +1,53 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`PluginPostPublishPanel renders fill properly 1`] = `
<div
role="presentation"
<PanelBody
className="my-plugin-post-publish-panel"
initialOpen={true}
key="1---0/.0"
title="My panel title"
>
<PanelBody
className="my-plugin-post-publish-panel"
initialOpen={true}
key="1---0/.0"
title="My panel title"
<div
className="components-panel__body my-plugin-post-publish-panel is-opened"
>
<div
className="components-panel__body my-plugin-post-publish-panel is-opened"
<h2
className="components-panel__body-title"
>
<h2
className="components-panel__body-title"
<Button
aria-expanded={true}
className="components-panel__body-toggle"
onClick={[Function]}
>
<Button
<button
aria-expanded={true}
className="components-panel__body-toggle"
className="components-button components-panel__body-toggle"
onClick={[Function]}
type="button"
>
<button
aria-expanded={true}
className="components-button components-panel__body-toggle"
onClick={[Function]}
type="button"
<svg
className="components-panel__arrow"
height="24px"
viewBox="0 0 24 24"
width="24px"
xmlns="http://www.w3.org/2000/svg"
>
<svg
className="components-panel__arrow"
height="24px"
viewBox="0 0 24 24"
width="24px"
xmlns="http://www.w3.org/2000/svg"
>
<g>
<path
d="M0,0h24v24H0V0z"
fill="none"
/>
</g>
<g>
<path
d="M12,8l-6,6l1.41,1.41L12,10.83l4.59,4.58L18,14L12,8z"
/>
</g>
</svg>
My panel title
</button>
</Button>
</h2>
My panel content
</div>
</PanelBody>
</div>
<g>
<path
d="M0,0h24v24H0V0z"
fill="none"
/>
</g>
<g>
<path
d="M12,8l-6,6l1.41,1.41L12,10.83l4.59,4.58L18,14L12,8z"
/>
</g>
</svg>
My panel title
</button>
</Button>
</h2>
My panel content
</div>
</PanelBody>
`;
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`PluginPostStatusInfo renders fill properly 1`] = `
<div
role="presentation"
<PanelRow
className="my-plugin-post-status-info"
key="1---0/.0"
>
<PanelRow
className="my-plugin-post-status-info"
key="1---0/.0"
<div
className="components-panel__row my-plugin-post-status-info"
>
<div
className="components-panel__row my-plugin-post-status-info"
>
My plugin post status info
</div>
</PanelRow>
</div>
My plugin post status info
</div>
</PanelRow>
`;
Original file line number Diff line number Diff line change
@@ -1,57 +1,53 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`PluginPrePublishPanel renders fill properly 1`] = `
<div
role="presentation"
<PanelBody
className="my-plugin-pre-publish-panel"
initialOpen={true}
key="1---0/.0"
title="My panel title"
>
<PanelBody
className="my-plugin-pre-publish-panel"
initialOpen={true}
key="1---0/.0"
title="My panel title"
<div
className="components-panel__body my-plugin-pre-publish-panel is-opened"
>
<div
className="components-panel__body my-plugin-pre-publish-panel is-opened"
<h2
className="components-panel__body-title"
>
<h2
className="components-panel__body-title"
<Button
aria-expanded={true}
className="components-panel__body-toggle"
onClick={[Function]}
>
<Button
<button
aria-expanded={true}
className="components-panel__body-toggle"
className="components-button components-panel__body-toggle"
onClick={[Function]}
type="button"
>
<button
aria-expanded={true}
className="components-button components-panel__body-toggle"
onClick={[Function]}
type="button"
<svg
className="components-panel__arrow"
height="24px"
viewBox="0 0 24 24"
width="24px"
xmlns="http://www.w3.org/2000/svg"
>
<svg
className="components-panel__arrow"
height="24px"
viewBox="0 0 24 24"
width="24px"
xmlns="http://www.w3.org/2000/svg"
>
<g>
<path
d="M0,0h24v24H0V0z"
fill="none"
/>
</g>
<g>
<path
d="M12,8l-6,6l1.41,1.41L12,10.83l4.59,4.58L18,14L12,8z"
/>
</g>
</svg>
My panel title
</button>
</Button>
</h2>
My panel content
</div>
</PanelBody>
</div>
<g>
<path
d="M0,0h24v24H0V0z"
fill="none"
/>
</g>
<g>
<path
d="M12,8l-6,6l1.41,1.41L12,10.83l4.59,4.58L18,14L12,8z"
/>
</g>
</svg>
My panel title
</button>
</Button>
</h2>
My panel content
</div>
</PanelBody>
`;
32 changes: 30 additions & 2 deletions packages/components/src/slot-fill/fill.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ class Fill extends Component {
const { registerFill = noop } = this.context;

registerFill( this.props.name, this );

this.checkIfSlotAvailable();
}

componentWillUpdate() {
Expand Down Expand Up @@ -50,6 +52,23 @@ class Fill extends Component {
unregisterFill( prevProps.name, this );
registerFill( name, this );
}

this.checkIfSlotAvailable();
}

/**
* Forces an update if the target slot becomes available after the fill was
* rendered without the slot having yet been prepared. This can occur when
* the slot is mounted after the fill, or when the slot and fill render
* simultaneously and the Slot's portal target has not yet been mounted for
* the fill to use as a container.
*/
checkIfSlotAvailable() {
const { getSlot = noop } = this.context;
const { name } = this.props;
if ( this.isPendingSlot && !! getSlot( name ) ) {
this.forceUpdate();
}
}

resetOccurrence() {
Expand All @@ -60,9 +79,18 @@ class Fill extends Component {
const { getSlot = noop } = this.context;
const { name } = this.props;
let { children } = this.props;

const slot = getSlot( name );
if ( ! slot ) {
this.isPendingSlot = true;
return null;
}

delete this.isPendingSlot;

if ( ! slot || ! slot.props.bubblesVirtually ) {
// A slot which does not bubble events virtually is responsible for
// rendering its own fills.
if ( ! slot.props.bubblesVirtually ) {
return null;
}

Expand All @@ -71,7 +99,7 @@ class Fill extends Component {
children = children( slot.props.fillProps );
}

return createPortal( children, slot.node );
return createPortal( children, slot.virtualTarget.current );
}
}

Expand Down
27 changes: 21 additions & 6 deletions packages/components/src/slot-fill/provider.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,27 @@ class SlotFillProvider extends Component {

registerSlot( name, slot ) {
this.slots[ name ] = slot;
this.forceUpdateFills( name );

// TODO: Track down when this case occurs, see if we can at least limit
// it to specific variations of Slot/Fill. Needs test case.

// Sometimes the fills are registered after the initial render of slot
// But before the registerSlot call, we need to rerender the slot
this.forceUpdateSlot( name );
this.forceUpdateFillRenderingSlot( name );

// A fill in a bubblesVirtually slot renders itself via createPortal.
// If the slot was mounted after the fill, the fill needs update.
if ( slot.props.bubblesVirtually ) {
this.forceUpdateFills( name );
}
}

registerFill( name, instance ) {
this.fills[ name ] = [
...( this.fills[ name ] || [] ),
instance,
];
this.forceUpdateSlot( name );
this.forceUpdateFillRenderingSlot( name );
}

unregisterSlot( name ) {
Expand All @@ -62,7 +70,7 @@ class SlotFillProvider extends Component {
instance
);
this.resetFillOccurrence( name );
this.forceUpdateSlot( name );
this.forceUpdateFillRenderingSlot( name );
}

getSlot( name ) {
Expand All @@ -85,10 +93,17 @@ class SlotFillProvider extends Component {
} );
}

forceUpdateSlot( name ) {
/**
* Forces update of a slot, if the slot is responsible for rendering fills
* of the given name. A slot renders its fills if its bubblesVirtually prop
* is not `true`; otherwise, the fill renders itself by createPortal.
*
* @param {string} name Name of fill-rendering slot to update.
*/
forceUpdateFillRenderingSlot( name ) {
const slot = this.getSlot( name );

if ( slot ) {
if ( slot && ! slot.props.bubblesVirtually ) {
slot.forceUpdate();
}
}
Expand Down
Loading