From 79335df33e80622e20c6a75ffdaf76879b42bc9c Mon Sep 17 00:00:00 2001 From: Charles de Dreuille Date: Mon, 28 Jul 2025 09:00:23 +0100 Subject: [PATCH] Restructure raw content + css Signed-off-by: Charles de Dreuille --- packages/ui/css/styles.css | 292 +++++++++--------- .../Table/RawTable/RawTable.stories.tsx | 115 ------- .../Table/RawTable/RawTable.styles.css | 29 +- .../components/Table/RawTable/RawTable.tsx | 91 +----- .../Table/RawTable/RawTableBody.tsx | 32 ++ .../Table/RawTable/RawTableCaption.tsx | 36 +++ .../index.ts => RawTable/RawTableCell.tsx} | 18 +- .../RawTableHead.tsx} | 48 ++- .../Table/RawTable/RawTableHeader.tsx | 36 +++ .../components/Table/RawTable/RawTableRow.tsx | 34 ++ .../ui/src/components/Table/RawTable/index.ts | 15 +- .../{RawHeadContent => RawTable}/types.ts | 3 +- .../ui/src/components/Table/Table.stories.tsx | 4 + .../ui/src/components/Table/Table.styles.css | 37 --- packages/ui/src/components/Table/Table.tsx | 12 +- .../src/components/Table/mocked-columns.tsx | 13 +- packages/ui/src/css/components.css | 13 +- packages/ui/src/utils/componentDefinitions.ts | 3 +- 18 files changed, 381 insertions(+), 450 deletions(-) delete mode 100644 packages/ui/src/components/Table/RawTable/RawTable.stories.tsx create mode 100644 packages/ui/src/components/Table/RawTable/RawTableBody.tsx create mode 100644 packages/ui/src/components/Table/RawTable/RawTableCaption.tsx rename packages/ui/src/components/Table/{RawHeadContent/index.ts => RawTable/RawTableCell.tsx} (56%) rename packages/ui/src/components/Table/{RawHeadContent/RawHeadContent.tsx => RawTable/RawTableHead.tsx} (64%) create mode 100644 packages/ui/src/components/Table/RawTable/RawTableHeader.tsx create mode 100644 packages/ui/src/components/Table/RawTable/RawTableRow.tsx rename packages/ui/src/components/Table/{RawHeadContent => RawTable}/types.ts (87%) delete mode 100644 packages/ui/src/components/Table/Table.styles.css diff --git a/packages/ui/css/styles.css b/packages/ui/css/styles.css index 10051f9ef1..a647f1d17a 100644 --- a/packages/ui/css/styles.css +++ b/packages/ui/css/styles.css @@ -9517,155 +9517,6 @@ } } -.bui-DataTableRoot { - gap: var(--bui-space-3); - flex-direction: column; - display: flex; -} - -.bui-DataTableRoot--sort { - cursor: pointer; - user-select: none; - align-items: center; - gap: var(--bui-space-1); - display: inline-flex; -} - -.bui-DataTableRoot--sort .bui-DataTableRoot--unsorted { - opacity: 0; - transition: opacity .1s ease-in-out, transform .1s ease-in-out; -} - -.bui-DataTableRoot--sort:hover .bui-DataTableRoot--unsorted, .bui-DataTableRoot--sort:focus .bui-DataTableRoot--unsorted { - opacity: .5; -} - -.bui-DataTableRoot--sort .bui-DataTableRoot--sorted-asc, .bui-DataTableRoot--sort:hover .bui-DataTableRoot--sorted-asc, .bui-DataTableRoot--sort:focus .bui-DataTableRoot--sorted-asc { - opacity: 1; - transform: rotate(0); -} - -.bui-DataTableRoot--sort .bui-DataTableRoot--sorted-desc, .bui-DataTableRoot--sort:hover .bui-DataTableRoot--sorted-desc, .bui-DataTableRoot--sort:focus .bui-DataTableRoot--sorted-desc { - opacity: 1; - transform: rotate(180deg); -} - -.bui-TableRoot { - caption-side: bottom; - border-collapse: collapse; - width: 100%; -} - -.bui-TableHead { - text-align: left; - padding: var(--bui-space-3); - font-size: var(--bui-font-size-3); - color: var(--bui-fg-primary); -} - -.bui-TableBody { - color: var(--bui-fg-primary); -} - -.bui-TableRow { - border-bottom: 1px solid var(--bui-border); - transition: color .2s ease-in-out; -} - -.bui-TableBody .bui-TableRow:hover { - background-color: var(--bui-gray-2); -} - -.bui-TableCell { - padding: var(--bui-space-3); - font-size: var(--bui-font-size-3); -} - -.bui-TableCellText { - align-items: center; - gap: var(--bui-space-2); - flex-direction: row; - display: inline-flex; -} - -.bui-TableCellTextIcon, .bui-TableCellTextIcon svg { - color: var(--bui-fg-primary); - align-items: center; - display: inline-flex; -} - -.bui-TableCellTextContent { - gap: var(--bui-space-0_5); - flex-direction: column; - display: flex; -} - -.bui-TableCellProfile { - gap: var(--bui-space-2); - flex-direction: row; - align-items: center; - display: flex; -} - -.bui-TableCellProfileAvatar { - vertical-align: middle; - user-select: none; - color: var(--bui-fg-primary); - background-color: var(--bui-bg-surface-2); - border-radius: 100%; - justify-content: center; - align-items: center; - width: 1.25rem; - height: 1.25rem; - font-size: 1rem; - font-weight: 500; - line-height: 1; - display: inline-flex; - overflow: hidden; -} - -.bui-TableCellProfileAvatarImage { - object-fit: cover; - width: 100%; - height: 100%; -} - -.bui-TableCellProfileAvatarFallback { - width: 100%; - height: 100%; - font-size: var(--bui-font-size-2); - font-weight: var(--bui-font-weight-regular); - box-shadow: inset 0 0 0 1px var(--bui-border); - border-radius: var(--bui-radius-full); - justify-content: center; - align-items: center; - display: flex; -} - -.bui-DataTablePagination { - padding-top: var(--bui-space-5); - justify-content: space-between; - align-items: center; - display: flex; -} - -.bui-DataTablePagination--left { - justify-content: space-between; - align-items: center; - display: flex; -} - -.bui-DataTablePagination--right { - justify-content: space-between; - align-items: center; - gap: var(--bui-space-2); - display: flex; -} - -.bui-DataTablePagination--select { - min-width: 10.5rem; -} - .bui-FieldError { color: var(--bui-fg-danger); font-size: var(--bui-font-size-2); @@ -10166,6 +10017,149 @@ } } +.bui-Table { + caption-side: bottom; + border-collapse: collapse; + width: 100%; +} + +.bui-TableHead { + text-align: left; + padding: var(--bui-space-3); + font-size: var(--bui-font-size-3); + color: var(--bui-fg-primary); +} + +.bui-TableHeadSortButton { + cursor: pointer; + user-select: none; + align-items: center; + gap: var(--bui-space-1); + display: inline-flex; + + &:hover svg { + opacity: .5; + } + + & svg { + opacity: 0; + transition: opacity .1s ease-in-out, transform .1s ease-in-out; + } + + &[data-sort-order="asc"] svg { + opacity: 1; + transform: rotate(0); + } + + &[data-sort-order="desc"] svg { + opacity: 1; + transform: rotate(180deg); + } +} + +.bui-TableBody { + color: var(--bui-fg-primary); +} + +.bui-TableRow { + border-bottom: 1px solid var(--bui-border); + transition: color .2s ease-in-out; +} + +.bui-TableBody .bui-TableRow:hover { + background-color: var(--bui-gray-2); +} + +.bui-TableCell { + padding: var(--bui-space-3); + font-size: var(--bui-font-size-3); +} + +.bui-TableCellText { + align-items: center; + gap: var(--bui-space-2); + flex-direction: row; + display: inline-flex; +} + +.bui-TableCellTextIcon, .bui-TableCellTextIcon svg { + color: var(--bui-fg-primary); + align-items: center; + display: inline-flex; +} + +.bui-TableCellTextContent { + gap: var(--bui-space-0_5); + flex-direction: column; + display: flex; +} + +.bui-TableCellProfile { + gap: var(--bui-space-2); + flex-direction: row; + align-items: center; + display: flex; +} + +.bui-TableCellProfileAvatar { + vertical-align: middle; + user-select: none; + color: var(--bui-fg-primary); + background-color: var(--bui-bg-surface-2); + border-radius: 100%; + justify-content: center; + align-items: center; + width: 1.25rem; + height: 1.25rem; + font-size: 1rem; + font-weight: 500; + line-height: 1; + display: inline-flex; + overflow: hidden; +} + +.bui-TableCellProfileAvatarImage { + object-fit: cover; + width: 100%; + height: 100%; +} + +.bui-TableCellProfileAvatarFallback { + width: 100%; + height: 100%; + font-size: var(--bui-font-size-2); + font-weight: var(--bui-font-weight-regular); + box-shadow: inset 0 0 0 1px var(--bui-border); + border-radius: var(--bui-radius-full); + justify-content: center; + align-items: center; + display: flex; +} + +.bui-DataTablePagination { + padding-top: var(--bui-space-5); + justify-content: space-between; + align-items: center; + display: flex; +} + +.bui-DataTablePagination--left { + justify-content: space-between; + align-items: center; + display: flex; +} + +.bui-DataTablePagination--right { + justify-content: space-between; + align-items: center; + gap: var(--bui-space-2); + display: flex; +} + +.bui-DataTablePagination--select { + min-width: 10.5rem; +} + .bui-Tabs { --active-tab-left: 0px; --active-tab-right: 0px; diff --git a/packages/ui/src/components/Table/RawTable/RawTable.stories.tsx b/packages/ui/src/components/Table/RawTable/RawTable.stories.tsx deleted file mode 100644 index 0e5bc6b080..0000000000 --- a/packages/ui/src/components/Table/RawTable/RawTable.stories.tsx +++ /dev/null @@ -1,115 +0,0 @@ -/* - * 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 { ComponentType } from 'react'; -import type { Meta, StoryObj } from '@storybook/react'; -import { - RawTable, - RawTableBody, - RawTableHead, - RawTableHeader, - RawTableRow, - RawTableCell, -} from '.'; - -const invoices = [ - { - invoice: 'INV001', - paymentStatus: 'Paid', - totalAmount: '$250.00', - paymentMethod: 'Credit Card', - }, - { - invoice: 'INV002', - paymentStatus: 'Pending', - totalAmount: '$150.00', - paymentMethod: 'PayPal', - }, - { - invoice: 'INV003', - paymentStatus: 'Unpaid', - totalAmount: '$350.00', - paymentMethod: 'Bank Transfer', - }, - { - invoice: 'INV004', - paymentStatus: 'Paid', - totalAmount: '$450.00', - paymentMethod: 'Credit Card', - }, - { - invoice: 'INV005', - paymentStatus: 'Paid', - totalAmount: '$550.00', - paymentMethod: 'PayPal', - }, - { - invoice: 'INV006', - paymentStatus: 'Pending', - totalAmount: '$200.00', - paymentMethod: 'Bank Transfer', - }, - { - invoice: 'INV007', - paymentStatus: 'Unpaid', - totalAmount: '$300.00', - paymentMethod: 'Credit Card', - }, -]; - -const meta = { - title: 'Components/Table/RawTable', - component: RawTable, - subcomponents: { - Body: RawTableBody as ComponentType, - Cell: RawTableCell as ComponentType, - Head: RawTableHead as ComponentType, - Header: RawTableHeader as ComponentType, - Row: RawTableRow as ComponentType, - }, -} satisfies Meta; - -export default meta; -type Story = StoryObj; - -export const Default: Story = { - render: () => ( - - - - Invoice - Status - Method - Amount - - - - {invoices.map(invoice => ( - - - {invoice.invoice} - - {invoice.paymentStatus} - {invoice.paymentMethod} - - {invoice.totalAmount} - - - ))} - - - ), -}; diff --git a/packages/ui/src/components/Table/RawTable/RawTable.styles.css b/packages/ui/src/components/Table/RawTable/RawTable.styles.css index f935ca511e..0373401c97 100644 --- a/packages/ui/src/components/Table/RawTable/RawTable.styles.css +++ b/packages/ui/src/components/Table/RawTable/RawTable.styles.css @@ -14,7 +14,7 @@ * limitations under the License. */ -.bui-TableRoot { +.bui-Table { width: 100%; caption-side: bottom; border-collapse: collapse; @@ -27,6 +27,33 @@ color: var(--bui-fg-primary); } +.bui-TableHeadSortButton { + cursor: pointer; + user-select: none; + display: inline-flex; + align-items: center; + gap: var(--bui-space-1); + + &:hover svg { + opacity: 0.5; + } + + & svg { + opacity: 0; + transition: opacity 0.1s ease-in-out, transform 0.1s ease-in-out; + } + + &[data-sort-order='asc'] svg { + opacity: 1; + transform: rotate(0); + } + + &[data-sort-order='desc'] svg { + opacity: 1; + transform: rotate(180deg); + } +} + .bui-TableBody { color: var(--bui-fg-primary); } diff --git a/packages/ui/src/components/Table/RawTable/RawTable.tsx b/packages/ui/src/components/Table/RawTable/RawTable.tsx index 05bca42a46..d05f8a711f 100644 --- a/packages/ui/src/components/Table/RawTable/RawTable.tsx +++ b/packages/ui/src/components/Table/RawTable/RawTable.tsx @@ -26,95 +26,8 @@ export const RawTable = forwardRef< const { classNames } = useStyles('Table'); return ( - +
); }); + RawTable.displayName = 'RawTable'; - -/** @internal */ -export const RawTableHeader = forwardRef< - HTMLTableSectionElement, - React.HTMLAttributes ->(({ className, ...props }, ref) => { - const { classNames } = useStyles('Table'); - - return ( - - ); -}); -RawTableHeader.displayName = 'RawTableHeader'; - -/** @internal */ -export const RawTableBody = forwardRef< - HTMLTableSectionElement, - React.HTMLAttributes ->(({ className, ...props }, ref) => { - const { classNames } = useStyles('Table'); - - return ( - - ); -}); -RawTableBody.displayName = 'RawTableBody'; - -/** @internal */ -export const RawTableRow = forwardRef< - HTMLTableRowElement, - React.HTMLAttributes ->(({ className, ...props }, ref) => { - const { classNames } = useStyles('Table'); - - return ( - - {props.children} - - ); -}); -RawTableRow.displayName = 'RawTableRow'; - -/** @internal */ -export const RawTableHead = forwardRef< - HTMLTableCellElement, - React.ThHTMLAttributes ->(({ className, ...props }, ref) => { - const { classNames } = useStyles('Table'); - - return ( - + ); +}); +RawTableBody.displayName = 'RawTableBody'; diff --git a/packages/ui/src/components/Table/RawTable/RawTableCaption.tsx b/packages/ui/src/components/Table/RawTable/RawTableCaption.tsx new file mode 100644 index 0000000000..8b7330f873 --- /dev/null +++ b/packages/ui/src/components/Table/RawTable/RawTableCaption.tsx @@ -0,0 +1,36 @@ +/* + * Copyright 2025 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 { useStyles } from '../../../hooks/useStyles'; + +/** @internal */ +export const RawTableCaption = forwardRef< + HTMLTableCaptionElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => { + const { classNames } = useStyles('Table'); + + return ( + ; } return ( - - {headerContent} - , {getSortTitle(header.column.getNextSortingOrder())} - - + ); } diff --git a/packages/ui/src/components/Table/RawTable/RawTableHeader.tsx b/packages/ui/src/components/Table/RawTable/RawTableHeader.tsx new file mode 100644 index 0000000000..fb47936b1f --- /dev/null +++ b/packages/ui/src/components/Table/RawTable/RawTableHeader.tsx @@ -0,0 +1,36 @@ +/* + * Copyright 2025 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 { useStyles } from '../../../hooks/useStyles'; + +/** @internal */ +export const RawTableHeader = forwardRef< + HTMLTableSectionElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => { + const { classNames } = useStyles('Table'); + + return ( + + ); +}); +RawTableHeader.displayName = 'RawTableHeader'; diff --git a/packages/ui/src/components/Table/RawTable/RawTableRow.tsx b/packages/ui/src/components/Table/RawTable/RawTableRow.tsx new file mode 100644 index 0000000000..7b47c2fe38 --- /dev/null +++ b/packages/ui/src/components/Table/RawTable/RawTableRow.tsx @@ -0,0 +1,34 @@ +/* + * Copyright 2025 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 { useStyles } from '../../../hooks/useStyles'; + +/** @internal */ +export const RawTableRow = forwardRef< + HTMLTableRowElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => { + const { classNames } = useStyles('Table'); + + return ( + + {props.children} + + ); +}); +RawTableRow.displayName = 'RawTableRow'; diff --git a/packages/ui/src/components/Table/RawTable/index.ts b/packages/ui/src/components/Table/RawTable/index.ts index 7ef0246902..a510e04431 100644 --- a/packages/ui/src/components/Table/RawTable/index.ts +++ b/packages/ui/src/components/Table/RawTable/index.ts @@ -14,11 +14,10 @@ * limitations under the License. */ -export { - RawTable, - RawTableBody, - RawTableHead, - RawTableHeader, - RawTableRow, - RawTableCell, -} from './RawTable'; +export { RawTable } from './RawTable'; +export { RawTableBody } from './RawTableBody'; +export { RawTableCaption } from './RawTableCaption'; +export { RawTableCell } from './RawTableCell'; +export { RawTableHead } from './RawTableHead'; +export { RawTableHeader } from './RawTableHeader'; +export { RawTableRow } from './RawTableRow'; diff --git a/packages/ui/src/components/Table/RawHeadContent/types.ts b/packages/ui/src/components/Table/RawTable/types.ts similarity index 87% rename from packages/ui/src/components/Table/RawHeadContent/types.ts rename to packages/ui/src/components/Table/RawTable/types.ts index b1757db80b..81cdd00172 100644 --- a/packages/ui/src/components/Table/RawHeadContent/types.ts +++ b/packages/ui/src/components/Table/RawTable/types.ts @@ -17,6 +17,7 @@ import { Header } from '@tanstack/react-table'; /** @internal */ -export interface RawHeadContentProps { +export interface RawTableHeadProps + extends React.ThHTMLAttributes { header: Header; } diff --git a/packages/ui/src/components/Table/Table.stories.tsx b/packages/ui/src/components/Table/Table.stories.tsx index d0242ca123..6790d5e148 100644 --- a/packages/ui/src/components/Table/Table.stories.tsx +++ b/packages/ui/src/components/Table/Table.stories.tsx @@ -21,6 +21,7 @@ import { columns } from './mocked-columns'; import { getCoreRowModel, getPaginationRowModel, + getSortedRowModel, useReactTable, PaginationState, } from '@tanstack/react-table'; @@ -48,8 +49,11 @@ export const Uncontrolled: Story = { columns, getCoreRowModel: getCoreRowModel(), getPaginationRowModel: getPaginationRowModel(), + getSortedRowModel: getSortedRowModel(), }); + console.log(table.getState().sorting); + return ( <>
- ); -}); -RawTableHead.displayName = 'RawTableHead'; - -/** @internal */ -export const RawTableCaption = forwardRef< - HTMLTableCaptionElement, - React.HTMLAttributes ->(({ className, ...props }, ref) => { - const { classNames } = useStyles('Table'); - - return ( -
- ); -}); -RawTableCaption.displayName = 'RawTableCaption'; - -/** @internal */ -export const RawTableCell = forwardRef< - HTMLTableCellElement, - React.TdHTMLAttributes ->(({ className, ...props }, ref) => { - const { classNames } = useStyles('Table'); - - return ( -
- ); -}); -RawTableCell.displayName = 'RawTableCell'; diff --git a/packages/ui/src/components/Table/RawTable/RawTableBody.tsx b/packages/ui/src/components/Table/RawTable/RawTableBody.tsx new file mode 100644 index 0000000000..115d9affd2 --- /dev/null +++ b/packages/ui/src/components/Table/RawTable/RawTableBody.tsx @@ -0,0 +1,32 @@ +/* + * Copyright 2025 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 { useStyles } from '../../../hooks/useStyles'; + +/** @internal */ +export const RawTableBody = forwardRef< + HTMLTableSectionElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => { + const { classNames } = useStyles('Table'); + + return ( +
+ ); +}); +RawTableCaption.displayName = 'RawTableCaption'; diff --git a/packages/ui/src/components/Table/RawHeadContent/index.ts b/packages/ui/src/components/Table/RawTable/RawTableCell.tsx similarity index 56% rename from packages/ui/src/components/Table/RawHeadContent/index.ts rename to packages/ui/src/components/Table/RawTable/RawTableCell.tsx index 9d430e95ec..cb86c9a56b 100644 --- a/packages/ui/src/components/Table/RawHeadContent/index.ts +++ b/packages/ui/src/components/Table/RawTable/RawTableCell.tsx @@ -14,5 +14,19 @@ * limitations under the License. */ -export { RawHeadContent } from './RawHeadContent'; -export type { RawHeadContentProps } from './types'; +import { forwardRef } from 'react'; +import clsx from 'clsx'; +import { useStyles } from '../../../hooks/useStyles'; + +/** @internal */ +export const RawTableCell = forwardRef< + HTMLTableCellElement, + React.TdHTMLAttributes +>(({ className, ...props }, ref) => { + const { classNames } = useStyles('Table'); + + return ( +
+ ); +}); +RawTableCell.displayName = 'RawTableCell'; diff --git a/packages/ui/src/components/Table/RawHeadContent/RawHeadContent.tsx b/packages/ui/src/components/Table/RawTable/RawTableHead.tsx similarity index 64% rename from packages/ui/src/components/Table/RawHeadContent/RawHeadContent.tsx rename to packages/ui/src/components/Table/RawTable/RawTableHead.tsx index f875ed2eee..71fe86015c 100644 --- a/packages/ui/src/components/Table/RawHeadContent/RawHeadContent.tsx +++ b/packages/ui/src/components/Table/RawTable/RawTableHead.tsx @@ -15,11 +15,11 @@ */ import { useCallback, useMemo } from 'react'; -import clsx from 'clsx'; import { flexRender } from '@tanstack/react-table'; import { Icon } from '../../Icon'; import { Hidden } from '../../Hidden'; -import { RawHeadContentProps } from './types'; +import { RawTableHeadProps } from './types'; +import { useStyles } from '../../../hooks/useStyles'; function getSortTitle(nextOrder: string | false) { if (nextOrder === 'asc') { @@ -32,7 +32,8 @@ function getSortTitle(nextOrder: string | false) { } /** @internal */ -export function RawHeadContent({ header }: RawHeadContentProps) { +export function RawTableHead({ header }: RawTableHeadProps) { + const { classNames } = useStyles('Table'); const headerContent = useMemo( () => flexRender(header.column.columnDef.header, header.getContext()), [header], @@ -50,32 +51,25 @@ export function RawHeadContent({ header }: RawHeadContentProps) { ); if (!header.column.getCanSort()) { - return headerContent; + return {headerContent} + + {headerContent} + , {getSortTitle(header.column.getNextSortingOrder())} + + +
diff --git a/packages/ui/src/components/Table/Table.styles.css b/packages/ui/src/components/Table/Table.styles.css deleted file mode 100644 index 78c463a883..0000000000 --- a/packages/ui/src/components/Table/Table.styles.css +++ /dev/null @@ -1,37 +0,0 @@ -.bui-DataTableRoot { - display: flex; - flex-direction: column; - gap: var(--bui-space-3); -} - -.bui-DataTableRoot--sort { - cursor: pointer; - user-select: none; - display: inline-flex; - align-items: center; - gap: var(--bui-space-1); -} - -.bui-DataTableRoot--sort .bui-DataTableRoot--unsorted { - opacity: 0; - transition: opacity 0.1s ease-in-out, transform 0.1s ease-in-out; -} - -.bui-DataTableRoot--sort:hover .bui-DataTableRoot--unsorted, -.bui-DataTableRoot--sort:focus .bui-DataTableRoot--unsorted { - opacity: 0.5; -} - -.bui-DataTableRoot--sort .bui-DataTableRoot--sorted-asc, -.bui-DataTableRoot--sort:hover .bui-DataTableRoot--sorted-asc, -.bui-DataTableRoot--sort:focus .bui-DataTableRoot--sorted-asc { - opacity: 1; - transform: rotate(0); -} - -.bui-DataTableRoot--sort .bui-DataTableRoot--sorted-desc, -.bui-DataTableRoot--sort:hover .bui-DataTableRoot--sorted-desc, -.bui-DataTableRoot--sort:focus .bui-DataTableRoot--sorted-desc { - opacity: 1; - transform: rotate(180deg); -} diff --git a/packages/ui/src/components/Table/Table.tsx b/packages/ui/src/components/Table/Table.tsx index aafbcdf01f..1e3afda6e2 100644 --- a/packages/ui/src/components/Table/Table.tsx +++ b/packages/ui/src/components/Table/Table.tsx @@ -24,7 +24,6 @@ import { RawTableBody, RawTableCell, } from './RawTable'; -import { RawHeadContent } from './RawHeadContent'; import { flexRender } from '@tanstack/react-table'; function getAriaSort(sortDirection: string | false) { @@ -58,16 +57,17 @@ export function Table( {table.getHeaderGroups().map(headerGroup => ( {headerGroup.headers.map(header => { + if (header.isPlaceholder) { + return null; + } + return ( - {header.isPlaceholder ? null : ( - - )} - + header={header} + /> ); })} diff --git a/packages/ui/src/components/Table/mocked-columns.tsx b/packages/ui/src/components/Table/mocked-columns.tsx index bfaf9fd966..1795c90dfa 100644 --- a/packages/ui/src/components/Table/mocked-columns.tsx +++ b/packages/ui/src/components/Table/mocked-columns.tsx @@ -33,13 +33,11 @@ export const columns: ColumnDef[] = [ /> ), cell: ({ row }) => ( - + row.toggleSelected(checked)} + aria-label="Select row" + /> ), enableSorting: false, enableHiding: false, @@ -56,6 +54,7 @@ export const columns: ColumnDef[] = [ /> ), size: 450, + enableSorting: false, }, { accessorKey: 'owner', diff --git a/packages/ui/src/css/components.css b/packages/ui/src/css/components.css index 5e55644da8..e23e0d8209 100644 --- a/packages/ui/src/css/components.css +++ b/packages/ui/src/css/components.css @@ -22,13 +22,6 @@ @import '../components/Checkbox/styles.css'; @import '../components/Collapsible/Collapsible.styles.css'; @import '../components/Container/styles.css'; - -@import '../components/Table/Table.styles.css'; -@import '../components/Table/RawTable/RawTable.styles.css'; -@import '../components/Table/TableCellText/TableCellText.styles.css'; -@import '../components/Table/TableCellProfile/TableCellProfile.styles.css'; -@import '../components/Table/TablePagination/TablePagination.styles.css'; - @import '../components/FieldError/FieldError.styles.css'; @import '../components/FieldLabel/FieldLabel.styles.css'; @import '../components/Flex/styles.css'; @@ -41,6 +34,12 @@ @import '../components/Menu/Menu.styles.css'; @import '../components/Popover/Popover.styles.css'; @import '../components/RadioGroup/RadioGroup.styles.css'; + +@import '../components/Table/RawTable/RawTable.styles.css'; +@import '../components/Table/TableCellText/TableCellText.styles.css'; +@import '../components/Table/TableCellProfile/TableCellProfile.styles.css'; +@import '../components/Table/TablePagination/TablePagination.styles.css'; + @import '../components/Tabs/Tabs.styles.css'; @import '../components/Text/styles.css'; @import '../components/TextField/TextField.styles.css'; diff --git a/packages/ui/src/utils/componentDefinitions.ts b/packages/ui/src/utils/componentDefinitions.ts index 5f48c8524e..83f6470dbf 100644 --- a/packages/ui/src/utils/componentDefinitions.ts +++ b/packages/ui/src/utils/componentDefinitions.ts @@ -231,11 +231,12 @@ export const componentDefinitions = { }, Table: { classNames: { - root: 'bui-TableRoot', + table: 'bui-Table', header: 'bui-TableHeader', body: 'bui-TableBody', row: 'bui-TableRow', head: 'bui-TableHead', + headSortButton: 'bui-TableHeadSortButton', caption: 'bui-TableCaption', cell: 'bui-TableCell', cellText: 'bui-TableCellText',
- row.toggleSelected(checked)} - aria-label="Select row" - /> -