Skip to content

Commit

Permalink
Components: Render popover as slot / fill
Browse files Browse the repository at this point in the history
  • Loading branch information
aduth committed Oct 10, 2017
1 parent 181d97d commit a2e813a
Show file tree
Hide file tree
Showing 10 changed files with 41 additions and 70 deletions.
2 changes: 2 additions & 0 deletions components/dropdown/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { mount } from 'enzyme';
*/
import Dropdown from '../';

jest.mock( '../../slot-fill/fill' );

describe( 'Dropdown', () => {
it( 'should toggle the dropdown properly', () => {
const wrapper = mount( <Dropdown
Expand Down
1 change: 0 additions & 1 deletion components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ export { default as PanelHeader } from './panel/header';
export { default as PanelRow } from './panel/row';
export { default as Placeholder } from './placeholder';
export { default as Popover } from './popover';
export { default as PopoverProvider } from './popover/provider';
export { default as ResponsiveWrapper } from './responsive-wrapper';
export { default as SandBox } from './sandbox';
export { default as Spinner } from './spinner';
Expand Down
15 changes: 8 additions & 7 deletions components/popover/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,20 @@ function ToggleButton( { isVisible, toggleVisible } ) {
}
```

If you want Popover elementss to render to a specific location on the page to allow style cascade to take effect, you must render a `PopoverProvider` further up the element tree, specifying a target:
If you want Popover elements to render to a specific location on the page to allow style cascade to take effect, you must render a `Popover.Slot` further up the element tree:

```
```jsx
import { render } from '@wordpress/element';
import { PopoverContext } from '@wordpress/components';
import App from './app';
import { Popover } from '@wordpress/components';
import Content from './Content';

const app = document.getElementById( 'app' );

render(
<PopoverContext target={ app }>
<App />
</PopoverContext>,
<div>
<Content />
<Popover.Slot />
</div>,
app
);
```
Expand Down
24 changes: 14 additions & 10 deletions components/popover/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,20 @@
* External dependencies
*/
import classnames from 'classnames';
import { isEqual, noop } from 'lodash';
import { isEqual } from 'lodash';

/**
* WordPress dependencies
*/
import { createPortal, Component } from '@wordpress/element';
import { Component } from '@wordpress/element';
import { focus, keycodes } from '@wordpress/utils';

/**
* Internal dependencies
*/
import './style.scss';
import PopoverDetectOutside from './detect-outside';
import { Slot, Fill } from '../slot-fill';

const { ESCAPE } = keycodes;

Expand All @@ -25,6 +26,13 @@ const { ESCAPE } = keycodes;
*/
const ARROW_OFFSET = 20;

/**
* Name of slot in which popover should fill.
*
* @type {String}
*/
const SLOT_NAME = 'Popover';

export class Popover extends Component {
constructor() {
super( ...arguments );
Expand Down Expand Up @@ -222,7 +230,6 @@ export class Popover extends Component {
return null;
}

const { popoverTarget = document.body } = this.context;
const classes = classnames(
'components-popover',
className,
Expand All @@ -236,7 +243,7 @@ export class Popover extends Component {
/* eslint-disable jsx-a11y/no-static-element-interactions */
return (
<span ref={ this.bindNode( 'anchor' ) }>
{ createPortal(
<Fill name={ SLOT_NAME }>
<PopoverDetectOutside onClickOutside={ onClickOutside }>
<div
ref={ this.bindNode( 'popover' ) }
Expand All @@ -252,17 +259,14 @@ export class Popover extends Component {
{ children }
</div>
</div>
</PopoverDetectOutside>,
popoverTarget
) }
</PopoverDetectOutside>
</Fill>
</span>
);
/* eslint-enable jsx-a11y/no-static-element-interactions */
}
}

Popover.contextTypes = {
popoverTarget: noop,
};
Popover.Slot = () => <Slot name={ SLOT_NAME } />;

export default Popover;
27 changes: 0 additions & 27 deletions components/popover/provider.js

This file was deleted.

17 changes: 2 additions & 15 deletions components/popover/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import { shallow, mount } from 'enzyme';
* Internal dependencies
*/
import { Popover } from '../';
import PopoverProvider from '../provider';

jest.mock( '../../slot-fill/fill' );

describe( 'Popover', () => {
describe( '#componentDidUpdate()', () => {
Expand Down Expand Up @@ -273,19 +274,5 @@ describe( 'Popover', () => {

expect( wrapper.find( '.components-popover' ).prop( 'role' ) ).toBe( 'tooltip' );
} );

it( 'should render into provider context', () => {
const element = require( '@wordpress/element' );
jest.spyOn( element, 'createPortal' );
const target = document.createElement( 'div' );

mount(
<PopoverProvider target={ target }>
<Popover isOpen>Hello</Popover>
</PopoverProvider>
);

expect( element.createPortal.mock.calls[ 0 ][ 1 ] ).toBe( target );
} );
} );
} );
1 change: 1 addition & 0 deletions components/slot-fill/__mocks__/fill.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default ( { children } ) => children;
2 changes: 2 additions & 0 deletions components/tooltip/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { shallow, mount } from 'enzyme';
*/
import Tooltip from '../';

jest.mock( '../../slot-fill/fill' );

describe( 'Tooltip', () => {
describe( '#render()', () => {
// Disable reason: The Tooltip component leverages array return values
Expand Down
19 changes: 10 additions & 9 deletions editor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import 'moment-timezone/moment-timezone-utils';
*/
import { EditableProvider } from '@wordpress/blocks';
import { createElement, render } from '@wordpress/element';
import { APIProvider, PopoverProvider, DropZoneProvider } from '@wordpress/components';
import { APIProvider, DropZoneProvider, SlotFillProvider as WPSlotFillProvider } from '@wordpress/components';
import { settings as dateSettings } from '@wordpress/date';

/**
Expand Down Expand Up @@ -92,6 +92,15 @@ export function createEditorInstance( id, post, settings ) {
SlotFillProvider,
],

// Slot / Fill provider:
//
// - context.getSlot
// - context.registerSlot
// - context.unregisterSlot
[
WPSlotFillProvider,
],

// Editable provider:
//
// - context.onUndo
Expand All @@ -110,14 +119,6 @@ export function createEditorInstance( id, post, settings ) {
{ settings },
],

// Popover provider:
//
// - context.popoverTarget
[
PopoverProvider,
{ target },
],

// APIProvider
//
// - context.getAPISchema
Expand Down
3 changes: 2 additions & 1 deletion editor/layout/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import classnames from 'classnames';
/**
* WordPress dependencies
*/
import { NoticeList } from '@wordpress/components';
import { NoticeList, Popover } from '@wordpress/components';

/**
* Internal dependencies
Expand Down Expand Up @@ -48,6 +48,7 @@ function Layout( { mode, isSidebarOpened, notices, ...props } ) {
<MetaBoxes />
</div>
{ isSidebarOpened && <Sidebar /> }
<Popover.Slot />
</div>
);
}
Expand Down

0 comments on commit a2e813a

Please sign in to comment.