diff --git a/packages/mui-lab/src/Masonry/Masonry.js b/packages/mui-lab/src/Masonry/Masonry.js
index 7a5b83acc46e8d..78c23bf31c44c4 100644
--- a/packages/mui-lab/src/Masonry/Masonry.js
+++ b/packages/mui-lab/src/Masonry/Masonry.js
@@ -22,40 +22,6 @@ const useUtilityClasses = (ownerState) => {
return composeClasses(slots, getMasonryUtilityClass, classes);
};
-// compute base for responsive values; e.g.,
-// [1,2,3] => {xs: true, sm: true, md: true}
-// {xs: 1, sm: 2, md: 3} => {xs: true, sm: true, md: true}
-const computeBreakpointsBase = (breakpoints, prop) => {
- const base = {};
- if (Array.isArray(prop)) {
- Object.keys(breakpoints.values).forEach((breakpoint, i, arr) => {
- if (i < arr.length) {
- base[breakpoint] = true;
- }
- });
- } else {
- Object.keys(breakpoints.values).forEach((breakpoint) => {
- if (prop[breakpoint] != null) {
- base[breakpoint] = true;
- }
- });
- }
- return base;
-};
-
-// if prop is an array, convert to object; e.g.,
-// (base: {xs: true, sm: true, md: true}, prop: [1,2,3]) => {xs: 1, sm: 2, md: 3}
-const validatePropValues = (base, prop) => {
- const values = {};
- if (Array.isArray(prop)) {
- Object.keys(base).forEach((breakpoint, i) => {
- values[breakpoint] = prop[i];
- });
- return values;
- }
- return prop;
-};
-
export const getStyle = ({ ownerState, theme }) => {
let styles = {
width: '100%',
@@ -94,10 +60,9 @@ export const getStyle = ({ ownerState, theme }) => {
};
}
- const spacingBreakpointsBase = computeBreakpointsBase(theme.breakpoints, ownerState.spacing);
const spacingValues = resolveBreakpointValues({
- values: validatePropValues(spacingBreakpointsBase, ownerState.spacing),
- base: spacingBreakpointsBase,
+ values: ownerState.spacing,
+ breakpoints: theme.breakpoints.values,
});
const transformer = createUnarySpacing(theme);
@@ -120,10 +85,9 @@ export const getStyle = ({ ownerState, theme }) => {
handleBreakpoints({ theme }, spacingValues, spacingStyleFromPropValue),
);
- const columnBreakpointsBase = computeBreakpointsBase(theme.breakpoints, ownerState.columns);
const columnValues = resolveBreakpointValues({
- values: validatePropValues(columnBreakpointsBase, ownerState.columns),
- base: columnBreakpointsBase,
+ values: ownerState.columns,
+ breakpoints: theme.breakpoints.values,
});
const columnStyleFromPropValue = (propValue) => {
diff --git a/packages/mui-lab/src/Masonry/Masonry.test.js b/packages/mui-lab/src/Masonry/Masonry.test.js
index 4b1a633edbb846..5f6e3b225a5c4c 100644
--- a/packages/mui-lab/src/Masonry/Masonry.test.js
+++ b/packages/mui-lab/src/Masonry/Masonry.test.js
@@ -213,4 +213,99 @@ describe('', () => {
});
});
});
+
+ describe('prop: columns', () => {
+ it('should generate correct responsive styles regardless of breakpoints order', () => {
+ const columns = { sm: 5, md: 7, xs: 3 };
+ const spacing = 1;
+ expect(
+ getStyle({
+ ownerState: {
+ columns,
+ spacing,
+ maxColumnHeight,
+ },
+ theme,
+ }),
+ ).to.deep.equal({
+ width: '100%',
+ display: 'flex',
+ flexFlow: 'column wrap',
+ alignContent: 'space-between',
+ boxSizing: 'border-box',
+ '& > *': {
+ boxSizing: 'border-box',
+ margin: parseToNumber(theme.spacing(spacing)) / 2,
+ },
+ margin: -(parseToNumber(theme.spacing(spacing)) / 2),
+ height: maxColumnHeight + parseToNumber(theme.spacing(spacing)),
+ [`@media (min-width:${theme.breakpoints.values.xs}px)`]: {
+ '& > *': {
+ width: `calc(${(100 / columns.xs).toFixed(2)}% - ${theme.spacing(spacing)})`,
+ },
+ },
+ [`@media (min-width:${theme.breakpoints.values.sm}px)`]: {
+ '& > *': {
+ width: `calc(${(100 / columns.sm).toFixed(2)}% - ${theme.spacing(spacing)})`,
+ },
+ },
+ [`@media (min-width:${theme.breakpoints.values.md}px)`]: {
+ '& > *': {
+ width: `calc(${(100 / columns.md).toFixed(2)}% - ${theme.spacing(spacing)})`,
+ },
+ },
+ });
+ });
+ });
+
+ describe('prop: spacing', () => {
+ it('should generate correct responsive styles regardless of breakpoints order', () => {
+ const columns = 4;
+ const spacing = { sm: 2, md: 3, xs: 1 };
+ expect(
+ getStyle({
+ ownerState: {
+ columns,
+ spacing,
+ maxColumnHeight,
+ },
+ theme,
+ }),
+ ).to.deep.equal({
+ width: '100%',
+ display: 'flex',
+ flexFlow: 'column wrap',
+ alignContent: 'space-between',
+ boxSizing: 'border-box',
+ '& > *': {
+ boxSizing: 'border-box',
+ width: `calc(${(100 / columns).toFixed(2)}% - 0px)`,
+ },
+ [`@media (min-width:${theme.breakpoints.values.xs}px)`]: {
+ '& > *': {
+ margin: parseToNumber(theme.spacing(spacing.xs)) / 2,
+ width: `calc(${(100 / columns).toFixed(2)}% - ${theme.spacing(spacing.xs)})`,
+ },
+ margin: -(parseToNumber(theme.spacing(spacing.xs)) / 2),
+ height: maxColumnHeight + parseToNumber(theme.spacing(spacing.xs)),
+ },
+ [`@media (min-width:${theme.breakpoints.values.sm}px)`]: {
+ '& > *': {
+ margin: parseToNumber(theme.spacing(spacing.sm)) / 2,
+ width: `calc(${(100 / columns).toFixed(2)}% - ${theme.spacing(spacing.sm)})`,
+ },
+ margin: -(parseToNumber(theme.spacing(spacing.sm)) / 2),
+ height: maxColumnHeight + parseToNumber(theme.spacing(spacing.sm)),
+ },
+ [`@media (min-width:${theme.breakpoints.values.md}px)`]: {
+ '& > *': {
+ margin: parseToNumber(theme.spacing(spacing.md)) / 2,
+ width: `calc(${(100 / columns).toFixed(2)}% - ${theme.spacing(spacing.md)})`,
+ },
+ margin: -(parseToNumber(theme.spacing(spacing.md)) / 2),
+ height: maxColumnHeight + parseToNumber(theme.spacing(spacing.md)),
+ },
+ });
+ });
+ });
});
diff --git a/packages/mui-material/src/Grid/Grid.js b/packages/mui-material/src/Grid/Grid.js
index f237ab63835638..acee341f052ee9 100644
--- a/packages/mui-material/src/Grid/Grid.js
+++ b/packages/mui-material/src/Grid/Grid.js
@@ -56,11 +56,15 @@ function generateGrid(globalStyles, theme, breakpoint, ownerState) {
} else {
const columnsBreakpointValues = resolveBreakpointValues({
values: ownerState.columns,
- base: theme.breakpoints.values,
+ breakpoints: theme.breakpoints.values,
});
+ const columnValue =
+ typeof columnsBreakpointValues === 'object'
+ ? columnsBreakpointValues[breakpoint]
+ : columnsBreakpointValues;
// Keep 7 significant numbers.
- const width = `${Math.round((size / columnsBreakpointValues[breakpoint]) * 10e7) / 10e5}%`;
+ const width = `${Math.round((size / columnValue) * 10e7) / 10e5}%`;
let more = {};
if (ownerState.container && ownerState.item && ownerState.columnSpacing !== 0) {
@@ -92,8 +96,13 @@ function generateGrid(globalStyles, theme, breakpoint, ownerState) {
}
}
-function generateDirection({ theme, ownerState }) {
- return handleBreakpoints({ theme }, ownerState.direction, (propValue) => {
+export function generateDirection({ theme, ownerState }) {
+ const directionValues = resolveBreakpointValues({
+ values: ownerState.direction,
+ breakpoints: theme.breakpoints.values,
+ });
+
+ return handleBreakpoints({ theme }, directionValues, (propValue) => {
const output = {
flexDirection: propValue,
};
@@ -113,7 +122,12 @@ export function generateRowGap({ theme, ownerState }) {
let styles = {};
if (container && rowSpacing !== 0) {
- styles = handleBreakpoints({ theme }, rowSpacing, (propValue) => {
+ const rowSpacingValues = resolveBreakpointValues({
+ values: rowSpacing,
+ breakpoints: theme.breakpoints.values,
+ });
+
+ styles = handleBreakpoints({ theme }, rowSpacingValues, (propValue) => {
const themeSpacing = theme.spacing(propValue);
if (themeSpacing !== '0px') {
@@ -137,9 +151,13 @@ export function generateColumnGap({ theme, ownerState }) {
let styles = {};
if (container && columnSpacing !== 0) {
- styles = handleBreakpoints({ theme }, columnSpacing, (propValue) => {
- const themeSpacing = theme.spacing(propValue);
+ const columnSpacingValues = resolveBreakpointValues({
+ values: columnSpacing,
+ breakpoints: theme.breakpoints.values,
+ });
+ styles = handleBreakpoints({ theme }, columnSpacingValues, (propValue) => {
+ const themeSpacing = theme.spacing(propValue);
if (themeSpacing !== '0px') {
return {
width: `calc(100% + ${getOffset(themeSpacing)})`,
diff --git a/packages/mui-material/src/Grid/Grid.test.js b/packages/mui-material/src/Grid/Grid.test.js
index 8919d59fb5dc68..0cf677aaba9fc7 100644
--- a/packages/mui-material/src/Grid/Grid.test.js
+++ b/packages/mui-material/src/Grid/Grid.test.js
@@ -4,7 +4,7 @@ import { describeConformance, createClientRender, screen } from 'test/utils';
import { createTheme, ThemeProvider } from '@mui/material/styles';
import defaultTheme from '@mui/material/styles/defaultTheme';
import Grid, { gridClasses as classes } from '@mui/material/Grid';
-import { generateRowGap, generateColumnGap } from './Grid';
+import { generateRowGap, generateColumnGap, generateDirection } from './Grid';
describe('', () => {
const render = createClientRender();
@@ -94,6 +94,59 @@ describe('', () => {
});
});
+ describe('prop: direction', () => {
+ it('should have a direction', () => {
+ const { container } = render();
+ expect(container.firstChild).toHaveComputedStyle({ flexDirection: 'column' });
+ });
+
+ it('should support responsive values', () => {
+ const theme = createTheme();
+ expect(
+ generateDirection({
+ ownerState: {
+ container: true,
+ direction: { xs: 'row', sm: 'column' },
+ },
+ theme,
+ }),
+ ).to.deep.equal({
+ '@media (min-width:0px)': {
+ flexDirection: 'row',
+ },
+ [`@media (min-width:${defaultTheme.breakpoints.values.sm}px)`]: {
+ flexDirection: 'column',
+ '& > .MuiGrid-item': {
+ maxWidth: 'none',
+ },
+ },
+ });
+ });
+
+ it('should generate correct responsive styles regardless of breakpoints order', () => {
+ const theme = createTheme();
+ expect(
+ generateDirection({
+ ownerState: {
+ container: true,
+ direction: { sm: 'column', xs: 'row' },
+ },
+ theme,
+ }),
+ ).to.deep.equal({
+ '@media (min-width:0px)': {
+ flexDirection: 'row',
+ },
+ [`@media (min-width:${defaultTheme.breakpoints.values.sm}px)`]: {
+ flexDirection: 'column',
+ '& > .MuiGrid-item': {
+ maxWidth: 'none',
+ },
+ },
+ });
+ });
+ });
+
describe('prop: spacing', () => {
it('should have a spacing', () => {
const { container } = render();
@@ -112,56 +165,107 @@ describe('', () => {
paddingLeft: '12px',
});
});
- });
- it('should generate responsive styles', () => {
- const theme = createTheme();
- expect(
- generateRowGap({
- ownerState: {
- container: true,
- rowSpacing: { xs: 1, sm: 2 },
+ it('should generate correct responsive styles', () => {
+ const theme = createTheme();
+ expect(
+ generateRowGap({
+ ownerState: {
+ container: true,
+ rowSpacing: { xs: 1, sm: 2 },
+ },
+ theme,
+ }),
+ ).to.deep.equal({
+ '@media (min-width:0px)': {
+ '& > .MuiGrid-item': {
+ paddingTop: '8px',
+ },
+ marginTop: '-8px',
+ },
+ [`@media (min-width:${defaultTheme.breakpoints.values.sm}px)`]: {
+ '& > .MuiGrid-item': {
+ paddingTop: '16px',
+ },
+ marginTop: '-16px',
},
- theme,
- }),
- ).to.deep.equal({
- '@media (min-width:0px)': {
- '& > .MuiGrid-item': {
- paddingTop: '8px',
+ });
+
+ expect(
+ generateColumnGap({
+ ownerState: {
+ container: true,
+ columnSpacing: { xs: 1, sm: 2 },
+ },
+ theme,
+ }),
+ ).to.deep.equal({
+ '@media (min-width:0px)': {
+ '& > .MuiGrid-item': {
+ paddingLeft: '8px',
+ },
+ marginLeft: '-8px',
+ width: 'calc(100% + 8px)',
},
- marginTop: '-8px',
- },
- [`@media (min-width:${defaultTheme.breakpoints.values.sm}px)`]: {
- '& > .MuiGrid-item': {
- paddingTop: '16px',
+ [`@media (min-width:${defaultTheme.breakpoints.values.sm}px)`]: {
+ '& > .MuiGrid-item': {
+ paddingLeft: '16px',
+ },
+ marginLeft: '-16px',
+ width: 'calc(100% + 16px)',
},
- marginTop: '-16px',
- },
+ });
});
- expect(
- generateColumnGap({
- ownerState: {
- container: true,
- columnSpacing: { xs: 1, sm: 2 },
+ it('should generate correct responsive styles regardless of breakpoints order ', () => {
+ const theme = createTheme();
+ expect(
+ generateRowGap({
+ ownerState: {
+ container: true,
+ rowSpacing: { sm: 2, xs: 1 },
+ },
+ theme,
+ }),
+ ).to.deep.equal({
+ '@media (min-width:0px)': {
+ '& > .MuiGrid-item': {
+ paddingTop: '8px',
+ },
+ marginTop: '-8px',
+ },
+ [`@media (min-width:${defaultTheme.breakpoints.values.sm}px)`]: {
+ '& > .MuiGrid-item': {
+ paddingTop: '16px',
+ },
+ marginTop: '-16px',
},
- theme,
- }),
- ).to.deep.equal({
- '@media (min-width:0px)': {
- '& > .MuiGrid-item': {
- paddingLeft: '8px',
+ });
+
+ expect(
+ generateColumnGap({
+ ownerState: {
+ container: true,
+ columnSpacing: { sm: 2, xs: 1 },
+ },
+ theme,
+ }),
+ ).to.deep.equal({
+ '@media (min-width:0px)': {
+ '& > .MuiGrid-item': {
+ paddingLeft: '8px',
+ },
+ marginLeft: '-8px',
+ width: 'calc(100% + 8px)',
},
- marginLeft: '-8px',
- width: 'calc(100% + 8px)',
- },
- [`@media (min-width:${defaultTheme.breakpoints.values.sm}px)`]: {
- '& > .MuiGrid-item': {
- paddingLeft: '16px',
+ [`@media (min-width:${defaultTheme.breakpoints.values.sm}px)`]: {
+ '& > .MuiGrid-item': {
+ paddingLeft: '16px',
+ },
+ marginLeft: '-16px',
+ width: 'calc(100% + 16px)',
},
- marginLeft: '-16px',
- width: 'calc(100% + 16px)',
- },
+ });
});
});
diff --git a/packages/mui-material/src/Stack/Stack.js b/packages/mui-material/src/Stack/Stack.js
index 22e7df4f7dfb45..bfa62f79935174 100644
--- a/packages/mui-material/src/Stack/Stack.js
+++ b/packages/mui-material/src/Stack/Stack.js
@@ -44,9 +44,16 @@ const getSideFromDirection = (direction) => {
export const style = ({ ownerState, theme }) => {
let styles = {
display: 'flex',
- ...handleBreakpoints({ theme }, ownerState.direction, (propValue) => ({
- flexDirection: propValue,
- })),
+ ...handleBreakpoints(
+ { theme },
+ resolveBreakpointValues({
+ values: ownerState.direction,
+ breakpoints: theme.breakpoints.values,
+ }),
+ (propValue) => ({
+ flexDirection: propValue,
+ }),
+ ),
};
if (ownerState.spacing) {
@@ -59,8 +66,15 @@ export const style = ({ ownerState, theme }) => {
return acc;
}, {});
- const directionValues = resolveBreakpointValues({ values: ownerState.direction, base });
- const spacingValues = resolveBreakpointValues({ values: ownerState.spacing, base });
+ const directionValues = resolveBreakpointValues({
+ values: ownerState.direction,
+ base,
+ });
+
+ const spacingValues = resolveBreakpointValues({
+ values: ownerState.spacing,
+ base,
+ });
const styleFromPropValue = (propValue, breakpoint) => {
return {
diff --git a/packages/mui-material/src/Stack/Stack.test.js b/packages/mui-material/src/Stack/Stack.test.js
index 64cfa47cb1474f..579980838e0c13 100644
--- a/packages/mui-material/src/Stack/Stack.test.js
+++ b/packages/mui-material/src/Stack/Stack.test.js
@@ -186,4 +186,75 @@ describe('', () => {
display: 'flex',
});
});
+
+ describe('prop: direction', () => {
+ it('should generate correct responsive styles regardless of breakpoints order', () => {
+ expect(
+ style({
+ ownerState: {
+ direction: { sm: 'row', xs: 'column' },
+ spacing: { xs: 1, sm: 2, md: 3 },
+ },
+ theme,
+ }),
+ ).to.deep.equal({
+ '@media (min-width:0px)': {
+ '& > :not(style) + :not(style)': {
+ margin: 0,
+ marginTop: '8px',
+ },
+ flexDirection: 'column',
+ },
+ [`@media (min-width:${defaultTheme.breakpoints.values.sm}px)`]: {
+ '& > :not(style) + :not(style)': {
+ margin: 0,
+ marginLeft: '16px',
+ },
+ flexDirection: 'row',
+ },
+ [`@media (min-width:${defaultTheme.breakpoints.values.md}px)`]: {
+ '& > :not(style) + :not(style)': {
+ margin: 0,
+ marginLeft: '24px',
+ },
+ },
+ display: 'flex',
+ });
+ });
+ });
+
+ describe('prop: spacing', () => {
+ it('should generate correct responsive styles regardless of breakpoints order', () => {
+ expect(
+ style({
+ ownerState: {
+ direction: 'column',
+ spacing: { sm: 2, md: 3, xs: 1 },
+ },
+ theme,
+ }),
+ ).to.deep.equal({
+ '@media (min-width:0px)': {
+ '& > :not(style) + :not(style)': {
+ margin: 0,
+ marginTop: '8px',
+ },
+ },
+ [`@media (min-width:${defaultTheme.breakpoints.values.sm}px)`]: {
+ '& > :not(style) + :not(style)': {
+ margin: 0,
+ marginTop: '16px',
+ },
+ },
+ [`@media (min-width:${defaultTheme.breakpoints.values.md}px)`]: {
+ '& > :not(style) + :not(style)': {
+ margin: 0,
+ marginTop: '24px',
+ },
+ },
+ display: 'flex',
+ flexDirection: 'column',
+ });
+ });
+ });
});
diff --git a/packages/mui-system/src/breakpoints.js b/packages/mui-system/src/breakpoints.js
index edda30b4803fb6..fad8d2625e9762 100644
--- a/packages/mui-system/src/breakpoints.js
+++ b/packages/mui-system/src/breakpoints.js
@@ -113,7 +113,38 @@ export function mergeBreakpointsInOrder(breakpointsInput, ...styles) {
return removeUnusedBreakpoints(Object.keys(emptyBreakpoints), mergedOutput);
}
-export function resolveBreakpointValues({ values: breakpointValues, base }) {
+// compute base for responsive values; e.g.,
+// [1,2,3] => {xs: true, sm: true, md: true}
+// {xs: 1, sm: 2, md: 3} => {xs: true, sm: true, md: true}
+export function computeBreakpointsBase(breakpointValues, themeBreakpoints) {
+ // fixed value
+ if (typeof breakpointValues !== 'object') {
+ return {};
+ }
+ const base = {};
+ const breakpointsKeys = Object.keys(themeBreakpoints);
+ if (Array.isArray(breakpointValues)) {
+ breakpointsKeys.forEach((breakpoint, i) => {
+ if (i < breakpointValues.length) {
+ base[breakpoint] = true;
+ }
+ });
+ } else {
+ breakpointsKeys.forEach((breakpoint) => {
+ if (breakpointValues[breakpoint] != null) {
+ base[breakpoint] = true;
+ }
+ });
+ }
+ return base;
+}
+
+export function resolveBreakpointValues({
+ values: breakpointValues,
+ breakpoints: themeBreakpoints,
+ base: customBase,
+}) {
+ const base = customBase || computeBreakpointsBase(breakpointValues, themeBreakpoints);
const keys = Object.keys(base);
if (keys.length === 0) {
@@ -122,16 +153,18 @@ export function resolveBreakpointValues({ values: breakpointValues, base }) {
let previous;
- return keys.reduce((acc, breakpoint) => {
- if (typeof breakpointValues === 'object') {
+ return keys.reduce((acc, breakpoint, i) => {
+ if (Array.isArray(breakpointValues)) {
+ acc[breakpoint] =
+ breakpointValues[i] != null ? breakpointValues[i] : breakpointValues[previous];
+ previous = i;
+ } else {
acc[breakpoint] =
breakpointValues[breakpoint] != null
? breakpointValues[breakpoint]
- : breakpointValues[previous];
- } else {
- acc[breakpoint] = breakpointValues;
+ : breakpointValues[previous] || breakpointValues;
+ previous = breakpoint;
}
- previous = breakpoint;
return acc;
}, {});
}
diff --git a/packages/mui-system/src/breakpoints.test.js b/packages/mui-system/src/breakpoints.test.js
index dac47c5a994c15..0cb0b209bfa08f 100644
--- a/packages/mui-system/src/breakpoints.test.js
+++ b/packages/mui-system/src/breakpoints.test.js
@@ -1,5 +1,5 @@
import { expect } from 'chai';
-import breakpoints from './breakpoints';
+import breakpoints, { computeBreakpointsBase, resolveBreakpointValues } from './breakpoints';
import style from './style';
const textColor = style({
@@ -8,6 +8,14 @@ const textColor = style({
});
describe('breakpoints', () => {
+ const muiThemeBreakpoints = { xs: 0, sm: 600, md: 900, lg: 1200, xl: 1536 };
+ const customThemeBreakpoints = {
+ extraSmall: 0,
+ small: 300,
+ medium: 600,
+ large: 900,
+ extraLarge: 1200,
+ };
it('should work', () => {
const palette = breakpoints(textColor);
@@ -26,4 +34,180 @@ describe('breakpoints', () => {
},
});
});
+
+ describe('function: computeBreakpointsBase', () => {
+ describe('mui default breakpoints', () => {
+ it('compute base for breakpoint values of array type', () => {
+ const columns = [1, 2, 3];
+ const base = computeBreakpointsBase(columns, muiThemeBreakpoints);
+ expect(base).to.deep.equal({ xs: true, sm: true, md: true });
+ });
+
+ it('compute base for breakpoint values of object type', () => {
+ const columns = { xs: 1, sm: 2, md: 3 };
+ const base = computeBreakpointsBase(columns, muiThemeBreakpoints);
+ expect(base).to.deep.equal({ xs: true, sm: true, md: true });
+ });
+
+ it('return empty object for fixed value', () => {
+ const columns = 3;
+ const base = computeBreakpointsBase(columns, muiThemeBreakpoints);
+ expect(base).to.deep.equal({});
+ });
+ });
+
+ describe('custom breakpoints', () => {
+ it('compute base for breakpoint values of array type', () => {
+ const columns = [1, 2, 3];
+ const base = computeBreakpointsBase(columns, customThemeBreakpoints);
+ expect(base).to.deep.equal({ extraSmall: true, small: true, medium: true });
+ });
+
+ it('compute base for breakpoint values of object type', () => {
+ const columns = { extraSmall: 1, small: 2, medium: 3 };
+ const base = computeBreakpointsBase(columns, customThemeBreakpoints);
+ expect(base).to.deep.equal({ extraSmall: true, small: true, medium: true });
+ });
+
+ it('return empty object for fixed value', () => {
+ const columns = 3;
+ const base = computeBreakpointsBase(columns, customThemeBreakpoints);
+ expect(base).to.deep.equal({});
+ });
+ });
+ });
+
+ describe('function: resolveBreakpointValues', () => {
+ describe('mui default breakpoints', () => {
+ it('resolve breakpoint values for prop of array type', () => {
+ const columns = [1, 2, 3];
+ const values = resolveBreakpointValues({
+ values: columns,
+ breakpoints: muiThemeBreakpoints,
+ });
+ expect(values).to.deep.equal({ xs: 1, sm: 2, md: 3 });
+ });
+
+ it('resolve breakpoint values for prop of object type', () => {
+ const columns = { xs: 1, sm: 2, md: 3 };
+ const values = resolveBreakpointValues({
+ values: columns,
+ breakpoints: muiThemeBreakpoints,
+ });
+ expect(values).to.deep.equal({ xs: 1, sm: 2, md: 3 });
+ });
+
+ it('resolve breakpoint values for unordered prop of object type', () => {
+ const columns = { sm: 2, md: 3, xs: 1 };
+ const values = resolveBreakpointValues({
+ values: columns,
+ breakpoints: muiThemeBreakpoints,
+ });
+ expect(values).to.deep.equal({ xs: 1, sm: 2, md: 3 });
+ });
+
+ it('return prop as it is for prop of fixed value', () => {
+ const columns = 3;
+ const values = resolveBreakpointValues({
+ values: columns,
+ breakpoints: muiThemeBreakpoints,
+ });
+ expect(values).to.equal(3);
+ });
+
+ it('given custom base, resolve breakpoint values for prop of array type', () => {
+ const columns = [1, 2, 3];
+ const customBase = { xs: true, sm: true, md: true, lg: true };
+ const values = resolveBreakpointValues({ values: columns, base: customBase });
+ expect(values).to.deep.equal({ xs: 1, sm: 2, md: 3, lg: 3 });
+ });
+
+ it('given custom base, resolve breakpoint values for prop of object type', () => {
+ const columns = { xs: 1, sm: 2, md: 3 };
+ const customBase = { xs: true, sm: true, md: true, lg: true };
+ const values = resolveBreakpointValues({ values: columns, base: customBase });
+ expect(values).to.deep.equal({ xs: 1, sm: 2, md: 3, lg: 3 });
+ });
+
+ it('given custom base, resolve breakpoint values for unordered prop of object type', () => {
+ const columns = { sm: 2, md: 3, xs: 1 };
+ const customBase = { xs: true, sm: true, md: true, lg: true };
+ const values = resolveBreakpointValues({ values: columns, base: customBase });
+ expect(values).to.deep.equal({ xs: 1, sm: 2, md: 3, lg: 3 });
+ });
+
+ it('given custom base, resolve breakpoint values for prop of object type with missing breakpoints', () => {
+ const columns = { xs: 1, md: 2 };
+ const customBase = { xs: true, sm: true, md: true, lg: true };
+ const values = resolveBreakpointValues({ values: columns, base: customBase });
+ expect(values).to.deep.equal({ xs: 1, sm: 1, md: 2, lg: 2 });
+ });
+
+ it('given custom base, resolve breakpoint values for unordered prop of object type with missing breakpoints', () => {
+ const columns = { md: 2, xs: 1 };
+ const customBase = { xs: true, sm: true, md: true, lg: true };
+ const values = resolveBreakpointValues({ values: columns, base: customBase });
+ expect(values).to.deep.equal({ xs: 1, sm: 1, md: 2, lg: 2 });
+ });
+ });
+
+ describe('custom breakpoints', () => {
+ it('resolve breakpoint values for prop of array type', () => {
+ const columns = [1, 2, 3];
+ const values = resolveBreakpointValues({
+ values: columns,
+ breakpoints: customThemeBreakpoints,
+ });
+ expect(values).to.deep.equal({ extraSmall: 1, small: 2, medium: 3 });
+ });
+
+ it('resolve breakpoint values for prop of object type', () => {
+ const columns = { extraSmall: 1, small: 2, medium: 3 };
+ const values = resolveBreakpointValues({
+ values: columns,
+ breakpoints: customThemeBreakpoints,
+ });
+ expect(values).to.deep.equal({ extraSmall: 1, small: 2, medium: 3 });
+ });
+
+ it('resolve breakpoint values for unordered prop of object type', () => {
+ const columns = { small: 2, medium: 3, extraSmall: 1 };
+ const values = resolveBreakpointValues({
+ values: columns,
+ breakpoints: customThemeBreakpoints,
+ });
+ expect(values).to.deep.equal({ extraSmall: 1, small: 2, medium: 3 });
+ });
+
+ it('return prop as it is for prop of fixed value', () => {
+ const columns = 3;
+ const values = resolveBreakpointValues({
+ values: columns,
+ breakpoints: customThemeBreakpoints,
+ });
+ expect(values).to.equal(3);
+ });
+
+ it('given custom base, resolve breakpoint values for prop of array type', () => {
+ const columns = [1, 2, 3];
+ const customBase = { extraSmall: true, small: true, medium: true, large: true };
+ const values = resolveBreakpointValues({ values: columns, base: customBase });
+ expect(values).to.deep.equal({ extraSmall: 1, small: 2, medium: 3, large: 3 });
+ });
+
+ it('given custom base, resolve breakpoint values for prop of object type', () => {
+ const columns = { extraSmall: 1, small: 2, medium: 3 };
+ const customBase = { extraSmall: true, small: true, medium: true, large: true };
+ const values = resolveBreakpointValues({ values: columns, base: customBase });
+ expect(values).to.deep.equal({ extraSmall: 1, small: 2, medium: 3, large: 3 });
+ });
+
+ it('given custom base, resolve breakpoint values for unordered prop of object type', () => {
+ const columns = { small: 2, medium: 3, extraSmall: 1 };
+ const customBase = { extraSmall: true, small: true, medium: true, large: true };
+ const values = resolveBreakpointValues({ values: columns, base: customBase });
+ expect(values).to.deep.equal({ extraSmall: 1, small: 2, medium: 3, large: 3 });
+ });
+ });
+ });
});