Skip to content

Commit 3f856f0

Browse files
authored
Add Layout Components (47) (#737)
* Deprecate old layout components * Added Center, Circle, and Square components * Added AspectRatio, HStack, VStack, ZStack components * Fixed aspect ratio component * Address feedback
1 parent f9d9221 commit 3f856f0

File tree

13 files changed

+265
-51
lines changed

13 files changed

+265
-51
lines changed

example/src/LayoutExample.js

Lines changed: 0 additions & 49 deletions
This file was deleted.

example/src/LayoutExample.tsx

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import * as React from "react";
2+
import { Text } from "react-native";
3+
import {
4+
AspectRatio,
5+
HStack,
6+
VStack,
7+
ZStack,
8+
Center,
9+
Circle,
10+
Square,
11+
} from "@draftbit/ui";
12+
import Section, { Container } from "./Section";
13+
14+
const LayoutExample = () => {
15+
return (
16+
<Container style={{}}>
17+
<Section title="Center" style={{}}>
18+
<Center
19+
style={{
20+
width: 200,
21+
height: 50,
22+
borderColor: "red",
23+
borderWidth: 1,
24+
}}
25+
>
26+
<Text>Centered Text</Text>
27+
</Center>
28+
</Section>
29+
<Section title="Circle" style={{}}>
30+
<Circle
31+
style={{
32+
width: 100,
33+
borderColor: "red",
34+
borderWidth: 1,
35+
}}
36+
/>
37+
</Section>
38+
<Section title="Square" style={{}}>
39+
<Square
40+
style={{
41+
width: 100,
42+
borderColor: "red",
43+
borderWidth: 1,
44+
}}
45+
/>
46+
</Section>
47+
<Section title="Aspect Ratio" style={{}}>
48+
<AspectRatio
49+
style={{
50+
width: 200,
51+
borderColor: "red",
52+
borderWidth: 1,
53+
}}
54+
aspectRatio={16 / 9}
55+
/>
56+
</Section>
57+
<Section title="HStack" style={{}}>
58+
<HStack>
59+
<Text>HStack 1</Text>
60+
<Text>HStack 2</Text>
61+
</HStack>
62+
</Section>
63+
<Section title="VStack" style={{}}>
64+
<VStack>
65+
<Text>VStack 1</Text>
66+
<Text>VStack 2</Text>
67+
</VStack>
68+
</Section>
69+
<Section title="ZStack" style={{}}>
70+
<ZStack>
71+
<Text>ZStack 1</Text>
72+
<Text>ZStack 2</Text>
73+
</ZStack>
74+
</Section>
75+
</Container>
76+
);
77+
};
78+
79+
export default LayoutExample;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import React from "react";
2+
import { View, ViewProps } from "react-native";
3+
4+
interface AspectRatioProps extends ViewProps {
5+
aspectRatio?: number;
6+
}
7+
8+
const AspectRatio: React.FC<AspectRatioProps> = ({
9+
aspectRatio = 1,
10+
style,
11+
...rest
12+
}) => {
13+
return <View {...rest} style={[{ aspectRatio }, style]} />;
14+
};
15+
16+
export default AspectRatio;
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import React from "react";
2+
import { View, ViewProps, StyleSheet } from "react-native";
3+
4+
const Center: React.FC<ViewProps> = ({ style, ...rest }) => {
5+
return <View {...rest} style={[styles.center, style]} />;
6+
};
7+
8+
const styles = StyleSheet.create({
9+
center: {
10+
alignItems: "center",
11+
justifyContent: "center",
12+
},
13+
});
14+
15+
export default Center;
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import React from "react";
2+
import { ViewProps, StyleSheet } from "react-native";
3+
import Square from "./Square";
4+
5+
interface CircleProps extends ViewProps {
6+
size?: number;
7+
}
8+
9+
const Circle: React.FC<CircleProps> = ({ size, style, ...rest }) => {
10+
return <Square {...rest} size={size} style={[style, styles.circle]} />;
11+
};
12+
13+
const styles = StyleSheet.create({
14+
circle: {
15+
borderRadius: 1000, // Border radius maxes out as a circle, use an overly large number to ensure circle in all cases
16+
},
17+
});
18+
19+
export default Circle;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import React from "react";
2+
import { View, ViewProps, StyleSheet } from "react-native";
3+
4+
const HStack: React.FC<ViewProps> = ({ style, ...rest }) => {
5+
return <View {...rest} style={[styles.hStack, style]} />;
6+
};
7+
8+
const styles = StyleSheet.create({
9+
hStack: {
10+
flexDirection: "row",
11+
},
12+
});
13+
14+
export default HStack;
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import React from "react";
2+
import { ViewProps } from "react-native";
3+
import Center from "./Center";
4+
5+
interface SquareProps extends ViewProps {
6+
size?: number;
7+
}
8+
9+
const Square: React.FC<SquareProps> = ({ size, style, onLayout, ...rest }) => {
10+
const [calculatedSize, setCalculatedSize] = React.useState(0);
11+
12+
return (
13+
<Center
14+
onLayout={(e) => {
15+
const layout = e.nativeEvent.layout;
16+
setCalculatedSize(Math.max(layout.width, layout.height));
17+
onLayout?.(e);
18+
}}
19+
{...rest}
20+
style={[
21+
style,
22+
size != undefined ? { width: size, height: size } : {},
23+
calculatedSize > 0
24+
? {
25+
width: calculatedSize,
26+
height: calculatedSize,
27+
}
28+
: {},
29+
]}
30+
/>
31+
);
32+
};
33+
34+
export default Square;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import React from "react";
2+
import { View, ViewProps, StyleSheet } from "react-native";
3+
4+
const VStack: React.FC<ViewProps> = ({ style, ...rest }) => {
5+
return <View {...rest} style={[styles.vStack, style]} />;
6+
};
7+
8+
const styles = StyleSheet.create({
9+
vStack: {
10+
flexDirection: "column",
11+
},
12+
});
13+
14+
export default VStack;
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import React from "react";
2+
import { View, ViewProps } from "react-native";
3+
4+
interface ZStackProps extends ViewProps {
5+
reversed?: boolean;
6+
}
7+
8+
const ZStack: React.FC<ZStackProps> = ({ reversed, children, ...rest }) => {
9+
const absoluteChildren = React.useMemo(() => {
10+
let childrenArray = React.Children.toArray(
11+
children
12+
) as React.ReactElement[];
13+
14+
if (reversed) {
15+
childrenArray = childrenArray.reverse();
16+
}
17+
18+
return childrenArray.map((child, index) => {
19+
const props = child.props || {};
20+
return React.cloneElement(
21+
child,
22+
{
23+
...props,
24+
style: { position: "absolute", zIndex: index + 1, ...props.style },
25+
},
26+
props.children
27+
);
28+
});
29+
}, [children, reversed]);
30+
31+
return <View {...rest}>{absoluteChildren}</View>;
32+
};
33+
34+
export default ZStack;
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export { default as AspectRatio } from "./AspectRatio";
2+
export { default as Circle } from "./Circle";
3+
export { default as Center } from "./Center";
4+
export { default as HStack } from "./HStack";
5+
export { default as VStack } from "./VStack";
6+
export { default as ZStack } from "./ZStack";
7+
export { default as Square } from "./Square";

0 commit comments

Comments
 (0)