diff --git a/docs/data/date-pickers/custom-components/MonthButtonComponent.js b/docs/data/date-pickers/custom-components/MonthButtonComponent.js
index 8f0c336d4b22..2b94d95414f8 100644
--- a/docs/data/date-pickers/custom-components/MonthButtonComponent.js
+++ b/docs/data/date-pickers/custom-components/MonthButtonComponent.js
@@ -6,7 +6,6 @@ import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { DateCalendar } from '@mui/x-date-pickers/DateCalendar';
const CustomMonthButton = styled('button')({
- margin: '8px 0',
height: 36,
width: 72,
});
diff --git a/docs/data/date-pickers/custom-components/MonthButtonComponent.tsx b/docs/data/date-pickers/custom-components/MonthButtonComponent.tsx
index 8f0c336d4b22..2b94d95414f8 100644
--- a/docs/data/date-pickers/custom-components/MonthButtonComponent.tsx
+++ b/docs/data/date-pickers/custom-components/MonthButtonComponent.tsx
@@ -6,7 +6,6 @@ import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { DateCalendar } from '@mui/x-date-pickers/DateCalendar';
const CustomMonthButton = styled('button')({
- margin: '8px 0',
height: 36,
width: 72,
});
diff --git a/docs/data/date-pickers/custom-components/YearButtonComponent.js b/docs/data/date-pickers/custom-components/YearButtonComponent.js
index 6fe7a05365d8..eee824d0d872 100644
--- a/docs/data/date-pickers/custom-components/YearButtonComponent.js
+++ b/docs/data/date-pickers/custom-components/YearButtonComponent.js
@@ -6,7 +6,6 @@ import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { DateCalendar } from '@mui/x-date-pickers/DateCalendar';
const CustomYearButton = styled('button')({
- margin: '8px 0',
height: 36,
width: 72,
});
diff --git a/docs/data/date-pickers/custom-components/YearButtonComponent.tsx b/docs/data/date-pickers/custom-components/YearButtonComponent.tsx
index 6fe7a05365d8..eee824d0d872 100644
--- a/docs/data/date-pickers/custom-components/YearButtonComponent.tsx
+++ b/docs/data/date-pickers/custom-components/YearButtonComponent.tsx
@@ -6,7 +6,6 @@ import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { DateCalendar } from '@mui/x-date-pickers/DateCalendar';
const CustomYearButton = styled('button')({
- margin: '8px 0',
height: 36,
width: 72,
});
diff --git a/docs/data/date-pickers/date-picker/examplesConfig.styling.tsx b/docs/data/date-pickers/date-picker/examplesConfig.styling.tsx
index 07602069862c..0e1a6e4e8c4e 100644
--- a/docs/data/date-pickers/date-picker/examplesConfig.styling.tsx
+++ b/docs/data/date-pickers/date-picker/examplesConfig.styling.tsx
@@ -115,25 +115,7 @@ export const staticDatePickerExamples: PickersSubcomponentType = {
componentProps: { views: ['month'] },
},
},
- slots: ['root'],
- },
- PickersMonth: {
- examples: {
- customTheme: {
- type: 'success',
- componentProps: { views: ['month'] },
- },
- sxProp: {
- type: 'success',
- componentProps: { views: ['month'] },
- },
-
- styledComponents: {
- type: 'success',
- componentProps: { views: ['month'] },
- },
- },
- slots: ['root', 'monthButton'],
+ slots: ['root', 'button'],
},
};
@@ -240,7 +222,7 @@ export const datePickerExamples: PickersSubcomponentType = {
},
slots: ['root', 'today'],
},
- PickersMonth: {
+ MonthCalendar: {
examples: {
customTheme: {
type: 'success',
@@ -263,7 +245,7 @@ export const datePickerExamples: PickersSubcomponentType = {
componentProps: { views: ['month'] },
},
},
- slots: ['root', 'monthButton'],
+ slots: ['button'],
},
PickersTextField: {
examples: {
diff --git a/docs/data/migration/migration-pickers-v7/migration-pickers-v7.md b/docs/data/migration/migration-pickers-v7/migration-pickers-v7.md
index e442c6924293..6bc805040ba9 100644
--- a/docs/data/migration/migration-pickers-v7/migration-pickers-v7.md
+++ b/docs/data/migration/migration-pickers-v7/migration-pickers-v7.md
@@ -68,7 +68,9 @@ After running the codemods, make sure to test your application and that you don'
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
+## Components breaking changes
+
+### New DOM structure for the field
Before version `v7.x`, the fields' DOM structure consisted of an ` `, which held the whole value for the component.
Unfortunately it presented accessibility limitations, which are impossible to resolve.
@@ -78,7 +80,7 @@ This approach is recommended in [W3C ARIA](https://www.w3.org/WAI/ARIA/apg/patte
Starting with version `v8.x`, the new DOM structure is the default for all fields.
-### Fallback to the non-accessible DOM structure
+#### Fallback to the non-accessible DOM structure
```tsx
@@ -86,7 +88,7 @@ Starting with version `v8.x`, the new DOM structure is the default for all field
```
-### Migrate `slotProps.field`
+#### Migrate `slotProps.field`
When using `slotProps.field` to pass props to your field component,
the field consumes some props (for example `shouldRespectLeadingZeros`) and forwards the rest to the `TextField`.
@@ -120,7 +122,7 @@ the field consumes some props (for example `shouldRespectLeadingZeros`) and forw
/>
```
-### Migrate `slotProps.textField`
+#### 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.
@@ -142,14 +144,14 @@ If you are passing `inputProps` to `slotProps.textField`,
these props will now be passed to the hidden ` ` element.
:::
-### Migrate `slots.field`
+#### 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) section to have a concrete example.
-### Migrate `slots.textField`
+#### 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.
@@ -162,7 +164,7 @@ please consider having a look at the [Using a custom input](/x/react-date-picker
This approach can be more appropriate for deeper changes.
:::
-### Migrate the theme
+#### Migrate the theme
If you are using the theme to customize `MuiTextField`,
you need to pass the same config to `MuiPickersTextField`:
@@ -260,6 +262,88 @@ const theme = createTheme({
});
```
+### Month Calendar
+
+To simplify the theme and class structure, the ` ` component has been moved inside the Month Calendar component.
+This change causes a few breaking changes:
+
+- The classes from `pickersMonthClasses` have been moved inside `monthCalendarClasses`:
+
+ ```diff
+ -import { pickersMonthClasses } from '@mui/x-date-pickers/MonthCalendar';
+ +import { monthCalendarClasses } from '@mui/x-date-pickers/MonthCalendar';
+
+ -const buttonClassName = pickersMonthClasses.monthButton;
+ +const buttonClassName = monthCalendarClasses.button;
+
+ -const selectedButtonClassName = pickersMonthClasses.selected;
+ +const selectedButtonClassName = monthCalendarClasses.selected;
+
+ -const disabledButtonClassName = pickersMonthClasses.disabled;
+ +const disabledButtonClassName = monthCalendarClasses.disabled;
+ ```
+
+- The `monthButton` slot of the `PickersMonth` style overrides has been replaced by the `button` slot of the `MonthCalendar` theme entry:
+
+ ```diff
+ const theme = createTheme({
+ components: {
+ - PickersMonth: {
+ + MonthCalendar: {
+ styleOverrides: {
+ - monthButton: {
+ + button: {
+ color: 'red',
+ },
+ },
+ },
+ },
+ });
+ ```
+
+- The button to render a single month is no longer wrapped in a `
`, the spacing are instead defined inside the `root` slot of the Month Calendar.
+
+### Year Calendar
+
+To simplify the theme and class structure, the ` ` component has been moved inside the Year Calendar component.
+This change causes a few breaking changes:
+
+- The classes from `pickersYearClasses` have been moved inside `yearCalendarClasses`:
+
+ ```diff
+ -import { pickersYearClasses } from '@mui/x-date-pickers/YearCalendar';
+ +import { yearCalendarClasses } from '@mui/x-date-pickers/YearCalendar';
+
+ -const buttonClassName = pickersYearClasses.monthButton;
+ +const buttonClassName = yearCalendarClasses.button;
+
+ -const selectedButtonClassName = pickersYearClasses.selected;
+ +const selectedButtonClassName = yearCalendarClasses.selected;
+
+ -const disabledButtonClassName = pickersYearClasses.disabled;
+ +const disabledButtonClassName = yearCalendarClasses.disabled;
+ ```
+
+- The `yearButton` slot of the `PickersYear` style overrides has been replaced by the `button` slot of the `YearCalendar` theme entry:
+
+ ```diff
+ const theme = createTheme({
+ components: {
+ - PickersYear: {
+ + YearCalendar: {
+ styleOverrides: {
+ - yearButton: {
+ + button: {
+ color: 'red',
+ },
+ },
+ },
+ },
+ });
+ ```
+
+- The button to render a single year is no longer wrapped in a `
`, the spacing are instead defined inside the `root` slot of the Year Calendar.
+
## Slots breaking changes
### Slot: `layout`
diff --git a/docs/pages/x/api/date-pickers/month-calendar.json b/docs/pages/x/api/date-pickers/month-calendar.json
index 1f23727e3137..fe50f964d8e8 100644
--- a/docs/pages/x/api/date-pickers/month-calendar.json
+++ b/docs/pages/x/api/date-pickers/month-calendar.json
@@ -70,11 +70,29 @@
}
],
"classes": [
+ {
+ "key": "button",
+ "className": "MuiMonthCalendar-button",
+ "description": "Styles applied to the button element that represents a single month",
+ "isGlobal": false
+ },
+ {
+ "key": "disabled",
+ "className": "Mui-disabled",
+ "description": "Styles applied to a disabled button element.",
+ "isGlobal": true
+ },
{
"key": "root",
"className": "MuiMonthCalendar-root",
"description": "Styles applied to the root element.",
"isGlobal": false
+ },
+ {
+ "key": "selected",
+ "className": "Mui-selected",
+ "description": "Styles applied to a selected button element.",
+ "isGlobal": true
}
],
"spread": true,
diff --git a/docs/pages/x/api/date-pickers/year-calendar.json b/docs/pages/x/api/date-pickers/year-calendar.json
index e40978126d0b..cdb5e131d367 100644
--- a/docs/pages/x/api/date-pickers/year-calendar.json
+++ b/docs/pages/x/api/date-pickers/year-calendar.json
@@ -74,11 +74,29 @@
}
],
"classes": [
+ {
+ "key": "button",
+ "className": "MuiYearCalendar-button",
+ "description": "Styles applied to the button element that represents a single year",
+ "isGlobal": false
+ },
+ {
+ "key": "disabled",
+ "className": "Mui-disabled",
+ "description": "Styles applied to a disabled button element.",
+ "isGlobal": true
+ },
{
"key": "root",
"className": "MuiYearCalendar-root",
"description": "Styles applied to the root element.",
"isGlobal": false
+ },
+ {
+ "key": "selected",
+ "className": "Mui-selected",
+ "description": "Styles applied to a selected button element.",
+ "isGlobal": true
}
],
"spread": true,
diff --git a/docs/src/modules/components/overview/MainDemo.tsx b/docs/src/modules/components/overview/MainDemo.tsx
index 52e697ed6fef..cc3f2ce6125b 100644
--- a/docs/src/modules/components/overview/MainDemo.tsx
+++ b/docs/src/modules/components/overview/MainDemo.tsx
@@ -26,9 +26,9 @@ const components: Components = {
}),
},
},
- MuiPickersMonth: {
+ MuiMonthCalendar: {
styleOverrides: {
- monthButton: ({ theme }) => ({
+ button: ({ theme }) => ({
fontWeight: 400,
fontSize: '0.875rem',
borderRadius: theme.shape.borderRadius,
@@ -37,9 +37,9 @@ const components: Components = {
}),
},
},
- MuiPickersYear: {
+ MuiYearCalendar: {
styleOverrides: {
- yearButton: ({ theme }) => ({
+ button: ({ theme }) => ({
fontWeight: 400,
fontSize: '0.875rem',
borderRadius: theme.shape.borderRadius,
diff --git a/docs/src/modules/components/overview/themes/customTheme.ts b/docs/src/modules/components/overview/themes/customTheme.ts
index 64e2edc7dca3..61440b5ce4aa 100644
--- a/docs/src/modules/components/overview/themes/customTheme.ts
+++ b/docs/src/modules/components/overview/themes/customTheme.ts
@@ -371,16 +371,16 @@ export const getCustomTheme = (mode: PaletteMode, config: Config): ThemeOptions
}),
},
},
- MuiPickersMonth: {
+ MuiMonthCalendar: {
styleOverrides: {
- monthButton: ({ theme }) => ({
+ button: ({ theme }) => ({
borderRadius: theme.shape.borderRadius,
}),
},
},
- MuiPickersYear: {
+ MuiYearCalendar: {
styleOverrides: {
- yearButton: ({ theme }) => ({
+ button: ({ theme }) => ({
borderRadius: theme.shape.borderRadius,
}),
},
diff --git a/docs/src/modules/components/overview/themes/md3.ts b/docs/src/modules/components/overview/themes/md3.ts
index 8a13b16b2799..c7506eaf5ed7 100644
--- a/docs/src/modules/components/overview/themes/md3.ts
+++ b/docs/src/modules/components/overview/themes/md3.ts
@@ -245,7 +245,6 @@ export const getMD3Theme = (mode: PaletteMode, config: Config): ThemeOptions =>
height: 'fit-content',
maxHeight: 'initial',
},
-
viewTransitionContainer: ({ theme }) => ({
height: theme.mixins.density.height * 7 + theme.mixins.density.spacing * 6,
}),
@@ -258,6 +257,11 @@ export const getMD3Theme = (mode: PaletteMode, config: Config): ThemeOptions =>
borderBottom: `1px solid ${theme.palette.divider}`,
alignContent: 'flex-start',
width: theme.mixins.density.width * 7 + theme.mixins.density.spacing * 6 + 40,
+ columnGap: '12px',
+ }),
+ button: ({ theme }) => ({
+ borderRadius: theme.shape.borderRadius,
+ height: theme.mixins.density.height,
}),
},
},
@@ -298,15 +302,6 @@ export const getMD3Theme = (mode: PaletteMode, config: Config): ThemeOptions =>
}),
},
},
- MuiPickersYear: {
- styleOverrides: {
- yearButton: ({ theme, ownerState }) => ({
- borderRadius: theme.shape.borderRadius,
- height: theme.mixins.density.height,
- ...(!ownerState.selected && { color: theme.palette.text.secondary }),
- }),
- },
- },
MuiCard: {
styleOverrides: {
root: {
diff --git a/docs/translations/api-docs/date-pickers/month-calendar/month-calendar.json b/docs/translations/api-docs/date-pickers/month-calendar/month-calendar.json
index 547d39e20c12..c9ada403d18b 100644
--- a/docs/translations/api-docs/date-pickers/month-calendar/month-calendar.json
+++ b/docs/translations/api-docs/date-pickers/month-calendar/month-calendar.json
@@ -48,7 +48,20 @@
},
"value": { "description": "The selected value. Used when the component is controlled." }
},
- "classDescriptions": { "root": { "description": "Styles applied to the root element." } },
+ "classDescriptions": {
+ "button": {
+ "description": "Styles applied to the button element that represents a single month"
+ },
+ "disabled": {
+ "description": "Styles applied to {{nodeName}}.",
+ "nodeName": "a disabled button element"
+ },
+ "root": { "description": "Styles applied to the root element." },
+ "selected": {
+ "description": "Styles applied to {{nodeName}}.",
+ "nodeName": "a selected button element"
+ }
+ },
"slotDescriptions": {
"monthButton": "Button displayed to render a single month in the month
view."
}
diff --git a/docs/translations/api-docs/date-pickers/year-calendar/year-calendar.json b/docs/translations/api-docs/date-pickers/year-calendar/year-calendar.json
index 3741404f4a84..59ad06a05723 100644
--- a/docs/translations/api-docs/date-pickers/year-calendar/year-calendar.json
+++ b/docs/translations/api-docs/date-pickers/year-calendar/year-calendar.json
@@ -51,7 +51,20 @@
},
"yearsPerRow": { "description": "Years rendered per row." }
},
- "classDescriptions": { "root": { "description": "Styles applied to the root element." } },
+ "classDescriptions": {
+ "button": {
+ "description": "Styles applied to the button element that represents a single year"
+ },
+ "disabled": {
+ "description": "Styles applied to {{nodeName}}.",
+ "nodeName": "a disabled button element"
+ },
+ "root": { "description": "Styles applied to the root element." },
+ "selected": {
+ "description": "Styles applied to {{nodeName}}.",
+ "nodeName": "a selected button element"
+ }
+ },
"slotDescriptions": {
"yearButton": "Button displayed to render a single year in the year
view."
}
diff --git a/packages/x-date-pickers/src/DateCalendar/tests/DateCalendar.test.tsx b/packages/x-date-pickers/src/DateCalendar/tests/DateCalendar.test.tsx
index aafc00857bd5..a6456ef66a57 100644
--- a/packages/x-date-pickers/src/DateCalendar/tests/DateCalendar.test.tsx
+++ b/packages/x-date-pickers/src/DateCalendar/tests/DateCalendar.test.tsx
@@ -439,7 +439,7 @@ describe(' ', () => {
it('renders year selection standalone', () => {
render( );
- expect(screen.getAllByTestId('year')).to.have.length(200);
+ expect(screen.getAllByRole('radio')).to.have.length(200);
});
it('should select the closest enabled date in the month if the current date is disabled', () => {
diff --git a/packages/x-date-pickers/src/MonthCalendar/MonthCalendar.tsx b/packages/x-date-pickers/src/MonthCalendar/MonthCalendar.tsx
index 0667892ee47c..d57564fdd172 100644
--- a/packages/x-date-pickers/src/MonthCalendar/MonthCalendar.tsx
+++ b/packages/x-date-pickers/src/MonthCalendar/MonthCalendar.tsx
@@ -3,6 +3,7 @@ import * as React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import { useRtl } from '@mui/system/RtlProvider';
+import { shouldForwardProp } from '@mui/system/createStyled';
import { styled, useThemeProps } from '@mui/material/styles';
import {
unstable_useControlled as useControlled,
@@ -10,7 +11,7 @@ import {
unstable_useEventCallback as useEventCallback,
} from '@mui/utils';
import { DefaultizedProps } from '@mui/x-internals/types';
-import { PickersMonth } from './PickersMonth';
+import { MonthCalendarButton } from './MonthCalendarButton';
import { useUtils, useNow, useDefaultDates } from '../internals/hooks/useUtils';
import { getMonthCalendarUtilityClass, MonthCalendarClasses } from './monthCalendarClasses';
import { applyDefaultDate, getMonthsInYear } from '../internals/utils/date-utils';
@@ -33,7 +34,10 @@ const useUtilityClasses = (classes: Partial | undefined) =
export function useMonthCalendarDefaultizedProps(
props: MonthCalendarProps,
name: string,
-): DefaultizedProps {
+): DefaultizedProps<
+ MonthCalendarProps,
+ 'minDate' | 'maxDate' | 'disableFuture' | 'disablePast' | 'monthsPerRow'
+> {
const utils = useUtils();
const defaultDates = useDefaultDates();
const themeProps = useThemeProps({
@@ -45,6 +49,7 @@ export function useMonthCalendarDefaultizedProps(
disableFuture: false,
disablePast: false,
...themeProps,
+ monthsPerRow: themeProps.monthsPerRow ?? 3,
minDate: applyDefaultDate(utils, themeProps.minDate, defaultDates.minDate),
maxDate: applyDefaultDate(utils, themeProps.maxDate, defaultDates.maxDate),
};
@@ -54,14 +59,26 @@ const MonthCalendarRoot = styled('div', {
name: 'MuiMonthCalendar',
slot: 'Root',
overridesResolver: (props, styles) => styles.root,
-})<{ ownerState: PickerOwnerState }>({
+ shouldForwardProp: (prop) => shouldForwardProp(prop) && prop !== 'monthsPerRow',
+})<{ ownerState: PickerOwnerState; monthsPerRow: 3 | 4 }>({
display: 'flex',
flexWrap: 'wrap',
- alignContent: 'stretch',
- padding: '0 4px',
+ justifyContent: 'space-evenly',
+ rowGap: 16,
+ padding: '8px 0',
width: DIALOG_WIDTH,
// avoid padding increasing width over defined
boxSizing: 'border-box',
+ variants: [
+ {
+ props: { monthsPerRow: 3 },
+ style: { columnGap: 24 },
+ },
+ {
+ props: { monthsPerRow: 4 },
+ style: { columnGap: 0 },
+ },
+ ],
});
type MonthCalendarComponent = ((
@@ -83,6 +100,7 @@ export const MonthCalendar = React.forwardRef(function MonthCalendar(
) {
const props = useMonthCalendarDefaultizedProps(inProps, 'MuiMonthCalendar');
const {
+ autoFocus,
className,
classes: classesProp,
value: valueProp,
@@ -97,11 +115,10 @@ export const MonthCalendar = React.forwardRef(function MonthCalendar(
shouldDisableMonth,
readOnly,
disableHighlightToday,
- autoFocus = false,
onMonthFocus,
hasFocus,
onFocusedViewChange,
- monthsPerRow = 3,
+ monthsPerRow,
timezone: timezoneProp,
gridLabelId,
slots,
@@ -268,6 +285,7 @@ export const MonthCalendar = React.forwardRef(function MonthCalendar(
ownerState={ownerState}
role="radiogroup"
aria-labelledby={gridLabelId}
+ monthsPerRow={monthsPerRow}
{...other}
>
{getMonthsInYear(utils, value ?? referenceDate).map((month) => {
@@ -278,7 +296,7 @@ export const MonthCalendar = React.forwardRef(function MonthCalendar(
const isDisabled = disabled || isMonthDisabled(month);
return (
-
{monthText}
-
+
);
})}
diff --git a/packages/x-date-pickers/src/MonthCalendar/MonthCalendar.types.ts b/packages/x-date-pickers/src/MonthCalendar/MonthCalendar.types.ts
index 14506792ce94..05b1b4a0fd47 100644
--- a/packages/x-date-pickers/src/MonthCalendar/MonthCalendar.types.ts
+++ b/packages/x-date-pickers/src/MonthCalendar/MonthCalendar.types.ts
@@ -7,7 +7,7 @@ import { BaseDateValidationProps, MonthValidationProps } from '../internals/mode
import { PickerOwnerState, PickerValidDate, TimezoneProps } from '../models';
import { FormProps } from '../internals/models/formProps';
-export interface PickerMonthOwnerState extends PickerOwnerState {
+export interface MonthButtonOwnerState extends PickerOwnerState {
isMonthSelected: boolean;
isMonthDisabled: boolean;
}
@@ -24,7 +24,7 @@ export interface MonthCalendarSlotProps {
monthButton?: SlotComponentPropsFromProps<
React.HTMLAttributes & { sx: SxProps },
{},
- PickerMonthOwnerState
+ MonthButtonOwnerState
>;
}
diff --git a/packages/x-date-pickers/src/MonthCalendar/PickersMonth.tsx b/packages/x-date-pickers/src/MonthCalendar/MonthCalendarButton.tsx
similarity index 56%
rename from packages/x-date-pickers/src/MonthCalendar/PickersMonth.tsx
rename to packages/x-date-pickers/src/MonthCalendar/MonthCalendarButton.tsx
index 992053d82bc9..4702657cc036 100644
--- a/packages/x-date-pickers/src/MonthCalendar/PickersMonth.tsx
+++ b/packages/x-date-pickers/src/MonthCalendar/MonthCalendarButton.tsx
@@ -1,91 +1,69 @@
import * as React from 'react';
-import clsx from 'clsx';
-import { styled, alpha, useThemeProps } from '@mui/material/styles';
+import { styled, alpha } from '@mui/material/styles';
import useSlotProps from '@mui/utils/useSlotProps';
import composeClasses from '@mui/utils/composeClasses';
import useEnhancedEffect from '@mui/utils/useEnhancedEffect';
-import {
- getPickersMonthUtilityClass,
- pickersMonthClasses,
- PickersMonthClasses,
-} from './pickersMonthClasses';
import {
MonthCalendarSlotProps,
MonthCalendarSlots,
- PickerMonthOwnerState,
+ MonthButtonOwnerState,
} from './MonthCalendar.types';
import { usePickerPrivateContext } from '../internals/hooks/usePickerPrivateContext';
+import {
+ getMonthCalendarUtilityClass,
+ monthCalendarClasses,
+ MonthCalendarClasses,
+} from './monthCalendarClasses';
-export interface ExportedPickersMonthProps {
- classes?: Partial;
-}
-
-export interface PickersMonthProps extends ExportedPickersMonthProps {
- 'aria-current'?: React.AriaAttributes['aria-current'];
- 'aria-label'?: React.AriaAttributes['aria-label'];
+export interface MonthCalendarButtonProps {
+ value: number;
+ tabIndex: number;
+ selected: boolean;
+ disabled: boolean;
autoFocus: boolean;
+ classes: Partial | undefined;
+ slots: MonthCalendarSlots | undefined;
+ slotProps: MonthCalendarSlotProps | undefined;
+ 'aria-current': React.AriaAttributes['aria-current'];
+ 'aria-label': React.AriaAttributes['aria-label'];
children: React.ReactNode;
- className?: string;
- disabled?: boolean;
onClick: (event: React.MouseEvent, month: number) => void;
onKeyDown: (event: React.KeyboardEvent, month: number) => void;
onFocus: (event: React.FocusEvent, month: number) => void;
onBlur: (event: React.FocusEvent, month: number) => void;
- selected?: boolean;
- value: number;
- tabIndex: number;
- monthsPerRow: 3 | 4;
- slots?: MonthCalendarSlots;
- slotProps?: MonthCalendarSlotProps;
}
const useUtilityClasses = (
- classes: Partial | undefined,
- ownerState: PickerMonthOwnerState,
+ classes: Partial | undefined,
+ ownerState: MonthButtonOwnerState,
) => {
const slots = {
- root: ['root'],
- monthButton: [
- 'monthButton',
+ button: [
+ 'button',
ownerState.isMonthDisabled && 'disabled',
ownerState.isMonthSelected && 'selected',
],
};
- return composeClasses(slots, getPickersMonthUtilityClass, classes);
+ return composeClasses(slots, getMonthCalendarUtilityClass, classes);
};
-const PickersMonthRoot = styled('div', {
- name: 'MuiPickersMonth',
- slot: 'Root',
- overridesResolver: (_, styles) => [styles.root],
-})<{
- ownerState: PickerMonthOwnerState;
-}>({
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'center',
- flexBasis: '33.3%',
- variants: [{ props: { monthsPerRow: 4 }, style: { flexBasis: '25%' } }],
-});
-
-const MonthCalendarButton = styled('button', {
- name: 'MuiPickersMonth',
- slot: 'MonthButton',
+const DefaultMonthButton = styled('button', {
+ name: 'MuiMonthCalendar',
+ slot: 'Button',
overridesResolver: (_, styles) => [
- styles.monthButton,
- { [`&.${pickersMonthClasses.disabled}`]: styles.disabled },
- { [`&.${pickersMonthClasses.selected}`]: styles.selected },
+ styles.button,
+ { [`&.${monthCalendarClasses.disabled}`]: styles.disabled },
+ { [`&.${monthCalendarClasses.selected}`]: styles.selected },
],
})<{
- ownerState?: PickerMonthOwnerState;
+ ownerState?: MonthButtonOwnerState;
}>(({ theme }) => ({
color: 'unset',
backgroundColor: 'transparent',
border: 0,
outline: 0,
...theme.typography.subtitle1,
- margin: '8px 0',
height: 36,
width: 72,
borderRadius: 18,
@@ -104,10 +82,10 @@ const MonthCalendarButton = styled('button', {
cursor: 'auto',
pointerEvents: 'none',
},
- [`&.${pickersMonthClasses.disabled}`]: {
+ [`&.${monthCalendarClasses.disabled}`]: {
color: (theme.vars || theme).palette.text.secondary,
},
- [`&.${pickersMonthClasses.selected}`]: {
+ [`&.${monthCalendarClasses.selected}`]: {
color: (theme.vars || theme).palette.primary.contrastText,
backgroundColor: (theme.vars || theme).palette.primary.main,
'&:focus, &:hover': {
@@ -119,28 +97,19 @@ const MonthCalendarButton = styled('button', {
/**
* @ignore - do not document.
*/
-export const PickersMonth = React.memo(function PickersMonth(inProps: PickersMonthProps) {
- const props = useThemeProps({
- props: inProps,
- name: 'MuiPickersMonth',
- });
+export const MonthCalendarButton = React.memo(function MonthCalendarButton(
+ props: MonthCalendarButtonProps,
+) {
const {
autoFocus,
- className,
classes: classesProp,
- children,
- disabled = false,
- selected = false,
+ disabled,
+ selected,
value,
- tabIndex,
onClick,
onKeyDown,
onFocus,
onBlur,
- 'aria-current': ariaCurrent,
- 'aria-label': ariaLabel,
- // We don't want to forward this prop to the root element
- monthsPerRow,
slots,
slotProps,
...other
@@ -148,7 +117,7 @@ export const PickersMonth = React.memo(function PickersMonth(inProps: PickersMon
const ref = React.useRef(null);
const { ownerState: pickerOwnerState } = usePickerPrivateContext();
- const ownerState: PickerMonthOwnerState = {
+ const ownerState: MonthButtonOwnerState = {
...pickerOwnerState,
isMonthDisabled: disabled,
isMonthSelected: selected,
@@ -164,37 +133,25 @@ export const PickersMonth = React.memo(function PickersMonth(inProps: PickersMon
}
}, [autoFocus]);
- const MonthButton = slots?.monthButton ?? MonthCalendarButton;
+ const MonthButton = slots?.monthButton ?? DefaultMonthButton;
const monthButtonProps = useSlotProps({
elementType: MonthButton,
externalSlotProps: slotProps?.monthButton,
+ externalForwardedProps: other,
additionalProps: {
- children,
disabled,
- tabIndex,
ref,
type: 'button' as const,
role: 'radio',
- 'aria-current': ariaCurrent,
'aria-checked': selected,
- 'aria-label': ariaLabel,
onClick: (event: React.MouseEvent) => onClick(event, value),
onKeyDown: (event: React.KeyboardEvent) => onKeyDown(event, value),
onFocus: (event: React.FocusEvent) => onFocus(event, value),
onBlur: (event: React.FocusEvent) => onBlur(event, value),
},
ownerState,
- className: classes.monthButton,
+ className: classes.button,
});
- return (
-
-
-
- );
+ return ;
});
diff --git a/packages/x-date-pickers/src/MonthCalendar/index.ts b/packages/x-date-pickers/src/MonthCalendar/index.ts
index c7f6f59c9b89..fa29a7bb1714 100644
--- a/packages/x-date-pickers/src/MonthCalendar/index.ts
+++ b/packages/x-date-pickers/src/MonthCalendar/index.ts
@@ -7,7 +7,3 @@ export type {
export { monthCalendarClasses, getMonthCalendarUtilityClass } from './monthCalendarClasses';
export type { MonthCalendarClasses, MonthCalendarClassKey } from './monthCalendarClasses';
-
-export { pickersMonthClasses } from './pickersMonthClasses';
-export type { PickersMonthClassKey, PickersMonthClasses } from './pickersMonthClasses';
-export type { ExportedPickersMonthProps } from './PickersMonth';
diff --git a/packages/x-date-pickers/src/MonthCalendar/monthCalendarClasses.ts b/packages/x-date-pickers/src/MonthCalendar/monthCalendarClasses.ts
index 7f2cb1a3cf4d..a2e15ce85a08 100644
--- a/packages/x-date-pickers/src/MonthCalendar/monthCalendarClasses.ts
+++ b/packages/x-date-pickers/src/MonthCalendar/monthCalendarClasses.ts
@@ -10,11 +10,17 @@ export function getMonthCalendarUtilityClass(slot: string) {
export interface MonthCalendarClasses {
/** Styles applied to the root element. */
root: string;
+ /** Styles applied to the button element that represents a single month */
+ button: string;
+ /** Styles applied to a disabled button element. */
+ disabled: string;
+ /** Styles applied to a selected button element. */
+ selected: string;
}
export type MonthCalendarClassKey = keyof MonthCalendarClasses;
export const monthCalendarClasses = generateUtilityClasses(
'MuiMonthCalendar',
- ['root'],
+ ['root', 'button', 'disabled', 'selected'],
);
diff --git a/packages/x-date-pickers/src/MonthCalendar/pickersMonthClasses.ts b/packages/x-date-pickers/src/MonthCalendar/pickersMonthClasses.ts
deleted file mode 100644
index 4070fc9ab04a..000000000000
--- a/packages/x-date-pickers/src/MonthCalendar/pickersMonthClasses.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import {
- unstable_generateUtilityClass as generateUtilityClass,
- unstable_generateUtilityClasses as generateUtilityClasses,
-} from '@mui/utils';
-
-export interface PickersMonthClasses {
- /** Styles applied to the root element. */
- root: string;
- /** Styles applied to the month button element. */
- monthButton: string;
- /** Styles applied to a disabled month button element. */
- disabled: string;
- /** Styles applied to a selected month button element. */
- selected: string;
-}
-
-export type PickersMonthClassKey = keyof PickersMonthClasses;
-
-export function getPickersMonthUtilityClass(slot: string) {
- return generateUtilityClass('MuiPickersMonth', slot);
-}
-
-export const pickersMonthClasses = generateUtilityClasses('MuiPickersMonth', [
- 'root',
- 'monthButton',
- 'disabled',
- 'selected',
-]);
diff --git a/packages/x-date-pickers/src/MonthCalendar/tests/MonthCalendar.test.tsx b/packages/x-date-pickers/src/MonthCalendar/tests/MonthCalendar.test.tsx
index 72037d514c1c..572a9703454d 100644
--- a/packages/x-date-pickers/src/MonthCalendar/tests/MonthCalendar.test.tsx
+++ b/packages/x-date-pickers/src/MonthCalendar/tests/MonthCalendar.test.tsx
@@ -52,7 +52,7 @@ describe(' ', () => {
expect(onChangeMock.callCount).to.equal(0);
});
- it('clicking on a PickersMonth button should not trigger the form submit', () => {
+ it('clicking on a month button should not trigger the form submit', () => {
const onSubmitMock = spy();
render(