mui / pigment-css

Pigment CSS is a zero-runtime CSS-in-JS library that extracts the colocated styles to their own CSS files at build time.
MIT License
389 stars 18 forks source link

[core] Implement useTheme processor and runtime theme #105

Closed brijeshb42 closed 3 weeks ago

brijeshb42 commented 1 month ago

Here's how the replacement works

Before transformation:

import { useTheme } from '../zero-styled';

function Component() {
  const theme = useTheme();
  // ...rest
}

After transformation:

import _theme from '@pigment-css/react/theme';

function Component() {
  const theme = _theme;
  // ...rest
}

Fixes: https://github.com/mui/material-ui/issues/42260

siriwatknp commented 3 weeks ago

Here is my proposal, Material UI export a stringifyTheme function https://github.com/mui/material-ui/pull/42476 for zero-runtime libraries.

From Pigment side, I see 2 choices:

  1. Pigment calls a method from the theme, e.g. theme.toRuntime():

    // next.config.js
    const { extendTheme, stringifyTheme } = require('@mui/material/styles');
    
    const theme = extendTheme();
    
    theme.toRuntime = () => stringifyTheme(theme);
    
    module.exports = withPigment({
    theme,
    })
  2. Pigment read from the config

    // next.config.js
    const { extendTheme, stringifyTheme } = require('@mui/material/styles');
    
    const theme = extendTheme();
    
    module.exports = withPigment({
    theme,
    runtimeTheme: stringifyTheme(theme),
    })

I like this approach because regardless of the choice, it's not related to Material UI. In the future, stringifyTheme could be moved to Material UI plugin for Pigment.

brijeshb42 commented 3 weeks ago

I like the first approach better, ie, theme.toRuntime. This way, users won't have to care about anything extra. We can make toRuntime method part of the createTheme/extendTheme from material-ui source code. In future, this will anyways won't be part of the Pigment v1 release since the whole thing is very specific to Material UI. So we can move this over to the Material specific package.

I am naming the method to toRuntimeSource to be more explicit.