Skip to content

Commit

Permalink
crear componente select
Browse files Browse the repository at this point in the history
  • Loading branch information
damian committed Aug 14, 2023
1 parent 34dd85c commit d8a6a67
Show file tree
Hide file tree
Showing 11 changed files with 476 additions and 80 deletions.
77 changes: 39 additions & 38 deletions .ondevice/storybook.requires.js
Original file line number Diff line number Diff line change
@@ -1,61 +1,62 @@
/* 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/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/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/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/Select/Select.stories.js": require("../storybook/stories/Select/Select.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);
116 changes: 116 additions & 0 deletions src/components/Select/Components/Dropdown/index.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import React from 'react';
import {create} from 'react-test-renderer';
import Dropdown from './';
import {Text, TouchableOpacity, View} from 'react-native';
import {primary, white} from '../../../../theme/palette';

const validOptions = [
{label: '1', value: '1'},
{label: '2', value: '2'},
];

const selectValidOptions = [{label: '2', value: '2'}];

const validStyles = {
backgroundColor: '#02BFFB',
};

const validProp = {
isShowedDropdown: true,
filteredOptions: validOptions,
selectedOptions: selectValidOptions,
noOptionsMessage: 'no options test',
optionStyles: validStyles,
callbackOption: jest.fn(),
};

describe('Dropdown component', () => {
describe('render correctly', () => {
it('when props are valid', () => {
const {toJSON} = create(
<Dropdown
isShowedDropdown={validProp.isShowedDropdown}
filteredOptions={validProp.filteredOptions}
selectedOptions={validProp.selectedOptions}
noOptionsMessage={validProp.noOptionsMessage}
optionStyles={validProp.optionStyles}
callbackOption={validProp.callbackOption}
/>
);
expect(toJSON()).toBeTruthy();
});

it('when selectedOption is included in filteredOptions', () => {
const {root} = create(
<Dropdown
isShowedDropdown={validProp.isShowedDropdown}
filteredOptions={validProp.filteredOptions}
selectedOptions={validProp.selectedOptions}
noOptionsMessage={validProp.noOptionsMessage}
callbackOption={validProp.callbackOption}
/>
);
const OptionsComp = root.findAllByType(TouchableOpacity);
const OptionTextComp = root.findAllByType(Text);
const {backgroundColor} = OptionsComp[1].props.style;
const {color} = OptionTextComp[1].props.style;

expect(backgroundColor).toBe(white.light);
expect(color).toBe(primary.main);
});
});

describe('render null', () => {
it('when isShowedDropdown is invalid', () => {
const {toJSON} = create(
<Dropdown
isShowedDropdown={false}
filteredOptions={validProp.filteredOptions}
selectedOptions={validProp.selectedOptions}
noOptionsMessage={validProp.noOptionsMessage}
optionStyles={validProp.optionStyles}
callbackOption={validProp.callbackOption}
/>
);
expect(toJSON()).toBeNull();
});
});

describe('render noOptions', () => {
it('when isShowedDropdown is invalid', () => {
const {root} = create(
<Dropdown
isShowedDropdown={validProp.isShowedDropdown}
filteredOptions={[]}
selectedOptions={validProp.selectedOptions}
noOptionsMessage={validProp.noOptionsMessage}
optionStyles={validProp.optionStyles}
callbackOption={validProp.callbackOption}
/>
);
const [, noOptionsComp] = root.findAllByType(View);
const opTionText = noOptionsComp.props.children.props.children[1];

expect(opTionText).toBe(validProp.noOptionsMessage);
});
});

describe('when handleSelectedOption is pressed', () => {
it("should call callback with selected option's value", () => {
const {root} = create(
<Dropdown
isShowedDropdown={validProp.isShowedDropdown}
filteredOptions={validProp.filteredOptions}
selectedOptions={validProp.selectedOptions}
noOptionsMessage={validProp.noOptionsMessage}
callbackOption={validProp.callbackOption}
/>
);
const [, OptionsComp] = root.findAllByType(TouchableOpacity);
const {onPress} = OptionsComp.props;
onPress();

expect(validProp.callbackOption).toBeCalledWith(selectValidOptions[0]);
});
});
});
15 changes: 5 additions & 10 deletions src/components/Select/Components/Dropdown/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ interface DropdownProps {
isShowedDropdown: boolean;
filteredOptions: Option[];
selectedOptions: Option[];
callbackOption: (option: Option) => void;
noOptionsMessage: string;
optionStyles: {};
optionStyles?: {};
callbackOption: (option: Option) => void;
}

const Dropdown: FC<DropdownProps> = ({
Expand All @@ -24,12 +24,7 @@ const Dropdown: FC<DropdownProps> = ({
return null;
}

const handleSelectedOption = (option: Option) => {
if (!filteredOptions.length) {
return null;
}
return callbackOption(option);
};
const handleSelectedOption = (option: Option) => callbackOption(option);

const styles = StyleSheet.create({
container: {
Expand Down Expand Up @@ -70,7 +65,7 @@ const Dropdown: FC<DropdownProps> = ({
const renderOptions =
filteredOptions?.length &&
filteredOptions.map((option) => {
const isSelectedOption = selectedOptions.includes(option);
const isSelectedOption = selectedOptions.some((selected) => selected.label === option.label);
const styleText = {...styles.optionText, ...(isSelectedOption && {color: primary.main})};
const styleOption = {
...styles.option,
Expand All @@ -95,7 +90,7 @@ const Dropdown: FC<DropdownProps> = ({

return (
<ScrollView style={styles.optionWrapper} contentContainerStyle={styles.container}>
{filteredOptions.length ? renderOptions : noRenderOptions}
{filteredOptions?.length ? renderOptions : noRenderOptions}
</ScrollView>
);
};
Expand Down
24 changes: 24 additions & 0 deletions src/components/Select/Components/Icons/Chevron/index.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React from 'react';
import {create} from 'react-test-renderer';
import Chevron from './';
import {Pressable} from 'react-native';

const validProps = {
style: {backgroundColor: 'red'},
color: '#f2f2f2',
size: 25,
onPress: jest.fn(),
};

describe('Chevron component', () => {
it('render correctly', () => {
const {root} = create(
<Chevron style={validProps.style} color={validProps.color} size={validProps.size} />
);
const PressableComponent = root.findByType(Pressable);
const {onPress} = PressableComponent.props;
onPress();

expect(root).toBeTruthy();
});
});
24 changes: 24 additions & 0 deletions src/components/Select/Components/Icons/Delete/index.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React from 'react';
import {create} from 'react-test-renderer';
import Delete from './';
import {Pressable} from 'react-native';

const validProps = {
style: {backgroundColor: 'red'},
color: '#f2f2f2',
size: 25,
onPress: jest.fn(),
};

describe('Delete component', () => {
it('render correctly', () => {
const {root} = create(
<Delete style={validProps.style} color={validProps.color} size={validProps.size} />
);
const PressableComponent = root.findByType(Pressable);
const {onPress} = PressableComponent.props;
onPress();

expect(root).toBeTruthy();
});
});
1 change: 1 addition & 0 deletions src/components/Select/Components/Icons/Delete/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const Delete = ({style, color, size, onPress, ...props}: IconProps) => {
Delete.defaultProps = {
color: black.main,
size: 21,
onPress: () => {},
};

export default Delete;

0 comments on commit d8a6a67

Please sign in to comment.