UNPKG

20.9 kBJavaScriptView Raw
1"use strict";
2'use client';
3
4// A grid component using the following libs as inspiration.
5//
6// For the implementation:
7// - https://getbootstrap.com/docs/4.3/layout/grid/
8// - https://github.com/kristoferjoseph/flexboxgrid/blob/master/src/css/flexboxgrid.css
9// - https://github.com/roylee0704/react-flexbox-grid
10// - https://material.angularjs.org/latest/layout/introduction
11//
12// Follow this flexbox Guide to better understand the underlying model:
13// - https://css-tricks.com/snippets/css/a-guide-to-flexbox/
14var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
15var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
16Object.defineProperty(exports, "__esModule", {
17 value: true
18});
19exports.default = void 0;
20exports.generateColumnGap = generateColumnGap;
21exports.generateDirection = generateDirection;
22exports.generateGrid = generateGrid;
23exports.generateRowGap = generateRowGap;
24exports.resolveSpacingClasses = resolveSpacingClasses;
25exports.resolveSpacingStyles = resolveSpacingStyles;
26var React = _interopRequireWildcard(require("react"));
27var _propTypes = _interopRequireDefault(require("prop-types"));
28var _clsx = _interopRequireDefault(require("clsx"));
29var _system = require("@mui/system");
30var _styleFunctionSx = require("@mui/system/styleFunctionSx");
31var _composeClasses = _interopRequireDefault(require("@mui/utils/composeClasses"));
32var _requirePropFactory = _interopRequireDefault(require("../utils/requirePropFactory"));
33var _styled = _interopRequireDefault(require("../styles/styled"));
34var _DefaultPropsProvider = require("../DefaultPropsProvider");
35var _useTheme = _interopRequireDefault(require("../styles/useTheme"));
36var _GridContext = _interopRequireDefault(require("./GridContext"));
37var _gridClasses = _interopRequireWildcard(require("./gridClasses"));
38var _jsxRuntime = require("react/jsx-runtime");
39function generateGrid({
40 theme,
41 ownerState
42}) {
43 let size;
44 return theme.breakpoints.keys.reduce((globalStyles, breakpoint) => {
45 // Use side effect over immutability for better performance.
46 let styles = {};
47 if (ownerState[breakpoint]) {
48 size = ownerState[breakpoint];
49 }
50 if (!size) {
51 return globalStyles;
52 }
53 if (size === true) {
54 // For the auto layouting
55 styles = {
56 flexBasis: 0,
57 flexGrow: 1,
58 maxWidth: '100%'
59 };
60 } else if (size === 'auto') {
61 styles = {
62 flexBasis: 'auto',
63 flexGrow: 0,
64 flexShrink: 0,
65 maxWidth: 'none',
66 width: 'auto'
67 };
68 } else {
69 const columnsBreakpointValues = (0, _system.unstable_resolveBreakpointValues)({
70 values: ownerState.columns,
71 breakpoints: theme.breakpoints.values
72 });
73 const columnValue = typeof columnsBreakpointValues === 'object' ? columnsBreakpointValues[breakpoint] : columnsBreakpointValues;
74 if (columnValue === undefined || columnValue === null) {
75 return globalStyles;
76 }
77 // Keep 7 significant numbers.
78 const width = `${Math.round(size / columnValue * 10e7) / 10e5}%`;
79 let more = {};
80 if (ownerState.container && ownerState.item && ownerState.columnSpacing !== 0) {
81 const themeSpacing = theme.spacing(ownerState.columnSpacing);
82 if (themeSpacing !== '0px') {
83 const fullWidth = `calc(${width} + ${themeSpacing})`;
84 more = {
85 flexBasis: fullWidth,
86 maxWidth: fullWidth
87 };
88 }
89 }
90
91 // Close to the bootstrap implementation:
92 // https://github.com/twbs/bootstrap/blob/8fccaa2439e97ec72a4b7dc42ccc1f649790adb0/scss/mixins/_grid.scss#L41
93 styles = {
94 flexBasis: width,
95 flexGrow: 0,
96 maxWidth: width,
97 ...more
98 };
99 }
100
101 // No need for a media query for the first size.
102 if (theme.breakpoints.values[breakpoint] === 0) {
103 Object.assign(globalStyles, styles);
104 } else {
105 globalStyles[theme.breakpoints.up(breakpoint)] = styles;
106 }
107 return globalStyles;
108 }, {});
109}
110function generateDirection({
111 theme,
112 ownerState
113}) {
114 const directionValues = (0, _system.unstable_resolveBreakpointValues)({
115 values: ownerState.direction,
116 breakpoints: theme.breakpoints.values
117 });
118 return (0, _system.handleBreakpoints)({
119 theme
120 }, directionValues, propValue => {
121 const output = {
122 flexDirection: propValue
123 };
124 if (propValue.startsWith('column')) {
125 output[`& > .${_gridClasses.default.item}`] = {
126 maxWidth: 'none'
127 };
128 }
129 return output;
130 });
131}
132
133/**
134 * Extracts zero value breakpoint keys before a non-zero value breakpoint key.
135 * @example { xs: 0, sm: 0, md: 2, lg: 0, xl: 0 } or [0, 0, 2, 0, 0]
136 * @returns [xs, sm]
137 */
138function extractZeroValueBreakpointKeys({
139 breakpoints,
140 values
141}) {
142 let nonZeroKey = '';
143 Object.keys(values).forEach(key => {
144 if (nonZeroKey !== '') {
145 return;
146 }
147 if (values[key] !== 0) {
148 nonZeroKey = key;
149 }
150 });
151 const sortedBreakpointKeysByValue = Object.keys(breakpoints).sort((a, b) => {
152 return breakpoints[a] - breakpoints[b];
153 });
154 return sortedBreakpointKeysByValue.slice(0, sortedBreakpointKeysByValue.indexOf(nonZeroKey));
155}
156function generateRowGap({
157 theme,
158 ownerState
159}) {
160 const {
161 container,
162 rowSpacing
163 } = ownerState;
164 let styles = {};
165 if (container && rowSpacing !== 0) {
166 const rowSpacingValues = (0, _system.unstable_resolveBreakpointValues)({
167 values: rowSpacing,
168 breakpoints: theme.breakpoints.values
169 });
170 let zeroValueBreakpointKeys;
171 if (typeof rowSpacingValues === 'object') {
172 zeroValueBreakpointKeys = extractZeroValueBreakpointKeys({
173 breakpoints: theme.breakpoints.values,
174 values: rowSpacingValues
175 });
176 }
177 styles = (0, _system.handleBreakpoints)({
178 theme
179 }, rowSpacingValues, (propValue, breakpoint) => {
180 const themeSpacing = theme.spacing(propValue);
181 if (themeSpacing !== '0px') {
182 return {
183 marginTop: theme.spacing(-propValue),
184 [`& > .${_gridClasses.default.item}`]: {
185 paddingTop: themeSpacing
186 }
187 };
188 }
189 if (zeroValueBreakpointKeys?.includes(breakpoint)) {
190 return {};
191 }
192 return {
193 marginTop: 0,
194 [`& > .${_gridClasses.default.item}`]: {
195 paddingTop: 0
196 }
197 };
198 });
199 }
200 return styles;
201}
202function generateColumnGap({
203 theme,
204 ownerState
205}) {
206 const {
207 container,
208 columnSpacing
209 } = ownerState;
210 let styles = {};
211 if (container && columnSpacing !== 0) {
212 const columnSpacingValues = (0, _system.unstable_resolveBreakpointValues)({
213 values: columnSpacing,
214 breakpoints: theme.breakpoints.values
215 });
216 let zeroValueBreakpointKeys;
217 if (typeof columnSpacingValues === 'object') {
218 zeroValueBreakpointKeys = extractZeroValueBreakpointKeys({
219 breakpoints: theme.breakpoints.values,
220 values: columnSpacingValues
221 });
222 }
223 styles = (0, _system.handleBreakpoints)({
224 theme
225 }, columnSpacingValues, (propValue, breakpoint) => {
226 const themeSpacing = theme.spacing(propValue);
227 if (themeSpacing !== '0px') {
228 const negativeValue = theme.spacing(-propValue);
229 return {
230 width: `calc(100% + ${themeSpacing})`,
231 marginLeft: negativeValue,
232 [`& > .${_gridClasses.default.item}`]: {
233 paddingLeft: themeSpacing
234 }
235 };
236 }
237 if (zeroValueBreakpointKeys?.includes(breakpoint)) {
238 return {};
239 }
240 return {
241 width: '100%',
242 marginLeft: 0,
243 [`& > .${_gridClasses.default.item}`]: {
244 paddingLeft: 0
245 }
246 };
247 });
248 }
249 return styles;
250}
251function resolveSpacingStyles(spacing, breakpoints, styles = {}) {
252 // undefined/null or `spacing` <= 0
253 if (!spacing || spacing <= 0) {
254 return [];
255 }
256 // in case of string/number `spacing`
257 if (typeof spacing === 'string' && !Number.isNaN(Number(spacing)) || typeof spacing === 'number') {
258 return [styles[`spacing-xs-${String(spacing)}`]];
259 }
260 // in case of object `spacing`
261 const spacingStyles = [];
262 breakpoints.forEach(breakpoint => {
263 const value = spacing[breakpoint];
264 if (Number(value) > 0) {
265 spacingStyles.push(styles[`spacing-${breakpoint}-${String(value)}`]);
266 }
267 });
268 return spacingStyles;
269}
270
271// Default CSS values
272// flex: '0 1 auto',
273// flexDirection: 'row',
274// alignItems: 'flex-start',
275// flexWrap: 'nowrap',
276// justifyContent: 'flex-start',
277const GridRoot = (0, _styled.default)('div', {
278 name: 'MuiGrid',
279 slot: 'Root',
280 overridesResolver: (props, styles) => {
281 const {
282 ownerState
283 } = props;
284 const {
285 container,
286 direction,
287 item,
288 spacing,
289 wrap,
290 zeroMinWidth,
291 breakpoints
292 } = ownerState;
293 let spacingStyles = [];
294
295 // in case of grid item
296 if (container) {
297 spacingStyles = resolveSpacingStyles(spacing, breakpoints, styles);
298 }
299 const breakpointsStyles = [];
300 breakpoints.forEach(breakpoint => {
301 const value = ownerState[breakpoint];
302 if (value) {
303 breakpointsStyles.push(styles[`grid-${breakpoint}-${String(value)}`]);
304 }
305 });
306 return [styles.root, container && styles.container, item && styles.item, zeroMinWidth && styles.zeroMinWidth, ...spacingStyles, direction !== 'row' && styles[`direction-xs-${String(direction)}`], wrap !== 'wrap' && styles[`wrap-xs-${String(wrap)}`], ...breakpointsStyles];
307 }
308})(
309// FIXME(romgrk): Can't use memoTheme here
310({
311 ownerState
312}) => ({
313 boxSizing: 'border-box',
314 ...(ownerState.container && {
315 display: 'flex',
316 flexWrap: 'wrap',
317 width: '100%'
318 }),
319 ...(ownerState.item && {
320 margin: 0 // For instance, it's useful when used with a `figure` element.
321 }),
322 ...(ownerState.zeroMinWidth && {
323 minWidth: 0
324 }),
325 ...(ownerState.wrap !== 'wrap' && {
326 flexWrap: ownerState.wrap
327 })
328}), generateDirection, generateRowGap, generateColumnGap, generateGrid);
329function resolveSpacingClasses(spacing, breakpoints) {
330 // undefined/null or `spacing` <= 0
331 if (!spacing || spacing <= 0) {
332 return [];
333 }
334 // in case of string/number `spacing`
335 if (typeof spacing === 'string' && !Number.isNaN(Number(spacing)) || typeof spacing === 'number') {
336 return [`spacing-xs-${String(spacing)}`];
337 }
338 // in case of object `spacing`
339 const classes = [];
340 breakpoints.forEach(breakpoint => {
341 const value = spacing[breakpoint];
342 if (Number(value) > 0) {
343 const className = `spacing-${breakpoint}-${String(value)}`;
344 classes.push(className);
345 }
346 });
347 return classes;
348}
349const useUtilityClasses = ownerState => {
350 const {
351 classes,
352 container,
353 direction,
354 item,
355 spacing,
356 wrap,
357 zeroMinWidth,
358 breakpoints
359 } = ownerState;
360 let spacingClasses = [];
361
362 // in case of grid item
363 if (container) {
364 spacingClasses = resolveSpacingClasses(spacing, breakpoints);
365 }
366 const breakpointsClasses = [];
367 breakpoints.forEach(breakpoint => {
368 const value = ownerState[breakpoint];
369 if (value) {
370 breakpointsClasses.push(`grid-${breakpoint}-${String(value)}`);
371 }
372 });
373 const slots = {
374 root: ['root', container && 'container', item && 'item', zeroMinWidth && 'zeroMinWidth', ...spacingClasses, direction !== 'row' && `direction-xs-${String(direction)}`, wrap !== 'wrap' && `wrap-xs-${String(wrap)}`, ...breakpointsClasses]
375 };
376 return (0, _composeClasses.default)(slots, _gridClasses.getGridUtilityClass, classes);
377};
378
379/**
380 * @deprecated Use the [`Grid2`](https://mui.com/material-ui/react-grid2/) component instead.
381 */
382const Grid = /*#__PURE__*/React.forwardRef(function Grid(inProps, ref) {
383 const themeProps = (0, _DefaultPropsProvider.useDefaultProps)({
384 props: inProps,
385 name: 'MuiGrid'
386 });
387 const {
388 breakpoints
389 } = (0, _useTheme.default)();
390 const props = (0, _styleFunctionSx.extendSxProp)(themeProps);
391 const {
392 className,
393 columns: columnsProp,
394 columnSpacing: columnSpacingProp,
395 component = 'div',
396 container = false,
397 direction = 'row',
398 item = false,
399 rowSpacing: rowSpacingProp,
400 spacing = 0,
401 wrap = 'wrap',
402 zeroMinWidth = false,
403 ...other
404 } = props;
405 const rowSpacing = rowSpacingProp || spacing;
406 const columnSpacing = columnSpacingProp || spacing;
407 const columnsContext = React.useContext(_GridContext.default);
408
409 // columns set with default breakpoint unit of 12
410 const columns = container ? columnsProp || 12 : columnsContext;
411 const breakpointsValues = {};
412 const otherFiltered = {
413 ...other
414 };
415 breakpoints.keys.forEach(breakpoint => {
416 if (other[breakpoint] != null) {
417 breakpointsValues[breakpoint] = other[breakpoint];
418 delete otherFiltered[breakpoint];
419 }
420 });
421 const ownerState = {
422 ...props,
423 columns,
424 container,
425 direction,
426 item,
427 rowSpacing,
428 columnSpacing,
429 wrap,
430 zeroMinWidth,
431 spacing,
432 ...breakpointsValues,
433 breakpoints: breakpoints.keys
434 };
435 const classes = useUtilityClasses(ownerState);
436 return /*#__PURE__*/(0, _jsxRuntime.jsx)(_GridContext.default.Provider, {
437 value: columns,
438 children: /*#__PURE__*/(0, _jsxRuntime.jsx)(GridRoot, {
439 ownerState: ownerState,
440 className: (0, _clsx.default)(classes.root, className),
441 as: component,
442 ref: ref,
443 ...otherFiltered
444 })
445 });
446});
447process.env.NODE_ENV !== "production" ? Grid.propTypes /* remove-proptypes */ = {
448 // ┌────────────────────────────── Warning ──────────────────────────────┐
449 // │ These PropTypes are generated from the TypeScript type definitions. │
450 // │ To update them, edit the d.ts file and run `pnpm proptypes`. │
451 // └─────────────────────────────────────────────────────────────────────┘
452 /**
453 * The content of the component.
454 */
455 children: _propTypes.default.node,
456 /**
457 * Override or extend the styles applied to the component.
458 */
459 classes: _propTypes.default.object,
460 /**
461 * @ignore
462 */
463 className: _propTypes.default.string,
464 /**
465 * The number of columns.
466 * @default 12
467 */
468 columns: _propTypes.default.oneOfType([_propTypes.default.arrayOf(_propTypes.default.number), _propTypes.default.number, _propTypes.default.object]),
469 /**
470 * Defines the horizontal space between the type `item` components.
471 * It overrides the value of the `spacing` prop.
472 */
473 columnSpacing: _propTypes.default.oneOfType([_propTypes.default.arrayOf(_propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.string])), _propTypes.default.number, _propTypes.default.object, _propTypes.default.string]),
474 /**
475 * The component used for the root node.
476 * Either a string to use a HTML element or a component.
477 */
478 component: _propTypes.default.elementType,
479 /**
480 * If `true`, the component will have the flex *container* behavior.
481 * You should be wrapping *items* with a *container*.
482 * @default false
483 */
484 container: _propTypes.default.bool,
485 /**
486 * Defines the `flex-direction` style property.
487 * It is applied for all screen sizes.
488 * @default 'row'
489 */
490 direction: _propTypes.default.oneOfType([_propTypes.default.oneOf(['column-reverse', 'column', 'row-reverse', 'row']), _propTypes.default.arrayOf(_propTypes.default.oneOf(['column-reverse', 'column', 'row-reverse', 'row'])), _propTypes.default.object]),
491 /**
492 * If `true`, the component will have the flex *item* behavior.
493 * You should be wrapping *items* with a *container*.
494 * @default false
495 */
496 item: _propTypes.default.bool,
497 /**
498 * If a number, it sets the number of columns the grid item uses.
499 * It can't be greater than the total number of columns of the container (12 by default).
500 * If 'auto', the grid item's width matches its content.
501 * If false, the prop is ignored.
502 * If true, the grid item's width grows to use the space available in the grid container.
503 * The value is applied for the `lg` breakpoint and wider screens if not overridden.
504 * @default false
505 */
506 lg: _propTypes.default.oneOfType([_propTypes.default.oneOf(['auto']), _propTypes.default.number, _propTypes.default.bool]),
507 /**
508 * If a number, it sets the number of columns the grid item uses.
509 * It can't be greater than the total number of columns of the container (12 by default).
510 * If 'auto', the grid item's width matches its content.
511 * If false, the prop is ignored.
512 * If true, the grid item's width grows to use the space available in the grid container.
513 * The value is applied for the `md` breakpoint and wider screens if not overridden.
514 * @default false
515 */
516 md: _propTypes.default.oneOfType([_propTypes.default.oneOf(['auto']), _propTypes.default.number, _propTypes.default.bool]),
517 /**
518 * Defines the vertical space between the type `item` components.
519 * It overrides the value of the `spacing` prop.
520 */
521 rowSpacing: _propTypes.default.oneOfType([_propTypes.default.arrayOf(_propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.string])), _propTypes.default.number, _propTypes.default.object, _propTypes.default.string]),
522 /**
523 * If a number, it sets the number of columns the grid item uses.
524 * It can't be greater than the total number of columns of the container (12 by default).
525 * If 'auto', the grid item's width matches its content.
526 * If false, the prop is ignored.
527 * If true, the grid item's width grows to use the space available in the grid container.
528 * The value is applied for the `sm` breakpoint and wider screens if not overridden.
529 * @default false
530 */
531 sm: _propTypes.default.oneOfType([_propTypes.default.oneOf(['auto']), _propTypes.default.number, _propTypes.default.bool]),
532 /**
533 * Defines the space between the type `item` components.
534 * It can only be used on a type `container` component.
535 * @default 0
536 */
537 spacing: _propTypes.default.oneOfType([_propTypes.default.arrayOf(_propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.string])), _propTypes.default.number, _propTypes.default.object, _propTypes.default.string]),
538 /**
539 * The system prop that allows defining system overrides as well as additional CSS styles.
540 */
541 sx: _propTypes.default.oneOfType([_propTypes.default.arrayOf(_propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.object, _propTypes.default.bool])), _propTypes.default.func, _propTypes.default.object]),
542 /**
543 * Defines the `flex-wrap` style property.
544 * It's applied for all screen sizes.
545 * @default 'wrap'
546 */
547 wrap: _propTypes.default.oneOf(['nowrap', 'wrap-reverse', 'wrap']),
548 /**
549 * If a number, it sets the number of columns the grid item uses.
550 * It can't be greater than the total number of columns of the container (12 by default).
551 * If 'auto', the grid item's width matches its content.
552 * If false, the prop is ignored.
553 * If true, the grid item's width grows to use the space available in the grid container.
554 * The value is applied for the `xl` breakpoint and wider screens if not overridden.
555 * @default false
556 */
557 xl: _propTypes.default.oneOfType([_propTypes.default.oneOf(['auto']), _propTypes.default.number, _propTypes.default.bool]),
558 /**
559 * If a number, it sets the number of columns the grid item uses.
560 * It can't be greater than the total number of columns of the container (12 by default).
561 * If 'auto', the grid item's width matches its content.
562 * If false, the prop is ignored.
563 * If true, the grid item's width grows to use the space available in the grid container.
564 * The value is applied for all the screen sizes with the lowest priority.
565 * @default false
566 */
567 xs: _propTypes.default.oneOfType([_propTypes.default.oneOf(['auto']), _propTypes.default.number, _propTypes.default.bool]),
568 /**
569 * If `true`, it sets `min-width: 0` on the item.
570 * Refer to the limitations section of the documentation to better understand the use case.
571 * @default false
572 */
573 zeroMinWidth: _propTypes.default.bool
574} : void 0;
575if (process.env.NODE_ENV !== 'production') {
576 const requireProp = (0, _requirePropFactory.default)('Grid', Grid);
577 // eslint-disable-next-line no-useless-concat
578 Grid['propTypes' + ''] = {
579 // eslint-disable-next-line react/forbid-foreign-prop-types
580 ...Grid.propTypes,
581 direction: requireProp('container'),
582 lg: requireProp('item'),
583 md: requireProp('item'),
584 sm: requireProp('item'),
585 spacing: requireProp('container'),
586 wrap: requireProp('container'),
587 xs: requireProp('item'),
588 zeroMinWidth: requireProp('item')
589 };
590}
591var _default = exports.default = Grid;
\No newline at end of file