Skip to content

Commit

Permalink
Merge pull request #15 from janis-commerce/JUIP-110-radio-button
Browse files Browse the repository at this point in the history
Juip-110-radio-button
  • Loading branch information
christian97dd authored Sep 7, 2023
2 parents 99de5f7 + 760fba3 commit b3e0d1b
Show file tree
Hide file tree
Showing 7 changed files with 245 additions and 41 deletions.
81 changes: 41 additions & 40 deletions .ondevice/storybook.requires.js
Original file line number Diff line number Diff line change
@@ -1,63 +1,64 @@
/* do not change this file, it is auto generated by storybook. */

import {
configure,
addDecorator,
addParameters,
addArgsEnhancer,
clearDecorators,
} from '@storybook/react-native';
configure,
addDecorator,
addParameters,
addArgsEnhancer,
clearDecorators,
} from "@storybook/react-native";

global.STORIES = [
{
titlePrefix: '',
directory: './storybook/stories',
files: '**/*.stories.?(ts|tsx|js|jsx)',
importPathMatcher:
'^\\.[\\\\/](?:storybook\\/stories(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.(?:ts|tsx|js|jsx)?)$',
},
{
titlePrefix: "",
directory: "./storybook/stories",
files: "**/*.stories.?(ts|tsx|js|jsx)",
importPathMatcher:
"^\\.[\\\\/](?:storybook\\/stories(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.(?:ts|tsx|js|jsx)?)$",
},
];

import '@storybook/addon-ondevice-actions/register';
import '@storybook/addon-ondevice-controls/register';
import "@storybook/addon-ondevice-actions/register";
import "@storybook/addon-ondevice-controls/register";

import {argsEnhancers} from '@storybook/addon-actions/dist/modern/preset/addArgs';
import { argsEnhancers } from "@storybook/addon-actions/dist/modern/preset/addArgs";

import {decorators, parameters} from './preview';
import { decorators, parameters } from "./preview";

if (decorators) {
if (__DEV__) {
// stops the warning from showing on every HMR
require('react-native').LogBox.ignoreLogs([
'`clearDecorators` is deprecated and will be removed in Storybook 7.0',
]);
}
// workaround for global decorators getting infinitely applied on HMR, see https://github.com/storybookjs/react-native/issues/185
clearDecorators();
decorators.forEach((decorator) => addDecorator(decorator));
if (__DEV__) {
// stops the warning from showing on every HMR
require("react-native").LogBox.ignoreLogs([
"`clearDecorators` is deprecated and will be removed in Storybook 7.0",
]);
}
// workaround for global decorators getting infinitely applied on HMR, see https://github.com/storybookjs/react-native/issues/185
clearDecorators();
decorators.forEach((decorator) => addDecorator(decorator));
}

if (parameters) {
addParameters(parameters);
addParameters(parameters);
}

try {
argsEnhancers.forEach((enhancer) => addArgsEnhancer(enhancer));
argsEnhancers.forEach((enhancer) => addArgsEnhancer(enhancer));
} catch {}

const getStories = () => {
return {
'./storybook/stories/Avatar/Avatar.stories.js': require('../storybook/stories/Avatar/Avatar.stories.js'),
'./storybook/stories/CheckBox/CheckBox.stories.js': require('../storybook/stories/CheckBox/CheckBox.stories.js'),
'./storybook/stories/DesignStystem/Colors.stories.js': require('../storybook/stories/DesignStystem/Colors.stories.js'),
'./storybook/stories/Image/Image.stories.js': require('../storybook/stories/Image/Image.stories.js'),
'./storybook/stories/Input/Input.stories.js': require('../storybook/stories/Input/Input.stories.js'),
'./storybook/stories/Loading/Loading.stories.js': require('../storybook/stories/Loading/Loading.stories.js'),
'./storybook/stories/LoadingFullScreen/LoadingFullScreen.stories.js': require('../storybook/stories/LoadingFullScreen/LoadingFullScreen.stories.js'),
'./storybook/stories/StatusChip/StatusChip.stories.js': require('../storybook/stories/StatusChip/StatusChip.stories.js'),
'./storybook/stories/Svg/Svg.stories.js': require('../storybook/stories/Svg/Svg.stories.js'),
'./storybook/stories/Text/Text.stories.js': require('../storybook/stories/Text/Text.stories.js'),
};
return {
"./storybook/stories/Avatar/Avatar.stories.js": require("../storybook/stories/Avatar/Avatar.stories.js"),
"./storybook/stories/CheckBox/CheckBox.stories.js": require("../storybook/stories/CheckBox/CheckBox.stories.js"),
"./storybook/stories/DesignStystem/Colors.stories.js": require("../storybook/stories/DesignStystem/Colors.stories.js"),
"./storybook/stories/Image/Image.stories.js": require("../storybook/stories/Image/Image.stories.js"),
"./storybook/stories/Input/Input.stories.js": require("../storybook/stories/Input/Input.stories.js"),
"./storybook/stories/Loading/Loading.stories.js": require("../storybook/stories/Loading/Loading.stories.js"),
"./storybook/stories/LoadingFullScreen/LoadingFullScreen.stories.js": require("../storybook/stories/LoadingFullScreen/LoadingFullScreen.stories.js"),
"./storybook/stories/RadioButton/RadioButton.stories.js": require("../storybook/stories/RadioButton/RadioButton.stories.js"),
"./storybook/stories/StatusChip/StatusChip.stories.js": require("../storybook/stories/StatusChip/StatusChip.stories.js"),
"./storybook/stories/Svg/Svg.stories.js": require("../storybook/stories/Svg/Svg.stories.js"),
"./storybook/stories/Text/Text.stories.js": require("../storybook/stories/Text/Text.stories.js"),
};
};

configure(getStories, module, false);
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Added radio button component

### Fixed

- Fixed lint staged command in order to check typescript errors on commits
Expand Down
1 change: 1 addition & 0 deletions src/components/CheckBox/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ interface CheckBoxProps {
borderRadius?: number;
disabled?: boolean;
style?: ViewStyle;
onPress?: () => {};
}

const getCheckBoxScale = (size: number, divisor: number): number => size / divisor;
Expand Down
37 changes: 37 additions & 0 deletions src/components/RadioButton/index.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from 'react';
import {create} from 'react-test-renderer';
import RadioButton from './index';
import Text from '../Text';
import {TouchableOpacity} from 'react-native';

describe('radioButton component', () => {
it('not rendered when not receive a valid text', () => {
const {toJSON} = create(<RadioButton children="" />);

expect(toJSON()).toStrictEqual(null);
});

it('should render correctly when receives a valid text as child', () => {
const {toJSON} = create(<RadioButton checkPosition="right">Example text</RadioButton>);
expect(toJSON()).toBeTruthy();
});

it('should render correctly when receives a valid child', () => {
const child = <Text>valid child</Text>;

const {toJSON} = create(<RadioButton>{child}</RadioButton>);
expect(toJSON()).toBeTruthy();
});

it('should execute the onPress function when it is received', () => {
const onPressFunc = jest.fn();

const {root} = create(<RadioButton onPress={onPressFunc}>Example text</RadioButton>);

const [pressableText] = root.findAllByType(TouchableOpacity);

pressableText.props.onPress();

expect(onPressFunc).toBeCalled();
});
});
91 changes: 91 additions & 0 deletions src/components/RadioButton/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import React from 'react';
import {View, TouchableOpacity, StyleSheet, ViewStyle} from 'react-native';
import Text from '../Text';
import CheckBox from '../CheckBox';

const checkLocation = ['left', 'right'] as const;

type positions = (typeof checkLocation)[number];

const CheckSizeValues = {
sm: 16,
md: 24,
lg: 32,
};

type sizeType = typeof CheckSizeValues;
type sizeKeys = keyof sizeType;

interface RadioButtonProps {
children: React.ReactNode | string;
selected?: boolean;
onPress?: () => {};
checkPosition?: positions;
disabled?: boolean;
checkSize?: sizeKeys;
style?: ViewStyle;
}

const styles = StyleSheet.create({
container: {
alignItems: 'center',
paddingHorizontal: 16,
marginVertical: 10,
height: 'auto',
},

row: {
flexDirection: 'row',
justifyContent: 'flex-start',
},
reverseRow: {
flexDirection: 'row-reverse',
justifyContent: 'space-between',
},
checkToLeft: {
marginLeft: 15,
},
checkToRight: {
marginRight: 15,
},
});

const RadioButton = ({
children,
onPress,
selected = false,
checkPosition = 'left',
checkSize = 'sm',
disabled = false,
style,
...props
}: RadioButtonProps) => {
if (!children) {
return null;
}

const {container, row, reverseRow, checkToLeft, checkToRight} = styles;
const isStringChild = typeof children === 'string';
const checkLeft = checkPosition === 'left';
const customSize = CheckSizeValues[checkSize];

return (
<TouchableOpacity
style={[container, checkLeft ? row : reverseRow, style]}
disabled={disabled}
onPress={onPress}
{...props}>
<CheckBox
checked={selected}
disabled={disabled}
customSize={customSize}
borderRadius={customSize / 2}
/>
<View style={checkLeft ? checkToLeft : checkToRight}>
{isStringChild ? <Text>{children}</Text> : children}
</View>
</TouchableOpacity>
);
};

export default RadioButton;
15 changes: 14 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,18 @@ import StatusChip from './components/StatusChip';
import Input from './components/Input';
import LoadingFullScreen from './components/LoadingFullScreen';
import {palette} from './theme/palette';
import RadioButton from './components/RadioButton';

export {Text, Avatar, CheckBox, Image, Loading, Svg, StatusChip, Input, palette, LoadingFullScreen};
export {
Text,
Avatar,
CheckBox,
Image,
Loading,
Svg,
StatusChip,
Input,
palette,
LoadingFullScreen,
RadioButton,
};
57 changes: 57 additions & 0 deletions storybook/stories/RadioButton/RadioButton.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import React from 'react';
import RadioButton from '../../../src/components/RadioButton';
import Image from '../../../src/components/Image';

export default {
title: 'Components/RadioButton',
argTypes: {
checkSize: {
options: ['sm', 'md', 'lg'],
control: {type: 'select'},
},
checkPosition: {
options: ['left', 'right'],
control: {type: 'select'},
},
selected: {
options: [true, false],
control: {type: 'radio'},
},
disabled: {
options: [true, false],
control: {type: 'radio'},
},
},
};

export const WithTextChild = (props) => <RadioButton {...props}>option 1</RadioButton>;

WithTextChild.storyName = 'with text child';

WithTextChild.args = {
checkSize: 'sm',
checkPosition: 'left',
selected: true,
disabled: false,
};

export const WithChildComponent = (props) => (
<RadioButton {...props}>
<Image
source={{
uri: 'https://avatars.githubusercontent.com/u/49998302?s=200&v=4',
width: 80,
height: 80,
}}
/>
</RadioButton>
);

WithChildComponent.storyName = 'with child component';

WithChildComponent.args = {
checkSize: 'lg',
checkPosition: 'right',
selected: false,
disabled: false,
};

0 comments on commit b3e0d1b

Please sign in to comment.