UNPKG

@wordpress/components

Version:
137 lines (111 loc) 3.56 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _element = require("@wordpress/element"); var _lodash = require("lodash"); var _context = _interopRequireDefault(require("./context")); /** * External dependencies */ /** * WordPress dependencies */ /** * Internal dependencies */ class SlotFillProvider extends _element.Component { constructor() { super(...arguments); this.registerSlot = this.registerSlot.bind(this); this.registerFill = this.registerFill.bind(this); this.unregisterSlot = this.unregisterSlot.bind(this); this.unregisterFill = this.unregisterFill.bind(this); this.getSlot = this.getSlot.bind(this); this.getFills = this.getFills.bind(this); this.hasFills = this.hasFills.bind(this); this.subscribe = this.subscribe.bind(this); this.slots = {}; this.fills = {}; this.listeners = []; this.contextValue = { registerSlot: this.registerSlot, unregisterSlot: this.unregisterSlot, registerFill: this.registerFill, unregisterFill: this.unregisterFill, getSlot: this.getSlot, getFills: this.getFills, hasFills: this.hasFills, subscribe: this.subscribe }; } registerSlot(name, slot) { const previousSlot = this.slots[name]; this.slots[name] = slot; this.triggerListeners(); // 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); // If a new instance of a slot is being mounted while another with the // same name exists, force its update _after_ the new slot has been // assigned into the instance, such that its own rendering of children // will be empty (the new Slot will subsume all fills for this name). if (previousSlot) { previousSlot.forceUpdate(); } } registerFill(name, instance) { this.fills[name] = [...(this.fills[name] || []), instance]; this.forceUpdateSlot(name); } unregisterSlot(name, instance) { // If a previous instance of a Slot by this name unmounts, do nothing, // as the slot and its fills should only be removed for the current // known instance. if (this.slots[name] !== instance) { return; } delete this.slots[name]; this.triggerListeners(); } unregisterFill(name, instance) { this.fills[name] = (0, _lodash.without)(this.fills[name], instance); this.forceUpdateSlot(name); } getSlot(name) { return this.slots[name]; } getFills(name, slotInstance) { // Fills should only be returned for the current instance of the slot // in which they occupy. if (this.slots[name] !== slotInstance) { return []; } return this.fills[name]; } hasFills(name) { return this.fills[name] && !!this.fills[name].length; } forceUpdateSlot(name) { const slot = this.getSlot(name); if (slot) { slot.forceUpdate(); } } triggerListeners() { this.listeners.forEach(listener => listener()); } subscribe(listener) { this.listeners.push(listener); return () => { this.listeners = (0, _lodash.without)(this.listeners, listener); }; } render() { return (0, _element.createElement)(_context.default.Provider, { value: this.contextValue }, this.props.children); } } exports.default = SlotFillProvider; //# sourceMappingURL=provider.js.map