Skip to content

Commit

Permalink
[pickers] Migrate PickersCalendarHeader to emotion (#26354)
Browse files Browse the repository at this point in the history
  • Loading branch information
siriwatknp authored May 21, 2021
1 parent 6209295 commit 12a017d
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 111 deletions.
147 changes: 71 additions & 76 deletions packages/material-ui-lab/src/CalendarPicker/PickersCalendarHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import Fade from '@material-ui/core/Fade';
import { WithStyles, withStyles, StyleRules, MuiStyles } from '@material-ui/core/styles';
import { experimentalStyled as styled } from '@material-ui/core/styles';
import IconButton from '@material-ui/core/IconButton';
import { SlideDirection } from './PickersSlideTransition';
import { useUtils } from '../internal/pickers/hooks/useUtils';
Expand Down Expand Up @@ -59,53 +57,47 @@ export interface PickersCalendarHeaderProps<TDate>
onViewChange?: (view: CalendarPickerView) => void;
}

export type PickersCalendarHeaderClassKey =
| 'root'
| 'yearSelectionSwitcher'
| 'switchView'
| 'switchViewActive'
| 'label'
| 'labelItem';

export const styles: MuiStyles<PickersCalendarHeaderClassKey> = (
theme,
): StyleRules<PickersCalendarHeaderClassKey> => ({
root: {
display: 'flex',
alignItems: 'center',
marginTop: 16,
marginBottom: 8,
paddingLeft: 24,
paddingRight: 12,
// prevent jumping in safari
maxHeight: 30,
minHeight: 30,
},
yearSelectionSwitcher: {
marginRight: 'auto',
},
switchView: {
const PickersCalendarHeaderRoot = styled('div', { skipSx: true })({
display: 'flex',
alignItems: 'center',
marginTop: 16,
marginBottom: 8,
paddingLeft: 24,
paddingRight: 12,
// prevent jumping in safari
maxHeight: 30,
minHeight: 30,
});

const PickersCalendarHeaderLabel = styled('div', { skipSx: true })(({ theme }) => ({
display: 'flex',
maxHeight: 30,
overflow: 'hidden',
alignItems: 'center',
cursor: 'pointer',
marginRight: 'auto',
...theme.typography.body1,
fontWeight: theme.typography.fontWeightMedium,
}));

const PickersCalendarHeaderLabelItem = styled('div', { skipSx: true })({
marginRight: 6,
});

const PickersCalendarHeaderSwitchViewButton = styled(IconButton, { skipSx: true })({
marginRight: 'auto',
});

const PickersCalendarHeaderSwitchView = styled(ArrowDropDownIcon, { skipSx: true })(
({ theme, styleProps = {} }) => ({
willChange: 'transform',
transition: theme.transitions.create('transform'),
transform: 'rotate(0deg)',
},
switchViewActive: {
transform: 'rotate(180deg)',
},
label: {
display: 'flex',
maxHeight: 30,
overflow: 'hidden',
alignItems: 'center',
cursor: 'pointer',
marginRight: 'auto',
...theme.typography.body1,
fontWeight: theme.typography.fontWeightMedium,
},
labelItem: {
marginRight: 6,
},
});
...(styleProps.openView === 'year' && {
transform: 'rotate(180deg)',
}),
}),
);

function getSwitchingViewAriaText(view: CalendarPickerView) {
return view === 'year'
Expand All @@ -116,11 +108,8 @@ function getSwitchingViewAriaText(view: CalendarPickerView) {
/**
* @ignore - do not document.
*/
function PickersCalendarHeader<TDate>(
props: PickersCalendarHeaderProps<TDate> & WithStyles<typeof styles>,
) {
function PickersCalendarHeader<TDate>(props: PickersCalendarHeaderProps<TDate>) {
const {
classes,
components = {},
componentsProps = {},
currentMonth: month,
Expand All @@ -140,9 +129,7 @@ function PickersCalendarHeader<TDate>(

const utils = useUtils<TDate>();

const SwitchViewButton = components.SwitchViewButton || IconButton;
const switchViewButtonProps = componentsProps.switchViewButton || {};
const SwitchViewIcon = components.SwitchViewIcon || ArrowDropDownIcon;

const selectNextMonth = () => onMonthChange(utils.getNextMonth(month), 'left');
const selectPreviousMonth = () => onMonthChange(utils.getPreviousMonth(month), 'right');
Expand All @@ -169,40 +156,55 @@ function PickersCalendarHeader<TDate>(
return null;
}

// TODO: convert to simple assignment after the type error in defaultPropsHandler.js:60:6 is fixed
const styleProps = { ...props };

return (
<div className={classes.root}>
<div role="presentation" className={classes.label} onClick={handleToggleView}>
<PickersCalendarHeaderRoot styleProps={styleProps}>
<PickersCalendarHeaderLabel
role="presentation"
onClick={handleToggleView}
styleProps={styleProps}
>
<FadeTransitionGroup
reduceAnimations={reduceAnimations}
transKey={utils.format(month, 'month')}
>
<div aria-live="polite" data-mui-test="calendar-month-text" className={classes.labelItem}>
<PickersCalendarHeaderLabelItem
aria-live="polite"
data-mui-test="calendar-month-text"
styleProps={styleProps}
>
{utils.format(month, 'month')}
</div>
</PickersCalendarHeaderLabelItem>
</FadeTransitionGroup>
<FadeTransitionGroup
reduceAnimations={reduceAnimations}
transKey={utils.format(month, 'year')}
>
<div aria-live="polite" data-mui-test="calendar-year-text" className={classes.labelItem}>
<PickersCalendarHeaderLabelItem
aria-live="polite"
data-mui-test="calendar-year-text"
styleProps={styleProps}
>
{utils.format(month, 'year')}
</div>
</PickersCalendarHeaderLabelItem>
</FadeTransitionGroup>
{views.length > 1 && (
<SwitchViewButton
<PickersCalendarHeaderSwitchViewButton
size="small"
className={classes.yearSelectionSwitcher}
as={components.SwitchViewButton}
aria-label={getViewSwitchingButtonText(currentView)}
{...switchViewButtonProps}
styleProps={{ ...styleProps, ...switchViewButtonProps }}
>
<SwitchViewIcon
className={clsx(classes.switchView, {
[classes.switchViewActive]: currentView === 'year',
})}
<PickersCalendarHeaderSwitchView
as={components.SwitchViewIcon}
styleProps={styleProps}
/>
</SwitchViewButton>
</PickersCalendarHeaderSwitchViewButton>
)}
</div>
</PickersCalendarHeaderLabel>
<Fade in={currentView === 'day'}>
<PickersArrowSwitcher
leftArrowButtonText={leftArrowButtonText}
Expand All @@ -215,15 +217,8 @@ function PickersCalendarHeader<TDate>(
isRightDisabled={isNextMonthDisabled}
/>
</Fade>
</div>
</PickersCalendarHeaderRoot>
);
}

PickersCalendarHeader.propTypes = {
leftArrowButtonText: PropTypes.string,
rightArrowButtonText: PropTypes.string,
};

export default withStyles(styles, { name: 'PrivatePickersCalendarHeader' })(
PickersCalendarHeader,
) as <TDate>(props: PickersCalendarHeaderProps<TDate>) => JSX.Element;
export default PickersCalendarHeader;
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import * as React from 'react';
import clsx from 'clsx';
import Typography from '@material-ui/core/Typography';
import { MuiStyles, StyleRules, WithStyles, withStyles, useTheme } from '@material-ui/core/styles';
import { useTheme, experimentalStyled as styled } from '@material-ui/core/styles';
import IconButton from '@material-ui/core/IconButton';
import ArrowLeftIcon from '../svg-icons/ArrowLeft';
import ArrowRightIcon from '../svg-icons/ArrowRight';
Expand Down Expand Up @@ -45,29 +44,27 @@ interface ArrowSwitcherProps extends ExportedArrowSwitcherProps, React.HTMLProps
onLeftClick: () => void;
onRightClick: () => void;
}
export type PickersArrowSwitcherClassKey = 'root' | 'spacer' | 'hidden';

export const styles: MuiStyles<PickersArrowSwitcherClassKey> = (
theme,
): StyleRules<PickersArrowSwitcherClassKey> => ({
root: {
display: 'flex',
},
spacer: {
width: theme.spacing(3),
},
hidden: {
visibility: 'hidden',
},
const PickersArrowSwitcherRoot = styled('div', { skipSx: true })({
display: 'flex',
});

const PickersArrowSwitcherSpacer = styled('div', { skipSx: true })(({ theme }) => ({
width: theme.spacing(3),
}));

const PickersArrowSwitcherButton = styled(IconButton, { skipSx: true })(({ styleProps = {} }) => ({
...(!!styleProps.hidden && {
visibility: 'hidden',
}),
}));

const PickersArrowSwitcher = React.forwardRef(function PickersArrowSwitcher(
props: ArrowSwitcherProps & WithStyles<typeof styles>,
props: Omit<ArrowSwitcherProps, 'as'>,
ref: React.Ref<HTMLDivElement>,
) {
const {
children,
classes,
className,
components = {},
componentsProps = {},
Expand All @@ -84,55 +81,54 @@ const PickersArrowSwitcher = React.forwardRef(function PickersArrowSwitcher(
const theme = useTheme();
const isRtl = theme.direction === 'rtl';

const LeftArrowButton = components.LeftArrowButton || IconButton;
const leftArrowButtonProps = componentsProps.leftArrowButton || {};
const LeftArrowIcon = components.LeftArrowIcon || ArrowLeftIcon;

const RightArrowButton = components.RightArrowButton || IconButton;
const rightArrowButtonProps = componentsProps.rightArrowButton || {};
const RightArrowIcon = components.RightArrowIcon || ArrowRightIcon;

// TODO: convert to simple assignment after the type error in defaultPropsHandler.js:60:6 is fixed
const styleProps = { ...props };

return (
<div className={clsx(classes.root, className)} ref={ref} {...other}>
<LeftArrowButton
<PickersArrowSwitcherRoot ref={ref} className={className} styleProps={styleProps} {...other}>
<PickersArrowSwitcherButton
as={components.LeftArrowButton}
size="small"
aria-label={leftArrowButtonText}
title={leftArrowButtonText}
disabled={isLeftDisabled}
edge="end"
onClick={onLeftClick}
{...leftArrowButtonProps}
className={clsx(leftArrowButtonProps.className, {
[classes.hidden]: isLeftHidden,
})}
className={leftArrowButtonProps.className}
styleProps={{ ...styleProps, ...leftArrowButtonProps, hidden: isLeftHidden }}
>
{isRtl ? <RightArrowIcon /> : <LeftArrowIcon />}
</LeftArrowButton>
</PickersArrowSwitcherButton>
{children ? (
<Typography variant="subtitle1" component="span">
{children}
</Typography>
) : (
<div className={classes.spacer} />
<PickersArrowSwitcherSpacer styleProps={styleProps} />
)}
<RightArrowButton
<PickersArrowSwitcherButton
as={components.RightArrowButton}
size="small"
aria-label={rightArrowButtonText}
title={rightArrowButtonText}
edge="start"
disabled={isRightDisabled}
onClick={onRightClick}
{...rightArrowButtonProps}
className={clsx(rightArrowButtonProps.className, {
[classes.hidden]: isRightHidden,
})}
className={rightArrowButtonProps.className}
styleProps={{ ...styleProps, ...rightArrowButtonProps, hidden: isRightHidden }}
>
{isRtl ? <LeftArrowIcon /> : <RightArrowIcon />}
</RightArrowButton>
</div>
</PickersArrowSwitcherButton>
</PickersArrowSwitcherRoot>
);
});

export default React.memo(
withStyles(styles, { name: 'PrivatePickersArrowSwitcher' })(PickersArrowSwitcher),
);
export default PickersArrowSwitcher;

0 comments on commit 12a017d

Please sign in to comment.