diff --git a/package-lock.json b/package-lock.json index fe0ead305..c001668ab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -39,7 +39,7 @@ "react": "^18.2.0", "react-chartjs-2": "^4.2.0", "react-clipboard.js": "^2.0.16", - "react-data-table-component": "^6.11.7", + "react-data-table-component": "^7.5.2", "react-dom": "^18.1.0", "react-dotdotdot": "^1.3.1", "react-modal": "^3.15.1", @@ -32361,11 +32361,6 @@ "resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz", "integrity": "sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA=" }, - "node_modules/lodash.orderby": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.orderby/-/lodash.orderby-4.6.0.tgz", - "integrity": "sha1-5pfwTOXXhSL1TZM4syuBozk+TrM=" - }, "node_modules/lodash.pickby": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.pickby/-/lodash.pickby-4.6.0.tgz", @@ -36391,17 +36386,15 @@ } }, "node_modules/react-data-table-component": { - "version": "6.11.8", - "resolved": "https://registry.npmjs.org/react-data-table-component/-/react-data-table-component-6.11.8.tgz", - "integrity": "sha512-ukKJKaKNDU5+jEEZFo16+4zwQPRvw1Z13S7FOj4dr73JWRf/lKkE108jciK2tj1JPMub3qXG2h0zXDn5y2WUfQ==", + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/react-data-table-component/-/react-data-table-component-7.5.2.tgz", + "integrity": "sha512-sOmeEEZiORJcnzf8fwcwA5+JbhIChjf+tQV/dLYvlhU8UT8rJZ33aBSOJNjNYq/5+t3lj/xCJXtSa2kgoZTDVQ==", "dependencies": { - "deepmerge": "^4.2.2", - "lodash.orderby": "^4.6.0", - "shortid": "^2.2.16" + "deepmerge": "^4.2.2" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0", - "styled-components": "^4.0.0 || ^5.0.0" + "react": ">= 16.8.3", + "styled-components": ">= 4" } }, "node_modules/react-docgen": { @@ -38606,19 +38599,6 @@ "node": ">= 0.10" } }, - "node_modules/shortid": { - "version": "2.2.16", - "resolved": "https://registry.npmjs.org/shortid/-/shortid-2.2.16.tgz", - "integrity": "sha512-Ugt+GIZqvGXCIItnsL+lvFJOiN7RYqlGy7QE41O3YC1xbNSeDGIRO7xg2JJXIAj1cAGnOeC1r7/T9pgrtQbv4g==", - "dependencies": { - "nanoid": "^2.1.0" - } - }, - "node_modules/shortid/node_modules/nanoid": { - "version": "2.1.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-2.1.11.tgz", - "integrity": "sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA==" - }, "node_modules/side-channel": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", @@ -68296,11 +68276,6 @@ "resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz", "integrity": "sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA=" }, - "lodash.orderby": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.orderby/-/lodash.orderby-4.6.0.tgz", - "integrity": "sha1-5pfwTOXXhSL1TZM4syuBozk+TrM=" - }, "lodash.pickby": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.pickby/-/lodash.pickby-4.6.0.tgz", @@ -71457,13 +71432,11 @@ } }, "react-data-table-component": { - "version": "6.11.8", - "resolved": "https://registry.npmjs.org/react-data-table-component/-/react-data-table-component-6.11.8.tgz", - "integrity": "sha512-ukKJKaKNDU5+jEEZFo16+4zwQPRvw1Z13S7FOj4dr73JWRf/lKkE108jciK2tj1JPMub3qXG2h0zXDn5y2WUfQ==", + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/react-data-table-component/-/react-data-table-component-7.5.2.tgz", + "integrity": "sha512-sOmeEEZiORJcnzf8fwcwA5+JbhIChjf+tQV/dLYvlhU8UT8rJZ33aBSOJNjNYq/5+t3lj/xCJXtSa2kgoZTDVQ==", "requires": { - "deepmerge": "^4.2.2", - "lodash.orderby": "^4.6.0", - "shortid": "^2.2.16" + "deepmerge": "^4.2.2" } }, "react-docgen": { @@ -73239,21 +73212,6 @@ } } }, - "shortid": { - "version": "2.2.16", - "resolved": "https://registry.npmjs.org/shortid/-/shortid-2.2.16.tgz", - "integrity": "sha512-Ugt+GIZqvGXCIItnsL+lvFJOiN7RYqlGy7QE41O3YC1xbNSeDGIRO7xg2JJXIAj1cAGnOeC1r7/T9pgrtQbv4g==", - "requires": { - "nanoid": "^2.1.0" - }, - "dependencies": { - "nanoid": { - "version": "2.1.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-2.1.11.tgz", - "integrity": "sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA==" - } - } - }, "side-channel": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", diff --git a/package.json b/package.json index 170856c2a..9dab7fb5e 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "react": "^18.2.0", "react-chartjs-2": "^4.2.0", "react-clipboard.js": "^2.0.16", - "react-data-table-component": "^6.11.7", + "react-data-table-component": "^7.5.2", "react-dom": "^18.1.0", "react-dotdotdot": "^1.3.1", "react-modal": "^3.15.1", diff --git a/src/components/@shared/PoolTransactions/index.tsx b/src/components/@shared/PoolTransactions/index.tsx index d45760b66..8e9c870e5 100644 --- a/src/components/@shared/PoolTransactions/index.tsx +++ b/src/components/@shared/PoolTransactions/index.tsx @@ -1,6 +1,6 @@ import React, { ReactElement, useCallback, useEffect, useState } from 'react' import Time from '@shared/atoms/Time' -import Table from '@shared/atoms/Table' +import Table, { TableOceanColumn } from '@shared/atoms/Table' import AssetTitle from '@shared/AssetList/AssetListTitle' import { useUserPreferences } from '@context/UserPreferences' import { gql } from 'urql' @@ -84,38 +84,30 @@ export interface PoolTransaction extends TransactionHistoryPoolTransactions { asset: Asset } -const columns = [ +const columns: TableOceanColumn[] = [ { name: 'Title', - selector: function getTitleRow(row: PoolTransaction) { - return - } + selector: (row) => <Title row={row} /> }, { name: 'Data Set', - selector: function getAssetRow(row: PoolTransaction) { - return <AssetTitle asset={row.asset} /> - } + selector: (row) => <AssetTitle asset={row.asset} /> }, { name: 'Network', - selector: function getNetwork(row: PoolTransaction) { - return <NetworkName networkId={row.networkId} /> - }, + selector: (row) => <NetworkName networkId={row.networkId} />, maxWidth: '12rem' }, { name: 'Time', - selector: function getTimeRow(row: PoolTransaction) { - return ( - <Time - className={styles.time} - date={row.timestamp.toString()} - relative - isUnix - /> - ) - }, + selector: (row) => ( + <Time + className={styles.time} + date={row.timestamp.toString()} + relative + isUnix + /> + ), maxWidth: '10rem' } ] diff --git a/src/components/@shared/atoms/Table/Empty.module.css b/src/components/@shared/atoms/Table/Empty.module.css new file mode 100644 index 000000000..37da6b45b --- /dev/null +++ b/src/components/@shared/atoms/Table/Empty.module.css @@ -0,0 +1,7 @@ +.empty { + width: 100%; + text-align: left; + color: var(--color-secondary); + font-size: var(--font-size-small); + font-style: italic; +} diff --git a/src/components/@shared/atoms/Table/Empty.tsx b/src/components/@shared/atoms/Table/Empty.tsx new file mode 100644 index 000000000..f3ca115ce --- /dev/null +++ b/src/components/@shared/atoms/Table/Empty.tsx @@ -0,0 +1,6 @@ +import React, { ReactElement } from 'react' +import styles from './Empty.module.css' + +export default function Empty({ message }: { message?: string }): ReactElement { + return <div className={styles.empty}>{message || 'No results found'}</div> +} diff --git a/src/components/@shared/atoms/Table/_styles.ts b/src/components/@shared/atoms/Table/_styles.ts new file mode 100644 index 000000000..275461fb1 --- /dev/null +++ b/src/components/@shared/atoms/Table/_styles.ts @@ -0,0 +1,57 @@ +import { createTheme, TableStyles, Theme } from 'react-data-table-component' + +// https://github.com/jbetancur/react-data-table-component/blob/master/src/DataTable/themes.ts +const theme: Partial<Theme> = { + text: { + primary: 'var(--font-color-text)', + secondary: 'var(--color-secondary)', + disabled: 'var(--color-secondary)' + }, + background: { + default: 'transparent' + }, + divider: { + default: 'var(--border-color)' + }, + button: { + default: 'var(--font-color-text)', + focus: 'var(--color-primary)', + hover: 'var(--color-primary)', + disabled: 'var(--color-secondary)' + } +} + +createTheme('ocean', theme) + +// https://github.com/jbetancur/react-data-table-component/blob/master/src/DataTable/styles.ts +export const customStyles: TableStyles = { + table: { + style: { + scrollbarWidth: 'thin' + } + }, + head: { + style: { + fontSize: 'var(--font-size-small)', + fontWeight: 'var(--font-weight-base)' + } + }, + headCells: { + style: { + textTransform: 'uppercase', + color: 'var(--color-secondary)', + fontSize: 'var(--font-size-small)' + } + }, + cells: { + style: { + minWidth: '0 !important' + } + }, + rows: { + style: { + fontSize: 'var(--font-size-small)', + fontWeight: 'var(--font-weight-base)' + } + } +} diff --git a/src/components/@shared/atoms/Table/index.module.css b/src/components/@shared/atoms/Table/index.module.css deleted file mode 100644 index 7e3b076f8..000000000 --- a/src/components/@shared/atoms/Table/index.module.css +++ /dev/null @@ -1,82 +0,0 @@ -.table div { - background-color: transparent !important; -} - -.table [role='table'], -.table [role='row'] { - color: var(--font-color-text); - font-size: var(--font-size-small); - min-width: 0; -} - -.table [class~='rdt_TableCol'] { - border-bottom: 1px solid var(--border-color); -} - -.table [role='columnheader'] { - text-transform: uppercase; - font-size: var(--font-size-small); -} - -.table [role='columnheader'] > span, -.table [role='columnheader'] > div { - color: var(--color-secondary); -} - -.table [role='gridcell'] { - min-width: 0; -} - -.table [role='row'] { - border-bottom: 1px solid var(--border-color) !important; -} - -.table + div [class*='rdt_Pagination'] { - font-size: var(--font-size-small); - font-weight: var(--font-weight-bold); - color: var(--color-secondary); - background: none; - min-height: 0; - padding-top: calc(var(--spacer) / 2); -} - -.table + div [class*='rdt_Pagination'] svg { - fill: var(--color-secondary); -} - -.table + div [class*='rdt_Pagination'] [disabled] svg { - fill: var(--background-highlight); -} - -.table + div [class*='rdt_Pagination'] button:hover:not(:disabled) { - background: none; -} - -.table + div [class*='rdt_Pagination'] button:hover:not(:disabled) svg { - fill: var(--brand-pink); -} - -.table + div [class*='rdt_Pagination'] button[aria-label='First Page'], -.table + div [class*='rdt_Pagination'] button[aria-label='Last Page'] { - display: none; -} - -.table [class*='Table-module'] { - scrollbar-width: thin; -} - -.empty { - width: 100%; - text-align: left; - color: var(--color-secondary); - font-size: var(--font-size-small); - font-style: italic; -} - -.arrow { - composes: arrow from '@shared/Pagination/index.module.css'; -} - -.previous { - composes: previous from '@shared/Pagination/index.module.css'; -} diff --git a/src/components/@shared/atoms/Table/index.stories.tsx b/src/components/@shared/atoms/Table/index.stories.tsx index 13bdb7794..452518bbd 100644 --- a/src/components/@shared/atoms/Table/index.stories.tsx +++ b/src/components/@shared/atoms/Table/index.stories.tsx @@ -1,6 +1,6 @@ import React from 'react' import { ComponentStory, ComponentMeta } from '@storybook/react' -import Table, { TableProps } from '@shared/atoms/Table' +import Table, { TableOceanProps } from '@shared/atoms/Table' export default { title: 'Component/@shared/atoms/Table', @@ -10,7 +10,7 @@ export default { const Template: ComponentStory<typeof Table> = (args) => <Table {...args} /> interface Props { - args: TableProps + args: TableOceanProps<any> } const columns = [ diff --git a/src/components/@shared/atoms/Table/index.tsx b/src/components/@shared/atoms/Table/index.tsx index 17f7104ca..a00cd9c5f 100644 --- a/src/components/@shared/atoms/Table/index.tsx +++ b/src/components/@shared/atoms/Table/index.tsx @@ -1,10 +1,19 @@ -import React, { ReactElement, ReactNode } from 'react' -import DataTable, { IDataTableProps } from 'react-data-table-component' +import React, { ReactElement } from 'react' +import DataTable, { TableProps, TableColumn } from 'react-data-table-component' import Loader from '../Loader' import Pagination from '@shared/Pagination' -import styles from './index.module.css' +import { PaginationComponent } from 'react-data-table-component/dist/src/DataTable/types' +import Empty from './Empty' +import { customStyles } from './_styles' -export interface TableProps extends IDataTableProps { +// Hack in support for returning components for each row, as this works, +// but is not supported by the typings. +export interface TableOceanColumn<T> extends TableColumn<T> { + selector?: (row: T) => any +} + +export interface TableOceanProps<T> extends TableProps<T> { + columns: TableOceanColumn<T>[] isLoading?: boolean emptyMessage?: string sortField?: string @@ -12,10 +21,6 @@ export interface TableProps extends IDataTableProps { className?: string } -function Empty({ message }: { message?: string }): ReactElement { - return <div className={styles.empty}>{message || 'No results found'}</div> -} - export default function Table({ data, columns, @@ -27,22 +32,24 @@ export default function Table({ sortAsc, className, ...props -}: TableProps): ReactElement { +}: TableOceanProps<any>): ReactElement { return ( - <DataTable - columns={columns} - data={data} - className={className ? styles.table + ` ${className}` : styles.table} - noHeader - pagination={pagination || data?.length >= 9} - paginationPerPage={paginationPerPage || 10} - noDataComponent={<Empty message={emptyMessage} />} - progressPending={isLoading} - progressComponent={<Loader />} - paginationComponent={Pagination as unknown as ReactNode} - defaultSortField={sortField} - defaultSortAsc={sortAsc} - {...props} - /> + <div className={className}> + <DataTable + columns={columns} + data={data} + pagination={pagination || data?.length >= 9} + paginationPerPage={paginationPerPage || 10} + noDataComponent={<Empty message={emptyMessage} />} + progressPending={isLoading} + progressComponent={<Loader />} + paginationComponent={Pagination as unknown as PaginationComponent} + defaultSortFieldId={sortField} + defaultSortAsc={sortAsc} + theme="ocean" + customStyles={customStyles} + {...props} + /> + </div> ) } diff --git a/src/components/@shared/atoms/Tabs/index.module.css b/src/components/@shared/atoms/Tabs/index.module.css index 3339cd988..6204392b5 100644 --- a/src/components/@shared/atoms/Tabs/index.module.css +++ b/src/components/@shared/atoms/Tabs/index.module.css @@ -10,6 +10,7 @@ padding: calc(var(--spacer) / 2); display: flex; overflow-x: auto; + scrollbar-width: none; } .tab { diff --git a/src/components/Home/Bookmarks.tsx b/src/components/Home/Bookmarks.tsx index 36cb299b0..1ec9314d0 100644 --- a/src/components/Home/Bookmarks.tsx +++ b/src/components/Home/Bookmarks.tsx @@ -1,6 +1,6 @@ import { useUserPreferences } from '@context/UserPreferences' import React, { ReactElement, useEffect, useState } from 'react' -import Table from '@shared/atoms/Table' +import Table, { TableOceanColumn } from '@shared/atoms/Table' import { LoggerInstance } from '@oceanprotocol/lib' import Price from '@shared/Price' import Tooltip from '@shared/atoms/Tooltip' @@ -12,10 +12,10 @@ import { getAccessDetailsForAssets } from '@utils/accessDetailsAndPricing' import { useWeb3 } from '@context/Web3' import { useMarketMetadata } from '@context/MarketMetadata' -const columns = [ +const columns: TableOceanColumn<AssetExtended>[] = [ { name: 'Data Set', - selector: function getAssetRow(row: AssetExtended) { + selector: (row) => { const { metadata } = row return <AssetTitle title={metadata.name} asset={row} /> }, @@ -24,20 +24,16 @@ const columns = [ }, { name: 'Datatoken Symbol', - selector: function getAssetRow(row: AssetExtended) { - return ( - <Tooltip content={row.datatokens[0].name}> - <>{row.datatokens[0].symbol}</> - </Tooltip> - ) - }, + selector: (row) => ( + <Tooltip content={row.datatokens[0].name}> + <>{row.datatokens[0].symbol}</> + </Tooltip> + ), maxWidth: '10rem' }, { name: 'Price', - selector: function getAssetRow(row: AssetExtended) { - return <Price accessDetails={row.accessDetails} size="small" /> - }, + selector: (row) => <Price accessDetails={row.accessDetails} size="small" />, right: true } ] diff --git a/src/components/Profile/History/ComputeJobs/index.tsx b/src/components/Profile/History/ComputeJobs/index.tsx index c3643ed77..a395deede 100644 --- a/src/components/Profile/History/ComputeJobs/index.tsx +++ b/src/components/Profile/History/ComputeJobs/index.tsx @@ -1,7 +1,7 @@ import React, { ReactElement, useEffect, useState, useCallback } from 'react' import Time from '@shared/atoms/Time' import { LoggerInstance } from '@oceanprotocol/lib' -import Table from '@shared/atoms/Table' +import Table, { TableOceanColumn } from '@shared/atoms/Table' import Button from '@shared/atoms/Button' import { useWeb3 } from '@context/Web3' import Details from './Details' @@ -19,46 +19,33 @@ export function Status({ children }: { children: string }): ReactElement { return <div className={styles.status}>{children}</div> } -const columns = [ +const columns: TableOceanColumn<ComputeJobMetaData>[] = [ { name: 'Data Set', - selector: function getAssetRow(row: ComputeJobMetaData) { - return <AssetListTitle did={row.inputDID[0]} title={row.assetName} /> - } + selector: (row) => ( + <AssetListTitle did={row.inputDID[0]} title={row.assetName} /> + ) }, { name: 'Network', - selector: function getNetwork(row: ComputeJobMetaData) { - return <NetworkName networkId={row.networkId} /> - } + selector: (row) => <NetworkName networkId={row.networkId} /> }, { name: 'Created', - selector: function getTimeRow(row: ComputeJobMetaData) { - return <Time date={row.dateCreated} isUnix relative /> - } + selector: (row) => <Time date={row.dateCreated} isUnix relative /> }, { name: 'Finished', - selector: function getTimeRow(row: ComputeJobMetaData) { - return row.dateFinished ? ( - <Time date={row.dateFinished} isUnix relative /> - ) : ( - '' - ) - } + selector: (row) => + row.dateFinished ? <Time date={row.dateFinished} isUnix relative /> : '' }, { name: 'Status', - selector: function getStatus(row: ComputeJobMetaData) { - return <Status>{row.statusText}</Status> - } + selector: (row) => <Status>{row.statusText}</Status> }, { name: 'Actions', - selector: function getActions(row: ComputeJobMetaData) { - return <Details job={row} /> - } + selector: (row) => <Details job={row} /> } ] @@ -125,7 +112,7 @@ export default function ComputeJobs({ columns={minimal ? columnsMinimal : columns} data={jobs} isLoading={isLoading} - defaultSortField="row.dateCreated" + defaultSortFieldId="row.dateCreated" defaultSortAsc={false} emptyMessage={chainIds.length === 0 ? 'No network selected' : null} /> diff --git a/src/components/Profile/History/Downloads.tsx b/src/components/Profile/History/Downloads.tsx index f56343700..dfd0bb8c5 100644 --- a/src/components/Profile/History/Downloads.tsx +++ b/src/components/Profile/History/Downloads.tsx @@ -1,34 +1,27 @@ import React, { ReactElement } from 'react' -import Table from '@shared/atoms/Table' +import Table, { TableOceanColumn } from '@shared/atoms/Table' import Time from '@shared/atoms/Time' import AssetTitle from '@shared/AssetList/AssetListTitle' import NetworkName from '@shared/NetworkName' import { useProfile } from '@context/Profile' import { useUserPreferences } from '@context/UserPreferences' -const columns = [ + +const columns: TableOceanColumn<DownloadedAsset>[] = [ { name: 'Data Set', - selector: function getAssetRow(row: DownloadedAsset) { - return <AssetTitle asset={row.asset} /> - } + selector: (row) => <AssetTitle asset={row.asset} /> }, { name: 'Network', - selector: function getNetwork(row: DownloadedAsset) { - return <NetworkName networkId={row.networkId} /> - } + selector: (row) => <NetworkName networkId={row.networkId} /> }, { name: 'Datatoken', - selector: function getTitleRow(row: DownloadedAsset) { - return row.dtSymbol - } + selector: (row) => row.dtSymbol }, { name: 'Time', - selector: function getTimeRow(row: DownloadedAsset) { - return <Time date={row.timestamp.toString()} relative isUnix /> - } + selector: (row) => <Time date={row.timestamp.toString()} relative isUnix /> } ] diff --git a/src/components/Profile/History/PoolShares/index.tsx b/src/components/Profile/History/PoolShares/index.tsx index e4b1d8ad1..f6504885c 100644 --- a/src/components/Profile/History/PoolShares/index.tsx +++ b/src/components/Profile/History/PoolShares/index.tsx @@ -1,5 +1,5 @@ import React, { ReactElement, useCallback, useEffect, useState } from 'react' -import Table from '@shared/atoms/Table' +import Table, { TableOceanColumn } from '@shared/atoms/Table' import styles from './index.module.css' import AssetTitle from '@shared/AssetList/AssetListTitle' import { PoolShares_poolShares as PoolShare } from '../../../../@types/subgraph/PoolShares' @@ -23,32 +23,24 @@ export interface AssetPoolShare { asset: Asset } -const columns = [ +const columns: TableOceanColumn<AssetPoolShare>[] = [ { name: 'Data Set', - selector: function getAssetRow(row: AssetPoolShare) { - return <AssetTitle asset={row.asset} /> - }, + selector: (row) => <AssetTitle asset={row.asset} />, grow: 2 }, { name: 'Network', - selector: function getNetwork(row: AssetPoolShare) { - return <NetworkName networkId={row.networkId} /> - } + selector: (row) => <NetworkName networkId={row.networkId} /> }, { name: 'Your liquidity', - selector: function getAssetRow(row: AssetPoolShare) { - return <Liquidity row={row} type="user" /> - }, + selector: (row) => <Liquidity row={row} type="user" />, right: true }, { name: 'Total Value Locked', - selector: function getAssetRow(row: AssetPoolShare) { - return <Liquidity row={row} type="pool" /> - }, + selector: (row) => <Liquidity row={row} type="pool" />, right: true } ] diff --git a/src/components/Profile/History/index.module.css b/src/components/Profile/History/index.module.css index 75db8b925..b1e047554 100644 --- a/src/components/Profile/History/index.module.css +++ b/src/components/Profile/History/index.module.css @@ -34,6 +34,7 @@ .tabs div[class*='tabContent'] { border: 1px solid var(--border-color); + border-top: 0; padding-bottom: 0; }