Skip to content

Commit

Permalink
[DatePicker] Migrate YearPicker to emotion (#25928)
Browse files Browse the repository at this point in the history
  • Loading branch information
siriwatknp authored Apr 28, 2021
1 parent 9431d4a commit 0fb3764
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 44 deletions.
2 changes: 1 addition & 1 deletion docs/pages/api-docs/year-picker.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@
"filename": "/packages/material-ui-lab/src/YearPicker/YearPicker.tsx",
"inheritance": null,
"demos": "<ul><li><a href=\"/components/date-picker/\">Date Picker</a></li></ul>",
"styledComponent": false,
"styledComponent": true,
"cssComponent": false
}
2 changes: 1 addition & 1 deletion docs/translations/api-docs/year-picker/year-picker.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
"onYearChange": "Callback firing on year change @DateIOType.",
"shouldDisableYear": "Disable specific years dynamically. Works like <code>shouldDisableDate</code> but for year selection view @DateIOType."
},
"classDescriptions": {}
"classDescriptions": { "root": { "description": "Styles applied to the root element." } }
}
2 changes: 1 addition & 1 deletion packages/material-ui-lab/src/Timeline/Timeline.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
import TimelineContext from './TimelineContext';
import { getTimelineUtilityClass } from './timelineClasses';

export type TimelineClassKey = 'root' | 'alignLeft' | 'alignRight' | 'alignAlternate';
export type TimelineClassKey = keyof NonNullable<TimelineProps['classes']>;

export interface TimelineProps extends StandardProps<React.HTMLAttributes<HTMLUListElement>> {
/**
Expand Down
30 changes: 13 additions & 17 deletions packages/material-ui-lab/src/YearPicker/YearPicker.test.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +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 YearPicker from '@material-ui/lab/YearPicker';
import YearPicker, { yearPickerClasses as classes } from '@material-ui/lab/YearPicker';
import { adapterToUse, createPickerRender } from '../internal/pickers/test-utils';

describe('<YearPicker />', () => {
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(
<YearPicker
minDate={adapterToUse.date('2019-01-01T00:00:00.000')}
maxDate={adapterToUse.date('2029-01-01T00:00:00.000')}
isDateDisabled={() => false}
date={adapterToUse.date()}
onChange={() => {}}
/>,
);
});

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

Expand Down
72 changes: 50 additions & 22 deletions packages/material-ui-lab/src/YearPicker/YearPicker.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import { WithStyles, withStyles, useTheme, MuiStyles } from '@material-ui/core/styles';
import {
useTheme,
experimentalStyled,
unstable_useThemeProps as useThemProps,
} from '@material-ui/core/styles';
import { unstable_composeClasses as composeClasses } from '@material-ui/unstyled';
import clsx from 'clsx';
import PickersYear from './PickersYear';
import { useUtils, useNow } from '../internal/pickers/hooks/useUtils';
import { PickerOnChangeFn } from '../internal/pickers/hooks/useViews';
import { findClosestEnabledDate } from '../internal/pickers/date-utils';
import { PickerSelectionState } from '../internal/pickers/hooks/usePickerState';
import { WrapperVariantContext } from '../internal/pickers/wrappers/WrapperVariantContext';
import { getYearPickerUtilityClass } from './yearPickerClasses';

export interface ExportedYearPickerProps<TDate> {
/**
Expand All @@ -21,9 +27,43 @@ export interface ExportedYearPickerProps<TDate> {
shouldDisableYear?: (day: TDate) => boolean;
}

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

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

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

const YearPickerRoot = experimentalStyled(
'div',
{},
{
name: 'MuiYearPicker',
slot: 'Root',
overridesResolver: (props, styles) => styles.root,
},
)({
display: 'flex',
flexDirection: 'row',
flexWrap: 'wrap',
overflowY: 'auto',
height: '100%',
margin: '0 4px',
});

export type YearPickerClassKey = keyof NonNullable<YearPickerProps<any>['classes']>;

export interface YearPickerProps<TDate> extends ExportedYearPickerProps<TDate> {
allowKeyboardControl?: boolean;
className?: string;
classes?: {
/** Styles applied to the root element. */
root?: string;
};

date: TDate | null;
disableFuture?: boolean | null;
disablePast?: boolean | null;
Expand All @@ -34,26 +74,13 @@ export interface YearPickerProps<TDate> extends ExportedYearPickerProps<TDate> {
onFocusedDayChange?: (day: TDate) => void;
}

export type YearPickerClassKey = 'root';

export const styles: MuiStyles<YearPickerClassKey> = {
root: {
display: 'flex',
flexDirection: 'row',
flexWrap: 'wrap',
overflowY: 'auto',
height: '100%',
margin: '0 4px',
},
};

const YearPicker = React.forwardRef(function YearPicker<TDate>(
props: YearPickerProps<TDate> & WithStyles<typeof styles>,
inProps: YearPickerProps<TDate>,
ref: React.Ref<HTMLDivElement>,
) {
const props = useThemProps({ props: inProps, name: 'MuiYearPicker' });
const {
allowKeyboardControl,
classes,
className,
date,
disableFuture,
Expand All @@ -67,6 +94,9 @@ const YearPicker = React.forwardRef(function YearPicker<TDate>(
shouldDisableYear,
} = props;

const styleProps = { ...props };
const classes = useUtilityClasses(styleProps);

const now = useNow<TDate>();
const theme = useTheme();
const utils = useUtils<TDate>();
Expand Down Expand Up @@ -150,7 +180,7 @@ const YearPicker = React.forwardRef(function YearPicker<TDate>(
};

return (
<div ref={ref} className={clsx(classes.root, className)}>
<YearPickerRoot ref={ref} className={clsx(classes.root, className)} styleProps={styleProps}>
{utils.getYearRange(minDate, maxDate).map((year) => {
const yearNumber = utils.getYear(year);
const selected = yearNumber === currentYear;
Expand All @@ -174,7 +204,7 @@ const YearPicker = React.forwardRef(function YearPicker<TDate>(
</PickersYear>
);
})}
</div>
</YearPickerRoot>
);
});

Expand All @@ -190,7 +220,7 @@ YearPicker.propTypes /* remove-proptypes */ = {
/**
* @ignore
*/
classes: PropTypes.object.isRequired,
classes: PropTypes.object,
/**
* @ignore
*/
Expand Down Expand Up @@ -248,6 +278,4 @@ YearPicker.propTypes /* remove-proptypes */ = {
*
* - [YearPicker API](https://material-ui.com/api/year-picker/)
*/
export default withStyles(styles, { name: 'MuiYearPicker' })(YearPicker) as <TDate>(
props: YearPickerProps<TDate> & React.RefAttributes<HTMLDivElement>,
) => JSX.Element;
export default YearPicker as <TDate>(props: YearPickerProps<TDate>) => JSX.Element;
3 changes: 3 additions & 0 deletions packages/material-ui-lab/src/YearPicker/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@ export { default } from './YearPicker';

export type YearPickerClassKey = import('./YearPicker').YearPickerClassKey;
export type YearPickerProps<TDate> = import('./YearPicker').YearPickerProps<TDate>;

export { default as yearPickerClasses } from './yearPickerClasses';
export * from './yearPickerClasses';
9 changes: 9 additions & 0 deletions packages/material-ui-lab/src/YearPicker/yearPickerClasses.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { generateUtilityClass, generateUtilityClasses } from '@material-ui/unstyled';

export function getYearPickerUtilityClass(slot: string) {
return generateUtilityClass('MuiYearPicker', slot);
}

const yearPickerClasses = generateUtilityClasses('MuiYearPicker', ['root']);

export default yearPickerClasses;
18 changes: 16 additions & 2 deletions packages/material-ui/src/styles/experimentalStyled.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ export interface CreateMUIStyled<Theme extends object = DefaultTheme> {
theme?: Theme;
as?: React.ElementType;
sx?: SxProps<Theme>;
styleProps?: Record<string, unknown>;
},
{},
{
Expand All @@ -182,6 +183,7 @@ export interface CreateMUIStyled<Theme extends object = DefaultTheme> {
theme?: Theme;
as?: React.ElementType;
sx?: SxProps<Theme>;
styleProps?: Record<string, unknown>;
},
{},
{
Expand All @@ -201,6 +203,7 @@ export interface CreateMUIStyled<Theme extends object = DefaultTheme> {
theme?: Theme;
as?: React.ElementType;
sx?: SxProps<Theme>;
styleProps?: Record<string, unknown>;
}
>;

Expand All @@ -213,6 +216,7 @@ export interface CreateMUIStyled<Theme extends object = DefaultTheme> {
theme?: Theme;
as?: React.ElementType;
sx?: SxProps<Theme>;
styleProps?: Record<string, unknown>;
}
>;

Expand All @@ -224,7 +228,12 @@ export interface CreateMUIStyled<Theme extends object = DefaultTheme> {
options: FilteringStyledOptions<JSX.IntrinsicElements[Tag], ForwardedProps>,
muiOptions?: MuiStyledOptions,
): CreateStyledComponent<
{ theme?: Theme; as?: React.ElementType; sx?: SxProps<Theme> },
{
theme?: Theme;
as?: React.ElementType;
sx?: SxProps<Theme>;
styleProps?: Record<string, unknown>;
},
Pick<JSX.IntrinsicElements[Tag], ForwardedProps>
>;

Expand All @@ -233,7 +242,12 @@ export interface CreateMUIStyled<Theme extends object = DefaultTheme> {
options?: StyledOptions,
muiOptions?: MuiStyledOptions,
): CreateStyledComponent<
{ theme?: Theme; as?: React.ElementType; sx?: SxProps<Theme> },
{
theme?: Theme;
as?: React.ElementType;
sx?: SxProps<Theme>;
styleProps?: Record<string, unknown>;
},
JSX.IntrinsicElements[Tag]
>;
}
Expand Down

0 comments on commit 0fb3764

Please sign in to comment.