Skip to content

Commit

Permalink
feat: Add TagColored to component temp (#8677)
Browse files Browse the repository at this point in the history
## **Description**
- Added TagColored to component temp folder, based on
https://www.figma.com/file/PsKqriAOpJDQpaHt373D45/Off-Ramp?type=design&node-id=1%3A2&mode=design&t=pPqrfRmG4eNsCDPZ-1

## **Related issues**

Fixes: #8676 

## **Manual testing steps**

1. Change pointer in `index.js` to Storybook to open Storybook
2. Click on Components Temp
3. Click on TagColored

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

https://github.com/MetaMask/metamask-mobile/assets/14355083/12c727d0-474c-4638-aae5-ac551b4f81d6

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [x] I’ve followed [MetaMask Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've clearly explained what problem this PR is solving and how it
is solved.
- [x] I've linked related issues
- [x] I've included manual testing steps
- [x] I've included screenshots/recordings if applicable
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
- [x] I’ve properly set the pull request status:
  - [ ] In case it's not yet "ready for review", I've set it to "draft".
- [ ] In case it's "ready for review", I've changed it from "draft" to
"non-draft".

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
  • Loading branch information
brianacnguyen authored Feb 22, 2024
1 parent e572035 commit 291bc71
Show file tree
Hide file tree
Showing 11 changed files with 431 additions and 1 deletion.
1 change: 1 addition & 0 deletions .storybook/main.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module.exports = {
stories: [
'../app/component-library/components/**/*.stories.?(ts|tsx|js|jsx)',
'../app/component-library/components-temp/TagColored/**/*.stories.?(ts|tsx|js|jsx)',
],
addons: ['@storybook/addon-ondevice-controls'],
framework: '@storybook/react-native',
Expand Down
10 changes: 9 additions & 1 deletion .storybook/storybook.requires.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ global.STORIES = [
importPathMatcher:
"^\\.[\\\\/](?:app\\/component-library\\/components(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.(?:ts|tsx|js|jsx)?)$",
},
{
titlePrefix: "",
directory: "./app/component-library/components-temp/TagColored",
files: "**/*.stories.?(ts|tsx|js|jsx)",
importPathMatcher:
"^\\.[\\\\/](?:app\\/component-library\\/components-temp\\/TagColored(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.(?:ts|tsx|js|jsx)?)$",
},
];

import "@storybook/addon-ondevice-controls/register";
Expand Down Expand Up @@ -87,8 +94,8 @@ const getStories = () => {
"./app/component-library/components/Pickers/PickerAccount/PickerAccount.stories.tsx": require("../app/component-library/components/Pickers/PickerAccount/PickerAccount.stories.tsx"),
"./app/component-library/components/Pickers/PickerNetwork/PickerNetwork.stories.tsx": require("../app/component-library/components/Pickers/PickerNetwork/PickerNetwork.stories.tsx"),
"./app/component-library/components/RadioButton/RadioButton.stories.tsx": require("../app/component-library/components/RadioButton/RadioButton.stories.tsx"),
"./app/component-library/components/Select/SelectOption/SelectOption.stories.tsx": require("../app/component-library/components/Select/SelectOption/SelectOption.stories.tsx"),
"./app/component-library/components/Select/SelectButton/SelectButton.stories.tsx": require("../app/component-library/components/Select/SelectButton/SelectButton.stories.tsx"),
"./app/component-library/components/Select/SelectOption/SelectOption.stories.tsx": require("../app/component-library/components/Select/SelectOption/SelectOption.stories.tsx"),
"./app/component-library/components/Select/SelectValue/SelectValue.stories.tsx": require("../app/component-library/components/Select/SelectValue/SelectValue.stories.tsx"),
"./app/component-library/components/Sheet/SheetBottom/SheetBottom.stories.tsx": require("../app/component-library/components/Sheet/SheetBottom/SheetBottom.stories.tsx"),
"./app/component-library/components/Sheet/SheetHeader/SheetHeader.stories.tsx": require("../app/component-library/components/Sheet/SheetHeader/SheetHeader.stories.tsx"),
Expand All @@ -97,6 +104,7 @@ const getStories = () => {
"./app/component-library/components/Texts/Text/Text.stories.tsx": require("../app/component-library/components/Texts/Text/Text.stories.tsx"),
"./app/component-library/components/Texts/TextWithPrefixIcon/TextWithPrefixIcon.stories.tsx": require("../app/component-library/components/Texts/TextWithPrefixIcon/TextWithPrefixIcon.stories.tsx"),
"./app/component-library/components/Toast/Toast.stories.tsx": require("../app/component-library/components/Toast/Toast.stories.tsx"),
"./app/component-library/components-temp/TagColored/TagColored.stories.tsx": require("../app/component-library/components-temp/TagColored/TagColored.stories.tsx"),
};
};

Expand Down
40 changes: 40 additions & 0 deletions app/component-library/components-temp/TagColored/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# TagColored

## TagColored Props

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

### `color`

Optional prop to configure the color of the TagColored

| <span style="color:gray;font-size:14px">TYPE</span> | <span style="color:gray;font-size:14px">REQUIRED</span> | <span style="color:gray;font-size:14px">DEFAULT</span> |
| :-------------------------------------------------- | :------------------------------------------------------ | :----------------------------------------------------- |
| [TagColor](./TagColored.types.ts) | No | TagColor.Default |

### `children`

Content to wrap to display.

| <span style="color:gray;font-size:14px">TYPE</span> | <span style="color:gray;font-size:14px">REQUIRED</span> |
| :-------------------------------------------------- | :------------------------------------------------------ |
| string or ReactNode | Yes |

## Usage

```javascript
// Passing text to children
<TagColored color={TagColor.Default}>SAMPLE TAGCOLORED TEXT</TagColored>;

// Passing node to children
<TagColored color={TagColor.Default}>
<Text>SAMPLE TAGCOLORED TEXT</Text>
</TagColored>;

// Configuring different colors
<TagColored color={TagColor.Default}>SAMPLE TAGCOLORED TEXT</TagColored>;
<TagColored color={TagColor.Success}>SAMPLE TAGCOLORED TEXT</TagColored>;
<TagColored color={TagColor.Info}>SAMPLE TAGCOLORED TEXT</TagColored>;
<TagColored color={TagColor.Danger}>SAMPLE TAGCOLORED TEXT</TagColored>;
<TagColored color={TagColor.Warning}>SAMPLE TAGCOLORED TEXT</TagColored>;
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/* eslint-disable import/prefer-default-export */
// External dependencies
import { TextVariant } from '../../components/Texts/Text';

// Internal dependencies
import { TagColor, TagColoredProps } from './TagColored.types';

// Defaults
export const DEFAULT_TAGCOLORED_COLOR = TagColor.Default;
export const DEFAULT_TAGCOLORED_TEXTVARIANT = TextVariant.BodyXS;

// Test IDs
export const TAGCOLORED_TESTID = 'tagcolored';
export const TAGCOLORED_TEXT_TESTID = 'tagcolored-text';

// Sample consts
export const SAMPLE_TAGCOLORED_PROPS: TagColoredProps = {
color: DEFAULT_TAGCOLORED_COLOR,
children: 'Sample TagColored text',
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Internal dependencies.
import { default as TagColoredComponent } from './TagColored';
import { TagColor } from './TagColored.types';
import { SAMPLE_TAGCOLORED_PROPS } from './TagColored.constants';

const TagColoredStoryMeta = {
title: 'Components Temp / TagColored',
component: TagColoredComponent,
argTypes: {
color: {
options: TagColor,
control: {
type: 'select',
},
},
children: {
control: { type: 'text' },
},
},
};

export default TagColoredStoryMeta;

export const TagColored = {
args: {
color: SAMPLE_TAGCOLORED_PROPS.color,
children: SAMPLE_TAGCOLORED_PROPS.children,
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Third party dependencies.
import { StyleSheet, ViewStyle } from 'react-native';

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

// Internal dependencies.
import { TagColoredStyleSheetVars, TagColor } from './TagColored.types';

/**
* Style sheet function for TagColored 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: TagColoredStyleSheetVars;
}) => {
const { vars, theme } = params;
const { style, color } = vars;
let backgroundColor, textColor;
switch (color) {
case TagColor.Default:
backgroundColor = theme.colors.background.alternative;
textColor = theme.colors.text.alternative;
break;
case TagColor.Success:
backgroundColor = theme.colors.success.muted;
textColor = theme.colors.success.default;
break;
case TagColor.Info:
backgroundColor = theme.colors.primary.muted;
textColor = theme.colors.primary.default;
break;
case TagColor.Danger:
backgroundColor = theme.colors.error.muted;
textColor = theme.colors.error.default;
break;
case TagColor.Warning:
backgroundColor = theme.colors.warning.muted;
textColor = theme.colors.warning.default;
break;
default:
backgroundColor = theme.colors.background.alternative;
textColor = theme.colors.text.alternative;
}

return StyleSheet.create({
base: Object.assign(
{
height: 20,
backgroundColor,
borderRadius: 4,
paddingHorizontal: 8,
alignSelf: 'flex-start',
alignItems: 'center',
justifyContent: 'center',
} as ViewStyle,
style,
) as ViewStyle,
text: {
fontWeight: 'bold',
textTransform: 'uppercase',
color: textColor,
},
});
};

export default styleSheet;
144 changes: 144 additions & 0 deletions app/component-library/components-temp/TagColored/TagColored.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
// Third party dependencies
import React from 'react';
import { render } from '@testing-library/react-native';

// External dependencies
import Text from '../../components/Texts/Text';
import { mockTheme } from '../../../util/theme';

// Internal dependencies
import TagColored from './TagColored';
import {
DEFAULT_TAGCOLORED_TEXTVARIANT,
SAMPLE_TAGCOLORED_PROPS,
TAGCOLORED_TESTID,
TAGCOLORED_TEXT_TESTID,
} from './TagColored.constants';
import { TagColor } from './TagColored.types';

describe('TagColored', () => {
it('should render TagColored', () => {
const wrapper = render(<TagColored {...SAMPLE_TAGCOLORED_PROPS} />);
expect(wrapper).toMatchSnapshot();
expect(wrapper.queryByTestId(TAGCOLORED_TESTID)).not.toBe(null);
});

it('should render children correctly when provided', () => {
const testText = 'TagColored';
const ChildrenComponent = () => <Text>{testText}</Text>;

const { getByText } = render(
<TagColored>
<ChildrenComponent />
</TagColored>,
);

expect(getByText(testText)).toBeDefined();
});

it('should render children correctly when a string is provided', () => {
const testText = 'TagColored';

const { getByText } = render(<TagColored>{testText}</TagColored>);

expect(getByText(testText)).toBeDefined();
});

it('should render children with the right text variant if typeof children === string', () => {
const testText = 'TagColored';

const { getByText } = render(<TagColored>{testText}</TagColored>);

expect(getByText(testText).props.style.fontSize).toBe(
mockTheme.typography[DEFAULT_TAGCOLORED_TEXTVARIANT].fontSize,
);
});

it('should render the correct default color on default', () => {
const testText = 'TagColored';

const { getByTestId } = render(<TagColored>{testText}</TagColored>);

expect(getByTestId(TAGCOLORED_TESTID).props.style.backgroundColor).toBe(
mockTheme.colors.background.alternative,
);
expect(getByTestId(TAGCOLORED_TEXT_TESTID).props.style.color).toBe(
mockTheme.colors.text.alternative,
);
});

it('should render the correct default color when given', () => {
const testText = 'TagColored';

const { getByTestId } = render(
<TagColored color={TagColor.Default}>{testText}</TagColored>,
);

expect(getByTestId(TAGCOLORED_TESTID).props.style.backgroundColor).toBe(
mockTheme.colors.background.alternative,
);
expect(getByTestId(TAGCOLORED_TEXT_TESTID).props.style.color).toBe(
mockTheme.colors.text.alternative,
);
});

it('should render the correct success color when given', () => {
const testText = 'TagColored';

const { getByTestId } = render(
<TagColored color={TagColor.Success}>{testText}</TagColored>,
);

expect(getByTestId(TAGCOLORED_TESTID).props.style.backgroundColor).toBe(
mockTheme.colors.success.muted,
);
expect(getByTestId(TAGCOLORED_TEXT_TESTID).props.style.color).toBe(
mockTheme.colors.success.default,
);
});

it('should render the correct info color when given', () => {
const testText = 'TagColored';

const { getByTestId } = render(
<TagColored color={TagColor.Info}>{testText}</TagColored>,
);

expect(getByTestId(TAGCOLORED_TESTID).props.style.backgroundColor).toBe(
mockTheme.colors.primary.muted,
);
expect(getByTestId(TAGCOLORED_TEXT_TESTID).props.style.color).toBe(
mockTheme.colors.primary.default,
);
});

it('should render the correct danger color when given', () => {
const testText = 'TagColored';

const { getByTestId } = render(
<TagColored color={TagColor.Danger}>{testText}</TagColored>,
);

expect(getByTestId(TAGCOLORED_TESTID).props.style.backgroundColor).toBe(
mockTheme.colors.error.muted,
);
expect(getByTestId(TAGCOLORED_TEXT_TESTID).props.style.color).toBe(
mockTheme.colors.error.default,
);
});

it('should render the correct warning color when given', () => {
const testText = 'TagColored';

const { getByTestId } = render(
<TagColored color={TagColor.Warning}>{testText}</TagColored>,
);

expect(getByTestId(TAGCOLORED_TESTID).props.style.backgroundColor).toBe(
mockTheme.colors.warning.muted,
);
expect(getByTestId(TAGCOLORED_TEXT_TESTID).props.style.color).toBe(
mockTheme.colors.warning.default,
);
});
});
44 changes: 44 additions & 0 deletions app/component-library/components-temp/TagColored/TagColored.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/* eslint-disable react/prop-types */

// Third party dependencies.
import React from 'react';
import { View } from 'react-native';

// External dependencies.
import { useStyles } from '../../hooks';
import Text from '../../../component-library/components/Texts/Text';

// Internal dependencies.
import styleSheet from './TagColored.styles';
import { TagColoredProps } from './TagColored.types';
import {
DEFAULT_TAGCOLORED_COLOR,
DEFAULT_TAGCOLORED_TEXTVARIANT,
TAGCOLORED_TESTID,
TAGCOLORED_TEXT_TESTID,
} from './TagColored.constants';

const TagColored: React.FC<TagColoredProps> = ({
style,
color = DEFAULT_TAGCOLORED_COLOR,
children,
}) => {
const { styles } = useStyles(styleSheet, { style, color });
return (
<View style={styles.base} testID={TAGCOLORED_TESTID}>
{typeof children === 'string' ? (
<Text
variant={DEFAULT_TAGCOLORED_TEXTVARIANT}
style={styles.text}
testID={TAGCOLORED_TEXT_TESTID}
>
{children}
</Text>
) : (
children
)}
</View>
);
};

export default TagColored;
Loading

0 comments on commit 291bc71

Please sign in to comment.