UNPKG

@wordpress/editor

Version:
166 lines (164 loc) 5.8 kB
/** * External dependencies */ import deepmerge from 'deepmerge'; import { isPlainObject } from 'is-plain-object'; /** * WordPress dependencies */ import { privateApis as blockEditorPrivateApis } from '@wordpress/block-editor'; import { store as coreStore } from '@wordpress/core-data'; import { useSelect, useDispatch } from '@wordpress/data'; import { useMemo, useCallback } from '@wordpress/element'; /** * Internal dependencies */ import { unlock } from '../../lock-unlock'; import { jsx as _jsx } from "react/jsx-runtime"; const { GlobalStylesContext, cleanEmptyObject } = unlock(blockEditorPrivateApis); export function mergeBaseAndUserConfigs(base, user) { return deepmerge(base, user, { /* * We only pass as arrays the presets, * in which case we want the new array of values * to override the old array (no merging). */ isMergeableObject: isPlainObject, /* * Exceptions to the above rule. * Background images should be replaced, not merged, * as they themselves are specific object definitions for the style. */ customMerge: key => { if (key === 'backgroundImage') { return (baseConfig, userConfig) => userConfig; } return undefined; } }); } function useGlobalStylesUserConfig() { const { globalStylesId, isReady, settings, styles, _links } = useSelect(select => { const { getEntityRecord, getEditedEntityRecord, hasFinishedResolution, canUser } = select(coreStore); const _globalStylesId = select(coreStore).__experimentalGetCurrentGlobalStylesId(); let record; const userCanEditGlobalStyles = canUser('update', { kind: 'root', name: 'globalStyles', id: _globalStylesId }); if (_globalStylesId) { if (userCanEditGlobalStyles) { record = getEditedEntityRecord('root', 'globalStyles', _globalStylesId); } else { record = getEntityRecord('root', 'globalStyles', _globalStylesId, { context: 'view' }); } } let hasResolved = false; if (hasFinishedResolution('__experimentalGetCurrentGlobalStylesId')) { if (_globalStylesId) { hasResolved = userCanEditGlobalStyles ? hasFinishedResolution('getEditedEntityRecord', ['root', 'globalStyles', _globalStylesId]) : hasFinishedResolution('getEntityRecord', ['root', 'globalStyles', _globalStylesId, { context: 'view' }]); } else { hasResolved = true; } } return { globalStylesId: _globalStylesId, isReady: hasResolved, settings: record?.settings, styles: record?.styles, _links: record?._links }; }, []); const { getEditedEntityRecord } = useSelect(coreStore); const { editEntityRecord } = useDispatch(coreStore); const config = useMemo(() => { return { settings: settings !== null && settings !== void 0 ? settings : {}, styles: styles !== null && styles !== void 0 ? styles : {}, _links: _links !== null && _links !== void 0 ? _links : {} }; }, [settings, styles, _links]); const setConfig = useCallback( /** * Set the global styles config. * @param {Function|Object} callbackOrObject If the callbackOrObject is a function, pass the current config to the callback so the consumer can merge values. * Otherwise, overwrite the current config with the incoming object. * @param {Object} options Options for editEntityRecord Core selector. */ (callbackOrObject, options = {}) => { var _record$styles, _record$settings, _record$_links; const record = getEditedEntityRecord('root', 'globalStyles', globalStylesId); const currentConfig = { styles: (_record$styles = record?.styles) !== null && _record$styles !== void 0 ? _record$styles : {}, settings: (_record$settings = record?.settings) !== null && _record$settings !== void 0 ? _record$settings : {}, _links: (_record$_links = record?._links) !== null && _record$_links !== void 0 ? _record$_links : {} }; const updatedConfig = typeof callbackOrObject === 'function' ? callbackOrObject(currentConfig) : callbackOrObject; editEntityRecord('root', 'globalStyles', globalStylesId, { styles: cleanEmptyObject(updatedConfig.styles) || {}, settings: cleanEmptyObject(updatedConfig.settings) || {}, _links: cleanEmptyObject(updatedConfig._links) || {} }, options); }, [globalStylesId, editEntityRecord, getEditedEntityRecord]); return [isReady, config, setConfig]; } function useGlobalStylesBaseConfig() { const baseConfig = useSelect(select => select(coreStore).__experimentalGetCurrentThemeBaseGlobalStyles(), []); return [!!baseConfig, baseConfig]; } export function useGlobalStylesContext() { const [isUserConfigReady, userConfig, setUserConfig] = useGlobalStylesUserConfig(); const [isBaseConfigReady, baseConfig] = useGlobalStylesBaseConfig(); const mergedConfig = useMemo(() => { if (!baseConfig || !userConfig) { return {}; } return mergeBaseAndUserConfigs(baseConfig, userConfig); }, [userConfig, baseConfig]); const context = useMemo(() => { return { isReady: isUserConfigReady && isBaseConfigReady, user: userConfig, base: baseConfig, merged: mergedConfig, setUserConfig }; }, [mergedConfig, userConfig, baseConfig, setUserConfig, isUserConfigReady, isBaseConfigReady]); return context; } export function GlobalStylesProvider({ children }) { const context = useGlobalStylesContext(); if (!context.isReady) { return null; } return /*#__PURE__*/_jsx(GlobalStylesContext.Provider, { value: context, children: children }); } //# sourceMappingURL=index.js.map