@webpros/eslint-plugin-mui-theme
v0.1.0
Published
ESLint rules for WebPros MUI theme to enforce Material Design 3 best practices
Readme
Custom ESLint Rules
This folder contains custom ESLint rules specific to the WebPros MUI theme project.
Rules
no-palette-usage
Type: Problem
Severity: Error
Category: Best Practices
Description
Prevents direct usage of palette from the MUI Theme object. This rule enforces the use of design tokens from colors.schemes.* instead to maintain consistency with Material Design 3 specifications.
no-standard-typography-variants
Type: Problem
Severity: Error
Category: Best Practices
Description
Prevents usage of standard MUI Typography variants (h1-h6, body1, body2, etc.) and enforces the use of Material Design 3 custom typography variants. The allowed variants are automatically extracted from Figma design tokens.
Rationale
The WebPros MUI theme implements a custom typography system based on Material Design 3 specifications. Using standard MUI variants bypasses this system and can lead to inconsistent typography across the application.
Rationale
The WebPros MUI theme follows Material Design 3 token-based design system. Direct usage of palette bypasses the centralized design token system and can lead to inconsistencies. All color references should use the token system: colors.schemes.*, colors.stateLayers.*, etc.
Patterns Detected
The rule catches two common patterns:
Direct property access:
// ❌ BAD const color = theme.palette.primary.main; const bgColor = theme.palette.background.default;Destructuring from theme:
// ❌ BAD const { palette, spacing } = theme; const { palette } = theme;
Patterns Detected (no-standard-typography-variants)
The rule catches usage of standard MUI Typography variants:
// ❌ BAD - Standard MUI variants
<Typography variant="h1">Heading</Typography>
<Typography variant="h6">Subheading</Typography>
<Typography variant="body1">Body text</Typography>
<Typography variant="body2">Secondary text</Typography>
<Typography variant="subtitle1">Subtitle</Typography>
<Typography variant="caption">Caption</Typography>Correct Usage (no-standard-typography-variants)
Instead, use Material Design 3 custom variants:
// ✅ GOOD - M3 custom variants
<Typography variant="DisplayLarge">Display text</Typography>
<Typography variant="HeadlineMedium">Headline</Typography>
<Typography variant="TitleLarge">Title</Typography>
<Typography variant="BodyMedium">Body text</Typography>
<Typography variant="LabelSmall">Label</Typography>Allowed Variants
The allowed variants are automatically generated from src/tokens/typography/typescale.ts:
- Body:
BodySmall,BodyMedium,BodyLarge(+ Prominent versions) - Label:
LabelSmall,LabelMedium,LabelLarge(+ Prominent versions) - Title:
TitleSmall,TitleMedium,TitleLarge - Headline:
HeadlineSmall,HeadlineMedium,HeadlineLarge - Display:
DisplaySmall,DisplayMedium,DisplayLarge,DisplayXLarge
The list of allowed variants is maintained in eslint/rules/allowed-typography-variants.js and is auto-generated when running node tools/extractM3Typography.js.
Error Messages (no-standard-typography-variants)
noStandardVariant: "Do not use standard MUI Typography variant "{{variant}}". Use M3 custom variants like LabelMedium, BodyLarge, TitleSmall, etc."
Correct Usage
Instead, use design tokens:
// ✅ GOOD
const { colors, spacing } = theme;
const color = colors.schemes.base.primary;
const bgColor = colors.schemes.surfaces.background;Error Messages
noPaletteAccess: "Do not use theme.palette.{{property}}. Use colors.schemes.* tokens instead."noPaletteDestructuring: "Do not destructure palette from theme. Use colors.schemes.* tokens instead."
no-hardcoded-typography-in-sx
Type: Problem
Severity: Error
Category: Best Practices
Description
Prevents hardcoded typography properties (fontSize, lineHeight, fontWeight, letterSpacing, fontFamily) in the sx prop on Typography components. This rule enforces the use of theme typography variants to maintain consistency with Material Design 3 specifications.
Note: This rule only checks the sx prop on Typography components. Hardcoded typography values in sx props on other components (Box, Stack, etc.) are allowed, as they may need custom typography for specific use cases.
Rationale
Typography components should always use theme.typography variants (e.g., ...theme.typography.LabelMedium) instead of hardcoded values. This ensures Typography-specific components remain consistent with the design system, while still allowing flexibility for custom layouts in other components.
Patterns Detected
The rule catches hardcoded typography in various sx prop patterns on Typography components:
// ❌ BAD - Hardcoded typography properties on Typography
<Typography sx={{ fontSize: '14px', lineHeight: '20px' }}>Text</Typography>
<Typography sx={{ fontWeight: 500, letterSpacing: '0.5px' }}>Text</Typography>
<Typography sx={(theme) => ({ fontSize: '16px', lineHeight: '24px' })}>Text</Typography>
<Typography sx={[{ fontWeight: 600 }, otherStyles]}>Text</Typography>Correct Usage
Instead, use theme typography variants or the variant prop:
// ✅ GOOD - Use variant prop (preferred)
<Typography variant="LabelMedium">Text</Typography>
// ✅ GOOD - Use theme typography in sx if needed
<Typography sx={(theme) => ({
...theme.typography.LabelMedium,
color: theme.colors.schemes.base.primary
})}>Text</Typography>
// ✅ ALLOWED - Hardcoded typography on non-Typography components
<Box sx={{ fontSize: '14px', lineHeight: '20px' }}>
Custom layout text
</Box>Error Messages
noHardcodedTypography: "Do not hardcode "{{property}}" in sx prop on Typography component. Use theme.typography variants (e.g., ...theme.typography.LabelMedium) instead."
Rule Development Resources
- ESLint Custom Rules Documentation
- AST Explorer - Useful for understanding AST structure
- ESLint Rule Tester
For information on adding new custom rules, see the main README.
