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 MonthPicker to emotion #26025

Merged
merged 10 commits into from
May 11, 2021
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
99 changes: 82 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,69 @@ 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;
const styleProps = { ...props };
mnajdova marked this conversation as resolved.
Show resolved Hide resolved
const classes = useUtilityClasses(styleProps);

const utils = useUtils<TDate>();
const now = useNow<TDate>();
Expand Down Expand Up @@ -79,7 +135,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 +157,7 @@ const MonthPicker = React.forwardRef(function MonthPicker<TDate>(
</PickersMonth>
);
})}
</div>
</MonthPickerRoot>
);
});

Expand All @@ -106,11 +167,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 +202,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 +218,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>;