Skip to content

[pickers] Update Date calendar styling following MD3 guidelines #9279

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 50 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
b048d46
Update date calendar styling and spacing
LukasTy May 3, 2023
453b479
Fix to not hide label container when non-day view is selected
LukasTy May 3, 2023
6559071
Align date range calendar month label style to date calendar
LukasTy May 3, 2023
b7eaee8
Remove no longer needed padding
LukasTy May 3, 2023
6900afd
Pixel adjustments
LukasTy May 3, 2023
6230f7b
Remove irrelevant range calendar `minWidth`
LukasTy May 4, 2023
64298fd
Remove unwanted extra margins
LukasTy May 4, 2023
bb4d5a3
Align date range calendar day size with date calendar
LukasTy May 4, 2023
8417435
Re-use `DAY_SIZE` constant
LukasTy May 4, 2023
7e6205b
Add export
LukasTy May 4, 2023
9bfbf28
Remove irrelevant width
LukasTy May 4, 2023
da69b82
Merge remote-tracking branch 'origin/master' into update-date-calenda…
LukasTy May 5, 2023
fd9113e
Fix desktop spacing and alignment
LukasTy May 5, 2023
920f344
Fix year calendar styling
LukasTy May 5, 2023
5c8bd4b
Fix month calendar styling
LukasTy May 5, 2023
ce430fa
Adjust container width based on `disableMargin` value
LukasTy May 8, 2023
42d83f5
Reduce week number width to correctly fit it on mobile
LukasTy May 8, 2023
de01ca1
Remove initial fade-in animation
LukasTy May 8, 2023
416c00c
proptypes
LukasTy May 8, 2023
e2e78c8
Revert no longer relevant change done in #8541
LukasTy May 8, 2023
ec70adf
Merge remote-tracking branch 'origin/master' into update-date-calenda…
LukasTy May 8, 2023
fec3c7b
Use `inherit` width when inside of a date calendar
LukasTy May 8, 2023
0349132
Reduce margin
LukasTy May 8, 2023
d0c54cd
Support 4 years and months per row on standalone calendars
LukasTy May 8, 2023
70068ed
Update drag touch coordinates
LukasTy May 8, 2023
0220fe3
Reduce spacing between view switcher items on time clock
LukasTy May 9, 2023
f8feb15
Merge branch 'master' into update-date-calendar-styling
LukasTy May 17, 2023
1307f93
Remove unwanted extra `opacity`
LukasTy May 17, 2023
04f4b96
Align week container vertically to center week numbers
LukasTy May 17, 2023
0a7d486
Add the bottom margin to the calculated height of the container
LukasTy May 17, 2023
94406d2
Use clock dimension constant for styles
LukasTy May 18, 2023
93f67d7
Align toolbar to end
LukasTy May 18, 2023
b6217c6
Adjust toolbar styling based on Gerda's feedback
LukasTy May 18, 2023
075591d
Update test
LukasTy May 18, 2023
1a625fb
Fix range calendar height
LukasTy May 18, 2023
31045ce
Extract weeks container height into dimensions
LukasTy May 18, 2023
71fa978
prettier
LukasTy May 18, 2023
6fc9c82
Reduce toolbar bottom padding
LukasTy May 18, 2023
f503fb1
Remove toolbar pen icon leftovers
LukasTy May 18, 2023
173f0da
Fix range toolbar alignment
LukasTy May 18, 2023
7b42f95
Fix range calendar width on mobile
LukasTy May 18, 2023
c439e11
Fix date range calendar weekday container alignment
LukasTy May 18, 2023
f022b74
Revert toolbar changes
LukasTy May 23, 2023
90dc0d3
Revert to having minimum modal width
LukasTy May 23, 2023
62d5aae
Remove comments
LukasTy May 23, 2023
6853653
Revert test change
LukasTy May 23, 2023
6e3c7a9
Merge remote-tracking branch 'origin/master' into update-date-calenda…
LukasTy May 31, 2023
2d9a421
Apply selected style only to days inside current month
LukasTy May 31, 2023
7b9977e
Align date calendar spacing with MD3 guidelines
LukasTy Jun 9, 2023
7d7a71c
Experiment with range calendar styling update
LukasTy Jun 9, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/data/date-pickers/date-calendar/CustomDay.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ function Day(props) {
<CustomPickersDay
{...other}
day={day}
sx={dayIsBetween ? { px: 2.5, mx: 0 } : {}}
disableMargin
dayIsBetween={dayIsBetween}
isFirstDay={isFirstDay}
isLastDay={isLastDay}
Expand Down
2 changes: 1 addition & 1 deletion docs/data/date-pickers/date-calendar/CustomDay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ function Day(props: PickersDayProps<Dayjs> & { selectedDay?: Dayjs | null }) {
<CustomPickersDay
{...other}
day={day}
sx={dayIsBetween ? { px: 2.5, mx: 0 } : {}}
disableMargin
dayIsBetween={dayIsBetween}
isFirstDay={isFirstDay}
isLastDay={isLastDay}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { Watermark } from '@mui/x-license-pro';
import {
applyDefaultDate,
BaseDateValidationProps,
DAY_MARGIN,
DayCalendar,
DayCalendarSlotsComponent,
DayCalendarSlotsComponentsProps,
Expand All @@ -30,7 +29,10 @@ import {
UncapitalizeObjectKeys,
DEFAULT_DESKTOP_MODE_MEDIA_QUERY,
buildWarning,
CALENDAR_MARGIN,
} from '@mui/x-date-pickers/internals';
import Typography from '@mui/material/Typography';
import { VIEW_HEIGHT } from '@mui/x-date-pickers/internals/constants/dimensions';
import { getReleaseInfo } from '../internal/utils/releaseInfo';
import {
dateRangeCalendarClasses,
Expand Down Expand Up @@ -64,11 +66,12 @@ const DateRangeCalendarRoot = styled('div', {
})<{ ownerState: DateRangeCalendarOwnerState<any> }>({
display: 'flex',
flexDirection: 'row',
minHeight: VIEW_HEIGHT,
});

const DateRangeCalendarMonthContainer = styled('div', {
name: 'MuiDateRangeCalendar',
slot: 'Container',
slot: 'MonthContainer',
overridesResolver: (_, styles) => styles.monthContainer,
})(({ theme }) => ({
'&:not(:last-of-type)': {
Expand All @@ -77,23 +80,18 @@ const DateRangeCalendarMonthContainer = styled('div', {
}));

const DateRangeCalendarArrowSwitcher = styled(PickersArrowSwitcher)({
padding: '16px 16px 8px 16px',
display: 'flex',
margin: CALENDAR_MARGIN,
marginBottom: CALENDAR_MARGIN / 2,
alignItems: 'center',
justifyContent: 'space-between',
});

const DAY_RANGE_SIZE = 40;
const weeksContainerHeight = (DAY_RANGE_SIZE + DAY_MARGIN * 2) * 6;

const warnInvalidCurrentMonthCalendarPosition = buildWarning([
'The `currentMonthCalendarPosition` prop must be an integer between `1` and the amount of calendars rendered.',
'For example if you have 2 calendars rendered, it should be equal to either 1 or 2.',
]);

const DayCalendarForRange = styled(DayCalendar)(({ theme }) => ({
minWidth: 312,
minHeight: weeksContainerHeight,
[`&.${dateRangeCalendarClasses.dayDragging}`]: {
[`& .${dayClasses.day}`]: {
cursor: 'grabbing',
Expand Down Expand Up @@ -545,7 +543,9 @@ const DateRangeCalendar = React.forwardRef(function DateRangeCalendar<TDate>(
slots={slots}
slotProps={slotProps}
>
{utils.format(visibleMonths[month], 'monthAndYear')}
<Typography variant="body1" fontWeight="medium" component="span">
{utils.format(visibleMonths[month], 'monthAndYear')}
</Typography>
</DateRangeCalendarArrowSwitcher>
)}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { unstable_composeClasses as composeClasses } from '@mui/utils';
import {
PickersToolbar,
PickersToolbarButton,
pickersToolbarClasses,
useUtils,
BaseToolbarProps,
useLocaleText,
Expand Down Expand Up @@ -47,19 +46,15 @@ const DateRangePickerToolbarRoot = styled(PickersToolbar, {
overridesResolver: (_, styles) => styles.root,
})<{
ownerState: DateRangePickerToolbarProps<any>;
}>({
[`& .${pickersToolbarClasses.penIconButton}`]: {
position: 'relative',
top: 4,
},
});
}>({});

const DateRangePickerToolbarContainer = styled('div', {
name: 'MuiDateRangePickerToolbar',
slot: 'Container',
overridesResolver: (_, styles) => styles.container,
})({
display: 'flex',
alignItems: 'center',
});

const DateRangePickerToolbar = React.forwardRef(function DateRangePickerToolbar<
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import clsx from 'clsx';
import { useLicenseVerifier } from '@mui/x-license-pro';
import { alpha, styled, useThemeProps } from '@mui/material/styles';
import { unstable_composeClasses as composeClasses } from '@mui/utils';
import { useUtils } from '@mui/x-date-pickers/internals';
import { PickersDay, pickersDayClasses, PickersDayProps } from '@mui/x-date-pickers/PickersDay';
import { DAY_MARGIN, DAY_SIZE, useUtils } from '@mui/x-date-pickers/internals';
import { PickersDay, PickersDayProps } from '@mui/x-date-pickers/PickersDay';
import {
DateRangePickerDayClasses,
getDateRangePickerDayUtilityClass,
Expand Down Expand Up @@ -157,6 +157,7 @@ const DateRangePickerDayRoot = styled('div', {
ownerState.isHiddenDayFiller
? {}
: {
position: 'relative',
[`&:first-of-type .${dateRangePickerDayClasses.rangeIntervalDayPreview}`]: {
...startBorderStyle,
borderLeftColor: (theme.vars || theme).palette.divider,
Expand All @@ -165,22 +166,35 @@ const DateRangePickerDayRoot = styled('div', {
...endBorderStyle,
borderRightColor: (theme.vars || theme).palette.divider,
},
border: `${DAY_MARGIN}px solid transparent`,
...(ownerState.isHighlighting && {
borderRadius: 0,
color: (theme.vars || theme).palette.primary.contrastText,
backgroundColor: theme.vars
? `rgba(${theme.vars.palette.primary.mainChannel} / ${theme.vars.palette.action.focusOpacity})`
: alpha(theme.palette.primary.main, theme.palette.action.focusOpacity),
'&:first-of-type': startBorderStyle,
'&:last-of-type': endBorderStyle,
}),
...((ownerState.isStartOfHighlighting || ownerState.isFirstVisibleCell) && {
...startBorderStyle,
paddingLeft: 0,
}),
...((ownerState.isEndOfHighlighting || ownerState.isLastVisibleCell) && {
...endBorderStyle,
paddingRight: 0,
'&:before': {
pointerEvents: 'none',
position: 'absolute',
content: '""',
width: `calc(100% + ${2 * DAY_MARGIN}px)`,
height: DAY_SIZE,
borderRadius: 0,
color: (theme.vars || theme).palette.primary.contrastText,
backgroundColor: theme.vars
? `rgba(${theme.vars.palette.primary.mainChannel} / ${theme.vars.palette.action.focusOpacity})`
: alpha(theme.palette.primary.main, theme.palette.action.focusOpacity),
...((ownerState.isStartOfHighlighting || ownerState.isFirstVisibleCell) && {
...startBorderStyle,
paddingLeft: 0,
}),
...((ownerState.isEndOfHighlighting || ownerState.isLastVisibleCell) && {
...endBorderStyle,
paddingRight: 0,
width: `100%`,
right: 0,
}),
},
'&:first-of-type:before': startBorderStyle,
'&:last-of-type:before': {
...endBorderStyle,
width: `calc(100% + ${DAY_MARGIN}px)`,
},
}),
},
);
Expand Down Expand Up @@ -211,6 +225,9 @@ const DateRangePickerDayRangeIntervalPreview = styled('div', {
})<{ ownerState: OwnerState }>(({ theme, ownerState }) => ({
// replace default day component margin with transparent border to avoid jumping on preview
border: '2px solid transparent',
...(ownerState.isHiddenDayFiller && {
margin: DAY_MARGIN,
}),
...(ownerState.isPreviewing &&
!ownerState.isHiddenDayFiller && {
borderRadius: 0,
Expand Down Expand Up @@ -248,18 +265,11 @@ const DateRangePickerDayDay = styled(PickersDay, {
})<{
ownerState: OwnerState;
}>(({ ownerState }) => ({
// account for difference in expected margin and the preview border
width: DAY_SIZE - DAY_MARGIN,
height: DAY_SIZE - DAY_MARGIN,
// Required to overlap preview border
transform: 'scale(1.1)',
'& > *': {
transform: 'scale(0.9)',
},
...(!ownerState.selected &&
ownerState.isHighlighting && {
opacity: 0.7,
[`&.${pickersDayClasses.dayOutsideMonth}`]: {
opacity: 0.4,
},
}),
transform: 'scale(1.111)',
...(ownerState.draggable && {
cursor: 'grab',
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
PickersLayout,
PickersLayoutSlotsComponentsProps,
} from '@mui/x-date-pickers/PickersLayout';
import { usePicker, DIALOG_WIDTH, ExportedBaseToolbarProps } from '@mui/x-date-pickers/internals';
import { usePicker, ExportedBaseToolbarProps } from '@mui/x-date-pickers/internals';
import { DateOrTimeViewWithMeridiem } from '@mui/x-date-pickers/internals/models';
import {
UseStaticRangePickerParams,
Expand All @@ -18,7 +18,6 @@ import { RangeFieldSection } from '../../models/fields';

const PickerStaticLayout = styled(PickersLayout)(({ theme }) => ({
overflow: 'hidden',
minWidth: DIALOG_WIDTH,
backgroundColor: (theme.vars || theme).palette.background.paper,
})) as unknown as typeof PickersLayout;

Expand Down
16 changes: 11 additions & 5 deletions packages/x-date-pickers/src/DateCalendar/DateCalendar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
unstable_useEventCallback as useEventCallback,
unstable_useControlled as useControlled,
} from '@mui/utils';
import { resolveComponentProps } from '@mui/base/utils';
import { DateCalendarProps, DateCalendarDefaultizedProps } from './DateCalendar.types';
import { useCalendarState } from './useCalendarState';
import { useDefaultDates, useUtils } from '../internals/hooks/useUtils';
Expand All @@ -27,6 +28,7 @@ import { defaultReduceAnimations } from '../internals/utils/defaultReduceAnimati
import { getDateCalendarUtilityClass } from './dateCalendarClasses';
import { BaseDateValidationProps } from '../internals/models/validation';
import type { PickerSelectionState } from '../internals/hooks/usePicker';
import { DAY_MARGIN, DIALOG_WIDTH } from '../internals';

const useUtilityClasses = (ownerState: DateCalendarProps<any>) => {
const { classes } = ownerState;
Expand Down Expand Up @@ -67,10 +69,9 @@ const DateCalendarRoot = styled(PickerViewRoot, {
name: 'MuiDateCalendar',
slot: 'Root',
overridesResolver: (props, styles) => styles.root,
})<{ ownerState: DateCalendarProps<any> }>({
display: 'flex',
flexDirection: 'column',
});
})<{ ownerState: DateCalendarProps<any> & { disableDayMargin?: boolean } }>(({ ownerState }) => ({
width: DIALOG_WIDTH + (ownerState.disableDayMargin ? 7 * 2 * DAY_MARGIN : 0),
}));

const DateCalendarViewTransitionContainer = styled(PickersFadeTransitionGroup, {
name: 'MuiDateCalendar',
Expand Down Expand Up @@ -255,7 +256,9 @@ export const DateCalendar = React.forwardRef(function DateCalendar<TDate>(
}
}, [value]); // eslint-disable-line

const ownerState = props;
// we only need one prop resolved correctly, passing empty object shouldn't be a problem
const disableDayMargin = resolveComponentProps(slotProps?.day, {} as any)?.disableMargin;
const ownerState = { ...props, disableDayMargin };
const classes = useUtilityClasses(ownerState);

const baseDateValidationProps: Required<BaseDateValidationProps<TDate>> = {
Expand Down Expand Up @@ -316,6 +319,7 @@ export const DateCalendar = React.forwardRef(function DateCalendar<TDate>(
labelId={gridLabelId}
slots={slots}
slotProps={slotProps}
displayWeekNumber={displayWeekNumber}
/>
<DateCalendarViewTransitionContainer
reduceAnimations={reduceAnimations}
Expand All @@ -334,6 +338,7 @@ export const DateCalendar = React.forwardRef(function DateCalendar<TDate>(
hasFocus={hasFocus}
onFocusedViewChange={(isViewFocused) => setFocusedView('year', isViewFocused)}
yearsPerRow={yearsPerRow}
width="inherit"
/>
)}

Expand All @@ -348,6 +353,7 @@ export const DateCalendar = React.forwardRef(function DateCalendar<TDate>(
shouldDisableMonth={shouldDisableMonth}
onFocusedViewChange={(isViewFocused) => setFocusedView('month', isViewFocused)}
monthsPerRow={monthsPerRow}
width="inherit"
/>
)}

Expand Down
Loading