-
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
Fix HStack and VStack alignment prop #47914
Conversation
@@ -62,7 +62,7 @@ export function useFlex( props: WordPressComponentProps< FlexProps, 'div' > ) { | |||
|
|||
const classes = useMemo( () => { | |||
const base = css( { | |||
alignItems: isColumn ? 'normal' : align, | |||
alignItems: align, |
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 is the most important change. I'm not sure I understand the reason for the check originally, I checked the original PR and it's not mentioned.
@@ -11,7 +11,7 @@ import { isValueDefined } from '../utils/values'; | |||
|
|||
const H_ALIGNMENTS: Alignments = { | |||
bottom: { align: 'flex-end', justify: 'center' }, | |||
bottomLeft: { align: 'flex-start', justify: 'flex-end' }, | |||
bottomLeft: { align: 'flex-end', justify: 'flex-start' }, |
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 was buggy (inverted values)
@@ -25,13 +25,13 @@ const H_ALIGNMENTS: Alignments = { | |||
|
|||
const V_ALIGNMENTS: Alignments = { | |||
bottom: { justify: 'flex-end', align: 'center' }, | |||
bottomLeft: { justify: 'flex-start', align: 'flex-end' }, | |||
bottomLeft: { justify: 'flex-end', align: 'flex-start' }, |
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 was buggy (inverted values)
bottomRight: { justify: 'flex-end', align: 'flex-end' }, | ||
center: { justify: 'center', align: 'center' }, | ||
edge: { justify: 'space-between', align: 'center' }, | ||
left: { justify: 'center', align: 'flex-start' }, | ||
right: { justify: 'center', align: 'flex-end' }, | ||
stretch: { justify: 'stretch' }, | ||
stretch: { align: 'stretch' }, |
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 was buggy too.
Flaky tests detected in 172ee45. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/4265445081
|
Any thoughts on this PR @ciampo |
It's in my review queue — I hope to get to it by EOD. I've been working on implementing some VizReg tests specifically on HStack and VStack (#48260) in the meantime, which will help while reviewing this PR. |
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.
Alright — I took a first look at the code changes! Since it's quite tricky to understand the full implications of these changes, I used the recently introduced Visual Regression tests to compare this PR against trunk.
Here's what I'm doing to test this PR with VizReg
- Checkout
trunk
- Install latest version of dependencies:
npm run distclean && npm ci
- Install PlayWright:
npx playwright install
- Generate snapshots:
- In one terminal window, run Storybook for VizReg:
npm run storybook:e2e:dev
- Once Storybook is up and running, generate Playwright snapshots:
npm run test:e2e:storybook -- --update-snapshots
- In one terminal window, run Storybook for VizReg:
- Checkout this PR
- Compare snapshots:
- In one terminal window, run Storybook for VizReg:
npm run storybook:e2e:dev
- Once Storybook is up and running, compare VizReg snapshots:
npm run test:e2e:storybook
- In one terminal window, run Storybook for VizReg:
I also rebased on top of trunk
to include the latest VizReg changes
@@ -62,7 +62,7 @@ export function useFlex( props: WordPressComponentProps< FlexProps, 'div' > ) { | |||
|
|||
const classes = useMemo( () => { | |||
const base = css( { | |||
alignItems: isColumn ? 'normal' : align, | |||
alignItems: align ?? ( isColumn ? 'normal' : 'center' ), |
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 change definitely makes sense, but I'm not sure if the new behaviour of HStack
is 100% correct either.
I was taking a look at HStack
when direction="column"
, and I was playing around with the alignment
prop:
- on
trunk
, in this case changing thealignment
prop doesn't seem to make any differences - on this PR, it seems to work as expected, except for the
alignment="edge"
case - the items appear to be centered, but I believed they should be stretched (especially given the description of theedge
value: "Aligns content to the edges of the container.")
Looks like this change would fix it
diff --git a/packages/components/src/h-stack/utils.ts b/packages/components/src/h-stack/utils.ts
index b1413ee2dc..60151b00a2 100644
--- a/packages/components/src/h-stack/utils.ts
+++ b/packages/components/src/h-stack/utils.ts
@@ -28,7 +28,7 @@ const V_ALIGNMENTS: Alignments = {
bottomLeft: { justify: 'flex-end', align: 'flex-start' },
bottomRight: { justify: 'flex-end', align: 'flex-end' },
center: { justify: 'center', align: 'center' },
- edge: { justify: 'space-between', align: 'center' },
+ edge: { justify: 'space-between', align: 'stretch' },
left: { justify: 'center', align: 'flex-start' },
right: { justify: 'center', align: 'flex-end' },
stretch: { align: 'stretch' },
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.
If I remember properly, I based the behavior of "edge" here by comparing the behavior of "h" in HStack and applied the same behavior but in the other axis.
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.
As much as I don't love the arbitrariness of this align
prop, I agree with Riad that this new edge
behavior for VStack is correct/consistent within the existing logic of the system.
In this system, I understand stretch
to apply only to the cross axis, and edge
to apply only to the main axis.
How about we tweak the description to make that clearer?
- * * `edge`: Aligns content to the edges of the container.
+ * * `edge`: Justifies content to be evenly spread out up to the main axis edges of the container.
- * * `stretch`: Stretches content to the edges of the container.
+ * * `stretch`: Stretches content to the cross axis edges of the container.
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 both.
Given that the separation between breaking change and bug fix can be blurry here, I agree with Lena's proposed solution
02d893c
to
172ee45
Compare
<VStack | ||
{ ...props } | ||
style={ { background: '#eee', minHeight: '200px' } } | ||
> | ||
{ [ 'One', 'Two', 'Three', 'Four', 'Five' ].map( ( text ) => ( | ||
<View key={ text } style={ { background: '#b9f9ff' } }> | ||
{ text } | ||
</View> | ||
) ) } |
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.
Thanks for this improvement!
@@ -62,7 +62,7 @@ export function useFlex( props: WordPressComponentProps< FlexProps, 'div' > ) { | |||
|
|||
const classes = useMemo( () => { | |||
const base = css( { | |||
alignItems: isColumn ? 'normal' : align, | |||
alignItems: align ?? ( isColumn ? 'normal' : 'center' ), |
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.
As much as I don't love the arbitrariness of this align
prop, I agree with Riad that this new edge
behavior for VStack is correct/consistent within the existing logic of the system.
In this system, I understand stretch
to apply only to the cross axis, and edge
to apply only to the main axis.
How about we tweak the description to make that clearer?
- * * `edge`: Aligns content to the edges of the container.
+ * * `edge`: Justifies content to be evenly spread out up to the main axis edges of the container.
- * * `stretch`: Stretches content to the edges of the container.
+ * * `stretch`: Stretches content to the cross axis edges of the container.
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.
Thanks! 🚢
What?
While working on #47827 I've noticed a bug in VStack component. The alignment prop was not working as expected. It turns out that there are several bugs in the alignment prop of both VStack and HStack, This PR fixes it.
Testing Instructions
1- Open the storybook of both VStack and HStack
2- Check that all the alignment options behave as expected.