From bd9d97600646aa231c394b415727f9d49c98350d Mon Sep 17 00:00:00 2001 From: George Marshall Date: Mon, 15 Nov 2021 10:13:54 -0800 Subject: [PATCH] Updating Card ui component and adding story (#12666) --- ui/components/ui/card/README.mdx | 42 +++++ ui/components/ui/card/card.component.js | 23 --- ui/components/ui/card/card.component.test.js | 21 --- ui/components/ui/card/card.js | 60 +++++++ ui/components/ui/card/card.stories.js | 169 +++++++++++++++++++ ui/components/ui/card/card.test.js | 11 ++ ui/components/ui/card/index.js | 2 +- ui/components/ui/card/index.scss | 11 -- ui/components/ui/ui-components.scss | 1 - 9 files changed, 283 insertions(+), 57 deletions(-) create mode 100644 ui/components/ui/card/README.mdx delete mode 100644 ui/components/ui/card/card.component.js delete mode 100644 ui/components/ui/card/card.component.test.js create mode 100644 ui/components/ui/card/card.js create mode 100644 ui/components/ui/card/card.stories.js create mode 100644 ui/components/ui/card/card.test.js delete mode 100644 ui/components/ui/card/index.scss diff --git a/ui/components/ui/card/README.mdx b/ui/components/ui/card/README.mdx new file mode 100644 index 000000000..88110ef1d --- /dev/null +++ b/ui/components/ui/card/README.mdx @@ -0,0 +1,42 @@ +import { Story, Canvas, ArgsTable } from '@storybook/addon-docs'; + +import Card from '.'; + +# Card + +Cards are used to group related content or actions together. + + + + + +## Component API + +The `Card` component extends the `Box` component. See the `Box` component for an extended list of props. + + + +## Usage + +The following describes the props and example usage for this component. + +### Padding, Border and Background Color + +The Card component has a set of default props that should meet most card use cases. There is a strong recommendation to not overwrite these to ensure our cards stay consistent across the app. + +That being said all props can be overwritten if necessary. + +```jsx +import { COLORS } from '../../../helpers/constants/design-system'; + +// To remove the border + +// All border related props of the Box component will work + +// To remove or change padding + +// All padding related props of the Box component will work + +// To change the background color + +``` diff --git a/ui/components/ui/card/card.component.js b/ui/components/ui/card/card.component.js deleted file mode 100644 index d75506b9a..000000000 --- a/ui/components/ui/card/card.component.js +++ /dev/null @@ -1,23 +0,0 @@ -import React, { PureComponent } from 'react'; -import PropTypes from 'prop-types'; -import classnames from 'classnames'; - -export default class Card extends PureComponent { - static propTypes = { - className: PropTypes.string, - overrideClassName: PropTypes.bool, - title: PropTypes.string, - children: PropTypes.node, - }; - - render() { - const { className, overrideClassName, title } = this.props; - - return ( -
-
{title}
- {this.props.children} -
- ); - } -} diff --git a/ui/components/ui/card/card.component.test.js b/ui/components/ui/card/card.component.test.js deleted file mode 100644 index 83205ec9c..000000000 --- a/ui/components/ui/card/card.component.test.js +++ /dev/null @@ -1,21 +0,0 @@ -import React from 'react'; -import { shallow } from 'enzyme'; -import Card from './card.component'; - -describe('Card Component', () => { - it('should render a card with a title and child element', () => { - const wrapper = shallow( - -
Child
-
, - ); - - expect(wrapper.hasClass('card-test-class')).toStrictEqual(true); - const title = wrapper.find('.card__title'); - expect(title).toHaveLength(1); - expect(title.text()).toStrictEqual('Test'); - const child = wrapper.find('.child-test-class'); - expect(child).toHaveLength(1); - expect(child.text()).toStrictEqual('Child'); - }); -}); diff --git a/ui/components/ui/card/card.js b/ui/components/ui/card/card.js new file mode 100644 index 000000000..fc1beafaf --- /dev/null +++ b/ui/components/ui/card/card.js @@ -0,0 +1,60 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + +import Box from '../box'; +import { + BORDER_STYLE, + COLORS, + SIZES, +} from '../../../helpers/constants/design-system'; + +const Card = ({ + border = true, + padding = 4, + backgroundColor = COLORS.WHITE, + children, + ...props +}) => { + const defaultBorderProps = { + borderColor: border && COLORS.UI2, + borderRadius: border && SIZES.MD, + borderStyle: border && BORDER_STYLE.SOLID, + }; + + return ( + + {children} + + ); +}; + +Card.propTypes = { + /** + * Whether the Card has a border or not. + * Defaults to true + */ + border: PropTypes.bool, + /** + * Padding of the Card component accepts number or an array of 2 numbers. + * Defaults to 4 (16px) + */ + padding: Box.propTypes.padding, + /** + * The background color of the card + * Defaults to COLORS.WHITE + */ + backgroundColor: Box.propTypes.backgroundColor, + /** + * The Card component accepts all Box component props + */ + ...Box.propTypes, +}; + +export default Card; diff --git a/ui/components/ui/card/card.stories.js b/ui/components/ui/card/card.stories.js new file mode 100644 index 000000000..1dd2075e2 --- /dev/null +++ b/ui/components/ui/card/card.stories.js @@ -0,0 +1,169 @@ +import React from 'react'; +import { + ALIGN_ITEMS, + BLOCK_SIZES, + BORDER_STYLE, + COLORS, + DISPLAY, + JUSTIFY_CONTENT, + TEXT_ALIGN, +} from '../../../helpers/constants/design-system'; + +import README from './README.mdx'; +import Card from '.'; + +const sizeOptions = [undefined, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; + +export default { + title: 'UI/Card', + id: __filename, + component: Card, + parameters: { + docs: { + page: README, + }, + }, + argTypes: { + children: { control: 'text' }, + border: { + control: 'boolean', + }, + borderStyle: { + control: { + type: 'select', + }, + options: Object.values(BORDER_STYLE), + }, + borderWidth: { + control: { + type: 'select', + }, + options: [...sizeOptions], + }, + borderColor: { + control: { + type: 'select', + }, + options: Object.values(COLORS), + }, + backgroundColor: { + control: { + type: 'select', + }, + options: Object.values(COLORS), + }, + width: { + control: { + type: 'select', + }, + options: Object.values(BLOCK_SIZES), + }, + height: { + control: { + type: 'select', + }, + options: Object.values(BLOCK_SIZES), + }, + textAlign: { + control: { + type: 'select', + }, + options: Object.values(TEXT_ALIGN), + }, + margin: { + control: { + type: 'select', + }, + options: [...sizeOptions], + }, + marginTop: { + control: { + type: 'select', + }, + options: [...sizeOptions], + }, + marginRight: { + control: { + type: 'select', + }, + options: [...sizeOptions], + }, + marginBottom: { + control: { + type: 'select', + }, + options: [...sizeOptions], + }, + marginLeft: { + control: { + type: 'select', + }, + options: [...sizeOptions], + }, + padding: { + control: { + type: 'select', + }, + options: [...sizeOptions], + }, + paddingTop: { + control: { + type: 'select', + }, + options: [...sizeOptions], + }, + paddingRight: { + control: { + type: 'select', + }, + options: [...sizeOptions], + }, + paddingBottom: { + control: { + type: 'select', + }, + options: [...sizeOptions], + }, + paddingLeft: { + control: { + type: 'select', + }, + options: [...sizeOptions], + }, + display: { + control: { + type: 'select', + }, + options: Object.values(DISPLAY), + }, + justifyContent: { + control: { + type: 'select', + }, + options: Object.values(JUSTIFY_CONTENT), + }, + alignItems: { + control: { + type: 'select', + }, + options: Object.values(ALIGN_ITEMS), + }, + }, + args: { + children: 'Card children', + }, +}; + +export const DefaultStory = (args) => {args.children}; + +DefaultStory.storyName = 'Default'; + +DefaultStory.args = { + padding: 4, + border: true, + borderWidth: 1, + borderColor: COLORS.UI2, + borderStyle: BORDER_STYLE.SOLID, + backgroundColor: COLORS.WHITE, + display: DISPLAY.BLOCK, +}; diff --git a/ui/components/ui/card/card.test.js b/ui/components/ui/card/card.test.js new file mode 100644 index 000000000..cbfd0db1c --- /dev/null +++ b/ui/components/ui/card/card.test.js @@ -0,0 +1,11 @@ +import * as React from 'react'; +import { render } from '@testing-library/react'; +import Card from '.'; + +describe('Card', () => { + it('should render the Card without crashing', () => { + const { getByText } = render(Card content); + + expect(getByText('Card content')).toBeDefined(); + }); +}); diff --git a/ui/components/ui/card/index.js b/ui/components/ui/card/index.js index 643fad74d..2c9f20524 100644 --- a/ui/components/ui/card/index.js +++ b/ui/components/ui/card/index.js @@ -1 +1 @@ -export { default } from './card.component'; +export { default } from './card'; diff --git a/ui/components/ui/card/index.scss b/ui/components/ui/card/index.scss deleted file mode 100644 index 4fa32e1bc..000000000 --- a/ui/components/ui/card/index.scss +++ /dev/null @@ -1,11 +0,0 @@ -.card { - border-radius: 4px; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08); - padding: 8px; - - &__title { - border-bottom: 1px solid #d8d8d8; - padding-bottom: 4px; - text-transform: capitalize; - } -} diff --git a/ui/components/ui/ui-components.scss b/ui/components/ui/ui-components.scss index 75cddcb90..6200bb21f 100644 --- a/ui/components/ui/ui-components.scss +++ b/ui/components/ui/ui-components.scss @@ -8,7 +8,6 @@ @import 'button-group/index'; @import 'button/buttons'; @import 'callout/callout'; -@import 'card/index'; @import 'check-box/index'; @import 'chip/chip'; @import 'circle-icon/index';