Skip to content

Commit

Permalink
Global styles revisions: ensure that user-defined variation styles CS…
Browse files Browse the repository at this point in the history
…S is generated (#62768)

* Render styles after the variation style overrides have been saved to stage.
Getting closer. But the overrides in state need to be merged with incoming revision styles.

* For every current override, update the variation CSS with the incoming config from the revision.

* Rename hook
Destructure in hook so the consumer doesn't have to clone
Only send the override overrides to EditorStyles that need to be overridden.

* Fetching overrides in the hook

* Feedback suggestions from review:
add overrides to dep array in Editor Styles
rename hook

* Return getBlockStyles from the useSelect callback

* Refactor so we don't have to change the EditorStyles props
Register revision overrides with useStyleOverride

* Adding some explanatory comments
Add rudimentary E2E test covering block style partials, applying them, updating them and viewing styles revisions.

* Removed unused style fixture

Co-authored-by: ramonjd <ramonopoly@git.wordpress.org>
Co-authored-by: aaronrobertshaw <aaronrobertshaw@git.wordpress.org>
Co-authored-by: ellatrix <ellatrix@git.wordpress.org>
  • Loading branch information
4 people authored Jun 27, 2024
1 parent 2e41a46 commit 49b9692
Show file tree
Hide file tree
Showing 9 changed files with 548 additions and 2 deletions.
122 changes: 122 additions & 0 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,6 +60,126 @@ function getVariationNameFromClass( className, registeredStyles = [] ) {
return null;
}

// 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 );

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
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,
} = 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

1 comment on commit 49b9692

@github-actions
Copy link

Choose a reason for hiding this comment

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

Flaky tests detected in 49b9692.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/9691834377
📝 Reported issues:

Please sign in to comment.