Skip to content

Commit

Permalink
Merge 78b82e7 into 3ca824a
Browse files Browse the repository at this point in the history
  • Loading branch information
frabbit committed Jul 26, 2019
2 parents 3ca824a + 78b82e7 commit ac6a8bb
Show file tree
Hide file tree
Showing 2 changed files with 182 additions and 79 deletions.
184 changes: 105 additions & 79 deletions src/components/Card/Card.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { PureComponent } from 'react';
import { bool, string, node, oneOfType } from 'prop-types';
import React from 'react';
import { bool, string, node, oneOfType, shape } from 'prop-types';
import classnames from 'classnames';
import { pascalize } from 'humps';
import * as olt from '@lightelligence/styles';
Expand All @@ -9,84 +9,110 @@ import { colorProp } from '../../propTypes';
import { Image } from '../../content/Image';
import { Link } from '../../content/Link';

export class Card extends PureComponent {
static propTypes = {
children: node,
className: string,
title: node,
description: node,
image: oneOfType([node, string]),
action: node,
color: colorProp,
selectable: bool,
disabled: bool,
to: string,
};
export const Card = ({
children,
image,
title,
description,
action,
color,
selectable,
className,
disabled,
to,
contentProps,
actionProps,
headerProps,
...props
}) => {
const Element = selectable && !to ? 'button' : (to && Link) || 'div';

static defaultProps = {
children: null,
className: null,
title: null,
description: null,
image: null,
action: null,
color: undefined,
selectable: false,
disabled: false,
to: '',
};
const { className: contentClassName, ...contentOther } = contentProps;
const { className: actionClassName, ...actionOther } = actionProps;
const { className: headerClassName, ...headerOther } = headerProps;

render() {
const {
children,
image,
title,
description,
action,
color,
selectable,
className,
disabled,
to,
...props
} = this.props;
return (
<Element
to={to || undefined}
normal={to ? true : undefined}
className={classnames(
olt.Card,
color && olt[`Card${pascalize(color)}`],
selectable && olt.ButtonSelectable,
className,
disabled && olt.isDisabled,
)}
{...props}
>
{image &&
(typeof image === 'string' ? (
<Image
className={classnames(olt.Image, olt.CardImage)}
src={image}
fluid
/>
) : (
image
))}
{(title || description || action) && (
<div
className={classnames(olt.CardHeader, headerClassName)}
{...headerOther}
>
{title && <div className={olt.CardTitle}>{title}</div>}
{description && (
<div className={olt.CardDescription}>{description}</div>
)}
{action && (
<div
className={classnames(olt.CardAction, actionClassName)}
{...actionOther}
>
{action}
</div>
)}
</div>
)}
{children && (
<div
className={classnames(olt.CardContent, contentClassName)}
{...contentOther}
>
{children}
</div>
)}
</Element>
);
};

const Element = selectable && !to ? 'button' : (to && Link) || 'div';
Card.propTypes = {
children: node,
className: string,
title: node,
description: node,
image: oneOfType([node, string]),
action: node,
color: colorProp,
selectable: bool,
disabled: bool,
contentProps: shape({}),
actionProps: shape({}),
headerProps: shape({}),
to: string,
};

return (
<Element
to={to || undefined}
normal={to ? true : undefined}
className={classnames(
olt.Card,
color && olt[`Card${pascalize(color)}`],
selectable && olt.ButtonSelectable,
className,
disabled && olt.isDisabled,
)}
{...props}
>
{image &&
(typeof image === 'string' ? (
<Image
className={classnames(olt.Image, olt.CardImage)}
src={image}
fluid
/>
) : (
image
))}
{(title || description || action) && (
<div className={olt.CardHeader}>
{title && <div className={olt.CardTitle}>{title}</div>}
{description && (
<div className={olt.CardDescription}>{description}</div>
)}
{action && <div className={olt.CardAction}>{action}</div>}
</div>
)}
{children && <div className={olt.CardContent}>{children}</div>}
</Element>
);
}
}
Card.defaultProps = {
children: null,
className: null,
title: null,
description: null,
image: null,
action: null,
color: undefined,
selectable: false,
disabled: false,
contentProps: {},
actionProps: {},
headerProps: {},
to: '',
};
77 changes: 77 additions & 0 deletions src/components/Card/Card.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import React from 'react';
import { render } from 'react-testing-library';

import { oltStyles } from '../..';

import { Card } from './Card';

const renderCard = (props) => {
return render(<Card {...props} />);
};

describe('Card', () => {
test('content is rendered', () => {
const { getByText } = renderCard({
children: 'Content',
});
getByText('Content');
});

test('has the corresponding Card class from styles', () => {
const { getByTestId } = renderCard({
children: 'Content',
'data-testid': 'Card',
});
const card = getByTestId('Card');
expect(card.classList.contains(oltStyles.Card)).toBeTruthy();
});

test('has the corresponding Content class from styles', () => {
const { getByTestId } = renderCard({
children: 'ContentText',
contentProps: {
'data-testid': 'Content',
},
});
const card = getByTestId('Content');
expect(card.classList.contains(oltStyles.CardContent)).toBeTruthy();
});

test('has the corresponding Header class from styles', () => {
const { getByTestId } = renderCard({
title: 'TitleText',
headerProps: {
'data-testid': 'Header',
},
});
const card = getByTestId('Header');
expect(card.classList.contains(oltStyles.CardHeader)).toBeTruthy();
});

test('has the corresponding Action class from styles', () => {
const { getByTestId } = renderCard({
action: 'ActionText',
actionProps: {
'data-testid': 'Action',
},
});
const card = getByTestId('Action');
expect(card.classList.contains(oltStyles.CardAction)).toBeTruthy();
});

test('has the corresponding Title class from styles', () => {
const { getByText } = renderCard({
title: 'TitleText',
});
const card = getByText('TitleText');
expect(card.classList.contains(oltStyles.CardTitle)).toBeTruthy();
});

test('has the corresponding Desciption class from styles', () => {
const { getByText } = renderCard({
description: 'DescriptionText',
});
const card = getByText('DescriptionText');
expect(card.classList.contains(oltStyles.CardDescription)).toBeTruthy();
});
});

0 comments on commit ac6a8bb

Please sign in to comment.