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 Visualizer - improve styles #64321

Open
wants to merge 25 commits into
base: trunk
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
b74481f
Add support to root block list in `useBlockRefs`
talldan Aug 7, 2024
995d04d
Add basic underlay component
talldan Aug 7, 2024
c260c5f
Only render GridVisualizer above GridBlock and no longer on LayoutChi…
talldan Aug 7, 2024
e3ad0c3
Remove outdated comment
talldan Aug 7, 2024
210b233
Move padding to underlay to ensure it refreshes
talldan Aug 7, 2024
5f98335
Handle block moving
talldan Aug 7, 2024
ebcd385
Add a background for cells
talldan Aug 7, 2024
9e3b9ae
Use BlockPopoverCover with inline prop
talldan Aug 8, 2024
6c3b96a
Allow margin reset on inline popover via inline styles
talldan Aug 8, 2024
ca816ec
Override popover default z index
talldan Aug 8, 2024
6d078c6
Render two "grid visualizers", one under the block and one over-the o…
talldan Aug 8, 2024
8ff3a22
Revert change to root block list
talldan Aug 8, 2024
03c068e
Update grid styles
talldan Aug 9, 2024
628ffb1
Update appender styles
talldan Aug 9, 2024
1e4c9e7
Hide drop zone until active
talldan Aug 9, 2024
4386508
Improve highlight style
talldan Aug 9, 2024
37c4203
Refactor into separate GridPopunder / GridPopover components
talldan Aug 9, 2024
497eb0f
Fix resizer bounds
talldan Aug 9, 2024
3b4e9ae
Try for a smaller diff
talldan Aug 9, 2024
98cb5de
Rename GridVisualizerGrid, move occupiedRects
noisysocks Aug 12, 2024
ed7e1ed
Update grid css
talldan Aug 13, 2024
6139488
Move GridResizerBoundsContext.Provider rendering to `GridTools` and m…
talldan Aug 13, 2024
e1343e7
Use scss variables
talldan Aug 13, 2024
4620f5e
Rename popover prop to `style` instead of `contentStyle`
talldan Aug 13, 2024
f73ca9f
Fix: Resizer bounds not working for auto grids
talldan Aug 13, 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
2 changes: 1 addition & 1 deletion packages/base-styles/_z-index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ $z-layers: (
".block-editor-block-popover": 31,

// Below the block toolbar.
".block-editor-grid-visualizer": 30,
".block-editor-grid-visualizer-popover": 30,

// Show snackbars above everything (similar to popovers)
".components-snackbar-list": 100000,
Expand Down
127 changes: 90 additions & 37 deletions packages/block-editor/src/components/grid/grid-visualizer.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export function GridVisualizer( { clientId, contentRef, parentLayout } ) {
parentLayout?.isManualPlacement &&
window.__experimentalEnableGridInteractivity;
return (
<GridVisualizerGrid
<GridVisualizerUI
gridClientId={ clientId }
gridElement={ gridElement }
isManualGrid={ isManualGrid }
Expand All @@ -45,12 +45,11 @@ export function GridVisualizer( { clientId, contentRef, parentLayout } ) {
);
}

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

useEffect( () => {
const observers = [];
Expand All @@ -68,6 +67,38 @@ const GridVisualizerGrid = forwardRef(
};
}, [ gridElement ] );

return (
<>
<GridPopunder
gridClientId={ gridClientId }
gridInfo={ gridInfo }
isManualGrid={ isManualGrid }
/>
<GridPopover
ref={ ref }
gridClientId={ gridClientId }
gridInfo={ gridInfo }
isManualGrid={ isManualGrid }
/>
</>
);
}
);

/**
* A popover component that renders in a slot over the grid block.
*
* This provides interactive elements of the grid visualization —
* block inserters and drop zones.
*
* @param {Object} props
* @param {string} props.gridClientId
* @param {Object} props.gridInfo
*/
const GridPopover = forwardRef(
( { gridClientId, gridInfo, isManualGrid }, ref ) => {
const [ isDroppingAllowed, setIsDroppingAllowed ] = useState( false );

useEffect( () => {
function onGlobalDrag() {
setIsDroppingAllowed( true );
Expand All @@ -85,43 +116,32 @@ const GridVisualizerGrid = forwardRef(

return (
<BlockPopoverCover
className={ clsx( 'block-editor-grid-visualizer', {
__unstablePopoverSlot="__unstable-block-tools-after"
className={ clsx( 'block-editor-grid-visualizer-popover', {
'is-dropping-allowed': isDroppingAllowed,
} ) }
clientId={ gridClientId }
__unstablePopoverSlot="__unstable-block-tools-after"
>
<div
ref={ ref }
className="block-editor-grid-visualizer__grid"
style={ gridInfo.style }
>
{ isManualGrid ? (
<ManualGridVisualizer
<div ref={ ref } style={ gridInfo.style }>
{ isManualGrid && (
<ManualGridPopoverItems
gridClientId={ gridClientId }
gridInfo={ gridInfo }
/>
) : (
Array.from( { length: gridInfo.numItems }, ( _, i ) => (
<GridVisualizerCell
key={ i }
color={ gridInfo.currentColor }
/>
) )
) }
</div>
</BlockPopoverCover>
);
}
);

function ManualGridVisualizer( { gridClientId, gridInfo } ) {
function ManualGridPopoverItems( { 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 ) {
Expand Down Expand Up @@ -153,11 +173,16 @@ function ManualGridVisualizer( { gridClientId, gridInfo } ) {
);
const isHighlighted =
highlightedRect?.contains( column, row ) ?? false;

return (
<GridVisualizerCell
<div
key={ `${ row }-${ column }` }
color={ gridInfo.currentColor }
className={ isHighlighted && 'is-highlighted' }
className={ clsx(
'block-editor-grid-visualizer-popover__cell',
{
'is-highlighted': isHighlighted,
}
) }
>
{ isCellOccupied ? (
<GridVisualizerDropZone
Expand All @@ -176,26 +201,54 @@ function ManualGridVisualizer( { gridClientId, gridInfo } ) {
setHighlightedRect={ setHighlightedRect }
/>
) }
</GridVisualizerCell>
</div>
);
} )
);
}

function GridVisualizerCell( { color, children, className } ) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I decided to get rid of GridVisualizerCell as it wasn't doing very much, especially in GridPopover where it's just a <div>.

In GridPopunder it's a <div> with a some styles, so I think it still doesn't need its own component.

return (
<div
className={ clsx(
'block-editor-grid-visualizer__cell',
className
) }
style={ {
boxShadow: `inset 0 0 0 1px color-mix(in srgb, ${ color } 20%, #0000)`,
/**
* A popover component that renders inline under the grid block.
*
* This provides non-interactive elements of the grid visualization and
* renders under the block so that the background colors are not atop
* the block content.
*
* @param {Object} props
* @param {string} props.gridClientId
* @param {Object} props.gridInfo
* @param {boolean} props.isManualGrid
*/
function GridPopunder( { gridClientId, gridInfo, isManualGrid } ) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

GridPopunder (not sure if the name is too twee) now renders the blue cells in the background. It's pretty similar to the auto mode cells in trunk in terms of code.

const color = gridInfo.currentColor;
const cellStyle = isManualGrid
? {
backgroundColor: `rgba(var(--wp-admin-theme-color--rgb), 0.2)`,
border: `1px dashed rgb(var(--wp-admin-theme-color--rgb))`,
borderRadius: '2px',
color,
} }
opacity: 0.2,
}
: {
border: `1px dashed ${ color }`,
borderRadius: '2px',
color,
opacity: 0.2,
};

return (
<BlockPopoverCover
inline
clientId={ gridClientId }
// Override layout margin and popover's zIndex.
style={ { margin: 0, zIndex: 0 } }
>
{ children }
</div>
<div style={ gridInfo.style }>
{ Array.from( { length: gridInfo.numItems }, ( _, i ) => (
<div key={ i } style={ cellStyle } />
) ) }
</div>
</BlockPopoverCover>
);
}

Expand Down
31 changes: 18 additions & 13 deletions packages/block-editor/src/components/grid/style.scss
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
.block-editor-grid-visualizer {
.block-editor-grid-visualizer-popover {
// Specificity to override the z-index and pointer-events set by .components-popover.
&.block-editor-grid-visualizer.block-editor-grid-visualizer {
z-index: z-index(".block-editor-grid-visualizer");
&.block-editor-grid-visualizer-popover.block-editor-grid-visualizer-popover {
z-index: z-index(".block-editor-grid-visualizer-popover");

.components-popover__content * {
pointer-events: none;
Expand All @@ -18,11 +18,7 @@
}
}

.block-editor-grid-visualizer__grid {
display: grid;
}

.block-editor-grid-visualizer__cell {
.block-editor-grid-visualizer-popover__cell {
display: grid;
position: relative;

Expand All @@ -37,7 +33,7 @@
overflow: hidden;

.block-editor-grid-visualizer__appender {
box-shadow: inset 0 0 0 1px color-mix(in srgb, currentColor 20%, #0000);
box-shadow: none;
color: inherit;
overflow: hidden;
height: 100%;
Expand All @@ -48,17 +44,26 @@

}

.block-editor-grid-visualizer__drop-zone {
opacity: 0;
}

&.is-highlighted {
.block-editor-inserter,
.block-editor-grid-visualizer__drop-zone {
background: var(--wp-admin-theme-color);
background: rgba(var(--wp-admin-theme-color--rgb), 0.25);
border: $border-width solid var(--wp-admin-theme-color);
}
}

&:hover .block-editor-grid-visualizer__appender,
.block-editor-grid-visualizer__appender:focus {
opacity: 1;
background-color: color-mix(in srgb, currentColor 20%, #0000);
box-shadow: none;
background-color: rgba(var(--wp-admin-theme-color--rgb), 0.05);
border: $border-width dashed;
border-radius: $radius-small;
color: var(--wp-admin-theme-color);
}
}

Expand All @@ -77,7 +82,7 @@
.block-editor-grid-item-resizer {
// Specificity to override the z-index and pointer-events set by .components-popover.
&.block-editor-grid-item-resizer.block-editor-grid-item-resizer {
z-index: z-index(".block-editor-grid-visualizer");
z-index: z-index(".block-editor-grid-visualizer-popover");

.components-popover__content * {
pointer-events: none;
Expand Down Expand Up @@ -117,7 +122,7 @@
content: "";
position: absolute;
display: block;
border-radius: $radius-block-ui;
border-radius: $radius-small;
height: $grid-unit-40;

// Position the focus rectangle.
Expand Down
1 change: 1 addition & 0 deletions packages/block-editor/src/components/grid/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ export function getGridInfo( gridElement ) {
gridTemplateColumns,
gridTemplateRows,
gap: getComputedCSS( gridElement, 'gap' ),
display: 'grid',
padding: getComputedCSS( gridElement, 'padding' ),
},
};
Expand Down
40 changes: 26 additions & 14 deletions packages/block-editor/src/hooks/grid-visualizer.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,48 @@
import { createHigherOrderComponent } from '@wordpress/compose';
import { addFilter } from '@wordpress/hooks';
import { useSelect } from '@wordpress/data';
import { createContext, useState } from '@wordpress/element';

/**
* Internal dependencies
*/
import { GridVisualizer, useGridLayoutSync } from '../components/grid';
import { store as blockEditorStore } from '../store';

export const GridResizerBoundsContext = createContext();

function GridLayoutSync( props ) {
useGridLayoutSync( props );
}

function GridTools( { clientId, layout } ) {
const { isSelected, isDragging } = useSelect( ( select ) => {
const { isBlockSelected, isDraggingBlocks } =
function GridTools( { clientId, layout, children } ) {
const { hasSelection, isDragging } = useSelect( ( select ) => {
const { isBlockSelected, hasSelectedInnerBlock, isDraggingBlocks } =
select( blockEditorStore );

return {
isSelected: isBlockSelected( clientId ),
hasSelection:
isBlockSelected( clientId ) ||
hasSelectedInnerBlock( clientId ),
isDragging: isDraggingBlocks(),
};
} );

// Use useState() instead of useRef() so that GridItemResizer updates when ref is set.
const [ resizerBounds, setResizerBounds ] = useState();

return (
<>
<GridResizerBoundsContext.Provider value={ resizerBounds }>
<GridLayoutSync clientId={ clientId } />
{ ( isSelected || isDragging ) && (
<GridVisualizer clientId={ clientId } parentLayout={ layout } />
{ ( hasSelection || isDragging ) && (
<GridVisualizer
clientId={ clientId }
parentLayout={ layout }
contentRef={ setResizerBounds }
/>
) }
</>
{ children }
</GridResizerBoundsContext.Provider>
);
}

Expand All @@ -43,13 +56,12 @@ const addGridVisualizerToBlockEdit = createHigherOrderComponent(
}

return (
<>
<GridTools
clientId={ props.clientId }
layout={ props.attributes.layout }
/>
<GridTools
clientId={ props.clientId }
layout={ props.attributes.layout }
>
<BlockEdit key="edit" { ...props } />
</>
</GridTools>
);
},
'addGridVisualizerToBlockEdit'
Expand Down
Loading
Loading