diff --git a/packages/components/src/popover/index.js b/packages/components/src/popover/index.js index c7d229e5f77b4..7ce7163006a21 100644 --- a/packages/components/src/popover/index.js +++ b/packages/components/src/popover/index.js @@ -2,7 +2,6 @@ * External dependencies */ import classnames from 'classnames'; -import { noop } from 'lodash'; /** * WordPress dependencies @@ -20,7 +19,7 @@ import withConstrainedTabbing from '../higher-order/with-constrained-tabbing'; import PopoverDetectOutside from './detect-outside'; import IconButton from '../icon-button'; import ScrollLock from '../scroll-lock'; -import { Slot, Fill } from '../slot-fill'; +import { Slot, Fill, Consumer } from '../slot-fill'; const FocusManaged = withConstrainedTabbing( withFocusReturn( ( { children } ) => children ) ); @@ -302,17 +301,24 @@ class Popover extends Component { content = { content }; } - // In case there is no slot context in which to render, default to an - // in-place rendering. - const { getSlot } = this.context; - if ( getSlot && getSlot( SLOT_NAME ) ) { - content = { content }; - } - - return - { content } - { isMobile && expandOnMobile && } - ; + return ( + + { ( { getSlot } ) => { + // In case there is no slot context in which to render, + // default to an in-place rendering. + if ( getSlot && getSlot( SLOT_NAME ) ) { + content = { content }; + } + + return ( + + { content } + { isMobile && expandOnMobile && } + + ); + } } + + ); } } @@ -323,10 +329,6 @@ Popover.defaultProps = { const PopoverContainer = Popover; -PopoverContainer.contextTypes = { - getSlot: noop, -}; - PopoverContainer.Slot = () => ; export default PopoverContainer; diff --git a/packages/components/src/slot-fill/provider.js b/packages/components/src/slot-fill/context.js similarity index 72% rename from packages/components/src/slot-fill/provider.js rename to packages/components/src/slot-fill/context.js index 29f5555244cb6..df4476fea5b9c 100644 --- a/packages/components/src/slot-fill/provider.js +++ b/packages/components/src/slot-fill/context.js @@ -1,12 +1,21 @@ /** * External dependencies */ -import { pick, sortBy, forEach, without, noop } from 'lodash'; +import { sortBy, forEach, without } from 'lodash'; /** * WordPress dependencies */ -import { Component } from '@wordpress/element'; +import { Component, createContext } from '@wordpress/element'; + +const { Provider, Consumer } = createContext( { + registerSlot: () => {}, + unregisterSlot: () => {}, + registerFill: () => {}, + unregisterFill: () => {}, + getSlot: () => {}, + getFills: () => {}, +} ); class SlotFillProvider extends Component { constructor() { @@ -21,17 +30,14 @@ class SlotFillProvider extends Component { this.slots = {}; this.fills = {}; - } - - getChildContext() { - return pick( this, [ - 'registerSlot', - 'registerFill', - 'unregisterSlot', - 'unregisterFill', - 'getSlot', - 'getFills', - ] ); + this.state = { + registerSlot: this.registerSlot, + unregisterSlot: this.unregisterSlot, + registerFill: this.registerFill, + unregisterFill: this.unregisterFill, + getSlot: this.getSlot, + getFills: this.getFills, + }; } registerSlot( name, slot ) { @@ -94,17 +100,13 @@ class SlotFillProvider extends Component { } render() { - return this.props.children; + return ( + + { this.props.children } + + ); } } -SlotFillProvider.childContextTypes = { - registerSlot: noop, - unregisterSlot: noop, - registerFill: noop, - unregisterFill: noop, - getSlot: noop, - getFills: noop, -}; - export default SlotFillProvider; +export { Consumer }; diff --git a/packages/components/src/slot-fill/fill.js b/packages/components/src/slot-fill/fill.js index 27f8da4c6fa85..66b025ca00178 100644 --- a/packages/components/src/slot-fill/fill.js +++ b/packages/components/src/slot-fill/fill.js @@ -1,23 +1,28 @@ /** * External dependencies */ -import { noop, isFunction } from 'lodash'; +import { isFunction } from 'lodash'; /** * WordPress dependencies */ import { Component, createPortal } from '@wordpress/element'; +/** + * Internal dependencies + */ +import { Consumer } from './context'; + let occurrences = 0; -class Fill extends Component { +class FillComponent extends Component { constructor() { super( ...arguments ); this.occurrence = ++occurrences; } componentDidMount() { - const { registerFill = noop } = this.context; + const { registerFill } = this.props; registerFill( this.props.name, this ); } @@ -26,7 +31,7 @@ class Fill extends Component { if ( ! this.occurrence ) { this.occurrence = ++occurrences; } - const { getSlot = noop } = this.context; + const { getSlot } = this.props; const slot = getSlot( this.props.name ); if ( slot && ! slot.props.bubblesVirtually ) { slot.forceUpdate(); @@ -34,17 +39,13 @@ class Fill extends Component { } componentWillUnmount() { - const { unregisterFill = noop } = this.context; + const { unregisterFill } = this.props; unregisterFill( this.props.name, this ); } componentDidUpdate( prevProps ) { - const { name } = this.props; - const { - unregisterFill = noop, - registerFill = noop, - } = this.context; + const { name, unregisterFill, registerFill } = this.props; if ( prevProps.name !== name ) { unregisterFill( prevProps.name, this ); @@ -57,8 +58,7 @@ class Fill extends Component { } render() { - const { getSlot = noop } = this.context; - const { name } = this.props; + const { name, getSlot } = this.props; let { children } = this.props; const slot = getSlot( name ); @@ -75,10 +75,17 @@ class Fill extends Component { } } -Fill.contextTypes = { - getSlot: noop, - registerFill: noop, - unregisterFill: noop, -}; +const Fill = ( props ) => ( + + { ( { getSlot, registerFill, unregisterFill } ) => ( + + ) } + +); export default Fill; diff --git a/packages/components/src/slot-fill/index.js b/packages/components/src/slot-fill/index.js index bec51806039a6..4155b083b0fdf 100644 --- a/packages/components/src/slot-fill/index.js +++ b/packages/components/src/slot-fill/index.js @@ -3,11 +3,11 @@ */ import Slot from './slot'; import Fill from './fill'; -import Provider from './provider'; +import Provider, { Consumer } from './context'; export { Slot }; export { Fill }; -export { Provider }; +export { Provider, Consumer }; export function createSlotFill( name ) { const FillComponent = ( props ) => ; diff --git a/packages/components/src/slot-fill/slot.js b/packages/components/src/slot-fill/slot.js index 4ce429f4863c9..4f53cd6d10300 100644 --- a/packages/components/src/slot-fill/slot.js +++ b/packages/components/src/slot-fill/slot.js @@ -6,7 +6,6 @@ import { isString, map, negate, - noop, } from 'lodash'; /** @@ -20,7 +19,12 @@ import { isEmptyElement, } from '@wordpress/element'; -class Slot extends Component { +/** + * Internal dependencies + */ +import { Consumer } from './context'; + +class SlotComponent extends Component { constructor() { super( ...arguments ); @@ -28,23 +32,19 @@ class Slot extends Component { } componentDidMount() { - const { registerSlot = noop } = this.context; + const { registerSlot } = this.props; registerSlot( this.props.name, this ); } componentWillUnmount() { - const { unregisterSlot = noop } = this.context; + const { unregisterSlot } = this.props; unregisterSlot( this.props.name, this ); } componentDidUpdate( prevProps ) { - const { name } = this.props; - const { - unregisterSlot = noop, - registerSlot = noop, - } = this.context; + const { name, unregisterSlot, registerSlot } = this.props; if ( prevProps.name !== name ) { unregisterSlot( prevProps.name ); @@ -57,8 +57,7 @@ class Slot extends Component { } render() { - const { children, name, bubblesVirtually = false, fillProps = {} } = this.props; - const { getFills = noop } = this.context; + const { children, name, bubblesVirtually = false, fillProps = {}, getFills } = this.props; if ( bubblesVirtually ) { return
; @@ -91,10 +90,17 @@ class Slot extends Component { } } -Slot.contextTypes = { - registerSlot: noop, - unregisterSlot: noop, - getFills: noop, -}; +const Slot = ( props ) => ( + + { ( { registerSlot, unregisterSlot, getFills } ) => ( + + ) } + +); export default Slot; diff --git a/packages/components/src/slot-fill/test/slot.js b/packages/components/src/slot-fill/test/slot.js index d3b0716e49841..a12c9cd99c6ca 100644 --- a/packages/components/src/slot-fill/test/slot.js +++ b/packages/components/src/slot-fill/test/slot.js @@ -9,7 +9,7 @@ import ReactTestRenderer from 'react-test-renderer'; */ import Slot from '../slot'; import Fill from '../fill'; -import Provider from '../provider'; +import Provider from '../context'; /** * WordPress Dependencies