Skip to content

Commit

Permalink
[pickers] Migrate MonthPicker to emotion (#26025)
Browse files Browse the repository at this point in the history
* migrate to emotion

* add sx props

* Inline classes

* styleProps will be needed for the component API

* simplify changes

* revert the change since this is not internal component

* use generic for convention

* run docs:api

* Update packages/material-ui-lab/src/MonthPicker/MonthPicker.tsx

Co-authored-by: eps1lon <silbermann.sebastian@gmail.com>
Co-authored-by: Olivier Tassinari <olivier.tassinari@gmail.com>
Co-authored-by: Marija Najdova <mnajdova@gmail.com>
  • Loading branch information
4 people committed May 11, 2021
1 parent 68ea9e5 commit 2351cfa
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 38 deletions.
7 changes: 5 additions & 2 deletions docs/pages/api-docs/month-picker.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@
"maxDate": { "type": { "name": "any" }, "required": true },
"minDate": { "type": { "name": "any" }, "required": true },
"onChange": { "type": { "name": "func" }, "required": true },
"classes": { "type": { "name": "object" } },
"className": { "type": { "name": "string" } },
"disableFuture": { "type": { "name": "bool" } },
"disablePast": { "type": { "name": "bool" } }
"disablePast": { "type": { "name": "bool" } },
"sx": { "type": { "name": "object" } }
},
"name": "MonthPicker",
"styles": { "classes": ["root"], "globalClasses": {}, "name": "MuiMonthPicker" },
Expand All @@ -14,6 +17,6 @@
"filename": "/packages/material-ui-lab/src/MonthPicker/MonthPicker.tsx",
"inheritance": null,
"demos": "<ul><li><a href=\"/components/date-picker/\">Date Picker</a></li></ul>",
"styledComponent": false,
"styledComponent": true,
"cssComponent": false
}
7 changes: 5 additions & 2 deletions docs/translations/api-docs/month-picker/month-picker.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
{
"componentDescription": "",
"propDescriptions": {
"classes": "Override or extend the styles applied to the component. See <a href=\"#css\">CSS API</a> below for more details.",
"className": "className applied to the root element.",
"date": "Date value for the MonthPicker",
"disableFuture": "If <code>true</code> future days are disabled.",
"disablePast": "If <code>true</code> past days are disabled.",
"maxDate": "Maximal selectable date.",
"minDate": "Minimal selectable date.",
"onChange": "Callback fired on date change."
"onChange": "Callback fired on date change.",
"sx": "The system prop that allows defining system overrides as well as additional CSS styles. See the <a href=\"/system/basics/#the-sx-prop\">`sx` page</a> for more details."
},
"classDescriptions": {}
"classDescriptions": { "root": { "description": "Styles applied to the root element." } }
}
27 changes: 11 additions & 16 deletions packages/material-ui-lab/src/MonthPicker/MonthPicker.test.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,21 @@
import * as React from 'react';
import { spy } from 'sinon';
import { expect } from 'chai';
import { getClasses, createMount, fireEvent, screen, describeConformance } from 'test/utils';
import { createMount, fireEvent, screen, describeConformanceV5 } from 'test/utils';
import LocalizationProvider from '@material-ui/lab/LocalizationProvider';
import AdapterDateFns from '@material-ui/lab/AdapterDateFns';
import MonthPicker from '@material-ui/lab/MonthPicker';
import MonthPicker, { monthPickerClasses as classes } from '@material-ui/lab/MonthPicker';
import { adapterToUse, createPickerRender } from '../internal/pickers/test-utils';

describe('<MonthPicker />', () => {
const mount = createMount();
const render = createPickerRender();
let classes: Record<string, string>;

const localizedMount = (node: React.ReactNode) => {
return mount(<LocalizationProvider dateAdapter={AdapterDateFns}>{node}</LocalizationProvider>);
};

before(() => {
classes = getClasses(
<MonthPicker
minDate={adapterToUse.date('2019-01-01T00:00:00.000')}
maxDate={adapterToUse.date('2029-01-01T00:00:00.000')}
date={adapterToUse.date()}
onChange={() => {}}
/>,
);
});

describeConformance(
describeConformanceV5(
<MonthPicker
minDate={adapterToUse.date('2019-01-01T00:00:00.000')}
maxDate={adapterToUse.date('2029-01-01T00:00:00.000')}
Expand All @@ -39,9 +27,16 @@ describe('<MonthPicker />', () => {
inheritComponent: 'div',
render,
mount: localizedMount,
muiName: 'MuiMonthPicker',
refInstanceof: window.HTMLDivElement,
// cannot test reactTestRenderer because of required context
skip: ['componentProp', 'propsSpread', 'reactTestRenderer'],
skip: [
'componentProp',
'componentsProp',
'propsSpread',
'reactTestRenderer',
'themeVariants',
],
}),
);

Expand Down
100 changes: 83 additions & 17 deletions packages/material-ui-lab/src/MonthPicker/MonthPicker.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,34 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import { MuiStyles, WithStyles, withStyles } from '@material-ui/core/styles';
import clsx from 'clsx';
import { SxProps } from '@material-ui/system';
import {
experimentalStyled,
unstable_useThemeProps as useThemeProps,
Theme,
} from '@material-ui/core/styles';
import {
unstable_composeClasses as composeClasses,
generateUtilityClass,
generateUtilityClasses,
} from '@material-ui/unstyled';
import PickersMonth from './PickersMonth';
import { useUtils, useNow } from '../internal/pickers/hooks/useUtils';
import { PickerOnChangeFn } from '../internal/pickers/hooks/useViews';

export interface MonthPickerProps<TDate> {
/**
* className applied to the root element.
*/
className?: string;
/**
* Override or extend the styles applied to the component.
*/
classes?: {
/** Styles applied to the root element. */
root?: string;
};

/** Date value for the MonthPicker */
date: TDate | null;
/** If `true` past days are disabled. */
Expand All @@ -21,34 +42,70 @@ export interface MonthPickerProps<TDate> {
/** Callback fired on date change. */
onChange: PickerOnChangeFn<TDate>;
onMonthChange?: (date: TDate) => void | Promise<void>;
/**
* The system prop that allows defining system overrides as well as additional CSS styles.
*/
sx?: SxProps<Theme>;
}

export function getMonthPickerUtilityClass(slot: string) {
return generateUtilityClass('MuiMonthPicker', slot);
}

export type MonthPickerClassKey = 'root';
export type MonthPickerClassKey = keyof NonNullable<MonthPickerProps<unknown>['classes']>;

export const styles: MuiStyles<MonthPickerClassKey> = {
root: {
width: 310,
display: 'flex',
flexWrap: 'wrap',
alignContent: 'stretch',
},
export const monthPickerClasses = generateUtilityClasses<MonthPickerClassKey>('MuiMonthPicker', [
'root',
]);

const useUtilityClasses = (styleProps: MonthPickerProps<any>) => {
const { classes } = styleProps;

const slots = {
root: ['root'],
};

return composeClasses(slots, getMonthPickerUtilityClass, classes);
};

const MonthPickerRoot = experimentalStyled(
'div',
{},
{
name: 'MuiMonthPicker',
slot: 'Root',
overridesResolver: (props, styles) => styles.root,
},
)({
width: 310,
display: 'flex',
flexWrap: 'wrap',
alignContent: 'stretch',
});

const MonthPicker = React.forwardRef(function MonthPicker<TDate>(
props: MonthPickerProps<TDate> & WithStyles<typeof styles>,
inProps: MonthPickerProps<TDate>,
ref: React.Ref<HTMLDivElement>,
) {
const props = useThemeProps<Theme, MonthPickerProps<TDate>, 'MuiMonthPicker'>({
props: inProps,
name: 'MuiMonthPicker',
});

const {
className,
classes,
date,
disableFuture,
disablePast,
maxDate,
minDate,
onChange,
onMonthChange,
...other
} = props;
// TODO: convert to simple assignment after the type error in defaultPropsHandler.js:60:6 is fixed
const styleProps = { ...props };
const classes = useUtilityClasses(styleProps);

const utils = useUtils<TDate>();
const now = useNow<TDate>();
Expand Down Expand Up @@ -79,7 +136,12 @@ const MonthPicker = React.forwardRef(function MonthPicker<TDate>(
};

return (
<div ref={ref} className={clsx(classes.root, className)}>
<MonthPickerRoot
ref={ref}
className={clsx(classes.root, className)}
styleProps={styleProps}
{...other}
>
{utils.getMonthArray(date || now).map((month) => {
const monthNumber = utils.getMonth(month);
const monthText = utils.format(month, 'monthShort');
Expand All @@ -96,7 +158,7 @@ const MonthPicker = React.forwardRef(function MonthPicker<TDate>(
</PickersMonth>
);
})}
</div>
</MonthPickerRoot>
);
});

Expand All @@ -106,11 +168,11 @@ MonthPicker.propTypes /* remove-proptypes */ = {
// | To update them edit TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
/**
* @ignore
* Override or extend the styles applied to the component.
*/
classes: PropTypes.object.isRequired,
classes: PropTypes.object,
/**
* @ignore
* className applied to the root element.
*/
className: PropTypes.string,
/**
Expand Down Expand Up @@ -141,6 +203,10 @@ MonthPicker.propTypes /* remove-proptypes */ = {
* @ignore
*/
onMonthChange: PropTypes.func,
/**
* The system prop that allows defining system overrides as well as additional CSS styles.
*/
sx: PropTypes.object,
} as any;

/**
Expand All @@ -153,6 +219,6 @@ MonthPicker.propTypes /* remove-proptypes */ = {
*
* - [MonthPicker API](https://material-ui.com/api/month-picker/)
*/
export default withStyles(styles, { name: 'MuiMonthPicker' })(MonthPicker) as <TDate>(
export default MonthPicker as <TDate>(
props: MonthPickerProps<TDate> & React.RefAttributes<HTMLDivElement>,
) => JSX.Element;
2 changes: 1 addition & 1 deletion packages/material-ui-lab/src/MonthPicker/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export { default } from './MonthPicker';
export { default, getMonthPickerUtilityClass, monthPickerClasses } from './MonthPicker';

export type MonthPickerClassKey = import('./MonthPicker').MonthPickerClassKey;
export type MonthPickerProps<TDate> = import('./MonthPicker').MonthPickerProps<TDate>;

0 comments on commit 2351cfa

Please sign in to comment.