agentsclimarketplace

Mui theme

Skill LaoitdevOpen/laoitdev-skills/skills/frontend/mui-theme

MUI theme configuration, color palette, typography, dark/light mode, and shared UI building blocks. Use this when working with colors, spacing, typography, component styling, adding theme overrides, or using SectionCard/InfoRow shared components for consistent UI. Also covers how ThemeContext and LocalizationProvider are wired up.From its SKILL.md

Install
npx -y skills add LaoitdevOpen/laoitdev-skills --skill mui-theme

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

6.3 KB, ~1.7k tokens by cl100k_base, as published. Nobody here has run it

Theme & UI Building Blocks

Color Palette

The theme uses a government-style palette. Reference these via MUI's sx prop or theme.palette:

TokenValueUse
primary.main#027BC5Azure Blue — primary actions, headers
primary.dark#015A94Hover/active state
secondary.main#CE1126Red — destructive, secondary accent
success.main#059669Success state
warning.main#D97706Warning state
error.main#DC2626Error state
info.main#027BC5Same as primary

Light mode backgrounds:

  • background.default: #F8FAFC (page background)
  • background.paper: #FFFFFF (card/surface)
  • divider: #E2E8F0
  • text.primary: #1E293B
  • text.secondary: #64748B

Dark mode backgrounds:

  • background.default: #0F172A
  • background.paper: #1E293B
  • divider: #334155

Typography Scale

VariantSizeWeightUse
h132px700Page titles (rare)
h420px600Form headings
h616px600Card/section headings
body115px400Main body text
body214px400Secondary text
caption13px500Labels in InfoRow
overline12px600Uppercase section labels
button15px500Button text (no uppercase)

Font stack: 'Noto Sans Lao', 'Noto Sans', 'Phetsarath OT', 'Saysettha OT', sans-serif

Component Defaults

  • MuiButton: borderRadius: 8px, disableElevation: true, no uppercase transform
  • MuiTextField: size: 'small', borderRadius: 6px
  • MuiCard: borderRadius: 8px, subtle shadow
  • MuiChip: borderRadius: 4px
  • spacing: 8px baseline (theme.spacing(1) === '8px')

Dark/Light Mode Toggle

import { useTheme } from '@/core/context/ThemeContext'

function MyComponent() {
  const { mode, toggleTheme } = useTheme()

  return (
    <IconButton onClick={toggleTheme}>
      {mode === 'dark' ? <LightModeIcon /> : <DarkModeIcon />}
    </IconButton>
  )
}

Mode persists in localStorage under key 'admin-theme-mode'.

Provider Setup

Wrap the app (in main.tsx) in this order:

<QueryClientProvider client={queryClient}>
  <ThemeProvider>          {/* MUI theme + CssBaseline + LocalizationProvider */}
    <AuthProvider>
      <SnackbarProvider>
        <ConfirmDialogProvider>
          <RouterProvider router={router} />
        </ConfirmDialogProvider>
      </SnackbarProvider>
    </AuthProvider>
  </ThemeProvider>
</QueryClientProvider>

ThemeProvider wraps MUI's ThemeProvider, CssBaseline, and MUI's LocalizationProvider (with Day.js adapter) — so date pickers work without additional setup.

SectionCard

A card with an icon avatar, title, and a divider — used in detail pages to group related fields.

import { SectionCard } from '@/shared/components'

<SectionCard
  icon={<InfoIcon />}             // MUI icon
  title="Basic Information"
  iconColor="primary.main"        // optional, defaults to 'primary.main'
>
  {/* InfoRow children or raw children */}
  <InfoRow label="Name" value={item.name} />
</SectionCard>

// With raw children (not wrapped in List):
<SectionCard icon={<AttachFileIcon />} title="Attachments" rawChildren>
  <Button href={item.fileUrl}>Download</Button>
</SectionCard>

Hover effect: border color changes to primary.main, box shadow lifts.

InfoRow

A label + value pair used inside SectionCard. Displays a subtle uppercase label above the value.

import { InfoRow } from '@/shared/components'

<InfoRow label="Serial Number" value={item.serialNumber} />
<InfoRow label="Status" value={null} />        // shows '-' for null/undefined
<InfoRow label="Actions" value={<Button>Edit</Button>} />  // accepts ReactNode

Labels render as caption variant, uppercase, text.secondary. Values render as body1, text.primary.

Page Layout Patterns

Page Header

<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 3 }}>
  <Box>
    <Box component="h1" sx={{ fontSize: { xs: '1.5rem', md: '2rem' }, fontWeight: 600, mb: 0.5 }}>
      {pageTitle}
    </Box>
    <Box component="p" sx={{ fontSize: '0.875rem', color: 'text.secondary' }}>
      {description}
    </Box>
  </Box>
  <Button variant="contained" startIcon={<AddIcon />}>Create</Button>
</Box>

Detail Page Hero (full-width colored header)

<Paper
  elevation={0}
  sx={{
    bgcolor: 'primary.main',
    color: 'white',
    py: { xs: 2.5, md: 3.5 },
    px: { xs: 3, md: 4 },
    mx: { xs: -2, md: -4 },  // bleed beyond container padding
    borderRadius: 0,
    position: 'relative',
    overflow: 'hidden',
    // decorative circles
    '&::before': {
      content: '""', position: 'absolute', top: 0, right: 0,
      width: { xs: '120px', md: '250px' }, height: { xs: '120px', md: '250px' },
      bgcolor: 'rgba(255, 255, 255, 0.05)', borderRadius: '50%',
      transform: 'translate(35%, -35%)',
    },
  }}
>
  ...
</Paper>

MUI Grid

Grid items must use the size prop — never legacy xs/md props or the item prop. See react-standard for the full rule.

Card Grid for Detail Sections

<Container maxWidth="xl" sx={{ mt: 4, mb: 4 }}>
  <Grid container spacing={3}>
    <Grid size={{ xs: 12, md: 6 }}>
      <SectionCard icon={<InfoIcon />} title="Section Title">
        <InfoRow label="Field" value={value} />
      </SectionCard>
    </Grid>
  </Grid>
</Container>

sx Prop Tips

// Responsive values
sx={{ fontSize: { xs: '1rem', md: '1.25rem' } }}

// Theme-aware colors
sx={{ bgcolor: 'primary.main', color: 'white' }}
sx={{ borderColor: 'divider' }}

// Callback form for theme access
sx={{ bgcolor: (theme) => theme.palette.action.hover }}

// Combined
sx={{
  borderRadius: 3,
  border: '1px solid',
  borderColor: 'divider',
  '&:hover': { borderColor: 'primary.main' },
}}

Theme Config Location

src/core/config/theme.config.ts — edit this file to change global colors, typography, or component defaults.

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Gives 0 of the 12 instructions most design systems skills give in ~1.7k tokens

Counted across 501 of the 520 authors here whose files we hold, read 2026-09-06

  • Extract colors, typography, spacing, radii, shadows, breakpointsin 20 of 501, across 10 files
  • Create a self-contained dependency-free HTML preview pagein 20 of 501, across 10 files
  • Keep touch targets at least 44x44pxin 20 of 501
  • Score the UI across ten dimensionsin 18 of 501, across 8 files
  • Animate exclusively via transform and opacityin 18 of 501, across 15 files
  • Ensure WCAG AA color contrastin 18 of 501, across 13 files
  • Generate DESIGN.md with rationale for each decisionin 17 of 501, across 7 files
  • Ensure proper contrast and readabilityin 15 of 501, across 10 files
  • Scan the codebase for existing style patternsin 15 of 501, across 6 files
  • Give every interactive element a visible focus indicatorin 15 of 501, across 13 files
  • Propose a design token setin 14 of 501, across 5 files
  • Create a custom theme when none fitin 14 of 501, across 9 files

Said here and by no other author read

  • Reference palette tokens via sx prop or theme.palette
  • Use the size prop on Grid items
  • Wrap providers in the documented order
  • Edit the theme config file to change global styling
  • Use SectionCard to group fields on detail pages
  • Use InfoRow for label-value pairs

Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.