ui-rn 1.0.19 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +14 -7
- package/src/Icon/index.tsx +82 -129
- package/src/Icon/makeProps.ts +77 -34
- package/src/Layout.tsx +18 -16
- package/src/Text/Props.ts +4 -5
- package/src/Text/Style.ts +3 -3
- package/src/Text/index.tsx +42 -39
- package/src/Text/makeStyle.ts +42 -21
- package/src/Touch/Block.tsx +14 -31
- package/src/Touch/Props.ts +3 -3
- package/src/Touch/Style.ts +0 -1
- package/src/Touch/Touch.tsx +19 -45
- package/src/Touch/TouchScale.tsx +41 -59
- package/src/Touch/makeStyle.ts +48 -56
- package/src/index.tsx +1 -3
- package/src/types/react-native-vector-icons.d.ts +12 -0
- package/Example/index.tsx +0 -31
- package/ZoomImg.tsx +0 -206
- package/globals.config.js +0 -33
- package/globals.d.ts +0 -16
- package/src/Dropdown.tsx +0 -41
- package/src/Loading/Loading.tsx +0 -172
- package/src/Loading/LoadingType.tsx +0 -46
- package/src/Loading/index.tsx +0 -55
- package/src/config.ts +0 -36
- package/test.tsx +0 -25
- package/tsconfig.json +0 -6
package/package.json
CHANGED
|
@@ -1,19 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ui-rn",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"repository": "https://github.com/package-dev/ui-rn",
|
|
5
5
|
"description": "ui-rn",
|
|
6
6
|
"author": "Phamha98",
|
|
7
7
|
"main": "src/index.tsx",
|
|
8
|
+
"peerDependencies": {
|
|
9
|
+
"react": ">=18",
|
|
10
|
+
"react-native": ">=0.70"
|
|
11
|
+
},
|
|
8
12
|
"dependencies": {
|
|
9
|
-
"underscore": "^1.13.6",
|
|
10
13
|
"@types/underscore": "^1.11.15",
|
|
11
|
-
"
|
|
14
|
+
"react-native-vector-icons": "^9.2.0",
|
|
12
15
|
"react-native-safe-area-view": "^1.1.1",
|
|
13
|
-
"
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
"
|
|
16
|
+
"underscore": "^1.13.6"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"typescript": "^5.9.3",
|
|
20
|
+
"@types/react": "^19.2.14",
|
|
21
|
+
"react": "^19.2.4",
|
|
22
|
+
"react-native": "^0.84.1",
|
|
23
|
+
"@react-native/typescript-config": "^0.84.1"
|
|
17
24
|
},
|
|
18
25
|
"scripts": {
|
|
19
26
|
"test": "echo \"Error: no test specified\" && exit 1"
|
package/src/Icon/index.tsx
CHANGED
|
@@ -1,149 +1,102 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
import
|
|
13
|
-
import
|
|
14
|
-
import
|
|
15
|
-
import FontAwesome5 from 'react-native-vector-icons/FontAwesome5'
|
|
16
|
-
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'
|
|
17
|
-
import MaterialIcons from 'react-native-vector-icons/MaterialIcons'
|
|
18
|
-
import Entypo from 'react-native-vector-icons/Entypo'
|
|
19
|
-
import AntDesign from 'react-native-vector-icons/AntDesign'
|
|
20
|
-
import SimpleLineIcons from 'react-native-vector-icons/SimpleLineIcons'
|
|
21
|
-
import Feather from 'react-native-vector-icons/Feather'
|
|
22
|
-
import Octicons from 'react-native-vector-icons/Octicons'
|
|
23
|
-
import Fontisto from 'react-native-vector-icons/Fontisto'
|
|
24
|
-
import { IconProps } from 'react-native-vector-icons/Icon'
|
|
25
|
-
import { isArray, isString } from 'underscore'
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { StyleSheet, TouchableOpacity } from "react-native";
|
|
3
|
+
import Ionicons from "react-native-vector-icons/Ionicons";
|
|
4
|
+
import EvilIcons from "react-native-vector-icons/EvilIcons";
|
|
5
|
+
import FontAwesome from "react-native-vector-icons/FontAwesome";
|
|
6
|
+
import FontAwesome5 from "react-native-vector-icons/FontAwesome5";
|
|
7
|
+
import MaterialCommunityIcons from "react-native-vector-icons/MaterialCommunityIcons";
|
|
8
|
+
import MaterialIcons from "react-native-vector-icons/MaterialIcons";
|
|
9
|
+
import Entypo from "react-native-vector-icons/Entypo";
|
|
10
|
+
import AntDesign from "react-native-vector-icons/AntDesign";
|
|
11
|
+
import SimpleLineIcons from "react-native-vector-icons/SimpleLineIcons";
|
|
12
|
+
import Feather from "react-native-vector-icons/Feather";
|
|
13
|
+
import Octicons from "react-native-vector-icons/Octicons";
|
|
14
|
+
import Fontisto from "react-native-vector-icons/Fontisto";
|
|
26
15
|
|
|
27
16
|
/**
|
|
28
17
|
* Collection of React Native Vector Icons
|
|
29
18
|
* Provides access to various icon sets from react-native-vector-icons
|
|
30
19
|
*/
|
|
31
20
|
export const RNVectorIcon = {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
21
|
+
Ionicons,
|
|
22
|
+
AntDesign,
|
|
23
|
+
Entypo,
|
|
24
|
+
EvilIcons,
|
|
25
|
+
MaterialIcons,
|
|
26
|
+
MaterialCommunityIcons,
|
|
27
|
+
FontAwesome,
|
|
28
|
+
FontAwesome5,
|
|
29
|
+
SimpleLineIcons,
|
|
30
|
+
Feather,
|
|
31
|
+
Octicons,
|
|
32
|
+
Fontisto,
|
|
33
|
+
};
|
|
45
34
|
|
|
46
|
-
|
|
47
|
-
export type IconType = keyof typeof RNVectorIcon
|
|
35
|
+
export type IconType = keyof typeof RNVectorIcon;
|
|
48
36
|
|
|
49
|
-
import { Props
|
|
50
|
-
import { makeProps } from
|
|
37
|
+
import { Props } from "./PropsStyle";
|
|
38
|
+
import { makeProps } from "./makeProps";
|
|
51
39
|
|
|
52
|
-
/**
|
|
53
|
-
* IconApp component that provides a unified interface for using various icon sets
|
|
54
|
-
* Supports touch interaction and custom styling
|
|
55
|
-
*
|
|
56
|
-
* @component
|
|
57
|
-
* @example
|
|
58
|
-
* ```tsx
|
|
59
|
-
* // Basic usage
|
|
60
|
-
* <IconApp name="home" />
|
|
61
|
-
*
|
|
62
|
-
* // Custom size and color
|
|
63
|
-
* <IconApp
|
|
64
|
-
* name="star"
|
|
65
|
-
* size={30}
|
|
66
|
-
* color="gold"
|
|
67
|
-
* />
|
|
68
|
-
*
|
|
69
|
-
* // With touch interaction
|
|
70
|
-
* <IconApp
|
|
71
|
-
* name="heart"
|
|
72
|
-
* onPress={() => console.log('pressed')}
|
|
73
|
-
* />
|
|
74
|
-
*
|
|
75
|
-
* // Using different icon set
|
|
76
|
-
* <IconApp
|
|
77
|
-
* type="FontAwesome"
|
|
78
|
-
* name="user"
|
|
79
|
-
* />
|
|
80
|
-
* ```
|
|
81
|
-
*/
|
|
82
40
|
export default class IconApp extends React.PureComponent<Props> {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
41
|
+
static defaultProps: Props = {
|
|
42
|
+
size: 23,
|
|
43
|
+
color: "gray",
|
|
44
|
+
name: "home",
|
|
45
|
+
};
|
|
89
46
|
|
|
90
|
-
|
|
91
|
-
res: { color: string, style: any, size: number }
|
|
47
|
+
res: { color: string; style: any; size: number };
|
|
92
48
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
49
|
+
constructor(props: Props) {
|
|
50
|
+
super(props);
|
|
51
|
+
this.res = makeProps(props);
|
|
52
|
+
}
|
|
53
|
+
render() {
|
|
54
|
+
const { size, color, style } = this.res;
|
|
55
|
+
if (this.props.name === "none") return null;
|
|
56
|
+
const IconView = RNVectorIcon[this.props.type || "Ionicons"];
|
|
57
|
+
if (typeof this.props.onPress != "function") {
|
|
58
|
+
return (
|
|
59
|
+
<IconView
|
|
60
|
+
size={size}
|
|
61
|
+
color={color}
|
|
62
|
+
style={style}
|
|
63
|
+
name={this.props.name}
|
|
64
|
+
onPress={this.props.onPress}
|
|
65
|
+
/>
|
|
66
|
+
);
|
|
96
67
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
const IconView = RNVectorIcon[this.props.type || 'Ionicons']
|
|
103
|
-
if (typeof this.props.onPress != "function") {
|
|
104
|
-
return (
|
|
105
|
-
<IconView
|
|
106
|
-
size={size}
|
|
107
|
-
color={color}
|
|
108
|
-
style={style}
|
|
109
|
-
name={this.props.name}
|
|
110
|
-
onPress={this.props.onPress}
|
|
111
|
-
/>
|
|
112
|
-
)
|
|
68
|
+
return (
|
|
69
|
+
<TouchableOpacity
|
|
70
|
+
activeOpacity={this.props.activeOpacity || 0.5}
|
|
71
|
+
disabled={
|
|
72
|
+
typeof this.props.onPress == "function" ? this.props.disabled : true
|
|
113
73
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
style={style}
|
|
132
|
-
name={this.props.name}
|
|
133
|
-
onPress={this.props.onPress}
|
|
134
|
-
/>
|
|
135
|
-
</TouchableOpacity>
|
|
136
|
-
)
|
|
137
|
-
}
|
|
74
|
+
style={[
|
|
75
|
+
styles.container,
|
|
76
|
+
{ ...(this.props.alignSelf && { alignSelf: this.props.alignSelf }) },
|
|
77
|
+
this.props.style,
|
|
78
|
+
this.props.styleContainer,
|
|
79
|
+
]}
|
|
80
|
+
>
|
|
81
|
+
<IconView
|
|
82
|
+
size={size}
|
|
83
|
+
color={color}
|
|
84
|
+
style={style}
|
|
85
|
+
name={this.props.name}
|
|
86
|
+
onPress={this.props.onPress}
|
|
87
|
+
/>
|
|
88
|
+
</TouchableOpacity>
|
|
89
|
+
);
|
|
90
|
+
}
|
|
138
91
|
}
|
|
139
92
|
|
|
140
93
|
/**
|
|
141
94
|
* Default styles for the IconApp component
|
|
142
95
|
*/
|
|
143
96
|
const styles = StyleSheet.create({
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
})
|
|
97
|
+
container: {
|
|
98
|
+
alignItems: "center",
|
|
99
|
+
justifyContent: "center",
|
|
100
|
+
alignSelf: "flex-start",
|
|
101
|
+
},
|
|
102
|
+
});
|
package/src/Icon/makeProps.ts
CHANGED
|
@@ -1,11 +1,21 @@
|
|
|
1
|
-
import { StyleSheet } from "react-native";
|
|
2
|
-
|
|
3
|
-
enum COLORS {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
import { StyleSheet, ViewStyle } from "react-native";
|
|
2
|
+
|
|
3
|
+
enum COLORS {
|
|
4
|
+
white = 1,
|
|
5
|
+
red,
|
|
6
|
+
blue,
|
|
7
|
+
black,
|
|
8
|
+
green,
|
|
9
|
+
yellow,
|
|
10
|
+
pink,
|
|
11
|
+
gray,
|
|
12
|
+
primary,
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
type ColorKey = keyof typeof COLORS;
|
|
16
|
+
type ColorModifiers = Partial<Record<ColorKey, boolean>>;
|
|
17
|
+
|
|
18
|
+
const PROPS = {
|
|
9
19
|
mar: "margin",
|
|
10
20
|
marH: "marginHorizontal",
|
|
11
21
|
marV: "marginVertical",
|
|
@@ -13,36 +23,69 @@ const SHORT_VARIATIONS = {
|
|
|
13
23
|
marT: "marginTop",
|
|
14
24
|
marR: "marginRight",
|
|
15
25
|
marB: "marginBottom",
|
|
16
|
-
zIndex:
|
|
17
|
-
opacity:
|
|
18
|
-
size:
|
|
26
|
+
zIndex: "zIndex",
|
|
27
|
+
opacity: "opacity",
|
|
28
|
+
size: "size",
|
|
29
|
+
} as const;
|
|
30
|
+
|
|
31
|
+
export type ShortKey = keyof typeof PROPS;
|
|
32
|
+
|
|
33
|
+
export type Convert<T extends string> = Partial<
|
|
34
|
+
Record<T, boolean | number | string>
|
|
35
|
+
>;
|
|
19
36
|
|
|
37
|
+
export type MakeProp = Convert<ShortKey> & ColorModifiers;
|
|
38
|
+
|
|
39
|
+
/** type guards */
|
|
40
|
+
const isColorKey = (key: string): key is ColorKey => key in COLORS;
|
|
41
|
+
const isShortKey = (key: string): key is ShortKey =>
|
|
42
|
+
key in PROPS;
|
|
43
|
+
|
|
44
|
+
type Result = {
|
|
45
|
+
size: number;
|
|
46
|
+
color: string;
|
|
47
|
+
name: string;
|
|
48
|
+
style: ViewStyle;
|
|
20
49
|
};
|
|
21
|
-
export type ShortKey = keyof typeof SHORT_VARIATIONS;
|
|
22
|
-
export type Convert<T extends string> = Partial<Record<T, boolean | number | string>>
|
|
23
|
-
export type MakeProp = Convert<ShortKey> & ColorModifiers & NameModifiers
|
|
24
50
|
|
|
25
|
-
export const makeProps = (props:
|
|
26
|
-
const style:
|
|
27
|
-
|
|
51
|
+
export const makeProps = (props: Record<string, any>): Result => {
|
|
52
|
+
const style: ViewStyle = {};
|
|
53
|
+
|
|
54
|
+
const res: Omit<Result, "style"> = {
|
|
55
|
+
size: props.size ?? 23,
|
|
56
|
+
color: props.color ?? "gray",
|
|
57
|
+
name: props.name ?? "home",
|
|
58
|
+
};
|
|
59
|
+
|
|
28
60
|
Object.keys(props).forEach((key) => {
|
|
29
|
-
const match = key.match(/^(\w+)-(\w+)$/)
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
res
|
|
34
|
-
|
|
35
|
-
if (NAMES[key]) {
|
|
36
|
-
let match = key.match(/^(\w+)_(\w+)$/) as string[]
|
|
37
|
-
res['name'] = NAMES[match[1]]
|
|
38
|
-
}
|
|
39
|
-
else if (match) {
|
|
40
|
-
const value = isNaN(parseInt(match[2], 10)) ? match[2] : parseInt(match[2], 10)
|
|
41
|
-
if (match[1] == 'size') res['size'] = parseInt(match[2], 10)
|
|
42
|
-
else if (match[1] == 'color') res['color'] = match[2]
|
|
43
|
-
else if (SHORT_VARIATIONS[match[1]]) style[SHORT_VARIATIONS[match[1]]] = value
|
|
61
|
+
const match = key.match(/^(\w+)-(\w+)$/);
|
|
62
|
+
|
|
63
|
+
// color modifier
|
|
64
|
+
if (isColorKey(key)) {
|
|
65
|
+
res.color = key;
|
|
66
|
+
return;
|
|
44
67
|
}
|
|
45
68
|
|
|
69
|
+
if (match) {
|
|
70
|
+
const rawKey = match[1];
|
|
71
|
+
const rawValue = match[2];
|
|
72
|
+
|
|
73
|
+
const value = isNaN(Number(rawValue))
|
|
74
|
+
? rawValue
|
|
75
|
+
: Number(rawValue);
|
|
76
|
+
|
|
77
|
+
if (rawKey === "size") {
|
|
78
|
+
res.size = Number(rawValue);
|
|
79
|
+
} else if (rawKey === "color") {
|
|
80
|
+
res.color = rawValue;
|
|
81
|
+
} else if (isShortKey(rawKey)) {
|
|
82
|
+
(style as any)[PROPS[rawKey]] = value;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
46
85
|
});
|
|
47
|
-
|
|
48
|
-
|
|
86
|
+
|
|
87
|
+
return {
|
|
88
|
+
...res,
|
|
89
|
+
style: StyleSheet.create({ style }).style,
|
|
90
|
+
};
|
|
91
|
+
};
|
package/src/Layout.tsx
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
import SafeAreaView, { ForceInsetProp } from
|
|
3
|
-
import {
|
|
1
|
+
import React from "react";
|
|
2
|
+
import SafeAreaView, { ForceInsetProp } from "react-native-safe-area-view";
|
|
3
|
+
import { StyleProp, ViewStyle } from "react-native";
|
|
4
4
|
export interface LayoutAppProps {
|
|
5
|
-
children?: any
|
|
6
|
-
forceInset?: ForceInsetProp
|
|
7
|
-
forceInsetBot?: ForceInsetProp
|
|
8
|
-
styleBot?: StyleProp<ViewStyle> | undefined
|
|
9
|
-
style?: StyleProp<ViewStyle> | undefined
|
|
10
|
-
isBack?: boolean
|
|
11
|
-
disable?: boolean
|
|
5
|
+
children?: any;
|
|
6
|
+
forceInset?: ForceInsetProp;
|
|
7
|
+
forceInsetBot?: ForceInsetProp;
|
|
8
|
+
styleBot?: StyleProp<ViewStyle> | undefined;
|
|
9
|
+
style?: StyleProp<ViewStyle> | undefined;
|
|
10
|
+
isBack?: boolean;
|
|
11
|
+
disable?: boolean;
|
|
12
12
|
}
|
|
13
13
|
export default function Layout({
|
|
14
14
|
children,
|
|
15
|
-
forceInset = { top:
|
|
16
|
-
forceInsetBot = { vertical:
|
|
15
|
+
forceInset = { top: "always", horizontal: "never", bottom: "never" },
|
|
16
|
+
forceInsetBot = { vertical: "never" },
|
|
17
17
|
styleBot,
|
|
18
18
|
style,
|
|
19
19
|
disable,
|
|
20
20
|
}: LayoutAppProps) {
|
|
21
|
-
if (disable) return <>{children}
|
|
21
|
+
if (disable) return <>{children}</>;
|
|
22
22
|
return (
|
|
23
23
|
<SafeAreaView
|
|
24
24
|
style={[
|
|
@@ -27,7 +27,8 @@ export default function Layout({
|
|
|
27
27
|
},
|
|
28
28
|
style,
|
|
29
29
|
]}
|
|
30
|
-
forceInset={forceInset}
|
|
30
|
+
forceInset={forceInset}
|
|
31
|
+
>
|
|
31
32
|
<SafeAreaView
|
|
32
33
|
style={[
|
|
33
34
|
{
|
|
@@ -35,9 +36,10 @@ export default function Layout({
|
|
|
35
36
|
},
|
|
36
37
|
styleBot,
|
|
37
38
|
]}
|
|
38
|
-
forceInset={forceInsetBot}
|
|
39
|
+
forceInset={forceInsetBot}
|
|
40
|
+
>
|
|
39
41
|
{children}
|
|
40
42
|
</SafeAreaView>
|
|
41
43
|
</SafeAreaView>
|
|
42
|
-
)
|
|
44
|
+
);
|
|
43
45
|
}
|
package/src/Text/Props.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import { TextProps, TextStyle } from 'react-native'
|
|
3
|
-
import { ILanguage } from '../config'
|
|
4
3
|
import { MakeProp } from './makeStyle'
|
|
5
4
|
interface PropsParent {
|
|
6
5
|
children?: React.ReactNode
|
|
@@ -8,10 +7,10 @@ interface PropsParent {
|
|
|
8
7
|
center?: boolean
|
|
9
8
|
italic?: boolean
|
|
10
9
|
underline?: boolean
|
|
11
|
-
color?: string
|
|
10
|
+
color?: string
|
|
12
11
|
toUpperCase?: boolean
|
|
13
12
|
toLowerCase?: boolean
|
|
14
|
-
background?: string
|
|
13
|
+
background?: string
|
|
15
14
|
}
|
|
16
15
|
//@ts-ignore
|
|
17
16
|
export interface Props extends TextProps, PropsParent, MakeProp {
|
|
@@ -25,6 +24,6 @@ export interface Props extends TextProps, PropsParent, MakeProp {
|
|
|
25
24
|
pink?: boolean
|
|
26
25
|
gray?: boolean
|
|
27
26
|
black?: boolean
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
lang?: string
|
|
28
|
+
content?: string
|
|
30
29
|
}
|
package/src/Text/Style.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
1
|
+
|
|
2
|
+
import { StyleSheet } from "react-native";
|
|
3
3
|
|
|
4
4
|
import { Props } from './Props'
|
|
5
5
|
import { makeStyle } from "./makeStyle";
|
|
6
|
-
export const Style: any = (props: Props
|
|
6
|
+
export const Style: any = (props: Props) => {
|
|
7
7
|
const PropsConvert = StyleSheet.flatten([
|
|
8
8
|
props.color && { color: props.color },
|
|
9
9
|
props.center && { textAlign: 'center' },
|
package/src/Text/index.tsx
CHANGED
|
@@ -1,42 +1,45 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { isArray, isObject } from 'underscore'
|
|
1
|
+
import React, { isValidElement } from "react";
|
|
2
|
+
import { StyleSheet, Text } from "react-native";
|
|
3
|
+
import { Style } from "./Style";
|
|
4
|
+
import { Props } from "./Props";
|
|
5
|
+
import { isArray, isObject } from "underscore";
|
|
7
6
|
const TextApp: React.FC<Props> = ({ style, children, ...props }) => {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
if (isValidElement(children)) return children
|
|
22
|
-
return React.createElement(Text, {}, children)
|
|
23
|
-
}
|
|
7
|
+
const Children = () => {
|
|
8
|
+
const content = props?.lang ?? undefined;
|
|
9
|
+
if (typeof content !== "undefined") {
|
|
10
|
+
if (
|
|
11
|
+
typeof content == "string" ||
|
|
12
|
+
typeof content == "number" ||
|
|
13
|
+
isArray(children)
|
|
14
|
+
)
|
|
15
|
+
return content;
|
|
16
|
+
if (typeof content == "function") return "Error content == 'function'";
|
|
17
|
+
if (isObject(children)) return JSON.stringify(children);
|
|
18
|
+
if (isValidElement(content)) return content;
|
|
19
|
+
return React.createElement(Text, {});
|
|
24
20
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
21
|
+
if (typeof children !== "undefined") {
|
|
22
|
+
if (
|
|
23
|
+
typeof children == "string" ||
|
|
24
|
+
typeof children == "number" ||
|
|
25
|
+
isArray(children)
|
|
26
|
+
)
|
|
27
|
+
return children;
|
|
28
|
+
if (isObject(children)) return JSON.stringify(children);
|
|
29
|
+
if (typeof children == "function") return "Error children == 'function'";
|
|
30
|
+
if (isValidElement(children)) return children;
|
|
31
|
+
return React.createElement(Text, {}, children);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
return (
|
|
35
|
+
<Text style={[styles.default, Style(props), style]} {...props}>
|
|
36
|
+
{Children()}
|
|
37
|
+
</Text>
|
|
38
|
+
);
|
|
39
|
+
};
|
|
40
|
+
export default TextApp;
|
|
35
41
|
const styles = StyleSheet.create({
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
paddingTop: 2
|
|
41
|
-
},
|
|
42
|
-
})
|
|
42
|
+
default: {
|
|
43
|
+
fontSize: 14,
|
|
44
|
+
},
|
|
45
|
+
});
|
package/src/Text/makeStyle.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { StyleSheet } from "react-native";
|
|
1
|
+
import { StyleSheet, TextStyle } from "react-native";
|
|
2
2
|
import { isNaN, isNumber } from "underscore";
|
|
3
3
|
enum COLORS {
|
|
4
4
|
"white" = 1,
|
|
@@ -11,9 +11,7 @@ enum COLORS {
|
|
|
11
11
|
"gray",
|
|
12
12
|
"primary"
|
|
13
13
|
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const SHORT_VARIATIONS = {
|
|
14
|
+
const PROPS = {
|
|
17
15
|
bg: "backgroundColor",
|
|
18
16
|
background: "backgroundColor",
|
|
19
17
|
color: "color",
|
|
@@ -54,31 +52,54 @@ const SHORT_VARIATIONS = {
|
|
|
54
52
|
bottom: 'bottom',
|
|
55
53
|
right: 'right',
|
|
56
54
|
opacity: 'opacity',
|
|
57
|
-
//
|
|
58
55
|
size: 'fontSize'
|
|
56
|
+
} as const;
|
|
57
|
+
const isColorKey = (key: string): key is ColorKey => {
|
|
58
|
+
return key in COLORS;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const isShortKey = (key: string): key is ShortKey => {
|
|
62
|
+
return key in PROPS;
|
|
59
63
|
};
|
|
60
|
-
|
|
64
|
+
|
|
65
|
+
export type ColorKey = keyof typeof COLORS;
|
|
66
|
+
export type ShortKey = keyof typeof PROPS;
|
|
61
67
|
export type Convert<T extends string> = Partial<Record<T, boolean | number | string>>
|
|
62
|
-
export type MakeProp =
|
|
68
|
+
export type MakeProp =
|
|
69
|
+
Partial<Record<ShortKey, number | string>> &
|
|
70
|
+
Partial<Record<ColorKey, boolean>> &
|
|
71
|
+
Record<string, any>;
|
|
63
72
|
|
|
64
73
|
export const makeStyle = (props: { [key: string]: any }) => {
|
|
65
|
-
const style:
|
|
74
|
+
const style: TextStyle = {};
|
|
66
75
|
Object.keys(props).forEach((key) => {
|
|
67
|
-
const match = key.match(/^(\w+)-(\w+)$/)
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
const value = isNaN(parseInt(match[2], 10)) ? match[2] : parseInt(match[2], 10)
|
|
73
|
-
if (SHORT_VARIATIONS[match[1]]) style[SHORT_VARIATIONS[match[1]]] = value
|
|
74
|
-
else style[match[1]] = value
|
|
76
|
+
const match = key.match(/^(\w+)-(\w+)$/);
|
|
77
|
+
|
|
78
|
+
if (isColorKey(key)) {
|
|
79
|
+
style.backgroundColor = key;
|
|
80
|
+
return;
|
|
75
81
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
82
|
+
|
|
83
|
+
if (match) {
|
|
84
|
+
const [, rawKey, rawValue] = match;
|
|
85
|
+
|
|
86
|
+
const value = isNaN(Number(rawValue))
|
|
87
|
+
? rawValue
|
|
88
|
+
: Number(rawValue);
|
|
89
|
+
|
|
90
|
+
if (isShortKey(rawKey)) {
|
|
91
|
+
style[PROPS[rawKey]] = value as any;
|
|
92
|
+
} else {
|
|
93
|
+
(style as any)[rawKey] = value;
|
|
79
94
|
}
|
|
80
|
-
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// 🔹 Normal props
|
|
99
|
+
if (isShortKey(key)) {
|
|
100
|
+
style[PROPS[key]] = props[key] as any;
|
|
81
101
|
}
|
|
82
102
|
});
|
|
103
|
+
|
|
83
104
|
return StyleSheet.create({ style }).style;
|
|
84
|
-
};
|
|
105
|
+
};
|