Skip to content

Commit 5ecc70e

Browse files
authored
Update ZStack to have a size of largest child (47) (#785)
* Update ZStack to have a size of largest child * Cleaned up how map is updated
1 parent 8a9aea9 commit 5ecc70e

File tree

1 file changed

+69
-4
lines changed

1 file changed

+69
-4
lines changed

packages/core/src/components/Layout/ZStack.tsx

Lines changed: 69 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,50 @@
11
import React from "react";
2-
import { View, ViewProps } from "react-native";
2+
import { View, ViewProps, LayoutChangeEvent } from "react-native";
33

44
interface ZStackProps extends ViewProps {
55
reversed?: boolean;
66
}
77

8-
const ZStack: React.FC<ZStackProps> = ({ reversed, children, ...rest }) => {
8+
interface ChildSize {
9+
width: number;
10+
height: number;
11+
}
12+
13+
const ZStack: React.FC<ZStackProps> = ({
14+
reversed,
15+
children,
16+
style,
17+
...rest
18+
}) => {
19+
const childSizes = React.useRef(new Map<number, ChildSize>());
20+
const [maxChildWidth, setMaxChildWidth] = React.useState<number>();
21+
const [maxChildHeight, setMaxChildHeight] = React.useState<number>();
22+
23+
const onChildLayout = React.useCallback(
24+
(index: number, width: number, height: number) => {
25+
childSizes.current.set(index, {
26+
width,
27+
height,
28+
});
29+
30+
let maxWidth = 0;
31+
let maxHeight = 0;
32+
33+
for (const { width, height } of childSizes.current.values()) {
34+
if (width > maxWidth) {
35+
maxWidth = width;
36+
}
37+
if (height > maxHeight) {
38+
maxHeight = height;
39+
}
40+
}
41+
42+
setMaxChildWidth(maxWidth);
43+
setMaxChildHeight(maxHeight);
44+
},
45+
[setMaxChildWidth, setMaxChildHeight]
46+
);
47+
948
const absoluteChildren = React.useMemo(() => {
1049
let childrenArray = React.Children.toArray(
1150
children
@@ -21,14 +60,40 @@ const ZStack: React.FC<ZStackProps> = ({ reversed, children, ...rest }) => {
2160
child,
2261
{
2362
...props,
63+
onLayout: (event: LayoutChangeEvent) => {
64+
const layout = event.nativeEvent.layout;
65+
66+
const fullWidth = layout.x + layout.width;
67+
const fullHeight = layout.y + layout.height;
68+
onChildLayout(index, fullWidth, fullHeight);
69+
70+
props.onLayout?.(event);
71+
},
72+
key: index,
2473
style: { position: "absolute", zIndex: index + 1, ...props.style },
2574
},
2675
props.children
2776
);
2877
});
29-
}, [children, reversed]);
78+
}, [children, reversed, onChildLayout]);
79+
80+
React.useEffect(() => {
81+
childSizes.current.clear();
82+
}, [absoluteChildren.length]);
3083

31-
return <View {...rest}>{absoluteChildren}</View>;
84+
return (
85+
<View
86+
style={[
87+
maxChildWidth && maxChildHeight
88+
? { width: maxChildWidth, height: maxChildHeight }
89+
: {},
90+
style,
91+
]}
92+
{...rest}
93+
>
94+
{absoluteChildren}
95+
</View>
96+
);
3297
};
3398

3499
export default ZStack;

0 commit comments

Comments
 (0)