init project
Some checks failed
No response / noResponse (push) Has been cancelled
CI / Continuous releases (push) Has been cancelled
CI / test-dev (macos-latest) (push) Has been cancelled
CI / test-dev (ubuntu-latest) (push) Has been cancelled
CI / test-dev (windows-latest) (push) Has been cancelled
Maintenance / main (push) Has been cancelled
Scorecards supply-chain security / Scorecards analysis (push) Has been cancelled
CodeQL / Analyze (push) Has been cancelled

This commit is contained in:
how2ice
2025-12-12 14:26:25 +09:00
commit 005cf56baf
43188 changed files with 1079531 additions and 0 deletions

View File

@@ -0,0 +1,33 @@
import FormControl from '@mui/material/FormControl';
import InputLabel from '@mui/material/InputLabel';
import Input from '@mui/material/Input';
import FormHelperText from '@mui/material/FormHelperText';
export default function TextFieldTailwind() {
return (
<FormControl>
<InputLabel
shrink
htmlFor="component-outlined"
className="relative top-0 left-0 transform-none text-sm font-medium text-neutral-800 dark:text-neutral-200 pointer-events-auto mb-0.5"
>
Name
</InputLabel>
<Input
id="component-outlined"
placeholder="Type your name"
slotProps={{
root: {
className:
'mt-0 -ml-0.5 px-2 h-10 border-1 border-neutral-300 dark:border-neutral-700 rounded-md has-[input:focus-visible]:outline-2 has-[input:focus-visible]:outline-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm before:hidden after:hidden',
},
input: {
className:
'placeholder:opacity-100 placeholder:text-neutral-400 dark:placeholder:text-neutral-500',
},
}}
/>
<FormHelperText className="ml-0">Some important helper text</FormHelperText>
</FormControl>
);
}

View File

@@ -0,0 +1,33 @@
import FormControl from '@mui/material/FormControl';
import InputLabel from '@mui/material/InputLabel';
import Input from '@mui/material/Input';
import FormHelperText from '@mui/material/FormHelperText';
export default function TextFieldTailwind() {
return (
<FormControl>
<InputLabel
shrink
htmlFor="component-outlined"
className="relative top-0 left-0 transform-none text-sm font-medium text-neutral-800 dark:text-neutral-200 pointer-events-auto mb-0.5"
>
Name
</InputLabel>
<Input
id="component-outlined"
placeholder="Type your name"
slotProps={{
root: {
className:
'mt-0 -ml-0.5 px-2 h-10 border-1 border-neutral-300 dark:border-neutral-700 rounded-md has-[input:focus-visible]:outline-2 has-[input:focus-visible]:outline-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm before:hidden after:hidden',
},
input: {
className:
'placeholder:opacity-100 placeholder:text-neutral-400 dark:placeholder:text-neutral-500',
},
}}
/>
<FormHelperText className="ml-0">Some important helper text</FormHelperText>
</FormControl>
);
}

View File

@@ -0,0 +1,469 @@
# Tailwind CSS v4 integration
<p class="description">Learn how to use Material UI with Tailwind CSS v4.</p>
## Overview
There are two steps to integrate Tailwind CSS v4 with Material UI:
1. Configure the styles to generate with the `@layer` directive.
2. Set up the layer order so that `mui` comes before the `utilities` layer, allowing Tailwind CSS classes to override Material UI styles.
The instructions below detail how to achieve this using common React frameworks.
### Next.js App Router
To integrate Tailwind CSS v4 with Material UI in a Next.js App Router project, start by configuring Material UI with Next.js in the [App Router integration guide](/material-ui/integrations/nextjs/#app-router).
Then follow these steps:
1. Enable the [CSS layer feature](/material-ui/integrations/nextjs/#using-other-styling-solutions) in the root layout:
```tsx title="src/app/layout.tsx"
import { AppRouterCacheProvider } from '@mui/material-nextjs/v15-appRouter';
export default function RootLayout() {
return (
<html lang="en" suppressHydrationWarning>
<body>
<AppRouterCacheProvider options={{ enableCssLayer: true }}>
{/* Your app */}
</AppRouterCacheProvider>
</body>
</html>
);
}
```
2. Configure the layer order in the Tailwind CSS file:
```css title="src/app/globals.css"
@layer theme, base, mui, components, utilities;
@import 'tailwindcss';
```
### Next.js Pages Router
To integrate Tailwind CSS v4 with Material UI in a Next.js Pages Router project, start by configuring Material UI with Next.js in the [Pages Router integration guide](/material-ui/integrations/nextjs/#pages-router).
Then follow these steps:
1. Enable the [CSS layer feature](/material-ui/integrations/nextjs/#configuration-2) in a custom `_document`:
```tsx title="pages/_document.tsx"
import {
createCache,
documentGetInitialProps,
} from '@mui/material-nextjs/v15-pagesRouter';
// ...
MyDocument.getInitialProps = async (ctx: DocumentContext) => {
const finalProps = await documentGetInitialProps(ctx, {
emotionCache: createCache({ enableCssLayer: true }),
});
return finalProps;
};
```
2. Configure the layer order with the `GlobalStyles` component—it must be the first child of the `AppCacheProvider`:
```tsx title="pages/_app.tsx"
import { AppCacheProvider } from '@mui/material-nextjs/v15-pagesRouter';
import GlobalStyles from '@mui/material/GlobalStyles';
export default function MyApp(props: AppProps) {
const { Component, pageProps } = props;
return (
<AppCacheProvider {...props}>
<GlobalStyles styles="@layer theme, base, mui, components, utilities;" />
{/* Your app */}
</AppCacheProvider>
);
}
```
### Vite.js or any other SPA
To integrate Tailwind CSS v4 with Material UI in a Vite-based app, make the following changes in `src/main.tsx`:
1. Pass the `enableCssLayer` prop to the `StyledEngineProvider` component.
2. Configure the layer order with the `GlobalStyles` component.
```tsx title="main.tsx"
import { StyledEngineProvider } from '@mui/material/styles';
import GlobalStyles from '@mui/material/GlobalStyles';
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<StyledEngineProvider enableCssLayer>
<GlobalStyles styles="@layer theme, base, mui, components, utilities;" />
{/* Your app */}
</StyledEngineProvider>
</React.StrictMode>,
);
```
## Tailwind CSS IntelliSense for VS Code
The official [Tailwind CSS IntelliSense](https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss) extension requires extra configuration to work properly when customizing the interior slots of Material UI components.
After installing the extension, add the following line to your [VS Code `settings.json`](https://code.visualstudio.com/docs/configure/settings#_settings-json-file) file:
```json
{
// ...config
"tailwindCSS.experimental.classRegex": [["className\\s*:\\s*['\"]([^'\"]*)['\"]"]]
}
```
Now you should see the autocomplete and syntax highlighting features when using the `slotProps` prop, as shown in the screenshot below:
![A preview of Tailwind CSS Intellisense](/static/material-ui/tailwind-intellisense.jpg)
## Usage
- Use the `className` prop to apply Tailwind CSS classes to the root element of the component.
- Use `slotProps.{slotName}.className` to apply Tailwind CSS classes to a component's [interior slots](/material-ui/customization/overriding-component-structure/#interior-slots).
{{"demo": "TextFieldTailwind.js"}}
## Extend Material UI classes
If you want to use Material UI theme tokens in your Tailwind CSS classes, copy the snippet below into your CSS file.
```css title="global.css"
@layer theme, base, mui, components, utilities;
@import 'tailwindcss';
@theme inline {
/* Material UI typography */
--font-h1: var(--mui-font-h1);
--font-h2: var(--mui-font-h2);
--font-h3: var(--mui-font-h3);
--font-h4: var(--mui-font-h4);
--font-h5: var(--mui-font-h5);
--font-h6: var(--mui-font-h6);
--font-subtitle1: var(--mui-font-subtitle1);
--font-subtitle2: var(--mui-font-subtitle2);
--font-body1: var(--mui-font-body1);
--font-body2: var(--mui-font-body2);
--font-button: var(--mui-font-button);
--font-caption: var(--mui-font-caption);
--font-overline: var(--mui-font-overline);
--letter-spacing-h1: -0.01562em;
--letter-spacing-h2: -0.00833em;
--letter-spacing-h4: 0.00735em;
--letter-spacing-h6: 0.0075em;
--letter-spacing-body1: 0.00938em;
--letter-spacing-body2: 0.01071em;
/* Material UI breakpoints */
--breakpoint-sm: 37.5rem; /* 600px */
--breakpoint-md: 56.25rem; /* 900px */
--breakpoint-lg: 75rem; /* 1200px */
--breakpoint-xl: 96rem; /* 1536px */
--breakpoint-2xl: 120rem; /* 1920px */
/* Material UI theme colors */
--color-primary: rgb(var(--mui-palette-primary-mainChannel));
--color-primary-light: rgb(var(--mui-palette-primary-lightChannel));
--color-primary-dark: rgb(var(--mui-palette-primary-darkChannel));
--color-primary-contrast: rgb(var(--mui-palette-primary-contrastTextChannel));
--color-secondary: rgb(var(--mui-palette-secondary-mainChannel));
--color-secondary-light: rgb(var(--mui-palette-secondary-lightChannel));
--color-secondary-dark: rgb(var(--mui-palette-secondary-darkChannel));
--color-secondary-contrast: rgb(var(--mui-palette-secondary-contrastTextChannel));
/* Material UI status colors */
--color-info: rgb(var(--mui-palette-info-mainChannel));
--color-info-light: rgb(var(--mui-palette-info-lightChannel));
--color-info-dark: rgb(var(--mui-palette-info-darkChannel));
--color-info-contrast: rgb(var(--mui-palette-info-contrastTextChannel));
--color-error: rgb(var(--mui-palette-error-mainChannel));
--color-error-light: rgb(var(--mui-palette-error-lightChannel));
--color-error-dark: rgb(var(--mui-palette-error-darkChannel));
--color-error-contrast: rgb(var(--mui-palette-error-contrastTextChannel));
--color-success: rgb(var(--mui-palette-success-mainChannel));
--color-success-light: rgb(var(--mui-palette-success-lightChannel));
--color-success-dark: rgb(var(--mui-palette-success-darkChannel));
--color-success-contrast: rgb(var(--mui-palette-success-contrastTextChannel));
--color-warning: rgb(var(--mui-palette-warning-mainChannel));
--color-warning-light: rgb(var(--mui-palette-warning-lightChannel));
--color-warning-dark: rgb(var(--mui-palette-warning-darkChannel));
--color-warning-contrast: rgb(var(--mui-palette-warning-contrastTextChannel));
/* Material UI text & common colors */
--color-text-primary: rgb(var(--mui-palette-text-primaryChannel));
--color-text-secondary: rgb(var(--mui-palette-text-secondaryChannel));
--color-text-disabled: var(--mui-palette-text-disabled);
--color-common-background: var(--mui-palette-common-background);
--color-common-onBackground: var(--mui-palette-common-onBackground);
--color-divider: var(--mui-palette-divider);
/* Material UI background colors */
--color-background-default: rgb(var(--mui-palette-background-defaultChannel));
--color-background-paper: rgb(var(--mui-palette-background-paperChannel));
/* Material UI action colors */
--color-action-active: var(--mui-palette-action-active);
--color-action-hover: var(--mui-palette-action-hover);
--color-action-selected: var(--mui-palette-action-selected);
--color-action-disabled: var(--mui-palette-action-disabled);
--color-action-focus: var(--mui-palette-action-focus);
/* Material UI gray scale */
--color-gray-50: var(--mui-palette-grey-50);
--color-gray-100: var(--mui-palette-grey-100);
--color-gray-200: var(--mui-palette-grey-200);
--color-gray-300: var(--mui-palette-grey-300);
--color-gray-400: var(--mui-palette-grey-400);
--color-gray-500: var(--mui-palette-grey-500);
--color-gray-600: var(--mui-palette-grey-600);
--color-gray-700: var(--mui-palette-grey-700);
--color-gray-800: var(--mui-palette-grey-800);
--color-gray-900: var(--mui-palette-grey-900);
--color-gray-A100: var(--mui-palette-grey-A100);
--color-gray-A200: var(--mui-palette-grey-A200);
--color-gray-A400: var(--mui-palette-grey-A400);
--color-gray-A700: var(--mui-palette-grey-A700);
/* Material UI Component Colors */
/* Alert */
--color-Alert-error: var(--mui-palette-Alert-errorColor);
--color-Alert-info: var(--mui-palette-Alert-infoColor);
--color-Alert-success: var(--mui-palette-Alert-successColor);
--color-Alert-warning: var(--mui-palette-Alert-warningColor);
--color-Alert-errorFilled: var(--mui-palette-Alert-errorFilledBg);
--color-Alert-infoFilled: var(--mui-palette-Alert-infoFilledBg);
--color-Alert-successFilled: var(--mui-palette-Alert-successFilledBg);
--color-Alert-warningFilled: var(--mui-palette-Alert-warningFilledBg);
--color-Alert-errorFilledColor: var(--mui-palette-Alert-errorFilledColor);
--color-Alert-infoFilledColor: var(--mui-palette-Alert-infoFilledColor);
--color-Alert-successFilledColor: var(--mui-palette-Alert-successFilledColor);
--color-Alert-warningFilledColor: var(--mui-palette-Alert-warningFilledColor);
--color-Alert-errorStandard: var(--mui-palette-Alert-errorStandardBg);
--color-Alert-infoStandard: var(--mui-palette-Alert-infoStandardBg);
--color-Alert-successStandard: var(--mui-palette-Alert-successStandardBg);
--color-Alert-warningStandard: var(--mui-palette-Alert-warningStandardBg);
--color-Alert-errorIcon: var(--mui-palette-Alert-errorIconColor);
--color-Alert-infoIcon: var(--mui-palette-Alert-infoIconColor);
--color-Alert-successIcon: var(--mui-palette-Alert-successIconColor);
--color-Alert-warningIcon: var(--mui-palette-Alert-warningIconColor);
/* AppBar */
--color-AppBar-default: var(--mui-palette-AppBar-defaultBg);
/* Avatar */
--color-Avatar-default: var(--mui-palette-Avatar-defaultBg);
/* Button */
--color-Button-inheritContained: var(--mui-palette-Button-inheritContainedBg);
--color-Button-inheritContainedHover: var(
--mui-palette-Button-inheritContainedHoverBg
);
/* Chip */
--color-Chip-defaultBorder: var(--mui-palette-Chip-defaultBorder);
--color-Chip-defaultAvatar: var(--mui-palette-Chip-defaultAvatarColor);
--color-Chip-defaultIcon: var(--mui-palette-Chip-defaultIconColor);
/* FilledInput */
--color-FilledInput-bg: var(--mui-palette-FilledInput-bg);
--color-FilledInput-hover: var(--mui-palette-FilledInput-hoverBg);
--color-FilledInput-disabled: var(--mui-palette-FilledInput-disabledBg);
/* LinearProgress */
--color-LinearProgress-primary: var(--mui-palette-LinearProgress-primaryBg);
--color-LinearProgress-secondary: var(--mui-palette-LinearProgress-secondaryBg);
--color-LinearProgress-error: var(--mui-palette-LinearProgress-errorBg);
--color-LinearProgress-info: var(--mui-palette-LinearProgress-infoBg);
--color-LinearProgress-success: var(--mui-palette-LinearProgress-successBg);
--color-LinearProgress-warning: var(--mui-palette-LinearProgress-warningBg);
/* Skeleton */
--color-Skeleton-bg: var(--mui-palette-Skeleton-bg);
/* Slider */
--color-Slider-primary: var(--mui-palette-Slider-primaryTrack);
--color-Slider-secondary: var(--mui-palette-Slider-secondaryTrack);
--color-Slider-error: var(--mui-palette-Slider-errorTrack);
--color-Slider-info: var(--mui-palette-Slider-infoTrack);
--color-Slider-success: var(--mui-palette-Slider-successTrack);
--color-Slider-warning: var(--mui-palette-Slider-warningTrack);
/* SnackbarContent */
--color-SnackbarContent-bg: var(--mui-palette-SnackbarContent-bg);
--color-SnackbarContent-text: var(--mui-palette-SnackbarContent-color);
/* SpeedDialAction */
--color-SpeedDialAction-fabHover: var(--mui-palette-SpeedDialAction-fabHoverBg);
/* StepConnector & StepContent */
--color-StepConnector-border: var(--mui-palette-StepConnector-border);
--color-StepContent-border: var(--mui-palette-StepContent-border);
/* Switch */
--color-Switch-default: var(--mui-palette-Switch-defaultColor);
--color-Switch-defaultDisabled: var(--mui-palette-Switch-defaultDisabledColor);
--color-Switch-primaryDisabled: var(--mui-palette-Switch-primaryDisabledColor);
--color-Switch-secondaryDisabled: var(--mui-palette-Switch-secondaryDisabledColor);
--color-Switch-errorDisabled: var(--mui-palette-Switch-errorDisabledColor);
--color-Switch-infoDisabled: var(--mui-palette-Switch-infoDisabledColor);
--color-Switch-successDisabled: var(--mui-palette-Switch-successDisabledColor);
--color-Switch-warningDisabled: var(--mui-palette-Switch-warningDisabledColor);
/* TableCell */
--color-TableCell-border: var(--mui-palette-TableCell-border);
/* Tooltip */
--color-Tooltip-bg: var(--mui-palette-Tooltip-bg);
/* Material UI shadows */
--shadow-1: var(--mui-shadows-1);
--shadow-2: var(--mui-shadows-2);
--shadow-3: var(--mui-shadows-3);
--shadow-4: var(--mui-shadows-4);
--shadow-5: var(--mui-shadows-5);
--shadow-6: var(--mui-shadows-6);
--shadow-7: var(--mui-shadows-7);
--shadow-8: var(--mui-shadows-8);
--shadow-9: var(--mui-shadows-9);
--shadow-10: var(--mui-shadows-10);
--shadow-11: var(--mui-shadows-11);
--shadow-12: var(--mui-shadows-12);
--shadow-13: var(--mui-shadows-13);
--shadow-14: var(--mui-shadows-14);
--shadow-15: var(--mui-shadows-15);
--shadow-16: var(--mui-shadows-16);
--shadow-17: var(--mui-shadows-17);
--shadow-18: var(--mui-shadows-18);
--shadow-19: var(--mui-shadows-19);
--shadow-20: var(--mui-shadows-20);
--shadow-21: var(--mui-shadows-21);
--shadow-22: var(--mui-shadows-22);
--shadow-23: var(--mui-shadows-23);
--shadow-24: var(--mui-shadows-24);
/* Material UI opacity */
--opacity-activated: calc(100% * var(--mui-palette-action-activatedOpacity));
--opacity-disabled: calc(100% * var(--mui-palette-action-disabledOpacity));
--opacity-focus: calc(100% * var(--mui-palette-action-focusOpacity));
--opacity-hover: calc(100% * var(--mui-palette-action-hoverOpacity));
--opacity-selected: calc(100% * var(--mui-palette-action-selectedOpacity));
/* Material UI overlays */
--overlay-1: var(--mui-overlays-1);
--overlay-2: var(--mui-overlays-2);
--overlay-3: var(--mui-overlays-3);
--overlay-4: var(--mui-overlays-4);
--overlay-5: var(--mui-overlays-5);
--overlay-6: var(--mui-overlays-6);
--overlay-7: var(--mui-overlays-7);
--overlay-8: var(--mui-overlays-8);
--overlay-9: var(--mui-overlays-9);
--overlay-10: var(--mui-overlays-10);
--overlay-11: var(--mui-overlays-11);
--overlay-12: var(--mui-overlays-12);
--overlay-13: var(--mui-overlays-13);
--overlay-14: var(--mui-overlays-14);
--overlay-15: var(--mui-overlays-15);
--overlay-16: var(--mui-overlays-16);
--overlay-17: var(--mui-overlays-17);
--overlay-18: var(--mui-overlays-18);
--overlay-19: var(--mui-overlays-19);
--overlay-20: var(--mui-overlays-20);
--overlay-21: var(--mui-overlays-21);
--overlay-22: var(--mui-overlays-22);
--overlay-23: var(--mui-overlays-23);
--overlay-24: var(--mui-overlays-24);
}
/* Material UI base styles */
@layer base {
h1 {
font: var(--mui-font-h1);
letter-spacing: -0.01562em;
}
h2 {
font: var(--mui-font-h2);
letter-spacing: -0.00833em;
}
h3 {
font: var(--mui-font-h3);
}
h4 {
font: var(--mui-font-h4);
letter-spacing: 0.00735em;
}
h5 {
font: var(--mui-font-h5);
}
h6 {
font: var(--mui-font-h6);
letter-spacing: 0.0075em;
}
p {
font: var(--mui-font-body1);
letter-spacing: 0.00938em;
}
span {
font: var(--mui-font-body2);
letter-spacing: 0.01071em;
}
}
/* Material UI typography utilities */
@utility typography-* {
font: --value(--font-*);
}
/* Material UI overlay utilities */
@utility overlay-* {
background-image: --value(--overlay-*);
}
/* Material UI elevation utilities */
@utility elevation-* {
background-image: --value(--overlay-*);
box-shadow: --value(--shadow-*);
}
```
Then you can start using the new classes—for example:
- The class `typography-h1` produces `font: var(--mui-font-h1);`
- The class `text-primary` produces `color: rgb(var(--mui-palette-primary-mainChannel));`
So when you add these classes to an element…
```js title="App.tsx"
<div className="typography-h1 text-primary">Hello world</div>
```
…the CSS looks like this:
```css
@layer utilities {
.typography-h1 {
font: var(--mui-font-h1);
letter-spacing: -0.01562em;
}
.text-primary {
color: rgb(var(--mui-palette-primary-mainChannel));
}
}
```
### Playground
Visit the [Tailwind CSS Playground](https://play.tailwindcss.com/f1ZIr0qSNG) to explore the classes from Material UI theme tokens.
## Troubleshooting
If the Tailwind CSS classes are not overriding Material UI components, make sure that:
- You are using Tailwind CSS >= v4.
- You have configured the layer order correctly by checking the [DevTools styles tab](https://developer.chrome.com/docs/devtools/css/reference#cascade-layers). The `mui` layer should come before the `utilities` layer.