Skip to content

Commit

Permalink
Add variant="static" (mui#1164)
Browse files Browse the repository at this point in the history
* Add variant="static"

* More variant="static" examples
  • Loading branch information
dmtrKovalenko authored Jul 6, 2019
1 parent 973dc27 commit 15a44a0
Show file tree
Hide file tree
Showing 12 changed files with 101 additions and 15 deletions.
12 changes: 10 additions & 2 deletions docs/_shared/Example.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as React from 'react';
import clsx from 'clsx';
import Code from './Code';
import CodeIcon from '@material-ui/icons/Code';
import CopyIcon from '@material-ui/icons/FileCopy';
Expand All @@ -12,6 +13,7 @@ import { makeStyles, IconButton, Collapse, Tooltip } from '@material-ui/core';

interface Props extends InjectedNotistackProps {
testId: string;
paddingBottom?: boolean;
source: { raw: string; relativePath: string; default: React.FC<any> };
}

Expand Down Expand Up @@ -44,6 +46,9 @@ const useStyles = makeStyles(theme => ({
},
},
},
paddingBottom: {
paddingBottom: 40,
},
sourceToolbar: {
display: 'flex',
},
Expand All @@ -60,7 +65,7 @@ const useStyles = makeStyles(theme => ({
},
}));

function Example({ source, testId, enqueueSnackbar }: Props) {
function Example({ source, testId, paddingBottom, enqueueSnackbar }: Props) {
if (!source.default || !source.raw || !source.relativePath) {
throw new Error(
'Missing component or raw component code, you likely forgot to .example to your example extension'
Expand Down Expand Up @@ -118,7 +123,10 @@ function Example({ source, testId, enqueueSnackbar }: Props) {
</div>
</Collapse>

<div data-test-id={testId} className={classes.pickers}>
<div
data-test-id={testId}
className={clsx(classes.pickers, { [classes.paddingBottom]: paddingBottom })}
>
<Tooltip title="Show/Hide the source">
<IconButton className={classes.sourceBtn} onClick={() => setExpanded(!expanded)}>
<CodeIcon />
Expand Down
3 changes: 2 additions & 1 deletion docs/pages/demo/datepicker/KeyboardDatePicker.example.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ function KeyboardDatePickerExample(props) {
<KeyboardDatePicker
clearable
value={selectedDate}
placeholder="10/10/2018"
onChange={date => handleDateChange(date)}
minDate={new Date()}
format={props.__willBeReplacedGetFormatString({
Expand All @@ -18,7 +19,7 @@ function KeyboardDatePickerExample(props) {
/>

<KeyboardDatePicker
placeholder="10/10/2018"
placeholder="2018/10/10"
value={selectedDate}
onChange={date => handleDateChange(date)}
format={props.__willBeReplacedGetFormatString({
Expand Down
15 changes: 15 additions & 0 deletions docs/pages/demo/datepicker/StaticDatePicker.example.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React, { useState } from 'react';
import { DatePicker } from '@material-ui/pickers';

const StaticDatePicker = () => {
const [date, changeDate] = useState(new Date());

return (
<>
<DatePicker autoOk variant="static" openTo="year" value={date} onChange={changeDate} />
<DatePicker autoOk variant="static" openTo="date" value={date} onChange={changeDate} />
</>
);
};

export default StaticDatePicker;
10 changes: 9 additions & 1 deletion docs/pages/demo/datepicker/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import LinkedComponents from '_shared/LinkedComponents'

import * as CustomDay from './CustomDay.example'
import * as ServerRequest from './ServerRequest.example'
import * as BasicDatePicker from './BasicDatePicker.example'
import * as ViewsDatePicker from './ViewsDatePicker.example'
import * as BasicDatePicker from './BasicDatePicker.example'
import * as StaticDatePicker from './StaticDatePicker.example'
import * as InlineDatePicker from './InlineDatePicker.example'
import * as KeyboardDatePicker from './KeyboardDatePicker.example'

Expand Down Expand Up @@ -45,6 +46,13 @@ Thus you can easily create

<Example source={InlineDatePicker} />

#### Static mode

It is possible to render any picker inline. This will be really helpful to build cutom popover/modal containers.
For that use `variant="static"`.

<Example paddingBottom source={StaticDatePicker} />

#### Customization

The displaying of dates is heavily cusomizable. Thus you can add badges or fully change displaying of day.
Expand Down
15 changes: 15 additions & 0 deletions docs/pages/demo/timepicker/StaticTimePicker.example.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React, { useState } from 'react';
import { TimePicker } from '@material-ui/pickers';

const StaticTimePicker = () => {
const [date, changeDate] = useState(new Date());

return (
<>
<TimePicker autoOk variant="static" openTo="hours" value={date} onChange={changeDate} />
<TimePicker autoOk variant="static" openTo="minutes" value={date} onChange={changeDate} />
</>
);
};

export default StaticTimePicker;
8 changes: 8 additions & 0 deletions docs/pages/demo/timepicker/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import LinkedComponents from '_shared/LinkedComponents'

import * as BasicTimePicker from './BasicTimePicker.example'
import * as InlineTimePicker from './InlineTimePicker.example'
import * as StaticTimePicker from './StaticTimePicker.example'
import * as SecondsTimePicker from './SecondsTimePicker.example'
import * as KeyboardTimePicker from './KeyboardTimePicker.example'

Expand All @@ -31,6 +32,13 @@ A time picker should adjust to a user’s preferred time setting, i.e. the 12-ho

<Example source={InlineTimePicker} />

#### Static mode

It is possible to render any picker inline. This will be really helpful to build cutom popover/modal containers.
For that use `variant="static"`.

<Example paddingBottom source={StaticTimePicker} />

#### Seconds
Seconds input can be used for selection of a precise time point.

Expand Down
2 changes: 1 addition & 1 deletion lib/src/_shared/hooks/usePickerState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export function usePickerState(props: BasePickerProps, options: StateHookOptions
onChange: (newDate: MaterialUiPickersDate, isFinish = true) => {
setPickerDate(newDate);

if (variant === 'inline') {
if (variant === 'inline' || variant === 'static') {
onChange(newDate);
}

Expand Down
3 changes: 3 additions & 0 deletions lib/src/views/Year/YearView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Year from './Year';
import { DateType } from '@date-io/type';
import { makeStyles } from '@material-ui/core/styles';
import { useUtils } from '../../_shared/hooks/useUtils';
import { VariantContext } from '../../wrappers/Wrapper';
import { MaterialUiPickersDate } from '../../typings/date';

export interface YearSelectionProps {
Expand Down Expand Up @@ -38,11 +39,13 @@ export const YearSelection: React.FC<YearSelectionProps> = ({
}) => {
const utils = useUtils();
const classes = useStyles();
const currentVariant = React.useContext(VariantContext);
const selectedYearRef = React.useRef<HTMLElement>(null);

React.useEffect(() => {
if (selectedYearRef.current && selectedYearRef.current.scrollIntoView) {
selectedYearRef.current.scrollIntoView({
block: currentVariant === 'static' ? 'nearest' : 'center',
behavior: animateYearScrolling ? 'smooth' : 'auto',
});
}
Expand Down
2 changes: 0 additions & 2 deletions lib/src/wrappers/InlineWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,5 +78,3 @@ InlineWrapper.propTypes = {
onClose: PropTypes.func,
PopoverProps: PropTypes.object,
} as any;

export default InlineWrapper;
2 changes: 0 additions & 2 deletions lib/src/wrappers/ModalWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,5 +111,3 @@ ModalWrapper.defaultProps = {
clearable: false,
showTodayButton: false,
};

export default ModalWrapper;
22 changes: 22 additions & 0 deletions lib/src/wrappers/StaticWrapper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import * as React from 'react';
import { makeStyles } from '@material-ui/core';
import { DIALOG_WIDTH } from '../constants/dimensions';

const useStyles = makeStyles(
theme => ({
staticWrapperRoot: {
overflow: 'hidden',
width: DIALOG_WIDTH,
display: 'flex',
flexDirection: 'column',
backgroundColor: theme.palette.background.paper,
},
}),
{ name: 'MuiPickersStaticWrapper' }
);

export const StaticWrapper: React.FC = ({ children }) => {
const classes = useStyles();

return <div className={classes.staticWrapperRoot} children={children} />;
};
22 changes: 16 additions & 6 deletions lib/src/wrappers/Wrapper.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import * as React from 'react';
import ModalWrapper, { ModalWrapperProps } from './ModalWrapper';
import InlineWrapper, { InlineWrapperProps } from './InlineWrapper';
import { Omit } from '@material-ui/core';
import { StaticWrapper } from './StaticWrapper';
import { PureDateInputProps } from '../_shared/PureDateInput';
import { ModalWrapper, ModalWrapperProps } from './ModalWrapper';
import { InlineWrapper, InlineWrapperProps } from './InlineWrapper';
import { KeyboardDateInputProps } from '../_shared/KeyboardDateInput';

export type WrapperVariant = 'dialog' | 'inline';
export type WrapperVariant = 'dialog' | 'inline' | 'static';

export interface WrapperProps<T> {
open: boolean;
Expand Down Expand Up @@ -34,18 +35,21 @@ export type ExtendWrapper<TInput extends PureDateInputProps | KeyboardDateInputP
* Displaying variant
* @default 'dialog'
*/
variant?: 'dialog' | 'inline'; // not WrapperVariant for docgen
variant?: WrapperVariant
} & ModalRoot
& InlineRoot
& Omit<TInput, 'inputValue' | 'onChange' | 'format' | 'validationError' | 'format' | 'forwardedRef'>

export function getWrapperFromVariant<T>(
variant?: WrapperVariant
): React.ComponentClass<InlineWrapperProps<T> | ModalWrapperProps<T>> {
): React.ComponentType<InlineWrapperProps<T> | ModalWrapperProps<T>> {
switch (variant) {
case 'inline':
return InlineWrapper as any;

case 'static':
return StaticWrapper as any;

default:
return ModalWrapper as any;
}
Expand All @@ -56,10 +60,16 @@ type Props<T> = {
children?: React.ReactChild;
} & (ModalWrapperProps<T> | InlineWrapperProps<T>);

export const VariantContext = React.createContext<WrapperVariant | null>(null);

export const Wrapper: <T extends KeyboardDateInputProps | PureDateInputProps>(
p: Props<T>
) => React.ReactElement<Props<T>> = ({ variant, ...props }) => {
const Component = getWrapperFromVariant<typeof props.DateInputProps>(variant);

return <Component {...props} />;
return (
<VariantContext.Provider value={variant || 'dialog'}>
<Component {...props} />
</VariantContext.Provider>
);
};

0 comments on commit 15a44a0

Please sign in to comment.