CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-tss-react

Type safe CSS-in-JS API heavily inspired by react-jss

Pending
Overview
Eval results
Files

mui-integration.mddocs/

MUI Integration

TSS-React provides specialized integration for Material-UI applications with built-in theme support, style overrides compatibility, and seamless migration from @material-ui/core v4. The integration includes pre-configured instances and plugins for MUI theme systems.

Capabilities

Pre-configured MUI Instances

Ready-to-use TSS, makeStyles, and withStyles instances with MUI theme integration.

/**
 * Pre-configured TSS instance with MUI theme context and plugin support
 */
const tss: Tss<{ theme: Theme }, {}, never, MuiThemeStyleOverridesPluginParams, never>;

/**
 * Pre-configured makeStyles function with MUI theme
 */
const makeStyles: <Params = void, RuleNameSubsetReferencableInNestedSelectors extends string = never>(
  params?: { name?: string | Record<string, unknown>; uniqId?: string }
) => MakeStylesHook<Theme, Params, RuleNameSubsetReferencableInNestedSelectors>;

/**
 * Pre-configured withStyles HOC with MUI theme
 */
const withStyles: <Component, Props, CssObjectByRuleName>(
  Component: Component,
  cssObjectByRuleNameOrGetCssObjectByRuleName: 
    | CssObjectByRuleName 
    | ((theme: Theme, props: Props, classes: Record<string, string>) => CssObjectByRuleName)
) => ComponentType<Props>;

/**
 * Pre-configured useStyles hook with MUI theme context
 */
const useStyles: UseStyles<{ theme: Theme }, {}, string, MuiThemeStyleOverridesPluginParams>;

interface Theme {
  palette: any;
  typography: any;
  spacing: (...args: any[]) => any;
  breakpoints: any;
  shadows: any;
  shape: any;
  transitions: any;
  zIndex: any;
  [key: string]: any;
}

Usage Examples:

import { tss, makeStyles, withStyles, useStyles } from "tss-react/mui";

// Using pre-configured TSS instance
const useComponentStyles = tss.create(({ theme }) => ({
  root: {
    backgroundColor: theme.palette.background.paper,
    padding: theme.spacing(2),
    borderRadius: theme.shape.borderRadius
  },
  title: {
    color: theme.palette.primary.main,
    fontSize: theme.typography.h5.fontSize,
    fontWeight: theme.typography.fontWeightBold
  }
}));

// Using pre-configured makeStyles
const useMakeStyles = makeStyles()(theme => ({
  container: {
    maxWidth: theme.breakpoints.values.md,
    margin: "0 auto",
    padding: theme.spacing(0, 2)
  }
}));

// Using pre-configured withStyles
const StyledButton = withStyles(
  ({ children, classes }: { children: React.ReactNode; classes?: { root?: string } }) => (
    <button className={classes?.root}>{children}</button>
  ),
  theme => ({
    root: {
      backgroundColor: theme.palette.primary.main,
      color: theme.palette.primary.contrastText,
      padding: theme.spacing(1, 2),
      border: "none",
      borderRadius: theme.shape.borderRadius,
      "&:hover": {
        backgroundColor: theme.palette.primary.dark
      }
    }
  })
);

function MyMuiComponent() {
  const { classes } = useComponentStyles();
  const { classes: layoutClasses } = useMakeStyles();
  
  return (
    <div className={layoutClasses.container}>
      <div className={classes.root}>
        <h1 className={classes.title}>MUI Integration Example</h1>
        <StyledButton>Click me</StyledButton>
      </div>
    </div>
  );
}

MUI Theme Style Overrides Plugin

Plugin system for integrating with MUI's theme style overrides mechanism, enabling component customization through theme configuration.

/**
 * Plugin for MUI theme style overrides integration
 * @param params - Plugin parameters including classes, theme, and MUI-specific options
 * @returns Processed classes with theme overrides applied
 */
const useMuiThemeStyleOverridesPlugin: UsePlugin<
  { theme: MuiThemeLike },
  MuiThemeStyleOverridesPluginParams
> = (params: {
  classes: Record<string, string>;
  theme: MuiThemeLike;
  muiStyleOverridesParams?: MuiThemeStyleOverridesPluginParams;
  css: Css;
  cx: Cx;
  name?: string;
}) => Record<string, string>;

interface MuiThemeStyleOverridesPluginParams {
  muiStyleOverridesParams?: {
    props: Record<string, unknown>;
    ownerState?: Record<string, unknown>;
  };
}

interface MuiThemeLike {
  components?: Record<string, {
    styleOverrides?: Record<string, any>;
  }>;
}

Usage Examples:

import { createTss } from "tss-react";
import { useTheme } from "@mui/material/styles";
import { useMuiThemeStyleOverridesPlugin } from "tss-react/mui";

// Manual setup with plugin
const { tss } = createTss({
  useContext: () => {
    const theme = useTheme();
    return { theme };
  },
  usePlugin: useMuiThemeStyleOverridesPlugin
});

// Component with theme overrides support
const useCardStyles = tss
  .withName("MyCard")
  .withParams<{ variant: "outlined" | "elevated" }>()
  .create(({ theme }, { variant }) => ({
    root: {
      backgroundColor: theme.palette.background.paper,
      borderRadius: theme.shape.borderRadius,
      padding: theme.spacing(2),
      ...(variant === "outlined" && {
        border: `1px solid ${theme.palette.divider}`
      }),
      ...(variant === "elevated" && {
        boxShadow: theme.shadows[4]
      })
    },
    header: {
      borderBottom: `1px solid ${theme.palette.divider}`,
      paddingBottom: theme.spacing(1),
      marginBottom: theme.spacing(2)
    },
    content: {
      color: theme.palette.text.secondary
    }
  }));

// Theme configuration with style overrides
const theme = createTheme({
  components: {
    MyCard: {
      styleOverrides: {
        root: {
          // These styles will be merged with component styles
          transition: "all 0.3s ease",
          "&:hover": {
            transform: "translateY(-2px)"
          }
        },
        header: {
          fontWeight: 600,
          textTransform: "uppercase"
        }
      }
    }
  }
});

function MyCard({ 
  variant, 
  title, 
  children 
}: { 
  variant: "outlined" | "elevated";
  title: string;
  children: React.ReactNode;
}) {
  const { classes } = useCardStyles({ variant });
  
  return (
    <div className={classes.root}>
      <div className={classes.header}>{title}</div>
      <div className={classes.content}>{children}</div>
    </div>
  );
}

MUI Theme Integration Patterns

Responsive Design with Breakpoints

import { tss } from "tss-react/mui";

const useResponsiveStyles = tss.create(({ theme }) => ({
  container: {
    padding: theme.spacing(1),
    [theme.breakpoints.up("sm")]: {
      padding: theme.spacing(2)
    },
    [theme.breakpoints.up("md")]: {
      padding: theme.spacing(3),
      maxWidth: theme.breakpoints.values.lg,
      margin: "0 auto"
    }
  },
  grid: {
    display: "grid",
    gap: theme.spacing(1),
    gridTemplateColumns: "1fr",
    [theme.breakpoints.up("sm")]: {
      gridTemplateColumns: "repeat(2, 1fr)",
      gap: theme.spacing(2)
    },
    [theme.breakpoints.up("lg")]: {
      gridTemplateColumns: "repeat(3, 1fr)",
      gap: theme.spacing(3)
    }
  }
}));

Theme Palette and Typography Integration

import { tss } from "tss-react/mui";

const useThemedStyles = tss
  .withParams<{ 
    severity: "info" | "warning" | "error" | "success";
    size: "small" | "medium" | "large";
  }>()
  .create(({ theme }, { severity, size }) => {
    const palette = theme.palette[severity];
    const typography = {
      small: theme.typography.body2,
      medium: theme.typography.body1,
      large: theme.typography.h6
    }[size];
    
    return {
      alert: {
        backgroundColor: palette.light,
        color: palette.contrastText,
        border: `1px solid ${palette.main}`,
        borderRadius: theme.shape.borderRadius,
        padding: theme.spacing(1, 2),
        fontSize: typography.fontSize,
        fontWeight: typography.fontWeight,
        lineHeight: typography.lineHeight
      },
      icon: {
        marginRight: theme.spacing(1),
        color: palette.main
      }
    };
  });

Animation and Transitions

import { tss } from "tss-react/mui";

const useAnimatedStyles = tss
  .withParams<{ expanded: boolean; loading: boolean }>()
  .create(({ theme }, { expanded, loading }) => ({
    expandableCard: {
      backgroundColor: theme.palette.background.paper,
      borderRadius: theme.shape.borderRadius,
      overflow: "hidden",
      transition: theme.transitions.create(
        ["height", "box-shadow"],
        {
          duration: theme.transitions.duration.standard,
          easing: theme.transitions.easing.easeInOut
        }
      ),
      height: expanded ? "auto" : 60,
      boxShadow: expanded ? theme.shadows[8] : theme.shadows[2]
    },
    loadingSpinner: {
      animation: loading ? `$spin 1s linear infinite` : "none",
      color: theme.palette.primary.main
    },
    "@keyframes spin": {
      "0%": { transform: "rotate(0deg)" },
      "100%": { transform: "rotate(360deg)" }
    }
  }));

Migration from Material-UI v4

Complete Migration Example

// Before (Material-UI v4)
import { makeStyles, withStyles } from "@material-ui/core/styles";

const useStyles = makeStyles(theme => ({
  root: {
    backgroundColor: theme.palette.background.paper,
    padding: theme.spacing(2)
  }
}));

const StyledComponent = withStyles(theme => ({
  root: {
    color: theme.palette.primary.main
  }
}))(({ classes }) => <div className={classes.root}>Content</div>);

// After (TSS-React MUI)
import { makeStyles, withStyles } from "tss-react/mui";

const useStyles = makeStyles()(theme => ({
  root: {
    backgroundColor: theme.palette.background.paper,
    padding: theme.spacing(2)
  }
}));

const StyledComponent = withStyles(
  ({ classes }: { classes?: { root?: string } }) => (
    <div className={classes?.root}>Content</div>
  ),
  theme => ({
    root: {
      color: theme.palette.primary.main
    }
  })
);

Theme Provider Setup

import { ThemeProvider, createTheme } from "@mui/material/styles";
import CssBaseline from "@mui/material/CssBaseline";

const theme = createTheme({
  palette: {
    mode: "light",
    primary: {
      main: "#1976d2"
    },
    secondary: {
      main: "#dc004e"
    }
  },
  components: {
    // Style overrides work automatically with TSS-React
    MuiButton: {
      styleOverrides: {
        root: {
          textTransform: "none"
        }
      }
    }
  }
});

function App() {
  return (
    <ThemeProvider theme={theme}>
      <CssBaseline />
      <MyStyledComponents />
    </ThemeProvider>
  );
}

Advanced MUI Integration

Custom Theme Extensions

declare module "@mui/material/styles" {
  interface Theme {
    custom: {
      gradients: {
        primary: string;
        secondary: string;
      };
    };
  }
  
  interface ThemeOptions {
    custom?: {
      gradients?: {
        primary?: string;
        secondary?: string;
      };
    };
  }
}

const theme = createTheme({
  custom: {
    gradients: {
      primary: "linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)",
      secondary: "linear-gradient(45deg, #2196F3 30%, #21CBF3 90%)"
    }
  }
});

const useCustomThemeStyles = tss.create(({ theme }) => ({
  gradientButton: {
    background: theme.custom.gradients.primary,
    color: "white",
    border: "none",
    borderRadius: theme.shape.borderRadius,
    padding: theme.spacing(1, 3),
    cursor: "pointer",
    transition: theme.transitions.create("transform"),
    "&:hover": {
      transform: "scale(1.05)"
    }
  }
}));

Integration with MUI Components

import { Button, Card, CardContent, Typography } from "@mui/material";
import { tss } from "tss-react/mui";

const useIntegratedStyles = tss.create(({ theme }) => ({
  styledCard: {
    // Enhancing MUI Card component
    background: `linear-gradient(135deg, ${theme.palette.primary.light} 0%, ${theme.palette.primary.main} 100%)`,
    color: theme.palette.primary.contrastText,
    "& .MuiCardContent-root": {
      padding: theme.spacing(3)
    }
  },
  customButton: {
    // Custom styling that complements MUI Button
    marginTop: theme.spacing(2),
    borderRadius: theme.spacing(3),
    textTransform: "none",
    fontWeight: theme.typography.fontWeightBold
  }
}));

function IntegratedComponent() {
  const { classes } = useIntegratedStyles();
  
  return (
    <Card className={classes.styledCard}>
      <CardContent>
        <Typography variant="h5" component="h2">
          Custom Styled Card
        </Typography>
        <Typography variant="body2">
          This card combines MUI components with TSS-React custom styling.
        </Typography>
        <Button 
          variant="contained" 
          color="secondary"
          className={classes.customButton}
        >
          Learn More
        </Button>
      </CardContent>
    </Card>
  );
}

Install with Tessl CLI

npx tessl i tessl/npm-tss-react

docs

compatibility.md

core-tss-api.md

css-utilities.md

dsfr-integration.md

global-styles-keyframes.md

index.md

makestyles-api.md

mui-integration.md

nextjs-ssr.md

withstyles-hoc.md

tile.json