Skip to content

Commit

Permalink
Create Checkbox (#4599)
Browse files Browse the repository at this point in the history
* Create Checkbox

* Remove touchable
  • Loading branch information
Cal-L authored Jun 29, 2022
1 parent 20035d1 commit 27950e7
Show file tree
Hide file tree
Showing 16 changed files with 189 additions and 2 deletions.
14 changes: 14 additions & 0 deletions app/component-library/components/Checkbox/Checkbox.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* eslint-disable no-console */
import React from 'react';
import { storiesOf } from '@storybook/react-native';
import Checkbox from './Checkbox';
import { boolean } from '@storybook/addon-knobs';

storiesOf('Component Library / Checkbox', module)
.addDecorator((getStory) => getStory())
.add('Default', () => {
const groupId = 'Props';
const selectedSelector = boolean('isSelected', false, groupId);

return <Checkbox isSelected={selectedSelector} />;
});
22 changes: 22 additions & 0 deletions app/component-library/components/Checkbox/Checkbox.styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { StyleSheet, ViewStyle } from 'react-native';
import { CheckboxStyleSheet, CheckboxStyleSheetVars } from './Checkbox.types';

/**
* Style sheet function for Checkbox component.
*
* @param params Style sheet params.
* @param params.theme App theme from ThemeContext.
* @param params.vars Inputs that the style sheet depends on.
* @returns StyleSheet object.
*/
const styleSheet = (params: {
vars: CheckboxStyleSheetVars;
}): CheckboxStyleSheet => {
const { vars } = params;
const { style } = vars;
return StyleSheet.create({
base: Object.assign({} as ViewStyle, style) as ViewStyle,
});
};

export default styleSheet;
30 changes: 30 additions & 0 deletions app/component-library/components/Checkbox/Checkbox.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from 'react';
import { shallow } from 'enzyme';
import Checkbox from './Checkbox';
import { CHECKBOX_ICON_ID } from '../../../constants/test-ids';
import { IconName } from '../Icon';

describe('Checkbox', () => {
it('should render correctly', () => {
const wrapper = shallow(<Checkbox isSelected />);
expect(wrapper).toMatchSnapshot();
});

it('should render correct icon when selected', () => {
const wrapper = shallow(<Checkbox isSelected />);
const iconComponent = wrapper.findWhere(
(node) => node.prop('testID') === CHECKBOX_ICON_ID,
);
const iconName = iconComponent.props().name;
expect(iconName).toBe(IconName.CheckBoxOnFilled);
});

it('should render correct icon when not selected', () => {
const wrapper = shallow(<Checkbox isSelected={false} />);
const iconComponent = wrapper.findWhere(
(node) => node.prop('testID') === CHECKBOX_ICON_ID,
);
const iconName = iconComponent.props().name;
expect(iconName).toBe(IconName.CheckBoxOffOutline);
});
});
36 changes: 36 additions & 0 deletions app/component-library/components/Checkbox/Checkbox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/* eslint-disable react/prop-types */
import React, { useMemo } from 'react';
import { useStyles } from '../../hooks';
import Icon, { IconName, IconSize } from '../Icon';
import styleSheet from './Checkbox.styles';
import { CheckboxProps } from './Checkbox.types';
import { CHECKBOX_ICON_ID } from '../../../constants/test-ids';

const Checkbox = ({ style, isSelected, ...props }: CheckboxProps) => {
const {
styles,
theme: { colors },
} = useStyles(styleSheet, { style, isSelected });
const iconName = useMemo(
() =>
isSelected ? IconName.CheckBoxOnFilled : IconName.CheckBoxOffOutline,
[isSelected],
);
const iconColor = useMemo(
() => (isSelected ? colors.primary.default : colors.icon.muted),
[isSelected, colors],
);

return (
<Icon
testID={CHECKBOX_ICON_ID}
name={iconName}
size={IconSize.Lg}
color={iconColor}
style={styles.base}
{...props}
/>
);
};

export default Checkbox;
30 changes: 30 additions & 0 deletions app/component-library/components/Checkbox/Checkbox.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { StyleProp, ViewProps, ViewStyle } from 'react-native';

/**
* Checkbox component props.
*/
export interface CheckboxProps extends ViewProps {
/**
* Determines if checkbox is selected.
*/
isSelected: boolean;
/**
* Escape hatch for applying extra styles. Only use if absolutely necessary.
*/
style?: StyleProp<ViewStyle>;
}

/**
* Checkbox component style sheet.
*/
export interface CheckboxStyleSheet {
base: ViewStyle;
}

/**
* Style sheet input parameters.
*/
export type CheckboxStyleSheetVars = Pick<
CheckboxProps,
'style' | 'isSelected'
>;
15 changes: 15 additions & 0 deletions app/component-library/components/Checkbox/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Checkbox

Checkbox is a component typically used for multi-select scenarios.

## Props

This component extends `ViewProps` from React Native's [View Component](https://reactnative.dev/docs/view).

### `isSelected`

Determines if checkbox is selected.

| <span style="color:gray;font-size:14px">TYPE</span> | <span style="color:gray;font-size:14px">REQUIRED</span> |
| :-------------------------------------------------- | :------------------------------------------------------ |
| boolean | Yes |
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Checkbox should render correctly 1`] = `
<Icon
color="#037DD6"
name="CheckBoxOnFilled"
size="24"
style={Object {}}
testID="checkbox-icon"
/>
`;
1 change: 1 addition & 0 deletions app/component-library/components/Checkbox/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './Checkbox';
8 changes: 8 additions & 0 deletions app/component-library/components/Icon/Icon.assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ import CardTokenFilled from './assets/card-token-filled.svg';
import CategoryFilled from './assets/category-filled.svg';
import ChartFilled1 from './assets/chart-filled-1.svg';
import ChartFilled from './assets/chart-filled.svg';
import CheckBoxOffOutline from './assets/check-box-off-outline.svg';
import CheckBoxOnFilled from './assets/check-box-on-filled.svg';
import CheckCircleOffOutline from './assets/check-circle-off-outline.svg';
import CheckCircleOnFilled from './assets/check-circle-on-filled.svg';
import CheckOutline from './assets/check-outline.svg';
import ClockFilled from './assets/clock-filled.svg';
import CloseOutline from './assets/close-outline.svg';
Expand Down Expand Up @@ -158,6 +162,10 @@ export const assetByIconName: AssetByIconName = {
[IconName.CategoryFilled]: CategoryFilled,
[IconName.ChartFilled1]: ChartFilled1,
[IconName.ChartFilled]: ChartFilled,
[IconName.CheckBoxOffOutline]: CheckBoxOffOutline,
[IconName.CheckBoxOnFilled]: CheckBoxOnFilled,
[IconName.CheckCircleOffOutline]: CheckCircleOffOutline,
[IconName.CheckCircleOnFilled]: CheckCircleOnFilled,
[IconName.CheckOutline]: CheckOutline,
[IconName.ClockFilled]: ClockFilled,
[IconName.CloseOutline]: CloseOutline,
Expand Down
4 changes: 4 additions & 0 deletions app/component-library/components/Icon/Icon.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ export enum IconName {
CategoryFilled = 'CategoryFilled',
ChartFilled1 = 'ChartFilled1',
ChartFilled = 'ChartFilled',
CheckBoxOffOutline = 'CheckBoxOffOutline',
CheckBoxOnFilled = 'CheckBoxOnFilled',
CheckCircleOffOutline = 'CheckCircleOffOutline',
CheckCircleOnFilled = 'CheckCircleOnFilled',
CheckOutline = 'CheckOutline',
ClockFilled = 'ClockFilled',
CloseOutline = 'CloseOutline',
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions app/constants/test-ids.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,4 @@ export const NEW_NETWORK_ADDED_SWITCH_TO_NETWORK_BUTTON_ID =
// Component library test ids
export const FAVICON_AVATAR_IMAGE_ID = 'favicon-avatar-image';
export const NETWORK_AVATAR_IMAGE_ID = 'network-avatar-image';
export const CHECKBOX_ICON_ID = 'checkbox-icon';
6 changes: 4 additions & 2 deletions storybook/storyLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,12 @@ function loadStories() {
require('../app/component-library/components/ButtonSecondary/ButtonSecondary.stories');
require('../app/component-library/components/ButtonTertiary/ButtonTertiary.stories');
require('../app/component-library/components/BaseText/BaseText.stories');
require('../app/component-library/components/Checkbox/Checkbox.stories');
require('../app/component-library/components/FaviconAvatar/FaviconAvatar.stories');
require('../app/component-library/components/Icon/Icon.stories');
require('../app/component-library/components/IconButton/IconButton.stories');
require('../app/component-library/components/Link/Link.stories');
require('../app/component-library/components/NetworkAvatar/NetworkAvatar.stories');
require('../app/component-library/components/FaviconAvatar/FaviconAvatar.stories');
require('../app/component-library/components/TabBarItem/TabBarItem.stories');
}

Expand All @@ -43,11 +44,12 @@ const stories = [
'../app/component-library/components/ButtonSecondary/ButtonSecondary.stories',
'../app/component-library/components/ButtonTertiary/ButtonTertiary.stories',
'../app/component-library/components/BaseText/BaseText.stories',
'../app/component-library/components/Checkbox/Checkbox.stories',
'../app/component-library/components/FaviconAvatar/FaviconAvatar.stories',
'../app/component-library/components/Icon/Icon.stories',
'../app/component-library/components/IconButton/IconButton.stories',
'../app/component-library/components/Link/Link.stories',
'../app/component-library/components/NetworkAvatar/NetworkAvatar.stories',
'../app/component-library/components/FaviconAvatar/FaviconAvatar.stories',
'../app/component-library/components/TabBarItem/TabBarItem.stories',
];

Expand Down

0 comments on commit 27950e7

Please sign in to comment.