Skip to content

Commit

Permalink
Merge pull request #1757 from dequelabs/release-v6.12.0
Browse files Browse the repository at this point in the history
chore(cauldron): Release 6.12.0
  • Loading branch information
scurker authored Dec 4, 2024
2 parents 59b79f4 + 91b0be8 commit 71d7786
Show file tree
Hide file tree
Showing 22 changed files with 706 additions and 156 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,20 @@

All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.

## [6.12.0](https://github.com/dequelabs/cauldron/compare/v6.11.0...v6.12.0) (2024-12-04)


### Features

* **react,styles:** add grid layout for table component ([#1748](https://github.com/dequelabs/cauldron/issues/1748)) ([983c89f](https://github.com/dequelabs/cauldron/commit/983c89f21b584f1cef2c405c9e2db03529edbec1))
* **styles:** synced `table` ([#1745](https://github.com/dequelabs/cauldron/issues/1745)) ([4531fb6](https://github.com/dequelabs/cauldron/commit/4531fb687cf53a1f40aad11c1494b38b2b04038d))
* **styles:** synced tabs with design ([#1741](https://github.com/dequelabs/cauldron/issues/1741)) ([242ac5d](https://github.com/dequelabs/cauldron/commit/242ac5d921b08476e1d65219c24c7ae0a9d432df))


### Bug Fixes

* **react:** fix non-text contrast with text fields ([#1756](https://github.com/dequelabs/cauldron/issues/1756)) ([afe4062](https://github.com/dequelabs/cauldron/commit/afe40620f9eaa560b55f03368034fd99d50068ec))

## [6.11.0](https://github.com/dequelabs/cauldron/compare/v6.10.1...v6.11.0) (2024-11-06)


Expand Down
131 changes: 131 additions & 0 deletions docs/pages/components/Table.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,115 @@ function SortableTableExample() {
</Table>
```

### Grid Layout

The Table component supports an optional css grid layout that can specify column alignment and width definitions per column.

```jsx example
<Table
layout="grid"
columns={[
{ width: 'max-content', align: 'start' },
{ width: 'max-content', align: 'start' },
{ width: '1fr', align: 'end' }
]}>
<TableHead>
<TableRow>
<TableHeader scope="col">First Name</TableHeader>
<TableHeader scope="col">Last Name</TableHeader>
<TableHeader scope="col">Email</TableHeader>
</TableRow>
</TableHead>
<TableBody>
<TableRow>
<TableCell>Frank</TableCell>
<TableCell>Zappa</TableCell>
<TableCell>frank@zappa.io</TableCell>
</TableRow>
<TableRow>
<TableCell>Duane</TableCell>
<TableCell>Allman</TableCell>
<TableCell>duane@almond.biz</TableCell>
</TableRow>
<TableRow>
<TableCell>Yamandu</TableCell>
<TableCell>Costa</TableCell>
<TableCell>yamandu_costa@gmail.br</TableCell>
</TableRow>
<TableRow>
<TableCell>Jimmy</TableCell>
<TableCell>Herring</TableCell>
<TableCell>jamesHerring@hotmail.gov</TableCell>
</TableRow>
</TableBody>
</Table>
```

For column alignments, all cells will be positioned according to the alignment specified for that column, defaulting to `start`:

<Table layout="grid" columns={[{ width: 'max-content', align: 'start' }, { align: 'start' }]}>
<TableHead>
<TableRow>
<TableHeader scope="col">Alignment Type</TableHeader>
<TableHeader scope="col">Description</TableHeader>
</TableRow>
</TableHead>
<TableBody>
<TableRow>
<TableCell>`start`</TableCell>
<TableCell>Aligns all cells within the column to the start.</TableCell>
</TableRow>
<TableRow>
<TableCell>`center`</TableCell>
<TableCell>Aligns all cells within the column to the center.</TableCell>
</TableRow>
<TableRow>
<TableCell>`end`</TableCell>
<TableCell>Aligns all cells within the column to the center.</TableCell>
</TableRow>
</TableBody>
</Table>

For column sizing, the values are roughly equivalent to [track sizing for grid-template-columns](https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-columns)
and the following values are supported:

<Table layout="grid" columns={[{ width: 'max-content', align: 'start' }, { align: 'start' }]}>
<TableHead>
<TableRow>
<TableHeader scope="col">Width Type</TableHeader>
<TableHeader scope="col">Description</TableHeader>
</TableRow>
</TableHead>
<TableBody>
<TableRow>
<TableCell>`auto`</TableCell>
<TableCell>Sizes the column between a range of `min-content` and `max-content`. </TableCell>
</TableRow>
<TableRow>
<TableCell>`max-content`</TableCell>
<TableCell>Will size the column respective to the largest cell.</TableCell>
</TableRow>
<TableRow>
<TableCell>`min-content`</TableCell>
<TableCell>Will size the column respective to the smallest cell.</TableCell>
</TableRow>
<TableRow>
<TableCell>`number`</TableCell>
<TableCell>Applies a fixed width to the column.</TableCell>
</TableRow>
<TableRow>
<TableCell>`<number>fr`</TableCell>
<TableCell>Applies a flex value that sizes a column proportional to the remaining space from other columns.</TableCell>
</TableRow>
<TableRow>
<TableCell>`<number>%`</TableCell>
<TableCell>Applies a percentage width to the column respective to the size of the table.</TableCell>
</TableRow>
</TableBody>
</Table>

For more advanced usage, the width value does not need to be specified as part of a column but can be specified using `--table-grid-template-columns` to set the respective column sizes relative to the content displayed within the table.

## Props

### Table
Expand All @@ -346,6 +455,16 @@ function SortableTableExample() {
name: 'variant',
type: 'bordered',
description: 'Use the bordered variant of Table'
},
{
name: 'layout',
type: 'grid',
description: 'When set, uses a css grid layout instead of a table layout.'
},
{
name: 'columns',
type: ['Array<Column>', 'number'],
description: 'Only allowed when the table has a grid layout. Sets the column widths and alignments for each column.'
}
]}
/>
Expand Down Expand Up @@ -379,6 +498,11 @@ function SortableTableExample() {
type: 'function',
description: 'The function that the implementer passes in to control the change of sort direction.',
defaultValue: 'sorted ascending'
},
{
name: 'align',
type: ['start', 'center', 'end'],
description: 'Only allowed when the table has a grid layout. Overrides any column alignments for this table header.'
}
]}
/>
Expand Down Expand Up @@ -416,4 +540,11 @@ function SortableTableExample() {
<ComponentProps
children={true}
className={true}
props={[
{
name: 'align',
type: ['start', 'center', 'end'],
description: 'Only allowed when the table has a grid layout. Overrides any column alignments for this table cell.'
}
]}
/>
Binary file modified e2e/screenshots/combobox.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified e2e/screenshots/searchfield.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified e2e/screenshots/select.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified e2e/screenshots/textfield.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "cauldron",
"private": true,
"version": "6.11.0",
"version": "6.12.0",
"license": "MPL-2.0",
"scripts": {
"clean": "rimraf dist docs/dist",
Expand Down
2 changes: 1 addition & 1 deletion packages/react/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@deque/cauldron-react",
"version": "6.11.0",
"version": "6.12.0",
"license": "MPL-2.0",
"description": "Fully accessible react components library for Deque Cauldron",
"homepage": "https://cauldron.dequelabs.com/",
Expand Down
111 changes: 96 additions & 15 deletions packages/react/src/components/Table/Table.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,102 @@
import React, { TableHTMLAttributes } from 'react';
import React, { useMemo } from 'react';
import classNames from 'classnames';
import { TableProvider } from './TableContext';

interface TableProps extends TableHTMLAttributes<HTMLTableElement> {
export type Column = {
align: ColumnAlignment;
width?: ColumnWidth;
};
export type ColumnAlignment = 'start' | 'center' | 'end';
export type ColumnWidth =
| 'auto'
| 'min-content'
| 'max-content'
| `${number}`
| `${number}%`
| `${number}fr`;
export type RowAlignment = 'start' | 'center';

type TableBaseProps = {
layout: never;
columns: never;
variant?: 'border';
};

type TableGridProps = {
layout: 'grid';
columns?: Array<Column> | number;
variant?: 'border';
}

const Table = ({ children, className, variant, ...other }: TableProps) => (
<table
className={classNames(
'Table',
variant === 'border' && 'Table--border',
className
)}
{...other}
>
{children}
</table>
};

type TableProps = (TableBaseProps | Partial<TableGridProps>) &
React.TableHTMLAttributes<HTMLTableElement>;

const Table = React.forwardRef<HTMLTableElement, TableProps>(
(
{
children,
className,
variant,
layout,
columns: columnsProp = [],
style,
...other
},
ref
) => {
const isGridLayout = layout === 'grid';
const columns: Column[] = useMemo(() => {
if (typeof columnsProp === 'number') {
return columnsProp > 0
? Array(columnsProp).fill({ align: 'start' })
: [{ align: 'start' }];
}

return columnsProp;
}, [columnsProp]);

const styleTemplateColumns = useMemo(() => {
if (layout !== 'grid') {
return;
}

if (!columns) {
return 'auto';
}

return columns
.map(({ width }) => width || 'auto')
.join(' ');
}, [layout, columns]);

const tableGridStyles: React.CSSProperties = isGridLayout
? ({
'--table-grid-template-columns': styleTemplateColumns
} as React.CSSProperties)
: {};

return (
<table
ref={ref}
style={{
...tableGridStyles,
...style
}}
className={classNames('Table', className, {
'Table--border': variant === 'border',
TableGrid: isGridLayout
})}
{...other}
>
<TableProvider
layout={isGridLayout ? 'grid' : 'table'}
columns={columns}
>
{children}
</TableProvider>
</table>
);
}
);

Table.displayName = 'Table';
Expand Down
20 changes: 11 additions & 9 deletions packages/react/src/components/Table/TableBody.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import React, { HTMLAttributes } from 'react';
import React, { forwardRef } from 'react';
import classNames from 'classnames';

const TableBody = ({
children,
className,
...other
}: HTMLAttributes<HTMLTableSectionElement>) => (
<tbody className={classNames('TableBody', className)} {...other}>
{children}
</tbody>
type TableBodyProps = React.HTMLAttributes<HTMLTableSectionElement> & {
className?: string;
};

const TableBody = forwardRef<HTMLTableSectionElement, TableBodyProps>(
({ children, className, ...other }, ref) => (
<tbody ref={ref} className={classNames('TableBody', className)} {...other}>
{children}
</tbody>
)
);

TableBody.displayName = 'TableBody';
Expand Down
41 changes: 32 additions & 9 deletions packages/react/src/components/Table/TableCell.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,37 @@
import React, { TdHTMLAttributes } from 'react';
import type { ColumnAlignment } from './Table';
import React, { forwardRef } from 'react';
import classNames from 'classnames';
import { useTable } from './TableContext';
import useTableGridStyles from './useTableGridStyles';
import useSharedRef from '../../utils/useSharedRef';

const TableCell = ({
children,
className,
...other
}: TdHTMLAttributes<HTMLTableCellElement>) => (
<td className={classNames('TableCell', className)} {...other}>
{children}
</td>
interface TableCellProps
extends Omit<React.TdHTMLAttributes<HTMLTableDataCellElement>, 'align'> {
align?: ColumnAlignment;
}

const TableCell = forwardRef<HTMLTableCellElement, TableCellProps>(
({ children, className, align, style, ...other }, ref) => {
const tableCellRef = useSharedRef<HTMLTableCellElement>(ref);
const { layout, columns } = useTable();
const tableGridStyles = useTableGridStyles({
elementRef: tableCellRef,
align,
columns,
layout
});

return (
<td
ref={tableCellRef}
style={{ ...tableGridStyles, ...style }}
className={classNames('TableCell', className)}
{...other}
>
{children}
</td>
);
}
);

TableCell.displayName = 'TableCell';
Expand Down
Loading

0 comments on commit 71d7786

Please sign in to comment.