From 65aa5563596e006a6fa4ee1520921d1bf7318f20 Mon Sep 17 00:00:00 2001 From: Bilal Shafi Date: Tue, 5 Nov 2024 20:18:35 +0500 Subject: [PATCH] [DataGrid] Fix `null` reference error in `GridVirtualScrollbar` (#15009) --- .circleci/config.yml | 17 +- .github/workflows/codeql.yml | 6 +- .github/workflows/codspeed.yml | 4 +- .github/workflows/create-cherry-pick-pr.yml | 18 + .github/workflows/l10n.yml | 4 +- .../priority-support-validation-prompt.yml | 2 +- .github/workflows/scorecards.yml | 4 +- .github/workflows/vale-action.yml | 2 +- CHANGELOG.md | 157 +- changelogOld/CHANGELOG.v5.md | 4 +- changelogOld/CHANGELOG.v6.md | 4 +- docs/.link-check-errors.txt | 1 + docs/constants.js | 2 +- docs/data/charts/areas-demo/areas-demo.md | 2 +- docs/data/charts/axis/axis.md | 2 +- docs/data/charts/bars/BarAnimation.tsx | 5 +- docs/data/charts/bars/bars.md | 6 +- docs/data/charts/components/components.md | 2 +- docs/data/charts/gauge/gauge.md | 2 +- .../charts/getting-started/getting-started.md | 98 +- .../highlighting/ControlledHighlight.js | 16 +- .../highlighting/ControlledHighlight.tsx | 16 +- .../charts/highlighting/ElementHighlights.js | 32 +- .../charts/highlighting/ElementHighlights.tsx | 32 +- .../data/charts/highlighting/SyncHighlight.js | 12 +- .../charts/highlighting/SyncHighlight.tsx | 12 +- docs/data/charts/lines/LineDataset.js | 2 +- docs/data/charts/lines/LineDataset.tsx | 2 +- docs/data/charts/lines/lines.md | 2 +- docs/data/charts/overview/overview.md | 25 +- .../pie-demo/PieChartWithCustomizedLabel.js | 2 +- .../pie-demo/PieChartWithCustomizedLabel.tsx | 2 +- .../pie-demo/PieChartWithPaddingAngle.js | 6 +- .../pie-demo/PieChartWithPaddingAngle.tsx | 6 +- docs/data/charts/pie-demo/TwoLevelPieChart.js | 4 +- .../data/charts/pie-demo/TwoLevelPieChart.tsx | 4 +- .../data/charts/pie-demo/TwoSimplePieChart.js | 4 +- .../charts/pie-demo/TwoSimplePieChart.tsx | 4 +- docs/data/charts/pie/PieClickNoSnap.js | 4 +- docs/data/charts/pie/pie.md | 2 +- docs/data/charts/tooltip/CustomAxisTooltip.js | 90 +- .../data/charts/tooltip/CustomAxisTooltip.tsx | 98 +- docs/data/charts/tooltip/CustomItemTooltip.js | 89 +- .../data/charts/tooltip/CustomItemTooltip.tsx | 97 +- docs/data/charts/tooltip/Interaction.js | 6 +- docs/data/charts/tooltip/Interaction.tsx | 6 +- docs/data/charts/tooltip/ItemTooltip.js | 89 +- docs/data/charts/tooltip/ItemTooltip.tsx | 97 +- docs/data/charts/tooltip/ItemTooltipFixedY.js | 97 +- .../data/charts/tooltip/ItemTooltipFixedY.tsx | 105 +- .../charts/tooltip/ItemTooltipTopElement.js | 67 +- .../charts/tooltip/ItemTooltipTopElement.tsx | 75 +- docs/data/charts/tooltip/tooltip.md | 18 +- docs/data/chartsApiPages.ts | 233 ++ .../CustomSlotPropsCallback.js | 2 +- .../CustomSlotPropsCallback.tsx | 2 +- .../CustomSlotPropsCallback.tsx.preview | 2 +- .../custom-components/TypescriptCasting.js | 1 - .../custom-components/TypescriptCasting.tsx | 7 +- .../TypescriptCasting.tsx.preview | 4 +- .../custom-components/custom-components.md | 11 +- .../column-definition/column-definition.md | 4 +- docs/data/data-grid/components/components.md | 2 +- docs/data/data-grid/editing/editing.md | 2 +- docs/data/data-grid/joy-ui/joy-ui.md | 2 +- .../data-grid/layout/GridOverlayHeight.js | 70 + .../data-grid/layout/GridOverlayHeight.tsx | 70 + .../layout/GridOverlayHeight.tsx.preview | 6 + docs/data/data-grid/layout/layout.md | 22 +- .../data-grid/list-view/ListViewAdvanced.js | 8 +- .../data-grid/list-view/ListViewAdvanced.tsx | 8 +- docs/data/data-grid/localization/data.json | 72 +- .../data-grid/localization/localization.md | 4 +- docs/data/dataGridApiPages.ts | 31 + .../CalendarHeaderComponent.js | 1 - .../CalendarHeaderComponent.tsx | 3 +- .../CalendarHeaderComponentRange.js | 1 - .../CalendarHeaderComponentRange.tsx | 3 +- .../custom-components/ToolbarComponent.tsx | 4 +- .../custom-components/custom-components.md | 2 +- .../custom-field/BrowserV7Field.js | 6 +- .../custom-field/BrowserV7Field.tsx | 15 +- .../BrowserV7MultiInputRangeField.js | 2 +- .../BrowserV7MultiInputRangeField.tsx | 11 +- .../BrowserV7SingleInputRangeField.js | 6 +- .../BrowserV7SingleInputRangeField.tsx | 22 +- .../date-pickers/custom-field/JoyV6Field.js | 1 - .../date-pickers/custom-field/JoyV6Field.tsx | 12 +- .../custom-field/JoyV6MultiInputRangeField.js | 2 +- .../JoyV6MultiInputRangeField.tsx | 11 +- .../JoyV6SingleInputRangeField.js | 1 - .../JoyV6SingleInputRangeField.tsx | 15 +- .../custom-field/MaterialV6Field.js | 4 +- .../custom-field/MaterialV6Field.tsx | 4 +- .../custom-field/MaterialV6Field.tsx.preview | 4 +- .../custom-field/MaterialV7FieldWrapped.js | 10 +- .../custom-field/MaterialV7FieldWrapped.tsx | 10 +- .../MaterialV7FieldWrapped.tsx.preview | 10 +- .../SingleInputDateRangePickerWrapped.js | 1 - .../SingleInputDateRangePickerWrapped.tsx | 12 +- .../MaterialDatePicker.js | 135 + .../MaterialDatePicker.tsx | 156 + .../MaterialDatePicker.tsx.preview | 9 + .../behavior-button/MaterialDatePicker.js | 72 + .../behavior-button/MaterialDatePicker.tsx | 76 + .../MaterialDatePicker.tsx.preview | 1 + .../MaterialDateRangePicker.js | 82 + .../MaterialDateRangePicker.tsx | 86 + .../MaterialDateRangePicker.tsx.preview | 1 + .../MaskedMaterialTextField.js | 164 + .../MaskedMaterialTextField.tsx | 168 ++ .../MaskedMaterialTextField.tsx.preview | 1 + .../MaterialDatePicker.js | 66 + .../MaterialDatePicker.tsx | 70 + .../MaterialDatePicker.tsx.preview | 1 + .../date-pickers/custom-field/custom-field.md | 117 +- .../custom-layout/AddComponent.tsx | 2 +- .../custom-layout/custom-layout.md | 4 +- .../custom-opening-button.md | 2 +- .../DateCalendarServerRequest.tsx | 2 +- .../date-pickers/date-calendar/WeekPicker.tsx | 4 +- .../date-picker/examplesConfig.styling.tsx | 8 +- .../CustomDateRangePickerDay.js | 1 + .../CustomDateRangePickerDay.tsx | 5 +- .../date-range-field/DateRangeFieldValue.js | 1 - .../date-range-field/DateRangeFieldValue.tsx | 2 +- .../digital-clock/DigitalClockSkipDisabled.js | 6 +- .../DigitalClockSkipDisabled.tsx | 6 +- .../experimentation/experimentation.md | 2 +- .../fields/BasicV7DOMStructure.js | 2 +- .../fields/BasicV7DOMStructure.tsx | 2 +- .../fields/BasicV7DOMStructure.tsx.preview | 2 +- docs/data/date-pickers/fields/fields.md | 195 -- .../lifecycle/ServerInteraction.tsx | 2 +- docs/data/date-pickers/localization/data.json | 76 +- .../date-pickers/localization/localization.md | 4 +- .../date-pickers/timezone/LuxonTimezone.tsx | 2 +- docs/data/date-pickers/timezone/LuxonUTC.tsx | 2 +- .../TimeValidationShouldDisableTime.tsx | 8 +- docs/data/datePickersApiPages.ts | 236 ++ docs/data/introduction/support/support.md | 4 +- .../migration-charts-v7.md | 34 + .../migration-data-grid-v7.md | 78 + .../MobileKeyboardView.tsx | 6 +- .../migration-pickers-v6.md | 2 +- .../migration-pickers-v7.md | 422 +++ .../migration-tree-view-v7.md | 180 ++ docs/data/pages.ts | 349 ++- docs/data/pickersAdapterOverride.ts | 9 + docs/data/tree-view/datasets/employees.ts | 40 + docs/data/tree-view/overview/overview.md | 72 - .../customization/FileExplorer.js | 46 +- .../customization/FileExplorer.tsx | 50 +- .../customization/HeadlessAPI.js | 48 +- .../customization/HeadlessAPI.tsx | 50 +- .../customization/customization.md | 13 +- .../rich-tree-view/editing/CustomBehavior.js | 12 +- .../rich-tree-view/editing/CustomBehavior.tsx | 18 +- .../editing/CustomBehavior.tsx.preview | 2 +- .../editing/CustomLabelInput.js | 20 +- .../editing/CustomLabelInput.tsx | 40 +- .../editing/CustomLabelInput.tsx.preview | 2 +- .../rich-tree-view/editing/EditWithIcons.js | 20 +- .../rich-tree-view/editing/EditWithIcons.tsx | 42 +- .../editing/EditWithIcons.tsx.preview | 2 +- .../rich-tree-view/editing/Validation.js | 16 +- .../rich-tree-view/editing/Validation.tsx | 26 +- .../editing/Validation.tsx.preview | 2 +- .../rich-tree-view/editing/editing.md | 5 +- .../tree-view/rich-tree-view/focus/focus.md | 2 +- .../tree-view/rich-tree-view/items/items.md | 2 +- .../rich-tree-view/ordering/FileExplorer.js | 50 +- .../rich-tree-view/ordering/FileExplorer.tsx | 54 +- .../ordering/OnlyReorderFromDragHandle.js | 54 +- .../ordering/OnlyReorderFromDragHandle.tsx | 56 +- .../rich-tree-view/ordering/ordering.md | 2 +- .../selection/SelectionPropagation.js | 59 + .../selection/SelectionPropagation.tsx | 60 + .../rich-tree-view/selection/selection.md | 41 +- .../customization/GmailTreeView.js | 32 +- .../customization/GmailTreeView.tsx | 34 +- .../customization/HeadlessAPI.js | 44 +- .../customization/HeadlessAPI.tsx | 46 +- .../customization/customization.md | 13 +- .../tree-view/simple-tree-view/focus/focus.md | 2 +- .../tree-view/simple-tree-view/items/items.md | 4 +- .../simple-tree-view/selection/selection.md | 2 +- .../tree-item-customization/CheckboxSlot.js | 4 +- .../tree-item-customization/CheckboxSlot.tsx | 6 +- .../CheckboxSlotProps.js | 4 +- .../CheckboxSlotProps.tsx | 14 +- .../tree-item-customization/ContentSlot.js | 4 +- .../tree-item-customization/ContentSlot.tsx | 12 +- .../ContentSlotProps.js | 4 +- .../ContentSlotProps.tsx | 14 +- .../CustomTreeItemDemo.js | 82 +- .../CustomTreeItemDemo.tsx | 84 +- .../HandleCheckboxSelectionDemo.js | 8 +- .../HandleCheckboxSelectionDemo.tsx | 22 +- .../HandleExpansionDemo.js | 40 +- .../HandleExpansionDemo.tsx | 44 +- .../HandleSelectionDemo.js | 8 +- .../HandleSelectionDemo.tsx | 32 +- .../tree-item-customization/LabelSlot.js | 8 +- .../tree-item-customization/LabelSlot.tsx | 10 +- .../tree-item-customization/LabelSlotProps.js | 4 +- .../LabelSlotProps.tsx | 6 +- .../tree-item-customization.md | 48 +- .../useTreeItemHookProperties.js | 72 + .../useTreeItemHookProperties.tsx | 73 + .../useTreeItemHookProperties.tsx.preview | 10 + .../useTreeItemHookPublicAPI.js | 56 + .../useTreeItemHookPublicAPI.tsx | 65 + .../useTreeItemHookPublicAPI.tsx.preview | 5 + .../useTreeItemHookStatus.js | 152 + .../useTreeItemHookStatus.tsx | 157 + .../useTreeItemHookStatus.tsx.preview | 14 + docs/data/treeViewApiPages.ts | 34 + docs/package.json | 29 +- docs/pages/_app.js | 67 +- docs/pages/x/api/charts/bar-series-type.json | 4 +- docs/pages/x/api/charts/line-series-type.json | 4 +- docs/pages/x/api/charts/pie-chart.json | 60 - .../x/api/charts/scatter-series-type.json | 5 +- .../x/api/data-grid/data-grid-premium.json | 12 + docs/pages/x/api/data-grid/data-grid-pro.json | 12 + docs/pages/x/api/data-grid/data-grid.json | 12 + .../x/api/date-pickers/date-calendar.json | 17 +- docs/pages/x/api/date-pickers/date-field.json | 6 +- .../pages/x/api/date-pickers/date-picker.json | 17 +- .../api/date-pickers/date-range-calendar.json | 11 +- .../x/api/date-pickers/date-range-picker.json | 11 +- .../x/api/date-pickers/date-time-field.json | 8 +- .../x/api/date-pickers/date-time-picker.json | 19 +- .../date-pickers/date-time-range-picker.json | 13 +- .../api/date-pickers/desktop-date-picker.json | 17 +- .../desktop-date-range-picker.json | 11 +- .../desktop-date-time-picker.json | 19 +- .../desktop-date-time-range-picker.json | 13 +- .../api/date-pickers/desktop-time-picker.json | 2 +- .../x/api/date-pickers/digital-clock.json | 2 +- .../api/date-pickers/mobile-date-picker.json | 17 +- .../mobile-date-range-picker.json | 11 +- .../date-pickers/mobile-date-time-picker.json | 19 +- .../mobile-date-time-range-picker.json | 13 +- .../api/date-pickers/mobile-time-picker.json | 2 +- .../x/api/date-pickers/month-calendar.json | 7 +- .../multi-input-date-range-field.json | 2 +- .../multi-input-date-time-range-field.json | 4 +- .../multi-input-time-range-field.json | 2 +- .../multi-section-digital-clock.json | 2 +- .../single-input-date-range-field.json | 2 +- .../single-input-date-time-range-field.json | 4 +- .../single-input-time-range-field.json | 2 +- .../api/date-pickers/static-date-picker.json | 17 +- .../static-date-range-picker.json | 11 +- .../date-pickers/static-date-time-picker.json | 19 +- .../api/date-pickers/static-time-picker.json | 2 +- docs/pages/x/api/date-pickers/time-clock.json | 2 +- docs/pages/x/api/date-pickers/time-field.json | 2 +- .../pages/x/api/date-pickers/time-picker.json | 2 +- .../x/api/date-pickers/year-calendar.json | 7 +- .../x/api/tree-view/rich-tree-view-pro.json | 4 + .../pages/x/api/tree-view/rich-tree-view.json | 6 +- .../x/api/tree-view/simple-tree-view.json | 4 + .../tree-item-drag-and-drop-overlay.js | 23 + .../tree-item-drag-and-drop-overlay.json | 15 + docs/pages/x/api/tree-view/tree-item-icon.js | 23 + .../pages/x/api/tree-view/tree-item-icon.json | 32 + docs/pages/x/api/tree-view/tree-item.json | 118 +- docs/pages/x/api/tree-view/tree-view.json | 4 + docs/pages/x/migration/migration-charts-v7.js | 7 + .../x/migration/migration-data-grid-v7.js | 7 + .../pages/x/migration/migration-pickers-v7.js | 7 + .../x/migration/migration-tree-view-v7.js | 7 + .../tree-item-dark.png | Bin 47445 -> 47994 bytes .../tree-item-light.png | Bin 48527 -> 48820 bytes docs/scripts/generateProptypes.ts | 10 +- .../modules/components/ChartFeaturesGrid.js | 34 +- .../ChartsInstallationInstructions.js | 4 +- .../DataGridInstallationInstructions.js | 6 +- .../PickersInstallationInstructions.js | 4 +- .../modules/components/PickersPlayground.tsx | 2 +- .../TreeViewInstallationInstructions.js | 4 +- .../modules/components/overview/Keyboard.tsx | 1 - .../components/overview/mainDemo/Clock.tsx | 2 +- .../mainDemo/DateRangeWithShortcuts.tsx | 2 +- .../overview/mainDemo/DigitalClock.tsx | 4 +- .../overview/mainDemo/PickerButton.tsx | 11 +- .../api-docs/charts/bar-series-type.json | 4 +- .../api-docs/charts/line-series-type.json | 4 +- .../api-docs/charts/pie-chart/pie-chart.json | 21 - .../api-docs/charts/scatter-series-type.json | 5 +- .../data-grid-premium/data-grid-premium.json | 2 + .../data-grid-pro/data-grid-pro.json | 2 + .../data-grid/data-grid/data-grid.json | 2 + .../rich-tree-view-pro.json | 3 + .../rich-tree-view/rich-tree-view.json | 3 + .../simple-tree-view/simple-tree-view.json | 3 + .../tree-item-drag-and-drop-overlay.json | 1 + .../tree-item-icon/tree-item-icon.json | 14 + .../tree-view/tree-item/tree-item.json | 54 +- .../tree-view/tree-view/tree-view.json | 3 + package.json | 76 +- packages/rsc-builder/package.json | 2 +- packages/x-charts-pro/package.json | 4 +- .../src/BarChartPro/BarChartPro.tsx | 29 - packages/x-charts-pro/src/Heatmap/Heatmap.tsx | 2 +- .../src/LineChartPro/LineChartPro.tsx | 29 - .../src/ScatterChartPro/ScatterChartPro.tsx | 29 - .../src/models/seriesType/heatmap.ts | 2 +- .../x-charts-pro/src/typeOverloads/modules.ts | 2 +- packages/x-charts-vendor/package.json | 6 +- packages/x-charts/package.json | 6 +- packages/x-charts/src/BarChart/BarChart.tsx | 42 +- packages/x-charts/src/BarChart/BarElement.tsx | 2 +- .../src/BarChart/BarLabel/BarLabelItem.tsx | 2 +- packages/x-charts/src/BarChart/BarPlot.tsx | 4 +- packages/x-charts/src/BarChart/extremums.ts | 6 +- packages/x-charts/src/BarChart/formatter.ts | 2 +- .../x-charts/src/BarChart/useBarChartProps.ts | 2 - .../src/ChartContainer/ChartContainer.tsx | 2 +- .../src/ChartContainer/useDefaultizeAxis.ts | 2 +- .../src/ChartsLegend/ChartsLegend.tsx | 5 +- .../src/ChartsLegend/DefaultChartsLegend.tsx | 18 +- .../src/ChartsLegend/LegendPerItem.tsx | 2 +- .../ChartsOnAxisClickHandler.tsx | 4 +- .../src/ChartsOverlay/ChartsOverlay.tsx | 2 +- .../ChartsAxisTooltipContent.tsx | 7 +- .../ChartsItemTooltipContent.tsx | 6 +- .../src/ChartsTooltip/ChartsTooltip.tsx | 59 +- .../ChartsTooltip/contentDisplayed.test.tsx | 4 + .../src/ChartsTooltip/useAxisTooltip.tsx | 7 +- .../src/ChartsTooltip/useItemTooltip.tsx | 6 +- packages/x-charts/src/ChartsTooltip/utils.tsx | 89 +- .../ChartsVoronoiHandler.tsx | 6 +- .../x-charts/src/LineChart/AreaElement.tsx | 2 +- packages/x-charts/src/LineChart/AreaPlot.tsx | 9 +- packages/x-charts/src/LineChart/LineChart.tsx | 42 +- .../x-charts/src/LineChart/LineElement.tsx | 2 +- .../src/LineChart/LineHighlightPlot.tsx | 11 +- packages/x-charts/src/LineChart/LinePlot.tsx | 9 +- packages/x-charts/src/LineChart/MarkPlot.tsx | 9 +- packages/x-charts/src/LineChart/extremums.ts | 6 +- packages/x-charts/src/LineChart/formatter.ts | 2 +- .../src/LineChart/useLineChartProps.ts | 2 - packages/x-charts/src/PieChart/PieArc.tsx | 15 - packages/x-charts/src/PieChart/PieArcPlot.tsx | 3 - packages/x-charts/src/PieChart/PieChart.tsx | 154 +- .../src/ScatterChart/ScatterChart.tsx | 42 +- .../x-charts/src/ScatterChart/ScatterPlot.tsx | 13 +- .../x-charts/src/ScatterChart/extremums.ts | 12 +- .../src/ScatterChart/useScatterChartProps.ts | 2 - .../src/SparkLineChart/SparkLineChart.tsx | 2 +- .../CartesianProvider/defaultizeAxis.ts | 2 +- .../HighlightedProvider/HighlightedContext.ts | 8 - .../HighlightedProvider.tsx | 11 +- .../src/context/ZAxisContextProvider.tsx | 2 +- packages/x-charts/src/internals/getSymbol.ts | 16 +- packages/x-charts/src/internals/index.ts | 1 - .../x-charts/src/models/seriesType/bar.ts | 2 +- .../x-charts/src/models/seriesType/common.ts | 14 +- .../x-charts/src/models/seriesType/config.ts | 2 +- .../x-charts/src/models/seriesType/line.ts | 2 +- .../x-charts/src/models/seriesType/pie.ts | 2 +- .../x-charts/src/models/seriesType/scatter.ts | 7 +- packages/x-codemod/README.md | 55 +- packages/x-codemod/package.json | 7 +- packages/x-codemod/src/types.ts | 7 +- .../v8.0.0/charts/preset-safe/actual.spec.tsx | 9 + .../charts/preset-safe/expected.spec.tsx | 16 + .../src/v8.0.0/charts/preset-safe/index.ts | 9 + .../charts/preset-safe/preset-safe.test.ts | 41 + .../rename-legend-to-slots-legend/index.ts | 79 + .../src/v8.0.0/preset-safe/actual.spec.js | 15 + .../src/v8.0.0/preset-safe/expected.spec.js | 18 + .../x-codemod/src/v8.0.0/preset-safe/index.ts | 10 + .../v8.0.0/preset-safe/preset-safe.test.ts | 27 + .../tree-view/preset-safe/actual.spec.tsx | 11 + .../tree-view/preset-safe/expected.spec.tsx | 11 + .../src/v8.0.0/tree-view/preset-safe/index.ts | 9 + .../tree-view/preset-safe/preset-safe.test.ts | 41 + .../actual-community-nested-imports.spec.tsx | 94 + .../actual-community-root-imports.spec.tsx | 83 + .../actual-pro-root-imports.spec.tsx | 83 + ...expected-community-nested-imports.spec.tsx | 94 + .../expected-community-root-imports.spec.tsx | 83 + .../expected-pro-root-imports.spec.tsx | 83 + .../tree-view/rename-tree-item-2/index.ts | 98 + .../rename-tree-item-2.test.ts | 44 + packages/x-data-grid-generator/package.json | 4 +- packages/x-data-grid-premium/package.json | 6 +- .../GridColumnMenuAggregationItem.tsx | 22 +- .../components/GridColumnMenuRowGroupItem.tsx | 9 +- .../GridColumnMenuRowUngroupItem.tsx | 9 +- .../components/GridExcelExportMenuItem.tsx | 7 +- .../cellSelection/useGridCellSelection.ts | 3 +- packages/x-data-grid-pro/package.json | 6 +- .../components/GridColumnMenuPinningItem.tsx | 17 +- .../headerFiltering/GridHeaderFilterMenu.tsx | 16 +- packages/x-data-grid/package.json | 6 +- .../src/components/base/GridOverlays.tsx | 20 +- .../src/components/cell/GridActionsCell.tsx | 5 +- .../components/cell/GridActionsCellItem.tsx | 6 +- .../menuItems/GridColumnMenuFilterItem.tsx | 5 +- .../menuItems/GridColumnMenuHideItem.tsx | 5 +- .../menuItems/GridColumnMenuManageItem.tsx | 5 +- .../menuItems/GridColumnMenuSortItem.tsx | 13 +- .../toolbar/GridToolbarColumnsButton.tsx | 2 +- .../toolbar/GridToolbarDensitySelector.tsx | 10 +- .../components/toolbar/GridToolbarExport.tsx | 12 +- .../toolbar/GridToolbarExportContainer.tsx | 5 +- .../virtualization/GridVirtualScrollbar.tsx | 10 +- .../rowSelection/useGridRowSelection.ts | 37 +- .../src/hooks/features/rows/gridRowsUtils.ts | 6 +- .../virtualization/useGridVirtualScroller.tsx | 15 +- packages/x-data-grid/src/locales/plPL.ts | 48 +- packages/x-data-grid/src/material/index.ts | 4 + .../src/models/gridSlotsComponent.ts | 10 + .../src/models/gridSlotsComponentsProps.ts | 6 + packages/x-date-pickers-pro/package.json | 6 +- .../DateRangeCalendar/DateRangeCalendar.tsx | 119 +- .../DateRangeCalendar.types.ts | 66 +- .../src/DateRangeCalendar/useDragRange.ts | 41 +- .../DateRangePicker/DateRangePicker.test.tsx | 6 +- .../src/DateRangePicker/DateRangePicker.tsx | 25 +- .../DateRangePicker/DateRangePicker.types.ts | 41 +- .../DateRangePickerToolbar.tsx | 26 +- .../src/DateRangePicker/index.ts | 1 + .../src/DateRangePicker/shared.tsx | 47 +- .../DateRangePickerDay/DateRangePickerDay.tsx | 26 +- .../DateTimeRangePicker.tsx | 28 +- .../DateTimeRangePicker.types.ts | 57 +- .../DateTimeRangePickerTabs.tsx | 5 +- .../DateTimeRangePickerTimeWrapper.tsx | 24 +- .../DateTimeRangePickerToolbar.tsx | 50 +- .../src/DateTimeRangePicker/index.ts | 1 + .../src/DateTimeRangePicker/shared.tsx | 79 +- .../DesktopDateRangePicker.tsx | 44 +- .../DesktopDateRangePicker.types.ts | 26 +- .../tests/DesktopDateRangePicker.test.tsx | 116 +- .../describes.DesktopDateRangePicker.test.tsx | 2 +- .../DesktopDateTimeRangePicker.tsx | 54 +- .../DesktopDateTimeRangePicker.types.ts | 27 +- .../tests/DesktopDateTimeRangePicker.test.tsx | 10 +- ...cribes.DesktopDateTimeRangePicker.test.tsx | 2 +- .../MobileDateRangePicker.tsx | 44 +- .../MobileDateRangePicker.types.ts | 26 +- .../tests/MobileDateRangePicker.test.tsx | 44 +- .../describes.MobileDateRangePicker.test.tsx | 2 +- .../MobileDateTimeRangePicker.tsx | 53 +- .../MobileDateTimeRangePicker.types.ts | 27 +- ...scribes.MobileDateTimeRangePicker.test.tsx | 2 +- .../MultiInputDateRangeField.tsx | 29 +- .../MultiInputDateRangeField.types.ts | 28 +- ...escribes.MultiInputDateRangeField.test.tsx | 2 +- .../MultiInputDateTimeRangeField.tsx | 32 +- .../MultiInputDateTimeRangeField.types.ts | 25 +- ...ibes.MultiInputDateTimeRangeField.test.tsx | 2 +- .../MultiInputTimeRangeField.tsx | 29 +- .../MultiInputTimeRangeField.types.ts | 28 +- ...escribes.MultiInputTimeRangeField.test.tsx | 2 +- .../PickersRangeCalendarHeader.tsx | 16 +- .../PickersRangeCalendarHeader.types.ts | 9 +- .../SingleInputDateRangeField.tsx | 23 +- .../SingleInputDateRangeField.types.ts | 23 +- ...scribes.SingleInputDateRangeField.test.tsx | 2 +- ...editing.SingleInputDateRangeField.test.tsx | 40 +- ...lection.SingleInputDateRangeField.test.tsx | 30 +- .../useSingleInputDateRangeField.ts | 16 +- .../SingleInputDateTimeRangeField.tsx | 26 +- .../SingleInputDateTimeRangeField.types.ts | 24 +- ...bes.SingleInputDateTimeRangeField.test.tsx | 2 +- .../useSingleInputDateTimeRangeField.ts | 23 +- .../SingleInputTimeRangeField.tsx | 23 +- .../SingleInputTimeRangeField.types.ts | 24 +- ...scribes.SingleInputTimeRangeField.test.tsx | 2 +- .../useSingleInputTimeRangeField.ts | 16 +- .../StaticDateRangePicker.test.tsx | 2 +- .../StaticDateRangePicker.tsx | 37 +- .../StaticDateRangePicker.types.ts | 23 +- .../dateRangeViewRenderers.tsx | 11 +- packages/x-date-pickers-pro/src/index.ts | 7 - .../internals/hooks/models/useRangePicker.ts | 32 +- .../useDesktopRangePicker.tsx | 33 +- .../useDesktopRangePicker.types.ts | 27 +- .../hooks/useEnrichedRangePickerFieldProps.ts | 53 +- .../useMobileRangePicker.tsx | 33 +- .../useMobileRangePicker.types.ts | 34 +- .../useMultiInputFieldSelectedSections.ts | 2 +- .../useMultiInputDateRangeField.ts | 38 +- .../useMultiInputDateTimeRangeField.ts | 31 +- .../useMultiInputTimeRangeField.ts | 38 +- .../useStaticRangePicker.tsx | 25 +- .../useStaticRangePicker.types.ts | 30 +- .../src/internals/models/dateRange.ts | 7 +- .../src/internals/models/dateTimeRange.ts | 32 +- .../src/internals/models/timeRange.ts | 30 +- .../utils/date-range-manager.test.ts | 5 +- .../src/internals/utils/date-range-manager.ts | 30 +- .../src/internals/utils/date-utils.ts | 34 +- .../src/internals/utils/valueManagers.ts | 21 +- .../src/models/dateRange.ts | 23 +- .../x-date-pickers-pro/src/models/fields.ts | 4 +- .../x-date-pickers-pro/src/models/range.ts | 4 +- .../src/themeAugmentation/props.d.ts | 33 +- .../src/validation/validateDateRange.ts | 23 +- .../src/validation/validateDateTimeRange.ts | 28 +- .../src/validation/validateTimeRange.ts | 22 +- packages/x-date-pickers/package.json | 6 +- .../AdapterDateFns/AdapterDateFns.test.tsx | 6 +- .../src/AdapterDateFns/AdapterDateFns.ts | 2 +- .../AdapterDateFnsBase/AdapterDateFnsBase.ts | 16 +- .../AdapterDateFnsJalali.test.tsx | 2 +- .../AdapterDateFnsJalali.ts | 2 +- .../AdapterDateFnsJalaliV3.test.tsx | 2 +- .../AdapterDateFnsJalaliV3.ts | 2 +- .../src/AdapterDateFnsV3/AdapterDateFnsV3.ts | 2 +- .../src/AdapterDayjs/AdapterDayjs.test.tsx | 12 +- .../src/AdapterDayjs/AdapterDayjs.ts | 12 +- .../src/AdapterLuxon/AdapterLuxon.test.tsx | 6 +- .../src/AdapterLuxon/AdapterLuxon.ts | 6 +- .../src/AdapterMoment/AdapterMoment.test.tsx | 10 +- .../src/AdapterMoment/AdapterMoment.ts | 14 +- .../AdapterMomentHijri.test.tsx | 4 +- .../AdapterMomentHijri/AdapterMomentHijri.ts | 12 +- .../AdapterMomentJalaali.test.tsx | 4 +- .../AdapterMomentJalaali.ts | 15 +- .../src/DateCalendar/DateCalendar.tsx | 61 +- .../src/DateCalendar/DateCalendar.types.ts | 65 +- .../src/DateCalendar/DayCalendar.tsx | 106 +- .../tests/describes.DateCalendar.test.tsx | 2 +- .../tests/validation.DateCalendar.test.tsx | 8 +- .../src/DateCalendar/useCalendarState.tsx | 50 +- .../src/DateCalendar/useIsDateDisabled.ts | 10 +- .../src/DateField/DateField.tsx | 40 +- .../src/DateField/DateField.types.ts | 82 +- .../x-date-pickers/src/DateField/index.ts | 6 +- .../tests/describes.DateField.test.tsx | 4 +- .../tests/editing.DateField.test.tsx | 135 +- .../DateField/tests/format.DateField.test.tsx | 32 +- .../tests/selection.DateField.test.tsx | 56 +- .../src/DateField/useDateField.ts | 9 +- .../src/DatePicker/DatePicker.tsx | 38 +- .../src/DatePicker/DatePicker.types.ts | 40 +- .../src/DatePicker/DatePickerToolbar.tsx | 23 +- .../x-date-pickers/src/DatePicker/shared.tsx | 49 +- .../src/DatePicker/tests/DatePicker.test.tsx | 2 +- .../src/DateTimeField/DateTimeField.tsx | 39 +- .../src/DateTimeField/DateTimeField.types.ts | 98 +- .../x-date-pickers/src/DateTimeField/index.ts | 6 +- .../tests/describes.DateTimeField.test.tsx | 4 +- .../tests/timezone.DateTimeField.test.tsx | 3 +- .../src/DateTimeField/useDateTimeField.ts | 9 +- .../src/DateTimePicker/DateTimePicker.tsx | 39 +- .../DateTimePicker/DateTimePicker.types.ts | 59 +- .../src/DateTimePicker/DateTimePickerTabs.tsx | 7 +- .../DateTimePicker/DateTimePickerToolbar.tsx | 39 +- .../src/DateTimePicker/shared.tsx | 56 +- .../tests/DateTimePicker.test.tsx | 2 +- .../DesktopDatePicker/DesktopDatePicker.tsx | 47 +- .../DesktopDatePicker.types.ts | 28 +- .../describes.DesktopDatePicker.test.tsx | 2 +- .../tests/field.DesktopDatePicker.test.tsx | 10 +- .../DesktopDateTimePicker.tsx | 63 +- .../DesktopDateTimePicker.types.ts | 33 +- .../DesktopDateTimePickerLayout.tsx | 12 +- .../describes.DesktopDateTimePicker.test.tsx | 6 +- .../field.DesktopDateTimePicker.test.tsx | 6 +- .../DesktopTimePicker/DesktopTimePicker.tsx | 33 +- .../DesktopTimePicker.types.ts | 36 +- .../describes.DesktopTimePicker.test.tsx | 8 +- .../tests/field.DesktopTimePicker.test.tsx | 6 +- .../src/DigitalClock/DigitalClock.tsx | 31 +- .../src/DigitalClock/DigitalClock.types.ts | 14 +- .../tests/describes.DigitalClock.test.tsx | 2 +- .../LocalizationProvider.test.tsx | 8 +- .../LocalizationProvider.tsx | 56 +- .../src/MobileDatePicker/MobileDatePicker.tsx | 47 +- .../MobileDatePicker.types.ts | 28 +- .../tests/MobileDatePicker.test.tsx | 37 +- .../tests/describes.MobileDatePicker.test.tsx | 2 +- .../MobileDateTimePicker.tsx | 50 +- .../MobileDateTimePicker.types.ts | 26 +- .../tests/MobileDateTimePicker.test.tsx | 15 +- .../describes.MobileDateTimePicker.test.tsx | 4 +- .../src/MobileTimePicker/MobileTimePicker.tsx | 31 +- .../MobileTimePicker.types.ts | 24 +- .../tests/MobileTimePicker.test.tsx | 4 +- .../tests/describes.MobileTimePicker.test.tsx | 6 +- .../src/MonthCalendar/MonthCalendar.tsx | 41 +- .../src/MonthCalendar/MonthCalendar.types.ts | 19 +- .../tests/describes.MonthCalendar.test.tsx | 2 +- .../MultiSectionDigitalClock.tsx | 40 +- .../MultiSectionDigitalClock.types.ts | 13 +- .../MultiSectionDigitalClock.utils.ts | 22 +- .../tests/MultiSectionDigitalClock.test.tsx | 2 +- ...escribes.MultiSectionDigitalClock.test.tsx | 2 +- .../PickersCalendarHeader.tsx | 28 +- .../PickersCalendarHeader.types.ts | 24 +- .../src/PickersDay/PickersDay.spec.tsx | 4 +- .../src/PickersDay/PickersDay.tsx | 28 +- .../src/PickersLayout/PickersLayout.tsx | 16 +- .../src/PickersLayout/PickersLayout.types.ts | 62 +- .../x-date-pickers/src/PickersLayout/index.ts | 1 + .../src/PickersLayout/usePickerLayout.tsx | 55 +- .../src/StaticDatePicker/StaticDatePicker.tsx | 35 +- .../StaticDatePicker.types.ts | 24 +- .../StaticDateTimePicker.tsx | 42 +- .../StaticDateTimePicker.types.ts | 24 +- .../src/StaticTimePicker/StaticTimePicker.tsx | 26 +- .../StaticTimePicker.types.ts | 22 +- .../x-date-pickers/src/TimeClock/Clock.tsx | 21 +- .../src/TimeClock/ClockNumbers.tsx | 14 +- .../src/TimeClock/TimeClock.tsx | 35 +- .../src/TimeClock/TimeClock.types.ts | 15 +- .../tests/describes.TimeClock.test.tsx | 2 +- .../src/TimeField/TimeField.tsx | 34 +- .../src/TimeField/TimeField.types.ts | 85 +- .../x-date-pickers/src/TimeField/index.ts | 6 +- .../tests/describes.TimeField.test.tsx | 4 +- .../tests/editing.TimeField.test.tsx | 20 +- .../src/TimeField/useTimeField.ts | 9 +- .../src/TimePicker/TimePicker.tsx | 24 +- .../src/TimePicker/TimePicker.types.ts | 45 +- .../src/TimePicker/TimePickerToolbar.tsx | 25 +- .../x-date-pickers/src/TimePicker/shared.tsx | 38 +- .../src/TimePicker/tests/TimePicker.test.tsx | 2 +- .../src/YearCalendar/YearCalendar.tsx | 38 +- .../src/YearCalendar/YearCalendar.types.ts | 19 +- .../tests/describes.YearCalendar.test.tsx | 2 +- .../dateViewRenderers/dateViewRenderers.tsx | 15 +- .../src/hooks/useParsedFormat.ts | 11 +- .../src/hooks/usePickersTranslations.ts | 4 +- .../internals/components/PickersProvider.tsx | 25 +- .../internals/hooks/date-helpers-hooks.tsx | 32 +- .../internals/hooks/defaultizedFieldProps.ts | 35 +- .../internals/hooks/useClockReferenceDate.ts | 10 +- .../useDesktopPicker/useDesktopPicker.tsx | 25 +- .../useDesktopPicker.types.ts | 54 +- .../hooks/useField/buildSectionsFromFormat.ts | 41 +- .../src/internals/hooks/useField/useField.ts | 11 +- .../hooks/useField/useField.types.ts | 104 +- .../hooks/useField/useField.utils.ts | 89 +- .../useField/useFieldCharacterEditing.ts | 18 +- .../internals/hooks/useField/useFieldState.ts | 28 +- .../hooks/useMobilePicker/useMobilePicker.tsx | 22 +- .../useMobilePicker/useMobilePicker.types.ts | 47 +- .../internals/hooks/usePicker/usePicker.ts | 30 +- .../hooks/usePicker/usePicker.types.ts | 26 +- .../hooks/usePicker/usePickerOwnerState.ts | 33 +- .../hooks/usePicker/usePickerProvider.ts | 46 + .../hooks/usePicker/usePickerValue.ts | 25 +- .../hooks/usePicker/usePickerValue.types.ts | 77 +- .../hooks/usePicker/usePickerViews.ts | 25 +- .../hooks/usePickersPrivateContext.ts | 17 + .../hooks/useStaticPicker/useStaticPicker.tsx | 17 +- .../useStaticPicker/useStaticPicker.types.ts | 26 +- .../src/internals/hooks/useUtils.ts | 17 +- .../internals/hooks/useValueWithTimezone.ts | 20 +- .../src/internals/hooks/useViews.tsx | 12 +- .../x-date-pickers/src/internals/index.ts | 4 +- .../src/internals/models/fields.ts | 6 +- .../src/internals/models/helpers.ts | 18 - .../src/internals/models/index.ts | 1 + .../models/props/basePickerProps.tsx | 22 +- .../src/internals/models/props/time.ts | 98 + .../src/internals/models/validation.ts | 45 +- .../src/internals/models/value.ts | 5 + .../src/internals/utils/date-time-utils.ts | 24 +- .../src/internals/utils/date-utils.test.ts | 2 +- .../src/internals/utils/date-utils.ts | 82 +- .../utils/getDefaultReferenceDate.ts | 26 +- .../src/internals/utils/time-utils.ts | 30 +- .../src/internals/utils/valueManagers.ts | 6 +- packages/x-date-pickers/src/locales/beBY.ts | 18 +- packages/x-date-pickers/src/locales/bgBG.ts | 18 +- packages/x-date-pickers/src/locales/caES.ts | 18 +- packages/x-date-pickers/src/locales/csCZ.ts | 18 +- packages/x-date-pickers/src/locales/daDK.ts | 18 +- packages/x-date-pickers/src/locales/deDE.ts | 18 +- packages/x-date-pickers/src/locales/elGR.ts | 34 +- packages/x-date-pickers/src/locales/enUS.ts | 22 +- packages/x-date-pickers/src/locales/esES.ts | 18 +- packages/x-date-pickers/src/locales/eu.ts | 18 +- packages/x-date-pickers/src/locales/faIR.ts | 18 +- packages/x-date-pickers/src/locales/fiFI.ts | 18 +- packages/x-date-pickers/src/locales/frFR.ts | 16 +- packages/x-date-pickers/src/locales/heIL.ts | 18 +- packages/x-date-pickers/src/locales/hrHR.ts | 18 +- packages/x-date-pickers/src/locales/huHU.ts | 18 +- packages/x-date-pickers/src/locales/isIS.ts | 18 +- packages/x-date-pickers/src/locales/itIT.ts | 18 +- packages/x-date-pickers/src/locales/jaJP.ts | 18 +- packages/x-date-pickers/src/locales/koKR.ts | 18 +- packages/x-date-pickers/src/locales/kzKZ.ts | 18 +- packages/x-date-pickers/src/locales/mk.ts | 18 +- packages/x-date-pickers/src/locales/nbNO.ts | 18 +- packages/x-date-pickers/src/locales/nlNL.ts | 18 +- packages/x-date-pickers/src/locales/nnNO.ts | 18 +- packages/x-date-pickers/src/locales/plPL.ts | 18 +- packages/x-date-pickers/src/locales/ptBR.ts | 21 +- packages/x-date-pickers/src/locales/ptPT.ts | 18 +- packages/x-date-pickers/src/locales/roRO.ts | 18 +- packages/x-date-pickers/src/locales/ruRU.ts | 18 +- packages/x-date-pickers/src/locales/skSK.ts | 18 +- packages/x-date-pickers/src/locales/svSE.ts | 18 +- packages/x-date-pickers/src/locales/trTR.ts | 18 +- packages/x-date-pickers/src/locales/ukUA.ts | 18 +- packages/x-date-pickers/src/locales/urPK.ts | 18 +- .../locales/utils/getPickersLocalization.ts | 24 +- .../src/locales/utils/pickersLocaleTextApi.ts | 70 +- packages/x-date-pickers/src/locales/viVN.ts | 18 +- packages/x-date-pickers/src/locales/zhCN.ts | 18 +- packages/x-date-pickers/src/locales/zhHK.ts | 18 +- .../x-date-pickers/src/models/adapters.ts | 355 +-- packages/x-date-pickers/src/models/fields.ts | 4 +- packages/x-date-pickers/src/models/pickers.ts | 12 +- .../tests/fieldKeyboardInteraction.test.tsx | 30 +- .../src/themeAugmentation/props.d.ts | 56 +- .../timeViewRenderers/timeViewRenderers.tsx | 24 +- .../src/validation/extractValidationProps.ts | 12 +- .../src/validation/useValidation.ts | 34 +- .../src/validation/validateDate.ts | 24 +- .../src/validation/validateDateTime.ts | 22 +- .../src/validation/validateTime.ts | 14 +- packages/x-internals/package.json | 4 +- packages/x-internals/src/types/index.ts | 17 + packages/x-license/package.json | 4 +- packages/x-tree-view-pro/package.json | 6 +- .../src/RichTreeViewPro/RichTreeViewPro.tsx | 20 + .../RichTreeViewPro/RichTreeViewPro.types.ts | 3 +- packages/x-tree-view-pro/src/index.ts | 11 +- .../useTreeViewItemsReordering.itemPlugin.ts | 17 +- .../useTreeViewItemsReordering.types.ts | 28 +- packages/x-tree-view/package.json | 6 +- .../src/RichTreeView/RichTreeView.tsx | 20 + .../src/RichTreeView/RichTreeView.types.ts | 16 +- .../src/SimpleTreeView/SimpleTreeView.tsx | 20 + .../src/TreeItem/TreeItem.test.tsx | 49 +- .../x-tree-view/src/TreeItem/TreeItem.tsx | 676 ++--- .../src/TreeItem/TreeItem.types.ts | 140 +- packages/x-tree-view/src/TreeItem/index.ts | 14 +- .../TreeItemDragAndDropOverlay.tsx | 76 + .../TreeItemDragAndDropOverlay.types.ts | 7 + .../src/TreeItemDragAndDropOverlay/index.ts | 2 + .../src/TreeItemIcon/TreeItemIcon.tsx | 84 + .../src/TreeItemIcon/TreeItemIcon.types.ts | 43 + .../x-tree-view/src/TreeItemIcon/index.ts | 6 + .../TreeItemLabelInput/TreeItemLabelInput.tsx | 23 + .../TreeItemLabelInput.types.ts | 15 + .../src/TreeItemLabelInput/index.ts | 2 + .../src/TreeItemProvider/TreeItemProvider.tsx | 24 + .../TreeItemProvider.types.ts | 7 + .../x-tree-view/src/TreeItemProvider/index.ts | 2 + .../x-tree-view/src/TreeView/TreeView.tsx | 20 + packages/x-tree-view/src/hooks/index.ts | 2 +- .../src/hooks/useTreeItemUtils/index.ts | 1 + .../useTreeItemUtils/useTreeItemUtils.tsx | 193 ++ packages/x-tree-view/src/index.ts | 11 +- .../TreeViewProvider.types.ts | 5 +- .../components/RichTreeViewItems.tsx | 4 +- packages/x-tree-view/src/internals/index.ts | 1 - .../src/internals/models/helpers.ts | 14 - .../src/internals/models/itemPlugin.ts | 35 +- .../src/internals/models/plugin.ts | 2 +- .../useTreeViewExpansion.test.tsx | 566 ++-- .../useTreeViewExpansion.types.ts | 3 +- .../useTreeViewItems.types.ts | 3 +- .../useTreeViewJSXItems.tsx | 8 +- .../useTreeViewLabel.itemPlugin.ts | 10 +- .../useTreeViewLabel.types.ts | 13 +- .../useTreeViewSelection.itemPlugin.ts | 111 + .../useTreeViewSelection.test.tsx | 122 + .../useTreeViewSelection.ts | 76 +- .../useTreeViewSelection.types.ts | 41 +- .../useTreeViewSelection.utils.ts | 131 +- packages/x-tree-view/src/models/items.ts | 5 + .../src/themeAugmentation/components.d.ts | 5 - .../src/themeAugmentation/overrides.d.ts | 1 - .../src/themeAugmentation/props.d.ts | 4 +- .../themeAugmentation.spec.ts | 19 - packages/x-tree-view/src/useTreeItem/index.ts | 15 + .../src/useTreeItem/useTreeItem.test.tsx | 164 + .../src/useTreeItem/useTreeItem.ts | 377 +++ .../src/useTreeItem/useTreeItem.types.ts | 235 ++ pnpm-lock.yaml | 2653 ++++++++--------- scripts/buildApiDocs/chartsSettings/index.ts | 6 +- scripts/buildApiDocs/gridSettings/index.ts | 6 +- scripts/buildApiDocs/pickersSettings/index.ts | 6 +- .../buildApiDocs/treeViewSettings/index.ts | 6 +- scripts/releaseChangelog.mjs | 2 +- scripts/x-data-grid-premium.exports.json | 2 + scripts/x-data-grid-pro.exports.json | 2 + scripts/x-data-grid.exports.json | 2 + scripts/x-date-pickers-pro.exports.json | 7 +- scripts/x-date-pickers.exports.json | 4 +- scripts/x-tree-view-pro.exports.json | 66 +- scripts/x-tree-view.exports.json | 66 +- .../DatePicker/BasicDesktopDatePicker.tsx | 1 - ...topDatePickerNonAccessibleDOMStructure.tsx | 17 + .../BasicDesktopDateRangePicker.tsx | 2 +- .../DatePicker/BasicDesktopDateTimePicker.tsx | 2 +- .../DatePicker/BasicMobileDatePicker.tsx | 2 +- ...atePickerFormNonAccessibleDOMStructure.tsx | 29 + ...thClearActionNonAccessibleDOMStructure.tsx | 22 + .../ReadonlyDesktopDateRangePickerSingle.tsx | 16 + ...ePickerSingleNonAccessibleDOMStructure.tsx | 17 + .../SingleDesktopDateRangePickerWithTZ.tsx | 1 - test/e2e/index.test.ts | 35 +- test/package.json | 4 +- test/performance-charts/package.json | 8 +- .../regressions/data-grid/DataGridOverlays.js | 168 ++ test/utils/pickers/adapters.ts | 4 +- .../describeGregorianAdapter.ts | 22 +- .../describeGregorianAdapter.types.ts | 20 +- .../testCalculations.ts | 5 +- .../describeHijriAdapter.ts | 6 +- .../describeHijriAdapter.types.ts | 6 +- .../describeJalaliAdapter.ts | 6 +- .../describeJalaliAdapter.types.ts | 6 +- .../testTextFieldKeyboardRangeValidation.tsx | 49 +- .../testTextFieldRangeValidation.tsx | 21 +- .../testTextFieldValidation.tsx | 15 +- .../pickers/describeValue/describeValue.tsx | 3 +- .../testControlledUnControlled.tsx | 1 - .../describeValue/testPickerActionBar.tsx | 6 - .../testPickerOpenCloseLifeCycle.tsx | 19 +- .../pickers/describeValue/testShortcuts.tsx | 3 - test/utils/pickers/fields.tsx | 8 +- test/utils/pickers/misc.ts | 10 +- test/utils/pickers/viewHandlers.ts | 6 +- .../describeTreeView/describeTreeView.tsx | 77 +- .../describeTreeView.types.ts | 8 +- test/utils/tree-view/fakeContextValue.ts | 1 + 835 files changed, 15198 insertions(+), 10261 deletions(-) create mode 100644 .github/workflows/create-cherry-pick-pr.yml create mode 100644 docs/data/chartsApiPages.ts create mode 100644 docs/data/data-grid/layout/GridOverlayHeight.js create mode 100644 docs/data/data-grid/layout/GridOverlayHeight.tsx create mode 100644 docs/data/data-grid/layout/GridOverlayHeight.tsx.preview create mode 100644 docs/data/dataGridApiPages.ts create mode 100644 docs/data/date-pickers/custom-field/behavior-autocomplete/MaterialDatePicker.js create mode 100644 docs/data/date-pickers/custom-field/behavior-autocomplete/MaterialDatePicker.tsx create mode 100644 docs/data/date-pickers/custom-field/behavior-autocomplete/MaterialDatePicker.tsx.preview create mode 100644 docs/data/date-pickers/custom-field/behavior-button/MaterialDatePicker.js create mode 100644 docs/data/date-pickers/custom-field/behavior-button/MaterialDatePicker.tsx create mode 100644 docs/data/date-pickers/custom-field/behavior-button/MaterialDatePicker.tsx.preview create mode 100644 docs/data/date-pickers/custom-field/behavior-button/MaterialDateRangePicker.js create mode 100644 docs/data/date-pickers/custom-field/behavior-button/MaterialDateRangePicker.tsx create mode 100644 docs/data/date-pickers/custom-field/behavior-button/MaterialDateRangePicker.tsx.preview create mode 100644 docs/data/date-pickers/custom-field/behavior-masked-text-field/MaskedMaterialTextField.js create mode 100644 docs/data/date-pickers/custom-field/behavior-masked-text-field/MaskedMaterialTextField.tsx create mode 100644 docs/data/date-pickers/custom-field/behavior-masked-text-field/MaskedMaterialTextField.tsx.preview create mode 100644 docs/data/date-pickers/custom-field/behavior-read-only-text-field/MaterialDatePicker.js create mode 100644 docs/data/date-pickers/custom-field/behavior-read-only-text-field/MaterialDatePicker.tsx create mode 100644 docs/data/date-pickers/custom-field/behavior-read-only-text-field/MaterialDatePicker.tsx.preview create mode 100644 docs/data/datePickersApiPages.ts create mode 100644 docs/data/migration/migration-charts-v7/migration-charts-v7.md create mode 100644 docs/data/migration/migration-data-grid-v7/migration-data-grid-v7.md create mode 100644 docs/data/migration/migration-pickers-v7/migration-pickers-v7.md create mode 100644 docs/data/migration/migration-tree-view-v7/migration-tree-view-v7.md create mode 100644 docs/data/pickersAdapterOverride.ts create mode 100644 docs/data/tree-view/datasets/employees.ts create mode 100644 docs/data/tree-view/rich-tree-view/selection/SelectionPropagation.js create mode 100644 docs/data/tree-view/rich-tree-view/selection/SelectionPropagation.tsx create mode 100644 docs/data/tree-view/tree-item-customization/useTreeItemHookProperties.js create mode 100644 docs/data/tree-view/tree-item-customization/useTreeItemHookProperties.tsx create mode 100644 docs/data/tree-view/tree-item-customization/useTreeItemHookProperties.tsx.preview create mode 100644 docs/data/tree-view/tree-item-customization/useTreeItemHookPublicAPI.js create mode 100644 docs/data/tree-view/tree-item-customization/useTreeItemHookPublicAPI.tsx create mode 100644 docs/data/tree-view/tree-item-customization/useTreeItemHookPublicAPI.tsx.preview create mode 100644 docs/data/tree-view/tree-item-customization/useTreeItemHookStatus.js create mode 100644 docs/data/tree-view/tree-item-customization/useTreeItemHookStatus.tsx create mode 100644 docs/data/tree-view/tree-item-customization/useTreeItemHookStatus.tsx.preview create mode 100644 docs/data/treeViewApiPages.ts create mode 100644 docs/pages/x/api/tree-view/tree-item-drag-and-drop-overlay.js create mode 100644 docs/pages/x/api/tree-view/tree-item-drag-and-drop-overlay.json create mode 100644 docs/pages/x/api/tree-view/tree-item-icon.js create mode 100644 docs/pages/x/api/tree-view/tree-item-icon.json create mode 100644 docs/pages/x/migration/migration-charts-v7.js create mode 100644 docs/pages/x/migration/migration-data-grid-v7.js create mode 100644 docs/pages/x/migration/migration-pickers-v7.js create mode 100644 docs/pages/x/migration/migration-tree-view-v7.js create mode 100644 docs/translations/api-docs/tree-view/tree-item-drag-and-drop-overlay/tree-item-drag-and-drop-overlay.json create mode 100644 docs/translations/api-docs/tree-view/tree-item-icon/tree-item-icon.json create mode 100644 packages/x-codemod/src/v8.0.0/charts/preset-safe/actual.spec.tsx create mode 100644 packages/x-codemod/src/v8.0.0/charts/preset-safe/expected.spec.tsx create mode 100644 packages/x-codemod/src/v8.0.0/charts/preset-safe/index.ts create mode 100644 packages/x-codemod/src/v8.0.0/charts/preset-safe/preset-safe.test.ts create mode 100644 packages/x-codemod/src/v8.0.0/charts/rename-legend-to-slots-legend/index.ts create mode 100644 packages/x-codemod/src/v8.0.0/preset-safe/actual.spec.js create mode 100644 packages/x-codemod/src/v8.0.0/preset-safe/expected.spec.js create mode 100644 packages/x-codemod/src/v8.0.0/preset-safe/index.ts create mode 100644 packages/x-codemod/src/v8.0.0/preset-safe/preset-safe.test.ts create mode 100644 packages/x-codemod/src/v8.0.0/tree-view/preset-safe/actual.spec.tsx create mode 100644 packages/x-codemod/src/v8.0.0/tree-view/preset-safe/expected.spec.tsx create mode 100644 packages/x-codemod/src/v8.0.0/tree-view/preset-safe/index.ts create mode 100644 packages/x-codemod/src/v8.0.0/tree-view/preset-safe/preset-safe.test.ts create mode 100644 packages/x-codemod/src/v8.0.0/tree-view/rename-tree-item-2/actual-community-nested-imports.spec.tsx create mode 100644 packages/x-codemod/src/v8.0.0/tree-view/rename-tree-item-2/actual-community-root-imports.spec.tsx create mode 100644 packages/x-codemod/src/v8.0.0/tree-view/rename-tree-item-2/actual-pro-root-imports.spec.tsx create mode 100644 packages/x-codemod/src/v8.0.0/tree-view/rename-tree-item-2/expected-community-nested-imports.spec.tsx create mode 100644 packages/x-codemod/src/v8.0.0/tree-view/rename-tree-item-2/expected-community-root-imports.spec.tsx create mode 100644 packages/x-codemod/src/v8.0.0/tree-view/rename-tree-item-2/expected-pro-root-imports.spec.tsx create mode 100644 packages/x-codemod/src/v8.0.0/tree-view/rename-tree-item-2/index.ts create mode 100644 packages/x-codemod/src/v8.0.0/tree-view/rename-tree-item-2/rename-tree-item-2.test.ts create mode 100644 packages/x-date-pickers/src/internals/hooks/usePicker/usePickerProvider.ts create mode 100644 packages/x-date-pickers/src/internals/hooks/usePickersPrivateContext.ts create mode 100644 packages/x-date-pickers/src/internals/models/props/time.ts create mode 100644 packages/x-date-pickers/src/internals/models/value.ts create mode 100644 packages/x-internals/src/types/index.ts create mode 100644 packages/x-tree-view/src/TreeItemDragAndDropOverlay/TreeItemDragAndDropOverlay.tsx create mode 100644 packages/x-tree-view/src/TreeItemDragAndDropOverlay/TreeItemDragAndDropOverlay.types.ts create mode 100644 packages/x-tree-view/src/TreeItemDragAndDropOverlay/index.ts create mode 100644 packages/x-tree-view/src/TreeItemIcon/TreeItemIcon.tsx create mode 100644 packages/x-tree-view/src/TreeItemIcon/TreeItemIcon.types.ts create mode 100644 packages/x-tree-view/src/TreeItemIcon/index.ts create mode 100644 packages/x-tree-view/src/TreeItemLabelInput/TreeItemLabelInput.tsx create mode 100644 packages/x-tree-view/src/TreeItemLabelInput/TreeItemLabelInput.types.ts create mode 100644 packages/x-tree-view/src/TreeItemLabelInput/index.ts create mode 100644 packages/x-tree-view/src/TreeItemProvider/TreeItemProvider.tsx create mode 100644 packages/x-tree-view/src/TreeItemProvider/TreeItemProvider.types.ts create mode 100644 packages/x-tree-view/src/TreeItemProvider/index.ts create mode 100644 packages/x-tree-view/src/hooks/useTreeItemUtils/index.ts create mode 100644 packages/x-tree-view/src/hooks/useTreeItemUtils/useTreeItemUtils.tsx create mode 100644 packages/x-tree-view/src/internals/plugins/useTreeViewSelection/useTreeViewSelection.itemPlugin.ts create mode 100644 packages/x-tree-view/src/useTreeItem/index.ts create mode 100644 packages/x-tree-view/src/useTreeItem/useTreeItem.test.tsx create mode 100644 packages/x-tree-view/src/useTreeItem/useTreeItem.ts create mode 100644 packages/x-tree-view/src/useTreeItem/useTreeItem.types.ts create mode 100644 test/e2e/fixtures/DatePicker/BasicDesktopDatePickerNonAccessibleDOMStructure.tsx create mode 100644 test/e2e/fixtures/DatePicker/DesktopDatePickerFormNonAccessibleDOMStructure.tsx create mode 100644 test/e2e/fixtures/DatePicker/MobileDatePickerWithClearActionNonAccessibleDOMStructure.tsx create mode 100644 test/e2e/fixtures/DatePicker/ReadonlyDesktopDateRangePickerSingle.tsx create mode 100644 test/e2e/fixtures/DatePicker/ReadonlyDesktopDateRangePickerSingleNonAccessibleDOMStructure.tsx create mode 100644 test/regressions/data-grid/DataGridOverlays.js diff --git a/.circleci/config.yml b/.circleci/config.yml index 7db19933a6e7..a5685e260757 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -110,7 +110,7 @@ jobs: name: '`pnpm dedupe` was run?' command: | # #default-branch-switch - if [[ $(git diff --name-status v7.x | grep pnpm-lock) == "" ]]; + if [[ $(git diff --name-status master | grep pnpm-lock) == "" ]]; then echo "No changes to dependencies detected. Skipping..." else @@ -160,7 +160,7 @@ jobs: name: '`pnpm prettier` changes committed?' command: | # #default-branch-switch - if [[ $(git diff --name-status v7.x | grep pnpm-lock) == "" ]]; + if [[ $(git diff --name-status master | grep pnpm-lock) == "" ]]; then pnpm prettier --check else @@ -203,13 +203,24 @@ jobs: name: '`pnpm @mui/x-charts-vendor build` was run?' command: | # #default-branch-switch - if [[ $(git diff --name-status v7.x | grep pnpm-lock) == "" ]]; + if [[ $(git diff --name-status master | grep pnpm-lock) == "" ]]; then echo "No changes to dependencies detected. Skipping..." else pnpm --filter @mui/x-charts-vendor build git add -A && git diff --exit-code --staged fi + - run: + name: 'No dynamic date library import in the Pickers built types?' + command: | + pnpm --filter @mui/x-date-pickers* prebuild + pnpm --filter @mui/x-date-pickers* build:types + if grep -nr 'import("luxon")\|import("dayjs")\|import("moment")' --exclude Adapter*.d.ts packages/{x-date-pickers,x-date-pickers-pro}/build + then + exit 1 + else + exit 0 + fi test_browser: <<: *default-job diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index ce61542f2bc3..99c62e16f892 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -16,10 +16,10 @@ jobs: security-events: write steps: - name: Checkout repository - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@f779452ac5af1c261dce0346a8f964149f49322b # v3.26.13 + uses: github/codeql-action/init@662472033e021d55d94146f66f6058822b0b39fd # v3.27.0 with: languages: typescript # If you wish to specify custom queries, you can do so here or in a config file. @@ -29,4 +29,4 @@ jobs: # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs # queries: security-extended,security-and-quality - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@f779452ac5af1c261dce0346a8f964149f49322b # v3.26.13 + uses: github/codeql-action/analyze@662472033e021d55d94146f66f6058822b0b39fd # v3.27.0 diff --git a/.github/workflows/codspeed.yml b/.github/workflows/codspeed.yml index 42a715a8669b..c0df4ca87ef7 100644 --- a/.github/workflows/codspeed.yml +++ b/.github/workflows/codspeed.yml @@ -34,12 +34,12 @@ jobs: (github.event_name == 'pull_request' && github.event.action != 'labeled' && contains(github.event.pull_request.labels.*.name, 'component: charts')) }} steps: - - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0 with: run_install: false - name: Use Node.js 20.x - uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 + uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 with: node-version: 20 cache: 'pnpm' # https://github.com/actions/setup-node/blob/main/docs/advanced-usage.md#caching-packages-dependencies diff --git a/.github/workflows/create-cherry-pick-pr.yml b/.github/workflows/create-cherry-pick-pr.yml new file mode 100644 index 000000000000..0d5381c25b9d --- /dev/null +++ b/.github/workflows/create-cherry-pick-pr.yml @@ -0,0 +1,18 @@ +name: Create cherry-pick PR +on: + pull_request_target: + branches: + - 'v*.x' + - 'master' + types: ['closed'] + +permissions: {} + +jobs: + create_pr: + name: Create cherry-pick PR + uses: mui/mui-public/.github/workflows/prs_create-cherry-pick-pr.yml@master + permissions: + contents: write + issues: write + pull-requests: write diff --git a/.github/workflows/l10n.yml b/.github/workflows/l10n.yml index 20da63d2e474..435a320e346d 100644 --- a/.github/workflows/l10n.yml +++ b/.github/workflows/l10n.yml @@ -17,12 +17,12 @@ jobs: issues: write steps: - run: echo "${{ github.actor }}" - - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0 with: run_install: false - name: Use Node.js 20.x - uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 + uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 with: node-version: 20 cache: 'pnpm' # https://github.com/actions/setup-node/blob/main/docs/advanced-usage.md#caching-packages-dependencies diff --git a/.github/workflows/priority-support-validation-prompt.yml b/.github/workflows/priority-support-validation-prompt.yml index 021003075108..03db70fae5a1 100644 --- a/.github/workflows/priority-support-validation-prompt.yml +++ b/.github/workflows/priority-support-validation-prompt.yml @@ -31,7 +31,7 @@ jobs: body: | You have created a support request under the ["Priority Support"](https://mui.com/legal/technical-support-sla/#priority-support) terms, which is a paid add-on to MUI X Premium ⏰. Please validate your support key using the link below: - https://tools-public.mui.com/prod/pages/jyhs86t?repo=mui-x&issueId=${{ github.event.issue.number }} + https://tools-public.mui.com/prod/pages/validateSupport?repo=mui-x&issueId=${{ github.event.issue.number }} Do not share your support key in this issue! diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index d4b8443a2a78..0868a58d28b9 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -23,7 +23,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false @@ -44,6 +44,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: Upload to code-scanning - uses: github/codeql-action/upload-sarif@f779452ac5af1c261dce0346a8f964149f49322b # v3.26.13 + uses: github/codeql-action/upload-sarif@662472033e021d55d94146f66f6058822b0b39fd # v3.27.0 with: sarif_file: results.sarif diff --git a/.github/workflows/vale-action.yml b/.github/workflows/vale-action.yml index fb8b37aa93fe..555ecbce6be5 100644 --- a/.github/workflows/vale-action.yml +++ b/.github/workflows/vale-action.yml @@ -12,7 +12,7 @@ jobs: contents: read pull-requests: write steps: - - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - uses: errata-ai/vale-action@d89dee975228ae261d22c15adcd03578634d429c # v2.1.1 continue-on-error: true # GitHub Action flag needed until https://github.com/errata-ai/vale-action/issues/89 is fixed with: diff --git a/CHANGELOG.md b/CHANGELOG.md index deaeddbf9209..2dac6eb4e0c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,148 +3,6 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. -## 7.22.1 - -_Nov 1, 2024_ - -We'd like to offer a big thanks to the 7 contributors who made this release possible. Here are some highlights ✨: - -- 🐞 Bugfixes -- 📚 Documentation improvements -- 🌍 Improve Polish (pl-PL) locale on the Date Pickers - -Special thanks go out to the community contributors who have helped make this release possible: -@wojtkolos, @dpak-maurya, @k-rajat19. -Following are all team members who have contributed to this release: -@LukasTy, @arminmeh, @MBilalShafi, @KenanYusuf, @flaviendelangle. - - - -### Data Grid - -#### `@mui/x-data-grid@7.22.1` - -- [DataGrid] Fix right column group header border (#15152) @KenanYusuf -- [DataGrid] Fix scroll jump when holding down arrow keys (#15167) @arminmeh -- [DataGrid] Move `rowGroupingModelChange` handler to respective hook (#15127) @MBilalShafi -- [DataGrid] Prevent error when deleting the last row (#15153) @dpak-maurya -- [DataGrid] Fix overlay height in autoHeight mode (#15205) @cherniavskii - -#### `@mui/x-data-grid-pro@7.22.1` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan') - -Same changes as in `@mui/x-data-grid@7.22.1`, plus: - -- [DataGridPro] Add list view tests (#15166) @KenanYusuf - -#### `@mui/x-data-grid-premium@7.22.1` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan') - -- [DataGridPremium] Keep focus on the grouping cell on space bar press #15155 @k-rajat19 - -### Date and Time Pickers - -#### `@mui/x-date-pickers@7.22.1` - -- [l10n] Improve Polish (pl-PL) locale (#15177) @wojtkolos - -#### `@mui/x-date-pickers-pro@7.22.1` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan') - -Same changes as in `@mui/x-date-pickers@7.22.1`. - -### Tree View - -#### `@mui/x-tree-view@7.22.1` - -- [TreeView] Export `TreeItem2DragAndDropOverlay` and `TreeItem2LabelInput` from the root of each package (#15208) @flaviendelangle -- [TreeView] Fix drag and drop color usage (#15149) @LukasTy - -#### `@mui/x-tree-view-pro@7.22.1` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan') - -Same changes as in `@mui/x-tree-view@7.22.1`. - -### Docs - -- [docs] Add section explaining how to keep the selection while filtering in Data grid docs (#15199) @arminmeh - -## 7.22.0 - -_Oct 25, 2024_ - -We'd like to offer a big thanks to the 11 contributors who made this release possible. Here are some highlights ✨: - -- 🛰 Introduce [server-side support for Data Grid row grouping](https://mui.com/x/react-data-grid/server-side-data/row-grouping/) -- 🐞 Bugfixes -- 📚 Documentation improvements -- 🌍 Improve Portuguese (pt-BR) locale on the Data Grid component - -Special thanks go out to the community contributors who have helped make this release possible: -@clins1994, @GITPHLAP, @k-rajat19, @kalyan90, @merotosc, @yash49. -Following are all team members who have contributed to this release: -@cherniavskii, @flaviendelangle, @LukasTy, @MBilalShafi, @romgrk. - - - -### Data Grid - -#### `@mui/x-data-grid@7.22.0` - -- [DataGrid] Fix `GridPanelAnchor` positioning (#15022) @k-rajat19 -- [DataGrid] Fix ugly prop-types for the `pageStyle` prop of the `GridPrintExportMenuItem` component (#15015) @flaviendelangle -- [DataGrid] Fix value type in filter model for number and boolean column type (#14733) @k-rajat19 -- [DataGrid] Focus next row when the focused row is deleted (#15067) @cherniavskii -- [DataGrid] Remove some usages of `` and `` (#15013) @romgrk -- [DataGrid] Fix number of rows to display for page size options with negative value (#14890) @kalyan90 -- [l10n] Improve Portuguese (pt-BR) locale (#15021) @k-rajat19 - -#### `@mui/x-data-grid-pro@7.22.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan') - -Same changes as in `@mui/x-data-grid@7.22.0`, plus: - -- [DataGridPro] Fix column pinning layout (#15073) @cherniavskii - -#### `@mui/x-data-grid-premium@7.22.0` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan') - -Same changes as in `@mui/x-data-grid-pro@7.22.0`, plus: - -- [DataGridPremium] Server-side data source with row grouping (#15109) @MBilalShafi - -### Date and Time Pickers - -#### `@mui/x-date-pickers@7.22.0` - -- [pickers] Fix `DateCalendar` timezone management (#15119) @LukasTy -- [pickers] Fix `DigitalClock` time options on a `DST` switch day (#15092) @LukasTy - -#### `@mui/x-date-pickers-pro@7.22.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan') - -Same changes as in `@mui/x-date-pickers@7.22.0`. - -### Charts - -#### `@mui/x-charts@7.22.0` - -- [charts] Export data type in `onAxisClick(_, data)` callback (#15038) @clins1994 - -#### `@mui/x-charts-pro@7.0.0-beta.6` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan') - -Same changes as in `@mui/x-charts@7.22.0`. - -### Tree View - -#### `@mui/x-tree-view@7.22.0` - -- [TreeView] Make the cancellable event types public (#14992) @flaviendelangle - -### Docs - -- [docs] Fix typo in Tree View docs (#15047) @yash49 - -### Core - -- [core] Adjust cherry-pick GH actions (#15101) @LukasTy -- [core] Update prettier target branch (#15100) @MBilalShafi -- [core] Update some `default-branch-switch` instances for `v7.x` (#15085) @MBilalShafi -- [test] Revert to using `fireEvent` instead of `userEvent` (#14927) @LukasTy - ## 7.21.0 _Oct 17, 2024_ @@ -211,7 +69,7 @@ Same changes as in `@mui/x-charts@7.21.0`. #### `@mui/x-tree-view@7.21.0` -- [TreeView] Fix `alpha` usage with CSS variables (#14969) @wangkailang +- [TreeView] Fix `alpha()` usage with CSS variables (#14969) @wangkailang - [TreeView] Fix usage of the `aria-selected` attribute (#14991) @flaviendelangle - [TreeView] Fix hydration error (#15002) @flaviendelangle @@ -431,7 +289,7 @@ Same changes as in `@mui/x-charts@7.19.0`. - [code-infra] Remove custom playwright installation steps (#14728) @Janpot - [code-infra] Replace or remove all instances of `e` identifier (#14724) @samuelsycamore - [infra] Adds community contribution section to the changelog script (#14799) @michelengelen -- [infra] Fix line break in Stack Overflow message @oliviertassinari +- [infra] Fix line break in Stack Overflow message @oliviertassinari - [test] Fix `Escape` event firing event (#14797) @oliviertassinari ## 7.18.0 @@ -523,7 +381,7 @@ Same changes as in `@mui/x-charts@7.18.0`. - [core] Fix 301 link to Next.js and git diff @oliviertassinari - [core] Fix failing CI on `master` (#14644) @cherniavskii - [core] Fix `package.json` repository rule @oliviertassinari -- [core] MUI X repository moved to a new location @oliviertassinari +- [core] MUI X repository moved to a new location @oliviertassinari - [docs-infra] Strengthen CSP (#14581) @oliviertassinari - [license] Finish renaming of LicensingModel (#14615) @oliviertassinari @@ -547,7 +405,7 @@ We'd like to offer a big thanks to the 12 contributors who made this release pos - [DataGrid] Add "does not equal" and "does not contain" filter operators (#14489) @KenanYusuf - [DataGrid] Add demo to the "Custom columns" page that does not use generator (#13695) @arminmeh -- [DataGrid] Fix Voice Over reading the column name twice (#14482) @arminmeh +- [DataGrid] Fix VoiceOver reading the column name twice (#14482) @arminmeh - [DataGrid] Fix bug in CRUD example (#14513) @michelengelen - [DataGrid] Fix failing jsdom tests caused by `:has()` selectors (#14559) @KenanYusuf - [DataGrid] Refactor string operator filter functions (#14564) @KenanYusuf @@ -1367,7 +1225,7 @@ _Jul 5, 2024_ We'd like to offer a big thanks to the 7 contributors who made this release possible. Here are some highlights ✨: - 🔄 Add loading overlay variants, including a skeleton loader option to the Data Grid component. See [Loading overlay docs](https://mui.com/x/react-data-grid/overlays/#loading-overlay) for more details. -- 🌳 Add `selectItem` and `getItemDOMElement` methods to the TreeView component public API +- 🌳 Add `selectItem()` and `getItemDOMElement()` methods to the TreeView component public API - ⛏️ Make the `usePickersTranslations` hook public in the pickers component - 🐞 Bugfixes @@ -1412,7 +1270,7 @@ Same changes as in `@mui/x-date-pickers@7.9.0`. #### `@mui/x-tree-view@7.9.0` -- [TreeView] Add `selectItem` and `getItemDOMElement` methods to the public API (#13485) @flaviendelangle +- [TreeView] Add `selectItem()` and `getItemDOMElement()` methods to the public API (#13485) @flaviendelangle ### Docs @@ -3044,7 +2902,8 @@ Same changes as in `@mui/x-data-grid-pro@7.0.0-beta.4`. ``` - The headless field hooks (e.g.: `useDateField`) now returns a new prop called `enableAccessibleFieldDOMStructure`. - This property is utilized to determine whether the anticipated UI is constructed using an accessible DOM structure. Learn more about this new [accessible DOM structure](/x/react-date-pickers/fields/#accessible-dom-structure). + This property is utilized to determine whether the anticipated UI is constructed using an accessible DOM structure. + Learn more about this new accessible DOM structure in the [v8 migration guide](https://next.mui.com/x/migration/migration-pickers-v7/#new-dom-structure-for-the-field). When building a custom UI, you are most-likely only supporting one DOM structure, so you can remove `enableAccessibleFieldDOMStructure` before it is passed to the DOM: diff --git a/changelogOld/CHANGELOG.v5.md b/changelogOld/CHANGELOG.v5.md index f8f3abc95eeb..e4378fb582ed 100644 --- a/changelogOld/CHANGELOG.v5.md +++ b/changelogOld/CHANGELOG.v5.md @@ -956,7 +956,7 @@ We'd like to offer a big thanks to the 10 contributors who made this release pos - [docs] New location for the legal content (#5595) @oliviertassinari - [docs] Update description of `maxDateTime` prop (#5639) @jurecuhalev -- [docs] Add missing `date-fns` dependency when opening Codesandbox demo (#5692) @cherniavskii +- [docs] Add missing `date-fns` dependency when opening CodeSandbox demo (#5692) @cherniavskii ### Core @@ -2819,7 +2819,7 @@ _Nov 4, 2021_ - [core] Group update of MUI Core (#3055) @oliviertassinari - [core] Ignore `*.tsbuildinfo` files (#3068) @m4theushw - [core] Implement tree-based row management (#2996) @flaviendelangle -- [core] Invert Codesandbox examples on README (#3073) @flaviendelangle +- [core] Invert CodeSandbox examples on README (#3073) @flaviendelangle - [core] Prefix selectors from `useGridContainerProps` with `unsafe` (#3002) @flaviendelangle - [core] Reduce `setGridState` and `applyFilters` call when updating `filterModel` (#3023) @flaviendelangle - [core] Reduce styles complexity (#3012) @DanailH diff --git a/changelogOld/CHANGELOG.v6.md b/changelogOld/CHANGELOG.v6.md index 985e7aba0905..df02a516936d 100644 --- a/changelogOld/CHANGELOG.v6.md +++ b/changelogOld/CHANGELOG.v6.md @@ -20,7 +20,7 @@ Same changes as in `@mui/x-date-pickers@6.19.12`. ### Docs -- [docs] Use MUI X v6 in Codesandbox and Stackblitz demos (#12838) @cherniavskii +- [docs] Use MUI X v6 in CodeSandbox and StackBlitz demos (#12838) @cherniavskii ## 6.19.11 @@ -2596,7 +2596,7 @@ We'd like to offer a big thanks to the 12 contributors who made this release pos - [docs] Fix date pickers typo in the docs (#8939) @richbustos - [docs] Fix master detail demo (#8894) @m4theushw - [docs] Fix typo in clipboard docs (#8971) @MBilalShafi -- [docs] Reduce list of dependencies in Codesandbox/Stackblitz demos (#8535) @cherniavskii +- [docs] Reduce list of dependencies in CodeSandbox/StackBlitz demos (#8535) @cherniavskii ### Core diff --git a/docs/.link-check-errors.txt b/docs/.link-check-errors.txt index 6ecc503cc78a..0438fa82a091 100644 --- a/docs/.link-check-errors.txt +++ b/docs/.link-check-errors.txt @@ -1,2 +1,3 @@ Broken links found by `docs:link-check` that exist: +- https://mui.com/x/react-date-pickers/fields/#accessible-dom-structure diff --git a/docs/constants.js b/docs/constants.js index eea337d13586..7a90120b7174 100644 --- a/docs/constants.js +++ b/docs/constants.js @@ -2,5 +2,5 @@ module.exports = { SOURCE_CODE_REPO: 'https://github.com/mui/mui-x', - SOURCE_GITHUB_BRANCH: 'v7.x', // #default-branch-switch + SOURCE_GITHUB_BRANCH: 'master', // #default-branch-switch }; diff --git a/docs/data/charts/areas-demo/areas-demo.md b/docs/data/charts/areas-demo/areas-demo.md index 92432f02ad72..d784d0996c93 100644 --- a/docs/data/charts/areas-demo/areas-demo.md +++ b/docs/data/charts/areas-demo/areas-demo.md @@ -36,7 +36,7 @@ You can pass this gradient definition as a children of the `` and u To do so you will need to use the [``](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/linearGradient) and [``](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/stop) SVG elements. The first part is to get the SVG total height. -Which can be done with the `useDrawingArea` hook. +Which can be done with the `useDrawingArea()` hook. It's useful to define the `` as a vector that goes from the top to the bottom of our SVG container. Then to define where the gradient should switch from one color to another, you can use the `useYScale` hook to get the y coordinate of value 0. diff --git a/docs/data/charts/axis/axis.md b/docs/data/charts/axis/axis.md index e415596c2583..e8edd2836409 100644 --- a/docs/data/charts/axis/axis.md +++ b/docs/data/charts/axis/axis.md @@ -56,7 +56,7 @@ Which expects an array of value coherent with the `scaleType`: Some series types also require specific axis attributes: - line plots require an `xAxis` to have `data` provided -- bar plots require an `xAxis` with `scaleType='band'` and some `data` provided. +- bar plots require an `xAxis` with `scaleType="band"` and some `data` provided. ### Axis formatter diff --git a/docs/data/charts/bars/BarAnimation.tsx b/docs/data/charts/bars/BarAnimation.tsx index 9bdd402a65e7..13694483bb7b 100644 --- a/docs/data/charts/bars/BarAnimation.tsx +++ b/docs/data/charts/bars/BarAnimation.tsx @@ -5,6 +5,7 @@ import Slider from '@mui/material/Slider'; import FormControlLabel from '@mui/material/FormControlLabel'; import Checkbox from '@mui/material/Checkbox'; import { BarChart } from '@mui/x-charts/BarChart'; +import { HighlightScope } from '@mui/x-charts/context'; export default function BarAnimation() { const [seriesNb, setSeriesNb] = React.useState(2); @@ -67,10 +68,10 @@ export default function BarAnimation() { ); } -const highlightScope = { +const highlightScope: HighlightScope = { highlight: 'series', fade: 'global', -} as const; +}; const series = [ { diff --git a/docs/data/charts/bars/bars.md b/docs/data/charts/bars/bars.md index 11c42dd85e93..606f2895de13 100644 --- a/docs/data/charts/bars/bars.md +++ b/docs/data/charts/bars/bars.md @@ -100,7 +100,7 @@ Learn more about the `colorMap` properties in the [Styling docs](/x/react-charts {{"demo": "ColorScale.js"}} -### Border Radius +### Border radius To give your bar chart rounded corners, you can change the value of the `borderRadius` property on the [BarChart](/x/api/charts/bar-chart/#bar-chart-prop-slots). @@ -117,7 +117,7 @@ Or you can pass `'value'` to display the raw value of the bar. {{"demo": "BarLabel.js"}} -### Custom Labels +### Custom labels You can display, change, or hide labels based on conditional logic. To do so, provide a function to the `barLabel`. @@ -174,7 +174,7 @@ import ChartsOnAxisClickHandler from '@mui/x-charts/ChartsOnAxisClickHandler'; To skip animation at the creation and update of your chart, you can use the `skipAnimation` prop. When set to `true` it skips animation powered by `@react-spring/web`. -Charts containers already use the `useReducedMotion` from `@react-spring/web` to skip animation [according to user preferences](https://react-spring.dev/docs/utilities/use-reduced-motion#why-is-it-important). +Charts containers already use the `useReducedMotion()` from `@react-spring/web` to skip animation [according to user preferences](https://react-spring.dev/docs/utilities/use-reduced-motion#why-is-it-important). ```jsx // For a single component chart diff --git a/docs/data/charts/components/components.md b/docs/data/charts/components/components.md index 5cfff2f9f6d9..be2f67d72870 100644 --- a/docs/data/charts/components/components.md +++ b/docs/data/charts/components/components.md @@ -20,7 +20,7 @@ Charts dimensions are defined by a few props: The term **drawing area** refers to the space available to plot data (scatter points, lines, or pie arcs). The `margin` is used to leave some space for extra elements, such as the axes, the legend, or the title. -You can use the `useDrawingArea` hook in the charts subcomponents to get the coordinates of the **drawing area**. +You can use the `useDrawingArea()` hook in the charts subcomponents to get the coordinates of the **drawing area**. ```jsx import { useDrawingArea } from '@mui/x-charts'; diff --git a/docs/data/charts/gauge/gauge.md b/docs/data/charts/gauge/gauge.md index 30c5df560756..465560c8527d 100644 --- a/docs/data/charts/gauge/gauge.md +++ b/docs/data/charts/gauge/gauge.md @@ -101,7 +101,7 @@ import { ### Creating your components -To create your own components, use the `useGaugeState` hook which provides all you need about the gauge configuration: +To create your own components, use the `useGaugeState()` hook which provides all you need about the gauge configuration: - information about the value: `value`, `valueMin`, `valueMax` - information to plot the arc: `startAngle`, `endAngle`, `outerRadius`, `innerRadius`, `cornerRadius`, `cx`, and `cy` diff --git a/docs/data/charts/getting-started/getting-started.md b/docs/data/charts/getting-started/getting-started.md index 6c6057abfc00..83dbff7001c7 100644 --- a/docs/data/charts/getting-started/getting-started.md +++ b/docs/data/charts/getting-started/getting-started.md @@ -4,20 +4,20 @@ githubLabel: 'component: charts' packageName: '@mui/x-charts' --- -# Charts - Getting Started +# Charts - Getting started -

Get started with the MUI X Charts components. Install the package, configure your application, and start using the components.

+

Install the MUI X Charts package to start building React data visualization components.

## Installation -Using your favorite package manager, install `@mui/x-charts-pro` for the commercial version, or `@mui/x-charts` for the free community version. +Run one of the following commands to install the free Community version or the paid Pro version of the MUI X Charts: {{"component": "modules/components/ChartsInstallationInstructions.js"}} -The Charts package has a peer dependency on `@mui/material`. -If you are not already using it in your project, you can install it with: +The Charts packages have a peer dependency on `@mui/material`. +If you're not already using it, install it with the following command: @@ -37,7 +37,7 @@ yarn add @mui/material @emotion/react @emotion/styled -Please note that [react](https://www.npmjs.com/package/react) and [react-dom](https://www.npmjs.com/package/react-dom) are peer dependencies too: +[`react`](https://www.npmjs.com/package/react) and [`react-dom`](https://www.npmjs.com/package/react-dom) are also peer dependencies: ```json "peerDependencies": { @@ -46,85 +46,66 @@ Please note that [react](https://www.npmjs.com/package/react) and [react-dom](ht }, ``` -### Style engine - -Material UI is using [Emotion](https://emotion.sh/docs/introduction) as a styling engine by default. If you want to use [`styled-components`](https://styled-components.com/) instead, run: - - -```bash npm -npm install @mui/styled-engine-sc styled-components -``` - -```bash pnpm -pnpm add @mui/styled-engine-sc styled-components -``` - -```bash yarn -yarn add @mui/styled-engine-sc styled-components -``` - - - -Take a look at the [Styled engine guide](/material-ui/integrations/styled-components/) for more information about how to configure `styled-components` as the style engine. - ### Usage with D3 To help folks using CommonJS, the `@mui/x-charts` package uses a vendored package named `@mui/x-charts-vendor` to access D3 libraries. +You can import D3 functions from `@mui/x-charts-vendor/d3-color`. -If you need some D3 functions, you can import them with `@mui/x-charts-vendor/d3-color`. +## Rendering Charts -## Displaying charts +MUI X Charts can be rendered as _self-contained_ or _composable_ components. +[Self-contained components](#self-contained-charts) are simpler to get started with and are recommended for most common use cases; more complex visualization (such as combining Bar and Line Charts on a single plot) requires [custom composition](#composable-charts). -A Chart can be rendered in one of two ways: as a single component, or by composing subcomponents. +### Self-contained Charts -### Single charts +Self-contained Chart components are imported and rendered as a single React component (such as `` or ``) which contains all of the necessary subcomponents. -For common use cases, the single component is the recommended way. -Those components' names end with "Chart", as opposed to "Plot", and only require the series prop describing the data to render. +These components require a `series` prop describing the data to render, as well as a numerical value (rendered in pixels) for the `height` prop. +The `width` prop is optional; if no value is provided, the Charts expand to fill the available space. {{"demo": "SimpleCharts.js"}} -### Composed charts +### Composable Charts -To combine different Charts, like Lines with Bars, you can use composition with the `ChartContainer` wrapper. +More complex use cases require composition of the necessary subcomponents inside of a Chart Container wrapper. +Subcomponents include: -Inside this wrapper, render either axis components, such as `XAxis` and `YAxis`, or any plot component like `BarPlot`, `LinePlot`, `AreaPlot`, and `ScatterPlot`. +- Axis components – to define the X and Y axes +- Plot components – to create Bars, Lines, or any other Chart type +- Auxillary components - to add Tooltips, Highlights, and more +- Utilities - such as classes and types -Visit the [Composition page](/x/react-charts/composition/) for more details. +See the [Charts composition documentation](/x/react-charts/composition/) for complete details. -{{"demo": "Combining.js"}} +The demo below shows how to use composition to create a custom Chart that combines a Bar and a Line Chart on a single plot: -### Positions +{{"demo": "Combining.js"}} -Charts are composed of two main areas. -The SVG defined by its `width` and `height` delimits the available space. +## Chart layouts -Within this SVG, a dedicated "drawing area" (aka "plot area") serves as the canvas for data representation. -Here, elements like lines, bars, and areas visually depict the information. -It's controlled by the `margin = {top, bottom, left, right}` object defining the margin between the SVG and the drawing area. +The layout of a Chart is defined by two main spaces: the plot area, and the outer margins. -The space left by margins can display axes, titles, a legend, or any other additional information. +The `width` and `height` props define the dimensions of the SVG which is the root of the chart. +Within this SVG, the plot area (or drawing area) serves as the canvas for data visualization, where the lines, bars or other visual elements are rendered. +The size of the plot area is determined by the `margin = {top, bottom, left, right}` object which defines its outer margins inside the SVG. +The outer margin space is where information like axes, titles, and legends are displayed. -For more information about the position configuration, visit the [styling page](/x/react-charts/styling/#styling). +See the [Styling documentation](/x/react-charts/styling/#placement) for complete details. ## Axis management -MUI X Charts have a flexible approach to axis management, supporting multiple-axis charts with any combination of scales and ranges. - -Visit the [Axis page](/x/react-charts/axis/) for more details. - -## Styling +MUI X Charts take a flexible approach to axis management, with support for multiple axes and any combination of scales and ranges. -MUI X Charts follows the Material UI styling and features all of the customization tools you'd find there, making tweaking charts as straightforward as designing buttons. - -Visit the [Styling page](/x/react-charts/styling/) for more details. +See the [Axis documentation](/x/react-charts/axis/) for complete details. ## TypeScript -In order to benefit from the [CSS overrides](/material-ui/customization/theme-components/#theme-style-overrides) and [default prop customization](/material-ui/customization/theme-components/#theme-default-props) with the theme, TypeScript users need to import the following types. -Internally, it uses module augmentation to extend the default theme structure. +To benefit from [CSS overrides](/material-ui/customization/theme-components/#theme-style-overrides) and [default prop customization](/material-ui/customization/theme-components/#theme-default-props) with the theme, TypeScript users must import the following types. +These types use module augmentation to extend the default theme structure. ```tsx +// only one import is necessary, +// from the version you're currently using. import type {} from '@mui/x-charts/themeAugmentation'; import type {} from '@mui/x-charts-pro/themeAugmentation'; @@ -140,8 +121,3 @@ const theme = createTheme({ }, }); ``` - -:::info -You don't have to import the theme augmentation from both `@mui/x-charts` and `@mui/x-charts-pro` when using `@mui/x-charts-pro`. -Importing it from `@mui/x-charts-pro` is enough. -::: diff --git a/docs/data/charts/highlighting/ControlledHighlight.js b/docs/data/charts/highlighting/ControlledHighlight.js index 6106b70cd9d8..e7b0a1fa951e 100644 --- a/docs/data/charts/highlighting/ControlledHighlight.js +++ b/docs/data/charts/highlighting/ControlledHighlight.js @@ -18,8 +18,8 @@ export default function ControlledHighlight() { seriesId: 'A', dataIndex: 0, }); - const [highlighted, setHighlighted] = React.useState('item'); - const [faded, setFaded] = React.useState('global'); + const [highlight, setHighlight] = React.useState('item'); + const [fade, setFade] = React.useState('global'); const handleHighLightedSeries = (event, newHighLightedSeries) => { if (newHighLightedSeries !== null) { @@ -80,8 +80,8 @@ export default function ControlledHighlight() { series={barChartsProps.series.map((series) => ({ ...series, highlightScope: { - highlighted, - faded, + highlight, + fade, }, }))} highlightedItem={highlightedItem} @@ -98,8 +98,8 @@ export default function ControlledHighlight() { setHighlighted(event.target.value)} + value={highlight} + onChange={(event) => setHighlight(event.target.value)} sx={{ minWidth: 150 }} > none @@ -109,8 +109,8 @@ export default function ControlledHighlight() { setFaded(event.target.value)} + value={fade} + onChange={(event) => setFade(event.target.value)} sx={{ minWidth: 150 }} > none diff --git a/docs/data/charts/highlighting/ControlledHighlight.tsx b/docs/data/charts/highlighting/ControlledHighlight.tsx index 4de4eb1b81ae..b29d70302bbc 100644 --- a/docs/data/charts/highlighting/ControlledHighlight.tsx +++ b/docs/data/charts/highlighting/ControlledHighlight.tsx @@ -19,8 +19,8 @@ export default function ControlledHighlight() { seriesId: 'A', dataIndex: 0, }); - const [highlighted, setHighlighted] = React.useState('item'); - const [faded, setFaded] = React.useState('global'); + const [highlight, setHighlight] = React.useState('item'); + const [fade, setFade] = React.useState('global'); const handleHighLightedSeries = (event: any, newHighLightedSeries: string) => { if (newHighLightedSeries !== null) { @@ -81,8 +81,8 @@ export default function ControlledHighlight() { series={barChartsProps.series.map((series) => ({ ...series, highlightScope: { - highlighted, - faded, + highlight, + fade, } as HighlightScope, }))} highlightedItem={highlightedItem} @@ -99,8 +99,8 @@ export default function ControlledHighlight() { setHighlighted(event.target.value)} + value={highlight} + onChange={(event) => setHighlight(event.target.value)} sx={{ minWidth: 150 }} > none @@ -110,8 +110,8 @@ export default function ControlledHighlight() { setFaded(event.target.value)} + value={fade} + onChange={(event) => setFade(event.target.value)} sx={{ minWidth: 150 }} > none diff --git a/docs/data/charts/highlighting/ElementHighlights.js b/docs/data/charts/highlighting/ElementHighlights.js index 7379647649bd..fe1f78527ae4 100644 --- a/docs/data/charts/highlighting/ElementHighlights.js +++ b/docs/data/charts/highlighting/ElementHighlights.js @@ -88,8 +88,8 @@ const pieChartsParams = { export default function ElementHighlights() { const [chartType, setChartType] = React.useState('bar'); const [withArea, setWithArea] = React.useState(false); - const [highlighted, setHighlighted] = React.useState('item'); - const [faded, setFaded] = React.useState('global'); + const [highlight, setHighlight] = React.useState('item'); + const [fade, setFade] = React.useState('global'); const handleChartType = (event, newChartType) => { if (newChartType !== null) { @@ -123,8 +123,8 @@ export default function ElementHighlights() { series={barChartsParams.series.map((series) => ({ ...series, highlightScope: { - highlighted, - faded, + highlight, + fade, }, }))} /> @@ -137,8 +137,8 @@ export default function ElementHighlights() { ...series, area: withArea, highlightScope: { - highlighted, - faded, + highlight, + fade, }, }))} /> @@ -150,8 +150,8 @@ export default function ElementHighlights() { series={scatterChartsParams.series.map((series) => ({ ...series, highlightScope: { - highlighted, - faded, + highlight, + fade, }, }))} /> @@ -163,8 +163,8 @@ export default function ElementHighlights() { series={pieChartsParams.series.map((series) => ({ ...series, highlightScope: { - highlighted, - faded, + highlight, + fade, }, }))} /> @@ -179,9 +179,9 @@ export default function ElementHighlights() { > setHighlighted(event.target.value)} + label="highlight" + value={highlight} + onChange={(event) => setHighlight(event.target.value)} sx={{ minWidth: 150 }} > none @@ -190,9 +190,9 @@ export default function ElementHighlights() { setFaded(event.target.value)} + label="fade" + value={fade} + onChange={(event) => setFade(event.target.value)} sx={{ minWidth: 150 }} > none diff --git a/docs/data/charts/highlighting/ElementHighlights.tsx b/docs/data/charts/highlighting/ElementHighlights.tsx index d576ed201c50..b961f5ccfd0c 100644 --- a/docs/data/charts/highlighting/ElementHighlights.tsx +++ b/docs/data/charts/highlighting/ElementHighlights.tsx @@ -89,8 +89,8 @@ const pieChartsParams = { export default function ElementHighlights() { const [chartType, setChartType] = React.useState('bar'); const [withArea, setWithArea] = React.useState(false); - const [highlighted, setHighlighted] = React.useState('item'); - const [faded, setFaded] = React.useState('global'); + const [highlight, setHighlight] = React.useState('item'); + const [fade, setFade] = React.useState('global'); const handleChartType = (event: any, newChartType: string) => { if (newChartType !== null) { @@ -124,8 +124,8 @@ export default function ElementHighlights() { series={barChartsParams.series.map((series) => ({ ...series, highlightScope: { - highlighted, - faded, + highlight, + fade, } as HighlightScope, }))} /> @@ -138,8 +138,8 @@ export default function ElementHighlights() { ...series, area: withArea, highlightScope: { - highlighted, - faded, + highlight, + fade, } as HighlightScope, }))} /> @@ -151,8 +151,8 @@ export default function ElementHighlights() { series={scatterChartsParams.series.map((series) => ({ ...series, highlightScope: { - highlighted, - faded, + highlight, + fade, } as HighlightScope, }))} /> @@ -164,8 +164,8 @@ export default function ElementHighlights() { series={pieChartsParams.series.map((series) => ({ ...series, highlightScope: { - highlighted, - faded, + highlight, + fade, } as HighlightScope, }))} /> @@ -180,9 +180,9 @@ export default function ElementHighlights() { > setHighlighted(event.target.value)} + label="highlight" + value={highlight} + onChange={(event) => setHighlight(event.target.value)} sx={{ minWidth: 150 }} > none @@ -191,9 +191,9 @@ export default function ElementHighlights() { setFaded(event.target.value)} + label="fade" + value={fade} + onChange={(event) => setFade(event.target.value)} sx={{ minWidth: 150 }} > none diff --git a/docs/data/charts/highlighting/SyncHighlight.js b/docs/data/charts/highlighting/SyncHighlight.js index b6275d7b6c13..16c16744f7f3 100644 --- a/docs/data/charts/highlighting/SyncHighlight.js +++ b/docs/data/charts/highlighting/SyncHighlight.js @@ -37,11 +37,7 @@ const barChartsProps = { ], xAxis: [{ scaleType: 'band', data: ['A', 'B', 'C', 'D', 'E'] }], height: 400, - slotProps: { - legend: { - hidden: true, - }, - }, + slotProps: { legend: { hidden: true } }, }; const pieChartProps = { @@ -59,9 +55,5 @@ const pieChartProps = { }, ], height: 400, - slotProps: { - legend: { - hidden: true, - }, - }, + slotProps: { legend: { hidden: true } }, }; diff --git a/docs/data/charts/highlighting/SyncHighlight.tsx b/docs/data/charts/highlighting/SyncHighlight.tsx index 1da00da5021c..83ea2a015fae 100644 --- a/docs/data/charts/highlighting/SyncHighlight.tsx +++ b/docs/data/charts/highlighting/SyncHighlight.tsx @@ -38,11 +38,7 @@ const barChartsProps: BarChartProps = { ], xAxis: [{ scaleType: 'band', data: ['A', 'B', 'C', 'D', 'E'] }], height: 400, - slotProps: { - legend: { - hidden: true, - }, - }, + slotProps: { legend: { hidden: true } }, }; const pieChartProps: PieChartProps = { @@ -60,9 +56,5 @@ const pieChartProps: PieChartProps = { }, ], height: 400, - slotProps: { - legend: { - hidden: true, - }, - }, + slotProps: { legend: { hidden: true } }, }; diff --git a/docs/data/charts/lines/LineDataset.js b/docs/data/charts/lines/LineDataset.js index 936c9cd946a7..acc86ac368c7 100644 --- a/docs/data/charts/lines/LineDataset.js +++ b/docs/data/charts/lines/LineDataset.js @@ -14,7 +14,7 @@ const stackStrategy = { const customize = { height: 300, - legend: { hidden: true }, + slotProps: { legend: { hidden: true } }, margin: { top: 5 }, }; diff --git a/docs/data/charts/lines/LineDataset.tsx b/docs/data/charts/lines/LineDataset.tsx index fb00e63ac534..5873c34a71d6 100644 --- a/docs/data/charts/lines/LineDataset.tsx +++ b/docs/data/charts/lines/LineDataset.tsx @@ -14,7 +14,7 @@ const stackStrategy = { const customize = { height: 300, - legend: { hidden: true }, + slotProps: { legend: { hidden: true } }, margin: { top: 5 }, }; diff --git a/docs/data/charts/lines/lines.md b/docs/data/charts/lines/lines.md index be651d4dd57a..de9a55dfb928 100644 --- a/docs/data/charts/lines/lines.md +++ b/docs/data/charts/lines/lines.md @@ -235,7 +235,7 @@ sx={{ To skip animation at the creation and update of your chart, you can use the `skipAnimation` prop. When set to `true` it skips animation powered by `@react-spring/web`. -Charts containers already use the `useReducedMotion` from `@react-spring/web` to skip animation [according to user preferences](https://react-spring.dev/docs/utilities/use-reduced-motion#why-is-it-important). +Charts containers already use the `useReducedMotion()` from `@react-spring/web` to skip animation [according to user preferences](https://react-spring.dev/docs/utilities/use-reduced-motion#why-is-it-important). :::warning If you support interactive ways to add or remove series from your chart, you have to provide the series' id. diff --git a/docs/data/charts/overview/overview.md b/docs/data/charts/overview/overview.md index ef86f4a0793f..92f1d289714d 100644 --- a/docs/data/charts/overview/overview.md +++ b/docs/data/charts/overview/overview.md @@ -7,34 +7,33 @@ packageName: '@mui/x-charts' # MUI X Charts -

A fast and extendable library of react chart components for data visualization.

+

A collection of React chart components for data visualization.

{{"component": "@mui/docs/ComponentLinkHeader", "design": false}} ## Overview -The `@mui/x-charts` is an MIT library for rendering charts relying on [D3.js](https://d3js.org/) for data manipulation and SVG for rendering. -And, like other MUI X components, charts are production-ready components that integrate smoothly into your app. +MUI X Charts is a library of production-ready components for rendering charts with React. +It uses [D3.js](https://d3js.org/) for data manipulation and SVGs for rendering. -With a high level of customization, MUI X Charts provides three levels of customization layers: **single components** with great defaults, extensive **configuration props**, and **subcomponents** for flexible composition. -Additionally, you can also use all the [MUI System](https://mui.com/system/getting-started/) tools, such as the theme override or the `sx` prop. +The components provide a high level of customization, with beautiful defaults as well as extensive configuration props and flexible composition options. +They also have access to all [MUI System](https://mui.com/system/getting-started/) tools such as theme overrides and the `sx` prop. {{"demo": "ChartsOverviewDemo.js", "defaultCodeOpen": true}} -## Using the documentation +## All MUI X Charts -The MUI X Charts documentation has a slightly different structure than other MUI X components. -Instead of having a long page for each, the pages are divided in two: +{{"component": "modules/components/ChartComponentsGrid.js"}} -1. General description of the built-in features the component provides. -2. A set of examples demonstrating the component with customizations. +## Using this documentation -## All MUI X Charts components +Each Chart type has two accompanying documents: -{{"component": "modules/components/ChartComponentsGrid.js"}} +1. **Overview** – a general description of built-in features +2. **Demo** – a collection of custom examples ## Supported features -The features that are shared across multiple Charts components, such as axes and legends, are also documented on separate pages. +Features shared across Chart components such as axes and legends are described in standalone documents: {{"component": "modules/components/ChartFeaturesGrid.js"}} diff --git a/docs/data/charts/pie-demo/PieChartWithCustomizedLabel.js b/docs/data/charts/pie-demo/PieChartWithCustomizedLabel.js index d8382e0a39c5..22fa253558c6 100644 --- a/docs/data/charts/pie-demo/PieChartWithCustomizedLabel.js +++ b/docs/data/charts/pie-demo/PieChartWithCustomizedLabel.js @@ -13,7 +13,7 @@ const sizing = { margin: { right: 5 }, width: 200, height: 200, - legend: { hidden: true }, + slotProps: { legend: { hidden: true } }, }; const TOTAL = data.map((item) => item.value).reduce((a, b) => a + b, 0); diff --git a/docs/data/charts/pie-demo/PieChartWithCustomizedLabel.tsx b/docs/data/charts/pie-demo/PieChartWithCustomizedLabel.tsx index 9610b494dcd6..2c833f776c53 100644 --- a/docs/data/charts/pie-demo/PieChartWithCustomizedLabel.tsx +++ b/docs/data/charts/pie-demo/PieChartWithCustomizedLabel.tsx @@ -13,7 +13,7 @@ const sizing = { margin: { right: 5 }, width: 200, height: 200, - legend: { hidden: true }, + slotProps: { legend: { hidden: true } }, }; const TOTAL = data.map((item) => item.value).reduce((a, b) => a + b, 0); diff --git a/docs/data/charts/pie-demo/PieChartWithPaddingAngle.js b/docs/data/charts/pie-demo/PieChartWithPaddingAngle.js index f0606ec0e296..de23607e9260 100644 --- a/docs/data/charts/pie-demo/PieChartWithPaddingAngle.js +++ b/docs/data/charts/pie-demo/PieChartWithPaddingAngle.js @@ -24,7 +24,7 @@ export default function PieChartWithPaddingAngle() { margin={{ right: 5 }} width={200} height={200} - legend={{ hidden: true }} + slotProps={{ legend: { hidden: true } }} /> ); diff --git a/docs/data/charts/pie-demo/PieChartWithPaddingAngle.tsx b/docs/data/charts/pie-demo/PieChartWithPaddingAngle.tsx index f0606ec0e296..de23607e9260 100644 --- a/docs/data/charts/pie-demo/PieChartWithPaddingAngle.tsx +++ b/docs/data/charts/pie-demo/PieChartWithPaddingAngle.tsx @@ -24,7 +24,7 @@ export default function PieChartWithPaddingAngle() { margin={{ right: 5 }} width={200} height={200} - legend={{ hidden: true }} + slotProps={{ legend: { hidden: true } }} /> ); diff --git a/docs/data/charts/pie-demo/TwoLevelPieChart.js b/docs/data/charts/pie-demo/TwoLevelPieChart.js index 7a409b13b88a..f5c617245e77 100644 --- a/docs/data/charts/pie-demo/TwoLevelPieChart.js +++ b/docs/data/charts/pie-demo/TwoLevelPieChart.js @@ -39,9 +39,7 @@ export default function TwoLevelPieChart() { ]} width={400} height={300} - slotProps={{ - legend: { hidden: true }, - }} + slotProps={{ legend: { hidden: true } }} /> ); } diff --git a/docs/data/charts/pie-demo/TwoLevelPieChart.tsx b/docs/data/charts/pie-demo/TwoLevelPieChart.tsx index 2a8db580d08b..a5302bb71de0 100644 --- a/docs/data/charts/pie-demo/TwoLevelPieChart.tsx +++ b/docs/data/charts/pie-demo/TwoLevelPieChart.tsx @@ -38,9 +38,7 @@ export default function TwoLevelPieChart() { ]} width={400} height={300} - slotProps={{ - legend: { hidden: true }, - }} + slotProps={{ legend: { hidden: true } }} /> ); } diff --git a/docs/data/charts/pie-demo/TwoSimplePieChart.js b/docs/data/charts/pie-demo/TwoSimplePieChart.js index 7cbc1c6f3e92..234043c52c2c 100644 --- a/docs/data/charts/pie-demo/TwoSimplePieChart.js +++ b/docs/data/charts/pie-demo/TwoSimplePieChart.js @@ -36,9 +36,7 @@ export default function TwoSimplePieChart() { }, ]} height={300} - slotProps={{ - legend: { hidden: true }, - }} + slotProps={{ legend: { hidden: true } }} /> ); } diff --git a/docs/data/charts/pie-demo/TwoSimplePieChart.tsx b/docs/data/charts/pie-demo/TwoSimplePieChart.tsx index bb88d77dfd8b..fd421c0d5353 100644 --- a/docs/data/charts/pie-demo/TwoSimplePieChart.tsx +++ b/docs/data/charts/pie-demo/TwoSimplePieChart.tsx @@ -37,9 +37,7 @@ export default function TwoSimplePieChart() { }, ]} height={300} - slotProps={{ - legend: { hidden: true }, - }} + slotProps={{ legend: { hidden: true } }} /> ); } diff --git a/docs/data/charts/pie/PieClickNoSnap.js b/docs/data/charts/pie/PieClickNoSnap.js index 8b13dfb3d48b..0a6ee078ab7f 100644 --- a/docs/data/charts/pie/PieClickNoSnap.js +++ b/docs/data/charts/pie/PieClickNoSnap.js @@ -22,9 +22,7 @@ export default function PieClickNoSnap() { series={series} width={400} height={300} - slotProps={{ - legend: { hidden: true }, - }} + slotProps={{ legend: { hidden: true } }} onItemClick={(event, d) => setItemData(d)} />{' '}
diff --git a/docs/data/charts/pie/pie.md b/docs/data/charts/pie/pie.md index 047a4cc576e2..eda5601ffc78 100644 --- a/docs/data/charts/pie/pie.md +++ b/docs/data/charts/pie/pie.md @@ -110,7 +110,7 @@ const onItemClick = ( To skip animation at the creation and update of your chart you can use the `skipAnimation` prop. When set to `true` it skips animation powered by `@react-spring/web`. -Charts containers already use the `useReducedMotion` from `@react-spring/web` to skip animation [according to user preferences](https://react-spring.dev/docs/utilities/use-reduced-motion#why-is-it-important). +Charts containers already use the `useReducedMotion()` from `@react-spring/web` to skip animation [according to user preferences](https://react-spring.dev/docs/utilities/use-reduced-motion#why-is-it-important). ```jsx // For a single component chart diff --git a/docs/data/charts/tooltip/CustomAxisTooltip.js b/docs/data/charts/tooltip/CustomAxisTooltip.js index bb893b9e83b1..b65f7d3df4b2 100644 --- a/docs/data/charts/tooltip/CustomAxisTooltip.js +++ b/docs/data/charts/tooltip/CustomAxisTooltip.js @@ -3,22 +3,95 @@ import NoSsr from '@mui/material/NoSsr'; import Popper from '@mui/material/Popper'; import Paper from '@mui/material/Paper'; import Typography from '@mui/material/Typography'; -import { useAxisTooltip, useMouseTracker } from '@mui/x-charts/ChartsTooltip'; -import { generateVirtualElement } from './generateVirtualElement'; +import { useAxisTooltip } from '@mui/x-charts/ChartsTooltip'; +import { useSvgRef } from '@mui/x-charts/hooks'; + +function usePointer() { + const svgRef = useSvgRef(); + const popperRef = React.useRef(null); + const positionRef = React.useRef({ x: 0, y: 0 }); + + // Use a ref to avoid rerendering on every mousemove event. + const [pointer, setPointer] = React.useState({ + isActive: false, + isMousePointer: false, + pointerHeight: 0, + }); + + React.useEffect(() => { + const element = svgRef.current; + if (element === null) { + return () => {}; + } + + const handleOut = (event) => { + if (event.pointerType !== 'mouse') { + setPointer((prev) => ({ + ...prev, + isActive: false, + })); + } + }; + + const handleEnter = (event) => { + setPointer({ + isActive: true, + isMousePointer: event.pointerType === 'mouse', + pointerHeight: event.height, + }); + }; + + const handleMove = (event) => { + positionRef.current = { + x: event.clientX, + y: event.clientY, + }; + popperRef.current?.update(); + }; + + element.addEventListener('pointerenter', handleEnter); + element.addEventListener('pointerup', handleOut); + element.addEventListener('pointermove', handleMove); + + return () => { + element.removeEventListener('pointerenter', handleEnter); + element.removeEventListener('pointerup', handleOut); + element.removeEventListener('pointermove', handleMove); + }; + }, [svgRef]); + + return { + ...pointer, + popperRef, + anchorEl: { + getBoundingClientRect: () => ({ + x: positionRef.current.x, + y: positionRef.current.y, + top: positionRef.current.y, + left: positionRef.current.x, + right: positionRef.current.x, + bottom: positionRef.current.y, + width: 0, + height: 0, + toJSON: () => '', + }), + }, + }; +} export function CustomAxisTooltip() { const tooltipData = useAxisTooltip(); - const mousePosition = useMouseTracker(); // Track the mouse position on chart. + const { isActive, isMousePointer, pointerHeight, popperRef, anchorEl } = + usePointer(); - if (!tooltipData || !mousePosition) { + if (!tooltipData || !isActive) { // No data to display return null; } // The pointer type can be used to have different behavior based on pointer type. - const isMousePointer = mousePosition?.pointerType === 'mouse'; // Adapt the tooltip offset to the size of the pointer. - const yOffset = isMousePointer ? 0 : 40 - mousePosition.height; + const yOffset = isMousePointer ? 0 : 40 - pointerHeight; return ( @@ -29,7 +102,8 @@ export function CustomAxisTooltip() { }} open placement={isMousePointer ? 'top-end' : 'top'} - anchorEl={generateVirtualElement(mousePosition)} + anchorEl={anchorEl} + popperRef={popperRef} modifiers={[ { name: 'offset', @@ -81,7 +155,7 @@ export function CustomAxisTooltip() { {tooltipData.seriesItems.map((seriesItem) => ( - +
{ + const svgRef = useSvgRef(); + const popperRef: PopperProps['popperRef'] = React.useRef(null); + const positionRef = React.useRef({ x: 0, y: 0 }); + + // Use a ref to avoid rerendering on every mousemove event. + const [pointer, setPointer] = React.useState({ + isActive: false, + isMousePointer: false, + pointerHeight: 0, + }); + + React.useEffect(() => { + const element = svgRef.current; + if (element === null) { + return () => {}; + } + + const handleOut = (event: PointerEvent) => { + if (event.pointerType !== 'mouse') { + setPointer((prev) => ({ + ...prev, + isActive: false, + })); + } + }; + + const handleEnter = (event: PointerEvent) => { + setPointer({ + isActive: true, + isMousePointer: event.pointerType === 'mouse', + pointerHeight: event.height, + }); + }; + + const handleMove = (event: PointerEvent) => { + positionRef.current = { + x: event.clientX, + y: event.clientY, + }; + popperRef.current?.update(); + }; + + element.addEventListener('pointerenter', handleEnter); + element.addEventListener('pointerup', handleOut); + element.addEventListener('pointermove', handleMove); + + return () => { + element.removeEventListener('pointerenter', handleEnter); + element.removeEventListener('pointerup', handleOut); + element.removeEventListener('pointermove', handleMove); + }; + }, [svgRef]); + + return { + ...pointer, + popperRef, + anchorEl: { + getBoundingClientRect: () => ({ + x: positionRef.current.x, + y: positionRef.current.y, + top: positionRef.current.y, + left: positionRef.current.x, + right: positionRef.current.x, + bottom: positionRef.current.y, + width: 0, + height: 0, + toJSON: () => '', + }), + }, + }; +} export function CustomAxisTooltip() { const tooltipData = useAxisTooltip(); - const mousePosition = useMouseTracker(); // Track the mouse position on chart. + const { isActive, isMousePointer, pointerHeight, popperRef, anchorEl } = + usePointer(); - if (!tooltipData || !mousePosition) { + if (!tooltipData || !isActive) { // No data to display return null; } // The pointer type can be used to have different behavior based on pointer type. - const isMousePointer = mousePosition?.pointerType === 'mouse'; // Adapt the tooltip offset to the size of the pointer. - const yOffset = isMousePointer ? 0 : 40 - mousePosition.height; + const yOffset = isMousePointer ? 0 : 40 - pointerHeight; return ( @@ -29,7 +108,8 @@ export function CustomAxisTooltip() { }} open placement={isMousePointer ? 'top-end' : 'top'} - anchorEl={generateVirtualElement(mousePosition)} + anchorEl={anchorEl} + popperRef={popperRef} modifiers={[ { name: 'offset', @@ -81,7 +161,7 @@ export function CustomAxisTooltip() { {tooltipData.seriesItems.map((seriesItem) => ( - +
{ + const element = svgRef.current; + if (element === null) { + return () => {}; + } + + const handleOut = (event) => { + if (event.pointerType !== 'mouse') { + setPointer((prev) => ({ + ...prev, + isActive: false, + })); + } + }; + + const handleEnter = (event) => { + setPointer({ + isActive: true, + isMousePointer: event.pointerType === 'mouse', + pointerHeight: event.height, + }); + }; + + const handleMove = (event) => { + positionRef.current = { + x: event.clientX, + y: event.clientY, + }; + popperRef.current?.update(); + }; + + element.addEventListener('pointerenter', handleEnter); + element.addEventListener('pointerup', handleOut); + element.addEventListener('pointermove', handleMove); + + return () => { + element.removeEventListener('pointerenter', handleEnter); + element.removeEventListener('pointerup', handleOut); + element.removeEventListener('pointermove', handleMove); + }; + }, [svgRef]); + + return { + ...pointer, + popperRef, + anchorEl: { + getBoundingClientRect: () => ({ + x: positionRef.current.x, + y: positionRef.current.y, + top: positionRef.current.y, + left: positionRef.current.x, + right: positionRef.current.x, + bottom: positionRef.current.y, + width: 0, + height: 0, + toJSON: () => '', + }), + }, + }; +} export function CustomItemTooltip() { const tooltipData = useItemTooltip(); - const mousePosition = useMouseTracker(); // Track the mouse position on chart. + const { isActive, isMousePointer, pointerHeight, popperRef, anchorEl } = + usePointer(); - if (!tooltipData || !mousePosition) { + if (!tooltipData || !isActive) { // No data to display return null; } - // The pointer type can be used to have different behavior based on pointer type. - const isMousePointer = mousePosition?.pointerType === 'mouse'; // Adapt the tooltip offset to the size of the pointer. - const yOffset = isMousePointer ? 0 : 40 - mousePosition.height; + const yOffset = isMousePointer ? 0 : 40 - pointerHeight; return ( @@ -30,7 +102,8 @@ export function CustomItemTooltip() { }} open placement={isMousePointer ? 'top-end' : 'top'} - anchorEl={generateVirtualElement(mousePosition)} + anchorEl={anchorEl} + popperRef={popperRef} modifiers={[ { name: 'offset', diff --git a/docs/data/charts/tooltip/CustomItemTooltip.tsx b/docs/data/charts/tooltip/CustomItemTooltip.tsx index fcaf28469db1..077243411c5d 100644 --- a/docs/data/charts/tooltip/CustomItemTooltip.tsx +++ b/docs/data/charts/tooltip/CustomItemTooltip.tsx @@ -1,25 +1,103 @@ import * as React from 'react'; import NoSsr from '@mui/material/NoSsr'; -import Popper from '@mui/material/Popper'; +import Popper, { PopperProps } from '@mui/material/Popper'; import Paper from '@mui/material/Paper'; import Stack from '@mui/material/Stack'; import Typography from '@mui/material/Typography'; -import { useItemTooltip, useMouseTracker } from '@mui/x-charts/ChartsTooltip'; -import { generateVirtualElement } from './generateVirtualElement'; +import { useItemTooltip } from '@mui/x-charts/ChartsTooltip'; +import { useSvgRef } from '@mui/x-charts/hooks'; + +type PointerState = { + isActive: boolean; + isMousePointer: boolean; + pointerHeight: number; +}; + +function usePointer(): PointerState & Pick { + const svgRef = useSvgRef(); + const popperRef: PopperProps['popperRef'] = React.useRef(null); + const positionRef = React.useRef({ x: 0, y: 0 }); + + // Use a ref to avoid rerendering on every mousemove event. + const [pointer, setPointer] = React.useState({ + isActive: false, + isMousePointer: false, + pointerHeight: 0, + }); + + React.useEffect(() => { + const element = svgRef.current; + if (element === null) { + return () => {}; + } + + const handleOut = (event: PointerEvent) => { + if (event.pointerType !== 'mouse') { + setPointer((prev) => ({ + ...prev, + isActive: false, + })); + } + }; + + const handleEnter = (event: PointerEvent) => { + setPointer({ + isActive: true, + isMousePointer: event.pointerType === 'mouse', + pointerHeight: event.height, + }); + }; + + const handleMove = (event: PointerEvent) => { + positionRef.current = { + x: event.clientX, + y: event.clientY, + }; + popperRef.current?.update(); + }; + + element.addEventListener('pointerenter', handleEnter); + element.addEventListener('pointerup', handleOut); + element.addEventListener('pointermove', handleMove); + + return () => { + element.removeEventListener('pointerenter', handleEnter); + element.removeEventListener('pointerup', handleOut); + element.removeEventListener('pointermove', handleMove); + }; + }, [svgRef]); + + return { + ...pointer, + popperRef, + anchorEl: { + getBoundingClientRect: () => ({ + x: positionRef.current.x, + y: positionRef.current.y, + top: positionRef.current.y, + left: positionRef.current.x, + right: positionRef.current.x, + bottom: positionRef.current.y, + width: 0, + height: 0, + toJSON: () => '', + }), + }, + }; +} export function CustomItemTooltip() { const tooltipData = useItemTooltip(); - const mousePosition = useMouseTracker(); // Track the mouse position on chart. + const { isActive, isMousePointer, pointerHeight, popperRef, anchorEl } = + usePointer(); - if (!tooltipData || !mousePosition) { + if (!tooltipData || !isActive) { // No data to display return null; } - // The pointer type can be used to have different behavior based on pointer type. - const isMousePointer = mousePosition?.pointerType === 'mouse'; // Adapt the tooltip offset to the size of the pointer. - const yOffset = isMousePointer ? 0 : 40 - mousePosition.height; + const yOffset = isMousePointer ? 0 : 40 - pointerHeight; return ( @@ -30,7 +108,8 @@ export function CustomItemTooltip() { }} open placement={isMousePointer ? 'top-end' : 'top'} - anchorEl={generateVirtualElement(mousePosition)} + anchorEl={anchorEl} + popperRef={popperRef} modifiers={[ { name: 'offset', diff --git a/docs/data/charts/tooltip/Interaction.js b/docs/data/charts/tooltip/Interaction.js index a7e6142713d6..04a4a516f511 100644 --- a/docs/data/charts/tooltip/Interaction.js +++ b/docs/data/charts/tooltip/Interaction.js @@ -16,11 +16,7 @@ const barChartsParams = { ], margin: { top: 10, right: 10 }, height: 200, - slotProps: { - legend: { - hidden: true, - }, - }, + slotProps: { legend: { hidden: true } }, }; export default function Interaction() { return ( diff --git a/docs/data/charts/tooltip/Interaction.tsx b/docs/data/charts/tooltip/Interaction.tsx index 2920b6d6b2e2..70cbd6c201f8 100644 --- a/docs/data/charts/tooltip/Interaction.tsx +++ b/docs/data/charts/tooltip/Interaction.tsx @@ -16,11 +16,7 @@ const barChartsParams = { ], margin: { top: 10, right: 10 }, height: 200, - slotProps: { - legend: { - hidden: true, - }, - }, + slotProps: { legend: { hidden: true } }, }; export default function Interaction() { return ( diff --git a/docs/data/charts/tooltip/ItemTooltip.js b/docs/data/charts/tooltip/ItemTooltip.js index 68fbab1d77ae..4e3b52476e27 100644 --- a/docs/data/charts/tooltip/ItemTooltip.js +++ b/docs/data/charts/tooltip/ItemTooltip.js @@ -1,23 +1,95 @@ import * as React from 'react'; import NoSsr from '@mui/material/NoSsr'; import Popper from '@mui/material/Popper'; -import { useItemTooltip, useMouseTracker } from '@mui/x-charts/ChartsTooltip'; +import { useItemTooltip } from '@mui/x-charts/ChartsTooltip'; +import { useSvgRef } from '@mui/x-charts/hooks'; import { CustomItemTooltipContent } from './CustomItemTooltipContent'; -import { generateVirtualElement } from './generateVirtualElement'; + +function usePointer() { + const svgRef = useSvgRef(); + const popperRef = React.useRef(null); + const positionRef = React.useRef({ x: 0, y: 0 }); + + // Use a ref to avoid rerendering on every mousemove event. + const [pointer, setPointer] = React.useState({ + isActive: false, + isMousePointer: false, + pointerHeight: 0, + }); + + React.useEffect(() => { + const element = svgRef.current; + if (element === null) { + return () => {}; + } + + const handleOut = (event) => { + if (event.pointerType !== 'mouse') { + setPointer((prev) => ({ + ...prev, + isActive: false, + })); + } + }; + + const handleEnter = (event) => { + setPointer({ + isActive: true, + isMousePointer: event.pointerType === 'mouse', + pointerHeight: event.height, + }); + }; + + const handleMove = (event) => { + positionRef.current = { + x: event.clientX, + y: event.clientY, + }; + popperRef.current?.update(); + }; + + element.addEventListener('pointerenter', handleEnter); + element.addEventListener('pointerup', handleOut); + element.addEventListener('pointermove', handleMove); + + return () => { + element.removeEventListener('pointerenter', handleEnter); + element.removeEventListener('pointerup', handleOut); + element.removeEventListener('pointermove', handleMove); + }; + }, [svgRef]); + + return { + ...pointer, + popperRef, + anchorEl: { + getBoundingClientRect: () => ({ + x: positionRef.current.x, + y: positionRef.current.y, + top: positionRef.current.y, + left: positionRef.current.x, + right: positionRef.current.x, + bottom: positionRef.current.y, + width: 0, + height: 0, + toJSON: () => '', + }), + }, + }; +} export function ItemTooltip() { const tooltipData = useItemTooltip(); - const mousePosition = useMouseTracker(); // Track the mouse position on chart. + const { isActive, isMousePointer, pointerHeight, popperRef, anchorEl } = + usePointer(); - if (!tooltipData || !mousePosition) { + if (!tooltipData || !isActive) { // No data to display return null; } - // The pointer type can be used to have different behavior based on pointer type. - const isMousePointer = mousePosition?.pointerType === 'mouse'; // Adapt the tooltip offset to the size of the pointer. - const yOffset = isMousePointer ? 0 : 40 - mousePosition.height; + const yOffset = isMousePointer ? 0 : 40 - pointerHeight; return ( @@ -28,7 +100,8 @@ export function ItemTooltip() { }} open placement={isMousePointer ? 'top-end' : 'top'} - anchorEl={generateVirtualElement(mousePosition)} + anchorEl={anchorEl} + popperRef={popperRef} modifiers={[ { name: 'offset', diff --git a/docs/data/charts/tooltip/ItemTooltip.tsx b/docs/data/charts/tooltip/ItemTooltip.tsx index 68fbab1d77ae..1f4277d578c7 100644 --- a/docs/data/charts/tooltip/ItemTooltip.tsx +++ b/docs/data/charts/tooltip/ItemTooltip.tsx @@ -1,23 +1,101 @@ import * as React from 'react'; import NoSsr from '@mui/material/NoSsr'; -import Popper from '@mui/material/Popper'; -import { useItemTooltip, useMouseTracker } from '@mui/x-charts/ChartsTooltip'; +import Popper, { PopperProps } from '@mui/material/Popper'; +import { useItemTooltip } from '@mui/x-charts/ChartsTooltip'; +import { useSvgRef } from '@mui/x-charts/hooks'; import { CustomItemTooltipContent } from './CustomItemTooltipContent'; -import { generateVirtualElement } from './generateVirtualElement'; + +type PointerState = { + isActive: boolean; + isMousePointer: boolean; + pointerHeight: number; +}; + +function usePointer(): PointerState & Pick { + const svgRef = useSvgRef(); + const popperRef: PopperProps['popperRef'] = React.useRef(null); + const positionRef = React.useRef({ x: 0, y: 0 }); + + // Use a ref to avoid rerendering on every mousemove event. + const [pointer, setPointer] = React.useState({ + isActive: false, + isMousePointer: false, + pointerHeight: 0, + }); + + React.useEffect(() => { + const element = svgRef.current; + if (element === null) { + return () => {}; + } + + const handleOut = (event: PointerEvent) => { + if (event.pointerType !== 'mouse') { + setPointer((prev) => ({ + ...prev, + isActive: false, + })); + } + }; + + const handleEnter = (event: PointerEvent) => { + setPointer({ + isActive: true, + isMousePointer: event.pointerType === 'mouse', + pointerHeight: event.height, + }); + }; + + const handleMove = (event: PointerEvent) => { + positionRef.current = { + x: event.clientX, + y: event.clientY, + }; + popperRef.current?.update(); + }; + + element.addEventListener('pointerenter', handleEnter); + element.addEventListener('pointerup', handleOut); + element.addEventListener('pointermove', handleMove); + + return () => { + element.removeEventListener('pointerenter', handleEnter); + element.removeEventListener('pointerup', handleOut); + element.removeEventListener('pointermove', handleMove); + }; + }, [svgRef]); + + return { + ...pointer, + popperRef, + anchorEl: { + getBoundingClientRect: () => ({ + x: positionRef.current.x, + y: positionRef.current.y, + top: positionRef.current.y, + left: positionRef.current.x, + right: positionRef.current.x, + bottom: positionRef.current.y, + width: 0, + height: 0, + toJSON: () => '', + }), + }, + }; +} export function ItemTooltip() { const tooltipData = useItemTooltip(); - const mousePosition = useMouseTracker(); // Track the mouse position on chart. + const { isActive, isMousePointer, pointerHeight, popperRef, anchorEl } = + usePointer(); - if (!tooltipData || !mousePosition) { + if (!tooltipData || !isActive) { // No data to display return null; } - // The pointer type can be used to have different behavior based on pointer type. - const isMousePointer = mousePosition?.pointerType === 'mouse'; // Adapt the tooltip offset to the size of the pointer. - const yOffset = isMousePointer ? 0 : 40 - mousePosition.height; + const yOffset = isMousePointer ? 0 : 40 - pointerHeight; return ( @@ -28,7 +106,8 @@ export function ItemTooltip() { }} open placement={isMousePointer ? 'top-end' : 'top'} - anchorEl={generateVirtualElement(mousePosition)} + anchorEl={anchorEl} + popperRef={popperRef} modifiers={[ { name: 'offset', diff --git a/docs/data/charts/tooltip/ItemTooltipFixedY.js b/docs/data/charts/tooltip/ItemTooltipFixedY.js index 4e19cd1bc9f6..aa11e750dc8d 100644 --- a/docs/data/charts/tooltip/ItemTooltipFixedY.js +++ b/docs/data/charts/tooltip/ItemTooltipFixedY.js @@ -1,28 +1,90 @@ import * as React from 'react'; import NoSsr from '@mui/material/NoSsr'; import Popper from '@mui/material/Popper'; -import { useItemTooltip, useMouseTracker } from '@mui/x-charts/ChartsTooltip'; +import { useItemTooltip } from '@mui/x-charts/ChartsTooltip'; import { useDrawingArea, useSvgRef } from '@mui/x-charts/hooks'; import { CustomItemTooltipContent } from './CustomItemTooltipContent'; -import { generateVirtualElement } from './generateVirtualElement'; + +function usePointer() { + const svgRef = useSvgRef(); + + // Use a ref to avoid rerendering on every mousemove event. + const [pointer, setPointer] = React.useState({ + isActive: false, + isMousePointer: false, + pointerHeight: 0, + }); + + React.useEffect(() => { + const element = svgRef.current; + if (element === null) { + return () => {}; + } + + const handleOut = (event) => { + if (event.pointerType !== 'mouse') { + setPointer((prev) => ({ + ...prev, + isActive: false, + })); + } + }; + + const handleEnter = (event) => { + setPointer({ + isActive: true, + isMousePointer: event.pointerType === 'mouse', + pointerHeight: event.height, + }); + }; + + element.addEventListener('pointerenter', handleEnter); + element.addEventListener('pointerup', handleOut); + + return () => { + element.removeEventListener('pointerenter', handleEnter); + element.removeEventListener('pointerup', handleOut); + }; + }, [svgRef]); + + return pointer; +} export function ItemTooltipFixedY() { const tooltipData = useItemTooltip(); - const mousePosition = useMouseTracker(); + const { isActive } = usePointer(); + + const popperRef = React.useRef(null); + const positionRef = React.useRef({ x: 0, y: 0 }); const svgRef = useSvgRef(); // Get the ref of the component. const drawingArea = useDrawingArea(); // Get the dimensions of the chart inside the . - if (!tooltipData || !mousePosition) { + React.useEffect(() => { + const element = svgRef.current; + if (element === null) { + return () => {}; + } + + const handleMove = (event) => { + positionRef.current = { + x: event.clientX, + y: event.clientY, + }; + popperRef.current?.update(); + }; + + element.addEventListener('pointermove', handleMove); + + return () => { + element.removeEventListener('pointermove', handleMove); + }; + }, [svgRef, drawingArea.top]); + + if (!tooltipData || !isActive) { // No data to display return null; } - const tooltipPosition = { - ...mousePosition, - // Add the y-coordinate of the to the to margin between the and the drawing area - y: svgRef.current.getBoundingClientRect().top + drawingArea.top, - }; - return ( ({ + x: positionRef.current.x, + y: positionRef.current.y, + top: positionRef.current.y, + left: positionRef.current.x, + right: positionRef.current.x, + bottom: positionRef.current.y, + width: 0, + height: 0, + toJSON: () => '', + }), + }} + popperRef={popperRef} > diff --git a/docs/data/charts/tooltip/ItemTooltipFixedY.tsx b/docs/data/charts/tooltip/ItemTooltipFixedY.tsx index 3059c260afca..925b27453789 100644 --- a/docs/data/charts/tooltip/ItemTooltipFixedY.tsx +++ b/docs/data/charts/tooltip/ItemTooltipFixedY.tsx @@ -1,28 +1,96 @@ import * as React from 'react'; import NoSsr from '@mui/material/NoSsr'; -import Popper from '@mui/material/Popper'; -import { useItemTooltip, useMouseTracker } from '@mui/x-charts/ChartsTooltip'; +import Popper, { PopperProps } from '@mui/material/Popper'; +import { useItemTooltip } from '@mui/x-charts/ChartsTooltip'; import { useDrawingArea, useSvgRef } from '@mui/x-charts/hooks'; import { CustomItemTooltipContent } from './CustomItemTooltipContent'; -import { generateVirtualElement, MousePosition } from './generateVirtualElement'; + +type PointerState = { + isActive: boolean; + isMousePointer: boolean; + pointerHeight: number; +}; + +function usePointer(): PointerState { + const svgRef = useSvgRef(); + + // Use a ref to avoid rerendering on every mousemove event. + const [pointer, setPointer] = React.useState({ + isActive: false, + isMousePointer: false, + pointerHeight: 0, + }); + + React.useEffect(() => { + const element = svgRef.current; + if (element === null) { + return () => {}; + } + + const handleOut = (event: PointerEvent) => { + if (event.pointerType !== 'mouse') { + setPointer((prev) => ({ + ...prev, + isActive: false, + })); + } + }; + + const handleEnter = (event: PointerEvent) => { + setPointer({ + isActive: true, + isMousePointer: event.pointerType === 'mouse', + pointerHeight: event.height, + }); + }; + + element.addEventListener('pointerenter', handleEnter); + element.addEventListener('pointerup', handleOut); + + return () => { + element.removeEventListener('pointerenter', handleEnter); + element.removeEventListener('pointerup', handleOut); + }; + }, [svgRef]); + + return pointer; +} export function ItemTooltipFixedY() { const tooltipData = useItemTooltip(); - const mousePosition = useMouseTracker(); + const { isActive } = usePointer(); + + const popperRef: PopperProps['popperRef'] = React.useRef(null); + const positionRef = React.useRef({ x: 0, y: 0 }); const svgRef = useSvgRef(); // Get the ref of the component. const drawingArea = useDrawingArea(); // Get the dimensions of the chart inside the . - if (!tooltipData || !mousePosition) { + React.useEffect(() => { + const element = svgRef.current; + if (element === null) { + return () => {}; + } + + const handleMove = (event: PointerEvent) => { + positionRef.current = { + x: event.clientX, + y: event.clientY, + }; + popperRef.current?.update(); + }; + + element.addEventListener('pointermove', handleMove); + + return () => { + element.removeEventListener('pointermove', handleMove); + }; + }, [svgRef, drawingArea.top]); + + if (!tooltipData || !isActive) { // No data to display return null; } - const tooltipPosition: MousePosition = { - ...mousePosition, - // Add the y-coordinate of the to the to margin between the and the drawing area - y: svgRef.current.getBoundingClientRect().top + drawingArea.top, - }; - return ( ({ + x: positionRef.current.x, + y: positionRef.current.y, + top: positionRef.current.y, + left: positionRef.current.x, + right: positionRef.current.x, + bottom: positionRef.current.y, + width: 0, + height: 0, + toJSON: () => '', + }), + }} + popperRef={popperRef} > diff --git a/docs/data/charts/tooltip/ItemTooltipTopElement.js b/docs/data/charts/tooltip/ItemTooltipTopElement.js index 7d86e69b81e4..538a729564c9 100644 --- a/docs/data/charts/tooltip/ItemTooltipTopElement.js +++ b/docs/data/charts/tooltip/ItemTooltipTopElement.js @@ -2,14 +2,58 @@ import * as React from 'react'; import NoSsr from '@mui/material/NoSsr'; import Popper from '@mui/material/Popper'; -import { useItemTooltip, useMouseTracker } from '@mui/x-charts/ChartsTooltip'; +import { useItemTooltip } from '@mui/x-charts/ChartsTooltip'; import { useSvgRef, useXAxis, useXScale, useYScale } from '@mui/x-charts/hooks'; import { CustomItemTooltipContent } from './CustomItemTooltipContent'; -import { generateVirtualElement } from './generateVirtualElement'; + +function usePointer() { + const svgRef = useSvgRef(); + + // Use a ref to avoid rerendering on every mousemove event. + const [pointer, setPointer] = React.useState({ + isActive: false, + isMousePointer: false, + pointerHeight: 0, + }); + + React.useEffect(() => { + const element = svgRef.current; + if (element === null) { + return () => {}; + } + + const handleOut = (event) => { + if (event.pointerType !== 'mouse') { + setPointer((prev) => ({ + ...prev, + isActive: false, + })); + } + }; + + const handleEnter = (event) => { + setPointer({ + isActive: true, + isMousePointer: event.pointerType === 'mouse', + pointerHeight: event.height, + }); + }; + + element.addEventListener('pointerenter', handleEnter); + element.addEventListener('pointerup', handleOut); + + return () => { + element.removeEventListener('pointerenter', handleEnter); + element.removeEventListener('pointerup', handleOut); + }; + }, [svgRef]); + + return pointer; +} export function ItemTooltipTopElement() { const tooltipData = useItemTooltip(); - const mousePosition = useMouseTracker(); + const { isActive } = usePointer(); // Get xAxis config to access its data array. const xAxis = useXAxis(); // Get the scale which map values to SVG coordinates. @@ -21,7 +65,7 @@ export function ItemTooltipTopElement() { // Get the ref of the component. const svgRef = useSvgRef(); - if (!tooltipData || !mousePosition || !xAxis.data) { + if (!tooltipData || !isActive || !xAxis.data) { // No data to display return null; } @@ -41,7 +85,6 @@ export function ItemTooltipTopElement() { const svgXPosition = xScale(xValue) ?? 0; const tooltipPosition = { - ...mousePosition, // Add half of `yScale.step()` to be in the middle of the band. x: svgRef.current.getBoundingClientRect().left + svgXPosition + xScale.step() / 2, @@ -58,7 +101,19 @@ export function ItemTooltipTopElement() { }} open placement="top" - anchorEl={generateVirtualElement(tooltipPosition)} + anchorEl={{ + getBoundingClientRect: () => ({ + x: tooltipPosition.x, + y: tooltipPosition.y, + top: tooltipPosition.y, + left: tooltipPosition.x, + right: tooltipPosition.x, + bottom: tooltipPosition.y, + width: 0, + height: 0, + toJSON: () => '', + }), + }} > diff --git a/docs/data/charts/tooltip/ItemTooltipTopElement.tsx b/docs/data/charts/tooltip/ItemTooltipTopElement.tsx index d69ab33e96da..9c73fa1d4383 100644 --- a/docs/data/charts/tooltip/ItemTooltipTopElement.tsx +++ b/docs/data/charts/tooltip/ItemTooltipTopElement.tsx @@ -2,14 +2,64 @@ import * as React from 'react'; import { ScaleBand } from '@mui/x-charts-vendor/d3-scale'; import NoSsr from '@mui/material/NoSsr'; import Popper from '@mui/material/Popper'; -import { useItemTooltip, useMouseTracker } from '@mui/x-charts/ChartsTooltip'; +import { useItemTooltip } from '@mui/x-charts/ChartsTooltip'; import { useSvgRef, useXAxis, useXScale, useYScale } from '@mui/x-charts/hooks'; import { CustomItemTooltipContent } from './CustomItemTooltipContent'; -import { generateVirtualElement, MousePosition } from './generateVirtualElement'; + +type PointerState = { + isActive: boolean; + isMousePointer: boolean; + pointerHeight: number; +}; + +function usePointer(): PointerState { + const svgRef = useSvgRef(); + + // Use a ref to avoid rerendering on every mousemove event. + const [pointer, setPointer] = React.useState({ + isActive: false, + isMousePointer: false, + pointerHeight: 0, + }); + + React.useEffect(() => { + const element = svgRef.current; + if (element === null) { + return () => {}; + } + + const handleOut = (event: PointerEvent) => { + if (event.pointerType !== 'mouse') { + setPointer((prev) => ({ + ...prev, + isActive: false, + })); + } + }; + + const handleEnter = (event: PointerEvent) => { + setPointer({ + isActive: true, + isMousePointer: event.pointerType === 'mouse', + pointerHeight: event.height, + }); + }; + + element.addEventListener('pointerenter', handleEnter); + element.addEventListener('pointerup', handleOut); + + return () => { + element.removeEventListener('pointerenter', handleEnter); + element.removeEventListener('pointerup', handleOut); + }; + }, [svgRef]); + + return pointer; +} export function ItemTooltipTopElement() { const tooltipData = useItemTooltip<'bar'>(); - const mousePosition = useMouseTracker(); + const { isActive } = usePointer(); // Get xAxis config to access its data array. const xAxis = useXAxis(); // Get the scale which map values to SVG coordinates. @@ -21,7 +71,7 @@ export function ItemTooltipTopElement() { // Get the ref of the component. const svgRef = useSvgRef(); - if (!tooltipData || !mousePosition || !xAxis.data) { + if (!tooltipData || !isActive || !xAxis.data) { // No data to display return null; } @@ -40,8 +90,7 @@ export function ItemTooltipTopElement() { const svgYPosition = yScale(tooltipData.value) ?? 0; const svgXPosition = xScale(xValue) ?? 0; - const tooltipPosition: MousePosition = { - ...mousePosition, + const tooltipPosition = { // Add half of `yScale.step()` to be in the middle of the band. x: svgRef.current.getBoundingClientRect().left + @@ -60,7 +109,19 @@ export function ItemTooltipTopElement() { }} open placement="top" - anchorEl={generateVirtualElement(tooltipPosition)} + anchorEl={{ + getBoundingClientRect: () => ({ + x: tooltipPosition.x, + y: tooltipPosition.y, + top: tooltipPosition.y, + left: tooltipPosition.x, + right: tooltipPosition.x, + bottom: tooltipPosition.y, + width: 0, + height: 0, + toJSON: () => '', + }), + }} > diff --git a/docs/data/charts/tooltip/tooltip.md b/docs/data/charts/tooltip/tooltip.md index 655886065223..f53171fca6e5 100644 --- a/docs/data/charts/tooltip/tooltip.md +++ b/docs/data/charts/tooltip/tooltip.md @@ -15,8 +15,8 @@ If you are using composition, you can add the `` component and The tooltip can be triggered by two kinds of events: -- `'item'`—when the user's mouse hovers over an item on the chart, the tooltip will display data about this specific item. -- `'axis'`—the user's mouse position is associated with a value of the x-axis. The tooltip will display data about all series at this specific x value. +- `'item'`—when the user's mouse hovers over an item on the chart, the tooltip displays data about this specific item. +- `'axis'`—the user's mouse position is associated with a value of the x-axis. The tooltip displays data about all series at this specific x value. - `'none'`—disable the tooltip. {{"demo": "Interaction.js"}} @@ -79,7 +79,7 @@ See [Label—Conditional formatting](/x/react-charts/label/#conditional-formatti ### Hiding values You can hide the axis value with `hideTooltip` in the `xAxis` props. -It will remove the header showing the x-axis value from the tooltip. +It removes the header showing the x-axis value from the tooltip. ```jsx ({ - color: ownerState.open ? 'secondary' : 'primary', + color: ownerState.isPickerOpen ? 'secondary' : 'primary', }), }} /> diff --git a/docs/data/common-concepts/custom-components/CustomSlotPropsCallback.tsx b/docs/data/common-concepts/custom-components/CustomSlotPropsCallback.tsx index e1272f2776ba..ea3b72c58ed1 100644 --- a/docs/data/common-concepts/custom-components/CustomSlotPropsCallback.tsx +++ b/docs/data/common-concepts/custom-components/CustomSlotPropsCallback.tsx @@ -9,7 +9,7 @@ export default function CustomSlotPropsCallback() { ({ - color: ownerState.open ? 'secondary' : 'primary', + color: ownerState.isPickerOpen ? 'secondary' : 'primary', }), }} /> diff --git a/docs/data/common-concepts/custom-components/CustomSlotPropsCallback.tsx.preview b/docs/data/common-concepts/custom-components/CustomSlotPropsCallback.tsx.preview index 100188718fae..70bc3e35f25e 100644 --- a/docs/data/common-concepts/custom-components/CustomSlotPropsCallback.tsx.preview +++ b/docs/data/common-concepts/custom-components/CustomSlotPropsCallback.tsx.preview @@ -1,7 +1,7 @@ ({ - color: ownerState.open ? 'secondary' : 'primary', + color: ownerState.isPickerOpen ? 'secondary' : 'primary', }), }} /> \ No newline at end of file diff --git a/docs/data/common-concepts/custom-components/TypescriptCasting.js b/docs/data/common-concepts/custom-components/TypescriptCasting.js index 4d0346ef92f1..045e2b06a2c7 100644 --- a/docs/data/common-concepts/custom-components/TypescriptCasting.js +++ b/docs/data/common-concepts/custom-components/TypescriptCasting.js @@ -1,5 +1,4 @@ import * as React from 'react'; - import Stack from '@mui/material/Stack'; import FormControlLabel from '@mui/material/FormControlLabel'; import Switch from '@mui/material/Switch'; diff --git a/docs/data/common-concepts/custom-components/TypescriptCasting.tsx b/docs/data/common-concepts/custom-components/TypescriptCasting.tsx index 2d68d2c1e6be..394187d805d2 100644 --- a/docs/data/common-concepts/custom-components/TypescriptCasting.tsx +++ b/docs/data/common-concepts/custom-components/TypescriptCasting.tsx @@ -1,5 +1,4 @@ import * as React from 'react'; -import { Dayjs } from 'dayjs'; import Stack from '@mui/material/Stack'; import FormControlLabel from '@mui/material/FormControlLabel'; import Switch from '@mui/material/Switch'; @@ -35,7 +34,7 @@ function DisplayWeekNumberToggle({ } interface CustomCalendarHeaderProps - extends PropsFromSlot['calendarHeader']> { + extends PropsFromSlot { displayWeekNumber: boolean; setDisplayWeekNumber: (displayWeekNumber: boolean) => void; } @@ -66,13 +65,13 @@ export default function TypescriptCasting() { // Cast the custom component to the type expected by the X component slots={{ calendarHeader: - CustomCalendarHeader as DateCalendarSlots['calendarHeader'], + CustomCalendarHeader as DateCalendarSlots['calendarHeader'], }} slotProps={{ calendarHeader: { displayWeekNumber, setDisplayWeekNumber, - } as DateCalendarSlotProps['calendarHeader'], + } as DateCalendarSlotProps['calendarHeader'], }} /> diff --git a/docs/data/common-concepts/custom-components/TypescriptCasting.tsx.preview b/docs/data/common-concepts/custom-components/TypescriptCasting.tsx.preview index 461108b0d9c5..6f7e58781ac3 100644 --- a/docs/data/common-concepts/custom-components/TypescriptCasting.tsx.preview +++ b/docs/data/common-concepts/custom-components/TypescriptCasting.tsx.preview @@ -3,12 +3,12 @@ // Cast the custom component to the type expected by the X component slots={{ calendarHeader: - CustomCalendarHeader as DateCalendarSlots['calendarHeader'], + CustomCalendarHeader as DateCalendarSlots['calendarHeader'], }} slotProps={{ calendarHeader: { displayWeekNumber, setDisplayWeekNumber, - } as DateCalendarSlotProps['calendarHeader'], + } as DateCalendarSlotProps['calendarHeader'], }} /> \ No newline at end of file diff --git a/docs/data/common-concepts/custom-components/custom-components.md b/docs/data/common-concepts/custom-components/custom-components.md index 1875037ac5bf..e5605eb8ddc9 100644 --- a/docs/data/common-concepts/custom-components/custom-components.md +++ b/docs/data/common-concepts/custom-components/custom-components.md @@ -105,7 +105,7 @@ you can declare your component using the `PropsFromSlot` interface: ```tsx function CustomCalendarHeader({ currentMonth, -}: PropsFromSlot['calendarHeader']>) { +}: PropsFromSlot) { return
{currentMonth?.format('MM-DD-YYYY')}
; } ``` @@ -129,7 +129,7 @@ import { DateCalendarSlots } from '@mui/x-date-pickers'; type ToolbarProps = PropsFromSlot; // Most of the picker slots interfaces need to receive the date type as a generic. -type CalendarHeaderProps = PropsFromSlot['calendarHeader']>; +type CalendarHeaderProps = PropsFromSlot; ``` ::: @@ -140,7 +140,7 @@ If you are passing additional props to your slot, you can add them to the props ```ts interface CustomCalendarHeaderProps - extends PropsFromSlot['calendarHeader']> { + extends PropsFromSlot { displayWeekNumber: boolean; setDisplayWeekNumber: (displayWeekNumber: boolean) => void; } @@ -178,14 +178,13 @@ function MyApp() { ['calendarHeader'], + calendarHeader: CustomCalendarHeader as DateCalendarSlots['calendarHeader'], }} slotProps={{ calendarHeader: { displayWeekNumber, setDisplayWeekNumber, - } as DateCalendarSlotProps['calendarHeader'], + } as DateCalendarSlotProps['calendarHeader'], }} /> ); diff --git a/docs/data/data-grid/column-definition/column-definition.md b/docs/data/data-grid/column-definition/column-definition.md index 75364b0c7c81..89c245b09175 100644 --- a/docs/data/data-grid/column-definition/column-definition.md +++ b/docs/data/data-grid/column-definition/column-definition.md @@ -102,8 +102,8 @@ Read more in the [handling autogenerated rows](/x/react-data-grid/column-definit ::: :::warning -[Row grouping](/x/react-data-grid/row-grouping/) uses the [`groupingValueGetter`](/x/react-data-grid/row-grouping/#using-groupingvaluegetter-for-complex-grouping-value) instead of `valueGetter` to get the value for the grouping. -The value passed to the `groupingValueGetter` is the raw row value (`row[field]`) even if the column definition has a `valueGetter` defined. +[Row grouping](/x/react-data-grid/row-grouping/) uses the [`groupingValueGetter()`](/x/react-data-grid/row-grouping/#using-groupingvaluegetter-for-complex-grouping-value) instead of `valueGetter` to get the value for the grouping. +The value passed to the `groupingValueGetter()` is the raw row value (`row[field]`) even if the column definition has a `valueGetter` defined. ::: ### Value formatter diff --git a/docs/data/data-grid/components/components.md b/docs/data/data-grid/components/components.md index 4819b7e5d8c4..b0747354e452 100644 --- a/docs/data/data-grid/components/components.md +++ b/docs/data/data-grid/components/components.md @@ -31,7 +31,7 @@ function CustomPagination() { :::success -- See [Common concepts—Custom slots and subcomponents](/x/common-concepts/custom-components/) to learn how to use slots. +- See [Common concepts—Slots and subcomponents](/x/common-concepts/custom-components/) to learn how to use slots. - See [`GridSlotsComponent`](/x/api/data-grid/data-grid/#slots) to learn about the available slots. ::: diff --git a/docs/data/data-grid/editing/editing.md b/docs/data/data-grid/editing/editing.md index d9702fae6f91..5d10456d299a 100644 --- a/docs/data/data-grid/editing/editing.md +++ b/docs/data/data-grid/editing/editing.md @@ -241,7 +241,7 @@ const columns: GridColDef[] = [ You can use the `valueSetter` property of the column definition to customize how the row is updated with a new value. This lets you insert a value from a nested object. It is called with an object containing the new cell value to be saved as well as the row that the cell belongs to. -If you are already using a `valueGetter` to extract the value from a nested object, then the `valueSetter` will probably also be necessary. +If you are already using a `valueGetter` to extract the value from a nested object, then the `valueSetter` is probably also necessary. ```tsx const columns: GridColDef[] = [ diff --git a/docs/data/data-grid/joy-ui/joy-ui.md b/docs/data/data-grid/joy-ui/joy-ui.md index 7a9d146b94b9..bd43afc26176 100644 --- a/docs/data/data-grid/joy-ui/joy-ui.md +++ b/docs/data/data-grid/joy-ui/joy-ui.md @@ -1,5 +1,5 @@ # Data Grid - Joy UI -

Using the Data Grid with Joy UI components

+

Using the Data Grid with Joy UI components.

{{"demo": "GridJoyUISlots.js", "bg": "inline"}} diff --git a/docs/data/data-grid/layout/GridOverlayHeight.js b/docs/data/data-grid/layout/GridOverlayHeight.js new file mode 100644 index 000000000000..385ed124616a --- /dev/null +++ b/docs/data/data-grid/layout/GridOverlayHeight.js @@ -0,0 +1,70 @@ +import * as React from 'react'; +import Box from '@mui/material/Box'; +import { DataGrid } from '@mui/x-data-grid'; +import { styled } from '@mui/material/styles'; + +const StyledGridOverlay = styled('div')(({ theme }) => ({ + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + justifyContent: 'center', + height: '100%', + '& .no-rows-primary': { + fill: '#3D4751', + ...theme.applyStyles('light', { + fill: '#AEB8C2', + }), + }, + '& .no-rows-secondary': { + fill: '#1D2126', + ...theme.applyStyles('light', { + fill: '#E8EAED', + }), + }, +})); + +function CustomNoRowsOverlay() { + return ( + + + + + + + + No rows + + ); +} + +export default function GridOverlayHeight() { + return ( + + + + ); +} diff --git a/docs/data/data-grid/layout/GridOverlayHeight.tsx b/docs/data/data-grid/layout/GridOverlayHeight.tsx new file mode 100644 index 000000000000..385ed124616a --- /dev/null +++ b/docs/data/data-grid/layout/GridOverlayHeight.tsx @@ -0,0 +1,70 @@ +import * as React from 'react'; +import Box from '@mui/material/Box'; +import { DataGrid } from '@mui/x-data-grid'; +import { styled } from '@mui/material/styles'; + +const StyledGridOverlay = styled('div')(({ theme }) => ({ + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + justifyContent: 'center', + height: '100%', + '& .no-rows-primary': { + fill: '#3D4751', + ...theme.applyStyles('light', { + fill: '#AEB8C2', + }), + }, + '& .no-rows-secondary': { + fill: '#1D2126', + ...theme.applyStyles('light', { + fill: '#E8EAED', + }), + }, +})); + +function CustomNoRowsOverlay() { + return ( + + + + + + + + No rows + + ); +} + +export default function GridOverlayHeight() { + return ( + + + + ); +} diff --git a/docs/data/data-grid/layout/GridOverlayHeight.tsx.preview b/docs/data/data-grid/layout/GridOverlayHeight.tsx.preview new file mode 100644 index 000000000000..c8b6cb157e21 --- /dev/null +++ b/docs/data/data-grid/layout/GridOverlayHeight.tsx.preview @@ -0,0 +1,6 @@ + \ No newline at end of file diff --git a/docs/data/data-grid/layout/layout.md b/docs/data/data-grid/layout/layout.md index 263a08ec21eb..ef887d550bcd 100644 --- a/docs/data/data-grid/layout/layout.md +++ b/docs/data/data-grid/layout/layout.md @@ -41,6 +41,17 @@ You can predefine dimensions for the parent of the Data Grid. {{"demo": "FixedSizeGrid.js", "bg": "inline"}} +## Overlay height + +When data grid has no content, overlays (such as +["Loading"](/x/react-data-grid/overlays/#loading-overlay) or +["No rows"](/x/react-data-grid/overlays/#no-rows-overlay)) +take the height of two rows by default. + +To customize the overlay height, use the `--DataGrid-overlayHeight` CSS variable. + +{{"demo": "GridOverlayHeight.js", "bg": "inline"}} + ## Auto height :::error @@ -52,17 +63,6 @@ This means that the Data Grid's height will be determined by the number of rows, {{"demo": "AutoHeightGrid.js", "bg": "inline"}} -### Overlay height - -When `autoHeight` is enabled, grid overlays (such as -["Loading"](/x/react-data-grid/overlays/#loading-overlay) or -["No rows"](/x/react-data-grid/overlays/#no-rows-overlay)) -take the height of two rows by default. - -To customize the overlay height, use the `--DataGrid-overlayHeight` CSS variable. - -{{"demo": "AutoHeightOverlay.js", "bg": "inline"}} - ## API - [DataGrid](/x/api/data-grid/data-grid/) diff --git a/docs/data/data-grid/list-view/ListViewAdvanced.js b/docs/data/data-grid/list-view/ListViewAdvanced.js index b27633b63270..2185d42a142d 100644 --- a/docs/data/data-grid/list-view/ListViewAdvanced.js +++ b/docs/data/data-grid/list-view/ListViewAdvanced.js @@ -258,7 +258,13 @@ export default function ListViewAdvanced() { return ( -
+
-
+
; ``` -Note that `createTheme` accepts any number of arguments. +Note that `createTheme()` accepts any number of arguments. If you are already using the [translations of the core components](/material-ui/guides/localization/#locale-text), you can add `bgBG` as a new argument. The same import works for Data Grid Pro as it's an extension of Data Grid. @@ -86,7 +86,7 @@ const theme = createTheme( ; ``` -If you want to pass language translations directly to the Data Grid without using `createTheme` and `ThemeProvider`, you can directly load the language translations from `@mui/x-data-grid/locales`. +If you want to pass language translations directly to the Data Grid without using `createTheme()` and `ThemeProvider`, you can directly load the language translations from `@mui/x-data-grid/locales`. ```jsx import { DataGrid } from '@mui/x-data-grid'; diff --git a/docs/data/dataGridApiPages.ts b/docs/data/dataGridApiPages.ts new file mode 100644 index 000000000000..37479bd4801b --- /dev/null +++ b/docs/data/dataGridApiPages.ts @@ -0,0 +1,31 @@ +import type { MuiPage } from 'docs/src/MuiPage'; + +const dataGridApiPages: MuiPage[] = [ + { + pathname: '/x/api/data-grid/data-grid', + title: 'DataGrid', + }, + { + pathname: '/x/api/data-grid/data-grid-premium', + title: 'DataGridPremium', + plan: 'premium', + }, + { + pathname: '/x/api/data-grid/data-grid-pro', + title: 'DataGridPro', + plan: 'pro', + }, + { + pathname: '/x/api/data-grid/grid-filter-form', + title: 'GridFilterForm', + }, + { + pathname: '/x/api/data-grid/grid-filter-panel', + title: 'GridFilterPanel', + }, + { + pathname: '/x/api/data-grid/grid-toolbar-quick-filter', + title: 'GridToolbarQuickFilter', + }, +]; +export default dataGridApiPages; diff --git a/docs/data/date-pickers/custom-components/CalendarHeaderComponent.js b/docs/data/date-pickers/custom-components/CalendarHeaderComponent.js index 053d4fc857fc..03a95b966892 100644 --- a/docs/data/date-pickers/custom-components/CalendarHeaderComponent.js +++ b/docs/data/date-pickers/custom-components/CalendarHeaderComponent.js @@ -1,5 +1,4 @@ import * as React from 'react'; - import { styled } from '@mui/material/styles'; import Typography from '@mui/material/Typography'; import Stack from '@mui/material/Stack'; diff --git a/docs/data/date-pickers/custom-components/CalendarHeaderComponent.tsx b/docs/data/date-pickers/custom-components/CalendarHeaderComponent.tsx index 3cec6edb80b3..1485aff154fc 100644 --- a/docs/data/date-pickers/custom-components/CalendarHeaderComponent.tsx +++ b/docs/data/date-pickers/custom-components/CalendarHeaderComponent.tsx @@ -1,5 +1,4 @@ import * as React from 'react'; -import { Dayjs } from 'dayjs'; import { styled } from '@mui/material/styles'; import Typography from '@mui/material/Typography'; import Stack from '@mui/material/Stack'; @@ -21,7 +20,7 @@ const CustomCalendarHeaderRoot = styled('div')({ alignItems: 'center', }); -function CustomCalendarHeader(props: PickersCalendarHeaderProps) { +function CustomCalendarHeader(props: PickersCalendarHeaderProps) { const { currentMonth, onMonthChange } = props; const selectNextMonth = () => onMonthChange(currentMonth.add(1, 'month'), 'left'); diff --git a/docs/data/date-pickers/custom-components/CalendarHeaderComponentRange.js b/docs/data/date-pickers/custom-components/CalendarHeaderComponentRange.js index 881a6630a012..77e1ef974b77 100644 --- a/docs/data/date-pickers/custom-components/CalendarHeaderComponentRange.js +++ b/docs/data/date-pickers/custom-components/CalendarHeaderComponentRange.js @@ -1,5 +1,4 @@ import * as React from 'react'; - import { styled } from '@mui/material/styles'; import Typography from '@mui/material/Typography'; import IconButton from '@mui/material/IconButton'; diff --git a/docs/data/date-pickers/custom-components/CalendarHeaderComponentRange.tsx b/docs/data/date-pickers/custom-components/CalendarHeaderComponentRange.tsx index e150031d943e..5d94074bf0ca 100644 --- a/docs/data/date-pickers/custom-components/CalendarHeaderComponentRange.tsx +++ b/docs/data/date-pickers/custom-components/CalendarHeaderComponentRange.tsx @@ -1,5 +1,4 @@ import * as React from 'react'; -import { Dayjs } from 'dayjs'; import { styled } from '@mui/material/styles'; import Typography from '@mui/material/Typography'; import IconButton from '@mui/material/IconButton'; @@ -18,7 +17,7 @@ const CustomCalendarHeaderRoot = styled('div')({ alignItems: 'center', }); -function CustomCalendarHeader(props: PickersRangeCalendarHeaderProps) { +function CustomCalendarHeader(props: PickersRangeCalendarHeaderProps) { const { currentMonth, onMonthChange, month, calendars, monthIndex } = props; const selectNextMonth = () => diff --git a/docs/data/date-pickers/custom-components/ToolbarComponent.tsx b/docs/data/date-pickers/custom-components/ToolbarComponent.tsx index 1bd91ecaf27d..3d24bc3a483a 100644 --- a/docs/data/date-pickers/custom-components/ToolbarComponent.tsx +++ b/docs/data/date-pickers/custom-components/ToolbarComponent.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import dayjs, { Dayjs } from 'dayjs'; +import dayjs from 'dayjs'; import Box from '@mui/material/Box'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; @@ -10,7 +10,7 @@ import { DatePickerToolbarProps, } from '@mui/x-date-pickers/DatePicker'; -function CustomToolbar(props: DatePickerToolbarProps) { +function CustomToolbar(props: DatePickerToolbarProps) { return ( { const BrowserDateField = React.forwardRef((props, ref) => { const { slots, slotProps, ...textFieldProps } = props; - const fieldResponse = useDateField({ - ...textFieldProps, - enableAccessibleFieldDOMStructure: true, - }); + const fieldResponse = useDateField(textFieldProps); /* If you don't need a clear button, you can skip the use of this hook */ const processedFieldProps = useClearableField({ diff --git a/docs/data/date-pickers/custom-field/BrowserV7Field.tsx b/docs/data/date-pickers/custom-field/BrowserV7Field.tsx index 202c6dd74e0a..00e3b3388d57 100644 --- a/docs/data/date-pickers/custom-field/BrowserV7Field.tsx +++ b/docs/data/date-pickers/custom-field/BrowserV7Field.tsx @@ -1,5 +1,4 @@ import * as React from 'react'; -import { Dayjs } from 'dayjs'; import useForkRef from '@mui/utils/useForkRef'; import { styled } from '@mui/material/styles'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; @@ -15,6 +14,7 @@ import { BaseSingleInputFieldProps, DateValidationError, FieldSection, + PickerValidDate, } from '@mui/x-date-pickers/models'; import { Unstable_PickersSectionList as PickersSectionList } from '@mui/x-date-pickers/PickersSectionList'; @@ -105,10 +105,10 @@ const BrowserTextField = React.forwardRef( ); interface BrowserDateFieldProps - extends UseDateFieldProps, + extends UseDateFieldProps, BaseSingleInputFieldProps< - Dayjs | null, - Dayjs, + // This usage of PickerValidDate will go away with TIsRange + PickerValidDate | null, FieldSection, true, DateValidationError @@ -118,10 +118,7 @@ const BrowserDateField = React.forwardRef( (props: BrowserDateFieldProps, ref: React.Ref) => { const { slots, slotProps, ...textFieldProps } = props; - const fieldResponse = useDateField({ - ...textFieldProps, - enableAccessibleFieldDOMStructure: true, - }); + const fieldResponse = useDateField(textFieldProps); /* If you don't need a clear button, you can skip the use of this hook */ const processedFieldProps = useClearableField({ @@ -135,7 +132,7 @@ const BrowserDateField = React.forwardRef( ); const BrowserDatePicker = React.forwardRef( - (props: DatePickerProps, ref: React.Ref) => { + (props: DatePickerProps, ref: React.Ref) => { return ( , + extends UseDateRangeFieldProps, BaseMultiInputFieldProps< - DateRange, - Dayjs, + // This usage of PickerValidDate will go away with TIsRange + DateRange, RangeFieldSection, true, DateRangeValidationError @@ -157,7 +157,6 @@ const BrowserMultiInputDateRangeField = React.forwardRef( }) as MultiInputFieldSlotTextFieldProps; const fieldResponse = useMultiInputDateRangeField< - Dayjs, true, MultiInputFieldSlotTextFieldProps >({ @@ -201,7 +200,7 @@ const BrowserMultiInputDateRangeField = React.forwardRef( ) as BrowserMultiInputDateRangeFieldComponent; const BrowserDateRangePicker = React.forwardRef( - (props: DateRangePickerProps, ref: React.Ref) => { + (props: DateRangePickerProps, ref: React.Ref) => { return ( { ), }; - const fieldResponse = useSingleInputDateRangeField({ - ...textFieldProps, - enableAccessibleFieldDOMStructure: true, - }); + const fieldResponse = useSingleInputDateRangeField(textFieldProps); /* If you don't need a clear button, you can skip the use of this hook */ const processedFieldProps = useClearableField({ diff --git a/docs/data/date-pickers/custom-field/BrowserV7SingleInputRangeField.tsx b/docs/data/date-pickers/custom-field/BrowserV7SingleInputRangeField.tsx index 5c925effbaab..adfe26146591 100644 --- a/docs/data/date-pickers/custom-field/BrowserV7SingleInputRangeField.tsx +++ b/docs/data/date-pickers/custom-field/BrowserV7SingleInputRangeField.tsx @@ -1,5 +1,4 @@ import * as React from 'react'; -import { Dayjs } from 'dayjs'; import useForkRef from '@mui/utils/useForkRef'; import useSlotProps from '@mui/utils/useSlotProps'; import { styled } from '@mui/material/styles'; @@ -25,7 +24,10 @@ import { DateRange, FieldType, } from '@mui/x-date-pickers-pro/models'; -import { BaseSingleInputFieldProps } from '@mui/x-date-pickers/models'; +import { + BaseSingleInputFieldProps, + PickerValidDate, +} from '@mui/x-date-pickers/models'; const BrowserFieldRoot = styled('div', { name: 'BrowserField', slot: 'Root' })({ display: 'flex', @@ -114,10 +116,10 @@ const BrowserTextField = React.forwardRef( ); interface BrowserSingleInputDateRangeFieldProps - extends UseSingleInputDateRangeFieldProps, + extends UseSingleInputDateRangeFieldProps, BaseSingleInputFieldProps< - DateRange, - Dayjs, + // This usage of PickerValidDate will go away with TIsRange + DateRange, RangeFieldSection, true, DateRangeValidationError @@ -151,11 +153,9 @@ const BrowserSingleInputDateRangeField = React.forwardRef( ), }; - const fieldResponse = useSingleInputDateRangeField< - Dayjs, - true, - typeof textFieldProps - >({ ...textFieldProps, enableAccessibleFieldDOMStructure: true }); + const fieldResponse = useSingleInputDateRangeField( + textFieldProps, + ); /* If you don't need a clear button, you can skip the use of this hook */ const processedFieldProps = useClearableField({ @@ -179,7 +179,7 @@ const BrowserSingleInputDateRangeField = React.forwardRef( BrowserSingleInputDateRangeField.fieldType = 'single-input'; const BrowserSingleInputDateRangePicker = React.forwardRef( - (props: DateRangePickerProps, ref: React.Ref) => { + (props: DateRangePickerProps, ref: React.Ref) => { const [isOpen, setIsOpen] = React.useState(false); const toggleOpen = () => setIsOpen((currentOpen) => !currentOpen); diff --git a/docs/data/date-pickers/custom-field/JoyV6Field.js b/docs/data/date-pickers/custom-field/JoyV6Field.js index 29f4e14ce291..9d6802c1ecef 100644 --- a/docs/data/date-pickers/custom-field/JoyV6Field.js +++ b/docs/data/date-pickers/custom-field/JoyV6Field.js @@ -1,5 +1,4 @@ import * as React from 'react'; - import { useTheme as useMaterialTheme, useColorScheme as useMaterialColorScheme, diff --git a/docs/data/date-pickers/custom-field/JoyV6Field.tsx b/docs/data/date-pickers/custom-field/JoyV6Field.tsx index 05c311984ebf..a2dfdebe9255 100644 --- a/docs/data/date-pickers/custom-field/JoyV6Field.tsx +++ b/docs/data/date-pickers/custom-field/JoyV6Field.tsx @@ -1,5 +1,4 @@ import * as React from 'react'; -import { Dayjs } from 'dayjs'; import { useTheme as useMaterialTheme, useColorScheme as useMaterialColorScheme, @@ -26,6 +25,7 @@ import { BaseSingleInputFieldProps, DateValidationError, FieldSection, + PickerValidDate, } from '@mui/x-date-pickers/models'; const joyTheme = extendJoyTheme(); @@ -100,10 +100,10 @@ const JoyField = React.forwardRef( ) as JoyFieldComponent; interface JoyDateFieldProps - extends UseDateFieldProps, + extends UseDateFieldProps, BaseSingleInputFieldProps< - Dayjs | null, - Dayjs, + // This usage of PickerValidDate will go away with TIsRange + PickerValidDate | null, FieldSection, false, DateValidationError @@ -113,7 +113,7 @@ const JoyDateField = React.forwardRef( (props: JoyDateFieldProps, ref: React.Ref) => { const { slots, slotProps, ...textFieldProps } = props; - const fieldResponse = useDateField({ + const fieldResponse = useDateField({ ...textFieldProps, enableAccessibleFieldDOMStructure: false, }); @@ -130,7 +130,7 @@ const JoyDateField = React.forwardRef( ); const JoyDatePicker = React.forwardRef( - (props: DatePickerProps, ref: React.Ref) => { + (props: DatePickerProps, ref: React.Ref) => { return ( , + extends UseDateRangeFieldProps, BaseMultiInputFieldProps< - DateRange, - Dayjs, + // This usage of PickerValidDate will go away with TIsRange + DateRange, RangeFieldSection, false, DateRangeValidationError @@ -179,7 +179,6 @@ const JoyMultiInputDateRangeField = React.forwardRef( }) as MultiInputFieldSlotTextFieldProps; const fieldResponse = useMultiInputDateRangeField< - Dayjs, false, MultiInputFieldSlotTextFieldProps >({ @@ -215,7 +214,7 @@ const JoyMultiInputDateRangeField = React.forwardRef( ) as JoyMultiInputDateRangeFieldComponent; const JoyDateRangePicker = React.forwardRef( - (props: DateRangePickerProps, ref: React.Ref) => { + (props: DateRangePickerProps, ref: React.Ref) => { return ( , + extends UseSingleInputDateRangeFieldProps, BaseSingleInputFieldProps< - DateRange, - Dayjs, + // This usage of PickerValidDate will go away with TIsRange + DateRange, RangeFieldSection, false, DateRangeValidationError @@ -128,7 +130,6 @@ const JoySingleInputDateRangeField = React.forwardRef( }); const fieldResponse = useSingleInputDateRangeField< - Dayjs, false, JoySingleInputDateRangeFieldProps >({ ...textFieldProps, enableAccessibleFieldDOMStructure: false }); @@ -162,7 +163,7 @@ const JoySingleInputDateRangeField = React.forwardRef( JoySingleInputDateRangeField.fieldType = 'single-input'; const JoySingleInputDateRangePicker = React.forwardRef( - (props: DateRangePickerProps, ref: React.Ref) => { + (props: DateRangePickerProps, ref: React.Ref) => { const [isOpen, setIsOpen] = React.useState(false); const toggleOpen = (event: React.PointerEvent) => { diff --git a/docs/data/date-pickers/custom-field/MaterialV6Field.js b/docs/data/date-pickers/custom-field/MaterialV6Field.js index 35d4e0ca73ea..98a5d2d58c27 100644 --- a/docs/data/date-pickers/custom-field/MaterialV6Field.js +++ b/docs/data/date-pickers/custom-field/MaterialV6Field.js @@ -9,8 +9,8 @@ export default function MaterialV6Field() { return ( - - + + ); diff --git a/docs/data/date-pickers/custom-field/MaterialV6Field.tsx b/docs/data/date-pickers/custom-field/MaterialV6Field.tsx index 35d4e0ca73ea..98a5d2d58c27 100644 --- a/docs/data/date-pickers/custom-field/MaterialV6Field.tsx +++ b/docs/data/date-pickers/custom-field/MaterialV6Field.tsx @@ -9,8 +9,8 @@ export default function MaterialV6Field() { return ( - - + + ); diff --git a/docs/data/date-pickers/custom-field/MaterialV6Field.tsx.preview b/docs/data/date-pickers/custom-field/MaterialV6Field.tsx.preview index 027cb7beacfa..9041ed886d8b 100644 --- a/docs/data/date-pickers/custom-field/MaterialV6Field.tsx.preview +++ b/docs/data/date-pickers/custom-field/MaterialV6Field.tsx.preview @@ -1,2 +1,2 @@ - - \ No newline at end of file + + \ No newline at end of file diff --git a/docs/data/date-pickers/custom-field/MaterialV7FieldWrapped.js b/docs/data/date-pickers/custom-field/MaterialV7FieldWrapped.js index d125a8479b5c..22560a3bcc80 100644 --- a/docs/data/date-pickers/custom-field/MaterialV7FieldWrapped.js +++ b/docs/data/date-pickers/custom-field/MaterialV7FieldWrapped.js @@ -14,14 +14,8 @@ export default function MaterialV7FieldWrapped() { return ( - - + + ); diff --git a/docs/data/date-pickers/custom-field/MaterialV7FieldWrapped.tsx b/docs/data/date-pickers/custom-field/MaterialV7FieldWrapped.tsx index 82e06da7316b..d054e12c04de 100644 --- a/docs/data/date-pickers/custom-field/MaterialV7FieldWrapped.tsx +++ b/docs/data/date-pickers/custom-field/MaterialV7FieldWrapped.tsx @@ -19,14 +19,8 @@ export default function MaterialV7FieldWrapped() { return ( - - + + ); diff --git a/docs/data/date-pickers/custom-field/MaterialV7FieldWrapped.tsx.preview b/docs/data/date-pickers/custom-field/MaterialV7FieldWrapped.tsx.preview index 17535291f5f3..a31c9c5bc351 100644 --- a/docs/data/date-pickers/custom-field/MaterialV7FieldWrapped.tsx.preview +++ b/docs/data/date-pickers/custom-field/MaterialV7FieldWrapped.tsx.preview @@ -1,8 +1,2 @@ - - \ No newline at end of file + + \ No newline at end of file diff --git a/docs/data/date-pickers/custom-field/SingleInputDateRangePickerWrapped.js b/docs/data/date-pickers/custom-field/SingleInputDateRangePickerWrapped.js index aa20bda0c427..c701e767e0c3 100644 --- a/docs/data/date-pickers/custom-field/SingleInputDateRangePickerWrapped.js +++ b/docs/data/date-pickers/custom-field/SingleInputDateRangePickerWrapped.js @@ -1,5 +1,4 @@ import * as React from 'react'; - import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { DateRangePicker } from '@mui/x-date-pickers-pro/DateRangePicker'; diff --git a/docs/data/date-pickers/custom-field/SingleInputDateRangePickerWrapped.tsx b/docs/data/date-pickers/custom-field/SingleInputDateRangePickerWrapped.tsx index 21ea29ee17dd..470c3de71092 100644 --- a/docs/data/date-pickers/custom-field/SingleInputDateRangePickerWrapped.tsx +++ b/docs/data/date-pickers/custom-field/SingleInputDateRangePickerWrapped.tsx @@ -1,5 +1,4 @@ import * as React from 'react'; -import { Dayjs } from 'dayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { DateRangePicker } from '@mui/x-date-pickers-pro/DateRangePicker'; @@ -8,19 +7,14 @@ import { SingleInputDateRangeFieldProps, } from '@mui/x-date-pickers-pro/SingleInputDateRangeField'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; -import { PickerValidDate } from '@mui/x-date-pickers/models'; import { FieldType } from '@mui/x-date-pickers-pro/models'; -type FieldComponent = (( - props: SingleInputDateRangeFieldProps & - React.RefAttributes, +type FieldComponent = (( + props: SingleInputDateRangeFieldProps & React.RefAttributes, ) => React.JSX.Element) & { fieldType?: FieldType }; const WrappedSingleInputDateRangeField = React.forwardRef( - ( - props: SingleInputDateRangeFieldProps, - ref: React.Ref, - ) => { + (props: SingleInputDateRangeFieldProps, ref: React.Ref) => { return ; }, ) as FieldComponent; diff --git a/docs/data/date-pickers/custom-field/behavior-autocomplete/MaterialDatePicker.js b/docs/data/date-pickers/custom-field/behavior-autocomplete/MaterialDatePicker.js new file mode 100644 index 000000000000..0e849ab1228c --- /dev/null +++ b/docs/data/date-pickers/custom-field/behavior-autocomplete/MaterialDatePicker.js @@ -0,0 +1,135 @@ +import * as React from 'react'; +import dayjs from 'dayjs'; +import Autocomplete from '@mui/material/Autocomplete'; +import TextField from '@mui/material/TextField'; +import Stack from '@mui/material/Stack'; +import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; +import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; +import { DatePicker } from '@mui/x-date-pickers/DatePicker'; +import { useSplitFieldProps } from '@mui/x-date-pickers/hooks'; +import { useValidation, validateDate } from '@mui/x-date-pickers/validation'; + +function AutocompleteField(props) { + const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date'); + const { value, timezone, onChange } = internalProps; + const { + InputProps, + slotProps, + slots, + ownerState, + label, + focused, + name, + options = [], + inputProps, + ...other + } = forwardedProps; + + const { hasValidationError } = useValidation({ + validator: validateDate, + value, + timezone, + props: internalProps, + }); + + const mergeAdornments = (...adornments) => { + const nonNullAdornments = adornments.filter((el) => el != null); + if (nonNullAdornments.length === 0) { + return null; + } + + if (nonNullAdornments.length === 1) { + return nonNullAdornments[0]; + } + + return ( + + {nonNullAdornments.map((adornment, index) => ( + {adornment} + ))} + + ); + }; + + return ( + ( + + )} + getOptionLabel={(option) => { + if (!dayjs.isDayjs(option)) { + return ''; + } + + return option.format('MM / DD / YYYY'); + }} + value={value} + onChange={(_, newValue) => { + onChange?.(newValue, { validationError: null }); + }} + isOptionEqualToValue={(option, valueToCheck) => + option.toISOString() === valueToCheck.toISOString() + } + /> + ); +} + +function AutocompleteDatePicker(props) { + const { options, ...other } = props; + + const optionsLookup = React.useMemo( + () => + options.reduce((acc, option) => { + acc[option.toISOString()] = true; + return acc; + }, {}), + [options], + ); + + return ( + !optionsLookup[date.startOf('day').toISOString()]} + {...other} + /> + ); +} + +const today = dayjs().startOf('day'); + +export default function MaterialDatePicker() { + return ( + + + + ); +} diff --git a/docs/data/date-pickers/custom-field/behavior-autocomplete/MaterialDatePicker.tsx b/docs/data/date-pickers/custom-field/behavior-autocomplete/MaterialDatePicker.tsx new file mode 100644 index 000000000000..10228ff08be1 --- /dev/null +++ b/docs/data/date-pickers/custom-field/behavior-autocomplete/MaterialDatePicker.tsx @@ -0,0 +1,156 @@ +import * as React from 'react'; +import dayjs, { Dayjs } from 'dayjs'; +import Autocomplete from '@mui/material/Autocomplete'; +import TextField from '@mui/material/TextField'; +import Stack from '@mui/material/Stack'; +import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; +import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; +import { + DatePicker, + DatePickerFieldProps, + DatePickerProps, +} from '@mui/x-date-pickers/DatePicker'; +import { useSplitFieldProps } from '@mui/x-date-pickers/hooks'; +import { useValidation, validateDate } from '@mui/x-date-pickers/validation'; + +interface AutocompleteFieldProps extends DatePickerFieldProps { + /** + * @typescript-to-proptypes-ignore + */ + options?: Dayjs[]; +} + +function AutocompleteField(props: AutocompleteFieldProps) { + const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date'); + const { value, timezone, onChange } = internalProps; + const { + InputProps, + slotProps, + slots, + ownerState, + label, + focused, + name, + options = [], + inputProps, + ...other + } = forwardedProps; + + const { hasValidationError } = useValidation({ + validator: validateDate, + value, + timezone, + props: internalProps, + }); + + const mergeAdornments = (...adornments: React.ReactNode[]) => { + const nonNullAdornments = adornments.filter((el) => el != null); + if (nonNullAdornments.length === 0) { + return null; + } + + if (nonNullAdornments.length === 1) { + return nonNullAdornments[0]; + } + + return ( + + {nonNullAdornments.map((adornment, index) => ( + {adornment} + ))} + + ); + }; + + return ( + ( + + )} + getOptionLabel={(option) => { + if (!dayjs.isDayjs(option)) { + return ''; + } + + return option.format('MM / DD / YYYY'); + }} + value={value} + onChange={(_, newValue) => { + onChange?.(newValue, { validationError: null }); + }} + isOptionEqualToValue={(option, valueToCheck) => + option.toISOString() === valueToCheck.toISOString() + } + /> + ); +} + +interface AutocompleteDatePickerProps extends DatePickerProps { + /** + * @typescript-to-proptypes-ignore + */ + options: Dayjs[]; +} + +function AutocompleteDatePicker(props: AutocompleteDatePickerProps) { + const { options, ...other } = props; + + const optionsLookup = React.useMemo( + () => + options.reduce( + (acc, option) => { + acc[option.toISOString()] = true; + return acc; + }, + {} as Record, + ), + [options], + ); + + return ( + !optionsLookup[date.startOf('day').toISOString()]} + {...other} + /> + ); +} + +const today = dayjs().startOf('day'); + +export default function MaterialDatePicker() { + return ( + + + + ); +} diff --git a/docs/data/date-pickers/custom-field/behavior-autocomplete/MaterialDatePicker.tsx.preview b/docs/data/date-pickers/custom-field/behavior-autocomplete/MaterialDatePicker.tsx.preview new file mode 100644 index 000000000000..955d5bd4d018 --- /dev/null +++ b/docs/data/date-pickers/custom-field/behavior-autocomplete/MaterialDatePicker.tsx.preview @@ -0,0 +1,9 @@ + \ No newline at end of file diff --git a/docs/data/date-pickers/custom-field/behavior-button/MaterialDatePicker.js b/docs/data/date-pickers/custom-field/behavior-button/MaterialDatePicker.js new file mode 100644 index 000000000000..6082f6580ca7 --- /dev/null +++ b/docs/data/date-pickers/custom-field/behavior-button/MaterialDatePicker.js @@ -0,0 +1,72 @@ +import * as React from 'react'; +import Button from '@mui/material/Button'; +import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; +import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; +import { DatePicker } from '@mui/x-date-pickers/DatePicker'; +import { useValidation, validateDate } from '@mui/x-date-pickers/validation'; +import { + useSplitFieldProps, + useParsedFormat, + usePickersContext, +} from '@mui/x-date-pickers/hooks'; + +function ButtonDateField(props) { + const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date'); + const { value, timezone, format } = internalProps; + const { + InputProps, + slotProps, + slots, + ownerState, + label, + focused, + name, + ...other + } = forwardedProps; + + const pickersContext = usePickersContext(); + + const parsedFormat = useParsedFormat(internalProps); + const { hasValidationError } = useValidation({ + validator: validateDate, + value, + timezone, + props: internalProps, + }); + + const handleTogglePicker = (event) => { + if (pickersContext.open) { + pickersContext.onClose(event); + } else { + pickersContext.onOpen(event); + } + }; + + const valueStr = value == null ? parsedFormat : value.format(format); + + return ( + + ); +} + +function ButtonFieldDatePicker(props) { + return ( + + ); +} + +export default function MaterialDatePicker() { + return ( + + + + ); +} diff --git a/docs/data/date-pickers/custom-field/behavior-button/MaterialDatePicker.tsx b/docs/data/date-pickers/custom-field/behavior-button/MaterialDatePicker.tsx new file mode 100644 index 000000000000..ae9ffb08d896 --- /dev/null +++ b/docs/data/date-pickers/custom-field/behavior-button/MaterialDatePicker.tsx @@ -0,0 +1,76 @@ +import * as React from 'react'; +import Button from '@mui/material/Button'; +import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; +import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; +import { + DatePicker, + DatePickerProps, + DatePickerFieldProps, +} from '@mui/x-date-pickers/DatePicker'; +import { useValidation, validateDate } from '@mui/x-date-pickers/validation'; +import { + useSplitFieldProps, + useParsedFormat, + usePickersContext, +} from '@mui/x-date-pickers/hooks'; + +function ButtonDateField(props: DatePickerFieldProps) { + const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date'); + const { value, timezone, format } = internalProps; + const { + InputProps, + slotProps, + slots, + ownerState, + label, + focused, + name, + ...other + } = forwardedProps; + + const pickersContext = usePickersContext(); + + const parsedFormat = useParsedFormat(internalProps); + const { hasValidationError } = useValidation({ + validator: validateDate, + value, + timezone, + props: internalProps, + }); + + const handleTogglePicker = (event: React.UIEvent) => { + if (pickersContext.open) { + pickersContext.onClose(event); + } else { + pickersContext.onOpen(event); + } + }; + + const valueStr = value == null ? parsedFormat : value.format(format); + + return ( + + ); +} + +function ButtonFieldDatePicker(props: DatePickerProps) { + return ( + + ); +} + +export default function MaterialDatePicker() { + return ( + + + + ); +} diff --git a/docs/data/date-pickers/custom-field/behavior-button/MaterialDatePicker.tsx.preview b/docs/data/date-pickers/custom-field/behavior-button/MaterialDatePicker.tsx.preview new file mode 100644 index 000000000000..5f578e21a1d6 --- /dev/null +++ b/docs/data/date-pickers/custom-field/behavior-button/MaterialDatePicker.tsx.preview @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/data/date-pickers/custom-field/behavior-button/MaterialDateRangePicker.js b/docs/data/date-pickers/custom-field/behavior-button/MaterialDateRangePicker.js new file mode 100644 index 000000000000..f9fc03f45d57 --- /dev/null +++ b/docs/data/date-pickers/custom-field/behavior-button/MaterialDateRangePicker.js @@ -0,0 +1,82 @@ +import * as React from 'react'; + +import Button from '@mui/material/Button'; +import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; +import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; +import { DateRangePicker } from '@mui/x-date-pickers-pro/DateRangePicker'; +import { useValidation } from '@mui/x-date-pickers/validation'; +import { validateDateRange } from '@mui/x-date-pickers-pro/validation'; +import { + useSplitFieldProps, + useParsedFormat, + usePickersContext, +} from '@mui/x-date-pickers/hooks'; + +function ButtonDateRangeField(props) { + const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date'); + const { value, timezone, format } = internalProps; + const { + InputProps, + slotProps, + slots, + ownerState, + label, + focused, + name, + ...other + } = forwardedProps; + + const pickersContext = usePickersContext(); + + const parsedFormat = useParsedFormat(internalProps); + const { hasValidationError } = useValidation({ + validator: validateDateRange, + value, + timezone, + props: internalProps, + }); + + const handleTogglePicker = (event) => { + if (pickersContext.open) { + pickersContext.onClose(event); + } else { + pickersContext.onOpen(event); + } + }; + + const formattedValue = (value ?? [null, null]) + .map((date) => (date == null ? parsedFormat : date.format(format))) + .join(' – '); + + return ( + + ); +} + +// TODO v8: Will be removed before the end of the alpha since single input will become the default field. +ButtonDateRangeField.fieldType = 'single-input'; + +function ButtonFieldDateRangePicker(props) { + return ( + + ); +} + +export default function MaterialDateRangePicker() { + return ( + + + + ); +} diff --git a/docs/data/date-pickers/custom-field/behavior-button/MaterialDateRangePicker.tsx b/docs/data/date-pickers/custom-field/behavior-button/MaterialDateRangePicker.tsx new file mode 100644 index 000000000000..522fe8a047b4 --- /dev/null +++ b/docs/data/date-pickers/custom-field/behavior-button/MaterialDateRangePicker.tsx @@ -0,0 +1,86 @@ +import * as React from 'react'; +import { Dayjs } from 'dayjs'; +import Button from '@mui/material/Button'; +import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; +import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; +import { + DateRangePicker, + DateRangePickerProps, + DateRangePickerFieldProps, +} from '@mui/x-date-pickers-pro/DateRangePicker'; +import { useValidation } from '@mui/x-date-pickers/validation'; +import { validateDateRange } from '@mui/x-date-pickers-pro/validation'; +import { + useSplitFieldProps, + useParsedFormat, + usePickersContext, +} from '@mui/x-date-pickers/hooks'; + +function ButtonDateRangeField(props: DateRangePickerFieldProps) { + const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date'); + const { value, timezone, format } = internalProps; + const { + InputProps, + slotProps, + slots, + ownerState, + label, + focused, + name, + ...other + } = forwardedProps; + + const pickersContext = usePickersContext(); + + const parsedFormat = useParsedFormat(internalProps); + const { hasValidationError } = useValidation({ + validator: validateDateRange, + value, + timezone, + props: internalProps, + }); + + const handleTogglePicker = (event: React.UIEvent) => { + if (pickersContext.open) { + pickersContext.onClose(event); + } else { + pickersContext.onOpen(event); + } + }; + + const formattedValue = (value ?? [null, null]) + .map((date: Dayjs) => (date == null ? parsedFormat : date.format(format))) + .join(' – '); + + return ( + + ); +} + +// TODO v8: Will be removed before the end of the alpha since single input will become the default field. +ButtonDateRangeField.fieldType = 'single-input'; + +function ButtonFieldDateRangePicker(props: DateRangePickerProps) { + return ( + + ); +} + +export default function MaterialDateRangePicker() { + return ( + + + + ); +} diff --git a/docs/data/date-pickers/custom-field/behavior-button/MaterialDateRangePicker.tsx.preview b/docs/data/date-pickers/custom-field/behavior-button/MaterialDateRangePicker.tsx.preview new file mode 100644 index 000000000000..6512674c0bb6 --- /dev/null +++ b/docs/data/date-pickers/custom-field/behavior-button/MaterialDateRangePicker.tsx.preview @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/data/date-pickers/custom-field/behavior-masked-text-field/MaskedMaterialTextField.js b/docs/data/date-pickers/custom-field/behavior-masked-text-field/MaskedMaterialTextField.js new file mode 100644 index 000000000000..0723d4565c51 --- /dev/null +++ b/docs/data/date-pickers/custom-field/behavior-masked-text-field/MaskedMaterialTextField.js @@ -0,0 +1,164 @@ +import * as React from 'react'; +import dayjs from 'dayjs'; +import { useRifm } from 'rifm'; +import TextField from '@mui/material/TextField'; +import useControlled from '@mui/utils/useControlled'; +import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; +import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; +import { DatePicker } from '@mui/x-date-pickers/DatePicker'; +import { useSplitFieldProps, useParsedFormat } from '@mui/x-date-pickers/hooks'; +import { useValidation, validateDate } from '@mui/x-date-pickers/validation'; + +const MASK_USER_INPUT_SYMBOL = '_'; +const ACCEPT_REGEX = /[\d]/gi; + +const staticDateWith2DigitTokens = dayjs('2019-11-21T11:30:00.000'); +const staticDateWith1DigitTokens = dayjs('2019-01-01T09:00:00.000'); + +function getValueStrFromValue(value, format) { + if (value == null) { + return ''; + } + + return value.isValid() ? value.format(format) : ''; +} + +function MaskedField(props) { + const { slots, slotProps, ...other } = props; + + const { forwardedProps, internalProps } = useSplitFieldProps(other, 'date'); + + const { + format, + value: valueProp, + defaultValue, + onChange, + timezone, + onError, + } = internalProps; + + const [value, setValue] = useControlled({ + controlled: valueProp, + default: defaultValue ?? null, + name: 'MaskedField', + state: 'value', + }); + + // Control the input text + const [inputValue, setInputValue] = React.useState(() => + getValueStrFromValue(value, format), + ); + + React.useEffect(() => { + if (value && value.isValid()) { + const newDisplayDate = getValueStrFromValue(value, format); + setInputValue(newDisplayDate); + } + }, [format, value]); + + const parsedFormat = useParsedFormat(internalProps); + + const { hasValidationError, getValidationErrorForNewValue } = useValidation({ + value, + timezone, + onError, + props: internalProps, + validator: validateDate, + }); + + const handleValueStrChange = (newValueStr) => { + setInputValue(newValueStr); + + const newValue = dayjs(newValueStr, format); + setValue(newValue); + + if (onChange) { + onChange(newValue, { + validationError: getValidationErrorForNewValue(newValue), + }); + } + }; + + const rifmFormat = React.useMemo(() => { + const formattedDateWith1Digit = staticDateWith1DigitTokens.format(format); + const inferredFormatPatternWith1Digits = formattedDateWith1Digit.replace( + ACCEPT_REGEX, + MASK_USER_INPUT_SYMBOL, + ); + const inferredFormatPatternWith2Digits = staticDateWith2DigitTokens + .format(format) + .replace(ACCEPT_REGEX, '_'); + + if (inferredFormatPatternWith1Digits !== inferredFormatPatternWith2Digits) { + throw new Error( + `Mask does not support numbers with variable length such as 'M'.`, + ); + } + + const maskToUse = inferredFormatPatternWith1Digits; + + return function formatMaskedDate(valueToFormat) { + let outputCharIndex = 0; + return valueToFormat + .split('') + .map((character, characterIndex) => { + ACCEPT_REGEX.lastIndex = 0; + + if (outputCharIndex > maskToUse.length - 1) { + return ''; + } + + const maskChar = maskToUse[outputCharIndex]; + const nextMaskChar = maskToUse[outputCharIndex + 1]; + + const acceptedChar = ACCEPT_REGEX.test(character) ? character : ''; + const formattedChar = + maskChar === MASK_USER_INPUT_SYMBOL + ? acceptedChar + : maskChar + acceptedChar; + + outputCharIndex += formattedChar.length; + + const isLastCharacter = characterIndex === valueToFormat.length - 1; + if ( + isLastCharacter && + nextMaskChar && + nextMaskChar !== MASK_USER_INPUT_SYMBOL + ) { + // when cursor at the end of mask part (e.g. month) prerender next symbol "21" -> "21/" + return formattedChar ? formattedChar + nextMaskChar : ''; + } + + return formattedChar; + }) + .join(''); + }; + }, [format]); + + const rifmProps = useRifm({ + value: inputValue, + onChange: handleValueStrChange, + format: rifmFormat, + }); + + return ( + + ); +} + +function MaskedFieldDatePicker(props) { + return ; +} + +export default function MaskedMaterialTextField() { + return ( + + + + ); +} diff --git a/docs/data/date-pickers/custom-field/behavior-masked-text-field/MaskedMaterialTextField.tsx b/docs/data/date-pickers/custom-field/behavior-masked-text-field/MaskedMaterialTextField.tsx new file mode 100644 index 000000000000..13c0a71b5456 --- /dev/null +++ b/docs/data/date-pickers/custom-field/behavior-masked-text-field/MaskedMaterialTextField.tsx @@ -0,0 +1,168 @@ +import * as React from 'react'; +import dayjs, { Dayjs } from 'dayjs'; +import { useRifm } from 'rifm'; +import TextField from '@mui/material/TextField'; +import useControlled from '@mui/utils/useControlled'; +import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; +import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; +import { + DatePicker, + DatePickerProps, + DatePickerFieldProps, +} from '@mui/x-date-pickers/DatePicker'; +import { useSplitFieldProps, useParsedFormat } from '@mui/x-date-pickers/hooks'; +import { useValidation, validateDate } from '@mui/x-date-pickers/validation'; + +const MASK_USER_INPUT_SYMBOL = '_'; +const ACCEPT_REGEX = /[\d]/gi; + +const staticDateWith2DigitTokens = dayjs('2019-11-21T11:30:00.000'); +const staticDateWith1DigitTokens = dayjs('2019-01-01T09:00:00.000'); + +function getValueStrFromValue(value: Dayjs | null, format: string) { + if (value == null) { + return ''; + } + + return value.isValid() ? value.format(format) : ''; +} + +function MaskedField(props: DatePickerFieldProps) { + const { slots, slotProps, ...other } = props; + + const { forwardedProps, internalProps } = useSplitFieldProps(other, 'date'); + + const { + format, + value: valueProp, + defaultValue, + onChange, + timezone, + onError, + } = internalProps; + + const [value, setValue] = useControlled({ + controlled: valueProp, + default: defaultValue ?? null, + name: 'MaskedField', + state: 'value', + }); + + // Control the input text + const [inputValue, setInputValue] = React.useState(() => + getValueStrFromValue(value, format), + ); + + React.useEffect(() => { + if (value && value.isValid()) { + const newDisplayDate = getValueStrFromValue(value, format); + setInputValue(newDisplayDate); + } + }, [format, value]); + + const parsedFormat = useParsedFormat(internalProps); + + const { hasValidationError, getValidationErrorForNewValue } = useValidation({ + value, + timezone, + onError, + props: internalProps, + validator: validateDate, + }); + + const handleValueStrChange = (newValueStr: string) => { + setInputValue(newValueStr); + + const newValue = dayjs(newValueStr, format); + setValue(newValue); + + if (onChange) { + onChange(newValue, { + validationError: getValidationErrorForNewValue(newValue), + }); + } + }; + + const rifmFormat = React.useMemo(() => { + const formattedDateWith1Digit = staticDateWith1DigitTokens.format(format); + const inferredFormatPatternWith1Digits = formattedDateWith1Digit.replace( + ACCEPT_REGEX, + MASK_USER_INPUT_SYMBOL, + ); + const inferredFormatPatternWith2Digits = staticDateWith2DigitTokens + .format(format) + .replace(ACCEPT_REGEX, '_'); + + if (inferredFormatPatternWith1Digits !== inferredFormatPatternWith2Digits) { + throw new Error( + `Mask does not support numbers with variable length such as 'M'.`, + ); + } + + const maskToUse = inferredFormatPatternWith1Digits; + + return function formatMaskedDate(valueToFormat: string) { + let outputCharIndex = 0; + return valueToFormat + .split('') + .map((character, characterIndex) => { + ACCEPT_REGEX.lastIndex = 0; + + if (outputCharIndex > maskToUse.length - 1) { + return ''; + } + + const maskChar = maskToUse[outputCharIndex]; + const nextMaskChar = maskToUse[outputCharIndex + 1]; + + const acceptedChar = ACCEPT_REGEX.test(character) ? character : ''; + const formattedChar = + maskChar === MASK_USER_INPUT_SYMBOL + ? acceptedChar + : maskChar + acceptedChar; + + outputCharIndex += formattedChar.length; + + const isLastCharacter = characterIndex === valueToFormat.length - 1; + if ( + isLastCharacter && + nextMaskChar && + nextMaskChar !== MASK_USER_INPUT_SYMBOL + ) { + // when cursor at the end of mask part (e.g. month) prerender next symbol "21" -> "21/" + return formattedChar ? formattedChar + nextMaskChar : ''; + } + + return formattedChar; + }) + .join(''); + }; + }, [format]); + + const rifmProps = useRifm({ + value: inputValue, + onChange: handleValueStrChange, + format: rifmFormat, + }); + + return ( + + ); +} + +function MaskedFieldDatePicker(props: DatePickerProps) { + return ; +} + +export default function MaskedMaterialTextField() { + return ( + + + + ); +} diff --git a/docs/data/date-pickers/custom-field/behavior-masked-text-field/MaskedMaterialTextField.tsx.preview b/docs/data/date-pickers/custom-field/behavior-masked-text-field/MaskedMaterialTextField.tsx.preview new file mode 100644 index 000000000000..1340a82dd55d --- /dev/null +++ b/docs/data/date-pickers/custom-field/behavior-masked-text-field/MaskedMaterialTextField.tsx.preview @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/data/date-pickers/custom-field/behavior-read-only-text-field/MaterialDatePicker.js b/docs/data/date-pickers/custom-field/behavior-read-only-text-field/MaterialDatePicker.js new file mode 100644 index 000000000000..7c83e6a7480a --- /dev/null +++ b/docs/data/date-pickers/custom-field/behavior-read-only-text-field/MaterialDatePicker.js @@ -0,0 +1,66 @@ +import * as React from 'react'; +import TextField from '@mui/material/TextField'; +import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; +import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; +import { DatePicker } from '@mui/x-date-pickers/DatePicker'; +import { useValidation, validateDate } from '@mui/x-date-pickers/validation'; +import { + useSplitFieldProps, + useParsedFormat, + usePickersContext, +} from '@mui/x-date-pickers/hooks'; +import { CalendarIcon } from '@mui/x-date-pickers/icons'; + +function ReadOnlyDateField(props) { + const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date'); + const { value, timezone, format } = internalProps; + const { InputProps, slotProps, slots, ...other } = forwardedProps; + + const pickersContext = usePickersContext(); + + const parsedFormat = useParsedFormat(internalProps); + const { hasValidationError } = useValidation({ + validator: validateDate, + value, + timezone, + props: internalProps, + }); + + const handleTogglePicker = (event) => { + if (pickersContext.open) { + pickersContext.onClose(event); + } else { + pickersContext.onOpen(event); + } + }; + + return ( + , + sx: { cursor: 'pointer', '& *': { cursor: 'inherit' } }, + }} + error={hasValidationError} + onClick={handleTogglePicker} + /> + ); +} + +function ReadOnlyFieldDatePicker(props) { + return ( + + ); +} + +export default function MaterialDatePicker() { + return ( + + + + ); +} diff --git a/docs/data/date-pickers/custom-field/behavior-read-only-text-field/MaterialDatePicker.tsx b/docs/data/date-pickers/custom-field/behavior-read-only-text-field/MaterialDatePicker.tsx new file mode 100644 index 000000000000..9c06797fc2fc --- /dev/null +++ b/docs/data/date-pickers/custom-field/behavior-read-only-text-field/MaterialDatePicker.tsx @@ -0,0 +1,70 @@ +import * as React from 'react'; +import TextField from '@mui/material/TextField'; +import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; +import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; +import { + DatePicker, + DatePickerProps, + DatePickerFieldProps, +} from '@mui/x-date-pickers/DatePicker'; +import { useValidation, validateDate } from '@mui/x-date-pickers/validation'; +import { + useSplitFieldProps, + useParsedFormat, + usePickersContext, +} from '@mui/x-date-pickers/hooks'; +import { CalendarIcon } from '@mui/x-date-pickers/icons'; + +function ReadOnlyDateField(props: DatePickerFieldProps) { + const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date'); + const { value, timezone, format } = internalProps; + const { InputProps, slotProps, slots, ...other } = forwardedProps; + + const pickersContext = usePickersContext(); + + const parsedFormat = useParsedFormat(internalProps); + const { hasValidationError } = useValidation({ + validator: validateDate, + value, + timezone, + props: internalProps, + }); + + const handleTogglePicker = (event: React.UIEvent) => { + if (pickersContext.open) { + pickersContext.onClose(event); + } else { + pickersContext.onOpen(event); + } + }; + + return ( + , + sx: { cursor: 'pointer', '& *': { cursor: 'inherit' } }, + }} + error={hasValidationError} + onClick={handleTogglePicker} + /> + ); +} + +function ReadOnlyFieldDatePicker(props: DatePickerProps) { + return ( + + ); +} + +export default function MaterialDatePicker() { + return ( + + + + ); +} diff --git a/docs/data/date-pickers/custom-field/behavior-read-only-text-field/MaterialDatePicker.tsx.preview b/docs/data/date-pickers/custom-field/behavior-read-only-text-field/MaterialDatePicker.tsx.preview new file mode 100644 index 000000000000..e3842a12cb5d --- /dev/null +++ b/docs/data/date-pickers/custom-field/behavior-read-only-text-field/MaterialDatePicker.tsx.preview @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/data/date-pickers/custom-field/custom-field.md b/docs/data/date-pickers/custom-field/custom-field.md index 4f5b5f782fb3..3b9459feb141 100644 --- a/docs/data/date-pickers/custom-field/custom-field.md +++ b/docs/data/date-pickers/custom-field/custom-field.md @@ -8,10 +8,10 @@ components: PickersSectionList, PickersTextField # Custom field -

The Date and Time Pickers let you customize the field by passing props or custom components

+

The Date and Time Pickers let you customize the field by passing props or custom components.

:::success -See [Common concepts—Custom slots and subcomponents](/x/common-concepts/custom-components/) to learn how to use slots. +See [Common concepts—Slots and subcomponents](/x/common-concepts/custom-components/) to learn how to use slots. ::: ## Customize the default field @@ -66,30 +66,9 @@ Setting `formatDensity` to `"spacious"` will add a space before and after each ` {{"demo": "FieldFormatDensity.js"}} -## Usage with Material UI +## With Material UI -### Using Material `TextField` - -You can import the `TextField` component to create custom wrappers: - -{{"demo": "MaterialV6FieldWrapped.js"}} - -:::success -This approach is only recommended if you need complex customizations on your `TextField`, -or if you already have a wrapper also used outside the Date and Time Pickers. - -If you just need to set some default props, you can use [the `slotProps` prop](/x/react-date-pickers/custom-field/#customize-the-textfield). -::: - -### Using Material `PickersTextField` - -Pass the `enableAccessibleFieldDOMStructure` to any Field or Picker component to enable the accessible DOM structure: - -{{"demo": "MaterialV7Field.js"}} - -:::success -Learn more about the [accessible DOM structure](/x/react-date-pickers/fields/#accessible-dom-structure). -::: +### Wrapping `PickersTextField` You can import the `PickersTextField` component to create custom wrappers: @@ -101,80 +80,80 @@ This approach is only recommended if you need complex customizations on your `Pi If you just need to set some default props, you can use [the `slotProps` prop](/x/react-date-pickers/custom-field/#customize-the-textfield). ::: -## Usage with Joy UI +### Using Material `TextField` -### Using Joy `Input` +Pass the `enableAccessibleFieldDOMStructure={false}` to any Field or Picker component to use an `` for the editing instead of the new accessible DOM structure: -You can use the [Joy UI](https://mui.com/joy-ui/getting-started/) components instead of the Material UI ones: +{{"demo": "MaterialV6Field.js"}} -:::info -A higher-level solution for _Joy UI_ will be provided in the near future for even simpler usage. +:::warning +The non-accessible DOM structure will be deprecated in a follow up minor version and remove in `v9.x`. +If you are unable to migrate for some reason, please open an issue to describe what is missing from the new DOM structure so that we can improve it before dropping the old one. ::: -{{"demo": "JoyV6Field.js", "defaultCodeOpen": false}} - -{{"demo": "JoyV6SingleInputRangeField.js", "defaultCodeOpen": false}} +## With another Design System -{{"demo": "JoyV6MultiInputRangeField.js", "defaultCodeOpen": false}} - -### Using Joy `PickersTextField` +### Using a custom input :::warning -This component is not available yet. +You will need to use a component that supports the `sx` prop as a wrapper for your input +to be able to benefit from the **hover** and **focus** behavior of the clear button. +You will have access to the `clearable` and `onClear` props using native HTML elements, +but the on **focus** and **hover** behavior depends on styles applied via the `sx` prop. ::: -## Usage with an unstyled input +{{"demo": "BrowserV7Field.js", "defaultCodeOpen": false}} -### Using the browser input +{{"demo": "BrowserV7SingleInputRangeField.js", "defaultCodeOpen": false}} -{{"demo": "BrowserV6Field.js", "defaultCodeOpen": false}} +{{"demo": "BrowserV7MultiInputRangeField.js", "defaultCodeOpen": false}} -{{"demo": "BrowserV6SingleInputRangeField.js", "defaultCodeOpen": false}} +### Using Joy UI -{{"demo": "BrowserV6MultiInputRangeField.js", "defaultCodeOpen": false}} +You can use the [Joy UI](https://mui.com/joy-ui/getting-started/) components instead of the Material UI ones: -:::warning -You will need to use a component that supports the `sx` prop as a wrapper for your input, in order to be able to benefit from the **hover** and **focus** behavior of the clear button. You will have access to the `clearable` and `onClear` props using native HTML elements, but the on **focus** and **hover** behavior depends on styles applied via the `sx` prop. -::: +{{"demo": "JoyV6Field.js", "defaultCodeOpen": false}} -### Using custom `PickersTextField` +{{"demo": "JoyV6SingleInputRangeField.js", "defaultCodeOpen": false}} -:::success -Learn more about the accessible DOM structure and its difference compared to the current one on the [dedicated doc section](/x/react-date-pickers/fields/#accessible-dom-structure). +{{"demo": "JoyV6MultiInputRangeField.js", "defaultCodeOpen": false}} + +:::warning +All the Joy UI examples use the non-accessible DOM structure. +The new accessible DOM structure will become compatible with Joy UI in the future. ::: -{{"demo": "BrowserV7Field.js", "defaultCodeOpen": false}} +## With a custom editing experience -{{"demo": "BrowserV7SingleInputRangeField.js", "defaultCodeOpen": false}} +### Using an Autocomplete -{{"demo": "BrowserV7MultiInputRangeField.js", "defaultCodeOpen": false}} +If your user can only select a value in a small list of available dates, you can replace the field with the [Autocomplete](/material-ui/react-autocomplete/) component to list those dates: -## Usage with another UI +{{"demo": "behavior-autocomplete/MaterialDatePicker.js", "defaultCodeOpen": false}} -### Using an `Autocomplete` +### Using a masked Text Field -If your user can only select a value in a small list of available dates, -you can replace the field with an `Autocomplete` listing those dates: +If you want to use a simple mask approach for the field editing instead of the built-in logic, you can replace the default field with the [TextField](/material-ui/react-text-field/) component using a masked input value built with the [rifm](https://github.com/realadvisor/rifm) package. -{{"demo": "PickerWithAutocompleteField.js", "defaultCodeOpen": false}} +{{"demo": "behavior-masked-text-field/MaskedMaterialTextField.js", "defaultCodeOpen": false}} -### Using a read-only `TextField` +### Using a read-only Text Field If you want users to select a value exclusively through the views -but you still want the UI to look like a `TextField`, you can replace the field with a read-only `TextField`: +but you still want the UI to look like a Text Field, you can replace the field with a read-only [Text Field](/material-ui/react-text-field/) component: -{{"demo": "custom-behavior/ReadOnlyMaterialTextField.js", "defaultCodeOpen": false}} +{{"demo": "behavior-read-only-text-field/MaterialDatePicker.js", "defaultCodeOpen": false}} -### Using a `Button` +### Using a Button If you want users to select a value exclusively through the views -and you don't want the UI to look like a `TextField`, you can replace the field with a `Button`: +and you don't want the UI to look like a Text Field, you can replace the field with the [Button](/material-ui/react-button/) component: -{{"demo": "PickerWithButtonField.js", "defaultCodeOpen": false}} +{{"demo": "behavior-button/MaterialDatePicker.js", "defaultCodeOpen": false}} -The same can be applied to the `DateRangePicker`: +The same logic can be applied to any Range Picker: -{{"demo": "DateRangePickerWithButtonField.js", "defaultCodeOpen": false}} +{{"demo": "behavior-button/MaterialDateRangePicker.js", "defaultCodeOpen": false}} ## How to build a custom field @@ -184,22 +163,20 @@ On the examples below, you can see that the typing of the props received by a cu ```tsx interface JoyDateFieldProps - extends UseDateFieldProps, // The headless field props + extends UseDateFieldProps, // The headless field props BaseSingleInputFieldProps< Dayjs | null, - Dayjs, FieldSection, - false, // `true` for `enableAccessibleFieldDOMStructure` + true, // `false` for `enableAccessibleFieldDOMStructure={false}` DateValidationError > {} // The DOM field props interface JoyDateTimeFieldProps - extends UseDateTimeFieldProps, // The headless field props + extends UseDateTimeFieldProps, // The headless field props BaseSingleInputFieldProps< Dayjs | null, - Dayjs, FieldSection, - false, // `true` for `enableAccessibleFieldDOMStructure` + true, // `false` for `enableAccessibleFieldDOMStructure={false}` DateTimeValidationError > {} // The DOM field props ``` diff --git a/docs/data/date-pickers/custom-layout/AddComponent.tsx b/docs/data/date-pickers/custom-layout/AddComponent.tsx index a509a29f2175..2584a13756ed 100644 --- a/docs/data/date-pickers/custom-layout/AddComponent.tsx +++ b/docs/data/date-pickers/custom-layout/AddComponent.tsx @@ -58,7 +58,7 @@ function RestaurantHeader() { ); } -function CustomLayout(props: PickersLayoutProps) { +function CustomLayout(props: PickersLayoutProps) { const { toolbar, tabs, content, actionBar } = usePickerLayout(props); return ( diff --git a/docs/data/date-pickers/custom-layout/custom-layout.md b/docs/data/date-pickers/custom-layout/custom-layout.md index 421e80851236..ca327aaa57b6 100644 --- a/docs/data/date-pickers/custom-layout/custom-layout.md +++ b/docs/data/date-pickers/custom-layout/custom-layout.md @@ -8,10 +8,10 @@ packageName: '@mui/x-date-pickers' # Custom layout -

The Date and Time Pickers let you reorganize the layout

+

The Date and Time Pickers let you reorganize the layout.

:::success -See [Common concepts—Custom slots and subcomponents](/x/common-concepts/custom-components/) to learn how to use slots. +See [Common concepts—Slots and subcomponents](/x/common-concepts/custom-components/) to learn how to use slots. ::: ## Default layout structure diff --git a/docs/data/date-pickers/custom-opening-button/custom-opening-button.md b/docs/data/date-pickers/custom-opening-button/custom-opening-button.md index 2e71fe686d5b..21f4b44eeda5 100644 --- a/docs/data/date-pickers/custom-opening-button/custom-opening-button.md +++ b/docs/data/date-pickers/custom-opening-button/custom-opening-button.md @@ -8,7 +8,7 @@ title: Date and Time Pickers - Custom opening button

The date picker lets you customize the button to open the views.

:::success -See [Common concepts—Custom slots and subcomponents](/x/common-concepts/custom-components/) to learn how to use slots. +See [Common concepts—Slots and subcomponents](/x/common-concepts/custom-components/) to learn how to use slots. ::: ## Set a custom opening icon diff --git a/docs/data/date-pickers/date-calendar/DateCalendarServerRequest.tsx b/docs/data/date-pickers/date-calendar/DateCalendarServerRequest.tsx index 99acbc802a79..8064aa7b44a8 100644 --- a/docs/data/date-pickers/date-calendar/DateCalendarServerRequest.tsx +++ b/docs/data/date-pickers/date-calendar/DateCalendarServerRequest.tsx @@ -33,7 +33,7 @@ function fakeFetch(date: Dayjs, { signal }: { signal: AbortSignal }) { const initialValue = dayjs('2022-04-17'); -function ServerDay(props: PickersDayProps & { highlightedDays?: number[] }) { +function ServerDay(props: PickersDayProps & { highlightedDays?: number[] }) { const { highlightedDays = [], day, outsideCurrentMonth, ...other } = props; const isSelected = diff --git a/docs/data/date-pickers/date-calendar/WeekPicker.tsx b/docs/data/date-pickers/date-calendar/WeekPicker.tsx index 7e46c36ba876..fd987bd9c82c 100644 --- a/docs/data/date-pickers/date-calendar/WeekPicker.tsx +++ b/docs/data/date-pickers/date-calendar/WeekPicker.tsx @@ -9,7 +9,7 @@ import { PickersDay, PickersDayProps } from '@mui/x-date-pickers/PickersDay'; dayjs.extend(isBetweenPlugin); -interface CustomPickerDayProps extends PickersDayProps { +interface CustomPickerDayProps extends PickersDayProps { isSelected: boolean; isHovered: boolean; } @@ -56,7 +56,7 @@ const isInSameWeek = (dayA: Dayjs, dayB: Dayjs | null | undefined) => { }; function Day( - props: PickersDayProps & { + props: PickersDayProps & { selectedDay?: Dayjs | null; hoveredDay?: Dayjs | null; }, diff --git a/docs/data/date-pickers/date-picker/examplesConfig.styling.tsx b/docs/data/date-pickers/date-picker/examplesConfig.styling.tsx index e5ade00e61d4..11158f2a9c50 100644 --- a/docs/data/date-pickers/date-picker/examplesConfig.styling.tsx +++ b/docs/data/date-pickers/date-picker/examplesConfig.styling.tsx @@ -10,7 +10,7 @@ import { DesktopDatePickerProps, } from '@mui/x-date-pickers/DesktopDatePicker'; import { DatePickerProps } from '@mui/x-date-pickers/DatePicker'; -import dayjs, { Dayjs } from 'dayjs'; +import dayjs from 'dayjs'; import { PickersSubcomponentType } from 'docsx/src/modules/utils/useCustomizationPlayground'; type PickerExamplesType = { @@ -291,7 +291,7 @@ export const datePickerExamples: PickersSubcomponentType = { }, }; -const pickerProps: DatePickerProps = { +const pickerProps: DatePickerProps = { views: ['day', 'month', 'year'], monthsPerRow: 3, yearsPerRow: 3, @@ -306,7 +306,7 @@ export const pickerExamples = [ component: StaticDatePicker, componentProps: { ...pickerProps, orientation: 'portrait' }, examples: staticDatePickerExamples, - } as PickerExamplesType>, + } as PickerExamplesType, { name: 'DesktopDatePicker', component: DesktopDatePicker, @@ -331,5 +331,5 @@ export const pickerExamples = [ ...pickerProps, }, examples: datePickerExamples, - } as PickerExamplesType>, + } as PickerExamplesType, ]; diff --git a/docs/data/date-pickers/date-range-calendar/CustomDateRangePickerDay.js b/docs/data/date-pickers/date-range-calendar/CustomDateRangePickerDay.js index 6f1dbf791830..7d61206f6173 100644 --- a/docs/data/date-pickers/date-range-calendar/CustomDateRangePickerDay.js +++ b/docs/data/date-pickers/date-range-calendar/CustomDateRangePickerDay.js @@ -37,6 +37,7 @@ const DateRangePickerDay = styled(MuiDateRangePickerDay)(({ theme }) => ({ }, ], })); + export default function CustomDateRangePickerDay() { return ( diff --git a/docs/data/date-pickers/date-range-calendar/CustomDateRangePickerDay.tsx b/docs/data/date-pickers/date-range-calendar/CustomDateRangePickerDay.tsx index caf9d98b2c8f..2734106cb610 100644 --- a/docs/data/date-pickers/date-range-calendar/CustomDateRangePickerDay.tsx +++ b/docs/data/date-pickers/date-range-calendar/CustomDateRangePickerDay.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; -import dayjs, { Dayjs } from 'dayjs'; +import dayjs from 'dayjs'; import { styled } from '@mui/material/styles'; import { LocalizationProvider } from '@mui/x-date-pickers-pro/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers-pro/AdapterDayjs'; @@ -39,7 +39,8 @@ const DateRangePickerDay = styled(MuiDateRangePickerDay)(({ theme }) => ({ }, }, ], -})) as React.ComponentType>; +})) as React.ComponentType; + export default function CustomDateRangePickerDay() { return ( diff --git a/docs/data/date-pickers/date-range-field/DateRangeFieldValue.js b/docs/data/date-pickers/date-range-field/DateRangeFieldValue.js index 447469e63d63..7b8a8ff02cf1 100644 --- a/docs/data/date-pickers/date-range-field/DateRangeFieldValue.js +++ b/docs/data/date-pickers/date-range-field/DateRangeFieldValue.js @@ -2,7 +2,6 @@ import * as React from 'react'; import dayjs from 'dayjs'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; - import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { SingleInputDateRangeField } from '@mui/x-date-pickers-pro/SingleInputDateRangeField'; diff --git a/docs/data/date-pickers/date-range-field/DateRangeFieldValue.tsx b/docs/data/date-pickers/date-range-field/DateRangeFieldValue.tsx index 68feea759a44..bafc74db3e09 100644 --- a/docs/data/date-pickers/date-range-field/DateRangeFieldValue.tsx +++ b/docs/data/date-pickers/date-range-field/DateRangeFieldValue.tsx @@ -2,9 +2,9 @@ import * as React from 'react'; import dayjs, { Dayjs } from 'dayjs'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; -import { DateRange } from '@mui/x-date-pickers-pro/models'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { SingleInputDateRangeField } from '@mui/x-date-pickers-pro/SingleInputDateRangeField'; +import { DateRange } from '@mui/x-date-pickers-pro/models'; export default function DateRangeFieldValue() { const [value, setValue] = React.useState>(() => [ diff --git a/docs/data/date-pickers/digital-clock/DigitalClockSkipDisabled.js b/docs/data/date-pickers/digital-clock/DigitalClockSkipDisabled.js index 240a8f343ad8..9906d038dd16 100644 --- a/docs/data/date-pickers/digital-clock/DigitalClockSkipDisabled.js +++ b/docs/data/date-pickers/digital-clock/DigitalClockSkipDisabled.js @@ -6,13 +6,13 @@ import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { DigitalClock } from '@mui/x-date-pickers/DigitalClock'; import { MultiSectionDigitalClock } from '@mui/x-date-pickers/MultiSectionDigitalClock'; -const shouldDisableTime = (value, view) => { - const hour = value.hour(); +const shouldDisableTime = (date, view) => { + const hour = date.hour(); if (view === 'hours') { return hour < 9 || hour > 13; } if (view === 'minutes') { - const minute = value.minute(); + const minute = date.minute(); return minute > 20 && hour === 13; } return false; diff --git a/docs/data/date-pickers/digital-clock/DigitalClockSkipDisabled.tsx b/docs/data/date-pickers/digital-clock/DigitalClockSkipDisabled.tsx index cd8c8127fc04..bd54ab9775cc 100644 --- a/docs/data/date-pickers/digital-clock/DigitalClockSkipDisabled.tsx +++ b/docs/data/date-pickers/digital-clock/DigitalClockSkipDisabled.tsx @@ -7,13 +7,13 @@ import { DigitalClock } from '@mui/x-date-pickers/DigitalClock'; import { MultiSectionDigitalClock } from '@mui/x-date-pickers/MultiSectionDigitalClock'; import { TimeView } from '@mui/x-date-pickers/models'; -const shouldDisableTime = (value: Dayjs, view: TimeView) => { - const hour = value.hour(); +const shouldDisableTime = (date: Dayjs, view: TimeView) => { + const hour = date.hour(); if (view === 'hours') { return hour < 9 || hour > 13; } if (view === 'minutes') { - const minute = value.minute(); + const minute = date.minute(); return minute > 20 && hour === 13; } return false; diff --git a/docs/data/date-pickers/experimentation/experimentation.md b/docs/data/date-pickers/experimentation/experimentation.md index 88b3ea3fe5ad..ddecd52bb1e9 100644 --- a/docs/data/date-pickers/experimentation/experimentation.md +++ b/docs/data/date-pickers/experimentation/experimentation.md @@ -4,4 +4,4 @@ productId: x-date-pickers # Date and Time Pickers experimentation -

Demos not accessible through the navbar of the doc

+

Demos not accessible through the navbar of the doc.

diff --git a/docs/data/date-pickers/fields/BasicV7DOMStructure.js b/docs/data/date-pickers/fields/BasicV7DOMStructure.js index 1f32eca967da..62c0924c3c90 100644 --- a/docs/data/date-pickers/fields/BasicV7DOMStructure.js +++ b/docs/data/date-pickers/fields/BasicV7DOMStructure.js @@ -8,7 +8,7 @@ export default function BasicV7DOMStructure() { return ( - + ); diff --git a/docs/data/date-pickers/fields/BasicV7DOMStructure.tsx b/docs/data/date-pickers/fields/BasicV7DOMStructure.tsx index 1f32eca967da..62c0924c3c90 100644 --- a/docs/data/date-pickers/fields/BasicV7DOMStructure.tsx +++ b/docs/data/date-pickers/fields/BasicV7DOMStructure.tsx @@ -8,7 +8,7 @@ export default function BasicV7DOMStructure() { return ( - + ); diff --git a/docs/data/date-pickers/fields/BasicV7DOMStructure.tsx.preview b/docs/data/date-pickers/fields/BasicV7DOMStructure.tsx.preview index f33bc6c8fdc7..2dc079345c09 100644 --- a/docs/data/date-pickers/fields/BasicV7DOMStructure.tsx.preview +++ b/docs/data/date-pickers/fields/BasicV7DOMStructure.tsx.preview @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/docs/data/date-pickers/fields/fields.md b/docs/data/date-pickers/fields/fields.md index 5f54b1411f66..9bd7260fff46 100644 --- a/docs/data/date-pickers/fields/fields.md +++ b/docs/data/date-pickers/fields/fields.md @@ -25,201 +25,6 @@ All fields to edit a range are available in a single input version and in a mult {{"demo": "DateRangeFieldExamples.js", "defaultCodeOpen": false}} -## Accessible DOM structure - -By default, the fields' DOM structure consists of an ``, which holds the whole value for the component, but unfortunately presents a few limitations in terms of accessibility when managing multiple section values. - -From v7 version, you can opt-in for a new and experimental DOM structure on any field or picker component using the `enableAccessibleFieldDOMStructure` prop. - -```tsx - - - -``` - -This new feature allows the field component to set aria attributes on individual sections, providing a far better experience with screen readers. - -{{"demo": "BasicV7DOMStructure.js", "defaultCodeOpen": false }} - -### Usage with `slotProps.field` - -When using `slotProps.field` to pass props to your field component, -the field consumes some props (e.g: `shouldRespectLeadingZeros`) and forwards the rest to the `TextField`. - -- For the props consumed by the field, the behavior should remain exactly the same with both DOM structures. - - Both components below will respect the leading zeroes on digit sections: - - ```js - - - ``` - -- For the props forwarded to the `TextField`, - you can have a look at the next section to see how the migration impact them. - - Both components below will render a small size UI: - - ```js - - - ``` - -### Usage with `slotProps.textField` - -If you are passing props to `slotProps.textField`, -these props will now be received by `PickersTextField` and should keep working the same way as before. - -Both components below will render a small size UI: - -```js - - -``` - -:::info -If you are passing `inputProps` to `slotProps.textField`, -these props will now be passed to the hidden `` element. -::: - -### Usage with `slots.field` - -If you are passing a custom field component to your pickers, you need to create a new one that is using the accessible DOM structure. -This new component will need to use the `PickersSectionList` component instead of an `` HTML element. - -You can have a look at the [custom PickersTextField](/x/react-date-pickers/custom-field/#using-custom-pickerstextfield) to have a concrete example. - -:::info -If your custom field was used to create a Joy UI design component, -you may want to wait a few weeks for the release of an out-of-the-box Joy `PickersTextField` component instead of implementing it yourself. -::: - -### Usage with `slots.textField` - -If you are passing a custom `TextField` component to your fields and pickers, -you need to create a new one that is using the accessible DOM structure. - -You can have a look at the second demo of the [Material PickersTextField section](/x/react-date-pickers/custom-field/#using-material-pickerstextfield) to have a concrete example. - -:::info -If your custom `TextField` was used to apply a totally different input that did not use `@mui/material/TextField`, -please consider having a look at the [custom PickersTextField](/x/react-date-pickers/custom-field/#using-custom-pickerstextfield) section which uses `slots.field`. -This approach can be more appropriate for deeper changes. -::: - -### Usage with theme - -If you are using the theme to customize `MuiTextField`, -you need to pass the same config to `MuiPickersTextField`: - -```js -const theme = createTheme({ - components: { - MuiTextField: { - defaultProps: { - variant: 'outlined', - }, - styleOverrides: { - root: { - '& .MuiInputLabel-outlined.Mui-focused': { - color: 'red', - }, - }, - }, - }, - MuiPickersTextField: { - defaultProps: { - variant: 'outlined', - }, - styleOverrides: { - root: { - '& .MuiInputLabel-outlined.Mui-focused': { - color: 'red', - }, - }, - }, - }, - }, -}); -``` - -If you are using the theme to customize `MuiInput`, `MuiOutlinedInput` or `MuiFilledInput`, -you need to pass the same config to `MuiPickersInput`, `MuiPickersOutlinedInput` or `MuiPickersFilledInput`: - -```js -const theme = createTheme({ - components: { - // Replace with `MuiOutlinedInput` or `MuiFilledInput` if needed - MuiInput: { - defaultProps: { - margin: 'dense', - }, - styleOverrides: { - root: { - color: 'red', - }, - }, - }, - // Replace with `MuiPickersOutlinedInput` or `MuiPickersFilledInput` if needed - MuiPickersInput: { - defaultProps: { - margin: 'dense', - }, - styleOverrides: { - root: { - color: 'red', - }, - }, - }, - }, -}); -``` - -If you are using the theme to customize `MuiInputBase`, -you need to pass the same config to `MuiPickersInputBase`: - -```js -const theme = createTheme({ - components: { - MuiInputBase: { - defaultProps: { - margin: 'dense', - }, - styleOverrides: { - root: { - color: 'red', - }, - }, - }, - MuiPickersInputBase: { - defaultProps: { - margin: 'dense', - }, - styleOverrides: { - root: { - color: 'red', - }, - }, - }, - }, -}); -``` - ## Advanced ### What is a section? diff --git a/docs/data/date-pickers/lifecycle/ServerInteraction.tsx b/docs/data/date-pickers/lifecycle/ServerInteraction.tsx index c265b005dd90..231e0dbeaa06 100644 --- a/docs/data/date-pickers/lifecycle/ServerInteraction.tsx +++ b/docs/data/date-pickers/lifecycle/ServerInteraction.tsx @@ -57,7 +57,7 @@ function debounce(func: (...arg: any) => void, wait = 500) { } function DateFieldWithAccept( - props: DateFieldProps & { onAccept: (value: Dayjs | null) => void }, + props: DateFieldProps & { onAccept: (value: Dayjs | null) => void }, ) { const { value: valueProp, onAccept, onChange, ...other } = props; diff --git a/docs/data/date-pickers/localization/data.json b/docs/data/date-pickers/localization/data.json index 75901bdcb30c..14a69bf378d6 100644 --- a/docs/data/date-pickers/localization/data.json +++ b/docs/data/date-pickers/localization/data.json @@ -5,7 +5,7 @@ "localeName": "Basque", "missingKeysCount": 13, "totalKeysCount": 50, - "githubLink": "https://github.com/mui/mui-x/blob/v7.x/packages/x-date-pickers/src/locales/eu.ts" + "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/eu.ts" }, { "languageTag": "be-BY", @@ -13,7 +13,7 @@ "localeName": "Belarusian", "missingKeysCount": 15, "totalKeysCount": 50, - "githubLink": "https://github.com/mui/mui-x/blob/v7.x/packages/x-date-pickers/src/locales/beBY.ts" + "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/beBY.ts" }, { "languageTag": "bg-BG", @@ -21,7 +21,7 @@ "localeName": "Bulgarian", "missingKeysCount": 0, "totalKeysCount": 50, - "githubLink": "https://github.com/mui/mui-x/blob/v7.x/packages/x-date-pickers/src/locales/bgBG.ts" + "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/bgBG.ts" }, { "languageTag": "ca-ES", @@ -29,7 +29,7 @@ "localeName": "Catalan", "missingKeysCount": 0, "totalKeysCount": 50, - "githubLink": "https://github.com/mui/mui-x/blob/v7.x/packages/x-date-pickers/src/locales/caES.ts" + "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/caES.ts" }, { "languageTag": "zh-HK", @@ -37,7 +37,7 @@ "localeName": "Chinese (Hong Kong)", "missingKeysCount": 0, "totalKeysCount": 50, - "githubLink": "https://github.com/mui/mui-x/blob/v7.x/packages/x-date-pickers/src/locales/zhHK.ts" + "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/zhHK.ts" }, { "languageTag": "zh-CN", @@ -45,7 +45,7 @@ "localeName": "Chinese (Simplified)", "missingKeysCount": 0, "totalKeysCount": 50, - "githubLink": "https://github.com/mui/mui-x/blob/v7.x/packages/x-date-pickers/src/locales/zhCN.ts" + "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/zhCN.ts" }, { "languageTag": "hr-HR", @@ -53,7 +53,7 @@ "localeName": "Croatian", "missingKeysCount": 0, "totalKeysCount": 50, - "githubLink": "https://github.com/mui/mui-x/blob/v7.x/packages/x-date-pickers/src/locales/hrHR.ts" + "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/hrHR.ts" }, { "languageTag": "cs-CZ", @@ -61,7 +61,7 @@ "localeName": "Czech", "missingKeysCount": 0, "totalKeysCount": 50, - "githubLink": "https://github.com/mui/mui-x/blob/v7.x/packages/x-date-pickers/src/locales/csCZ.ts" + "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/csCZ.ts" }, { "languageTag": "da-DK", @@ -69,7 +69,7 @@ "localeName": "Danish", "missingKeysCount": 0, "totalKeysCount": 50, - "githubLink": "https://github.com/mui/mui-x/blob/v7.x/packages/x-date-pickers/src/locales/daDK.ts" + "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/daDK.ts" }, { "languageTag": "nl-NL", @@ -77,7 +77,7 @@ "localeName": "Dutch", "missingKeysCount": 0, "totalKeysCount": 50, - "githubLink": "https://github.com/mui/mui-x/blob/v7.x/packages/x-date-pickers/src/locales/nlNL.ts" + "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/nlNL.ts" }, { "languageTag": "fi-FI", @@ -85,7 +85,7 @@ "localeName": "Finnish", "missingKeysCount": 0, "totalKeysCount": 50, - "githubLink": "https://github.com/mui/mui-x/blob/v7.x/packages/x-date-pickers/src/locales/fiFI.ts" + "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/fiFI.ts" }, { "languageTag": "fr-FR", @@ -93,7 +93,7 @@ "localeName": "French", "missingKeysCount": 0, "totalKeysCount": 50, - "githubLink": "https://github.com/mui/mui-x/blob/v7.x/packages/x-date-pickers/src/locales/frFR.ts" + "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/frFR.ts" }, { "languageTag": "de-DE", @@ -101,15 +101,15 @@ "localeName": "German", "missingKeysCount": 0, "totalKeysCount": 50, - "githubLink": "https://github.com/mui/mui-x/blob/v7.x/packages/x-date-pickers/src/locales/deDE.ts" + "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/deDE.ts" }, { "languageTag": "el-GR", "importName": "elGR", "localeName": "Greek", - "missingKeysCount": 14, + "missingKeysCount": 6, "totalKeysCount": 50, - "githubLink": "https://github.com/mui/mui-x/blob/v7.x/packages/x-date-pickers/src/locales/elGR.ts" + "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/elGR.ts" }, { "languageTag": "he-IL", @@ -117,7 +117,7 @@ "localeName": "Hebrew", "missingKeysCount": 0, "totalKeysCount": 50, - "githubLink": "https://github.com/mui/mui-x/blob/v7.x/packages/x-date-pickers/src/locales/heIL.ts" + "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/heIL.ts" }, { "languageTag": "hu-HU", @@ -125,7 +125,7 @@ "localeName": "Hungarian", "missingKeysCount": 0, "totalKeysCount": 50, - "githubLink": "https://github.com/mui/mui-x/blob/v7.x/packages/x-date-pickers/src/locales/huHU.ts" + "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/huHU.ts" }, { "languageTag": "is-IS", @@ -133,7 +133,7 @@ "localeName": "Icelandic", "missingKeysCount": 14, "totalKeysCount": 50, - "githubLink": "https://github.com/mui/mui-x/blob/v7.x/packages/x-date-pickers/src/locales/isIS.ts" + "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/isIS.ts" }, { "languageTag": "it-IT", @@ -141,7 +141,7 @@ "localeName": "Italian", "missingKeysCount": 0, "totalKeysCount": 50, - "githubLink": "https://github.com/mui/mui-x/blob/v7.x/packages/x-date-pickers/src/locales/itIT.ts" + "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/itIT.ts" }, { "languageTag": "ja-JP", @@ -149,7 +149,7 @@ "localeName": "Japanese", "missingKeysCount": 0, "totalKeysCount": 50, - "githubLink": "https://github.com/mui/mui-x/blob/v7.x/packages/x-date-pickers/src/locales/jaJP.ts" + "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/jaJP.ts" }, { "languageTag": "kz-KZ", @@ -157,7 +157,7 @@ "localeName": "Kazakh", "missingKeysCount": 15, "totalKeysCount": 50, - "githubLink": "https://github.com/mui/mui-x/blob/v7.x/packages/x-date-pickers/src/locales/kzKZ.ts" + "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/kzKZ.ts" }, { "languageTag": "ko-KR", @@ -165,7 +165,7 @@ "localeName": "Korean", "missingKeysCount": 1, "totalKeysCount": 50, - "githubLink": "https://github.com/mui/mui-x/blob/v7.x/packages/x-date-pickers/src/locales/koKR.ts" + "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/koKR.ts" }, { "languageTag": "mk", @@ -173,7 +173,7 @@ "localeName": "Macedonian", "missingKeysCount": 13, "totalKeysCount": 50, - "githubLink": "https://github.com/mui/mui-x/blob/v7.x/packages/x-date-pickers/src/locales/mk.ts" + "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/mk.ts" }, { "languageTag": "nb-NO", @@ -181,7 +181,7 @@ "localeName": "Norwegian (Bokmål)", "missingKeysCount": 14, "totalKeysCount": 50, - "githubLink": "https://github.com/mui/mui-x/blob/v7.x/packages/x-date-pickers/src/locales/nbNO.ts" + "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/nbNO.ts" }, { "languageTag": "nn-NO", @@ -189,7 +189,7 @@ "localeName": "Norwegian (Nynorsk)", "missingKeysCount": 0, "totalKeysCount": 50, - "githubLink": "https://github.com/mui/mui-x/blob/v7.x/packages/x-date-pickers/src/locales/nnNO.ts" + "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/nnNO.ts" }, { "languageTag": "fa-IR", @@ -197,7 +197,7 @@ "localeName": "Persian", "missingKeysCount": 0, "totalKeysCount": 50, - "githubLink": "https://github.com/mui/mui-x/blob/v7.x/packages/x-date-pickers/src/locales/faIR.ts" + "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/faIR.ts" }, { "languageTag": "pl-PL", @@ -205,7 +205,7 @@ "localeName": "Polish", "missingKeysCount": 10, "totalKeysCount": 50, - "githubLink": "https://github.com/mui/mui-x/blob/v7.x/packages/x-date-pickers/src/locales/plPL.ts" + "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/plPL.ts" }, { "languageTag": "pt-PT", @@ -213,7 +213,7 @@ "localeName": "Portuguese", "missingKeysCount": 0, "totalKeysCount": 50, - "githubLink": "https://github.com/mui/mui-x/blob/v7.x/packages/x-date-pickers/src/locales/ptPT.ts" + "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/ptPT.ts" }, { "languageTag": "pt-BR", @@ -221,7 +221,7 @@ "localeName": "Portuguese (Brazil)", "missingKeysCount": 0, "totalKeysCount": 50, - "githubLink": "https://github.com/mui/mui-x/blob/v7.x/packages/x-date-pickers/src/locales/ptBR.ts" + "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/ptBR.ts" }, { "languageTag": "ro-RO", @@ -229,7 +229,7 @@ "localeName": "Romanian", "missingKeysCount": 14, "totalKeysCount": 50, - "githubLink": "https://github.com/mui/mui-x/blob/v7.x/packages/x-date-pickers/src/locales/roRO.ts" + "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/roRO.ts" }, { "languageTag": "ru-RU", @@ -237,7 +237,7 @@ "localeName": "Russian", "missingKeysCount": 0, "totalKeysCount": 50, - "githubLink": "https://github.com/mui/mui-x/blob/v7.x/packages/x-date-pickers/src/locales/ruRU.ts" + "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/ruRU.ts" }, { "languageTag": "sk-SK", @@ -245,7 +245,7 @@ "localeName": "Slovak", "missingKeysCount": 15, "totalKeysCount": 50, - "githubLink": "https://github.com/mui/mui-x/blob/v7.x/packages/x-date-pickers/src/locales/skSK.ts" + "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/skSK.ts" }, { "languageTag": "es-ES", @@ -253,7 +253,7 @@ "localeName": "Spanish", "missingKeysCount": 0, "totalKeysCount": 50, - "githubLink": "https://github.com/mui/mui-x/blob/v7.x/packages/x-date-pickers/src/locales/esES.ts" + "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/esES.ts" }, { "languageTag": "sv-SE", @@ -261,7 +261,7 @@ "localeName": "Swedish", "missingKeysCount": 0, "totalKeysCount": 50, - "githubLink": "https://github.com/mui/mui-x/blob/v7.x/packages/x-date-pickers/src/locales/svSE.ts" + "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/svSE.ts" }, { "languageTag": "tr-TR", @@ -269,7 +269,7 @@ "localeName": "Turkish", "missingKeysCount": 14, "totalKeysCount": 50, - "githubLink": "https://github.com/mui/mui-x/blob/v7.x/packages/x-date-pickers/src/locales/trTR.ts" + "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/trTR.ts" }, { "languageTag": "uk-UA", @@ -277,7 +277,7 @@ "localeName": "Ukrainian", "missingKeysCount": 0, "totalKeysCount": 50, - "githubLink": "https://github.com/mui/mui-x/blob/v7.x/packages/x-date-pickers/src/locales/ukUA.ts" + "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/ukUA.ts" }, { "languageTag": "ur-PK", @@ -285,7 +285,7 @@ "localeName": "Urdu (Pakistan)", "missingKeysCount": 22, "totalKeysCount": 50, - "githubLink": "https://github.com/mui/mui-x/blob/v7.x/packages/x-date-pickers/src/locales/urPK.ts" + "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/urPK.ts" }, { "languageTag": "vi-VN", @@ -293,6 +293,6 @@ "localeName": "Vietnamese", "missingKeysCount": 0, "totalKeysCount": 50, - "githubLink": "https://github.com/mui/mui-x/blob/v7.x/packages/x-date-pickers/src/locales/viVN.ts" + "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/viVN.ts" } ] diff --git a/docs/data/date-pickers/localization/localization.md b/docs/data/date-pickers/localization/localization.md index 9c17517d832a..dab97f4bcb5d 100644 --- a/docs/data/date-pickers/localization/localization.md +++ b/docs/data/date-pickers/localization/localization.md @@ -46,7 +46,7 @@ function App({ children }) { } ``` -Note that `createTheme` accepts any number of arguments. +Note that `createTheme()` accepts any number of arguments. If you are already using the [translations of the core components](/material-ui/guides/localization/#locale-text) or the [translations of the Data Grid](/x/react-data-grid/localization/#locale-text), you can add `deDE` as a new argument. ```jsx @@ -73,7 +73,7 @@ function App({ children }) { ### Using LocalizationProvider -If you want to pass language translations without using `createTheme` and `ThemeProvider`, +If you want to pass language translations without using `createTheme()` and `ThemeProvider`, you can directly load the language translations from the `@mui/x-date-pickers` or `@mui/x-date-pickers-pro` package and pass them to the `LocalizationProvider`. ```jsx diff --git a/docs/data/date-pickers/timezone/LuxonTimezone.tsx b/docs/data/date-pickers/timezone/LuxonTimezone.tsx index d0f95909ebb9..a80ccfbc26f8 100644 --- a/docs/data/date-pickers/timezone/LuxonTimezone.tsx +++ b/docs/data/date-pickers/timezone/LuxonTimezone.tsx @@ -7,7 +7,7 @@ import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker'; export default function LuxonTimezone() { - const [value, setValue] = React.useState | DateTime | null>( + const [value, setValue] = React.useState( DateTime.fromISO('2022-04-17T15:30', { zone: 'America/New_York' }), ); diff --git a/docs/data/date-pickers/timezone/LuxonUTC.tsx b/docs/data/date-pickers/timezone/LuxonUTC.tsx index 8948b050208a..fad298a38155 100644 --- a/docs/data/date-pickers/timezone/LuxonUTC.tsx +++ b/docs/data/date-pickers/timezone/LuxonUTC.tsx @@ -7,7 +7,7 @@ import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker'; export default function LuxonUTC() { - const [value, setValue] = React.useState | DateTime | null>( + const [value, setValue] = React.useState( DateTime.fromISO('2022-04-17T15:30', { zone: 'UTC' }), ); diff --git a/docs/data/date-pickers/validation/TimeValidationShouldDisableTime.tsx b/docs/data/date-pickers/validation/TimeValidationShouldDisableTime.tsx index 2af87819746b..ce9497c0c85e 100644 --- a/docs/data/date-pickers/validation/TimeValidationShouldDisableTime.tsx +++ b/docs/data/date-pickers/validation/TimeValidationShouldDisableTime.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import dayjs, { Dayjs } from 'dayjs'; +import dayjs from 'dayjs'; import { DemoContainer, DemoItem } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; @@ -7,10 +7,8 @@ import { TimePicker, TimePickerProps } from '@mui/x-date-pickers/TimePicker'; import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker'; import { DateTimeRangePicker } from '@mui/x-date-pickers-pro/DateTimeRangePicker'; -const shouldDisableTime: TimePickerProps['shouldDisableTime'] = ( - value, - view, -) => view === 'minutes' && value.minute() >= 45; +const shouldDisableTime: TimePickerProps['shouldDisableTime'] = (value, view) => + view === 'minutes' && value.minute() >= 45; const defaultValue = dayjs().set('hour', 10).set('minute', 50).startOf('minute'); diff --git a/docs/data/datePickersApiPages.ts b/docs/data/datePickersApiPages.ts new file mode 100644 index 000000000000..339472cbea73 --- /dev/null +++ b/docs/data/datePickersApiPages.ts @@ -0,0 +1,236 @@ +import type { MuiPage } from 'docs/src/MuiPage'; + +const datePickersApiPages: MuiPage[] = [ + { + pathname: '/x/api/date-pickers/date-calendar', + title: 'DateCalendar', + }, + { + pathname: '/x/api/date-pickers/date-field', + title: 'DateField', + }, + { + pathname: '/x/api/date-pickers/date-picker', + title: 'DatePicker', + }, + { + pathname: '/x/api/date-pickers/date-picker-toolbar', + title: 'DatePickerToolbar', + }, + { + pathname: '/x/api/date-pickers/date-range-calendar', + title: 'DateRangeCalendar', + plan: 'pro', + }, + { + pathname: '/x/api/date-pickers/date-range-picker', + title: 'DateRangePicker', + plan: 'pro', + }, + { + pathname: '/x/api/date-pickers/date-range-picker-day', + title: 'DateRangePickerDay', + plan: 'pro', + }, + { + pathname: '/x/api/date-pickers/date-range-picker-toolbar', + title: 'DateRangePickerToolbar', + plan: 'pro', + }, + { + pathname: '/x/api/date-pickers/date-time-field', + title: 'DateTimeField', + }, + { + pathname: '/x/api/date-pickers/date-time-picker', + title: 'DateTimePicker', + }, + { + pathname: '/x/api/date-pickers/date-time-picker-tabs', + title: 'DateTimePickerTabs', + }, + { + pathname: '/x/api/date-pickers/date-time-picker-toolbar', + title: 'DateTimePickerToolbar', + }, + { + pathname: '/x/api/date-pickers/date-time-range-picker', + title: 'DateTimeRangePicker', + plan: 'pro', + }, + { + pathname: '/x/api/date-pickers/date-time-range-picker-tabs', + title: 'DateTimeRangePickerTabs', + plan: 'pro', + }, + { + pathname: '/x/api/date-pickers/date-time-range-picker-toolbar', + title: 'DateTimeRangePickerToolbar', + plan: 'pro', + }, + { + pathname: '/x/api/date-pickers/day-calendar-skeleton', + title: 'DayCalendarSkeleton', + }, + { + pathname: '/x/api/date-pickers/desktop-date-picker', + title: 'DesktopDatePicker', + }, + { + pathname: '/x/api/date-pickers/desktop-date-range-picker', + title: 'DesktopDateRangePicker', + plan: 'pro', + }, + { + pathname: '/x/api/date-pickers/desktop-date-time-picker', + title: 'DesktopDateTimePicker', + }, + { + pathname: '/x/api/date-pickers/desktop-date-time-range-picker', + title: 'DesktopDateTimeRangePicker', + plan: 'pro', + }, + { + pathname: '/x/api/date-pickers/desktop-time-picker', + title: 'DesktopTimePicker', + }, + { + pathname: '/x/api/date-pickers/digital-clock', + title: 'DigitalClock', + }, + { + pathname: '/x/api/date-pickers/localization-provider', + title: 'LocalizationProvider', + }, + { + pathname: '/x/api/date-pickers/mobile-date-picker', + title: 'MobileDatePicker', + }, + { + pathname: '/x/api/date-pickers/mobile-date-range-picker', + title: 'MobileDateRangePicker', + plan: 'pro', + }, + { + pathname: '/x/api/date-pickers/mobile-date-time-picker', + title: 'MobileDateTimePicker', + }, + { + pathname: '/x/api/date-pickers/mobile-date-time-range-picker', + title: 'MobileDateTimeRangePicker', + plan: 'pro', + }, + { + pathname: '/x/api/date-pickers/mobile-time-picker', + title: 'MobileTimePicker', + }, + { + pathname: '/x/api/date-pickers/month-calendar', + title: 'MonthCalendar', + }, + { + pathname: '/x/api/date-pickers/multi-input-date-range-field', + title: 'MultiInputDateRangeField', + plan: 'pro', + }, + { + pathname: '/x/api/date-pickers/multi-input-date-time-range-field', + title: 'MultiInputDateTimeRangeField', + plan: 'pro', + }, + { + pathname: '/x/api/date-pickers/multi-input-time-range-field', + title: 'MultiInputTimeRangeField', + plan: 'pro', + }, + { + pathname: '/x/api/date-pickers/multi-section-digital-clock', + title: 'MultiSectionDigitalClock', + }, + { + pathname: '/x/api/date-pickers/pickers-action-bar', + title: 'PickersActionBar', + }, + { + pathname: '/x/api/date-pickers/pickers-calendar-header', + title: 'PickersCalendarHeader', + }, + { + pathname: '/x/api/date-pickers/pickers-day', + title: 'PickersDay', + }, + { + pathname: '/x/api/date-pickers/pickers-layout', + title: 'PickersLayout', + }, + { + pathname: '/x/api/date-pickers/pickers-range-calendar-header', + title: 'PickersRangeCalendarHeader', + plan: 'pro', + }, + { + pathname: '/x/api/date-pickers/pickers-section-list', + title: 'PickersSectionList', + }, + { + pathname: '/x/api/date-pickers/pickers-shortcuts', + title: 'PickersShortcuts', + }, + { + pathname: '/x/api/date-pickers/pickers-text-field', + title: 'PickersTextField', + }, + { + pathname: '/x/api/date-pickers/single-input-date-range-field', + title: 'SingleInputDateRangeField', + plan: 'pro', + }, + { + pathname: '/x/api/date-pickers/single-input-date-time-range-field', + title: 'SingleInputDateTimeRangeField', + plan: 'pro', + }, + { + pathname: '/x/api/date-pickers/single-input-time-range-field', + title: 'SingleInputTimeRangeField', + plan: 'pro', + }, + { + pathname: '/x/api/date-pickers/static-date-picker', + title: 'StaticDatePicker', + }, + { + pathname: '/x/api/date-pickers/static-date-range-picker', + title: 'StaticDateRangePicker', + plan: 'pro', + }, + { + pathname: '/x/api/date-pickers/static-date-time-picker', + title: 'StaticDateTimePicker', + }, + { + pathname: '/x/api/date-pickers/static-time-picker', + title: 'StaticTimePicker', + }, + { + pathname: '/x/api/date-pickers/time-clock', + title: 'TimeClock', + }, + { + pathname: '/x/api/date-pickers/time-field', + title: 'TimeField', + }, + { + pathname: '/x/api/date-pickers/time-picker', + title: 'TimePicker', + }, + { + pathname: '/x/api/date-pickers/time-picker-toolbar', + title: 'TimePickerToolbar', + }, + { + pathname: '/x/api/date-pickers/year-calendar', + title: 'YearCalendar', + }, +]; +export default datePickersApiPages; diff --git a/docs/data/introduction/support/support.md b/docs/data/introduction/support/support.md index f9284b6e78d7..ebba1a99214b 100644 --- a/docs/data/introduction/support/support.md +++ b/docs/data/introduction/support/support.md @@ -42,7 +42,7 @@ You can browse the documentation, find an example close to your use case, and th - [Data Grid](/x/react-data-grid/#mit-license-free-forever) - [Date Pickers](/x/react-date-pickers/getting-started/#render-your-first-component) -- [Charts](/x/react-charts/getting-started/#single-charts) +- [Charts](/x/react-charts/getting-started/#self-contained-charts) - [Tree View](/x/react-tree-view/#simple-tree-view) #### Use starter templates @@ -51,7 +51,7 @@ You can use a starter template to build a reproduction case with: -- A minimal Data Grid [TypeScript template](https://stackblitz.com/github/mui/mui-x/tree/v7.x/bug-reproductions/x-data-grid?file=src/index.tsx) +- A minimal Data Grid [TypeScript template](https://stackblitz.com/github/mui/mui-x/tree/master/bug-reproductions/x-data-grid?file=src/index.tsx) - A plain React [JavaScript](https://stackblitz.com/github/stackblitz/starters/tree/main/react) or [TypeScript](https://stackblitz.com/github/stackblitz/starters/tree/main/react-ts) template ## Stack Overflow diff --git a/docs/data/migration/migration-charts-v7/migration-charts-v7.md b/docs/data/migration/migration-charts-v7/migration-charts-v7.md new file mode 100644 index 000000000000..a23f9406feff --- /dev/null +++ b/docs/data/migration/migration-charts-v7/migration-charts-v7.md @@ -0,0 +1,34 @@ +--- +productId: x-charts +--- + +# Migration from v7 to v8 + +

This guide describes the changes needed to migrate Charts from v7 to v8.

+ +## Introduction + +This is a reference guide for upgrading `@mui/x-charts` from v7 to v8. +The change between v7 and v8 is mostly here to match the version with other MUI X packages. +No big breaking changes are expected. + +## Start using the new release + +In `package.json`, change the version of the charts package to `next`. + +```diff +-"@mui/x-charts": "^7.0.0", ++"@mui/x-charts": "next", +``` + +Using `next` ensures that it will always use the latest v8 pre-release version, but you can also use a fixed version, like `8.0.0-alpha.0`. + +## Breaking changes + +Since v8 is a major release, it contains some changes that affect the public API. +These changes were done for consistency, improve stability and make room for new features. +Below are described the steps you need to make to migrate from v7 to v8. + +:::info +The list is currently empty, but as we move forward with development during the alpha and beta phases, we'll feed this page with all changes in the API. +::: diff --git a/docs/data/migration/migration-data-grid-v7/migration-data-grid-v7.md b/docs/data/migration/migration-data-grid-v7/migration-data-grid-v7.md new file mode 100644 index 000000000000..eea548d0fbc0 --- /dev/null +++ b/docs/data/migration/migration-data-grid-v7/migration-data-grid-v7.md @@ -0,0 +1,78 @@ +--- +productId: x-data-grid +--- + +# Migration from v7 to v8 + +

This guide describes the changes needed to migrate the Data Grid from v7 to v8.

+ +## Introduction + +This is a reference guide for upgrading `@mui/x-data-grid` from v7 to v8. + +## Start using the new release + +In `package.json`, change the version of the Data Grid package to `next`. + +```diff +-"@mui/x-data-grid": "^7.0.0", ++"@mui/x-data-grid": "next", + +-"@mui/x-data-grid-pro": "^7.0.0", ++"@mui/x-data-grid-pro": "next", + +-"@mui/x-data-grid-premium": "^7.0.0", ++"@mui/x-data-grid-premium": "next", +``` + +Using `next` ensures that it will always use the latest v8 pre-release version, but you can also use a fixed version, like `8.0.0-alpha.0`. + +## Breaking changes + +Since v8 is a major release, it contains some changes that affect the public API. +These changes were done for consistency, improve stability and make room for new features. +Below are described the steps you need to make to migrate from v7 to v8. + +:::info +The list is currently empty, but as we move forward with development during the alpha and beta phases, we'll feed this page with all changes in the API. +::: + + diff --git a/docs/data/migration/migration-pickers-v5/MobileKeyboardView.tsx b/docs/data/migration/migration-pickers-v5/MobileKeyboardView.tsx index 08a963f789ba..97a25bbfc036 100644 --- a/docs/data/migration/migration-pickers-v5/MobileKeyboardView.tsx +++ b/docs/data/migration/migration-pickers-v5/MobileKeyboardView.tsx @@ -22,9 +22,7 @@ import { DatePickerToolbarProps, } from '@mui/x-date-pickers/DatePicker'; -function LayoutWithKeyboardView( - props: PickersLayoutProps, -) { +function LayoutWithKeyboardView(props: PickersLayoutProps) { const { value, onChange } = props; const [showKeyboardView, setShowKeyboardView] = React.useState(false); @@ -61,7 +59,7 @@ function LayoutWithKeyboardView( } function ToolbarWithKeyboardViewSwitch( - props: DatePickerToolbarProps & { + props: DatePickerToolbarProps & { showKeyboardViewSwitch?: boolean; showKeyboardView?: boolean; setShowKeyboardView?: React.Dispatch>; diff --git a/docs/data/migration/migration-pickers-v6/migration-pickers-v6.md b/docs/data/migration/migration-pickers-v6/migration-pickers-v6.md index 787bbefb3182..ab73ca9e1900 100644 --- a/docs/data/migration/migration-pickers-v6/migration-pickers-v6.md +++ b/docs/data/migration/migration-pickers-v6/migration-pickers-v6.md @@ -440,7 +440,7 @@ The headless field hooks (e.g.: `useDateField`) now return a new prop called `en This is used to know if the current UI expected is built using the accessible DOM structure or not. :::info -See [Fields—Accessible DOM structure](/x/react-date-pickers/fields/#accessible-dom-structure) for more details. +See [Migration from v7 to v8—New DOM structure for the field](/x/migration/migration-pickers-v7/#new-dom-structure-for-the-field) for more details. ::: When building a custom UI, you are most-likely only supporting one DOM structure, so you can remove `enableAccessibleFieldDOMStructure` before it is passed to the DOM: diff --git a/docs/data/migration/migration-pickers-v7/migration-pickers-v7.md b/docs/data/migration/migration-pickers-v7/migration-pickers-v7.md new file mode 100644 index 000000000000..a7c30b0a931b --- /dev/null +++ b/docs/data/migration/migration-pickers-v7/migration-pickers-v7.md @@ -0,0 +1,422 @@ +--- +productId: x-date-pickers +--- + +# Migration from v7 to v8 + +

This guide describes the changes needed to migrate the Date and Time Pickers from v7 to v8.

+ +## Introduction + +This is a reference guide for upgrading `@mui/x-date-pickers` from v7 to v8. + +## Start using the new release + +In `package.json`, change the version of the date pickers package to `next`. + +```diff +-"@mui/x-date-pickers": "7.x.x", ++"@mui/x-date-pickers": "next", +``` + +Using `next` ensures that it will always use the latest v8 pre-release version, but you can also use a fixed version, like `8.0.0-alpha.0`. + +Since `v8` is a major release, it contains changes that affect the public API. +These changes were done for consistency, improved stability and to make room for new features. +Described below are the steps needed to migrate from v7 to v8. + +## Run codemods + +The `preset-safe` codemod will automatically adjust the bulk of your code to account for breaking changes in v8. You can run `v8.0.0/pickers/preset-safe` targeting only Date and Time Pickers or `v8.0.0/preset-safe` to target the other packages as well. + +You can either run it on a specific file, folder, or your entire codebase when choosing the `` argument. + + + +```bash +// Date and Time Pickers specific +npx @mui/x-codemod@latest v8.0.0/pickers/preset-safe + +// Target the other packages as well +npx @mui/x-codemod@latest v8.0.0/preset-safe +``` + +:::info +If you want to run the transformers one by one, check out the transformers included in the [preset-safe codemod for pickers](https://github.com/mui/mui-x/blob/HEAD/packages/x-codemod/README.md#preset-safe-for-pickers-v800) for more details. +::: + +Breaking changes that are handled by this codemod are denoted by a ✅ emoji in the table of contents on the right side of the screen. + +If you have already applied the `v8.0.0/pickers/preset-safe` (or `v8.0.0/preset-safe`) codemod, then you should not need to take any further action on these items. + +All other changes must be handled manually. + +:::warning +Not all use cases are covered by codemods. In some scenarios, like props spreading, cross-file dependencies, etc., the changes are not properly identified and therefore must be handled manually. + +For example, if a codemod tries to rename a prop, but this prop is hidden with the spread operator, it won't be transformed as expected. + +```tsx + +``` + +After running the codemods, make sure to test your application and that you don't have any console errors. + +Feel free to [open an issue](https://github.com/mui/mui-x/issues/new/choose) for support if you need help to proceed with your migration. +::: + +## New DOM structure for the field + +Before version `v8.x`, the fields' DOM structure consisted of an ``, which held the whole value for the component, +but unfortunately presents a few limitations in terms of accessibility when managing multiple section values. + +Starting with version `v8.x`, all the field and picker components come with a new DOM structure that allows the field component to set aria attributes on individual sections, providing a far better experience with screen readers. + +### Fallback to the non-accessible DOM structure + +```tsx + + + +``` + +### Migrate `slotProps.field` + +When using `slotProps.field` to pass props to your field component, +the field consumes some props (e.g: `shouldRespectLeadingZeros`) and forwards the rest to the `TextField`. + +- For the props consumed by the field, the behavior should remain exactly the same with both DOM structures. + + Both components below will respect the leading zeroes on digit sections: + + ```js + + + ``` + +- For the props forwarded to the `TextField`, + you can have a look at the next section to see how the migration impact them. + + Both components below will render a small size UI: + + ```js + + + ``` + +### Migrate `slotProps.textField` + +If you are passing props to `slotProps.textField`, +these props will now be received by `PickersTextField` and should keep working the same way as before. + +Both components below will render a small size UI: + +```js + + +``` + +:::info +If you are passing `inputProps` to `slotProps.textField`, +these props will now be passed to the hidden `` element. +::: + +### Migrate `slots.field` + +If you are passing a custom field component to your pickers, you need to create a new one that is using the accessible DOM structure. +This new component will need to use the `PickersSectionList` component instead of an `` HTML element. + +You can have a look at the [Using a custom input](/x/react-date-pickers/custom-field/#using-a-custom-input) to have a concrete example. + +:::info +If your custom field was used to create a Joy UI design component, +you may want to wait a few weeks for the release of an out-of-the-box Joy `PickersTextField` component instead of implementing it yourself. +::: + +### Migrate `slots.textField` + +If you are passing a custom `TextField` component to your fields and pickers, +you need to create a new one that is using the accessible DOM structure. + +You can have a look at the second demo of the [Wrapping PickersTextField](/x/react-date-pickers/custom-field/#wrapping-pickerstextfield) to have a concrete example. + +:::info +If your custom `TextField` was used to apply a totally different input that did not use `@mui/material/TextField`, +please consider having a look at the [Using a custom input](/x/react-date-pickers/custom-field/#using-a-custom-input) section which uses `slots.field`. +This approach can be more appropriate for deeper changes. +::: + +### Migrate the theme + +If you are using the theme to customize `MuiTextField`, +you need to pass the same config to `MuiPickersTextField`: + +```js +const theme = createTheme({ + components: { + MuiTextField: { + defaultProps: { + variant: 'outlined', + }, + styleOverrides: { + root: { + '& .MuiInputLabel-outlined.Mui-focused': { + color: 'red', + }, + }, + }, + }, + MuiPickersTextField: { + defaultProps: { + variant: 'outlined', + }, + styleOverrides: { + root: { + '& .MuiInputLabel-outlined.Mui-focused': { + color: 'red', + }, + }, + }, + }, + }, +}); +``` + +If you are using the theme to customize `MuiInput`, `MuiOutlinedInput` or `MuiFilledInput`, +you need to pass the same config to `MuiPickersInput`, `MuiPickersOutlinedInput` or `MuiPickersFilledInput`: + +```js +const theme = createTheme({ + components: { + // Replace with `MuiOutlinedInput` or `MuiFilledInput` if needed + MuiInput: { + defaultProps: { + margin: 'dense', + }, + styleOverrides: { + root: { + color: 'red', + }, + }, + }, + // Replace with `MuiPickersOutlinedInput` or `MuiPickersFilledInput` if needed + MuiPickersInput: { + defaultProps: { + margin: 'dense', + }, + styleOverrides: { + root: { + color: 'red', + }, + }, + }, + }, +}); +``` + +If you are using the theme to customize `MuiInputBase`, +you need to pass the same config to `MuiPickersInputBase`: + +```js +const theme = createTheme({ + components: { + MuiInputBase: { + defaultProps: { + margin: 'dense', + }, + styleOverrides: { + root: { + color: 'red', + }, + }, + }, + MuiPickersInputBase: { + defaultProps: { + margin: 'dense', + }, + styleOverrides: { + root: { + color: 'red', + }, + }, + }, + }, +}); +``` + +## Removed types + +The following types are no longer exported by `@mui/x-date-pickers` and/or `@mui/x-date-pickers-pro`. +If you were using them, you need to replace them with the following code: + +- `UseDateFieldComponentProps` + + ```ts + import { UseDateFieldProps } from '@mui/x-date-pickers/DateField'; + import { PickerValidDate } from '@mui/x-date-pickers/models'; + + type UseDateFieldComponentProps< + TDate extends PickerValidDate, + TEnableAccessibleFieldDOMStructure extends boolean, + TChildProps extends {}, + > = Omit< + TChildProps, + keyof UseDateFieldProps + > & + UseDateFieldProps; + ``` + +- `UseTimeFieldComponentProps` + + ```ts + import { UseTimeFieldProps } from '@mui/x-date-pickers/TimeField'; + import { PickerValidDate } from '@mui/x-date-pickers/models'; + + type UseTimeFieldComponentProps< + TDate extends PickerValidDate, + TEnableAccessibleFieldDOMStructure extends boolean, + TChildProps extends {}, + > = Omit< + TChildProps, + keyof UseTimeFieldProps + > & + UseTimeFieldProps; + ``` + +- `UseDateTimeFieldComponentProps` + + ```ts + import { UseDateTimeFieldProps } from '@mui/x-date-pickers/DateTimeField'; + import { PickerValidDate } from '@mui/x-date-pickers/models'; + + type UseDateTimeFieldComponentProps< + TDate extends PickerValidDate, + TEnableAccessibleFieldDOMStructure extends boolean, + TChildProps extends {}, + > = Omit< + TChildProps, + keyof UseDateTimeFieldProps + > & + UseDateTimeFieldProps; + ``` + +## Stop passing `utils` and the date object to some translation keys + +Some translation keys no longer require `utils` and the date object as parameters, but only the formatted value as a string. The keys affected by this changes are: `clockLabelText`, `openDatePickerDialogue` and `openTimePickerDialogue`. +If you have customized those translation keys, you have to update them following the examples below: + +- If you are setting a custom value in a picker component: + +```diff +-clockLabelText: (view, time, utils) => +- `Select ${view}. ${ +- time === null || !utils.isValid(time) +- ? 'No time selected' +- : `Selected time is ${utils.format(time, 'fullTime')}` +- }` ++clockLabelText: (view, formattedTime) => ++ `Select ${view}. ${ ++ formattedTime == null ? 'No time selected' : `Selected time is ${formattedTime}` ++ }` + +-openDatePickerDialogue: (value, utils) => +- value !== null && utils.isValid(value) +- ? `Choose date, selected date is ${utils.format(value, 'fullDate')}` +- : 'Choose date', ++openDatePickerDialogue: (formattedDate) => ++ formattedDate ? `Choose date, selected date is ${formattedDate}` : 'Choose date' + +-openTimePickerDialogue: (value, utils) => +- value !== null && utils.isValid(value) +- ? `Choose time, selected time is ${utils.format(value, 'fullTime')}` +- : 'Choose time', ++openTimePickerDialogue: (formattedTime) => ++ formattedTime ? `Choose time, selected time is ${formattedTime}` : 'Choose time' +``` + +- If you are setting a custom value in the `LocalizationProvider`: + +```diff + +- `Select ${view}. ${ +- time === null || !utils.isValid(time) +- ? 'No time selected' +- : `Selected time is ${utils.format(time, 'fullTime')}` +- }` ++ clockLabelText: (view, formattedTime) => ++ `Select ${view}. ${ ++ formattedTime == null ? 'No time selected' : `Selected time is ${formattedTime}` ++ }` +- openDatePickerDialogue: (value, utils) => +- value !== null && utils.isValid(value) +- ? `Choose date, selected date is ${utils.format(value, 'fullDate')}` +- : 'Choose date', ++ openDatePickerDialogue: (formattedDate) => ++ formattedDate ? `Choose date, selected date is ${formattedDate}` : 'Choose date' +- openTimePickerDialogue: (value, utils) => +- value !== null && utils.isValid(value) +- ? `Choose time, selected time is ${utils.format(value, 'fullTime')}` +- : 'Choose time', ++ openTimePickerDialogue: (formattedTime) => ++ formattedTime ? `Choose time, selected time is ${formattedTime}` : 'Choose time' + }} > +``` + +- If you using this translation key in a custom component: + +```diff + const translations = usePickersTranslations(); + +-const clockLabelText = translations.clockLabelText( +- view, +- value, +- {} as any, +- value == null ? null : value.format('hh:mm:ss') +-); ++const clockLabelText = translations.clockLabelText( ++ view, ++ value == null ? null : value.format('hh:mm:ss') ++); + +-const openDatePickerDialogue = translations.openDatePickerDialogue( +- value, +- {} as any, +- value == null ? null : value.format('MM/DD/YYY') +-); ++const openDatePickerDialogue = translations.openDatePickerDialogue( ++ value == null ? null : value.format('MM/DD/YYY') ++); + +-const openTimePickerDialogue = translations.openTimePickerDialogue( +- value, +- {} as any, +- value == null ? null : value.format('hh:mm:ss') +-); ++const openTimePickerDialogue = translations.openTimePickerDialogue( ++ value == null ? null : value.format('hh:mm:ss') ++); +``` + +Also the following types and interfaces no longer receive a generic type parameter: + +- `PickersComponentAgnosticLocaleText` +- `PickersInputComponentLocaleText` +- `PickersInputLocaleText` +- `PickersLocaleText` +- `PickersTranslationKeys` diff --git a/docs/data/migration/migration-tree-view-v7/migration-tree-view-v7.md b/docs/data/migration/migration-tree-view-v7/migration-tree-view-v7.md new file mode 100644 index 000000000000..c76698100726 --- /dev/null +++ b/docs/data/migration/migration-tree-view-v7/migration-tree-view-v7.md @@ -0,0 +1,180 @@ +--- +productId: x-tree-view +--- + +# Migration from v7 to v8 + +

This guide describes the changes needed to migrate the Tree View from v7 to v8.

+ +## Introduction + +This is a reference guide for upgrading `@mui/x-tree-view` from v7 to v8. + +## Start using the new release + +In `package.json`, change the version of the Tree View package to `next`. + +```diff +-"@mui/x-tree-view": "7.x.x", ++"@mui/x-tree-view": "next", +``` + +Using `next` ensures that it will always use the latest v8 pre-release version, but you can also use a fixed version, like `8.0.0-alpha.0`. + +Since `v8` is a major release, it contains changes that affect the public API. +These changes were done for consistency, improved stability and to make room for new features. +Described below are the steps needed to migrate from v7 to v8. + +## Run codemods + +The `preset-safe` codemod will automatically adjust the bulk of your code to account for breaking changes in v8. You can run `v8.0.0/tree-view/preset-safe` targeting only Tree View or `v8.0.0/preset-safe` to target the other packages as well. + +You can either run it on a specific file, folder, or your entire codebase when choosing the `` argument. + + + +```bash +// Tree View specific +npx @mui/x-codemod@latest v8.0.0/tree-view/preset-safe + +// Target the other packages as well +npx @mui/x-codemod@latest v8.0.0/preset-safe +``` + +:::info +If you want to run the transformers one by one, check out the transformers included in the [preset-safe codemod for the Tree View](https://github.com/mui/mui-x/blob/HEAD/packages/x-codemod/README.md#preset-safe-for-tree-view-v800) for more details. +::: + +Breaking changes that are handled by this codemod are denoted by a ✅ emoji in the table of contents on the right side of the screen. + +If you have already applied the `v8.0.0/tree-view/preset-safe` (or `v8.0.0/preset-safe`) codemod, then you should not need to take any further action on these items. + +All other changes must be handled manually. + +:::warning +Not all use cases are covered by codemods. In some scenarios, like props spreading, cross-file dependencies, etc., the changes are not properly identified and therefore must be handled manually. + +For example, if a codemod tries to rename a prop, but this prop is hidden with the spread operator, it won't be transformed as expected. + +```tsx + +``` + +After running the codemods, make sure to test your application and that you don't have any console errors. + +Feel free to [open an issue](https://github.com/mui/mui-x/issues/new/choose) for support if you need help to proceed with your migration. +::: + +## New API to customize the Tree Item + +The `ContentComponent` or `ContentProps` props of the `TreeItem` component have been removed in favor of the new `slots`, `slotProps` props and of the `useTreeItem` hook. + +Learn more about the anatomy of the Tree Items and the customization utilities provided on the [Tree Item Customization page](/x/react-tree-view/tree-item-customization/). + +## Behavior change on the `onClick` and `onMouseDown` props of `TreeItem` + +The `onClick` and `onMouseDown` were the only event callback that were passed to the content of the Tree Item instead of its root. +The goal was to make sure that the callback was not fired when clicking on a descendant of a giving item. +This inconsistency has been solved, all the event manager now target the root of the item, and you can use the `onItemClick` prop on the Tree View component to target the content of an item: + +```diff +- ++ +- ++ + +``` + +## Rename the `TreeItem2` (and related utils) + +All the new Tree Item-related components and utils (introduced in the previous major to improve the DX of the Tree Item component) are becoming the default way of using the Tree Item and are therefore losing their `2` suffix: + +```diff + import * as React from 'react'; + import { +- TreeItem2, ++ TreeItem, +- TreeItem2Root, ++ TreeItemRoot, +- TreeItem2Content, ++ TreeItemContent, +- TreeItem2IconContainer, ++ TreeItemIconContainer, +- TreeItem2GroupTransition, ++ TreeItemGroupTransition, +- TreeItem2Checkbox, ++ TreeItemCheckbox, +- TreeItem2Label, ++ TreeItemLabel, +- TreeItem2Props, ++ TreeItemProps, +- TreeItem2Slots, ++ TreeItemSlots, +- TreeItem2SlotProps, ++ TreeItemSlotProps, +- } from '@mui/x-tree-view/TreeItem2'; ++ } from '@mui/x-tree-view/TreeItem'; + import { +- useTreeItem2, ++ useTreeItem, +- unstable_useTreeItem2 as useAliasedTreeItem, ++ unstable_useTreeItem as useAliasedTreeItem, +- UseTreeItem2Parameters, ++ UseTreeItemParameters, +- UseTreeItem2ReturnValue, ++ UseTreeItemReturnValue, +- UseTreeItem2Status, ++ UseTreeItemStatus, +- UseTreeItem2RootSlotOwnProps, ++ UseTreeItemRootSlotOwnProps, +- UseTreeItem2ContentSlotOwnProps, ++ UseTreeItemContentSlotOwnProps, +- UseTreeItem2LabelInputSlotOwnProps, ++ UseTreeItemLabelInputSlotOwnProps, +- UseTreeItem2LabelSlotOwnProps, ++ UseTreeItemLabelSlotOwnProps, +- UseTreeItem2CheckboxSlotOwnProps, ++ UseTreeItemCheckboxSlotOwnProps, +- UseTreeItem2IconContainerSlotOwnProps, ++ UseTreeItemIconContainerSlotOwnProps, +- UseTreeItem2GroupTransitionSlotOwnProps, ++ UseTreeItemGroupTransitionSlotOwnProps, +- UseTreeItem2DragAndDropOverlaySlotOwnProps, ++ UseTreeItemDragAndDropOverlaySlotOwnProps, +- } from '@mui/x-tree-view/useTreeItem2'; ++ } from '@mui/x-tree-view/useTreeItem'; +- import { useTreeItem2Utils } from '@mui/x-tree-view/hooks'; ++ import { useTreeItemUtils } from '@mui/x-tree-view/hooks'; + import { +- TreeItem2Provider, ++ TreeItemProvider, +- TreeItem2ProviderProps, ++ TreeItemProviderProps, +- } from '@mui/x-tree-view/TreeItem2Provider'; ++ } from '@mui/x-tree-view/TreeItemProvider'; + import { +- TreeItem2Icon, ++ TreeItemIcon, +- TreeItem2IconProps, ++ TreeItemIconProps, +- TreeItem2IconSlots, ++ TreeItemIconSlots, +- TreeItem2IconSlotProps, ++ TreeItemIconSlotProps, +- } from '@mui/x-tree-view/TreeItem2Icon'; ++ } from '@mui/x-tree-view/TreeItemIcon'; + import { +- TreeItem2DragAndDropOverlay, ++ TreeItemDragAndDropOverlay, +- TreeItem2DragAndDropOverlayProps, ++ TreeItemDragAndDropOverlayProps, +- } from '@mui/x-tree-view/TreeItem2DragAndDropOverlay'; ++ } from '@mui/x-tree-view/TreeItemDragAndDropOverlay'; + import { +- TreeItem2LabelInput, ++ TreeItemLabelInput, +- TreeItem2LabelInputProps, ++ TreeItemLabelInputProps, +- } from '@mui/x-tree-view/TreeItem2LabelInput'; ++ } from '@mui/x-tree-view/TreeItemLabelInput'; +``` diff --git a/docs/data/pages.ts b/docs/data/pages.ts index 557be8daaba8..62ebde3d4dee 100644 --- a/docs/data/pages.ts +++ b/docs/data/pages.ts @@ -1,8 +1,8 @@ import type { MuiPage } from 'docs/src/MuiPage'; -import chartsComponentApi from './charts-component-api-pages'; -import dataGridComponentApi from './data-grid-component-api-pages'; -import pickersComponentApi from './date-pickers-component-api-pages'; -import treeViewComponentApi from './tree-view-component-api-pages'; +import chartsComponentApi from './chartsApiPages'; +import dataGridComponentApi from './dataGridApiPages'; +import pickersComponentApi from './datePickersApiPages'; +import treeViewComponentApi from './treeViewApiPages'; const pages: MuiPage[] = [ { @@ -23,145 +23,168 @@ const pages: MuiPage[] = [ { pathname: '/x/common-features-group', title: 'Common concepts', - children: [{ pathname: `/x/common-concepts/custom-components`, title: 'Custom subcomponents' }], + children: [ + { pathname: `/x/common-concepts/custom-components`, title: 'Slots and subcomponents' }, + ], }, { pathname: '/x/react-data-grid-group', title: 'Data Grid', - children: [ { pathname: '/x/react-data-grid', title: 'Overview' }, - { pathname: '/x/react-data-grid/demo' }, { pathname: '/x/react-data-grid/getting-started' }, - { pathname: '/x/react-data-grid/layout' }, - { - pathname: '/x/react-data-grid/columns', - children: [ - { pathname: '/x/react-data-grid/column-definition' }, - { pathname: '/x/react-data-grid/column-dimensions' }, - { pathname: '/x/react-data-grid/column-visibility' }, - { pathname: '/x/react-data-grid/custom-columns' }, - { pathname: '/x/react-data-grid/column-header' }, - { pathname: '/x/react-data-grid/column-menu' }, - { pathname: '/x/react-data-grid/column-spanning' }, - { pathname: '/x/react-data-grid/column-groups' }, - { pathname: '/x/react-data-grid/column-ordering', plan: 'pro' }, - { pathname: '/x/react-data-grid/column-pinning', plan: 'pro' }, - ], - }, - { - pathname: '/x/react-data-grid/rows', - children: [ - { pathname: '/x/react-data-grid/row-definition' }, - { pathname: '/x/react-data-grid/row-updates' }, - { pathname: '/x/react-data-grid/row-height' }, - { pathname: '/x/react-data-grid/row-spanning', newFeature: true }, - { pathname: '/x/react-data-grid/master-detail', plan: 'pro' }, - { pathname: '/x/react-data-grid/row-ordering', plan: 'pro' }, - { pathname: '/x/react-data-grid/row-pinning', plan: 'pro' }, - { pathname: '/x/react-data-grid/row-recipes', title: 'Recipes' }, - ], - }, - { pathname: '/x/react-data-grid/editing' }, - { pathname: '/x/react-data-grid/sorting' }, + { pathname: '/x/react-data-grid/demo' }, + { pathname: '/x/react-data-grid/faq', title: 'FAQs' }, { - pathname: '/x/react-data-grid/filtering-group', - title: 'Filtering', + pathname: '/x/react-data-grid/main-features', + subheader: 'Main features', children: [ - { pathname: '/x/react-data-grid/filtering', title: 'Overview' }, - { pathname: '/x/react-data-grid/filtering/customization' }, - { pathname: '/x/react-data-grid/filtering/quick-filter' }, - { pathname: '/x/react-data-grid/filtering/server-side', title: 'Server-side filter' }, - { pathname: '/x/react-data-grid/filtering/multi-filters', plan: 'pro' }, + { pathname: '/x/react-data-grid/layout' }, { - pathname: '/x/react-data-grid/filtering/header-filters', - plan: 'pro', - newFeature: true, + pathname: '/x/react-data-grid/columns', + children: [ + { pathname: '/x/react-data-grid/column-definition' }, + { pathname: '/x/react-data-grid/column-dimensions' }, + { pathname: '/x/react-data-grid/column-visibility' }, + { pathname: '/x/react-data-grid/custom-columns' }, + { pathname: '/x/react-data-grid/column-header' }, + { pathname: '/x/react-data-grid/column-menu' }, + { pathname: '/x/react-data-grid/column-spanning' }, + { pathname: '/x/react-data-grid/column-groups' }, + { pathname: '/x/react-data-grid/column-ordering', plan: 'pro' }, + { pathname: '/x/react-data-grid/column-pinning', plan: 'pro' }, + ], }, - { pathname: '/x/react-data-grid/filtering-recipes', title: 'Recipes' }, - ], - }, - { pathname: '/x/react-data-grid/pagination' }, - { - pathname: '/x/react-data-grid/selection', - children: [ - { pathname: '/x/react-data-grid/row-selection' }, - { pathname: '/x/react-data-grid/cell-selection', plan: 'premium', newFeature: true }, - ], - }, - { pathname: '/x/react-data-grid/export' }, - { pathname: '/x/react-data-grid/clipboard', title: 'Copy and paste', newFeature: true }, - { pathname: '/x/react-data-grid/overlays', title: 'Overlays' }, - { pathname: '/x/react-data-grid/components', title: 'Custom subcomponents' }, - { - pathname: '/x/react-data-grid/style-group', - title: 'Style', - children: [ - { pathname: '/x/react-data-grid/style', title: 'Overview' }, - { pathname: '/x/react-data-grid/style-recipes', title: 'Recipes' }, + { + pathname: '/x/react-data-grid/rows', + children: [ + { pathname: '/x/react-data-grid/row-definition' }, + { pathname: '/x/react-data-grid/row-updates' }, + { pathname: '/x/react-data-grid/row-height' }, + { pathname: '/x/react-data-grid/row-spanning', newFeature: true }, + { pathname: '/x/react-data-grid/master-detail', plan: 'pro' }, + { pathname: '/x/react-data-grid/row-ordering', plan: 'pro' }, + { pathname: '/x/react-data-grid/row-pinning', plan: 'pro' }, + { pathname: '/x/react-data-grid/row-recipes', title: 'Recipes' }, + ], + }, + { + pathname: '/x/react-data-grid/editing-group', + title: 'Editing', + children: [ + { pathname: '/x/react-data-grid/editing', title: 'Overview' }, + { pathname: '/x/react-data-grid/recipes-editing', title: 'Recipes' }, + ], + }, + { pathname: '/x/react-data-grid/sorting' }, + { + pathname: '/x/react-data-grid/filtering-group', + title: 'Filtering', + children: [ + { pathname: '/x/react-data-grid/filtering', title: 'Overview' }, + { pathname: '/x/react-data-grid/filtering/customization' }, + { pathname: '/x/react-data-grid/filtering/quick-filter' }, + { pathname: '/x/react-data-grid/filtering/server-side', title: 'Server-side filter' }, + { pathname: '/x/react-data-grid/filtering/multi-filters', plan: 'pro' }, + { + pathname: '/x/react-data-grid/filtering/header-filters', + plan: 'pro', + newFeature: true, + }, + { pathname: '/x/react-data-grid/filtering-recipes', title: 'Recipes' }, + ], + }, + { pathname: '/x/react-data-grid/pagination' }, + { + pathname: '/x/react-data-grid/selection', + children: [ + { pathname: '/x/react-data-grid/row-selection' }, + { pathname: '/x/react-data-grid/cell-selection', plan: 'premium', newFeature: true }, + ], + }, + { pathname: '/x/react-data-grid/virtualization' }, + { pathname: '/x/react-data-grid/accessibility' }, + { pathname: '/x/react-data-grid/localization' }, ], }, - { pathname: '/x/react-data-grid/localization' }, - { pathname: '/x/react-data-grid/scrolling' }, - { pathname: '/x/react-data-grid/virtualization' }, - { pathname: '/x/react-data-grid/accessibility' }, - { pathname: '/x/react-data-grid/performance' }, - { pathname: '/x/react-data-grid/tree-data', plan: 'pro' }, - { pathname: '/x/react-data-grid/row-grouping', plan: 'premium' }, - { pathname: '/x/react-data-grid/aggregation', plan: 'premium' }, - { pathname: '/x/react-data-grid/pivoting', plan: 'premium', planned: true }, - { - pathname: '/x/react-data-grid/list-view', - title: 'List view', - plan: 'pro', - unstable: true, - }, { - pathname: '/x/react-data-grid/server-side-data-group', - title: 'Server-side data', - plan: 'pro', - newFeature: true, + pathname: '/x/react-data-grid/advanced-features-group', + subheader: 'Advanced features', children: [ - { pathname: '/x/react-data-grid/server-side-data', title: 'Overview', plan: 'pro' }, - { pathname: '/x/react-data-grid/server-side-data/tree-data', plan: 'pro' }, + { pathname: '/x/react-data-grid/tree-data', plan: 'pro' }, { - pathname: '/x/react-data-grid/server-side-data/lazy-loading', - plan: 'pro', - planned: true, + pathname: '/x/react-data-grid/row-grouping-group', + title: 'Row grouping', + plan: 'premium', + children: [ + { pathname: '/x/react-data-grid/row-grouping', title: 'Overview' }, + { + pathname: '/x/react-data-grid/recipes-row-grouping', + title: 'Recipes', + }, + ], }, + { pathname: '/x/react-data-grid/aggregation', plan: 'premium' }, + { pathname: '/x/react-data-grid/pivoting', plan: 'premium', planned: true }, + { pathname: '/x/react-data-grid/export' }, + { pathname: '/x/react-data-grid/clipboard', title: 'Copy and paste', newFeature: true }, + { pathname: '/x/react-data-grid/scrolling' }, + { - pathname: '/x/react-data-grid/server-side-data/infinite-loading', + pathname: '/x/react-data-grid/list-view', + title: 'List view', plan: 'pro', - planned: true, - }, - { - pathname: '/x/react-data-grid/server-side-data/row-grouping', - plan: 'premium', + unstable: true, }, { - pathname: '/x/react-data-grid/server-side-data/aggregation', - plan: 'premium', - planned: true, + pathname: '/x/react-data-grid/server-side-data-group', + title: 'Server-side data', + plan: 'pro', + children: [ + { pathname: '/x/react-data-grid/server-side-data', title: 'Overview' }, + { pathname: '/x/react-data-grid/server-side-data/tree-data', plan: 'pro' }, + { + pathname: '/x/react-data-grid/server-side-data/lazy-loading', + plan: 'pro', + planned: true, + }, + { + pathname: '/x/react-data-grid/server-side-data/infinite-loading', + plan: 'pro', + planned: true, + }, + { + pathname: '/x/react-data-grid/server-side-data/row-grouping', + plan: 'premium', + planned: true, + }, + { + pathname: '/x/react-data-grid/server-side-data/aggregation', + plan: 'premium', + planned: true, + }, + ], }, ], }, { - pathname: '/x/react-data-grid/custom-behavior', + pathname: '/x/react-data-grid/customization-group', + subheader: 'Customization', children: [ - { pathname: '/x/react-data-grid/api-object', title: 'API object' }, - { pathname: '/x/react-data-grid/events' }, - { pathname: '/x/react-data-grid/state' }, + { pathname: '/x/react-data-grid/style', title: 'Styling basics' }, + { pathname: '/x/react-data-grid/style-recipes', title: 'Styling recipes' }, + { pathname: '/x/react-data-grid/overlays', title: 'Overlays' }, + { pathname: '/x/react-data-grid/components', title: 'Custom subcomponents' }, ], }, { - pathname: '/x/react-data-grid/recipes', + pathname: '/x/api/resources-group', + subheader: 'Resources', children: [ - { pathname: '/x/react-data-grid/recipes-editing', title: 'Editing' }, - { - pathname: '/x/react-data-grid/recipes-row-grouping', - title: 'Row grouping', - plan: 'premium', - }, + { pathname: '/x/react-data-grid/api-object', title: 'API object' }, + { pathname: '/x/react-data-grid/events' }, + { pathname: '/x/react-data-grid/state' }, + { pathname: '/x/react-data-grid/performance' }, ], }, { @@ -223,7 +246,6 @@ const pages: MuiPage[] = [ }, ], }, - { pathname: '/x/react-data-grid/faq', title: 'FAQ' }, ], }, { @@ -233,8 +255,7 @@ const pages: MuiPage[] = [ { pathname: '/x/react-date-pickers', title: 'Overview' }, { pathname: '/x/react-date-pickers/getting-started' }, { pathname: '/x/react-date-pickers/base-concepts' }, - { pathname: '/x/react-date-pickers/accessibility' }, - { pathname: '/x/react-date-pickers/faq', title: 'FAQ' }, + { pathname: '/x/react-date-pickers/faq', title: 'FAQs' }, { pathname: '/x/react-date-pickers-components', subheader: 'Components', @@ -327,20 +348,16 @@ const pages: MuiPage[] = [ ], }, { pathname: '/x/react-date-pickers/fields', title: 'Field components' }, - { - pathname: '/x/api/date-pickers-group', - title: 'API reference', - children: [{ pathname: '/x/api/date-pickers', title: 'Index' }, ...pickersComponentApi], - }, ], }, { - pathname: '/x/react-date-pickers/common-features', - subheader: 'Common features', + pathname: '/x/react-date-pickers/main-features', + subheader: 'Main features', children: [ { pathname: '/x/react-date-pickers/validation' }, { pathname: '/x/react-date-pickers/lifecycle', title: 'Components lifecycle' }, { pathname: '/x/react-date-pickers/shortcuts' }, + { pathname: '/x/react-date-pickers/accessibility' }, ], }, { @@ -363,8 +380,8 @@ const pages: MuiPage[] = [ ], }, { - pathname: '/x/react-date-pickers/visual-customization', - subheader: 'Visual customization', + pathname: '/x/react-date-pickers/customization-group', + subheader: 'Customization', children: [ { pathname: '/x/react-date-pickers/custom-components', @@ -376,6 +393,17 @@ const pages: MuiPage[] = [ { pathname: '/x/react-date-pickers/playground', title: 'Customization playground' }, ], }, + { + pathname: '/x/api/picker-resources', + subheader: 'Resources', + children: [ + { + pathname: '/x/api/date-pickers-group', + title: 'API reference', + children: [{ pathname: '/x/api/date-pickers', title: 'Index' }, ...pickersComponentApi], + }, + ], + }, ], }, { @@ -386,8 +414,8 @@ const pages: MuiPage[] = [ { pathname: '/x/react-charts', title: 'Overview' }, { pathname: '/x/react-charts/getting-started' }, { - pathname: '/x/react-charts-available', - subheader: 'Available components', + pathname: '/x/react-chart-components', + subheader: 'Components', children: [ { pathname: '/x/react-charts-bars', @@ -434,8 +462,8 @@ const pages: MuiPage[] = [ unstable: true, }, { - pathname: '/x/react-charts/common-features', - subheader: 'Common features', + pathname: '/x/react-charts/main-features', + subheader: 'Main features', children: [ { pathname: '/x/react-charts/axis' }, { pathname: '/x/react-charts/components', title: 'Custom components' }, @@ -455,19 +483,25 @@ const pages: MuiPage[] = [ ], }, { - pathname: '/x/api/charts-group', - title: 'API reference', + pathname: '/x/api/chart-resources', + subheader: 'Resources', children: [ - ...chartsComponentApi, { - pathname: '/x/api/charts-interfaces-group', - subheader: 'Interfaces', + pathname: '/x/api/charts-group', + title: 'API reference', children: [ - { pathname: '/x/api/charts/axis-config', title: 'AxisConfig' }, - { pathname: '/x/api/charts/bar-series-type', title: 'BarSeriesType' }, - { pathname: '/x/api/charts/line-series-type', title: 'LineSeriesType' }, - { pathname: '/x/api/charts/pie-series-type', title: 'PieSeriesType' }, - { pathname: '/x/api/charts/scatter-series-type', title: 'ScatterSeriesType' }, + ...chartsComponentApi, + { + pathname: '/x/api/charts-interfaces-group', + subheader: 'Interfaces', + children: [ + { pathname: '/x/api/charts/axis-config', title: 'AxisConfig' }, + { pathname: '/x/api/charts/bar-series-type', title: 'BarSeriesType' }, + { pathname: '/x/api/charts/line-series-type', title: 'LineSeriesType' }, + { pathname: '/x/api/charts/pie-series-type', title: 'PieSeriesType' }, + { pathname: '/x/api/charts/scatter-series-type', title: 'ScatterSeriesType' }, + ], + }, ], }, ], @@ -519,17 +553,23 @@ const pages: MuiPage[] = [ ], }, { - pathname: '/x/react-tree-view/common-features', - subheader: 'Common features', + pathname: '/x/react-tree-view/main-features', + subheader: 'Main features', children: [ { pathname: '/x/react-tree-view/accessibility' }, { pathname: '/x/react-tree-view/tree-item-customization', title: 'Item customization' }, ], }, { - pathname: '/x/api/tree-view-group', - title: 'API reference', - children: [...treeViewComponentApi], + pathname: '/x/api/tree-view-resources', + subheader: 'Resources', + children: [ + { + pathname: '/x/api/tree-view-group', + title: 'API reference', + children: [...treeViewComponentApi], + }, + ], }, ], }, @@ -537,9 +577,28 @@ const pages: MuiPage[] = [ pathname: '/x/migration-group', title: 'Migration', children: [ + { + pathname: '/x/migration-v8', + subheader: 'Upgrade to v8', + children: [ + { pathname: '/x/migration/migration-data-grid-v7', title: 'Breaking changes: Data Grid' }, + { + pathname: '/x/migration/migration-pickers-v7', + title: 'Breaking changes: Date and Time Pickers', + }, + { + pathname: '/x/migration/migration-tree-view-v7', + title: 'Breaking changes: Tree View', + }, + { + pathname: '/x/migration/migration-charts-v7', + title: 'Breaking changes: Charts', + }, + ], + }, { pathname: '/x/migration-v7', - subheader: 'Upgrade to v7', + title: 'Upgrade to v7', children: [ { pathname: '/x/migration/migration-data-grid-v6', title: 'Breaking changes: Data Grid' }, { diff --git a/docs/data/pickersAdapterOverride.ts b/docs/data/pickersAdapterOverride.ts new file mode 100644 index 000000000000..1e3fec79c0a9 --- /dev/null +++ b/docs/data/pickersAdapterOverride.ts @@ -0,0 +1,9 @@ +// This module override mark all the date object in the doc to be any instead of Date | Dayjs | Moment | DateTime. +// That way we can use date library methods without casting the date object to a specific type. +declare module '@mui/x-date-pickers/models' { + interface PickerValidDateLookup { + fakeDocAdapter: any; + } +} + +export {}; diff --git a/docs/data/tree-view/datasets/employees.ts b/docs/data/tree-view/datasets/employees.ts new file mode 100644 index 000000000000..2af62416f36e --- /dev/null +++ b/docs/data/tree-view/datasets/employees.ts @@ -0,0 +1,40 @@ +import { TreeViewBaseItem } from '@mui/x-tree-view/models'; + +export const EMPLOYEES_DATASET: TreeViewBaseItem[] = [ + { + id: '0', + label: 'Sarah', + }, + { + id: '1', + label: 'Thomas', + children: [ + { id: '2', label: 'Robert' }, + { id: '3', label: 'Karen' }, + { id: '4', label: 'Nancy' }, + { id: '5', label: 'Daniel' }, + { id: '6', label: 'Christopher' }, + { id: '7', label: 'Donald' }, + ], + }, + { + id: '8', + label: 'Mary', + children: [ + { + id: '9', + label: 'Jennifer', + children: [{ id: '10', label: 'Anna' }], + }, + { id: '11', label: 'Michael' }, + { + id: '12', + label: 'Linda', + children: [ + { id: '13', label: 'Elizabeth' }, + { id: '14', label: 'William' }, + ], + }, + ], + }, +]; diff --git a/docs/data/tree-view/overview/overview.md b/docs/data/tree-view/overview/overview.md index 05a98d903ddf..e1c49a7e2bd6 100644 --- a/docs/data/tree-view/overview/overview.md +++ b/docs/data/tree-view/overview/overview.md @@ -41,75 +41,3 @@ This is the recommended version for larger trees, as well as those that require :::info At the moment, the Simple and Rich Tree Views are similar in terms of feature support. But as the component grows, you can expect to see the more advanced ones appear primarily on the Rich Tree View. ::: - -### Tree Item components - -The `@mui/x-tree-view` package exposes two different components to define your tree items: - -- `` -- `` - -#### Tree Item - -This is the long-standing component that is very similar to the one used in previous versions (`@mui/x-tree-view@6` and `@mui/lab`). - -When using Simple Tree View, -you can import it from `@mui/x-tree-view/TreeItem` and use it as a child of the Simple Tree View component: - -```tsx -import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView'; -import { TreeItem } from '@mui/x-tree-view/TreeItem'; - -export default function App() { - return ( - - - - - ); -} -``` - -When using Rich Tree View, -you don't have to import anything; it's the default component used to render the items: - -```tsx -import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; - -export default function App() { - return ; -} -``` - -#### Tree Item 2 - -This is a new component that provides a more powerful customization API, and will eventually replace ``. - -When using Simple Tree View, -you can import it from `@mui/x-tree-view/TreeItem2` and use it as a child of the Simple Tree View component: - -```tsx -import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView'; -import { TreeItem2 } from '@mui/x-tree-view/TreeItem2'; - -export default function App() { - return ( - - - - - ); -} -``` - -When using Rich Tree View, -you can import it from `@mui/x-tree-view/TreeItem2` and pass it as a slot of the Rich Tree View component: - -```tsx -import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; -import { TreeItem2 } from '@mui/x-tree-view/TreeItem2'; - -export default function App() { - return ; -} -``` diff --git a/docs/data/tree-view/rich-tree-view/customization/FileExplorer.js b/docs/data/tree-view/rich-tree-view/customization/FileExplorer.js index 305d77fc61a3..304f82faaf74 100644 --- a/docs/data/tree-view/rich-tree-view/customization/FileExplorer.js +++ b/docs/data/tree-view/rich-tree-view/customization/FileExplorer.js @@ -14,18 +14,18 @@ import ImageIcon from '@mui/icons-material/Image'; import PictureAsPdfIcon from '@mui/icons-material/PictureAsPdf'; import VideoCameraBackIcon from '@mui/icons-material/VideoCameraBack'; import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; -import { treeItemClasses } from '@mui/x-tree-view/TreeItem'; -import { useTreeItem2 } from '@mui/x-tree-view/useTreeItem2'; +import { useTreeItem } from '@mui/x-tree-view/useTreeItem'; import { - TreeItem2Checkbox, - TreeItem2Content, - TreeItem2IconContainer, - TreeItem2Label, - TreeItem2Root, -} from '@mui/x-tree-view/TreeItem2'; -import { TreeItem2Icon } from '@mui/x-tree-view/TreeItem2Icon'; -import { TreeItem2Provider } from '@mui/x-tree-view/TreeItem2Provider'; -import { TreeItem2DragAndDropOverlay } from '@mui/x-tree-view/TreeItem2DragAndDropOverlay'; + TreeItemCheckbox, + TreeItemContent, + TreeItemIconContainer, + TreeItemLabel, + TreeItemRoot, + treeItemClasses, +} from '@mui/x-tree-view/TreeItem'; +import { TreeItemIcon } from '@mui/x-tree-view/TreeItemIcon'; +import { TreeItemProvider } from '@mui/x-tree-view/TreeItemProvider'; +import { TreeItemDragAndDropOverlay } from '@mui/x-tree-view/TreeItemDragAndDropOverlay'; const ITEMS = [ { @@ -79,7 +79,7 @@ function DotIcon() { ); } -const StyledTreeItemRoot = styled(TreeItem2Root)(({ theme }) => ({ +const StyledTreeItemRoot = styled(TreeItemRoot)(({ theme }) => ({ color: theme.palette.grey[400], position: 'relative', [`& .${treeItemClasses.groupTransition}`]: { @@ -90,7 +90,7 @@ const StyledTreeItemRoot = styled(TreeItem2Root)(({ theme }) => ({ }), })); -const CustomTreeItemContent = styled(TreeItem2Content)(({ theme }) => ({ +const CustomTreeItemContent = styled(TreeItemContent)(({ theme }) => ({ flexDirection: 'row-reverse', borderRadius: theme.spacing(0.7), marginBottom: theme.spacing(0.5), @@ -156,7 +156,7 @@ const StyledTreeItemLabelText = styled(Typography)({ function CustomLabel({ icon: Icon, expandable, children, ...other }) { return ( - {children} {expandable && } - + ); } @@ -219,7 +219,7 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem(props, ref) { getDragAndDropOverlayProps, status, publicAPI, - } = useTreeItem2({ id, itemId, children, label, disabled, rootRef: ref }); + } = useTreeItem({ id, itemId, children, label, disabled, rootRef: ref }); const item = publicAPI.getItem(itemId); const expandable = isExpandable(children); @@ -231,7 +231,7 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem(props, ref) { } return ( - + - - - - + + + + - + {children && } - + ); }); diff --git a/docs/data/tree-view/rich-tree-view/customization/FileExplorer.tsx b/docs/data/tree-view/rich-tree-view/customization/FileExplorer.tsx index 6711c554ba9d..09291542de68 100644 --- a/docs/data/tree-view/rich-tree-view/customization/FileExplorer.tsx +++ b/docs/data/tree-view/rich-tree-view/customization/FileExplorer.tsx @@ -14,18 +14,18 @@ import ImageIcon from '@mui/icons-material/Image'; import PictureAsPdfIcon from '@mui/icons-material/PictureAsPdf'; import VideoCameraBackIcon from '@mui/icons-material/VideoCameraBack'; import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; -import { treeItemClasses } from '@mui/x-tree-view/TreeItem'; -import { useTreeItem2, UseTreeItem2Parameters } from '@mui/x-tree-view/useTreeItem2'; +import { useTreeItem, UseTreeItemParameters } from '@mui/x-tree-view/useTreeItem'; import { - TreeItem2Checkbox, - TreeItem2Content, - TreeItem2IconContainer, - TreeItem2Label, - TreeItem2Root, -} from '@mui/x-tree-view/TreeItem2'; -import { TreeItem2Icon } from '@mui/x-tree-view/TreeItem2Icon'; -import { TreeItem2Provider } from '@mui/x-tree-view/TreeItem2Provider'; -import { TreeItem2DragAndDropOverlay } from '@mui/x-tree-view/TreeItem2DragAndDropOverlay'; + TreeItemCheckbox, + TreeItemContent, + TreeItemIconContainer, + TreeItemLabel, + TreeItemRoot, + treeItemClasses, +} from '@mui/x-tree-view/TreeItem'; +import { TreeItemIcon } from '@mui/x-tree-view/TreeItemIcon'; +import { TreeItemProvider } from '@mui/x-tree-view/TreeItemProvider'; +import { TreeItemDragAndDropOverlay } from '@mui/x-tree-view/TreeItemDragAndDropOverlay'; import { TreeViewBaseItem } from '@mui/x-tree-view/models'; type FileType = 'image' | 'pdf' | 'doc' | 'video' | 'folder' | 'pinned' | 'trash'; @@ -94,7 +94,7 @@ declare module 'react' { } } -const StyledTreeItemRoot = styled(TreeItem2Root)(({ theme }) => ({ +const StyledTreeItemRoot = styled(TreeItemRoot)(({ theme }) => ({ color: theme.palette.grey[400], position: 'relative', [`& .${treeItemClasses.groupTransition}`]: { @@ -103,9 +103,9 @@ const StyledTreeItemRoot = styled(TreeItem2Root)(({ theme }) => ({ ...theme.applyStyles('light', { color: theme.palette.grey[800], }), -})) as unknown as typeof TreeItem2Root; +})) as unknown as typeof TreeItemRoot; -const CustomTreeItemContent = styled(TreeItem2Content)(({ theme }) => ({ +const CustomTreeItemContent = styled(TreeItemContent)(({ theme }) => ({ flexDirection: 'row-reverse', borderRadius: theme.spacing(0.7), marginBottom: theme.spacing(0.5), @@ -182,7 +182,7 @@ function CustomLabel({ ...other }: CustomLabelProps) { return ( - {children} {expandable && } - + ); } @@ -233,7 +233,7 @@ const getIconFromFileType = (fileType: FileType) => { }; interface CustomTreeItemProps - extends Omit, + extends Omit, Omit, 'onFocus'> {} const CustomTreeItem = React.forwardRef(function CustomTreeItem( @@ -252,7 +252,7 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem( getDragAndDropOverlayProps, status, publicAPI, - } = useTreeItem2({ id, itemId, children, label, disabled, rootRef: ref }); + } = useTreeItem({ id, itemId, children, label, disabled, rootRef: ref }); const item = publicAPI.getItem(itemId); const expandable = isExpandable(children); @@ -264,7 +264,7 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem( } return ( - + - - - - + + + + - + {children && } - + ); }); diff --git a/docs/data/tree-view/rich-tree-view/customization/HeadlessAPI.js b/docs/data/tree-view/rich-tree-view/customization/HeadlessAPI.js index afb1f90aec17..5619fbf9b31d 100644 --- a/docs/data/tree-view/rich-tree-view/customization/HeadlessAPI.js +++ b/docs/data/tree-view/rich-tree-view/customization/HeadlessAPI.js @@ -4,18 +4,18 @@ import Box from '@mui/material/Box'; import Avatar from '@mui/material/Avatar'; import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; -import { useTreeItem2 } from '@mui/x-tree-view/useTreeItem2'; +import { useTreeItem } from '@mui/x-tree-view/useTreeItem'; import { - TreeItem2Content, - TreeItem2IconContainer, - TreeItem2GroupTransition, - TreeItem2Label, - TreeItem2Root, - TreeItem2Checkbox, -} from '@mui/x-tree-view/TreeItem2'; -import { TreeItem2Icon } from '@mui/x-tree-view/TreeItem2Icon'; -import { TreeItem2Provider } from '@mui/x-tree-view/TreeItem2Provider'; -import { TreeItem2DragAndDropOverlay } from '@mui/x-tree-view/TreeItem2DragAndDropOverlay'; + TreeItemContent, + TreeItemIconContainer, + TreeItemGroupTransition, + TreeItemLabel, + TreeItemRoot, + TreeItemCheckbox, +} from '@mui/x-tree-view/TreeItem'; +import { TreeItemIcon } from '@mui/x-tree-view/TreeItemIcon'; +import { TreeItemProvider } from '@mui/x-tree-view/TreeItemProvider'; +import { TreeItemDragAndDropOverlay } from '@mui/x-tree-view/TreeItemDragAndDropOverlay'; const ITEMS = [ { @@ -37,7 +37,7 @@ const ITEMS = [ }, ]; -const CustomTreeItemContent = styled(TreeItem2Content)(({ theme }) => ({ +const CustomTreeItemContent = styled(TreeItemContent)(({ theme }) => ({ padding: theme.spacing(0.5, 1), })); @@ -53,15 +53,15 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem(props, ref) { getGroupTransitionProps, getDragAndDropOverlayProps, status, - } = useTreeItem2({ id, itemId, children, label, disabled, rootRef: ref }); + } = useTreeItem({ id, itemId, children, label, disabled, rootRef: ref }); return ( - - + + - - - + + + ({ @@ -73,14 +73,14 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem(props, ref) { > {label[0]} - - + + - + - {children && } - - + {children && } + + ); }); diff --git a/docs/data/tree-view/rich-tree-view/customization/HeadlessAPI.tsx b/docs/data/tree-view/rich-tree-view/customization/HeadlessAPI.tsx index d07cd21249f8..c4ac1965cf83 100644 --- a/docs/data/tree-view/rich-tree-view/customization/HeadlessAPI.tsx +++ b/docs/data/tree-view/rich-tree-view/customization/HeadlessAPI.tsx @@ -4,18 +4,18 @@ import Box from '@mui/material/Box'; import Avatar from '@mui/material/Avatar'; import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; import { TreeViewBaseItem } from '@mui/x-tree-view/models'; -import { useTreeItem2, UseTreeItem2Parameters } from '@mui/x-tree-view/useTreeItem2'; +import { useTreeItem, UseTreeItemParameters } from '@mui/x-tree-view/useTreeItem'; import { - TreeItem2Content, - TreeItem2IconContainer, - TreeItem2GroupTransition, - TreeItem2Label, - TreeItem2Root, - TreeItem2Checkbox, -} from '@mui/x-tree-view/TreeItem2'; -import { TreeItem2Icon } from '@mui/x-tree-view/TreeItem2Icon'; -import { TreeItem2Provider } from '@mui/x-tree-view/TreeItem2Provider'; -import { TreeItem2DragAndDropOverlay } from '@mui/x-tree-view/TreeItem2DragAndDropOverlay'; + TreeItemContent, + TreeItemIconContainer, + TreeItemGroupTransition, + TreeItemLabel, + TreeItemRoot, + TreeItemCheckbox, +} from '@mui/x-tree-view/TreeItem'; +import { TreeItemIcon } from '@mui/x-tree-view/TreeItemIcon'; +import { TreeItemProvider } from '@mui/x-tree-view/TreeItemProvider'; +import { TreeItemDragAndDropOverlay } from '@mui/x-tree-view/TreeItemDragAndDropOverlay'; const ITEMS: TreeViewBaseItem[] = [ { @@ -37,12 +37,12 @@ const ITEMS: TreeViewBaseItem[] = [ }, ]; -const CustomTreeItemContent = styled(TreeItem2Content)(({ theme }) => ({ +const CustomTreeItemContent = styled(TreeItemContent)(({ theme }) => ({ padding: theme.spacing(0.5, 1), })); interface CustomTreeItemProps - extends Omit, + extends Omit, Omit, 'onFocus'> {} const CustomTreeItem = React.forwardRef(function CustomTreeItem( @@ -60,15 +60,15 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem( getGroupTransitionProps, getDragAndDropOverlayProps, status, - } = useTreeItem2({ id, itemId, children, label, disabled, rootRef: ref }); + } = useTreeItem({ id, itemId, children, label, disabled, rootRef: ref }); return ( - - + + - - - + + + ({ @@ -80,14 +80,14 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem( > {(label as string)[0]} - - + + - + - {children && } - - + {children && } + + ); }); diff --git a/docs/data/tree-view/rich-tree-view/customization/customization.md b/docs/data/tree-view/rich-tree-view/customization/customization.md index bb6aba1d2453..ae18c0407ee1 100644 --- a/docs/data/tree-view/rich-tree-view/customization/customization.md +++ b/docs/data/tree-view/rich-tree-view/customization/customization.md @@ -1,7 +1,7 @@ --- productId: x-tree-view title: Rich Tree View - Customization -components: RichTreeView, TreeItem, TreeItem2 +components: RichTreeView, TreeItem packageName: '@mui/x-tree-view' githubLabel: 'component: tree view' waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/treeview/ @@ -12,7 +12,7 @@ waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/treeview/

Learn how to customize the Rich Tree View component.

:::success -See [Common concepts—Custom slots and subcomponents](/x/common-concepts/custom-components/) to learn how to use slots. +See [Common concepts—Slots and subcomponents](/x/common-concepts/custom-components/) to learn how to use slots. ::: ## Basics @@ -45,7 +45,7 @@ Learn more about the anatomy of the Tree Item components and the customization u ### Headless API -Use the `useTreeItem2` hook to create your own component. +Use the `useTreeItem` hook to create your own component. The demo below shows how to add an avatar and custom typography elements. {{"demo": "HeadlessAPI.js", "defaultCodeOpen": false}} @@ -54,13 +54,6 @@ The demo below shows how to add an avatar and custom typography elements. ### File explorer -:::warning -This example is built using the new `` component -which adds several slots to modify the content of the Tree Item or change its behavior. - -You can learn more about this new component in the [Overview page](/x/react-tree-view/#tree-item-components). -::: - The demo below shows many of the previous customization examples brought together to make the Tree View component look completely different than its default design. {{"demo": "FileExplorer.js", "defaultCodeOpen": false}} diff --git a/docs/data/tree-view/rich-tree-view/editing/CustomBehavior.js b/docs/data/tree-view/rich-tree-view/editing/CustomBehavior.js index 4c52e4c94ec8..e6ed064a1613 100644 --- a/docs/data/tree-view/rich-tree-view/editing/CustomBehavior.js +++ b/docs/data/tree-view/rich-tree-view/editing/CustomBehavior.js @@ -1,13 +1,13 @@ import * as React from 'react'; import Box from '@mui/material/Box'; import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; -import { useTreeItem2Utils } from '@mui/x-tree-view/hooks'; -import { TreeItem2 } from '@mui/x-tree-view/TreeItem2'; +import { useTreeItemUtils } from '@mui/x-tree-view/hooks'; +import { TreeItem } from '@mui/x-tree-view/TreeItem'; import { MUI_X_PRODUCTS } from './products'; -const CustomTreeItem2 = React.forwardRef(function CustomTreeItem2(props, ref) { - const { interactions } = useTreeItem2Utils({ +const CustomTreeItem = React.forwardRef(function CustomTreeItem(props, ref) { + const { interactions } = useTreeItemUtils({ itemId: props.itemId, children: props.children, }); @@ -17,7 +17,7 @@ const CustomTreeItem2 = React.forwardRef(function CustomTreeItem2(props, ref) { }; return ( - , ) { - const { interactions } = useTreeItem2Utils({ + const { interactions } = useTreeItemUtils({ itemId: props.itemId, children: props.children, }); - const handleInputBlur: UseTreeItem2LabelInputSlotOwnProps['onBlur'] = (event) => { + const handleInputBlur: UseTreeItemLabelInputSlotOwnProps['onBlur'] = (event) => { interactions.handleCancelItemLabelEditing(event); }; return ( - ({ ...theme.typography.body1, @@ -53,7 +53,7 @@ export const ITEMS = [ function Label({ children, ...other }) { return ( - {children} - + ); } @@ -136,12 +136,12 @@ const LabelInput = React.forwardRef(function LabelInput( ); }); -const CustomTreeItem2 = React.forwardRef(function CustomTreeItem2(props, ref) { - const { interactions } = useTreeItem2Utils({ +const CustomTreeItem = React.forwardRef(function CustomTreeItem(props, ref) { + const { interactions } = useTreeItemUtils({ itemId: props.itemId, children: props.children, }); - const { publicAPI } = useTreeItem2(props); + const { publicAPI } = useTreeItem(props); const handleInputBlur = (event) => { event.defaultMuiPrevented = true; @@ -152,7 +152,7 @@ const CustomTreeItem2 = React.forwardRef(function CustomTreeItem2(props, ref) { }; return ( - ({ @@ -67,9 +63,9 @@ export const ITEMS: TreeViewBaseItem[] = [ }, ]; -function Label({ children, ...other }: UseTreeItem2LabelSlotOwnProps) { +function Label({ children, ...other }: UseTreeItemLabelSlotOwnProps) { return ( - {children} - + ); } -interface CustomLabelInputProps extends UseTreeItem2LabelInputSlotOwnProps { +interface CustomLabelInputProps extends UseTreeItemLabelInputSlotOwnProps { handleCancelItemLabelEditing: (event: React.SyntheticEvent) => void; handleSaveItemLabel: (event: React.SyntheticEvent, label: string) => void; item: TreeViewBaseItem; @@ -163,28 +159,28 @@ const LabelInput = React.forwardRef(function LabelInput( ); }); -const CustomTreeItem2 = React.forwardRef(function CustomTreeItem2( - props: TreeItem2Props, +const CustomTreeItem = React.forwardRef(function CustomTreeItem( + props: TreeItemProps, ref: React.Ref, ) { - const { interactions } = useTreeItem2Utils({ + const { interactions } = useTreeItemUtils({ itemId: props.itemId, children: props.children, }); - const { publicAPI } = useTreeItem2(props); + const { publicAPI } = useTreeItem(props); - const handleInputBlur: UseTreeItem2LabelInputSlotOwnProps['onBlur'] = (event) => { + const handleInputBlur: UseTreeItemLabelInputSlotOwnProps['onBlur'] = (event) => { event.defaultMuiPrevented = true; }; - const handleInputKeyDown: UseTreeItem2LabelInputSlotOwnProps['onKeyDown'] = ( + const handleInputKeyDown: UseTreeItemLabelInputSlotOwnProps['onKeyDown'] = ( event, ) => { event.defaultMuiPrevented = true; }; return ( - )} - + ); } @@ -43,7 +43,7 @@ function CustomLabelInput(props) { return ( - + void; @@ -32,7 +28,7 @@ function CustomLabel({ ...other }: CustomLabelProps) { return ( - )} - + ); } -interface CustomLabelInputProps extends UseTreeItem2LabelInputSlotOwnProps { +interface CustomLabelInputProps extends UseTreeItemLabelInputSlotOwnProps { handleCancelItemLabelEditing: (event: React.SyntheticEvent) => void; handleSaveItemLabel: (event: React.SyntheticEvent, label: string) => void; value: string; @@ -68,7 +64,7 @@ function CustomLabelInput(props: Omit) { return ( - + ) { ); } -const CustomTreeItem2 = React.forwardRef(function CustomTreeItem2( - props: TreeItem2Props, +const CustomTreeItem = React.forwardRef(function CustomTreeItem( + props: TreeItemProps, ref: React.Ref, ) { - const { interactions, status } = useTreeItem2Utils({ + const { interactions, status } = useTreeItemUtils({ itemId: props.itemId, children: props.children, }); - const handleContentDoubleClick: UseTreeItem2LabelSlotOwnProps['onDoubleClick'] = ( + const handleContentDoubleClick: UseTreeItemLabelSlotOwnProps['onDoubleClick'] = ( event, ) => { event.defaultMuiPrevented = true; }; - const handleInputBlur: UseTreeItem2LabelInputSlotOwnProps['onBlur'] = (event) => { + const handleInputBlur: UseTreeItemLabelInputSlotOwnProps['onBlur'] = (event) => { event.defaultMuiPrevented = true; }; - const handleInputKeyDown: UseTreeItem2LabelInputSlotOwnProps['onKeyDown'] = ( + const handleInputKeyDown: UseTreeItemLabelInputSlotOwnProps['onKeyDown'] = ( event, ) => { event.defaultMuiPrevented = true; }; return ( - - + {error ? ( @@ -34,9 +34,9 @@ function CustomLabelInput(props) { ); } -const CustomTreeItem2 = React.forwardRef(function CustomTreeItem2(props, ref) { +const CustomTreeItem = React.forwardRef(function CustomTreeItem(props, ref) { const [error, setError] = React.useState(null); - const { interactions } = useTreeItem2Utils({ + const { interactions } = useTreeItemUtils({ itemId: props.itemId, children: props.children, }); @@ -77,7 +77,7 @@ const CustomTreeItem2 = React.forwardRef(function CustomTreeItem2(props, ref) { }; return ( - ) { return ( - + {error ? ( @@ -38,12 +38,12 @@ function CustomLabelInput(props: Omit) { ); } -const CustomTreeItem2 = React.forwardRef(function CustomTreeItem2( - props: TreeItem2Props, +const CustomTreeItem = React.forwardRef(function CustomTreeItem( + props: TreeItemProps, ref: React.Ref, ) { const [error, setError] = React.useState(null); - const { interactions } = useTreeItem2Utils({ + const { interactions } = useTreeItemUtils({ itemId: props.itemId, children: props.children, }); @@ -57,13 +57,13 @@ const CustomTreeItem2 = React.forwardRef(function CustomTreeItem2( } }; - const handleInputBlur: UseTreeItem2LabelInputSlotOwnProps['onBlur'] = (event) => { + const handleInputBlur: UseTreeItemLabelInputSlotOwnProps['onBlur'] = (event) => { if (error) { event.defaultMuiPrevented = true; } }; - const handleInputKeyDown: UseTreeItem2LabelInputSlotOwnProps['onKeyDown'] = ( + const handleInputKeyDown: UseTreeItemLabelInputSlotOwnProps['onKeyDown'] = ( event, ) => { event.defaultMuiPrevented = true; @@ -86,7 +86,7 @@ const CustomTreeItem2 = React.forwardRef(function CustomTreeItem2( }; return ( - `. +To modify this behavior, use the `slotProps` of the Tree Item. {{"demo": "CustomBehavior.js"}} ## Validation -You can override the event handlers of the `labelInput` and implement a custom validation logic using the interaction methods from `useTreeItem2Utils`. +You can override the event handlers of the `labelInput` and implement a custom validation logic using the interaction methods from `useTreeItemUtils`. {{"demo": "Validation.js"}} diff --git a/docs/data/tree-view/rich-tree-view/focus/focus.md b/docs/data/tree-view/rich-tree-view/focus/focus.md index a293e75b0d20..9a23786173ea 100644 --- a/docs/data/tree-view/rich-tree-view/focus/focus.md +++ b/docs/data/tree-view/rich-tree-view/focus/focus.md @@ -41,7 +41,7 @@ apiRef.current.focusItem( :::info This method only works with items that are currently visible. -Calling `apiRef.focusItem` on an item whose parent is collapsed will do nothing. +Calling `apiRef.focusItem()` on an item whose parent is collapsed does nothing. ::: {{"demo": "ApiMethodFocusItem.js"}} diff --git a/docs/data/tree-view/rich-tree-view/items/items.md b/docs/data/tree-view/rich-tree-view/items/items.md index 964ee3b266f2..49db9da0a4e2 100644 --- a/docs/data/tree-view/rich-tree-view/items/items.md +++ b/docs/data/tree-view/rich-tree-view/items/items.md @@ -179,7 +179,7 @@ const item = apiRef.current.getItem( ### Get an item's DOM element by ID -Use the `getItemDOMElement` API method to get an item's DOM element by its ID. +Use the `getItemDOMElement()` API method to get an item's DOM element by its ID. ```ts const itemElement = apiRef.current.getItemDOMElement( diff --git a/docs/data/tree-view/rich-tree-view/ordering/FileExplorer.js b/docs/data/tree-view/rich-tree-view/ordering/FileExplorer.js index 9a05f402be2c..423926095ed7 100644 --- a/docs/data/tree-view/rich-tree-view/ordering/FileExplorer.js +++ b/docs/data/tree-view/rich-tree-view/ordering/FileExplorer.js @@ -10,19 +10,19 @@ import ImageIcon from '@mui/icons-material/Image'; import PictureAsPdfIcon from '@mui/icons-material/PictureAsPdf'; import VideoCameraBackIcon from '@mui/icons-material/VideoCameraBack'; import { RichTreeViewPro } from '@mui/x-tree-view-pro/RichTreeViewPro'; -import { treeItemClasses } from '@mui/x-tree-view/TreeItem'; -import { useTreeItem2 } from '@mui/x-tree-view/useTreeItem2'; +import { useTreeItem } from '@mui/x-tree-view/useTreeItem'; import { - TreeItem2Checkbox, - TreeItem2Content, - TreeItem2IconContainer, - TreeItem2Label, - TreeItem2Root, - TreeItem2GroupTransition, -} from '@mui/x-tree-view/TreeItem2'; -import { TreeItem2Icon } from '@mui/x-tree-view/TreeItem2Icon'; -import { TreeItem2Provider } from '@mui/x-tree-view/TreeItem2Provider'; -import { TreeItem2DragAndDropOverlay } from '@mui/x-tree-view/TreeItem2DragAndDropOverlay'; + TreeItemCheckbox, + TreeItemContent, + TreeItemIconContainer, + TreeItemLabel, + TreeItemRoot, + TreeItemGroupTransition, + treeItemClasses, +} from '@mui/x-tree-view/TreeItem'; +import { TreeItemIcon } from '@mui/x-tree-view/TreeItemIcon'; +import { TreeItemProvider } from '@mui/x-tree-view/TreeItemProvider'; +import { TreeItemDragAndDropOverlay } from '@mui/x-tree-view/TreeItemDragAndDropOverlay'; import { useTreeViewApiRef } from '@mui/x-tree-view/hooks'; @@ -80,7 +80,7 @@ function DotIcon() { ); } -const StyledTreeItemRoot = styled(TreeItem2Root)(({ theme }) => ({ +const StyledTreeItemRoot = styled(TreeItemRoot)(({ theme }) => ({ color: theme.palette.grey[400], position: 'relative', [`& .${treeItemClasses.groupTransition}`]: { @@ -90,7 +90,7 @@ const StyledTreeItemRoot = styled(TreeItem2Root)(({ theme }) => ({ color: theme.palette.grey[800], }), })); -const CustomTreeItemContent = styled(TreeItem2Content)(({ theme }) => ({ +const CustomTreeItemContent = styled(TreeItemContent)(({ theme }) => ({ flexDirection: 'row-reverse', borderRadius: theme.spacing(0.7), marginBottom: theme.spacing(0.5), @@ -142,7 +142,7 @@ const StyledTreeItemLabelText = styled(Typography)({ function CustomLabel({ icon: Icon, expandable, children, ...other }) { return ( - {children} {expandable && } - + ); } @@ -203,14 +203,14 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem(props, ref) { getDragAndDropOverlayProps, status, publicAPI, - } = useTreeItem2({ id, itemId, children, label, disabled, rootRef: ref }); + } = useTreeItem({ id, itemId, children, label, disabled, rootRef: ref }); const item = publicAPI.getItem(itemId); const expandable = isExpandable(children); const icon = getIconFromFileType(item.fileType); return ( - + - - - - + + + + - + - {children && } + {children && } - + ); }); diff --git a/docs/data/tree-view/rich-tree-view/ordering/FileExplorer.tsx b/docs/data/tree-view/rich-tree-view/ordering/FileExplorer.tsx index f555c2afd64b..5f5a0434956b 100644 --- a/docs/data/tree-view/rich-tree-view/ordering/FileExplorer.tsx +++ b/docs/data/tree-view/rich-tree-view/ordering/FileExplorer.tsx @@ -10,19 +10,19 @@ import ImageIcon from '@mui/icons-material/Image'; import PictureAsPdfIcon from '@mui/icons-material/PictureAsPdf'; import VideoCameraBackIcon from '@mui/icons-material/VideoCameraBack'; import { RichTreeViewPro } from '@mui/x-tree-view-pro/RichTreeViewPro'; -import { treeItemClasses } from '@mui/x-tree-view/TreeItem'; -import { useTreeItem2, UseTreeItem2Parameters } from '@mui/x-tree-view/useTreeItem2'; +import { useTreeItem, UseTreeItemParameters } from '@mui/x-tree-view/useTreeItem'; import { - TreeItem2Checkbox, - TreeItem2Content, - TreeItem2IconContainer, - TreeItem2Label, - TreeItem2Root, - TreeItem2GroupTransition, -} from '@mui/x-tree-view/TreeItem2'; -import { TreeItem2Icon } from '@mui/x-tree-view/TreeItem2Icon'; -import { TreeItem2Provider } from '@mui/x-tree-view/TreeItem2Provider'; -import { TreeItem2DragAndDropOverlay } from '@mui/x-tree-view/TreeItem2DragAndDropOverlay'; + TreeItemCheckbox, + TreeItemContent, + TreeItemIconContainer, + TreeItemLabel, + TreeItemRoot, + TreeItemGroupTransition, + treeItemClasses, +} from '@mui/x-tree-view/TreeItem'; +import { TreeItemIcon } from '@mui/x-tree-view/TreeItemIcon'; +import { TreeItemProvider } from '@mui/x-tree-view/TreeItemProvider'; +import { TreeItemDragAndDropOverlay } from '@mui/x-tree-view/TreeItemDragAndDropOverlay'; import { TreeViewBaseItem } from '@mui/x-tree-view/models'; import { useTreeViewApiRef } from '@mui/x-tree-view/hooks'; @@ -94,7 +94,7 @@ declare module 'react' { } } -const StyledTreeItemRoot = styled(TreeItem2Root)(({ theme }) => ({ +const StyledTreeItemRoot = styled(TreeItemRoot)(({ theme }) => ({ color: theme.palette.grey[400], position: 'relative', [`& .${treeItemClasses.groupTransition}`]: { @@ -103,8 +103,8 @@ const StyledTreeItemRoot = styled(TreeItem2Root)(({ theme }) => ({ ...theme.applyStyles('light', { color: theme.palette.grey[800], }), -})) as unknown as typeof TreeItem2Root; -const CustomTreeItemContent = styled(TreeItem2Content)(({ theme }) => ({ +})) as unknown as typeof TreeItemRoot; +const CustomTreeItemContent = styled(TreeItemContent)(({ theme }) => ({ flexDirection: 'row-reverse', borderRadius: theme.spacing(0.7), marginBottom: theme.spacing(0.5), @@ -167,7 +167,7 @@ function CustomLabel({ ...other }: CustomLabelProps) { return ( - {children} {expandable && } - + ); } @@ -216,7 +216,7 @@ const getIconFromFileType = (fileType: FileType) => { }; interface CustomTreeItemProps - extends Omit, + extends Omit, Omit, 'onFocus'> {} const CustomTreeItem = React.forwardRef(function CustomTreeItem( @@ -235,14 +235,14 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem( getDragAndDropOverlayProps, status, publicAPI, - } = useTreeItem2({ id, itemId, children, label, disabled, rootRef: ref }); + } = useTreeItem({ id, itemId, children, label, disabled, rootRef: ref }); const item = publicAPI.getItem(itemId); const expandable = isExpandable(children); const icon = getIconFromFileType(item.fileType); return ( - + - - - - + + + + - + - {children && } + {children && } - + ); }); diff --git a/docs/data/tree-view/rich-tree-view/ordering/OnlyReorderFromDragHandle.js b/docs/data/tree-view/rich-tree-view/ordering/OnlyReorderFromDragHandle.js index c9f03403a38f..500411bd806c 100644 --- a/docs/data/tree-view/rich-tree-view/ordering/OnlyReorderFromDragHandle.js +++ b/docs/data/tree-view/rich-tree-view/ordering/OnlyReorderFromDragHandle.js @@ -3,18 +3,18 @@ import Box from '@mui/material/Box'; import DragIndicatorIcon from '@mui/icons-material/DragIndicator'; import { RichTreeViewPro } from '@mui/x-tree-view-pro/RichTreeViewPro'; -import { useTreeItem2 } from '@mui/x-tree-view/useTreeItem2'; +import { useTreeItem } from '@mui/x-tree-view/useTreeItem'; import { - TreeItem2Content, - TreeItem2IconContainer, - TreeItem2GroupTransition, - TreeItem2Label, - TreeItem2Root, - TreeItem2Checkbox, -} from '@mui/x-tree-view/TreeItem2'; -import { TreeItem2Icon } from '@mui/x-tree-view/TreeItem2Icon'; -import { TreeItem2Provider } from '@mui/x-tree-view/TreeItem2Provider'; -import { TreeItem2DragAndDropOverlay } from '@mui/x-tree-view/TreeItem2DragAndDropOverlay'; + TreeItemContent, + TreeItemIconContainer, + TreeItemGroupTransition, + TreeItemLabel, + TreeItemRoot, + TreeItemCheckbox, +} from '@mui/x-tree-view/TreeItem'; +import { TreeItemIcon } from '@mui/x-tree-view/TreeItemIcon'; +import { TreeItemProvider } from '@mui/x-tree-view/TreeItemProvider'; +import { TreeItemDragAndDropOverlay } from '@mui/x-tree-view/TreeItemDragAndDropOverlay'; const MUI_X_PRODUCTS = [ { @@ -58,7 +58,7 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem(props, ref) { getGroupTransitionProps, getDragAndDropOverlayProps, status, - } = useTreeItem2({ id, itemId, children, label, disabled, rootRef: ref }); + } = useTreeItem({ id, itemId, children, label, disabled, rootRef: ref }); const { draggable, onDragStart, onDragOver, onDragEnd, ...otherRootProps } = getRootProps(other); @@ -73,27 +73,27 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem(props, ref) { }; return ( - - - - - - - + + + + + + - - - - - - {children && } - - + + + + + + {children && } + + ); }); diff --git a/docs/data/tree-view/rich-tree-view/ordering/OnlyReorderFromDragHandle.tsx b/docs/data/tree-view/rich-tree-view/ordering/OnlyReorderFromDragHandle.tsx index 8780d381c49b..8b0395890c15 100644 --- a/docs/data/tree-view/rich-tree-view/ordering/OnlyReorderFromDragHandle.tsx +++ b/docs/data/tree-view/rich-tree-view/ordering/OnlyReorderFromDragHandle.tsx @@ -3,18 +3,18 @@ import Box from '@mui/material/Box'; import DragIndicatorIcon from '@mui/icons-material/DragIndicator'; import { RichTreeViewPro } from '@mui/x-tree-view-pro/RichTreeViewPro'; import { TreeViewBaseItem } from '@mui/x-tree-view/models'; -import { useTreeItem2, UseTreeItem2Parameters } from '@mui/x-tree-view/useTreeItem2'; +import { useTreeItem, UseTreeItemParameters } from '@mui/x-tree-view/useTreeItem'; import { - TreeItem2Content, - TreeItem2IconContainer, - TreeItem2GroupTransition, - TreeItem2Label, - TreeItem2Root, - TreeItem2Checkbox, -} from '@mui/x-tree-view/TreeItem2'; -import { TreeItem2Icon } from '@mui/x-tree-view/TreeItem2Icon'; -import { TreeItem2Provider } from '@mui/x-tree-view/TreeItem2Provider'; -import { TreeItem2DragAndDropOverlay } from '@mui/x-tree-view/TreeItem2DragAndDropOverlay'; + TreeItemContent, + TreeItemIconContainer, + TreeItemGroupTransition, + TreeItemLabel, + TreeItemRoot, + TreeItemCheckbox, +} from '@mui/x-tree-view/TreeItem'; +import { TreeItemIcon } from '@mui/x-tree-view/TreeItemIcon'; +import { TreeItemProvider } from '@mui/x-tree-view/TreeItemProvider'; +import { TreeItemDragAndDropOverlay } from '@mui/x-tree-view/TreeItemDragAndDropOverlay'; const MUI_X_PRODUCTS: TreeViewBaseItem[] = [ { @@ -47,7 +47,7 @@ const MUI_X_PRODUCTS: TreeViewBaseItem[] = [ ]; interface CustomTreeItemProps - extends Omit, + extends Omit, Omit, 'onFocus'> {} const CustomTreeItem = React.forwardRef(function CustomTreeItem( @@ -65,7 +65,7 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem( getGroupTransitionProps, getDragAndDropOverlayProps, status, - } = useTreeItem2({ id, itemId, children, label, disabled, rootRef: ref }); + } = useTreeItem({ id, itemId, children, label, disabled, rootRef: ref }); const { draggable, onDragStart, onDragOver, onDragEnd, ...otherRootProps } = getRootProps(other); @@ -84,27 +84,27 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem( }; return ( - - - - - - - + + + + + + - - - - - - {children && } - - + + + + + + {children && } + + ); }); diff --git a/docs/data/tree-view/rich-tree-view/ordering/ordering.md b/docs/data/tree-view/rich-tree-view/ordering/ordering.md index 891f3588e634..be62d10fd51b 100644 --- a/docs/data/tree-view/rich-tree-view/ordering/ordering.md +++ b/docs/data/tree-view/rich-tree-view/ordering/ordering.md @@ -1,7 +1,7 @@ --- productId: x-tree-view title: Rich Tree View - Ordering -components: TreeItem2, TreeItem, RichTreeViewPro +components: TreeItem, RichTreeViewPro, TreeItemDragAndDropOverlay packageName: '@mui/x-tree-view' githubLabel: 'component: tree view' waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/treeview/ diff --git a/docs/data/tree-view/rich-tree-view/selection/SelectionPropagation.js b/docs/data/tree-view/rich-tree-view/selection/SelectionPropagation.js new file mode 100644 index 000000000000..2c54a087f326 --- /dev/null +++ b/docs/data/tree-view/rich-tree-view/selection/SelectionPropagation.js @@ -0,0 +1,59 @@ +import * as React from 'react'; +import FormControlLabel from '@mui/material/FormControlLabel'; +import Checkbox from '@mui/material/Checkbox'; +import Stack from '@mui/material/Stack'; +import Box from '@mui/material/Box'; +import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; + +import { EMPLOYEES_DATASET } from '../../datasets/employees'; + +export default function SelectionPropagation() { + const [selectionPropagation, setSelectionPropagation] = React.useState({ + parents: true, + descendants: true, + }); + + return ( +
+ + + setSelectionPropagation((prev) => ({ + ...prev, + descendants: event.target.checked, + })) + } + /> + } + label="Auto select descendants" + /> + + setSelectionPropagation((prev) => ({ + ...prev, + parents: event.target.checked, + })) + } + /> + } + label="Auto select parents" + /> + + + + +
+ ); +} diff --git a/docs/data/tree-view/rich-tree-view/selection/SelectionPropagation.tsx b/docs/data/tree-view/rich-tree-view/selection/SelectionPropagation.tsx new file mode 100644 index 000000000000..c41780b8fb9c --- /dev/null +++ b/docs/data/tree-view/rich-tree-view/selection/SelectionPropagation.tsx @@ -0,0 +1,60 @@ +import * as React from 'react'; +import FormControlLabel from '@mui/material/FormControlLabel'; +import Checkbox from '@mui/material/Checkbox'; +import Stack from '@mui/material/Stack'; +import Box from '@mui/material/Box'; +import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; +import { TreeViewSelectionPropagation } from '@mui/x-tree-view/models'; +import { EMPLOYEES_DATASET } from '../../datasets/employees'; + +export default function SelectionPropagation() { + const [selectionPropagation, setSelectionPropagation] = + React.useState({ + parents: true, + descendants: true, + }); + + return ( +
+ + + setSelectionPropagation((prev) => ({ + ...prev, + descendants: event.target.checked, + })) + } + /> + } + label="Auto select descendants" + /> + + setSelectionPropagation((prev) => ({ + ...prev, + parents: event.target.checked, + })) + } + /> + } + label="Auto select parents" + /> + + + + +
+ ); +} diff --git a/docs/data/tree-view/rich-tree-view/selection/selection.md b/docs/data/tree-view/rich-tree-view/selection/selection.md index 2175d7ad3978..02036050d502 100644 --- a/docs/data/tree-view/rich-tree-view/selection/selection.md +++ b/docs/data/tree-view/rich-tree-view/selection/selection.md @@ -75,25 +75,36 @@ Use the `onItemSelectionToggle` prop if you want to react to an item selection c {{"demo": "TrackItemSelectionToggle.js"}} -## Parent / children selection relationship +## Automatic parents and children selection -Automatically select an item when all of its children are selected and automatically select all children when the parent is selected. +By default, selecting a parent item does not select its children. You can override this behavior using the `selectionPropagation` prop. -:::warning -This feature isn't implemented yet. It's coming. +Here's how it's structured: -👍 Upvote [issue #4821](https://github.com/mui/mui-x/issues/4821) if you want to see it land faster. +```ts +type TreeViewSelectionPropagation = { + descendants?: boolean; // default: false + parents?: boolean; // default: false +}; +``` -Don't hesitate to leave a comment on the same issue to influence what gets built. -Especially if you already have a use case for this component, -or if you are facing a pain point with your current solution. -::: +When `selectionPropagation.descendants` is set to `true`. + +- Selecting a parent selects all its descendants automatically. +- Deselecting a parent deselects all its descendants automatically. -If you cannot wait for the official implementation, -you can create your own custom solution using the `selectedItems`, -`onSelectedItemsChange` and `onItemSelectionToggle` props: +When `selectionPropagation.parents` is set to `true`. -{{"demo": "ParentChildrenSelectionRelationship.js"}} +- Selecting all the descendants of a parent selects the parent automatically. +- Deselecting a descendant of a selected parent deselects the parent automatically. + +The example below demonstrates the usage of the `selectionPropagation` prop. + +{{"demo": "SelectionPropagation.js", "defaultCodeOpen": false}} + +:::warning +This feature only works when multi selection is enabled using `props.multiSelect`. +::: ## Imperative API @@ -106,13 +117,13 @@ const apiRef = useTreeViewApiRef(); return ; ``` -When your component first renders, `apiRef` will be `undefined`. +When your component first renders, `apiRef` is `undefined`. After this initial render, `apiRef` holds methods to interact imperatively with the Tree View. ::: ### Select or deselect an item -Use the `selectItem` API method to select or deselect an item: +Use the `selectItem()` API method to select or deselect an item: ```ts apiRef.current.selectItem({ diff --git a/docs/data/tree-view/simple-tree-view/customization/GmailTreeView.js b/docs/data/tree-view/simple-tree-view/customization/GmailTreeView.js index 7dc64dbbe9b0..b12875731714 100644 --- a/docs/data/tree-view/simple-tree-view/customization/GmailTreeView.js +++ b/docs/data/tree-view/simple-tree-view/customization/GmailTreeView.js @@ -15,20 +15,20 @@ import ArrowRightIcon from '@mui/icons-material/ArrowRight'; import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView'; import { - TreeItem2Content, - TreeItem2IconContainer, - TreeItem2Root, - TreeItem2GroupTransition, -} from '@mui/x-tree-view/TreeItem2'; -import { useTreeItem2 } from '@mui/x-tree-view/useTreeItem2'; -import { TreeItem2Provider } from '@mui/x-tree-view/TreeItem2Provider'; -import { TreeItem2Icon } from '@mui/x-tree-view/TreeItem2Icon'; + TreeItemContent, + TreeItemIconContainer, + TreeItemRoot, + TreeItemGroupTransition, +} from '@mui/x-tree-view/TreeItem'; +import { useTreeItem } from '@mui/x-tree-view/useTreeItem'; +import { TreeItemProvider } from '@mui/x-tree-view/TreeItemProvider'; +import { TreeItemIcon } from '@mui/x-tree-view/TreeItemIcon'; -const CustomTreeItemRoot = styled(TreeItem2Root)(({ theme }) => ({ +const CustomTreeItemRoot = styled(TreeItemRoot)(({ theme }) => ({ color: theme.palette.text.secondary, })); -const CustomTreeItemContent = styled(TreeItem2Content)(({ theme }) => ({ +const CustomTreeItemContent = styled(TreeItemContent)(({ theme }) => ({ marginBottom: theme.spacing(0.3), color: theme.palette.text.secondary, borderRadius: theme.spacing(2), @@ -46,11 +46,11 @@ const CustomTreeItemContent = styled(TreeItem2Content)(({ theme }) => ({ }, })); -const CustomTreeItemIconContainer = styled(TreeItem2IconContainer)(({ theme }) => ({ +const CustomTreeItemIconContainer = styled(TreeItemIconContainer)(({ theme }) => ({ marginRight: theme.spacing(1), })); -const CustomTreeItemGroupTransition = styled(TreeItem2GroupTransition)( +const CustomTreeItemGroupTransition = styled(TreeItemGroupTransition)( ({ theme }) => ({ marginLeft: 0, [`& .content`]: { @@ -83,7 +83,7 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem(props, ref) { getLabelProps, getGroupTransitionProps, status, - } = useTreeItem2({ id, itemId, children, label, disabled, rootRef: ref }); + } = useTreeItem({ id, itemId, children, label, disabled, rootRef: ref }); const style = { '--tree-view-color': theme.palette.mode !== 'dark' ? color : colorForDarkMode, @@ -92,7 +92,7 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem(props, ref) { }; return ( - + - + )} - + ); }); diff --git a/docs/data/tree-view/simple-tree-view/customization/GmailTreeView.tsx b/docs/data/tree-view/simple-tree-view/customization/GmailTreeView.tsx index 88d4d92db453..c2c669a25182 100644 --- a/docs/data/tree-view/simple-tree-view/customization/GmailTreeView.tsx +++ b/docs/data/tree-view/simple-tree-view/customization/GmailTreeView.tsx @@ -15,14 +15,14 @@ import ArrowRightIcon from '@mui/icons-material/ArrowRight'; import { SvgIconProps } from '@mui/material/SvgIcon'; import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView'; import { - TreeItem2Content, - TreeItem2IconContainer, - TreeItem2Root, - TreeItem2GroupTransition, -} from '@mui/x-tree-view/TreeItem2'; -import { useTreeItem2, UseTreeItem2Parameters } from '@mui/x-tree-view/useTreeItem2'; -import { TreeItem2Provider } from '@mui/x-tree-view/TreeItem2Provider'; -import { TreeItem2Icon } from '@mui/x-tree-view/TreeItem2Icon'; + TreeItemContent, + TreeItemIconContainer, + TreeItemRoot, + TreeItemGroupTransition, +} from '@mui/x-tree-view/TreeItem'; +import { useTreeItem, UseTreeItemParameters } from '@mui/x-tree-view/useTreeItem'; +import { TreeItemProvider } from '@mui/x-tree-view/TreeItemProvider'; +import { TreeItemIcon } from '@mui/x-tree-view/TreeItemIcon'; declare module 'react' { interface CSSProperties { @@ -32,7 +32,7 @@ declare module 'react' { } interface StyledTreeItemProps - extends Omit, + extends Omit, React.HTMLAttributes { bgColor?: string; bgColorForDarkMode?: string; @@ -42,11 +42,11 @@ interface StyledTreeItemProps labelInfo?: string; } -const CustomTreeItemRoot = styled(TreeItem2Root)(({ theme }) => ({ +const CustomTreeItemRoot = styled(TreeItemRoot)(({ theme }) => ({ color: theme.palette.text.secondary, })); -const CustomTreeItemContent = styled(TreeItem2Content)(({ theme }) => ({ +const CustomTreeItemContent = styled(TreeItemContent)(({ theme }) => ({ marginBottom: theme.spacing(0.3), color: theme.palette.text.secondary, borderRadius: theme.spacing(2), @@ -64,11 +64,11 @@ const CustomTreeItemContent = styled(TreeItem2Content)(({ theme }) => ({ }, })); -const CustomTreeItemIconContainer = styled(TreeItem2IconContainer)(({ theme }) => ({ +const CustomTreeItemIconContainer = styled(TreeItemIconContainer)(({ theme }) => ({ marginRight: theme.spacing(1), })); -const CustomTreeItemGroupTransition = styled(TreeItem2GroupTransition)( +const CustomTreeItemGroupTransition = styled(TreeItemGroupTransition)( ({ theme }) => ({ marginLeft: 0, [`& .content`]: { @@ -104,7 +104,7 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem( getLabelProps, getGroupTransitionProps, status, - } = useTreeItem2({ id, itemId, children, label, disabled, rootRef: ref }); + } = useTreeItem({ id, itemId, children, label, disabled, rootRef: ref }); const style = { '--tree-view-color': theme.palette.mode !== 'dark' ? color : colorForDarkMode, @@ -113,7 +113,7 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem( }; return ( - + - + )} - + ); }); diff --git a/docs/data/tree-view/simple-tree-view/customization/HeadlessAPI.js b/docs/data/tree-view/simple-tree-view/customization/HeadlessAPI.js index c6e201274016..b8af5dff4380 100644 --- a/docs/data/tree-view/simple-tree-view/customization/HeadlessAPI.js +++ b/docs/data/tree-view/simple-tree-view/customization/HeadlessAPI.js @@ -3,19 +3,19 @@ import { styled } from '@mui/material/styles'; import Box from '@mui/material/Box'; import Avatar from '@mui/material/Avatar'; import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView'; -import { useTreeItem2 } from '@mui/x-tree-view/useTreeItem2'; +import { useTreeItem } from '@mui/x-tree-view/useTreeItem'; import { - TreeItem2Content, - TreeItem2IconContainer, - TreeItem2GroupTransition, - TreeItem2Label, - TreeItem2Root, - TreeItem2Checkbox, -} from '@mui/x-tree-view/TreeItem2'; -import { TreeItem2Icon } from '@mui/x-tree-view/TreeItem2Icon'; -import { TreeItem2Provider } from '@mui/x-tree-view/TreeItem2Provider'; + TreeItemContent, + TreeItemIconContainer, + TreeItemGroupTransition, + TreeItemLabel, + TreeItemRoot, + TreeItemCheckbox, +} from '@mui/x-tree-view/TreeItem'; +import { TreeItemIcon } from '@mui/x-tree-view/TreeItemIcon'; +import { TreeItemProvider } from '@mui/x-tree-view/TreeItemProvider'; -const CustomTreeItemContent = styled(TreeItem2Content)(({ theme }) => ({ +const CustomTreeItemContent = styled(TreeItemContent)(({ theme }) => ({ padding: theme.spacing(0.5, 1), })); @@ -30,16 +30,16 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem(props, ref) { getLabelProps, getGroupTransitionProps, status, - } = useTreeItem2({ id, itemId, children, label, disabled, rootRef: ref }); + } = useTreeItem({ id, itemId, children, label, disabled, rootRef: ref }); return ( - - + + - - - - + + + + ({ @@ -51,12 +51,12 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem(props, ref) { > {label[0]} - + - {children && } - - + {children && } + + ); }); diff --git a/docs/data/tree-view/simple-tree-view/customization/HeadlessAPI.tsx b/docs/data/tree-view/simple-tree-view/customization/HeadlessAPI.tsx index a2e9d06a5714..42d5fa6e3768 100644 --- a/docs/data/tree-view/simple-tree-view/customization/HeadlessAPI.tsx +++ b/docs/data/tree-view/simple-tree-view/customization/HeadlessAPI.tsx @@ -3,24 +3,24 @@ import { styled } from '@mui/material/styles'; import Box from '@mui/material/Box'; import Avatar from '@mui/material/Avatar'; import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView'; -import { useTreeItem2, UseTreeItem2Parameters } from '@mui/x-tree-view/useTreeItem2'; +import { useTreeItem, UseTreeItemParameters } from '@mui/x-tree-view/useTreeItem'; import { - TreeItem2Content, - TreeItem2IconContainer, - TreeItem2GroupTransition, - TreeItem2Label, - TreeItem2Root, - TreeItem2Checkbox, -} from '@mui/x-tree-view/TreeItem2'; -import { TreeItem2Icon } from '@mui/x-tree-view/TreeItem2Icon'; -import { TreeItem2Provider } from '@mui/x-tree-view/TreeItem2Provider'; + TreeItemContent, + TreeItemIconContainer, + TreeItemGroupTransition, + TreeItemLabel, + TreeItemRoot, + TreeItemCheckbox, +} from '@mui/x-tree-view/TreeItem'; +import { TreeItemIcon } from '@mui/x-tree-view/TreeItemIcon'; +import { TreeItemProvider } from '@mui/x-tree-view/TreeItemProvider'; -const CustomTreeItemContent = styled(TreeItem2Content)(({ theme }) => ({ +const CustomTreeItemContent = styled(TreeItemContent)(({ theme }) => ({ padding: theme.spacing(0.5, 1), })); interface CustomTreeItemProps - extends Omit, + extends Omit, Omit, 'onFocus'> {} const CustomTreeItem = React.forwardRef(function CustomTreeItem( @@ -37,16 +37,16 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem( getLabelProps, getGroupTransitionProps, status, - } = useTreeItem2({ id, itemId, children, label, disabled, rootRef: ref }); + } = useTreeItem({ id, itemId, children, label, disabled, rootRef: ref }); return ( - - + + - - - - + + + + ({ @@ -58,12 +58,12 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem( > {(label as string)[0]} - + - {children && } - - + {children && } + + ); }); diff --git a/docs/data/tree-view/simple-tree-view/customization/customization.md b/docs/data/tree-view/simple-tree-view/customization/customization.md index 26da29b34139..641136df7b94 100644 --- a/docs/data/tree-view/simple-tree-view/customization/customization.md +++ b/docs/data/tree-view/simple-tree-view/customization/customization.md @@ -1,7 +1,7 @@ --- productId: x-tree-view title: Simple Tree View - Customization -components: SimpleTreeView, TreeItem, TreeItem2 +components: SimpleTreeView, TreeItem packageName: '@mui/x-tree-view' githubLabel: 'component: tree view' waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/treeview/ @@ -12,7 +12,7 @@ waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/treeview/

Learn how to customize the Simple Tree View component.

:::success -See [Common concepts—Custom slots and subcomponents](/x/common-concepts/custom-components/) to learn how to use slots. +See [Common concepts—Slots and subcomponents](/x/common-concepts/custom-components/) to learn how to use slots. ::: ## Basics @@ -46,7 +46,7 @@ Learn more about the anatomy of the Tree Items and the customization utilities p ### Headless API -Use the `useTreeItem2` hook to create your own component. +Use the `useTreeItem` hook to create your own component. The demo below shows how to add an avatar and custom typography elements. {{"demo": "HeadlessAPI.js", "defaultCodeOpen": false}} @@ -61,13 +61,6 @@ Target the `treeItemClasses.groupTransition` class to add connection borders bet ### Gmail clone -:::warning -This example is built using the new `` component -which adds several slots to modify the content of the Tree Item or change its behavior. - -You can learn more about this new component in the [Overview page](/x/react-tree-view/#tree-item-components). -::: - Google's Gmail side nav is potentially one of the web's most famous tree view components. The demo below shows how to replicate it. diff --git a/docs/data/tree-view/simple-tree-view/focus/focus.md b/docs/data/tree-view/simple-tree-view/focus/focus.md index ef9cd7d5558e..8cc4576f617e 100644 --- a/docs/data/tree-view/simple-tree-view/focus/focus.md +++ b/docs/data/tree-view/simple-tree-view/focus/focus.md @@ -41,7 +41,7 @@ apiRef.current.focusItem( :::info This method only works with items that are currently visible. -Calling `apiRef.focusItem` on an item whose parent is collapsed will do nothing. +Calling `apiRef.focusItem()` on an item whose parent is collapsed does nothing. ::: {{"demo": "ApiMethodFocusItem.js"}} diff --git a/docs/data/tree-view/simple-tree-view/items/items.md b/docs/data/tree-view/simple-tree-view/items/items.md index 6c1bc4f06e64..cd516f83665a 100644 --- a/docs/data/tree-view/simple-tree-view/items/items.md +++ b/docs/data/tree-view/simple-tree-view/items/items.md @@ -91,13 +91,13 @@ const apiRef = useTreeViewApiRef(); return {children}; ``` -When your component first renders, `apiRef` will be `undefined`. +When your component first renders, `apiRef` is `undefined`. After this initial render, `apiRef` holds methods to interact imperatively with the Tree View. ::: ### Get an item's DOM element by ID -Use the `getItemDOMElement` API method to get an item's DOM element by its ID. +Use the `getItemDOMElement()` API method to get an item's DOM element by its ID. ```ts const itemElement = apiRef.current.getItemDOMElement( diff --git a/docs/data/tree-view/simple-tree-view/selection/selection.md b/docs/data/tree-view/simple-tree-view/selection/selection.md index aceb02cb7215..c9f44a4e63ef 100644 --- a/docs/data/tree-view/simple-tree-view/selection/selection.md +++ b/docs/data/tree-view/simple-tree-view/selection/selection.md @@ -91,7 +91,7 @@ After this initial render, `apiRef` holds methods to interact imperatively with ### Select or deselect an item -Use the `selectItem` API method to select or deselect an item: +Use the `selectItem()` API method to select or deselect an item: ```ts apiRef.current.selectItem({ diff --git a/docs/data/tree-view/tree-item-customization/CheckboxSlot.js b/docs/data/tree-view/tree-item-customization/CheckboxSlot.js index 81245357631e..fe14e7b79ae3 100644 --- a/docs/data/tree-view/tree-item-customization/CheckboxSlot.js +++ b/docs/data/tree-view/tree-item-customization/CheckboxSlot.js @@ -1,7 +1,7 @@ import * as React from 'react'; import Box from '@mui/material/Box'; import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; -import { TreeItem2 } from '@mui/x-tree-view/TreeItem2'; +import { TreeItem } from '@mui/x-tree-view/TreeItem'; import { MUI_X_PRODUCTS } from './products'; const CustomCheckbox = React.forwardRef(function CustomCheckbox(props, ref) { @@ -10,7 +10,7 @@ const CustomCheckbox = React.forwardRef(function CustomCheckbox(props, ref) { const CustomTreeItem = React.forwardRef(function CustomTreeItem(props, ref) { return ( - , ) { return ( - , ) { return ( - , checkedIcon: , }, - } as TreeItem2SlotProps + } as TreeItemSlotProps } /> ); diff --git a/docs/data/tree-view/tree-item-customization/ContentSlot.js b/docs/data/tree-view/tree-item-customization/ContentSlot.js index 78857c927c61..5404af12ac70 100644 --- a/docs/data/tree-view/tree-item-customization/ContentSlot.js +++ b/docs/data/tree-view/tree-item-customization/ContentSlot.js @@ -2,7 +2,7 @@ import * as React from 'react'; import { alpha, styled } from '@mui/material/styles'; import Stack from '@mui/material/Stack'; import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; -import { TreeItem2 } from '@mui/x-tree-view/TreeItem2'; +import { TreeItem } from '@mui/x-tree-view/TreeItem'; import { MUI_X_PRODUCTS } from './products'; @@ -34,7 +34,7 @@ const CustomContent = styled('div')(({ theme }) => ({ const CustomTreeItem = React.forwardRef(function CustomTreeItem(props, ref) { return ( - ({ @@ -17,14 +17,14 @@ const CustomContent = styled('div')(({ theme }) => ({ }, variants: [ { - props: ({ status }: UseTreeItem2ContentSlotOwnProps) => status.disabled, + props: ({ status }: UseTreeItemContentSlotOwnProps) => status.disabled, style: { opacity: 0.5, backgroundColor: theme.palette.action.disabledBackground, }, }, { - props: ({ status }: UseTreeItem2ContentSlotOwnProps) => status.selected, + props: ({ status }: UseTreeItemContentSlotOwnProps) => status.selected, style: { backgroundColor: alpha((theme.vars || theme).palette.primary.main, 0.4), }, @@ -33,11 +33,11 @@ const CustomContent = styled('div')(({ theme }) => ({ })); const CustomTreeItem = React.forwardRef(function CustomTreeItem( - props: TreeItem2Props, + props: TreeItemProps, ref: React.Ref, ) { return ( - , ) { return ( - ); diff --git a/docs/data/tree-view/tree-item-customization/CustomTreeItemDemo.js b/docs/data/tree-view/tree-item-customization/CustomTreeItemDemo.js index b5e9421b1df5..785462f87910 100644 --- a/docs/data/tree-view/tree-item-customization/CustomTreeItemDemo.js +++ b/docs/data/tree-view/tree-item-customization/CustomTreeItemDemo.js @@ -5,19 +5,19 @@ import Popover from '@mui/material/Popover'; import Typography from '@mui/material/Typography'; import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; -import { useTreeItem2 } from '@mui/x-tree-view/useTreeItem2'; +import { useTreeItem } from '@mui/x-tree-view/useTreeItem'; import { - TreeItem2Content, - TreeItem2IconContainer, - TreeItem2GroupTransition, - TreeItem2Label, - TreeItem2Root, - TreeItem2Checkbox, -} from '@mui/x-tree-view/TreeItem2'; -import { TreeItem2Icon } from '@mui/x-tree-view/TreeItem2Icon'; -import { TreeItem2Provider } from '@mui/x-tree-view/TreeItem2Provider'; -import { TreeItem2DragAndDropOverlay } from '@mui/x-tree-view/TreeItem2DragAndDropOverlay'; -import { TreeItem2LabelInput } from '@mui/x-tree-view/TreeItem2LabelInput'; + TreeItemContent, + TreeItemIconContainer, + TreeItemGroupTransition, + TreeItemLabel, + TreeItemRoot, + TreeItemCheckbox, +} from '@mui/x-tree-view/TreeItem'; +import { TreeItemIcon } from '@mui/x-tree-view/TreeItemIcon'; +import { TreeItemProvider } from '@mui/x-tree-view/TreeItemProvider'; +import { TreeItemDragAndDropOverlay } from '@mui/x-tree-view/TreeItemDragAndDropOverlay'; +import { TreeItemLabelInput } from '@mui/x-tree-view/TreeItemLabelInput'; const ITEMS = [ { @@ -35,7 +35,7 @@ const AnnotationText = styled(Typography)(({ theme }) => ({ fontSize: theme.typography.pxToRem(11), })); -const CustomTreeItem2Transition = styled(TreeItem2GroupTransition)(({ theme }) => ({ +const CustomTreeItemTransition = styled(TreeItemGroupTransition)(({ theme }) => ({ padding: 6, border: '1px solid transparent', '&:hover:not(:has(:hover))': { @@ -43,34 +43,34 @@ const CustomTreeItem2Transition = styled(TreeItem2GroupTransition)(({ theme }) = }, })); -const CustomTreeItem2LabelInput = styled(TreeItem2LabelInput)(({ theme }) => ({ +const CustomTreeItemLabelInput = styled(TreeItemLabelInput)(({ theme }) => ({ color: theme.palette.text.primary, border: '1px solid transparent', '&:hover': { borderColor: theme.palette.primary.main, }, })); -const CustomTreeItem2Content = styled(TreeItem2Content)(({ theme }) => ({ +const CustomTreeItemContent = styled(TreeItemContent)(({ theme }) => ({ border: '1px solid transparent', '&:hover:not(:has(:hover))': { borderColor: theme.palette.primary.main, }, })); -const CustomTreeItem2IconContainer = styled(TreeItem2IconContainer)(({ theme }) => ({ +const CustomTreeItemIconContainer = styled(TreeItemIconContainer)(({ theme }) => ({ borderRadius: theme.shape.borderRadius, border: '1px solid transparent', '&:hover': { borderColor: theme.palette.primary.main, }, })); -const CustomTreeItem2Label = styled(TreeItem2Label)(({ theme }) => ({ +const CustomTreeItemLabel = styled(TreeItemLabel)(({ theme }) => ({ borderRadius: theme.shape.borderRadius, border: '1px solid transparent', '&:hover': { borderColor: theme.palette.primary.main, }, })); -const CustomTreeItem2Checkbox = styled(TreeItem2Checkbox)(({ theme }) => ({ +const CustomTreeItemCheckbox = styled(TreeItemCheckbox)(({ theme }) => ({ borderRadius: theme.shape.borderRadius, border: '1px solid transparent', '&:hover': { @@ -100,65 +100,65 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem(props, ref) { getDragAndDropOverlayProps, getLabelInputProps, status, - } = useTreeItem2({ id, itemId, children, label, disabled, rootRef: ref }); + } = useTreeItem({ id, itemId, children, label, disabled, rootRef: ref }); return ( - - + - - - - - + + {status?.editable ? ( - ) : ( - )} - - + {children && ( - )} - - + + ({ fontSize: theme.typography.pxToRem(11), })); -const CustomTreeItem2Transition = styled(TreeItem2GroupTransition)(({ theme }) => ({ +const CustomTreeItemTransition = styled(TreeItemGroupTransition)(({ theme }) => ({ padding: 6, border: '1px solid transparent', '&:hover:not(:has(:hover))': { @@ -48,34 +48,34 @@ const CustomTreeItem2Transition = styled(TreeItem2GroupTransition)(({ theme }) = }, })); -const CustomTreeItem2LabelInput = styled(TreeItem2LabelInput)(({ theme }) => ({ +const CustomTreeItemLabelInput = styled(TreeItemLabelInput)(({ theme }) => ({ color: theme.palette.text.primary, border: '1px solid transparent', '&:hover': { borderColor: theme.palette.primary.main, }, })); -const CustomTreeItem2Content = styled(TreeItem2Content)(({ theme }) => ({ +const CustomTreeItemContent = styled(TreeItemContent)(({ theme }) => ({ border: '1px solid transparent', '&:hover:not(:has(:hover))': { borderColor: theme.palette.primary.main, }, })); -const CustomTreeItem2IconContainer = styled(TreeItem2IconContainer)(({ theme }) => ({ +const CustomTreeItemIconContainer = styled(TreeItemIconContainer)(({ theme }) => ({ borderRadius: theme.shape.borderRadius, border: '1px solid transparent', '&:hover': { borderColor: theme.palette.primary.main, }, })); -const CustomTreeItem2Label = styled(TreeItem2Label)(({ theme }) => ({ +const CustomTreeItemLabel = styled(TreeItemLabel)(({ theme }) => ({ borderRadius: theme.shape.borderRadius, border: '1px solid transparent', '&:hover': { borderColor: theme.palette.primary.main, }, })); -const CustomTreeItem2Checkbox = styled(TreeItem2Checkbox)(({ theme }) => ({ +const CustomTreeItemCheckbox = styled(TreeItemCheckbox)(({ theme }) => ({ borderRadius: theme.shape.borderRadius, border: '1px solid transparent', '&:hover': { @@ -84,7 +84,7 @@ const CustomTreeItem2Checkbox = styled(TreeItem2Checkbox)(({ theme }) => ({ })); interface CustomTreeItemProps - extends Omit, + extends Omit, Omit, 'onFocus'> {} const CustomTreeItem = React.forwardRef(function CustomTreeItem( @@ -112,65 +112,65 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem( getDragAndDropOverlayProps, getLabelInputProps, status, - } = useTreeItem2({ id, itemId, children, label, disabled, rootRef: ref }); + } = useTreeItem({ id, itemId, children, label, disabled, rootRef: ref }); return ( - - + - - - - - + + {status?.editable ? ( - ) : ( - )} - - + {children && ( - )} - - + + , ) { - const { interactions } = useTreeItem2Utils({ + const { interactions } = useTreeItemUtils({ itemId: props.itemId, children: props.children, }); @@ -23,7 +23,7 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem( // Do something when the checkbox is clicked }; - const handleCheckboxOnChange: UseTreeItem2CheckboxSlotOwnProps['onChange'] = ( + const handleCheckboxOnChange: UseTreeItemCheckboxSlotOwnProps['onChange'] = ( event, ) => { event.defaultMuiPrevented = true; @@ -32,13 +32,13 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem( }; return ( - ); diff --git a/docs/data/tree-view/tree-item-customization/HandleExpansionDemo.js b/docs/data/tree-view/tree-item-customization/HandleExpansionDemo.js index 07f41849946f..e160321aa89c 100644 --- a/docs/data/tree-view/tree-item-customization/HandleExpansionDemo.js +++ b/docs/data/tree-view/tree-item-customization/HandleExpansionDemo.js @@ -4,16 +4,16 @@ import IconButton from '@mui/material/IconButton'; import AddBoxOutlinedIcon from '@mui/icons-material/AddBoxOutlined'; import IndeterminateCheckBoxOutlinedIcon from '@mui/icons-material/IndeterminateCheckBoxOutlined'; import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; -import { useTreeItem2 } from '@mui/x-tree-view/useTreeItem2'; +import { useTreeItem } from '@mui/x-tree-view/useTreeItem'; import { - TreeItem2Content, - TreeItem2Label, - TreeItem2Root, - TreeItem2GroupTransition, -} from '@mui/x-tree-view/TreeItem2'; -import { TreeItem2Provider } from '@mui/x-tree-view/TreeItem2Provider'; -import { TreeItem2DragAndDropOverlay } from '@mui/x-tree-view/TreeItem2DragAndDropOverlay'; -import { useTreeItem2Utils } from '@mui/x-tree-view/hooks'; + TreeItemContent, + TreeItemLabel, + TreeItemRoot, + TreeItemGroupTransition, +} from '@mui/x-tree-view/TreeItem'; +import { TreeItemProvider } from '@mui/x-tree-view/TreeItemProvider'; +import { TreeItemDragAndDropOverlay } from '@mui/x-tree-view/TreeItemDragAndDropOverlay'; +import { useTreeItemUtils } from '@mui/x-tree-view/hooks'; import { MUI_X_PRODUCTS } from './products'; const CustomTreeItem = React.forwardRef(function CustomTreeItem( @@ -27,9 +27,9 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem( getGroupTransitionProps, getDragAndDropOverlayProps, status, - } = useTreeItem2({ id, itemId, children, label, disabled, rootRef: ref }); + } = useTreeItem({ id, itemId, children, label, disabled, rootRef: ref }); - const { interactions } = useTreeItem2Utils({ + const { interactions } = useTreeItemUtils({ itemId, children, }); @@ -39,8 +39,8 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem( }; return ( - - + + {status.expandable && ( )} - - - - - {children && } - - + + + + + {children && } + + ); }); diff --git a/docs/data/tree-view/tree-item-customization/HandleExpansionDemo.tsx b/docs/data/tree-view/tree-item-customization/HandleExpansionDemo.tsx index 59d5869eeff8..9b4dad21c33d 100644 --- a/docs/data/tree-view/tree-item-customization/HandleExpansionDemo.tsx +++ b/docs/data/tree-view/tree-item-customization/HandleExpansionDemo.tsx @@ -4,21 +4,21 @@ import IconButton from '@mui/material/IconButton'; import AddBoxOutlinedIcon from '@mui/icons-material/AddBoxOutlined'; import IndeterminateCheckBoxOutlinedIcon from '@mui/icons-material/IndeterminateCheckBoxOutlined'; import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; -import { useTreeItem2 } from '@mui/x-tree-view/useTreeItem2'; +import { useTreeItem } from '@mui/x-tree-view/useTreeItem'; import { - TreeItem2Content, - TreeItem2Label, - TreeItem2Root, - TreeItem2Props, - TreeItem2GroupTransition, -} from '@mui/x-tree-view/TreeItem2'; -import { TreeItem2Provider } from '@mui/x-tree-view/TreeItem2Provider'; -import { TreeItem2DragAndDropOverlay } from '@mui/x-tree-view/TreeItem2DragAndDropOverlay'; -import { useTreeItem2Utils } from '@mui/x-tree-view/hooks'; + TreeItemContent, + TreeItemLabel, + TreeItemRoot, + TreeItemProps, + TreeItemGroupTransition, +} from '@mui/x-tree-view/TreeItem'; +import { TreeItemProvider } from '@mui/x-tree-view/TreeItemProvider'; +import { TreeItemDragAndDropOverlay } from '@mui/x-tree-view/TreeItemDragAndDropOverlay'; +import { useTreeItemUtils } from '@mui/x-tree-view/hooks'; import { MUI_X_PRODUCTS } from './products'; const CustomTreeItem = React.forwardRef(function CustomTreeItem( - { id, itemId, label, disabled, children }: TreeItem2Props, + { id, itemId, label, disabled, children }: TreeItemProps, ref: React.Ref, ) { const { @@ -28,9 +28,9 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem( getGroupTransitionProps, getDragAndDropOverlayProps, status, - } = useTreeItem2({ id, itemId, children, label, disabled, rootRef: ref }); + } = useTreeItem({ id, itemId, children, label, disabled, rootRef: ref }); - const { interactions } = useTreeItem2Utils({ + const { interactions } = useTreeItemUtils({ itemId, children, }); @@ -40,8 +40,8 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem( }; return ( - - + + {status.expandable && ( )} - - + + - - - {children && } - - + + + {children && } + + ); }); diff --git a/docs/data/tree-view/tree-item-customization/HandleSelectionDemo.js b/docs/data/tree-view/tree-item-customization/HandleSelectionDemo.js index 09caf51788b1..8723527c35dc 100644 --- a/docs/data/tree-view/tree-item-customization/HandleSelectionDemo.js +++ b/docs/data/tree-view/tree-item-customization/HandleSelectionDemo.js @@ -5,10 +5,10 @@ import IconButton from '@mui/material/IconButton'; import Typography from '@mui/material/Typography'; import PanoramaFishEyeIcon from '@mui/icons-material/PanoramaFishEye'; import CircleIcon from '@mui/icons-material/Circle'; -import { useTreeItem2Utils } from '@mui/x-tree-view/hooks'; +import { useTreeItemUtils } from '@mui/x-tree-view/hooks'; import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; -import { TreeItem2 } from '@mui/x-tree-view/TreeItem2'; +import { TreeItem } from '@mui/x-tree-view/TreeItem'; import { MUI_X_PRODUCTS } from './products'; function CustomLabel({ children, status, onClick, ...props }) { @@ -33,7 +33,7 @@ function CustomLabel({ children, status, onClick, ...props }) { } const CustomTreeItem = React.forwardRef(function CustomTreeItem(props, ref) { - const { interactions, status } = useTreeItem2Utils({ + const { interactions, status } = useTreeItemUtils({ itemId: props.itemId, children: props.children, }); @@ -46,7 +46,7 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem(props, ref) { }; return ( - ; } @@ -46,14 +46,14 @@ function CustomLabel({ children, status, onClick, ...props }: CustomLabelProps) } const CustomTreeItem = React.forwardRef(function CustomTreeItem( - props: TreeItem2Props, + props: TreeItemProps, ref: React.Ref, ) { - const { interactions, status } = useTreeItem2Utils({ + const { interactions, status } = useTreeItemUtils({ itemId: props.itemId, children: props.children, }); - const handleContentClick: UseTreeItem2ContentSlotOwnProps['onClick'] = (event) => { + const handleContentClick: UseTreeItemContentSlotOwnProps['onClick'] = (event) => { event.defaultMuiPrevented = true; }; @@ -62,7 +62,7 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem( }; return ( - ); diff --git a/docs/data/tree-view/tree-item-customization/LabelSlot.js b/docs/data/tree-view/tree-item-customization/LabelSlot.js index de54cf4eb424..fcac64f4f9e4 100644 --- a/docs/data/tree-view/tree-item-customization/LabelSlot.js +++ b/docs/data/tree-view/tree-item-customization/LabelSlot.js @@ -2,9 +2,9 @@ import * as React from 'react'; import Box from '@mui/material/Box'; import Typography from '@mui/material/Typography'; import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; -import { TreeItem2 } from '@mui/x-tree-view/TreeItem2'; +import { TreeItem } from '@mui/x-tree-view/TreeItem'; -import { useTreeItem2Utils } from '@mui/x-tree-view/hooks'; +import { useTreeItemUtils } from '@mui/x-tree-view/hooks'; export const MUI_X_PRODUCTS = [ { @@ -70,7 +70,7 @@ function CustomLabel({ children, className, secondaryLabel }) { } const CustomTreeItem = React.forwardRef(function CustomTreeItem(props, ref) { - const { publicAPI } = useTreeItem2Utils({ + const { publicAPI } = useTreeItemUtils({ itemId: props.itemId, children: props.children, }); @@ -78,7 +78,7 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem(props, ref) { const item = publicAPI.getItem(props.itemId); return ( - , ) { - const { publicAPI } = useTreeItem2Utils({ + const { publicAPI } = useTreeItemUtils({ itemId: props.itemId, children: props.children, }); @@ -95,7 +95,7 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem( const item = publicAPI.getItem(props.itemId); return ( - , ) { return ( - - - -{{"component": "modules/components/TreeItem2Anatomy.js"}} + +Tree Item anatomy + + +Tree Item anatomy + ### Content @@ -81,12 +83,11 @@ By default, a nested item is indented by `12px` from its parent item. {{"demo": "ItemChildrenIndentationProp.js"}} :::success -This feature is compatible with both the `` and `` components If you are using a custom Tree Item component, and you want to override the padding, then apply the following padding to your `groupTransition` element: ```ts -const CustomTreeItem2GroupTransition = styled(TreeItem2GroupTransition)(({ theme }) => ({ +const CustomTreeItemGroupTransition = styled(TreeItemGroupTransition)(({ theme }) => ({ // ...other styles paddingLeft: `var(--TreeView-itemChildrenIndentation)`, } @@ -95,7 +96,7 @@ const CustomTreeItem2GroupTransition = styled(TreeItem2GroupTransition)(({ theme If you are using the `indentationAtItemLevel` prop, then instead apply the following padding to your `content` element: ```ts -const CustomTreeItem2Content = styled(TreeItem2Content)(({ theme }) => ({ +const CustomTreeItemContent = styled(TreeItemContent)(({ theme }) => ({ // ...other styles paddingLeft: `calc(${theme.spacing(1)} + var(--TreeView-itemChildrenIndentation) * var(--TreeView-itemDepth))`, @@ -116,12 +117,11 @@ It will become the default behavior in the next major version of the Tree View c {{"demo": "IndentationAtItemLevel.js"}} :::success -This feature is compatible with both the `` and `` components and with the `itemChildrenIndentation` prop. If you are using a custom Tree Item component, and you want to override the padding, then apply the following padding to your `content` element: ```ts -const CustomTreeItem2Content = styled(TreeItem2Content)(({ theme }) => ({ +const CustomTreeItemContent = styled(TreeItemContent)(({ theme }) => ({ // ...other styles paddingLeft: `calc(${theme.spacing(1)} + var(--TreeView-itemChildrenIndentation) * var(--TreeView-itemDepth))`, @@ -132,19 +132,19 @@ const CustomTreeItem2Content = styled(TreeItem2Content)(({ theme }) => ({ ## Hooks -### useTreeItem2 +### useTreeItem -The `useTreeItem2` hook lets you manage and customize individual Tree Items. +The `useTreeItem` hook lets you manage and customize individual Tree Items. You can use it to get the properties needed for all slots, the status of any given Item, or to tap into the interactive API of the Tree View. #### Slot properties -The `useTreeItem2` hook gives you granular control over an Item's layout by providing resolvers to get the appropriate props for each slot. +The `useTreeItem` hook gives you granular control over an Item's layout by providing resolvers to get the appropriate props for each slot. This makes it possible to build a fully custom layout for your Tree Items. The demo below shows how to get the props needed for each slot, and how to pass them correctly. -{{"demo": "useTreeItem2HookProperties.js"}} +{{"demo": "useTreeItemHookProperties.js"}} You can pass additional props to a slot—or override existing slots—by passing an object argument to the slot's props resolver, as shown below: @@ -159,34 +159,34 @@ You can pass additional props to a slot—or override existing slots—by passin #### Item status -The `useTreeItem2` hook also returns a `status` object that holds boolean values for each possible state of a Tree Item. +The `useTreeItem` hook also returns a `status` object that holds boolean values for each possible state of a Tree Item. ```jsx const { status: { expanded, expandable, focused, selected, disabled, editable, editing }, -} = useTreeItem2(props); +} = useTreeItem(props); ``` You can use these statuses to apply custom styling to the item or conditionally render subcomponents. -{{"demo": "useTreeItem2HookStatus.js"}} +{{"demo": "useTreeItemHookStatus.js"}} #### Imperative API The `publicAPI` object provides a number of methods to programmatically interact with the Tree View. -You can use the `useTreeItem2` hook to access the `publicAPI` object from within a Tree Item. +You can use the `useTreeItem` hook to access the `publicAPI` object from within a Tree Item. -{{"demo": "useTreeItem2HookPublicAPI.js"}} +{{"demo": "useTreeItemHookPublicAPI.js"}} See the **Imperative API** section on each feature page to learn more about the public API methods available on the Tree View. -### `useTreeItem2Utils` +### `useTreeItemUtils` -The `useTreeItem2Utils` hook provides a set of interaction methods for implementing custom behaviors for the Tree View. +The `useTreeItemUtils` hook provides a set of interaction methods for implementing custom behaviors for the Tree View. It also returns the status of the Item. ```jsx -const { interactions, status } = useTreeItem2Utils({ +const { interactions, status } = useTreeItemUtils({ itemId: props.itemId, children: props.children, }); @@ -225,7 +225,7 @@ The demo below shows how to introduce a new element that expands and collapses t #### Label editing -The `useTreeItem2Utils` hook provides the following interaction methods relevant to label editing behavior: +The `useTreeItemUtils` hook provides the following interaction methods relevant to label editing behavior: ```jsx const { @@ -234,7 +234,7 @@ const { handleCancelItemLabelEditing, handleSaveItemLabel, }, -} = useTreeItem2Utils({ +} = useTreeItemUtils({ itemId: props.itemId, children: props.children, }); diff --git a/docs/data/tree-view/tree-item-customization/useTreeItemHookProperties.js b/docs/data/tree-view/tree-item-customization/useTreeItemHookProperties.js new file mode 100644 index 000000000000..f9683d989e7b --- /dev/null +++ b/docs/data/tree-view/tree-item-customization/useTreeItemHookProperties.js @@ -0,0 +1,72 @@ +import * as React from 'react'; +import Box from '@mui/material/Box'; +import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; +import { useTreeItem } from '@mui/x-tree-view/useTreeItem'; +import { + TreeItemCheckbox, + TreeItemContent, + TreeItemIconContainer, + TreeItemLabel, + TreeItemRoot, + TreeItemGroupTransition, +} from '@mui/x-tree-view/TreeItem'; +import { TreeItemIcon } from '@mui/x-tree-view/TreeItemIcon'; +import { TreeItemProvider } from '@mui/x-tree-view/TreeItemProvider'; +import { TreeItemDragAndDropOverlay } from '@mui/x-tree-view/TreeItemDragAndDropOverlay'; +import { TreeItemLabelInput } from '@mui/x-tree-view/TreeItemLabelInput'; +import { MUI_X_PRODUCTS } from './products'; + +const CustomTreeItem = React.forwardRef(function CustomTreeItem( + { id, itemId, label, disabled, children }, + ref, +) { + const { + getRootProps, + getContentProps, + getIconContainerProps, + getCheckboxProps, + getLabelProps, + getLabelInputProps, + getGroupTransitionProps, + getDragAndDropOverlayProps, + status, + } = useTreeItem({ id, itemId, children, label, disabled, rootRef: ref }); + + return ( + + + + + + + + {status.editing ? ( + + ) : ( + + )} + + + + {children && } + + + ); +}); + +export default function useTreeItemHookProperties() { + return ( + + + + ); +} diff --git a/docs/data/tree-view/tree-item-customization/useTreeItemHookProperties.tsx b/docs/data/tree-view/tree-item-customization/useTreeItemHookProperties.tsx new file mode 100644 index 000000000000..8e49e71df547 --- /dev/null +++ b/docs/data/tree-view/tree-item-customization/useTreeItemHookProperties.tsx @@ -0,0 +1,73 @@ +import * as React from 'react'; +import Box from '@mui/material/Box'; +import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; +import { useTreeItem } from '@mui/x-tree-view/useTreeItem'; +import { + TreeItemCheckbox, + TreeItemContent, + TreeItemIconContainer, + TreeItemLabel, + TreeItemRoot, + TreeItemProps, + TreeItemGroupTransition, +} from '@mui/x-tree-view/TreeItem'; +import { TreeItemIcon } from '@mui/x-tree-view/TreeItemIcon'; +import { TreeItemProvider } from '@mui/x-tree-view/TreeItemProvider'; +import { TreeItemDragAndDropOverlay } from '@mui/x-tree-view/TreeItemDragAndDropOverlay'; +import { TreeItemLabelInput } from '@mui/x-tree-view/TreeItemLabelInput'; +import { MUI_X_PRODUCTS } from './products'; + +const CustomTreeItem = React.forwardRef(function CustomTreeItem( + { id, itemId, label, disabled, children }: TreeItemProps, + ref: React.Ref, +) { + const { + getRootProps, + getContentProps, + getIconContainerProps, + getCheckboxProps, + getLabelProps, + getLabelInputProps, + getGroupTransitionProps, + getDragAndDropOverlayProps, + status, + } = useTreeItem({ id, itemId, children, label, disabled, rootRef: ref }); + + return ( + + + + + + + + {status.editing ? ( + + ) : ( + + )} + + + + {children && } + + + ); +}); + +export default function useTreeItemHookProperties() { + return ( + + + + ); +} diff --git a/docs/data/tree-view/tree-item-customization/useTreeItemHookProperties.tsx.preview b/docs/data/tree-view/tree-item-customization/useTreeItemHookProperties.tsx.preview new file mode 100644 index 000000000000..5c65f878fe8f --- /dev/null +++ b/docs/data/tree-view/tree-item-customization/useTreeItemHookProperties.tsx.preview @@ -0,0 +1,10 @@ + \ No newline at end of file diff --git a/docs/data/tree-view/tree-item-customization/useTreeItemHookPublicAPI.js b/docs/data/tree-view/tree-item-customization/useTreeItemHookPublicAPI.js new file mode 100644 index 000000000000..72886928944d --- /dev/null +++ b/docs/data/tree-view/tree-item-customization/useTreeItemHookPublicAPI.js @@ -0,0 +1,56 @@ +import * as React from 'react'; +import Box from '@mui/material/Box'; +import Typography from '@mui/material/Typography'; +import Chip from '@mui/material/Chip'; +import Stack from '@mui/material/Stack'; +import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; +import { TreeItem } from '@mui/x-tree-view/TreeItem'; +import { useTreeItem } from '@mui/x-tree-view/useTreeItem'; +import { MUI_X_PRODUCTS } from './products'; + +function CustomLabel({ children, className, numberOfChildren }) { + return ( + + {children} + + + + ); +} + +const CustomTreeItem = React.forwardRef(function CustomTreeItem(props, ref) { + const { publicAPI } = useTreeItem(props); + + const childrenNumber = publicAPI.getItemOrderedChildrenIds(props.itemId).length; + + return ( + + ); +}); + +export default function useTreeItemHookPublicAPI() { + return ( + + + + ); +} diff --git a/docs/data/tree-view/tree-item-customization/useTreeItemHookPublicAPI.tsx b/docs/data/tree-view/tree-item-customization/useTreeItemHookPublicAPI.tsx new file mode 100644 index 000000000000..48bf738b2fc8 --- /dev/null +++ b/docs/data/tree-view/tree-item-customization/useTreeItemHookPublicAPI.tsx @@ -0,0 +1,65 @@ +import * as React from 'react'; +import Box from '@mui/material/Box'; +import Typography from '@mui/material/Typography'; +import Chip from '@mui/material/Chip'; +import Stack from '@mui/material/Stack'; +import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; +import { TreeItem, TreeItemProps } from '@mui/x-tree-view/TreeItem'; +import { useTreeItem } from '@mui/x-tree-view/useTreeItem'; +import { MUI_X_PRODUCTS } from './products'; + +interface CustomLabelProps { + children: string; + className: string; + numberOfChildren: number; +} + +function CustomLabel({ children, className, numberOfChildren }: CustomLabelProps) { + return ( + + {children} + + + + ); +} + +const CustomTreeItem = React.forwardRef(function CustomTreeItem( + props: TreeItemProps, + ref: React.Ref, +) { + const { publicAPI } = useTreeItem(props); + + const childrenNumber = publicAPI.getItemOrderedChildrenIds(props.itemId).length; + + return ( + + ); +}); + +export default function useTreeItemHookPublicAPI() { + return ( + + + + ); +} diff --git a/docs/data/tree-view/tree-item-customization/useTreeItemHookPublicAPI.tsx.preview b/docs/data/tree-view/tree-item-customization/useTreeItemHookPublicAPI.tsx.preview new file mode 100644 index 000000000000..1333b932705f --- /dev/null +++ b/docs/data/tree-view/tree-item-customization/useTreeItemHookPublicAPI.tsx.preview @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/docs/data/tree-view/tree-item-customization/useTreeItemHookStatus.js b/docs/data/tree-view/tree-item-customization/useTreeItemHookStatus.js new file mode 100644 index 000000000000..5c6e53c47b14 --- /dev/null +++ b/docs/data/tree-view/tree-item-customization/useTreeItemHookStatus.js @@ -0,0 +1,152 @@ +import * as React from 'react'; +import Box from '@mui/material/Box'; +import Stack from '@mui/material/Stack'; +import Paper from '@mui/material/Paper'; +import Typography from '@mui/material/Typography'; +import AdjustIcon from '@mui/icons-material/Adjust'; +import CheckCircleOutlinedIcon from '@mui/icons-material/CheckCircleOutlined'; +import ExpandCircleDownOutlinedIcon from '@mui/icons-material/ExpandCircleDownOutlined'; +import ExpandCircleDownRoundedIcon from '@mui/icons-material/ExpandCircleDownRounded'; +import CancelOutlinedIcon from '@mui/icons-material/CancelOutlined'; +import EditOutlinedIcon from '@mui/icons-material/EditOutlined'; +import DrawOutlinedIcon from '@mui/icons-material/DrawOutlined'; +import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; +import { useTreeItem } from '@mui/x-tree-view/useTreeItem'; +import { + TreeItemContent, + TreeItemRoot, + TreeItemGroupTransition, + TreeItemIconContainer, + TreeItemLabel, +} from '@mui/x-tree-view/TreeItem'; +import { TreeItemIcon } from '@mui/x-tree-view/TreeItemIcon'; +import { TreeItemProvider } from '@mui/x-tree-view/TreeItemProvider'; +import { TreeItemLabelInput } from '@mui/x-tree-view/TreeItemLabelInput'; +import { MUI_X_PRODUCTS } from './products'; + +function StatusLegend() { + return ( + ({ + padding: 2, + background: theme.palette.grey[50], + ...theme.applyStyles('dark', { + background: theme.palette.grey[900], + }), + })} + > + + Legend + + + {STATUS_ICONS.focused} + focused + + + {STATUS_ICONS.selected} + selected + + + {STATUS_ICONS.expandable} + expandable + + + {STATUS_ICONS.expanded} + expanded + + + {STATUS_ICONS.disabled} + disabled + + + {STATUS_ICONS.editable} + editable + + + {STATUS_ICONS.editing} + editing + + + + ); +} + +const STATUS_ICONS = { + focused: , + selected: , + expandable: , + expanded: , + disabled: , + editable: , + editing: , +}; + +const CustomTreeItem = React.forwardRef(function CustomTreeItem( + { id, itemId, label, disabled, children }, + ref, +) { + const { + getRootProps, + getContentProps, + getLabelProps, + getGroupTransitionProps, + getIconContainerProps, + getLabelInputProps, + status, + } = useTreeItem({ id, itemId, label, disabled, children, rootRef: ref }); + + return ( + + + + + + + + {status.editing ? ( + + ) : ( + + )} + + + {Object.keys(STATUS_ICONS).map((iconKey, index) => { + if (status[iconKey]) { + return ( + + {STATUS_ICONS[iconKey]} + + ); + } + return null; + })} + + + {children && } + + + ); +}); + +export default function useTreeItemHookStatus() { + return ( + + + Boolean(item?.disabled)} + isItemEditable={(item) => Boolean(item?.editable)} + experimentalFeatures={{ + labelEditing: true, + }} + /> + + + + ); +} diff --git a/docs/data/tree-view/tree-item-customization/useTreeItemHookStatus.tsx b/docs/data/tree-view/tree-item-customization/useTreeItemHookStatus.tsx new file mode 100644 index 000000000000..d03d53ca63d0 --- /dev/null +++ b/docs/data/tree-view/tree-item-customization/useTreeItemHookStatus.tsx @@ -0,0 +1,157 @@ +import * as React from 'react'; +import Box from '@mui/material/Box'; +import Stack from '@mui/material/Stack'; +import Paper from '@mui/material/Paper'; +import Typography from '@mui/material/Typography'; +import AdjustIcon from '@mui/icons-material/Adjust'; +import CheckCircleOutlinedIcon from '@mui/icons-material/CheckCircleOutlined'; +import ExpandCircleDownOutlinedIcon from '@mui/icons-material/ExpandCircleDownOutlined'; +import ExpandCircleDownRoundedIcon from '@mui/icons-material/ExpandCircleDownRounded'; +import CancelOutlinedIcon from '@mui/icons-material/CancelOutlined'; +import EditOutlinedIcon from '@mui/icons-material/EditOutlined'; +import DrawOutlinedIcon from '@mui/icons-material/DrawOutlined'; +import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; +import { useTreeItem, UseTreeItemStatus } from '@mui/x-tree-view/useTreeItem'; +import { + TreeItemContent, + TreeItemRoot, + TreeItemProps, + TreeItemGroupTransition, + TreeItemIconContainer, + TreeItemLabel, +} from '@mui/x-tree-view/TreeItem'; +import { TreeItemIcon } from '@mui/x-tree-view/TreeItemIcon'; +import { TreeItemProvider } from '@mui/x-tree-view/TreeItemProvider'; +import { TreeItemLabelInput } from '@mui/x-tree-view/TreeItemLabelInput'; +import { MUI_X_PRODUCTS } from './products'; + +function StatusLegend() { + return ( + ({ + padding: 2, + background: theme.palette.grey[50], + ...theme.applyStyles('dark', { + background: theme.palette.grey[900], + }), + })} + > + + Legend + + + {STATUS_ICONS.focused} + focused + + + {STATUS_ICONS.selected} + selected + + + {STATUS_ICONS.expandable} + expandable + + + {STATUS_ICONS.expanded} + expanded + + + {STATUS_ICONS.disabled} + disabled + + + {STATUS_ICONS.editable} + editable + + + {STATUS_ICONS.editing} + editing + + + + ); +} + +const STATUS_ICONS: { + [K in keyof UseTreeItemStatus]: React.ReactNode; +} = { + focused: , + selected: , + expandable: , + expanded: , + disabled: , + editable: , + editing: , +}; + +const CustomTreeItem = React.forwardRef(function CustomTreeItem( + { id, itemId, label, disabled, children }: TreeItemProps, + ref: React.Ref, +) { + const { + getRootProps, + getContentProps, + getLabelProps, + getGroupTransitionProps, + getIconContainerProps, + getLabelInputProps, + status, + } = useTreeItem({ id, itemId, label, disabled, children, rootRef: ref }); + + return ( + + + + + + + + {status.editing ? ( + + ) : ( + + )} + + + {(Object.keys(STATUS_ICONS) as [keyof UseTreeItemStatus]).map( + (iconKey, index) => { + if (status[iconKey]) { + return ( + + {STATUS_ICONS[iconKey]} + + ); + } + return null; + }, + )} + + + {children && } + + + ); +}); + +export default function useTreeItemHookStatus() { + return ( + + + Boolean(item?.disabled)} + isItemEditable={(item) => Boolean(item?.editable)} + experimentalFeatures={{ + labelEditing: true, + }} + /> + + + + ); +} diff --git a/docs/data/tree-view/tree-item-customization/useTreeItemHookStatus.tsx.preview b/docs/data/tree-view/tree-item-customization/useTreeItemHookStatus.tsx.preview new file mode 100644 index 000000000000..bdd7c89341d1 --- /dev/null +++ b/docs/data/tree-view/tree-item-customization/useTreeItemHookStatus.tsx.preview @@ -0,0 +1,14 @@ + + Boolean(item?.disabled)} + isItemEditable={(item) => Boolean(item?.editable)} + experimentalFeatures={{ + labelEditing: true, + }} + /> + + \ No newline at end of file diff --git a/docs/data/treeViewApiPages.ts b/docs/data/treeViewApiPages.ts new file mode 100644 index 000000000000..b503ea53e2c8 --- /dev/null +++ b/docs/data/treeViewApiPages.ts @@ -0,0 +1,34 @@ +import type { MuiPage } from 'docs/src/MuiPage'; + +const treeViewApiPages: MuiPage[] = [ + { + pathname: '/x/api/tree-view/rich-tree-view', + title: 'RichTreeView', + }, + { + pathname: '/x/api/tree-view/rich-tree-view-pro', + title: 'RichTreeViewPro', + plan: 'pro', + }, + { + pathname: '/x/api/tree-view/simple-tree-view', + title: 'SimpleTreeView', + }, + { + pathname: '/x/api/tree-view/tree-item', + title: 'TreeItem', + }, + { + pathname: '/x/api/tree-view/tree-item-drag-and-drop-overlay', + title: 'TreeItemDragAndDropOverlay', + }, + { + pathname: '/x/api/tree-view/tree-item-icon', + title: 'TreeItemIcon', + }, + { + pathname: '/x/api/tree-view/tree-view', + title: 'TreeView', + }, +]; +export default treeViewApiPages; diff --git a/docs/package.json b/docs/package.json index f9f2ee98e944..4e7d0638b4ab 100644 --- a/docs/package.json +++ b/docs/package.json @@ -9,7 +9,7 @@ "build:clean": "rimraf .next && pnpm build", "build-sw": "node ./scripts/buildServiceWorker.js", "dev": "next dev --port 3001", - "deploy": "git push -f upstream v7.x:docs-v7", + "deploy": "git push -f upstream master:docs-next", "icons": "rimraf public/static/icons/* && node ./scripts/buildIcons.js", "serve": "serve ./export -l 3010", "create-playground": "cpy --cwd=scripts playground.template.tsx ../../pages/playground --rename=index.tsx", @@ -19,15 +19,15 @@ "populate:demos": "tsx scripts/populatePickersDemos" }, "dependencies": { - "@babel/core": "^7.25.8", - "@babel/runtime": "^7.25.7", - "@babel/runtime-corejs2": "^7.25.7", + "@babel/core": "^7.26.0", + "@babel/runtime": "^7.26.0", + "@babel/runtime-corejs2": "^7.26.0", "@docsearch/react": "^3.6.2", "@emotion/cache": "^11.13.1", "@emotion/react": "^11.13.3", "@emotion/server": "^11.11.0", "@emotion/styled": "^11.13.0", - "@mui/docs": "6.1.4", + "@mui/docs": "6.1.6", "@mui/icons-material": "^5.16.7", "@mui/joy": "^5.0.0-beta.48", "@mui/lab": "^5.0.0-alpha.173", @@ -46,7 +46,7 @@ "@mui/x-date-pickers-pro": "workspace:*", "@mui/x-tree-view": "workspace:*", "@react-spring/web": "^9.7.5", - "@tanstack/query-core": "^5.59.13", + "@tanstack/query-core": "^5.59.16", "ast-types": "^0.14.2", "autoprefixer": "^10.4.20", "babel-plugin-module-resolver": "^5.0.2", @@ -76,7 +76,7 @@ "moment-hijri": "^2.30.0", "moment-jalaali": "^0.10.1", "moment-timezone": "^0.5.46", - "next": "^14.2.15", + "next": "^14.2.16", "nprogress": "^0.2.0", "postcss": "^8.4.47", "prismjs": "^1.29.0", @@ -84,13 +84,14 @@ "react": "^18.3.1", "react-docgen": "^5.4.3", "react-dom": "^18.3.1", - "react-hook-form": "^7.53.0", + "react-hook-form": "^7.53.1", "react-is": "^18.3.1", "react-router": "^6.27.0", "react-router-dom": "^6.27.0", "react-runner": "^1.0.5", "react-simple-code-editor": "^0.14.1", "recast": "^0.23.9", + "rifm": "0.12.1", "rimraf": "^6.0.1", "rxjs": "^7.8.1", "styled-components": "^6.1.13", @@ -99,16 +100,16 @@ "webpack-bundle-analyzer": "^4.10.2" }, "devDependencies": { - "@babel/plugin-transform-react-constant-elements": "^7.25.7", - "@babel/preset-typescript": "^7.25.7", - "@mui/internal-docs-utils": "^1.0.14", - "@mui/internal-scripts": "^1.0.24", + "@babel/plugin-transform-react-constant-elements": "^7.25.9", + "@babel/preset-typescript": "^7.26.0", + "@mui/internal-docs-utils": "^1.0.15", + "@mui/internal-scripts": "^1.0.26", "@types/chance": "^1.1.6", "@types/d3-scale": "^4.0.8", "@types/d3-scale-chromatic": "^3.0.3", "@types/doctrine": "^0.0.9", "@types/gtag.js": "^0.0.20", - "@types/lodash": "^4.17.10", + "@types/lodash": "^4.17.12", "@types/luxon": "^3.4.2", "@types/moment-hijri": "^2.1.4", "@types/moment-jalaali": "^0.7.9", @@ -118,6 +119,6 @@ "@types/stylis": "^4.2.6", "@types/webpack-bundle-analyzer": "^4.7.0", "gm": "^1.25.0", - "serve": "^14.2.3" + "serve": "^14.2.4" } } diff --git a/docs/pages/_app.js b/docs/pages/_app.js index 08a025daad50..8f1471a414c7 100644 --- a/docs/pages/_app.js +++ b/docs/pages/_app.js @@ -30,9 +30,9 @@ LicenseInfo.setLicenseKey(process.env.NEXT_PUBLIC_MUI_LICENSE); function getMuiPackageVersion(packageName, commitRef) { if (commitRef === undefined) { // #default-branch-switch - // Use the "latest" npm tag for the master git branch - // Use the "next" npm tag for the next git branch - return 'latest'; + // Use the "next" tag for the master git branch after we start working on the next major version + // Once the major release is finished we can go back to "latest" + return 'next'; } const shortSha = commitRef.slice(0, 8); return `https://pkg.csb.dev/mui/mui-x/commit/${shortSha}/@mui/${packageName}`; @@ -53,7 +53,7 @@ ponyfillGlobal.muiDocConfig = { return newDeps; }, csbGetVersions: (versions, { muiCommitRef }) => { - const output = { + return { ...versions, '@mui/x-data-grid': getMuiPackageVersion('x-data-grid', muiCommitRef), '@mui/x-data-grid-pro': getMuiPackageVersion('x-data-grid-pro', muiCommitRef), @@ -68,7 +68,6 @@ ponyfillGlobal.muiDocConfig = { '@mui/x-internals': getMuiPackageVersion('x-internals', muiCommitRef), exceljs: 'latest', }; - return output; }, postProcessImport, }; @@ -206,17 +205,34 @@ function AppWrapper(props) { const pageContextValue = React.useMemo(() => { const { activePage, activePageParents } = findActivePage(pages, router.pathname); const languagePrefix = pageProps.userLanguage === 'en' ? '' : `/${pageProps.userLanguage}`; + const productIdSubpathMap = { + introduction: '/x/introduction', + 'x-data-grid': '/x/react-data-grid', + 'x-date-pickers': '/x/react-date-pickers', + 'x-charts': '/x/react-charts', + 'x-tree-view': '/x/react-tree-view', + }; + + const getVersionOptions = (id, versions) => + versions.map((version) => { + if (version === process.env.LIB_VERSION) { + return { + current: true, + text: `v${version}`, + href: `${languagePrefix}${productIdSubpathMap[id]}/`, + }; + } + return { + text: version, + href: `https://${version}.mui.com${languagePrefix}${productIdSubpathMap[id]}/`, + }; + }); let productIdentifier = { metadata: '', name: 'MUI X', versions: [ - { - text: `v${process.env.LIB_VERSION}`, - current: true, - }, - { text: 'v6', href: `https://v6.mui.com${languagePrefix}/x/introduction/` }, - { text: 'v5', href: `https://v5.mui.com${languagePrefix}/x/introduction/` }, + ...getVersionOptions('introduction', ['next', process.env.LIB_VERSION, 'v6', 'v5']), { text: 'v4', href: `https://v4.mui.com${languagePrefix}/components/data-grid/` }, ], }; @@ -226,12 +242,7 @@ function AppWrapper(props) { metadata: 'MUI X', name: 'Data Grid', versions: [ - { - text: `v${process.env.DATA_GRID_VERSION}`, - current: true, - }, - { text: 'v6', href: `https://v6.mui.com${languagePrefix}/x/react-data-grid/` }, - { text: 'v5', href: `https://v5.mui.com${languagePrefix}/x/react-data-grid/` }, + ...getVersionOptions('x-data-grid', ['next', process.env.DATA_GRID_VERSION, 'v6', 'v5']), { text: 'v4', href: `https://v4.mui.com${languagePrefix}/components/data-grid/` }, ], }; @@ -240,14 +251,7 @@ function AppWrapper(props) { metadata: 'MUI X', name: 'Date Pickers', versions: [ - { - text: `v${process.env.DATE_PICKERS_VERSION}`, - current: true, - }, - { - text: 'v6', - href: `https://v6.mui.com${languagePrefix}/x/react-date-pickers/`, - }, + ...getVersionOptions('x-date-pickers', ['next', process.env.DATE_PICKERS_VERSION, 'v6']), { text: 'v5', href: `https://v5.mui.com${languagePrefix}/x/react-date-pickers/getting-started/`, @@ -258,23 +262,14 @@ function AppWrapper(props) { productIdentifier = { metadata: 'MUI X', name: 'Charts', - versions: [ - { - text: `v${process.env.CHARTS_VERSION}`, - current: true, - }, - { text: 'v6', href: `https://v6.mui.com${languagePrefix}/x/react-charts/` }, - ], + versions: getVersionOptions('x-charts', ['next', process.env.CHARTS_VERSION, 'v6']), }; } else if (productId === 'x-tree-view') { productIdentifier = { metadata: 'MUI X', name: 'Tree View', versions: [ - { - text: `v${process.env.TREE_VIEW_VERSION}`, - current: true, - }, + ...getVersionOptions('x-tree-view', ['next', process.env.TREE_VIEW_VERSION]), { text: 'v6', href: `https://v6.mui.com${languagePrefix}/x/react-tree-view/getting-started`, diff --git a/docs/pages/x/api/charts/bar-series-type.json b/docs/pages/x/api/charts/bar-series-type.json index cf2252d4cc89..29c14e4317f7 100644 --- a/docs/pages/x/api/charts/bar-series-type.json +++ b/docs/pages/x/api/charts/bar-series-type.json @@ -17,8 +17,6 @@ "stackOrder": { "type": { "description": "StackOrderType" }, "default": "'none'" }, "valueFormatter": { "type": { "description": "SeriesValueFormatter<TValue>" } }, "xAxisId": { "type": { "description": "string" } }, - "xAxisKey": { "type": { "description": "string" } }, - "yAxisId": { "type": { "description": "string" } }, - "yAxisKey": { "type": { "description": "string" } } + "yAxisId": { "type": { "description": "string" } } } } diff --git a/docs/pages/x/api/charts/line-series-type.json b/docs/pages/x/api/charts/line-series-type.json index 147f90302c1d..7833c7370804 100644 --- a/docs/pages/x/api/charts/line-series-type.json +++ b/docs/pages/x/api/charts/line-series-type.json @@ -22,8 +22,6 @@ "stackOrder": { "type": { "description": "StackOrderType" }, "default": "'none'" }, "valueFormatter": { "type": { "description": "SeriesValueFormatter<TValue>" } }, "xAxisId": { "type": { "description": "string" } }, - "xAxisKey": { "type": { "description": "string" } }, - "yAxisId": { "type": { "description": "string" } }, - "yAxisKey": { "type": { "description": "string" } } + "yAxisId": { "type": { "description": "string" } } } } diff --git a/docs/pages/x/api/charts/pie-chart.json b/docs/pages/x/api/charts/pie-chart.json index 1e8d0d773d8a..33ae8035bbe3 100644 --- a/docs/pages/x/api/charts/pie-chart.json +++ b/docs/pages/x/api/charts/pie-chart.json @@ -4,21 +4,6 @@ "type": { "name": "arrayOf", "description": "Array<object>" }, "required": true }, - "axisHighlight": { - "type": { - "name": "shape", - "description": "{ x?: 'band'
| 'line'
| 'none', y?: 'band'
| 'line'
| 'none' }" - }, - "default": "{ x: 'none', y: 'none' }", - "seeMoreLink": { - "url": "https://mui.com/x/react-charts/highlighting", - "text": "highlighting docs" - } - }, - "bottomAxis": { - "type": { "name": "union", "description": "object
| string" }, - "default": "null" - }, "colors": { "type": { "name": "union", "description": "Array<string>
| func" }, "default": "blueberryTwilightPalette" @@ -32,19 +17,6 @@ "description": "{ dataIndex?: number, seriesId?: number
| string }" } }, - "leftAxis": { - "type": { "name": "union", "description": "object
| string" }, - "default": "null" - }, - "legend": { - "type": { - "name": "shape", - "description": "{ classes?: object, direction?: 'column'
| 'row', hidden?: bool, itemGap?: number, itemMarkHeight?: number, itemMarkWidth?: number, labelStyle?: object, markGap?: number, onItemClick?: func, padding?: number
| { bottom?: number, left?: number, right?: number, top?: number }, position?: { horizontal: 'left'
| 'middle'
| 'right', vertical: 'bottom'
| 'middle'
| 'top' }, slotProps?: object, slots?: object }" - }, - "default": "{ direction: 'column', position: { vertical: 'middle', horizontal: 'right' } }", - "deprecated": true, - "deprecationInfo": "Consider using slotProps.legend instead." - }, "loading": { "type": { "name": "bool" }, "default": "false" }, "margin": { "type": { @@ -62,10 +34,6 @@ }, "onItemClick": { "type": { "name": "func" } }, "resolveSizeBeforeRender": { "type": { "name": "bool" }, "default": "false" }, - "rightAxis": { - "type": { "name": "union", "description": "object
| string" }, - "default": "null" - }, "skipAnimation": { "type": { "name": "bool" } }, "slotProps": { "type": { "name": "object" }, "default": "{}" }, "slots": { @@ -81,10 +49,6 @@ "default": "{ trigger: 'item' }", "seeMoreLink": { "url": "https://mui.com/x/react-charts/tooltip/", "text": "tooltip docs" } }, - "topAxis": { - "type": { "name": "union", "description": "object
| string" }, - "default": "null" - }, "width": { "type": { "name": "number" } }, "xAxis": { "type": { @@ -112,30 +76,6 @@ "default": "DefaultChartsAxisTooltipContent", "class": null }, - { - "name": "axisLabel", - "description": "Custom component for axis label.", - "default": "ChartsText", - "class": null - }, - { - "name": "axisLine", - "description": "Custom component for the axis main line.", - "default": "'line'", - "class": null - }, - { - "name": "axisTick", - "description": "Custom component for the axis tick.", - "default": "'line'", - "class": null - }, - { - "name": "axisTickLabel", - "description": "Custom component for tick label.", - "default": "ChartsText", - "class": null - }, { "name": "itemContent", "description": "Custom component for displaying tooltip content when triggered by item event.", diff --git a/docs/pages/x/api/charts/scatter-series-type.json b/docs/pages/x/api/charts/scatter-series-type.json index 9d560abcee2d..5f422acb6896 100644 --- a/docs/pages/x/api/charts/scatter-series-type.json +++ b/docs/pages/x/api/charts/scatter-series-type.json @@ -19,10 +19,7 @@ "markerSize": { "type": { "description": "number" } }, "valueFormatter": { "type": { "description": "SeriesValueFormatter<TValue>" } }, "xAxisId": { "type": { "description": "string" } }, - "xAxisKey": { "type": { "description": "string" } }, "yAxisId": { "type": { "description": "string" } }, - "yAxisKey": { "type": { "description": "string" } }, - "zAxisId": { "type": { "description": "string" } }, - "zAxisKey": { "type": { "description": "string" } } + "zAxisId": { "type": { "description": "string" } } } } diff --git a/docs/pages/x/api/data-grid/data-grid-premium.json b/docs/pages/x/api/data-grid/data-grid-premium.json index 99283c51b8ae..ded5c1bd3c90 100644 --- a/docs/pages/x/api/data-grid/data-grid-premium.json +++ b/docs/pages/x/api/data-grid/data-grid-premium.json @@ -814,6 +814,18 @@ "default": "Divider", "class": null }, + { + "name": "baseMenuList", + "description": "The custom MenuList component used in the grid.", + "default": "MenuList", + "class": null + }, + { + "name": "baseMenuItem", + "description": "The custom MenuItem component used in the grid.", + "default": "MenuItem", + "class": null + }, { "name": "baseInputAdornment", "description": "The custom InputAdornment component used in the grid.", diff --git a/docs/pages/x/api/data-grid/data-grid-pro.json b/docs/pages/x/api/data-grid/data-grid-pro.json index 3a0923e1a1d9..42df3c139311 100644 --- a/docs/pages/x/api/data-grid/data-grid-pro.json +++ b/docs/pages/x/api/data-grid/data-grid-pro.json @@ -746,6 +746,18 @@ "default": "Divider", "class": null }, + { + "name": "baseMenuList", + "description": "The custom MenuList component used in the grid.", + "default": "MenuList", + "class": null + }, + { + "name": "baseMenuItem", + "description": "The custom MenuItem component used in the grid.", + "default": "MenuItem", + "class": null + }, { "name": "baseInputAdornment", "description": "The custom InputAdornment component used in the grid.", diff --git a/docs/pages/x/api/data-grid/data-grid.json b/docs/pages/x/api/data-grid/data-grid.json index 87da7c9e9a81..9994e0dc6317 100644 --- a/docs/pages/x/api/data-grid/data-grid.json +++ b/docs/pages/x/api/data-grid/data-grid.json @@ -633,6 +633,18 @@ "default": "Divider", "class": null }, + { + "name": "baseMenuList", + "description": "The custom MenuList component used in the grid.", + "default": "MenuList", + "class": null + }, + { + "name": "baseMenuItem", + "description": "The custom MenuItem component used in the grid.", + "default": "MenuItem", + "class": null + }, { "name": "baseInputAdornment", "description": "The custom InputAdornment component used in the grid.", diff --git a/docs/pages/x/api/date-pickers/date-calendar.json b/docs/pages/x/api/date-pickers/date-calendar.json index 55aee6f102ab..e38e7f86edc4 100644 --- a/docs/pages/x/api/date-pickers/date-calendar.json +++ b/docs/pages/x/api/date-pickers/date-calendar.json @@ -4,9 +4,9 @@ "classes": { "type": { "name": "object" }, "additionalInfo": { "cssApi": true } }, "dayOfWeekFormatter": { "type": { "name": "func" }, - "default": "(date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", + "default": "(date: PickerValidDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", "signature": { - "type": "function(date: TDate) => string", + "type": "function(date: PickerValidDate) => string", "describedArgs": ["date"], "returned": "string" } @@ -47,7 +47,10 @@ }, "onMonthChange": { "type": { "name": "func" }, - "signature": { "type": "function(month: TDate) => void", "describedArgs": ["month"] } + "signature": { + "type": "function(month: PickerValidDate) => void", + "describedArgs": ["month"] + } }, "onViewChange": { "type": { "name": "func" }, @@ -55,7 +58,7 @@ }, "onYearChange": { "type": { "name": "func" }, - "signature": { "type": "function(year: TDate) => void", "describedArgs": ["year"] } + "signature": { "type": "function(year: PickerValidDate) => void", "describedArgs": ["year"] } }, "openTo": { "type": { @@ -84,7 +87,7 @@ "shouldDisableDate": { "type": { "name": "func" }, "signature": { - "type": "function(day: TDate) => boolean", + "type": "function(day: PickerValidDate) => boolean", "describedArgs": ["day"], "returned": "boolean" } @@ -92,7 +95,7 @@ "shouldDisableMonth": { "type": { "name": "func" }, "signature": { - "type": "function(month: TDate) => boolean", + "type": "function(month: PickerValidDate) => boolean", "describedArgs": ["month"], "returned": "boolean" } @@ -100,7 +103,7 @@ "shouldDisableYear": { "type": { "name": "func" }, "signature": { - "type": "function(year: TDate) => boolean", + "type": "function(year: PickerValidDate) => boolean", "describedArgs": ["year"], "returned": "boolean" } diff --git a/docs/pages/x/api/date-pickers/date-field.json b/docs/pages/x/api/date-pickers/date-field.json index 6aa1c3a910ad..6a53307f3dc3 100644 --- a/docs/pages/x/api/date-pickers/date-field.json +++ b/docs/pages/x/api/date-pickers/date-field.json @@ -76,7 +76,7 @@ "shouldDisableDate": { "type": { "name": "func" }, "signature": { - "type": "function(day: TDate) => boolean", + "type": "function(day: PickerValidDate) => boolean", "describedArgs": ["day"], "returned": "boolean" } @@ -84,7 +84,7 @@ "shouldDisableMonth": { "type": { "name": "func" }, "signature": { - "type": "function(month: TDate) => boolean", + "type": "function(month: PickerValidDate) => boolean", "describedArgs": ["month"], "returned": "boolean" } @@ -92,7 +92,7 @@ "shouldDisableYear": { "type": { "name": "func" }, "signature": { - "type": "function(year: TDate) => boolean", + "type": "function(year: PickerValidDate) => boolean", "describedArgs": ["year"], "returned": "boolean" } diff --git a/docs/pages/x/api/date-pickers/date-picker.json b/docs/pages/x/api/date-pickers/date-picker.json index d3099c56a971..33b4cd3a0f78 100644 --- a/docs/pages/x/api/date-pickers/date-picker.json +++ b/docs/pages/x/api/date-pickers/date-picker.json @@ -7,9 +7,9 @@ }, "dayOfWeekFormatter": { "type": { "name": "func" }, - "default": "(date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", + "default": "(date: PickerValidDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", "signature": { - "type": "function(date: TDate) => string", + "type": "function(date: PickerValidDate) => string", "describedArgs": ["date"], "returned": "string" } @@ -66,7 +66,10 @@ }, "onMonthChange": { "type": { "name": "func" }, - "signature": { "type": "function(month: TDate) => void", "describedArgs": ["month"] } + "signature": { + "type": "function(month: PickerValidDate) => void", + "describedArgs": ["month"] + } }, "onOpen": { "type": { "name": "func" } }, "onSelectedSectionsChange": { @@ -82,7 +85,7 @@ }, "onYearChange": { "type": { "name": "func" }, - "signature": { "type": "function(year: TDate) => void", "describedArgs": ["year"] } + "signature": { "type": "function(year: PickerValidDate) => void", "describedArgs": ["year"] } }, "open": { "type": { "name": "bool" }, "default": "false" }, "openTo": { @@ -120,7 +123,7 @@ "shouldDisableDate": { "type": { "name": "func" }, "signature": { - "type": "function(day: TDate) => boolean", + "type": "function(day: PickerValidDate) => boolean", "describedArgs": ["day"], "returned": "boolean" } @@ -128,7 +131,7 @@ "shouldDisableMonth": { "type": { "name": "func" }, "signature": { - "type": "function(month: TDate) => boolean", + "type": "function(month: PickerValidDate) => boolean", "describedArgs": ["month"], "returned": "boolean" } @@ -136,7 +139,7 @@ "shouldDisableYear": { "type": { "name": "func" }, "signature": { - "type": "function(year: TDate) => boolean", + "type": "function(year: PickerValidDate) => boolean", "describedArgs": ["year"], "returned": "boolean" } diff --git a/docs/pages/x/api/date-pickers/date-range-calendar.json b/docs/pages/x/api/date-pickers/date-range-calendar.json index cdf5928d090c..c8273a887566 100644 --- a/docs/pages/x/api/date-pickers/date-range-calendar.json +++ b/docs/pages/x/api/date-pickers/date-range-calendar.json @@ -16,9 +16,9 @@ }, "dayOfWeekFormatter": { "type": { "name": "func" }, - "default": "(date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", + "default": "(date: PickerValidDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", "signature": { - "type": "function(date: TDate) => string", + "type": "function(date: PickerValidDate) => string", "describedArgs": ["date"], "returned": "string" } @@ -56,7 +56,10 @@ }, "onMonthChange": { "type": { "name": "func" }, - "signature": { "type": "function(month: TDate) => void", "describedArgs": ["month"] } + "signature": { + "type": "function(month: PickerValidDate) => void", + "describedArgs": ["month"] + } }, "onRangePositionChange": { "type": { "name": "func" }, @@ -92,7 +95,7 @@ "shouldDisableDate": { "type": { "name": "func" }, "signature": { - "type": "function(day: TDate, position: string) => boolean", + "type": "function(day: PickerValidDate, position: string) => boolean", "describedArgs": ["day", "position"], "returned": "boolean" } diff --git a/docs/pages/x/api/date-pickers/date-range-picker.json b/docs/pages/x/api/date-pickers/date-range-picker.json index a64156ea0d03..a357693be539 100644 --- a/docs/pages/x/api/date-pickers/date-range-picker.json +++ b/docs/pages/x/api/date-pickers/date-range-picker.json @@ -15,9 +15,9 @@ }, "dayOfWeekFormatter": { "type": { "name": "func" }, - "default": "(date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", + "default": "(date: PickerValidDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", "signature": { - "type": "function(date: TDate) => string", + "type": "function(date: PickerValidDate) => string", "describedArgs": ["date"], "returned": "string" } @@ -76,7 +76,10 @@ }, "onMonthChange": { "type": { "name": "func" }, - "signature": { "type": "function(month: TDate) => void", "describedArgs": ["month"] } + "signature": { + "type": "function(month: PickerValidDate) => void", + "describedArgs": ["month"] + } }, "onOpen": { "type": { "name": "func" } }, "onRangePositionChange": { @@ -121,7 +124,7 @@ "shouldDisableDate": { "type": { "name": "func" }, "signature": { - "type": "function(day: TDate, position: string) => boolean", + "type": "function(day: PickerValidDate, position: string) => boolean", "describedArgs": ["day", "position"], "returned": "boolean" } diff --git a/docs/pages/x/api/date-pickers/date-time-field.json b/docs/pages/x/api/date-pickers/date-time-field.json index 28e462156626..8ddb6b01c5cc 100644 --- a/docs/pages/x/api/date-pickers/date-time-field.json +++ b/docs/pages/x/api/date-pickers/date-time-field.json @@ -83,7 +83,7 @@ "shouldDisableDate": { "type": { "name": "func" }, "signature": { - "type": "function(day: TDate) => boolean", + "type": "function(day: PickerValidDate) => boolean", "describedArgs": ["day"], "returned": "boolean" } @@ -91,7 +91,7 @@ "shouldDisableMonth": { "type": { "name": "func" }, "signature": { - "type": "function(month: TDate) => boolean", + "type": "function(month: PickerValidDate) => boolean", "describedArgs": ["month"], "returned": "boolean" } @@ -99,7 +99,7 @@ "shouldDisableTime": { "type": { "name": "func" }, "signature": { - "type": "function(value: TDate, view: TimeView) => boolean", + "type": "function(value: PickerValidDate, view: TimeView) => boolean", "describedArgs": ["value", "view"], "returned": "boolean" } @@ -107,7 +107,7 @@ "shouldDisableYear": { "type": { "name": "func" }, "signature": { - "type": "function(year: TDate) => boolean", + "type": "function(year: PickerValidDate) => boolean", "describedArgs": ["year"], "returned": "boolean" } diff --git a/docs/pages/x/api/date-pickers/date-time-picker.json b/docs/pages/x/api/date-pickers/date-time-picker.json index 7a40cea6d2a2..c0d304a92e66 100644 --- a/docs/pages/x/api/date-pickers/date-time-picker.json +++ b/docs/pages/x/api/date-pickers/date-time-picker.json @@ -9,9 +9,9 @@ }, "dayOfWeekFormatter": { "type": { "name": "func" }, - "default": "(date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", + "default": "(date: PickerValidDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", "signature": { - "type": "function(date: TDate) => string", + "type": "function(date: PickerValidDate) => string", "describedArgs": ["date"], "returned": "string" } @@ -74,7 +74,10 @@ }, "onMonthChange": { "type": { "name": "func" }, - "signature": { "type": "function(month: TDate) => void", "describedArgs": ["month"] } + "signature": { + "type": "function(month: PickerValidDate) => void", + "describedArgs": ["month"] + } }, "onOpen": { "type": { "name": "func" } }, "onSelectedSectionsChange": { @@ -90,7 +93,7 @@ }, "onYearChange": { "type": { "name": "func" }, - "signature": { "type": "function(year: TDate) => void", "describedArgs": ["year"] } + "signature": { "type": "function(year: PickerValidDate) => void", "describedArgs": ["year"] } }, "open": { "type": { "name": "bool" }, "default": "false" }, "openTo": { @@ -128,7 +131,7 @@ "shouldDisableDate": { "type": { "name": "func" }, "signature": { - "type": "function(day: TDate) => boolean", + "type": "function(day: PickerValidDate) => boolean", "describedArgs": ["day"], "returned": "boolean" } @@ -136,7 +139,7 @@ "shouldDisableMonth": { "type": { "name": "func" }, "signature": { - "type": "function(month: TDate) => boolean", + "type": "function(month: PickerValidDate) => boolean", "describedArgs": ["month"], "returned": "boolean" } @@ -144,7 +147,7 @@ "shouldDisableTime": { "type": { "name": "func" }, "signature": { - "type": "function(value: TDate, view: TimeView) => boolean", + "type": "function(value: PickerValidDate, view: TimeView) => boolean", "describedArgs": ["value", "view"], "returned": "boolean" } @@ -152,7 +155,7 @@ "shouldDisableYear": { "type": { "name": "func" }, "signature": { - "type": "function(year: TDate) => boolean", + "type": "function(year: PickerValidDate) => boolean", "describedArgs": ["year"], "returned": "boolean" } diff --git a/docs/pages/x/api/date-pickers/date-time-range-picker.json b/docs/pages/x/api/date-pickers/date-time-range-picker.json index d1820b9ce74e..d3901e8bc3a0 100644 --- a/docs/pages/x/api/date-pickers/date-time-range-picker.json +++ b/docs/pages/x/api/date-pickers/date-time-range-picker.json @@ -16,9 +16,9 @@ }, "dayOfWeekFormatter": { "type": { "name": "func" }, - "default": "(date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", + "default": "(date: PickerValidDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", "signature": { - "type": "function(date: TDate) => string", + "type": "function(date: PickerValidDate) => string", "describedArgs": ["date"], "returned": "string" } @@ -83,7 +83,10 @@ }, "onMonthChange": { "type": { "name": "func" }, - "signature": { "type": "function(month: TDate) => void", "describedArgs": ["month"] } + "signature": { + "type": "function(month: PickerValidDate) => void", + "describedArgs": ["month"] + } }, "onOpen": { "type": { "name": "func" } }, "onRangePositionChange": { @@ -138,7 +141,7 @@ "shouldDisableDate": { "type": { "name": "func" }, "signature": { - "type": "function(day: TDate, position: string) => boolean", + "type": "function(day: PickerValidDate, position: string) => boolean", "describedArgs": ["day", "position"], "returned": "boolean" } @@ -146,7 +149,7 @@ "shouldDisableTime": { "type": { "name": "func" }, "signature": { - "type": "function(value: TDate, view: TimeView) => boolean", + "type": "function(value: PickerValidDate, view: TimeView) => boolean", "describedArgs": ["value", "view"], "returned": "boolean" } diff --git a/docs/pages/x/api/date-pickers/desktop-date-picker.json b/docs/pages/x/api/date-pickers/desktop-date-picker.json index 4c39c52f7bea..cc8dee6f79e6 100644 --- a/docs/pages/x/api/date-pickers/desktop-date-picker.json +++ b/docs/pages/x/api/date-pickers/desktop-date-picker.json @@ -7,9 +7,9 @@ }, "dayOfWeekFormatter": { "type": { "name": "func" }, - "default": "(date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", + "default": "(date: PickerValidDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", "signature": { - "type": "function(date: TDate) => string", + "type": "function(date: PickerValidDate) => string", "describedArgs": ["date"], "returned": "string" } @@ -62,7 +62,10 @@ }, "onMonthChange": { "type": { "name": "func" }, - "signature": { "type": "function(month: TDate) => void", "describedArgs": ["month"] } + "signature": { + "type": "function(month: PickerValidDate) => void", + "describedArgs": ["month"] + } }, "onOpen": { "type": { "name": "func" } }, "onSelectedSectionsChange": { @@ -78,7 +81,7 @@ }, "onYearChange": { "type": { "name": "func" }, - "signature": { "type": "function(year: TDate) => void", "describedArgs": ["year"] } + "signature": { "type": "function(year: PickerValidDate) => void", "describedArgs": ["year"] } }, "open": { "type": { "name": "bool" }, "default": "false" }, "openTo": { @@ -116,7 +119,7 @@ "shouldDisableDate": { "type": { "name": "func" }, "signature": { - "type": "function(day: TDate) => boolean", + "type": "function(day: PickerValidDate) => boolean", "describedArgs": ["day"], "returned": "boolean" } @@ -124,7 +127,7 @@ "shouldDisableMonth": { "type": { "name": "func" }, "signature": { - "type": "function(month: TDate) => boolean", + "type": "function(month: PickerValidDate) => boolean", "describedArgs": ["month"], "returned": "boolean" } @@ -132,7 +135,7 @@ "shouldDisableYear": { "type": { "name": "func" }, "signature": { - "type": "function(year: TDate) => boolean", + "type": "function(year: PickerValidDate) => boolean", "describedArgs": ["year"], "returned": "boolean" } diff --git a/docs/pages/x/api/date-pickers/desktop-date-range-picker.json b/docs/pages/x/api/date-pickers/desktop-date-range-picker.json index 911ec96679f0..32abb59adbbf 100644 --- a/docs/pages/x/api/date-pickers/desktop-date-range-picker.json +++ b/docs/pages/x/api/date-pickers/desktop-date-range-picker.json @@ -15,9 +15,9 @@ }, "dayOfWeekFormatter": { "type": { "name": "func" }, - "default": "(date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", + "default": "(date: PickerValidDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", "signature": { - "type": "function(date: TDate) => string", + "type": "function(date: PickerValidDate) => string", "describedArgs": ["date"], "returned": "string" } @@ -72,7 +72,10 @@ }, "onMonthChange": { "type": { "name": "func" }, - "signature": { "type": "function(month: TDate) => void", "describedArgs": ["month"] } + "signature": { + "type": "function(month: PickerValidDate) => void", + "describedArgs": ["month"] + } }, "onOpen": { "type": { "name": "func" } }, "onRangePositionChange": { @@ -117,7 +120,7 @@ "shouldDisableDate": { "type": { "name": "func" }, "signature": { - "type": "function(day: TDate, position: string) => boolean", + "type": "function(day: PickerValidDate, position: string) => boolean", "describedArgs": ["day", "position"], "returned": "boolean" } diff --git a/docs/pages/x/api/date-pickers/desktop-date-time-picker.json b/docs/pages/x/api/date-pickers/desktop-date-time-picker.json index 88f2d64e03d3..62a9ffa7411c 100644 --- a/docs/pages/x/api/date-pickers/desktop-date-time-picker.json +++ b/docs/pages/x/api/date-pickers/desktop-date-time-picker.json @@ -9,9 +9,9 @@ }, "dayOfWeekFormatter": { "type": { "name": "func" }, - "default": "(date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", + "default": "(date: PickerValidDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", "signature": { - "type": "function(date: TDate) => string", + "type": "function(date: PickerValidDate) => string", "describedArgs": ["date"], "returned": "string" } @@ -70,7 +70,10 @@ }, "onMonthChange": { "type": { "name": "func" }, - "signature": { "type": "function(month: TDate) => void", "describedArgs": ["month"] } + "signature": { + "type": "function(month: PickerValidDate) => void", + "describedArgs": ["month"] + } }, "onOpen": { "type": { "name": "func" } }, "onSelectedSectionsChange": { @@ -86,7 +89,7 @@ }, "onYearChange": { "type": { "name": "func" }, - "signature": { "type": "function(year: TDate) => void", "describedArgs": ["year"] } + "signature": { "type": "function(year: PickerValidDate) => void", "describedArgs": ["year"] } }, "open": { "type": { "name": "bool" }, "default": "false" }, "openTo": { @@ -124,7 +127,7 @@ "shouldDisableDate": { "type": { "name": "func" }, "signature": { - "type": "function(day: TDate) => boolean", + "type": "function(day: PickerValidDate) => boolean", "describedArgs": ["day"], "returned": "boolean" } @@ -132,7 +135,7 @@ "shouldDisableMonth": { "type": { "name": "func" }, "signature": { - "type": "function(month: TDate) => boolean", + "type": "function(month: PickerValidDate) => boolean", "describedArgs": ["month"], "returned": "boolean" } @@ -140,7 +143,7 @@ "shouldDisableTime": { "type": { "name": "func" }, "signature": { - "type": "function(value: TDate, view: TimeView) => boolean", + "type": "function(value: PickerValidDate, view: TimeView) => boolean", "describedArgs": ["value", "view"], "returned": "boolean" } @@ -148,7 +151,7 @@ "shouldDisableYear": { "type": { "name": "func" }, "signature": { - "type": "function(year: TDate) => boolean", + "type": "function(year: PickerValidDate) => boolean", "describedArgs": ["year"], "returned": "boolean" } diff --git a/docs/pages/x/api/date-pickers/desktop-date-time-range-picker.json b/docs/pages/x/api/date-pickers/desktop-date-time-range-picker.json index 2ffe9722be4a..7f2205b1922d 100644 --- a/docs/pages/x/api/date-pickers/desktop-date-time-range-picker.json +++ b/docs/pages/x/api/date-pickers/desktop-date-time-range-picker.json @@ -16,9 +16,9 @@ }, "dayOfWeekFormatter": { "type": { "name": "func" }, - "default": "(date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", + "default": "(date: PickerValidDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", "signature": { - "type": "function(date: TDate) => string", + "type": "function(date: PickerValidDate) => string", "describedArgs": ["date"], "returned": "string" } @@ -79,7 +79,10 @@ }, "onMonthChange": { "type": { "name": "func" }, - "signature": { "type": "function(month: TDate) => void", "describedArgs": ["month"] } + "signature": { + "type": "function(month: PickerValidDate) => void", + "describedArgs": ["month"] + } }, "onOpen": { "type": { "name": "func" } }, "onRangePositionChange": { @@ -134,7 +137,7 @@ "shouldDisableDate": { "type": { "name": "func" }, "signature": { - "type": "function(day: TDate, position: string) => boolean", + "type": "function(day: PickerValidDate, position: string) => boolean", "describedArgs": ["day", "position"], "returned": "boolean" } @@ -142,7 +145,7 @@ "shouldDisableTime": { "type": { "name": "func" }, "signature": { - "type": "function(value: TDate, view: TimeView) => boolean", + "type": "function(value: PickerValidDate, view: TimeView) => boolean", "describedArgs": ["value", "view"], "returned": "boolean" } diff --git a/docs/pages/x/api/date-pickers/desktop-time-picker.json b/docs/pages/x/api/date-pickers/desktop-time-picker.json index 5ed580f886e8..bc22f8994e8c 100644 --- a/docs/pages/x/api/date-pickers/desktop-time-picker.json +++ b/docs/pages/x/api/date-pickers/desktop-time-picker.json @@ -86,7 +86,7 @@ "shouldDisableTime": { "type": { "name": "func" }, "signature": { - "type": "function(value: TDate, view: TimeView) => boolean", + "type": "function(value: PickerValidDate, view: TimeView) => boolean", "describedArgs": ["value", "view"], "returned": "boolean" } diff --git a/docs/pages/x/api/date-pickers/digital-clock.json b/docs/pages/x/api/date-pickers/digital-clock.json index 332f062056cf..1d06e31bfb38 100644 --- a/docs/pages/x/api/date-pickers/digital-clock.json +++ b/docs/pages/x/api/date-pickers/digital-clock.json @@ -39,7 +39,7 @@ "shouldDisableTime": { "type": { "name": "func" }, "signature": { - "type": "function(value: TDate, view: TimeView) => boolean", + "type": "function(value: PickerValidDate, view: TimeView) => boolean", "describedArgs": ["value", "view"], "returned": "boolean" } diff --git a/docs/pages/x/api/date-pickers/mobile-date-picker.json b/docs/pages/x/api/date-pickers/mobile-date-picker.json index 9f638cdc4f40..6dcd610f508e 100644 --- a/docs/pages/x/api/date-pickers/mobile-date-picker.json +++ b/docs/pages/x/api/date-pickers/mobile-date-picker.json @@ -7,9 +7,9 @@ }, "dayOfWeekFormatter": { "type": { "name": "func" }, - "default": "(date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", + "default": "(date: PickerValidDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", "signature": { - "type": "function(date: TDate) => string", + "type": "function(date: PickerValidDate) => string", "describedArgs": ["date"], "returned": "string" } @@ -62,7 +62,10 @@ }, "onMonthChange": { "type": { "name": "func" }, - "signature": { "type": "function(month: TDate) => void", "describedArgs": ["month"] } + "signature": { + "type": "function(month: PickerValidDate) => void", + "describedArgs": ["month"] + } }, "onOpen": { "type": { "name": "func" } }, "onSelectedSectionsChange": { @@ -78,7 +81,7 @@ }, "onYearChange": { "type": { "name": "func" }, - "signature": { "type": "function(year: TDate) => void", "describedArgs": ["year"] } + "signature": { "type": "function(year: PickerValidDate) => void", "describedArgs": ["year"] } }, "open": { "type": { "name": "bool" }, "default": "false" }, "openTo": { @@ -116,7 +119,7 @@ "shouldDisableDate": { "type": { "name": "func" }, "signature": { - "type": "function(day: TDate) => boolean", + "type": "function(day: PickerValidDate) => boolean", "describedArgs": ["day"], "returned": "boolean" } @@ -124,7 +127,7 @@ "shouldDisableMonth": { "type": { "name": "func" }, "signature": { - "type": "function(month: TDate) => boolean", + "type": "function(month: PickerValidDate) => boolean", "describedArgs": ["month"], "returned": "boolean" } @@ -132,7 +135,7 @@ "shouldDisableYear": { "type": { "name": "func" }, "signature": { - "type": "function(year: TDate) => boolean", + "type": "function(year: PickerValidDate) => boolean", "describedArgs": ["year"], "returned": "boolean" } diff --git a/docs/pages/x/api/date-pickers/mobile-date-range-picker.json b/docs/pages/x/api/date-pickers/mobile-date-range-picker.json index b5b1d54a04cd..4f50f20ccf6b 100644 --- a/docs/pages/x/api/date-pickers/mobile-date-range-picker.json +++ b/docs/pages/x/api/date-pickers/mobile-date-range-picker.json @@ -11,9 +11,9 @@ }, "dayOfWeekFormatter": { "type": { "name": "func" }, - "default": "(date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", + "default": "(date: PickerValidDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", "signature": { - "type": "function(date: TDate) => string", + "type": "function(date: PickerValidDate) => string", "describedArgs": ["date"], "returned": "string" } @@ -68,7 +68,10 @@ }, "onMonthChange": { "type": { "name": "func" }, - "signature": { "type": "function(month: TDate) => void", "describedArgs": ["month"] } + "signature": { + "type": "function(month: PickerValidDate) => void", + "describedArgs": ["month"] + } }, "onOpen": { "type": { "name": "func" } }, "onRangePositionChange": { @@ -113,7 +116,7 @@ "shouldDisableDate": { "type": { "name": "func" }, "signature": { - "type": "function(day: TDate, position: string) => boolean", + "type": "function(day: PickerValidDate, position: string) => boolean", "describedArgs": ["day", "position"], "returned": "boolean" } diff --git a/docs/pages/x/api/date-pickers/mobile-date-time-picker.json b/docs/pages/x/api/date-pickers/mobile-date-time-picker.json index d90b474d9a77..79eb455f2379 100644 --- a/docs/pages/x/api/date-pickers/mobile-date-time-picker.json +++ b/docs/pages/x/api/date-pickers/mobile-date-time-picker.json @@ -9,9 +9,9 @@ }, "dayOfWeekFormatter": { "type": { "name": "func" }, - "default": "(date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", + "default": "(date: PickerValidDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", "signature": { - "type": "function(date: TDate) => string", + "type": "function(date: PickerValidDate) => string", "describedArgs": ["date"], "returned": "string" } @@ -70,7 +70,10 @@ }, "onMonthChange": { "type": { "name": "func" }, - "signature": { "type": "function(month: TDate) => void", "describedArgs": ["month"] } + "signature": { + "type": "function(month: PickerValidDate) => void", + "describedArgs": ["month"] + } }, "onOpen": { "type": { "name": "func" } }, "onSelectedSectionsChange": { @@ -86,7 +89,7 @@ }, "onYearChange": { "type": { "name": "func" }, - "signature": { "type": "function(year: TDate) => void", "describedArgs": ["year"] } + "signature": { "type": "function(year: PickerValidDate) => void", "describedArgs": ["year"] } }, "open": { "type": { "name": "bool" }, "default": "false" }, "openTo": { @@ -124,7 +127,7 @@ "shouldDisableDate": { "type": { "name": "func" }, "signature": { - "type": "function(day: TDate) => boolean", + "type": "function(day: PickerValidDate) => boolean", "describedArgs": ["day"], "returned": "boolean" } @@ -132,7 +135,7 @@ "shouldDisableMonth": { "type": { "name": "func" }, "signature": { - "type": "function(month: TDate) => boolean", + "type": "function(month: PickerValidDate) => boolean", "describedArgs": ["month"], "returned": "boolean" } @@ -140,7 +143,7 @@ "shouldDisableTime": { "type": { "name": "func" }, "signature": { - "type": "function(value: TDate, view: TimeView) => boolean", + "type": "function(value: PickerValidDate, view: TimeView) => boolean", "describedArgs": ["value", "view"], "returned": "boolean" } @@ -148,7 +151,7 @@ "shouldDisableYear": { "type": { "name": "func" }, "signature": { - "type": "function(year: TDate) => boolean", + "type": "function(year: PickerValidDate) => boolean", "describedArgs": ["year"], "returned": "boolean" } diff --git a/docs/pages/x/api/date-pickers/mobile-date-time-range-picker.json b/docs/pages/x/api/date-pickers/mobile-date-time-range-picker.json index 1f6d76bd4612..9228bf05b26d 100644 --- a/docs/pages/x/api/date-pickers/mobile-date-time-range-picker.json +++ b/docs/pages/x/api/date-pickers/mobile-date-time-range-picker.json @@ -12,9 +12,9 @@ }, "dayOfWeekFormatter": { "type": { "name": "func" }, - "default": "(date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", + "default": "(date: PickerValidDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", "signature": { - "type": "function(date: TDate) => string", + "type": "function(date: PickerValidDate) => string", "describedArgs": ["date"], "returned": "string" } @@ -75,7 +75,10 @@ }, "onMonthChange": { "type": { "name": "func" }, - "signature": { "type": "function(month: TDate) => void", "describedArgs": ["month"] } + "signature": { + "type": "function(month: PickerValidDate) => void", + "describedArgs": ["month"] + } }, "onOpen": { "type": { "name": "func" } }, "onRangePositionChange": { @@ -130,7 +133,7 @@ "shouldDisableDate": { "type": { "name": "func" }, "signature": { - "type": "function(day: TDate, position: string) => boolean", + "type": "function(day: PickerValidDate, position: string) => boolean", "describedArgs": ["day", "position"], "returned": "boolean" } @@ -138,7 +141,7 @@ "shouldDisableTime": { "type": { "name": "func" }, "signature": { - "type": "function(value: TDate, view: TimeView) => boolean", + "type": "function(value: PickerValidDate, view: TimeView) => boolean", "describedArgs": ["value", "view"], "returned": "boolean" } diff --git a/docs/pages/x/api/date-pickers/mobile-time-picker.json b/docs/pages/x/api/date-pickers/mobile-time-picker.json index 89ddfed4d56b..64336f642f90 100644 --- a/docs/pages/x/api/date-pickers/mobile-time-picker.json +++ b/docs/pages/x/api/date-pickers/mobile-time-picker.json @@ -86,7 +86,7 @@ "shouldDisableTime": { "type": { "name": "func" }, "signature": { - "type": "function(value: TDate, view: TimeView) => boolean", + "type": "function(value: PickerValidDate, view: TimeView) => boolean", "describedArgs": ["value", "view"], "returned": "boolean" } diff --git a/docs/pages/x/api/date-pickers/month-calendar.json b/docs/pages/x/api/date-pickers/month-calendar.json index d1b1fb06b8bb..5794619b01fc 100644 --- a/docs/pages/x/api/date-pickers/month-calendar.json +++ b/docs/pages/x/api/date-pickers/month-calendar.json @@ -14,7 +14,10 @@ }, "onChange": { "type": { "name": "func" }, - "signature": { "type": "function(value: TDate) => void", "describedArgs": ["value"] } + "signature": { + "type": "function(value: PickerValidDate) => void", + "describedArgs": ["value"] + } }, "readOnly": { "type": { "name": "bool" } }, "referenceDate": { @@ -24,7 +27,7 @@ "shouldDisableMonth": { "type": { "name": "func" }, "signature": { - "type": "function(month: TDate) => boolean", + "type": "function(month: PickerValidDate) => boolean", "describedArgs": ["month"], "returned": "boolean" } diff --git a/docs/pages/x/api/date-pickers/multi-input-date-range-field.json b/docs/pages/x/api/date-pickers/multi-input-date-range-field.json index 244b3c3ff67f..d9e6f2cbf77d 100644 --- a/docs/pages/x/api/date-pickers/multi-input-date-range-field.json +++ b/docs/pages/x/api/date-pickers/multi-input-date-range-field.json @@ -57,7 +57,7 @@ "shouldDisableDate": { "type": { "name": "func" }, "signature": { - "type": "function(day: TDate, position: string) => boolean", + "type": "function(day: PickerValidDate, position: string) => boolean", "describedArgs": ["day", "position"], "returned": "boolean" } diff --git a/docs/pages/x/api/date-pickers/multi-input-date-time-range-field.json b/docs/pages/x/api/date-pickers/multi-input-date-time-range-field.json index eccae7c10c52..783e9b93b467 100644 --- a/docs/pages/x/api/date-pickers/multi-input-date-time-range-field.json +++ b/docs/pages/x/api/date-pickers/multi-input-date-time-range-field.json @@ -64,7 +64,7 @@ "shouldDisableDate": { "type": { "name": "func" }, "signature": { - "type": "function(day: TDate, position: string) => boolean", + "type": "function(day: PickerValidDate, position: string) => boolean", "describedArgs": ["day", "position"], "returned": "boolean" } @@ -72,7 +72,7 @@ "shouldDisableTime": { "type": { "name": "func" }, "signature": { - "type": "function(value: TDate, view: TimeView) => boolean", + "type": "function(value: PickerValidDate, view: TimeView) => boolean", "describedArgs": ["value", "view"], "returned": "boolean" } diff --git a/docs/pages/x/api/date-pickers/multi-input-time-range-field.json b/docs/pages/x/api/date-pickers/multi-input-time-range-field.json index 6065a53110fa..120e10742bd0 100644 --- a/docs/pages/x/api/date-pickers/multi-input-time-range-field.json +++ b/docs/pages/x/api/date-pickers/multi-input-time-range-field.json @@ -60,7 +60,7 @@ "shouldDisableTime": { "type": { "name": "func" }, "signature": { - "type": "function(value: TDate, view: TimeView) => boolean", + "type": "function(value: PickerValidDate, view: TimeView) => boolean", "describedArgs": ["value", "view"], "returned": "boolean" } diff --git a/docs/pages/x/api/date-pickers/multi-section-digital-clock.json b/docs/pages/x/api/date-pickers/multi-section-digital-clock.json index 50b3e3ded3d7..d2b097c5e763 100644 --- a/docs/pages/x/api/date-pickers/multi-section-digital-clock.json +++ b/docs/pages/x/api/date-pickers/multi-section-digital-clock.json @@ -49,7 +49,7 @@ "shouldDisableTime": { "type": { "name": "func" }, "signature": { - "type": "function(value: TDate, view: TimeView) => boolean", + "type": "function(value: PickerValidDate, view: TimeView) => boolean", "describedArgs": ["value", "view"], "returned": "boolean" } diff --git a/docs/pages/x/api/date-pickers/single-input-date-range-field.json b/docs/pages/x/api/date-pickers/single-input-date-range-field.json index d029a9c08222..179b58765222 100644 --- a/docs/pages/x/api/date-pickers/single-input-date-range-field.json +++ b/docs/pages/x/api/date-pickers/single-input-date-range-field.json @@ -77,7 +77,7 @@ "shouldDisableDate": { "type": { "name": "func" }, "signature": { - "type": "function(day: TDate, position: string) => boolean", + "type": "function(day: PickerValidDate, position: string) => boolean", "describedArgs": ["day", "position"], "returned": "boolean" } diff --git a/docs/pages/x/api/date-pickers/single-input-date-time-range-field.json b/docs/pages/x/api/date-pickers/single-input-date-time-range-field.json index dfc1fa601465..483f9c001649 100644 --- a/docs/pages/x/api/date-pickers/single-input-date-time-range-field.json +++ b/docs/pages/x/api/date-pickers/single-input-date-time-range-field.json @@ -84,7 +84,7 @@ "shouldDisableDate": { "type": { "name": "func" }, "signature": { - "type": "function(day: TDate, position: string) => boolean", + "type": "function(day: PickerValidDate, position: string) => boolean", "describedArgs": ["day", "position"], "returned": "boolean" } @@ -92,7 +92,7 @@ "shouldDisableTime": { "type": { "name": "func" }, "signature": { - "type": "function(value: TDate, view: TimeView) => boolean", + "type": "function(value: PickerValidDate, view: TimeView) => boolean", "describedArgs": ["value", "view"], "returned": "boolean" } diff --git a/docs/pages/x/api/date-pickers/single-input-time-range-field.json b/docs/pages/x/api/date-pickers/single-input-time-range-field.json index 9fcb5181883d..fbfcdcd2781e 100644 --- a/docs/pages/x/api/date-pickers/single-input-time-range-field.json +++ b/docs/pages/x/api/date-pickers/single-input-time-range-field.json @@ -80,7 +80,7 @@ "shouldDisableTime": { "type": { "name": "func" }, "signature": { - "type": "function(value: TDate, view: TimeView) => boolean", + "type": "function(value: PickerValidDate, view: TimeView) => boolean", "describedArgs": ["value", "view"], "returned": "boolean" } diff --git a/docs/pages/x/api/date-pickers/static-date-picker.json b/docs/pages/x/api/date-pickers/static-date-picker.json index 8def7ccac462..812b43b131ea 100644 --- a/docs/pages/x/api/date-pickers/static-date-picker.json +++ b/docs/pages/x/api/date-pickers/static-date-picker.json @@ -3,9 +3,9 @@ "autoFocus": { "type": { "name": "bool" } }, "dayOfWeekFormatter": { "type": { "name": "func" }, - "default": "(date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", + "default": "(date: PickerValidDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", "signature": { - "type": "function(date: TDate) => string", + "type": "function(date: PickerValidDate) => string", "describedArgs": ["date"], "returned": "string" } @@ -57,7 +57,10 @@ }, "onMonthChange": { "type": { "name": "func" }, - "signature": { "type": "function(month: TDate) => void", "describedArgs": ["month"] } + "signature": { + "type": "function(month: PickerValidDate) => void", + "describedArgs": ["month"] + } }, "onViewChange": { "type": { "name": "func" }, @@ -65,7 +68,7 @@ }, "onYearChange": { "type": { "name": "func" }, - "signature": { "type": "function(year: TDate) => void", "describedArgs": ["year"] } + "signature": { "type": "function(year: PickerValidDate) => void", "describedArgs": ["year"] } }, "openTo": { "type": { @@ -96,7 +99,7 @@ "shouldDisableDate": { "type": { "name": "func" }, "signature": { - "type": "function(day: TDate) => boolean", + "type": "function(day: PickerValidDate) => boolean", "describedArgs": ["day"], "returned": "boolean" } @@ -104,7 +107,7 @@ "shouldDisableMonth": { "type": { "name": "func" }, "signature": { - "type": "function(month: TDate) => boolean", + "type": "function(month: PickerValidDate) => boolean", "describedArgs": ["month"], "returned": "boolean" } @@ -112,7 +115,7 @@ "shouldDisableYear": { "type": { "name": "func" }, "signature": { - "type": "function(year: TDate) => boolean", + "type": "function(year: PickerValidDate) => boolean", "describedArgs": ["year"], "returned": "boolean" } diff --git a/docs/pages/x/api/date-pickers/static-date-range-picker.json b/docs/pages/x/api/date-pickers/static-date-range-picker.json index eb9b535b7bd5..6948a339c0f0 100644 --- a/docs/pages/x/api/date-pickers/static-date-range-picker.json +++ b/docs/pages/x/api/date-pickers/static-date-range-picker.json @@ -11,9 +11,9 @@ }, "dayOfWeekFormatter": { "type": { "name": "func" }, - "default": "(date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", + "default": "(date: PickerValidDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", "signature": { - "type": "function(date: TDate) => string", + "type": "function(date: PickerValidDate) => string", "describedArgs": ["date"], "returned": "string" } @@ -67,7 +67,10 @@ }, "onMonthChange": { "type": { "name": "func" }, - "signature": { "type": "function(month: TDate) => void", "describedArgs": ["month"] } + "signature": { + "type": "function(month: PickerValidDate) => void", + "describedArgs": ["month"] + } }, "onRangePositionChange": { "type": { "name": "func" }, @@ -97,7 +100,7 @@ "shouldDisableDate": { "type": { "name": "func" }, "signature": { - "type": "function(day: TDate, position: string) => boolean", + "type": "function(day: PickerValidDate, position: string) => boolean", "describedArgs": ["day", "position"], "returned": "boolean" } diff --git a/docs/pages/x/api/date-pickers/static-date-time-picker.json b/docs/pages/x/api/date-pickers/static-date-time-picker.json index ed807f2ccfab..cf48a45f5b7f 100644 --- a/docs/pages/x/api/date-pickers/static-date-time-picker.json +++ b/docs/pages/x/api/date-pickers/static-date-time-picker.json @@ -5,9 +5,9 @@ "autoFocus": { "type": { "name": "bool" } }, "dayOfWeekFormatter": { "type": { "name": "func" }, - "default": "(date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", + "default": "(date: PickerValidDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()", "signature": { - "type": "function(date: TDate) => string", + "type": "function(date: PickerValidDate) => string", "describedArgs": ["date"], "returned": "string" } @@ -65,7 +65,10 @@ }, "onMonthChange": { "type": { "name": "func" }, - "signature": { "type": "function(month: TDate) => void", "describedArgs": ["month"] } + "signature": { + "type": "function(month: PickerValidDate) => void", + "describedArgs": ["month"] + } }, "onViewChange": { "type": { "name": "func" }, @@ -73,7 +76,7 @@ }, "onYearChange": { "type": { "name": "func" }, - "signature": { "type": "function(year: TDate) => void", "describedArgs": ["year"] } + "signature": { "type": "function(year: PickerValidDate) => void", "describedArgs": ["year"] } }, "openTo": { "type": { @@ -104,7 +107,7 @@ "shouldDisableDate": { "type": { "name": "func" }, "signature": { - "type": "function(day: TDate) => boolean", + "type": "function(day: PickerValidDate) => boolean", "describedArgs": ["day"], "returned": "boolean" } @@ -112,7 +115,7 @@ "shouldDisableMonth": { "type": { "name": "func" }, "signature": { - "type": "function(month: TDate) => boolean", + "type": "function(month: PickerValidDate) => boolean", "describedArgs": ["month"], "returned": "boolean" } @@ -120,7 +123,7 @@ "shouldDisableTime": { "type": { "name": "func" }, "signature": { - "type": "function(value: TDate, view: TimeView) => boolean", + "type": "function(value: PickerValidDate, view: TimeView) => boolean", "describedArgs": ["value", "view"], "returned": "boolean" } @@ -128,7 +131,7 @@ "shouldDisableYear": { "type": { "name": "func" }, "signature": { - "type": "function(year: TDate) => boolean", + "type": "function(year: PickerValidDate) => boolean", "describedArgs": ["year"], "returned": "boolean" } diff --git a/docs/pages/x/api/date-pickers/static-time-picker.json b/docs/pages/x/api/date-pickers/static-time-picker.json index b7d4ba33f30f..8e2fefb00aee 100644 --- a/docs/pages/x/api/date-pickers/static-time-picker.json +++ b/docs/pages/x/api/date-pickers/static-time-picker.json @@ -66,7 +66,7 @@ "shouldDisableTime": { "type": { "name": "func" }, "signature": { - "type": "function(value: TDate, view: TimeView) => boolean", + "type": "function(value: PickerValidDate, view: TimeView) => boolean", "describedArgs": ["value", "view"], "returned": "boolean" } diff --git a/docs/pages/x/api/date-pickers/time-clock.json b/docs/pages/x/api/date-pickers/time-clock.json index 9a0eb6b0e057..2b59bb35d2d4 100644 --- a/docs/pages/x/api/date-pickers/time-clock.json +++ b/docs/pages/x/api/date-pickers/time-clock.json @@ -50,7 +50,7 @@ "shouldDisableTime": { "type": { "name": "func" }, "signature": { - "type": "function(value: TDate, view: TimeView) => boolean", + "type": "function(value: PickerValidDate, view: TimeView) => boolean", "describedArgs": ["value", "view"], "returned": "boolean" } diff --git a/docs/pages/x/api/date-pickers/time-field.json b/docs/pages/x/api/date-pickers/time-field.json index fe2713222b37..fb99ace144ee 100644 --- a/docs/pages/x/api/date-pickers/time-field.json +++ b/docs/pages/x/api/date-pickers/time-field.json @@ -79,7 +79,7 @@ "shouldDisableTime": { "type": { "name": "func" }, "signature": { - "type": "function(value: TDate, view: TimeView) => boolean", + "type": "function(value: PickerValidDate, view: TimeView) => boolean", "describedArgs": ["value", "view"], "returned": "boolean" } diff --git a/docs/pages/x/api/date-pickers/time-picker.json b/docs/pages/x/api/date-pickers/time-picker.json index fc3050e0d0c8..e4ce5e054eeb 100644 --- a/docs/pages/x/api/date-pickers/time-picker.json +++ b/docs/pages/x/api/date-pickers/time-picker.json @@ -90,7 +90,7 @@ "shouldDisableTime": { "type": { "name": "func" }, "signature": { - "type": "function(value: TDate, view: TimeView) => boolean", + "type": "function(value: PickerValidDate, view: TimeView) => boolean", "describedArgs": ["value", "view"], "returned": "boolean" } diff --git a/docs/pages/x/api/date-pickers/year-calendar.json b/docs/pages/x/api/date-pickers/year-calendar.json index 3efe3212590e..67c5c221d51e 100644 --- a/docs/pages/x/api/date-pickers/year-calendar.json +++ b/docs/pages/x/api/date-pickers/year-calendar.json @@ -10,7 +10,10 @@ "minDate": { "type": { "name": "object" }, "default": "1900-01-01" }, "onChange": { "type": { "name": "func" }, - "signature": { "type": "function(value: TDate) => void", "describedArgs": ["value"] } + "signature": { + "type": "function(value: PickerValidDate) => void", + "describedArgs": ["value"] + } }, "readOnly": { "type": { "name": "bool" } }, "referenceDate": { @@ -20,7 +23,7 @@ "shouldDisableYear": { "type": { "name": "func" }, "signature": { - "type": "function(year: TDate) => boolean", + "type": "function(year: PickerValidDate) => boolean", "describedArgs": ["year"], "returned": "boolean" } diff --git a/docs/pages/x/api/tree-view/rich-tree-view-pro.json b/docs/pages/x/api/tree-view/rich-tree-view-pro.json index fb4b208b9f1d..79efa8560520 100644 --- a/docs/pages/x/api/tree-view/rich-tree-view-pro.json +++ b/docs/pages/x/api/tree-view/rich-tree-view-pro.json @@ -134,6 +134,10 @@ } }, "selectedItems": { "type": { "name": "any" } }, + "selectionPropagation": { + "type": { "name": "shape", "description": "{ descendants?: bool, parents?: bool }" }, + "default": "{ parents: false, descendants: false }" + }, "slotProps": { "type": { "name": "object" }, "default": "{}" }, "slots": { "type": { "name": "object" }, diff --git a/docs/pages/x/api/tree-view/rich-tree-view.json b/docs/pages/x/api/tree-view/rich-tree-view.json index 98191cec2fc0..83ada41f5bc5 100644 --- a/docs/pages/x/api/tree-view/rich-tree-view.json +++ b/docs/pages/x/api/tree-view/rich-tree-view.json @@ -109,6 +109,10 @@ } }, "selectedItems": { "type": { "name": "any" } }, + "selectionPropagation": { + "type": { "name": "shape", "description": "{ descendants?: bool, parents?: bool }" }, + "default": "{ parents: false, descendants: false }" + }, "slotProps": { "type": { "name": "object" }, "default": "{}" }, "slots": { "type": { "name": "object" }, @@ -164,6 +168,6 @@ "forwardsRefTo": "HTMLUListElement", "filename": "/packages/x-tree-view/src/RichTreeView/RichTreeView.tsx", "inheritance": null, - "demos": "", + "demos": "", "cssComponent": false } diff --git a/docs/pages/x/api/tree-view/simple-tree-view.json b/docs/pages/x/api/tree-view/simple-tree-view.json index b3507fdce74d..bcf5153e9cb5 100644 --- a/docs/pages/x/api/tree-view/simple-tree-view.json +++ b/docs/pages/x/api/tree-view/simple-tree-view.json @@ -73,6 +73,10 @@ } }, "selectedItems": { "type": { "name": "any" } }, + "selectionPropagation": { + "type": { "name": "shape", "description": "{ descendants?: bool, parents?: bool }" }, + "default": "{ parents: false, descendants: false }" + }, "slotProps": { "type": { "name": "object" } }, "slots": { "type": { "name": "object" }, "additionalInfo": { "slotsApi": true } }, "sx": { diff --git a/docs/pages/x/api/tree-view/tree-item-drag-and-drop-overlay.js b/docs/pages/x/api/tree-view/tree-item-drag-and-drop-overlay.js new file mode 100644 index 000000000000..256f275cd77e --- /dev/null +++ b/docs/pages/x/api/tree-view/tree-item-drag-and-drop-overlay.js @@ -0,0 +1,23 @@ +import * as React from 'react'; +import ApiPage from 'docs/src/modules/components/ApiPage'; +import mapApiPageTranslations from 'docs/src/modules/utils/mapApiPageTranslations'; +import jsonPageContent from './tree-item-drag-and-drop-overlay.json'; + +export default function Page(props) { + const { descriptions, pageContent } = props; + return ; +} + +Page.getInitialProps = () => { + const req = require.context( + 'docsx/translations/api-docs/tree-view/tree-item-drag-and-drop-overlay', + false, + /\.\/tree-item-drag-and-drop-overlay.*.json$/, + ); + const descriptions = mapApiPageTranslations(req); + + return { + descriptions, + pageContent: jsonPageContent, + }; +}; diff --git a/docs/pages/x/api/tree-view/tree-item-drag-and-drop-overlay.json b/docs/pages/x/api/tree-view/tree-item-drag-and-drop-overlay.json new file mode 100644 index 000000000000..8c5d38162293 --- /dev/null +++ b/docs/pages/x/api/tree-view/tree-item-drag-and-drop-overlay.json @@ -0,0 +1,15 @@ +{ + "props": {}, + "name": "TreeItemDragAndDropOverlay", + "imports": [ + "import { TreeItemDragAndDropOverlay } from '@mui/x-tree-view/TreeItemDragAndDropOverlay';", + "import { TreeItemDragAndDropOverlay } from '@mui/x-tree-view';", + "import { TreeItemDragAndDropOverlay } from '@mui/x-tree-view-pro';" + ], + "classes": [], + "muiName": "MuiTreeItemDragAndDropOverlay", + "filename": "/packages/x-tree-view/src/TreeItemDragAndDropOverlay/TreeItemDragAndDropOverlay.tsx", + "inheritance": null, + "demos": "", + "cssComponent": false +} diff --git a/docs/pages/x/api/tree-view/tree-item-icon.js b/docs/pages/x/api/tree-view/tree-item-icon.js new file mode 100644 index 000000000000..866a7447a59d --- /dev/null +++ b/docs/pages/x/api/tree-view/tree-item-icon.js @@ -0,0 +1,23 @@ +import * as React from 'react'; +import ApiPage from 'docs/src/modules/components/ApiPage'; +import mapApiPageTranslations from 'docs/src/modules/utils/mapApiPageTranslations'; +import jsonPageContent from './tree-item-icon.json'; + +export default function Page(props) { + const { descriptions, pageContent } = props; + return ; +} + +Page.getInitialProps = () => { + const req = require.context( + 'docsx/translations/api-docs/tree-view/tree-item-icon', + false, + /\.\/tree-item-icon.*.json$/, + ); + const descriptions = mapApiPageTranslations(req); + + return { + descriptions, + pageContent: jsonPageContent, + }; +}; diff --git a/docs/pages/x/api/tree-view/tree-item-icon.json b/docs/pages/x/api/tree-view/tree-item-icon.json new file mode 100644 index 000000000000..adf8622e98fd --- /dev/null +++ b/docs/pages/x/api/tree-view/tree-item-icon.json @@ -0,0 +1,32 @@ +{ + "props": { + "slotProps": { "type": { "name": "object" }, "default": "{}" }, + "slots": { + "type": { "name": "object" }, + "default": "{}", + "additionalInfo": { "slotsApi": true } + } + }, + "name": "TreeItemIcon", + "imports": [ + "import { TreeItemIcon } from '@mui/x-tree-view/TreeItemIcon';", + "import { TreeItemIcon } from '@mui/x-tree-view';", + "import { TreeItemIcon } from '@mui/x-tree-view-pro';" + ], + "slots": [ + { "name": "collapseIcon", "description": "The icon used to collapse the item.", "class": null }, + { "name": "expandIcon", "description": "The icon used to expand the item.", "class": null }, + { "name": "endIcon", "description": "The icon displayed next to an end item.", "class": null }, + { + "name": "icon", + "description": "The icon to display next to the Tree Item's label.", + "class": null + } + ], + "classes": [], + "muiName": "MuiTreeItemIcon", + "filename": "/packages/x-tree-view/src/TreeItemIcon/TreeItemIcon.tsx", + "inheritance": null, + "demos": "", + "cssComponent": false +} diff --git a/docs/pages/x/api/tree-view/tree-item.json b/docs/pages/x/api/tree-view/tree-item.json index 1d0f0081cc6a..be0a273ec4c0 100644 --- a/docs/pages/x/api/tree-view/tree-item.json +++ b/docs/pages/x/api/tree-view/tree-item.json @@ -3,19 +3,10 @@ "itemId": { "type": { "name": "string" }, "required": true }, "children": { "type": { "name": "node" } }, "classes": { "type": { "name": "object" }, "additionalInfo": { "cssApi": true } }, - "ContentComponent": { - "type": { "name": "custom", "description": "element type" }, - "default": "TreeItemContent", - "deprecated": true, - "deprecationInfo": "Consider using the <TreeItem2 /> component or the useTreeItem2 hook instead. For more details, see https://mui.com/x/react-tree-view/tree-item-customization/." - }, - "ContentProps": { - "type": { "name": "object" }, - "deprecated": true, - "deprecationInfo": "Consider using the <TreeItem2 /> component or the useTreeItem2 hook instead. For more details, see https://mui.com/x/react-tree-view/tree-item-customization/." - }, "disabled": { "type": { "name": "bool" }, "default": "false" }, + "id": { "type": { "name": "string" } }, "label": { "type": { "name": "node" } }, + "onBlur": { "type": { "name": "func" } }, "onFocus": { "type": { "name": "custom", "description": "unsupportedProp" } }, "onKeyDown": { "type": { "name": "func" } }, "slotProps": { "type": { "name": "object" }, "default": "{}" }, @@ -23,13 +14,6 @@ "type": { "name": "object" }, "default": "{}", "additionalInfo": { "slotsApi": true } - }, - "sx": { - "type": { - "name": "union", - "description": "Array<func
| object
| bool>
| func
| object" - }, - "additionalInfo": { "sx": true } } }, "name": "TreeItem", @@ -39,6 +23,54 @@ "import { TreeItem } from '@mui/x-tree-view-pro';" ], "slots": [ + { + "name": "root", + "description": "The component that renders the root.", + "default": "TreeItemRoot", + "class": "MuiTreeItem-root" + }, + { + "name": "content", + "description": "The component that renders the content of the item.\n(e.g.: everything related to this item, not to its children).", + "default": "TreeItemContent", + "class": "MuiTreeItem-content" + }, + { + "name": "groupTransition", + "description": "The component that renders the children of the item.", + "default": "TreeItemGroupTransition", + "class": "MuiTreeItem-groupTransition" + }, + { + "name": "iconContainer", + "description": "The component that renders the icon.", + "default": "TreeItemIconContainer", + "class": "MuiTreeItem-iconContainer" + }, + { + "name": "checkbox", + "description": "The component that renders the item checkbox for selection.", + "default": "TreeItemCheckbox", + "class": "MuiTreeItem-checkbox" + }, + { + "name": "label", + "description": "The component that renders the item label.", + "default": "TreeItemLabel", + "class": "MuiTreeItem-label" + }, + { + "name": "labelInput", + "description": "The component that renders the input to edit the label when the item is editable and is currently being edited.", + "default": "TreeItemLabelInput", + "class": "MuiTreeItem-labelInput" + }, + { + "name": "dragAndDropOverlay", + "description": "The component that renders the overlay when an item reordering is ongoing.\nWarning: This slot is only useful when using the `` component.", + "default": "TreeItemDragAndDropOverlay", + "class": "MuiTreeItem-dragAndDropOverlay" + }, { "name": "collapseIcon", "description": "The icon used to collapse the item.", "class": null }, { "name": "expandIcon", "description": "The icon used to expand the item.", "class": null }, { "name": "endIcon", "description": "The icon displayed next to an end item.", "class": null }, @@ -46,39 +78,15 @@ "name": "icon", "description": "The icon to display next to the Tree Item's label.", "class": null - }, - { - "name": "groupTransition", - "description": "The component that animates the appearance / disappearance of the item's children.", - "default": "TreeItem2Group", - "class": "MuiTreeItem-groupTransition" } ], "classes": [ - { - "key": "checkbox", - "className": "MuiTreeItem-checkbox", - "description": "Styles applied to the checkbox element.", - "isGlobal": false - }, - { - "key": "content", - "className": "MuiTreeItem-content", - "description": "Styles applied to the content element.", - "isGlobal": false - }, { "key": "disabled", "className": "Mui-disabled", "description": "State class applied to the element when disabled.", "isGlobal": true }, - { - "key": "dragAndDropOverlay", - "className": "MuiTreeItem-dragAndDropOverlay", - "description": "Styles applied to the drag and drop overlay.", - "isGlobal": false - }, { "key": "editable", "className": "MuiTreeItem-editable", @@ -103,30 +111,6 @@ "description": "State class applied to the content element when focused.", "isGlobal": true }, - { - "key": "iconContainer", - "className": "MuiTreeItem-iconContainer", - "description": "Styles applied to the Tree Item icon.", - "isGlobal": false - }, - { - "key": "label", - "className": "MuiTreeItem-label", - "description": "Styles applied to the label element.", - "isGlobal": false - }, - { - "key": "labelInput", - "className": "MuiTreeItem-labelInput", - "description": "Styles applied to the input element that is visible when editing is enabled.", - "isGlobal": false - }, - { - "key": "root", - "className": "MuiTreeItem-root", - "description": "Styles applied to the root element.", - "isGlobal": false - }, { "key": "selected", "className": "Mui-selected", @@ -140,6 +124,6 @@ "forwardsRefTo": "HTMLLIElement", "filename": "/packages/x-tree-view/src/TreeItem/TreeItem.tsx", "inheritance": null, - "demos": "", + "demos": "", "cssComponent": false } diff --git a/docs/pages/x/api/tree-view/tree-view.json b/docs/pages/x/api/tree-view/tree-view.json index dc8fc5e8013f..c9f0691c2b7b 100644 --- a/docs/pages/x/api/tree-view/tree-view.json +++ b/docs/pages/x/api/tree-view/tree-view.json @@ -73,6 +73,10 @@ } }, "selectedItems": { "type": { "name": "any" } }, + "selectionPropagation": { + "type": { "name": "shape", "description": "{ descendants?: bool, parents?: bool }" }, + "default": "{ parents: false, descendants: false }" + }, "slotProps": { "type": { "name": "object" } }, "slots": { "type": { "name": "object" }, "additionalInfo": { "slotsApi": true } }, "sx": { diff --git a/docs/pages/x/migration/migration-charts-v7.js b/docs/pages/x/migration/migration-charts-v7.js new file mode 100644 index 000000000000..09b47f90866e --- /dev/null +++ b/docs/pages/x/migration/migration-charts-v7.js @@ -0,0 +1,7 @@ +import * as React from 'react'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import * as pageProps from 'docsx/data/migration/migration-charts-v7/migration-charts-v7.md?muiMarkdown'; + +export default function Page() { + return ; +} diff --git a/docs/pages/x/migration/migration-data-grid-v7.js b/docs/pages/x/migration/migration-data-grid-v7.js new file mode 100644 index 000000000000..454b6a6e813e --- /dev/null +++ b/docs/pages/x/migration/migration-data-grid-v7.js @@ -0,0 +1,7 @@ +import * as React from 'react'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import * as pageProps from 'docsx/data/migration/migration-data-grid-v7/migration-data-grid-v7.md?muiMarkdown'; + +export default function Page() { + return ; +} diff --git a/docs/pages/x/migration/migration-pickers-v7.js b/docs/pages/x/migration/migration-pickers-v7.js new file mode 100644 index 000000000000..24de8699a05f --- /dev/null +++ b/docs/pages/x/migration/migration-pickers-v7.js @@ -0,0 +1,7 @@ +import * as React from 'react'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import * as pageProps from 'docsx/data/migration/migration-pickers-v7/migration-pickers-v7.md?muiMarkdown'; + +export default function Page() { + return ; +} diff --git a/docs/pages/x/migration/migration-tree-view-v7.js b/docs/pages/x/migration/migration-tree-view-v7.js new file mode 100644 index 000000000000..6dd80f8e2a2d --- /dev/null +++ b/docs/pages/x/migration/migration-tree-view-v7.js @@ -0,0 +1,7 @@ +import * as React from 'react'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import * as pageProps from 'docsx/data/migration/migration-tree-view-v7/migration-tree-view-v7.md?muiMarkdown'; + +export default function Page() { + return ; +} diff --git a/docs/public/static/x/tree-view-illustrations/tree-item-dark.png b/docs/public/static/x/tree-view-illustrations/tree-item-dark.png index 9cd285c3d2797479699f247cd3d563405a3a8d69..4067c0fb25a5dcd45838e3231b2d89b51f1b9573 100644 GIT binary patch literal 47994 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 IU7J_`0hrkkHUIzs literal 47445 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 diff --git a/docs/public/static/x/tree-view-illustrations/tree-item-light.png b/docs/public/static/x/tree-view-illustrations/tree-item-light.png index 052d8359525c4dd5f75b7c82c71b7d64459c317c..355f6c8813406f4285c04a4e516817ef9985a7ad 100644 GIT binary patch literal 48820 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 WEw(ibY^1Ypeox0x8>MCU;y(ZcOg4}J literal 48527 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 H{NjHBLjKJq diff --git a/docs/scripts/generateProptypes.ts b/docs/scripts/generateProptypes.ts index c68602a94873..b15053b7c1fd 100644 --- a/docs/scripts/generateProptypes.ts +++ b/docs/scripts/generateProptypes.ts @@ -13,9 +13,9 @@ import { createXTypeScriptProjects, XTypeScriptProject } from './createXTypeScri const COMPONENTS_WITHOUT_PROPTYPES = ['ChartsAxisTooltipContent', 'ChartsItemTooltipContent']; async function generateProptypes(project: XTypeScriptProject, sourceFile: string) { - const isTDate = (name: string) => { + const isDateObject = (name: string) => { if (['x-date-pickers', 'x-date-pickers-pro'].includes(project.name)) { - const T_DATE_PROPS = [ + const DATE_OBJECT_PROPS = [ 'value', 'defaultValue', 'minDate', @@ -30,7 +30,7 @@ async function generateProptypes(project: XTypeScriptProject, sourceFile: string 'month', ]; - if (T_DATE_PROPS.includes(name)) { + if (DATE_OBJECT_PROPS.includes(name)) { return true; } } @@ -80,13 +80,13 @@ async function generateProptypes(project: XTypeScriptProject, sourceFile: string return false; } - if (isTDate(name)) { + if (isDateObject(name)) { return false; } return undefined; }, - shouldUseObjectForDate: ({ name }) => isTDate(name), + shouldUseObjectForDate: ({ name }) => isDateObject(name), }); if (components.length === 0) { diff --git a/docs/src/modules/components/ChartFeaturesGrid.js b/docs/src/modules/components/ChartFeaturesGrid.js index 36af272ba23c..7da1be867826 100644 --- a/docs/src/modules/components/ChartFeaturesGrid.js +++ b/docs/src/modules/components/ChartFeaturesGrid.js @@ -1,12 +1,16 @@ import * as React from 'react'; import Grid from '@mui/material/Grid'; import { InfoCard } from '@mui/docs/InfoCard'; -import LineAxisRoundedIcon from '@mui/icons-material/LineAxisRounded'; +import ChatBubbleRoundedIcon from '@mui/icons-material/ChatBubble'; import DashboardCustomizeRoundedIcon from '@mui/icons-material/DashboardCustomizeRounded'; +import ExtensionRoundedIcon from '@mui/icons-material/Extension'; +import HighlightRoundedIcon from '@mui/icons-material/Highlight'; +import LabelImportantRoundedIcon from '@mui/icons-material/LabelImportant'; import LegendToggleRoundedIcon from '@mui/icons-material/LegendToggleRounded'; +import LineAxisRoundedIcon from '@mui/icons-material/LineAxisRounded'; import StackedBarChartRoundedIcon from '@mui/icons-material/StackedBarChartRounded'; import StyleRoundedIcon from '@mui/icons-material/StyleRounded'; -import TipsAndUpdatesRoundedIcon from '@mui/icons-material/TipsAndUpdatesRounded'; +import ZoomInRoundedIcon from '@mui/icons-material/ZoomIn'; const content = [ { @@ -19,6 +23,16 @@ const content = [ link: '/x/react-charts/components/', icon: , }, + { + title: 'Composition', + link: '/x/react-charts/composition/', + icon: , + }, + { + title: 'Label', + link: '/x/react-charts/label/', + icon: , + }, { title: 'Legend', link: '/x/react-charts/legend/', @@ -35,9 +49,19 @@ const content = [ icon: , }, { - title: 'Tooltips and highlights', + title: 'Tooltips', link: '/x/react-charts/tooltip/', - icon: , + icon: , + }, + { + title: 'Highlighting', + link: '/x/react-charts/highlighting/', + icon: , + }, + { + title: 'Zoom and pan', + link: '/x/react-charts/zoom-and-pan/', + icon: , }, ]; @@ -45,7 +69,7 @@ export default function ChartFeaturesGrid() { return ( {content.map(({ icon, title, link }) => ( - + ))} diff --git a/docs/src/modules/components/ChartsInstallationInstructions.js b/docs/src/modules/components/ChartsInstallationInstructions.js index b11fd2a21135..eeb2d1af8627 100644 --- a/docs/src/modules/components/ChartsInstallationInstructions.js +++ b/docs/src/modules/components/ChartsInstallationInstructions.js @@ -4,8 +4,8 @@ import InstallationInstructions from './InstallationInstructions'; // #default-branch-switch const packages = { - Community: '@mui/x-charts', - Pro: '@mui/x-charts-pro', + Community: '@mui/x-charts@next', + Pro: '@mui/x-charts-pro@next', }; export default function DataGridInstallationInstructions() { diff --git a/docs/src/modules/components/DataGridInstallationInstructions.js b/docs/src/modules/components/DataGridInstallationInstructions.js index fd41a7bddc3e..030004edd155 100644 --- a/docs/src/modules/components/DataGridInstallationInstructions.js +++ b/docs/src/modules/components/DataGridInstallationInstructions.js @@ -4,9 +4,9 @@ import InstallationInstructions from './InstallationInstructions'; // #default-branch-switch const packages = { - Community: '@mui/x-data-grid', - Pro: '@mui/x-data-grid-pro', - Premium: '@mui/x-data-grid-premium', + Community: '@mui/x-data-grid@next', + Pro: '@mui/x-data-grid-pro@next', + Premium: '@mui/x-data-grid-premium@next', }; export default function DataGridInstallationInstructions() { diff --git a/docs/src/modules/components/PickersInstallationInstructions.js b/docs/src/modules/components/PickersInstallationInstructions.js index 1282d02797a6..bac6c64d7c20 100644 --- a/docs/src/modules/components/PickersInstallationInstructions.js +++ b/docs/src/modules/components/PickersInstallationInstructions.js @@ -4,8 +4,8 @@ import InstallationInstructions from './InstallationInstructions'; // #default-branch-switch const packages = { - Community: '@mui/x-date-pickers', - Pro: '@mui/x-date-pickers-pro', + Community: '@mui/x-date-pickers@next', + Pro: '@mui/x-date-pickers-pro@next', }; const peerDependency = { diff --git a/docs/src/modules/components/PickersPlayground.tsx b/docs/src/modules/components/PickersPlayground.tsx index 5980b1565b98..7366b804e184 100644 --- a/docs/src/modules/components/PickersPlayground.tsx +++ b/docs/src/modules/components/PickersPlayground.tsx @@ -370,7 +370,7 @@ export default function PickersPlayground() { const dateViews = React.useMemo(() => availableViews.filter(isDatePickerView), [availableViews]); const timeViews = React.useMemo(() => availableViews.filter(isTimeView), [availableViews]); - const commonProps = React.useMemo>( + const commonProps = React.useMemo( () => ({ orientation: isLandscape ? 'landscape' : 'portrait', showDaysOutsideCurrentMonth, diff --git a/docs/src/modules/components/TreeViewInstallationInstructions.js b/docs/src/modules/components/TreeViewInstallationInstructions.js index d05d2ebba846..fdec6c899509 100644 --- a/docs/src/modules/components/TreeViewInstallationInstructions.js +++ b/docs/src/modules/components/TreeViewInstallationInstructions.js @@ -4,8 +4,8 @@ import InstallationInstructions from './InstallationInstructions'; // #default-branch-switch const packages = { - Community: '@mui/x-tree-view', - Pro: '@mui/x-tree-view-pro', + Community: '@mui/x-tree-view@next', + Pro: '@mui/x-tree-view-pro@next', }; export default function TreeViewInstallationInstructions() { diff --git a/docs/src/modules/components/overview/Keyboard.tsx b/docs/src/modules/components/overview/Keyboard.tsx index 2d0a141601f0..1f4beb6a6746 100644 --- a/docs/src/modules/components/overview/Keyboard.tsx +++ b/docs/src/modules/components/overview/Keyboard.tsx @@ -487,7 +487,6 @@ export default function Keyboard() { onKeyUp={() => { setSelectedKey(null); }} - enableAccessibleFieldDOMStructure onSelectedSectionsChange={(newSelectedSection) => { selectedSection.current = newSelectedSection; }} diff --git a/docs/src/modules/components/overview/mainDemo/Clock.tsx b/docs/src/modules/components/overview/mainDemo/Clock.tsx index 2b1b1d5eb80b..6ca16f44532e 100644 --- a/docs/src/modules/components/overview/mainDemo/Clock.tsx +++ b/docs/src/modules/components/overview/mainDemo/Clock.tsx @@ -31,7 +31,7 @@ const StyledLayout = styled(PickersLayoutRoot)({ }, }); -function CustomLayout(props: PickersLayoutProps) { +function CustomLayout(props: PickersLayoutProps) { const { actionBar, content, toolbar } = usePickerLayout(props); return ( diff --git a/docs/src/modules/components/overview/mainDemo/DateRangeWithShortcuts.tsx b/docs/src/modules/components/overview/mainDemo/DateRangeWithShortcuts.tsx index a197487ce22d..c8a9df4ce611 100644 --- a/docs/src/modules/components/overview/mainDemo/DateRangeWithShortcuts.tsx +++ b/docs/src/modules/components/overview/mainDemo/DateRangeWithShortcuts.tsx @@ -55,7 +55,7 @@ const shortcutsItems: PickersShortcutsItem>[] = [ { label: 'Reset', getValue: () => [null, null] }, ]; -interface CustomLayoutProps extends PickersLayoutProps, Dayjs, 'day'> { +interface CustomLayoutProps extends PickersLayoutProps, 'day'> { isHorizontal?: boolean; } function CustomLayout(props: CustomLayoutProps) { diff --git a/docs/src/modules/components/overview/mainDemo/DigitalClock.tsx b/docs/src/modules/components/overview/mainDemo/DigitalClock.tsx index d7c96867004b..b6959d39ed3f 100644 --- a/docs/src/modules/components/overview/mainDemo/DigitalClock.tsx +++ b/docs/src/modules/components/overview/mainDemo/DigitalClock.tsx @@ -24,7 +24,7 @@ const StyledLayout = styled(PickersLayoutRoot)({ }, }); -function CustomLayout(props: PickersLayoutProps) { +function CustomLayout(props: PickersLayoutProps) { const { actionBar, content } = usePickerLayout(props); return ( @@ -57,7 +57,7 @@ export default function DigitalClock() { hours: renderMultiSectionDigitalClockTimeView, minutes: renderMultiSectionDigitalClockTimeView, meridiem: renderMultiSectionDigitalClockTimeView, - } as StaticTimePickerProps['viewRenderers'] + } as StaticTimePickerProps['viewRenderers'] } /> diff --git a/docs/src/modules/components/overview/mainDemo/PickerButton.tsx b/docs/src/modules/components/overview/mainDemo/PickerButton.tsx index 0dc82b364e0f..7dee0bad4fed 100644 --- a/docs/src/modules/components/overview/mainDemo/PickerButton.tsx +++ b/docs/src/modules/components/overview/mainDemo/PickerButton.tsx @@ -9,11 +9,18 @@ import { BaseSingleInputFieldProps, DateValidationError, FieldSection, + PickerValidDate, } from '@mui/x-date-pickers/models'; interface ButtonFieldProps - extends UseDateFieldProps, - BaseSingleInputFieldProps { + extends UseDateFieldProps, + BaseSingleInputFieldProps< + // This usage of PickerValidDate will go away with TIsRange + PickerValidDate | null, + FieldSection, + true, + DateValidationError + > { setOpen?: React.Dispatch>; } diff --git a/docs/translations/api-docs/charts/bar-series-type.json b/docs/translations/api-docs/charts/bar-series-type.json index 179d3e15bd8e..ebb278d10e61 100644 --- a/docs/translations/api-docs/charts/bar-series-type.json +++ b/docs/translations/api-docs/charts/bar-series-type.json @@ -22,8 +22,6 @@ "description": "Formatter used to render values in tooltip or other data display." }, "xAxisId": { "description": "The id of the x-axis used to render the series." }, - "xAxisKey": { "description": "The id of the x-axis used to render the series." }, - "yAxisId": { "description": "The id of the y-axis used to render the series." }, - "yAxisKey": { "description": "The id of the y-axis used to render the series." } + "yAxisId": { "description": "The id of the y-axis used to render the series." } } } diff --git a/docs/translations/api-docs/charts/line-series-type.json b/docs/translations/api-docs/charts/line-series-type.json index c7c871a6b8e8..62a540a7437a 100644 --- a/docs/translations/api-docs/charts/line-series-type.json +++ b/docs/translations/api-docs/charts/line-series-type.json @@ -37,8 +37,6 @@ "description": "Formatter used to render values in tooltip or other data display." }, "xAxisId": { "description": "The id of the x-axis used to render the series." }, - "xAxisKey": { "description": "The id of the x-axis used to render the series." }, - "yAxisId": { "description": "The id of the y-axis used to render the series." }, - "yAxisKey": { "description": "The id of the y-axis used to render the series." } + "yAxisId": { "description": "The id of the y-axis used to render the series." } } } diff --git a/docs/translations/api-docs/charts/pie-chart/pie-chart.json b/docs/translations/api-docs/charts/pie-chart/pie-chart.json index 86d14a746ffb..fe7624f98324 100644 --- a/docs/translations/api-docs/charts/pie-chart/pie-chart.json +++ b/docs/translations/api-docs/charts/pie-chart/pie-chart.json @@ -1,13 +1,6 @@ { "componentDescription": "", "propDescriptions": { - "axisHighlight": { - "description": "The configuration of axes highlight.", - "seeMoreText": "See {{link}} for more details." - }, - "bottomAxis": { - "description": "Indicate which axis to display the bottom of the charts. Can be a string (the id of the axis) or an object ChartsXAxisProps." - }, "colors": { "description": "Color palette used to colorize multiple series." }, "dataset": { "description": "An array of objects that can be used to populate series and axes data using their dataKey property." @@ -21,10 +14,6 @@ "highlightedItem": { "description": "The item currently highlighted. Turns highlighting into a controlled prop." }, - "leftAxis": { - "description": "Indicate which axis to display the left of the charts. Can be a string (the id of the axis) or an object ChartsYAxisProps." - }, - "legend": { "description": "The props of the legend." }, "loading": { "description": "If true, a loading overlay is displayed." }, "margin": { "description": "The margin between the SVG and the drawing area. It's used for leaving some space for extra information such as the x- and y-axis or legend. Accepts an object with the optional properties: top, bottom, left, and right." @@ -37,9 +26,6 @@ "resolveSizeBeforeRender": { "description": "The chart will try to wait for the parent container to resolve its size before it renders for the first time.
This can be useful in some scenarios where the chart appear to grow after the first render, like when used inside a grid." }, - "rightAxis": { - "description": "Indicate which axis to display the right of the charts. Can be a string (the id of the axis) or an object ChartsYAxisProps." - }, "series": { "description": "The series to display in the pie chart. An array of PieSeriesType objects." }, @@ -52,9 +38,6 @@ "description": "The configuration of the tooltip.", "seeMoreText": "See {{link}} for more details." }, - "topAxis": { - "description": "Indicate which axis to display the top of the charts. Can be a string (the id of the axis) or an object ChartsXAxisProps." - }, "width": { "description": "The width of the chart in px. If not defined, it takes the width of the parent element." }, @@ -68,10 +51,6 @@ "classDescriptions": {}, "slotDescriptions": { "axisContent": "Custom component for displaying tooltip content when triggered by axis event.", - "axisLabel": "Custom component for axis label.", - "axisLine": "Custom component for the axis main line.", - "axisTick": "Custom component for the axis tick.", - "axisTickLabel": "Custom component for tick label.", "itemContent": "Custom component for displaying tooltip content when triggered by item event.", "legend": "Custom rendering of the legend.", "loadingOverlay": "Overlay component rendered when the chart is in a loading state.", diff --git a/docs/translations/api-docs/charts/scatter-series-type.json b/docs/translations/api-docs/charts/scatter-series-type.json index 4f3fed0aa9e9..58a593f0bdbf 100644 --- a/docs/translations/api-docs/charts/scatter-series-type.json +++ b/docs/translations/api-docs/charts/scatter-series-type.json @@ -20,10 +20,7 @@ "description": "Formatter used to render values in tooltip or other data display." }, "xAxisId": { "description": "The id of the x-axis used to render the series." }, - "xAxisKey": { "description": "The id of the x-axis used to render the series." }, "yAxisId": { "description": "The id of the y-axis used to render the series." }, - "yAxisKey": { "description": "The id of the y-axis used to render the series." }, - "zAxisId": { "description": "The id of the z-axis used to render the series." }, - "zAxisKey": { "description": "The id of the z-axis used to render the series." } + "zAxisId": { "description": "The id of the z-axis used to render the series." } } } diff --git a/docs/translations/api-docs/data-grid/data-grid-premium/data-grid-premium.json b/docs/translations/api-docs/data-grid/data-grid-premium/data-grid-premium.json index dc242fd21180..3b9442aa58e3 100644 --- a/docs/translations/api-docs/data-grid/data-grid-premium/data-grid-premium.json +++ b/docs/translations/api-docs/data-grid/data-grid-premium/data-grid-premium.json @@ -1239,6 +1239,8 @@ "baseIconButton": "The custom IconButton component used in the grid.", "baseInputAdornment": "The custom InputAdornment component used in the grid.", "baseInputLabel": "The custom InputLabel component used in the grid.", + "baseMenuItem": "The custom MenuItem component used in the grid.", + "baseMenuList": "The custom MenuList component used in the grid.", "basePopper": "The custom Popper component used in the grid.", "baseSelect": "The custom Select component used in the grid.", "baseSelectOption": "The custom SelectOption component used in the grid.", diff --git a/docs/translations/api-docs/data-grid/data-grid-pro/data-grid-pro.json b/docs/translations/api-docs/data-grid/data-grid-pro/data-grid-pro.json index 42302d388bbf..c1d26982ac46 100644 --- a/docs/translations/api-docs/data-grid/data-grid-pro/data-grid-pro.json +++ b/docs/translations/api-docs/data-grid/data-grid-pro/data-grid-pro.json @@ -1177,6 +1177,8 @@ "baseIconButton": "The custom IconButton component used in the grid.", "baseInputAdornment": "The custom InputAdornment component used in the grid.", "baseInputLabel": "The custom InputLabel component used in the grid.", + "baseMenuItem": "The custom MenuItem component used in the grid.", + "baseMenuList": "The custom MenuList component used in the grid.", "basePopper": "The custom Popper component used in the grid.", "baseSelect": "The custom Select component used in the grid.", "baseSelectOption": "The custom SelectOption component used in the grid.", diff --git a/docs/translations/api-docs/data-grid/data-grid/data-grid.json b/docs/translations/api-docs/data-grid/data-grid/data-grid.json index 141c83b1b2eb..d082ef5d495d 100644 --- a/docs/translations/api-docs/data-grid/data-grid/data-grid.json +++ b/docs/translations/api-docs/data-grid/data-grid/data-grid.json @@ -1057,6 +1057,8 @@ "baseIconButton": "The custom IconButton component used in the grid.", "baseInputAdornment": "The custom InputAdornment component used in the grid.", "baseInputLabel": "The custom InputLabel component used in the grid.", + "baseMenuItem": "The custom MenuItem component used in the grid.", + "baseMenuList": "The custom MenuList component used in the grid.", "basePopper": "The custom Popper component used in the grid.", "baseSelect": "The custom Select component used in the grid.", "baseSelectOption": "The custom SelectOption component used in the grid.", diff --git a/docs/translations/api-docs/tree-view/rich-tree-view-pro/rich-tree-view-pro.json b/docs/translations/api-docs/tree-view/rich-tree-view-pro/rich-tree-view-pro.json index d7edf9c18d6d..b43dd9784328 100644 --- a/docs/translations/api-docs/tree-view/rich-tree-view-pro/rich-tree-view-pro.json +++ b/docs/translations/api-docs/tree-view/rich-tree-view-pro/rich-tree-view-pro.json @@ -137,6 +137,9 @@ "selectedItems": { "description": "Selected item ids. (Controlled) When multiSelect is true this takes an array of strings; when false (default) a string." }, + "selectionPropagation": { + "description": "When selectionPropagation.descendants is set to true.
- Selecting a parent selects all its descendants automatically. - Deselecting a parent deselects all its descendants automatically.
When selectionPropagation.parents is set to true.
- Selecting all the descendants of a parent selects the parent automatically. - Deselecting a descendant of a selected parent deselects the parent automatically.
Only works when multiSelect is true. On the <SimpleTreeView />, only the expanded items are considered (since the collapsed item are not passed to the Tree View component at all)" + }, "slotProps": { "description": "The props used for each component slot." }, "slots": { "description": "Overridable component slots." }, "sx": { diff --git a/docs/translations/api-docs/tree-view/rich-tree-view/rich-tree-view.json b/docs/translations/api-docs/tree-view/rich-tree-view/rich-tree-view.json index feba556e087c..a2fdbd15c255 100644 --- a/docs/translations/api-docs/tree-view/rich-tree-view/rich-tree-view.json +++ b/docs/translations/api-docs/tree-view/rich-tree-view/rich-tree-view.json @@ -108,6 +108,9 @@ "selectedItems": { "description": "Selected item ids. (Controlled) When multiSelect is true this takes an array of strings; when false (default) a string." }, + "selectionPropagation": { + "description": "When selectionPropagation.descendants is set to true.
- Selecting a parent selects all its descendants automatically. - Deselecting a parent deselects all its descendants automatically.
When selectionPropagation.parents is set to true.
- Selecting all the descendants of a parent selects the parent automatically. - Deselecting a descendant of a selected parent deselects the parent automatically.
Only works when multiSelect is true. On the <SimpleTreeView />, only the expanded items are considered (since the collapsed item are not passed to the Tree View component at all)" + }, "slotProps": { "description": "The props used for each component slot." }, "slots": { "description": "Overridable component slots." }, "sx": { diff --git a/docs/translations/api-docs/tree-view/simple-tree-view/simple-tree-view.json b/docs/translations/api-docs/tree-view/simple-tree-view/simple-tree-view.json index 1d9142ee23a9..86afc50c65db 100644 --- a/docs/translations/api-docs/tree-view/simple-tree-view/simple-tree-view.json +++ b/docs/translations/api-docs/tree-view/simple-tree-view/simple-tree-view.json @@ -84,6 +84,9 @@ "selectedItems": { "description": "Selected item ids. (Controlled) When multiSelect is true this takes an array of strings; when false (default) a string." }, + "selectionPropagation": { + "description": "When selectionPropagation.descendants is set to true.
- Selecting a parent selects all its descendants automatically. - Deselecting a parent deselects all its descendants automatically.
When selectionPropagation.parents is set to true.
- Selecting all the descendants of a parent selects the parent automatically. - Deselecting a descendant of a selected parent deselects the parent automatically.
Only works when multiSelect is true. On the <SimpleTreeView />, only the expanded items are considered (since the collapsed item are not passed to the Tree View component at all)" + }, "slotProps": { "description": "The props used for each component slot." }, "slots": { "description": "Overridable component slots." }, "sx": { diff --git a/docs/translations/api-docs/tree-view/tree-item-drag-and-drop-overlay/tree-item-drag-and-drop-overlay.json b/docs/translations/api-docs/tree-view/tree-item-drag-and-drop-overlay/tree-item-drag-and-drop-overlay.json new file mode 100644 index 000000000000..f93d4cbd8c79 --- /dev/null +++ b/docs/translations/api-docs/tree-view/tree-item-drag-and-drop-overlay/tree-item-drag-and-drop-overlay.json @@ -0,0 +1 @@ +{ "componentDescription": "", "propDescriptions": {}, "classDescriptions": {} } diff --git a/docs/translations/api-docs/tree-view/tree-item-icon/tree-item-icon.json b/docs/translations/api-docs/tree-view/tree-item-icon/tree-item-icon.json new file mode 100644 index 000000000000..c39a07ae223f --- /dev/null +++ b/docs/translations/api-docs/tree-view/tree-item-icon/tree-item-icon.json @@ -0,0 +1,14 @@ +{ + "componentDescription": "", + "propDescriptions": { + "slotProps": { "description": "The props used for each component slot." }, + "slots": { "description": "Overridable component slots." } + }, + "classDescriptions": {}, + "slotDescriptions": { + "collapseIcon": "The icon used to collapse the item.", + "endIcon": "The icon displayed next to an end item.", + "expandIcon": "The icon used to expand the item.", + "icon": "The icon to display next to the Tree Item's label." + } +} diff --git a/docs/translations/api-docs/tree-view/tree-item/tree-item.json b/docs/translations/api-docs/tree-view/tree-item/tree-item.json index 19addf4e001f..5177a55030aa 100644 --- a/docs/translations/api-docs/tree-view/tree-item/tree-item.json +++ b/docs/translations/api-docs/tree-view/tree-item/tree-item.json @@ -3,44 +3,26 @@ "propDescriptions": { "children": { "description": "The content of the component." }, "classes": { "description": "Override or extend the styles applied to the component." }, - "ContentComponent": { - "description": "The component used to render the content of the item.", - "requiresRef": true - }, - "ContentProps": { "description": "Props applied to ContentComponent." }, "disabled": { "description": "If true, the item is disabled." }, - "itemId": { "description": "The id of the item." }, - "label": { "description": "The Tree Item label." }, + "id": { "description": "The id attribute of the item. If not provided, it will be generated." }, + "itemId": { "description": "The id of the item. Must be unique." }, + "label": { "description": "The label of the item." }, + "onBlur": { "description": "Callback fired when the item root is blurred." }, "onFocus": { - "description": "This prop isn't supported. Use the onItemFocus callback on the tree if you need to monitor a item's focus." + "description": "This prop isn't supported. Use the onItemFocus callback on the tree if you need to monitor an item's focus." }, "onKeyDown": { - "description": "Callback fired when a key of the keyboard is pressed on the item." + "description": "Callback fired when a key is pressed on the keyboard and the tree is in focus." }, "slotProps": { "description": "The props used for each component slot." }, - "slots": { "description": "Overridable component slots." }, - "sx": { - "description": "The system prop that allows defining system overrides as well as additional CSS styles." - } + "slots": { "description": "Overridable component slots." } }, "classDescriptions": { - "checkbox": { - "description": "Styles applied to {{nodeName}}.", - "nodeName": "the checkbox element" - }, - "content": { - "description": "Styles applied to {{nodeName}}.", - "nodeName": "the content element" - }, "disabled": { "description": "State class applied to {{nodeName}} when {{conditions}}.", "nodeName": "the element", "conditions": "disabled" }, - "dragAndDropOverlay": { - "description": "Styles applied to {{nodeName}}.", - "nodeName": "the drag and drop overlay" - }, "editable": { "description": "Styles applied to {{nodeName}}.", "nodeName": "the content of the items that are editable" @@ -60,17 +42,6 @@ "nodeName": "the content element", "conditions": "focused" }, - "iconContainer": { - "description": "Styles applied to {{nodeName}}.", - "nodeName": "the Tree Item icon" - }, - "label": { "description": "Styles applied to {{nodeName}}.", "nodeName": "the label element" }, - "labelInput": { - "description": "Styles applied to {{nodeName}} when {{conditions}}.", - "nodeName": "the input element that is visible", - "conditions": "editing is enabled" - }, - "root": { "description": "Styles applied to the root element." }, "selected": { "description": "State class applied to {{nodeName}} when {{conditions}}.", "nodeName": "the content element", @@ -78,10 +49,17 @@ } }, "slotDescriptions": { + "checkbox": "The component that renders the item checkbox for selection.", "collapseIcon": "The icon used to collapse the item.", + "content": "The component that renders the content of the item. (e.g.: everything related to this item, not to its children).", + "dragAndDropOverlay": "The component that renders the overlay when an item reordering is ongoing. Warning: This slot is only useful when using the <RichTreeViewPro /> component.", "endIcon": "The icon displayed next to an end item.", "expandIcon": "The icon used to expand the item.", - "groupTransition": "The component that animates the appearance / disappearance of the item's children.", - "icon": "The icon to display next to the Tree Item's label." + "groupTransition": "The component that renders the children of the item.", + "icon": "The icon to display next to the Tree Item's label.", + "iconContainer": "The component that renders the icon.", + "label": "The component that renders the item label.", + "labelInput": "The component that renders the input to edit the label when the item is editable and is currently being edited.", + "root": "The component that renders the root." } } diff --git a/docs/translations/api-docs/tree-view/tree-view/tree-view.json b/docs/translations/api-docs/tree-view/tree-view/tree-view.json index 069ba6b9dbc6..7558c542dc41 100644 --- a/docs/translations/api-docs/tree-view/tree-view/tree-view.json +++ b/docs/translations/api-docs/tree-view/tree-view/tree-view.json @@ -84,6 +84,9 @@ "selectedItems": { "description": "Selected item ids. (Controlled) When multiSelect is true this takes an array of strings; when false (default) a string." }, + "selectionPropagation": { + "description": "When selectionPropagation.descendants is set to true.
- Selecting a parent selects all its descendants automatically. - Deselecting a parent deselects all its descendants automatically.
When selectionPropagation.parents is set to true.
- Selecting all the descendants of a parent selects the parent automatically. - Deselecting a descendant of a selected parent deselects the parent automatically.
Only works when multiSelect is true. On the <SimpleTreeView />, only the expanded items are considered (since the collapsed item are not passed to the Tree View component at all)" + }, "slotProps": { "description": "The props used for each component slot." }, "slots": { "description": "Overridable component slots." }, "sx": { diff --git a/package.json b/package.json index 98425f40561a..c133b697217a 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "version": "7.22.1", + "version": "7.21.0", "private": true, "scripts": { "preinstall": "npx only-allow pnpm", @@ -25,7 +25,7 @@ "eslint:fix": "pnpm eslint --fix", "eslint:ci": "eslint . --report-unused-disable-directives --ext .js,.ts,.tsx --max-warnings 0", "markdownlint": "markdownlint-cli2 \"**/*.md\"", - "prettier": "pretty-quick --branch v7.x --ignore-path .eslintignore", + "prettier": "pretty-quick --branch master --ignore-path .eslintignore", "prettier:all": "prettier --write . --ignore-path .eslintignore", "prettier:check": "prettier --check . --ignore-path .eslintignore", "proptypes": "cross-env BABEL_ENV=development babel-node -i \"/node_modules/(?!@mui)/\" -x .ts,.tsx,.js ./docs/scripts/generateProptypes.ts", @@ -62,8 +62,8 @@ "release:changelog": "node scripts/releaseChangelog.mjs", "release:version": "lerna version --exact --no-changelog --no-push --no-git-tag-version --no-private", "release:build": "lerna run --parallel --no-private --scope \"@mui/*\" build", - "release:publish": "pnpm publish --recursive --tag latest", - "release:publish:dry-run": "pnpm publish --recursive --tag latest --registry=\"http://localhost:4873/\"", + "release:publish": "pnpm publish --recursive --tag next", + "release:publish:dry-run": "pnpm publish --recursive --tag next --registry=\"http://localhost:4873/\"", "release:tag": "node scripts/releaseTag.mjs", "validate": "concurrently \"pnpm prettier && pnpm eslint\" \"pnpm proptypes\" \"pnpm docs:typescript:formatted\" \"pnpm docs:api\"", "clean:node_modules": "rimraf --glob \"**/node_modules\"" @@ -71,33 +71,33 @@ "devDependencies": { "@actions/core": "^1.11.1", "@actions/github": "^6.0.0", - "@argos-ci/core": "^2.9.0", - "@babel/cli": "^7.25.7", - "@babel/core": "^7.25.8", - "@babel/node": "^7.25.7", - "@babel/plugin-transform-class-properties": "^7.25.7", - "@babel/plugin-transform-object-rest-spread": "^7.25.8", - "@babel/plugin-transform-private-methods": "^7.25.7", - "@babel/plugin-transform-private-property-in-object": "^7.25.8", - "@babel/plugin-transform-react-constant-elements": "^7.25.7", - "@babel/plugin-transform-runtime": "^7.25.7", - "@babel/preset-env": "^7.25.8", - "@babel/preset-react": "^7.25.7", - "@babel/preset-typescript": "^7.25.7", - "@babel/register": "^7.25.7", - "@babel/traverse": "^7.25.7", - "@babel/types": "^7.25.8", + "@argos-ci/core": "^2.10.0", + "@babel/cli": "^7.25.9", + "@babel/core": "^7.26.0", + "@babel/node": "^7.26.0", + "@babel/plugin-transform-class-properties": "^7.25.9", + "@babel/plugin-transform-object-rest-spread": "^7.25.9", + "@babel/plugin-transform-private-methods": "^7.25.9", + "@babel/plugin-transform-private-property-in-object": "^7.25.9", + "@babel/plugin-transform-react-constant-elements": "^7.25.9", + "@babel/plugin-transform-runtime": "^7.25.9", + "@babel/preset-env": "^7.26.0", + "@babel/preset-react": "^7.25.9", + "@babel/preset-typescript": "^7.26.0", + "@babel/register": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.26.0", "@emotion/cache": "^11.13.1", "@emotion/react": "^11.13.3", "@emotion/styled": "^11.13.0", "@mui/icons-material": "^5.16.7", "@mui/internal-babel-plugin-resolve-imports": "1.0.18", - "@mui/internal-markdown": "^1.0.17", - "@mui/internal-test-utils": "^1.0.17", + "@mui/internal-markdown": "^1.0.19", + "@mui/internal-test-utils": "^1.0.19", "@mui/material": "^5.16.7", - "@mui/monorepo": "github:mui/material-ui#010de4505361345951824d905d1508d6f258ba67", + "@mui/monorepo": "github:mui/material-ui#32112b76aa821c2a1e98120545019ef1a71ea274", "@mui/utils": "^5.16.6", - "@next/eslint-plugin-next": "14.2.15", + "@next/eslint-plugin-next": "15.0.2", "@octokit/plugin-retry": "^7.1.2", "@octokit/rest": "^21.0.2", "@playwright/test": "^1.44.1", @@ -106,10 +106,10 @@ "@types/chai": "^4.3.20", "@types/chai-dom": "^1.11.3", "@types/fs-extra": "^11.0.4", - "@types/karma": "^6.3.8", - "@types/lodash": "^4.17.10", + "@types/karma": "^6.3.9", + "@types/lodash": "^4.17.12", "@types/mocha": "^10.0.9", - "@types/node": "^20.16.11", + "@types/node": "^20.17.3", "@types/react": "^18.3.4", "@types/react-dom": "^18.3.0", "@types/react-test-renderer": "^18.3.0", @@ -119,7 +119,7 @@ "@typescript-eslint/eslint-plugin": "^7.18.0", "@typescript-eslint/parser": "^7.18.0", "autoprefixer": "^10.4.20", - "axe-core": "4.10.0", + "axe-core": "4.10.2", "babel-loader": "^9.2.1", "babel-plugin-istanbul": "^7.0.0", "babel-plugin-module-resolver": "^5.0.2", @@ -144,21 +144,21 @@ "eslint-import-resolver-webpack": "^0.13.9", "eslint-plugin-filenames": "^1.3.2", "eslint-plugin-import": "^2.31.0", - "eslint-plugin-jsdoc": "^50.4.1", - "eslint-plugin-jsx-a11y": "^6.10.0", + "eslint-plugin-jsdoc": "^50.4.3", + "eslint-plugin-jsx-a11y": "^6.10.2", "eslint-plugin-material-ui": "workspace:^", "eslint-plugin-mocha": "^10.5.0", "eslint-plugin-prettier": "^5.2.1", - "eslint-plugin-react": "^7.37.1", + "eslint-plugin-react": "^7.37.2", "eslint-plugin-react-compiler": "0.0.0-experimental-9ed098e-20240725", "eslint-plugin-react-hooks": "^5.0.0", - "eslint-plugin-testing-library": "^6.3.0", + "eslint-plugin-testing-library": "^6.4.0", "fast-glob": "^3.3.2", "format-util": "^1.0.5", "fs-extra": "^11.2.0", "glob-gitignore": "^1.0.15", "globby": "^14.0.2", - "html-webpack-plugin": "^5.6.0", + "html-webpack-plugin": "^5.6.3", "jsdom": "24.1.3", "jss": "^10.10.0", "jss-plugin-template": "^10.10.0", @@ -183,12 +183,12 @@ "react-dom": "^18.3.1", "remark": "^15.0.1", "rimraf": "^6.0.1", - "serve": "^14.2.3", + "serve": "^14.2.4", "sinon": "^18.0.1", "stream-browserify": "^3.0.0", "string-replace-loader": "^3.1.0", "terser-webpack-plugin": "^5.3.10", - "tsx": "^4.19.1", + "tsx": "^4.19.2", "typescript": "^5.6.3", "unist-util-visit": "^5.0.0", "util": "^0.12.5", @@ -199,11 +199,11 @@ }, "resolutions": { "react-is": "^18.3.1", - "@types/node": "^20.16.11" + "@types/node": "^20.17.3" }, - "packageManager": "pnpm@9.12.1", + "packageManager": "pnpm@9.12.2", "engines": { - "pnpm": "9.12.1" + "pnpm": "9.12.2" }, "pnpm": { "patchedDependencies": { diff --git a/packages/rsc-builder/package.json b/packages/rsc-builder/package.json index 92d10aa52ebb..934708ddd01d 100644 --- a/packages/rsc-builder/package.json +++ b/packages/rsc-builder/package.json @@ -9,6 +9,6 @@ }, "devDependencies": { "@types/mocha": "^10.0.9", - "@types/node": "^20.16.11" + "@types/node": "^20.17.3" } } diff --git a/packages/x-charts-pro/package.json b/packages/x-charts-pro/package.json index 27e4179bbc82..ae9cc81b1bdc 100644 --- a/packages/x-charts-pro/package.json +++ b/packages/x-charts-pro/package.json @@ -1,6 +1,6 @@ { "name": "@mui/x-charts-pro", - "version": "7.0.0-beta.6", + "version": "7.0.0-beta.5", "description": "The Pro plan edition of the Charts components (MUI X).", "author": "MUI Team", "main": "src/index.ts", @@ -39,7 +39,7 @@ "directory": "packages/x-charts-pro" }, "dependencies": { - "@babel/runtime": "^7.25.7", + "@babel/runtime": "^7.26.0", "@mui/utils": "^5.16.6 || ^6.0.0", "@mui/x-charts": "workspace:*", "@mui/x-charts-vendor": "workspace:*", diff --git a/packages/x-charts-pro/src/BarChartPro/BarChartPro.tsx b/packages/x-charts-pro/src/BarChartPro/BarChartPro.tsx index 887cd1058746..8424bfbb844f 100644 --- a/packages/x-charts-pro/src/BarChartPro/BarChartPro.tsx +++ b/packages/x-charts-pro/src/BarChartPro/BarChartPro.tsx @@ -199,35 +199,6 @@ BarChartPro.propTypes = { * @default yAxisIds[0] The id of the first provided axis */ leftAxis: PropTypes.oneOfType([PropTypes.object, PropTypes.string]), - /** - * @deprecated Consider using `slotProps.legend` instead. - */ - legend: PropTypes.shape({ - classes: PropTypes.object, - direction: PropTypes.oneOf(['column', 'row']), - hidden: PropTypes.bool, - itemGap: PropTypes.number, - itemMarkHeight: PropTypes.number, - itemMarkWidth: PropTypes.number, - labelStyle: PropTypes.object, - markGap: PropTypes.number, - onItemClick: PropTypes.func, - padding: PropTypes.oneOfType([ - PropTypes.number, - PropTypes.shape({ - bottom: PropTypes.number, - left: PropTypes.number, - right: PropTypes.number, - top: PropTypes.number, - }), - ]), - position: PropTypes.shape({ - horizontal: PropTypes.oneOf(['left', 'middle', 'right']).isRequired, - vertical: PropTypes.oneOf(['bottom', 'middle', 'top']).isRequired, - }), - slotProps: PropTypes.object, - slots: PropTypes.object, - }), /** * If `true`, a loading overlay is displayed. * @default false diff --git a/packages/x-charts-pro/src/Heatmap/Heatmap.tsx b/packages/x-charts-pro/src/Heatmap/Heatmap.tsx index f310b073bed5..202b40914d81 100644 --- a/packages/x-charts-pro/src/Heatmap/Heatmap.tsx +++ b/packages/x-charts-pro/src/Heatmap/Heatmap.tsx @@ -3,6 +3,7 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import { useThemeProps } from '@mui/material/styles'; import useId from '@mui/utils/useId'; +import { MakeOptional } from '@mui/x-internals/types'; import { interpolateRgbBasis } from '@mui/x-charts-vendor/d3-interpolate'; import { ChartsAxis, ChartsAxisProps } from '@mui/x-charts/ChartsAxis'; import { @@ -12,7 +13,6 @@ import { ChartsTooltipSlots, } from '@mui/x-charts/ChartsTooltip'; import { - MakeOptional, ChartsAxisSlots, ChartsAxisSlotProps, ChartsXAxisProps, diff --git a/packages/x-charts-pro/src/LineChartPro/LineChartPro.tsx b/packages/x-charts-pro/src/LineChartPro/LineChartPro.tsx index b7d66add50ba..b7bbf72236ce 100644 --- a/packages/x-charts-pro/src/LineChartPro/LineChartPro.tsx +++ b/packages/x-charts-pro/src/LineChartPro/LineChartPro.tsx @@ -264,35 +264,6 @@ LineChartPro.propTypes = { * @default yAxisIds[0] The id of the first provided axis */ leftAxis: PropTypes.oneOfType([PropTypes.object, PropTypes.string]), - /** - * @deprecated Consider using `slotProps.legend` instead. - */ - legend: PropTypes.shape({ - classes: PropTypes.object, - direction: PropTypes.oneOf(['column', 'row']), - hidden: PropTypes.bool, - itemGap: PropTypes.number, - itemMarkHeight: PropTypes.number, - itemMarkWidth: PropTypes.number, - labelStyle: PropTypes.object, - markGap: PropTypes.number, - onItemClick: PropTypes.func, - padding: PropTypes.oneOfType([ - PropTypes.number, - PropTypes.shape({ - bottom: PropTypes.number, - left: PropTypes.number, - right: PropTypes.number, - top: PropTypes.number, - }), - ]), - position: PropTypes.shape({ - horizontal: PropTypes.oneOf(['left', 'middle', 'right']).isRequired, - vertical: PropTypes.oneOf(['bottom', 'middle', 'top']).isRequired, - }), - slotProps: PropTypes.object, - slots: PropTypes.object, - }), /** * If `true`, a loading overlay is displayed. * @default false diff --git a/packages/x-charts-pro/src/ScatterChartPro/ScatterChartPro.tsx b/packages/x-charts-pro/src/ScatterChartPro/ScatterChartPro.tsx index 74401ac085dc..b415635daf08 100644 --- a/packages/x-charts-pro/src/ScatterChartPro/ScatterChartPro.tsx +++ b/packages/x-charts-pro/src/ScatterChartPro/ScatterChartPro.tsx @@ -141,35 +141,6 @@ ScatterChartPro.propTypes = { * @default yAxisIds[0] The id of the first provided axis */ leftAxis: PropTypes.oneOfType([PropTypes.object, PropTypes.string]), - /** - * @deprecated Consider using `slotProps.legend` instead. - */ - legend: PropTypes.shape({ - classes: PropTypes.object, - direction: PropTypes.oneOf(['column', 'row']), - hidden: PropTypes.bool, - itemGap: PropTypes.number, - itemMarkHeight: PropTypes.number, - itemMarkWidth: PropTypes.number, - labelStyle: PropTypes.object, - markGap: PropTypes.number, - onItemClick: PropTypes.func, - padding: PropTypes.oneOfType([ - PropTypes.number, - PropTypes.shape({ - bottom: PropTypes.number, - left: PropTypes.number, - right: PropTypes.number, - top: PropTypes.number, - }), - ]), - position: PropTypes.shape({ - horizontal: PropTypes.oneOf(['left', 'middle', 'right']).isRequired, - vertical: PropTypes.oneOf(['bottom', 'middle', 'top']).isRequired, - }), - slotProps: PropTypes.object, - slots: PropTypes.object, - }), /** * If `true`, a loading overlay is displayed. * @default false diff --git a/packages/x-charts-pro/src/models/seriesType/heatmap.ts b/packages/x-charts-pro/src/models/seriesType/heatmap.ts index 9444f4af60a2..2db79f66bd74 100644 --- a/packages/x-charts-pro/src/models/seriesType/heatmap.ts +++ b/packages/x-charts-pro/src/models/seriesType/heatmap.ts @@ -1,5 +1,5 @@ +import { DefaultizedProps } from '@mui/x-internals/types'; import { - DefaultizedProps, CommonDefaultizedProps, CommonSeriesType, CartesianSeriesType, diff --git a/packages/x-charts-pro/src/typeOverloads/modules.ts b/packages/x-charts-pro/src/typeOverloads/modules.ts index 8cdc24c0f409..734e3e911b7e 100644 --- a/packages/x-charts-pro/src/typeOverloads/modules.ts +++ b/packages/x-charts-pro/src/typeOverloads/modules.ts @@ -1,4 +1,4 @@ -import { DefaultizedProps } from '@mui/x-charts/internals'; +import { DefaultizedProps } from '@mui/x-internals/types'; import { HeatmapItemIdentifier, HeatmapSeriesType, diff --git a/packages/x-charts-vendor/package.json b/packages/x-charts-vendor/package.json index 79dd902e3dd1..7b2db9acb00d 100644 --- a/packages/x-charts-vendor/package.json +++ b/packages/x-charts-vendor/package.json @@ -24,7 +24,7 @@ } }, "dependencies": { - "@babel/runtime": "^7.25.7", + "@babel/runtime": "^7.26.0", "@types/d3-color": "^3.1.3", "@types/d3-delaunay": "^6.0.4", "@types/d3-interpolate": "^3.0.4", @@ -41,7 +41,7 @@ "robust-predicates": "^3.0.2" }, "devDependencies": { - "@babel/plugin-transform-runtime": "^7.25.7", + "@babel/plugin-transform-runtime": "^7.25.9", "@types/d3-array": "^3.2.1", "@types/d3-format": "^3.0.4", "@types/d3-path": "^3.1.0", @@ -50,7 +50,7 @@ "d3-format": "^3.1.0", "d3-path": "^3.1.0", "d3-time-format": "^4.1.0", - "execa": "^9.4.0", + "execa": "^9.4.1", "internmap": "^2.0.3", "rimraf": "^6.0.1" }, diff --git a/packages/x-charts/package.json b/packages/x-charts/package.json index a4ca379f0280..e860ba6bf183 100644 --- a/packages/x-charts/package.json +++ b/packages/x-charts/package.json @@ -1,6 +1,6 @@ { "name": "@mui/x-charts", - "version": "7.22.1", + "version": "7.21.0", "description": "The community edition of the Charts components (MUI X).", "author": "MUI Team", "main": "src/index.js", @@ -39,7 +39,7 @@ "directory": "packages/x-charts" }, "dependencies": { - "@babel/runtime": "^7.25.7", + "@babel/runtime": "^7.26.0", "@mui/utils": "^5.16.6 || ^6.0.0", "@mui/x-charts-vendor": "workspace:*", "@mui/x-internals": "workspace:*", @@ -65,7 +65,7 @@ } }, "devDependencies": { - "@mui/internal-test-utils": "^1.0.17", + "@mui/internal-test-utils": "^1.0.19", "@mui/material": "^5.16.7", "@mui/system": "^5.16.7", "@react-spring/core": "^9.7.5", diff --git a/packages/x-charts/src/BarChart/BarChart.tsx b/packages/x-charts/src/BarChart/BarChart.tsx index ca3e113ac302..58dea244f59a 100644 --- a/packages/x-charts/src/BarChart/BarChart.tsx +++ b/packages/x-charts/src/BarChart/BarChart.tsx @@ -2,6 +2,7 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import { useThemeProps } from '@mui/material/styles'; +import { MakeOptional } from '@mui/x-internals/types'; import { BarPlot, BarPlotProps, BarPlotSlotProps, BarPlotSlots } from './BarPlot'; import { ResponsiveChartContainer, @@ -9,19 +10,13 @@ import { } from '../ResponsiveChartContainer'; import { ChartsAxis, ChartsAxisProps } from '../ChartsAxis'; import { BarSeriesType } from '../models/seriesType/bar'; -import { MakeOptional } from '../models/helpers'; import { ChartsTooltip, ChartsTooltipProps, ChartsTooltipSlotProps, ChartsTooltipSlots, } from '../ChartsTooltip'; -import { - ChartsLegend, - ChartsLegendProps, - ChartsLegendSlots, - ChartsLegendSlotProps, -} from '../ChartsLegend'; +import { ChartsLegend, ChartsLegendSlots, ChartsLegendSlotProps } from '../ChartsLegend'; import { ChartsAxisHighlight, ChartsAxisHighlightProps } from '../ChartsAxisHighlight'; import { ChartsClipPath } from '../ChartsClipPath'; import { ChartsAxisSlots, ChartsAxisSlotProps } from '../models/axis'; @@ -79,10 +74,6 @@ export interface BarChartProps * */ axisHighlight?: ChartsAxisHighlightProps; - /** - * @deprecated Consider using `slotProps.legend` instead. - */ - legend?: ChartsLegendProps; /** * Overridable component slots. * @default {} @@ -226,35 +217,6 @@ BarChart.propTypes = { * @default yAxisIds[0] The id of the first provided axis */ leftAxis: PropTypes.oneOfType([PropTypes.object, PropTypes.string]), - /** - * @deprecated Consider using `slotProps.legend` instead. - */ - legend: PropTypes.shape({ - classes: PropTypes.object, - direction: PropTypes.oneOf(['column', 'row']), - hidden: PropTypes.bool, - itemGap: PropTypes.number, - itemMarkHeight: PropTypes.number, - itemMarkWidth: PropTypes.number, - labelStyle: PropTypes.object, - markGap: PropTypes.number, - onItemClick: PropTypes.func, - padding: PropTypes.oneOfType([ - PropTypes.number, - PropTypes.shape({ - bottom: PropTypes.number, - left: PropTypes.number, - right: PropTypes.number, - top: PropTypes.number, - }), - ]), - position: PropTypes.shape({ - horizontal: PropTypes.oneOf(['left', 'middle', 'right']).isRequired, - vertical: PropTypes.oneOf(['bottom', 'middle', 'top']).isRequired, - }), - slotProps: PropTypes.object, - slots: PropTypes.object, - }), /** * If `true`, a loading overlay is displayed. * @default false diff --git a/packages/x-charts/src/BarChart/BarElement.tsx b/packages/x-charts/src/BarChart/BarElement.tsx index f33865e1747f..ce5f91fcfd2f 100644 --- a/packages/x-charts/src/BarChart/BarElement.tsx +++ b/packages/x-charts/src/BarChart/BarElement.tsx @@ -8,7 +8,7 @@ import { styled } from '@mui/material/styles'; import generateUtilityClasses from '@mui/utils/generateUtilityClasses'; import { color as d3Color } from '@mui/x-charts-vendor/d3-color'; import { AnimatedProps, animated } from '@react-spring/web'; -import { SlotComponentPropsFromProps } from '../internals/SlotComponentPropsFromProps'; +import { SlotComponentPropsFromProps } from '@mui/x-internals/types'; import { useInteractionItemProps } from '../hooks/useInteractionItemProps'; import { SeriesId } from '../models/seriesType/common'; import { useItemHighlighted } from '../context'; diff --git a/packages/x-charts/src/BarChart/BarLabel/BarLabelItem.tsx b/packages/x-charts/src/BarChart/BarLabel/BarLabelItem.tsx index a71c3c7a4a29..33a993fd7694 100644 --- a/packages/x-charts/src/BarChart/BarLabel/BarLabelItem.tsx +++ b/packages/x-charts/src/BarChart/BarLabel/BarLabelItem.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import useSlotProps from '@mui/utils/useSlotProps'; import PropTypes from 'prop-types'; -import { SlotComponentPropsFromProps } from '../../internals/SlotComponentPropsFromProps'; +import { SlotComponentPropsFromProps } from '@mui/x-internals/types'; import { useUtilityClasses } from './barLabelClasses'; import { BarLabelOwnerState, BarItem, BarLabelContext } from './BarLabel.types'; import { getBarLabel } from './getBarLabel'; diff --git a/packages/x-charts/src/BarChart/BarPlot.tsx b/packages/x-charts/src/BarChart/BarPlot.tsx index c84f74c7711f..e81f631d0c30 100644 --- a/packages/x-charts/src/BarChart/BarPlot.tsx +++ b/packages/x-charts/src/BarChart/BarPlot.tsx @@ -103,8 +103,8 @@ const useAggregatedData = (): { const data = stackingGroups.flatMap(({ ids: groupIds }, groupIndex) => { return groupIds.flatMap((seriesId) => { - const xAxisId = series[seriesId].xAxisId ?? series[seriesId].xAxisKey ?? defaultXAxisId; - const yAxisId = series[seriesId].yAxisId ?? series[seriesId].yAxisKey ?? defaultYAxisId; + const xAxisId = series[seriesId].xAxisId ?? defaultXAxisId; + const yAxisId = series[seriesId].yAxisId ?? defaultYAxisId; const xAxisConfig = xAxis[xAxisId]; const yAxisConfig = yAxis[yAxisId]; diff --git a/packages/x-charts/src/BarChart/extremums.ts b/packages/x-charts/src/BarChart/extremums.ts index 1ec2cc001b9f..7d29d237c867 100644 --- a/packages/x-charts/src/BarChart/extremums.ts +++ b/packages/x-charts/src/BarChart/extremums.ts @@ -28,7 +28,7 @@ const getValueExtremum = return Object.keys(series) .filter((seriesId) => { - const yAxisId = series[seriesId].yAxisId ?? series[seriesId].yAxisKey; + const yAxisId = series[seriesId].yAxisId; return yAxisId === axis.id || (isDefaultAxis && yAxisId === undefined); }) .reduce( @@ -38,8 +38,8 @@ const getValueExtremum = const filter = getFilters?.({ currentAxisId: axis.id, isDefaultAxis, - seriesXAxisId: series[seriesId].xAxisId ?? series[seriesId].xAxisKey, - seriesYAxisId: series[seriesId].yAxisId ?? series[seriesId].yAxisKey, + seriesXAxisId: series[seriesId].xAxisId, + seriesYAxisId: series[seriesId].yAxisId, }); const [seriesMin, seriesMax] = stackedData?.reduce( diff --git a/packages/x-charts/src/BarChart/formatter.ts b/packages/x-charts/src/BarChart/formatter.ts index d2c5639f7973..64175e646d30 100644 --- a/packages/x-charts/src/BarChart/formatter.ts +++ b/packages/x-charts/src/BarChart/formatter.ts @@ -1,9 +1,9 @@ import { stack as d3Stack } from '@mui/x-charts-vendor/d3-shape'; import { warnOnce } from '@mui/x-internals/warning'; +import { DefaultizedProps } from '@mui/x-internals/types'; import { getStackingGroups } from '../internals/stackSeries'; import { ChartSeries, DatasetElementType, DatasetType } from '../models/seriesType/config'; import { defaultizeValueFormatter } from '../internals/defaultizeValueFormatter'; -import { DefaultizedProps } from '../models/helpers'; import { SeriesId } from '../models/seriesType/common'; import { SeriesFormatter } from '../context/PluginProvider/SeriesFormatter.types'; diff --git a/packages/x-charts/src/BarChart/useBarChartProps.ts b/packages/x-charts/src/BarChart/useBarChartProps.ts index 16d17fc3ffe5..d6495a9c6148 100644 --- a/packages/x-charts/src/BarChart/useBarChartProps.ts +++ b/packages/x-charts/src/BarChart/useBarChartProps.ts @@ -34,7 +34,6 @@ export const useBarChartProps = (props: BarChartProps) => { tooltip, onAxisClick, axisHighlight, - legend, grid, topAxis, leftAxis, @@ -146,7 +145,6 @@ export const useBarChartProps = (props: BarChartProps) => { }; const legendProps: ChartsLegendProps = { - ...legend, slots, slotProps, }; diff --git a/packages/x-charts/src/ChartContainer/ChartContainer.tsx b/packages/x-charts/src/ChartContainer/ChartContainer.tsx index 7343ceb1a2fd..661df7f5987a 100644 --- a/packages/x-charts/src/ChartContainer/ChartContainer.tsx +++ b/packages/x-charts/src/ChartContainer/ChartContainer.tsx @@ -1,6 +1,7 @@ 'use client'; import * as React from 'react'; import PropTypes from 'prop-types'; +import { MakeOptional } from '@mui/x-internals/types'; import { DrawingProvider, DrawingProviderProps } from '../context/DrawingProvider'; import { SeriesProvider, SeriesProviderProps } from '../context/SeriesProvider'; import { InteractionProvider } from '../context/InteractionProvider'; @@ -16,7 +17,6 @@ import { import { PluginProvider, PluginProviderProps } from '../context/PluginProvider'; import { useChartContainerProps } from './useChartContainerProps'; import { AxisConfig, ChartsXAxisProps, ChartsYAxisProps, ScaleName } from '../models/axis'; -import { MakeOptional } from '../models/helpers'; import { AnimationProvider, AnimationProviderProps } from '../context/AnimationProvider'; export type ChartContainerProps = Omit< diff --git a/packages/x-charts/src/ChartContainer/useDefaultizeAxis.ts b/packages/x-charts/src/ChartContainer/useDefaultizeAxis.ts index a260517f0ba0..99d08ec6c099 100644 --- a/packages/x-charts/src/ChartContainer/useDefaultizeAxis.ts +++ b/packages/x-charts/src/ChartContainer/useDefaultizeAxis.ts @@ -1,7 +1,7 @@ 'use client'; import * as React from 'react'; +import { MakeOptional } from '@mui/x-internals/types'; import { DEFAULT_X_AXIS_KEY, DEFAULT_Y_AXIS_KEY } from '../constants'; -import { MakeOptional } from '../models/helpers'; import { AxisConfig, ScaleName } from '../models'; import { ChartsAxisProps } from '../models/axis'; import { DatasetType } from '../models/seriesType/config'; diff --git a/packages/x-charts/src/ChartsLegend/ChartsLegend.tsx b/packages/x-charts/src/ChartsLegend/ChartsLegend.tsx index de75c3dfc288..1a68804b785f 100644 --- a/packages/x-charts/src/ChartsLegend/ChartsLegend.tsx +++ b/packages/x-charts/src/ChartsLegend/ChartsLegend.tsx @@ -3,12 +3,11 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import useSlotProps from '@mui/utils/useSlotProps'; import composeClasses from '@mui/utils/composeClasses'; +import { DefaultizedProps } from '@mui/x-internals/types'; import { useThemeProps, useTheme, Theme } from '@mui/material/styles'; import { getSeriesToDisplay } from './utils'; import { getLegendUtilityClass } from './chartsLegendClasses'; -import { DefaultizedProps } from '../models/helpers'; import { DefaultChartsLegend, LegendRendererProps } from './DefaultChartsLegend'; -import { useDrawingArea } from '../hooks'; import { useSeries } from '../hooks/useSeries'; import { LegendPlacement } from './legend.types'; @@ -74,7 +73,6 @@ function ChartsLegend(inProps: ChartsLegendProps) { const theme = useTheme(); const classes = useUtilityClasses({ ...defaultizedProps, theme }); - const drawingArea = useDrawingArea(); const series = useSeries(); const seriesToDisplay = getSeriesToDisplay(series); @@ -86,7 +84,6 @@ function ChartsLegend(inProps: ChartsLegendProps) { additionalProps: { ...other, classes, - drawingArea, series, seriesToDisplay, }, diff --git a/packages/x-charts/src/ChartsLegend/DefaultChartsLegend.tsx b/packages/x-charts/src/ChartsLegend/DefaultChartsLegend.tsx index 7278a105536f..ff2c62ade76b 100644 --- a/packages/x-charts/src/ChartsLegend/DefaultChartsLegend.tsx +++ b/packages/x-charts/src/ChartsLegend/DefaultChartsLegend.tsx @@ -3,7 +3,6 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import { FormattedSeries } from '../context/SeriesProvider'; import { LegendPerItem, LegendPerItemProps } from './LegendPerItem'; -import { DrawingArea } from '../context/DrawingProvider'; import { LegendItemParams, SeriesLegendItemContext } from './chartsLegend.types'; const seriesContextBuilder = (context: LegendItemParams): SeriesLegendItemContext => @@ -19,10 +18,6 @@ export interface LegendRendererProps extends Omit { series: FormattedSeries; seriesToDisplay: LegendPerItemProps['itemsToDisplay']; - /** - * @deprecated Use the `useDrawingArea` hook instead. - */ - drawingArea: Omit; /** * Callback fired when a legend item is clicked. * @param {React.MouseEvent} event The click event. @@ -42,7 +37,7 @@ export interface LegendRendererProps } function DefaultChartsLegend(props: LegendRendererProps) { - const { drawingArea, seriesToDisplay, hidden, onItemClick, ...other } = props; + const { seriesToDisplay, hidden, onItemClick, ...other } = props; if (hidden) { return null; @@ -75,17 +70,6 @@ DefaultChartsLegend.propTypes = { * The default depends on the chart. */ direction: PropTypes.oneOf(['column', 'row']).isRequired, - /** - * @deprecated Use the `useDrawingArea` hook instead. - */ - drawingArea: PropTypes.shape({ - bottom: PropTypes.number.isRequired, - height: PropTypes.number.isRequired, - left: PropTypes.number.isRequired, - right: PropTypes.number.isRequired, - top: PropTypes.number.isRequired, - width: PropTypes.number.isRequired, - }).isRequired, /** * Set to true to hide the legend. * @default false diff --git a/packages/x-charts/src/ChartsLegend/LegendPerItem.tsx b/packages/x-charts/src/ChartsLegend/LegendPerItem.tsx index 60abf0ff950d..77ac080ec7b7 100644 --- a/packages/x-charts/src/ChartsLegend/LegendPerItem.tsx +++ b/packages/x-charts/src/ChartsLegend/LegendPerItem.tsx @@ -1,5 +1,6 @@ 'use client'; import * as React from 'react'; +import { DefaultizedProps } from '@mui/x-internals/types'; import NoSsr from '@mui/material/NoSsr'; import { useTheme, styled } from '@mui/material/styles'; import { DrawingArea } from '../context/DrawingProvider'; @@ -12,7 +13,6 @@ import { useDrawingArea } from '../hooks/useDrawingArea'; import { AnchorPosition, Direction, LegendPlacement } from './legend.types'; import { ChartsLegendItem } from './ChartsLegendItem'; import { ChartsLegendClasses } from './chartsLegendClasses'; -import { DefaultizedProps } from '../models/helpers'; export type ChartsLegendRootOwnerState = { position: AnchorPosition; diff --git a/packages/x-charts/src/ChartsOnAxisClickHandler/ChartsOnAxisClickHandler.tsx b/packages/x-charts/src/ChartsOnAxisClickHandler/ChartsOnAxisClickHandler.tsx index c4da5f03a666..8c26ff5650e6 100644 --- a/packages/x-charts/src/ChartsOnAxisClickHandler/ChartsOnAxisClickHandler.tsx +++ b/packages/x-charts/src/ChartsOnAxisClickHandler/ChartsOnAxisClickHandler.tsx @@ -55,8 +55,8 @@ function ChartsOnAxisClickHandler(props: ChartsOnAxisClickHandlerProps) { series[seriesType]?.seriesOrder.forEach((seriesId) => { const seriesItem = series[seriesType]!.series[seriesId]; - const providedXAxisId = seriesItem.xAxisId ?? seriesItem.xAxisKey; - const providedYAxisId = seriesItem.yAxisId ?? seriesItem.yAxisKey; + const providedXAxisId = seriesItem.xAxisId; + const providedYAxisId = seriesItem.yAxisId; const axisKey = isXaxis ? providedXAxisId : providedYAxisId; if (axisKey === undefined || axisKey === USED_AXIS_ID) { diff --git a/packages/x-charts/src/ChartsOverlay/ChartsOverlay.tsx b/packages/x-charts/src/ChartsOverlay/ChartsOverlay.tsx index 05287192e40b..f78c62b03624 100644 --- a/packages/x-charts/src/ChartsOverlay/ChartsOverlay.tsx +++ b/packages/x-charts/src/ChartsOverlay/ChartsOverlay.tsx @@ -1,7 +1,7 @@ 'use client'; import * as React from 'react'; import { SxProps, Theme } from '@mui/material/styles'; -import { SlotComponentPropsFromProps } from '../internals/SlotComponentPropsFromProps'; +import { SlotComponentPropsFromProps } from '@mui/x-internals/types'; import { ChartsLoadingOverlay } from './ChartsLoadingOverlay'; import { useSeries } from '../hooks/useSeries'; import { SeriesId } from '../models/seriesType/common'; diff --git a/packages/x-charts/src/ChartsTooltip/ChartsAxisTooltipContent.tsx b/packages/x-charts/src/ChartsTooltip/ChartsAxisTooltipContent.tsx index b9daca3379cb..28b6f6f833e0 100644 --- a/packages/x-charts/src/ChartsTooltip/ChartsAxisTooltipContent.tsx +++ b/packages/x-charts/src/ChartsTooltip/ChartsAxisTooltipContent.tsx @@ -77,8 +77,8 @@ function ChartsAxisTooltipContent(props: { series[seriesType]!.seriesOrder.forEach((seriesId) => { const item = series[seriesType]!.series[seriesId]; - const providedXAxisId = item.xAxisId ?? item.xAxisKey; - const providedYAxisId = item.yAxisId ?? item.yAxisKey; + const providedXAxisId = item.xAxisId; + const providedYAxisId = item.yAxisId; const axisKey = isXaxis ? providedXAxisId : providedYAxisId; @@ -87,8 +87,7 @@ function ChartsAxisTooltipContent(props: { const xAxisId = providedXAxisId ?? xAxisIds[0]; const yAxisId = providedYAxisId ?? yAxisIds[0]; - const zAxisId = - (seriesToAdd as any).zAxisId ?? (seriesToAdd as any).zAxisKey ?? zAxisIds[0]; + const zAxisId = (seriesToAdd as any).zAxisId ?? zAxisIds[0]; const getColor = colorProcessors[seriesType]?.( diff --git a/packages/x-charts/src/ChartsTooltip/ChartsItemTooltipContent.tsx b/packages/x-charts/src/ChartsTooltip/ChartsItemTooltipContent.tsx index 8a941f4d9c68..30140400a948 100644 --- a/packages/x-charts/src/ChartsTooltip/ChartsItemTooltipContent.tsx +++ b/packages/x-charts/src/ChartsTooltip/ChartsItemTooltipContent.tsx @@ -54,9 +54,9 @@ function ChartsItemTooltipContent( const { zAxis, zAxisIds } = React.useContext(ZAxisContext); const colorProcessors = useColorProcessor(); - const xAxisId = (series as any).xAxisId ?? (series as any).xAxisKey ?? xAxisIds[0]; - const yAxisId = (series as any).yAxisId ?? (series as any).yAxisKey ?? yAxisIds[0]; - const zAxisId = (series as any).zAxisId ?? (series as any).zAxisKey ?? zAxisIds[0]; + const xAxisId = (series as any).xAxisId ?? xAxisIds[0]; + const yAxisId = (series as any).yAxisId ?? yAxisIds[0]; + const zAxisId = (series as any).zAxisId ?? zAxisIds[0]; const getColor = colorProcessors[series.type]?.( diff --git a/packages/x-charts/src/ChartsTooltip/ChartsTooltip.tsx b/packages/x-charts/src/ChartsTooltip/ChartsTooltip.tsx index 4566eddb96d6..560a83ccc9a4 100644 --- a/packages/x-charts/src/ChartsTooltip/ChartsTooltip.tsx +++ b/packages/x-charts/src/ChartsTooltip/ChartsTooltip.tsx @@ -2,6 +2,7 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import composeClasses from '@mui/utils/composeClasses'; +import useLazyRef from '@mui/utils/useLazyRef'; import { styled, useThemeProps, SxProps, Theme } from '@mui/material/styles'; import Popper, { PopperProps as BasePopperProps } from '@mui/material/Popper'; import NoSsr from '@mui/material/NoSsr'; @@ -11,12 +12,8 @@ import { InteractionContext, ItemInteractionData, } from '../context/InteractionProvider'; -import { - generateVirtualElement, - useMouseTracker, - getTooltipHasData, - TriggerOptions, -} from './utils'; +import { useSvgRef } from '../hooks/useSvgRef'; +import { getTooltipHasData, TriggerOptions, usePointerType } from './utils'; import { ChartSeriesType } from '../models/seriesType/config'; import { ChartsItemContentProps, ChartsItemTooltipContent } from './ChartsItemTooltipContent'; import { ChartsAxisContentProps, ChartsAxisTooltipContent } from './ChartsAxisTooltipContent'; @@ -133,14 +130,19 @@ function ChartsTooltip(inProps: ChartsTooltipProps }); const { trigger = 'axis', itemContent, axisContent, slots, slotProps } = props; - const mousePosition = useMouseTracker(); + const svgRef = useSvgRef(); + const pointerType = usePointerType(); + + const popperRef: PopperProps['popperRef'] = React.useRef(null); + + const positionRef = useLazyRef(() => ({ x: 0, y: 0 })); const { item, axis } = React.useContext(InteractionContext); const displayedData = trigger === 'item' ? item : axis; const tooltipHasData = getTooltipHasData(trigger, displayedData); - const popperOpen = mousePosition !== null && tooltipHasData; + const popperOpen = pointerType !== null && tooltipHasData; const classes = useUtilityClasses({ classes: props.classes }); @@ -150,14 +152,26 @@ function ChartsTooltip(inProps: ChartsTooltipProps externalSlotProps: slotProps?.popper, additionalProps: { open: popperOpen, - placement: - mousePosition?.pointerType === 'mouse' ? ('right-start' as const) : ('top' as const), - anchorEl: generateVirtualElement(mousePosition), + placement: pointerType?.pointerType === 'mouse' ? ('right-start' as const) : ('top' as const), + popperRef, + anchorEl: { + getBoundingClientRect: () => ({ + x: positionRef.current.x, + y: positionRef.current.y, + top: positionRef.current.y, + left: positionRef.current.x, + right: positionRef.current.x, + bottom: positionRef.current.y, + width: 0, + height: 0, + toJSON: () => '', + }), + }, modifiers: [ { name: 'offset', options: { - offset: [0, mousePosition?.pointerType === 'touch' ? 40 - mousePosition.height : 0], + offset: [0, pointerType?.pointerType === 'touch' ? 40 - pointerType.height : 0], }, }, ], @@ -165,6 +179,27 @@ function ChartsTooltip(inProps: ChartsTooltipProps ownerState: {}, }); + React.useEffect(() => { + const element = svgRef.current; + if (element === null) { + return () => {}; + } + + const handleMove = (event: PointerEvent) => { + // eslint-disable-next-line react-compiler/react-compiler + positionRef.current = { + x: event.clientX, + y: event.clientY, + }; + popperRef.current?.update(); + }; + element.addEventListener('pointermove', handleMove); + + return () => { + element.removeEventListener('pointermove', handleMove); + }; + }, [svgRef, positionRef]); + if (trigger === 'none') { return null; } diff --git a/packages/x-charts/src/ChartsTooltip/contentDisplayed.test.tsx b/packages/x-charts/src/ChartsTooltip/contentDisplayed.test.tsx index 6b4634241e3d..bde48ebc9f35 100644 --- a/packages/x-charts/src/ChartsTooltip/contentDisplayed.test.tsx +++ b/packages/x-charts/src/ChartsTooltip/contentDisplayed.test.tsx @@ -54,6 +54,7 @@ describe('ChartsTooltip', () => { ); const svg = document.querySelector('svg')!; + fireEvent.pointerEnter(svg); // Trigger the tooltip firePointerEvent(svg, 'pointermove', { clientX: 198, clientY: 60, @@ -120,6 +121,7 @@ describe('ChartsTooltip', () => { ); const svg = document.querySelector('svg')!; + fireEvent.pointerEnter(svg); // Trigger the tooltip firePointerEvent(svg, 'pointermove', { clientX: 150, clientY: 60, @@ -191,6 +193,7 @@ describe('ChartsTooltip', () => { fireEvent.pointerEnter(rectangles[0]); + fireEvent.pointerEnter(svg); // Trigger the tooltip firePointerEvent(svg, 'pointermove', { clientX: 150, clientY: 60, @@ -235,6 +238,7 @@ describe('ChartsTooltip', () => { fireEvent.pointerEnter(rectangles[0]); + fireEvent.pointerEnter(svg); // Trigger the tooltip firePointerEvent(svg, 'pointermove', { clientX: 150, clientY: 60, diff --git a/packages/x-charts/src/ChartsTooltip/useAxisTooltip.tsx b/packages/x-charts/src/ChartsTooltip/useAxisTooltip.tsx index 7b86b0bb0648..109665b90e5d 100644 --- a/packages/x-charts/src/ChartsTooltip/useAxisTooltip.tsx +++ b/packages/x-charts/src/ChartsTooltip/useAxisTooltip.tsx @@ -61,8 +61,8 @@ export function useAxisTooltip(): null | UseAxisTooltipReturnValue { return seriesOfType.seriesOrder.map((seriesId) => { const seriesToAdd = seriesOfType.series[seriesId]!; - const providedXAxisId = seriesToAdd.xAxisId ?? seriesToAdd.xAxisKey; - const providedYAxisId = seriesToAdd.yAxisId ?? seriesToAdd.yAxisKey; + const providedXAxisId = seriesToAdd.xAxisId; + const providedYAxisId = seriesToAdd.yAxisId; const axisKey = isXaxis ? providedXAxisId : providedYAxisId; @@ -70,8 +70,7 @@ export function useAxisTooltip(): null | UseAxisTooltipReturnValue { if (axisKey === undefined || axisKey === USED_AXIS_ID) { const xAxisId = providedXAxisId ?? xAxisIds[0]; const yAxisId = providedYAxisId ?? yAxisIds[0]; - const zAxisId = - (seriesToAdd as any).zAxisId ?? (seriesToAdd as any).zAxisKey ?? zAxisIds[0]; + const zAxisId = (seriesToAdd as any).zAxisId ?? zAxisIds[0]; const color = colorProcessors[seriesType]?.( diff --git a/packages/x-charts/src/ChartsTooltip/useItemTooltip.tsx b/packages/x-charts/src/ChartsTooltip/useItemTooltip.tsx index 5743592e31dc..a3ab97c287b1 100644 --- a/packages/x-charts/src/ChartsTooltip/useItemTooltip.tsx +++ b/packages/x-charts/src/ChartsTooltip/useItemTooltip.tsx @@ -29,9 +29,9 @@ export function useItemTooltip(): null | UseItemToolt const { zAxis, zAxisIds } = React.useContext(ZAxisContext); const colorProcessors = useColorProcessor(); - const xAxisId = (series as any).xAxisId ?? (series as any).xAxisKey ?? xAxisIds[0]; - const yAxisId = (series as any).yAxisId ?? (series as any).yAxisKey ?? yAxisIds[0]; - const zAxisId = (series as any).zAxisId ?? (series as any).zAxisKey ?? zAxisIds[0]; + const xAxisId = (series as any).xAxisId ?? xAxisIds[0]; + const yAxisId = (series as any).yAxisId ?? yAxisIds[0]; + const zAxisId = (series as any).zAxisId ?? zAxisIds[0]; if (!item || item.dataIndex === undefined) { return null; diff --git a/packages/x-charts/src/ChartsTooltip/utils.tsx b/packages/x-charts/src/ChartsTooltip/utils.tsx index 89faff2a7b17..227c7f58e24e 100644 --- a/packages/x-charts/src/ChartsTooltip/utils.tsx +++ b/packages/x-charts/src/ChartsTooltip/utils.tsx @@ -10,43 +10,11 @@ type MousePosition = { height: number; }; -export function generateVirtualElement(mousePosition: MousePosition | null) { - if (mousePosition === null) { - return { - getBoundingClientRect: () => ({ - width: 0, - height: 0, - x: 0, - y: 0, - top: 0, - right: 0, - bottom: 0, - left: 0, - toJSON: () => '', - }), - }; - } - const { x, y } = mousePosition; - const boundingBox = { - width: 0, - height: 0, - x, - y, - top: y, - right: x, - bottom: y, - left: x, - }; - return { - getBoundingClientRect: () => ({ - ...boundingBox, - toJSON: () => JSON.stringify(boundingBox), - }), - }; -} - export type UseMouseTrackerReturnValue = null | MousePosition; +/** + * @deprecated We recommend using vanilla JS to let popper track mouse position. + */ export function useMouseTracker(): UseMouseTrackerReturnValue { const svgRef = useSvgRef(); @@ -59,6 +27,8 @@ export function useMouseTracker(): UseMouseTrackerReturnValue { return () => {}; } + const controller = new AbortController(); + const handleOut = (event: PointerEvent) => { if (event.pointerType !== 'mouse') { setMousePosition(null); @@ -74,18 +44,57 @@ export function useMouseTracker(): UseMouseTrackerReturnValue { }); }; - element.addEventListener('pointerdown', handleMove); - element.addEventListener('pointermove', handleMove); + element.addEventListener('pointerdown', handleMove, { signal: controller.signal }); + element.addEventListener('pointermove', handleMove, { signal: controller.signal }); + element.addEventListener('pointerup', handleOut, { signal: controller.signal }); + + return () => { + // Calling `.abort()` removes ALL event listeners + // For more info, see https://kettanaito.com/blog/dont-sleep-on-abort-controller + controller.abort(); + }; + }, [svgRef]); + + return mousePosition; +} + +type PointerType = Pick; + +export function usePointerType(): null | PointerType { + const svgRef = useSvgRef(); + + // Use a ref to avoid rerendering on every mousemove event. + const [pointerType, setPointerType] = React.useState(null); + + React.useEffect(() => { + const element = svgRef.current; + if (element === null) { + return () => {}; + } + + const handleOut = (event: PointerEvent) => { + if (event.pointerType !== 'mouse') { + setPointerType(null); + } + }; + + const handleEnter = (event: PointerEvent) => { + setPointerType({ + height: event.height, + pointerType: event.pointerType as PointerType['pointerType'], + }); + }; + + element.addEventListener('pointerenter', handleEnter); element.addEventListener('pointerup', handleOut); return () => { - element.removeEventListener('pointerdown', handleMove); - element.removeEventListener('pointermove', handleMove); + element.removeEventListener('pointerenter', handleEnter); element.removeEventListener('pointerup', handleOut); }; }, [svgRef]); - return mousePosition; + return pointerType; } export type TriggerOptions = 'item' | 'axis' | 'none'; diff --git a/packages/x-charts/src/ChartsVoronoiHandler/ChartsVoronoiHandler.tsx b/packages/x-charts/src/ChartsVoronoiHandler/ChartsVoronoiHandler.tsx index 4a70336255de..ad1dea102fc6 100644 --- a/packages/x-charts/src/ChartsVoronoiHandler/ChartsVoronoiHandler.tsx +++ b/packages/x-charts/src/ChartsVoronoiHandler/ChartsVoronoiHandler.tsx @@ -64,10 +64,10 @@ function ChartsVoronoiHandler(props: ChartsVoronoiHandlerProps) { voronoiRef.current = {}; let points: number[] = []; seriesOrder.forEach((seriesId) => { - const { data, xAxisId, yAxisId, xAxisKey, yAxisKey } = series[seriesId]; + const { data, xAxisId, yAxisId } = series[seriesId]; - const xScale = xAxis[xAxisId ?? xAxisKey ?? defaultXAxisId].scale; - const yScale = yAxis[yAxisId ?? yAxisKey ?? defaultYAxisId].scale; + const xScale = xAxis[xAxisId ?? defaultXAxisId].scale; + const yScale = yAxis[yAxisId ?? defaultYAxisId].scale; const getXPosition = getValueToPositionMapper(xScale); const getYPosition = getValueToPositionMapper(yScale); diff --git a/packages/x-charts/src/LineChart/AreaElement.tsx b/packages/x-charts/src/LineChart/AreaElement.tsx index 6fe9bfabf030..fe7a0216bee5 100644 --- a/packages/x-charts/src/LineChart/AreaElement.tsx +++ b/packages/x-charts/src/LineChart/AreaElement.tsx @@ -5,7 +5,7 @@ import composeClasses from '@mui/utils/composeClasses'; import useSlotProps from '@mui/utils/useSlotProps'; import generateUtilityClass from '@mui/utils/generateUtilityClass'; import generateUtilityClasses from '@mui/utils/generateUtilityClasses'; -import { SlotComponentPropsFromProps } from '../internals/SlotComponentPropsFromProps'; +import { SlotComponentPropsFromProps } from '@mui/x-internals/types'; import { useInteractionItemProps } from '../hooks/useInteractionItemProps'; import { AnimatedArea, AnimatedAreaProps } from './AnimatedArea'; import { SeriesId } from '../models/seriesType/common'; diff --git a/packages/x-charts/src/LineChart/AreaPlot.tsx b/packages/x-charts/src/LineChart/AreaPlot.tsx index e46e1e4df24a..7db6cbaf1c82 100644 --- a/packages/x-charts/src/LineChart/AreaPlot.tsx +++ b/packages/x-charts/src/LineChart/AreaPlot.tsx @@ -56,19 +56,14 @@ const useAggregatedData = () => { .reverse() // Revert stacked area for a more pleasant animation .map((seriesId) => { const { - xAxisId: xAxisIdProp, - yAxisId: yAxisIdProp, - xAxisKey = defaultXAxisId, - yAxisKey = defaultYAxisId, + xAxisId = defaultXAxisId, + yAxisId = defaultYAxisId, stackedData, data, connectNulls, baseline, } = series[seriesId]; - const xAxisId = xAxisIdProp ?? xAxisKey; - const yAxisId = yAxisIdProp ?? yAxisKey; - const xScale = getValueToPositionMapper(xAxis[xAxisId].scale); const yScale = yAxis[yAxisId].scale; const xData = xAxis[xAxisId].data; diff --git a/packages/x-charts/src/LineChart/LineChart.tsx b/packages/x-charts/src/LineChart/LineChart.tsx index 127c029e9867..f18aef0a7969 100644 --- a/packages/x-charts/src/LineChart/LineChart.tsx +++ b/packages/x-charts/src/LineChart/LineChart.tsx @@ -2,6 +2,7 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import { useThemeProps } from '@mui/material/styles'; +import { MakeOptional } from '@mui/x-internals/types'; import { AreaPlot, AreaPlotProps, AreaPlotSlotProps, AreaPlotSlots } from './AreaPlot'; import { LinePlot, LinePlotProps, LinePlotSlotProps, LinePlotSlots } from './LinePlot'; import { @@ -11,19 +12,13 @@ import { import { MarkPlot, MarkPlotProps, MarkPlotSlotProps, MarkPlotSlots } from './MarkPlot'; import { ChartsAxis, ChartsAxisProps } from '../ChartsAxis/ChartsAxis'; import { LineSeriesType } from '../models/seriesType/line'; -import { MakeOptional } from '../models/helpers'; import { ChartsTooltip, ChartsTooltipProps, ChartsTooltipSlotProps, ChartsTooltipSlots, } from '../ChartsTooltip'; -import { - ChartsLegend, - ChartsLegendProps, - ChartsLegendSlotProps, - ChartsLegendSlots, -} from '../ChartsLegend'; +import { ChartsLegend, ChartsLegendSlotProps, ChartsLegendSlots } from '../ChartsLegend'; import { ChartsAxisHighlight, ChartsAxisHighlightProps } from '../ChartsAxisHighlight'; import { ChartsClipPath } from '../ChartsClipPath'; import { ChartsAxisSlotProps, ChartsAxisSlots } from '../models/axis'; @@ -90,10 +85,6 @@ export interface LineChartProps * @default { x: 'line' } */ axisHighlight?: ChartsAxisHighlightProps; - /** - * @deprecated Consider using `slotProps.legend` instead. - */ - legend?: ChartsLegendProps; /** * If `true`, render the line highlight item. */ @@ -255,35 +246,6 @@ LineChart.propTypes = { * @default yAxisIds[0] The id of the first provided axis */ leftAxis: PropTypes.oneOfType([PropTypes.object, PropTypes.string]), - /** - * @deprecated Consider using `slotProps.legend` instead. - */ - legend: PropTypes.shape({ - classes: PropTypes.object, - direction: PropTypes.oneOf(['column', 'row']), - hidden: PropTypes.bool, - itemGap: PropTypes.number, - itemMarkHeight: PropTypes.number, - itemMarkWidth: PropTypes.number, - labelStyle: PropTypes.object, - markGap: PropTypes.number, - onItemClick: PropTypes.func, - padding: PropTypes.oneOfType([ - PropTypes.number, - PropTypes.shape({ - bottom: PropTypes.number, - left: PropTypes.number, - right: PropTypes.number, - top: PropTypes.number, - }), - ]), - position: PropTypes.shape({ - horizontal: PropTypes.oneOf(['left', 'middle', 'right']).isRequired, - vertical: PropTypes.oneOf(['bottom', 'middle', 'top']).isRequired, - }), - slotProps: PropTypes.object, - slots: PropTypes.object, - }), /** * If `true`, a loading overlay is displayed. * @default false diff --git a/packages/x-charts/src/LineChart/LineElement.tsx b/packages/x-charts/src/LineChart/LineElement.tsx index 269f5a910226..a251ebf47ebc 100644 --- a/packages/x-charts/src/LineChart/LineElement.tsx +++ b/packages/x-charts/src/LineChart/LineElement.tsx @@ -5,7 +5,7 @@ import composeClasses from '@mui/utils/composeClasses'; import useSlotProps from '@mui/utils/useSlotProps'; import generateUtilityClass from '@mui/utils/generateUtilityClass'; import generateUtilityClasses from '@mui/utils/generateUtilityClasses'; -import { SlotComponentPropsFromProps } from '../internals/SlotComponentPropsFromProps'; +import { SlotComponentPropsFromProps } from '@mui/x-internals/types'; import { useInteractionItemProps } from '../hooks/useInteractionItemProps'; import { AnimatedLine, AnimatedLineProps } from './AnimatedLine'; import { SeriesId } from '../models/seriesType/common'; diff --git a/packages/x-charts/src/LineChart/LineHighlightPlot.tsx b/packages/x-charts/src/LineChart/LineHighlightPlot.tsx index 5e1f55c1530f..a5911052eb10 100644 --- a/packages/x-charts/src/LineChart/LineHighlightPlot.tsx +++ b/packages/x-charts/src/LineChart/LineHighlightPlot.tsx @@ -1,7 +1,7 @@ 'use client'; import * as React from 'react'; import PropTypes from 'prop-types'; -import { SlotComponentPropsFromProps } from '../internals/SlotComponentPropsFromProps'; +import { SlotComponentPropsFromProps } from '@mui/x-internals/types'; import { useCartesianContext } from '../context/CartesianProvider'; import { LineHighlightElement, LineHighlightElementProps } from './LineHighlightElement'; import { getValueToPositionMapper } from '../hooks/useScale'; @@ -70,18 +70,13 @@ function LineHighlightPlot(props: LineHighlightPlotProps) { {stackingGroups.flatMap(({ ids: groupIds }) => { return groupIds.flatMap((seriesId) => { const { - xAxisId: xAxisIdProp, - yAxisId: yAxisIdProp, - xAxisKey = defaultXAxisId, - yAxisKey = defaultYAxisId, + xAxisId = defaultXAxisId, + yAxisId = defaultYAxisId, stackedData, data, disableHighlight, } = series[seriesId]; - const xAxisId = xAxisIdProp ?? xAxisKey; - const yAxisId = yAxisIdProp ?? yAxisKey; - if (disableHighlight || data[highlightedIndex] == null) { return null; } diff --git a/packages/x-charts/src/LineChart/LinePlot.tsx b/packages/x-charts/src/LineChart/LinePlot.tsx index a8451c0a787d..75ada74aa047 100644 --- a/packages/x-charts/src/LineChart/LinePlot.tsx +++ b/packages/x-charts/src/LineChart/LinePlot.tsx @@ -54,18 +54,13 @@ const useAggregatedData = () => { return stackingGroups.flatMap(({ ids: groupIds }) => { return groupIds.flatMap((seriesId) => { const { - xAxisId: xAxisIdProp, - yAxisId: yAxisIdProp, - xAxisKey = defaultXAxisId, - yAxisKey = defaultYAxisId, + xAxisId = defaultXAxisId, + yAxisId = defaultYAxisId, stackedData, data, connectNulls, } = series[seriesId]; - const xAxisId = xAxisIdProp ?? xAxisKey; - const yAxisId = yAxisIdProp ?? yAxisKey; - const xScale = getValueToPositionMapper(xAxis[xAxisId].scale); const yScale = yAxis[yAxisId].scale; const xData = xAxis[xAxisId].data; diff --git a/packages/x-charts/src/LineChart/MarkPlot.tsx b/packages/x-charts/src/LineChart/MarkPlot.tsx index c9e446c2a3ff..7731eba6392f 100644 --- a/packages/x-charts/src/LineChart/MarkPlot.tsx +++ b/packages/x-charts/src/LineChart/MarkPlot.tsx @@ -93,10 +93,8 @@ function MarkPlot(props: MarkPlotProps) { {stackingGroups.flatMap(({ ids: groupIds }) => { return groupIds.map((seriesId) => { const { - xAxisId: xAxisIdProp, - yAxisId: yAxisIdProp, - xAxisKey = defaultXAxisId, - yAxisKey = defaultYAxisId, + xAxisId = defaultXAxisId, + yAxisId = defaultYAxisId, stackedData, data, showMark = true, @@ -106,9 +104,6 @@ function MarkPlot(props: MarkPlotProps) { return null; } - const xAxisId = xAxisIdProp ?? xAxisKey; - const yAxisId = yAxisIdProp ?? yAxisKey; - const xScale = getValueToPositionMapper(xAxis[xAxisId].scale); const yScale = yAxis[yAxisId].scale; const xData = xAxis[xAxisId].data; diff --git a/packages/x-charts/src/LineChart/extremums.ts b/packages/x-charts/src/LineChart/extremums.ts index e903b5b6e748..1640dbc7b91d 100644 --- a/packages/x-charts/src/LineChart/extremums.ts +++ b/packages/x-charts/src/LineChart/extremums.ts @@ -36,7 +36,7 @@ export const getExtremumY: ExtremumGetter<'line'> = (params) => { return Object.keys(series) .filter((seriesId) => { - const yAxisId = series[seriesId].yAxisId ?? series[seriesId].yAxisKey; + const yAxisId = series[seriesId].yAxisId; return yAxisId === axis.id || (isDefaultAxis && yAxisId === undefined); }) .reduce( @@ -47,8 +47,8 @@ export const getExtremumY: ExtremumGetter<'line'> = (params) => { const filter = getFilters?.({ currentAxisId: axis.id, isDefaultAxis, - seriesXAxisId: series[seriesId].xAxisId ?? series[seriesId].xAxisKey, - seriesYAxisId: series[seriesId].yAxisId ?? series[seriesId].yAxisKey, + seriesXAxisId: series[seriesId].xAxisId, + seriesYAxisId: series[seriesId].yAxisId, }); // Since this series is not used to display an area, we do not consider the base (the d[0]). diff --git a/packages/x-charts/src/LineChart/formatter.ts b/packages/x-charts/src/LineChart/formatter.ts index ec0ec804abb5..9364ed579e3e 100644 --- a/packages/x-charts/src/LineChart/formatter.ts +++ b/packages/x-charts/src/LineChart/formatter.ts @@ -1,9 +1,9 @@ import { stack as d3Stack } from '@mui/x-charts-vendor/d3-shape'; import { warnOnce } from '@mui/x-internals/warning'; +import { DefaultizedProps } from '@mui/x-internals/types'; import { getStackingGroups } from '../internals/stackSeries'; import { ChartSeries, DatasetElementType, DatasetType } from '../models/seriesType/config'; import { defaultizeValueFormatter } from '../internals/defaultizeValueFormatter'; -import { DefaultizedProps } from '../models/helpers'; import { SeriesId } from '../models/seriesType/common'; import { SeriesFormatter } from '../context/PluginProvider/SeriesFormatter.types'; diff --git a/packages/x-charts/src/LineChart/useLineChartProps.ts b/packages/x-charts/src/LineChart/useLineChartProps.ts index 2b609dc7ff5d..75ccf3bab780 100644 --- a/packages/x-charts/src/LineChart/useLineChartProps.ts +++ b/packages/x-charts/src/LineChart/useLineChartProps.ts @@ -41,7 +41,6 @@ export const useLineChartProps = (props: LineChartProps) => { onMarkClick, axisHighlight, disableLineItemHighlight, - legend, grid, topAxis, leftAxis, @@ -160,7 +159,6 @@ export const useLineChartProps = (props: LineChartProps) => { }; const legendProps: ChartsLegendProps = { - ...legend, slots, slotProps, }; diff --git a/packages/x-charts/src/PieChart/PieArc.tsx b/packages/x-charts/src/PieChart/PieArc.tsx index 6919b17363ed..99c7eda9f856 100644 --- a/packages/x-charts/src/PieChart/PieArc.tsx +++ b/packages/x-charts/src/PieChart/PieArc.tsx @@ -9,7 +9,6 @@ import { styled } from '@mui/material/styles'; import generateUtilityClasses from '@mui/utils/generateUtilityClasses'; import { useInteractionItemProps } from '../hooks/useInteractionItemProps'; import { PieItemId } from '../models'; -import { HighlightScope } from '../context'; export interface PieArcClasses { /** Styles applied to the root element. */ @@ -64,10 +63,6 @@ export type PieArcProps = Omit, 'ref' | 'id'> & PieArcOwnerState & { cornerRadius: SpringValue; endAngle: SpringValue; - /** - * @deprecated Use the `isFaded` or `isHighlighted` props instead. - */ - highlightScope?: Partial; innerRadius: SpringValue; onClick?: (event: React.MouseEvent) => void; outerRadius: SpringValue; @@ -90,7 +85,6 @@ function PieArc(props: PieArcProps) { outerRadius, paddingAngle, startAngle, - highlightScope, ...other } = props; @@ -137,15 +131,6 @@ PieArc.propTypes = { // ---------------------------------------------------------------------- classes: PropTypes.object, dataIndex: PropTypes.number.isRequired, - /** - * @deprecated Use the `isFaded` or `isHighlighted` props instead. - */ - highlightScope: PropTypes.shape({ - fade: PropTypes.oneOf(['global', 'none', 'series']), - faded: PropTypes.oneOf(['global', 'none', 'series']), - highlight: PropTypes.oneOf(['item', 'none', 'series']), - highlighted: PropTypes.oneOf(['item', 'none', 'series']), - }), id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired, isFaded: PropTypes.bool.isRequired, isHighlighted: PropTypes.bool.isRequired, diff --git a/packages/x-charts/src/PieChart/PieArcPlot.tsx b/packages/x-charts/src/PieChart/PieArcPlot.tsx index 13e233d5b642..c2c7279a9ef9 100644 --- a/packages/x-charts/src/PieChart/PieArcPlot.tsx +++ b/packages/x-charts/src/PieChart/PieArcPlot.tsx @@ -15,7 +15,6 @@ import { ValueWithHighlight, useTransformData, } from './dataTransform/useTransformData'; -import { useHighlighted } from '../context'; export interface PieArcPlotSlots { pieArc?: React.JSXElementConstructor; @@ -95,7 +94,6 @@ function PieArcPlot(props: PieArcPlotProps) { ...defaultTransitionConfig, immediate: skipAnimation, }); - const { highlightScope } = useHighlighted(); if (data.length === 0) { return null; @@ -133,7 +131,6 @@ function PieArcPlot(props: PieArcPlotProps) { id={id} color={item.color} dataIndex={index} - highlightScope={highlightScope} isFaded={item.isFaded} isHighlighted={item.isHighlighted} onClick={ diff --git a/packages/x-charts/src/PieChart/PieChart.tsx b/packages/x-charts/src/PieChart/PieChart.tsx index 94b5ae48ac89..b0496fa39bb5 100644 --- a/packages/x-charts/src/PieChart/PieChart.tsx +++ b/packages/x-charts/src/PieChart/PieChart.tsx @@ -3,35 +3,21 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import { useRtl } from '@mui/system/RtlProvider'; import { useThemeProps } from '@mui/material/styles'; +import { MakeOptional } from '@mui/x-internals/types'; import { ResponsiveChartContainer, ResponsiveChartContainerProps, } from '../ResponsiveChartContainer'; -import { ChartsAxis, ChartsAxisProps } from '../ChartsAxis/ChartsAxis'; import { PieSeriesType } from '../models/seriesType'; -import { MakeOptional } from '../models/helpers'; -import { DEFAULT_X_AXIS_KEY } from '../constants'; import { ChartsTooltip, ChartsTooltipProps, ChartsTooltipSlotProps, ChartsTooltipSlots, } from '../ChartsTooltip'; -import { - ChartsLegend, - ChartsLegendProps, - ChartsLegendSlotProps, - ChartsLegendSlots, -} from '../ChartsLegend'; -import { ChartsAxisHighlight, ChartsAxisHighlightProps } from '../ChartsAxisHighlight'; +import { ChartsLegend, ChartsLegendSlotProps, ChartsLegendSlots } from '../ChartsLegend'; import { PiePlot, PiePlotProps, PiePlotSlotProps, PiePlotSlots } from './PiePlot'; import { PieValueType } from '../models/seriesType/pie'; -import { - ChartsAxisSlots, - ChartsAxisSlotProps, - ChartsXAxisProps, - ChartsYAxisProps, -} from '../models/axis'; import { ChartsOverlay, ChartsOverlayProps, @@ -40,15 +26,13 @@ import { } from '../ChartsOverlay'; export interface PieChartSlots - extends ChartsAxisSlots, - PiePlotSlots, + extends PiePlotSlots, ChartsLegendSlots, ChartsTooltipSlots<'pie'>, ChartsOverlaySlots {} export interface PieChartSlotProps - extends ChartsAxisSlotProps, - PiePlotSlotProps, + extends PiePlotSlotProps, ChartsLegendSlotProps, ChartsTooltipSlotProps<'pie'>, ChartsOverlaySlotProps {} @@ -58,21 +42,8 @@ export interface PieChartProps ResponsiveChartContainerProps, 'series' | 'leftAxis' | 'bottomAxis' | 'plugins' | 'zAxis' >, - Omit, Omit, Pick { - /** - * Indicate which axis to display the bottom of the charts. - * Can be a string (the id of the axis) or an object `ChartsXAxisProps`. - * @default null - */ - bottomAxis?: null | string | ChartsXAxisProps; - /** - * Indicate which axis to display the left of the charts. - * Can be a string (the id of the axis) or an object `ChartsYAxisProps`. - * @default null - */ - leftAxis?: null | string | ChartsYAxisProps; /** * The series to display in the pie chart. * An array of [[PieSeriesType]] objects. @@ -84,18 +55,6 @@ export interface PieChartProps * @default { trigger: 'item' } */ tooltip?: ChartsTooltipProps<'pie'>; - /** - * The configuration of axes highlight. - * @see See {@link https://mui.com/x/react-charts/highlighting highlighting docs} for more details. - * @default { x: 'none', y: 'none' } - */ - axisHighlight?: ChartsAxisHighlightProps; - /** - * The props of the legend. - * @default { direction: 'column', position: { vertical: 'middle', horizontal: 'right' } } - * @deprecated Consider using `slotProps.legend` instead. - */ - legend?: ChartsLegendProps; /** * Callback fired when a pie arc is clicked. */ @@ -137,13 +96,7 @@ const PieChart = React.forwardRef(function PieChart(inProps: PieChartProps, ref) colors, sx, tooltip = { trigger: 'item' }, - axisHighlight = { x: 'none', y: 'none' }, skipAnimation, - legend: legendProps, - topAxis = null, - leftAxis = null, - rightAxis = null, - bottomAxis = null, children, slots, slotProps, @@ -157,11 +110,6 @@ const PieChart = React.forwardRef(function PieChart(inProps: PieChartProps, ref) const isRtl = useRtl(); const margin = { ...(isRtl ? defaultRTLMargin : defaultMargin), ...marginProps }; - const legend: ChartsLegendProps = { - direction: 'column', - position: { vertical: 'middle', horizontal: isRtl ? 'left' : 'right' }, - ...legendProps, - }; return ( s.data.length)))].map( - (_, index) => index, - ), - }, - ] - } - yAxis={yAxis} colors={colors} sx={sx} - disableAxisListener={ - tooltip?.trigger !== 'axis' && axisHighlight?.x === 'none' && axisHighlight?.y === 'none' - } + disableAxisListener highlightedItem={highlightedItem} onHighlightChange={onHighlightChange} className={className} skipAnimation={skipAnimation} > - + + - - - - {!loading && } {children} @@ -216,21 +146,6 @@ PieChart.propTypes = { // | These PropTypes are generated from the TypeScript type definitions | // | To update them edit the TypeScript types and run "pnpm proptypes" | // ---------------------------------------------------------------------- - /** - * The configuration of axes highlight. - * @see See {@link https://mui.com/x/react-charts/highlighting highlighting docs} for more details. - * @default { x: 'none', y: 'none' } - */ - axisHighlight: PropTypes.shape({ - x: PropTypes.oneOf(['band', 'line', 'none']), - y: PropTypes.oneOf(['band', 'line', 'none']), - }), - /** - * Indicate which axis to display the bottom of the charts. - * Can be a string (the id of the axis) or an object `ChartsXAxisProps`. - * @default null - */ - bottomAxis: PropTypes.oneOfType([PropTypes.object, PropTypes.string]), children: PropTypes.node, className: PropTypes.string, /** @@ -260,43 +175,6 @@ PieChart.propTypes = { dataIndex: PropTypes.number, seriesId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), }), - /** - * Indicate which axis to display the left of the charts. - * Can be a string (the id of the axis) or an object `ChartsYAxisProps`. - * @default null - */ - leftAxis: PropTypes.oneOfType([PropTypes.object, PropTypes.string]), - /** - * The props of the legend. - * @default { direction: 'column', position: { vertical: 'middle', horizontal: 'right' } } - * @deprecated Consider using `slotProps.legend` instead. - */ - legend: PropTypes.shape({ - classes: PropTypes.object, - direction: PropTypes.oneOf(['column', 'row']), - hidden: PropTypes.bool, - itemGap: PropTypes.number, - itemMarkHeight: PropTypes.number, - itemMarkWidth: PropTypes.number, - labelStyle: PropTypes.object, - markGap: PropTypes.number, - onItemClick: PropTypes.func, - padding: PropTypes.oneOfType([ - PropTypes.number, - PropTypes.shape({ - bottom: PropTypes.number, - left: PropTypes.number, - right: PropTypes.number, - top: PropTypes.number, - }), - ]), - position: PropTypes.shape({ - horizontal: PropTypes.oneOf(['left', 'middle', 'right']).isRequired, - vertical: PropTypes.oneOf(['bottom', 'middle', 'top']).isRequired, - }), - slotProps: PropTypes.object, - slots: PropTypes.object, - }), /** * If `true`, a loading overlay is displayed. * @default false @@ -334,12 +212,6 @@ PieChart.propTypes = { * @default false */ resolveSizeBeforeRender: PropTypes.bool, - /** - * Indicate which axis to display the right of the charts. - * Can be a string (the id of the axis) or an object `ChartsYAxisProps`. - * @default null - */ - rightAxis: PropTypes.oneOfType([PropTypes.object, PropTypes.string]), /** * The series to display in the pie chart. * An array of [[PieSeriesType]] objects. @@ -379,12 +251,6 @@ PieChart.propTypes = { slots: PropTypes.object, trigger: PropTypes.oneOf(['axis', 'item', 'none']), }), - /** - * Indicate which axis to display the top of the charts. - * Can be a string (the id of the axis) or an object `ChartsXAxisProps`. - * @default null - */ - topAxis: PropTypes.oneOfType([PropTypes.object, PropTypes.string]), viewBox: PropTypes.shape({ height: PropTypes.number, width: PropTypes.number, diff --git a/packages/x-charts/src/ScatterChart/ScatterChart.tsx b/packages/x-charts/src/ScatterChart/ScatterChart.tsx index 88a946521121..97583d34e035 100644 --- a/packages/x-charts/src/ScatterChart/ScatterChart.tsx +++ b/packages/x-charts/src/ScatterChart/ScatterChart.tsx @@ -2,6 +2,7 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import { useThemeProps } from '@mui/material/styles'; +import { MakeOptional } from '@mui/x-internals/types'; import { ScatterPlot, ScatterPlotProps, @@ -14,19 +15,13 @@ import { } from '../ResponsiveChartContainer'; import { ChartsAxis, ChartsAxisProps } from '../ChartsAxis'; import { ScatterSeriesType } from '../models/seriesType/scatter'; -import { MakeOptional } from '../models/helpers'; import { ChartsTooltip, ChartsTooltipProps, ChartsTooltipSlotProps, ChartsTooltipSlots, } from '../ChartsTooltip'; -import { - ChartsLegend, - ChartsLegendProps, - ChartsLegendSlotProps, - ChartsLegendSlots, -} from '../ChartsLegend'; +import { ChartsLegend, ChartsLegendSlotProps, ChartsLegendSlots } from '../ChartsLegend'; import { ChartsOverlay, ChartsOverlayProps, @@ -88,10 +83,6 @@ export interface ScatterChartProps * @default false */ disableVoronoi?: boolean; - /** - * @deprecated Consider using `slotProps.legend` instead. - */ - legend?: ChartsLegendProps; /** * Overridable component slots. * @default {} @@ -222,35 +213,6 @@ ScatterChart.propTypes = { * @default yAxisIds[0] The id of the first provided axis */ leftAxis: PropTypes.oneOfType([PropTypes.object, PropTypes.string]), - /** - * @deprecated Consider using `slotProps.legend` instead. - */ - legend: PropTypes.shape({ - classes: PropTypes.object, - direction: PropTypes.oneOf(['column', 'row']), - hidden: PropTypes.bool, - itemGap: PropTypes.number, - itemMarkHeight: PropTypes.number, - itemMarkWidth: PropTypes.number, - labelStyle: PropTypes.object, - markGap: PropTypes.number, - onItemClick: PropTypes.func, - padding: PropTypes.oneOfType([ - PropTypes.number, - PropTypes.shape({ - bottom: PropTypes.number, - left: PropTypes.number, - right: PropTypes.number, - top: PropTypes.number, - }), - ]), - position: PropTypes.shape({ - horizontal: PropTypes.oneOf(['left', 'middle', 'right']).isRequired, - vertical: PropTypes.oneOf(['bottom', 'middle', 'top']).isRequired, - }), - slotProps: PropTypes.object, - slots: PropTypes.object, - }), /** * If `true`, a loading overlay is displayed. * @default false diff --git a/packages/x-charts/src/ScatterChart/ScatterPlot.tsx b/packages/x-charts/src/ScatterChart/ScatterPlot.tsx index dcc8f4ebf083..639121a8c79e 100644 --- a/packages/x-charts/src/ScatterChart/ScatterPlot.tsx +++ b/packages/x-charts/src/ScatterChart/ScatterPlot.tsx @@ -59,17 +59,16 @@ function ScatterPlot(props: ScatterPlotProps) { return ( {seriesOrder.map((seriesId) => { - const { id, xAxisKey, yAxisKey, zAxisKey, xAxisId, yAxisId, zAxisId, markerSize, color } = - series[seriesId]; + const { id, xAxisId, yAxisId, zAxisId, markerSize, color } = series[seriesId]; const colorGetter = getColor( series[seriesId], - xAxis[xAxisId ?? xAxisKey ?? defaultXAxisId], - yAxis[yAxisId ?? yAxisKey ?? defaultYAxisId], - zAxis[zAxisId ?? zAxisKey ?? defaultZAxisId], + xAxis[xAxisId ?? defaultXAxisId], + yAxis[yAxisId ?? defaultYAxisId], + zAxis[zAxisId ?? defaultZAxisId], ); - const xScale = xAxis[xAxisId ?? xAxisKey ?? defaultXAxisId].scale; - const yScale = yAxis[yAxisId ?? yAxisKey ?? defaultYAxisId].scale; + const xScale = xAxis[xAxisId ?? defaultXAxisId].scale; + const yScale = yAxis[yAxisId ?? defaultYAxisId].scale; return ( = (params) => { return Object.keys(series) .filter((seriesId) => { - const axisId = series[seriesId].xAxisId ?? series[seriesId].xAxisKey; + const axisId = series[seriesId].xAxisId; return axisId === axis.id || (axisId === undefined && isDefaultAxis); }) .reduce( @@ -23,8 +23,8 @@ export const getExtremumX: ExtremumGetter<'scatter'> = (params) => { const filter = getFilters?.({ currentAxisId: axis.id, isDefaultAxis, - seriesXAxisId: series[seriesId].xAxisId ?? series[seriesId].xAxisKey, - seriesYAxisId: series[seriesId].yAxisId ?? series[seriesId].yAxisKey, + seriesXAxisId: series[seriesId].xAxisId, + seriesYAxisId: series[seriesId].yAxisId, }); const seriesMinMax = series[seriesId].data?.reduce( @@ -47,7 +47,7 @@ export const getExtremumY: ExtremumGetter<'scatter'> = (params) => { return Object.keys(series) .filter((seriesId) => { - const axisId = series[seriesId].yAxisId ?? series[seriesId].yAxisKey; + const axisId = series[seriesId].yAxisId; return axisId === axis.id || (axisId === undefined && isDefaultAxis); }) .reduce( @@ -55,8 +55,8 @@ export const getExtremumY: ExtremumGetter<'scatter'> = (params) => { const filter = getFilters?.({ currentAxisId: axis.id, isDefaultAxis, - seriesXAxisId: series[seriesId].xAxisId ?? series[seriesId].xAxisKey, - seriesYAxisId: series[seriesId].yAxisId ?? series[seriesId].yAxisKey, + seriesXAxisId: series[seriesId].xAxisId, + seriesYAxisId: series[seriesId].yAxisId, }); const seriesMinMax = series[seriesId].data?.reduce( diff --git a/packages/x-charts/src/ScatterChart/useScatterChartProps.ts b/packages/x-charts/src/ScatterChart/useScatterChartProps.ts index c54a3b8c7fd0..e6ae591aa08d 100644 --- a/packages/x-charts/src/ScatterChart/useScatterChartProps.ts +++ b/packages/x-charts/src/ScatterChart/useScatterChartProps.ts @@ -28,7 +28,6 @@ export const useScatterChartProps = (props: ScatterChartProps) => { axisHighlight, voronoiMaxRadius, disableVoronoi, - legend, width, height, margin, @@ -98,7 +97,6 @@ export const useScatterChartProps = (props: ScatterChartProps) => { }; const legendProps: ChartsLegendProps = { - ...legend, slots, slotProps, }; diff --git a/packages/x-charts/src/SparkLineChart/SparkLineChart.tsx b/packages/x-charts/src/SparkLineChart/SparkLineChart.tsx index d6e698333a55..af5b7b3d8760 100644 --- a/packages/x-charts/src/SparkLineChart/SparkLineChart.tsx +++ b/packages/x-charts/src/SparkLineChart/SparkLineChart.tsx @@ -1,6 +1,7 @@ 'use client'; import * as React from 'react'; import PropTypes from 'prop-types'; +import { MakeOptional } from '@mui/x-internals/types'; import { BarPlot } from '../BarChart'; import { LinePlot, AreaPlot, LineHighlightPlot } from '../LineChart'; import { @@ -16,7 +17,6 @@ import { } from '../ChartsTooltip'; import { ChartsAxisHighlight, ChartsAxisHighlightProps } from '../ChartsAxisHighlight'; import { AxisConfig, ChartsXAxisProps, ChartsYAxisProps, ScaleName } from '../models/axis'; -import { MakeOptional } from '../models/helpers'; import { LineSeriesType, BarSeriesType } from '../models/seriesType'; import { CardinalDirections } from '../models/layout'; import { AreaPlotSlots, AreaPlotSlotProps } from '../LineChart/AreaPlot'; diff --git a/packages/x-charts/src/context/CartesianProvider/defaultizeAxis.ts b/packages/x-charts/src/context/CartesianProvider/defaultizeAxis.ts index 6848835d34a6..0ae491cce71d 100644 --- a/packages/x-charts/src/context/CartesianProvider/defaultizeAxis.ts +++ b/packages/x-charts/src/context/CartesianProvider/defaultizeAxis.ts @@ -1,5 +1,5 @@ +import { MakeOptional } from '@mui/x-internals/types'; import { DEFAULT_X_AXIS_KEY, DEFAULT_Y_AXIS_KEY } from '../../constants'; -import { MakeOptional } from '../../models/helpers'; import { AxisConfig, ScaleName } from '../../models'; import { ChartsAxisProps } from '../../models/axis'; diff --git a/packages/x-charts/src/context/HighlightedProvider/HighlightedContext.ts b/packages/x-charts/src/context/HighlightedProvider/HighlightedContext.ts index 335b8ba59223..f89055efd50b 100644 --- a/packages/x-charts/src/context/HighlightedProvider/HighlightedContext.ts +++ b/packages/x-charts/src/context/HighlightedProvider/HighlightedContext.ts @@ -34,10 +34,6 @@ export type HighlightOptions = 'none' | 'item' | 'series'; export type FadeOptions = 'none' | 'series' | 'global'; export type HighlightScope = { - /** - * @deprecated Use `highlight` instead. - */ - highlighted?: HighlightOptions; /** * The scope of highlighted elements. * - 'none': no highlight. @@ -46,10 +42,6 @@ export type HighlightScope = { * @default 'none' */ highlight?: HighlightOptions; - /** - * @deprecated Use `fade` instead. - */ - faded?: FadeOptions; /** * The scope of faded elements. * - 'none': no fading. diff --git a/packages/x-charts/src/context/HighlightedProvider/HighlightedProvider.tsx b/packages/x-charts/src/context/HighlightedProvider/HighlightedProvider.tsx index 23a99d9b3e39..a5e097e067f6 100644 --- a/packages/x-charts/src/context/HighlightedProvider/HighlightedProvider.tsx +++ b/packages/x-charts/src/context/HighlightedProvider/HighlightedProvider.tsx @@ -29,15 +29,6 @@ export type HighlightedProviderProps = { onHighlightChange?: (highlightedItem: HighlightItemData | null) => void; }; -const mergeDeprecatedOptions = (options?: Partial): HighlightScope => { - const { highlighted, faded, ...other } = options ?? {}; - return { - highlight: highlighted, - fade: faded, - ...other, - }; -}; - function HighlightedProvider({ children, highlightedItem: highlightedItemProps, @@ -58,7 +49,7 @@ function HighlightedProvider({ const seriesData = series[seriesType as ChartSeriesType]; Object.keys(seriesData?.series ?? {}).forEach((seriesId) => { const seriesItem = seriesData?.series[seriesId]; - map.set(seriesId, mergeDeprecatedOptions(seriesItem?.highlightScope)); + map.set(seriesId, seriesItem?.highlightScope); }); }); return map; diff --git a/packages/x-charts/src/context/ZAxisContextProvider.tsx b/packages/x-charts/src/context/ZAxisContextProvider.tsx index 0c028a6e7fc9..67763d9f7cc6 100644 --- a/packages/x-charts/src/context/ZAxisContextProvider.tsx +++ b/packages/x-charts/src/context/ZAxisContextProvider.tsx @@ -1,8 +1,8 @@ 'use client'; import * as React from 'react'; import PropTypes from 'prop-types'; +import { MakeOptional } from '@mui/x-internals/types'; import { DatasetType } from '../models/seriesType/config'; -import { MakeOptional } from '../models/helpers'; import { getColorScale, getOrdinalColorScale } from '../internals/colorScale'; import { ZAxisConfig, ZAxisDefaultized } from '../models/z-axis'; diff --git a/packages/x-charts/src/internals/getSymbol.ts b/packages/x-charts/src/internals/getSymbol.ts index 72d216c2e02a..09e83d4fadba 100644 --- a/packages/x-charts/src/internals/getSymbol.ts +++ b/packages/x-charts/src/internals/getSymbol.ts @@ -1,7 +1,15 @@ export type SymbolsTypes = 'circle' | 'cross' | 'diamond' | 'square' | 'star' | 'triangle' | 'wye'; -// Returns the index of a defined shape -export function getSymbol(shape: SymbolsTypes): number { - const symbolNames = 'circle cross diamond square star triangle wye'.split(/ /); - return symbolNames.indexOf(shape) || 0; +export function getSymbol(shape: SymbolsTypes): number { + // prettier-ignore + switch (shape) { + case 'circle': return 0; + case 'cross': return 1; + case 'diamond': return 2; + case 'square': return 3; + case 'star': return 4; + case 'triangle': return 5; + case 'wye': return 6; + default: return 0; + } } diff --git a/packages/x-charts/src/internals/index.ts b/packages/x-charts/src/internals/index.ts index c8f1ffd8626b..2c9e50be6b42 100644 --- a/packages/x-charts/src/internals/index.ts +++ b/packages/x-charts/src/internals/index.ts @@ -40,6 +40,5 @@ export { getAxisExtremum } from '../context/CartesianProvider/getAxisExtremum'; export * from '../models/seriesType/config'; export * from '../models/seriesType/common'; -export * from '../models/helpers'; export * from '../models/z-axis'; export * from '../models/axis'; diff --git a/packages/x-charts/src/models/seriesType/bar.ts b/packages/x-charts/src/models/seriesType/bar.ts index 94023220b54b..238d7c7e4cbe 100644 --- a/packages/x-charts/src/models/seriesType/bar.ts +++ b/packages/x-charts/src/models/seriesType/bar.ts @@ -1,4 +1,4 @@ -import { DefaultizedProps } from '../helpers'; +import { DefaultizedProps } from '@mui/x-internals/types'; import type { StackOffsetType } from '../stacking'; import { CartesianSeriesType, diff --git a/packages/x-charts/src/models/seriesType/common.ts b/packages/x-charts/src/models/seriesType/common.ts index 5ec59cc45455..356c8a4b4b23 100644 --- a/packages/x-charts/src/models/seriesType/common.ts +++ b/packages/x-charts/src/models/seriesType/common.ts @@ -13,7 +13,7 @@ export type SeriesValueFormatterContext = { export type SeriesValueFormatter = ( value: TValue, context: SeriesValueFormatterContext, -) => string; +) => string | null; export type CommonSeriesType = { id?: SeriesId; @@ -22,7 +22,7 @@ export type CommonSeriesType = { * Formatter used to render values in tooltip or other data display. * @param {TValue} value The series' value to render. * @param {SeriesValueFormatterContext} context The rendering context of the value. - * @returns {string} The string to display. + * @returns {string | null} The string to display or null if the value should not be shown. */ valueFormatter?: SeriesValueFormatter; /** @@ -34,16 +34,6 @@ export type CommonSeriesType = { export type CommonDefaultizedProps = 'id' | 'valueFormatter' | 'data'; export type CartesianSeriesType = { - /** - * The id of the x-axis used to render the series. - * @deprecated Use `xAxisId` instead - */ - xAxisKey?: string; - /** - * The id of the y-axis used to render the series. - * @deprecated Use `xAxisId` instead - */ - yAxisKey?: string; /** * The id of the x-axis used to render the series. */ diff --git a/packages/x-charts/src/models/seriesType/config.ts b/packages/x-charts/src/models/seriesType/config.ts index 563ca7b6ec62..f266d53fa487 100644 --- a/packages/x-charts/src/models/seriesType/config.ts +++ b/packages/x-charts/src/models/seriesType/config.ts @@ -1,3 +1,4 @@ +import { DefaultizedProps, MakeOptional } from '@mui/x-internals/types'; import { ScatterSeriesType, DefaultizedScatterSeriesType, @@ -13,7 +14,6 @@ import { PieValueType, DefaultizedPieValueType, } from './pie'; -import { DefaultizedProps, MakeOptional } from '../helpers'; export interface ChartsSeriesConfig { bar: { diff --git a/packages/x-charts/src/models/seriesType/line.ts b/packages/x-charts/src/models/seriesType/line.ts index f27c6f4eec49..298d95b30cac 100644 --- a/packages/x-charts/src/models/seriesType/line.ts +++ b/packages/x-charts/src/models/seriesType/line.ts @@ -1,4 +1,4 @@ -import { DefaultizedProps } from '../helpers'; +import { DefaultizedProps } from '@mui/x-internals/types'; import type { StackOffsetType } from '../stacking'; import { CartesianSeriesType, diff --git a/packages/x-charts/src/models/seriesType/pie.ts b/packages/x-charts/src/models/seriesType/pie.ts index bf87340066cb..1ab1a6a4b5a8 100644 --- a/packages/x-charts/src/models/seriesType/pie.ts +++ b/packages/x-charts/src/models/seriesType/pie.ts @@ -1,5 +1,5 @@ import { PieArcDatum as D3PieArcDatum } from '@mui/x-charts-vendor/d3-shape'; -import { DefaultizedProps } from '../helpers'; +import { DefaultizedProps } from '@mui/x-internals/types'; import { CommonDefaultizedProps, CommonSeriesType, SeriesId } from './common'; export type PieItemId = string | number; diff --git a/packages/x-charts/src/models/seriesType/scatter.ts b/packages/x-charts/src/models/seriesType/scatter.ts index 211763f1ef36..61f4d0c4b808 100644 --- a/packages/x-charts/src/models/seriesType/scatter.ts +++ b/packages/x-charts/src/models/seriesType/scatter.ts @@ -1,4 +1,4 @@ -import { DefaultizedProps } from '../helpers'; +import { DefaultizedProps } from '@mui/x-internals/types'; import { CartesianSeriesType, CommonDefaultizedProps, CommonSeriesType, SeriesId } from './common'; export type ScatterValueType = { @@ -24,11 +24,6 @@ export interface ScatterSeriesType extends CommonSeriesType, C * @default false */ disableHover?: boolean; - /** - * The id of the z-axis used to render the series. - * @deprecated Use `zAxisId` instead. - */ - zAxisKey?: string; /** * The id of the z-axis used to render the series. */ diff --git a/packages/x-codemod/README.md b/packages/x-codemod/README.md index 32eb12c7aa55..af1290cabb81 100644 --- a/packages/x-codemod/README.md +++ b/packages/x-codemod/README.md @@ -13,7 +13,7 @@ This repository contains a collection of codemod scripts based for use with ```bash -npx @mui/x-codemod@latest +npx @mui/x-codemod@next Applies a `@mui/x-codemod` to the specified paths @@ -29,8 +29,8 @@ Options: --jscodeshift Pass options directly to jscodeshift [array] Examples: - npx @mui/x-codemod@latest v7.0.0/preset-safe src - npx @mui/x-codemod@latest v6.0.0/component-rename-prop src -- + npx @mui/x-codemod@next v7.0.0/preset-safe src + npx @mui/x-codemod@next v6.0.0/component-rename-prop src -- --component=DataGrid --from=prop --to=newProp ``` @@ -40,9 +40,9 @@ To pass more options directly to jscodeshift, use `--jscodeshift=...`. For examp ```bash // single option -npx @mui/x-codemod@latest --jscodeshift=--run-in-band +npx @mui/x-codemod@next --jscodeshift=--run-in-band // multiple options -npx @mui/x-codemod@latest --jscodeshift=--cpus=1 --jscodeshift=--print --jscodeshift=--dry --jscodeshift=--verbose=2 +npx @mui/x-codemod@next --jscodeshift=--cpus=1 --jscodeshift=--print --jscodeshift=--dry --jscodeshift=--verbose=2 ``` See all available options [here](https://github.com/facebook/jscodeshift#usage-cli). @@ -53,7 +53,50 @@ Options to [recast](https://github.com/benjamn/recast)'s printer can be provided through jscodeshift's `printOptions` command line argument ```bash -npx @mui/x-codemod@latest --jscodeshift="--printOptions='{\"quote\":\"double\"}'" +npx @mui/x-codemod@next --jscodeshift="--printOptions='{\"quote\":\"double\"}'" +``` + +## v8.0.0 + +### 🚀 `preset-safe` for v8.0.0 + +A combination of all important transformers for migrating v7 to v8. +⚠️ This codemod should be run only once. +It runs codemods for both Data Grid and Date and Time Pickers packages. +To run codemods for a specific package, refer to the respective section. + +```bash +npx @mui/x-codemod@latest v8.0.0/preset-safe +``` + +The corresponding sub-sections are listed below + +- [`preset-safe-for-tree-view`](#preset-safe-for-tree-view-v800) + +### Tree View codemods + +#### `preset-safe` for tree view v8.0.0 + +The `preset-safe` codemods for tree view. + +```bash +npx @mui/x-codemod@latest v8.0.0/tree-view/preset-safe +``` + +The list includes these transformers + +- [`rename-tree-item-2`](#rename-tree-item-2) + +#### `rename-tree-item-2` + +Renames the `TreeItem2` component to `TreeItem` (same for any subcomponents or utils like `useTreeItem2` or `TreeItem2Icon`). + +```diff +-import { TreeItem2 } from '@mui/x-tree-view'; ++import { TreeItem } from '@mui/x-tree-view'; + +-import { TreeItem2 } from '@mui/x-tree-view/TreeItem2'; ++import { TreeItem } from '@mui/x-tree-view/TreeItem'; ``` ## v7.0.0 diff --git a/packages/x-codemod/package.json b/packages/x-codemod/package.json index c9a7f1934e1d..15d3299c56d5 100644 --- a/packages/x-codemod/package.json +++ b/packages/x-codemod/package.json @@ -32,9 +32,10 @@ "url": "https://opencollective.com/mui-org" }, "dependencies": { - "@babel/core": "^7.25.8", - "@babel/runtime": "^7.25.7", - "@babel/traverse": "^7.25.7", + "@babel/core": "^7.26.0", + "@babel/runtime": "^7.26.0", + "@babel/traverse": "^7.25.9", + "@mui/x-internals": "workspace:*", "jscodeshift": "17.0.0", "yargs": "^17.7.2" }, diff --git a/packages/x-codemod/src/types.ts b/packages/x-codemod/src/types.ts index 0e5315efaf19..6a93f6de2e1f 100644 --- a/packages/x-codemod/src/types.ts +++ b/packages/x-codemod/src/types.ts @@ -1,9 +1,8 @@ import type { FileInfo, API } from 'jscodeshift'; +import { MakeOptional } from '@mui/x-internals/types'; -type MakeRequired = Pick & Partial>; - -type MakeOptional = Omit & Partial>; +type KeepRequired = Pick & Partial>; export type JsCodeShiftFileInfo = MakeOptional; -export type JsCodeShiftAPI = MakeRequired; +export type JsCodeShiftAPI = KeepRequired; diff --git a/packages/x-codemod/src/v8.0.0/charts/preset-safe/actual.spec.tsx b/packages/x-codemod/src/v8.0.0/charts/preset-safe/actual.spec.tsx new file mode 100644 index 000000000000..dbeda401f028 --- /dev/null +++ b/packages/x-codemod/src/v8.0.0/charts/preset-safe/actual.spec.tsx @@ -0,0 +1,9 @@ +// @ts-nocheck +import * as React from 'react'; +import { PieChart } from '@mui/x-charts/PieChart'; + +// prettier-ignore +
+ + +
; diff --git a/packages/x-codemod/src/v8.0.0/charts/preset-safe/expected.spec.tsx b/packages/x-codemod/src/v8.0.0/charts/preset-safe/expected.spec.tsx new file mode 100644 index 000000000000..cc9413b2bf3b --- /dev/null +++ b/packages/x-codemod/src/v8.0.0/charts/preset-safe/expected.spec.tsx @@ -0,0 +1,16 @@ +// @ts-nocheck +import * as React from 'react'; +import { PieChart } from '@mui/x-charts/PieChart'; + +// prettier-ignore +
+ + +
; diff --git a/packages/x-codemod/src/v8.0.0/charts/preset-safe/index.ts b/packages/x-codemod/src/v8.0.0/charts/preset-safe/index.ts new file mode 100644 index 000000000000..6e02a9f2935f --- /dev/null +++ b/packages/x-codemod/src/v8.0.0/charts/preset-safe/index.ts @@ -0,0 +1,9 @@ +import transformLegendToSlots from '../rename-legend-to-slots-legend'; + +import { JsCodeShiftAPI, JsCodeShiftFileInfo } from '../../../types'; + +export default function transformer(file: JsCodeShiftFileInfo, api: JsCodeShiftAPI, options: any) { + file.source = transformLegendToSlots(file, api, options); + + return file.source; +} diff --git a/packages/x-codemod/src/v8.0.0/charts/preset-safe/preset-safe.test.ts b/packages/x-codemod/src/v8.0.0/charts/preset-safe/preset-safe.test.ts new file mode 100644 index 000000000000..95b4e3f0d69b --- /dev/null +++ b/packages/x-codemod/src/v8.0.0/charts/preset-safe/preset-safe.test.ts @@ -0,0 +1,41 @@ +import path from 'path'; +import { expect } from 'chai'; +import jscodeshift from 'jscodeshift'; +import transform from './index'; +import readFile from '../../../util/readFile'; + +function read(fileName) { + return readFile(path.join(__dirname, fileName)); +} + +describe('v8.0.0/charts', () => { + describe('preset-safe', () => { + it('transforms code as needed', () => { + const actual = transform( + { + source: read('./actual.spec.tsx'), + path: require.resolve('./actual.spec.tsx'), + }, + { jscodeshift: jscodeshift.withParser('tsx') }, + {}, + ); + + const expected = read('./expected.spec.tsx'); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + + it('should be idempotent for expression', () => { + const actual = transform( + { + source: read('./expected.spec.tsx'), + path: require.resolve('./expected.spec.tsx'), + }, + { jscodeshift: jscodeshift.withParser('tsx') }, + {}, + ); + + const expected = read('./expected.spec.tsx'); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + }); +}); diff --git a/packages/x-codemod/src/v8.0.0/charts/rename-legend-to-slots-legend/index.ts b/packages/x-codemod/src/v8.0.0/charts/rename-legend-to-slots-legend/index.ts new file mode 100644 index 000000000000..2c6d0aeec4ac --- /dev/null +++ b/packages/x-codemod/src/v8.0.0/charts/rename-legend-to-slots-legend/index.ts @@ -0,0 +1,79 @@ +import { JsCodeShiftAPI, JsCodeShiftFileInfo } from '../../../types'; +import { transformNestedProp } from '../../../util/addComponentsSlots'; +/** + * @param {import('jscodeshift').FileInfo} file + * @param {import('jscodeshift').API} api + */ +export default function transformer(file: JsCodeShiftFileInfo, api: JsCodeShiftAPI, options: any) { + const j = api.jscodeshift; + + const printOptions = options.printOptions; + + const root = j(file.source); + + root + .find(j.ImportDeclaration) + .filter(({ node }) => { + return typeof node.source.value === 'string' && node.source.value.startsWith('@mui/x-charts'); + }) + .forEach((path) => { + path.node.specifiers?.forEach((node) => { + root.findJSXElements(node.local?.name).forEach((elementPath) => { + if (elementPath.node.type !== 'JSXElement') { + return; + } + + const legendProps = elementPath.node.openingElement.attributes?.find( + (elementNode) => + elementNode.type === 'JSXAttribute' && elementNode.name.name === 'legend', + ); + + if (!legendProps) { + // No legend props to manage + return; + } + + const slotProps = elementPath.node.openingElement.attributes?.find( + (elementNode) => + elementNode.type === 'JSXAttribute' && elementNode.name.name === 'slotProps', + ); + + if (slotProps === null) { + // We create a new slotProps object + elementPath.node.openingElement.attributes?.push( + j.jsxAttribute( + j.jsxIdentifier('slotProps'), + j.jsxExpressionContainer( + j.objectExpression([ + // @ts-ignore legend receives an object. + j.objectProperty(j.identifier('legend'), legendProps.value.expression), + ]), + ), + ), + ); + } else { + transformNestedProp( + elementPath, + 'slotProps', + 'legend', + // @ts-ignore legend receives an object. + legendProps.value.expression, + j, + ); + } + + // Remove the legend prop + j(elementPath) + .find(j.JSXAttribute) + .filter((a) => a.value.name.name === 'legend') + .forEach((pathToRemove) => { + j(pathToRemove).remove(); + }); + }); + }); + }); + + const transformed = root.findJSXElements(); + + return transformed.toSource(printOptions); +} diff --git a/packages/x-codemod/src/v8.0.0/preset-safe/actual.spec.js b/packages/x-codemod/src/v8.0.0/preset-safe/actual.spec.js new file mode 100644 index 000000000000..f8a5b4f02aa2 --- /dev/null +++ b/packages/x-codemod/src/v8.0.0/preset-safe/actual.spec.js @@ -0,0 +1,15 @@ +// @ts-nocheck +import * as React from 'react'; +import { TreeItem2 } from '@mui/x-tree-view/TreeItem2'; +import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView'; +import { PieChart } from '@mui/x-charts/PieChart'; + +const className = treeViewClasses.root; + +// prettier-ignore + + + + + + diff --git a/packages/x-codemod/src/v8.0.0/preset-safe/expected.spec.js b/packages/x-codemod/src/v8.0.0/preset-safe/expected.spec.js new file mode 100644 index 000000000000..b85fe4c34ed3 --- /dev/null +++ b/packages/x-codemod/src/v8.0.0/preset-safe/expected.spec.js @@ -0,0 +1,18 @@ +// @ts-nocheck +import * as React from 'react'; +import { TreeItem } from '@mui/x-tree-view/TreeItem'; +import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView'; +import { PieChart } from '@mui/x-charts/PieChart'; + +const className = treeViewClasses.root; + +// prettier-ignore + + + + + + diff --git a/packages/x-codemod/src/v8.0.0/preset-safe/index.ts b/packages/x-codemod/src/v8.0.0/preset-safe/index.ts new file mode 100644 index 000000000000..92c7cb70ec21 --- /dev/null +++ b/packages/x-codemod/src/v8.0.0/preset-safe/index.ts @@ -0,0 +1,10 @@ +import transformTreeView from '../tree-view/preset-safe'; +import transformCharts from '../charts/preset-safe'; +import { JsCodeShiftAPI, JsCodeShiftFileInfo } from '../../types'; + +export default function transformer(file: JsCodeShiftFileInfo, api: JsCodeShiftAPI, options: any) { + file.source = transformTreeView(file, api, options); + file.source = transformCharts(file, api, options); + + return file.source; +} diff --git a/packages/x-codemod/src/v8.0.0/preset-safe/preset-safe.test.ts b/packages/x-codemod/src/v8.0.0/preset-safe/preset-safe.test.ts new file mode 100644 index 000000000000..b0ea5e858c7a --- /dev/null +++ b/packages/x-codemod/src/v8.0.0/preset-safe/preset-safe.test.ts @@ -0,0 +1,27 @@ +import path from 'path'; +import { expect } from 'chai'; +import jscodeshift from 'jscodeshift'; +import transform from '.'; +import readFile from '../../util/readFile'; + +function read(fileName) { + return readFile(path.join(__dirname, fileName)); +} + +describe('v8.0.0', () => { + describe('preset-safe', () => { + it('transforms code as needed', () => { + const actual = transform({ source: read('./actual.spec.js') }, { jscodeshift }, {}); + + const expected = read('./expected.spec.js'); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + + it('should be idempotent', () => { + const actual = transform({ source: read('./expected.spec.js') }, { jscodeshift }, {}); + + const expected = read('./expected.spec.js'); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + }); +}); diff --git a/packages/x-codemod/src/v8.0.0/tree-view/preset-safe/actual.spec.tsx b/packages/x-codemod/src/v8.0.0/tree-view/preset-safe/actual.spec.tsx new file mode 100644 index 000000000000..4b5b1a751562 --- /dev/null +++ b/packages/x-codemod/src/v8.0.0/tree-view/preset-safe/actual.spec.tsx @@ -0,0 +1,11 @@ +// @ts-nocheck +import * as React from 'react'; +import { TreeItem2 } from '@mui/x-tree-view/TreeItem2'; +import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView'; + +const className = treeViewClasses.root; + +// prettier-ignore + + +; diff --git a/packages/x-codemod/src/v8.0.0/tree-view/preset-safe/expected.spec.tsx b/packages/x-codemod/src/v8.0.0/tree-view/preset-safe/expected.spec.tsx new file mode 100644 index 000000000000..4a5aa4e135b9 --- /dev/null +++ b/packages/x-codemod/src/v8.0.0/tree-view/preset-safe/expected.spec.tsx @@ -0,0 +1,11 @@ +// @ts-nocheck +import * as React from 'react'; +import { TreeItem } from '@mui/x-tree-view/TreeItem'; +import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView'; + +const className = treeViewClasses.root; + +// prettier-ignore + + +; diff --git a/packages/x-codemod/src/v8.0.0/tree-view/preset-safe/index.ts b/packages/x-codemod/src/v8.0.0/tree-view/preset-safe/index.ts new file mode 100644 index 000000000000..d94e0b16c030 --- /dev/null +++ b/packages/x-codemod/src/v8.0.0/tree-view/preset-safe/index.ts @@ -0,0 +1,9 @@ +import transformRenameTreeItem2 from '../rename-tree-item-2'; + +import { JsCodeShiftAPI, JsCodeShiftFileInfo } from '../../../types'; + +export default function transformer(file: JsCodeShiftFileInfo, api: JsCodeShiftAPI, options: any) { + file.source = transformRenameTreeItem2(file, api, options); + + return file.source; +} diff --git a/packages/x-codemod/src/v8.0.0/tree-view/preset-safe/preset-safe.test.ts b/packages/x-codemod/src/v8.0.0/tree-view/preset-safe/preset-safe.test.ts new file mode 100644 index 000000000000..7f61d9c0e721 --- /dev/null +++ b/packages/x-codemod/src/v8.0.0/tree-view/preset-safe/preset-safe.test.ts @@ -0,0 +1,41 @@ +import path from 'path'; +import { expect } from 'chai'; +import jscodeshift from 'jscodeshift'; +import transform from './index'; +import readFile from '../../../util/readFile'; + +function read(fileName) { + return readFile(path.join(__dirname, fileName)); +} + +describe('v8.0.0/tree-view', () => { + describe('preset-safe', () => { + it('transforms code as needed', () => { + const actual = transform( + { + source: read('./actual.spec.tsx'), + path: require.resolve('./actual.spec.tsx'), + }, + { jscodeshift: jscodeshift.withParser('tsx') }, + {}, + ); + + const expected = read('./expected.spec.tsx'); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + + it('should be idempotent for expression', () => { + const actual = transform( + { + source: read('./expected.spec.tsx'), + path: require.resolve('./expected.spec.tsx'), + }, + { jscodeshift: jscodeshift.withParser('tsx') }, + {}, + ); + + const expected = read('./expected.spec.tsx'); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + }); +}); diff --git a/packages/x-codemod/src/v8.0.0/tree-view/rename-tree-item-2/actual-community-nested-imports.spec.tsx b/packages/x-codemod/src/v8.0.0/tree-view/rename-tree-item-2/actual-community-nested-imports.spec.tsx new file mode 100644 index 000000000000..48001cc74bf5 --- /dev/null +++ b/packages/x-codemod/src/v8.0.0/tree-view/rename-tree-item-2/actual-community-nested-imports.spec.tsx @@ -0,0 +1,94 @@ +// @ts-nocheck +import * as React from 'react'; +import { + TreeItem2, + TreeItem2Root, + TreeItem2Content, + TreeItem2IconContainer, + TreeItem2GroupTransition, + TreeItem2Checkbox, + TreeItem2Label, + TreeItem2Props, + TreeItem2Slots, + TreeItem2SlotProps, +} from '@mui/x-tree-view/TreeItem2'; +import { + useTreeItem2, + unstable_useTreeItem2 as useAliasedTreeItem, + UseTreeItem2Parameters, + UseTreeItem2ReturnValue, + UseTreeItem2Status, + UseTreeItem2RootSlotOwnProps, + UseTreeItem2ContentSlotOwnProps, + UseTreeItem2LabelInputSlotOwnProps, + UseTreeItem2LabelSlotOwnProps, + UseTreeItem2CheckboxSlotOwnProps, + UseTreeItem2IconContainerSlotOwnProps, + UseTreeItem2GroupTransitionSlotOwnProps, + UseTreeItem2DragAndDropOverlaySlotOwnProps, +} from '@mui/x-tree-view/useTreeItem2'; +import { useTreeItem2Utils } from '@mui/x-tree-view/hooks'; +import { + TreeItem2Provider, + TreeItem2ProviderProps, + FakeImportToForcePrettierNewLine, +} from '@mui/x-tree-view/TreeItem2Provider'; +import { + TreeItem2Icon, + TreeItem2IconProps, + TreeItem2IconSlots, + TreeItem2IconSlotProps, +} from '@mui/x-tree-view/TreeItem2Icon'; +import { + TreeItem2DragAndDropOverlay, + TreeItem2DragAndDropOverlayProps, +} from '@mui/x-tree-view/TreeItem2DragAndDropOverlay'; +import { + TreeItem2LabelInput, + TreeItem2LabelInputProps, + FakeImport2ToForcePrettierNewLine, +} from '@mui/x-tree-view/TreeItem2LabelInput'; + +// prettier-ignore +function App() { + useTreeItem2({}); + useAliasedTreeItem({}); + useTreeItem2Utils(); + + const treeItemProps: TreeItem2Props = {}; + const treeItemSlots: TreeItem2Slots = {}; + const treeItemSlotProps: TreeItem2SlotProps = {}; + + const params: UseTreeItem2Parameters = {}; + const returnValue: UseTreeItem2ReturnValue = {}; + const status: UseTreeItem2Status = {}; + const root: UseTreeItem2RootSlotOwnProps = {}; + const content: UseTreeItem2ContentSlotOwnProps = {}; + const labelInput: UseTreeItem2LabelInputSlotOwnProps = {}; + const label: UseTreeItem2LabelSlotOwnProps = {}; + const checkbox: UseTreeItem2CheckboxSlotOwnProps = {}; + const iconContainer: UseTreeItem2IconContainerSlotOwnProps = {}; + const groupTransition: UseTreeItem2GroupTransitionSlotOwnProps = {}; + const dragAndDropOverlay: UseTreeItem2DragAndDropOverlaySlotOwnProps = {}; + + const treeItemProviderProps: TreeItem2ProviderProps = {}; + const treeItemIconProps: TreeItem2IconProps = {}; + const treeItemDragAndDropOverlayProps: TreeItem2DragAndDropOverlayProps = {}; + const treeItemLabelInputProps: TreeItem2LabelInputProps = {}; + + return ( + + + + + + + + + + + + + + ); +} diff --git a/packages/x-codemod/src/v8.0.0/tree-view/rename-tree-item-2/actual-community-root-imports.spec.tsx b/packages/x-codemod/src/v8.0.0/tree-view/rename-tree-item-2/actual-community-root-imports.spec.tsx new file mode 100644 index 000000000000..9b5484ad5f45 --- /dev/null +++ b/packages/x-codemod/src/v8.0.0/tree-view/rename-tree-item-2/actual-community-root-imports.spec.tsx @@ -0,0 +1,83 @@ +/* eslint-disable no-restricted-imports */ +// @ts-nocheck +import * as React from 'react'; +import { + TreeItem2, + TreeItem2Root, + TreeItem2Content, + TreeItem2IconContainer, + TreeItem2GroupTransition, + TreeItem2Checkbox, + TreeItem2Label, + TreeItem2Props, + TreeItem2Slots, + TreeItem2SlotProps, + useTreeItem2, + unstable_useTreeItem2 as useAliasedTreeItem, + UseTreeItem2Parameters, + UseTreeItem2ReturnValue, + UseTreeItem2Status, + UseTreeItem2RootSlotOwnProps, + UseTreeItem2ContentSlotOwnProps, + UseTreeItem2LabelInputSlotOwnProps, + UseTreeItem2LabelSlotOwnProps, + UseTreeItem2CheckboxSlotOwnProps, + UseTreeItem2IconContainerSlotOwnProps, + UseTreeItem2GroupTransitionSlotOwnProps, + UseTreeItem2DragAndDropOverlaySlotOwnProps, + useTreeItem2Utils, + TreeItem2Provider, + TreeItem2ProviderProps, + TreeItem2Icon, + TreeItem2IconProps, + TreeItem2IconSlots, + TreeItem2IconSlotProps, + TreeItem2DragAndDropOverlay, + TreeItem2DragAndDropOverlayProps, + TreeItem2LabelInput, + TreeItem2LabelInputProps, +} from '@mui/x-tree-view'; + +// prettier-ignore +function App() { + useTreeItem2({}); + useAliasedTreeItem({}); + useTreeItem2Utils(); + + const treeItemProps: TreeItem2Props = {}; + const treeItemSlots: TreeItem2Slots = {}; + const treeItemSlotProps: TreeItem2SlotProps = {}; + + const params: UseTreeItem2Parameters = {}; + const returnValue: UseTreeItem2ReturnValue = {}; + const status: UseTreeItem2Status = {}; + const root: UseTreeItem2RootSlotOwnProps = {}; + const content: UseTreeItem2ContentSlotOwnProps = {}; + const labelInput: UseTreeItem2LabelInputSlotOwnProps = {}; + const label: UseTreeItem2LabelSlotOwnProps = {}; + const checkbox: UseTreeItem2CheckboxSlotOwnProps = {}; + const iconContainer: UseTreeItem2IconContainerSlotOwnProps = {}; + const groupTransition: UseTreeItem2GroupTransitionSlotOwnProps = {}; + const dragAndDropOverlay: UseTreeItem2DragAndDropOverlaySlotOwnProps = {}; + + const treeItemProviderProps: TreeItem2ProviderProps = {}; + const treeItemIconProps: TreeItem2IconProps = {}; + const treeItemDragAndDropOverlayProps: TreeItem2DragAndDropOverlayProps = {}; + const treeItemLabelInputProps: TreeItem2LabelInputProps = {}; + + return ( + + + + + + + + + + + + + + ); +} diff --git a/packages/x-codemod/src/v8.0.0/tree-view/rename-tree-item-2/actual-pro-root-imports.spec.tsx b/packages/x-codemod/src/v8.0.0/tree-view/rename-tree-item-2/actual-pro-root-imports.spec.tsx new file mode 100644 index 000000000000..46275e564461 --- /dev/null +++ b/packages/x-codemod/src/v8.0.0/tree-view/rename-tree-item-2/actual-pro-root-imports.spec.tsx @@ -0,0 +1,83 @@ +/* eslint-disable no-restricted-imports */ +// @ts-nocheck +import * as React from 'react'; +import { + TreeItem2, + TreeItem2Root, + TreeItem2Content, + TreeItem2IconContainer, + TreeItem2GroupTransition, + TreeItem2Checkbox, + TreeItem2Label, + TreeItem2Props, + TreeItem2Slots, + TreeItem2SlotProps, + useTreeItem2, + unstable_useTreeItem2 as useAliasedTreeItem, + UseTreeItem2Parameters, + UseTreeItem2ReturnValue, + UseTreeItem2Status, + UseTreeItem2RootSlotOwnProps, + UseTreeItem2ContentSlotOwnProps, + UseTreeItem2LabelInputSlotOwnProps, + UseTreeItem2LabelSlotOwnProps, + UseTreeItem2CheckboxSlotOwnProps, + UseTreeItem2IconContainerSlotOwnProps, + UseTreeItem2GroupTransitionSlotOwnProps, + UseTreeItem2DragAndDropOverlaySlotOwnProps, + useTreeItem2Utils, + TreeItem2Provider, + TreeItem2ProviderProps, + TreeItem2Icon, + TreeItem2IconProps, + TreeItem2IconSlots, + TreeItem2IconSlotProps, + TreeItem2DragAndDropOverlay, + TreeItem2DragAndDropOverlayProps, + TreeItem2LabelInput, + TreeItem2LabelInputProps, +} from '@mui/x-tree-view-pro'; + +// prettier-ignore +function App() { + useTreeItem2({}); + useAliasedTreeItem({}); + useTreeItem2Utils(); + + const treeItemProps: TreeItem2Props = {}; + const treeItemSlots: TreeItem2Slots = {}; + const treeItemSlotProps: TreeItem2SlotProps = {}; + + const params: UseTreeItem2Parameters = {}; + const returnValue: UseTreeItem2ReturnValue = {}; + const status: UseTreeItem2Status = {}; + const root: UseTreeItem2RootSlotOwnProps = {}; + const content: UseTreeItem2ContentSlotOwnProps = {}; + const labelInput: UseTreeItem2LabelInputSlotOwnProps = {}; + const label: UseTreeItem2LabelSlotOwnProps = {}; + const checkbox: UseTreeItem2CheckboxSlotOwnProps = {}; + const iconContainer: UseTreeItem2IconContainerSlotOwnProps = {}; + const groupTransition: UseTreeItem2GroupTransitionSlotOwnProps = {}; + const dragAndDropOverlay: UseTreeItem2DragAndDropOverlaySlotOwnProps = {}; + + const treeItemProviderProps: TreeItem2ProviderProps = {}; + const treeItemIconProps: TreeItem2IconProps = {}; + const treeItemDragAndDropOverlayProps: TreeItem2DragAndDropOverlayProps = {}; + const treeItemLabelInputProps: TreeItem2LabelInputProps = {}; + + return ( + + + + + + + + + + + + + + ); +} diff --git a/packages/x-codemod/src/v8.0.0/tree-view/rename-tree-item-2/expected-community-nested-imports.spec.tsx b/packages/x-codemod/src/v8.0.0/tree-view/rename-tree-item-2/expected-community-nested-imports.spec.tsx new file mode 100644 index 000000000000..b3f4a9d62063 --- /dev/null +++ b/packages/x-codemod/src/v8.0.0/tree-view/rename-tree-item-2/expected-community-nested-imports.spec.tsx @@ -0,0 +1,94 @@ +// @ts-nocheck +import * as React from 'react'; +import { + TreeItem, + TreeItemRoot, + TreeItemContent, + TreeItemIconContainer, + TreeItemGroupTransition, + TreeItemCheckbox, + TreeItemLabel, + TreeItemProps, + TreeItemSlots, + TreeItemSlotProps, +} from '@mui/x-tree-view/TreeItem'; +import { + useTreeItem, + useTreeItem as useAliasedTreeItem, + UseTreeItemParameters, + UseTreeItemReturnValue, + UseTreeItemStatus, + UseTreeItemRootSlotOwnProps, + UseTreeItemContentSlotOwnProps, + UseTreeItemLabelInputSlotOwnProps, + UseTreeItemLabelSlotOwnProps, + UseTreeItemCheckboxSlotOwnProps, + UseTreeItemIconContainerSlotOwnProps, + UseTreeItemGroupTransitionSlotOwnProps, + UseTreeItemDragAndDropOverlaySlotOwnProps, +} from '@mui/x-tree-view/useTreeItem'; +import { useTreeItemUtils } from '@mui/x-tree-view/hooks'; +import { + TreeItemProvider, + TreeItemProviderProps, + FakeImportToForcePrettierNewLine, +} from '@mui/x-tree-view/TreeItemProvider'; +import { + TreeItemIcon, + TreeItemIconProps, + TreeItemIconSlots, + TreeItemIconSlotProps, +} from '@mui/x-tree-view/TreeItemIcon'; +import { + TreeItemDragAndDropOverlay, + TreeItemDragAndDropOverlayProps, +} from '@mui/x-tree-view/TreeItemDragAndDropOverlay'; +import { + TreeItemLabelInput, + TreeItemLabelInputProps, + FakeImport2ToForcePrettierNewLine, +} from '@mui/x-tree-view/TreeItemLabelInput'; + +// prettier-ignore +function App() { + useTreeItem({}); + useAliasedTreeItem({}); + useTreeItemUtils(); + + const treeItemProps: TreeItemProps = {}; + const treeItemSlots: TreeItemSlots = {}; + const treeItemSlotProps: TreeItemSlotProps = {}; + + const params: UseTreeItemParameters = {}; + const returnValue: UseTreeItemReturnValue = {}; + const status: UseTreeItemStatus = {}; + const root: UseTreeItemRootSlotOwnProps = {}; + const content: UseTreeItemContentSlotOwnProps = {}; + const labelInput: UseTreeItemLabelInputSlotOwnProps = {}; + const label: UseTreeItemLabelSlotOwnProps = {}; + const checkbox: UseTreeItemCheckboxSlotOwnProps = {}; + const iconContainer: UseTreeItemIconContainerSlotOwnProps = {}; + const groupTransition: UseTreeItemGroupTransitionSlotOwnProps = {}; + const dragAndDropOverlay: UseTreeItemDragAndDropOverlaySlotOwnProps = {}; + + const treeItemProviderProps: TreeItemProviderProps = {}; + const treeItemIconProps: TreeItemIconProps = {}; + const treeItemDragAndDropOverlayProps: TreeItemDragAndDropOverlayProps = {}; + const treeItemLabelInputProps: TreeItemLabelInputProps = {}; + + return ( + ( + + + + + + + + + + + + ) + ); +} diff --git a/packages/x-codemod/src/v8.0.0/tree-view/rename-tree-item-2/expected-community-root-imports.spec.tsx b/packages/x-codemod/src/v8.0.0/tree-view/rename-tree-item-2/expected-community-root-imports.spec.tsx new file mode 100644 index 000000000000..864d5e1a5c40 --- /dev/null +++ b/packages/x-codemod/src/v8.0.0/tree-view/rename-tree-item-2/expected-community-root-imports.spec.tsx @@ -0,0 +1,83 @@ +/* eslint-disable no-restricted-imports */ +// @ts-nocheck +import * as React from 'react'; +import { + TreeItem, + TreeItemRoot, + TreeItemContent, + TreeItemIconContainer, + TreeItemGroupTransition, + TreeItemCheckbox, + TreeItemLabel, + TreeItemProps, + TreeItemSlots, + TreeItemSlotProps, + useTreeItem, + useTreeItem as useAliasedTreeItem, + UseTreeItemParameters, + UseTreeItemReturnValue, + UseTreeItemStatus, + UseTreeItemRootSlotOwnProps, + UseTreeItemContentSlotOwnProps, + UseTreeItemLabelInputSlotOwnProps, + UseTreeItemLabelSlotOwnProps, + UseTreeItemCheckboxSlotOwnProps, + UseTreeItemIconContainerSlotOwnProps, + UseTreeItemGroupTransitionSlotOwnProps, + UseTreeItemDragAndDropOverlaySlotOwnProps, + useTreeItemUtils, + TreeItemProvider, + TreeItemProviderProps, + TreeItemIcon, + TreeItemIconProps, + TreeItemIconSlots, + TreeItemIconSlotProps, + TreeItemDragAndDropOverlay, + TreeItemDragAndDropOverlayProps, + TreeItemLabelInput, + TreeItemLabelInputProps, +} from '@mui/x-tree-view'; + +// prettier-ignore +function App() { + useTreeItem({}); + useAliasedTreeItem({}); + useTreeItemUtils(); + + const treeItemProps: TreeItemProps = {}; + const treeItemSlots: TreeItemSlots = {}; + const treeItemSlotProps: TreeItemSlotProps = {}; + + const params: UseTreeItemParameters = {}; + const returnValue: UseTreeItemReturnValue = {}; + const status: UseTreeItemStatus = {}; + const root: UseTreeItemRootSlotOwnProps = {}; + const content: UseTreeItemContentSlotOwnProps = {}; + const labelInput: UseTreeItemLabelInputSlotOwnProps = {}; + const label: UseTreeItemLabelSlotOwnProps = {}; + const checkbox: UseTreeItemCheckboxSlotOwnProps = {}; + const iconContainer: UseTreeItemIconContainerSlotOwnProps = {}; + const groupTransition: UseTreeItemGroupTransitionSlotOwnProps = {}; + const dragAndDropOverlay: UseTreeItemDragAndDropOverlaySlotOwnProps = {}; + + const treeItemProviderProps: TreeItemProviderProps = {}; + const treeItemIconProps: TreeItemIconProps = {}; + const treeItemDragAndDropOverlayProps: TreeItemDragAndDropOverlayProps = {}; + const treeItemLabelInputProps: TreeItemLabelInputProps = {}; + + return ( + ( + + + + + + + + + + + + ) + ); +} diff --git a/packages/x-codemod/src/v8.0.0/tree-view/rename-tree-item-2/expected-pro-root-imports.spec.tsx b/packages/x-codemod/src/v8.0.0/tree-view/rename-tree-item-2/expected-pro-root-imports.spec.tsx new file mode 100644 index 000000000000..a05a8d97ba11 --- /dev/null +++ b/packages/x-codemod/src/v8.0.0/tree-view/rename-tree-item-2/expected-pro-root-imports.spec.tsx @@ -0,0 +1,83 @@ +/* eslint-disable no-restricted-imports */ +// @ts-nocheck +import * as React from 'react'; +import { + TreeItem, + TreeItemRoot, + TreeItemContent, + TreeItemIconContainer, + TreeItemGroupTransition, + TreeItemCheckbox, + TreeItemLabel, + TreeItemProps, + TreeItemSlots, + TreeItemSlotProps, + useTreeItem, + useTreeItem as useAliasedTreeItem, + UseTreeItemParameters, + UseTreeItemReturnValue, + UseTreeItemStatus, + UseTreeItemRootSlotOwnProps, + UseTreeItemContentSlotOwnProps, + UseTreeItemLabelInputSlotOwnProps, + UseTreeItemLabelSlotOwnProps, + UseTreeItemCheckboxSlotOwnProps, + UseTreeItemIconContainerSlotOwnProps, + UseTreeItemGroupTransitionSlotOwnProps, + UseTreeItemDragAndDropOverlaySlotOwnProps, + useTreeItemUtils, + TreeItemProvider, + TreeItemProviderProps, + TreeItemIcon, + TreeItemIconProps, + TreeItemIconSlots, + TreeItemIconSlotProps, + TreeItemDragAndDropOverlay, + TreeItemDragAndDropOverlayProps, + TreeItemLabelInput, + TreeItemLabelInputProps, +} from '@mui/x-tree-view-pro'; + +// prettier-ignore +function App() { + useTreeItem({}); + useAliasedTreeItem({}); + useTreeItemUtils(); + + const treeItemProps: TreeItemProps = {}; + const treeItemSlots: TreeItemSlots = {}; + const treeItemSlotProps: TreeItemSlotProps = {}; + + const params: UseTreeItemParameters = {}; + const returnValue: UseTreeItemReturnValue = {}; + const status: UseTreeItemStatus = {}; + const root: UseTreeItemRootSlotOwnProps = {}; + const content: UseTreeItemContentSlotOwnProps = {}; + const labelInput: UseTreeItemLabelInputSlotOwnProps = {}; + const label: UseTreeItemLabelSlotOwnProps = {}; + const checkbox: UseTreeItemCheckboxSlotOwnProps = {}; + const iconContainer: UseTreeItemIconContainerSlotOwnProps = {}; + const groupTransition: UseTreeItemGroupTransitionSlotOwnProps = {}; + const dragAndDropOverlay: UseTreeItemDragAndDropOverlaySlotOwnProps = {}; + + const treeItemProviderProps: TreeItemProviderProps = {}; + const treeItemIconProps: TreeItemIconProps = {}; + const treeItemDragAndDropOverlayProps: TreeItemDragAndDropOverlayProps = {}; + const treeItemLabelInputProps: TreeItemLabelInputProps = {}; + + return ( + ( + + + + + + + + + + + + ) + ); +} diff --git a/packages/x-codemod/src/v8.0.0/tree-view/rename-tree-item-2/index.ts b/packages/x-codemod/src/v8.0.0/tree-view/rename-tree-item-2/index.ts new file mode 100644 index 000000000000..fcc1d0b10b12 --- /dev/null +++ b/packages/x-codemod/src/v8.0.0/tree-view/rename-tree-item-2/index.ts @@ -0,0 +1,98 @@ +import type { JsCodeShiftAPI, JsCodeShiftFileInfo } from '../../../types'; +import { renameImports } from '../../../util/renameImports'; + +export default function transformer(file: JsCodeShiftFileInfo, api: JsCodeShiftAPI, options: any) { + const j = api.jscodeshift; + const root = j(file.source); + + const printOptions = options.printOptions || { + quote: 'single', + trailingComma: true, + wrapColumn: 40, + }; + + renameImports({ + j, + root, + packageNames: ['@mui/x-tree-view', '@mui/x-tree-view-pro'], + imports: [ + { + oldEndpoint: 'TreeItem2', + newEndpoint: 'TreeItem', + importsMapping: { + TreeItem2: 'TreeItem', + TreeItem2Root: 'TreeItemRoot', + TreeItem2Content: 'TreeItemContent', + TreeItem2IconContainer: 'TreeItemIconContainer', + TreeItem2GroupTransition: 'TreeItemGroupTransition', + TreeItem2Checkbox: 'TreeItemCheckbox', + TreeItem2Label: 'TreeItemLabel', + TreeItem2Props: 'TreeItemProps', + TreeItem2Slots: 'TreeItemSlots', + TreeItem2SlotProps: 'TreeItemSlotProps', + }, + }, + { + oldEndpoint: 'useTreeItem2', + newEndpoint: 'useTreeItem', + importsMapping: { + useTreeItem2: 'useTreeItem', + unstable_useTreeItem2: 'useTreeItem', + UseTreeItem2Parameters: 'UseTreeItemParameters', + UseTreeItem2ReturnValue: 'UseTreeItemReturnValue', + UseTreeItem2Status: 'UseTreeItemStatus', + UseTreeItem2RootSlotOwnProps: 'UseTreeItemRootSlotOwnProps', + UseTreeItem2ContentSlotOwnProps: 'UseTreeItemContentSlotOwnProps', + UseTreeItem2LabelInputSlotOwnProps: 'UseTreeItemLabelInputSlotOwnProps', + UseTreeItem2LabelSlotOwnProps: 'UseTreeItemLabelSlotOwnProps', + UseTreeItem2CheckboxSlotOwnProps: 'UseTreeItemCheckboxSlotOwnProps', + UseTreeItem2IconContainerSlotOwnProps: 'UseTreeItemIconContainerSlotOwnProps', + UseTreeItem2GroupTransitionSlotOwnProps: 'UseTreeItemGroupTransitionSlotOwnProps', + UseTreeItem2DragAndDropOverlaySlotOwnProps: 'UseTreeItemDragAndDropOverlaySlotOwnProps', + }, + }, + { + oldEndpoint: 'TreeItem2Provider', + newEndpoint: 'TreeItemProvider', + importsMapping: { + TreeItem2Provider: 'TreeItemProvider', + TreeItem2ProviderProps: 'TreeItemProviderProps', + }, + }, + { + oldEndpoint: 'TreeItem2Icon', + newEndpoint: 'TreeItemIcon', + importsMapping: { + TreeItem2Icon: 'TreeItemIcon', + TreeItem2IconProps: 'TreeItemIconProps', + TreeItem2IconSlots: 'TreeItemIconSlots', + TreeItem2IconSlotProps: 'TreeItemIconSlotProps', + }, + }, + { + oldEndpoint: 'TreeItem2DragAndDropOverlay', + newEndpoint: 'TreeItemDragAndDropOverlay', + importsMapping: { + TreeItem2DragAndDropOverlay: 'TreeItemDragAndDropOverlay', + TreeItem2DragAndDropOverlayProps: 'TreeItemDragAndDropOverlayProps', + }, + }, + { + oldEndpoint: 'TreeItem2LabelInput', + newEndpoint: 'TreeItemLabelInput', + importsMapping: { + TreeItem2LabelInput: 'TreeItemLabelInput', + TreeItem2LabelInputProps: 'TreeItemLabelInputProps', + }, + }, + { + oldEndpoint: 'hooks', + importsMapping: { + useTreeItem2Utils: 'useTreeItemUtils', + }, + }, + ], + }); + + return root.toSource(printOptions); +} diff --git a/packages/x-codemod/src/v8.0.0/tree-view/rename-tree-item-2/rename-tree-item-2.test.ts b/packages/x-codemod/src/v8.0.0/tree-view/rename-tree-item-2/rename-tree-item-2.test.ts new file mode 100644 index 000000000000..d91b9e1456b5 --- /dev/null +++ b/packages/x-codemod/src/v8.0.0/tree-view/rename-tree-item-2/rename-tree-item-2.test.ts @@ -0,0 +1,44 @@ +import path from 'path'; +import { expect } from 'chai'; +import jscodeshift from 'jscodeshift'; +import transform from '.'; +import readFile from '../../../util/readFile'; + +function read(fileName) { + return readFile(path.join(__dirname, fileName)); +} + +const TEST_FILES = ['community-nested-imports', 'community-root-imports', 'pro-root-imports']; + +describe('v7.0.0/tree-view', () => { + describe('rename-tree-item-2', () => { + TEST_FILES.forEach((testFile) => { + const actualPath = `./actual-${testFile}.spec.tsx`; + const expectedPath = `./expected-${testFile}.spec.tsx`; + + describe(`${testFile.replace(/-/g, ' ')}`, () => { + it('transforms imports as needed', () => { + const actual = transform( + { source: read(actualPath) }, + { jscodeshift: jscodeshift.withParser('tsx') }, + {}, + ); + + const expected = read(expectedPath); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + + it('should be idempotent', () => { + const actual = transform( + { source: read(expectedPath) }, + { jscodeshift: jscodeshift.withParser('tsx') }, + {}, + ); + + const expected = read(expectedPath); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + }); + }); + }); +}); diff --git a/packages/x-data-grid-generator/package.json b/packages/x-data-grid-generator/package.json index 6835a7437993..45bb125c6f14 100644 --- a/packages/x-data-grid-generator/package.json +++ b/packages/x-data-grid-generator/package.json @@ -1,6 +1,6 @@ { "name": "@mui/x-data-grid-generator", - "version": "7.22.1", + "version": "7.21.0", "description": "Generate fake data for demo purposes only.", "author": "MUI Team", "main": "src/index.ts", @@ -33,7 +33,7 @@ "directory": "packages/x-data-grid-generator" }, "dependencies": { - "@babel/runtime": "^7.25.7", + "@babel/runtime": "^7.26.0", "@mui/x-data-grid-premium": "workspace:*", "chance": "^1.1.12", "clsx": "^2.1.1", diff --git a/packages/x-data-grid-premium/package.json b/packages/x-data-grid-premium/package.json index 628dbaea45d5..a4b728197627 100644 --- a/packages/x-data-grid-premium/package.json +++ b/packages/x-data-grid-premium/package.json @@ -1,6 +1,6 @@ { "name": "@mui/x-data-grid-premium", - "version": "7.22.1", + "version": "7.21.0", "description": "The Premium plan edition of the Data Grid Components (MUI X).", "author": "MUI Team", "main": "src/index.ts", @@ -43,7 +43,7 @@ "directory": "packages/x-data-grid-premium" }, "dependencies": { - "@babel/runtime": "^7.25.7", + "@babel/runtime": "^7.26.0", "@mui/utils": "^5.16.6 || ^6.0.0", "@mui/x-data-grid": "workspace:*", "@mui/x-data-grid-pro": "workspace:*", @@ -72,7 +72,7 @@ } }, "devDependencies": { - "@mui/internal-test-utils": "^1.0.17", + "@mui/internal-test-utils": "^1.0.19", "@mui/material": "^5.16.7", "@mui/system": "^5.16.7", "@types/prop-types": "^15.7.13", diff --git a/packages/x-data-grid-premium/src/components/GridColumnMenuAggregationItem.tsx b/packages/x-data-grid-premium/src/components/GridColumnMenuAggregationItem.tsx index f2976b011913..27fd029bb344 100644 --- a/packages/x-data-grid-premium/src/components/GridColumnMenuAggregationItem.tsx +++ b/packages/x-data-grid-premium/src/components/GridColumnMenuAggregationItem.tsx @@ -1,13 +1,11 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import { GridColumnMenuItemProps, useGridSelector } from '@mui/x-data-grid-pro'; -import MenuItem from '@mui/material/MenuItem'; import ListItemIcon from '@mui/material/ListItemIcon'; import ListItemText from '@mui/material/ListItemText'; import FormControl from '@mui/material/FormControl'; import InputLabel from '@mui/material/InputLabel'; import { unstable_useId as useId } from '@mui/utils'; -import Select, { SelectChangeEvent } from '@mui/material/Select'; import { useGridApiContext } from '../hooks/utils/useGridApiContext'; import { useGridRootProps } from '../hooks/utils/useGridRootProps'; import { @@ -53,8 +51,8 @@ function GridColumnMenuAggregationItem(props: GridColumnMenuItemProps) { return ''; }, [rootProps.aggregationFunctions, aggregationModel, colDef]); - const handleAggregationItemChange = (event: SelectChangeEvent) => { - const newAggregationItem = event.target?.value || undefined; + const handleAggregationItemChange = (event: Event) => { + const newAggregationItem = (event.target as HTMLSelectElement | null)?.value || undefined; const currentModel = gridAggregationModelSelector(apiRef); const { [colDef.field]: columnItem, ...otherColumnItems } = currentModel; const newModel: GridAggregationModel = @@ -69,26 +67,26 @@ function GridColumnMenuAggregationItem(props: GridColumnMenuItemProps) { const label = apiRef.current.getLocaleText('aggregationMenuItemHeader'); return ( - + {label} - + - + ); } diff --git a/packages/x-data-grid-premium/src/components/GridColumnMenuRowGroupItem.tsx b/packages/x-data-grid-premium/src/components/GridColumnMenuRowGroupItem.tsx index 0cc989571312..7f661095f957 100644 --- a/packages/x-data-grid-premium/src/components/GridColumnMenuRowGroupItem.tsx +++ b/packages/x-data-grid-premium/src/components/GridColumnMenuRowGroupItem.tsx @@ -1,5 +1,4 @@ import * as React from 'react'; -import MenuItem from '@mui/material/MenuItem'; import ListItemIcon from '@mui/material/ListItemIcon'; import ListItemText from '@mui/material/ListItemText'; import { @@ -32,12 +31,16 @@ export function GridColumnMenuRowGroupItem(props: GridColumnMenuItemProps) { const groupedColumn = columnsLookup[field]; const name = groupedColumn.headerName ?? field; return ( - + {apiRef.current.getLocaleText('unGroupColumn')(name)} - + ); }; diff --git a/packages/x-data-grid-premium/src/components/GridColumnMenuRowUngroupItem.tsx b/packages/x-data-grid-premium/src/components/GridColumnMenuRowUngroupItem.tsx index 48a8e21f85ff..9f100470d0b6 100644 --- a/packages/x-data-grid-premium/src/components/GridColumnMenuRowUngroupItem.tsx +++ b/packages/x-data-grid-premium/src/components/GridColumnMenuRowUngroupItem.tsx @@ -1,5 +1,4 @@ import * as React from 'react'; -import MenuItem from '@mui/material/MenuItem'; import ListItemIcon from '@mui/material/ListItemIcon'; import ListItemText from '@mui/material/ListItemText'; import { @@ -36,21 +35,21 @@ export function GridColumnMenuRowUngroupItem(props: GridColumnMenuItemProps) { if (rowGroupingModel.includes(colDef.field)) { return ( - + {apiRef.current.getLocaleText('unGroupColumn')(name)} - + ); } return ( - + {apiRef.current.getLocaleText('groupColumn')(name)} - + ); } diff --git a/packages/x-data-grid-premium/src/components/GridExcelExportMenuItem.tsx b/packages/x-data-grid-premium/src/components/GridExcelExportMenuItem.tsx index 37e265b9233b..a73c4619b3bf 100644 --- a/packages/x-data-grid-premium/src/components/GridExcelExportMenuItem.tsx +++ b/packages/x-data-grid-premium/src/components/GridExcelExportMenuItem.tsx @@ -1,18 +1,19 @@ import * as React from 'react'; import PropTypes from 'prop-types'; -import MenuItem from '@mui/material/MenuItem'; import { GridExportMenuItemProps } from '@mui/x-data-grid-pro'; import { useGridApiContext } from '../hooks/utils/useGridApiContext'; +import { useGridRootProps } from '../hooks/utils/useGridRootProps'; import { GridExcelExportOptions } from '../hooks/features/export'; export type GridExcelExportMenuItemProps = GridExportMenuItemProps; function GridExcelExportMenuItem(props: GridExcelExportMenuItemProps) { const apiRef = useGridApiContext(); + const rootProps = useGridRootProps(); const { hideMenu, options, ...other } = props; return ( - { apiRef.current.exportDataAsExcel(options); hideMenu?.(); @@ -20,7 +21,7 @@ function GridExcelExportMenuItem(props: GridExcelExportMenuItemProps) { {...other} > {apiRef.current.getLocaleText('toolbarExportExcel')} - + ); } diff --git a/packages/x-data-grid-premium/src/hooks/features/cellSelection/useGridCellSelection.ts b/packages/x-data-grid-premium/src/hooks/features/cellSelection/useGridCellSelection.ts index 634fbdad61b9..928b1cd11bfb 100644 --- a/packages/x-data-grid-premium/src/hooks/features/cellSelection/useGridCellSelection.ts +++ b/packages/x-data-grid-premium/src/hooks/features/cellSelection/useGridCellSelection.ts @@ -1,5 +1,6 @@ import * as React from 'react'; -import { ownerDocument, useEventCallback } from '@mui/material/utils'; +import ownerDocument from '@mui/utils/ownerDocument'; +import useEventCallback from '@mui/utils/useEventCallback'; import { GridPipeProcessor, GridStateInitializer, diff --git a/packages/x-data-grid-pro/package.json b/packages/x-data-grid-pro/package.json index d0dc42008f5d..ae699d6cc972 100644 --- a/packages/x-data-grid-pro/package.json +++ b/packages/x-data-grid-pro/package.json @@ -1,6 +1,6 @@ { "name": "@mui/x-data-grid-pro", - "version": "7.22.1", + "version": "7.21.0", "description": "The Pro plan edition of the Data Grid components (MUI X).", "author": "MUI Team", "main": "src/index.ts", @@ -43,7 +43,7 @@ "directory": "packages/x-data-grid-pro" }, "dependencies": { - "@babel/runtime": "^7.25.7", + "@babel/runtime": "^7.26.0", "@mui/utils": "^5.16.6 || ^6.0.0", "@mui/x-data-grid": "workspace:*", "@mui/x-internals": "workspace:*", @@ -70,7 +70,7 @@ } }, "devDependencies": { - "@mui/internal-test-utils": "^1.0.17", + "@mui/internal-test-utils": "^1.0.19", "@mui/material": "^5.16.7", "@mui/system": "^5.16.7", "@types/prop-types": "^15.7.13", diff --git a/packages/x-data-grid-pro/src/components/GridColumnMenuPinningItem.tsx b/packages/x-data-grid-pro/src/components/GridColumnMenuPinningItem.tsx index 0a07624dc306..89168d11fa8d 100644 --- a/packages/x-data-grid-pro/src/components/GridColumnMenuPinningItem.tsx +++ b/packages/x-data-grid-pro/src/components/GridColumnMenuPinningItem.tsx @@ -1,7 +1,6 @@ import * as React from 'react'; import { useRtl } from '@mui/system/RtlProvider'; import PropTypes from 'prop-types'; -import MenuItem from '@mui/material/MenuItem'; import ListItemIcon from '@mui/material/ListItemIcon'; import ListItemText from '@mui/material/ListItemText'; import { GridPinnedColumnPosition, GridColumnMenuItemProps } from '@mui/x-data-grid'; @@ -27,21 +26,21 @@ function GridColumnMenuPinningItem(props: GridColumnMenuItemProps) { onClick(event); }; const pinToLeftMenuItem = ( - + {apiRef.current.getLocaleText('pinToLeft')} - + ); const pinToRightMenuItem = ( - + {apiRef.current.getLocaleText('pinToRight')} - + ); if (!colDef) { @@ -62,16 +61,16 @@ function GridColumnMenuPinningItem(props: GridColumnMenuItemProps) { : rootProps.slots.columnMenuPinRightIcon; return ( - + {apiRef.current.getLocaleText(label)} - - + + {apiRef.current.getLocaleText('unpin')} - + ); } diff --git a/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenu.tsx b/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenu.tsx index 9c049130ee1a..c3fe31d4aea7 100644 --- a/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenu.tsx +++ b/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenu.tsx @@ -1,9 +1,8 @@ import * as React from 'react'; import PropTypes from 'prop-types'; -import MenuList from '@mui/material/MenuList'; -import MenuItem from '@mui/material/MenuItem'; import { unstable_capitalize as capitalize, HTMLElementType } from '@mui/utils'; import { + useGridRootProps, useGridApiContext, GridMenu, GridFilterOperator, @@ -33,6 +32,7 @@ function GridHeaderFilterMenu({ labelledBy, }: GridHeaderFilterMenuProps) { const apiRef = useGridApiContext(); + const rootProps = useGridRootProps(); const hideMenu = React.useCallback(() => { apiRef.current.hideHeaderFilterMenu(); @@ -56,7 +56,11 @@ function GridHeaderFilterMenu({ return ( - + {operators.map((op, i) => { const label = op?.headerLabel ?? @@ -65,7 +69,7 @@ function GridHeaderFilterMenu({ ); return ( - { applyFilterChanges({ ...item, operator: op.value }); hideMenu(); @@ -75,10 +79,10 @@ function GridHeaderFilterMenu({ key={`${field}-${op.value}`} > {label} - + ); })} - + ); } diff --git a/packages/x-data-grid/package.json b/packages/x-data-grid/package.json index c787d0fb6ca8..6e9ee4e5c28e 100644 --- a/packages/x-data-grid/package.json +++ b/packages/x-data-grid/package.json @@ -1,6 +1,6 @@ { "name": "@mui/x-data-grid", - "version": "7.22.1", + "version": "7.21.0", "description": "The Community plan edition of the Data Grid components (MUI X).", "author": "MUI Team", "main": "src/index.ts", @@ -47,7 +47,7 @@ "directory": "packages/x-data-grid" }, "dependencies": { - "@babel/runtime": "^7.25.7", + "@babel/runtime": "^7.26.0", "@mui/utils": "^5.16.6 || ^6.0.0", "@mui/x-internals": "workspace:*", "clsx": "^2.1.1", @@ -71,7 +71,7 @@ } }, "devDependencies": { - "@mui/internal-test-utils": "^1.0.17", + "@mui/internal-test-utils": "^1.0.19", "@mui/joy": "^5.0.0-beta.48", "@mui/material": "^5.16.7", "@mui/system": "^5.16.7", diff --git a/packages/x-data-grid/src/components/base/GridOverlays.tsx b/packages/x-data-grid/src/components/base/GridOverlays.tsx index 79baf162939d..b8b88d17eaa8 100644 --- a/packages/x-data-grid/src/components/base/GridOverlays.tsx +++ b/packages/x-data-grid/src/components/base/GridOverlays.tsx @@ -3,13 +3,12 @@ import PropTypes from 'prop-types'; import { styled } from '@mui/system'; import composeClasses from '@mui/utils/composeClasses'; import clsx from 'clsx'; +import { minimalContentHeight } from '../../hooks/features/rows/gridRowsUtils'; import { useGridSelector } from '../../hooks/utils/useGridSelector'; import { gridDimensionsSelector } from '../../hooks/features/dimensions'; import { GridOverlayType } from '../../hooks/features/overlays/useGridOverlays'; import { useGridApiContext } from '../../hooks/utils/useGridApiContext'; import { useGridRootProps } from '../../hooks/utils/useGridRootProps'; -import { useGridVisibleRows } from '../../hooks/utils/useGridVisibleRows'; -import { getMinimalContentHeight } from '../../hooks/features/rows/gridRowsUtils'; import { DataGridProcessedProps } from '../../models/props/DataGridProps'; import { getDataGridUtilityClass } from '../../constants/gridClasses'; import { GridLoadingOverlayVariant } from '../GridLoadingOverlay'; @@ -29,7 +28,7 @@ const GridOverlayWrapperRoot = styled('div', { loadingOverlayVariant !== 'skeleton' ? { position: 'sticky', // To stay in place while scrolling - top: 'var(--DataGrid-headersTotalHeight)', + top: 'var(--DataGrid-headersTotalHeight)', // TODO: take pinned rows into account left: 0, width: 0, // To stay above the content instead of shifting it down height: 0, // To stay above the content instead of shifting it down @@ -64,17 +63,18 @@ const useUtilityClasses = (ownerState: OwnerState) => { function GridOverlayWrapper(props: React.PropsWithChildren) { const apiRef = useGridApiContext(); const rootProps = useGridRootProps(); - const currentPage = useGridVisibleRows(apiRef, rootProps); const dimensions = useGridSelector(apiRef, gridDimensionsSelector); - let height: React.CSSProperties['height'] = + let height: React.CSSProperties['height'] = Math.max( dimensions.viewportOuterSize.height - - dimensions.topContainerHeight - - dimensions.bottomContainerHeight - - (dimensions.hasScrollX ? dimensions.scrollbarSize : 0); + dimensions.topContainerHeight - + dimensions.bottomContainerHeight - + (dimensions.hasScrollX ? dimensions.scrollbarSize : 0), + 0, + ); - if ((rootProps.autoHeight && currentPage.rows.length === 0) || height === 0) { - height = getMinimalContentHeight(apiRef); + if (height === 0) { + height = minimalContentHeight; } const classes = useUtilityClasses({ ...props, classes: rootProps.classes }); diff --git a/packages/x-data-grid/src/components/cell/GridActionsCell.tsx b/packages/x-data-grid/src/components/cell/GridActionsCell.tsx index 39c20b5c639e..5707b3939a5c 100644 --- a/packages/x-data-grid/src/components/cell/GridActionsCell.tsx +++ b/packages/x-data-grid/src/components/cell/GridActionsCell.tsx @@ -1,6 +1,5 @@ import * as React from 'react'; import PropTypes from 'prop-types'; -import MenuList from '@mui/material/MenuList'; import { useRtl } from '@mui/system/RtlProvider'; import { unstable_useId as useId } from '@mui/utils'; import { GridRenderCellParams } from '../../models/params/gridCellParams'; @@ -224,7 +223,7 @@ function GridActionsCell(props: GridActionsCellProps) { {menuButtons.length > 0 && ( - React.cloneElement(button, { key: index, closeMenu: hideMenu }), )} - + )}
diff --git a/packages/x-data-grid/src/components/cell/GridActionsCellItem.tsx b/packages/x-data-grid/src/components/cell/GridActionsCellItem.tsx index 3d39805c11f0..2c0edaec52bb 100644 --- a/packages/x-data-grid/src/components/cell/GridActionsCellItem.tsx +++ b/packages/x-data-grid/src/components/cell/GridActionsCellItem.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import { IconButtonProps } from '@mui/material/IconButton'; -import MenuItem, { MenuItemProps } from '@mui/material/MenuItem'; +import { MenuItemProps } from '@mui/material/MenuItem'; import ListItemIcon from '@mui/material/ListItemIcon'; import { useGridRootProps } from '../../hooks/utils/useGridRootProps'; @@ -70,10 +70,10 @@ const GridActionsCellItem = React.forwardRef + {icon && {icon}} {label} - + ); }, ); diff --git a/packages/x-data-grid/src/components/menu/columnMenu/menuItems/GridColumnMenuFilterItem.tsx b/packages/x-data-grid/src/components/menu/columnMenu/menuItems/GridColumnMenuFilterItem.tsx index d86f61e78098..f7db300a230c 100644 --- a/packages/x-data-grid/src/components/menu/columnMenu/menuItems/GridColumnMenuFilterItem.tsx +++ b/packages/x-data-grid/src/components/menu/columnMenu/menuItems/GridColumnMenuFilterItem.tsx @@ -1,6 +1,5 @@ import * as React from 'react'; import PropTypes from 'prop-types'; -import MenuItem from '@mui/material/MenuItem'; import ListItemIcon from '@mui/material/ListItemIcon'; import ListItemText from '@mui/material/ListItemText'; import { useGridApiContext } from '../../../../hooks/utils/useGridApiContext'; @@ -25,12 +24,12 @@ function GridColumnMenuFilterItem(props: GridColumnMenuItemProps) { } return ( - + {apiRef.current.getLocaleText('columnMenuFilter')} - + ); } diff --git a/packages/x-data-grid/src/components/menu/columnMenu/menuItems/GridColumnMenuHideItem.tsx b/packages/x-data-grid/src/components/menu/columnMenu/menuItems/GridColumnMenuHideItem.tsx index ce7660929312..f6594765ba05 100644 --- a/packages/x-data-grid/src/components/menu/columnMenu/menuItems/GridColumnMenuHideItem.tsx +++ b/packages/x-data-grid/src/components/menu/columnMenu/menuItems/GridColumnMenuHideItem.tsx @@ -1,6 +1,5 @@ import * as React from 'react'; import PropTypes from 'prop-types'; -import MenuItem from '@mui/material/MenuItem'; import ListItemIcon from '@mui/material/ListItemIcon'; import ListItemText from '@mui/material/ListItemText'; import { GridColumnMenuItemProps } from '../GridColumnMenuItemProps'; @@ -43,12 +42,12 @@ function GridColumnMenuHideItem(props: GridColumnMenuItemProps) { } return ( - + {apiRef.current.getLocaleText('columnMenuHideColumn')} - + ); } diff --git a/packages/x-data-grid/src/components/menu/columnMenu/menuItems/GridColumnMenuManageItem.tsx b/packages/x-data-grid/src/components/menu/columnMenu/menuItems/GridColumnMenuManageItem.tsx index 860751420dda..df95549cbf30 100644 --- a/packages/x-data-grid/src/components/menu/columnMenu/menuItems/GridColumnMenuManageItem.tsx +++ b/packages/x-data-grid/src/components/menu/columnMenu/menuItems/GridColumnMenuManageItem.tsx @@ -1,6 +1,5 @@ import * as React from 'react'; import PropTypes from 'prop-types'; -import MenuItem from '@mui/material/MenuItem'; import ListItemIcon from '@mui/material/ListItemIcon'; import ListItemText from '@mui/material/ListItemText'; import { GridPreferencePanelsValue } from '../../../../hooks/features/preferencesPanel/gridPreferencePanelsValue'; @@ -26,12 +25,12 @@ function GridColumnMenuManageItem(props: GridColumnMenuItemProps) { } return ( - + {apiRef.current.getLocaleText('columnMenuManageColumns')} - + ); } diff --git a/packages/x-data-grid/src/components/menu/columnMenu/menuItems/GridColumnMenuSortItem.tsx b/packages/x-data-grid/src/components/menu/columnMenu/menuItems/GridColumnMenuSortItem.tsx index de67a637774e..7ac4c77444da 100644 --- a/packages/x-data-grid/src/components/menu/columnMenu/menuItems/GridColumnMenuSortItem.tsx +++ b/packages/x-data-grid/src/components/menu/columnMenu/menuItems/GridColumnMenuSortItem.tsx @@ -1,6 +1,5 @@ import * as React from 'react'; import PropTypes from 'prop-types'; -import MenuItem from '@mui/material/MenuItem'; import ListItemIcon from '@mui/material/ListItemIcon'; import ListItemText from '@mui/material/ListItemText'; import { useGridSelector } from '../../../../hooks/utils/useGridSelector'; @@ -55,26 +54,26 @@ function GridColumnMenuSortItem(props: GridColumnMenuItemProps) { return ( {sortingOrder.includes('asc') && sortDirection !== 'asc' ? ( - + {getLabel('columnMenuSortAsc')} - + ) : null} {sortingOrder.includes('desc') && sortDirection !== 'desc' ? ( - + {getLabel('columnMenuSortDesc')} - + ) : null} {sortingOrder.includes(null) && sortDirection != null ? ( - + {apiRef.current.getLocaleText('columnMenuUnsort')} - + ) : null} ); diff --git a/packages/x-data-grid/src/components/toolbar/GridToolbarColumnsButton.tsx b/packages/x-data-grid/src/components/toolbar/GridToolbarColumnsButton.tsx index 67a176845fac..58feb8f10f10 100644 --- a/packages/x-data-grid/src/components/toolbar/GridToolbarColumnsButton.tsx +++ b/packages/x-data-grid/src/components/toolbar/GridToolbarColumnsButton.tsx @@ -1,8 +1,8 @@ import * as React from 'react'; import PropTypes from 'prop-types'; +import useId from '@mui/utils/useId'; import { ButtonProps } from '@mui/material/Button'; import { TooltipProps } from '@mui/material/Tooltip'; -import { unstable_useId as useId } from '@mui/material/utils'; import { useGridSelector } from '../../hooks/utils/useGridSelector'; import { gridPreferencePanelStateSelector } from '../../hooks/features/preferencesPanel/gridPreferencePanelSelector'; import { GridPreferencePanelsValue } from '../../hooks/features/preferencesPanel/gridPreferencePanelsValue'; diff --git a/packages/x-data-grid/src/components/toolbar/GridToolbarDensitySelector.tsx b/packages/x-data-grid/src/components/toolbar/GridToolbarDensitySelector.tsx index 5e185987fa16..d6c952c6f543 100644 --- a/packages/x-data-grid/src/components/toolbar/GridToolbarDensitySelector.tsx +++ b/packages/x-data-grid/src/components/toolbar/GridToolbarDensitySelector.tsx @@ -1,10 +1,8 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import { unstable_useId as useId, unstable_useForkRef as useForkRef } from '@mui/utils'; -import MenuList from '@mui/material/MenuList'; import { ButtonProps } from '@mui/material/Button'; import { TooltipProps } from '@mui/material/Tooltip'; -import MenuItem from '@mui/material/MenuItem'; import ListItemIcon from '@mui/material/ListItemIcon'; import { gridDensitySelector } from '../../hooks/features/density/densitySelector'; import { GridDensity } from '../../models/gridDensity'; @@ -97,14 +95,14 @@ const GridToolbarDensitySelector = React.forwardRef< } const densityElements = densityOptions.map((option, index) => ( - handleDensityUpdate(option.value)} selected={option.value === density} > {option.icon} {option.label} - + )); return ( @@ -137,7 +135,7 @@ const GridToolbarDensitySelector = React.forwardRef< onClose={handleDensitySelectorClose} position="bottom-start" > - {densityElements} - + ); diff --git a/packages/x-data-grid/src/components/toolbar/GridToolbarExport.tsx b/packages/x-data-grid/src/components/toolbar/GridToolbarExport.tsx index 7b3ee4453cf5..fada5a986636 100644 --- a/packages/x-data-grid/src/components/toolbar/GridToolbarExport.tsx +++ b/packages/x-data-grid/src/components/toolbar/GridToolbarExport.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import { ButtonProps } from '@mui/material/Button'; import { TooltipProps } from '@mui/material/Tooltip'; -import MenuItem from '@mui/material/MenuItem'; +import { useGridRootProps } from '../../hooks/utils/useGridRootProps'; import { useGridApiContext } from '../../hooks/utils/useGridApiContext'; import { GridCsvExportOptions, GridPrintExportOptions } from '../../models/gridExport'; import { GridToolbarExportContainer } from './GridToolbarExportContainer'; @@ -37,10 +37,11 @@ export interface GridToolbarExportProps { function GridCsvExportMenuItem(props: GridCsvExportMenuItemProps) { const apiRef = useGridApiContext(); + const rootProps = useGridRootProps(); const { hideMenu, options, ...other } = props; return ( - { apiRef.current.exportDataAsCsv(options); hideMenu?.(); @@ -48,7 +49,7 @@ function GridCsvExportMenuItem(props: GridCsvExportMenuItemProps) { {...other} > {apiRef.current.getLocaleText('toolbarExportCSV')} - + ); } @@ -75,10 +76,11 @@ GridCsvExportMenuItem.propTypes = { function GridPrintExportMenuItem(props: GridPrintExportMenuItemProps) { const apiRef = useGridApiContext(); + const rootProps = useGridRootProps(); const { hideMenu, options, ...other } = props; return ( - { apiRef.current.exportDataAsPrint(options); hideMenu?.(); @@ -86,7 +88,7 @@ function GridPrintExportMenuItem(props: GridPrintExportMenuItemProps) { {...other} > {apiRef.current.getLocaleText('toolbarExportPrint')} - + ); } diff --git a/packages/x-data-grid/src/components/toolbar/GridToolbarExportContainer.tsx b/packages/x-data-grid/src/components/toolbar/GridToolbarExportContainer.tsx index 2c00e4ba0b8b..df889bd02870 100644 --- a/packages/x-data-grid/src/components/toolbar/GridToolbarExportContainer.tsx +++ b/packages/x-data-grid/src/components/toolbar/GridToolbarExportContainer.tsx @@ -1,7 +1,6 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import { unstable_useId as useId, unstable_useForkRef as useForkRef } from '@mui/utils'; -import MenuList from '@mui/material/MenuList'; import { ButtonProps } from '@mui/material/Button'; import { TooltipProps } from '@mui/material/Tooltip'; import { isHideMenuKey } from '../../utils/keyboardUtils'; @@ -85,7 +84,7 @@ const GridToolbarExportContainer = React.forwardRef< onClose={handleMenuClose} position="bottom-start" > - (child, { hideMenu: handleMenuClose }); })} - + ); diff --git a/packages/x-data-grid/src/components/virtualization/GridVirtualScrollbar.tsx b/packages/x-data-grid/src/components/virtualization/GridVirtualScrollbar.tsx index 42b3fb00e8c7..ba3534bfbc79 100644 --- a/packages/x-data-grid/src/components/virtualization/GridVirtualScrollbar.tsx +++ b/packages/x-data-grid/src/components/virtualization/GridVirtualScrollbar.tsx @@ -94,7 +94,10 @@ const GridVirtualScrollbar = React.forwardRef { const scroller = apiRef.current.virtualScrollerRef.current!; - const scrollbar = scrollbarRef.current!; + const scrollbar = scrollbarRef.current; + if (!scrollbar) { + return; + } if (scroller[propertyScroll] === lastPosition.current) { return; @@ -114,7 +117,10 @@ const GridVirtualScrollbar = React.forwardRef { const scroller = apiRef.current.virtualScrollerRef.current!; - const scrollbar = scrollbarRef.current!; + const scrollbar = scrollbarRef.current; + if (!scrollbar) { + return; + } if (isLocked.current) { isLocked.current = false; diff --git a/packages/x-data-grid/src/hooks/features/rowSelection/useGridRowSelection.ts b/packages/x-data-grid/src/hooks/features/rowSelection/useGridRowSelection.ts index fb8b76b078a4..7fc8dd13d2cc 100644 --- a/packages/x-data-grid/src/hooks/features/rowSelection/useGridRowSelection.ts +++ b/packages/x-data-grid/src/hooks/features/rowSelection/useGridRowSelection.ts @@ -11,7 +11,11 @@ import { GridSignature, useGridApiEventHandler } from '../../utils/useGridApiEve import { useGridApiMethod } from '../../utils/useGridApiMethod'; import { useGridLogger } from '../../utils/useGridLogger'; import { useGridSelector } from '../../utils/useGridSelector'; -import { gridRowMaximumTreeDepthSelector, gridRowTreeSelector } from '../rows/gridRowsSelector'; +import { + gridRowsLookupSelector, + gridRowMaximumTreeDepthSelector, + gridRowTreeSelector, +} from '../rows/gridRowsSelector'; import { gridRowSelectionStateSelector, selectedGridRowsSelector, @@ -81,6 +85,7 @@ export const useGridRowSelection = ( | 'checkboxSelectionVisibleOnly' | 'pagination' | 'paginationMode' + | 'filterMode' | 'classes' | 'keepNonExistentRowsSelected' | 'rowSelection' @@ -332,6 +337,13 @@ export const useGridRowSelection = ( } else { newSelection = new Set(); } + const currentLookup = selectedIdsLookupSelector(apiRef); + if ( + newSelection.size === Object.keys(currentLookup).length && + Array.from(newSelection).every((id) => currentLookup[id] === id) + ) { + return; + } } else { newSelection = new Set(Object.values(selectedIdsLookupSelector(apiRef))); const addRow = (rowId: GridRowId) => { @@ -445,14 +457,22 @@ export const useGridRowSelection = ( return; } const currentSelection = gridRowSelectionStateSelector(apiRef.current.state); + const rowsLookup = gridRowsLookupSelector(apiRef); const filteredRowsLookup = gridFilteredRowsLookupSelector(apiRef); // We clone the existing object to avoid mutating the same object returned by the selector to others part of the project const selectionLookup = { ...selectedIdsLookupSelector(apiRef) }; + const isNonExistent = (id: GridRowId) => { + if (props.filterMode === 'server') { + return !rowsLookup[id]; + } + return filteredRowsLookup[id] !== true; + }; + let hasChanged = false; currentSelection.forEach((id: GridRowId) => { - if (filteredRowsLookup[id] !== true) { + if (isNonExistent(id)) { if (props.keepNonExistentRowsSelected) { return; } @@ -479,9 +499,17 @@ export const useGridRowSelection = ( } }); - if (hasChanged || (isNestedData && !sortModelUpdated)) { + // For nested data, on row tree updation (filtering, adding rows, etc.) when the selection is + // not empty, we need to re-run scanning of the tree to propagate the selection changes + // Example: A parent whose de-selected children are filtered out should now be selected + const shouldReapplyPropagation = + isNestedData && + props.rowSelectionPropagation?.parents && + Object.keys(selectionLookup).length > 0; + + if (hasChanged || (shouldReapplyPropagation && !sortModelUpdated)) { const newSelection = Object.values(selectionLookup); - if (isNestedData) { + if (shouldReapplyPropagation) { apiRef.current.selectRows(newSelection, true, true); } else { apiRef.current.setRowSelectionModel(newSelection); @@ -493,6 +521,7 @@ export const useGridRowSelection = ( isNestedData, props.rowSelectionPropagation?.parents, props.keepNonExistentRowsSelected, + props.filterMode, tree, ], ); diff --git a/packages/x-data-grid/src/hooks/features/rows/gridRowsUtils.ts b/packages/x-data-grid/src/hooks/features/rows/gridRowsUtils.ts index 5630a73d551d..86be1ee37647 100644 --- a/packages/x-data-grid/src/hooks/features/rows/gridRowsUtils.ts +++ b/packages/x-data-grid/src/hooks/features/rows/gridRowsUtils.ts @@ -25,7 +25,6 @@ import { GridRowsPartialUpdateAction, } from './gridRowsInterfaces'; import { gridPinnedRowsSelector } from './gridRowsSelector'; -import { gridDimensionsSelector } from '../dimensions/gridDimensionsSelectors'; export const GRID_ROOT_GROUP_ID: GridRowId = `auto-generated-group-node-root`; export const GRID_ID_AUTOGENERATED = Symbol('mui.id_autogenerated'); @@ -401,10 +400,7 @@ export function calculatePinnedRowsHeight(apiRef: React.MutableRefObject) { - const dimensions = gridDimensionsSelector(apiRef.current.state); - return `var(--DataGrid-overlayHeight, ${2 * dimensions.rowHeight}px)`; -} +export const minimalContentHeight = 'var(--DataGrid-overlayHeight, calc(var(--height) * 2))'; export function computeRowsUpdates( apiRef: React.MutableRefObject, 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 b5ae34dc7fc4..86435660917e 100644 --- a/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx +++ b/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx @@ -36,7 +36,6 @@ import type { import { selectedIdsLookupSelector } from '../rowSelection/gridRowSelectionSelector'; import { gridRowsMetaSelector } from '../rows/gridRowsMetaSelector'; import { getFirstNonSpannedColumnToRender } from '../columns/gridColumnsUtils'; -import { getMinimalContentHeight } from '../rows/gridRowsUtils'; import { GridRowProps } from '../../../components/GridRow'; import { GridInfiniteLoaderPrivateApi } from '../../../models/api/gridInfiniteLoaderApi'; import { @@ -47,6 +46,7 @@ import { import { EMPTY_RENDER_CONTEXT } from './useGridVirtualization'; import { gridRowSpanningHiddenCellsOriginMapSelector } from '../rows/gridRowSpanningSelectors'; import { gridListColumnSelector } from '../listView/gridListViewSelectors'; +import { minimalContentHeight } from '../rows/gridRowsUtils'; const MINIMUM_COLUMN_WIDTH = 50; @@ -538,19 +538,12 @@ export const useGridVirtualScroller = () => { flexShrink: 0, }; - if (rootProps.autoHeight && currentPage.rows.length === 0) { - size.flexBasis = getMinimalContentHeight(apiRef); // Give room to show the overlay when there no rows. + if (size.flexBasis === 0) { + size.flexBasis = minimalContentHeight; // Give room to show the overlay when there no rows. } return size; - }, [ - apiRef, - columnsTotalWidth, - contentHeight, - needsHorizontalScrollbar, - rootProps.autoHeight, - currentPage.rows.length, - ]); + }, [columnsTotalWidth, contentHeight, needsHorizontalScrollbar]); React.useEffect(() => { apiRef.current.publishEvent('virtualScrollerContentSizeChange'); diff --git a/packages/x-data-grid/src/locales/plPL.ts b/packages/x-data-grid/src/locales/plPL.ts index 07ea181044ea..af001de70617 100644 --- a/packages/x-data-grid/src/locales/plPL.ts +++ b/packages/x-data-grid/src/locales/plPL.ts @@ -38,10 +38,10 @@ const plPLGrid: Partial = { toolbarExportExcel: 'Pobierz jako plik Excel', // Columns management text - // columnsManagementSearchTitle: 'Search', - // columnsManagementNoColumns: 'No columns', - // columnsManagementShowHideAllText: 'Show/Hide All', - // columnsManagementReset: 'Reset', + columnsManagementSearchTitle: 'Szukaj', + columnsManagementNoColumns: 'Brak kolumn', + columnsManagementShowHideAllText: 'Wyświetl/Ukryj wszystkie', + columnsManagementReset: 'Resetuj', // Filter panel text filterPanelAddFilter: 'Dodaj filtr', @@ -57,9 +57,9 @@ const plPLGrid: Partial = { // Filter operators text filterOperatorContains: 'zawiera', - // filterOperatorDoesNotContain: 'does not contain', + filterOperatorDoesNotContain: 'nie zawiera', filterOperatorEquals: 'równa się', - // filterOperatorDoesNotEqual: 'does not equal', + filterOperatorDoesNotEqual: 'nie równa się', filterOperatorStartsWith: 'zaczyna się od', filterOperatorEndsWith: 'kończy się na', filterOperatorIs: 'równa się', @@ -80,26 +80,26 @@ const plPLGrid: Partial = { // Header filter operators text headerFilterOperatorContains: 'Zawiera', - // headerFilterOperatorDoesNotContain: 'Does not contain', + headerFilterOperatorDoesNotContain: 'Nie zawiera', headerFilterOperatorEquals: 'Równa się', - // headerFilterOperatorDoesNotEqual: 'Does not equal', + headerFilterOperatorDoesNotEqual: 'Nie równa się', headerFilterOperatorStartsWith: 'Zaczyna się od', headerFilterOperatorEndsWith: 'Kończy się na', - // headerFilterOperatorIs: 'Is', + headerFilterOperatorIs: 'Jest', headerFilterOperatorNot: 'Niepuste', - // headerFilterOperatorAfter: 'Is after', - // headerFilterOperatorOnOrAfter: 'Is on or after', - // headerFilterOperatorBefore: 'Is before', - // headerFilterOperatorOnOrBefore: 'Is on or before', - // headerFilterOperatorIsEmpty: 'Is empty', - // headerFilterOperatorIsNotEmpty: 'Is not empty', - // headerFilterOperatorIsAnyOf: 'Is any of', - // 'headerFilterOperator=': 'Equals', - // 'headerFilterOperator!=': 'Not equals', - // 'headerFilterOperator>': 'Greater than', - // 'headerFilterOperator>=': 'Greater than or equal to', - // 'headerFilterOperator<': 'Less than', - // 'headerFilterOperator<=': 'Less than or equal to', + headerFilterOperatorAfter: 'Jest po', + headerFilterOperatorOnOrAfter: 'Jest w lub po', + headerFilterOperatorBefore: 'Jest przed', + headerFilterOperatorOnOrBefore: 'Jest w lub przed', + headerFilterOperatorIsEmpty: 'Jest pusty', + headerFilterOperatorIsNotEmpty: 'Nie jest pusty', + headerFilterOperatorIsAnyOf: 'Is any of', + 'headerFilterOperator=': 'Równa się', + 'headerFilterOperator!=': 'Nie równa się', + 'headerFilterOperator>': 'Większy niż', + 'headerFilterOperator>=': 'Większy lub równy', + 'headerFilterOperator<': 'Mniejszy niż', + 'headerFilterOperator<=': 'Mniejszy lub równe', // Filter values text filterValueAny: 'dowolny', @@ -161,7 +161,7 @@ const plPLGrid: Partial = { unGroupColumn: (name) => `Rozgrupuj ${name}`, // Master/detail - // detailPanelToggle: 'Detail panel toggle', + detailPanelToggle: 'Szczegóły', expandDetailPanel: 'Rozwiń', collapseDetailPanel: 'Zwiń', @@ -169,7 +169,7 @@ const plPLGrid: Partial = { rowReorderingHeaderName: 'Porządkowanie wierszy', // Aggregation - // aggregationMenuItemHeader: 'Aggregation', + aggregationMenuItemHeader: 'Agregacja', // aggregationFunctionLabelSum: 'sum', // aggregationFunctionLabelAvg: 'avg', // aggregationFunctionLabelMin: 'min', diff --git a/packages/x-data-grid/src/material/index.ts b/packages/x-data-grid/src/material/index.ts index 5377891acffc..db2748de022c 100644 --- a/packages/x-data-grid/src/material/index.ts +++ b/packages/x-data-grid/src/material/index.ts @@ -1,6 +1,8 @@ import MUIBadge from '@mui/material/Badge'; import MUICheckbox from '@mui/material/Checkbox'; import MUIDivider from '@mui/material/Divider'; +import MUIMenuList from '@mui/material/MenuList'; +import MUIMenuItem from '@mui/material/MenuItem'; import MUITextField from '@mui/material/TextField'; import MUIFormControl from '@mui/material/FormControl'; import MUISelect from '@mui/material/Select'; @@ -86,6 +88,8 @@ const materialSlots: GridBaseSlots & GridIconSlotsComponent = { baseBadge: MUIBadge, baseCheckbox: MUICheckbox, baseDivider: MUIDivider, + baseMenuList: MUIMenuList, + baseMenuItem: MUIMenuItem, baseTextField: MUITextField, baseFormControl: MUIFormControl, baseSelect: MUISelect, diff --git a/packages/x-data-grid/src/models/gridSlotsComponent.ts b/packages/x-data-grid/src/models/gridSlotsComponent.ts index 51fc7ccac3b8..c9c38a0fe356 100644 --- a/packages/x-data-grid/src/models/gridSlotsComponent.ts +++ b/packages/x-data-grid/src/models/gridSlotsComponent.ts @@ -25,6 +25,16 @@ export interface GridBaseSlots { * @default Divider */ baseDivider: React.JSXElementConstructor; + /** + * The custom MenuList component used in the grid. + * @default MenuList + */ + baseMenuList: React.JSXElementConstructor; + /** + * The custom MenuItem component used in the grid. + * @default MenuItem + */ + baseMenuItem: React.JSXElementConstructor; /** * The custom InputAdornment component used in the grid. * @default InputAdornment diff --git a/packages/x-data-grid/src/models/gridSlotsComponentsProps.ts b/packages/x-data-grid/src/models/gridSlotsComponentsProps.ts index fb3a00c76088..8b709b41a55b 100644 --- a/packages/x-data-grid/src/models/gridSlotsComponentsProps.ts +++ b/packages/x-data-grid/src/models/gridSlotsComponentsProps.ts @@ -1,6 +1,8 @@ import * as React from 'react'; import type { BadgeProps } from '@mui/material/Badge'; import type { CheckboxProps } from '@mui/material/Checkbox'; +import type { MenuListProps } from '@mui/material/MenuList'; +import type { MenuItemProps } from '@mui/material/MenuItem'; import type { TextFieldProps } from '@mui/material/TextField'; import type { FormControlProps } from '@mui/material/FormControl'; import type { SelectProps } from '@mui/material/Select'; @@ -38,6 +40,8 @@ type DividerProps = {}; export interface BaseBadgePropsOverrides {} export interface BaseCheckboxPropsOverrides {} export interface BaseDividerPropsOverrides {} +export interface BaseMenuListPropsOverrides {} +export interface BaseMenuItemPropsOverrides {} export interface BaseTextFieldPropsOverrides {} export interface BaseFormControlPropsOverrides {} export interface BaseSelectPropsOverrides {} @@ -74,6 +78,8 @@ export interface GridSlotProps { baseBadge: BadgeProps & BaseBadgePropsOverrides; baseCheckbox: CheckboxProps & BaseCheckboxPropsOverrides; baseDivider: DividerProps & BaseDividerPropsOverrides; + baseMenuList: MenuListProps & BaseMenuListPropsOverrides; + baseMenuItem: MenuItemProps & BaseMenuItemPropsOverrides; baseTextField: TextFieldProps & BaseTextFieldPropsOverrides; baseFormControl: FormControlProps & BaseFormControlPropsOverrides; baseSelect: SelectProps & BaseSelectPropsOverrides; diff --git a/packages/x-date-pickers-pro/package.json b/packages/x-date-pickers-pro/package.json index 4a6021a3a989..3a6790f31f02 100644 --- a/packages/x-date-pickers-pro/package.json +++ b/packages/x-date-pickers-pro/package.json @@ -1,6 +1,6 @@ { "name": "@mui/x-date-pickers-pro", - "version": "7.22.1", + "version": "7.21.0", "description": "The Pro plan edition of the Date and Time Picker components (MUI X).", "author": "MUI Team", "main": "src/index.ts", @@ -42,7 +42,7 @@ "directory": "packages/x-date-pickers-pro" }, "dependencies": { - "@babel/runtime": "^7.25.7", + "@babel/runtime": "^7.26.0", "@mui/utils": "^5.16.6 || ^6.0.0", "@mui/x-date-pickers": "workspace:*", "@mui/x-internals": "workspace:*", @@ -96,7 +96,7 @@ } }, "devDependencies": { - "@mui/internal-test-utils": "^1.0.17", + "@mui/internal-test-utils": "^1.0.19", "@mui/material": "^5.16.7", "@mui/system": "^5.16.7", "@types/luxon": "^3.4.2", diff --git a/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.tsx b/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.tsx index e41859e4304f..0e7a18a2e7af 100644 --- a/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.tsx +++ b/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.tsx @@ -25,6 +25,7 @@ import { DEFAULT_DESKTOP_MODE_MEDIA_QUERY, useControlledValueWithTimezone, useViews, + PickerRangeValue, } from '@mui/x-date-pickers/internals'; import { warnOnce } from '@mui/x-internals/warning'; import { PickerValidDate } from '@mui/x-date-pickers/models'; @@ -45,7 +46,7 @@ import { isWithinRange, } from '../internals/utils/date-utils'; import { calculateRangeChange, calculateRangePreview } from '../internals/utils/date-range-manager'; -import { DateRange, RangePosition } from '../models'; +import { RangePosition } from '../models'; import { DateRangePickerDay, dateRangePickerDayClasses as dayClasses } from '../DateRangePickerDay'; import { rangeValueManager } from '../internals/utils/valueManagers'; import { useDragRange } from './useDragRange'; @@ -62,7 +63,7 @@ const DateRangeCalendarRoot = styled('div', { name: 'MuiDateRangeCalendar', slot: 'Root', overridesResolver: (_, styles) => styles.root, -})<{ ownerState: DateRangeCalendarOwnerState }>({ +})<{ ownerState: DateRangeCalendarOwnerState }>({ display: 'flex', flexDirection: 'row', }); @@ -103,12 +104,12 @@ const InnerDayCalendarForRange = styled(DayCalendar)(({ theme }) => ({ const DayCalendarForRange = InnerDayCalendarForRange as typeof DayCalendar; -function useDateRangeCalendarDefaultizedProps( - props: DateRangeCalendarProps, +function useDateRangeCalendarDefaultizedProps( + props: DateRangeCalendarProps, name: string, -): DateRangeCalendarDefaultizedProps { - const utils = useUtils(); - const defaultDates = useDefaultDates(); +): DateRangeCalendarDefaultizedProps { + const utils = useUtils(); + const defaultDates = useDefaultDates(); const defaultReduceAnimations = useDefaultReduceAnimations(); const themeProps = useThemeProps({ props, @@ -133,7 +134,7 @@ function useDateRangeCalendarDefaultizedProps( }; } -const useUtilityClasses = (ownerState: DateRangeCalendarOwnerState) => { +const useUtilityClasses = (ownerState: DateRangeCalendarOwnerState) => { const { classes, isDragging } = ownerState; const slots = { root: ['root'], @@ -144,8 +145,8 @@ const useUtilityClasses = (ownerState: DateRangeCalendarOwnerState) => { return composeClasses(slots, getDateRangeCalendarUtilityClass, classes); }; -type DateRangeCalendarComponent = (( - props: DateRangeCalendarProps & React.RefAttributes, +type DateRangeCalendarComponent = (( + props: DateRangeCalendarProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; /** @@ -158,9 +159,10 @@ type DateRangeCalendarComponent = (( * * - [DateRangeCalendar API](https://mui.com/x/api/date-pickers/date-range-calendar/) */ -const DateRangeCalendar = React.forwardRef(function DateRangeCalendar< - TDate extends PickerValidDate, ->(inProps: DateRangeCalendarProps, ref: React.Ref) { +const DateRangeCalendar = React.forwardRef(function DateRangeCalendar( + inProps: DateRangeCalendarProps, + ref: React.Ref, +) { const props = useDateRangeCalendarDefaultizedProps(inProps, 'MuiDateRangeCalendar'); const shouldHavePreview = useMediaQuery(DEFAULT_DESKTOP_MODE_MEDIA_QUERY, { defaultMatches: false, @@ -208,8 +210,7 @@ const DateRangeCalendar = React.forwardRef(function DateRangeCalendar< } = props; const { value, handleValueChange, timezone } = useControlledValueWithTimezone< - TDate, - DateRange, + PickerRangeValue, NonNullable >({ name: 'DateRangeCalendar', @@ -229,8 +230,8 @@ const DateRangeCalendar = React.forwardRef(function DateRangeCalendar< autoFocus, }); - const utils = useUtils(); - const now = useNow(timezone); + const utils = useUtils(); + const now = useNow(timezone); const id = useId(); const { rangePosition, onRangePositionChange } = useRangePosition({ @@ -247,7 +248,7 @@ const DateRangeCalendar = React.forwardRef(function DateRangeCalendar< const handleSelectedDayChange = useEventCallback( ( - newDate: TDate | null, + newDate: PickerValidDate | null, selectionState: PickerSelectionState | undefined, allowRangeFlip: boolean = false, ) => { @@ -274,7 +275,7 @@ const DateRangeCalendar = React.forwardRef(function DateRangeCalendar< }, ); - const handleDrop = useEventCallback((newDate: TDate) => { + const handleDrop = useEventCallback((newDate: PickerValidDate) => { handleSelectedDayChange(newDate, undefined, true); }); @@ -282,7 +283,7 @@ const DateRangeCalendar = React.forwardRef(function DateRangeCalendar< // Range going for the start of the start day to the end of the end day. // This makes sure that `isWithinRange` works with any time in the start and end day. - const valueDayRange = React.useMemo>( + const valueDayRange = React.useMemo( () => [ value[0] == null || !utils.isValid(value[0]) ? value[0] : utils.startOfDay(value[0]), value[1] == null || !utils.isValid(value[1]) ? value[1] : utils.endOfDay(value[1]), @@ -302,7 +303,7 @@ const DateRangeCalendar = React.forwardRef(function DateRangeCalendar< const ownerState = { ...props, isDragging }; const classes = useUtilityClasses(ownerState); - const draggingRange = React.useMemo>(() => { + const draggingRange = React.useMemo(() => { if (!valueDayRange[0] || !valueDayRange[1] || !rangeDragDay) { return [null, null]; } @@ -323,7 +324,7 @@ const DateRangeCalendar = React.forwardRef(function DateRangeCalendar< return undefined; } - return (dayToTest: TDate) => + return (dayToTest: PickerValidDate) => shouldDisableDate(dayToTest, draggingDatePosition || rangePosition); }, [shouldDisableDate, rangePosition, draggingDatePosition]); @@ -333,7 +334,7 @@ const DateRangeCalendar = React.forwardRef(function DateRangeCalendar< changeMonth, handleChangeMonth, onMonthSwitchingAnimationEnd, - } = useCalendarState({ + } = useCalendarState({ value: value[0] || value[1], referenceDate, disableFuture, @@ -348,32 +349,30 @@ const DateRangeCalendar = React.forwardRef(function DateRangeCalendar< }); const CalendarHeader = slots?.calendarHeader ?? PickersRangeCalendarHeader; - const calendarHeaderProps: Omit< - PickersRangeCalendarHeaderProps, - 'month' | 'monthIndex' - > = useSlotProps({ - elementType: CalendarHeader, - externalSlotProps: slotProps?.calendarHeader, - additionalProps: { - calendars, - views: ['day'], - view: 'day', - currentMonth: calendarState.currentMonth, - onMonthChange: (newMonth, direction) => handleChangeMonth({ newMonth, direction }), - minDate, - maxDate, - disabled, - disablePast, - disableFuture, - reduceAnimations, - timezone, - slots, - slotProps, - }, - ownerState: props, - }); + const calendarHeaderProps: Omit = + useSlotProps({ + elementType: CalendarHeader, + externalSlotProps: slotProps?.calendarHeader, + additionalProps: { + calendars, + views: ['day'], + view: 'day', + currentMonth: calendarState.currentMonth, + onMonthChange: (newMonth, direction) => handleChangeMonth({ newMonth, direction }), + minDate, + maxDate, + disabled, + disablePast, + disableFuture, + reduceAnimations, + timezone, + slots, + slotProps, + }, + ownerState: props, + }); - const prevValue = React.useRef | null>(null); + const prevValue = React.useRef(null); React.useEffect(() => { const date = rangePosition === 'start' ? value[0] : value[1]; if (!date || !utils.isValid(date)) { @@ -408,7 +407,7 @@ const DateRangeCalendar = React.forwardRef(function DateRangeCalendar< } }, [rangePosition, value]); // eslint-disable-line - const baseDateValidationProps: Required> = { + const baseDateValidationProps: Required = { disablePast, disableFuture, maxDate, @@ -421,7 +420,7 @@ const DateRangeCalendar = React.forwardRef(function DateRangeCalendar< disabled, }; - const [rangePreviewDay, setRangePreviewDay] = React.useState(null); + const [rangePreviewDay, setRangePreviewDay] = React.useState(null); const CalendarTransitionProps = React.useMemo( () => ({ @@ -438,7 +437,7 @@ const DateRangeCalendar = React.forwardRef(function DateRangeCalendar< }); const handleDayMouseEnter = useEventCallback( - (event: React.MouseEvent, newPreviewRequest: TDate) => { + (event: React.MouseEvent, newPreviewRequest: PickerValidDate) => { if (!isWithinRange(utils, newPreviewRequest, valueDayRange)) { setRangePreviewDay(newPreviewRequest); } else { @@ -450,7 +449,7 @@ const DateRangeCalendar = React.forwardRef(function DateRangeCalendar< const slotsForDayCalendar = { day: DateRangePickerDay, ...slots, - } as DayCalendarSlots; + } as DayCalendarSlots; const slotPropsForDayCalendar = { ...slotProps, @@ -495,7 +494,7 @@ const DateRangeCalendar = React.forwardRef(function DateRangeCalendar< ...(resolveComponentProps(slotProps?.day, dayOwnerState) ?? {}), }; }, - } as DayCalendarSlotProps; + } as DayCalendarSlotProps; const calendarMonths = React.useMemo( () => Array.from({ length: calendars }).map((_, index) => index), @@ -556,13 +555,13 @@ const DateRangeCalendar = React.forwardRef(function DateRangeCalendar< return ( - + - + adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() + * @default (date: PickerValidDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() */ dayOfWeekFormatter: PropTypes.func, /** @@ -724,8 +723,7 @@ DateRangeCalendar.propTypes = { onFocusedViewChange: PropTypes.func, /** * Callback fired on month change. - * @template TDate - * @param {TDate} month The new month. + * @param {PickerValidDate} month The new month. */ onMonthChange: PropTypes.func, /** @@ -776,8 +774,7 @@ DateRangeCalendar.propTypes = { * * Warning: This function can be called multiple times (for example when rendering date calendar, checking if focus can be moved to a certain date, etc.). Expensive computations can impact performance. * - * @template TDate - * @param {TDate} day The date to test. + * @param {PickerValidDate} day The date to test. * @param {string} position The date to test, 'start' or 'end'. * @returns {boolean} Returns `true` if the date should be disabled. */ diff --git a/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.types.ts b/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.types.ts index ac56c4d44149..4bb144a7c0cb 100644 --- a/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.types.ts +++ b/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.types.ts @@ -2,6 +2,7 @@ import * as React from 'react'; import { SxProps } from '@mui/system'; import { SlotComponentProps } from '@mui/utils'; import { Theme } from '@mui/material/styles'; +import { DefaultizedProps } from '@mui/x-internals/types'; import { PickerValidDate, TimezoneProps } from '@mui/x-date-pickers/models'; import { PickersCalendarHeader, @@ -10,7 +11,6 @@ import { } from '@mui/x-date-pickers/PickersCalendarHeader'; import { BaseDateValidationProps, - DefaultizedProps, ExportedDayCalendarProps, DayCalendarSlots, DayCalendarSlotProps, @@ -18,52 +18,48 @@ import { PickersArrowSwitcherSlotProps, DayCalendarProps, ExportedUseViewsOptions, + PickerRangeValue, } from '@mui/x-date-pickers/internals'; -import { DayRangeValidationProps } from '../internals/models/dateRange'; -import { DateRange, RangePosition } from '../models'; +import { RangePosition } from '../models'; import { DateRangeCalendarClasses } from './dateRangeCalendarClasses'; import { DateRangePickerDay, DateRangePickerDayProps } from '../DateRangePickerDay'; import { UseRangePositionProps } from '../internals/hooks/useRangePosition'; import { PickersRangeCalendarHeaderProps } from '../PickersRangeCalendarHeader'; +import { ExportedValidateDateRangeProps } from '../validation/validateDateRange'; -export interface DateRangeCalendarSlots +export interface DateRangeCalendarSlots extends PickersArrowSwitcherSlots, - Omit, 'day'>, + Omit, PickersCalendarHeaderSlots { /** * Custom component for calendar header. * Check the [PickersCalendarHeader](https://mui.com/x/api/date-pickers/pickers-calendar-header/) component. * @default PickersCalendarHeader */ - calendarHeader?: React.ElementType>; + calendarHeader?: React.ElementType; /** * Custom component for day in range pickers. * Check the [DateRangePickersDay](https://mui.com/x/api/date-pickers/date-range-picker-day/) component. * @default DateRangePickersDay */ - day?: React.ElementType>; + day?: React.ElementType; } -export interface DateRangeCalendarSlotProps +export interface DateRangeCalendarSlotProps extends PickersArrowSwitcherSlotProps, - Omit, 'day'>, - PickersCalendarHeaderSlotProps { - calendarHeader?: SlotComponentProps< - typeof PickersCalendarHeader, - {}, - DateRangeCalendarProps - >; + Omit, + PickersCalendarHeaderSlotProps { + calendarHeader?: SlotComponentProps; day?: SlotComponentProps< typeof DateRangePickerDay, {}, - DayCalendarProps & { day: TDate; selected: boolean } + DayCalendarProps & { day: PickerValidDate; selected: boolean } >; } -export interface ExportedDateRangeCalendarProps - extends ExportedDayCalendarProps, - BaseDateValidationProps, - DayRangeValidationProps, +export interface ExportedDateRangeCalendarProps + extends ExportedDayCalendarProps, + ExportedValidateDateRangeProps, TimezoneProps { /** * If `true`, after selecting `start` date calendar will not automatically switch to the month of `end` date. @@ -87,10 +83,9 @@ export interface ExportedDateRangeCalendarProps reduceAnimations?: boolean; /** * Callback fired on month change. - * @template TDate - * @param {TDate} month The new month. + * @param {PickerValidDate} month The new month. */ - onMonthChange?: (month: TDate) => void; + onMonthChange?: (month: PickerValidDate) => void; /** * Position the current month is rendered in. * @default 1 @@ -103,25 +98,25 @@ export interface ExportedDateRangeCalendarProps disableDragEditing?: boolean; } -export interface DateRangeCalendarProps - extends ExportedDateRangeCalendarProps, +export interface DateRangeCalendarProps + extends ExportedDateRangeCalendarProps, UseRangePositionProps, - ExportedUseViewsOptions<'day'> { + ExportedUseViewsOptions { /** * The selected value. * Used when the component is controlled. */ - value?: DateRange; + value?: PickerRangeValue; /** * The default selected value. * Used when the component is not controlled. */ - defaultValue?: DateRange; + defaultValue?: PickerRangeValue; /** * The date used to generate the new value when both `value` and `defaultValue` are empty. * @default The closest valid date using the validation props, except callbacks such as `shouldDisableDate`. */ - referenceDate?: TDate; + referenceDate?: PickerValidDate; /** * The number of calendars to render. * @default 2 @@ -140,12 +135,12 @@ export interface DateRangeCalendarProps * Overridable component slots. * @default {} */ - slots?: DateRangeCalendarSlots; + slots?: DateRangeCalendarSlots; /** * The props used for each component slot. * @default {} */ - slotProps?: DateRangeCalendarSlotProps; + slotProps?: DateRangeCalendarSlotProps; /** * Range positions available for selection. * This list is checked against when checking if a next range position can be selected. @@ -156,18 +151,17 @@ export interface DateRangeCalendarProps availableRangePositions?: RangePosition[]; } -export interface DateRangeCalendarOwnerState - extends DateRangeCalendarProps { +export interface DateRangeCalendarOwnerState extends DateRangeCalendarProps { isDragging: boolean; } -export type DateRangeCalendarDefaultizedProps = DefaultizedProps< - DateRangeCalendarProps, +export type DateRangeCalendarDefaultizedProps = DefaultizedProps< + DateRangeCalendarProps, | 'views' | 'openTo' | 'reduceAnimations' | 'calendars' | 'disableDragEditing' | 'availableRangePositions' - | keyof BaseDateValidationProps + | keyof BaseDateValidationProps >; diff --git a/packages/x-date-pickers-pro/src/DateRangeCalendar/useDragRange.ts b/packages/x-date-pickers-pro/src/DateRangeCalendar/useDragRange.ts index 25db9f81dcb1..a25b6fe4f2bc 100644 --- a/packages/x-date-pickers-pro/src/DateRangeCalendar/useDragRange.ts +++ b/packages/x-date-pickers-pro/src/DateRangeCalendar/useDragRange.ts @@ -2,18 +2,19 @@ import * as React from 'react'; import useEventCallback from '@mui/utils/useEventCallback'; import { MuiPickersAdapter, PickersTimezone, PickerValidDate } from '@mui/x-date-pickers/models'; -import { DateRange, RangePosition } from '../models'; +import { PickerRangeValue } from '@mui/x-date-pickers/internals'; +import { RangePosition } from '../models'; import { isEndOfRange, isStartOfRange } from '../internals/utils/date-utils'; -interface UseDragRangeParams { +interface UseDragRangeParams { disableDragEditing?: boolean; - utils: MuiPickersAdapter; - setRangeDragDay: (value: TDate | null) => void; + utils: MuiPickersAdapter; + setRangeDragDay: (value: PickerValidDate | null) => void; setIsDragging: (value: boolean) => void; isDragging: boolean; onDatePositionChange: (position: RangePosition) => void; - onDrop: (newDate: TDate) => void; - dateRange: DateRange; + onDrop: (newDate: PickerValidDate) => void; + dateRange: PickerRangeValue; timezone: PickersTimezone; } @@ -29,15 +30,15 @@ interface UseDragRangeEvents { onTouchEnd?: React.TouchEventHandler; } -interface UseDragRangeResponse extends UseDragRangeEvents { +interface UseDragRangeResponse extends UseDragRangeEvents { isDragging: boolean; - rangeDragDay: TDate | null; + rangeDragDay: PickerValidDate | null; draggingDatePosition: RangePosition | null; } -const resolveDateFromTarget = ( +const resolveDateFromTarget = ( target: EventTarget, - utils: MuiPickersAdapter, + utils: MuiPickersAdapter, timezone: PickersTimezone, ) => { const timestampString = (target as HTMLElement).dataset.timestamp; @@ -87,7 +88,7 @@ const resolveElementFromTouch = ( return null; }; -const useDragRangeEvents = ({ +const useDragRangeEvents = ({ utils, setRangeDragDay, setIsDragging, @@ -97,7 +98,7 @@ const useDragRangeEvents = ({ disableDragEditing, dateRange, timezone, -}: UseDragRangeParams): UseDragRangeEvents => { +}: UseDragRangeParams): UseDragRangeEvents => { const emptyDragImgRef = React.useRef(null); React.useEffect(() => { // Preload the image - required for Safari support: https://stackoverflow.com/a/40923520/3303436 @@ -106,7 +107,7 @@ const useDragRangeEvents = ({ 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'; }, []); - const isElementDraggable = (day: TDate | null): day is TDate => { + const isElementDraggable = (day: PickerValidDate | null): day is PickerValidDate => { if (day == null) { return false; } @@ -276,7 +277,7 @@ const useDragRangeEvents = ({ }; }; -export const useDragRange = ({ +export const useDragRange = ({ disableDragEditing, utils, onDatePositionChange, @@ -284,15 +285,15 @@ export const useDragRange = ({ dateRange, timezone, }: Omit< - UseDragRangeParams, + UseDragRangeParams, 'setRangeDragDay' | 'setIsDragging' | 'isDragging' ->): UseDragRangeResponse => { +>): UseDragRangeResponse => { const [isDragging, setIsDragging] = React.useState(false); - const [rangeDragDay, setRangeDragDay] = React.useState(null); + const [rangeDragDay, setRangeDragDay] = React.useState(null); - const handleRangeDragDayChange = useEventCallback((val: TDate | null) => { - if (!utils.isEqual(val, rangeDragDay)) { - setRangeDragDay(val); + const handleRangeDragDayChange = useEventCallback((newValue: PickerValidDate | null) => { + if (!utils.isEqual(newValue, rangeDragDay)) { + setRangeDragDay(newValue); } }); diff --git a/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.test.tsx b/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.test.tsx index 2d6094f4db18..7aa94997646b 100644 --- a/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.test.tsx +++ b/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.test.tsx @@ -22,7 +22,7 @@ describe('', () => { }); it('should not open mobile picker dialog when clicked on input', () => { - // Test with v7 input + // Test with accessible DOM structure const { unmount } = renderWithProps({ enableAccessibleFieldDOMStructure: true }); fireEvent.click(getFieldInputRoot()); clock.runToLast(); @@ -32,7 +32,7 @@ describe('', () => { unmount(); - // Test with v6 input + // Test with non-accessible DOM structure renderWithProps({ enableAccessibleFieldDOMStructure: false }); fireEvent.click(screen.getAllByRole('textbox')[0]); clock.runToLast(); @@ -45,7 +45,7 @@ describe('', () => { const originalMatchMedia = window.matchMedia; window.matchMedia = stubMatchMedia(false); - render(); + render(); fireEvent.click(getFieldInputRoot()); clock.runToLast(); diff --git a/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.tsx b/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.tsx index c6a5c6e350c8..4c4ada8e4094 100644 --- a/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.tsx +++ b/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.tsx @@ -4,16 +4,12 @@ import PropTypes from 'prop-types'; import useMediaQuery from '@mui/material/useMediaQuery'; import { useThemeProps } from '@mui/material/styles'; import { refType } from '@mui/utils'; -import { PickerValidDate } from '@mui/x-date-pickers/models'; import { DesktopDateRangePicker } from '../DesktopDateRangePicker'; import { MobileDateRangePicker } from '../MobileDateRangePicker'; import { DateRangePickerProps } from './DateRangePicker.types'; -type DatePickerComponent = (< - TDate extends PickerValidDate, - TEnableAccessibleFieldDOMStructure extends boolean = false, ->( - props: DateRangePickerProps & +type DatePickerComponent = (( + props: DateRangePickerProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; @@ -28,10 +24,9 @@ type DatePickerComponent = (< * - [DateRangePicker API](https://mui.com/x/api/date-pickers/date-range-picker/) */ const DateRangePicker = React.forwardRef(function DateRangePicker< - TDate extends PickerValidDate, - TEnableAccessibleFieldDOMStructure extends boolean = false, + TEnableAccessibleFieldDOMStructure extends boolean = true, >( - inProps: DateRangePickerProps, + inProps: DateRangePickerProps, ref: React.Ref, ) { const props = useThemeProps({ props: inProps, name: 'MuiDateRangePicker' }); @@ -78,9 +73,9 @@ DateRangePicker.propTypes = { currentMonthCalendarPosition: PropTypes.oneOf([1, 2, 3]), /** * Formats the day of week displayed in the calendar header. - * @param {TDate} date The date of the day of week provided by the adapter. + * @param {PickerValidDate} date The date of the day of week provided by the adapter. * @returns {string} The name to display. - * @default (date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() + * @default (date: PickerValidDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() */ dayOfWeekFormatter: PropTypes.func, /** @@ -140,7 +135,7 @@ DateRangePicker.propTypes = { */ displayWeekNumber: PropTypes.bool, /** - * @default false + * @default true */ enableAccessibleFieldDOMStructure: PropTypes.any, /** @@ -228,8 +223,7 @@ DateRangePicker.propTypes = { onError: PropTypes.func, /** * Callback fired on month change. - * @template TDate - * @param {TDate} month The new month. + * @param {PickerValidDate} month The new month. */ onMonthChange: PropTypes.func, /** @@ -303,8 +297,7 @@ DateRangePicker.propTypes = { * * Warning: This function can be called multiple times (for example when rendering date calendar, checking if focus can be moved to a certain date, etc.). Expensive computations can impact performance. * - * @template TDate - * @param {TDate} day The date to test. + * @param {PickerValidDate} day The date to test. * @param {string} position The date to test, 'start' or 'end'. * @returns {boolean} Returns `true` if the date should be disabled. */ diff --git a/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.types.ts b/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.types.ts index cc56765af366..326c9b650e99 100644 --- a/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.types.ts +++ b/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.types.ts @@ -1,4 +1,6 @@ -import { PickerValidDate } from '@mui/x-date-pickers/models'; +import { MakeRequired } from '@mui/x-internals/types'; +import { BaseDateValidationProps, PickerRangeValue } from '@mui/x-date-pickers/internals'; +import { BaseSingleInputFieldProps } from '@mui/x-date-pickers/models'; import { DesktopDateRangePickerProps, DesktopDateRangePickerSlots, @@ -9,22 +11,19 @@ import { MobileDateRangePickerSlots, MobileDateRangePickerSlotProps, } from '../MobileDateRangePicker'; +import { DateRangeValidationError, RangeFieldSection, UseDateRangeFieldProps } from '../models'; -export interface DateRangePickerSlots - extends DesktopDateRangePickerSlots, - MobileDateRangePickerSlots {} +export interface DateRangePickerSlots + extends DesktopDateRangePickerSlots, + MobileDateRangePickerSlots {} -export interface DateRangePickerSlotProps< - TDate extends PickerValidDate, - TEnableAccessibleFieldDOMStructure extends boolean, -> extends DesktopDateRangePickerSlotProps, - MobileDateRangePickerSlotProps {} +export interface DateRangePickerSlotProps + extends DesktopDateRangePickerSlotProps, + MobileDateRangePickerSlotProps {} -export interface DateRangePickerProps< - TDate extends PickerValidDate, - TEnableAccessibleFieldDOMStructure extends boolean = false, -> extends DesktopDateRangePickerProps, - MobileDateRangePickerProps { +export interface DateRangePickerProps + extends DesktopDateRangePickerProps, + MobileDateRangePickerProps { /** * CSS media query when `Mobile` mode will be changed to `Desktop`. * @default '@media (pointer: fine)' @@ -35,10 +34,20 @@ export interface DateRangePickerProps< * Overridable component slots. * @default {} */ - slots?: DateRangePickerSlots; + slots?: DateRangePickerSlots; /** * The props used for each component slot. * @default {} */ - slotProps?: DateRangePickerSlotProps; + slotProps?: DateRangePickerSlotProps; } + +/** + * Props the field can receive when used inside a `DateRangePicker`, `DesktopDateRangePicker` or `MobileDateRangePicker` component. + */ +export type DateRangePickerFieldProps = + MakeRequired< + UseDateRangeFieldProps, + 'format' | 'timezone' | 'value' | keyof BaseDateValidationProps + > & + BaseSingleInputFieldProps; diff --git a/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePickerToolbar.tsx b/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePickerToolbar.tsx index a3b4ff70d6d6..8273067b4870 100644 --- a/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePickerToolbar.tsx +++ b/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePickerToolbar.tsx @@ -11,17 +11,16 @@ import { useUtils, BaseToolbarProps, ExportedBaseToolbarProps, + PickerRangeValue, } from '@mui/x-date-pickers/internals'; import { usePickersTranslations } from '@mui/x-date-pickers/hooks'; -import { PickerValidDate } from '@mui/x-date-pickers/models'; -import { DateRange } from '../models'; import { UseRangePositionResponse } from '../internals/hooks/useRangePosition'; import { DateRangePickerToolbarClasses, getDateRangePickerToolbarUtilityClass, } from './dateRangePickerToolbarClasses'; -const useUtilityClasses = (ownerState: DateRangePickerToolbarProps) => { +const useUtilityClasses = (ownerState: DateRangePickerToolbarProps) => { const { classes } = ownerState; const slots = { root: ['root'], @@ -31,9 +30,9 @@ const useUtilityClasses = (ownerState: DateRangePickerToolbarProps) => { return composeClasses(slots, getDateRangePickerToolbarUtilityClass, classes); }; -export interface DateRangePickerToolbarProps +export interface DateRangePickerToolbarProps extends ExportedDateRangePickerToolbarProps, - Omit, 'day'>, 'onChange' | 'isLandscape'>, + Omit, 'onChange' | 'isLandscape'>, Pick {} export interface ExportedDateRangePickerToolbarProps extends ExportedBaseToolbarProps { @@ -48,7 +47,7 @@ const DateRangePickerToolbarRoot = styled(PickersToolbar, { slot: 'Root', overridesResolver: (_, styles) => styles.root, })<{ - ownerState: DateRangePickerToolbarProps; + ownerState: DateRangePickerToolbarProps; }>({}); const DateRangePickerToolbarContainer = styled('div', { @@ -59,8 +58,8 @@ const DateRangePickerToolbarContainer = styled('div', { display: 'flex', }); -type DateRangePickerToolbarComponent = (( - props: DateRangePickerToolbarProps & React.RefAttributes, +type DateRangePickerToolbarComponent = (( + props: DateRangePickerToolbarProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; /** @@ -73,10 +72,11 @@ type DateRangePickerToolbarComponent = (( * * - [DateRangePickerToolbar API](https://mui.com/x/api/date-pickers/date-range-picker-toolbar/) */ -const DateRangePickerToolbar = React.forwardRef(function DateRangePickerToolbar< - TDate extends PickerValidDate, ->(inProps: DateRangePickerToolbarProps, ref: React.Ref) { - const utils = useUtils(); +const DateRangePickerToolbar = React.forwardRef(function DateRangePickerToolbar( + inProps: DateRangePickerToolbarProps, + ref: React.Ref, +) { + const utils = useUtils(); const props = useThemeProps({ props: inProps, name: 'MuiDateRangePickerToolbar' }); const { @@ -91,7 +91,7 @@ const DateRangePickerToolbar = React.forwardRef(function DateRangePickerToolbar< ...other } = props; - const translations = usePickersTranslations(); + const translations = usePickersTranslations(); const startDateValue = start ? utils.formatByString(start, toolbarFormat || utils.formats.shortDate) diff --git a/packages/x-date-pickers-pro/src/DateRangePicker/index.ts b/packages/x-date-pickers-pro/src/DateRangePicker/index.ts index 4f65679f8be2..561b96d1667c 100644 --- a/packages/x-date-pickers-pro/src/DateRangePicker/index.ts +++ b/packages/x-date-pickers-pro/src/DateRangePicker/index.ts @@ -3,6 +3,7 @@ export type { DateRangePickerProps, DateRangePickerSlots, DateRangePickerSlotProps, + DateRangePickerFieldProps, } from './DateRangePicker.types'; export { DateRangePickerToolbar } from './DateRangePickerToolbar'; diff --git a/packages/x-date-pickers-pro/src/DateRangePicker/shared.tsx b/packages/x-date-pickers-pro/src/DateRangePicker/shared.tsx index 36beb3a913bb..b098d57cfb0f 100644 --- a/packages/x-date-pickers-pro/src/DateRangePicker/shared.tsx +++ b/packages/x-date-pickers-pro/src/DateRangePicker/shared.tsx @@ -1,17 +1,17 @@ import * as React from 'react'; +import { DefaultizedProps } from '@mui/x-internals/types'; import { useThemeProps } from '@mui/material/styles'; import { LocalizedComponent, PickersInputLocaleText } from '@mui/x-date-pickers/locales'; import { - DefaultizedProps, useDefaultDates, useUtils, applyDefaultDate, BaseDateValidationProps, BasePickerInputProps, PickerViewRendererLookup, + PickerRangeValue, } from '@mui/x-date-pickers/internals'; -import { PickerValidDate } from '@mui/x-date-pickers/models'; -import { DateRangeValidationError, DateRange } from '../models'; +import { DateRangeValidationError } from '../models'; import { DateRangeCalendarSlots, DateRangeCalendarSlotProps, @@ -24,64 +24,59 @@ import { } from './DateRangePickerToolbar'; import { DateRangeViewRendererProps } from '../dateRangeViewRenderers'; -export interface BaseDateRangePickerSlots - extends DateRangeCalendarSlots { +export interface BaseDateRangePickerSlots extends DateRangeCalendarSlots { /** * Custom component for the toolbar rendered above the views. * @default DateTimePickerToolbar */ - toolbar?: React.JSXElementConstructor>; + toolbar?: React.JSXElementConstructor; } -export interface BaseDateRangePickerSlotProps - extends DateRangeCalendarSlotProps { +export interface BaseDateRangePickerSlotProps extends DateRangeCalendarSlotProps { toolbar?: ExportedDateRangePickerToolbarProps; } -export interface BaseDateRangePickerProps +export interface BaseDateRangePickerProps extends Omit< - BasePickerInputProps, TDate, 'day', DateRangeValidationError>, + BasePickerInputProps, 'view' | 'views' | 'openTo' | 'onViewChange' | 'orientation' >, - ExportedDateRangeCalendarProps, - BaseDateValidationProps { + ExportedDateRangeCalendarProps { /** * Overridable component slots. * @default {} */ - slots?: BaseDateRangePickerSlots; + slots?: BaseDateRangePickerSlots; /** * The props used for each component slot. * @default {} */ - slotProps?: BaseDateRangePickerSlotProps; + slotProps?: BaseDateRangePickerSlotProps; /** * Define custom view renderers for each section. * If `null`, the section will only have field editing. * If `undefined`, internally defined view will be used. */ viewRenderers?: Partial< - PickerViewRendererLookup, 'day', DateRangeViewRendererProps, {}> + PickerViewRendererLookup, {}> >; } -type UseDateRangePickerDefaultizedProps< - TDate extends PickerValidDate, - Props extends BaseDateRangePickerProps, -> = LocalizedComponent>>; +type UseDateRangePickerDefaultizedProps = + LocalizedComponent>; -export function useDateRangePickerDefaultizedProps< - TDate extends PickerValidDate, - Props extends BaseDateRangePickerProps, ->(props: Props, name: string): UseDateRangePickerDefaultizedProps { - const utils = useUtils(); - const defaultDates = useDefaultDates(); +export function useDateRangePickerDefaultizedProps( + props: Props, + name: string, +): UseDateRangePickerDefaultizedProps { + const utils = useUtils(); + const defaultDates = useDefaultDates(); const themeProps = useThemeProps({ props, name, }); - const localeText = React.useMemo | undefined>(() => { + const localeText = React.useMemo(() => { if (themeProps.localeText?.toolbarTitle == null) { return themeProps.localeText; } diff --git a/packages/x-date-pickers-pro/src/DateRangePickerDay/DateRangePickerDay.tsx b/packages/x-date-pickers-pro/src/DateRangePickerDay/DateRangePickerDay.tsx index f5ee14896d79..76de35070d63 100644 --- a/packages/x-date-pickers-pro/src/DateRangePickerDay/DateRangePickerDay.tsx +++ b/packages/x-date-pickers-pro/src/DateRangePickerDay/DateRangePickerDay.tsx @@ -6,7 +6,6 @@ import { useLicenseVerifier } from '@mui/x-license'; import { alpha, styled, useThemeProps } from '@mui/material/styles'; import composeClasses from '@mui/utils/composeClasses'; import { useUtils } from '@mui/x-date-pickers/internals'; -import { PickerValidDate } from '@mui/x-date-pickers/models'; import { PickersDay, PickersDayProps } from '@mui/x-date-pickers/PickersDay'; import { DateRangePickerDayClasses, @@ -17,8 +16,8 @@ import { getReleaseInfo } from '../internals/utils/releaseInfo'; const releaseInfo = getReleaseInfo(); -export interface DateRangePickerDayProps - extends Omit, 'classes' | 'onBlur' | 'onFocus' | 'onKeyDown'> { +export interface DateRangePickerDayProps + extends Omit { /** * Set to `true` if the `day` is in a highlighted date range. */ @@ -58,7 +57,7 @@ export interface DateRangePickerDayProps draggable?: boolean; } -type OwnerState = DateRangePickerDayProps & { +type OwnerState = DateRangePickerDayProps & { isEndOfMonth: boolean; isStartOfMonth: boolean; isFirstVisibleCell: boolean; @@ -291,17 +290,16 @@ const DateRangePickerDayDay = styled(PickersDay, { }, }, ], -}) as unknown as ( - props: PickersDayProps & { ownerState: OwnerState }, -) => React.JSX.Element; +}) as (props: PickersDayProps & { ownerState: OwnerState }) => React.JSX.Element; -type DateRangePickerDayComponent = ( - props: DateRangePickerDayProps & React.RefAttributes, +type DateRangePickerDayComponent = ( + props: DateRangePickerDayProps & React.RefAttributes, ) => React.JSX.Element; -const DateRangePickerDayRaw = React.forwardRef(function DateRangePickerDay< - TDate extends PickerValidDate, ->(inProps: DateRangePickerDayProps, ref: React.Ref) { +const DateRangePickerDayRaw = React.forwardRef(function DateRangePickerDay( + inProps: DateRangePickerDayProps, + ref: React.Ref, +) { const props = useThemeProps({ props: inProps, name: 'MuiDateRangePickerDay' }); const { className, @@ -323,7 +321,7 @@ const DateRangePickerDayRaw = React.forwardRef(function DateRangePickerDay< } = props; useLicenseVerifier('x-date-pickers-pro', releaseInfo); - const utils = useUtils(); + const utils = useUtils(); const isEndOfMonth = utils.isSameDay(day, utils.endOfMonth(day)); const isStartOfMonth = utils.isSameDay(day, utils.startOfMonth(day)); @@ -356,7 +354,7 @@ const DateRangePickerDayRaw = React.forwardRef(function DateRangePickerDay< className={classes.rangeIntervalPreview} ownerState={ownerState} > - + ( - props: DateTimeRangePickerProps & +type DateTimeRangePickerComponent = (( + props: DateTimeRangePickerProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; @@ -28,10 +24,9 @@ type DateTimeRangePickerComponent = (< * - [DateTimeRangePicker API](https://mui.com/x/api/date-pickers/date-time-range-picker/) */ const DateTimeRangePicker = React.forwardRef(function DateTimeRangePicker< - TDate extends PickerValidDate, - TEnableAccessibleFieldDOMStructure extends boolean = false, + TEnableAccessibleFieldDOMStructure extends boolean = true, >( - inProps: DateTimeRangePickerProps, + inProps: DateTimeRangePickerProps, ref: React.Ref, ) { const props = useThemeProps({ props: inProps, name: 'MuiDateTimeRangePicker' }); @@ -83,9 +78,9 @@ DateTimeRangePicker.propTypes = { currentMonthCalendarPosition: PropTypes.oneOf([1, 2, 3]), /** * Formats the day of week displayed in the calendar header. - * @param {TDate} date The date of the day of week provided by the adapter. + * @param {PickerValidDate} date The date of the day of week provided by the adapter. * @returns {string} The name to display. - * @default (date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() + * @default (date: PickerValidDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() */ dayOfWeekFormatter: PropTypes.func, /** @@ -150,7 +145,7 @@ DateTimeRangePicker.propTypes = { */ displayWeekNumber: PropTypes.bool, /** - * @default false + * @default true */ enableAccessibleFieldDOMStructure: PropTypes.any, /** @@ -261,8 +256,7 @@ DateTimeRangePicker.propTypes = { onError: PropTypes.func, /** * Callback fired on month change. - * @template TDate - * @param {TDate} month The new month. + * @param {PickerValidDate} month The new month. */ onMonthChange: PropTypes.func, /** @@ -348,16 +342,14 @@ DateTimeRangePicker.propTypes = { * * Warning: This function can be called multiple times (for example when rendering date calendar, checking if focus can be moved to a certain date, etc.). Expensive computations can impact performance. * - * @template TDate - * @param {TDate} day The date to test. + * @param {PickerValidDate} day The date to test. * @param {string} position The date to test, 'start' or 'end'. * @returns {boolean} Returns `true` if the date should be disabled. */ shouldDisableDate: PropTypes.func, /** * Disable specific time. - * @template TDate - * @param {TDate} value The value to check. + * @param {PickerValidDate} value The value to check. * @param {TimeView} view The clock type of the timeValue. * @returns {boolean} If `true` the time will be disabled. */ diff --git a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePicker.types.ts b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePicker.types.ts index 109b4715c963..43998205dc64 100644 --- a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePicker.types.ts +++ b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePicker.types.ts @@ -1,4 +1,10 @@ -import { PickerValidDate } from '@mui/x-date-pickers/models'; +import { MakeRequired } from '@mui/x-internals/types'; +import { + BaseDateValidationProps, + BaseTimeValidationProps, + PickerRangeValue, +} from '@mui/x-date-pickers/internals'; +import { BaseSingleInputFieldProps } from '@mui/x-date-pickers/models'; import { DesktopDateTimeRangePickerProps, DesktopDateTimeRangePickerSlots, @@ -9,22 +15,20 @@ import { MobileDateTimeRangePickerSlots, MobileDateTimeRangePickerSlotProps, } from '../MobileDateTimeRangePicker'; +import { UseDateTimeRangeFieldProps } from '../internals/models'; +import { DateTimeRangeValidationError, RangeFieldSection } from '../models'; -export interface DateTimeRangePickerSlots - extends DesktopDateTimeRangePickerSlots, - MobileDateTimeRangePickerSlots {} +export interface DateTimeRangePickerSlots + extends DesktopDateTimeRangePickerSlots, + MobileDateTimeRangePickerSlots {} -export interface DateTimeRangePickerSlotProps< - TDate extends PickerValidDate, - TEnableAccessibleFieldDOMStructure extends boolean, -> extends DesktopDateTimeRangePickerSlotProps, - MobileDateTimeRangePickerSlotProps {} +export interface DateTimeRangePickerSlotProps + extends DesktopDateTimeRangePickerSlotProps, + MobileDateTimeRangePickerSlotProps {} -export interface DateTimeRangePickerProps< - TDate extends PickerValidDate, - TEnableAccessibleFieldDOMStructure extends boolean = false, -> extends DesktopDateTimeRangePickerProps, - MobileDateTimeRangePickerProps { +export interface DateTimeRangePickerProps + extends DesktopDateTimeRangePickerProps, + MobileDateTimeRangePickerProps { /** * CSS media query when `Mobile` mode will be changed to `Desktop`. * @default '@media (pointer: fine)' @@ -35,10 +39,31 @@ export interface DateTimeRangePickerProps< * Overridable component slots. * @default {} */ - slots?: DateTimeRangePickerSlots; + slots?: DateTimeRangePickerSlots; /** * The props used for each component slot. * @default {} */ - slotProps?: DateTimeRangePickerSlotProps; + slotProps?: DateTimeRangePickerSlotProps; } + +/** + * Props the field can receive when used inside a `DateTimeRangePicker`, `DesktopDateTimeRangePicker` or `MobileDateTimeRangePicker` component. + */ +export type DateTimeRangePickerFieldProps< + TEnableAccessibleFieldDOMStructure extends boolean = true, +> = MakeRequired< + UseDateTimeRangeFieldProps, + | 'format' + | 'timezone' + | 'value' + | 'ampm' + | keyof BaseDateValidationProps + | keyof BaseTimeValidationProps +> & + BaseSingleInputFieldProps< + PickerRangeValue, + RangeFieldSection, + false, + DateTimeRangeValidationError + >; diff --git a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerTabs.tsx b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerTabs.tsx index 60e1a9f533f2..dac5929e2567 100644 --- a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerTabs.tsx +++ b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerTabs.tsx @@ -6,7 +6,6 @@ import { styled, useThemeProps } from '@mui/material/styles'; import composeClasses from '@mui/utils/composeClasses'; import useEventCallback from '@mui/utils/useEventCallback'; import { TimeIcon, DateRangeIcon, ArrowLeftIcon, ArrowRightIcon } from '@mui/x-date-pickers/icons'; -import { PickerValidDate } from '@mui/x-date-pickers/models'; import { DateOrTimeViewWithMeridiem, BaseTabsProps, @@ -108,7 +107,7 @@ const DateTimeRangePickerTabFiller = styled('div', { const tabOptions: TabValue[] = ['start-date', 'start-time', 'end-date', 'end-time']; -const DateTimeRangePickerTabs = function DateTimeRangePickerTabs( +const DateTimeRangePickerTabs = function DateTimeRangePickerTabs( inProps: DateTimeRangePickerTabsProps, ) { const props = useThemeProps({ props: inProps, name: 'MuiDateTimeRangePickerTabs' }); @@ -124,7 +123,7 @@ const DateTimeRangePickerTabs = function DateTimeRangePickerTabs(); + const translations = usePickersTranslations(); const classes = useUtilityClasses(props); const value = React.useMemo(() => viewToTab(view, rangePosition), [view, rangePosition]); const isPreviousHidden = value === 'start-date'; diff --git a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerTimeWrapper.tsx b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerTimeWrapper.tsx index e8f096ffcef5..653a818b33b6 100644 --- a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerTimeWrapper.tsx +++ b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerTimeWrapper.tsx @@ -1,4 +1,5 @@ import * as React from 'react'; +import { DefaultizedProps } from '@mui/x-internals/types'; import { PickerSelectionState, PickerViewRenderer, @@ -6,19 +7,17 @@ import { useUtils, TimeViewWithMeridiem, BaseClockProps, - DefaultizedProps, + PickerRangeValue, } from '@mui/x-date-pickers/internals'; import { PickerValidDate } from '@mui/x-date-pickers/models'; -import { DateRange } from '../models'; import { UseRangePositionResponse } from '../internals/hooks/useRangePosition'; import { isRangeValid } from '../internals/utils/date-utils'; import { calculateRangeChange } from '../internals/utils/date-range-manager'; export type DateTimeRangePickerTimeWrapperProps< - TDate extends PickerValidDate, TView extends TimeViewWithMeridiem, TComponentProps extends DefaultizedProps< - Omit, 'value' | 'defaultValue' | 'onChange'>, + Omit, 'value' | 'defaultValue' | 'onChange'>, 'views' >, > = Pick & @@ -29,14 +28,14 @@ export type DateTimeRangePickerTimeWrapperProps< view: TView; onViewChange?: (view: TView) => void; views: readonly TView[]; - value?: DateRange; - defaultValue?: DateRange; + value?: PickerRangeValue; + defaultValue?: PickerRangeValue; onChange?: ( - value: DateRange, + value: PickerRangeValue, selectionState: PickerSelectionState, selectedView: TView, ) => void; - viewRenderer?: PickerViewRenderer, TView, TComponentProps, any> | null; + viewRenderer?: PickerViewRenderer | null; openTo?: TView; }; @@ -44,17 +43,16 @@ export type DateTimeRangePickerTimeWrapperProps< * @ignore - internal component. */ function DateTimeRangePickerTimeWrapper< - TDate extends PickerValidDate, TView extends TimeViewWithMeridiem, TComponentProps extends DefaultizedProps< - Omit, 'value' | 'defaultValue' | 'onChange'>, + Omit, 'value' | 'defaultValue' | 'onChange'>, 'views' >, >( - props: DateTimeRangePickerTimeWrapperProps, + props: DateTimeRangePickerTimeWrapperProps, ref: React.Ref, ) { - const utils = useUtils(); + const utils = useUtils(); const { rangePosition, @@ -77,7 +75,7 @@ function DateTimeRangePickerTimeWrapper< const currentDefaultValue = (rangePosition === 'start' ? defaultValue?.[0] : defaultValue?.[1]) ?? null; const handleOnChange = ( - newDate: TDate | null, + newDate: PickerValidDate | null, selectionState: PickerSelectionState, selectedView: TView, ) => { diff --git a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerToolbar.tsx b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerToolbar.tsx index 7ae6e7853319..cb78335558ed 100644 --- a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerToolbar.tsx +++ b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerToolbar.tsx @@ -10,6 +10,7 @@ import { useUtils, DateOrTimeViewWithMeridiem, WrapperVariant, + PickerRangeValue, } from '@mui/x-date-pickers/internals'; import { usePickersTranslations } from '@mui/x-date-pickers/hooks'; import { PickerValidDate } from '@mui/x-date-pickers/models'; @@ -17,7 +18,6 @@ import { DateTimePickerToolbarProps, DateTimePickerToolbar, } from '@mui/x-date-pickers/DateTimePicker'; -import { DateRange } from '../models'; import { UseRangePositionResponse } from '../internals/hooks/useRangePosition'; import { DateTimeRangePickerToolbarClasses, @@ -25,7 +25,7 @@ import { } from './dateTimeRangePickerToolbarClasses'; import { calculateRangeChange } from '../internals/utils/date-range-manager'; -const useUtilityClasses = (ownerState: DateTimeRangePickerToolbarProps) => { +const useUtilityClasses = (ownerState: DateTimeRangePickerToolbarProps) => { const { classes } = ownerState; const slots = { root: ['root'], @@ -38,8 +38,8 @@ const useUtilityClasses = (ownerState: DateTimeRangePickerToolbarProps) => type DateTimeRangeViews = Exclude; -export interface DateTimeRangePickerToolbarProps - extends BaseToolbarProps, DateTimeRangeViews>, +export interface DateTimeRangePickerToolbarProps + extends BaseToolbarProps, Pick, ExportedDateTimeRangePickerToolbarProps { ampm?: boolean; @@ -58,30 +58,29 @@ const DateTimeRangePickerToolbarRoot = styled('div', { slot: 'Root', overridesResolver: (_, styles) => styles.root, })<{ - ownerState: DateTimeRangePickerToolbarProps; + ownerState: DateTimeRangePickerToolbarProps; }>({ display: 'flex', flexDirection: 'column', }); -type DateTimeRangePickerStartOrEndToolbarProps = - DateTimePickerToolbarProps & { - ownerState?: DateTimeRangePickerToolbarProps; - }; +type DateTimeRangePickerStartOrEndToolbarProps = DateTimePickerToolbarProps & { + ownerState?: DateTimeRangePickerToolbarProps; +}; -type DateTimeRangePickerStartOrEndToolbarComponent = ( - props: DateTimeRangePickerStartOrEndToolbarProps, +type DateTimeRangePickerStartOrEndToolbarComponent = ( + props: DateTimeRangePickerStartOrEndToolbarProps, ) => React.JSX.Element; const DateTimeRangePickerToolbarStart = styled(DateTimePickerToolbar, { name: 'MuiDateTimeRangePickerToolbar', slot: 'StartToolbar', overridesResolver: (_, styles) => styles.startToolbar, -})>({ +})({ borderBottom: 'none', variants: [ { - props: ({ toolbarVariant }: DateTimeRangePickerStartOrEndToolbarProps) => + props: ({ toolbarVariant }: DateTimeRangePickerStartOrEndToolbarProps) => toolbarVariant !== 'desktop', style: { padding: '12px 8px 0 12px', @@ -100,10 +99,10 @@ const DateTimeRangePickerToolbarEnd = styled(DateTimePickerToolbar, { name: 'MuiDateTimeRangePickerToolbar', slot: 'EndToolbar', overridesResolver: (_, styles) => styles.endToolbar, -})>({ +})({ variants: [ { - props: ({ toolbarVariant }: DateTimeRangePickerStartOrEndToolbarProps) => + props: ({ toolbarVariant }: DateTimeRangePickerStartOrEndToolbarProps) => toolbarVariant !== 'desktop', style: { padding: '12px 8px 12px 12px', @@ -112,15 +111,16 @@ const DateTimeRangePickerToolbarEnd = styled(DateTimePickerToolbar, { ], }) as DateTimeRangePickerStartOrEndToolbarComponent; -type DateTimeRangePickerToolbarComponent = (( - props: DateTimeRangePickerToolbarProps & React.RefAttributes, +type DateTimeRangePickerToolbarComponent = (( + props: DateTimeRangePickerToolbarProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; -const DateTimeRangePickerToolbar = React.forwardRef(function DateTimeRangePickerToolbar< - TDate extends PickerValidDate, ->(inProps: DateTimeRangePickerToolbarProps, ref: React.Ref) { +const DateTimeRangePickerToolbar = React.forwardRef(function DateTimeRangePickerToolbar( + inProps: DateTimeRangePickerToolbarProps, + ref: React.Ref, +) { const props = useThemeProps({ props: inProps, name: 'MuiDateTimeRangePickerToolbar' }); - const utils = useUtils(); + const utils = useUtils(); const { value: [start, end], @@ -156,7 +156,7 @@ const DateTimeRangePickerToolbar = React.forwardRef(function DateTimeRangePicker toolbarPlaceholder, }; - const translations = usePickersTranslations(); + const translations = usePickersTranslations(); const ownerState = props; const classes = useUtilityClasses(ownerState); @@ -188,7 +188,7 @@ const DateTimeRangePickerToolbar = React.forwardRef(function DateTimeRangePicker ); const handleOnChange = React.useCallback( - (newDate: TDate | null) => { + (newDate: PickerValidDate | null) => { const { nextSelection, newRange } = calculateRangeChange({ newDate, utils, @@ -214,7 +214,7 @@ const DateTimeRangePickerToolbar = React.forwardRef(function DateTimeRangePicker sx={sx} {...other} > - + - + - extends DateRangeCalendarSlots, +export interface BaseDateTimeRangePickerSlots + extends DateRangeCalendarSlots, DigitalClockSlots, MultiSectionDigitalClockSlots { /** @@ -57,11 +57,11 @@ export interface BaseDateTimeRangePickerSlots * Custom component for the toolbar rendered above the views. * @default DateTimeRangePickerToolbar */ - toolbar?: React.JSXElementConstructor>; + toolbar?: React.JSXElementConstructor; } -export interface BaseDateTimeRangePickerSlotProps - extends DateRangeCalendarSlotProps, +export interface BaseDateTimeRangePickerSlotProps + extends DateRangeCalendarSlotProps, DigitalClockSlotProps, MultiSectionDigitalClockSlotProps { /** @@ -75,72 +75,63 @@ export interface BaseDateTimeRangePickerSlotProps } export type DateTimeRangePickerRenderers< - TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem, TAdditionalProps extends {} = {}, > = PickerViewRendererLookup< - DateRange, + PickerRangeValue, TView, - Omit, 'view' | 'slots' | 'slotProps'> & + Omit, 'view' | 'slots' | 'slotProps'> & Omit< - TimeViewRendererProps>, + TimeViewRendererProps>, 'view' | 'slots' | 'slotProps' > & { view: TView }, TAdditionalProps >; -export interface BaseDateTimeRangePickerProps +export interface BaseDateTimeRangePickerProps extends Omit< - BasePickerInputProps< - DateRange, - TDate, - DateTimeRangePickerView, - DateTimeRangeValidationError - >, + BasePickerInputProps, 'orientation' | 'views' | 'openTo' >, - ExportedDateRangeCalendarProps, - BaseDateValidationProps, - DesktopOnlyTimePickerProps, + ExportedDateRangeCalendarProps, + BaseDateValidationProps, + DesktopOnlyTimePickerProps, Partial< - Pick, DateTimeRangePickerViewExternal>, 'openTo' | 'views'> + Pick, 'openTo' | 'views'> >, - DateTimeValidationProps { + DateTimeValidationProps { /** * Overridable component slots. * @default {} */ - slots?: BaseDateTimeRangePickerSlots; + slots?: BaseDateTimeRangePickerSlots; /** * The props used for each component slot. * @default {} */ - slotProps?: BaseDateTimeRangePickerSlotProps; + slotProps?: BaseDateTimeRangePickerSlotProps; /** * Define custom view renderers for each section. * If `null`, the section will only have field editing. * If `undefined`, internally defined view will be used. */ - viewRenderers?: Partial>; + viewRenderers?: Partial>; } -type UseDateTimeRangePickerDefaultizedProps< - TDate extends PickerValidDate, - Props extends BaseDateTimeRangePickerProps, -> = LocalizedComponent< - TDate, - Omit>, 'views'> -> & { - shouldRenderTimeInASingleColumn: boolean; - views: readonly DateTimeRangePickerView[]; -}; +type UseDateTimeRangePickerDefaultizedProps = + LocalizedComponent< + Omit, 'views'> + > & { + shouldRenderTimeInASingleColumn: boolean; + views: readonly DateTimeRangePickerView[]; + }; -export function useDateTimeRangePickerDefaultizedProps< - TDate extends PickerValidDate, - Props extends BaseDateTimeRangePickerProps, ->(props: Props, name: string): UseDateTimeRangePickerDefaultizedProps { - const utils = useUtils(); - const defaultDates = useDefaultDates(); +export function useDateTimeRangePickerDefaultizedProps( + props: Props, + name: string, +): UseDateTimeRangePickerDefaultizedProps { + const utils = useUtils(); + const defaultDates = useDefaultDates(); const themeProps = useThemeProps({ props, name, @@ -158,7 +149,7 @@ export function useDateTimeRangePickerDefaultizedProps< thresholdToRenderTimeInASingleColumn, views, timeSteps, - } = resolveTimeViewsResponse({ + } = resolveTimeViewsResponse({ thresholdToRenderTimeInASingleColumn: themeProps.thresholdToRenderTimeInASingleColumn, ampm, timeSteps: themeProps.timeSteps, diff --git a/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.tsx b/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.tsx index 984548ad2a1b..ce29eb7a0e8f 100644 --- a/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.tsx +++ b/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.tsx @@ -1,9 +1,13 @@ 'use client'; import * as React from 'react'; import PropTypes from 'prop-types'; -import { PickerViewRendererLookup } from '@mui/x-date-pickers/internals'; +import { + PickerViewRendererLookup, + useUtils, + PickerRangeValue, +} from '@mui/x-date-pickers/internals'; import { extractValidationProps } from '@mui/x-date-pickers/validation'; -import { PickerValidDate } from '@mui/x-date-pickers/models'; +import { PickerOwnerState } from '@mui/x-date-pickers/models'; import resolveComponentProps from '@mui/utils/resolveComponentProps'; import { refType } from '@mui/utils'; import { rangeValueManager } from '../internals/utils/valueManagers'; @@ -13,13 +17,9 @@ import { renderDateRangeViewCalendar } from '../dateRangeViewRenderers'; import { MultiInputDateRangeField } from '../MultiInputDateRangeField'; import { useDesktopRangePicker } from '../internals/hooks/useDesktopRangePicker'; import { validateDateRange } from '../validation'; -import { DateRange } from '../models'; -type DesktopDateRangePickerComponent = (< - TDate extends PickerValidDate, - TEnableAccessibleFieldDOMStructure extends boolean = false, ->( - props: DesktopDateRangePickerProps & +type DesktopDateRangePickerComponent = (( + props: DesktopDateRangePickerProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; @@ -34,19 +34,19 @@ type DesktopDateRangePickerComponent = (< * - [DesktopDateRangePicker API](https://mui.com/x/api/date-pickers/desktop-date-range-picker/) */ const DesktopDateRangePicker = React.forwardRef(function DesktopDateRangePicker< - TDate extends PickerValidDate, - TEnableAccessibleFieldDOMStructure extends boolean = false, + TEnableAccessibleFieldDOMStructure extends boolean = true, >( - inProps: DesktopDateRangePickerProps, + inProps: DesktopDateRangePickerProps, ref: React.Ref, ) { + const utils = useUtils(); + // Props with the default values common to all date time pickers const defaultizedProps = useDateRangePickerDefaultizedProps< - TDate, - DesktopDateRangePickerProps + DesktopDateRangePickerProps >(inProps, 'MuiDesktopDateRangePicker'); - const viewRenderers: PickerViewRendererLookup, 'day', any, {}> = { + const viewRenderers: PickerViewRendererLookup = { day: renderDateRangeViewCalendar, ...defaultizedProps.viewRenderers, }; @@ -54,6 +54,7 @@ const DesktopDateRangePicker = React.forwardRef(function DesktopDateRangePicker< const props = { ...defaultizedProps, viewRenderers, + format: utils.formats.keyboardDate, calendars: defaultizedProps.calendars ?? 2, views: ['day'] as const, openTo: 'day' as const, @@ -63,7 +64,7 @@ const DesktopDateRangePicker = React.forwardRef(function DesktopDateRangePicker< }, slotProps: { ...defaultizedProps.slotProps, - field: (ownerState: any) => ({ + field: (ownerState: PickerOwnerState) => ({ ...resolveComponentProps(defaultizedProps.slotProps?.field, ownerState), ...extractValidationProps(defaultizedProps), ref, @@ -76,7 +77,6 @@ const DesktopDateRangePicker = React.forwardRef(function DesktopDateRangePicker< }; const { renderPicker } = useDesktopRangePicker< - TDate, 'day', TEnableAccessibleFieldDOMStructure, typeof props @@ -120,9 +120,9 @@ DesktopDateRangePicker.propTypes = { currentMonthCalendarPosition: PropTypes.oneOf([1, 2, 3]), /** * Formats the day of week displayed in the calendar header. - * @param {TDate} date The date of the day of week provided by the adapter. + * @param {PickerValidDate} date The date of the day of week provided by the adapter. * @returns {string} The name to display. - * @default (date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() + * @default (date: PickerValidDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase() */ dayOfWeekFormatter: PropTypes.func, /** @@ -176,7 +176,7 @@ DesktopDateRangePicker.propTypes = { */ displayWeekNumber: PropTypes.bool, /** - * @default false + * @default true */ enableAccessibleFieldDOMStructure: PropTypes.any, /** @@ -264,8 +264,7 @@ DesktopDateRangePicker.propTypes = { onError: PropTypes.func, /** * Callback fired on month change. - * @template TDate - * @param {TDate} month The new month. + * @param {PickerValidDate} month The new month. */ onMonthChange: PropTypes.func, /** @@ -339,8 +338,7 @@ DesktopDateRangePicker.propTypes = { * * Warning: This function can be called multiple times (for example when rendering date calendar, checking if focus can be moved to a certain date, etc.). Expensive computations can impact performance. * - * @template TDate - * @param {TDate} day The date to test. + * @param {PickerValidDate} day The date to test. * @param {string} position The date to test, 'start' or 'end'. * @returns {boolean} Returns `true` if the date should be disabled. */ diff --git a/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.types.ts b/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.types.ts index 8c96020fd9fa..5b238ebbf61d 100644 --- a/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.types.ts +++ b/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.types.ts @@ -1,5 +1,4 @@ -import { MakeOptional } from '@mui/x-date-pickers/internals'; -import { PickerValidDate } from '@mui/x-date-pickers/models'; +import { MakeOptional } from '@mui/x-internals/types'; import { UseDesktopRangePickerSlots, UseDesktopRangePickerSlotProps, @@ -11,23 +10,20 @@ import { BaseDateRangePickerSlotProps, } from '../DateRangePicker/shared'; -export interface DesktopDateRangePickerSlots - extends BaseDateRangePickerSlots, - MakeOptional, 'field'> {} +export interface DesktopDateRangePickerSlots + extends BaseDateRangePickerSlots, + MakeOptional, 'field'> {} -export interface DesktopDateRangePickerSlotProps< - TDate extends PickerValidDate, - TEnableAccessibleFieldDOMStructure extends boolean, -> extends BaseDateRangePickerSlotProps, +export interface DesktopDateRangePickerSlotProps + extends BaseDateRangePickerSlotProps, Omit< - UseDesktopRangePickerSlotProps, + UseDesktopRangePickerSlotProps<'day', TEnableAccessibleFieldDOMStructure>, 'tabs' | 'toolbar' > {} export interface DesktopDateRangePickerProps< - TDate extends PickerValidDate, - TEnableAccessibleFieldDOMStructure extends boolean = false, -> extends BaseDateRangePickerProps, + TEnableAccessibleFieldDOMStructure extends boolean = true, +> extends BaseDateRangePickerProps, DesktopRangeOnlyPickerProps { /** * The number of calendars to render on **desktop**. @@ -38,10 +34,10 @@ export interface DesktopDateRangePickerProps< * Overridable component slots. * @default {} */ - slots?: DesktopDateRangePickerSlots; + slots?: DesktopDateRangePickerSlots; /** * The props used for each component slot. * @default {} */ - slotProps?: DesktopDateRangePickerSlotProps; + slotProps?: DesktopDateRangePickerSlotProps; } 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 8ec961707343..807b5511d78a 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 @@ -6,6 +6,7 @@ import { createTheme, ThemeProvider } from '@mui/material/styles'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DesktopDateRangePicker } from '@mui/x-date-pickers-pro/DesktopDateRangePicker'; import { DateRange } from '@mui/x-date-pickers-pro/models'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { SingleInputDateRangeField } from '@mui/x-date-pickers-pro/SingleInputDateRangeField'; import { createPickerRenderer, @@ -30,7 +31,6 @@ describe('', () => { it('should scroll current month to the active selection when focusing appropriate field', () => { render( , @@ -49,10 +49,7 @@ describe('', () => { it(`should not crash when opening picker with invalid date value`, () => { render( - , + , ); openPicker({ type: 'date-range', variant: 'desktop', initialFocus: 'start' }); @@ -74,7 +71,6 @@ describe('', () => { ', () => { describe('Field slot: SingleInputDateRangeField', () => { it('should add focused class to the field when it is focused', () => { - // test v7 behavior + // Test with accessible DOM structure const { unmount } = render( - , + , ); const sectionsContainer = getFieldSectionsContainer(); @@ -107,8 +100,13 @@ describe('', () => { unmount(); - // test v6 behavior - render(); + // Test with non-accessible DOM structure + render( + , + ); const input = getTextbox(); act(() => input.focus()); @@ -117,20 +115,22 @@ describe('', () => { }); it('should render the input with a given `name` when `SingleInputDateRangeField` is used', () => { - // Test with v7 input + // Test with accessible DOM structure const { unmount } = render( - , + , ); expect(screen.getByRole('textbox', { hidden: true }).name).to.equal('test'); unmount(); - // Test with v6 input - render(); + // Test with non-accessible DOM structure + render( + , + ); expect(screen.getByRole('textbox').name).to.equal('test'); }); }); @@ -141,7 +141,6 @@ describe('', () => { const handleTouchStart = spy(); render( ', () => { it('should open when clicking the start input', () => { const onOpen = spy(); - render(); + render(); openPicker({ type: 'date-range', variant: 'desktop', initialFocus: 'start' }); @@ -178,7 +177,7 @@ describe('', () => { it('should open when clicking the end input', () => { const onOpen = spy(); - render(); + render(); openPicker({ type: 'date-range', variant: 'desktop', initialFocus: 'end' }); @@ -190,7 +189,7 @@ describe('', () => { it(`should open when pressing "${key}" in the start input`, () => { const onOpen = spy(); - render(); + render(); const startInput = getFieldSectionsContainer(); act(() => startInput.focus()); @@ -206,7 +205,7 @@ describe('', () => { it(`should open when pressing "${key}" in the end input`, () => { const onOpen = spy(); - render(); + render(); const endInput = getFieldSectionsContainer(1); act(() => endInput.focus()); @@ -222,14 +221,13 @@ describe('', () => { const onChange = spy(); const onAccept = spy(); const onClose = spy(); - const defaultValue: DateRange = [ + const defaultValue: DateRange = [ adapterToUse.date('2018-01-01'), adapterToUse.date('2018-01-06'), ]; render( ', () => { const onChange = spy(); const onAccept = spy(); const onClose = spy(); - const defaultValue: DateRange = [ + const defaultValue: DateRange = [ adapterToUse.date('2018-01-01'), adapterToUse.date('2018-01-06'), ]; render( ', () => { it('should not call onClose and onAccept when selecting the end date if props.closeOnSelect = false', () => { const onAccept = spy(); const onClose = spy(); - const defaultValue: DateRange = [ + const defaultValue: DateRange = [ adapterToUse.date('2018-01-01'), adapterToUse.date('2018-01-06'), ]; render( ', () => { const onChange = spy(); const onAccept = spy(); const onClose = spy(); - const defaultValue: DateRange = [ + const defaultValue: DateRange = [ adapterToUse.date('2018-01-01'), adapterToUse.date('2018-01-06'), ]; render( ', () => { render(
- +
, ); @@ -396,7 +386,7 @@ describe('', () => { const onChange = spy(); const onAccept = spy(); const onClose = spy(); - const defaultValue: DateRange = [ + const defaultValue: DateRange = [ adapterToUse.date('2018-01-01'), adapterToUse.date('2018-01-06'), ]; @@ -404,7 +394,6 @@ describe('', () => { render(
', () => { const onAccept = spy(); const onClose = spy(); - render( - , - ); + render(); // Dismiss the picker fireEvent.click(document.body); @@ -471,12 +453,7 @@ describe('', () => { render( - + + + + + + , + ); + } else { + view = renderFromJSX( + + + ({ 'data-testid': ownerState.itemId }) as any, + }} + getItemLabel={(item) => item.id} + /> + , + ); + } + + act(() => { + view.getItemRoot('2').focus(); + }); + + expect(view.getFocusedItemId()).to.equal('2'); + + act(() => { + screen.getByRole('button').focus(); + }); + + expect(screen.getByRole('button')).toHaveFocus(); + + act(() => { + setActiveItemMounted(false); + }); + act(() => { + setActiveItemMounted(true); + }); + + expect(screen.getByRole('button')).toHaveFocus(); + }); + }, +); diff --git a/packages/x-tree-view/src/useTreeItem/useTreeItem.ts b/packages/x-tree-view/src/useTreeItem/useTreeItem.ts new file mode 100644 index 000000000000..0492ddd182a2 --- /dev/null +++ b/packages/x-tree-view/src/useTreeItem/useTreeItem.ts @@ -0,0 +1,377 @@ +'use client'; +import * as React from 'react'; +import { EventHandlers } from '@mui/utils'; +import extractEventHandlers from '@mui/utils/extractEventHandlers'; +import useForkRef from '@mui/utils/useForkRef'; +import { TreeViewCancellableEvent } from '../models'; +import { + UseTreeItemParameters, + UseTreeItemReturnValue, + UseTreeItemRootSlotProps, + UseTreeItemContentSlotProps, + UseTreeItemGroupTransitionSlotProps, + UseTreeItemLabelSlotProps, + UseTreeItemIconContainerSlotProps, + UseTreeItemCheckboxSlotProps, + UseTreeItemLabelInputSlotProps, + UseTreeItemMinimalPlugins, + UseTreeItemOptionalPlugins, + UseTreeItemDragAndDropOverlaySlotProps, + UseTreeItemRootSlotPropsFromUseTreeItem, + UseTreeItemContentSlotPropsFromUseTreeItem, +} from './useTreeItem.types'; +import { useTreeViewContext } from '../internals/TreeViewProvider'; +import { TreeViewItemPluginSlotPropsEnhancerParams } from '../internals/models'; +import { useTreeItemUtils } from '../hooks/useTreeItemUtils'; +import { TreeViewItemDepthContext } from '../internals/TreeViewItemDepthContext'; +import { isTargetInDescendants } from '../internals/utils/tree'; +import { generateTreeItemIdAttribute } from '../internals/corePlugins/useTreeViewId/useTreeViewId.utils'; + +export const useTreeItem = < + TSignatures extends UseTreeItemMinimalPlugins = UseTreeItemMinimalPlugins, + TOptionalSignatures extends UseTreeItemOptionalPlugins = UseTreeItemOptionalPlugins, +>( + parameters: UseTreeItemParameters, +): UseTreeItemReturnValue => { + const { + runItemPlugins, + items: { onItemClick, disabledItemsFocusable, indentationAtItemLevel }, + selection: { disableSelection, checkboxSelection }, + expansion: { expansionTrigger }, + treeId, + instance, + publicAPI, + } = useTreeViewContext(); + const depthContext = React.useContext(TreeViewItemDepthContext); + + const { id, itemId, label, children, rootRef } = parameters; + + const { rootRef: pluginRootRef, contentRef, propsEnhancers } = runItemPlugins(parameters); + const { interactions, status } = useTreeItemUtils({ itemId, children }); + const rootRefObject = React.useRef(null); + const contentRefObject = React.useRef(null); + const handleRootRef = useForkRef(rootRef, pluginRootRef, rootRefObject)!; + const handleContentRef = useForkRef(contentRef, contentRefObject)!; + const checkboxRef = React.useRef(null); + + const idAttribute = generateTreeItemIdAttribute({ itemId, treeId, id }); + const rootTabIndex = instance.canItemBeTabbed(itemId) ? 0 : -1; + + const sharedPropsEnhancerParams: Omit< + TreeViewItemPluginSlotPropsEnhancerParams, + 'externalEventHandlers' + > = { rootRefObject, contentRefObject, interactions, status }; + + const createRootHandleFocus = + (otherHandlers: EventHandlers) => + (event: React.FocusEvent & TreeViewCancellableEvent) => { + otherHandlers.onFocus?.(event); + if (event.defaultMuiPrevented) { + return; + } + + const canBeFocused = !status.disabled || disabledItemsFocusable; + if (!status.focused && canBeFocused && event.currentTarget === event.target) { + instance.focusItem(event, itemId); + } + }; + + const createRootHandleBlur = + (otherHandlers: EventHandlers) => + (event: React.FocusEvent & TreeViewCancellableEvent) => { + otherHandlers.onBlur?.(event); + if (event.defaultMuiPrevented) { + return; + } + + const rootElement = instance.getItemDOMElement(itemId); + + // Don't blur the root when switching to editing mode + // the input that triggers the root blur can be either the relatedTarget (when entering editing state) or the target (when exiting editing state) + // when we enter the editing state, we focus the input -> we don't want to remove the focused item from the state + if ( + status.editing || + // we can exit the editing state by clicking outside the input (within the Tree Item) or by pressing Enter or Escape -> we don't want to remove the focused item from the state in these cases + // we can also exit the editing state by clicking on the root itself -> want to remove the focused item from the state in this case + (event.relatedTarget && + isTargetInDescendants(event.relatedTarget as HTMLElement, rootElement) && + ((event.target && + (event.target as HTMLElement)?.dataset?.element === 'labelInput' && + isTargetInDescendants(event.target as HTMLElement, rootElement)) || + (event.relatedTarget as HTMLElement)?.dataset?.element === 'labelInput')) + ) { + return; + } + + instance.removeFocusedItem(); + }; + + const createRootHandleKeyDown = + (otherHandlers: EventHandlers) => + (event: React.KeyboardEvent & TreeViewCancellableEvent) => { + otherHandlers.onKeyDown?.(event); + if ( + event.defaultMuiPrevented || + (event.target as HTMLElement)?.dataset?.element === 'labelInput' + ) { + return; + } + + instance.handleItemKeyDown(event, itemId); + }; + + const createLabelHandleDoubleClick = + (otherHandlers: EventHandlers) => (event: React.MouseEvent & TreeViewCancellableEvent) => { + otherHandlers.onDoubleClick?.(event); + if (event.defaultMuiPrevented) { + return; + } + interactions.toggleItemEditing(); + }; + + const createContentHandleClick = + (otherHandlers: EventHandlers) => (event: React.MouseEvent & TreeViewCancellableEvent) => { + otherHandlers.onClick?.(event); + onItemClick?.(event, itemId); + + if (event.defaultMuiPrevented || checkboxRef.current?.contains(event.target as HTMLElement)) { + return; + } + if (expansionTrigger === 'content') { + interactions.handleExpansion(event); + } + + if (!checkboxSelection) { + interactions.handleSelection(event); + } + }; + + const createContentHandleMouseDown = + (otherHandlers: EventHandlers) => (event: React.MouseEvent & TreeViewCancellableEvent) => { + otherHandlers.onMouseDown?.(event); + if (event.defaultMuiPrevented) { + return; + } + + // Prevent text selection + if (event.shiftKey || event.ctrlKey || event.metaKey || status.disabled) { + event.preventDefault(); + } + }; + + const createIconContainerHandleClick = + (otherHandlers: EventHandlers) => (event: React.MouseEvent & TreeViewCancellableEvent) => { + otherHandlers.onClick?.(event); + if (event.defaultMuiPrevented) { + return; + } + if (expansionTrigger === 'iconContainer') { + interactions.handleExpansion(event); + } + }; + + const getRootProps = = {}>( + externalProps: ExternalProps = {} as ExternalProps, + ): UseTreeItemRootSlotProps => { + const externalEventHandlers = { + ...extractEventHandlers(parameters), + ...extractEventHandlers(externalProps), + }; + + // https://www.w3.org/WAI/ARIA/apg/patterns/treeview/ + let ariaSelected: boolean | undefined; + if (status.selected) { + // - each selected node has aria-selected set to true. + ariaSelected = true; + } else if (disableSelection || status.disabled) { + // - if the tree contains nodes that are not selectable, aria-selected is not present on those nodes. + ariaSelected = undefined; + } else { + // - all nodes that are selectable but not selected have aria-selected set to false. + ariaSelected = false; + } + + const props: UseTreeItemRootSlotPropsFromUseTreeItem = { + ...externalEventHandlers, + ref: handleRootRef, + role: 'treeitem', + tabIndex: rootTabIndex, + id: idAttribute, + 'aria-expanded': status.expandable ? status.expanded : undefined, + 'aria-selected': ariaSelected, + 'aria-disabled': status.disabled || undefined, + ...externalProps, + onFocus: createRootHandleFocus(externalEventHandlers), + onBlur: createRootHandleBlur(externalEventHandlers), + onKeyDown: createRootHandleKeyDown(externalEventHandlers), + }; + + if (indentationAtItemLevel) { + props.style = { + '--TreeView-itemDepth': + typeof depthContext === 'function' ? depthContext(itemId) : depthContext, + } as React.CSSProperties; + } + + const enhancedRootProps = + propsEnhancers.root?.({ ...sharedPropsEnhancerParams, externalEventHandlers }) ?? {}; + + return { + ...props, + ...enhancedRootProps, + } as UseTreeItemRootSlotProps; + }; + + const getContentProps = = {}>( + externalProps: ExternalProps = {} as ExternalProps, + ): UseTreeItemContentSlotProps => { + const externalEventHandlers = extractEventHandlers(externalProps); + + const props: UseTreeItemContentSlotPropsFromUseTreeItem = { + ...externalEventHandlers, + ...externalProps, + ref: handleContentRef, + onClick: createContentHandleClick(externalEventHandlers), + onMouseDown: createContentHandleMouseDown(externalEventHandlers), + status, + }; + + if (indentationAtItemLevel) { + props.indentationAtItemLevel = true; + } + + const enhancedContentProps = + propsEnhancers.content?.({ ...sharedPropsEnhancerParams, externalEventHandlers }) ?? {}; + + return { + ...props, + ...enhancedContentProps, + } as UseTreeItemContentSlotProps; + }; + + const getCheckboxProps = = {}>( + externalProps: ExternalProps = {} as ExternalProps, + ): UseTreeItemCheckboxSlotProps => { + const externalEventHandlers = extractEventHandlers(externalProps); + + const props = { + ...externalEventHandlers, + ref: checkboxRef, + ...externalProps, + }; + + const enhancedCheckboxProps = + propsEnhancers.checkbox?.({ + ...sharedPropsEnhancerParams, + externalEventHandlers, + }) ?? {}; + + return { + ...props, + ...enhancedCheckboxProps, + }; + }; + + const getLabelProps = = {}>( + externalProps: ExternalProps = {} as ExternalProps, + ): UseTreeItemLabelSlotProps => { + const externalEventHandlers = { + ...extractEventHandlers(externalProps), + }; + + const props: UseTreeItemLabelSlotProps = { + ...externalEventHandlers, + children: label, + ...externalProps, + onDoubleClick: createLabelHandleDoubleClick(externalEventHandlers), + }; + + if (instance.isTreeViewEditable) { + props.editable = status.editable; + } + + return props; + }; + + const getLabelInputProps = = {}>( + externalProps: ExternalProps = {} as ExternalProps, + ): UseTreeItemLabelInputSlotProps => { + const externalEventHandlers = extractEventHandlers(externalProps); + + const enhancedLabelInputProps = + propsEnhancers.labelInput?.({ + ...sharedPropsEnhancerParams, + externalEventHandlers, + }) ?? {}; + + return { + ...externalProps, + ...enhancedLabelInputProps, + } as UseTreeItemLabelInputSlotProps; + }; + + const getIconContainerProps = = {}>( + externalProps: ExternalProps = {} as ExternalProps, + ): UseTreeItemIconContainerSlotProps => { + const externalEventHandlers = extractEventHandlers(externalProps); + + return { + ...externalEventHandlers, + ...externalProps, + onClick: createIconContainerHandleClick(externalEventHandlers), + }; + }; + + const getGroupTransitionProps = = {}>( + externalProps: ExternalProps = {} as ExternalProps, + ): UseTreeItemGroupTransitionSlotProps => { + const externalEventHandlers = extractEventHandlers(externalProps); + + const response: UseTreeItemGroupTransitionSlotProps = { + ...externalEventHandlers, + unmountOnExit: true, + component: 'ul', + role: 'group', + in: status.expanded, + children, + ...externalProps, + }; + + if (indentationAtItemLevel) { + response.indentationAtItemLevel = true; + } + + return response; + }; + + const getDragAndDropOverlayProps = = {}>( + externalProps: ExternalProps = {} as ExternalProps, + ): UseTreeItemDragAndDropOverlaySlotProps => { + const externalEventHandlers = extractEventHandlers(externalProps); + + const enhancedDragAndDropOverlayProps = + propsEnhancers.dragAndDropOverlay?.({ + ...sharedPropsEnhancerParams, + externalEventHandlers, + }) ?? {}; + + return { + ...externalProps, + ...enhancedDragAndDropOverlayProps, + } as UseTreeItemDragAndDropOverlaySlotProps; + }; + + return { + getRootProps, + getContentProps, + getGroupTransitionProps, + getIconContainerProps, + getCheckboxProps, + getLabelProps, + getLabelInputProps, + getDragAndDropOverlayProps, + rootRef: handleRootRef, + status, + publicAPI, + }; +}; diff --git a/packages/x-tree-view/src/useTreeItem/useTreeItem.types.ts b/packages/x-tree-view/src/useTreeItem/useTreeItem.types.ts new file mode 100644 index 000000000000..07a29ab799f7 --- /dev/null +++ b/packages/x-tree-view/src/useTreeItem/useTreeItem.types.ts @@ -0,0 +1,235 @@ +import * as React from 'react'; +import { TreeViewItemId, TreeViewCancellableEventHandler } from '../models'; +import { TreeViewPublicAPI } from '../internals/models'; +import { UseTreeViewSelectionSignature } from '../internals/plugins/useTreeViewSelection'; +import { UseTreeViewItemsSignature } from '../internals/plugins/useTreeViewItems'; +import { UseTreeViewFocusSignature } from '../internals/plugins/useTreeViewFocus'; +import { UseTreeViewKeyboardNavigationSignature } from '../internals/plugins/useTreeViewKeyboardNavigation'; +import { UseTreeViewLabelSignature } from '../internals/plugins/useTreeViewLabel'; +import { UseTreeViewExpansionSignature } from '../internals/plugins/useTreeViewExpansion'; + +export interface UseTreeItemParameters { + /** + * The id attribute of the item. If not provided, it will be generated. + */ + id?: string; + /** + * If `true`, the item is disabled. + * @default false + */ + disabled?: boolean; + /** + * The id of the item. + * Must be unique. + */ + itemId: TreeViewItemId; + /** + * The label of the item. + */ + label?: React.ReactNode; + rootRef?: React.Ref; + /** + * The content of the component. + */ + children?: React.ReactNode; +} + +export interface UseTreeItemRootSlotPropsFromUseTreeItem { + role: 'treeitem'; + tabIndex: 0 | -1; + id: string; + 'aria-expanded': React.AriaAttributes['aria-expanded']; + 'aria-selected': React.AriaAttributes['aria-selected']; + 'aria-disabled': React.AriaAttributes['aria-disabled']; + onFocus: TreeViewCancellableEventHandler>; + onBlur: TreeViewCancellableEventHandler>; + onKeyDown: TreeViewCancellableEventHandler>; + ref: React.RefCallback; + /** + * Only defined when the `indentationAtItemLevel` experimental feature is enabled. + */ + style?: React.CSSProperties; +} + +export interface UseTreeItemRootSlotOwnProps extends UseTreeItemRootSlotPropsFromUseTreeItem {} + +export type UseTreeItemRootSlotProps = ExternalProps & + UseTreeItemRootSlotOwnProps; + +export interface UseTreeItemContentSlotPropsFromUseTreeItem { + onClick: TreeViewCancellableEventHandler; + onMouseDown: TreeViewCancellableEventHandler; + ref: React.RefCallback | null; + status: UseTreeItemStatus; + /** + * Only defined when the `indentationAtItemLevel` experimental feature is enabled. + */ + indentationAtItemLevel?: true; +} + +export interface UseTreeItemContentSlotOwnProps + extends UseTreeItemContentSlotPropsFromUseTreeItem {} + +export type UseTreeItemContentSlotProps = ExternalProps & + UseTreeItemContentSlotOwnProps; + +export interface UseTreeItemIconContainerSlotOwnProps { + onClick: TreeViewCancellableEventHandler; +} + +export type UseTreeItemIconContainerSlotProps = ExternalProps & + UseTreeItemIconContainerSlotOwnProps; + +export interface UseTreeItemLabelSlotOwnProps { + children: React.ReactNode; + onDoubleClick: TreeViewCancellableEventHandler; + /** + * Only defined when the `isItemEditable` experimental feature is enabled. + */ + editable?: boolean; +} + +export type UseTreeItemLabelSlotProps = ExternalProps & + UseTreeItemLabelSlotOwnProps; + +export interface UseTreeItemLabelInputSlotOwnProps {} + +export type UseTreeItemLabelInputSlotProps = ExternalProps & + UseTreeItemLabelInputSlotOwnProps; + +export interface UseTreeItemCheckboxSlotOwnProps { + ref: React.RefObject; +} + +export type UseTreeItemCheckboxSlotProps = ExternalProps & + UseTreeItemCheckboxSlotOwnProps; + +export interface UseTreeItemGroupTransitionSlotOwnProps { + unmountOnExit: boolean; + in: boolean; + component: 'ul'; + role: 'group'; + children: React.ReactNode; + /** + * Only defined when the `indentationAtItemLevel` experimental feature is enabled. + */ + indentationAtItemLevel?: true; +} + +export type UseTreeItemGroupTransitionSlotProps = ExternalProps & + UseTreeItemGroupTransitionSlotOwnProps; + +export interface UseTreeItemDragAndDropOverlaySlotOwnProps {} + +export type UseTreeItemDragAndDropOverlaySlotProps = ExternalProps & + UseTreeItemDragAndDropOverlaySlotOwnProps; + +export interface UseTreeItemStatus { + expandable: boolean; + expanded: boolean; + focused: boolean; + selected: boolean; + disabled: boolean; + editing: boolean; + editable: boolean; +} + +export interface UseTreeItemReturnValue< + TSignatures extends UseTreeItemMinimalPlugins, + TOptionalSignatures extends UseTreeItemOptionalPlugins, +> { + /** + * Resolver for the root slot's props. + * @param {ExternalProps} externalProps Additional props for the root slot. + * @returns {UseTreeItemRootSlotProps} Props that should be spread on the root slot. + */ + getRootProps: = {}>( + externalProps?: ExternalProps, + ) => UseTreeItemRootSlotProps; + /** + * Resolver for the content slot's props. + * @param {ExternalProps} externalProps Additional props for the content slot. + * @returns {UseTreeItemContentSlotProps} Props that should be spread on the content slot. + */ + getContentProps: = {}>( + externalProps?: ExternalProps, + ) => UseTreeItemContentSlotProps; + /** + * Resolver for the label slot's props. + * @param {ExternalProps} externalProps Additional props for the label slot. + * @returns {UseTreeItemLabelSlotProps} Props that should be spread on the label slot. + */ + getLabelProps: = {}>( + externalProps?: ExternalProps, + ) => UseTreeItemLabelSlotProps; + /** + * Resolver for the labelInput slot's props. + * @param {ExternalProps} externalProps Additional props for the labelInput slot. + * @returns {UseTreeItemLabelInputSlotProps} Props that should be spread on the labelInput slot. + */ + getLabelInputProps: = {}>( + externalProps?: ExternalProps, + ) => UseTreeItemLabelInputSlotProps; + /** + * Resolver for the checkbox slot's props. + * @param {ExternalProps} externalProps Additional props for the checkbox slot. + * @returns {UseTreeItemCheckboxSlotProps} Props that should be spread on the checkbox slot. + */ + getCheckboxProps: = {}>( + externalProps?: ExternalProps, + ) => UseTreeItemCheckboxSlotProps; + /** + * Resolver for the iconContainer slot's props. + * @param {ExternalProps} externalProps Additional props for the iconContainer slot. + * @returns {UseTreeItemIconContainerSlotProps} Props that should be spread on the iconContainer slot. + */ + getIconContainerProps: = {}>( + externalProps?: ExternalProps, + ) => UseTreeItemIconContainerSlotProps; + /** + * Resolver for the GroupTransition slot's props. + * @param {ExternalProps} externalProps Additional props for the GroupTransition slot. + * @returns {UseTreeItemGroupTransitionSlotProps} Props that should be spread on the GroupTransition slot. + */ + getGroupTransitionProps: = {}>( + externalProps?: ExternalProps, + ) => UseTreeItemGroupTransitionSlotProps; + /** + * Resolver for the DragAndDropOverlay slot's props. + * Warning: This slot is only useful when using the `` component. + * @param {ExternalProps} externalProps Additional props for the DragAndDropOverlay slot. + * @returns {UseTreeItemDragAndDropOverlaySlotProps} Props that should be spread on the DragAndDropOverlay slot. + */ + getDragAndDropOverlayProps: = {}>( + externalProps?: ExternalProps, + ) => UseTreeItemDragAndDropOverlaySlotProps; + /** + * A ref to the component's root DOM element. + */ + rootRef: React.RefCallback | null; + /** + * Current status of the item. + */ + status: UseTreeItemStatus; + /** + * The object the allows Tree View manipulation. + */ + publicAPI: TreeViewPublicAPI; +} + +/** + * Plugins that need to be present in the Tree View in order for `UseTreeItem` to work correctly. + */ +export type UseTreeItemMinimalPlugins = readonly [ + UseTreeViewSelectionSignature, + UseTreeViewExpansionSignature, + UseTreeViewItemsSignature, + UseTreeViewFocusSignature, + UseTreeViewKeyboardNavigationSignature, + UseTreeViewLabelSignature, +]; + +/** + * Plugins that `UseTreeItem` can use if they are present, but are not required. + */ +export type UseTreeItemOptionalPlugins = readonly []; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 57785408e6f7..e62821132aad 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,7 +6,7 @@ settings: overrides: react-is: ^18.3.1 - '@types/node': ^20.16.11 + '@types/node': ^20.17.3 patchedDependencies: babel-plugin-replace-imports@1.0.2: @@ -27,53 +27,53 @@ importers: specifier: ^6.0.0 version: 6.0.0 '@argos-ci/core': - specifier: ^2.9.0 - version: 2.9.0 + specifier: ^2.10.0 + version: 2.10.0 '@babel/cli': - specifier: ^7.25.7 - version: 7.25.7(@babel/core@7.25.8) + specifier: ^7.25.9 + version: 7.25.9(@babel/core@7.26.0) '@babel/core': - specifier: ^7.25.8 - version: 7.25.8 + specifier: ^7.26.0 + version: 7.26.0 '@babel/node': - specifier: ^7.25.7 - version: 7.25.7(@babel/core@7.25.8) + specifier: ^7.26.0 + version: 7.26.0(@babel/core@7.26.0) '@babel/plugin-transform-class-properties': - specifier: ^7.25.7 - version: 7.25.7(@babel/core@7.25.8) + specifier: ^7.25.9 + version: 7.25.9(@babel/core@7.26.0) '@babel/plugin-transform-object-rest-spread': - specifier: ^7.25.8 - version: 7.25.8(@babel/core@7.25.8) + specifier: ^7.25.9 + version: 7.25.9(@babel/core@7.26.0) '@babel/plugin-transform-private-methods': - specifier: ^7.25.7 - version: 7.25.7(@babel/core@7.25.8) + specifier: ^7.25.9 + version: 7.25.9(@babel/core@7.26.0) '@babel/plugin-transform-private-property-in-object': - specifier: ^7.25.8 - version: 7.25.8(@babel/core@7.25.8) + specifier: ^7.25.9 + version: 7.25.9(@babel/core@7.26.0) '@babel/plugin-transform-react-constant-elements': - specifier: ^7.25.7 - version: 7.25.7(@babel/core@7.25.8) + specifier: ^7.25.9 + version: 7.25.9(@babel/core@7.26.0) '@babel/plugin-transform-runtime': - specifier: ^7.25.7 - version: 7.25.7(@babel/core@7.25.8) + specifier: ^7.25.9 + version: 7.25.9(@babel/core@7.26.0) '@babel/preset-env': - specifier: ^7.25.8 - version: 7.25.8(@babel/core@7.25.8) + specifier: ^7.26.0 + version: 7.26.0(@babel/core@7.26.0) '@babel/preset-react': - specifier: ^7.25.7 - version: 7.25.7(@babel/core@7.25.8) + specifier: ^7.25.9 + version: 7.25.9(@babel/core@7.26.0) '@babel/preset-typescript': - specifier: ^7.25.7 - version: 7.25.7(@babel/core@7.25.8) + specifier: ^7.26.0 + version: 7.26.0(@babel/core@7.26.0) '@babel/register': - specifier: ^7.25.7 - version: 7.25.7(@babel/core@7.25.8) + specifier: ^7.25.9 + version: 7.25.9(@babel/core@7.26.0) '@babel/traverse': - specifier: ^7.25.7 - version: 7.25.7 + specifier: ^7.25.9 + version: 7.25.9 '@babel/types': - specifier: ^7.25.8 - version: 7.25.8 + specifier: ^7.26.0 + version: 7.26.0 '@emotion/cache': specifier: ^11.13.1 version: 11.13.1 @@ -88,25 +88,25 @@ importers: 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/internal-babel-plugin-resolve-imports': specifier: 1.0.18 - version: 1.0.18(@babel/core@7.25.8) + version: 1.0.18(@babel/core@7.26.0) '@mui/internal-markdown': - specifier: ^1.0.17 - version: 1.0.17 + specifier: ^1.0.19 + version: 1.0.19 '@mui/internal-test-utils': - specifier: ^1.0.17 - version: 1.0.17(@babel/core@7.25.8)(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^1.0.19 + version: 1.0.19(@babel/core@7.26.0)(@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.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#010de4505361345951824d905d1508d6f258ba67 - version: https://codeload.github.com/mui/material-ui/tar.gz/010de4505361345951824d905d1508d6f258ba67(encoding@0.1.13) + specifier: github:mui/material-ui#32112b76aa821c2a1e98120545019ef1a71ea274 + version: https://codeload.github.com/mui/material-ui/tar.gz/32112b76aa821c2a1e98120545019ef1a71ea274(encoding@0.1.13) '@mui/utils': specifier: ^5.16.6 version: 5.16.6(@types/react@18.3.4)(react@18.3.1) '@next/eslint-plugin-next': - specifier: 14.2.15 - version: 14.2.15 + specifier: 15.0.2 + version: 15.0.2 '@octokit/plugin-retry': specifier: ^7.1.2 version: 7.1.2(@octokit/core@4.2.4(encoding@0.1.13)) @@ -132,17 +132,17 @@ importers: specifier: ^11.0.4 version: 11.0.4 '@types/karma': - specifier: ^6.3.8 - version: 6.3.8 + specifier: ^6.3.9 + version: 6.3.9 '@types/lodash': - specifier: ^4.17.10 - version: 4.17.10 + specifier: ^4.17.12 + version: 4.17.12 '@types/mocha': specifier: ^10.0.9 version: 10.0.9 '@types/node': - specifier: ^20.16.11 - version: 20.16.11 + specifier: ^20.17.3 + version: 20.17.3 '@types/react': specifier: ^18.3.4 version: 18.3.4 @@ -171,11 +171,11 @@ importers: specifier: ^10.4.20 version: 10.4.20(postcss@8.4.47) axe-core: - specifier: 4.10.0 - version: 4.10.0 + specifier: 4.10.2 + version: 4.10.2 babel-loader: specifier: ^9.2.1 - version: 9.2.1(@babel/core@7.25.8)(webpack@5.95.0) + version: 9.2.1(@babel/core@7.26.0)(webpack@5.95.0) babel-plugin-istanbul: specifier: ^7.0.0 version: 7.0.0 @@ -229,7 +229,7 @@ importers: version: 8.57.1 eslint-config-airbnb: specifier: ^19.0.4 - version: 19.0.4(eslint-plugin-import@2.31.0)(eslint-plugin-jsx-a11y@6.10.0(eslint@8.57.1))(eslint-plugin-react-hooks@5.0.0(eslint@8.57.1))(eslint-plugin-react@7.37.1(eslint@8.57.1))(eslint@8.57.1) + version: 19.0.4(eslint-plugin-import@2.31.0)(eslint-plugin-jsx-a11y@6.10.2(eslint@8.57.1))(eslint-plugin-react-hooks@5.0.0(eslint@8.57.1))(eslint-plugin-react@7.37.2(eslint@8.57.1))(eslint@8.57.1) eslint-config-airbnb-typescript: specifier: ^18.0.0 version: 18.0.0(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3))(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-plugin-import@2.31.0)(eslint@8.57.1) @@ -246,11 +246,11 @@ importers: specifier: ^2.31.0 version: 2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-webpack@0.13.9)(eslint@8.57.1) eslint-plugin-jsdoc: - specifier: ^50.4.1 - version: 50.4.1(eslint@8.57.1) + specifier: ^50.4.3 + version: 50.4.3(eslint@8.57.1) eslint-plugin-jsx-a11y: - specifier: ^6.10.0 - version: 6.10.0(eslint@8.57.1) + specifier: ^6.10.2 + version: 6.10.2(eslint@8.57.1) eslint-plugin-material-ui: specifier: workspace:^ version: link:packages/eslint-plugin-material-ui @@ -261,8 +261,8 @@ importers: specifier: ^5.2.1 version: 5.2.1(@types/eslint@8.56.12)(eslint-config-prettier@9.1.0(eslint@8.57.1))(eslint@8.57.1)(prettier@3.3.3) eslint-plugin-react: - specifier: ^7.37.1 - version: 7.37.1(eslint@8.57.1) + specifier: ^7.37.2 + version: 7.37.2(eslint@8.57.1) eslint-plugin-react-compiler: specifier: 0.0.0-experimental-9ed098e-20240725 version: 0.0.0-experimental-9ed098e-20240725(eslint@8.57.1) @@ -270,8 +270,8 @@ importers: specifier: ^5.0.0 version: 5.0.0(eslint@8.57.1) eslint-plugin-testing-library: - specifier: ^6.3.0 - version: 6.3.0(eslint@8.57.1)(typescript@5.6.3) + specifier: ^6.4.0 + version: 6.4.0(eslint@8.57.1)(typescript@5.6.3) fast-glob: specifier: ^3.3.2 version: 3.3.2 @@ -288,8 +288,8 @@ importers: specifier: ^14.0.2 version: 14.0.2 html-webpack-plugin: - specifier: ^5.6.0 - version: 5.6.0(webpack@5.95.0) + specifier: ^5.6.3 + version: 5.6.3(webpack@5.95.0) jsdom: specifier: 24.1.3 version: 24.1.3 @@ -363,8 +363,8 @@ importers: specifier: ^6.0.1 version: 6.0.1 serve: - specifier: ^14.2.3 - version: 14.2.3 + specifier: ^14.2.4 + version: 14.2.4 sinon: specifier: ^18.0.1 version: 18.0.1 @@ -378,8 +378,8 @@ importers: specifier: ^5.3.10 version: 5.3.10(@swc/core@1.7.35(@swc/helpers@0.5.5))(webpack@5.95.0) tsx: - specifier: ^4.19.1 - version: 4.19.1 + specifier: ^4.19.2 + version: 4.19.2 typescript: specifier: ^5.6.3 version: 5.6.3 @@ -405,14 +405,14 @@ importers: docs: dependencies: '@babel/core': - specifier: ^7.25.8 - version: 7.25.8 + specifier: ^7.26.0 + version: 7.26.0 '@babel/runtime': - specifier: ^7.25.7 - version: 7.25.7 + specifier: ^7.26.0 + version: 7.26.0 '@babel/runtime-corejs2': - specifier: ^7.25.7 - version: 7.25.7 + specifier: ^7.26.0 + version: 7.26.0 '@docsearch/react': specifier: ^3.6.2 version: 3.6.2(@algolia/client-search@4.22.1)(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.13.0) @@ -429,8 +429,8 @@ importers: specifier: ^11.13.0 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/docs': - specifier: 6.1.4 - version: 6.1.4(ycp24r7hmgzk3bu34shnp2ejgu) + specifier: 6.1.6 + version: 6.1.6(5qvtg2qlcuewh33f6ogt54yk7e) '@mui/icons-material': specifier: ^5.16.7 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) @@ -445,7 +445,7 @@ importers: 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/material-nextjs': specifier: ^5.16.6 - version: 5.16.6(@emotion/cache@11.13.1)(@emotion/server@11.11.0)(@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)(next@14.2.15(@babel/core@7.25.8)(@opentelemetry/api@1.8.0)(@playwright/test@1.44.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + version: 5.16.6(@emotion/cache@11.13.1)(@emotion/server@11.11.0)(@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)(next@14.2.16(@babel/core@7.26.0)(@opentelemetry/api@1.8.0)(@playwright/test@1.44.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@mui/styles': specifier: ^5.16.7 version: 5.16.7(@types/react@18.3.4)(react@18.3.1) @@ -486,8 +486,8 @@ importers: specifier: ^9.7.5 version: 9.7.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@tanstack/query-core': - specifier: ^5.59.13 - version: 5.59.13 + specifier: ^5.59.16 + version: 5.59.16 ast-types: specifier: ^0.14.2 version: 0.14.2 @@ -550,7 +550,7 @@ importers: version: 3.1.0 jscodeshift: specifier: 17.0.0 - version: 17.0.0(@babel/preset-env@7.25.8(@babel/core@7.25.8)) + version: 17.0.0(@babel/preset-env@7.26.0(@babel/core@7.26.0)) lodash: specifier: ^4.17.21 version: 4.17.21 @@ -576,8 +576,8 @@ importers: specifier: ^0.5.46 version: 0.5.46 next: - specifier: ^14.2.15 - version: 14.2.15(@babel/core@7.25.8)(@opentelemetry/api@1.8.0)(@playwright/test@1.44.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^14.2.16 + version: 14.2.16(@babel/core@7.26.0)(@opentelemetry/api@1.8.0)(@playwright/test@1.44.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) nprogress: specifier: ^0.2.0 version: 0.2.0 @@ -600,8 +600,8 @@ importers: specifier: ^18.3.1 version: 18.3.1(react@18.3.1) react-hook-form: - specifier: ^7.53.0 - version: 7.53.0(react@18.3.1) + specifier: ^7.53.1 + version: 7.53.1(react@18.3.1) react-is: specifier: ^18.3.1 version: 18.3.1 @@ -620,6 +620,9 @@ importers: recast: specifier: ^0.23.9 version: 0.23.9 + rifm: + specifier: 0.12.1 + version: 0.12.1(react@18.3.1) rimraf: specifier: ^6.0.1 version: 6.0.1 @@ -640,17 +643,17 @@ importers: version: 4.10.2 devDependencies: '@babel/plugin-transform-react-constant-elements': - specifier: ^7.25.7 - version: 7.25.7(@babel/core@7.25.8) + specifier: ^7.25.9 + version: 7.25.9(@babel/core@7.26.0) '@babel/preset-typescript': - specifier: ^7.25.7 - version: 7.25.7(@babel/core@7.25.8) + specifier: ^7.26.0 + version: 7.26.0(@babel/core@7.26.0) '@mui/internal-docs-utils': - specifier: ^1.0.14 - version: 1.0.14 + specifier: ^1.0.15 + version: 1.0.15 '@mui/internal-scripts': - specifier: ^1.0.24 - version: 1.0.24 + specifier: ^1.0.26 + version: 1.0.26 '@types/chance': specifier: ^1.1.6 version: 1.1.6 @@ -667,8 +670,8 @@ importers: specifier: ^0.0.20 version: 0.0.20 '@types/lodash': - specifier: ^4.17.10 - version: 4.17.10 + specifier: ^4.17.12 + version: 4.17.12 '@types/luxon': specifier: ^3.4.2 version: 3.4.2 @@ -697,8 +700,8 @@ importers: specifier: ^1.25.0 version: 1.25.0 serve: - specifier: ^14.2.3 - version: 14.2.3 + specifier: ^14.2.4 + version: 14.2.4 packages/eslint-plugin-material-ui: devDependencies: @@ -725,14 +728,14 @@ importers: specifier: ^10.0.9 version: 10.0.9 '@types/node': - specifier: ^20.16.11 - version: 20.16.11 + specifier: ^20.17.3 + version: 20.17.3 packages/x-charts: dependencies: '@babel/runtime': - specifier: ^7.25.7 - version: 7.25.7 + specifier: ^7.26.0 + version: 7.26.0 '@emotion/react': specifier: ^11.9.0 version: 11.13.3(@types/react@18.3.4)(react@18.3.1) @@ -768,8 +771,8 @@ importers: version: 18.3.1(react@18.3.1) devDependencies: '@mui/internal-test-utils': - specifier: ^1.0.17 - version: 1.0.17(@babel/core@7.25.8)(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^1.0.19 + version: 1.0.19(@babel/core@7.26.0)(@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.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) @@ -796,8 +799,8 @@ importers: packages/x-charts-pro: dependencies: '@babel/runtime': - specifier: ^7.25.7 - version: 7.25.7 + specifier: ^7.26.0 + version: 7.26.0 '@emotion/react': specifier: ^11.9.0 version: 11.13.3(@types/react@18.3.4)(react@18.3.1) @@ -864,8 +867,8 @@ importers: packages/x-charts-vendor: dependencies: '@babel/runtime': - specifier: ^7.25.7 - version: 7.25.7 + specifier: ^7.26.0 + version: 7.26.0 '@types/d3-color': specifier: ^3.1.3 version: 3.1.3 @@ -910,8 +913,8 @@ importers: version: 3.0.2 devDependencies: '@babel/plugin-transform-runtime': - specifier: ^7.25.7 - version: 7.25.7(@babel/core@7.25.8) + specifier: ^7.25.9 + version: 7.25.9(@babel/core@7.26.0) '@types/d3-array': specifier: ^3.2.1 version: 3.2.1 @@ -937,8 +940,8 @@ importers: specifier: ^4.1.0 version: 4.1.0 execa: - specifier: ^9.4.0 - version: 9.4.0 + specifier: ^9.4.1 + version: 9.4.1 internmap: specifier: ^2.0.3 version: 2.0.3 @@ -949,17 +952,20 @@ importers: packages/x-codemod: dependencies: '@babel/core': - specifier: ^7.25.8 - version: 7.25.8 + specifier: ^7.26.0 + version: 7.26.0 '@babel/runtime': - specifier: ^7.25.7 - version: 7.25.7 + specifier: ^7.26.0 + version: 7.26.0 '@babel/traverse': - specifier: ^7.25.7 - version: 7.25.7 + specifier: ^7.25.9 + version: 7.25.9 + '@mui/x-internals': + specifier: workspace:* + version: link:../x-internals/build jscodeshift: specifier: 17.0.0 - version: 17.0.0(@babel/preset-env@7.25.8(@babel/core@7.25.8)) + version: 17.0.0(@babel/preset-env@7.26.0(@babel/core@7.26.0)) yargs: specifier: ^17.7.2 version: 17.7.2 @@ -981,8 +987,8 @@ importers: packages/x-data-grid: dependencies: '@babel/runtime': - specifier: ^7.25.7 - version: 7.25.7 + specifier: ^7.26.0 + version: 7.26.0 '@emotion/react': specifier: ^11.9.0 version: 11.13.3(@types/react@18.3.4)(react@18.3.1) @@ -1012,8 +1018,8 @@ importers: version: 5.1.1 devDependencies: '@mui/internal-test-utils': - specifier: ^1.0.17 - version: 1.0.17(@babel/core@7.25.8)(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^1.0.19 + version: 1.0.19(@babel/core@7.26.0)(@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/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) @@ -1037,8 +1043,8 @@ importers: packages/x-data-grid-generator: dependencies: '@babel/runtime': - specifier: ^7.25.7 - version: 7.25.7 + specifier: ^7.26.0 + version: 7.26.0 '@emotion/react': specifier: ^11.9.0 version: 11.13.3(@types/react@18.3.4)(react@18.3.1) @@ -1078,8 +1084,8 @@ importers: packages/x-data-grid-premium: dependencies: '@babel/runtime': - specifier: ^7.25.7 - version: 7.25.7 + specifier: ^7.26.0 + version: 7.26.0 '@emotion/react': specifier: ^11.9.0 version: 11.13.3(@types/react@18.3.4)(react@18.3.1) @@ -1124,8 +1130,8 @@ importers: version: 5.1.1 devDependencies: '@mui/internal-test-utils': - specifier: ^1.0.17 - version: 1.0.17(@babel/core@7.25.8)(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^1.0.19 + version: 1.0.19(@babel/core@7.26.0)(@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.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) @@ -1146,8 +1152,8 @@ importers: packages/x-data-grid-pro: dependencies: '@babel/runtime': - specifier: ^7.25.7 - version: 7.25.7 + specifier: ^7.26.0 + version: 7.26.0 '@emotion/react': specifier: ^11.9.0 version: 11.13.3(@types/react@18.3.4)(react@18.3.1) @@ -1186,8 +1192,8 @@ importers: version: 5.1.1 devDependencies: '@mui/internal-test-utils': - specifier: ^1.0.17 - version: 1.0.17(@babel/core@7.25.8)(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^1.0.19 + version: 1.0.19(@babel/core@7.26.0)(@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.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) @@ -1205,8 +1211,8 @@ importers: packages/x-date-pickers: dependencies: '@babel/runtime': - specifier: ^7.25.7 - version: 7.25.7 + specifier: ^7.26.0 + version: 7.26.0 '@emotion/react': specifier: ^11.9.0 version: 11.13.3(@types/react@18.3.4)(react@18.3.1) @@ -1239,8 +1245,8 @@ importers: version: 4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) devDependencies: '@mui/internal-test-utils': - specifier: ^1.0.17 - version: 1.0.17(@babel/core@7.25.8)(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^1.0.19 + version: 1.0.19(@babel/core@7.26.0)(@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.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) @@ -1291,8 +1297,8 @@ importers: packages/x-date-pickers-pro: dependencies: '@babel/runtime': - specifier: ^7.25.7 - version: 7.25.7 + specifier: ^7.26.0 + version: 7.26.0 '@emotion/react': specifier: ^11.9.0 version: 11.13.3(@types/react@18.3.4)(react@18.3.1) @@ -1334,8 +1340,8 @@ importers: version: 4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) devDependencies: '@mui/internal-test-utils': - specifier: ^1.0.17 - version: 1.0.17(@babel/core@7.25.8)(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^1.0.19 + version: 1.0.19(@babel/core@7.26.0)(@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.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) @@ -1371,8 +1377,8 @@ importers: packages/x-internals: dependencies: '@babel/runtime': - specifier: ^7.25.7 - version: 7.25.7 + specifier: ^7.26.0 + version: 7.26.0 '@mui/utils': specifier: ^5.16.6 || ^6.0.0 version: 5.16.6(@types/react@18.3.4)(react@18.3.1) @@ -1381,8 +1387,8 @@ importers: version: 18.3.1 devDependencies: '@mui/internal-test-utils': - specifier: ^1.0.17 - version: 1.0.17(@babel/core@7.25.8)(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^1.0.19 + version: 1.0.19(@babel/core@7.26.0)(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) rimraf: specifier: ^6.0.1 version: 6.0.1 @@ -1391,8 +1397,8 @@ importers: packages/x-license: dependencies: '@babel/runtime': - specifier: ^7.25.7 - version: 7.25.7 + specifier: ^7.26.0 + version: 7.26.0 '@mui/utils': specifier: ^5.16.6 || ^6.0.0 version: 5.16.6(@types/react@18.3.4)(react@18.3.1) @@ -1401,8 +1407,8 @@ importers: version: 18.3.1 devDependencies: '@mui/internal-test-utils': - specifier: ^1.0.17 - version: 1.0.17(@babel/core@7.25.8)(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^1.0.19 + version: 1.0.19(@babel/core@7.26.0)(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) rimraf: specifier: ^6.0.1 version: 6.0.1 @@ -1411,8 +1417,8 @@ importers: packages/x-tree-view: dependencies: '@babel/runtime': - specifier: ^7.25.7 - version: 7.25.7 + specifier: ^7.26.0 + version: 7.26.0 '@emotion/react': specifier: ^11.9.0 version: 11.13.3(@types/react@18.3.4)(react@18.3.1) @@ -1445,8 +1451,8 @@ importers: version: 4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) devDependencies: '@mui/internal-test-utils': - specifier: ^1.0.17 - version: 1.0.17(@babel/core@7.25.8)(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^1.0.19 + version: 1.0.19(@babel/core@7.26.0)(@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.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) @@ -1464,8 +1470,8 @@ importers: packages/x-tree-view-pro: dependencies: '@babel/runtime': - specifier: ^7.25.7 - version: 7.25.7 + specifier: ^7.26.0 + version: 7.26.0 '@emotion/react': specifier: ^11.9.0 version: 11.13.3(@types/react@18.3.4)(react@18.3.1) @@ -1504,8 +1510,8 @@ importers: version: 4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) devDependencies: '@mui/internal-test-utils': - specifier: ^1.0.17 - version: 1.0.17(@babel/core@7.25.8)(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^1.0.19 + version: 1.0.19(@babel/core@7.26.0)(@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.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) @@ -1523,8 +1529,8 @@ importers: test: devDependencies: '@babel/runtime': - specifier: ^7.25.7 - version: 7.25.7 + specifier: ^7.26.0 + version: 7.26.0 '@emotion/cache': specifier: ^11.13.1 version: 11.13.1 @@ -1568,8 +1574,8 @@ importers: specifier: ^4.3.20 version: 4.3.20 '@types/karma': - specifier: ^6.3.8 - version: 6.3.8 + specifier: ^6.3.9 + version: 6.3.9 '@types/moment-jalaali': specifier: ^0.7.9 version: 0.7.9 @@ -1620,7 +1626,7 @@ importers: devDependencies: '@codspeed/vitest-plugin': specifier: ^3.1.1 - version: 3.1.1(vite@5.3.4(@types/node@20.16.11)(terser@5.27.0))(vitest@2.1.2) + version: 3.1.1(vite@5.3.4(@types/node@20.17.3)(terser@5.27.0))(vitest@2.1.3) '@emotion/react': specifier: ^11.13.3 version: 11.13.3(@types/react@18.3.4)(react@18.3.1) @@ -1631,8 +1637,8 @@ importers: specifier: workspace:* version: link:../../packages/x-charts-pro/build '@testing-library/jest-dom': - specifier: ^6.5.0 - version: 6.5.0 + specifier: ^6.6.2 + version: 6.6.2 '@testing-library/react': specifier: ^16.0.1 version: 16.0.1(@testing-library/dom@10.4.0)(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -1640,14 +1646,14 @@ importers: specifier: ^14.5.2 version: 14.5.2(@testing-library/dom@10.4.0) '@vitejs/plugin-react': - specifier: ^4.3.2 - version: 4.3.2(vite@5.3.4(@types/node@20.16.11)(terser@5.27.0)) + specifier: ^4.3.3 + version: 4.3.3(vite@5.3.4(@types/node@20.17.3)(terser@5.27.0)) '@vitejs/plugin-react-swc': specifier: ^3.7.1 - version: 3.7.1(@swc/helpers@0.5.5)(vite@5.3.4(@types/node@20.16.11)(terser@5.27.0)) + version: 3.7.1(@swc/helpers@0.5.5)(vite@5.3.4(@types/node@20.17.3)(terser@5.27.0)) '@vitest/ui': - specifier: 2.1.2 - version: 2.1.2(vitest@2.1.2) + specifier: 2.1.3 + version: 2.1.3(vitest@2.1.3) jsdom: specifier: ^24.1.3 version: 24.1.3 @@ -1658,8 +1664,8 @@ importers: specifier: ^18.3.1 version: 18.3.1(react@18.3.1) vitest: - specifier: 2.1.2 - version: 2.1.2(@types/node@20.16.11)(@vitest/ui@2.1.2)(jsdom@24.1.3)(terser@5.27.0) + specifier: 2.1.3 + version: 2.1.3(@types/node@20.17.3)(@vitest/ui@2.1.3)(jsdom@24.1.3)(terser@5.27.0) packages: @@ -1751,61 +1757,61 @@ packages: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} - '@argos-ci/api-client@0.6.0': - resolution: {integrity: sha512-m8ARJOfdOzyML8bFjTwPNAhGrLD5WaEvYS5g0qoHFD+6Za7Cz3d2mTDoXJX/h3T5aeVZ4WLK+ac0/F6jttd/sQ==} + '@argos-ci/api-client@0.7.0': + resolution: {integrity: sha512-oRCaqA4DZn+yxD78/dqPTcz7dJd5SIU+GwnlvqorGLw6bktQ3TMPmKND/jb/GOf8tUpOs9FrSrwxVwFjYfiVeg==} engines: {node: '>=18.0.0'} - '@argos-ci/core@2.9.0': - resolution: {integrity: sha512-EVo8Twd/At3r2z/ruycI+czMIJT88K5TrcUyrNH3osdV5eF9Vcp2wp+u9VVbBYTTTfLywIJ30v/ucb662CoUfg==} + '@argos-ci/core@2.10.0': + resolution: {integrity: sha512-mj+qt+SFYm5lM+TrDiDXEpLy5pTiznVSHktO+uhKBrAgpG3i2n3x21SITK+mERjpkxX40Tz5Dr7MYus6YWTLsQ==} engines: {node: '>=18.0.0'} - '@argos-ci/util@2.1.1': - resolution: {integrity: sha512-UyACLQe9rvCPbo9muhrLte1AD75kQlcGBuecjmaotaF9MBMj+9Yz+TYs1jJrlLMgqowfIgbXjBYmkXRUn36tCg==} + '@argos-ci/util@2.2.0': + resolution: {integrity: sha512-MLm8276zl/JkBiQKrkNUCdxQ+OcrGxffn3u61GOH7epaMd3PbxipUnD7JnptxBOt5rnXXqIObprCMl1ox7yAyw==} engines: {node: '>=18.0.0'} - '@babel/cli@7.25.7': - resolution: {integrity: sha512-vQw4QjrqjLSuL0Tt3gfVXbxEHOfsCcHN8tKyTclpSMYLq3Bp0BTzWYZfMKBs3PQ+to8q3BnumBIAsMdOqDJ6nw==} + '@babel/cli@7.25.9': + resolution: {integrity: sha512-I+02IfrTiSanpxJBlZQYb18qCxB6c2Ih371cVpfgIrPQrjAYkf45XxomTJOG8JBWX5GY35/+TmhCMdJ4ZPkL8Q==} engines: {node: '>=6.9.0'} hasBin: true peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/code-frame@7.25.7': - resolution: {integrity: sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g==} + '@babel/code-frame@7.26.0': + resolution: {integrity: sha512-INCKxTtbXtcNbUZ3YXutwMpEleqttcswhAdee7dhuoVrD2cnuc3PqtERBtxkX5nziX9vnBL8WXmSGwv8CuPV6g==} engines: {node: '>=6.9.0'} - '@babel/compat-data@7.25.8': - resolution: {integrity: sha512-ZsysZyXY4Tlx+Q53XdnOFmqwfB9QDTHYxaZYajWRoBLuLEAwI2UIbtxOjWh/cFaa9IKUlcB+DDuoskLuKu56JA==} + '@babel/compat-data@7.26.0': + resolution: {integrity: sha512-qETICbZSLe7uXv9VE8T/RWOdIE5qqyTucOt4zLYMafj2MRO271VGgLd4RACJMeBO37UPWhXiKMBk7YlJ0fOzQA==} engines: {node: '>=6.9.0'} - '@babel/core@7.25.8': - resolution: {integrity: sha512-Oixnb+DzmRT30qu9d3tJSQkxuygWm32DFykT4bRoORPa9hZ/L4KhVB/XiRm6KG+roIEM7DBQlmg27kw2HZkdZg==} + '@babel/core@7.26.0': + resolution: {integrity: sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==} engines: {node: '>=6.9.0'} - '@babel/generator@7.25.7': - resolution: {integrity: sha512-5Dqpl5fyV9pIAD62yK9P7fcA768uVPUyrQmqpqstHWgMma4feF1x/oFysBCVZLY5wJ2GkMUCdsNDnGZrPoR6rA==} + '@babel/generator@7.26.0': + resolution: {integrity: sha512-/AIkAmInnWwgEAJGQr9vY0c66Mj6kjkE2ZPB1PurTRaRAh3U+J45sAQMjQDJdh4WbR3l0x5xkimXBKyBXXAu2w==} engines: {node: '>=6.9.0'} - '@babel/helper-annotate-as-pure@7.25.7': - resolution: {integrity: sha512-4xwU8StnqnlIhhioZf1tqnVWeQ9pvH/ujS8hRfw/WOza+/a+1qv69BWNy+oY231maTCWgKWhfBU7kDpsds6zAA==} + '@babel/helper-annotate-as-pure@7.25.9': + resolution: {integrity: sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==} engines: {node: '>=6.9.0'} - '@babel/helper-builder-binary-assignment-operator-visitor@7.25.7': - resolution: {integrity: sha512-12xfNeKNH7jubQNm7PAkzlLwEmCs1tfuX3UjIw6vP6QXi+leKh6+LyC/+Ed4EIQermwd58wsyh070yjDHFlNGg==} + '@babel/helper-builder-binary-assignment-operator-visitor@7.25.9': + resolution: {integrity: sha512-C47lC7LIDCnz0h4vai/tpNOI95tCd5ZT3iBt/DBH5lXKHZsyNQv18yf1wIIg2ntiQNgmAvA+DgZ82iW8Qdym8g==} engines: {node: '>=6.9.0'} - '@babel/helper-compilation-targets@7.25.7': - resolution: {integrity: sha512-DniTEax0sv6isaw6qSQSfV4gVRNtw2rte8HHM45t9ZR0xILaufBRNkpMifCRiAPyvL4ACD6v0gfCwCmtOQaV4A==} + '@babel/helper-compilation-targets@7.25.9': + resolution: {integrity: sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==} engines: {node: '>=6.9.0'} - '@babel/helper-create-class-features-plugin@7.25.7': - resolution: {integrity: sha512-bD4WQhbkx80mAyj/WCm4ZHcF4rDxkoLFO6ph8/5/mQ3z4vAzltQXAmbc7GvVJx5H+lk5Mi5EmbTeox5nMGCsbw==} + '@babel/helper-create-class-features-plugin@7.25.9': + resolution: {integrity: sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-create-regexp-features-plugin@7.25.7': - resolution: {integrity: sha512-byHhumTj/X47wJ6C6eLpK7wW/WBEcnUeb7D0FNc/jFQnQVw7DOso3Zz5u9x/zLrFVkHa89ZGDbkAa1D54NdrCQ==} + '@babel/helper-create-regexp-features-plugin@7.25.9': + resolution: {integrity: sha512-ORPNZ3h6ZRkOyAa/SaHU+XsLZr0UQzRwuDQ0cczIA17nAzZ+85G5cVkOJIj7QavLZGSe8QXUmNFxSZzjcZF9bw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -1815,110 +1821,106 @@ packages: peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - '@babel/helper-member-expression-to-functions@7.25.7': - resolution: {integrity: sha512-O31Ssjd5K6lPbTX9AAYpSKrZmLeagt9uwschJd+Ixo6QiRyfpvgtVQp8qrDR9UNFjZ8+DO34ZkdrN+BnPXemeA==} + '@babel/helper-member-expression-to-functions@7.25.9': + resolution: {integrity: sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==} engines: {node: '>=6.9.0'} - '@babel/helper-module-imports@7.25.7': - resolution: {integrity: sha512-o0xCgpNmRohmnoWKQ0Ij8IdddjyBFE4T2kagL/x6M3+4zUgc+4qTOUBoNe4XxDskt1HPKO007ZPiMgLDq2s7Kw==} + '@babel/helper-module-imports@7.25.9': + resolution: {integrity: sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==} engines: {node: '>=6.9.0'} - '@babel/helper-module-transforms@7.25.7': - resolution: {integrity: sha512-k/6f8dKG3yDz/qCwSM+RKovjMix563SLxQFo0UhRNo239SP6n9u5/eLtKD6EAjwta2JHJ49CsD8pms2HdNiMMQ==} + '@babel/helper-module-transforms@7.26.0': + resolution: {integrity: sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-optimise-call-expression@7.25.7': - resolution: {integrity: sha512-VAwcwuYhv/AT+Vfr28c9y6SHzTan1ryqrydSTFGjU0uDJHw3uZ+PduI8plCLkRsDnqK2DMEDmwrOQRsK/Ykjng==} + '@babel/helper-optimise-call-expression@7.25.9': + resolution: {integrity: sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==} engines: {node: '>=6.9.0'} - '@babel/helper-plugin-utils@7.25.7': - resolution: {integrity: sha512-eaPZai0PiqCi09pPs3pAFfl/zYgGaE6IdXtYvmf0qlcDTd3WCtO7JWCcRd64e0EQrcYgiHibEZnOGsSY4QSgaw==} + '@babel/helper-plugin-utils@7.25.9': + resolution: {integrity: sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==} engines: {node: '>=6.9.0'} - '@babel/helper-remap-async-to-generator@7.25.7': - resolution: {integrity: sha512-kRGE89hLnPfcz6fTrlNU+uhgcwv0mBE4Gv3P9Ke9kLVJYpi4AMVVEElXvB5CabrPZW4nCM8P8UyyjrzCM0O2sw==} + '@babel/helper-remap-async-to-generator@7.25.9': + resolution: {integrity: sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-replace-supers@7.25.7': - resolution: {integrity: sha512-iy8JhqlUW9PtZkd4pHM96v6BdJ66Ba9yWSE4z0W4TvSZwLBPkyDsiIU3ENe4SmrzRBs76F7rQXTy1lYC49n6Lw==} + '@babel/helper-replace-supers@7.25.9': + resolution: {integrity: sha512-IiDqTOTBQy0sWyeXyGSC5TBJpGFXBkRynjBeXsvbhQFKj2viwJC76Epz35YLU1fpe/Am6Vppb7W7zM4fPQzLsQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-simple-access@7.25.7': - resolution: {integrity: sha512-FPGAkJmyoChQeM+ruBGIDyrT2tKfZJO8NcxdC+CWNJi7N8/rZpSxK7yvBJ5O/nF1gfu5KzN7VKG3YVSLFfRSxQ==} - engines: {node: '>=6.9.0'} - - '@babel/helper-skip-transparent-expression-wrappers@7.25.7': - resolution: {integrity: sha512-pPbNbchZBkPMD50K0p3JGcFMNLVUCuU/ABybm/PGNj4JiHrpmNyqqCphBk4i19xXtNV0JhldQJJtbSW5aUvbyA==} + '@babel/helper-simple-access@7.25.9': + resolution: {integrity: sha512-c6WHXuiaRsJTyHYLJV75t9IqsmTbItYfdj99PnzYGQZkYKvan5/2jKJ7gu31J3/BJ/A18grImSPModuyG/Eo0Q==} engines: {node: '>=6.9.0'} - '@babel/helper-string-parser@7.25.7': - resolution: {integrity: sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g==} + '@babel/helper-skip-transparent-expression-wrappers@7.25.9': + resolution: {integrity: sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.25.7': - resolution: {integrity: sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==} + '@babel/helper-string-parser@7.25.9': + resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-option@7.25.7': - resolution: {integrity: sha512-ytbPLsm+GjArDYXJ8Ydr1c/KJuutjF2besPNbIZnZ6MKUxi/uTA22t2ymmA4WFjZFpjiAMO0xuuJPqK2nvDVfQ==} + '@babel/helper-validator-identifier@7.25.9': + resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} engines: {node: '>=6.9.0'} - '@babel/helper-wrap-function@7.25.7': - resolution: {integrity: sha512-MA0roW3JF2bD1ptAaJnvcabsVlNQShUaThyJbCDD4bCp8NEgiFvpoqRI2YS22hHlc2thjO/fTg2ShLMC3jygAg==} + '@babel/helper-validator-option@7.25.9': + resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.25.7': - resolution: {integrity: sha512-Sv6pASx7Esm38KQpF/U/OXLwPPrdGHNKoeblRxgZRLXnAtnkEe4ptJPDtAZM7fBLadbc1Q07kQpSiGQ0Jg6tRA==} + '@babel/helper-wrap-function@7.25.9': + resolution: {integrity: sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==} engines: {node: '>=6.9.0'} - '@babel/highlight@7.25.7': - resolution: {integrity: sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw==} + '@babel/helpers@7.26.0': + resolution: {integrity: sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==} engines: {node: '>=6.9.0'} - '@babel/node@7.25.7': - resolution: {integrity: sha512-SLrRogiTuneH3mZeZQtWBECyVRtznezYdnH4UjatZjHrk/QP+GH9bqsToCWp23pPeA20NO1/p8kECzWt5TTpUA==} + '@babel/node@7.26.0': + resolution: {integrity: sha512-5ASMjh42hbnqyCOK68Q5chh1jKAqn91IswFTN+niwt4FLABhEWCT1tEuuo6mlNQ4WG/oFQLvJ71PaHAKtWtJyA==} engines: {node: '>=6.9.0'} hasBin: true peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/parser@7.25.8': - resolution: {integrity: sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ==} + '@babel/parser@7.26.1': + resolution: {integrity: sha512-reoQYNiAJreZNsJzyrDNzFQ+IQ5JFiIzAHJg9bn94S3l+4++J7RsIhNMoB+lgP/9tpmiAQqspv+xfdxTSzREOw==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.7': - resolution: {integrity: sha512-UV9Lg53zyebzD1DwQoT9mzkEKa922LNUp5YkTJ6Uta0RbyXaQNUgcvSt7qIu1PpPzVb6rd10OVNTzkyBGeVmxQ==} + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.9': + resolution: {integrity: sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.25.7': - resolution: {integrity: sha512-GDDWeVLNxRIkQTnJn2pDOM1pkCgYdSqPeT1a9vh9yIqu2uzzgw1zcqEb+IJOhy+dTBMlNdThrDIksr2o09qrrQ==} + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.25.9': + resolution: {integrity: sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.25.7': - resolution: {integrity: sha512-wxyWg2RYaSUYgmd9MR0FyRGyeOMQE/Uzr1wzd/g5cf5bwi9A4v6HFdDm7y1MgDtod/fLOSTZY6jDgV0xU9d5bA==} + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.25.9': + resolution: {integrity: sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.25.7': - resolution: {integrity: sha512-Xwg6tZpLxc4iQjorYsyGMyfJE7nP5MV8t/Ka58BgiA7Jw0fRqQNcANlLfdJ/yvBt9z9LD2We+BEkT7vLqZRWng==} + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.25.9': + resolution: {integrity: sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.13.0 - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.25.7': - resolution: {integrity: sha512-UVATLMidXrnH+GMUIuxq55nejlj02HP7F5ETyBONzP6G87fPBogG4CH6kxrSrdIuAjdwNO9VzyaYsrZPscWUrw==} + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.25.9': + resolution: {integrity: sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -1947,26 +1949,26 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-import-assertions@7.25.7': - resolution: {integrity: sha512-ZvZQRmME0zfJnDQnVBKYzHxXT7lYBB3Revz1GuS7oLXWMgqUPX4G+DDbT30ICClht9WKV34QVrZhSw6WdklwZQ==} + '@babel/plugin-syntax-import-assertions@7.26.0': + resolution: {integrity: sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-import-attributes@7.25.7': - resolution: {integrity: sha512-AqVo+dguCgmpi/3mYBdu9lkngOBlQ2w2vnNpa6gfiCxQZLzV4ZbhsXitJ2Yblkoe1VQwtHSaNmIaGll/26YWRw==} + '@babel/plugin-syntax-import-attributes@7.26.0': + resolution: {integrity: sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-jsx@7.25.7': - resolution: {integrity: sha512-ruZOnKO+ajVL/MVx+PwNBPOkrnXTXoWMtte1MBpegfCArhqOe3Bj52avVj1huLLxNKYKXYaSxZ2F+woK1ekXfw==} + '@babel/plugin-syntax-jsx@7.25.9': + resolution: {integrity: sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-typescript@7.25.7': - resolution: {integrity: sha512-rR+5FDjpCHqqZN2bzZm18bVYGaejGq5ZkpVCJLXor/+zlSrSoc4KWcHI0URVWjl/68Dyr1uwZUz/1njycEAv9g==} + '@babel/plugin-syntax-typescript@7.25.9': + resolution: {integrity: sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1977,98 +1979,98 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - '@babel/plugin-transform-arrow-functions@7.25.7': - resolution: {integrity: sha512-EJN2mKxDwfOUCPxMO6MUI58RN3ganiRAG/MS/S3HfB6QFNjroAMelQo/gybyYq97WerCBAZoyrAoW8Tzdq2jWg==} + '@babel/plugin-transform-arrow-functions@7.25.9': + resolution: {integrity: sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-async-generator-functions@7.25.8': - resolution: {integrity: sha512-9ypqkozyzpG+HxlH4o4gdctalFGIjjdufzo7I2XPda0iBnZ6a+FO0rIEQcdSPXp02CkvGsII1exJhmROPQd5oA==} + '@babel/plugin-transform-async-generator-functions@7.25.9': + resolution: {integrity: sha512-RXV6QAzTBbhDMO9fWwOmwwTuYaiPbggWQ9INdZqAYeSHyG7FzQ+nOZaUUjNwKv9pV3aE4WFqFm1Hnbci5tBCAw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-async-to-generator@7.25.7': - resolution: {integrity: sha512-ZUCjAavsh5CESCmi/xCpX1qcCaAglzs/7tmuvoFnJgA1dM7gQplsguljoTg+Ru8WENpX89cQyAtWoaE0I3X3Pg==} + '@babel/plugin-transform-async-to-generator@7.25.9': + resolution: {integrity: sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-block-scoped-functions@7.25.7': - resolution: {integrity: sha512-xHttvIM9fvqW+0a3tZlYcZYSBpSWzGBFIt/sYG3tcdSzBB8ZeVgz2gBP7Df+sM0N1850jrviYSSeUuc+135dmQ==} + '@babel/plugin-transform-block-scoped-functions@7.25.9': + resolution: {integrity: sha512-toHc9fzab0ZfenFpsyYinOX0J/5dgJVA2fm64xPewu7CoYHWEivIWKxkK2rMi4r3yQqLnVmheMXRdG+k239CgA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-block-scoping@7.25.7': - resolution: {integrity: sha512-ZEPJSkVZaeTFG/m2PARwLZQ+OG0vFIhPlKHK/JdIMy8DbRJ/htz6LRrTFtdzxi9EHmcwbNPAKDnadpNSIW+Aow==} + '@babel/plugin-transform-block-scoping@7.25.9': + resolution: {integrity: sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-class-properties@7.25.7': - resolution: {integrity: sha512-mhyfEW4gufjIqYFo9krXHJ3ElbFLIze5IDp+wQTxoPd+mwFb1NxatNAwmv8Q8Iuxv7Zc+q8EkiMQwc9IhyGf4g==} + '@babel/plugin-transform-class-properties@7.25.9': + resolution: {integrity: sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-class-static-block@7.25.8': - resolution: {integrity: sha512-e82gl3TCorath6YLf9xUwFehVvjvfqFhdOo4+0iVIVju+6XOi5XHkqB3P2AXnSwoeTX0HBoXq5gJFtvotJzFnQ==} + '@babel/plugin-transform-class-static-block@7.26.0': + resolution: {integrity: sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.12.0 - '@babel/plugin-transform-classes@7.25.7': - resolution: {integrity: sha512-9j9rnl+YCQY0IGoeipXvnk3niWicIB6kCsWRGLwX241qSXpbA4MKxtp/EdvFxsc4zI5vqfLxzOd0twIJ7I99zg==} + '@babel/plugin-transform-classes@7.25.9': + resolution: {integrity: sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-computed-properties@7.25.7': - resolution: {integrity: sha512-QIv+imtM+EtNxg/XBKL3hiWjgdLjMOmZ+XzQwSgmBfKbfxUjBzGgVPklUuE55eq5/uVoh8gg3dqlrwR/jw3ZeA==} + '@babel/plugin-transform-computed-properties@7.25.9': + resolution: {integrity: sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-destructuring@7.25.7': - resolution: {integrity: sha512-xKcfLTlJYUczdaM1+epcdh1UGewJqr9zATgrNHcLBcV2QmfvPPEixo/sK/syql9cEmbr7ulu5HMFG5vbbt/sEA==} + '@babel/plugin-transform-destructuring@7.25.9': + resolution: {integrity: sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-dotall-regex@7.25.7': - resolution: {integrity: sha512-kXzXMMRzAtJdDEgQBLF4oaiT6ZCU3oWHgpARnTKDAqPkDJ+bs3NrZb310YYevR5QlRo3Kn7dzzIdHbZm1VzJdQ==} + '@babel/plugin-transform-dotall-regex@7.25.9': + resolution: {integrity: sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-duplicate-keys@7.25.7': - resolution: {integrity: sha512-by+v2CjoL3aMnWDOyCIg+yxU9KXSRa9tN6MbqggH5xvymmr9p4AMjYkNlQy4brMceBnUyHZ9G8RnpvT8wP7Cfg==} + '@babel/plugin-transform-duplicate-keys@7.25.9': + resolution: {integrity: sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.25.7': - resolution: {integrity: sha512-HvS6JF66xSS5rNKXLqkk7L9c/jZ/cdIVIcoPVrnl8IsVpLggTjXs8OWekbLHs/VtYDDh5WXnQyeE3PPUGm22MA==} + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.25.9': + resolution: {integrity: sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/plugin-transform-dynamic-import@7.25.8': - resolution: {integrity: sha512-gznWY+mr4ZQL/EWPcbBQUP3BXS5FwZp8RUOw06BaRn8tQLzN4XLIxXejpHN9Qo8x8jjBmAAKp6FoS51AgkSA/A==} + '@babel/plugin-transform-dynamic-import@7.25.9': + resolution: {integrity: sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-exponentiation-operator@7.25.7': - resolution: {integrity: sha512-yjqtpstPfZ0h/y40fAXRv2snciYr0OAoMXY/0ClC7tm4C/nG5NJKmIItlaYlLbIVAWNfrYuy9dq1bE0SbX0PEg==} + '@babel/plugin-transform-exponentiation-operator@7.25.9': + resolution: {integrity: sha512-KRhdhlVk2nObA5AYa7QMgTMTVJdfHprfpAk4DjZVtllqRg9qarilstTKEhpVjyt+Npi8ThRyiV8176Am3CodPA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-export-namespace-from@7.25.8': - resolution: {integrity: sha512-sPtYrduWINTQTW7FtOy99VCTWp4H23UX7vYcut7S4CIMEXU+54zKX9uCoGkLsWXteyaMXzVHgzWbLfQ1w4GZgw==} + '@babel/plugin-transform-export-namespace-from@7.25.9': + resolution: {integrity: sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -2079,152 +2081,152 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-for-of@7.25.7': - resolution: {integrity: sha512-n/TaiBGJxYFWvpJDfsxSj9lEEE44BFM1EPGz4KEiTipTgkoFVVcCmzAL3qA7fdQU96dpo4gGf5HBx/KnDvqiHw==} + '@babel/plugin-transform-for-of@7.25.9': + resolution: {integrity: sha512-LqHxduHoaGELJl2uhImHwRQudhCM50pT46rIBNvtT/Oql3nqiS3wOwP+5ten7NpYSXrrVLgtZU3DZmPtWZo16A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-function-name@7.25.7': - resolution: {integrity: sha512-5MCTNcjCMxQ63Tdu9rxyN6cAWurqfrDZ76qvVPrGYdBxIj+EawuuxTu/+dgJlhK5eRz3v1gLwp6XwS8XaX2NiQ==} + '@babel/plugin-transform-function-name@7.25.9': + resolution: {integrity: sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-json-strings@7.25.8': - resolution: {integrity: sha512-4OMNv7eHTmJ2YXs3tvxAfa/I43di+VcF+M4Wt66c88EAED1RoGaf1D64cL5FkRpNL+Vx9Hds84lksWvd/wMIdA==} + '@babel/plugin-transform-json-strings@7.25.9': + resolution: {integrity: sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-literals@7.25.7': - resolution: {integrity: sha512-fwzkLrSu2fESR/cm4t6vqd7ebNIopz2QHGtjoU+dswQo/P6lwAG04Q98lliE3jkz/XqnbGFLnUcE0q0CVUf92w==} + '@babel/plugin-transform-literals@7.25.9': + resolution: {integrity: sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-logical-assignment-operators@7.25.8': - resolution: {integrity: sha512-f5W0AhSbbI+yY6VakT04jmxdxz+WsID0neG7+kQZbCOjuyJNdL5Nn4WIBm4hRpKnUcO9lP0eipUhFN12JpoH8g==} + '@babel/plugin-transform-logical-assignment-operators@7.25.9': + resolution: {integrity: sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-member-expression-literals@7.25.7': - resolution: {integrity: sha512-Std3kXwpXfRV0QtQy5JJcRpkqP8/wG4XL7hSKZmGlxPlDqmpXtEPRmhF7ztnlTCtUN3eXRUJp+sBEZjaIBVYaw==} + '@babel/plugin-transform-member-expression-literals@7.25.9': + resolution: {integrity: sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-amd@7.25.7': - resolution: {integrity: sha512-CgselSGCGzjQvKzghCvDTxKHP3iooenLpJDO842ehn5D2G5fJB222ptnDwQho0WjEvg7zyoxb9P+wiYxiJX5yA==} + '@babel/plugin-transform-modules-amd@7.25.9': + resolution: {integrity: sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-commonjs@7.25.7': - resolution: {integrity: sha512-L9Gcahi0kKFYXvweO6n0wc3ZG1ChpSFdgG+eV1WYZ3/dGbJK7vvk91FgGgak8YwRgrCuihF8tE/Xg07EkL5COg==} + '@babel/plugin-transform-modules-commonjs@7.25.9': + resolution: {integrity: sha512-dwh2Ol1jWwL2MgkCzUSOvfmKElqQcuswAZypBSUsScMXvgdT8Ekq5YA6TtqpTVWH+4903NmboMuH1o9i8Rxlyg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-systemjs@7.25.7': - resolution: {integrity: sha512-t9jZIvBmOXJsiuyOwhrIGs8dVcD6jDyg2icw1VL4A/g+FnWyJKwUfSSU2nwJuMV2Zqui856El9u+ElB+j9fV1g==} + '@babel/plugin-transform-modules-systemjs@7.25.9': + resolution: {integrity: sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-umd@7.25.7': - resolution: {integrity: sha512-p88Jg6QqsaPh+EB7I9GJrIqi1Zt4ZBHUQtjw3z1bzEXcLh6GfPqzZJ6G+G1HBGKUNukT58MnKG7EN7zXQBCODw==} + '@babel/plugin-transform-modules-umd@7.25.9': + resolution: {integrity: sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-named-capturing-groups-regex@7.25.7': - resolution: {integrity: sha512-BtAT9LzCISKG3Dsdw5uso4oV1+v2NlVXIIomKJgQybotJY3OwCwJmkongjHgwGKoZXd0qG5UZ12JUlDQ07W6Ow==} + '@babel/plugin-transform-named-capturing-groups-regex@7.25.9': + resolution: {integrity: sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/plugin-transform-new-target@7.25.7': - resolution: {integrity: sha512-CfCS2jDsbcZaVYxRFo2qtavW8SpdzmBXC2LOI4oO0rP+JSRDxxF3inF4GcPsLgfb5FjkhXG5/yR/lxuRs2pySA==} + '@babel/plugin-transform-new-target@7.25.9': + resolution: {integrity: sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-nullish-coalescing-operator@7.25.8': - resolution: {integrity: sha512-Z7WJJWdQc8yCWgAmjI3hyC+5PXIubH9yRKzkl9ZEG647O9szl9zvmKLzpbItlijBnVhTUf1cpyWBsZ3+2wjWPQ==} + '@babel/plugin-transform-nullish-coalescing-operator@7.25.9': + resolution: {integrity: sha512-ENfftpLZw5EItALAD4WsY/KUWvhUlZndm5GC7G3evUsVeSJB6p0pBeLQUnRnBCBx7zV0RKQjR9kCuwrsIrjWog==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-numeric-separator@7.25.8': - resolution: {integrity: sha512-rm9a5iEFPS4iMIy+/A/PiS0QN0UyjPIeVvbU5EMZFKJZHt8vQnasbpo3T3EFcxzCeYO0BHfc4RqooCZc51J86Q==} + '@babel/plugin-transform-numeric-separator@7.25.9': + resolution: {integrity: sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-object-rest-spread@7.25.8': - resolution: {integrity: sha512-LkUu0O2hnUKHKE7/zYOIjByMa4VRaV2CD/cdGz0AxU9we+VA3kDDggKEzI0Oz1IroG+6gUP6UmWEHBMWZU316g==} + '@babel/plugin-transform-object-rest-spread@7.25.9': + resolution: {integrity: sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-object-super@7.25.7': - resolution: {integrity: sha512-pWT6UXCEW3u1t2tcAGtE15ornCBvopHj9Bps9D2DsH15APgNVOTwwczGckX+WkAvBmuoYKRCFa4DK+jM8vh5AA==} + '@babel/plugin-transform-object-super@7.25.9': + resolution: {integrity: sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-optional-catch-binding@7.25.8': - resolution: {integrity: sha512-EbQYweoMAHOn7iJ9GgZo14ghhb9tTjgOc88xFgYngifx7Z9u580cENCV159M4xDh3q/irbhSjZVpuhpC2gKBbg==} + '@babel/plugin-transform-optional-catch-binding@7.25.9': + resolution: {integrity: sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-optional-chaining@7.25.8': - resolution: {integrity: sha512-q05Bk7gXOxpTHoQ8RSzGSh/LHVB9JEIkKnk3myAWwZHnYiTGYtbdrYkIsS8Xyh4ltKf7GNUSgzs/6P2bJtBAQg==} + '@babel/plugin-transform-optional-chaining@7.25.9': + resolution: {integrity: sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-parameters@7.25.7': - resolution: {integrity: sha512-FYiTvku63me9+1Nz7TOx4YMtW3tWXzfANZtrzHhUZrz4d47EEtMQhzFoZWESfXuAMMT5mwzD4+y1N8ONAX6lMQ==} + '@babel/plugin-transform-parameters@7.25.9': + resolution: {integrity: sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-private-methods@7.25.7': - resolution: {integrity: sha512-KY0hh2FluNxMLwOCHbxVOKfdB5sjWG4M183885FmaqWWiGMhRZq4DQRKH6mHdEucbJnyDyYiZNwNG424RymJjA==} + '@babel/plugin-transform-private-methods@7.25.9': + resolution: {integrity: sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-private-property-in-object@7.25.8': - resolution: {integrity: sha512-8Uh966svuB4V8RHHg0QJOB32QK287NBksJOByoKmHMp1TAobNniNalIkI2i5IPj5+S9NYCG4VIjbEuiSN8r+ow==} + '@babel/plugin-transform-private-property-in-object@7.25.9': + resolution: {integrity: sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-property-literals@7.25.7': - resolution: {integrity: sha512-lQEeetGKfFi0wHbt8ClQrUSUMfEeI3MMm74Z73T9/kuz990yYVtfofjf3NuA42Jy3auFOpbjDyCSiIkTs1VIYw==} + '@babel/plugin-transform-property-literals@7.25.9': + resolution: {integrity: sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-react-constant-elements@7.25.7': - resolution: {integrity: sha512-/qXt69Em8HgsjCLu7G3zdIQn7A2QwmYND7Wa0LTp09Na+Zn8L5d0A7wSXrKi18TJRc/Q5S1i1De/SU1LzVkSvA==} + '@babel/plugin-transform-react-constant-elements@7.25.9': + resolution: {integrity: sha512-Ncw2JFsJVuvfRsa2lSHiC55kETQVLSnsYGQ1JDDwkUeWGTL/8Tom8aLTnlqgoeuopWrbbGndrc9AlLYrIosrow==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-react-display-name@7.25.7': - resolution: {integrity: sha512-r0QY7NVU8OnrwE+w2IWiRom0wwsTbjx4+xH2RTd7AVdof3uurXOF+/mXHQDRk+2jIvWgSaCHKMgggfvM4dyUGA==} + '@babel/plugin-transform-react-display-name@7.25.9': + resolution: {integrity: sha512-KJfMlYIUxQB1CJfO3e0+h0ZHWOTLCPP115Awhaz8U0Zpq36Gl/cXlpoyMRnUWlhNUBAzldnCiAZNvCDj7CrKxQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-react-jsx-development@7.25.7': - resolution: {integrity: sha512-5yd3lH1PWxzW6IZj+p+Y4OLQzz0/LzlOG8vGqonHfVR3euf1vyzyMUJk9Ac+m97BH46mFc/98t9PmYLyvgL3qg==} + '@babel/plugin-transform-react-jsx-development@7.25.9': + resolution: {integrity: sha512-9mj6rm7XVYs4mdLIpbZnHOYdpW42uoiBCTVowg7sP1thUOiANgMb4UtpRivR0pp5iL+ocvUv7X4mZgFRpJEzGw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -2241,98 +2243,104 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-react-jsx@7.25.7': - resolution: {integrity: sha512-vILAg5nwGlR9EXE8JIOX4NHXd49lrYbN8hnjffDtoULwpL9hUx/N55nqh2qd0q6FyNDfjl9V79ecKGvFbcSA0Q==} + '@babel/plugin-transform-react-jsx@7.25.9': + resolution: {integrity: sha512-s5XwpQYCqGerXl+Pu6VDL3x0j2d82eiV77UJ8a2mDHAW7j9SWRqQ2y1fNo1Z74CdcYipl5Z41zvjj4Nfzq36rw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-react-pure-annotations@7.25.7': - resolution: {integrity: sha512-6YTHJ7yjjgYqGc8S+CbEXhLICODk0Tn92j+vNJo07HFk9t3bjFgAKxPLFhHwF2NjmQVSI1zBRfBWUeVBa2osfA==} + '@babel/plugin-transform-react-pure-annotations@7.25.9': + resolution: {integrity: sha512-KQ/Takk3T8Qzj5TppkS1be588lkbTp5uj7w6a0LeQaTMSckU/wK0oJ/pih+T690tkgI5jfmg2TqDJvd41Sj1Cg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-regenerator@7.25.7': - resolution: {integrity: sha512-mgDoQCRjrY3XK95UuV60tZlFCQGXEtMg8H+IsW72ldw1ih1jZhzYXbJvghmAEpg5UVhhnCeia1CkGttUvCkiMQ==} + '@babel/plugin-transform-regenerator@7.25.9': + resolution: {integrity: sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-reserved-words@7.25.7': - resolution: {integrity: sha512-3OfyfRRqiGeOvIWSagcwUTVk2hXBsr/ww7bLn6TRTuXnexA+Udov2icFOxFX9abaj4l96ooYkcNN1qi2Zvqwng==} + '@babel/plugin-transform-regexp-modifiers@7.26.0': + resolution: {integrity: sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-reserved-words@7.25.9': + resolution: {integrity: sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-runtime@7.25.7': - resolution: {integrity: sha512-Y9p487tyTzB0yDYQOtWnC+9HGOuogtP3/wNpun1xJXEEvI6vip59BSBTsHnekZLqxmPcgsrAKt46HAAb//xGhg==} + '@babel/plugin-transform-runtime@7.25.9': + resolution: {integrity: sha512-nZp7GlEl+yULJrClz0SwHPqir3lc0zsPrDHQUcxGspSL7AKrexNSEfTbfqnDNJUO13bgKyfuOLMF8Xqtu8j3YQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-shorthand-properties@7.25.7': - resolution: {integrity: sha512-uBbxNwimHi5Bv3hUccmOFlUy3ATO6WagTApenHz9KzoIdn0XeACdB12ZJ4cjhuB2WSi80Ez2FWzJnarccriJeA==} + '@babel/plugin-transform-shorthand-properties@7.25.9': + resolution: {integrity: sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-spread@7.25.7': - resolution: {integrity: sha512-Mm6aeymI0PBh44xNIv/qvo8nmbkpZze1KvR8MkEqbIREDxoiWTi18Zr2jryfRMwDfVZF9foKh060fWgni44luw==} + '@babel/plugin-transform-spread@7.25.9': + resolution: {integrity: sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-sticky-regex@7.25.7': - resolution: {integrity: sha512-ZFAeNkpGuLnAQ/NCsXJ6xik7Id+tHuS+NT+ue/2+rn/31zcdnupCdmunOizEaP0JsUmTFSTOPoQY7PkK2pttXw==} + '@babel/plugin-transform-sticky-regex@7.25.9': + resolution: {integrity: sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-template-literals@7.25.7': - resolution: {integrity: sha512-SI274k0nUsFFmyQupiO7+wKATAmMFf8iFgq2O+vVFXZ0SV9lNfT1NGzBEhjquFmD8I9sqHLguH+gZVN3vww2AA==} + '@babel/plugin-transform-template-literals@7.25.9': + resolution: {integrity: sha512-o97AE4syN71M/lxrCtQByzphAdlYluKPDBzDVzMmfCobUjjhAryZV0AIpRPrxN0eAkxXO6ZLEScmt+PNhj2OTw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-typeof-symbol@7.25.7': - resolution: {integrity: sha512-OmWmQtTHnO8RSUbL0NTdtpbZHeNTnm68Gj5pA4Y2blFNh+V4iZR68V1qL9cI37J21ZN7AaCnkfdHtLExQPf2uA==} + '@babel/plugin-transform-typeof-symbol@7.25.9': + resolution: {integrity: sha512-v61XqUMiueJROUv66BVIOi0Fv/CUuZuZMl5NkRoCVxLAnMexZ0A3kMe7vvZ0nulxMuMp0Mk6S5hNh48yki08ZA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-typescript@7.25.7': - resolution: {integrity: sha512-VKlgy2vBzj8AmEzunocMun2fF06bsSWV+FvVXohtL6FGve/+L217qhHxRTVGHEDO/YR8IANcjzgJsd04J8ge5Q==} + '@babel/plugin-transform-typescript@7.25.9': + resolution: {integrity: sha512-7PbZQZP50tzv2KGGnhh82GSyMB01yKY9scIjf1a+GfZCtInOWqUH5+1EBU4t9fyR5Oykkkc9vFTs4OHrhHXljQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-unicode-escapes@7.25.7': - resolution: {integrity: sha512-BN87D7KpbdiABA+t3HbVqHzKWUDN3dymLaTnPFAMyc8lV+KN3+YzNhVRNdinaCPA4AUqx7ubXbQ9shRjYBl3SQ==} + '@babel/plugin-transform-unicode-escapes@7.25.9': + resolution: {integrity: sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-unicode-property-regex@7.25.7': - resolution: {integrity: sha512-IWfR89zcEPQGB/iB408uGtSPlQd3Jpq11Im86vUgcmSTcoWAiQMCTOa2K2yNNqFJEBVICKhayctee65Ka8OB0w==} + '@babel/plugin-transform-unicode-property-regex@7.25.9': + resolution: {integrity: sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-unicode-regex@7.25.7': - resolution: {integrity: sha512-8JKfg/hiuA3qXnlLx8qtv5HWRbgyFx2hMMtpDDuU2rTckpKkGu4ycK5yYHwuEa16/quXfoxHBIApEsNyMWnt0g==} + '@babel/plugin-transform-unicode-regex@7.25.9': + resolution: {integrity: sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-unicode-sets-regex@7.25.7': - resolution: {integrity: sha512-YRW8o9vzImwmh4Q3Rffd09bH5/hvY0pxg+1H1i0f7APoUeg12G7+HhLj9ZFNIrYkgBXhIijPJ+IXypN0hLTIbw==} + '@babel/plugin-transform-unicode-sets-regex@7.25.9': + resolution: {integrity: sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/preset-env@7.25.8': - resolution: {integrity: sha512-58T2yulDHMN8YMUxiLq5YmWUnlDCyY1FsHM+v12VMx+1/FlrUj5tY50iDCpofFQEM8fMYOaY9YRvym2jcjn1Dg==} + '@babel/preset-env@7.26.0': + resolution: {integrity: sha512-H84Fxq0CQJNdPFT2DrfnylZ3cf5K43rGfWK4LJGPpjKHiZlk0/RzwEus3PDDZZg+/Er7lCA03MVacueUuXdzfw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -2348,42 +2356,42 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0 - '@babel/preset-react@7.25.7': - resolution: {integrity: sha512-GjV0/mUEEXpi1U5ZgDprMRRgajGMRW3G5FjMr5KLKD8nT2fTG8+h/klV3+6Dm5739QE+K5+2e91qFKAYI3pmRg==} + '@babel/preset-react@7.25.9': + resolution: {integrity: sha512-D3to0uSPiWE7rBrdIICCd0tJSIGpLaaGptna2+w7Pft5xMqLpA1sz99DK5TZ1TjGbdQ/VI1eCSZ06dv3lT4JOw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/preset-typescript@7.25.7': - resolution: {integrity: sha512-rkkpaXJZOFN45Fb+Gki0c+KMIglk4+zZXOoMJuyEK8y8Kkc8Jd3BDmP7qPsz0zQMJj+UD7EprF+AqAXcILnexw==} + '@babel/preset-typescript@7.26.0': + resolution: {integrity: sha512-NMk1IGZ5I/oHhoXEElcm+xUnL/szL6xflkFZmoEU9xj1qSJXpiS7rsspYo92B4DRCDvZn2erT5LdsCeXAKNCkg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/register@7.25.7': - resolution: {integrity: sha512-qHTd2Rhn/rKhSUwdY6+n98FmwXN+N+zxSVx3zWqRe9INyvTpv+aQ5gDV2+43ACd3VtMBzPPljbb0gZb8u5ma6Q==} + '@babel/register@7.25.9': + resolution: {integrity: sha512-8D43jXtGsYmEeDvm4MWHYUpWf8iiXgWYx3fW7E7Wb7Oe6FWqJPl5K6TuFW0dOwNZzEE5rjlaSJYH9JjrUKJszA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/runtime-corejs2@7.25.7': - resolution: {integrity: sha512-xdsLBlDCJIZzwH1fBJ7GJu+bRFO0Sqv10WotmwMu83Joep1erPcWbTr84rZD42kPzSjtmrFgshdWHKfQTWOsng==} + '@babel/runtime-corejs2@7.26.0': + resolution: {integrity: sha512-AQKSxUdaM7uTEGFmLZj1LOgX3LaLdt4udjqywaVdN6R5P2KAgqtBkDW4TS2ySRYNqcKmEe8Xv96jegHJNNb7Gg==} engines: {node: '>=6.9.0'} - '@babel/runtime@7.25.7': - resolution: {integrity: sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w==} + '@babel/runtime@7.26.0': + resolution: {integrity: sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==} engines: {node: '>=6.9.0'} - '@babel/template@7.25.7': - resolution: {integrity: sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA==} + '@babel/template@7.25.9': + resolution: {integrity: sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.25.7': - resolution: {integrity: sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg==} + '@babel/traverse@7.25.9': + resolution: {integrity: sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==} engines: {node: '>=6.9.0'} - '@babel/types@7.25.8': - resolution: {integrity: sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg==} + '@babel/types@7.26.0': + resolution: {integrity: sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==} engines: {node: '>=6.9.0'} '@bcoe/v8-coverage@0.2.3': @@ -3025,8 +3033,8 @@ packages: '@mui/core-downloads-tracker@5.16.7': resolution: {integrity: sha512-RtsCt4Geed2/v74sbihWzzRs+HsIQCfclHeORh5Ynu2fS4icIKozcSubwuG7vtzq2uW3fOR1zITSP84TNt2GoQ==} - '@mui/docs@6.1.4': - resolution: {integrity: sha512-pUMMy4Hxx1se+gG0stiX/ICphFfOx9RC3bKI4da11iUNVsSaUfYaCtiPc296BUbilaTMcQ82v8jYu+AOexHT3w==} + '@mui/docs@6.1.6': + resolution: {integrity: sha512-RSDuaanoDUHYSAjm+Stia9MvDHVElw0cFC4lo/Ekw8cZ22ke90KB6YKE7hqnqr2+knUfBvOcQxLJrJfkLElyiQ==} engines: {node: '>=14.0.0'} peerDependencies: '@mui/base': '*' @@ -3058,17 +3066,17 @@ packages: peerDependencies: '@babel/core': '7' - '@mui/internal-docs-utils@1.0.14': - resolution: {integrity: sha512-jb8RyzoGkV8zvTJndB4An95WCasbDwmDiTibw2YQaUh3+4XiAX3jS2XUB9ab3BxMv3TDCCywL5g0viB1bxQVBw==} + '@mui/internal-docs-utils@1.0.15': + resolution: {integrity: sha512-I+/9+8p9qck/pePgB7qkJdPd181TwCQf9p1+Re40Vs+FsirbQ6j4lgAsVleu2RZMCwzO6q2k1tfPOHIshNp62w==} - '@mui/internal-markdown@1.0.17': - resolution: {integrity: sha512-sws1OTUvJxNZ04mTYgahB7Z35yWcAEzVQxqqnOB+tPgDL/iMLtMQXB6wEFbW77e/P3O6Y/XOe7FhHXnK46vYTQ==} + '@mui/internal-markdown@1.0.19': + resolution: {integrity: sha512-on9EsIqZU2fuMSyxEyOQrgq2t6VQ0cZbAGPSJtY/m/+5rv8At+VxdeyQLkxSBUcpw6mKIgGTFY3oCWqtO+8qjA==} - '@mui/internal-scripts@1.0.24': - resolution: {integrity: sha512-omDYril4RiR8PSmPWkja16BjNyGkcj7N9sK1Ul9pSVpKSw8LF4BUxLOkF5NzAfDxNQgoZp+7DJPWBm9c/hmC+A==} + '@mui/internal-scripts@1.0.26': + resolution: {integrity: sha512-Y+0zfHXEMxNWisJXNzLI/akfhi88M1RoWK/RVthnQk//OzVY/3xVPwKnJ6SgPGWVZ+6MPASMAK6XmFSiqoQYQA==} - '@mui/internal-test-utils@1.0.17': - resolution: {integrity: sha512-tLOlGMIkDIUnExfl+3LoaV60PWniOjfv44C5gCVW6PDhg0O0P5T1E2vM1zvOwm4T7xM+6IKY9E5BKcEUsdpqaQ==} + '@mui/internal-test-utils@1.0.19': + resolution: {integrity: sha512-0t3L1bOi4uWZL3BwZqARVXMsw4MUuvV6njCgvfHuY5tuc2iAcVWO+zyCwEgVZYAlZY8QTyC+99xuYBUPSo8pcw==} peerDependencies: react: ^18.2.0 react-dom: ^18.2.0 @@ -3143,10 +3151,10 @@ packages: '@types/react': optional: true - '@mui/monorepo@https://codeload.github.com/mui/material-ui/tar.gz/010de4505361345951824d905d1508d6f258ba67': - resolution: {tarball: https://codeload.github.com/mui/material-ui/tar.gz/010de4505361345951824d905d1508d6f258ba67} - version: 6.1.4 - engines: {pnpm: 9.12.1} + '@mui/monorepo@https://codeload.github.com/mui/material-ui/tar.gz/32112b76aa821c2a1e98120545019ef1a71ea274': + resolution: {tarball: https://codeload.github.com/mui/material-ui/tar.gz/32112b76aa821c2a1e98120545019ef1a71ea274} + version: 6.1.6 + engines: {pnpm: 9.12.2} '@mui/private-theming@5.16.6': resolution: {integrity: sha512-rAk+Rh8Clg7Cd7shZhyt2HGTTE5wYKNSJ5sspf28Fqm/PZ69Er9o6KX25g03/FG2dfpg5GCwZh/xOojiTfm3hw==} @@ -3227,62 +3235,62 @@ packages: resolution: {integrity: sha512-q3L9i3HoNfz0SGpTIS4zTcKBbRkxzCRpd169eyiTuk3IwcPC3/85mzLHranlKo2b+HYT0gu37YxGB45aD8A3Tw==} engines: {node: '>=18.0.0'} - '@next/env@14.2.15': - resolution: {integrity: sha512-S1qaj25Wru2dUpcIZMjxeMVSwkt8BK4dmWHHiBuRstcIyOsMapqT4A4jSB6onvqeygkSSmOkyny9VVx8JIGamQ==} + '@next/env@14.2.16': + resolution: {integrity: sha512-fLrX5TfJzHCbnZ9YUSnGW63tMV3L4nSfhgOQ0iCcX21Pt+VSTDuaLsSuL8J/2XAiVA5AnzvXDpf6pMs60QxOag==} - '@next/eslint-plugin-next@14.2.15': - resolution: {integrity: sha512-pKU0iqKRBlFB/ocOI1Ip2CkKePZpYpnw5bEItEkuZ/Nr9FQP1+p7VDWr4VfOdff4i9bFmrOaeaU1bFEyAcxiMQ==} + '@next/eslint-plugin-next@15.0.2': + resolution: {integrity: sha512-R9Jc7T6Ge0txjmqpPwqD8vx6onQjynO9JT73ArCYiYPvSrwYXepH/UY/WdKDY8JPWJl72sAE4iGMHPeQ5xdEWg==} - '@next/swc-darwin-arm64@14.2.15': - resolution: {integrity: sha512-Rvh7KU9hOUBnZ9TJ28n2Oa7dD9cvDBKua9IKx7cfQQ0GoYUwg9ig31O2oMwH3wm+pE3IkAQ67ZobPfEgurPZIA==} + '@next/swc-darwin-arm64@14.2.16': + resolution: {integrity: sha512-uFT34QojYkf0+nn6MEZ4gIWQ5aqGF11uIZ1HSxG+cSbj+Mg3+tYm8qXYd3dKN5jqKUm5rBVvf1PBRO/MeQ6rxw==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@next/swc-darwin-x64@14.2.15': - resolution: {integrity: sha512-5TGyjFcf8ampZP3e+FyCax5zFVHi+Oe7sZyaKOngsqyaNEpOgkKB3sqmymkZfowy3ufGA/tUgDPPxpQx931lHg==} + '@next/swc-darwin-x64@14.2.16': + resolution: {integrity: sha512-mCecsFkYezem0QiZlg2bau3Xul77VxUD38b/auAjohMA22G9KTJneUYMv78vWoCCFkleFAhY1NIvbyjj1ncG9g==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@next/swc-linux-arm64-gnu@14.2.15': - resolution: {integrity: sha512-3Bwv4oc08ONiQ3FiOLKT72Q+ndEMyLNsc/D3qnLMbtUYTQAmkx9E/JRu0DBpHxNddBmNT5hxz1mYBphJ3mfrrw==} + '@next/swc-linux-arm64-gnu@14.2.16': + resolution: {integrity: sha512-yhkNA36+ECTC91KSyZcgWgKrYIyDnXZj8PqtJ+c2pMvj45xf7y/HrgI17hLdrcYamLfVt7pBaJUMxADtPaczHA==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@next/swc-linux-arm64-musl@14.2.15': - resolution: {integrity: sha512-k5xf/tg1FBv/M4CMd8S+JL3uV9BnnRmoe7F+GWC3DxkTCD9aewFRH1s5rJ1zkzDa+Do4zyN8qD0N8c84Hu96FQ==} + '@next/swc-linux-arm64-musl@14.2.16': + resolution: {integrity: sha512-X2YSyu5RMys8R2lA0yLMCOCtqFOoLxrq2YbazFvcPOE4i/isubYjkh+JCpRmqYfEuCVltvlo+oGfj/b5T2pKUA==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@next/swc-linux-x64-gnu@14.2.15': - resolution: {integrity: sha512-kE6q38hbrRbKEkkVn62reLXhThLRh6/TvgSP56GkFNhU22TbIrQDEMrO7j0IcQHcew2wfykq8lZyHFabz0oBrA==} + '@next/swc-linux-x64-gnu@14.2.16': + resolution: {integrity: sha512-9AGcX7VAkGbc5zTSa+bjQ757tkjr6C/pKS7OK8cX7QEiK6MHIIezBLcQ7gQqbDW2k5yaqba2aDtaBeyyZh1i6Q==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@next/swc-linux-x64-musl@14.2.15': - resolution: {integrity: sha512-PZ5YE9ouy/IdO7QVJeIcyLn/Rc4ml9M2G4y3kCM9MNf1YKvFY4heg3pVa/jQbMro+tP6yc4G2o9LjAz1zxD7tQ==} + '@next/swc-linux-x64-musl@14.2.16': + resolution: {integrity: sha512-Klgeagrdun4WWDaOizdbtIIm8khUDQJ/5cRzdpXHfkbY91LxBXeejL4kbZBrpR/nmgRrQvmz4l3OtttNVkz2Sg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@next/swc-win32-arm64-msvc@14.2.15': - resolution: {integrity: sha512-2raR16703kBvYEQD9HNLyb0/394yfqzmIeyp2nDzcPV4yPjqNUG3ohX6jX00WryXz6s1FXpVhsCo3i+g4RUX+g==} + '@next/swc-win32-arm64-msvc@14.2.16': + resolution: {integrity: sha512-PwW8A1UC1Y0xIm83G3yFGPiOBftJK4zukTmk7DI1CebyMOoaVpd8aSy7K6GhobzhkjYvqS/QmzcfsWG2Dwizdg==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@next/swc-win32-ia32-msvc@14.2.15': - resolution: {integrity: sha512-fyTE8cklgkyR1p03kJa5zXEaZ9El+kDNM5A+66+8evQS5e/6v0Gk28LqA0Jet8gKSOyP+OTm/tJHzMlGdQerdQ==} + '@next/swc-win32-ia32-msvc@14.2.16': + resolution: {integrity: sha512-jhPl3nN0oKEshJBNDAo0etGMzv0j3q3VYorTSFqH1o3rwv1MQRdor27u1zhkgsHPNeY1jxcgyx1ZsCkDD1IHgg==} engines: {node: '>= 10'} cpu: [ia32] os: [win32] - '@next/swc-win32-x64-msvc@14.2.15': - resolution: {integrity: sha512-SzqGbsLsP9OwKNUG9nekShTwhj6JSB9ZLMWQ8g1gG6hdE5gQLncbnbymrwy2yVmH9nikSLYRYxYMFu78Ggp7/g==} + '@next/swc-win32-x64-msvc@14.2.16': + resolution: {integrity: sha512-OA7NtfxgirCjfqt+02BqxC3MIgM/JaGjw9tOe4fyZgPsqfseNiMPnCRP44Pfs+Gpo9zPN+SXaFsgP6vk8d571A==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -3928,15 +3936,15 @@ packages: '@swc/types@0.1.13': resolution: {integrity: sha512-JL7eeCk6zWCbiYQg2xQSdLXQJl8Qoc9rXmG2cEKvHe3CKwMHwHGpfOb8frzNLmbycOo6I51qxnLnn9ESf4I20Q==} - '@tanstack/query-core@5.59.13': - resolution: {integrity: sha512-Oou0bBu/P8+oYjXsJQ11j+gcpLAMpqW42UlokQYEz4dE7+hOtVO9rVuolJKgEccqzvyFzqX4/zZWY+R/v1wVsQ==} + '@tanstack/query-core@5.59.16': + resolution: {integrity: sha512-crHn+G3ltqb5JG0oUv6q+PMz1m1YkjpASrXTU+sYWW9pLk0t2GybUHNRqYPZWhxgjPaVGC4yp92gSFEJgYEsPw==} '@testing-library/dom@10.4.0': resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==} engines: {node: '>=18'} - '@testing-library/jest-dom@6.5.0': - resolution: {integrity: sha512-xGGHpBXYSHUUr6XsKBfs85TWlYKpTc37cSBBVrXcib2MkHLboWlkClhWF37JKlDb9KEq3dHs+f2xR7XJEWGBxA==} + '@testing-library/jest-dom@6.6.2': + resolution: {integrity: sha512-P6GJD4yqc9jZLbe98j/EkyQDTPgqftohZF5FBkHY5BUERZmcf4HeO2k0XaefEg329ux2p21i1A1DmyQ1kKw2Jw==} engines: {node: '>=14', npm: '>=6', yarn: '>=1'} '@testing-library/react@16.0.1': @@ -4098,11 +4106,11 @@ packages: '@types/jsonwebtoken@8.5.9': resolution: {integrity: sha512-272FMnFGzAVMGtu9tkr29hRL6bZj4Zs1KZNeHLnKqAvp06tAIcarTMwOh8/8bz4FmKRcMxZhZNeUAQsNLoiPhg==} - '@types/karma@6.3.8': - resolution: {integrity: sha512-+QGoOPhb1f6Oli8pG+hxdnGDzVhIrpsHaFSJ4UJg15Xj+QBtluKELkJY+L4Li532HmT3l5K5o1FoUZHRQeOOaQ==} + '@types/karma@6.3.9': + resolution: {integrity: sha512-sjE/MHnoAZAQYAKRXAbjTOiBKyGGErEM725bruRcmDdMa2vp1bjWPhApI7/i564PTyHlzc3vIGXLL6TFIpAxFg==} - '@types/lodash@4.17.10': - resolution: {integrity: sha512-YpS0zzoduEhuOWjAotS6A5AVCva7X4lVlYLF0FYHAY9sdraBfnatttHItlWeZdGhuEkf+OzMNg2ZYAx8t+52uQ==} + '@types/lodash@4.17.12': + resolution: {integrity: sha512-sviUmCE8AYdaF/KIHLDJBQgeYzPBI0vf/17NaYehBJfYD1j6/L95Slh07NlyK2iNyBNaEkb3En2jRt+a8y3xZQ==} '@types/luxon@3.4.2': resolution: {integrity: sha512-TifLZlFudklWlMBfhubvgqTXRzLDI5pCbGa4P8a3wPyUQSW+1xQ5eDsreP9DWHX3tjq1ke96uYG/nwundroWcA==} @@ -4134,8 +4142,8 @@ packages: '@types/ms@0.7.34': resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} - '@types/node@20.16.11': - resolution: {integrity: sha512-y+cTCACu92FyA5fgQSAI8A1H429g7aSK2HsO7K4XYUWc4dY5IUz55JSDIYT6/VsOLfGy8vmvQYC2hfb0iF16Uw==} + '@types/node@20.17.3': + resolution: {integrity: sha512-tSQrmKKatLDGnG92h40GD7FzUt0MjahaHwOME4VAFeeA/Xopayq5qLyQRy7Jg/pjgKIFBXuKcGhJo+UdYG55jQ==} '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} @@ -4311,19 +4319,19 @@ packages: peerDependencies: vite: ^4 || ^5 - '@vitejs/plugin-react@4.3.2': - resolution: {integrity: sha512-hieu+o05v4glEBucTcKMK3dlES0OeJlD9YVOAPraVMOInBCwzumaIFiUjr4bHK7NPgnAHgiskUoceKercrN8vg==} + '@vitejs/plugin-react@4.3.3': + resolution: {integrity: sha512-NooDe9GpHGqNns1i8XDERg0Vsg5SSYRhRxxyTGogUdkdNt47jal+fbuYi+Yfq6pzRCKXyoPcWisfxE6RIM3GKA==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: vite: ^4.2.0 || ^5.0.0 - '@vitest/expect@2.1.2': - resolution: {integrity: sha512-FEgtlN8mIUSEAAnlvn7mP8vzaWhEaAEvhSXCqrsijM7K6QqjB11qoRZYEd4AKSCDz8p0/+yH5LzhZ47qt+EyPg==} + '@vitest/expect@2.1.3': + resolution: {integrity: sha512-SNBoPubeCJhZ48agjXruCI57DvxcsivVDdWz+SSsmjTT4QN/DfHk3zB/xKsJqMs26bLZ/pNRLnCf0j679i0uWQ==} - '@vitest/mocker@2.1.2': - resolution: {integrity: sha512-ExElkCGMS13JAJy+812fw1aCv2QO/LBK6CyO4WOPAzLTmve50gydOlWhgdBJPx2ztbADUq3JVI0C5U+bShaeEA==} + '@vitest/mocker@2.1.3': + resolution: {integrity: sha512-eSpdY/eJDuOvuTA3ASzCjdithHa+GIF1L4PqtEELl6Qa3XafdMLBpBlZCIUCX2J+Q6sNmjmxtosAG62fK4BlqQ==} peerDependencies: - '@vitest/spy': 2.1.2 + '@vitest/spy': 2.1.3 msw: ^2.3.5 vite: ^5.0.0 peerDependenciesMeta: @@ -4332,25 +4340,25 @@ packages: vite: optional: true - '@vitest/pretty-format@2.1.2': - resolution: {integrity: sha512-FIoglbHrSUlOJPDGIrh2bjX1sNars5HbxlcsFKCtKzu4+5lpsRhOCVcuzp0fEhAGHkPZRIXVNzPcpSlkoZ3LuA==} + '@vitest/pretty-format@2.1.3': + resolution: {integrity: sha512-XH1XdtoLZCpqV59KRbPrIhFCOO0hErxrQCMcvnQete3Vibb9UeIOX02uFPfVn3Z9ZXsq78etlfyhnkmIZSzIwQ==} - '@vitest/runner@2.1.2': - resolution: {integrity: sha512-UCsPtvluHO3u7jdoONGjOSil+uON5SSvU9buQh3lP7GgUXHp78guN1wRmZDX4wGK6J10f9NUtP6pO+SFquoMlw==} + '@vitest/runner@2.1.3': + resolution: {integrity: sha512-JGzpWqmFJ4fq5ZKHtVO3Xuy1iF2rHGV4d/pdzgkYHm1+gOzNZtqjvyiaDGJytRyMU54qkxpNzCx+PErzJ1/JqQ==} - '@vitest/snapshot@2.1.2': - resolution: {integrity: sha512-xtAeNsZ++aRIYIUsek7VHzry/9AcxeULlegBvsdLncLmNCR6tR8SRjn8BbDP4naxtccvzTqZ+L1ltZlRCfBZFA==} + '@vitest/snapshot@2.1.3': + resolution: {integrity: sha512-qWC2mWc7VAXmjAkEKxrScWHWFyCQx/cmiZtuGqMi+WwqQJ2iURsVY4ZfAK6dVo6K2smKRU6l3BPwqEBvhnpQGg==} - '@vitest/spy@2.1.2': - resolution: {integrity: sha512-GSUi5zoy+abNRJwmFhBDC0yRuVUn8WMlQscvnbbXdKLXX9dE59YbfwXxuJ/mth6eeqIzofU8BB5XDo/Ns/qK2A==} + '@vitest/spy@2.1.3': + resolution: {integrity: sha512-Nb2UzbcUswzeSP7JksMDaqsI43Sj5+Kry6ry6jQJT4b5gAK+NS9NED6mDb8FlMRCX8m5guaHCDZmqYMMWRy5nQ==} - '@vitest/ui@2.1.2': - resolution: {integrity: sha512-92gcNzkDnmxOxyHzQrQYRsoV9Q0Aay0r4QMLnV+B+lbqlUWa8nDg9ivyLV5mMVTtGirHsYUGGh/zbIA55gBZqA==} + '@vitest/ui@2.1.3': + resolution: {integrity: sha512-2XwTrHVJw3t9NYES26LQUYy51ZB8W4bRPgqUH2Eyda3kIuOlYw1ZdPNU22qcVlUVx4WKgECFQOSXuopsczuVjQ==} peerDependencies: - vitest: 2.1.2 + vitest: 2.1.3 - '@vitest/utils@2.1.2': - resolution: {integrity: sha512-zMO2KdYy6mx56btx9JvAqAZ6EyS3g49krMPPrgOp1yxGZiA93HumGk+bZ5jIZtOg5/VBYl5eBmGRQHqq4FG6uQ==} + '@vitest/utils@2.1.3': + resolution: {integrity: sha512-xpiVfDSg1RrYT0tX6czgerkpcKFmFOF/gCr30+Mve5V2kewCy4Prn1/NDMSRwaSmT7PRaOF83wu+bEtsY1wrvA==} '@webassemblyjs/ast@1.12.1': resolution: {integrity: sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==} @@ -4609,12 +4617,13 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - aria-query@5.1.3: - resolution: {integrity: sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==} - aria-query@5.3.0: resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + aria-query@5.3.2: + resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} + engines: {node: '>= 0.4'} + array-buffer-byte-length@1.0.1: resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} engines: {node: '>= 0.4'} @@ -4728,12 +4737,12 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} - axe-core@4.10.0: - resolution: {integrity: sha512-Mr2ZakwQ7XUAjp7pAwQWRhhK8mQQ6JAaNWSjmjxil0R8BPioMtQsTLOolGYkji1rcL++3dCqZA3zWqpT+9Ew6g==} + axe-core@4.10.2: + resolution: {integrity: sha512-RE3mdQ7P3FRSe7eqCWoeQ/Z9QXrtniSjp1wUjt5nRC3WIpz5rSCve6o3fsZ2aCpJtrZjSZgjwXAoTO5k4tEI0w==} engines: {node: '>=4'} - axios@1.7.5: - resolution: {integrity: sha512-fZu86yCo+svH3uqJ/yTdQ0QHpQu5oL+/QE+QPSv6BZSkDAoky9vytxp7u5qk83OJFS3kEBcesWni9WTZAv3tSw==} + axios@1.7.7: + resolution: {integrity: sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==} axobject-query@4.1.0: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} @@ -5507,8 +5516,8 @@ packages: supports-color: optional: true - debug@4.3.6: - resolution: {integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==} + debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' @@ -5550,10 +5559,6 @@ packages: resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} engines: {node: '>=6'} - deep-equal@2.2.3: - resolution: {integrity: sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==} - engines: {node: '>= 0.4'} - deep-extend@0.6.0: resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} engines: {node: '>=4.0.0'} @@ -5792,8 +5797,8 @@ packages: es-get-iterator@1.1.3: resolution: {integrity: sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==} - es-iterator-helpers@1.0.19: - resolution: {integrity: sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==} + es-iterator-helpers@1.1.0: + resolution: {integrity: sha512-/SurEfycdyssORP/E+bj4sEu1CWw4EmLDsHynHwSXQ7utgbrMRWW195pTrCjFgFCddf/UkYm3oqKPRq5i8bJbw==} engines: {node: '>= 0.4'} es-module-lexer@1.5.4: @@ -5927,14 +5932,14 @@ packages: '@typescript-eslint/parser': optional: true - eslint-plugin-jsdoc@50.4.1: - resolution: {integrity: sha512-OXIq+JJQPCLAKL473/esioFOwbXyRE5MAQ4HbZjcp3e+K3zdxt2uDpGs3FR+WezUXNStzEtTfgx15T+JFrVwBA==} + eslint-plugin-jsdoc@50.4.3: + resolution: {integrity: sha512-uWtwFxGRv6B8sU63HZM5dAGDhgsatb+LONwmILZJhdRALLOkCX2HFZhdL/Kw2ls8SQMAVEfK+LmnEfxInRN8HA==} engines: {node: '>=18'} peerDependencies: eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 - eslint-plugin-jsx-a11y@6.10.0: - resolution: {integrity: sha512-ySOHvXX8eSN6zz8Bywacm7CvGNhUtdjvqfQDVe6020TUK34Cywkw7m0KsCCk1Qtm9G1FayfTN1/7mMYnYO2Bhg==} + eslint-plugin-jsx-a11y@6.10.2: + resolution: {integrity: sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==} engines: {node: '>=4.0'} peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 @@ -5971,17 +5976,17 @@ packages: peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 - eslint-plugin-react@7.37.1: - resolution: {integrity: sha512-xwTnwDqzbDRA8uJ7BMxPs/EXRB3i8ZfnOIp8BsxEQkT0nHPp+WWceqGgo6rKb9ctNi8GJLDT4Go5HAWELa/WMg==} + eslint-plugin-react@7.37.2: + resolution: {integrity: sha512-EsTAnj9fLVr/GZleBLFbj/sSuXeWmp1eXIN60ceYnZveqEaUCyW4X+Vh4WTdUhCkW4xutXYqTXCUSyqD4rB75w==} engines: {node: '>=4'} peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 - eslint-plugin-testing-library@6.3.0: - resolution: {integrity: sha512-GYcEErTt6EGwE0bPDY+4aehfEBpB2gDBFKohir8jlATSUvzStEyzCx8QWB/14xeKc/AwyXkzScSzMHnFojkWrA==} + eslint-plugin-testing-library@6.4.0: + resolution: {integrity: sha512-yeWF+YgCgvNyPNI9UKnG0FjeE2sk93N/3lsKqcmR8dSfeXJwFT5irnWo7NjLf152HkRzfoFjh3LsBUrhvFz4eA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0, npm: '>=6'} peerDependencies: - eslint: ^7.5.0 || ^8.0.0 + eslint: ^7.5.0 || ^8.0.0 || ^9.0.0 eslint-scope@5.1.1: resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} @@ -6093,8 +6098,8 @@ packages: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} - execa@9.4.0: - resolution: {integrity: sha512-yKHlle2YGxZE842MERVIplWwNH5VYmqqcPFgtnlU//K8gxuFFXu0pwd/CrfXTumFpeEiufsP7+opT/bPJa1yVw==} + execa@9.4.1: + resolution: {integrity: sha512-5eo/BRqZm3GYce+1jqX/tJ7duA2AnE39i88fuedNFUV8XxGxUpF3aWkBRfbUcjV49gCkvS/pzc0YrCPhaIewdg==} engines: {node: ^18.19.0 || >=20.5.0} expand-tilde@2.0.2: @@ -6129,6 +6134,10 @@ packages: fast-diff@1.3.0: resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} + fast-glob@3.3.1: + resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} + engines: {node: '>=8.6.0'} + fast-glob@3.3.2: resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} engines: {node: '>=8.6.0'} @@ -6142,9 +6151,6 @@ packages: fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - fast-url-parser@1.1.3: - resolution: {integrity: sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==} - fastest-levenshtein@1.0.16: resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} engines: {node: '>= 4.9.1'} @@ -6485,8 +6491,8 @@ packages: resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} engines: {node: '>=8'} - globalthis@1.0.3: - resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} engines: {node: '>= 0.4'} globby@11.1.0: @@ -6628,8 +6634,8 @@ packages: resolution: {integrity: sha512-QY6S+hZ0f5m1WT8WffYN+Hg+xm/w5I8XeUcAq/ZYP5wVC8xbKi4Whhru3FtrAebD5EhBW8rmFzkDI6eCAuFe2w==} hasBin: true - html-webpack-plugin@5.6.0: - resolution: {integrity: sha512-iwaY4wzbe48AfKLZ/Cc8k0L+FKG6oSNRaZ8x5A/T/IVDGyXcbHncM9TdDa93wn0FsSm82FhTKW7f3vS61thXAw==} + html-webpack-plugin@5.6.3: + resolution: {integrity: sha512-QSf1yjtSAsmf7rYBV7XX86uua4W/vkhIt0xNXKbsi2foEeW7vjJQz4bhnpL3xH+l1ryl1680uNv968Z+X6jSYg==} engines: {node: '>=10.13.0'} peerDependencies: '@rspack/core': 0.x || 1.x @@ -7049,8 +7055,9 @@ packages: iterate-value@1.0.2: resolution: {integrity: sha512-A6fMAio4D2ot2r/TYzr4yUWrmwNdsN5xL7+HUiyACE4DXm+q8HtPcnFTp+NnW3k4N05tZ7FVYFFb2CR13NxyHQ==} - iterator.prototype@1.1.2: - resolution: {integrity: sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==} + iterator.prototype@1.1.3: + resolution: {integrity: sha512-FW5iMbeQ6rBGm/oKgzq2aW4KvAGpxPzYES8N4g4xNXUKpL1mclMvOe+76AcLDTvD+Ze+sOpVhgdAQEKF4L9iGQ==} + engines: {node: '>= 0.4'} jackspeak@2.3.6: resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} @@ -7847,9 +7854,6 @@ packages: ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} - ms@2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -7888,8 +7892,8 @@ packages: nested-error-stacks@2.1.1: resolution: {integrity: sha512-9iN1ka/9zmX1ZvLV9ewJYEk9h7RyRRtqdK0woXcqohu8EWIerfPUjYJPg0ULy0UqP7cslmdGc8xKDJcojlKiaw==} - next@14.2.15: - resolution: {integrity: sha512-h9ctmOokpoDphRvMGnwOJAedT6zKhwqyZML9mDtspgf4Rh3Pn7UTYKqePNoDvhsWBAO5GoPNYshnAUGIazVGmw==} + next@14.2.16: + resolution: {integrity: sha512-LcO7WnFu6lYSvCzZoo1dB+IO0xXz5uEv52HF1IUN0IqVTUIZGHuuR10I5efiLadGt+4oZqTcNZyVVEem/TM5nA==} engines: {node: '>=18.17.0'} hasBin: true peerDependencies: @@ -8060,10 +8064,6 @@ packages: object-inspect@1.13.1: resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} - object-is@1.1.5: - resolution: {integrity: sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==} - engines: {node: '>= 0.4'} - object-keys@0.4.0: resolution: {integrity: sha512-ncrLw+X55z7bkl5PnUvHwFK9FcGuFYo9gtjws2XtSzL+aZ8tm830P60WJ0dSmFVaSalWieW5MD7kEdnXda9yJw==} @@ -8118,11 +8118,11 @@ packages: resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} engines: {node: '>=12'} - openapi-fetch@0.11.2: - resolution: {integrity: sha512-zc37VvX9vHJjJxNY3JLhg5Ks3J3KSL56NJrIAp2QRt/fdkOhGQHBTVY+Zz7tEOdqocS/1xfRTzWC6NguCGjUnA==} + openapi-fetch@0.13.0: + resolution: {integrity: sha512-6Nlf/BDbtyHwHdNrLPUiyt4CZMzL3ZyAt55yWH8W7+Z+8aYWnvca4uZHQHXViy8KcnCMqAhLM/bifh2Yjjkf6w==} - openapi-typescript-helpers@0.0.12: - resolution: {integrity: sha512-FO+5kTWO6KDutigamr2MRwciYkAUYhqdctlyVRrQOe2uxif2/O2+GcS07jNnP36AUK6ubSsGu3GeBiYIc6eQzA==} + openapi-typescript-helpers@0.0.15: + resolution: {integrity: sha512-opyTPaunsklCBpTK8JGef6mfPhLSnyy5a0IN9vKtx3+4aExf+KxEqYwIy3hqkedXIB97u357uLMJsOnm3GVjsw==} opener@1.5.2: resolution: {integrity: sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==} @@ -8373,8 +8373,8 @@ packages: path-to-regexp@0.1.10: resolution: {integrity: sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==} - path-to-regexp@2.2.1: - resolution: {integrity: sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ==} + path-to-regexp@3.3.0: + resolution: {integrity: sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==} path-to-regexp@6.2.1: resolution: {integrity: sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==} @@ -8464,8 +8464,8 @@ packages: engines: {node: '>=16'} hasBin: true - playwright-core@1.47.2: - resolution: {integrity: sha512-3JvMfF+9LJfe16l7AbSmU555PaTl2tPyQsVInqm3id16pdDfvZ8TTZ/pyzmkbDrZTQefyzU7AIHlZqQnxpqHVQ==} + playwright-core@1.48.2: + resolution: {integrity: sha512-sjjw+qrLFlriJo64du+EK0kJgZzoQPsabGF4lBvsid+3CNIZIYLgnMj9V6JY5VhM2Peh20DJWIVpVljLLnlawA==} engines: {node: '>=18'} hasBin: true @@ -8474,8 +8474,8 @@ packages: engines: {node: '>=16'} hasBin: true - playwright@1.47.2: - resolution: {integrity: sha512-nx1cLMmQWqmA3UsnjaaokyoUpdVaaDhJhMoxX2qj3McpjnsqFHs516QAKYhqHAgOP+oCFTEOCOAaD1RgD/RQfA==} + playwright@1.48.2: + resolution: {integrity: sha512-NjYvYgp4BPmiwfe31j4gHLa3J7bD2WiBz8Lk2RoSsmX38SVIARZ18VYjxLjAcDsAhA+F4iSEXTSGgjua0rrlgQ==} engines: {node: '>=18'} hasBin: true @@ -8621,9 +8621,6 @@ packages: resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} engines: {node: '>=6'} - punycode@1.4.1: - resolution: {integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==} - punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -8678,8 +8675,8 @@ packages: peerDependencies: react: ^18.3.1 - react-hook-form@7.53.0: - resolution: {integrity: sha512-M1n3HhqCww6S2hxLxciEXy2oISPnAzxY7gvwVPrtlczTM/1dDadXgUxDpHMrMTblDOcm/AXtXxHwZ3jpg1mqKQ==} + react-hook-form@7.53.1: + resolution: {integrity: sha512-6aiQeBda4zjcuaugWvim9WsGqisoUk+etmFEsSUMm451/Ic8L/UAb7sRtMj3V+Hdzm6mMjU1VhiSzYUZeBm0Vg==} engines: {node: '>=18.0.0'} peerDependencies: react: ^16.8.0 || ^17 || ^18 || ^19 @@ -8922,6 +8919,11 @@ packages: rfdc@1.3.1: resolution: {integrity: sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==} + rifm@0.12.1: + resolution: {integrity: sha512-OGA1Bitg/dSJtI/c4dh90svzaUPt228kzFsUkJbtA2c964IqEAwWXeL9ZJi86xWv3j5SMqRvGULl7bA6cK0Bvg==} + peerDependencies: + react: '>=16.8' + rimraf@2.6.3: resolution: {integrity: sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==} deprecated: Rimraf versions prior to v4 are no longer supported @@ -9038,15 +9040,15 @@ packages: serialize-javascript@6.0.2: resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} - serve-handler@6.1.5: - resolution: {integrity: sha512-ijPFle6Hwe8zfmBxJdE+5fta53fdIY0lHISJvuikXB3VYFafRjMRpOffSPvCYsbKyBA7pvy9oYr/BT1O3EArlg==} + serve-handler@6.1.6: + resolution: {integrity: sha512-x5RL9Y2p5+Sh3D38Fh9i/iQ5ZK+e4xuXRd/pGbM4D13tgo/MGwbttUk8emytcr1YYzBYs+apnUngBDFYfpjPuQ==} serve-static@1.16.2: resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==} engines: {node: '>= 0.8.0'} - serve@14.2.3: - resolution: {integrity: sha512-VqUFMC7K3LDGeGnJM9h56D3XGKb6KGgOw0cVNtA26yYXHCcpxf3xwCTUaQoWlVS7i8Jdh3GjQkOB23qsXyjoyQ==} + serve@14.2.4: + resolution: {integrity: sha512-qy1S34PJ/fcY8gjVGszDB3EXiPSk5FKhUa7tQe0UPRddxRidc2V6cNHPNewbE1D7MAkgLuWEt3Vw56vYy73tzQ==} engines: {node: '>= 14'} hasBin: true @@ -9256,8 +9258,9 @@ packages: resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} engines: {node: '>=12'} - string.prototype.includes@2.0.0: - resolution: {integrity: sha512-E34CkBgyeqNDcrbU76cDjL5JLcVrtSdYq0MEh/B10r17pRP4ciHLwTgnuLV8Ay6cgEMLkcBkFCKyFZ43YldYzg==} + string.prototype.includes@2.0.1: + resolution: {integrity: sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==} + engines: {node: '>= 0.4'} string.prototype.matchall@4.0.11: resolution: {integrity: sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==} @@ -9505,10 +9508,6 @@ packages: resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==} engines: {node: '>=14.14'} - to-fast-properties@2.0.0: - resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} - engines: {node: '>=4'} - to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -9582,8 +9581,8 @@ packages: peerDependencies: typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' - tsx@4.19.1: - resolution: {integrity: sha512-0flMz1lh74BR4wOvBjuh9olbnwqCPc35OOlfyzHba0Dc+QNUeWX/Gq2YTbnwcWPO3BMd8fkzRVrHcsR+a7z7rA==} + tsx@4.19.2: + resolution: {integrity: sha512-pOUl6Vo2LUq/bSa8S5q7b91cgNSjctn9ugq/+Mvow99qW6x/UZYwzxy/3NmqoT66eHYfCVvFvACC58UBPFf28g==} engines: {node: '>=18.0.0'} hasBin: true @@ -9842,8 +9841,8 @@ packages: vfile@6.0.3: resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} - vite-node@2.1.2: - resolution: {integrity: sha512-HPcGNN5g/7I2OtPjLqgOtCRu/qhVvBxTUD3qzitmL0SrG1cWFzxzhMDWussxSbrRYWqnKf8P2jiNhPMSN+ymsQ==} + vite-node@2.1.3: + resolution: {integrity: sha512-I1JadzO+xYX887S39Do+paRePCKoiDrWRRjp9kkG5he0t7RXNvPAJPCQSJqbGN4uCrFFeS3Kj3sLqY8NMYBEdA==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true @@ -9852,7 +9851,7 @@ packages: engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: - '@types/node': ^20.16.11 + '@types/node': ^20.17.3 less: '*' lightningcss: ^1.21.0 sass: '*' @@ -9875,15 +9874,15 @@ packages: terser: optional: true - vitest@2.1.2: - resolution: {integrity: sha512-veNjLizOMkRrJ6xxb+pvxN6/QAWg95mzcRjtmkepXdN87FNfxAss9RKe2far/G9cQpipfgP2taqg0KiWsquj8A==} + vitest@2.1.3: + resolution: {integrity: sha512-Zrxbg/WiIvUP2uEzelDNTXmEMJXuzJ1kCpbDvaKByFA9MNeO95V+7r/3ti0qzJzrxdyuUw5VduN7k+D3VmVOSA==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' - '@types/node': ^20.16.11 - '@vitest/browser': 2.1.2 - '@vitest/ui': 2.1.2 + '@types/node': ^20.17.3 + '@vitest/browser': 2.1.3 + '@vitest/ui': 2.1.3 happy-dom: '*' jsdom: '*' peerDependenciesMeta: @@ -10326,31 +10325,31 @@ snapshots: '@jridgewell/gen-mapping': 0.3.5 '@jridgewell/trace-mapping': 0.3.25 - '@argos-ci/api-client@0.6.0': + '@argos-ci/api-client@0.7.0': dependencies: - debug: 4.3.6(supports-color@8.1.1) - openapi-fetch: 0.11.2 + debug: 4.3.7(supports-color@8.1.1) + openapi-fetch: 0.13.0 transitivePeerDependencies: - supports-color - '@argos-ci/core@2.9.0': + '@argos-ci/core@2.10.0': dependencies: - '@argos-ci/api-client': 0.6.0 - '@argos-ci/util': 2.1.1 - axios: 1.7.5(debug@4.3.6) + '@argos-ci/api-client': 0.7.0 + '@argos-ci/util': 2.2.0 + axios: 1.7.7(debug@4.3.7) convict: 6.2.4 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) fast-glob: 3.3.2 sharp: 0.33.5 tmp: 0.2.3 transitivePeerDependencies: - supports-color - '@argos-ci/util@2.1.1': {} + '@argos-ci/util@2.2.0': {} - '@babel/cli@7.25.7(@babel/core@7.25.8)': + '@babel/cli@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 + '@babel/core': 7.26.0 '@jridgewell/trace-mapping': 0.3.25 commander: 6.2.1 convert-source-map: 2.0.0 @@ -10362,834 +10361,834 @@ snapshots: '@nicolo-ribaudo/chokidar-2': 2.1.8-no-fsevents.3 chokidar: 3.6.0 - '@babel/code-frame@7.25.7': + '@babel/code-frame@7.26.0': dependencies: - '@babel/highlight': 7.25.7 + '@babel/helper-validator-identifier': 7.25.9 + js-tokens: 4.0.0 picocolors: 1.1.0 - '@babel/compat-data@7.25.8': {} + '@babel/compat-data@7.26.0': {} - '@babel/core@7.25.8': + '@babel/core@7.26.0': dependencies: '@ampproject/remapping': 2.3.0 - '@babel/code-frame': 7.25.7 - '@babel/generator': 7.25.7 - '@babel/helper-compilation-targets': 7.25.7 - '@babel/helper-module-transforms': 7.25.7(@babel/core@7.25.8) - '@babel/helpers': 7.25.7 - '@babel/parser': 7.25.8 - '@babel/template': 7.25.7 - '@babel/traverse': 7.25.7 - '@babel/types': 7.25.8 + '@babel/code-frame': 7.26.0 + '@babel/generator': 7.26.0 + '@babel/helper-compilation-targets': 7.25.9 + '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.0) + '@babel/helpers': 7.26.0 + '@babel/parser': 7.26.1 + '@babel/template': 7.25.9 + '@babel/traverse': 7.25.9 + '@babel/types': 7.26.0 convert-source-map: 2.0.0 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/generator@7.25.7': + '@babel/generator@7.26.0': dependencies: - '@babel/types': 7.25.8 + '@babel/parser': 7.26.1 + '@babel/types': 7.26.0 '@jridgewell/gen-mapping': 0.3.5 '@jridgewell/trace-mapping': 0.3.25 jsesc: 3.0.2 - '@babel/helper-annotate-as-pure@7.25.7': + '@babel/helper-annotate-as-pure@7.25.9': dependencies: - '@babel/types': 7.25.8 + '@babel/types': 7.26.0 - '@babel/helper-builder-binary-assignment-operator-visitor@7.25.7': + '@babel/helper-builder-binary-assignment-operator-visitor@7.25.9': dependencies: - '@babel/traverse': 7.25.7 - '@babel/types': 7.25.8 + '@babel/traverse': 7.25.9 + '@babel/types': 7.26.0 transitivePeerDependencies: - supports-color - '@babel/helper-compilation-targets@7.25.7': + '@babel/helper-compilation-targets@7.25.9': dependencies: - '@babel/compat-data': 7.25.8 - '@babel/helper-validator-option': 7.25.7 + '@babel/compat-data': 7.26.0 + '@babel/helper-validator-option': 7.25.9 browserslist: 4.24.0 lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-create-class-features-plugin@7.25.7(@babel/core@7.25.8)': + '@babel/helper-create-class-features-plugin@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-annotate-as-pure': 7.25.7 - '@babel/helper-member-expression-to-functions': 7.25.7 - '@babel/helper-optimise-call-expression': 7.25.7 - '@babel/helper-replace-supers': 7.25.7(@babel/core@7.25.8) - '@babel/helper-skip-transparent-expression-wrappers': 7.25.7 - '@babel/traverse': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-annotate-as-pure': 7.25.9 + '@babel/helper-member-expression-to-functions': 7.25.9 + '@babel/helper-optimise-call-expression': 7.25.9 + '@babel/helper-replace-supers': 7.25.9(@babel/core@7.26.0) + '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 + '@babel/traverse': 7.25.9 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/helper-create-regexp-features-plugin@7.25.7(@babel/core@7.25.8)': + '@babel/helper-create-regexp-features-plugin@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-annotate-as-pure': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-annotate-as-pure': 7.25.9 regexpu-core: 6.1.1 semver: 6.3.1 - '@babel/helper-define-polyfill-provider@0.6.2(@babel/core@7.25.8)': + '@babel/helper-define-polyfill-provider@0.6.2(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-compilation-targets': 7.25.7 - '@babel/helper-plugin-utils': 7.25.7 - debug: 4.3.6(supports-color@8.1.1) + '@babel/core': 7.26.0 + '@babel/helper-compilation-targets': 7.25.9 + '@babel/helper-plugin-utils': 7.25.9 + debug: 4.3.7(supports-color@8.1.1) lodash.debounce: 4.0.8 resolve: 1.22.8 transitivePeerDependencies: - supports-color - '@babel/helper-member-expression-to-functions@7.25.7': + '@babel/helper-member-expression-to-functions@7.25.9': dependencies: - '@babel/traverse': 7.25.7 - '@babel/types': 7.25.8 + '@babel/traverse': 7.25.9 + '@babel/types': 7.26.0 transitivePeerDependencies: - supports-color - '@babel/helper-module-imports@7.25.7': + '@babel/helper-module-imports@7.25.9': dependencies: - '@babel/traverse': 7.25.7 - '@babel/types': 7.25.8 + '@babel/traverse': 7.25.9 + '@babel/types': 7.26.0 transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.25.7(@babel/core@7.25.8)': + '@babel/helper-module-transforms@7.26.0(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-module-imports': 7.25.7 - '@babel/helper-simple-access': 7.25.7 - '@babel/helper-validator-identifier': 7.25.7 - '@babel/traverse': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-module-imports': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 + '@babel/traverse': 7.25.9 transitivePeerDependencies: - supports-color - '@babel/helper-optimise-call-expression@7.25.7': + '@babel/helper-optimise-call-expression@7.25.9': dependencies: - '@babel/types': 7.25.8 + '@babel/types': 7.26.0 - '@babel/helper-plugin-utils@7.25.7': {} + '@babel/helper-plugin-utils@7.25.9': {} - '@babel/helper-remap-async-to-generator@7.25.7(@babel/core@7.25.8)': + '@babel/helper-remap-async-to-generator@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-annotate-as-pure': 7.25.7 - '@babel/helper-wrap-function': 7.25.7 - '@babel/traverse': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-annotate-as-pure': 7.25.9 + '@babel/helper-wrap-function': 7.25.9 + '@babel/traverse': 7.25.9 transitivePeerDependencies: - supports-color - '@babel/helper-replace-supers@7.25.7(@babel/core@7.25.8)': + '@babel/helper-replace-supers@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-member-expression-to-functions': 7.25.7 - '@babel/helper-optimise-call-expression': 7.25.7 - '@babel/traverse': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-member-expression-to-functions': 7.25.9 + '@babel/helper-optimise-call-expression': 7.25.9 + '@babel/traverse': 7.25.9 transitivePeerDependencies: - supports-color - '@babel/helper-simple-access@7.25.7': + '@babel/helper-simple-access@7.25.9': dependencies: - '@babel/traverse': 7.25.7 - '@babel/types': 7.25.8 + '@babel/traverse': 7.25.9 + '@babel/types': 7.26.0 transitivePeerDependencies: - supports-color - '@babel/helper-skip-transparent-expression-wrappers@7.25.7': + '@babel/helper-skip-transparent-expression-wrappers@7.25.9': dependencies: - '@babel/traverse': 7.25.7 - '@babel/types': 7.25.8 + '@babel/traverse': 7.25.9 + '@babel/types': 7.26.0 transitivePeerDependencies: - supports-color - '@babel/helper-string-parser@7.25.7': {} + '@babel/helper-string-parser@7.25.9': {} - '@babel/helper-validator-identifier@7.25.7': {} + '@babel/helper-validator-identifier@7.25.9': {} - '@babel/helper-validator-option@7.25.7': {} + '@babel/helper-validator-option@7.25.9': {} - '@babel/helper-wrap-function@7.25.7': + '@babel/helper-wrap-function@7.25.9': dependencies: - '@babel/template': 7.25.7 - '@babel/traverse': 7.25.7 - '@babel/types': 7.25.8 + '@babel/template': 7.25.9 + '@babel/traverse': 7.25.9 + '@babel/types': 7.26.0 transitivePeerDependencies: - supports-color - '@babel/helpers@7.25.7': + '@babel/helpers@7.26.0': dependencies: - '@babel/template': 7.25.7 - '@babel/types': 7.25.8 + '@babel/template': 7.25.9 + '@babel/types': 7.26.0 - '@babel/highlight@7.25.7': + '@babel/node@7.26.0(@babel/core@7.26.0)': dependencies: - '@babel/helper-validator-identifier': 7.25.7 - chalk: 2.4.2 - js-tokens: 4.0.0 - picocolors: 1.1.0 - - '@babel/node@7.25.7(@babel/core@7.25.8)': - dependencies: - '@babel/core': 7.25.8 - '@babel/register': 7.25.7(@babel/core@7.25.8) + '@babel/core': 7.26.0 + '@babel/register': 7.25.9(@babel/core@7.26.0) commander: 6.2.1 core-js: 3.35.1 node-environment-flags: 1.0.6 regenerator-runtime: 0.14.1 v8flags: 3.2.0 - '@babel/parser@7.25.8': + '@babel/parser@7.26.1': dependencies: - '@babel/types': 7.25.8 + '@babel/types': 7.26.0 - '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 - '@babel/traverse': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 + '@babel/traverse': 7.25.9 transitivePeerDependencies: - supports-color - '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 - '@babel/helper-skip-transparent-expression-wrappers': 7.25.7 - '@babel/plugin-transform-optional-chaining': 7.25.8(@babel/core@7.25.8) + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 + '@babel/plugin-transform-optional-chaining': 7.25.9(@babel/core@7.26.0) transitivePeerDependencies: - supports-color - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 - '@babel/traverse': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 + '@babel/traverse': 7.25.9 transitivePeerDependencies: - supports-color - '@babel/plugin-proposal-private-methods@7.18.6(@babel/core@7.25.8)': + '@babel/plugin-proposal-private-methods@7.18.6(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-create-class-features-plugin': 7.25.7(@babel/core@7.25.8) - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-create-class-features-plugin': 7.25.9(@babel/core@7.26.0) + '@babel/helper-plugin-utils': 7.25.9 transitivePeerDependencies: - supports-color - '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.25.8)': + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 + '@babel/core': 7.26.0 - '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.25.8)': + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-syntax-flow@7.24.7(@babel/core@7.25.8)': + '@babel/plugin-syntax-flow@7.24.7(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-syntax-import-assertions@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-syntax-import-assertions@7.26.0(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-syntax-import-attributes@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-syntax-import-attributes@7.26.0(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-syntax-jsx@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-syntax-jsx@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-syntax-typescript@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-syntax-typescript@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.25.8)': + '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-create-regexp-features-plugin': 7.25.7(@babel/core@7.25.8) - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-create-regexp-features-plugin': 7.25.9(@babel/core@7.26.0) + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-transform-arrow-functions@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-transform-arrow-functions@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-transform-async-generator-functions@7.25.8(@babel/core@7.25.8)': + '@babel/plugin-transform-async-generator-functions@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 - '@babel/helper-remap-async-to-generator': 7.25.7(@babel/core@7.25.8) - '@babel/traverse': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-remap-async-to-generator': 7.25.9(@babel/core@7.26.0) + '@babel/traverse': 7.25.9 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-async-to-generator@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-transform-async-to-generator@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-module-imports': 7.25.7 - '@babel/helper-plugin-utils': 7.25.7 - '@babel/helper-remap-async-to-generator': 7.25.7(@babel/core@7.25.8) + '@babel/core': 7.26.0 + '@babel/helper-module-imports': 7.25.9 + '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-remap-async-to-generator': 7.25.9(@babel/core@7.26.0) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-block-scoped-functions@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-transform-block-scoped-functions@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-transform-block-scoping@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-transform-block-scoping@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-transform-class-properties@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-transform-class-properties@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-create-class-features-plugin': 7.25.7(@babel/core@7.25.8) - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-create-class-features-plugin': 7.25.9(@babel/core@7.26.0) + '@babel/helper-plugin-utils': 7.25.9 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-class-static-block@7.25.8(@babel/core@7.25.8)': + '@babel/plugin-transform-class-static-block@7.26.0(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-create-class-features-plugin': 7.25.7(@babel/core@7.25.8) - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-create-class-features-plugin': 7.25.9(@babel/core@7.26.0) + '@babel/helper-plugin-utils': 7.25.9 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-classes@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-transform-classes@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-annotate-as-pure': 7.25.7 - '@babel/helper-compilation-targets': 7.25.7 - '@babel/helper-plugin-utils': 7.25.7 - '@babel/helper-replace-supers': 7.25.7(@babel/core@7.25.8) - '@babel/traverse': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-annotate-as-pure': 7.25.9 + '@babel/helper-compilation-targets': 7.25.9 + '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-replace-supers': 7.25.9(@babel/core@7.26.0) + '@babel/traverse': 7.25.9 globals: 11.12.0 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-computed-properties@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-transform-computed-properties@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 - '@babel/template': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 + '@babel/template': 7.25.9 - '@babel/plugin-transform-destructuring@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-transform-destructuring@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-transform-dotall-regex@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-transform-dotall-regex@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-create-regexp-features-plugin': 7.25.7(@babel/core@7.25.8) - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-create-regexp-features-plugin': 7.25.9(@babel/core@7.26.0) + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-transform-duplicate-keys@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-transform-duplicate-keys@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-create-regexp-features-plugin': 7.25.7(@babel/core@7.25.8) - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-create-regexp-features-plugin': 7.25.9(@babel/core@7.26.0) + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-transform-dynamic-import@7.25.8(@babel/core@7.25.8)': + '@babel/plugin-transform-dynamic-import@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-transform-exponentiation-operator@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-transform-exponentiation-operator@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-builder-binary-assignment-operator-visitor': 7.25.7 - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-builder-binary-assignment-operator-visitor': 7.25.9 + '@babel/helper-plugin-utils': 7.25.9 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-export-namespace-from@7.25.8(@babel/core@7.25.8)': + '@babel/plugin-transform-export-namespace-from@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-transform-flow-strip-types@7.24.7(@babel/core@7.25.8)': + '@babel/plugin-transform-flow-strip-types@7.24.7(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-syntax-flow': 7.24.7(@babel/core@7.25.8) + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 + '@babel/plugin-syntax-flow': 7.24.7(@babel/core@7.26.0) - '@babel/plugin-transform-for-of@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-transform-for-of@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 - '@babel/helper-skip-transparent-expression-wrappers': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-function-name@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-transform-function-name@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-compilation-targets': 7.25.7 - '@babel/helper-plugin-utils': 7.25.7 - '@babel/traverse': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-compilation-targets': 7.25.9 + '@babel/helper-plugin-utils': 7.25.9 + '@babel/traverse': 7.25.9 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-json-strings@7.25.8(@babel/core@7.25.8)': + '@babel/plugin-transform-json-strings@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-transform-literals@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-transform-literals@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-transform-logical-assignment-operators@7.25.8(@babel/core@7.25.8)': + '@babel/plugin-transform-logical-assignment-operators@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-transform-member-expression-literals@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-transform-member-expression-literals@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-transform-modules-amd@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-transform-modules-amd@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-module-transforms': 7.25.7(@babel/core@7.25.8) - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.0) + '@babel/helper-plugin-utils': 7.25.9 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-commonjs@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-transform-modules-commonjs@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-module-transforms': 7.25.7(@babel/core@7.25.8) - '@babel/helper-plugin-utils': 7.25.7 - '@babel/helper-simple-access': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.0) + '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-simple-access': 7.25.9 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-systemjs@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-transform-modules-systemjs@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-module-transforms': 7.25.7(@babel/core@7.25.8) - '@babel/helper-plugin-utils': 7.25.7 - '@babel/helper-validator-identifier': 7.25.7 - '@babel/traverse': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.0) + '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 + '@babel/traverse': 7.25.9 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-umd@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-transform-modules-umd@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-module-transforms': 7.25.7(@babel/core@7.25.8) - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.0) + '@babel/helper-plugin-utils': 7.25.9 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-named-capturing-groups-regex@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-transform-named-capturing-groups-regex@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-create-regexp-features-plugin': 7.25.7(@babel/core@7.25.8) - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-create-regexp-features-plugin': 7.25.9(@babel/core@7.26.0) + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-transform-new-target@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-transform-new-target@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-transform-nullish-coalescing-operator@7.25.8(@babel/core@7.25.8)': + '@babel/plugin-transform-nullish-coalescing-operator@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-transform-numeric-separator@7.25.8(@babel/core@7.25.8)': + '@babel/plugin-transform-numeric-separator@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-transform-object-rest-spread@7.25.8(@babel/core@7.25.8)': + '@babel/plugin-transform-object-rest-spread@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-compilation-targets': 7.25.7 - '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-parameters': 7.25.7(@babel/core@7.25.8) + '@babel/core': 7.26.0 + '@babel/helper-compilation-targets': 7.25.9 + '@babel/helper-plugin-utils': 7.25.9 + '@babel/plugin-transform-parameters': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-object-super@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-transform-object-super@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 - '@babel/helper-replace-supers': 7.25.7(@babel/core@7.25.8) + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-replace-supers': 7.25.9(@babel/core@7.26.0) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-optional-catch-binding@7.25.8(@babel/core@7.25.8)': + '@babel/plugin-transform-optional-catch-binding@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-transform-optional-chaining@7.25.8(@babel/core@7.25.8)': + '@babel/plugin-transform-optional-chaining@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 - '@babel/helper-skip-transparent-expression-wrappers': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-parameters@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-transform-parameters@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-transform-private-methods@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-transform-private-methods@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-create-class-features-plugin': 7.25.7(@babel/core@7.25.8) - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-create-class-features-plugin': 7.25.9(@babel/core@7.26.0) + '@babel/helper-plugin-utils': 7.25.9 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-private-property-in-object@7.25.8(@babel/core@7.25.8)': + '@babel/plugin-transform-private-property-in-object@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-annotate-as-pure': 7.25.7 - '@babel/helper-create-class-features-plugin': 7.25.7(@babel/core@7.25.8) - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-annotate-as-pure': 7.25.9 + '@babel/helper-create-class-features-plugin': 7.25.9(@babel/core@7.26.0) + '@babel/helper-plugin-utils': 7.25.9 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-property-literals@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-transform-property-literals@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-transform-react-constant-elements@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-transform-react-constant-elements@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-transform-react-display-name@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-transform-react-display-name@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-transform-react-jsx-development@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-transform-react-jsx-development@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/plugin-transform-react-jsx': 7.25.7(@babel/core@7.25.8) + '@babel/core': 7.26.0 + '@babel/plugin-transform-react-jsx': 7.25.9(@babel/core@7.26.0) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-react-jsx-self@7.24.7(@babel/core@7.25.8)': + '@babel/plugin-transform-react-jsx-self@7.24.7(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-transform-react-jsx-source@7.24.7(@babel/core@7.25.8)': + '@babel/plugin-transform-react-jsx-source@7.24.7(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-transform-react-jsx@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-annotate-as-pure': 7.25.7 - '@babel/helper-module-imports': 7.25.7 - '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-syntax-jsx': 7.25.7(@babel/core@7.25.8) - '@babel/types': 7.25.8 + '@babel/core': 7.26.0 + '@babel/helper-annotate-as-pure': 7.25.9 + '@babel/helper-module-imports': 7.25.9 + '@babel/helper-plugin-utils': 7.25.9 + '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.0) + '@babel/types': 7.26.0 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-react-pure-annotations@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-transform-react-pure-annotations@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-annotate-as-pure': 7.25.7 - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-annotate-as-pure': 7.25.9 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-transform-regenerator@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-transform-regenerator@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 regenerator-transform: 0.15.2 - '@babel/plugin-transform-reserved-words@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-transform-regexp-modifiers@7.26.0(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-create-regexp-features-plugin': 7.25.9(@babel/core@7.26.0) + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-transform-runtime@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-transform-reserved-words@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-module-imports': 7.25.7 - '@babel/helper-plugin-utils': 7.25.7 - babel-plugin-polyfill-corejs2: 0.4.10(@babel/core@7.25.8) - babel-plugin-polyfill-corejs3: 0.10.6(@babel/core@7.25.8) - babel-plugin-polyfill-regenerator: 0.6.1(@babel/core@7.25.8) + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 + + '@babel/plugin-transform-runtime@7.25.9(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-module-imports': 7.25.9 + '@babel/helper-plugin-utils': 7.25.9 + babel-plugin-polyfill-corejs2: 0.4.10(@babel/core@7.26.0) + babel-plugin-polyfill-corejs3: 0.10.6(@babel/core@7.26.0) + babel-plugin-polyfill-regenerator: 0.6.1(@babel/core@7.26.0) semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-shorthand-properties@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-transform-shorthand-properties@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-transform-spread@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-transform-spread@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 - '@babel/helper-skip-transparent-expression-wrappers': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-sticky-regex@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-transform-sticky-regex@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-transform-template-literals@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-transform-template-literals@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-transform-typeof-symbol@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-transform-typeof-symbol@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-transform-typescript@7.25.7(@babel/core@7.25.8)': + '@babel/plugin-transform-typescript@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-annotate-as-pure': 7.25.7 - '@babel/helper-create-class-features-plugin': 7.25.7(@babel/core@7.25.8) - '@babel/helper-plugin-utils': 7.25.7 - '@babel/helper-skip-transparent-expression-wrappers': 7.25.7 - '@babel/plugin-syntax-typescript': 7.25.7(@babel/core@7.25.8) + '@babel/core': 7.26.0 + '@babel/helper-annotate-as-pure': 7.25.9 + '@babel/helper-create-class-features-plugin': 7.25.9(@babel/core@7.26.0) + '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 + '@babel/plugin-syntax-typescript': 7.25.9(@babel/core@7.26.0) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-unicode-escapes@7.25.7(@babel/core@7.25.8)': - dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 - - '@babel/plugin-transform-unicode-property-regex@7.25.7(@babel/core@7.25.8)': - dependencies: - '@babel/core': 7.25.8 - '@babel/helper-create-regexp-features-plugin': 7.25.7(@babel/core@7.25.8) - '@babel/helper-plugin-utils': 7.25.7 - - '@babel/plugin-transform-unicode-regex@7.25.7(@babel/core@7.25.8)': - dependencies: - '@babel/core': 7.25.8 - '@babel/helper-create-regexp-features-plugin': 7.25.7(@babel/core@7.25.8) - '@babel/helper-plugin-utils': 7.25.7 - - '@babel/plugin-transform-unicode-sets-regex@7.25.7(@babel/core@7.25.8)': - dependencies: - '@babel/core': 7.25.8 - '@babel/helper-create-regexp-features-plugin': 7.25.7(@babel/core@7.25.8) - '@babel/helper-plugin-utils': 7.25.7 - - '@babel/preset-env@7.25.8(@babel/core@7.25.8)': - dependencies: - '@babel/compat-data': 7.25.8 - '@babel/core': 7.25.8 - '@babel/helper-compilation-targets': 7.25.7 - '@babel/helper-plugin-utils': 7.25.7 - '@babel/helper-validator-option': 7.25.7 - '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.25.8) - '@babel/plugin-syntax-import-assertions': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-syntax-import-attributes': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.25.8) - '@babel/plugin-transform-arrow-functions': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-async-generator-functions': 7.25.8(@babel/core@7.25.8) - '@babel/plugin-transform-async-to-generator': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-block-scoped-functions': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-block-scoping': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-class-properties': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-class-static-block': 7.25.8(@babel/core@7.25.8) - '@babel/plugin-transform-classes': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-computed-properties': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-destructuring': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-dotall-regex': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-duplicate-keys': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-dynamic-import': 7.25.8(@babel/core@7.25.8) - '@babel/plugin-transform-exponentiation-operator': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-export-namespace-from': 7.25.8(@babel/core@7.25.8) - '@babel/plugin-transform-for-of': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-function-name': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-json-strings': 7.25.8(@babel/core@7.25.8) - '@babel/plugin-transform-literals': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-logical-assignment-operators': 7.25.8(@babel/core@7.25.8) - '@babel/plugin-transform-member-expression-literals': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-modules-amd': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-modules-commonjs': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-modules-systemjs': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-modules-umd': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-named-capturing-groups-regex': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-new-target': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-nullish-coalescing-operator': 7.25.8(@babel/core@7.25.8) - '@babel/plugin-transform-numeric-separator': 7.25.8(@babel/core@7.25.8) - '@babel/plugin-transform-object-rest-spread': 7.25.8(@babel/core@7.25.8) - '@babel/plugin-transform-object-super': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-optional-catch-binding': 7.25.8(@babel/core@7.25.8) - '@babel/plugin-transform-optional-chaining': 7.25.8(@babel/core@7.25.8) - '@babel/plugin-transform-parameters': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-private-methods': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-private-property-in-object': 7.25.8(@babel/core@7.25.8) - '@babel/plugin-transform-property-literals': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-regenerator': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-reserved-words': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-shorthand-properties': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-spread': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-sticky-regex': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-template-literals': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-typeof-symbol': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-unicode-escapes': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-unicode-property-regex': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-unicode-regex': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-unicode-sets-regex': 7.25.7(@babel/core@7.25.8) - '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.25.8) - babel-plugin-polyfill-corejs2: 0.4.10(@babel/core@7.25.8) - babel-plugin-polyfill-corejs3: 0.10.6(@babel/core@7.25.8) - babel-plugin-polyfill-regenerator: 0.6.1(@babel/core@7.25.8) + '@babel/plugin-transform-unicode-escapes@7.25.9(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 + + '@babel/plugin-transform-unicode-property-regex@7.25.9(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-create-regexp-features-plugin': 7.25.9(@babel/core@7.26.0) + '@babel/helper-plugin-utils': 7.25.9 + + '@babel/plugin-transform-unicode-regex@7.25.9(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-create-regexp-features-plugin': 7.25.9(@babel/core@7.26.0) + '@babel/helper-plugin-utils': 7.25.9 + + '@babel/plugin-transform-unicode-sets-regex@7.25.9(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-create-regexp-features-plugin': 7.25.9(@babel/core@7.26.0) + '@babel/helper-plugin-utils': 7.25.9 + + '@babel/preset-env@7.26.0(@babel/core@7.26.0)': + dependencies: + '@babel/compat-data': 7.26.0 + '@babel/core': 7.26.0 + '@babel/helper-compilation-targets': 7.25.9 + '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-validator-option': 7.25.9 + '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.26.0) + '@babel/plugin-syntax-import-assertions': 7.26.0(@babel/core@7.26.0) + '@babel/plugin-syntax-import-attributes': 7.26.0(@babel/core@7.26.0) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.26.0) + '@babel/plugin-transform-arrow-functions': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-async-generator-functions': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-async-to-generator': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-block-scoped-functions': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-block-scoping': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-class-properties': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-class-static-block': 7.26.0(@babel/core@7.26.0) + '@babel/plugin-transform-classes': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-computed-properties': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-destructuring': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-dotall-regex': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-duplicate-keys': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-dynamic-import': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-exponentiation-operator': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-export-namespace-from': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-for-of': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-function-name': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-json-strings': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-literals': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-logical-assignment-operators': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-member-expression-literals': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-modules-amd': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-modules-commonjs': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-modules-systemjs': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-modules-umd': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-named-capturing-groups-regex': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-new-target': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-nullish-coalescing-operator': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-numeric-separator': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-object-rest-spread': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-object-super': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-optional-catch-binding': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-optional-chaining': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-parameters': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-private-methods': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-private-property-in-object': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-property-literals': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-regenerator': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-regexp-modifiers': 7.26.0(@babel/core@7.26.0) + '@babel/plugin-transform-reserved-words': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-shorthand-properties': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-spread': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-sticky-regex': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-template-literals': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-typeof-symbol': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-unicode-escapes': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-unicode-property-regex': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-unicode-regex': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-unicode-sets-regex': 7.25.9(@babel/core@7.26.0) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.26.0) + babel-plugin-polyfill-corejs2: 0.4.10(@babel/core@7.26.0) + babel-plugin-polyfill-corejs3: 0.10.6(@babel/core@7.26.0) + babel-plugin-polyfill-regenerator: 0.6.1(@babel/core@7.26.0) core-js-compat: 3.38.1 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/preset-flow@7.24.7(@babel/core@7.25.8)': + '@babel/preset-flow@7.24.7(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 - '@babel/helper-validator-option': 7.25.7 - '@babel/plugin-transform-flow-strip-types': 7.24.7(@babel/core@7.25.8) + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-validator-option': 7.25.9 + '@babel/plugin-transform-flow-strip-types': 7.24.7(@babel/core@7.26.0) - '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.25.8)': + '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 - '@babel/types': 7.25.8 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 + '@babel/types': 7.26.0 esutils: 2.0.3 - '@babel/preset-react@7.25.7(@babel/core@7.25.8)': + '@babel/preset-react@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 - '@babel/helper-validator-option': 7.25.7 - '@babel/plugin-transform-react-display-name': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-react-jsx': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-react-jsx-development': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-react-pure-annotations': 7.25.7(@babel/core@7.25.8) + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-validator-option': 7.25.9 + '@babel/plugin-transform-react-display-name': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-react-jsx': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-react-jsx-development': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-react-pure-annotations': 7.25.9(@babel/core@7.26.0) transitivePeerDependencies: - supports-color - '@babel/preset-typescript@7.25.7(@babel/core@7.25.8)': + '@babel/preset-typescript@7.26.0(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 - '@babel/helper-plugin-utils': 7.25.7 - '@babel/helper-validator-option': 7.25.7 - '@babel/plugin-syntax-jsx': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-modules-commonjs': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-typescript': 7.25.7(@babel/core@7.25.8) + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-validator-option': 7.25.9 + '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-modules-commonjs': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-typescript': 7.25.9(@babel/core@7.26.0) transitivePeerDependencies: - supports-color - '@babel/register@7.25.7(@babel/core@7.25.8)': + '@babel/register@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 + '@babel/core': 7.26.0 clone-deep: 4.0.1 find-cache-dir: 2.1.0 make-dir: 2.1.0 pirates: 4.0.6 source-map-support: 0.5.21 - '@babel/runtime-corejs2@7.25.7': + '@babel/runtime-corejs2@7.26.0': dependencies: core-js: 2.6.12 regenerator-runtime: 0.14.1 - '@babel/runtime@7.25.7': + '@babel/runtime@7.26.0': dependencies: regenerator-runtime: 0.14.1 - '@babel/template@7.25.7': + '@babel/template@7.25.9': dependencies: - '@babel/code-frame': 7.25.7 - '@babel/parser': 7.25.8 - '@babel/types': 7.25.8 + '@babel/code-frame': 7.26.0 + '@babel/parser': 7.26.1 + '@babel/types': 7.26.0 - '@babel/traverse@7.25.7': + '@babel/traverse@7.25.9': dependencies: - '@babel/code-frame': 7.25.7 - '@babel/generator': 7.25.7 - '@babel/parser': 7.25.8 - '@babel/template': 7.25.7 - '@babel/types': 7.25.8 - debug: 4.3.6(supports-color@8.1.1) + '@babel/code-frame': 7.26.0 + '@babel/generator': 7.26.0 + '@babel/parser': 7.26.1 + '@babel/template': 7.25.9 + '@babel/types': 7.26.0 + debug: 4.3.7(supports-color@8.1.1) globals: 11.12.0 transitivePeerDependencies: - supports-color - '@babel/types@7.25.8': + '@babel/types@7.26.0': dependencies: - '@babel/helper-string-parser': 7.25.7 - '@babel/helper-validator-identifier': 7.25.7 - to-fast-properties: 2.0.0 + '@babel/helper-string-parser': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 '@bcoe/v8-coverage@0.2.3': {} '@codspeed/core@3.1.1': dependencies: - axios: 1.7.5(debug@4.3.6) + axios: 1.7.7(debug@4.3.7) find-up: 6.3.0 form-data: 4.0.0 node-gyp-build: 4.8.1 transitivePeerDependencies: - debug - '@codspeed/vitest-plugin@3.1.1(vite@5.3.4(@types/node@20.16.11)(terser@5.27.0))(vitest@2.1.2)': + '@codspeed/vitest-plugin@3.1.1(vite@5.3.4(@types/node@20.17.3)(terser@5.27.0))(vitest@2.1.3)': dependencies: '@codspeed/core': 3.1.1 - vite: 5.3.4(@types/node@20.16.11)(terser@5.27.0) - vitest: 2.1.2(@types/node@20.16.11)(@vitest/ui@2.1.2)(jsdom@24.1.3)(terser@5.27.0) + vite: 5.3.4(@types/node@20.17.3)(terser@5.27.0) + vitest: 2.1.3(@types/node@20.17.3)(@vitest/ui@2.1.3)(jsdom@24.1.3)(terser@5.27.0) transitivePeerDependencies: - debug @@ -11220,8 +11219,8 @@ snapshots: '@emotion/babel-plugin@11.12.0': dependencies: - '@babel/helper-module-imports': 7.25.7 - '@babel/runtime': 7.25.7 + '@babel/helper-module-imports': 7.25.9 + '@babel/runtime': 7.26.0 '@emotion/hash': 0.9.2 '@emotion/memoize': 0.9.0 '@emotion/serialize': 1.3.1 @@ -11258,7 +11257,7 @@ snapshots: '@emotion/react@11.13.3(@types/react@18.3.4)(react@18.3.1)': dependencies: - '@babel/runtime': 7.25.7 + '@babel/runtime': 7.26.0 '@emotion/babel-plugin': 11.12.0 '@emotion/cache': 11.13.1 '@emotion/serialize': 1.3.1 @@ -11291,7 +11290,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)': dependencies: - '@babel/runtime': 7.25.7 + '@babel/runtime': 7.26.0 '@emotion/babel-plugin': 11.12.0 '@emotion/is-prop-valid': 1.3.0 '@emotion/react': 11.13.3(@types/react@18.3.4)(react@18.3.1) @@ -11473,7 +11472,7 @@ snapshots: '@eslint/eslintrc@2.1.4': dependencies: ajv: 6.12.6 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) espree: 9.6.1 globals: 13.24.0 ignore: 5.3.1 @@ -11488,7 +11487,7 @@ snapshots: '@fast-csv/format@4.3.5': dependencies: - '@types/node': 20.16.11 + '@types/node': 20.17.3 lodash.escaperegexp: 4.1.2 lodash.isboolean: 3.0.3 lodash.isequal: 4.5.0 @@ -11497,7 +11496,7 @@ snapshots: '@fast-csv/parse@4.3.6': dependencies: - '@types/node': 20.16.11 + '@types/node': 20.17.3 lodash.escaperegexp: 4.1.2 lodash.groupby: 4.6.0 lodash.isfunction: 3.0.9 @@ -11550,7 +11549,7 @@ snapshots: '@humanwhocodes/config-array@0.13.0': dependencies: '@humanwhocodes/object-schema': 2.0.3 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -11768,7 +11767,7 @@ snapshots: '@mui/base@5.0.0-beta.40(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.25.7 + '@babel/runtime': 7.26.0 '@floating-ui/react-dom': 2.0.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mui/types': 7.2.15(@types/react@18.3.4) '@mui/utils': 5.16.6(@types/react@18.3.4)(react@18.3.1) @@ -11782,19 +11781,19 @@ snapshots: '@mui/core-downloads-tracker@5.16.7': {} - '@mui/docs@6.1.4(ycp24r7hmgzk3bu34shnp2ejgu)': + '@mui/docs@6.1.6(5qvtg2qlcuewh33f6ogt54yk7e)': dependencies: - '@babel/runtime': 7.25.7 + '@babel/runtime': 7.26.0 '@mui/base': 5.0.0-beta.40(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mui/icons-material': 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/internal-markdown': 1.0.17 + '@mui/internal-markdown': 1.0.19 '@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) '@mui/system': 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) chai: 5.1.1 clipboard-copy: 4.0.1 clsx: 2.1.1 csstype: 3.1.3 - next: 14.2.15(@babel/core@7.25.8)(@opentelemetry/api@1.8.0)(@playwright/test@1.44.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 14.2.16(@babel/core@7.26.0)(@opentelemetry/api@1.8.0)(@playwright/test@1.44.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) nprogress: 0.2.0 prop-types: 15.8.1 react: 18.3.1 @@ -11803,37 +11802,37 @@ snapshots: '@mui/icons-material@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)': dependencies: - '@babel/runtime': 7.25.7 + '@babel/runtime': 7.26.0 '@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) react: 18.3.1 optionalDependencies: '@types/react': 18.3.4 - '@mui/internal-babel-plugin-resolve-imports@1.0.18(@babel/core@7.25.8)': + '@mui/internal-babel-plugin-resolve-imports@1.0.18(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.8 + '@babel/core': 7.26.0 resolve: 1.22.8 - '@mui/internal-docs-utils@1.0.14': + '@mui/internal-docs-utils@1.0.15': dependencies: rimraf: 6.0.1 typescript: 5.6.3 - '@mui/internal-markdown@1.0.17': + '@mui/internal-markdown@1.0.19': dependencies: - '@babel/runtime': 7.25.7 + '@babel/runtime': 7.26.0 lodash: 4.17.21 marked: 14.1.3 prismjs: 1.29.0 - '@mui/internal-scripts@1.0.24': + '@mui/internal-scripts@1.0.26': dependencies: - '@babel/core': 7.25.8 - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.25.8) - '@babel/plugin-syntax-jsx': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-syntax-typescript': 7.25.7(@babel/core@7.25.8) - '@babel/types': 7.25.8 - '@mui/internal-docs-utils': 1.0.14 + '@babel/core': 7.26.0 + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.26.0) + '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-syntax-typescript': 7.25.9(@babel/core@7.26.0) + '@babel/types': 7.26.0 + '@mui/internal-docs-utils': 1.0.15 doctrine: 3.0.0 lodash: 4.17.21 typescript: 5.6.3 @@ -11841,12 +11840,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@mui/internal-test-utils@1.0.17(@babel/core@7.25.8)(@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/internal-test-utils@1.0.19(@babel/core@7.26.0)(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/plugin-transform-modules-commonjs': 7.25.7(@babel/core@7.25.8) - '@babel/preset-typescript': 7.25.7(@babel/core@7.25.8) - '@babel/register': 7.25.7(@babel/core@7.25.8) - '@babel/runtime': 7.25.7 + '@babel/plugin-transform-modules-commonjs': 7.25.9(@babel/core@7.26.0) + '@babel/preset-typescript': 7.26.0(@babel/core@7.26.0) + '@babel/register': 7.25.9(@babel/core@7.26.0) + '@babel/runtime': 7.26.0 '@emotion/cache': 11.13.1 '@emotion/react': 11.13.3(@types/react@18.3.4)(react@18.3.1) '@testing-library/dom': 10.4.0 @@ -11860,7 +11859,7 @@ snapshots: jsdom: 24.1.3 lodash: 4.17.21 mocha: 10.7.3 - playwright: 1.47.2 + playwright: 1.48.2 prop-types: 15.8.1 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -11876,7 +11875,7 @@ snapshots: '@mui/joy@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)': dependencies: - '@babel/runtime': 7.25.7 + '@babel/runtime': 7.26.0 '@mui/base': 5.0.0-beta.40(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mui/core-downloads-tracker': 5.16.7 '@mui/system': 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) @@ -11893,7 +11892,7 @@ snapshots: '@mui/lab@5.0.0-alpha.173(@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))(@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-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.25.7 + '@babel/runtime': 7.26.0 '@mui/base': 5.0.0-beta.40(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@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) '@mui/system': 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) @@ -11908,11 +11907,11 @@ 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/material-nextjs@5.16.6(@emotion/cache@11.13.1)(@emotion/server@11.11.0)(@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)(next@14.2.15(@babel/core@7.25.8)(@opentelemetry/api@1.8.0)(@playwright/test@1.44.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': + '@mui/material-nextjs@5.16.6(@emotion/cache@11.13.1)(@emotion/server@11.11.0)(@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)(next@14.2.16(@babel/core@7.26.0)(@opentelemetry/api@1.8.0)(@playwright/test@1.44.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.25.7 + '@babel/runtime': 7.26.0 '@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) - next: 14.2.15(@babel/core@7.25.8)(@opentelemetry/api@1.8.0)(@playwright/test@1.44.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 14.2.16(@babel/core@7.26.0)(@opentelemetry/api@1.8.0)(@playwright/test@1.44.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 optionalDependencies: '@emotion/cache': 11.13.1 @@ -11921,7 +11920,7 @@ snapshots: '@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)': dependencies: - '@babel/runtime': 7.25.7 + '@babel/runtime': 7.26.0 '@mui/core-downloads-tracker': 5.16.7 '@mui/system': 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': 7.2.15(@types/react@18.3.4) @@ -11940,12 +11939,12 @@ 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/010de4505361345951824d905d1508d6f258ba67(encoding@0.1.13)': + '@mui/monorepo@https://codeload.github.com/mui/material-ui/tar.gz/32112b76aa821c2a1e98120545019ef1a71ea274(encoding@0.1.13)': dependencies: '@googleapis/sheets': 9.3.1(encoding@0.1.13) '@netlify/functions': 2.8.2 '@slack/bolt': 3.22.0 - execa: 9.4.0 + execa: 9.4.1 google-auth-library: 9.14.2(encoding@0.1.13) transitivePeerDependencies: - bufferutil @@ -11956,7 +11955,7 @@ snapshots: '@mui/private-theming@5.16.6(@types/react@18.3.4)(react@18.3.1)': dependencies: - '@babel/runtime': 7.25.7 + '@babel/runtime': 7.26.0 '@mui/utils': 5.16.6(@types/react@18.3.4)(react@18.3.1) prop-types: 15.8.1 react: 18.3.1 @@ -11965,7 +11964,7 @@ snapshots: '@mui/styled-engine@5.16.6(@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))(react@18.3.1)': dependencies: - '@babel/runtime': 7.25.7 + '@babel/runtime': 7.26.0 '@emotion/cache': 11.13.1 csstype: 3.1.3 prop-types: 15.8.1 @@ -11976,7 +11975,7 @@ snapshots: '@mui/styles@5.16.7(@types/react@18.3.4)(react@18.3.1)': dependencies: - '@babel/runtime': 7.25.7 + '@babel/runtime': 7.26.0 '@emotion/hash': 0.9.2 '@mui/private-theming': 5.16.6(@types/react@18.3.4)(react@18.3.1) '@mui/types': 7.2.15(@types/react@18.3.4) @@ -11999,7 +11998,7 @@ snapshots: '@mui/system@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)': dependencies: - '@babel/runtime': 7.25.7 + '@babel/runtime': 7.26.0 '@mui/private-theming': 5.16.6(@types/react@18.3.4)(react@18.3.1) '@mui/styled-engine': 5.16.6(@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))(react@18.3.1) '@mui/types': 7.2.15(@types/react@18.3.4) @@ -12019,7 +12018,7 @@ snapshots: '@mui/utils@5.16.6(@types/react@18.3.4)(react@18.3.1)': dependencies: - '@babel/runtime': 7.25.7 + '@babel/runtime': 7.26.0 '@mui/types': 7.2.15(@types/react@18.3.4) '@types/prop-types': 15.7.13 clsx: 2.1.1 @@ -12040,37 +12039,37 @@ snapshots: '@netlify/node-cookies': 0.1.0 urlpattern-polyfill: 8.0.2 - '@next/env@14.2.15': {} + '@next/env@14.2.16': {} - '@next/eslint-plugin-next@14.2.15': + '@next/eslint-plugin-next@15.0.2': dependencies: - glob: 10.3.10 + fast-glob: 3.3.1 - '@next/swc-darwin-arm64@14.2.15': + '@next/swc-darwin-arm64@14.2.16': optional: true - '@next/swc-darwin-x64@14.2.15': + '@next/swc-darwin-x64@14.2.16': optional: true - '@next/swc-linux-arm64-gnu@14.2.15': + '@next/swc-linux-arm64-gnu@14.2.16': optional: true - '@next/swc-linux-arm64-musl@14.2.15': + '@next/swc-linux-arm64-musl@14.2.16': optional: true - '@next/swc-linux-x64-gnu@14.2.15': + '@next/swc-linux-x64-gnu@14.2.16': optional: true - '@next/swc-linux-x64-musl@14.2.15': + '@next/swc-linux-x64-musl@14.2.16': optional: true - '@next/swc-win32-arm64-msvc@14.2.15': + '@next/swc-win32-arm64-msvc@14.2.16': optional: true - '@next/swc-win32-ia32-msvc@14.2.15': + '@next/swc-win32-ia32-msvc@14.2.16': optional: true - '@next/swc-win32-x64-msvc@14.2.15': + '@next/swc-win32-x64-msvc@14.2.16': optional: true '@nicolo-ribaudo/chokidar-2@2.1.8-no-fsevents.3': @@ -12722,7 +12721,7 @@ snapshots: '@types/express': 4.17.21 '@types/promise.allsettled': 1.0.6 '@types/tsscmp': 1.0.2 - axios: 1.7.5(debug@4.3.6) + axios: 1.7.7(debug@4.3.7) express: 4.21.0 path-to-regexp: 8.1.0 promise.allsettled: 1.0.7 @@ -12736,18 +12735,18 @@ snapshots: '@slack/logger@3.0.0': dependencies: - '@types/node': 20.16.11 + '@types/node': 20.17.3 '@slack/logger@4.0.0': dependencies: - '@types/node': 20.16.11 + '@types/node': 20.17.3 '@slack/oauth@2.6.3': dependencies: '@slack/logger': 3.0.0 '@slack/web-api': 6.13.0 '@types/jsonwebtoken': 8.5.9 - '@types/node': 20.16.11 + '@types/node': 20.17.3 jsonwebtoken: 9.0.2 lodash.isstring: 4.0.1 transitivePeerDependencies: @@ -12757,7 +12756,7 @@ snapshots: dependencies: '@slack/logger': 3.0.0 '@slack/web-api': 6.13.0 - '@types/node': 20.16.11 + '@types/node': 20.17.3 '@types/ws': 7.4.7 eventemitter3: 5.0.1 finity: 0.5.4 @@ -12774,8 +12773,8 @@ snapshots: '@slack/logger': 3.0.0 '@slack/types': 2.13.0 '@types/is-stream': 1.1.0 - '@types/node': 20.16.11 - axios: 1.7.5(debug@4.3.6) + '@types/node': 20.17.3 + axios: 1.7.7(debug@4.3.7) eventemitter3: 3.1.2 form-data: 2.5.1 is-electron: 2.2.2 @@ -12845,12 +12844,12 @@ snapshots: dependencies: '@swc/counter': 0.1.3 - '@tanstack/query-core@5.59.13': {} + '@tanstack/query-core@5.59.16': {} '@testing-library/dom@10.4.0': dependencies: - '@babel/code-frame': 7.25.7 - '@babel/runtime': 7.25.7 + '@babel/code-frame': 7.26.0 + '@babel/runtime': 7.26.0 '@types/aria-query': 5.0.4 aria-query: 5.3.0 chalk: 4.1.2 @@ -12858,10 +12857,10 @@ snapshots: lz-string: 1.5.0 pretty-format: 27.5.1 - '@testing-library/jest-dom@6.5.0': + '@testing-library/jest-dom@6.6.2': dependencies: '@adobe/css-tools': 4.4.0 - aria-query: 5.3.0 + aria-query: 5.3.2 chalk: 3.0.0 css.escape: 1.5.1 dom-accessibility-api: 0.6.3 @@ -12870,7 +12869,7 @@ snapshots: '@testing-library/react@16.0.1(@testing-library/dom@10.4.0)(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.25.7 + '@babel/runtime': 7.26.0 '@testing-library/dom': 10.4.0 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -12895,29 +12894,29 @@ snapshots: '@types/babel__core@7.20.5': dependencies: - '@babel/parser': 7.25.8 - '@babel/types': 7.25.8 + '@babel/parser': 7.26.1 + '@babel/types': 7.26.0 '@types/babel__generator': 7.6.8 '@types/babel__template': 7.4.4 '@types/babel__traverse': 7.20.6 '@types/babel__generator@7.6.8': dependencies: - '@babel/types': 7.25.8 + '@babel/types': 7.26.0 '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.25.8 - '@babel/types': 7.25.8 + '@babel/parser': 7.26.1 + '@babel/types': 7.26.0 '@types/babel__traverse@7.20.6': dependencies: - '@babel/types': 7.25.8 + '@babel/types': 7.26.0 '@types/body-parser@1.19.5': dependencies: '@types/connect': 3.4.38 - '@types/node': 20.16.11 + '@types/node': 20.17.3 '@types/chai-dom@1.11.3': dependencies: @@ -12929,13 +12928,13 @@ snapshots: '@types/connect@3.4.38': dependencies: - '@types/node': 20.16.11 + '@types/node': 20.17.3 '@types/cookie@0.4.1': {} '@types/cors@2.8.17': dependencies: - '@types/node': 20.16.11 + '@types/node': 20.17.3 '@types/d3-array@3.2.1': {} @@ -12980,7 +12979,7 @@ snapshots: '@types/express-serve-static-core@4.17.42': dependencies: - '@types/node': 20.16.11 + '@types/node': 20.17.3 '@types/qs': 6.9.11 '@types/range-parser': 1.2.7 '@types/send': 0.17.4 @@ -12997,7 +12996,7 @@ snapshots: '@types/fs-extra@11.0.4': dependencies: '@types/jsonfile': 6.1.4 - '@types/node': 20.16.11 + '@types/node': 20.17.3 '@types/gtag.js@0.0.20': {} @@ -13009,7 +13008,7 @@ snapshots: '@types/is-stream@1.1.0': dependencies: - '@types/node': 20.16.11 + '@types/node': 20.17.3 '@types/istanbul-lib-coverage@2.0.6': {} @@ -13024,20 +13023,20 @@ snapshots: '@types/jsonfile@6.1.4': dependencies: - '@types/node': 20.16.11 + '@types/node': 20.17.3 '@types/jsonwebtoken@8.5.9': dependencies: - '@types/node': 20.16.11 + '@types/node': 20.17.3 - '@types/karma@6.3.8': + '@types/karma@6.3.9': dependencies: - '@types/node': 20.16.11 + '@types/node': 20.17.3 log4js: 6.9.1 transitivePeerDependencies: - supports-color - '@types/lodash@4.17.10': {} + '@types/lodash@4.17.12': {} '@types/luxon@3.4.2': {} @@ -13065,7 +13064,7 @@ snapshots: '@types/ms@0.7.34': {} - '@types/node@20.16.11': + '@types/node@20.17.3': dependencies: undici-types: 6.19.8 @@ -13118,13 +13117,13 @@ snapshots: '@types/send@0.17.4': dependencies: '@types/mime': 1.3.5 - '@types/node': 20.16.11 + '@types/node': 20.17.3 '@types/serve-static@1.15.5': dependencies: '@types/http-errors': 2.0.4 '@types/mime': 3.0.4 - '@types/node': 20.16.11 + '@types/node': 20.17.3 '@types/sinon@17.0.3': dependencies: @@ -13142,7 +13141,7 @@ snapshots: '@types/webpack-bundle-analyzer@4.7.0(@swc/core@1.7.35(@swc/helpers@0.5.5))(webpack-cli@5.1.4(webpack-bundle-analyzer@4.10.2)(webpack@5.95.0))': dependencies: - '@types/node': 20.16.11 + '@types/node': 20.17.3 tapable: 2.2.1 webpack: 5.95.0(@swc/core@1.7.35(@swc/helpers@0.5.5))(webpack-cli@5.1.4(webpack-bundle-analyzer@4.10.2)(webpack@5.95.0)) transitivePeerDependencies: @@ -13153,7 +13152,7 @@ snapshots: '@types/ws@7.4.7': dependencies: - '@types/node': 20.16.11 + '@types/node': 20.17.3 '@types/yargs-parser@21.0.3': {} @@ -13185,7 +13184,7 @@ snapshots: '@typescript-eslint/types': 7.18.0 '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.6.3) '@typescript-eslint/visitor-keys': 7.18.0 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) eslint: 8.57.1 optionalDependencies: typescript: 5.6.3 @@ -13206,7 +13205,7 @@ snapshots: dependencies: '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.6.3) '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@5.6.3) - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) eslint: 8.57.1 ts-api-utils: 1.3.0(typescript@5.6.3) optionalDependencies: @@ -13222,7 +13221,7 @@ snapshots: dependencies: '@typescript-eslint/types': 5.62.0 '@typescript-eslint/visitor-keys': 5.62.0 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) globby: 11.1.0 is-glob: 4.0.3 semver: 7.6.3 @@ -13236,7 +13235,7 @@ snapshots: dependencies: '@typescript-eslint/types': 7.18.0 '@typescript-eslint/visitor-keys': 7.18.0 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.4 @@ -13285,72 +13284,72 @@ snapshots: '@ungap/structured-clone@1.2.0': {} - '@vitejs/plugin-react-swc@3.7.1(@swc/helpers@0.5.5)(vite@5.3.4(@types/node@20.16.11)(terser@5.27.0))': + '@vitejs/plugin-react-swc@3.7.1(@swc/helpers@0.5.5)(vite@5.3.4(@types/node@20.17.3)(terser@5.27.0))': dependencies: '@swc/core': 1.7.35(@swc/helpers@0.5.5) - vite: 5.3.4(@types/node@20.16.11)(terser@5.27.0) + vite: 5.3.4(@types/node@20.17.3)(terser@5.27.0) transitivePeerDependencies: - '@swc/helpers' - '@vitejs/plugin-react@4.3.2(vite@5.3.4(@types/node@20.16.11)(terser@5.27.0))': + '@vitejs/plugin-react@4.3.3(vite@5.3.4(@types/node@20.17.3)(terser@5.27.0))': dependencies: - '@babel/core': 7.25.8 - '@babel/plugin-transform-react-jsx-self': 7.24.7(@babel/core@7.25.8) - '@babel/plugin-transform-react-jsx-source': 7.24.7(@babel/core@7.25.8) + '@babel/core': 7.26.0 + '@babel/plugin-transform-react-jsx-self': 7.24.7(@babel/core@7.26.0) + '@babel/plugin-transform-react-jsx-source': 7.24.7(@babel/core@7.26.0) '@types/babel__core': 7.20.5 react-refresh: 0.14.2 - vite: 5.3.4(@types/node@20.16.11)(terser@5.27.0) + vite: 5.3.4(@types/node@20.17.3)(terser@5.27.0) transitivePeerDependencies: - supports-color - '@vitest/expect@2.1.2': + '@vitest/expect@2.1.3': dependencies: - '@vitest/spy': 2.1.2 - '@vitest/utils': 2.1.2 + '@vitest/spy': 2.1.3 + '@vitest/utils': 2.1.3 chai: 5.1.1 tinyrainbow: 1.2.0 - '@vitest/mocker@2.1.2(@vitest/spy@2.1.2)(vite@5.3.4(@types/node@20.16.11)(terser@5.27.0))': + '@vitest/mocker@2.1.3(@vitest/spy@2.1.3)(vite@5.3.4(@types/node@20.17.3)(terser@5.27.0))': dependencies: - '@vitest/spy': 2.1.2 + '@vitest/spy': 2.1.3 estree-walker: 3.0.3 magic-string: 0.30.11 optionalDependencies: - vite: 5.3.4(@types/node@20.16.11)(terser@5.27.0) + vite: 5.3.4(@types/node@20.17.3)(terser@5.27.0) - '@vitest/pretty-format@2.1.2': + '@vitest/pretty-format@2.1.3': dependencies: tinyrainbow: 1.2.0 - '@vitest/runner@2.1.2': + '@vitest/runner@2.1.3': dependencies: - '@vitest/utils': 2.1.2 + '@vitest/utils': 2.1.3 pathe: 1.1.2 - '@vitest/snapshot@2.1.2': + '@vitest/snapshot@2.1.3': dependencies: - '@vitest/pretty-format': 2.1.2 + '@vitest/pretty-format': 2.1.3 magic-string: 0.30.11 pathe: 1.1.2 - '@vitest/spy@2.1.2': + '@vitest/spy@2.1.3': dependencies: tinyspy: 3.0.0 - '@vitest/ui@2.1.2(vitest@2.1.2)': + '@vitest/ui@2.1.3(vitest@2.1.3)': dependencies: - '@vitest/utils': 2.1.2 + '@vitest/utils': 2.1.3 fflate: 0.8.2 flatted: 3.3.1 pathe: 1.1.2 sirv: 2.0.4 tinyglobby: 0.2.6 tinyrainbow: 1.2.0 - vitest: 2.1.2(@types/node@20.16.11)(@vitest/ui@2.1.2)(jsdom@24.1.3)(terser@5.27.0) + vitest: 2.1.3(@types/node@20.17.3)(@vitest/ui@2.1.3)(jsdom@24.1.3)(terser@5.27.0) - '@vitest/utils@2.1.2': + '@vitest/utils@2.1.3': dependencies: - '@vitest/pretty-format': 2.1.2 + '@vitest/pretty-format': 2.1.3 loupe: 3.1.1 tinyrainbow: 1.2.0 @@ -13494,13 +13493,13 @@ snapshots: agent-base@6.0.2: dependencies: - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) transitivePeerDependencies: - supports-color agent-base@7.1.0: dependencies: - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -13650,14 +13649,12 @@ snapshots: argparse@2.0.1: {} - aria-query@5.1.3: - dependencies: - deep-equal: 2.2.3 - aria-query@5.3.0: dependencies: dequal: 2.0.3 + aria-query@5.3.2: {} + array-buffer-byte-length@1.0.1: dependencies: call-bind: 1.0.7 @@ -13795,11 +13792,11 @@ snapshots: dependencies: possible-typed-array-names: 1.0.0 - axe-core@4.10.0: {} + axe-core@4.10.2: {} - axios@1.7.5(debug@4.3.6): + axios@1.7.7(debug@4.3.7): dependencies: - follow-redirects: 1.15.6(debug@4.3.6) + follow-redirects: 1.15.6(debug@4.3.7) form-data: 4.0.0 proxy-from-env: 1.1.0 transitivePeerDependencies: @@ -13807,16 +13804,16 @@ snapshots: axobject-query@4.1.0: {} - babel-loader@9.2.1(@babel/core@7.25.8)(webpack@5.95.0): + babel-loader@9.2.1(@babel/core@7.26.0)(webpack@5.95.0): dependencies: - '@babel/core': 7.25.8 + '@babel/core': 7.26.0 find-cache-dir: 4.0.0 schema-utils: 4.2.0 webpack: 5.95.0(@swc/core@1.7.35(@swc/helpers@0.5.5))(webpack-cli@5.1.4(webpack-bundle-analyzer@4.10.2)(webpack@5.95.0)) babel-plugin-istanbul@7.0.0: dependencies: - '@babel/helper-plugin-utils': 7.25.7 + '@babel/helper-plugin-utils': 7.25.9 '@istanbuljs/load-nyc-config': 1.1.0 '@istanbuljs/schema': 0.1.3 istanbul-lib-instrument: 6.0.2 @@ -13826,7 +13823,7 @@ snapshots: babel-plugin-macros@3.1.0: dependencies: - '@babel/runtime': 7.25.7 + '@babel/runtime': 7.26.0 cosmiconfig: 7.1.0 resolve: 1.22.8 @@ -13840,40 +13837,40 @@ snapshots: babel-plugin-optimize-clsx@2.6.2: dependencies: - '@babel/generator': 7.25.7 - '@babel/template': 7.25.7 - '@babel/types': 7.25.8 + '@babel/generator': 7.26.0 + '@babel/template': 7.25.9 + '@babel/types': 7.26.0 find-cache-dir: 3.3.2 lodash: 4.17.21 object-hash: 2.2.0 - babel-plugin-polyfill-corejs2@0.4.10(@babel/core@7.25.8): + babel-plugin-polyfill-corejs2@0.4.10(@babel/core@7.26.0): dependencies: - '@babel/compat-data': 7.25.8 - '@babel/core': 7.25.8 - '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.25.8) + '@babel/compat-data': 7.26.0 + '@babel/core': 7.26.0 + '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.26.0) semver: 6.3.1 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-corejs3@0.10.6(@babel/core@7.25.8): + babel-plugin-polyfill-corejs3@0.10.6(@babel/core@7.26.0): dependencies: - '@babel/core': 7.25.8 - '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.25.8) + '@babel/core': 7.26.0 + '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.26.0) core-js-compat: 3.38.1 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-regenerator@0.6.1(@babel/core@7.25.8): + babel-plugin-polyfill-regenerator@0.6.1(@babel/core@7.26.0): dependencies: - '@babel/core': 7.25.8 - '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.25.8) + '@babel/core': 7.26.0 + '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.26.0) transitivePeerDependencies: - supports-color babel-plugin-preval@5.1.0: dependencies: - '@babel/runtime': 7.25.7 + '@babel/runtime': 7.26.0 '@types/babel__core': 7.20.5 babel-plugin-macros: 3.1.0 require-from-string: 2.0.2 @@ -14524,7 +14521,7 @@ snapshots: css-vendor@2.0.8: dependencies: - '@babel/runtime': 7.25.7 + '@babel/runtime': 7.26.0 is-in-browser: 1.1.3 css-what@6.1.0: {} @@ -14596,7 +14593,7 @@ snapshots: chalk: 2.4.2 commander: 2.20.3 core-js: 3.35.1 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) fast-json-patch: 3.1.1 get-stdin: 6.0.0 http-proxy-agent: 5.0.0 @@ -14658,13 +14655,13 @@ snapshots: date-fns-jalali@2.30.0-0: dependencies: - '@babel/runtime': 7.25.7 + '@babel/runtime': 7.26.0 date-fns-jalali@3.6.0-1: {} date-fns@2.30.0: dependencies: - '@babel/runtime': 7.25.7 + '@babel/runtime': 7.26.0 date-fns@4.1.0: {} @@ -14684,9 +14681,9 @@ snapshots: dependencies: ms: 2.1.3 - debug@4.3.6(supports-color@8.1.1): + debug@4.3.7(supports-color@8.1.1): dependencies: - ms: 2.1.2 + ms: 2.1.3 optionalDependencies: supports-color: 8.1.1 @@ -14715,27 +14712,6 @@ snapshots: deep-eql@5.0.2: {} - deep-equal@2.2.3: - dependencies: - array-buffer-byte-length: 1.0.1 - call-bind: 1.0.7 - es-get-iterator: 1.1.3 - get-intrinsic: 1.2.4 - is-arguments: 1.1.1 - is-array-buffer: 3.0.4 - is-date-object: 1.0.5 - is-regex: 1.1.4 - is-shared-array-buffer: 1.0.3 - isarray: 2.0.5 - object-is: 1.1.5 - object-keys: 1.1.1 - object.assign: 4.1.5 - regexp.prototype.flags: 1.5.2 - side-channel: 1.0.6 - which-boxed-primitive: 1.0.2 - which-collection: 1.0.1 - which-typed-array: 1.1.15 - deep-extend@0.6.0: {} deep-is@0.1.4: {} @@ -14814,7 +14790,7 @@ snapshots: dom-helpers@5.2.1: dependencies: - '@babel/runtime': 7.25.7 + '@babel/runtime': 7.26.0 csstype: 3.1.3 dom-serialize@2.2.1: @@ -14900,12 +14876,12 @@ snapshots: dependencies: '@types/cookie': 0.4.1 '@types/cors': 2.8.17 - '@types/node': 20.16.11 + '@types/node': 20.17.3 accepts: 1.3.8 base64id: 2.0.0 cookie: 0.4.2 cors: 2.8.5 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) engine.io-parser: 5.2.1 ws: 8.11.0 transitivePeerDependencies: @@ -14961,7 +14937,7 @@ snapshots: function.prototype.name: 1.1.6 get-intrinsic: 1.2.4 get-symbol-description: 1.0.2 - globalthis: 1.0.3 + globalthis: 1.0.4 gopd: 1.0.1 has-property-descriptors: 1.0.2 has-proto: 1.0.3 @@ -15013,7 +14989,7 @@ snapshots: isarray: 2.0.5 stop-iteration-iterator: 1.0.0 - es-iterator-helpers@1.0.19: + es-iterator-helpers@1.1.0: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 @@ -15022,12 +14998,12 @@ snapshots: es-set-tostringtag: 2.0.3 function-bind: 1.1.2 get-intrinsic: 1.2.4 - globalthis: 1.0.3 + globalthis: 1.0.4 has-property-descriptors: 1.0.2 has-proto: 1.0.3 has-symbols: 1.0.3 internal-slot: 1.0.7 - iterator.prototype: 1.1.2 + iterator.prototype: 1.1.3 safe-array-concat: 1.1.2 es-module-lexer@1.5.4: {} @@ -15144,13 +15120,13 @@ snapshots: transitivePeerDependencies: - eslint-plugin-import - eslint-config-airbnb@19.0.4(eslint-plugin-import@2.31.0)(eslint-plugin-jsx-a11y@6.10.0(eslint@8.57.1))(eslint-plugin-react-hooks@5.0.0(eslint@8.57.1))(eslint-plugin-react@7.37.1(eslint@8.57.1))(eslint@8.57.1): + eslint-config-airbnb@19.0.4(eslint-plugin-import@2.31.0)(eslint-plugin-jsx-a11y@6.10.2(eslint@8.57.1))(eslint-plugin-react-hooks@5.0.0(eslint@8.57.1))(eslint-plugin-react@7.37.2(eslint@8.57.1))(eslint@8.57.1): dependencies: eslint: 8.57.1 eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.31.0)(eslint@8.57.1) eslint-plugin-import: 2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-webpack@0.13.9)(eslint@8.57.1) - eslint-plugin-jsx-a11y: 6.10.0(eslint@8.57.1) - eslint-plugin-react: 7.37.1(eslint@8.57.1) + eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.1) + eslint-plugin-react: 7.37.2(eslint@8.57.1) eslint-plugin-react-hooks: 5.0.0(eslint@8.57.1) object.assign: 4.1.5 object.entries: 1.1.8 @@ -15232,12 +15208,12 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-plugin-jsdoc@50.4.1(eslint@8.57.1): + eslint-plugin-jsdoc@50.4.3(eslint@8.57.1): dependencies: '@es-joy/jsdoccomment': 0.49.0 are-docs-informative: 0.0.2 comment-parser: 1.4.1 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) escape-string-regexp: 4.0.0 eslint: 8.57.1 espree: 10.1.0 @@ -15249,17 +15225,16 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-plugin-jsx-a11y@6.10.0(eslint@8.57.1): + eslint-plugin-jsx-a11y@6.10.2(eslint@8.57.1): dependencies: - aria-query: 5.1.3 + aria-query: 5.3.2 array-includes: 3.1.8 array.prototype.flatmap: 1.3.2 ast-types-flow: 0.0.8 - axe-core: 4.10.0 + axe-core: 4.10.2 axobject-query: 4.1.0 damerau-levenshtein: 1.0.8 emoji-regex: 9.2.2 - es-iterator-helpers: 1.0.19 eslint: 8.57.1 hasown: 2.0.2 jsx-ast-utils: 3.3.5 @@ -15267,7 +15242,7 @@ snapshots: minimatch: 3.1.2 object.fromentries: 2.0.8 safe-regex-test: 1.0.3 - string.prototype.includes: 2.0.0 + string.prototype.includes: 2.0.1 eslint-plugin-mocha@10.5.0(eslint@8.57.1): dependencies: @@ -15288,9 +15263,9 @@ snapshots: eslint-plugin-react-compiler@0.0.0-experimental-9ed098e-20240725(eslint@8.57.1): dependencies: - '@babel/core': 7.25.8 - '@babel/parser': 7.25.8 - '@babel/plugin-proposal-private-methods': 7.18.6(@babel/core@7.25.8) + '@babel/core': 7.26.0 + '@babel/parser': 7.26.1 + '@babel/plugin-proposal-private-methods': 7.18.6(@babel/core@7.26.0) eslint: 8.57.1 hermes-parser: 0.20.1 zod: 3.23.8 @@ -15302,14 +15277,14 @@ snapshots: dependencies: eslint: 8.57.1 - eslint-plugin-react@7.37.1(eslint@8.57.1): + eslint-plugin-react@7.37.2(eslint@8.57.1): dependencies: array-includes: 3.1.8 array.prototype.findlast: 1.2.5 array.prototype.flatmap: 1.3.2 array.prototype.tosorted: 1.1.4 doctrine: 2.1.0 - es-iterator-helpers: 1.0.19 + es-iterator-helpers: 1.1.0 eslint: 8.57.1 estraverse: 5.3.0 hasown: 2.0.2 @@ -15324,7 +15299,7 @@ snapshots: string.prototype.matchall: 4.0.11 string.prototype.repeat: 1.0.0 - eslint-plugin-testing-library@6.3.0(eslint@8.57.1)(typescript@5.6.3): + eslint-plugin-testing-library@6.4.0(eslint@8.57.1)(typescript@5.6.3): dependencies: '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@5.6.3) eslint: 8.57.1 @@ -15366,7 +15341,7 @@ snapshots: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.2.2 @@ -15428,8 +15403,8 @@ snapshots: estree-to-babel@3.2.1: dependencies: - '@babel/traverse': 7.25.7 - '@babel/types': 7.25.8 + '@babel/traverse': 7.25.9 + '@babel/types': 7.26.0 c8: 7.14.0 transitivePeerDependencies: - supports-color @@ -15486,7 +15461,7 @@ snapshots: signal-exit: 3.0.7 strip-final-newline: 2.0.0 - execa@9.4.0: + execa@9.4.1: dependencies: '@sindresorhus/merge-streams': 4.0.0 cross-spawn: 7.0.3 @@ -15564,6 +15539,14 @@ snapshots: fast-diff@1.3.0: {} + fast-glob@3.3.1: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + fast-glob@3.3.2: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -15578,10 +15561,6 @@ snapshots: fast-levenshtein@2.0.6: {} - fast-url-parser@1.1.3: - dependencies: - punycode: 1.4.1 - fastest-levenshtein@1.0.16: {} fastq@1.17.0: @@ -15701,9 +15680,9 @@ snapshots: flow-parser@0.227.0: {} - follow-redirects@1.15.6(debug@4.3.6): + follow-redirects@1.15.6(debug@4.3.7): optionalDependencies: - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) for-each@0.3.3: dependencies: @@ -15965,9 +15944,10 @@ snapshots: dependencies: type-fest: 0.20.2 - globalthis@1.0.3: + globalthis@1.0.4: dependencies: define-properties: 1.2.1 + gopd: 1.0.1 globby@11.1.0: dependencies: @@ -16142,7 +16122,7 @@ snapshots: readable-stream: 1.0.34 through2: 0.4.2 - html-webpack-plugin@5.6.0(webpack@5.95.0): + html-webpack-plugin@5.6.3(webpack@5.95.0): dependencies: '@types/html-minifier-terser': 6.1.0 html-minifier-terser: 6.1.0 @@ -16173,21 +16153,21 @@ snapshots: dependencies: '@tootallnate/once': 2.0.0 agent-base: 6.0.2 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) transitivePeerDependencies: - supports-color http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.0 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) transitivePeerDependencies: - supports-color http-proxy@1.18.1: dependencies: eventemitter3: 4.0.7 - follow-redirects: 1.15.6(debug@4.3.6) + follow-redirects: 1.15.6(debug@4.3.7) requires-port: 1.0.0 transitivePeerDependencies: - debug @@ -16195,14 +16175,14 @@ snapshots: https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) transitivePeerDependencies: - supports-color https-proxy-agent@7.0.5: dependencies: agent-base: 7.1.0 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -16494,8 +16474,8 @@ snapshots: istanbul-lib-instrument@6.0.2: dependencies: - '@babel/core': 7.25.8 - '@babel/parser': 7.25.8 + '@babel/core': 7.26.0 + '@babel/parser': 7.26.1 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 7.6.3 @@ -16519,7 +16499,7 @@ snapshots: istanbul-lib-source-maps@4.0.1: dependencies: - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) istanbul-lib-coverage: 3.2.2 source-map: 0.6.1 transitivePeerDependencies: @@ -16554,7 +16534,7 @@ snapshots: es-get-iterator: 1.1.3 iterate-iterator: 1.0.2 - iterator.prototype@1.1.2: + iterator.prototype@1.1.3: dependencies: define-properties: 1.2.1 get-intrinsic: 1.2.4 @@ -16594,7 +16574,7 @@ snapshots: jest-worker@27.5.1: dependencies: - '@types/node': 20.16.11 + '@types/node': 20.17.3 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -16609,18 +16589,18 @@ snapshots: dependencies: argparse: 2.0.1 - jscodeshift@17.0.0(@babel/preset-env@7.25.8(@babel/core@7.25.8)): - dependencies: - '@babel/core': 7.25.8 - '@babel/parser': 7.25.8 - '@babel/plugin-transform-class-properties': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-modules-commonjs': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-transform-nullish-coalescing-operator': 7.25.8(@babel/core@7.25.8) - '@babel/plugin-transform-optional-chaining': 7.25.8(@babel/core@7.25.8) - '@babel/plugin-transform-private-methods': 7.25.7(@babel/core@7.25.8) - '@babel/preset-flow': 7.24.7(@babel/core@7.25.8) - '@babel/preset-typescript': 7.25.7(@babel/core@7.25.8) - '@babel/register': 7.25.7(@babel/core@7.25.8) + jscodeshift@17.0.0(@babel/preset-env@7.26.0(@babel/core@7.26.0)): + dependencies: + '@babel/core': 7.26.0 + '@babel/parser': 7.26.1 + '@babel/plugin-transform-class-properties': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-modules-commonjs': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-nullish-coalescing-operator': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-optional-chaining': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-private-methods': 7.25.9(@babel/core@7.26.0) + '@babel/preset-flow': 7.24.7(@babel/core@7.26.0) + '@babel/preset-typescript': 7.26.0(@babel/core@7.26.0) + '@babel/register': 7.25.9(@babel/core@7.26.0) flow-parser: 0.227.0 graceful-fs: 4.2.11 micromatch: 4.0.8 @@ -16630,7 +16610,7 @@ snapshots: temp: 0.9.4 write-file-atomic: 5.0.1 optionalDependencies: - '@babel/preset-env': 7.25.8(@babel/core@7.25.8) + '@babel/preset-env': 7.26.0(@babel/core@7.26.0) transitivePeerDependencies: - supports-color @@ -16727,46 +16707,46 @@ snapshots: jss-plugin-camel-case@10.10.0: dependencies: - '@babel/runtime': 7.25.7 + '@babel/runtime': 7.26.0 hyphenate-style-name: 1.0.4 jss: 10.10.0 jss-plugin-default-unit@10.10.0: dependencies: - '@babel/runtime': 7.25.7 + '@babel/runtime': 7.26.0 jss: 10.10.0 jss-plugin-global@10.10.0: dependencies: - '@babel/runtime': 7.25.7 + '@babel/runtime': 7.26.0 jss: 10.10.0 jss-plugin-nested@10.10.0: dependencies: - '@babel/runtime': 7.25.7 + '@babel/runtime': 7.26.0 jss: 10.10.0 tiny-warning: 1.0.3 jss-plugin-props-sort@10.10.0: dependencies: - '@babel/runtime': 7.25.7 + '@babel/runtime': 7.26.0 jss: 10.10.0 jss-plugin-rule-value-function@10.10.0: dependencies: - '@babel/runtime': 7.25.7 + '@babel/runtime': 7.26.0 jss: 10.10.0 tiny-warning: 1.0.3 jss-plugin-template@10.10.0: dependencies: - '@babel/runtime': 7.25.7 + '@babel/runtime': 7.26.0 jss: 10.10.0 tiny-warning: 1.0.3 jss-plugin-vendor-prefixer@10.10.0: dependencies: - '@babel/runtime': 7.25.7 + '@babel/runtime': 7.26.0 css-vendor: 2.0.8 jss: 10.10.0 @@ -16777,7 +16757,7 @@ snapshots: jss@10.10.0: dependencies: - '@babel/runtime': 7.25.7 + '@babel/runtime': 7.26.0 csstype: 3.1.3 is-in-browser: 1.1.3 tiny-warning: 1.0.3 @@ -17159,7 +17139,7 @@ snapshots: log4js@6.9.1: dependencies: date-format: 4.0.14 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) flatted: 3.3.1 rfdc: 1.3.1 streamroller: 3.1.5 @@ -17466,7 +17446,7 @@ snapshots: micromark@4.0.0: dependencies: '@types/debug': 4.1.12 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) decode-named-character-reference: 1.0.2 devlop: 1.1.0 micromark-core-commonmark: 2.0.1 @@ -17596,7 +17576,7 @@ snapshots: ansi-colors: 4.1.3 browser-stdout: 1.3.1 chokidar: 3.6.0 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) diff: 5.2.0 escape-string-regexp: 4.0.0 find-up: 5.0.0 @@ -17639,8 +17619,6 @@ snapshots: ms@2.0.0: {} - ms@2.1.2: {} - ms@2.1.3: {} multimatch@5.0.0: @@ -17676,9 +17654,9 @@ snapshots: nested-error-stacks@2.1.1: {} - next@14.2.15(@babel/core@7.25.8)(@opentelemetry/api@1.8.0)(@playwright/test@1.44.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + next@14.2.16(@babel/core@7.26.0)(@opentelemetry/api@1.8.0)(@playwright/test@1.44.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@next/env': 14.2.15 + '@next/env': 14.2.16 '@swc/helpers': 0.5.5 busboy: 1.6.0 caniuse-lite: 1.0.30001667 @@ -17686,17 +17664,17 @@ snapshots: postcss: 8.4.31 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - styled-jsx: 5.1.1(@babel/core@7.25.8)(babel-plugin-macros@3.1.0)(react@18.3.1) + styled-jsx: 5.1.1(@babel/core@7.26.0)(babel-plugin-macros@3.1.0)(react@18.3.1) optionalDependencies: - '@next/swc-darwin-arm64': 14.2.15 - '@next/swc-darwin-x64': 14.2.15 - '@next/swc-linux-arm64-gnu': 14.2.15 - '@next/swc-linux-arm64-musl': 14.2.15 - '@next/swc-linux-x64-gnu': 14.2.15 - '@next/swc-linux-x64-musl': 14.2.15 - '@next/swc-win32-arm64-msvc': 14.2.15 - '@next/swc-win32-ia32-msvc': 14.2.15 - '@next/swc-win32-x64-msvc': 14.2.15 + '@next/swc-darwin-arm64': 14.2.16 + '@next/swc-darwin-x64': 14.2.16 + '@next/swc-linux-arm64-gnu': 14.2.16 + '@next/swc-linux-arm64-musl': 14.2.16 + '@next/swc-linux-x64-gnu': 14.2.16 + '@next/swc-linux-x64-musl': 14.2.16 + '@next/swc-win32-arm64-msvc': 14.2.16 + '@next/swc-win32-ia32-msvc': 14.2.16 + '@next/swc-win32-x64-msvc': 14.2.16 '@opentelemetry/api': 1.8.0 '@playwright/test': 1.44.1 transitivePeerDependencies: @@ -17860,7 +17838,7 @@ snapshots: '@yarnpkg/lockfile': 1.1.0 '@yarnpkg/parsers': 3.0.0-rc.46 '@zkochan/js-yaml': 0.0.6 - axios: 1.7.5(debug@4.3.6) + axios: 1.7.7(debug@4.3.7) chalk: 4.1.2 cli-cursor: 3.1.0 cli-spinners: 2.6.1 @@ -17943,11 +17921,6 @@ snapshots: object-inspect@1.13.1: {} - object-is@1.1.5: - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - object-keys@0.4.0: {} object-keys@1.1.1: {} @@ -18016,11 +17989,11 @@ snapshots: is-docker: 2.2.1 is-wsl: 2.2.0 - openapi-fetch@0.11.2: + openapi-fetch@0.13.0: dependencies: - openapi-typescript-helpers: 0.0.12 + openapi-typescript-helpers: 0.0.15 - openapi-typescript-helpers@0.0.12: {} + openapi-typescript-helpers@0.0.15: {} opener@1.5.2: {} @@ -18230,7 +18203,7 @@ snapshots: parse-json@5.2.0: dependencies: - '@babel/code-frame': 7.25.7 + '@babel/code-frame': 7.26.0 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -18290,7 +18263,7 @@ snapshots: path-to-regexp@0.1.10: {} - path-to-regexp@2.2.1: {} + path-to-regexp@3.3.0: {} path-to-regexp@6.2.1: {} @@ -18348,7 +18321,7 @@ snapshots: playwright-core@1.44.1: {} - playwright-core@1.47.2: {} + playwright-core@1.48.2: {} playwright@1.44.1: dependencies: @@ -18356,9 +18329,9 @@ snapshots: optionalDependencies: fsevents: 2.3.2 - playwright@1.47.2: + playwright@1.48.2: dependencies: - playwright-core: 1.47.2 + playwright-core: 1.48.2 optionalDependencies: fsevents: 2.3.2 @@ -18497,8 +18470,6 @@ snapshots: punycode.js@2.3.1: {} - punycode@1.4.1: {} - punycode@2.3.1: {} qjobs@1.2.0: {} @@ -18539,9 +18510,9 @@ snapshots: react-docgen@5.4.3: dependencies: - '@babel/core': 7.25.8 - '@babel/generator': 7.25.7 - '@babel/runtime': 7.25.7 + '@babel/core': 7.26.0 + '@babel/generator': 7.26.0 + '@babel/runtime': 7.26.0 ast-types: 0.14.2 commander: 2.20.3 doctrine: 3.0.0 @@ -18558,7 +18529,7 @@ snapshots: react: 18.3.1 scheduler: 0.23.2 - react-hook-form@7.53.0(react@18.3.1): + react-hook-form@7.53.1(react@18.3.1): dependencies: react: 18.3.1 @@ -18591,7 +18562,7 @@ snapshots: react-transition-group@4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.25.7 + '@babel/runtime': 7.26.0 dom-helpers: 5.2.1 loose-envify: 1.4.0 prop-types: 15.8.1 @@ -18704,7 +18675,7 @@ snapshots: define-properties: 1.2.1 es-abstract: 1.23.3 get-intrinsic: 1.2.4 - globalthis: 1.0.3 + globalthis: 1.0.4 which-builtin-type: 1.1.3 regenerate-unicode-properties@10.2.0: @@ -18719,7 +18690,7 @@ snapshots: regenerator-transform@0.15.2: dependencies: - '@babel/runtime': 7.25.7 + '@babel/runtime': 7.26.0 regexp.prototype.flags@1.5.2: dependencies: @@ -18839,6 +18810,10 @@ snapshots: rfdc@1.3.1: {} + rifm@0.12.1(react@18.3.1): + dependencies: + react: 18.3.1 + rimraf@2.6.3: dependencies: glob: 7.2.3 @@ -18890,7 +18865,7 @@ snapshots: rtl-css-js@1.16.1: dependencies: - '@babel/runtime': 7.25.7 + '@babel/runtime': 7.26.0 run-async@2.4.1: {} @@ -18980,15 +18955,14 @@ snapshots: dependencies: randombytes: 2.1.0 - serve-handler@6.1.5: + serve-handler@6.1.6: dependencies: bytes: 3.0.0 content-disposition: 0.5.2 - fast-url-parser: 1.1.3 mime-types: 2.1.18 minimatch: 3.1.2 path-is-inside: 1.0.2 - path-to-regexp: 2.2.1 + path-to-regexp: 3.3.0 range-parser: 1.2.0 serve-static@1.16.2: @@ -19000,7 +18974,7 @@ snapshots: transitivePeerDependencies: - supports-color - serve@14.2.3: + serve@14.2.4: dependencies: '@zeit/schemas': 2.36.0 ajv: 8.12.0 @@ -19011,7 +18985,7 @@ snapshots: clipboardy: 3.0.0 compression: 1.7.4 is-port-reachable: 4.0.0 - serve-handler: 6.1.5 + serve-handler: 6.1.6 update-check: 1.5.4 transitivePeerDependencies: - supports-color @@ -19143,7 +19117,7 @@ snapshots: socket.io-parser@4.2.4: dependencies: '@socket.io/component-emitter': 3.1.0 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -19152,7 +19126,7 @@ snapshots: accepts: 1.3.8 base64id: 2.0.0 cors: 2.8.5 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) engine.io: 6.5.4 socket.io-adapter: 2.5.2 socket.io-parser: 4.2.4 @@ -19164,7 +19138,7 @@ snapshots: socks-proxy-agent@8.0.2: dependencies: agent-base: 7.1.0 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) socks: 2.7.1 transitivePeerDependencies: - supports-color @@ -19256,7 +19230,7 @@ snapshots: streamroller@3.1.5: dependencies: date-format: 4.0.14 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) fs-extra: 8.1.0 transitivePeerDependencies: - supports-color @@ -19281,8 +19255,9 @@ snapshots: emoji-regex: 9.2.2 strip-ansi: 7.1.0 - string.prototype.includes@2.0.0: + string.prototype.includes@2.0.1: dependencies: + call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.23.3 @@ -19379,12 +19354,12 @@ snapshots: stylis: 4.3.2 tslib: 2.6.2 - styled-jsx@5.1.1(@babel/core@7.25.8)(babel-plugin-macros@3.1.0)(react@18.3.1): + styled-jsx@5.1.1(@babel/core@7.26.0)(babel-plugin-macros@3.1.0)(react@18.3.1): dependencies: client-only: 0.0.1 react: 18.3.1 optionalDependencies: - '@babel/core': 7.25.8 + '@babel/core': 7.26.0 babel-plugin-macros: 3.1.0 stylis-plugin-rtl@2.1.1(stylis@4.3.4): @@ -19539,8 +19514,6 @@ snapshots: tmp@0.2.3: {} - to-fast-properties@2.0.0: {} - to-regex-range@5.0.1: dependencies: is-number: 7.0.0 @@ -19602,7 +19575,7 @@ snapshots: tslib: 1.14.1 typescript: 5.6.3 - tsx@4.19.1: + tsx@4.19.2: dependencies: esbuild: 0.23.1 get-tsconfig: 4.7.5 @@ -19612,7 +19585,7 @@ snapshots: tuf-js@2.2.0: dependencies: '@tufjs/models': 2.0.0 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) make-fetch-happen: 13.0.0 transitivePeerDependencies: - supports-color @@ -19864,12 +19837,12 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.2 - vite-node@2.1.2(@types/node@20.16.11)(terser@5.27.0): + vite-node@2.1.3(@types/node@20.17.3)(terser@5.27.0): dependencies: cac: 6.7.14 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) pathe: 1.1.2 - vite: 5.3.4(@types/node@20.16.11)(terser@5.27.0) + vite: 5.3.4(@types/node@20.17.3)(terser@5.27.0) transitivePeerDependencies: - '@types/node' - less @@ -19880,27 +19853,27 @@ snapshots: - supports-color - terser - vite@5.3.4(@types/node@20.16.11)(terser@5.27.0): + vite@5.3.4(@types/node@20.17.3)(terser@5.27.0): dependencies: esbuild: 0.21.5 postcss: 8.4.47 rollup: 4.18.1 optionalDependencies: - '@types/node': 20.16.11 + '@types/node': 20.17.3 fsevents: 2.3.3 terser: 5.27.0 - vitest@2.1.2(@types/node@20.16.11)(@vitest/ui@2.1.2)(jsdom@24.1.3)(terser@5.27.0): + vitest@2.1.3(@types/node@20.17.3)(@vitest/ui@2.1.3)(jsdom@24.1.3)(terser@5.27.0): dependencies: - '@vitest/expect': 2.1.2 - '@vitest/mocker': 2.1.2(@vitest/spy@2.1.2)(vite@5.3.4(@types/node@20.16.11)(terser@5.27.0)) - '@vitest/pretty-format': 2.1.2 - '@vitest/runner': 2.1.2 - '@vitest/snapshot': 2.1.2 - '@vitest/spy': 2.1.2 - '@vitest/utils': 2.1.2 + '@vitest/expect': 2.1.3 + '@vitest/mocker': 2.1.3(@vitest/spy@2.1.3)(vite@5.3.4(@types/node@20.17.3)(terser@5.27.0)) + '@vitest/pretty-format': 2.1.3 + '@vitest/runner': 2.1.3 + '@vitest/snapshot': 2.1.3 + '@vitest/spy': 2.1.3 + '@vitest/utils': 2.1.3 chai: 5.1.1 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) magic-string: 0.30.11 pathe: 1.1.2 std-env: 3.7.0 @@ -19908,12 +19881,12 @@ snapshots: tinyexec: 0.3.0 tinypool: 1.0.0 tinyrainbow: 1.2.0 - vite: 5.3.4(@types/node@20.16.11)(terser@5.27.0) - vite-node: 2.1.2(@types/node@20.16.11)(terser@5.27.0) + vite: 5.3.4(@types/node@20.17.3)(terser@5.27.0) + vite-node: 2.1.3(@types/node@20.17.3)(terser@5.27.0) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 20.16.11 - '@vitest/ui': 2.1.2(vitest@2.1.2) + '@types/node': 20.17.3 + '@vitest/ui': 2.1.3(vitest@2.1.3) jsdom: 24.1.3 transitivePeerDependencies: - less diff --git a/scripts/buildApiDocs/chartsSettings/index.ts b/scripts/buildApiDocs/chartsSettings/index.ts index 90479273d2a4..30c812c5182d 100644 --- a/scripts/buildApiDocs/chartsSettings/index.ts +++ b/scripts/buildApiDocs/chartsSettings/index.ts @@ -9,7 +9,7 @@ type PageType = { pathname: string; title: string; plan?: 'community' | 'pro' | export const projectChartsSettings: ProjectSettings = { output: { - apiManifestPath: path.join(process.cwd(), 'docs/data/charts-component-api-pages.ts'), + apiManifestPath: path.join(process.cwd(), 'docs/data/chartsApiPages.ts'), }, onWritingManifestFile: ( builds: PromiseSettledResult[], @@ -33,8 +33,8 @@ export const projectChartsSettings: ProjectSettings = { return `import type { MuiPage } from 'docs/src/MuiPage'; -const apiPages: MuiPage[] = ${JSON.stringify(pages, null, 2)}; -export default apiPages; +const chartsApiPages: MuiPage[] = ${JSON.stringify(pages, null, 2)}; +export default chartsApiPages; `; }, typeScriptProjects: [ diff --git a/scripts/buildApiDocs/gridSettings/index.ts b/scripts/buildApiDocs/gridSettings/index.ts index b5890318ade6..2da34675345f 100644 --- a/scripts/buildApiDocs/gridSettings/index.ts +++ b/scripts/buildApiDocs/gridSettings/index.ts @@ -9,7 +9,7 @@ type PageType = { pathname: string; title: string; plan?: 'community' | 'pro' | export const projectGridSettings: ProjectSettings = { output: { - apiManifestPath: path.join(process.cwd(), 'docs/data/data-grid-component-api-pages.ts'), + apiManifestPath: path.join(process.cwd(), 'docs/data/dataGridApiPages.ts'), }, onWritingManifestFile: ( builds: PromiseSettledResult[], @@ -33,8 +33,8 @@ export const projectGridSettings: ProjectSettings = { return `import type { MuiPage } from 'docs/src/MuiPage'; -const apiPages: MuiPage[] = ${JSON.stringify(pages, null, 2)}; -export default apiPages; +const dataGridApiPages: MuiPage[] = ${JSON.stringify(pages, null, 2)}; +export default dataGridApiPages; `; }, typeScriptProjects: [ diff --git a/scripts/buildApiDocs/pickersSettings/index.ts b/scripts/buildApiDocs/pickersSettings/index.ts index e34ef1e9057e..f40aa1ca068b 100644 --- a/scripts/buildApiDocs/pickersSettings/index.ts +++ b/scripts/buildApiDocs/pickersSettings/index.ts @@ -9,7 +9,7 @@ type PageType = { pathname: string; title: string; plan?: 'community' | 'pro' | export const projectPickersSettings: ProjectSettings = { output: { - apiManifestPath: path.join(process.cwd(), 'docs/data/date-pickers-component-api-pages.ts'), + apiManifestPath: path.join(process.cwd(), 'docs/data/datePickersApiPages.ts'), }, onWritingManifestFile: ( builds: PromiseSettledResult[], @@ -33,8 +33,8 @@ export const projectPickersSettings: ProjectSettings = { return `import type { MuiPage } from 'docs/src/MuiPage'; -const apiPages: MuiPage[] = ${JSON.stringify(pages, null, 2)}; -export default apiPages; +const datePickersApiPages: MuiPage[] = ${JSON.stringify(pages, null, 2)}; +export default datePickersApiPages; `; }, typeScriptProjects: [ diff --git a/scripts/buildApiDocs/treeViewSettings/index.ts b/scripts/buildApiDocs/treeViewSettings/index.ts index d0202935db0e..d2dda4d0879f 100644 --- a/scripts/buildApiDocs/treeViewSettings/index.ts +++ b/scripts/buildApiDocs/treeViewSettings/index.ts @@ -9,7 +9,7 @@ type PageType = { pathname: string; title: string; plan?: 'community' | 'pro' | export const projectTreeSettings: ProjectSettings = { output: { - apiManifestPath: path.join(process.cwd(), 'docs/data/tree-view-component-api-pages.ts'), + apiManifestPath: path.join(process.cwd(), 'docs/data/treeViewApiPages.ts'), }, onWritingManifestFile: ( builds: PromiseSettledResult[], @@ -33,8 +33,8 @@ export const projectTreeSettings: ProjectSettings = { return `import type { MuiPage } from 'docs/src/MuiPage'; -const apiPages: MuiPage[] = ${JSON.stringify(pages, null, 2)}; -export default apiPages; +const treeViewApiPages: MuiPage[] = ${JSON.stringify(pages, null, 2)}; +export default treeViewApiPages; `; }, typeScriptProjects: [ diff --git a/scripts/releaseChangelog.mjs b/scripts/releaseChangelog.mjs index 48424a3a3c08..209304695b1c 100644 --- a/scripts/releaseChangelog.mjs +++ b/scripts/releaseChangelog.mjs @@ -399,7 +399,7 @@ yargs(hideBin(process.argv)) }) .option('release', { // #default-branch-switch - default: 'v7.x', + default: 'master', describe: 'Ref which we want to release', type: 'string', }) diff --git a/scripts/x-data-grid-premium.exports.json b/scripts/x-data-grid-premium.exports.json index a9c1ad2bbf18..d532bf45e0c7 100644 --- a/scripts/x-data-grid-premium.exports.json +++ b/scripts/x-data-grid-premium.exports.json @@ -8,6 +8,8 @@ { "name": "BaseIconButtonPropsOverrides", "kind": "Interface" }, { "name": "BaseInputAdornmentPropsOverrides", "kind": "Interface" }, { "name": "BaseInputLabelPropsOverrides", "kind": "Interface" }, + { "name": "BaseMenuItemPropsOverrides", "kind": "Interface" }, + { "name": "BaseMenuListPropsOverrides", "kind": "Interface" }, { "name": "BasePopperPropsOverrides", "kind": "Interface" }, { "name": "BaseSelectOptionPropsOverrides", "kind": "Interface" }, { "name": "BaseSelectPropsOverrides", "kind": "Interface" }, diff --git a/scripts/x-data-grid-pro.exports.json b/scripts/x-data-grid-pro.exports.json index e3f48b5e8432..ecfde558fe7f 100644 --- a/scripts/x-data-grid-pro.exports.json +++ b/scripts/x-data-grid-pro.exports.json @@ -8,6 +8,8 @@ { "name": "BaseIconButtonPropsOverrides", "kind": "Interface" }, { "name": "BaseInputAdornmentPropsOverrides", "kind": "Interface" }, { "name": "BaseInputLabelPropsOverrides", "kind": "Interface" }, + { "name": "BaseMenuItemPropsOverrides", "kind": "Interface" }, + { "name": "BaseMenuListPropsOverrides", "kind": "Interface" }, { "name": "BasePopperPropsOverrides", "kind": "Interface" }, { "name": "BaseSelectOptionPropsOverrides", "kind": "Interface" }, { "name": "BaseSelectPropsOverrides", "kind": "Interface" }, diff --git a/scripts/x-data-grid.exports.json b/scripts/x-data-grid.exports.json index 1f9473402f2f..55c84d4b10e2 100644 --- a/scripts/x-data-grid.exports.json +++ b/scripts/x-data-grid.exports.json @@ -8,6 +8,8 @@ { "name": "BaseIconButtonPropsOverrides", "kind": "Interface" }, { "name": "BaseInputAdornmentPropsOverrides", "kind": "Interface" }, { "name": "BaseInputLabelPropsOverrides", "kind": "Interface" }, + { "name": "BaseMenuItemPropsOverrides", "kind": "Interface" }, + { "name": "BaseMenuListPropsOverrides", "kind": "Interface" }, { "name": "BasePopperPropsOverrides", "kind": "Interface" }, { "name": "BaseSelectOptionPropsOverrides", "kind": "Interface" }, { "name": "BaseSelectPropsOverrides", "kind": "Interface" }, diff --git a/scripts/x-date-pickers-pro.exports.json b/scripts/x-date-pickers-pro.exports.json index 7bce2723c04e..836e164724c1 100644 --- a/scripts/x-date-pickers-pro.exports.json +++ b/scripts/x-date-pickers-pro.exports.json @@ -61,6 +61,7 @@ { "name": "DateRangePickerDayClasses", "kind": "Interface" }, { "name": "DateRangePickerDayClassKey", "kind": "TypeAlias" }, { "name": "DateRangePickerDayProps", "kind": "Interface" }, + { "name": "DateRangePickerFieldProps", "kind": "TypeAlias" }, { "name": "DateRangePickerProps", "kind": "Interface" }, { "name": "DateRangePickerSlotProps", "kind": "Interface" }, { "name": "DateRangePickerSlots", "kind": "Interface" }, @@ -89,6 +90,7 @@ { "name": "DateTimePickerToolbarClassKey", "kind": "TypeAlias" }, { "name": "DateTimePickerToolbarProps", "kind": "Interface" }, { "name": "DateTimeRangePicker", "kind": "Variable" }, + { "name": "DateTimeRangePickerFieldProps", "kind": "TypeAlias" }, { "name": "DateTimeRangePickerProps", "kind": "Interface" }, { "name": "DateTimeRangePickerSlotProps", "kind": "Interface" }, { "name": "DateTimeRangePickerSlots", "kind": "Interface" }, @@ -188,7 +190,6 @@ { "name": "getTimeClockUtilityClass", "kind": "Function" }, { "name": "getYearCalendarUtilityClass", "kind": "Function" }, { "name": "InferError", "kind": "TypeAlias" }, - { "name": "LicenseInfo", "kind": "Class" }, { "name": "LocalizationProvider", "kind": "Variable" }, { "name": "LocalizationProviderProps", "kind": "Interface" }, { "name": "LocalizedComponent", "kind": "TypeAlias" }, @@ -292,6 +293,7 @@ { "name": "pickersLayoutClasses", "kind": "Variable" }, { "name": "PickersLayoutClassKey", "kind": "TypeAlias" }, { "name": "PickersLayoutContentWrapper", "kind": "Variable" }, + { "name": "PickersLayoutOwnerState", "kind": "Interface" }, { "name": "PickersLayoutProps", "kind": "Interface" }, { "name": "PickersLayoutRoot", "kind": "Variable" }, { "name": "PickersLayoutSlotProps", "kind": "Interface" }, @@ -409,10 +411,8 @@ { "name": "UseClearableFieldResponse", "kind": "TypeAlias" }, { "name": "UseClearableFieldSlotProps", "kind": "Interface" }, { "name": "UseClearableFieldSlots", "kind": "Interface" }, - { "name": "UseDateFieldComponentProps", "kind": "TypeAlias" }, { "name": "UseDateFieldProps", "kind": "Interface" }, { "name": "UseDateRangeFieldProps", "kind": "Interface" }, - { "name": "UseDateTimeFieldComponentProps", "kind": "TypeAlias" }, { "name": "UseDateTimeFieldProps", "kind": "Interface" }, { "name": "UseMultiInputDateRangeFieldComponentProps", "kind": "TypeAlias" }, { "name": "UseMultiInputDateRangeFieldProps", "kind": "Interface" }, @@ -428,7 +428,6 @@ { "name": "UseSingleInputDateTimeRangeFieldProps", "kind": "Interface" }, { "name": "UseSingleInputTimeRangeFieldProps", "kind": "Interface" }, { "name": "useSplitFieldProps", "kind": "Variable" }, - { "name": "UseTimeFieldComponentProps", "kind": "TypeAlias" }, { "name": "UseTimeFieldProps", "kind": "Interface" }, { "name": "useValidation", "kind": "Function" }, { "name": "validateDate", "kind": "Variable" }, diff --git a/scripts/x-date-pickers.exports.json b/scripts/x-date-pickers.exports.json index df1cacc6fcfe..94e004c0da2d 100644 --- a/scripts/x-date-pickers.exports.json +++ b/scripts/x-date-pickers.exports.json @@ -207,6 +207,7 @@ { "name": "pickersLayoutClasses", "kind": "Variable" }, { "name": "PickersLayoutClassKey", "kind": "TypeAlias" }, { "name": "PickersLayoutContentWrapper", "kind": "Variable" }, + { "name": "PickersLayoutOwnerState", "kind": "Interface" }, { "name": "PickersLayoutProps", "kind": "Interface" }, { "name": "PickersLayoutRoot", "kind": "Variable" }, { "name": "PickersLayoutSlotProps", "kind": "Interface" }, @@ -301,16 +302,13 @@ { "name": "UseClearableFieldResponse", "kind": "TypeAlias" }, { "name": "UseClearableFieldSlotProps", "kind": "Interface" }, { "name": "UseClearableFieldSlots", "kind": "Interface" }, - { "name": "UseDateFieldComponentProps", "kind": "TypeAlias" }, { "name": "UseDateFieldProps", "kind": "Interface" }, - { "name": "UseDateTimeFieldComponentProps", "kind": "TypeAlias" }, { "name": "UseDateTimeFieldProps", "kind": "Interface" }, { "name": "useParsedFormat", "kind": "Variable" }, { "name": "usePickerLayout", "kind": "ExportAssignment" }, { "name": "usePickersContext", "kind": "Variable" }, { "name": "usePickersTranslations", "kind": "Variable" }, { "name": "useSplitFieldProps", "kind": "Variable" }, - { "name": "UseTimeFieldComponentProps", "kind": "TypeAlias" }, { "name": "UseTimeFieldProps", "kind": "Interface" }, { "name": "useValidation", "kind": "Function" }, { "name": "validateDate", "kind": "Variable" }, diff --git a/scripts/x-tree-view-pro.exports.json b/scripts/x-tree-view-pro.exports.json index 29a22224c43a..1a133d166da0 100644 --- a/scripts/x-tree-view-pro.exports.json +++ b/scripts/x-tree-view-pro.exports.json @@ -24,33 +24,26 @@ { "name": "SimpleTreeViewSlots", "kind": "Interface" }, { "name": "SingleSelectTreeViewProps", "kind": "TypeAlias" }, { "name": "TreeItem", "kind": "Variable" }, - { "name": "TreeItem2", "kind": "Variable" }, - { "name": "TreeItem2Checkbox", "kind": "Variable" }, - { "name": "TreeItem2Content", "kind": "Variable" }, - { "name": "TreeItem2DragAndDropOverlay", "kind": "Function" }, - { "name": "TreeItem2DragAndDropOverlayProps", "kind": "Interface" }, - { "name": "TreeItem2GroupTransition", "kind": "Variable" }, - { "name": "TreeItem2Icon", "kind": "Function" }, - { "name": "TreeItem2IconContainer", "kind": "Variable" }, - { "name": "TreeItem2IconProps", "kind": "Interface" }, - { "name": "TreeItem2IconSlotProps", "kind": "Interface" }, - { "name": "TreeItem2IconSlots", "kind": "Interface" }, - { "name": "TreeItem2Label", "kind": "Variable" }, - { "name": "TreeItem2LabelInput", "kind": "Variable" }, - { "name": "TreeItem2LabelInputProps", "kind": "Interface" }, - { "name": "TreeItem2Props", "kind": "Interface" }, - { "name": "TreeItem2Provider", "kind": "Function" }, - { "name": "TreeItem2ProviderProps", "kind": "Interface" }, - { "name": "TreeItem2Root", "kind": "Variable" }, - { "name": "TreeItem2SlotProps", "kind": "Interface" }, - { "name": "TreeItem2Slots", "kind": "Interface" }, + { "name": "TreeItemCheckbox", "kind": "Variable" }, { "name": "treeItemClasses", "kind": "Variable" }, { "name": "TreeItemClasses", "kind": "Interface" }, { "name": "TreeItemClassKey", "kind": "TypeAlias" }, { "name": "TreeItemContent", "kind": "Variable" }, - { "name": "TreeItemContentClassKey", "kind": "TypeAlias" }, - { "name": "TreeItemContentProps", "kind": "Interface" }, + { "name": "TreeItemDragAndDropOverlay", "kind": "Function" }, + { "name": "TreeItemDragAndDropOverlayProps", "kind": "Interface" }, + { "name": "TreeItemGroupTransition", "kind": "Variable" }, + { "name": "TreeItemIcon", "kind": "Function" }, + { "name": "TreeItemIconContainer", "kind": "Variable" }, + { "name": "TreeItemIconProps", "kind": "Interface" }, + { "name": "TreeItemIconSlotProps", "kind": "Interface" }, + { "name": "TreeItemIconSlots", "kind": "Interface" }, + { "name": "TreeItemLabel", "kind": "Variable" }, + { "name": "TreeItemLabelInput", "kind": "Variable" }, + { "name": "TreeItemLabelInputProps", "kind": "Interface" }, { "name": "TreeItemProps", "kind": "Interface" }, + { "name": "TreeItemProvider", "kind": "Function" }, + { "name": "TreeItemProviderProps", "kind": "Interface" }, + { "name": "TreeItemRoot", "kind": "Variable" }, { "name": "TreeItemSlotProps", "kind": "Interface" }, { "name": "TreeItemSlots", "kind": "Interface" }, { "name": "TreeView", "kind": "Variable" }, @@ -65,23 +58,22 @@ { "name": "TreeViewItemId", "kind": "TypeAlias" }, { "name": "TreeViewItemsReorderingAction", "kind": "TypeAlias" }, { "name": "TreeViewProps", "kind": "Interface" }, + { "name": "TreeViewSelectionPropagation", "kind": "Interface" }, { "name": "TreeViewSlotProps", "kind": "Interface" }, { "name": "TreeViewSlots", "kind": "Interface" }, { "name": "unstable_resetCleanupTracking", "kind": "Variable" }, - { "name": "unstable_useTreeItem2", "kind": "Variable" }, - { "name": "useTreeItem2", "kind": "Variable" }, - { "name": "UseTreeItem2CheckboxSlotOwnProps", "kind": "Interface" }, - { "name": "UseTreeItem2ContentSlotOwnProps", "kind": "Interface" }, - { "name": "UseTreeItem2DragAndDropOverlaySlotOwnProps", "kind": "Interface" }, - { "name": "UseTreeItem2GroupTransitionSlotOwnProps", "kind": "Interface" }, - { "name": "UseTreeItem2IconContainerSlotOwnProps", "kind": "Interface" }, - { "name": "UseTreeItem2LabelInputSlotOwnProps", "kind": "Interface" }, - { "name": "UseTreeItem2LabelSlotOwnProps", "kind": "Interface" }, - { "name": "UseTreeItem2Parameters", "kind": "Interface" }, - { "name": "UseTreeItem2ReturnValue", "kind": "Interface" }, - { "name": "UseTreeItem2RootSlotOwnProps", "kind": "Interface" }, - { "name": "UseTreeItem2Status", "kind": "Interface" }, - { "name": "useTreeItem2Utils", "kind": "Variable" }, - { "name": "useTreeItemState", "kind": "Function" }, + { "name": "useTreeItem", "kind": "Variable" }, + { "name": "UseTreeItemCheckboxSlotOwnProps", "kind": "Interface" }, + { "name": "UseTreeItemContentSlotOwnProps", "kind": "Interface" }, + { "name": "UseTreeItemDragAndDropOverlaySlotOwnProps", "kind": "Interface" }, + { "name": "UseTreeItemGroupTransitionSlotOwnProps", "kind": "Interface" }, + { "name": "UseTreeItemIconContainerSlotOwnProps", "kind": "Interface" }, + { "name": "UseTreeItemLabelInputSlotOwnProps", "kind": "Interface" }, + { "name": "UseTreeItemLabelSlotOwnProps", "kind": "Interface" }, + { "name": "UseTreeItemParameters", "kind": "Interface" }, + { "name": "UseTreeItemReturnValue", "kind": "Interface" }, + { "name": "UseTreeItemRootSlotOwnProps", "kind": "Interface" }, + { "name": "UseTreeItemStatus", "kind": "Interface" }, + { "name": "useTreeItemUtils", "kind": "Variable" }, { "name": "useTreeViewApiRef", "kind": "Variable" } ] diff --git a/scripts/x-tree-view.exports.json b/scripts/x-tree-view.exports.json index fcc6706acbc0..01fac9eb0846 100644 --- a/scripts/x-tree-view.exports.json +++ b/scripts/x-tree-view.exports.json @@ -28,33 +28,26 @@ { "name": "SimpleTreeViewSlots", "kind": "Interface" }, { "name": "SingleSelectTreeViewProps", "kind": "TypeAlias" }, { "name": "TreeItem", "kind": "Variable" }, - { "name": "TreeItem2", "kind": "Variable" }, - { "name": "TreeItem2Checkbox", "kind": "Variable" }, - { "name": "TreeItem2Content", "kind": "Variable" }, - { "name": "TreeItem2DragAndDropOverlay", "kind": "Function" }, - { "name": "TreeItem2DragAndDropOverlayProps", "kind": "Interface" }, - { "name": "TreeItem2GroupTransition", "kind": "Variable" }, - { "name": "TreeItem2Icon", "kind": "Function" }, - { "name": "TreeItem2IconContainer", "kind": "Variable" }, - { "name": "TreeItem2IconProps", "kind": "Interface" }, - { "name": "TreeItem2IconSlotProps", "kind": "Interface" }, - { "name": "TreeItem2IconSlots", "kind": "Interface" }, - { "name": "TreeItem2Label", "kind": "Variable" }, - { "name": "TreeItem2LabelInput", "kind": "Variable" }, - { "name": "TreeItem2LabelInputProps", "kind": "Interface" }, - { "name": "TreeItem2Props", "kind": "Interface" }, - { "name": "TreeItem2Provider", "kind": "Function" }, - { "name": "TreeItem2ProviderProps", "kind": "Interface" }, - { "name": "TreeItem2Root", "kind": "Variable" }, - { "name": "TreeItem2SlotProps", "kind": "Interface" }, - { "name": "TreeItem2Slots", "kind": "Interface" }, + { "name": "TreeItemCheckbox", "kind": "Variable" }, { "name": "treeItemClasses", "kind": "Variable" }, { "name": "TreeItemClasses", "kind": "Interface" }, { "name": "TreeItemClassKey", "kind": "TypeAlias" }, { "name": "TreeItemContent", "kind": "Variable" }, - { "name": "TreeItemContentClassKey", "kind": "TypeAlias" }, - { "name": "TreeItemContentProps", "kind": "Interface" }, + { "name": "TreeItemDragAndDropOverlay", "kind": "Function" }, + { "name": "TreeItemDragAndDropOverlayProps", "kind": "Interface" }, + { "name": "TreeItemGroupTransition", "kind": "Variable" }, + { "name": "TreeItemIcon", "kind": "Function" }, + { "name": "TreeItemIconContainer", "kind": "Variable" }, + { "name": "TreeItemIconProps", "kind": "Interface" }, + { "name": "TreeItemIconSlotProps", "kind": "Interface" }, + { "name": "TreeItemIconSlots", "kind": "Interface" }, + { "name": "TreeItemLabel", "kind": "Variable" }, + { "name": "TreeItemLabelInput", "kind": "Variable" }, + { "name": "TreeItemLabelInputProps", "kind": "Interface" }, { "name": "TreeItemProps", "kind": "Interface" }, + { "name": "TreeItemProvider", "kind": "Function" }, + { "name": "TreeItemProviderProps", "kind": "Interface" }, + { "name": "TreeItemRoot", "kind": "Variable" }, { "name": "TreeItemSlotProps", "kind": "Interface" }, { "name": "TreeItemSlots", "kind": "Interface" }, { "name": "TreeView", "kind": "Variable" }, @@ -69,23 +62,22 @@ { "name": "TreeViewItemId", "kind": "TypeAlias" }, { "name": "TreeViewItemsReorderingAction", "kind": "TypeAlias" }, { "name": "TreeViewProps", "kind": "Interface" }, + { "name": "TreeViewSelectionPropagation", "kind": "Interface" }, { "name": "TreeViewSlotProps", "kind": "Interface" }, { "name": "TreeViewSlots", "kind": "Interface" }, { "name": "unstable_resetCleanupTracking", "kind": "Variable" }, - { "name": "unstable_useTreeItem2", "kind": "Variable" }, - { "name": "useTreeItem2", "kind": "Variable" }, - { "name": "UseTreeItem2CheckboxSlotOwnProps", "kind": "Interface" }, - { "name": "UseTreeItem2ContentSlotOwnProps", "kind": "Interface" }, - { "name": "UseTreeItem2DragAndDropOverlaySlotOwnProps", "kind": "Interface" }, - { "name": "UseTreeItem2GroupTransitionSlotOwnProps", "kind": "Interface" }, - { "name": "UseTreeItem2IconContainerSlotOwnProps", "kind": "Interface" }, - { "name": "UseTreeItem2LabelInputSlotOwnProps", "kind": "Interface" }, - { "name": "UseTreeItem2LabelSlotOwnProps", "kind": "Interface" }, - { "name": "UseTreeItem2Parameters", "kind": "Interface" }, - { "name": "UseTreeItem2ReturnValue", "kind": "Interface" }, - { "name": "UseTreeItem2RootSlotOwnProps", "kind": "Interface" }, - { "name": "UseTreeItem2Status", "kind": "Interface" }, - { "name": "useTreeItem2Utils", "kind": "Variable" }, - { "name": "useTreeItemState", "kind": "Function" }, + { "name": "useTreeItem", "kind": "Variable" }, + { "name": "UseTreeItemCheckboxSlotOwnProps", "kind": "Interface" }, + { "name": "UseTreeItemContentSlotOwnProps", "kind": "Interface" }, + { "name": "UseTreeItemDragAndDropOverlaySlotOwnProps", "kind": "Interface" }, + { "name": "UseTreeItemGroupTransitionSlotOwnProps", "kind": "Interface" }, + { "name": "UseTreeItemIconContainerSlotOwnProps", "kind": "Interface" }, + { "name": "UseTreeItemLabelInputSlotOwnProps", "kind": "Interface" }, + { "name": "UseTreeItemLabelSlotOwnProps", "kind": "Interface" }, + { "name": "UseTreeItemParameters", "kind": "Interface" }, + { "name": "UseTreeItemReturnValue", "kind": "Interface" }, + { "name": "UseTreeItemRootSlotOwnProps", "kind": "Interface" }, + { "name": "UseTreeItemStatus", "kind": "Interface" }, + { "name": "useTreeItemUtils", "kind": "Variable" }, { "name": "useTreeViewApiRef", "kind": "Variable" } ] diff --git a/test/e2e/fixtures/DatePicker/BasicDesktopDatePicker.tsx b/test/e2e/fixtures/DatePicker/BasicDesktopDatePicker.tsx index 992dd6244777..cdf3be6e2d0f 100644 --- a/test/e2e/fixtures/DatePicker/BasicDesktopDatePicker.tsx +++ b/test/e2e/fixtures/DatePicker/BasicDesktopDatePicker.tsx @@ -7,7 +7,6 @@ export default function BasicDesktopDatePicker() { return ( + + + ); +} diff --git a/test/e2e/fixtures/DatePicker/BasicDesktopDateRangePicker.tsx b/test/e2e/fixtures/DatePicker/BasicDesktopDateRangePicker.tsx index e8823aaa3910..6d9b2d52874f 100644 --- a/test/e2e/fixtures/DatePicker/BasicDesktopDateRangePicker.tsx +++ b/test/e2e/fixtures/DatePicker/BasicDesktopDateRangePicker.tsx @@ -6,7 +6,7 @@ import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; export default function BasicDesktopDateRangePicker() { return ( - + ); } diff --git a/test/e2e/fixtures/DatePicker/BasicDesktopDateTimePicker.tsx b/test/e2e/fixtures/DatePicker/BasicDesktopDateTimePicker.tsx index f1f8dc403abf..13861f2069cd 100644 --- a/test/e2e/fixtures/DatePicker/BasicDesktopDateTimePicker.tsx +++ b/test/e2e/fixtures/DatePicker/BasicDesktopDateTimePicker.tsx @@ -6,7 +6,7 @@ import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; export default function BasicDesktopDateTimePicker() { return ( - + ); } diff --git a/test/e2e/fixtures/DatePicker/BasicMobileDatePicker.tsx b/test/e2e/fixtures/DatePicker/BasicMobileDatePicker.tsx index 7b869f691654..67d126d5eea1 100644 --- a/test/e2e/fixtures/DatePicker/BasicMobileDatePicker.tsx +++ b/test/e2e/fixtures/DatePicker/BasicMobileDatePicker.tsx @@ -6,7 +6,7 @@ import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; export default function BasicMobileDatePicker() { return ( - + ); } diff --git a/test/e2e/fixtures/DatePicker/DesktopDatePickerFormNonAccessibleDOMStructure.tsx b/test/e2e/fixtures/DatePicker/DesktopDatePickerFormNonAccessibleDOMStructure.tsx new file mode 100644 index 000000000000..357302cc37b2 --- /dev/null +++ b/test/e2e/fixtures/DatePicker/DesktopDatePickerFormNonAccessibleDOMStructure.tsx @@ -0,0 +1,29 @@ +import * as React from 'react'; +import dayjs from 'dayjs'; +import { DesktopDatePicker } from '@mui/x-date-pickers/DesktopDatePicker'; +import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; +import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; + +export default function DesktopDatePickerFormNonAccessibleDOMStructure() { + const [submittedDate, setSubmittedDate] = React.useState(undefined); + const submitHandler: React.FormEventHandler = (event) => { + event.preventDefault(); + setSubmittedDate( + new FormData(event.target as HTMLFormElement).values().next().value?.toString(), + ); + }; + return ( +
+ + + + {submittedDate && } + +
+ ); +} diff --git a/test/e2e/fixtures/DatePicker/MobileDatePickerWithClearActionNonAccessibleDOMStructure.tsx b/test/e2e/fixtures/DatePicker/MobileDatePickerWithClearActionNonAccessibleDOMStructure.tsx new file mode 100644 index 000000000000..60be9bdcaf52 --- /dev/null +++ b/test/e2e/fixtures/DatePicker/MobileDatePickerWithClearActionNonAccessibleDOMStructure.tsx @@ -0,0 +1,22 @@ +import * as React from 'react'; +import dayjs from 'dayjs'; +import { MobileDatePicker } from '@mui/x-date-pickers/MobileDatePicker'; +import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; +import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; + +export default function MobileDatePickerWithClearActionNonAccessibleDOMStructure() { + return ( + + + + ); +} diff --git a/test/e2e/fixtures/DatePicker/ReadonlyDesktopDateRangePickerSingle.tsx b/test/e2e/fixtures/DatePicker/ReadonlyDesktopDateRangePickerSingle.tsx new file mode 100644 index 000000000000..5d64567e7ff1 --- /dev/null +++ b/test/e2e/fixtures/DatePicker/ReadonlyDesktopDateRangePickerSingle.tsx @@ -0,0 +1,16 @@ +import * as React from 'react'; +import { DateRangePicker } from '@mui/x-date-pickers-pro/DateRangePicker'; +import { SingleInputDateRangeField } from '@mui/x-date-pickers-pro/SingleInputDateRangeField'; +import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; +import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; + +export default function ReadonlyDesktopDateRangePickerSingle() { + return ( + + + + ); +} diff --git a/test/e2e/fixtures/DatePicker/ReadonlyDesktopDateRangePickerSingleNonAccessibleDOMStructure.tsx b/test/e2e/fixtures/DatePicker/ReadonlyDesktopDateRangePickerSingleNonAccessibleDOMStructure.tsx new file mode 100644 index 000000000000..0ad01f33f707 --- /dev/null +++ b/test/e2e/fixtures/DatePicker/ReadonlyDesktopDateRangePickerSingleNonAccessibleDOMStructure.tsx @@ -0,0 +1,17 @@ +import * as React from 'react'; +import { DateRangePicker } from '@mui/x-date-pickers-pro/DateRangePicker'; +import { SingleInputDateRangeField } from '@mui/x-date-pickers-pro/SingleInputDateRangeField'; +import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; +import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; + +export default function ReadonlyDesktopDateRangePickerSingleNonAccessibleDOMStructure() { + return ( + + + + ); +} diff --git a/test/e2e/fixtures/DatePicker/SingleDesktopDateRangePickerWithTZ.tsx b/test/e2e/fixtures/DatePicker/SingleDesktopDateRangePickerWithTZ.tsx index 0f920bf2aa9b..8eb717e0c3e2 100644 --- a/test/e2e/fixtures/DatePicker/SingleDesktopDateRangePickerWithTZ.tsx +++ b/test/e2e/fixtures/DatePicker/SingleDesktopDateRangePickerWithTZ.tsx @@ -14,7 +14,6 @@ export default function BasicDesktopDateRangePicker() { return ( diff --git a/test/e2e/index.test.ts b/test/e2e/index.test.ts index 558914be9364..f9145efca503 100644 --- a/test/e2e/index.test.ts +++ b/test/e2e/index.test.ts @@ -622,7 +622,8 @@ async function initializeEnvironment( // assertion for: https://github.com/mui/mui-x/issues/12652 it('should allow field editing after opening and closing the picker', async () => { - await renderFixture('DatePicker/BasicClearableDesktopDatePicker'); + await renderFixture('DatePicker/BasicDesktopDatePicker'); + // open picker await page.getByRole('button').click(); await page.waitForSelector('[role="dialog"]', { state: 'attached' }); @@ -630,11 +631,13 @@ async function initializeEnvironment( await page.getByRole('button', { name: 'Choose date' }).click(); await page.waitForSelector('[role="dialog"]', { state: 'detached' }); - // click on the input to focus it - await page.getByRole('textbox').click(); + await page.locator(`.${pickersSectionListClasses.root}`).click(); + await page.getByRole(`spinbutton`, { name: 'Month' }).fill('04'); + await page.getByRole(`spinbutton`, { name: 'Day' }).fill('11'); + await page.getByRole(`spinbutton`, { name: 'Year' }).fill('2022'); - // test that the input value is set after focus - expect(await page.getByRole('textbox').inputValue()).to.equal('MM/DD/YYYY'); + const input = page.getByRole('textbox', { includeHidden: true }); + expect(await input.inputValue()).to.equal('04/11/2022'); }); it('should allow filling in a value and clearing a value', async () => { @@ -726,8 +729,8 @@ async function initializeEnvironment( expect(await page.evaluate(() => document.activeElement?.textContent)).to.equal('MM'); }); - it('should focus the first field section after clearing a value in v6 input', async () => { - await renderFixture('DatePicker/BasicClearableDesktopDatePicker'); + it('should focus the first field section after clearing a value with the non-accessible DOM structure', async () => { + await renderFixture('DatePicker/BasicDesktopDatePickerNonAccessibleDOMStructure'); const textbox = page.getByRole('textbox'); // locator.fill('2') does not work reliably for this case in all browsers @@ -752,7 +755,7 @@ async function initializeEnvironment( }); it('should submit a form when clicking "Enter" key', async () => { - await renderFixture('DatePicker/DesktopDatePickerForm'); + await renderFixture('DatePicker/DesktopDatePickerFormNonAccessibleDOMStructure'); const textbox = page.getByRole('textbox'); await textbox.focus(); @@ -814,8 +817,10 @@ async function initializeEnvironment( ); }); - it('should have consistent `placeholder` and `value` behavior', async () => { - await renderFixture('DatePicker/MobileDatePickerV6WithClearAction'); + it('should have consistent `placeholder` and `value` behavior in the non-accessible DOM structure', async () => { + await renderFixture( + 'DatePicker/MobileDatePickerWithClearActionNonAccessibleDOMStructure', + ); const input = page.getByRole('textbox'); @@ -990,13 +995,13 @@ async function initializeEnvironment( await page.waitForSelector('[role="tooltip"]', { state: 'detached' }); }); - it('should have the same selection process when "readOnly" with single input v7 field', async () => { + it('should have the same selection process when "readOnly" with single input field with an accessible DOM structure', async () => { // firefox in CI is not happy with this test if (browserType.name() === 'firefox') { return; } - await renderFixture('DatePicker/ReadonlyDesktopDateRangePickerSingleV7'); + await renderFixture('DatePicker/ReadonlyDesktopDateRangePickerSingle'); await page.locator(`.${pickersSectionListClasses.root}`).first().click(); @@ -1014,13 +1019,15 @@ async function initializeEnvironment( ); }); - it('should have the same selection process when "readOnly" with single input v6 field', async () => { + it('should have the same selection process when "readOnly" with single input field with a non-accessible DOM structure', async () => { // firefox in CI is not happy with this test if (browserType.name() === 'firefox') { return; } - await renderFixture('DatePicker/ReadonlyDesktopDateRangePickerSingleV6'); + await renderFixture( + 'DatePicker/ReadonlyDesktopDateRangePickerSingleNonAccessibleDOMStructure', + ); await page.getByRole('textbox').click(); diff --git a/test/package.json b/test/package.json index 3bcd15516424..7b7c92519386 100644 --- a/test/package.json +++ b/test/package.json @@ -6,7 +6,7 @@ "typescript": "tsc -p tsconfig.json" }, "devDependencies": { - "@babel/runtime": "^7.25.7", + "@babel/runtime": "^7.26.0", "@emotion/cache": "^11.13.1", "@emotion/react": "^11.13.3", "@mui/material": "^5.16.7", @@ -21,7 +21,7 @@ "@playwright/test": "^1.44.1", "@react-spring/web": "^9.7.5", "@types/chai": "^4.3.20", - "@types/karma": "^6.3.8", + "@types/karma": "^6.3.9", "@types/moment-jalaali": "^0.7.9", "@types/prop-types": "^15.7.13", "@types/react": "^18.3.4", diff --git a/test/performance-charts/package.json b/test/performance-charts/package.json index fe5e946b9981..8fa196176d91 100644 --- a/test/performance-charts/package.json +++ b/test/performance-charts/package.json @@ -11,15 +11,15 @@ "@emotion/react": "^11.13.3", "@mui/x-charts": "workspace:*", "@mui/x-charts-pro": "workspace:*", - "@testing-library/jest-dom": "^6.5.0", + "@testing-library/jest-dom": "^6.6.2", "@testing-library/react": "^16.0.1", "@testing-library/user-event": "^14.5.2", - "@vitejs/plugin-react": "^4.3.2", + "@vitejs/plugin-react": "^4.3.3", "@vitejs/plugin-react-swc": "^3.7.1", - "@vitest/ui": "2.1.2", + "@vitest/ui": "2.1.3", "jsdom": "^24.1.3", "react": "^18.3.1", "react-dom": "^18.3.1", - "vitest": "2.1.2" + "vitest": "2.1.3" } } diff --git a/test/regressions/data-grid/DataGridOverlays.js b/test/regressions/data-grid/DataGridOverlays.js new file mode 100644 index 000000000000..a3afeee84d5b --- /dev/null +++ b/test/regressions/data-grid/DataGridOverlays.js @@ -0,0 +1,168 @@ +/* eslint-disable react/prop-types */ +import * as React from 'react'; +import { DataGrid } from '@mui/x-data-grid'; + +function FlexParent({ children, style }) { + return
{children}
; +} + +function FlexParentNoRowsOverlay() { + return ( +
+ FlexParentNoRowsOverlay + + + +
+ ); +} + +function FlexParentMinHeightNoRowsOverlay() { + return ( +
+ FlexParentMinHeightNoRowsOverlay + + + +
+ ); +} + +function FlexParentMaxHeightNoRowsOverlay() { + return ( +
+ FlexParentMaxHeightNoRowsOverlay + + + +
+ ); +} + +function AutoHeightNoRowsOverlay() { + return ( +
+ AutoHeightNoRowsOverlay +
+ +
+
+ ); +} + +function AutoHeightLoadingOverlay() { + return ( +
+ AutoHeightLoadingOverlay +
+ +
+
+ ); +} + +function PredefinedSizeNoRowsLoadingOverlay() { + return ( +
+ PredefinedSizeNoRowsLoadingOverlay +
+ +
+
+ ); +} + +function FlexParentSkeletonOverlay() { + return ( +
+ FlexParentSkeletonOverlay + + + +
+ ); +} + +function FlexParentMinHeightSkeletonOverlay() { + return ( +
+ FlexParentMinHeightSkeletonOverlay + + + +
+ ); +} + +function FlexParentMaxHeightSkeletonOverlay() { + return ( +
+ FlexParentMaxHeightSkeletonOverlay + + + +
+ ); +} + +function AutoHeightSkeletonOverlay() { + return ( +
+ AutoHeightSkeletonOverlay +
+ +
+
+ ); +} + +function PredefinedSizeSkeletonOverlay() { + return ( +
+ PredefinedSizeSkeletonOverlay +
+ +
+
+ ); +} + +export default function DataGridFlexParentOverlay() { + return ( +
+ + + + + + + + + + + + +
+ ); +} diff --git a/test/utils/pickers/adapters.ts b/test/utils/pickers/adapters.ts index a236fc563a46..2aa34e1d3663 100644 --- a/test/utils/pickers/adapters.ts +++ b/test/utils/pickers/adapters.ts @@ -19,7 +19,7 @@ export type AdapterName = | 'date-fns-jalali'; export const availableAdapters: { - [key in AdapterName]: new (...args: any) => MuiPickersAdapter; + [key in AdapterName]: new (...args: any) => MuiPickersAdapter; } = { 'date-fns': AdapterDateFns, dayjs: AdapterDayjs, @@ -59,4 +59,4 @@ if (/jsdom/.test(window.navigator.userAgent)) { export class AdapterClassToUse extends AdapterClassToExtend {} -export const adapterToUse = new AdapterClassToUse(); +export const adapterToUse = new AdapterClassToUse() as MuiPickersAdapter; diff --git a/test/utils/pickers/describeGregorianAdapter/describeGregorianAdapter.ts b/test/utils/pickers/describeGregorianAdapter/describeGregorianAdapter.ts index 9b457d082181..3fb54da667c5 100644 --- a/test/utils/pickers/describeGregorianAdapter/describeGregorianAdapter.ts +++ b/test/utils/pickers/describeGregorianAdapter/describeGregorianAdapter.ts @@ -1,5 +1,5 @@ import createDescribe from '@mui/internal-test-utils/createDescribe'; -import { MuiPickersAdapter, PickerValidDate } from '@mui/x-date-pickers/models'; +import { MuiPickersAdapter } from '@mui/x-date-pickers/models'; import { testCalculations } from './testCalculations'; import { testLocalization } from './testLocalization'; import { testFormat } from './testFormat'; @@ -8,9 +8,9 @@ import { DescribeGregorianAdapterTestSuiteParams, } from './describeGregorianAdapter.types'; -function innerGregorianDescribeAdapter( - Adapter: new (...args: any) => MuiPickersAdapter, - params: DescribeGregorianAdapterParams, +function innerGregorianDescribeAdapter( + Adapter: new (...args: any) => MuiPickersAdapter, + params: DescribeGregorianAdapterParams, ) { const prepareAdapter = params.prepareAdapter ?? ((adapter) => adapter); @@ -29,7 +29,7 @@ function innerGregorianDescribeAdapter( prepareAdapter(adapterTZ); describe(adapter.lib, () => { - const testSuitParams: DescribeGregorianAdapterTestSuiteParams = { + const testSuitParams: DescribeGregorianAdapterTestSuiteParams = { ...params, adapter, adapterTZ, @@ -42,15 +42,15 @@ function innerGregorianDescribeAdapter( }); } -type Params = [ - Adapter: new (...args: any) => MuiPickersAdapter, - params: DescribeGregorianAdapterParams, +type Params = [ + Adapter: new (...args: any) => MuiPickersAdapter, + params: DescribeGregorianAdapterParams, ]; type DescribeGregorianAdapter = { - (...args: Params): void; - skip: (...args: Params) => void; - only: (...args: Params) => void; + (...args: Params): void; + skip: (...args: Params) => void; + only: (...args: Params) => void; }; export const describeGregorianAdapter = createDescribe( diff --git a/test/utils/pickers/describeGregorianAdapter/describeGregorianAdapter.types.ts b/test/utils/pickers/describeGregorianAdapter/describeGregorianAdapter.types.ts index 2f1c49b76d2d..3840f7db22ad 100644 --- a/test/utils/pickers/describeGregorianAdapter/describeGregorianAdapter.types.ts +++ b/test/utils/pickers/describeGregorianAdapter/describeGregorianAdapter.types.ts @@ -1,21 +1,21 @@ import { MuiPickersAdapter, PickersTimezone, PickerValidDate } from '@mui/x-date-pickers/models'; -export interface DescribeGregorianAdapterParams { - prepareAdapter?: (adapter: MuiPickersAdapter) => void; +export interface DescribeGregorianAdapterParams { + prepareAdapter?: (adapter: MuiPickersAdapter) => void; formatDateTime: string; - getLocaleFromDate?: (value: TDate) => string; + getLocaleFromDate?: (value: PickerValidDate) => string; dateLibInstanceWithTimezoneSupport?: any; setDefaultTimezone: (timezone: PickersTimezone | undefined) => void; frenchLocale: TLocale; } -export interface DescribeGregorianAdapterTestSuiteParams - extends Omit, 'frenchLocale'> { - adapter: MuiPickersAdapter; - adapterTZ: MuiPickersAdapter; - adapterFr: MuiPickersAdapter; +export interface DescribeGregorianAdapterTestSuiteParams + extends Omit, 'frenchLocale'> { + adapter: MuiPickersAdapter; + adapterTZ: MuiPickersAdapter; + adapterFr: MuiPickersAdapter; } -export type DescribeGregorianAdapterTestSuite = ( - params: DescribeGregorianAdapterTestSuiteParams, +export type DescribeGregorianAdapterTestSuite = ( + params: DescribeGregorianAdapterTestSuiteParams, ) => void; diff --git a/test/utils/pickers/describeGregorianAdapter/testCalculations.ts b/test/utils/pickers/describeGregorianAdapter/testCalculations.ts index 10ef8845ec08..8e698658e7e0 100644 --- a/test/utils/pickers/describeGregorianAdapter/testCalculations.ts +++ b/test/utils/pickers/describeGregorianAdapter/testCalculations.ts @@ -10,10 +10,7 @@ import { TEST_DATE_ISO_STRING, TEST_DATE_LOCALE_STRING } from './describeGregori * then we check that both dates have the same hour value. */ // We change to -const expectSameTimeInMonacoTZ = ( - adapter: MuiPickersAdapter, - value: TDate, -) => { +const expectSameTimeInMonacoTZ = (adapter: MuiPickersAdapter, value: PickerValidDate) => { const valueInMonacoTz = adapter.setTimezone(value, 'Europe/Monaco'); expect(adapter.getHours(value)).to.equal(adapter.getHours(valueInMonacoTz)); }; diff --git a/test/utils/pickers/describeHijriAdapter/describeHijriAdapter.ts b/test/utils/pickers/describeHijriAdapter/describeHijriAdapter.ts index 8f5c520b3e15..21b591e25eb9 100644 --- a/test/utils/pickers/describeHijriAdapter/describeHijriAdapter.ts +++ b/test/utils/pickers/describeHijriAdapter/describeHijriAdapter.ts @@ -1,12 +1,12 @@ import createDescribe from '@mui/internal-test-utils/createDescribe'; -import { MuiPickersAdapter, PickerValidDate } from '@mui/x-date-pickers/models'; +import { MuiPickersAdapter } from '@mui/x-date-pickers/models'; import { testCalculations } from './testCalculations'; import { testLocalization } from './testLocalization'; import { testFormat } from './testFormat'; import { DescribeHijriAdapterParams } from './describeHijriAdapter.types'; -function innerJalaliDescribeAdapter( - Adapter: new (...args: any) => MuiPickersAdapter, +function innerJalaliDescribeAdapter( + Adapter: new (...args: any) => MuiPickersAdapter, params: DescribeHijriAdapterParams, ) { const adapter = new Adapter(); diff --git a/test/utils/pickers/describeHijriAdapter/describeHijriAdapter.types.ts b/test/utils/pickers/describeHijriAdapter/describeHijriAdapter.types.ts index 09c2da3616a8..588c5a6d7b99 100644 --- a/test/utils/pickers/describeHijriAdapter/describeHijriAdapter.types.ts +++ b/test/utils/pickers/describeHijriAdapter/describeHijriAdapter.types.ts @@ -1,10 +1,8 @@ -import { MuiPickersAdapter, PickerValidDate } from '@mui/x-date-pickers/models'; +import { MuiPickersAdapter } from '@mui/x-date-pickers/models'; export interface DescribeHijriAdapterParams { before?: () => void; after?: () => void; } -export type DescribeHijriAdapterTestSuite = (params: { - adapter: MuiPickersAdapter; -}) => void; +export type DescribeHijriAdapterTestSuite = (params: { adapter: MuiPickersAdapter }) => void; diff --git a/test/utils/pickers/describeJalaliAdapter/describeJalaliAdapter.ts b/test/utils/pickers/describeJalaliAdapter/describeJalaliAdapter.ts index 15c7968352d7..b31048d1fcd2 100644 --- a/test/utils/pickers/describeJalaliAdapter/describeJalaliAdapter.ts +++ b/test/utils/pickers/describeJalaliAdapter/describeJalaliAdapter.ts @@ -1,12 +1,12 @@ import createDescribe from '@mui/internal-test-utils/createDescribe'; -import { MuiPickersAdapter, PickerValidDate } from '@mui/x-date-pickers/models'; +import { MuiPickersAdapter } from '@mui/x-date-pickers/models'; import { testCalculations } from './testCalculations'; import { testLocalization } from './testLocalization'; import { testFormat } from './testFormat'; import { DescribeJalaliAdapterParams } from './describeJalaliAdapter.types'; -function innerJalaliDescribeAdapter( - Adapter: new (...args: any) => MuiPickersAdapter, +function innerJalaliDescribeAdapter( + Adapter: new (...args: any) => MuiPickersAdapter, params: DescribeJalaliAdapterParams, ) { const adapter = new Adapter(); diff --git a/test/utils/pickers/describeJalaliAdapter/describeJalaliAdapter.types.ts b/test/utils/pickers/describeJalaliAdapter/describeJalaliAdapter.types.ts index 176319483313..12c1df5edf5d 100644 --- a/test/utils/pickers/describeJalaliAdapter/describeJalaliAdapter.types.ts +++ b/test/utils/pickers/describeJalaliAdapter/describeJalaliAdapter.types.ts @@ -1,10 +1,8 @@ -import { MuiPickersAdapter, PickerValidDate } from '@mui/x-date-pickers/models'; +import { MuiPickersAdapter } from '@mui/x-date-pickers/models'; export interface DescribeJalaliAdapterParams { before?: () => void; after?: () => void; } -export type DescribeJalaliAdapterTestSuite = (params: { - adapter: MuiPickersAdapter; -}) => void; +export type DescribeJalaliAdapterTestSuite = (params: { adapter: MuiPickersAdapter }) => void; diff --git a/test/utils/pickers/describeRangeValidation/testTextFieldKeyboardRangeValidation.tsx b/test/utils/pickers/describeRangeValidation/testTextFieldKeyboardRangeValidation.tsx index c25c09224a9a..37ce52823b4a 100644 --- a/test/utils/pickers/describeRangeValidation/testTextFieldKeyboardRangeValidation.tsx +++ b/test/utils/pickers/describeRangeValidation/testTextFieldKeyboardRangeValidation.tsx @@ -29,7 +29,7 @@ export const testTextFieldKeyboardRangeValidation: DescribeRangeValidationTestSu describe('text field keyboard:', () => { it('should not accept end date prior to start state', () => { const onErrorMock = spy(); - render(); + render(); expect(onErrorMock.callCount).to.equal(0); act(() => { @@ -53,7 +53,6 @@ export const testTextFieldKeyboardRangeValidation: DescribeRangeValidationTestSu const onErrorMock = spy(); const { setProps } = render( adapterToUse.isAfter(date, adapterToUse.date('2018-03-11'))} />, @@ -100,7 +99,7 @@ export const testTextFieldKeyboardRangeValidation: DescribeRangeValidationTestSu it('should apply disablePast', function test() { const onErrorMock = spy(); const now = adapterToUse.date(); - render(); + render(); let past: null | typeof now = null; if (withDate) { @@ -114,7 +113,7 @@ export const testTextFieldKeyboardRangeValidation: DescribeRangeValidationTestSu } act(() => { - setValue(adapterToUse.date(past)); + setValue(past); }); expect(onErrorMock.callCount).to.equal(1); @@ -122,7 +121,7 @@ export const testTextFieldKeyboardRangeValidation: DescribeRangeValidationTestSu testInvalidStatus([true, false], isSingleInput); act(() => { - setValue(adapterToUse.date(past), { setEndDate: true }); + setValue(past, { setEndDate: true }); }); expect(onErrorMock.callCount).to.equal(2); @@ -130,7 +129,7 @@ export const testTextFieldKeyboardRangeValidation: DescribeRangeValidationTestSu testInvalidStatus([true, true], isSingleInput); act(() => { - setValue(adapterToUse.date(now)); + setValue(now); }); expect(onErrorMock.callCount).to.equal(3); expect(onErrorMock.lastCall.args[0]).to.deep.equal([null, 'disablePast']); @@ -140,9 +139,7 @@ export const testTextFieldKeyboardRangeValidation: DescribeRangeValidationTestSu it('should apply disableFuture', function test() { const onErrorMock = spy(); const now = adapterToUse.date(); - render( - , - ); + render(); let future: null | typeof now = null; @@ -157,7 +154,7 @@ export const testTextFieldKeyboardRangeValidation: DescribeRangeValidationTestSu } act(() => { - setValue(adapterToUse.date(future), { setEndDate: true }); + setValue(future, { setEndDate: true }); }); expect(onErrorMock.callCount).to.equal(1); @@ -165,7 +162,7 @@ export const testTextFieldKeyboardRangeValidation: DescribeRangeValidationTestSu testInvalidStatus([false, true], isSingleInput); act(() => { - setValue(adapterToUse.date(future)); + setValue(future); }); expect(onErrorMock.callCount).to.equal(2); @@ -173,7 +170,7 @@ export const testTextFieldKeyboardRangeValidation: DescribeRangeValidationTestSu testInvalidStatus([true, true], isSingleInput); act(() => { - setValue(adapterToUse.date(now)); + setValue(now); }); expect(onErrorMock.callCount).to.equal(3); @@ -187,13 +184,7 @@ export const testTextFieldKeyboardRangeValidation: DescribeRangeValidationTestSu } const onErrorMock = spy(); - render( - , - ); + render(); act(() => { [adapterToUse.date('2018-03-09'), adapterToUse.date('2018-03-10')].forEach( @@ -230,13 +221,7 @@ export const testTextFieldKeyboardRangeValidation: DescribeRangeValidationTestSu } const onErrorMock = spy(); - render( - , - ); + render(); act(() => { [adapterToUse.date('2018-03-15'), adapterToUse.date('2018-03-17')].forEach( @@ -266,11 +251,7 @@ export const testTextFieldKeyboardRangeValidation: DescribeRangeValidationTestSu const onErrorMock = spy(); render( - , + , ); act(() => { @@ -310,11 +291,7 @@ export const testTextFieldKeyboardRangeValidation: DescribeRangeValidationTestSu const onErrorMock = spy(); render( - , + , ); act(() => { diff --git a/test/utils/pickers/describeRangeValidation/testTextFieldRangeValidation.tsx b/test/utils/pickers/describeRangeValidation/testTextFieldRangeValidation.tsx index 7d78327e23ab..3bc1182de0b7 100644 --- a/test/utils/pickers/describeRangeValidation/testTextFieldRangeValidation.tsx +++ b/test/utils/pickers/describeRangeValidation/testTextFieldRangeValidation.tsx @@ -30,7 +30,6 @@ export const testTextFieldRangeValidation: DescribeRangeValidationTestSuite = ( const onErrorMock = spy(); render( , @@ -66,7 +64,6 @@ export const testTextFieldRangeValidation: DescribeRangeValidationTestSuite = ( const onErrorMock = spy(); const { setProps } = render( adapterToUse.isAfter(date, adapterToUse.date('2018-03-10'))} @@ -113,7 +110,6 @@ export const testTextFieldRangeValidation: DescribeRangeValidationTestSuite = ( const onErrorMock = spy(); const { setProps } = render( @@ -160,7 +156,6 @@ export const testTextFieldRangeValidation: DescribeRangeValidationTestSuite = ( const onErrorMock = spy(); const { setProps } = render( @@ -206,7 +201,7 @@ export const testTextFieldRangeValidation: DescribeRangeValidationTestSuite = ( let now; function WithFakeTimer(props) { now = adapterToUse.date(); - return ; + return ; } const { setProps } = render(); @@ -244,7 +239,7 @@ export const testTextFieldRangeValidation: DescribeRangeValidationTestSuite = ( let now; function WithFakeTimer(props) { now = adapterToUse.date(); - return ; + return ; } const { setProps } = render(); @@ -286,7 +281,6 @@ export const testTextFieldRangeValidation: DescribeRangeValidationTestSuite = ( const onErrorMock = spy(); const { setProps } = render( @@ -55,7 +54,6 @@ export const testTextFieldValidation: DescribeValidationTestSuite = (ElementToTe const onErrorMock = spy(); const { setProps } = render( adapterToUse.getYear(date) === 2018} @@ -82,7 +80,6 @@ export const testTextFieldValidation: DescribeValidationTestSuite = (ElementToTe const onErrorMock = spy(); const { setProps } = render( adapterToUse.getMonth(date) === 2} value={adapterToUse.date('2018-03-12')} @@ -113,7 +110,6 @@ export const testTextFieldValidation: DescribeValidationTestSuite = (ElementToTe const onErrorMock = spy(); const { setProps } = render( { let comparingValue = adapterToUse.getHours(value); @@ -165,7 +161,7 @@ export const testTextFieldValidation: DescribeValidationTestSuite = (ElementToTe let now; function WithFakeTimer(props: any) { now = adapterToUse.date(); - return ; + return ; } const onErrorMock = spy(); @@ -198,7 +194,7 @@ export const testTextFieldValidation: DescribeValidationTestSuite = (ElementToTe let now; function WithFakeTimer(props: any) { now = adapterToUse.date(); - return ; + return ; } const onErrorMock = spy(); @@ -229,7 +225,6 @@ export const testTextFieldValidation: DescribeValidationTestSuite = (ElementToTe const onErrorMock = spy(); const { setProps } = render( ( const { defaultProps, render, clock, componentFamily } = options; function WrappedElementToTest( - props: BasePickerInputProps & - UsePickerValueNonStaticProps & { hook?: any }, + props: BasePickerInputProps & UsePickerValueNonStaticProps & { hook?: any }, ) { const { hook, ...other } = props; const hookResult = hook?.(props); diff --git a/test/utils/pickers/describeValue/testControlledUnControlled.tsx b/test/utils/pickers/describeValue/testControlledUnControlled.tsx index e5dca22796b5..272360c609c0 100644 --- a/test/utils/pickers/describeValue/testControlledUnControlled.tsx +++ b/test/utils/pickers/describeValue/testControlledUnControlled.tsx @@ -223,7 +223,6 @@ export const testControlledUnControlled: DescribeValueTestSuite = (
external label
= ( render( = ( render( = ( render( = ( render( = ( render( = ( render( describe('Picker open / close lifecycle', () => { it('should not open on mount if `props.open` is false', () => { - render(); + render(); expect(screen.queryByRole(viewWrapperRole)).to.equal(null); }); it('should open on mount if `prop.open` is true', () => { - render(); + render(); expect(screen.queryByRole(viewWrapperRole)).toBeVisible(); }); it('should not open when `prop.disabled` is true ', () => { const onOpen = spy(); - render(); + render(); openPicker(pickerParams); expect(onOpen.callCount).to.equal(0); @@ -41,7 +41,7 @@ export const testPickerOpenCloseLifeCycle: DescribeValueTestSuite it('should not open when `prop.readOnly` is true ', () => { const onOpen = spy(); - render(); + render(); openPicker(pickerParams); expect(onOpen.callCount).to.equal(0); @@ -298,7 +298,6 @@ export const testPickerOpenCloseLifeCycle: DescribeValueTestSuite render( render( const onAccept = spy(); const onClose = spy(); - render( - , - ); + render(); // Dismiss the picker fireEvent.keyDown(document.body, { key: 'Escape' }); diff --git a/test/utils/pickers/describeValue/testShortcuts.tsx b/test/utils/pickers/describeValue/testShortcuts.tsx index ae14f1ddc801..1e77be81334a 100644 --- a/test/utils/pickers/describeValue/testShortcuts.tsx +++ b/test/utils/pickers/describeValue/testShortcuts.tsx @@ -28,7 +28,6 @@ export const testShortcuts: DescribeValueTestSuite = (ElementToTe render( = (ElementToTe render( = (ElementToTe render( ({ selectedSection, ...props }) => { - // Test with v7 input + // Test with accessible DOM structure const v7Response = renderWithProps({ ...props, enableAccessibleFieldDOMStructure: true, @@ -244,7 +244,7 @@ export const buildFieldInteractions =

({ expectFieldValueV7(v7Response.getSectionsContainer(), expectedValue); v7Response.unmount(); - // Test with v6 input + // Test with non-accessible DOM structure const v6Response = renderWithProps({ ...props, enableAccessibleFieldDOMStructure: false, @@ -263,7 +263,7 @@ export const buildFieldInteractions =

({ ...props }) => { if (!skipV7) { - // Test with v7 input + // Test with accessible DOM structure const v7Response = renderWithProps({ ...props, enableAccessibleFieldDOMStructure: true, @@ -280,7 +280,7 @@ export const buildFieldInteractions =

({ v7Response.unmount(); } - // Test with v6 input + // Test with non-accessible DOM structure const v6Response = renderWithProps({ ...props, enableAccessibleFieldDOMStructure: false, diff --git a/test/utils/pickers/misc.ts b/test/utils/pickers/misc.ts index f5fcf9c40ee7..76e9ba1d5068 100644 --- a/test/utils/pickers/misc.ts +++ b/test/utils/pickers/misc.ts @@ -56,19 +56,13 @@ export const getExpectedOnChangeCount = ( return getChangeCountForComponentFamily(componentFamily); }; -export const getDateOffset = ( - adapter: MuiPickersAdapter, - date: TDate, -) => { +export const getDateOffset = (adapter: MuiPickersAdapter, date: PickerValidDate) => { const utcHour = adapter.getHours(adapter.setTimezone(adapter.startOfDay(date), 'UTC')); const cleanUtcHour = utcHour > 12 ? 24 - utcHour : -utcHour; return cleanUtcHour * 60; }; -export const formatFullTimeValue = ( - adapter: MuiPickersAdapter, - value: TDate, -) => { +export const formatFullTimeValue = (adapter: MuiPickersAdapter, value: PickerValidDate) => { const hasMeridiem = adapter.is12HourCycleInCurrentLocale(); return adapter.format(value, hasMeridiem ? 'fullTime12h' : 'fullTime24h'); }; diff --git a/test/utils/pickers/viewHandlers.ts b/test/utils/pickers/viewHandlers.ts index 84086aa10029..8c78a199e8cc 100644 --- a/test/utils/pickers/viewHandlers.ts +++ b/test/utils/pickers/viewHandlers.ts @@ -1,12 +1,10 @@ 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 { MuiPickersAdapter, PickerValidDate, TimeView } from '@mui/x-date-pickers/models'; import { formatMeridiem } from '@mui/x-date-pickers/internals'; -type TDate = any; - interface ViewHandler { - setViewValue: (utils: MuiPickersAdapter, viewValue: TDate, view?: TView) => void; + setViewValue: (utils: MuiPickersAdapter, viewValue: PickerValidDate, view?: TView) => void; } export const timeClockHandler: ViewHandler = { diff --git a/test/utils/tree-view/describeTreeView/describeTreeView.tsx b/test/utils/tree-view/describeTreeView/describeTreeView.tsx index 8063e32ad330..4d7d28078f17 100644 --- a/test/utils/tree-view/describeTreeView/describeTreeView.tsx +++ b/test/utils/tree-view/describeTreeView/describeTreeView.tsx @@ -5,7 +5,6 @@ import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; import { RichTreeViewPro } from '@mui/x-tree-view-pro/RichTreeViewPro'; import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView'; import { TreeItem, treeItemClasses } from '@mui/x-tree-view/TreeItem'; -import { TreeItem2 } from '@mui/x-tree-view/TreeItem2'; import { TreeViewBaseItem } from '@mui/x-tree-view/models'; import { TreeViewAnyPluginSignature, TreeViewPublicAPI } from '@mui/x-tree-view/internals/models'; import { MuiRenderResult } from '@mui/internal-test-utils/createRenderer'; @@ -114,10 +113,7 @@ const innerDescribeTreeView = return getUtils(result); }; - const createRendererForComponentWithItemsProp = ( - TreeViewComponent: typeof RichTreeView, - TreeItemComponent: typeof TreeItem | typeof TreeItem2, - ) => { + const createRendererForComponentWithItemsProp = (TreeViewComponent: typeof RichTreeView) => { const objectRenderer: DescribeTreeViewRenderer = ({ items: rawItems, withErrorBoundary, @@ -131,7 +127,7 @@ const innerDescribeTreeView = @@ -172,10 +168,7 @@ const innerDescribeTreeView = }; }; - const createRenderersForComponentWithJSXItems = ( - TreeViewComponent: typeof SimpleTreeView, - TreeItemComponent: typeof TreeItem | typeof TreeItem2, - ) => { + const createRenderersForComponentWithJSXItems = (TreeViewComponent: typeof SimpleTreeView) => { const objectRenderer: DescribeTreeViewRenderer = ({ items: rawItems, withErrorBoundary, @@ -184,7 +177,7 @@ const innerDescribeTreeView = ...other }) => { const items = rawItems as readonly DescribeTreeViewItem[]; - const Item = slots?.item ?? TreeItemComponent; + const Item = slots?.item ?? TreeItem; const apiRef = { current: undefined }; const renderItem = (item: DescribeTreeViewItem) => ( @@ -223,71 +216,32 @@ const innerDescribeTreeView = }; describe(message, () => { - describe('RichTreeView + TreeItem', () => { + describe('RichTreeView', () => { testRunner({ - ...createRendererForComponentWithItemsProp(RichTreeView, TreeItem), - setup: 'RichTreeView + TreeItem', + ...createRendererForComponentWithItemsProp(RichTreeView), treeViewComponentName: 'RichTreeView', - treeItemComponentName: 'TreeItem', TreeViewComponent: RichTreeView, TreeItemComponent: TreeItem, }); }); - describe('RichTreeView + TreeItem2', () => { + describe('RichTreeViewPro', () => { testRunner({ - ...createRendererForComponentWithItemsProp(RichTreeView, TreeItem2), - setup: 'RichTreeView + TreeItem2', - treeViewComponentName: 'RichTreeView', - treeItemComponentName: 'TreeItem2', - TreeViewComponent: RichTreeView, - TreeItemComponent: TreeItem2, - }); - }); - - describe('RichTreeViewPro + TreeItem', () => { - testRunner({ - ...createRendererForComponentWithItemsProp(RichTreeViewPro, TreeItem), - setup: 'RichTreeViewPro + TreeItem', + ...createRendererForComponentWithItemsProp(RichTreeViewPro), treeViewComponentName: 'RichTreeViewPro', - treeItemComponentName: 'TreeItem', TreeViewComponent: RichTreeViewPro, TreeItemComponent: TreeItem, }); }); - describe('RichTreeViewPro + TreeItem2', () => { - testRunner({ - ...createRendererForComponentWithItemsProp(RichTreeViewPro, TreeItem2), - setup: 'RichTreeViewPro + TreeItem2', - treeViewComponentName: 'RichTreeViewPro', - treeItemComponentName: 'TreeItem2', - TreeViewComponent: RichTreeViewPro, - TreeItemComponent: TreeItem2, - }); - }); - - describe('SimpleTreeView + TreeItem', () => { + describe('SimpleTreeView', () => { testRunner({ - ...createRenderersForComponentWithJSXItems(SimpleTreeView, TreeItem), - setup: 'SimpleTreeView + TreeItem', + ...createRenderersForComponentWithJSXItems(SimpleTreeView), treeViewComponentName: 'SimpleTreeView', - treeItemComponentName: 'TreeItem', TreeViewComponent: SimpleTreeView, TreeItemComponent: TreeItem, }); }); - - describe('SimpleTreeView + TreeItem2', () => { - testRunner({ - ...createRenderersForComponentWithJSXItems(SimpleTreeView, TreeItem2), - setup: 'SimpleTreeView + TreeItem2', - treeViewComponentName: 'SimpleTreeView', - treeItemComponentName: 'TreeItem2', - TreeViewComponent: SimpleTreeView, - TreeItemComponent: TreeItem2, - }); - }); }); }; @@ -303,13 +257,10 @@ type DescribeTreeView = { }; /** - * Describe tests for the Tree View that will be executed with the following setups: - * - RichTreeView + TreeItem - * - RichTreeView + TreeItem2 - * - RichTreeViewPro + TreeItem - * - RichTreeViewPro + TreeItem2 - * - SimpleTreeView + TreeItem - * - SimpleTreeView + TreeItem2 + * Describe tests for the Tree View that will be executed with the following Tree View components: + * - RichTreeView + * - RichTreeViewPro + * - SimpleTreeView * * Is used as follows: * diff --git a/test/utils/tree-view/describeTreeView/describeTreeView.types.ts b/test/utils/tree-view/describeTreeView/describeTreeView.types.ts index b470f885df76..20996106b13b 100644 --- a/test/utils/tree-view/describeTreeView/describeTreeView.types.ts +++ b/test/utils/tree-view/describeTreeView/describeTreeView.types.ts @@ -7,7 +7,6 @@ import { } from '@mui/x-tree-view/internals/models'; import { TreeViewItemId } from '@mui/x-tree-view/models'; import { TreeItemProps } from '@mui/x-tree-view/TreeItem'; -import { TreeItem2Props } from '@mui/x-tree-view/TreeItem2'; export type DescribeTreeViewTestRunner = ( params: DescribeTreeViewTestRunnerParams, @@ -129,10 +128,10 @@ export type DescribeTreeViewRenderer, 'slots' | 'slotProps'> & { slots?: MergeSignaturesProperty & { - item?: React.ElementType; + item?: React.ElementType; }; slotProps?: MergeSignaturesProperty & { - item?: Partial | Partial; + item?: Partial; }; experimentalFeatures?: TreeViewExperimentalFeatures; }, @@ -143,7 +142,6 @@ export type DescribeTreeViewJSXRenderer = ( ) => DescribeTreeViewRendererUtils; type TreeViewComponentName = 'RichTreeView' | 'RichTreeViewPro' | 'SimpleTreeView'; -type TreeItemComponentName = 'TreeItem' | 'TreeItem2'; interface DescribeTreeViewTestRunnerParams { /** @@ -178,9 +176,7 @@ interface DescribeTreeViewTestRunnerParams; TreeItemComponent: React.ElementType; } diff --git a/test/utils/tree-view/fakeContextValue.ts b/test/utils/tree-view/fakeContextValue.ts index eabcda86ac5d..649fb121c4b2 100644 --- a/test/utils/tree-view/fakeContextValue.ts +++ b/test/utils/tree-view/fakeContextValue.ts @@ -41,6 +41,7 @@ export const getFakeContextValue = ( multiSelect: false, checkboxSelection: features.checkboxSelection ?? false, disableSelection: false, + selectionPropagation: {}, }, treeId: 'mui-tree-view-1', rootRef: {