11import React from "react" ;
2- import { View , ViewProps } from "react-native" ;
2+ import { View , ViewProps , LayoutChangeEvent } from "react-native" ;
33
44interface 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
3499export default ZStack ;
0 commit comments