diff options
author | Ismail Cherri <ismail.cherri@sonarsource.com> | 2024-04-15 17:57:32 +0200 |
---|---|---|
committer | Matteo Mara <matteo.mara@sonarsource.com> | 2024-04-30 10:59:04 +0200 |
commit | ac0a2bdb2cb1ad49a2effc5ec48e087308ac767c (patch) | |
tree | 8593337741460339168ccdda233a66de99a655df /server/sonar-web/design-system/src/components | |
parent | bc73a8589ffcd7e32a2e32b72be986849ad2c16a (diff) | |
download | sonarqube-ac0a2bdb2cb1ad49a2effc5ec48e087308ac767c.tar.gz sonarqube-ac0a2bdb2cb1ad49a2effc5ec48e087308ac767c.zip |
SONAR-22049 Allow table to use grid template and column widths
Diffstat (limited to 'server/sonar-web/design-system/src/components')
3 files changed, 0 insertions, 381 deletions
diff --git a/server/sonar-web/design-system/src/components/Table.tsx b/server/sonar-web/design-system/src/components/Table.tsx deleted file mode 100644 index 44c09e399fe..00000000000 --- a/server/sonar-web/design-system/src/components/Table.tsx +++ /dev/null @@ -1,272 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2024 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -import styled from '@emotion/styled'; -import classNames from 'classnames'; -import { times } from 'lodash'; -import { ComponentProps, createContext, ReactNode, useContext } from 'react'; -import tw from 'twin.macro'; -import { themeBorder, themeColor } from '../helpers'; -import { FCProps } from '../types/misc'; - -export interface TableProps extends ComponentProps<'table'> { - caption?: ReactNode; - columnCount: number; - columnWidths?: Array<number | string>; - header?: ReactNode; - noHeaderTopBorder?: boolean; - noSidePadding?: boolean; - withRoundedBorder?: boolean; -} - -export function Table(props: TableProps) { - const { - className, - columnCount, - columnWidths = [], - header, - caption, - children, - noHeaderTopBorder, - noSidePadding, - withRoundedBorder, - ...rest - } = props; - - return ( - <StyledTable - className={classNames( - { - 'no-header-top-border': noHeaderTopBorder, - 'no-side-padding': noSidePadding, - 'with-rounded-border': withRoundedBorder, - }, - className, - )} - {...rest} - > - <colgroup> - {times(columnCount, (i) => ( - <col key={i} width={columnWidths[i] ?? 'auto'} /> - ))} - </colgroup> - - {caption && ( - <caption> - <div className="sw-py-4 sw-text-middle sw-flex sw-justify-center sw-body-sm-highlight"> - {caption} - </div> - </caption> - )} - - {header && ( - <thead> - <CellTypeContext.Provider value="th">{header}</CellTypeContext.Provider> - </thead> - )} - - <tbody>{children}</tbody> - </StyledTable> - ); -} - -export const TableSeparator = styled.tr` - ${tw`sw-h-4`} - border-top: ${themeBorder('default')}; -`; - -export const TableRow = styled.tr` - td, - th { - border-top: ${themeBorder('default')}; - } - - .no-header-top-border & th { - ${tw`sw-border-t-0`} - } - - td:first-of-type, - th:first-of-type, - td:last-child, - th:last-child { - border-right: ${themeBorder('default', 'transparent')}; - border-left: ${themeBorder('default', 'transparent')}; - } - - .no-side-padding & { - td:first-of-type, - th:first-of-type { - ${tw`sw-pl-0`} - } - - td:last-child, - th:last-child { - ${tw`sw-pr-0`} - } - } - - &:last-child > td { - border-bottom: ${themeBorder('default')}; - } -`; - -interface TableRowInteractiveProps extends FCProps<typeof TableRow> { - selected?: boolean; -} - -function TableRowInteractiveBase({ - className, - children, - selected, - ...props -}: TableRowInteractiveProps) { - return ( - <TableRow aria-selected={selected} className={classNames(className, { selected })} {...props}> - {children} - </TableRow> - ); -} - -export const TableRowInteractive = styled(TableRowInteractiveBase)` - &:hover > td, - &.selected > td, - &.selected > th, - th.selected, - td.selected { - background: ${themeColor('tableRowHover')}; - } - - &.selected > td:first-of-type, - &.selected > th:first-of-type, - th.selected:first-of-type, - td.selected:first-of-type { - border-left: ${themeBorder('default', 'tableRowSelected')}; - } - - &.selected > td, - &.selected > th, - th.selected, - td.selected { - border-top: ${themeBorder('default', 'tableRowSelected')}; - border-bottom: ${themeBorder('default', 'tableRowSelected')}; - } - - &.selected > td:last-child, - &.selected > th:last-child, - th.selected:last-child, - td.selected:last-child { - border-right: ${themeBorder('default', 'tableRowSelected')}; - } - - &.selected + &:not(.selected) > td { - border-top: none; - } -`; - -const CellTypeContext = createContext<'th' | 'td'>('td'); -type CellComponentProps = ComponentProps<'th' | 'td'>; - -export function CellComponent(props: CellComponentProps) { - const containerType = useContext(CellTypeContext); - return <CellComponentStyled as={containerType} {...props} />; -} - -export function ContentCell({ - children, - cellClassName, - className, - ...props -}: CellComponentProps & { cellClassName?: string }) { - return ( - <CellComponent className={cellClassName} {...props}> - <div - className={classNames('sw-text-left sw-justify-start sw-flex sw-items-center', className)} - > - {children} - </div> - </CellComponent> - ); -} - -export function NumericalCell({ children, ...props }: CellComponentProps) { - return ( - <CellComponent {...props}> - <div className="sw-text-right sw-justify-end sw-flex sw-items-center">{children}</div> - </CellComponent> - ); -} - -export function RatingCell({ children, ...props }: CellComponentProps) { - return ( - <CellComponent {...props}> - <div className="sw-text-right sw-justify-end sw-flex sw-items-center">{children}</div> - </CellComponent> - ); -} - -export function ActionCell({ children, ...props }: CellComponentProps) { - return ( - <CellComponent {...props}> - <div className="sw-text-right sw-justify-end sw-flex sw-items-center">{children}</div> - </CellComponent> - ); -} - -export function CheckboxCell({ children, ...props }: CellComponentProps) { - return ( - <CellComponent {...props}> - <div className="sw-text-center sw-justify-center sw-flex sw-items-center">{children}</div> - </CellComponent> - ); -} - -const StyledTable = styled.table` - width: 100%; - border-collapse: collapse; - - &.with-rounded-border { - border-collapse: separate; - border: ${themeBorder('default', 'breakdownBorder')}; - ${tw`sw-rounded-1`}; - - th:first-of-type { - ${tw`sw-rounded-tl-1`}; - } - th:last-of-type { - ${tw`sw-rounded-tr-1`}; - } - - tr:last-child > td { - border-bottom: none; - } - } -`; - -const CellComponentStyled = styled.td` - color: ${themeColor('pageContent')}; - ${tw`sw-body-sm`} - ${tw`sw-py-4 sw-px-2`} - ${tw`sw-align-middle`} - - thead > tr > & { - color: ${themeColor('pageTitle')}; - - ${tw`sw-body-sm-highlight`} - } -`; diff --git a/server/sonar-web/design-system/src/components/__tests__/Table-test.tsx b/server/sonar-web/design-system/src/components/__tests__/Table-test.tsx deleted file mode 100644 index c8e3bf8e418..00000000000 --- a/server/sonar-web/design-system/src/components/__tests__/Table-test.tsx +++ /dev/null @@ -1,108 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2024 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -import { screen } from '@testing-library/react'; -import { render } from '../../helpers/testUtils'; -import { - CheckboxCell, - ContentCell, - NumericalCell, - Table, - TableProps, - TableRow, - TableRowInteractive, -} from '../Table'; - -it('check that the html structure and style is correct for a regular table', () => { - renderTable({ - columnCount: 3, - 'aria-colcount': 3, - header: ( - <TableRow> - <ContentCell>ContentCellHeader</ContentCell> - <NumericalCell>NumericalCellHeader</NumericalCell> - <CheckboxCell>CheckboxCellHeader</CheckboxCell> - </TableRow> - ), - children: ( - <> - <TableRowInteractive> - <ContentCell>ContentCell 1</ContentCell> - <NumericalCell>NumericalCell 1</NumericalCell> - <CheckboxCell>CheckboxCell 1</CheckboxCell> - </TableRowInteractive> - <TableRowInteractive selected> - <ContentCell>ContentCell 2</ContentCell> - <NumericalCell>NumericalCell 2</NumericalCell> - <CheckboxCell>CheckboxCell 2</CheckboxCell> - </TableRowInteractive> - <TableRow> - <ContentCell aria-colspan={3}>ContentCell 3</ContentCell> - </TableRow> - <TableRowInteractive> - <NumericalCell aria-colindex={2}>NumericalCell 4</NumericalCell> - <CheckboxCell aria-colindex={3}>CheckboxCell 4</CheckboxCell> - </TableRowInteractive> - </> - ), - }); - - // Table should have accessible attribute - expect(screen.getByRole('table')).toHaveAttribute('aria-colcount', '3'); - - // Rows should have accessible attributes - expect( - screen.getByRole('row', { name: 'ContentCellHeader NumericalCellHeader CheckboxCellHeader' }), - ).toBeInTheDocument(); - expect( - screen.getByRole('row', { - name: 'ContentCell 1 NumericalCell 1 CheckboxCell 1', - }), - ).toBeInTheDocument(); - expect( - screen.getByRole('row', { - name: 'ContentCell 1 NumericalCell 1 CheckboxCell 1', - }), - ).not.toHaveAttribute('aria-selected'); - expect( - screen.getByRole('row', { - selected: true, - name: 'ContentCell 2 NumericalCell 2 CheckboxCell 2', - }), - ).toBeInTheDocument(); - expect( - screen.getByRole('row', { - name: 'NumericalCell 4 CheckboxCell 4', - }), - ).toBeInTheDocument(); - - // Cells should have accessible attributes - expect(screen.getByRole('cell', { name: 'NumericalCell 4' })).toHaveAttribute( - 'aria-colindex', - '2', - ); - expect(screen.getByRole('cell', { name: 'CheckboxCell 4' })).toHaveAttribute( - 'aria-colindex', - '3', - ); -}); - -function renderTable(props: TableProps) { - return render(<Table {...props}>{props.children}</Table>); -} diff --git a/server/sonar-web/design-system/src/components/index.ts b/server/sonar-web/design-system/src/components/index.ts index ae2932330ec..35e06bdc597 100644 --- a/server/sonar-web/design-system/src/components/index.ts +++ b/server/sonar-web/design-system/src/components/index.ts @@ -71,7 +71,6 @@ export * from './SonarQubeLogo'; export { Spinner } from './Spinner'; export * from './SpotlightTour'; export * from './Switch'; -export * from './Table'; export * from './Tabs'; export * from './Tags'; export * from './Text'; |