react-native-boxes 1.3.24 → 1.3.25
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 +3 -2
- package/src/Bar.tsx +3 -2
- package/src/Modal.tsx +90 -8
- package/src/utils.ts +42 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-boxes",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.25",
|
|
4
4
|
"description": "A react native library for rapid development of UI using boxes",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
"typescript": "^5.4.3"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@react-native-async-storage/async-storage": "^1.23.1"
|
|
37
|
+
"@react-native-async-storage/async-storage": "^1.23.1",
|
|
38
|
+
"expo-web-browser": "^13.0.3"
|
|
38
39
|
}
|
|
39
40
|
}
|
package/src/Bar.tsx
CHANGED
|
@@ -131,15 +131,16 @@ export function TransparentCenterToolbar(props: SimpleToolbarProps) {
|
|
|
131
131
|
const theme = useContext(ThemeContext)
|
|
132
132
|
return (
|
|
133
133
|
<SimpleToolbar
|
|
134
|
+
{...props}
|
|
134
135
|
style={[{
|
|
135
136
|
width: '100%'
|
|
136
137
|
}, props.style]}
|
|
137
138
|
textStyle={{
|
|
138
139
|
color: theme.colors.text
|
|
139
140
|
}}
|
|
140
|
-
homeIcon=
|
|
141
|
+
homeIcon={props.homeIcon || ""}
|
|
142
|
+
title={props.title}
|
|
141
143
|
backgroundColor={theme.colors.transparent}
|
|
142
|
-
{...props}
|
|
143
144
|
/>
|
|
144
145
|
)
|
|
145
146
|
}
|
package/src/Modal.tsx
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
//@ts-nocheck
|
|
2
1
|
import * as React from 'react';
|
|
3
2
|
import { useContext, useEffect, useRef, useState } from 'react';
|
|
4
|
-
import { Animated, Button, Easing, LayoutChangeEvent, Modal, Platform, Pressable, ScrollView, StyleProp, StyleSheet, TextStyle, TouchableHighlight, TouchableOpacity, View, ViewProps } from 'react-native';
|
|
3
|
+
import { Animated, Button, Easing, LayoutChangeEvent, Linking, Modal, Platform, Pressable, ScrollView, StyleProp, StyleSheet, TextStyle, TouchableHighlight, TouchableOpacity, View, ViewProps } from 'react-native';
|
|
5
4
|
import { Icon, IconProps } from './Image';
|
|
6
|
-
import { isDesktop } from './utils';
|
|
5
|
+
import { getNavParamsFromDeeplink, isDesktop, isWeb } from './utils';
|
|
7
6
|
import { ThemeContext } from './ThemeContext';
|
|
8
|
-
import { Center, HBox, VBox } from './Box';
|
|
7
|
+
import { Center, HBox, VBox, VPage } from './Box';
|
|
9
8
|
import { Subtitle, TextView, Title } from './Text';
|
|
10
|
-
import { ButtonView, ButtonViewProps, PressableView, TertiaryButtonView } from './Button';
|
|
11
|
-
import { CompositeTextInputView
|
|
9
|
+
import { ButtonView, ButtonViewProps, LoadingButton, PressableView, TertiaryButtonView } from './Button';
|
|
10
|
+
import { CompositeTextInputView } from './Input';
|
|
11
|
+
import * as WebBrowser from 'expo-web-browser';
|
|
12
|
+
import { TransparentCenterToolbar } from './Bar';
|
|
13
|
+
|
|
12
14
|
|
|
13
15
|
export type BottomSheetProps = {
|
|
14
16
|
visible: boolean,
|
|
@@ -340,6 +342,7 @@ export const DropDownView = (props: DropDownViewProps) => {
|
|
|
340
342
|
<select
|
|
341
343
|
defaultValue={props.selectedId}
|
|
342
344
|
onChange={(e) => {
|
|
345
|
+
//@ts-ignore
|
|
343
346
|
props.onSelect(e.target.value, props.options.find(o => o.id == e.target.value)?.value)
|
|
344
347
|
}}
|
|
345
348
|
//@ts-ignore
|
|
@@ -370,7 +373,7 @@ export const DropDownView = (props: DropDownViewProps) => {
|
|
|
370
373
|
return (
|
|
371
374
|
<VBox style={props.style}>
|
|
372
375
|
<BottomSheet
|
|
373
|
-
visible={visible}
|
|
376
|
+
visible={visible as boolean}
|
|
374
377
|
onDismiss={() => {
|
|
375
378
|
setVisible(false)
|
|
376
379
|
}}
|
|
@@ -423,6 +426,7 @@ export const DropDownView = (props: DropDownViewProps) => {
|
|
|
423
426
|
onIconPress={() => { setVisible(true) }}
|
|
424
427
|
icon={"caret-down"}
|
|
425
428
|
pointerEvents="none"
|
|
429
|
+
//@ts-ignore
|
|
426
430
|
_textInputProps={{
|
|
427
431
|
caretHidden: true,
|
|
428
432
|
placeholder: props.title || 'select',
|
|
@@ -484,4 +488,82 @@ export function ConfirmationDialog(props: ConfirmationDialogProps) {
|
|
|
484
488
|
|
|
485
489
|
</BottomSheet>
|
|
486
490
|
)
|
|
487
|
-
}
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
|
|
494
|
+
export default function WebBrowserView(props: {
|
|
495
|
+
url: string,
|
|
496
|
+
title?: string,
|
|
497
|
+
openMessage?: string,
|
|
498
|
+
retryMessage?: string,
|
|
499
|
+
cancelMessage?: string;
|
|
500
|
+
onCancel: () => void,
|
|
501
|
+
navigation: {
|
|
502
|
+
navigate: (path: string, params: any) => void
|
|
503
|
+
}
|
|
504
|
+
}) {
|
|
505
|
+
const [result, setResult] = useState(null);
|
|
506
|
+
const [loading, setLoading] = useState(false)
|
|
507
|
+
const _handlePressButtonAsync = async () => {
|
|
508
|
+
if (isWeb()) {
|
|
509
|
+
setLoading(true)
|
|
510
|
+
setTimeout(() => {
|
|
511
|
+
setLoading(false)
|
|
512
|
+
}, 5000)
|
|
513
|
+
//@ts-ignore
|
|
514
|
+
window.location.href = props.url
|
|
515
|
+
} else {
|
|
516
|
+
let result: any = await WebBrowser.openBrowserAsync(props.url);
|
|
517
|
+
setResult(result);
|
|
518
|
+
}
|
|
519
|
+
};
|
|
520
|
+
|
|
521
|
+
useEffect(() => {
|
|
522
|
+
if (result == null)
|
|
523
|
+
_handlePressButtonAsync()
|
|
524
|
+
}, [])
|
|
525
|
+
const theme = useContext(ThemeContext)
|
|
526
|
+
Linking.addEventListener('url', (url) => {
|
|
527
|
+
if (url?.url) {
|
|
528
|
+
let path = url?.url.split("://")[1]
|
|
529
|
+
if (path) {
|
|
530
|
+
const [root, params] = getNavParamsFromDeeplink(path)
|
|
531
|
+
props.navigation?.navigate(root, params)
|
|
532
|
+
}
|
|
533
|
+
Linking.removeAllListeners('url')
|
|
534
|
+
}
|
|
535
|
+
});
|
|
536
|
+
return (
|
|
537
|
+
<VPage >
|
|
538
|
+
<TransparentCenterToolbar title={props.title || ''} />
|
|
539
|
+
<Center style={{
|
|
540
|
+
paddingBottom: theme.dimens.space.xl,
|
|
541
|
+
flex: 1,
|
|
542
|
+
}}>
|
|
543
|
+
<Center style={{
|
|
544
|
+
paddingBottom: theme.dimens.space.xl * 2,
|
|
545
|
+
}}>
|
|
546
|
+
<Icon name="globe" size={theme.dimens.icon.xxl} />
|
|
547
|
+
<Subtitle style={{
|
|
548
|
+
padding: theme.dimens.space.xl,
|
|
549
|
+
paddingTop: theme.dimens.space.lg,
|
|
550
|
+
textAlign: 'center'
|
|
551
|
+
}}>{props.openMessage || "Open in browser to continue."}</Subtitle>
|
|
552
|
+
</Center>
|
|
553
|
+
<LoadingButton
|
|
554
|
+
loading={loading}
|
|
555
|
+
onPress={() => {
|
|
556
|
+
_handlePressButtonAsync()
|
|
557
|
+
}}
|
|
558
|
+
style={{
|
|
559
|
+
width: '80%'
|
|
560
|
+
}}>{props.retryMessage || "Retry"}</LoadingButton>
|
|
561
|
+
<TertiaryButtonView
|
|
562
|
+
onPress={() => {
|
|
563
|
+
props.onCancel && props.onCancel()
|
|
564
|
+
}}
|
|
565
|
+
text={props.cancelMessage || "Cancel"} />
|
|
566
|
+
</Center>
|
|
567
|
+
</VPage>
|
|
568
|
+
);
|
|
569
|
+
}
|
package/src/utils.ts
CHANGED
|
@@ -2,6 +2,48 @@ import { Platform } from "react-native";
|
|
|
2
2
|
import { Dimensions } from 'react-native';
|
|
3
3
|
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
4
4
|
|
|
5
|
+
|
|
6
|
+
export function getNavParamsFromDeeplink(url: string) {
|
|
7
|
+
let parts = url.split("/");
|
|
8
|
+
|
|
9
|
+
let root, rootParams: any = {};
|
|
10
|
+
root = parts[0];
|
|
11
|
+
if (parts.length > 1) {
|
|
12
|
+
|
|
13
|
+
let obj = {
|
|
14
|
+
screen: '',
|
|
15
|
+
params: {}
|
|
16
|
+
};
|
|
17
|
+
let lastCloneObj = undefined;
|
|
18
|
+
for (let i = 1; i < parts.length; i++) {
|
|
19
|
+
const part = parts[i];
|
|
20
|
+
let cloneObj = Object.assign({}, obj);
|
|
21
|
+
|
|
22
|
+
if (part?.indexOf("?") > -1) {
|
|
23
|
+
cloneObj.screen = part.split("?")[0];
|
|
24
|
+
const query = part.split("?")[1];
|
|
25
|
+
const params: any = {};
|
|
26
|
+
const queryParams = query.split("&");
|
|
27
|
+
queryParams?.forEach((pk) => {
|
|
28
|
+
const [value, key] = pk.split("=")
|
|
29
|
+
params[key] = value;
|
|
30
|
+
});
|
|
31
|
+
cloneObj.params = params;
|
|
32
|
+
} else {
|
|
33
|
+
cloneObj.screen = part;
|
|
34
|
+
}
|
|
35
|
+
if (lastCloneObj == undefined) {
|
|
36
|
+
lastCloneObj = cloneObj;
|
|
37
|
+
} else {
|
|
38
|
+
lastCloneObj.params = cloneObj;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
rootParams = lastCloneObj;
|
|
42
|
+
}
|
|
43
|
+
return [root, rootParams];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
|
|
5
47
|
export const Storage = {
|
|
6
48
|
async getKeyAsync(key: string) {
|
|
7
49
|
return await AsyncStorage.getItem(key);
|