本文へ移動
cccskills
無料GitHub で公開

web-ui-mui

Material UI component library patterns for React

インストール方法を見る

含まれるファイル(10)

  • SKILL.md13.8 KB
  • examples/core.md9.6 KB
  • examples/data-grid.md3.7 KB
  • examples/feedback.md4.5 KB
  • examples/form-inputs.md6.4 KB
  • examples/layout.md4.7 KB
  • examples/navigation.md5.1 KB
  • examples/styling.md3.8 KB
  • metadata.yaml433 B
  • reference.md14.2 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

MUI (Material UI) Patterns

Quick Guide: MUI is a pre-styled React component library built on a theme. createTheme + ThemeProvider define the tokens every component reads; sx styles one instance, styled() makes a reusable one, theme.components changes every instance, and slots / slotProps reach inner elements. Current: v7.x (March 2025) — CSS layers, slots/slotProps standardised everywhere, Grid v2 promoted to Grid, React 19 compatible. MUI X v8 covers DataGrid, DatePicker and Charts. Emotion is the styling engine; Pigment CSS is still alpha and on hold.

Detailed Resources:

  • examples/core.md — theme with colour schemes, component overrides, dark-mode menu, TypeScript augmentation, SSR and SPA setup with CSS layers
  • examples/styling.md — styled(), custom props via shouldForwardProp, sx theme-aware, responsive and callback forms
  • examples/form-inputs.md — TextField, Select, Autocomplete, slots and slotProps
  • examples/layout.md — Grid, Stack, Box, Container, responsive card grid
  • examples/navigation.md — AppBar, Drawer, Tabs, responsive dashboard shell
  • examples/feedback.md — Dialog, Snackbar, Alert, Skeleton, CircularProgress
  • examples/data-grid.md — DataGrid columns, pagination, cell rendering
  • reference.md — component tables, theme structure, sx shorthands, breakpoints, package list, v6 → v7 migration, anti-pattern code

<critical_requirements>

Before writing MUI code

Wrap the app in ThemeProvider with a createTheme() instance. Without one, components fall back to MUI's default theme and render correctly but wrong — no error, just someone else's design.

Import from the path, not the barrel — @mui/material/Button, not { Button } from "@mui/material". The barrel makes the dev server parse the whole package on first load, and @mui/icons-material alone is over 2000 modules.

Use slots and slotProps to reach inner elements. They are the v7 API across every component; components and componentsProps are deprecated and scheduled for removal.

Write dark-mode branches as theme.applyStyles("dark", { … }). It emits both rulesets and lets CSS pick, so the server and the client agree. theme.palette.mode === "dark" decides at render time, which is what makes the wrong theme flash before hydration.

</critical_requirements>


Auto-detection: MUI, Material UI, @mui/material, @mui/system, @mui/icons-material, @mui/x-data-grid, @mui/x-date-pickers, createTheme, ThemeProvider, CssBaseline, sx prop, styled, useTheme, useColorScheme, colorSchemes, cssVariables, applyStyles, slots, slotProps, shouldForwardProp, GridColDef, StyledEngineProvider, enableCssLayer

Applies to:

  • Building on MUI's component set and customising it through the theme rather than by forking
  • Choosing between sx, styled(), theme.components and slots/slotProps for a given override
  • Colour schemes and dark mode, including the CSS-variables route that survives server rendering
  • Typing custom palette colours and typography variants through module augmentation
  • MUI X — DataGrid, date pickers, charts

Handled elsewhere:

  • CSS methodology and design-token architecture beyond MUI's own theme — enableCssLayer puts MUI's styles in a named layer so an external stylesheet can order itself against them, and how that stylesheet is written is settled elsewhere
  • Unstyled primitives — this library arrives fully styled, and a project that wants to own every pixel wants headless primitives instead
  • Form state and validation — TextField takes error and helperText to render a failure, and inputRef to hand the underlying <input> to a library that registers by ref; what decides those values is not this skill's concern
  • Server state — components take data as props

<philosophy>

The theme is the product. Palette, typography, spacing, shadows, breakpoints, z-index and transitions are all one object, and every component reads from it. An override written at a call site is a decision that will need repeating; the same decision in theme.components is made once.

Customisation is layered, and the layer is the choice. sx for this instance, styled() for a reusable variant, theme.components for every instance, slots/slotProps for elements inside a component you do not own. Reaching for a heavier layer than the situation needs is the usual source of style that cannot be changed later.

MUI components are client components. They use context and effects, so a server-rendered app needs a cache provider above ThemeProvider and a client boundary around the pages that use them.

</philosophy>

<decision_framework>

Which styling layer

Used in one place                  → sx prop
Reused, same shape each time       → styled()
Every instance in the app          → theme.components.MuiX
An element inside the component    → slots / slotProps

Which layout component

One axis, even spacing             → Stack
Twelve-column grid                 → Grid (size prop)
Centred page with a max width      → Container
Anything else that needs sx        → Box

Colour scheme

No dark mode                       → one palette in createTheme
Follow the system only             → cssVariables: true
User can choose                    → colorSchemes + useColorScheme
Both, without a flash              → cssVariables: { colorSchemeSelector: "data" } + useColorScheme

MUI X data display

Under ~100 rows, read-only         → Table
Sorting, filtering, pagination     → DataGrid
Very large datasets                → DataGridPro (row virtualisation)
Date or time entry                 → DatePicker / DateTimePicker
Charts                             → MUI X Charts
Hierarchy                          → TreeView

</decision_framework>


<patterns>

Core patterns

Pattern 1: Theme and provider

const theme = createTheme({
  palette: { primary: { main: "#1976d2" } },
  typography: {
    fontFamily: '"Inter", sans-serif',
    button: { textTransform: "none" },
  },
  shape: { borderRadius: 8 },
  spacing: 8,
});

<ThemeProvider theme={theme}>
  <CssBaseline />
  {children}
</ThemeProvider>;

CssBaseline applies MUI's normalisation and the theme's background and text colours to <body> — without it the page around the components keeps the browser defaults.

Full code: examples/core.md


Pattern 2: CSS variables and dark mode

const theme = createTheme({
  cssVariables: { colorSchemeSelector: "data" },
  colorSchemes: {
    light: { palette: { primary: { main: "#1976d2" } } },
    dark: { palette: { primary: { main: "#90caf9" } } },
  },
});

const { mode, setMode } = useColorScheme(); // "light" | "dark" | "system"

With cssVariables, both palettes are emitted as custom properties and a data-* attribute selects between them, so the scheme is settled before React runs. mode is undefined on the first render — guard on it before rendering anything that depends on the scheme.

Full code: examples/core.md


Pattern 3: The sx prop

<Box
  sx={{
    p: 3, // theme.spacing(3)
    bgcolor: "background.paper", // theme.palette.background.paper
    borderRadius: 1, // theme.shape.borderRadius
    boxShadow: 3, // theme.shadows[3]
    width: { xs: "100%", md: "50%" },
    "&:hover": { boxShadow: 6 },
  }}
/>

Numbers go through the theme's scales and dotted strings resolve against the palette, so a themed value never needs to be repeated as a literal. Breakpoint objects replace media queries, and an array of sx objects merges left to right — which is how a conditional style is added without rebuilding the object.

Full code: examples/styling.md


Pattern 4: styled()

const StyledCard = styled(Card)(({ theme }) => ({
  padding: theme.spacing(3),
  "&:hover": { boxShadow: theme.shadows[8] },
  ...theme.applyStyles("dark", { backgroundColor: theme.palette.grey[900] }),
}));

Reach for this when the same styling appears more than once. A second argument takes shouldForwardProp, which is what stops a styling-only prop reaching the DOM as an unknown attribute.

Full code: examples/styling.md


Pattern 5: Slots and slotProps

<Autocomplete
  slots={{ paper: CustomPaper }}
  slotProps={{
    paper: { elevation: 8, sx: { borderRadius: 2 } },
    listbox: { sx: { maxHeight: 300 } },
    input: ({ open }) => ({
      sx: { borderColor: open ? "primary.main" : "divider" },
    }),
  }}
  renderInput={(params) => <TextField {...params} label="Framework" />}
/>

slots replaces an inner component, slotProps configures one, and a slotProp written as a callback receives that slot's own state. Define slot components outside the render — an inline arrow is a new component type each time, which remounts the slot on every render.

Full code: examples/form-inputs.md


Pattern 6: Layout

<Grid container spacing={3}>
  <Grid size={{ xs: 12, md: 4 }}><Sidebar /></Grid>
  <Grid size={{ xs: 12, md: 8 }}><MainContent /></Grid>
</Grid>

<Stack direction={{ xs: "column", sm: "row" }} spacing={2}>
  <Button variant="contained">Save</Button>
</Stack>

<Container maxWidth="lg" sx={{ py: 4 }}>{children}</Container>

In v7 Grid is the former Grid2 and takes one size prop instead of separate xs/sm/md props; the previous component is still available as GridLegacy.

Full code: examples/layout.md


Pattern 7: TypeScript augmentation

declare module "@mui/material/styles" {
  interface Palette {
    neutral: Palette["primary"];
  }
  interface PaletteOptions {
    neutral?: PaletteOptions["primary"];
  }
}
declare module "@mui/material/Button" {
  interface ButtonPropsColorOverrides {
    neutral: true;
  }
}

Two augmentations, and both are needed: the first makes the token exist on the theme, the second lets a component accept it as a prop value. Skip the second and color="neutral" is a type error at every call site even though the theme carries it.

Full code: examples/core.md


Pattern 8: Server-rendered setup

<AppRouterCacheProvider options={{ enableCssLayer: true }}>
  <GlobalStyles styles="@layer theme, base, mui, components, utilities;" />
  <ThemeProvider theme={theme}>
    <CssBaseline />
    {children}
  </ThemeProvider>
</AppRouterCacheProvider>

Emotion generates styles as components render, so a server-rendered app needs a cache provider above ThemeProvider to collect and flush them with the streamed HTML — without it the markup arrives unstyled and restyles on hydration. MUI publishes an adapter package per supported server framework; a client-only app uses StyledEngineProvider in the same position instead. enableCssLayer puts MUI's output into a named layer, and the @layer declaration is what fixes the order of that layer against everything else on the page.

Full code, both arrangements: examples/core.md

</patterns>
<performance>

Performance

Path imports. import Button from "@mui/material/Button" skips barrel parsing; the barrel form costs several times the dev-server startup. Some bundlers and frameworks rewrite barrel imports automatically — check before assuming the cost applies. A lint rule restricting the pattern ^@mui/[^/]+$ is what keeps it from creeping back.

Stable references for anything a component treats as identity. DataGrid columns, slot components, and Dialog TransitionProps are all compared by reference: define them at module scope, or memoise them. Inline, they cause a re-render or a remount on every parent render.

createTheme does not affect bundle size — it is data, not components. The bundle is decided by which components are imported.

</performance>

<red_flags>

Red flags

Breaks at runtime:

  • theme.palette.mode === "dark" in a style function — resolved at render time, so the server and the first client paint disagree and the wrong theme flashes
  • An inline arrow in slots — a new component type each render, so the slot remounts and loses its state and focus
  • Inline columns on a DataGrid — a new array each render, re-rendering the whole grid
  • Importing more than one level deep, @mui/material/styles/createTheme — the v7 ESM package layout does not expose those paths
  • @mui/lab imports for Alert, Skeleton or Autocomplete — they graduated to @mui/material in v7
  • MUI components rendered on the server without a client boundary — they need context and effects, and the boundary belongs on the page, not only on the root layout

Surprising behaviour:

  • spacing is a multiplier, not pixels: spacing(2) is 16px at the default base of 8
  • sx arrays merge left to right, so a later entry wins — which is what makes conditional styles work
  • TextField is three components in a trench coat (input, label, helper text), so targeting the actual <input> means slotProps.input
  • Setting zIndex by hand fights MUI's own scale, where modal, drawer, snackbar and tooltip already have assigned values
  • useMediaQuery returns false during server rendering, so a desktop-first branch renders the wrong thing before hydration
  • useColorScheme().mode is undefined on the first render, and rendering a scheme-dependent icon from it produces a hydration mismatch
  • A missing TypeScript augmentation for a custom palette colour is a type error at the usage site, not at the theme
  • components and componentsProps still work in v7 but are deprecated

</red_flags>

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Hugging Face Inference SDK patterns for TypeScript/Node.js — InferenceClient setup, chat completion, text generation, streaming, embeddings, image generation, audio transcription, translation, summarization, and Inference Endpoints

日本語の概要は準備中です。原文の説明を表示しています。

agents-inc/skills242026年9月8日 更新

LiteLLM proxy server setup, TypeScript client patterns via OpenAI SDK, model routing, fallbacks, load balancing, spend tracking, virtual keys, and production deployment

日本語の概要は準備中です。原文の説明を表示しています。

agents-inc/skills242026年9月8日 更新

Serverless GPU compute platform for AI model deployment — web endpoints, GPU functions, model serving, and TypeScript client patterns

日本語の概要は準備中です。原文の説明を表示しています。

agents-inc/skills242026年9月8日 更新

Local LLM inference with the Ollama JavaScript client -- chat, streaming, tool calling, vision, embeddings, structured output, model management, and OpenAI-compatible endpoint

日本語の概要は準備中です。原文の説明を表示しています。

agents-inc/skills242026年9月8日 更新

Replicate SDK patterns for TypeScript/Node.js -- client setup, predictions, streaming, webhooks, file handling, model versioning, deployments, and training

日本語の概要は準備中です。原文の説明を表示しています。

agents-inc/skills242026年9月8日 更新

Together AI SDK patterns for TypeScript — client setup, chat completions, streaming, structured output, function calling, embeddings, image generation, fine-tuning, and OpenAI-compatible endpoints

日本語の概要は準備中です。原文の説明を表示しています。

agents-inc/skills242026年9月8日 更新

agents-inc のスキルをすべて見る

このスキルの問題を報告する