Refactor Table component
This commit is contained in:
parent
e1a20e96ab
commit
3c314b455d
|
@ -0,0 +1,14 @@
|
||||||
|
import { SimpleText } from "../SimpleText/SimpleText";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
action: string;
|
||||||
|
onClick: (data: unknown) => unknown | Promise<unknown>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ActionCell = ({ action, onClick }: Props) => (
|
||||||
|
<a onClick={onClick} className="cell--action">
|
||||||
|
<SimpleText variant="primary" bold={true}>
|
||||||
|
{action}
|
||||||
|
</SimpleText>
|
||||||
|
</a>
|
||||||
|
);
|
|
@ -1,20 +0,0 @@
|
||||||
import { SimpleText } from "../SimpleText/SimpleText";
|
|
||||||
|
|
||||||
export const ActionCellRender =
|
|
||||||
(action: string, onClick: (row: string[]) => void) =>
|
|
||||||
(_: string, row: string[]) => {
|
|
||||||
return (
|
|
||||||
<a
|
|
||||||
href="#"
|
|
||||||
onClick={(e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
onClick(row);
|
|
||||||
}}
|
|
||||||
className="cell--action"
|
|
||||||
>
|
|
||||||
<SimpleText variant="primary" bold={true}>
|
|
||||||
{action}
|
|
||||||
</SimpleText>
|
|
||||||
</a>
|
|
||||||
);
|
|
||||||
};
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
.cell--break {
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
import "./BreakCell.css";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
value: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const BreakCell = ({ value }: Props) => (
|
||||||
|
<span className="cell--break">{value || " "}</span>
|
||||||
|
);
|
|
@ -1,3 +0,0 @@
|
||||||
export const BreakCellRender = (val: string) => (
|
|
||||||
<span className="cell--break">{val || " "}</span>
|
|
||||||
);
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
.cell--action {
|
||||||
|
text-decoration: none;
|
||||||
|
transition: text-shadow 0.35s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cell--action:hover {
|
||||||
|
text-shadow: var(--codex-color-primary) 0px 0 20px;
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
import "./Cell.css";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
value: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Cell = ({ value }: Props) => <span>{value}</span>;
|
|
@ -1,22 +0,0 @@
|
||||||
.cell--break {
|
|
||||||
word-break: break-all;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cell--action {
|
|
||||||
text-decoration: none;
|
|
||||||
transition: text-shadow 0.35s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cell--action:hover {
|
|
||||||
text-shadow: var(--codex-color-primary) 0px 0 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cell-state {
|
|
||||||
border-radius: var(--codex-border-radius);
|
|
||||||
padding: 0.5rem 0.75rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cell-state--error {
|
|
||||||
background-color: var(--codex-color-error);
|
|
||||||
mix-blend-mode: difference;
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
import { ReactNode } from "react";
|
|
||||||
import "./CellRender.css";
|
|
||||||
|
|
||||||
export type CellRender = (
|
|
||||||
value: string,
|
|
||||||
row: string[],
|
|
||||||
index: number
|
|
||||||
) => ReactNode;
|
|
||||||
|
|
||||||
export const DefaultCellRender = (val: string) => val;
|
|
|
@ -1,3 +0,0 @@
|
||||||
import "./CellRender.css";
|
|
||||||
|
|
||||||
export const DefaultCellRender = (val: string) => val;
|
|
|
@ -1,10 +0,0 @@
|
||||||
import prettyMilliseconds from "pretty-ms";
|
|
||||||
|
|
||||||
export function DurationCellRender(value: string) {
|
|
||||||
const ms = parseInt(value, 10);
|
|
||||||
if (isNaN(ms)) {
|
|
||||||
return "Nan";
|
|
||||||
}
|
|
||||||
|
|
||||||
return prettyMilliseconds(ms, { compact: true });
|
|
||||||
}
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
.cell-state {
|
||||||
|
border-radius: var(--codex-border-radius);
|
||||||
|
padding: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cell-state--error {
|
||||||
|
background-color: rgba(var(--codex-color-error), 0.2);
|
||||||
|
color: rgb(var(--codex-color-error));
|
||||||
|
}
|
||||||
|
|
||||||
|
.cell-state--success {
|
||||||
|
background-color: rgba(var(--codex-color-success), 0.2);
|
||||||
|
color: rgb(var(--codex-color-success));
|
||||||
|
}
|
||||||
|
|
||||||
|
.cell-state--warning {
|
||||||
|
background-color: rgba(var(--codex-color-warning), 0.2);
|
||||||
|
color: rgb(var(--codex-color-warning));
|
||||||
|
}
|
||||||
|
|
||||||
|
.cell-state--loading {
|
||||||
|
background-color: rgba(var(--codex-color-blue), 0.2);
|
||||||
|
color: rgb(var(--codex-color-blue));
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
import "./StateCell.css";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
type: "success" | "warning" | "error" | "default";
|
||||||
|
value: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const StateCell = ({ type, value }: Props) => {
|
||||||
|
return <span className={"cell-state cell-state--" + type}>{value}</span>;
|
||||||
|
};
|
|
@ -1,11 +0,0 @@
|
||||||
type Mapping = { [k: string]: "success" | "warning" | "error" | "default" };
|
|
||||||
|
|
||||||
export const StateCellRender = (mapping: Mapping) => (value: string) => {
|
|
||||||
return (
|
|
||||||
<p>
|
|
||||||
<span className={"cell-state cell-state--" + mapping[value]}>
|
|
||||||
{value}
|
|
||||||
</span>
|
|
||||||
</p>
|
|
||||||
);
|
|
||||||
};
|
|
|
@ -1,5 +1,5 @@
|
||||||
import "./Table.css";
|
import "./Table.css";
|
||||||
import { CellRender } from "./CellRender";
|
import { ReactNode } from "react";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
/**
|
/**
|
||||||
|
@ -7,21 +7,12 @@ type Props = {
|
||||||
*/
|
*/
|
||||||
headers: string[];
|
headers: string[];
|
||||||
|
|
||||||
/**
|
cells: ReactNode[][];
|
||||||
* The data are represented by a 2 dimensions array.
|
|
||||||
* Each row contains a dataset whose data structure is a string array.
|
|
||||||
*/
|
|
||||||
data: string[][];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The cell render is an array of function that returns the cell data.
|
|
||||||
*/
|
|
||||||
cells: CellRender[];
|
|
||||||
|
|
||||||
className?: string;
|
className?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function Table({ data, headers, cells, className }: Props) {
|
export function Table({ headers, cells, className }: Props) {
|
||||||
return (
|
return (
|
||||||
<div className={`table-container ${className}`}>
|
<div className={`table-container ${className}`}>
|
||||||
<table className={"table"}>
|
<table className={"table"}>
|
||||||
|
@ -35,14 +26,14 @@ export function Table({ data, headers, cells, className }: Props) {
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{data.map((row, index) => (
|
{cells.map((row, index) => (
|
||||||
<tr key={index} className="table-tbodyTr">
|
<tr key={index} className="table-tbodyTr">
|
||||||
{headers.map((header, idx) => {
|
{headers.map((header, idx) => {
|
||||||
const render = cells[idx];
|
const cell = row[idx];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<td key={header} className="table-tbodyTd">
|
<td key={header} className="table-tbodyTd">
|
||||||
{render(row[idx], row, index)}
|
{cell}
|
||||||
</td>
|
</td>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|
Loading…
Reference in New Issue