Skip to content

Commit

Permalink
Introduce the layout prop to InnerBlocks
Browse files Browse the repository at this point in the history
  • Loading branch information
youknowriad committed Oct 22, 2020
1 parent 55bf7ec commit 9db2619
Show file tree
Hide file tree
Showing 10 changed files with 86 additions and 76 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
*/
import { __ } from '@wordpress/i18n';
import { ToolbarGroup } from '@wordpress/components';
import { withSelect } from '@wordpress/data';
import { compose } from '@wordpress/compose';
import { useSelect } from '@wordpress/data';
import {
positionCenter,
positionLeft,
Expand All @@ -13,6 +12,11 @@ import {
stretchWide,
} from '@wordpress/icons';

/**
* Internal dependencies
*/
import { useLayout } from '../inner-blocks/layout';

const BLOCK_ALIGNMENTS_CONTROLS = {
left: {
icon: positionLeft,
Expand Down Expand Up @@ -49,18 +53,36 @@ export function BlockAlignmentToolbar( {
onChange,
controls = DEFAULT_CONTROLS,
isCollapsed = true,
wideControlsEnabled = false,
} ) {
const { wideControlsEnabled = false } = useSelect( ( select ) => {
const { getSettings } = select( 'core/block-editor' );
const settings = getSettings();
return {
wideControlsEnabled: settings.alignWide,
};
} );
const layout = useLayout();
const supportsAlignments = layout.type === 'default';

if ( ! supportsAlignments ) {
return null;
}

const { alignments: availableAlignments = DEFAULT_CONTROLS } = layout;
const enabledControls = controls.filter(
( control ) =>
( wideControlsEnabled || WIDE_CONTROLS.includes( control ) ) &&
availableAlignments.includes( control )
);

if ( enabledControls.length === 0 ) {
return null;
}

function applyOrUnset( align ) {
return () => onChange( value === align ? undefined : align );
}

const enabledControls = wideControlsEnabled
? controls
: controls.filter(
( control ) => WIDE_CONTROLS.indexOf( control ) === -1
);

const activeAlignmentControl = BLOCK_ALIGNMENTS_CONTROLS[ value ];
const defaultAlignmentControl =
BLOCK_ALIGNMENTS_CONTROLS[ DEFAULT_CONTROL ];
Expand All @@ -87,12 +109,4 @@ export function BlockAlignmentToolbar( {
);
}

export default compose(
withSelect( ( select ) => {
const { getSettings } = select( 'core/block-editor' );
const settings = getSettings();
return {
wideControlsEnabled: settings.alignWide,
};
} )
)( BlockAlignmentToolbar );
export default BlockAlignmentToolbar;
24 changes: 15 additions & 9 deletions packages/block-editor/src/components/inner-blocks/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { BlockListItems } from '../block-list';
import { BlockContextProvider } from '../block-context';
import { useBlockEditContext } from '../block-edit/context';
import useBlockSync from '../provider/use-block-sync';
import { defaultLayout, LayoutProvider } from './layout';

/**
* InnerBlocks is a component which allows a single block to have multiple blocks
Expand All @@ -49,6 +50,7 @@ function UncontrolledInnerBlocks( props ) {
renderAppender,
orientation,
placeholder,
__experimentalLayout: layout = defaultLayout,
} = props;

useNestedSettingsUpdate(
Expand Down Expand Up @@ -83,15 +85,19 @@ function UncontrolledInnerBlocks( props ) {
// This component needs to always be synchronous as it's the one changing
// the async mode depending on the block selection.
return (
<BlockContextProvider value={ context }>
<BlockListItems
rootClientId={ clientId }
renderAppender={ renderAppender }
__experimentalAppenderTagName={ __experimentalAppenderTagName }
wrapperRef={ wrapperRef }
placeholder={ placeholder }
/>
</BlockContextProvider>
<LayoutProvider value={ layout }>
<BlockContextProvider value={ context }>
<BlockListItems
rootClientId={ clientId }
renderAppender={ renderAppender }
__experimentalAppenderTagName={
__experimentalAppenderTagName
}
wrapperRef={ wrapperRef }
placeholder={ placeholder }
/>
</BlockContextProvider>
</LayoutProvider>
);
}

Expand Down
20 changes: 20 additions & 0 deletions packages/block-editor/src/components/inner-blocks/layout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* WordPress dependencies
*/
import { createContext, useContext } from '@wordpress/element';

export const defaultLayout = { type: 'default' };

const Layout = createContext( defaultLayout );

/**
* Allows to define the layout.
*/
export const LayoutProvider = Layout.Provider;

/**
* React hook used to retrieve the layout config.
*/
export function useLayout() {
return useContext( Layout );
}
24 changes: 7 additions & 17 deletions packages/block-editor/src/hooks/align.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { has, without } from 'lodash';
/**
* WordPress dependencies
*/
import { createContext, useContext } from '@wordpress/element';
import { createHigherOrderComponent } from '@wordpress/compose';
import { addFilter } from '@wordpress/hooks';
import {
Expand Down Expand Up @@ -106,13 +105,6 @@ export function addAttribute( settings ) {
return settings;
}

const AlignmentHookSettings = createContext( {} );

/**
* Allows to pass additional settings to the alignment hook.
*/
export const AlignmentHookSettingsProvider = AlignmentHookSettings.Provider;

/**
* Override the default edit UI to include new toolbar controls for block
* alignment, if block defines support.
Expand All @@ -122,17 +114,15 @@ export const AlignmentHookSettingsProvider = AlignmentHookSettings.Provider;
*/
export const withToolbarControls = createHigherOrderComponent(
( BlockEdit ) => ( props ) => {
const { isEmbedButton } = useContext( AlignmentHookSettings );
const { name: blockName } = props;
// Compute valid alignments without taking into account,
// if the theme supports wide alignments or not.
// BlockAlignmentToolbar takes into account the theme support.
const validAlignments = isEmbedButton
? []
: getValidAlignments(
getBlockSupport( blockName, 'align' ),
hasBlockSupport( blockName, 'alignWide', true )
);
// if the theme supports wide alignments or not
// and without checking the layout for availble alignments.
// BlockAlignmentToolbar takes both of these into account.
const validAlignments = getValidAlignments(
getBlockSupport( blockName, 'align' ),
hasBlockSupport( blockName, 'alignWide', true )
);

const updateAlignment = ( nextAlign ) => {
if ( ! nextAlign ) {
Expand Down
2 changes: 0 additions & 2 deletions packages/block-editor/src/hooks/align.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ import { WIDE_ALIGNMENTS } from '@wordpress/components';

const ALIGNMENTS = [ 'left', 'center', 'right' ];

export { AlignmentHookSettingsProvider } from './align.js';

// Used to filter out blocks that don't support wide/full alignment on mobile
addFilter(
'blocks.registerBlockType',
Expand Down
4 changes: 1 addition & 3 deletions packages/block-editor/src/hooks/index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
/**
* Internal dependencies
*/
import { AlignmentHookSettingsProvider } from './align';
import './align';
import './anchor';
import './custom-class-name';
import './generated-class-name';
import './style';
import './color';
import './font-size';

export { AlignmentHookSettingsProvider };
4 changes: 1 addition & 3 deletions packages/block-editor/src/hooks/index.native.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
/**
* Internal dependencies
*/
import { AlignmentHookSettingsProvider } from './align';
import './align';
import './anchor';
import './custom-class-name';
import './generated-class-name';
import './style';
import './color';
import './font-size';

export { AlignmentHookSettingsProvider };
3 changes: 1 addition & 2 deletions packages/block-editor/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ import '@wordpress/notices';
/**
* Internal dependencies
*/
import { AlignmentHookSettingsProvider as __experimentalAlignmentHookSettingsProvider } from './hooks';
export { __experimentalAlignmentHookSettingsProvider };
import './hooks';
export * from './components';
export * from './utils';
export { storeConfig } from './store';
Expand Down
16 changes: 5 additions & 11 deletions packages/block-library/src/buttons/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
* WordPress dependencies
*/
import {
__experimentalAlignmentHookSettingsProvider as AlignmentHookSettingsProvider,
__experimentalUseInnerBlocksProps as useInnerBlocksProps,
useBlockProps,
} from '@wordpress/block-editor';
Expand All @@ -15,23 +14,18 @@ import { name as buttonBlockName } from '../button/';
const ALLOWED_BLOCKS = [ buttonBlockName ];
const BUTTONS_TEMPLATE = [ [ 'core/button' ] ];

// Inside buttons block alignment options are not supported.
const alignmentHooksSetting = {
isEmbedButton: true,
};

function ButtonsEdit() {
const blockProps = useBlockProps();
const innerBlocksProps = useInnerBlocksProps( blockProps, {
allowedBlocks: ALLOWED_BLOCKS,
template: BUTTONS_TEMPLATE,
orientation: 'horizontal',
__experimentalLayout: {
type: 'default',
alignments: [],
},
} );
return (
<AlignmentHookSettingsProvider value={ alignmentHooksSetting }>
<div { ...innerBlocksProps } />
</AlignmentHookSettingsProvider>
);
return <div { ...innerBlocksProps } />;
}

export default ButtonsEdit;
15 changes: 4 additions & 11 deletions packages/block-library/src/buttons/edit.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@ import { View } from 'react-native';
/**
* WordPress dependencies
*/
import {
__experimentalAlignmentHookSettingsProvider as AlignmentHookSettingsProvider,
InnerBlocks,
} from '@wordpress/block-editor';
import { InnerBlocks } from '@wordpress/block-editor';
import { createBlock } from '@wordpress/blocks';
import { useResizeObserver } from '@wordpress/compose';
import { useDispatch, useSelect } from '@wordpress/data';
Expand Down Expand Up @@ -97,15 +94,10 @@ export default function ButtonsEdit( {
</View>
) );

// Inside buttons block alignment options are not supported.
const alignmentHooksSetting = {
isEmbedButton: true,
};

const shouldRenderFooterAppender = isSelected || isInnerButtonSelected;

return (
<AlignmentHookSettingsProvider value={ alignmentHooksSetting }>
<>
{ resizeObserver }
<InnerBlocks
allowedBlocks={ ALLOWED_BLOCKS }
Expand All @@ -122,7 +114,8 @@ export default function ButtonsEdit( {
parentWidth={ maxWidth }
marginHorizontal={ spacing }
marginVertical={ spacing }
__experimentalLayout={ { type: 'default', alignments: [] } }
/>
</AlignmentHookSettingsProvider>
</>
);
}

0 comments on commit 9db2619

Please sign in to comment.