Skip to content

Instantly share code, notes, and snippets.

@rosskevin
Last active December 3, 2018 16:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rosskevin/e8a93feb03e2d73eabd307b9bc5fd0c7 to your computer and use it in GitHub Desktop.
Save rosskevin/e8a93feb03e2d73eabd307b9bc5fd0c7 to your computer and use it in GitHub Desktop.
Responsive material-ui dialog
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