Skip to content

Commit

Permalink
[Table][Joy] Replace uses of css selector *-child to *-of-type (#36839)
Browse files Browse the repository at this point in the history
  • Loading branch information
keyvanm committed Apr 14, 2023
1 parent 5853e6a commit a0c1b25
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 37 deletions.
4 changes: 2 additions & 2 deletions packages/mui-joy/src/Table/Table.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Table, { tableClasses as classes } from '@mui/joy/Table';
import { unstable_capitalize as capitalize } from '@mui/utils';

describe('<Table />', () => {
const { render } = createRenderer({ emotionCompat: true });
const { render } = createRenderer();

describeConformance(<Table />, () => ({
classes,
Expand Down Expand Up @@ -35,7 +35,7 @@ describe('<Table />', () => {
},
}));

describeJoyColorInversion(<Table />, { muiName: 'JoyTable', classes, emotionCompat: true });
describeJoyColorInversion(<Table />, { muiName: 'JoyTable', classes });

describe('prop: variant', () => {
it('plain by default', () => {
Expand Down
39 changes: 17 additions & 22 deletions packages/mui-joy/src/Table/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,12 @@ const useUtilityClasses = (ownerState: TableOwnerState) => {
};

const tableSelector = {
getColumn(col: number | string) {
if (typeof col === 'number' && col < 0) {
return `& tr > *:nth-last-child(${Math.abs(col)})`;
}
return `& tr > *:nth-child(${col})`;
},
/**
* Except first column
* According to https://www.w3.org/TR/2014/REC-html5-20141028/tabular-data.html#the-tr-element,
* `tr` can only have `td | th` as children, so using :first-of-type is better than :first-child to prevent emotion SSR warning
*/
getColumnExceptFirst() {
return '& tr > *:not(:first-child)';
return '& tr > *:not(:first-of-type), & tr > th + td, & tr > td + th';
},
/**
* Every cell in the table
Expand All @@ -62,13 +57,13 @@ const tableSelector = {
return '& thead th';
},
getHeaderCellOfRow(row: number | string) {
return `& thead tr:nth-child(${row}) th`;
return `& thead tr:nth-of-type(${row}) th`;
},
getBottomHeaderCell() {
return '& thead th:not([colspan])';
},
getHeaderNestedFirstColumn() {
return '& thead tr:not(:first-of-type) th:not([colspan]):first-child';
return '& thead tr:not(:first-of-type) th:not([colspan]):first-of-type';
},
/**
* The body cell that contains data
Expand All @@ -77,27 +72,27 @@ const tableSelector = {
return '& td';
},
getDataCellExceptLastRow() {
return '& tr:not(:last-child) > td';
return '& tr:not(:last-of-type) > td';
},
/**
* The body cell either `td` or `th`
*/
getBodyCellExceptLastRow() {
return `${this.getDataCellExceptLastRow()}, & tr:not(:last-child) > th[scope="row"]`;
return `${this.getDataCellExceptLastRow()}, & tr:not(:last-of-type) > th[scope="row"]`;
},
getBodyCellOfRow(row: number | string) {
if (typeof row === 'number' && row < 0) {
return `& tbody tr:nth-last-child(${Math.abs(row)}) td, & tbody tr:nth-last-child(${Math.abs(
return `& tbody tr:nth-last-of-type(${Math.abs(
row,
)}) th[scope="row"]`;
)}) td, & tbody tr:nth-last-of-type(${Math.abs(row)}) th[scope="row"]`;
}
return `& tbody tr:nth-child(${row}) td, & tbody tr:nth-child(${row}) th[scope="row"]`;
return `& tbody tr:nth-of-type(${row}) td, & tbody tr:nth-of-type(${row}) th[scope="row"]`;
},
getBodyRow(row?: number | string) {
if (row === undefined) {
return `& tbody tr`;
}
return `& tbody tr:nth-child(${row})`;
return `& tbody tr:nth-of-type(${row})`;
},
getFooterCell() {
return '& tfoot th, & tfoot td';
Expand Down Expand Up @@ -169,20 +164,20 @@ const TableRoot = styled('table', {
[tableSelector.getHeaderCell()]: {
verticalAlign: 'bottom',
// Automatic radius adjustment with Sheet
'&:first-child': {
'&:first-of-type': {
borderTopLeftRadius: 'var(--TableCell-cornerRadius, var(--unstable_actionRadius))',
},
'&:last-child': {
'&:last-of-type': {
borderTopRightRadius: 'var(--TableCell-cornerRadius, var(--unstable_actionRadius))',
},
},
'& tfoot tr > *': {
backgroundColor: `var(--TableCell-footBackground, ${theme.vars.palette.background.level1})`,
// Automatic radius adjustment with Sheet
'&:first-child': {
'&:first-of-type': {
borderBottomLeftRadius: 'var(--TableCell-cornerRadius, var(--unstable_actionRadius))',
},
'&:last-child': {
'&:last-of-type': {
borderBottomRightRadius: 'var(--TableCell-cornerRadius, var(--unstable_actionRadius))',
},
},
Expand Down Expand Up @@ -230,11 +225,11 @@ const TableRoot = styled('table', {
},
(ownerState.borderAxis === 'y' || ownerState.borderAxis === 'both') && {
// insert border on the left of first column and right of the last column
[tableSelector.getColumn(1)]: {
'& tr > *:first-of-type': {
borderLeftWidth: 1,
borderLeftStyle: 'solid',
},
[tableSelector.getColumn(-1)]: {
'& tr > *:last-of-type:not(:first-of-type)': {
borderRightWidth: 1,
borderRightStyle: 'solid',
},
Expand Down
10 changes: 0 additions & 10 deletions test/utils/createRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -441,11 +441,6 @@ export interface CreateRendererOptions extends Pick<RenderOptions, 'strict' | 's
*/
clock?: 'fake' | 'real';
clockConfig?: ClockConfig;
/**
* To disable SSR warnings when using CSS pseudo selectors, e.g. :first-child
* https://github.com/emotion-js/emotion/issues/1105#issuecomment-1058225197
*/
emotionCompat?: true;
}

export function createRenderer(globalOptions: CreateRendererOptions = {}): Renderer {
Expand All @@ -454,7 +449,6 @@ export function createRenderer(globalOptions: CreateRendererOptions = {}): Rende
clockConfig,
strict: globalStrict = true,
strictEffects: globalStrictEffects = globalStrict,
emotionCompat,
} = globalOptions;
// save stack to re-use in test-hooks
const { stack: createClientRenderStack } = new Error();
Expand Down Expand Up @@ -520,10 +514,6 @@ export function createRenderer(globalOptions: CreateRendererOptions = {}): Rende

emotionCache = createEmotionCache({ key: 'emotion-client-render' });

if (emotionCompat) {
emotionCache.compat = true;
}

serverContainer = document.createElement('div');
document.body.appendChild(serverContainer);

Expand Down
5 changes: 2 additions & 3 deletions test/utils/describeJoyColorInversion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,10 @@ export default function describeJoyColorInversion(
classes: { colorContext: string; colorPrimary: string; colorSuccess: string };
wrapper?: (node: React.ReactElement) => React.ReactElement;
portalSlot?: string;
emotionCompat?: true;
},
) {
const { classes, muiName, wrapper = (node) => node, portalSlot, emotionCompat } = options;
const { render } = createRenderer({ emotionCompat });
const { classes, muiName, wrapper = (node) => node, portalSlot } = options;
const { render } = createRenderer();
const getTestElement = (result: MuiRenderResult, id = '') => {
const { container, queryByTestId } = result;
let testElement = queryByTestId('test-element') ?? container.firstChild?.firstChild;
Expand Down

0 comments on commit a0c1b25

Please sign in to comment.