@codeleap/mobile 3.25.0 → 3.25.3

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 (131) hide show
  1. package/package.json +4 -6
  2. package/src/components/ActionIcon/index.tsx +37 -55
  3. package/src/components/ActionIcon/styles.ts +4 -2
  4. package/src/components/ActivityIndicator/index.tsx +64 -42
  5. package/src/components/ActivityIndicator/styles.ts +10 -1
  6. package/src/components/Autocomplete/index.tsx +54 -46
  7. package/src/components/Autocomplete/styles.ts +5 -2
  8. package/src/components/Autocomplete/types.ts +23 -13
  9. package/src/components/Avatar/index.tsx +71 -59
  10. package/src/components/Avatar/styles.ts +9 -1
  11. package/src/components/AvatarGroup/index.tsx +44 -30
  12. package/src/components/AvatarGroup/styles.ts +6 -0
  13. package/src/components/Backdrop/index.tsx +34 -51
  14. package/src/components/Backdrop/styles.ts +10 -5
  15. package/src/components/Badge/index.tsx +62 -36
  16. package/src/components/Badge/styles.ts +11 -3
  17. package/src/components/Button/index.tsx +82 -55
  18. package/src/components/Button/styles.ts +14 -13
  19. package/src/components/Calendar/index.tsx +29 -35
  20. package/src/components/Calendar/style.ts +6 -0
  21. package/src/components/Checkbox/index.tsx +64 -43
  22. package/src/components/Checkbox/styles.ts +6 -1
  23. package/src/components/ContentView/index.tsx +63 -0
  24. package/src/components/ContentView/styles.ts +8 -0
  25. package/src/components/DatePickerModal/index.tsx +65 -50
  26. package/src/components/DatePickerModal/styles.ts +10 -9
  27. package/src/components/DatePickerModal/types.ts +54 -36
  28. package/src/components/Drawer/index.tsx +28 -0
  29. package/src/components/Drawer/styles.ts +8 -0
  30. package/src/components/EmptyPlaceholder/index.tsx +63 -40
  31. package/src/components/EmptyPlaceholder/styles.ts +5 -0
  32. package/src/components/FileInput/index.tsx +49 -11
  33. package/src/components/FileInput/styles.ts +8 -0
  34. package/src/components/Grid/index.tsx +116 -84
  35. package/src/components/Grid/styles.ts +5 -0
  36. package/src/components/Icon/index.tsx +79 -44
  37. package/src/components/Icon/styles.ts +6 -0
  38. package/src/components/Image/index.tsx +78 -58
  39. package/src/components/Image/styles.ts +6 -1
  40. package/src/components/ImageView/Spotlight.tsx +4 -1
  41. package/src/components/ImageView/component.tsx +2 -1
  42. package/src/components/InputBase/index.tsx +24 -33
  43. package/src/components/InputBase/styles.ts +75 -66
  44. package/src/components/InputBase/types.ts +4 -3
  45. package/src/components/InputBase/utils.ts +4 -6
  46. package/src/components/InputLabel/index.tsx +38 -0
  47. package/src/components/InputLabel/styles.ts +7 -0
  48. package/src/components/List/PaginationIndicator.tsx +54 -0
  49. package/src/components/List/index.tsx +151 -99
  50. package/src/components/List/styles.ts +6 -0
  51. package/src/components/LoadingOverlay/index.tsx +29 -42
  52. package/src/components/LoadingOverlay/styles.ts +7 -7
  53. package/src/components/Modal/index.tsx +127 -80
  54. package/src/components/Modal/styles.ts +8 -0
  55. package/src/components/Navigation/Navigation.tsx +0 -1
  56. package/src/components/Navigation/types.ts +9 -2
  57. package/src/components/NumberIncrement/index.tsx +60 -50
  58. package/src/components/NumberIncrement/styles.ts +5 -0
  59. package/src/components/NumberIncrement/types.ts +39 -32
  60. package/src/components/Pager/index.tsx +94 -42
  61. package/src/components/Pager/styles.ts +13 -1
  62. package/src/components/RadioInput/index.tsx +57 -32
  63. package/src/components/RadioInput/styles.ts +7 -5
  64. package/src/components/RefreshControl/index.tsx +19 -39
  65. package/src/components/RefreshControl/styles.ts +6 -1
  66. package/src/components/Scroll/index.tsx +105 -89
  67. package/src/components/Scroll/styles.ts +5 -0
  68. package/src/components/Sections/index.tsx +161 -111
  69. package/src/components/Sections/styles.ts +5 -0
  70. package/src/components/SegmentedControl/Option.tsx +31 -46
  71. package/src/components/SegmentedControl/index.tsx +121 -86
  72. package/src/components/SegmentedControl/styles.ts +22 -15
  73. package/src/components/Select/index.tsx +82 -71
  74. package/src/components/Select/styles.ts +5 -3
  75. package/src/components/Select/types.ts +25 -20
  76. package/src/components/Slider/index.tsx +43 -58
  77. package/src/components/Slider/styles.ts +6 -15
  78. package/src/components/Slider/types.ts +14 -9
  79. package/src/components/Switch/index.tsx +56 -43
  80. package/src/components/Switch/styles.ts +7 -1
  81. package/src/components/Text/index.tsx +52 -56
  82. package/src/components/Text/styles.ts +7 -1
  83. package/src/components/TextInput/index.tsx +162 -49
  84. package/src/components/TextInput/styles.ts +8 -2
  85. package/src/components/Touchable/index.tsx +87 -44
  86. package/src/components/Touchable/styles.ts +9 -0
  87. package/src/components/View/index.tsx +92 -23
  88. package/src/components/View/styles.ts +6 -0
  89. package/src/components/components.ts +6 -2
  90. package/src/components/defaultStyles.ts +77 -0
  91. package/src/index.ts +0 -2
  92. package/src/modules/PressableRipple/type.ts +0 -1
  93. package/src/utils/KeyboardAware/context.tsx +2 -0
  94. package/src/utils/KeyboardAware/keyboardHooks.ts +2 -1
  95. package/src/utils/ModalManager/components.tsx +30 -1
  96. package/src/utils/ModalManager/context.tsx +4 -4
  97. package/src/utils/ModalManager/index.ts +4 -1
  98. package/src/utils/hooks.ts +1 -12
  99. package/src/Registry.ts +0 -52
  100. package/src/components/ActionIcon/types.ts +0 -15
  101. package/src/components/ActivityIndicator/types.ts +0 -9
  102. package/src/components/Avatar/types.ts +0 -23
  103. package/src/components/AvatarGroup/types.ts +0 -10
  104. package/src/components/Backdrop/types.ts +0 -14
  105. package/src/components/Badge/types.ts +0 -27
  106. package/src/components/Button/types.ts +0 -20
  107. package/src/components/Checkbox/types.ts +0 -13
  108. package/src/components/EmptyPlaceholder/types.ts +0 -21
  109. package/src/components/FileInput/types.ts +0 -27
  110. package/src/components/Grid/types.ts +0 -20
  111. package/src/components/Icon/types.ts +0 -15
  112. package/src/components/Image/types.ts +0 -18
  113. package/src/components/List/types.ts +0 -41
  114. package/src/components/LoadingOverlay/types.ts +0 -9
  115. package/src/components/Modal/types.ts +0 -41
  116. package/src/components/Pager/types.ts +0 -37
  117. package/src/components/PaginationIndicator/index.tsx +0 -51
  118. package/src/components/PaginationIndicator/styles.ts +0 -3
  119. package/src/components/PaginationIndicator/types.ts +0 -10
  120. package/src/components/RadioInput/types.ts +0 -31
  121. package/src/components/RefreshControl/types.ts +0 -9
  122. package/src/components/Scroll/types.ts +0 -21
  123. package/src/components/SearchInput/index.tsx +0 -90
  124. package/src/components/Sections/types.ts +0 -39
  125. package/src/components/SegmentedControl/types.ts +0 -31
  126. package/src/components/Switch/types.ts +0 -12
  127. package/src/components/Text/types.ts +0 -18
  128. package/src/components/TextInput/types.ts +0 -23
  129. package/src/components/Touchable/types.ts +0 -27
  130. package/src/components/View/types.ts +0 -13
  131. package/src/hooks/index.ts +0 -13
@@ -1,25 +1,72 @@
1
- import React from 'react'
2
- import { View } from '../View'
1
+ import * as React from 'react'
2
+ import { View, ViewProps } from '../View'
3
+ import { ButtonProps } from '../Button'
3
4
  import { Scroll } from '../Scroll'
4
- import { TypeGuards } from '@codeleap/common'
5
+ import {
6
+ ComponentVariants,
7
+ getNestedStylesByKey,
8
+ IconPlaceholder,
9
+ PropsOf,
10
+ TypeGuards,
11
+ useDefaultComponentStyle,
12
+ useRef,
13
+ useCodeleapContext,
14
+ } from '@codeleap/common'
15
+ import {
16
+ ModalComposition,
17
+ ModalPresets,
18
+ ModalParts,
19
+ } from './styles'
20
+ import { ScrollView, StyleSheet } from 'react-native'
21
+ import { StylesOf } from '../../types/utility'
22
+
5
23
  import { Backdrop } from '../Backdrop'
6
24
  import { useAnimatedVariantStyles, useBackButton } from '../../utils/hooks'
7
- import { Text } from '../Text'
25
+ import { Text, TextProps } from '../Text'
8
26
  import { Touchable } from '../Touchable'
9
27
  import { ActionIcon } from '../ActionIcon'
10
28
  import { useState } from 'react'
11
- import { ModalHeaderProps, ModalProps } from './types'
12
- import { AnyRecord, AppIcon, useNestedStylesByKey, IJSX, StyledComponentProps, useTheme, AppTheme, Theme } from '@codeleap/styles'
13
- import { MobileStyleRegistry } from '../../Registry'
14
- import { useStylesFor } from '../../hooks'
15
29
 
16
30
  export * from './styles'
17
- export * from './types'
31
+
32
+ export type ModalProps = Omit<ViewProps, 'variants' | 'styles'> & {
33
+ variants?: ComponentVariants<typeof ModalPresets>['variants']
34
+ styles?: StylesOf<ModalComposition>
35
+ dismissOnBackdrop?: boolean
36
+ buttonProps?: ButtonProps
37
+ accessible?: boolean
38
+ showClose?: boolean
39
+ closable?: boolean
40
+ footer?: React.ReactNode
41
+ title?: React.ReactNode
42
+ debugName: string
43
+ closeIconName?: IconPlaceholder
44
+ visible: boolean
45
+ toggle?: () => void
46
+ zIndex?: number
47
+ description?: React.ReactElement
48
+ scroll?: boolean
49
+ header?: React.ReactElement
50
+ closeOnHardwareBackPress?: boolean
51
+ renderHeader?: (props: ModalHeaderProps) => React.ReactElement
52
+ keyboardAware?: boolean
53
+ scrollProps?: PropsOf<typeof Scroll, 'ref'>
54
+ }
55
+
56
+ export type ModalHeaderProps = Omit<ModalProps, 'styles' | 'renderHeader'> & {
57
+ styles: {
58
+ wrapper: ViewProps['style']
59
+ titleWrapper: ViewProps['style']
60
+ title: TextProps['style']
61
+ description: TextProps['style']
62
+ closeButton: ButtonProps['styles']
63
+ }
64
+ description?: React.ReactElement
65
+ }
18
66
 
19
67
  const DefaultHeader = (props: ModalHeaderProps) => {
20
68
  const {
21
69
  styles,
22
- buttonStyles,
23
70
  title = null,
24
71
  showClose = false,
25
72
  description = null,
@@ -27,10 +74,9 @@ const DefaultHeader = (props: ModalHeaderProps) => {
27
74
  closeIconName = 'x',
28
75
  toggle,
29
76
  } = props
30
-
31
77
  return <>
32
78
  {(title || showClose || description) && (
33
- <View style={styles.header}>
79
+ <View style={styles.wrapper}>
34
80
  <View style={styles.titleWrapper}>
35
81
  {TypeGuards.isString(title) ? (
36
82
  <Text text={title} style={styles.title} />
@@ -38,14 +84,14 @@ const DefaultHeader = (props: ModalHeaderProps) => {
38
84
  title
39
85
  )}
40
86
 
41
- {(showClose && closable) ? (
87
+ {(showClose && closable) && (
42
88
  <ActionIcon
43
89
  debugName={`${debugName} modal close button`}
44
- icon={closeIconName as AppIcon}
90
+ icon={closeIconName as IconPlaceholder}
45
91
  onPress={toggle}
46
- style={buttonStyles}
92
+ styles={styles.closeButton}
47
93
  />
48
- ) : null}
94
+ )}
49
95
  </View>
50
96
 
51
97
  {TypeGuards.isString(description) ? (
@@ -54,39 +100,51 @@ const DefaultHeader = (props: ModalHeaderProps) => {
54
100
  description
55
101
  )}
56
102
  </View>
57
- )}
58
- </>
103
+ )}</>
59
104
  }
60
105
 
61
106
  export const Modal = (modalProps: ModalProps) => {
62
107
  const {
108
+ variants = [],
109
+ styles = {},
63
110
  visible,
64
- closable,
111
+
112
+ closable = true,
113
+
65
114
  footer,
66
115
  children,
67
116
  toggle = () => null,
68
- dismissOnBackdrop,
117
+ dismissOnBackdrop = true,
69
118
  header = null,
70
119
  debugName,
71
- scroll,
120
+ scroll = true,
72
121
  renderHeader,
73
122
  zIndex = null,
74
123
  scrollProps = {},
75
- closeOnHardwareBackPress,
76
- style,
124
+ closeOnHardwareBackPress = true,
77
125
  ...props
78
126
  } = {
79
127
  ...Modal.defaultProps,
80
128
  ...modalProps,
81
129
  }
82
-
83
- const themeValues = useTheme(store => (store.current as AppTheme<Theme>)?.values)
84
-
85
130
  const [modalHeight, setModalHeight] = useState(0)
131
+ const { Theme } = useCodeleapContext()
86
132
 
87
- const styles = useStylesFor(Modal.styleRegistryName, style)
133
+ const variantStyles = useDefaultComponentStyle('u:Modal', {
134
+ variants: variants as any,
135
+ transform: StyleSheet.flatten,
136
+ styles,
137
+ }) as ModalProps['styles']
138
+ const scrollRef = useRef<ScrollView>(null)
139
+ function getStyles(key: ModalParts) {
140
+ const s = [
141
+ variantStyles[key],
142
+ styles[key],
143
+ ]
88
144
 
89
- const buttonStyles = useNestedStylesByKey('closeButton', styles)
145
+ return StyleSheet.flatten(s)
146
+ }
147
+ const buttonStyles = React.useMemo(() => getNestedStylesByKey('closeButton', variantStyles), [variantStyles])
90
148
 
91
149
  const boxAnimationStyles = useAnimatedVariantStyles({
92
150
  updater: (states) => {
@@ -94,24 +152,31 @@ export const Modal = (modalProps: ModalProps) => {
94
152
  return visible ? states['box:visible'] : states['box:hidden']
95
153
  },
96
154
  animatedProperties: ['box:hidden', 'box:visible'],
97
- variantStyles: styles,
98
- transition: styles['box:transition'],
155
+ variantStyles,
156
+ transition: variantStyles['box:transition'],
99
157
  dependencies: [visible],
100
158
  })
101
159
 
160
+ const wrapperStyle = getStyles('wrapper')
161
+
102
162
  const ScrollComponent = scroll ? Scroll : View
103
- const scrollStyle = scroll ? styles?.scroll : styles?.innerWrapper
163
+ const scrollStyle = scroll ? getStyles('scroll') : getStyles('innerWrapper')
104
164
 
105
- const heightThreshold = themeValues?.height * 0.75
106
- const topSpacing = modalHeight > heightThreshold ? styles?.topSpacing : 0
165
+ const heightThreshold = Theme.values.height * 0.75
166
+ const topSpacing = modalHeight > heightThreshold ? variantStyles.topSpacing : Theme.spacing.paddingTop(0)
107
167
 
108
168
  const headerProps: ModalHeaderProps = {
169
+
109
170
  ...modalProps,
110
171
  closable,
111
- styles,
112
- buttonStyles,
172
+ styles: {
173
+ wrapper: getStyles('header'),
174
+ title: getStyles('title'),
175
+ description: getStyles('description'),
176
+ closeButton: buttonStyles,
177
+ titleWrapper: getStyles('titleWrapper'),
178
+ },
113
179
  }
114
-
115
180
  const Header = renderHeader || DefaultHeader
116
181
 
117
182
  useBackButton(() => {
@@ -129,83 +194,65 @@ export const Modal = (modalProps: ModalProps) => {
129
194
 
130
195
  return (
131
196
  <View
132
- style={[
133
- styles?.wrapper,
134
- // @ts-expect-error
135
- { zIndex: TypeGuards.isNumber(zIndex) ? zIndex : styles?.wrapper?.zIndex, ...topSpacing }
136
- ]}
197
+ style={[wrapperStyle, {
198
+ zIndex: TypeGuards.isNumber(zIndex) ? zIndex : wrapperStyle?.zIndex, ...topSpacing,
199
+ }]}
137
200
  pointerEvents={visible ? 'auto' : 'none'}
138
201
  >
139
- <Backdrop
140
- visible={visible}
141
- debugName={`Modal ${debugName} backdrop`}
142
- style={{
143
- 'wrapper:hidden': styles['backdrop:hidden'],
144
- 'wrapper:visible': styles['backdrop:visible'],
145
- 'wrapper': styles?.backdrop,
146
- }}
202
+
203
+ <Backdrop visible={visible} debugName={`Modal ${debugName} backdrop`} styles={{
204
+ 'wrapper:hidden': variantStyles['backdrop:hidden'],
205
+ 'wrapper:visible': variantStyles['backdrop:visible'],
206
+ wrapper: variantStyles.backdrop,
207
+ }}
147
208
  wrapperProps={{
148
- // @ts-expect-error
149
- transition: styles['backdrop:transition'],
209
+ transition: { ...variantStyles['backdrop:transition'] },
150
210
  }}
151
211
  />
152
-
153
212
  <ScrollComponent
154
- contentContainerStyle={styles?.scrollContent}
213
+ style={scrollStyle}
214
+ contentContainerStyle={getStyles('scrollContent')}
155
215
  showsVerticalScrollIndicator={false}
156
216
  keyboardAware
157
217
  animated
218
+
158
219
  {...scrollProps}
159
- style={scrollStyle}
160
220
  >
161
- {dismissOnBackdrop ? (
221
+ {dismissOnBackdrop &&
162
222
  <Touchable
163
223
  onPress={closable && visible ? toggle : (() => { })}
164
224
  debounce={400}
165
225
  debugName={'Modal backdrop touchable'}
166
- style={styles?.backdropTouchable}
226
+ style={variantStyles.backdropTouchable}
167
227
  android_ripple={null}
168
228
  noFeedback
169
- />) : null}
229
+ />}
170
230
 
171
231
  <View
172
232
  animated
173
- animatedStyle={boxAnimationStyles}
233
+ style={[getStyles('box'), boxAnimationStyles]}
174
234
  {...props}
175
235
  onLayout={onModalLayout}
176
- style={styles?.box}
177
236
  >
178
- {header ? header : <Header {...headerProps} />}
179
237
 
180
- <View style={styles?.body}>{children}</View>
238
+ {header ? header : <Header {...headerProps} />}
181
239
 
182
- {footer ? (
183
- <View style={styles?.footer}>
240
+ <View style={getStyles('body')}>{children}</View>
241
+ {footer && (
242
+ <View style={getStyles('footer')}>
184
243
  {typeof footer === 'string' ? <Text text={footer} /> : footer}
185
244
  </View>
186
- ) : null}
245
+ )}
187
246
  </View>
247
+
188
248
  </ScrollComponent>
189
249
  </View >
190
- )
191
- }
192
-
193
- Modal.styleRegistryName = 'Modal'
194
- Modal.elements = ['box', 'backdrop', 'innerWrapper', 'scroll', 'body', 'footer', 'header', 'title', 'description', 'closeButton', 'topSpacing']
195
- Modal.rootElement = 'wrapper'
196
250
 
197
- Modal.withVariantTypes = <S extends AnyRecord>(styles: S) => {
198
- return Modal as (props: StyledComponentProps<ModalProps, typeof styles>) => IJSX
251
+ )
199
252
  }
200
253
 
201
254
  Modal.defaultProps = {
202
- closeIconName: 'close' as AppIcon,
203
- closable: true,
204
- dismissOnBackdrop: true,
205
- scroll: true,
206
- closeOnHardwareBackPress: true,
207
- } as Partial<ModalProps>
208
-
209
- MobileStyleRegistry.registerComponent(Modal)
255
+ closeIconName: 'close' as IconPlaceholder,
256
+ }
210
257
 
211
258
  export default Modal
@@ -1,3 +1,7 @@
1
+ import {
2
+ createDefaultVariantFactory,
3
+ includePresets,
4
+ } from '@codeleap/common'
1
5
  import { ActionIconComposition } from '../ActionIcon'
2
6
 
3
7
  export type AnimatableParts = 'box' | 'backdrop'
@@ -23,3 +27,7 @@ export type ModalComposition =
23
27
  | `${AnimatableParts}:visible`
24
28
  | `${AnimatableParts}:hidden`
25
29
  | `${AnimatableParts}:transition`
30
+
31
+ const createModalStyle = createDefaultVariantFactory<ModalComposition>()
32
+
33
+ export const ModalPresets = includePresets((style) => createModalStyle(() => ({ body: style })))
@@ -34,7 +34,6 @@ export const Navigation = <T extends NavigatorType>({ type, scenes, ...props }:
34
34
  options: (optionProps) => ({
35
35
  title,
36
36
  tabBarIcon: (style) => <Icon name={content?.icon} style={style}/>,
37
- tabIcon: content?.icon,
38
37
  tabBarIconFocused: content?.iconFocused ? (style) => <Icon name={content?.iconFocused} style={style}/> : null,
39
38
  ...(TypeGuards.isFunction(content.options) ? content.options(optionProps) : content.options),
40
39
  }),
@@ -1,4 +1,4 @@
1
- import { AppIcon } from '@codeleap/styles'
1
+ import { IconPlaceholder } from '@codeleap/common'
2
2
  import { Navigators } from './constants'
3
3
 
4
4
  export type TNavigators = typeof Navigators
@@ -13,7 +13,7 @@ export type PropTypes = {
13
13
  }
14
14
  export type SceneComponent<K extends NavigatorType> = PropTypes[K]['Screen']
15
15
  export type SceneOptions<K extends NavigatorType> =
16
- { icon?: AppIcon; default?:SceneComponent<K> } & PropTypes[K]['Screen']
16
+ { icon?: IconPlaceholder; default?:SceneComponent<K> } & PropTypes[K]['Screen']
17
17
  export type Scene<K extends NavigatorType> = SceneComponent<K> | SceneOptions<K>
18
18
 
19
19
  export type Scenes<K extends NavigatorType> = {
@@ -26,3 +26,10 @@ export type NavigationProps<T extends NavigatorType> = {
26
26
  type: T
27
27
  scenes: Scenes<T>
28
28
  } & PropTypes[T]['Navigator']
29
+
30
+ // export type NavigationStructure = {
31
+ // [module:string] : {
32
+ // scenes: Scenes,
33
+
34
+ // }
35
+ // }
@@ -1,6 +1,14 @@
1
- import React, { useState, useRef } from 'react'
2
- import { TypeGuards, useValidate } from '@codeleap/common'
1
+ import * as React from 'react'
2
+ import {
3
+ useDefaultComponentStyle,
4
+ TypeGuards,
5
+ useState,
6
+ useRef,
7
+ useValidate,
8
+ IconPlaceholder,
9
+ } from '@codeleap/common'
3
10
  import { forwardRef, useImperativeHandle } from 'react'
11
+ import { NumberIncrementPresets } from './styles'
4
12
  import { InputBase, selectInputBaseProps } from '../InputBase'
5
13
  import { Text } from '../Text'
6
14
  import { MaskedTextInput } from '../../modules/textInputMask'
@@ -8,9 +16,6 @@ import { TextInput as NativeTextInput, TextInputProps as NativeTextInputProps, N
8
16
  import { Touchable } from '../Touchable'
9
17
  import { useActionValidate } from './utils'
10
18
  import { NumberIncrementProps } from './types'
11
- import { AnyRecord, AppIcon, IJSX, StyledComponentProps, StyledComponentWithProps } from '@codeleap/styles'
12
- import { MobileStyleRegistry } from '../../Registry'
13
- import { useStylesFor } from '../../hooks'
14
19
 
15
20
  export * from './styles'
16
21
  export * from './types'
@@ -25,6 +30,22 @@ const defaultParseValue = (_value: string) => {
25
30
  return parseFloat(parsedValue)
26
31
  }
27
32
 
33
+ const defaultProps: Partial<NumberIncrementProps> = {
34
+ max: MAX_VALID_DIGITS,
35
+ min: 0,
36
+ step: 1,
37
+ editable: true,
38
+ separator: null,
39
+ formatter: null,
40
+ parseValue: defaultParseValue,
41
+ delimiter: null,
42
+ mask: null,
43
+ masking: null,
44
+ timeoutActionFocus: 300,
45
+ actionPressAutoFocus: true,
46
+ actionDebounce: null,
47
+ }
48
+
28
49
  export const NumberIncrement = forwardRef<NativeTextInput, NumberIncrementProps>((props, inputRef) => {
29
50
  const {
30
51
  inputBaseProps,
@@ -35,7 +56,9 @@ export const NumberIncrement = forwardRef<NativeTextInput, NumberIncrementProps>
35
56
  })
36
57
 
37
58
  const {
38
- style,
59
+ variants = [],
60
+ style = {},
61
+ styles = {},
39
62
  value,
40
63
  disabled,
41
64
  onChangeText,
@@ -104,29 +127,34 @@ export const NumberIncrement = forwardRef<NativeTextInput, NumberIncrementProps>
104
127
  return false
105
128
  }, [value])
106
129
 
107
- const styles = useStylesFor(NumberIncrement.styleRegistryName, style)
130
+ const variantStyles = useDefaultComponentStyle<'u:NumberIncrement', typeof NumberIncrementPresets>(
131
+ 'u:NumberIncrement',
132
+ {
133
+ variants,
134
+ styles,
135
+ rootElement: 'wrapper',
136
+ },
137
+ )
108
138
 
109
139
  const inputTextStyle = React.useMemo(() => ([
110
- styles.input,
111
- isFocused && styles['input:focus'],
112
- hasError && styles['input:error'],
113
- disabled && styles['input:disabled'],
140
+ variantStyles.input,
141
+ isFocused && variantStyles['input:focus'],
142
+ hasError && variantStyles['input:error'],
143
+ disabled && variantStyles['input:disabled'],
114
144
  ]), [disabled, isFocused, hasError])
115
145
 
116
146
  const placeholderTextColor = [
117
- [disabled, styles['placeholder:disabled']],
118
- [hasError, styles['placeholder:error']],
119
- [isFocused, styles['placeholder:focus']],
120
- [true, styles.placeholder],
121
- // @ts-expect-error
147
+ [disabled, variantStyles['placeholder:disabled']],
148
+ [hasError, variantStyles['placeholder:error']],
149
+ [isFocused, variantStyles['placeholder:focus']],
150
+ [true, variantStyles.placeholder],
122
151
  ].find(([x]) => x)?.[1]?.color
123
152
 
124
153
  const selectionColor = [
125
- [disabled, styles['selection:disabled']],
126
- [!validation.isValid, styles['selection:error']],
127
- [isFocused, styles['selection:focus']],
128
- [true, styles.selection],
129
- // @ts-expect-error
154
+ [disabled, variantStyles['selection:disabled']],
155
+ [!validation.isValid, variantStyles['selection:error']],
156
+ [isFocused, variantStyles['selection:focus']],
157
+ [true, variantStyles.selection],
130
158
  ].find(([x]) => x)?.[1]?.color
131
159
 
132
160
  const onChange = (newValue: number) => {
@@ -229,21 +257,27 @@ export const NumberIncrement = forwardRef<NativeTextInput, NumberIncrementProps>
229
257
  <InputBase
230
258
  {...inputBaseProps}
231
259
  error={hasError ? errorMessage : null}
232
- style={styles}
260
+ styles={{
261
+ ...variantStyles,
262
+ innerWrapper: [
263
+ variantStyles.innerWrapper,
264
+ ],
265
+ }}
233
266
  rightIcon={{
234
- name: 'plus' as AppIcon,
267
+ name: 'plus' as IconPlaceholder,
235
268
  disabled: disabled || incrementDisabled || !editable,
236
269
  onPress: () => handleChange('increment'),
237
270
  debounce: actionDebounce,
238
271
  ...inputBaseProps.rightIcon,
239
272
  }}
240
273
  leftIcon={{
241
- name: 'minus' as AppIcon,
274
+ name: 'minus' as IconPlaceholder,
242
275
  disabled: disabled || decrementDisabled || !editable,
243
276
  onPress: () => handleChange('decrement'),
244
277
  debounce: actionDebounce,
245
278
  ...inputBaseProps.leftIcon,
246
279
  }}
280
+ style={style}
247
281
  disabled={disabled}
248
282
  focused={isFocused}
249
283
  innerWrapper={Touchable}
@@ -279,30 +313,6 @@ export const NumberIncrement = forwardRef<NativeTextInput, NumberIncrementProps>
279
313
  )}
280
314
  </InputBase>
281
315
  )
282
- }) as StyledComponentWithProps<NumberIncrementProps>
283
-
284
- NumberIncrement.styleRegistryName = 'NumberIncrement'
285
- NumberIncrement.elements = [...InputBase.elements, 'input', 'placeholder', 'selection']
286
- NumberIncrement.rootElement = 'wrapper'
287
-
288
- NumberIncrement.withVariantTypes = <S extends AnyRecord>(styles: S) => {
289
- return NumberIncrement as (props: StyledComponentProps<NumberIncrementProps, typeof styles>) => IJSX
290
- }
291
-
292
- NumberIncrement.defaultProps = {
293
- max: MAX_VALID_DIGITS,
294
- min: 0,
295
- step: 1,
296
- editable: true,
297
- separator: null,
298
- formatter: null,
299
- parseValue: defaultParseValue,
300
- delimiter: null,
301
- mask: null,
302
- masking: null,
303
- timeoutActionFocus: 300,
304
- actionPressAutoFocus: true,
305
- actionDebounce: null,
306
- } as Partial<NumberIncrementProps>
316
+ })
307
317
 
308
- MobileStyleRegistry.registerComponent(NumberIncrement)
318
+ NumberIncrement.defaultProps = defaultProps
@@ -1,3 +1,4 @@
1
+ import { createDefaultVariantFactory, includePresets } from '@codeleap/common'
1
2
  import { InputBaseParts, InputBaseStates } from '../InputBase'
2
3
 
3
4
  export type NumberIncrementParts = InputBaseParts | 'input' | 'placeholder' | 'selection'
@@ -7,3 +8,7 @@ export type NumberIncrementStates = InputBaseStates
7
8
  export type NumberIncrementComposition =
8
9
  | NumberIncrementParts
9
10
  | `${NumberIncrementParts}:${NumberIncrementStates}`
11
+
12
+ const createNumberIncrementStyle = createDefaultVariantFactory<NumberIncrementComposition>()
13
+
14
+ export const NumberIncrementPresets = includePresets((styles) => createNumberIncrementStyle(() => ({ wrapper: styles })))
@@ -1,37 +1,44 @@
1
- import { yup, FormTypes, AnyFunction } from '@codeleap/common'
2
- import { NumberIncrementComposition } from './styles'
1
+ import {
2
+ ComponentVariants,
3
+ yup,
4
+ StylesOf,
5
+ PropsOf,
6
+ FormTypes,
7
+ } from '@codeleap/common'
8
+ import { NumberIncrementPresets, NumberIncrementComposition } from './styles'
3
9
  import { TextInputMaskProps } from '../../modules/textInputMask'
4
- import { TextInputProps as RNTextInputProps } from 'react-native'
10
+ import { TextInputProps as NativeTextInputProps } from 'react-native'
11
+ import { View } from '../View'
12
+ import { Touchable } from '../Touchable'
5
13
  import { InputBaseProps } from '../InputBase'
6
- import { StyledProp } from '@codeleap/styles'
7
14
 
8
15
  type Masking = FormTypes.TextField['masking']
9
- type MaskOptions = Masking['options']
16
+ type MaskOptions = Masking['options']
10
17
 
11
- export type NumberIncrementProps =
12
- Omit<InputBaseProps, 'style'> &
13
- Omit<RNTextInputProps, 'style'> &
14
- {
15
- value: number
16
- validate?: FormTypes.ValidatorWithoutForm<string> | yup.SchemaOf<string>
17
- max?: number
18
- min?: number
19
- step?: number
20
- editable?: boolean
21
- _error?: string
22
- placeholder?: string
23
- onChangeMask?: TextInputMaskProps['onChangeText']
24
- masking?: Exclude<Masking, 'mask' | 'format'>
25
- prefix?: MaskOptions['unit']
26
- suffix?: MaskOptions['suffixUnit']
27
- separator?: MaskOptions['separator']
28
- delimiter?: MaskOptions['delimiter']
29
- mask?: MaskOptions['mask']
30
- formatter?: (value: string | number) => string
31
- parseValue?: (value: string) => number
32
- timeoutActionFocus?: number
33
- actionPressAutoFocus?: boolean
34
- actionDebounce?: number | null
35
- onPress?: AnyFunction
36
- style?: StyledProp<NumberIncrementComposition>
37
- }
18
+ export type NumberIncrementProps =
19
+ Omit<InputBaseProps, 'styles' | 'variants'> &
20
+ NativeTextInputProps & {
21
+ variants?: ComponentVariants<typeof NumberIncrementPresets>['variants']
22
+ styles?: StylesOf<NumberIncrementComposition>
23
+ value: number
24
+ validate?: FormTypes.ValidatorWithoutForm<string> | yup.SchemaOf<string>
25
+ style?: PropsOf<typeof View>['style']
26
+ max?: number
27
+ min?: number
28
+ step?: number
29
+ editable?: boolean
30
+ _error?: string
31
+ placeholder?: string
32
+ onChangeMask?: TextInputMaskProps['onChangeText']
33
+ masking?: Exclude<Masking, 'mask' | 'format'>
34
+ prefix?: MaskOptions['unit']
35
+ suffix?: MaskOptions['suffixUnit']
36
+ separator?: MaskOptions['separator']
37
+ delimiter?: MaskOptions['delimiter']
38
+ mask?: MaskOptions['mask']
39
+ formatter?: (value: string | number) => string
40
+ parseValue?: (value: string) => number
41
+ timeoutActionFocus?: number
42
+ actionPressAutoFocus?: boolean
43
+ actionDebounce?: number | null
44
+ } & Pick<PropsOf<typeof Touchable>, 'onPress'>