1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-11-22 18:00:18 +01:00

Update HelpText component (#17705)

* Updating HelpText component

* Updating logic for html element depending on children

* Adding span to story to reflect docs

* Updating reveal seed instance
This commit is contained in:
George Marshall 2023-02-16 12:42:15 -08:00 committed by GitHub
parent 33cc8d587a
commit cf487b8f97
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 147 additions and 85 deletions

View File

@ -5,6 +5,7 @@ import classnames from 'classnames';
import {
DISPLAY,
FLEX_DIRECTION,
SEVERITIES,
Size,
} from '../../../helpers/constants/design-system';
@ -103,6 +104,7 @@ export const FormTextField = ({
{helpText && (
<HelpText
error={error}
severity={error && SEVERITIES.DANGER}
marginTop={1}
{...helpTextProps}
className={classnames(

View File

@ -6,7 +6,7 @@ import { HelpText } from './help-text';
# HelpText
The `HelpText` is intended to be used as the help or error text under a form element
The `HelpText` is used as feedback text under a form field including error, success, warning or info messages
<Canvas>
<Story id="components-componentlibrary-helptext--default-story" />
@ -24,40 +24,49 @@ The `HelpText` accepts all props below as well as all [Box](/docs/components-ui-
### Children
The `children` of the `HelpText` can be plain text or react nodes
<Canvas>
<Story id="components-componentlibrary-helptext--children" />
</Canvas>
`HelpText` renders as a `<p>` tag if the child is a `string` or a `<div>` if the child is an `object`.
```jsx
import { Size, IconColor } from '../../../helpers/constants/design-system';
import { HelpText, Icon, ICON_NAMES } from '../../component-library';
<HelpText>Plain text</HelpText>
<HelpText>Plain text</HelpText> // renders as <p>Plain text</p>
<HelpText>
Text and icon
<Icon
marginLeft={1}
color={IconColor.inherit}
name={ICON_NAMES.WARNING}
size={Size.inherit}
/>
</HelpText>
<span>Text and icon</span>
<Icon
marginLeft={1}
color={IconColor.iconAlternative}
name={ICON_NAMES.WARNING}
size={Size.inherit}
/>
</HelpText> // renders as <div><span>Text and icon</span> <div style={{background: icon/warning.svg}} /></div>
```
### Error
### Severity
Use the `error` prop to show the `HelpText` in error state
Use the `severity` prop and `SEVERITIES` object to change the severity of the `HelpText`
<Canvas>
<Story id="components-componentlibrary-helptext--error-story" />
<Story id="components-componentlibrary-helptext--severity-story" />
</Canvas>
```jsx
import { SEVERITIES } from '../../../helpers/constants/design-system';
import { HelpText } from '../../component-library';
<HelpText error>This HelpText in error state</HelpText>;
<HelpText>HelpText without severity prop</HelpText>
<HelpText severity={SEVERITIES.DANGER}>
HelpText with severity: SEVERITY.DANGER
</HelpText>
<HelpText severity={SEVERITIES.SUCCESS}>
HelpText with severity: SEVERITY.SUCCESS
</HelpText>
<HelpText severity={SEVERITIES.WARNING}>
HelpText with severity: SEVERITY.WARNING
</HelpText>
<HelpText severity={SEVERITIES.INFO}>
HelpText with severity: SEVERITY.INFO
</HelpText>
```
### Color
@ -72,18 +81,13 @@ It may be useful to change the color of the `HelpText`. Use the `color` prop and
import { Color } from '../../../helpers/constants/design-system';
import { HelpText } from '../../component-library';
<Box display={DISPLAY.FLEX} flexDirection={FLEX_DIRECTION.COLUMN} gap={2}>
<HelpText color={Color.textDefault} {...args}>
This HelpText default color is Color.textDefault
</HelpText>
<HelpText color={Color.infoDefault} {...args}>
This HelpText color is Color.infoDefault
</HelpText>
<HelpText color={Color.warningDefault} {...args}>
This HelpText color is Color.warningDefault
</HelpText>
<HelpText color={Color.successDefault} {...args}>
This HelpText color is Color.successDefault
</HelpText>
</Box>;
<HelpText color={TextColor.textDefault}>
This HelpText default color is TextColor.textDefault
</HelpText>
<HelpText color={TextColor.textAlternative}>
This HelpText color is TextColor.textAlternative
</HelpText>
<HelpText color={TextColor.textMuted}>
This HelpText color is TextColor.textMuted
</HelpText>
```

View File

@ -1,11 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`HelpText should render with text inside the HelpText 1`] = `
exports[`HelpText should match snapshot 1`] = `
<div>
<span
<p
class="box mm-text mm-help-text mm-text--body-xs mm-text--color-text-default box--flex-direction-row"
>
help text
</span>
</p>
</div>
`;

View File

@ -6,34 +6,46 @@ import {
Color,
TextVariant,
TextColor,
SEVERITIES,
} from '../../../helpers/constants/design-system';
import { Text } from '../text';
export const HelpText = ({
error,
severity,
color = Color.textDefault,
className,
children,
...props
}) => (
<Text
className={classnames('mm-help-text', className)}
as="span"
variant={TextVariant.bodyXs}
color={error ? Color.errorDefault : color}
{...props}
>
{children}
</Text>
);
}) => {
const severityColor = () => {
switch (severity) {
case SEVERITIES.DANGER:
return TextColor.errorDefault;
case SEVERITIES.WARNING:
return TextColor.warningDefault;
case SEVERITIES.SUCCESS:
return TextColor.successDefault;
case SEVERITIES.INFO:
return TextColor.infoDefault;
// Defaults to SEVERITIES.INFO
default:
return TextColor.textDefault;
}
};
return (
<Text
className={classnames('mm-help-text', className)}
as={children && typeof children === 'object' ? 'div' : 'p'}
variant={TextVariant.bodyXs}
color={severity ? severityColor() : color}
{...props}
>
{children}
</Text>
);
};
HelpText.propTypes = {
/**
* If the HelperText should display in error state
* Will override the color prop if true
*/
error: PropTypes.bool,
/**
* The color of the HelpText will be overridden if error is true
* Defaults to Color.textDefault

View File

@ -2,9 +2,10 @@ import React from 'react';
import {
DISPLAY,
FLEX_DIRECTION,
Color,
IconColor,
TextColor,
Size,
SEVERITIES,
} from '../../../helpers/constants/design-system';
import Box from '../../ui/box';
@ -31,8 +32,9 @@ export default {
className: {
control: 'text',
},
error: {
control: 'boolean',
severity: {
control: 'select',
options: Object.values(SEVERITIES),
},
color: {
control: 'select',
@ -52,38 +54,49 @@ DefaultStory.storyName = 'Default';
export const Children = (args) => (
<Box display={DISPLAY.FLEX} flexDirection={FLEX_DIRECTION.COLUMN} gap={2}>
<HelpText {...args}>Plain text</HelpText>
<HelpText {...args}>
Text and icon
<HelpText>
<span>Text and icon</span>
<Icon
marginLeft={1}
color={Color.inherit}
color={IconColor.iconAlternative}
name={ICON_NAMES.WARNING}
size={Size.inherit}
as="span"
/>
</HelpText>
</Box>
);
export const ErrorStory = (args) => (
<HelpText error {...args}>
This HelpText in error state
</HelpText>
export const SeverityStory = (args) => (
<>
<HelpText {...args}>HelpText without severity prop</HelpText>
<HelpText {...args} severity={SEVERITIES.DANGER}>
HelpText with severity: SEVERITY.DANGER
</HelpText>
<HelpText {...args} severity={SEVERITIES.SUCCESS}>
HelpText with severity: SEVERITY.SUCCESS
</HelpText>
<HelpText {...args} severity={SEVERITIES.WARNING}>
HelpText with severity: SEVERITY.WARNING
</HelpText>
<HelpText {...args} severity={SEVERITIES.INFO}>
HelpText with severity: SEVERITY.INFO
</HelpText>
</>
);
ErrorStory.storyName = 'Error';
SeverityStory.storyName = 'Severity';
export const ColorStory = (args) => (
<Box display={DISPLAY.FLEX} flexDirection={FLEX_DIRECTION.COLUMN} gap={2}>
<HelpText color={Color.textDefault} {...args}>
This HelpText default color is Color.textDefault
<HelpText color={TextColor.textDefault} {...args}>
This HelpText default color is TextColor.textDefault
</HelpText>
<HelpText color={Color.infoDefault} {...args}>
This HelpText color is Color.infoDefault
<HelpText color={TextColor.textAlternative} {...args}>
This HelpText color is TextColor.textAlternative
</HelpText>
<HelpText color={Color.warningDefault} {...args}>
This HelpText color is Color.warningDefault
</HelpText>
<HelpText color={Color.successDefault} {...args}>
This HelpText color is Color.successDefault
<HelpText color={TextColor.textMuted} {...args}>
This HelpText color is TextColor.textMuted
</HelpText>
</Box>
);

View File

@ -1,16 +1,19 @@
/* eslint-disable jest/require-top-level-describe */
import { render } from '@testing-library/react';
import React from 'react';
import { Color } from '../../../helpers/constants/design-system';
import { Color, SEVERITIES } from '../../../helpers/constants/design-system';
import { Icon, ICON_NAMES } from '../icon';
import { HelpText } from './help-text';
describe('HelpText', () => {
it('should render with text inside the HelpText', () => {
const { getByText, container } = render(<HelpText>help text</HelpText>);
const { getByText } = render(<HelpText>help text</HelpText>);
expect(getByText('help text')).toBeDefined();
expect(getByText('help text')).toHaveClass('mm-help-text');
});
it('should match snapshot', () => {
const { container } = render(<HelpText>help text</HelpText>);
expect(container).toMatchSnapshot();
});
it('should render with and additional className', () => {
@ -29,22 +32,50 @@ describe('HelpText', () => {
expect(getByText('help text')).toBeDefined();
expect(getByTestId('icon')).toBeDefined();
});
it('should render with error state', () => {
const { getByText } = render(<HelpText error>error</HelpText>);
it('should render with severities', () => {
const { getByText } = render(
<>
<HelpText severity={SEVERITIES.DANGER}>error</HelpText>
<HelpText severity={SEVERITIES.SUCCESS}>success</HelpText>
<HelpText severity={SEVERITIES.WARNING}>warning</HelpText>
<HelpText severity={SEVERITIES.INFO}>info</HelpText>
</>,
);
expect(getByText('error')).toHaveClass('mm-text--color-error-default');
expect(getByText('success')).toHaveClass('mm-text--color-success-default');
expect(getByText('warning')).toHaveClass('mm-text--color-warning-default');
expect(getByText('info')).toHaveClass('mm-text--color-info-default');
});
it('should render with different colors', () => {
const { getByText } = render(
<>
<HelpText>default</HelpText>
<HelpText color={Color.warningDefault}>warning</HelpText>
<HelpText color={Color.successDefault}>success</HelpText>
<HelpText color={Color.infoDefault}>info</HelpText>
<HelpText color={Color.textDefault}>text default</HelpText>
<HelpText color={Color.textAlternative}>text alternative</HelpText>
<HelpText color={Color.textMuted}>text muted</HelpText>
</>,
);
expect(getByText('default')).toHaveClass('mm-text--color-text-default');
expect(getByText('warning')).toHaveClass('mm-text--color-warning-default');
expect(getByText('success')).toHaveClass('mm-text--color-success-default');
expect(getByText('info')).toHaveClass('mm-text--color-info-default');
expect(getByText('text default')).toHaveClass(
'mm-text--color-text-default',
);
expect(getByText('text alternative')).toHaveClass(
'mm-text--color-text-alternative',
);
expect(getByText('text muted')).toHaveClass('mm-text--color-text-muted');
});
it('should render with a different html element if children is an object', () => {
const { getByText, getByTestId } = render(
<>
<HelpText>help text as p</HelpText>
<HelpText data-testid="help-text-div">
<span>help text as div</span> <Icon name={ICON_NAMES.WARNING} />
</HelpText>
</>,
);
expect(getByText('help text as p')).toBeDefined();
expect(getByText('help text as p').tagName).toBe('P');
expect(getByText('help text as div')).toBeDefined();
expect(getByTestId('help-text-div').tagName).toBe('DIV');
});
});

View File

@ -138,7 +138,7 @@ const RevealSeedPage = () => {
error={error}
width={BLOCK_SIZES.FULL}
/>
{error && <HelpText error>{error}</HelpText>}
{error && <HelpText severity={SEVERITIES.DANGER}>{error}</HelpText>}
</form>
);
};