Skip to content

Commit 4a1ead3

Browse files
feat(card): create CardWithFile high-level component
1 parent e359f49 commit 4a1ead3

File tree

6 files changed

+501
-9
lines changed

6 files changed

+501
-9
lines changed
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
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 ClayLabel from '@clayui/label';
11+
import ClaySticker from '@clayui/sticker';
12+
import React from 'react';
13+
import {ClayDropDownWithBasicItems} from '@clayui/drop-down';
14+
15+
interface IProps {
16+
/**
17+
* List of actions in the dropdown menu
18+
*/
19+
actions?: React.ComponentProps<typeof ClayDropDownWithBasicItems>['items'];
20+
21+
/**
22+
* Description of the file
23+
*/
24+
description?: React.ReactText;
25+
26+
/**
27+
* Path or URL to file
28+
*/
29+
href?: string;
30+
31+
/**
32+
* List of labels that are applied to the file
33+
*/
34+
labels?: Array<
35+
React.ComponentProps<typeof ClayLabel> & {value: React.ReactText}
36+
>;
37+
38+
/**
39+
* Name of the file
40+
*/
41+
name: string;
42+
43+
/**
44+
* Callback for when item is selected
45+
*/
46+
onSelectChange?: (val: boolean) => void;
47+
48+
/**
49+
* Flag to indicate if card is selected
50+
*/
51+
selected?: boolean;
52+
53+
/**
54+
* Path to clay icon spritemap
55+
*/
56+
spritemap: string;
57+
58+
/**
59+
* Values used in displaying bottom-left icon
60+
*/
61+
iconProps?: {
62+
content: React.ReactNode;
63+
displayType: React.ComponentProps<typeof ClaySticker>['displayType'];
64+
};
65+
}
66+
67+
export const ClayCardWithFile: React.FunctionComponent<IProps> = ({
68+
actions,
69+
description,
70+
href,
71+
iconProps,
72+
labels,
73+
name,
74+
onSelectChange,
75+
selected = false,
76+
spritemap,
77+
}) => {
78+
const headerContent = (
79+
<ClayCard.AspectRatio className="card-item-first">
80+
<div className="aspect-ratio-item aspect-ratio-item-center-middle aspect-ratio-item-fluid card-type-asset-icon">
81+
<ClayIcon spritemap={spritemap} symbol="documents-and-media" />
82+
</div>
83+
84+
<ClaySticker
85+
displayType={iconProps ? iconProps.displayType : 'primary'}
86+
position="bottom-left"
87+
>
88+
{iconProps ? (
89+
iconProps.content
90+
) : (
91+
<ClayIcon spritemap={spritemap} symbol="document-text" />
92+
)}
93+
</ClaySticker>
94+
</ClayCard.AspectRatio>
95+
);
96+
97+
return (
98+
<ClayCard displayType="file" selectable={!!onSelectChange}>
99+
{onSelectChange && (
100+
<ClayForm.Checkbox
101+
checked={selected}
102+
disabled={false}
103+
indeterminate={false}
104+
onChange={() => onSelectChange(!selected)}
105+
>
106+
{headerContent}
107+
</ClayForm.Checkbox>
108+
)}
109+
110+
{!onSelectChange && headerContent}
111+
112+
<ClayCard.Body>
113+
<div className="autofit-col autofit-col-expand">
114+
<ClayCard.Description displayType="title" href={href}>
115+
{name}
116+
</ClayCard.Description>
117+
118+
<ClayCard.Description displayType="subtitle">
119+
{description}
120+
</ClayCard.Description>
121+
122+
{labels && (
123+
<ClayCard.Caption>
124+
{labels.map(({value, ...others}, i: number) => (
125+
<ClayLabel {...others} key={i}>
126+
{value}
127+
</ClayLabel>
128+
))}
129+
</ClayCard.Caption>
130+
)}
131+
</div>
132+
133+
{actions && (
134+
<div className="autofit-col">
135+
<ClayDropDownWithBasicItems
136+
items={actions}
137+
spritemap={spritemap}
138+
trigger={
139+
<button className="component-action">
140+
<ClayIcon
141+
spritemap={spritemap}
142+
symbol="ellipsis-v"
143+
/>
144+
</button>
145+
}
146+
/>
147+
</div>
148+
)}
149+
</ClayCard.Body>
150+
</ClayCard>
151+
);
152+
};

packages/clay-card/src/CardWithUser.tsx

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ interface IProps {
2525
/**
2626
* List of labels that are applied to the user
2727
*/
28-
labels: Array<
28+
labels?: Array<
2929
React.ComponentProps<typeof ClayLabel> & {value: React.ReactText}
3030
>;
3131

@@ -117,13 +117,15 @@ export const ClayCardWithUser: React.FunctionComponent<IProps> = ({
117117
<ClayCard.Description displayType="subtitle">
118118
{description}
119119
</ClayCard.Description>
120-
<ClayCard.Caption>
121-
{labels.map(({value, ...others}, i: number) => (
122-
<ClayLabel {...others} key={i}>
123-
{value}
124-
</ClayLabel>
125-
))}
126-
</ClayCard.Caption>
120+
{labels && (
121+
<ClayCard.Caption>
122+
{labels.map(({value, ...others}, i: number) => (
123+
<ClayLabel {...others} key={i}>
124+
{value}
125+
</ClayLabel>
126+
))}
127+
</ClayCard.Caption>
128+
)}
127129
</div>
128130
</ClayCard.Body>
129131
</ClayCard>

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

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1331,6 +1331,198 @@ exports[`ClayCard renders a group of ClayCards 1`] = `
13311331
</div>
13321332
`;
13331333

1334+
exports[`ClayCardWithFile renders as not selectable 1`] = `
1335+
<div>
1336+
<div
1337+
class="card card-type-asset file-card"
1338+
>
1339+
<div
1340+
class="card-item-first aspect-ratio"
1341+
>
1342+
<div
1343+
class="aspect-ratio-item aspect-ratio-item-center-middle aspect-ratio-item-fluid card-type-asset-icon"
1344+
>
1345+
<svg
1346+
class="lexicon-icon lexicon-icon-documents-and-media"
1347+
role="presentation"
1348+
>
1349+
<use
1350+
xlink:href="/some/spritemap#documents-and-media"
1351+
/>
1352+
</svg>
1353+
</div>
1354+
<span
1355+
class="sticker sticker-rounded sticker-primary sticker-bottom-left"
1356+
>
1357+
<span
1358+
class="sticker-overlay"
1359+
>
1360+
<svg
1361+
class="lexicon-icon lexicon-icon-document-text"
1362+
role="presentation"
1363+
>
1364+
<use
1365+
xlink:href="/some/spritemap#document-text"
1366+
/>
1367+
</svg>
1368+
</span>
1369+
</span>
1370+
</div>
1371+
<div
1372+
class="card-body"
1373+
>
1374+
<div
1375+
class="card-row"
1376+
>
1377+
<div
1378+
class="autofit-col autofit-col-expand"
1379+
>
1380+
<h3
1381+
class="card-title"
1382+
title="Very Large File"
1383+
>
1384+
<span
1385+
class="text-truncate-inline"
1386+
>
1387+
<a
1388+
class="text-truncate"
1389+
href="#"
1390+
>
1391+
Very Large File
1392+
</a>
1393+
</span>
1394+
</h3>
1395+
<span
1396+
class="card-subtitle"
1397+
title="A cool description"
1398+
>
1399+
<span
1400+
class="text-truncate-inline"
1401+
>
1402+
<span
1403+
class="text-truncate"
1404+
>
1405+
A cool description
1406+
</span>
1407+
</span>
1408+
</span>
1409+
<div
1410+
class="card-detail"
1411+
>
1412+
<span
1413+
class="label label-success"
1414+
>
1415+
<span
1416+
class="label-item label-item-expand"
1417+
>
1418+
Awesome
1419+
</span>
1420+
</span>
1421+
</div>
1422+
</div>
1423+
</div>
1424+
</div>
1425+
</div>
1426+
</div>
1427+
`;
1428+
1429+
exports[`ClayCardWithFile renders as selectable 1`] = `
1430+
<div>
1431+
<div
1432+
class="card-type-asset file-card form-check form-check-card form-check-top-left"
1433+
>
1434+
<div
1435+
class="card"
1436+
>
1437+
<div
1438+
class="custom-control custom-checkbox"
1439+
>
1440+
<label>
1441+
<input
1442+
class="custom-control-input"
1443+
type="checkbox"
1444+
value="false"
1445+
/>
1446+
<span
1447+
class="custom-control-label"
1448+
/>
1449+
<div
1450+
class="card-item-first aspect-ratio"
1451+
>
1452+
<div
1453+
class="aspect-ratio-item aspect-ratio-item-center-middle aspect-ratio-item-fluid card-type-asset-icon"
1454+
>
1455+
<svg
1456+
class="lexicon-icon lexicon-icon-documents-and-media"
1457+
role="presentation"
1458+
>
1459+
<use
1460+
xlink:href="/path/to/some/resource.svg#documents-and-media"
1461+
/>
1462+
</svg>
1463+
</div>
1464+
<span
1465+
class="sticker sticker-rounded sticker-primary sticker-bottom-left"
1466+
>
1467+
<span
1468+
class="sticker-overlay"
1469+
>
1470+
<svg
1471+
class="lexicon-icon lexicon-icon-document-text"
1472+
role="presentation"
1473+
>
1474+
<use
1475+
xlink:href="/path/to/some/resource.svg#document-text"
1476+
/>
1477+
</svg>
1478+
</span>
1479+
</span>
1480+
</div>
1481+
</label>
1482+
</div>
1483+
<div
1484+
class="card-body"
1485+
>
1486+
<div
1487+
class="card-row"
1488+
>
1489+
<div
1490+
class="autofit-col autofit-col-expand"
1491+
>
1492+
<h3
1493+
class="card-title"
1494+
title="Foo Bar"
1495+
>
1496+
<span
1497+
class="text-truncate-inline"
1498+
>
1499+
<a
1500+
class="text-truncate"
1501+
href="#"
1502+
>
1503+
Foo Bar
1504+
</a>
1505+
</span>
1506+
</h3>
1507+
<span
1508+
class="card-subtitle"
1509+
>
1510+
<span
1511+
class="text-truncate-inline"
1512+
>
1513+
<span
1514+
class="text-truncate"
1515+
/>
1516+
</span>
1517+
</span>
1518+
</div>
1519+
</div>
1520+
</div>
1521+
</div>
1522+
</div>
1523+
</div>
1524+
`;
1525+
13341526
exports[`ClayCardWithFolder renders as not selectable 1`] = `
13351527
<div>
13361528
<div

0 commit comments

Comments
 (0)