Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 124 additions & 2 deletions packages/block-editor/src/hooks/block-style-variation.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
import { useStyleOverride } from './utils';
import { store as blockEditorStore } from '../store';
import { globalStylesDataKey } from '../store/private-keys';
import { unlock } from '../lock-unlock';

const VARIATION_PREFIX = 'is-style-';

Expand Down Expand Up @@ -59,7 +60,127 @@ function getVariationNameFromClass( className, registeredStyles = [] ) {
return null;
}

function useBlockSyleVariation( name, variation, clientId ) {
// A helper component to apply a style override using the useStyleOverride hook.
function OverrideStyles( { override } ) {
useStyleOverride( override );
}

/**
* This component is used to generate new block style variation overrides
* based on an incoming theme config. If a matching style is found in the config,
* a new override is created and returned. The overrides can be used in conjunction with
* useStyleOverride to apply the new styles to the editor. Its use is
* subject to change.
*
* @param {Object} props Props.
* @param {Object} props.config A global styles object, containing settings and styles.
* @return {JSX.Element|undefined} An array of new block variation overrides.
*/
export function __unstableBlockStyleVariationOverridesWithConfig( { config } ) {
const { getBlockStyles, overrides } = useSelect(
( select ) => ( {
getBlockStyles: select( blocksStore ).getBlockStyles,
overrides: unlock( select( blockEditorStore ) ).getStyleOverrides(),
} ),
[]
);
const { getBlockName } = useSelect( blockEditorStore );
Comment thread
ramonjd marked this conversation as resolved.

const overridesWithConfig = useMemo( () => {
if ( ! overrides?.length ) {
return;
}
const newOverrides = [];
const overriddenClientIds = [];
for ( const [ , override ] of overrides ) {
if (
override?.variation &&
override?.clientId &&
/*
* Because this component overwrites existing style overrides,
* filter out any overrides that are already present in the store.
*/
! overriddenClientIds.includes( override.clientId )
) {
const blockName = getBlockName( override.clientId );
const configStyles =
config?.styles?.blocks?.[ blockName ]?.variations?.[
override.variation
];
if ( configStyles ) {
const variationConfig = {
settings: config?.settings,
// The variation style data is all that is needed to generate
// the styles for the current application to a block. The variation
// name is updated to match the instance specific class name.
styles: {
blocks: {
[ blockName ]: {
variations: {
[ `${ override.variation }-${ override.clientId }` ]:
configStyles,
},
},
},
},
};
const blockSelectors = getBlockSelectors(
getBlockTypes(),
getBlockStyles,
override.clientId
);
const hasBlockGapSupport = false;
const hasFallbackGapSupport = true;
const disableLayoutStyles = true;
const disableRootPadding = true;
const variationStyles = toStyles(
variationConfig,
blockSelectors,
hasBlockGapSupport,
hasFallbackGapSupport,
disableLayoutStyles,
disableRootPadding,
{
blockGap: false,
blockStyles: true,
layoutStyles: false,
marginReset: false,
presets: false,
rootPadding: false,
variationStyles: true,
}
);
newOverrides.push( {
id: `${ override.variation }-${ override.clientId }`,
css: variationStyles,
__unstableType: 'variation',
variation: override.variation,
// The clientId will be stored with the override and used to ensure
// the order of overrides matches the order of blocks so that the
// correct CSS cascade is maintained.
clientId: override.clientId,
} );
overriddenClientIds.push( override.clientId );
}
}
}
return newOverrides;
}, [ config, overrides, getBlockStyles, getBlockName ] );

if ( ! overridesWithConfig || ! overridesWithConfig.length ) {
return;
}

return (
<>
{ overridesWithConfig.map( ( override ) => (
<OverrideStyles key={ override.id } override={ override } />
) ) }
</>
);
}

function useBlockStyleVariation( name, variation, clientId ) {
// Prefer global styles data in GlobalStylesContext, which are available
// if in the site editor. Otherwise fall back to whatever is in the
// editor settings and available in the post editor.
Expand Down Expand Up @@ -112,7 +233,7 @@ function useBlockProps( { name, className, clientId } ) {
const variation = getVariationNameFromClass( className, registeredStyles );
const variationClass = `${ VARIATION_PREFIX }${ variation }-${ clientId }`;

const { settings, styles } = useBlockSyleVariation(
const { settings, styles } = useBlockStyleVariation(
name,
variation,
clientId
Expand Down Expand Up @@ -157,6 +278,7 @@ function useBlockProps( { name, className, clientId } ) {
id: `variation-${ clientId }`,
css: variationStyles,
__unstableType: 'variation',
variation,
// The clientId will be stored with the override and used to ensure
// the order of overrides matches the order of blocks so that the
// correct CSS cascade is maintained.
Expand Down
1 change: 1 addition & 0 deletions packages/block-editor/src/hooks/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,4 @@ export { getTypographyClassesAndStyles } from './use-typography-props';
export { getGapCSSValue } from './gap';
export { useCachedTruthy } from './use-cached-truthy';
export { useZoomOut } from './use-zoom-out';
export { __unstableBlockStyleVariationOverridesWithConfig } from './block-style-variation';
2 changes: 2 additions & 0 deletions packages/block-editor/src/hooks/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ export function useStyleOverride( {
css,
assets,
__unstableType,
variation,
clientId,
} = {} ) {
const { setStyleOverride, deleteStyleOverride } = unlock(
Expand All @@ -159,6 +160,7 @@ export function useStyleOverride( {
css,
assets,
__unstableType,
variation,
clientId,
};
// Batch updates to style overrides to avoid triggering cascading renders
Expand Down
7 changes: 6 additions & 1 deletion packages/block-editor/src/private-apis.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ import { cleanEmptyObject, useStyleOverride } from './hooks/utils';
import BlockQuickNavigation from './components/block-quick-navigation';
import { LayoutStyle } from './components/block-list/layout';
import { BlockRemovalWarningModal } from './components/block-removal-warning-modal';
import { useLayoutClasses, useLayoutStyles } from './hooks';
import {
useLayoutClasses,
useLayoutStyles,
__unstableBlockStyleVariationOverridesWithConfig,
} from './hooks';
import DimensionsTool from './components/dimensions-tool';
import ResolutionTool from './components/resolution-tool';
import TextAlignmentControl from './components/text-alignment-control';
Expand Down Expand Up @@ -88,4 +92,5 @@ lock( privateApis, {
PrivatePublishDateTimePicker,
useSpacingSizes,
useBlockDisplayTitle,
__unstableBlockStyleVariationOverridesWithConfig,
} );
10 changes: 9 additions & 1 deletion packages/edit-site/src/components/revisions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const {
ExperimentalBlockEditorProvider,
GlobalStylesContext,
useGlobalStylesOutputWithConfig,
__unstableBlockStyleVariationOverridesWithConfig,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this __unstable? It's already private, right?

@ramonjd ramonjd Jun 28, 2024

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There was a bit of discussion around it.

To answer the "why", to advertise without ambiguity that, despite being private, it's unstable.

Similar to how private block editor functions have the Experimental or Private prefixes 🤷🏻

I don't think it does any harm, but could easily be communicated in comments. I can rename it next week if you feel strongly about it.

} = unlock( blockEditorPrivateApis );
const { mergeBaseAndUserConfigs } = unlock( editorPrivateApis );

Expand Down Expand Up @@ -74,7 +75,6 @@ function Revisions( { userConfig, blocks } ) {
name="revisions"
tabIndex={ 0 }
>
<EditorStyles styles={ editorStyles } />
<style>
{
// Forming a "block formatting context" to prevent margin collapsing.
Expand All @@ -88,6 +88,14 @@ function Revisions( { userConfig, blocks } ) {
settings={ settings }
>
<BlockList renderAppender={ false } />
{ /*
* Styles are printed inside the block editor provider,
* so they can access any registered style overrides.
*/ }
<EditorStyles styles={ editorStyles } />
<__unstableBlockStyleVariationOverridesWithConfig
config={ mergedConfig }
/>
</ExperimentalBlockEditorProvider>
</Disabled>
</Iframe>
Expand Down
Loading