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(
diff --git a/packages/x-date-pickers/src/YearCalendar/YearCalendar.tsx b/packages/x-date-pickers/src/YearCalendar/YearCalendar.tsx index 423c78caf2df..dcaf7d8ce436 100644 --- a/packages/x-date-pickers/src/YearCalendar/YearCalendar.tsx +++ b/packages/x-date-pickers/src/YearCalendar/YearCalendar.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_useForkRef as useForkRef, @@ -11,7 +12,7 @@ import { unstable_useEventCallback as useEventCallback, } from '@mui/utils'; import { DefaultizedProps } from '@mui/x-internals/types'; -import { PickersYear } from './PickersYear'; +import { YearCalendarButton } from './YearCalendarButton'; import { useUtils, useNow, useDefaultDates } from '../internals/hooks/useUtils'; import { getYearCalendarUtilityClass, YearCalendarClasses } from './yearCalendarClasses'; import { applyDefaultDate } from '../internals/utils/date-utils'; @@ -36,7 +37,7 @@ function useYearCalendarDefaultizedProps( name: string, ): DefaultizedProps< YearCalendarProps, - 'minDate' | 'maxDate' | 'disableFuture' | 'disablePast' | 'yearsPerRow' + 'minDate' | 'maxDate' | 'disableFuture' | 'disablePast' | 'yearsPerRow' | 'yearsOrder' > { const utils = useUtils(); const defaultDates = useDefaultDates(); @@ -50,6 +51,7 @@ function useYearCalendarDefaultizedProps( disableFuture: false, ...themeProps, yearsPerRow: themeProps.yearsPerRow ?? 3, + yearsOrder: themeProps.yearsOrder ?? 'asc', minDate: applyDefaultDate(utils, themeProps.minDate, defaultDates.minDate), maxDate: applyDefaultDate(utils, themeProps.maxDate, defaultDates.maxDate), }; @@ -58,19 +60,38 @@ function useYearCalendarDefaultizedProps( const YearCalendarRoot = styled('div', { name: 'MuiYearCalendar', slot: 'Root', - overridesResolver: (props, styles) => styles.root, -})<{ ownerState: PickerOwnerState }>({ + shouldForwardProp: (prop) => shouldForwardProp(prop) && prop !== 'yearsPerRow', +})<{ ownerState: PickerOwnerState; yearsPerRow: 3 | 4 }>({ display: 'flex', - flexDirection: 'row', flexWrap: 'wrap', + justifyContent: 'space-evenly', + rowGap: 12, + padding: '6px 0', overflowY: 'auto', height: '100%', - padding: '0 4px', width: DIALOG_WIDTH, maxHeight: MAX_CALENDAR_HEIGHT, // avoid padding increasing width over defined boxSizing: 'border-box', position: 'relative', + variants: [ + { + props: { yearsPerRow: 3 }, + style: { columnGap: 24 }, + }, + { + props: { yearsPerRow: 4 }, + style: { columnGap: 0, padding: '0 2px' }, + }, + ], +}); + +const YearCalendarButtonFiller = styled('div', { + name: 'MuiYearCalendar', + slot: 'ButtonFiller', +})({ + height: 36, + width: 72, }); type YearCalendarComponent = ((props: YearCalendarProps) => React.JSX.Element) & { @@ -110,7 +131,7 @@ export const YearCalendar = React.forwardRef(function YearCalendar( onYearFocus, hasFocus, onFocusedViewChange, - yearsOrder = 'asc', + yearsOrder, yearsPerRow, timezone: timezoneProp, gridLabelId, @@ -294,6 +315,11 @@ export const YearCalendar = React.forwardRef(function YearCalendar( yearRange.reverse(); } + let fillerAmount = yearsPerRow - (yearRange.length % yearsPerRow); + if (fillerAmount === yearsPerRow) { + fillerAmount = 0; + } + return ( {yearRange.map((year) => { @@ -309,7 +336,7 @@ export const YearCalendar = React.forwardRef(function YearCalendar( const isDisabled = disabled || isYearDisabled(year); return ( - {utils.format(year, 'year')} - + ); })} + {Array.from({ length: fillerAmount }, (_, index) => ( + + ))} ); }) as YearCalendarComponent; diff --git a/packages/x-date-pickers/src/YearCalendar/YearCalendar.types.ts b/packages/x-date-pickers/src/YearCalendar/YearCalendar.types.ts index 8b7604afbe4a..955aa0cffc77 100644 --- a/packages/x-date-pickers/src/YearCalendar/YearCalendar.types.ts +++ b/packages/x-date-pickers/src/YearCalendar/YearCalendar.types.ts @@ -7,7 +7,7 @@ import { BaseDateValidationProps, YearValidationProps } from '../internals/model import { PickerOwnerState, PickerValidDate, TimezoneProps } from '../models'; import { FormProps } from '../internals/models/formProps'; -export interface PickerYearOwnerState extends PickerOwnerState { +export interface YearButtonOwnerState extends PickerOwnerState { isYearSelected: boolean; isYearDisabled: boolean; } @@ -24,7 +24,7 @@ export interface YearCalendarSlotProps { yearButton?: SlotComponentPropsFromProps< React.HTMLAttributes & { sx: SxProps }, {}, - PickerYearOwnerState + YearButtonOwnerState >; } diff --git a/packages/x-date-pickers/src/YearCalendar/PickersYear.tsx b/packages/x-date-pickers/src/YearCalendar/YearCalendarButton.tsx similarity index 59% rename from packages/x-date-pickers/src/YearCalendar/PickersYear.tsx rename to packages/x-date-pickers/src/YearCalendar/YearCalendarButton.tsx index 80f81f95d0a2..4362bceb4fce 100644 --- a/packages/x-date-pickers/src/YearCalendar/PickersYear.tsx +++ b/packages/x-date-pickers/src/YearCalendar/YearCalendarButton.tsx @@ -1,79 +1,60 @@ 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 { - getPickersYearUtilityClass, - pickersYearClasses, - PickersYearClasses, -} from './pickersYearClasses'; -import { - PickerYearOwnerState, + YearButtonOwnerState, YearCalendarSlotProps, YearCalendarSlots, } from './YearCalendar.types'; import { usePickerPrivateContext } from '../internals/hooks/usePickerPrivateContext'; import { PickerOwnerState } from '../models/pickers'; +import { + getYearCalendarUtilityClass, + yearCalendarClasses, + YearCalendarClasses, +} from './yearCalendarClasses'; -export interface ExportedPickersYearProps { - classes?: Partial; -} - -export interface PickersYearProps extends ExportedPickersYearProps { - 'aria-current'?: React.AriaAttributes['aria-current']; - autoFocus?: boolean; +export interface YearCalendarButtonProps { + value: number; + tabIndex: number; + selected: boolean; + disabled: boolean; + autoFocus: boolean; + classes: Partial | undefined; + slots: YearCalendarSlots | undefined; + slotProps: YearCalendarSlotProps | undefined; + 'aria-current': React.AriaAttributes['aria-current']; children: React.ReactNode; - className?: string; - disabled?: boolean; onClick: (event: React.MouseEvent, year: number) => void; onKeyDown: (event: React.KeyboardEvent, year: number) => void; onFocus: (event: React.FocusEvent, year: number) => void; onBlur: (event: React.FocusEvent, year: number) => void; - selected: boolean; - value: number; - tabIndex: number; - yearsPerRow: 3 | 4; - slots?: YearCalendarSlots; - slotProps?: YearCalendarSlotProps; } const useUtilityClasses = ( - classes: Partial | undefined, - ownerState: PickerYearOwnerState, + classes: Partial | undefined, + ownerState: YearButtonOwnerState, ) => { const slots = { - root: ['root'], - yearButton: [ - 'yearButton', + button: [ + 'button', ownerState.isYearDisabled && 'disabled', ownerState.isYearSelected && 'selected', ], }; - return composeClasses(slots, getPickersYearUtilityClass, classes); + return composeClasses(slots, getYearCalendarUtilityClass, classes); }; -const PickersYearRoot = styled('div', { - name: 'MuiPickersYear', - slot: 'Root', - overridesResolver: (_, styles) => [styles.root], -})<{ ownerState: PickerOwnerState }>({ - display: 'flex', - alignItems: 'center', - justifyContent: 'center', - flexBasis: '33.3%', - variants: [{ props: { yearsPerRow: 4 }, style: { flexBasis: '25%' } }], -}); - -const YearCalendarButton = styled('button', { - name: 'MuiPickersYear', - slot: 'YearButton', +const DefaultYearButton = styled('button', { + name: 'MuiYearCalendar', + slot: 'Button', overridesResolver: (_, styles) => [ - styles.yearButton, - { [`&.${pickersYearClasses.disabled}`]: styles.disabled }, - { [`&.${pickersYearClasses.selected}`]: styles.selected }, + styles.button, + { [`&.${yearCalendarClasses.disabled}`]: styles.disabled }, + { [`&.${yearCalendarClasses.selected}`]: styles.selected }, ], })<{ ownerState: PickerOwnerState }>(({ theme }) => ({ color: 'unset', @@ -81,7 +62,6 @@ const YearCalendarButton = styled('button', { border: 0, outline: 0, ...theme.typography.subtitle1, - margin: '6px 0', height: 36, width: 72, borderRadius: 18, @@ -100,10 +80,10 @@ const YearCalendarButton = styled('button', { cursor: 'auto', pointerEvents: 'none', }, - [`&.${pickersYearClasses.disabled}`]: { + [`&.${yearCalendarClasses.disabled}`]: { color: (theme.vars || theme).palette.text.secondary, }, - [`&.${pickersYearClasses.selected}`]: { + [`&.${yearCalendarClasses.selected}`]: { color: (theme.vars || theme).palette.primary.contrastText, backgroundColor: (theme.vars || theme).palette.primary.main, '&:focus, &:hover': { @@ -115,27 +95,19 @@ const YearCalendarButton = styled('button', { /** * @ignore - internal component. */ -export const PickersYear = React.memo(function PickersYear(inProps: PickersYearProps) { - const props = useThemeProps({ - props: inProps, - name: 'MuiPickersYear', - }); +export const YearCalendarButton = React.memo(function YearCalendarButton( + props: YearCalendarButtonProps, +) { const { autoFocus, - className, classes: classesProp, - children, - disabled = false, - selected = false, + disabled, + selected, value, - tabIndex, onClick, onKeyDown, onFocus, onBlur, - 'aria-current': ariaCurrent, - // We don't want to forward this prop to the root element - yearsPerRow, slots, slotProps, ...other @@ -143,7 +115,7 @@ export const PickersYear = React.memo(function PickersYear(inProps: PickersYearP const ref = React.useRef(null); const { ownerState: pickerOwnerState } = usePickerPrivateContext(); - const ownerState: PickerYearOwnerState = { + const ownerState: YearButtonOwnerState = { ...pickerOwnerState, isYearDisabled: disabled, isYearSelected: selected, @@ -158,18 +130,16 @@ export const PickersYear = React.memo(function PickersYear(inProps: PickersYearP } }, [autoFocus]); - const YearButton = slots?.yearButton ?? YearCalendarButton; + const YearButton = slots?.yearButton ?? DefaultYearButton; const yearButtonProps = useSlotProps({ elementType: YearButton, externalSlotProps: slotProps?.yearButton, + externalForwardedProps: other, additionalProps: { - children, disabled, - tabIndex, ref, type: 'button' as const, role: 'radio', - 'aria-current': ariaCurrent, 'aria-checked': selected, onClick: (event: React.MouseEvent) => onClick(event, value), onKeyDown: (event: React.KeyboardEvent) => onKeyDown(event, value), @@ -177,17 +147,8 @@ export const PickersYear = React.memo(function PickersYear(inProps: PickersYearP onBlur: (event: React.FocusEvent) => onBlur(event, value), }, ownerState, - className: classes.yearButton, + className: classes.button, }); - return ( - - - - ); + return ; }); diff --git a/packages/x-date-pickers/src/YearCalendar/index.ts b/packages/x-date-pickers/src/YearCalendar/index.ts index fce796c41eeb..0dc3d8590611 100644 --- a/packages/x-date-pickers/src/YearCalendar/index.ts +++ b/packages/x-date-pickers/src/YearCalendar/index.ts @@ -7,6 +7,3 @@ export type { export { yearCalendarClasses, getYearCalendarUtilityClass } from './yearCalendarClasses'; export type { YearCalendarClasses, YearCalendarClassKey } from './yearCalendarClasses'; -export { pickersYearClasses } from './pickersYearClasses'; -export type { PickersYearClasses, PickersYearClassKey } from './pickersYearClasses'; -export type { ExportedPickersYearProps } from './PickersYear'; diff --git a/packages/x-date-pickers/src/YearCalendar/pickersYearClasses.ts b/packages/x-date-pickers/src/YearCalendar/pickersYearClasses.ts deleted file mode 100644 index 67a37ee31b21..000000000000 --- a/packages/x-date-pickers/src/YearCalendar/pickersYearClasses.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { - unstable_generateUtilityClass as generateUtilityClass, - unstable_generateUtilityClasses as generateUtilityClasses, -} from '@mui/utils'; - -export interface PickersYearClasses { - /** Styles applied to the root element. */ - root: string; - /** Styles applied to the year button element. */ - yearButton: string; - /** Styles applied to a selected year button element. */ - selected: string; - /** Styles applied to a disabled year button element. */ - disabled: string; -} - -export type PickersYearClassKey = keyof PickersYearClasses; - -export function getPickersYearUtilityClass(slot: string) { - return generateUtilityClass('MuiPickersYear', slot); -} - -export const pickersYearClasses = generateUtilityClasses('MuiPickersYear', [ - 'root', - 'yearButton', - 'selected', - 'disabled', -]); diff --git a/packages/x-date-pickers/src/YearCalendar/tests/YearCalendar.test.tsx b/packages/x-date-pickers/src/YearCalendar/tests/YearCalendar.test.tsx index 630b5ab09fdd..77cc4f757b1f 100644 --- a/packages/x-date-pickers/src/YearCalendar/tests/YearCalendar.test.tsx +++ b/packages/x-date-pickers/src/YearCalendar/tests/YearCalendar.test.tsx @@ -57,8 +57,8 @@ describe('', () => { />, ); - const yearButttons = screen.queryAllByTestId('year'); - expect(yearButttons[0].children.item(0)?.textContent).to.equal('2020'); + const yearButtons = screen.queryAllByRole('radio'); + expect(yearButtons[0]?.textContent).to.equal('2020'); }); it('should display years in descending (reverse chronological) order when props.yearsOrder = "desc"', () => { @@ -70,8 +70,8 @@ describe('', () => { />, ); - const yearButtons = screen.queryAllByTestId('year'); - expect(yearButtons[0].children.item(0)?.textContent).to.equal('2024'); + const yearButtons = screen.queryAllByRole('radio'); + expect(yearButtons[0]?.textContent).to.equal('2024'); }); describe('Disabled', () => { @@ -79,9 +79,9 @@ describe('', () => { const onChange = spy(); render(); - screen.getAllByRole('radio').forEach((monthButton) => { - expect(monthButton).to.have.attribute('disabled'); - fireEvent.click(monthButton); + screen.getAllByRole('radio').forEach((yearButton) => { + expect(yearButton).to.have.attribute('disabled'); + fireEvent.click(yearButton); expect(onChange.callCount).to.equal(0); }); }); diff --git a/packages/x-date-pickers/src/YearCalendar/yearCalendarClasses.ts b/packages/x-date-pickers/src/YearCalendar/yearCalendarClasses.ts index 8d9962731b5b..67e4666c52f0 100644 --- a/packages/x-date-pickers/src/YearCalendar/yearCalendarClasses.ts +++ b/packages/x-date-pickers/src/YearCalendar/yearCalendarClasses.ts @@ -6,6 +6,12 @@ import { export interface YearCalendarClasses { /** Styles applied to the root element. */ root: string; + /** Styles applied to the button element that represents a single year */ + button: string; + /** Styles applied to a disabled button element. */ + disabled: string; + /** Styles applied to a selected button element. */ + selected: string; } export type YearCalendarClassKey = keyof YearCalendarClasses; @@ -14,4 +20,9 @@ export function getYearCalendarUtilityClass(slot: string) { return generateUtilityClass('MuiYearCalendar', slot); } -export const yearCalendarClasses = generateUtilityClasses('MuiYearCalendar', ['root']); +export const yearCalendarClasses = generateUtilityClasses('MuiYearCalendar', [ + 'root', + 'button', + 'disabled', + 'selected', +]); diff --git a/packages/x-date-pickers/src/themeAugmentation/components.d.ts b/packages/x-date-pickers/src/themeAugmentation/components.d.ts index 7ec1df957c55..fe83141400e0 100644 --- a/packages/x-date-pickers/src/themeAugmentation/components.d.ts +++ b/packages/x-date-pickers/src/themeAugmentation/components.d.ts @@ -78,10 +78,6 @@ export interface PickerComponents { defaultProps?: ComponentsProps['MuiPickersFadeTransitionGroup']; styleOverrides?: ComponentsOverrides['MuiPickersFadeTransitionGroup']; }; - MuiPickersMonth?: { - defaultProps?: ComponentsProps['MuiPickersMonth']; - styleOverrides?: ComponentsOverrides['MuiPickersMonth']; - }; MuiPickersPopper?: { defaultProps?: ComponentsProps['MuiPickersPopper']; styleOverrides?: ComponentsOverrides['MuiPickersPopper']; @@ -106,10 +102,6 @@ export interface PickerComponents { defaultProps?: ComponentsProps['MuiPickersLayout']; styleOverrides?: ComponentsOverrides['MuiPickersLayout']; }; - MuiPickersYear?: { - defaultProps?: ComponentsProps['MuiPickersYear']; - styleOverrides?: ComponentsOverrides['MuiPickersYear']; - }; MuiTimeClock?: { defaultProps?: ComponentsProps['MuiTimeClock']; styleOverrides?: ComponentsOverrides['MuiTimeClock']; diff --git a/packages/x-date-pickers/src/themeAugmentation/overrides.d.ts b/packages/x-date-pickers/src/themeAugmentation/overrides.d.ts index 085620287683..2722d0ad6267 100644 --- a/packages/x-date-pickers/src/themeAugmentation/overrides.d.ts +++ b/packages/x-date-pickers/src/themeAugmentation/overrides.d.ts @@ -12,9 +12,9 @@ import { TimeClockClassKey, ClockPointerClassKey, } from '../TimeClock'; -import { MonthCalendarClassKey, PickersMonthClassKey } from '../MonthCalendar'; +import { MonthCalendarClassKey } from '../MonthCalendar'; import { PickersDayClassKey } from '../PickersDay'; -import { PickersYearClassKey, YearCalendarClassKey } from '../YearCalendar'; +import { YearCalendarClassKey } from '../YearCalendar'; import { PickersLayoutClassKey } from '../PickersLayout'; import { DatePickerToolbarClassKey } from '../DatePicker'; import { TimePickerToolbarClassKey } from '../TimePicker'; @@ -58,13 +58,11 @@ export interface PickersComponentNameToClassKey { MuiPickersDay: PickersDayClassKey; MuiPickersFadeTransitionGroup: PickersFadeTransitionGroupClassKey; MuiPickersLayout: PickersLayoutClassKey; - MuiPickersMonth: PickersMonthClassKey; MuiPickersPopper: PickersPopperClassKey; MuiPickersSlideTransition: PickersSlideTransitionClassKey; MuiPickersToolbar: PickersToolbarClassKey; MuiPickersToolbarButton: PickersToolbarButtonClassKey; MuiPickersToolbarText: PickersToolbarTextClassKey; - MuiPickersYear: PickersYearClassKey; MuiTimeClock: TimeClockClassKey; MuiTimePickerToolbar: TimePickerToolbarClassKey; MuiYearCalendar: YearCalendarClassKey; diff --git a/packages/x-date-pickers/src/themeAugmentation/props.d.ts b/packages/x-date-pickers/src/themeAugmentation/props.d.ts index f5bdfe45dade..453152c39664 100644 --- a/packages/x-date-pickers/src/themeAugmentation/props.d.ts +++ b/packages/x-date-pickers/src/themeAugmentation/props.d.ts @@ -5,9 +5,9 @@ import { } from '../DateCalendar'; import { DayCalendarSkeletonProps } from '../DayCalendarSkeleton'; import { ClockNumberProps, TimeClockProps, ClockPointerProps, ClockProps } from '../TimeClock'; -import { ExportedPickersMonthProps, MonthCalendarProps } from '../MonthCalendar'; +import { MonthCalendarProps } from '../MonthCalendar'; import { PickersDayProps } from '../PickersDay'; -import { ExportedPickersYearProps, YearCalendarProps } from '../YearCalendar'; +import { YearCalendarProps } from '../YearCalendar'; import { DateFieldProps } from '../DateField'; import { LocalizationProviderProps } from '../LocalizationProvider'; import { PickersLayoutProps } from '../PickersLayout'; @@ -75,14 +75,12 @@ export interface PickersComponentsPropsList { MuiPickersCalendarHeader: ExportedPickersCalendarHeaderProps; MuiPickersDay: PickersDayProps; MuiPickersFadeTransitionGroup: PickersFadeTransitionGroupProps; - MuiPickersMonth: ExportedPickersMonthProps; MuiPickersPopper: PickerPopperProps; MuiPickersSlideTransition: ExportedSlideTransitionProps; MuiPickersToolbar: PickersToolbarProps; MuiPickersToolbarButton: PickersToolbarButtonProps; MuiPickersToolbarText: ExportedPickersToolbarTextProps; MuiPickersLayout: PickersLayoutProps; - MuiPickersYear: ExportedPickersYearProps; MuiTimeClock: TimeClockProps; MuiTimeField: TimeFieldProps; MuiTimePickerToolbar: ExportedTimePickerToolbarProps; diff --git a/packages/x-date-pickers/src/themeAugmentation/themeAugmentation.spec.ts b/packages/x-date-pickers/src/themeAugmentation/themeAugmentation.spec.ts index 0909e08f5cf6..8bd7cdc5e7d7 100644 --- a/packages/x-date-pickers/src/themeAugmentation/themeAugmentation.spec.ts +++ b/packages/x-date-pickers/src/themeAugmentation/themeAugmentation.spec.ts @@ -18,7 +18,6 @@ import { pickersArrowSwitcherClasses } from '../internals/components/PickersArro import { pickersPopperClasses } from '../internals/components/pickersPopperClasses'; import { pickersDayClasses } from '../PickersDay'; import { timePickerToolbarClasses } from '../TimePicker'; -import { pickersMonthClasses } from '../MonthCalendar'; import { digitalClockClasses } from '../DigitalClock'; import { multiSectionDigitalClockClasses, @@ -355,25 +354,6 @@ createTheme({ }, }, }, - MuiPickersMonth: { - defaultProps: { - classes: { selected: 'test' }, - // @ts-expect-error invalid MuiPickersMonth prop - someRandomProp: true, - }, - styleOverrides: { - root: { - backgroundColor: 'red', - [`.${pickersMonthClasses.monthButton}`]: { - backgroundColor: 'green', - }, - }, - // @ts-expect-error invalid MuiPickersMonth class key - content: { - backgroundColor: 'blue', - }, - }, - }, MuiPickersPopper: { defaultProps: { open: true, @@ -479,22 +459,6 @@ createTheme({ }, }, }, - MuiPickersYear: { - defaultProps: { - classes: { yearButton: 'test' }, - // @ts-expect-error invalid MuiPickersYear prop - someRandomProp: true, - }, - styleOverrides: { - yearButton: { - backgroundColor: 'red', - }, - // @ts-expect-error invalid MuiPickersYear class key - content: { - backgroundColor: 'blue', - }, - }, - }, MuiTimeClock: { defaultProps: { view: 'hours', diff --git a/scripts/x-date-pickers-pro.exports.json b/scripts/x-date-pickers-pro.exports.json index 36b647590889..9ec051502703 100644 --- a/scripts/x-date-pickers-pro.exports.json +++ b/scripts/x-date-pickers-pro.exports.json @@ -149,10 +149,8 @@ { "name": "ExportedPickersCalendarHeaderProps", "kind": "TypeAlias" }, { "name": "ExportedPickersLayoutSlotProps", "kind": "Interface" }, { "name": "ExportedPickersLayoutSlots", "kind": "Interface" }, - { "name": "ExportedPickersMonthProps", "kind": "Interface" }, { "name": "ExportedPickersRangeCalendarHeaderProps", "kind": "Interface" }, { "name": "ExportedPickersSectionListProps", "kind": "Interface" }, - { "name": "ExportedPickersYearProps", "kind": "Interface" }, { "name": "ExportedSlideTransitionProps", "kind": "Interface" }, { "name": "ExportedUseClearableFieldProps", "kind": "Interface" }, { "name": "extractValidationProps", "kind": "Variable" }, @@ -301,9 +299,6 @@ { "name": "PickersLayoutSlotProps", "kind": "Interface" }, { "name": "PickersLayoutSlots", "kind": "Interface" }, { "name": "PickersLocaleText", "kind": "Interface" }, - { "name": "pickersMonthClasses", "kind": "Variable" }, - { "name": "PickersMonthClasses", "kind": "Interface" }, - { "name": "PickersMonthClassKey", "kind": "TypeAlias" }, { "name": "PickersOutlinedInput", "kind": "Variable" }, { "name": "pickersOutlinedInputClasses", "kind": "Variable" }, { "name": "PickersOutlinedInputClasses", "kind": "Interface" }, @@ -333,9 +328,6 @@ { "name": "PickersTextFieldProps", "kind": "TypeAlias" }, { "name": "PickersTimezone", "kind": "TypeAlias" }, { "name": "PickersTranslationKeys", "kind": "TypeAlias" }, - { "name": "pickersYearClasses", "kind": "Variable" }, - { "name": "PickersYearClasses", "kind": "Interface" }, - { "name": "PickersYearClassKey", "kind": "TypeAlias" }, { "name": "PickerValidDate", "kind": "TypeAlias" }, { "name": "PickerValidDateLookup", "kind": "Interface" }, { "name": "PickerValueType", "kind": "TypeAlias" }, diff --git a/scripts/x-date-pickers.exports.json b/scripts/x-date-pickers.exports.json index 60cb4180bd3c..ff4ae2da325f 100644 --- a/scripts/x-date-pickers.exports.json +++ b/scripts/x-date-pickers.exports.json @@ -98,9 +98,7 @@ { "name": "ExportedPickersCalendarHeaderProps", "kind": "TypeAlias" }, { "name": "ExportedPickersLayoutSlotProps", "kind": "Interface" }, { "name": "ExportedPickersLayoutSlots", "kind": "Interface" }, - { "name": "ExportedPickersMonthProps", "kind": "Interface" }, { "name": "ExportedPickersSectionListProps", "kind": "Interface" }, - { "name": "ExportedPickersYearProps", "kind": "Interface" }, { "name": "ExportedSlideTransitionProps", "kind": "Interface" }, { "name": "ExportedUseClearableFieldProps", "kind": "Interface" }, { "name": "extractValidationProps", "kind": "Variable" }, @@ -215,9 +213,6 @@ { "name": "PickersLayoutSlotProps", "kind": "Interface" }, { "name": "PickersLayoutSlots", "kind": "Interface" }, { "name": "PickersLocaleText", "kind": "Interface" }, - { "name": "pickersMonthClasses", "kind": "Variable" }, - { "name": "PickersMonthClasses", "kind": "Interface" }, - { "name": "PickersMonthClassKey", "kind": "TypeAlias" }, { "name": "PickersOutlinedInput", "kind": "Variable" }, { "name": "pickersOutlinedInputClasses", "kind": "Variable" }, { "name": "PickersOutlinedInputClasses", "kind": "Interface" }, @@ -245,9 +240,6 @@ { "name": "PickersTextFieldProps", "kind": "TypeAlias" }, { "name": "PickersTimezone", "kind": "TypeAlias" }, { "name": "PickersTranslationKeys", "kind": "TypeAlias" }, - { "name": "pickersYearClasses", "kind": "Variable" }, - { "name": "PickersYearClasses", "kind": "Interface" }, - { "name": "PickersYearClassKey", "kind": "TypeAlias" }, { "name": "PickerValidDate", "kind": "TypeAlias" }, { "name": "PickerValidDateLookup", "kind": "Interface" }, { "name": "PickerValueType", "kind": "TypeAlias" },