nx-react-native-cli 2.1.2 → 2.2.0
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/README.md +2 -2
- package/lib/index.cjs +36 -36
- package/package.json +1 -1
- package/templates/apps/mobile/Gemfile +7 -1
- package/templates/apps/mobile/android/gradle/wrapper/gradle-wrapper.properties +1 -1
- package/templates/apps/mobile/android/gradle.properties +1 -1
- package/templates/apps/mobile/android/gradlew +0 -0
- package/templates/apps/mobile/android/gradlew.bat +0 -0
- package/templates/apps/mobile/fastlane/Fastfile +1 -1
- package/templates/apps/mobile/ios/AppsMobile/AppDelegate.mm +34 -14
- package/templates/apps/mobile/package.json +2 -2
- package/templates/apps/mobile/src/app/index.tsx +0 -3
- package/templates/apps/mobile/src/assets/images/.gitkeep +0 -0
- package/templates/apps/mobile/src/components/atoms/BottomSheet/bottom-sheet.component.tsx +4 -1
- package/templates/apps/mobile/src/components/atoms/Button/button.component.tsx +3 -3
- package/templates/apps/mobile/src/components/atoms/KeyboardAwareScrollView/keyboard-aware-scroll-view.component.tsx +2 -2
- package/templates/apps/mobile/src/components/atoms/ListLoadingItem/list-loading-item.component.tsx +19 -27
- package/templates/apps/mobile/src/components/atoms/TextInput/bottom-sheet-text-input.component.tsx +79 -0
- package/templates/apps/mobile/src/components/atoms/TextInput/constants.ts +3 -0
- package/templates/apps/mobile/src/components/atoms/TextInput/index.ts +2 -0
- package/templates/apps/mobile/src/components/atoms/TextInput/text-input-area.component.tsx +68 -0
- package/templates/apps/mobile/src/components/atoms/TextInput/text-input.component.tsx +2 -63
- package/templates/apps/mobile/src/components/atoms/TextInput/util.ts +12 -0
- package/templates/apps/mobile/src/components/molecules/ScreenContainer/screen-container.component.tsx +27 -6
- package/templates/apps/mobile/src/icons/index.ts +1 -30
- package/templates/apps/mobile/src/screens/LandingScreen/landing.screen.tsx +1 -29
- package/templates/apps/mobile/src/assets/fonts/InterBlack.ttf +0 -0
- package/templates/apps/mobile/src/assets/fonts/InterBlackItalic.ttf +0 -0
- package/templates/apps/mobile/src/assets/fonts/InterBold.ttf +0 -0
- package/templates/apps/mobile/src/assets/fonts/InterBoldItalic.ttf +0 -0
- package/templates/apps/mobile/src/assets/fonts/InterExtraBold.ttf +0 -0
- package/templates/apps/mobile/src/assets/fonts/InterExtraBoldItalic.ttf +0 -0
- package/templates/apps/mobile/src/assets/fonts/InterExtraLight.ttf +0 -0
- package/templates/apps/mobile/src/assets/fonts/InterExtraLightItalic.ttf +0 -0
- package/templates/apps/mobile/src/assets/fonts/InterItalic.ttf +0 -0
- package/templates/apps/mobile/src/assets/fonts/InterLight.ttf +0 -0
- package/templates/apps/mobile/src/assets/fonts/InterLightItalic.ttf +0 -0
- package/templates/apps/mobile/src/assets/fonts/InterMedium.ttf +0 -0
- package/templates/apps/mobile/src/assets/fonts/InterMediumItalic.ttf +0 -0
- package/templates/apps/mobile/src/assets/fonts/InterRegular.ttf +0 -0
- package/templates/apps/mobile/src/assets/fonts/InterSemiBold.ttf +0 -0
- package/templates/apps/mobile/src/assets/fonts/InterSemiBoldItalic.ttf +0 -0
- package/templates/apps/mobile/src/assets/fonts/InterThin.ttf +0 -0
- package/templates/apps/mobile/src/assets/fonts/InterThinItalic.ttf +0 -0
- package/templates/apps/mobile/src/icons/checkbox-active.svg +0 -4
- package/templates/apps/mobile/src/icons/checkbox-unactive.svg +0 -4
- package/templates/apps/mobile/src/icons/close.svg +0 -3
- package/templates/apps/mobile/src/icons/download.svg +0 -4
- package/templates/apps/mobile/src/icons/email.svg +0 -10
- package/templates/apps/mobile/src/icons/eye-slash.svg +0 -11
- package/templates/apps/mobile/src/icons/eye.svg +0 -4
- package/templates/apps/mobile/src/icons/home.svg +0 -3
- package/templates/apps/mobile/src/icons/pencil.svg +0 -3
- package/templates/apps/mobile/src/icons/phone.svg +0 -3
- package/templates/apps/mobile/src/icons/user-circle.svg +0 -3
- package/templates/apps/mobile/src/icons/user.svg +0 -4
- package/templates/apps/mobile/src/icons/warning.svg +0 -3
package/package.json
CHANGED
|
@@ -10,5 +10,11 @@ gem 'activesupport', '>= 6.1.7.5', '!= 7.1.0'
|
|
|
10
10
|
gem 'xcodeproj', '< 1.26.0'
|
|
11
11
|
gem 'concurrent-ruby', '< 1.3.4'
|
|
12
12
|
|
|
13
|
+
# Ruby 3.4.0 has removed some libraries from the standard library.
|
|
14
|
+
gem 'bigdecimal'
|
|
15
|
+
gem 'logger'
|
|
16
|
+
gem 'benchmark'
|
|
17
|
+
gem 'mutex_m'
|
|
18
|
+
|
|
13
19
|
plugins_path = File.join(File.dirname(__FILE__), './fastlane', 'Pluginfile')
|
|
14
|
-
eval_gemfile(plugins_path) if File.exist?(plugins_path)
|
|
20
|
+
eval_gemfile(plugins_path) if File.exist?(plugins_path)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
distributionBase=GRADLE_USER_HOME
|
|
2
2
|
distributionPath=wrapper/dists
|
|
3
|
-
distributionUrl=https\://services.gradle.org/distributions/gradle-8.
|
|
3
|
+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
|
|
4
4
|
networkTimeout=10000
|
|
5
5
|
validateDistributionUrl=true
|
|
6
6
|
zipStoreBase=GRADLE_USER_HOME
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
# Specifies the JVM arguments used for the daemon process.
|
|
11
11
|
# The setting is particularly useful for tweaking memory settings.
|
|
12
12
|
# Default value: -Xmx512m -XX:MaxMetaspaceSize=256m
|
|
13
|
-
org.gradle.jvmargs=-
|
|
13
|
+
org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=4g
|
|
14
14
|
|
|
15
15
|
# When configured, Gradle will run in incubating parallel mode.
|
|
16
16
|
# This option should only be used with decoupled projects. More details, visit
|
|
File without changes
|
|
File without changes
|
|
@@ -3,26 +3,19 @@
|
|
|
3
3
|
#import <React/RCTBundleURLProvider.h>
|
|
4
4
|
#import <ReactAppDependencyProvider/RCTAppDependencyProvider.h>
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
#import <RCTDefaultReactNativeFactoryDelegate.h>
|
|
7
|
+
#import <RCTReactNativeFactory.h>
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
self.moduleName = @"AppsMobile";
|
|
11
|
-
self.dependencyProvider = [RCTAppDependencyProvider new];
|
|
12
|
-
// You can add your custom initial props in the dictionary below.
|
|
13
|
-
// They will be passed down to the ViewController used by React Native.
|
|
14
|
-
self.initialProps = @{};
|
|
9
|
+
@interface ReactNativeDelegate : RCTDefaultReactNativeFactoryDelegate
|
|
10
|
+
@end
|
|
15
11
|
|
|
16
|
-
|
|
17
|
-
}
|
|
12
|
+
@implementation ReactNativeDelegate
|
|
18
13
|
|
|
19
|
-
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
|
|
20
|
-
{
|
|
14
|
+
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge {
|
|
21
15
|
return [self bundleURL];
|
|
22
16
|
}
|
|
23
17
|
|
|
24
|
-
- (NSURL *)bundleURL
|
|
25
|
-
{
|
|
18
|
+
- (NSURL *)bundleURL {
|
|
26
19
|
#if DEBUG
|
|
27
20
|
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"src/main"];
|
|
28
21
|
#else
|
|
@@ -31,3 +24,30 @@
|
|
|
31
24
|
}
|
|
32
25
|
|
|
33
26
|
@end
|
|
27
|
+
|
|
28
|
+
@interface AppDelegate ()
|
|
29
|
+
@property (nonatomic, strong) ReactNativeDelegate *reactNativeDelegate;
|
|
30
|
+
@property (nonatomic, strong) RCTReactNativeFactory *reactNativeFactory;
|
|
31
|
+
@end
|
|
32
|
+
|
|
33
|
+
@implementation AppDelegate
|
|
34
|
+
|
|
35
|
+
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
|
36
|
+
{
|
|
37
|
+
ReactNativeDelegate *delegate = [ReactNativeDelegate new];
|
|
38
|
+
RCTReactNativeFactory *factory = [[RCTReactNativeFactory alloc] initWithDelegate:delegate];
|
|
39
|
+
delegate.dependencyProvider = [RCTAppDependencyProvider new];
|
|
40
|
+
|
|
41
|
+
self.reactNativeDelegate = delegate;
|
|
42
|
+
self.reactNativeFactory = factory;
|
|
43
|
+
|
|
44
|
+
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
|
45
|
+
|
|
46
|
+
[factory startReactNativeWithModuleName:@"AppsMobile"
|
|
47
|
+
inWindow:self.window
|
|
48
|
+
launchOptions:launchOptions];
|
|
49
|
+
|
|
50
|
+
return YES;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
@end
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"scripts": {
|
|
6
6
|
"android:connect": "adb reverse tcp:8081 tcp:8081",
|
|
7
7
|
"start": "npx nx start mobile --skip-nx-cache",
|
|
8
|
-
"run-ios": "npx nx run-ios mobile --skip-nx-cache --scheme=Dev --simulator='iPhone
|
|
8
|
+
"run-ios": "npx nx run-ios mobile --skip-nx-cache --scheme=Dev --simulator='iPhone 16'",
|
|
9
9
|
"run-android": "npx nx run-android mobile --skip-nx-cache",
|
|
10
10
|
"ensure-symlink": "npx nx ensure-symlink mobile",
|
|
11
11
|
"sync-deps": "npx nx sync-deps mobile",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"pre-build": "npm run ensure-symlink && npm run sync-deps && npm run pod-install",
|
|
16
16
|
"list:ios-configurations": "cd ios && xcodebuild -list",
|
|
17
17
|
"list:ios-devices": "xcrun xctrace list devices",
|
|
18
|
-
"xcode": "
|
|
18
|
+
"xcode": "xed -b ios",
|
|
19
19
|
"touch-xcode": "cd ios && touch .xcode.env",
|
|
20
20
|
"check-env:mobile": "cd ../.. && npm run check-env:mobile",
|
|
21
21
|
"setup-fastlane": "rbenv local && bundle install && bundle update",
|
|
@@ -7,7 +7,6 @@ import { GestureHandlerRootView } from 'react-native-gesture-handler';
|
|
|
7
7
|
import 'react-native-get-random-values';
|
|
8
8
|
import { MMKV } from 'react-native-mmkv';
|
|
9
9
|
import { SafeAreaProvider } from 'react-native-safe-area-context';
|
|
10
|
-
import { enableFreeze } from 'react-native-screens';
|
|
11
10
|
import { useDeviceContext } from 'twrnc';
|
|
12
11
|
|
|
13
12
|
import { StorageManager } from '@/components';
|
|
@@ -18,8 +17,6 @@ import 'react-native-url-polyfill/auto';
|
|
|
18
17
|
|
|
19
18
|
LogBox.ignoreLogs(['VirtualizedLists', 'onAnimatedValueUpdate']);
|
|
20
19
|
|
|
21
|
-
enableFreeze(true);
|
|
22
|
-
|
|
23
20
|
const CACHE_TIME = 0;
|
|
24
21
|
const STALE_TIME = 0;
|
|
25
22
|
|
|
File without changes
|
|
@@ -120,7 +120,10 @@ export function BottomSheet(props: BottomSheetProps) {
|
|
|
120
120
|
style,
|
|
121
121
|
]}
|
|
122
122
|
>
|
|
123
|
-
<BottomSheetScrollView
|
|
123
|
+
<BottomSheetScrollView
|
|
124
|
+
contentContainerStyle={contentContainerStyle}
|
|
125
|
+
keyboardShouldPersistTaps="handled"
|
|
126
|
+
>
|
|
124
127
|
{children}
|
|
125
128
|
</BottomSheetScrollView>
|
|
126
129
|
</BottomSheetModal>
|
|
@@ -47,7 +47,7 @@ export function Button(props: Props) {
|
|
|
47
47
|
<TouchableOpacity activeOpacity={activeOpacity} disabled={disabled} style={[style]} {...rest}>
|
|
48
48
|
<View
|
|
49
49
|
style={[
|
|
50
|
-
tw`bg-primary-
|
|
50
|
+
tw`bg-primary-500 items-center justify-center rounded-xl px-6 py-2`,
|
|
51
51
|
buttonStyle,
|
|
52
52
|
disabledInputStyle(disabled),
|
|
53
53
|
]}
|
|
@@ -64,8 +64,8 @@ export function OutlinedButton(props: Props) {
|
|
|
64
64
|
return (
|
|
65
65
|
<Button
|
|
66
66
|
{...rest}
|
|
67
|
-
buttonStyle={tw`border-primary-
|
|
68
|
-
textStyle={tw`text-primary-
|
|
67
|
+
buttonStyle={tw`border-primary-500 border-2 bg-white`}
|
|
68
|
+
textStyle={tw`text-primary-500`}
|
|
69
69
|
/>
|
|
70
70
|
);
|
|
71
71
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable no-magic-numbers */
|
|
1
2
|
import React from 'react';
|
|
2
3
|
import {
|
|
3
4
|
NativeScrollEvent,
|
|
@@ -14,7 +15,7 @@ import { DefaultComponentProps } from '@/types';
|
|
|
14
15
|
|
|
15
16
|
type Props = DefaultComponentProps & {
|
|
16
17
|
children?: React.ReactNode;
|
|
17
|
-
scrollViewRef?: React.RefObject<RNKeyboardAwareScrollView>;
|
|
18
|
+
scrollViewRef?: React.RefObject<RNKeyboardAwareScrollView | null>;
|
|
18
19
|
containerStyle?: StyleProp<ViewStyle>;
|
|
19
20
|
extraBottomPadding?: number;
|
|
20
21
|
refreshControl?: React.ReactElement<RefreshControlProps> | undefined;
|
|
@@ -39,7 +40,6 @@ export function KeyboardAwareScrollView(props: Props) {
|
|
|
39
40
|
const defaultContainerStyle = [
|
|
40
41
|
defaultStyle,
|
|
41
42
|
containerStyle,
|
|
42
|
-
// eslint-disable-next-line no-magic-numbers
|
|
43
43
|
extraBottomPadding && tw`pb-[${extraBottomPadding + 50}px]`,
|
|
44
44
|
];
|
|
45
45
|
|
package/templates/apps/mobile/src/components/atoms/ListLoadingItem/list-loading-item.component.tsx
CHANGED
|
@@ -1,55 +1,47 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { View } from 'react-native';
|
|
2
|
+
import { Dimensions, View } from 'react-native';
|
|
3
3
|
|
|
4
4
|
import { Skeleton } from '@/components/atoms/Skeleton';
|
|
5
5
|
import { tw } from '@/tailwind';
|
|
6
6
|
import { DefaultComponentProps } from '@/types';
|
|
7
7
|
|
|
8
|
+
const SPACING = 2;
|
|
9
|
+
const screenWidth = Dimensions.get('window').width;
|
|
10
|
+
|
|
8
11
|
type Props = DefaultComponentProps & {
|
|
12
|
+
count: number;
|
|
9
13
|
isLoading: boolean;
|
|
10
14
|
};
|
|
11
15
|
|
|
12
16
|
export function ListLoadingItemComponent(props: Props) {
|
|
13
|
-
const { isLoading, style } = props;
|
|
17
|
+
const { count, isLoading, style } = props;
|
|
18
|
+
const itemWidth = (screenWidth - (count + 1) * SPACING) / count;
|
|
14
19
|
|
|
15
20
|
return (
|
|
16
21
|
<View style={[style]}>
|
|
17
22
|
<View style={[tw`gap-2`, style]}>
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
</Skeleton>
|
|
24
|
-
<Skeleton isLoading={isLoading}>
|
|
25
|
-
{isLoading && <View style={tw`h-[100px] w-full`} />}
|
|
26
|
-
</Skeleton>
|
|
23
|
+
{Array.from({ length: count }).map((_, index) => (
|
|
24
|
+
<Skeleton key={index} isLoading={isLoading}>
|
|
25
|
+
{isLoading && <View style={tw`h-[${itemWidth}px] w-full`} />}
|
|
26
|
+
</Skeleton>
|
|
27
|
+
))}
|
|
27
28
|
</View>
|
|
28
29
|
</View>
|
|
29
30
|
);
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
export function ListLoadingHorizontalItemComponent(props: Props) {
|
|
33
|
-
const { isLoading, style } = props;
|
|
34
|
+
const { count, isLoading, style } = props;
|
|
35
|
+
const itemWidth = (screenWidth - (count + 1) * SPACING) / count;
|
|
34
36
|
|
|
35
37
|
return (
|
|
36
38
|
<View style={[style]}>
|
|
37
39
|
<View style={[tw`flex-row gap-2`, style]}>
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
</Skeleton>
|
|
44
|
-
<Skeleton isLoading={isLoading}>
|
|
45
|
-
{isLoading && <View style={tw`h-[200px] w-[100px]`} />}
|
|
46
|
-
</Skeleton>
|
|
47
|
-
<Skeleton isLoading={isLoading}>
|
|
48
|
-
{isLoading && <View style={tw`h-[200px] w-[100px]`} />}
|
|
49
|
-
</Skeleton>
|
|
50
|
-
<Skeleton isLoading={isLoading}>
|
|
51
|
-
{isLoading && <View style={tw`h-[200px] w-[100px]`} />}
|
|
52
|
-
</Skeleton>
|
|
40
|
+
{Array.from({ length: count }).map((_, index) => (
|
|
41
|
+
<Skeleton key={index} isLoading={isLoading}>
|
|
42
|
+
{isLoading && <View style={tw`h-[${itemWidth}px] w-[${itemWidth}px]`} />}
|
|
43
|
+
</Skeleton>
|
|
44
|
+
))}
|
|
53
45
|
</View>
|
|
54
46
|
</View>
|
|
55
47
|
);
|
package/templates/apps/mobile/src/components/atoms/TextInput/bottom-sheet-text-input.component.tsx
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { BottomSheetTextInput as RNBottomSheetTextInput } from '@gorhom/bottom-sheet';
|
|
2
|
+
import React, { useState } from 'react';
|
|
3
|
+
import {
|
|
4
|
+
TextInput as RNTextInput,
|
|
5
|
+
TextInputProps as RNTextInputProps,
|
|
6
|
+
StyleProp,
|
|
7
|
+
TextStyle,
|
|
8
|
+
View,
|
|
9
|
+
} from 'react-native';
|
|
10
|
+
|
|
11
|
+
import { DefaultNameInputProps } from '@/components/atoms/TextInput/constants';
|
|
12
|
+
import {
|
|
13
|
+
colors,
|
|
14
|
+
defaultInputContainerStyle,
|
|
15
|
+
defaultInputTextStyle,
|
|
16
|
+
disabledInputStyle,
|
|
17
|
+
focusedInputStyle,
|
|
18
|
+
} from '@/tailwind';
|
|
19
|
+
import { DefaultComponentProps } from '@/types';
|
|
20
|
+
|
|
21
|
+
export type BottomSheetTextInputProps = DefaultComponentProps &
|
|
22
|
+
RNTextInputProps & {
|
|
23
|
+
textInputRef?: React.RefObject<RNTextInput>;
|
|
24
|
+
textStyle?: StyleProp<TextStyle>;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export function BottomSheetTextInput(props: BottomSheetTextInputProps) {
|
|
28
|
+
const {
|
|
29
|
+
isDisabled = false,
|
|
30
|
+
multiline = false,
|
|
31
|
+
onChangeText,
|
|
32
|
+
placeholder,
|
|
33
|
+
style,
|
|
34
|
+
textInputRef,
|
|
35
|
+
textStyle,
|
|
36
|
+
value,
|
|
37
|
+
...extraProps
|
|
38
|
+
} = props;
|
|
39
|
+
const [isFocused, setFocused] = useState<boolean>(false);
|
|
40
|
+
|
|
41
|
+
function handleOnChangeText(text: string) {
|
|
42
|
+
onChangeText?.(text);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function handleOnFocus() {
|
|
46
|
+
setFocused(true);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function handleOnBlur() {
|
|
50
|
+
setFocused(false);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
<View
|
|
55
|
+
style={[
|
|
56
|
+
defaultInputContainerStyle,
|
|
57
|
+
focusedInputStyle(isFocused),
|
|
58
|
+
disabledInputStyle(isDisabled),
|
|
59
|
+
style,
|
|
60
|
+
]}
|
|
61
|
+
>
|
|
62
|
+
<RNBottomSheetTextInput
|
|
63
|
+
{...DefaultNameInputProps}
|
|
64
|
+
ref={textInputRef as unknown as any}
|
|
65
|
+
editable={!isDisabled}
|
|
66
|
+
multiline={multiline}
|
|
67
|
+
placeholder={placeholder}
|
|
68
|
+
placeholderTextColor={colors.gray[600]}
|
|
69
|
+
selectionColor={colors.primary[400]}
|
|
70
|
+
style={[defaultInputTextStyle, textStyle]}
|
|
71
|
+
value={value}
|
|
72
|
+
onBlur={handleOnBlur}
|
|
73
|
+
onChangeText={handleOnChangeText}
|
|
74
|
+
onFocus={handleOnFocus}
|
|
75
|
+
{...extraProps}
|
|
76
|
+
/>
|
|
77
|
+
</View>
|
|
78
|
+
);
|
|
79
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { useState, useEffect } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
TextInput as RNTextInput,
|
|
4
|
+
TextInputProps as RNTextInputProps,
|
|
5
|
+
StyleProp,
|
|
6
|
+
TextStyle,
|
|
7
|
+
} from 'react-native';
|
|
8
|
+
|
|
9
|
+
import { TextInput } from '@/components/atoms/TextInput';
|
|
10
|
+
import {
|
|
11
|
+
DefaultTextAreaInputProps,
|
|
12
|
+
TEXT_INPUT_MIN_HEIGHT,
|
|
13
|
+
} from '@/components/atoms/TextInput/constants';
|
|
14
|
+
import { getTextInputHeightAdjustment } from '@/components/atoms/TextInput/util';
|
|
15
|
+
import { DefaultComponentProps } from '@/types';
|
|
16
|
+
|
|
17
|
+
export type TextInputAreaProps = DefaultComponentProps &
|
|
18
|
+
RNTextInputProps & {
|
|
19
|
+
textInputRef?: React.RefObject<RNTextInput>;
|
|
20
|
+
textStyle?: StyleProp<TextStyle>;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export function TextInputArea(props: TextInputAreaProps) {
|
|
24
|
+
const {
|
|
25
|
+
numberOfLines = DefaultTextAreaInputProps.numberOfLines as number,
|
|
26
|
+
onChangeText,
|
|
27
|
+
textStyle,
|
|
28
|
+
value,
|
|
29
|
+
...extraProps
|
|
30
|
+
} = props;
|
|
31
|
+
const [numberOfNewLines, setNumberOfNewLines] = useState<number>(numberOfLines);
|
|
32
|
+
|
|
33
|
+
function handleOnChangeText(text: string) {
|
|
34
|
+
onChangeText?.(text);
|
|
35
|
+
}
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
if (!value) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const newLines = value.split(/\r\n|\r|\n/).length;
|
|
42
|
+
|
|
43
|
+
if (numberOfNewLines !== newLines) {
|
|
44
|
+
setNumberOfNewLines(newLines);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
48
|
+
}, [value]);
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<TextInput
|
|
52
|
+
{...DefaultTextAreaInputProps}
|
|
53
|
+
multiline
|
|
54
|
+
numberOfLines={numberOfLines}
|
|
55
|
+
textStyle={[
|
|
56
|
+
textStyle,
|
|
57
|
+
{
|
|
58
|
+
height: getTextInputHeightAdjustment(numberOfNewLines),
|
|
59
|
+
minHeight: TEXT_INPUT_MIN_HEIGHT,
|
|
60
|
+
textAlignVertical: 'top',
|
|
61
|
+
},
|
|
62
|
+
]}
|
|
63
|
+
value={value}
|
|
64
|
+
onChangeText={handleOnChangeText}
|
|
65
|
+
{...extraProps}
|
|
66
|
+
/>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
TextInput as RNTextInput,
|
|
4
4
|
TextInputProps as RNTextInputProps,
|
|
@@ -7,10 +7,7 @@ import {
|
|
|
7
7
|
View,
|
|
8
8
|
} from 'react-native';
|
|
9
9
|
|
|
10
|
-
import {
|
|
11
|
-
DefaultNameInputProps,
|
|
12
|
-
DefaultTextAreaInputProps,
|
|
13
|
-
} from '@/components/atoms/TextInput/constants';
|
|
10
|
+
import { DefaultNameInputProps } from '@/components/atoms/TextInput/constants';
|
|
14
11
|
import {
|
|
15
12
|
colors,
|
|
16
13
|
defaultInputContainerStyle,
|
|
@@ -20,17 +17,6 @@ import {
|
|
|
20
17
|
} from '@/tailwind';
|
|
21
18
|
import { DefaultComponentProps } from '@/types';
|
|
22
19
|
|
|
23
|
-
export const TEXT_INPUT_MIN_HEIGHT = 100;
|
|
24
|
-
export const TEXT_INPUT_LINE_HEIGHT = 21;
|
|
25
|
-
|
|
26
|
-
export function getTextInputHeightAdjustment(numberOfNewLines: number) {
|
|
27
|
-
if (numberOfNewLines < 2) {
|
|
28
|
-
return TEXT_INPUT_MIN_HEIGHT;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
return TEXT_INPUT_MIN_HEIGHT + (numberOfNewLines - 2) * TEXT_INPUT_LINE_HEIGHT;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
20
|
export type TextInputProps = DefaultComponentProps &
|
|
35
21
|
RNTextInputProps & {
|
|
36
22
|
textInputRef?: React.RefObject<RNTextInput>;
|
|
@@ -90,50 +76,3 @@ export function TextInput(props: TextInputProps) {
|
|
|
90
76
|
</View>
|
|
91
77
|
);
|
|
92
78
|
}
|
|
93
|
-
|
|
94
|
-
export function TextInputArea(props: TextInputProps) {
|
|
95
|
-
const {
|
|
96
|
-
numberOfLines = DefaultTextAreaInputProps.numberOfLines as number,
|
|
97
|
-
onChangeText,
|
|
98
|
-
textStyle,
|
|
99
|
-
value,
|
|
100
|
-
...extraProps
|
|
101
|
-
} = props;
|
|
102
|
-
const [numberOfNewLines, setNumberOfNewLines] = useState<number>(numberOfLines);
|
|
103
|
-
|
|
104
|
-
function handleOnChangeText(text: string) {
|
|
105
|
-
onChangeText?.(text);
|
|
106
|
-
}
|
|
107
|
-
useEffect(() => {
|
|
108
|
-
if (!value) {
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const newLines = value.split(/\r\n|\r|\n/).length;
|
|
113
|
-
|
|
114
|
-
if (numberOfNewLines !== newLines) {
|
|
115
|
-
setNumberOfNewLines(newLines);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
119
|
-
}, [value]);
|
|
120
|
-
|
|
121
|
-
return (
|
|
122
|
-
<TextInput
|
|
123
|
-
{...DefaultTextAreaInputProps}
|
|
124
|
-
multiline
|
|
125
|
-
numberOfLines={numberOfLines}
|
|
126
|
-
textStyle={[
|
|
127
|
-
textStyle,
|
|
128
|
-
{
|
|
129
|
-
height: getTextInputHeightAdjustment(numberOfNewLines),
|
|
130
|
-
minHeight: TEXT_INPUT_MIN_HEIGHT,
|
|
131
|
-
textAlignVertical: 'top',
|
|
132
|
-
},
|
|
133
|
-
]}
|
|
134
|
-
value={value}
|
|
135
|
-
onChangeText={handleOnChangeText}
|
|
136
|
-
{...extraProps}
|
|
137
|
-
/>
|
|
138
|
-
);
|
|
139
|
-
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import {
|
|
2
|
+
TEXT_INPUT_LINE_HEIGHT,
|
|
3
|
+
TEXT_INPUT_MIN_HEIGHT,
|
|
4
|
+
} from '@/components/atoms/TextInput/constants';
|
|
5
|
+
|
|
6
|
+
export function getTextInputHeightAdjustment(numberOfNewLines: number) {
|
|
7
|
+
if (numberOfNewLines < 2) {
|
|
8
|
+
return TEXT_INPUT_MIN_HEIGHT;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
return TEXT_INPUT_MIN_HEIGHT + (numberOfNewLines - 2) * TEXT_INPUT_LINE_HEIGHT;
|
|
12
|
+
}
|
|
@@ -20,7 +20,7 @@ import { tw } from '@/tailwind';
|
|
|
20
20
|
|
|
21
21
|
type Props = SafeAreaProviderProps & {
|
|
22
22
|
barStyle?: StatusBarStyle;
|
|
23
|
-
scrollViewRef?: React.RefObject<RNKeyboardAwareScrollView>;
|
|
23
|
+
scrollViewRef?: React.RefObject<RNKeyboardAwareScrollView | null>;
|
|
24
24
|
containerStyle?: StyleProp<ViewStyle>;
|
|
25
25
|
excludedEdges?: Edge[];
|
|
26
26
|
extraBottomPadding?: number;
|
|
@@ -29,6 +29,7 @@ type Props = SafeAreaProviderProps & {
|
|
|
29
29
|
shouldShowStatusBar?: boolean;
|
|
30
30
|
shouldBeTranslucent?: boolean;
|
|
31
31
|
statusBarColor?: string;
|
|
32
|
+
useSafeAreaView?: boolean;
|
|
32
33
|
onScroll?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;
|
|
33
34
|
};
|
|
34
35
|
|
|
@@ -55,12 +56,8 @@ export function ScreenContainer(props: Props) {
|
|
|
55
56
|
shouldShowStatusBar = true,
|
|
56
57
|
statusBarColor = 'transparent',
|
|
57
58
|
style,
|
|
59
|
+
useSafeAreaView = true,
|
|
58
60
|
} = props;
|
|
59
|
-
const edges =
|
|
60
|
-
excludedEdges.length > 0
|
|
61
|
-
? safeAreaViewEdges.filter((edge) => !excludedEdges.includes(edge))
|
|
62
|
-
: safeAreaViewEdges;
|
|
63
|
-
|
|
64
61
|
useFocusEffect(() => {
|
|
65
62
|
StatusBar.setHidden(!shouldShowStatusBar);
|
|
66
63
|
if (CONFIG.IS_ANDROID) {
|
|
@@ -77,6 +74,30 @@ export function ScreenContainer(props: Props) {
|
|
|
77
74
|
extraBottomPadding && tw`pb-[${extraBottomPadding + 50}px]`,
|
|
78
75
|
];
|
|
79
76
|
|
|
77
|
+
if (!useSafeAreaView) {
|
|
78
|
+
return (
|
|
79
|
+
<View style={[tw`flex-1 bg-white`, style]}>
|
|
80
|
+
{hasScroll ? (
|
|
81
|
+
<KeyboardAwareScrollView
|
|
82
|
+
containerStyle={defaultContainerStyle}
|
|
83
|
+
refreshControl={refreshControl as ReactElement<RefreshControlProps>}
|
|
84
|
+
scrollViewRef={scrollViewRef}
|
|
85
|
+
onScroll={onScroll}
|
|
86
|
+
>
|
|
87
|
+
{children}
|
|
88
|
+
</KeyboardAwareScrollView>
|
|
89
|
+
) : (
|
|
90
|
+
<View style={defaultContainerStyle}>{children}</View>
|
|
91
|
+
)}
|
|
92
|
+
</View>
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const edges =
|
|
97
|
+
excludedEdges.length > 0
|
|
98
|
+
? safeAreaViewEdges.filter((edge) => !excludedEdges.includes(edge))
|
|
99
|
+
: safeAreaViewEdges;
|
|
100
|
+
|
|
80
101
|
return (
|
|
81
102
|
<SafeAreaView edges={edges} style={[tw`flex-1 bg-white`, style]}>
|
|
82
103
|
{hasScroll ? (
|
|
@@ -1,33 +1,4 @@
|
|
|
1
1
|
import ArrowLeftIcon from './arrow-left.svg';
|
|
2
|
-
import ActiveCheckboxIcon from './checkbox-active.svg';
|
|
3
|
-
import UnActiveCheckboxIcon from './checkbox-unactive.svg';
|
|
4
|
-
import CloseIcon from './close.svg';
|
|
5
|
-
import DownloadIcon from './download.svg';
|
|
6
|
-
import EmailIcon from './email.svg';
|
|
7
|
-
import EyeSlashIcon from './eye-slash.svg';
|
|
8
|
-
import EyeIcon from './eye.svg';
|
|
9
2
|
import GearIcon from './gear.svg';
|
|
10
|
-
import HomeIcon from './home.svg';
|
|
11
|
-
import PencilIcon from './pencil.svg';
|
|
12
|
-
import PhoneIcon from './phone.svg';
|
|
13
|
-
import UserCircleIcon from './user-circle.svg';
|
|
14
|
-
import UserIcon from './user.svg';
|
|
15
|
-
import WarningIcon from './warning.svg';
|
|
16
3
|
|
|
17
|
-
export {
|
|
18
|
-
ActiveCheckboxIcon,
|
|
19
|
-
ArrowLeftIcon,
|
|
20
|
-
CloseIcon,
|
|
21
|
-
DownloadIcon,
|
|
22
|
-
EmailIcon,
|
|
23
|
-
EyeIcon,
|
|
24
|
-
EyeSlashIcon,
|
|
25
|
-
GearIcon,
|
|
26
|
-
HomeIcon,
|
|
27
|
-
PencilIcon,
|
|
28
|
-
PhoneIcon,
|
|
29
|
-
UnActiveCheckboxIcon,
|
|
30
|
-
UserCircleIcon,
|
|
31
|
-
UserIcon,
|
|
32
|
-
WarningIcon,
|
|
33
|
-
};
|
|
4
|
+
export { ArrowLeftIcon, GearIcon };
|