diff --git a/apps/pigment-css-next-app/src/app/layout.tsx b/apps/pigment-css-next-app/src/app/layout.tsx
index 77126c9b714539..b232ba291a9f28 100644
--- a/apps/pigment-css-next-app/src/app/layout.tsx
+++ b/apps/pigment-css-next-app/src/app/layout.tsx
@@ -1,9 +1,7 @@
import type { Metadata } from 'next';
-import { css } from '@pigment-css/react';
import { Inter } from 'next/font/google';
import { AppRouterCacheProvider } from '@mui/material-nextjs/v14-appRouter';
import { ThemeProvider } from '@mui/material/styles';
-import CssBaseline from '@mui/material/CssBaseline';
import '@pigment-css/react/styles.css';
import theme from './theme';
@@ -19,20 +17,9 @@ export const metadata: Metadata = {
export default function RootLayout(props: { children: React.ReactNode }) {
return (
-
t.vars.palette.background.default};
- color: ${({ theme: t }) => t.vars.palette.text.primary};
- background-image: url('@/assets/mui.svg');
- background-repeat: no-repeat;
- background-position: 1rem 1rem;
- `}`}
- >
+
-
-
- {props.children}
-
+ {props.children}
diff --git a/apps/pigment-css-next-app/src/app/material-ui/react-css-baseline/page.tsx b/apps/pigment-css-next-app/src/app/material-ui/react-css-baseline/page.tsx
new file mode 100644
index 00000000000000..ba513ac0612826
--- /dev/null
+++ b/apps/pigment-css-next-app/src/app/material-ui/react-css-baseline/page.tsx
@@ -0,0 +1,24 @@
+'use client';
+import * as React from 'react';
+import CssBaseline from '@mui/material/CssBaseline';
+import ScopedCssBaseline from '@mui/material/ScopedCssBaseline';
+
+export default function CssBaselinePage() {
+ return (
+
+
+
+
+ Positioned Popper
+
+ Hello world
+
+
+
+ );
+}
diff --git a/apps/pigment-css-next-app/src/app/material-ui/react-popper/page.tsx b/apps/pigment-css-next-app/src/app/material-ui/react-popper/page.tsx
new file mode 100644
index 00000000000000..99197dba12699d
--- /dev/null
+++ b/apps/pigment-css-next-app/src/app/material-ui/react-popper/page.tsx
@@ -0,0 +1,51 @@
+'use client';
+import * as React from 'react';
+import PopperPopupState from '../../../../../../docs/data/material/components/popper/PopperPopupState';
+import PositionedPopper from '../../../../../../docs/data/material/components/popper/PositionedPopper';
+import SimplePopper from '../../../../../../docs/data/material/components/popper/SimplePopper';
+import SpringPopper from '../../../../../../docs/data/material/components/popper/SpringPopper';
+import TransitionsPopper from '../../../../../../docs/data/material/components/popper/TransitionsPopper';
+import VirtualElementPopper from '../../../../../../docs/data/material/components/popper/VirtualElementPopper';
+
+export default function Popper() {
+ return (
+
+
+
+
+
+
+ Transitions Popper
+
+
+
+
+
+ Virtual Element Popper
+
+
+
+
+
+ );
+}
diff --git a/apps/pigment-css-next-app/src/app/material-ui/react-text-field/page.tsx b/apps/pigment-css-next-app/src/app/material-ui/react-text-field/page.tsx
new file mode 100644
index 00000000000000..f3d627bd2944ce
--- /dev/null
+++ b/apps/pigment-css-next-app/src/app/material-ui/react-text-field/page.tsx
@@ -0,0 +1,163 @@
+'use client';
+import * as React from 'react';
+import BasicTextFields from '../../../../../../docs/data/material/components/text-fields/BasicTextFields';
+import ColorTextFields from '../../../../../../docs/data/material/components/text-fields/ColorTextFields';
+import ComposedTextField from '../../../../../../docs/data/material/components/text-fields/ComposedTextField';
+import CustomizedInputBase from '../../../../../../docs/data/material/components/text-fields/CustomizedInputBase';
+import CustomizedInputsStyleOverrides from '../../../../../../docs/data/material/components/text-fields/CustomizedInputsStyleOverrides';
+import CustomizedInputsStyled from '../../../../../../docs/data/material/components/text-fields/CustomizedInputsStyled';
+import FormPropsTextFields from '../../../../../../docs/data/material/components/text-fields/FormPropsTextFields';
+import FormattedInputs from '../../../../../../docs/data/material/components/text-fields/FormattedInputs';
+import FullWidthTextField from '../../../../../../docs/data/material/components/text-fields/FullWidthTextField';
+import HelperTextAligned from '../../../../../../docs/data/material/components/text-fields/HelperTextAligned';
+import HelperTextMisaligned from '../../../../../../docs/data/material/components/text-fields/HelperTextMisaligned';
+import InputAdornments from '../../../../../../docs/data/material/components/text-fields/InputAdornments';
+import InputWithIcon from '../../../../../../docs/data/material/components/text-fields/InputWithIcon';
+import Inputs from '../../../../../../docs/data/material/components/text-fields/Inputs';
+import LayoutTextFields from '../../../../../../docs/data/material/components/text-fields/LayoutTextFields';
+import MultilineTextFields from '../../../../../../docs/data/material/components/text-fields/MultilineTextFields';
+import SelectTextFields from '../../../../../../docs/data/material/components/text-fields/SelectTextFields';
+import StateTextFields from '../../../../../../docs/data/material/components/text-fields/StateTextFields';
+import TextFieldHiddenLabel from '../../../../../../docs/data/material/components/text-fields/TextFieldHiddenLabel';
+import TextFieldSizes from '../../../../../../docs/data/material/components/text-fields/TextFieldSizes';
+import UseFormControl from '../../../../../../docs/data/material/components/text-fields/UseFormControl';
+import ValidationTextFields from '../../../../../../docs/data/material/components/text-fields/ValidationTextFields';
+
+export default function TextFields() {
+ return (
+
+
+ Basic Text Fields
+
+
+
+
+
+ Color Text Fields
+
+
+
+
+
+ Composed Text Field
+
+
+
+
+
+ Customized Input Base
+
+
+
+
+
+ Customized Inputs Style Overrides
+
+
+
+
+
+ Customized Inputs Styled
+
+
+
+
+
+ Form Props Text Fields
+
+
+
+
+
+ Formatted Inputs
+
+
+
+
+
+ Full Width Text Field
+
+
+
+
+
+ Helper Text Aligned
+
+
+
+
+
+ Helper Text Misaligned
+
+
+
+
+
+ Input Adornments
+
+
+
+
+
+ Input With Icon
+
+
+
+
+
+
+ Layout Text Fields
+
+
+
+
+
+ Multiline Text Fields
+
+
+
+
+
+ Select Text Fields
+
+
+
+
+
+ State Text Fields
+
+
+
+
+
+ Text Field Hidden Label
+
+
+
+
+
+ Text Field Sizes
+
+
+
+
+
+ Use Form Control
+
+
+
+
+
+ Validation Text Fields
+
+
+
+
+
+ );
+}
diff --git a/apps/pigment-css-vite-app/src/pages/material-ui/react-css-baseline.tsx b/apps/pigment-css-vite-app/src/pages/material-ui/react-css-baseline.tsx
new file mode 100644
index 00000000000000..14caca148fca49
--- /dev/null
+++ b/apps/pigment-css-vite-app/src/pages/material-ui/react-css-baseline.tsx
@@ -0,0 +1,24 @@
+import * as React from 'react';
+import CssBaseline from '@mui/material/CssBaseline';
+import ScopedCssBaseline from '@mui/material/ScopedCssBaseline';
+import MaterialUILayout from '../../Layout';
+
+export default function CssBaselinePage() {
+ return (
+
+
+
+
+ Positioned Popper
+
+ Hello world
+
+
+
+ );
+}
diff --git a/apps/pigment-css-vite-app/src/pages/material-ui/react-popper.tsx b/apps/pigment-css-vite-app/src/pages/material-ui/react-popper.tsx
new file mode 100644
index 00000000000000..29dccd4a30a793
--- /dev/null
+++ b/apps/pigment-css-vite-app/src/pages/material-ui/react-popper.tsx
@@ -0,0 +1,52 @@
+import * as React from 'react';
+import MaterialUILayout from '../../Layout';
+import PopperPopupState from '../../../../../docs/data/material/components/popper/PopperPopupState.tsx';
+import PositionedPopper from '../../../../../docs/data/material/components/popper/PositionedPopper.tsx';
+import SimplePopper from '../../../../../docs/data/material/components/popper/SimplePopper.tsx';
+import SpringPopper from '../../../../../docs/data/material/components/popper/SpringPopper.tsx';
+import TransitionsPopper from '../../../../../docs/data/material/components/popper/TransitionsPopper.tsx';
+import VirtualElementPopper from '../../../../../docs/data/material/components/popper/VirtualElementPopper.tsx';
+
+export default function Popper() {
+ return (
+
+ Popper
+
+
+
+
+
+ Transitions Popper
+
+
+
+
+
+ Virtual Element Popper
+
+
+
+
+
+ );
+}
diff --git a/apps/pigment-css-vite-app/src/pages/material-ui/react-text-field.tsx b/apps/pigment-css-vite-app/src/pages/material-ui/react-text-field.tsx
new file mode 100644
index 00000000000000..bdd998a45605f0
--- /dev/null
+++ b/apps/pigment-css-vite-app/src/pages/material-ui/react-text-field.tsx
@@ -0,0 +1,164 @@
+import * as React from 'react';
+import MaterialUILayout from '../../Layout';
+import BasicTextFields from '../../../../../docs/data/material/components/text-fields/BasicTextFields.tsx';
+import ColorTextFields from '../../../../../docs/data/material/components/text-fields/ColorTextFields.tsx';
+import ComposedTextField from '../../../../../docs/data/material/components/text-fields/ComposedTextField.tsx';
+import CustomizedInputBase from '../../../../../docs/data/material/components/text-fields/CustomizedInputBase.tsx';
+import CustomizedInputsStyleOverrides from '../../../../../docs/data/material/components/text-fields/CustomizedInputsStyleOverrides.tsx';
+import CustomizedInputsStyled from '../../../../../docs/data/material/components/text-fields/CustomizedInputsStyled.tsx';
+import FormPropsTextFields from '../../../../../docs/data/material/components/text-fields/FormPropsTextFields.tsx';
+import FormattedInputs from '../../../../../docs/data/material/components/text-fields/FormattedInputs.tsx';
+import FullWidthTextField from '../../../../../docs/data/material/components/text-fields/FullWidthTextField.tsx';
+import HelperTextAligned from '../../../../../docs/data/material/components/text-fields/HelperTextAligned.tsx';
+import HelperTextMisaligned from '../../../../../docs/data/material/components/text-fields/HelperTextMisaligned.tsx';
+import InputAdornments from '../../../../../docs/data/material/components/text-fields/InputAdornments.tsx';
+import InputWithIcon from '../../../../../docs/data/material/components/text-fields/InputWithIcon.tsx';
+import Inputs from '../../../../../docs/data/material/components/text-fields/Inputs.tsx';
+import LayoutTextFields from '../../../../../docs/data/material/components/text-fields/LayoutTextFields.tsx';
+import MultilineTextFields from '../../../../../docs/data/material/components/text-fields/MultilineTextFields.tsx';
+import SelectTextFields from '../../../../../docs/data/material/components/text-fields/SelectTextFields.tsx';
+import StateTextFields from '../../../../../docs/data/material/components/text-fields/StateTextFields.tsx';
+import TextFieldHiddenLabel from '../../../../../docs/data/material/components/text-fields/TextFieldHiddenLabel.tsx';
+import TextFieldSizes from '../../../../../docs/data/material/components/text-fields/TextFieldSizes.tsx';
+import UseFormControl from '../../../../../docs/data/material/components/text-fields/UseFormControl.tsx';
+import ValidationTextFields from '../../../../../docs/data/material/components/text-fields/ValidationTextFields.tsx';
+
+export default function TextFields() {
+ return (
+
+ TextFields
+
+ Basic Text Fields
+
+
+
+
+
+ Color Text Fields
+
+
+
+
+
+ Composed Text Field
+
+
+
+
+
+ Customized Input Base
+
+
+
+
+
+ Customized Inputs Style Overrides
+
+
+
+
+
+ Customized Inputs Styled
+
+
+
+
+
+ Form Props Text Fields
+
+
+
+
+
+ Formatted Inputs
+
+
+
+
+
+ Full Width Text Field
+
+
+
+
+
+ Helper Text Aligned
+
+
+
+
+
+ Helper Text Misaligned
+
+
+
+
+
+ Input Adornments
+
+
+
+
+
+ Input With Icon
+
+
+
+
+
+
+ Layout Text Fields
+
+
+
+
+
+ Multiline Text Fields
+
+
+
+
+
+ Select Text Fields
+
+
+
+
+
+ State Text Fields
+
+
+
+
+
+ Text Field Hidden Label
+
+
+
+
+
+ Text Field Sizes
+
+
+
+
+
+ Use Form Control
+
+
+
+
+
+ Validation Text Fields
+
+
+
+
+
+ );
+}
diff --git a/packages/mui-material/src/CssBaseline/CssBaseline.js b/packages/mui-material/src/CssBaseline/CssBaseline.js
index 12d16875e3f984..9caadb2ba5efb3 100644
--- a/packages/mui-material/src/CssBaseline/CssBaseline.js
+++ b/packages/mui-material/src/CssBaseline/CssBaseline.js
@@ -1,8 +1,11 @@
'use client';
import * as React from 'react';
import PropTypes from 'prop-types';
-import useThemeProps from '../styles/useThemeProps';
-import GlobalStyles from '../GlobalStyles';
+import { globalCss } from '../zero-styled';
+import { useDefaultProps } from '../DefaultPropsProvider';
+
+// to determine if the global styles are static or dynamic
+const isDynamicSupport = typeof globalCss({}) === 'function';
export const html = (theme, enableColorScheme) => ({
WebkitFontSmoothing: 'antialiased', // Antialiasing.
@@ -30,9 +33,20 @@ export const styles = (theme, enableColorScheme = false) => {
const colorSchemeStyles = {};
if (enableColorScheme && theme.colorSchemes) {
Object.entries(theme.colorSchemes).forEach(([key, scheme]) => {
- colorSchemeStyles[theme.getColorSchemeSelector(key).replace(/\s*&/, '')] = {
- colorScheme: scheme.palette?.mode,
- };
+ const selector = theme.getColorSchemeSelector(key);
+ if (selector.startsWith('@')) {
+ // for @media (prefers-color-scheme), we need to target :root
+ colorSchemeStyles[selector] = {
+ ':root': {
+ colorScheme: scheme.palette?.mode,
+ },
+ };
+ } else {
+ // else, it's likely that the selector already target an element with a class or data attribute
+ colorSchemeStyles[selector.replace(/\s*&/, '')] = {
+ colorScheme: scheme.palette?.mode,
+ };
+ }
});
}
let defaultStyles = {
@@ -63,15 +77,59 @@ export const styles = (theme, enableColorScheme = false) => {
return defaultStyles;
};
+// `ecs` stands for enableColorScheme. This is internal logic to make it work with Pigment CSS, so shorter is better.
+const SELECTOR = 'mui-ecs';
+const staticStyles = (theme) => {
+ const result = styles(theme, false);
+ const baseStyles = Array.isArray(result) ? result[0] : result;
+ if (!theme.vars && baseStyles) {
+ baseStyles.html[`:root:has(${SELECTOR})`] = { colorScheme: theme.palette.mode };
+ }
+ if (theme.colorSchemes) {
+ Object.entries(theme.colorSchemes).forEach(([key, scheme]) => {
+ const selector = theme.getColorSchemeSelector(key);
+ if (selector.startsWith('@')) {
+ // for @media (prefers-color-scheme), we need to target :root
+ baseStyles[selector] = {
+ [`:root:not(:has(.${SELECTOR}))`]: {
+ colorScheme: scheme.palette?.mode,
+ },
+ };
+ } else {
+ // else, it's likely that the selector already target an element with a class or data attribute
+ baseStyles[selector.replace(/\s*&/, '')] = {
+ [`&:not(:has(.${SELECTOR}))`]: {
+ colorScheme: scheme.palette?.mode,
+ },
+ };
+ }
+ });
+ }
+ return result;
+};
+
+const GlobalStyles = globalCss(
+ isDynamicSupport
+ ? ({ theme, enableColorScheme }) => styles(theme, enableColorScheme)
+ : ({ theme }) => staticStyles(theme),
+);
+
/**
* Kickstart an elegant, consistent, and simple baseline to build upon.
*/
function CssBaseline(inProps) {
- const props = useThemeProps({ props: inProps, name: 'MuiCssBaseline' });
+ const props = useDefaultProps({ props: inProps, name: 'MuiCssBaseline' });
const { children, enableColorScheme = false } = props;
return (
- styles(theme, enableColorScheme)} />
+ {/* Emotion */}
+ {isDynamicSupport && }
+
+ {/* Pigment CSS */}
+ {!isDynamicSupport && !enableColorScheme && (
+
+ )}
+
{children}
);
diff --git a/packages/mui-material/src/Popper/Popper.tsx b/packages/mui-material/src/Popper/Popper.tsx
index ea1ee028a96a75..565559630ff4b8 100644
--- a/packages/mui-material/src/Popper/Popper.tsx
+++ b/packages/mui-material/src/Popper/Popper.tsx
@@ -1,12 +1,14 @@
'use client';
import { Popper as BasePopper, PopperProps as BasePopperProps } from '@mui/base/Popper';
-import { Direction, SxProps } from '@mui/system';
-import useTheme from '@mui/system/useThemeWithoutDefault';
+import { SxProps } from '@mui/system';
+import { useRtl } from '@mui/system/RtlProvider';
import refType from '@mui/utils/refType';
import HTMLElementType from '@mui/utils/HTMLElementType';
import PropTypes from 'prop-types';
import * as React from 'react';
-import { styled, Theme, useThemeProps } from '../styles';
+import { Theme } from '../styles';
+import { styled } from '../zero-styled';
+import { useDefaultProps } from '../DefaultPropsProvider';
export interface PopperProps extends Omit {
/**
@@ -59,8 +61,8 @@ const Popper = React.forwardRef(function Popper(
inProps: PopperProps,
ref: React.ForwardedRef,
) {
- const theme = useTheme<{ direction?: Direction }>();
- const props = useThemeProps({
+ const isRtl = useRtl();
+ const props = useDefaultProps({
props: inProps,
name: 'MuiPopper',
});
@@ -101,7 +103,7 @@ const Popper = React.forwardRef(function Popper(
return (
styles.root,
-})(({ theme, ownerState }) => {
+})(({ theme }) => {
const colorSchemeStyles = {};
- if (ownerState.enableColorScheme && theme.colorSchemes) {
+ if (theme.colorSchemes) {
Object.entries(theme.colorSchemes).forEach(([key, scheme]) => {
- colorSchemeStyles[`&${theme.getColorSchemeSelector(key).replace(/\s*&/, '')}`] = {
- colorScheme: scheme.palette?.mode,
- };
+ const selector = theme.getColorSchemeSelector(key);
+ if (selector.startsWith('@')) {
+ colorSchemeStyles[selector] = {
+ colorScheme: scheme.palette?.mode,
+ };
+ } else {
+ colorSchemeStyles[`&${selector.replace(/\s*&/, '')}`] = {
+ colorScheme: scheme.palette?.mode,
+ };
+ }
});
}
return {
- ...html(theme, ownerState.enableColorScheme),
+ ...html(theme, false),
...body(theme),
'& *, & *::before, & *::after': {
boxSizing: 'inherit',
@@ -40,12 +47,17 @@ const ScopedCssBaselineRoot = styled('div', {
'& strong, & b': {
fontWeight: theme.typography.fontWeightBold,
},
- ...colorSchemeStyles,
+ variants: [
+ {
+ props: { enableColorScheme: true },
+ style: theme.vars ? colorSchemeStyles : { colorScheme: theme.palette.mode },
+ },
+ ],
};
});
const ScopedCssBaseline = React.forwardRef(function ScopedCssBaseline(inProps, ref) {
- const props = useThemeProps({ props: inProps, name: 'MuiScopedCssBaseline' });
+ const props = useDefaultProps({ props: inProps, name: 'MuiScopedCssBaseline' });
const { className, component = 'div', enableColorScheme, ...other } = props;
const ownerState = {
diff --git a/packages/mui-material/src/zero-styled/index.tsx b/packages/mui-material/src/zero-styled/index.tsx
index e56c98cf9182d1..159973f48008a3 100644
--- a/packages/mui-material/src/zero-styled/index.tsx
+++ b/packages/mui-material/src/zero-styled/index.tsx
@@ -1,5 +1,7 @@
import * as React from 'react';
+import { Interpolation } from '@mui/system';
import { extendSxProp } from '@mui/system/styleFunctionSx';
+import { Theme } from '../styles/createTheme';
import useTheme from '../styles/useTheme';
import GlobalStyles, { GlobalStylesProps } from '../GlobalStyles';
@@ -7,9 +9,18 @@ export { css, keyframes } from '@mui/system';
export { default as styled } from '../styles/styled';
-export function globalCss(styles: GlobalStylesProps['styles']) {
- return function GlobalStylesWrapper() {
- return ;
+export function globalCss(styles: Interpolation<{ theme: Theme }>) {
+ return function GlobalStylesWrapper(props: Record) {
+ return (
+ // Pigment CSS `globalCss` support callback with theme inside an object but `GlobalStyles` support theme as a callback value.
+ styles({ theme, ...props })
+ : styles) as GlobalStylesProps['styles']
+ }
+ />
+ );
};
}