Skip to content

Commit

Permalink
[PS] Componentize Cell #4083 (#4756)
Browse files Browse the repository at this point in the history
* [PS] Componentize Cell #4083

* Updated commit based on reviews

* Renamed Cell component to CellAccount

* Add usage section to README
  • Loading branch information
brianacnguyen authored Aug 3, 2022
1 parent f5dd908 commit 5c7df8c
Show file tree
Hide file tree
Showing 40 changed files with 1,518 additions and 300 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export const TEST_ACCOUNT_ADDRESS =
'0x2990079bcdEe240329a520d2444386FC119da21a';
export const TEST_CELL_ACCOUNT_TITLE = 'Orangefox.eth';
export const TEST_CELL_ACCOUNT_SECONDARY_TEXT =
'0x2990079bcdEe240329a520d2444386FC119da21a';
export const TEST_CELL_ACCOUNT_TERTIARY_TEXT = 'Updated 1 sec ago';
export const TEST_TAG_LABEL_TEXT = 'Imported';

export const CELL_ACCOUNT_SINGLE_SELECT_TEST_ID = 'cell-account-single-select';
export const CELL_ACCOUNT_MULTI_SELECT_TEST_ID = 'cell-account-multi-select';
export const CELL_ACCOUNT_AVATAR_TEST_ID = 'cell-account-avatar';
export const CELL_ACCOUNT_TITLE_TEST_ID = 'cell-account-title';
export const CELL_ACCOUNT_SECONDARY_TEXT_TEST_ID =
'cell-account-secondary-text';
export const CELL_ACCOUNT_TERTIARY_TEXT_TEST_ID = 'cell-account-tertiary-text';
export const CELL_ACCOUNT_TAG_LABEL_TEST_ID = 'cell-account-label';
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/* eslint-disable no-console */
// 3rd party dependencies
import React from 'react';
import { Alert } from 'react-native';
import { boolean, text } from '@storybook/addon-knobs';
import { storiesOf } from '@storybook/react-native';

// External dependencies
import { AccountAvatarType } from '../AccountAvatar';

// Internal dependencies
import CellAccount from './CellAccount';
import {
TEST_ACCOUNT_ADDRESS,
TEST_CELL_ACCOUNT_TITLE,
TEST_CELL_ACCOUNT_SECONDARY_TEXT,
TEST_CELL_ACCOUNT_TERTIARY_TEXT,
TEST_TAG_LABEL_TEXT,
} from './CellAccount.constants';

storiesOf('Component Library / Cell', module).add('Default', () => {
const groupId = 'Props';
const isMultiSelect = boolean('IsMultiSelect?', false, groupId);
const titleText = text('title', TEST_CELL_ACCOUNT_TITLE, groupId);
const includeSecondaryText = boolean(
'Includes secondaryText?',
false,
groupId,
);
const secondaryText = includeSecondaryText
? text('secondaryText', TEST_CELL_ACCOUNT_SECONDARY_TEXT, groupId)
: '';
const includeTertiaryText = boolean('Includes tertiaryText?', false, groupId);
const tertiaryText = includeTertiaryText
? text('tertiaryText', TEST_CELL_ACCOUNT_TERTIARY_TEXT, groupId)
: '';
const includeTagLabel = boolean('Includes label?', false, groupId);
const tagLabel = includeTagLabel
? text('label', TEST_TAG_LABEL_TEXT, groupId)
: '';
const isSelected = boolean('isSelected?', false, groupId);

return (
<CellAccount
accountAddress={TEST_ACCOUNT_ADDRESS}
accountAvatarType={AccountAvatarType.JazzIcon}
title={titleText}
secondaryText={secondaryText}
tertiaryText={tertiaryText}
tagLabel={tagLabel}
isSelected={isSelected}
isMultiSelect={isMultiSelect}
onPress={() => Alert.alert('Pressed account Cell!')}
/>
);
});
53 changes: 53 additions & 0 deletions app/component-library/components/CellAccount/CellAccount.styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// 3rd library dependencies
import { StyleSheet, ViewStyle } from 'react-native';

// External dependencies
import { CellAccountStyleSheetVars } from './CellAccount.types';

// Internal dependencies
import { Theme } from '../../../util/theme/models';

/**
* Style sheet function for CellAccount 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: {
theme: Theme;
vars: CellAccountStyleSheetVars;
}) => {
const { vars, theme } = params;
const { colors } = theme;
const { style } = vars;

return StyleSheet.create({
base: Object.assign({} as ViewStyle, style) as ViewStyle,
cellAccount: {
flexDirection: 'row',
},
accountAvatar: {
marginRight: 16,
},
cellAccountInfo: {
flex: 1,
alignItems: 'flex-start',
},
optionalAccessory: {
marginLeft: 16,
},
secondaryText: {
color: colors.text.alternative,
},
tertiaryText: {
color: colors.text.alternative,
},
tagLabel: {
marginTop: 4,
},
});
};

export default styleSheet;
259 changes: 259 additions & 0 deletions app/component-library/components/CellAccount/CellAccount.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,259 @@
// 3rd party dependencies
import React from 'react';
import { shallow } from 'enzyme';

// External dependencies
import { AccountAvatarType } from '../AccountAvatar';

// Internal dependencies
import CellAccount from './CellAccount';
import {
TEST_ACCOUNT_ADDRESS,
TEST_CELL_ACCOUNT_TITLE,
TEST_CELL_ACCOUNT_SECONDARY_TEXT,
TEST_CELL_ACCOUNT_TERTIARY_TEXT,
TEST_TAG_LABEL_TEXT,
CELL_ACCOUNT_SINGLE_SELECT_TEST_ID,
CELL_ACCOUNT_MULTI_SELECT_TEST_ID,
CELL_ACCOUNT_AVATAR_TEST_ID,
CELL_ACCOUNT_TITLE_TEST_ID,
CELL_ACCOUNT_SECONDARY_TEXT_TEST_ID,
CELL_ACCOUNT_TERTIARY_TEXT_TEST_ID,
CELL_ACCOUNT_TAG_LABEL_TEST_ID,
} from './CellAccount.constants';

describe('CellAccount - Snapshot', () => {
it('should render default settings correctly', () => {
const wrapper = shallow(
<CellAccount
accountAddress={TEST_ACCOUNT_ADDRESS}
accountAvatarType={AccountAvatarType.JazzIcon}
title={TEST_CELL_ACCOUNT_TITLE}
onPress={jest.fn}
/>,
);
expect(wrapper).toMatchSnapshot();
});
it('should render secondaryText when given', () => {
const wrapper = shallow(
<CellAccount
accountAddress={TEST_ACCOUNT_ADDRESS}
accountAvatarType={AccountAvatarType.JazzIcon}
title={TEST_CELL_ACCOUNT_TITLE}
secondaryText={TEST_CELL_ACCOUNT_SECONDARY_TEXT}
onPress={jest.fn}
/>,
);
expect(wrapper).toMatchSnapshot();
});
it('should render tertiaryText when given', () => {
const wrapper = shallow(
<CellAccount
accountAddress={TEST_ACCOUNT_ADDRESS}
accountAvatarType={AccountAvatarType.JazzIcon}
title={TEST_CELL_ACCOUNT_TITLE}
tertiaryText={TEST_CELL_ACCOUNT_TERTIARY_TEXT}
onPress={jest.fn}
/>,
);
expect(wrapper).toMatchSnapshot();
});
it('should render label when given', () => {
const wrapper = shallow(
<CellAccount
accountAddress={TEST_ACCOUNT_ADDRESS}
accountAvatarType={AccountAvatarType.JazzIcon}
title={TEST_CELL_ACCOUNT_TITLE}
tagLabel={TEST_TAG_LABEL_TEXT}
onPress={jest.fn}
/>,
);
expect(wrapper).toMatchSnapshot();
});
it('should render the proper selected state', () => {
const wrapper = shallow(
<CellAccount
accountAddress={TEST_ACCOUNT_ADDRESS}
accountAvatarType={AccountAvatarType.JazzIcon}
title={TEST_CELL_ACCOUNT_TITLE}
isSelected
onPress={jest.fn}
/>,
);
expect(wrapper).toMatchSnapshot();
});
it('should render the proper multiselect when isMultiSelect is true', () => {
const wrapper = shallow(
<CellAccount
accountAddress={TEST_ACCOUNT_ADDRESS}
accountAvatarType={AccountAvatarType.JazzIcon}
title={TEST_CELL_ACCOUNT_TITLE}
isMultiSelect
onPress={jest.fn}
/>,
);
expect(wrapper).toMatchSnapshot();
});
});

describe('CellAccount', () => {
it('should render singleSelect if isMultiSelect is false', () => {
const wrapper = shallow(
<CellAccount
accountAddress={TEST_ACCOUNT_ADDRESS}
accountAvatarType={AccountAvatarType.JazzIcon}
title={TEST_CELL_ACCOUNT_TITLE}
onPress={jest.fn}
isMultiSelect={false}
/>,
);
const singleSelectComponent = wrapper.findWhere(
(node) => node.prop('testID') === CELL_ACCOUNT_SINGLE_SELECT_TEST_ID,
);
expect(singleSelectComponent.exists()).toBe(true);

const multiSelectComponent = wrapper.findWhere(
(node) => node.prop('testID') === CELL_ACCOUNT_MULTI_SELECT_TEST_ID,
);
expect(multiSelectComponent.exists()).toBe(false);
});
it('should render multiSelect if isMultiSelect is true', () => {
const wrapper = shallow(
<CellAccount
accountAddress={TEST_ACCOUNT_ADDRESS}
accountAvatarType={AccountAvatarType.JazzIcon}
title={TEST_CELL_ACCOUNT_TITLE}
isMultiSelect
onPress={jest.fn}
/>,
);
const singleSelectComponent = wrapper.findWhere(
(node) => node.prop('testID') === CELL_ACCOUNT_SINGLE_SELECT_TEST_ID,
);
expect(singleSelectComponent.exists()).toBe(false);

const multiSelectComponent = wrapper.findWhere(
(node) => node.prop('testID') === CELL_ACCOUNT_MULTI_SELECT_TEST_ID,
);
expect(multiSelectComponent.exists()).toBe(true);
});
it('should render Avatar', () => {
const wrapper = shallow(
<CellAccount
accountAddress={TEST_ACCOUNT_ADDRESS}
accountAvatarType={AccountAvatarType.JazzIcon}
title={TEST_CELL_ACCOUNT_TITLE}
onPress={jest.fn}
/>,
);
const avatarComponent = wrapper.findWhere(
(node) => node.prop('testID') === CELL_ACCOUNT_AVATAR_TEST_ID,
);
expect(avatarComponent.exists()).toBe(true);
});
it('should render the given title', () => {
const wrapper = shallow(
<CellAccount
accountAddress={TEST_ACCOUNT_ADDRESS}
accountAvatarType={AccountAvatarType.JazzIcon}
title={TEST_CELL_ACCOUNT_TITLE}
onPress={jest.fn}
/>,
);
const titleElement = wrapper.findWhere(
(node) => node.prop('testID') === CELL_ACCOUNT_TITLE_TEST_ID,
);
expect(titleElement.props().children).toBe(TEST_CELL_ACCOUNT_TITLE);
});
it('should render the given secondaryText', () => {
const wrapper = shallow(
<CellAccount
accountAddress={TEST_ACCOUNT_ADDRESS}
accountAvatarType={AccountAvatarType.JazzIcon}
title={TEST_CELL_ACCOUNT_TITLE}
secondaryText={TEST_CELL_ACCOUNT_SECONDARY_TEXT}
onPress={jest.fn}
/>,
);
const secondaryTextElement = wrapper.findWhere(
(node) => node.prop('testID') === CELL_ACCOUNT_SECONDARY_TEXT_TEST_ID,
);
expect(secondaryTextElement.props().children).toBe(
TEST_CELL_ACCOUNT_SECONDARY_TEXT,
);
});
it('should not render secondaryText if not given', () => {
const wrapper = shallow(
<CellAccount
accountAddress={TEST_ACCOUNT_ADDRESS}
accountAvatarType={AccountAvatarType.JazzIcon}
title={TEST_CELL_ACCOUNT_TITLE}
onPress={jest.fn}
/>,
);
const secondaryTextElement = wrapper.findWhere(
(node) => node.prop('testID') === CELL_ACCOUNT_SECONDARY_TEXT_TEST_ID,
);
expect(secondaryTextElement.exists()).toBe(false);
});
it('should render the given tertiaryText', () => {
const wrapper = shallow(
<CellAccount
accountAddress={TEST_ACCOUNT_ADDRESS}
accountAvatarType={AccountAvatarType.JazzIcon}
title={TEST_CELL_ACCOUNT_TITLE}
tertiaryText={TEST_CELL_ACCOUNT_TERTIARY_TEXT}
onPress={jest.fn}
/>,
);
const tertiaryTextElement = wrapper.findWhere(
(node) => node.prop('testID') === CELL_ACCOUNT_TERTIARY_TEXT_TEST_ID,
);
expect(tertiaryTextElement.props().children).toBe(
TEST_CELL_ACCOUNT_TERTIARY_TEXT,
);
});
it('should not render tertiaryText if not given', () => {
const wrapper = shallow(
<CellAccount
accountAddress={TEST_ACCOUNT_ADDRESS}
accountAvatarType={AccountAvatarType.JazzIcon}
title={TEST_CELL_ACCOUNT_TITLE}
onPress={jest.fn}
/>,
);
const tertiaryTextElement = wrapper.findWhere(
(node) => node.prop('testID') === CELL_ACCOUNT_TERTIARY_TEXT_TEST_ID,
);
expect(tertiaryTextElement.exists()).toBe(false);
});
it('should render tag with given label', () => {
const wrapper = shallow(
<CellAccount
accountAddress={TEST_ACCOUNT_ADDRESS}
accountAvatarType={AccountAvatarType.JazzIcon}
title={TEST_CELL_ACCOUNT_TITLE}
tagLabel={TEST_TAG_LABEL_TEXT}
onPress={jest.fn}
/>,
);
const tagComponent = wrapper.findWhere(
(node) => node.prop('testID') === CELL_ACCOUNT_TAG_LABEL_TEST_ID,
);
expect(tagComponent.exists()).toBe(true);
});
it('should not render tag without given label', () => {
const wrapper = shallow(
<CellAccount
accountAddress={TEST_ACCOUNT_ADDRESS}
accountAvatarType={AccountAvatarType.JazzIcon}
title={TEST_CELL_ACCOUNT_TITLE}
onPress={jest.fn}
/>,
);
const tagComponent = wrapper.findWhere(
(node) => node.prop('testID') === CELL_ACCOUNT_TAG_LABEL_TEST_ID,
);
expect(tagComponent.exists()).toBe(false);
});
});
Loading

0 comments on commit 5c7df8c

Please sign in to comment.