Skip to content

Commit

Permalink
[F] add SimpleTable and ComplexTable
Browse files Browse the repository at this point in the history
  • Loading branch information
alexgoff committed Dec 29, 2022
1 parent c7b6ecb commit 62e1cbd
Show file tree
Hide file tree
Showing 17 changed files with 650 additions and 12 deletions.
1 change: 1 addition & 0 deletions packages/epo-react-lib/.storybook/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const config = {
alias: {
"@/assets": path.resolve(__dirname, "../src/assets"),
"@/atomic": path.resolve(__dirname, "../src/atomic"),
"@/content-blocks": path.resolve(__dirname, "../src/content-blocks"),
"@/contexts": path.resolve(__dirname, "../src/contexts"),
"@/form": path.resolve(__dirname, "../src/form"),
"@/helpers": path.resolve(__dirname, "../src/helpers"),
Expand Down
1 change: 1 addition & 0 deletions packages/epo-react-lib/jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const config: JestConfigWithTsJest = {
moduleNameMapper: {
"^@/assets(.*)$": "<rootDir>/src/assets$1",
"^@/atomic(.*)$": "<rootDir>/src/atomic$1",
"^@/content-blocks(.*)$": "<rootDir>/src/content-blocks$1",
"^@/contexts(.*)$": "<rootDir>/src/contexts$1",
"^@/form(.*)$": "<rootDir>/src/form$1",
"^@/helpers(.*)$": "<rootDir>/src/helpers$1",
Expand Down
2 changes: 1 addition & 1 deletion packages/epo-react-lib/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@rubin-epo/epo-react-lib",
"version": "1.0.11",
"version": "1.0.12",
"author": "Rubin EPO",
"license": "MIT",
"homepage": "https://lsst-epo.github.io/epo-react-lib",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
import { ComponentMeta, ComponentStoryObj } from "@storybook/react";

import ComplexTable from ".";
import { ComplexTableRow } from "./ComplexTable";

const MockTableContent: ComplexTableRow[] = [
{
tableRow: [
{
id: "0VvOOc",
cellContent: "Header",
},
{
id: "3MeJAm",
cellContent:
"<a href='https://rubinobs.org/' target='_blank'>Header</a>",
},
{
id: "fD8HUc",
cellContent: "Header",
},
{
id: "C5l39F",
cellContent:
"<a href='https://rubinobs.org/' target='_blank'>Header</a>",
},
],
},
{
tableRow: [
{
id: "KsKZtU",
cellContent: "Rubin Observatory",
},
{
id: "OVp7Dp",
cellContent:
"<a href='https://rubinobs.org/' target='_blank'>Rubin Observatory</a>",
},
{
id: "QRm6AM",
cellContent: "Rubin Observatory",
},
{
id: "0S8OAG",
cellContent: "Rubin Observatory",
},
],
},
];

const meta: ComponentMeta<typeof ComplexTable> = {
component: ComplexTable,
argTypes: {
complexTable: {
description:
"Array of `ComplexTableRow` objects to populate the table with.",
},
plainText: {
type: "string",
description:
"Table caption shown above the table. Does not display if `isChild` is set.",
table: {
type: {
summary: "string",
},
},
},
isChild: {
type: "boolean",
description:
"If the table is a child of another component, this prop will add a narrow width container around the table.",
table: {
type: {
summary: "boolean",
},
defaultValue: {
summary: false,
},
},
},
styleAs: {
type: "string",
control: {
type: "select",
},
options: ["primary", "secondary"],
description:
"Determines if table is visually styled using primary or secondary theme.",
table: {
type: {
summary: "primary | secondary",
},
defaultValue: {
summary: "primary",
},
},
},
verticalAlignment: {
type: "string",
description:
"Sets the `vertical-align` CSS property for all table cells.",
table: {
type: {
summary: "string",
},
defaultValue: {
summary: "top",
},
},
},
},
};
export default meta;

export const Primary: ComponentStoryObj<typeof ComplexTable> = {
args: {
complexTable: MockTableContent,
styleAs: "primary",
plainText: "Complex Table",
isChild: false,
},
};

export const Secondary: ComponentStoryObj<typeof ComplexTable> = {
args: {
complexTable: MockTableContent,
styleAs: "secondary",
plainText: "Complex Table",
isChild: false,
},
};

export const Child: ComponentStoryObj<typeof ComplexTable> = {
args: {
complexTable: MockTableContent,
plainText: "Complex Table",
isChild: true,
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { render, screen } from "@testing-library/react";
import ComplexTable from ".";

const props = {
plainText: "Test table",
complexTable: [
{
tableRow: [
{
id: "0VvOOc",
cellContent: "Header",
},
{
id: "3MeJAm",
cellContent:
"<a href='https://rubinobs.org/' target='_blank'>Header</a>",
},
{
id: "fD8HUc",
cellContent: "Header",
},
{
id: "C5l39F",
cellContent:
"<a href='https://rubinobs.org/' target='_blank'>Header</a>",
},
],
},
{
tableRow: [
{
id: "KsKZtU",
cellContent: "Rubin Observatory",
},
{
id: "OVp7Dp",
cellContent:
"<a href='https://rubinobs.org/' target='_blank'>Rubin Observatory</a>",
},
{
id: "QRm6AM",
cellContent: "Rubin Observatory",
},
{
id: "0S8OAG",
cellContent: "Rubin Observatory",
},
],
},
],
};

describe("ComplexTable", () => {
it("should create a table with a caption", () => {
render(<ComplexTable {...props} />);

const table = screen.getByRole("table");

expect(table).toBeInTheDocument;
expect(table).toHaveAccessibleName;
});
it("should render rows", () => {
render(<ComplexTable {...props} />);

const rows = screen.getAllByRole("row");

expect(rows.length).toBe(props.complexTable.length);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { FunctionComponent } from "react";
import Container from "@/layout/Container";
import * as Styled from "./styles";

interface ComplexTableCell {
id: string;
cellBackground?: string;
hasFlexibleCellWidth?: boolean;
cellWidth?: number;
cellContent: string;
}

export interface ComplexTableRow {
tableRow: ComplexTableCell[];
}

export interface ComplexTableProps {
complexTable: ComplexTableRow[];
plainText?: string;
verticalAlignment?: string;
styleAs?: "primary" | "secondary";
isChild?: boolean;
}

const ComplexTable: FunctionComponent<ComplexTableProps> = ({
complexTable,
plainText,
verticalAlignment,
styleAs = "primary",
isChild = false,
}) => {
const renderTable = () => (
<Styled.TableWrapper>
<Styled.Table
as="table"
$styleAs={styleAs}
$verticalAlignment={verticalAlignment}
>
{plainText && (
<Styled.Caption {...{ isChild }}>{plainText}</Styled.Caption>
)}
<tbody>
{complexTable.map((row, i) => (
<Styled.TableRow key={i}>
{row.tableRow.map((cell) => (
<Styled.TableCell
as={i === 0 ? "th" : "td"}
key={cell.id}
$row={i + 1}
$background={cell.cellBackground}
$hasFlexibleCellWidth={cell.hasFlexibleCellWidth}
colSpan={cell.cellWidth || 1}
dangerouslySetInnerHTML={{ __html: cell.cellContent }}
/>
))}
</Styled.TableRow>
))}
</tbody>
</Styled.Table>
</Styled.TableWrapper>
);

return isChild ? (
renderTable()
) : (
<Container width="narrow">{renderTable()}</Container>
);
};

export default ComplexTable;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from "./ComplexTable";
70 changes: 70 additions & 0 deletions packages/epo-react-lib/src/content-blocks/ComplexTable/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import styled, { css } from "styled-components";
import { fluidScale } from "@/styles/globalStyles";
import { aHidden } from "@/styles/mixins/appearance";

export const TableWrapper = styled.div`
max-width: 100vw;
width: 100%;
overflow: auto;
`;

interface TableProps {
$styleAs?: "primary" | "secondary";
$verticalAlignment?: string;
}

export const Table = styled.table<TableProps>`
width: 100%;
border-collapse: collapse;
${({ $styleAs, $verticalAlignment = "top" }) =>
$styleAs === "secondary"
? css`
--ComplexTable-cell-bg: var(--neutral10);
--ComplexTable-border: 5px solid var(--white);
--ComplexTable-vertical-align: ${$verticalAlignment};
border-style: hidden;
`
: css`
--ComplexTable-border: 1px solid var(--black);
--ComplexTable-cell-bg: none;
--ComplexTable-vertical-align: ${$verticalAlignment};
`}
`;

export const Caption = styled.caption<{ isChild: boolean }>`
padding-block-end: 1em;
font-size: 1.136em;
font-weight: bold;
text-align: start;
${({ isChild }) => (isChild ? aHidden : null)}
`;

export const TableRow = styled.tr`
&:nth-child(odd) {
background-color: var(--neutral10);
}
`;

interface TableCellProps {
$background?: string;
$hasFlexibleCellWidth?: boolean;
$row: number;
}

export const TableCell = styled.td<TableCellProps>`
${({ $background }) =>
css`
background-color: ${$background || "var(--ComplexTable-cell-bg)"};
color: ${$background ? "var(--black)" : "inherit"};
`};
${({ $hasFlexibleCellWidth }) =>
$hasFlexibleCellWidth && `white-space: nowrap;`}
min-width: ${fluidScale("180px", "110px")};
border: var(--ComplexTable-border);
padding: 20px;
text-align: inherit;
vertical-align: var(--ComplexTable-vertical-align);
`;
Loading

0 comments on commit 62e1cbd

Please sign in to comment.