@wordpress/block-editor
Version:
106 lines (80 loc) • 3.66 kB
JavaScript
/**
* External dependencies
*/
import { get } from 'lodash';
/**
* Internal dependencies
*/
import { scopeSelector } from './utils';
/**
* Determine the CSS selector for the block type and target provided, returning
* it if available.
*
* @param {import('@wordpress/blocks').Block} blockType The block's type.
* @param {string|string[]} target The desired selector's target e.g. `root`, delimited string, or array path.
* @param {Object} options Options object.
* @param {boolean} options.fallback Whether or not to fallback to broader selector.
*
* @return {?string} The CSS selector or `null` if no selector available.
*/
export function getBlockCSSSelector(blockType, target = 'root', options = {}) {
if (!target) {
return null;
}
const {
fallback = false
} = options;
const {
name,
selectors,
supports
} = blockType;
const hasSelectors = selectors && Object.keys(selectors).length > 0;
const path = Array.isArray(target) ? target.join('.') : target; // Root selector.
// Calculated before returning as it can be used as a fallback for feature
// selectors later on.
let rootSelector = null;
if (hasSelectors && selectors.root) {
// Use the selectors API if available.
rootSelector = selectors?.root;
} else if (supports?.__experimentalSelector) {
// Use the old experimental selector supports property if set.
rootSelector = supports.__experimentalSelector;
} else {
// If no root selector found, generate default block class selector.
rootSelector = '.wp-block-' + name.replace('core/', '').replace('/', '-');
} // Return selector if it's the root target we are looking for.
if (path === 'root') {
return rootSelector;
} // If target is not `root` or `duotone` we have a feature or subfeature
// as the target. If the target is a string convert to an array.
const pathArray = Array.isArray(target) ? target : target.split('.'); // Feature selectors ( may fallback to root selector );
if (pathArray.length === 1) {
const fallbackSelector = fallback ? rootSelector : null; // Prefer the selectors API if available.
if (hasSelectors) {
// Get selector from either `feature.root` or shorthand path.
const featureSelector = get(selectors, `${path}.root`, null) || get(selectors, path, null); // Return feature selector if found or any available fallback.
return featureSelector || fallbackSelector;
} // Try getting old experimental supports selector value.
const featureSelector = get(supports, `${path}.__experimentalSelector`, null); // If nothing to work with, provide fallback selector if available.
if (!featureSelector) {
return fallbackSelector;
} // Scope the feature selector by the block's root selector.
return scopeSelector(rootSelector, featureSelector);
} // Subfeature selector.
// This may fallback either to parent feature or root selector.
let subfeatureSelector; // Use selectors API if available.
if (hasSelectors) {
subfeatureSelector = get(selectors, path, null);
} // Only return if we have a subfeature selector.
if (subfeatureSelector) {
return subfeatureSelector;
} // To this point we don't have a subfeature selector. If a fallback has been
// requested, remove subfeature from target path and return results of a
// call for the parent feature's selector.
if (fallback) {
return getBlockCSSSelector(blockType, pathArray[0], options);
} // We tried.
return null;
}
//# sourceMappingURL=get-block-css-selector.js.map