tss-react

repository·main·Indexed 20 days ago

https://github.com/garronej/tss-react

A type-safe CSS-in-TS library powered by Emotion, designed as a modern alternative to JSS and Material UI v4's makeStyles. It allows developers to write plain CSS that dynamically reacts to component props and state. Features include full TypeScript support, seamless MUI integration, and compatibility with Next.js App and Page Routers. It provides utilities like createMakeAndWithStyles for hook-based and HOC-based styling, and a classnames utility (Cx) for conditional class name composition.

Tokens
4.2K
Snippets
19
Records
23
Agent score
72%

What's inside tss-react

  1. Overview of tss-react

    main

    tss-react is a dynamic CSS-in-TS solution built on top of Emotion. It provides a type-safe equivalent to the JSS API, making it a modern replacement for @material-ui v4 makeStyles and react-jss.

    Key features include:

    • Type-safety: Full TypeScript support for styles.
    • Dynamic Styles: Generate styles based on component props and internal state.
    • MUI Integration: Seamlessly works with Material UI.
    • Next.js Support: Compatible with both App and Page Router (note: dynamic style generation currently prevents support for React Server Components/RSC).
    • CSS Control: Ability to increase rule specificity to avoid priority conflicts.
    • Low Overhead: Minimal impact on bundle size (~5kB minzipped alongside MUI).
    • JSS Syntax: Provides a type-safe equivalent of the JSS $ syntax for nested selectors.
  2. Integrate tss-react with MUI Material

    main

    To use tss-react with Material UI (MUI), you must initialize it using createMakeAndWithStyles and createTss while providing the MUI useTheme hook. This ensures that the generated styles have access to your MUI theme context.

    Use the exported makeStyles and withStyles for standard style creation, or the tss instance for advanced usage with plugins like useMuiThemeStyleOverridesPlugin.

    import { makeStyles, withStyles, tss } from "@garronej/tss-react/mui";
    
    // Standard usage with MUI theme support
    const useStyles = makeStyles({ class1: { color: 'red' } });
    
    // Advanced usage via the tss instance
    const useStylesAdvanced = tss.create({
      class1: { color: 'blue' }
    });
  3. Configure createEmotionSsrAdvancedApproach options

    main

    The createEmotionSsrAdvancedApproach function accepts an options object used to configure the underlying Emotion cache.

    Available keys:

    • key: (Required) The prefix used for the cache and the insertion point ID (e.g., css).
    • prepend: (Optional) A boolean indicating whether Emotion styles should be prepended to the existing styles in the document. If true, emotionStyles appear before otherStyles in the final output.
    • nonce: (Optional) A string used for Content Security Policy (CSP) nonces on the generated <style> tags.
    • Any other valid options from @emotion/cache (excluding insertionPoint).
  4. Configure CSS Layers with prepend option

    main

    The NextAppDirEmotionCacheProvider allows you to wrap injected Emotion styles in a CSS layer. This is useful for managing CSS specificity when using modern CSS features like @layer.

    Set prepend: true within the options object to wrap all injected styles in @layer emotion { ... }.

    <NextAppDirEmotionCacheProvider options={{ prepend: true }}>
      {/* Styles will be injected inside @layer emotion { ... } */}
      {children}
    </NextAppDirEmotionCacheProvider>
  5. Avoid passing Emotion `css` objects to `classnames`

    main

    The classnames utility is designed to compose class name strings. If you pass an object created by the @emotion/react css function (which contains styles and name properties) to classnames, it will trigger a development-mode error.

    Error Message: "You have passed styles created with cssfrom@emotion/reactpackage to thecx.\ncxis meant to compose class names (strings) so you should convert those styles to a class name by passing them to thecss received from <ClassNames/> component."

    Solution: Instead of passing the raw Emotion object to classnames, use the css prop/function provided by the <ClassNames/> component to convert those styles into a valid class name string first.

  6. Use NextAppDirEmotionCacheProvider for Next.js App Router

    main

    When using Emotion with the Next.js App Router, use NextAppDirEmotionCacheProvider to ensure styles are correctly injected during server-side rendering. This provider manages the Emotion cache and uses useServerInsertedHTML to flush and inject styles into the HTML stream, preventing FOUC (Flash of Unstyled Content).

    Props

    PropTypeDescription
    optionsOmit<OptionsOfCreateCache, "insertionPoint"> & { prepend?: boolean }Configuration options passed to @emotion/cache's createCache. Use prepend: true to wrap styles in a @layer emotion block.
    CacheProviderReact.Provider<EmotionCache>Optional custom Emotion CacheProvider. Defaults to the standard @emotion/react provider.
    childrenReactNodeThe component tree to be wrapped by the provider.
    options.noncestring(Via options) A nonce for security when using Content Security Policy (CSP).
    options.prependboolean(Via options) If true, styles are wrapped in @layer emotion { ... }. Defaults to false.
    import { NextAppDirEmotionCacheProvider } from "tss-react/next";
    
    export default function RootLayout({ children }: { children: React.ReactNode }) {
      return (
        <html lang="en">
          <body>
            <NextAppDirEmotionCacheProvider options={{ prepend: true }}>
              {children}
            </NextAppDirEmotionCacheProvider>
          </body>
        </html>
      );
    }
  7. Create combined MakeStyles and WithStyles utilities

    main

    Use createMakeAndWithStyles to generate a single object containing both makeStyles (for hook-based styling) and withStyles (for HOC-based styling) utilities. This function requires a useTheme callback to access your application's theme and an optional EmotionCache for integration with Emotion.

    import { createMakeAndWithStyles } from 'tss-react';
    
    const { makeStyles, withStyles } = createMakeAndWithStyles({
      useTheme: () => ({ color: 'red' } as any),
      cache: myEmotionCache,
    });
  8. Create combined MakeStyles and WithStyles with createMakeAndWithStyles

    main

    If you need both the makeStyles pattern (hook-based) and the withStyles pattern (HOC-based) using a shared theme and cache, use createMakeAndWithStyles. This function requires a useTheme function that returns your application's theme and an optional EmotionCache.

    import { createMakeAndWithStyles } from 'tss-react';
    
    const { makeStyles, withStyles } = createMakeAndWithStyles({
        useTheme: () => ({ color: 'red' } as any),
        // cache is optional
    });
  9. Use the useMuiThemeStyleOverridesPlugin

    main

    The useMuiThemeStyleOverridesPlugin allows you to apply style overrides to the MUI theme. It accepts a configuration object of type MuiThemeStyleOverridesPluginParams to define how the theme should be modified.

    import { useMuiThemeStyleOverridesPlugin } from './mui';
    import type { MuiThemeStyleOverridesPluginParams } from './mui';
  10. Initialize tss with createTss

    main

    Use createTss to initialize the core tss instance. This allows you to provide context-based logic, such as a useContext hook, which will be available to your styles. The exported tss object provides the foundation for creating styles and hooks within the library.

    import { createTss } from 'tss-react';
    
    export const { tss } = createTss({
        "useContext": () => ({}) // Provide your context logic here
    });
  11. Import Next.js integration from tss-react/next

    main

    The tss-react/next entrypoint provides specialized integrations for Next.js, split by directory structure. Depending on whether you are using the Next.js App Router or the Pages Router, you should import from the corresponding sub-module exported by this entrypoint.

    • For App Router projects: Use exports from ./appDir.
    • For Pages Router projects: Use exports from ./pagesDir.
  12. Use the default tss instance

    main

    The library exports a pre-configured tss instance. This instance is useful for quick setups where you don't need to provide a custom theme provider or specialized context immediately. You can also use tss.create({}) to generate a useStyles hook.

    import { tss, useStyles } from 'tss-react';
    
    // Using the exported tss instance
    const { classes } = tss.create({
      root: { color: 'blue' }
    });
    
    // Or using the pre-generated useStyles hook
    const { classes } = useStyles({
      root: { color: 'green' }
    });