Add new TableCells

Signed-off-by: Charles de Dreuille <charles.dedreuille@gmail.com>
This commit is contained in:
Charles de Dreuille
2025-04-13 08:40:52 +02:00
parent c2576b2f06
commit 32d5f0e0a5
21 changed files with 424 additions and 116 deletions
+6
View File
@@ -240,6 +240,12 @@
font-size: var(--canon-font-size-3);
}
.canon-TableCellText, .canon-TableCellLink {
gap: var(--canon-space-0_5);
flex-direction: column;
display: flex;
}
.canon-Text {
font-family: var(--canon-font-regular);
color: var(--canon-fg-primary);
+6
View File
@@ -9464,6 +9464,12 @@
font-size: var(--canon-font-size-3);
}
.canon-TableCellText, .canon-TableCellLink {
gap: var(--canon-space-0_5);
flex-direction: column;
display: flex;
}
.canon-Text {
font-family: var(--canon-font-regular);
color: var(--canon-fg-primary);
-26
View File
@@ -1,29 +1,3 @@
.canon-TableRoot {
caption-side: bottom;
border-collapse: collapse;
width: 100%;
}
.canon-TableHead {
text-align: left;
padding: var(--canon-space-3);
font-size: var(--canon-font-size-3);
color: var(--canon-fg-primary);
}
.canon-TableBody {
color: var(--canon-fg-primary);
}
.canon-TableRow {
border-bottom: 1px solid var(--canon-border);
transition: color .2s ease-in-out;
}
.canon-TableBody .canon-TableRow:hover {
background-color: var(--canon-gray-2);
}
.canon-TableCell {
padding: var(--canon-space-3);
font-size: var(--canon-font-size-3);
+39 -27
View File
@@ -241,43 +241,27 @@ export const DataTable: {
RefAttributes<HTMLTableElement>
>;
TableHeader: ForwardRefExoticComponent<
Omit<
HTMLAttributes<HTMLTableSectionElement> &
RefAttributes<HTMLTableSectionElement>,
'ref'
> &
HTMLAttributes<HTMLTableSectionElement> &
RefAttributes<HTMLTableSectionElement>
>;
TableBody: ForwardRefExoticComponent<
Omit<
HTMLAttributes<HTMLTableSectionElement> &
RefAttributes<HTMLTableSectionElement>,
'ref'
> &
HTMLAttributes<HTMLTableSectionElement> &
RefAttributes<HTMLTableSectionElement>
>;
TableRow: ForwardRefExoticComponent<
Omit<
HTMLAttributes<HTMLTableRowElement> & RefAttributes<HTMLTableRowElement>,
'ref'
> &
RefAttributes<HTMLTableRowElement>
HTMLAttributes<HTMLTableRowElement> & RefAttributes<HTMLTableRowElement>
>;
TableCell: ForwardRefExoticComponent<
Omit<
TdHTMLAttributes<HTMLTableCellElement> &
RefAttributes<HTMLTableCellElement>,
'ref'
> &
RefAttributes<HTMLTableCellElement>
TdHTMLAttributes<HTMLTableCellElement> & RefAttributes<HTMLTableCellElement>
>;
TableCellText: ForwardRefExoticComponent<
TableCellTextProps & RefAttributes<HTMLDivElement>
>;
TableCellLink: ForwardRefExoticComponent<
TableCellLinkProps & RefAttributes<HTMLDivElement>
>;
TableHead: ForwardRefExoticComponent<
Omit<
ThHTMLAttributes<HTMLTableCellElement> &
RefAttributes<HTMLTableCellElement>,
'ref'
> &
RefAttributes<HTMLTableCellElement>
ThHTMLAttributes<HTMLTableCellElement> & RefAttributes<HTMLTableCellElement>
>;
};
@@ -1126,12 +1110,40 @@ export const Table: {
Cell: ForwardRefExoticComponent<
TdHTMLAttributes<HTMLTableCellElement> & RefAttributes<HTMLTableCellElement>
>;
CellText: ForwardRefExoticComponent<
TableCellTextProps & RefAttributes<HTMLDivElement>
>;
CellLink: ForwardRefExoticComponent<
TableCellLinkProps & RefAttributes<HTMLDivElement>
>;
Caption: ForwardRefExoticComponent<
HTMLAttributes<HTMLTableCaptionElement> &
RefAttributes<HTMLTableCaptionElement>
>;
};
// @public (undocumented)
export interface TableCellLinkProps
extends React.TdHTMLAttributes<HTMLTableCellElement> {
// (undocumented)
description?: string;
// (undocumented)
href: string;
// (undocumented)
render?: useRender.ComponentProps<'a'>['render'];
// (undocumented)
title: string;
}
// @public (undocumented)
export interface TableCellTextProps
extends React.TdHTMLAttributes<HTMLTableCellElement> {
// (undocumented)
description?: string;
// (undocumented)
title: string;
}
// @public (undocumented)
const Text_2: ForwardRefExoticComponent<
TextProps & RefAttributes<HTMLParagraphElement>
@@ -27,36 +27,6 @@ const TableRoot = forwardRef<
>(({ className, ...props }, ref) => <Table.Root ref={ref} {...props} />);
TableRoot.displayName = Table.Root.displayName;
const TableHeader = forwardRef<
React.ElementRef<typeof Table.Header>,
React.ComponentPropsWithoutRef<typeof Table.Header>
>(({ className, ...props }, ref) => <Table.Header ref={ref} {...props} />);
TableHeader.displayName = Table.Header.displayName;
const TableBody = forwardRef<
React.ElementRef<typeof Table.Body>,
React.ComponentPropsWithoutRef<typeof Table.Body>
>(({ className, ...props }, ref) => <Table.Body ref={ref} {...props} />);
TableBody.displayName = Table.Body.displayName;
const TableRow = forwardRef<
React.ElementRef<typeof Table.Row>,
React.ComponentPropsWithoutRef<typeof Table.Row>
>(({ className, ...props }, ref) => <Table.Row ref={ref} {...props} />);
TableRow.displayName = Table.Row.displayName;
const TableCell = forwardRef<
React.ElementRef<typeof Table.Cell>,
React.ComponentPropsWithoutRef<typeof Table.Cell>
>(({ className, ...props }, ref) => <Table.Cell ref={ref} {...props} />);
TableCell.displayName = Table.Cell.displayName;
const TableHead = forwardRef<
React.ElementRef<typeof Table.Head>,
React.ComponentPropsWithoutRef<typeof Table.Head>
>(({ className, ...props }, ref) => <Table.Head ref={ref} {...props} />);
TableHead.displayName = Table.Head.displayName;
/**
* DataTable component for displaying tabular data with pagination
* @public
@@ -70,9 +40,11 @@ export const DataTable = {
Pagination: DataTablePagination,
Table: DataTableTable,
TableRoot: TableRoot,
TableHeader: TableHeader,
TableBody: TableBody,
TableRow: TableRow,
TableCell: TableCell,
TableHead: TableHead,
TableHeader: Table.Header,
TableBody: Table.Body,
TableRow: Table.Row,
TableCell: Table.Cell,
TableCellText: Table.CellText,
TableCellLink: Table.CellLink,
TableHead: Table.Head,
};
@@ -17,7 +17,7 @@
import { ColumnDef } from '@tanstack/react-table';
import { DataProps } from './mocked-components';
import { Checkbox } from '../Checkbox';
import { Text } from '../Text';
import { DataTable } from './DataTable';
export const columns: ColumnDef<DataProps>[] = [
{
@@ -32,11 +32,13 @@ export const columns: ColumnDef<DataProps>[] = [
/>
),
cell: ({ row }) => (
<Checkbox
checked={row.getIsSelected()}
onChange={(checked: boolean) => row.toggleSelected(checked)}
aria-label="Select row"
/>
<td>
<Checkbox
checked={row.getIsSelected()}
onChange={(checked: boolean) => row.toggleSelected(checked)}
aria-label="Select row"
/>
</td>
),
enableSorting: false,
enableHiding: false,
@@ -45,27 +47,28 @@ export const columns: ColumnDef<DataProps>[] = [
accessorKey: 'name',
header: 'Name',
cell: ({ row }) => (
<div>
<Text variant="body">{row.getValue('name')}</Text>
<Text variant="body" color="secondary">
{row.original.description}
</Text>
</div>
<DataTable.TableCellLink
title={row.getValue('name')}
description={row.original.description}
href="/"
/>
),
},
{
accessorKey: 'owner',
header: 'Owner',
cell: ({ row }) => <Text variant="body">{row.getValue('owner')}</Text>,
cell: ({ row }) => (
<DataTable.TableCellText title={row.getValue('owner')} />
),
},
{
accessorKey: 'type',
header: 'Type',
cell: ({ row }) => <Text variant="body">{row.getValue('type')}</Text>,
cell: ({ row }) => <DataTable.TableCellText title={row.getValue('type')} />,
},
{
accessorKey: 'tags',
header: 'Tags',
cell: ({ row }) => <Text variant="body">{row.getValue('tags')}</Text>,
cell: ({ row }) => <DataTable.TableCellText title={row.getValue('tags')} />,
},
];
@@ -13,8 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { forwardRef } from 'react';
import clsx from 'clsx';
import { TableCell } from './TableCell/TableCell';
import { TableCellText } from './TableCellText/TableCellText';
import { TableCellLink } from './TableCellLink/TableCellLink';
const TableRoot = forwardRef<
HTMLTableElement,
@@ -62,14 +66,6 @@ const TableHead = forwardRef<
));
TableHead.displayName = 'TableHead';
const TableCell = forwardRef<
HTMLTableCellElement,
React.TdHTMLAttributes<HTMLTableCellElement>
>(({ className, ...props }, ref) => (
<td ref={ref} className={clsx('canon-TableCell', className)} {...props} />
));
TableCell.displayName = 'TableCell';
const TableCaption = forwardRef<
HTMLTableCaptionElement,
React.HTMLAttributes<HTMLTableCaptionElement>
@@ -93,5 +89,7 @@ export const Table = {
Head: TableHead,
Row: TableRow,
Cell: TableCell,
CellText: TableCellText,
CellLink: TableCellLink,
Caption: TableCaption,
};
@@ -0,0 +1,32 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import type { Meta, StoryObj } from '@storybook/react';
import { TableCell } from './TableCell';
const meta = {
title: 'Components/Table/TableCell',
component: TableCell,
} satisfies Meta<typeof TableCell>;
export default meta;
type Story = StoryObj<typeof meta>;
export const Default: Story = {
args: {
children: 'Hello world',
},
};
@@ -0,0 +1,20 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
.canon-TableCell {
padding: var(--canon-space-3);
font-size: var(--canon-font-size-3);
}
@@ -0,0 +1,29 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { forwardRef } from 'react';
import clsx from 'clsx';
/** @public */
const TableCell = forwardRef<
HTMLTableCellElement,
React.TdHTMLAttributes<HTMLTableCellElement>
>(({ className, ...props }, ref) => (
<td ref={ref} className={clsx('canon-TableCell', className)} {...props} />
));
TableCell.displayName = 'TableCell';
export { TableCell };
@@ -0,0 +1,40 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import type { Meta, StoryObj } from '@storybook/react';
import { TableCellLink } from './TableCellLink';
const meta = {
title: 'Components/Table/TableCellLink',
component: TableCellLink,
} satisfies Meta<typeof TableCellLink>;
export default meta;
type Story = StoryObj<typeof meta>;
export const Default: Story = {
args: {
title: 'I am a link',
href: 'https://canon.backstage.io',
},
};
export const WithDescription: Story = {
args: {
...Default.args,
description: 'This is a description',
},
};
@@ -0,0 +1,21 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
.canon-TableCellLink {
display: flex;
flex-direction: column;
gap: var(--canon-space-0_5);
}
@@ -0,0 +1,46 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { forwardRef } from 'react';
import clsx from 'clsx';
import { TableCellLinkProps } from './types';
import { Text } from '../../Text/Text';
import { Link } from '../../Link/Link';
/** @public */
const TableCellLink = forwardRef<HTMLDivElement, TableCellLinkProps>(
({ className, title, description, href, render, ...props }, ref) => (
<div
ref={ref}
className={clsx('canon-TableCellLink', className)}
{...props}
>
{title && (
<Link href={href} render={render}>
{title}
</Link>
)}
{description && (
<Text variant="body" color="secondary">
{description}
</Text>
)}
</div>
),
);
TableCellLink.displayName = 'TableCellLink';
export { TableCellLink };
@@ -0,0 +1,26 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import type { useRender } from '@base-ui-components/react/use-render';
/** @public */
export interface TableCellLinkProps
extends React.TdHTMLAttributes<HTMLTableCellElement> {
title: string;
description?: string;
href: string;
render?: useRender.ComponentProps<'a'>['render'];
}
@@ -0,0 +1,39 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import type { Meta, StoryObj } from '@storybook/react';
import { TableCellText } from './TableCellText';
const meta = {
title: 'Components/Table/TableCellText',
component: TableCellText,
} satisfies Meta<typeof TableCellText>;
export default meta;
type Story = StoryObj<typeof meta>;
export const Default: Story = {
args: {
title: 'Hello world',
},
};
export const WithDescription: Story = {
args: {
...Default.args,
description: 'This is a description',
},
};
@@ -0,0 +1,21 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
.canon-TableCellText {
display: flex;
flex-direction: column;
gap: var(--canon-space-0_5);
}
@@ -0,0 +1,41 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { forwardRef } from 'react';
import clsx from 'clsx';
import { TableCellTextProps } from './types';
import { Text } from '../../Text/Text';
/** @public */
const TableCellText = forwardRef<HTMLDivElement, TableCellTextProps>(
({ className, title, description, ...props }, ref) => (
<div
ref={ref}
className={clsx('canon-TableCellText', className)}
{...props}
>
{title && <Text variant="body">{title}</Text>}
{description && (
<Text variant="body" color="secondary">
{description}
</Text>
)}
</div>
),
);
TableCellText.displayName = 'TableCellText';
export { TableCellText };
@@ -0,0 +1,22 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/** @public */
export interface TableCellTextProps
extends React.TdHTMLAttributes<HTMLTableCellElement> {
title: string;
description?: string;
}
@@ -15,3 +15,5 @@
*/
export * from './Table';
export * from './TableCellText/types';
export * from './TableCellLink/types';
@@ -23,8 +23,3 @@
.canon-TableBody .canon-TableRow:hover {
background-color: var(--canon-gray-2);
}
.canon-TableCell {
padding: var(--canon-space-3);
font-size: var(--canon-font-size-3);
}
+3
View File
@@ -24,6 +24,9 @@
@import '../components/Icon/styles.css';
@import '../components/Checkbox/styles.css';
@import '../components/Table/styles.css';
@import '../components/Table/TableCell/TableCell.styles.css';
@import '../components/Table/TableCellText/TableCellText.styles.css';
@import '../components/Table/TableCellLink/TableCellLink.styles.css';
@import '../components/Text/styles.css';
@import '../components/Heading/styles.css';
@import '../components/IconButton/styles.css';