diff --git a/ui/components/component-library/help-text/README.mdx b/ui/components/component-library/help-text/README.mdx new file mode 100644 index 000000000000..b7dcf5b10f35 --- /dev/null +++ b/ui/components/component-library/help-text/README.mdx @@ -0,0 +1,84 @@ +import { Story, Canvas, ArgsTable } from '@storybook/addon-docs'; + +import { HelpText } from './help-text'; + +# HelpText + +The `HelpText` is intended to be used as the help or error text under a form element + + + + + +## Props + +The `HelpText` accepts all props below as well as all [Text](/docs/ui-components-component-library-text-text-stories-js--default-story#props) and [Box](/docs/ui-components-ui-box-box-stories-js--default-story#props) component props. + + + +### Children + +The `children` of the `HelpText` can be plain text or react nodes. + + + + + +```jsx +import { SIZES, COLORS } from '../../../helpers/constants/design-system'; +import { Icon, ICON_NAMES } from '../../ui/component-library/icon'; +import { HelpText } from '../../ui/component-library/help-text'; + +Plain text + + Text and icon + + +``` + +### Error + +Use the `error` prop to show the `HelpText` in error state. + + + + + +```jsx +import { HelpText } from '../../ui/component-library/help-text'; + +This HelpText in error state; +``` + +### Color + +It may be useful to change the color of the `HelpText`. Use the `color` prop and the `COLORS` object to change the color of the `HelpText`. Defaults to `COLORS.TEXT_DEFAULT`. + + + + + +```jsx +import { COLORS } from '../../../helpers/constants/design-system'; +import { HelpText } from '../../ui/component-library/help-text'; + + + + The HelpText default color is COLORS.TEXT_DEFAULT + + + This HelpText color is COLORS.INFO_DEFAULT + + + This HelpText color is COLORS.WARNING_DEFAULT + + + This HelpText color is COLORS.SUCCESS_DEFAULT + +; +``` diff --git a/ui/components/component-library/help-text/help-text.js b/ui/components/component-library/help-text/help-text.js new file mode 100644 index 000000000000..c3cc34e5b992 --- /dev/null +++ b/ui/components/component-library/help-text/help-text.js @@ -0,0 +1,54 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; + +import { + COLORS, + TEXT, + TEXT_COLORS, +} from '../../../helpers/constants/design-system'; + +import { Text } from '../text'; + +export const HelpText = ({ + error, + color = COLORS.TEXT_DEFAULT, + className, + children, + ...props +}) => ( + + {children} + +); + +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 COLORS.TEXT_DEFAULT + */ + color: PropTypes.oneOf(Object.values[TEXT_COLORS]), + /** + * The content of the help-text + */ + children: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), + /** + * Additional classNames to be added to the HelpText component + */ + className: PropTypes.string, + /** + * HelpText also accepts all Text and Box props + */ + ...Text.propTypes, +}; diff --git a/ui/components/component-library/help-text/help-text.stories.js b/ui/components/component-library/help-text/help-text.stories.js new file mode 100644 index 000000000000..07853b56c973 --- /dev/null +++ b/ui/components/component-library/help-text/help-text.stories.js @@ -0,0 +1,88 @@ +import React from 'react'; +import { + DISPLAY, + FLEX_DIRECTION, + COLORS, + TEXT_COLORS, + SIZES, +} from '../../../helpers/constants/design-system'; + +import Box from '../../ui/box'; +import { Icon, ICON_NAMES } from '../icon'; + +import { HelpText } from './help-text'; + +import README from './README.mdx'; + +export default { + title: 'Components/ComponentLibrary/HelpText', + id: __filename, + component: HelpText, + parameters: { + docs: { + page: README, + }, + }, + argTypes: { + children: { + control: 'text', + }, + className: { + control: 'text', + }, + error: { + control: 'boolean', + }, + color: { + control: 'select', + options: Object.values(TEXT_COLORS), + }, + }, + args: { + children: 'Help text', + }, +}; + +const Template = (args) => ; + +export const DefaultStory = Template.bind({}); +DefaultStory.storyName = 'Default'; + +export const Children = (args) => ( + + Plain text + + Text and icon + + + +); + +export const ErrorStory = (args) => ( + + This HelpText in error state + +); +ErrorStory.storyName = 'Error'; + +export const Color = (args) => ( + + + This HelpText default color is COLORS.TEXT_DEFAULT + + + This HelpText color is COLORS.INFO_DEFAULT + + + This HelpText color is COLORS.WARNING_DEFAULT + + + This HelpText color is COLORS.SUCCESS_DEFAULT + + +); diff --git a/ui/components/component-library/help-text/help-text.test.js b/ui/components/component-library/help-text/help-text.test.js new file mode 100644 index 000000000000..9391ed0cbdbd --- /dev/null +++ b/ui/components/component-library/help-text/help-text.test.js @@ -0,0 +1,52 @@ +/* eslint-disable jest/require-top-level-describe */ +import { render } from '@testing-library/react'; +import React from 'react'; +import { COLORS } 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 } = render(help text); + expect(getByText('help text')).toBeDefined(); + }); + it('should render with react nodes inside the HelpText', () => { + const { getByText, getByTestId } = render( + + help text + , + ); + expect(getByText('help text')).toBeDefined(); + expect(getByTestId('icon')).toBeDefined(); + }); + it('should render with and additional className', () => { + const { getByText } = render( + help text, + ); + expect(getByText('help text')).toBeDefined(); + expect(getByText('help text')).toHaveClass('test-class'); + }); + it('should render with error state', () => { + const { getByText } = render( + <> + error + , + ); + expect(getByText('error')).toHaveClass('text--color-error-default'); + }); + it('should render with different colors', () => { + const { getByText } = render( + <> + default + warning + success + info + , + ); + expect(getByText('default')).toHaveClass('text--color-text-default'); + expect(getByText('warning')).toHaveClass('text--color-warning-default'); + expect(getByText('success')).toHaveClass('text--color-success-default'); + expect(getByText('info')).toHaveClass('text--color-info-default'); + }); +}); diff --git a/ui/components/component-library/help-text/index.js b/ui/components/component-library/help-text/index.js new file mode 100644 index 000000000000..cbc88e159608 --- /dev/null +++ b/ui/components/component-library/help-text/index.js @@ -0,0 +1 @@ +export { HelpText } from './help-text';