Skip to content
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

[pickers] Migrate Clock to emotion #26278

Merged
merged 3 commits into from
May 16, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
197 changes: 105 additions & 92 deletions packages/material-ui-lab/src/ClockPicker/Clock.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import IconButton from '@material-ui/core/IconButton';
import Typography from '@material-ui/core/Typography';
import { MuiStyles, StyleRules, WithStyles, withStyles } from '@material-ui/core/styles';
import { experimentalStyled as styled } from '@material-ui/core/styles';
import ClockPointer from './ClockPointer';
import { useUtils, MuiPickersAdapter } from '../internal/pickers/hooks/useUtils';
import { useGlobalKeyDown, keycode } from '../internal/pickers/hooks/useKeyDown';
Expand All @@ -29,89 +27,113 @@ export interface ClockProps<TDate> extends ReturnType<typeof useMeridiemMode> {
value: number;
}

export type ClockClassKey =
| 'root'
| 'clock'
| 'squareMask'
| 'pin'
| 'amButton'
| 'pmButton'
| 'meridiemButtonSelected';
const ClockRoot = styled(
'div',
{},
{ skipSx: true },
)(({ theme }) => ({
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
margin: theme.spacing(2),
}));

export const styles: MuiStyles<ClockClassKey> = (theme): StyleRules<ClockClassKey> => ({
root: {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
margin: theme.spacing(2),
},
clock: {
backgroundColor: 'rgba(0,0,0,.07)',
const ClockClock = styled(
'div',
{},
{ skipSx: true },
)({
backgroundColor: 'rgba(0,0,0,.07)',
borderRadius: '50%',
height: 220,
width: 220,
flexShrink: 0,
position: 'relative',
pointerEvents: 'none',
});

const ClockSquareMask = styled(
'div',
{},
{ skipSx: true },
)({
width: '100%',
height: '100%',
position: 'absolute',
pointerEvents: 'auto',
outline: 0,
// Disable scroll capabilities.
touchAction: 'none',
userSelect: 'none',
'@media (pointer: fine)': {
cursor: 'pointer',
borderRadius: '50%',
height: 220,
width: 220,
flexShrink: 0,
position: 'relative',
pointerEvents: 'none',
},
squareMask: {
width: '100%',
height: '100%',
position: 'absolute',
pointerEvents: 'auto',
outline: 0,
// Disable scroll capabilities.
touchAction: 'none',
userSelect: 'none',
'@media (pointer: fine)': {
cursor: 'pointer',
borderRadius: '50%',
},
'&:active': {
cursor: 'move',
},
'&:active': {
cursor: 'move',
},
pin: {
width: 6,
height: 6,
borderRadius: '50%',
});

const ClockPin = styled(
'div',
{},
{ skipSx: true },
)(({ theme }) => ({
width: 6,
height: 6,
borderRadius: '50%',
backgroundColor: theme.palette.primary.main,
position: 'absolute',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
}));

const ClockAmButton = styled(
IconButton,
{},
{ skipSx: true },
)(({ theme, styleProps = {} }) => ({
zIndex: 1,
position: 'absolute',
bottom: 8,
left: 8,
...(styleProps.meridiemMode === 'am' && {
backgroundColor: theme.palette.primary.main,
position: 'absolute',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
},
amButton: {
zIndex: 1,
left: 8,
position: 'absolute',
bottom: 8,
},
pmButton: {
zIndex: 1,
position: 'absolute',
bottom: 8,
right: 8,
},
meridiemButtonSelected: {
color: theme.palette.primary.contrastText,
'&:hover': {
backgroundColor: theme.palette.primary.light,
},
}),
}));

const ClockPmButton = styled(
IconButton,
{},
{ skipSx: true },
)(({ theme, styleProps = {} }) => ({
zIndex: 1,
position: 'absolute',
bottom: 8,
right: 8,
...(styleProps.meridiemMode === 'pm' && {
backgroundColor: theme.palette.primary.main,
color: theme.palette.primary.contrastText,
'&:hover': {
backgroundColor: theme.palette.primary.light,
},
},
});
}),
}));

/**
* @ignore - internal component.
*/
function Clock<TDate>(props: ClockProps<TDate> & WithStyles<typeof styles>) {
function Clock<TDate>(props: ClockProps<TDate>) {
const {
allowKeyboardControl,
ampm,
ampmInClock,
children: numbersElementsArray,
classes,
date,
getClockLabelText,
handleMeridiemChange,
Expand All @@ -123,6 +145,9 @@ function Clock<TDate>(props: ClockProps<TDate> & WithStyles<typeof styles>) {
value,
} = props;

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

const utils = useUtils<TDate>();
const isStatic = React.useContext(IsStaticVariantContext);
const wrapperVariant = React.useContext(WrapperVariantContext);
Expand Down Expand Up @@ -207,21 +232,20 @@ function Clock<TDate>(props: ClockProps<TDate> & WithStyles<typeof styles>) {
});

return (
<div className={classes.root}>
<div className={classes.clock}>
<div
<ClockRoot>
<ClockClock>
<ClockSquareMask
role="menu"
data-mui-test="clock"
tabIndex={0}
className={classes.squareMask}
onTouchMove={handleTouchMove}
onTouchEnd={handleTouchEnd}
onMouseUp={handleMouseUp}
onMouseMove={handleMouseMove}
/>
{!isSelectedTimeDisabled && (
<React.Fragment>
<div className={classes.pin} />
<ClockPin />
{date && (
<ClockPointer
type={type}
Expand All @@ -235,40 +259,29 @@ function Clock<TDate>(props: ClockProps<TDate> & WithStyles<typeof styles>) {
</React.Fragment>
)}
{numbersElementsArray}
</div>
</ClockClock>
{ampm && (wrapperVariant === 'desktop' || ampmInClock) && (
<React.Fragment>
<IconButton
<ClockAmButton
data-mui-test="in-clock-am-btn"
onClick={() => handleMeridiemChange('am')}
disabled={meridiemMode === null}
className={clsx(classes.amButton, {
[classes.meridiemButtonSelected]: meridiemMode === 'am',
})}
styleProps={styleProps}
>
<Typography variant="caption">AM</Typography>
</IconButton>
<IconButton
</ClockAmButton>
<ClockPmButton
disabled={meridiemMode === null}
data-mui-test="in-clock-pm-btn"
onClick={() => handleMeridiemChange('pm')}
className={clsx(classes.pmButton, {
[classes.meridiemButtonSelected]: meridiemMode === 'pm',
})}
styleProps={styleProps}
>
<Typography variant="caption">PM</Typography>
</IconButton>
</ClockPmButton>
</React.Fragment>
)}
</div>
</ClockRoot>
);
}

Clock.propTypes = {
mnajdova marked this conversation as resolved.
Show resolved Hide resolved
ampm: PropTypes.bool,
minutesStep: PropTypes.number,
} as any;

export default withStyles(styles, {
name: 'MuiInternalClock',
})(Clock) as <TDate>(props: ClockProps<TDate>) => JSX.Element;
export default Clock;