Skip to content

Commit 18acda2

Browse files
committed
Create Card List layout component for rendering Cards in grid
1 parent 47be0cb commit 18acda2

File tree

19 files changed

+210
-9
lines changed

19 files changed

+210
-9
lines changed

demo/generated/demo.js

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/lib.js

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@react-ui-org/react-ui",
3-
"version": "0.22.1",
3+
"version": "0.23.0",
44
"license": "MIT",
55
"main": "dist/lib.js",
66
"repository": {

src/demo/pages/DemoContainer.jsx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
Button,
1212
ButtonGroup,
1313
Card,
14+
CardList,
1415
CheckboxField,
1516
Documentation,
1617
DocumentationLayout,
@@ -273,6 +274,22 @@ class DemoContainer extends React.Component {
273274
<hr />
274275
<section id="layout-components" className="mb-7">
275276
<h2 className="typography-size-5 mb-6">Layout Components</h2>
277+
<h3 id="layout-components-card-list" className="typography-size-4 mb-6">Card List</h3>
278+
<p>
279+
Card List can be used to render <a href="#ui-components-card">Cards</a> in grid.
280+
</p>
281+
<Documentation
282+
name="Card List"
283+
component={(
284+
<CardList>
285+
<DocumentationPlaceholder text="card" />
286+
<DocumentationPlaceholder text="card" />
287+
<DocumentationPlaceholder text="card" />
288+
<DocumentationPlaceholder text="card" />
289+
<DocumentationPlaceholder text="card" />
290+
</CardList>
291+
)}
292+
/>
276293
<h3 id="layout-components-centered-layout" className="typography-size-4 mb-6">Centered Layout</h3>
277294
<p>
278295
Centered layout takes 100 % of viewport height.
@@ -670,6 +687,9 @@ class DemoContainer extends React.Component {
670687
)}
671688
/>
672689
<h3 id="ui-components-card" className="typography-size-4 mb-6">Card</h3>
690+
<p>
691+
You might want to use Cards along with <a href="#layout-components-card-list">Card List</a> layout.
692+
</p>
673693
<Documentation
674694
name="Card types"
675695
component={(

src/demo/pages/navigation.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ export default [
2727
},
2828
{
2929
items: [
30+
{
31+
link: '#layout-components-card-list',
32+
title: 'Card List',
33+
},
3034
{
3135
link: '#layout-components-centered-layout',
3236
title: 'Centered Layout',
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import PropTypes from 'prop-types';
2+
import React from 'react';
3+
import styles from './CardList.scss';
4+
5+
const CardList = (props) => {
6+
const {
7+
children,
8+
id,
9+
...other
10+
} = props;
11+
12+
if (!props.children) {
13+
return null;
14+
}
15+
16+
return (
17+
<div
18+
id={id}
19+
className={styles.root}
20+
{...other}
21+
>
22+
{React.Children.map(children, (child) => {
23+
if (!React.isValidElement(child)) {
24+
return null;
25+
}
26+
27+
return React.cloneElement(child, {
28+
inList: true,
29+
});
30+
})}
31+
</div>
32+
);
33+
};
34+
35+
CardList.defaultProps = {
36+
children: null,
37+
id: undefined,
38+
};
39+
40+
CardList.propTypes = {
41+
children: PropTypes.oneOfType([
42+
PropTypes.arrayOf(PropTypes.node),
43+
PropTypes.node,
44+
]),
45+
id: PropTypes.string,
46+
};
47+
48+
export default CardList;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
@import '../../../styles/tools/breakpoints';
2+
@import '../../../styles/tools/offset';
3+
@import './theme';
4+
5+
/* autoprefixer grid: off */
6+
.root {
7+
display: grid;
8+
grid-template-columns: 1fr;
9+
grid-template-rows: auto;
10+
grid-gap: $card-list-grid-gap;
11+
margin-bottom: offset(4);
12+
13+
@include breakpoint-up(xs) {
14+
grid-template-columns: repeat(auto-fit, minmax($card-list-card-min-width, $card-list-card-max-width));
15+
}
16+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import React from 'react';
2+
import { shallow } from 'enzyme';
3+
import CardList from '../CardList';
4+
5+
describe('rendering', () => {
6+
it('renders correctly with no children', () => {
7+
const tree = shallow((
8+
<CardList />
9+
));
10+
11+
expect(tree).toMatchSnapshot();
12+
});
13+
14+
it('renders correctly with a single child', () => {
15+
const tree = shallow((
16+
<CardList>
17+
<span>content</span>
18+
</CardList>
19+
));
20+
21+
expect(tree).toMatchSnapshot();
22+
});
23+
24+
it('renders correctly with multiple children', () => {
25+
const tree = shallow((
26+
<CardList>
27+
<span>content 1</span>
28+
<span>content 2</span>
29+
<span>content 3</span>
30+
</CardList>
31+
));
32+
33+
expect(tree).toMatchSnapshot();
34+
});
35+
});
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`rendering renders correctly with a single child 1`] = `
4+
<div
5+
className="root"
6+
>
7+
<span
8+
inList={true}
9+
key=".0"
10+
>
11+
content
12+
</span>
13+
</div>
14+
`;
15+
16+
exports[`rendering renders correctly with multiple children 1`] = `
17+
<div
18+
className="root"
19+
>
20+
<span
21+
inList={true}
22+
key=".0"
23+
>
24+
content 1
25+
</span>
26+
<span
27+
inList={true}
28+
key=".1"
29+
>
30+
content 2
31+
</span>
32+
<span
33+
inList={true}
34+
key=".2"
35+
>
36+
content 3
37+
</span>
38+
</div>
39+
`;
40+
41+
exports[`rendering renders correctly with no children 1`] = `""`;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
$card-list-card-min-width: var(--rui-card-list-card-min-width);
2+
$card-list-card-max-width: var(--rui-card-list-card-max-width);
3+
$card-list-grid-gap: var(--rui-card-list-grid-gap);
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default } from './CardList';

src/lib/components/ui/Card/Card.jsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export const Card = (props) => {
77
children,
88
disabled,
99
id,
10+
inList,
1011
raised,
1112
type,
1213
} = props;
@@ -25,6 +26,11 @@ export const Card = (props) => {
2526
disabledClass = styles.isRootDisabled;
2627
}
2728

29+
let inListClass = '';
30+
if (inList) {
31+
inListClass = styles.isRootInList;
32+
}
33+
2834
let raisedClass = '';
2935
if (raised) {
3036
raisedClass = styles.isRootRaised;
@@ -36,6 +42,7 @@ export const Card = (props) => {
3642
${styles.root}
3743
${typeClass}
3844
${disabledClass}
45+
${inListClass}
3946
${raisedClass}
4047
`).trim()}
4148
id={id}
@@ -48,6 +55,7 @@ export const Card = (props) => {
4855
Card.defaultProps = {
4956
disabled: false,
5057
id: undefined,
58+
inList: false,
5159
raised: false,
5260
type: 'flat',
5361
};
@@ -59,6 +67,7 @@ Card.propTypes = {
5967
]).isRequired,
6068
disabled: PropTypes.bool,
6169
id: PropTypes.string,
70+
inList: PropTypes.bool,
6271
raised: PropTypes.bool,
6372
type: PropTypes.oneOf(['flat', 'bordered', 'warning', 'error']),
6473
};

src/lib/components/ui/Card/Card.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@
2424
@include card-disabled();
2525
}
2626

27+
.isRootInList {
28+
@include card-in-list();
29+
}
30+
2731
.isRootRaised {
2832
@include card-raised();
2933
}

src/lib/components/ui/Card/_mixins.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
background-color: map-get($card-disabled, background-color);
2020
}
2121

22+
@mixin card-in-list() {
23+
max-width: $card-in-list-max-width;
24+
}
25+
2226
@mixin card-raised() {
2327
box-shadow: map-get($card-raised, box-shadow);
2428
}

src/lib/components/ui/Card/_theme.scss

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ $card-disabled: (
2323
border-color: var(--rui-card-disabled-border-color),
2424
);
2525

26+
$card-in-list-max-width: var(--rui-card-in-list-max-width);
27+
2628
$card-raised: (
2729
box-shadow: var(--rui-card-raised-box-shadow),
2830
);

src/lib/components/ui/Card/tests/__snapshots__/Card.test.jsx.snap

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ exports[`rendering renders correctly raised 1`] = `
3939
className="root
4040
flat
4141
42+
4243
isRootRaised"
4344
>
4445
<p>
@@ -52,6 +53,7 @@ exports[`rendering renders correctly with all props 1`] = `
5253
className="root
5354
warning
5455
isRootDisabled
56+
5557
isRootRaised"
5658
id="custom-id"
5759
>

src/lib/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export { DocumentationLayoutContent } from './components/documentation/Documenta
88
export { DocumentationLayoutSidebar } from './components/documentation/DocumentationLayout';
99

1010
// Layout components
11+
export { default as CardList } from './components/layout/CardList';
1112
export { default as LayoutCenter } from './components/layout/LayoutCenter';
1213
export { List } from './components/layout/List';
1314
export { ListItem } from './components/layout/List';

src/lib/theme.scss

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -418,9 +418,17 @@
418418
--rui-button-large-padding-x: var(--rui-offset-5);
419419
--rui-button-large-font-size: var(--rui-typography-size-1);
420420

421+
//
422+
// Card List
423+
// =========
424+
425+
--rui-card-list-card-min-width: 300px;
426+
--rui-card-list-card-max-width: auto;
427+
--rui-card-list-grid-gap: var(--rui-offset-4);
428+
421429
//
422430
// Cards
423-
// ============
431+
// =====
424432

425433
// Cards: common properties
426434
--rui-card-padding: var(--rui-offset-4);
@@ -443,6 +451,9 @@
443451
// Cards: raised
444452
--rui-card-raised-box-shadow: 0 0.01rem 0.65rem -0.1rem #{rgba(0, 0, 0, 0.3)};
445453

454+
// Cards: in Card List
455+
--rui-card-in-list-max-width: 400px;
456+
446457
// Cards: disabled
447458
--rui-card-disabled-border-color: transparent;
448459
--rui-card-disabled-background-color: var(--rui-color-gray-200);

0 commit comments

Comments
 (0)