-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Sticky Position: Try re-enabling non-root sticky position #49321
Changes from all commits
877f788
80be3a6
95a5504
d78322c
9e5d9bc
5ad63a2
c4a105d
9311103
c995d72
b9e7b37
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 |
---|---|---|
|
@@ -28,6 +28,7 @@ import { addFilter } from '@wordpress/hooks'; | |
import BlockList from '../components/block-list'; | ||
import useSetting from '../components/use-setting'; | ||
import InspectorControls from '../components/inspector-controls'; | ||
import useBlockDisplayInformation from '../components/use-block-display-information'; | ||
import { cleanEmptyObject } from './utils'; | ||
import { unlock } from '../lock-unlock'; | ||
import { store as blockEditorStore } from '../store'; | ||
|
@@ -222,32 +223,39 @@ export function PositionPanel( props ) { | |
const allowSticky = hasStickyPositionSupport( blockName ); | ||
const value = style?.position?.type; | ||
|
||
const { hasParents } = useSelect( | ||
const { firstParentClientId } = useSelect( | ||
( select ) => { | ||
const { getBlockParents } = select( blockEditorStore ); | ||
const parents = getBlockParents( clientId ); | ||
return { | ||
hasParents: parents.length, | ||
}; | ||
return { firstParentClientId: parents[ parents.length - 1 ] }; | ||
}, | ||
[ clientId ] | ||
); | ||
|
||
const blockInformation = useBlockDisplayInformation( firstParentClientId ); | ||
const stickyHelpText = | ||
allowSticky && value === STICKY_OPTION.value && blockInformation | ||
? sprintf( | ||
/* translators: %s: the name of the parent block. */ | ||
__( | ||
'The block will stick to the scrollable area of the parent %s block.' | ||
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. Not a blocker, just asking: Is there a way to tell if a block is nested inside a template? I know getting sticky to work on templates is off the cards for now, but I guess folks might try to make the header sticky and until we can get that working this doesn't make much sense when I try to make Header > Group sticky:
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 question! Unfortunately it's a tricky one to figure out, because depending on what a user's site layout is like, there could be a good case for a user making their block sticky to the immediate parent within a header. I suppose it's one of the challenges of exposing the controls in non-root positions — we'd like to try to help communicate what's going to happen, but at the same time, it's up to users to use the tools however it suits their current designs 🤔 Personally, I'd probably explore tweaking logic surrounding where the block sits in relation to templates / template parts in follow-ups, as it gets quite tricky to come up with something the feels just right. Thanks for taking a look! |
||
), | ||
blockInformation.title | ||
) | ||
: null; | ||
|
||
const options = useMemo( () => { | ||
const availableOptions = [ DEFAULT_OPTION ]; | ||
// Only display sticky option if the block has no parents (is at the root of the document), | ||
// or if the block already has a sticky position value set. | ||
if ( | ||
( allowSticky && ! hasParents ) || | ||
value === STICKY_OPTION.value | ||
) { | ||
// Display options if they are allowed, or if a block already has a valid value set. | ||
// This allows for a block to be switched off from a position type that is not allowed. | ||
if ( allowSticky || value === STICKY_OPTION.value ) { | ||
availableOptions.push( STICKY_OPTION ); | ||
} | ||
if ( allowFixed || value === FIXED_OPTION.value ) { | ||
availableOptions.push( FIXED_OPTION ); | ||
} | ||
return availableOptions; | ||
}, [ allowFixed, allowSticky, hasParents, value ] ); | ||
}, [ allowFixed, allowSticky, value ] ); | ||
|
||
const onChangeType = ( next ) => { | ||
// For now, use a hard-coded `0px` value for the position. | ||
|
@@ -281,7 +289,11 @@ export function PositionPanel( props ) { | |
web: | ||
options.length > 1 ? ( | ||
<InspectorControls group="position"> | ||
<BaseControl className="block-editor-hooks__position-selection"> | ||
<BaseControl | ||
className="block-editor-hooks__position-selection" | ||
__nextHasNoMarginBottom | ||
help={ stickyHelpText } | ||
> | ||
<CustomSelectControl | ||
__nextUnconstrainedWidth | ||
__next36pxDefaultSize | ||
|
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.
Crazy idea: could we use this client id to instead inject a style in the DOM like
#block-clientid :has(.ist-sticky.is-selected) { outline: 1px solid grey}
or whatever?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.
Oh, that is a clever idea — I can't remember why exactly, but I think from memory there was a preference to try to use popovers so that we don't accidentally collide with any styles that a theme might have for a particular block. It could be to ensure that the visualizers / popover always displays its CSS styling in addition to whatever might be set on the parent block (that we can't quite know) rather than overriding anything. Worth playing with though!
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 picked outline because it's very unlikely that it gets used for block styling, as it's mostly a property applied on focus. Though if the popover calculations are performant I suppose it's not really an issue.