aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/design-system/src/components
diff options
context:
space:
mode:
authorIsmail Cherri <ismail.cherri@sonarsource.com>2024-04-15 17:57:32 +0200
committerMatteo Mara <matteo.mara@sonarsource.com>2024-04-30 10:59:04 +0200
commitac0a2bdb2cb1ad49a2effc5ec48e087308ac767c (patch)
tree8593337741460339168ccdda233a66de99a655df /server/sonar-web/design-system/src/components
parentbc73a8589ffcd7e32a2e32b72be986849ad2c16a (diff)
downloadsonarqube-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')
-rw-r--r--server/sonar-web/design-system/src/components/Table.tsx272
-rw-r--r--server/sonar-web/design-system/src/components/__tests__/Table-test.tsx108
-rw-r--r--server/sonar-web/design-system/src/components/index.ts1
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';