Last active
December 3, 2018 16:37
-
-
Save rosskevin/e8a93feb03e2d73eabd307b9bc5fd0c7 to your computer and use it in GitHub Desktop.
Responsive material-ui dialog
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { ExtendMui } from '@alienfast/ui/styles' | |
import { default as MuiDialog, DialogProps as MuiDialogProps } from '@material-ui/core/Dialog' | |
import { createStyles, Theme, withStyles, WithStyles } from '@material-ui/core/styles' | |
import { keys } from '@material-ui/core/styles/createBreakpoints' | |
import { Breakpoint } from '@material-ui/core/styles/createBreakpoints' | |
import withMobileDialog from '@material-ui/core/withMobileDialog' | |
import { isWidthUp } from '@material-ui/core/withWidth' | |
import * as React from 'react' | |
const MobileResponsiveDialog = withMobileDialog<MuiDialogProps>({ breakpoint: 'xs' })(MuiDialog) | |
/** | |
* Find all breakpoints from reference and up (inclusive) | |
*/ | |
function breakpointsGreaterThanOrEqual(reference: Breakpoint) { | |
const result: Breakpoint[] = [] | |
for (const breakpoint of keys) { | |
if (isWidthUp(reference, breakpoint)) { | |
result.push(breakpoint) | |
} | |
} | |
return result | |
} | |
// @media (min-width:0px) { | |
// .ui-Dialog-xs { | |
// min-width: 0; | |
// } | |
// .ui-Dialog-sm { | |
// min-width: 0; | |
// } | |
// .ui-Dialog-md { | |
// min-width: 0; | |
// } | |
// .ui-Dialog-lg { | |
// min-width: 0; | |
// } | |
// .ui-Dialog-xl { | |
// min-width: 0; | |
// } | |
// } | |
// @media (min-width:600px) { | |
// .ui-Dialog-sm { | |
// min-width: 600px; | |
// } | |
// .ui-Dialog-md { | |
// min-width: 600px; | |
// } | |
// .ui-Dialog-lg { | |
// min-width: 600px; | |
// } | |
// .ui-Dialog-xl { | |
// min-width: 600px; | |
// } | |
// } | |
// @media (min-width:960px) { | |
// .ui-Dialog-md { | |
// min-width: 960px; | |
// } | |
// .ui-Dialog-lg { | |
// min-width: 960px; | |
// } | |
// .ui-Dialog-xl { | |
// min-width: 960px; | |
// } | |
// } | |
// @media (min-width:1280px) { | |
// .ui-Dialog-lg { | |
// min-width: 1280px; | |
// } | |
// .ui-Dialog-xl { | |
// min-width: 1280px; | |
// } | |
// } | |
// @media (min-width:1920px) { | |
// .ui-Dialog-xl { | |
// min-width: 1920px; | |
// } | |
// } | |
const styles = (theme: Theme) => { | |
const sheet = {} | |
const { breakpoints } = theme | |
for (const breakpoint of keys) { | |
const responsiveBreakpoints = breakpointsGreaterThanOrEqual(breakpoint) | |
const pointStyles = {} | |
for (const responsiveBreakpoint of responsiveBreakpoints) { | |
pointStyles[responsiveBreakpoint] = { | |
minWidth: breakpoints.width(breakpoint), | |
} | |
} | |
// would be shorter but doesn't work, generated class name not substituted | |
// pointStyles[responsiveBreakpoints.join(',')] = { | |
// minWidth: breakpoints.width(breakpoint), | |
// } | |
sheet[breakpoints.up(breakpoint)] = pointStyles | |
} | |
return createStyles(sheet) | |
} | |
export interface DialogProps extends ExtendMui<MuiDialogProps> { | |
/** | |
* Enforce a minimum width (to prevent dialogs from looking too thin) as long as screen size allows for such width. | |
* | minWidth | screenWidth | dialogWidth | |
* | -------- | ----------- | ------------------------------------------------- | |
* | lg | sm | sm or larger | |
* | lg | lg | lg or larger | |
* | lg | xl | lg or larger | |
* | sm | lg | sm or larger | |
* | >= sm | xs | mobile full screen | |
* | xs | any | disable mobile full screen and be xs or larger | |
* | |
* All of this is subject to content. If the content is larger, it will allow the content to grow | |
* up to the given (defaulted lg) maxWidth. | |
*/ | |
minWidth?: Breakpoint | |
} | |
export interface Props extends DialogProps, WithStyles<typeof styles> {} | |
const Dialog = withStyles(styles, { name: 'ui-Dialog' })((props: Props) => { | |
const { | |
minWidth = 'sm', // other than mobile (which will be full screen), default a minimum size | |
classes, | |
maxWidth = 'lg', // allow it to grow as big as you want | |
scroll = 'paper', | |
...rest | |
} = props | |
const { xs, sm, md, lg, xl, ...restClasses } = classes as any // avoid unnecessary stubbing of classes types | |
const modifiedClasses = { | |
...restClasses, | |
paper: classes[minWidth], | |
} | |
if (minWidth === 'xs') { | |
return <MuiDialog maxWidth={maxWidth} {...rest} classes={modifiedClasses} scroll={scroll} /> | |
} | |
return ( | |
<MobileResponsiveDialog | |
maxWidth={maxWidth} | |
{...rest} | |
classes={modifiedClasses} | |
scroll={scroll} | |
/> | |
) | |
}) | |
export default Dialog |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment