@codeleap/mobile 2.1.10 → 2.2.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.
Files changed (67) hide show
  1. package/dist/components/AutoComplete/styles.js +1 -1
  2. package/dist/components/AutoComplete/styles.js.map +1 -1
  3. package/dist/components/Drawer/index.js +13 -2
  4. package/dist/components/Drawer/index.js.map +1 -1
  5. package/dist/components/Drawer/styles.js +2 -4
  6. package/dist/components/Drawer/styles.js.map +1 -1
  7. package/dist/components/EmptyPlaceholder/styles.js +1 -1
  8. package/dist/components/EmptyPlaceholder/styles.js.map +1 -1
  9. package/dist/components/Grid/index.d.ts +3 -1
  10. package/dist/components/Grid/index.js +19 -4
  11. package/dist/components/Grid/index.js.map +1 -1
  12. package/dist/components/ImageView/Spotlight.js +1 -2
  13. package/dist/components/ImageView/Spotlight.js.map +1 -1
  14. package/dist/components/List/index.d.ts +2 -1
  15. package/dist/components/List/index.js +19 -5
  16. package/dist/components/List/index.js.map +1 -1
  17. package/dist/components/Modal/index.d.ts +1 -0
  18. package/dist/components/Modal/index.js +7 -1
  19. package/dist/components/Modal/index.js.map +1 -1
  20. package/dist/components/Modal/styles.js +15 -18
  21. package/dist/components/Modal/styles.js.map +1 -1
  22. package/dist/components/Pager/styles.js +7 -7
  23. package/dist/components/Pager/styles.js.map +1 -1
  24. package/dist/components/Scroll/index.d.ts +4 -2
  25. package/dist/components/Scroll/index.js +5 -5
  26. package/dist/components/Scroll/index.js.map +1 -1
  27. package/dist/components/Scroll/styles.js +12 -4
  28. package/dist/components/Scroll/styles.js.map +1 -1
  29. package/dist/components/SegmentedControl/index.js +1 -1
  30. package/dist/components/SegmentedControl/index.js.map +1 -1
  31. package/dist/components/Select/index.js +2 -4
  32. package/dist/components/Select/index.js.map +1 -1
  33. package/dist/components/Select/styles.js +5 -1
  34. package/dist/components/Select/styles.js.map +1 -1
  35. package/dist/components/Select/types.d.ts +2 -1
  36. package/dist/components/legacy/Modal/index.d.ts +2 -1
  37. package/dist/components/legacy/Modal/index.js +1 -1
  38. package/dist/components/legacy/Modal/index.js.map +1 -1
  39. package/dist/components/legacy/Modal/styles.js +9 -9
  40. package/dist/components/legacy/Modal/styles.js.map +1 -1
  41. package/dist/utils/KeyboardAware/keyboardHooks.d.ts +22 -6
  42. package/dist/utils/KeyboardAware/keyboardHooks.js +63 -29
  43. package/dist/utils/KeyboardAware/keyboardHooks.js.map +1 -1
  44. package/dist/utils/hooks.d.ts +1 -0
  45. package/dist/utils/hooks.js +17 -1
  46. package/dist/utils/hooks.js.map +1 -1
  47. package/package.json +1 -1
  48. package/src/components/AutoComplete/styles.ts +1 -1
  49. package/src/components/Drawer/index.tsx +11 -1
  50. package/src/components/Drawer/styles.ts +3 -3
  51. package/src/components/EmptyPlaceholder/styles.ts +1 -1
  52. package/src/components/Grid/index.tsx +28 -18
  53. package/src/components/ImageView/Spotlight.tsx +0 -1
  54. package/src/components/List/index.tsx +31 -24
  55. package/src/components/Modal/index.tsx +11 -1
  56. package/src/components/Modal/styles.ts +28 -28
  57. package/src/components/Pager/styles.ts +7 -7
  58. package/src/components/Scroll/index.tsx +15 -8
  59. package/src/components/Scroll/styles.ts +1 -2
  60. package/src/components/SegmentedControl/index.tsx +1 -0
  61. package/src/components/Select/index.tsx +3 -6
  62. package/src/components/Select/styles.ts +2 -2
  63. package/src/components/Select/types.ts +2 -1
  64. package/src/components/legacy/Modal/index.tsx +3 -2
  65. package/src/components/legacy/Modal/styles.ts +17 -17
  66. package/src/utils/KeyboardAware/keyboardHooks.ts +102 -38
  67. package/src/utils/hooks.ts +19 -1
@@ -1,15 +1,23 @@
1
- import { PropsOf, TypeGuards } from '@codeleap/common'
1
+ import { PropsOf, TypeGuards, useCodeleapContext } from '@codeleap/common'
2
2
  import { useEffect, useState } from 'react'
3
- import { Keyboard, Platform, KeyboardEvent, KeyboardEventName, ScrollView, StyleSheet, ViewStyle } from 'react-native'
3
+ import {
4
+ Keyboard,
5
+ Platform,
6
+ KeyboardEvent,
7
+ KeyboardEventName,
8
+ Dimensions,
9
+ ScrollView,
10
+ StyleSheet,
11
+ } from 'react-native'
4
12
 
5
13
  type KeyboardVisibilityEvents = {
6
14
  show: KeyboardEventName
7
15
  hide: KeyboardEventName
8
16
  }
9
17
 
10
- export const useKeyboardVisibility = () => {
18
+ export const useKeyboard = () => {
11
19
  const [keyboardEvent, setKeyboardEvent] = useState<KeyboardEvent>(null)
12
- const [keyboardVisible, setKeyboardVisible] = useState(true)
20
+ const [keyboardVisible, setKeyboardVisible] = useState(false)
13
21
 
14
22
  useEffect(() => {
15
23
  const eventNames = Platform.select<KeyboardVisibilityEvents>({
@@ -39,53 +47,109 @@ export const useKeyboardVisibility = () => {
39
47
 
40
48
  const _return = {
41
49
  event: keyboardEvent,
42
- visible: keyboardVisible,
50
+ isVisible: keyboardVisible,
43
51
  height: keyboardEvent?.endCoordinates?.height || 0,
52
+ ...Keyboard,
44
53
  }
45
54
 
46
55
  return _return
47
56
  }
48
- type ScrollViewProps = PropsOf<typeof ScrollView>
57
+ type ScrollViewProps = Partial<
58
+ Pick<
59
+ PropsOf<typeof ScrollView>,
60
+ 'horizontal' | 'contentContainerStyle' | 'style'
61
+ >
62
+ >
49
63
 
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
64
+ export type GetKeyboardAwarePropsOptions = {
65
+ baseStyleProp?: 'style' | 'contentContainerStyle'
66
+ adapt?: 'height' | 'maxHeight' | 'paddingBottom' | 'marginBottom' | 'bottom'
67
+ enabled?: boolean
68
+ enableOnAndroid?: boolean
69
+ }
70
+ type UseKeyboardAwareViewParams = {
71
+ debugName?: string
72
+ }
73
+ export const useKeyboardAwareView = (params?: UseKeyboardAwareViewParams) => {
74
+ const keyboard = useKeyboard()
75
+ const { logger } = useCodeleapContext()
76
+ function getKeyboardAwareProps<T extends ScrollViewProps>(
77
+ props?:T,
78
+ options?: GetKeyboardAwarePropsOptions,
79
+ ): T {
80
+ const _options:GetKeyboardAwarePropsOptions = {
81
+ adapt: 'maxHeight',
82
+ baseStyleProp: 'style',
83
+ enabled: true,
84
+ enableOnAndroid: true,
85
+ ...options,
86
+ }
62
87
 
63
- const baseStyle:ScrollViewProps['style'] = StyleSheet.flatten(baseProps?.[styleProperty])
88
+ if (!_options.enabled || props?.horizontal || (Platform.OS === 'android' && !_options.enableOnAndroid)) return props
64
89
 
65
- const baseBottom = baseStyle?.paddingBottom || baseStyle?.padding || 0
90
+ if (!props) {
91
+ props = {} as T
92
+ }
93
+ const baseStyle = StyleSheet.flatten(props[_options.baseStyleProp] || {})
66
94
 
67
- if (TypeGuards.isNumber(baseBottom)) {
95
+ const baseValue = baseStyle[_options.adapt] as number
96
+ let valid = true
97
+ const warnOnNotNumber = () => {
98
+ if (!TypeGuards.isNil(baseValue) && !TypeGuards.isNumber(baseValue)) {
99
+ valid = false
100
+ const debugStr = params?.debugName ? 'at ' + params?.debugName + ' ' : ''
101
+ logger.warn(
102
+ `${_options.baseStyleProp}.${_options.adapt} must be a number or not be set at all`,
103
+ { props, options: _options },
104
+ 'useKeyboardAwareView' + debugStr,
105
+ )
106
+ }
107
+ }
68
108
 
69
- const keyboardAdaptionStyle = {
70
- ...baseStyle,
71
- [insetProperty]: baseBottom + keyboard.height,
109
+ const newStyleProp = {
110
+ ...baseStyle,
111
+ }
72
112
 
113
+ switch (_options.adapt) {
114
+ case 'height':
115
+ warnOnNotNumber()
116
+ const baseHeight = baseValue || 0
117
+ newStyleProp.height = baseHeight - keyboard.height
118
+ break
119
+ case 'maxHeight':
120
+ if (keyboard.isVisible) {
121
+ warnOnNotNumber()
122
+ const baseMaxHeight = baseValue || Dimensions.get('window').height
123
+ newStyleProp.maxHeight = baseMaxHeight - keyboard.height
124
+ // break
73
125
  }
74
- return {
126
+ break
127
+ case 'paddingBottom':
128
+ warnOnNotNumber()
129
+ const basePaddingBottom = baseValue || 0
130
+ newStyleProp.paddingBottom = basePaddingBottom + keyboard.height
131
+ break
132
+ case 'marginBottom':
133
+ warnOnNotNumber()
134
+ const baseMarginBottom = baseValue || 0
135
+ newStyleProp.marginBottom = baseMarginBottom + keyboard.height
136
+ break
137
+ case 'bottom':
138
+ warnOnNotNumber()
139
+ const baseBottom = baseValue || 0
140
+ newStyleProp.bottom = baseBottom + keyboard.height
141
+ break
142
+ }
75
143
 
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
- }
144
+ if (!valid) return props
88
145
 
89
- },
146
+ return {
147
+ ...props,
148
+ [_options.baseStyleProp]: newStyleProp,
149
+ }
150
+ }
151
+ return {
152
+ keyboard,
153
+ getKeyboardAwareProps,
90
154
  }
91
155
  }
@@ -1,5 +1,5 @@
1
1
  import { onMount, onUpdate, shadeColor, TypeGuards, usePrevious, useRef, useState } from '@codeleap/common'
2
- import { Animated, AppState, AppStateStatus, Platform, PressableAndroidRippleConfig } from 'react-native'
2
+ import { Animated, AppState, AppStateStatus, Platform, PressableAndroidRippleConfig, BackHandler } from 'react-native'
3
3
 
4
4
  export function useAnimateColor(value: string, opts?: Partial<Animated.TimingAnimationConfig>) {
5
5
  const iters = useRef(0)
@@ -143,3 +143,21 @@ export function usePressableFeedback(styles: any, config:UsePressableFeedbackCon
143
143
  rippleConfig,
144
144
  }
145
145
  }
146
+
147
+ export function useBackButton(cb: () => boolean|void, deps = []) {
148
+ onUpdate(() => {
149
+ const subscription = BackHandler.addEventListener('hardwareBackPress', () => {
150
+ const stopBubbling = cb()
151
+
152
+ if (TypeGuards.isBoolean(stopBubbling)) {
153
+ return stopBubbling
154
+ }
155
+
156
+ return false
157
+
158
+ })
159
+ return () => {
160
+ subscription.remove()
161
+ }
162
+ }, deps)
163
+ }