Skip to content

Commit

Permalink
Try inserting blocks directly in empty grid cells (WordPress#63108)
Browse files Browse the repository at this point in the history
Co-authored-by: tellthemachines <isabel_brison@git.wordpress.org>
Co-authored-by: noisysocks <noisysocks@git.wordpress.org>
Co-authored-by: jasmussen <joen@git.wordpress.org>
Co-authored-by: andrewserong <andrewserong@git.wordpress.org>
Co-authored-by: liviopv <liviopv@git.wordpress.org>
  • Loading branch information
6 people authored and carstingaxion committed Jul 18, 2024
1 parent 375dbad commit 611ba72
Show file tree
Hide file tree
Showing 11 changed files with 296 additions and 82 deletions.
3 changes: 2 additions & 1 deletion backport-changelog/6.7/6910.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ https://github.com/WordPress/wordpress-develop/pull/6910

* https://github.com/WordPress/gutenberg/pull/59483
* https://github.com/WordPress/gutenberg/pull/60652
* https://github.com/WordPress/gutenberg/pull/62777
* https://github.com/WordPress/gutenberg/pull/62777
* https://github.com/WordPress/gutenberg/pull/63108
4 changes: 2 additions & 2 deletions lib/block-supports/layout.php
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@ function gutenberg_get_layout_style( $selector, $layout, $has_block_gap_support
if ( ! empty( $layout['rowCount'] ) ) {
$layout_styles[] = array(
'selector' => $selector,
'declarations' => array( 'grid-template-rows' => 'repeat(' . $layout['rowCount'] . ', minmax(8px, auto))' ),
'declarations' => array( 'grid-template-rows' => 'repeat(' . $layout['rowCount'] . ', minmax(1rem, auto))' ),
);
}
} elseif ( ! empty( $layout['columnCount'] ) ) {
Expand All @@ -512,7 +512,7 @@ function gutenberg_get_layout_style( $selector, $layout, $has_block_gap_support
if ( ! empty( $layout['rowCount'] ) ) {
$layout_styles[] = array(
'selector' => $selector,
'declarations' => array( 'grid-template-rows' => 'repeat(' . $layout['rowCount'] . ', minmax(8px, auto))' ),
'declarations' => array( 'grid-template-rows' => 'repeat(' . $layout['rowCount'] . ', minmax(1rem, auto))' ),
);
}
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,15 @@ import deprecated from '@wordpress/deprecated';
import Inserter from '../inserter';

function ButtonBlockAppender(
{ rootClientId, className, onFocus, tabIndex },
{ rootClientId, className, onFocus, tabIndex, onSelect },
ref
) {
return (
<Inserter
position="bottom center"
rootClientId={ rootClientId }
__experimentalIsQuick
onSelectOrClose={ onSelect }
renderToggle={ ( {
onToggle,
disabled,
Expand Down
223 changes: 170 additions & 53 deletions packages/block-editor/src/components/grid/grid-visualizer.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import clsx from 'clsx';
/**
* WordPress dependencies
*/
import { useState, useEffect, forwardRef } from '@wordpress/element';
import { useState, useEffect, forwardRef, useMemo } from '@wordpress/element';
import { useSelect, useDispatch } from '@wordpress/data';
import { __experimentalUseDropZone as useDropZone } from '@wordpress/compose';

Expand All @@ -18,6 +18,7 @@ import BlockPopoverCover from '../block-popover/cover';
import { range, GridRect, getGridInfo } from './utils';
import { store as blockEditorStore } from '../../store';
import { useGetNumberOfBlocksBeforeCell } from './use-get-number-of-blocks-before-cell';
import ButtonBlockAppender from '../button-block-appender';

export function GridVisualizer( { clientId, contentRef, parentLayout } ) {
const isDistractionFree = useSelect(
Expand All @@ -36,7 +37,7 @@ export function GridVisualizer( { clientId, contentRef, parentLayout } ) {
window.__experimentalEnableGridInteractivity;
return (
<GridVisualizerGrid
clientId={ clientId }
gridClientId={ clientId }
gridElement={ gridElement }
isManualGrid={ isManualGrid }
ref={ contentRef }
Expand All @@ -45,12 +46,11 @@ export function GridVisualizer( { clientId, contentRef, parentLayout } ) {
}

const GridVisualizerGrid = forwardRef(
( { clientId, gridElement, isManualGrid }, ref ) => {
( { gridClientId, gridElement, isManualGrid }, ref ) => {
const [ gridInfo, setGridInfo ] = useState( () =>
getGridInfo( gridElement )
);
const [ isDroppingAllowed, setIsDroppingAllowed ] = useState( false );
const [ highlightedRect, setHighlightedRect ] = useState( null );

useEffect( () => {
const observers = [];
Expand Down Expand Up @@ -88,75 +88,126 @@ const GridVisualizerGrid = forwardRef(
className={ clsx( 'block-editor-grid-visualizer', {
'is-dropping-allowed': isDroppingAllowed,
} ) }
clientId={ clientId }
clientId={ gridClientId }
__unstablePopoverSlot="block-toolbar"
>
<div
ref={ ref }
className="block-editor-grid-visualizer__grid"
style={ gridInfo.style }
>
{ isManualGrid
? range( 1, gridInfo.numRows ).map( ( row ) =>
range( 1, gridInfo.numColumns ).map(
( column ) => (
<GridVisualizerCell
key={ `${ row }-${ column }` }
color={ gridInfo.currentColor }
>
<GridVisualizerDropZone
column={ column }
row={ row }
gridClientId={ clientId }
gridInfo={ gridInfo }
highlightedRect={
highlightedRect
}
setHighlightedRect={
setHighlightedRect
}
/>
</GridVisualizerCell>
)
)
)
: Array.from(
{ length: gridInfo.numItems },
( _, i ) => (
<GridVisualizerCell
key={ i }
color={ gridInfo.currentColor }
/>
)
) }
{ isManualGrid ? (
<ManualGridVisualizer
gridClientId={ gridClientId }
gridInfo={ gridInfo }
/>
) : (
Array.from( { length: gridInfo.numItems }, ( _, i ) => (
<GridVisualizerCell
key={ i }
color={ gridInfo.currentColor }
/>
) )
) }
</div>
</BlockPopoverCover>
);
}
);

function GridVisualizerCell( { color, children } ) {
function ManualGridVisualizer( { gridClientId, gridInfo } ) {
const [ highlightedRect, setHighlightedRect ] = useState( null );

const gridItems = useSelect(
( select ) => select( blockEditorStore ).getBlocks( gridClientId ),
[ gridClientId ]
);
const occupiedRects = useMemo( () => {
const rects = [];
for ( const block of gridItems ) {
const {
columnStart,
rowStart,
columnSpan = 1,
rowSpan = 1,
} = block.attributes.style?.layout || {};
if ( ! columnStart || ! rowStart ) {
continue;
}
rects.push(
new GridRect( {
columnStart,
rowStart,
columnSpan,
rowSpan,
} )
);
}
return rects;
}, [ gridItems ] );

return range( 1, gridInfo.numRows ).map( ( row ) =>
range( 1, gridInfo.numColumns ).map( ( column ) => {
const isCellOccupied = occupiedRects.some( ( rect ) =>
rect.contains( column, row )
);
const isHighlighted =
highlightedRect?.contains( column, row ) ?? false;
return (
<GridVisualizerCell
key={ `${ row }-${ column }` }
color={ gridInfo.currentColor }
className={ isHighlighted && 'is-highlighted' }
>
{ isCellOccupied ? (
<GridVisualizerDropZone
column={ column }
row={ row }
gridClientId={ gridClientId }
gridInfo={ gridInfo }
setHighlightedRect={ setHighlightedRect }
/>
) : (
<GridVisualizerAppender
column={ column }
row={ row }
gridClientId={ gridClientId }
gridInfo={ gridInfo }
setHighlightedRect={ setHighlightedRect }
/>
) }
</GridVisualizerCell>
);
} )
);
}

function GridVisualizerCell( { color, children, className } ) {
return (
<div
className="block-editor-grid-visualizer__cell"
className={ clsx(
'block-editor-grid-visualizer__cell',
className
) }
style={ {
boxShadow: `inset 0 0 0 1px color-mix(in srgb, ${ color } 20%, #0000)`,
color,
} }
>
{ children }
</div>
);
}

function GridVisualizerDropZone( {
function useGridVisualizerDropZone(
column,
row,
gridClientId,
gridInfo,
highlightedRect,
setHighlightedRect,
} ) {
const { getBlockAttributes } = useSelect( blockEditorStore );
setHighlightedRect
) {
const { getBlockAttributes, getBlockRootClientId } =
useSelect( blockEditorStore );
const {
updateBlockAttributes,
moveBlocksToPosition,
Expand All @@ -168,7 +219,7 @@ function GridVisualizerDropZone( {
gridInfo.numColumns
);

const ref = useDropZoneWithValidation( {
return useDropZoneWithValidation( {
validateDrag( srcClientId ) {
const attributes = getBlockAttributes( srcClientId );
const rect = new GridRect( {
Expand Down Expand Up @@ -221,21 +272,87 @@ function GridVisualizerDropZone( {
__unstableMarkNextChangeAsNotPersistent();
moveBlocksToPosition(
[ srcClientId ],
gridClientId,
getBlockRootClientId( srcClientId ),
gridClientId,
getNumberOfBlocksBeforeCell( column, row )
);
},
} );
}

const isHighlighted = highlightedRect?.contains( column, row ) ?? false;

function GridVisualizerDropZone( {
column,
row,
gridClientId,
gridInfo,
setHighlightedRect,
} ) {
return (
<div
ref={ ref }
className={ clsx( 'block-editor-grid-visualizer__drop-zone', {
'is-highlighted': isHighlighted,
} ) }
className="block-editor-grid-visualizer__drop-zone"
ref={ useGridVisualizerDropZone(
column,
row,
gridClientId,
gridInfo,
setHighlightedRect
) }
/>
);
}

function GridVisualizerAppender( {
column,
row,
gridClientId,
gridInfo,
setHighlightedRect,
} ) {
const {
updateBlockAttributes,
moveBlocksToPosition,
__unstableMarkNextChangeAsNotPersistent,
} = useDispatch( blockEditorStore );

const getNumberOfBlocksBeforeCell = useGetNumberOfBlocksBeforeCell(
gridClientId,
gridInfo.numColumns
);

return (
<ButtonBlockAppender
rootClientId={ gridClientId }
className="block-editor-grid-visualizer__appender"
ref={ useGridVisualizerDropZone(
column,
row,
gridClientId,
gridInfo,
setHighlightedRect
) }
style={ {
color: gridInfo.currentColor,
} }
onSelect={ ( block ) => {
if ( ! block ) {
return;
}
updateBlockAttributes( block.clientId, {
style: {
layout: {
columnStart: column,
rowStart: row,
},
},
} );
__unstableMarkNextChangeAsNotPersistent();
moveBlocksToPosition(
[ block.clientId ],
gridClientId,
gridClientId,
getNumberOfBlocksBeforeCell( column, row )
);
} }
/>
);
}
Expand Down
Loading

0 comments on commit 611ba72

Please sign in to comment.