Skip to content

Commit 2679eab

Browse files
author
eunchankim
committed
feat: implement Spacer component
1 parent 4c7c0b3 commit 2679eab

File tree

11 files changed

+132
-5
lines changed

11 files changed

+132
-5
lines changed

example/src/App.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as React from 'react';
22

33
import { StyleSheet, View, Text } from 'react-native';
4-
import { multiply, Hello } from 'good-ui';
4+
import { multiply, Hello, Spacer } from 'react-native-good-ui';
55

66
export default function App() {
77
const [result, setResult] = React.useState<number | undefined>();
@@ -14,6 +14,8 @@ export default function App() {
1414
<View style={styles.container}>
1515
<Hello />
1616

17+
<Spacer direction={'both'} preset={'huge'} />
18+
1719
<Text>Result: {result}</Text>
1820
</View>
1921
);

package.json

+5-1
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,12 @@
5151
"registry": "https://registry.npmjs.org/"
5252
},
5353
"devDependencies": {
54-
"@evilmartians/lefthook": "^1.2.2",
5554
"@commitlint/config-conventional": "^17.0.2",
55+
"@evilmartians/lefthook": "^1.2.2",
5656
"@react-native-community/eslint-config": "^3.0.2",
5757
"@release-it/conventional-changelog": "^5.0.0",
5858
"@types/jest": "^28.1.2",
59+
"@types/ramda": "^0.28.20",
5960
"@types/react": "~17.0.21",
6061
"@types/react-native": "0.70.0",
6162
"commitlint": "^17.0.2",
@@ -155,5 +156,8 @@
155156
}
156157
]
157158
]
159+
},
160+
"dependencies": {
161+
"ramda": "^0.28.0"
158162
}
159163
}

src/components/Spacer/index.tsx

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/**
2+
* The Spacer component is responsible for handling the space UI.
3+
* This component can create 3 types of spaces that is flex, preset and pixel type.
4+
* You should avoid using "size" prop that allow input in units of pixels for coherent spatial processing.
5+
*/
6+
7+
import React from 'react';
8+
import { View, ViewStyle } from 'react-native';
9+
import { Spacing, spacing } from '../../theme';
10+
import { isNilOrEmpty } from '../../utils';
11+
12+
interface SpacerDirection {
13+
direction?: 'both' | 'vertical' | 'horizontal';
14+
}
15+
16+
interface FlexSpacerProps extends SpacerDirection {
17+
/**
18+
* flex type is joint 1st place priority. Strictly speaking, this is First.
19+
* If you don't know flex layout, Reference https://reactnative.dev/docs/flexbox.
20+
*/
21+
flex: number;
22+
/**
23+
* When using the above props, you should never use any other props.
24+
*/
25+
preset?: never;
26+
size?: never;
27+
}
28+
29+
interface PresetSpacerProps extends SpacerDirection {
30+
/**
31+
* preset Type is joint 1st place priority.
32+
*/
33+
preset: Spacing;
34+
/**
35+
* When using the above props, you should never use any other props.
36+
*/
37+
flex?: never;
38+
size?: never;
39+
}
40+
41+
interface SizeSpacerProps extends SpacerDirection {
42+
/**
43+
* size has the lowest priority.
44+
* because The use of size is not recommended because UI & UX quality is often poor.
45+
*/
46+
size?: number;
47+
/**
48+
* When using the above props, you should never use any other props.
49+
*/
50+
preset?: never;
51+
flex?: never;
52+
}
53+
54+
type SpacerProps = PresetSpacerProps | FlexSpacerProps | SizeSpacerProps;
55+
56+
export function Spacer(props: SpacerProps) {
57+
const { direction = 'both', flex, preset, size: pixelSize, ...rest } = props;
58+
59+
// @ts-ignore
60+
const presetSize = spacing[preset];
61+
const value = presetSize ? presetSize : pixelSize;
62+
63+
const style: ViewStyle = {
64+
flex: flex ? flex : undefined,
65+
width:
66+
direction === 'both' || direction === 'horizontal' ? value : undefined,
67+
height:
68+
direction === 'both' || direction === 'vertical' ? value : undefined,
69+
};
70+
71+
if (__DEV__ && isNilOrEmpty(value)) {
72+
console.warn(`Spacer component's value is nil or empty!`);
73+
}
74+
75+
return <View style={style} {...rest} />;
76+
}

src/components/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { Spacer } from './Spacer';

src/index.tsx

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
import React from 'react';
2-
import { View } from 'react-native';
2+
import { View, Text } from 'react-native';
3+
4+
export { Spacer } from './components';
35

46
export function multiply(a: number, b: number): Promise<number> {
57
return Promise.resolve(a * b);
68
}
79

810
export function Hello() {
9-
return <View>Hello World</View>;
11+
return (
12+
<View>
13+
<Text>Hello World</Text>
14+
</View>
15+
);
1016
}

src/theme/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './spacing';

src/theme/spacing.ts

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/**
2+
Use these spacings for margins/paddings and other whitespace throughout your app.
3+
*/
4+
export const spacing = {
5+
micro: 2,
6+
tiny: 4,
7+
extraSmall: 8,
8+
small: 12,
9+
medium: 16,
10+
large: 24,
11+
extraLarge: 32,
12+
huge: 48,
13+
massive: 64,
14+
} as const;
15+
16+
export type Spacing = keyof typeof spacing;

src/utils/functions.ts

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { isNil, isEmpty } from 'ramda';
2+
3+
export const isNilOrEmpty = (value: any) => isNil(value) || isEmpty(value);

src/utils/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './functions';

tsconfig.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"compilerOptions": {
33
"baseUrl": "./",
44
"paths": {
5-
"good-ui": ["./src/index"]
5+
"react-native-good-ui": ["./src/index"]
66
},
77
"allowUnreachableCode": false,
88
"allowUnusedLabels": false,

yarn.lock

+17
Original file line numberDiff line numberDiff line change
@@ -2176,6 +2176,13 @@
21762176
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf"
21772177
integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==
21782178

2179+
"@types/ramda@^0.28.20":
2180+
version "0.28.20"
2181+
resolved "https://registry.yarnpkg.com/@types/ramda/-/ramda-0.28.20.tgz#df93bb5674f0051464c075480ca3075d1c1361ba"
2182+
integrity sha512-MeUhzGSXQTRsY19JGn5LIBTLxVEnyF6HDNr08KSJqybsm4DlfLIgK1jBHjhpiSyk252tXYmp+UOe0UFg0UiFsA==
2183+
dependencies:
2184+
ts-toolbelt "^6.15.1"
2185+
21792186
21802187
version "0.70.0"
21812188
resolved "https://registry.yarnpkg.com/@types/react-native/-/react-native-0.70.0.tgz#f8cdcdd542d36467d7591585b93d27e0563676e0"
@@ -7788,6 +7795,11 @@ quick-lru@^5.1.1:
77887795
resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932"
77897796
integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==
77907797

7798+
ramda@^0.28.0:
7799+
version "0.28.0"
7800+
resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.28.0.tgz#acd785690100337e8b063cab3470019be427cc97"
7801+
integrity sha512-9QnLuG/kPVgWvMQ4aODhsBUFKOUmnbUnsSXACv+NCQZcHbeb+v8Lodp8OVxtRULN1/xOyYLLaL6npE6dMq5QTA==
7802+
77917803
range-parser@~1.2.1:
77927804
version "1.2.1"
77937805
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
@@ -9087,6 +9099,11 @@ ts-node@^10.8.1:
90879099
v8-compile-cache-lib "^3.0.1"
90889100
yn "3.1.1"
90899101

9102+
ts-toolbelt@^6.15.1:
9103+
version "6.15.5"
9104+
resolved "https://registry.yarnpkg.com/ts-toolbelt/-/ts-toolbelt-6.15.5.tgz#cb3b43ed725cb63644782c64fbcad7d8f28c0a83"
9105+
integrity sha512-FZIXf1ksVyLcfr7M317jbB67XFJhOO1YqdTcuGaq9q5jLUoTikukZ+98TPjKiP2jC5CgmYdWWYs0s2nLSU0/1A==
9106+
90909107
tslib@^1.8.1:
90919108
version "1.14.1"
90929109
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"

0 commit comments

Comments
 (0)