@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.
- package/dist/components/ActionIcon/index.js +2 -1
- package/dist/components/ActionIcon/index.js.map +1 -1
- package/dist/components/ActionIcon/styles.d.ts +58 -58
- package/dist/components/Backdrop/index.js +1 -1
- package/dist/components/Backdrop/index.js.map +1 -1
- package/dist/components/Button/index.d.ts +109 -109
- package/dist/components/Button/index.js +5 -7
- package/dist/components/Button/index.js.map +1 -1
- package/dist/components/Button/styles.d.ts +60 -55
- package/dist/components/Button/styles.js +4 -2
- package/dist/components/Button/styles.js.map +1 -1
- package/dist/components/Checkbox/index.js +4 -2
- package/dist/components/Checkbox/index.js.map +1 -1
- package/dist/components/Checkbox/styles.d.ts +1 -1
- package/dist/components/Checkbox/styles.js +4 -0
- package/dist/components/Checkbox/styles.js.map +1 -1
- package/dist/components/FileInput/index.d.ts +1 -1
- package/dist/components/Image/index.js +3 -0
- package/dist/components/Image/index.js.map +1 -1
- package/dist/components/Modal/index.js +1 -1
- package/dist/components/Modal/index.js.map +1 -1
- package/dist/components/MultiSelect/styles.js +1 -4
- package/dist/components/MultiSelect/styles.js.map +1 -1
- package/dist/components/Navigation/utils.js +0 -1
- package/dist/components/Navigation/utils.js.map +1 -1
- package/dist/components/Pager/styles.js +13 -11
- package/dist/components/Pager/styles.js.map +1 -1
- package/dist/components/RadioInput/index.js +3 -1
- package/dist/components/RadioInput/index.js.map +1 -1
- package/dist/components/RadioInput/styles.d.ts +1 -1
- package/dist/components/RadioInput/styles.js +1 -0
- package/dist/components/RadioInput/styles.js.map +1 -1
- package/dist/components/SegmentedControl/index.d.ts +10 -1
- package/dist/components/SegmentedControl/index.js +27 -27
- package/dist/components/SegmentedControl/index.js.map +1 -1
- package/dist/components/SegmentedControl/styles.d.ts +56 -51
- package/dist/components/SegmentedControl/styles.js +10 -3
- package/dist/components/SegmentedControl/styles.js.map +1 -1
- package/dist/components/Select/index.js +1 -2
- package/dist/components/Select/index.js.map +1 -1
- package/dist/components/Select/styles.d.ts +1 -1
- package/dist/components/Select/styles.js +4 -1
- package/dist/components/Select/styles.js.map +1 -1
- package/dist/components/Switch/index.js +1 -1
- package/dist/components/Switch/index.js.map +1 -1
- package/dist/components/Text/index.d.ts +2 -0
- package/dist/components/Text/index.js +43 -3
- package/dist/components/Text/index.js.map +1 -1
- package/dist/components/Text/styles.d.ts +57 -52
- package/dist/components/Text/styles.js +11 -3
- package/dist/components/Text/styles.js.map +1 -1
- package/dist/components/TextInput/index.d.ts +8 -4
- package/dist/components/TextInput/index.js +37 -17
- package/dist/components/TextInput/index.js.map +1 -1
- package/dist/components/TextInput/styles.d.ts +1 -1
- package/dist/components/TextInput/styles.js +11 -3
- package/dist/components/TextInput/styles.js.map +1 -1
- package/dist/components/Touchable/index.d.ts +1 -1
- package/dist/components/Touchable/index.js +81 -43
- package/dist/components/Touchable/index.js.map +1 -1
- package/dist/components/Touchable/styles.d.ts +56 -51
- package/dist/components/Touchable/styles.js +6 -1
- package/dist/components/Touchable/styles.js.map +1 -1
- package/dist/components/defaultStyles.d.ts +263 -263
- package/dist/utils/KeyboardAware/lib/KeyboardAwareHOC.d.ts +2 -0
- package/dist/utils/KeyboardAware/lib/KeyboardAwareHOC.js +287 -286
- package/dist/utils/KeyboardAware/lib/KeyboardAwareHOC.js.map +1 -1
- package/dist/utils/OSAlert.d.ts +6 -5
- package/dist/utils/OSAlert.js +7 -6
- package/dist/utils/OSAlert.js.map +1 -1
- package/dist/utils/hooks.d.ts +34 -1
- package/dist/utils/hooks.js +54 -1
- package/dist/utils/hooks.js.map +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.js +2 -6
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/notifications.js +4 -4
- package/dist/utils/notifications.js.map +1 -1
- package/package.json +1 -1
- package/src/components/ActionIcon/index.tsx +2 -1
- package/src/components/Backdrop/index.tsx +1 -1
- package/src/components/Button/index.tsx +7 -11
- package/src/components/Button/styles.ts +34 -10
- package/src/components/Checkbox/index.tsx +4 -1
- package/src/components/Checkbox/styles.ts +5 -0
- package/src/components/Image/index.tsx +3 -0
- package/src/components/Modal/index.tsx +1 -1
- package/src/components/MultiSelect/styles.ts +1 -8
- package/src/components/Navigation/utils.tsx +0 -2
- package/src/components/Pager/styles.ts +16 -11
- package/src/components/RadioInput/index.tsx +3 -1
- package/src/components/RadioInput/styles.ts +2 -1
- package/src/components/SegmentedControl/index.tsx +31 -18
- package/src/components/SegmentedControl/styles.ts +29 -7
- package/src/components/Select/index.tsx +2 -1
- package/src/components/Select/styles.ts +12 -2
- package/src/components/Switch/index.tsx +1 -1
- package/src/components/Text/index.tsx +57 -7
- package/src/components/Text/styles.ts +25 -9
- package/src/components/TextInput/index.tsx +48 -9
- package/src/components/TextInput/styles.ts +14 -4
- package/src/components/Touchable/index.tsx +90 -36
- package/src/components/Touchable/styles.ts +15 -3
- package/src/utils/KeyboardAware/lib/KeyboardAwareHOC.tsx +34 -24
- package/src/utils/OSAlert.ts +10 -10
- package/src/utils/hooks.ts +82 -2
- package/src/utils/index.ts +2 -2
- 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
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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
|
-
|
|
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
|
-
|
|
14
|
-
|
|
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
|
-
|
|
244
|
+
{subtitleContent}
|
|
218
245
|
</Touchable>
|
|
219
246
|
)
|
|
220
247
|
})
|
|
221
248
|
|
|
222
|
-
export const FormError = ({
|
|
223
|
-
|
|
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}
|
|
260
|
+
return <Text text={text} {...props} />
|
|
226
261
|
}
|
|
227
|
-
return
|
|
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(
|
|
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
|
-
|
|
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(
|
|
79
|
+
// ...theme.spacing.marginRight(0.5),
|
|
78
80
|
},
|
|
79
81
|
rightIconTouchableWrapper: {
|
|
80
|
-
...theme.spacing.marginLeft(
|
|
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
|
},
|