UNPKG

@material-ui/core

Version:

React components that implement Google's Material Design.

391 lines (334 loc) 13.5 kB
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties"; import _extends from "@babel/runtime/helpers/esm/extends"; // A grid component using the following libs as inspiration. // // For the implementation: // - https://getbootstrap.com/docs/4.3/layout/grid/ // - https://github.com/kristoferjoseph/flexboxgrid/blob/master/src/css/flexboxgrid.css // - https://github.com/roylee0704/react-flexbox-grid // - https://material.angularjs.org/latest/layout/introduction // // Follow this flexbox Guide to better understand the underlying model: // - https://css-tricks.com/snippets/css/a-guide-to-flexbox/ import React from 'react'; import PropTypes from 'prop-types'; import clsx from 'clsx'; import withStyles from '../styles/withStyles'; import { keys as breakpointKeys } from '../styles/createBreakpoints'; import requirePropFactory from '../utils/requirePropFactory'; var SPACINGS = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; var GRID_SIZES = ['auto', true, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; function generateGrid(globalStyles, theme, breakpoint) { var styles = {}; GRID_SIZES.forEach(function (size) { var key = "grid-".concat(breakpoint, "-").concat(size); if (size === true) { // For the auto layouting styles[key] = { flexBasis: 0, flexGrow: 1, maxWidth: '100%' }; return; } if (size === 'auto') { styles[key] = { flexBasis: 'auto', flexGrow: 0, maxWidth: 'none' }; return; } // Keep 7 significant numbers. var width = "".concat(Math.round(size / 12 * 10e7) / 10e5, "%"); // Close to the bootstrap implementation: // https://github.com/twbs/bootstrap/blob/8fccaa2439e97ec72a4b7dc42ccc1f649790adb0/scss/mixins/_grid.scss#L41 styles[key] = { flexBasis: width, flexGrow: 0, maxWidth: width }; }); // No need for a media query for the first size. if (breakpoint === 'xs') { _extends(globalStyles, styles); } else { globalStyles[theme.breakpoints.up(breakpoint)] = styles; } } function generateGutter(theme, breakpoint) { var styles = {}; SPACINGS.forEach(function (spacing) { var themeSpacing = theme.spacing(spacing); if (themeSpacing === 0) { return; } styles["spacing-".concat(breakpoint, "-").concat(spacing)] = { margin: -themeSpacing / 2, width: "calc(100% + ".concat(themeSpacing, "px)"), '& > $item': { padding: themeSpacing / 2 } }; }); return styles; } // Default CSS values // flex: '0 1 auto', // flexDirection: 'row', // alignItems: 'flex-start', // flexWrap: 'nowrap', // justifyContent: 'flex-start', export var styles = function styles(theme) { return _extends({ /* Styles applied to the root element */ root: {}, /* Styles applied to the root element if `container={true}`. */ container: { boxSizing: 'border-box', display: 'flex', flexWrap: 'wrap', width: '100%' }, /* Styles applied to the root element if `item={true}`. */ item: { boxSizing: 'border-box', margin: '0' // For instance, it's useful when used with a `figure` element. }, /* Styles applied to the root element if `zeroMinWidth={true}`. */ zeroMinWidth: { minWidth: 0 }, /* Styles applied to the root element if `direction="column"`. */ 'direction-xs-column': { flexDirection: 'column' }, /* Styles applied to the root element if `direction="column-reverse"`. */ 'direction-xs-column-reverse': { flexDirection: 'column-reverse' }, /* Styles applied to the root element if `direction="rwo-reverse"`. */ 'direction-xs-row-reverse': { flexDirection: 'row-reverse' }, /* Styles applied to the root element if `wrap="nowrap"`. */ 'wrap-xs-nowrap': { flexWrap: 'nowrap' }, /* Styles applied to the root element if `wrap="reverse"`. */ 'wrap-xs-wrap-reverse': { flexWrap: 'wrap-reverse' }, /* Styles applied to the root element if `alignItems="center"`. */ 'align-items-xs-center': { alignItems: 'center' }, /* Styles applied to the root element if `alignItems="flex-start"`. */ 'align-items-xs-flex-start': { alignItems: 'flex-start' }, /* Styles applied to the root element if `alignItems="flex-end"`. */ 'align-items-xs-flex-end': { alignItems: 'flex-end' }, /* Styles applied to the root element if `alignItems="baseline"`. */ 'align-items-xs-baseline': { alignItems: 'baseline' }, /* Styles applied to the root element if `alignContent="center"`. */ 'align-content-xs-center': { alignContent: 'center' }, /* Styles applied to the root element if `alignContent="flex-start"`. */ 'align-content-xs-flex-start': { alignContent: 'flex-start' }, /* Styles applied to the root element if `alignContent="flex-end"`. */ 'align-content-xs-flex-end': { alignContent: 'flex-end' }, /* Styles applied to the root element if `alignContent="space-between"`. */ 'align-content-xs-space-between': { alignContent: 'space-between' }, /* Styles applied to the root element if `alignContent="space-around"`. */ 'align-content-xs-space-around': { alignContent: 'space-around' }, /* Styles applied to the root element if `justify="center"`. */ 'justify-xs-center': { justifyContent: 'center' }, /* Styles applied to the root element if `justify="flex-end"`. */ 'justify-xs-flex-end': { justifyContent: 'flex-end' }, /* Styles applied to the root element if `justify="space-between"`. */ 'justify-xs-space-between': { justifyContent: 'space-between' }, /* Styles applied to the root element if `justify="space-around"`. */ 'justify-xs-space-around': { justifyContent: 'space-around' }, /* Styles applied to the root element if `justify="space-evenly"`. */ 'justify-xs-space-evenly': { justifyContent: 'space-evenly' } }, generateGutter(theme, 'xs'), {}, breakpointKeys.reduce(function (accumulator, key) { // Use side effect over immutability for better performance. generateGrid(accumulator, theme, key); return accumulator; }, {})); }; var Grid = React.forwardRef(function (props, ref) { var _props$alignContent = props.alignContent, alignContent = _props$alignContent === void 0 ? 'stretch' : _props$alignContent, _props$alignItems = props.alignItems, alignItems = _props$alignItems === void 0 ? 'stretch' : _props$alignItems, classes = props.classes, classNameProp = props.className, _props$component = props.component, Component = _props$component === void 0 ? 'div' : _props$component, _props$container = props.container, container = _props$container === void 0 ? false : _props$container, _props$direction = props.direction, direction = _props$direction === void 0 ? 'row' : _props$direction, _props$item = props.item, item = _props$item === void 0 ? false : _props$item, _props$justify = props.justify, justify = _props$justify === void 0 ? 'flex-start' : _props$justify, _props$lg = props.lg, lg = _props$lg === void 0 ? false : _props$lg, _props$md = props.md, md = _props$md === void 0 ? false : _props$md, _props$sm = props.sm, sm = _props$sm === void 0 ? false : _props$sm, _props$spacing = props.spacing, spacing = _props$spacing === void 0 ? 0 : _props$spacing, _props$wrap = props.wrap, wrap = _props$wrap === void 0 ? 'wrap' : _props$wrap, _props$xl = props.xl, xl = _props$xl === void 0 ? false : _props$xl, _props$xs = props.xs, xs = _props$xs === void 0 ? false : _props$xs, _props$zeroMinWidth = props.zeroMinWidth, zeroMinWidth = _props$zeroMinWidth === void 0 ? false : _props$zeroMinWidth, other = _objectWithoutProperties(props, ["alignContent", "alignItems", "classes", "className", "component", "container", "direction", "item", "justify", "lg", "md", "sm", "spacing", "wrap", "xl", "xs", "zeroMinWidth"]); var className = clsx(classes.root, classNameProp, container && [classes.container, spacing !== 0 && classes["spacing-xs-".concat(String(spacing))]], item && classes.item, zeroMinWidth && classes.zeroMinWidth, direction !== 'row' && classes["direction-xs-".concat(String(direction))], wrap !== 'wrap' && classes["wrap-xs-".concat(String(wrap))], alignItems !== 'stretch' && classes["align-items-xs-".concat(String(alignItems))], alignContent !== 'stretch' && classes["align-content-xs-".concat(String(alignContent))], justify !== 'flex-start' && classes["justify-xs-".concat(String(justify))], xs !== false && classes["grid-xs-".concat(String(xs))], sm !== false && classes["grid-sm-".concat(String(sm))], md !== false && classes["grid-md-".concat(String(md))], lg !== false && classes["grid-lg-".concat(String(lg))], xl !== false && classes["grid-xl-".concat(String(xl))]); return React.createElement(Component, _extends({ className: className, ref: ref }, other)); }); if (process.env.NODE_ENV !== 'production') { // can't use named function expression since the function body references `Grid` // which would point to the render function instead of the actual component Grid.displayName = 'ForwardRef(Grid)'; } process.env.NODE_ENV !== "production" ? Grid.propTypes = { /** * Defines the `align-content` style property. * It's applied for all screen sizes. */ alignContent: PropTypes.oneOf(['stretch', 'center', 'flex-start', 'flex-end', 'space-between', 'space-around']), /** * Defines the `align-items` style property. * It's applied for all screen sizes. */ alignItems: PropTypes.oneOf(['flex-start', 'center', 'flex-end', 'stretch', 'baseline']), /** * The content of the component. */ children: PropTypes.node, /** * Override or extend the styles applied to the component. * See [CSS API](#css) below for more details. */ classes: PropTypes.object.isRequired, /** * @ignore */ className: PropTypes.string, /** * The component used for the root node. * Either a string to use a DOM element or a component. */ component: PropTypes.elementType, /** * If `true`, the component will have the flex *container* behavior. * You should be wrapping *items* with a *container*. */ container: PropTypes.bool, /** * Defines the `flex-direction` style property. * It is applied for all screen sizes. */ direction: PropTypes.oneOf(['row', 'row-reverse', 'column', 'column-reverse']), /** * If `true`, the component will have the flex *item* behavior. * You should be wrapping *items* with a *container*. */ item: PropTypes.bool, /** * Defines the `justify-content` style property. * It is applied for all screen sizes. */ justify: PropTypes.oneOf(['flex-start', 'center', 'flex-end', 'space-between', 'space-around', 'space-evenly']), /** * Defines the number of grids the component is going to use. * It's applied for the `lg` breakpoint and wider screens if not overridden. */ lg: PropTypes.oneOf([false, 'auto', true, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]), /** * Defines the number of grids the component is going to use. * It's applied for the `md` breakpoint and wider screens if not overridden. */ md: PropTypes.oneOf([false, 'auto', true, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]), /** * Defines the number of grids the component is going to use. * It's applied for the `sm` breakpoint and wider screens if not overridden. */ sm: PropTypes.oneOf([false, 'auto', true, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]), /** * Defines the space between the type `item` component. * It can only be used on a type `container` component. */ spacing: PropTypes.oneOf(SPACINGS), /** * Defines the `flex-wrap` style property. * It's applied for all screen sizes. */ wrap: PropTypes.oneOf(['nowrap', 'wrap', 'wrap-reverse']), /** * Defines the number of grids the component is going to use. * It's applied for the `xl` breakpoint and wider screens. */ xl: PropTypes.oneOf([false, 'auto', true, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]), /** * Defines the number of grids the component is going to use. * It's applied for all the screen sizes with the lowest priority. */ xs: PropTypes.oneOf([false, 'auto', true, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]), /** * If `true`, it sets `min-width: 0` on the item. * Refer to the limitations section of the documentation to better understand the use case. */ zeroMinWidth: PropTypes.bool } : void 0; var StyledGrid = withStyles(styles, { name: 'MuiGrid' })(Grid); if (process.env.NODE_ENV !== 'production') { var requireProp = requirePropFactory('Grid'); StyledGrid.propTypes = _extends({}, StyledGrid.propTypes, { alignContent: requireProp('container'), alignItems: requireProp('container'), direction: requireProp('container'), justify: requireProp('container'), lg: requireProp('item'), md: requireProp('item'), sm: requireProp('item'), spacing: requireProp('container'), wrap: requireProp('container'), xs: requireProp('item'), zeroMinWidth: requireProp('item') }); } export default StyledGrid;