diff --git a/.circleci/config.yml b/.circleci/config.yml index 86a47dd04d852..90eebf32d31c8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -57,6 +57,16 @@ default-context: &default-context context: - org-global +test-react-18-context: &test-react-18-context + <<: *default-context + react-version: ^18.0.0 + filters: + branches: + only: + - master + - /^v.*\.x$/ + - next + commands: install_js: parameters: @@ -64,6 +74,10 @@ commands: type: boolean default: false description: 'Set to true if you intend to any browser (for example with playwright).' + react-version: + type: string + default: << pipeline.parameters.react-version >> + description: The version of React to use. steps: - when: @@ -81,14 +95,35 @@ commands: # See https://stackoverflow.com/a/73411601 command: corepack enable --install-directory ~/bin + - when: + condition: + not: + equal: [stable, << parameters.react-version >>] + steps: + - run: + name: Change pnpm setting to not install peer dependencies + command: pnpm config set auto-install-peers false --location project + - run: name: View install environment command: | node --version pnpm --version - - run: - name: Install js dependencies - command: pnpm install + - when: + condition: + not: + equal: [stable, << parameters.react-version >>] + steps: + - run: + name: Install js dependencies without frozen lockfile + command: pnpm install --no-frozen-lockfile + - when: + condition: + equal: [stable, << parameters.react-version >>] + steps: + - run: + name: Install js dependencies + command: pnpm install - run: name: Resolve React version @@ -127,7 +162,8 @@ jobs: <<: *default-job steps: - checkout - - install_js + - install_js: + react-version: << parameters.react-version >> - run: name: Tests fake browser command: pnpm test:coverage @@ -226,6 +262,7 @@ jobs: - checkout - install_js: browsers: true + react-version: << parameters.react-version >> - run: name: Tests real browsers command: pnpm test:karma @@ -257,6 +294,7 @@ jobs: - checkout - install_js: browsers: true + react-version: << parameters.react-version >> - run: name: Run e2e tests command: pnpm test:e2e @@ -281,6 +319,7 @@ jobs: - checkout - install_js: browsers: true + react-version: << parameters.react-version >> - run: name: Run visual regression tests command: xvfb-run pnpm test:regressions @@ -296,7 +335,6 @@ jobs: name: Run danger on PRs command: pnpm danger ci --fail-on-errors workflows: - version: 2 pipeline: when: equal: [pipeline, << pipeline.parameters.workflow >>] @@ -380,3 +418,17 @@ workflows: - test_types: <<: *default-context name: test_types_additional + test-react-18: + jobs: + - test_unit: + <<: *test-react-18-context + name: test_unit_react_18 + - test_browser: + <<: *test-react-18-context + name: test_browser_react_18 + - test_regressions: + <<: *test-react-18-context + name: test_regressions_react_18 + - test_e2e: + <<: *test-react-18-context + name: test_e2e_react_18 diff --git a/docs/data/charts/components/ScaleDemo.tsx b/docs/data/charts/components/ScaleDemo.tsx index b912d56affc2c..be71daf192fd6 100644 --- a/docs/data/charts/components/ScaleDemo.tsx +++ b/docs/data/charts/components/ScaleDemo.tsx @@ -21,7 +21,7 @@ const StyledText = styled('text')(({ theme }) => ({ shapeRendering: 'crispEdges', })); -function ValueHighlight(props: { svgRef: React.RefObject }) { +function ValueHighlight(props: { svgRef: React.RefObject }) { const { svgRef } = props; // Get the drawing area bounding box diff --git a/docs/data/data-grid/filtering/CustomMultiValueOperator.js b/docs/data/data-grid/filtering/CustomMultiValueOperator.js index 7155e509dc995..4dbfb04c5a87e 100644 --- a/docs/data/data-grid/filtering/CustomMultiValueOperator.js +++ b/docs/data/data-grid/filtering/CustomMultiValueOperator.js @@ -9,7 +9,7 @@ function InputNumberInterval(props) { const rootProps = useGridRootProps(); const { item, applyValue, focusElementRef = null } = props; - const filterTimeout = React.useRef(); + const filterTimeout = React.useRef(undefined); const [filterValueState, setFilterValueState] = React.useState(item.value ?? ''); const [applying, setIsApplying] = React.useState(false); diff --git a/docs/data/data-grid/filtering/CustomMultiValueOperator.tsx b/docs/data/data-grid/filtering/CustomMultiValueOperator.tsx index 0ac2080fb364b..d1d777e8b4848 100644 --- a/docs/data/data-grid/filtering/CustomMultiValueOperator.tsx +++ b/docs/data/data-grid/filtering/CustomMultiValueOperator.tsx @@ -15,7 +15,7 @@ function InputNumberInterval(props: GridFilterInputValueProps) { const rootProps = useGridRootProps(); const { item, applyValue, focusElementRef = null } = props; - const filterTimeout = React.useRef(); + const filterTimeout = React.useRef>(undefined); const [filterValueState, setFilterValueState] = React.useState<[string, string]>( item.value ?? '', ); diff --git a/docs/data/data-grid/layout/MinMaxHeightGrid.tsx b/docs/data/data-grid/layout/MinMaxHeightGrid.tsx index 79bb6db519699..66d52455a4a87 100644 --- a/docs/data/data-grid/layout/MinMaxHeightGrid.tsx +++ b/docs/data/data-grid/layout/MinMaxHeightGrid.tsx @@ -53,7 +53,7 @@ export default function MinMaxHeightGrid() { function ContainerMeasurements({ containerRef, }: { - containerRef: React.RefObject; + containerRef: React.RefObject; }) { const [containerHeight, setContainerHeight] = React.useState(0); diff --git a/docs/data/data-grid/pagination/CursorPaginationGrid.js b/docs/data/data-grid/pagination/CursorPaginationGrid.js index 1815b05771007..2bc291793b737 100644 --- a/docs/data/data-grid/pagination/CursorPaginationGrid.js +++ b/docs/data/data-grid/pagination/CursorPaginationGrid.js @@ -48,7 +48,7 @@ export default function CursorPaginationGrid() { } }; - const paginationMetaRef = React.useRef(); + const paginationMetaRef = React.useRef(undefined); // Memoize to avoid flickering when the `hasNextPage` is `undefined` during refetch const paginationMeta = React.useMemo(() => { diff --git a/docs/data/data-grid/pagination/CursorPaginationGrid.tsx b/docs/data/data-grid/pagination/CursorPaginationGrid.tsx index 113e1b7945c45..4d92a2a68be5c 100644 --- a/docs/data/data-grid/pagination/CursorPaginationGrid.tsx +++ b/docs/data/data-grid/pagination/CursorPaginationGrid.tsx @@ -55,7 +55,7 @@ export default function CursorPaginationGrid() { } }; - const paginationMetaRef = React.useRef(); + const paginationMetaRef = React.useRef(undefined); // Memoize to avoid flickering when the `hasNextPage` is `undefined` during refetch const paginationMeta = React.useMemo(() => { diff --git a/docs/data/data-grid/pagination/ServerPaginationGridNoRowCount.js b/docs/data/data-grid/pagination/ServerPaginationGridNoRowCount.js index 2de106edc5d3e..239db20b0e972 100644 --- a/docs/data/data-grid/pagination/ServerPaginationGridNoRowCount.js +++ b/docs/data/data-grid/pagination/ServerPaginationGridNoRowCount.js @@ -23,7 +23,7 @@ export default function ServerPaginationGridNoRowCount() { pageInfo: { hasNextPage }, } = useQuery(paginationModel); - const paginationMetaRef = React.useRef(); + const paginationMetaRef = React.useRef(undefined); // Memoize to avoid flickering when the `hasNextPage` is `undefined` during refetch const paginationMeta = React.useMemo(() => { diff --git a/docs/data/data-grid/pagination/ServerPaginationGridNoRowCount.tsx b/docs/data/data-grid/pagination/ServerPaginationGridNoRowCount.tsx index bb35ce14cebd5..98fdf4dcc1513 100644 --- a/docs/data/data-grid/pagination/ServerPaginationGridNoRowCount.tsx +++ b/docs/data/data-grid/pagination/ServerPaginationGridNoRowCount.tsx @@ -23,7 +23,7 @@ export default function ServerPaginationGridNoRowCount() { pageInfo: { hasNextPage }, } = useQuery(paginationModel); - const paginationMetaRef = React.useRef(); + const paginationMetaRef = React.useRef(undefined); // Memoize to avoid flickering when the `hasNextPage` is `undefined` during refetch const paginationMeta = React.useMemo(() => { diff --git a/docs/data/tree-view/rich-tree-view/customization/CustomAnimation.js b/docs/data/tree-view/rich-tree-view/customization/CustomAnimation.js index 7941d92b58e5d..cd398604ab5bf 100644 --- a/docs/data/tree-view/rich-tree-view/customization/CustomAnimation.js +++ b/docs/data/tree-view/rich-tree-view/customization/CustomAnimation.js @@ -45,6 +45,7 @@ function TransitionComponent(props) { }); return ( + // @ts-expect-error diff --git a/docs/data/tree-view/rich-tree-view/customization/CustomAnimation.tsx b/docs/data/tree-view/rich-tree-view/customization/CustomAnimation.tsx index 234b4b656bd98..60fd9f16f5251 100644 --- a/docs/data/tree-view/rich-tree-view/customization/CustomAnimation.tsx +++ b/docs/data/tree-view/rich-tree-view/customization/CustomAnimation.tsx @@ -45,6 +45,7 @@ function TransitionComponent(props: TransitionProps) { }); return ( + // @ts-expect-error diff --git a/docs/data/tree-view/simple-tree-view/customization/CustomAnimation.js b/docs/data/tree-view/simple-tree-view/customization/CustomAnimation.js index f507b6768cca7..e88f87658b23f 100644 --- a/docs/data/tree-view/simple-tree-view/customization/CustomAnimation.js +++ b/docs/data/tree-view/simple-tree-view/customization/CustomAnimation.js @@ -15,6 +15,7 @@ function TransitionComponent(props) { }); return ( + // @ts-expect-error diff --git a/docs/data/tree-view/simple-tree-view/customization/CustomAnimation.tsx b/docs/data/tree-view/simple-tree-view/customization/CustomAnimation.tsx index 5a2428ac5a08d..e46d7537cb9e1 100644 --- a/docs/data/tree-view/simple-tree-view/customization/CustomAnimation.tsx +++ b/docs/data/tree-view/simple-tree-view/customization/CustomAnimation.tsx @@ -15,6 +15,7 @@ function TransitionComponent(props: TransitionProps) { }); return ( + // @ts-expect-error diff --git a/docs/package.json b/docs/package.json index 1a933828246d3..17d6026d2fd0f 100644 --- a/docs/package.json +++ b/docs/package.json @@ -28,14 +28,14 @@ "@emotion/server": "^11.11.0", "@emotion/styled": "^11.13.0", "@mui/docs": "6.1.6", - "@mui/icons-material": "^5.16.7", - "@mui/joy": "^5.0.0-beta.48", - "@mui/lab": "^5.0.0-alpha.173", - "@mui/material": "^5.16.7", - "@mui/material-nextjs": "^5.16.6", - "@mui/styles": "^5.16.7", - "@mui/system": "^5.16.7", - "@mui/utils": "^5.16.6", + "@mui/icons-material": "^5.16.13", + "@mui/joy": "^5.0.0-beta.51", + "@mui/lab": "^5.0.0-alpha.175", + "@mui/material": "^5.16.13", + "@mui/material-nextjs": "^5.16.13", + "@mui/styles": "^5.16.13", + "@mui/system": "^5.16.13", + "@mui/utils": "^5.16.13", "@mui/x-charts": "workspace:*", "@mui/x-charts-vendor": "workspace:*", "@mui/x-data-grid": "workspace:*", @@ -81,11 +81,11 @@ "postcss": "^8.4.47", "prismjs": "^1.29.0", "prop-types": "^15.8.1", - "react": "^18.3.1", + "react": "^19.0.0", "react-docgen": "^5.4.3", - "react-dom": "^18.3.1", + "react-dom": "^19.0.0", "react-hook-form": "^7.53.0", - "react-is": "^18.3.1", + "react-is": "^19.0.0", "react-router": "^6.27.0", "react-router-dom": "^6.27.0", "react-runner": "^1.0.5", @@ -113,7 +113,7 @@ "@types/moment-hijri": "^2.1.4", "@types/moment-jalaali": "^0.7.9", "@types/prop-types": "^15.7.13", - "@types/react-dom": "^18.3.1", + "@types/react-dom": "^19.0.2", "@types/react-router-dom": "^5.3.3", "@types/stylis": "^4.2.6", "@types/webpack-bundle-analyzer": "^4.7.0", diff --git a/docs/src/modules/components/PickersPlayground.tsx b/docs/src/modules/components/PickersPlayground.tsx index 5980b1565b989..ec9ede2eb8ef5 100644 --- a/docs/src/modules/components/PickersPlayground.tsx +++ b/docs/src/modules/components/PickersPlayground.tsx @@ -217,7 +217,7 @@ const shortcutsItems: PickersShortcutsItem>[] = [ { label: 'Reset', getValue: () => [null, null] }, ]; -function DisabledCheckboxTooltip({ children }: { children: React.ReactElement }) { +function DisabledCheckboxTooltip({ children }: { children: React.ReactElement }) { return ( {children} ); diff --git a/docs/src/modules/utils/useCustomizationPlayground.tsx b/docs/src/modules/utils/useCustomizationPlayground.tsx index f3a92e7c3e136..5634e025d0b00 100644 --- a/docs/src/modules/utils/useCustomizationPlayground.tsx +++ b/docs/src/modules/utils/useCustomizationPlayground.tsx @@ -24,13 +24,13 @@ export type PickersSubcomponentType = { [k: string]: { examples: CustomizationItemsType; slots: string[]; - moreInformation?: React.ReactElement | string; + moreInformation?: React.ReactElement | string; }; }; export interface UseCustomizationPlaygroundProps { examples: PickersSubcomponentType; - children?: React.ReactElement | React.ReactElement[]; + children?: React.ReactElement | React.ReactElement[]; componentName: string; } export const customizationLabels: CustomizationLabelType = { @@ -72,7 +72,7 @@ export type UseCustomizationPlaygroundReturnType = { handleTokenChange: HandleTokenChangeType; selectedTokens: StyleTokensType; selectedExample?: CustomizationItemType | null; - moreInformation?: React.ReactElement | string | null; + moreInformation?: React.ReactElement | string | null; }; export function withStyles( diff --git a/package.json b/package.json index dbd44a15e6518..b87920f9cd5e6 100644 --- a/package.json +++ b/package.json @@ -90,13 +90,13 @@ "@emotion/cache": "^11.13.1", "@emotion/react": "^11.13.3", "@emotion/styled": "^11.13.0", - "@mui/icons-material": "^5.16.7", + "@mui/icons-material": "^5.16.13", "@mui/internal-babel-plugin-resolve-imports": "1.0.18", "@mui/internal-markdown": "^1.0.19", "@mui/internal-test-utils": "^1.0.17", - "@mui/material": "^5.16.7", + "@mui/material": "^5.16.13", "@mui/monorepo": "github:mui/material-ui#7aa841466a01b745012e59e9d201ed50807a022e", - "@mui/utils": "^5.16.6", + "@mui/utils": "^5.16.13", "@next/eslint-plugin-next": "14.2.15", "@octokit/plugin-retry": "^7.1.2", "@octokit/rest": "^21.0.2", @@ -110,8 +110,8 @@ "@types/lodash": "^4.17.10", "@types/mocha": "^10.0.9", "@types/node": "^20.16.11", - "@types/react": "^18.3.12", - "@types/react-dom": "^18.3.1", + "@types/react": "^19.0.2", + "@types/react-dom": "^19.0.2", "@types/react-test-renderer": "^18.3.0", "@types/requestidlecallback": "^0.3.7", "@types/sinon": "^17.0.3", @@ -179,8 +179,8 @@ "prettier": "^3.3.3", "pretty-quick": "^4.0.0", "process": "^0.11.10", - "react": "^18.3.1", - "react-dom": "^18.3.1", + "react": "^19.0.0", + "react-dom": "^19.0.0", "remark": "^15.0.1", "rimraf": "^6.0.1", "serve": "^14.2.3", @@ -198,7 +198,7 @@ "yargs": "^17.7.2" }, "resolutions": { - "react-is": "^18.3.1", + "react-is": "^19.0.0", "@types/node": "^20.16.11" }, "packageManager": "pnpm@9.15.1", diff --git a/packages/x-charts-pro/package.json b/packages/x-charts-pro/package.json index 6159c9eeb405e..1e16cbebb76c7 100644 --- a/packages/x-charts-pro/package.json +++ b/packages/x-charts-pro/package.json @@ -67,8 +67,8 @@ } }, "devDependencies": { - "@mui/material": "^5.16.7", - "@mui/system": "^5.16.7", + "@mui/material": "^5.16.13", + "@mui/system": "^5.16.13", "@react-spring/core": "^9.7.5", "@react-spring/shared": "^9.7.5", "@types/prop-types": "^15.7.13", diff --git a/packages/x-charts-pro/tsconfig.json b/packages/x-charts-pro/tsconfig.json index 5f862d31ec2ba..f63ee3ebfc2ad 100644 --- a/packages/x-charts-pro/tsconfig.json +++ b/packages/x-charts-pro/tsconfig.json @@ -8,7 +8,8 @@ "mocha", "node" ], - "noImplicitAny": false + "noImplicitAny": false, + "skipLibCheck": true }, "include": ["src/**/*", "../../test/utils/addChaiAssertions.ts"] } diff --git a/packages/x-charts/package.json b/packages/x-charts/package.json index e3b03d3895565..4b1e75dd7c26a 100644 --- a/packages/x-charts/package.json +++ b/packages/x-charts/package.json @@ -66,8 +66,8 @@ }, "devDependencies": { "@mui/internal-test-utils": "^1.0.17", - "@mui/material": "^5.16.7", - "@mui/system": "^5.16.7", + "@mui/material": "^5.16.13", + "@mui/system": "^5.16.13", "@react-spring/core": "^9.7.5", "@react-spring/shared": "^9.7.5", "@types/prop-types": "^15.7.13", diff --git a/packages/x-charts/src/LineChart/AnimatedArea.tsx b/packages/x-charts/src/LineChart/AnimatedArea.tsx index c88c8be9d585f..d8b8cd61ea849 100644 --- a/packages/x-charts/src/LineChart/AnimatedArea.tsx +++ b/packages/x-charts/src/LineChart/AnimatedArea.tsx @@ -58,6 +58,7 @@ function AnimatedArea(props: AnimatedAreaProps) { return ( {transitionChange((style, interpolator) => ( + // @ts-expect-error ))} diff --git a/packages/x-charts/src/LineChart/AnimatedLine.tsx b/packages/x-charts/src/LineChart/AnimatedLine.tsx index 6c2eeb435102c..5d5f7eaff0c8d 100644 --- a/packages/x-charts/src/LineChart/AnimatedLine.tsx +++ b/packages/x-charts/src/LineChart/AnimatedLine.tsx @@ -60,6 +60,7 @@ function AnimatedLine(props: AnimatedLineProps) { return ( {transitionChange((style, interpolator) => ( + // @ts-expect-error ))} diff --git a/packages/x-charts/src/LineChart/AppearingMask.tsx b/packages/x-charts/src/LineChart/AppearingMask.tsx index cbf7a341f375e..6121e2e215502 100644 --- a/packages/x-charts/src/LineChart/AppearingMask.tsx +++ b/packages/x-charts/src/LineChart/AppearingMask.tsx @@ -35,6 +35,7 @@ export function AppearingMask(props: AppearingMaskProps) { {transitionAppear((style) => ( `${pX}px ${pY}px`), }} ownerState={ownerState} + // @ts-expect-error className={classes.root} d={d3Symbol(d3SymbolsFill[getSymbol(shape)])()!} onClick={onClick} diff --git a/packages/x-charts/src/PieChart/PieArc.tsx b/packages/x-charts/src/PieChart/PieArc.tsx index 6f6c61104d629..914a66e213906 100644 --- a/packages/x-charts/src/PieChart/PieArc.tsx +++ b/packages/x-charts/src/PieChart/PieArc.tsx @@ -126,6 +126,7 @@ function PieArc(props: PieArcProps) { })!, )} visibility={to([startAngle, endAngle], (sA, eA) => (sA === eA ? 'hidden' : 'visible'))} + // @ts-expect-error onClick={onClick} cursor={onClick ? 'pointer' : 'unset'} ownerState={ownerState} diff --git a/packages/x-charts/src/PieChart/PieArcLabel.tsx b/packages/x-charts/src/PieChart/PieArcLabel.tsx index 7734d46b60faf..20eb27a030a64 100644 --- a/packages/x-charts/src/PieChart/PieArcLabel.tsx +++ b/packages/x-charts/src/PieChart/PieArcLabel.tsx @@ -129,6 +129,7 @@ function PieArcLabel(props: PieArcLabelProps) { const classes = useUtilityClasses(ownerState); return ( + // @ts-expect-error - {plotType === 'bar' && ( - - )} + {plotType === 'bar' && } {plotType === 'line' && ( diff --git a/packages/x-charts/src/hooks/useSvgRef.ts b/packages/x-charts/src/hooks/useSvgRef.ts index 502debfe151e1..309341b118715 100644 --- a/packages/x-charts/src/hooks/useSvgRef.ts +++ b/packages/x-charts/src/hooks/useSvgRef.ts @@ -2,7 +2,7 @@ import * as React from 'react'; import { SvgContext } from '../context/DrawingProvider'; -export function useSvgRef(): React.MutableRefObject { +export function useSvgRef(): React.RefObject { const { isInitialized, data } = React.useContext(SvgContext); if (!isInitialized) { @@ -14,5 +14,5 @@ export function useSvgRef(): React.MutableRefObject { ); } - return data as React.MutableRefObject; + return data as React.RefObject; } diff --git a/packages/x-charts/tsconfig.json b/packages/x-charts/tsconfig.json index 96d9df1cf6673..8cd34736be383 100644 --- a/packages/x-charts/tsconfig.json +++ b/packages/x-charts/tsconfig.json @@ -7,7 +7,8 @@ "chai-dom", "mocha", "node" - ] + ], + "skipLibCheck": true }, "include": ["src/**/*", "../../test/utils/addChaiAssertions.ts", "../../test/utils/init.ts"] } diff --git a/packages/x-codemod/tsconfig.json b/packages/x-codemod/tsconfig.json index 8ed9735012229..97636e2180272 100644 --- a/packages/x-codemod/tsconfig.json +++ b/packages/x-codemod/tsconfig.json @@ -11,7 +11,8 @@ "moment-timezone", "node" ], - "noImplicitAny": false + "noImplicitAny": false, + "skipLibCheck": true }, "include": ["src/**/*"], "exclude": ["src/**/actual*.ts*"] diff --git a/packages/x-data-grid-generator/package.json b/packages/x-data-grid-generator/package.json index 843229c151433..c3630fa946d8c 100644 --- a/packages/x-data-grid-generator/package.json +++ b/packages/x-data-grid-generator/package.json @@ -40,8 +40,8 @@ "lru-cache": "^11.0.1" }, "devDependencies": { - "@mui/icons-material": "^5.16.7", - "@mui/material": "^5.16.7", + "@mui/icons-material": "^5.16.13", + "@mui/material": "^5.16.13", "@types/chance": "^1.1.6", "rimraf": "^6.0.1" }, diff --git a/packages/x-data-grid-premium/package.json b/packages/x-data-grid-premium/package.json index 41d510767ada5..9828f7fd3227a 100644 --- a/packages/x-data-grid-premium/package.json +++ b/packages/x-data-grid-premium/package.json @@ -73,8 +73,8 @@ }, "devDependencies": { "@mui/internal-test-utils": "^1.0.17", - "@mui/material": "^5.16.7", - "@mui/system": "^5.16.7", + "@mui/material": "^5.16.13", + "@mui/system": "^5.16.13", "@types/prop-types": "^15.7.13", "date-fns": "^2.30.0", "rimraf": "^6.0.1" diff --git a/packages/x-data-grid-premium/src/hooks/features/cellSelection/useGridCellSelection.ts b/packages/x-data-grid-premium/src/hooks/features/cellSelection/useGridCellSelection.ts index 634fbdad61b93..9ea7241a20590 100644 --- a/packages/x-data-grid-premium/src/hooks/features/cellSelection/useGridCellSelection.ts +++ b/packages/x-data-grid-premium/src/hooks/features/cellSelection/useGridCellSelection.ts @@ -49,7 +49,7 @@ const AUTO_SCROLL_SENSITIVITY = 50; // The distance from the edge to start scrol const AUTO_SCROLL_SPEED = 20; // The speed to scroll once the mouse enters the sensitivity area export const useGridCellSelection = ( - apiRef: React.MutableRefObject, + apiRef: React.RefObject, props: Pick< DataGridPremiumProcessedProps, | 'cellSelection' @@ -64,10 +64,10 @@ export const useGridCellSelection = ( ) => { const hasRootReference = apiRef.current.rootElementRef.current !== null; const visibleRows = useGridVisibleRows(apiRef, props); - const cellWithVirtualFocus = React.useRef(); - const lastMouseDownCell = React.useRef(); - const mousePosition = React.useRef<{ x: number; y: number } | null>(null); - const autoScrollRAF = React.useRef(); + const cellWithVirtualFocus = React.useRef(null); + const lastMouseDownCell = React.useRef(null); + const mousePosition = React.useRef<{ x: number; y: number }>(null); + const autoScrollRAF = React.useRef(null); const sortedRowIds = useGridSelector(apiRef, gridSortedRowIdsSelector); const dimensions = useGridSelector(apiRef, gridDimensionsSelector); const totalHeaderHeight = getTotalHeaderHeight(apiRef, props); diff --git a/packages/x-data-grid-premium/src/tests/DataGridPremium.test.tsx b/packages/x-data-grid-premium/src/tests/DataGridPremium.test.tsx index 70df5ae9c3d59..789a91a953f10 100644 --- a/packages/x-data-grid-premium/src/tests/DataGridPremium.test.tsx +++ b/packages/x-data-grid-premium/src/tests/DataGridPremium.test.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { createRenderer, act } from '@mui/internal-test-utils'; +import { createRenderer, act, waitFor } from '@mui/internal-test-utils'; import { expect } from 'chai'; import { DataGridPremium as DataGrid, @@ -63,7 +63,7 @@ describe(' - Quick filter', () => { } // https://github.com/mui/mui-x/issues/9677 - it('should not fail when adding a grouping criterion', () => { + it('should not fail when adding a grouping criterion', async () => { const { setProps } = render( - Quick filter', () => { />, ); - act(() => apiRef.current.addRowGroupingCriteria('year')); + await act(() => apiRef.current.addRowGroupingCriteria('year')); setProps({ filterModel: { @@ -103,6 +103,6 @@ describe(' - Quick filter', () => { }, }); - expect(getColumnValues(0)).to.deep.equal(['20th Century Fox (1)', '']); + await waitFor(() => expect(getColumnValues(0)).to.deep.equal(['20th Century Fox (1)', ''])); }); }); diff --git a/packages/x-data-grid-premium/src/tests/cellSelection.DataGridPremium.test.tsx b/packages/x-data-grid-premium/src/tests/cellSelection.DataGridPremium.test.tsx index 1918719266a19..4d8604f27d128 100644 --- a/packages/x-data-grid-premium/src/tests/cellSelection.DataGridPremium.test.tsx +++ b/packages/x-data-grid-premium/src/tests/cellSelection.DataGridPremium.test.tsx @@ -88,14 +88,16 @@ describe(' - Cell selection', () => { }); describe('Ctrl + click', () => { - it('should add the clicked cells to the selection', () => { - render(); + it('should add the clicked cells to the selection', async () => { + const { user } = render(); expect(document.querySelector('.Mui-selected')).to.equal(null); const cell11 = getCell(1, 1); - fireEvent.click(cell11); + await user.click(cell11); expect(cell11).to.have.class('Mui-selected'); const cell21 = getCell(2, 1); - fireEvent.click(cell21, { ctrlKey: true }); + await user.keyboard('{Control>}'); + await user.click(cell21); + await user.keyboard('{/Control}'); expect(cell21).to.have.class('Mui-selected'); expect(cell11).to.have.class('Mui-selected'); }); @@ -187,14 +189,15 @@ describe(' - Cell selection', () => { expect(spiedSelectCellsBetweenRange.lastCall.args[1]).to.deep.equal({ id: 1, field: 'id' }); }); - it('should call selectCellRange when ArrowUp is pressed', () => { - render(); + it('should call selectCellRange when ArrowUp is pressed', async () => { + const { user } = render(); const spiedSelectCellsBetweenRange = spyApi(apiRef.current, 'selectCellRange'); const cell = getCell(1, 0); - cell.focus(); - fireUserEvent.mousePress(cell); - fireEvent.keyDown(cell, { key: 'Shift' }); - fireEvent.keyDown(cell, { key: 'ArrowUp', shiftKey: true }); + await act(() => { + cell.focus(); + }); + await user.click(cell); + await user.keyboard('{Shift>}{ArrowUp}{/Shift}'); expect(spiedSelectCellsBetweenRange.lastCall.args[0]).to.deep.equal({ id: 1, field: 'id' }); expect(spiedSelectCellsBetweenRange.lastCall.args[1]).to.deep.equal({ id: 0, field: 'id' }); }); @@ -298,9 +301,9 @@ describe(' - Cell selection', () => { expect(getCell(2, 2)).to.have.class('Mui-selected'); }); - it('should select all cells within the given arguments if start > end', () => { + it('should select all cells within the given arguments if start > end', async () => { render(); - act(() => + await act(() => apiRef.current.selectCellRange({ id: 0, field: 'id' }, { id: 2, field: 'price1M' }), ); diff --git a/packages/x-data-grid-premium/src/tests/exportExcel.DataGridPremium.test.tsx b/packages/x-data-grid-premium/src/tests/exportExcel.DataGridPremium.test.tsx index b7e6c72fe40f0..7cb9dc712a09e 100644 --- a/packages/x-data-grid-premium/src/tests/exportExcel.DataGridPremium.test.tsx +++ b/packages/x-data-grid-premium/src/tests/exportExcel.DataGridPremium.test.tsx @@ -221,7 +221,10 @@ describe(' - Export Excel', () => { } render(); - const workbook = await apiRef.current.getDataAsExcel(); + let workbook: Excel.Workbook | null = null; + await act(async () => { + workbook = await apiRef.current.getDataAsExcel(); + }); const worksheet = workbook!.worksheets[0]; // 1-based index + 1 for column header row diff --git a/packages/x-data-grid-premium/src/tests/rowSelection.DataGridPremium.test.tsx b/packages/x-data-grid-premium/src/tests/rowSelection.DataGridPremium.test.tsx index 69a67346684e3..24d3422a08fd3 100644 --- a/packages/x-data-grid-premium/src/tests/rowSelection.DataGridPremium.test.tsx +++ b/packages/x-data-grid-premium/src/tests/rowSelection.DataGridPremium.test.tsx @@ -120,19 +120,19 @@ describe(' - Row selection', () => { ]); }); - it('should deselect auto selected parent if one of the children is deselected', () => { - render(); + it('should deselect auto selected parent if one of the children is deselected', async () => { + const { user } = render(); - fireEvent.click(getCell(1, 0).querySelector('input')!); - fireEvent.click(getCell(2, 0).querySelector('input')!); - fireEvent.click(getCell(3, 0).querySelector('input')!); + await user.click(getCell(1, 0).querySelector('input')!); + await user.click(getCell(2, 0).querySelector('input')!); + await user.click(getCell(3, 0).querySelector('input')!); expect(apiRef.current.getSelectedRows()).to.have.keys([ 0, 1, 2, 'auto-generated-row-category1/Cat A', ]); - fireEvent.click(getCell(2, 0).querySelector('input')!); + await user.click(getCell(2, 0).querySelector('input')!); expect(apiRef.current.getSelectedRows()).to.have.keys([0, 2]); }); diff --git a/packages/x-data-grid-premium/src/tests/statePersistence.DataGridPremium.test.tsx b/packages/x-data-grid-premium/src/tests/statePersistence.DataGridPremium.test.tsx index 3ae5c92b250e4..647123bbca6f8 100644 --- a/packages/x-data-grid-premium/src/tests/statePersistence.DataGridPremium.test.tsx +++ b/packages/x-data-grid-premium/src/tests/statePersistence.DataGridPremium.test.tsx @@ -11,6 +11,7 @@ import { import { createRenderer, act } from '@mui/internal-test-utils'; import { expect } from 'chai'; import { getColumnValues } from 'test/utils/helperFn'; +import { GridInitialStatePremium } from '../models/gridStatePremium'; const isJSDOM = /jsdom/.test(window.navigator.userAgent); @@ -90,30 +91,40 @@ describe(' - State persistence', () => { }); }); - it('should export the current version of the exportable state', () => { + it('should export the current version of the exportable state', async () => { render(); - act(() => apiRef.current.setRowGroupingModel(['category'])); - act(() => + await act(() => { + apiRef.current.setRowGroupingModel(['category']); + }); + await act(() => { apiRef.current.setAggregationModel({ id: 'size', - }), - ); + }); + }); - const exportedState = apiRef.current.exportState(); + let exportedState: GridInitialStatePremium = {}; + await act(() => { + exportedState = apiRef.current.exportState(); + }); expect(exportedState.rowGrouping).to.deep.equal(FULL_INITIAL_STATE.rowGrouping); expect(exportedState.aggregation).to.deep.equal(FULL_INITIAL_STATE.aggregation); }); - it('should export the current version of the exportable state when using exportOnlyDirtyModels', () => { + it('should export the current version of the exportable state when using exportOnlyDirtyModels', async () => { render(); - act(() => apiRef.current.setRowGroupingModel(['category'])); - act(() => + await act(() => { + apiRef.current.setRowGroupingModel(['category']); + }); + await act(() => { apiRef.current.setAggregationModel({ id: 'size', - }), - ); + }); + }); - const exportedState = apiRef.current.exportState({ exportOnlyDirtyModels: true }); + let exportedState: GridInitialStatePremium = {}; + await act(() => { + exportedState = apiRef.current.exportState({ exportOnlyDirtyModels: true }); + }); expect(exportedState.rowGrouping).to.deep.equal(FULL_INITIAL_STATE.rowGrouping); expect(exportedState.aggregation).to.deep.equal(FULL_INITIAL_STATE.aggregation); }); diff --git a/packages/x-data-grid-pro/package.json b/packages/x-data-grid-pro/package.json index 1631330d469e7..4fd1be4e154a5 100644 --- a/packages/x-data-grid-pro/package.json +++ b/packages/x-data-grid-pro/package.json @@ -71,8 +71,8 @@ }, "devDependencies": { "@mui/internal-test-utils": "^1.0.17", - "@mui/material": "^5.16.7", - "@mui/system": "^5.16.7", + "@mui/material": "^5.16.13", + "@mui/system": "^5.16.13", "@types/prop-types": "^15.7.13", "rimraf": "^6.0.1" }, diff --git a/packages/x-data-grid-pro/src/DataGridPro/useDataGridProComponent.tsx b/packages/x-data-grid-pro/src/DataGridPro/useDataGridProComponent.tsx index 0240d83802fcc..b56fd3f104edb 100644 --- a/packages/x-data-grid-pro/src/DataGridPro/useDataGridProComponent.tsx +++ b/packages/x-data-grid-pro/src/DataGridPro/useDataGridProComponent.tsx @@ -88,7 +88,7 @@ import { } from '../hooks/features/dataSource/useGridDataSource'; export const useDataGridProComponent = ( - inputApiRef: React.MutableRefObject | undefined, + inputApiRef: React.RefObject | undefined, props: DataGridProProcessedProps, ) => { const apiRef = useGridInitialization(inputApiRef, props); diff --git a/packages/x-data-grid-pro/src/hooks/features/columnReorder/useGridColumnReorder.tsx b/packages/x-data-grid-pro/src/hooks/features/columnReorder/useGridColumnReorder.tsx index db0e3dc99fdd3..0dc4f05c7c384 100644 --- a/packages/x-data-grid-pro/src/hooks/features/columnReorder/useGridColumnReorder.tsx +++ b/packages/x-data-grid-pro/src/hooks/features/columnReorder/useGridColumnReorder.tsx @@ -72,7 +72,7 @@ export const useGridColumnReorder = ( }); const originColumnIndex = React.useRef(null); const forbiddenIndexes = React.useRef<{ [key: number]: boolean }>({}); - const removeDnDStylesTimeout = React.useRef>(); + const removeDnDStylesTimeout = React.useRef>(undefined); const ownerState = { classes: props.classes }; const classes = useUtilityClasses(ownerState); const isRtl = useRtl(); diff --git a/packages/x-data-grid-pro/src/hooks/features/detailPanel/useGridDetailPanel.ts b/packages/x-data-grid-pro/src/hooks/features/detailPanel/useGridDetailPanel.ts index 2efc3fbe92505..bb79fec8650ed 100644 --- a/packages/x-data-grid-pro/src/hooks/features/detailPanel/useGridDetailPanel.ts +++ b/packages/x-data-grid-pro/src/hooks/features/detailPanel/useGridDetailPanel.ts @@ -260,9 +260,9 @@ export const useGridDetailPanel = ( useGridApiEventHandler(apiRef, 'sortedRowsSet', updateCachesAndForceUpdate); const previousGetDetailPanelContentProp = - React.useRef(); + React.useRef(null); const previousGetDetailPanelHeightProp = - React.useRef(); + React.useRef(null); const updateCachesIfNeeded = React.useCallback(() => { if ( diff --git a/packages/x-data-grid-pro/src/hooks/features/infiniteLoader/useGridInfiniteLoader.tsx b/packages/x-data-grid-pro/src/hooks/features/infiniteLoader/useGridInfiniteLoader.tsx index 9e38bde1833f4..0996a53562300 100644 --- a/packages/x-data-grid-pro/src/hooks/features/infiniteLoader/useGridInfiniteLoader.tsx +++ b/packages/x-data-grid-pro/src/hooks/features/infiniteLoader/useGridInfiniteLoader.tsx @@ -38,7 +38,7 @@ export const useGridInfiniteLoader = ( ): void => { const visibleColumns = useGridSelector(apiRef, gridVisibleColumnDefinitionsSelector); const currentPage = useGridVisibleRows(apiRef, props); - const observer = React.useRef(); + const observer = React.useRef(null); const updateTargetTimeout = useTimeout(); const triggerElement = React.useRef(null); diff --git a/packages/x-data-grid-pro/src/hooks/features/rowReorder/useGridRowReorder.tsx b/packages/x-data-grid-pro/src/hooks/features/rowReorder/useGridRowReorder.tsx index 866dd4e242a59..6e906e370cae9 100644 --- a/packages/x-data-grid-pro/src/hooks/features/rowReorder/useGridRowReorder.tsx +++ b/packages/x-data-grid-pro/src/hooks/features/rowReorder/useGridRowReorder.tsx @@ -62,7 +62,7 @@ export const useGridRowReorder = ( const treeDepth = useGridSelector(apiRef, gridRowMaximumTreeDepthSelector); const dragRowNode = React.useRef(null); const originRowIndex = React.useRef(null); - const removeDnDStylesTimeout = React.useRef>(); + const removeDnDStylesTimeout = React.useRef>(undefined); const ownerState = { classes: props.classes }; const classes = useUtilityClasses(ownerState); const [dragRowId, setDragRowId] = React.useState(''); diff --git a/packages/x-data-grid-pro/src/tests/cellEditing.DataGridPro.test.tsx b/packages/x-data-grid-pro/src/tests/cellEditing.DataGridPro.test.tsx index 2f65dfafabee0..a0bcce7ee09d3 100644 --- a/packages/x-data-grid-pro/src/tests/cellEditing.DataGridPro.test.tsx +++ b/packages/x-data-grid-pro/src/tests/cellEditing.DataGridPro.test.tsx @@ -54,9 +54,9 @@ describe(' - Cell editing', () => { describe('apiRef', () => { describe('startCellEditMode', () => { - it('should throw when the cell is already in edit mode', () => { + it('should throw when the cell is already in edit mode', async () => { render(); - act(() => apiRef.current.startCellEditMode({ id: 0, field: 'currencyPair' })); + await act(() => apiRef.current.startCellEditMode({ id: 0, field: 'currencyPair' })); expect(() => { apiRef.current.startCellEditMode({ id: 0, field: 'currencyPair' }); }).to.throw('MUI X: The cell with id=0 and field=currencyPair is not in view mode.'); @@ -805,13 +805,13 @@ describe(' - Cell editing', () => { expect(listener.lastCall.args[0].reason).to.equal('printableKeyDown'); }); - it(`should not publish 'cellEditStart' if space is pressed`, () => { - render(); + it(`should not publish 'cellEditStart' if space is pressed`, async () => { + const { user } = render(); const listener = spy(); apiRef.current.subscribeEvent('cellEditStart', listener); const cell = getCell(0, 1); - fireUserEvent.mousePress(cell); - fireEvent.keyDown(cell, { key: ' ' }); + await user.click(cell); + await user.keyboard('[Space]'); expect(listener.callCount).to.equal(0); }); }); @@ -1167,15 +1167,15 @@ describe(' - Cell editing', () => { }); describe('by pressing Tab', () => { - it(`should publish 'cellEditStop' with reason=tabKeyDown`, () => { - render(); + it(`should publish 'cellEditStop' with reason=tabKeyDown`, async () => { + const { user } = render(); const listener = spy(); apiRef.current.subscribeEvent('cellEditStop', listener); const cell = getCell(0, 1); - fireUserEvent.mousePress(cell); - fireEvent.doubleClick(cell); + await user.click(cell); + await user.dblClick(cell); expect(listener.callCount).to.equal(0); - fireEvent.keyDown(cell, { key: 'Tab' }); + await user.keyboard('{Tab}'); expect(listener.lastCall.args[0].reason).to.equal('tabKeyDown'); }); @@ -1255,9 +1255,9 @@ describe(' - Cell editing', () => { const { setProps } = render( , ); - await act(() => - apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }), - ); + await act(() => { + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }); + }); setProps({ cellModesModel: { 0: { currencyPair: { mode: GridCellModes.View, cellToFocusAfter: 'below' } }, diff --git a/packages/x-data-grid-pro/src/tests/columnPinning.DataGridPro.test.tsx b/packages/x-data-grid-pro/src/tests/columnPinning.DataGridPro.test.tsx index 448aa1d0c63ca..66a6efd68d318 100644 --- a/packages/x-data-grid-pro/src/tests/columnPinning.DataGridPro.test.tsx +++ b/packages/x-data-grid-pro/src/tests/columnPinning.DataGridPro.test.tsx @@ -261,15 +261,15 @@ describe(' - Column pinning', () => { }); describe('props: onPinnedColumnsChange', () => { - it('should call when a column is pinned', () => { + it('should call when a column is pinned', async () => { const handlePinnedColumnsChange = spy(); render(); - act(() => apiRef.current.pinColumn('currencyPair', GridPinnedColumnPosition.LEFT)); + await act(() => apiRef.current.pinColumn('currencyPair', GridPinnedColumnPosition.LEFT)); expect(handlePinnedColumnsChange.lastCall.args[0]).to.deep.equal({ left: ['currencyPair'], right: [], }); - act(() => apiRef.current.pinColumn('price17M', GridPinnedColumnPosition.RIGHT)); + await act(() => apiRef.current.pinColumn('price17M', GridPinnedColumnPosition.RIGHT)); expect(handlePinnedColumnsChange.lastCall.args[0]).to.deep.equal({ left: ['currencyPair'], right: ['price17M'], @@ -285,7 +285,7 @@ describe(' - Column pinning', () => { />, ); expect($$(`[role="gridcell"].${gridClasses['cell--pinnedLeft']}`)).to.have.length(1); - act(() => apiRef.current.pinColumn('price17M', GridPinnedColumnPosition.LEFT)); + await act(() => apiRef.current.pinColumn('price17M', GridPinnedColumnPosition.LEFT)); await microtasks(); expect($$(`[role="gridcell"].${gridClasses['cell--pinnedLeft']}`)).to.have.length(1); expect(handlePinnedColumnsChange.lastCall.args[0]).to.deep.equal({ @@ -296,7 +296,7 @@ describe(' - Column pinning', () => { }); describe('prop: pinnedColumns', () => { - it('should pin the columns specified', () => { + it('should pin the columns specified', async () => { render(); const cell = document.querySelector( `.${gridClasses['cell--pinnedLeft']}[data-field="currencyPair"]`, @@ -304,12 +304,12 @@ describe(' - Column pinning', () => { expect(cell).not.to.equal(null); }); - it("should not change the pinned columns if the prop didn't change", () => { + it("should not change the pinned columns if the prop didn't change", async () => { render(); expect( document.querySelector(`.${gridClasses['cell--pinnedLeft']}[data-field="currencyPair"]`), ).not.to.equal(null); - act(() => apiRef.current.pinColumn('price17M', GridPinnedColumnPosition.LEFT)); + await act(() => apiRef.current.pinColumn('price17M', GridPinnedColumnPosition.LEFT)); expect( document.querySelector(`.${gridClasses['cell--pinnedLeft']}[data-field="currencyPair"]`), ).not.to.equal(null); @@ -354,9 +354,9 @@ describe(' - Column pinning', () => { expect(cell).not.to.equal(null); }); - it('should allow to pin column using `apiRef.current.pinColumn`', () => { + it('should allow to pin column using `apiRef.current.pinColumn`', async () => { render(); - act(() => apiRef.current.pinColumn('id', GridPinnedColumnPosition.LEFT)); + await act(() => apiRef.current.pinColumn('id', GridPinnedColumnPosition.LEFT)); const cell = document.querySelector( `.${gridClasses['cell--pinnedLeft']}[data-field="id"]`, )!; @@ -382,55 +382,57 @@ describe(' - Column pinning', () => { it('should not crash if a non-existent column is pinned', () => { expect(() => { render(); + }).not.to.throw(); + expect(() => { render(); }).not.to.throw(); }); describe('pinColumn', () => { - it('should pin the given column', () => { + it('should pin the given column', async () => { render(); expect($('[data-field="currencyPair"]')?.className).not.to.include('pinned'); - act(() => apiRef.current.pinColumn('currencyPair', GridPinnedColumnPosition.LEFT)); + await act(() => apiRef.current.pinColumn('currencyPair', GridPinnedColumnPosition.LEFT)); expect($(`.${gridClasses['cell--pinnedLeft']}[data-field="currencyPair"]`)).not.to.equal( null, ); }); - it('should change the side when called on a pinned column', () => { + it('should change the side when called on a pinned column', async () => { render(); const renderZone = $(`.${gridClasses.virtualScrollerRenderZone}`)!; expect($(renderZone, '[data-field="currencyPair"]')!.className).not.to.include('pinned'); - act(() => apiRef.current.pinColumn('currencyPair', GridPinnedColumnPosition.LEFT)); + await act(() => apiRef.current.pinColumn('currencyPair', GridPinnedColumnPosition.LEFT)); expect( $(renderZone, `.${gridClasses['cell--pinnedLeft']}[data-field="currencyPair"]`), ).not.to.equal(null); expect($(renderZone, '[data-field="currencyPair"]')!.className).to.include('pinned'); - act(() => apiRef.current.pinColumn('currencyPair', GridPinnedColumnPosition.RIGHT)); + await act(() => apiRef.current.pinColumn('currencyPair', GridPinnedColumnPosition.RIGHT)); expect($$(renderZone, `.${gridClasses['cell--pinnedLeft']}`).length).to.equal(0); expect( $(renderZone, `.${gridClasses['cell--pinnedRight']}[data-field="currencyPair"]`), ).not.to.equal(null); }); - it('should not change the columns when called on a pinned column with the same side ', () => { + it('should not change the columns when called on a pinned column with the same side', async () => { render(); - act(() => apiRef.current.pinColumn('currencyPair', GridPinnedColumnPosition.LEFT)); + await act(() => apiRef.current.pinColumn('currencyPair', GridPinnedColumnPosition.LEFT)); expect($$(`.${gridClasses['cell--pinnedLeft']}`)).to.have.length(1); - act(() => apiRef.current.pinColumn('currencyPair', GridPinnedColumnPosition.LEFT)); + await act(() => apiRef.current.pinColumn('currencyPair', GridPinnedColumnPosition.LEFT)); expect($$(`.${gridClasses['cell--pinnedLeft']}`)).to.have.length(1); }); }); describe('unpinColumn', () => { - it('should unpin the given column', () => { + it('should unpin the given column', async () => { render(); - act(() => apiRef.current.pinColumn('currencyPair', GridPinnedColumnPosition.LEFT)); + await act(() => apiRef.current.pinColumn('currencyPair', GridPinnedColumnPosition.LEFT)); expect($$(`.${gridClasses['cell--pinnedLeft']}`).length).not.to.equal(0); - act(() => apiRef.current.unpinColumn('currencyPair')); + await act(() => apiRef.current.unpinColumn('currencyPair')); expect($$(`.${gridClasses['cell--pinnedLeft']}`).length).to.equal(0); const renderZone = $(`.${gridClasses.virtualScrollerRenderZone}`)!; expect(renderZone.querySelector('[data-field="currencyPair"]')).not.to.equal(null); @@ -548,12 +550,14 @@ describe(' - Column pinning', () => { expect(getColumnHeadersTextContent()).to.deep.equal(['', 'id', 'Currency Pair', '1M', '2M']); }); - it('should restore the position when unpinning a column added after the first pinned column', () => { + it('should restore the position when unpinning a column added after the first pinned column', async () => { const { setProps } = render(); expect(getColumnHeadersTextContent()).to.deep.equal(['id', 'Currency Pair']); setProps({ pinnedColumns: { left: ['currencyPair'] } }); expect(getColumnHeadersTextContent()).to.deep.equal(['Currency Pair', 'id']); - act(() => apiRef.current.updateColumns([{ field: 'foo' }, { field: 'bar' }])); + await act(() => { + apiRef.current.updateColumns([{ field: 'foo' }, { field: 'bar' }]); + }); expect(getColumnHeadersTextContent()).to.deep.equal(['Currency Pair', 'id', 'foo', 'bar']); setProps({ pinnedColumns: { left: ['currencyPair', 'foo'] } }); expect(getColumnHeadersTextContent()).to.deep.equal(['Currency Pair', 'foo', 'id', 'bar']); @@ -561,12 +565,12 @@ describe(' - Column pinning', () => { expect(getColumnHeadersTextContent()).to.deep.equal(['id', 'Currency Pair', 'foo', 'bar']); }); - it('should restore the position of a column pinned before it is added', () => { + it('should restore the position of a column pinned before it is added', async () => { const { setProps } = render( , ); expect(getColumnHeadersTextContent()).to.deep.equal(['id', 'Currency Pair']); - act(() => apiRef.current.updateColumns([{ field: 'foo' }, { field: 'bar' }])); + await act(() => apiRef.current.updateColumns([{ field: 'foo' }, { field: 'bar' }])); expect(getColumnHeadersTextContent()).to.deep.equal(['foo', 'id', 'Currency Pair', 'bar']); setProps({ pinnedColumns: {} }); expect(getColumnHeadersTextContent()).to.deep.equal(['id', 'Currency Pair', 'foo', 'bar']); @@ -588,12 +592,12 @@ describe(' - Column pinning', () => { expect(getColumnHeadersTextContent()).to.deep.equal(['id', 'price1M']); }); - it('should restore the position when the neighboring columns are reordered', () => { + it('should restore the position when the neighboring columns are reordered', async () => { const { setProps } = render(); expect(getColumnHeadersTextContent()).to.deep.equal(['id', 'Currency Pair', '1M', '2M']); // price1M's index = 2 setProps({ pinnedColumns: { left: ['price1M'] } }); expect(getColumnHeadersTextContent()).to.deep.equal(['1M', 'id', 'Currency Pair', '2M']); - act(() => apiRef.current.setColumnIndex('id', 2)); + await act(() => apiRef.current.setColumnIndex('id', 2)); expect(getColumnHeadersTextContent()).to.deep.equal(['1M', 'Currency Pair', 'id', '2M']); setProps({ pinnedColumns: {} }); expect(getColumnHeadersTextContent()).to.deep.equal(['Currency Pair', 'id', '1M', '2M']); // price1M's index = 2 diff --git a/packages/x-data-grid-pro/src/tests/columnReorder.DataGridPro.test.tsx b/packages/x-data-grid-pro/src/tests/columnReorder.DataGridPro.test.tsx index 180920eca159d..82340efbe43e2 100644 --- a/packages/x-data-grid-pro/src/tests/columnReorder.DataGridPro.test.tsx +++ b/packages/x-data-grid-pro/src/tests/columnReorder.DataGridPro.test.tsx @@ -51,7 +51,7 @@ describe(' - Columns reorder', () => { }; it('resizing after columns reorder should respect the new columns order', async () => { - let apiRef: React.MutableRefObject; + let apiRef: React.RefObject; function TestCase(props: { width: number }) { const { width } = props; @@ -66,14 +66,14 @@ describe(' - Columns reorder', () => { const { setProps } = render(); expect(getColumnHeadersTextContent()).to.deep.equal(['id', 'brand']); - act(() => apiRef.current.setColumnIndex('id', 1)); + await act(() => apiRef.current.setColumnIndex('id', 1)); setProps({ width: 200 }); await raf(); expect(getColumnHeadersTextContent()).to.deep.equal(['brand', 'id']); }); - it('should not reset the column order when a prop change', () => { - let apiRef: React.MutableRefObject; + it('should not reset the column order when a prop change', async () => { + let apiRef: React.RefObject; const rows = [{ id: 0, brand: 'Nike' }]; const columns = [{ field: 'brand' }, { field: 'desc' }, { field: 'type' }]; @@ -89,7 +89,7 @@ describe(' - Columns reorder', () => { const { forceUpdate } = render(); expect(getColumnHeadersTextContent()).to.deep.equal(['brand', 'desc', 'type']); - act(() => apiRef.current.setColumnIndex('brand', 2)); + await act(() => apiRef.current.setColumnIndex('brand', 2)); expect(getColumnHeadersTextContent()).to.deep.equal(['desc', 'type', 'brand']); forceUpdate(); // test stability expect(getColumnHeadersTextContent()).to.deep.equal(['desc', 'type', 'brand']); diff --git a/packages/x-data-grid-pro/src/tests/components.DataGridPro.test.tsx b/packages/x-data-grid-pro/src/tests/components.DataGridPro.test.tsx index 6dcdef061528a..b7379576783cc 100644 --- a/packages/x-data-grid-pro/src/tests/components.DataGridPro.test.tsx +++ b/packages/x-data-grid-pro/src/tests/components.DataGridPro.test.tsx @@ -11,7 +11,6 @@ import { } from '@mui/x-data-grid-pro'; import { useBasicDemoData } from '@mui/x-data-grid-generator'; import { getCell, getRow } from 'test/utils/helperFn'; -import { fireUserEvent } from 'test/utils/fireUserEvent'; describe(' - Components', () => { const { render } = createRenderer(); @@ -78,17 +77,17 @@ describe(' - Components', () => { }); }); - it(`should still publish the 'cellKeyDown' event when overriding the 'onKeyDown' prop in slots.cell`, () => { + it(`should still publish the 'cellKeyDown' event when overriding the 'onKeyDown' prop in slots.cell`, async () => { const propHandler = spy(); const eventHandler = spy(); - render(); + const { user } = render(); apiRef!.current.subscribeEvent('cellKeyDown', eventHandler); expect(propHandler.callCount).to.equal(0); expect(eventHandler.callCount).to.equal(0); - fireUserEvent.mousePress(getCell(0, 0)); - fireEvent.keyDown(getCell(0, 0)); + await user.click(getCell(0, 0)); + await user.keyboard('a'); expect(propHandler.callCount).to.equal(1); expect(propHandler.lastCall.args[0]).not.to.equal(undefined); diff --git a/packages/x-data-grid-pro/src/tests/detailPanel.DataGridPro.test.tsx b/packages/x-data-grid-pro/src/tests/detailPanel.DataGridPro.test.tsx index 115a7b69feeb5..2bfa9c25a0a71 100644 --- a/packages/x-data-grid-pro/src/tests/detailPanel.DataGridPro.test.tsx +++ b/packages/x-data-grid-pro/src/tests/detailPanel.DataGridPro.test.tsx @@ -271,14 +271,14 @@ describe(' - Detail panel', () => { expect(virtualScroller.scrollTop).to.equal(0); }); - it('should toggle the detail panel when pressing Space on detail toggle cell', () => { - render(
Detail
} />); + it('should toggle the detail panel when pressing Space on detail toggle cell', async () => { + const { user } = render(
Detail
} />); expect(screen.queryByText('Detail')).to.equal(null); const cell = getCell(0, 0); - fireUserEvent.mousePress(cell); - fireEvent.keyDown(cell, { key: ' ' }); + await user.click(cell); + await user.keyboard('[Space]'); expect(screen.queryByText('Detail')).not.to.equal(null); - fireEvent.keyDown(cell, { key: ' ' }); + await user.keyboard('[Space]'); expect(screen.queryByText('Detail')).to.equal(null); }); @@ -298,9 +298,9 @@ describe(' - Detail panel', () => { expect(getCell(0, 1).firstChild).to.equal(screen.queryByRole('button', { name: 'Toggle' })); }); - it('should cache the content of getDetailPanelContent', () => { + it('should cache the content of getDetailPanelContent', async () => { const getDetailPanelContent = spy(() =>
Detail
); - const { setProps } = render( + const { setProps, user } = render( - Detail panel', () => { const expectedCallCount = reactMajor >= 19 ? 4 : 8; expect(getDetailPanelContent.callCount).to.equal(expectedCallCount); - fireEvent.click(screen.getByRole('button', { name: 'Expand' })); + await user.click(screen.getByRole('button', { name: 'Expand' })); expect(getDetailPanelContent.callCount).to.equal(expectedCallCount); - fireEvent.click(screen.getByRole('button', { name: /next page/i })); + await user.click(screen.getByRole('button', { name: /next page/i })); expect(getDetailPanelContent.callCount).to.equal(expectedCallCount); const getDetailPanelContent2 = spy(() =>
Detail
); setProps({ getDetailPanelContent: getDetailPanelContent2 }); - fireEvent.click(screen.getByRole('button', { name: 'Expand' })); + await user.click(screen.getByRole('button', { name: 'Expand' })); expect(getDetailPanelContent2.callCount).to.equal(2); // Called 2x by the effect - fireEvent.click(screen.getByRole('button', { name: /previous page/i })); + await user.click(screen.getByRole('button', { name: /previous page/i })); expect(getDetailPanelContent2.callCount).to.equal(2); }); - it('should cache the content of getDetailPanelHeight', () => { + it('should cache the content of getDetailPanelHeight', async () => { const getDetailPanelHeight = spy(() => 100); - const { setProps } = render( + const { setProps, user } = render( - Detail panel', () => { const expectedCallCount = reactMajor >= 19 ? 4 : 8; expect(getDetailPanelHeight.callCount).to.equal(expectedCallCount); - fireEvent.click(screen.getByRole('button', { name: 'Expand' })); + await user.click(screen.getByRole('button', { name: 'Expand' })); expect(getDetailPanelHeight.callCount).to.equal(expectedCallCount); - fireEvent.click(screen.getByRole('button', { name: /next page/i })); + await user.click(screen.getByRole('button', { name: /next page/i })); expect(getDetailPanelHeight.callCount).to.equal(expectedCallCount); const getDetailPanelHeight2 = spy(() => 200); setProps({ getDetailPanelHeight: getDetailPanelHeight2 }); - fireEvent.click(screen.getByRole('button', { name: 'Expand' })); + await user.click(screen.getByRole('button', { name: 'Expand' })); expect(getDetailPanelHeight2.callCount).to.equal(2); // Called 2x by the effect - fireEvent.click(screen.getByRole('button', { name: /previous page/i })); + await user.click(screen.getByRole('button', { name: /previous page/i })); expect(getDetailPanelHeight2.callCount).to.equal(2); }); @@ -443,9 +443,9 @@ describe(' - Detail panel', () => { expect(getDetailPanelHeight.lastCall.args[0].id).to.equal(0); }); - it('should not select the row when opening the detail panel', () => { + it('should not select the row when opening the detail panel', async () => { const handleRowSelectionModelChange = spy(); - render( + const { user } = render(
Detail
} onRowSelectionModelChange={handleRowSelectionModelChange} @@ -453,8 +453,7 @@ describe(' - Detail panel', () => { />, ); expect(screen.queryByText('Detail')).to.equal(null); - const cell = getCell(1, 0); - fireUserEvent.mousePress(cell); + await user.click(getCell(1, 0)); expect(handleRowSelectionModelChange.callCount).to.equal(0); }); @@ -539,21 +538,21 @@ describe(' - Detail panel', () => { }); describe('prop: onDetailPanelsExpandedRowIds', () => { - it('should call when a row is expanded or closed', () => { + it('should call when a row is expanded or closed', async () => { const handleDetailPanelsExpandedRowIdsChange = spy(); - render( + const { user } = render(
Detail
} onDetailPanelExpandedRowIdsChange={handleDetailPanelsExpandedRowIdsChange} />, ); - fireEvent.click(screen.getAllByRole('button', { name: 'Expand' })[0]); // Expand the 1st row + await user.click(screen.getAllByRole('button', { name: 'Expand' })[0]); // Expand the 1st row expect(handleDetailPanelsExpandedRowIdsChange.lastCall.args[0]).to.deep.equal([0]); - fireEvent.click(screen.getAllByRole('button', { name: 'Expand' })[0]); // Expand the 2nd row + await user.click(screen.getAllByRole('button', { name: 'Expand' })[0]); // Expand the 2nd row expect(handleDetailPanelsExpandedRowIdsChange.lastCall.args[0]).to.deep.equal([0, 1]); - fireEvent.click(screen.getAllByRole('button', { name: 'Collapse' })[0]); // Close the 1st row + await user.click(screen.getAllByRole('button', { name: 'Collapse' })[0]); // Close the 1st row expect(handleDetailPanelsExpandedRowIdsChange.lastCall.args[0]).to.deep.equal([1]); - fireEvent.click(screen.getAllByRole('button', { name: 'Collapse' })[0]); // Close the 2nd row + await user.click(screen.getAllByRole('button', { name: 'Collapse' })[0]); // Close the 2nd row expect(handleDetailPanelsExpandedRowIdsChange.lastCall.args[0]).to.deep.equal([]); }); diff --git a/packages/x-data-grid-pro/src/tests/editComponents.DataGridPro.test.tsx b/packages/x-data-grid-pro/src/tests/editComponents.DataGridPro.test.tsx index cf60cc02141c3..09a10b8652fad 100644 --- a/packages/x-data-grid-pro/src/tests/editComponents.DataGridPro.test.tsx +++ b/packages/x-data-grid-pro/src/tests/editComponents.DataGridPro.test.tsx @@ -232,12 +232,12 @@ describe(' - Edit components', () => { defaultData.columns = [{ field: 'createdAt', type: 'date', editable: true }]; }); - it('should call setEditCellValue with the value converted to Date', () => { - render(); + it('should call setEditCellValue with the value converted to Date', async () => { + const { user } = render(); const spiedSetEditCellValue = spyApi(apiRef.current, 'setEditCellValue'); const cell = getCell(0, 0); - fireEvent.doubleClick(cell); + await user.dblClick(cell); const input = cell.querySelector('input')!; expect(input.value).to.equal('2022-02-18'); @@ -353,12 +353,12 @@ describe(' - Edit components', () => { defaultData.columns = [{ field: 'createdAt', type: 'dateTime', editable: true }]; }); - it('should call setEditCellValue with the value converted to Date', () => { - render(); + it('should call setEditCellValue with the value converted to Date', async () => { + const { user } = render(); const spiedSetEditCellValue = spyApi(apiRef.current, 'setEditCellValue'); const cell = getCell(0, 0); - fireEvent.doubleClick(cell); + await user.dblClick(cell); const input = cell.querySelector('input')!; expect(input.value).to.equal('2022-02-18T14:30'); @@ -592,13 +592,16 @@ describe(' - Edit components', () => { defaultData.columns[0].renderEditCell = (params) => renderEditSingleSelectCell(params); - render(); + const { user } = render(); const cell = getCell(0, 0); - fireEvent.doubleClick(cell); - fireUserEvent.mousePress(screen.queryAllByRole('option')[1]); + await user.dblClick(cell); + await user.click(screen.queryAllByRole('option')[1]); await waitFor(() => expect(screen.queryByRole('listbox')).to.equal(null)); - fireEvent.keyDown(screen.getByRole('combobox'), { key: 'Enter' }); + await act(() => { + screen.getByRole('combobox').focus(); + }); + await user.keyboard('{Enter}'); expect(screen.queryByRole('listbox')).to.equal(null); resolveCallback!(); diff --git a/packages/x-data-grid-pro/src/tests/rowEditing.DataGridPro.test.tsx b/packages/x-data-grid-pro/src/tests/rowEditing.DataGridPro.test.tsx index 0605434f2a7e7..b63b6c91820b1 100644 --- a/packages/x-data-grid-pro/src/tests/rowEditing.DataGridPro.test.tsx +++ b/packages/x-data-grid-pro/src/tests/rowEditing.DataGridPro.test.tsx @@ -1241,13 +1241,13 @@ describe(' - Row editing', () => { expect(listener.lastCall.args[0].reason).to.equal('shiftTabKeyDown'); }); - it('should call stopRowEditMode with ignoreModifications=false and cellToFocusAfter=right', () => { - render(); + it('should call stopRowEditMode with ignoreModifications=false and cellToFocusAfter=right', async () => { + const { user } = render(); const spiedStopRowEditMode = spyApi(apiRef.current, 'stopRowEditMode'); const cell = getCell(0, 2); - fireUserEvent.mousePress(cell); - fireEvent.doubleClick(cell); - fireEvent.keyDown(cell.querySelector('input')!, { key: 'Tab' }); + await user.click(cell); + await user.dblClick(cell); + await user.keyboard('{Tab}'); expect(spiedStopRowEditMode.callCount).to.equal(1); expect(spiedStopRowEditMode.lastCall.args[0]).to.deep.equal({ id: 0, @@ -1500,7 +1500,12 @@ describe(' - Row editing', () => { }, [hasFocus, inputRef]); return ( - setInputRef(ref)} data-testid="input" /> + { + setInputRef(ref); + }} + data-testid="input" + /> ); } diff --git a/packages/x-data-grid-pro/src/tests/rowPinning.DataGridPro.test.tsx b/packages/x-data-grid-pro/src/tests/rowPinning.DataGridPro.test.tsx index 15f787bfdc454..dea9277b0605a 100644 --- a/packages/x-data-grid-pro/src/tests/rowPinning.DataGridPro.test.tsx +++ b/packages/x-data-grid-pro/src/tests/rowPinning.DataGridPro.test.tsx @@ -183,7 +183,7 @@ describe(' - Row pinning', () => { it('should update pinned rows when calling `apiRef.current.setPinnedRows` method', async () => { const data = getBasicGridData(20, 5); - let apiRef!: React.MutableRefObject; + let apiRef!: React.RefObject; function TestCase(props: any) { const [pinnedRow0, pinnedRow1, ...rows] = data.rows; @@ -214,8 +214,8 @@ describe(' - Row pinning', () => { let rows = data.rows.filter((row) => row.id !== 11 && row.id !== 3); // should work when calling `setPinnedRows` before `setRows` - act(() => apiRef.current.unstable_setPinnedRows(pinnedRows)); - act(() => apiRef.current.setRows(rows)); + await act(() => apiRef.current.unstable_setPinnedRows(pinnedRows)); + await act(() => apiRef.current.setRows(rows)); expect(isRowPinned(getRowById(0), 'top')).to.equal(false, '#0 pinned top'); expect(isRowPinned(getRowById(1), 'bottom')).to.equal(false, '#1 pinned bottom'); @@ -227,8 +227,8 @@ describe(' - Row pinning', () => { rows = data.rows.filter((row) => row.id !== 8 && row.id !== 5); // should work when calling `setPinnedRows` after `setRows` - act(() => apiRef.current.setRows(rows)); - act(() => apiRef.current.unstable_setPinnedRows(pinnedRows)); + await act(() => apiRef.current.setRows(rows)); + await act(() => apiRef.current.unstable_setPinnedRows(pinnedRows)); expect(isRowPinned(getRowById(11), 'top')).to.equal(false, '#11 pinned top'); expect(isRowPinned(getRowById(3), 'bottom')).to.equal(false, '#3 pinned bottom'); @@ -277,20 +277,20 @@ describe(' - Row pinning', () => { expect(isRowPinned(getRowById(1), 'bottom')).to.equal(true, '#1 pinned bottom'); }); - it('should not be impacted by sorting', () => { - render(); + it('should not be impacted by sorting', async () => { + const { user } = render(); expect(isRowPinned(getRowById(0), 'top')).to.equal(true, '#0 pinned top'); expect(isRowPinned(getRowById(1), 'bottom')).to.equal(true, '#1 pinned bottom'); expect(getColumnValues(0)).to.deep.equal(['0', '2', '3', '4', '1']); - fireEvent.click(getColumnHeaderCell(0)); + await user.click(getColumnHeaderCell(0)); expect(isRowPinned(getRowById(0), 'top')).to.equal(true, '#0 pinned top'); expect(isRowPinned(getRowById(1), 'bottom')).to.equal(true, '#1 pinned bottom'); expect(getColumnValues(0)).to.deep.equal(['0', '2', '3', '4', '1']); - fireEvent.click(getColumnHeaderCell(0)); + await user.click(getColumnHeaderCell(0)); expect(isRowPinned(getRowById(0), 'top')).to.equal(true, '#0 pinned top'); expect(isRowPinned(getRowById(1), 'bottom')).to.equal(true, '#1 pinned bottom'); @@ -339,7 +339,7 @@ describe(' - Row pinning', () => { return cell.parentElement!.getAttribute('data-id'); } - it('should work with top pinned rows', () => { + it('should work with top pinned rows', async () => { function TestCase() { const data = getBasicGridData(20, 5); const [pinnedRow0, pinnedRow1, ...rows] = data.rows; @@ -357,27 +357,24 @@ describe(' - Row pinning', () => { ); } - render(); + const { user } = render(); expect(isRowPinned(getRowById(1), 'top')).to.equal(true, '#1 pinned top'); expect(isRowPinned(getRowById(0), 'top')).to.equal(true, '#0 pinned top'); - fireUserEvent.mousePress(getCell(0, 0)); + await user.click(getCell(0, 0)); // first top pinned row expect(getActiveCellRowId()).to.equal('1'); - fireEvent.keyDown(getCell(0, 0), { key: 'ArrowDown' }); + await user.keyboard('{ArrowDown}'); // second top pinned row expect(getActiveCellRowId()).to.equal('0'); - fireEvent.keyDown(getCell(1, 0), { key: 'ArrowDown' }); + await user.keyboard('{ArrowDown}'); // first non-pinned row expect(getActiveCellRowId()).to.equal('2'); - fireEvent.keyDown(getCell(2, 0), { key: 'ArrowRight' }); - fireEvent.keyDown(getCell(2, 1), { key: 'ArrowUp' }); - fireEvent.keyDown(getCell(1, 1), { key: 'ArrowUp' }); - fireEvent.keyDown(getCell(0, 1), { key: 'ArrowUp' }); + await user.keyboard('{ArrowRight}{ArrowUp}{ArrowUp}{ArrowUp}'); expect(getActiveColumnHeader()).to.equal('1'); }); @@ -627,8 +624,8 @@ describe(' - Row pinning', () => { expect(cell.querySelector(`.${gridClasses.rowReorderCell}`)).to.equal(null); }); - it('should keep pinned rows on page change', () => { - render( + it('should keep pinned rows on page change', async () => { + const { user } = render( - Row pinning', () => { expect(isRowPinned(getRowById(0), 'top')).to.equal(true, '#0 pinned top'); expect(isRowPinned(getRowById(1), 'bottom')).to.equal(true, '#1 pinned bottom'); - fireEvent.click(screen.getByRole('button', { name: /next page/i })); + await user.click(screen.getByRole('button', { name: /next page/i })); expect(isRowPinned(getRowById(0), 'top')).to.equal(true, '#0 pinned top'); expect(isRowPinned(getRowById(1), 'bottom')).to.equal(true, '#1 pinned bottom'); - fireEvent.click(screen.getByRole('button', { name: /next page/i })); + await user.click(screen.getByRole('button', { name: /next page/i })); expect(isRowPinned(getRowById(0), 'top')).to.equal(true, '#0 pinned top'); expect(isRowPinned(getRowById(1), 'bottom')).to.equal(true, '#1 pinned bottom'); diff --git a/packages/x-data-grid-pro/src/tests/rowSelection.DataGridPro.test.tsx b/packages/x-data-grid-pro/src/tests/rowSelection.DataGridPro.test.tsx index c9e93334b13a4..8eb9f3c11e4eb 100644 --- a/packages/x-data-grid-pro/src/tests/rowSelection.DataGridPro.test.tsx +++ b/packages/x-data-grid-pro/src/tests/rowSelection.DataGridPro.test.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import { expect } from 'chai'; import { spy } from 'sinon'; import { getCell, getColumnValues, getRows } from 'test/utils/helperFn'; -import { createRenderer, fireEvent, screen, act } from '@mui/internal-test-utils'; +import { createRenderer, screen, act, reactMajor, fireEvent } from '@mui/internal-test-utils'; import { GridApi, useGridApiRef, @@ -169,10 +169,10 @@ describe(' - Row selection', () => { ); } - it('should keep the previously selected tree data parent selected if it becomes leaf after filtering', () => { - render(); + it('should keep the previously selected tree data parent selected if it becomes leaf after filtering', async () => { + const { user } = render(); - fireEvent.click( + await user.click( screen.getByRole('checkbox', { name: /select all rows/i, }), @@ -180,7 +180,7 @@ describe(' - Row selection', () => { expect(apiRef.current.getSelectedRows()).to.have.length(15); - act(() => { + await act(() => { apiRef.current.setFilterModel({ items: [ { @@ -196,7 +196,7 @@ describe(' - Row selection', () => { }); // Context: https://github.com/mui/mui-x/issues/15045 - it('should not throw when using `isRowSelectable` and `keepNonExistentRowsSelected`', () => { + it('should not throw when using `isRowSelectable` and `keepNonExistentRowsSelected`', async () => { function TestDataGrid() { const [gridRows, setRows] = React.useState(rows); const onFilterChange = React.useCallback( @@ -222,10 +222,10 @@ describe(' - Row selection', () => { /> ); } - render(); + const { user } = render(); // Select `Thomas` - fireEvent.click( + await user.click( screen.getAllByRole('checkbox', { name: /select row/i, })[1], @@ -234,7 +234,7 @@ describe(' - Row selection', () => { expect(apiRef.current.getSelectedRows()).to.have.length(1); expect(Array.from(apiRef.current.getSelectedRows())[0][0]).to.equal(1); - act(() => { + await act(() => { apiRef.current.setFilterModel({ items: [{ field: 'jobTitle', value: 'Head of Human Resources', operator: 'contains' }], }); @@ -245,23 +245,23 @@ describe(' - Row selection', () => { }); // Context: https://github.com/mui/mui-x/issues/15068 - it('should not call `onRowSelectionModelChange` when adding a new row', () => { + it('should not call `onRowSelectionModelChange` when adding a new row', async () => { const onRowSelectionModelChange = spy(); const { setProps } = render( , ); - act(() => { + await act(() => { setProps({ rows: [...rows, { id: 15, hierarchy: ['New'], jobTitle: 'Test Job' }] }); }); expect(onRowSelectionModelChange.callCount).to.equal(0); }); - it('should put the parent into indeterminate if some but not all the children are selected', () => { - render(); + it('should put the parent into indeterminate if some but not all the children are selected', async () => { + const { user } = render(); - fireEvent.click(getCell(2, 0).querySelector('input')!); + await user.click(getCell(2, 0).querySelector('input')!); expect(getCell(1, 0).querySelector('input')!).to.have.attr('data-indeterminate', 'true'); }); @@ -282,8 +282,8 @@ describe(' - Row selection', () => { }); describe('prop: checkboxSelectionVisibleOnly = false', () => { - it('should select all rows of all pages if no row is selected', () => { - render( + it('should select all rows of all pages if no row is selected', async () => { + const { user } = render( - Row selection', () => { const selectAllCheckbox: HTMLInputElement = screen.getByRole('checkbox', { name: /select all rows/i, }); - fireEvent.click(selectAllCheckbox); + await user.click(selectAllCheckbox); expect(apiRef.current.getSelectedRows()).to.have.length(4); expect(selectAllCheckbox.checked).to.equal(true); }); - it('should unselect all rows of all the pages if 1 row of another page is selected', () => { - render( + it('should unselect all rows of all the pages if 1 row of another page is selected', async () => { + const { user } = render( - Row selection', () => { pageSizeOptions={[2]} />, ); - fireEvent.click(getCell(0, 0).querySelector('input')!); + await user.click(getCell(0, 0).querySelector('input')!); expect(apiRef.current.getSelectedRows()).to.have.keys([0]); - fireEvent.click(screen.getByRole('button', { name: /next page/i })); + await user.click(screen.getByRole('button', { name: /next page/i })); const selectAllCheckbox: HTMLInputElement = screen.getByRole('checkbox', { name: /select all rows/i, }); - fireEvent.click(selectAllCheckbox); + await user.click(selectAllCheckbox); expect(apiRef.current.getSelectedRows()).to.have.length(0); expect(selectAllCheckbox.checked).to.equal(false); }); - it('should select all visible rows if pagination is not enabled', () => { + it('should select all visible rows if pagination is not enabled', async () => { const rowLength = 10; - render( + const { user } = render( - Row selection', () => { const selectAllCheckbox: HTMLInputElement = screen.getByRole('checkbox', { name: /select all rows/i, }); - fireEvent.click(selectAllCheckbox); + await user.click(selectAllCheckbox); expect(apiRef.current.getSelectedRows()).to.have.length(rowLength); expect(selectAllCheckbox.checked).to.equal(true); }); - it('should set the header checkbox in a indeterminate state when some rows of other pages are not selected', () => { - render( + it('should set the header checkbox in a indeterminate state when some rows of other pages are not selected', async () => { + const { user } = render( - Row selection', () => { name: /select all rows/i, }); - fireEvent.click(getCell(0, 0).querySelector('input')!); - fireEvent.click(getCell(1, 0).querySelector('input')!); - fireEvent.click(screen.getByRole('button', { name: /next page/i })); + await user.click(getCell(0, 0).querySelector('input')!); + await user.click(getCell(1, 0).querySelector('input')!); + await user.click(screen.getByRole('button', { name: /next page/i })); expect(selectAllCheckbox).to.have.attr('data-indeterminate', 'true'); }); - it('should not select more than one row when disableMultipleRowSelection = true', () => { - render(); + it('should not select more than one row when disableMultipleRowSelection = true', async () => { + const { user } = render( + , + ); const input1 = getCell(0, 0).querySelector('input')!; - fireEvent.click(input1); + await user.click(input1); expect(input1.checked).to.equal(true); const input2 = getCell(1, 0).querySelector('input')!; - fireEvent.click(input2); + await user.click(input2); expect(input1.checked).to.equal(false); expect(input2.checked).to.equal(true); }); @@ -383,8 +385,8 @@ describe(' - Row selection', () => { ); }); - it('should select all the rows of the current page if no row of the current page is selected', () => { - render( + it('should select all the rows of the current page if no row of the current page is selected', async () => { + const { user } = render( - Row selection', () => { />, ); - fireEvent.click(getCell(0, 0).querySelector('input')!); + await user.click(getCell(0, 0).querySelector('input')!); expect(apiRef.current.getSelectedRows()).to.have.keys([0]); - fireEvent.click(screen.getByRole('button', { name: /next page/i })); + await user.click(screen.getByRole('button', { name: /next page/i })); const selectAllCheckbox: HTMLInputElement = screen.getByRole('checkbox', { name: /select all rows/i, }); - fireEvent.click(selectAllCheckbox); + await user.click(selectAllCheckbox); expect(apiRef.current.getSelectedRows()).to.have.keys([0, 2, 3]); expect(selectAllCheckbox.checked).to.equal(true); }); - it('should unselect all the rows of the current page if 1 row of the current page is selected', () => { - render( + it('should unselect all the rows of the current page if 1 row of the current page is selected', async () => { + const { user } = render( - Row selection', () => { />, ); - fireEvent.click(getCell(0, 0).querySelector('input')!); + await user.click(getCell(0, 0).querySelector('input')!); expect(apiRef.current.getSelectedRows()).to.have.keys([0]); - fireEvent.click(screen.getByRole('button', { name: /next page/i })); - fireEvent.click(getCell(2, 0).querySelector('input')!); + await user.click(screen.getByRole('button', { name: /next page/i })); + await user.click(getCell(2, 0).querySelector('input')!); expect(apiRef.current.getSelectedRows()).to.have.keys([0, 2]); const selectAllCheckbox: HTMLInputElement = screen.getByRole('checkbox', { name: /select all rows/i, }); - fireEvent.click(selectAllCheckbox); + await user.click(selectAllCheckbox); expect(apiRef.current.getSelectedRows()).to.have.keys([0]); expect(selectAllCheckbox.checked).to.equal(false); }); - it('should not set the header checkbox in a indeterminate state when some rows of other pages are not selected', () => { - render( + it('should not set the header checkbox in a indeterminate state when some rows of other pages are not selected', async () => { + const { user } = render( - Row selection', () => { />, ); - fireEvent.click(getCell(0, 0)); - fireEvent.click(getCell(1, 0)); - fireEvent.click(screen.getByRole('button', { name: /next page/i })); + await user.click(getCell(0, 0)); + await user.click(getCell(1, 0)); + await user.click(screen.getByRole('button', { name: /next page/i })); const selectAllCheckbox = screen.getByRole('checkbox', { name: /select all rows/i, }); expect(selectAllCheckbox).to.have.attr('data-indeterminate', 'false'); }); - it('should allow to select all the current page rows when props.paginationMode="server"', () => { + it('should allow to select all the current page rows when props.paginationMode="server"', async () => { function TestDataGridSelectionServerSide({ rowLength = 4, }: Omit & @@ -479,19 +481,19 @@ describe(' - Row selection', () => { ); } - render(); + const { user } = render(); const selectAllCheckbox = screen.getByRole('checkbox', { name: /select all rows/i, }); - fireEvent.click(selectAllCheckbox); + await user.click(selectAllCheckbox); expect(apiRef.current.getSelectedRows()).to.have.length(2); }); // https://github.com/mui/mui-x/issues/14074 - it('should select all the rows of the current page keeping the previously selected rows when a filter is applied', () => { - render( + it('should select all the rows of the current page keeping the previously selected rows when a filter is applied', async () => { + const { user } = render( - Row selection', () => { />, ); - fireEvent.click(getCell(0, 0).querySelector('input')!); + await user.click(getCell(0, 0).querySelector('input')!); expect(apiRef.current.getSelectedRows()).to.have.keys([0]); - fireEvent.click(screen.getByRole('button', { name: /next page/i })); + await user.click(screen.getByRole('button', { name: /next page/i })); const selectAllCheckbox: HTMLInputElement = screen.getByRole('checkbox', { name: /select all rows/i, }); - fireEvent.click(selectAllCheckbox); + await user.click(selectAllCheckbox); expect(apiRef.current.getSelectedRows()).to.have.keys([0, 3, 4]); expect(selectAllCheckbox.checked).to.equal(true); }); @@ -546,65 +548,71 @@ describe(' - Row selection', () => { expect(onRowSelectionModelChange.callCount).to.equal(0); }); - it('should select the parent only when selecting it', () => { - render(); + it('should select the parent only when selecting it', async () => { + const { user } = render(); - fireEvent.click(getCell(1, 0).querySelector('input')!); + await user.click(getCell(1, 0).querySelector('input')!); expect(apiRef.current.getSelectedRows()).to.have.keys([1]); }); - it('should deselect the parent only when deselecting it', () => { - render(); + it('should deselect the parent only when deselecting it', async () => { + const { user } = render( + , + ); - fireEvent.click(getCell(1, 0).querySelector('input')!); - fireEvent.click(getCell(2, 0).querySelector('input')!); + await user.click(getCell(1, 0).querySelector('input')!); + await user.click(getCell(2, 0).querySelector('input')!); expect(apiRef.current.getSelectedRows()).to.have.keys([1, 2]); - fireEvent.click(getCell(1, 0).querySelector('input')!); + await user.click(getCell(1, 0).querySelector('input')!); expect(apiRef.current.getSelectedRows()).to.have.keys([2]); }); - it('should not auto select the parent if all the children are selected', () => { - render(); + it('should not auto select the parent if all the children are selected', async () => { + const { user } = render( + , + ); - fireEvent.click(getCell(2, 0).querySelector('input')!); - fireEvent.click(getCell(3, 0).querySelector('input')!); - fireEvent.click(getCell(4, 0).querySelector('input')!); - fireEvent.click(getCell(5, 0).querySelector('input')!); - fireEvent.click(getCell(6, 0).querySelector('input')!); - fireEvent.click(getCell(7, 0).querySelector('input')!); + await user.click(getCell(2, 0).querySelector('input')!); + await user.click(getCell(3, 0).querySelector('input')!); + await user.click(getCell(4, 0).querySelector('input')!); + await user.click(getCell(5, 0).querySelector('input')!); + await user.click(getCell(6, 0).querySelector('input')!); + await user.click(getCell(7, 0).querySelector('input')!); // The parent row (Thomas, id: 1) should not be among the selected rows expect(apiRef.current.getSelectedRows()).to.have.keys([2, 3, 4, 5, 6, 7]); }); - it('should not deselect selected parent if one of the children is deselected', () => { - render(); + it('should not deselect selected parent if one of the children is deselected', async () => { + const { user } = render( + , + ); - fireEvent.click(getCell(1, 0).querySelector('input')!); - fireEvent.click(getCell(2, 0).querySelector('input')!); - fireEvent.click(getCell(3, 0).querySelector('input')!); - fireEvent.click(getCell(4, 0).querySelector('input')!); - fireEvent.click(getCell(5, 0).querySelector('input')!); - fireEvent.click(getCell(6, 0).querySelector('input')!); - fireEvent.click(getCell(7, 0).querySelector('input')!); + await user.click(getCell(1, 0).querySelector('input')!); + await user.click(getCell(2, 0).querySelector('input')!); + await user.click(getCell(3, 0).querySelector('input')!); + await user.click(getCell(4, 0).querySelector('input')!); + await user.click(getCell(5, 0).querySelector('input')!); + await user.click(getCell(6, 0).querySelector('input')!); + await user.click(getCell(7, 0).querySelector('input')!); expect(apiRef.current.getSelectedRows()).to.have.keys([1, 2, 3, 4, 5, 6, 7]); - fireEvent.click(getCell(2, 0).querySelector('input')!); + await user.click(getCell(2, 0).querySelector('input')!); // The parent row (Thomas, id: 1) should still be among the selected rows expect(apiRef.current.getSelectedRows()).to.have.keys([1, 3, 4, 5, 6, 7]); }); - it('should select only the unwrapped rows when clicking "Select All" checkbox', () => { - render(); + it('should select only the unwrapped rows when clicking "Select All" checkbox', async () => { + const { user } = render(); - fireEvent.click(screen.getByRole('checkbox', { name: /select all rows/i })); + await user.click(screen.getByRole('checkbox', { name: /select all rows/i })); expect(apiRef.current.getSelectedRows()).to.have.keys([0, 1, 8]); }); - it('should deselect only the unwrapped rows when clicking "Select All" checkbox', () => { - render(); + it('should deselect only the unwrapped rows when clicking "Select All" checkbox', async () => { + const { user } = render(); - fireEvent.click(screen.getByRole('checkbox', { name: /select all rows/i })); + await user.click(screen.getByRole('checkbox', { name: /select all rows/i })); expect(apiRef.current.getSelectedRows()).to.have.keys([0, 1, 8]); - fireEvent.click(screen.getByRole('checkbox', { name: /select all rows/i })); + await user.click(screen.getByRole('checkbox', { name: /select all rows/i })); expect(apiRef.current.getSelectedRows().size).to.equal(0); }); }); @@ -616,58 +624,62 @@ describe(' - Row selection', () => { ); } - it('should select all the children when selecting a parent', () => { - render(); + it('should select all the children when selecting a parent', async () => { + const { user } = render(); - fireEvent.click(getCell(1, 0).querySelector('input')!); + await user.click(getCell(1, 0).querySelector('input')!); expect(apiRef.current.getSelectedRows()).to.have.keys([1, 2, 3, 4, 5, 6, 7]); }); - it('should deselect all the children when deselecting a parent', () => { - render(); + it('should deselect all the children when deselecting a parent', async () => { + const { user } = render(); - fireEvent.click(getCell(1, 0).querySelector('input')!); + await user.click(getCell(1, 0).querySelector('input')!); expect(apiRef.current.getSelectedRows()).to.have.keys([1, 2, 3, 4, 5, 6, 7]); - fireEvent.click(getCell(1, 0).querySelector('input')!); + await user.click(getCell(1, 0).querySelector('input')!); expect(apiRef.current.getSelectedRows().size).to.equal(0); }); - it('should not auto select the parent if all the children are selected', () => { - render(); + it('should not auto select the parent if all the children are selected', async () => { + const { user } = render( + , + ); - fireEvent.click(getCell(2, 0).querySelector('input')!); - fireEvent.click(getCell(3, 0).querySelector('input')!); - fireEvent.click(getCell(4, 0).querySelector('input')!); - fireEvent.click(getCell(5, 0).querySelector('input')!); - fireEvent.click(getCell(6, 0).querySelector('input')!); - fireEvent.click(getCell(7, 0).querySelector('input')!); + await user.click(getCell(2, 0).querySelector('input')!); + await user.click(getCell(3, 0).querySelector('input')!); + await user.click(getCell(4, 0).querySelector('input')!); + await user.click(getCell(5, 0).querySelector('input')!); + await user.click(getCell(6, 0).querySelector('input')!); + await user.click(getCell(7, 0).querySelector('input')!); // The parent row (Thomas, id: 1) should not be among the selected rows expect(apiRef.current.getSelectedRows()).to.have.keys([2, 3, 4, 5, 6, 7]); }); - it('should not deselect selected parent if one of the children is deselected', () => { - render(); + it('should not deselect selected parent if one of the children is deselected', async () => { + const { user } = render( + , + ); - fireEvent.click(getCell(1, 0).querySelector('input')!); + await user.click(getCell(1, 0).querySelector('input')!); expect(apiRef.current.getSelectedRows()).to.have.keys([1, 2, 3, 4, 5, 6, 7]); - fireEvent.click(getCell(2, 0).querySelector('input')!); + await user.click(getCell(2, 0).querySelector('input')!); // The parent row (Thomas, id: 1) should still be among the selected rows expect(apiRef.current.getSelectedRows()).to.have.keys([1, 3, 4, 5, 6, 7]); }); - it('should select all the nested rows when clicking "Select All" checkbox', () => { - render(); + it('should select all the nested rows when clicking "Select All" checkbox', async () => { + const { user } = render(); - fireEvent.click(screen.getByRole('checkbox', { name: /select all rows/i })); + await user.click(screen.getByRole('checkbox', { name: /select all rows/i })); expect(apiRef.current.getSelectedRows().size).to.equal(15); }); - it('should deselect all the nested rows when clicking "Select All" checkbox', () => { - render(); + it('should deselect all the nested rows when clicking "Select All" checkbox', async () => { + const { user } = render(); - fireEvent.click(screen.getByRole('checkbox', { name: /select all rows/i })); + await user.click(screen.getByRole('checkbox', { name: /select all rows/i })); expect(apiRef.current.getSelectedRows().size).to.equal(15); - fireEvent.click(screen.getByRole('checkbox', { name: /select all rows/i })); + await user.click(screen.getByRole('checkbox', { name: /select all rows/i })); expect(apiRef.current.getSelectedRows().size).to.equal(0); }); @@ -685,8 +697,8 @@ describe(' - Row selection', () => { expect(apiRef.current.getSelectedRows().size).to.equal(0); }); - it('should not auto-select a descendant if not allowed', () => { - render( + it('should not auto-select a descendant if not allowed', async () => { + const { user } = render( - Row selection', () => { />, ); - fireEvent.click(getCell(1, 0).querySelector('input')!); + await user.click(getCell(1, 0).querySelector('input')!); expect(apiRef.current.getSelectedRows()).to.have.keys([1, 3, 4, 5, 6, 7]); }); }); @@ -716,58 +728,64 @@ describe(' - Row selection', () => { />, ); - expect(onRowSelectionModelChange.callCount).to.equal(2); // Dev mode calls twice + expect(onRowSelectionModelChange.callCount).to.equal(reactMajor < 19 ? 2 : 1); // Dev mode calls twice on React 18 expect(onRowSelectionModelChange.lastCall.args[0]).to.deep.equal([2, 3, 4, 5, 6, 7, 1]); }); - it('should select the parent only when selecting it', () => { - render(); + it('should select the parent only when selecting it', async () => { + const { user } = render(); - fireEvent.click(getCell(1, 0).querySelector('input')!); + await user.click(getCell(1, 0).querySelector('input')!); expect(apiRef.current.getSelectedRows()).to.have.keys([1]); }); - it('should deselect the parent only when deselecting it', () => { - render(); + it('should deselect the parent only when deselecting it', async () => { + const { user } = render( + , + ); - fireEvent.click(getCell(1, 0).querySelector('input')!); - fireEvent.click(getCell(2, 0).querySelector('input')!); + await user.click(getCell(1, 0).querySelector('input')!); + await user.click(getCell(2, 0).querySelector('input')!); expect(apiRef.current.getSelectedRows()).to.have.keys([1, 2]); - fireEvent.click(getCell(1, 0).querySelector('input')!); + await user.click(getCell(1, 0).querySelector('input')!); expect(apiRef.current.getSelectedRows()).to.have.keys([2]); }); - it('should auto select the parent if all the children are selected', () => { - render(); + it('should auto select the parent if all the children are selected', async () => { + const { user } = render( + , + ); - fireEvent.click(getCell(2, 0).querySelector('input')!); - fireEvent.click(getCell(3, 0).querySelector('input')!); - fireEvent.click(getCell(4, 0).querySelector('input')!); - fireEvent.click(getCell(5, 0).querySelector('input')!); - fireEvent.click(getCell(6, 0).querySelector('input')!); - fireEvent.click(getCell(7, 0).querySelector('input')!); + await user.click(getCell(2, 0).querySelector('input')!); + await user.click(getCell(3, 0).querySelector('input')!); + await user.click(getCell(4, 0).querySelector('input')!); + await user.click(getCell(5, 0).querySelector('input')!); + await user.click(getCell(6, 0).querySelector('input')!); + await user.click(getCell(7, 0).querySelector('input')!); // The parent row (Thomas, id: 1) should be among the selected rows expect(apiRef.current.getSelectedRows()).to.have.keys([2, 3, 4, 5, 6, 7, 1]); }); - it('should deselect selected parent if one of the children is deselected', () => { - render(); + it('should deselect selected parent if one of the children is deselected', async () => { + const { user } = render( + , + ); - fireEvent.click(getCell(2, 0).querySelector('input')!); - fireEvent.click(getCell(3, 0).querySelector('input')!); - fireEvent.click(getCell(4, 0).querySelector('input')!); - fireEvent.click(getCell(5, 0).querySelector('input')!); - fireEvent.click(getCell(6, 0).querySelector('input')!); - fireEvent.click(getCell(7, 0).querySelector('input')!); + await user.click(getCell(2, 0).querySelector('input')!); + await user.click(getCell(3, 0).querySelector('input')!); + await user.click(getCell(4, 0).querySelector('input')!); + await user.click(getCell(5, 0).querySelector('input')!); + await user.click(getCell(6, 0).querySelector('input')!); + await user.click(getCell(7, 0).querySelector('input')!); expect(apiRef.current.getSelectedRows()).to.have.keys([2, 3, 4, 5, 6, 7, 1]); - fireEvent.click(getCell(2, 0).querySelector('input')!); + await user.click(getCell(2, 0).querySelector('input')!); // The parent row (Thomas, id: 1) should not be among the selected rows expect(apiRef.current.getSelectedRows()).to.have.keys([3, 4, 5, 6, 7]); }); describe('prop: isRowSelectable', () => { - it('should not auto select a parent if not allowed', () => { - render( + it('should not auto select a parent if not allowed', async () => { + const { user } = render( - Row selection', () => { />, ); - fireEvent.click(getCell(2, 0).querySelector('input')!); - fireEvent.click(getCell(3, 0).querySelector('input')!); - fireEvent.click(getCell(4, 0).querySelector('input')!); - fireEvent.click(getCell(5, 0).querySelector('input')!); - fireEvent.click(getCell(6, 0).querySelector('input')!); - fireEvent.click(getCell(7, 0).querySelector('input')!); + await user.click(getCell(2, 0).querySelector('input')!); + await user.click(getCell(3, 0).querySelector('input')!); + await user.click(getCell(4, 0).querySelector('input')!); + await user.click(getCell(5, 0).querySelector('input')!); + await user.click(getCell(6, 0).querySelector('input')!); + await user.click(getCell(7, 0).querySelector('input')!); // The parent row (Thomas, id: 1) should still not be among the selected rows expect(apiRef.current.getSelectedRows()).to.have.keys([2, 3, 4, 5, 6, 7]); }); @@ -794,47 +812,51 @@ describe(' - Row selection', () => { ); } - it('should select all the children when selecting a parent', () => { - render(); + it('should select all the children when selecting a parent', async () => { + const { user } = render(); - fireEvent.click(getCell(1, 0).querySelector('input')!); + await user.click(getCell(1, 0).querySelector('input')!); expect(apiRef.current.getSelectedRows()).to.have.keys([1, 2, 3, 4, 5, 6, 7]); }); - it('should deselect all the children when deselecting a parent', () => { - render(); + it('should deselect all the children when deselecting a parent', async () => { + const { user } = render(); - fireEvent.click(getCell(1, 0).querySelector('input')!); + await user.click(getCell(1, 0).querySelector('input')!); expect(apiRef.current.getSelectedRows()).to.have.keys([1, 2, 3, 4, 5, 6, 7]); - fireEvent.click(getCell(1, 0).querySelector('input')!); + await user.click(getCell(1, 0).querySelector('input')!); expect(apiRef.current.getSelectedRows().size).to.equal(0); }); - it('should auto select the parent if all the children are selected', () => { - render(); + it('should auto select the parent if all the children are selected', async () => { + const { user } = render( + , + ); - fireEvent.click(getCell(9, 0).querySelector('input')!); - fireEvent.click(getCell(11, 0).querySelector('input')!); - fireEvent.click(getCell(12, 0).querySelector('input')!); + await user.click(getCell(9, 0).querySelector('input')!); + await user.click(getCell(11, 0).querySelector('input')!); + await user.click(getCell(12, 0).querySelector('input')!); // The parent row (Mary, id: 8) should be among the selected rows expect(apiRef.current.getSelectedRows()).to.have.keys([9, 10, 11, 12, 8, 13, 14]); }); - it('should deselect auto selected parent if one of the children is deselected', () => { - render(); + it('should deselect auto selected parent if one of the children is deselected', async () => { + const { user } = render( + , + ); - fireEvent.click(getCell(9, 0).querySelector('input')!); - fireEvent.click(getCell(11, 0).querySelector('input')!); - fireEvent.click(getCell(12, 0).querySelector('input')!); + await user.click(getCell(9, 0).querySelector('input')!); + await user.click(getCell(11, 0).querySelector('input')!); + await user.click(getCell(12, 0).querySelector('input')!); expect(apiRef.current.getSelectedRows()).to.have.keys([9, 10, 11, 12, 8, 13, 14]); - fireEvent.click(getCell(9, 0).querySelector('input')!); + await user.click(getCell(9, 0).querySelector('input')!); expect(apiRef.current.getSelectedRows()).to.have.keys([11, 12, 13, 14]); }); describe("prop: indeterminateCheckboxAction = 'select'", () => { - it('should select all the children when selecting an indeterminate parent', () => { - render( + it('should select all the children when selecting an indeterminate parent', async () => { + const { user } = render( - Row selection', () => { />, ); - fireEvent.click(getCell(2, 0).querySelector('input')!); + await user.click(getCell(2, 0).querySelector('input')!); expect(getCell(1, 0).querySelector('input')!).to.have.attr('data-indeterminate', 'true'); - fireEvent.click(getCell(1, 0).querySelector('input')!); + await user.click(getCell(1, 0).querySelector('input')!); expect(apiRef.current.getSelectedRows()).to.have.keys([1, 2, 3, 4, 5, 6, 7]); }); }); describe("prop: indeterminateCheckboxAction = 'deselect'", () => { - it('should deselect all the children when selecting an indeterminate parent', () => { - render( + it('should deselect all the children when selecting an indeterminate parent', async () => { + const { user } = render( - Row selection', () => { />, ); - fireEvent.click(getCell(2, 0).querySelector('input')!); + await user.click(getCell(2, 0).querySelector('input')!); expect(getCell(1, 0).querySelector('input')!).to.have.attr('data-indeterminate', 'true'); - fireEvent.click(getCell(1, 0).querySelector('input')!); + await user.click(getCell(1, 0).querySelector('input')!); expect(apiRef.current.getSelectedRows().size).to.equal(0); }); }); describe('prop: keepNonExistentRowsSelected = true', () => { - it('should keep non-existent rows selected on filtering', () => { - render(); + it('should keep non-existent rows selected on filtering', async () => { + const { user } = render(); - fireEvent.click(getCell(1, 0).querySelector('input')!); + await user.click(getCell(1, 0).querySelector('input')!); expect(apiRef.current.getSelectedRows()).to.have.keys([1, 2, 3, 4, 5, 6, 7]); - act(() => { + await act(() => { apiRef.current.setFilterModel({ items: [ { @@ -885,7 +907,7 @@ describe(' - Row selection', () => { }); }); - fireEvent.click(getCell(0, 0).querySelector('input')!); + await user.click(getCell(0, 0).querySelector('input')!); expect(apiRef.current.getSelectedRows()).to.have.keys([0, 1, 2, 3, 4, 5, 6, 7]); }); @@ -893,7 +915,7 @@ describe(' - Row selection', () => { }); describe('apiRef: getSelectedRows', () => { - it('should handle the event internally before triggering onRowSelectionModelChange', () => { + it('should handle the event internally before triggering onRowSelectionModelChange', async () => { render( { @@ -903,7 +925,7 @@ describe(' - Row selection', () => { />, ); expect(apiRef.current.getSelectedRows()).to.have.length(0); - act(() => apiRef.current.selectRow(1)); + await act(() => apiRef.current.selectRow(1)); expect(apiRef.current.getSelectedRows().get(1)).to.deep.equal({ id: 1, currencyPair: 'USDEUR', @@ -912,10 +934,10 @@ describe(' - Row selection', () => { }); describe('apiRef: isRowSelected', () => { - it('should check if the rows selected by clicking on the rows are selected', () => { - render(); + it('should check if the rows selected by clicking on the rows are selected', async () => { + const { user } = render(); - fireEvent.click(getCell(1, 0)); + await user.click(getCell(1, 0)); expect(apiRef.current.isRowSelected(0)).to.equal(false); expect(apiRef.current.isRowSelected(1)).to.equal(true); @@ -930,22 +952,22 @@ describe(' - Row selection', () => { }); describe('apiRef: selectRow', () => { - it('should call onRowSelectionModelChange with the ids selected', () => { + it('should call onRowSelectionModelChange with the ids selected', async () => { const handleRowSelectionModelChange = spy(); render(); - act(() => apiRef.current.selectRow(1)); + await act(() => apiRef.current.selectRow(1)); expect(handleRowSelectionModelChange.lastCall.args[0]).to.deep.equal([1]); // Reset old selection - act(() => apiRef.current.selectRow(2, true, true)); + await act(() => apiRef.current.selectRow(2, true, true)); expect(handleRowSelectionModelChange.lastCall.args[0]).to.deep.equal([2]); // Keep old selection - act(() => apiRef.current.selectRow(3)); + await act(() => apiRef.current.selectRow(3)); expect(handleRowSelectionModelChange.lastCall.args[0]).to.deep.equal([2, 3]); - act(() => apiRef.current.selectRow(3, false)); + await act(() => apiRef.current.selectRow(3, false)); expect(handleRowSelectionModelChange.lastCall.args[0]).to.deep.equal([2]); }); - it('should not call onRowSelectionModelChange if the row is unselectable', () => { + it('should not call onRowSelectionModelChange if the row is unselectable', async () => { const handleRowSelectionModelChange = spy(); render( - Row selection', () => { onRowSelectionModelChange={handleRowSelectionModelChange} />, ); - act(() => apiRef.current.selectRow(0)); + await act(() => apiRef.current.selectRow(0)); expect(handleRowSelectionModelChange.callCount).to.equal(0); - act(() => apiRef.current.selectRow(1)); + await act(() => apiRef.current.selectRow(1)); expect(handleRowSelectionModelChange.callCount).to.equal(1); }); }); describe('apiRef: selectRows', () => { - it('should call onRowSelectionModelChange with the ids selected', () => { + it('should call onRowSelectionModelChange with the ids selected', async () => { const handleRowSelectionModelChange = spy(); render(); - act(() => apiRef.current.selectRows([1, 2])); + await act(() => apiRef.current.selectRows([1, 2])); expect(handleRowSelectionModelChange.lastCall.args[0]).to.deep.equal([1, 2]); - act(() => apiRef.current.selectRows([3])); + await act(() => apiRef.current.selectRows([3])); expect(handleRowSelectionModelChange.lastCall.args[0]).to.deep.equal([1, 2, 3]); - act(() => apiRef.current.selectRows([1, 2], false)); + await act(() => apiRef.current.selectRows([1, 2], false)); expect(handleRowSelectionModelChange.lastCall.args[0]).to.deep.equal([3]); // Deselect others - act(() => apiRef.current.selectRows([4, 5], true, true)); + await act(() => apiRef.current.selectRows([4, 5], true, true)); expect(handleRowSelectionModelChange.lastCall.args[0]).to.deep.equal([4, 5]); }); - it('should filter out unselectable rows before calling onRowSelectionModelChange', () => { + it('should filter out unselectable rows before calling onRowSelectionModelChange', async () => { const handleRowSelectionModelChange = spy(); render( - Row selection', () => { onRowSelectionModelChange={handleRowSelectionModelChange} />, ); - act(() => apiRef.current.selectRows([0, 1, 2])); + await act(() => apiRef.current.selectRows([0, 1, 2])); expect(handleRowSelectionModelChange.lastCall.args[0]).to.deep.equal([1, 2]); }); - it('should not select a range of several elements when disableMultipleRowSelection = true', () => { + it('should not select a range of several elements when disableMultipleRowSelection = true', async () => { render(); - act(() => apiRef.current.selectRows([0, 1, 2], true)); + await act(() => apiRef.current.selectRows([0, 1, 2], true)); expect(getSelectedRowIds()).to.deep.equal([]); }); }); describe('apiRef: selectRowRange', () => { - it('should select all the rows in the range', () => { + it('should select all the rows in the range', async () => { render(); - act(() => apiRef.current.selectRowRange({ startId: 1, endId: 3 }, true)); + await act(() => apiRef.current.selectRowRange({ startId: 1, endId: 3 }, true)); expect(getSelectedRowIds()).to.deep.equal([1, 2, 3]); }); - it('should unselect all the rows in the range', () => { + it('should unselect all the rows in the range', async () => { render(); - act(() => apiRef.current.setRowSelectionModel([2, 3])); + await act(() => apiRef.current.setRowSelectionModel([2, 3])); expect(getSelectedRowIds()).to.deep.equal([2, 3]); - act(() => apiRef.current.selectRowRange({ startId: 0, endId: 3 }, false)); + await act(() => apiRef.current.selectRowRange({ startId: 0, endId: 3 }, false)); expect(getSelectedRowIds()).to.deep.equal([]); }); - it('should not unselect the selected elements if the range is to be selected', () => { + it('should not unselect the selected elements if the range is to be selected', async () => { render(); - act(() => { + await act(() => { apiRef.current.setRowSelectionModel([2]); + }); + await act(() => { apiRef.current.selectRowRange({ startId: 1, endId: 3 }, true); }); expect(getSelectedRowIds()).to.deep.equal([1, 2, 3]); }); - it('should not reset the other selections when resetSelection = false', () => { + it('should not reset the other selections when resetSelection = false', async () => { render(); - act(() => { + await act(() => { apiRef.current.setRowSelectionModel([0]); + }); + await act(() => { apiRef.current.selectRowRange({ startId: 2, endId: 3 }, true, false); }); expect(getSelectedRowIds()).to.deep.equal([0, 2, 3]); }); - it('should reset the other selections when resetSelection = true', () => { + it('should reset the other selections when resetSelection = true', async () => { render(); - act(() => { + await act(() => { apiRef.current.setRowSelectionModel([0]); + }); + await act(() => { apiRef.current.selectRowRange({ startId: 2, endId: 3 }, true, true); }); expect(getSelectedRowIds()).to.deep.equal([2, 3]); }); - it('should not select unselectable rows inside the range', () => { + it('should not select unselectable rows inside the range', async () => { render( Number(params.id) % 2 === 1} />); - act(() => apiRef.current.selectRowRange({ startId: 1, endId: 3 }, true)); + await act(() => apiRef.current.selectRowRange({ startId: 1, endId: 3 }, true)); expect(getSelectedRowIds()).to.deep.equal([1, 3]); }); - it('should not select a range of several elements when disableMultipleRowSelection = true', () => { + it('should not select a range of several elements when disableMultipleRowSelection = true', async () => { render(); - act(() => apiRef.current.selectRowRange({ startId: 1, endId: 3 }, true)); + await act(() => apiRef.current.selectRowRange({ startId: 1, endId: 3 }, true)); expect(getSelectedRowIds()).to.deep.equal([]); }); - it('should select only filtered rows selecting a range', () => { + it('should select only filtered rows selecting a range', async () => { render( { - render(); + it('should select only filtered rows after filter is applied', async () => { + const { user } = render(); const selectAll = screen.getByRole('checkbox', { name: /select all rows/i, }); - act(() => + await act(() => apiRef.current.setFilterModel({ items: [ { @@ -1088,13 +1116,13 @@ describe(' - Row selection', () => { }), ); expect(getColumnValues(1)).to.deep.equal(['0', '1']); - fireEvent.click(selectAll); + await user.click(selectAll); expect(getSelectedRowIds()).to.deep.equal([0, 1]); - fireEvent.click(selectAll); + await user.click(selectAll); expect(getSelectedRowIds()).to.deep.equal([]); - fireEvent.click(selectAll); + await user.click(selectAll); expect(getSelectedRowIds()).to.deep.equal([0, 1]); - fireEvent.click(selectAll); + await user.click(selectAll); expect(getSelectedRowIds()).to.deep.equal([]); }); diff --git a/packages/x-data-grid/package.json b/packages/x-data-grid/package.json index 737f29c7ece56..32402e7822b44 100644 --- a/packages/x-data-grid/package.json +++ b/packages/x-data-grid/package.json @@ -72,10 +72,10 @@ }, "devDependencies": { "@mui/internal-test-utils": "^1.0.17", - "@mui/joy": "^5.0.0-beta.48", - "@mui/material": "^5.16.7", - "@mui/system": "^5.16.7", - "@mui/types": "^7.2.15", + "@mui/joy": "^5.0.0-beta.51", + "@mui/material": "^5.16.13", + "@mui/system": "^5.16.13", + "@mui/types": "^7.2.20", "@types/prop-types": "^15.7.13", "rimraf": "^6.0.1" }, diff --git a/packages/x-data-grid/src/DataGrid/useDataGridComponent.tsx b/packages/x-data-grid/src/DataGrid/useDataGridComponent.tsx index 2c888c05b2384..827f1e48b6d8a 100644 --- a/packages/x-data-grid/src/DataGrid/useDataGridComponent.tsx +++ b/packages/x-data-grid/src/DataGrid/useDataGridComponent.tsx @@ -63,7 +63,7 @@ import { } from '../hooks/features/listView/useGridListView'; export const useDataGridComponent = ( - inputApiRef: React.MutableRefObject | undefined, + inputApiRef: React.RefObject | undefined, props: DataGridProcessedProps, ) => { const apiRef = useGridInitialization( diff --git a/packages/x-data-grid/src/components/cell/GridActionsCellItem.tsx b/packages/x-data-grid/src/components/cell/GridActionsCellItem.tsx index 77d7f6d284cc2..04bd44cafe091 100644 --- a/packages/x-data-grid/src/components/cell/GridActionsCellItem.tsx +++ b/packages/x-data-grid/src/components/cell/GridActionsCellItem.tsx @@ -8,14 +8,14 @@ import { useGridRootProps } from '../../hooks/utils/useGridRootProps'; interface GridActionsCellItemCommonProps { label: string; - icon?: React.ReactElement; + icon?: React.ReactElement; /** from https://mui.com/material-ui/api/button-base/#ButtonBase-prop-component */ component?: React.ElementType; } export type GridActionsCellItemProps = GridActionsCellItemCommonProps & ( - | ({ showInMenu?: false; icon: React.ReactElement } & Omit) + | ({ showInMenu?: false; icon: React.ReactElement } & Omit) | ({ showInMenu: true; /** @@ -45,7 +45,7 @@ const GridActionsCellItem = forwardRef((p {...other} onClick={handleClick} {...rootProps.slotProps?.baseIconButton} - ref={ref as React.MutableRefObject} + ref={ref as React.RefObject} > {React.cloneElement(icon!, { fontSize: 'small' })} diff --git a/packages/x-data-grid/src/components/cell/GridEditDateCell.tsx b/packages/x-data-grid/src/components/cell/GridEditDateCell.tsx index 0927583c5aab7..17baf45933207 100644 --- a/packages/x-data-grid/src/components/cell/GridEditDateCell.tsx +++ b/packages/x-data-grid/src/components/cell/GridEditDateCell.tsx @@ -66,7 +66,7 @@ function GridEditDateCell(props: GridEditDateCellProps) { const isDateTime = colDef.type === 'dateTime'; const apiRef = useGridApiContext(); - const inputRef = React.useRef(); + const inputRef = React.useRef(null); const valueTransformed = React.useMemo(() => { let parsedDate: Date | null; diff --git a/packages/x-data-grid/src/components/cell/GridEditInputCell.tsx b/packages/x-data-grid/src/components/cell/GridEditInputCell.tsx index e1243ecb269d2..73416184fade9 100644 --- a/packages/x-data-grid/src/components/cell/GridEditInputCell.tsx +++ b/packages/x-data-grid/src/components/cell/GridEditInputCell.tsx @@ -78,7 +78,7 @@ const GridEditInputCell = forwardRef(( } = props; const apiRef = useGridApiContext(); - const inputRef = React.useRef(); + const inputRef = React.useRef(null); const [valueState, setValueState] = React.useState(value); const classes = useUtilityClasses(rootProps); diff --git a/packages/x-data-grid/src/components/cell/GridEditSingleSelectCell.tsx b/packages/x-data-grid/src/components/cell/GridEditSingleSelectCell.tsx index baab9cfbdcd14..90e8b042441ba 100644 --- a/packages/x-data-grid/src/components/cell/GridEditSingleSelectCell.tsx +++ b/packages/x-data-grid/src/components/cell/GridEditSingleSelectCell.tsx @@ -58,8 +58,8 @@ function GridEditSingleSelectCell(props: GridEditSingleSelectCellProps) { } = props; const apiRef = useGridApiContext(); - const ref = React.useRef(); - const inputRef = React.useRef(); + const ref = React.useRef(null); + const inputRef = React.useRef(null); const [open, setOpen] = React.useState(initialOpen); const baseSelectProps = rootProps.slotProps?.baseSelect || {}; diff --git a/packages/x-data-grid/src/components/columnHeaders/ColumnHeaderMenuIcon.tsx b/packages/x-data-grid/src/components/columnHeaders/ColumnHeaderMenuIcon.tsx index 82f61061a22e8..81bb9fc0a929b 100644 --- a/packages/x-data-grid/src/components/columnHeaders/ColumnHeaderMenuIcon.tsx +++ b/packages/x-data-grid/src/components/columnHeaders/ColumnHeaderMenuIcon.tsx @@ -11,7 +11,7 @@ export interface ColumnHeaderMenuIconProps { columnMenuId: string; columnMenuButtonId: string; open: boolean; - iconButtonRef: React.RefObject; + iconButtonRef: React.RefObject; } type OwnerState = ColumnHeaderMenuIconProps & { diff --git a/packages/x-data-grid/src/components/columnHeaders/GridColumnHeaderFilterIconButton.tsx b/packages/x-data-grid/src/components/columnHeaders/GridColumnHeaderFilterIconButton.tsx index 92641c45e46e8..770a0d754d9d7 100644 --- a/packages/x-data-grid/src/components/columnHeaders/GridColumnHeaderFilterIconButton.tsx +++ b/packages/x-data-grid/src/components/columnHeaders/GridColumnHeaderFilterIconButton.tsx @@ -89,7 +89,7 @@ function GridColumnHeaderFilterIconButton(props: ColumnHeaderFilterIconButtonPro title={ apiRef.current.getLocaleText('columnHeaderFiltersTooltipActive')( counter, - ) as React.ReactElement + ) as React.ReactElement } enterDelay={1000} {...rootProps.slotProps?.baseTooltip} diff --git a/packages/x-data-grid/src/components/panel/GridPanel.test.tsx b/packages/x-data-grid/src/components/panel/GridPanel.test.tsx index 4e82d0de7ddd9..51c38dc7e87e4 100644 --- a/packages/x-data-grid/src/components/panel/GridPanel.test.tsx +++ b/packages/x-data-grid/src/components/panel/GridPanel.test.tsx @@ -33,7 +33,7 @@ describe('', () => { classes: classes as any, inheritComponent: Popper, muiName: 'MuiGridPanel', - render: (node: React.ReactElement) => + render: (node: React.ReactElement) => render(
diff --git a/packages/x-data-grid/src/components/toolbar/GridToolbarDensitySelector.tsx b/packages/x-data-grid/src/components/toolbar/GridToolbarDensitySelector.tsx index e71a2202f7d38..fe4caae9a6bc3 100644 --- a/packages/x-data-grid/src/components/toolbar/GridToolbarDensitySelector.tsx +++ b/packages/x-data-grid/src/components/toolbar/GridToolbarDensitySelector.tsx @@ -58,7 +58,7 @@ const GridToolbarDensitySelector = forwardRef(() => { + const startIcon = React.useMemo>(() => { switch (density) { case 'compact': return ; @@ -95,7 +95,7 @@ const GridToolbarDensitySelector = forwardRef((option, index) => ( + const densityElements = densityOptions.map>((option, index) => ( handleDensityUpdate(option.value)} diff --git a/packages/x-data-grid/src/components/toolbar/GridToolbarFilterButton.tsx b/packages/x-data-grid/src/components/toolbar/GridToolbarFilterButton.tsx index fa235faedd502..27cd712e3e699 100644 --- a/packages/x-data-grid/src/components/toolbar/GridToolbarFilterButton.tsx +++ b/packages/x-data-grid/src/components/toolbar/GridToolbarFilterButton.tsx @@ -72,10 +72,10 @@ const GridToolbarFilterButton = forwardRef { if (preferencePanel.open) { - return apiRef.current.getLocaleText('toolbarFiltersTooltipHide') as React.ReactElement; + return apiRef.current.getLocaleText('toolbarFiltersTooltipHide') as React.ReactElement; } if (activeFilters.length === 0) { - return apiRef.current.getLocaleText('toolbarFiltersTooltipShow') as React.ReactElement; + return apiRef.current.getLocaleText('toolbarFiltersTooltipShow') as React.ReactElement; } const getOperatorLabel = (item: GridFilterItem): string => diff --git a/packages/x-data-grid/src/hooks/core/pipeProcessing/gridPipeProcessingApi.ts b/packages/x-data-grid/src/hooks/core/pipeProcessing/gridPipeProcessingApi.ts index d47a8bbe98b09..78300aa77e2a1 100644 --- a/packages/x-data-grid/src/hooks/core/pipeProcessing/gridPipeProcessingApi.ts +++ b/packages/x-data-grid/src/hooks/core/pipeProcessing/gridPipeProcessingApi.ts @@ -38,7 +38,10 @@ export interface GridPipeProcessingLookup { hydrateRows: { value: GridHydrateRowsValue; }; - exportMenu: { value: { component: React.ReactElement; componentName: string }[]; context: any }; + exportMenu: { + value: { component: React.ReactElement; componentName: string }[]; + context: any; + }; preferencePanel: { value: React.ReactNode; context: GridPreferencePanelsValue }; restoreState: { value: GridRestoreStatePreProcessingValue; diff --git a/packages/x-data-grid/src/hooks/core/pipeProcessing/useGridPipeProcessing.ts b/packages/x-data-grid/src/hooks/core/pipeProcessing/useGridPipeProcessing.ts index 5b8f5e4c40464..2a015ab85cdde 100644 --- a/packages/x-data-grid/src/hooks/core/pipeProcessing/useGridPipeProcessing.ts +++ b/packages/x-data-grid/src/hooks/core/pipeProcessing/useGridPipeProcessing.ts @@ -49,7 +49,7 @@ type GroupCache = { * * a processor is registered. * * `apiRef.current.requestPipeProcessorsApplication` is called for the given group. */ -export const useGridPipeProcessing = (apiRef: React.MutableRefObject) => { +export const useGridPipeProcessing = (apiRef: React.RefObject) => { const cache = React.useRef({}); const isRunning = React.useRef(false); diff --git a/packages/x-data-grid/src/hooks/core/pipeProcessing/useGridRegisterPipeApplier.ts b/packages/x-data-grid/src/hooks/core/pipeProcessing/useGridRegisterPipeApplier.ts index f90a2045f2b77..540487e2889fc 100644 --- a/packages/x-data-grid/src/hooks/core/pipeProcessing/useGridRegisterPipeApplier.ts +++ b/packages/x-data-grid/src/hooks/core/pipeProcessing/useGridRegisterPipeApplier.ts @@ -7,11 +7,11 @@ export const useGridRegisterPipeApplier = < PrivateApi extends GridPrivateApiCommon, G extends GridPipeProcessorGroup, >( - apiRef: React.MutableRefObject, + apiRef: React.RefObject, group: G, callback: () => void, ) => { - const cleanup = React.useRef<(() => void) | null>(); + const cleanup = React.useRef<(() => void) | null>(null); const id = React.useRef(`mui-${Math.round(Math.random() * 1e9)}`); const registerPreProcessor = React.useCallback(() => { diff --git a/packages/x-data-grid/src/hooks/core/pipeProcessing/useGridRegisterPipeProcessor.ts b/packages/x-data-grid/src/hooks/core/pipeProcessing/useGridRegisterPipeProcessor.ts index 6082a61bdffa7..fe82da7b78487 100644 --- a/packages/x-data-grid/src/hooks/core/pipeProcessing/useGridRegisterPipeProcessor.ts +++ b/packages/x-data-grid/src/hooks/core/pipeProcessing/useGridRegisterPipeProcessor.ts @@ -7,11 +7,11 @@ export const useGridRegisterPipeProcessor = < PrivateApi extends GridPrivateApiCommon, G extends GridPipeProcessorGroup, >( - apiRef: React.MutableRefObject, + apiRef: React.RefObject, group: G, callback: GridPipeProcessor, ) => { - const cleanup = React.useRef<(() => void) | null>(); + const cleanup = React.useRef<(() => void) | null>(null); const id = React.useRef(`mui-${Math.round(Math.random() * 1e9)}`); const registerPreProcessor = React.useCallback(() => { diff --git a/packages/x-data-grid/src/hooks/core/strategyProcessing/useGridRegisterStrategyProcessor.ts b/packages/x-data-grid/src/hooks/core/strategyProcessing/useGridRegisterStrategyProcessor.ts index d90fdd630916a..6eb888a914f8a 100644 --- a/packages/x-data-grid/src/hooks/core/strategyProcessing/useGridRegisterStrategyProcessor.ts +++ b/packages/x-data-grid/src/hooks/core/strategyProcessing/useGridRegisterStrategyProcessor.ts @@ -7,7 +7,7 @@ export const useGridRegisterStrategyProcessor = < Api extends GridPrivateApiCommon, G extends GridStrategyProcessorName, >( - apiRef: React.MutableRefObject, + apiRef: React.RefObject, strategyName: string, group: G, processor: GridStrategyProcessor, diff --git a/packages/x-data-grid/src/hooks/core/strategyProcessing/useGridStrategyProcessing.ts b/packages/x-data-grid/src/hooks/core/strategyProcessing/useGridStrategyProcessing.ts index 0dbe135f4d75d..0815fba761251 100644 --- a/packages/x-data-grid/src/hooks/core/strategyProcessing/useGridStrategyProcessing.ts +++ b/packages/x-data-grid/src/hooks/core/strategyProcessing/useGridStrategyProcessing.ts @@ -64,7 +64,7 @@ type UntypedStrategyProcessors = { * - sorting algorithm. * - filtering algorithm. */ -export const useGridStrategyProcessing = (apiRef: React.MutableRefObject) => { +export const useGridStrategyProcessing = (apiRef: React.RefObject) => { const availableStrategies = React.useRef( new Map boolean }>(), ); diff --git a/packages/x-data-grid/src/hooks/core/useGridApiInitialization.ts b/packages/x-data-grid/src/hooks/core/useGridApiInitialization.ts index 3113bc9970105..75659f4926a62 100644 --- a/packages/x-data-grid/src/hooks/core/useGridApiInitialization.ts +++ b/packages/x-data-grid/src/hooks/core/useGridApiInitialization.ts @@ -23,7 +23,7 @@ export function unwrapPrivateAPI< let globalId = 0; function createPrivateAPI( - publicApiRef: React.MutableRefObject, + publicApiRef: React.RefObject, ): PrivateApi { const existingPrivateApi = (publicApiRef.current as any)?.[SYMBOL_API_PRIVATE]; if (existingPrivateApi) { @@ -96,14 +96,14 @@ export function useGridApiInitialization< PrivateApi extends GridPrivateApiCommon, Api extends GridApiCommon, >( - inputApiRef: React.MutableRefObject | undefined, + inputApiRef: React.RefObject | undefined, props: Pick, -): React.MutableRefObject { - const publicApiRef = React.useRef() as React.MutableRefObject; - const privateApiRef = React.useRef() as React.MutableRefObject; +): React.RefObject { + const publicApiRef = React.useRef(null) as React.RefObject; + const privateApiRef = React.useRef(null) as React.RefObject; if (!privateApiRef.current) { - privateApiRef.current = createPrivateAPI(publicApiRef) as PrivateApi; + privateApiRef.current = createPrivateAPI(publicApiRef); } if (!publicApiRef.current) { diff --git a/packages/x-data-grid/src/hooks/core/useGridInitialization.ts b/packages/x-data-grid/src/hooks/core/useGridInitialization.ts index d59852b43a54a..5b2e857ff6485 100644 --- a/packages/x-data-grid/src/hooks/core/useGridInitialization.ts +++ b/packages/x-data-grid/src/hooks/core/useGridInitialization.ts @@ -17,7 +17,7 @@ export const useGridInitialization = < PrivateApi extends GridPrivateApiCommon, Api extends GridApiCommon, >( - inputApiRef: React.MutableRefObject | undefined, + inputApiRef: React.RefObject | undefined, props: DataGridProcessedProps, ) => { const privateApiRef = useGridApiInitialization(inputApiRef, props); diff --git a/packages/x-data-grid/src/hooks/core/useGridIsRtl.tsx b/packages/x-data-grid/src/hooks/core/useGridIsRtl.tsx index 576952df12ca4..cc5f32c1dc317 100644 --- a/packages/x-data-grid/src/hooks/core/useGridIsRtl.tsx +++ b/packages/x-data-grid/src/hooks/core/useGridIsRtl.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import { useRtl } from '@mui/system/RtlProvider'; import { GridPrivateApiCommon } from '../../models/api/gridApiCommon'; -export const useGridIsRtl = (apiRef: React.MutableRefObject): void => { +export const useGridIsRtl = (apiRef: React.RefObject): void => { const isRtl = useRtl(); if (apiRef.current.state.isRtl === undefined) { diff --git a/packages/x-data-grid/src/hooks/core/useGridLocaleText.tsx b/packages/x-data-grid/src/hooks/core/useGridLocaleText.tsx index 7a1605e0c665c..26809f6f6047f 100644 --- a/packages/x-data-grid/src/hooks/core/useGridLocaleText.tsx +++ b/packages/x-data-grid/src/hooks/core/useGridLocaleText.tsx @@ -4,7 +4,7 @@ import { GridLocaleTextApi } from '../../models/api/gridLocaleTextApi'; import { DataGridProcessedProps } from '../../models/props/DataGridProps'; export const useGridLocaleText = ( - apiRef: React.MutableRefObject, + apiRef: React.RefObject, props: Pick, ): void => { const getLocaleText = React.useCallback( diff --git a/packages/x-data-grid/src/hooks/core/useGridLoggerFactory.ts b/packages/x-data-grid/src/hooks/core/useGridLoggerFactory.ts index b5586e6acfcbd..d403482e4498b 100644 --- a/packages/x-data-grid/src/hooks/core/useGridLoggerFactory.ts +++ b/packages/x-data-grid/src/hooks/core/useGridLoggerFactory.ts @@ -43,7 +43,7 @@ function getAppender(name: string, logLevel: string, appender: Logger = console) } export const useGridLoggerFactory = ( - apiRef: React.MutableRefObject, + apiRef: React.RefObject, props: Pick, ) => { const getLogger = React.useCallback( diff --git a/packages/x-data-grid/src/hooks/core/useGridRefs.ts b/packages/x-data-grid/src/hooks/core/useGridRefs.ts index 98e266fda316d..11e71729b0ee0 100644 --- a/packages/x-data-grid/src/hooks/core/useGridRefs.ts +++ b/packages/x-data-grid/src/hooks/core/useGridRefs.ts @@ -2,10 +2,10 @@ import * as React from 'react'; import type { GridPrivateApiCommon } from '../../models/api/gridApiCommon'; export const useGridRefs = ( - apiRef: React.MutableRefObject, + apiRef: React.RefObject, ) => { const rootElementRef = React.useRef(null); - const mainElementRef = React.useRef(null); + const mainElementRef = React.useRef(null); const virtualScrollerRef = React.useRef(null); const virtualScrollbarVerticalRef = React.useRef(null); const virtualScrollbarHorizontalRef = React.useRef(null); diff --git a/packages/x-data-grid/src/hooks/core/useGridStateInitialization.ts b/packages/x-data-grid/src/hooks/core/useGridStateInitialization.ts index 28cc2b149d4ff..880fa8ffccc87 100644 --- a/packages/x-data-grid/src/hooks/core/useGridStateInitialization.ts +++ b/packages/x-data-grid/src/hooks/core/useGridStateInitialization.ts @@ -6,7 +6,7 @@ import { useGridApiMethod } from '../utils'; import { isFunction } from '../../utils/utils'; export const useGridStateInitialization = ( - apiRef: React.MutableRefObject, + apiRef: React.RefObject, ) => { const controlStateMapRef = React.useRef< Record> diff --git a/packages/x-data-grid/src/hooks/features/columnResize/useGridColumnResize.tsx b/packages/x-data-grid/src/hooks/features/columnResize/useGridColumnResize.tsx index 133661062d5e0..ae4c318dc523f 100644 --- a/packages/x-data-grid/src/hooks/features/columnResize/useGridColumnResize.tsx +++ b/packages/x-data-grid/src/hooks/features/columnResize/useGridColumnResize.tsx @@ -132,8 +132,8 @@ function preventClick(event: MouseEvent) { * Checker that returns a promise that resolves when the column virtualization * is disabled. */ -function useColumnVirtualizationDisabled(apiRef: React.MutableRefObject) { - const promise = React.useRef(); +function useColumnVirtualizationDisabled(apiRef: React.RefObject) { + const promise = React.useRef(undefined); const selector = () => gridVirtualizationColumnEnabledSelector(apiRef); const value = useGridSelector(apiRef, selector); @@ -184,7 +184,7 @@ function excludeOutliers(inputValues: number[], factor: number) { } function extractColumnWidths( - apiRef: React.MutableRefObject, + apiRef: React.RefObject, options: AutosizeOptionsRequired, columns: GridStateColDef[], ) { @@ -270,7 +270,7 @@ function createResizeRefs() { * TODO: improve experience for last column */ export const useGridColumnResize = ( - apiRef: React.MutableRefObject, + apiRef: React.RefObject, props: Pick< DataGridProcessedProps, | 'autosizeOptions' @@ -289,11 +289,11 @@ export const useGridColumnResize = ( // To improve accessibility, the separator has padding on both sides. // Clicking inside the padding area should be treated as a click in the separator. // This ref stores the offset between the click and the separator. - const initialOffsetToSeparator = React.useRef(); - const resizeDirection = React.useRef(); + const initialOffsetToSeparator = React.useRef(null); + const resizeDirection = React.useRef(null); const stopResizeEventTimeout = useTimeout(); - const touchId = React.useRef(); + const touchId = React.useRef(undefined); const updateWidth = (newWidth: number) => { logger.debug(`Updating width to ${newWidth} for col ${refs.colDef!.field}`); diff --git a/packages/x-data-grid/src/hooks/features/editing/useGridRowEditing.ts b/packages/x-data-grid/src/hooks/features/editing/useGridRowEditing.ts index f0b21f9e62674..d2a015cbde00a 100644 --- a/packages/x-data-grid/src/hooks/features/editing/useGridRowEditing.ts +++ b/packages/x-data-grid/src/hooks/features/editing/useGridRowEditing.ts @@ -65,7 +65,7 @@ export const useGridRowEditing = ( const [rowModesModel, setRowModesModel] = React.useState({}); const rowModesModelRef = React.useRef(rowModesModel); const prevRowModesModel = React.useRef({}); - const focusTimeout = React.useRef>(); + const focusTimeout = React.useRef>(undefined); const nextFocusedCell = React.useRef(null); const { diff --git a/packages/x-data-grid/src/hooks/features/export/useGridPrintExport.tsx b/packages/x-data-grid/src/hooks/features/export/useGridPrintExport.tsx index e895aaf614065..bc07bd7bc5592 100644 --- a/packages/x-data-grid/src/hooks/features/export/useGridPrintExport.tsx +++ b/packages/x-data-grid/src/hooks/features/export/useGridPrintExport.tsx @@ -70,7 +70,7 @@ export const useGridPrintExport = ( const previousGridState = React.useRef(null); const previousColumnVisibility = React.useRef<{ [key: string]: boolean }>({}); const previousRows = React.useRef([]); - const previousVirtualizationState = React.useRef(); + const previousVirtualizationState = React.useRef(null); React.useEffect(() => { doc.current = ownerDocument(apiRef.current.rootElementRef!.current!); diff --git a/packages/x-data-grid/src/hooks/features/keyboardNavigation/useGridKeyboardNavigation.ts b/packages/x-data-grid/src/hooks/features/keyboardNavigation/useGridKeyboardNavigation.ts index 8622525c32dd8..45cb7e7df94c1 100644 --- a/packages/x-data-grid/src/hooks/features/keyboardNavigation/useGridKeyboardNavigation.ts +++ b/packages/x-data-grid/src/hooks/features/keyboardNavigation/useGridKeyboardNavigation.ts @@ -48,7 +48,7 @@ import { gridListColumnSelector } from '../listView/gridListViewSelectors'; * @requires useGridColumnSpanning (method) - can be after */ export const useGridKeyboardNavigation = ( - apiRef: React.MutableRefObject, + apiRef: React.RefObject, props: Pick< DataGridProcessedProps, | 'pagination' diff --git a/packages/x-data-grid/src/hooks/features/preferencesPanel/useGridPreferencesPanel.ts b/packages/x-data-grid/src/hooks/features/preferencesPanel/useGridPreferencesPanel.ts index ef0b9ad65321f..8461272804d26 100644 --- a/packages/x-data-grid/src/hooks/features/preferencesPanel/useGridPreferencesPanel.ts +++ b/packages/x-data-grid/src/hooks/features/preferencesPanel/useGridPreferencesPanel.ts @@ -24,8 +24,8 @@ export const useGridPreferencesPanel = ( ): void => { const logger = useGridLogger(apiRef, 'useGridPreferencesPanel'); - const hideTimeout = React.useRef>(); - const immediateTimeout = React.useRef>(); + const hideTimeout = React.useRef>(undefined); + const immediateTimeout = React.useRef>(undefined); /** * API METHODS diff --git a/packages/x-data-grid/src/hooks/features/rowSelection/useGridRowSelectionPreProcessors.ts b/packages/x-data-grid/src/hooks/features/rowSelection/useGridRowSelectionPreProcessors.ts index 3732826456486..aceac61373078 100644 --- a/packages/x-data-grid/src/hooks/features/rowSelection/useGridRowSelectionPreProcessors.ts +++ b/packages/x-data-grid/src/hooks/features/rowSelection/useGridRowSelectionPreProcessors.ts @@ -23,7 +23,7 @@ const useUtilityClasses = (ownerState: OwnerState) => { }; export const useGridRowSelectionPreProcessors = ( - apiRef: React.MutableRefObject, + apiRef: React.RefObject, props: DataGridProcessedProps, ) => { const ownerState = { classes: props.classes }; diff --git a/packages/x-data-grid/src/hooks/features/rows/useGridRowSpanning.ts b/packages/x-data-grid/src/hooks/features/rows/useGridRowSpanning.ts index 72e510c837ded..ebb6cdc5c3b37 100644 --- a/packages/x-data-grid/src/hooks/features/rows/useGridRowSpanning.ts +++ b/packages/x-data-grid/src/hooks/features/rows/useGridRowSpanning.ts @@ -47,7 +47,7 @@ const skippedFields = new Set([ const DEFAULT_ROWS_TO_PROCESS = 20; const computeRowSpanningState = ( - apiRef: React.MutableRefObject, + apiRef: React.RefObject, colDefs: GridColDef[], visibleRows: GridRowEntry[], range: RowRange, diff --git a/packages/x-data-grid/src/hooks/features/rows/useGridRowsPreProcessors.tsx b/packages/x-data-grid/src/hooks/features/rows/useGridRowsPreProcessors.tsx index f587417bd36b6..56bc28c17dbec 100644 --- a/packages/x-data-grid/src/hooks/features/rows/useGridRowsPreProcessors.tsx +++ b/packages/x-data-grid/src/hooks/features/rows/useGridRowsPreProcessors.tsx @@ -93,9 +93,7 @@ const flatRowTreeCreationMethod: GridStrategyProcessor<'rowTreeCreation'> = (par return updateFlatRowTree({ previousTree: params.previousTree!, actions: params.updates.actions }); }; -export const useGridRowsPreProcessors = ( - apiRef: React.MutableRefObject, -) => { +export const useGridRowsPreProcessors = (apiRef: React.RefObject) => { useGridRegisterStrategyProcessor( apiRef, GRID_DEFAULT_STRATEGY, diff --git a/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx b/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx index 948450691a821..0b1b5919c8430 100644 --- a/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx +++ b/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx @@ -99,7 +99,7 @@ try { } export const useGridVirtualScroller = () => { - const apiRef = useGridPrivateApiContext() as React.MutableRefObject; + const apiRef = useGridPrivateApiContext() as React.RefObject; const rootProps = useGridRootProps(); const { unstable_listView: listView } = rootProps; const visibleColumns = useGridSelector(apiRef, () => @@ -136,6 +136,8 @@ export const useGridVirtualScroller = () => { const columnsTotalWidth = dimensions.columnsTotalWidth; const hasColSpan = useGridSelector(apiRef, gridHasColSpanSelector); + const previousSize = React.useRef<{ width: number; height: number }>(null); + const mainRefCallback = React.useCallback( (node: HTMLDivElement | null) => { mainRef.current = node; @@ -145,10 +147,16 @@ export const useGridVirtualScroller = () => { } const initialRect = node.getBoundingClientRect(); - let lastSize = roundDimensions(initialRect); - apiRef.current.publishEvent('resize', lastSize); + if ( + !previousSize.current || + (lastSize.width !== previousSize.current.width && + lastSize.height !== previousSize.current.height) + ) { + previousSize.current = lastSize; + apiRef.current.publishEvent('resize', lastSize); + } if (typeof ResizeObserver === 'undefined') { return undefined; diff --git a/packages/x-data-grid/src/hooks/utils/useGridApiEventHandler.ts b/packages/x-data-grid/src/hooks/utils/useGridApiEventHandler.ts index 76cf3808c28ef..26ad34bf45d0f 100644 --- a/packages/x-data-grid/src/hooks/utils/useGridApiEventHandler.ts +++ b/packages/x-data-grid/src/hooks/utils/useGridApiEventHandler.ts @@ -43,7 +43,7 @@ export function createUseGridApiEventHandler(registryContainer: RegistryContaine const [objectRetainedByReact] = React.useState(new ObjectToBeRetainedByReact()); const subscription = React.useRef<(() => void) | null>(null); - const handlerRef = React.useRef | undefined>(); + const handlerRef = React.useRef | undefined>(null); handlerRef.current = handler; const cleanupTokenRef = React.useRef(null); diff --git a/packages/x-data-grid/src/hooks/utils/useGridApiMethod.ts b/packages/x-data-grid/src/hooks/utils/useGridApiMethod.ts index bbaaa2b3eb6cd..7b1131b82a6c6 100644 --- a/packages/x-data-grid/src/hooks/utils/useGridApiMethod.ts +++ b/packages/x-data-grid/src/hooks/utils/useGridApiMethod.ts @@ -12,7 +12,7 @@ export function useGridApiMethod< PrivateOnlyApi extends Omit, V extends 'public' | 'private', T extends V extends 'public' ? Partial : Partial, ->(privateApiRef: React.MutableRefObject, apiMethods: T, visibility: V) { +>(privateApiRef: React.RefObject, apiMethods: T, visibility: V) { const isFirstRender = React.useRef(true); useEnhancedEffect(() => { diff --git a/packages/x-data-grid/src/hooks/utils/useGridApiRef.ts b/packages/x-data-grid/src/hooks/utils/useGridApiRef.ts index ae5db730f0975..03fafb33fb2a3 100644 --- a/packages/x-data-grid/src/hooks/utils/useGridApiRef.ts +++ b/packages/x-data-grid/src/hooks/utils/useGridApiRef.ts @@ -6,4 +6,4 @@ import { GridApiCommunity } from '../../models/api/gridApiCommunity'; * Hook that instantiate a [[GridApiRef]]. */ export const useGridApiRef = () => - React.useRef({}) as React.MutableRefObject; + React.useRef({}) as React.RefObject; diff --git a/packages/x-data-grid/src/hooks/utils/useGridInitializeState.ts b/packages/x-data-grid/src/hooks/utils/useGridInitializeState.ts index 7f3a59d6e5d7a..0b48e54195616 100644 --- a/packages/x-data-grid/src/hooks/utils/useGridInitializeState.ts +++ b/packages/x-data-grid/src/hooks/utils/useGridInitializeState.ts @@ -13,7 +13,7 @@ export type GridStateInitializer< > = ( state: DeepPartial, props: P, - privateApiRef: React.MutableRefObject, + privateApiRef: React.RefObject, ) => DeepPartial; export const useGridInitializeState = < @@ -21,7 +21,7 @@ export const useGridInitializeState = < PrivateApi extends GridPrivateApiCommon = GridPrivateApiCommunity, >( initializer: GridStateInitializer, - privateApiRef: React.MutableRefObject, + privateApiRef: React.RefObject, props: P, ) => { const isInitialized = React.useRef(false); diff --git a/packages/x-data-grid/src/hooks/utils/useGridLogger.ts b/packages/x-data-grid/src/hooks/utils/useGridLogger.ts index c672a622996d1..d8671461f7466 100644 --- a/packages/x-data-grid/src/hooks/utils/useGridLogger.ts +++ b/packages/x-data-grid/src/hooks/utils/useGridLogger.ts @@ -3,7 +3,7 @@ import { Logger } from '../../models/logger'; import { GridPrivateApiCommon } from '../../models/api/gridApiCommon'; export function useGridLogger( - privateApiRef: React.MutableRefObject, + privateApiRef: React.RefObject, name: string, ): Logger { const logger = React.useRef(null); diff --git a/packages/x-data-grid/src/hooks/utils/useGridVisibleRows.ts b/packages/x-data-grid/src/hooks/utils/useGridVisibleRows.ts index 7b32dcfb0c988..b291c89dbdc53 100644 --- a/packages/x-data-grid/src/hooks/utils/useGridVisibleRows.ts +++ b/packages/x-data-grid/src/hooks/utils/useGridVisibleRows.ts @@ -8,7 +8,7 @@ import { gridExpandedSortedRowEntriesSelector } from '../features/filter/gridFil import type { GridApiCommon, GridRowEntry } from '../../models'; export const getVisibleRows = ( - apiRef: React.MutableRefObject, + apiRef: React.RefObject, props: Pick, ) => { let rows: GridRowEntry[]; @@ -37,7 +37,7 @@ export const getVisibleRows = ( * - If the row tree is flat, it only contains up to `state.pageSize` rows. */ export const useGridVisibleRows = ( - apiRef: React.MutableRefObject, + apiRef: React.RefObject, props: Pick, ) => { const response = getVisibleRows(apiRef, props); diff --git a/packages/x-data-grid/src/models/api/gridCoreApi.ts b/packages/x-data-grid/src/models/api/gridCoreApi.ts index c5d7be49b1fd3..ce309191f7ab8 100644 --- a/packages/x-data-grid/src/models/api/gridCoreApi.ts +++ b/packages/x-data-grid/src/models/api/gridCoreApi.ts @@ -14,7 +14,7 @@ export interface GridCoreApi { * The React ref of the grid root container div element. * @ignore - do not document. */ - rootElementRef: React.RefObject; + rootElementRef: React.RefObject; /** * Registers a handler for an event. * @param {string} event The name of the event. @@ -67,27 +67,27 @@ export interface GridCorePrivateApi< /** * The React ref of the grid main container div element. */ - mainElementRef: React.MutableRefObject; + mainElementRef: React.RefObject; /** * The React ref of the grid's virtual scroller container element. */ - virtualScrollerRef: React.RefObject; + virtualScrollerRef: React.RefObject; /** * The React ref of the grid's vertical virtual scrollbar container element. */ - virtualScrollbarVerticalRef: React.RefObject; + virtualScrollbarVerticalRef: React.RefObject; /** * The React ref of the grid's horizontal virtual scrollbar container element. */ - virtualScrollbarHorizontalRef: React.RefObject; + virtualScrollbarHorizontalRef: React.RefObject; /** * The React ref of the grid column container virtualized div element. */ - columnHeadersContainerRef: React.RefObject; + columnHeadersContainerRef: React.RefObject; /** * The React ref of the grid header filter row element. */ - headerFiltersElementRef?: React.RefObject; + headerFiltersElementRef?: React.RefObject; register: < V extends 'public' | 'private', T extends V extends 'public' diff --git a/packages/x-data-grid/src/models/api/gridDensityApi.ts b/packages/x-data-grid/src/models/api/gridDensityApi.ts index 8614bda501a81..2445925f25249 100644 --- a/packages/x-data-grid/src/models/api/gridDensityApi.ts +++ b/packages/x-data-grid/src/models/api/gridDensityApi.ts @@ -2,7 +2,7 @@ import * as React from 'react'; import { GridDensity } from '../gridDensity'; export interface GridDensityOption { - icon: React.ReactElement; + icon: React.ReactElement; label: string; value: GridDensity; } diff --git a/packages/x-data-grid/src/models/props/DataGridProps.ts b/packages/x-data-grid/src/models/props/DataGridProps.ts index 02c4bc07b4a9b..3e6e86380c2fb 100644 --- a/packages/x-data-grid/src/models/props/DataGridProps.ts +++ b/packages/x-data-grid/src/models/props/DataGridProps.ts @@ -415,7 +415,7 @@ export interface DataGridPropsWithoutDefaultValue; + apiRef?: React.RefObject; /** * Forwarded props for the Data Grid root element. * @ignore - do not document. diff --git a/packages/x-data-grid/src/tests/columnsVisibility.DataGrid.test.tsx b/packages/x-data-grid/src/tests/columnsVisibility.DataGrid.test.tsx index 0adf925558ef2..581c6534bc437 100644 --- a/packages/x-data-grid/src/tests/columnsVisibility.DataGrid.test.tsx +++ b/packages/x-data-grid/src/tests/columnsVisibility.DataGrid.test.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { expect } from 'chai'; import { spy } from 'sinon'; -import { act, createRenderer, fireEvent, screen } from '@mui/internal-test-utils'; +import { createRenderer, fireEvent, screen } from '@mui/internal-test-utils'; import { DataGrid, DataGridProps, @@ -18,7 +18,7 @@ const rows: GridRowsProp = [{ id: 1, idBis: 1 }]; const columns: GridColDef[] = [{ field: 'id' }, { field: 'idBis' }]; -describe(' - Columns visibility', () => { +describe(' - Columns visibility', () => { const { render } = createRenderer(); function TestDataGrid( @@ -50,8 +50,8 @@ describe(' - Columns visibility', () => { expect(getColumnHeadersTextContent()).to.deep.equal(['id', 'idBis']); }); - it('should update the visible columns when props.onColumnVisibilityModelChange and props.columnVisibilityModel are not defined', () => { - render( + it('should update the visible columns when props.onColumnVisibilityModelChange and props.columnVisibilityModel are not defined', async () => { + const { user } = render( - Columns visibility', () => { ); expect(getColumnHeadersTextContent()).to.deep.equal(['id', 'idBis']); - fireEvent.click(screen.getByRole('button', { name: 'Select columns' })); - fireEvent.click(screen.getByRole('checkbox', { name: 'id' })); + await user.click(screen.getByRole('button', { name: 'Select columns' })); + await user.click(screen.getByRole('checkbox', { name: 'id' })); expect(getColumnHeadersTextContent()).to.deep.equal(['idBis']); }); - it('should call onColumnVisibilityModelChange and update the visible columns when props.columnVisibilityModel is not defined', () => { + it('should call onColumnVisibilityModelChange and update the visible columns when props.columnVisibilityModel is not defined', async () => { const onColumnVisibilityModelChange = spy(); - render( + const { user } = render( - Columns visibility', () => { ); expect(getColumnHeadersTextContent()).to.deep.equal(['id', 'idBis']); - fireEvent.click(screen.getByRole('button', { name: 'Select columns' })); - fireEvent.click(screen.getByRole('checkbox', { name: 'id' })); + await user.click(screen.getByRole('button', { name: 'Select columns' })); + await user.click(screen.getByRole('checkbox', { name: 'id' })); expect(getColumnHeadersTextContent()).to.deep.equal(['idBis']); expect(onColumnVisibilityModelChange.callCount).to.equal(1); expect(onColumnVisibilityModelChange.lastCall.firstArg).to.deep.equal({ @@ -109,7 +109,7 @@ describe(' - Columns visibility', () => { }); }); - it('should call onColumnVisibilityModelChange with the new model when toggling all columns', () => { + it('should call onColumnVisibilityModelChange with the new model when toggling all columns', async () => { const onColumnVisibilityModelChange = spy(); function ControlledTest() { const [model, setModel] = React.useState({ idBis: false }); @@ -126,20 +126,20 @@ describe(' - Columns visibility', () => { /> ); } - render(); + const { user } = render(); expect(getColumnHeadersTextContent()).to.deep.equal(['id']); - fireEvent.click(screen.getByRole('button', { name: 'Select columns' })); + await user.click(screen.getByRole('button', { name: 'Select columns' })); const showHideAllCheckbox = screen.getByRole('checkbox', { name: 'Show/Hide All' }); // Hide all - fireEvent.click(showHideAllCheckbox); + await user.click(showHideAllCheckbox); expect(onColumnVisibilityModelChange.callCount).to.equal(1); expect(onColumnVisibilityModelChange.lastCall.firstArg).to.deep.equal({}); // Show all - fireEvent.click(showHideAllCheckbox); + await user.click(showHideAllCheckbox); expect(onColumnVisibilityModelChange.callCount).to.equal(2); expect(onColumnVisibilityModelChange.lastCall.firstArg).to.deep.equal({ id: false, @@ -148,8 +148,8 @@ describe(' - Columns visibility', () => { }); // Fixes (1) and (2) in https://github.com/mui/mui-x/issues/7393#issuecomment-1372129661 - it('should not show hidden non hideable columns when "Show/Hide All" is clicked', () => { - render( + it('should not show hidden non hideable columns when "Show/Hide All" is clicked', async () => { + const { user } = render( - Columns visibility', () => { />, ); - fireEvent.click(screen.getByRole('button', { name: 'Select columns' })); + await user.click(screen.getByRole('button', { name: 'Select columns' })); const showHideAllCheckbox = screen.getByRole('checkbox', { name: 'Show/Hide All' }); // Hide all - fireEvent.click(showHideAllCheckbox); + await user.click(showHideAllCheckbox); expect(getColumnHeadersTextContent()).to.deep.equal([]); // Show all - fireEvent.click(showHideAllCheckbox); + await user.click(showHideAllCheckbox); expect(getColumnHeadersTextContent()).to.deep.equal(['id']); }); }); @@ -226,8 +226,8 @@ describe(' - Columns visibility', () => { expect(getColumnHeadersTextContent()).to.deep.equal(['id']); }); - it('should allow to update the visible columns through the UI when initialized with initialState', () => { - render( + it('should allow to update the visible columns through the UI when initialized with initialState', async () => { + const { user } = render( - Columns visibility', () => { ); expect(getColumnHeadersTextContent()).to.deep.equal(['id']); - fireEvent.click(screen.getByRole('button', { name: 'Select columns' })); - fireEvent.click(screen.getByRole('checkbox', { name: 'id' })); + await user.click(screen.getByRole('button', { name: 'Select columns' })); + await user.click(screen.getByRole('checkbox', { name: 'id' })); expect(getColumnHeadersTextContent()).to.deep.equal([]); }); }); - it('should autofocus the first switch element in columns management when `autoFocusSearchField` disabled', () => { - render( + it('should autofocus the first switch element in columns management when `autoFocusSearchField` disabled', async () => { + const { user } = render( - Columns visibility', () => { />, ); - fireEvent.click(screen.getByRole('button', { name: 'Select columns' })); + await user.click(screen.getByRole('button', { name: 'Select columns' })); expect(screen.getByRole('checkbox', { name: columns[0].field })).toHaveFocus(); }); - it('should hide `Show/Hide all` in columns management when `disableShowHideToggle` is `true`', () => { - const { setProps } = render( + it('should hide `Show/Hide all` in columns management when `disableShowHideToggle` is `true`', async () => { + const { setProps, user } = render( - Columns visibility', () => { />, ); - fireEvent.click(screen.getByRole('button', { name: 'Select columns' })); + await user.click(screen.getByRole('button', { name: 'Select columns' })); // check if `Show/Hide all` checkbox is present initially expect(screen.getByRole('checkbox', { name: 'Show/Hide All' })).not.to.equal(null); setProps({ @@ -290,8 +290,8 @@ describe(' - Columns visibility', () => { expect(screen.queryByRole('checkbox', { name: 'Show/Hide All' })).to.equal(null); }); - it('should hide `Reset` in columns panel when `disableResetButton` is `true`', () => { - const { setProps } = render( + it('should hide `Reset` in columns panel when `disableResetButton` is `true`', async () => { + const { setProps, user } = render( - Columns visibility', () => { />, ); - fireEvent.click(screen.getByRole('button', { name: 'Select columns' })); + await user.click(screen.getByRole('button', { name: 'Select columns' })); // check if Reset button is present initially expect(screen.getByRole('button', { name: 'Reset' })).not.to.equal(null); setProps({ @@ -313,8 +313,8 @@ describe(' - Columns visibility', () => { expect(screen.queryByRole('button', { name: 'Reset' })).to.equal(null); }); - it('should reset the columns to initial columns state when `Reset` button is clicked in columns management panel', () => { - render( + it('should reset the columns to initial columns state when `Reset` button is clicked in columns management panel', async () => { + const { user } = render( - Columns visibility', () => { ); expect(getColumnHeadersTextContent()).to.deep.equal(['id', 'idBis']); - fireEvent.click(screen.getByRole('button', { name: 'Select columns' })); + await user.click(screen.getByRole('button', { name: 'Select columns' })); const resetButton = screen.getByRole('button', { name: 'Reset' }); expect(resetButton).to.have.attribute('disabled'); // Hide `idBis` column - fireEvent.click(screen.getByRole('checkbox', { name: 'idBis' })); + await user.click(screen.getByRole('checkbox', { name: 'idBis' })); expect(getColumnHeadersTextContent()).to.deep.equal(['id']); expect(resetButton).not.to.have.attribute('disabled'); // Reset columns - fireEvent.click(resetButton); + await user.click(resetButton); expect(getColumnHeadersTextContent()).to.deep.equal(['id', 'idBis']); expect(resetButton).to.have.attribute('disabled'); }); @@ -360,10 +360,10 @@ describe(' - Columns visibility', () => { expect(screen.queryByRole('checkbox', { name: 'idBis' })).to.equal(null); }); - it('should avoid toggling columns provided by `getTogglableColumns` prop on `Show/Hide All`', () => { + it('should avoid toggling columns provided by `getTogglableColumns` prop on `Show/Hide All`', async () => { const getTogglableColumns = (cols: GridColDef[]) => cols.filter((column) => column.field !== 'idBis').map((column) => column.field); - render( + const { user } = render( - Columns visibility', () => { />, ); - fireEvent.click(screen.getByRole('button', { name: 'Select columns' })); + await user.click(screen.getByRole('button', { name: 'Select columns' })); const showHideAllCheckbox = screen.getByRole('checkbox', { name: 'Show/Hide All' }); - fireEvent.click(showHideAllCheckbox); + await user.click(showHideAllCheckbox); expect(getColumnHeadersTextContent()).to.deep.equal(['idBis']); - fireEvent.click(showHideAllCheckbox); + await user.click(showHideAllCheckbox); expect(getColumnHeadersTextContent()).to.deep.equal(['id', 'idBis']); }); }); describe('prop: toggleAllMode', () => { - it('should toggle filtered columns when `toggleAllMode` is `filtered`', () => { - render( + it('should toggle filtered columns when `toggleAllMode` is `filtered`', async () => { + const { user } = render(
- Columns visibility', () => { expect(getColumnHeadersTextContent()).to.deep.equal(['id', 'firstName', 'lastName', 'age']); const button = screen.getByRole('button', { name: 'Select columns' }); - act(() => button.focus()); - fireEvent.click(button); + await user.click(button); const input = screen.getByPlaceholderText('Search'); - fireEvent.change(input, { target: { value: 'name' } }); + await user.type(input, 'name'); const showHideAllCheckbox = screen.getByRole('checkbox', { name: 'Show/Hide All' }); - fireEvent.click(showHideAllCheckbox); + await user.click(showHideAllCheckbox); expect(getColumnHeadersTextContent()).to.deep.equal(['id', 'age']); - fireEvent.change(input, { target: { value: 'firstName' } }); - fireEvent.click(showHideAllCheckbox); + // clear the search before the new search + await user.clear(input); + await user.type(input, 'firstName'); + await user.click(showHideAllCheckbox); expect(getColumnHeadersTextContent()).to.deep.equal(['id', 'firstName', 'age']); }); }); diff --git a/packages/x-data-grid/src/tests/rowSelection.DataGrid.test.tsx b/packages/x-data-grid/src/tests/rowSelection.DataGrid.test.tsx index e549ffd113009..0efc11d304a66 100644 --- a/packages/x-data-grid/src/tests/rowSelection.DataGrid.test.tsx +++ b/packages/x-data-grid/src/tests/rowSelection.DataGrid.test.tsx @@ -29,7 +29,6 @@ import { getActiveCell, grid, } from 'test/utils/helperFn'; -import { fireUserEvent } from 'test/utils/fireUserEvent'; import { getBasicGridData } from '@mui/x-data-grid-generator'; const isJSDOM = /jsdom/.test(window.navigator.userAgent); @@ -67,7 +66,7 @@ describe(' - Row selection', () => { } // Context: https://github.com/mui/mui-x/issues/15079 - it('should not call `onRowSelectionModelChange` twice when using filterMode="server"', () => { + it('should not call `onRowSelectionModelChange` twice when using filterMode="server"', async () => { const onRowSelectionModelChange = spy(); function TestDataGrid() { const [, setRowSelectionModel] = React.useState([]); @@ -84,25 +83,25 @@ describe(' - Row selection', () => { /> ); } - render(); - fireEvent.click(getCell(0, 0).querySelector('input')!); + const { user } = render(); + await user.click(getCell(0, 0).querySelector('input')!); expect(onRowSelectionModelChange.callCount).to.equal(1); }); describe('prop: checkboxSelection = false (single selection)', () => { - it('should select one row at a time on click WITHOUT ctrl or meta pressed', () => { - render(); - fireUserEvent.mousePress(getCell(0, 0)); + it('should select one row at a time on click WITHOUT ctrl or meta pressed', async () => { + const { user } = render(); + await user.click(getCell(0, 0)); expect(getSelectedRowIds()).to.deep.equal([0]); - fireUserEvent.mousePress(getCell(1, 0)); + await user.click(getCell(1, 0)); expect(getSelectedRowIds()).to.deep.equal([1]); }); - it(`should not deselect the selected row on click WITHOUT ctrl or meta pressed`, () => { - render(); - fireEvent.click(getCell(0, 0)); + it(`should not deselect the selected row on click WITHOUT ctrl or meta pressed`, async () => { + const { user } = render(); + await user.click(getCell(0, 0)); expect(getSelectedRowIds()).to.deep.equal([0]); - fireEvent.click(getCell(0, 0)); + await user.click(getCell(0, 0)); expect(getSelectedRowIds()).to.deep.equal([0]); }); @@ -124,34 +123,36 @@ describe(' - Row selection', () => { }); }); - it('should not select a range with shift pressed', () => { - render(); - fireEvent.click(getCell(0, 0)); + it('should not select a range with shift pressed', async () => { + const { user } = render(); + await user.click(getCell(0, 0)); expect(getSelectedRowIds()).to.deep.equal([0]); - fireEvent.click(getCell(2, 0), { shiftKey: true }); + await user.keyboard('{Shift>}'); + await user.click(getCell(2, 0)); + await user.keyboard('{/Shift}'); expect(getSelectedRowIds()).to.deep.equal([2]); }); }); describe('prop: checkboxSelection = false (single selection), with keyboard events', () => { - it('should select one row at a time on Shift + Space', () => { - render(); + it('should select one row at a time on Shift + Space', async () => { + const { user } = render(); const cell0 = getCell(0, 0); - fireUserEvent.mousePress(cell0); - fireEvent.keyDown(cell0, { key: ' ', shiftKey: true }); + await user.click(cell0); + await user.keyboard('{Shift>}[Space]{/Shift}'); expect(getSelectedRowIds()).to.deep.equal([0]); const cell1 = getCell(1, 0); - fireUserEvent.mousePress(cell1); - fireEvent.keyDown(cell1, { key: ' ', shiftKey: true }); + await user.click(cell1); + await user.keyboard('{Shift>}[Space]{/Shift}'); expect(getSelectedRowIds()).to.deep.equal([1]); }); [GridEditModes.Cell, GridEditModes.Row].forEach((editMode) => { - it(`should select row on Shift + Space without starting editing the ${editMode}`, () => { + it(`should select row on Shift + Space without starting editing the ${editMode}`, async () => { const onCellEditStart = spy(); - render( + const { user } = render( - Row selection', () => { expect(onCellEditStart.callCount).to.equal(0); const cell01 = getCell(0, 1); - fireUserEvent.mousePress(cell01); + await user.click(cell01); - fireEvent.keyDown(cell01, { key: ' ', shiftKey: true }); + await user.keyboard('{Shift>}[Space]{/Shift}'); expect(onCellEditStart.callCount).to.equal(0); expect(getSelectedRowIds()).to.deep.equal([0]); const cell11 = getCell(1, 1); - fireUserEvent.mousePress(cell11); - fireEvent.keyDown(cell11, { key: ' ', shiftKey: true }); + await user.click(cell11); + await user.keyboard('{Shift>}[Space]{/Shift}'); expect(onCellEditStart.callCount).to.equal(0); expect(getSelectedRowIds()).to.deep.equal([1]); }); }); - it(`should deselect the selected row on Shift + Space`, () => { - render(); + it(`should deselect the selected row on Shift + Space`, async () => { + const { user } = render(); const cell00 = getCell(0, 0); - fireUserEvent.mousePress(cell00); + await user.click(cell00); - fireEvent.keyDown(cell00, { key: ' ', shiftKey: true }); + await user.keyboard('{Shift>}[Space]{/Shift}'); expect(getSelectedRowIds()).to.deep.equal([0]); - fireEvent.keyDown(cell00, { key: ' ', shiftKey: true }); + await user.keyboard('{Shift>}[Space]{/Shift}'); expect(getSelectedRowIds()).to.deep.equal([]); }); - it('should not select a range with shift pressed', () => { - render(); + it('should not select a range with shift pressed', async () => { + const { user } = render(); const cell00 = getCell(0, 0); - fireUserEvent.mousePress(cell00); + await user.click(cell00); - fireEvent.keyDown(cell00, { key: ' ', shiftKey: true }); + await user.keyboard('{Shift>}[Space]{/Shift}'); expect(getSelectedRowIds()).to.deep.equal([0]); - fireEvent.keyDown(cell00, { - key: 'ArrowDown', - shiftKey: true, - }); + await user.keyboard('{Shift>}[ArrowDown]{/Shift}'); expect(getSelectedRowIds()).to.deep.equal([1]); }); @@ -224,47 +222,47 @@ describe(' - Row selection', () => { expect(getColumnHeaderCell(0).querySelectorAll('input')).to.have.length(1); }); - it('should check then uncheck when clicking twice the row', () => { - render(); + it('should check then uncheck when clicking twice the row', async () => { + const { user } = render(); expect(getSelectedRowIds()).to.deep.equal([]); expect(getRow(0).querySelector('input')).to.have.property('checked', false); - fireEvent.click(getCell(0, 1)); + await user.click(getCell(0, 1)); expect(getSelectedRowIds()).to.deep.equal([0]); expect(getRow(0).querySelector('input')).to.have.property('checked', true); - fireEvent.click(getCell(0, 1)); + await user.click(getCell(0, 1)); expect(getSelectedRowIds()).to.deep.equal([]); expect(getRow(0).querySelector('input')).to.have.property('checked', false); }); - it('should check and uncheck when double clicking the checkbox', () => { - render(); + it('should check and uncheck when double clicking the checkbox', async () => { + const { user } = render(); expect(getSelectedRowIds()).to.deep.equal([]); expect(getRow(0).querySelector('input')).to.have.property('checked', false); - fireEvent.click(getCell(0, 0).querySelector('input')!); + await user.click(getCell(0, 0).querySelector('input')!); expect(getSelectedRowIds()).to.deep.equal([0]); expect(getRow(0).querySelector('input')).to.have.property('checked', true); - fireEvent.click(getCell(0, 0).querySelector('input')!); + await user.click(getCell(0, 0).querySelector('input')!); expect(getSelectedRowIds()).to.deep.equal([]); expect(getRow(0).querySelector('input')).to.have.property('checked', false); }); it('should set focus on the cell when clicking the checkbox', async () => { - render(); + const { user } = render(); expect(getActiveCell()).to.equal(null); const checkboxInput = getCell(0, 0).querySelector('input'); - fireUserEvent.mousePress(checkboxInput!); + await user.click(checkboxInput!); await waitFor(() => expect(getActiveCell()).to.equal('0-0')); }); - it('should select all visible rows regardless of pagination', () => { - render( + it('should select all visible rows regardless of pagination', async () => { + const { user } = render( - Row selection', () => { />, ); const selectAllCheckbox = screen.getByRole('checkbox', { name: 'Select all rows' }); - fireEvent.click(selectAllCheckbox); + await user.click(selectAllCheckbox); expect(getSelectedRowIds()).to.deep.equal([0]); - fireEvent.click(screen.getByRole('button', { name: /next page/i })); + await user.click(screen.getByRole('button', { name: /next page/i })); expect(getSelectedRowIds()).to.deep.equal([1]); }); @@ -294,53 +292,67 @@ describe(' - Row selection', () => { expect(getRow(1).querySelector('input')).to.have.property('disabled', true); }); - it('should select a range with shift pressed when clicking the row', () => { - render(); - fireEvent.click(getCell(0, 1)); + it('should select a range with shift pressed when clicking the row', async () => { + const { user } = render(); + await user.click(getCell(0, 1)); expect(getSelectedRowIds()).to.deep.equal([0]); - fireEvent.click(getCell(2, 1), { shiftKey: true }); + await user.keyboard('{Shift>}'); + await user.click(getCell(2, 1)); expect(getSelectedRowIds()).to.deep.equal([0, 1, 2]); }); - it('should select a range with shift pressed when clicking the checkbox', () => { - render(); - fireEvent.click(getCell(0, 0).querySelector('input')!); + it('should select a range with shift pressed when clicking the checkbox', async () => { + const { user } = render(); + await user.click(getCell(0, 0).querySelector('input')!); expect(getSelectedRowIds()).to.deep.equal([0]); - fireEvent.click(getCell(2, 0).querySelector('input')!, { shiftKey: true }); + await user.keyboard('{Shift>}'); + await user.click(getCell(2, 0).querySelector('input')!); expect(getSelectedRowIds()).to.deep.equal([0, 1, 2]); }); - it('should unselect from last clicked cell to cell after clicked cell if clicking inside a selected range', () => { - render(); - fireEvent.click(getCell(0, 0).querySelector('input')!); + it('should unselect from last clicked cell to cell after clicked cell if clicking inside a selected range', async () => { + const { user } = render(); + await user.click(getCell(0, 0).querySelector('input')!); expect(getSelectedRowIds()).to.deep.equal([0]); - fireEvent.click(getCell(3, 0).querySelector('input')!, { shiftKey: true }); + + await user.keyboard('{Shift>}'); + await user.click(getCell(3, 0).querySelector('input')!); + await user.keyboard('{/Shift}'); expect(getSelectedRowIds()).to.deep.equal([0, 1, 2, 3]); - fireEvent.click(getCell(1, 0).querySelector('input')!, { shiftKey: true }); + + await user.keyboard('{Shift>}'); + await user.click(getCell(1, 0).querySelector('input')!); + await user.keyboard('{/Shift}'); expect(getSelectedRowIds()).to.deep.equal([0, 1]); }); - it('should not change the selection with shift pressed when clicking on the last row of the selection', () => { - render(); - fireEvent.click(getCell(0, 0).querySelector('input')!); + it('should not change the selection with shift pressed when clicking on the last row of the selection', async () => { + const { user } = render(); + await user.click(getCell(0, 0).querySelector('input')!); expect(getSelectedRowIds()).to.deep.equal([0]); - fireEvent.click(getCell(2, 0).querySelector('input')!, { shiftKey: true }); + + await user.keyboard('{Shift>}'); + await user.click(getCell(2, 0).querySelector('input')!); + await user.keyboard('{/Shift}'); expect(getSelectedRowIds()).to.deep.equal([0, 1, 2]); - fireEvent.click(getCell(2, 0).querySelector('input')!, { shiftKey: true }); + + await user.keyboard('{Shift>}'); + await user.click(getCell(2, 0).querySelector('input')!); + await user.keyboard('{/Shift}'); expect(getSelectedRowIds()).to.deep.equal([0, 1, 2]); }); - it('should reset selected rows when turning off checkboxSelection', () => { - const { setProps } = render(); - fireEvent.click(getCell(0, 0).querySelector('input')!); - fireEvent.click(getCell(1, 0).querySelector('input')!); + it('should reset selected rows when turning off checkboxSelection', async () => { + const { setProps, user } = render(); + await user.click(getCell(0, 0).querySelector('input')!); + await user.click(getCell(1, 0).querySelector('input')!); expect(getSelectedRowIds()).to.deep.equal([0, 1]); setProps({ checkboxSelection: false }); expect(getSelectedRowIds()).to.deep.equal([]); }); - it('should reset row selection in the current page as selected when turning off checkboxSelection', () => { - const { setProps } = render( + it('should reset row selection in the current page as selected when turning off checkboxSelection', async () => { + const { setProps, user } = render( - Row selection', () => { pageSizeOptions={[2]} />, ); - fireEvent.click(getCell(0, 0).querySelector('input')!); + await user.click(getCell(0, 0).querySelector('input')!); expect(getSelectedRowIds()).to.deep.equal([0]); - fireEvent.click(screen.getByRole('button', { name: /next page/i })); - fireEvent.click(getCell(2, 0).querySelector('input')!); + await user.click(screen.getByRole('button', { name: /next page/i })); + await user.click(getCell(2, 0).querySelector('input')!); expect(screen.getByText('2 rows selected')).not.to.equal(null); setProps({ checkboxSelection: false }); expect(getSelectedRowIds()).to.deep.equal([]); expect(screen.queryByText('2 row selected')).to.equal(null); }); - it('should set the correct aria-label on the column header checkbox', () => { - render(); + it('should set the correct aria-label on the column header checkbox', async () => { + const { user } = render(); expect(screen.queryByRole('checkbox', { name: 'Unselect all rows' })).to.equal(null); expect(screen.queryByRole('checkbox', { name: 'Select all rows' })).not.to.equal(null); - fireEvent.click(screen.getByRole('checkbox', { name: 'Select all rows' })); + await user.click(screen.getByRole('checkbox', { name: 'Select all rows' })); expect(screen.queryByRole('checkbox', { name: 'Select all rows' })).to.equal(null); expect(screen.queryByRole('checkbox', { name: 'Unselect all rows' })).not.to.equal(null); }); - it('should set the correct aria-label on the cell checkbox', () => { - render(); + it('should set the correct aria-label on the cell checkbox', async () => { + const { user } = render( + , + ); expect(screen.queryByRole('checkbox', { name: 'Unselect row' })).to.equal(null); expect(screen.queryByRole('checkbox', { name: 'Select row' })).not.to.equal(null); - fireEvent.click(screen.getByRole('checkbox', { name: 'Select row' })); + await user.click(screen.getByRole('checkbox', { name: 'Select row' })); expect(screen.queryByRole('checkbox', { name: 'Select row' })).to.equal(null); expect(screen.queryByRole('checkbox', { name: 'Unselect row' })).not.to.equal(null); }); - it('should not select more than one row when disableMultipleRowSelection = true', () => { - render(); + it('should not select more than one row when disableMultipleRowSelection = true', async () => { + const { user } = render( + , + ); const input1 = getCell(0, 0).querySelector('input')!; - fireEvent.click(input1); + await user.click(input1); expect(input1.checked).to.equal(true); const input2 = getCell(1, 0).querySelector('input')!; - fireEvent.click(input2); + await user.click(input2); expect(input1.checked).to.equal(false); expect(input2.checked).to.equal(true); }); @@ -430,6 +446,7 @@ describe(' - Row selection', () => { }} />, ); + const selectAllCheckbox = screen.getByRole('checkbox', { name: 'Select all rows' }); fireEvent.click(selectAllCheckbox); await waitFor(() => { @@ -437,6 +454,7 @@ describe(' - Row selection', () => { }); expect(grid('selectedRowCount')?.textContent).to.equal('4 rows selected'); + // Click on Menu in id header column fireEvent.change(screen.getByRole('spinbutton', { name: 'Value' }), { target: { value: 1 }, }); @@ -460,113 +478,130 @@ describe(' - Row selection', () => { }); describe('prop: indeterminateCheckboxAction = "select"', () => { - it('should select all the rows when clicking on "Select All" checkbox in indeterminate state', () => { - render(); + it('should select all the rows when clicking on "Select All" checkbox in indeterminate state', async () => { + const { user } = render( + , + ); const selectAllCheckbox = screen.getByRole('checkbox', { name: 'Select all rows' }); - fireEvent.click(screen.getAllByRole('checkbox', { name: /select row/i })[0]); - fireEvent.click(selectAllCheckbox); + await user.click(screen.getAllByRole('checkbox', { name: /select row/i })[0]); + await user.click(selectAllCheckbox); expect(getSelectedRowIds()).to.deep.equal([0, 1, 2, 3]); }); }); describe('prop: indeterminateCheckboxAction = "deselect"', () => { - it('should deselect all the rows when clicking on "Select All" checkbox in indeterminate state', () => { - render(); + it('should deselect all the rows when clicking on "Select All" checkbox in indeterminate state', async () => { + const { user } = render( + , + ); const selectAllCheckbox = screen.getByRole('checkbox', { name: 'Select all rows' }); - fireEvent.click(screen.getAllByRole('checkbox', { name: /select row/i })[0]); - fireEvent.click(selectAllCheckbox); + await user.click(screen.getAllByRole('checkbox', { name: /select row/i })[0]); + await user.click(selectAllCheckbox); expect(getSelectedRowIds()).to.deep.equal([]); }); }); }); describe('prop: checkboxSelection = true (multi selection), with keyboard events', () => { - it('should select row below when pressing "ArrowDown" + shiftKey', () => { - render(); - fireUserEvent.mousePress(getCell(2, 1)); + it('should select row below when pressing "ArrowDown" + shiftKey', async () => { + const { user } = render(); + await user.click(getCell(2, 1)); expect(getSelectedRowIds()).to.deep.equal([2]); - fireEvent.keyDown(getCell(2, 1), { key: 'ArrowDown', shiftKey: true }); + await user.keyboard('{Shift>}[ArrowDown]{/Shift}'); expect(getSelectedRowIds()).to.deep.equal([2, 3]); - fireEvent.keyDown(getCell(3, 1), { key: 'ArrowDown' }); + + await user.click(getCell(3, 1)); + await user.keyboard('{ArrowDown}'); expect(getSelectedRowIds()).to.deep.equal([2, 3]); // Already on the last row }); - it('should unselect previous row when pressing "ArrowDown" + shiftKey', () => { - render(); - fireUserEvent.mousePress(getCell(3, 1)); + it('should unselect previous row when pressing "ArrowDown" + shiftKey', async () => { + const { user } = render(); + await user.click(getCell(3, 1)); expect(getSelectedRowIds()).to.deep.equal([3]); - fireUserEvent.mousePress(getCell(1, 1), { shiftKey: true }); + await user.keyboard('{Shift>}'); + await user.click(getCell(1, 1)); + await user.keyboard('{/Shift}'); expect(getSelectedRowIds()).to.deep.equal([1, 2, 3]); - fireEvent.keyDown(getCell(1, 1), { key: 'ArrowDown', shiftKey: true }); + + await user.keyboard('{Shift>}[ArrowDown]{/Shift}'); expect(getSelectedRowIds()).to.deep.equal([2, 3]); }); - it('should not unselect row above when pressing "ArrowDown" + shiftKey', () => { - render(); - fireUserEvent.mousePress(getCell(1, 1)); + it('should not unselect row above when pressing "ArrowDown" + shiftKey', async () => { + const { user } = render(); + await user.click(getCell(1, 1)); expect(getSelectedRowIds()).to.deep.equal([1]); - fireUserEvent.mousePress(getCell(2, 1), { shiftKey: true }); + + await user.keyboard('{Shift>}'); + await user.click(getCell(2, 1)); + await user.keyboard('{/Shift}'); expect(getSelectedRowIds()).to.deep.equal([1, 2]); - fireEvent.keyDown(getCell(2, 1), { key: 'ArrowDown', shiftKey: true }); + + await user.keyboard('{Shift>}[ArrowDown]{/Shift}'); expect(getSelectedRowIds()).to.deep.equal([1, 2, 3]); - fireEvent.keyDown(getCell(3, 1), { key: 'ArrowDown' }); + + await user.keyboard('{ArrowDown/}'); expect(getSelectedRowIds()).to.deep.equal([1, 2, 3]); // Already on the last row }); - it('should unselect previous row when pressing "ArrowUp" + shiftKey', () => { - render(); - fireUserEvent.mousePress(getCell(2, 1)); + it('should unselect previous row when pressing "ArrowUp" + shiftKey', async () => { + const { user } = render(); + await user.click(getCell(2, 1)); expect(getSelectedRowIds()).to.deep.equal([2]); - fireUserEvent.mousePress(getCell(3, 1), { shiftKey: true }); + + await user.keyboard('{Shift>}'); + await user.click(getCell(3, 1)); + await user.keyboard('{/Shift}'); expect(getSelectedRowIds()).to.deep.equal([2, 3]); - fireEvent.keyDown(getCell(3, 1), { key: 'ArrowUp', shiftKey: true }); + + await user.keyboard('{Shift>}[ArrowUp]{/Shift}'); expect(getSelectedRowIds()).to.deep.equal([2]); }); - it('should add new row to the selection when pressing Shift+Space', () => { - render(); + it('should add new row to the selection when pressing Shift+Space', async () => { + const { user } = render( + , + ); expect(getSelectedRowIds()).to.deep.equal([]); const cell21 = getCell(2, 1); - fireUserEvent.mousePress(cell21); - fireEvent.keyDown(cell21, { - key: ' ', - shiftKey: true, - }); + await user.click(cell21); + await user.keyboard('{Shift>}[Space]{/Shift}'); expect(getSelectedRowIds()).to.deep.equal([2]); const cell11 = getCell(1, 1); - fireUserEvent.mousePress(cell11); - fireEvent.keyDown(cell11, { - key: ' ', - shiftKey: true, - }); + await user.click(cell11); + await user.keyboard('{Shift>}[Space]{/Shift}'); expect(getSelectedRowIds()).to.deep.equal([1, 2]); }); - it('should not jump during scroll while the focus is on the checkbox', function test() { + it('should not jump during scroll while the focus is on the checkbox', async function test() { if (isJSDOM) { this.skip(); // HTMLElement.focus() only scrolls to the element on a real browser } const data = getBasicGridData(20, 1); - render(); + const { user } = render( + , + ); const checkboxes = screen.queryAllByRole('checkbox', { name: /select row/i }); - fireUserEvent.mousePress(checkboxes[0]); + await user.click(checkboxes[0]); expect(checkboxes[0]).toHaveFocus(); - fireEvent.keyDown(checkboxes[0], { key: 'ArrowDown' }); - fireEvent.keyDown(checkboxes[1], { key: 'ArrowDown' }); - fireEvent.keyDown(checkboxes[2], { key: 'ArrowDown' }); + + await user.keyboard('{ArrowDown}'); + await user.keyboard('{ArrowDown}'); + await user.keyboard('{ArrowDown}'); const virtualScroller = document.querySelector('.MuiDataGrid-virtualScroller')!; virtualScroller.scrollTop = 250; // Scroll 5 rows virtualScroller.dispatchEvent(new Event('scroll')); expect(virtualScroller.scrollTop).to.equal(250); }); - it('should set tabindex=0 on the checkbox when the it receives focus', () => { - render(); + it('should set tabindex=0 on the checkbox when the it receives focus', async () => { + const { user } = render(); const checkbox = screen.getAllByRole('checkbox', { name: /select row/i })[0]; const checkboxCell = getCell(0, 0); const secondCell = getCell(0, 1); @@ -574,32 +609,28 @@ describe(' - Row selection', () => { expect(checkboxCell).to.have.attribute('tabindex', '-1'); expect(secondCell).to.have.attribute('tabindex', '-1'); - fireUserEvent.mousePress(secondCell); + await user.click(secondCell); expect(secondCell).to.have.attribute('tabindex', '0'); - fireEvent.keyDown(secondCell, { key: 'ArrowLeft' }); + await user.keyboard('{ArrowLeft}'); expect(secondCell).to.have.attribute('tabindex', '-1'); // Ensure that checkbox has tabindex=0 and the cell has tabindex=-1 expect(checkbox).to.have.attribute('tabindex', '0'); expect(checkboxCell).to.have.attribute('tabindex', '-1'); }); - it('should select/unselect all rows when pressing space', () => { - render(); + it('should select/unselect all rows when pressing space', async () => { + const { user } = render(); const selectAllCell = document.querySelector( '[role="columnheader"][data-field="__check__"] input', )!; - act(() => selectAllCell.focus()); + await act(() => selectAllCell.focus()); - fireEvent.keyDown(selectAllCell, { - key: ' ', - }); + await user.keyboard('[Space]'); expect(getSelectedRowIds()).to.deep.equal([0, 1, 2, 3]); - fireEvent.keyDown(selectAllCell, { - key: ' ', - }); + await user.keyboard('[Space]'); expect(getSelectedRowIds()).to.deep.equal([]); }); @@ -615,7 +646,7 @@ describe(' - Row selection', () => { } render(); const cell = getCell(1, 1); - fireUserEvent.mousePress(cell); + fireEvent.click(cell); fireEvent.keyDown(cell, { key: 'ArrowLeft' }); fireEvent.keyDown(getCell(1, 0).querySelector('input')!, { key: 'ArrowUp' }); clock.runToLast(); // Wait for transition @@ -626,13 +657,13 @@ describe(' - Row selection', () => { }); describe('prop: isRowSelectable', () => { - it('should update the selected rows when the isRowSelectable prop changes', () => { - const { setProps } = render( + it('should update the selected rows when the isRowSelectable prop changes', async () => { + const { setProps, user } = render( true} checkboxSelection />, ); - fireEvent.click(getCell(0, 0).querySelector('input')!); - fireEvent.click(getCell(1, 0).querySelector('input')!); + await user.click(getCell(0, 0).querySelector('input')!); + await user.click(getCell(1, 0).querySelector('input')!); expect(getSelectedRowIds()).to.deep.equal([0, 1]); @@ -785,9 +816,9 @@ describe(' - Row selection', () => { expect(onRowSelectionModelChange.callCount).to.equal(0); }); - it('should call onRowSelectionModelChange with an empty array if no row is selectable in the current page when turning off checkboxSelection', () => { + it('should call onRowSelectionModelChange with an empty array if no row is selectable in the current page when turning off checkboxSelection', async () => { const onRowSelectionModelChange = spy(); - const { setProps } = render( + const { setProps, user } = render( - Row selection', () => { onRowSelectionModelChange={onRowSelectionModelChange} />, ); - fireEvent.click(getCell(0, 0).querySelector('input')!); + await user.click(getCell(0, 0).querySelector('input')!); expect(onRowSelectionModelChange.lastCall.args[0]).to.deep.equal([0]); - fireEvent.click(screen.getByRole('button', { name: /next page/i })); - fireEvent.click(getCell(2, 0).querySelector('input')!); + await user.click(screen.getByRole('button', { name: /next page/i })); + await user.click(getCell(2, 0).querySelector('input')!); expect(onRowSelectionModelChange.lastCall.args[0]).to.deep.equal([0, 2]); setProps({ checkboxSelection: false, isRowSelectable: () => false }); expect(onRowSelectionModelChange.lastCall.args[0]).to.deep.equal([]); }); - it('should call onRowSelectionModelChange with an empty array if there is no selected row in the current page when turning off checkboxSelection', () => { + it('should call onRowSelectionModelChange with an empty array if there is no selected row in the current page when turning off checkboxSelection', async () => { const onRowSelectionModelChange = spy(); - const { setProps } = render( + const { setProps, user } = render( - Row selection', () => { onRowSelectionModelChange={onRowSelectionModelChange} />, ); - fireEvent.click(getCell(0, 0).querySelector('input')!); - fireEvent.click(getCell(1, 0).querySelector('input')!); + await user.click(getCell(0, 0).querySelector('input')!); + await user.click(getCell(1, 0).querySelector('input')!); expect(onRowSelectionModelChange.lastCall.args[0]).to.deep.equal([0, 1]); - fireEvent.click(screen.getByRole('button', { name: /next page/i })); + await user.click(screen.getByRole('button', { name: /next page/i })); setProps({ checkboxSelection: false }); expect(onRowSelectionModelChange.lastCall.args[0]).to.deep.equal([]); }); @@ -832,32 +863,32 @@ describe(' - Row selection', () => { expect(getSelectedRowIds()).to.deep.equal([1]); }); - it('should update the selection when neither the model nor the onChange are set', () => { - render(); - fireEvent.click(getCell(0, 0)); + it('should update the selection when neither the model nor the onChange are set', async () => { + const { user } = render(); + await user.click(getCell(0, 0)); expect(getSelectedRowIds()).to.deep.equal([0]); }); - it('should not update the selection model when the rowSelectionModel prop is set', () => { + it('should not update the selection model when the rowSelectionModel prop is set', async () => { const rowSelectionModel: GridInputRowSelectionModel = [1]; - render(); + const { user } = render(); expect(getSelectedRowIds()).to.deep.equal([1]); - fireEvent.click(getCell(0, 0)); + await user.click(getCell(0, 0)); expect(getSelectedRowIds()).to.deep.equal([1]); }); - it('should update the selection when the model is not set, but the onChange is set', () => { + it('should update the selection when the model is not set, but the onChange is set', async () => { const onModelChange = spy(); - render(); + const { user } = render(); - fireEvent.click(getCell(0, 0)); + await user.click(getCell(0, 0)); expect(getSelectedRowIds()).to.deep.equal([0]); expect(onModelChange.callCount).to.equal(1); expect(onModelChange.firstCall.firstArg).to.deep.equal([0]); }); - it('should control selection state when the model and the onChange are set', () => { + it('should control selection state when the model and the onChange are set', async () => { function ControlCase() { const [rowSelectionModel, setRowSelectionModel] = React.useState([]); @@ -878,9 +909,9 @@ describe(' - Row selection', () => { ); } - render(); + const { user } = render(); expect(getSelectedRowIds()).to.deep.equal([]); - fireEvent.click(getCell(1, 1)); + await user.click(getCell(1, 1)); expect(getSelectedRowIds()).to.deep.equal([1, 2]); }); @@ -905,25 +936,31 @@ describe(' - Row selection', () => { } render(); - expect(() => act(() => apiRef.current.setRowSelectionModel([0, 1]))).not.to.throw(); + expect(() => + act(() => { + apiRef.current.setRowSelectionModel([0, 1]); + }), + ).not.to.throw(); }); }); describe('prop: rowSelection = false', () => { - it('should not select rows when clicking the checkbox', () => { - render(); + it('should not select rows when clicking the checkbox', async () => { + const { user } = render(); expect(getSelectedRowIds()).to.deep.equal([]); expect(getRow(0).querySelector('input')).to.have.property('checked', false); - fireEvent.click(getCell(0, 1)); + await user.click(getCell(0, 1)); expect(getSelectedRowIds()).to.deep.equal([]); expect(getRow(0).querySelector('input')).to.have.property('checked', false); }); - it('should not select rows with Shift + Space', () => { - render(); + it('should not select rows with Shift + Space', async () => { + const { user } = render( + , + ); const cell0 = getCell(0, 0); - fireUserEvent.mousePress(cell0); - fireEvent.keyDown(cell0, { key: ' ', shiftKey: true }); + await user.click(cell0); + await user.keyboard('{Shift>}[Space]{/Shift}'); expect(getSelectedRowIds()).to.deep.equal([]); }); @@ -934,28 +971,28 @@ describe(' - Row selection', () => { }); describe('accessibility', () => { - it('should add aria-selected attributes to the selectable rows', () => { - render(); + it('should add aria-selected attributes to the selectable rows', async () => { + const { user } = render(); // Select the first row - fireUserEvent.mousePress(getCell(0, 0)); + await user.click(getCell(0, 0)); expect(getRow(0).getAttribute('aria-selected')).to.equal('true'); expect(getRow(1).getAttribute('aria-selected')).to.equal('false'); }); - it('should not add aria-selected attributes if the row selection is disabled', () => { - render(); + it('should not add aria-selected attributes if the row selection is disabled', async () => { + const { user } = render(); expect(getRow(0).getAttribute('aria-selected')).to.equal(null); // Try to select the first row - fireUserEvent.mousePress(getCell(0, 0)); + await user.click(getCell(0, 0)); // nothing should change expect(getRow(0).getAttribute('aria-selected')).to.equal(null); }); }); describe('performance', () => { - it('should not rerender unrelated nodes', () => { + it('should not rerender unrelated nodes', async () => { // Couldn't use because we need to track multiple components let commits: any[] = []; function CustomCell(props: any) { @@ -967,7 +1004,7 @@ describe(' - Row selection', () => { return
Hello
; } - render( + const { user } = render(
- Row selection', () => { expect(getSelectedRowIds()).to.deep.equal([]); expect(getRow(0).querySelector('input')).to.have.property('checked', false); commits = []; - fireEvent.click(getCell(0, 1)); + await user.click(getCell(0, 1)); expect(getSelectedRowIds()).to.deep.equal([0]); expect(getRow(0).querySelector('input')).to.have.property('checked', true); // It shouldn't rerender any of the custom cells diff --git a/packages/x-data-grid/src/tests/rows.DataGrid.test.tsx b/packages/x-data-grid/src/tests/rows.DataGrid.test.tsx index 2c859d30fccbf..e3dbe06d56f85 100644 --- a/packages/x-data-grid/src/tests/rows.DataGrid.test.tsx +++ b/packages/x-data-grid/src/tests/rows.DataGrid.test.tsx @@ -425,8 +425,8 @@ describe(' - Rows', () => { expect(deleteButton).toHaveFocus(); }); - it('should set the correct tabIndex to the focused button', () => { - render( + it('should set the correct tabIndex to the focused button', async () => { + const { user } = render( [ } label="print" />, @@ -436,9 +436,11 @@ describe(' - Rows', () => { ); const firstCell = getCell(0, 0); const secondCell = getCell(0, 1); - firstCell.focus(); + act(() => { + firstCell.focus(); + }); - fireEvent.keyDown(firstCell, { key: 'ArrowRight' }); + await user.keyboard('{ArrowRight}'); expect(secondCell).to.have.property('tabIndex', -1); const printButton = screen.getByRole('menuitem', { name: 'print' }); @@ -446,7 +448,10 @@ describe(' - Rows', () => { expect(printButton).to.have.property('tabIndex', 0); expect(menuButton).to.have.property('tabIndex', -1); - fireEvent.keyDown(printButton, { key: 'ArrowRight' }); + act(() => { + printButton.focus(); + }); + await user.keyboard('{ArrowRight}'); expect(printButton).to.have.property('tabIndex', -1); expect(menuButton).to.have.property('tabIndex', 0); }); diff --git a/packages/x-data-grid/src/tests/sorting.DataGrid.test.tsx b/packages/x-data-grid/src/tests/sorting.DataGrid.test.tsx index c57d2ec690c4c..5779fa9a59ccf 100644 --- a/packages/x-data-grid/src/tests/sorting.DataGrid.test.tsx +++ b/packages/x-data-grid/src/tests/sorting.DataGrid.test.tsx @@ -119,7 +119,7 @@ describe(' - Sorting', () => { expect(getColumnValues(0)).to.deep.equal(['10', '0', '5']); }); - it('should allow clearing the current sorting using `sortColumn` idempotently', () => { + it('should allow clearing the current sorting using `sortColumn` idempotently', async () => { let apiRef: React.MutableRefObject; function TestCase() { apiRef = useGridApiRef(); @@ -133,20 +133,20 @@ describe(' - Sorting', () => { ); } - render(); + const { user } = render(); expect(getColumnValues(0)).to.deep.equal(['10', '0', '5']); const header = getColumnHeaderCell(0); // Trigger a sort using the header - fireEvent.click(header); + await user.click(header); expect(getColumnValues(0)).to.deep.equal(['0', '5', '10']); // Clear the value using `apiRef` - act(() => apiRef.current.sortColumn('id', null)); + await act(() => apiRef.current.sortColumn('id', null)); expect(getColumnValues(0)).to.deep.equal(['10', '0', '5']); // Check the behavior is idempotent - act(() => apiRef.current.sortColumn('id', null)); + await act(() => apiRef.current.sortColumn('id', null)); expect(getColumnValues(0)).to.deep.equal(['10', '0', '5']); }); diff --git a/packages/x-data-grid/tsconfig.json b/packages/x-data-grid/tsconfig.json index a95beb1e8020a..08e4c0e2576ce 100644 --- a/packages/x-data-grid/tsconfig.json +++ b/packages/x-data-grid/tsconfig.json @@ -7,7 +7,8 @@ "chai-dom", "mocha", "node" - ] + ], + "skipLibCheck": true }, "include": ["src/**/*"] } diff --git a/packages/x-date-pickers-pro/package.json b/packages/x-date-pickers-pro/package.json index d66d4ffb75a7e..3c52904e57b82 100644 --- a/packages/x-date-pickers-pro/package.json +++ b/packages/x-date-pickers-pro/package.json @@ -97,8 +97,8 @@ }, "devDependencies": { "@mui/internal-test-utils": "^1.0.17", - "@mui/material": "^5.16.7", - "@mui/system": "^5.16.7", + "@mui/material": "^5.16.13", + "@mui/system": "^5.16.13", "@types/luxon": "^3.4.2", "@types/prop-types": "^15.7.13", "date-fns": "^2.30.0", diff --git a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerTabs.tsx b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerTabs.tsx index 60e1a9f533f2b..0e939f2eb6d70 100644 --- a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerTabs.tsx +++ b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerTabs.tsx @@ -51,12 +51,12 @@ export interface ExportedDateTimeRangePickerTabsProps extends ExportedBaseTabsPr * Date tab icon. * @default DateRangeIcon */ - dateIcon?: React.ReactElement; + dateIcon?: React.ReactElement; /** * Time tab icon. * @default TimeIcon */ - timeIcon?: React.ReactElement; + timeIcon?: React.ReactElement; /** * Override or extend the styles applied to the component. */ diff --git a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerTimeWrapper.tsx b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerTimeWrapper.tsx index e8f096ffcef58..cf513a55c2663 100644 --- a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerTimeWrapper.tsx +++ b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerTimeWrapper.tsx @@ -1,4 +1,4 @@ -import * as React from 'react'; +import { DefaultizedProps } from '@mui/x-internals/types'; import { PickerSelectionState, PickerViewRenderer, @@ -6,7 +6,6 @@ import { useUtils, TimeViewWithMeridiem, BaseClockProps, - DefaultizedProps, } from '@mui/x-date-pickers/internals'; import { PickerValidDate } from '@mui/x-date-pickers/models'; import { DateRange } from '../models'; @@ -50,10 +49,7 @@ function DateTimeRangePickerTimeWrapper< Omit, 'value' | 'defaultValue' | 'onChange'>, 'views' >, ->( - props: DateTimeRangePickerTimeWrapperProps, - ref: React.Ref, -) { +>(props: DateTimeRangePickerTimeWrapperProps) { const utils = useUtils(); const { @@ -102,7 +98,6 @@ function DateTimeRangePickerTimeWrapper< return viewRenderer({ ...other, - ref, views, onViewChange, value: currentValue, diff --git a/packages/x-date-pickers-pro/src/internals/hooks/useEnrichedRangePickerFieldProps.ts b/packages/x-date-pickers-pro/src/internals/hooks/useEnrichedRangePickerFieldProps.ts index aa1862e0f49a5..f00b4fa68cedb 100644 --- a/packages/x-date-pickers-pro/src/internals/hooks/useEnrichedRangePickerFieldProps.ts +++ b/packages/x-date-pickers-pro/src/internals/hooks/useEnrichedRangePickerFieldProps.ts @@ -138,8 +138,8 @@ export interface UseEnrichedRangePickerFieldPropsParams< currentView?: TView | null; initialView?: TView; onViewChange?: (view: TView) => void; - startFieldRef: React.RefObject>; - endFieldRef: React.RefObject>; + startFieldRef: React.RefObject | null>; + endFieldRef: React.RefObject | null>; } const useMultiInputFieldSlotProps = < diff --git a/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputFieldSelectedSections.ts b/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputFieldSelectedSections.ts index 4f6987aa23612..4778c5ee78ac4 100644 --- a/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputFieldSelectedSections.ts +++ b/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputFieldSelectedSections.ts @@ -14,9 +14,20 @@ interface UseMultiInputFieldSelectedSectionsParams unstableEndFieldRef?: React.Ref>; } +interface UseMultiInputFieldSelectedSectionsResponseItem { + unstableFieldRef?: React.Ref>; + selectedSections: FieldSelectedSections; + onSelectedSectionsChange: (newSelectedSections: FieldSelectedSections) => void; +} + +interface UseMultiInputFieldSelectedSectionsResponse { + start: UseMultiInputFieldSelectedSectionsResponseItem; + end: UseMultiInputFieldSelectedSectionsResponseItem; +} + export const useMultiInputFieldSelectedSections = ( params: UseMultiInputFieldSelectedSectionsParams, -) => { +): UseMultiInputFieldSelectedSectionsResponse => { const unstableEndFieldRef = React.useRef>(null); const handleUnstableEndFieldRef = useForkRef(params.unstableEndFieldRef, unstableEndFieldRef); diff --git a/packages/x-date-pickers-pro/src/internals/hooks/useRangePosition.ts b/packages/x-date-pickers-pro/src/internals/hooks/useRangePosition.ts index c5029471e4e88..fe4798ee7709b 100644 --- a/packages/x-date-pickers-pro/src/internals/hooks/useRangePosition.ts +++ b/packages/x-date-pickers-pro/src/internals/hooks/useRangePosition.ts @@ -30,7 +30,7 @@ export interface UseRangePositionResponse { export const useRangePosition = ( props: UseRangePositionProps, - singleInputFieldRef?: React.RefObject>, + singleInputFieldRef?: React.RefObject | null>, ): UseRangePositionResponse => { const [rangePosition, setRangePosition] = useControlled({ name: 'useRangePosition', diff --git a/packages/x-date-pickers/package.json b/packages/x-date-pickers/package.json index 49e8ab2b835cc..733c592a380ff 100644 --- a/packages/x-date-pickers/package.json +++ b/packages/x-date-pickers/package.json @@ -99,8 +99,8 @@ }, "devDependencies": { "@mui/internal-test-utils": "^1.0.17", - "@mui/material": "^5.16.7", - "@mui/system": "^5.16.7", + "@mui/material": "^5.16.13", + "@mui/system": "^5.16.13", "@types/luxon": "^3.4.2", "@types/moment-hijri": "^2.1.4", "@types/moment-jalaali": "^0.7.9", diff --git a/packages/x-date-pickers/src/DateCalendar/PickersFadeTransitionGroup.tsx b/packages/x-date-pickers/src/DateCalendar/PickersFadeTransitionGroup.tsx index 584a245ad0157..6601088e0a036 100644 --- a/packages/x-date-pickers/src/DateCalendar/PickersFadeTransitionGroup.tsx +++ b/packages/x-date-pickers/src/DateCalendar/PickersFadeTransitionGroup.tsx @@ -10,7 +10,7 @@ import { } from './pickersFadeTransitionGroupClasses'; export interface PickersFadeTransitionGroupProps { - children: React.ReactElement; + children: React.ReactElement; className?: string; reduceAnimations: boolean; transKey: React.Key; diff --git a/packages/x-date-pickers/src/DateCalendar/PickersSlideTransition.tsx b/packages/x-date-pickers/src/DateCalendar/PickersSlideTransition.tsx index e560306b50331..16e5e255b511d 100644 --- a/packages/x-date-pickers/src/DateCalendar/PickersSlideTransition.tsx +++ b/packages/x-date-pickers/src/DateCalendar/PickersSlideTransition.tsx @@ -21,7 +21,7 @@ export interface ExportedSlideTransitionProps { export interface SlideTransitionProps extends Omit, ExportedSlideTransitionProps { - children: React.ReactElement; + children: React.ReactElement; className?: string; reduceAnimations: boolean; slideDirection: SlideDirection; @@ -137,7 +137,7 @@ export function PickersSlideTransition(inProps: SlideTransitionProps) { return ( + childFactory={(element: React.ReactElement) => React.cloneElement(element, { classNames: transitionClasses, }) diff --git a/packages/x-date-pickers/src/internals/hooks/useField/useFieldV6TextField.ts b/packages/x-date-pickers/src/internals/hooks/useField/useFieldV6TextField.ts index 288b0ee44de97..b882e0c56f942 100644 --- a/packages/x-date-pickers/src/internals/hooks/useField/useFieldV6TextField.ts +++ b/packages/x-date-pickers/src/internals/hooks/useField/useFieldV6TextField.ts @@ -76,8 +76,8 @@ export const addPositionPropertiesToSections = ( export const useFieldV6TextField: UseFieldTextField = (params) => { const isRtl = useRtl(); - const focusTimeoutRef = React.useRef>(); - const selectionSyncTimeoutRef = React.useRef>(); + const focusTimeoutRef = React.useRef>(undefined); + const selectionSyncTimeoutRef = React.useRef>(undefined); const { forwardedProps: { diff --git a/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerViews.ts b/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerViews.ts index e96e3754fe946..8a70152236ef0 100644 --- a/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerViews.ts +++ b/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerViews.ts @@ -122,7 +122,7 @@ export interface UsePickerViewParams< propsFromPickerValue: UsePickerValueViewsResponse; additionalViewProps: TAdditionalProps; autoFocusView: boolean; - fieldRef: React.RefObject> | undefined; + fieldRef?: React.RefObject | null>; /** * A function that intercepts the regular picker rendering. * Can be used to consume the provided `viewRenderers` and render a custom component wrapping them. diff --git a/packages/x-date-pickers/src/internals/hooks/useStaticPicker/useStaticPicker.tsx b/packages/x-date-pickers/src/internals/hooks/useStaticPicker/useStaticPicker.tsx index 08873f535dd21..7c6f79c2914d1 100644 --- a/packages/x-date-pickers/src/internals/hooks/useStaticPicker/useStaticPicker.tsx +++ b/packages/x-date-pickers/src/internals/hooks/useStaticPicker/useStaticPicker.tsx @@ -43,7 +43,6 @@ export const useStaticPicker = < ...pickerParams, props, autoFocusView: autoFocus ?? false, - fieldRef: undefined, additionalViewProps: {}, wrapperVariant: displayStaticWrapperAs, }); diff --git a/packages/x-date-pickers/src/internals/hooks/useUtils.ts b/packages/x-date-pickers/src/internals/hooks/useUtils.ts index a7c2e1d541307..ecf9e269277a5 100644 --- a/packages/x-date-pickers/src/internals/hooks/useUtils.ts +++ b/packages/x-date-pickers/src/internals/hooks/useUtils.ts @@ -53,7 +53,7 @@ export const useDefaultDates = () => export const useNow = (timezone: PickersTimezone): TDate => { const utils = useUtils(); - const now = React.useRef() as React.MutableRefObject; + const now = React.useRef(undefined); if (now.current === undefined) { now.current = utils.date(undefined, timezone); } diff --git a/packages/x-tree-view-pro/package.json b/packages/x-tree-view-pro/package.json index 67b77a27c94b5..3b77f71092e0d 100644 --- a/packages/x-tree-view-pro/package.json +++ b/packages/x-tree-view-pro/package.json @@ -71,8 +71,8 @@ }, "devDependencies": { "@mui/internal-test-utils": "^1.0.17", - "@mui/material": "^5.16.7", - "@mui/system": "^5.16.7", + "@mui/material": "^5.16.13", + "@mui/system": "^5.16.13", "@types/prop-types": "^15.7.13", "rimraf": "^6.0.1" }, diff --git a/packages/x-tree-view/package.json b/packages/x-tree-view/package.json index 3b5fce81a8320..567a2ce60b20e 100644 --- a/packages/x-tree-view/package.json +++ b/packages/x-tree-view/package.json @@ -69,8 +69,8 @@ }, "devDependencies": { "@mui/internal-test-utils": "^1.0.17", - "@mui/material": "^5.16.7", - "@mui/system": "^5.16.7", + "@mui/material": "^5.16.13", + "@mui/system": "^5.16.13", "@types/prop-types": "^15.7.13", "rimraf": "^6.0.1" }, diff --git a/packages/x-tree-view/src/internals/hooks/useInstanceEventHandler.ts b/packages/x-tree-view/src/internals/hooks/useInstanceEventHandler.ts index 796b68309b7ff..519ea9e11402c 100644 --- a/packages/x-tree-view/src/internals/hooks/useInstanceEventHandler.ts +++ b/packages/x-tree-view/src/internals/hooks/useInstanceEventHandler.ts @@ -41,7 +41,7 @@ export function createUseInstanceEventHandler(registryContainer: RegistryContain const subscription = React.useRef<(() => void) | null>(null); const handlerRef = React.useRef< TreeViewEventListener[E]> | undefined - >(); + >(undefined); handlerRef.current = handler; const cleanupTokenRef = React.useRef(null); diff --git a/packages/x-tree-view/src/internals/useTreeView/useTreeView.ts b/packages/x-tree-view/src/internals/useTreeView/useTreeView.ts index 09f41ff67af73..4fccb37a93d12 100644 --- a/packages/x-tree-view/src/internals/useTreeView/useTreeView.ts +++ b/packages/x-tree-view/src/internals/useTreeView/useTreeView.ts @@ -62,7 +62,7 @@ export const useTreeView = < const instanceRef = React.useRef({} as TreeViewInstance); const instance = instanceRef.current as TreeViewInstance; const publicAPI = useTreeViewApiInitialization>(apiRef); - const innerRootRef: React.RefObject = React.useRef(null); + const innerRootRef = React.useRef(null); const handleRootRef = useForkRef(innerRootRef, rootRef); const contextValue = useTreeViewBuildContext({ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 14e053cbe7102..02139a53736c5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -351,11 +351,11 @@ importers: specifier: ^0.11.10 version: 0.11.10 react: - specifier: ^18.3.1 - version: 18.3.1 + specifier: ^19.0.0 + version: 19.0.0 react-dom: - specifier: ^18.3.1 - version: 18.3.1(react@18.3.1) + specifier: ^19.0.0 + version: 19.0.0(react@19.0.0) remark: specifier: ^15.0.1 version: 15.0.1 @@ -484,7 +484,7 @@ importers: version: link:../packages/x-tree-view/build '@react-spring/web': specifier: ^9.7.5 - version: 9.7.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 9.7.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0) '@tanstack/query-core': specifier: ^5.59.13 version: 5.59.13 @@ -591,20 +591,20 @@ importers: specifier: ^15.8.1 version: 15.8.1 react: - specifier: ^18.3.1 - version: 18.3.1 + specifier: ^19.0.0 + version: 19.0.0 react-docgen: specifier: ^5.4.3 version: 5.4.3 react-dom: - specifier: ^18.3.1 - version: 18.3.1(react@18.3.1) + specifier: ^19.0.0 + version: 19.0.0(react@19.0.0) react-hook-form: specifier: ^7.53.0 version: 7.53.0(react@18.3.1) react-is: - specifier: ^18.3.1 - version: 18.3.1 + specifier: ^19.0.0 + version: 19.0.0 react-router: specifier: ^6.27.0 version: 6.27.0(react@18.3.1) @@ -613,10 +613,10 @@ importers: version: 6.27.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react-runner: specifier: ^1.0.5 - version: 1.0.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 1.0.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0) react-simple-code-editor: specifier: ^0.14.1 - version: 0.14.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 0.14.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) recast: specifier: ^0.23.9 version: 0.23.9 @@ -628,7 +628,7 @@ importers: version: 7.8.1 styled-components: specifier: ^6.1.13 - version: 6.1.13(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 6.1.13(react-dom@19.0.0(react@19.0.0))(react@19.0.0) stylis: specifier: ^4.3.4 version: 4.3.4 @@ -753,7 +753,7 @@ importers: version: 9.7.5 '@react-spring/web': specifier: ^9.7.5 - version: 9.7.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 9.7.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0) clsx: specifier: ^2.1.1 version: 2.1.1 @@ -762,7 +762,7 @@ importers: version: 15.8.1 react: specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 - version: 18.3.1 + version: 19.0.0 react-dom: specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 version: 18.3.1(react@18.3.1) @@ -778,10 +778,10 @@ importers: version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1) '@react-spring/core': specifier: ^9.7.5 - version: 9.7.5(react@18.3.1) + version: 9.7.5(react@19.0.0) '@react-spring/shared': specifier: ^9.7.5 - version: 9.7.5(react@18.3.1) + version: 9.7.5(react@19.0.0) '@types/prop-types': specifier: ^15.7.13 version: 15.7.13 @@ -824,7 +824,7 @@ importers: version: 9.7.5 '@react-spring/web': specifier: ^9.7.5 - version: 9.7.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 9.7.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0) clsx: specifier: ^2.1.1 version: 2.1.1 @@ -833,10 +833,10 @@ importers: version: 15.8.1 react: specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 - version: 18.3.1 + version: 19.0.0 react-dom: specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 - version: 18.3.1(react@18.3.1) + version: 19.0.0(react@19.0.0) devDependencies: '@mui/material': specifier: ^5.16.7 @@ -846,10 +846,10 @@ importers: version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1) '@react-spring/core': specifier: ^9.7.5 - version: 9.7.5(react@18.3.1) + version: 9.7.5(react@19.0.0) '@react-spring/shared': specifier: ^9.7.5 - version: 9.7.5(react@18.3.1) + version: 9.7.5(react@19.0.0) '@types/prop-types': specifier: ^15.7.13 version: 15.7.13 @@ -1003,10 +1003,10 @@ importers: version: 15.8.1 react: specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 - version: 18.3.1 + version: 19.0.0 react-dom: specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 - version: 18.3.1(react@18.3.1) + version: 19.0.0(react@19.0.0) reselect: specifier: ^5.1.1 version: 5.1.1 @@ -1059,7 +1059,7 @@ importers: version: 11.0.1 react: specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 - version: 18.3.1 + version: 19.0.0 devDependencies: '@mui/icons-material': specifier: ^5.16.7 @@ -1115,10 +1115,10 @@ importers: version: 15.8.1 react: specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 - version: 18.3.1 + version: 19.0.0 react-dom: specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 - version: 18.3.1(react@18.3.1) + version: 19.0.0(react@19.0.0) reselect: specifier: ^5.1.1 version: 5.1.1 @@ -1177,10 +1177,10 @@ importers: version: 15.8.1 react: specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 - version: 18.3.1 + version: 19.0.0 react-dom: specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 - version: 18.3.1(react@18.3.1) + version: 19.0.0(react@19.0.0) reselect: specifier: ^5.1.1 version: 5.1.1 @@ -1230,13 +1230,13 @@ importers: version: 15.8.1 react: specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 - version: 18.3.1 + version: 19.0.0 react-dom: specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 - version: 18.3.1(react@18.3.1) + version: 19.0.0(react@19.0.0) react-transition-group: specifier: ^4.4.5 - version: 4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 4.4.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0) devDependencies: '@mui/internal-test-utils': specifier: ^1.0.17 @@ -1325,13 +1325,13 @@ importers: version: 15.8.1 react: specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 - version: 18.3.1 + version: 19.0.0 react-dom: specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 - version: 18.3.1(react@18.3.1) + version: 19.0.0(react@19.0.0) react-transition-group: specifier: ^4.4.5 - version: 4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 4.4.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0) devDependencies: '@mui/internal-test-utils': specifier: ^1.0.17 @@ -1378,7 +1378,7 @@ importers: version: 5.16.6(@types/react@18.3.12)(react@18.3.1) react: specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 - version: 18.3.1 + version: 19.0.0 devDependencies: '@mui/internal-test-utils': specifier: ^1.0.17 @@ -1398,7 +1398,7 @@ importers: version: 5.16.6(@types/react@18.3.12)(react@18.3.1) react: specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 - version: 18.3.1 + version: 19.0.0 devDependencies: '@mui/internal-test-utils': specifier: ^1.0.17 @@ -1436,10 +1436,10 @@ importers: version: 15.8.1 react: specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 - version: 18.3.1 + version: 19.0.0 react-dom: specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 - version: 18.3.1(react@18.3.1) + version: 19.0.0(react@19.0.0) react-transition-group: specifier: ^4.4.5 version: 4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -1495,10 +1495,10 @@ importers: version: 15.8.1 react: specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 - version: 18.3.1 + version: 19.0.0 react-dom: specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 - version: 18.3.1(react@18.3.1) + version: 19.0.0(react@19.0.0) react-transition-group: specifier: ^4.4.5 version: 4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -1563,7 +1563,7 @@ importers: version: 1.44.1 '@react-spring/web': specifier: ^9.7.5 - version: 9.7.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 9.7.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0) '@types/chai': specifier: ^4.3.20 version: 4.3.20 @@ -1598,11 +1598,11 @@ importers: specifier: ^15.8.1 version: 15.8.1 react: - specifier: ^18.3.1 - version: 18.3.1 + specifier: ^19.0.0 + version: 19.0.0 react-dom: - specifier: ^18.3.1 - version: 18.3.1(react@18.3.1) + specifier: ^19.0.0 + version: 19.0.0(react@19.0.0) react-router-dom: specifier: ^6.27.0 version: 6.27.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -1652,11 +1652,11 @@ importers: specifier: ^24.1.3 version: 24.1.3 react: - specifier: ^18.3.1 - version: 18.3.1 + specifier: ^19.0.0 + version: 19.0.0 react-dom: - specifier: ^18.3.1 - version: 18.3.1(react@18.3.1) + specifier: ^19.0.0 + version: 19.0.0(react@19.0.0) vitest: specifier: 2.1.2 version: 2.1.2(@types/node@20.16.11)(@vitest/ui@2.1.2)(jsdom@24.1.3)(terser@5.27.0) @@ -3019,9 +3019,9 @@ packages: resolution: {integrity: sha512-I/lGHztkCzvwlXpjD2+SNmvNQvB4227xBXhISPjEaJUXGImOQ9f3D2Yj/T3KasSI/h0MLWy74X0J6clhPmsRbQ==} engines: {node: '>=12.0.0'} peerDependencies: - '@types/react': ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 - react-dom: ^17.0.0 || ^18.0.0 + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: '@types/react': optional: true @@ -3077,15 +3077,15 @@ packages: react: ^18.2.0 react-dom: ^18.2.0 - '@mui/joy@5.0.0-beta.48': - resolution: {integrity: sha512-OhTvjuGl9I5IvpBr0BQyDehIW/xb2yteW6YglHJMdOb/279nItn76X1NBtPV9ImldNlBjReGwvpOXmBTTGER9w==} + '@mui/joy@5.0.0-beta.51': + resolution: {integrity: sha512-0M+aSSm291CnVLIdQP1di538zD/kekRYSzm+5hWattpGiXvUAYRQMKV4XFcs/dCsr0tkMpVT3dIdmbu6YP2r7g==} engines: {node: '>=12.0.0'} peerDependencies: '@emotion/react': ^11.5.0 '@emotion/styled': ^11.3.0 - '@types/react': ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 - react-dom: ^17.0.0 || ^18.0.0 + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: '@emotion/react': optional: true @@ -8677,10 +8677,10 @@ packages: engines: {node: '>=8.10.0'} hasBin: true - react-dom@18.3.1: - resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} + react-dom@19.0.0: + resolution: {integrity: sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==} peerDependencies: - react: ^18.3.1 + react: ^19.0.0 react-hook-form@7.53.0: resolution: {integrity: sha512-M1n3HhqCww6S2hxLxciEXy2oISPnAzxY7gvwVPrtlczTM/1dDadXgUxDpHMrMTblDOcm/AXtXxHwZ3jpg1mqKQ==} @@ -8688,8 +8688,8 @@ packages: peerDependencies: react: ^16.8.0 || ^17 || ^18 || ^19 - react-is@18.3.1: - resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + react-is@19.0.0: + resolution: {integrity: sha512-H91OHcwjZsbq3ClIDHMzBShc1rotbfACdWENsmEf0IFvZ3FgGPtdHMcsv45bQ1hAbgdfiA8SnxTKfDS+x/8m2g==} react-refresh@0.14.2: resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} @@ -8726,8 +8726,8 @@ packages: react: '>=16.6.0' react-dom: '>=16.6.0' - react@18.3.1: - resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} + react@19.0.0: + resolution: {integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==} engines: {node: '>=0.10.0'} read-cmd-shim@4.0.0: @@ -9007,8 +9007,8 @@ packages: resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} engines: {node: '>=v12.22.7'} - scheduler@0.23.2: - resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + scheduler@0.25.0: + resolution: {integrity: sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==} schema-utils@3.3.0: resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} @@ -11282,7 +11282,7 @@ snapshots: '@emotion/utils': 1.4.0 '@emotion/weak-memoize': 0.4.0 hoist-non-react-statics: 3.3.2 - react: 18.3.1 + react: 19.0.0 optionalDependencies: '@types/react': 18.3.12 transitivePeerDependencies: @@ -11326,7 +11326,7 @@ snapshots: '@emotion/use-insertion-effect-with-fallbacks@1.1.0(react@18.3.1)': dependencies: - react: 18.3.1 + react: 19.0.0 '@emotion/utils@1.4.0': {} @@ -11791,8 +11791,8 @@ snapshots: '@popperjs/core': 2.11.8 clsx: 2.1.1 prop-types: 15.8.1 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) optionalDependencies: '@types/react': 18.3.12 @@ -11813,7 +11813,7 @@ snapshots: next: 14.2.15(@babel/core@7.25.8)(@opentelemetry/api@1.8.0)(@playwright/test@1.44.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) nprogress: 0.2.0 prop-types: 15.8.1 - react: 18.3.1 + react: 19.0.0 optionalDependencies: '@types/react': 18.3.12 @@ -11900,8 +11900,8 @@ snapshots: '@mui/utils': 5.16.6(@types/react@18.3.12)(react@18.3.1) clsx: 2.1.1 prop-types: 15.8.1 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) optionalDependencies: '@emotion/react': 11.13.3(@types/react@18.3.12)(react@18.3.1) '@emotion/styled': 11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1) @@ -11917,8 +11917,8 @@ snapshots: '@mui/utils': 5.16.6(@types/react@18.3.12)(react@18.3.1) clsx: 2.1.1 prop-types: 15.8.1 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) optionalDependencies: '@emotion/react': 11.13.3(@types/react@18.3.12)(react@18.3.1) '@emotion/styled': 11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1) @@ -11947,10 +11947,10 @@ snapshots: clsx: 2.1.1 csstype: 3.1.3 prop-types: 15.8.1 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-is: 18.3.1 - react-transition-group: 4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) + react-is: 19.0.0 + react-transition-group: 4.4.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0) optionalDependencies: '@emotion/react': 11.13.3(@types/react@18.3.12)(react@18.3.1) '@emotion/styled': 11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1) @@ -11975,7 +11975,7 @@ snapshots: '@babel/runtime': 7.25.7 '@mui/utils': 5.16.6(@types/react@18.3.12)(react@18.3.1) prop-types: 15.8.1 - react: 18.3.1 + react: 19.0.0 optionalDependencies: '@types/react': 18.3.12 @@ -11985,7 +11985,7 @@ snapshots: '@emotion/cache': 11.13.1 csstype: 3.1.3 prop-types: 15.8.1 - react: 18.3.1 + react: 19.0.0 optionalDependencies: '@emotion/react': 11.13.3(@types/react@18.3.12)(react@18.3.1) '@emotion/styled': 11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1) @@ -12009,7 +12009,7 @@ snapshots: jss-plugin-rule-value-function: 10.10.0 jss-plugin-vendor-prefixer: 10.10.0 prop-types: 15.8.1 - react: 18.3.1 + react: 19.0.0 optionalDependencies: '@types/react': 18.3.12 @@ -12023,7 +12023,7 @@ snapshots: clsx: 2.1.1 csstype: 3.1.3 prop-types: 15.8.1 - react: 18.3.1 + react: 19.0.0 optionalDependencies: '@emotion/react': 11.13.3(@types/react@18.3.12)(react@18.3.1) '@emotion/styled': 11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1) @@ -12040,8 +12040,8 @@ snapshots: '@types/prop-types': 15.7.13 clsx: 2.1.1 prop-types: 15.8.1 - react: 18.3.1 - react-is: 18.3.1 + react: 19.0.0 + react-is: 19.0.0 optionalDependencies: '@types/react': 18.3.12 @@ -12586,37 +12586,37 @@ snapshots: '@popperjs/core@2.11.8': {} - '@react-spring/animated@9.7.5(react@18.3.1)': + '@react-spring/animated@9.7.5(react@19.0.0)': dependencies: - '@react-spring/shared': 9.7.5(react@18.3.1) + '@react-spring/shared': 9.7.5(react@19.0.0) '@react-spring/types': 9.7.5 - react: 18.3.1 + react: 19.0.0 - '@react-spring/core@9.7.5(react@18.3.1)': + '@react-spring/core@9.7.5(react@19.0.0)': dependencies: - '@react-spring/animated': 9.7.5(react@18.3.1) - '@react-spring/shared': 9.7.5(react@18.3.1) + '@react-spring/animated': 9.7.5(react@19.0.0) + '@react-spring/shared': 9.7.5(react@19.0.0) '@react-spring/types': 9.7.5 - react: 18.3.1 + react: 19.0.0 '@react-spring/rafz@9.7.5': {} - '@react-spring/shared@9.7.5(react@18.3.1)': + '@react-spring/shared@9.7.5(react@19.0.0)': dependencies: '@react-spring/rafz': 9.7.5 '@react-spring/types': 9.7.5 - react: 18.3.1 + react: 19.0.0 '@react-spring/types@9.7.5': {} - '@react-spring/web@9.7.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@react-spring/web@9.7.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': dependencies: - '@react-spring/animated': 9.7.5(react@18.3.1) - '@react-spring/core': 9.7.5(react@18.3.1) - '@react-spring/shared': 9.7.5(react@18.3.1) + '@react-spring/animated': 9.7.5(react@19.0.0) + '@react-spring/core': 9.7.5(react@19.0.0) + '@react-spring/shared': 9.7.5(react@19.0.0) '@react-spring/types': 9.7.5 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) '@remix-run/router@1.20.0': {} @@ -12881,8 +12881,8 @@ snapshots: dependencies: '@babel/runtime': 7.25.7 '@testing-library/dom': 10.4.0 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) optionalDependencies: '@types/react': 18.3.12 '@types/react-dom': 18.3.1 @@ -16112,7 +16112,7 @@ snapshots: hoist-non-react-statics@3.3.2: dependencies: - react-is: 18.3.1 + react-is: 19.0.0 homedir-polyfill@1.0.3: dependencies: @@ -17262,7 +17262,7 @@ snapshots: markdown-to-jsx@7.5.0(react@18.3.1): dependencies: - react: 18.3.1 + react: 19.0.0 markdownlint-cli2-formatter-default@0.0.5(markdownlint-cli2@0.14.0): dependencies: @@ -18421,13 +18421,13 @@ snapshots: dependencies: ansi-regex: 5.0.1 ansi-styles: 5.2.0 - react-is: 18.3.1 + react-is: 19.0.0 pretty-format@29.7.0: dependencies: '@jest/schemas': 29.6.3 ansi-styles: 5.2.0 - react-is: 18.3.1 + react-is: 19.0.0 pretty-ms@9.0.0: dependencies: @@ -18484,7 +18484,7 @@ snapshots: dependencies: loose-envify: 1.4.0 object-assign: 4.1.1 - react-is: 18.3.1 + react-is: 19.0.0 protocols@2.0.1: {} @@ -18563,17 +18563,16 @@ snapshots: transitivePeerDependencies: - supports-color - react-dom@18.3.1(react@18.3.1): + react-dom@19.0.0(react@19.0.0): dependencies: - loose-envify: 1.4.0 - react: 18.3.1 - scheduler: 0.23.2 + react: 19.0.0 + scheduler: 0.25.0 react-hook-form@7.53.0(react@18.3.1): dependencies: - react: 18.3.1 + react: 19.0.0 - react-is@18.3.1: {} + react-is@19.0.0: {} react-refresh@0.14.2: {} @@ -18589,29 +18588,27 @@ snapshots: '@remix-run/router': 1.20.0 react: 18.3.1 - react-runner@1.0.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + react-runner@1.0.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0): dependencies: - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) sucrase: 3.35.0 - react-simple-code-editor@0.14.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + react-simple-code-editor@0.14.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0): dependencies: - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) - react-transition-group@4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + react-transition-group@4.4.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0): dependencies: '@babel/runtime': 7.25.7 dom-helpers: 5.2.1 loose-envify: 1.4.0 prop-types: 15.8.1 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) - react@18.3.1: - dependencies: - loose-envify: 1.4.0 + react@19.0.0: {} read-cmd-shim@4.0.0: {} @@ -18950,9 +18947,7 @@ snapshots: dependencies: xmlchars: 2.2.0 - scheduler@0.23.2: - dependencies: - loose-envify: 1.4.0 + scheduler@0.25.0: {} schema-utils@3.3.0: dependencies: @@ -19385,7 +19380,7 @@ snapshots: minimist: 1.2.8 through: 2.3.8 - styled-components@6.1.13(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + styled-components@6.1.13(react-dom@19.0.0(react@19.0.0))(react@19.0.0): dependencies: '@emotion/is-prop-valid': 1.2.2 '@emotion/unitless': 0.8.1 @@ -19393,8 +19388,8 @@ snapshots: css-to-react-native: 3.2.0 csstype: 3.1.3 postcss: 8.4.38 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) shallowequal: 1.1.0 stylis: 4.3.2 tslib: 2.6.2 @@ -19402,7 +19397,7 @@ snapshots: styled-jsx@5.1.1(@babel/core@7.25.8)(babel-plugin-macros@3.1.0)(react@18.3.1): dependencies: client-only: 0.0.1 - react: 18.3.1 + react: 19.0.0 optionalDependencies: '@babel/core': 7.25.8 babel-plugin-macros: 3.1.0 diff --git a/test/package.json b/test/package.json index bfdebd1b08fdf..98aa6f0b05dc7 100644 --- a/test/package.json +++ b/test/package.json @@ -9,7 +9,7 @@ "@babel/runtime": "^7.25.7", "@emotion/cache": "^11.13.1", "@emotion/react": "^11.13.3", - "@mui/material": "^5.16.7", + "@mui/material": "^5.16.13", "@mui/x-charts": "workspace:*", "@mui/x-charts-pro": "workspace:*", "@mui/x-charts-vendor": "workspace:*", @@ -24,15 +24,15 @@ "@types/karma": "^6.3.8", "@types/moment-jalaali": "^0.7.9", "@types/prop-types": "^15.7.13", - "@types/react": "^18.3.12", + "@types/react": "^19.0.2", "@types/semver": "^7.5.8", "chai": "^4.5.0", "dayjs": "^1.11.13", "moment": "^2.30.1", "moment-jalaali": "^0.10.1", "prop-types": "^15.8.1", - "react": "^18.3.1", - "react-dom": "^18.3.1", + "react": "^19.0.0", + "react-dom": "^19.0.0", "react-router-dom": "^6.27.0", "semver": "^7.6.3", "stylis": "^4.3.4", diff --git a/test/performance-charts/package.json b/test/performance-charts/package.json index fe5e946b99811..7e0f57427ff03 100644 --- a/test/performance-charts/package.json +++ b/test/performance-charts/package.json @@ -18,8 +18,8 @@ "@vitejs/plugin-react-swc": "^3.7.1", "@vitest/ui": "2.1.2", "jsdom": "^24.1.3", - "react": "^18.3.1", - "react-dom": "^18.3.1", + "react": "^19.0.0", + "react-dom": "^19.0.0", "vitest": "2.1.2" } } diff --git a/test/tsconfig.json b/test/tsconfig.json index 49092d4a09070..28bcc756d16e2 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -9,7 +9,8 @@ "dayjs/plugin/utc.d.ts", "mocha", "moment-timezone" - ] + ], + "skipLibCheck": true }, "include": ["e2e/**/*", "e2e-website/**/*", "regressions/**/*"], "exclude": ["regressions/build/**/*", "regressions/screenshots/**/*"] diff --git a/test/utils/describeConformance.ts b/test/utils/describeConformance.ts index 85129ca7a1714..676226a48cd66 100644 --- a/test/utils/describeConformance.ts +++ b/test/utils/describeConformance.ts @@ -5,7 +5,7 @@ import { import { ThemeProvider, createTheme } from '@mui/material/styles'; export function describeConformance( - minimalElement: React.ReactElement, + minimalElement: React.ReactElement, getOptions: () => ConformanceOptions, ) { function getOptionsWithDefaults() { diff --git a/test/utils/describeSlotsConformance.tsx b/test/utils/describeSlotsConformance.tsx index 0d638bfa8fb08..b596722026360 100644 --- a/test/utils/describeSlotsConformance.tsx +++ b/test/utils/describeSlotsConformance.tsx @@ -5,7 +5,7 @@ import { MuiRenderResult } from '@mui/internal-test-utils/createRenderer'; interface DescribeSlotsConformanceParams { getElement: (params: { slotName: string; props: any }) => React.ReactElement; - render: (node: React.ReactElement) => MuiRenderResult; + render: (node: React.ReactElement) => MuiRenderResult; slots: { [slotName: string]: { className: string } }; } diff --git a/test/utils/helperFn.ts b/test/utils/helperFn.ts index 068d37943e5d3..7d56f6d752be4 100644 --- a/test/utils/helperFn.ts +++ b/test/utils/helperFn.ts @@ -140,9 +140,7 @@ export function getColumnHeaderCell(colIndex: number, rowIndex?: number): HTMLEl } export function getColumnHeadersTextContent() { - return Array.from(document.querySelectorAll('[role="columnheader"]')).map( - (node) => node!.textContent, - ); + return screen.queryAllByRole('columnheader').map((node) => node!.textContent); } export function getRowsFieldContent(field: string) { diff --git a/test/utils/pickers/createPickerRenderer.tsx b/test/utils/pickers/createPickerRenderer.tsx index 25da543cf517d..9a353651b344e 100644 --- a/test/utils/pickers/createPickerRenderer.tsx +++ b/test/utils/pickers/createPickerRenderer.tsx @@ -46,7 +46,7 @@ export function createPickerRenderer({ return { clock, - render(node: React.ReactElement, options?: Omit) { + render(node: React.ReactElement, options?: Omit) { return clientRender(node, { ...options, wrapper: Wrapper }); }, adapter, diff --git a/test/utils/pickers/describePicker/describePicker.types.ts b/test/utils/pickers/describePicker/describePicker.types.ts index 342ec13c02cc8..08ac8e3247634 100644 --- a/test/utils/pickers/describePicker/describePicker.types.ts +++ b/test/utils/pickers/describePicker/describePicker.types.ts @@ -5,5 +5,5 @@ export interface DescribePickerOptions { fieldType: 'single-input' | 'multi-input'; variant: 'mobile' | 'desktop' | 'static'; hasNoView?: boolean; - render: (node: React.ReactElement) => MuiRenderResult; + render: (node: React.ReactElement) => MuiRenderResult; } diff --git a/test/utils/pickers/describeValidation/describeValidation.types.ts b/test/utils/pickers/describeValidation/describeValidation.types.ts index 66d1f7720def2..68f894ae312bc 100644 --- a/test/utils/pickers/describeValidation/describeValidation.types.ts +++ b/test/utils/pickers/describeValidation/describeValidation.types.ts @@ -4,7 +4,7 @@ import { DateOrTimeView } from '@mui/x-date-pickers/models'; import { PickerComponentFamily } from '../describe.types'; export interface DescribeValidationInputOptions { - render: (node: React.ReactElement) => MuiRenderResult; + render: (node: React.ReactElement) => MuiRenderResult; // TODO: Export `Clock` from monorepo clock: ReturnType['clock']; after?: () => void; diff --git a/test/utils/pickers/describeValue/describeValue.types.ts b/test/utils/pickers/describeValue/describeValue.types.ts index 27332ec2b7192..dfea89df71394 100644 --- a/test/utils/pickers/describeValue/describeValue.types.ts +++ b/test/utils/pickers/describeValue/describeValue.types.ts @@ -10,7 +10,7 @@ import { PickerComponentFamily } from '../describe.types'; interface DescribeValueBaseOptions { componentFamily: C; - render: (node: React.ReactElement) => MuiRenderResult; + render: (node: React.ReactElement) => MuiRenderResult; assertRenderedValue: (expectedValue: TValue) => void; values: [TValue, TValue]; emptyValue: TValue; diff --git a/test/utils/pickers/fields.tsx b/test/utils/pickers/fields.tsx index 7fbed5eda3d81..744e9bdbce64e 100644 --- a/test/utils/pickers/fields.tsx +++ b/test/utils/pickers/fields.tsx @@ -88,7 +88,7 @@ export const buildFieldInteractions =

({ props, { hook, componentFamily = 'field', direction = 'ltr' } = {}, ) => { - let fieldRef: React.RefObject> = { current: null }; + let fieldRef: React.RefObject | null> = { current: null }; function WrappedComponent(propsFromRender: any) { fieldRef = React.useRef>(null); diff --git a/test/utils/tree-view/describeTreeView/describeTreeView.types.ts b/test/utils/tree-view/describeTreeView/describeTreeView.types.ts index b470f885df767..e64f78b0fd2b9 100644 --- a/test/utils/tree-view/describeTreeView/describeTreeView.types.ts +++ b/test/utils/tree-view/describeTreeView/describeTreeView.types.ts @@ -139,7 +139,7 @@ export type DescribeTreeViewRenderer DescribeTreeViewRendererReturnValue; export type DescribeTreeViewJSXRenderer = ( - element: React.ReactElement, + element: React.ReactElement, ) => DescribeTreeViewRendererUtils; type TreeViewComponentName = 'RichTreeView' | 'RichTreeViewPro' | 'SimpleTreeView';