Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Grid interactivity: Allow blocks to be positioned in manual mode using drag and drop #61025

Merged
merged 31 commits into from
Jun 25, 2024
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
539bb86
Try version of grid where manual mode means all blocks have a columnS…
noisysocks Apr 24, 2024
37ff369
Fix some rebase breakage
tellthemachines Jun 14, 2024
b3e7d95
Clean up deleted files
tellthemachines Jun 14, 2024
eb732d1
Fix visualiser
tellthemachines Jun 14, 2024
6b72367
fix booboos
tellthemachines Jun 14, 2024
73b821a
Show appender on manual grid
tellthemachines Jun 14, 2024
9dff09b
Fix row situation when converting from auto to manual
tellthemachines Jun 17, 2024
eef95b2
Set row attribute
tellthemachines Jun 18, 2024
ef056c1
markup reordering on drag and drop
tellthemachines Jun 19, 2024
ca959da
Reorder markup when using movers
tellthemachines Jun 19, 2024
4ac5e9d
Jump through a few hoops
tellthemachines Jun 20, 2024
881af91
Only show sidebar row/col start controls in manual mode.
tellthemachines Jun 20, 2024
5f6e8d7
Fix string concatenation bugs
tellthemachines Jun 20, 2024
249549b
Undo folder rename
tellthemachines Jun 21, 2024
86f0c1c
Fix inserters for different grid types
tellthemachines Jun 21, 2024
fa2b066
Allow overlap
tellthemachines Jun 21, 2024
28ab6b9
Update file path
tellthemachines Jun 21, 2024
29e97e1
Fix undo weirdness
tellthemachines Jun 24, 2024
e2b2897
Fix col and row start on resize
tellthemachines Jun 24, 2024
b79494d
Put back isDistractionFree check
noisysocks Jun 24, 2024
81623d5
Use ternary
noisysocks Jun 24, 2024
2b2e16a
Try to escape indent hell
noisysocks Jun 24, 2024
9621ddb
Fix things for non-experimental mode
tellthemachines Jun 24, 2024
2062300
Fix block movers when experiment disabled
tellthemachines Jun 24, 2024
f1141af
Refactor useGetBlocksBeforeCurrentCell to useGetNumberOfBlocksBeforeC…
noisysocks Jun 25, 2024
3455e3c
remove todo comment
tellthemachines Jun 25, 2024
51de6e8
Tidy useGridLayoutSync
noisysocks Jun 25, 2024
f1f82b2
Fix class name typo
noisysocks Jun 25, 2024
c12b098
Fix toggle label
tellthemachines Jun 25, 2024
c80ce4d
Bring back range control when experiment is disabled
tellthemachines Jun 25, 2024
d982fdf
Fix min rows needed when items span multiple cells
tellthemachines Jun 25, 2024
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
63 changes: 39 additions & 24 deletions packages/block-editor/src/components/block-mover/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,22 @@ function BlockMover( {
isBlockMoverUpButtonDisabled,
isBlockMoverDownButtonDisabled,
} ) {
const { canMove, rootClientId, isFirst, isLast, orientation } = useSelect(
const {
canMove,
rootClientId,
isFirst,
isLast,
orientation,
isManualGrid,
} = useSelect(
( select ) => {
const {
getBlockIndex,
getBlockListSettings,
canMoveBlocks,
getBlockOrder,
getBlockRootClientId,
getBlockAttributes,
} = select( blockEditorStore );
const normalizedClientIds = Array.isArray( clientIds )
? clientIds
Expand All @@ -44,13 +52,20 @@ function BlockMover( {
normalizedClientIds[ normalizedClientIds.length - 1 ]
);
const blockOrder = getBlockOrder( _rootClientId );
const { layout = {} } = getBlockAttributes( _rootClientId ) ?? {};

return {
canMove: canMoveBlocks( clientIds, _rootClientId ),
rootClientId: _rootClientId,
isFirst: firstIndex === 0,
isLast: lastIndex === blockOrder.length - 1,
orientation: getBlockListSettings( _rootClientId )?.orientation,
// TODO: Doesn't feel great to couple BlockMover and grid layouts.
// TODO: Can we use useLayout() instead?
tellthemachines marked this conversation as resolved.
Show resolved Hide resolved
isManualGrid:
layout.type === 'grid' &&
!! layout.columnCount &&
window.__experimentalEnableGridInteractivity,
};
},
[ clientIds ]
Expand All @@ -60,8 +75,6 @@ function BlockMover( {
return null;
}

const dragHandleLabel = __( 'Drag' );

return (
<ToolbarGroup
className={ clsx( 'block-editor-block-mover', {
Expand All @@ -75,7 +88,7 @@ function BlockMover( {
icon={ dragHandle }
className="block-editor-block-mover__drag-handle"
aria-hidden="true"
label={ dragHandleLabel }
label={ __( 'Drag' ) }
// Should not be able to tab to drag handle as this
// button can only be used with a pointer device.
tabIndex="-1"
Expand All @@ -84,26 +97,28 @@ function BlockMover( {
) }
</BlockDraggable>
) }
<div className="block-editor-block-mover__move-button-container">
<ToolbarItem>
{ ( itemProps ) => (
<BlockMoverUpButton
disabled={ isBlockMoverUpButtonDisabled }
clientIds={ clientIds }
{ ...itemProps }
/>
) }
</ToolbarItem>
<ToolbarItem>
{ ( itemProps ) => (
<BlockMoverDownButton
disabled={ isBlockMoverDownButtonDisabled }
clientIds={ clientIds }
{ ...itemProps }
/>
) }
</ToolbarItem>
</div>
{ ! isManualGrid && (
<div className="block-editor-block-mover__move-button-container">
<ToolbarItem>
{ ( itemProps ) => (
<BlockMoverUpButton
disabled={ isBlockMoverUpButtonDisabled }
clientIds={ clientIds }
{ ...itemProps }
/>
) }
</ToolbarItem>
<ToolbarItem>
{ ( itemProps ) => (
<BlockMoverDownButton
disabled={ isBlockMoverDownButtonDisabled }
clientIds={ clientIds }
{ ...itemProps }
/>
) }
</ToolbarItem>
</div>
) }
</ToolbarGroup>
);
}
Expand Down
174 changes: 111 additions & 63 deletions packages/block-editor/src/components/child-layout-control/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ import {
} from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { useEffect } from '@wordpress/element';
import { useSelect, useDispatch } from '@wordpress/data';

/**
* Internal dependencies
*/
import { useGetBlocksBeforeCurrentCell } from '../grid-visualizer/use-get-blocks-before-current-cell';
import { store as blockEditorStore } from '../../store';

function helpText( selfStretch, parentLayout ) {
const { orientation = 'horizontal' } = parentLayout;
Expand Down Expand Up @@ -60,9 +67,20 @@ export default function ChildLayoutControl( {
type: parentType,
default: { type: defaultParentType = 'default' } = {},
orientation = 'horizontal',
columnCount,
} = parentLayout ?? {};
const parentLayoutType = parentType || defaultParentType;

const gridColumnNumber = parseInt( columnCount, 10 ) || 3;
const rootClientId = useSelect( ( select ) =>
select( blockEditorStore ).getBlockRootClientId( panelId )
);
const { moveBlocksToPosition, __unstableMarkNextChangeAsNotPersistent } =
useDispatch( blockEditorStore );
const getBlocksBeforeCurrentCell = useGetBlocksBeforeCurrentCell(
Copy link
Contributor

Choose a reason for hiding this comment

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

Welp, had to add a bunch of hooks here to be able to move the blocks in the markup order 😅
Not sure if there's a better way of doing this. A possible alternative would be not exposing these controls in the sidebar at all (which would mean keyboard manipulation would depend exclusively on the block movers, maybe not ideal)

rootClientId,
gridColumnNumber,
parentLayoutType === 'grid'
);
const hasFlexValue = () => !! selfStretch;
const flexResetLabel =
orientation === 'horizontal' ? __( 'Width' ) : __( 'Height' );
Expand Down Expand Up @@ -196,68 +214,98 @@ export default function ChildLayoutControl( {
min={ 1 }
/>
</HStack>
{ window.__experimentalEnableGridInteractivity && (
// Use Flex with an explicit width on the FlexItem instead of HStack to
// work around an issue in webkit where inputs with a max attribute are
// sized incorrectly.
<Flex
as={ ToolsPanelItem }
hasValue={ hasStartValue }
label={ __( 'Grid placement' ) }
onDeselect={ resetGridStarts }
isShownByDefault={ false }
panelId={ panelId }
>
<FlexItem style={ { width: '50%' } }>
<InputControl
size="__unstable-large"
label={ __( 'Column' ) }
type="number"
onChange={ ( value ) => {
onChange( {
columnStart: value,
rowStart,
columnSpan,
rowSpan,
} );
} }
value={ columnStart }
min={ 1 }
max={
parentLayout?.columnCount
? parentLayout.columnCount -
( columnSpan ?? 1 ) +
1
: undefined
}
/>
</FlexItem>
<FlexItem style={ { width: '50%' } }>
<InputControl
size="__unstable-large"
label={ __( 'Row' ) }
type="number"
onChange={ ( value ) => {
onChange( {
columnStart,
rowStart: value,
columnSpan,
rowSpan,
} );
} }
value={ rowStart }
min={ 1 }
max={
parentLayout?.rowCount
? parentLayout.rowCount -
( rowSpan ?? 1 ) +
1
: undefined
}
/>
</FlexItem>
</Flex>
) }
{ window.__experimentalEnableGridInteractivity &&
columnCount && (
// Use Flex with an explicit width on the FlexItem instead of HStack to
// work around an issue in webkit where inputs with a max attribute are
// sized incorrectly.
<Flex
as={ ToolsPanelItem }
hasValue={ hasStartValue }
label={ __( 'Grid placement' ) }
onDeselect={ resetGridStarts }
isShownByDefault={ false }
panelId={ panelId }
>
<FlexItem style={ { width: '50%' } }>
<InputControl
size="__unstable-large"
label={ __( 'Column' ) }
type="number"
onChange={ ( value ) => {
onChange( {
columnStart: value,
rowStart,
columnSpan,
rowSpan,
} );
const currentBlockIndex =
( parseInt( rowStart, 10 ) -
1 ) *
gridColumnNumber +
parseInt( value, 10 ) -
1;
__unstableMarkNextChangeAsNotPersistent();
moveBlocksToPosition(
[ panelId ],
rootClientId,
rootClientId,
getBlocksBeforeCurrentCell(
currentBlockIndex
)
);
} }
value={ columnStart }
min={ 1 }
max={
gridColumnNumber
? gridColumnNumber -
( columnSpan ?? 1 ) +
1
: undefined
}
/>
</FlexItem>
<FlexItem style={ { width: '50%' } }>
<InputControl
size="__unstable-large"
label={ __( 'Row' ) }
type="number"
onChange={ ( value ) => {
onChange( {
columnStart,
rowStart: value,
columnSpan,
rowSpan,
} );
const currentBlockIndex =
( parseInt( value, 10 ) - 1 ) *
gridColumnNumber +
parseInt( columnStart, 10 ) -
1;
__unstableMarkNextChangeAsNotPersistent();
moveBlocksToPosition(
[ panelId ],
rootClientId,
rootClientId,
getBlocksBeforeCurrentCell(
currentBlockIndex
)
);
} }
value={ rowStart }
min={ 1 }
max={
parentLayout?.rowCount
? parentLayout.rowCount -
( rowSpan ?? 1 ) +
1
: undefined
}
/>
</FlexItem>
</Flex>
) }
</>
) }
</>
Expand Down
Loading
Loading