@momo-kits/foundation 0.92.21-beta.0 → 0.92.21-beta.2
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/Application/BottomTab/BottomTabBar.tsx +2 -2
- package/Application/BottomTab/index.tsx +1 -1
- package/Application/Components.tsx +86 -38
- package/Application/Navigation.ts +0 -13
- package/Application/types.ts +18 -15
- package/Application/utils.tsx +0 -9
- package/Button/index.tsx +0 -1
- package/Icon/types.ts +1 -0
- package/Input/InputDropDown.tsx +2 -2
- package/Input/InputMoney.tsx +3 -3
- package/Input/InputOTP.tsx +4 -4
- package/Input/InputSearch.tsx +166 -147
- package/Input/TextTyping.tsx +113 -0
- package/Input/index.tsx +11 -1
- package/Layout/AnimatedInputSearch.tsx +58 -0
- package/Layout/Screen.tsx +109 -25
- package/Layout/styles.ts +0 -6
- package/Layout/types.ts +20 -1
- package/Title/index.tsx +9 -6
- package/package.json +2 -2
- package/publish.sh +6 -6
package/Layout/Screen.tsx
CHANGED
|
@@ -2,14 +2,17 @@ import {useHeaderHeight} from '@react-navigation/stack';
|
|
|
2
2
|
import React, {
|
|
3
3
|
forwardRef,
|
|
4
4
|
Fragment,
|
|
5
|
+
LegacyRef,
|
|
5
6
|
ReactNode,
|
|
6
7
|
useContext,
|
|
7
8
|
useEffect,
|
|
8
9
|
useRef,
|
|
10
|
+
useState,
|
|
9
11
|
} from 'react';
|
|
10
12
|
import {
|
|
11
13
|
Animated,
|
|
12
14
|
KeyboardAvoidingView,
|
|
15
|
+
LayoutChangeEvent,
|
|
13
16
|
NativeScrollEvent,
|
|
14
17
|
NativeSyntheticEvent,
|
|
15
18
|
Platform,
|
|
@@ -24,13 +27,20 @@ import {
|
|
|
24
27
|
HeaderTitle,
|
|
25
28
|
} from '../Application';
|
|
26
29
|
import Navigation from '../Application/Navigation';
|
|
27
|
-
import {
|
|
30
|
+
import {
|
|
31
|
+
AnimatedHeader,
|
|
32
|
+
HeaderRightActions,
|
|
33
|
+
HeaderRightToolkit,
|
|
34
|
+
NavigationOptions,
|
|
35
|
+
} from '../Application/types';
|
|
28
36
|
import {Colors, Spacing, Styles} from '../Consts';
|
|
29
37
|
import {FloatingButton, FloatingButtonProps} from './FloatingButton';
|
|
30
|
-
import {Image} from '../Image';
|
|
31
38
|
import {Card, Section, validateChildren} from './index';
|
|
32
39
|
import styles from './styles';
|
|
33
40
|
import {HeaderType} from './types';
|
|
41
|
+
import AnimatedInputSearch from './AnimatedInputSearch';
|
|
42
|
+
import {InputSearchProps, InputSearchRef} from '../Input';
|
|
43
|
+
import {ExtendBackground, HeaderRight} from '../Application/Components';
|
|
34
44
|
|
|
35
45
|
export interface ScreenProps extends ViewProps {
|
|
36
46
|
/**
|
|
@@ -101,8 +111,15 @@ export interface ScreenProps extends ViewProps {
|
|
|
101
111
|
* Optional. If `true`, the screen content is using grid layout by span.
|
|
102
112
|
*/
|
|
103
113
|
useGridLayout?: boolean;
|
|
114
|
+
|
|
115
|
+
inputSearchProps?: InputSearchProps;
|
|
116
|
+
|
|
117
|
+
headerRight?: HeaderRightActions | HeaderRightToolkit | CustomHeaderRight;
|
|
118
|
+
inputSearchRef?: LegacyRef<InputSearchRef>;
|
|
104
119
|
}
|
|
105
120
|
|
|
121
|
+
type CustomHeaderRight = (props: any) => Element;
|
|
122
|
+
|
|
106
123
|
const Screen = forwardRef(
|
|
107
124
|
(
|
|
108
125
|
{
|
|
@@ -120,26 +137,31 @@ const Screen = forwardRef(
|
|
|
120
137
|
floatingButtonProps,
|
|
121
138
|
useGridLayout = true,
|
|
122
139
|
keyboardVerticalOffset,
|
|
140
|
+
inputSearchProps,
|
|
141
|
+
headerRight,
|
|
142
|
+
inputSearchRef,
|
|
123
143
|
}: ScreenProps,
|
|
124
|
-
ref
|
|
144
|
+
ref
|
|
125
145
|
) => {
|
|
126
146
|
const animatedValue = useRef<Animated.Value>(new Animated.Value(0));
|
|
127
147
|
const {theme} = useContext(ApplicationContext);
|
|
128
148
|
const insets = useSafeAreaInsets();
|
|
129
149
|
const heightHeader = useHeaderHeight();
|
|
150
|
+
const scrollViewRef = useRef<any>(ref);
|
|
130
151
|
const currentTint = useRef(Colors.black_01);
|
|
131
|
-
const isTab = navigation?.instance?.getState?.()?.type
|
|
152
|
+
const isTab = navigation?.instance?.getState?.()?.type === 'tab';
|
|
153
|
+
const [headerRightWidth, setHeaderRightWidth] = useState(0);
|
|
132
154
|
|
|
133
155
|
let styleAnimatedHeader: NavigationOptions;
|
|
134
156
|
let handleScroll;
|
|
135
157
|
let headerBackground: string | undefined = undefined;
|
|
136
158
|
let Component: any = View;
|
|
137
159
|
let keyboardOffset = heightHeader - 20;
|
|
138
|
-
if (headerType
|
|
160
|
+
if (headerType === 'extended' || animatedHeader) {
|
|
139
161
|
keyboardOffset = -20;
|
|
140
162
|
}
|
|
141
163
|
|
|
142
|
-
if (headerType
|
|
164
|
+
if (headerType === 'extended') {
|
|
143
165
|
headerBackground = theme.assets?.headerBackground;
|
|
144
166
|
}
|
|
145
167
|
|
|
@@ -157,7 +179,7 @@ const Screen = forwardRef(
|
|
|
157
179
|
<HeaderTitle {...props} animatedValue={animatedValue.current} />
|
|
158
180
|
),
|
|
159
181
|
};
|
|
160
|
-
if (animatedHeader.type
|
|
182
|
+
if (animatedHeader.type === 'surface') {
|
|
161
183
|
styleAnimatedHeader = {
|
|
162
184
|
...styleAnimatedHeader,
|
|
163
185
|
headerBackground: (props: any) => (
|
|
@@ -180,6 +202,7 @@ const Screen = forwardRef(
|
|
|
180
202
|
}),
|
|
181
203
|
};
|
|
182
204
|
}
|
|
205
|
+
|
|
183
206
|
navigation?.setOptions(styleAnimatedHeader);
|
|
184
207
|
}
|
|
185
208
|
}, [animatedHeader]);
|
|
@@ -187,6 +210,22 @@ const Screen = forwardRef(
|
|
|
187
210
|
useEffect(() => {
|
|
188
211
|
if (!animatedHeader) {
|
|
189
212
|
let headerOptions: NavigationOptions;
|
|
213
|
+
|
|
214
|
+
const interpolateConfig: Animated.InterpolationConfigType =
|
|
215
|
+
inputSearchProps
|
|
216
|
+
? {
|
|
217
|
+
inputRange: [0, 100],
|
|
218
|
+
outputRange: [1, 0],
|
|
219
|
+
extrapolate: 'clamp',
|
|
220
|
+
}
|
|
221
|
+
: {
|
|
222
|
+
inputRange: [0, 200],
|
|
223
|
+
outputRange: [0, 1],
|
|
224
|
+
extrapolate: 'clamp',
|
|
225
|
+
};
|
|
226
|
+
const titleOpacity =
|
|
227
|
+
animatedValue.current.interpolate(interpolateConfig);
|
|
228
|
+
|
|
190
229
|
switch (headerType) {
|
|
191
230
|
case 'none':
|
|
192
231
|
headerOptions = {
|
|
@@ -214,7 +253,9 @@ const Screen = forwardRef(
|
|
|
214
253
|
headerTransparent: true,
|
|
215
254
|
headerTintColor: Colors.black_01,
|
|
216
255
|
headerBackground: () => null,
|
|
217
|
-
headerTitle: (props: any) =>
|
|
256
|
+
headerTitle: (props: any) => (
|
|
257
|
+
<HeaderTitle {...props} titleOpacity={titleOpacity} />
|
|
258
|
+
),
|
|
218
259
|
};
|
|
219
260
|
break;
|
|
220
261
|
|
|
@@ -230,13 +271,33 @@ const Screen = forwardRef(
|
|
|
230
271
|
}
|
|
231
272
|
}, [headerType]);
|
|
232
273
|
|
|
274
|
+
useEffect(() => {
|
|
275
|
+
if (headerRight) {
|
|
276
|
+
navigation?.setOptions({
|
|
277
|
+
headerRight: (props: any) => (
|
|
278
|
+
<View onLayout={onHeaderRightLayout}>
|
|
279
|
+
{typeof headerRight === 'function' ? (
|
|
280
|
+
headerRight(props)
|
|
281
|
+
) : (
|
|
282
|
+
<HeaderRight {...props} {...headerRight} />
|
|
283
|
+
)}
|
|
284
|
+
</View>
|
|
285
|
+
),
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
}, [headerRight]);
|
|
289
|
+
|
|
290
|
+
const onHeaderRightLayout = (e: LayoutChangeEvent) => {
|
|
291
|
+
setHeaderRightWidth(e.nativeEvent.layout.width);
|
|
292
|
+
};
|
|
293
|
+
|
|
233
294
|
/**
|
|
234
295
|
* animated when use scroll && animated value
|
|
235
296
|
*/
|
|
236
297
|
if (scrollable) {
|
|
237
298
|
Component = Animated.ScrollView;
|
|
238
299
|
handleScroll = scrollViewProps?.onScroll;
|
|
239
|
-
if (animatedHeader || floatingButtonProps?.icon) {
|
|
300
|
+
if (animatedHeader || floatingButtonProps?.icon || inputSearchProps) {
|
|
240
301
|
handleScroll = Animated.event(
|
|
241
302
|
[
|
|
242
303
|
{
|
|
@@ -249,13 +310,13 @@ const Screen = forwardRef(
|
|
|
249
310
|
useNativeDriver: true,
|
|
250
311
|
listener: (e: NativeSyntheticEvent<NativeScrollEvent>) => {
|
|
251
312
|
scrollViewProps?.onScroll?.(e);
|
|
252
|
-
if (animatedHeader?.type
|
|
313
|
+
if (animatedHeader?.type === 'surface') {
|
|
253
314
|
const offsetY = e.nativeEvent.contentOffset.y;
|
|
254
315
|
let color = Colors.black_01;
|
|
255
316
|
if (offsetY > 50) {
|
|
256
317
|
color = theme.colors.text.default;
|
|
257
318
|
}
|
|
258
|
-
if (color
|
|
319
|
+
if (color !== currentTint.current) {
|
|
259
320
|
currentTint.current = color;
|
|
260
321
|
navigation?.setOptions({
|
|
261
322
|
headerTintColor: color,
|
|
@@ -263,11 +324,26 @@ const Screen = forwardRef(
|
|
|
263
324
|
}
|
|
264
325
|
}
|
|
265
326
|
},
|
|
266
|
-
}
|
|
327
|
+
}
|
|
267
328
|
);
|
|
268
329
|
}
|
|
269
330
|
}
|
|
270
331
|
|
|
332
|
+
const handleScrollEnd = (e: NativeSyntheticEvent<NativeScrollEvent>) => {
|
|
333
|
+
const offsetY = e.nativeEvent.contentOffset.y;
|
|
334
|
+
|
|
335
|
+
if (inputSearchProps && offsetY < 100 && offsetY > 0) {
|
|
336
|
+
Animated.timing(animatedValue.current, {
|
|
337
|
+
toValue: 0,
|
|
338
|
+
useNativeDriver: true,
|
|
339
|
+
duration: 300,
|
|
340
|
+
}).start();
|
|
341
|
+
scrollViewRef.current?.scrollTo({y: 0, animated: true});
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
scrollViewProps?.onScrollEndDrag?.(e);
|
|
345
|
+
};
|
|
346
|
+
|
|
271
347
|
/**
|
|
272
348
|
* render top navigation banner
|
|
273
349
|
*/
|
|
@@ -287,7 +363,7 @@ const Screen = forwardRef(
|
|
|
287
363
|
if (Array.isArray(results)) {
|
|
288
364
|
return results.map((item, index) => {
|
|
289
365
|
const space = item?.props?.useMargin === false ? 0 : Spacing.M;
|
|
290
|
-
if (item?.type
|
|
366
|
+
if (item?.type === Fragment) {
|
|
291
367
|
return renderContent(item?.props?.children);
|
|
292
368
|
}
|
|
293
369
|
if (item) {
|
|
@@ -307,7 +383,7 @@ const Screen = forwardRef(
|
|
|
307
383
|
} else {
|
|
308
384
|
const item: any = children;
|
|
309
385
|
const space = item?.props?.useMargin === false ? 0 : Spacing.M;
|
|
310
|
-
if (item?.type
|
|
386
|
+
if (item?.type === Fragment) {
|
|
311
387
|
return renderContent(item?.props?.children);
|
|
312
388
|
}
|
|
313
389
|
return (
|
|
@@ -327,15 +403,21 @@ const Screen = forwardRef(
|
|
|
327
403
|
return (
|
|
328
404
|
<View style={[Styles.flex, {backgroundColor}]}>
|
|
329
405
|
{!!headerBackground && (
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
406
|
+
<ExtendBackground
|
|
407
|
+
headerBackground={headerBackground}
|
|
408
|
+
heightHeader={heightHeader}
|
|
409
|
+
animatedValue={animatedValue.current}
|
|
410
|
+
/>
|
|
411
|
+
)}
|
|
412
|
+
{inputSearchProps && (
|
|
413
|
+
<AnimatedInputSearch
|
|
414
|
+
animatedValue={animatedValue.current}
|
|
415
|
+
headerRightWidth={headerRightWidth}
|
|
416
|
+
headerType={headerType}
|
|
417
|
+
heightHeader={heightHeader}
|
|
418
|
+
inputSearchProps={inputSearchProps}
|
|
419
|
+
inputRef={inputSearchRef}
|
|
420
|
+
/>
|
|
339
421
|
)}
|
|
340
422
|
<KeyboardAvoidingView
|
|
341
423
|
style={Styles.flex}
|
|
@@ -349,9 +431,11 @@ const Screen = forwardRef(
|
|
|
349
431
|
|
|
350
432
|
<Component
|
|
351
433
|
{...scrollViewProps}
|
|
352
|
-
ref={
|
|
434
|
+
ref={scrollViewRef}
|
|
353
435
|
showsVerticalScrollIndicator={false}
|
|
354
436
|
onScroll={handleScroll}
|
|
437
|
+
onScrollEndDrag={handleScrollEnd}
|
|
438
|
+
scrollEventThrottle={16}
|
|
355
439
|
style={Styles.flex}>
|
|
356
440
|
<View
|
|
357
441
|
style={[styles.screenBanner, {maxHeight: 210 + layoutOffset}]}>
|
|
@@ -387,7 +471,7 @@ const Screen = forwardRef(
|
|
|
387
471
|
</KeyboardAvoidingView>
|
|
388
472
|
</View>
|
|
389
473
|
);
|
|
390
|
-
}
|
|
474
|
+
}
|
|
391
475
|
);
|
|
392
476
|
|
|
393
477
|
export default Screen;
|
package/Layout/styles.ts
CHANGED
|
@@ -2,12 +2,6 @@ import {Platform, StyleSheet} from 'react-native';
|
|
|
2
2
|
import {Colors, Radius, Spacing} from '../Consts';
|
|
3
3
|
|
|
4
4
|
export default StyleSheet.create({
|
|
5
|
-
extendedHeader: {
|
|
6
|
-
aspectRatio: 1.75,
|
|
7
|
-
position: 'absolute',
|
|
8
|
-
width: '100%',
|
|
9
|
-
height: 210,
|
|
10
|
-
},
|
|
11
5
|
screenBanner: {
|
|
12
6
|
width: '100%',
|
|
13
7
|
},
|
package/Layout/types.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
import {Animated} from 'react-native';
|
|
2
|
+
import {InputSearchProps, InputSearchRef} from '../Input';
|
|
3
|
+
import {LegacyRef} from 'react';
|
|
4
|
+
|
|
5
|
+
export type HeaderType = 'default' | 'surface' | 'extended' | 'search' | 'none';
|
|
2
6
|
|
|
3
7
|
export type GridContextProps = {
|
|
4
8
|
/**
|
|
@@ -21,3 +25,18 @@ export type GridContextProps = {
|
|
|
21
25
|
*/
|
|
22
26
|
getSizeSpan: (span: number) => number;
|
|
23
27
|
};
|
|
28
|
+
|
|
29
|
+
export type AnimatedInputSearchProps = {
|
|
30
|
+
animatedValue: Animated.Value;
|
|
31
|
+
headerRightWidth: number;
|
|
32
|
+
heightHeader: number;
|
|
33
|
+
headerType: HeaderType;
|
|
34
|
+
inputSearchProps?: InputSearchProps;
|
|
35
|
+
inputRef?: LegacyRef<InputSearchRef>;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export type ExtendHeaderProps = {
|
|
39
|
+
headerBackground: string;
|
|
40
|
+
animatedValue: Animated.Value;
|
|
41
|
+
heightHeader: number;
|
|
42
|
+
};
|
package/Title/index.tsx
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import React, {FC, useContext, useState} from 'react';
|
|
2
2
|
import {Text as RNText, TouchableOpacity, View, ViewStyle} from 'react-native';
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
import {
|
|
4
|
+
Typography,
|
|
5
|
+
Colors,
|
|
6
|
+
Icon,
|
|
7
|
+
Badge,
|
|
8
|
+
ApplicationContext,
|
|
9
|
+
scaleSize,
|
|
10
|
+
Text,
|
|
11
|
+
} from '@momo-kits/foundation';
|
|
8
12
|
import styles from './styles';
|
|
9
13
|
import {TitleProps} from './types';
|
|
10
|
-
import {Typography} from '../Text/types';
|
|
11
14
|
|
|
12
15
|
const Title: FC<TitleProps> = ({
|
|
13
16
|
title = 'Title',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@momo-kits/foundation",
|
|
3
|
-
"version": "0.92.21-beta.
|
|
3
|
+
"version": "0.92.21-beta.2",
|
|
4
4
|
"description": "React Native Component Kits",
|
|
5
5
|
"main": "index.ts",
|
|
6
6
|
"scripts": {},
|
|
@@ -43,4 +43,4 @@
|
|
|
43
43
|
},
|
|
44
44
|
"author": "@momo-kits/foundation",
|
|
45
45
|
"license": "ISC"
|
|
46
|
-
}
|
|
46
|
+
}
|
package/publish.sh
CHANGED
|
@@ -7,16 +7,16 @@ rsync -r --exclude=/dist ./* dist
|
|
|
7
7
|
cd dist
|
|
8
8
|
|
|
9
9
|
if [ "$1" == "stable" ]; then
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
npm version $(npm view @momo-kits/foundation@stable version)
|
|
11
|
+
npm version patch
|
|
12
12
|
npm publish --tag stable --access=public
|
|
13
13
|
elif [ "$1" == "latest" ]; then
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
npm version $(npm view @momo-kits/foundation@latest version)
|
|
15
|
+
npm version prerelease --preid=rc
|
|
16
16
|
npm publish --tag latest --access=public
|
|
17
17
|
else
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
npm version $(npm view @momo-kits/foundation@beta version)
|
|
19
|
+
npm version prerelease --preid=beta
|
|
20
20
|
npm publish --tag beta --access=public
|
|
21
21
|
fi
|
|
22
22
|
|