From b1e5983c8a2a6b64e9aa11d8db11952162b824ae Mon Sep 17 00:00:00 2001 From: Muhammad Saeed <37156636+Stringsaeed@users.noreply.github.com> Date: Sun, 30 Aug 2020 23:20:12 +0200 Subject: [PATCH] adding snack player instead of images for flexbox (#2171) * adding snack player instead of images for flexbox * chore: revert yarn.lock * minor changes and improvements, prettier run on examples Co-authored-by: Bartosz Kaszubowski --- docs/flexbox.md | 1406 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 1347 insertions(+), 59 deletions(-) diff --git a/docs/flexbox.md b/docs/flexbox.md index 8e39b0cd340..19f43cd873b 100644 --- a/docs/flexbox.md +++ b/docs/flexbox.md @@ -15,42 +15,157 @@ You will normally use a combination of `flexDirection`, `alignItems`, and `justi In the following example, the red, yellow, and green views are all children in the container view that has `flex: 1` set. The red view uses `flex: 1` , the yellow view uses `flex: 2`, and the green view uses `flex: 3` . **1+2+3 = 6**, which means that the red view will get `1/6` of the space, the yellow `2/6` of the space, and the green `3/6` of the space. -![Flex](https://cdn-images-1.medium.com/max/800/1*PhCFmO5tYX_sZSyCd4vO3w.png) +```SnackPlayer name=Flex%20Example +import React from "react"; +import { StyleSheet, Text, View } from "react-native"; + +const Flex = () => { + return ( + + + + + + ); +}; + +const styles = StyleSheet.create({ + container: { + flex: 1, + padding: 20, + }, +}); + +export default Flex; +``` ## Flex Direction [`flexDirection`](layout-props#flexdirection) controls the direction in which the children of a node are laid out. This is also referred to as the _main axis_. The cross axis is the axis perpendicular to the main axis, or the axis which the wrapping lines are laid out in. -- `row` Align children from left to right. If wrapping is enabled, then the next line will start under the first item on the left of the container. - - `column` (**default value**) Align children from top to bottom. If wrapping is enabled, then the next line will start to the right of the first item on the top of the container. -- `row-reverse` Align children from right to left. If wrapping is enabled, then the next line will start under the first item on the right of the container. +- `row` Align children from left to right. If wrapping is enabled, then the next line will start under the first item on the left of the container. - `column-reverse` Align children from bottom to top. If wrapping is enabled, then the next line will start to the right of the first item on the bottom of the container. +- `row-reverse` Align children from right to left. If wrapping is enabled, then the next line will start under the first item on the right of the container. + You can learn more [here](https://yogalayout.com/docs/flex-direction). ```SnackPlayer name=Flex%20Direction -import React from 'react'; -import { View } from 'react-native'; +import React, { useState } from "react"; +import { StyleSheet, Text, TouchableOpacity, View } from "react-native"; const FlexDirectionBasics = () => { - return ( - // Try setting `flexDirection` to `column`. - - - - - - ); + const [flexDirection, setflexDirection] = useState("column"); + + return ( + + + + + + ); }; +const PreviewLayout = ({ + label, + children, + values, + selectedValue, + setSelectedValue, +}) => ( + + {label} + + {values.map((value) => ( + setSelectedValue(value)} + style={[ + styles.button, + selectedValue === value && styles.selected, + ]} + > + + {value} + + + ))} + + + {children} + + +); + +const styles = StyleSheet.create({ + container: { + flex: 1, + marginTop: 8, + backgroundColor: "aliceblue", + }, + box: { + width: 50, + height: 50, + }, + row: { + flexDirection: "row", + flexWrap: "wrap", + }, + button: { + paddingHorizontal: 8, + paddingVertical: 6, + borderRadius: 4, + backgroundColor: "oldlace", + alignSelf: "flex-start", + marginHorizontal: "1%", + marginBottom: 6, + minWidth: "48%", + textAlign: "center", + }, + selected: { + backgroundColor: "coral", + borderWidth: 0, + }, + buttonLabel: { + fontSize: 12, + fontWeight: "500", + color: "coral", + }, + selectedLabel: { + color: "white", + }, + label: { + textAlign: "center", + marginBottom: 10, + fontSize: 24, + }, +}); + export default FlexDirectionBasics; ``` -![Flex Direction](https://cdn-images-1.medium.com/max/800/1*rA7IbuUsJWsx6evKAsabVw.png) - ## Layout Direction Layout direction specifies the direction in which children and text in a hierarchy should be laid out. Layout direction also affects what edge `start` and `end` refer to. By default, React Native lays out with LTR layout direction. In this mode `start` refers to left and `end` refers to right. @@ -59,6 +174,115 @@ Layout direction specifies the direction in which children and text in a hierarc - `RTL` Text and children are laid out from right to left. Margin and padding applied to the start of an element are applied on the right side. +```SnackPlayer name=Flex%20Direction +import React, { useState } from "react"; +import { View, TouchableOpacity, Text, StyleSheet } from "react-native"; + +const DirectionLayout = () => { + const [direction, setDirection] = useState("ltr"); + + return ( + + + + + + ); +}; + +const PreviewLayout = ({ + label, + children, + values, + selectedValue, + setSelectedValue, +}) => ( + + {label} + + {values.map((value) => ( + setSelectedValue(value)} + style={[ + styles.button, + selectedValue === value && styles.selected, + ]} + > + + {value} + + + ))} + + + {children} + + +); + +const styles = StyleSheet.create({ + container: { + flex: 1, + marginTop: 8, + backgroundColor: "aliceblue", + }, + box: { + width: 50, + height: 50, + }, + row: { + flexDirection: "row", + flexWrap: "wrap", + }, + button: { + paddingHorizontal: 8, + paddingVertical: 6, + borderRadius: 4, + backgroundColor: "oldlace", + alignSelf: "flex-start", + marginHorizontal: "1%", + marginBottom: 6, + minWidth: "48%", + textAlign: "center", + }, + selected: { + backgroundColor: "coral", + borderWidth: 0, + }, + buttonLabel: { + fontSize: 12, + fontWeight: "500", + color: "coral", + }, + selectedLabel: { + color: "white", + }, + label: { + textAlign: "center", + marginBottom: 10, + fontSize: 24, + }, +}); + +export default DirectionLayout; +``` + ## Justify Content [`justifyContent`](layout-props#justifycontent) describes how to align children within the main axis of their container. For example, you can use this property to center a child horizontally within a container with `flexDirection` set to `row` or vertically within a container with `flexDirection` set to `column`. @@ -78,30 +302,119 @@ Layout direction specifies the direction in which children and text in a hierarc You can learn more [here](https://yogalayout.com/docs/justify-content). ```SnackPlayer name=Justify%20Content -import React from 'react'; -import { View } from 'react-native'; +import React, { useState } from "react"; +import { View, TouchableOpacity, Text, StyleSheet } from "react-native"; const JustifyContentBasics = () => { - return ( - // Try setting `justifyContent` to `center`. - // Try setting `flexDirection` to `row`. - - - - - - ); + const [justifyContent, setJustifyContent] = useState("flex-start"); + + return ( + + + + + + ); }; +const PreviewLayout = ({ + label, + children, + values, + selectedValue, + setSelectedValue, +}) => ( + + {label} + + {values.map((value) => ( + setSelectedValue(value)} + style={[styles.button, selectedValue === value && styles.selected]} + > + + {value} + + + ))} + + + {children} + + +); + +const styles = StyleSheet.create({ + container: { + flex: 1, + marginTop: 8, + backgroundColor: "aliceblue", + }, + box: { + width: 50, + height: 50, + }, + row: { + flexDirection: "row", + flexWrap: "wrap", + }, + button: { + paddingHorizontal: 8, + paddingVertical: 6, + borderRadius: 4, + backgroundColor: "oldlace", + alignSelf: "flex-start", + marginHorizontal: "1%", + marginBottom: 6, + minWidth: "48%", + textAlign: "center", + }, + selected: { + backgroundColor: "coral", + borderWidth: 0, + }, + buttonLabel: { + fontSize: 12, + fontWeight: "500", + color: "coral", + }, + selectedLabel: { + color: "white", + }, + label: { + textAlign: "center", + marginBottom: 10, + fontSize: 24, + }, +}); + export default JustifyContentBasics; ``` -![Justify Content](https://cdn-images-1.medium.com/max/800/1*i5TVlme-TisAVvD5ax2yPA.png) - ## Align Items [`alignItems`](layout-props#alignitems) describes how to align children along the cross axis of their container. Align items is very similar to `justifyContent` but instead of applying to the main axis, `alignItems` applies to the cross axis. @@ -121,37 +434,259 @@ export default JustifyContentBasics; You can learn more [here](https://yogalayout.com/docs/align-items). ```SnackPlayer name=Align%20Items -import React from 'react'; -import { View } from 'react-native'; - -const AlignItemsBasics = () => { - return ( - // Try setting `alignItems` to 'flex-start' - // Try setting `justifyContent` to `flex-end`. - // Try setting `flexDirection` to `row`. - - - - - - ); +import React, { useState } from "react"; +import { + View, + TouchableOpacity, + Text, + StyleSheet, +} from "react-native"; + +const AlignItemsLayout = () => { + const [alignItems, setAlignItems] = useState("stretch"); + + return ( + + + + + + ); }; -export default AlignItemsBasics; +const PreviewLayout = ({ + label, + children, + values, + selectedValue, + setSelectedValue, +}) => ( + + {label} + + {values.map((value) => ( + setSelectedValue(value)} + style={[ + styles.button, + selectedValue === value && styles.selected, + ]} + > + + {value} + + + ))} + + + {children} + + +); + +const styles = StyleSheet.create({ + container: { + flex: 1, + marginTop: 8, + backgroundColor: "aliceblue", + minHeight: 200, + }, + box: { + width: 50, + height: 50, + }, + row: { + flexDirection: "row", + flexWrap: "wrap", + }, + button: { + paddingHorizontal: 8, + paddingVertical: 6, + borderRadius: 4, + backgroundColor: "oldlace", + alignSelf: "flex-start", + marginHorizontal: "1%", + marginBottom: 6, + minWidth: "48%", + textAlign: "center", + }, + selected: { + backgroundColor: "coral", + borderWidth: 0, + }, + buttonLabel: { + fontSize: 12, + fontWeight: "500", + color: "coral", + }, + selectedLabel: { + color: "white", + }, + label: { + textAlign: "center", + marginBottom: 10, + fontSize: 24, + }, +}); + +export default AlignItemsLayout; ``` -![Align Items](https://cdn-images-1.medium.com/max/800/1*evkM7zfxt-9p-HJ1M0Bh2g.png) - ## Align Self [`alignSelf`](layout-props#alignself) has the same options and effect as `alignItems` but instead of affecting the children within a container, you can apply this property to a single child to change its alignment within its parent. `alignSelf` overrides any option set by the parent with `alignItems`. -![Align Self](https://cdn-images-1.medium.com/max/800/1*J1JCoKwLCokX9JXVBvP71g.png) +```SnackPlayer name=Align%20Self +import React, { useState } from "react"; +import { View, TouchableOpacity, Text, StyleSheet } from "react-native"; + +const AlignSelfLayout = () => { + const [alignSelf, setAlignSelf] = useState("stretch"); + + return ( + + + + + + ); +}; + +const PreviewLayout = ({ + label, + children, + values, + selectedValue, + setSelectedValue, +}) => ( + + {label} + + {values.map((value) => ( + setSelectedValue(value)} + style={[ + styles.button, + selectedValue === value && styles.selected, + ]} + > + + {value} + + + ))} + + + {children} + + +); + +const styles = StyleSheet.create({ + container: { + flex: 1, + marginTop: 8, + backgroundColor: "aliceblue", + minHeight: 200, + }, + box: { + width: 50, + height: 50, + }, + row: { + flexDirection: "row", + flexWrap: "wrap", + }, + button: { + paddingHorizontal: 8, + paddingVertical: 6, + borderRadius: 4, + backgroundColor: "oldlace", + alignSelf: "flex-start", + marginHorizontal: "1%", + marginBottom: 6, + minWidth: "48%", + textAlign: "center", + }, + selected: { + backgroundColor: "coral", + borderWidth: 0, + }, + buttonLabel: { + fontSize: 12, + fontWeight: "500", + color: "coral", + }, + selectedLabel: { + color: "white", + }, + label: { + textAlign: "center", + marginBottom: 10, + fontSize: 24, + }, +}); + +export default AlignSelfLayout; +``` ## Align Content @@ -171,7 +706,141 @@ export default AlignItemsBasics; You can learn more [here](https://yogalayout.com/docs/align-content). -![Align Content](https://cdn-images-1.medium.com/max/800/1*cC2XFyCF_igp20Ombt4wBw.png) +```SnackPlayer name=Align%20Content +import React, { useState } from "react"; +import { View, TouchableOpacity, Text, StyleSheet } from "react-native"; + +const AlignContentLayout = () => { + const [alignContent, setAlignContent] = useState("flex-start"); + + return ( + + + + + + + + + + ); +}; + +const PreviewLayout = ({ + label, + children, + values, + selectedValue, + setSelectedValue, +}) => ( + + {label} + + {values.map((value) => ( + setSelectedValue(value)} + style={[ + styles.button, + selectedValue === value && styles.selected, + ]} + > + + {value} + + + ))} + + + {children} + + +); + +const styles = StyleSheet.create({ + container: { + flex: 1, + flexWrap: "wrap", + marginTop: 8, + backgroundColor: "aliceblue", + maxHeight: 400, + }, + box: { + width: 50, + height: 80, + }, + row: { + flexDirection: "row", + flexWrap: "wrap", + }, + button: { + paddingHorizontal: 8, + paddingVertical: 6, + borderRadius: 4, + backgroundColor: "oldlace", + alignSelf: "flex-start", + marginHorizontal: "1%", + marginBottom: 6, + minWidth: "48%", + textAlign: "center", + }, + selected: { + backgroundColor: "coral", + borderWidth: 0, + }, + buttonLabel: { + fontSize: 12, + fontWeight: "500", + color: "coral", + }, + selectedLabel: { + color: "white", + }, + label: { + textAlign: "center", + marginBottom: 10, + fontSize: 24, + }, +}); + +export default AlignContentLayout; +``` ## Flex Wrap @@ -179,7 +848,132 @@ The [`flexWrap`](layout-props#flexwrap) property is set on containers and it con When wrapping lines, `alignContent` can be used to specify how the lines are placed in the container. Learn more [here](https://yogalayout.com/docs/flex-wrap). -![Flex Wrap](https://cdn-images-1.medium.com/max/800/1*_7v4uQhSsuCn1cfeOMVfrA.png) +```SnackPlayer name=Flex%20Wrap +import React, { useState } from "react"; +import { View, TouchableOpacity, Text, StyleSheet } from "react-native"; + +const FlexWrapLayout = () => { + const [flexWrap, setFlexWrap] = useState("wrap"); + + return ( + + + + + + + + + + ); +}; + +const PreviewLayout = ({ + label, + children, + values, + selectedValue, + setSelectedValue, +}) => ( + + {label} + + {values.map((value) => ( + setSelectedValue(value)} + style={[ + styles.button, + selectedValue === value && styles.selected, + ]} + > + + {value} + + + ))} + + + {children} + + +); + +const styles = StyleSheet.create({ + container: { + flex: 1, + marginTop: 8, + backgroundColor: "aliceblue", + maxHeight: 400, + }, + box: { + width: 50, + height: 80, + }, + row: { + flexDirection: "row", + flexWrap: "wrap", + }, + button: { + paddingHorizontal: 8, + paddingVertical: 6, + borderRadius: 4, + backgroundColor: "oldlace", + marginHorizontal: "1%", + marginBottom: 6, + minWidth: "48%", + textAlign: "center", + }, + selected: { + backgroundColor: "coral", + borderWidth: 0, + }, + buttonLabel: { + fontSize: 12, + fontWeight: "500", + color: "coral", + }, + selectedLabel: { + color: "white", + }, + label: { + textAlign: "center", + marginBottom: 10, + fontSize: 24, + }, +}); + +export default FlexWrapLayout; +``` ## Flex Basis, Grow, and Shrink @@ -195,6 +989,209 @@ When wrapping lines, `alignContent` can be used to specify how the lines are pla You can learn more [here](https://yogalayout.com/docs/flex). +```SnackPlayer name=Flex%20Basis%2C%20Grow%2C%20and%20Shrink +import React, { useState } from "react"; +import { + View, + Text, + TextInput, + StyleSheet, +} from "react-native"; + +const App = () => { + const [powderblue, setPowderblue] = useState({ + flexGrow: 0, + flexShrink: 1, + flexBasis: "auto", + }); + const [skyblue, setSkyblue] = useState({ + flexGrow: 1, + flexShrink: 0, + flexBasis: 100, + }); + const [steelblue, setSteelblue] = useState({ + flexGrow: 0, + flexShrink: 1, + flexBasis: 200, + }); + return ( + + + + + + + + + + + + + ); +}; + +const BoxInfo = ({ + color, + flexBasis, + flexShrink, + setStyle, + flexGrow, +}) => ( + + + + Box + + + flexBasis + + setStyle((value) => ({ + ...value, + flexBasis: isNaN(parseInt(fB)) + ? "auto" + : parseInt(fB), + })) + } + /> + flexShrink + + setStyle((value) => ({ + ...value, + flexShrink: isNaN(parseInt(fS)) + ? "" + : parseInt(fS), + })) + } + /> + flexGrow + + setStyle((value) => ({ + ...value, + flexGrow: isNaN(parseInt(fG)) + ? "" + : parseInt(fG), + })) + } + /> + +); + +const styles = StyleSheet.create({ + container: { + flex: 1, + paddingHorizontal: 10, + }, + box: { + flex: 1, + height: 50, + width: 50, + }, + boxLabel: { + minWidth: 80, + padding: 8, + borderRadius: 4, + marginTop: 8, + }, + label: { + marginTop: 6, + fontSize: 16, + fontWeight: "100", + }, + previewContainer: { + flex: 1, + flexDirection: "row", + backgroundColor: "aliceblue", + }, + row: { + flex: 1, + flexDirection: "row", + flexWrap: "wrap", + alignItems: "center", + marginBottom: 10, + }, + input: { + borderBottomWidth: 1, + paddingVertical: 3, + width: 50, + textAlign: "center", + }, +}); + +export default App; +``` + ## Width and Height The `width` property specifies the width of an element's content area. Similarly, the `height` property specifies the height of an element's content area. @@ -207,6 +1204,159 @@ Both `width` and `height` can take the following values: - `percentage` Defines the width or height in percentage of its parent's width or height, respectively. +```SnackPlayer name=Width%20and%20Height +import React, { useState } from "react"; +import { + View, + SafeAreaView, + TouchableOpacity, + Text, + StyleSheet, +} from "react-native"; + +const WidthHeightBasics = () => { + const [widthType, setWidthType] = useState("auto"); + const [heightType, setHeightType] = useState("auto"); + + return ( + + + + + + + + ); +}; + +const PreviewLayout = ({ + children, + widthType, + heightType, + widthValues, + heightValues, + setWidthType, + setHeightType, +}) => ( + + + width + {widthValues.map((value) => ( + setWidthType(value)} + style={[ + styles.button, + widthType === value && styles.selected, + ]} + > + + {value} + + + ))} + + + height + {heightValues.map((value) => ( + setHeightType(value)} + style={[ + styles.button, + heightType === value && styles.selected, + ]} + > + + {value} + + + ))} + + {children} + +); + +const styles = StyleSheet.create({ + box: { + width: 50, + height: 50, + }, + row: { + flexDirection: "row", + flexWrap: "wrap", + }, + button: { + padding: 8, + borderRadius: 4, + backgroundColor: "oldlace", + alignSelf: "flex-start", + marginRight: 10, + marginBottom: 10, + }, + selected: { + backgroundColor: "coral", + shadowOpacity: 0, + borderWidth: 0, + }, + buttonLabel: { + fontSize: 12, + fontWeight: "500", + color: "coral", + }, + selectedLabel: { + color: "white", + }, + label: { + textAlign: "center", + marginBottom: 10, + fontSize: 24, + }, +}); + +export default WidthHeightBasics; +``` + ## Absolute & Relative Layout The `position` type of an element defines how it is positioned within its parent. @@ -215,7 +1365,145 @@ The `position` type of an element defines how it is positioned within its parent - `absolute` When positioned absolutely, an element doesn't take part in the normal layout flow. It is instead laid out independent of its siblings. The position is determined based on the `top`, `right`, `bottom`, and `left` values. -![Absolute & Relative Layoutp](https://cdn-images-1.medium.com/max/800/1*NlPeRQCQK3Vb5nyjL0Mqxw.png) +```SnackPlayer name=Absolute%20%26%20Relative%20Layout +import React, { useState } from "react"; +import { + View, + SafeAreaView, + TouchableOpacity, + Text, + StyleSheet, +} from "react-native"; + +const PositionLayout = () => { + const [position, setPosition] = useState("relative"); + + return ( + + + + + + ); +}; + +const PreviewLayout = ({ + label, + children, + values, + selectedValue, + setSelectedValue, +}) => ( + + {label} + + {values.map((value) => ( + setSelectedValue(value)} + style={[ + styles.button, + selectedValue === value && styles.selected, + ]} + > + + {value} + + + ))} + + {children} + +); + +const styles = StyleSheet.create({ + container: { + flex: 1, + marginTop: 8, + backgroundColor: "aliceblue", + minHeight: 200, + }, + box: { + width: 50, + height: 50, + }, + row: { + flexDirection: "row", + flexWrap: "wrap", + }, + button: { + paddingHorizontal: 8, + paddingVertical: 6, + borderRadius: 4, + backgroundColor: "oldlace", + alignSelf: "flex-start", + marginHorizontal: "1%", + marginBottom: 6, + minWidth: "48%", + textAlign: "center", + }, + selected: { + backgroundColor: "coral", + borderWidth: 0, + }, + buttonLabel: { + fontSize: 12, + fontWeight: "500", + color: "coral", + }, + selectedLabel: { + color: "white", + }, + label: { + textAlign: "center", + marginBottom: 10, + fontSize: 24, + }, +}); + +export default PositionLayout; +``` ## Going Deeper