From 05bc42576b4faf2564bf7e38439de2c9b1d2b632 Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Tue, 26 Mar 2024 14:35:51 +0700 Subject: [PATCH 01/13] add container queries --- .../cssContainerQueries.test.ts | 38 +++++++++++++++ .../cssContainerQueries.ts | 46 +++++++++++++++++++ .../src/cssContainerQueries/index.ts | 1 + packages/mui-system/src/index.d.ts | 4 ++ packages/mui-system/src/index.js | 4 ++ 5 files changed, 93 insertions(+) create mode 100644 packages/mui-system/src/cssContainerQueries/cssContainerQueries.test.ts create mode 100644 packages/mui-system/src/cssContainerQueries/cssContainerQueries.ts create mode 100644 packages/mui-system/src/cssContainerQueries/index.ts diff --git a/packages/mui-system/src/cssContainerQueries/cssContainerQueries.test.ts b/packages/mui-system/src/cssContainerQueries/cssContainerQueries.test.ts new file mode 100644 index 00000000000000..9b7573ec0c303b --- /dev/null +++ b/packages/mui-system/src/cssContainerQueries/cssContainerQueries.test.ts @@ -0,0 +1,38 @@ +import { expect } from 'chai'; + +import createTheme from '@mui/system/createTheme'; +import cssContainerQueries from '@mui/system/cssContainerQueries'; + +describe('cssContainerQueries', () => { + it('should have `up`, `down`, `between`, `only`, and `not` functions', () => { + const theme = cssContainerQueries(createTheme()); + + expect(theme.cq.up('sm')).to.equal('@container (min-width:600px)'); + expect(theme.cq.down('sm')).to.equal('@container (max-width:599.95px)'); + expect(theme.cq.between('sm', 'md')).to.equal( + '@container (min-width:600px) and (max-width:899.95px)', + ); + expect(theme.cq.only('sm')).to.equal('@container (min-width:600px) and (max-width:899.95px)'); + expect(theme.cq.not('xs')).to.equal('@container (min-width:600px)'); + expect(theme.cq.not('xl')).to.equal('@container (max-width:1535.95px)'); + expect(theme.cq.not('md')).to.equal('@container (width<900px) and (width>1199.95px)'); + }); + + it('should be able to create named containment context', () => { + const theme = cssContainerQueries(createTheme()); + + expect(theme.cq('sidebar').up('sm')).to.equal('@container sidebar (min-width:600px)'); + expect(theme.cq('sidebar').down('sm')).to.equal('@container sidebar (max-width:599.95px)'); + expect(theme.cq('sidebar').between('sm', 'md')).to.equal( + '@container sidebar (min-width:600px) and (max-width:899.95px)', + ); + expect(theme.cq('sidebar').only('sm')).to.equal( + '@container sidebar (min-width:600px) and (max-width:899.95px)', + ); + expect(theme.cq('sidebar').not('xs')).to.equal('@container sidebar (min-width:600px)'); + expect(theme.cq('sidebar').not('xl')).to.equal('@container sidebar (max-width:1535.95px)'); + expect(theme.cq('sidebar').not('sm')).to.equal( + '@container sidebar (width<600px) and (width>899.95px)', + ); + }); +}); diff --git a/packages/mui-system/src/cssContainerQueries/cssContainerQueries.ts b/packages/mui-system/src/cssContainerQueries/cssContainerQueries.ts new file mode 100644 index 00000000000000..f34b80b4a8db28 --- /dev/null +++ b/packages/mui-system/src/cssContainerQueries/cssContainerQueries.ts @@ -0,0 +1,46 @@ +import { Breakpoints, Breakpoint } from '../createTheme/createBreakpoints'; + +type Fn = 'up' | 'down' | 'between' | 'only' | 'not'; + +interface CssContainerQueries { + cq: ((name: string) => Pick) & Pick; +} + +export default function cssContainerQueries( + themeInput: T, +): T & CssContainerQueries { + function toContainerQuery(key: Fn, name?: string) { + return (...args: Array) => { + // @ts-ignore + const result = themeInput.breakpoints[key](...args).replace( + '@media', + name ? `@container ${name}` : '@container', + ); + if (key === 'not' && result.includes('not all and')) { + return result + .replace('not all and ', '') + .replace('min-width:', 'width<') + .replace('max-width:', 'width>'); + } + return result; + }; + } + function cq(name: string) { + return { + up: toContainerQuery('up', name), + down: toContainerQuery('down', name), + between: toContainerQuery('between', name), + only: toContainerQuery('only', name), + not: toContainerQuery('not', name), + }; + } + cq.up = toContainerQuery('up'); + cq.down = toContainerQuery('down'); + cq.between = toContainerQuery('between'); + cq.only = toContainerQuery('only'); + cq.not = toContainerQuery('not'); + return { + ...themeInput, + cq, + }; +} diff --git a/packages/mui-system/src/cssContainerQueries/index.ts b/packages/mui-system/src/cssContainerQueries/index.ts new file mode 100644 index 00000000000000..4912288ba1dd47 --- /dev/null +++ b/packages/mui-system/src/cssContainerQueries/index.ts @@ -0,0 +1 @@ +export { default } from './cssContainerQueries'; diff --git a/packages/mui-system/src/index.d.ts b/packages/mui-system/src/index.d.ts index ea3580a981cc9f..023efbe1b22122 100644 --- a/packages/mui-system/src/index.d.ts +++ b/packages/mui-system/src/index.d.ts @@ -120,3 +120,7 @@ export * from './Unstable_Grid'; export { default as Stack } from './Stack'; export * from './Stack'; + +/** ----------------- */ +/** Unstable APIs */ +export { default as unstable_cssContainerQueries } from './cssContainerQueries'; diff --git a/packages/mui-system/src/index.js b/packages/mui-system/src/index.js index b7215ef8dee1b4..468b101f04e40c 100644 --- a/packages/mui-system/src/index.js +++ b/packages/mui-system/src/index.js @@ -78,3 +78,7 @@ export * from './Unstable_Grid'; export { default as Stack } from './Stack/Stack'; export * from './Stack'; + +/** ----------------- */ +/** Unstable APIs */ +export { default as unstable_cssContainerQueries } from './cssContainerQueries'; From ca0d7794bed97d7f8764af17481ca3aa24fdf5cc Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Tue, 26 Mar 2024 18:14:33 +0700 Subject: [PATCH 02/13] add containerQueries --- packages/mui-babel-macros/MuiError.macro.d.ts | 2 +- .../mui-system/src/breakpoints/breakpoints.js | 19 ++++- .../cssContainerQueries.test.ts | 55 ++++++++++++- .../cssContainerQueries.ts | 70 ++++++++++++++++- .../src/cssContainerQueries/index.ts | 1 + .../mui-system/src/cssGrid/cssGrid.test.js | 21 +++++ .../mui-system/src/spacing/spacing.test.js | 21 +++++ .../src/styleFunctionSx/styleFunctionSx.js | 3 +- .../styleFunctionSx/styleFunctionSx.test.js | 78 ++++++++++++++++++- 9 files changed, 259 insertions(+), 11 deletions(-) diff --git a/packages/mui-babel-macros/MuiError.macro.d.ts b/packages/mui-babel-macros/MuiError.macro.d.ts index 53d894b2241058..54293408e59b1a 100644 --- a/packages/mui-babel-macros/MuiError.macro.d.ts +++ b/packages/mui-babel-macros/MuiError.macro.d.ts @@ -1,3 +1,3 @@ export default class MuiError { - constructor(message: string); + constructor(message: string, ...args: string[]); } diff --git a/packages/mui-system/src/breakpoints/breakpoints.js b/packages/mui-system/src/breakpoints/breakpoints.js index 4d6fdf84b3eaba..8e6256a2d3a4d4 100644 --- a/packages/mui-system/src/breakpoints/breakpoints.js +++ b/packages/mui-system/src/breakpoints/breakpoints.js @@ -1,6 +1,7 @@ import PropTypes from 'prop-types'; import deepmerge from '@mui/utils/deepmerge'; import merge from '../merge'; +import { getContainerQuery } from '../cssContainerQueries'; // The breakpoint **start** at this value. // For instance with the first breakpoint xs: [xs, sm[. @@ -16,7 +17,15 @@ const defaultBreakpoints = { // Sorted ASC by size. That's important. // It can't be configured as it's used statically for propTypes. keys: ['xs', 'sm', 'md', 'lg', 'xl'], - up: (key) => `@media (min-width:${values[key]}px)`, + up: (key) => { + let result = typeof key === 'number' ? key : values[key]; + if (typeof result === 'number') { + result = `${result}px`; + } else { + result = key; + } + return `@media (min-width:${result})`; + }, }; export function handleBreakpoints(props, propValue, styleFromPropValue) { @@ -33,8 +42,14 @@ export function handleBreakpoints(props, propValue, styleFromPropValue) { if (typeof propValue === 'object') { const themeBreakpoints = theme.breakpoints || defaultBreakpoints; return Object.keys(propValue).reduce((acc, breakpoint) => { + if (breakpoint.startsWith('cq')) { + const containerKey = getContainerQuery({ breakpoints: themeBreakpoints }, breakpoint); + if (containerKey) { + acc[containerKey] = styleFromPropValue(propValue[breakpoint], breakpoint); + } + } // key is breakpoint - if (Object.keys(themeBreakpoints.values || values).indexOf(breakpoint) !== -1) { + else if (Object.keys(themeBreakpoints.values || values).indexOf(breakpoint) !== -1) { const mediaKey = themeBreakpoints.up(breakpoint); acc[mediaKey] = styleFromPropValue(propValue[breakpoint], breakpoint); } else { diff --git a/packages/mui-system/src/cssContainerQueries/cssContainerQueries.test.ts b/packages/mui-system/src/cssContainerQueries/cssContainerQueries.test.ts index 9b7573ec0c303b..17763ad060c951 100644 --- a/packages/mui-system/src/cssContainerQueries/cssContainerQueries.test.ts +++ b/packages/mui-system/src/cssContainerQueries/cssContainerQueries.test.ts @@ -1,7 +1,10 @@ import { expect } from 'chai'; import createTheme from '@mui/system/createTheme'; -import cssContainerQueries from '@mui/system/cssContainerQueries'; +import cssContainerQueries, { + sortContainerQueries, + getContainerQuery, +} from '@mui/system/cssContainerQueries'; describe('cssContainerQueries', () => { it('should have `up`, `down`, `between`, `only`, and `not` functions', () => { @@ -35,4 +38,54 @@ describe('cssContainerQueries', () => { '@container sidebar (width<600px) and (width>899.95px)', ); }); + + it('should sort container queries', () => { + const theme = cssContainerQueries(createTheme()); + + const css = { + '@container (min-width:960px)': {}, + '@container (min-width:1280px)': {}, + '@container (min-width:0px)': {}, + '@container (min-width:600px)': {}, + }; + + const sorted = sortContainerQueries(theme, css); + + expect(Object.keys(sorted)).to.deep.equal([ + '@container (min-width:0px)', + '@container (min-width:600px)', + '@container (min-width:960px)', + '@container (min-width:1280px)', + ]); + }); + + it('should sort container queries with other unit', () => { + const theme = cssContainerQueries(createTheme()); + + const css = { + '@container (min-width:30.5rem)': {}, + '@container (min-width:20rem)': {}, + '@container (min-width:50.5rem)': {}, + '@container (min-width:40rem)': {}, + }; + + const sorted = sortContainerQueries(theme, css); + + expect(Object.keys(sorted)).to.deep.equal([ + '@container (min-width:20rem)', + '@container (min-width:30.5rem)', + '@container (min-width:40rem)', + '@container (min-width:50.5rem)', + ]); + }); + + it('should throw an error if shorthand is invalid', () => { + expect(() => { + const theme = cssContainerQueries(createTheme()); + getContainerQuery(theme, 'cq0'); + }).to.throw( + 'MUI: The provided shorthand (cq0) is invalid. The format should be `cq@` or `cq@/`.\n' + + 'For example, `cq@sm` or `cq@600` or `cq@40rem/sidebar`.', + ); + }); }); diff --git a/packages/mui-system/src/cssContainerQueries/cssContainerQueries.ts b/packages/mui-system/src/cssContainerQueries/cssContainerQueries.ts index f34b80b4a8db28..eea6cc815eb4e8 100644 --- a/packages/mui-system/src/cssContainerQueries/cssContainerQueries.ts +++ b/packages/mui-system/src/cssContainerQueries/cssContainerQueries.ts @@ -1,3 +1,4 @@ +import MuiError from '@mui/internal-babel-macros/MuiError.macro'; import { Breakpoints, Breakpoint } from '../createTheme/createBreakpoints'; type Fn = 'up' | 'down' | 'between' | 'only' | 'not'; @@ -6,10 +7,8 @@ interface CssContainerQueries { cq: ((name: string) => Pick) & Pick; } -export default function cssContainerQueries( - themeInput: T, -): T & CssContainerQueries { - function toContainerQuery(key: Fn, name?: string) { +function createBreakpointToCQ }>(themeInput: T) { + return function toContainerQuery(key: Fn, name?: string) { return (...args: Array) => { // @ts-ignore const result = themeInput.breakpoints[key](...args).replace( @@ -24,7 +23,70 @@ export default function cssContainerQueries, + css: Record, +) { + if (!theme.cq) { + return css; + } + const sorted = Object.keys(css) + .filter((key) => key.startsWith('@container')) + .sort((a, b) => { + const regex = /min-width:\s*([0-9.]+)/; + return +(a.match(regex)?.[1] || 0) - +(b.match(regex)?.[1] || 0); + }); + if (!sorted.length) { + return css; + } + return sorted.reduce( + (acc, key) => { + const value = css[key]; + delete acc[key]; + acc[key] = value; + return acc; + }, + { ...css }, + ); +} + +export function getContainerQuery( + theme: Partial & { breakpoints: Pick }, + shorthand: string, +) { + if (shorthand.startsWith('cq')) { + const matches = shorthand.match(/@([^/\n]+)\/?(.+)?/); + if (!matches) { + if (process.env.NODE_ENV !== 'production') { + throw new MuiError( + 'MUI: The provided shorthand %s is invalid. The format should be `cq@` or `cq@/`.\n' + + 'For example, `cq@sm` or `cq@600` or `cq@40rem/sidebar`.', + `(${shorthand})`, + ); + } + return null; + } + const [, containerQuery, containerName] = matches; + const value = (Number.isNaN(+containerQuery) ? containerQuery : +containerQuery) as + | Breakpoint + | number; + if (theme.cq) { + return containerName ? theme.cq(containerName).up(value) : theme.cq.up(value); + } + if (theme.breakpoints) { + return createBreakpointToCQ(theme)('up', containerName)(value); + } } + return null; +} + +export default function cssContainerQueries( + themeInput: T, +): T & CssContainerQueries { + const toContainerQuery = createBreakpointToCQ(themeInput); function cq(name: string) { return { up: toContainerQuery('up', name), diff --git a/packages/mui-system/src/cssContainerQueries/index.ts b/packages/mui-system/src/cssContainerQueries/index.ts index 4912288ba1dd47..4041c121b3aa3f 100644 --- a/packages/mui-system/src/cssContainerQueries/index.ts +++ b/packages/mui-system/src/cssContainerQueries/index.ts @@ -1 +1,2 @@ export { default } from './cssContainerQueries'; +export { getContainerQuery, sortContainerQueries } from './cssContainerQueries'; diff --git a/packages/mui-system/src/cssGrid/cssGrid.test.js b/packages/mui-system/src/cssGrid/cssGrid.test.js index a12b8d0e511821..1a8dff573d3801 100644 --- a/packages/mui-system/src/cssGrid/cssGrid.test.js +++ b/packages/mui-system/src/cssGrid/cssGrid.test.js @@ -37,4 +37,25 @@ describe('grid', () => { }, }); }); + + it('should support container queries', () => { + const output1 = grid({ + gap: { + 'cq@sm': 1, + 'cq@900/sidebar': 2, + 'cq@80rem/sidebar': 3, + }, + }); + expect(output1).to.deep.equal({ + '@container (min-width:600px)': { + gap: 8, + }, + '@container sidebar (min-width:900px)': { + gap: 16, + }, + '@container sidebar (min-width:80rem)': { + gap: 24, + }, + }); + }); }); diff --git a/packages/mui-system/src/spacing/spacing.test.js b/packages/mui-system/src/spacing/spacing.test.js index 1b6a77996c6ecd..c41527e6bbe636 100644 --- a/packages/mui-system/src/spacing/spacing.test.js +++ b/packages/mui-system/src/spacing/spacing.test.js @@ -154,6 +154,27 @@ describe('system spacing', () => { }); }); + it('should support container queries', () => { + const output1 = spacing({ + p: { + 'cq@sm': 1, + 'cq@900/sidebar': 2, + 'cq@80rem/sidebar': 3, + }, + }); + expect(output1).to.deep.equal({ + '@container (min-width:600px)': { + padding: 8, + }, + '@container sidebar (min-width:900px)': { + padding: 16, + }, + '@container sidebar (min-width:80rem)': { + padding: 24, + }, + }); + }); + it('should support full version', () => { const output1 = spacing({ paddingTop: 1, diff --git a/packages/mui-system/src/styleFunctionSx/styleFunctionSx.js b/packages/mui-system/src/styleFunctionSx/styleFunctionSx.js index 151f117c416477..a74b44b553311c 100644 --- a/packages/mui-system/src/styleFunctionSx/styleFunctionSx.js +++ b/packages/mui-system/src/styleFunctionSx/styleFunctionSx.js @@ -6,6 +6,7 @@ import { createEmptyBreakpointObject, removeUnusedBreakpoints, } from '../breakpoints'; +import { sortContainerQueries } from '../cssContainerQueries'; import defaultSxConfig from './defaultSxConfig'; function objectsHaveSameKeys(...objects) { @@ -127,7 +128,7 @@ export function unstable_createStyleFunctionSx() { } }); - return removeUnusedBreakpoints(breakpointsKeys, css); + return sortContainerQueries(theme, removeUnusedBreakpoints(breakpointsKeys, css)); } return Array.isArray(sx) ? sx.map(traverse) : traverse(sx); diff --git a/packages/mui-system/src/styleFunctionSx/styleFunctionSx.test.js b/packages/mui-system/src/styleFunctionSx/styleFunctionSx.test.js index dced5959cb72aa..6b6d28e2f383e7 100644 --- a/packages/mui-system/src/styleFunctionSx/styleFunctionSx.test.js +++ b/packages/mui-system/src/styleFunctionSx/styleFunctionSx.test.js @@ -1,5 +1,6 @@ import { expect } from 'chai'; import styleFunctionSx from './styleFunctionSx'; +import cssContainerQueries from '../cssContainerQueries'; describe('styleFunctionSx', () => { const breakpointsValues = { @@ -12,7 +13,7 @@ describe('styleFunctionSx', () => { const round = (value) => Math.round(value * 1e5) / 1e5; - const theme = { + const theme = cssContainerQueries({ spacing: (val) => `${val * 10}px`, breakpoints: { keys: ['xs', 'sm', 'md', 'lg', 'xl'], @@ -49,7 +50,7 @@ describe('styleFunctionSx', () => { lineHeight: 1.43, }, }, - }; + }); describe('system', () => { it('resolves system ', () => { @@ -243,6 +244,79 @@ describe('styleFunctionSx', () => { }); }); + describe('container queries', () => { + const queriesExpectedResult = { + '@container (min-width:0px)': { border: '1px solid' }, + '@container (min-width:600px)': { border: '2px solid' }, + '@container (min-width:960px)': { border: '3px solid' }, + '@container (min-width:1280px)': { border: '4px solid' }, + '@container (min-width:1920px)': { border: '5px solid' }, + }; + + it('resolves queries object', () => { + const result = styleFunctionSx({ + theme, + sx: { + border: { + 'cq@xs': 1, + 'cq@sm': 2, + 'cq@md': 3, + 'cq@lg': 4, + 'cq@xl': 5, + }, + }, + }); + + expect(result).to.deep.equal(queriesExpectedResult); + }); + + it('merges multiple queries object', () => { + const result = styleFunctionSx({ + theme, + sx: { + m: { + 'cq@xs': 1, + 'cq@sm': 2, + 'cq@md': 3, + }, + p: { + 'cq@xs': 5, + 'cq@sm': 6, + 'cq@md': 7, + }, + }, + }); + + expect(result).to.deep.equal({ + '@container (min-width:0px)': { padding: '50px', margin: '10px' }, + '@container (min-width:600px)': { padding: '60px', margin: '20px' }, + '@container (min-width:960px)': { padding: '70px', margin: '30px' }, + }); + }); + + it('writes queries in correct order', () => { + const result = styleFunctionSx({ + theme, + sx: { m: { 'cq@md': 1, 'cq@lg': 2 }, p: { 'cq@xs': 0, 'cq@sm': 1, 'cq@md': 2 } }, + }); + + // Test the order + expect(Object.keys(result)).to.deep.equal([ + '@container (min-width:0px)', + '@container (min-width:600px)', + '@container (min-width:960px)', + '@container (min-width:1280px)', + ]); + + expect(result).to.deep.equal({ + '@container (min-width:0px)': { padding: '0px' }, + '@container (min-width:600px)': { padding: '10px' }, + '@container (min-width:960px)': { padding: '20px', margin: '10px' }, + '@container (min-width:1280px)': { margin: '20px' }, + }); + }); + }); + describe('theme callback', () => { it('works on CSS properties', () => { const result = styleFunctionSx({ From 6682098506165e8bb2af28aa7333fe2c02490861 Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Wed, 27 Mar 2024 09:56:25 +0700 Subject: [PATCH 03/13] pnpm extract-error-codes --- docs/public/static/error-codes.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/public/static/error-codes.json b/docs/public/static/error-codes.json index a6486f38f45d49..9776d27153c7c8 100644 --- a/docs/public/static/error-codes.json +++ b/docs/public/static/error-codes.json @@ -18,5 +18,6 @@ "17": "MUI: Expected valid input target. Did you use a custom `slots.input` and forget to forward refs? See https://mui.com/r/input-component-ref-interface for more info.", "18": "MUI: `vars` is a private field used for CSS variables support.\nPlease use another name.", "19": "MUI: `useColorScheme` must be called under ", - "20": "MUI: The `experimental_sx` has been moved to `theme.unstable_sx`.For more details, see https://github.com/mui/material-ui/pull/35150." -} + "20": "MUI: The `experimental_sx` has been moved to `theme.unstable_sx`.For more details, see https://github.com/mui/material-ui/pull/35150.", + "21": "MUI: The provided shorthand %s is invalid. The format should be `cq@` or `cq@/`.\nFor example, `cq@sm` or `cq@600` or `cq@40rem/sidebar`." +} \ No newline at end of file From 35e2a07dda55175725f7033a8e898089d70dca8e Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Wed, 27 Mar 2024 10:01:23 +0700 Subject: [PATCH 04/13] reexport cssContainerQueries --- packages/mui-joy/src/styles/index.ts | 1 + packages/mui-material/src/styles/index.d.ts | 1 + packages/mui-material/src/styles/index.js | 1 + packages/mui-system/src/index.d.ts | 6 ++---- packages/mui-system/src/index.js | 5 +---- 5 files changed, 6 insertions(+), 8 deletions(-) diff --git a/packages/mui-joy/src/styles/index.ts b/packages/mui-joy/src/styles/index.ts index 82fd57ca9ee0da..71aa400ee9c573 100644 --- a/packages/mui-joy/src/styles/index.ts +++ b/packages/mui-joy/src/styles/index.ts @@ -1,5 +1,6 @@ 'use client'; // reexports from system for module augmentation +export { cssContainerQueries } from '@mui/system'; export type { BreakpointOverrides } from '@mui/system'; // Joy typings diff --git a/packages/mui-material/src/styles/index.d.ts b/packages/mui-material/src/styles/index.d.ts index 234aed07d592ce..0760a670c2b522 100644 --- a/packages/mui-material/src/styles/index.d.ts +++ b/packages/mui-material/src/styles/index.d.ts @@ -65,6 +65,7 @@ export { ColorObject, StyledEngineProvider, SxProps, + cssContainerQueries, } from '@mui/system'; // TODO: Remove this function in v6. // eslint-disable-next-line @typescript-eslint/naming-convention diff --git a/packages/mui-material/src/styles/index.js b/packages/mui-material/src/styles/index.js index 42e3a789b6c13c..ee77c68e6e0b5b 100644 --- a/packages/mui-material/src/styles/index.js +++ b/packages/mui-material/src/styles/index.js @@ -17,6 +17,7 @@ export { lighten, css, keyframes, + cssContainerQueries, } from '@mui/system'; // TODO: Remove this function in v6. // eslint-disable-next-line @typescript-eslint/naming-convention diff --git a/packages/mui-system/src/index.d.ts b/packages/mui-system/src/index.d.ts index 023efbe1b22122..22df2b0ef7a81d 100644 --- a/packages/mui-system/src/index.d.ts +++ b/packages/mui-system/src/index.d.ts @@ -5,6 +5,8 @@ export * from './borders'; export { default as breakpoints, handleBreakpoints, mergeBreakpointsInOrder } from './breakpoints'; +export { default as cssContainerQueries } from './cssContainerQueries'; + export { default as compose } from './compose'; export * from './display'; @@ -120,7 +122,3 @@ export * from './Unstable_Grid'; export { default as Stack } from './Stack'; export * from './Stack'; - -/** ----------------- */ -/** Unstable APIs */ -export { default as unstable_cssContainerQueries } from './cssContainerQueries'; diff --git a/packages/mui-system/src/index.js b/packages/mui-system/src/index.js index 468b101f04e40c..8bc93c6d64d0c9 100644 --- a/packages/mui-system/src/index.js +++ b/packages/mui-system/src/index.js @@ -5,6 +5,7 @@ export { default as GlobalStyles } from './GlobalStyles'; export { default as borders } from './borders'; export * from './borders'; export { default as breakpoints } from './breakpoints'; +export { default as cssContainerQueries } from './cssContainerQueries'; export { handleBreakpoints, mergeBreakpointsInOrder, @@ -78,7 +79,3 @@ export * from './Unstable_Grid'; export { default as Stack } from './Stack/Stack'; export * from './Stack'; - -/** ----------------- */ -/** Unstable APIs */ -export { default as unstable_cssContainerQueries } from './cssContainerQueries'; From c66c031b7f9954e7dc260667c5f7003c94d14b7c Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Wed, 27 Mar 2024 13:32:34 +0700 Subject: [PATCH 05/13] add demo --- .../the-sx-prop/the-sx-prop.md | 2 +- .../getting-started/usage/ContainerQueries.js | 88 +++++++++++++++++++ .../usage/ContainerQueries.tsx | 88 +++++++++++++++++++ .../system/getting-started/usage/usage.md | 13 +++ .../cssContainerQueries.ts | 10 +++ 5 files changed, 200 insertions(+), 1 deletion(-) create mode 100644 docs/data/system/getting-started/usage/ContainerQueries.js create mode 100644 docs/data/system/getting-started/usage/ContainerQueries.tsx diff --git a/docs/data/system/getting-started/the-sx-prop/the-sx-prop.md b/docs/data/system/getting-started/the-sx-prop/the-sx-prop.md index a3e75054c37355..17b147787e83b6 100644 --- a/docs/data/system/getting-started/the-sx-prop/the-sx-prop.md +++ b/docs/data/system/getting-started/the-sx-prop/the-sx-prop.md @@ -179,7 +179,7 @@ Read more on the [Typography page](/system/typography/). ## Responsive values -All properties associated with the `sx` prop also support responsive values for specific breakpoints. +All properties associated with the `sx` prop also support responsive values for specific breakpoints and container queries. Read more on the [Usage page—Responsive values](/system/getting-started/usage/#responsive-values). diff --git a/docs/data/system/getting-started/usage/ContainerQueries.js b/docs/data/system/getting-started/usage/ContainerQueries.js new file mode 100644 index 00000000000000..6583a061eba48b --- /dev/null +++ b/docs/data/system/getting-started/usage/ContainerQueries.js @@ -0,0 +1,88 @@ +import * as React from 'react'; +import Box from '@mui/material/Box'; + +export default function ContainerQueries() { + return ( + + + + +
+ + 123 Main St, Phoenix AZ + + + $280,000 — $310,000 + +
+ + Confidence score: 85% + +
+
+
+ ); +} diff --git a/docs/data/system/getting-started/usage/ContainerQueries.tsx b/docs/data/system/getting-started/usage/ContainerQueries.tsx new file mode 100644 index 00000000000000..6583a061eba48b --- /dev/null +++ b/docs/data/system/getting-started/usage/ContainerQueries.tsx @@ -0,0 +1,88 @@ +import * as React from 'react'; +import Box from '@mui/material/Box'; + +export default function ContainerQueries() { + return ( + + + + +
+ + 123 Main St, Phoenix AZ + + + $280,000 — $310,000 + +
+ + Confidence score: 85% + +
+
+
+ ); +} diff --git a/docs/data/system/getting-started/usage/usage.md b/docs/data/system/getting-started/usage/usage.md index 487340ad2b1585..c41a71a6b92e69 100644 --- a/docs/data/system/getting-started/usage/usage.md +++ b/docs/data/system/getting-started/usage/usage.md @@ -291,6 +291,19 @@ The following demo shows how to define a set of breakpoints using the object syn {{"demo": "BreakpointsAsObject.js"}} +:::info +📣 Starting from v6, the object structure supports [container queries](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_containment/Container_queries) shorthand with `cq`. + +We recommend you to check the [browser support](https://caniuse.com/?search=container%20que) before using CSS container queries. +::: + +The shorthand syntax is `cq@{breakpoint}/{container}`: + +- **breakpoint**: a number for `px` unit or a breakpoint key (e.g. `sm`, `md`, `lg`, `xl` for default breakpoints) or a valid CSS value (e.g. `40em`). +- **container** (optional): the name of the [containment context](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_containment/Container_queries#naming_containment_contexts). + +{{"demo": "ContainerQueries.js"}} + #### Breakpoints as an array The second option is to define your breakpoints as an array, from smallest to largest. diff --git a/packages/mui-system/src/cssContainerQueries/cssContainerQueries.ts b/packages/mui-system/src/cssContainerQueries/cssContainerQueries.ts index eea6cc815eb4e8..e39bfa57c8ea56 100644 --- a/packages/mui-system/src/cssContainerQueries/cssContainerQueries.ts +++ b/packages/mui-system/src/cssContainerQueries/cssContainerQueries.ts @@ -7,6 +7,9 @@ interface CssContainerQueries { cq: ((name: string) => Pick) & Pick; } +/** + * A wrapper of the `breakpoints`'s utilities to create container queries. + */ function createBreakpointToCQ }>(themeInput: T) { return function toContainerQuery(key: Fn, name?: string) { return (...args: Array) => { @@ -16,6 +19,7 @@ function createBreakpointToCQ }>(t name ? `@container ${name}` : '@container', ); if (key === 'not' && result.includes('not all and')) { + // `@container` does not work with `not all and`, so need to invert the logic return result .replace('not all and ', '') .replace('min-width:', 'width<') @@ -26,6 +30,12 @@ function createBreakpointToCQ }>(t }; } +/** + * For using in `sx` prop to sort the breakpoint from low to high. + * Note: this function does not work and will not support multiple units. + * e.g. input: { '@container (min-width:300px)': '1rem', '@container (min-width:40rem)': '2rem' } + * output: { '@container (min-width:40rem)': '2rem', '@container (min-width:300px)': '1rem' } // since 40 < 300 eventhough 40rem > 300px + */ export function sortContainerQueries( theme: Partial, css: Record, From 235a5c3a943e35133d9644aff8150cf5adf9e423 Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Wed, 27 Mar 2024 14:08:32 +0700 Subject: [PATCH 06/13] remove cq prefix --- .../getting-started/usage/ContainerQueries.js | 6 +-- .../usage/ContainerQueries.tsx | 6 +-- .../system/getting-started/usage/usage.md | 4 +- docs/public/static/error-codes.json | 4 +- .../mui-system/src/breakpoints/breakpoints.js | 4 +- .../cssContainerQueries.test.ts | 20 +++++++- .../cssContainerQueries.ts | 47 ++++++++++--------- .../src/cssContainerQueries/index.ts | 2 +- .../mui-system/src/cssGrid/cssGrid.test.js | 6 +-- .../mui-system/src/spacing/spacing.test.js | 6 +-- .../styleFunctionSx/styleFunctionSx.test.js | 24 +++++----- 11 files changed, 75 insertions(+), 54 deletions(-) diff --git a/docs/data/system/getting-started/usage/ContainerQueries.js b/docs/data/system/getting-started/usage/ContainerQueries.js index 6583a061eba48b..aa1e523a0989e4 100644 --- a/docs/data/system/getting-started/usage/ContainerQueries.js +++ b/docs/data/system/getting-started/usage/ContainerQueries.js @@ -15,7 +15,7 @@ export default function ContainerQueries() { ", "20": "MUI: The `experimental_sx` has been moved to `theme.unstable_sx`.For more details, see https://github.com/mui/material-ui/pull/35150.", - "21": "MUI: The provided shorthand %s is invalid. The format should be `cq@` or `cq@/`.\nFor example, `cq@sm` or `cq@600` or `cq@40rem/sidebar`." -} \ No newline at end of file + "21": "MUI: The provided shorthand %s is invalid. The format should be `@{breakpoint | number}` or `@{breakpoint | number}/{container}`.\nFor example, `@sm` or `@600` or `@40rem/sidebar`." +} diff --git a/packages/mui-system/src/breakpoints/breakpoints.js b/packages/mui-system/src/breakpoints/breakpoints.js index 8e6256a2d3a4d4..dd453f19340e14 100644 --- a/packages/mui-system/src/breakpoints/breakpoints.js +++ b/packages/mui-system/src/breakpoints/breakpoints.js @@ -1,7 +1,7 @@ import PropTypes from 'prop-types'; import deepmerge from '@mui/utils/deepmerge'; import merge from '../merge'; -import { getContainerQuery } from '../cssContainerQueries'; +import { isCqShorthand, getContainerQuery } from '../cssContainerQueries'; // The breakpoint **start** at this value. // For instance with the first breakpoint xs: [xs, sm[. @@ -42,7 +42,7 @@ export function handleBreakpoints(props, propValue, styleFromPropValue) { if (typeof propValue === 'object') { const themeBreakpoints = theme.breakpoints || defaultBreakpoints; return Object.keys(propValue).reduce((acc, breakpoint) => { - if (breakpoint.startsWith('cq')) { + if (isCqShorthand(themeBreakpoints.keys, breakpoint)) { const containerKey = getContainerQuery({ breakpoints: themeBreakpoints }, breakpoint); if (containerKey) { acc[containerKey] = styleFromPropValue(propValue[breakpoint], breakpoint); diff --git a/packages/mui-system/src/cssContainerQueries/cssContainerQueries.test.ts b/packages/mui-system/src/cssContainerQueries/cssContainerQueries.test.ts index 17763ad060c951..1cdb811727598d 100644 --- a/packages/mui-system/src/cssContainerQueries/cssContainerQueries.test.ts +++ b/packages/mui-system/src/cssContainerQueries/cssContainerQueries.test.ts @@ -2,11 +2,27 @@ import { expect } from 'chai'; import createTheme from '@mui/system/createTheme'; import cssContainerQueries, { + isCqShorthand, sortContainerQueries, getContainerQuery, } from '@mui/system/cssContainerQueries'; describe('cssContainerQueries', () => { + it('should return false if the shorthand is not a container query', () => { + expect(isCqShorthand(['xs', 'sm', 'md'], '@container (min-width:600px)')).to.equal(false); + expect(isCqShorthand(['xs', 'sm', 'md'], '@media (min-width:600px)')).to.equal(false); + expect(isCqShorthand(['xs', 'sm', 'md'], '@page')).to.equal(false); + expect(isCqShorthand(['xs', 'sm', 'md'], '@support (display: flex)')).to.equal(false); + }); + + it('should return true if the shorthand is a container query', () => { + expect(isCqShorthand(['xs', 'sm', 'md'], '@xs')).to.equal(true); + expect(isCqShorthand(['xs', 'sm', 'md'], '@xs/sidebar')).to.equal(true); + expect(isCqShorthand(['xs', 'sm', 'md'], '@md')).to.equal(true); + expect(isCqShorthand(['xs', 'sm', 'md'], '@200')).to.equal(true); + expect(isCqShorthand(['xs', 'sm', 'md'], '@15.5rem')).to.equal(true); + }); + it('should have `up`, `down`, `between`, `only`, and `not` functions', () => { const theme = cssContainerQueries(createTheme()); @@ -84,8 +100,8 @@ describe('cssContainerQueries', () => { const theme = cssContainerQueries(createTheme()); getContainerQuery(theme, 'cq0'); }).to.throw( - 'MUI: The provided shorthand (cq0) is invalid. The format should be `cq@` or `cq@/`.\n' + - 'For example, `cq@sm` or `cq@600` or `cq@40rem/sidebar`.', + 'MUI: The provided shorthand (cq0) is invalid. The format should be `@` or `@/`.\n' + + 'For example, `@sm` or `@600` or `@40rem/sidebar`.', ); }); }); diff --git a/packages/mui-system/src/cssContainerQueries/cssContainerQueries.ts b/packages/mui-system/src/cssContainerQueries/cssContainerQueries.ts index e39bfa57c8ea56..3767df0b6a6210 100644 --- a/packages/mui-system/src/cssContainerQueries/cssContainerQueries.ts +++ b/packages/mui-system/src/cssContainerQueries/cssContainerQueries.ts @@ -63,32 +63,37 @@ export function sortContainerQueries( ); } +export function isCqShorthand(breakpointKeys: string[], value: string) { + return ( + value.startsWith('@') && + (breakpointKeys.some((key) => value.startsWith(`@${key}`)) || !!value.match(/^@\d/)) + ); +} + export function getContainerQuery( theme: Partial & { breakpoints: Pick }, shorthand: string, ) { - if (shorthand.startsWith('cq')) { - const matches = shorthand.match(/@([^/\n]+)\/?(.+)?/); - if (!matches) { - if (process.env.NODE_ENV !== 'production') { - throw new MuiError( - 'MUI: The provided shorthand %s is invalid. The format should be `cq@` or `cq@/`.\n' + - 'For example, `cq@sm` or `cq@600` or `cq@40rem/sidebar`.', - `(${shorthand})`, - ); - } - return null; - } - const [, containerQuery, containerName] = matches; - const value = (Number.isNaN(+containerQuery) ? containerQuery : +containerQuery) as - | Breakpoint - | number; - if (theme.cq) { - return containerName ? theme.cq(containerName).up(value) : theme.cq.up(value); - } - if (theme.breakpoints) { - return createBreakpointToCQ(theme)('up', containerName)(value); + const matches = shorthand.match(/^@([^/]+)\/?(.+)?$/); + if (!matches) { + if (process.env.NODE_ENV !== 'production') { + throw new MuiError( + 'MUI: The provided shorthand %s is invalid. The format should be `@` or `@/`.\n' + + 'For example, `@sm` or `@600` or `@40rem/sidebar`.', + `(${shorthand})`, + ); } + return null; + } + const [, containerQuery, containerName] = matches; + const value = (Number.isNaN(+containerQuery) ? containerQuery : +containerQuery) as + | Breakpoint + | number; + if (theme.cq) { + return containerName ? theme.cq(containerName).up(value) : theme.cq.up(value); + } + if (theme.breakpoints) { + return createBreakpointToCQ(theme)('up', containerName)(value); } return null; } diff --git a/packages/mui-system/src/cssContainerQueries/index.ts b/packages/mui-system/src/cssContainerQueries/index.ts index 4041c121b3aa3f..16c617f5c9cebd 100644 --- a/packages/mui-system/src/cssContainerQueries/index.ts +++ b/packages/mui-system/src/cssContainerQueries/index.ts @@ -1,2 +1,2 @@ export { default } from './cssContainerQueries'; -export { getContainerQuery, sortContainerQueries } from './cssContainerQueries'; +export { isCqShorthand, getContainerQuery, sortContainerQueries } from './cssContainerQueries'; diff --git a/packages/mui-system/src/cssGrid/cssGrid.test.js b/packages/mui-system/src/cssGrid/cssGrid.test.js index 1a8dff573d3801..62266bcdfb42c4 100644 --- a/packages/mui-system/src/cssGrid/cssGrid.test.js +++ b/packages/mui-system/src/cssGrid/cssGrid.test.js @@ -41,9 +41,9 @@ describe('grid', () => { it('should support container queries', () => { const output1 = grid({ gap: { - 'cq@sm': 1, - 'cq@900/sidebar': 2, - 'cq@80rem/sidebar': 3, + '@sm': 1, + '@900/sidebar': 2, + '@80rem/sidebar': 3, }, }); expect(output1).to.deep.equal({ diff --git a/packages/mui-system/src/spacing/spacing.test.js b/packages/mui-system/src/spacing/spacing.test.js index c41527e6bbe636..ed9f6a1423c9af 100644 --- a/packages/mui-system/src/spacing/spacing.test.js +++ b/packages/mui-system/src/spacing/spacing.test.js @@ -157,9 +157,9 @@ describe('system spacing', () => { it('should support container queries', () => { const output1 = spacing({ p: { - 'cq@sm': 1, - 'cq@900/sidebar': 2, - 'cq@80rem/sidebar': 3, + '@sm': 1, + '@900/sidebar': 2, + '@80rem/sidebar': 3, }, }); expect(output1).to.deep.equal({ diff --git a/packages/mui-system/src/styleFunctionSx/styleFunctionSx.test.js b/packages/mui-system/src/styleFunctionSx/styleFunctionSx.test.js index 6b6d28e2f383e7..d8ca1d7a8e778e 100644 --- a/packages/mui-system/src/styleFunctionSx/styleFunctionSx.test.js +++ b/packages/mui-system/src/styleFunctionSx/styleFunctionSx.test.js @@ -258,11 +258,11 @@ describe('styleFunctionSx', () => { theme, sx: { border: { - 'cq@xs': 1, - 'cq@sm': 2, - 'cq@md': 3, - 'cq@lg': 4, - 'cq@xl': 5, + '@xs': 1, + '@sm': 2, + '@md': 3, + '@lg': 4, + '@xl': 5, }, }, }); @@ -275,14 +275,14 @@ describe('styleFunctionSx', () => { theme, sx: { m: { - 'cq@xs': 1, - 'cq@sm': 2, - 'cq@md': 3, + '@xs': 1, + '@sm': 2, + '@md': 3, }, p: { - 'cq@xs': 5, - 'cq@sm': 6, - 'cq@md': 7, + '@xs': 5, + '@sm': 6, + '@md': 7, }, }, }); @@ -297,7 +297,7 @@ describe('styleFunctionSx', () => { it('writes queries in correct order', () => { const result = styleFunctionSx({ theme, - sx: { m: { 'cq@md': 1, 'cq@lg': 2 }, p: { 'cq@xs': 0, 'cq@sm': 1, 'cq@md': 2 } }, + sx: { m: { '@md': 1, '@lg': 2 }, p: { '@xs': 0, '@sm': 1, '@md': 2 } }, }); // Test the order From 1ae42b4f06a6fd5a6e87116be5b3a8fc3c97964f Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Wed, 3 Apr 2024 12:05:14 +0700 Subject: [PATCH 07/13] make container queries as default --- packages/mui-joy/src/styles/index.ts | 1 - packages/mui-joy/src/styles/types/theme.ts | 3 ++- packages/mui-material/src/styles/index.d.ts | 1 - packages/mui-material/src/styles/index.js | 1 - .../mui-system/src/breakpoints/breakpoints.js | 10 +------ .../src/createTheme/createTheme.d.ts | 3 ++- .../mui-system/src/createTheme/createTheme.js | 2 ++ .../cssContainerQueries.test.ts | 12 ++++----- .../cssContainerQueries.ts | 27 +++++++++---------- .../src/cssContainerQueries/index.ts | 1 + packages/mui-system/src/index.d.ts | 2 +- 11 files changed, 27 insertions(+), 36 deletions(-) diff --git a/packages/mui-joy/src/styles/index.ts b/packages/mui-joy/src/styles/index.ts index 71aa400ee9c573..82fd57ca9ee0da 100644 --- a/packages/mui-joy/src/styles/index.ts +++ b/packages/mui-joy/src/styles/index.ts @@ -1,6 +1,5 @@ 'use client'; // reexports from system for module augmentation -export { cssContainerQueries } from '@mui/system'; export type { BreakpointOverrides } from '@mui/system'; // Joy typings diff --git a/packages/mui-joy/src/styles/types/theme.ts b/packages/mui-joy/src/styles/types/theme.ts index 511a5d61f8f025..ea33f34fb6f7a0 100644 --- a/packages/mui-joy/src/styles/types/theme.ts +++ b/packages/mui-joy/src/styles/types/theme.ts @@ -1,6 +1,7 @@ import { OverridableStringUnion } from '@mui/types'; import { Breakpoints, + CssContainerQueries, Spacing, SxProps as SystemSxProps, SystemProps as SystemSystemProps, @@ -95,7 +96,7 @@ export type TextColor = export type ThemeCssVar = OverridableStringUnion, ThemeCssVarOverrides>; -export interface Theme extends ThemeScales, RuntimeColorSystem { +export interface Theme extends ThemeScales, RuntimeColorSystem, CssContainerQueries { colorSchemes: Record; defaultColorScheme: DefaultColorScheme | ExtendedColorScheme; focus: Focus; diff --git a/packages/mui-material/src/styles/index.d.ts b/packages/mui-material/src/styles/index.d.ts index 0760a670c2b522..234aed07d592ce 100644 --- a/packages/mui-material/src/styles/index.d.ts +++ b/packages/mui-material/src/styles/index.d.ts @@ -65,7 +65,6 @@ export { ColorObject, StyledEngineProvider, SxProps, - cssContainerQueries, } from '@mui/system'; // TODO: Remove this function in v6. // eslint-disable-next-line @typescript-eslint/naming-convention diff --git a/packages/mui-material/src/styles/index.js b/packages/mui-material/src/styles/index.js index ee77c68e6e0b5b..42e3a789b6c13c 100644 --- a/packages/mui-material/src/styles/index.js +++ b/packages/mui-material/src/styles/index.js @@ -17,7 +17,6 @@ export { lighten, css, keyframes, - cssContainerQueries, } from '@mui/system'; // TODO: Remove this function in v6. // eslint-disable-next-line @typescript-eslint/naming-convention diff --git a/packages/mui-system/src/breakpoints/breakpoints.js b/packages/mui-system/src/breakpoints/breakpoints.js index dd453f19340e14..7d3a3bb351f628 100644 --- a/packages/mui-system/src/breakpoints/breakpoints.js +++ b/packages/mui-system/src/breakpoints/breakpoints.js @@ -17,15 +17,7 @@ const defaultBreakpoints = { // Sorted ASC by size. That's important. // It can't be configured as it's used statically for propTypes. keys: ['xs', 'sm', 'md', 'lg', 'xl'], - up: (key) => { - let result = typeof key === 'number' ? key : values[key]; - if (typeof result === 'number') { - result = `${result}px`; - } else { - result = key; - } - return `@media (min-width:${result})`; - }, + up: (key) => `@media (min-width:${values[key]}px)`, }; export function handleBreakpoints(props, propValue, styleFromPropValue) { diff --git a/packages/mui-system/src/createTheme/createTheme.d.ts b/packages/mui-system/src/createTheme/createTheme.d.ts index aee763ec114398..0d6d555539d1b9 100644 --- a/packages/mui-system/src/createTheme/createTheme.d.ts +++ b/packages/mui-system/src/createTheme/createTheme.d.ts @@ -4,6 +4,7 @@ import { Shape, ShapeOptions } from './shape'; import { Spacing, SpacingOptions } from './createSpacing'; import { SxConfig, SxProps } from '../styleFunctionSx'; import { ApplyStyles } from './applyStyles'; +import { CssContainerQueries } from '../cssContainerQueries'; export { Breakpoint, BreakpointOverrides } from './createBreakpoints'; @@ -24,7 +25,7 @@ export interface ThemeOptions { unstable_sxConfig?: SxConfig; } -export interface Theme { +export interface Theme extends CssContainerQueries { shape: Shape; breakpoints: Breakpoints; direction: Direction; diff --git a/packages/mui-system/src/createTheme/createTheme.js b/packages/mui-system/src/createTheme/createTheme.js index 24c1c4d29971cc..dce4ff93cc428d 100644 --- a/packages/mui-system/src/createTheme/createTheme.js +++ b/packages/mui-system/src/createTheme/createTheme.js @@ -1,5 +1,6 @@ import deepmerge from '@mui/utils/deepmerge'; import createBreakpoints from './createBreakpoints'; +import cssContainerQueries from '../cssContainerQueries'; import shape from './shape'; import createSpacing from './createSpacing'; import styleFunctionSx from '../styleFunctionSx/styleFunctionSx'; @@ -29,6 +30,7 @@ function createTheme(options = {}, ...args) { }, other, ); + muiTheme = cssContainerQueries(muiTheme); muiTheme.applyStyles = applyStyles; diff --git a/packages/mui-system/src/cssContainerQueries/cssContainerQueries.test.ts b/packages/mui-system/src/cssContainerQueries/cssContainerQueries.test.ts index 1cdb811727598d..b1e901480e0c63 100644 --- a/packages/mui-system/src/cssContainerQueries/cssContainerQueries.test.ts +++ b/packages/mui-system/src/cssContainerQueries/cssContainerQueries.test.ts @@ -1,7 +1,7 @@ import { expect } from 'chai'; import createTheme from '@mui/system/createTheme'; -import cssContainerQueries, { +import { isCqShorthand, sortContainerQueries, getContainerQuery, @@ -24,7 +24,7 @@ describe('cssContainerQueries', () => { }); it('should have `up`, `down`, `between`, `only`, and `not` functions', () => { - const theme = cssContainerQueries(createTheme()); + const theme = createTheme(); expect(theme.cq.up('sm')).to.equal('@container (min-width:600px)'); expect(theme.cq.down('sm')).to.equal('@container (max-width:599.95px)'); @@ -38,7 +38,7 @@ describe('cssContainerQueries', () => { }); it('should be able to create named containment context', () => { - const theme = cssContainerQueries(createTheme()); + const theme = createTheme(); expect(theme.cq('sidebar').up('sm')).to.equal('@container sidebar (min-width:600px)'); expect(theme.cq('sidebar').down('sm')).to.equal('@container sidebar (max-width:599.95px)'); @@ -56,7 +56,7 @@ describe('cssContainerQueries', () => { }); it('should sort container queries', () => { - const theme = cssContainerQueries(createTheme()); + const theme = createTheme(); const css = { '@container (min-width:960px)': {}, @@ -76,7 +76,7 @@ describe('cssContainerQueries', () => { }); it('should sort container queries with other unit', () => { - const theme = cssContainerQueries(createTheme()); + const theme = createTheme(); const css = { '@container (min-width:30.5rem)': {}, @@ -97,7 +97,7 @@ describe('cssContainerQueries', () => { it('should throw an error if shorthand is invalid', () => { expect(() => { - const theme = cssContainerQueries(createTheme()); + const theme = createTheme(); getContainerQuery(theme, 'cq0'); }).to.throw( 'MUI: The provided shorthand (cq0) is invalid. The format should be `@` or `@/`.\n' + diff --git a/packages/mui-system/src/cssContainerQueries/cssContainerQueries.ts b/packages/mui-system/src/cssContainerQueries/cssContainerQueries.ts index 3767df0b6a6210..3609edb7d1b80e 100644 --- a/packages/mui-system/src/cssContainerQueries/cssContainerQueries.ts +++ b/packages/mui-system/src/cssContainerQueries/cssContainerQueries.ts @@ -1,17 +1,23 @@ import MuiError from '@mui/internal-babel-macros/MuiError.macro'; import { Breakpoints, Breakpoint } from '../createTheme/createBreakpoints'; -type Fn = 'up' | 'down' | 'between' | 'only' | 'not'; +interface ContainerQueries { + up: Breakpoints['up']; + down: Breakpoints['down']; + between: Breakpoints['between']; + only: Breakpoints['only']; + not: Breakpoints['not']; +} -interface CssContainerQueries { - cq: ((name: string) => Pick) & Pick; +export interface CssContainerQueries { + cq: ((name: string) => ContainerQueries) & ContainerQueries; } /** * A wrapper of the `breakpoints`'s utilities to create container queries. */ function createBreakpointToCQ }>(themeInput: T) { - return function toContainerQuery(key: Fn, name?: string) { + return function toContainerQuery(key: keyof ContainerQueries, name?: string) { return (...args: Array) => { // @ts-ignore const result = themeInput.breakpoints[key](...args).replace( @@ -70,10 +76,7 @@ export function isCqShorthand(breakpointKeys: string[], value: string) { ); } -export function getContainerQuery( - theme: Partial & { breakpoints: Pick }, - shorthand: string, -) { +export function getContainerQuery(theme: CssContainerQueries, shorthand: string) { const matches = shorthand.match(/^@([^/]+)\/?(.+)?$/); if (!matches) { if (process.env.NODE_ENV !== 'production') { @@ -89,13 +92,7 @@ export function getContainerQuery( const value = (Number.isNaN(+containerQuery) ? containerQuery : +containerQuery) as | Breakpoint | number; - if (theme.cq) { - return containerName ? theme.cq(containerName).up(value) : theme.cq.up(value); - } - if (theme.breakpoints) { - return createBreakpointToCQ(theme)('up', containerName)(value); - } - return null; + return theme.cq(containerName).up(value); } export default function cssContainerQueries( diff --git a/packages/mui-system/src/cssContainerQueries/index.ts b/packages/mui-system/src/cssContainerQueries/index.ts index 16c617f5c9cebd..e1061e417fc187 100644 --- a/packages/mui-system/src/cssContainerQueries/index.ts +++ b/packages/mui-system/src/cssContainerQueries/index.ts @@ -1,2 +1,3 @@ export { default } from './cssContainerQueries'; export { isCqShorthand, getContainerQuery, sortContainerQueries } from './cssContainerQueries'; +export type { CssContainerQueries } from './cssContainerQueries'; diff --git a/packages/mui-system/src/index.d.ts b/packages/mui-system/src/index.d.ts index 22df2b0ef7a81d..ec606cc14d467b 100644 --- a/packages/mui-system/src/index.d.ts +++ b/packages/mui-system/src/index.d.ts @@ -5,7 +5,7 @@ export * from './borders'; export { default as breakpoints, handleBreakpoints, mergeBreakpointsInOrder } from './breakpoints'; -export { default as cssContainerQueries } from './cssContainerQueries'; +export { default as cssContainerQueries, type CssContainerQueries } from './cssContainerQueries'; export { default as compose } from './compose'; From 2602d28861c1bf7cc6e451e3eafece739f5d01bb Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Wed, 3 Apr 2024 13:16:51 +0700 Subject: [PATCH 08/13] simplify logic --- .../mui-system/src/breakpoints/breakpoints.js | 19 ++++- .../cssContainerQueries.ts | 70 +++++++++---------- 2 files changed, 52 insertions(+), 37 deletions(-) diff --git a/packages/mui-system/src/breakpoints/breakpoints.js b/packages/mui-system/src/breakpoints/breakpoints.js index 7d3a3bb351f628..c87133ab8df2f9 100644 --- a/packages/mui-system/src/breakpoints/breakpoints.js +++ b/packages/mui-system/src/breakpoints/breakpoints.js @@ -20,6 +20,20 @@ const defaultBreakpoints = { up: (key) => `@media (min-width:${values[key]}px)`, }; +const defaultContainerQueries = { + cq: (containerName) => ({ + up: (key) => { + let result = typeof key === 'number' ? key : values[key] || key; + if (typeof result === 'number') { + result = `${result}px`; + } + return containerName + ? `@container ${containerName} (min-width:${result})` + : `@container (min-width:${result})`; + }, + }), +}; + export function handleBreakpoints(props, propValue, styleFromPropValue) { const theme = props.theme || {}; @@ -35,7 +49,10 @@ export function handleBreakpoints(props, propValue, styleFromPropValue) { const themeBreakpoints = theme.breakpoints || defaultBreakpoints; return Object.keys(propValue).reduce((acc, breakpoint) => { if (isCqShorthand(themeBreakpoints.keys, breakpoint)) { - const containerKey = getContainerQuery({ breakpoints: themeBreakpoints }, breakpoint); + const containerKey = getContainerQuery( + theme.cq ? theme : defaultContainerQueries, + breakpoint, + ); if (containerKey) { acc[containerKey] = styleFromPropValue(propValue[breakpoint], breakpoint); } diff --git a/packages/mui-system/src/cssContainerQueries/cssContainerQueries.ts b/packages/mui-system/src/cssContainerQueries/cssContainerQueries.ts index 3609edb7d1b80e..6fa078523b298f 100644 --- a/packages/mui-system/src/cssContainerQueries/cssContainerQueries.ts +++ b/packages/mui-system/src/cssContainerQueries/cssContainerQueries.ts @@ -13,29 +13,6 @@ export interface CssContainerQueries { cq: ((name: string) => ContainerQueries) & ContainerQueries; } -/** - * A wrapper of the `breakpoints`'s utilities to create container queries. - */ -function createBreakpointToCQ }>(themeInput: T) { - return function toContainerQuery(key: keyof ContainerQueries, name?: string) { - return (...args: Array) => { - // @ts-ignore - const result = themeInput.breakpoints[key](...args).replace( - '@media', - name ? `@container ${name}` : '@container', - ); - if (key === 'not' && result.includes('not all and')) { - // `@container` does not work with `not all and`, so need to invert the logic - return result - .replace('not all and ', '') - .replace('min-width:', 'width<') - .replace('max-width:', 'width>'); - } - return result; - }; - }; -} - /** * For using in `sx` prop to sort the breakpoint from low to high. * Note: this function does not work and will not support multiple units. @@ -98,21 +75,42 @@ export function getContainerQuery(theme: CssContainerQueries, shorthand: string) export default function cssContainerQueries( themeInput: T, ): T & CssContainerQueries { - const toContainerQuery = createBreakpointToCQ(themeInput); - function cq(name: string) { - return { - up: toContainerQuery('up', name), - down: toContainerQuery('down', name), - between: toContainerQuery('between', name), - only: toContainerQuery('only', name), - not: toContainerQuery('not', name), + const toContainerQuery = (mediaQuery: string, name?: string) => + mediaQuery.replace('@media', name ? `@container ${name}` : '@container'); + + function attachCq(node: any, name?: string) { + node.up = (...args: Parameters) => + toContainerQuery(themeInput.breakpoints.up(...args), name); + + node.down = (...args: Parameters) => + toContainerQuery(themeInput.breakpoints.down(...args), name); + + node.between = (...args: Parameters) => + toContainerQuery(themeInput.breakpoints.between(...args), name); + + node.only = (...args: Parameters) => + toContainerQuery(themeInput.breakpoints.only(...args), name); + + node.not = (...args: Parameters) => { + const result = toContainerQuery(themeInput.breakpoints.not(...args), name); + if (result.includes('not all and')) { + // `@container` does not work with `not all and`, so need to invert the logic + return result + .replace('not all and ', '') + .replace('min-width:', 'width<') + .replace('max-width:', 'width>'); + } + return result; }; } - cq.up = toContainerQuery('up'); - cq.down = toContainerQuery('down'); - cq.between = toContainerQuery('between'); - cq.only = toContainerQuery('only'); - cq.not = toContainerQuery('not'); + const node = {}; + const cq = ((name: string) => { + attachCq(node, name); + return node; + }) as CssContainerQueries['cq']; + + attachCq(cq); + return { ...themeInput, cq, From 7a88670322637ccea77f130b158864950c137cb4 Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Wed, 3 Apr 2024 13:24:24 +0700 Subject: [PATCH 09/13] add containerQueries to Joy theme --- packages/mui-joy/src/styles/extendTheme.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/mui-joy/src/styles/extendTheme.ts b/packages/mui-joy/src/styles/extendTheme.ts index 7404c27310ef29..eb73ba81d40c2d 100644 --- a/packages/mui-joy/src/styles/extendTheme.ts +++ b/packages/mui-joy/src/styles/extendTheme.ts @@ -10,6 +10,7 @@ import { unstable_styleFunctionSx as styleFunctionSx, SxConfig, } from '@mui/system'; +import cssContainerQueries from '@mui/system/cssContainerQueries'; import { unstable_applyStyles as applyStyles } from '@mui/system/createTheme'; import { createUnarySpacing } from '@mui/system/spacing'; import defaultSxConfig from './sxConfig'; @@ -559,7 +560,7 @@ export default function extendTheme(themeOptions?: CssVarsThemeOptions): Theme { ? deepmerge(defaultScales, scalesInput) : defaultScales; - const theme = { + let theme = { colorSchemes, defaultColorScheme: 'light', ...mergedScales, @@ -605,6 +606,7 @@ export default function extendTheme(themeOptions?: CssVarsThemeOptions): Theme { getCssVar, spacing: getSpacingVal(spacing), } as unknown as Theme & { attribute: string; colorSchemeSelector: string }; // Need type casting due to module augmentation inside the repo + theme = cssContainerQueries(theme); /** Color channels generation From e77155d15e9733241bd60fd50606af269ca06c61 Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Wed, 3 Apr 2024 13:27:57 +0700 Subject: [PATCH 10/13] add more tests --- packages/mui-joy/src/styles/defaultTheme.test.js | 6 ++++++ .../src/styles/experimental_extendTheme.test.js | 8 ++++++++ 2 files changed, 14 insertions(+) diff --git a/packages/mui-joy/src/styles/defaultTheme.test.js b/packages/mui-joy/src/styles/defaultTheme.test.js index 25469909a49cd6..242721a724e42d 100644 --- a/packages/mui-joy/src/styles/defaultTheme.test.js +++ b/packages/mui-joy/src/styles/defaultTheme.test.js @@ -9,6 +9,7 @@ describe('defaultTheme', () => { 'colorSchemeSelector', 'defaultColorScheme', 'breakpoints', + 'cq', 'components', 'colorSchemes', 'focus', @@ -46,4 +47,9 @@ describe('defaultTheme', () => { expect(defaultTheme.palette.mode).to.equal('light'); expect(defaultTheme.palette.colorScheme).to.equal('light'); }); + + it('has `cq` in the theme', () => { + expect(defaultTheme.cq('sidebar').up('sm')).to.equal('@container sidebar (min-width:600px)'); + expect(defaultTheme.cq.up(300)).to.equal('@container (min-width:300px)'); + }); }); diff --git a/packages/mui-material/src/styles/experimental_extendTheme.test.js b/packages/mui-material/src/styles/experimental_extendTheme.test.js index 297418eea7ada1..2eff852b6eb1da 100644 --- a/packages/mui-material/src/styles/experimental_extendTheme.test.js +++ b/packages/mui-material/src/styles/experimental_extendTheme.test.js @@ -408,6 +408,14 @@ describe('experimental_extendTheme', () => { }); }); + describe('container queries', () => { + it('should generate container queries', () => { + const theme = extendTheme(); + expect(theme.cq('sidebar').up('sm')).to.equal('@container sidebar (min-width:600px)'); + expect(theme.cq.up(300)).to.equal('@container (min-width:300px)'); + }); + }); + it('shallow merges multiple arguments', () => { const theme = extendTheme({ foo: 'I am foo' }, { bar: 'I am bar' }); expect(theme.foo).to.equal('I am foo'); From 4493ee98a51d9cb6b59b333b1d792b811dfd47ca Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Mon, 8 Apr 2024 16:38:47 +0700 Subject: [PATCH 11/13] add cq field to test --- packages/mui-joy/src/styles/extendTheme.test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/mui-joy/src/styles/extendTheme.test.js b/packages/mui-joy/src/styles/extendTheme.test.js index c13f29d5c99315..037e430cfdd96d 100644 --- a/packages/mui-joy/src/styles/extendTheme.test.js +++ b/packages/mui-joy/src/styles/extendTheme.test.js @@ -10,6 +10,7 @@ describe('extendTheme', () => { expect([ 'attribute', 'breakpoints', + 'cq', 'colorSchemeSelector', 'components', 'colorSchemes', From 07907de6cfca6101366552bf1e48a5a344a55e45 Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Tue, 9 Apr 2024 16:28:38 +0700 Subject: [PATCH 12/13] pnpm extract-error-codes --- docs/public/static/error-codes.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/public/static/error-codes.json b/docs/public/static/error-codes.json index ed72d9fe2297f2..c5acc584689575 100644 --- a/docs/public/static/error-codes.json +++ b/docs/public/static/error-codes.json @@ -19,5 +19,5 @@ "18": "MUI: `vars` is a private field used for CSS variables support.\nPlease use another name.", "19": "MUI: `useColorScheme` must be called under ", "20": "MUI: The `experimental_sx` has been moved to `theme.unstable_sx`.For more details, see https://github.com/mui/material-ui/pull/35150.", - "21": "MUI: The provided shorthand %s is invalid. The format should be `@{breakpoint | number}` or `@{breakpoint | number}/{container}`.\nFor example, `@sm` or `@600` or `@40rem/sidebar`." + "21": "MUI: The provided shorthand %s is invalid. The format should be `@` or `@/`.\nFor example, `@sm` or `@600` or `@40rem/sidebar`." } From 7677ad0232f10b923a615abc5b4f806f183fb1ff Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Fri, 12 Apr 2024 09:31:40 +0700 Subject: [PATCH 13/13] change `cq` to `containerQueries` --- .../mui-joy/src/styles/defaultTheme.test.js | 10 +++-- .../mui-joy/src/styles/extendTheme.test.js | 2 +- .../styles/experimental_extendTheme.test.js | 6 ++- .../mui-system/src/breakpoints/breakpoints.js | 4 +- .../cssContainerQueries.test.ts | 40 ++++++++++++------- .../cssContainerQueries.ts | 14 +++---- 6 files changed, 46 insertions(+), 30 deletions(-) diff --git a/packages/mui-joy/src/styles/defaultTheme.test.js b/packages/mui-joy/src/styles/defaultTheme.test.js index 242721a724e42d..80e9c510728db0 100644 --- a/packages/mui-joy/src/styles/defaultTheme.test.js +++ b/packages/mui-joy/src/styles/defaultTheme.test.js @@ -9,7 +9,7 @@ describe('defaultTheme', () => { 'colorSchemeSelector', 'defaultColorScheme', 'breakpoints', - 'cq', + 'containerQueries', 'components', 'colorSchemes', 'focus', @@ -48,8 +48,10 @@ describe('defaultTheme', () => { expect(defaultTheme.palette.colorScheme).to.equal('light'); }); - it('has `cq` in the theme', () => { - expect(defaultTheme.cq('sidebar').up('sm')).to.equal('@container sidebar (min-width:600px)'); - expect(defaultTheme.cq.up(300)).to.equal('@container (min-width:300px)'); + it('has `containerQueries` in the theme', () => { + expect(defaultTheme.containerQueries('sidebar').up('sm')).to.equal( + '@container sidebar (min-width:600px)', + ); + expect(defaultTheme.containerQueries.up(300)).to.equal('@container (min-width:300px)'); }); }); diff --git a/packages/mui-joy/src/styles/extendTheme.test.js b/packages/mui-joy/src/styles/extendTheme.test.js index 037e430cfdd96d..4fcbb49a26e0a3 100644 --- a/packages/mui-joy/src/styles/extendTheme.test.js +++ b/packages/mui-joy/src/styles/extendTheme.test.js @@ -10,7 +10,7 @@ describe('extendTheme', () => { expect([ 'attribute', 'breakpoints', - 'cq', + 'containerQueries', 'colorSchemeSelector', 'components', 'colorSchemes', diff --git a/packages/mui-material/src/styles/experimental_extendTheme.test.js b/packages/mui-material/src/styles/experimental_extendTheme.test.js index 2eff852b6eb1da..0a942ae032eb23 100644 --- a/packages/mui-material/src/styles/experimental_extendTheme.test.js +++ b/packages/mui-material/src/styles/experimental_extendTheme.test.js @@ -411,8 +411,10 @@ describe('experimental_extendTheme', () => { describe('container queries', () => { it('should generate container queries', () => { const theme = extendTheme(); - expect(theme.cq('sidebar').up('sm')).to.equal('@container sidebar (min-width:600px)'); - expect(theme.cq.up(300)).to.equal('@container (min-width:300px)'); + expect(theme.containerQueries('sidebar').up('sm')).to.equal( + '@container sidebar (min-width:600px)', + ); + expect(theme.containerQueries.up(300)).to.equal('@container (min-width:300px)'); }); }); diff --git a/packages/mui-system/src/breakpoints/breakpoints.js b/packages/mui-system/src/breakpoints/breakpoints.js index c87133ab8df2f9..ee98789726298e 100644 --- a/packages/mui-system/src/breakpoints/breakpoints.js +++ b/packages/mui-system/src/breakpoints/breakpoints.js @@ -21,7 +21,7 @@ const defaultBreakpoints = { }; const defaultContainerQueries = { - cq: (containerName) => ({ + containerQueries: (containerName) => ({ up: (key) => { let result = typeof key === 'number' ? key : values[key] || key; if (typeof result === 'number') { @@ -50,7 +50,7 @@ export function handleBreakpoints(props, propValue, styleFromPropValue) { return Object.keys(propValue).reduce((acc, breakpoint) => { if (isCqShorthand(themeBreakpoints.keys, breakpoint)) { const containerKey = getContainerQuery( - theme.cq ? theme : defaultContainerQueries, + theme.containerQueries ? theme : defaultContainerQueries, breakpoint, ); if (containerKey) { diff --git a/packages/mui-system/src/cssContainerQueries/cssContainerQueries.test.ts b/packages/mui-system/src/cssContainerQueries/cssContainerQueries.test.ts index b1e901480e0c63..785aa3186732c7 100644 --- a/packages/mui-system/src/cssContainerQueries/cssContainerQueries.test.ts +++ b/packages/mui-system/src/cssContainerQueries/cssContainerQueries.test.ts @@ -26,31 +26,43 @@ describe('cssContainerQueries', () => { it('should have `up`, `down`, `between`, `only`, and `not` functions', () => { const theme = createTheme(); - expect(theme.cq.up('sm')).to.equal('@container (min-width:600px)'); - expect(theme.cq.down('sm')).to.equal('@container (max-width:599.95px)'); - expect(theme.cq.between('sm', 'md')).to.equal( + expect(theme.containerQueries.up('sm')).to.equal('@container (min-width:600px)'); + expect(theme.containerQueries.down('sm')).to.equal('@container (max-width:599.95px)'); + expect(theme.containerQueries.between('sm', 'md')).to.equal( '@container (min-width:600px) and (max-width:899.95px)', ); - expect(theme.cq.only('sm')).to.equal('@container (min-width:600px) and (max-width:899.95px)'); - expect(theme.cq.not('xs')).to.equal('@container (min-width:600px)'); - expect(theme.cq.not('xl')).to.equal('@container (max-width:1535.95px)'); - expect(theme.cq.not('md')).to.equal('@container (width<900px) and (width>1199.95px)'); + expect(theme.containerQueries.only('sm')).to.equal( + '@container (min-width:600px) and (max-width:899.95px)', + ); + expect(theme.containerQueries.not('xs')).to.equal('@container (min-width:600px)'); + expect(theme.containerQueries.not('xl')).to.equal('@container (max-width:1535.95px)'); + expect(theme.containerQueries.not('md')).to.equal( + '@container (width<900px) and (width>1199.95px)', + ); }); it('should be able to create named containment context', () => { const theme = createTheme(); - expect(theme.cq('sidebar').up('sm')).to.equal('@container sidebar (min-width:600px)'); - expect(theme.cq('sidebar').down('sm')).to.equal('@container sidebar (max-width:599.95px)'); - expect(theme.cq('sidebar').between('sm', 'md')).to.equal( + expect(theme.containerQueries('sidebar').up('sm')).to.equal( + '@container sidebar (min-width:600px)', + ); + expect(theme.containerQueries('sidebar').down('sm')).to.equal( + '@container sidebar (max-width:599.95px)', + ); + expect(theme.containerQueries('sidebar').between('sm', 'md')).to.equal( '@container sidebar (min-width:600px) and (max-width:899.95px)', ); - expect(theme.cq('sidebar').only('sm')).to.equal( + expect(theme.containerQueries('sidebar').only('sm')).to.equal( '@container sidebar (min-width:600px) and (max-width:899.95px)', ); - expect(theme.cq('sidebar').not('xs')).to.equal('@container sidebar (min-width:600px)'); - expect(theme.cq('sidebar').not('xl')).to.equal('@container sidebar (max-width:1535.95px)'); - expect(theme.cq('sidebar').not('sm')).to.equal( + expect(theme.containerQueries('sidebar').not('xs')).to.equal( + '@container sidebar (min-width:600px)', + ); + expect(theme.containerQueries('sidebar').not('xl')).to.equal( + '@container sidebar (max-width:1535.95px)', + ); + expect(theme.containerQueries('sidebar').not('sm')).to.equal( '@container sidebar (width<600px) and (width>899.95px)', ); }); diff --git a/packages/mui-system/src/cssContainerQueries/cssContainerQueries.ts b/packages/mui-system/src/cssContainerQueries/cssContainerQueries.ts index 6fa078523b298f..49b85f558cff00 100644 --- a/packages/mui-system/src/cssContainerQueries/cssContainerQueries.ts +++ b/packages/mui-system/src/cssContainerQueries/cssContainerQueries.ts @@ -10,7 +10,7 @@ interface ContainerQueries { } export interface CssContainerQueries { - cq: ((name: string) => ContainerQueries) & ContainerQueries; + containerQueries: ((name: string) => ContainerQueries) & ContainerQueries; } /** @@ -23,7 +23,7 @@ export function sortContainerQueries( theme: Partial, css: Record, ) { - if (!theme.cq) { + if (!theme.containerQueries) { return css; } const sorted = Object.keys(css) @@ -69,7 +69,7 @@ export function getContainerQuery(theme: CssContainerQueries, shorthand: string) const value = (Number.isNaN(+containerQuery) ? containerQuery : +containerQuery) as | Breakpoint | number; - return theme.cq(containerName).up(value); + return theme.containerQueries(containerName).up(value); } export default function cssContainerQueries( @@ -104,15 +104,15 @@ export default function cssContainerQueries { + const containerQueries = ((name: string) => { attachCq(node, name); return node; - }) as CssContainerQueries['cq']; + }) as CssContainerQueries['containerQueries']; - attachCq(cq); + attachCq(containerQueries); return { ...themeInput, - cq, + containerQueries, }; }