@codeleap/mobile 4.3.9 → 5.0.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.
- package/dist/components/Autocomplete/index.js.map +1 -1
- package/dist/components/Autocomplete/types.d.ts +9 -10
- package/dist/components/Backdrop/index.js.map +1 -1
- package/dist/components/Checkbox/index.js +13 -9
- package/dist/components/Checkbox/index.js.map +1 -1
- package/dist/components/Checkbox/types.d.ts +5 -2
- package/dist/components/DatePickerModal/index.js +18 -11
- package/dist/components/DatePickerModal/index.js.map +1 -1
- package/dist/components/DatePickerModal/types.d.ts +12 -9
- package/dist/components/FileInput/types.d.ts +3 -4
- package/dist/components/Grid/index.js.map +1 -1
- package/dist/components/Image/types.d.ts +2 -5
- package/dist/components/InputBase/index.d.ts +2 -6
- package/dist/components/InputBase/index.js +9 -5
- package/dist/components/InputBase/index.js.map +1 -1
- package/dist/components/InputBase/types.d.ts +2 -0
- package/dist/components/InputBase/useInputBase.d.ts +24 -0
- package/dist/components/InputBase/useInputBase.js +46 -0
- package/dist/components/InputBase/useInputBase.js.map +1 -0
- package/dist/components/InputBase/useInputBasePartialStyles.d.ts +2 -0
- package/dist/components/InputBase/useInputBasePartialStyles.js +30 -0
- package/dist/components/InputBase/useInputBasePartialStyles.js.map +1 -0
- package/dist/components/InputBase/utils.js +16 -16
- package/dist/components/InputBase/utils.js.map +1 -1
- package/dist/components/List/index.js +1 -1
- package/dist/components/List/index.js.map +1 -1
- package/dist/components/Modal/index.js +4 -14
- package/dist/components/Modal/index.js.map +1 -1
- package/dist/components/NumberIncrement/index.js +21 -132
- package/dist/components/NumberIncrement/index.js.map +1 -1
- package/dist/components/NumberIncrement/types.d.ts +7 -5
- package/dist/components/NumberIncrement/useNumberIncrement.d.ts +55 -0
- package/dist/components/NumberIncrement/useNumberIncrement.js +107 -0
- package/dist/components/NumberIncrement/useNumberIncrement.js.map +1 -0
- package/dist/components/RadioInput/index.d.ts +1 -1
- package/dist/components/RadioInput/index.js +20 -41
- package/dist/components/RadioInput/index.js.map +1 -1
- package/dist/components/RadioInput/types.d.ts +11 -9
- package/dist/components/Scroll/index.js +25 -28
- package/dist/components/Scroll/index.js.map +1 -1
- package/dist/components/Scroll/types.d.ts +4 -4
- package/dist/components/Sections/index.js +1 -1
- package/dist/components/Sections/index.js.map +1 -1
- package/dist/components/SegmentedControl/index.js +6 -4
- package/dist/components/SegmentedControl/index.js.map +1 -1
- package/dist/components/SegmentedControl/types.d.ts +4 -3
- package/dist/components/Select/index.js +10 -6
- package/dist/components/Select/index.js.map +1 -1
- package/dist/components/Select/types.d.ts +19 -18
- package/dist/components/Slider/index.js +18 -57
- package/dist/components/Slider/index.js.map +1 -1
- package/dist/components/Slider/types.d.ts +7 -5
- package/dist/components/SortablePhotos/index.js +17 -18
- package/dist/components/SortablePhotos/index.js.map +1 -1
- package/dist/components/SortablePhotos/types.d.ts +5 -15
- package/dist/components/SortablePhotos/useSortablePhotos.d.ts +11 -8
- package/dist/components/SortablePhotos/useSortablePhotos.js +18 -11
- package/dist/components/SortablePhotos/useSortablePhotos.js.map +1 -1
- package/dist/components/Switch/index.js +13 -9
- package/dist/components/Switch/index.js.map +1 -1
- package/dist/components/Switch/types.d.ts +5 -2
- package/dist/components/TextInput/index.js +26 -70
- package/dist/components/TextInput/index.js.map +1 -1
- package/dist/components/TextInput/types.d.ts +8 -6
- package/dist/components/TextInput/useTextInput.d.ts +54 -0
- package/dist/components/TextInput/useTextInput.js +59 -0
- package/dist/components/TextInput/useTextInput.js.map +1 -0
- package/dist/components/Touchable/index.js +4 -3
- package/dist/components/Touchable/index.js.map +1 -1
- package/dist/components/View/index.d.ts +7 -12
- package/dist/components/View/index.js +9 -7
- package/dist/components/View/index.js.map +1 -1
- package/dist/components/View/types.d.ts +6 -6
- package/dist/components/components.d.ts +0 -2
- package/dist/components/components.js +0 -2
- package/dist/components/components.js.map +1 -1
- package/dist/hooks/index.d.ts +3 -2
- package/dist/hooks/index.js +3 -10
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/useKeyboardController.d.ts +6 -0
- package/dist/hooks/useKeyboardController.js +19 -0
- package/dist/hooks/useKeyboardController.js.map +1 -0
- package/dist/hooks/useStatusBar.d.ts +6 -0
- package/dist/hooks/useStatusBar.js +15 -0
- package/dist/hooks/useStatusBar.js.map +1 -0
- package/dist/hooks/useStylesFor.d.ts +2 -0
- package/dist/hooks/useStylesFor.js +11 -0
- package/dist/hooks/useStylesFor.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/modules/backgroundTimer.d.ts +3 -0
- package/dist/modules/backgroundTimer.js +31 -0
- package/dist/modules/backgroundTimer.js.map +1 -0
- package/dist/modules/index.d.ts +3 -0
- package/dist/modules/index.js +3 -0
- package/dist/modules/index.js.map +1 -0
- package/dist/modules/reactNavigation.d.ts +8 -21
- package/dist/modules/reactNavigation.js +38 -12
- package/dist/modules/reactNavigation.js.map +1 -1
- package/dist/modules/scroll.d.ts +18 -0
- package/dist/modules/scroll.js +57 -0
- package/dist/modules/scroll.js.map +1 -0
- package/dist/modules/types/textInputMask.d.ts +6 -2
- package/dist/utils/KeyboardAware/context.js +2 -6
- package/dist/utils/KeyboardAware/context.js.map +1 -1
- package/dist/utils/KeyboardAware/index.d.ts +0 -1
- package/dist/utils/KeyboardAware/index.js +0 -1
- package/dist/utils/KeyboardAware/index.js.map +1 -1
- package/dist/utils/ModalManager/context.js +2 -2
- package/dist/utils/ModalManager/context.js.map +1 -1
- package/dist/utils/hooks.js +4 -4
- package/dist/utils/hooks.js.map +1 -1
- package/dist/utils/locale.d.ts +1 -1
- package/dist/utils/locale.js +10 -5
- package/dist/utils/locale.js.map +1 -1
- package/dist/utils/theme.d.ts +1 -0
- package/dist/utils/theme.js +4 -2
- package/dist/utils/theme.js.map +1 -1
- package/package.json +32 -36
- package/package.json.bak +16 -20
- package/src/components/Autocomplete/index.tsx +2 -3
- package/src/components/Autocomplete/types.ts +9 -10
- package/src/components/Backdrop/index.tsx +0 -1
- package/src/components/Checkbox/index.tsx +23 -9
- package/src/components/Checkbox/types.ts +5 -2
- package/src/components/DatePickerModal/index.tsx +27 -18
- package/src/components/DatePickerModal/types.ts +12 -9
- package/src/components/FileInput/types.ts +3 -4
- package/src/components/Grid/index.tsx +3 -3
- package/src/components/Image/types.ts +3 -6
- package/src/components/InputBase/index.tsx +13 -7
- package/src/components/InputBase/types.ts +2 -0
- package/src/components/InputBase/useInputBase.ts +60 -0
- package/src/components/InputBase/useInputBasePartialStyles.ts +38 -0
- package/src/components/InputBase/utils.ts +17 -17
- package/src/components/List/index.tsx +0 -1
- package/src/components/Modal/index.tsx +4 -15
- package/src/components/NumberIncrement/index.tsx +52 -160
- package/src/components/NumberIncrement/types.ts +7 -5
- package/src/components/NumberIncrement/useNumberIncrement.ts +152 -0
- package/src/components/RadioInput/index.tsx +37 -53
- package/src/components/RadioInput/types.ts +11 -9
- package/src/components/Scroll/index.tsx +44 -45
- package/src/components/Scroll/types.ts +4 -4
- package/src/components/Sections/index.tsx +0 -1
- package/src/components/SegmentedControl/index.tsx +8 -6
- package/src/components/SegmentedControl/types.ts +4 -3
- package/src/components/Select/index.tsx +32 -24
- package/src/components/Select/types.ts +19 -18
- package/src/components/Slider/index.tsx +34 -66
- package/src/components/Slider/types.ts +7 -5
- package/src/components/SortablePhotos/index.tsx +31 -47
- package/src/components/SortablePhotos/types.ts +6 -15
- package/src/components/SortablePhotos/useSortablePhotos.ts +28 -22
- package/src/components/Switch/index.tsx +23 -9
- package/src/components/Switch/types.ts +5 -2
- package/src/components/TextInput/index.tsx +55 -89
- package/src/components/TextInput/types.ts +9 -7
- package/src/components/TextInput/useTextInput.ts +88 -0
- package/src/components/Touchable/index.tsx +5 -1
- package/src/components/View/index.tsx +19 -12
- package/src/components/View/types.ts +7 -6
- package/src/components/components.ts +0 -2
- package/src/hooks/index.ts +3 -13
- package/src/hooks/useKeyboardController.ts +28 -0
- package/src/hooks/useStatusBar.ts +21 -0
- package/src/hooks/useStylesFor.ts +13 -0
- package/src/index.ts +3 -1
- package/src/modules/backgroundTimer.ts +39 -0
- package/src/modules/index.ts +3 -0
- package/src/modules/reactNavigation.ts +64 -14
- package/src/modules/scroll.tsx +89 -0
- package/src/modules/types/textInputMask.ts +8 -4
- package/src/types/index.ts +1 -0
- package/src/utils/KeyboardAware/context.tsx +2 -6
- package/src/utils/KeyboardAware/index.ts +1 -1
- package/src/utils/ModalManager/context.tsx +2 -2
- package/src/utils/hooks.ts +4 -4
- package/src/utils/locale.ts +13 -5
- package/src/utils/theme.ts +6 -2
- package/dist/components/Navigation/Navigation.d.ts +0 -55
- package/dist/components/Navigation/Navigation.js +0 -41
- package/dist/components/Navigation/Navigation.js.map +0 -1
- package/dist/components/Navigation/constants.d.ts +0 -9
- package/dist/components/Navigation/constants.js +0 -9
- package/dist/components/Navigation/constants.js.map +0 -1
- package/dist/components/Navigation/index.d.ts +0 -3
- package/dist/components/Navigation/index.js +0 -4
- package/dist/components/Navigation/index.js.map +0 -1
- package/dist/components/Navigation/types.d.ts +0 -26
- package/dist/components/Navigation/types.js +0 -2
- package/dist/components/Navigation/types.js.map +0 -1
- package/dist/components/Navigation/utils.d.ts +0 -3
- package/dist/components/Navigation/utils.js +0 -34
- package/dist/components/Navigation/utils.js.map +0 -1
- package/dist/components/NumberIncrement/utils.d.ts +0 -5
- package/dist/components/NumberIncrement/utils.js +0 -23
- package/dist/components/NumberIncrement/utils.js.map +0 -1
- package/dist/utils/KeyboardAware/types.d.ts +0 -1
- package/dist/utils/KeyboardAware/types.js +0 -6
- package/dist/utils/KeyboardAware/types.js.map +0 -1
- package/src/components/Navigation/Navigation.tsx +0 -55
- package/src/components/Navigation/constants.ts +0 -24
- package/src/components/Navigation/index.tsx +0 -3
- package/src/components/Navigation/types.ts +0 -28
- package/src/components/Navigation/utils.tsx +0 -57
- package/src/components/NumberIncrement/utils.ts +0 -27
- 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
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|
-
|
|
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={() =>
|
|
144
|
-
separator={idx < options
|
|
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
|
|
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
|
|
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?:
|
|
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
|
-
|
|
22
|
+
onRefresh: onRefresh,
|
|
25
23
|
...props
|
|
26
24
|
} = {
|
|
27
25
|
...Scroll.defaultProps,
|
|
28
26
|
...scrollProps,
|
|
29
27
|
}
|
|
30
28
|
|
|
31
|
-
const hasRefresh = !!
|
|
32
|
-
const [
|
|
33
|
-
const refreshingDisplay = props.refreshing !== undefined ? props.refreshing :
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
58
|
+
useImperativeHandle(ref, () => scrollRef.current as unknown as ScrollView, [])
|
|
66
59
|
|
|
67
60
|
return (
|
|
68
|
-
<
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
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 {
|
|
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 =
|
|
21
|
+
export type ScrollRef = ScrollView
|
|
@@ -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?.
|
|
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?:
|
|
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
|