From 97afd65d2338b42982923771dc647e20e4d6676a Mon Sep 17 00:00:00 2001 From: Jose C Quintas Jr Date: Wed, 28 Aug 2024 12:52:13 +0200 Subject: [PATCH 1/9] [charts] Fix `LineChart` transition stopping before completion (#14366) --- .../x-charts/src/LineChart/MarkElement.tsx | 2 +- .../x-charts/src/internals/useAnimatedPath.ts | 45 ++++++++++++------- 2 files changed, 30 insertions(+), 17 deletions(-) diff --git a/packages/x-charts/src/LineChart/MarkElement.tsx b/packages/x-charts/src/LineChart/MarkElement.tsx index 137f44f252b7..b86ef162168d 100644 --- a/packages/x-charts/src/LineChart/MarkElement.tsx +++ b/packages/x-charts/src/LineChart/MarkElement.tsx @@ -107,7 +107,7 @@ function MarkElement(props: MarkElementProps) { }); const { axis } = React.useContext(InteractionContext); - const position = useSpring({ x, y, immediate: skipAnimation }); + const position = useSpring({ to: { x, y }, immediate: skipAnimation }); const ownerState = { id, classes: innerClasses, diff --git a/packages/x-charts/src/internals/useAnimatedPath.ts b/packages/x-charts/src/internals/useAnimatedPath.ts index 9f29447fe138..03b0470b0db0 100644 --- a/packages/x-charts/src/internals/useAnimatedPath.ts +++ b/packages/x-charts/src/internals/useAnimatedPath.ts @@ -1,29 +1,42 @@ import * as React from 'react'; import { interpolateString } from '@mui/x-charts-vendor/d3-interpolate'; -import { useSpring, to } from '@react-spring/web'; +import { useSpring } from '@react-spring/web'; function usePrevious(value: T) { - const ref = React.useRef(null); - React.useEffect(() => { - ref.current = value; - }, [value]); + const ref = React.useRef<{ currentPath: T; previousPath?: T }>({ + currentPath: value, + previousPath: undefined, + }); + if (ref.current.currentPath !== value) { + ref.current = { + currentPath: value, + previousPath: ref.current.currentPath, + }; + } + return ref.current; } -// Taken from Nivo export const useAnimatedPath = (path: string, skipAnimation?: boolean) => { - const previousPath = usePrevious(path); + const memoryRef = usePrevious(path); + const interpolator = React.useMemo( - () => (previousPath ? interpolateString(previousPath, path) : () => path), - [previousPath, path], + () => + memoryRef.previousPath + ? interpolateString(memoryRef.previousPath, memoryRef.currentPath) + : () => memoryRef.currentPath, + [memoryRef.currentPath, memoryRef.previousPath], ); - const { value } = useSpring({ - from: { value: 0 }, - to: { value: 1 }, - reset: true, - immediate: skipAnimation, - }); + const [{ value }] = useSpring( + { + from: { value: 0 }, + to: { value: 1 }, + reset: true, + immediate: skipAnimation, + }, + [memoryRef.currentPath], + ); - return to([value], interpolator); + return value.to(interpolator); }; From 113a61207d8afa836bce60a3a2c002d38cec0e9c Mon Sep 17 00:00:00 2001 From: Olivier Tassinari Date: Wed, 28 Aug 2024 23:47:03 +0200 Subject: [PATCH 2/9] [infra] Fix Issue cleanup action A follow-up on https://github.com/mui/mui-x/pull/13957#discussion_r1718833226 --- scripts/githubActions/orderIdValidation.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/githubActions/orderIdValidation.js b/scripts/githubActions/orderIdValidation.js index 1acc23cc1d00..c98fea6e9722 100644 --- a/scripts/githubActions/orderIdValidation.js +++ b/scripts/githubActions/orderIdValidation.js @@ -22,11 +22,15 @@ module.exports = async ({ core, context, github }) => { } else { const order = await fetch(`${orderApi}${orderId}`, { headers: { - Authorization: orderApiToken, + Authorization: `Basic ${orderApiToken}`, 'User-Agent': 'MUI-Tools-Private/X-Orders-Inspector v1', }, }); + if (!order.ok) { + core.info(`Request to ${orderApi} failed. Response status code: ${order.status}.`); + } + const orderDetails = await order.json(); core.debug(`>>> Order Items: ${orderDetails.line_items?.join(',')}`); From 1a23942b90f1b46fafc82c8db78c873d9f4bbae1 Mon Sep 17 00:00:00 2001 From: Alexandre Fauquette <45398769+alexfauquette@users.noreply.github.com> Date: Thu, 29 Aug 2024 10:11:56 +0200 Subject: [PATCH 3/9] [charts] Keep axis root classe usage explicit (#14378) --- .../src/internals/components/AxisSharedComponents.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/x-charts/src/internals/components/AxisSharedComponents.tsx b/packages/x-charts/src/internals/components/AxisSharedComponents.tsx index 5fb7076d5455..ba6078ebe23b 100644 --- a/packages/x-charts/src/internals/components/AxisSharedComponents.tsx +++ b/packages/x-charts/src/internals/components/AxisSharedComponents.tsx @@ -6,21 +6,21 @@ export const AxisRoot = styled('g', { slot: 'Root', overridesResolver: (props, styles) => styles.root, })(({ theme }) => ({ - [`.${axisClasses.tickLabel}`]: { + [`& .${axisClasses.tickLabel}`]: { ...theme.typography.caption, fill: (theme.vars || theme).palette.text.primary, }, - [`.${axisClasses.label}`]: { + [`& .${axisClasses.label}`]: { ...theme.typography.body1, fill: (theme.vars || theme).palette.text.primary, }, - [`.${axisClasses.line}`]: { + [`& .${axisClasses.line}`]: { stroke: (theme.vars || theme).palette.text.primary, shapeRendering: 'crispEdges', strokeWidth: 1, }, - [`.${axisClasses.tick}`]: { + [`& .${axisClasses.tick}`]: { stroke: (theme.vars || theme).palette.text.primary, shapeRendering: 'crispEdges', }, From a8794b65f7dfcc862aa93fcf8f1529506444da6f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 29 Aug 2024 11:31:43 +0300 Subject: [PATCH 4/9] Bump @mui/monorepo digest to 029eb3b (#14316) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Lukas --- docs/.link-check-errors.txt | 3 --- package.json | 2 +- pnpm-lock.yaml | 12 ++++++------ 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/docs/.link-check-errors.txt b/docs/.link-check-errors.txt index cbb0918c2363..6ecc503cc78a 100644 --- a/docs/.link-check-errors.txt +++ b/docs/.link-check-errors.txt @@ -1,5 +1,2 @@ Broken links found by `docs:link-check` that exist: -- https://mui.com/material-ui/customization/theme-components/#creating-new-component-variants -- https://mui.com/material-ui/customization/theme-components/#overrides-based-on-props -- https://mui.com/material-ui/react-grid2/#whats-changed diff --git a/package.json b/package.json index 802da58f6c93..db70f91832aa 100644 --- a/package.json +++ b/package.json @@ -92,7 +92,7 @@ "@mui/internal-markdown": "^1.0.11", "@mui/internal-test-utils": "^1.0.10", "@mui/material": "^5.16.7", - "@mui/monorepo": "github:mui/material-ui#55bea65c83c1beac77382fe961f8aa72eec21daa", + "@mui/monorepo": "github:mui/material-ui#029eb3b1f4837591e729779da9a82f0a66187770", "@mui/utils": "^5.16.6", "@next/eslint-plugin-next": "14.2.6", "@octokit/plugin-retry": "^7.1.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 91a7006a09dc..3150f4133589 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -96,8 +96,8 @@ importers: specifier: ^5.16.7 version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mui/monorepo': - specifier: github:mui/material-ui#55bea65c83c1beac77382fe961f8aa72eec21daa - version: https://codeload.github.com/mui/material-ui/tar.gz/55bea65c83c1beac77382fe961f8aa72eec21daa(encoding@0.1.13) + specifier: github:mui/material-ui#029eb3b1f4837591e729779da9a82f0a66187770 + version: https://codeload.github.com/mui/material-ui/tar.gz/029eb3b1f4837591e729779da9a82f0a66187770(encoding@0.1.13) '@mui/utils': specifier: ^5.16.6 version: 5.16.6(@types/react@18.3.4)(react@18.3.1) @@ -3168,9 +3168,9 @@ packages: '@types/react': optional: true - '@mui/monorepo@https://codeload.github.com/mui/material-ui/tar.gz/55bea65c83c1beac77382fe961f8aa72eec21daa': - resolution: {tarball: https://codeload.github.com/mui/material-ui/tar.gz/55bea65c83c1beac77382fe961f8aa72eec21daa} - version: 6.0.0-rc.0 + '@mui/monorepo@https://codeload.github.com/mui/material-ui/tar.gz/029eb3b1f4837591e729779da9a82f0a66187770': + resolution: {tarball: https://codeload.github.com/mui/material-ui/tar.gz/029eb3b1f4837591e729779da9a82f0a66187770} + version: 6.0.0 engines: {pnpm: 9.7.1} '@mui/private-theming@5.16.6': @@ -11985,7 +11985,7 @@ snapshots: '@emotion/styled': 11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1) '@types/react': 18.3.4 - '@mui/monorepo@https://codeload.github.com/mui/material-ui/tar.gz/55bea65c83c1beac77382fe961f8aa72eec21daa(encoding@0.1.13)': + '@mui/monorepo@https://codeload.github.com/mui/material-ui/tar.gz/029eb3b1f4837591e729779da9a82f0a66187770(encoding@0.1.13)': dependencies: '@googleapis/sheets': 9.3.0(encoding@0.1.13) '@netlify/functions': 2.8.1 From bba14d0445743768568ca501e6579723283e9eb1 Mon Sep 17 00:00:00 2001 From: Lukas Tyla Date: Thu, 29 Aug 2024 11:57:38 +0300 Subject: [PATCH 5/9] [core] Use `useRtl` instead of `useTheme` to access direction (#14359) --- .../ChartsLegend/ContinuousColorLegend.tsx | 6 +-- .../src/ChartsLegend/LegendPerItem.tsx | 9 ++-- .../x-charts/src/ChartsYAxis/ChartsYAxis.tsx | 5 +- packages/x-charts/src/PieChart/PieChart.tsx | 8 +-- packages/x-charts/src/internals/useIsRTL.ts | 6 --- .../components/GridColumnMenuPinningItem.tsx | 6 +-- .../columnReorder/useGridColumnReorder.tsx | 14 ++--- .../src/components/cell/GridActionsCell.tsx | 6 +-- .../src/hooks/core/gridCoreSelector.ts | 2 +- .../src/hooks/core/useGridInitialization.ts | 4 +- .../src/hooks/core/useGridIsRtl.tsx | 20 ++++++++ .../src/hooks/core/useGridTheme.tsx | 20 -------- .../columnHeaders/useGridColumnHeaders.tsx | 7 +-- .../columnResize/useGridColumnResize.tsx | 10 ++-- .../features/columns/gridColumnsSelector.ts | 12 ++--- .../useGridKeyboardNavigation.ts | 51 ++++++++----------- .../hooks/features/scroll/useGridScroll.ts | 8 +-- .../virtualization/useGridVirtualScroller.tsx | 26 +++++----- .../src/models/gridStateCommunity.ts | 3 +- 19 files changed, 101 insertions(+), 122 deletions(-) delete mode 100644 packages/x-charts/src/internals/useIsRTL.ts create mode 100644 packages/x-data-grid/src/hooks/core/useGridIsRtl.tsx delete mode 100644 packages/x-data-grid/src/hooks/core/useGridTheme.tsx diff --git a/packages/x-charts/src/ChartsLegend/ContinuousColorLegend.tsx b/packages/x-charts/src/ChartsLegend/ContinuousColorLegend.tsx index d331e317f945..00880553da64 100644 --- a/packages/x-charts/src/ChartsLegend/ContinuousColorLegend.tsx +++ b/packages/x-charts/src/ChartsLegend/ContinuousColorLegend.tsx @@ -2,6 +2,7 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import { ScaleSequential } from '@mui/x-charts-vendor/d3-scale'; import { useTheme } from '@mui/material/styles'; +import { useRtl } from '@mui/system/RtlProvider'; import ChartsContinuousGradient from '../internals/components/ChartsAxesGradients/ChartsContinuousGradient'; import { AxisDefaultized, ContinuousScaleName } from '../models/axis'; import { useChartId, useDrawingArea } from '../hooks'; @@ -205,6 +206,7 @@ const defaultLabelFormatter: LabelFormatter = ({ formattedValue }) => formattedV function ContinuousColorLegend(props: ContinuousColorLegendProps) { const theme = useTheme(); + const isRtl = useRtl(); const { id: idProp, minLabel = defaultLabelFormatter, @@ -224,8 +226,6 @@ function ContinuousColorLegend(props: ContinuousColorLegendProps) { const chartId = useChartId(); const id = idProp ?? `gradient-legend-${chartId}`; - const isRTL = theme.direction === 'rtl'; - const axisItem = useAxis({ axisDirection, axisId }); const { width, height, left, right, top, bottom } = useDrawingArea(); @@ -277,7 +277,7 @@ function ContinuousColorLegend(props: ContinuousColorLegendProps) { // Place bar and texts const barBox = - direction === 'column' || (isRTL && direction === 'row') + direction === 'column' || (isRtl && direction === 'row') ? { width: thickness, height: size } : { width: size, height: thickness }; diff --git a/packages/x-charts/src/ChartsLegend/LegendPerItem.tsx b/packages/x-charts/src/ChartsLegend/LegendPerItem.tsx index dd61aeb4e9f8..da5ef97569b5 100644 --- a/packages/x-charts/src/ChartsLegend/LegendPerItem.tsx +++ b/packages/x-charts/src/ChartsLegend/LegendPerItem.tsx @@ -1,6 +1,7 @@ import * as React from 'react'; import NoSsr from '@mui/material/NoSsr'; import { useTheme, styled } from '@mui/material/styles'; +import { useRtl } from '@mui/system/RtlProvider'; import { DrawingArea } from '../context/DrawingProvider'; import { DefaultizedProps } from '../models/helpers'; import { ChartsText, ChartsTextStyle } from '../ChartsText'; @@ -111,7 +112,7 @@ export function LegendPerItem(props: LegendPerItemProps) { labelStyle: inLabelStyle, } = props; const theme = useTheme(); - const isRTL = theme.direction === 'rtl'; + const isRtl = useRtl(); const drawingArea = useDrawingArea(); const labelStyle = React.useMemo( @@ -200,11 +201,11 @@ export function LegendPerItem(props: LegendPerItemProps) { diff --git a/packages/x-charts/src/ChartsYAxis/ChartsYAxis.tsx b/packages/x-charts/src/ChartsYAxis/ChartsYAxis.tsx index 281ce8d1b3d2..a26a6b4f67d8 100644 --- a/packages/x-charts/src/ChartsYAxis/ChartsYAxis.tsx +++ b/packages/x-charts/src/ChartsYAxis/ChartsYAxis.tsx @@ -3,6 +3,7 @@ import PropTypes from 'prop-types'; import useSlotProps from '@mui/utils/useSlotProps'; import composeClasses from '@mui/utils/composeClasses'; import { useThemeProps, useTheme, Theme } from '@mui/material/styles'; +import { useRtl } from '@mui/system/RtlProvider'; import { useCartesianContext } from '../context/CartesianProvider'; import { useTicks } from '../hooks/useTicks'; import { useDrawingArea } from '../hooks/useDrawingArea'; @@ -77,7 +78,7 @@ function ChartsYAxis(inProps: ChartsYAxisProps) { } = defaultizedProps; const theme = useTheme(); - const isRTL = theme.direction === 'rtl'; + const isRtl = useRtl(); const classes = useUtilityClasses({ ...defaultizedProps, theme }); @@ -106,7 +107,7 @@ function ChartsYAxis(inProps: ChartsYAxisProps) { const TickLabel = slots?.axisTickLabel ?? ChartsText; const Label = slots?.axisLabel ?? ChartsText; - const revertAnchor = (!isRTL && position === 'right') || (isRTL && position !== 'right'); + const revertAnchor = (!isRtl && position === 'right') || (isRtl && position !== 'right'); const axisTickLabelProps = useSlotProps({ elementType: TickLabel, externalSlotProps: slotProps?.axisTickLabel, diff --git a/packages/x-charts/src/PieChart/PieChart.tsx b/packages/x-charts/src/PieChart/PieChart.tsx index dca99305017f..51fe9e0d87a3 100644 --- a/packages/x-charts/src/PieChart/PieChart.tsx +++ b/packages/x-charts/src/PieChart/PieChart.tsx @@ -1,5 +1,6 @@ import * as React from 'react'; import PropTypes from 'prop-types'; +import { useRtl } from '@mui/system/RtlProvider'; import { useThemeProps } from '@mui/material/styles'; import { ResponsiveChartContainer, @@ -30,7 +31,6 @@ import { ChartsXAxisProps, ChartsYAxisProps, } from '../models/axis'; -import { useIsRTL } from '../internals/useIsRTL'; import { ChartsOverlay, ChartsOverlayProps, @@ -153,12 +153,12 @@ const PieChart = React.forwardRef(function PieChart(inProps: PieChartProps, ref) className, ...other } = props; - const isRTL = useIsRTL(); + const isRtl = useRtl(); - const margin = { ...(isRTL ? defaultRTLMargin : defaultMargin), ...marginProps }; + const margin = { ...(isRtl ? defaultRTLMargin : defaultMargin), ...marginProps }; const legend: ChartsLegendProps = { direction: 'column', - position: { vertical: 'middle', horizontal: isRTL ? 'left' : 'right' }, + position: { vertical: 'middle', horizontal: isRtl ? 'left' : 'right' }, ...legendProps, }; diff --git a/packages/x-charts/src/internals/useIsRTL.ts b/packages/x-charts/src/internals/useIsRTL.ts deleted file mode 100644 index 21e7f0fe692d..000000000000 --- a/packages/x-charts/src/internals/useIsRTL.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { useTheme } from '@mui/material/styles'; - -export const useIsRTL = () => { - const theme = useTheme(); - return theme.direction === 'rtl'; -}; diff --git a/packages/x-data-grid-pro/src/components/GridColumnMenuPinningItem.tsx b/packages/x-data-grid-pro/src/components/GridColumnMenuPinningItem.tsx index 743fcb3fc341..0a07624dc306 100644 --- a/packages/x-data-grid-pro/src/components/GridColumnMenuPinningItem.tsx +++ b/packages/x-data-grid-pro/src/components/GridColumnMenuPinningItem.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { useTheme } from '@mui/material/styles'; +import { useRtl } from '@mui/system/RtlProvider'; import PropTypes from 'prop-types'; import MenuItem from '@mui/material/MenuItem'; import ListItemIcon from '@mui/material/ListItemIcon'; @@ -12,7 +12,7 @@ function GridColumnMenuPinningItem(props: GridColumnMenuItemProps) { const { colDef, onClick } = props; const apiRef = useGridApiContext(); const rootProps = useGridRootProps(); - const theme = useTheme(); + const isRtl = useRtl(); const pinColumn = React.useCallback( (side: GridPinnedColumnPosition) => (event: React.MouseEvent) => { @@ -76,7 +76,7 @@ function GridColumnMenuPinningItem(props: GridColumnMenuItemProps) { ); } - if (theme.direction === 'rtl') { + if (isRtl) { return ( {pinToRightMenuItem} 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 e882e42ea10a..9f47e47ab497 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 @@ -1,6 +1,6 @@ import * as React from 'react'; import composeClasses from '@mui/utils/composeClasses'; -import { useTheme } from '@mui/material/styles'; +import { useRtl } from '@mui/system/RtlProvider'; import { CursorCoordinates, useGridApiEventHandler, @@ -75,7 +75,7 @@ export const useGridColumnReorder = ( const removeDnDStylesTimeout = React.useRef>(); const ownerState = { classes: props.classes }; const classes = useUtilityClasses(ownerState); - const theme = useTheme(); + const isRtl = useRtl(); React.useEffect(() => { return () => { @@ -219,14 +219,10 @@ export const useGridColumnReorder = ( const cursorMoveDirectionX = getCursorMoveDirectionX(cursorPosition.current, coordinates); const hasMovedLeft = cursorMoveDirectionX === CURSOR_MOVE_DIRECTION_LEFT && - (theme.direction === 'rtl' - ? dragColIndex < targetColIndex - : targetColIndex < dragColIndex); + (isRtl ? dragColIndex < targetColIndex : targetColIndex < dragColIndex); const hasMovedRight = cursorMoveDirectionX === CURSOR_MOVE_DIRECTION_RIGHT && - (theme.direction === 'rtl' - ? targetColIndex < dragColIndex - : dragColIndex < targetColIndex); + (isRtl ? targetColIndex < dragColIndex : dragColIndex < targetColIndex); if (hasMovedLeft || hasMovedRight) { let canBeReordered: boolean; @@ -298,7 +294,7 @@ export const useGridColumnReorder = ( cursorPosition.current = coordinates; } }, - [apiRef, logger, theme.direction], + [apiRef, logger, isRtl], ); const handleDragEnd = React.useCallback>( diff --git a/packages/x-data-grid/src/components/cell/GridActionsCell.tsx b/packages/x-data-grid/src/components/cell/GridActionsCell.tsx index 2abc7adc0e45..39c20b5c639e 100644 --- a/packages/x-data-grid/src/components/cell/GridActionsCell.tsx +++ b/packages/x-data-grid/src/components/cell/GridActionsCell.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import MenuList from '@mui/material/MenuList'; -import { useTheme } from '@mui/material/styles'; +import { useRtl } from '@mui/system/RtlProvider'; import { unstable_useId as useId } from '@mui/utils'; import { GridRenderCellParams } from '../../models/params/gridCellParams'; import { gridClasses } from '../../constants/gridClasses'; @@ -47,7 +47,7 @@ function GridActionsCell(props: GridActionsCellProps) { const buttonRef = React.useRef(null); const ignoreCallToFocus = React.useRef(false); const touchRippleRefs = React.useRef>({}); - const theme = useTheme(); + const isRtl = useRtl(); const menuId = useId(); const buttonId = useId(); const rootProps = useGridRootProps(); @@ -149,7 +149,7 @@ function GridActionsCell(props: GridActionsCellProps) { } // for rtl mode we need to reverse the direction - const rtlMod = theme.direction === 'rtl' ? -1 : 1; + const rtlMod = isRtl ? -1 : 1; const indexMod = (direction === 'left' ? -1 : 1) * rtlMod; // if the button that should receive focus is disabled go one more step diff --git a/packages/x-data-grid/src/hooks/core/gridCoreSelector.ts b/packages/x-data-grid/src/hooks/core/gridCoreSelector.ts index b48fbbb0d2a0..3ec68fdafab0 100644 --- a/packages/x-data-grid/src/hooks/core/gridCoreSelector.ts +++ b/packages/x-data-grid/src/hooks/core/gridCoreSelector.ts @@ -4,4 +4,4 @@ import { GridStateCommunity } from '../../models/gridStateCommunity'; * Get the theme state * @category Core */ -export const gridThemeSelector = (state: GridStateCommunity) => state.theme; +export const gridIsRtlSelector = (state: GridStateCommunity) => state.isRtl; diff --git a/packages/x-data-grid/src/hooks/core/useGridInitialization.ts b/packages/x-data-grid/src/hooks/core/useGridInitialization.ts index 104363f8ba80..d59852b43a54 100644 --- a/packages/x-data-grid/src/hooks/core/useGridInitialization.ts +++ b/packages/x-data-grid/src/hooks/core/useGridInitialization.ts @@ -2,7 +2,7 @@ import * as React from 'react'; import type { GridApiCommon, GridPrivateApiCommon } from '../../models/api/gridApiCommon'; import { DataGridProcessedProps } from '../../models/props/DataGridProps'; import { useGridRefs } from './useGridRefs'; -import { useGridTheme } from './useGridTheme'; +import { useGridIsRtl } from './useGridIsRtl'; import { useGridLoggerFactory } from './useGridLoggerFactory'; import { useGridApiInitialization } from './useGridApiInitialization'; import { useGridLocaleText } from './useGridLocaleText'; @@ -23,7 +23,7 @@ export const useGridInitialization = < const privateApiRef = useGridApiInitialization(inputApiRef, props); useGridRefs(privateApiRef); - useGridTheme(privateApiRef); + useGridIsRtl(privateApiRef); useGridLoggerFactory(privateApiRef, props); useGridStateInitialization(privateApiRef); useGridPipeProcessing(privateApiRef); diff --git a/packages/x-data-grid/src/hooks/core/useGridIsRtl.tsx b/packages/x-data-grid/src/hooks/core/useGridIsRtl.tsx new file mode 100644 index 000000000000..576952df12ca --- /dev/null +++ b/packages/x-data-grid/src/hooks/core/useGridIsRtl.tsx @@ -0,0 +1,20 @@ +import * as React from 'react'; +import { useRtl } from '@mui/system/RtlProvider'; +import { GridPrivateApiCommon } from '../../models/api/gridApiCommon'; + +export const useGridIsRtl = (apiRef: React.MutableRefObject): void => { + const isRtl = useRtl(); + + if (apiRef.current.state.isRtl === undefined) { + apiRef.current.state.isRtl = isRtl; + } + + const isFirstEffect = React.useRef(true); + React.useEffect(() => { + if (isFirstEffect.current) { + isFirstEffect.current = false; + } else { + apiRef.current.setState((state) => ({ ...state, isRtl })); + } + }, [apiRef, isRtl]); +}; diff --git a/packages/x-data-grid/src/hooks/core/useGridTheme.tsx b/packages/x-data-grid/src/hooks/core/useGridTheme.tsx deleted file mode 100644 index 9647f596bd28..000000000000 --- a/packages/x-data-grid/src/hooks/core/useGridTheme.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import * as React from 'react'; -import { useTheme } from '@mui/material/styles'; -import { GridPrivateApiCommon } from '../../models/api/gridApiCommon'; - -export const useGridTheme = (apiRef: React.MutableRefObject): void => { - const theme = useTheme(); - - if (!apiRef.current.state.theme) { - apiRef.current.state.theme = theme; - } - - const isFirstEffect = React.useRef(true); - React.useEffect(() => { - if (isFirstEffect.current) { - isFirstEffect.current = false; - } else { - apiRef.current.setState((state) => ({ ...state, theme })); - } - }, [apiRef, theme]); -}; diff --git a/packages/x-data-grid/src/hooks/features/columnHeaders/useGridColumnHeaders.tsx b/packages/x-data-grid/src/hooks/features/columnHeaders/useGridColumnHeaders.tsx index de3a72f4a844..6653bc4367ff 100644 --- a/packages/x-data-grid/src/hooks/features/columnHeaders/useGridColumnHeaders.tsx +++ b/packages/x-data-grid/src/hooks/features/columnHeaders/useGridColumnHeaders.tsx @@ -1,6 +1,7 @@ import * as React from 'react'; import clsx from 'clsx'; -import { styled, useTheme } from '@mui/material/styles'; +import { styled } from '@mui/material/styles'; +import { useRtl } from '@mui/system/RtlProvider'; import { DataGridProcessedProps } from '../../../models/props/DataGridProps'; import { useGridSelector } from '../../utils'; import { useGridRootProps } from '../../utils/useGridRootProps'; @@ -98,7 +99,7 @@ export const useGridColumnHeaders = (props: UseGridColumnHeadersProps) => { const [resizeCol, setResizeCol] = React.useState(''); const apiRef = useGridPrivateApiContext(); - const theme = useTheme(); + const isRtl = useRtl(); const rootProps = useGridRootProps(); const dimensions = useGridSelector(apiRef, gridDimensionsSelector); const hasVirtualization = useGridSelector(apiRef, gridVirtualizationColumnEnabledSelector); @@ -110,7 +111,7 @@ export const useGridColumnHeaders = (props: UseGridColumnHeadersProps) => { const offsetLeft = computeOffsetLeft( columnPositions, renderContext, - theme.direction, + isRtl, pinnedColumns.left.length, ); const gridHasFiller = dimensions.columnsTotalWidth < dimensions.viewportOuterSize.width; 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 6e4b3cc9573e..b087e8243b9e 100644 --- a/packages/x-data-grid/src/hooks/features/columnResize/useGridColumnResize.tsx +++ b/packages/x-data-grid/src/hooks/features/columnResize/useGridColumnResize.tsx @@ -4,7 +4,7 @@ import { unstable_useEventCallback as useEventCallback, } from '@mui/utils'; import useLazyRef from '@mui/utils/useLazyRef'; -import { useTheme, Direction } from '@mui/material/styles'; +import { useRtl } from '@mui/system/RtlProvider'; import { findGridCellElementsFromCol, findGridElement, @@ -112,11 +112,11 @@ function flipResizeDirection(side: ResizeDirection) { return 'Right'; } -function getResizeDirection(separator: HTMLElement, direction: Direction) { +function getResizeDirection(separator: HTMLElement, isRtl: boolean) { const side = separator.classList.contains(gridClasses['columnSeparator--sideRight']) ? 'Right' : 'Left'; - if (direction === 'rtl') { + if (isRtl) { // Resizing logic should be mirrored in the RTL case return flipResizeDirection(side); } @@ -280,7 +280,7 @@ export const useGridColumnResize = ( | 'onColumnWidthChange' >, ) => { - const theme = useTheme(); + const isRtl = useRtl(); const logger = useGridLogger(apiRef, 'useGridColumnResize'); const refs = useLazyRef(createResizeRefs).current; @@ -491,7 +491,7 @@ export const useGridColumnResize = ( ? [] : findRightPinnedHeadersBeforeCol(apiRef.current, refs.columnHeaderElement); - resizeDirection.current = getResizeDirection(separator, theme.direction); + resizeDirection.current = getResizeDirection(separator, isRtl); initialOffsetToSeparator.current = computeOffsetToSeparator( xStart, diff --git a/packages/x-data-grid/src/hooks/features/columns/gridColumnsSelector.ts b/packages/x-data-grid/src/hooks/features/columns/gridColumnsSelector.ts index c06920307eb8..f252388bc18f 100644 --- a/packages/x-data-grid/src/hooks/features/columns/gridColumnsSelector.ts +++ b/packages/x-data-grid/src/hooks/features/columns/gridColumnsSelector.ts @@ -5,7 +5,7 @@ import { GridPinnedColumnFields, EMPTY_PINNED_COLUMN_FIELDS, } from './gridColumnsInterfaces'; -import { gridThemeSelector } from '../../core/gridCoreSelector'; +import { gridIsRtlSelector } from '../../core/gridCoreSelector'; /** * Get the columns state @@ -85,13 +85,9 @@ export const gridVisiblePinnedColumnDefinitionsSelector = createSelectorMemoized gridColumnsStateSelector, gridPinnedColumnsSelector, gridVisibleColumnFieldsSelector, - gridThemeSelector, - (columnsState, model, visibleColumnFields, theme) => { - const visiblePinnedFields = filterVisibleColumns( - model, - visibleColumnFields, - theme.direction === 'rtl', - ); + gridIsRtlSelector, + (columnsState, model, visibleColumnFields, isRtl) => { + const visiblePinnedFields = filterVisibleColumns(model, visibleColumnFields, isRtl); const visiblePinnedColumns = { left: visiblePinnedFields.left.map((field) => columnsState.lookup[field]), right: visiblePinnedFields.right.map((field) => columnsState.lookup[field]), 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 1854e8a134b0..d11ecf537ce0 100644 --- a/packages/x-data-grid/src/hooks/features/keyboardNavigation/useGridKeyboardNavigation.ts +++ b/packages/x-data-grid/src/hooks/features/keyboardNavigation/useGridKeyboardNavigation.ts @@ -1,5 +1,5 @@ import * as React from 'react'; -import { useTheme } from '@mui/material/styles'; +import { useRtl } from '@mui/system/RtlProvider'; import { GridEventListener } from '../../../models/events'; import { GridApiCommunity, GridPrivateApiCommunity } from '../../../models/api/gridApiCommunity'; import { GridCellParams } from '../../../models/params/gridCellParams'; @@ -38,18 +38,18 @@ const getLeftColumnIndex = ({ currentColIndex, firstColIndex, lastColIndex, - direction, + isRtl, }: { currentColIndex: number; firstColIndex: number; lastColIndex: number; - direction: 'rtl' | 'ltr'; + isRtl: boolean; }) => { - if (direction === 'rtl') { + if (isRtl) { if (currentColIndex < lastColIndex) { return currentColIndex + 1; } - } else if (direction === 'ltr') { + } else if (!isRtl) { if (currentColIndex > firstColIndex) { return currentColIndex - 1; } @@ -61,18 +61,18 @@ const getRightColumnIndex = ({ currentColIndex, firstColIndex, lastColIndex, - direction, + isRtl, }: { currentColIndex: number; firstColIndex: number; lastColIndex: number; - direction: 'rtl' | 'ltr'; + isRtl: boolean; }) => { - if (direction === 'rtl') { + if (isRtl) { if (currentColIndex > firstColIndex) { return currentColIndex - 1; } - } else if (direction === 'ltr') { + } else if (!isRtl) { if (currentColIndex < lastColIndex) { return currentColIndex + 1; } @@ -103,7 +103,7 @@ export const useGridKeyboardNavigation = ( ): void => { const logger = useGridLogger(apiRef, 'useGridKeyboardNavigation'); const initialCurrentPageRows = useGridVisibleRows(apiRef, props).rows; - const theme = useTheme(); + const isRtl = useRtl(); const currentPageRows = React.useMemo( () => enrichPageRowsWithPinnedRows(apiRef, initialCurrentPageRows), @@ -220,7 +220,7 @@ export const useGridKeyboardNavigation = ( currentColIndex: colIndexBefore, firstColIndex, lastColIndex, - direction: theme.direction, + isRtl, }); if (rightColIndex !== null) { @@ -235,7 +235,7 @@ export const useGridKeyboardNavigation = ( currentColIndex: colIndexBefore, firstColIndex, lastColIndex, - direction: theme.direction, + isRtl, }); if (leftColIndex !== null) { goToHeader(leftColIndex, event); @@ -300,7 +300,7 @@ export const useGridKeyboardNavigation = ( goToHeaderFilter, goToCell, getRowIdFromIndex, - theme.direction, + isRtl, goToHeader, goToGroupHeader, ], @@ -337,7 +337,7 @@ export const useGridKeyboardNavigation = ( currentColIndex: colIndexBefore, firstColIndex, lastColIndex, - direction: theme.direction, + isRtl, }); if (rightColIndex !== null) { @@ -352,7 +352,7 @@ export const useGridKeyboardNavigation = ( currentColIndex: colIndexBefore, firstColIndex, lastColIndex, - direction: theme.direction, + isRtl, }); if (leftColIndex !== null) { goToHeaderFilter(leftColIndex, event); @@ -407,7 +407,7 @@ export const useGridKeyboardNavigation = ( apiRef, currentPageRows.length, goToHeaderFilter, - theme.direction, + isRtl, goToHeader, goToCell, getRowIdFromIndex, @@ -535,7 +535,6 @@ export const useGridKeyboardNavigation = ( return; } - const direction = theme.direction; const viewportPageSize = apiRef.current.getViewportPageSize(); const colIndexBefore = (params as GridCellParams).field @@ -573,14 +572,10 @@ export const useGridKeyboardNavigation = ( currentColIndex: colIndexBefore, firstColIndex, lastColIndex, - direction, + isRtl, }); if (rightColIndex !== null) { - goToCell( - rightColIndex, - getRowIdFromIndex(rowIndexBefore), - direction === 'rtl' ? 'left' : 'right', - ); + goToCell(rightColIndex, getRowIdFromIndex(rowIndexBefore), isRtl ? 'left' : 'right'); } break; } @@ -590,14 +585,10 @@ export const useGridKeyboardNavigation = ( currentColIndex: colIndexBefore, firstColIndex, lastColIndex, - direction, + isRtl, }); if (leftColIndex !== null) { - goToCell( - leftColIndex, - getRowIdFromIndex(rowIndexBefore), - direction === 'rtl' ? 'right' : 'left', - ); + goToCell(leftColIndex, getRowIdFromIndex(rowIndexBefore), isRtl ? 'right' : 'left'); } break; } @@ -685,7 +676,7 @@ export const useGridKeyboardNavigation = ( [ apiRef, currentPageRows, - theme.direction, + isRtl, goToCell, getRowIdFromIndex, headerFilteringEnabled, diff --git a/packages/x-data-grid/src/hooks/features/scroll/useGridScroll.ts b/packages/x-data-grid/src/hooks/features/scroll/useGridScroll.ts index 0c5543e0d12e..798ffd854c01 100644 --- a/packages/x-data-grid/src/hooks/features/scroll/useGridScroll.ts +++ b/packages/x-data-grid/src/hooks/features/scroll/useGridScroll.ts @@ -1,5 +1,5 @@ import * as React from 'react'; -import { useTheme } from '@mui/material/styles'; +import { useRtl } from '@mui/system/RtlProvider'; import { GridCellIndexCoordinates } from '../../../models/gridCell'; import { GridPrivateApiCommunity } from '../../../models/api/gridApiCommunity'; import { useGridLogger } from '../../utils/useGridLogger'; @@ -55,7 +55,7 @@ export const useGridScroll = ( apiRef: React.MutableRefObject, props: Pick, ): void => { - const theme = useTheme(); + const isRtl = useRtl(); const logger = useGridLogger(apiRef, 'useGridScroll'); const colRef = apiRef.current.columnHeadersContainerRef; const virtualScrollerRef = apiRef.current.virtualScrollerRef!; @@ -145,7 +145,7 @@ export const useGridScroll = ( const scroll = React.useCallback( (params: Partial) => { if (virtualScrollerRef.current && params.left !== undefined && colRef.current) { - const direction = theme.direction === 'rtl' ? -1 : 1; + const direction = isRtl ? -1 : 1; colRef.current.scrollLeft = params.left; virtualScrollerRef.current.scrollLeft = direction * params.left; logger.debug(`Scrolling left: ${params.left}`); @@ -156,7 +156,7 @@ export const useGridScroll = ( } logger.debug(`Scrolling, updating container, and viewport`); }, - [virtualScrollerRef, theme.direction, colRef, logger], + [virtualScrollerRef, isRtl, colRef, logger], ); const getScrollPosition = React.useCallback(() => { 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 4c12b9b87a56..614af3bf0847 100644 --- a/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx +++ b/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx @@ -7,7 +7,7 @@ import { import useLazyRef from '@mui/utils/useLazyRef'; import useTimeout from '@mui/utils/useTimeout'; import { useResizeObserver } from '@mui/x-internals/useResizeObserver'; -import { useTheme, Theme } from '@mui/material/styles'; +import { useRtl } from '@mui/system/RtlProvider'; import type { GridPrivateApiCommunity } from '../../../models/api/gridApiCommunity'; import { useGridPrivateApiContext } from '../../utils/useGridPrivateApiContext'; import { useGridRootProps } from '../../utils/useGridRootProps'; @@ -68,7 +68,7 @@ const EMPTY_SCROLL_POSITION = { top: 0, left: 0 }; export const EMPTY_DETAIL_PANELS = Object.freeze(new Map()); const createScrollCache = ( - mode: 'ltr' | 'rtl', + isRtl: boolean, rowBufferPx: number, columnBufferPx: number, verticalBuffer: number, @@ -76,7 +76,7 @@ const createScrollCache = ( ) => ({ direction: ScrollDirection.NONE, buffer: bufferForDirection( - mode, + isRtl, ScrollDirection.NONE, rowBufferPx, columnBufferPx, @@ -109,7 +109,7 @@ export const useGridVirtualScroller = () => { const hasBottomPinnedRows = pinnedRows.bottom.length > 0; const [panels, setPanels] = React.useState(EMPTY_DETAIL_PANELS); - const theme = useTheme(); + const isRtl = useRtl(); const cellFocus = useGridSelector(apiRef, gridFocusCellSelector); const cellTabIndex = useGridSelector(apiRef, gridTabIndexCellSelector); const rowsMeta = useGridSelector(apiRef, gridRowsMetaSelector); @@ -149,7 +149,7 @@ export const useGridVirtualScroller = () => { const frozenContext = React.useRef(undefined); const scrollCache = useLazyRef(() => createScrollCache( - theme.direction, + isRtl, rootProps.rowBufferPx, rootProps.columnBufferPx, dimensions.rowHeight * 15, @@ -254,7 +254,7 @@ export const useGridVirtualScroller = () => { scrollCache.direction = direction; scrollCache.buffer = bufferForDirection( - theme.direction, + isRtl, direction, rootProps.rowBufferPx, rootProps.columnBufferPx, @@ -290,12 +290,12 @@ export const useGridVirtualScroller = () => { if (scrollTop < 0) { return; } - if (theme.direction === 'ltr') { + if (!isRtl) { if (scrollLeft < 0) { return; } } - if (theme.direction === 'rtl') { + if (isRtl) { if (scrollLeft > 0) { return; } @@ -466,7 +466,7 @@ export const useGridVirtualScroller = () => { const offsetLeft = computeOffsetLeft( columnPositions, currentRenderContext, - theme.direction, + isRtl, pinnedColumns.left.length, ); const showBottomBorder = isLastVisibleInSection && params.position === 'top'; @@ -943,10 +943,10 @@ export function areRenderContextsEqual(context1: GridRenderContext, context2: Gr export function computeOffsetLeft( columnPositions: number[], renderContext: GridColumnsRenderContext, - direction: Theme['direction'], + isRtl: boolean, pinnedLeftLength: number, ) { - const factor = direction === 'ltr' ? 1 : -1; + const factor = isRtl ? -1 : 1; const left = factor * (columnPositions[renderContext.firstColumnIndex] ?? 0) - (columnPositions[pinnedLeftLength] ?? 0); @@ -976,14 +976,14 @@ function directionForDelta(dx: number, dy: number) { } function bufferForDirection( - mode: 'ltr' | 'rtl', + isRtl: boolean, direction: ScrollDirection, rowBufferPx: number, columnBufferPx: number, verticalBuffer: number, horizontalBuffer: number, ) { - if (mode === 'rtl') { + if (isRtl) { switch (direction) { case ScrollDirection.LEFT: direction = ScrollDirection.RIGHT; diff --git a/packages/x-data-grid/src/models/gridStateCommunity.ts b/packages/x-data-grid/src/models/gridStateCommunity.ts index 7e00992692bf..ee737b4b8a51 100644 --- a/packages/x-data-grid/src/models/gridStateCommunity.ts +++ b/packages/x-data-grid/src/models/gridStateCommunity.ts @@ -1,4 +1,3 @@ -import type { Theme } from '@mui/material/styles'; import type { GridColumnMenuState, GridColumnsInitialState, @@ -31,7 +30,7 @@ import type { GridColumnResizeState } from '../hooks/features/columnResize'; * The state of `DataGrid`. */ export interface GridStateCommunity { - theme: Theme; + isRtl: boolean; dimensions: GridDimensionsState; rows: GridRowsState; visibleRowsLookup: GridVisibleRowsLookupState; From d9416d778f7639eb822905986765b2fd11b952af Mon Sep 17 00:00:00 2001 From: Lukas Tyla Date: Thu, 29 Aug 2024 12:17:21 +0300 Subject: [PATCH 6/9] [core] Allow only v5.x for `MUI Core` renovate group (#14382) --- renovate.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/renovate.json b/renovate.json index e8960ee9db0d..4196a9df8eda 100644 --- a/renovate.json +++ b/renovate.json @@ -90,7 +90,8 @@ "@mui/system", "@mui/types", "@mui/utils" - ] + ], + "allowedVersions": "< 6.0.0" }, { "groupName": "MUI Internal", From 70b6cb716063dce01463ec9a72505ebe20971e31 Mon Sep 17 00:00:00 2001 From: Andrew Cherniavskii Date: Thu, 29 Aug 2024 11:41:42 +0200 Subject: [PATCH 7/9] [core] Support `@mui/material@6` peer dependency (#14142) Co-authored-by: Lukas --- .circleci/config.yml | 30 ++- docs/data/data-grid/joy-ui/GridJoyUISlots.js | 10 +- docs/data/data-grid/joy-ui/GridJoyUISlots.tsx | 10 +- .../modules/components/ChartFeaturesGrid.js | 4 +- .../modules/components/InstallationGrid.js | 4 +- package.json | 1 + packages/x-charts-pro/package.json | 6 +- .../src/tests/materialVersion.test.tsx | 5 + packages/x-charts/package.json | 6 +- .../src/tests/materialVersion.test.tsx | 5 + packages/x-data-grid-generator/package.json | 6 +- packages/x-data-grid-premium/package.json | 6 +- .../aggregation.DataGridPremium.test.tsx | 1 + .../src/tests/materialVersion.test.tsx | 5 + packages/x-data-grid-pro/package.json | 6 +- .../src/tests/materialVersion.test.tsx | 5 + packages/x-data-grid/package.json | 6 +- .../src/tests/columnHeaders.DataGrid.test.tsx | 55 +++-- .../src/tests/materialVersion.test.tsx | 5 + .../src/tests/rowSelection.DataGrid.test.tsx | 18 +- packages/x-date-pickers-pro/package.json | 6 +- .../DateRangeCalendar.test.tsx | 7 +- .../tests/DesktopDateRangePicker.test.tsx | 23 +- .../describes.DesktopDateRangePicker.test.tsx | 7 +- .../tests/DesktopDateTimeRangePicker.test.tsx | 19 +- ...cribes.DesktopDateTimeRangePicker.test.tsx | 15 +- .../tests/MobileDateRangePicker.test.tsx | 77 ++++--- .../describes.MobileDateRangePicker.test.tsx | 5 +- ...scribes.MobileDateTimeRangePicker.test.tsx | 17 +- .../src/tests/materialVersion.test.tsx | 5 + packages/x-date-pickers/package.json | 6 +- .../DateCalendar/tests/DateCalendar.test.tsx | 199 +++++++++--------- .../tests/describes.DateCalendar.test.tsx | 5 +- .../tests/timezone.DateCalendar.test.tsx | 9 +- .../tests/DesktopDatePicker.test.tsx | 19 +- .../describes.DesktopDatePicker.test.tsx | 5 +- .../tests/DesktopDateTimePicker.test.tsx | 70 +++--- .../describes.DesktopDateTimePicker.test.tsx | 15 +- .../tests/DesktopTimePicker.test.tsx | 79 ++++--- .../describes.DesktopTimePicker.test.tsx | 13 +- .../tests/timezone.DigitalClock.test.tsx | 9 +- .../tests/MobileDatePicker.test.tsx | 3 +- .../tests/describes.MobileDatePicker.test.tsx | 3 +- .../tests/MobileDateTimePicker.test.tsx | 11 +- .../describes.MobileDateTimePicker.test.tsx | 9 +- .../tests/MobileTimePicker.test.tsx | 27 ++- .../tests/describes.MobileTimePicker.test.tsx | 7 +- .../tests/describes.MonthCalendar.test.tsx | 7 +- .../PickersActionBar.test.tsx | 29 ++- .../tests/describes.YearCalendar.test.tsx | 5 +- .../src/tests/materialVersion.test.tsx | 5 + packages/x-tree-view-pro/package.json | 6 +- .../src/tests/materialVersion.test.tsx | 5 + packages/x-tree-view/package.json | 6 +- .../src/tests/materialVersion.test.tsx | 5 + pnpm-lock.yaml | 172 +++++++-------- scripts/useMaterialUIv6.mjs | 12 ++ test/README.md | 38 +++- test/circleci-workflow.png | Bin 0 -> 40490 bytes test/karma.conf.js | 1 + test/package.json | 8 +- test/regressions/index.test.js | 22 ++ test/utils/checkMaterialVersion.ts | 43 ++++ .../describeValue/testPickerActionBar.tsx | 19 +- .../testPickerOpenCloseLifeCycle.tsx | 24 +-- .../pickers/describeValue/testShortcuts.tsx | 9 +- test/utils/pickers/misc.ts | 2 + test/utils/pickers/openPicker.ts | 21 +- test/utils/pickers/viewHandlers.ts | 13 +- 69 files changed, 761 insertions(+), 555 deletions(-) create mode 100644 packages/x-charts-pro/src/tests/materialVersion.test.tsx create mode 100644 packages/x-charts/src/tests/materialVersion.test.tsx create mode 100644 packages/x-data-grid-premium/src/tests/materialVersion.test.tsx create mode 100644 packages/x-data-grid-pro/src/tests/materialVersion.test.tsx create mode 100644 packages/x-data-grid/src/tests/materialVersion.test.tsx create mode 100644 packages/x-date-pickers-pro/src/tests/materialVersion.test.tsx create mode 100644 packages/x-date-pickers/src/tests/materialVersion.test.tsx create mode 100644 packages/x-tree-view-pro/src/tests/materialVersion.test.tsx create mode 100644 packages/x-tree-view/src/tests/materialVersion.test.tsx create mode 100644 scripts/useMaterialUIv6.mjs create mode 100644 test/circleci-workflow.png create mode 100644 test/utils/checkMaterialVersion.ts diff --git a/.circleci/config.yml b/.circleci/config.yml index 53f9f97eed6c..72bff75bfe51 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -99,6 +99,14 @@ commands: # log a patch for maintainers who want to check out this change git --no-pager diff HEAD + - when: + condition: + equal: [material-ui-v6, << pipeline.parameters.workflow >>] + steps: + - run: + name: Install @mui/material@next + command: pnpm use-material-ui-v6 + - when: condition: << parameters.browsers >> steps: @@ -248,7 +256,7 @@ jobs: command: pnpm docs:typescript:formatted --disable-cache - run: name: '`pnpm docs:typescript:formatted` changes committed?' - command: git add -A && git diff --exit-code --staged + command: git add -A && git diff --exit-code --staged docs/src docs/data - run: name: Tests TypeScript definitions command: pnpm typescript:ci @@ -383,3 +391,23 @@ workflows: <<: *default-context react-version: next name: test_e2e-react@next + + material-ui-v6: + when: + equal: [material-ui-v6, << pipeline.parameters.workflow >>] + jobs: + - test_unit: + <<: *default-context + name: test_unit-material@next + - test_browser: + <<: *default-context + name: test_browser-material@next + - test_regressions: + <<: *default-context + name: test_regressions-material@next + - test_e2e: + <<: *default-context + name: test_e2e-material@next + - test_types: + <<: *default-context + name: test_types-material@next diff --git a/docs/data/data-grid/joy-ui/GridJoyUISlots.js b/docs/data/data-grid/joy-ui/GridJoyUISlots.js index 7d88bad69902..35c89967fc53 100644 --- a/docs/data/data-grid/joy-ui/GridJoyUISlots.js +++ b/docs/data/data-grid/joy-ui/GridJoyUISlots.js @@ -3,8 +3,8 @@ import Box from '@mui/material/Box'; import { DataGrid, GridToolbar, GridActionsCellItem } from '@mui/x-data-grid'; import { unstable_joySlots } from '@mui/x-data-grid/joy'; import { - experimental_extendTheme as materialExtendTheme, - Experimental_CssVarsProvider as MaterialCssVarsProvider, + createTheme, + ThemeProvider as MaterialThemeProvider, THEME_ID as MATERIAL_THEME_ID, } from '@mui/material/styles'; import { CssVarsProvider as JoyCssVarsProvider } from '@mui/joy/styles'; @@ -18,7 +18,7 @@ import { randomArrayItem, } from '@mui/x-data-grid-generator'; -const materialTheme = materialExtendTheme({ +const materialTheme = createTheme({ components: { MuiSvgIcon: { styleOverrides: { @@ -97,7 +97,7 @@ export default function GridJoyUISlots() { }, []); return ( - + - + ); } diff --git a/docs/data/data-grid/joy-ui/GridJoyUISlots.tsx b/docs/data/data-grid/joy-ui/GridJoyUISlots.tsx index 8bcd13834ceb..6b1817921dcc 100644 --- a/docs/data/data-grid/joy-ui/GridJoyUISlots.tsx +++ b/docs/data/data-grid/joy-ui/GridJoyUISlots.tsx @@ -3,8 +3,8 @@ import Box from '@mui/material/Box'; import { DataGrid, GridToolbar, GridActionsCellItem } from '@mui/x-data-grid'; import { unstable_joySlots } from '@mui/x-data-grid/joy'; import { - experimental_extendTheme as materialExtendTheme, - Experimental_CssVarsProvider as MaterialCssVarsProvider, + createTheme, + ThemeProvider as MaterialThemeProvider, THEME_ID as MATERIAL_THEME_ID, } from '@mui/material/styles'; import { CssVarsProvider as JoyCssVarsProvider } from '@mui/joy/styles'; @@ -19,7 +19,7 @@ import { } from '@mui/x-data-grid-generator'; import type {} from '@mui/material/themeCssVarsAugmentation'; -const materialTheme = materialExtendTheme({ +const materialTheme = createTheme({ components: { MuiSvgIcon: { styleOverrides: { @@ -106,7 +106,7 @@ export default function GridJoyUISlots() { }, []); return ( - + - + ); } diff --git a/docs/src/modules/components/ChartFeaturesGrid.js b/docs/src/modules/components/ChartFeaturesGrid.js index ecff879e95c2..36af272ba23c 100644 --- a/docs/src/modules/components/ChartFeaturesGrid.js +++ b/docs/src/modules/components/ChartFeaturesGrid.js @@ -1,5 +1,5 @@ import * as React from 'react'; -import Grid from '@mui/material/Unstable_Grid2'; +import Grid from '@mui/material/Grid'; import { InfoCard } from '@mui/docs/InfoCard'; import LineAxisRoundedIcon from '@mui/icons-material/LineAxisRounded'; import DashboardCustomizeRoundedIcon from '@mui/icons-material/DashboardCustomizeRounded'; @@ -45,7 +45,7 @@ export default function ChartFeaturesGrid() { return ( {content.map(({ icon, title, link }) => ( - + ))} diff --git a/docs/src/modules/components/InstallationGrid.js b/docs/src/modules/components/InstallationGrid.js index a5dcda305945..a917df909e2a 100644 --- a/docs/src/modules/components/InstallationGrid.js +++ b/docs/src/modules/components/InstallationGrid.js @@ -1,5 +1,5 @@ import * as React from 'react'; -import Grid from '@mui/material/Unstable_Grid2'; +import Grid from '@mui/material/Grid'; import { InfoCard } from '@mui/docs/InfoCard'; import AccountTreeRounded from '@mui/icons-material/AccountTreeRounded'; import PivotTableChartRoundedIcon from '@mui/icons-material/PivotTableChartRounded'; @@ -38,7 +38,7 @@ export default function InstallationGrid() { return ( {content.map(({ icon, title, description, link }) => ( - + - Aggregation', () => { }), ).getByText('max'), ); + clock.runToLast(); expect(getColumnValues(0)).to.deep.equal(['0', '1', '2', '3', '4', '5', '5' /* Agg */]); }); diff --git a/packages/x-data-grid-premium/src/tests/materialVersion.test.tsx b/packages/x-data-grid-premium/src/tests/materialVersion.test.tsx new file mode 100644 index 000000000000..dc0c0a7e6ee0 --- /dev/null +++ b/packages/x-data-grid-premium/src/tests/materialVersion.test.tsx @@ -0,0 +1,5 @@ +import materialPackageJson from '@mui/material/package.json'; +import { checkMaterialVersion } from 'test/utils/checkMaterialVersion'; +import packageJson from '../../package.json'; + +checkMaterialVersion({ packageJson, materialPackageJson }); diff --git a/packages/x-data-grid-pro/package.json b/packages/x-data-grid-pro/package.json index 72204827ec4c..1bffa00b34bd 100644 --- a/packages/x-data-grid-pro/package.json +++ b/packages/x-data-grid-pro/package.json @@ -44,7 +44,6 @@ }, "dependencies": { "@babel/runtime": "^7.25.4", - "@mui/system": "^5.16.7", "@mui/utils": "^5.16.6", "@mui/x-data-grid": "workspace:*", "@mui/x-internals": "workspace:*", @@ -57,7 +56,8 @@ "peerDependencies": { "@emotion/react": "^11.9.0", "@emotion/styled": "^11.8.1", - "@mui/material": "^5.15.14", + "@mui/material": "^5.15.14 || ^6.0.0", + "@mui/system": "^5.15.14 || ^6.0.0", "react": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0" }, @@ -71,6 +71,8 @@ }, "devDependencies": { "@mui/internal-test-utils": "^1.0.10", + "@mui/material": "^5.16.5", + "@mui/system": "^5.16.7", "@types/prop-types": "^15.7.12", "rimraf": "^5.0.10" }, diff --git a/packages/x-data-grid-pro/src/tests/materialVersion.test.tsx b/packages/x-data-grid-pro/src/tests/materialVersion.test.tsx new file mode 100644 index 000000000000..dc0c0a7e6ee0 --- /dev/null +++ b/packages/x-data-grid-pro/src/tests/materialVersion.test.tsx @@ -0,0 +1,5 @@ +import materialPackageJson from '@mui/material/package.json'; +import { checkMaterialVersion } from 'test/utils/checkMaterialVersion'; +import packageJson from '../../package.json'; + +checkMaterialVersion({ packageJson, materialPackageJson }); diff --git a/packages/x-data-grid/package.json b/packages/x-data-grid/package.json index b15ac1b96fbd..dd1ea5206375 100644 --- a/packages/x-data-grid/package.json +++ b/packages/x-data-grid/package.json @@ -48,7 +48,6 @@ }, "dependencies": { "@babel/runtime": "^7.25.4", - "@mui/system": "^5.16.7", "@mui/utils": "^5.16.6", "@mui/x-internals": "workspace:*", "clsx": "^2.1.1", @@ -58,7 +57,8 @@ "peerDependencies": { "@emotion/react": "^11.9.0", "@emotion/styled": "^11.8.1", - "@mui/material": "^5.15.14", + "@mui/material": "^5.15.14 || ^6.0.0", + "@mui/system": "^5.15.14 || ^6.0.0", "react": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0" }, @@ -73,6 +73,8 @@ "devDependencies": { "@mui/internal-test-utils": "^1.0.10", "@mui/joy": "^5.0.0-beta.48", + "@mui/material": "^5.16.5", + "@mui/system": "^5.16.7", "@mui/types": "^7.2.15", "@types/prop-types": "^15.7.12", "rimraf": "^5.0.10" diff --git a/packages/x-data-grid/src/tests/columnHeaders.DataGrid.test.tsx b/packages/x-data-grid/src/tests/columnHeaders.DataGrid.test.tsx index 0d8a7c325d47..d2fe4adf9853 100644 --- a/packages/x-data-grid/src/tests/columnHeaders.DataGrid.test.tsx +++ b/packages/x-data-grid/src/tests/columnHeaders.DataGrid.test.tsx @@ -1,14 +1,13 @@ import * as React from 'react'; -import { createRenderer, fireEvent, screen, within } from '@mui/internal-test-utils'; +import { createRenderer, screen, waitFor, within } from '@mui/internal-test-utils'; import { expect } from 'chai'; import { DataGrid } from '@mui/x-data-grid'; import { getColumnHeaderCell, getColumnHeadersTextContent } from 'test/utils/helperFn'; -import { fireUserEvent } from 'test/utils/fireUserEvent'; const isJSDOM = /jsdom/.test(window.navigator.userAgent); describe(' - Column headers', () => { - const { render, clock } = createRenderer({ clock: 'fake' }); + const { render } = createRenderer(); const baselineProps = { autoHeight: isJSDOM, @@ -52,8 +51,8 @@ describe(' - Column headers', () => { }); describe('Column menu', () => { - it('should allow to hide column', () => { - render( + it('should allow to hide column', async () => { + const { user } = render(
- Column headers', () => { expect(getColumnHeadersTextContent()).to.deep.equal(['id', 'brand']); - fireEvent.click(within(getColumnHeaderCell(0)).getByLabelText('Menu')); - fireEvent.click(screen.getByRole('menuitem', { name: 'Hide column' })); - clock.runToLast(); + await user.click(within(getColumnHeaderCell(0)).getByLabelText('Menu')); + await user.click(screen.getByRole('menuitem', { name: 'Hide column' })); expect(getColumnHeadersTextContent()).to.deep.equal(['brand']); }); - it('should not allow to hide the only visible column', () => { - render( + it('should not allow to hide the only visible column', async () => { + const { user } = render(
- Column headers', () => { expect(getColumnHeadersTextContent()).to.deep.equal(['id']); - fireEvent.click(within(getColumnHeaderCell(0)).getByLabelText('Menu')); - fireEvent.click(screen.getByRole('menuitem', { name: 'Hide column' })); - clock.runToLast(); + await user.click(within(getColumnHeaderCell(0)).getByLabelText('Menu')); + await user + .setup({ pointerEventsCheck: 0 }) + .click(screen.getByRole('menuitem', { name: 'Hide column' })); expect(getColumnHeadersTextContent()).to.deep.equal(['id']); }); - it('should not allow to hide the only visible column that has menu', () => { - render( + it('should not allow to hide the only visible column that has menu', async () => { + const { user } = render(
- Column headers', () => { expect(getColumnHeadersTextContent()).to.deep.equal(['id', 'brand']); - fireEvent.click(within(getColumnHeaderCell(1)).getByLabelText('Menu')); - fireEvent.click(screen.getByRole('menuitem', { name: 'Hide column' })); - clock.runToLast(); + await user.click(within(getColumnHeaderCell(1)).getByLabelText('Menu')); + await user + .setup({ pointerEventsCheck: 0 }) + .click(screen.getByRole('menuitem', { name: 'Hide column' })); expect(getColumnHeadersTextContent()).to.deep.equal(['id', 'brand']); }); it('menu icon button should close column menu when already open', async () => { - render( + const { user } = render(
, ); - fireUserEvent.mousePress(within(getColumnHeaderCell(0)).getByLabelText('Menu')); - clock.runToLast(); + await user.click(within(getColumnHeaderCell(0)).getByLabelText('Menu')); expect(screen.queryByRole('menu')).not.to.equal(null); - fireUserEvent.mousePress(within(getColumnHeaderCell(0)).getByLabelText('Menu')); - clock.runToLast(); - expect(screen.queryByRole('menu')).to.equal(null); + await user.click(within(getColumnHeaderCell(0)).getByLabelText('Menu')); + await waitFor(() => { + expect(screen.queryByRole('menu')).to.equal(null); + }); }); }); - it('should display sort column menu items as per sortingOrder prop', () => { - render( + it('should display sort column menu items as per sortingOrder prop', async () => { + const { user } = render(
- Column headers', () => { ); const columnCell = getColumnHeaderCell(0); const menuIconButton = columnCell.querySelector('button[aria-label="Menu"]')!; - fireEvent.click(menuIconButton); - clock.runToLast(); + await user.click(menuIconButton); expect(screen.queryByRole('menuitem', { name: /asc/i })).not.to.equal(null); expect(screen.queryByRole('menuitem', { name: /desc/i })).not.to.equal(null); diff --git a/packages/x-data-grid/src/tests/materialVersion.test.tsx b/packages/x-data-grid/src/tests/materialVersion.test.tsx new file mode 100644 index 000000000000..dc0c0a7e6ee0 --- /dev/null +++ b/packages/x-data-grid/src/tests/materialVersion.test.tsx @@ -0,0 +1,5 @@ +import materialPackageJson from '@mui/material/package.json'; +import { checkMaterialVersion } from 'test/utils/checkMaterialVersion'; +import packageJson from '../../package.json'; + +checkMaterialVersion({ packageJson, materialPackageJson }); 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 23f1c8f406d2..b39a5d79d580 100644 --- a/packages/x-data-grid/src/tests/rowSelection.DataGrid.test.tsx +++ b/packages/x-data-grid/src/tests/rowSelection.DataGrid.test.tsx @@ -1,7 +1,14 @@ import * as React from 'react'; import { expect } from 'chai'; import { spy } from 'sinon'; -import { createRenderer, fireEvent, screen, act, waitFor } from '@mui/internal-test-utils'; +import { + createRenderer, + fireEvent, + screen, + act, + waitFor, + flushMicrotasks, +} from '@mui/internal-test-utils'; import { DataGrid, DataGridProps, @@ -221,7 +228,7 @@ describe(' - Row selection', () => { expect(getRow(0).querySelector('input')).to.have.property('checked', false); }); - it('should set focus on the cell when clicking the checkbox', () => { + it('should set focus on the cell when clicking the checkbox', async () => { render(); expect(getActiveCell()).to.equal(null); @@ -230,7 +237,9 @@ describe(' - Row selection', () => { fireUserEvent.mousePress(checkboxInput!); - expect(getActiveCell()).to.equal('0-0'); + await waitFor(() => { + expect(getActiveCell()).to.equal('0-0'); + }); }); it('should select all visible rows regardless of pagination', () => { @@ -527,7 +536,7 @@ describe(' - Row selection', () => { describe('ripple', () => { clock.withFakeTimers(); - it('should keep only one ripple visible when navigating between checkboxes', function test() { + it('should keep only one ripple visible when navigating between checkboxes', async function test() { if (isJSDOM) { // JSDOM doesn't fire "blur" when .focus is called in another element // FIXME Firefox doesn't show any ripple @@ -539,6 +548,7 @@ describe(' - Row selection', () => { fireEvent.keyDown(cell, { key: 'ArrowLeft' }); fireEvent.keyDown(getCell(1, 0).querySelector('input')!, { key: 'ArrowUp' }); clock.runToLast(); // Wait for transition + await flushMicrotasks(); expect(document.querySelectorAll('.MuiTouchRipple-rippleVisible')).to.have.length(1); }); }); diff --git a/packages/x-date-pickers-pro/package.json b/packages/x-date-pickers-pro/package.json index 015d92f04b60..727da9ac2882 100644 --- a/packages/x-date-pickers-pro/package.json +++ b/packages/x-date-pickers-pro/package.json @@ -43,7 +43,6 @@ }, "dependencies": { "@babel/runtime": "^7.25.4", - "@mui/system": "^5.16.7", "@mui/utils": "^5.16.6", "@mui/x-date-pickers": "workspace:*", "@mui/x-license": "workspace:*", @@ -54,7 +53,8 @@ "peerDependencies": { "@emotion/react": "^11.9.0", "@emotion/styled": "^11.8.1", - "@mui/material": "^5.15.14", + "@mui/material": "^5.15.14 || ^6.0.0", + "@mui/system": "^5.15.14 || ^6.0.0", "date-fns": "^2.25.0 || ^3.2.0", "date-fns-jalali": "^2.13.0-0 || ^3.2.0-0", "dayjs": "^1.10.7", @@ -96,6 +96,8 @@ }, "devDependencies": { "@mui/internal-test-utils": "^1.0.10", + "@mui/material": "^5.16.5", + "@mui/system": "^5.16.7", "@types/luxon": "^3.4.2", "@types/prop-types": "^15.7.12", "date-fns": "^2.30.0", diff --git a/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.test.tsx b/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.test.tsx index 2dc85c2aa91d..6c4f54626d5a 100644 --- a/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.test.tsx +++ b/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.test.tsx @@ -15,7 +15,6 @@ import { } from '@mui/x-date-pickers-pro/DateRangeCalendar'; import { DateRangePickerDay } from '@mui/x-date-pickers-pro/DateRangePickerDay'; import { describeConformance } from 'test/utils/describeConformance'; -import { fireUserEvent } from 'test/utils/fireUserEvent'; import { RangePosition } from '../models'; const getPickerDay = (name: string, picker = 'January 2018') => @@ -535,7 +534,7 @@ describe('', () => { ); const renderCountBeforeChange = RenderCount.callCount; - fireUserEvent.mousePress(getPickerDay('2')); + fireEvent.click(getPickerDay('2')); expect(RenderCount.callCount - renderCountBeforeChange).to.equal(2); // 2 render * 1 day }); @@ -550,10 +549,10 @@ describe('', () => { />, ); - fireUserEvent.mousePress(getPickerDay('2')); + fireEvent.click(getPickerDay('2')); const renderCountBeforeChange = RenderCount.callCount; - fireUserEvent.mousePress(getPickerDay('4')); + fireEvent.click(getPickerDay('4')); expect(RenderCount.callCount - renderCountBeforeChange).to.equal(6); // 2 render * 3 day }); }); diff --git a/packages/x-date-pickers-pro/src/DesktopDateRangePicker/tests/DesktopDateRangePicker.test.tsx b/packages/x-date-pickers-pro/src/DesktopDateRangePicker/tests/DesktopDateRangePicker.test.tsx index ee452e3e68ad..8ec961707343 100644 --- a/packages/x-date-pickers-pro/src/DesktopDateRangePicker/tests/DesktopDateRangePicker.test.tsx +++ b/packages/x-date-pickers-pro/src/DesktopDateRangePicker/tests/DesktopDateRangePicker.test.tsx @@ -15,7 +15,6 @@ import { getFieldSectionsContainer, getTextbox, } from 'test/utils/pickers'; -import { fireUserEvent } from 'test/utils/fireUserEvent'; const isJSDOM = /jsdom/.test(window.navigator.userAgent); @@ -48,7 +47,7 @@ describe('', () => { expect(screen.getByText('May 2019')).toBeVisible(); }); - it(`should not crash when opening picker with invalid date value`, async () => { + it(`should not crash when opening picker with invalid date value`, () => { render( ', () => { expect(onClose.callCount).to.equal(0); // Change the start date - fireUserEvent.mousePress(getPickerDay('3')); + fireEvent.click(getPickerDay('3')); expect(onChange.callCount).to.equal(1); expect(onChange.lastCall.args[0][0]).toEqualDateTime(new Date(2018, 0, 3)); expect(onChange.lastCall.args[0][1]).toEqualDateTime(defaultValue[1]); // Change the end date - fireUserEvent.mousePress(getPickerDay('5')); + fireEvent.click(getPickerDay('5')); expect(onChange.callCount).to.equal(2); expect(onChange.lastCall.args[0][0]).toEqualDateTime(new Date(2018, 0, 3)); expect(onChange.lastCall.args[0][1]).toEqualDateTime(new Date(2018, 0, 5)); @@ -288,7 +287,7 @@ describe('', () => { expect(onClose.callCount).to.equal(0); // Change the end date - fireUserEvent.mousePress(getPickerDay('3')); + fireEvent.click(getPickerDay('3')); expect(onChange.callCount).to.equal(1); expect(onChange.lastCall.args[0][0]).toEqualDateTime(defaultValue[0]); expect(onChange.lastCall.args[0][1]).toEqualDateTime(new Date(2018, 0, 3)); @@ -319,7 +318,7 @@ describe('', () => { openPicker({ type: 'date-range', variant: 'desktop', initialFocus: 'end' }); // Change the end date - fireUserEvent.mousePress(getPickerDay('3')); + fireEvent.click(getPickerDay('3')); expect(onAccept.callCount).to.equal(0); expect(onClose.callCount).to.equal(0); @@ -347,7 +346,7 @@ describe('', () => { openPicker({ type: 'date-range', variant: 'desktop', initialFocus: 'start' }); // Change the start date (already tested) - fireUserEvent.mousePress(getPickerDay('3')); + fireEvent.click(getPickerDay('3')); // Dismiss the picker // eslint-disable-next-line material-ui/disallow-active-element-as-key-event-target -- don't care @@ -418,7 +417,7 @@ describe('', () => { openPicker({ type: 'date-range', variant: 'desktop', initialFocus: 'start' }); // Change the start date (already tested) - fireUserEvent.mousePress(getPickerDay('3')); + fireEvent.click(getPickerDay('3')); clock.runToLast(); // Dismiss the picker @@ -454,7 +453,7 @@ describe('', () => { ); // Dismiss the picker - fireUserEvent.mousePress(document.body); + fireEvent.click(document.body); expect(onChange.callCount).to.equal(0); expect(onAccept.callCount).to.equal(0); expect(onClose.callCount).to.equal(0); @@ -522,7 +521,7 @@ describe('', () => { expect(screen.getByRole('tooltip')).toBeVisible(); // Change the start date (already tested) - fireUserEvent.mousePress(getPickerDay('3')); + fireEvent.click(getPickerDay('3')); clock.runToLast(); act(() => { @@ -560,7 +559,7 @@ describe('', () => { openPicker({ type: 'date-range', variant: 'desktop', initialFocus: 'start' }); // Clear the date - fireUserEvent.mousePress(screen.getByText(/clear/i)); + fireEvent.click(screen.getByText(/clear/i)); expect(onChange.callCount).to.equal(1); // Start date change expect(onChange.lastCall.args[0]).to.deep.equal([null, null]); expect(onAccept.callCount).to.equal(1); @@ -587,7 +586,7 @@ describe('', () => { openPicker({ type: 'date-range', variant: 'desktop', initialFocus: 'start' }); // Clear the date - fireUserEvent.mousePress(screen.getByText(/clear/i)); + fireEvent.click(screen.getByText(/clear/i)); expect(onChange.callCount).to.equal(0); expect(onAccept.callCount).to.equal(0); expect(onClose.callCount).to.equal(1); diff --git a/packages/x-date-pickers-pro/src/DesktopDateRangePicker/tests/describes.DesktopDateRangePicker.test.tsx b/packages/x-date-pickers-pro/src/DesktopDateRangePicker/tests/describes.DesktopDateRangePicker.test.tsx index 2639cbebef6b..640ac3b6c5f3 100644 --- a/packages/x-date-pickers-pro/src/DesktopDateRangePicker/tests/describes.DesktopDateRangePicker.test.tsx +++ b/packages/x-date-pickers-pro/src/DesktopDateRangePicker/tests/describes.DesktopDateRangePicker.test.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { screen } from '@mui/internal-test-utils'; +import { fireEvent, screen } from '@mui/internal-test-utils'; import { adapterToUse, createPickerRenderer, @@ -13,7 +13,6 @@ import { import { DesktopDateRangePicker } from '@mui/x-date-pickers-pro/DesktopDateRangePicker'; import { SingleInputDateRangeField } from '@mui/x-date-pickers-pro/SingleInputDateRangeField'; import { describeConformance } from 'test/utils/describeConformance'; -import { fireUserEvent } from 'test/utils/fireUserEvent'; describe(' - Describes', () => { const { render, clock } = createPickerRenderer({ @@ -87,7 +86,7 @@ describe(' - Describes', () => { } if (isOpened) { - fireUserEvent.mousePress( + fireEvent.click( screen.getAllByRole('gridcell', { name: adapterToUse.getDate(newValue[setEndDate ? 1 : 0]).toString(), })[0], @@ -149,7 +148,7 @@ describe(' - Describes', () => { } if (isOpened) { - fireUserEvent.mousePress( + fireEvent.click( screen.getAllByRole('gridcell', { name: adapterToUse.getDate(newValue[setEndDate ? 1 : 0]).toString(), })[0], diff --git a/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/tests/DesktopDateTimeRangePicker.test.tsx b/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/tests/DesktopDateTimeRangePicker.test.tsx index e866a5140081..078ffbc61c0b 100644 --- a/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/tests/DesktopDateTimeRangePicker.test.tsx +++ b/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/tests/DesktopDateTimeRangePicker.test.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import { expect } from 'chai'; -import { screen } from '@mui/internal-test-utils'; +import { fireEvent, screen } from '@mui/internal-test-utils'; import { createPickerRenderer, adapterToUse, @@ -8,7 +8,6 @@ import { getFieldSectionsContainer, expectFieldValueV7, } from 'test/utils/pickers'; -import { fireUserEvent } from 'test/utils/fireUserEvent'; import { DesktopDateTimeRangePicker } from '../DesktopDateTimeRangePicker'; describe('', () => { @@ -24,16 +23,16 @@ describe('', () => { openPicker({ type: 'date-time-range', variant: 'desktop', initialFocus: 'start' }); // select start date range - fireUserEvent.mousePress(screen.getByRole('gridcell', { name: '11' })); - fireUserEvent.mousePress(screen.getByRole('option', { name: '4 hours' })); - fireUserEvent.mousePress(screen.getByRole('option', { name: '5 minutes' })); - fireUserEvent.mousePress(screen.getByRole('option', { name: 'PM' })); + fireEvent.click(screen.getByRole('gridcell', { name: '11' })); + fireEvent.click(screen.getByRole('option', { name: '4 hours' })); + fireEvent.click(screen.getByRole('option', { name: '5 minutes' })); + fireEvent.click(screen.getByRole('option', { name: 'PM' })); // select end date range on the same day - fireUserEvent.mousePress(screen.getByRole('gridcell', { name: '11' })); - fireUserEvent.mousePress(screen.getByRole('option', { name: '5 hours' })); - fireUserEvent.mousePress(screen.getByRole('option', { name: '10 minutes' })); - fireUserEvent.mousePress(screen.getByRole('option', { name: 'PM' })); + fireEvent.click(screen.getByRole('gridcell', { name: '11' })); + fireEvent.click(screen.getByRole('option', { name: '5 hours' })); + fireEvent.click(screen.getByRole('option', { name: '10 minutes' })); + fireEvent.click(screen.getByRole('option', { name: 'PM' })); const startSectionsContainer = getFieldSectionsContainer(0); const endSectionsContainer = getFieldSectionsContainer(1); diff --git a/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/tests/describes.DesktopDateTimeRangePicker.test.tsx b/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/tests/describes.DesktopDateTimeRangePicker.test.tsx index bd7c125ec4b4..d9b960a96037 100644 --- a/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/tests/describes.DesktopDateTimeRangePicker.test.tsx +++ b/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/tests/describes.DesktopDateTimeRangePicker.test.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { describeConformance, screen } from '@mui/internal-test-utils'; +import { describeConformance, fireEvent, screen } from '@mui/internal-test-utils'; import { createPickerRenderer, adapterToUse, @@ -9,7 +9,6 @@ import { describeRangeValidation, getFieldSectionsContainer, } from 'test/utils/pickers'; -import { fireUserEvent } from 'test/utils/fireUserEvent'; import { DesktopDateTimeRangePicker } from '../DesktopDateTimeRangePicker'; describe(' - Describes', () => { @@ -102,7 +101,7 @@ describe(' - Describes', () => { ]; } if (isOpened) { - fireUserEvent.mousePress( + fireEvent.click( screen.getByRole('gridcell', { name: adapterToUse.getDate(newValue[setEndDate ? 1 : 0]).toString(), }), @@ -113,10 +112,8 @@ describe(' - Describes', () => { hasMeridiem ? 'hours12h' : 'hours24h', ); const hoursNumber = adapterToUse.getHours(newValue[setEndDate ? 1 : 0]); - fireUserEvent.mousePress( - screen.getByRole('option', { name: `${parseInt(hours, 10)} hours` }), - ); - fireUserEvent.mousePress( + fireEvent.click(screen.getByRole('option', { name: `${parseInt(hours, 10)} hours` })); + fireEvent.click( screen.getByRole('option', { name: `${adapterToUse.getMinutes(newValue[setEndDate ? 1 : 0])} minutes`, }), @@ -124,9 +121,7 @@ describe(' - Describes', () => { if (hasMeridiem) { // meridiem is an extra view on `DesktopDateTimeRangePicker` // we need to click it to finish selection - fireUserEvent.mousePress( - screen.getByRole('option', { name: hoursNumber >= 12 ? 'PM' : 'AM' }), - ); + fireEvent.click(screen.getByRole('option', { name: hoursNumber >= 12 ? 'PM' : 'AM' })); } } else { selectSection('day'); diff --git a/packages/x-date-pickers-pro/src/MobileDateRangePicker/tests/MobileDateRangePicker.test.tsx b/packages/x-date-pickers-pro/src/MobileDateRangePicker/tests/MobileDateRangePicker.test.tsx index 177cf4752e9a..76383fe45d87 100644 --- a/packages/x-date-pickers-pro/src/MobileDateRangePicker/tests/MobileDateRangePicker.test.tsx +++ b/packages/x-date-pickers-pro/src/MobileDateRangePicker/tests/MobileDateRangePicker.test.tsx @@ -9,12 +9,11 @@ import { openPicker, getFieldSectionsContainer, } from 'test/utils/pickers'; -import { fireUserEvent } from 'test/utils/fireUserEvent'; import { DateRange } from '@mui/x-date-pickers-pro/models'; import { SingleInputDateRangeField } from '@mui/x-date-pickers-pro/SingleInputDateRangeField'; describe('', () => { - const { render } = createPickerRenderer({ clock: 'fake' }); + const { render } = createPickerRenderer(); describe('Field slot: SingleInputDateRangeField', () => { it('should render the input with a given `name` when `SingleInputDateRangeField` is used', () => { @@ -37,29 +36,43 @@ describe('', () => { }); describe('picker state', () => { - it('should open when focusing the start input', () => { + it('should open when focusing the start input', async () => { const onOpen = spy(); - render(); + const { user } = render( + , + ); - openPicker({ type: 'date-range', variant: 'mobile', initialFocus: 'start' }); + await openPicker({ + type: 'date-range', + variant: 'mobile', + initialFocus: 'start', + click: user.click, + }); expect(onOpen.callCount).to.equal(1); expect(screen.queryByRole('dialog')).toBeVisible(); }); - it('should open when focusing the end input', () => { + it('should open when focusing the end input', async () => { const onOpen = spy(); - render(); + const { user } = render( + , + ); - openPicker({ type: 'date-range', variant: 'mobile', initialFocus: 'end' }); + await openPicker({ + type: 'date-range', + variant: 'mobile', + initialFocus: 'end', + click: user.click, + }); expect(onOpen.callCount).to.equal(1); expect(screen.queryByRole('dialog')).toBeVisible(); }); - it('should call onChange with updated start date then call onChange with updated end date when opening from start input', () => { + it('should call onChange with updated start date then call onChange with updated end date when opening from start input', async () => { const onChange = spy(); const onAccept = spy(); const onClose = spy(); @@ -68,7 +81,7 @@ describe('', () => { adapterToUse.date('2018-01-06'), ]; - render( + const { user } = render( ', () => { expect(onClose.callCount).to.equal(0); // Change the start date - fireUserEvent.mousePress(screen.getByRole('gridcell', { name: '3' })); + await user.click(screen.getByRole('gridcell', { name: '3' })); expect(onChange.callCount).to.equal(1); expect(onChange.lastCall.args[0][0]).toEqualDateTime(new Date(2018, 0, 3)); expect(onChange.lastCall.args[0][1]).toEqualDateTime(defaultValue[1]); // Change the end date - fireUserEvent.mousePress(screen.getByRole('gridcell', { name: '5' })); + await user.click(screen.getByRole('gridcell', { name: '5' })); expect(onChange.callCount).to.equal(2); expect(onChange.lastCall.args[0][0]).toEqualDateTime(new Date(2018, 0, 3)); expect(onChange.lastCall.args[0][1]).toEqualDateTime(new Date(2018, 0, 5)); @@ -100,7 +113,7 @@ describe('', () => { expect(onClose.callCount).to.equal(0); }); - it('should call onChange with updated end date when opening from end input', () => { + it('should call onChange with updated end date when opening from end input', async () => { const onChange = spy(); const onAccept = spy(); const onClose = spy(); @@ -109,7 +122,7 @@ describe('', () => { adapterToUse.date('2018-01-06'), ]; - render( + const { user } = render( ', () => { expect(onClose.callCount).to.equal(0); // Change the end date - fireUserEvent.mousePress(screen.getByRole('gridcell', { name: '3' })); + await user.click(screen.getByRole('gridcell', { name: '3' })); expect(onChange.callCount).to.equal(1); expect(onChange.lastCall.args[0][0]).toEqualDateTime(defaultValue[0]); expect(onChange.lastCall.args[0][1]).toEqualDateTime(new Date(2018, 0, 3)); @@ -134,7 +147,7 @@ describe('', () => { expect(onClose.callCount).to.equal(0); }); - it('should call onClose and onAccept when selecting the end date if props.closeOnSelect = true', () => { + it('should call onClose and onAccept when selecting the end date if props.closeOnSelect = true', async () => { const onAccept = spy(); const onClose = spy(); const defaultValue: DateRange = [ @@ -142,7 +155,7 @@ describe('', () => { adapterToUse.date('2018-01-06'), ]; - render( + const { user } = render( ', () => { openPicker({ type: 'date-range', variant: 'mobile', initialFocus: 'end' }); // Change the end date - fireUserEvent.mousePress(screen.getByRole('gridcell', { name: '3' })); + await user.click(screen.getByRole('gridcell', { name: '3' })); expect(onAccept.callCount).to.equal(1); expect(onAccept.lastCall.args[0][0]).toEqualDateTime(defaultValue[0]); @@ -163,7 +176,7 @@ describe('', () => { expect(onClose.callCount).to.equal(1); }); - it('should call onClose and onChange with the initial value when clicking "Cancel" button', () => { + it('should call onClose and onChange with the initial value when clicking "Cancel" button', async () => { const onChange = spy(); const onAccept = spy(); const onClose = spy(); @@ -172,7 +185,7 @@ describe('', () => { adapterToUse.date('2018-01-06'), ]; - render( + const { user } = render( ', () => { openPicker({ type: 'date-range', variant: 'mobile', initialFocus: 'start' }); // Change the start date (already tested) - fireUserEvent.mousePress(screen.getByRole('gridcell', { name: '3' })); + await user.click(screen.getByRole('gridcell', { name: '3' })); // Cancel the modifications - fireUserEvent.mousePress(screen.getByText(/cancel/i)); + await user.click(screen.getByText(/cancel/i)); expect(onChange.callCount).to.equal(2); // Start date change + reset expect(onChange.lastCall.args[0][0]).toEqualDateTime(defaultValue[0]); expect(onChange.lastCall.args[0][1]).toEqualDateTime(defaultValue[1]); @@ -197,7 +210,7 @@ describe('', () => { expect(onClose.callCount).to.equal(1); }); - it('should call onClose and onAccept with the live value and onAccept with the live value when clicking the "OK"', () => { + it('should call onClose and onAccept with the live value and onAccept with the live value when clicking the "OK"', async () => { const onChange = spy(); const onAccept = spy(); const onClose = spy(); @@ -206,7 +219,7 @@ describe('', () => { adapterToUse.date('2018-01-06'), ]; - render( + const { user } = render( ', () => { openPicker({ type: 'date-range', variant: 'mobile', initialFocus: 'start' }); // Change the start date (already tested) - fireUserEvent.mousePress(screen.getByRole('gridcell', { name: '3' })); + await user.click(screen.getByRole('gridcell', { name: '3' })); // Accept the modifications - fireUserEvent.mousePress(screen.getByText(/ok/i)); + await user.click(screen.getByText(/ok/i)); expect(onChange.callCount).to.equal(1); // Start date change expect(onAccept.callCount).to.equal(1); expect(onAccept.lastCall.args[0][0]).toEqualDateTime(new Date(2018, 0, 3)); @@ -230,7 +243,7 @@ describe('', () => { expect(onClose.callCount).to.equal(1); }); - it('should call onClose, onChange with empty value and onAccept with empty value when pressing the "Clear" button', () => { + it('should call onClose, onChange with empty value and onAccept with empty value when pressing the "Clear" button', async () => { const onChange = spy(); const onAccept = spy(); const onClose = spy(); @@ -239,7 +252,7 @@ describe('', () => { adapterToUse.date('2018-01-06'), ]; - render( + const { user } = render( ', () => { openPicker({ type: 'date-range', variant: 'mobile', initialFocus: 'start' }); // Clear the date - fireUserEvent.mousePress(screen.getByText(/clear/i)); + await user.click(screen.getByText(/clear/i)); expect(onChange.callCount).to.equal(1); // Start date change expect(onChange.lastCall.args[0]).to.deep.equal([null, null]); expect(onAccept.callCount).to.equal(1); @@ -261,12 +274,12 @@ describe('', () => { expect(onClose.callCount).to.equal(1); }); - it('should not call onChange or onAccept when pressing "Clear" button with an already null value', () => { + it('should not call onChange or onAccept when pressing "Clear" button with an already null value', async () => { const onChange = spy(); const onAccept = spy(); const onClose = spy(); - render( + const { user } = render( ', () => { openPicker({ type: 'date-range', variant: 'mobile', initialFocus: 'start' }); // Clear the date - fireUserEvent.mousePress(screen.getByText(/clear/i)); + await user.click(screen.getByText(/clear/i)); expect(onChange.callCount).to.equal(0); expect(onAccept.callCount).to.equal(0); expect(onClose.callCount).to.equal(1); diff --git a/packages/x-date-pickers-pro/src/MobileDateRangePicker/tests/describes.MobileDateRangePicker.test.tsx b/packages/x-date-pickers-pro/src/MobileDateRangePicker/tests/describes.MobileDateRangePicker.test.tsx index 7503ccadc73e..3410aec62f20 100644 --- a/packages/x-date-pickers-pro/src/MobileDateRangePicker/tests/describes.MobileDateRangePicker.test.tsx +++ b/packages/x-date-pickers-pro/src/MobileDateRangePicker/tests/describes.MobileDateRangePicker.test.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { screen, fireDiscreteEvent } from '@mui/internal-test-utils'; +import { screen, fireDiscreteEvent, fireEvent } from '@mui/internal-test-utils'; import { MobileDateRangePicker } from '@mui/x-date-pickers-pro/MobileDateRangePicker'; import { adapterToUse, @@ -12,7 +12,6 @@ import { getFieldSectionsContainer, } from 'test/utils/pickers'; import { describeConformance } from 'test/utils/describeConformance'; -import { fireUserEvent } from 'test/utils/fireUserEvent'; describe(' - Describes', () => { const { render, clock } = createPickerRenderer({ @@ -87,7 +86,7 @@ describe(' - Describes', () => { openPicker({ type: 'date-range', variant: 'mobile', initialFocus: 'start' }); } - fireUserEvent.mousePress( + fireEvent.click( screen.getAllByRole('gridcell', { name: adapterToUse.getDate(newValue[setEndDate ? 1 : 0]).toString(), })[0], diff --git a/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/tests/describes.MobileDateTimeRangePicker.test.tsx b/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/tests/describes.MobileDateTimeRangePicker.test.tsx index 1422ba7bb233..06f204cc0cf6 100644 --- a/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/tests/describes.MobileDateTimeRangePicker.test.tsx +++ b/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/tests/describes.MobileDateTimeRangePicker.test.tsx @@ -10,7 +10,6 @@ import { getFieldSectionsContainer, openPicker, } from 'test/utils/pickers'; -import { fireUserEvent } from 'test/utils/fireUserEvent'; import { MobileDateTimeRangePicker } from '../MobileDateTimeRangePicker'; describe(' - Describes', () => { @@ -109,12 +108,12 @@ describe(' - Describes', () => { // if we want to set the end date, we firstly need to switch to end date "range position" if (setEndDate) { - fireUserEvent.mousePress( + fireEvent.click( screen.getByRole('button', { name: adapterToUse.format(value[1], 'shortDate') }), ); } - fireUserEvent.mousePress( + fireEvent.click( screen.getByRole('gridcell', { name: adapterToUse.getDate(newValue[setEndDate ? 1 : 0]).toString(), }), @@ -125,10 +124,8 @@ describe(' - Describes', () => { hasMeridiem ? 'hours12h' : 'hours24h', ); const hoursNumber = adapterToUse.getHours(newValue[setEndDate ? 1 : 0]); - fireUserEvent.mousePress( - screen.getByRole('option', { name: `${parseInt(hours, 10)} hours` }), - ); - fireUserEvent.mousePress( + fireEvent.click(screen.getByRole('option', { name: `${parseInt(hours, 10)} hours` })); + fireEvent.click( screen.getByRole('option', { name: `${adapterToUse.getMinutes(newValue[setEndDate ? 1 : 0])} minutes`, }), @@ -136,9 +133,7 @@ describe(' - Describes', () => { if (hasMeridiem) { // meridiem is an extra view on `MobileDateTimeRangePicker` // we need to click it to finish selection - fireUserEvent.mousePress( - screen.getByRole('option', { name: hoursNumber >= 12 ? 'PM' : 'AM' }), - ); + fireEvent.click(screen.getByRole('option', { name: hoursNumber >= 12 ? 'PM' : 'AM' })); } // Close the picker if (!isOpened) { @@ -147,7 +142,7 @@ describe(' - Describes', () => { clock.runToLast(); } else { // return to the start date view in case we'd like to repeat the selection process - fireUserEvent.mousePress( + fireEvent.click( screen.getByRole('button', { name: adapterToUse.format(newValue[0], 'shortDate') }), ); } diff --git a/packages/x-date-pickers-pro/src/tests/materialVersion.test.tsx b/packages/x-date-pickers-pro/src/tests/materialVersion.test.tsx new file mode 100644 index 000000000000..dc0c0a7e6ee0 --- /dev/null +++ b/packages/x-date-pickers-pro/src/tests/materialVersion.test.tsx @@ -0,0 +1,5 @@ +import materialPackageJson from '@mui/material/package.json'; +import { checkMaterialVersion } from 'test/utils/checkMaterialVersion'; +import packageJson from '../../package.json'; + +checkMaterialVersion({ packageJson, materialPackageJson }); diff --git a/packages/x-date-pickers/package.json b/packages/x-date-pickers/package.json index 7a5ea6153cc8..cb4f946a2fbe 100644 --- a/packages/x-date-pickers/package.json +++ b/packages/x-date-pickers/package.json @@ -46,7 +46,6 @@ }, "dependencies": { "@babel/runtime": "^7.25.4", - "@mui/system": "^5.16.7", "@mui/utils": "^5.16.6", "@types/react-transition-group": "^4.4.11", "clsx": "^2.1.1", @@ -56,7 +55,8 @@ "peerDependencies": { "@emotion/react": "^11.9.0", "@emotion/styled": "^11.8.1", - "@mui/material": "^5.15.14", + "@mui/material": "^5.15.14 || ^6.0.0", + "@mui/system": "^5.15.14 || ^6.0.0", "date-fns": "^2.25.0 || ^3.2.0", "date-fns-jalali": "^2.13.0-0 || ^3.2.0-0", "dayjs": "^1.10.7", @@ -98,6 +98,8 @@ }, "devDependencies": { "@mui/internal-test-utils": "^1.0.10", + "@mui/material": "^5.16.5", + "@mui/system": "^5.16.7", "@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/tests/DateCalendar.test.tsx b/packages/x-date-pickers/src/DateCalendar/tests/DateCalendar.test.tsx index 8cfd7af3ad1e..bf13515b44c8 100644 --- a/packages/x-date-pickers/src/DateCalendar/tests/DateCalendar.test.tsx +++ b/packages/x-date-pickers/src/DateCalendar/tests/DateCalendar.test.tsx @@ -1,40 +1,36 @@ import * as React from 'react'; import { expect } from 'chai'; import { spy } from 'sinon'; -import { fireEvent, screen } from '@mui/internal-test-utils'; +import { fireEvent, screen, waitFor } from '@mui/internal-test-utils'; import { DateCalendar } from '@mui/x-date-pickers/DateCalendar'; import { PickersDay } from '@mui/x-date-pickers/PickersDay'; import { createPickerRenderer, adapterToUse } from 'test/utils/pickers'; -import { fireUserEvent } from 'test/utils/fireUserEvent'; const isJSDOM = /jsdom/.test(window.navigator.userAgent); describe('', () => { - const { render, clock } = createPickerRenderer({ - clock: 'fake', - clockConfig: new Date('2019-01-02'), - }); + const { render } = createPickerRenderer(); - it('switches between views uncontrolled', () => { + it('switches between views uncontrolled', async () => { const handleViewChange = spy(); - render( + const { user } = render( , ); - fireEvent.click(screen.getByLabelText(/switch to year view/i)); + await user.click(screen.getByLabelText(/switch to year view/i)); expect(handleViewChange.callCount).to.equal(1); expect(screen.queryByLabelText(/switch to year view/i)).to.equal(null); expect(screen.getByLabelText('year view is open, switch to calendar view')).toBeVisible(); }); - it('should allow month and view changing, but not selection when readOnly prop is passed', () => { + it('should allow month and view changing, but not selection when readOnly prop is passed', async () => { const onChangeMock = spy(); const onMonthChangeMock = spy(); - render( + const { user } = render( ', () => { />, ); - fireEvent.click(screen.getByTitle('Previous month')); + await user.click(screen.getByTitle('Previous month')); expect(onMonthChangeMock.callCount).to.equal(1); - fireEvent.click(screen.getByTitle('Next month')); + await user.click(screen.getByTitle('Next month')); expect(onMonthChangeMock.callCount).to.equal(2); - clock.runToLast(); + await waitFor(() => expect(screen.getAllByRole('rowgroup').length).to.equal(1)); - fireEvent.click(screen.getByRole('gridcell', { name: '5' })); + await user.click(screen.getByRole('gridcell', { name: '5' })); expect(onChangeMock.callCount).to.equal(0); - fireEvent.click(screen.getByText('January 2019')); + await user.click(screen.getByText('January 2019')); expect(screen.queryByLabelText('year view is open, switch to calendar view')).toBeVisible(); }); - it('should not allow interaction when disabled prop is passed', () => { + it('should not allow interaction when disabled prop is passed', async () => { const onChangeMock = spy(); const onMonthChangeMock = spy(); - render( + const { user } = render( ', () => { />, ); - fireEvent.click(screen.getByText('January 2019')); + await user.click(screen.getByText('January 2019')); expect(screen.queryByText('January 2019')).toBeVisible(); expect(screen.queryByLabelText('year view is open, switch to calendar view')).to.equal(null); - fireEvent.click(screen.getByTitle('Previous month')); + await user.setup({ pointerEventsCheck: 0 }).click(screen.getByTitle('Previous month')); expect(onMonthChangeMock.callCount).to.equal(0); - fireEvent.click(screen.getByTitle('Next month')); + await user.setup({ pointerEventsCheck: 0 }).click(screen.getByTitle('Next month')); expect(onMonthChangeMock.callCount).to.equal(0); - fireEvent.click(screen.getByRole('gridcell', { name: '5' })); + await user.setup({ pointerEventsCheck: 0 }).click(screen.getByRole('gridcell', { name: '5' })); expect(onChangeMock.callCount).to.equal(0); }); @@ -131,28 +127,35 @@ describe('', () => { expect(screen.getAllByRole('rowheader').length).to.equal(5); }); - // test: https://github.com/mui/mui-x/issues/12373 - it('should not reset day to `startOfDay` if value already exists when finding the closest enabled date', () => { - const onChange = spy(); - const defaultDate = adapterToUse.date('2019-01-02T11:12:13.550Z'); - render(); - - fireUserEvent.mousePress( - screen.getByRole('button', { name: 'calendar view is open, switch to year view' }), - ); - fireUserEvent.mousePress(screen.getByRole('radio', { name: '2020' })); + describe('with fake timers', () => { + const { render: renderWithFakeTimers, clock } = createPickerRenderer({ + clock: 'fake', + clockConfig: new Date('2019-01-02'), + }); + // test: https://github.com/mui/mui-x/issues/12373 + it('should not reset day to `startOfDay` if value already exists when finding the closest enabled date', () => { + const onChange = spy(); + const defaultDate = adapterToUse.date('2019-01-02T11:12:13.550Z'); + renderWithFakeTimers( + , + ); - // Finish the transition to the day view - clock.runToLast(); + fireEvent.click( + screen.getByRole('button', { name: 'calendar view is open, switch to year view' }), + ); + fireEvent.click(screen.getByRole('radio', { name: '2020' })); + // Finish the transition to the day view + clock.runToLast(); - fireUserEvent.mousePress(screen.getByRole('gridcell', { name: '1' })); - fireUserEvent.mousePress( - screen.getByRole('button', { name: 'calendar view is open, switch to year view' }), - ); - // select the current year with a date in the past to trigger "findClosestEnabledDate" - fireUserEvent.mousePress(screen.getByRole('radio', { name: '2019' })); + fireEvent.click(screen.getByRole('gridcell', { name: '1' })); + fireEvent.click( + screen.getByRole('button', { name: 'calendar view is open, switch to year view' }), + ); + // select the current year with a date in the past to trigger "findClosestEnabledDate" + fireEvent.click(screen.getByRole('radio', { name: '2019' })); - expect(onChange.lastCall.firstArg).toEqualDateTime(defaultDate); + expect(onChange.lastCall.firstArg).toEqualDateTime(defaultDate); + }); }); describe('Slot: calendarHeader', () => { @@ -182,10 +185,10 @@ describe('', () => { ).to.have.text('1'); }); - it('should use `referenceDate` when no value defined', () => { + it('should use `referenceDate` when no value defined', async () => { const onChange = spy(); - render( + const { user } = render( ', () => { // should make the reference day firstly focusable expect(screen.getByRole('gridcell', { name: '17' })).to.have.attribute('tabindex', '0'); - fireUserEvent.mousePress(screen.getByRole('gridcell', { name: '2' })); + await user.click(screen.getByRole('gridcell', { name: '2' })); expect(onChange.callCount).to.equal(1); expect(onChange.lastCall.firstArg).toEqualDateTime(new Date(2022, 3, 2, 12, 30)); }); - it('should not use `referenceDate` when a value is defined', () => { + it('should not use `referenceDate` when a value is defined', async () => { const onChange = spy(); - render( + const { user } = render( ', () => { />, ); - fireUserEvent.mousePress(screen.getByRole('gridcell', { name: '2' })); + await user.click(screen.getByRole('gridcell', { name: '2' })); expect(onChange.callCount).to.equal(1); expect(onChange.lastCall.firstArg).toEqualDateTime(new Date(2019, 0, 2, 12, 20)); }); - it('should not use `referenceDate` when a defaultValue is defined', () => { + it('should not use `referenceDate` when a defaultValue is defined', async () => { const onChange = spy(); - render( + const { user } = render( ', () => { />, ); - fireUserEvent.mousePress(screen.getByRole('gridcell', { name: '2' })); + await user.click(screen.getByRole('gridcell', { name: '2' })); expect(onChange.callCount).to.equal(1); expect(onChange.lastCall.firstArg).toEqualDateTime(new Date(2019, 0, 2, 12, 20)); }); - it('should keep the time of the currently provided date', () => { + it('should keep the time of the currently provided date', async () => { const onChange = spy(); - render( + const { user } = render( ', () => { />, ); - fireUserEvent.mousePress(screen.getByRole('gridcell', { name: '2' })); + await user.click(screen.getByRole('gridcell', { name: '2' })); expect(onChange.callCount).to.equal(1); expect(onChange.lastCall.firstArg).toEqualDateTime( adapterToUse.date('2018-01-02T11:11:11.111'), @@ -290,10 +293,10 @@ describe('', () => { }); describe('view: month', () => { - it('should select the closest enabled date in the month if the current date is disabled', () => { + it('should select the closest enabled date in the month if the current date is disabled', async () => { const onChange = spy(); - render( + const { user } = render( ', () => { ); const april = screen.getByText('Apr', { selector: 'button' }); - fireEvent.click(april); + await user.click(april); expect(onChange.callCount).to.equal(1); expect(onChange.lastCall.firstArg).toEqualDateTime(new Date(2019, 3, 6)); }); - it('should respect minDate when selecting closest enabled date', () => { + it('should respect minDate when selecting closest enabled date', async () => { const onChange = spy(); - render( + const { user } = render( ', () => { ); const april = screen.getByText('Apr', { selector: 'button' }); - fireEvent.click(april); + await user.click(april); expect(onChange.callCount).to.equal(1); expect(onChange.lastCall.firstArg).toEqualDateTime(new Date(2019, 3, 7)); }); - it('should respect maxDate when selecting closest enabled date', () => { + it('should respect maxDate when selecting closest enabled date', async () => { const onChange = spy(); - render( + const { user } = render( ', () => { ); const april = screen.getByText('Apr', { selector: 'button' }); - fireEvent.click(april); + await user.click(april); expect(onChange.callCount).to.equal(1); expect(onChange.lastCall.firstArg).toEqualDateTime(new Date(2019, 3, 22)); }); - it('should go to next view without changing the date when no date of the new month is enabled', () => { + it('should go to next view without changing the date when no date of the new month is enabled', async () => { const onChange = spy(); - render( + const { user } = render( ', () => { ); const april = screen.getByText('Apr', { selector: 'button' }); - fireEvent.click(april); - clock.runToLast(); + await user.click(april); expect(onChange.callCount).to.equal(0); expect(screen.getByMuiTest('calendar-month-and-year-text')).to.have.text('April 2019'); }); - it('should use `referenceDate` when no value defined', () => { + it('should use `referenceDate` when no value defined', async () => { const onChange = spy(); - render( + const { user } = render( ', () => { ); const april = screen.getByText('Apr', { selector: 'button' }); - fireEvent.click(april); + await user.click(april); expect(onChange.callCount).to.equal(1); expect(onChange.lastCall.firstArg).toEqualDateTime(new Date(2018, 3, 1, 12, 30)); }); - it('should not use `referenceDate` when a value is defined', () => { + it('should not use `referenceDate` when a value is defined', async () => { const onChange = spy(); - render( + const { user } = render( ', () => { ); const april = screen.getByText('Apr', { selector: 'button' }); - fireEvent.click(april); + await user.click(april); expect(onChange.callCount).to.equal(1); expect(onChange.lastCall.firstArg).toEqualDateTime(new Date(2019, 3, 1, 12, 20)); }); - it('should not use `referenceDate` when a defaultValue is defined', () => { + it('should not use `referenceDate` when a defaultValue is defined', async () => { const onChange = spy(); - render( + const { user } = render( ', () => { ); const april = screen.getByText('Apr', { selector: 'button' }); - fireEvent.click(april); + await user.click(april); expect(onChange.callCount).to.equal(1); expect(onChange.lastCall.firstArg).toEqualDateTime(new Date(2019, 3, 1, 12, 20)); @@ -440,10 +442,10 @@ describe('', () => { expect(screen.getAllByMuiTest('year')).to.have.length(200); }); - it('should select the closest enabled date in the month if the current date is disabled', () => { + it('should select the closest enabled date in the month if the current date is disabled', async () => { const onChange = spy(); - render( + const { user } = render( ', () => { ); const year2022 = screen.getByText('2022', { selector: 'button' }); - fireEvent.click(year2022); + await user.click(year2022); expect(onChange.callCount).to.equal(1); expect(onChange.lastCall.firstArg).toEqualDateTime(new Date(2022, 4, 1)); }); - it('should respect minDate when selecting closest enabled date', () => { + it('should respect minDate when selecting closest enabled date', async () => { const onChange = spy(); - render( + const { user } = render( ', () => { ); const year2017 = screen.getByText('2017', { selector: 'button' }); - fireEvent.click(year2017); + await user.click(year2017); expect(onChange.callCount).to.equal(1); expect(onChange.lastCall.firstArg).toEqualDateTime(new Date(2017, 4, 12)); }); - it('should respect maxDate when selecting closest enabled date', () => { + it('should respect maxDate when selecting closest enabled date', async () => { const onChange = spy(); - render( + const { user } = render( ', () => { ); const year2022 = screen.getByText('2022', { selector: 'button' }); - fireEvent.click(year2022); + await user.click(year2022); expect(onChange.callCount).to.equal(1); expect(onChange.lastCall.firstArg).toEqualDateTime(new Date(2022, 2, 31)); }); - it('should go to next view without changing the date when no date of the new year is enabled', () => { + it('should go to next view without changing the date when no date of the new year is enabled', async () => { const onChange = spy(); - render( + const { user } = render( ', () => { ); const year2022 = screen.getByText('2022', { selector: 'button' }); - fireEvent.click(year2022); - clock.runToLast(); + await user.click(year2022); expect(onChange.callCount).to.equal(0); expect(screen.getByMuiTest('calendar-month-and-year-text')).to.have.text('January 2022'); @@ -548,10 +549,10 @@ describe('', () => { expect(parentBoundingBox.bottom).not.to.lessThan(buttonBoundingBox.bottom); }); - it('should use `referenceDate` when no value defined', () => { + it('should use `referenceDate` when no value defined', async () => { const onChange = spy(); - render( + const { user } = render( ', () => { ); const year2022 = screen.getByText('2022', { selector: 'button' }); - fireEvent.click(year2022); + await user.click(year2022); expect(onChange.callCount).to.equal(1); expect(onChange.lastCall.firstArg).toEqualDateTime(new Date(2022, 0, 1, 12, 30)); }); - it('should not use `referenceDate` when a value is defined', () => { + it('should not use `referenceDate` when a value is defined', async () => { const onChange = spy(); - render( + const { user } = render( ', () => { ); const year2022 = screen.getByText('2022', { selector: 'button' }); - fireEvent.click(year2022); + await user.click(year2022); expect(onChange.callCount).to.equal(1); expect(onChange.lastCall.firstArg).toEqualDateTime(new Date(2022, 0, 1, 12, 20)); }); - it('should not use `referenceDate` when a defaultValue is defined', () => { + it('should not use `referenceDate` when a defaultValue is defined', async () => { const onChange = spy(); - render( + const { user } = render( ', () => { ); const year2022 = screen.getByText('2022', { selector: 'button' }); - fireEvent.click(year2022); + await user.click(year2022); expect(onChange.callCount).to.equal(1); expect(onChange.lastCall.firstArg).toEqualDateTime(new Date(2022, 0, 1, 12, 20)); @@ -621,7 +622,7 @@ describe('', () => { ); const renderCountBeforeChange = RenderCount.callCount; - fireUserEvent.mousePress(screen.getByRole('gridcell', { name: '2' })); + fireEvent.click(screen.getByRole('gridcell', { name: '2' })); expect(RenderCount.callCount - renderCountBeforeChange).to.equal(2); // 2 render * 1 day }); @@ -638,7 +639,7 @@ describe('', () => { ); const renderCountBeforeChange = RenderCount.callCount; - fireUserEvent.mousePress(screen.getByRole('gridcell', { name: '2' })); + fireEvent.click(screen.getByRole('gridcell', { name: '2' })); expect(RenderCount.callCount - renderCountBeforeChange).to.equal(4); // 2 render * 2 days }); }); diff --git a/packages/x-date-pickers/src/DateCalendar/tests/describes.DateCalendar.test.tsx b/packages/x-date-pickers/src/DateCalendar/tests/describes.DateCalendar.test.tsx index d3ab8212f0d7..248fbb6e620e 100644 --- a/packages/x-date-pickers/src/DateCalendar/tests/describes.DateCalendar.test.tsx +++ b/packages/x-date-pickers/src/DateCalendar/tests/describes.DateCalendar.test.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import { expect } from 'chai'; -import { screen } from '@mui/internal-test-utils'; +import { fireEvent, screen } from '@mui/internal-test-utils'; import { DateCalendar, dateCalendarClasses as classes } from '@mui/x-date-pickers/DateCalendar'; import { pickersDayClasses } from '@mui/x-date-pickers/PickersDay'; import { @@ -10,7 +10,6 @@ import { describeValue, } from 'test/utils/pickers'; import { describeConformance } from 'test/utils/describeConformance'; -import { fireUserEvent } from 'test/utils/fireUserEvent'; describe(' - Describes', () => { const { render, clock } = createPickerRenderer({ clock: 'fake' }); @@ -48,7 +47,7 @@ describe(' - Describes', () => { }, setNewValue: (value) => { const newValue = adapterToUse.addDays(value, 1); - fireUserEvent.mousePress( + fireEvent.click( screen.getByRole('gridcell', { name: adapterToUse.getDate(newValue).toString() }), ); diff --git a/packages/x-date-pickers/src/DateCalendar/tests/timezone.DateCalendar.test.tsx b/packages/x-date-pickers/src/DateCalendar/tests/timezone.DateCalendar.test.tsx index 795a3bf042af..b6f1ef24905b 100644 --- a/packages/x-date-pickers/src/DateCalendar/tests/timezone.DateCalendar.test.tsx +++ b/packages/x-date-pickers/src/DateCalendar/tests/timezone.DateCalendar.test.tsx @@ -1,9 +1,8 @@ import * as React from 'react'; import { spy } from 'sinon'; import { expect } from 'chai'; -import { screen } from '@mui/internal-test-utils'; +import { fireEvent, screen } from '@mui/internal-test-utils'; import { describeAdapters } from 'test/utils/pickers'; -import { fireUserEvent } from 'test/utils/fireUserEvent'; import { DateCalendar } from '@mui/x-date-pickers/DateCalendar'; const TIMEZONE_TO_TEST = ['UTC', 'system', 'America/New_York']; @@ -18,7 +17,7 @@ describe(' - Timezone', () => { const onChange = spy(); render(); - fireUserEvent.mousePress(screen.getByRole('gridcell', { name: '25' })); + fireEvent.click(screen.getByRole('gridcell', { name: '25' })); const expectedDate = adapter.setDate(adapter.date(undefined, 'default'), 25); // Check the `onChange` value (uses default timezone, e.g: UTC, see TZ env variable) @@ -35,7 +34,7 @@ describe(' - Timezone', () => { it('should use timezone prop for onChange when no value is provided', () => { const onChange = spy(); render(); - fireUserEvent.mousePress(screen.getByRole('gridcell', { name: '25' })); + fireEvent.click(screen.getByRole('gridcell', { name: '25' })); const expectedDate = adapter.setDate( adapter.startOfDay(adapter.date(undefined, timezone)), 25, @@ -53,7 +52,7 @@ describe(' - Timezone', () => { render(); - fireUserEvent.mousePress(screen.getByRole('gridcell', { name: '25' })); + fireEvent.click(screen.getByRole('gridcell', { name: '25' })); const expectedDate = adapter.setDate(value, 25); // Check the `onChange` value (uses timezone prop) diff --git a/packages/x-date-pickers/src/DesktopDatePicker/tests/DesktopDatePicker.test.tsx b/packages/x-date-pickers/src/DesktopDatePicker/tests/DesktopDatePicker.test.tsx index 4078e7548eb3..5d90362ce078 100644 --- a/packages/x-date-pickers/src/DesktopDatePicker/tests/DesktopDatePicker.test.tsx +++ b/packages/x-date-pickers/src/DesktopDatePicker/tests/DesktopDatePicker.test.tsx @@ -6,7 +6,6 @@ import { inputBaseClasses } from '@mui/material/InputBase'; import { fireEvent, screen } from '@mui/internal-test-utils'; import { DesktopDatePicker } from '@mui/x-date-pickers/DesktopDatePicker'; import { createPickerRenderer, adapterToUse, openPicker } from 'test/utils/pickers'; -import { fireUserEvent } from 'test/utils/fireUserEvent'; const isJSDOM = /jsdom/.test(window.navigator.userAgent); @@ -47,7 +46,8 @@ describe('', () => { expect(handleViewChange.callCount).to.equal(1); // Dismiss the picker - fireUserEvent.keyPress(document.activeElement!, { key: 'Escape' }); + // eslint-disable-next-line material-ui/disallow-active-element-as-key-event-target + fireEvent.keyDown(document.activeElement!, { key: 'Escape' }); openPicker({ type: 'date', variant: 'desktop' }); expect(handleViewChange.callCount).to.equal(2); @@ -72,7 +72,8 @@ describe('', () => { expect(handleViewChange.callCount).to.equal(1); // Dismiss the picker - fireUserEvent.keyPress(document.activeElement!, { key: 'Escape' }); + // eslint-disable-next-line material-ui/disallow-active-element-as-key-event-target + fireEvent.keyDown(document.activeElement!, { key: 'Escape' }); openPicker({ type: 'date', variant: 'desktop' }); expect(handleViewChange.callCount).to.equal(2); @@ -89,7 +90,8 @@ describe('', () => { expect(screen.getByRole('radio', { checked: true, name: '2018' })).not.to.equal(null); // Dismiss the picker - fireUserEvent.keyPress(document.activeElement!, { key: 'Escape' }); + // eslint-disable-next-line material-ui/disallow-active-element-as-key-event-target + fireEvent.keyDown(document.activeElement!, { key: 'Escape' }); setProps({ views: ['month', 'year'] }); openPicker({ type: 'date', variant: 'desktop' }); // wait for all pending changes to be flushed @@ -126,7 +128,8 @@ describe('', () => { expect(screen.getByRole('radio', { checked: true, name: 'January' })).not.to.equal(null); // Dismiss the picker - fireUserEvent.keyPress(document.activeElement!, { key: 'Escape' }); + // eslint-disable-next-line material-ui/disallow-active-element-as-key-event-target + fireEvent.keyDown(document.activeElement!, { key: 'Escape' }); setProps({ view: 'year' }); openPicker({ type: 'date', variant: 'desktop' }); // wait for all pending changes to be flushed @@ -221,7 +224,7 @@ describe('', () => { render(); - fireUserEvent.mousePress(screen.getByLabelText(/Choose date/)); + fireEvent.click(screen.getByLabelText(/Choose date/)); expect(onOpen.callCount).to.equal(1); expect(screen.queryByRole('dialog')).toBeVisible(); @@ -245,14 +248,14 @@ describe('', () => { openPicker({ type: 'date', variant: 'desktop' }); // Select year - fireUserEvent.mousePress(screen.getByRole('radio', { name: '2025' })); + fireEvent.click(screen.getByRole('radio', { name: '2025' })); expect(onChange.callCount).to.equal(1); expect(onChange.lastCall.args[0]).toEqualDateTime(new Date(2025, 0, 1)); expect(onAccept.callCount).to.equal(0); expect(onClose.callCount).to.equal(0); // Change the date (same value) - fireUserEvent.mousePress(screen.getByRole('gridcell', { name: '1' })); + fireEvent.click(screen.getByRole('gridcell', { name: '1' })); expect(onChange.callCount).to.equal(1); // Don't call onChange again since the value did not change expect(onAccept.callCount).to.equal(1); expect(onAccept.lastCall.args[0]).toEqualDateTime(new Date(2025, 0, 1)); diff --git a/packages/x-date-pickers/src/DesktopDatePicker/tests/describes.DesktopDatePicker.test.tsx b/packages/x-date-pickers/src/DesktopDatePicker/tests/describes.DesktopDatePicker.test.tsx index 782794ba18eb..5c56072e2b19 100644 --- a/packages/x-date-pickers/src/DesktopDatePicker/tests/describes.DesktopDatePicker.test.tsx +++ b/packages/x-date-pickers/src/DesktopDatePicker/tests/describes.DesktopDatePicker.test.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { screen } from '@mui/internal-test-utils'; +import { fireEvent, screen } from '@mui/internal-test-utils'; import { createPickerRenderer, adapterToUse, @@ -11,7 +11,6 @@ import { } from 'test/utils/pickers'; import { DesktopDatePicker } from '@mui/x-date-pickers/DesktopDatePicker'; import { describeConformance } from 'test/utils/describeConformance'; -import { fireUserEvent } from 'test/utils/fireUserEvent'; describe(' - Describes', () => { const { render, clock } = createPickerRenderer({ clock: 'fake' }); @@ -63,7 +62,7 @@ describe(' - Describes', () => { const newValue = applySameValue ? value : adapterToUse.addDays(value, 1); if (isOpened) { - fireUserEvent.mousePress( + fireEvent.click( screen.getByRole('gridcell', { name: adapterToUse.getDate(newValue).toString() }), ); } else { diff --git a/packages/x-date-pickers/src/DesktopDateTimePicker/tests/DesktopDateTimePicker.test.tsx b/packages/x-date-pickers/src/DesktopDateTimePicker/tests/DesktopDateTimePicker.test.tsx index fbaa72781475..c298769075bb 100644 --- a/packages/x-date-pickers/src/DesktopDateTimePicker/tests/DesktopDateTimePicker.test.tsx +++ b/packages/x-date-pickers/src/DesktopDateTimePicker/tests/DesktopDateTimePicker.test.tsx @@ -4,32 +4,28 @@ import { spy } from 'sinon'; import { screen } from '@mui/internal-test-utils'; import { DesktopDateTimePicker } from '@mui/x-date-pickers/DesktopDateTimePicker'; import { adapterToUse, createPickerRenderer, openPicker } from 'test/utils/pickers'; -import { fireUserEvent } from 'test/utils/fireUserEvent'; describe('', () => { - const { render } = createPickerRenderer({ - clock: 'fake', - clockConfig: new Date('2018-01-01T10:05:05.000'), - }); + const { render } = createPickerRenderer(); describe('picker state', () => { - it('should open when clicking "Choose date"', () => { + it('should open when clicking "Choose date"', async () => { const onOpen = spy(); - render(); + const { user } = render(); - fireUserEvent.mousePress(screen.getByLabelText(/Choose date/)); + await user.click(screen.getByLabelText(/Choose date/)); expect(onOpen.callCount).to.equal(1); expect(screen.queryByRole('dialog')).toBeVisible(); }); - it('should call onAccept when selecting the same date and time after changing the year', () => { + it('should call onAccept when selecting the same date and time after changing the year', async () => { const onChange = spy(); const onAccept = spy(); const onClose = spy(); - render( + const { user } = render( ', () => { />, ); - openPicker({ type: 'date-time', variant: 'desktop' }); + await openPicker({ type: 'date-time', variant: 'desktop', click: user.click }); // Select year - fireUserEvent.mousePress(screen.getByRole('radio', { name: '2025' })); + await user.click(screen.getByRole('radio', { name: '2025' })); expect(onChange.callCount).to.equal(1); expect(onChange.lastCall.args[0]).toEqualDateTime(new Date(2025, 0, 1, 11, 55)); expect(onAccept.callCount).to.equal(0); expect(onClose.callCount).to.equal(0); // Change the date (same value) - fireUserEvent.mousePress(screen.getByRole('gridcell', { name: '1' })); + await user.click(screen.getByRole('gridcell', { name: '1' })); expect(onChange.callCount).to.equal(1); // Don't call onChange again since the value did not change // Change the hours (same value) - fireUserEvent.mousePress(screen.getByRole('option', { name: '11 hours' })); + await user.click(screen.getByRole('option', { name: '11 hours' })); expect(onChange.callCount).to.equal(1); // Don't call onChange again since the value did not change // Change the minutes (same value) - fireUserEvent.mousePress(screen.getByRole('option', { name: '55 minutes' })); + await user.click(screen.getByRole('option', { name: '55 minutes' })); expect(onChange.callCount).to.equal(1); // Don't call onChange again since the value did not change // Change the meridiem (same value) - fireUserEvent.mousePress(screen.getByRole('option', { name: 'AM' })); + await user.click(screen.getByRole('option', { name: 'AM' })); expect(onChange.callCount).to.equal(1); // Don't call onChange again since the value did not change expect(onAccept.callCount).to.equal(1); expect(onClose.callCount).to.equal(1); }); }); - it('should allow selecting same view multiple times', () => { + it('should allow selecting same view multiple times', async () => { const onChange = spy(); const onAccept = spy(); const onClose = spy(); - render( + const { user } = render( ', () => { />, ); - openPicker({ type: 'date-time', variant: 'desktop' }); + await openPicker({ type: 'date-time', variant: 'desktop', click: user.click }); // Change the date multiple times to check that picker doesn't close after cycling through all views internally - fireUserEvent.mousePress(screen.getByRole('gridcell', { name: '2' })); - fireUserEvent.mousePress(screen.getByRole('gridcell', { name: '3' })); - fireUserEvent.mousePress(screen.getByRole('gridcell', { name: '4' })); - fireUserEvent.mousePress(screen.getByRole('gridcell', { name: '5' })); + await user.click(screen.getByRole('gridcell', { name: '2' })); + await user.click(screen.getByRole('gridcell', { name: '3' })); + await user.click(screen.getByRole('gridcell', { name: '4' })); + await user.click(screen.getByRole('gridcell', { name: '5' })); expect(onChange.callCount).to.equal(4); expect(onAccept.callCount).to.equal(0); expect(onClose.callCount).to.equal(0); // Change the hours - fireUserEvent.mousePress(screen.getByRole('option', { name: '10 hours' })); - fireUserEvent.mousePress(screen.getByRole('option', { name: '9 hours' })); + await user.click(screen.getByRole('option', { name: '10 hours' })); + await user.click(screen.getByRole('option', { name: '9 hours' })); expect(onChange.callCount).to.equal(6); expect(onAccept.callCount).to.equal(0); expect(onClose.callCount).to.equal(0); // Change the minutes - fireUserEvent.mousePress(screen.getByRole('option', { name: '50 minutes' })); + await user.click(screen.getByRole('option', { name: '50 minutes' })); expect(onChange.callCount).to.equal(7); // Change the meridiem - fireUserEvent.mousePress(screen.getByRole('option', { name: 'PM' })); + await user.click(screen.getByRole('option', { name: 'PM' })); expect(onChange.callCount).to.equal(8); expect(onAccept.callCount).to.equal(1); expect(onClose.callCount).to.equal(1); }); describe('prop: timeSteps', () => { - it('should use "DigitalClock" view renderer, when "timeSteps.minutes" = 60', () => { + it('should use "DigitalClock" view renderer, when "timeSteps.minutes" = 60', async () => { const onChange = spy(); const onAccept = spy(); - render( + const { user } = render( , ); - fireUserEvent.mousePress(screen.getByLabelText(/Choose date/)); + await user.click(screen.getByLabelText(/Choose date/)); - fireUserEvent.mousePress(screen.getByRole('gridcell', { name: '2' })); - fireUserEvent.mousePress(screen.getByRole('option', { name: '03:00 AM' })); + await user.click(screen.getByRole('gridcell', { name: '2' })); + await user.click(screen.getByRole('option', { name: '03:00 AM' })); expect(onChange.callCount).to.equal(2); expect(onChange.lastCall.args[0]).toEqualDateTime(new Date(2018, 0, 2, 3, 0, 0)); expect(onAccept.callCount).to.equal(1); }); - it('should accept value and close picker when selecting time on "DigitalClock" view renderer', () => { + it('should accept value and close picker when selecting time on "DigitalClock" view renderer', async () => { const onChange = spy(); const onAccept = spy(); - render( + const { user } = render( , ); - fireUserEvent.mousePress(screen.getByLabelText(/Choose date/)); + await user.click(screen.getByLabelText(/Choose date/)); - fireUserEvent.mousePress(screen.getByRole('option', { name: '03:00 AM' })); + await user.click(screen.getByRole('option', { name: '03:00 AM' })); expect(onChange.callCount).to.equal(1); expect(onChange.lastCall.args[0]).toEqualDateTime(new Date(2018, 0, 1, 3, 0, 0)); diff --git a/packages/x-date-pickers/src/DesktopDateTimePicker/tests/describes.DesktopDateTimePicker.test.tsx b/packages/x-date-pickers/src/DesktopDateTimePicker/tests/describes.DesktopDateTimePicker.test.tsx index dc66bec63c58..c59e43a86486 100644 --- a/packages/x-date-pickers/src/DesktopDateTimePicker/tests/describes.DesktopDateTimePicker.test.tsx +++ b/packages/x-date-pickers/src/DesktopDateTimePicker/tests/describes.DesktopDateTimePicker.test.tsx @@ -1,4 +1,4 @@ -import { screen } from '@mui/internal-test-utils'; +import { fireEvent, screen } from '@mui/internal-test-utils'; import { createPickerRenderer, adapterToUse, @@ -12,7 +12,6 @@ import { DesktopDateTimePicker } from '@mui/x-date-pickers/DesktopDateTimePicker import { expect } from 'chai'; import * as React from 'react'; import { describeConformance } from 'test/utils/describeConformance'; -import { fireUserEvent } from 'test/utils/fireUserEvent'; describe(' - Describes', () => { const { render, clock } = createPickerRenderer({ clock: 'fake' }); @@ -85,24 +84,20 @@ describe(' - Describes', () => { : adapterToUse.addMinutes(adapterToUse.addHours(adapterToUse.addDays(value, 1), 1), 5); if (isOpened) { - fireUserEvent.mousePress( + fireEvent.click( screen.getByRole('gridcell', { name: adapterToUse.getDate(newValue).toString() }), ); const hasMeridiem = adapterToUse.is12HourCycleInCurrentLocale(); const hours = adapterToUse.format(newValue, hasMeridiem ? 'hours12h' : 'hours24h'); const hoursNumber = adapterToUse.getHours(newValue); - fireUserEvent.mousePress( - screen.getByRole('option', { name: `${parseInt(hours, 10)} hours` }), - ); - fireUserEvent.mousePress( + fireEvent.click(screen.getByRole('option', { name: `${parseInt(hours, 10)} hours` })); + fireEvent.click( screen.getByRole('option', { name: `${adapterToUse.getMinutes(newValue)} minutes` }), ); if (hasMeridiem) { // meridiem is an extra view on `DesktopDateTimePicker` // we need to click it to finish selection - fireUserEvent.mousePress( - screen.getByRole('option', { name: hoursNumber >= 12 ? 'PM' : 'AM' }), - ); + fireEvent.click(screen.getByRole('option', { name: hoursNumber >= 12 ? 'PM' : 'AM' })); } } else { selectSection('day'); diff --git a/packages/x-date-pickers/src/DesktopTimePicker/tests/DesktopTimePicker.test.tsx b/packages/x-date-pickers/src/DesktopTimePicker/tests/DesktopTimePicker.test.tsx index b60fa37d20fb..28663c2a7557 100644 --- a/packages/x-date-pickers/src/DesktopTimePicker/tests/DesktopTimePicker.test.tsx +++ b/packages/x-date-pickers/src/DesktopTimePicker/tests/DesktopTimePicker.test.tsx @@ -3,16 +3,15 @@ import { expect } from 'chai'; import { spy } from 'sinon'; import { screen } from '@mui/internal-test-utils'; import { DesktopTimePicker } from '@mui/x-date-pickers/DesktopTimePicker'; -import { createPickerRenderer, openPicker } from 'test/utils/pickers'; -import { fireUserEvent } from 'test/utils/fireUserEvent'; +import { adapterToUse, createPickerRenderer, openPicker } from 'test/utils/pickers'; describe('', () => { - const { render } = createPickerRenderer({ - clock: 'fake', - clockConfig: new Date('2018-01-01T10:05:05.000'), - }); - describe('rendering behavior', () => { + const { render } = createPickerRenderer({ + clock: 'fake', + clockConfig: new Date('2018-01-01T10:05:05.000'), + }); + it('should render "accept" action and 3 time sections by default', () => { render(); @@ -61,23 +60,26 @@ describe('', () => { }); describe('selecting behavior', () => { - it('should call "onAccept", "onChange", and "onClose" when selecting a single option', () => { + const { render } = createPickerRenderer(); + + it('should call "onAccept", "onChange", and "onClose" when selecting a single option', async () => { const onChange = spy(); const onAccept = spy(); const onClose = spy(); - render( + const { user } = render( , ); - openPicker({ type: 'time', variant: 'desktop' }); + await openPicker({ type: 'time', variant: 'desktop', click: user.click }); - fireUserEvent.mousePress(screen.getByRole('option', { name: '09:00 AM' })); + await user.click(screen.getByRole('option', { name: '09:00 AM' })); expect(onChange.callCount).to.equal(1); expect(onChange.lastCall.args[0]).toEqualDateTime(new Date(2018, 0, 1, 9, 0)); expect(onAccept.callCount).to.equal(1); @@ -85,73 +87,94 @@ describe('', () => { expect(onClose.callCount).to.equal(1); }); - it('should call "onAccept", "onChange", and "onClose" when selecting all section', () => { + it('should call "onAccept", "onChange", and "onClose" when selecting all section', async () => { const onChange = spy(); const onAccept = spy(); const onClose = spy(); - render(); + const { user } = render( + , + ); - openPicker({ type: 'time', variant: 'desktop' }); + await openPicker({ type: 'time', variant: 'desktop', click: user.click }); - fireUserEvent.mousePress(screen.getByRole('option', { name: '2 hours' })); + await user.click(screen.getByRole('option', { name: '2 hours' })); expect(onChange.callCount).to.equal(1); expect(onAccept.callCount).to.equal(0); expect(onClose.callCount).to.equal(0); - fireUserEvent.mousePress(screen.getByRole('option', { name: '15 minutes' })); + await user.click(screen.getByRole('option', { name: '15 minutes' })); expect(onChange.callCount).to.equal(2); expect(onAccept.callCount).to.equal(0); expect(onClose.callCount).to.equal(0); - fireUserEvent.mousePress(screen.getByRole('option', { name: 'PM' })); + await user.click(screen.getByRole('option', { name: 'PM' })); expect(onChange.callCount).to.equal(3); expect(onAccept.callCount).to.equal(1); expect(onAccept.lastCall.args[0]).toEqualDateTime(new Date(2018, 0, 1, 14, 15)); expect(onClose.callCount).to.equal(1); }); - it('should allow out of order section selection', () => { + it('should allow out of order section selection', async () => { const onChange = spy(); const onAccept = spy(); const onClose = spy(); - render(); + const { user } = render( + , + ); - openPicker({ type: 'time', variant: 'desktop' }); + await openPicker({ type: 'time', variant: 'desktop', click: user.click }); - fireUserEvent.mousePress(screen.getByRole('option', { name: '15 minutes' })); + await user.click(screen.getByRole('option', { name: '15 minutes' })); expect(onChange.callCount).to.equal(1); expect(onAccept.callCount).to.equal(0); expect(onClose.callCount).to.equal(0); - fireUserEvent.mousePress(screen.getByRole('option', { name: '2 hours' })); + await user.click(screen.getByRole('option', { name: '2 hours' })); expect(onChange.callCount).to.equal(2); expect(onAccept.callCount).to.equal(0); expect(onClose.callCount).to.equal(0); - fireUserEvent.mousePress(screen.getByRole('option', { name: '25 minutes' })); + await user.click(screen.getByRole('option', { name: '25 minutes' })); expect(onChange.callCount).to.equal(3); expect(onAccept.callCount).to.equal(0); expect(onClose.callCount).to.equal(0); - fireUserEvent.mousePress(screen.getByRole('option', { name: 'PM' })); + await user.click(screen.getByRole('option', { name: 'PM' })); expect(onChange.callCount).to.equal(4); expect(onAccept.callCount).to.equal(1); expect(onAccept.lastCall.args[0]).toEqualDateTime(new Date(2018, 0, 1, 14, 25)); expect(onClose.callCount).to.equal(1); }); - it('should finish selection when selecting only the last section', () => { + it('should finish selection when selecting only the last section', async () => { const onChange = spy(); const onAccept = spy(); const onClose = spy(); - render(); + const { user } = render( + , + ); - openPicker({ type: 'time', variant: 'desktop' }); + await openPicker({ type: 'time', variant: 'desktop', click: user.click }); - fireUserEvent.mousePress(screen.getByRole('option', { name: 'PM' })); + await user.click(screen.getByRole('option', { name: 'PM' })); expect(onChange.callCount).to.equal(1); expect(onAccept.callCount).to.equal(1); expect(onAccept.lastCall.args[0]).toEqualDateTime(new Date(2018, 0, 1, 12, 0)); diff --git a/packages/x-date-pickers/src/DesktopTimePicker/tests/describes.DesktopTimePicker.test.tsx b/packages/x-date-pickers/src/DesktopTimePicker/tests/describes.DesktopTimePicker.test.tsx index 2fe4730f6fd1..7d4652b6c4df 100644 --- a/packages/x-date-pickers/src/DesktopTimePicker/tests/describes.DesktopTimePicker.test.tsx +++ b/packages/x-date-pickers/src/DesktopTimePicker/tests/describes.DesktopTimePicker.test.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { screen } from '@mui/internal-test-utils'; +import { fireEvent, screen } from '@mui/internal-test-utils'; import { createPickerRenderer, adapterToUse, @@ -12,7 +12,6 @@ import { } from 'test/utils/pickers'; import { DesktopTimePicker } from '@mui/x-date-pickers/DesktopTimePicker'; import { describeConformance } from 'test/utils/describeConformance'; -import { fireUserEvent } from 'test/utils/fireUserEvent'; describe(' - Describes', () => { const { render, clock } = createPickerRenderer({ clock: 'fake' }); @@ -77,18 +76,14 @@ describe(' - Describes', () => { const hasMeridiem = adapterToUse.is12HourCycleInCurrentLocale(); const hours = adapterToUse.format(newValue, hasMeridiem ? 'hours12h' : 'hours24h'); const hoursNumber = adapterToUse.getHours(newValue); - fireUserEvent.mousePress( - screen.getByRole('option', { name: `${parseInt(hours, 10)} hours` }), - ); - fireUserEvent.mousePress( + fireEvent.click(screen.getByRole('option', { name: `${parseInt(hours, 10)} hours` })); + fireEvent.click( screen.getByRole('option', { name: `${adapterToUse.getMinutes(newValue)} minutes` }), ); if (hasMeridiem) { // meridiem is an extra view on `DesktopTimePicker` // we need to click it to finish selection - fireUserEvent.mousePress( - screen.getByRole('option', { name: hoursNumber >= 12 ? 'PM' : 'AM' }), - ); + fireEvent.click(screen.getByRole('option', { name: hoursNumber >= 12 ? 'PM' : 'AM' })); } } else { selectSection('hours'); diff --git a/packages/x-date-pickers/src/DigitalClock/tests/timezone.DigitalClock.test.tsx b/packages/x-date-pickers/src/DigitalClock/tests/timezone.DigitalClock.test.tsx index 070c9b9243f5..5d7a0aa650d8 100644 --- a/packages/x-date-pickers/src/DigitalClock/tests/timezone.DigitalClock.test.tsx +++ b/packages/x-date-pickers/src/DigitalClock/tests/timezone.DigitalClock.test.tsx @@ -1,10 +1,9 @@ import * as React from 'react'; import { spy } from 'sinon'; import { expect } from 'chai'; -import { screen } from '@mui/internal-test-utils'; +import { fireEvent, screen } from '@mui/internal-test-utils'; import { DigitalClock } from '@mui/x-date-pickers/DigitalClock'; import { getDateOffset, describeAdapters } from 'test/utils/pickers'; -import { fireUserEvent } from 'test/utils/fireUserEvent'; const TIMEZONE_TO_TEST = ['UTC', 'system', 'America/New_York']; @@ -26,7 +25,7 @@ describe(' - Timezone', () => { const onChange = spy(); render(); - fireUserEvent.mousePress(screen.getByRole('option', { name: '08:00 AM' })); + fireEvent.click(screen.getByRole('option', { name: '08:00 AM' })); const expectedDate = adapter.setHours(adapter.date(), 8); @@ -45,7 +44,7 @@ describe(' - Timezone', () => { const onChange = spy(); render(); - fireUserEvent.mousePress(screen.getByRole('option', { name: '08:00 AM' })); + fireEvent.click(screen.getByRole('option', { name: '08:00 AM' })); const expectedDate = adapter.setHours( adapter.startOfDay(adapter.date(undefined, timezone)), @@ -76,7 +75,7 @@ describe(' - Timezone', () => { (adapter.getHours(value) + offsetDiff / 60 + 24) % 24, ); - fireUserEvent.mousePress(screen.getByRole('option', { name: '08:30 PM' })); + fireEvent.click(screen.getByRole('option', { name: '08:30 PM' })); const actualDate = onChange.lastCall.firstArg; diff --git a/packages/x-date-pickers/src/MobileDatePicker/tests/MobileDatePicker.test.tsx b/packages/x-date-pickers/src/MobileDatePicker/tests/MobileDatePicker.test.tsx index 3dc67b806538..8491613b2622 100644 --- a/packages/x-date-pickers/src/MobileDatePicker/tests/MobileDatePicker.test.tsx +++ b/packages/x-date-pickers/src/MobileDatePicker/tests/MobileDatePicker.test.tsx @@ -13,7 +13,6 @@ import { openPicker, getFieldSectionsContainer, } from 'test/utils/pickers'; -import { fireUserEvent } from 'test/utils/fireUserEvent'; describe('', () => { const { render, clock } = createPickerRenderer({ clock: 'fake' }); @@ -156,7 +155,7 @@ describe('', () => { render(); - fireUserEvent.mousePress(getFieldSectionsContainer()); + fireEvent.click(getFieldSectionsContainer()); expect(onOpen.callCount).to.equal(1); expect(screen.queryByRole('dialog')).toBeVisible(); diff --git a/packages/x-date-pickers/src/MobileDatePicker/tests/describes.MobileDatePicker.test.tsx b/packages/x-date-pickers/src/MobileDatePicker/tests/describes.MobileDatePicker.test.tsx index b988c49e5827..431e6682e182 100644 --- a/packages/x-date-pickers/src/MobileDatePicker/tests/describes.MobileDatePicker.test.tsx +++ b/packages/x-date-pickers/src/MobileDatePicker/tests/describes.MobileDatePicker.test.tsx @@ -12,7 +12,6 @@ import { } from 'test/utils/pickers'; import { MobileDatePicker } from '@mui/x-date-pickers/MobileDatePicker'; import { describeConformance } from 'test/utils/describeConformance'; -import { fireUserEvent } from 'test/utils/fireUserEvent'; describe(' - Describes', () => { const { render, clock } = createPickerRenderer({ clock: 'fake' }); @@ -65,7 +64,7 @@ describe(' - Describes', () => { } const newValue = applySameValue ? value : adapterToUse.addDays(value, 1); - fireUserEvent.mousePress( + fireEvent.click( screen.getByRole('gridcell', { name: adapterToUse.getDate(newValue).toString() }), ); diff --git a/packages/x-date-pickers/src/MobileDateTimePicker/tests/MobileDateTimePicker.test.tsx b/packages/x-date-pickers/src/MobileDateTimePicker/tests/MobileDateTimePicker.test.tsx index 34849b1b5dc0..1e21c3dbc935 100644 --- a/packages/x-date-pickers/src/MobileDateTimePicker/tests/MobileDateTimePicker.test.tsx +++ b/packages/x-date-pickers/src/MobileDateTimePicker/tests/MobileDateTimePicker.test.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { expect } from 'chai'; import { spy } from 'sinon'; -import { fireTouchChangedEvent, screen } from '@mui/internal-test-utils'; +import { fireEvent, fireTouchChangedEvent, screen } from '@mui/internal-test-utils'; import { MobileDateTimePicker } from '@mui/x-date-pickers/MobileDateTimePicker'; import { adapterToUse, @@ -10,7 +10,6 @@ import { getClockTouchEvent, getFieldSectionsContainer, } from 'test/utils/pickers'; -import { fireUserEvent } from 'test/utils/fireUserEvent'; describe('', () => { const { render, clock } = createPickerRenderer({ clock: 'fake' }); @@ -99,7 +98,7 @@ describe('', () => { render(); - fireUserEvent.mousePress(getFieldSectionsContainer()); + fireEvent.click(getFieldSectionsContainer()); expect(onOpen.callCount).to.equal(1); expect(screen.queryByRole('dialog')).toBeVisible(); @@ -132,8 +131,8 @@ describe('', () => { expect(onClose.callCount).to.equal(0); // Change the year view - fireUserEvent.mousePress(screen.getByLabelText(/switch to year view/)); - fireUserEvent.mousePress(screen.getByText('2010', { selector: 'button' })); + fireEvent.click(screen.getByLabelText(/switch to year view/)); + fireEvent.click(screen.getByText('2010', { selector: 'button' })); expect(onChange.callCount).to.equal(1); expect(onChange.lastCall.args[0]).toEqualDateTime(new Date(2010, 0, 1)); @@ -141,7 +140,7 @@ describe('', () => { clock.runToLast(); // Change the date - fireUserEvent.mousePress(screen.getByRole('gridcell', { name: '15' })); + fireEvent.click(screen.getByRole('gridcell', { name: '15' })); expect(onChange.callCount).to.equal(2); expect(onChange.lastCall.args[0]).toEqualDateTime(new Date(2010, 0, 15)); diff --git a/packages/x-date-pickers/src/MobileDateTimePicker/tests/describes.MobileDateTimePicker.test.tsx b/packages/x-date-pickers/src/MobileDateTimePicker/tests/describes.MobileDateTimePicker.test.tsx index 7db743bb1c2e..49ebb8d55837 100644 --- a/packages/x-date-pickers/src/MobileDateTimePicker/tests/describes.MobileDateTimePicker.test.tsx +++ b/packages/x-date-pickers/src/MobileDateTimePicker/tests/describes.MobileDateTimePicker.test.tsx @@ -13,7 +13,6 @@ import { } from 'test/utils/pickers'; import { MobileDateTimePicker } from '@mui/x-date-pickers/MobileDateTimePicker'; import { describeConformance } from 'test/utils/describeConformance'; -import { fireUserEvent } from 'test/utils/fireUserEvent'; describe(' - Describes', () => { const { render, clock } = createPickerRenderer({ @@ -79,7 +78,7 @@ describe(' - Describes', () => { const newValue = applySameValue ? value : adapterToUse.addMinutes(adapterToUse.addHours(adapterToUse.addDays(value, 1), 1), 5); - fireUserEvent.mousePress( + fireEvent.click( screen.getByRole('gridcell', { name: adapterToUse.getDate(newValue).toString() }), ); const hasMeridiem = adapterToUse.is12HourCycleInCurrentLocale(); @@ -98,9 +97,7 @@ describe(' - Describes', () => { if (hasMeridiem) { const newHours = adapterToUse.getHours(newValue); // select appropriate meridiem - fireUserEvent.mousePress( - screen.getByRole('button', { name: newHours >= 12 ? 'PM' : 'AM' }), - ); + fireEvent.click(screen.getByRole('button', { name: newHours >= 12 ? 'PM' : 'AM' })); } // Close the picker @@ -110,7 +107,7 @@ describe(' - Describes', () => { clock.runToLast(); } else { // return to the date view in case we'd like to repeat the selection process - fireUserEvent.mousePress(screen.getByRole('tab', { name: 'pick date' })); + fireEvent.click(screen.getByRole('tab', { name: 'pick date' })); } return newValue; diff --git a/packages/x-date-pickers/src/MobileTimePicker/tests/MobileTimePicker.test.tsx b/packages/x-date-pickers/src/MobileTimePicker/tests/MobileTimePicker.test.tsx index 16e28b5b3c29..62d073d3c10c 100644 --- a/packages/x-date-pickers/src/MobileTimePicker/tests/MobileTimePicker.test.tsx +++ b/packages/x-date-pickers/src/MobileTimePicker/tests/MobileTimePicker.test.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { spy } from 'sinon'; import { expect } from 'chai'; -import { fireTouchChangedEvent, screen, act } from '@mui/internal-test-utils'; +import { fireTouchChangedEvent, screen } from '@mui/internal-test-utils'; import { MobileTimePicker } from '@mui/x-date-pickers/MobileTimePicker'; import { createPickerRenderer, @@ -10,26 +10,27 @@ import { getClockTouchEvent, getFieldSectionsContainer, } from 'test/utils/pickers'; -import { fireUserEvent } from 'test/utils/fireUserEvent'; describe('', () => { - const { render } = createPickerRenderer({ clock: 'fake' }); + const { render } = createPickerRenderer(); describe('picker state', () => { - it('should open when clicking the input', () => { + it('should open when clicking the input', async () => { const onOpen = spy(); - render(); + const { user } = render( + , + ); - fireUserEvent.mousePress(getFieldSectionsContainer()); + await user.click(getFieldSectionsContainer()); expect(onOpen.callCount).to.equal(1); expect(screen.queryByRole('dialog')).toBeVisible(); }); - it('should fire a change event when meridiem changes', () => { + it('should fire a change event when meridiem changes', async () => { const handleChange = spy(); - render( + const { user } = render( ', () => { ); const buttonPM = screen.getByRole('button', { name: 'PM' }); - act(() => { - buttonPM.click(); - }); + await user.click(buttonPM); expect(handleChange.callCount).to.equal(1); expect(handleChange.firstCall.args[0]).toEqualDateTime(new Date(2019, 0, 1, 16, 20)); }); - it('should call onChange when selecting each view', function test() { + it('should call onChange when selecting each view', async function test() { if (typeof window.Touch === 'undefined' || typeof window.TouchEvent === 'undefined') { this.skip(); } @@ -59,7 +58,7 @@ describe('', () => { const onClose = spy(); const defaultValue = adapterToUse.date('2018-01-01'); - render( + const { user } = render( ', () => { />, ); - openPicker({ type: 'time', variant: 'mobile' }); + await openPicker({ type: 'time', variant: 'mobile', click: user.click }); // Change the hours const hourClockEvent = getClockTouchEvent(11, '12hours'); diff --git a/packages/x-date-pickers/src/MobileTimePicker/tests/describes.MobileTimePicker.test.tsx b/packages/x-date-pickers/src/MobileTimePicker/tests/describes.MobileTimePicker.test.tsx index 8a694129a784..b3fa12461d7b 100644 --- a/packages/x-date-pickers/src/MobileTimePicker/tests/describes.MobileTimePicker.test.tsx +++ b/packages/x-date-pickers/src/MobileTimePicker/tests/describes.MobileTimePicker.test.tsx @@ -14,7 +14,6 @@ import { } from 'test/utils/pickers'; import { MobileTimePicker } from '@mui/x-date-pickers/MobileTimePicker'; import { describeConformance } from 'test/utils/describeConformance'; -import { fireUserEvent } from 'test/utils/fireUserEvent'; describe(' - Describes', () => { const { render, clock } = createPickerRenderer({ @@ -93,9 +92,7 @@ describe(' - Describes', () => { if (hasMeridiem) { const newHours = adapterToUse.getHours(newValue); // select appropriate meridiem - fireUserEvent.mousePress( - screen.getByRole('button', { name: newHours >= 12 ? 'PM' : 'AM' }), - ); + fireEvent.click(screen.getByRole('button', { name: newHours >= 12 ? 'PM' : 'AM' })); } // Close the picker @@ -105,7 +102,7 @@ describe(' - Describes', () => { clock.runToLast(); } else { // return to the hours view in case we'd like to repeat the selection process - fireUserEvent.mousePress(screen.getByRole('button', { name: 'Open previous view' })); + fireEvent.click(screen.getByRole('button', { name: 'Open previous view' })); } return newValue; diff --git a/packages/x-date-pickers/src/MonthCalendar/tests/describes.MonthCalendar.test.tsx b/packages/x-date-pickers/src/MonthCalendar/tests/describes.MonthCalendar.test.tsx index ef370265decd..2f289f70a552 100644 --- a/packages/x-date-pickers/src/MonthCalendar/tests/describes.MonthCalendar.test.tsx +++ b/packages/x-date-pickers/src/MonthCalendar/tests/describes.MonthCalendar.test.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import { expect } from 'chai'; -import { screen } from '@mui/internal-test-utils'; +import { fireEvent, screen } from '@mui/internal-test-utils'; import { createPickerRenderer, adapterToUse, @@ -9,7 +9,6 @@ import { } from 'test/utils/pickers'; import { MonthCalendar, monthCalendarClasses as classes } from '@mui/x-date-pickers/MonthCalendar'; import { describeConformance } from 'test/utils/describeConformance'; -import { fireUserEvent } from 'test/utils/fireUserEvent'; describe(' - Describes', () => { const { render, clock } = createPickerRenderer({ clock: 'fake' }); @@ -55,9 +54,7 @@ describe(' - Describes', () => { setNewValue: (value) => { const newValue = adapterToUse.addMonths(value, 1); - fireUserEvent.mousePress( - screen.getByRole('radio', { name: adapterToUse.format(newValue, 'month') }), - ); + fireEvent.click(screen.getByRole('radio', { name: adapterToUse.format(newValue, 'month') })); return newValue; }, diff --git a/packages/x-date-pickers/src/PickersActionBar/PickersActionBar.test.tsx b/packages/x-date-pickers/src/PickersActionBar/PickersActionBar.test.tsx index 465baad26cee..58d3b35893ac 100644 --- a/packages/x-date-pickers/src/PickersActionBar/PickersActionBar.test.tsx +++ b/packages/x-date-pickers/src/PickersActionBar/PickersActionBar.test.tsx @@ -4,12 +4,9 @@ import { spy } from 'sinon'; import { screen } from '@mui/internal-test-utils'; import { PickersActionBar } from '@mui/x-date-pickers/PickersActionBar'; import { createPickerRenderer } from 'test/utils/pickers'; -import { fireUserEvent } from 'test/utils/fireUserEvent'; describe('', () => { - const { render } = createPickerRenderer({ - clock: 'fake', - }); + const { render } = createPickerRenderer(); it('should not render buttons if actions array is empty', () => { const onAccept = () => {}; @@ -29,13 +26,13 @@ describe('', () => { expect(screen.queryByRole('button')).to.equal(null); }); - it('should render button for "clear" action calling the associated callback', () => { + it('should render button for "clear" action calling the associated callback', async () => { const onAccept = spy(); const onClear = spy(); const onCancel = spy(); const onSetToday = spy(); - render( + const { user } = render( ', () => { />, ); - fireUserEvent.mousePress(screen.getByText(/clear/i)); + await user.click(screen.getByText(/clear/i)); expect(onClear.callCount).to.equal(1); }); - it('should render button for "cancel" action calling the associated callback', () => { + it('should render button for "cancel" action calling the associated callback', async () => { const onAccept = spy(); const onClear = spy(); const onCancel = spy(); const onSetToday = spy(); - render( + const { user } = render( ', () => { />, ); - fireUserEvent.mousePress(screen.getByText(/cancel/i)); + await user.click(screen.getByText(/cancel/i)); expect(onCancel.callCount).to.equal(1); }); - it('should render button for "accept" action calling the associated callback', () => { + it('should render button for "accept" action calling the associated callback', async () => { const onAccept = spy(); const onClear = spy(); const onCancel = spy(); const onSetToday = spy(); - render( + const { user } = render( ', () => { />, ); - fireUserEvent.mousePress(screen.getByText(/ok/i)); + await user.click(screen.getByText(/ok/i)); expect(onAccept.callCount).to.equal(1); }); - it('should render button for "today" action calling the associated callback', () => { + it('should render button for "today" action calling the associated callback', async () => { const onAccept = spy(); const onClear = spy(); const onCancel = spy(); const onSetToday = spy(); - render( + const { user } = render( ', () => { />, ); - fireUserEvent.mousePress(screen.getByText(/today/i)); + await user.click(screen.getByText(/today/i)); expect(onSetToday.callCount).to.equal(1); }); diff --git a/packages/x-date-pickers/src/YearCalendar/tests/describes.YearCalendar.test.tsx b/packages/x-date-pickers/src/YearCalendar/tests/describes.YearCalendar.test.tsx index 87eeb7fee9f4..06c4de6035f4 100644 --- a/packages/x-date-pickers/src/YearCalendar/tests/describes.YearCalendar.test.tsx +++ b/packages/x-date-pickers/src/YearCalendar/tests/describes.YearCalendar.test.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import { expect } from 'chai'; -import { screen } from '@mui/internal-test-utils'; +import { fireEvent, screen } from '@mui/internal-test-utils'; import { YearCalendar, yearCalendarClasses as classes } from '@mui/x-date-pickers/YearCalendar'; import { createPickerRenderer, @@ -9,7 +9,6 @@ import { describeValue, } from 'test/utils/pickers'; import { describeConformance } from 'test/utils/describeConformance'; -import { fireUserEvent } from 'test/utils/fireUserEvent'; describe(' - Describes', () => { const { render, clock } = createPickerRenderer({ @@ -52,7 +51,7 @@ describe(' - Describes', () => { }, setNewValue: (value) => { const newValue = adapterToUse.addYears(value, 1); - fireUserEvent.mousePress( + fireEvent.click( screen.getByRole('radio', { name: adapterToUse.getYear(newValue).toString() }), ); diff --git a/packages/x-date-pickers/src/tests/materialVersion.test.tsx b/packages/x-date-pickers/src/tests/materialVersion.test.tsx new file mode 100644 index 000000000000..dc0c0a7e6ee0 --- /dev/null +++ b/packages/x-date-pickers/src/tests/materialVersion.test.tsx @@ -0,0 +1,5 @@ +import materialPackageJson from '@mui/material/package.json'; +import { checkMaterialVersion } from 'test/utils/checkMaterialVersion'; +import packageJson from '../../package.json'; + +checkMaterialVersion({ packageJson, materialPackageJson }); diff --git a/packages/x-tree-view-pro/package.json b/packages/x-tree-view-pro/package.json index 5db48bc3e193..02c6ae99d1a9 100644 --- a/packages/x-tree-view-pro/package.json +++ b/packages/x-tree-view-pro/package.json @@ -44,7 +44,6 @@ }, "dependencies": { "@babel/runtime": "^7.25.4", - "@mui/system": "^5.16.7", "@mui/utils": "^5.16.6", "@mui/x-internals": "workspace:*", "@mui/x-license": "workspace:*", @@ -57,7 +56,8 @@ "peerDependencies": { "@emotion/react": "^11.9.0", "@emotion/styled": "^11.8.1", - "@mui/material": "^5.15.14", + "@mui/material": "^5.15.14 || ^6.0.0", + "@mui/system": "^5.15.14 || ^6.0.0", "react": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0" }, @@ -71,6 +71,8 @@ }, "devDependencies": { "@mui/internal-test-utils": "^1.0.10", + "@mui/material": "^5.16.5", + "@mui/system": "^5.16.7", "@types/prop-types": "^15.7.12", "rimraf": "^5.0.10" }, diff --git a/packages/x-tree-view-pro/src/tests/materialVersion.test.tsx b/packages/x-tree-view-pro/src/tests/materialVersion.test.tsx new file mode 100644 index 000000000000..dc0c0a7e6ee0 --- /dev/null +++ b/packages/x-tree-view-pro/src/tests/materialVersion.test.tsx @@ -0,0 +1,5 @@ +import materialPackageJson from '@mui/material/package.json'; +import { checkMaterialVersion } from 'test/utils/checkMaterialVersion'; +import packageJson from '../../package.json'; + +checkMaterialVersion({ packageJson, materialPackageJson }); diff --git a/packages/x-tree-view/package.json b/packages/x-tree-view/package.json index 520e0c882539..a3b4f8ebc43e 100644 --- a/packages/x-tree-view/package.json +++ b/packages/x-tree-view/package.json @@ -44,7 +44,6 @@ }, "dependencies": { "@babel/runtime": "^7.25.4", - "@mui/system": "^5.16.7", "@mui/utils": "^5.16.6", "@mui/x-internals": "workspace:*", "@types/react-transition-group": "^4.4.11", @@ -55,7 +54,8 @@ "peerDependencies": { "@emotion/react": "^11.9.0", "@emotion/styled": "^11.8.1", - "@mui/material": "^5.15.14", + "@mui/material": "^5.15.14 || ^6.0.0", + "@mui/system": "^5.15.14 || ^6.0.0", "react": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0" }, @@ -69,6 +69,8 @@ }, "devDependencies": { "@mui/internal-test-utils": "^1.0.10", + "@mui/material": "^5.16.5", + "@mui/system": "^5.16.7", "@types/prop-types": "^15.7.12", "rimraf": "^5.0.10" }, diff --git a/packages/x-tree-view/src/tests/materialVersion.test.tsx b/packages/x-tree-view/src/tests/materialVersion.test.tsx new file mode 100644 index 000000000000..dc0c0a7e6ee0 --- /dev/null +++ b/packages/x-tree-view/src/tests/materialVersion.test.tsx @@ -0,0 +1,5 @@ +import materialPackageJson from '@mui/material/package.json'; +import { checkMaterialVersion } from 'test/utils/checkMaterialVersion'; +import packageJson from '../../package.json'; + +checkMaterialVersion({ packageJson, materialPackageJson }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3150f4133589..a377b74e87df 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -717,12 +717,6 @@ importers: '@emotion/styled': specifier: ^11.8.1 version: 11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1) - '@mui/material': - specifier: ^5.15.14 - version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@mui/system': - specifier: ^5.16.7 - version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1) '@mui/utils': specifier: ^5.16.6 version: 5.16.6(@types/react@18.3.4)(react@18.3.1) @@ -751,6 +745,12 @@ importers: '@mui/internal-test-utils': specifier: ^1.0.10 version: 1.0.10(@babel/core@7.25.2)(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/material': + specifier: ^5.16.5 + version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/system': + specifier: ^5.16.7 + version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1) '@react-spring/core': specifier: ^9.7.4 version: 9.7.4(react@18.3.1) @@ -779,12 +779,6 @@ importers: '@emotion/styled': specifier: ^11.8.1 version: 11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1) - '@mui/material': - specifier: ^5.15.14 - version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@mui/system': - specifier: ^5.16.7 - version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1) '@mui/utils': specifier: ^5.16.6 version: 5.16.6(@types/react@18.3.4)(react@18.3.1) @@ -816,6 +810,12 @@ importers: specifier: ^17.0.0 || ^18.0.0 version: 18.3.1(react@18.3.1) devDependencies: + '@mui/material': + specifier: ^5.16.5 + version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/system': + specifier: ^5.16.7 + version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1) '@react-spring/core': specifier: ^9.7.4 version: 9.7.4(react@18.3.1) @@ -961,12 +961,6 @@ importers: '@emotion/styled': specifier: ^11.8.1 version: 11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1) - '@mui/material': - specifier: ^5.15.14 - version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@mui/system': - specifier: ^5.16.7 - version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1) '@mui/utils': specifier: ^5.16.6 version: 5.16.6(@types/react@18.3.4)(react@18.3.1) @@ -995,6 +989,12 @@ importers: '@mui/joy': specifier: ^5.0.0-beta.48 version: 5.0.0-beta.48(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/material': + specifier: ^5.16.5 + version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/system': + specifier: ^5.16.7 + version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1) '@mui/types': specifier: ^7.2.15 version: 7.2.15(@types/react@18.3.4) @@ -1017,12 +1017,6 @@ importers: '@emotion/styled': specifier: ^11.8.1 version: 11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1) - '@mui/icons-material': - specifier: ^5.4.1 - version: 5.16.7(@mui/material@5.16.7(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.4)(react@18.3.1) - '@mui/material': - specifier: ^5.15.14 - version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mui/x-data-grid-premium': specifier: workspace:* version: link:../x-data-grid-premium/build @@ -1039,6 +1033,12 @@ importers: specifier: ^17.0.0 || ^18.0.0 version: 18.3.1 devDependencies: + '@mui/icons-material': + specifier: ^5.16.5 + version: 5.16.7(@mui/material@5.16.7(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.4)(react@18.3.1) + '@mui/material': + specifier: ^5.16.5 + version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@types/chance': specifier: ^1.1.6 version: 1.1.6 @@ -1058,12 +1058,6 @@ importers: '@emotion/styled': specifier: ^11.8.1 version: 11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1) - '@mui/material': - specifier: ^5.15.14 - version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@mui/system': - specifier: ^5.16.7 - version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1) '@mui/utils': specifier: ^5.16.6 version: 5.16.6(@types/react@18.3.4)(react@18.3.1) @@ -1104,6 +1098,12 @@ importers: '@mui/internal-test-utils': specifier: ^1.0.10 version: 1.0.10(@babel/core@7.25.2)(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/material': + specifier: ^5.16.5 + version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/system': + specifier: ^5.16.7 + version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1) '@types/prop-types': specifier: ^15.7.12 version: 15.7.12 @@ -1126,12 +1126,6 @@ importers: '@emotion/styled': specifier: ^11.8.1 version: 11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1) - '@mui/material': - specifier: ^5.15.14 - version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@mui/system': - specifier: ^5.16.7 - version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1) '@mui/utils': specifier: ^5.16.6 version: 5.16.6(@types/react@18.3.4)(react@18.3.1) @@ -1166,6 +1160,12 @@ importers: '@mui/internal-test-utils': specifier: ^1.0.10 version: 1.0.10(@babel/core@7.25.2)(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/material': + specifier: ^5.16.5 + version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/system': + specifier: ^5.16.7 + version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1) '@types/prop-types': specifier: ^15.7.12 version: 15.7.12 @@ -1185,12 +1185,6 @@ importers: '@emotion/styled': specifier: ^11.8.1 version: 11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1) - '@mui/material': - specifier: ^5.15.14 - version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@mui/system': - specifier: ^5.16.7 - version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1) '@mui/utils': specifier: ^5.16.6 version: 5.16.6(@types/react@18.3.4)(react@18.3.1) @@ -1216,6 +1210,12 @@ importers: '@mui/internal-test-utils': specifier: ^1.0.10 version: 1.0.10(@babel/core@7.25.2)(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/material': + specifier: ^5.16.5 + version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/system': + specifier: ^5.16.7 + version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1) '@types/luxon': specifier: ^3.4.2 version: 3.4.2 @@ -1268,12 +1268,6 @@ importers: '@emotion/styled': specifier: ^11.8.1 version: 11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1) - '@mui/material': - specifier: ^5.15.14 - version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@mui/system': - specifier: ^5.16.7 - version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1) '@mui/utils': specifier: ^5.16.6 version: 5.16.6(@types/react@18.3.4)(react@18.3.1) @@ -1308,6 +1302,12 @@ importers: '@mui/internal-test-utils': specifier: ^1.0.10 version: 1.0.10(@babel/core@7.25.2)(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/material': + specifier: ^5.16.5 + version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/system': + specifier: ^5.16.7 + version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1) '@types/luxon': specifier: ^3.4.2 version: 3.4.2 @@ -1385,12 +1385,6 @@ importers: '@emotion/styled': specifier: ^11.8.1 version: 11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1) - '@mui/material': - specifier: ^5.15.14 - version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@mui/system': - specifier: ^5.16.7 - version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1) '@mui/utils': specifier: ^5.16.6 version: 5.16.6(@types/react@18.3.4)(react@18.3.1) @@ -1419,6 +1413,12 @@ importers: '@mui/internal-test-utils': specifier: ^1.0.10 version: 1.0.10(@babel/core@7.25.2)(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/material': + specifier: ^5.16.5 + version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/system': + specifier: ^5.16.7 + version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1) '@types/prop-types': specifier: ^15.7.12 version: 15.7.12 @@ -1438,12 +1438,6 @@ importers: '@emotion/styled': specifier: ^11.8.1 version: 11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1) - '@mui/material': - specifier: ^5.15.14 - version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@mui/system': - specifier: ^5.16.7 - version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1) '@mui/utils': specifier: ^5.16.6 version: 5.16.6(@types/react@18.3.4)(react@18.3.1) @@ -1478,6 +1472,12 @@ importers: '@mui/internal-test-utils': specifier: ^1.0.10 version: 1.0.10(@babel/core@7.25.2)(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/material': + specifier: ^5.16.5 + version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/system': + specifier: ^5.16.7 + version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1))(@types/react@18.3.4)(react@18.3.1) '@types/prop-types': specifier: ^15.7.12 version: 15.7.12 @@ -1545,6 +1545,9 @@ importers: '@types/react': specifier: ^18.3.4 version: 18.3.4 + '@types/semver': + specifier: ^7.5.8 + version: 7.5.8 chai: specifier: ^4.5.0 version: 4.5.0 @@ -1569,6 +1572,9 @@ importers: react-router-dom: specifier: ^6.26.1 version: 6.26.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + semver: + specifier: ^7.6.3 + version: 7.6.3 stylis: specifier: ^4.3.2 version: 4.3.2 @@ -3031,8 +3037,8 @@ packages: '@jridgewell/source-map@0.3.5': resolution: {integrity: sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==} - '@jridgewell/sourcemap-codec@1.4.15': - resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} @@ -3045,7 +3051,7 @@ packages: resolution: {integrity: sha512-I/lGHztkCzvwlXpjD2+SNmvNQvB4227xBXhISPjEaJUXGImOQ9f3D2Yj/T3KasSI/h0MLWy74X0J6clhPmsRbQ==} engines: {node: '>=12.0.0'} peerDependencies: - '@types/react': ^17.0.0 || ^18.0.0 + '@types/react': 18.3.3 react: ^17.0.0 || ^18.0.0 react-dom: ^17.0.0 || ^18.0.0 peerDependenciesMeta: @@ -5038,8 +5044,8 @@ packages: resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} engines: {node: '>= 16'} - chokidar@3.5.3: - resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} chownr@2.0.0: @@ -7546,8 +7552,8 @@ packages: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} hasBin: true - magic-string@0.30.10: - resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} + magic-string@0.30.11: + resolution: {integrity: sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==} make-array@1.0.5: resolution: {integrity: sha512-sgK2SAzxT19rWU+qxKUcn6PAh/swiIiz2F8C2cZjLc1z4iwYIfdoihqFIDQ8BDzAGtWPYJ6Sr13K1j/DXynDLA==} @@ -8341,8 +8347,8 @@ packages: path-to-regexp@2.2.1: resolution: {integrity: sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ==} - path-to-regexp@6.2.1: - resolution: {integrity: sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==} + path-to-regexp@6.2.2: + resolution: {integrity: sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==} path-type@3.0.0: resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==} @@ -10312,7 +10318,7 @@ snapshots: slash: 2.0.0 optionalDependencies: '@nicolo-ribaudo/chokidar-2': 2.1.8-no-fsevents.3 - chokidar: 3.5.3 + chokidar: 3.6.0 '@babel/code-frame@7.24.7': dependencies: @@ -11714,7 +11720,7 @@ snapshots: '@jridgewell/gen-mapping@0.3.5': dependencies: '@jridgewell/set-array': 1.2.1 - '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/sourcemap-codec': 1.5.0 '@jridgewell/trace-mapping': 0.3.25 '@jridgewell/resolve-uri@3.1.1': {} @@ -11726,12 +11732,12 @@ snapshots: '@jridgewell/gen-mapping': 0.3.5 '@jridgewell/trace-mapping': 0.3.25 - '@jridgewell/sourcemap-codec@1.4.15': {} + '@jridgewell/sourcemap-codec@1.5.0': {} '@jridgewell/trace-mapping@0.3.25': dependencies: '@jridgewell/resolve-uri': 3.1.1 - '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/sourcemap-codec': 1.5.0 '@lerna/create@8.1.8(@swc/core@1.6.13(@swc/helpers@0.5.5))(babel-plugin-macros@3.1.0)(encoding@0.1.13)(typescript@5.5.4)': dependencies: @@ -12771,7 +12777,7 @@ snapshots: '@types/tsscmp': 1.0.2 axios: 1.7.4(debug@4.3.6) express: 4.18.2 - path-to-regexp: 6.2.1 + path-to-regexp: 6.2.2 please-upgrade-node: 3.2.0 promise.allsettled: 1.0.7 raw-body: 2.5.2 @@ -13364,7 +13370,7 @@ snapshots: '@vitest/snapshot@2.0.5': dependencies: '@vitest/pretty-format': 2.0.5 - magic-string: 0.30.10 + magic-string: 0.30.11 pathe: 1.1.2 '@vitest/spy@2.0.5': @@ -14214,7 +14220,7 @@ snapshots: check-error@2.1.1: {} - chokidar@3.5.3: + chokidar@3.6.0: dependencies: anymatch: 3.1.3 braces: 3.0.3 @@ -16936,7 +16942,7 @@ snapshots: '@colors/colors': 1.5.0 body-parser: 1.20.2 braces: 3.0.3 - chokidar: 3.5.3 + chokidar: 3.6.0 connect: 3.7.0 di: 0.0.1 dom-serialize: 2.2.1 @@ -17283,9 +17289,9 @@ snapshots: lz-string@1.5.0: {} - magic-string@0.30.10: + magic-string@0.30.11: dependencies: - '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/sourcemap-codec': 1.5.0 make-array@1.0.5: {} @@ -17534,7 +17540,7 @@ snapshots: dependencies: ansi-colors: 4.1.3 browser-stdout: 1.3.1 - chokidar: 3.5.3 + chokidar: 3.6.0 debug: 4.3.6(supports-color@8.1.1) diff: 5.2.0 escape-string-regexp: 4.0.0 @@ -17648,7 +17654,7 @@ snapshots: '@sinonjs/fake-timers': 11.2.2 '@sinonjs/text-encoding': 0.7.2 just-extend: 6.2.0 - path-to-regexp: 6.2.1 + path-to-regexp: 6.2.2 no-case@3.0.4: dependencies: @@ -18237,7 +18243,7 @@ snapshots: path-to-regexp@2.2.1: {} - path-to-regexp@6.2.1: {} + path-to-regexp@6.2.2: {} path-type@3.0.0: dependencies: @@ -19856,7 +19862,7 @@ snapshots: chai: 5.1.1 debug: 4.3.6(supports-color@8.1.1) execa: 8.0.1 - magic-string: 0.30.10 + magic-string: 0.30.11 pathe: 1.1.2 std-env: 3.7.0 tinybench: 2.8.0 diff --git a/scripts/useMaterialUIv6.mjs b/scripts/useMaterialUIv6.mjs new file mode 100644 index 000000000000..d6d0c4b4966a --- /dev/null +++ b/scripts/useMaterialUIv6.mjs @@ -0,0 +1,12 @@ +import childProcess from 'child_process'; + +const pnpmUpdate = childProcess.spawnSync( + 'pnpm', + ['update', '-r', '@mui/material@6.x', '@mui/system@6.x', '@mui/icons-material@6.x'], + { + shell: true, + stdio: ['inherit', 'inherit', 'inherit'], + }, +); + +process.exit(pnpmUpdate.status); diff --git a/test/README.md b/test/README.md index f2cf5858e304..1b571acc841d 100644 --- a/test/README.md +++ b/test/README.md @@ -2,17 +2,15 @@ ## Testing multiple versions of React -You can check integration of different versions of React (for example different [release channels](https://react.dev/community/versioning-policy) or PRs to React) by running the following commands: +You can check integration of different versions of React (for example different [release channels](https://react.dev/community/versioning-policy) or PRs to React) by running the following command: -1. `pnpm use-react-version `. +`pnpm use-react-version ` - Possible values for `version`: +Possible values for `version`: - - default: `stable` (minimum supported React version) - - a tag on npm, for example `next`, `experimental` or `latest` - - an older version, for example `^17.0.0` - -2. `pnpm install` +- default: `stable` (minimum supported React version) +- a tag on npm, for example `next`, `experimental` or `latest` +- an older version, for example `^17.0.0` ### CI @@ -44,3 +42,27 @@ curl --request POST \ --header 'Circle-Token: $CIRCLE_TOKEN' \ --data-raw '{"branch":"pull/24289/head","parameters":{"react-version":"next"}}' ``` + +## Testing multiple versions of Material UI + +Currently, we use `@mui/material` v5 in the MUI X repo and all tests are run against it. +But MUI X packages are compatible with v5 and v6. +You can run the tests against `@mui/material` v6 by running the following command: + +`pnpm use-material-ui-v6` + +### CI + +There's a `material-ui-v6` workflow in our CircleCI pipeline that you can trigger in CircleCI on the PR you want to test: + +1. Go to https://app.circleci.com/pipelines/github/mui/mui-x?branch=pull/PR_NUMBER and replace `PR_NUMBER` with the PR number you want to test. +2. Click `Trigger Pipeline` button. +3. Expand `Add parameters (optional)` and add the following parameter: + + | Parameter type | Name | Value | + | :------------- | :--------- | :--------------- | + | `string` | `workflow` | `material-ui-v6` | + +4. Click `Trigger Pipeline` button. + +![CircleCI workflow](./circleci-workflow.png) diff --git a/test/circleci-workflow.png b/test/circleci-workflow.png new file mode 100644 index 0000000000000000000000000000000000000000..de549e5eef462be7883674ae50802b25d19febc9 GIT binary patch literal 40490 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�wj=4Iw$jk=8`dK>%du4UK2k>a{ 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%0AHEz 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 YTlwqNav@vcA`1Krbuv65(0J}>0IRF3v literal 0 HcmV?d00001 diff --git a/test/karma.conf.js b/test/karma.conf.js index 3da8db12d540..87070fd88d44 100644 --- a/test/karma.conf.js +++ b/test/karma.conf.js @@ -80,6 +80,7 @@ module.exports = function setKarmaConfig(config) { fs: false, // Some tests import fs, stream: require.resolve('stream-browserify'), // util > inherits breaks with `false` path: false, + child_process: false, }, }, }, diff --git a/test/package.json b/test/package.json index 411ccad2a47b..aaa299ac3ed0 100644 --- a/test/package.json +++ b/test/package.json @@ -10,13 +10,13 @@ "@emotion/cache": "^11.13.1", "@emotion/react": "^11.13.3", "@mui/material": "^5.16.7", + "@mui/x-charts": "workspace:*", + "@mui/x-charts-pro": "workspace:*", + "@mui/x-charts-vendor": "workspace:*", "@mui/x-data-grid": "workspace:*", "@mui/x-data-grid-pro": "workspace:*", "@mui/x-date-pickers": "workspace:*", "@mui/x-date-pickers-pro": "workspace:*", - "@mui/x-charts": "workspace:*", - "@mui/x-charts-pro": "workspace:*", - "@mui/x-charts-vendor": "workspace:*", "@mui/x-license": "workspace:*", "@playwright/test": "^1.44.1", "@react-spring/web": "^9.7.4", @@ -25,6 +25,7 @@ "@types/moment-jalaali": "^0.7.9", "@types/prop-types": "^15.7.12", "@types/react": "^18.3.4", + "@types/semver": "^7.5.8", "chai": "^4.5.0", "dayjs": "^1.11.11", "moment": "^2.30.1", @@ -33,6 +34,7 @@ "react": "^18.3.1", "react-dom": "^18.3.1", "react-router-dom": "^6.26.1", + "semver": "^7.6.3", "stylis": "^4.3.2", "stylis-plugin-rtl": "^2.1.1" } diff --git a/test/regressions/index.test.js b/test/regressions/index.test.js index cb4971f83010..cc3f44deeb07 100644 --- a/test/regressions/index.test.js +++ b/test/regressions/index.test.js @@ -3,6 +3,7 @@ import { expect } from 'chai'; import * as path from 'path'; import * as childProcess from 'child_process'; import { chromium } from '@playwright/test'; +import materialPackageJson from '@mui/material/package.json'; function sleep(timeoutMS) { return new Promise((resolve) => { @@ -10,6 +11,21 @@ function sleep(timeoutMS) { }); } +const isMaterialUIv6 = materialPackageJson.version.startsWith('6.'); + +const isConsoleWarningIgnored = (msg) => { + if ( + msg && + isMaterialUIv6 && + msg.startsWith( + 'MUI: The Experimental_CssVarsProvider component has been ported into ThemeProvider.', + ) + ) { + return true; + } + return false; +}; + async function main() { const baseUrl = 'http://localhost:5001'; const screenshotDir = path.resolve(__dirname, './screenshots/chrome'); @@ -85,6 +101,9 @@ async function main() { it('should have no errors after the initial render', () => { const msg = errorConsole; errorConsole = undefined; + if (isConsoleWarningIgnored(msg)) { + return; + } expect(msg).to.equal(undefined); }); @@ -147,6 +166,9 @@ async function main() { it(`should have no errors rendering ${pathURL}`, () => { const msg = errorConsole; errorConsole = undefined; + if (isConsoleWarningIgnored(msg)) { + return; + } expect(msg).to.equal(undefined); }); }); diff --git a/test/utils/checkMaterialVersion.ts b/test/utils/checkMaterialVersion.ts new file mode 100644 index 000000000000..9ebaa81b7d6c --- /dev/null +++ b/test/utils/checkMaterialVersion.ts @@ -0,0 +1,43 @@ +import { expect } from 'chai'; +import semver from 'semver'; +import childProcess from 'child_process'; + +type PackageJson = { + name: string; + version: string; +}; + +const isJSDOM = /jsdom/.test(window.navigator.userAgent); + +export function checkMaterialVersion({ + packageJson, + materialPackageJson, +}: { + packageJson: PackageJson & { devDependencies: { '@mui/material': string } }; + materialPackageJson: PackageJson; +}) { + if (!isJSDOM) { + return undefined; + } + + const expectedVersion = packageJson.devDependencies['@mui/material']; + + const versions = childProcess.execSync(`npm dist-tag ls ${'@mui/material'} ${expectedVersion}`, { + encoding: 'utf8', + }); + const tagMapping = versions + .split('\n') + .find((mapping) => { + return mapping.startsWith(`${expectedVersion}: `); + }) + ?.split(': ')[1]; + + const version = tagMapping ?? expectedVersion; + + return it(`${packageJson.name} should resolve proper @mui/material version`, () => { + expect(semver.satisfies(materialPackageJson.version, version)).to.equal( + true, + `Expected @mui/material ${version}, but found ${materialPackageJson.version}`, + ); + }); +} diff --git a/test/utils/pickers/describeValue/testPickerActionBar.tsx b/test/utils/pickers/describeValue/testPickerActionBar.tsx index 850189c47294..1491dc6b8856 100644 --- a/test/utils/pickers/describeValue/testPickerActionBar.tsx +++ b/test/utils/pickers/describeValue/testPickerActionBar.tsx @@ -1,14 +1,13 @@ import * as React from 'react'; import { expect } from 'chai'; import { spy } from 'sinon'; -import { screen } from '@mui/internal-test-utils'; +import { fireEvent, screen } from '@mui/internal-test-utils'; import { adapterToUse, getExpectedOnChangeCount, expectPickerChangeHandlerValue, } from 'test/utils/pickers'; import { DescribeValueTestSuite } from './describeValue.types'; -import { fireUserEvent } from '../../fireUserEvent'; export const testPickerActionBar: DescribeValueTestSuite = ( ElementToTest, @@ -50,7 +49,7 @@ export const testPickerActionBar: DescribeValueTestSuite = ( ); // Clear the date - fireUserEvent.mousePress(screen.getByText(/clear/i)); + fireEvent.click(screen.getByText(/clear/i)); expect(onChange.callCount).to.equal(1); expectPickerChangeHandlerValue(pickerParams.type, onChange, emptyValue); expect(onAccept.callCount).to.equal(1); @@ -76,7 +75,7 @@ export const testPickerActionBar: DescribeValueTestSuite = ( ); // Clear the date - fireUserEvent.mousePress(screen.getByText(/clear/i)); + fireEvent.click(screen.getByText(/clear/i)); expect(onChange.callCount).to.equal(0); expect(onAccept.callCount).to.equal(0); expect(onClose.callCount).to.equal(1); @@ -104,7 +103,7 @@ export const testPickerActionBar: DescribeValueTestSuite = ( setNewValue(values[0], { isOpened: true, selectSection, pressKey }); // Cancel the modifications - fireUserEvent.mousePress(screen.getByText(/cancel/i)); + fireEvent.click(screen.getByText(/cancel/i)); expect(onChange.callCount).to.equal( getExpectedOnChangeCount(componentFamily, pickerParams) + 1, ); @@ -138,7 +137,7 @@ export const testPickerActionBar: DescribeValueTestSuite = ( ); // Cancel the modifications - fireUserEvent.mousePress(screen.getByText(/cancel/i)); + fireEvent.click(screen.getByText(/cancel/i)); expect(onChange.callCount).to.equal(0); expect(onAccept.callCount).to.equal(0); expect(onClose.callCount).to.equal(1); @@ -166,7 +165,7 @@ export const testPickerActionBar: DescribeValueTestSuite = ( setNewValue(values[0], { isOpened: true, selectSection, pressKey }); // Accept the modifications - fireUserEvent.mousePress(screen.getByText(/ok/i)); + fireEvent.click(screen.getByText(/ok/i)); expect(onChange.callCount).to.equal( getExpectedOnChangeCount(componentFamily, pickerParams), ); // The accepted value as already been committed, don't call onChange again @@ -193,7 +192,7 @@ export const testPickerActionBar: DescribeValueTestSuite = ( ); // Accept the modifications - fireUserEvent.mousePress(screen.getByText(/ok/i)); + fireEvent.click(screen.getByText(/ok/i)); expect(onChange.callCount).to.equal(1); expect(onAccept.callCount).to.equal(1); expect(onClose.callCount).to.equal(1); @@ -218,7 +217,7 @@ export const testPickerActionBar: DescribeValueTestSuite = ( ); // Accept the modifications - fireUserEvent.mousePress(screen.getByText(/ok/i)); + fireEvent.click(screen.getByText(/ok/i)); expect(onChange.callCount).to.equal(0); expect(onAccept.callCount).to.equal(0); expect(onClose.callCount).to.equal(1); @@ -243,7 +242,7 @@ export const testPickerActionBar: DescribeValueTestSuite = ( />, ); - fireUserEvent.mousePress(screen.getByText(/today/i)); + fireEvent.click(screen.getByText(/today/i)); let startOfToday: any; if (pickerParams.type === 'date') { diff --git a/test/utils/pickers/describeValue/testPickerOpenCloseLifeCycle.tsx b/test/utils/pickers/describeValue/testPickerOpenCloseLifeCycle.tsx index d2e1d1494439..57aa07b9e9c6 100644 --- a/test/utils/pickers/describeValue/testPickerOpenCloseLifeCycle.tsx +++ b/test/utils/pickers/describeValue/testPickerOpenCloseLifeCycle.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { expect } from 'chai'; import { spy } from 'sinon'; -import { screen } from '@mui/internal-test-utils'; +import { fireEvent, screen } from '@mui/internal-test-utils'; import { getExpectedOnChangeCount, getFieldInputRoot, openPicker } from 'test/utils/pickers'; import { DescribeValueTestSuite } from './describeValue.types'; import { fireUserEvent } from '../../fireUserEvent'; @@ -10,7 +10,7 @@ export const testPickerOpenCloseLifeCycle: DescribeValueTestSuite ElementToTest, options, ) => { - const { componentFamily, render, renderWithProps, values, setNewValue, ...pickerParams } = + const { componentFamily, render, renderWithProps, values, setNewValue, clock, ...pickerParams } = options; if (componentFamily !== 'picker') { @@ -82,7 +82,7 @@ export const testPickerOpenCloseLifeCycle: DescribeValueTestSuite expect(onChange.lastCall.args[0][index]).toEqualDateTime(value); }); } else { - expect(onChange.lastCall.args[0]).toEqualDateTime(newValue as any); + expect(onChange.lastCall.args[0]).toEqualDateTime(newValue); } expect(onAccept.callCount).to.equal(pickerParams.variant === 'mobile' ? 0 : 1); expect(onClose.callCount).to.equal(pickerParams.variant === 'mobile' ? 0 : 1); @@ -140,7 +140,7 @@ export const testPickerOpenCloseLifeCycle: DescribeValueTestSuite expect(onChange.lastCall.args[0][index]).toEqualDateTime(value); }); } else { - expect(onChange.lastCall.args[0]).toEqualDateTime(newValue as any); + expect(onChange.lastCall.args[0]).toEqualDateTime(newValue); } expect(onAccept.callCount).to.equal(1); expect(onClose.callCount).to.equal(1); @@ -216,7 +216,7 @@ export const testPickerOpenCloseLifeCycle: DescribeValueTestSuite expect(onChange.lastCall.args[0][index]).toEqualDateTime(value); }); } else { - expect(onChange.lastCall.args[0]).toEqualDateTime(newValue as any); + expect(onChange.lastCall.args[0]).toEqualDateTime(newValue); } expect(onAccept.callCount).to.equal(0); expect(onClose.callCount).to.equal(0); @@ -245,7 +245,7 @@ export const testPickerOpenCloseLifeCycle: DescribeValueTestSuite // meridiem does not change this time in case of multi section digital clock (pickerParams.type === 'time' || pickerParams.type === 'date-time' ? 1 : 0), ); - expect(onChange.lastCall.args[0]).toEqualDateTime(newValueBis as any); + expect(onChange.lastCall.args[0]).toEqualDateTime(newValueBis); } expect(onAccept.callCount).to.equal(0); expect(onClose.callCount).to.equal(0); @@ -273,7 +273,7 @@ export const testPickerOpenCloseLifeCycle: DescribeValueTestSuite const newValue = setNewValue(values[0], { isOpened: true, selectSection, pressKey }); // Dismiss the picker - fireUserEvent.keyPress(document.activeElement!, { key: 'Escape' }); + fireEvent.keyDown(document.activeElement!, { key: 'Escape' }); expect(onChange.callCount).to.equal(getExpectedOnChangeCount(componentFamily, pickerParams)); expect(onAccept.callCount).to.equal(1); if (isRangeType) { @@ -281,7 +281,7 @@ export const testPickerOpenCloseLifeCycle: DescribeValueTestSuite expect(onChange.lastCall.args[0][index]).toEqualDateTime(value); }); } else { - expect(onChange.lastCall.args[0]).toEqualDateTime(newValue as any); + expect(onChange.lastCall.args[0]).toEqualDateTime(newValue); } expect(onClose.callCount).to.equal(1); }); @@ -342,10 +342,10 @@ export const testPickerOpenCloseLifeCycle: DescribeValueTestSuite const newValue = setNewValue(values[0], { isOpened: true, selectSection, pressKey }); // Dismiss the picker - fireUserEvent.mousePress(document.body); + fireUserEvent.keyPress(document.activeElement!, { key: 'Escape' }); expect(onChange.callCount).to.equal(getExpectedOnChangeCount(componentFamily, pickerParams)); expect(onAccept.callCount).to.equal(1); - expect(onAccept.lastCall.args[0]).toEqualDateTime(newValue as any); + expect(onAccept.lastCall.args[0]).toEqualDateTime(newValue); expect(onClose.callCount).to.equal(1); }); @@ -365,7 +365,7 @@ export const testPickerOpenCloseLifeCycle: DescribeValueTestSuite ); // Dismiss the picker - fireUserEvent.mousePress(document.body); + fireEvent.click(document.body); expect(onChange.callCount).to.equal(0); expect(onAccept.callCount).to.equal(0); expect(onClose.callCount).to.equal(0); @@ -386,7 +386,7 @@ export const testPickerOpenCloseLifeCycle: DescribeValueTestSuite ); // Dismiss the picker - fireUserEvent.keyPress(document.body, { key: 'Escape' }); + fireEvent.keyDown(document.body, { key: 'Escape' }); expect(onChange.callCount).to.equal(0); expect(onAccept.callCount).to.equal(0); expect(onClose.callCount).to.equal(0); diff --git a/test/utils/pickers/describeValue/testShortcuts.tsx b/test/utils/pickers/describeValue/testShortcuts.tsx index 4e4493b442c2..ae14f1ddc801 100644 --- a/test/utils/pickers/describeValue/testShortcuts.tsx +++ b/test/utils/pickers/describeValue/testShortcuts.tsx @@ -2,9 +2,8 @@ import * as React from 'react'; import { expect } from 'chai'; import { spy } from 'sinon'; import { expectPickerChangeHandlerValue } from 'test/utils/pickers'; -import { screen } from '@mui/internal-test-utils'; +import { fireEvent, screen } from '@mui/internal-test-utils'; import { DescribeValueTestSuite } from './describeValue.types'; -import { fireUserEvent } from '../../fireUserEvent'; export const testShortcuts: DescribeValueTestSuite = (ElementToTest, options) => { const { @@ -50,7 +49,7 @@ export const testShortcuts: DescribeValueTestSuite = (ElementToTe ); const shortcut = screen.getByRole('button', { name: 'Test shortcut' }); - fireUserEvent.mousePress(shortcut); + fireEvent.click(shortcut); expect(onChange.callCount).to.equal(1); expectPickerChangeHandlerValue(pickerParams.type, onChange, values[1]); @@ -88,7 +87,7 @@ export const testShortcuts: DescribeValueTestSuite = (ElementToTe ); const shortcut = screen.getByRole('button', { name: 'Test shortcut' }); - fireUserEvent.mousePress(shortcut); + fireEvent.click(shortcut); expect(onChange.callCount).to.equal(1); expectPickerChangeHandlerValue(pickerParams.type, onChange, values[1]); @@ -126,7 +125,7 @@ export const testShortcuts: DescribeValueTestSuite = (ElementToTe ); const shortcut = screen.getByRole('button', { name: 'Test shortcut' }); - fireUserEvent.mousePress(shortcut); + fireEvent.click(shortcut); expect(onChange.callCount).to.equal(1); expectPickerChangeHandlerValue(pickerParams.type, onChange, values[1]); diff --git a/test/utils/pickers/misc.ts b/test/utils/pickers/misc.ts index 9e189dc2c8dc..f5fcf9c40ee7 100644 --- a/test/utils/pickers/misc.ts +++ b/test/utils/pickers/misc.ts @@ -7,7 +7,9 @@ export const stubMatchMedia = (matches = true) => sinon.stub().returns({ matches, addListener: () => {}, + addEventListener: () => {}, removeListener: () => {}, + removeEventListener: () => {}, }); const getChangeCountForComponentFamily = (componentFamily: PickerComponentFamily) => { diff --git a/test/utils/pickers/openPicker.ts b/test/utils/pickers/openPicker.ts index 67293e7a3cce..229510842e61 100644 --- a/test/utils/pickers/openPicker.ts +++ b/test/utils/pickers/openPicker.ts @@ -1,12 +1,12 @@ -import { screen } from '@mui/internal-test-utils'; +import { fireEvent, screen } from '@mui/internal-test-utils'; import { getFieldSectionsContainer } from 'test/utils/pickers/fields'; import { pickersInputBaseClasses } from '@mui/x-date-pickers/PickersTextField'; -import { fireUserEvent } from '../fireUserEvent'; export type OpenPickerParams = | { type: 'date' | 'date-time' | 'time'; variant: 'mobile' | 'desktop'; + click?: (element: Element) => Promise; } | { type: 'date-range' | 'date-time-range'; @@ -16,30 +16,34 @@ export type OpenPickerParams = * @default false */ isSingleInput?: boolean; + click?: (element: Element) => Promise; }; -export const openPicker = (params: OpenPickerParams) => { +export const openPicker = async (params: OpenPickerParams) => { const isRangeType = params.type === 'date-range' || params.type === 'date-time-range'; const fieldSectionsContainer = getFieldSectionsContainer( isRangeType && !params.isSingleInput && params.initialFocus === 'end' ? 1 : 0, ); + const { click = fireEvent.click } = params; if (isRangeType) { - fireUserEvent.mousePress(fieldSectionsContainer); + await click(fieldSectionsContainer); if (params.isSingleInput && params.initialFocus === 'end') { const sections = fieldSectionsContainer.querySelectorAll( `.${pickersInputBaseClasses.sectionsContainer}`, ); - fireUserEvent.mousePress(sections[sections.length - 1]); + await click(sections[sections.length - 1]); } - return undefined; + return true; } if (params.variant === 'mobile') { - return fireUserEvent.mousePress(fieldSectionsContainer); + await click(fieldSectionsContainer); + + return true; } const target = @@ -47,5 +51,6 @@ export const openPicker = (params: OpenPickerParams) => { ? screen.getByLabelText(/choose time/i) : screen.getByLabelText(/choose date/i); - return fireUserEvent.mousePress(target); + await click(target); + return true; }; diff --git a/test/utils/pickers/viewHandlers.ts b/test/utils/pickers/viewHandlers.ts index 2b3ab36c387f..845261f64156 100644 --- a/test/utils/pickers/viewHandlers.ts +++ b/test/utils/pickers/viewHandlers.ts @@ -1,8 +1,7 @@ -import { fireTouchChangedEvent, screen } from '@mui/internal-test-utils'; +import { fireEvent, fireTouchChangedEvent, screen } from '@mui/internal-test-utils'; import { getClockTouchEvent, formatFullTimeValue } from 'test/utils/pickers'; import { MuiPickersAdapter, TimeView } from '@mui/x-date-pickers/models'; import { formatMeridiem } from '@mui/x-date-pickers/internals'; -import { fireUserEvent } from '../fireUserEvent'; type TDate = any; @@ -36,9 +35,7 @@ export const timeClockHandler: ViewHandler = { export const digitalClockHandler: ViewHandler = { setViewValue: (adapter, value) => { - fireUserEvent.mousePress( - screen.getByRole('option', { name: formatFullTimeValue(adapter, value) }), - ); + fireEvent.click(screen.getByRole('option', { name: formatFullTimeValue(adapter, value) })); }, }; @@ -47,10 +44,10 @@ export const multiSectionDigitalClockHandler: ViewHandler = { const hasMeridiem = adapter.is12HourCycleInCurrentLocale(); const hoursLabel = parseInt(adapter.format(value, hasMeridiem ? 'hours12h' : 'hours24h'), 10); const minutesLabel = adapter.getMinutes(value).toString(); - fireUserEvent.mousePress(screen.getByRole('option', { name: `${hoursLabel} hours` })); - fireUserEvent.mousePress(screen.getByRole('option', { name: `${minutesLabel} minutes` })); + fireEvent.click(screen.getByRole('option', { name: `${hoursLabel} hours` })); + fireEvent.click(screen.getByRole('option', { name: `${minutesLabel} minutes` })); if (hasMeridiem) { - fireUserEvent.mousePress( + fireEvent.click( screen.getByRole('option', { name: formatMeridiem(adapter, adapter.getHours(value) >= 12 ? 'pm' : 'am'), }), From f1ab73460febce70393b1397fe35b42be5787cfd Mon Sep 17 00:00:00 2001 From: Arthur Suh Balduini <34691066+arthurbalduini@users.noreply.github.com> Date: Thu, 29 Aug 2024 13:25:06 +0200 Subject: [PATCH 8/9] [DateTimeRangePicker] Fix date format resolving from views on 24hr locales (#14341) Co-authored-by: Arthur Balduini Co-authored-by: Lukas --- .../DesktopDateTimeRangePicker.tsx | 2 +- .../MobileDateTimeRangePicker.tsx | 2 +- .../src/internals/utils/date-time-utils.ts | 15 +++++++++++---- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/DesktopDateTimeRangePicker.tsx b/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/DesktopDateTimeRangePicker.tsx index f3d52bc90d1f..069e4d66cc75 100644 --- a/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/DesktopDateTimeRangePicker.tsx +++ b/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/DesktopDateTimeRangePicker.tsx @@ -173,7 +173,7 @@ const DesktopDateTimeRangePicker = React.forwardRef(function DesktopDateTimeRang ...defaultizedProps, views, viewRenderers, - format: resolveDateTimeFormat(utils, defaultizedProps), + format: resolveDateTimeFormat(utils, defaultizedProps, true), // force true to correctly handle `renderTimeViewClock` as a renderer ampmInClock: true, calendars: defaultizedProps.calendars ?? 1, diff --git a/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/MobileDateTimeRangePicker.tsx b/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/MobileDateTimeRangePicker.tsx index 504484d7f344..27036c430d8e 100644 --- a/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/MobileDateTimeRangePicker.tsx +++ b/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/MobileDateTimeRangePicker.tsx @@ -172,7 +172,7 @@ const MobileDateTimeRangePicker = React.forwardRef(function MobileDateTimeRangeP const props = { ...defaultizedProps, viewRenderers, - format: resolveDateTimeFormat(utils, defaultizedProps), + format: resolveDateTimeFormat(utils, defaultizedProps, true), // Force one calendar on mobile to avoid layout issues calendars: 1, // force true to correctly handle `renderTimeViewClock` as a renderer diff --git a/packages/x-date-pickers/src/internals/utils/date-time-utils.ts b/packages/x-date-pickers/src/internals/utils/date-time-utils.ts index 47688559cf1b..eb7c100e9468 100644 --- a/packages/x-date-pickers/src/internals/utils/date-time-utils.ts +++ b/packages/x-date-pickers/src/internals/utils/date-time-utils.ts @@ -7,7 +7,7 @@ import { TimeView, } from '../../models'; import { resolveTimeFormat, isTimeView, isInternalTimeView } from './time-utils'; -import { resolveDateFormat } from './date-utils'; +import { isDatePickerView, resolveDateFormat } from './date-utils'; import { DateOrTimeViewWithMeridiem } from '../models'; import { DesktopOnlyTimePickerProps } from '../models/props/clock'; import { DefaultizedProps } from '../models/helpers'; @@ -18,7 +18,12 @@ export const resolveDateTimeFormat = ( views, format, ...other - }: { format?: string; views: readonly DateOrTimeViewWithMeridiem[]; ampm: boolean }, + }: { + format?: string; + views: readonly DateOrTimeViewWithMeridiem[]; + ampm: boolean; + }, + ignoreDateResolving?: boolean, ) => { if (format) { return format; @@ -30,7 +35,7 @@ export const resolveDateTimeFormat = ( views.forEach((view) => { if (isTimeView(view)) { timeViews.push(view as TimeView); - } else { + } else if (isDatePickerView(view)) { dateViews.push(view as DateView); } }); @@ -44,7 +49,9 @@ export const resolveDateTimeFormat = ( } const timeFormat = resolveTimeFormat(utils, { views: timeViews, ...other }); - const dateFormat = resolveDateFormat(utils, { views: dateViews, ...other }, false); + const dateFormat = ignoreDateResolving + ? utils.formats.keyboardDate + : resolveDateFormat(utils, { views: dateViews, ...other }, false); return `${dateFormat} ${timeFormat}`; }; From 1be2f4caab254861ce227b6ab398af07e6a45a6b Mon Sep 17 00:00:00 2001 From: Arthur Suh Balduini <34691066+arthurbalduini@users.noreply.github.com> Date: Thu, 29 Aug 2024 13:25:21 +0200 Subject: [PATCH 9/9] [pickers] Add `onTouchStart` handler for `TimeClock` (#14305) Co-authored-by: Arthur Balduini --- .../x-date-pickers/src/TimeClock/Clock.tsx | 5 +- .../src/TimeClock/tests/TimeClock.test.tsx | 68 +++++++++++++++---- 2 files changed, 59 insertions(+), 14 deletions(-) diff --git a/packages/x-date-pickers/src/TimeClock/Clock.tsx b/packages/x-date-pickers/src/TimeClock/Clock.tsx index d04f7c4f7ebe..fc69d7d028fe 100644 --- a/packages/x-date-pickers/src/TimeClock/Clock.tsx +++ b/packages/x-date-pickers/src/TimeClock/Clock.tsx @@ -261,7 +261,7 @@ export function Clock(inProps: ClockProps) handleValueChange(newSelectedValue, isFinish); }; - const handleTouchMove = (event: React.TouchEvent) => { + const handleTouchSelection = (event: React.TouchEvent) => { isMoving.current = true; setTime(event, 'shallow'); }; @@ -347,7 +347,8 @@ export function Clock(inProps: ClockProps) ', () => { const onChangeMock = spy(); render(); - fireTouchChangedEvent(screen.getByMuiTest('clock'), 'touchmove', selectEvent); + fireTouchChangedEvent(screen.getByMuiTest('clock'), 'touchstart', selectEvent); expect(onChangeMock.callCount).to.equal(0); // hours are not disabled @@ -224,7 +224,7 @@ describe('', () => { const onChangeMock = spy(); render(); - fireTouchChangedEvent(screen.getByMuiTest('clock'), 'touchmove', selectEvent); + fireTouchChangedEvent(screen.getByMuiTest('clock'), 'touchstart', selectEvent); expect(onChangeMock.callCount).to.equal(0); // hours are disabled @@ -252,7 +252,7 @@ describe('', () => { }, ], }, - '20:--': { + '19:--': { changedTouches: [ { clientX: 66, @@ -292,7 +292,7 @@ describe('', () => { />, ); - fireTouchChangedEvent(screen.getByMuiTest('clock'), 'touchmove', clockTouchEvent['13:--']); + fireTouchChangedEvent(screen.getByMuiTest('clock'), 'touchstart', clockTouchEvent['13:--']); expect(handleChange.callCount).to.equal(1); const [date, selectionState] = handleChange.firstCall.args; @@ -316,7 +316,7 @@ describe('', () => { />, ); - fireTouchChangedEvent(screen.getByMuiTest('clock'), 'touchmove', clockTouchEvent['--:20']); + fireTouchChangedEvent(screen.getByMuiTest('clock'), 'touchstart', clockTouchEvent['--:20']); expect(handleChange.callCount).to.equal(1); const [date, selectionState] = handleChange.firstCall.args; @@ -338,7 +338,7 @@ describe('', () => { />, ); - fireTouchChangedEvent(screen.getByMuiTest('clock'), 'touchmove', clockTouchEvent['--:20']); + fireTouchChangedEvent(screen.getByMuiTest('clock'), 'touchstart', clockTouchEvent['--:20']); expect(handleChange.callCount).to.equal(0); }); @@ -356,7 +356,7 @@ describe('', () => { />, ); - fireTouchChangedEvent(screen.getByMuiTest('clock'), 'touchmove', clockTouchEvent['--:20']); + fireTouchChangedEvent(screen.getByMuiTest('clock'), 'touchstart', clockTouchEvent['--:20']); expect(handleChange.callCount).to.equal(0); }); @@ -374,7 +374,7 @@ describe('', () => { />, ); - fireTouchChangedEvent(screen.getByMuiTest('clock'), 'touchmove', clockTouchEvent['20:--']); + fireTouchChangedEvent(screen.getByMuiTest('clock'), 'touchstart', clockTouchEvent['19:--']); expect(handleChange.callCount).to.equal(0); }); @@ -392,7 +392,7 @@ describe('', () => { />, ); - fireTouchChangedEvent(screen.getByMuiTest('clock'), 'touchmove', clockTouchEvent['20:--']); + fireTouchChangedEvent(screen.getByMuiTest('clock'), 'touchstart', clockTouchEvent['19:--']); expect(handleChange.callCount).to.equal(0); }); @@ -427,7 +427,7 @@ describe('', () => { />, ); - fireTouchChangedEvent(screen.getByMuiTest('clock'), 'touchmove', clockTouchEvent['--:10']); + fireTouchChangedEvent(screen.getByMuiTest('clock'), 'touchstart', clockTouchEvent['--:10']); expect(handleChange.callCount).to.equal(1); const [date, selectionState] = handleChange.firstCall.args; @@ -449,7 +449,7 @@ describe('', () => { />, ); - fireTouchChangedEvent(screen.getByMuiTest('clock'), 'touchmove', clockTouchEvent['--:20']); + fireTouchChangedEvent(screen.getByMuiTest('clock'), 'touchstart', clockTouchEvent['--:20']); expect(handleChange.callCount).to.equal(0); }); @@ -467,10 +467,54 @@ describe('', () => { />, ); - fireTouchChangedEvent(screen.getByMuiTest('clock'), 'touchmove', clockTouchEvent['--:20']); + fireTouchChangedEvent(screen.getByMuiTest('clock'), 'touchstart', clockTouchEvent['--:20']); expect(handleChange.callCount).to.equal(0); }); + + it('should select enabled hour on touch and drag', () => { + const handleChange = spy(); + const handleViewChange = spy(); + render( + , + ); + + fireTouchChangedEvent(screen.getByMuiTest('clock'), 'touchstart', clockTouchEvent['13:--']); + fireTouchChangedEvent(screen.getByMuiTest('clock'), 'touchmove', clockTouchEvent['19:--']); + + expect(handleChange.callCount).to.equal(2); + const [date, selectionState] = handleChange.lastCall.args; + expect(date).toEqualDateTime(new Date(2018, 0, 1, 19)); + expect(selectionState).to.equal('shallow'); + expect(handleViewChange.callCount).to.equal(0); + }); + + it('should select enabled hour and move to next view on touch end', () => { + const handleChange = spy(); + const handleViewChange = spy(); + render( + , + ); + + fireTouchChangedEvent(screen.getByMuiTest('clock'), 'touchstart', clockTouchEvent['13:--']); + fireTouchChangedEvent(screen.getByMuiTest('clock'), 'touchend', clockTouchEvent['13:--']); + + expect(handleChange.callCount).to.equal(2); + const [date, selectionState] = handleChange.lastCall.args; + expect(date).toEqualDateTime(new Date(2018, 0, 1, 13)); + expect(selectionState).to.equal('partial'); + expect(handleViewChange.callCount).to.equal(1); + }); }); describe('default value', () => {