Skip to content

Commit 2968282

Browse files
Merge pull request #2200 from bryceosterhaus/2198
feat(clay-card): create high-level ClayCardWithNavigation component
2 parents 58ce101 + f027b12 commit 2968282

File tree

6 files changed

+225
-77
lines changed

6 files changed

+225
-77
lines changed

packages/clay-card/src/Card.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ import {IContext} from './Context';
1717
type CardDisplayType = 'file' | 'image' | 'user';
1818

1919
export interface ICardProps extends IContext {
20+
/**
21+
* Determines the style of the card
22+
*/
2023
displayType?: CardDisplayType;
2124

2225
/**
@@ -27,7 +30,9 @@ export interface ICardProps extends IContext {
2730

2831
interface IProps
2932
extends ICardProps,
30-
React.BaseHTMLAttributes<HTMLAnchorElement | HTMLDivElement> {}
33+
React.BaseHTMLAttributes<
34+
HTMLAnchorElement | HTMLSpanElement | HTMLDivElement
35+
> {}
3136

3237
const ClayCard: React.FunctionComponent<IProps> & {
3338
AspectRatio: typeof AspectRatio;
@@ -40,7 +45,9 @@ const ClayCard: React.FunctionComponent<IProps> & {
4045
className,
4146
displayType,
4247
horizontal,
48+
href = 'javascript:;',
4349
interactive,
50+
onClick,
4451
selectable = false,
4552
...otherProps
4653
}: IProps) => {
@@ -81,6 +88,9 @@ const ClayCard: React.FunctionComponent<IProps> & {
8188
'template-card-horizontal': horizontal && interactive,
8289
'user-card': isCardType.user,
8390
})}
91+
href={interactive ? href : undefined}
92+
onClick={onClick}
93+
role={onClick ? 'button' : undefined}
8494
>
8595
{(selectable && !horizontal) ||
8696
(selectable && isCardType.image) ||
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/**
2+
* © 2019 Liferay, Inc. <https://liferay.com>
3+
*
4+
* SPDX-License-Identifier: BSD-3-Clause
5+
*/
6+
7+
import ClayCard from './Card';
8+
import ClayIcon from '@clayui/icon';
9+
import ClaySticker from '@clayui/sticker';
10+
import React from 'react';
11+
12+
interface IProps {
13+
/**
14+
* Value displayed that describes the card
15+
*/
16+
description?: React.ReactText;
17+
18+
/**
19+
* Flag to indicate if card should be the `horizontal` variant
20+
*/
21+
horizontal?: boolean;
22+
23+
/**
24+
* Icon to display when card is `horizontal`
25+
*/
26+
horizontalSymbol?: string;
27+
28+
/**
29+
* Path or url for click through
30+
*/
31+
href?: string;
32+
33+
/**
34+
* Callback for when card is clicked on
35+
*/
36+
onClick?: () => void;
37+
38+
/**
39+
* Path to spritemap for icon symbol.
40+
*/
41+
spritemap?: string;
42+
43+
/**
44+
* Value displayed for the card's title
45+
*/
46+
title: React.ReactText;
47+
}
48+
49+
export const ClayCardWithNavigation: React.FunctionComponent<IProps> = ({
50+
children,
51+
description,
52+
horizontal = false,
53+
horizontalSymbol = '',
54+
href,
55+
onClick,
56+
spritemap,
57+
title,
58+
}) => {
59+
return (
60+
<ClayCard
61+
horizontal={horizontal}
62+
href={href}
63+
interactive
64+
onClick={onClick}
65+
tabIndex={0}
66+
>
67+
{!horizontal && (
68+
<ClayCard.AspectRatio>
69+
<span className="aspect-ratio-item aspect-ratio-item-center-middle aspect-ratio-item-flush">
70+
{children}
71+
</span>
72+
</ClayCard.AspectRatio>
73+
)}
74+
75+
<ClayCard.Body>
76+
{!horizontal && (
77+
<>
78+
<ClayCard.Description displayType="title" truncate>
79+
{title}
80+
</ClayCard.Description>
81+
<ClayCard.Description displayType="text" truncate>
82+
{description}
83+
</ClayCard.Description>
84+
</>
85+
)}
86+
87+
{horizontal && (
88+
<>
89+
<span className="autofit-col">
90+
<ClaySticker inline>
91+
<ClayIcon
92+
spritemap={spritemap}
93+
symbol={horizontalSymbol}
94+
/>
95+
</ClaySticker>
96+
</span>
97+
<span className="autofit-col autofit-col-expand">
98+
<span className="autofit-section">
99+
<ClayCard.Description
100+
displayType="title"
101+
truncate
102+
>
103+
{title}
104+
</ClayCard.Description>
105+
</span>
106+
</span>
107+
</>
108+
)}
109+
</ClayCard.Body>
110+
</ClayCard>
111+
);
112+
};

packages/clay-card/src/__tests__/__snapshots__/index.tsx.snap

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,42 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3+
exports[`ClayCard renders ClayCardWithNavigation with image 1`] = `
4+
<div>
5+
<a
6+
class="card card-interactive card-interactive-primary card-type-template template-card"
7+
href="#"
8+
tabindex="0"
9+
>
10+
<span
11+
class="aspect-ratio"
12+
>
13+
<span
14+
class="aspect-ratio-item aspect-ratio-item-center-middle aspect-ratio-item-flush"
15+
>
16+
<img
17+
alt="portlet image"
18+
src="/some/path"
19+
/>
20+
</span>
21+
</span>
22+
<span
23+
class="card-body"
24+
>
25+
<span
26+
class="card-title text-truncate"
27+
>
28+
Layout Page
29+
</span>
30+
<span
31+
class="card-text text-truncate"
32+
>
33+
Pick and choose your layout...
34+
</span>
35+
</span>
36+
</a>
37+
</div>
38+
`;
39+
340
exports[`ClayCard renders ClayCardWithUser as selectable 1`] = `
441
<div>
542
<div
@@ -607,6 +644,7 @@ exports[`ClayCard renders a ClayCard as a template navigation card truncating te
607644
<div>
608645
<a
609646
class="card card-interactive card-interactive-primary card-type-template template-card"
647+
href="javascript:;"
610648
>
611649
<span
612650
class="aspect-ratio"
@@ -711,6 +749,7 @@ exports[`ClayCard renders a ClayCard as template navigation card 1`] = `
711749
<div>
712750
<a
713751
class="card card-interactive card-interactive-primary card-type-template template-card"
752+
href="javascript:;"
714753
>
715754
<span
716755
class="aspect-ratio"
@@ -746,6 +785,7 @@ exports[`ClayCard renders a ClayCard as template navigation card as horizontal c
746785
<div>
747786
<a
748787
class="card card-interactive card-interactive-primary card-type-template template-card-horizontal"
788+
href="javascript:;"
749789
>
750790
<span
751791
class="card-body"
@@ -796,6 +836,7 @@ exports[`ClayCard renders a ClayCard as template navigation card with icon inste
796836
<div>
797837
<a
798838
class="card card-interactive card-interactive-primary card-type-template template-card"
839+
href="javascript:;"
799840
>
800841
<span
801842
class="aspect-ratio"

packages/clay-card/src/__tests__/index.tsx

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* SPDX-License-Identifier: BSD-3-Clause
55
*/
66

7-
import ClayCard, {ClayCardWithUser} from '../index';
7+
import ClayCard, {ClayCardWithNavigation, ClayCardWithUser} from '../index';
88
import ClayForm from '@clayui/form';
99
import ClayIcon from '@clayui/icon';
1010
import ClayLabel from '@clayui/label';
@@ -627,4 +627,38 @@ describe('ClayCard', () => {
627627

628628
expect(container).toMatchSnapshot();
629629
});
630+
631+
it('renders ClayCardWithNavigation with image', () => {
632+
const {container} = render(
633+
<ClayCardWithNavigation
634+
description="Pick and choose your layout..."
635+
href="#"
636+
spritemap="foo/bar"
637+
title="Layout Page"
638+
>
639+
<img alt="portlet image" src="/some/path" />
640+
</ClayCardWithNavigation>
641+
);
642+
643+
expect(container).toMatchSnapshot();
644+
});
645+
646+
it('calls onClick callback', () => {
647+
const onClickFn = jest.fn();
648+
649+
const {container} = render(
650+
<ClayCardWithNavigation
651+
description="Pick and choose your layout..."
652+
onClick={onClickFn}
653+
spritemap="foo/bar"
654+
title="Layout Page"
655+
>
656+
<img alt="portlet image" src="/some/path" />
657+
</ClayCardWithNavigation>
658+
);
659+
660+
fireEvent.click(container.querySelector('img') as HTMLElement, {});
661+
662+
expect(onClickFn).toHaveBeenCalledTimes(1);
663+
});
630664
});

packages/clay-card/src/index.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
*/
66

77
import ClayCard from './Card';
8+
import {ClayCardWithNavigation} from './CardWithNavigation';
89
import {ClayCardWithUser} from './CardWithUser';
910

10-
export {ClayCardWithUser};
11+
export {ClayCardWithNavigation, ClayCardWithUser};
1112

1213
export default ClayCard;

0 commit comments

Comments
 (0)