Skip to content

Commit d3a1d91

Browse files
feat(card): create CardWithFile and CardWithHorizontal high-level components
1 parent 0ca8b8d commit d3a1d91

File tree

11 files changed

+2220
-1089
lines changed

11 files changed

+2220
-1089
lines changed

packages/clay-card/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@
2626
"react"
2727
],
2828
"dependencies": {
29+
"@clayui/drop-down": "^3.0.0-milestone.1",
30+
"@clayui/form": "^3.0.0-milestone.1",
31+
"@clayui/icon": "^3.0.0-milestone.1",
32+
"@clayui/label": "^3.0.0-milestone.1",
33+
"@clayui/sticker": "^3.0.0-milestone.1",
2934
"classnames": "^2.2.6"
3035
},
3136
"devDependencies": {
Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
/**
2+
* © 2019 Liferay, Inc. <https://liferay.com>
3+
*
4+
* SPDX-License-Identifier: BSD-3-Clause
5+
*/
6+
7+
import classNames from 'classnames';
8+
import ClayCard from './Card';
9+
import ClayForm from '@clayui/form';
10+
import ClayIcon from '@clayui/icon';
11+
import ClayLabel from '@clayui/label';
12+
import ClaySticker from '@clayui/sticker';
13+
import React, {ImgHTMLAttributes} from 'react';
14+
import {ClayDropDownWithBasicItems} from '@clayui/drop-down';
15+
16+
interface IProps {
17+
/**
18+
* List of actions in the dropdown menu
19+
*/
20+
actions?: React.ComponentProps<typeof ClayDropDownWithBasicItems>['items'];
21+
22+
/**
23+
* Description of the file
24+
*/
25+
description?: React.ReactText;
26+
27+
/**
28+
* Flag to indicate if `aspect-ratio-item-flush` class should be
29+
* applied to the image.
30+
*/
31+
flushHorizontal?: boolean;
32+
33+
/**
34+
* Flag to indicate if `aspect-ratio-item-vertical-flush` class should be
35+
* applied to the image.
36+
*/
37+
flushVertical?: boolean;
38+
39+
/**
40+
* Path or URL to file
41+
*/
42+
href?: string;
43+
44+
/**
45+
* Object of props for `<img />` or string path to image
46+
*/
47+
imgProps?: React.ImgHTMLAttributes<HTMLImageElement> | string;
48+
49+
/**
50+
* List of labels that are applied to the file
51+
*/
52+
labels?: Array<
53+
React.ComponentProps<typeof ClayLabel> & {value: React.ReactText}
54+
>;
55+
56+
/**
57+
* Callback for when item is selected
58+
*/
59+
onSelectChange?: (val: boolean) => void;
60+
61+
/**
62+
* Flag to indicate if card is selected
63+
*/
64+
selected?: boolean;
65+
66+
/**
67+
* Path to clay icon spritemap
68+
*/
69+
spritemap: string;
70+
71+
/**
72+
* Values used in displaying bottom-left icon
73+
*/
74+
stickerProps?: {
75+
content: React.ReactNode;
76+
displayType: React.ComponentProps<typeof ClaySticker>['displayType'];
77+
};
78+
79+
/**
80+
* Name of icon
81+
*/
82+
symbol?: string;
83+
84+
/**
85+
* Name of the file
86+
*/
87+
title: string;
88+
}
89+
90+
export const ClayCardWithFile: React.FunctionComponent<IProps> = ({
91+
actions,
92+
description,
93+
flushHorizontal,
94+
flushVertical,
95+
href,
96+
imgProps,
97+
labels,
98+
onSelectChange,
99+
selected = false,
100+
spritemap,
101+
stickerProps,
102+
symbol = 'documents-and-media',
103+
title,
104+
}) => {
105+
const headerContent = (
106+
<ClayCard.AspectRatio className="card-item-first">
107+
{!imgProps && (
108+
<div className="aspect-ratio-item aspect-ratio-item-center-middle aspect-ratio-item-fluid card-type-asset-icon">
109+
<ClayIcon spritemap={spritemap} symbol={symbol} />
110+
</div>
111+
)}
112+
113+
{imgProps && (
114+
<img
115+
className={classNames(
116+
'aspect-ratio-item aspect-ratio-item-center-middle aspect-ratio-item-fluid',
117+
typeof imgProps !== 'string' && imgProps.className,
118+
{
119+
['aspect-ratio-item-flush']: flushHorizontal,
120+
['aspect-ratio-item-vertical-flush']: flushVertical,
121+
}
122+
)}
123+
{...(typeof imgProps === 'string'
124+
? {src: imgProps}
125+
: imgProps)}
126+
/>
127+
)}
128+
129+
<ClaySticker
130+
displayType={
131+
stickerProps ? stickerProps.displayType : 'primary'
132+
}
133+
position="bottom-left"
134+
>
135+
{stickerProps ? (
136+
stickerProps.content
137+
) : (
138+
<ClayIcon spritemap={spritemap} symbol="document-text" />
139+
)}
140+
</ClaySticker>
141+
</ClayCard.AspectRatio>
142+
);
143+
144+
return (
145+
<ClayCard
146+
displayType={imgProps ? 'image' : 'file'}
147+
selectable={!!onSelectChange}
148+
>
149+
{onSelectChange && (
150+
<ClayForm.Checkbox
151+
checked={selected}
152+
disabled={false}
153+
indeterminate={false}
154+
onChange={() => onSelectChange(!selected)}
155+
>
156+
{headerContent}
157+
</ClayForm.Checkbox>
158+
)}
159+
160+
{!onSelectChange && headerContent}
161+
162+
<ClayCard.Body>
163+
<div className="autofit-col autofit-col-expand">
164+
<ClayCard.Description displayType="title" href={href}>
165+
{title}
166+
</ClayCard.Description>
167+
168+
<ClayCard.Description displayType="subtitle">
169+
{description}
170+
</ClayCard.Description>
171+
172+
{labels && (
173+
<ClayCard.Caption>
174+
{labels.map(({value, ...others}, i: number) => (
175+
<ClayLabel {...others} key={i}>
176+
{value}
177+
</ClayLabel>
178+
))}
179+
</ClayCard.Caption>
180+
)}
181+
</div>
182+
183+
{actions && (
184+
<div className="autofit-col">
185+
<ClayDropDownWithBasicItems
186+
items={actions}
187+
spritemap={spritemap}
188+
trigger={
189+
<button className="component-action">
190+
<ClayIcon
191+
spritemap={spritemap}
192+
symbol="ellipsis-v"
193+
/>
194+
</button>
195+
}
196+
/>
197+
</div>
198+
)}
199+
</ClayCard.Body>
200+
</ClayCard>
201+
);
202+
};
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
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 ClayForm from '@clayui/form';
9+
import ClayIcon from '@clayui/icon';
10+
import ClaySticker from '@clayui/sticker';
11+
import React from 'react';
12+
import {ClayDropDownWithBasicItems} from '@clayui/drop-down';
13+
14+
interface IProps {
15+
actions?: React.ComponentProps<typeof ClayDropDownWithBasicItems>['items'];
16+
/**
17+
* Path or URL to item
18+
*/
19+
href?: string;
20+
21+
/**
22+
* Callback for when item is selected
23+
*/
24+
onSelectChange?: (val: boolean) => void;
25+
26+
/**
27+
* Flag to indicate if card is selected
28+
*/
29+
selected?: boolean;
30+
31+
/**
32+
* Path to clay icon spritemap
33+
*/
34+
spritemap: string;
35+
36+
/**
37+
* Name of icon symbol
38+
*/
39+
symbol?: string;
40+
41+
/**
42+
* Name of the item
43+
*/
44+
title: string;
45+
}
46+
47+
export const ClayCardWithHorizontal: React.FunctionComponent<IProps> = ({
48+
actions,
49+
href,
50+
onSelectChange,
51+
selected = false,
52+
spritemap,
53+
symbol = 'folder',
54+
title,
55+
}) => {
56+
const content = (
57+
<ClayCard.Body>
58+
<div className="autofit-col">
59+
<ClaySticker inline>
60+
<ClayIcon spritemap={spritemap} symbol={symbol} />
61+
</ClaySticker>
62+
</div>
63+
64+
<div className="autofit-col autofit-col-expand autofit-col-gutters">
65+
<ClayCard.Description displayType="title" href={href}>
66+
{title}
67+
</ClayCard.Description>
68+
</div>
69+
70+
{actions && (
71+
<div className="autofit-col">
72+
<ClayDropDownWithBasicItems
73+
items={actions}
74+
spritemap={spritemap}
75+
trigger={
76+
<button className="component-action">
77+
<ClayIcon
78+
spritemap={spritemap}
79+
symbol="ellipsis-v"
80+
/>
81+
</button>
82+
}
83+
/>
84+
</div>
85+
)}
86+
</ClayCard.Body>
87+
);
88+
89+
return (
90+
<ClayCard horizontal selectable={!!onSelectChange}>
91+
{onSelectChange && (
92+
<ClayForm.Checkbox
93+
checked={selected}
94+
disabled={false}
95+
indeterminate={false}
96+
onChange={() => onSelectChange(!selected)}
97+
>
98+
{content}
99+
</ClayForm.Checkbox>
100+
)}
101+
102+
{!onSelectChange && content}
103+
</ClayCard>
104+
);
105+
};

packages/clay-card/src/CardWithNavigation.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ interface IProps {
1515
*/
1616
description?: React.ReactText;
1717

18+
/**
19+
* Path or url for click through
20+
*/
21+
href?: string;
22+
1823
/**
1924
* Flag to indicate if card should be the `horizontal` variant
2025
*/
@@ -25,11 +30,6 @@ interface IProps {
2530
*/
2631
horizontalSymbol?: string;
2732

28-
/**
29-
* Path or url for click through
30-
*/
31-
href?: string;
32-
3333
/**
3434
* Callback for when card is clicked on
3535
*/

0 commit comments

Comments
 (0)