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

makestyles-api.mddocs/

MakeStyles API

The MakeStyles API provides a React hook-based styling solution compatible with Material-UI v4 patterns. It offers theme integration, dynamic style generation, and seamless migration from @material-ui/core makeStyles.

Capabilities

MakeStyles Factory Function

Creates a makeStyles function with theme support and optional custom cache configuration.

/**
 * Creates a makeStyles function with theme support
 * @param params - Configuration object with theme provider and optional cache
 * @returns Object containing makeStyles function and TssCacheProvider component
 */
function createMakeStyles<Theme>(params: {
  useTheme: () => Theme;
  cache?: EmotionCache;
}): {
  makeStyles<Params = void, RuleNameSubsetReferencableInNestedSelectors extends string = never>(
    params?: { name?: string | Record<string, unknown>; uniqId?: string }
  ): MakeStylesFunction<Theme, Params, RuleNameSubsetReferencableInNestedSelectors>;
  TssCacheProvider: React.ComponentType<{ children: ReactNode }>;
};

type MakeStylesFunction<Theme, Params, RuleNameSubsetReferencableInNestedSelectors> = (
  cssObjectByRuleNameOrGetCssObjectByRuleName:
    | Record<string, CSSObject>
    | ((theme: Theme, params: Params, classes: Record<RuleNameSubsetReferencableInNestedSelectors, string>) => Record<string, CSSObject>)
) => (params: Params) => {
  classes: Record<string, string>;
  cx: Cx;
  css: Css;
  theme: Theme;
};

Usage Examples:

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

// Create makeStyles with MUI theme
const { makeStyles, TssCacheProvider } = createMakeStyles({
  useTheme
});

// Custom cache configuration
import createCache from "@emotion/cache";

const customCache = createCache({
  key: "my-styles",
  prepend: true
});

const { makeStyles: makeStylesWithCache } = createMakeStyles({
  useTheme,
  cache: customCache
});

MakeStyles Hook Creation

Creates a React hook that generates styles based on theme and optional parameters.

/**
 * Creates a styles hook with optional parameters and nested selectors
 * @param params - Optional configuration for component name and unique ID
 * @returns Function that accepts CSS object or function and returns styles hook
 */
function makeStyles<
  Params = void,
  RuleNameSubsetReferencableInNestedSelectors extends string = never
>(params?: {
  name?: string | Record<string, unknown>;
  uniqId?: string;
}): (
  cssObjectByRuleNameOrGetCssObjectByRuleName:
    | Record<string, CSSObject>
    | ((
        theme: Theme,
        params: Params,
        classes: Record<RuleNameSubsetReferencableInNestedSelectors, string>
      ) => Record<string, CSSObject>)
) => UseStylesHook<Theme, Params>;

type UseStylesHook<Theme, Params> = Params extends void
  ? () => {
      classes: Record<string, string>;
      cx: Cx;
      css: Css;
      theme: Theme;
    }
  : (params: Params) => {
      classes: Record<string, string>;
      cx: Cx;
      css: Css;
      theme: Theme;
    };

Usage Examples:

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

const { makeStyles } = createMakeStyles({ useTheme });

// Static styles
const useStyles = makeStyles()({
  root: {
    backgroundColor: "white",
    padding: 16
  },
  button: {
    color: "primary",
    "&:hover": {
      backgroundColor: "rgba(0, 0, 0, 0.04)"
    }
  }
});

// Dynamic styles with theme
const useThemedStyles = makeStyles()(theme => ({
  root: {
    backgroundColor: theme.palette.background.paper,
    color: theme.palette.text.primary,
    padding: theme.spacing(2)
  },
  accent: {
    color: theme.palette.primary.main,
    fontWeight: theme.typography.fontWeightBold
  }
}));

// Parameterized styles
const useParameterizedStyles = makeStyles<{
  color: string;
  size: "small" | "medium" | "large";
}>()((theme, { color, size }) => ({
  root: {
    color,
    padding: {
      small: theme.spacing(1),
      medium: theme.spacing(2),
      large: theme.spacing(3)
    }[size]
  }
}));

// Named styles for debugging
const useNamedStyles = makeStyles({
  name: "MyComponent"
})({
  root: { padding: 16 }
});

// Usage in components
function MyComponent() {
  const { classes, cx, css, theme } = useStyles();
  
  return (
    <div className={classes.root}>
      <button className={cx(classes.button, css({ margin: theme.spacing(1) }))}>
        Click me
      </button>
    </div>
  );
}

function ParameterizedComponent({ variant }: { variant: "primary" | "secondary" }) {
  const { classes } = useParameterizedStyles({
    color: variant === "primary" ? "blue" : "gray",
    size: "medium"
  });
  
  return <div className={classes.root}>Content</div>;
}

TSS Cache Provider

React component for providing custom Emotion cache configuration to the component tree.

/**
 * React component for providing custom Emotion cache
 * @param props - Props containing children components
 * @returns JSX element wrapping children with cache provider
 */
interface TssCacheProvider extends React.ComponentType<{
  children: ReactNode;
}> {}

Usage Examples:

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

const { makeStyles, TssCacheProvider } = createMakeStyles({ useTheme });

function App() {
  return (
    <TssCacheProvider>
      <MyComponentTree />
    </TssCacheProvider>
  );
}

Migration from Material-UI v4

The makeStyles API is designed for seamless migration from @material-ui/core v4:

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

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

// After (TSS-React)
import { createMakeStyles } from "tss-react";
import { useTheme } from "@mui/material/styles";

const { makeStyles } = createMakeStyles({ useTheme });

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

Advanced Patterns

Nested Selectors with Classes Reference

const useNestedStyles = makeStyles<
  void,
  "root" | "button" | "icon"
>()((theme, params, classes) => ({
  root: {
    padding: theme.spacing(2),
    [`& .${classes.button}`]: {
      marginBottom: theme.spacing(1)
    },
    [`& .${classes.icon}`]: {
      marginRight: theme.spacing(0.5)
    }
  },
  button: {
    backgroundColor: theme.palette.primary.main,
    color: theme.palette.primary.contrastText
  },
  icon: {
    fontSize: 16
  }
}));

Media Queries and Breakpoints

const useResponsiveStyles = makeStyles()(theme => ({
  root: {
    padding: theme.spacing(1),
    [theme.breakpoints.up("md")]: {
      padding: theme.spacing(2)
    },
    [theme.breakpoints.up("lg")]: {
      padding: theme.spacing(3)
    }
  }
}));

Dynamic Properties with Props

interface StyleProps {
  variant: "outlined" | "filled";
  disabled: boolean;
}

const useDynamicStyles = makeStyles<StyleProps>()(
  (theme, { variant, disabled }) => ({
    root: {
      border: variant === "outlined" ? `1px solid ${theme.palette.divider}` : "none",
      backgroundColor: variant === "filled" ? theme.palette.action.hover : "transparent",
      opacity: disabled ? 0.5 : 1,
      cursor: disabled ? "not-allowed" : "pointer"
    }
  })
);

Utility Returns

The makeStyles hook returns several utility functions alongside the generated classes:

interface MakeStylesReturn<Theme> {
  /** Generated CSS class names keyed by rule name */
  classes: Record<string, string>;
  /** Classname combination utility function */
  cx: Cx;
  /** CSS-in-JS function for inline styles */
  css: Css;
  /** Current theme object */
  theme: Theme;
}

type Cx = (...classNames: CxArg[]) => string;

interface Css {
  (template: TemplateStringsArray, ...args: CSSInterpolation[]): string;
  (...args: CSSInterpolation[]): string;
}

Usage Examples:

function StyledComponent() {
  const { classes, cx, css, theme } = useStyles();
  
  return (
    <div className={classes.root}>
      <span 
        className={cx(
          classes.text,
          css({
            fontSize: theme.typography.h6.fontSize,
            marginTop: theme.spacing(1)
          })
        )}
      >
        Combined styles
      </span>
    </div>
  );
}

Combined Factory Function

Creates both makeStyles and withStyles functions together with a shared cache provider. This is a convenience function for applications that need both APIs.

/**
 * Creates makeStyles and withStyles functions with shared configuration
 * @param params - Configuration object with theme hook and optional cache
 * @returns Object containing makeStyles, withStyles, and TssCacheProvider
 */
function createMakeAndWithStyles<Theme>(params: {
  useTheme: () => Theme;
  cache?: EmotionCache;
}): {
  makeStyles: MakeStylesFunction<Theme>;
  withStyles: WithStylesFunction<Theme>;
  TssCacheProvider: React.ComponentType<{ children: ReactNode }>;
};

Usage Examples:

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

// Create both APIs together
const { makeStyles, withStyles, TssCacheProvider } = createMakeAndWithStyles({
  useTheme
});

// Use makeStyles for hook-based styling
const useCardStyles = makeStyles()(theme => ({
  root: {
    backgroundColor: theme.palette.background.paper,
    padding: theme.spacing(2),
    borderRadius: theme.shape.borderRadius
  },
  title: {
    color: theme.palette.text.primary,
    fontSize: theme.typography.h5.fontSize,
    marginBottom: theme.spacing(1)
  }
}));

// Use withStyles for HOC-based styling
const StyledButton = withStyles("button", theme => ({
  root: {
    backgroundColor: theme.palette.primary.main,
    color: theme.palette.primary.contrastText,
    padding: theme.spacing(1, 2),
    border: "none",
    borderRadius: theme.shape.borderRadius,
    cursor: "pointer",
    "&:hover": {
      backgroundColor: theme.palette.primary.dark
    }
  }
}));

function App() {
  return (
    <TssCacheProvider>
      <MyApp />
    </TssCacheProvider>
  );
}

function MyCard() {
  const { classes } = useCardStyles();
  
  return (
    <div className={classes.root}>
      <h2 className={classes.title}>Card Title</h2>
      <StyledButton>Action Button</StyledButton>
    </div>
  );
}

This combined approach is particularly useful for:

  • Migration Scenarios: When transitioning from Material-UI v4 and need both makeStyles and withStyles
  • Mixed Component Patterns: Applications using both hook-based and HOC-based styling approaches
  • Component Libraries: Libraries that provide multiple styling APIs for different use cases
  • Consistency: Ensuring both APIs use the same theme and cache configuration

With Custom Cache:

import createCache from "@emotion/cache";

const customCache = createCache({
  key: "app-styles",
  prepend: true,
  speedy: process.env.NODE_ENV === "production"
});

const { makeStyles, withStyles, TssCacheProvider } = createMakeAndWithStyles({
  useTheme,
  cache: customCache
});

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