Skip to content

Commit

Permalink
ZStack: fix component bounding box to match children (#51836)
Browse files Browse the repository at this point in the history
* ZStack: rewrite using CSS grid

* Use first-of-type instead of fist-child

* CHANGELOG

* Improve comment

* Apply styles once in the parent wrapper

* Avoid each child view from expanding to all available space

* Remove unnecessary wrapeprs in storybook exmaple
  • Loading branch information
ciampo authored and tellthemachines committed Jun 27, 2023
1 parent da17fa8 commit 4f0d57f
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 39 deletions.
1 change: 1 addition & 0 deletions packages/components/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
- `Button`: Remove unnecessary margin from dashicon ([#51395](https://github.com/WordPress/gutenberg/pull/51395)).
- `Autocomplete`: Announce how many results are available to screen readers when suggestions list first renders ([#51018](https://github.com/WordPress/gutenberg/pull/51018)).
- `ConfirmDialog`: Ensure onConfirm isn't called an extra time when submitting one of the buttons using the keyboard ([#51730](https://github.com/WordPress/gutenberg/pull/51730)).
- `ZStack`: ZStack: fix component bounding box to match children ([#51836](https://github.com/WordPress/gutenberg/pull/51836)).

### Internal

Expand Down
6 changes: 4 additions & 2 deletions packages/components/src/z-stack/component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,14 @@ function UnconnectedZStack(

const clonedChildren = validChildren.map( ( child, index ) => {
const zIndex = isReversed ? childrenLastIndex - index : index;
const offsetAmount = offset * index;
// Only when the component is layered, the offset needs to be multiplied by
// the item's index, so that items can correctly stack at the right distance
const offsetAmount = isLayered ? offset * index : offset;

const key = isValidElement( child ) ? child.key : index;

return (
<ZStackChildView
isLayered={ isLayered }
offsetAmount={ offsetAmount }
zIndex={ zIndex }
key={ key }
Expand All @@ -55,6 +56,7 @@ function UnconnectedZStack(
<ZStackView
{ ...otherProps }
className={ className }
isLayered={ isLayered }
ref={ forwardedRef }
>
{ clonedChildren }
Expand Down
19 changes: 6 additions & 13 deletions packages/components/src/z-stack/stories/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import type { ComponentMeta, ComponentStory } from '@storybook/react';
* Internal dependencies
*/
import { Elevation } from '../../elevation';
import { HStack } from '../../h-stack';
import { View } from '../../view';
import { ZStack } from '..';

Expand Down Expand Up @@ -55,18 +54,12 @@ const Avatar = ( {

const Template: ComponentStory< typeof ZStack > = ( args ) => {
return (
<View>
<HStack>
<View>
<ZStack { ...args }>
<Avatar backgroundColor="#444" />
<Avatar backgroundColor="#777" />
<Avatar backgroundColor="#aaa" />
<Avatar backgroundColor="#fff" />
</ZStack>
</View>
</HStack>
</View>
<ZStack { ...args }>
<Avatar backgroundColor="#444" />
<Avatar backgroundColor="#777" />
<Avatar backgroundColor="#aaa" />
<Avatar backgroundColor="#fff" />
</ZStack>
);
};

Expand Down
47 changes: 23 additions & 24 deletions packages/components/src/z-stack/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,35 @@
import { css } from '@emotion/react';
import styled from '@emotion/styled';

/**
* Internal dependencies
*/
import { rtl } from '../utils';

export const ZStackView = styled.div`
display: flex;
position: relative;
`;

export const ZStackChildView = styled.div< {
isLayered: boolean;
offsetAmount: number;
zIndex: number;
} >`
${ ( { isLayered, offsetAmount } ) =>
isLayered
? css( rtl( { marginLeft: offsetAmount } )() )
: css( rtl( { right: offsetAmount * -1 } )() ) }
&:not( :first-of-type ) {
${ ( { offsetAmount } ) =>
css( {
marginInlineStart: offsetAmount,
} ) };
}
${ ( { isLayered } ) =>
isLayered ? positionAbsolute : positionRelative }
${ ( { zIndex } ) => css( { zIndex } ) }
`;

const positionAbsolute = css`
position: absolute;
${ ( { zIndex } ) => css( { zIndex } ) };
`;

const positionRelative = css`
export const ZStackView = styled.div< {
isLayered: boolean;
} >`
display: inline-grid;
grid-auto-flow: column;
position: relative;
& > ${ ZStackChildView } {
position: relative;
justify-self: start;
${ ( { isLayered } ) =>
isLayered
? // When `isLayered` is true, all items overlap in the same grid cell
css( { gridRowStart: 1, gridColumnStart: 1 } )
: undefined };
}
`;

1 comment on commit 4f0d57f

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flaky tests detected in 4f0d57f.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/5384717186
📝 Reported issues:

Please sign in to comment.