@testspectra/cli 1.2.11 → 1.2.13
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/commands/init.d.ts +3 -1
- package/dist/commands/init.js +67 -5
- package/dist/commands/test.d.ts +12 -0
- package/dist/commands/test.js +140 -1
- package/dist/config/schema.d.ts +24 -0
- package/dist/generator/harness-generator.d.ts +13 -0
- package/dist/generator/harness-generator.js +51 -0
- package/dist/generator/index.d.ts +1 -0
- package/dist/generator/index.js +1 -0
- package/dist/generator/page-object-declarations.d.ts +27 -0
- package/dist/generator/page-object-declarations.js +142 -0
- package/dist/generator/type-generator.d.ts +8 -3
- package/dist/generator/type-generator.js +51 -89
- package/dist/index.js +4 -1
- package/dist/linter/spec-linter.js +34 -4
- package/dist/refactor/refactor-engine.js +62 -34
- package/dist/utils/dev-server-health.d.ts +10 -0
- package/dist/utils/dev-server-health.js +65 -0
- package/dist/utils/dev-server-manager.d.ts +5 -0
- package/dist/utils/dev-server-manager.js +25 -0
- package/dist/utils/update-notifier.d.ts +17 -0
- package/dist/utils/update-notifier.js +47 -3
- package/package.json +10 -9
- package/templates/default/package.json +3 -3
- package/templates/nx/package.json +3 -3
- package/templates/react-component/package.json +3 -3
- package/templates/react-native-component/.testspectra/harness/App.tsx +15 -0
- package/templates/react-native-component/.testspectra/harness/index.js +6 -0
- package/templates/react-native-component/.testspectra/tsconfig/android.json +105 -0
- package/templates/react-native-component/.testspectra/tsconfig/android.tsbuildinfo +1 -0
- package/templates/react-native-component/.testspectra/tsconfig/common.json +164 -0
- package/templates/react-native-component/.testspectra/tsconfig/common.tsbuildinfo +1 -0
- package/templates/react-native-component/.testspectra/tsconfig/ios.json +105 -0
- package/templates/react-native-component/.testspectra/tsconfig/ios.tsbuildinfo +1 -0
- package/templates/react-native-component/.testspectra/tsconfig/mobile.json +137 -0
- package/templates/react-native-component/.testspectra/tsconfig/mobile.tsbuildinfo +1 -0
- package/templates/react-native-component/.testspectra/tsconfig/web.json +137 -0
- package/templates/react-native-component/.testspectra/tsconfig/web.tsbuildinfo +1 -0
- package/templates/react-native-component/.testspectra/tsconfig.json +29 -0
- package/templates/react-native-component/.testspectra/types/android.d.ts +22 -0
- package/templates/react-native-component/.testspectra/types/common.d.ts +19 -0
- package/templates/react-native-component/.testspectra/types/env.d.ts +6 -0
- package/templates/react-native-component/.testspectra/types/fixtures.d.ts +6 -0
- package/templates/react-native-component/.testspectra/types/index.d.ts +1 -0
- package/templates/react-native-component/.testspectra/types/ios.d.ts +22 -0
- package/templates/react-native-component/.testspectra/types/mobile.d.ts +22 -0
- package/templates/react-native-component/.testspectra/types/plugins/android.d.ts +2 -0
- package/templates/react-native-component/.testspectra/types/plugins/common.d.ts +2 -0
- package/templates/react-native-component/.testspectra/types/plugins/ios.d.ts +2 -0
- package/templates/react-native-component/.testspectra/types/plugins/mobile.d.ts +2 -0
- package/templates/react-native-component/.testspectra/types/plugins/web.d.ts +2 -0
- package/templates/react-native-component/.testspectra/types/web.d.ts +18 -0
- package/templates/react-native-component/.vscode/extensions.json +5 -0
- package/templates/react-native-component/.vscode/launch.json +32 -0
- package/templates/react-native-component/CLAUDE.md +13 -0
- package/templates/react-native-component/README.md +40 -0
- package/templates/react-native-component/node_modules/.bin/react-native +43 -0
- package/templates/react-native-component/node_modules/.bin/spectra +43 -0
- package/templates/react-native-component/node_modules/.bin/tsc +43 -0
- package/templates/react-native-component/node_modules/.bin/tsserver +43 -0
- package/templates/react-native-component/package.json +25 -0
- package/templates/react-native-component/page-objects/BadgeComponent/mobile.ts +13 -0
- package/templates/react-native-component/page-objects/ButtonComponent/mobile.ts +13 -0
- package/templates/react-native-component/page-objects/InputComponent/mobile.ts +8 -0
- package/templates/react-native-component/specs/BadgeComponent/TC-0002-badge-render/mobile.test.tsx +9 -0
- package/templates/react-native-component/specs/BadgeComponent/TC-0002-badge-render/spec.md +10 -0
- package/templates/react-native-component/specs/ButtonComponent/TC-0001-button-press/mobile.test.tsx +21 -0
- package/templates/react-native-component/specs/ButtonComponent/TC-0001-button-press/spec.md +10 -0
- package/templates/react-native-component/specs/InputComponent/TC-0003-input-typing/mobile.test.tsx +19 -0
- package/templates/react-native-component/specs/InputComponent/TC-0003-input-typing/spec.md +10 -0
- package/templates/react-native-component/spectra.config.ts +10 -0
- package/templates/react-native-component/src/components/Badge/Badge.tsx +56 -0
- package/templates/react-native-component/src/components/Button/Button.tsx +63 -0
- package/templates/react-native-component/src/components/Input/Input.tsx +56 -0
- package/templates/react-native-component/tsconfig.json +8 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
3
|
+
basedir_win="$basedir"
|
|
4
|
+
exe=""
|
|
5
|
+
msys=""
|
|
6
|
+
|
|
7
|
+
case `uname -a` in
|
|
8
|
+
*CYGWIN*|*MINGW*|*MSYS*)
|
|
9
|
+
if command -v cygpath > /dev/null 2>&1; then
|
|
10
|
+
basedir_win=`cygpath -w "$basedir"`
|
|
11
|
+
fi
|
|
12
|
+
exe=".exe"
|
|
13
|
+
msys="true"
|
|
14
|
+
;;
|
|
15
|
+
*WSL2*)
|
|
16
|
+
if command -v wslpath > /dev/null 2>&1; then
|
|
17
|
+
basedir_win="$(wslpath -w "$basedir" 2> /dev/null)"
|
|
18
|
+
if [ $? -ne 0 ] || [ -z "$basedir_win" ]; then
|
|
19
|
+
basedir_win="$basedir"
|
|
20
|
+
else
|
|
21
|
+
exe=".exe"
|
|
22
|
+
fi
|
|
23
|
+
fi
|
|
24
|
+
;;
|
|
25
|
+
esac
|
|
26
|
+
|
|
27
|
+
if [ -z "$NODE_PATH" ]; then
|
|
28
|
+
export NODE_PATH="/Volumes/Home/Documents/TestSpectra/testspectra-source/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/node_modules:/Volumes/Home/Documents/TestSpectra/testspectra-source/node_modules/.pnpm/typescript@5.9.3/node_modules:/Volumes/Home/Documents/TestSpectra/testspectra-source/node_modules/.pnpm/node_modules"
|
|
29
|
+
else
|
|
30
|
+
export NODE_PATH="/Volumes/Home/Documents/TestSpectra/testspectra-source/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/node_modules:/Volumes/Home/Documents/TestSpectra/testspectra-source/node_modules/.pnpm/typescript@5.9.3/node_modules:/Volumes/Home/Documents/TestSpectra/testspectra-source/node_modules/.pnpm/node_modules:$NODE_PATH"
|
|
31
|
+
fi
|
|
32
|
+
if [ -n "$exe" ] && [ -x "$basedir/node.exe" ]; then
|
|
33
|
+
exec "$basedir/node.exe" "$basedir_win/../../../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/bin/tsc" "$@"
|
|
34
|
+
elif [ -x "$basedir/node" ]; then
|
|
35
|
+
exec "$basedir/node" "$basedir/../../../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/bin/tsc" "$@"
|
|
36
|
+
elif command -v node >/dev/null 2>&1; then
|
|
37
|
+
exec node "$basedir/../../../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/bin/tsc" "$@"
|
|
38
|
+
elif [ -n "$exe" ] && command -v node.exe >/dev/null 2>&1; then
|
|
39
|
+
exec node.exe "$basedir_win/../../../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/bin/tsc" "$@"
|
|
40
|
+
else
|
|
41
|
+
exec node "$basedir/../../../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/bin/tsc" "$@"
|
|
42
|
+
fi
|
|
43
|
+
# cmd-shim-target=/Volumes/Home/Documents/TestSpectra/testspectra-source/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/bin/tsc
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
3
|
+
basedir_win="$basedir"
|
|
4
|
+
exe=""
|
|
5
|
+
msys=""
|
|
6
|
+
|
|
7
|
+
case `uname -a` in
|
|
8
|
+
*CYGWIN*|*MINGW*|*MSYS*)
|
|
9
|
+
if command -v cygpath > /dev/null 2>&1; then
|
|
10
|
+
basedir_win=`cygpath -w "$basedir"`
|
|
11
|
+
fi
|
|
12
|
+
exe=".exe"
|
|
13
|
+
msys="true"
|
|
14
|
+
;;
|
|
15
|
+
*WSL2*)
|
|
16
|
+
if command -v wslpath > /dev/null 2>&1; then
|
|
17
|
+
basedir_win="$(wslpath -w "$basedir" 2> /dev/null)"
|
|
18
|
+
if [ $? -ne 0 ] || [ -z "$basedir_win" ]; then
|
|
19
|
+
basedir_win="$basedir"
|
|
20
|
+
else
|
|
21
|
+
exe=".exe"
|
|
22
|
+
fi
|
|
23
|
+
fi
|
|
24
|
+
;;
|
|
25
|
+
esac
|
|
26
|
+
|
|
27
|
+
if [ -z "$NODE_PATH" ]; then
|
|
28
|
+
export NODE_PATH="/Volumes/Home/Documents/TestSpectra/testspectra-source/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/node_modules:/Volumes/Home/Documents/TestSpectra/testspectra-source/node_modules/.pnpm/typescript@5.9.3/node_modules:/Volumes/Home/Documents/TestSpectra/testspectra-source/node_modules/.pnpm/node_modules"
|
|
29
|
+
else
|
|
30
|
+
export NODE_PATH="/Volumes/Home/Documents/TestSpectra/testspectra-source/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/node_modules:/Volumes/Home/Documents/TestSpectra/testspectra-source/node_modules/.pnpm/typescript@5.9.3/node_modules:/Volumes/Home/Documents/TestSpectra/testspectra-source/node_modules/.pnpm/node_modules:$NODE_PATH"
|
|
31
|
+
fi
|
|
32
|
+
if [ -n "$exe" ] && [ -x "$basedir/node.exe" ]; then
|
|
33
|
+
exec "$basedir/node.exe" "$basedir_win/../../../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/bin/tsserver" "$@"
|
|
34
|
+
elif [ -x "$basedir/node" ]; then
|
|
35
|
+
exec "$basedir/node" "$basedir/../../../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/bin/tsserver" "$@"
|
|
36
|
+
elif command -v node >/dev/null 2>&1; then
|
|
37
|
+
exec node "$basedir/../../../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/bin/tsserver" "$@"
|
|
38
|
+
elif [ -n "$exe" ] && command -v node.exe >/dev/null 2>&1; then
|
|
39
|
+
exec node.exe "$basedir_win/../../../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/bin/tsserver" "$@"
|
|
40
|
+
else
|
|
41
|
+
exec node "$basedir/../../../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/bin/tsserver" "$@"
|
|
42
|
+
fi
|
|
43
|
+
# cmd-shim-target=/Volumes/Home/Documents/TestSpectra/testspectra-source/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/bin/tsserver
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@testspectra/template-react-native-component",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "spectra test --platform android",
|
|
8
|
+
"spectra": "spectra",
|
|
9
|
+
"doctor": "spectra doctor",
|
|
10
|
+
"type-check": "tsc -b",
|
|
11
|
+
"sync-types": "spectra sync-types",
|
|
12
|
+
"postinstall": "spectra sync-types"
|
|
13
|
+
},
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"@testspectra/cli": "link:../..",
|
|
16
|
+
"@testspectra/matchers": "link:../../../tools/matchers",
|
|
17
|
+
"@testspectra/react-native": "link:../../../tools/react-native",
|
|
18
|
+
"@types/node": "^20.14.0",
|
|
19
|
+
"@types/react": "^18.3.12",
|
|
20
|
+
"@types/react-native": "^0.73.0",
|
|
21
|
+
"react": "^18.3.1",
|
|
22
|
+
"react-native": "^0.76.0",
|
|
23
|
+
"typescript": "^5.4.5"
|
|
24
|
+
}
|
|
25
|
+
}
|
package/templates/react-native-component/specs/BadgeComponent/TC-0002-badge-render/mobile.test.tsx
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Badge } from '../../../src/components/Badge/Badge.js';
|
|
3
|
+
|
|
4
|
+
it('Verify Badge renders severity and text', async () => {
|
|
5
|
+
await Spectra.mount(<Badge label="Active" severity="success" />);
|
|
6
|
+
|
|
7
|
+
await BadgeComponent.root.shouldBeVisible();
|
|
8
|
+
await BadgeComponent.label.shouldHaveText('Active');
|
|
9
|
+
});
|
package/templates/react-native-component/specs/ButtonComponent/TC-0001-button-press/mobile.test.tsx
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Button } from '../../../src/components/Button/Button.js';
|
|
3
|
+
|
|
4
|
+
it('Verify Button renders label and triggers onPress callback', async () => {
|
|
5
|
+
let isPressed = false;
|
|
6
|
+
|
|
7
|
+
await Spectra.mount(
|
|
8
|
+
<Button
|
|
9
|
+
label="Save Settings"
|
|
10
|
+
variant="primary"
|
|
11
|
+
onPress={() => {
|
|
12
|
+
isPressed = true;
|
|
13
|
+
}}
|
|
14
|
+
/>,
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
await ButtonComponent.root.shouldBeVisible();
|
|
18
|
+
await ButtonComponent.label.shouldHaveText('Save Settings');
|
|
19
|
+
await ButtonComponent.root.click();
|
|
20
|
+
Spectra.expect(isPressed).toBe(true);
|
|
21
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: TC-0001-button-press
|
|
3
|
+
title: Verify Button renders label and triggers onPress callback
|
|
4
|
+
platform: mobile
|
|
5
|
+
type: component
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Verify Button renders label and triggers onPress callback
|
|
9
|
+
|
|
10
|
+
Ensure that the React Native Button component renders correctly with the expected label and dispatches the onPress callback when clicked.
|
package/templates/react-native-component/specs/InputComponent/TC-0003-input-typing/mobile.test.tsx
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Input } from '../../../src/components/Input/Input.js';
|
|
3
|
+
|
|
4
|
+
it('Verify Input renders placeholder and accepts text', async () => {
|
|
5
|
+
let textValue = '';
|
|
6
|
+
|
|
7
|
+
await Spectra.mount(
|
|
8
|
+
<Input
|
|
9
|
+
placeholder="Type username..."
|
|
10
|
+
onChangeText={(val) => {
|
|
11
|
+
textValue = val;
|
|
12
|
+
}}
|
|
13
|
+
/>,
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
await InputComponent.root.shouldBeVisible();
|
|
17
|
+
await InputComponent.root.setValue('budi_santoso');
|
|
18
|
+
Spectra.expect(textValue).toBe('budi_santoso');
|
|
19
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: TC-0003-input-typing
|
|
3
|
+
title: Verify Input renders placeholder and accepts text
|
|
4
|
+
platform: mobile
|
|
5
|
+
type: component
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Verify Input renders placeholder and accepts text
|
|
9
|
+
|
|
10
|
+
Ensure that the React Native Input component displays the placeholder and handles text changes.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { StyleSheet, Text, View } from 'react-native';
|
|
3
|
+
|
|
4
|
+
export interface BadgeProps {
|
|
5
|
+
label: string;
|
|
6
|
+
severity?: 'info' | 'success' | 'warning' | 'error';
|
|
7
|
+
testID?: string;
|
|
8
|
+
accessibilityLabel?: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const Badge: React.FC<BadgeProps> = ({
|
|
12
|
+
label,
|
|
13
|
+
severity = 'info',
|
|
14
|
+
testID = 'badge',
|
|
15
|
+
accessibilityLabel,
|
|
16
|
+
}) => {
|
|
17
|
+
const getBackgroundColor = () => {
|
|
18
|
+
switch (severity) {
|
|
19
|
+
case 'success':
|
|
20
|
+
return '#10b981';
|
|
21
|
+
case 'warning':
|
|
22
|
+
return '#f59e0b';
|
|
23
|
+
case 'error':
|
|
24
|
+
return '#ef4444';
|
|
25
|
+
case 'info':
|
|
26
|
+
default:
|
|
27
|
+
return '#3b82f6';
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<View
|
|
33
|
+
testID={testID}
|
|
34
|
+
accessibilityLabel={accessibilityLabel || testID}
|
|
35
|
+
style={[styles.badge, { backgroundColor: getBackgroundColor() }]}
|
|
36
|
+
>
|
|
37
|
+
<Text style={styles.text} testID={`${testID}-label`}>
|
|
38
|
+
{label}
|
|
39
|
+
</Text>
|
|
40
|
+
</View>
|
|
41
|
+
);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const styles = StyleSheet.create({
|
|
45
|
+
badge: {
|
|
46
|
+
paddingHorizontal: 10,
|
|
47
|
+
paddingVertical: 4,
|
|
48
|
+
borderRadius: 9999,
|
|
49
|
+
alignSelf: 'flex-start',
|
|
50
|
+
},
|
|
51
|
+
text: {
|
|
52
|
+
color: '#ffffff',
|
|
53
|
+
fontSize: 12,
|
|
54
|
+
fontWeight: '700',
|
|
55
|
+
},
|
|
56
|
+
});
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { StyleSheet, Text, TouchableOpacity } from 'react-native';
|
|
3
|
+
|
|
4
|
+
export interface ButtonProps {
|
|
5
|
+
label: string;
|
|
6
|
+
variant?: 'primary' | 'secondary' | 'danger';
|
|
7
|
+
disabled?: boolean;
|
|
8
|
+
onPress?: () => void;
|
|
9
|
+
accessibilityLabel?: string;
|
|
10
|
+
testID?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const Button: React.FC<ButtonProps> = ({
|
|
14
|
+
label,
|
|
15
|
+
variant = 'primary',
|
|
16
|
+
disabled = false,
|
|
17
|
+
onPress,
|
|
18
|
+
accessibilityLabel,
|
|
19
|
+
testID = 'button',
|
|
20
|
+
}) => {
|
|
21
|
+
const getBackgroundColor = () => {
|
|
22
|
+
if (disabled) return '#9ca3af';
|
|
23
|
+
switch (variant) {
|
|
24
|
+
case 'secondary':
|
|
25
|
+
return '#4b5563';
|
|
26
|
+
case 'danger':
|
|
27
|
+
return '#ef4444';
|
|
28
|
+
case 'primary':
|
|
29
|
+
default:
|
|
30
|
+
return '#3b82f6';
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<TouchableOpacity
|
|
36
|
+
accessibilityLabel={accessibilityLabel || 'button'}
|
|
37
|
+
testID={testID}
|
|
38
|
+
disabled={disabled}
|
|
39
|
+
onPress={onPress}
|
|
40
|
+
activeOpacity={0.7}
|
|
41
|
+
style={[styles.btn, { backgroundColor: getBackgroundColor() }]}
|
|
42
|
+
>
|
|
43
|
+
<Text style={styles.text} testID={`${testID}-label`}>
|
|
44
|
+
{label}
|
|
45
|
+
</Text>
|
|
46
|
+
</TouchableOpacity>
|
|
47
|
+
);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const styles = StyleSheet.create({
|
|
51
|
+
btn: {
|
|
52
|
+
paddingHorizontal: 16,
|
|
53
|
+
paddingVertical: 10,
|
|
54
|
+
borderRadius: 8,
|
|
55
|
+
alignItems: 'center',
|
|
56
|
+
justifyContent: 'center',
|
|
57
|
+
},
|
|
58
|
+
text: {
|
|
59
|
+
color: '#ffffff',
|
|
60
|
+
fontSize: 14,
|
|
61
|
+
fontWeight: '600',
|
|
62
|
+
},
|
|
63
|
+
});
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { StyleSheet, TextInput, View } from 'react-native';
|
|
3
|
+
|
|
4
|
+
export interface InputProps {
|
|
5
|
+
value?: string;
|
|
6
|
+
placeholder?: string;
|
|
7
|
+
onChangeText?: (text: string) => void;
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
testID?: string;
|
|
10
|
+
accessibilityLabel?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const Input: React.FC<InputProps> = ({
|
|
14
|
+
value,
|
|
15
|
+
placeholder = 'Enter text...',
|
|
16
|
+
onChangeText,
|
|
17
|
+
disabled = false,
|
|
18
|
+
testID = 'input',
|
|
19
|
+
accessibilityLabel,
|
|
20
|
+
}) => {
|
|
21
|
+
return (
|
|
22
|
+
<View style={styles.container}>
|
|
23
|
+
<TextInput
|
|
24
|
+
testID={testID}
|
|
25
|
+
accessibilityLabel={accessibilityLabel || testID}
|
|
26
|
+
value={value}
|
|
27
|
+
placeholder={placeholder}
|
|
28
|
+
placeholderTextColor="#94a3b8"
|
|
29
|
+
onChangeText={onChangeText}
|
|
30
|
+
editable={!disabled}
|
|
31
|
+
style={[styles.input, disabled && styles.disabled]}
|
|
32
|
+
/>
|
|
33
|
+
</View>
|
|
34
|
+
);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const styles = StyleSheet.create({
|
|
38
|
+
container: {
|
|
39
|
+
width: '100%',
|
|
40
|
+
marginVertical: 4,
|
|
41
|
+
},
|
|
42
|
+
input: {
|
|
43
|
+
borderWidth: 1,
|
|
44
|
+
borderColor: '#cbd5e1',
|
|
45
|
+
borderRadius: 8,
|
|
46
|
+
paddingHorizontal: 12,
|
|
47
|
+
paddingVertical: 10,
|
|
48
|
+
fontSize: 14,
|
|
49
|
+
color: '#0f172a',
|
|
50
|
+
backgroundColor: '#ffffff',
|
|
51
|
+
},
|
|
52
|
+
disabled: {
|
|
53
|
+
backgroundColor: '#f1f5f9',
|
|
54
|
+
color: '#94a3b8',
|
|
55
|
+
},
|
|
56
|
+
});
|