Skip to content

Commit

Permalink
Add layout styles from Post Content block to post editor (#44258)
Browse files Browse the repository at this point in the history
* Add layout styles from Post Content block to post editor

* Fix post content finding logic.

* Remove extra styles when Post Content block exists.

* templateContent should always be a string

* Memoise post content block.

* Change function signature and mark experimental

* _Really_ make sure templateContent is a string

* Update layout type for legacy layouts.

* Fix selector specificity and legacy layout logic.

* Fix 404s on fetch and only parse content if needed

* Fix acces to layout when no Post Content block

* Add doc comment to findPostContent

* Increase specificity

* Remove unneeded LayoutStyle
  • Loading branch information
tellthemachines authored and ockham committed Oct 4, 2022
1 parent 042214d commit a6e566a
Show file tree
Hide file tree
Showing 5 changed files with 189 additions and 55 deletions.
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 @@ -20,6 +20,7 @@ import './metadata';
import './metadata-name';

export { useCustomSides } from './dimensions';
export { useLayoutClasses, useLayoutStyles } from './layout';
export { getBorderClassesAndStyles, useBorderProps } from './use-border-props';
export { getColorClassesAndStyles, useColorProps } from './use-color-props';
export { getSpacingClassesAndStyles } from './use-spacing-props';
Expand Down
85 changes: 64 additions & 21 deletions packages/block-editor/src/hooks/layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,58 +37,101 @@ import { getLayoutType, getLayoutTypes } from '../layouts';
const layoutBlockSupportKey = '__experimentalLayout';

/**
* Generates the utility classnames for the given blocks layout attributes.
* This method was primarily added to reintroduce classnames that were removed
* in the 5.9 release (https://github.com/WordPress/gutenberg/issues/38719), rather
* than providing an extensive list of all possible layout classes. The plan is to
* have the style engine generate a more extensive list of utility classnames which
* will then replace this method.
* Generates the utility classnames for the given block's layout attributes.
*
* @param { Object } layout Layout object.
* @param { Object } layoutDefinitions An object containing layout definitions, stored in theme.json.
* @param { Object } block Block object.
*
* @return { Array } Array of CSS classname strings.
*/
function useLayoutClasses( layout, layoutDefinitions ) {
export function useLayoutClasses( block = {} ) {
const rootPaddingAlignment = useSelect( ( select ) => {
const { getSettings } = select( blockEditorStore );
return getSettings().__experimentalFeatures
?.useRootPaddingAwareAlignments;
}, [] );
const globalLayoutSettings = useSetting( 'layout' ) || {};

const { attributes = {}, name } = block;
const { layout } = attributes;

const { default: defaultBlockLayout } =
getBlockSupport( name, layoutBlockSupportKey ) || {};
const usedLayout =
layout?.inherit || layout?.contentSize || layout?.wideSize
? { ...layout, type: 'constrained' }
: layout || defaultBlockLayout || {};

const layoutClassnames = [];

if ( layoutDefinitions?.[ layout?.type || 'default' ]?.className ) {
if (
globalLayoutSettings?.definitions?.[ usedLayout?.type || 'default' ]
?.className
) {
layoutClassnames.push(
layoutDefinitions?.[ layout?.type || 'default' ]?.className
globalLayoutSettings?.definitions?.[ usedLayout?.type || 'default' ]
?.className
);
}

if (
( layout?.inherit ||
layout?.contentSize ||
layout?.type === 'constrained' ) &&
( usedLayout?.inherit ||
usedLayout?.contentSize ||
usedLayout?.type === 'constrained' ) &&
rootPaddingAlignment
) {
layoutClassnames.push( 'has-global-padding' );
}

if ( layout?.orientation ) {
layoutClassnames.push( `is-${ kebabCase( layout.orientation ) }` );
if ( usedLayout?.orientation ) {
layoutClassnames.push( `is-${ kebabCase( usedLayout.orientation ) }` );
}

if ( layout?.justifyContent ) {
if ( usedLayout?.justifyContent ) {
layoutClassnames.push(
`is-content-justification-${ kebabCase( layout.justifyContent ) }`
`is-content-justification-${ kebabCase(
usedLayout.justifyContent
) }`
);
}

if ( layout?.flexWrap && layout.flexWrap === 'nowrap' ) {
if ( usedLayout?.flexWrap && usedLayout.flexWrap === 'nowrap' ) {
layoutClassnames.push( 'is-nowrap' );
}

return layoutClassnames;
}

/**
* Generates a CSS rule with the given block's layout styles.
*
* @param { Object } block Block object.
* @param { string } selector A selector to use in generating the CSS rule.
*
* @return { string } CSS rule.
*/
export function useLayoutStyles( block = {}, selector ) {
const { attributes = {}, name } = block;
const { layout = {}, style = {} } = attributes;
// Update type for blocks using legacy layouts.
const usedLayout =
layout?.inherit || layout?.contentSize || layout?.wideSize
? { ...layout, type: 'constrained' }
: layout || {};
const fullLayoutType = getLayoutType( usedLayout?.type || 'default' );
const globalLayoutSettings = useSetting( 'layout' ) || {};
const blockGapSupport = useSetting( 'spacing.blockGap' );
const hasBlockGapSupport = blockGapSupport !== null;
const css = fullLayoutType?.getLayoutStyle?.( {
blockName: name,
selector,
layout,
layoutDefinitions: globalLayoutSettings?.definitions,
style,
hasBlockGapSupport,
} );
return css;
}

function LayoutPanel( { setAttributes, attributes, name: blockName } ) {
const { layout } = attributes;
const defaultThemeLayout = useSetting( 'layout' );
Expand Down Expand Up @@ -299,7 +342,7 @@ export const withInspectorControls = createHigherOrderComponent(
*/
export const withLayoutStyles = createHigherOrderComponent(
( BlockListBlock ) => ( props ) => {
const { name, attributes } = props;
const { name, attributes, block } = props;
const hasLayoutBlockSupport = hasBlockSupport(
name,
layoutBlockSupportKey
Expand All @@ -321,7 +364,7 @@ export const withLayoutStyles = createHigherOrderComponent(
? { ...layout, type: 'constrained' }
: layout || defaultBlockLayout || {};
const layoutClasses = hasLayoutBlockSupport
? useLayoutClasses( usedLayout, defaultThemeLayout?.definitions )
? useLayoutClasses( block )
: null;
const selector = `.${ getBlockDefaultClassName(
name
Expand Down
2 changes: 2 additions & 0 deletions packages/block-editor/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ export {
getSpacingClassesAndStyles as __experimentalGetSpacingClassesAndStyles,
getGapCSSValue as __experimentalGetGapCSSValue,
useCachedTruthy,
useLayoutClasses as __experimentaluseLayoutClasses,
useLayoutStyles as __experimentaluseLayoutStyles,
} from './hooks';
export * from './components';
export * from './elements';
Expand Down
4 changes: 3 additions & 1 deletion packages/block-library/src/post-content/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ function EditableContent( { layout, context = {} } ) {
return getSettings()?.supportsLayout;
}, [] );
const defaultLayout = useSetting( 'layout' ) || {};
const usedLayout = !! layout && layout.inherit ? defaultLayout : layout;
const usedLayout = ! layout?.type
? { ...defaultLayout, ...layout, type: 'default' }
: { ...defaultLayout, ...layout };
const [ blocks, onInput, onChange ] = useEntityBlockEditor(
'postType',
postType,
Expand Down
Loading

0 comments on commit a6e566a

Please sign in to comment.