Skip to content

Commit

Permalink
feat: add ScrollView support to Flex component & align
Browse files Browse the repository at this point in the history
  • Loading branch information
eduardoborges committed Nov 14, 2023
1 parent 5bb4a7d commit 7a2842e
Show file tree
Hide file tree
Showing 2 changed files with 152 additions and 141 deletions.
3 changes: 2 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"import/no-extraneous-dependencies": "off",
"@typescript-eslint/no-use-before-define": "off",
"react/require-default-props": "off",
"react/no-unused-prop-types": "off"
"react/no-unused-prop-types": "off",
"react/jsx-props-no-spreading": "off"
}
}
290 changes: 150 additions & 140 deletions src/Flex.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import React, { useMemo } from 'react';
import {
DimensionValue, StyleSheet, View, ViewProps,
DimensionValue, ScrollView, StyleSheet, View, ViewProps,
} from 'react-native';

export type FlexProps = React.PropsWithChildren<{
debug?: boolean;
debugBg?: boolean;
debugColor?: string;
//
scroll?: boolean;
size?: number;
full?: boolean;
gap?: number;
Expand All @@ -21,14 +22,12 @@ export type FlexProps = React.PropsWithChildren<{
vStart?: boolean;
vertical?: boolean;
horizontal?: boolean;
spaceBetween?: boolean;
spaceAround?: boolean;
width?: DimensionValue;
offset?: number;
narrow?: boolean;
bg?: string;
/**
* Description: margin
* @example m={10} // margin: 10
*/
p?: number | Array<number>;
pt?: number;
pr?: number;
Expand All @@ -40,150 +39,161 @@ export type FlexProps = React.PropsWithChildren<{
mb?: number;
ml?: number;
style?: ViewProps['style'];
}>;
}> & ViewProps;

export function Flex(props: FlexProps) {
const { children } = props;
const { children, style, scroll } = props;
const s = useMemo(() => getStyles(props), [props]);

const Component = scroll ? ScrollView : View;
return (
<View style={s.flex}>
<Component {...props} style={[s.flex, style]}>
{children}
</View>
</Component>
);
}

const getStyles = (p: FlexProps) => StyleSheet.create({
flex: {
const getStyles = (p: FlexProps) => {
//
const s = StyleSheet.create({
flex: {
// defaults
backgroundColor: p.bg,
flex: 1,
flexDirection: 'row',
flexWrap: 'nowrap',
backgroundColor: p.bg,
flex: 1,
flexDirection: 'row',
flexWrap: 'nowrap',

// for debugging
...(p.debug && {
borderWidth: 1,
borderColor: p.debugColor || 'blue',
}),
...(p.debugBg && {
backgroundColor: p.debugColor || 'blue',
}),
// overrides
...(p.full && {
width: '100%',
}),
...(p.size && {
flex: p.size,
}),
...(p.width && {
width: p.width,
flex: 0,
}),
...(p.offset && {
marginLeft: p.offset,
}),
...(p.narrow && {
flex: 0,
}),
// margins
...(p.m && typeof p.m === 'number' && {
margin: p.m,
}),
...(p.m && Array.isArray(p.m) && p.m.length === 2 && {
marginVertical: p.m[0],
marginHorizontal: p.m[1],
}),
...(p.m && Array.isArray(p.m) && p.m.length === 3 && {
marginTop: p.m[0],
marginHorizontal: p.m[1],
marginBottom: p.m[2],
}),
...(p.m && Array.isArray(p.m) && p.m.length === 4 && {
marginTop: p.m[0],
marginRight: p.m[1],
marginBottom: p.m[2],
marginLeft: p.m[3],
}),
...(p.mt && {
marginTop: p.mt,
}),
...(p.mr && {
marginRight: p.mr,
}),
...(p.mb && {
marginBottom: p.mb,
}),
...(p.ml && {
marginLeft: p.ml,
}),
// for debugging
...(p.debug && {
borderWidth: 1,
borderColor: p.debugColor || 'blue',
}),
...(p.debugBg && {
backgroundColor: p.debugColor || 'blue',
}),
// overrides
...(p.full && {
width: '100%',
}),
...(p.size && {
flex: p.size,
}),
...(p.width && {
width: p.width,
flex: 0,
}),
...(p.offset && {
marginLeft: p.offset,
}),
...(p.narrow && {
flex: 0,
}),
// margins
...(p.m && typeof p.m === 'number' && {
margin: p.m,
}),
...(p.m && Array.isArray(p.m) && p.m.length === 2 && {
marginVertical: p.m[0],
marginHorizontal: p.m[1],
}),
...(p.m && Array.isArray(p.m) && p.m.length === 3 && {
marginTop: p.m[0],
marginHorizontal: p.m[1],
marginBottom: p.m[2],
}),
...(p.m && Array.isArray(p.m) && p.m.length === 4 && {
marginTop: p.m[0],
marginRight: p.m[1],
marginBottom: p.m[2],
marginLeft: p.m[3],
}),
...(p.mt && {
marginTop: p.mt,
}),
...(p.mr && {
marginRight: p.mr,
}),
...(p.mb && {
marginBottom: p.mb,
}),
...(p.ml && {
marginLeft: p.ml,
}),

// paddings
...(p.p && typeof p.p === 'number' && {
padding: p.p,
}),
...(p.p && Array.isArray(p.p) && p.p.length === 2 && {
paddingVertical: p.p[0],
paddingHorizontal: p.p[1],
}),
...(p.p && Array.isArray(p.p) && p.p.length === 3 && {
paddingTop: p.p[0],
paddingHorizontal: p.p[1],
paddingBottom: p.p[2],
}),
...(p.p && Array.isArray(p.p) && p.p.length === 4 && {
paddingTop: p.p[0],
paddingRight: p.p[1],
paddingBottom: p.p[2],
paddingLeft: p.p[3],
}),
...(p.pt && {
paddingTop: p.pt,
}),
...(p.pr && {
paddingRight: p.pr,
}),
...(p.pb && {
paddingBottom: p.pb,
}),
...(p.pl && {
paddingLeft: p.pl,
}),
// paddings
...(p.p && typeof p.p === 'number' && {
padding: p.p,
}),
...(p.p && Array.isArray(p.p) && p.p.length === 2 && {
paddingVertical: p.p[0],
paddingHorizontal: p.p[1],
}),
...(p.p && Array.isArray(p.p) && p.p.length === 3 && {
paddingTop: p.p[0],
paddingHorizontal: p.p[1],
paddingBottom: p.p[2],
}),
...(p.p && Array.isArray(p.p) && p.p.length === 4 && {
paddingTop: p.p[0],
paddingRight: p.p[1],
paddingBottom: p.p[2],
paddingLeft: p.p[3],
}),
...(p.pt && {
paddingTop: p.pt,
}),
...(p.pr && {
paddingRight: p.pr,
}),
...(p.pb && {
paddingBottom: p.pb,
}),
...(p.pl && {
paddingLeft: p.pl,
}),

// flexbox
...(p.vertical && {
flexDirection: 'column',
}),
...(p.horizontal && {
flexDirection: 'row',
}),
...(p.gap && {
gap: p.gap,
}),
...(p.gapless && {
gap: 0,
}),
...(p.centered && {
justifyContent: 'center',
}),
...(p.end && {
justifyContent: 'flex-end',
}),
...(p.start && {
justifyContent: 'flex-start',
}),
...(p.vCentered && {
alignItems: 'center',
}),
...(p.vEnd && {
alignItems: 'flex-end',
}),
...(p.vStart && {
alignItems: 'flex-start',
}),
...(p.multiline && {
flexWrap: 'wrap',
}),
...p.style as object,
},
});
// flexbox
...(p.vertical && {
flexDirection: 'column',
}),
...(p.horizontal && {
flexDirection: 'row',
}),
...(p.gap && {
gap: p.gap,
}),
...(p.gapless && {
gap: 0,
}),
...(p.centered && {
justifyContent: 'center',
}),
...(p.end && {
justifyContent: 'flex-end',
}),
...(p.start && {
justifyContent: 'flex-start',
}),
...(p.vCentered && {
alignItems: 'center',
}),
...(p.vEnd && {
alignItems: 'flex-end',
}),
...(p.vStart && {
alignItems: 'flex-start',
}),
...(p.multiline && {
flexWrap: 'wrap',
}),
...(p.spaceBetween && {
justifyContent: 'space-between',
}),
...(p.spaceAround && {
justifyContent: 'space-around',
}),
...p.style as object,
},
});

return s;
};

0 comments on commit 7a2842e

Please sign in to comment.