Skip to content

Commit

Permalink
Merge pull request #170 from abusix/gops-418-create-multi-key-value-p…
Browse files Browse the repository at this point in the history
…air-table-components-in-hailstorm
  • Loading branch information
Coderwelsch authored Nov 17, 2024
2 parents 1d36d67 + 7986ab5 commit 339587d
Show file tree
Hide file tree
Showing 9 changed files with 242 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export { SpinnerOverlay } from "./spinner-overlay";
export { Tab } from "./tab";
export { TableUnvirtualized } from "./table-unvirtualized";
export { TableVirtualized, TableVirtualizedProps } from "./table-virtualized";
export { TableKeyValuePair } from "./table-key-value-pair";
export { Tag } from "./tag";
export { Toast } from "./toast";
export { Toggle } from "./toggle";
Expand Down
1 change: 1 addition & 0 deletions src/components/table-key-value-pair/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { TableKeyValuePair } from "./table-key-value-pair";
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from "react";
import { classNames } from "../../util/class-names";

export type TableKeyValuePairBodyKeyProps = React.DetailedHTMLProps<
React.TdHTMLAttributes<HTMLTableCellElement>,
HTMLTableCellElement
>;

export const TableKeyValuePairBodyKeyCell = ({
children,
className,
...props
}: TableKeyValuePairBodyKeyProps) => {
return (
<td
className={classNames(
"headline-400 border-b border-r border-neutral-300 px-2.5 text-neutral-900 first:border-l",
className
)}
{...props}
>
{children}
</td>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from "react";
import { classNames } from "../../util/class-names";

export type TableKeyValuePairBodyProps = React.TableHTMLAttributes<HTMLTableRowElement>;

export const TableKeyValuePairBodyRow = ({
children,
className,
...props
}: TableKeyValuePairBodyProps) => {
return (
<tr
className={classNames(
"h-12 [&:last-child_>_td:first-child]:rounded-bl-md [&:last-child_>_td:first-child]:border-l [&:last-child_>_td:first-child]:border-neutral-300 [&:last-child_>_td:last-child]:rounded-br-md",
className
)}
{...props}
>
{children}
</tr>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from "react";
import { classNames } from "../../util/class-names";

export type TableKeyValuePairBodyValueProps = React.DetailedHTMLProps<
React.TdHTMLAttributes<HTMLTableCellElement>,
HTMLTableCellElement
>;

export const TableKeyValuePairBodyValueCell = ({
children,
className,
...props
}: TableKeyValuePairBodyValueProps) => {
return (
<td
className={classNames(
"border-b border-r border-neutral-300 px-2.5 text-neutral-900",
className
)}
{...props}
>
{children}
</td>
);
};
16 changes: 16 additions & 0 deletions src/components/table-key-value-pair/table-key-value-pair-body.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from "react";
import { TableKeyValuePairBodyRow } from "./table-key-value-pair-body-row";
import { TableKeyValuePairBodyValueCell } from "./table-key-value-pair-body-value-cell";
import { TableKeyValuePairBodyKeyCell } from "./table-key-value-pair-body-key-cell";

export type TableKeyValuePairBodyProps = React.TableHTMLAttributes<HTMLTableSectionElement>;

const TableKeyValuePairBody = ({ children, ...props }: TableKeyValuePairBodyProps) => {
return <tbody {...props}>{children}</tbody>;
};

TableKeyValuePairBody.Row = TableKeyValuePairBodyRow;
TableKeyValuePairBody.Key = TableKeyValuePairBodyKeyCell;
TableKeyValuePairBody.Value = TableKeyValuePairBodyValueCell;

export { TableKeyValuePairBody };
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from "react";
import { classNames } from "../../util/class-names";

export interface TableKeyValuePairHeaderProps
extends React.HTMLAttributes<HTMLTableSectionElement> {
colSpan?: number;
}

export const TableKeyValuePairHeader = ({
children,
className,
colSpan,
...props
}: TableKeyValuePairHeaderProps) => {
return (
<thead className={classNames(className)} {...props}>
<tr>
<th
className="headline-400 rounded-t-md border border-neutral-300 bg-neutral-50 px-2.5 py-4 text-left text-neutral-900"
colSpan={colSpan}
>
{children}
</th>
</tr>
</thead>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import React from "react";
import type { Meta } from "@storybook/react";
import { TableKeyValuePair } from "./table-key-value-pair";
import { FormField } from "../form-field";

const meta: Meta<typeof TableKeyValuePair> = {
title: "Table / Key-Value Pairs",
component: TableKeyValuePair,
};

export default meta;

interface Person {
id: number;
name: string;
isDead?: boolean;
}

const people: Person[] = [
{ id: 1, name: "John Lennon", isDead: true },
{ id: 2, name: "Kenton Towne" },
{ id: 3, name: "Therese Wunsch" },
{ id: 4, name: "Benedict Kessler" },
{ id: 5, name: "Katelyn Rohan" },
];

const ExampleListbox = () => {
const [selectedPerson, setSelectedPerson] = React.useState<null | Person>(null);

return (
<FormField>
<FormField.Listbox value={selectedPerson} onChange={setSelectedPerson}>
<FormField.Listbox.Button>
<FormField.Listbox.Button.TextValue
value={selectedPerson?.name ?? null}
placeholder="Select..."
/>
</FormField.Listbox.Button>

<FormField.Listbox.Options>
{people.map((person) => (
<FormField.Listbox.Option
value={person}
key={person.id}
disabled={person.isDead}
>
<FormField.Listbox.Option.TextOption>
{person.name}
</FormField.Listbox.Option.TextOption>
</FormField.Listbox.Option>
))}
</FormField.Listbox.Options>
</FormField.Listbox>
</FormField>
);
};

export const Default = () => {
return (
<div className="min-h-[30rem]">
<TableKeyValuePair>
<TableKeyValuePair.Header colSpan={4}>Details</TableKeyValuePair.Header>

<TableKeyValuePair.Body>
<TableKeyValuePair.Body.Row>
<TableKeyValuePair.Body.Key>First Name</TableKeyValuePair.Body.Key>
<TableKeyValuePair.Body.Value>John</TableKeyValuePair.Body.Value>

<TableKeyValuePair.Body.Key>Age</TableKeyValuePair.Body.Key>
<TableKeyValuePair.Body.Value>John</TableKeyValuePair.Body.Value>
</TableKeyValuePair.Body.Row>

<TableKeyValuePair.Body.Row>
<TableKeyValuePair.Body.Key>Last Name</TableKeyValuePair.Body.Key>
<TableKeyValuePair.Body.Value>Doe</TableKeyValuePair.Body.Value>

<TableKeyValuePair.Body.Key>Birth</TableKeyValuePair.Body.Key>
<TableKeyValuePair.Body.Value>01.01.1970</TableKeyValuePair.Body.Value>
</TableKeyValuePair.Body.Row>

<TableKeyValuePair.Body.Row>
<TableKeyValuePair.Body.Key>Status</TableKeyValuePair.Body.Key>
<TableKeyValuePair.Body.Value>
<ExampleListbox />
</TableKeyValuePair.Body.Value>

<TableKeyValuePair.Body.Value colSpan={2}>
<a href="https://abusix.com" className="inline-link">
Open Comments
</a>
</TableKeyValuePair.Body.Value>
</TableKeyValuePair.Body.Row>
</TableKeyValuePair.Body>
</TableKeyValuePair>
</div>
);
};
28 changes: 28 additions & 0 deletions src/components/table-key-value-pair/table-key-value-pair.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from "react";
import { classNames } from "../../util/class-names";
import { TableKeyValuePairHeader } from "./table-key-value-pair-header";
import { TableKeyValuePairBody } from "./table-key-value-pair-body";

export type TableKeyValuePairProps = React.DetailedHTMLProps<
React.TableHTMLAttributes<HTMLTableElement>,
HTMLTableElement
>;

const TableKeyValuePair = ({ children, className, ...props }: TableKeyValuePairProps) => {
return (
<table
className={classNames(
"w-full table-fixed border-separate border-spacing-0 text-sm",
className
)}
{...props}
>
{children}
</table>
);
};

TableKeyValuePair.Header = TableKeyValuePairHeader;
TableKeyValuePair.Body = TableKeyValuePairBody;

export { TableKeyValuePair };

0 comments on commit 339587d

Please sign in to comment.