@codeleap/mobile 4.3.9 → 5.0.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 (209) hide show
  1. package/dist/components/Autocomplete/index.js.map +1 -1
  2. package/dist/components/Autocomplete/types.d.ts +9 -10
  3. package/dist/components/Backdrop/index.js.map +1 -1
  4. package/dist/components/Checkbox/index.js +13 -9
  5. package/dist/components/Checkbox/index.js.map +1 -1
  6. package/dist/components/Checkbox/types.d.ts +5 -2
  7. package/dist/components/DatePickerModal/index.js +18 -11
  8. package/dist/components/DatePickerModal/index.js.map +1 -1
  9. package/dist/components/DatePickerModal/types.d.ts +12 -9
  10. package/dist/components/FileInput/types.d.ts +3 -4
  11. package/dist/components/Grid/index.js.map +1 -1
  12. package/dist/components/Image/types.d.ts +2 -5
  13. package/dist/components/InputBase/index.d.ts +2 -6
  14. package/dist/components/InputBase/index.js +9 -5
  15. package/dist/components/InputBase/index.js.map +1 -1
  16. package/dist/components/InputBase/types.d.ts +2 -0
  17. package/dist/components/InputBase/useInputBase.d.ts +24 -0
  18. package/dist/components/InputBase/useInputBase.js +46 -0
  19. package/dist/components/InputBase/useInputBase.js.map +1 -0
  20. package/dist/components/InputBase/useInputBasePartialStyles.d.ts +2 -0
  21. package/dist/components/InputBase/useInputBasePartialStyles.js +30 -0
  22. package/dist/components/InputBase/useInputBasePartialStyles.js.map +1 -0
  23. package/dist/components/InputBase/utils.js +16 -16
  24. package/dist/components/InputBase/utils.js.map +1 -1
  25. package/dist/components/List/index.js +1 -1
  26. package/dist/components/List/index.js.map +1 -1
  27. package/dist/components/Modal/index.js +4 -14
  28. package/dist/components/Modal/index.js.map +1 -1
  29. package/dist/components/NumberIncrement/index.js +21 -132
  30. package/dist/components/NumberIncrement/index.js.map +1 -1
  31. package/dist/components/NumberIncrement/types.d.ts +7 -5
  32. package/dist/components/NumberIncrement/useNumberIncrement.d.ts +55 -0
  33. package/dist/components/NumberIncrement/useNumberIncrement.js +107 -0
  34. package/dist/components/NumberIncrement/useNumberIncrement.js.map +1 -0
  35. package/dist/components/RadioInput/index.d.ts +1 -1
  36. package/dist/components/RadioInput/index.js +20 -41
  37. package/dist/components/RadioInput/index.js.map +1 -1
  38. package/dist/components/RadioInput/types.d.ts +11 -9
  39. package/dist/components/Scroll/index.js +25 -28
  40. package/dist/components/Scroll/index.js.map +1 -1
  41. package/dist/components/Scroll/types.d.ts +4 -4
  42. package/dist/components/Sections/index.js +1 -1
  43. package/dist/components/Sections/index.js.map +1 -1
  44. package/dist/components/SegmentedControl/index.js +6 -4
  45. package/dist/components/SegmentedControl/index.js.map +1 -1
  46. package/dist/components/SegmentedControl/types.d.ts +4 -3
  47. package/dist/components/Select/index.js +10 -6
  48. package/dist/components/Select/index.js.map +1 -1
  49. package/dist/components/Select/types.d.ts +19 -18
  50. package/dist/components/Slider/index.js +18 -57
  51. package/dist/components/Slider/index.js.map +1 -1
  52. package/dist/components/Slider/types.d.ts +7 -5
  53. package/dist/components/SortablePhotos/index.js +17 -18
  54. package/dist/components/SortablePhotos/index.js.map +1 -1
  55. package/dist/components/SortablePhotos/types.d.ts +5 -15
  56. package/dist/components/SortablePhotos/useSortablePhotos.d.ts +11 -8
  57. package/dist/components/SortablePhotos/useSortablePhotos.js +18 -11
  58. package/dist/components/SortablePhotos/useSortablePhotos.js.map +1 -1
  59. package/dist/components/Switch/index.js +13 -9
  60. package/dist/components/Switch/index.js.map +1 -1
  61. package/dist/components/Switch/types.d.ts +5 -2
  62. package/dist/components/TextInput/index.js +26 -70
  63. package/dist/components/TextInput/index.js.map +1 -1
  64. package/dist/components/TextInput/types.d.ts +8 -6
  65. package/dist/components/TextInput/useTextInput.d.ts +54 -0
  66. package/dist/components/TextInput/useTextInput.js +59 -0
  67. package/dist/components/TextInput/useTextInput.js.map +1 -0
  68. package/dist/components/Touchable/index.js +4 -3
  69. package/dist/components/Touchable/index.js.map +1 -1
  70. package/dist/components/View/index.d.ts +7 -12
  71. package/dist/components/View/index.js +9 -7
  72. package/dist/components/View/index.js.map +1 -1
  73. package/dist/components/View/types.d.ts +6 -6
  74. package/dist/components/components.d.ts +0 -2
  75. package/dist/components/components.js +0 -2
  76. package/dist/components/components.js.map +1 -1
  77. package/dist/hooks/index.d.ts +3 -2
  78. package/dist/hooks/index.js +3 -10
  79. package/dist/hooks/index.js.map +1 -1
  80. package/dist/hooks/useKeyboardController.d.ts +6 -0
  81. package/dist/hooks/useKeyboardController.js +19 -0
  82. package/dist/hooks/useKeyboardController.js.map +1 -0
  83. package/dist/hooks/useStatusBar.d.ts +6 -0
  84. package/dist/hooks/useStatusBar.js +15 -0
  85. package/dist/hooks/useStatusBar.js.map +1 -0
  86. package/dist/hooks/useStylesFor.d.ts +2 -0
  87. package/dist/hooks/useStylesFor.js +11 -0
  88. package/dist/hooks/useStylesFor.js.map +1 -0
  89. package/dist/index.d.ts +2 -1
  90. package/dist/index.js +2 -1
  91. package/dist/index.js.map +1 -1
  92. package/dist/modules/backgroundTimer.d.ts +3 -0
  93. package/dist/modules/backgroundTimer.js +31 -0
  94. package/dist/modules/backgroundTimer.js.map +1 -0
  95. package/dist/modules/index.d.ts +3 -0
  96. package/dist/modules/index.js +3 -0
  97. package/dist/modules/index.js.map +1 -0
  98. package/dist/modules/reactNavigation.d.ts +8 -21
  99. package/dist/modules/reactNavigation.js +38 -12
  100. package/dist/modules/reactNavigation.js.map +1 -1
  101. package/dist/modules/scroll.d.ts +18 -0
  102. package/dist/modules/scroll.js +57 -0
  103. package/dist/modules/scroll.js.map +1 -0
  104. package/dist/modules/types/textInputMask.d.ts +6 -2
  105. package/dist/utils/KeyboardAware/context.js +2 -6
  106. package/dist/utils/KeyboardAware/context.js.map +1 -1
  107. package/dist/utils/KeyboardAware/index.d.ts +0 -1
  108. package/dist/utils/KeyboardAware/index.js +0 -1
  109. package/dist/utils/KeyboardAware/index.js.map +1 -1
  110. package/dist/utils/ModalManager/context.js +2 -2
  111. package/dist/utils/ModalManager/context.js.map +1 -1
  112. package/dist/utils/hooks.js +4 -4
  113. package/dist/utils/hooks.js.map +1 -1
  114. package/dist/utils/locale.d.ts +1 -1
  115. package/dist/utils/locale.js +10 -5
  116. package/dist/utils/locale.js.map +1 -1
  117. package/dist/utils/theme.d.ts +1 -0
  118. package/dist/utils/theme.js +4 -2
  119. package/dist/utils/theme.js.map +1 -1
  120. package/package.json +31 -35
  121. package/package.json.bak +17 -20
  122. package/src/components/Autocomplete/index.tsx +2 -3
  123. package/src/components/Autocomplete/types.ts +9 -10
  124. package/src/components/Backdrop/index.tsx +0 -1
  125. package/src/components/Checkbox/index.tsx +23 -9
  126. package/src/components/Checkbox/types.ts +5 -2
  127. package/src/components/DatePickerModal/index.tsx +27 -18
  128. package/src/components/DatePickerModal/types.ts +12 -9
  129. package/src/components/FileInput/types.ts +3 -4
  130. package/src/components/Grid/index.tsx +3 -3
  131. package/src/components/Image/types.ts +3 -6
  132. package/src/components/InputBase/index.tsx +13 -7
  133. package/src/components/InputBase/types.ts +2 -0
  134. package/src/components/InputBase/useInputBase.ts +60 -0
  135. package/src/components/InputBase/useInputBasePartialStyles.ts +38 -0
  136. package/src/components/InputBase/utils.ts +17 -17
  137. package/src/components/List/index.tsx +0 -1
  138. package/src/components/Modal/index.tsx +4 -15
  139. package/src/components/NumberIncrement/index.tsx +52 -160
  140. package/src/components/NumberIncrement/types.ts +7 -5
  141. package/src/components/NumberIncrement/useNumberIncrement.ts +152 -0
  142. package/src/components/RadioInput/index.tsx +37 -53
  143. package/src/components/RadioInput/types.ts +11 -9
  144. package/src/components/Scroll/index.tsx +44 -45
  145. package/src/components/Scroll/types.ts +4 -4
  146. package/src/components/Sections/index.tsx +0 -1
  147. package/src/components/SegmentedControl/index.tsx +8 -6
  148. package/src/components/SegmentedControl/types.ts +4 -3
  149. package/src/components/Select/index.tsx +32 -24
  150. package/src/components/Select/types.ts +19 -18
  151. package/src/components/Slider/index.tsx +34 -66
  152. package/src/components/Slider/types.ts +7 -5
  153. package/src/components/SortablePhotos/index.tsx +31 -47
  154. package/src/components/SortablePhotos/types.ts +6 -15
  155. package/src/components/SortablePhotos/useSortablePhotos.ts +28 -22
  156. package/src/components/Switch/index.tsx +23 -9
  157. package/src/components/Switch/types.ts +5 -2
  158. package/src/components/TextInput/index.tsx +55 -89
  159. package/src/components/TextInput/types.ts +9 -7
  160. package/src/components/TextInput/useTextInput.ts +88 -0
  161. package/src/components/Touchable/index.tsx +5 -1
  162. package/src/components/View/index.tsx +19 -12
  163. package/src/components/View/types.ts +7 -6
  164. package/src/components/components.ts +0 -2
  165. package/src/hooks/index.ts +3 -13
  166. package/src/hooks/useKeyboardController.ts +28 -0
  167. package/src/hooks/useStatusBar.ts +21 -0
  168. package/src/hooks/useStylesFor.ts +13 -0
  169. package/src/index.ts +3 -1
  170. package/src/modules/backgroundTimer.ts +39 -0
  171. package/src/modules/index.ts +3 -0
  172. package/src/modules/reactNavigation.ts +64 -14
  173. package/src/modules/scroll.tsx +89 -0
  174. package/src/modules/types/textInputMask.ts +8 -4
  175. package/src/types/index.ts +1 -0
  176. package/src/utils/KeyboardAware/context.tsx +2 -6
  177. package/src/utils/KeyboardAware/index.ts +1 -1
  178. package/src/utils/ModalManager/context.tsx +2 -2
  179. package/src/utils/hooks.ts +4 -4
  180. package/src/utils/locale.ts +13 -5
  181. package/src/utils/theme.ts +6 -2
  182. package/dist/components/Navigation/Navigation.d.ts +0 -55
  183. package/dist/components/Navigation/Navigation.js +0 -41
  184. package/dist/components/Navigation/Navigation.js.map +0 -1
  185. package/dist/components/Navigation/constants.d.ts +0 -9
  186. package/dist/components/Navigation/constants.js +0 -9
  187. package/dist/components/Navigation/constants.js.map +0 -1
  188. package/dist/components/Navigation/index.d.ts +0 -3
  189. package/dist/components/Navigation/index.js +0 -4
  190. package/dist/components/Navigation/index.js.map +0 -1
  191. package/dist/components/Navigation/types.d.ts +0 -26
  192. package/dist/components/Navigation/types.js +0 -2
  193. package/dist/components/Navigation/types.js.map +0 -1
  194. package/dist/components/Navigation/utils.d.ts +0 -3
  195. package/dist/components/Navigation/utils.js +0 -34
  196. package/dist/components/Navigation/utils.js.map +0 -1
  197. package/dist/components/NumberIncrement/utils.d.ts +0 -5
  198. package/dist/components/NumberIncrement/utils.js +0 -23
  199. package/dist/components/NumberIncrement/utils.js.map +0 -1
  200. package/dist/utils/KeyboardAware/types.d.ts +0 -1
  201. package/dist/utils/KeyboardAware/types.js +0 -6
  202. package/dist/utils/KeyboardAware/types.js.map +0 -1
  203. package/src/components/Navigation/Navigation.tsx +0 -55
  204. package/src/components/Navigation/constants.ts +0 -24
  205. package/src/components/Navigation/index.tsx +0 -3
  206. package/src/components/Navigation/types.ts +0 -28
  207. package/src/components/Navigation/utils.tsx +0 -57
  208. package/src/components/NumberIncrement/utils.ts +0 -27
  209. package/src/utils/KeyboardAware/types.ts +0 -159
@@ -0,0 +1,152 @@
1
+ import { useCallback, useMemo, useRef, useState } from 'react'
2
+ import { NativeSyntheticEvent, TextInputFocusEventData } from 'react-native/types'
3
+ import { useInputBase } from '../InputBase/useInputBase'
4
+ import { NumberIncrementProps } from './types'
5
+ import { TypeGuards } from '@codeleap/types'
6
+ import { Field, fields } from '@codeleap/form'
7
+
8
+ export const MAX_VALID_DIGITS = 1000000000000000 // maximum number of digits that the input supports to perform operations
9
+
10
+ export function useNumberIncrement(props: Partial<NumberIncrementProps>) {
11
+ const {
12
+ onFocus,
13
+ onBlur,
14
+ field,
15
+ actionPressAutoFocus,
16
+ timeoutActionFocus,
17
+ onChangeMask,
18
+ forceError,
19
+ editable,
20
+ step,
21
+ parseValue,
22
+ min,
23
+ max,
24
+ value,
25
+ onValueChange,
26
+ } = props
27
+
28
+ const [isFocused, setIsFocused] = useState(false)
29
+
30
+ const {
31
+ fieldHandle,
32
+ validation,
33
+ innerInputRef,
34
+ wrapperRef,
35
+ } = useInputBase(
36
+ field as Field<number, any, any>,
37
+ fields.number as () => Field<number, any, any>,
38
+ [value, onValueChange]
39
+ )
40
+
41
+ const actionTimeoutRef = useRef(null)
42
+
43
+ const clearActionTimeoutRef = useCallback(() => {
44
+ if (actionTimeoutRef.current !== null) {
45
+ clearTimeout(actionTimeoutRef.current)
46
+ actionTimeoutRef.current = null
47
+ }
48
+ }, [actionTimeoutRef.current])
49
+
50
+ const handleChange = useCallback((action: 'increment' | 'decrement') => {
51
+ if (actionPressAutoFocus) setIsFocused(true)
52
+ clearActionTimeoutRef()
53
+
54
+ if (action === 'increment' && !incrementDisabled) {
55
+ const newValue = Number(fieldHandle?.value) + step
56
+ fieldHandle.setValue(newValue)
57
+ } else if (action === 'decrement' && !decrementDisabled) {
58
+ const newValue = Number(fieldHandle?.value) - step
59
+ fieldHandle.setValue(newValue)
60
+ }
61
+
62
+ if (actionPressAutoFocus) {
63
+ actionTimeoutRef.current = setTimeout(() => {
64
+ setIsFocused(false)
65
+ }, timeoutActionFocus)
66
+ }
67
+ }, [fieldHandle?.value])
68
+
69
+ const checkValue = useCallback((newValue: number = null, withLimits = true) => {
70
+ const value = newValue ?? fieldHandle?.value
71
+
72
+ if (withLimits) {
73
+ if (TypeGuards.isNumber(max) && (Number(value) >= max)) {
74
+ return max
75
+ } else if (TypeGuards.isNumber(min) && (Number(value) <= min) || TypeGuards.isNil(value) || String(value)?.length <= 0) {
76
+ return min
77
+ }
78
+ }
79
+
80
+ if (!value) {
81
+ return min
82
+ }
83
+
84
+ if (value >= MAX_VALID_DIGITS) {
85
+ fieldHandle.setValue(MAX_VALID_DIGITS)
86
+ return MAX_VALID_DIGITS
87
+ }
88
+
89
+ return value
90
+ }, [])
91
+
92
+ const handleBlur = useCallback((e: NativeSyntheticEvent<TextInputFocusEventData>) => {
93
+ fieldHandle.setValue(checkValue())
94
+ validation.onInputBlurred()
95
+ setIsFocused(false)
96
+ onBlur?.(e)
97
+ }, [validation.onInputBlurred, onBlur])
98
+
99
+ const handleFocus = useCallback((e: NativeSyntheticEvent<TextInputFocusEventData>) => {
100
+ clearActionTimeoutRef()
101
+ if (editable) setIsFocused(true)
102
+ onFocus?.(e)
103
+ }, [onFocus])
104
+
105
+ const handleChangeInput = useCallback((text: string) => {
106
+ const value = checkValue(parseValue(text), false)
107
+
108
+ fieldHandle.setValue(value)
109
+
110
+ return value
111
+ }, [])
112
+
113
+ const handleMaskChange = useCallback((masked, unmasked) => {
114
+ handleChangeInput?.(masked)
115
+ if (onChangeMask) onChangeMask(masked, unmasked)
116
+ }, [onChangeMask])
117
+
118
+ const incrementDisabled = useMemo(() => {
119
+ const maxLimit = TypeGuards.isNumber(max) && (Number(fieldHandle?.value) >= max)
120
+ return maxLimit
121
+ }, [fieldHandle?.value])
122
+
123
+ const decrementDisabled = useMemo(() => {
124
+ const minLimit = TypeGuards.isNumber(min) && (Number(fieldHandle?.value) <= min)
125
+ return minLimit
126
+ }, [fieldHandle?.value])
127
+
128
+ const hasValue = TypeGuards.isString(fieldHandle?.value)
129
+ ? (fieldHandle?.value as string).length > 0
130
+ : !TypeGuards.isNil(fieldHandle?.value)
131
+
132
+ const hasError = validation.showError || forceError
133
+
134
+ return {
135
+ isFocused,
136
+ handleBlur,
137
+ handleFocus,
138
+ handleMaskChange,
139
+ handleChange,
140
+ handleChangeInput,
141
+ fieldHandle,
142
+ validation,
143
+ innerInputRef,
144
+ wrapperRef,
145
+ hasValue,
146
+ hasError,
147
+ incrementDisabled,
148
+ decrementDisabled,
149
+ min,
150
+ max,
151
+ }
152
+ }
@@ -8,6 +8,9 @@ import { RadioGroupProps, RadioOptionProps } from './types'
8
8
  import { AnyRecord, IJSX, StyledComponentProps } from '@codeleap/styles'
9
9
  import { MobileStyleRegistry } from '../../Registry'
10
10
  import { useStylesFor } from '../../hooks'
11
+ import { useInputBasePartialStyles } from '../InputBase/useInputBasePartialStyles'
12
+ import { useInputBase } from '../InputBase/useInputBase'
13
+ import { SelectableField, fields } from '@codeleap/form'
11
14
 
12
15
  export * from './styles'
13
16
  export * from './types'
@@ -26,34 +29,25 @@ const Option = <T extends string | number>(props: RadioOptionProps<T>) => {
26
29
 
27
30
  const isDisabled = disabled || item.disabled
28
31
 
29
- const getStyle = (key) => {
30
- if (isDisabled && selected) {
31
- return styles[`${key}:selectedDisabled`]
32
- }
33
- if (isDisabled) {
34
- return styles[`${key}:disabled`]
35
- }
36
- if (selected) {
37
- return styles[`${key}:selected`]
32
+ const partialStyles = useInputBasePartialStyles(
33
+ styles,
34
+ ['optionLabel', 'optionWrapper', 'optionIndicator', 'optionIndicatorInner'],
35
+ {
36
+ selectedDisabled: isDisabled && selected,
37
+ disabled: isDisabled,
38
+ selected,
38
39
  }
39
- return styles[key]
40
- }
40
+ )
41
41
 
42
42
  const label = TypeGuards.isString(item.label) ? <Text
43
- style={[
44
- styles.optionLabel,
45
- getStyle('optionLabel'),
46
- ]}
43
+ style={partialStyles.optionLabel}
47
44
  text={item.label}
48
45
  /> : item.label
49
46
 
50
47
  return <>
51
48
  <Touchable
52
49
  debugName={`${debugName} option ${item.value}`}
53
- style={[
54
- styles.optionWrapper,
55
- getStyle('optionWrapper'),
56
- ]}
50
+ style={partialStyles.optionWrapper}
57
51
  rippleDisabled
58
52
  onPress={onSelect}
59
53
  disabled={isDisabled}
@@ -61,40 +55,20 @@ const Option = <T extends string | number>(props: RadioOptionProps<T>) => {
61
55
  {reverseOrder ? (
62
56
  <>
63
57
  {label}
64
- <View
65
- style={[
66
- styles.optionIndicator,
67
- getStyle('optionIndicator'),
68
- ]}
69
- >
70
- <View
71
- style={[
72
- styles.optionIndicatorInner,
73
- getStyle('optionIndicatorInner'),
74
- ]}
75
- />
58
+ <View style={partialStyles.optionIndicator}>
59
+ <View style={partialStyles.optionIndicatorInner} />
76
60
  </View>
77
61
  </>
78
62
  ) : (
79
63
  <>
80
- <View
81
- style={[
82
- styles.optionIndicator,
83
- getStyle('optionIndicator'),
84
- ]}
85
- >
86
- <View
87
- style={[
88
- styles.optionIndicatorInner,
89
- getStyle('optionIndicatorInner'),
90
- ]}
91
- />
64
+ <View style={partialStyles.optionIndicator}>
65
+ <View style={partialStyles.optionIndicatorInner} />
92
66
  </View>
93
67
  {label}
94
68
  </>
95
69
  )}
96
-
97
70
  </Touchable>
71
+
98
72
  {separator ? <View style={styles.optionSeparator} /> : null}
99
73
  </>
100
74
  }
@@ -109,24 +83,35 @@ export const RadioGroup = <T extends string | number>(props: RadioGroupProps<T>)
109
83
  })
110
84
 
111
85
  const {
112
- options,
113
- value,
114
- onValueChange,
115
86
  disabled,
116
87
  debugName,
117
88
  radioOnRight,
118
89
  style,
90
+ field,
91
+ options,
92
+ value,
93
+ onValueChange,
119
94
  } = others
120
95
 
121
96
  const styles = useStylesFor(RadioGroup.styleRegistryName, style)
122
97
 
98
+ const {
99
+ fieldHandle,
100
+ wrapperRef,
101
+ } = useInputBase(
102
+ field as SelectableField<T, any>,
103
+ fields.selectable as () => SelectableField<T, any>,
104
+ [value, onValueChange]
105
+ )
106
+
123
107
  // @ts-expect-error icss type
124
108
  const _radioOnRight = radioOnRight ?? styles?.__props?.radioOnRight
125
109
 
126
- const hasValue = !TypeGuards.isNil(value)
110
+ const hasValue = !TypeGuards.isNil(fieldHandle?.value)
127
111
 
128
112
  return <InputBase
129
113
  {...inputBaseProps}
114
+ ref={wrapperRef}
130
115
  disabled={disabled}
131
116
  style={styles}
132
117
  debugName={debugName}
@@ -139,11 +124,10 @@ export const RadioGroup = <T extends string | number>(props: RadioGroupProps<T>)
139
124
  key={idx}
140
125
  disabled={disabled}
141
126
  styles={styles}
142
- selected={value === item.value}
143
- onSelect={() => onValueChange(item.value)}
144
- separator={idx < options.length - 1}
127
+ selected={fieldHandle?.value === item.value}
128
+ onSelect={() => fieldHandle.setValue(item.value)}
129
+ separator={idx < options?.length - 1}
145
130
  reverseOrder={_radioOnRight}
146
-
147
131
  />
148
132
  ))}
149
133
  </InputBase>
@@ -157,6 +141,6 @@ RadioGroup.withVariantTypes = <S extends AnyRecord>(styles: S) => {
157
141
  return RadioGroup as (<T extends string | number>(props: StyledComponentProps<RadioGroupProps<T>, typeof styles>) => IJSX)
158
142
  }
159
143
 
160
- RadioGroup.defaultProps = {} as Partial<RadioGroupProps<string | number>>
144
+ RadioGroup.defaultProps = {} as Partial<RadioGroupProps<string>>
161
145
 
162
146
  MobileStyleRegistry.registerComponent(RadioGroup)
@@ -1,23 +1,25 @@
1
- import { StylesOf } from '@codeleap/types'
2
- import { FormTypes } from '@codeleap/form'
3
1
  import { StyledProp } from '@codeleap/styles'
4
- import { ReactNode } from 'react'
5
2
  import { RadioInputComposition } from './styles'
6
3
  import { InputBaseProps } from '../InputBase'
4
+ import { ViewStyle } from 'react-native'
5
+ import { SelectableField } from '@codeleap/form'
6
+ import { Options } from '@codeleap/types'
7
7
 
8
- type RadioOption<T> = FormTypes.Options<T>[number] & {
8
+ type RadioOption<T extends string | number> = {
9
+ value: T
10
+ label: string
9
11
  disabled?: boolean
10
12
  }
11
13
 
12
14
  export type RadioGroupProps<T extends string | number> =
13
15
  Omit<InputBaseProps, 'style'> &
14
16
  {
15
- options: RadioOption<T>[]
16
- value: T
17
- onValueChange(value: T): void
18
- label: ReactNode
19
17
  radioOnRight?: boolean
20
18
  style?: StyledProp<RadioInputComposition>
19
+ field?: SelectableField<T, any>
20
+ options?: Options<T>
21
+ value?: T
22
+ onValueChange?: (value: T) => void
21
23
  }
22
24
 
23
25
  export type RadioOptionProps<T extends string | number> = {
@@ -28,5 +30,5 @@ export type RadioOptionProps<T extends string | number> = {
28
30
  disabled?: boolean
29
31
  separator?: boolean
30
32
  reverseOrder?: boolean
31
- styles?: StylesOf<RadioInputComposition>
33
+ styles?: Record<RadioInputComposition, ViewStyle>
32
34
  }
@@ -1,13 +1,12 @@
1
- import React, { forwardRef, useState } from 'react'
2
- import { onUpdate, usePrevious } from '@codeleap/hooks'
3
- import { deepEqual } from '@codeleap/utils'
1
+ import React, { forwardRef, useCallback, useImperativeHandle, useRef, useState } from 'react'
4
2
  import { ScrollView } from 'react-native'
5
3
  import { RefreshControl } from '../RefreshControl'
6
- import { useKeyboardPaddingStyle } from '../../utils'
7
4
  import { ScrollProps, ScrollRef } from './types'
8
5
  import { AnyRecord, IJSX, StyledComponentProps, StyledComponentWithProps } from '@codeleap/styles'
9
6
  import { MobileStyleRegistry } from '../../Registry'
10
7
  import { useStylesFor } from '../../hooks'
8
+ import { KeyboardAwareScrollView } from 'react-native-keyboard-controller'
9
+ import { ScrollProvider, useScrollPubSub } from '../../modules/scroll'
11
10
 
12
11
  export * from './styles'
13
12
  export * from './types'
@@ -17,73 +16,74 @@ export const Scroll = forwardRef<ScrollRef, ScrollProps>((scrollProps, ref) => {
17
16
  style,
18
17
  refreshTimeout,
19
18
  children,
20
- changeData,
21
19
  refreshControlProps = {},
22
20
  contentContainerStyle,
23
21
  keyboardAware,
24
- animated,
22
+ onRefresh: onRefresh,
25
23
  ...props
26
24
  } = {
27
25
  ...Scroll.defaultProps,
28
26
  ...scrollProps,
29
27
  }
30
28
 
31
- const hasRefresh = !!props.onRefresh
32
- const [refreshingState, setRefreshing] = useState(false)
33
- const refreshingDisplay = props.refreshing !== undefined ? props.refreshing : refreshingState
29
+ const hasRefresh = !!onRefresh
30
+ const [refreshing, setRefreshing] = useState(false)
31
+ const refreshingDisplay = props.refreshing !== undefined ? props.refreshing : refreshing
34
32
 
35
33
  const timer = React.useRef(null)
36
- const previousData = usePrevious(changeData)
37
34
 
38
- const onRefresh = () => {
39
- if (timer.current) {
35
+ const refresh = useCallback(() => {
36
+ if (timer.current !== null) {
40
37
  clearTimeout(timer.current)
38
+ timer.current = null
41
39
  }
42
40
 
43
41
  setRefreshing(true)
44
42
 
45
- props.onRefresh()
43
+ onRefresh?.()
46
44
 
47
45
  timer.current = setTimeout(() => {
48
46
  setRefreshing(false)
49
47
  }, refreshTimeout)
50
- }
51
-
52
- onUpdate(() => {
53
- if (refreshingDisplay && !deepEqual(previousData, changeData)) {
54
- setRefreshing(false)
55
- if (timer.current) {
56
- clearTimeout(timer.current)
57
- }
58
- }
59
- }, [refreshingDisplay, changeData])
48
+ }, [onRefresh])
60
49
 
61
50
  const styles = useStylesFor(Scroll.styleRegistryName, style)
62
51
 
63
- const Component = ScrollView
52
+ const Component = keyboardAware ? KeyboardAwareScrollView : ScrollView
53
+
54
+ const _scrollRef = useRef<ScrollView>()
55
+
56
+ const { ref: scrollRef, emit } = useScrollPubSub(_scrollRef)
64
57
 
65
- const keyboardStyle = useKeyboardPaddingStyle([styles?.content, contentContainerStyle], keyboardAware)
58
+ useImperativeHandle(ref, () => scrollRef.current as unknown as ScrollView, [])
66
59
 
67
60
  return (
68
- <Component
69
- showsVerticalScrollIndicator={false}
70
- // @ts-ignore
71
- ref={ref}
72
- refreshControl={
73
- hasRefresh && (
74
- <RefreshControl
75
- refreshing={refreshingDisplay}
76
- onRefresh={onRefresh}
77
- {...refreshControlProps}
78
- />
79
- )
80
- }
81
- {...props}
82
- style={styles?.wrapper}
83
- contentContainerStyle={keyboardStyle}
84
- >
85
- {children}
86
- </Component>
61
+ <ScrollProvider ref={scrollRef}>
62
+ <Component
63
+ showsVerticalScrollIndicator={false}
64
+ // @ts-ignore
65
+ ref={_scrollRef}
66
+ refreshControl={
67
+ hasRefresh && (
68
+ <RefreshControl
69
+ refreshing={refreshingDisplay}
70
+ onRefresh={refresh}
71
+ {...refreshControlProps}
72
+ />
73
+ )
74
+ }
75
+ bottomOffset={30}
76
+ {...props}
77
+ style={styles?.wrapper}
78
+ contentContainerStyle={[styles?.content, contentContainerStyle]}
79
+ onMomentumScrollEnd={(e) => {
80
+ emit('onMomentumScrollEnd', e)
81
+ props?.onMomentumScrollEnd?.(e)
82
+ }}
83
+ >
84
+ {children}
85
+ </Component>
86
+ </ScrollProvider>
87
87
  )
88
88
  }) as StyledComponentWithProps<ScrollProps>
89
89
 
@@ -99,7 +99,6 @@ Scroll.defaultProps = {
99
99
  keyboardShouldPersistTaps: 'handled',
100
100
  refreshTimeout: 3000,
101
101
  keyboardAware: true,
102
- animated: true,
103
102
  } as Partial<ScrollProps>
104
103
 
105
104
  MobileStyleRegistry.registerComponent(Scroll)
@@ -1,12 +1,12 @@
1
1
  import { StyledProp } from '@codeleap/styles'
2
- import { KeyboardAwareScrollView, KeyboardAwareScrollViewProps } from 'react-native-keyboard-aware-scroll-view'
3
2
  import { ScrollComposition } from './styles'
4
3
  import { RefreshControlProps } from '../RefreshControl'
5
- import { ViewProps } from '../View'
4
+ import { ScrollView, ScrollViewProps } from 'react-native'
5
+ import { KeyboardAwareScrollViewProps } from 'react-native-keyboard-controller'
6
6
 
7
7
  export type ScrollProps =
8
+ Omit<ScrollViewProps, 'style'> &
8
9
  Omit<KeyboardAwareScrollViewProps, 'style'> &
9
- Omit<ViewProps, 'style'> &
10
10
  {
11
11
  onRefresh?: () => void
12
12
  refreshTimeout?: number
@@ -18,4 +18,4 @@ export type ScrollProps =
18
18
  style?: StyledProp<ScrollComposition>
19
19
  }
20
20
 
21
- export type ScrollRef = KeyboardAwareScrollView
21
+ export type ScrollRef = ScrollView
@@ -22,7 +22,6 @@ export function Sections<T>(sectionsProps: SectionProps<T>) {
22
22
  const {
23
23
  style,
24
24
  onRefresh,
25
- component,
26
25
  refreshing,
27
26
  placeholder,
28
27
  refreshControlProps,
@@ -35,9 +35,9 @@ export const SegmentedControl = React.forwardRef<SegmentedControlRef, SegmentedC
35
35
  animation = {},
36
36
  scrollProps = {},
37
37
  getItemWidth = () => (themeValues?.width - themeSpacing?.value?.(4)) / options.length,
38
- renderBubble,
38
+ renderBubble: BubbleView,
39
39
  scrollToCurrentOptionOnMount,
40
- renderOption,
40
+ renderOption: Option,
41
41
  touchableProps,
42
42
  style,
43
43
  ...viewProps
@@ -60,7 +60,12 @@ export const SegmentedControl = React.forwardRef<SegmentedControlRef, SegmentedC
60
60
  function scrollTo(idx: number) {
61
61
  if (!scrollRef.current) return
62
62
  setTimeout(() => {
63
- scrollRef.current?.scrollToPosition?.(widthStyle.width * idx, 0, true)
63
+ scrollRef.current?.scrollTo({
64
+ x: widthStyle.width * idx,
65
+ y: 0,
66
+ animated: true
67
+ })
68
+
64
69
  })
65
70
  }
66
71
 
@@ -109,9 +114,6 @@ export const SegmentedControl = React.forwardRef<SegmentedControlRef, SegmentedC
109
114
  hasScrolledInitially.current = true
110
115
  }
111
116
 
112
- const BubbleView = renderBubble
113
- const Option = renderOption
114
-
115
117
  const bubbleAnimation = useAnimatedVariantStyles({
116
118
  variantStyles: styles,
117
119
  animatedProperties: [],
@@ -3,9 +3,8 @@ import { SegmentedControlOptionProps } from './Option'
3
3
  import { TransitionConfig } from '../../utils'
4
4
  import { TextProps } from '../Text'
5
5
  import { TouchableProps } from '../Touchable'
6
- import { FormTypes } from '@codeleap/form'
7
6
  import { StyledProp } from '@codeleap/styles'
8
- import { SegmentedControlComposition } from '../components'
7
+ import { SegmentedControlComposition, ViewProps } from '../components'
9
8
 
10
9
  export type SegmentedControlRef = ScrollRef & {
11
10
  scrollTo: (index: number) => void
@@ -20,9 +19,11 @@ export type SegmentedControlProps<T = string> =
20
19
  value: T
21
20
  debugName: string
22
21
  animation?: TransitionConfig
22
+ animated?: boolean
23
+ animatedStyle?: ViewProps['animatedStyle']
23
24
  textProps?: Partial<TextProps>
24
25
  touchableProps?: Partial<TouchableProps>
25
- label?: FormTypes.Label
26
+ label?: string
26
27
  renderOption?: (props: SegmentedControlOptionProps) => JSX.Element
27
28
  renderBubble?: (props: Partial<SegmentedControlProps>) => JSX.Element
28
29
  getItemWidth?: (item: { label: string; value: T }, idx: number, arr: { label: string; value: T }[]) => number