@wordpress/components
Version:
UI components for WordPress.
104 lines (87 loc) • 2.75 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.ContextSystemProvider = exports.useComponentsContext = exports.ComponentsContext = void 0;
var _element = require("@wordpress/element");
var _lodash = require("lodash");
var _utils = require("../utils");
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const ComponentsContext = (0, _element.createContext)(
/** @type {Record<string, any>} */
{});
exports.ComponentsContext = ComponentsContext;
const useComponentsContext = () => (0, _element.useContext)(ComponentsContext);
/**
* Consolidates incoming ContextSystem values with a (potential) parent ContextSystem value.
*
* @param {Object} props
* @param {Record<string, any>} props.value
* @return {Record<string, any>} The consolidated value.
*/
exports.useComponentsContext = useComponentsContext;
function useContextSystemBridge({
value
}) {
const parentContext = useComponentsContext();
const parentContextRef = (0, _element.useRef)(parentContext);
const valueRef = (0, _element.useRef)((0, _lodash.merge)(parentContext, value));
const [config, setConfig] = (0, _element.useState)(valueRef.current);
(0, _utils.useIsomorphicLayoutEffect)(() => {
let hasChange = false;
if (!(0, _lodash.isEqual)(value, valueRef.current)) {
valueRef.current = value;
hasChange = true;
}
if (!(0, _lodash.isEqual)(parentContext, parentContextRef.current)) {
valueRef.current = (0, _lodash.merge)(parentContext, valueRef.current);
parentContextRef.current = parentContext;
hasChange = true;
}
if (hasChange) {
setConfig(prev => ({ ...prev,
...valueRef.current
}));
}
}, [value, parentContext]);
return config;
}
/**
* A Provider component that can modify props for connected components within
* the Context system.
*
* @example
* ```jsx
* <ContextSystemProvider value={{ Button: { size: 'small' }}}>
* <Button>...</Button>
* </ContextSystemProvider>
* ```
*
* @template {Record<string, any>} T
* @param {Object} options
* @param {import('react').ReactNode} options.children Children to render.
* @param {T} options.value Props to render into connected components.
* @return {JSX.Element} A Provider wrapped component.
*/
const BaseContextSystemProvider = ({
children,
value
}) => {
const contextValue = useContextSystemBridge({
value
});
return (0, _element.createElement)(ComponentsContext.Provider, {
value: contextValue
}, children);
};
const ContextSystemProvider = (0, _element.memo)(BaseContextSystemProvider);
exports.ContextSystemProvider = ContextSystemProvider;
//# sourceMappingURL=context-system-provider.js.map