Skip to content

Commit

Permalink
Block editor: new filter
Browse files Browse the repository at this point in the history
  • Loading branch information
ellatrix committed Mar 7, 2023
1 parent 32b4481 commit 10fe5d6
Show file tree
Hide file tree
Showing 11 changed files with 428 additions and 438 deletions.
68 changes: 58 additions & 10 deletions packages/block-editor/src/components/block-list/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,14 @@ import {
} from '@wordpress/compose';
import {
createContext,
useState,
useMemo,
useCallback,
useLayoutEffect,
useContext,
useRef,
Fragment,
createElement,
useReducer,
} from '@wordpress/element';

/**
Expand All @@ -41,13 +46,55 @@ import {
DEFAULT_BLOCK_EDIT_CONTEXT,
} from '../block-edit/context';

const elementContext = createContext();
const componentsContext = createContext();

export const IntersectionObserver = createContext();
const pendingBlockVisibilityUpdatesPerRegistry = new WeakMap();

function useRootPortal( component ) {
const components = useContext( componentsContext );

useLayoutEffect( () => {
if ( ! component ) return;
components.add( component );
return () => {
components.delete( component );
};
} );
}

function Components( { subscriber, components } ) {
const [ , forceRender ] = useReducer( () => ( {} ) );
subscriber.current = forceRender;
return createElement( Fragment, null, ...components.current );
}

function ComponentRenderer( { children } ) {
const subscriber = useRef( () => {} );
const components = useRef( new Set() );
return (
<componentsContext.Provider
value={ useMemo(
() => ( {
add( component ) {
components.current.add( component );
subscriber.current();
},
delete( component ) {
components.current.delete( component );
subscriber.current();
},
} ),
[]
) }
>
<Components subscriber={ subscriber } components={ components } />
{ children }
</componentsContext.Provider>
);
}

function Root( { className, ...settings } ) {
const [ element, setElement ] = useState();
const isLargeViewport = useViewportMatch( 'medium' );
const { isOutlineMode, isFocusMode, editorMode } = useSelect(
( select ) => {
Expand Down Expand Up @@ -105,7 +152,6 @@ function Root( { className, ...settings } ) {
ref: useMergeRefs( [
useBlockSelectionClearer(),
useInBetweenInserter(),
setElement,
] ),
className: classnames( 'is-root-container', className, {
'is-outline-mode': isOutlineMode,
Expand All @@ -116,11 +162,13 @@ function Root( { className, ...settings } ) {
settings
);
return (
<elementContext.Provider value={ element }>
<IntersectionObserver.Provider value={ intersectionObserver }>
<div { ...innerBlocksProps } />
</IntersectionObserver.Provider>
</elementContext.Provider>
<IntersectionObserver.Provider value={ intersectionObserver }>
<div { ...innerBlocksProps }>
<ComponentRenderer>
{ innerBlocksProps.children }
</ComponentRenderer>
</div>
</IntersectionObserver.Provider>
);
}

Expand All @@ -135,7 +183,7 @@ export default function BlockList( settings ) {
);
}

BlockList.__unstableElementContext = elementContext;
BlockList.useRootPortal = useRootPortal;

function Items( {
placeholder,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
import { useMergeRefs, useDisabled } from '@wordpress/compose';
import { useSelect } from '@wordpress/data';
import warning from '@wordpress/warning';
import { applyFilters } from '@wordpress/hooks';

/**
* Internal dependencies
Expand Down Expand Up @@ -75,6 +76,8 @@ export function useBlockProps( props = {}, { __unstableIsHtml } = {} ) {
isPartOfSelection,
adjustScrolling,
enableAnimation,
blockType,
attributes,
} = useSelect(
( select ) => {
const {
Expand All @@ -95,22 +98,24 @@ export function useBlockProps( props = {}, { __unstableIsHtml } = {} ) {
isBlockMultiSelected( clientId ) ||
isAncestorMultiSelected( clientId );
const blockName = getBlockName( clientId );
const blockType = getBlockType( blockName );
const attributes = getBlockAttributes( clientId );
const match = getActiveBlockVariation( blockName, attributes );
const _blockType = getBlockType( blockName );
const _attributes = getBlockAttributes( clientId );
const match = getActiveBlockVariation( blockName, _attributes );

return {
index: getBlockIndex( clientId ),
mode: getBlockMode( clientId ),
name: blockName,
blockApiVersion: blockType?.apiVersion || 1,
blockTitle: match?.title || blockType?.title,
blockApiVersion: _blockType?.apiVersion || 1,
blockTitle: match?.title || _blockType?.title,
isPartOfSelection: isSelected || isPartOfMultiSelection,
adjustScrolling:
isSelected || isFirstMultiSelectedBlock( clientId ),
enableAnimation:
! isTyping() &&
getGlobalBlockCount() <= BLOCK_ANIMATION_THRESHOLD,
blockType: _blockType,
attributes: _attributes,
};
},
[ clientId ]
Expand Down Expand Up @@ -147,9 +152,16 @@ export function useBlockProps( props = {}, { __unstableIsHtml } = {} ) {
);
}

const filteredWrapperProps = applyFilters(
'blockEditor.useBlockProps',
wrapperProps,
blockType,
attributes
);

return {
tabIndex: 0,
...wrapperProps,
...filteredWrapperProps,
...props,
ref: mergedRefs,
id: `block-${ clientId }${ htmlSuffix }`,
Expand All @@ -166,13 +178,13 @@ export function useBlockProps( props = {}, { __unstableIsHtml } = {} ) {
} ),
className,
props.className,
wrapperProps.className,
filteredWrapperProps.className,
useBlockClassNames( clientId ),
useBlockDefaultClassName( clientId ),
useBlockCustomClassName( clientId ),
useBlockMovingModeClassNames( clientId )
),
style: { ...wrapperProps.style, ...props.style },
style: { ...filteredWrapperProps.style, ...props.style },
};
}

Expand Down
54 changes: 23 additions & 31 deletions packages/block-editor/src/hooks/align.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,38 +175,30 @@ export const withToolbarControls = createHigherOrderComponent(
/**
* Override the default block element to add alignment wrapper props.
*
* @param {Function} BlockListBlock Original component.
*
* @return {Function} Wrapped component.
* @param {Object} props Additional props applied to edit element.
* @param {Object} blockType Block type.
* @param {Object} attributes Block attributes.
*/
export const withDataAlign = createHigherOrderComponent(
( BlockListBlock ) => ( props ) => {
const { name, attributes } = props;
const { align } = attributes;
const blockAllowedAlignments = getValidAlignments(
getBlockSupport( name, 'align' ),
hasBlockSupport( name, 'alignWide', true )
);
const validAlignments = useAvailableAlignments(
blockAllowedAlignments
);

// If an alignment is not assigned, there's no need to go through the
// effort to validate or assign its value.
if ( align === undefined ) {
return <BlockListBlock { ...props } />;
}

let wrapperProps = props.wrapperProps;
if (
validAlignments.some( ( alignment ) => alignment.name === align )
) {
wrapperProps = { ...wrapperProps, 'data-align': align };
}
export const useDataAlign = ( props, blockType, attributes ) => {
const { align } = attributes;
const blockAllowedAlignments = getValidAlignments(
getBlockSupport( blockType, 'align' ),
hasBlockSupport( blockType, 'alignWide', true )
);
const validAlignments = useAvailableAlignments( blockAllowedAlignments );

// If an alignment is not assigned, there's no need to go through the
// effort to validate or assign its value.
if ( align === undefined ) {
return props;
}

return <BlockListBlock { ...props } wrapperProps={ wrapperProps } />;
if ( validAlignments.some( ( alignment ) => alignment.name === align ) ) {
return { ...props, 'data-align': align };
}
);

return props;
};

/**
* Override props assigned to save component to inject alignment class name if
Expand Down Expand Up @@ -243,9 +235,9 @@ addFilter(
addAttribute
);
addFilter(
'editor.BlockListBlock',
'blockEditor.useBlockProps',
'core/editor/align/with-data-align',
withDataAlign
useDataAlign
);
addFilter(
'editor.BlockEdit',
Expand Down
105 changes: 48 additions & 57 deletions packages/block-editor/src/hooks/border.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import classnames from 'classnames';
*/
import { getBlockSupport } from '@wordpress/blocks';
import { __experimentalHasSplitBorders as hasSplitBorders } from '@wordpress/components';
import { createHigherOrderComponent } from '@wordpress/compose';
import { Platform, useCallback, useMemo } from '@wordpress/element';
import { addFilter } from '@wordpress/hooks';

Expand Down Expand Up @@ -331,66 +330,58 @@ function addEditProps( settings ) {
* This adds inline styles for color palette colors.
* Ideally, this is not needed and themes should load their palettes on the editor.
*
* @param {Function} BlockListBlock Original component.
*
* @return {Function} Wrapped component.
* @param {Object} props Additional props applied to save element.
* @param {Object} blockType Block type definition.
* @param {Object} attributes Block's attributes.
*/
export const withBorderColorPaletteStyles = createHigherOrderComponent(
( BlockListBlock ) => ( props ) => {
const { name, attributes } = props;
const { borderColor, style } = attributes;
const { colors } = useMultipleOriginColorsAndGradients();

if (
! hasBorderSupport( name, 'color' ) ||
shouldSkipSerialization( name, BORDER_SUPPORT_KEY, 'color' )
) {
return <BlockListBlock { ...props } />;
}
export const useBorderColorPaletteStyles = ( props, blockType, attributes ) => {
const { borderColor, style } = attributes;
const { colors } = useMultipleOriginColorsAndGradients();

const { color: borderColorValue } = getMultiOriginColor( {
colors,
namedColor: borderColor,
} );
const { color: borderTopColor } = getMultiOriginColor( {
colors,
namedColor: getColorSlugFromVariable( style?.border?.top?.color ),
} );
const { color: borderRightColor } = getMultiOriginColor( {
colors,
namedColor: getColorSlugFromVariable( style?.border?.right?.color ),
} );
if (
! hasBorderSupport( blockType, 'color' ) ||
shouldSkipSerialization( blockType, BORDER_SUPPORT_KEY, 'color' )
) {
return props;
}

const { color: borderBottomColor } = getMultiOriginColor( {
colors,
namedColor: getColorSlugFromVariable(
style?.border?.bottom?.color
),
} );
const { color: borderLeftColor } = getMultiOriginColor( {
colors,
namedColor: getColorSlugFromVariable( style?.border?.left?.color ),
} );
const { color: borderColorValue } = getMultiOriginColor( {
colors,
namedColor: borderColor,
} );
const { color: borderTopColor } = getMultiOriginColor( {
colors,
namedColor: getColorSlugFromVariable( style?.border?.top?.color ),
} );
const { color: borderRightColor } = getMultiOriginColor( {
colors,
namedColor: getColorSlugFromVariable( style?.border?.right?.color ),
} );

const extraStyles = {
borderTopColor: borderTopColor || borderColorValue,
borderRightColor: borderRightColor || borderColorValue,
borderBottomColor: borderBottomColor || borderColorValue,
borderLeftColor: borderLeftColor || borderColorValue,
};
const { color: borderBottomColor } = getMultiOriginColor( {
colors,
namedColor: getColorSlugFromVariable( style?.border?.bottom?.color ),
} );
const { color: borderLeftColor } = getMultiOriginColor( {
colors,
namedColor: getColorSlugFromVariable( style?.border?.left?.color ),
} );

let wrapperProps = props.wrapperProps;
wrapperProps = {
...props.wrapperProps,
style: {
...props.wrapperProps?.style,
...extraStyles,
},
};
const extraStyles = {
borderTopColor: borderTopColor || borderColorValue,
borderRightColor: borderRightColor || borderColorValue,
borderBottomColor: borderBottomColor || borderColorValue,
borderLeftColor: borderLeftColor || borderColorValue,
};

return <BlockListBlock { ...props } wrapperProps={ wrapperProps } />;
}
);
return {
...props,
style: {
...props.style,
...extraStyles,
},
};
};

addFilter(
'blocks.registerBlockType',
Expand All @@ -411,7 +402,7 @@ addFilter(
);

addFilter(
'editor.BlockListBlock',
'blockEditor.useBlockProps',
'core/border/with-border-color-palette-styles',
withBorderColorPaletteStyles
useBorderColorPaletteStyles
);
Loading

0 comments on commit 10fe5d6

Please sign in to comment.