@codeleap/mobile 2.0.1 → 2.0.4

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 (108) hide show
  1. package/dist/components/ActionIcon/index.js +2 -1
  2. package/dist/components/ActionIcon/index.js.map +1 -1
  3. package/dist/components/ActionIcon/styles.d.ts +58 -58
  4. package/dist/components/Backdrop/index.js +1 -1
  5. package/dist/components/Backdrop/index.js.map +1 -1
  6. package/dist/components/Button/index.d.ts +109 -109
  7. package/dist/components/Button/index.js +5 -7
  8. package/dist/components/Button/index.js.map +1 -1
  9. package/dist/components/Button/styles.d.ts +60 -55
  10. package/dist/components/Button/styles.js +4 -2
  11. package/dist/components/Button/styles.js.map +1 -1
  12. package/dist/components/Checkbox/index.js +4 -2
  13. package/dist/components/Checkbox/index.js.map +1 -1
  14. package/dist/components/Checkbox/styles.d.ts +1 -1
  15. package/dist/components/Checkbox/styles.js +4 -0
  16. package/dist/components/Checkbox/styles.js.map +1 -1
  17. package/dist/components/FileInput/index.d.ts +1 -1
  18. package/dist/components/Image/index.js +3 -0
  19. package/dist/components/Image/index.js.map +1 -1
  20. package/dist/components/Modal/index.js +1 -1
  21. package/dist/components/Modal/index.js.map +1 -1
  22. package/dist/components/MultiSelect/styles.js +1 -4
  23. package/dist/components/MultiSelect/styles.js.map +1 -1
  24. package/dist/components/Navigation/utils.js +0 -1
  25. package/dist/components/Navigation/utils.js.map +1 -1
  26. package/dist/components/Pager/styles.js +13 -11
  27. package/dist/components/Pager/styles.js.map +1 -1
  28. package/dist/components/RadioInput/index.js +3 -1
  29. package/dist/components/RadioInput/index.js.map +1 -1
  30. package/dist/components/RadioInput/styles.d.ts +1 -1
  31. package/dist/components/RadioInput/styles.js +1 -0
  32. package/dist/components/RadioInput/styles.js.map +1 -1
  33. package/dist/components/SegmentedControl/index.d.ts +10 -1
  34. package/dist/components/SegmentedControl/index.js +27 -27
  35. package/dist/components/SegmentedControl/index.js.map +1 -1
  36. package/dist/components/SegmentedControl/styles.d.ts +56 -51
  37. package/dist/components/SegmentedControl/styles.js +10 -3
  38. package/dist/components/SegmentedControl/styles.js.map +1 -1
  39. package/dist/components/Select/index.js +1 -2
  40. package/dist/components/Select/index.js.map +1 -1
  41. package/dist/components/Select/styles.d.ts +1 -1
  42. package/dist/components/Select/styles.js +4 -1
  43. package/dist/components/Select/styles.js.map +1 -1
  44. package/dist/components/Switch/index.js +1 -1
  45. package/dist/components/Switch/index.js.map +1 -1
  46. package/dist/components/Text/index.d.ts +2 -0
  47. package/dist/components/Text/index.js +43 -3
  48. package/dist/components/Text/index.js.map +1 -1
  49. package/dist/components/Text/styles.d.ts +57 -52
  50. package/dist/components/Text/styles.js +11 -3
  51. package/dist/components/Text/styles.js.map +1 -1
  52. package/dist/components/TextInput/index.d.ts +8 -4
  53. package/dist/components/TextInput/index.js +37 -17
  54. package/dist/components/TextInput/index.js.map +1 -1
  55. package/dist/components/TextInput/styles.d.ts +1 -1
  56. package/dist/components/TextInput/styles.js +11 -3
  57. package/dist/components/TextInput/styles.js.map +1 -1
  58. package/dist/components/Touchable/index.d.ts +1 -1
  59. package/dist/components/Touchable/index.js +81 -43
  60. package/dist/components/Touchable/index.js.map +1 -1
  61. package/dist/components/Touchable/styles.d.ts +56 -51
  62. package/dist/components/Touchable/styles.js +6 -1
  63. package/dist/components/Touchable/styles.js.map +1 -1
  64. package/dist/components/defaultStyles.d.ts +263 -263
  65. package/dist/utils/KeyboardAware/lib/KeyboardAwareHOC.d.ts +2 -0
  66. package/dist/utils/KeyboardAware/lib/KeyboardAwareHOC.js +287 -286
  67. package/dist/utils/KeyboardAware/lib/KeyboardAwareHOC.js.map +1 -1
  68. package/dist/utils/OSAlert.d.ts +6 -5
  69. package/dist/utils/OSAlert.js +7 -6
  70. package/dist/utils/OSAlert.js.map +1 -1
  71. package/dist/utils/hooks.d.ts +34 -1
  72. package/dist/utils/hooks.js +54 -1
  73. package/dist/utils/hooks.js.map +1 -1
  74. package/dist/utils/index.d.ts +1 -1
  75. package/dist/utils/index.js +2 -6
  76. package/dist/utils/index.js.map +1 -1
  77. package/dist/utils/notifications.js +4 -4
  78. package/dist/utils/notifications.js.map +1 -1
  79. package/package.json +1 -1
  80. package/src/components/ActionIcon/index.tsx +2 -1
  81. package/src/components/Backdrop/index.tsx +1 -1
  82. package/src/components/Button/index.tsx +7 -11
  83. package/src/components/Button/styles.ts +34 -10
  84. package/src/components/Checkbox/index.tsx +4 -1
  85. package/src/components/Checkbox/styles.ts +5 -0
  86. package/src/components/Image/index.tsx +3 -0
  87. package/src/components/Modal/index.tsx +1 -1
  88. package/src/components/MultiSelect/styles.ts +1 -8
  89. package/src/components/Navigation/utils.tsx +0 -2
  90. package/src/components/Pager/styles.ts +16 -11
  91. package/src/components/RadioInput/index.tsx +3 -1
  92. package/src/components/RadioInput/styles.ts +2 -1
  93. package/src/components/SegmentedControl/index.tsx +31 -18
  94. package/src/components/SegmentedControl/styles.ts +29 -7
  95. package/src/components/Select/index.tsx +2 -1
  96. package/src/components/Select/styles.ts +12 -2
  97. package/src/components/Switch/index.tsx +1 -1
  98. package/src/components/Text/index.tsx +57 -7
  99. package/src/components/Text/styles.ts +25 -9
  100. package/src/components/TextInput/index.tsx +48 -9
  101. package/src/components/TextInput/styles.ts +14 -4
  102. package/src/components/Touchable/index.tsx +90 -36
  103. package/src/components/Touchable/styles.ts +15 -3
  104. package/src/utils/KeyboardAware/lib/KeyboardAwareHOC.tsx +34 -24
  105. package/src/utils/OSAlert.ts +10 -10
  106. package/src/utils/hooks.ts +82 -2
  107. package/src/utils/index.ts +2 -2
  108. package/src/utils/notifications.ts +4 -4
@@ -3,8 +3,6 @@ import { Navigation } from './Navigation'
3
3
 
4
4
  export function createAppNavigation(Scenes:any) {
5
5
 
6
- console.log('Creating app navigation', { Scenes }, 'PACKAGES')
7
-
8
6
  const AllScenes = Object.entries<any>(Scenes).reduce((allScenes, [moduleName, content]) => {
9
7
 
10
8
  const subScenes = []
@@ -51,17 +51,22 @@ export function pagerAnimation(height, width, translate = 'X', transition = defa
51
51
 
52
52
  export const PagerStyles = {
53
53
  ...presets,
54
- default: createPagerStyle((theme) => ({
55
- page: {
56
- width: '100%',
57
- height: '100%',
58
- position: 'absolute',
59
- left: 0,
60
- right: 0,
61
- bottom: 0,
62
- top: 0,
63
- },
64
- })),
54
+ default: createPagerStyle((theme) => {
55
+ const width = theme.values.width
56
+ const height = theme.values.height * 0.8
57
+ return {
58
+ ...pagerAnimation(height, width, 'X'),
59
+ page: {
60
+ width: '100%',
61
+ height: '100%',
62
+ position: 'absolute',
63
+ left: 0,
64
+ right: 0,
65
+ bottom: 0,
66
+ top: 0,
67
+ },
68
+ }
69
+ }),
65
70
  horizontal: createPagerStyle((Theme) => {
66
71
 
67
72
  const width = Theme.values.width
@@ -47,7 +47,9 @@ export const RadioButton: React.FC<RadioButtonProps> = ({
47
47
  ...props
48
48
  }) => {
49
49
  return (
50
- <Touchable onPress={select} style={style.itemWrapper} debugName={'Change radioButton value'}>
50
+ <Touchable onPress={select} style={style.itemWrapper} debugName={'Change radioButton value'} styles={{
51
+ feedback: style.buttonFeedback,
52
+ }}>
51
53
  <View style={[style.button, checked && style['button:checked']]}>
52
54
  <View
53
55
  style={[style.buttonMark, checked && style['buttonMark:checked']]}
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createDefaultVariantFactory, includePresets,
3
3
  } from '@codeleap/common'
4
- type RadioParts = 'button' | 'itemWrapper' | 'text' | 'buttonMark'
4
+ type RadioParts = 'button' | 'itemWrapper' | 'text' | 'buttonMark' | 'buttonFeedback'
5
5
 
6
6
  type RadioGroupParts = 'label' | 'wrapper' | 'list'
7
7
 
@@ -37,6 +37,7 @@ export const RadioInputStyles = {
37
37
  position: 'relative',
38
38
  ...theme.spacing.marginRight(1),
39
39
  },
40
+ buttonFeedback: { type: 'opacity', value: 0.5 },
40
41
  buttonMark: {
41
42
  backgroundColor: theme.colors.primary,
42
43
  position: 'absolute',
@@ -1,12 +1,12 @@
1
1
  import React, { ReactElement, useImperativeHandle, useMemo, useRef } from 'react'
2
2
  import { Scroll, ScrollProps } from '../Scroll'
3
3
 
4
- import { EasingFunction, StyleSheet } from 'react-native'
4
+ import { Easing, EasingFunction, StyleSheet } from 'react-native'
5
5
  import { PropsOf, useCodeleapContext, useDefaultComponentStyle } from '@codeleap/common'
6
6
  import { SegmentedControlComposition, SegmentedControlStyles } from './styles'
7
7
  import { Touchable } from '../Touchable'
8
8
  import { StylesOf } from '../../types/utility'
9
- import { Text } from '../Text'
9
+ import { Text, TextProps } from '../Text'
10
10
  import { KeyboardAwareScrollViewTypes } from '../../modules'
11
11
  import { View } from '../View'
12
12
  export * from './styles'
@@ -24,6 +24,8 @@ export type SegmentedControlProps<T = string> = ScrollProps & {
24
24
  duration?: number
25
25
  easing?: EasingFunction
26
26
  }
27
+ textProps?: Partial<PropsOf<typeof Text>>
28
+ touchableProps?: Partial<PropsOf<typeof Touchable>>
27
29
  styles?: StylesOf<SegmentedControlComposition>
28
30
  scrollProps?: any
29
31
  RenderButton?: (props: SegmentedControlProps & {
@@ -31,12 +33,14 @@ export type SegmentedControlProps<T = string> = ScrollProps & {
31
33
  textProps: PropsOf<typeof Text>
32
34
  option: {label: string; value: any}
33
35
  }) => ReactElement
34
- RenderAnimatedView?: (props: SegmentedControlProps) => ReactElement
36
+ RenderAnimatedView?: (props: Partial<SegmentedControlProps>) => ReactElement
37
+ getItemWidth?: (item:{label: string; value: T }, idx: number, arr: {label: string; value: T }[]) => number
35
38
  }
36
39
 
37
40
  const defaultAnimation = {
41
+ type: 'timing',
38
42
  duration: 200,
39
- // easing: Easing.linear,
43
+ easing: Easing.linear,
40
44
  }
41
45
 
42
46
  const _SegmentedControl = React.forwardRef<SegmentedControlRef, SegmentedControlProps>((props, ref) => {
@@ -49,13 +53,13 @@ const _SegmentedControl = React.forwardRef<SegmentedControlRef, SegmentedControl
49
53
  animation = {},
50
54
  variants = [],
51
55
  scrollProps = {},
56
+ getItemWidth = (i) => i.label.length * 20,
52
57
  RenderAnimatedView,
53
58
  RenderButton,
54
-
59
+ ...viewProps
55
60
  } = props
56
- const { Theme } = useCodeleapContext()
57
61
 
58
- const _animation = {
62
+ let _animation = {
59
63
  ...defaultAnimation, ...animation,
60
64
  }
61
65
 
@@ -75,14 +79,10 @@ const _SegmentedControl = React.forwardRef<SegmentedControlRef, SegmentedControl
75
79
  }
76
80
 
77
81
  const widthStyle = useMemo(() => {
78
- const maxWordLength = Object.assign([], options)
79
- .sort((a, b) => {
80
- return a.label.length - b.label.length
81
- })[0].label.length
82
- const fitMaxWidth = Theme.values.width - Theme.spacing.value(4)
83
- let fitItemWidth = maxWordLength * options.length * 6
84
- if (fitItemWidth * options.length < fitMaxWidth) fitItemWidth = fitMaxWidth / options.length
85
- return { width: fitItemWidth }
82
+ const sizes = options.map(getItemWidth)
83
+ const maxWidth = sizes.sort((a, b) => b - a)[0]
84
+
85
+ return { width: maxWidth }
86
86
  }, [options])
87
87
 
88
88
  const currentOptionIdx = options.findIndex(o => o.value === value) || 0
@@ -118,6 +118,7 @@ const _SegmentedControl = React.forwardRef<SegmentedControlRef, SegmentedControl
118
118
 
119
119
  const AnimatedView = RenderAnimatedView || View
120
120
  variantStyles = JSON.parse(JSON.stringify(variantStyles))
121
+ _animation = JSON.parse(JSON.stringify(_animation))
121
122
  return (
122
123
  <Scroll
123
124
  horizontal
@@ -128,14 +129,19 @@ const _SegmentedControl = React.forwardRef<SegmentedControlRef, SegmentedControl
128
129
  ref={scrollRef}
129
130
  >
130
131
  <View style={variantStyles.wrapper}>
131
- <AnimatedView {...props}
132
+ <AnimatedView
133
+ options={options}
134
+ styles={variantStyles}
135
+
132
136
  animated
133
137
  style={[variantStyles.selectedBubble, widthStyle]}
134
138
  animate={{
135
139
  translateX,
136
140
  }}
141
+ transition={{
142
+ translateX: _animation,
143
+ }}
137
144
 
138
- transition={_animation}
139
145
  />
140
146
  {options.map((o, idx) => {
141
147
  const selected = value === o.value
@@ -145,13 +151,16 @@ const _SegmentedControl = React.forwardRef<SegmentedControlRef, SegmentedControl
145
151
  debugName: `Segmented Control ${debugName}, option ${o.label}`,
146
152
  onPress: onPress(o.value, idx),
147
153
  style: [widthStyle, variantStyles.button],
154
+ ...props.touchableProps,
155
+
148
156
  }
149
157
 
150
- const textProps = {
158
+ const textProps:TextProps = {
151
159
  text: o.label as string,
152
160
  colorChangeConfig: _animation,
153
161
  style: StyleSheet.flatten([variantStyles.text, selected && variantStyles['text:selected']]),
154
162
  animated: true,
163
+ ...props.textProps,
155
164
  }
156
165
 
157
166
  if (RenderButton) {
@@ -161,7 +170,11 @@ const _SegmentedControl = React.forwardRef<SegmentedControlRef, SegmentedControl
161
170
  }
162
171
  return <Touchable
163
172
  {...touchableProps}
173
+ noFeedback={selected}
164
174
  key={touchableProps.key}
175
+ styles={{
176
+ feedback: variantStyles.buttonFeedback,
177
+ }}
165
178
  >
166
179
  <Text
167
180
 
@@ -1,4 +1,5 @@
1
- import { createDefaultVariantFactory, includePresets } from '@codeleap/common'
1
+ import { createDefaultVariantFactory, includePresets, StylesOf } from '@codeleap/common'
2
+ import { TouchableStylesGen } from '../Touchable'
2
3
 
3
4
  export type SegmentedControlStates = 'selected'
4
5
 
@@ -10,9 +11,20 @@ export type SegmentedControlComposition =
10
11
  'text' |
11
12
  `text:${SegmentedControlStates}` |
12
13
  'button' |
14
+ 'buttonFeedback' |
13
15
  `button:${SegmentedControlStates}`
14
16
 
15
- const createSegmentedControlStyle = createDefaultVariantFactory<SegmentedControlComposition>()
17
+ export type SegmentedControlStylesGen<TCSS = any> =
18
+ StylesOf<
19
+ Exclude<SegmentedControlComposition, 'buttonFeedback'>
20
+ > & {
21
+ buttonFeedback?: TouchableStylesGen['feedback']
22
+ }
23
+
24
+ const createSegmentedControlStyle = createDefaultVariantFactory<
25
+ SegmentedControlComposition,
26
+ SegmentedControlStylesGen
27
+ >()
16
28
 
17
29
  const presets = includePresets((style) => createSegmentedControlStyle(() => ({ scrollContent: style })))
18
30
 
@@ -21,7 +33,10 @@ export const SegmentedControlStyles = {
21
33
  default: createSegmentedControlStyle((theme) => {
22
34
 
23
35
  return {
24
-
36
+ buttonFeedback: {
37
+ type: 'opacity',
38
+ value: 0.5,
39
+ },
25
40
  text: {
26
41
  color: theme.colors.text,
27
42
  },
@@ -34,21 +49,28 @@ export const SegmentedControlStyles = {
34
49
  },
35
50
  scrollContent: {
36
51
  // borderRadius: Theme.borderRadius.large,
52
+ ...theme.presets.row,
37
53
  ...theme.spacing.paddingHorizontal(2),
54
+ ...theme.presets.alignStretch,
38
55
  },
39
56
  button: {
40
57
  backgroundColor: 'transparent',
41
58
  ...theme.presets.alignCenter,
42
- color: 'red',
43
- ...theme.spacing.padding(2),
44
59
  ...theme.presets.justifyCenter,
60
+
61
+ borderRadius: theme.borderRadius.large,
62
+ ...theme.spacing.padding(1),
63
+ minHeight: '100%',
64
+
45
65
  },
46
66
  selectedBubble: {
47
67
  position: 'absolute',
48
68
  zIndex: -1,
49
69
  ...theme.spacing.padding(2),
50
- maxHeight: 50,
51
- minHeight: 50,
70
+ // maxHeight: 50,
71
+ // minHeight: 50,
72
+ top: 0,
73
+ bottom: 0,
52
74
  borderRadius: theme.borderRadius.large,
53
75
  backgroundColor: theme.colors.primary,
54
76
  },
@@ -97,9 +97,10 @@ export const Select = <T extends string|number = string>(selectProps:CustomSelec
97
97
  }}
98
98
  editable={false}
99
99
  touchableWrapper
100
+ onPress={close}
100
101
  wrapperProps={{
101
102
  debugName: 'Select',
102
- onPress: close,
103
+
103
104
  }}
104
105
  pointerEvents={'none'}
105
106
  label={label}
@@ -9,7 +9,8 @@ export type SelectComposition =
9
9
  `itemWrapper${ItemStates}` |
10
10
  `itemText${ItemStates}` |
11
11
  'scroll' |
12
- 'scrollContent'
12
+ 'scrollContent' |
13
+ `itemIcon${ItemStates}`
13
14
 
14
15
  const createSelectStyle = createDefaultVariantFactory<SelectComposition>()
15
16
 
@@ -24,10 +25,11 @@ export const SelectStyles = {
24
25
 
25
26
  },
26
27
  itemWrapper: {
27
- ...theme.spacing.padding(2),
28
28
  ...theme.presets.row,
29
29
  ...theme.presets.justifySpaceBetween,
30
30
  ...theme.presets.alignCenter,
31
+ ...theme.spacing.padding(1.4),
32
+ height: 50,
31
33
  },
32
34
  'itemWrapper:selected': {
33
35
  backgroundColor: theme.colors.primary,
@@ -36,6 +38,14 @@ export const SelectStyles = {
36
38
  color: theme.colors.white,
37
39
 
38
40
  },
41
+ 'itemIcon:selected': {
42
+ color: theme.colors.white,
43
+ ...theme.sized(3),
44
+ },
45
+ itemIcon: {
46
+ width: 0,
47
+ height: 0,
48
+ },
39
49
  list: {
40
50
  height: 'auto',
41
51
 
@@ -79,7 +79,7 @@ export const Switch = forwardRef<NativeSwitch, SwitchProps>(
79
79
  />
80
80
  <InputLabel label={label} style={getStyles('label')} />
81
81
  </View>
82
- <FormError message={error.message} style={getStyles('error')} />
82
+ <FormError text={error.message} style={getStyles('error')} />
83
83
  </View>
84
84
  )
85
85
  },
@@ -4,12 +4,14 @@ import {
4
4
  ComponentVariants,
5
5
  useDefaultComponentStyle,
6
6
  BaseViewProps,
7
-
7
+ TypeGuards,
8
+ useState,
8
9
  } from '@codeleap/common'
9
- import { Animated, StyleSheet, Text as NativeText } from 'react-native'
10
+ import { Animated, GestureResponderEvent, Platform, StyleSheet, Text as NativeText } from 'react-native'
10
11
  import { MotiText as _MotiText, MotiProps } from 'moti'
11
- import { useAnimateColor } from '../../utils'
12
+ import { useAnimateColor, usePressableFeedback } from '../../utils'
12
13
  import { TextStyles } from './styles'
14
+ import { View } from '../View'
13
15
 
14
16
  export * from './styles'
15
17
 
@@ -18,6 +20,7 @@ export type TextProps = ComponentPropsWithoutRef<typeof NativeText> & {
18
20
  variants?: ComponentVariants<typeof TextStyles>['variants']
19
21
  animated?: boolean
20
22
  colorChangeConfig?: Partial<Animated.TimingAnimationConfig>
23
+ debugName?: string
21
24
  } & BaseViewProps & MotiProps
22
25
 
23
26
  const MotiText = Animated.createAnimatedComponent(_MotiText)
@@ -25,8 +28,21 @@ const MotiText = Animated.createAnimatedComponent(_MotiText)
25
28
  export const Text = forwardRef<NativeText, TextProps>((textProps, ref) => {
26
29
  const { variants = [], text, children, style, colorChangeConfig, ...props } = textProps
27
30
 
28
- const variantStyles = useDefaultComponentStyle('Text', {
31
+ const pressPolyfillEnabled = Platform.OS === 'android' && !!props.onPress
32
+
33
+ const [pressed, setPressed] = useState(false)
34
+ const handlePress = (pressed) => {
35
+ if (!pressPolyfillEnabled) return
36
+ return () => {
37
+ if (props.onPress) {
38
+ setPressed(pressed)
39
+
40
+ }
41
+ }
42
+ }
43
+ const variantStyles = useDefaultComponentStyle<'u:Text', typeof TextStyles>('u:Text', {
29
44
  variants,
45
+ transform: StyleSheet.flatten,
30
46
  rootElement: 'text',
31
47
  })
32
48
 
@@ -34,14 +50,48 @@ export const Text = forwardRef<NativeText, TextProps>((textProps, ref) => {
34
50
 
35
51
  const animatedColor = useAnimateColor(styles.color, colorChangeConfig)
36
52
 
53
+ if (!!text && !TypeGuards.isString(text)) return <>{text}</>
54
+
37
55
  const Component = textProps.animated ? MotiText : NativeText
38
56
 
39
57
  const colorStyle = { color: props.animated ? animatedColor : styles.color }
40
58
 
41
- // @ts-ignore
42
- return <Component {...props} style={[styles, colorStyle]} ref={ref}>
43
- {text || children}
59
+ const { getFeedbackStyle } = usePressableFeedback(styles, {
60
+ disabled: !pressPolyfillEnabled,
61
+ feedbackConfig: variantStyles.pressFeedback,
62
+ hightlightPropertyIn: 'color',
63
+ hightlightPropertyOut: 'backgroundColor',
64
+ })
65
+ const feedbackStyle = pressPolyfillEnabled ? getFeedbackStyle(pressed) : undefined
66
+
67
+ return <Component {...props}
68
+ onPressIn={handlePress(true)} onPressOut={handlePress(false)}
69
+ style={[styles, colorStyle, feedbackStyle]}
70
+ // @ts-ignore
71
+ ref={ref}
72
+ >
73
+ {text}
74
+ {children}
44
75
  </Component>
45
76
 
46
77
  })
47
78
 
79
+ // const childArr = React.Children.toArray([
80
+ // text,
81
+ // children,
82
+ // ])
83
+
84
+ // return <View style={[styles, colorStyle]}>
85
+ // {
86
+ // childArr.map((child) => {
87
+ // if (TypeGuards.isString(child)) {
88
+ // // @ts-ignore
89
+ // return <Component {...props} ref={ref}>
90
+ // {child}
91
+ // </Component>
92
+
93
+ // }
94
+ // return child
95
+ // })
96
+ // }
97
+ // </View>
@@ -1,19 +1,35 @@
1
- import { assignTextStyle, createDefaultVariantFactory, includePresets } from '@codeleap/common'
1
+ import { assignTextStyle, createDefaultVariantFactory, includePresets, shadeColor, StylesOf } from '@codeleap/common'
2
+ import { FeedbackConfig } from '../../utils'
2
3
 
3
- export type TextComposition = 'text'
4
- const createTextStyle = createDefaultVariantFactory<TextComposition>()
4
+ export type TextComposition = 'text' | 'touchFeedback'
5
+
6
+ export type TextStylesGen<TCSS = any> = StylesOf<'text', TCSS> & {
7
+ 'pressFeedback'?: FeedbackConfig
8
+ }
9
+
10
+ const createTextStyle = createDefaultVariantFactory<
11
+ TextComposition, TextStylesGen
12
+ >()
5
13
 
6
14
  const presets = includePresets((styles) => createTextStyle(() => ({ text: styles })),
7
15
  )
8
16
 
9
17
  export const TextStyles = {
10
18
  ...presets,
11
- default: createTextStyle((theme) => ({
12
- text: {
13
- fontFamily: theme.typography.fontFamily,
14
- ...assignTextStyle('p1')(theme).text,
15
- },
16
- })),
19
+ default: createTextStyle((theme) => {
20
+ const defaultStyle = assignTextStyle('p1')(theme).text
21
+ return {
22
+ text: {
23
+ fontFamily: theme.typography.fontFamily,
24
+ ...defaultStyle,
25
+ },
26
+ pressFeedback: {
27
+ type: 'highlight',
28
+ brightness: 0,
29
+ shiftOpacity: 0.3,
30
+ },
31
+ }
32
+ }),
17
33
  h1: assignTextStyle('h1'),
18
34
  h2: assignTextStyle('h2'),
19
35
  h3: assignTextStyle('h3'),
@@ -5,12 +5,14 @@ import {
5
5
  getNestedStylesByKey,
6
6
  IconPlaceholder,
7
7
 
8
+ TypeGuards,
9
+
8
10
  useBooleanToggle,
9
11
  useDefaultComponentStyle,
10
12
  useValidate,
11
13
  } from '@codeleap/common'
12
14
  import { ComponentPropsWithoutRef, forwardRef, useImperativeHandle, useRef, useState } from 'react'
13
- import { Text } from '../Text'
15
+ import { Text, TextProps } from '../Text'
14
16
  import { View, ViewProps } from '../View'
15
17
  import { StylesOf } from '../../types'
16
18
  import { Icon } from '../Icon'
@@ -34,6 +36,11 @@ type IconProp = { name: IconPlaceholder; action?: () => void }
34
36
 
35
37
  type NativeProps = ComponentPropsWithoutRef<typeof NativeTextInput>
36
38
 
39
+ type SubtitleProps = {
40
+ errorProps: TextProps
41
+ styles: Record<'wrapper'|'error'|'subtitle', any>
42
+ }
43
+
37
44
  export type TextInputProps =
38
45
  Partial<TextInputMaskProps> &
39
46
  ComponentVariants<typeof TextInputStyles> &
@@ -54,6 +61,7 @@ export type TextInputProps =
54
61
  password?: boolean
55
62
  visibilityToggle?: boolean
56
63
  touchableWrapper?: boolean
64
+ subtitle?: string | ((props: SubtitleProps) => React.ReactElement)
57
65
  onPress?: () => void
58
66
  masking?: FormTypes.TextField['masking']
59
67
  innerWrapperProps?: ViewProps
@@ -82,6 +90,7 @@ export const TextInput = forwardRef<NativeTextInput, TextInputProps>((rawprops,
82
90
  visibilityToggle,
83
91
  innerWrapperProps,
84
92
  masking = null,
93
+ subtitle = '',
85
94
  onChangeMask,
86
95
  debugName,
87
96
  required = false,
@@ -144,7 +153,7 @@ export const TextInput = forwardRef<NativeTextInput, TextInputProps>((rawprops,
144
153
  isFocused ? variantStyles[key + ':focus'] : {},
145
154
  showError ? variantStyles[key + ':error'] : {},
146
155
  ]
147
- return requestedStyles
156
+ return StyleSheet.flatten(requestedStyles)
148
157
  }
149
158
 
150
159
  function handlePress() {
@@ -161,6 +170,19 @@ export const TextInput = forwardRef<NativeTextInput, TextInputProps>((rawprops,
161
170
  debugName: `${debugName} toggle visibility`,
162
171
  } : {}
163
172
 
173
+ const subtitleStyles = {
174
+ error: getStyles('error'),
175
+ wrapper: getStyles('subtitleWrapper'),
176
+ subtitle: getStyles('subtitle'),
177
+
178
+ }
179
+ const errorProps = { text: error.message, style: subtitleStyles.error }
180
+
181
+ const subtitleContent = TypeGuards.isFunction(subtitle) ? subtitle({ styles: subtitleStyles, errorProps }) : <View style={subtitleStyles.wrapper}>
182
+ <FormError {...errorProps}/>
183
+ {TypeGuards.isString(subtitle) ? <Text text={subtitle} style={subtitleStyles.subtitle}/> : (subtitle || null)}
184
+ </View>
185
+
164
186
  return (
165
187
  <Touchable
166
188
  style={getStyles('wrapper')}
@@ -168,6 +190,7 @@ export const TextInput = forwardRef<NativeTextInput, TextInputProps>((rawprops,
168
190
  onPress={handlePress}
169
191
  {...wrapperProps}
170
192
  android_ripple={null}
193
+ noFeedback
171
194
  >
172
195
  <InputLabel
173
196
  label={label}
@@ -183,6 +206,8 @@ export const TextInput = forwardRef<NativeTextInput, TextInputProps>((rawprops,
183
206
  styles={leftIconStyles}
184
207
  commonStyles={commonIconStyles}
185
208
  debugName={`${debugName} left icon`}
209
+ onPress={() => {}}
210
+ noFeedback={!leftIcon.onPress}
186
211
  {...leftIcon}
187
212
  />
188
213
  {/* @ts-ignore */}
@@ -209,22 +234,34 @@ export const TextInput = forwardRef<NativeTextInput, TextInputProps>((rawprops,
209
234
  styles={rightIconStyles}
210
235
  commonStyles={commonIconStyles}
211
236
  debugName={`${debugName} right icon`}
237
+ onPress={() => {}}
238
+ noFeedback={!rightIcon?.onPress}
212
239
  {...rightIcon}
213
240
  {...visibilityToggleProps}
214
241
  />
215
242
 
216
243
  </View>
217
- <FormError message={error.message} style={getStyles('error')} />
244
+ {subtitleContent}
218
245
  </Touchable>
219
246
  )
220
247
  })
221
248
 
222
- export const FormError = ({ message, ...props }) => {
223
- if (['number', 'string', 'undefined'].includes(typeof message)) {
249
+ export const FormError:React.FC<TextProps> = ({ text, ...props }) => {
250
+ let message = text
251
+ if (TypeGuards.isNumber(message)) {
252
+ message = message.toString()
253
+ }
254
+ if (typeof message === 'undefined') {
255
+ message = ''
256
+ }
257
+
258
+ if (TypeGuards.isString(message)) {
224
259
  const text = message ? `${message.charAt(0).toUpperCase() + message.slice(1)}` : ' '
225
- return <Text text={text} variants={['p2', 'marginTop:1']} {...props} />
260
+ return <Text text={text} {...props} />
226
261
  }
227
- return message
262
+ return <>
263
+ {text}
264
+ </>
228
265
  }
229
266
 
230
267
  type InputIconProps = {
@@ -237,7 +274,8 @@ type InputIconProps = {
237
274
  export const InputIcon:React.FC<InputIconProps> = ({ styles, commonStyles, isFocused, showError, ...props }) => {
238
275
  if (!props.icon) return null
239
276
 
240
- function getStyles(key: ActionIconParts | '') {
277
+ function getStyles(k: ActionIconParts | '') {
278
+ let key = k
241
279
  if (key === 'icon') key = ''
242
280
  const requestedStyles = [
243
281
  commonStyles[key],
@@ -247,13 +285,14 @@ export const InputIcon:React.FC<InputIconProps> = ({ styles, commonStyles, isFoc
247
285
  isFocused ? styles[key + ':focus'] : {},
248
286
  showError ? styles[key + ':error'] : {},
249
287
  ]
288
+
250
289
  return StyleSheet.flatten(requestedStyles)
251
290
  }
252
291
  const iconStyles = {
253
292
  icon: getStyles('icon'),
254
293
  touchablePressable: getStyles('touchablePressable'),
255
294
  touchableWrapper: getStyles('touchableWrapper'),
256
- touchableRipple: getStyles('touchableRipple'),
295
+ touchableFeedback: getStyles('touchableFeedback'),
257
296
  }
258
297
 
259
298
  return <ActionIcon
@@ -14,6 +14,8 @@ type TextInputParts =
14
14
  | 'label'
15
15
  | 'innerWrapper'
16
16
  | 'error'
17
+ | 'subtitle'
18
+ | 'subtitleWrapper'
17
19
  | 'placeholder'
18
20
  | 'selection'
19
21
  | 'requiredAsterisk'
@@ -74,16 +76,24 @@ export const TextInputStyles = {
74
76
  color: theme.colors.primary,
75
77
  },
76
78
  leftIconTouchableWrapper: {
77
- ...theme.spacing.marginRight(1),
79
+ // ...theme.spacing.marginRight(0.5),
78
80
  },
79
81
  rightIconTouchableWrapper: {
80
- ...theme.spacing.marginLeft(1),
82
+ // ...theme.spacing.marginLeft(0.5),
81
83
  },
82
84
  error: {
83
85
  color: theme.colors.negative,
84
- ...theme.spacing.marginTop(0.5),
85
- },
86
86
 
87
+ },
88
+ subtitleWrapper: {
89
+ ...theme.spacing.marginTop(0.2),
90
+ ...theme.presets.row,
91
+ ...theme.presets.justifySpaceBetween,
92
+ ...theme.presets.alignCenter,
93
+ },
94
+ subtitle: {
95
+ ...theme.presets.textRight,
96
+ },
87
97
  'label:error': {
88
98
  color: theme.colors.negative,
89
99
  },