diff --git a/.cursor/skills/README.md b/.cursor/skills/README.md new file mode 100644 index 00000000000000..ed75e9c3ee7d6d --- /dev/null +++ b/.cursor/skills/README.md @@ -0,0 +1,5 @@ +# Cursor skills (symlinks) + +Each entry here is a **symlink** to the canonical skill under **`skills/`** at the repository root so Cursor loads **`SKILL.md`** from `.cursor/skills/`. + +See **[skills/README.md](../../skills/README.md)** for the catalog and how to add skills. diff --git a/.cursor/skills/material-ui-nextjs b/.cursor/skills/material-ui-nextjs new file mode 120000 index 00000000000000..e12533f33cb68f --- /dev/null +++ b/.cursor/skills/material-ui-nextjs @@ -0,0 +1 @@ +../../skills/material-ui-nextjs \ No newline at end of file diff --git a/.cursor/skills/material-ui-styling b/.cursor/skills/material-ui-styling new file mode 120000 index 00000000000000..61191aff60d083 --- /dev/null +++ b/.cursor/skills/material-ui-styling @@ -0,0 +1 @@ +../../skills/material-ui-styling \ No newline at end of file diff --git a/.cursor/skills/material-ui-tailwind b/.cursor/skills/material-ui-tailwind new file mode 120000 index 00000000000000..5c578b19d773b5 --- /dev/null +++ b/.cursor/skills/material-ui-tailwind @@ -0,0 +1 @@ +../../skills/material-ui-tailwind \ No newline at end of file diff --git a/.cursor/skills/material-ui-theming b/.cursor/skills/material-ui-theming new file mode 120000 index 00000000000000..3aad9812515609 --- /dev/null +++ b/.cursor/skills/material-ui-theming @@ -0,0 +1 @@ +../../skills/material-ui-theming \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md index d4c2b14a3af8f0..801f3b9bc45d85 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -162,6 +162,19 @@ import Button from '@mui/material/Button'; // Good import { Button } from '@mui/material'; // Avoid in packages ``` +## Agent Skills + +Packaged guidance for common integration topics lives under `skills/`. Each skill is a self-contained directory: + +| Skill | Focus | +| :--------------------------------------------------------------------- | :---------------------------------------------------------- | +| [skills/material-ui-styling](./skills/material-ui-styling/AGENTS.md) | `sx`, `styled()`, theme overrides, slots, global CSS | +| [skills/material-ui-theming](./skills/material-ui-theming/AGENTS.md) | `createTheme`, design tokens, `colorSchemes`, CSS variables | +| [skills/material-ui-nextjs](./skills/material-ui-nextjs/AGENTS.md) | App/Pages Router, Emotion cache, `next/font`, `Link`, SSR | +| [skills/material-ui-tailwind](./skills/material-ui-tailwind/AGENTS.md) | Tailwind v4 `@layer`, `enableCssLayer`, v3 interop | + +Read the relevant `AGENTS.md` when helping users with those topics. + ## Pre-PR Checklist 1. `pnpm prettier` - Format code diff --git a/docs/data/material/integrations/nextjs/nextjs.md b/docs/data/material/integrations/nextjs/nextjs.md index ac04b12cd45438..89bf355837f063 100644 --- a/docs/data/material/integrations/nextjs/nextjs.md +++ b/docs/data/material/integrations/nextjs/nextjs.md @@ -165,6 +165,60 @@ Then, replace the Next.js Link with the wrapper component: ``` +### URL-driven UI and the Suspense boundary + +When client components use Next.js App Router hooks that read the URL—for example `useSearchParams()` from `next/navigation` for filters, tabs, or pagination—Next.js expects a `` boundary around that part of the React tree. +Without it, you may see build failures or runtime messages about a missing Suspense boundary (behavior depends on your Next.js version and static vs dynamic rendering). + +This pattern is common with Material UI: `Table`, `Tabs`, `TextField`, and other controls are often implemented as client components that sync to the query string. + +Recommended structure: keep `page.tsx` as a server component when possible, and wrap only the client subtree that calls `useSearchParams` in ``. + +Avoid `fallback={null}` (or an empty fallback) for UI that reserves space in the layout (toolbars, filters, tab bars, and similar). +The server and the initial streamed HTML then omit that subtree, and the real content appears only after the client hydrates, which often causes layout shift and hurts CLS. +Prefer a fallback whose size and structure approximate the final UI, for example Material UI `Skeleton` inside `Stack` or `Box` with the same `minHeight`, flex direction, and breakpoints as the loaded component. + +```tsx title="app/orders/page.tsx" +import { Suspense } from 'react'; +import Box from '@mui/material/Box'; +import Skeleton from '@mui/material/Skeleton'; +import Stack from '@mui/material/Stack'; +import OrdersToolbar from './OrdersToolbar'; + +function OrdersToolbarFallback() { + return ( + + + + + + + ); +} + +export default function Page() { + return ( + }> + + + ); +} +``` + +`OrdersToolbar` would be a file marked with `'use client'` that calls `useSearchParams()` and renders Material UI components. +Adjust the fallback's layout and Skeleton sizes so they match your real toolbar (or filter row) as closely as possible. + +For details and version-specific notes, see the Next.js documentation for [`useSearchParams`](https://nextjs.org/docs/app/api-reference/functions/use-search-params). + ## Pages Router This section walks through the Material UI integration with the Next.js [Pages Router](https://nextjs.org/docs/pages/building-your-application), for both [Server-side Rendering](https://nextjs.org/docs/pages/building-your-application/rendering/server-side-rendering) (SSR) and [Static Site Generation](https://nextjs.org/docs/pages/building-your-application/rendering/static-site-generation) (SSG). diff --git a/skills/README.md b/skills/README.md new file mode 100644 index 00000000000000..102891a5ca62fc --- /dev/null +++ b/skills/README.md @@ -0,0 +1,68 @@ +# Material UI agent skills + +Packaged guidance for AI agents and humans. Each skill is a directory under `skills/` with this layout: + +```text +skills/ +├── README.md # this file +├── material-ui-styling/ # sx vs styled vs theme vs global CSS +│ ├── AGENTS.md # full guide (read for complete detail) +│ ├── SKILL.md # Cursor entry + index +│ ├── README.md +│ ├── metadata.json +│ └── reference.md +├── material-ui-theming/ # createTheme, tokens, dark mode, CSS variables +│ ├── AGENTS.md +│ ├── SKILL.md +│ ├── README.md +│ ├── metadata.json +│ └── reference.md +├── material-ui-nextjs/ # Next.js App/Pages Router, cache, fonts, Link +│ ├── AGENTS.md +│ ├── SKILL.md +│ ├── README.md +│ ├── metadata.json +│ └── reference.md +└── material-ui-tailwind/ # Tailwind v4 layers + v3 interoperability + ├── AGENTS.md + ├── SKILL.md + ├── README.md + ├── metadata.json + └── reference.md +``` + +## Files in each skill + +| File | Purpose | +| :-------------- | :------------------------------------------------------------------ | +| `AGENTS.md` | Full guide — the canonical source of truth for all agents and tools | +| `SKILL.md` | Cursor entry point and index (frontmatter + section summary) | +| `README.md` | Human-readable overview | +| `metadata.json` | Machine-readable metadata (version, references) | +| `reference.md` | Quick-reference cheat sheet (imports, API shapes) | + +## Tool-specific discovery + +### All AGENTS.md-compatible tools (Claude Code, Copilot, etc.) + +The root `AGENTS.md` lists each skill and links directly to `skills//AGENTS.md`. Any agent that reads `AGENTS.md` files will find the skills from there. + +### Cursor + +Symlinks under `.cursor/skills/` point at `skills/` so Cursor loads `SKILL.md` while the canonical content stays in `skills/`. See [.cursor/skills/README.md](../.cursor/skills/README.md). + +## Adding a skill + +1. Create `skills//` with `AGENTS.md`, `SKILL.md`, `README.md`, `metadata.json` (optional: `reference.md`). +2. Add an entry to the table in the root `AGENTS.md` linking to the new `AGENTS.md`. +3. For Cursor: `ln -s ../../skills/ .cursor/skills/` from the repo root (see existing symlinks). +4. List the new skill in the catalog below. + +## Catalog + +| Folder | Focus | +| :---------------------------------------------- | :------------------------------------------------------------------------------------------------------------- | +| [material-ui-styling](./material-ui-styling/) | Choosing styling scope: `sx`, `styled()`, theme overrides, global CSS; slots and state | +| [material-ui-theming](./material-ui-theming/) | Theme object, design tokens, `colorSchemes`, `cssVariables` / `theme.vars`, composition, TS augmentation | +| [material-ui-nextjs](./material-ui-nextjs/) | `@mui/material-nextjs`, App/Pages Router, Emotion cache, `next/font`, CSS layers, Next `Link` + MUI | +| [material-ui-tailwind](./material-ui-tailwind/) | Tailwind v4 `@layer` + `enableCssLayer`; `className` / `slotProps`; v3 preflight / `important` / `injectFirst` | diff --git a/skills/material-ui-nextjs/AGENTS.md b/skills/material-ui-nextjs/AGENTS.md new file mode 100644 index 00000000000000..65adf12817091e --- /dev/null +++ b/skills/material-ui-nextjs/AGENTS.md @@ -0,0 +1,144 @@ +# Material UI and Next.js + +Version 1.0.0 + +> Note: This document is for agents and LLMs integrating Material UI with Next.js. Source: `docs/data/material/integrations/nextjs/nextjs.md` and related integration docs in this repository. + +--- + +## Abstract + +Material UI uses Emotion for styles. On Next.js you must wire an Emotion cache so SSR and streaming produce correct CSS (prefer injecting styles into `head` instead of only `body`). The `@mui/material-nextjs` package supplies `AppRouterCacheProvider` (App Router) and `AppCacheProvider` / `DocumentHeadTags` (Pages Router). Material UI components ship as client components (`"use client"`); they still SSR but are not React Server Components. Match the package import suffix (for example `v15-appRouter`) to your Next.js major version. + +--- + +## Table of contents + +1. [App Router (recommended)](#app-router-recommended) +2. [Pages Router](#pages-router) +3. [Fonts (`next/font`)](#fonts-nextfont) +4. [CSS theme variables and SSR](#css-theme-variables-and-ssr) +5. [Other styling stacks (CSS layers)](#other-styling-stacks-css-layers) +6. [Next.js Link and `component` prop](#nextjs-link-and-component-prop) +7. [Further reading](#further-reading) + +--- + +## App Router (recommended) + +### Dependencies + +Have `@mui/material` and `next` installed, then add: + +- `@mui/material-nextjs` +- `@emotion/cache` + +Example: `pnpm add @mui/material-nextjs @emotion/cache` + +### Root layout + +In `app/layout.tsx`, wrap everything under `` with `AppRouterCacheProvider` from the entry that matches your Next major, for example: + +`import { AppRouterCacheProvider } from '@mui/material-nextjs/v15-appRouter';` + +(Use the `v1X-appRouter` path that matches your Next.js version if not on v15.) + +Why: it collects CSS from MUI System during server rendering and streaming so styles attach predictably; it is recommended so styles go to `` instead of only ``. See [Next.js integration—Configuration](https://mui.com/material-ui/integrations/nextjs/#configuration). + +### Optional cache `options` + +Pass `options` to `AppRouterCacheProvider` to override [Emotion cache options](https://emotion.sh/docs/@emotion/cache#options), for example `key: 'css'` (the default MUI key is `mui`). See [Next.js integration—Custom cache (optional)](https://mui.com/material-ui/integrations/nextjs/#custom-cache-optional). + +### URL hooks and Suspense + +Dashboards and internal tools often combine MUI client components with URL-driven UI (filters, tabs, pagination) using `useSearchParams()` from `next/navigation`. + +Next.js expects a `` boundary around the part of the tree that uses `useSearchParams` (and similar patterns that opt the route into client-side rendering), otherwise you can get build failures or runtime errors about a missing Suspense boundary. + +Practical pattern: keep `app/.../page.tsx` as a server component when possible; render a client subtree that uses components such as `Table`, `Tabs`, or `TextField` and is tied to the query string inside `` from that server page. Do not use `fallback={null}` for UI that occupies layout space (toolbars, filters, and similar); it tends to cause layout shift when the client mounts. Use a fallback that matches the real layout (for example `Skeleton` with `Stack` or `Box` and the same `minHeight` and rough dimensions as the final UI). Full example: [Next.js integration—URL-driven UI and the Suspense boundary](https://mui.com/material-ui/integrations/nextjs/#url-driven-ui-and-the-suspense-boundary). + +Official reference: [Next.js—`useSearchParams`](https://nextjs.org/docs/app/api-reference/functions/use-search-params) (static rendering and Suspense notes vary by major version). + +--- + +## Pages Router + +### Dependencies + +Add `@mui/material-nextjs`, `@emotion/cache`, and `@emotion/server`. + +Example: `pnpm add @mui/material-nextjs @emotion/cache @emotion/server` + +### `_document.tsx` + +- Import `DocumentHeadTags` and `documentGetInitialProps` from the `v15-pagesRouter` (or matching `v1X-pagesRouter`) entry. +- Render `` inside ``. +- Assign `getInitialProps` to call `documentGetInitialProps`. + +### `_app.tsx` + +Wrap the app with `AppCacheProvider` from the same major entry (for example `v15-pagesRouter`). + +### Optional: custom cache and cascade layers + +- Pass a custom `emotionCache` into `documentGetInitialProps` options when needed. +- For `@layer`, use `createEmotionCache({ enableCssLayer: true })` from `@mui/material-nextjs`, pass it from `_document` and align `_app` with the same cache pattern. See [Next.js integration—Cascade layers (optional)](https://mui.com/material-ui/integrations/nextjs/#cascade-layers-optional). + +### TypeScript + +Extend `Document` props with `DocumentHeadTagsProps` from the same import path. See [Next.js integration—TypeScript](https://mui.com/material-ui/integrations/nextjs/#typescript). + +--- + +## Fonts (`next/font`) + +App Router: theme modules that call `createTheme` need `'use client'` when they are consumed from server components. Use `next/font/google` (or local fonts), set `variable: '--font-…'`, put `className={font.variable}` on `` (or as in docs), and set `typography.fontFamily` to `'var(--font-…)'`. Wrap with `ThemeProvider` inside `AppRouterCacheProvider` as needed. + +Pages Router: similar pattern in `pages/_app.tsx` with `AppCacheProvider` and `ThemeProvider`. + +Details: [Next.js integration—Font optimization](https://mui.com/material-ui/integrations/nextjs/#font-optimization) (App) and [Next.js integration—Font optimization](https://mui.com/material-ui/integrations/nextjs/#font-optimization-1) (Pages). + +--- + +## CSS theme variables and SSR + +Enable `cssVariables: true` in `createTheme` when using [CSS theme variables](https://mui.com/material-ui/customization/css-theme-variables/overview/). For SSR flicker and `InitColorSchemeScript`, follow [CSS theme variables—Preventing SSR flickering](https://mui.com/material-ui/customization/css-theme-variables/configuration/#preventing-ssr-flickering) and [CSS theme variables overview—Advantages](https://mui.com/material-ui/customization/css-theme-variables/overview/#advantages). + +--- + +## Other styling stacks (CSS layers) + +If you combine MUI with Tailwind CSS, CSS Modules, or other global CSS, set `enableCssLayer: true` on `AppRouterCacheProvider`: + +`` + +That wraps MUI output in `@layer mui` so anonymous layers can override as intended. See [Next.js integration—Using other styling solutions](https://mui.com/material-ui/integrations/nextjs/#using-other-styling-solutions) and [MDN—@layer](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/At-rules/@layer). + +--- + +## Next.js Link and `component` prop + +Next.js v16: passing `next/link` directly into `component` can trigger "Functions cannot be passed directly to Client Components". Fix: a small client re-export: + +```tsx +'use client'; +import Link, { LinkProps } from 'next/link'; +export default Link; +``` + +Import that wrapper and use `component={Link}` on `Button` and similar. See [Next.js integration—Next.js v16 Client Component restriction](https://mui.com/material-ui/integrations/nextjs/#nextjs-v16-client-component-restriction). + +Pages Router and theme-wide patterns: see [Routing libraries—Next.js Pages Router](https://mui.com/material-ui/integrations/routing/#nextjs-pages-router) and the [material-ui-nextjs-pages-router-ts example](https://github.com/mui/material-ui/tree/master/examples/material-ui-nextjs-pages-router-ts). + +--- + +## Further reading + +| Topic | Link | +| :------------------------------- | :----------------------------------------------------------------------------------------------------- | +| Full integration guide | [Next.js integration](https://mui.com/material-ui/integrations/nextjs/) | +| Example (App Router, TypeScript) | [material-ui-nextjs-ts](https://github.com/mui/material-ui/tree/master/examples/material-ui-nextjs-ts) | +| Routing + Link adapters | [Routing libraries](https://mui.com/material-ui/integrations/routing/) | +| RSC vs SSR (terminology) | [React WG discussion](https://github.com/reactwg/server-components/discussions/4) | + +Import path cheat sheet: [reference.md](reference.md). diff --git a/skills/material-ui-nextjs/README.md b/skills/material-ui-nextjs/README.md new file mode 100644 index 00000000000000..114ea6e5ac94bf --- /dev/null +++ b/skills/material-ui-nextjs/README.md @@ -0,0 +1,16 @@ +# Material UI + Next.js (agent skill) + +Integration guide for Material UI with the Next.js App Router and Pages Router: Emotion cache via `@mui/material-nextjs`, `ThemeProvider`, `next/font`, CSS layers with other tools, and `Link` usage. + +## Files in this folder + +| File | Purpose | +| :------------ | :--------------------------------------- | +| AGENTS.md | Full agent/LLM document | +| SKILL.md | Cursor skill entry (frontmatter + index) | +| metadata.json | Version, abstract, references | +| reference.md | Import paths and layout sketch | + +## Cursor + +Canonical files live under `skills/`. `.cursor/skills/material-ui-nextjs` should symlink here so Cursor loads SKILL.md. diff --git a/skills/material-ui-nextjs/SKILL.md b/skills/material-ui-nextjs/SKILL.md new file mode 100644 index 00000000000000..36d67bc8b1d6e3 --- /dev/null +++ b/skills/material-ui-nextjs/SKILL.md @@ -0,0 +1,38 @@ +--- +name: material-ui-nextjs +description: Integrates Material UI with Next.js App and Pages routers using @mui/material-nextjs, Emotion cache providers, next/font, CSS layers with Tailwind/CSS Modules, Link component prop patterns, CSS theme variables SSR notes, and App Router useSearchParams + Suspense. Use when setting up or debugging MUI in a Next.js app. +license: MIT +metadata: + author: mui + version: '1.0.0' +--- + +# Material UI and Next.js + +Agent skill for Next.js + Material UI wiring (SSR/streaming, cache providers, fonts, layers, Link, App Router URL state). SKILL.md is the entry; AGENTS.md is the full guide. + +## When to apply + +- New App Router or Pages Router app using `@mui/material` +- Styles missing, wrong order, or in `body` instead of `head` +- `next/font` + `ThemeProvider` / `createTheme` +- Tailwind or CSS Modules + MUI (`enableCssLayer`) +- `Button` + `component={Link}` or Next.js v16 client boundary errors +- `useSearchParams` / URL-driven MUI views and Suspense boundaries + +## Sections in AGENTS.md + +| Area | Topics | +| :------------ | :-------------------------------------------------------------------------------------- | +| App Router | `AppRouterCacheProvider`, `@emotion/cache`, `options`, `useSearchParams` + `` | +| Pages Router | `_document`, `_app`, `DocumentHeadTags`, `AppCacheProvider` | +| Fonts | `'use client'` theme, `next/font`, CSS variables on `html` | +| CSS variables | `cssVariables`, SSR flicker docs | +| CSS layers | `enableCssLayer`, Tailwind / other CSS | +| Link | Client wrapper, routing guide, examples repo | + +## Full guide + +Read [AGENTS.md](./AGENTS.md) for complete steps and doc links. + +[reference.md](./reference.md) lists import paths and provider shape. diff --git a/skills/material-ui-nextjs/metadata.json b/skills/material-ui-nextjs/metadata.json new file mode 100644 index 00000000000000..90921a4a033d07 --- /dev/null +++ b/skills/material-ui-nextjs/metadata.json @@ -0,0 +1,11 @@ +{ + "version": "1.0.0", + "organization": "Material UI", + "abstract": "Documents Next.js integration for Material UI: AppRouterCacheProvider and Pages Router Document/App cache wiring, Emotion options, next/font with themes, CSS theme variables and SSR flicker pointers, enableCssLayer for Tailwind/CSS Modules, and Next.js Link client-wrapper patterns.", + "references": [ + "https://mui.com/material-ui/integrations/nextjs/", + "https://mui.com/material-ui/integrations/routing/", + "https://github.com/mui/material-ui/tree/master/examples/material-ui-nextjs-ts", + "https://nextjs.org/docs/app" + ] +} diff --git a/skills/material-ui-nextjs/reference.md b/skills/material-ui-nextjs/reference.md new file mode 100644 index 00000000000000..2b6f5997c51206 --- /dev/null +++ b/skills/material-ui-nextjs/reference.md @@ -0,0 +1,28 @@ +# Material UI + Next.js: reference + +## `@mui/material-nextjs` entry points + +Pick the `v1X-*` segment that matches the app's Next.js major (see the package's README on npm if a new major adds a new entry). + +| Router | Typical import path | +| :----------- | :--------------------------------------------------------------------- | +| App Router | `@mui/material-nextjs/v15-appRouter` (or `v14-appRouter`, etc.) | +| Pages Router | `@mui/material-nextjs/v15-pagesRouter` (or matching `v1X-pagesRouter`) | + +Pages Router also uses `@emotion/server` for the documented setup; App Router uses `@emotion/cache` only in the default instructions. + +## Provider placement (App Router) + +```text + + + + + {children} + + + + +``` + +Order and `next/font` `className` on `html` follow [Next.js integration—Font optimization](https://mui.com/material-ui/integrations/nextjs/#font-optimization). diff --git a/skills/material-ui-styling/AGENTS.md b/skills/material-ui-styling/AGENTS.md new file mode 100644 index 00000000000000..c005c1ff44b0c3 --- /dev/null +++ b/skills/material-ui-styling/AGENTS.md @@ -0,0 +1,138 @@ +# Material UI styling + +Version 1.0.0 + +> Note: This document is for agents and LLMs maintaining or generating Material UI code. It follows [How to customize](https://mui.com/material-ui/customization/how-to-customize/) and related sources in this repository (`docs/data/material/customization/`, `docs/data/system/`). + +--- + +## Abstract + +Material UI stacks four strategies from narrowest to broadest scope. Pick the smallest scope that solves the problem to avoid scattering global rules. The `sx` prop is the default for one-off tweaks; `styled()` is for reusable wrappers; the theme's `components` API is for app-wide consistency; `GlobalStyles` / `CssBaseline` is for baseline HTML or cross-cutting globals. + +--- + +## Table of contents + +1. [Quick decision (use in order)](#quick-decision-use-in-order) +2. [One-off: `sx` prop](#1-one-off-sx-prop) +3. [Reusable: `styled()`](#2-reusable-styled) +4. [Global theme: `createTheme({ components })`](#3-global-theme-createtheme-components) +5. [Global CSS: `GlobalStyles` / `CssBaseline`](#4-global-css-globalstyles--cssbaseline) +6. [`sx` vs `styled()`](#sx-vs-styled-differences-agents-should-know) +7. [Imports and consistency](#imports-and-consistency) +8. [Further reading](#further-reading-repo--site) + +--- + +## Quick decision (use in order) + +1. Single instance or local layout? → [`sx`](https://mui.com/system/getting-started/the-sx-prop/) +2. Same override in many places? → [`styled()`](https://mui.com/system/styled/) around the MUI component (or a thin wrapper component) +3. All instances of a component should look different by default? → [`theme.components`](https://mui.com/material-ui/customization/theme-components/) (`styleOverrides`, `variants`, `defaultProps`) +4. Global element baselines (e.g. all `h1`) or non-component CSS? → [`GlobalStyles`](https://mui.com/material-ui/api/global-styles/) or [`CssBaseline`](https://mui.com/material-ui/react-css-baseline/) overrides + +Do not jump to global theme overrides for a one-off screen; do not use `sx` for large repeated systems if a themed variant or `styled()` wrapper is clearer. + +--- + +## 1. One-off: `sx` prop + +Use when: changing one instance (or a small inline case) with access to the theme. + +- All Material UI components support `sx`. +- Supports theme shortcuts (`palette`, `spacing`, breakpoints, etc.), pseudo-selectors, nested selectors, and responsive objects. + +Nested parts (slots): target internal slots with global class fragments, e.g. `'& .MuiSlider-thumb'`. Discover the slot name in DevTools; the pattern is `Mui[Component]-[slot]`. Do not rely on the full hashed class string. Use only the stable `Mui*` fragment. + +State styles: MUI uses global state classes (`.Mui-disabled`, `.Mui-selected`, etc.) with specificity comparable to pseudo-classes. Override with increased specificity (e.g. combine with your class or the component root), never bare global state selectors alone. + +```css +/* Bad: affects every component using .Mui-error */ +.Mui-error { + color: red; +} + +/* Good: scoped to OutlinedInput root */ +.MuiOutlinedInput-root.Mui-error { + color: red; +} +``` + +See [How to customize—State classes](https://mui.com/material-ui/customization/how-to-customize/#state-classes). + +`className`: use when integrating with external CSS or CSS Modules; combine with the same slot/state rules as above. + +--- + +## 2. Reusable: `styled()` + +Use when: the same customized component appears in multiple places and deserves a named component. + +```ts +import { styled } from '@mui/material/styles'; +``` + +- Prefer `@mui/material/styles` when using Material UI so the default theme matches the rest of the app. +- `styled()` adds theme integration, optional `name` / `slot` for theme overrides, and `sx` on the result (unless disabled). +- For custom props, use `shouldForwardProp` so DOM/React does not receive invalid attributes. Extend the component's prop types in TypeScript. + +Dynamic styling: prefer CSS variables or conditional style objects in the style callback; avoid per-field functions inside the style object for readability (see [styled() docs](https://mui.com/system/styled/)). + +--- + +## 3. Global theme: `createTheme({ components })` + +Use when: default look of `Button`, `TextField`, etc. should change everywhere. + +- `defaultProps`: change defaults (e.g. `disableRipple` on `MuiButtonBase`). +- `styleOverrides`: target slots (`root`, `input`, …) with plain CSS-in-JS objects; nested selectors allowed. +- `variants`: map props to extra styles (built-in props like `variant: 'outlined'` or custom values you document for your design system). + +Caveat: the theme is not tree-shakable. For heavy one-off customizations, a new component is often better than bloating the theme. + +Full API: [Themed components](https://mui.com/material-ui/customization/theme-components/). + +--- + +## 4. Global CSS: `GlobalStyles` / `CssBaseline` + +Use when: styling raw HTML elements or app-wide snippets that are not tied to a single MUI component instance. + +- Prefer hoisting `` to a module-level constant so the style tag does not churn on re-renders. +- `styles` can be a callback for theme access. +- Can extend `MuiCssBaseline` `styleOverrides` if the app already uses `CssBaseline`. + +--- + +## `sx` vs `styled()`: differences agents should know + +| Topic | `sx` | `styled()` style object | +| :------------------------------------------- | :----------------- | :----------------------------------------------------------- | +| Theme spacing shorthand (`m`, `p`, `gap`, …) | Yes | No. Use `theme.spacing()` in a function or plain CSS values. | +| Meaning of numeric padding like `1` | Theme spacing unit | Pixels, not `theme.spacing(1)` | +| Theme palette strings (`'primary.main'`) | Yes | Use `theme` in a function | + +To reuse `sx` logic inside `styled()`, use theme's `unstable_sx` (see [styled()—Difference with the sx prop](https://mui.com/system/styled/#difference-with-the-sx-prop)). + +--- + +## Imports and consistency + +- In application code, prefer one-level imports from packages (e.g. `@mui/material/Button`) to avoid pulling the entire barrel. +- `Box` / `Stack` / `Typography` / `Grid`: system layout props apply directly on these; other components use `sx` for system shortcuts, not arbitrary CSS prop shortcuts on the component itself. + +--- + +## Further reading (repo / site) + +| Topic | Doc | +| :---------------------- | :------------------------------------------------------------------------------------------ | +| Choosing strategy | [How to customize](https://mui.com/material-ui/customization/how-to-customize/) | +| `sx` reference | [The sx prop](https://mui.com/system/getting-started/the-sx-prop/) | +| `styled()` API | [styled()](https://mui.com/system/styled/) | +| Theme per component | [Themed components](https://mui.com/material-ui/customization/theme-components/) | +| System property mapping | [System properties](https://mui.com/system/properties/) | +| State / class naming | [Advanced—Class names](https://mui.com/system/styles/advanced/#class-names) (system styles) | + +For MUI-specific class and state tables, see [reference.md](reference.md). diff --git a/skills/material-ui-styling/README.md b/skills/material-ui-styling/README.md new file mode 100644 index 00000000000000..e2984fbb912ee3 --- /dev/null +++ b/skills/material-ui-styling/README.md @@ -0,0 +1,16 @@ +# Material UI styling (agent skill) + +Material UI-specific guidance for which styling mechanism to use (`sx`, `styled()`, theme overrides, global CSS), aligned with the official docs in this monorepo. + +## Files in this folder + +| File | Purpose | +| :------------ | :------------------------------------------------------------- | +| AGENTS.md | Full agent/LLM document (read this for complete rules) | +| SKILL.md | Cursor skill entry: frontmatter + index + pointer to AGENTS.md | +| metadata.json | Version, abstract, references | +| reference.md | State classes and slot naming tables | + +## Cursor + +Project skills are loaded from `.cursor/skills/`. This repository symlinks each package under `.cursor/skills/` to the canonical `skills/` directory at the repo root. diff --git a/skills/material-ui-styling/SKILL.md b/skills/material-ui-styling/SKILL.md new file mode 100644 index 00000000000000..dd96c0257c76af --- /dev/null +++ b/skills/material-ui-styling/SKILL.md @@ -0,0 +1,35 @@ +--- +name: material-ui-styling +description: Chooses the right Material UI styling approach (sx, styled, theme overrides, global CSS) from official MUI guidance. Use when styling @mui/material components, customizing themes, overriding slots, or comparing sx vs styled. +license: MIT +metadata: + author: mui + version: '1.0.0' +--- + +# Material UI styling + +Agent skill for picking the correct styling layer in Material UI (narrowest scope first). SKILL.md is the entry and index; AGENTS.md is the full guide. + +## When to apply + +- Choosing among `sx`, `styled()`, theme `components`, or global CSS for a change +- Overriding component slots or state safely +- Comparing `sx` vs `styled()` semantics (spacing, theme shortcuts) + +## Sections in AGENTS.md (by priority) + +| Order | Topic | Scope | +| :---- | :----------------------------- | :------------------------------------ | +| 1 | Quick decision | Pick `sx` → `styled` → theme → global | +| 2 | `sx` prop | One-off / local | +| 3 | `styled()` | Reusable wrapper | +| 4 | `createTheme({ components })` | All instances | +| 5 | `GlobalStyles` / `CssBaseline` | HTML baseline / globals | +| 6 | `sx` vs `styled()` table | Foot-gun prevention | + +## Full guide + +Read [AGENTS.md](./AGENTS.md) for the complete instructions, examples, and doc links. + +Supplementary tables: [reference.md](./reference.md). diff --git a/skills/material-ui-styling/metadata.json b/skills/material-ui-styling/metadata.json new file mode 100644 index 00000000000000..69113eabfe5d0f --- /dev/null +++ b/skills/material-ui-styling/metadata.json @@ -0,0 +1,11 @@ +{ + "version": "1.0.0", + "organization": "Material UI", + "abstract": "Guides selection of Material UI styling strategies from narrowest to broadest scope (sx, styled, theme.components, GlobalStyles/CssBaseline), including slot/state overrides and sx vs styled foot-guns.", + "references": [ + "https://mui.com/material-ui/customization/how-to-customize/", + "https://mui.com/system/getting-started/the-sx-prop/", + "https://mui.com/system/styled/", + "https://mui.com/material-ui/customization/theme-components/" + ] +} diff --git a/skills/material-ui-styling/reference.md b/skills/material-ui-styling/reference.md new file mode 100644 index 00000000000000..cb327151326f94 --- /dev/null +++ b/skills/material-ui-styling/reference.md @@ -0,0 +1,31 @@ +# Material UI styling: reference tables + +## Global state class names + +Use only in combination with a component or scoped selector (never alone). + +| State | Global class | +| :------------ | :------------------ | +| active | `.Mui-active` | +| checked | `.Mui-checked` | +| completed | `.Mui-completed` | +| disabled | `.Mui-disabled` | +| error | `.Mui-error` | +| expanded | `.Mui-expanded` | +| focus visible | `.Mui-focusVisible` | +| focused | `.Mui-focused` | +| readOnly | `.Mui-readOnly` | +| required | `.Mui-required` | +| selected | `.Mui-selected` | + +Source: [How to customize](https://mui.com/material-ui/customization/how-to-customize/) (`docs/data/material/customization/how-to-customize/how-to-customize.md`). + +## Slot class name pattern + +Injected classes follow: `[hash]-Mui[ComponentName]-[slot]`. + +For selectors, use the stable fragment `Mui[ComponentName]-[slot]` (e.g. `.MuiSlider-thumb`), not the full hashed class. + +## Theme component keys + +Override via `createTheme({ components: { MuiButton: { ... } } })`. The key matches the component's internal name (e.g. `MuiButton`, `MuiTextField`). Check the component's Customization section in the docs for slot names and theme key. diff --git a/skills/material-ui-tailwind/AGENTS.md b/skills/material-ui-tailwind/AGENTS.md new file mode 100644 index 00000000000000..48c5c2598fdbcc --- /dev/null +++ b/skills/material-ui-tailwind/AGENTS.md @@ -0,0 +1,128 @@ +# Material UI and Tailwind CSS + +Version 1.0.0 + +> Note: For agents and LLMs combining Material UI with Tailwind CSS. Primary source for v4: `docs/data/material/integrations/tailwindcss/tailwindcss-v4.md`. v3: `docs/data/material/integrations/interoperability/interoperability.md` (Tailwind CSS v3). + +--- + +## Abstract + +Tailwind CSS v4 integration with Material UI is built on CSS cascade layers: MUI emits styles inside `@layer mui`, and Tailwind's `utilities` layer must come after so utilities can override without `!important`. Enable MUI's layer mode with `enableCssLayer: true` (Next.js via `AppRouterCacheProvider` / shared `createEmotionCache`) or `StyledEngineProvider` with `enableCssLayer` (Vite and other SPAs). Declare layer order (for example `@layer theme, base, mui, components, utilities`) before `@import 'tailwindcss'` (or inject the same string with `GlobalStyles` where the docs show). Tailwind CSS v3 uses a different recipe (preflight off, `important`, `StyledEngineProvider` with `injectFirst`, portal `container`). Prefer v4 for new work when possible. + +--- + +## Table of contents + +1. [Tailwind CSS v4 (preferred)](#tailwind-css-v4-preferred) +2. [Next.js specifics](#nextjs-specifics) +3. [Vite and other SPAs](#vite-and-other-spas) +4. [Applying utilities to MUI components](#applying-utilities-to-mui-components) +5. [Theme tokens in Tailwind (`@theme`)](#theme-tokens-in-tailwind-theme) +6. [VS Code IntelliSense](#vs-code-intellisense) +7. [Tailwind CSS v3 (legacy)](#tailwind-css-v3-legacy) +8. [Troubleshooting](#troubleshooting) +9. [Further reading](#further-reading) + +--- + +## Tailwind CSS v4 (preferred) + +### Goals + +1. Generate Tailwind with the `@layer` directive. +2. Order layers so `mui` comes before `utilities`, so Tailwind utilities override MUI predictably. + +See [Tailwind CSS v4 integration—Overview](https://mui.com/material-ui/integrations/tailwindcss/tailwindcss-v4/#overview). + +### Layer stack (typical) + +At the top of your global CSS (example from docs): + +```css +@layer theme, base, mui, components, utilities; +@import 'tailwindcss'; +``` + +Adjust file paths to your app (`src/app/global.css`, `styles/global.css`, etc.). + +--- + +## Next.js specifics + +1. Complete the [Next.js integration—App Router](https://mui.com/material-ui/integrations/nextjs/#app-router) or [Next.js integration—Pages Router](https://mui.com/material-ui/integrations/nextjs/#pages-router) setup first. +2. App Router: `` in the root layout. `suppressHydrationWarning` on `` appears in the doc example when relevant. +3. Pages Router: shared `createEmotionCache({ enableCssLayer: true })` from `@mui/material-nextjs`, passed through `documentGetInitialProps`; `AppCacheProvider` uses the same cache; layer order via `GlobalStyles` as the first child inside `AppCacheProvider`. See [Tailwind CSS v4 integration—Next.js Pages Router](https://mui.com/material-ui/integrations/tailwindcss/tailwindcss-v4/#nextjs-pages-router). + +For a concise provider checklist, see the material-ui-nextjs skill and [Next.js integration—Using other styling solutions](https://mui.com/material-ui/integrations/nextjs/#using-other-styling-solutions). + +--- + +## Vite and other SPAs + +1. `StyledEngineProvider` with `enableCssLayer`. +2. `GlobalStyles` injecting `@layer theme, base, mui, components, utilities;` before the app tree. + +See [Tailwind CSS v4 integration—Vite.js or any other SPA](https://mui.com/material-ui/integrations/tailwindcss/tailwindcss-v4/#vitejs-or-any-other-spa). + +Example repo: [material-ui-vite-tailwind-ts](https://github.com/mui/material-ui/tree/master/examples/material-ui-vite-tailwind-ts). + +--- + +## Applying utilities to MUI components + +- `className`: root element of the component. +- `slotProps.{slot}.className`: interior [slots](https://mui.com/material-ui/customization/overriding-component-structure/#interior-slots). + +See [Tailwind CSS v4 integration—Usage](https://mui.com/material-ui/integrations/tailwindcss/tailwindcss-v4/#usage). + +--- + +## Theme tokens in Tailwind (`@theme`) + +To reuse MUI theme variables (for example `--mui-palette-primary-main`, typography, breakpoints) as Tailwind tokens, copy the `@theme inline { ... }` block from the docs into your CSS. It is long and maintained on the doc page; do not hand-roll partial lists unless you know exactly which tokens you need. + +See [Tailwind CSS v4 integration—Extend Material UI classes](https://mui.com/material-ui/integrations/tailwindcss/tailwindcss-v4/#extend-material-ui-classes) and the linked [playground](https://play.tailwindcss.com/mh7Ym0mGff). + +Requirement: MUI CSS theme variables (`cssVariables: true` in `createTheme`) so the `--mui-*` variables exist. Align with the material-ui-theming skill. + +--- + +## VS Code IntelliSense + +For `slotProps` and similar, add `tailwindCSS.experimental.classRegex` in VS Code `settings.json` as in [Tailwind CSS v4 integration—Tailwind CSS IntelliSense for VS Code](https://mui.com/material-ui/integrations/tailwindcss/tailwindcss-v4/#tailwind-css-intellisense-for-vs-code). + +Snippet also lives in [reference.md](reference.md). + +--- + +## Tailwind CSS v3 (legacy) + +Use the interoperability guide, not the v4 page: + +1. Install Tailwind v3 per upstream docs. +2. `corePlugins: { preflight: false }` so MUI `CssBaseline` owns base resets. +3. `important: '#__next'` or `'#root'`; App Router may need `id="__next"` on `` manually. +4. `StyledEngineProvider` with `injectFirst` (or Emotion `prepend: true` cache) for injection order. +5. Theme `defaultProps` `container` on `Modal`, `Dialog`, `Popover`, `Popper` to the same root as `important`. + +See [Interoperability—Tailwind CSS v3](https://mui.com/material-ui/integrations/interoperability/#tailwind-css-v3) and [Interoperability—Troubleshooting](https://mui.com/material-ui/integrations/interoperability/#troubleshooting) (table of root IDs). + +--- + +## Troubleshooting + +v4: confirm Tailwind >= v4, layer order, and DevTools cascade layers (`mui` before `utilities`). See [Tailwind CSS v4 integration—Troubleshooting](https://mui.com/material-ui/integrations/tailwindcss/tailwindcss-v4/#troubleshooting). + +v3: verify `important` selector matches root `id`, `preflight: false`, and `injectFirst`. See the interoperability Troubleshooting subsection linked above. + +--- + +## Further reading + +| Topic | Link | +| :------------------------ | :---------------------------------------------------------------------------------------------------------------------------------------- | +| Tailwind CSS v4 + MUI | [Tailwind CSS v4 integration](https://mui.com/material-ui/integrations/tailwindcss/tailwindcss-v4/) | +| CSS layers (MUI concepts) | [CSS Layers](https://mui.com/material-ui/customization/css-layers/) | +| Interior slots | [Overriding component structure—Interior slots](https://mui.com/material-ui/customization/overriding-component-structure/#interior-slots) | +| Tailwind v3 + MUI | [Interoperability—Tailwind CSS v3](https://mui.com/material-ui/integrations/interoperability/#tailwind-css-v3) | diff --git a/skills/material-ui-tailwind/README.md b/skills/material-ui-tailwind/README.md new file mode 100644 index 00000000000000..62eb1d228a0b77 --- /dev/null +++ b/skills/material-ui-tailwind/README.md @@ -0,0 +1,16 @@ +# Material UI + Tailwind CSS (agent skill) + +Covers Tailwind CSS v4 with Material UI (cascade layers, `enableCssLayer`) and summarizes v3 patterns from the interoperability guide (preflight, `important`, `injectFirst`). + +## Files in this folder + +| File | Purpose | +| :------------ | :---------------------------------------------- | +| AGENTS.md | Full agent/LLM document | +| SKILL.md | Cursor skill entry | +| metadata.json | Version, abstract, references | +| reference.md | Layer line, IntelliSense JSON, v3 config sketch | + +## Cursor + +`.cursor/skills/material-ui-tailwind` should symlink to this directory. diff --git a/skills/material-ui-tailwind/SKILL.md b/skills/material-ui-tailwind/SKILL.md new file mode 100644 index 00000000000000..a9114d787cb88b --- /dev/null +++ b/skills/material-ui-tailwind/SKILL.md @@ -0,0 +1,36 @@ +--- +name: material-ui-tailwind +description: Integrates Material UI with Tailwind CSS v4 using cascade layers (enableCssLayer, @layer order) and documents Tailwind v3 interoperability (preflight, important, injectFirst, portals). Use when combining MUI with Tailwind utilities, slotProps className, or theme token bridges. +license: MIT +metadata: + author: mui + version: '1.0.0' +--- + +# Material UI and Tailwind CSS + +Agent skill for MUI + Tailwind. SKILL.md is the entry; AGENTS.md is the full guide. + +## When to apply + +- Tailwind utilities not overriding MUI (specificity / layer order) +- Setting up v4 with Next.js App or Pages Router, or Vite +- `className` / `slotProps.*.className` on MUI components +- Mapping `--mui-*` variables into Tailwind `@theme` +- Legacy v3 setups or migrations + +## Sections in AGENTS.md + +| Area | Topics | +| :----------- | :---------------------------------------------------- | +| v4 | `@layer` order, `mui` before `utilities` | +| Next.js | `enableCssLayer`, Pages `GlobalStyles` + shared cache | +| SPA | `StyledEngineProvider` + `enableCssLayer` | +| Usage | Root vs slot `className` | +| `@theme` | Full snippet on docs site; needs `cssVariables` | +| IntelliSense | VS Code `classRegex` | +| v3 | preflight, `important`, `injectFirst`, portals | + +## Full guide + +Read [AGENTS.md](./AGENTS.md). Copy-paste snippets: [reference.md](./reference.md). diff --git a/skills/material-ui-tailwind/metadata.json b/skills/material-ui-tailwind/metadata.json new file mode 100644 index 00000000000000..f4305d929a8964 --- /dev/null +++ b/skills/material-ui-tailwind/metadata.json @@ -0,0 +1,11 @@ +{ + "version": "1.0.0", + "organization": "Material UI", + "abstract": "Tailwind CSS v4 with Material UI via @layer ordering and enableCssLayer; Next.js App/Pages and Vite setup; className and slotProps; @theme token bridge from --mui-* variables; VS Code IntelliSense; Tailwind v3 legacy path via interoperability guide.", + "references": [ + "https://mui.com/material-ui/integrations/tailwindcss/tailwindcss-v4/", + "https://mui.com/material-ui/integrations/interoperability/#tailwind-css-v3", + "https://mui.com/material-ui/customization/css-layers/", + "https://github.com/mui/material-ui/tree/master/examples/material-ui-vite-tailwind-ts" + ] +} diff --git a/skills/material-ui-tailwind/reference.md b/skills/material-ui-tailwind/reference.md new file mode 100644 index 00000000000000..34d85bd79d0295 --- /dev/null +++ b/skills/material-ui-tailwind/reference.md @@ -0,0 +1,43 @@ +# Material UI + Tailwind CSS: reference + +## Layer order (v4) + +```css +@layer theme, base, mui, components, utilities; +@import 'tailwindcss'; +``` + +Pages Router + GlobalStyles (first child of `AppCacheProvider`): + +```jsx + +``` + +## VS Code `settings.json` (IntelliSense for `slotProps`) + +```json +{ + "tailwindCSS.experimental.classRegex": [["className\\s*:\\s*['\"]([^'\"]*)['\"]"]] +} +``` + +From [Tailwind CSS v4 integration—Tailwind CSS IntelliSense for VS Code](https://mui.com/material-ui/integrations/tailwindcss/tailwindcss-v4/#tailwind-css-intellisense-for-vs-code). + +## v3 `tailwind.config.js` sketch + +```js +module.exports = { + corePlugins: { + preflight: false, + }, + important: '#__next', // or '#root' for Vite + // ... +}; +``` + +See [Interoperability—Tailwind CSS v3](https://mui.com/material-ui/integrations/interoperability/#tailwind-css-v3). + +## Related skills + +- material-ui-nextjs: `AppRouterCacheProvider`, `enableCssLayer`, Pages `emotionCache` +- material-ui-theming: `cssVariables: true` for `--mui-*` token bridging diff --git a/skills/material-ui-theming/AGENTS.md b/skills/material-ui-theming/AGENTS.md new file mode 100644 index 00000000000000..e1aba0b909d60a --- /dev/null +++ b/skills/material-ui-theming/AGENTS.md @@ -0,0 +1,122 @@ +# Material UI theming and design tokens + +Version 1.0.0 + +> Note: This document is for agents and LLMs implementing themes and design tokens with Material UI. Grounded in `docs/data/material/customization/` (theming, palette, dark-mode, css-theme-variables, typography, spacing, shape). + +--- + +## Abstract + +A Material UI theme is a single object of design tokens (palette, typography, spacing, shape, breakpoints, etc.) plus optional per-component defaults (`theme.components`). Apps typically call `createTheme` once (or in composed steps), pass the result to `ThemeProvider` near the root, and read values with `useTheme`, `sx`, or `styled`. For system-driven light/dark, prefer `colorSchemes` and related APIs over a static `palette.mode`-only setup when you need toggling, tab sync, and SSR-friendly behavior; enable `cssVariables` when you want `theme.vars`, fewer theme nests for dark regions, and clearer debugging via `--mui-*` CSS variables. + +--- + +## Table of contents + +1. [Core setup](#core-setup) +2. [Where tokens live (design token map)](#where-tokens-live-design-token-map) +3. [Palette quick facts](#palette-quick-facts) +4. [Color schemes vs palette-only dark](#color-schemes-vs-palette-only-dark) +5. [CSS theme variables (`cssVariables: true`)](#css-theme-variables-cssvariables-true) +6. [Typography and spacing](#typography-and-spacing) +7. [Composing and merging themes](#composing-and-merging-themes) +8. [Nesting `ThemeProvider`](#nesting-themeprovider) +9. [Custom tokens (brand-specific design keys)](#custom-tokens-brand-specific-design-keys) +10. [Further reading](#further-reading) + +--- + +## Core setup + +1. `import { createTheme, ThemeProvider } from '@mui/material/styles'` (Material UI default theme). +2. Build a theme with `createTheme({ ... })`; wrap the app in `` so descendants receive context. +3. Use `` inside the provider when you want baseline element styles and correct dark background behavior (see [Dark mode](https://mui.com/material-ui/customization/dark-mode/)). + +Access in components: `useTheme()` from `@mui/material/styles`. + +--- + +## Where tokens live (design token map) + +| Area | Role | Doc | +| :------------ | :-------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------- | +| `palette` | Semantic colors (`primary`, `secondary`, `error`, …), text, background, divider, action | [Palette](https://mui.com/material-ui/customization/palette/) | +| `typography` | `fontFamily`, `fontSize`, variants (`h1` through `body2`, `button`, …) | [Typography](https://mui.com/material-ui/customization/typography/) | +| `spacing` | `theme.spacing(n)` scale (default 8px per unit) | [Spacing](https://mui.com/material-ui/customization/spacing/) | +| `shape` | `borderRadius` (default 4); optional extra radii need TS augmentation | [Shape](https://mui.com/material-ui/customization/shape/) | +| `breakpoints` | Responsive keys for `sx` / media queries | [Breakpoints](https://mui.com/material-ui/customization/breakpoints/) | +| `zIndex` | Layering tokens | [z-index](https://mui.com/material-ui/customization/z-index/) | +| `transitions` | Duration / easing helpers | [Transitions](https://mui.com/material-ui/customization/transitions/) | +| `components` | `defaultProps`, `styleOverrides`, `variants` per `Mui*` key | [Themed components](https://mui.com/material-ui/customization/theme-components/) | + +Full defaults: [Default theme explorer](https://mui.com/material-ui/customization/default-theme/). + +--- + +## Palette quick facts + +- Each palette color is usually `main`, `light`, `dark`, `contrastText`. Supplying `main` alone is often enough; `createTheme` can derive the rest. +- Use `@mui/material/colors` (e.g. `purple[500]`) for Material Design hues when building a palette. +- `palette.mode: 'dark'` forces a dark palette for the whole theme; if you use a fully custom palette with dark mode, ensure values match the mode (see [Dark mode](https://mui.com/material-ui/customization/dark-mode/)). + +--- + +## Color schemes vs palette-only dark + +- `colorSchemes` (e.g. `colorSchemes: { dark: true }`) enables built-in behavior: system preference, tab sync, optional transition disable on scheme change, storage, etc. Docs recommend it over the older, narrower palette-only approach for those features. +- If both `colorSchemes` and `palette` are set, `palette` takes precedence. Avoid accidental overrides. +- `useColorScheme` reads/updates mode for toggling. `mode` can be `undefined` on the first render; handle that to avoid hydration mismatches. +- `ThemeProvider` supports `storageManager`, `disableTransitionOnChange`, `noSsr`, etc., for color-scheme UX and SSR (see [Dark mode](https://mui.com/material-ui/customization/dark-mode/)). + +--- + +## CSS theme variables (`cssVariables: true`) + +- Set `cssVariables: true` in `createTheme` so components use `var(--mui-...)` values. Prefer `theme.vars` in style callbacks when variables are enabled (mirrors palette/typography as CSS var references). See [Usage](https://mui.com/material-ui/customization/css-theme-variables/usage/). +- Do not pass a custom `vars` key into `createTheme`. That key is reserved and autogenerated for this feature. +- For dark-specific styles with CSS variables, use `theme.applyStyles('dark', { ... })` rather than branching on `theme.palette.mode` in ways that cause flicker (see docs warning in [Usage](https://mui.com/material-ui/customization/css-theme-variables/usage/) and [Configuration](https://mui.com/material-ui/customization/css-theme-variables/configuration/)). +- Trade-offs: larger HTML (both schemes' variables), possible FCP impact; benefits include less JS work on scheme switch and better SSR dark experience. See [Overview](https://mui.com/material-ui/customization/css-theme-variables/overview/). +- `CssVarsProvider` is superseded by `ThemeProvider` with the same capabilities. Use `ThemeProvider`. + +--- + +## Typography and spacing + +- Typography uses `rem`; default root sizing is documented on [Typography](https://mui.com/material-ui/customization/typography/). Adjust `typography.fontSize` or per-variant sizes as needed; `responsiveFontSizes(theme)` can scale typography across breakpoints. +- `theme.spacing(k)` follows the configured scale; `sx` spacing shorthands use the same system. Array-based `spacing` in the theme has limitations (negative / fractional / `'auto'`). Prefer a function if you need full expressiveness (see [Spacing](https://mui.com/material-ui/customization/spacing/)). + +--- + +## Composing and merging themes + +- When one token should derive from another, build in steps: call `createTheme` with base options, then `createTheme(theme, { ... })` using the first result (see [Theming—Using theme options to define other options](https://mui.com/material-ui/customization/theming/#theme-composition-using-theme-options-to-define-other-options)). +- Avoid relying on multiple arguments to `createTheme` for merging; only the first argument is formally processed. Deep-merge yourself (e.g. `deepmerge` from `@mui/utils`) and pass a single object for forward compatibility (see [Theming—createTheme(options, ...args)](https://mui.com/material-ui/customization/theming/#createtheme-options-args-theme)). + +--- + +## Nesting `ThemeProvider` + +Inner provider overrides outer. Pass `theme={(outer) => createTheme({ ...outer, ... })}`-style functions only when intentionally extending the parent theme (see [Theming—Nesting the theme](https://mui.com/material-ui/customization/theming/#nesting-the-theme)). + +--- + +## Custom tokens (brand-specific design keys) + +Add keys on the theme (e.g. `status.danger`) inside `createTheme`, then augment TypeScript with `declare module '@mui/material/styles'` on `Theme` and `ThemeOptions` (see [Theming—Custom variables](https://mui.com/material-ui/customization/theming/#custom-variables)). For extra palette fields, follow [Palette customization](https://mui.com/material-ui/customization/palette/) patterns. + +Do not use `theme.vars` as a custom property name; it is private to CSS variables support. + +--- + +## Further reading + +| Topic | Link | +| :----------------------------- | :----------------------------------------------------------------------------------------------------------- | +| Theming overview & API | [Theming](https://mui.com/material-ui/customization/theming/) | +| Dark mode & toggling | [Dark mode](https://mui.com/material-ui/customization/dark-mode/) | +| CSS variables overview | [CSS theme variables](https://mui.com/material-ui/customization/css-theme-variables/overview/) | +| Color tool / brand hues | [Color](https://mui.com/material-ui/customization/color/) | +| TypeScript theme customization | [TypeScript—Customization of `Theme`](https://mui.com/material-ui/guides/typescript/#customization-of-theme) | + +TypeScript snippet templates: [reference.md](reference.md). diff --git a/skills/material-ui-theming/README.md b/skills/material-ui-theming/README.md new file mode 100644 index 00000000000000..8182ecb43fbf21 --- /dev/null +++ b/skills/material-ui-theming/README.md @@ -0,0 +1,16 @@ +# Material UI theming (agent skill) + +Theming and design tokens for Material UI: `createTheme`, `ThemeProvider`, palette, typography, spacing, `colorSchemes`, `cssVariables` / `theme.vars`, and TypeScript customization. + +## Files in this folder + +| File | Purpose | +| :------------ | :--------------------------------------- | +| AGENTS.md | Full agent/LLM document | +| SKILL.md | Cursor skill entry (frontmatter + index) | +| metadata.json | Version, abstract, references | +| reference.md | TypeScript augmentation snippets | + +## Cursor + +Canonical files live under `skills/` at the repository root. `.cursor/skills/` symlinks to `skills/` so Cursor discovers each skill. diff --git a/skills/material-ui-theming/SKILL.md b/skills/material-ui-theming/SKILL.md new file mode 100644 index 00000000000000..39991d5a7b1066 --- /dev/null +++ b/skills/material-ui-theming/SKILL.md @@ -0,0 +1,37 @@ +--- +name: material-ui-theming +description: Guides Material UI theming and design tokens (createTheme, ThemeProvider, palette, colorSchemes, cssVariables, theme.vars, dark mode, TypeScript augmentation). Use when building or extending a theme, toggling light/dark, or aligning tokens across an app. +license: MIT +metadata: + author: mui + version: '1.0.0' +--- + +# Material UI theming and design tokens + +Agent skill for theme creation, design tokens, light/dark, and CSS theme variables. SKILL.md is the entry; AGENTS.md is the full guide. + +## When to apply + +- `createTheme`, `ThemeProvider`, `useTheme`, `CssBaseline` +- `colorSchemes`, `useColorScheme`, storage / SSR behavior +- `cssVariables: true`, `theme.vars`, `applyStyles('dark', …)` +- Custom theme keys and TypeScript module augmentation + +## Sections in AGENTS.md + +| Area | Topics | +| :------------ | :-------------------------------------------------------------- | +| Core setup | Imports, provider placement, `useTheme` | +| Token map | palette, typography, spacing, shape, breakpoints, components, … | +| Palette | `main` / derived colors, `@mui/material/colors`, `mode` | +| Color schemes | vs palette-only, hydration, `ThemeProvider` props | +| CSS variables | `cssVariables`, reserved `vars`, flicker avoidance | +| Composition | Multi-step `createTheme`, `deepmerge`, nesting providers | +| Custom tokens | Augmenting `Theme` / `ThemeOptions` | + +## Full guide + +Read [AGENTS.md](./AGENTS.md) for the complete instructions and links. + +TypeScript snippets: [reference.md](./reference.md). diff --git a/skills/material-ui-theming/metadata.json b/skills/material-ui-theming/metadata.json new file mode 100644 index 00000000000000..760cd78ada208b --- /dev/null +++ b/skills/material-ui-theming/metadata.json @@ -0,0 +1,11 @@ +{ + "version": "1.0.0", + "organization": "Material UI", + "abstract": "Covers Material UI theme objects and design tokens: createTheme, ThemeProvider, palette and colorSchemes, cssVariables and theme.vars, dark mode toggling and SSR, typography/spacing, theme composition, and TypeScript augmentation.", + "references": [ + "https://mui.com/material-ui/customization/theming/", + "https://mui.com/material-ui/customization/palette/", + "https://mui.com/material-ui/customization/dark-mode/", + "https://mui.com/material-ui/customization/css-theme-variables/overview/" + ] +} diff --git a/skills/material-ui-theming/reference.md b/skills/material-ui-theming/reference.md new file mode 100644 index 00000000000000..faf5297d1ed28e --- /dev/null +++ b/skills/material-ui-theming/reference.md @@ -0,0 +1,34 @@ +# Material UI theming: reference snippets + +## Custom theme property (TypeScript) + +After adding a key in `createTheme`, augment both `Theme` and `ThemeOptions`: + +```ts +declare module '@mui/material/styles' { + interface Theme { + status: { danger: string }; + } + interface ThemeOptions { + status?: { danger?: string }; + } +} +``` + +Source pattern: [Theming—Custom variables](https://mui.com/material-ui/customization/theming/#custom-variables). + +## Extra `shape` keys (TypeScript) + +New shape properties require augmenting `Shape` and `ShapeOptions`. See [Shape—TypeScript](https://mui.com/material-ui/customization/shape/#typescript). + +## `theme.vars` typings (CSS variables) + +Typings for `theme.vars` are not enabled by default. Follow [CSS theme variables—TypeScript](https://mui.com/material-ui/customization/css-theme-variables/usage/#typescript). + +## Fallback when rendering outside `ThemeProvider` + +```js +backgroundColor: (theme.vars || theme).palette.primary.main; +``` + +Use when a component might run outside the provider. From [CSS theme variables—Usage](https://mui.com/material-ui/customization/css-theme-variables/usage/).