@codeleap/mobile 4.3.8 → 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 +22 -57
  51. package/dist/components/Slider/index.js.map +1 -1
  52. package/dist/components/Slider/types.d.ts +8 -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 +32 -36
  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 +35 -64
  152. package/src/components/Slider/types.ts +8 -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
@@ -1,6 +1,5 @@
1
1
  /* eslint-disable max-lines */
2
- import { TypeGuards } from '@codeleap/types'
3
- import { FormTypes } from '@codeleap/form'
2
+ import { Option, Options, TypeGuards } from '@codeleap/types'
4
3
  import {
5
4
  onMount,
6
5
  onUpdate,
@@ -19,11 +18,13 @@ import Modal from '../Modal'
19
18
  import { MobileStyleRegistry } from '../../Registry'
20
19
  import { SearchInput } from '../SearchInput'
21
20
  import { useStylesFor } from '../../hooks'
21
+ import { SelectableField, fields } from '@codeleap/form'
22
+ import { useInputBase } from '../InputBase/useInputBase'
22
23
 
23
24
  export * from './styles'
24
25
  export * from './types'
25
26
 
26
- const defaultFilterFunction = (search: string, options: FormTypes.Options<any>) => {
27
+ const defaultFilterFunction = (search: string, options: Options<any>) => {
27
28
  return options.filter((option) => {
28
29
  if (TypeGuards.isString(option.label)) {
29
30
  return option.label.toLowerCase().includes(search.toLowerCase())
@@ -38,7 +39,7 @@ const defaultGetLabel = (option) => {
38
39
  if (option?.length === 0) return null
39
40
 
40
41
  const labels = option?.map(option => option?.label)?.filter(value => !!value)
41
-
42
+
42
43
  return labels?.join(', ')
43
44
  } else {
44
45
  if (!option) return null
@@ -82,8 +83,6 @@ export const Select = <T extends string | number = string, Multi extends boolean
82
83
  }
83
84
 
84
85
  const {
85
- value,
86
- onValueChange,
87
86
  label,
88
87
  options = [],
89
88
  style,
@@ -117,9 +116,16 @@ export const Select = <T extends string | number = string, Multi extends boolean
117
116
  searchInputProps,
118
117
  outerInputComponent,
119
118
  disabled,
119
+ field,
120
+ value: _value,
121
+ onValueChange: _onValueChange,
120
122
  ...modalProps
121
123
  } = allProps
122
124
 
125
+ const { fieldHandle } = useInputBase(field, fields.selectable as () => SelectableField<T, any>, [_value, _onValueChange])
126
+
127
+ const value = fieldHandle.value
128
+
123
129
  const isValueArray = TypeGuards.isArray(value) && multiple
124
130
 
125
131
  const {
@@ -144,7 +150,7 @@ export const Select = <T extends string | number = string, Multi extends boolean
144
150
  const [visible, toggle] = useConditionalState(_visible, _toggle, { initialValue: false, isBooleanToggle: true })
145
151
 
146
152
  const currentValueLabel = useMemo(() => {
147
- const _options = (multiple ? labelOptions : labelOptions?.[0]) as Multi extends true ? FormTypes.Options<T> : FormTypes.Options<T>[number]
153
+ const _options = (multiple ? labelOptions : labelOptions?.[0]) as Multi extends true ? Options<T> : Option<T>
148
154
 
149
155
  const label = getLabel(_options)
150
156
 
@@ -197,7 +203,7 @@ export const Select = <T extends string | number = string, Multi extends boolean
197
203
  newOption = currentOptions.find(o => o.value === selectedValue)
198
204
  }
199
205
 
200
- onValueChange(newValue)
206
+ fieldHandle.setValue(newValue)
201
207
 
202
208
  if (isValueArray) {
203
209
  if (removedIndex !== null) {
@@ -226,20 +232,22 @@ export const Select = <T extends string | number = string, Multi extends boolean
226
232
  selected = value === item.value
227
233
  }
228
234
 
229
- return <Item
230
- debugName={`${debugName} item ${item.value}`}
231
- selected={selected}
232
- text={item.label}
233
- item={item}
234
- onPress={() => select(item.value)}
235
- // @ts-ignore
236
- icon={selectedIcon}
237
- // @ts-ignore
238
- rightIcon={selectedIcon}
239
- style={compositionStyles?.item}
240
- index={index}
241
- {...itemProps}
242
- />
235
+ return (
236
+ <Item
237
+ debugName={`${debugName} item ${item.value}`}
238
+ selected={selected}
239
+ text={item.label}
240
+ item={item}
241
+ onPress={() => select(item.value)}
242
+ // @ts-ignore
243
+ icon={selectedIcon}
244
+ // @ts-ignore
245
+ rightIcon={selectedIcon}
246
+ style={compositionStyles?.item}
247
+ index={index}
248
+ {...itemProps}
249
+ />
250
+ )
243
251
  }, [value, select, multiple])
244
252
 
245
253
  const isEmpty = TypeGuards.isNil(value)
@@ -249,7 +257,7 @@ export const Select = <T extends string | number = string, Multi extends boolean
249
257
 
250
258
  const onPressInputIcon = () => {
251
259
  if (showClearIcon) {
252
- onValueChange(null)
260
+ fieldHandle.setValue(null)
253
261
  } else {
254
262
  close?.()
255
263
  }
@@ -314,7 +322,7 @@ export const Select = <T extends string | number = string, Multi extends boolean
314
322
  >
315
323
  <ListComponent
316
324
  data={searchable ? filteredOptions : options}
317
- scrollEnabled={false}
325
+ scrollEnabled={true}
318
326
  showsHorizontalScrollIndicator={false}
319
327
  style={compositionStyles?.list}
320
328
  keyExtractor={(i: { value: any }) => i.value}
@@ -1,5 +1,4 @@
1
- import { PropsOf } from '@codeleap/types'
2
- import { FormTypes } from '@codeleap/form'
1
+ import { Option, Options, PropsOf } from '@codeleap/types'
3
2
  import { AppIcon, StyledProp } from '@codeleap/styles'
4
3
  import { StylesOf } from '../../types/utility'
5
4
  import { GetKeyboardAwarePropsOptions } from '../../utils'
@@ -12,12 +11,13 @@ import { TextInputComposition } from '../TextInput'
12
11
  import { SearchInputProps } from '../SearchInput'
13
12
  import { Touchable } from '../Touchable'
14
13
  import { SelectComposition } from './styles'
14
+ import { SelectableField } from '@codeleap/form'
15
15
 
16
16
  export type SelectRenderFNProps<T> = {
17
17
  style: StylesOf<SelectComposition>
18
18
  onPress: () => void
19
19
  selected?: boolean
20
- item: FormTypes.Options<T>[number]
20
+ item: Option<T>
21
21
  touchableProps?: Partial<PropsOf<typeof Touchable>>
22
22
  textProps?: Partial<PropsOf<typeof Text>>
23
23
  iconProps?: Partial<PropsOf<typeof Icon>>
@@ -36,44 +36,42 @@ type SelectHeaderProps = {
36
36
  searchComponent?: React.ReactNode
37
37
  }
38
38
 
39
- export type SelectOuterInputProps<T = any, Multi extends boolean = false> = SelectProps<T, Multi> & {
40
- currentValueLabel: FormTypes.Label
39
+ export type SelectOuterInputProps<T extends string | number = any, Multi extends boolean = false> = SelectProps<T, Multi> & {
40
+ currentValueLabel: string
41
41
  styles?: StylesOf<TextInputComposition>
42
42
  clearIcon?: Partial<ActionIconProps>
43
43
  }
44
44
 
45
- type OuterInputComponent<T, Multi extends boolean> = (props: SelectOuterInputProps<T, Multi>) => JSX.Element
45
+ type OuterInputComponent<T extends string | number, Multi extends boolean> = (props: SelectOuterInputProps<T, Multi>) => JSX.Element
46
46
 
47
47
  export type ValueBoundSelectProps<
48
- T,
48
+ T extends string | number,
49
49
  Multi extends boolean = false
50
50
  > = {
51
- options?: FormTypes.Options<T>
52
- defaultOptions?: FormTypes.Options<T>
53
- loadOptions?: (search: string) => Promise<FormTypes.Options<T>>
54
- value: SelectValue<T, Multi>
51
+ options?: Options<T>
52
+ defaultOptions?: Options<T>
53
+ loadOptions?: (search: string) => Promise<Options<T>>
55
54
  renderItem?: SelectRenderFN<SelectValue<T, Multi>>
56
- onValueChange: (value: SelectValue<T, Multi>) => void
57
- filterItems?: (search: string, items: FormTypes.Options<T>) => FormTypes.Options<T>
55
+ filterItems?: (search: string, items: Options<T>) => Options<T>
58
56
  onLoadOptionsError?: (error: any) => void
59
57
  multiple?: Multi
60
- getLabel?: (forOption: Multi extends true ? FormTypes.Options<T> : FormTypes.Options<T>[number]) => FormTypes.Label
58
+ getLabel?: (forOption: Multi extends true ? Options<T> : Option<T>) => string
61
59
  outerInputComponent?: OuterInputComponent<T, Multi>
62
60
  inputProps?: Partial<SelectOuterInputProps<T, Multi>>
63
61
  disabled?: boolean
64
62
  }
65
63
 
66
- export type ReplaceSelectProps<Props, T, Multi extends boolean = false> = Omit<
64
+ export type ReplaceSelectProps<Props, T extends string | number, Multi extends boolean = false> = Omit<
67
65
  Props,
68
66
  keyof ValueBoundSelectProps<T, Multi>
69
67
  > & ValueBoundSelectProps<T, Multi>
70
68
 
71
- export type SelectProps<T = any, Multi extends boolean = false> =
69
+ export type SelectProps<T extends string | number = any, Multi extends boolean = false> =
72
70
  SelectModalProps &
73
71
  ValueBoundSelectProps<T, Multi> &
74
72
  {
75
- placeholder?: FormTypes.Label
76
- label?: FormTypes.Label
73
+ placeholder?: string
74
+ label?: string
77
75
  hideInput?: boolean
78
76
  selectedIcon?: AppIcon
79
77
  arrowIconName?: AppIcon
@@ -92,4 +90,7 @@ export type SelectProps<T = any, Multi extends boolean = false> =
92
90
  loadOptionsOnMount?: boolean
93
91
  loadOptionsOnOpen?: boolean
94
92
  style?: StyledProp<SelectComposition>
93
+ field?: SelectableField<T, any>
94
+ value?: T
95
+ onValueChange?: (value: T) => void
95
96
  }
@@ -1,6 +1,5 @@
1
1
  import React from 'react'
2
2
  import { Slider as RNSlider } from '@miblanchard/react-native-slider'
3
- import { StyleSheet } from 'react-native'
4
3
  import { TypeGuards } from '@codeleap/types'
5
4
  import { onUpdate } from '@codeleap/hooks'
6
5
  import { SliderProps, TrackMarkProps } from './types'
@@ -11,6 +10,9 @@ import { Touchable } from '../Touchable'
11
10
  import { AnyRecord, IJSX, StyledComponentProps } from '@codeleap/styles'
12
11
  import { MobileStyleRegistry } from '../../Registry'
13
12
  import { useStylesFor } from '../../hooks'
13
+ import { useInputBase } from '../InputBase/useInputBase'
14
+ import { fields } from '@codeleap/form'
15
+ import { useInputBasePartialStyles } from '../InputBase/useInputBasePartialStyles'
14
16
 
15
17
  export * from './styles'
16
18
  export * from './types'
@@ -45,8 +47,7 @@ export const Slider = (props: SliderProps) => {
45
47
 
46
48
  const {
47
49
  debounce = null,
48
- onValueChange,
49
- value,
50
+ field,
50
51
  label,
51
52
  description,
52
53
  debugName,
@@ -55,54 +56,34 @@ export const Slider = (props: SliderProps) => {
55
56
  trackMarks,
56
57
  trackMarksClickable,
57
58
  labelClickable,
59
+ updateImmediately = false,
58
60
  trackMarkComponent: SliderTrackMark,
61
+ value,
62
+ onValueChange,
59
63
  ...sliderProps
60
64
  } = others
61
65
 
62
- const [_value, _setValue] = React.useState(value)
66
+ const {
67
+ fieldHandle,
68
+ wrapperRef,
69
+ } = useInputBase(field, fields.number, [value, onValueChange])
70
+
71
+ const [_value, _setValue] = updateImmediately ? [fieldHandle?.value, fieldHandle.setValue] : React.useState<number | Array<number>>(0)
63
72
 
64
73
  onUpdate(() => {
65
- if (value !== _value) {
66
- _setValue(value)
74
+ if (updateImmediately) return
75
+ if (fieldHandle?.value !== _value) {
76
+ _setValue(fieldHandle?.value)
67
77
  }
68
- }, [value])
78
+ }, [fieldHandle?.value])
69
79
 
70
80
  const styles = useStylesFor(Slider.styleRegistryName, style)
71
81
 
72
- const thumbStyle = React.useMemo(() => {
73
- return StyleSheet.flatten([
74
- styles?.thumb,
75
- disabled && styles['thumb:disabled'],
76
- ])
77
- }, [])
78
-
79
- const trackStyle = React.useMemo(() => {
80
- return StyleSheet.flatten([
81
- styles?.track,
82
- disabled && styles['track:disabled'],
83
- ])
84
- }, [disabled])
85
-
86
- const selectedTrackStyle = React.useMemo(() => {
87
- return StyleSheet.flatten([
88
- styles?.selectedTrack,
89
- disabled && styles['selectedTrack:disabled'],
90
- ])
91
- }, [disabled])
92
-
93
- const unselectedTrackStyle = React.useMemo(() => {
94
- return StyleSheet.flatten([
95
- styles?.unselectedTrack,
96
- disabled && styles['unselectedTrack:disabled'],
97
- ])
98
- }, [disabled])
99
-
100
- const containerStyle = React.useMemo(() => {
101
- return StyleSheet.flatten([
102
- styles?.sliderContainer,
103
- disabled && styles['sliderContainer:disabled'],
104
- ])
105
- }, [disabled])
82
+ const partialStyles = useInputBasePartialStyles(
83
+ styles,
84
+ ['thumb', 'track', 'selectedTrack', 'unselectedTrack', 'sliderContainer', 'trackMark'],
85
+ { disabled }
86
+ )
106
87
 
107
88
  const trackMarksHaveContent = !(TypeGuards.isArray(trackMarks) || TypeGuards.isNil(trackMarks))
108
89
 
@@ -113,16 +94,10 @@ export const Slider = (props: SliderProps) => {
113
94
  return Object.keys(trackMarks).map((key) => Number(key))
114
95
  }, [trackMarksHaveContent])
115
96
 
116
- const trackMarkStyle = React.useMemo(() => {
117
- return StyleSheet.flatten([
118
- styles?.trackMark,
119
- disabled && styles['trackMark:disabled'],
120
- ])
121
- }, [disabled])
122
-
123
97
  return (
124
98
  <InputBase
125
99
  {..._inputBaseProps}
100
+ ref={wrapperRef}
126
101
  disabled={disabled}
127
102
  style={styles}
128
103
  labelAsRow
@@ -131,7 +106,7 @@ export const Slider = (props: SliderProps) => {
131
106
  <View style={styles.labelRow}>
132
107
  {label ? (
133
108
  <Touchable
134
- onPress={() => labelClickable ? onValueChange(sliderProps?.minimumValue || minimumValue) : null}
109
+ onPress={() => labelClickable ? fieldHandle.setValue(sliderProps?.minimumValue || minimumValue) : null}
135
110
  style={styles.labelBtn}
136
111
  debugName='slider title'
137
112
  >
@@ -140,7 +115,7 @@ export const Slider = (props: SliderProps) => {
140
115
  ) : null}
141
116
  {description ? (
142
117
  <Touchable
143
- onPress={() => labelClickable ? onValueChange(sliderProps?.maximumValue || maximumValue) : null}
118
+ onPress={() => labelClickable ? fieldHandle.setValue(sliderProps?.maximumValue || maximumValue) : null}
144
119
  style={styles?.descriptionBtn}
145
120
  debugName='slider description'
146
121
  >
@@ -153,17 +128,16 @@ export const Slider = (props: SliderProps) => {
153
128
  <RNSlider
154
129
  value={_value}
155
130
  onValueChange={_setValue}
156
- // @ts-ignore
157
- thumbStyle={thumbStyle}
158
- // @ts-ignore
159
- trackStyle={trackStyle}
160
- minimumTrackStyle={selectedTrackStyle}
161
- maximumTrackStyle={unselectedTrackStyle}
162
- containerStyle={containerStyle}
131
+ thumbStyle={partialStyles?.thumb}
132
+ trackStyle={partialStyles?.track}
133
+ minimumTrackStyle={partialStyles?.selectedTrack}
134
+ maximumTrackStyle={partialStyles?.unselectedTrack}
135
+ containerStyle={partialStyles?.sliderContainer}
163
136
  minimumValue={minimumValue}
164
137
  maximumValue={maximumValue}
165
138
  onSlidingComplete={() => {
166
- onValueChange(_value)
139
+ if (updateImmediately) return
140
+ fieldHandle.setValue(_value)
167
141
  }}
168
142
  disabled={disabled}
169
143
  {...sliderProps}
@@ -182,17 +156,14 @@ export const Slider = (props: SliderProps) => {
182
156
  idxStyle = styles?.lastTrackMark
183
157
  }
184
158
 
185
- const style = [
186
- trackMarkStyle,
187
- idxStyle,
188
- ]
159
+ const style = [partialStyles?.trackMark, idxStyle]
189
160
 
190
161
  if (!trackMarksHaveContent) {
191
162
  return <SliderTrackMark
192
163
  index={idx}
193
164
  style={style}
194
165
  key={idx}
195
- onPress={() => trackMarksClickable ? onValueChange(trackMarksProp[idx]) : null}
166
+ onPress={() => trackMarksClickable ? fieldHandle.setValue(trackMarksProp[idx]) : null}
196
167
  />
197
168
  }
198
169
 
@@ -204,7 +175,7 @@ export const Slider = (props: SliderProps) => {
204
175
  content={content}
205
176
  style={style}
206
177
  key={idx}
207
- onPress={() => trackMarksClickable ? onValueChange(trackMarksProp[idx]) : null}
178
+ onPress={() => trackMarksClickable ? fieldHandle.setValue(trackMarksProp[idx]) : null}
208
179
  />
209
180
  })
210
181
  }
@@ -1,26 +1,29 @@
1
1
  import { SliderComposition } from './styles'
2
2
  import { SliderProps as RNSliderProps } from '@miblanchard/react-native-slider/lib/types'
3
3
  import { InputBaseProps } from '../InputBase'
4
- import { StyledProp } from '@codeleap/styles'
4
+ import { ICSS, StyledProp } from '@codeleap/styles'
5
+ import { NumberField } from '@codeleap/form'
5
6
 
6
7
  export type SliderProps =
7
8
  Partial<Omit<RNSliderProps, 'value' | 'onValueChange' | 'style'>> &
8
9
  Pick<InputBaseProps, 'disabled' | 'debugName' | 'description' | 'label'> &
9
10
  {
10
11
  debounce?: number | null
11
- trackMarklabels: string[]
12
- value: number | number[]
13
- onValueChange: (val: number | number[]) => void
12
+ trackMarklabels?: string[]
14
13
  trackMarks?: RNSliderProps['trackMarks'] | Record<number, string>
15
14
  trackMarksClickable?: boolean
16
15
  labelClickable?: boolean
17
16
  trackMarkComponent?: React.ComponentType<TrackMarkProps>
18
17
  style?: StyledProp<SliderComposition>
18
+ updateImmediately?: boolean
19
+ field?: NumberField<any>
20
+ value?: number | number[]
21
+ onValueChange?: (value: number | number[]) => void
19
22
  }
20
23
 
21
24
  export type TrackMarkProps = {
22
25
  index: number
23
26
  content?: string | React.ReactNode
24
- style?: any
27
+ style?: ICSS | ICSS[]
25
28
  onPress?: () => void
26
29
  }
@@ -2,22 +2,24 @@ import { AnyRecord, IJSX, StyledComponentProps, useNestedStylesByKey } from '@co
2
2
  import { FileInput } from '../FileInput'
3
3
  import { Icon } from '../Icon'
4
4
  import { Image } from '../Image'
5
- import { Dimensions, View } from 'react-native'
6
- import { DragSortableView } from 'react-native-drag-sort'
7
- import { SortableItemProps, SortablePhoto, SortablePhotosProps } from './types'
5
+ import { Pressable, View } from 'react-native'
6
+ import { SortableItemProps, SortablePhoto, SortablePhotosProps, WithId } from './types'
8
7
  import { useSortablePhotos } from './useSortablePhotos'
9
8
  import { useStylesFor } from '../../hooks'
10
9
  import { MobileStyleRegistry } from '../../Registry'
11
10
  import { ActivityIndicator } from '../ActivityIndicator'
11
+ import Sortable, { type SortableGridRenderItem } from 'react-native-sortables'
12
+ import { GestureHandlerRootView } from 'react-native-gesture-handler'
13
+ import { useCallback } from 'react'
12
14
 
13
15
  export * from './styles'
14
16
  export * from './types'
15
17
 
16
18
  const DefaultItem = <T extends SortablePhoto>(props: SortableItemProps<T>) => {
17
- const { photo, width, height, styles, emptyIcon } = props
19
+ const { photo, styles, emptyIcon } = props
18
20
 
19
21
  return (
20
- <View style={[{ width, height }, styles.photoWrapper]}>
22
+ <View style={styles.photoWrapper}>
21
23
  {
22
24
  !!photo?.filename
23
25
  ? <Image resizeMode='cover' source={{ uri: photo?.file }} style={styles.photoImage} />
@@ -39,8 +41,6 @@ const defaultGetFilename = (file: string) => {
39
41
  return new Date().toISOString()
40
42
  }
41
43
 
42
- const screenWidth = Dimensions.get('screen').width
43
-
44
44
  export const SortablePhotos = <T extends SortablePhoto>(props: SortablePhotosProps<T>) => {
45
45
  const allProps = {
46
46
  ...SortablePhotos.defaultProps,
@@ -54,10 +54,6 @@ export const SortablePhotos = <T extends SortablePhoto>(props: SortablePhotosPro
54
54
  multiple,
55
55
  pickerConfig,
56
56
  emptyIcon,
57
- disableDragDropEmptyItems,
58
- itemWidth: _itemWidth,
59
- itemHeight: _itemHeight,
60
- width: _parentWidth,
61
57
  style,
62
58
  loading,
63
59
  ...rest
@@ -71,20 +67,11 @@ export const SortablePhotos = <T extends SortablePhoto>(props: SortablePhotosPro
71
67
  input,
72
68
  handlePressPhoto,
73
69
  numberPhotosMissing,
74
- emptyIndexes,
70
+ enabledDragDrop,
75
71
  onChangePhotosOrder,
76
72
  data,
77
73
  } = useSortablePhotos<T>(allProps)
78
74
 
79
- const defaultParentWidth = screenWidth - (gap * 2)
80
- const defaultItemWidth = (defaultParentWidth / numColumns) - gap
81
-
82
- const itemWidth = _itemWidth ?? defaultItemWidth
83
- const itemHeight = _itemHeight ?? itemWidth
84
- const parentWidth = _parentWidth ?? defaultParentWidth
85
-
86
- const childrenMargin = gap / 2
87
-
88
75
  const fileInputPickerOptions = {
89
76
  ...SortablePhotos.defaultProps.pickerConfig,
90
77
  ...pickerConfig,
@@ -92,6 +79,17 @@ export const SortablePhotos = <T extends SortablePhoto>(props: SortablePhotosPro
92
79
  maxFiles: numberPhotosMissing,
93
80
  }
94
81
 
82
+ const renderItem: SortableGridRenderItem<WithId<T>> = useCallback(({ item, index }) => (
83
+ <Sortable.Pressable onPress={() => handlePressPhoto(item, index)}>
84
+ <RenderItem
85
+ photo={item}
86
+ order={index}
87
+ styles={styles}
88
+ emptyIcon={emptyIcon}
89
+ />
90
+ </Sortable.Pressable>
91
+ ), [handlePressPhoto])
92
+
95
93
  if (loading) {
96
94
  return (
97
95
  <View style={[styles.wrapper, styles['wrapper:loading']]}>
@@ -100,7 +98,7 @@ export const SortablePhotos = <T extends SortablePhoto>(props: SortablePhotosPro
100
98
  )
101
99
  }
102
100
 
103
- return (
101
+ return <GestureHandlerRootView>
104
102
  <View style={styles.wrapper}>
105
103
  <FileInput
106
104
  mode='hidden'
@@ -108,32 +106,19 @@ export const SortablePhotos = <T extends SortablePhoto>(props: SortablePhotosPro
108
106
  pickerOptions={fileInputPickerOptions}
109
107
  />
110
108
 
111
- <DragSortableView
112
- dataSource={data}
113
- childrenHeight={itemHeight}
114
- childrenWidth={itemWidth}
115
- parentWidth={parentWidth}
116
- marginChildrenBottom={childrenMargin}
117
- marginChildrenLeft={childrenMargin}
118
- marginChildrenRight={childrenMargin}
119
- marginChildrenTop={childrenMargin}
120
- onDataChange={onChangePhotosOrder}
121
- onClickItem={handlePressPhoto}
122
- fixedItems={disableDragDropEmptyItems ? emptyIndexes : undefined}
109
+ <Sortable.Grid
110
+ columns={numColumns}
111
+ columnGap={gap}
112
+ rowGap={gap}
113
+ sortEnabled={enabledDragDrop}
114
+ showDropIndicator
123
115
  {...rest}
124
- renderItem={(item, order) => (
125
- <RenderItem
126
- width={itemWidth}
127
- height={itemHeight}
128
- photo={item}
129
- order={order}
130
- styles={styles}
131
- emptyIcon={emptyIcon}
132
- />
133
- )}
116
+ data={data}
117
+ renderItem={renderItem}
118
+ onDragEnd={({ data }) => onChangePhotosOrder(data as unknown as WithId<T>[])}
134
119
  />
135
120
  </View>
136
- )
121
+ </GestureHandlerRootView>
137
122
  }
138
123
 
139
124
  SortablePhotos.styleRegistryName = 'SortablePhotos'
@@ -149,8 +134,7 @@ SortablePhotos.defaultProps = {
149
134
  numColumns: 3,
150
135
  renderPhoto: DefaultItem,
151
136
  multiple: true,
152
- disableDragDropEmptyItems: true,
153
- gap: 16,
137
+ gap: 8,
154
138
  emptyIcon: 'plus',
155
139
  modalTitle: 'Photos',
156
140
  modalBody: null,
@@ -1,17 +1,20 @@
1
1
  import { AppIcon, ICSS, StyledProp } from '@codeleap/styles'
2
2
  import { ReactElement } from 'react'
3
3
  import { SortablePhotosComposition } from './styles'
4
+ import { type SortableGridProps } from 'react-native-sortables'
4
5
 
5
6
  export type SortablePhoto = {
6
7
  filename: string | null
7
8
  file: string | null
8
9
  }
9
10
 
11
+ export type WithId<T extends SortablePhoto> = T & {
12
+ key: string
13
+ }
14
+
10
15
  export type SortableItemProps<T extends SortablePhoto> = {
11
16
  photo: T
12
17
  order: number
13
- height: number
14
- width: number
15
18
  styles: Record<SortablePhotosComposition, ICSS>
16
19
  emptyIcon: AppIcon
17
20
  }
@@ -24,29 +27,17 @@ export type SortablePhotosPickerConfig = {
24
27
  showCropFrame?: boolean
25
28
  }
26
29
 
27
- export type SortablePhotosProps<T extends SortablePhoto> = {
30
+ export type SortablePhotosProps<T extends SortablePhoto> = Omit<SortableGridProps<T>, 'data' | 'columns'> & {
28
31
  numColumns?: number
29
32
  numPhotos?: number
30
33
  renderPhoto?: (props: SortableItemProps<T>) => ReactElement
31
34
  photos: T[]
32
35
  onChangePhotos: (newPhotos: T[]) => void
33
36
  gap?: number
34
- itemHeight?: number
35
- itemWidth?: number
36
- width?: number
37
37
  onPressPhoto?: (data: T[], photo: T, order: number) => void
38
- onDragStart?: (fromIndex: number) => void
39
- onDragEnd?: (fromIndex: number, toIndex: number) => void
40
- keyExtractor?: (photo: T, order: number) => any
41
- delayLongPress?: number
42
38
  pickerConfig?: SortablePhotosPickerConfig
43
39
  multiple?: boolean
44
- maxScale?: number
45
- minOpacity?: number
46
- scaleDuration?: number
47
- slideDuration?: number
48
40
  emptyIcon?: AppIcon
49
- disableDragDropEmptyItems?: boolean
50
41
  style?: StyledProp<SortablePhotosComposition>
51
42
  modalTitle?: string
52
43
  modalBody?: string