Skip to content

Commit 7a2842e

Browse files
committed
feat: add ScrollView support to Flex component & align
1 parent 5bb4a7d commit 7a2842e

2 files changed

Lines changed: 152 additions & 141 deletions

File tree

.eslintrc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"import/no-extraneous-dependencies": "off",
1313
"@typescript-eslint/no-use-before-define": "off",
1414
"react/require-default-props": "off",
15-
"react/no-unused-prop-types": "off"
15+
"react/no-unused-prop-types": "off",
16+
"react/jsx-props-no-spreading": "off"
1617
}
1718
}

src/Flex.tsx

Lines changed: 150 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import React, { useMemo } from 'react';
22
import {
3-
DimensionValue, StyleSheet, View, ViewProps,
3+
DimensionValue, ScrollView, StyleSheet, View, ViewProps,
44
} from 'react-native';
55

66
export type FlexProps = React.PropsWithChildren<{
77
debug?: boolean;
88
debugBg?: boolean;
99
debugColor?: string;
1010
//
11+
scroll?: boolean;
1112
size?: number;
1213
full?: boolean;
1314
gap?: number;
@@ -21,14 +22,12 @@ export type FlexProps = React.PropsWithChildren<{
2122
vStart?: boolean;
2223
vertical?: boolean;
2324
horizontal?: boolean;
25+
spaceBetween?: boolean;
26+
spaceAround?: boolean;
2427
width?: DimensionValue;
2528
offset?: number;
2629
narrow?: boolean;
2730
bg?: string;
28-
/**
29-
* Description: margin
30-
* @example m={10} // margin: 10
31-
*/
3231
p?: number | Array<number>;
3332
pt?: number;
3433
pr?: number;
@@ -40,150 +39,161 @@ export type FlexProps = React.PropsWithChildren<{
4039
mb?: number;
4140
ml?: number;
4241
style?: ViewProps['style'];
43-
}>;
42+
}> & ViewProps;
4443

4544
export function Flex(props: FlexProps) {
46-
const { children } = props;
45+
const { children, style, scroll } = props;
4746
const s = useMemo(() => getStyles(props), [props]);
48-
47+
const Component = scroll ? ScrollView : View;
4948
return (
50-
<View style={s.flex}>
49+
<Component {...props} style={[s.flex, style]}>
5150
{children}
52-
</View>
51+
</Component>
5352
);
5453
}
5554

56-
const getStyles = (p: FlexProps) => StyleSheet.create({
57-
flex: {
55+
const getStyles = (p: FlexProps) => {
56+
//
57+
const s = StyleSheet.create({
58+
flex: {
5859
// defaults
59-
backgroundColor: p.bg,
60-
flex: 1,
61-
flexDirection: 'row',
62-
flexWrap: 'nowrap',
60+
backgroundColor: p.bg,
61+
flex: 1,
62+
flexDirection: 'row',
63+
flexWrap: 'nowrap',
6364

64-
// for debugging
65-
...(p.debug && {
66-
borderWidth: 1,
67-
borderColor: p.debugColor || 'blue',
68-
}),
69-
...(p.debugBg && {
70-
backgroundColor: p.debugColor || 'blue',
71-
}),
72-
// overrides
73-
...(p.full && {
74-
width: '100%',
75-
}),
76-
...(p.size && {
77-
flex: p.size,
78-
}),
79-
...(p.width && {
80-
width: p.width,
81-
flex: 0,
82-
}),
83-
...(p.offset && {
84-
marginLeft: p.offset,
85-
}),
86-
...(p.narrow && {
87-
flex: 0,
88-
}),
89-
// margins
90-
...(p.m && typeof p.m === 'number' && {
91-
margin: p.m,
92-
}),
93-
...(p.m && Array.isArray(p.m) && p.m.length === 2 && {
94-
marginVertical: p.m[0],
95-
marginHorizontal: p.m[1],
96-
}),
97-
...(p.m && Array.isArray(p.m) && p.m.length === 3 && {
98-
marginTop: p.m[0],
99-
marginHorizontal: p.m[1],
100-
marginBottom: p.m[2],
101-
}),
102-
...(p.m && Array.isArray(p.m) && p.m.length === 4 && {
103-
marginTop: p.m[0],
104-
marginRight: p.m[1],
105-
marginBottom: p.m[2],
106-
marginLeft: p.m[3],
107-
}),
108-
...(p.mt && {
109-
marginTop: p.mt,
110-
}),
111-
...(p.mr && {
112-
marginRight: p.mr,
113-
}),
114-
...(p.mb && {
115-
marginBottom: p.mb,
116-
}),
117-
...(p.ml && {
118-
marginLeft: p.ml,
119-
}),
65+
// for debugging
66+
...(p.debug && {
67+
borderWidth: 1,
68+
borderColor: p.debugColor || 'blue',
69+
}),
70+
...(p.debugBg && {
71+
backgroundColor: p.debugColor || 'blue',
72+
}),
73+
// overrides
74+
...(p.full && {
75+
width: '100%',
76+
}),
77+
...(p.size && {
78+
flex: p.size,
79+
}),
80+
...(p.width && {
81+
width: p.width,
82+
flex: 0,
83+
}),
84+
...(p.offset && {
85+
marginLeft: p.offset,
86+
}),
87+
...(p.narrow && {
88+
flex: 0,
89+
}),
90+
// margins
91+
...(p.m && typeof p.m === 'number' && {
92+
margin: p.m,
93+
}),
94+
...(p.m && Array.isArray(p.m) && p.m.length === 2 && {
95+
marginVertical: p.m[0],
96+
marginHorizontal: p.m[1],
97+
}),
98+
...(p.m && Array.isArray(p.m) && p.m.length === 3 && {
99+
marginTop: p.m[0],
100+
marginHorizontal: p.m[1],
101+
marginBottom: p.m[2],
102+
}),
103+
...(p.m && Array.isArray(p.m) && p.m.length === 4 && {
104+
marginTop: p.m[0],
105+
marginRight: p.m[1],
106+
marginBottom: p.m[2],
107+
marginLeft: p.m[3],
108+
}),
109+
...(p.mt && {
110+
marginTop: p.mt,
111+
}),
112+
...(p.mr && {
113+
marginRight: p.mr,
114+
}),
115+
...(p.mb && {
116+
marginBottom: p.mb,
117+
}),
118+
...(p.ml && {
119+
marginLeft: p.ml,
120+
}),
120121

121-
// paddings
122-
...(p.p && typeof p.p === 'number' && {
123-
padding: p.p,
124-
}),
125-
...(p.p && Array.isArray(p.p) && p.p.length === 2 && {
126-
paddingVertical: p.p[0],
127-
paddingHorizontal: p.p[1],
128-
}),
129-
...(p.p && Array.isArray(p.p) && p.p.length === 3 && {
130-
paddingTop: p.p[0],
131-
paddingHorizontal: p.p[1],
132-
paddingBottom: p.p[2],
133-
}),
134-
...(p.p && Array.isArray(p.p) && p.p.length === 4 && {
135-
paddingTop: p.p[0],
136-
paddingRight: p.p[1],
137-
paddingBottom: p.p[2],
138-
paddingLeft: p.p[3],
139-
}),
140-
...(p.pt && {
141-
paddingTop: p.pt,
142-
}),
143-
...(p.pr && {
144-
paddingRight: p.pr,
145-
}),
146-
...(p.pb && {
147-
paddingBottom: p.pb,
148-
}),
149-
...(p.pl && {
150-
paddingLeft: p.pl,
151-
}),
122+
// paddings
123+
...(p.p && typeof p.p === 'number' && {
124+
padding: p.p,
125+
}),
126+
...(p.p && Array.isArray(p.p) && p.p.length === 2 && {
127+
paddingVertical: p.p[0],
128+
paddingHorizontal: p.p[1],
129+
}),
130+
...(p.p && Array.isArray(p.p) && p.p.length === 3 && {
131+
paddingTop: p.p[0],
132+
paddingHorizontal: p.p[1],
133+
paddingBottom: p.p[2],
134+
}),
135+
...(p.p && Array.isArray(p.p) && p.p.length === 4 && {
136+
paddingTop: p.p[0],
137+
paddingRight: p.p[1],
138+
paddingBottom: p.p[2],
139+
paddingLeft: p.p[3],
140+
}),
141+
...(p.pt && {
142+
paddingTop: p.pt,
143+
}),
144+
...(p.pr && {
145+
paddingRight: p.pr,
146+
}),
147+
...(p.pb && {
148+
paddingBottom: p.pb,
149+
}),
150+
...(p.pl && {
151+
paddingLeft: p.pl,
152+
}),
152153

153-
// flexbox
154-
...(p.vertical && {
155-
flexDirection: 'column',
156-
}),
157-
...(p.horizontal && {
158-
flexDirection: 'row',
159-
}),
160-
...(p.gap && {
161-
gap: p.gap,
162-
}),
163-
...(p.gapless && {
164-
gap: 0,
165-
}),
166-
...(p.centered && {
167-
justifyContent: 'center',
168-
}),
169-
...(p.end && {
170-
justifyContent: 'flex-end',
171-
}),
172-
...(p.start && {
173-
justifyContent: 'flex-start',
174-
}),
175-
...(p.vCentered && {
176-
alignItems: 'center',
177-
}),
178-
...(p.vEnd && {
179-
alignItems: 'flex-end',
180-
}),
181-
...(p.vStart && {
182-
alignItems: 'flex-start',
183-
}),
184-
...(p.multiline && {
185-
flexWrap: 'wrap',
186-
}),
187-
...p.style as object,
188-
},
189-
});
154+
// flexbox
155+
...(p.vertical && {
156+
flexDirection: 'column',
157+
}),
158+
...(p.horizontal && {
159+
flexDirection: 'row',
160+
}),
161+
...(p.gap && {
162+
gap: p.gap,
163+
}),
164+
...(p.gapless && {
165+
gap: 0,
166+
}),
167+
...(p.centered && {
168+
justifyContent: 'center',
169+
}),
170+
...(p.end && {
171+
justifyContent: 'flex-end',
172+
}),
173+
...(p.start && {
174+
justifyContent: 'flex-start',
175+
}),
176+
...(p.vCentered && {
177+
alignItems: 'center',
178+
}),
179+
...(p.vEnd && {
180+
alignItems: 'flex-end',
181+
}),
182+
...(p.vStart && {
183+
alignItems: 'flex-start',
184+
}),
185+
...(p.multiline && {
186+
flexWrap: 'wrap',
187+
}),
188+
...(p.spaceBetween && {
189+
justifyContent: 'space-between',
190+
}),
191+
...(p.spaceAround && {
192+
justifyContent: 'space-around',
193+
}),
194+
...p.style as object,
195+
},
196+
});
197+
198+
return s;
199+
};

0 commit comments

Comments
 (0)