ui-rn 1.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.
@@ -0,0 +1,28 @@
1
+ import { StyleSheet, Text, View } from 'react-native'
2
+ import React from 'react'
3
+ import { Polygon, Svg } from 'react-native-svg'
4
+ export default function Hexagon({ width = 100, stroke = "black", strokeWidth = "2", fill = "lightblue" }) {
5
+ const diameter = width
6
+ const radius = (diameter / 2)
7
+ const m = (Math.sqrt(3) / 2) * radius// Math.sin(60) * radius //-> x
8
+ const n = (1 / 2) * radius//Math.cos(60) * radius//-> y
9
+ const hexagonPoints = [
10
+ { x: radius, y: 0 },
11
+ { x: radius + m, y: radius - n },//60
12
+ { x: radius + m, y: radius + n },
13
+ { x: radius, y: diameter },//180
14
+ { x: radius - m, y: radius + n },
15
+ { x: radius - m, y: radius - n },
16
+ { x: radius, y: 0 },
17
+ ]
18
+ const points = hexagonPoints.map(point => `${point.x},${point.y}`).join(' ');
19
+ return (
20
+ <View style={{ alignItems: 'center', justifyContent: 'center', flex: 1 }}>
21
+ <Svg height={diameter} width={width}>
22
+ <Polygon points={points} fill={fill} stroke={stroke} strokeWidth={strokeWidth} />
23
+ </Svg>
24
+ </View>
25
+ );
26
+ };
27
+
28
+ const styles = StyleSheet.create({})
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 Phạm Trần Quang Hà
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,29 @@
1
+ Install:
2
+
3
+ ```js
4
+ npm install ui-rn
5
+ ```
6
+
7
+ Example :
8
+
9
+ ```tsx
10
+ import {StyleSheet, Text, View} from 'react-native';
11
+ import React from 'react';
12
+ import Hexagon from 'ui-rn';
13
+ export default function App() {
14
+ return (
15
+ <View style={styles.container}>
16
+ <Text>App</Text>
17
+ <Block></Block>
18
+ </View>
19
+ );
20
+ }
21
+
22
+ const styles = StyleSheet.create({
23
+ container: {
24
+ flex: 1,
25
+ justifyContent: 'center',
26
+ alignItems: 'center',
27
+ },
28
+ });
29
+ ```
package/ZoomImg.tsx ADDED
@@ -0,0 +1,206 @@
1
+ import { Animated, Modal, StyleSheet, Text, TouchableOpacity, View } from 'react-native'
2
+ import React, { useEffect } from 'react'
3
+ import { Image, ImageProps } from 'react-native'
4
+ import { ImageZoom, ZoomableRef } from '@likashefqet/react-native-image-zoom';
5
+ import { GestureHandlerRootView } from 'react-native-gesture-handler';
6
+ import { Dimensions } from 'react-native';
7
+ import { isNumber } from 'underscore';
8
+ import { Platform } from 'react-native';
9
+ import { StatusBar } from 'react-native';
10
+ import SafeAreaView from 'react-native-safe-area-view'
11
+
12
+
13
+ const { width, height } = Dimensions.get('screen')
14
+ const HIT_SLOP = { top: 16, left: 16, bottom: 16, right: 16 };
15
+ const TIME = 50
16
+ interface ZoomImageProps extends ImageProps {
17
+ uri: string
18
+ }
19
+ interface ZoomImageState {
20
+ visible: boolean
21
+ disableZoonOut: boolean
22
+ }
23
+ export default class ZoomImg extends React.Component<ZoomImageProps, ZoomImageState> {
24
+ ref = React.createRef<ZoomableRef>()
25
+ scale: number = 1
26
+ scale_v = 0.3
27
+ _startZoomIn: any
28
+ _startZoomOut: any
29
+ constructor(props: ZoomImageProps) {
30
+ super(props)
31
+ this.state = {
32
+ visible: false,
33
+ disableZoonOut: true
34
+ }
35
+ this.zoomIn = this.zoomIn.bind(this)
36
+ this.zoomOut = this.zoomOut.bind(this)
37
+ this.startZoomIn = this.startZoomIn.bind(this)
38
+ this.stopZoomIn = this.stopZoomIn.bind(this)
39
+ this.startZoomOut = this.startZoomOut.bind(this)
40
+ this.stopZoomOut = this.stopZoomOut.bind(this)
41
+
42
+ }
43
+ onZoom(e?: any) { }
44
+ zoomIn() {
45
+ const { disableZoonOut } = this.state
46
+ if (disableZoonOut) { this.setState({ disableZoonOut: false }) }
47
+ this.scale = this.scale + this.scale_v
48
+ this.ref.current?.zoom({ scale: this.scale, x: width / 2, y: height / 2 })
49
+ }
50
+ zoomOut() {
51
+ if (this.scale - this.scale_v <= 1) {
52
+ this.ref.current?.zoom({ scale: 1, x: 0, y: 0 })
53
+ this.setState({ disableZoonOut: true })
54
+ return
55
+ }
56
+ this.scale = this.scale - this.scale_v
57
+ this.ref.current?.zoom({ scale: this.scale, x: width / 2, y: height / 2 })
58
+ }
59
+ startZoomIn() { this._startZoomIn = setInterval(() => { this.zoomIn() }, TIME); }
60
+ stopZoomIn() { if (this._startZoomIn) clearInterval(this._startZoomIn) }
61
+ startZoomOut() { this._startZoomOut = setInterval(() => { this.zoomOut() }, TIME); }
62
+ stopZoomOut() { if (this._startZoomOut) clearInterval(this._startZoomOut) }
63
+
64
+ open() { this.setState({ visible: true }) }
65
+ close() { this.setState({ visible: false }) }
66
+ render(): React.ReactNode {
67
+ const { uri, style, source } = this.props
68
+ const { visible, disableZoonOut, } = this.state
69
+ const styleButton = { hitSlop: HIT_SLOP }
70
+ if (isNumber(source)) return <Image source={source} style={style} />
71
+ //@ts-ignore
72
+ const value = uri ?? source.uri
73
+ return (
74
+ <>
75
+ <TouchableOpacity onPress={() => this.open()}>
76
+ <Image source={{ uri: value }} style={style} />
77
+ </TouchableOpacity>
78
+ <Modal visible={visible} presentationStyle='fullScreen'>
79
+ <StatusBarManager presentationStyle='overFullScreen' />
80
+ <SafeAreaView forceInset={{ top: 'always', }} style={{ flex: 1, backgroundColor: '#000' }}>
81
+ <GestureHandlerRootView style={styles.container}>
82
+ <View style={[styles.header]}>
83
+ <SafeAreaView style={styles.root}>
84
+ <TouchableOpacity style={styles.closeButton} onPress={() => this.close()} hitSlop={HIT_SLOP}>
85
+ <Text style={styles.closeText}>✕</Text>
86
+ </TouchableOpacity>
87
+ <TouchableOpacity style={styles.closeButton} onPress={this.zoomIn} onLongPress={this.startZoomIn} onPressOut={this.stopZoomIn} {...styleButton}>
88
+ <Text style={[styles.closeText, styles.actionText]}>+</Text>
89
+ </TouchableOpacity>
90
+ <TouchableOpacity style={[styles.closeButton, { backgroundColor: disableZoonOut ? "#0000001F" : "#00000077" }]} disabled={disableZoonOut} onPress={this.zoomOut} onLongPress={this.startZoomOut} onPressOut={this.stopZoomOut} {...styleButton}>
91
+ <Text style={[styles.closeText, styles.actionText]}>-</Text>
92
+ </TouchableOpacity>
93
+ </SafeAreaView>
94
+ </View>
95
+ <ImageZoom
96
+ ref={this.ref}
97
+ uri={value}
98
+ minScale={1}
99
+ maxScale={3}
100
+ // scale={4}
101
+ doubleTapScale={3}
102
+ isSingleTapEnabled
103
+ isDoubleTapEnabled
104
+ onInteractionStart={() => {
105
+ console.log('onInteractionStart');
106
+ this.onZoom();
107
+ }}
108
+ onInteractionEnd={() => console.log('onInteractionEnd')}
109
+ onPanStart={() => console.log('onPanStart')}
110
+ onPanEnd={() => console.log('onPanEnd')}
111
+ onPinchStart={() => console.log('onPinchStart')}
112
+ onPinchEnd={() => console.log('onPinchEnd')}
113
+ onSingleTap={() => console.log('onSingleTap')}
114
+ onDoubleTap={(zoomType) => {
115
+ console.log('onDoubleTap', zoomType);
116
+ this.onZoom(zoomType);
117
+ }}
118
+ onProgrammaticZoom={(zoomType) => {
119
+ console.log('onZoom', zoomType);
120
+ this.onZoom(zoomType);
121
+ }}
122
+ style={styles.image}
123
+ onResetAnimationEnd={(finished, values) => {
124
+ console.log('onResetAnimationEnd', finished);
125
+ console.log('lastScaleValue:', values?.SCALE.lastValue);
126
+ // onAnimationEnd(finished);
127
+ }}
128
+ resizeMode="contain"
129
+ />
130
+ </GestureHandlerRootView >
131
+ </SafeAreaView>
132
+ </Modal>
133
+ </>
134
+ )
135
+ }
136
+
137
+ }
138
+
139
+ const styles = StyleSheet.create({
140
+ container: {
141
+ flex: 1,
142
+ backgroundColor: "#000",
143
+ },
144
+ image: {
145
+ width: width,
146
+ height: height,
147
+ resizeMode: 'contain'
148
+ },
149
+ header: {
150
+ position: "absolute",
151
+ width: "100%",
152
+ zIndex: 1,
153
+ top: 0,
154
+ },
155
+ action: {
156
+ position: "absolute",
157
+ width: "100%",
158
+ zIndex: 1,
159
+ top: 100,
160
+ },
161
+ root: {
162
+ alignItems: "flex-end",
163
+ },
164
+ closeButton: {
165
+ marginRight: 8,
166
+ marginTop: 8,
167
+ width: 44,
168
+ height: 44,
169
+ alignItems: "center",
170
+ justifyContent: "center",
171
+ borderRadius: 22,
172
+ backgroundColor: "#00000077",
173
+ },
174
+ closeText: {
175
+ lineHeight: 22,
176
+ fontSize: 19,
177
+ textAlign: "center",
178
+ color: "#FFF",
179
+ includeFontPadding: false,
180
+ },
181
+ actionButton: {
182
+ marginRight: 5,
183
+ marginTop: 8,
184
+ width: 40,
185
+ height: 40,
186
+ alignItems: "center",
187
+ justifyContent: "center",
188
+ borderRadius: 22,
189
+ backgroundColor: "#00000077",
190
+ },
191
+ actionText: {
192
+ fontSize: 24
193
+ }
194
+ })
195
+ const StatusBarManager = ({ presentationStyle, }: { presentationStyle?: "fullScreen" | "pageSheet" | "formSheet" | "overFullScreen" | undefined; }) => {
196
+ if (Platform.OS === "ios" || presentationStyle !== "overFullScreen") {
197
+ return null;
198
+ }
199
+ //Can't get an actual state of app status bar with default RN. Gonna rely on "presentationStyle === overFullScreen" prop and guess application status bar state to be visible in this case.
200
+ StatusBar.setHidden(true);
201
+ useEffect(() => {
202
+ StatusBar.setHidden(true);
203
+ return () => StatusBar.setHidden(false);
204
+ }, []);
205
+ return null;
206
+ };
package/package.json ADDED
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "ui-rn",
3
+ "version": "1.0.0",
4
+ "repository": "https://github.com/phamha98/ui-rn",
5
+ "description": "ui-rn",
6
+ "author": "Phamha98",
7
+ "main": "src/index.tsx",
8
+ "scripts": {
9
+ "test": "echo \"Error: no test specified\" && exit 1"
10
+ },
11
+ "license": "ISC",
12
+ "keywords": [
13
+ "ui-rn"
14
+ ]
15
+ }
@@ -0,0 +1,41 @@
1
+ import React from "react";
2
+ import { Platform, StatusBar } from "react-native";
3
+ import DropdownAlert from "react-native-dropdownalert";
4
+ const ref = React.createRef<DropdownAlert>()
5
+
6
+ export default function AlertApp() {
7
+ return (
8
+ <DropdownAlert
9
+ ref={ref}
10
+ inactiveStatusBarBackgroundColor={'green'}
11
+ updateStatusBar={false}
12
+ errorColor={'#B57F00'}
13
+ successColor={'#238209'}
14
+ // errorImageSrc={Images('logo')}
15
+ // successImageSrc={Images('logo')}
16
+ imageStyle={{
17
+ padding: 8,
18
+ width: 36,
19
+ height: 36,
20
+ alignSelf: 'center',
21
+ borderRadius: 23,
22
+ }}
23
+ elevation={40}
24
+ containerStyle={{ backgroundColor: 'pink' }}
25
+ closeInterval={1300}
26
+ showCancel={false}
27
+ wrapperStyle={{ marginTop: Platform.OS == "ios" ? 0 : StatusBar.currentHeight }}
28
+ />
29
+ )
30
+ }
31
+ export class AlertPush {
32
+ static warn(title: string = 'title', message: string = '') {
33
+ ref.current?.alertWithType('warn', title, message)
34
+ }
35
+ static error(title: string = 'title', message: string = '') {
36
+ ref.current?.alertWithType('error', title, message)
37
+ }
38
+ static success(title: string = 'title', message: string = '') {
39
+ ref.current?.alertWithType('success', title, message)
40
+ }
41
+ }
@@ -0,0 +1,32 @@
1
+ import {
2
+ RNVectorIcon,
3
+ } from "./index"
4
+ import React from 'react'
5
+ import {
6
+ FlexStyle,
7
+ StyleProp,
8
+ StyleSheet,
9
+ TextProps,
10
+ TextStyle,
11
+ TouchableOpacity,
12
+ ViewProps,
13
+ ViewStyle,
14
+ } from 'react-native'
15
+
16
+ import { isArray, isEmpty, isNumber, isObject, isString } from "underscore";
17
+ export interface Props {
18
+ name: string
19
+ size?: number | Array<size>
20
+ type?: keyof typeof RNVectorIcon
21
+ onPress?: () => void
22
+ styleContainer?: StyleProp<ViewStyle>
23
+ style?: StyleProp<TextStyle>
24
+ alignSelf?: FlexStyle['alignSelf']
25
+ disabled?: boolean
26
+ activeOpacity?: number
27
+ color?: string
28
+
29
+ }
30
+
31
+ type size = 18 | 20 | 22 | 23 | 24 | 25 | 26 | 28 | 30 | 32 | 34 | 36
32
+
@@ -0,0 +1,98 @@
1
+ import React from 'react'
2
+ import {
3
+ FlexStyle,
4
+ StyleProp,
5
+ StyleSheet,
6
+ TextProps,
7
+ TextStyle,
8
+ TouchableOpacity,
9
+ ViewProps,
10
+ ViewStyle,
11
+ } from 'react-native'
12
+ import Ionicons from 'react-native-vector-icons/Ionicons'
13
+ import EvilIcons from 'react-native-vector-icons/EvilIcons'
14
+ import FontAwesome from 'react-native-vector-icons/FontAwesome'
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'
26
+ export const RNVectorIcon = {
27
+ Ionicons,
28
+ AntDesign,
29
+ Entypo,
30
+ EvilIcons,
31
+ MaterialIcons,
32
+ MaterialCommunityIcons,
33
+ FontAwesome,
34
+ FontAwesome5,
35
+ SimpleLineIcons,
36
+ Feather,
37
+ Octicons,
38
+ Fontisto
39
+ }
40
+ export type IconType = keyof typeof RNVectorIcon
41
+ import { Props, } from './PropsStyle'
42
+ import { Colors } from '../config'
43
+ export default class IconApp extends React.PureComponent<Props> {
44
+ static defaultProps: Props = {
45
+ size: 23,
46
+ color: 'gray',
47
+ name: 'home',
48
+ }
49
+ render() {
50
+ if (this.props.name === "none") return null
51
+ const IconView = RNVectorIcon[this.props.type || 'Ionicons']
52
+ if (typeof this.props.onPress != "function") {
53
+ return (
54
+ <IconView
55
+ //@ts-ignore
56
+ size={this.props.size}
57
+ //@ts-ignore
58
+ color={Colors[this.props.color] ?? this.props.color}
59
+ name={this.props.name}
60
+ onPress={this.props.onPress}
61
+ style={this.props.style as any}
62
+ />
63
+ )
64
+ }
65
+ return (
66
+ <TouchableOpacity
67
+ activeOpacity={this.props.activeOpacity || 0.5}
68
+ disabled={
69
+ typeof this.props.onPress == 'function' ? this.props.disabled : true
70
+ }
71
+ style={
72
+ [
73
+ styles.container,
74
+ { ...(this.props.alignSelf && { alignSelf: this.props.alignSelf }) },
75
+ this.props.style,
76
+ this.props.styleContainer,
77
+
78
+ ]} >
79
+ <IconView //@ts-ignore
80
+ size={this.props.size}
81
+ //@ts-ignore
82
+ color={Colors[this.props.color] ?? this.props.color}
83
+ name={this.props.name}
84
+ onPress={this.props.onPress}
85
+ style={this.props.style as any}
86
+ />
87
+ </TouchableOpacity>
88
+ )
89
+ }
90
+ }
91
+
92
+ const styles = StyleSheet.create({
93
+ container: {
94
+ alignItems: 'center',
95
+ justifyContent: 'center',
96
+ alignSelf: 'flex-start',
97
+ },
98
+ })
@@ -0,0 +1,35 @@
1
+ import React from 'react'
2
+ import { StyleSheet, View } from 'react-native'
3
+ import { Style } from './Style'
4
+ import { Props } from './Props'
5
+ import { isArray, isString } from 'underscore';
6
+ import LinearGradient from 'react-native-linear-gradient'
7
+
8
+ type TouchableOpacityRef = React.ComponentRef<typeof View>
9
+ const Block = React.forwardRef<TouchableOpacityRef, Props>(({ style, ...props }, ref) => {
10
+ if (props?.hidden) return <></>
11
+ //@ts-ignore
12
+ if (isArray(props.background) && props.background.length > 1 && props.background.every(i => isString(i)))
13
+ return (
14
+ <LinearGradient
15
+ //@ts-ignore
16
+ colors={props.background}
17
+ start={props.gradient == "vertical" ? { x: 0, y: 0 } : { x: 0, y: 0 }}
18
+ end={props.gradient == "vertical" ? { x: 0, y: 1 } : { x: 1, y: 0 }}
19
+ style={[Style(props), style, props.styleBox]}>
20
+ {props.children}
21
+ </LinearGradient >
22
+ )
23
+ //@ts-ignore
24
+ return (<View ref={ref} style={[Style(props), style, props.styleBox]}
25
+ {...props}>
26
+ {props.children}
27
+ </View>
28
+ )
29
+ })
30
+
31
+ export default Block
32
+ const styles = StyleSheet.create({
33
+ defaultTouch: {
34
+ },
35
+ })
@@ -0,0 +1,134 @@
1
+ import { ColorName } from "@assets/colors"
2
+ import { StyleProp, FlexStyle, TouchableWithoutFeedbackProps, ViewStyle } from "react-native"
3
+ type B = boolean
4
+ type N = number
5
+ type S = string
6
+ export interface PropsConvert {
7
+ bg?: S | Array<ColorName>
8
+ w?: FlexStyle['width']
9
+ h?: FlexStyle['height']
10
+ pad?: N
11
+ padH?: N
12
+ padV?: N
13
+ padL?: N
14
+ padT?: N
15
+ padR?: N
16
+ padB?: N
17
+ flex?: N
18
+ mar?: N
19
+ marH?: N
20
+ marV?: N
21
+ marL?: N
22
+ marT?: N
23
+ marR?: N
24
+ marB?: N
25
+ minW?: N
26
+ maxW?: N
27
+ minH?: N
28
+ maxH?: N
29
+ borderC?: S | Array<color>
30
+ borderW?: N | Array<border>
31
+ borderLW?: N | Array<border>
32
+ borderTW?: N | Array<border>
33
+ borderRW?: N | Array<border>
34
+ borderBW?: N | Array<border>
35
+ borderR?: N | Array<size>
36
+ borderUpRadius?: N | Array<size>
37
+ borderDownRadius?: N | Array<size>
38
+ alignItems?: FlexStyle['alignItems']
39
+ alignSelf?: FlexStyle['alignSelf']
40
+ justifyContent?: FlexStyle['justifyContent']
41
+ borderStyle?: ViewStyle['borderStyle']
42
+ opacity?: ViewStyle['opacity']
43
+ overflow?: ViewStyle['overflow']
44
+ zIndex?: ViewStyle['opacity']
45
+
46
+ }
47
+ export interface PropsApp {
48
+ _background?: S//old
49
+ alignI?: FlexStyle['alignItems']//old
50
+ justifyC?: FlexStyle['justifyContent']//old
51
+ bgW?: B//old
52
+ positionA?: boolean//old
53
+ left0?: boolean //old
54
+ top0?: boolean //old
55
+ right0?: boolean//old
56
+ bottom0?: boolean //old
57
+ centerH?: boolean //old
58
+ overH?: B //old
59
+ w100?: B //old
60
+ h100?: B //old
61
+ width?: FlexStyle['width']//old
62
+ height?: FlexStyle['height']//old
63
+ borderR100?: boolean
64
+ //
65
+ mid?: B
66
+ row?: B
67
+ alignCenter?: B
68
+ justifyCenter?: B
69
+ borderCircle?: B
70
+ centerBetween?: B
71
+ justifyBetween?: B
72
+ overHidden?: B
73
+ square?: N
74
+ width100?: B
75
+ height100?: B
76
+ white?: B
77
+ red?: B
78
+ blue?: B
79
+ black?: B
80
+ green?: B
81
+ yellow?: B
82
+ pink?: B
83
+ gray?: B
84
+ primary?: B
85
+ background?: Array<ColorName> | Array<(S)> | S
86
+ gradient?: 'vertical' | 'horizontal'
87
+ flexOne?: B//old
88
+ shadowColor?: S | B
89
+ //option
90
+ borderOption?: { top?: N, left?: N, right?: N, bottom?: N, color?: S }
91
+ positionOption?: { top?: N, left?: N, right?: N, bottom?: N }
92
+ paddingOption?: { all?: N, top?: N, left?: N, right?: N, bottom?: N }
93
+ paddingFlex?: { vertical?: N, horizontal?: N }
94
+ marginFlex?: { vertical?: N, horizontal?: N }
95
+ marginOption?: { all?: N, top?: N, left?: N, right?: N, bottom?: N }
96
+ shadowOption?: { color?: S, width?: N, height?: N, opacity?: N, radius?: N, elevation?: N }
97
+ //recent
98
+ pad5?: B; pad10?: B; pad20?: B;
99
+ padV5?: B; padV10?: B; padV20?: B;
100
+ padH5?: B; padH10?: B; padH20?: B;
101
+ padL5?: B; padL10?: B; padL20?: B;
102
+ padT5?: B; padT10?: B; padT20?: B;
103
+ padR5?: B; padR10?: B; padR20?: B;
104
+ padB5?: B; padB10?: B; padB20?: B;
105
+ //
106
+ mar5?: B; mar10?: B; mar20?: B;
107
+ marH5?: B; marH10?: B; marH20?: B;
108
+ marV5?: B; marV10?: B; marV20?: B;
109
+ marL5?: B; marL10?: B; marL20?: B;
110
+ marT5?: B; marT10?: B; marT20?: B;
111
+ marR5?: B; marR10?: B; marR20?: B;
112
+ marB5?: B; marB10?: B; marB20?: B;
113
+ //
114
+ flex1?: B; flex2?: B; flex3?: B; flex4?: B; flex5?: B; flex6?: B; flex7?: B; flex8?: B; flex9?: B;
115
+ borderR2?: B; borderR5?: B; borderR10?: B; borderR15?: B; borderR20?: B;
116
+ borderW1?: B; borderW2?: B; borderW3?: B; borderW4?: B; borderW5?: B;
117
+ /**'padding30;marginTop6;borderRadius11;' */
118
+ styleChar?: S
119
+ //
120
+ widthScreen?: boolean
121
+ heightScreen?: boolean
122
+ }
123
+ export interface Props extends TouchableWithoutFeedbackProps, PropsConvert, PropsApp {
124
+ children?: React.ReactNode
125
+ styleBox?: StyleProp<ViewStyle>
126
+ hidden?: B
127
+ activeOpacity?: N
128
+ }
129
+ /**
130
+ * backfaceVisibility:route hidden
131
+ */
132
+ type size = 0 | 5 | 10 | 15 | 20 | 30 | 40 | 50 | 100
133
+ type color = '#ddd' | '#fff' | '#eee' | '#000' | 'white' | 'blue' | 'green' | 'pink' | 'yellow' | "white" | 'black' | 'blue'
134
+ type border = 0.3 | 0.5 | 0.8 | 1 | 2 | 3 | 4 | 5
@@ -0,0 +1,187 @@
1
+ import { StyleProp, ViewStyle, StyleSheet, Dimensions } from "react-native";
2
+ import { isArray, isEmpty, isNumber, isObject, isString } from "underscore";
3
+ import { Props } from './Props'
4
+ import { Colors } from "../config";
5
+
6
+ export const Style: any = (props: Props) => {
7
+ const PropsConvert = StyleSheet.flatten([
8
+ props.bg && { backgroundColor: props.bg },
9
+ props.background && { backgroundColor: props.background },
10
+ props.w && { width: props.w },
11
+ props.minW && { minWidth: props.minW },
12
+ props.maxW && { maxWidth: props.maxW },
13
+ props.h && { height: props.h },
14
+ props.minH && { minHeight: props.minH },
15
+ props.maxH && { maxHeight: props.maxH },
16
+ props.pad && { padding: props.pad },
17
+ props.padH && { paddingHorizontal: props.padH },
18
+ props.padV && { paddingVertical: props.padV },
19
+ props.padL && { paddingLeft: props.padL },
20
+ props.padT && { paddingTop: props.padT },
21
+ props.padR && { paddingRight: props.padR },
22
+ props.padB && { paddingBottom: props.padB },
23
+ props.mar && { margin: props.mar },
24
+ props.marH && { marginHorizontal: props.marH },
25
+ props.marV && { marginVertical: props.marV },
26
+ props.marL && { marginLeft: props.marL },
27
+ props.marT && { marginTop: props.marT },
28
+ props.marR && { marginRight: props.marR },
29
+ props.marB && { marginBottom: props.marB },
30
+ //new
31
+ props.borderR && { borderRadius: (props.borderR) },
32
+ props.borderC && { borderColor: (props.borderC) },
33
+ props.borderW && { borderWidth: (props.borderW) },
34
+ props.borderLW && { borderLeftWidth: (props.borderLW) },
35
+ props.borderTW && { borderTopWidth: (props.borderTW) },
36
+ props.borderRW && { borderRightWidth: (props.borderRW) },
37
+ props.borderBW && { borderBottomWidth: (props.borderBW) },
38
+ //new
39
+ props.alignItems && { alignItems: props.alignItems },
40
+ props.justifyContent && { justifyContent: props.justifyContent },
41
+ props.borderStyle && { borderStyle: props.borderStyle },
42
+ props.opacity && { opacity: props.opacity },
43
+ props.overflow && { overflow: props.overflow },
44
+ props.zIndex && { zIndex: props.zIndex },
45
+
46
+ ])
47
+ const PropsApp = StyleSheet.flatten([
48
+ props._background && { backgroundColor: props._background },
49
+ props.borderUpRadius && { borderTopLeftRadius: (props.borderUpRadius), borderTopRightRadius: (props.borderUpRadius) },
50
+ props.borderDownRadius && { borderBottomLeftRadius: (props.borderUpRadius), borderBottomRightRadius: (props.borderUpRadius) },
51
+ //
52
+ props.mid && { alignItems: 'center', justifyContent: 'center' },
53
+ props.row && { flexDirection: 'row' },
54
+ props.width100 && { width: '100%' },
55
+ props.height100 && { height: '100%' },
56
+ props.square && { width: props.square, height: props.square },
57
+ props.borderCircle && { borderRadius: 1000 },
58
+ props.alignCenter && { alignItems: 'center' },
59
+ props.justifyCenter && { justifyContent: 'center' },
60
+ props.justifyBetween && { justifyContent: 'space-between' },
61
+ props.overHidden && { overflow: 'hidden' },
62
+ props.centerBetween && { alignItems: 'center', justifyContent: 'space-between', },
63
+
64
+ props.white && { backgroundColor: "white" }, props.black && { backgroundColor: "black" }, props.red && { backgroundColor: "red" },
65
+ props.blue && { backgroundColor: "blue" }, props.green && { backgroundColor: "green" },
66
+ props.yellow && { backgroundColor: "yellow" }, props.pink && { backgroundColor: "pink" },
67
+ props.gray && { backgroundColor: "gray" }, props.primary && { backgroundColor: Colors['primary'] },
68
+ //
69
+ props.positionOption && {
70
+ position: 'absolute',
71
+ top: props.positionOption?.top,
72
+ bottom: props.positionOption?.bottom,
73
+ left: props.positionOption?.left,
74
+ right: props.positionOption?.right,
75
+ },
76
+ props.paddingOption && {
77
+ paddingLeft: props.paddingOption?.all || props.paddingOption?.left,
78
+ paddingTop: props.paddingOption?.all || props.paddingOption?.top,
79
+ paddingRight: props.paddingOption?.all || props.paddingOption?.right,
80
+ paddingBottom: props.paddingOption?.all || props.paddingOption?.bottom,
81
+ },
82
+ props.marginOption && {
83
+ marginLeft: props.marginOption?.all || props.marginOption?.left,
84
+ marginTop: props.marginOption?.all || props.marginOption?.top,
85
+ marginRight: props.marginOption?.all || props.marginOption?.right,
86
+ marginBottom: props.marginOption?.all || props.marginOption?.bottom,
87
+ },
88
+ props.borderOption && {
89
+ borderLeftWidth: props.borderOption.left,
90
+ borderTopWidth: props.borderOption.top,
91
+ borderBottomWidth: props.borderOption.bottom,
92
+ borderRightWidth: props.borderOption.right,
93
+ borderColor: props.borderOption.color,
94
+ },
95
+ props.marginFlex && {
96
+ paddingHorizontal: props.marginFlex.horizontal,
97
+ paddingVertical: props.marginFlex.vertical,
98
+ },
99
+ props.paddingFlex && {
100
+ paddingHorizontal: props.paddingFlex.horizontal,
101
+ paddingVertical: props.paddingFlex.vertical,
102
+ },
103
+ !isEmpty(props.shadowOption) && {
104
+ shadowColor: props.shadowOption?.color,
105
+ shadowOffset: {
106
+ width: props.shadowOption?.width,
107
+ height: props.shadowOption?.height,
108
+ },
109
+ shadowOpacity: props.shadowOption?.opacity,
110
+ shadowRadius: props.shadowOption?.radius,
111
+ elevation: props.shadowOption?.elevation,
112
+ },
113
+ props.shadowColor && {
114
+ shadowColor: isString(props.shadowColor) ? props.shadowColor : '#000',
115
+ shadowOffset: { width: 2, height: 2, },
116
+ shadowOpacity: 1,
117
+ shadowRadius: 10,
118
+ elevation: 2,
119
+ },
120
+ props.pad5 && { padding: 5 }, props.pad10 && { padding: 10 }, props.pad20 && { padding: 20 },
121
+ props.padV5 && { paddingVertical: 5 },
122
+ props.padV10 && { paddingVertical: 10 }, props.padV20 && { paddingVertical: 20 },
123
+ props.padH5 && { paddingHorizontal: 5 }, props.padH10 && { paddingHorizontal: 10 },
124
+ props.padH20 && { paddingHorizontal: 20 }, props.padL10 && { paddingLeft: 10 },
125
+ props.padT10 && { paddingTop: 10 }, props.padR10 && { paddingRight: 10 },
126
+ props.padB10 && { paddingBottom: 10 }, props.mar5 && { margin: 5 },
127
+ props.mar10 && { margin: 10 }, props.mar20 && { margin: 20 },
128
+ props.marH5 && { marginHorizontal: 5 }, props.marH10 && { marginHorizontal: 10 },
129
+ props.marH20 && { marginHorizontal: 20 }, props.marV5 && { marginVertical: 5 },
130
+ props.marV10 && { marginVertical: 10 }, props.marV20 && { marginVertical: 20 },
131
+ props.marL10 && { marginLeft: 10 }, props.marT10 && { marginTop: 10 },
132
+ props.marR10 && { marginRight: 10 },
133
+ props.marB5 && { marginBottom: 5 }, props.marB10 && { marginBottom: 10 }, props.marB20 && { marginBottom: 20 },
134
+ /** */
135
+
136
+ props.pad5 && { padding: 5 }, props.pad10 && { padding: 10 }, props.pad20 && { padding: 20 },
137
+ props.padV5 && { paddingVertical: 5 }, props.padV10 && { paddingVertical: 10 }, props.padV20 && { paddingVertical: 20 },
138
+ props.padH5 && { paddingHorizontal: 5 }, props.padH10 && { paddingHorizontal: 10 }, props.padH20 && { paddingHorizontal: 20 },
139
+ props.padL5 && { paddingLeft: 5 }, props.padL10 && { paddingLeft: 10 }, props.padL20 && { paddingLeft: 20 },
140
+ props.padT5 && { paddingTop: 5 }, props.padT10 && { paddingTop: 10 }, props.padT20 && { paddingTop: 20 },
141
+ props.padR5 && { paddingRight: 5 }, props.padR10 && { paddingRight: 10 }, props.padR20 && { paddingRight: 20 },
142
+ props.padB5 && { paddingBottom: 5 }, props.padB10 && { paddingBottom: 10 }, props.padB20 && { paddingBottom: 20 },
143
+ //
144
+ props.mar5 && { margin: 5 }, props.mar10 && { margin: 10 }, props.mar20 && { margin: 20 },
145
+ props.marV5 && { marginVertical: 5 }, props.marV10 && { marginVertical: 10 }, props.marV20 && { marginVertical: 20 },
146
+ props.marH5 && { marginHorizontal: 5 }, props.marH10 && { marginHorizontal: 10 }, props.marH20 && { marginHorizontal: 20 },
147
+ props.marL5 && { marginLeft: 5 }, props.marL10 && { marginLeft: 10 }, props.marL20 && { marginLeft: 20 },
148
+ props.marT5 && { marginTop: 5 }, props.marT10 && { marginTop: 10 }, props.marT20 && { marginTop: 20 },
149
+ props.marR5 && { marginRight: 5 }, props.marR10 && { marginRight: 10 }, props.marR20 && { marginRight: 20 },
150
+ props.marB5 && { marginBottom: 5 }, props.marB10 && { marginBottom: 10 }, props.marB20 && { marginBottom: 20 },
151
+ /** */
152
+
153
+ props.flex1 && { flex: 1 }, props.flex2 && { flex: 2 }, props.flex3 && { flex: 3 },
154
+ props.flex4 && { flex: 4 }, props.flex5 && { flex: 5 }, props.flex6 && { flex: 6 },
155
+ props.flex7 && { flex: 7 }, props.flex8 && { flex: 8 }, props.flex9 && { flex: 9 },
156
+ props.borderR2 && { borderRadius: 2 }, props.borderR5 && { borderRadius: 5 },
157
+ props.borderR10 && { borderRadius: 10 }, props.borderR15 && { borderRadius: 15 }, props.borderR20 && { borderRadius: 20 },
158
+ props.borderW1 && { borderWidth: 1 }, props.borderW2 && { borderWidth: 2 },
159
+ props.borderW3 && { borderWidth: 3 }, props.borderW4 && { borderWidth: 4 }, props.borderW5 && { borderWidth: 5 }, ///
160
+ //old
161
+ props.positionA && { position: 'absolute' }, //old
162
+ props.left0 && { left: 0, }, //old
163
+ props.top0 && { top: 0, }, //old
164
+ props.right0 && { right: 0, }, //old
165
+ props.bottom0 && { bottom: 0, }, //old
166
+ props.flexOne && { flex: 1 }, //old
167
+ props.bgW && { backgroundColor: "white" }, //old
168
+ props.centerH && { alignItems: 'center', justifyContent: 'space-between', },//old
169
+ props.overH && { overflow: 'hidden' },//old
170
+ props.w100 && { width: '100%' }, //old
171
+ props.h100 && { height: '100%' }, //old
172
+ props.width && { width: props.width },
173
+ props.height && { height: props.height },
174
+ props.alignI && { alignItems: props.alignI },
175
+ props.justifyC && { justifyContent: props.justifyC },
176
+ props.borderR100 && { borderRadius: 100 },
177
+ //
178
+ props.widthScreen && { width: Dimensions.get('screen').width },
179
+ props.heightScreen && { height: Dimensions.get('screen').height },
180
+
181
+
182
+ ])
183
+ return [
184
+ PropsApp,
185
+ PropsConvert,
186
+ ]
187
+ }
@@ -0,0 +1,41 @@
1
+ import React from 'react'
2
+ import { StyleSheet, TouchableOpacity } from 'react-native'
3
+ import { Style } from './Style'
4
+ import { Props } from './Props'
5
+ import { isArray, isString } from 'underscore'
6
+ import LinearGradient from 'react-native-linear-gradient'
7
+
8
+ type TouchableOpacityRef = React.ComponentRef<typeof TouchableOpacity>
9
+ const Touch = React.forwardRef<TouchableOpacityRef, Props>(({ style, ...props }, ref) => {
10
+ if (props?.hidden) return <></>
11
+ //@ts-ignore
12
+ if (isArray(props.background) && props.background.length > 1 && props.background.every(i => isString(i)))
13
+ return (
14
+ <TouchableOpacity
15
+ ref={ref}
16
+ {...props}
17
+ activeOpacity={props.activeOpacity || 0.5}
18
+ >
19
+ <LinearGradient
20
+ //@ts-ignore
21
+ colors={props.background}
22
+ start={props.gradient == "vertical" ? { x: 0, y: 0 } : { x: 0, y: 0 }}
23
+ end={props.gradient == "vertical" ? { x: 0, y: 1 } : { x: 1, y: 0 }}
24
+ style={[Style(props), style, props.styleBox]}
25
+ >
26
+ {props.children}
27
+ </LinearGradient >
28
+ </TouchableOpacity>
29
+ )
30
+ return (
31
+ <TouchableOpacity
32
+ ref={ref}
33
+ activeOpacity={props.activeOpacity || 0.5}
34
+ style={[Style(props), style, props.styleBox]}
35
+ {...props}>
36
+ {props.children}
37
+ </TouchableOpacity>
38
+ )
39
+ })
40
+
41
+ export default Touch
@@ -0,0 +1,70 @@
1
+
2
+ import React, { ReactNode, useCallback } from 'react';
3
+ import { Animated, TouchableOpacity, ViewProps, } from 'react-native';
4
+ import { Style } from './Style'
5
+ import { Props } from './Props'
6
+ import { isArray } from 'underscore';
7
+ import LinearGradient from 'react-native-linear-gradient'
8
+ import isColor from "validate-color";
9
+
10
+ interface ButtonScaleProps extends Props {
11
+ scaleValue?: number
12
+ scale?: boolean
13
+ containerStyle?: ViewProps['style']
14
+ }
15
+ type TouchableOpacityRef = React.ComponentRef<typeof TouchableOpacity>
16
+
17
+ const Touch = React.forwardRef<TouchableOpacityRef, ButtonScaleProps>(({ scaleValue = 1.1, style, background, containerStyle, ...props }, ref) => {
18
+ if (props?.hidden) return <></>
19
+ const animatedButtonScale = React.useRef(new Animated.Value(1)).current;
20
+ const onPressIn = useCallback(() => {
21
+ Animated.spring(animatedButtonScale, {
22
+ toValue: scaleValue,
23
+ useNativeDriver: true,
24
+ }).start();
25
+ }, [scaleValue]);
26
+ const onPressOut = useCallback(() => {
27
+ Animated.spring(animatedButtonScale, {
28
+ toValue: 1,
29
+ useNativeDriver: true,
30
+ }).start();
31
+ }, []);
32
+ if (isArray(background) && background.length > 1 && background.every(i => isColor(i)))
33
+ return (
34
+
35
+ <TouchableOpacity
36
+ ref={ref}
37
+ onPressIn={onPressIn}
38
+ onPressOut={onPressOut}
39
+ {...props}
40
+ activeOpacity={props.activeOpacity || 1}
41
+ >
42
+ <Animated.View style={[{ transform: [{ scale: animatedButtonScale }] }, Style(props), style]}>
43
+ <LinearGradient
44
+ colors={background}
45
+ start={props.gradient == "vertical" ? { x: 0, y: 0 } : { x: 0, y: 0 }}
46
+ end={props.gradient == "vertical" ? { x: 0, y: 1 } : { x: 1, y: 0 }}
47
+ style={[Style(props), style,]}
48
+ >
49
+ {props.children}
50
+ </LinearGradient>
51
+ </Animated.View>
52
+ </TouchableOpacity>
53
+
54
+ )
55
+ return (
56
+ <TouchableOpacity
57
+ ref={ref}
58
+ onPressIn={onPressIn}
59
+ onPressOut={onPressOut}
60
+ activeOpacity={props.activeOpacity || 1}
61
+ style={containerStyle}
62
+ {...props}>
63
+ <Animated.View style={[{ transform: [{ scale: animatedButtonScale }] }, Style(props), style]}>
64
+ {props.children}
65
+ </Animated.View>
66
+ </TouchableOpacity>
67
+ )
68
+ });
69
+
70
+ export default Touch
@@ -0,0 +1,28 @@
1
+ import { Log } from "@utils";
2
+ import { isString } from "underscore";
3
+
4
+
5
+ export function sliceTextAndNumber(input: string) {
6
+ let text = "";
7
+ let number = "";
8
+ let mid: number | boolean = false
9
+ for (let i = 0; i < input.length; i++) {
10
+ const currentChar = input[i];
11
+ if (!isNaN(parseInt(currentChar)) && mid == false) {
12
+ mid = i
13
+ }
14
+ }
15
+ if (mid) {
16
+ text = input.slice(0, mid)
17
+ number = input.slice(mid)
18
+ }
19
+ // Log.d('mid', { mid, text, number })
20
+ return {
21
+ text: mid ? text : null,
22
+ number: mid ? Number(number) : null,
23
+ };
24
+ }
25
+ export function replaceAll(str = '', search = '', replacement = '') {
26
+ return str.replace(new RegExp(search, 'g'), replacement);//[g] ~~ search global
27
+
28
+ }
package/src/config.ts ADDED
@@ -0,0 +1,25 @@
1
+ export const Colors = {
2
+ primary: 'blue'
3
+ }
4
+ export const Icons = {
5
+ menu: "menu",
6
+ home: 'home',
7
+ person: 'person-outline',
8
+ camera: 'camera-outline',
9
+ pass: 'lock-closed-outline',
10
+ pass1: "key-outline",
11
+ image: 'image-outline',
12
+ image1: 'images-outline',
13
+ mail: 'mail-outline',
14
+ settings: 'settings-outline',
15
+ logout: 'log-out-outline',
16
+ filter: 'funnel-outline',
17
+ search: 'search-outline',
18
+ back: 'arrow-back-outline',
19
+ back1: 'chevron-back-outline',
20
+ down: "chevron-down-outline",
21
+ down1: "caret-down-outline",
22
+ up: 'chevron-up-outline',
23
+ up1: 'caret-up-outline',
24
+ header: 'heart-outline'
25
+ }
package/src/index.tsx ADDED
@@ -0,0 +1,2 @@
1
+ export { default as Touch } from './Touch/Touch'
2
+ export { default as Block } from './Touch/Block'