-
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
BorderControls: Alternate approach to handling popover positioning #40874
BorderControls: Alternate approach to handling popover positioning #40874
Conversation
Size Change: -180 B (0%) Total Size: 1.23 MB
ℹ️ View Unchanged
|
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.
While this draft PR still requires some polishing, it's functional and should serve to aid discussion on how we move forward in terms of positioning border control popovers.
const rightAlignedClassName = useMemo( () => { | ||
return cx( styles.RightBorderControl, className ); | ||
}, [] ); |
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.
Found while testing this the alignment of the right border control was out of whack when on tablet or mobile viewports.
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.
Let's make a note to apply this fix even in case this PR doesn't get merged.
// We only want to apply adjusted popover content styles when on desktop. | ||
const responsiveSide = useResponsiveValue( [ | ||
undefined, | ||
undefined, | ||
__experimentalSide, | ||
] ); |
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 couldn't find the @include break-medium()
equivalent using Emotion within the components package. This was my best guess but very happy to switch this out for any better ideas.
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.
Thank you @aaronrobertshaw for coming up with an alternative approach to #40836 so quickly!
I personally prefer this approach, but I'll share a couple of thoughts/doubts:
- the concept of a sidebar feels more part of the “Gutenberg app”, and less of the
@wordpress/components
package (there isn’t no sidebar component, for example) — although these components already feel very specific and situational to the block editor (and already expose the__experimentalIsRenderedInSidebar
prop). - having both
__experimentalSide
and__experimentalIsRenderedInSidebar
onBorderControl
doesn't feel like the cleanest API, especially given that__experimentalSide
only has effect when__experimentalIsRenderedInSidebar
istrue
. @mirka and I recently discussed about how we're not massive fans of such "conditional" props.
A way to partially mitigate this last point could be to use the __experimentalSide
also to tweak the popover's position when the component is not in the sidebar. I'm proposing this because currently the popover renders on top of other border controls (which is one of the main UX reasons for which we wanted to move the popover in the first place).
@@ -8,6 +8,7 @@ export type Border = { | |||
style?: CSSProperties[ 'borderStyle' ]; | |||
width?: CSSProperties[ 'borderWidth' ]; | |||
}; | |||
export type BorderSides = 'all' | 'left' | 'top' | 'right' | 'bottom'; |
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.
A quick though, not necessarily related to the changes in this PR.
I wonder if we should consider switching to logical properties) — which would eventually require this type to become something like
export type BorderSides = 'all' | 'left' | 'top' | 'right' | 'bottom'; | |
export type BorderSides = 'all' | 'inline-start' | 'block-start' | 'inline-end' | 'block-end'; |
@@ -115,11 +116,60 @@ export const colorIndicatorWrapper = ( border?: Border ) => { | |||
`; | |||
}; | |||
|
|||
export const borderControlPopover = css` | |||
const sidebarBorderPopoverContentStyles = css` | |||
width: 282px; |
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.
Probably OK for a first iteration, but I wonder if there any way we can read this from a variable (or ever somehow measure it in the client at runtime?)
It would also be interesting if we could save this value as a local variable, and derive all right/left margins with formulas? (not sure it makes sense though)
export const borderControlPopover = css` | ||
const sidebarBorderPopoverContentStyles = css` | ||
width: 282px; | ||
margin-bottom: calc( ${ space( 13 ) } * -1 ); |
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.
This style also feels a bit arbitrary — maybe we could add a comment explaining the reasoning behind it?
margin-bottom: calc( ${ space( 13 ) } * -1 ); | ||
`; | ||
|
||
const borderControlPopoverContent = ( |
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.
We could also add a comment here (or in this function's body) explaining that these margin rules are in place to align the popover to the sidebar
argTypes: { | ||
__experimentalSide: { | ||
options: [ undefined, 'all', 'left', 'top', 'right', 'bottom' ], | ||
}, | ||
}, |
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.
Tweaking the __experimentalSide
, even with the __experimentalIsRenderedInSidebar
flag set to true
, doesn't seem to change the appearance of the popover in the default story.
I wonder if we should disable the interactive controls for the story and/or create an ad-hoc story to showcase the "render in sidebar" scenario?
const rightAlignedClassName = useMemo( () => { | ||
return cx( styles.RightBorderControl, className ); | ||
}, [] ); |
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.
Let's make a note to apply this fix even in case this PR doesn't get merged.
Closing this PR due to a new approach that will be adopted as part of #40740. |
Thank you for taking the time to review this approach and leave feedback @ciampo. Despite not proceeding with these, it's appreciated 🙇 |
Don't mention it, Aaron! This was still a valuable approach that definitely deserved to be discussed / reviewed |
Related:
What?
Provides opt-in sidebar positioning for
BorderControl
popovers without exposing or passing through popoverProps via theBorderControl
's public API.Why?
New work refactoring the
Popover
component requires the ability to position aPopover
via props rather than a class name.This is an alternate approach to #40836 after concerns about passing through
popoverProps
were raised.How?
__experimentalIsRenderedInSidebar
istrue
and__experimentalSide
is set, theBorderControl
will generate new styles and apply them internally via the inner Dropdown'spopoverProps
.BorderBoxControl
and updates it to leverageBorderControl
's new approach (3aea82f)useResponsiveValue
to adjust when the sidebar positioning should occur (i.e. only on desktop).Testing Instructions
npm run test-unit packages/components/src/border-control/test/index.js
npm run test-unit packages/components/src/border-box-control/test/index.js
npm run build:package-types
BorderControl
popovers, they should all be the narrower default width and their positions not modified.Screenshots or screencast
Screen.Recording.2022-05-06.at.4.03.25.pm.mp4