Skip to content

Commit d412e34

Browse files
committed
✨ React JS Components - Add Positionnable classes on Grid
1 parent 0d381d1 commit d412e34

File tree

6 files changed

+101
-11
lines changed

6 files changed

+101
-11
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@crystallize/reactjs-components",
33
"license": "MIT",
4-
"version": "0.1.0",
4+
"version": "0.2.0",
55
"author": "Crystallize <[email protected]> (https://crystallize.com)",
66
"contributors": [
77
"Håkon Krogh <[email protected]>",

src/grid/CSSGrid.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { FunctionComponent } from 'react';
2+
import { getPositionnableCellClassNames } from './GridRenderer';
23
import { CSSGridProps } from './types';
34

45
export const CSSGrid: FunctionComponent<CSSGridProps> = ({
@@ -25,7 +26,12 @@ export const CSSGrid: FunctionComponent<CSSGridProps> = ({
2526
: cells.map((cell: any, i: number) => (
2627
<div
2728
key={`cell-${i}`}
28-
className="crystallize-grid__cell"
29+
className={`crystallize-grid__cell ${getPositionnableCellClassNames(
30+
cell.position[0],
31+
cell.position[1],
32+
cell.position[2],
33+
cell.position[3],
34+
)}`}
2935
style={{
3036
gridColumn: `span ${cell.layout.colspan}`,
3137
gridRow: `span ${cell.layout.rowspan}`,

src/grid/GridRenderer.tsx

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { FunctionComponent } from 'react';
22
import { CSSGrid } from './CSSGrid';
3+
import { RowCol } from './RowCol';
34
import { Table } from './Table';
45
import { GridRendererProps, GridRenderingType } from './types';
56

@@ -8,6 +9,24 @@ const getTotalGridDimensions = (rows: any[]): number => {
89
return totalColSpan;
910
};
1011

12+
export function getPositionnableCellClassNames(
13+
rowIndex: number,
14+
colIndex: number,
15+
rowLength: number,
16+
colLength: number,
17+
): string {
18+
return `cell-${rowIndex}-${colIndex} ${rowIndex == 0 ? 'first-row' : ''} ${colIndex == 0 ? 'first-col' : ''} ${
19+
rowIndex === rowLength - 1 ? 'last-row' : ''
20+
} ${colIndex === colLength - 1 ? 'last-col' : ''}`.replace(/\s+/g, ' ');
21+
}
22+
23+
export function getPositionnablRowClassNames(rowIndex: number, rowLength: number): string {
24+
return `row-${rowIndex} ${rowIndex == 0 ? 'first-row' : ''} ${rowIndex == rowLength - 1 ? 'last-row' : ''}`.replace(
25+
/\s+/g,
26+
' ',
27+
);
28+
}
29+
1130
export const GridRenderer: FunctionComponent<GridRendererProps> = ({
1231
cellComponent,
1332
children,
@@ -23,19 +42,29 @@ export const GridRenderer: FunctionComponent<GridRendererProps> = ({
2342

2443
if (!rows.length) return null;
2544
const totalColSpan = getTotalGridDimensions(rows);
26-
if (type === 'table') {
45+
if (type === GridRenderingType.Table) {
2746
return (
2847
<Table cellComponent={cellComponent} rows={rows} totalColSpan={totalColSpan} {...props}>
2948
{children}
3049
</Table>
3150
);
3251
}
33-
// Currently the data is only returned in a nested array of rows and
34-
// columns. To make use of CSS Grid we need a flat array of all of the
35-
// individual cells.
36-
const columns = rows.map((row: { columns: any }) => row.columns);
37-
const cells = [].concat.apply([], columns);
38-
52+
if (type === GridRenderingType.RowCol) {
53+
return (
54+
<RowCol cellComponent={cellComponent} rows={rows} totalColSpan={totalColSpan} {...props}>
55+
{children}
56+
</RowCol>
57+
);
58+
}
59+
const cells = rows.reduce((accumulator: any[], row: { columns: any }, rowIndex: number) => {
60+
row.columns.forEach((col: any, colIndex: number) => {
61+
accumulator.push({
62+
...col,
63+
position: [rowIndex, colIndex, rows.length, row.columns.length],
64+
});
65+
});
66+
return accumulator;
67+
}, []);
3968
return (
4069
<CSSGrid cellComponent={cellComponent} cells={cells} totalColSpan={totalColSpan} {...props}>
4170
{children}

src/grid/RowCol.tsx

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { FunctionComponent } from 'react';
2+
import { getPositionnableCellClassNames, getPositionnablRowClassNames } from './GridRenderer';
3+
import { RowColGridProps } from './types';
4+
5+
export const RowCol: FunctionComponent<RowColGridProps> = ({
6+
cellComponent,
7+
rows,
8+
children,
9+
totalColSpan = 4,
10+
...props
11+
}) => {
12+
const CellComponent = cellComponent;
13+
return (
14+
<div className="crystallize-grid crystallize-row-col-table" {...props}>
15+
{children
16+
? children({ rows, totalColSpan })
17+
: rows.map((row: any, i: number) => {
18+
return (
19+
<div
20+
className={`crystallize-grid-row row ${getPositionnablRowClassNames(i, rows.length)}`}
21+
key={`row-${i}`}
22+
>
23+
{row.columns.map((col: any, j: number) => (
24+
<div
25+
className={`crystallize-grid-col crystallize-grid__cell col ${getPositionnableCellClassNames(
26+
i,
27+
j,
28+
row.length,
29+
row.columns.length,
30+
)}`}
31+
key={`cell-${i}-${j}`}
32+
>
33+
<CellComponent cell={col} totalColSpan={totalColSpan} />
34+
</div>
35+
))}
36+
</div>
37+
);
38+
})}
39+
</div>
40+
);
41+
};

src/grid/Table.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { FunctionComponent } from 'react';
2+
import { getPositionnableCellClassNames, getPositionnablRowClassNames } from './GridRenderer';
23
import { TableGridProps } from './types';
34

45
export const Table: FunctionComponent<TableGridProps> = ({
@@ -23,11 +24,16 @@ export const Table: FunctionComponent<TableGridProps> = ({
2324
? children({ rows, totalColSpan })
2425
: rows.map((row: any, i: number) => {
2526
return (
26-
<tr key={`row-${i}`}>
27+
<tr key={`row-${i}`} className={getPositionnablRowClassNames(i, rows.length)}>
2728
{row.columns.map((col: any, j: number) => (
2829
<td
2930
key={`cell-${i}-${j}`}
30-
className="crystallize-grid__cell"
31+
className={`crystallize-grid__cell ${getPositionnableCellClassNames(
32+
i,
33+
j,
34+
row.length,
35+
row.columns.length,
36+
)}`}
3137
rowSpan={col.layout.rowspan}
3238
colSpan={col.layout.colspan}
3339
>

src/grid/types.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import React, { FunctionComponent } from 'react';
33
export enum GridRenderingType {
44
Table = 'table',
55
Div = 'div',
6+
RowCol = 'row-col',
67
}
78

89
export interface CSSGridProps {
@@ -21,6 +22,13 @@ export interface TableGridProps {
2122
style?: React.CSSProperties;
2223
}
2324

25+
export interface RowColGridProps {
26+
cellComponent: React.FunctionComponent<{ cell: any; totalColSpan: number }>;
27+
rows: any;
28+
children?: FunctionComponent<any>;
29+
totalColSpan: number;
30+
style?: React.CSSProperties;
31+
}
2432
export interface GridRendererProps {
2533
cellComponent: React.FunctionComponent<{ cell: any; totalColSpan: number }>;
2634
type: GridRenderingType;

0 commit comments

Comments
 (0)