@codeleap/mobile 2.1.9 → 2.2.1

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 (72) hide show
  1. package/dist/components/AutoComplete/styles.js +1 -2
  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 +3 -5
  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 +4 -2
  18. package/dist/components/Modal/index.js +11 -3
  19. package/dist/components/Modal/index.js.map +1 -1
  20. package/dist/components/Modal/styles.d.ts +1 -1
  21. package/dist/components/Modal/styles.js +15 -15
  22. package/dist/components/Modal/styles.js.map +1 -1
  23. package/dist/components/MultiSelect/index.js +1 -1
  24. package/dist/components/Pager/styles.js +7 -7
  25. package/dist/components/Pager/styles.js.map +1 -1
  26. package/dist/components/Scroll/index.d.ts +4 -2
  27. package/dist/components/Scroll/index.js +20 -6
  28. package/dist/components/Scroll/index.js.map +1 -1
  29. package/dist/components/SegmentedControl/index.js +3 -1
  30. package/dist/components/SegmentedControl/index.js.map +1 -1
  31. package/dist/components/Select/index.js +13 -1
  32. package/dist/components/Select/index.js.map +1 -1
  33. package/dist/components/Select/styles.js +2 -0
  34. package/dist/components/Select/styles.js.map +1 -1
  35. package/dist/components/Select/types.d.ts +2 -0
  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/index.d.ts +1 -0
  42. package/dist/utils/KeyboardAware/index.js +1 -0
  43. package/dist/utils/KeyboardAware/index.js.map +1 -1
  44. package/dist/utils/KeyboardAware/keyboardHooks.d.ts +30 -0
  45. package/dist/utils/KeyboardAware/keyboardHooks.js +113 -0
  46. package/dist/utils/KeyboardAware/keyboardHooks.js.map +1 -0
  47. package/dist/utils/KeyboardAware/lib/KeyboardAwareHOC.d.ts +1 -1
  48. package/dist/utils/hooks.d.ts +1 -0
  49. package/dist/utils/hooks.js +17 -1
  50. package/dist/utils/hooks.js.map +1 -1
  51. package/package.json +1 -1
  52. package/src/components/AutoComplete/styles.ts +1 -2
  53. package/src/components/Drawer/index.tsx +11 -1
  54. package/src/components/Drawer/styles.ts +4 -4
  55. package/src/components/EmptyPlaceholder/styles.ts +1 -1
  56. package/src/components/Grid/index.tsx +28 -18
  57. package/src/components/ImageView/Spotlight.tsx +0 -1
  58. package/src/components/List/index.tsx +31 -24
  59. package/src/components/Modal/index.tsx +18 -7
  60. package/src/components/Modal/styles.ts +38 -27
  61. package/src/components/MultiSelect/index.tsx +1 -1
  62. package/src/components/Pager/styles.ts +7 -7
  63. package/src/components/Scroll/index.tsx +37 -24
  64. package/src/components/SegmentedControl/index.tsx +3 -0
  65. package/src/components/Select/index.tsx +13 -7
  66. package/src/components/Select/styles.ts +2 -0
  67. package/src/components/Select/types.ts +2 -0
  68. package/src/components/legacy/Modal/index.tsx +3 -2
  69. package/src/components/legacy/Modal/styles.ts +17 -17
  70. package/src/utils/KeyboardAware/index.ts +1 -0
  71. package/src/utils/KeyboardAware/keyboardHooks.ts +155 -0
  72. package/src/utils/hooks.ts +19 -1
@@ -10,7 +10,7 @@ import { TextInput } from '../TextInput'
10
10
  import { Touchable } from '../Touchable'
11
11
  import { SelectStyles } from './styles'
12
12
  import { CustomSelectProps } from './types'
13
- import { ModalManager } from '../../utils'
13
+ import { ModalManager, useKeyboardAwareView } from '../../utils'
14
14
  import { Icon } from '../Icon'
15
15
 
16
16
  export const SelectItem = ({ item, icon = null, isSelected, styles, onPress }) => {
@@ -46,6 +46,7 @@ export const Select = <T extends string|number = string>(selectProps:CustomSelec
46
46
  selectedIcon = 'selectMarker',
47
47
  inputProps = {},
48
48
  hideInput = false,
49
+
49
50
  ...drawerProps
50
51
  } = selectProps
51
52
 
@@ -102,6 +103,16 @@ export const Select = <T extends string|number = string>(selectProps:CustomSelec
102
103
  }
103
104
 
104
105
  }
106
+
107
+ const baseListProps = {
108
+ data: options,
109
+ style: variantStyles.list,
110
+ contentContainerStyle: variantStyles.listContent,
111
+ keyExtractor: (i) => i.value,
112
+ renderItem: renderListItem,
113
+ ...listProps,
114
+ }
115
+
105
116
  return <>
106
117
  {
107
118
  !hideInput && (
@@ -132,12 +143,7 @@ export const Select = <T extends string|number = string>(selectProps:CustomSelec
132
143
 
133
144
  <ModalManager.Drawer scroll={false} title={label} {...drawerProps} styles={variantStyles}>
134
145
  <List<CustomSelectProps<any>['options']>
135
- data={options}
136
- style={variantStyles.list}
137
- contentContainerStyle={variantStyles.listContent}
138
- keyExtractor={(i) => i.value}
139
- renderItem={renderListItem}
140
- {...listProps}
146
+ {...baseListProps}
141
147
  />
142
148
  </ModalManager.Drawer>
143
149
 
@@ -49,6 +49,8 @@ export const SelectStyles = {
49
49
  list: {
50
50
  height: 'auto',
51
51
 
52
+ maxHeight: theme.values.window.height * 0.7,
53
+ // ...theme.presets.safeAreaBottom(),
52
54
  },
53
55
  listContent: {
54
56
  paddingBottom: theme.values.bottomNavHeight + theme.spacing.value(1),
@@ -4,6 +4,7 @@ import {
4
4
  IconPlaceholder,
5
5
  } from '@codeleap/common'
6
6
  import { StylesOf } from '../../types/utility'
7
+ import { GetKeyboardAwarePropsOptions } from '../../utils'
7
8
  import { DrawerProps } from '../Drawer'
8
9
  import { FlatListProps } from '../List'
9
10
  import { TextInputProps } from '../TextInput'
@@ -37,5 +38,6 @@ export type CustomSelectProps<T> = SelectDrawerProps & {
37
38
  listProps?: Partial<FlatListProps>
38
39
  clearable?: boolean
39
40
  clearIconName?: IconPlaceholder
41
+ keyboardAware?: GetKeyboardAwarePropsOptions
40
42
  } & ComponentVariants<typeof SelectStyles>
41
43
 
@@ -19,6 +19,7 @@ import { StylesOf } from '../../../types/utility'
19
19
  import { Touchable } from '../../Touchable'
20
20
  import { Text } from '../../Text'
21
21
  import { Animated } from '../../Animated'
22
+ import { GetKeyboardAwarePropsOptions } from '../../../utils'
22
23
 
23
24
  export * from './styles'
24
25
 
@@ -38,7 +39,7 @@ export type ModalProps = Omit<ViewProps, 'variants' | 'styles'> & {
38
39
  toggle?: () => void
39
40
  zIndex?: number
40
41
  scroll?: boolean
41
- keyboardAware?: boolean
42
+ keyboardAware?: GetKeyboardAwarePropsOptions
42
43
  }
43
44
 
44
45
  export const Modal: React.FC<ModalProps> = (modalProps) => {
@@ -56,7 +57,7 @@ export const Modal: React.FC<ModalProps> = (modalProps) => {
56
57
  closeIconName = 'close',
57
58
  debugName,
58
59
  scroll = true,
59
- keyboardAware = true,
60
+ keyboardAware,
60
61
  zIndex = null,
61
62
  ...props
62
63
  } = modalProps
@@ -39,12 +39,12 @@ const defaultModalStyles = ModalStyles
39
39
  export const MobileModalStyles = {
40
40
  ...defaultModalStyles,
41
41
  ...presets,
42
- default: createModalStyle((Theme) => {
42
+ default: createModalStyle((theme) => {
43
43
  const fullSize = {
44
- ...Theme.presets.whole,
44
+ ...theme.presets.whole,
45
45
  position: 'absolute',
46
- width: Theme?.values?.width,
47
- height: Theme?.values?.height,
46
+ width: theme?.values?.width,
47
+ height: theme?.values?.height,
48
48
  }
49
49
 
50
50
  return {
@@ -57,7 +57,7 @@ export const MobileModalStyles = {
57
57
  overlay: {
58
58
  opacity: 0,
59
59
 
60
- backgroundColor: Theme.colors.black,
60
+ backgroundColor: theme.colors.black,
61
61
  ...fullSize,
62
62
  },
63
63
  'overlay:visible': {
@@ -67,14 +67,14 @@ export const MobileModalStyles = {
67
67
  innerWrapperScroll: {
68
68
  display: 'flex',
69
69
  alignItems: 'center',
70
- ...Theme.presets.justifyCenter,
71
- minHeight: Theme.values.height,
70
+ ...theme.presets.justifyCenter,
71
+ minHeight: theme.values.window.height,
72
72
  },
73
73
  box: {
74
74
  width: '80%',
75
- backgroundColor: Theme.colors.background,
76
- borderRadius: Theme.borderRadius.medium,
77
- ...Theme.spacing.padding(2),
75
+ backgroundColor: theme.colors.background,
76
+ borderRadius: theme.borderRadius.medium,
77
+ ...theme.spacing.padding(2),
78
78
  },
79
79
  touchableBackdrop: {
80
80
  ...fullSize,
@@ -91,17 +91,17 @@ export const MobileModalStyles = {
91
91
  },
92
92
  header: {
93
93
  flexDirection: 'row',
94
- ...Theme.presets.justifySpaceBetween,
95
- ...Theme.presets.alignCenter,
94
+ ...theme.presets.justifySpaceBetween,
95
+ ...theme.presets.alignCenter,
96
96
  },
97
97
  closeButtonWrapper: {
98
98
  alignSelf: 'center',
99
- ...Theme.spacing.marginLeft('auto'),
99
+ ...theme.spacing.marginLeft('auto'),
100
100
  },
101
101
  title: {
102
- ...Theme.presets.textCenter,
103
- ...assignTextStyle('h3')(Theme).text,
104
- ...Theme.spacing.paddingBottom(1),
102
+ ...theme.presets.textCenter,
103
+ ...assignTextStyle('h3')(theme).text,
104
+ ...theme.spacing.paddingBottom(1),
105
105
  flex: 1,
106
106
  },
107
107
  }
@@ -118,7 +118,7 @@ export const MobileModalStyles = {
118
118
  flex: 1,
119
119
  borderRadius: 0,
120
120
  width: theme.values.width,
121
- height: theme.values.height,
121
+ height: theme.values.window.height,
122
122
  ...theme.presets.center,
123
123
  },
124
124
  })),
@@ -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,155 @@
1
+ import { PropsOf, TypeGuards, useCodeleapContext } from '@codeleap/common'
2
+ import { useEffect, useState } from 'react'
3
+ import {
4
+ Keyboard,
5
+ Platform,
6
+ KeyboardEvent,
7
+ KeyboardEventName,
8
+ Dimensions,
9
+ ScrollView,
10
+ StyleSheet,
11
+ } from 'react-native'
12
+
13
+ type KeyboardVisibilityEvents = {
14
+ show: KeyboardEventName
15
+ hide: KeyboardEventName
16
+ }
17
+
18
+ export const useKeyboard = () => {
19
+ const [keyboardEvent, setKeyboardEvent] = useState<KeyboardEvent>(null)
20
+ const [keyboardVisible, setKeyboardVisible] = useState(false)
21
+
22
+ useEffect(() => {
23
+ const eventNames = Platform.select<KeyboardVisibilityEvents>({
24
+ ios: {
25
+ show: 'keyboardWillShow',
26
+ hide: 'keyboardWillHide',
27
+ },
28
+ android: {
29
+ show: 'keyboardDidShow',
30
+ hide: 'keyboardDidHide',
31
+ },
32
+ })
33
+ const events = [
34
+ Keyboard.addListener(eventNames.show, (e) => {
35
+ setKeyboardVisible(true)
36
+ setKeyboardEvent(e)
37
+ }),
38
+ Keyboard.addListener(eventNames.hide, (e) => {
39
+ setKeyboardVisible(false)
40
+ setKeyboardEvent(e)
41
+ }),
42
+ ]
43
+ return () => {
44
+ events.forEach(e => e.remove())
45
+ }
46
+ }, [])
47
+
48
+ const _return = {
49
+ event: keyboardEvent,
50
+ isVisible: keyboardVisible,
51
+ height: keyboardEvent?.endCoordinates?.height || 0,
52
+ ...Keyboard,
53
+ }
54
+
55
+ return _return
56
+ }
57
+ type ScrollViewProps = Partial<
58
+ Pick<
59
+ PropsOf<typeof ScrollView>,
60
+ 'horizontal' | 'contentContainerStyle' | 'style'
61
+ >
62
+ >
63
+
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
+ }
87
+
88
+ if (!_options.enabled || props?.horizontal || (Platform.OS === 'android' && !_options.enableOnAndroid)) return props
89
+
90
+ if (!props) {
91
+ props = {} as T
92
+ }
93
+ const baseStyle = StyleSheet.flatten(props[_options.baseStyleProp] || {})
94
+
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
+ }
108
+
109
+ const newStyleProp = {
110
+ ...baseStyle,
111
+ }
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
125
+ }
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
+ }
143
+
144
+ if (!valid) return props
145
+
146
+ return {
147
+ ...props,
148
+ [_options.baseStyleProp]: newStyleProp,
149
+ }
150
+ }
151
+ return {
152
+ keyboard,
153
+ getKeyboardAwareProps,
154
+ }
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
+ }