Skip to content

Commit 9536de2

Browse files
authored
Merge pull request #14 from machielsdev/feature/grid
Feature/grid
2 parents 0465254 + 80a303c commit 9536de2

File tree

15 files changed

+488
-1
lines changed

15 files changed

+488
-1
lines changed

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
# testing
99
/coverage
10-
/www/src
1110

1211
# production
1312
/build

__tests__/Container.test.tsx

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { render } from 'enzyme';
2+
import React from 'react';
3+
import Container from '@/components/Container/Container';
4+
5+
describe('Container test', () => {
6+
it('should render container', () => {
7+
const container = render(
8+
<div>
9+
<Container/>
10+
</div>
11+
);
12+
13+
expect(container.find('.container').length).toBe(1);
14+
});
15+
16+
it('should render fluid container', () => {
17+
const container = render(
18+
<div>
19+
<Container fluid/>
20+
</div>
21+
);
22+
23+
expect(container.find('.container-fluid').length).toBe(1);
24+
});
25+
});

__tests__/Grid.test.tsx

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import { render } from 'enzyme';
2+
import React from 'react';
3+
import { Col, Grid, Row } from '@/components';
4+
5+
describe('Grid test', () => {
6+
it('should render grid', () => {
7+
const container = render(
8+
<div>
9+
<Grid />
10+
</div>
11+
);
12+
13+
expect(container.find('.grid').length).toBe(1);
14+
});
15+
16+
it('should render grid rows', () => {
17+
const container = render(
18+
<div>
19+
<Grid rows={5} />
20+
</div>
21+
);
22+
23+
expect(container.find('.grid.grid-rows-5').length).toBe(1);
24+
});
25+
26+
it('should render grid columns', () => {
27+
const container = render(
28+
<div>
29+
<Grid columns={5} />
30+
</div>
31+
);
32+
33+
expect(container.find('.grid.grid-columns-5').length).toBe(1);
34+
});
35+
36+
it('should render grid gap', () => {
37+
const container = render(
38+
<div>
39+
<Grid gap={5} />
40+
</div>
41+
);
42+
43+
expect(container.find('.grid.grid-gap-5').length).toBe(1);
44+
});
45+
46+
it('should render rows', () => {
47+
const container = render(
48+
<div>
49+
<Row />
50+
</div>
51+
);
52+
53+
expect(container.find('.row').length).toBe(1);
54+
});
55+
56+
it('should render row within cols', () => {
57+
const container = render(
58+
<div>
59+
<Row>
60+
<Col>Test</Col>
61+
<Col>Test</Col>
62+
<Col>Test</Col>
63+
</Row>
64+
</div>
65+
);
66+
67+
expect(container.find('.row .col').length).toBe(3);
68+
});
69+
70+
it('should render cols with breakpoints set', () => {
71+
const container = render(
72+
<div>
73+
<Row>
74+
<Col width={5}>Test</Col>
75+
<Col sm={5}>Test</Col>
76+
<Col md={5}>Test</Col>
77+
<Col lg={5}>Test</Col>
78+
<Col xl={5}>Test</Col>
79+
</Row>
80+
</div>
81+
);
82+
83+
expect(container.find('.row .col.col-5').length).toBe(1);
84+
expect(container.find('.row .col.sm\\:col-5').length).toBe(1);
85+
expect(container.find('.row .col.md\\:col-5').length).toBe(1);
86+
expect(container.find('.row .col.lg\\:col-5').length).toBe(1);
87+
expect(container.find('.row .col.xl\\:col-5').length).toBe(1);
88+
});
89+
});
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import * as React from 'react';
2+
import PropTypes from 'prop-types';
3+
import clsx from 'clsx';
4+
5+
interface ContainerProps extends React.HTMLAttributes<HTMLDivElement> {
6+
fluid?: boolean;
7+
}
8+
9+
const Container = React.forwardRef<HTMLDivElement, ContainerProps>((
10+
{
11+
children,
12+
className,
13+
fluid
14+
},
15+
ref
16+
): React.ReactElement => (
17+
<div
18+
ref={ref}
19+
className={clsx(
20+
fluid ? 'container-fluid' : 'container',
21+
className
22+
)}
23+
>
24+
{children}
25+
</div>
26+
));
27+
28+
Container.displayName = 'Container';
29+
Container.propTypes = {
30+
className: PropTypes.string,
31+
children: PropTypes.node,
32+
fluid: PropTypes.bool
33+
}
34+
35+
export default Container;

src/components/Container/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default as Container } from './Container';

src/components/Grid/Col.tsx

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import * as React from 'react';
2+
import clsx from 'clsx';
3+
import PropTypes from 'prop-types';
4+
5+
export interface ColProps extends React.HTMLAttributes<HTMLDivElement> {
6+
lg?: number | string;
7+
md?: number | string;
8+
sm?: number | string;
9+
width?: number | string;
10+
xl?: number | string;
11+
}
12+
13+
const Col = React.forwardRef<HTMLDivElement, ColProps>((
14+
{
15+
className,
16+
children,
17+
lg,
18+
md,
19+
sm,
20+
width,
21+
xl
22+
},
23+
ref
24+
) => (
25+
<div
26+
ref={ref}
27+
className={clsx(
28+
'col',
29+
className,
30+
lg && `lg:col-${lg}`,
31+
md && `md:col-${md}`,
32+
sm && `sm:col-${sm}`,
33+
width && `col-${width}`,
34+
xl && `xl:col-${xl}`
35+
)}
36+
>
37+
{children}
38+
</div>
39+
));
40+
41+
Col.displayName = 'Col';
42+
Col.propTypes = {
43+
className: PropTypes.string,
44+
children: PropTypes.node,
45+
lg: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
46+
md: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
47+
sm: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
48+
width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
49+
xl: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
50+
}
51+
52+
export default Col;

src/components/Grid/Grid.tsx

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import * as React from 'react';
2+
import PropTypes from 'prop-types';
3+
import clsx from 'clsx';
4+
5+
interface GridProps extends React.HTMLAttributes<HTMLDivElement> {
6+
columns?: string | number;
7+
gap?: string | number;
8+
rows?: string | number;
9+
}
10+
11+
const Grid = React.forwardRef<HTMLDivElement, GridProps>((
12+
{
13+
children,
14+
className,
15+
columns,
16+
gap,
17+
rows
18+
},
19+
ref
20+
): React.ReactElement => (
21+
<div
22+
ref={ref}
23+
className={clsx(
24+
'grid',
25+
rows && `grid-rows-${rows}`,
26+
columns && `grid-columns-${columns}`,
27+
gap && `grid-gap-${gap}`,
28+
className
29+
)}
30+
>
31+
{children}
32+
</div>
33+
));
34+
35+
Grid.displayName = 'Grid';
36+
Grid.propTypes = {
37+
className: PropTypes.string,
38+
children: PropTypes.node,
39+
columns: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
40+
gap: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
41+
rows: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
42+
}
43+
44+
export default Grid;

src/components/Grid/Row.tsx

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import * as React from 'react';
2+
import PropTypes from 'prop-types';
3+
import clsx from 'clsx';
4+
5+
type RowProps = React.HTMLAttributes<HTMLDivElement>;
6+
7+
const Row = React.forwardRef<HTMLDivElement, RowProps>((
8+
{
9+
children,
10+
className,
11+
},
12+
ref
13+
): React.ReactElement => (
14+
<div
15+
ref={ref}
16+
className={clsx(
17+
'row',
18+
className
19+
)}
20+
>
21+
{children}
22+
</div>
23+
));
24+
25+
Row.displayName = 'Row';
26+
Row.propTypes = {
27+
className: PropTypes.string,
28+
children: PropTypes.node
29+
}
30+
31+
export default Row;

src/components/Grid/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export { default as Grid } from './Grid';
2+
export { default as Row } from './Row';
3+
export { default as Col } from './Col';

src/components/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
export * from './Card';
2+
export * from './Container';
3+
export * from './Grid';
24
export * from './Page';
35
export * from './Panel';
46
export * from './utils';

src/style/base/_variables.scss

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,14 @@ $base-font-size: 16px;
1212
$base-border-color: mixins.color('gray', 300);
1313
$base-border-radius: 4px;
1414
$base-gutter: 1rem;
15+
$base-gutter-steps: 0.25;
16+
17+
$breakpoints: (
18+
'sm': '640px',
19+
'md': '768px',
20+
'lg': '1024px',
21+
'xl': '1280px'
22+
);
1523

1624
:root {
1725
--base-font-size: #{$base-font-size};

src/style/index.scss

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,9 @@
1414
@use "components/page";
1515
@use "components/panel";
1616
@use "components/card";
17+
18+
/**
19+
* 3. Layout
20+
*/
21+
@use "layout/grid";
22+
@use "layout/helpers";

0 commit comments

Comments
 (0)