ui-rn 1.0.16 → 1.0.18
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/Example/index.tsx +24 -12
- package/README.md +178 -26
- package/package.json +1 -1
- package/src/Icon/index.tsx +47 -0
- package/src/Loading/Loading.tsx +65 -0
- package/src/Loading/LoadingType.tsx +22 -0
- package/src/Loading/index.tsx +36 -3
- package/src/Touch/Props.ts +47 -1
- package/src/Touch/Style.ts +52 -4
- package/src/Touch/Touch.tsx +33 -0
- package/src/Touch/makeStyle.ts +35 -0
package/Example/index.tsx
CHANGED
|
@@ -1,19 +1,31 @@
|
|
|
1
|
-
import { StyleSheet, Text, View } from 'react-native';
|
|
1
|
+
import { StyleSheet, Text, View, TouchableOpacity } from 'react-native';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { Block } from 'ui-rn';
|
|
4
|
+
import { LinearGradient } from 'react-native-linear-gradient';
|
|
4
5
|
export default function App() {
|
|
5
6
|
return (
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
<
|
|
9
|
-
|
|
7
|
+
<>
|
|
8
|
+
|
|
9
|
+
<LinearGradient
|
|
10
|
+
colors={['#FF6B6B', '#4ECDC4']}
|
|
11
|
+
start={{ x: 0, y: 0 }}
|
|
12
|
+
end={{ x: 0, y: 1 }}
|
|
13
|
+
>
|
|
14
|
+
<TouchableOpacity style={{ padding: 20, borderRadius: 10 }}>
|
|
15
|
+
<Text style={{ color: 'white' }}>Gradient Block</Text>
|
|
16
|
+
</TouchableOpacity>
|
|
17
|
+
</LinearGradient>
|
|
18
|
+
<Text style={{ fontWeight: 'bold', fontStyle: 'italic', fontSize: 16, color: 'blue', alignItems: 'center' }}></Text>
|
|
19
|
+
<TouchableOpacity
|
|
20
|
+
style={{
|
|
21
|
+
padding: 10,
|
|
22
|
+
backgroundColor:'blue',
|
|
23
|
+
borderRadius: 10,
|
|
24
|
+
}}
|
|
25
|
+
>
|
|
26
|
+
<Text style={{ color: 'white', alignItems: 'center' }}>Press Me</Text>
|
|
27
|
+
</TouchableOpacity>
|
|
28
|
+
</>
|
|
10
29
|
);
|
|
11
30
|
}
|
|
12
31
|
|
|
13
|
-
const styles = StyleSheet.create({
|
|
14
|
-
container: {
|
|
15
|
-
flex: 1,
|
|
16
|
-
justifyContent: 'center',
|
|
17
|
-
alignItems: 'center',
|
|
18
|
-
},
|
|
19
|
-
});
|
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# <div align="center">UI-RN</div>
|
|
2
2
|
|
|
3
3
|
<div align="center">
|
|
4
|
-
<img src="https://img.shields.io/npm/v/ui-rn.svg?version=1.0.
|
|
4
|
+
<img src="https://img.shields.io/npm/v/ui-rn.svg?version=1.0.17" alt="npm version" />
|
|
5
5
|
<img src="https://img.shields.io/npm/dm/ui-rn.svg" alt="npm downloads" />
|
|
6
6
|
<img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="license" />
|
|
7
7
|
</div>
|
|
@@ -36,8 +36,8 @@ npm install ui-rn
|
|
|
36
36
|
Here's a simple example to get you started:
|
|
37
37
|
|
|
38
38
|
```tsx
|
|
39
|
-
import {
|
|
40
|
-
import React from
|
|
39
|
+
import {Block, Text, Icon, Touch, Layout, LoadingView} from 'ui-rn';
|
|
40
|
+
import React from 'react';
|
|
41
41
|
|
|
42
42
|
export default function Example() {
|
|
43
43
|
return (
|
|
@@ -46,15 +46,14 @@ export default function Example() {
|
|
|
46
46
|
mar-5
|
|
47
47
|
pad-5
|
|
48
48
|
red
|
|
49
|
-
background={[
|
|
50
|
-
positionOption={{
|
|
49
|
+
background={['red', 'blue']}
|
|
50
|
+
positionOption={{top: 10, left: 5}}
|
|
51
51
|
alignCenter
|
|
52
52
|
borderCircle
|
|
53
53
|
mid
|
|
54
54
|
row
|
|
55
55
|
width-150
|
|
56
|
-
height-300
|
|
57
|
-
>
|
|
56
|
+
height-300>
|
|
58
57
|
<Text size-14 red toUpperCase italic bold>
|
|
59
58
|
Hello
|
|
60
59
|
</Text>
|
|
@@ -72,6 +71,48 @@ export default function Example() {
|
|
|
72
71
|
<details>
|
|
73
72
|
<summary>The <code>Block</code> component is a versatile container that supports various styling options and layouts.</summary>
|
|
74
73
|
|
|
74
|
+
#### Example
|
|
75
|
+
|
|
76
|
+
```tsx
|
|
77
|
+
// Basic Block
|
|
78
|
+
<LinearGradient
|
|
79
|
+
colors={['#FF6B6B', '#4ECDC4']}
|
|
80
|
+
start={{ x: 0, y: 0 }}
|
|
81
|
+
end={{ x: 0, y: 1 }}
|
|
82
|
+
>
|
|
83
|
+
<TouchableOpacity style={{ padding: 20, borderRadius: 10 }}>
|
|
84
|
+
<Text style={{ color: 'white' }}>Gradient Block</Text>
|
|
85
|
+
</TouchableOpacity>
|
|
86
|
+
</LinearGradient>
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
// Block with gradient
|
|
90
|
+
<Block
|
|
91
|
+
background={['#FF6B6B', '#4ECDC4']}
|
|
92
|
+
gradient="vertical"
|
|
93
|
+
pad-20
|
|
94
|
+
borderR-10
|
|
95
|
+
>
|
|
96
|
+
<Text white>Gradient Block</Text>
|
|
97
|
+
</Block>
|
|
98
|
+
|
|
99
|
+
// Block with shadow
|
|
100
|
+
<Block
|
|
101
|
+
shadowOption={{
|
|
102
|
+
color: '#000',
|
|
103
|
+
width: 0,
|
|
104
|
+
height: 2,
|
|
105
|
+
opacity: 0.25,
|
|
106
|
+
radius: 3.84,
|
|
107
|
+
elevation: 5
|
|
108
|
+
}}
|
|
109
|
+
pad-15
|
|
110
|
+
bg-white
|
|
111
|
+
>
|
|
112
|
+
<Text>Shadow Block</Text>
|
|
113
|
+
</Block>
|
|
114
|
+
```
|
|
115
|
+
|
|
75
116
|
#### Block Props
|
|
76
117
|
|
|
77
118
|
| Prop | Type | Description |
|
|
@@ -162,6 +203,25 @@ export default function Example() {
|
|
|
162
203
|
<details>
|
|
163
204
|
<summary>The <code>Text</code> component provides various text styling options.</summary>
|
|
164
205
|
|
|
206
|
+
#### Example
|
|
207
|
+
|
|
208
|
+
```tsx
|
|
209
|
+
// Basic Text
|
|
210
|
+
<Text style={{ fontWeight: 'bold', fontStyle: 'italic', fontSize: 16, color: 'blue', alignItems: 'center' }}>Hello World</Text>
|
|
211
|
+
|
|
212
|
+
// new
|
|
213
|
+
<Text
|
|
214
|
+
bold
|
|
215
|
+
italic
|
|
216
|
+
size-16
|
|
217
|
+
color="blue"
|
|
218
|
+
center
|
|
219
|
+
>
|
|
220
|
+
Hello World
|
|
221
|
+
</Text>
|
|
222
|
+
|
|
223
|
+
```
|
|
224
|
+
|
|
165
225
|
#### Text Props
|
|
166
226
|
|
|
167
227
|
| Prop Style | Type | Description |
|
|
@@ -182,6 +242,24 @@ export default function Example() {
|
|
|
182
242
|
<details>
|
|
183
243
|
<summary>The <code>Icon</code> component supports various icon libraries.</summary>
|
|
184
244
|
|
|
245
|
+
#### Example
|
|
246
|
+
|
|
247
|
+
```tsx
|
|
248
|
+
// Basic Icon
|
|
249
|
+
<>
|
|
250
|
+
<MaterialIcons name="home" size={24} />
|
|
251
|
+
<FontAwesome name="heart" size={24} />
|
|
252
|
+
<Ionicons name="star" size={24} />
|
|
253
|
+
</>
|
|
254
|
+
|
|
255
|
+
// Different Icon Types
|
|
256
|
+
<>
|
|
257
|
+
<Icon name="home" type="MaterialIcons" size-24 />
|
|
258
|
+
<Icon name="heart" type="FontAwesome" size-24 color="red" />
|
|
259
|
+
<Icon name="star" type="Ionicons" size-24 color="gold" />
|
|
260
|
+
</>
|
|
261
|
+
```
|
|
262
|
+
|
|
185
263
|
#### Icon Props
|
|
186
264
|
|
|
187
265
|
| Prop Style | Type | Description |
|
|
@@ -213,6 +291,30 @@ export default function Example() {
|
|
|
213
291
|
<details>
|
|
214
292
|
<summary>The <code>Touch</code> component is a touchable wrapper with feedback effects.</summary>
|
|
215
293
|
|
|
294
|
+
#### Example
|
|
295
|
+
|
|
296
|
+
```tsx
|
|
297
|
+
// Basic Button
|
|
298
|
+
<TouchableOpacity
|
|
299
|
+
style={{
|
|
300
|
+
padding: 10,
|
|
301
|
+
backgroundColor:'blue',
|
|
302
|
+
borderRadius: 10,
|
|
303
|
+
}}
|
|
304
|
+
>
|
|
305
|
+
<Text style={{ color: 'white', alignItems: 'center' }}>Press Me</Text>
|
|
306
|
+
</TouchableOpacity>
|
|
307
|
+
|
|
308
|
+
// Button with ripple effect
|
|
309
|
+
<Touch
|
|
310
|
+
pad-10
|
|
311
|
+
bg-blue
|
|
312
|
+
borderR-10
|
|
313
|
+
>
|
|
314
|
+
<Text white center>Press Me</Text>
|
|
315
|
+
</Touch>
|
|
316
|
+
```
|
|
317
|
+
|
|
216
318
|
#### Touch Props
|
|
217
319
|
|
|
218
320
|
| Prop Style | Type | Description |
|
|
@@ -230,17 +332,71 @@ export default function Example() {
|
|
|
230
332
|
<details>
|
|
231
333
|
<summary>The <code>Layout</code> component provides a base layout structure with safe area handling.</summary>
|
|
232
334
|
|
|
335
|
+
#### Example
|
|
336
|
+
|
|
337
|
+
```tsx
|
|
338
|
+
// Layout with Safe Areas
|
|
339
|
+
<Layout forceInset={{top: 'always'}} forceInsetBot={{vertical: 'never'}}>
|
|
340
|
+
<Block pad-20>
|
|
341
|
+
<Text>Content with Safe Areas</Text>
|
|
342
|
+
</Block>
|
|
343
|
+
</Layout>
|
|
344
|
+
```
|
|
345
|
+
|
|
233
346
|
#### Layout Props
|
|
234
347
|
|
|
235
|
-
| Prop Style
|
|
236
|
-
|
|
|
237
|
-
|
|
|
238
|
-
|
|
|
239
|
-
|
|
|
240
|
-
|
|
|
241
|
-
|
|
|
242
|
-
|
|
|
348
|
+
| Prop Style | Type | Description | Default Value |
|
|
349
|
+
| ------------- | -------------------- | ------------------------------------------------- | ------------------------------------------------------- |
|
|
350
|
+
| children | ReactNode | Child components to be rendered inside layout | - |
|
|
351
|
+
| forceInset | ForceInsetProp | Safe area inset configuration for top view | { top: 'always', horizontal: 'never', bottom: 'never' } |
|
|
352
|
+
| forceInsetBot | ForceInsetProp | Safe area inset configuration for bottom view | { vertical: 'never' } |
|
|
353
|
+
| styleBot | StyleProp<ViewStyle> | Custom style for bottom SafeAreaView | undefined |
|
|
354
|
+
| style | StyleProp<ViewStyle> | Custom style for top SafeAreaView | undefined |
|
|
355
|
+
| isBack | boolean | Whether to show back button | false |
|
|
356
|
+
| disable | boolean | Disable SafeAreaView and render children directly | false |
|
|
243
357
|
|
|
358
|
+
#### Usage Examples
|
|
359
|
+
|
|
360
|
+
```tsx
|
|
361
|
+
// Basic usage
|
|
362
|
+
<Layout>
|
|
363
|
+
<Text>Content</Text>
|
|
364
|
+
</Layout>
|
|
365
|
+
|
|
366
|
+
// With custom safe area insets
|
|
367
|
+
<Layout
|
|
368
|
+
forceInset={{ top: 'always', bottom: 'always' }}
|
|
369
|
+
forceInsetBot={{ vertical: 'always' }}
|
|
370
|
+
>
|
|
371
|
+
<Text>Content with full safe area</Text>
|
|
372
|
+
</Layout>
|
|
373
|
+
|
|
374
|
+
// With custom styles
|
|
375
|
+
<Layout
|
|
376
|
+
style={{ backgroundColor: 'white' }}
|
|
377
|
+
styleBot={{ padding: 20 }}
|
|
378
|
+
>
|
|
379
|
+
<Text>Styled content</Text>
|
|
380
|
+
</Layout>
|
|
381
|
+
|
|
382
|
+
// Disable safe area
|
|
383
|
+
<Layout disable>
|
|
384
|
+
<Text>Content without safe area</Text>
|
|
385
|
+
</Layout>
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
#### ForceInsetProp Types
|
|
389
|
+
|
|
390
|
+
The `forceInset` and `forceInsetBot` props accept the following values:
|
|
391
|
+
|
|
392
|
+
- `'always'`: Always apply the safe area inset
|
|
393
|
+
- `'never'`: Never apply the safe area inset
|
|
394
|
+
- `'top'`: Apply inset only to the top
|
|
395
|
+
- `'bottom'`: Apply inset only to the bottom
|
|
396
|
+
- `'left'`: Apply inset only to the left
|
|
397
|
+
- `'right'`: Apply inset only to the right
|
|
398
|
+
- `'horizontal'`: Apply inset to both left and right
|
|
399
|
+
- `'vertical'`: Apply inset to both top and bottom
|
|
244
400
|
</details>
|
|
245
401
|
|
|
246
402
|
### LoadingView
|
|
@@ -248,17 +404,13 @@ export default function Example() {
|
|
|
248
404
|
<details>
|
|
249
405
|
<summary>The <code>LoadingView</code> component displays a loading indicator with optional overlay.</summary>
|
|
250
406
|
|
|
251
|
-
####
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
| type | 'spinner' \| 'dots' \| 'pulse' | Type of loading indicator |
|
|
259
|
-
| text | string | Loading text |
|
|
260
|
-
| textColor | string | Color of loading text |
|
|
261
|
-
| textSize | number | Size of loading text |
|
|
407
|
+
#### Example
|
|
408
|
+
|
|
409
|
+
```tsx
|
|
410
|
+
<Host>
|
|
411
|
+
<LoadingView />
|
|
412
|
+
</Host>
|
|
413
|
+
```
|
|
262
414
|
|
|
263
415
|
</details>
|
|
264
416
|
|
package/package.json
CHANGED
package/src/Icon/index.tsx
CHANGED
|
@@ -23,6 +23,11 @@ import Octicons from 'react-native-vector-icons/Octicons'
|
|
|
23
23
|
import Fontisto from 'react-native-vector-icons/Fontisto'
|
|
24
24
|
import { IconProps } from 'react-native-vector-icons/Icon'
|
|
25
25
|
import { isArray, isString } from 'underscore'
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Collection of React Native Vector Icons
|
|
29
|
+
* Provides access to various icon sets from react-native-vector-icons
|
|
30
|
+
*/
|
|
26
31
|
export const RNVectorIcon = {
|
|
27
32
|
Ionicons,
|
|
28
33
|
AntDesign,
|
|
@@ -37,20 +42,59 @@ export const RNVectorIcon = {
|
|
|
37
42
|
Octicons,
|
|
38
43
|
Fontisto
|
|
39
44
|
}
|
|
45
|
+
|
|
46
|
+
/** Type definition for available icon sets */
|
|
40
47
|
export type IconType = keyof typeof RNVectorIcon
|
|
48
|
+
|
|
41
49
|
import { Props, } from './PropsStyle'
|
|
42
50
|
import { makeProps } from './makeProps'
|
|
51
|
+
|
|
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
|
+
*/
|
|
43
82
|
export default class IconApp extends React.PureComponent<Props> {
|
|
83
|
+
/** Default props for the IconApp component */
|
|
44
84
|
static defaultProps: Props = {
|
|
45
85
|
size: 23,
|
|
46
86
|
color: 'gray',
|
|
47
87
|
name: 'home',
|
|
48
88
|
}
|
|
89
|
+
|
|
90
|
+
/** Internal state for computed props */
|
|
49
91
|
res: { color: string, style: any, size: number }
|
|
92
|
+
|
|
50
93
|
constructor(props) {
|
|
51
94
|
super(props)
|
|
52
95
|
this.res = makeProps(props)
|
|
53
96
|
}
|
|
97
|
+
|
|
54
98
|
render() {
|
|
55
99
|
const { size, color, style } = this.res
|
|
56
100
|
// console.debug('res', this.res)
|
|
@@ -93,6 +137,9 @@ export default class IconApp extends React.PureComponent<Props> {
|
|
|
93
137
|
}
|
|
94
138
|
}
|
|
95
139
|
|
|
140
|
+
/**
|
|
141
|
+
* Default styles for the IconApp component
|
|
142
|
+
*/
|
|
96
143
|
const styles = StyleSheet.create({
|
|
97
144
|
container: {
|
|
98
145
|
alignItems: 'center',
|
package/src/Loading/Loading.tsx
CHANGED
|
@@ -9,17 +9,53 @@ import {
|
|
|
9
9
|
Text
|
|
10
10
|
} from 'react-native'
|
|
11
11
|
import LoadingType, { LoadingTypeI } from './LoadingType'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Props for the Loading component
|
|
15
|
+
* @interface Props
|
|
16
|
+
*/
|
|
12
17
|
export type Props = {
|
|
18
|
+
/** Custom style for the loading box container */
|
|
13
19
|
boxStyle?: ViewProps['style']
|
|
20
|
+
/** Custom style for the main container */
|
|
14
21
|
containerStyle?: ViewProps['style']
|
|
15
22
|
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Internal state of the Loading component
|
|
26
|
+
* @interface State
|
|
27
|
+
*/
|
|
16
28
|
type State = {
|
|
29
|
+
/** Controls the visibility of the loading modal */
|
|
17
30
|
visible: boolean,
|
|
31
|
+
/** Determines if the loading can be dismissed by touch */
|
|
18
32
|
touch: boolean,
|
|
33
|
+
/** Current progress value (0-100) */
|
|
19
34
|
progress: number,
|
|
35
|
+
/** Controls whether to show progress indicator */
|
|
20
36
|
progressShow: boolean,
|
|
37
|
+
/** Type of loading indicator to display */
|
|
21
38
|
type: LoadingTypeI
|
|
22
39
|
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Loading component that displays a modal with customizable loading indicators
|
|
43
|
+
* and optional progress tracking.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```tsx
|
|
47
|
+
* const loading = useRef<Loading>(null);
|
|
48
|
+
*
|
|
49
|
+
* // Show loading
|
|
50
|
+
* loading.current?.show();
|
|
51
|
+
*
|
|
52
|
+
* // Show loading with progress
|
|
53
|
+
* loading.current?.openProgress({ progress: 50, progressShow: true });
|
|
54
|
+
*
|
|
55
|
+
* // Hide loading
|
|
56
|
+
* loading.current?.hide();
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
23
59
|
export default class Loading extends PureComponent<Props, State> {
|
|
24
60
|
state: State
|
|
25
61
|
constructor(props: any) {
|
|
@@ -32,13 +68,31 @@ export default class Loading extends PureComponent<Props, State> {
|
|
|
32
68
|
type: 'BallIndicator'
|
|
33
69
|
}
|
|
34
70
|
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Shows the loading modal
|
|
74
|
+
* @param touch - Whether the loading can be dismissed by touch (default: true)
|
|
75
|
+
*/
|
|
35
76
|
show(touch = true) {
|
|
36
77
|
this.setState({ visible: true, touch })
|
|
37
78
|
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Hides the loading modal and resets progress
|
|
82
|
+
*/
|
|
38
83
|
hide() {
|
|
39
84
|
this.setState({ visible: false, progress: 0, progressShow: false })
|
|
40
85
|
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Updates the progress state
|
|
89
|
+
* @param e - Object containing progress updates
|
|
90
|
+
*/
|
|
41
91
|
openProgress(e: any) { this.setState(prev => ({ ...prev, ...e })) }
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Handles touch events to dismiss the loading modal
|
|
95
|
+
*/
|
|
42
96
|
onPressOut() {
|
|
43
97
|
if (this.state.touch) {
|
|
44
98
|
this.hide()
|
|
@@ -49,16 +103,27 @@ export default class Loading extends PureComponent<Props, State> {
|
|
|
49
103
|
}
|
|
50
104
|
componentWillUnmount(): void {
|
|
51
105
|
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Renders the loading indicator based on the selected type
|
|
109
|
+
* @returns React element for the loading indicator
|
|
110
|
+
*/
|
|
52
111
|
renderIcon() {
|
|
53
112
|
if (this.state.type) return React.createElement(LoadingType[this.state.type], { color: '#4481EB' })
|
|
54
113
|
return null
|
|
55
114
|
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Renders the progress text if progressShow is true
|
|
118
|
+
* @returns React element for the progress text
|
|
119
|
+
*/
|
|
56
120
|
renderProgress() {
|
|
57
121
|
if (this.state.progressShow) {
|
|
58
122
|
return (<Text style={styles.text}>{this.state.progress}{'%'}</Text>)
|
|
59
123
|
}
|
|
60
124
|
return null
|
|
61
125
|
}
|
|
126
|
+
|
|
62
127
|
render() {
|
|
63
128
|
return (
|
|
64
129
|
<Modal
|
|
@@ -9,6 +9,22 @@ import {
|
|
|
9
9
|
UIActivityIndicator,
|
|
10
10
|
WaveIndicator,
|
|
11
11
|
} from 'react-native-indicators';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Collection of loading indicator components from react-native-indicators
|
|
15
|
+
* Each indicator provides a different visual style for loading states
|
|
16
|
+
*
|
|
17
|
+
* Available indicators:
|
|
18
|
+
* - BallIndicator: Animated bouncing balls
|
|
19
|
+
* - BarIndicator: Animated bars
|
|
20
|
+
* - DotIndicator: Animated dots
|
|
21
|
+
* - MaterialIndicator: Material design style loading indicator
|
|
22
|
+
* - PacmanIndicator: Pacman-style loading animation
|
|
23
|
+
* - PulseIndicator: Pulsing animation
|
|
24
|
+
* - SkypeIndicator: Skype-style loading indicator
|
|
25
|
+
* - UIActivityIndicator: Native iOS-style activity indicator
|
|
26
|
+
* - WaveIndicator: Wave-like animation
|
|
27
|
+
*/
|
|
12
28
|
const LoadingType = {
|
|
13
29
|
BallIndicator,
|
|
14
30
|
BarIndicator,
|
|
@@ -20,5 +36,11 @@ const LoadingType = {
|
|
|
20
36
|
UIActivityIndicator,
|
|
21
37
|
WaveIndicator,
|
|
22
38
|
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Type definition for loading indicator names
|
|
42
|
+
* Represents the keys of the LoadingType object
|
|
43
|
+
*/
|
|
23
44
|
export type LoadingTypeI = keyof typeof LoadingType
|
|
45
|
+
|
|
24
46
|
export default LoadingType
|
package/src/Loading/index.tsx
CHANGED
|
@@ -1,22 +1,55 @@
|
|
|
1
1
|
import React, { PureComponent, ReactNode } from "react"
|
|
2
2
|
import RNLoading, { Props } from "./Loading"
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Reference to the Loading component instance
|
|
6
|
+
*/
|
|
4
7
|
const loadingRef = React.createRef<RNLoading>()
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Static Loading class that provides global access to loading functionality
|
|
11
|
+
* This class allows showing and hiding the loading indicator from anywhere in the app
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```tsx
|
|
15
|
+
* // Show loading
|
|
16
|
+
* Loading.show();
|
|
17
|
+
*
|
|
18
|
+
* // Hide loading
|
|
19
|
+
* Loading.hide();
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
5
22
|
export class Loading {
|
|
23
|
+
/**
|
|
24
|
+
* Shows the loading indicator
|
|
25
|
+
*/
|
|
6
26
|
static show() {
|
|
7
27
|
loadingRef.current?.show()
|
|
8
28
|
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Hides the loading indicator
|
|
32
|
+
*/
|
|
9
33
|
static hide() {
|
|
10
34
|
loadingRef.current?.hide()
|
|
11
35
|
}
|
|
12
36
|
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* LoadingView component that renders the Loading component
|
|
40
|
+
* This component should be mounted at the root level of your app
|
|
41
|
+
* to enable global loading functionality
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```tsx
|
|
45
|
+
* // In your App.tsx or root component
|
|
46
|
+
* <LoadingView />
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
13
49
|
export default class LoadingView extends PureComponent<Props> {
|
|
14
50
|
render(): ReactNode {
|
|
15
51
|
return (
|
|
16
|
-
|
|
17
52
|
<RNLoading ref={loadingRef} {...this.props} />
|
|
18
|
-
|
|
19
53
|
)
|
|
20
|
-
|
|
21
54
|
}
|
|
22
55
|
}
|
package/src/Touch/Props.ts
CHANGED
|
@@ -2,48 +2,94 @@ import { IColor } from "../config"
|
|
|
2
2
|
import { StyleProp, FlexStyle, TouchableWithoutFeedbackProps, ViewStyle } from "react-native"
|
|
3
3
|
import { MakeProp } from "./makeStyle"
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Interface for application-specific props that extend React Native's style properties
|
|
7
|
+
* @interface PropsApp
|
|
8
|
+
*/
|
|
5
9
|
export interface PropsApp {
|
|
10
|
+
/** Border radius for top corners */
|
|
6
11
|
borderUpRadius?: number
|
|
12
|
+
/** Border radius for bottom corners */
|
|
7
13
|
borderDownRadius?: number
|
|
14
|
+
/** Flexbox alignment along cross axis */
|
|
8
15
|
alignItems?: FlexStyle['alignItems']
|
|
16
|
+
/** Flexbox alignment for self */
|
|
9
17
|
alignSelf?: FlexStyle['alignSelf']
|
|
18
|
+
/** Flexbox alignment along main axis */
|
|
10
19
|
justifyContent?: FlexStyle['justifyContent']
|
|
20
|
+
/** Border style (solid, dashed, dotted) */
|
|
11
21
|
borderStyle?: ViewStyle['borderStyle']
|
|
22
|
+
/** Opacity of the view */
|
|
12
23
|
opacity?: ViewStyle['opacity']
|
|
24
|
+
/** Overflow behavior */
|
|
13
25
|
overflow?: ViewStyle['overflow']
|
|
26
|
+
/** Set width to 100% */
|
|
14
27
|
w100?: boolean
|
|
28
|
+
/** Set height to 100% */
|
|
15
29
|
h100?: boolean
|
|
30
|
+
/** Center content both horizontally and vertically */
|
|
16
31
|
mid?: boolean
|
|
32
|
+
/** Set flex direction to row */
|
|
17
33
|
row?: boolean
|
|
34
|
+
/** Center content horizontally */
|
|
18
35
|
alignCenter?: boolean
|
|
36
|
+
/** Center content vertically */
|
|
19
37
|
justifyCenter?: boolean
|
|
38
|
+
/** Make border radius circular */
|
|
20
39
|
borderCircle?: boolean
|
|
40
|
+
/** Center content horizontally and space between vertically */
|
|
21
41
|
centerBetween?: boolean
|
|
42
|
+
/** Space content evenly along main axis */
|
|
22
43
|
justifyBetween?: boolean
|
|
44
|
+
/** Hide overflow content */
|
|
23
45
|
overHidden?: boolean
|
|
46
|
+
/** Set width and height to same value */
|
|
24
47
|
square?: number
|
|
48
|
+
/** Set width to 100% */
|
|
25
49
|
width100?: boolean
|
|
50
|
+
/** Set height to 100% */
|
|
26
51
|
height100?: boolean
|
|
52
|
+
/** Background color or gradient colors */
|
|
27
53
|
background?: Array<IColor> | Array<(string)> | string
|
|
54
|
+
/** Gradient direction */
|
|
28
55
|
gradient?: 'vertical' | 'horizontal'
|
|
56
|
+
/** Set flex to 1 */
|
|
29
57
|
flexOne?: boolean
|
|
58
|
+
flex1?: boolean
|
|
59
|
+
/** Shadow color or boolean to enable default shadow */
|
|
30
60
|
shadowColor?: string | boolean
|
|
61
|
+
/** Border options for each side */
|
|
31
62
|
borderOption?: { top?: number, left?: number, right?: number, bottom?: number, color?: string }
|
|
63
|
+
/** Position options for absolute positioning */
|
|
32
64
|
positionOption?: { top?: number, left?: number, right?: number, bottom?: number }
|
|
65
|
+
/** Padding options for each side */
|
|
33
66
|
paddingOption?: { all?: number, top?: number, left?: number, right?: number, bottom?: number }
|
|
67
|
+
/** Padding options for vertical and horizontal */
|
|
34
68
|
paddingFlex?: { vertical?: number, horizontal?: number }
|
|
69
|
+
/** Margin options for vertical and horizontal */
|
|
35
70
|
marginFlex?: { vertical?: number, horizontal?: number }
|
|
71
|
+
/** Margin options for each side */
|
|
36
72
|
marginOption?: { all?: number, top?: number, left?: number, right?: number, bottom?: number }
|
|
73
|
+
/** Shadow configuration options */
|
|
37
74
|
shadowOption?: { color?: string, width?: number, height?: number, opacity?: number, radius?: number, elevation?: number }
|
|
75
|
+
/** Custom style character */
|
|
38
76
|
styleChar?: string
|
|
77
|
+
/** Set width to screen width */
|
|
39
78
|
widthScreen?: boolean
|
|
79
|
+
/** Set height to screen height */
|
|
40
80
|
heightScreen?: boolean
|
|
41
|
-
|
|
42
81
|
}
|
|
43
82
|
|
|
83
|
+
/**
|
|
84
|
+
* Main Props interface that combines TouchableWithoutFeedbackProps, PropsApp, and MakeProp
|
|
85
|
+
* @interface Props
|
|
86
|
+
*/
|
|
44
87
|
//@ts-ignore
|
|
45
88
|
export interface Props extends TouchableWithoutFeedbackProps, PropsApp, MakeProp {
|
|
89
|
+
/** Child components */
|
|
46
90
|
children?: React.ReactNode
|
|
91
|
+
/** Hide the component */
|
|
47
92
|
hidden?: boolean
|
|
93
|
+
/** Opacity when pressed */
|
|
48
94
|
activeOpacity?: number
|
|
49
95
|
}
|
package/src/Touch/Style.ts
CHANGED
|
@@ -4,15 +4,50 @@ import { Props } from './Props'
|
|
|
4
4
|
import { Colors } from "../config";
|
|
5
5
|
import { makeStyle } from "./makeStyle";
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Style utility function that generates React Native styles based on provided props
|
|
9
|
+
* This function combines various style properties into a single style object
|
|
10
|
+
*
|
|
11
|
+
* @param props - Style properties object containing various style configurations
|
|
12
|
+
* @returns Array containing base styles and computed styles
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```tsx
|
|
16
|
+
* // Basic usage
|
|
17
|
+
* <View style={Style({ mid: true, row: true })}>
|
|
18
|
+
*
|
|
19
|
+
* // With position options
|
|
20
|
+
* <View style={Style({
|
|
21
|
+
* positionOption: { top: 10, left: 20 },
|
|
22
|
+
* paddingOption: { all: 10 }
|
|
23
|
+
* })}>
|
|
24
|
+
*
|
|
25
|
+
* // With shadow
|
|
26
|
+
* <View style={Style({
|
|
27
|
+
* shadowOption: {
|
|
28
|
+
* color: '#000',
|
|
29
|
+
* width: 2,
|
|
30
|
+
* height: 2,
|
|
31
|
+
* opacity: 0.5,
|
|
32
|
+
* radius: 5
|
|
33
|
+
* }
|
|
34
|
+
* })}>
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
7
37
|
export const Style: any = (props: Props) => {
|
|
8
38
|
|
|
9
39
|
const PropsApp = StyleSheet.flatten([
|
|
40
|
+
// Layout properties
|
|
10
41
|
props.alignItems && { alignItems: props.alignItems },
|
|
11
42
|
props.justifyContent && { justifyContent: props.justifyContent },
|
|
12
43
|
props.borderStyle && { borderStyle: props.borderStyle },
|
|
13
44
|
props.overflow && { overflow: props.overflow },
|
|
45
|
+
|
|
46
|
+
// Border radius properties
|
|
14
47
|
props.borderUpRadius && { borderTopLeftRadius: (props.borderUpRadius), borderTopRightRadius: (props.borderUpRadius) },
|
|
15
48
|
props.borderDownRadius && { borderBottomLeftRadius: (props.borderUpRadius), borderBottomRightRadius: (props.borderUpRadius) },
|
|
49
|
+
|
|
50
|
+
// Layout shortcuts
|
|
16
51
|
props.mid && { alignItems: 'center', justifyContent: 'center' },
|
|
17
52
|
props.row && { flexDirection: 'row' },
|
|
18
53
|
props.width100 && { width: '100%' },
|
|
@@ -25,7 +60,7 @@ export const Style: any = (props: Props) => {
|
|
|
25
60
|
props.overHidden && { overflow: 'hidden' },
|
|
26
61
|
props.centerBetween && { alignItems: 'center', justifyContent: 'space-between', },
|
|
27
62
|
|
|
28
|
-
//
|
|
63
|
+
// Position options
|
|
29
64
|
props.positionOption && {
|
|
30
65
|
position: 'absolute',
|
|
31
66
|
top: props.positionOption?.top,
|
|
@@ -33,18 +68,24 @@ export const Style: any = (props: Props) => {
|
|
|
33
68
|
left: props.positionOption?.left,
|
|
34
69
|
right: props.positionOption?.right,
|
|
35
70
|
},
|
|
71
|
+
|
|
72
|
+
// Padding options
|
|
36
73
|
props.paddingOption && {
|
|
37
74
|
paddingLeft: props.paddingOption?.all || props.paddingOption?.left,
|
|
38
75
|
paddingTop: props.paddingOption?.all || props.paddingOption?.top,
|
|
39
76
|
paddingRight: props.paddingOption?.all || props.paddingOption?.right,
|
|
40
77
|
paddingBottom: props.paddingOption?.all || props.paddingOption?.bottom,
|
|
41
78
|
},
|
|
79
|
+
|
|
80
|
+
// Margin options
|
|
42
81
|
props.marginOption && {
|
|
43
82
|
marginLeft: props.marginOption?.all || props.marginOption?.left,
|
|
44
83
|
marginTop: props.marginOption?.all || props.marginOption?.top,
|
|
45
84
|
marginRight: props.marginOption?.all || props.marginOption?.right,
|
|
46
85
|
marginBottom: props.marginOption?.all || props.marginOption?.bottom,
|
|
47
86
|
},
|
|
87
|
+
|
|
88
|
+
// Border options
|
|
48
89
|
props.borderOption && {
|
|
49
90
|
borderLeftWidth: props.borderOption.left,
|
|
50
91
|
borderTopWidth: props.borderOption.top,
|
|
@@ -52,6 +93,8 @@ export const Style: any = (props: Props) => {
|
|
|
52
93
|
borderRightWidth: props.borderOption.right,
|
|
53
94
|
borderColor: props.borderOption.color,
|
|
54
95
|
},
|
|
96
|
+
|
|
97
|
+
// Shadow options
|
|
55
98
|
!isEmpty(props.shadowOption) && {
|
|
56
99
|
shadowColor: props.shadowOption?.color,
|
|
57
100
|
shadowOffset: {
|
|
@@ -62,6 +105,8 @@ export const Style: any = (props: Props) => {
|
|
|
62
105
|
shadowRadius: props.shadowOption?.radius,
|
|
63
106
|
elevation: props.shadowOption?.elevation,
|
|
64
107
|
},
|
|
108
|
+
|
|
109
|
+
// Default shadow
|
|
65
110
|
props.shadowColor && {
|
|
66
111
|
shadowColor: isString(props.shadowColor) ? props.shadowColor : '#000',
|
|
67
112
|
shadowOffset: { width: 2, height: 2, },
|
|
@@ -69,14 +114,17 @@ export const Style: any = (props: Props) => {
|
|
|
69
114
|
shadowRadius: 10,
|
|
70
115
|
elevation: 2,
|
|
71
116
|
},
|
|
117
|
+
|
|
118
|
+
// Width and height shortcuts
|
|
72
119
|
props.w100 && { width: '100%' },
|
|
73
120
|
props.h100 && { height: '100%' },
|
|
74
|
-
|
|
121
|
+
props.flex1 && { flex: 1 },
|
|
122
|
+
props.flexOne && { flex: 1 },
|
|
123
|
+
// Screen dimensions
|
|
75
124
|
props.widthScreen && { width: Dimensions.get('screen').width },
|
|
76
125
|
props.heightScreen && { height: Dimensions.get('screen').height },
|
|
77
|
-
|
|
78
|
-
|
|
79
126
|
])
|
|
127
|
+
|
|
80
128
|
return [
|
|
81
129
|
makeStyle(props),
|
|
82
130
|
PropsApp,
|
package/src/Touch/Touch.tsx
CHANGED
|
@@ -6,6 +6,39 @@ import { isArray, isString } from 'underscore'
|
|
|
6
6
|
import LinearGradient from 'react-native-linear-gradient'
|
|
7
7
|
|
|
8
8
|
type TouchableOpacityRef = React.ComponentRef<typeof TouchableOpacity>
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Touch component that extends TouchableOpacity with additional styling capabilities
|
|
12
|
+
* Supports gradient backgrounds and custom styling options
|
|
13
|
+
*
|
|
14
|
+
* @component
|
|
15
|
+
* @example
|
|
16
|
+
* ```tsx
|
|
17
|
+
* // Basic usage
|
|
18
|
+
* <Touch onPress={() => console.log('pressed')}>
|
|
19
|
+
* <Text>Press me</Text>
|
|
20
|
+
* </Touch>
|
|
21
|
+
*
|
|
22
|
+
* // With gradient background
|
|
23
|
+
* <Touch
|
|
24
|
+
* background={['#ff0000', '#00ff00']}
|
|
25
|
+
* gradient="vertical"
|
|
26
|
+
* onPress={() => console.log('pressed')}
|
|
27
|
+
* >
|
|
28
|
+
* <Text>Gradient Button</Text>
|
|
29
|
+
* </Touch>
|
|
30
|
+
*
|
|
31
|
+
* // With custom styling
|
|
32
|
+
* <Touch
|
|
33
|
+
* mid={true}
|
|
34
|
+
* row={true}
|
|
35
|
+
* paddingOption={{ all: 10 }}
|
|
36
|
+
* onPress={() => console.log('pressed')}
|
|
37
|
+
* >
|
|
38
|
+
* <Text>Styled Button</Text>
|
|
39
|
+
* </Touch>
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
9
42
|
const Touch = React.forwardRef<TouchableOpacityRef, Props>(({ style, ...props }, ref) => {
|
|
10
43
|
if (props?.hidden) return <></>
|
|
11
44
|
//@ts-ignore
|
package/src/Touch/makeStyle.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { StyleSheet } from "react-native";
|
|
2
2
|
import { isNaN, isNumber } from "underscore";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Enum of predefined color names that can be used for background colors
|
|
6
|
+
*/
|
|
3
7
|
enum COLORS {
|
|
4
8
|
"white" = 1,
|
|
5
9
|
"red",
|
|
@@ -11,8 +15,14 @@ enum COLORS {
|
|
|
11
15
|
"gray",
|
|
12
16
|
"primary"
|
|
13
17
|
}
|
|
18
|
+
|
|
19
|
+
/** Type for color modifiers that can be used as boolean flags */
|
|
14
20
|
type ColorModifiers = Partial<Record<keyof typeof COLORS, boolean>>;
|
|
15
21
|
|
|
22
|
+
/**
|
|
23
|
+
* Mapping of short property names to their full React Native style property names
|
|
24
|
+
* This allows for shorter, more convenient style property names
|
|
25
|
+
*/
|
|
16
26
|
const SHORT_VARIATIONS = {
|
|
17
27
|
bg: "backgroundColor",
|
|
18
28
|
background: "backgroundColor",
|
|
@@ -54,10 +64,35 @@ const SHORT_VARIATIONS = {
|
|
|
54
64
|
right: 'right',
|
|
55
65
|
opacity: 'opacity'
|
|
56
66
|
};
|
|
67
|
+
|
|
68
|
+
/** Type for short property names */
|
|
57
69
|
export type ShortKey = keyof typeof SHORT_VARIATIONS;
|
|
70
|
+
|
|
71
|
+
/** Type for converting string keys to a record of boolean/number/string values */
|
|
58
72
|
export type Convert<T extends string> = Partial<Record<T, boolean | number | string>>
|
|
73
|
+
|
|
74
|
+
/** Type combining short property names and color modifiers */
|
|
59
75
|
export type MakeProp = Convert<ShortKey> & ColorModifiers
|
|
60
76
|
|
|
77
|
+
/**
|
|
78
|
+
* Creates a React Native style object from props using short property names
|
|
79
|
+
* Supports color names, hyphenated properties, and direct style properties
|
|
80
|
+
*
|
|
81
|
+
* @param props - Object containing style properties
|
|
82
|
+
* @returns React Native style object
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```tsx
|
|
86
|
+
* // Using color names
|
|
87
|
+
* makeStyle({ white: true }) // { backgroundColor: 'white' }
|
|
88
|
+
*
|
|
89
|
+
* // Using hyphenated properties
|
|
90
|
+
* makeStyle({ 'pad-10': true }) // { padding: 10 }
|
|
91
|
+
*
|
|
92
|
+
* // Using direct properties
|
|
93
|
+
* makeStyle({ width: 100 }) // { width: 100 }
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
61
96
|
export const makeStyle = (props: { [key: string]: any }) => {
|
|
62
97
|
const style: { [key: string]: number | string } = {};
|
|
63
98
|
Object.keys(props).forEach((key) => {
|