Skip to content

Commit

Permalink
adjusted base input and added input component
Browse files Browse the repository at this point in the history
  • Loading branch information
christian97dd committed Dec 5, 2024
1 parent 8d712c1 commit f0c1252
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 110 deletions.
20 changes: 3 additions & 17 deletions src/components/atoms/BaseInput/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import React, {forwardRef} from 'react';
import {StyleSheet, TextInput, TextInputProps} from 'react-native';
import {TextInput, TextInputProps} from 'react-native';
import {palette} from 'theme/palette';
import {moderateScale, scaledForDevice} from 'scale';

interface BaseInputProps extends TextInputProps {
export interface BaseInputProps extends TextInputProps {
placeholder?: string;
onChangeText?: (text: string) => void;
style?: any;
Expand All @@ -12,22 +11,9 @@ interface BaseInputProps extends TextInputProps {

const BaseInput = forwardRef<TextInput, BaseInputProps>(
({value, placeholder, onChangeText, style, textAlign, ...props}, ref) => {
const styles = StyleSheet.create({
input: {
padding: 0,
height: scaledForDevice(70, moderateScale),
borderColor: palette.primary.main,
borderWidth: 2,
borderRadius: 8,
fontSize: scaledForDevice(42, moderateScale),
backgroundColor: palette.white.light,
color: palette.black.main,
},
});

return (
<TextInput
style={[styles.input, style]}
style={[style]}
ref={ref}
value={value}
placeholder={placeholder}
Expand Down
51 changes: 51 additions & 0 deletions src/components/molecules/Input/index.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import React from 'react';
import {render, fireEvent} from '@testing-library/react-native';
import Input from './index';

describe('Input Component', () => {
it('should render correctly with default props', () => {
const {getByPlaceholderText} = render(<Input placeholder="Enter text" type="text" />);
const input = getByPlaceholderText('Enter text');
expect(input).toBeTruthy();
});

it('should apply the correct keyboardType for currency', () => {
const {getByPlaceholderText} = render(<Input placeholder="Enter amount" type="currency" />);
const input = getByPlaceholderText('Enter amount');
expect(input.props.keyboardType).toBe('numeric');
});

it('should apply the correct keyboardType for number', () => {
const {getByPlaceholderText} = render(<Input placeholder="Enter number" type="number" />);
const input = getByPlaceholderText('Enter number');
expect(input.props.keyboardType).toBe('numeric');
});

it('should apply the correct keyboardType for text', () => {
const {getByPlaceholderText} = render(<Input placeholder="Enter text" type="text" />);
const input = getByPlaceholderText('Enter text');
expect(input.props.keyboardType).toBe('default');
});

it('should apply the correct keyboardType for email', () => {
const {getByPlaceholderText} = render(<Input placeholder="Enter email" type="email" />);
const input = getByPlaceholderText('Enter email');
expect(input.props.keyboardType).toBe('email-address');
});

it('should apply the correct keyboardType for phone', () => {
const {getByPlaceholderText} = render(<Input placeholder="Enter phone" type="phone" />);
const input = getByPlaceholderText('Enter phone');
expect(input.props.keyboardType).toBe('phone-pad');
});

it('should call onChangeText when text is changed', () => {
const onChangeTextMock = jest.fn();
const {getByPlaceholderText} = render(
<Input placeholder="Enter text" type="text" onChangeText={onChangeTextMock} />
);
const input = getByPlaceholderText('Enter text');
fireEvent.changeText(input, 'new text');
expect(onChangeTextMock).toHaveBeenCalledWith('new text');
});
});
43 changes: 43 additions & 0 deletions src/components/molecules/Input/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React, {forwardRef} from 'react';
import {StyleSheet, TextInput} from 'react-native';
import BaseInput, {BaseInputProps} from 'atoms/BaseInput';
import {palette} from 'theme/palette';
import {moderateScale, scaledForDevice} from 'scale';

enum InputType {
currency = 'numeric',
number = 'numeric',
text = 'default',
email = 'email-address',
phone = 'phone-pad',
}

interface InputProps extends BaseInputProps {
type: 'currency' | 'number' | 'text' | 'email' | 'phone';
}

const Input = forwardRef<TextInput, InputProps>(({style, type, ...props}, ref) => {
const styles = StyleSheet.create({
input: {
padding: 0,
height: scaledForDevice(70, moderateScale),
borderColor: palette.primary.main,
borderWidth: 2,
borderRadius: 8,
fontSize: scaledForDevice(42, moderateScale),
backgroundColor: palette.white.light,
color: palette.black.main,
},
});

return (
<BaseInput
style={[styles.input, style]}
ref={ref}
keyboardType={InputType[type] || InputType.text}
{...props}
/>
);
});

export default Input;
4 changes: 2 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import BaseButton from 'atoms/BaseButton';
import CheckBox from 'atoms/CheckBox';
import Icon from 'atoms/Icon';
import Image from 'atoms/Image';
import Input from 'atoms/Input';
import List from 'atoms/List';
import Loading from 'atoms/Loading';
import RadioButton from 'atoms/RadioButton';
Expand All @@ -26,6 +25,7 @@ import {configToast} from 'molecules/Toast/utils';
import SwipeList from 'molecules/SwipeList';
import ItemSelectionButton from 'molecules/ItemSelectionButton';
import MainCardList from 'molecules/MainCardList';
import Input from 'molecules/Input';

// Organisms
import LoadingFullScreen from 'organisms/LoadingFullScreen';
Expand All @@ -42,10 +42,10 @@ export {
CheckBox,
Icon,
Image,
Input,
Loading,
Svg,
StatusChip,
Input,
palette,
LoadingFullScreen,
RadioButton,
Expand Down
27 changes: 16 additions & 11 deletions storybook/stories/BaseInput/BaseInput.stories.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,30 @@
import React, {useState} from 'react';
import React from 'react';
import BaseInput from 'atoms/BaseInput';

export default {
title: 'Components/BaseInput',
component: BaseInput,
argTypes: {
textAlign: {
options: ['center', 'left', 'right', null],
defaultValue: 'center',
control: {type: 'select'},
control: {
type: 'select',
options: ['center', 'left', 'right'],
},
},
},
};

export const DefaultProps = (props) => {
const [value, setValue] = useState('');
const Template = (args) => <BaseInput {...args} />;

return <BaseInput value={value} onChangeText={setValue} {...props} />;
export const Default = Template.bind({});
Default.args = {
placeholder: 'Enter text',
textAlign: 'center',
};

DefaultProps.storyName = 'Base input with default props';

DefaultProps.args = {
placeholder: 'Janis Commerce',
export const WithCustomStyle = Template.bind({});
WithCustomStyle.args = {
placeholder: 'Enter text',
textAlign: 'left',
style: {borderColor: 'red', borderWidth: 1},
};
109 changes: 29 additions & 80 deletions storybook/stories/Input/Input.stories.js
Original file line number Diff line number Diff line change
@@ -1,98 +1,47 @@
import React, {useState} from 'react';
import Input from 'atoms/Input';
import React from 'react';
import Input from 'molecules/Input';

export default {
title: 'Components/Input',
component: Input,
argTypes: {
keyboardType: {
options: [
'default',
'number-pad',
'decimal-pad',
'numeric',
'email-address',
'phone-pad',
'url',
],
control: {type: 'select'},
type: {
control: {
type: 'select',
options: ['currency', 'number', 'text', 'email', 'phone'],
},
},
},
};

export const ReadOnly = ({placeholder, label}) => (
<Input readOnly placeholder={placeholder} label={label} />
);
const Template = (args) => <Input {...args} />;

ReadOnly.storyName = 'read only';

ReadOnly.args = {
placeholder: 'Document',
label: 'Document',
export const Currency = Template.bind({});
Currency.args = {
placeholder: 'Enter amount',
type: 'currency',
};

export const Editable = ({label, placeholder, keyboardType}) => {
const [value, setValue] = useState('');

return (
<Input
label={label}
placeholder={placeholder}
keyboardType={keyboardType}
value={value}
onChangeText={(userInput) => setValue(userInput)}
/>
);
export const Number = Template.bind({});
Number.args = {
placeholder: 'Enter number',
type: 'number',
};

Editable.storyName = 'editable';

Editable.args = {
label: 'First name',
placeholder: 'First name',
keyboardType: 'default',
export const Text = Template.bind({});
Text.args = {
placeholder: 'Enter text',
type: 'text',
};

export const Disabled = ({placeholder, label}) => (
<Input disabled placeholder={placeholder} label={label} />
);

Disabled.storyName = 'disabled';

Disabled.args = {
placeholder: 'First name',
label: 'First name',
export const Email = Template.bind({});
Email.args = {
placeholder: 'Enter email',
type: 'email',
};

export const DisabledWithValue = ({placeholder, label, value}) => (
<Input disabled placeholder={placeholder} label={label} value={value} />
);

DisabledWithValue.storyName = 'disabled with value';

DisabledWithValue.args = {
placeholder: 'First name',
label: 'First name',
value: 'Joe',
};

export const WithError = ({placeholder, label, statusMessage}) => {
const [value, setValue] = useState('');

return (
<Input
placeholder={placeholder}
label={label}
statusMessage={statusMessage}
value={value}
onChangeText={(userInput) => setValue(userInput)}
/>
);
};

WithError.storyName = 'with an error';

WithError.args = {
placeholder: 'First name',
label: 'First name',
statusMessage: 'Invalid name',
export const Phone = Template.bind({});
Phone.args = {
placeholder: 'Enter phone',
type: 'phone',
};

0 comments on commit f0c1252

Please sign in to comment.