@codeleap/mobile 1.9.27 → 1.9.30
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/Backdrop.d.ts +66 -0
- package/dist/components/Backdrop.js +70 -0
- package/dist/components/Backdrop.js.map +1 -0
- package/dist/components/Button.d.ts +3 -3
- package/dist/components/Button.js.map +1 -1
- package/dist/components/FileInput.js +0 -2
- package/dist/components/FileInput.js.map +1 -1
- package/dist/components/Image.js +2 -2
- package/dist/components/Image.js.map +1 -1
- package/dist/components/List.d.ts +23 -4
- package/dist/components/List.js +17 -1
- package/dist/components/List.js.map +1 -1
- package/dist/components/Modal/index.d.ts +1 -1
- package/dist/components/Modal/index.js +26 -27
- package/dist/components/Modal/index.js.map +1 -1
- package/dist/components/Modal/styles.d.ts +4 -15
- package/dist/components/Modal/styles.js +27 -23
- package/dist/components/Modal/styles.js.map +1 -1
- package/dist/components/NewModal/index.d.ts +27 -0
- package/dist/components/NewModal/index.js +99 -0
- package/dist/components/NewModal/index.js.map +1 -0
- package/dist/components/NewModal/styles.d.ts +57 -0
- package/dist/components/NewModal/styles.js +58 -0
- package/dist/components/NewModal/styles.js.map +1 -0
- package/dist/components/NewPager/index.js +3 -7
- package/dist/components/NewPager/index.js.map +1 -1
- package/dist/components/Overlay.js +13 -9
- package/dist/components/Overlay.js.map +1 -1
- package/dist/components/Scroll.d.ts +4 -2
- package/dist/components/Scroll.js.map +1 -1
- package/dist/components/SegmentedControl/index.d.ts +42 -0
- package/dist/components/SegmentedControl/index.js +137 -0
- package/dist/components/SegmentedControl/index.js.map +1 -0
- package/dist/components/SegmentedControl/styles.d.ts +54 -0
- package/dist/components/SegmentedControl/styles.js +36 -0
- package/dist/components/SegmentedControl/styles.js.map +1 -0
- package/dist/components/SegmentedControl.d.ts +5 -0
- package/dist/components/SegmentedControl.js +32 -0
- package/dist/components/SegmentedControl.js.map +1 -0
- package/dist/components/Select/index.js +1 -1
- package/dist/components/Select/index.js.map +1 -1
- package/dist/components/Text.d.ts +8 -3
- package/dist/components/Text.js +12 -5
- package/dist/components/Text.js.map +1 -1
- package/dist/components/TextInput.d.ts +4 -2
- package/dist/components/TextInput.js +2 -2
- package/dist/components/TextInput.js.map +1 -1
- package/dist/components/Touchable.d.ts +5 -3
- package/dist/components/Touchable.js +26 -19
- package/dist/components/Touchable.js.map +1 -1
- package/dist/components/View.js +1 -1
- package/dist/components/View.js.map +1 -1
- package/dist/components/_Modal/index.d.ts +27 -0
- package/dist/components/_Modal/index.js +114 -0
- package/dist/components/_Modal/index.js.map +1 -0
- package/dist/components/_Modal/styles.d.ts +64 -0
- package/dist/components/_Modal/styles.js +60 -0
- package/dist/components/_Modal/styles.js.map +1 -0
- package/dist/components/components.d.ts +3 -0
- package/dist/components/components.js +3 -0
- package/dist/components/components.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +18 -1
- package/dist/index.js.map +1 -1
- package/dist/utils/ModalManager/components.d.ts +12 -0
- package/dist/utils/ModalManager/components.js +86 -0
- package/dist/utils/ModalManager/components.js.map +1 -0
- package/dist/utils/ModalManager/context.d.ts +47 -0
- package/dist/utils/ModalManager/context.js +196 -0
- package/dist/utils/ModalManager/context.js.map +1 -0
- package/dist/utils/ModalManager/index.d.ts +10 -0
- package/dist/utils/ModalManager/index.js +12 -0
- package/dist/utils/ModalManager/index.js.map +1 -0
- package/dist/utils/PermissionManager/components.d.ts +18 -0
- package/dist/utils/PermissionManager/components.js +52 -0
- package/dist/utils/PermissionManager/components.js.map +1 -0
- package/dist/utils/PermissionManager/context.d.ts +52 -0
- package/dist/utils/PermissionManager/context.js +325 -0
- package/dist/utils/PermissionManager/context.js.map +1 -0
- package/dist/utils/PermissionManager/index.d.ts +4 -0
- package/dist/utils/PermissionManager/index.js +9 -0
- package/dist/utils/PermissionManager/index.js.map +1 -0
- package/dist/utils/PermissionManager/types.d.ts +13 -0
- package/dist/utils/PermissionManager/types.js +3 -0
- package/dist/utils/PermissionManager/types.js.map +1 -0
- package/dist/utils/hooks.d.ts +6 -0
- package/dist/utils/hooks.js +62 -0
- package/dist/utils/hooks.js.map +1 -0
- package/package.json +2 -1
- package/src/components/Backdrop.tsx +77 -0
- package/src/components/Button.tsx +3 -2
- package/src/components/FileInput.tsx +2 -2
- package/src/components/Image.tsx +3 -2
- package/src/components/List.tsx +44 -5
- package/src/components/Modal/index.tsx +37 -50
- package/src/components/Modal/styles.ts +36 -39
- package/src/components/NewPager/index.tsx +5 -7
- package/src/components/Overlay.tsx +22 -13
- package/src/components/Scroll.tsx +3 -1
- package/src/components/SegmentedControl/index.tsx +182 -0
- package/src/components/SegmentedControl/styles.ts +65 -0
- package/src/components/Select/index.tsx +1 -2
- package/src/components/Text.tsx +23 -10
- package/src/components/TextInput.tsx +4 -2
- package/src/components/Touchable.tsx +31 -20
- package/src/components/View.tsx +1 -1
- package/src/components/_Modal/index.tsx +162 -0
- package/src/components/_Modal/styles.ts +125 -0
- package/src/components/components.ts +3 -0
- package/src/index.ts +6 -0
- package/src/modules/imageCropPicker.d.ts +497 -0
- package/src/modules/index.d.ts +186 -0
- package/src/utils/ModalManager/components.tsx +69 -0
- package/src/utils/ModalManager/context.tsx +247 -0
- package/src/utils/ModalManager/index.ts +13 -0
- package/src/utils/PermissionManager/context.tsx +299 -0
- package/src/utils/PermissionManager/index.ts +20 -0
- package/src/utils/PermissionManager/types.ts +24 -0
- package/src/utils/hooks.ts +65 -0
package/src/components/List.tsx
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
useDefaultComponentStyle,
|
|
7
7
|
usePrevious,
|
|
8
8
|
useCodeleapContext,
|
|
9
|
+
TypeGuards,
|
|
9
10
|
} from '@codeleap/common'
|
|
10
11
|
import {
|
|
11
12
|
|
|
@@ -13,13 +14,29 @@ import {
|
|
|
13
14
|
// @ts-ignore
|
|
14
15
|
} from 'react-native-keyboard-aware-scroll-view'
|
|
15
16
|
|
|
16
|
-
import { RefreshControl, FlatList, FlatListProps as RNFlatListProps } from 'react-native'
|
|
17
|
+
import { RefreshControl, FlatList, FlatListProps as RNFlatListProps, ListRenderItemInfo } from 'react-native'
|
|
17
18
|
import { View, ViewProps } from './View'
|
|
18
19
|
import { EmptyPlaceholder, EmptyPlaceholderProps } from './EmptyPlaceholder'
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
import { ActivityIndicator } from './ActivityIndicator'
|
|
21
|
+
import { Text } from './Text'
|
|
22
|
+
export type DataboundFlatListPropsTypes = 'data' | 'renderItem' | 'keyExtractor' | 'getItemLayout'
|
|
23
|
+
|
|
24
|
+
export type ReplaceFlatlistProps<P, T> = Omit<P, DataboundFlatListPropsTypes> & {
|
|
25
|
+
data: T[]
|
|
26
|
+
keyExtractor?: (item: T, index: number) => string
|
|
27
|
+
renderItem: (data: ListRenderItemInfo<T>) => React.ReactElement
|
|
28
|
+
onRefresh?: () => void
|
|
29
|
+
getItemLayout?: ((
|
|
30
|
+
data:T,
|
|
31
|
+
index: number,
|
|
32
|
+
) => { length: number; offset: number; index: number })
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export type FlatListProps<
|
|
36
|
+
T = any[],
|
|
37
|
+
Data = T extends Array<infer D> ? D : never
|
|
38
|
+
> =RNFlatListProps<Data> &
|
|
21
39
|
ViewProps & {
|
|
22
|
-
onRefresh?: () => void
|
|
23
40
|
refreshTimeout?: number
|
|
24
41
|
changeData?: any
|
|
25
42
|
separators?: boolean
|
|
@@ -112,5 +129,27 @@ const ListCP = forwardRef<FlatList, FlatListProps>(
|
|
|
112
129
|
},
|
|
113
130
|
)
|
|
114
131
|
|
|
115
|
-
export
|
|
132
|
+
export type PaginationIndicatorProps = {
|
|
133
|
+
isFetching?: boolean
|
|
134
|
+
hasMore?: boolean
|
|
135
|
+
noMoreItemsText: React.ReactChild
|
|
136
|
+
activityIndicator?: JSX.Element
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export const PaginationIndicator = ({ hasMore, isFetching, noMoreItemsText, activityIndicator }: PaginationIndicatorProps) => {
|
|
140
|
+
if (isFetching) {
|
|
141
|
+
return activityIndicator || <ActivityIndicator variants={['center', 'marginVertical:3']}/>
|
|
142
|
+
}
|
|
143
|
+
if (!hasMore) {
|
|
144
|
+
if (TypeGuards.isString(noMoreItemsText) || TypeGuards.isNumber(noMoreItemsText)) {
|
|
145
|
+
return <Text variants={['h4', 'marginVertical:3', 'textCenter', 'fullWidth']} text={noMoreItemsText.toString()}/>
|
|
146
|
+
}
|
|
147
|
+
return noMoreItemsText
|
|
148
|
+
}
|
|
149
|
+
return null
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export type ListComponentType = <T extends any[] = any[]>(props: FlatListProps<T>) => React.ReactElement
|
|
153
|
+
|
|
154
|
+
export const List = ListCP as ListComponentType
|
|
116
155
|
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import * as React from 'react'
|
|
2
|
-
import { View, ViewProps
|
|
2
|
+
import { View, ViewProps } from '../View'
|
|
3
3
|
import { Button, ButtonProps } from '../Button'
|
|
4
4
|
import { Scroll } from '../Scroll'
|
|
5
5
|
import {
|
|
6
|
-
capitalize,
|
|
7
6
|
ComponentVariants,
|
|
7
|
+
getNestedStylesByKey,
|
|
8
8
|
IconPlaceholder,
|
|
9
9
|
onUpdate,
|
|
10
|
+
TypeGuards,
|
|
10
11
|
useDefaultComponentStyle,
|
|
11
|
-
useCodeleapContext,
|
|
12
12
|
} from '@codeleap/common'
|
|
13
13
|
import {
|
|
14
14
|
MobileModalComposition,
|
|
@@ -18,9 +18,10 @@ import {
|
|
|
18
18
|
import { StyleSheet } from 'react-native'
|
|
19
19
|
import { StylesOf } from '../../types/utility'
|
|
20
20
|
|
|
21
|
-
import {
|
|
21
|
+
import { useDynamicAnimation } from 'moti'
|
|
22
|
+
import { Backdrop } from '../Backdrop'
|
|
23
|
+
import { useStaticAnimationStyles } from '../../utils/hooks'
|
|
22
24
|
import { Text } from '../Text'
|
|
23
|
-
import { Animated } from '../Animated'
|
|
24
25
|
|
|
25
26
|
export * from './styles'
|
|
26
27
|
|
|
@@ -34,7 +35,7 @@ export type ModalProps = Omit<ViewProps, 'variants' | 'styles'> & {
|
|
|
34
35
|
closable?: boolean
|
|
35
36
|
footer?: React.ReactNode
|
|
36
37
|
title?: React.ReactNode
|
|
37
|
-
debugName
|
|
38
|
+
debugName: string
|
|
38
39
|
closeIconName?: IconPlaceholder
|
|
39
40
|
visible: boolean
|
|
40
41
|
toggle?: () => void
|
|
@@ -63,7 +64,7 @@ export const Modal: React.FC<ModalProps> = (modalProps) => {
|
|
|
63
64
|
...props
|
|
64
65
|
} = modalProps
|
|
65
66
|
|
|
66
|
-
const variantStyles = useDefaultComponentStyle('Modal', {
|
|
67
|
+
const variantStyles = useDefaultComponentStyle('u:Modal', {
|
|
67
68
|
variants: variants as any,
|
|
68
69
|
transform: StyleSheet.flatten,
|
|
69
70
|
styles,
|
|
@@ -73,61 +74,46 @@ export const Modal: React.FC<ModalProps> = (modalProps) => {
|
|
|
73
74
|
const s = [
|
|
74
75
|
variantStyles[key],
|
|
75
76
|
styles[key],
|
|
76
|
-
visible ? variantStyles[key + ':visible'] : {},
|
|
77
|
-
visible ? styles[key + ':visible'] : {},
|
|
78
77
|
]
|
|
79
78
|
|
|
80
|
-
return s
|
|
79
|
+
return StyleSheet.flatten(s)
|
|
81
80
|
}
|
|
81
|
+
const buttonStyles = React.useMemo(() => getNestedStylesByKey('closeButton', variantStyles), [variantStyles])
|
|
82
82
|
|
|
83
|
-
const
|
|
84
|
-
const buttonEntries = {}
|
|
83
|
+
const boxAnimationStates = useStaticAnimationStyles(variantStyles, ['box:hidden', 'box:visible'])
|
|
85
84
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
return buttonEntries
|
|
92
|
-
}, [variantStyles])
|
|
85
|
+
const boxAnimation = useDynamicAnimation(() => {
|
|
86
|
+
return visible ? boxAnimationStates['box:visible'] : boxAnimationStates['box:hidden']
|
|
87
|
+
})
|
|
93
88
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
},
|
|
99
|
-
visible: {
|
|
100
|
-
...variantStyles['box:pose:visible'],
|
|
101
|
-
...styles['box:pose:visible'],
|
|
102
|
-
},
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
const wrapperStyle = StyleSheet.flatten(getStyles('wrapper'))
|
|
89
|
+
onUpdate(() => {
|
|
90
|
+
boxAnimation.animateTo(visible ? boxAnimationStates['box:visible'] : boxAnimationStates['box:hidden'])
|
|
91
|
+
}, [visible])
|
|
92
|
+
const wrapperStyle = getStyles('wrapper')
|
|
106
93
|
return (
|
|
107
|
-
<View
|
|
108
|
-
|
|
109
|
-
pointerEvents={visible ? 'auto' : 'none'}
|
|
110
|
-
>
|
|
111
|
-
<AnimatedView style={getStyles('overlay')} transition={'opacity'} />
|
|
94
|
+
<View style={[wrapperStyle, { zIndex: TypeGuards.isNumber(zIndex) ? zIndex : wrapperStyle?.zIndex }]} pointerEvents={visible ? 'auto' : 'none'}>
|
|
95
|
+
|
|
112
96
|
<Scroll
|
|
113
97
|
style={getStyles('innerWrapper')}
|
|
114
98
|
contentContainerStyle={getStyles('innerWrapperScroll')}
|
|
115
99
|
scrollEnabled={scroll}
|
|
116
100
|
keyboardAware={keyboardAware}
|
|
117
101
|
>
|
|
118
|
-
{
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
102
|
+
<Backdrop visible={visible} debugName={`Modal ${debugName} backdrop`} styles={{
|
|
103
|
+
'wrapper:hidden': variantStyles['backdrop:hidden'],
|
|
104
|
+
'wrapper:visible': variantStyles['backdrop:visible'],
|
|
105
|
+
wrapper: variantStyles.backdrop,
|
|
106
|
+
}} onPress={(dismissOnBackdrop && closable) ? toggle : (() => {})}
|
|
107
|
+
wrapperProps={{
|
|
108
|
+
transition: { ...variantStyles['backdrop:transition'] },
|
|
109
|
+
}}
|
|
110
|
+
/>
|
|
111
|
+
<View
|
|
112
|
+
animated
|
|
113
|
+
state={boxAnimation}
|
|
130
114
|
style={getStyles('box')}
|
|
115
|
+
transition={{ ...variantStyles['box:transition'] }}
|
|
116
|
+
{...props}
|
|
131
117
|
>
|
|
132
118
|
{(title || showClose) && (
|
|
133
119
|
<View style={getStyles('header')}>
|
|
@@ -137,7 +123,7 @@ export const Modal: React.FC<ModalProps> = (modalProps) => {
|
|
|
137
123
|
title
|
|
138
124
|
)}
|
|
139
125
|
|
|
140
|
-
{showClose && closable && (
|
|
126
|
+
{(showClose && closable) && (
|
|
141
127
|
<Button
|
|
142
128
|
debugName={`${debugName} modal close button`}
|
|
143
129
|
icon={closeIconName as IconPlaceholder}
|
|
@@ -155,9 +141,10 @@ export const Modal: React.FC<ModalProps> = (modalProps) => {
|
|
|
155
141
|
{typeof footer === 'string' ? <Text text={footer} /> : footer}
|
|
156
142
|
</View>
|
|
157
143
|
)}
|
|
158
|
-
</
|
|
144
|
+
</View>
|
|
159
145
|
</Scroll>
|
|
160
146
|
</View>
|
|
147
|
+
|
|
161
148
|
)
|
|
162
149
|
}
|
|
163
150
|
|
|
@@ -1,58 +1,40 @@
|
|
|
1
1
|
import {
|
|
2
|
+
assignTextStyle,
|
|
2
3
|
ButtonComposition,
|
|
3
4
|
createDefaultVariantFactory,
|
|
4
5
|
includePresets,
|
|
5
|
-
ModalComposition,
|
|
6
|
-
ModalStyles,
|
|
7
|
-
assignTextStyle,
|
|
8
6
|
} from '@codeleap/common'
|
|
9
7
|
|
|
10
|
-
export
|
|
11
|
-
duration: 200,
|
|
12
|
-
ease: 'easeOut',
|
|
13
|
-
useNativeDriver: false,
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export const modalTransition = {
|
|
17
|
-
duration: 150,
|
|
18
|
-
ease: 'easeOut',
|
|
19
|
-
useNativeDriver: false,
|
|
20
|
-
}
|
|
8
|
+
export type AnimatableParts = 'box' | 'backdrop'
|
|
21
9
|
|
|
22
10
|
export type MobileModalParts =
|
|
11
|
+
| AnimatableParts
|
|
23
12
|
| 'wrapper'
|
|
24
|
-
| 'overlay'
|
|
25
13
|
| 'innerWrapper'
|
|
26
14
|
| 'innerWrapperScroll'
|
|
27
|
-
| 'box'
|
|
28
|
-
| 'footer'
|
|
29
15
|
| 'body'
|
|
16
|
+
| 'footer'
|
|
30
17
|
| 'header'
|
|
31
|
-
| 'touchableBackdrop'
|
|
32
|
-
| 'box:pose'
|
|
33
18
|
| 'title'
|
|
34
19
|
| `closeButton${Capitalize<ButtonComposition>}`
|
|
35
20
|
|
|
36
21
|
export type MobileModalComposition =
|
|
37
22
|
| MobileModalParts
|
|
38
|
-
| `${
|
|
23
|
+
| `${AnimatableParts}:visible`
|
|
24
|
+
| `${AnimatableParts}:hidden`
|
|
25
|
+
| `${AnimatableParts}:transition`
|
|
39
26
|
|
|
40
27
|
const createModalStyle = createDefaultVariantFactory<MobileModalComposition>()
|
|
41
28
|
|
|
42
|
-
const presets = includePresets((style) => createModalStyle(() => ({ body: style }))
|
|
43
|
-
)
|
|
44
|
-
|
|
45
|
-
const defaultModalStyles = ModalStyles
|
|
29
|
+
const presets = includePresets((style) => createModalStyle(() => ({ body: style })))
|
|
46
30
|
|
|
47
31
|
export const MobileModalStyles = {
|
|
48
|
-
|
|
32
|
+
|
|
49
33
|
...presets,
|
|
50
34
|
default: createModalStyle((Theme) => {
|
|
51
35
|
const fullSize = {
|
|
52
36
|
...Theme.presets.whole,
|
|
53
37
|
position: 'absolute',
|
|
54
|
-
width: Theme?.values?.width,
|
|
55
|
-
height: Theme?.values?.height,
|
|
56
38
|
}
|
|
57
39
|
|
|
58
40
|
return {
|
|
@@ -61,16 +43,34 @@ export const MobileModalStyles = {
|
|
|
61
43
|
|
|
62
44
|
...fullSize,
|
|
63
45
|
},
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
46
|
+
'box:transition': {
|
|
47
|
+
scale: {
|
|
48
|
+
duration: Theme.values.transitions.modal.duration,
|
|
49
|
+
type: 'timing',
|
|
50
|
+
},
|
|
51
|
+
opacity: {
|
|
52
|
+
duration: Theme.values.transitions.modal.duration,
|
|
53
|
+
type: 'timing',
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
'backdrop:transition': {
|
|
57
|
+
opacity: {
|
|
58
|
+
duration: Theme.values.transitions.modal.duration,
|
|
59
|
+
type: 'timing',
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
backdrop: {
|
|
67
63
|
|
|
68
64
|
backgroundColor: Theme.colors.black,
|
|
69
65
|
...fullSize,
|
|
70
66
|
},
|
|
71
|
-
|
|
67
|
+
|
|
68
|
+
'backdrop:visible': {
|
|
72
69
|
opacity: 0.5,
|
|
73
70
|
},
|
|
71
|
+
'backdrop:hidden': {
|
|
72
|
+
opacity: 0,
|
|
73
|
+
},
|
|
74
74
|
innerWrapper: {},
|
|
75
75
|
innerWrapperScroll: {
|
|
76
76
|
display: 'flex',
|
|
@@ -84,18 +84,15 @@ export const MobileModalStyles = {
|
|
|
84
84
|
borderRadius: Theme.borderRadius.medium,
|
|
85
85
|
...Theme.spacing.padding(2),
|
|
86
86
|
},
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
},
|
|
90
|
-
'box:pose': {
|
|
87
|
+
|
|
88
|
+
'box:hidden': {
|
|
91
89
|
opacity: 0,
|
|
92
90
|
scale: 0.8,
|
|
93
|
-
|
|
91
|
+
|
|
94
92
|
},
|
|
95
|
-
'box:
|
|
93
|
+
'box:visible': {
|
|
96
94
|
opacity: 1,
|
|
97
95
|
scale: 1,
|
|
98
|
-
transition: modalTransition,
|
|
99
96
|
},
|
|
100
97
|
header: {
|
|
101
98
|
flexDirection: 'row',
|
|
@@ -114,7 +111,7 @@ export const MobileModalStyles = {
|
|
|
114
111
|
},
|
|
115
112
|
}
|
|
116
113
|
}),
|
|
117
|
-
popup: createModalStyle((
|
|
114
|
+
popup: createModalStyle(() => ({})),
|
|
118
115
|
fullscreen: createModalStyle((theme) => ({
|
|
119
116
|
overlay: {
|
|
120
117
|
backgroundColor: theme.colors.background,
|
|
@@ -43,9 +43,9 @@ export const NewPager:React.FC<NewPagerProps> = (pagerProps) => {
|
|
|
43
43
|
returnEarly = true,
|
|
44
44
|
renderPageWrapper,
|
|
45
45
|
pageWrapperProps = {},
|
|
46
|
-
|
|
46
|
+
children,
|
|
47
47
|
} = pagerProps
|
|
48
|
-
|
|
48
|
+
|
|
49
49
|
let variantStyles = useDefaultComponentStyle<'u:Pager', typeof NewMobilePagerStyles>(
|
|
50
50
|
'u:Pager',
|
|
51
51
|
{
|
|
@@ -58,7 +58,7 @@ export const NewPager:React.FC<NewPagerProps> = (pagerProps) => {
|
|
|
58
58
|
|
|
59
59
|
const lastPage = nChildren - 1
|
|
60
60
|
|
|
61
|
-
|
|
61
|
+
const childArr = React.Children.toArray(children)
|
|
62
62
|
|
|
63
63
|
const WrapperComponent = renderPageWrapper || View
|
|
64
64
|
|
|
@@ -68,7 +68,7 @@ export const NewPager:React.FC<NewPagerProps> = (pagerProps) => {
|
|
|
68
68
|
return (
|
|
69
69
|
<View style={[variantStyles.wrapper, style]} >
|
|
70
70
|
{
|
|
71
|
-
|
|
71
|
+
childArr.map((child:NewPagerProps['children'][number], index) => {
|
|
72
72
|
const isActive = index === page
|
|
73
73
|
const isLast = index === lastPage
|
|
74
74
|
const isFirst = index === 0
|
|
@@ -96,9 +96,7 @@ export const NewPager:React.FC<NewPagerProps> = (pagerProps) => {
|
|
|
96
96
|
index,
|
|
97
97
|
page,
|
|
98
98
|
}
|
|
99
|
-
|
|
100
|
-
child,
|
|
101
|
-
})
|
|
99
|
+
|
|
102
100
|
const content = typeof child === 'function' ? child(pageProps) : child
|
|
103
101
|
|
|
104
102
|
const wrapperProps = {
|
|
@@ -2,6 +2,7 @@ import * as React from 'react'
|
|
|
2
2
|
import {
|
|
3
3
|
ComponentVariants,
|
|
4
4
|
IconPlaceholder,
|
|
5
|
+
onUpdate,
|
|
5
6
|
OverlayComposition,
|
|
6
7
|
OverlayStyles,
|
|
7
8
|
useDefaultComponentStyle,
|
|
@@ -13,7 +14,8 @@ import { Button } from './Button'
|
|
|
13
14
|
import { View } from './View'
|
|
14
15
|
import { StylesOf } from '../types/utility'
|
|
15
16
|
import { StyleSheet, ViewProps } from 'react-native'
|
|
16
|
-
import { AnimatedTouchable } from './Touchable'
|
|
17
|
+
import { AnimatedTouchable, Touchable } from './Touchable'
|
|
18
|
+
import { useAnimationState } from 'moti'
|
|
17
19
|
|
|
18
20
|
export type OverlayProps = ViewProps & {
|
|
19
21
|
title?: ReactNode
|
|
@@ -43,21 +45,28 @@ export const Overlay: React.FC<OverlayProps> = (overlayProps) => {
|
|
|
43
45
|
variants: variants as any,
|
|
44
46
|
}) as StylesOf<OverlayComposition>
|
|
45
47
|
|
|
46
|
-
const
|
|
48
|
+
const animation = useAnimationState({
|
|
49
|
+
visible: variantStyles['wrapper:visible'],
|
|
50
|
+
hidden: styles['wrapper:visible'],
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
onUpdate(() => {
|
|
54
|
+
animation.transitionTo(visible ? 'visible' : 'hidden')
|
|
55
|
+
}, [visible])
|
|
56
|
+
|
|
57
|
+
const viewStyles = [
|
|
47
58
|
variantStyles.wrapper,
|
|
48
59
|
styles.wrapper,
|
|
49
|
-
visible && variantStyles['wrapper:visible'],
|
|
50
|
-
visible && styles['wrapper:visible'],
|
|
51
60
|
]
|
|
52
61
|
|
|
53
62
|
return (
|
|
54
|
-
<
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
63
|
+
<View animated state={animation} style={viewStyles}>
|
|
64
|
+
<Touchable
|
|
65
|
+
|
|
66
|
+
feedbackVariant='none'
|
|
67
|
+
variants={['whole', 'full', 'absolute']}
|
|
68
|
+
{...props}
|
|
69
|
+
>
|
|
61
70
|
{(title || showClose) && (
|
|
62
71
|
<View style={variantStyles.header}>
|
|
63
72
|
<InputLabel style={variantStyles.title} label={title} />
|
|
@@ -71,7 +80,7 @@ export const Overlay: React.FC<OverlayProps> = (overlayProps) => {
|
|
|
71
80
|
)}
|
|
72
81
|
</View>
|
|
73
82
|
)}
|
|
74
|
-
</
|
|
75
|
-
</
|
|
83
|
+
</Touchable>
|
|
84
|
+
</View>
|
|
76
85
|
)
|
|
77
86
|
}
|
|
@@ -9,12 +9,14 @@ import {
|
|
|
9
9
|
} from '@codeleap/common'
|
|
10
10
|
|
|
11
11
|
import {
|
|
12
|
-
KeyboardAwareScrollViewProps,
|
|
13
12
|
KeyboardAwareScrollView as KBDView,
|
|
14
13
|
// @ts-ignore
|
|
15
14
|
} from 'react-native-keyboard-aware-scroll-view'
|
|
16
15
|
import { RefreshControl, ScrollView, ScrollViewProps, ViewStyle } from 'react-native'
|
|
17
16
|
import { ViewProps } from './View'
|
|
17
|
+
import { KeyboardAwareScrollViewTypes } from '../modules'
|
|
18
|
+
|
|
19
|
+
type KeyboardAwareScrollViewProps = KeyboardAwareScrollViewTypes.KeyboardAwareScrollViewProps
|
|
18
20
|
|
|
19
21
|
export type ScrollProps = KeyboardAwareScrollViewProps &
|
|
20
22
|
ViewProps & {
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import React, { ReactElement, useImperativeHandle, useMemo, useRef } from 'react'
|
|
2
|
+
import { Scroll, ScrollProps } from '../Scroll'
|
|
3
|
+
|
|
4
|
+
import { Easing, EasingFunction, StyleSheet } from 'react-native'
|
|
5
|
+
import { PropsOf, useCodeleapContext, useDefaultComponentStyle } from '@codeleap/common'
|
|
6
|
+
import { SegmentedControlComposition, SegmentedControlStyles } from './styles'
|
|
7
|
+
import { Touchable } from '../Touchable'
|
|
8
|
+
import { StylesOf } from '../../types/utility'
|
|
9
|
+
import { Text } from '../Text'
|
|
10
|
+
import { KeyboardAwareScrollViewTypes } from '../../modules'
|
|
11
|
+
import { View } from '../View'
|
|
12
|
+
export * from './styles'
|
|
13
|
+
export type SegmentedControlRef =KeyboardAwareScrollViewTypes.KeyboardAwareScrollView & {
|
|
14
|
+
scrollTo: (index: number) => void
|
|
15
|
+
scrollToCurrent: () => void
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export type SegmentedControlProps<T = string> = ScrollProps & {
|
|
19
|
+
options : {label: string; value: T }[]
|
|
20
|
+
onValueChange: (value: T) => any
|
|
21
|
+
value: T
|
|
22
|
+
debugName: string
|
|
23
|
+
animation?: {
|
|
24
|
+
duration?: number
|
|
25
|
+
easing?: EasingFunction
|
|
26
|
+
}
|
|
27
|
+
styles?: StylesOf<SegmentedControlComposition>
|
|
28
|
+
scrollProps?: any
|
|
29
|
+
RenderButton?: (props: SegmentedControlProps & {
|
|
30
|
+
touchableProps: PropsOf<typeof Touchable>
|
|
31
|
+
textProps: PropsOf<typeof Text>
|
|
32
|
+
option: {label: string; value: any}
|
|
33
|
+
}) => ReactElement
|
|
34
|
+
RenderAnimatedView?: (props: SegmentedControlProps) => ReactElement
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const defaultAnimation = {
|
|
38
|
+
duration: 200,
|
|
39
|
+
// easing: Easing.linear,
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const _SegmentedControl = React.forwardRef<SegmentedControlRef, SegmentedControlProps>((props, ref) => {
|
|
43
|
+
const {
|
|
44
|
+
options = [],
|
|
45
|
+
onValueChange,
|
|
46
|
+
debugName,
|
|
47
|
+
value,
|
|
48
|
+
styles = {},
|
|
49
|
+
animation = {},
|
|
50
|
+
variants = [],
|
|
51
|
+
scrollProps = {},
|
|
52
|
+
RenderAnimatedView,
|
|
53
|
+
RenderButton,
|
|
54
|
+
|
|
55
|
+
} = props
|
|
56
|
+
const { Theme } = useCodeleapContext()
|
|
57
|
+
|
|
58
|
+
const _animation = {
|
|
59
|
+
...defaultAnimation, ...animation,
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
let variantStyles = useDefaultComponentStyle<'u:SegmentedControl', typeof SegmentedControlStyles>('u:SegmentedControl', {
|
|
63
|
+
styles,
|
|
64
|
+
transform: StyleSheet.flatten,
|
|
65
|
+
variants,
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
const scrollRef = useRef<KeyboardAwareScrollViewTypes.KeyboardAwareScrollView>(null)
|
|
69
|
+
|
|
70
|
+
function scrollTo(idx:number) {
|
|
71
|
+
if (!scrollRef.current) return
|
|
72
|
+
setTimeout(() => {
|
|
73
|
+
scrollRef.current?.scrollToPosition?.(widthStyle.width * idx, 0, true)
|
|
74
|
+
})
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
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 }
|
|
86
|
+
}, [options])
|
|
87
|
+
|
|
88
|
+
const currentOptionIdx = options.findIndex(o => o.value === value) || 0
|
|
89
|
+
|
|
90
|
+
const translateX = widthStyle.width * currentOptionIdx
|
|
91
|
+
|
|
92
|
+
const onPress = (txt:string, idx: number) => {
|
|
93
|
+
return () => {
|
|
94
|
+
onValueChange(txt)
|
|
95
|
+
scrollTo(idx)
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const hasScrolledInitially = useRef(false)
|
|
100
|
+
|
|
101
|
+
useImperativeHandle(ref, () => {
|
|
102
|
+
if (!scrollRef.current) return null
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
...(scrollRef.current),
|
|
106
|
+
scrollTo,
|
|
107
|
+
scrollToCurrent() {
|
|
108
|
+
if (!scrollRef.current) return
|
|
109
|
+
scrollTo(currentOptionIdx)
|
|
110
|
+
},
|
|
111
|
+
} as SegmentedControlRef
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
if (!hasScrolledInitially.current && scrollRef.current) {
|
|
115
|
+
scrollTo(currentOptionIdx)
|
|
116
|
+
hasScrolledInitially.current = true
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const AnimatedView = RenderAnimatedView || View
|
|
120
|
+
variantStyles = JSON.parse(JSON.stringify(variantStyles))
|
|
121
|
+
return (
|
|
122
|
+
<Scroll
|
|
123
|
+
horizontal
|
|
124
|
+
showsHorizontalScrollIndicator={false}
|
|
125
|
+
style={variantStyles.scroll}
|
|
126
|
+
contentContainerStyle={variantStyles.scrollContent}
|
|
127
|
+
{...scrollProps}
|
|
128
|
+
ref={scrollRef}
|
|
129
|
+
>
|
|
130
|
+
<View style={variantStyles.wrapper}>
|
|
131
|
+
<AnimatedView {...props}
|
|
132
|
+
animated
|
|
133
|
+
style={[variantStyles.selectedBubble, widthStyle]}
|
|
134
|
+
animate={{
|
|
135
|
+
translateX,
|
|
136
|
+
}}
|
|
137
|
+
|
|
138
|
+
transition={_animation}
|
|
139
|
+
/>
|
|
140
|
+
{options.map((o, idx) => {
|
|
141
|
+
const selected = value === o.value
|
|
142
|
+
|
|
143
|
+
const touchableProps = {
|
|
144
|
+
key: idx,
|
|
145
|
+
debugName: `Segmented Control ${debugName}, option ${o.label}`,
|
|
146
|
+
onPress: onPress(o.value, idx),
|
|
147
|
+
style: [widthStyle, variantStyles.button],
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const textProps = {
|
|
151
|
+
text: o.label as string,
|
|
152
|
+
colorChangeConfig: _animation,
|
|
153
|
+
style: StyleSheet.flatten([variantStyles.text, selected && variantStyles['text:selected']]),
|
|
154
|
+
animated: true,
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if (RenderButton) {
|
|
158
|
+
return (
|
|
159
|
+
<RenderButton {...props} touchableProps={touchableProps} key={touchableProps.key} textProps={textProps} option={o}/>
|
|
160
|
+
)
|
|
161
|
+
}
|
|
162
|
+
return <Touchable
|
|
163
|
+
{...touchableProps}
|
|
164
|
+
key={touchableProps.key}
|
|
165
|
+
>
|
|
166
|
+
<Text
|
|
167
|
+
|
|
168
|
+
{...textProps}
|
|
169
|
+
/>
|
|
170
|
+
|
|
171
|
+
</Touchable>
|
|
172
|
+
|
|
173
|
+
})}
|
|
174
|
+
</View>
|
|
175
|
+
</Scroll>
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
type SegControlComponent = <T = string>(props: SegmentedControlProps<T> & {ref?: React.Ref<SegmentedControlRef>}) => ReactElement
|
|
181
|
+
|
|
182
|
+
export const SegmentedControl = _SegmentedControl as SegControlComponent
|