Fix HStack and VStack alignment prop#47914
Conversation
| const classes = useMemo( () => { | ||
| const base = css( { | ||
| alignItems: isColumn ? 'normal' : align, | ||
| alignItems: align, |
There was a problem hiding this comment.
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.
| 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.
This was buggy (inverted values)
| 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.
This was buggy (inverted values)
| 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.
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.
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
| const classes = useMemo( () => { | ||
| const base = css( { | ||
| alignItems: isColumn ? 'normal' : align, | ||
| alignItems: align ?? ( isColumn ? 'normal' : 'center' ), |
There was a problem hiding this comment.
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 thealignmentprop 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 theedgevalue: "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.
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.
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.
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> | ||
| ) ) } |
| const classes = useMemo( () => { | ||
| const base = css( { | ||
| alignItems: isColumn ? 'normal' : align, | ||
| alignItems: align ?? ( isColumn ? 'normal' : 'center' ), |
There was a problem hiding this comment.
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.
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.