@codeleap/mobile 2.1.7 → 2.1.10
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/dist/components/AutoComplete/styles.js +0 -1
- package/dist/components/AutoComplete/styles.js.map +1 -1
- package/dist/components/Drawer/index.js +1 -1
- package/dist/components/Drawer/index.js.map +1 -1
- package/dist/components/Drawer/styles.js +2 -2
- package/dist/components/Drawer/styles.js.map +1 -1
- package/dist/components/Modal/index.d.ts +3 -2
- package/dist/components/Modal/index.js +5 -3
- package/dist/components/Modal/index.js.map +1 -1
- package/dist/components/Modal/styles.d.ts +1 -1
- package/dist/components/Modal/styles.js +7 -4
- package/dist/components/Modal/styles.js.map +1 -1
- package/dist/components/MultiSelect/index.js +15 -3
- package/dist/components/MultiSelect/index.js.map +1 -1
- package/dist/components/MultiSelect/types.d.ts +3 -0
- package/dist/components/Scroll/index.js +19 -5
- package/dist/components/Scroll/index.js.map +1 -1
- package/dist/components/Scroll/styles.js +4 -12
- package/dist/components/Scroll/styles.js.map +1 -1
- package/dist/components/Select/index.js +30 -3
- package/dist/components/Select/index.js.map +1 -1
- package/dist/components/Select/styles.js +1 -3
- package/dist/components/Select/styles.js.map +1 -1
- package/dist/components/Select/types.d.ts +3 -0
- package/dist/utils/KeyboardAware/index.d.ts +1 -0
- package/dist/utils/KeyboardAware/index.js +1 -0
- package/dist/utils/KeyboardAware/index.js.map +1 -1
- package/dist/utils/KeyboardAware/keyboardHooks.d.ts +14 -0
- package/dist/utils/KeyboardAware/keyboardHooks.js +79 -0
- package/dist/utils/KeyboardAware/keyboardHooks.js.map +1 -0
- package/dist/utils/KeyboardAware/lib/KeyboardAwareHOC.d.ts +1 -1
- package/dist/utils/PermissionManager/context.d.ts +2 -2
- package/dist/utils/PermissionManager/context.js +25 -29
- package/dist/utils/PermissionManager/context.js.map +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/input.d.ts +35 -0
- package/dist/utils/input.js +49 -0
- package/dist/utils/input.js.map +1 -0
- package/package.json +1 -1
- package/src/components/AutoComplete/styles.ts +0 -1
- package/src/components/Drawer/index.tsx +1 -1
- package/src/components/Drawer/styles.ts +2 -2
- package/src/components/Modal/index.tsx +8 -7
- package/src/components/Modal/styles.ts +17 -6
- package/src/components/MultiSelect/index.tsx +19 -1
- package/src/components/MultiSelect/types.ts +3 -0
- package/src/components/Scroll/index.tsx +26 -20
- package/src/components/Scroll/styles.ts +2 -1
- package/src/components/Select/index.tsx +34 -9
- package/src/components/Select/styles.ts +2 -0
- package/src/components/Select/types.ts +3 -0
- package/src/utils/KeyboardAware/index.ts +1 -0
- package/src/utils/KeyboardAware/keyboardHooks.ts +91 -0
- package/src/utils/PermissionManager/context.tsx +31 -22
- package/src/utils/index.ts +1 -0
- package/src/utils/input.ts +51 -0
|
@@ -4,6 +4,7 @@ import listenToKeyboardEvents from './lib/KeyboardAwareHOC'
|
|
|
4
4
|
import KeyboardAwareScrollView from './lib/KeyboardAwareScrollView'
|
|
5
5
|
import KeyboardAwareFlatList from './lib/KeyboardAwareFlatList'
|
|
6
6
|
import KeyboardAwareSectionList from './lib/KeyboardAwareSectionList'
|
|
7
|
+
export * from './keyboardHooks'
|
|
7
8
|
|
|
8
9
|
export {
|
|
9
10
|
listenToKeyboardEvents,
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { PropsOf, TypeGuards } from '@codeleap/common'
|
|
2
|
+
import { useEffect, useState } from 'react'
|
|
3
|
+
import { Keyboard, Platform, KeyboardEvent, KeyboardEventName, ScrollView, StyleSheet, ViewStyle } from 'react-native'
|
|
4
|
+
|
|
5
|
+
type KeyboardVisibilityEvents = {
|
|
6
|
+
show: KeyboardEventName
|
|
7
|
+
hide: KeyboardEventName
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const useKeyboardVisibility = () => {
|
|
11
|
+
const [keyboardEvent, setKeyboardEvent] = useState<KeyboardEvent>(null)
|
|
12
|
+
const [keyboardVisible, setKeyboardVisible] = useState(true)
|
|
13
|
+
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
const eventNames = Platform.select<KeyboardVisibilityEvents>({
|
|
16
|
+
ios: {
|
|
17
|
+
show: 'keyboardWillShow',
|
|
18
|
+
hide: 'keyboardWillHide',
|
|
19
|
+
},
|
|
20
|
+
android: {
|
|
21
|
+
show: 'keyboardDidShow',
|
|
22
|
+
hide: 'keyboardDidHide',
|
|
23
|
+
},
|
|
24
|
+
})
|
|
25
|
+
const events = [
|
|
26
|
+
Keyboard.addListener(eventNames.show, (e) => {
|
|
27
|
+
setKeyboardVisible(true)
|
|
28
|
+
setKeyboardEvent(e)
|
|
29
|
+
}),
|
|
30
|
+
Keyboard.addListener(eventNames.hide, (e) => {
|
|
31
|
+
setKeyboardVisible(false)
|
|
32
|
+
setKeyboardEvent(e)
|
|
33
|
+
}),
|
|
34
|
+
]
|
|
35
|
+
return () => {
|
|
36
|
+
events.forEach(e => e.remove())
|
|
37
|
+
}
|
|
38
|
+
}, [])
|
|
39
|
+
|
|
40
|
+
const _return = {
|
|
41
|
+
event: keyboardEvent,
|
|
42
|
+
visible: keyboardVisible,
|
|
43
|
+
height: keyboardEvent?.endCoordinates?.height || 0,
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return _return
|
|
47
|
+
}
|
|
48
|
+
type ScrollViewProps = PropsOf<typeof ScrollView>
|
|
49
|
+
|
|
50
|
+
export const useKeyboardScrollView = () => {
|
|
51
|
+
const keyboard = useKeyboardVisibility()
|
|
52
|
+
|
|
53
|
+
return {
|
|
54
|
+
keyboard,
|
|
55
|
+
getScrollProps: <T extends ScrollViewProps>(
|
|
56
|
+
base?:T,
|
|
57
|
+
styleProperty: keyof T = 'style',
|
|
58
|
+
insetProperty:keyof ViewStyle = 'marginBottom',
|
|
59
|
+
): T => {
|
|
60
|
+
if (!keyboard.visible) return base || ({} as T)
|
|
61
|
+
const baseProps = base
|
|
62
|
+
|
|
63
|
+
const baseStyle:ScrollViewProps['style'] = StyleSheet.flatten(baseProps?.[styleProperty])
|
|
64
|
+
|
|
65
|
+
const baseBottom = baseStyle?.paddingBottom || baseStyle?.padding || 0
|
|
66
|
+
|
|
67
|
+
if (TypeGuards.isNumber(baseBottom)) {
|
|
68
|
+
|
|
69
|
+
const keyboardAdaptionStyle = {
|
|
70
|
+
...baseStyle,
|
|
71
|
+
[insetProperty]: baseBottom + keyboard.height,
|
|
72
|
+
|
|
73
|
+
}
|
|
74
|
+
return {
|
|
75
|
+
|
|
76
|
+
...baseProps,
|
|
77
|
+
keyboardDismissMode: 'interactive',
|
|
78
|
+
contentInset: { bottom: keyboard.height },
|
|
79
|
+
automaticallyAdjustContentInsets: false,
|
|
80
|
+
showsVerticalScrollIndicator: true,
|
|
81
|
+
scrollEventThrottle: 1,
|
|
82
|
+
keyboardSpace: keyboard.height,
|
|
83
|
+
[styleProperty]: keyboardAdaptionStyle,
|
|
84
|
+
} as unknown as T
|
|
85
|
+
} else {
|
|
86
|
+
throw new Error('Keyboard adaptive scroll view\'s "style.marginBottom" must be a number')
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
},
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -63,42 +63,49 @@ type AskManyOpts<T extends string|number|symbol > = {
|
|
|
63
63
|
export type UsePermissions<
|
|
64
64
|
_PermissionNames extends string,
|
|
65
65
|
PermissionNames extends string = `${_PermissionNames}?` | _PermissionNames> = () => TPermissionContext & {
|
|
66
|
-
askPermission: (name: PermissionNames, onResolve?: (status: PermissionTypes.PermissionStatus) => any) =>
|
|
66
|
+
askPermission: (name: PermissionNames, onResolve?: (status: PermissionTypes.PermissionStatus) => any) => Promise<PermissionTypes.PermissionStatus>
|
|
67
67
|
askMany<T extends PermissionNames, R = TAskManyResults<T>>(
|
|
68
68
|
perms: T[],
|
|
69
69
|
onResolve?: (res:R) => any,
|
|
70
70
|
options?: AskManyOpts<T>
|
|
71
|
-
):Promise<
|
|
71
|
+
):Promise<
|
|
72
|
+
R
|
|
73
|
+
>
|
|
72
74
|
}
|
|
73
75
|
|
|
74
76
|
export const usePermissions:UsePermissions<any> = () => {
|
|
75
77
|
const modalCtx = ModalManager.useModalContext()
|
|
76
78
|
const permissionCtx = useContext(PermissionContext)
|
|
77
79
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
80
|
+
function askPermission(name: string, onResolve?: (status: PermissionTypes.PermissionStatus, modalName?: string) => any) {
|
|
81
|
+
return new Promise<PermissionTypes.PermissionStatus>((resolve, reject) => {
|
|
82
|
+
permissionCtx.manager.get(name, {
|
|
83
|
+
ask: false,
|
|
84
|
+
askOnDenied: false,
|
|
85
|
+
askOnPending: false,
|
|
86
|
+
}).then(status => {
|
|
87
|
+
const permissionModalName = `permissions.${name}`
|
|
84
88
|
|
|
85
|
-
|
|
89
|
+
if (!status.isGranted) {
|
|
86
90
|
|
|
87
|
-
|
|
91
|
+
modalCtx.toggleModal(permissionModalName, true, {
|
|
92
|
+
onPermissionResolve: (status) => {
|
|
93
|
+
modalCtx.toggleModal(permissionModalName, false, {})
|
|
94
|
+
setTimeout(() => {
|
|
95
|
+
onResolve?.(status, permissionModalName)
|
|
88
96
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
onResolve?.(status, permissionModalName)
|
|
97
|
+
resolve(status)
|
|
98
|
+
}, modalCtx.transitionDuration)
|
|
99
|
+
},
|
|
100
|
+
})
|
|
94
101
|
|
|
95
|
-
|
|
96
|
-
|
|
102
|
+
} else {
|
|
103
|
+
onResolve?.(status.status as unknown as PermissionTypes.PermissionStatus)
|
|
104
|
+
resolve(status)
|
|
105
|
+
}
|
|
97
106
|
})
|
|
107
|
+
})
|
|
98
108
|
|
|
99
|
-
} else {
|
|
100
|
-
onResolve?.(status.status as unknown as PermissionTypes.PermissionStatus)
|
|
101
|
-
}
|
|
102
109
|
}
|
|
103
110
|
|
|
104
111
|
const askMany = async (
|
|
@@ -164,10 +171,12 @@ export const usePermissions:UsePermissions<any> = () => {
|
|
|
164
171
|
modalCtx.toggleModal(prevModal, false, {})
|
|
165
172
|
})
|
|
166
173
|
}
|
|
167
|
-
onResolve
|
|
174
|
+
const res:Parameters<typeof onResolve>[0] = {
|
|
168
175
|
...results,
|
|
169
176
|
overall: Object.values(results).every(x => x === 'granted') ? 'granted' : 'denied',
|
|
170
|
-
}
|
|
177
|
+
}
|
|
178
|
+
onResolve(res)
|
|
179
|
+
return res
|
|
171
180
|
}
|
|
172
181
|
|
|
173
182
|
return {
|
package/src/utils/index.ts
CHANGED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { TextInputProps } from 'react-native'
|
|
2
|
+
|
|
3
|
+
const createInputPresets = <T extends Record<string, (...args:any[]) => Partial<TextInputProps>>>(p:T):T => {
|
|
4
|
+
return p
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export const mobileInputPresets = createInputPresets({
|
|
8
|
+
email: () => ({
|
|
9
|
+
keyboardType: 'email-address',
|
|
10
|
+
autoCapitalize: 'none',
|
|
11
|
+
autoComplete: 'email',
|
|
12
|
+
textContentType: 'emailAddress',
|
|
13
|
+
|
|
14
|
+
}),
|
|
15
|
+
name: () => ({
|
|
16
|
+
autoCapitalize: 'words',
|
|
17
|
+
autoComplete: 'name',
|
|
18
|
+
textContentType: 'name',
|
|
19
|
+
|
|
20
|
+
}),
|
|
21
|
+
chat: () => ({
|
|
22
|
+
returnKeyType: 'send',
|
|
23
|
+
|
|
24
|
+
}),
|
|
25
|
+
password: (options?: {new?: boolean}) => {
|
|
26
|
+
return {
|
|
27
|
+
autoCapitalize: 'none',
|
|
28
|
+
autoComplete: options?.new ? 'password-new' : 'password',
|
|
29
|
+
textContentType: options?.new ? 'newPassword' : 'password',
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
search: () => ({
|
|
33
|
+
returnKeyType: 'search',
|
|
34
|
+
}),
|
|
35
|
+
redeemCode: (action:'join'|'obtain' = 'obtain') => {
|
|
36
|
+
const isJoin = action === 'join'
|
|
37
|
+
if (isJoin) {
|
|
38
|
+
return {
|
|
39
|
+
returnKeyType: 'join',
|
|
40
|
+
textContentType: 'oneTimeCode',
|
|
41
|
+
autoComplete: 'sms-otp',
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
returnKeyType: 'done',
|
|
46
|
+
textContentType: 'oneTimeCode',
|
|
47
|
+
autoComplete: 'sms-otp',
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
},
|
|
51
|
+
})
|