@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
@@ -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,
@@ -57,54 +58,32 @@ export const Slider = (props: SliderProps) => {
57
58
  labelClickable,
58
59
  updateImmediately = false,
59
60
  trackMarkComponent: SliderTrackMark,
61
+ value,
62
+ onValueChange,
60
63
  ...sliderProps
61
64
  } = others
62
65
 
63
- const [_value, _setValue] = updateImmediately ? [value, onValueChange] : 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)
64
72
 
65
73
  onUpdate(() => {
66
- if(updateImmediately) return
67
- if (value !== _value) {
68
- _setValue(value)
74
+ if (updateImmediately) return
75
+ if (fieldHandle?.value !== _value) {
76
+ _setValue(fieldHandle?.value)
69
77
  }
70
- }, [value])
78
+ }, [fieldHandle?.value])
71
79
 
72
80
  const styles = useStylesFor(Slider.styleRegistryName, style)
73
81
 
74
- const thumbStyle = React.useMemo(() => {
75
- return StyleSheet.flatten([
76
- styles?.thumb,
77
- disabled && styles['thumb:disabled'],
78
- ])
79
- }, [])
80
-
81
- const trackStyle = React.useMemo(() => {
82
- return StyleSheet.flatten([
83
- styles?.track,
84
- disabled && styles['track:disabled'],
85
- ])
86
- }, [disabled])
87
-
88
- const selectedTrackStyle = React.useMemo(() => {
89
- return StyleSheet.flatten([
90
- styles?.selectedTrack,
91
- disabled && styles['selectedTrack:disabled'],
92
- ])
93
- }, [disabled])
94
-
95
- const unselectedTrackStyle = React.useMemo(() => {
96
- return StyleSheet.flatten([
97
- styles?.unselectedTrack,
98
- disabled && styles['unselectedTrack:disabled'],
99
- ])
100
- }, [disabled])
101
-
102
- const containerStyle = React.useMemo(() => {
103
- return StyleSheet.flatten([
104
- styles?.sliderContainer,
105
- disabled && styles['sliderContainer:disabled'],
106
- ])
107
- }, [disabled])
82
+ const partialStyles = useInputBasePartialStyles(
83
+ styles,
84
+ ['thumb', 'track', 'selectedTrack', 'unselectedTrack', 'sliderContainer', 'trackMark'],
85
+ { disabled }
86
+ )
108
87
 
109
88
  const trackMarksHaveContent = !(TypeGuards.isArray(trackMarks) || TypeGuards.isNil(trackMarks))
110
89
 
@@ -115,16 +94,10 @@ export const Slider = (props: SliderProps) => {
115
94
  return Object.keys(trackMarks).map((key) => Number(key))
116
95
  }, [trackMarksHaveContent])
117
96
 
118
- const trackMarkStyle = React.useMemo(() => {
119
- return StyleSheet.flatten([
120
- styles?.trackMark,
121
- disabled && styles['trackMark:disabled'],
122
- ])
123
- }, [disabled])
124
-
125
97
  return (
126
98
  <InputBase
127
99
  {..._inputBaseProps}
100
+ ref={wrapperRef}
128
101
  disabled={disabled}
129
102
  style={styles}
130
103
  labelAsRow
@@ -133,7 +106,7 @@ export const Slider = (props: SliderProps) => {
133
106
  <View style={styles.labelRow}>
134
107
  {label ? (
135
108
  <Touchable
136
- onPress={() => labelClickable ? onValueChange(sliderProps?.minimumValue || minimumValue) : null}
109
+ onPress={() => labelClickable ? fieldHandle.setValue(sliderProps?.minimumValue || minimumValue) : null}
137
110
  style={styles.labelBtn}
138
111
  debugName='slider title'
139
112
  >
@@ -142,7 +115,7 @@ export const Slider = (props: SliderProps) => {
142
115
  ) : null}
143
116
  {description ? (
144
117
  <Touchable
145
- onPress={() => labelClickable ? onValueChange(sliderProps?.maximumValue || maximumValue) : null}
118
+ onPress={() => labelClickable ? fieldHandle.setValue(sliderProps?.maximumValue || maximumValue) : null}
146
119
  style={styles?.descriptionBtn}
147
120
  debugName='slider description'
148
121
  >
@@ -155,18 +128,16 @@ export const Slider = (props: SliderProps) => {
155
128
  <RNSlider
156
129
  value={_value}
157
130
  onValueChange={_setValue}
158
- // @ts-ignore
159
- thumbStyle={thumbStyle}
160
- // @ts-ignore
161
- trackStyle={trackStyle}
162
- minimumTrackStyle={selectedTrackStyle}
163
- maximumTrackStyle={unselectedTrackStyle}
164
- containerStyle={containerStyle}
131
+ thumbStyle={partialStyles?.thumb}
132
+ trackStyle={partialStyles?.track}
133
+ minimumTrackStyle={partialStyles?.selectedTrack}
134
+ maximumTrackStyle={partialStyles?.unselectedTrack}
135
+ containerStyle={partialStyles?.sliderContainer}
165
136
  minimumValue={minimumValue}
166
137
  maximumValue={maximumValue}
167
138
  onSlidingComplete={() => {
168
- if(updateImmediately) return
169
- onValueChange(_value)
139
+ if (updateImmediately) return
140
+ fieldHandle.setValue(_value)
170
141
  }}
171
142
  disabled={disabled}
172
143
  {...sliderProps}
@@ -185,17 +156,14 @@ export const Slider = (props: SliderProps) => {
185
156
  idxStyle = styles?.lastTrackMark
186
157
  }
187
158
 
188
- const style = [
189
- trackMarkStyle,
190
- idxStyle,
191
- ]
159
+ const style = [partialStyles?.trackMark, idxStyle]
192
160
 
193
161
  if (!trackMarksHaveContent) {
194
162
  return <SliderTrackMark
195
163
  index={idx}
196
164
  style={style}
197
165
  key={idx}
198
- onPress={() => trackMarksClickable ? onValueChange(trackMarksProp[idx]) : null}
166
+ onPress={() => trackMarksClickable ? fieldHandle.setValue(trackMarksProp[idx]) : null}
199
167
  />
200
168
  }
201
169
 
@@ -207,7 +175,7 @@ export const Slider = (props: SliderProps) => {
207
175
  content={content}
208
176
  style={style}
209
177
  key={idx}
210
- onPress={() => trackMarksClickable ? onValueChange(trackMarksProp[idx]) : null}
178
+ onPress={() => trackMarksClickable ? fieldHandle.setValue(trackMarksProp[idx]) : null}
211
179
  />
212
180
  })
213
181
  }
@@ -1,27 +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>
19
18
  updateImmediately?: boolean
19
+ field?: NumberField<any>
20
+ value?: number | number[]
21
+ onValueChange?: (value: number | number[]) => void
20
22
  }
21
23
 
22
24
  export type TrackMarkProps = {
23
25
  index: number
24
26
  content?: string | React.ReactNode
25
- style?: any
27
+ style?: ICSS | ICSS[]
26
28
  onPress?: () => void
27
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