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 { CellRender } from "./CellRender";
|
||||
import { ReactNode } from "react";
|
||||
|
||||
type Props = {
|
||||
/**
|
||||
|
@ -7,21 +7,12 @@ type Props = {
|
|||
*/
|
||||
headers: string[];
|
||||
|
||||
/**
|
||||
* 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[];
|
||||
cells: ReactNode[][];
|
||||
|
||||
className?: string;
|
||||
};
|
||||
|
||||
export function Table({ data, headers, cells, className }: Props) {
|
||||
export function Table({ headers, cells, className }: Props) {
|
||||
return (
|
||||
<div className={`table-container ${className}`}>
|
||||
<table className={"table"}>
|
||||
|
@ -35,14 +26,14 @@ export function Table({ data, headers, cells, className }: Props) {
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{data.map((row, index) => (
|
||||
{cells.map((row, index) => (
|
||||
<tr key={index} className="table-tbodyTr">
|
||||
{headers.map((header, idx) => {
|
||||
const render = cells[idx];
|
||||
const cell = row[idx];
|
||||
|
||||
return (
|
||||
<td key={header} className="table-tbodyTd">
|
||||
{render(row[idx], row, index)}
|
||||
{cell}
|
||||
</td>
|
||||
);
|
||||
})}
|
||||
|
|
Loading…
Reference in New Issue