-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Adapt flex child controls for Spacer. #49362
Changes from all commits
b833bff
c709721
e3d1364
7d751d2
de0f39b
adcc4f8
f64baf7
8f1c8f9
1a3623c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -8,6 +8,8 @@ import classnames from 'classnames'; | |||
*/ | ||||
import { | ||||
useBlockProps, | ||||
useSetting, | ||||
getCustomValueFromPreset, | ||||
getSpacingPresetCssVar, | ||||
store as blockEditorStore, | ||||
} from '@wordpress/block-editor'; | ||||
|
@@ -92,13 +94,20 @@ const SpacerEdit = ( { | |||
} ); | ||||
const { orientation } = context; | ||||
const { orientation: parentOrientation, type } = parentLayout || {}; | ||||
// Check if the spacer is inside a flex container. | ||||
const isFlexLayout = type === 'flex'; | ||||
// If the spacer is inside a flex container, it should either inherit the orientation | ||||
// of the parent or use the flex default orientation. | ||||
const inheritedOrientation = | ||||
! parentOrientation && type === 'flex' | ||||
! parentOrientation && isFlexLayout | ||||
? 'horizontal' | ||||
: parentOrientation || orientation; | ||||
const { height, width } = attributes; | ||||
const { height, width, style: blockStyle = {} } = attributes; | ||||
|
||||
const { layout = {} } = blockStyle; | ||||
const { selfStretch, flexSize } = layout; | ||||
|
||||
const spacingSizes = useSetting( 'spacing.spacingSizes' ); | ||||
|
||||
const [ isResizing, setIsResizing ] = useState( false ); | ||||
const [ temporaryHeight, setTemporaryHeight ] = useState( null ); | ||||
|
@@ -110,32 +119,80 @@ const SpacerEdit = ( { | |||
const handleOnVerticalResizeStop = ( newHeight ) => { | ||||
onResizeStop(); | ||||
|
||||
if ( isFlexLayout ) { | ||||
setAttributes( { | ||||
style: { | ||||
...blockStyle, | ||||
layout: { | ||||
...layout, | ||||
flexSize: newHeight, | ||||
selfStretch: 'fixed', | ||||
}, | ||||
}, | ||||
} ); | ||||
} | ||||
|
||||
setAttributes( { height: newHeight } ); | ||||
setTemporaryHeight( null ); | ||||
}; | ||||
|
||||
const handleOnHorizontalResizeStop = ( newWidth ) => { | ||||
onResizeStop(); | ||||
|
||||
if ( isFlexLayout ) { | ||||
setAttributes( { | ||||
style: { | ||||
...blockStyle, | ||||
layout: { | ||||
...layout, | ||||
flexSize: newWidth, | ||||
selfStretch: 'fixed', | ||||
}, | ||||
}, | ||||
} ); | ||||
} | ||||
|
||||
setAttributes( { width: newWidth } ); | ||||
setTemporaryWidth( null ); | ||||
}; | ||||
|
||||
const getHeightForVerticalBlocks = () => { | ||||
if ( isFlexLayout ) { | ||||
return undefined; | ||||
} | ||||
return temporaryHeight || getSpacingPresetCssVar( height ) || undefined; | ||||
}; | ||||
|
||||
const getWidthForHorizontalBlocks = () => { | ||||
if ( isFlexLayout ) { | ||||
return undefined; | ||||
} | ||||
return temporaryWidth || getSpacingPresetCssVar( width ) || undefined; | ||||
}; | ||||
|
||||
const sizeConditionalOnOrientation = | ||||
inheritedOrientation === 'horizontal' | ||||
? temporaryWidth || flexSize | ||||
: temporaryHeight || flexSize; | ||||
|
||||
const style = { | ||||
height: | ||||
inheritedOrientation === 'horizontal' | ||||
? 24 | ||||
: temporaryHeight || | ||||
getSpacingPresetCssVar( height ) || | ||||
undefined, | ||||
: getHeightForVerticalBlocks(), | ||||
width: | ||||
inheritedOrientation === 'horizontal' | ||||
? temporaryWidth || getSpacingPresetCssVar( width ) || undefined | ||||
? getWidthForHorizontalBlocks() | ||||
: undefined, | ||||
// In vertical flex containers, the spacer shrinks to nothing without a minimum width. | ||||
minWidth: | ||||
inheritedOrientation === 'vertical' && type === 'flex' | ||||
inheritedOrientation === 'vertical' && isFlexLayout | ||||
? 48 | ||||
: undefined, | ||||
// Add flex-basis so temporary sizes are respected. | ||||
flexBasis: isFlexLayout ? sizeConditionalOnOrientation : undefined, | ||||
// Remove flex-grow when resizing. | ||||
flexGrow: isFlexLayout && isResizing ? 0 : undefined, | ||||
}; | ||||
|
||||
const resizableBoxWithOrientation = ( blockOrientation ) => { | ||||
|
@@ -191,13 +248,93 @@ const SpacerEdit = ( { | |||
}; | ||||
|
||||
useEffect( () => { | ||||
if ( inheritedOrientation === 'horizontal' && ! width ) { | ||||
if ( | ||||
isFlexLayout && | ||||
selfStretch !== 'fill' && | ||||
selfStretch !== 'fit' && | ||||
! flexSize | ||||
) { | ||||
if ( inheritedOrientation === 'horizontal' ) { | ||||
// If spacer is moving from a vertical container to a horizontal container, | ||||
// it might not have width but have height instead. | ||||
const newSize = | ||||
getCustomValueFromPreset( width, spacingSizes ) || | ||||
getCustomValueFromPreset( height, spacingSizes ) || | ||||
'100px'; | ||||
setAttributes( { | ||||
width: '0px', | ||||
style: { | ||||
...blockStyle, | ||||
layout: { | ||||
...layout, | ||||
flexSize: newSize, | ||||
selfStretch: 'fixed', | ||||
}, | ||||
}, | ||||
} ); | ||||
} else { | ||||
const newSize = | ||||
getCustomValueFromPreset( height, spacingSizes ) || | ||||
getCustomValueFromPreset( width, spacingSizes ) || | ||||
'100px'; | ||||
setAttributes( { | ||||
height: '0px', | ||||
style: { | ||||
...blockStyle, | ||||
layout: { | ||||
...layout, | ||||
flexSize: newSize, | ||||
selfStretch: 'fixed', | ||||
}, | ||||
}, | ||||
} ); | ||||
} | ||||
} else if ( | ||||
isFlexLayout && | ||||
( selfStretch === 'fill' || selfStretch === 'fit' ) | ||||
) { | ||||
if ( inheritedOrientation === 'horizontal' ) { | ||||
setAttributes( { | ||||
width: undefined, | ||||
} ); | ||||
} else { | ||||
setAttributes( { | ||||
height: undefined, | ||||
} ); | ||||
} | ||||
} else if ( ! isFlexLayout && ( selfStretch || flexSize ) ) { | ||||
if ( inheritedOrientation === 'horizontal' ) { | ||||
setAttributes( { | ||||
width: flexSize, | ||||
} ); | ||||
} else { | ||||
setAttributes( { | ||||
height: flexSize, | ||||
} ); | ||||
} | ||||
setAttributes( { | ||||
height: '0px', | ||||
width: '72px', | ||||
style: { | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One final nit (and not a blocker), but I just noticed that sometimes the serialized block markup contains an empty
It doesn't cause any block validation issues to retain the empty objects in the block markup, though, so I really don't think it's a blocker. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Funnily enough, running the object passed to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Good thinking! I'm in support of the idea of merging this now that it's in a good and working state, and we can look at further tweaks in isolation 👍 |
||||
...blockStyle, | ||||
layout: { | ||||
...layout, | ||||
flexSize: undefined, | ||||
selfStretch: undefined, | ||||
}, | ||||
}, | ||||
} ); | ||||
} | ||||
}, [] ); | ||||
}, [ | ||||
blockStyle, | ||||
flexSize, | ||||
height, | ||||
inheritedOrientation, | ||||
isFlexLayout, | ||||
layout, | ||||
selfStretch, | ||||
setAttributes, | ||||
spacingSizes, | ||||
width, | ||||
] ); | ||||
|
||||
return ( | ||||
<> | ||||
|
@@ -211,13 +348,15 @@ const SpacerEdit = ( { | |||
> | ||||
{ resizableBoxWithOrientation( inheritedOrientation ) } | ||||
</View> | ||||
<SpacerControls | ||||
setAttributes={ setAttributes } | ||||
height={ temporaryHeight || height } | ||||
width={ temporaryWidth || width } | ||||
orientation={ inheritedOrientation } | ||||
isResizing={ isResizing } | ||||
/> | ||||
{ ! isFlexLayout && ( | ||||
<SpacerControls | ||||
setAttributes={ setAttributes } | ||||
height={ temporaryHeight || height } | ||||
width={ temporaryWidth || width } | ||||
orientation={ inheritedOrientation } | ||||
isResizing={ isResizing } | ||||
/> | ||||
) } | ||||
</> | ||||
); | ||||
}; | ||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I totally forgot that we're of course working in a different package when making changes to the Spacer block, so this function needs to be exported now.
Shall we rename it to
getSpacingCustomValueFromPreset
orgetCustomSpacingValueFromPreset
since it's being exported from the block editor package? That way if we have other functions for different kinds of presets the need to be exported in the future, we won't have a collision?That said, from a quick search I see that the native version of
index.native.js
for the block editor package is already exporting this function as-is here: https://github.com/WordPress/gutenberg/blob/trunk/packages/block-editor/src/components/index.native.js#L79.So, perhaps another option would be to leave it as-is and if in the future we need a more generic
getCustomValueFromPreset
to be exported that handles other kinds of presets, then we could add a parent function that internally calls the existing spacing one.What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd leave it as is for now, and then perhaps if/when we need to handle other types of presets, we can reimplement this function to deal with any preset, so we don't have to change existing usage (we'd probably want to move it out of the spacing utils if we did that of course).