Skip to content

Commit

Permalink
[zero][vite] Create a package for vite plugin
Browse files Browse the repository at this point in the history
This internally wraps linaria's vite plugin with ability to generate
theme CSS file as well.
  • Loading branch information
brijeshb42 committed Sep 4, 2023
1 parent 34c6464 commit 243469d
Show file tree
Hide file tree
Showing 12 changed files with 432 additions and 13 deletions.
2 changes: 1 addition & 1 deletion packages/zero-tag-processor/src/generateCss.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export function generateCss(
}
let cssStr = '';
Object.entries(themeArgs).forEach(([themeKey, theme]) => {
const cssVarsObject = generateCssForTheme(theme, [cssVariablesPrefix]);
const cssVarsObject = generateCssForTheme(theme as Theme, [cssVariablesPrefix]);
const cssThemeObject: Record<string, CssVarsObject> = {};
if (themeKey === defaultThemeKey && injectInRoot) {
cssThemeObject[':root'] = cssVarsObject;
Expand Down
2 changes: 1 addition & 1 deletion packages/zero-tag-processor/src/styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ export default class StyledProcessor extends BaseProcessor {
if (!value.name || !theme) {
return;
}
const componentData = theme.components?.[value.name];
const componentData = (theme as Theme).components?.[value.name];
if (!componentData) {
return;
}
Expand Down
7 changes: 3 additions & 4 deletions packages/zero-tag-processor/src/utils/cssFnValueToVariable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ export type PluginCustomOptions = {
/**
* Object to pass as parameter to the styled css callback functions.
*/
themeArgs?: {
theme: Theme;
};
themeArgs?: Record<string, unknown>;
};

type CssFnValueToVariableParams = {
Expand All @@ -39,7 +37,8 @@ function transformThemeKeysInFn(
filename?: string,
) {
const { themeArgs: { theme } = {} } = options;
const config = theme?.unstable_sxConfig ?? defaultSxConfig;
const userTheme = theme as Theme;
const config = userTheme?.unstable_sxConfig ?? defaultSxConfig;
const cssPropOptions = config[styleKey];
const { themeKey } = cssPropOptions;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { declare } from '@babel/helper-plugin-utils';
import defaultSxConfig from '@mui/system/styleFunctionSx/defaultSxConfig';
import get from 'lodash.get';
import type { Theme } from '@mui/material/styles';
import type { PluginCustomOptions } from './cssFnValueToVariable';

type BabelPluginOptions = {
Expand All @@ -25,7 +26,7 @@ const cssFunctionTransformerPlugin = declare<BabelPluginOptions>((api, pluginOpt
options: { cssVariablesPrefix = 'mui', themeArgs: { theme } = {} },
styleKey,
} = pluginOptions;
const config = theme?.unstable_sxConfig ?? defaultSxConfig;
const config = (theme as Theme)?.unstable_sxConfig ?? defaultSxConfig;
const cssPropOptions = config[styleKey];
const { themeKey } = cssPropOptions;
if (!theme || !config || !cssPropOptions || !themeKey) {
Expand Down
5 changes: 5 additions & 0 deletions packages/zero-vite-plugin/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"rules": {
"@typescript-eslint/consistent-type-imports": "error"
}
}
3 changes: 3 additions & 0 deletions packages/zero-vite-plugin/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# @mui/zero-vite-plugin

Vite plugin to support MUI's `styled` processor.
60 changes: 60 additions & 0 deletions packages/zero-vite-plugin/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
{
"name": "@mui/zero-vite-plugin",
"version": "0.0.1-alpha.0",
"private": true,
"author": "MUI Team",
"description": "Vite plugin for MUI zero styled implementation.",
"main": "./src/index.ts",
"keywords": [
"zero runtime",
"css-in-js",
"mui"
],
"repository": {
"type": "git",
"url": "https://github.com/mui/material-ui.git",
"directory": "packages/zero-vite-plugin"
},
"license": "MIT",
"bugs": {
"url": "https://github.com/mui/material-ui/issues"
},
"homepage": "@TODO",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/mui"
},
"scripts": {
"build": "yarn build:legacy && yarn build:modern && yarn build:node && yarn build:stable && yarn build:types && yarn build:copy-files",
"build:legacy": "node ../../scripts/build.mjs legacy",
"build:modern": "node ../../scripts/build.mjs modern",
"build:node": "node ../../scripts/build.mjs node",
"build:stable": "node ../../scripts/build.mjs stable",
"build:copy-files": "node ../../scripts/copyFiles.mjs",
"build:types": "node ../../scripts/buildTypes.mjs",
"prebuild": "rimraf build tsconfig.build.tsbuildinfo",
"release": "yarn build && npm publish build",
"test": "cd ../../ && cross-env NODE_ENV=test mocha 'packages/zero-babel-plugin/**/*.test.{js,ts,tsx}'",
"typescript": "tslint -p tsconfig.json \"{src,test}/**/*.{spec,d}.{ts,tsx}\" && tsc -p tsconfig.json",
"typescript:module-augmentation": "node scripts/testModuleAugmentation.js"
},
"dependencies": {
"@babel/core": "^7.22.10",
"@linaria/vite": "^4.5.4",
"@mui/zero-tag-processor": "0.0.1-alpha.0"
},
"devDependencies": {
"@types/babel__core": "^7.20.1",
"vite": "^4.4.9"
},
"peerDependencies": {
"vite": "^4.0.0"
},
"sideEffects": false,
"publishConfig": {
"access": "public"
},
"engines": {
"node": ">=12.0.0"
}
}
89 changes: 89 additions & 0 deletions packages/zero-vite-plugin/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import type { PluginOption } from 'vite';
import { generateCss } from '@mui/zero-tag-processor/generateCss';
import { transformAsync } from '@babel/core';
import linaria from '@linaria/vite';

type LinariaOptions = Exclude<Parameters<typeof linaria>[0], undefined>;

export interface ZeroVitePluginOptions extends LinariaOptions {
/**
* An object of the themes that you want passed in as an argument in the callback argument of `styled`.
*/
themeArgs?: Record<string, unknown>;
/**
* Prefix string to use in the generated css variables.
*/
cssVariablesPrefix?: string;
/**
* Whether the css variables for the default theme should target the :root selector or not.
* @default true
*/
injectDefaultThemeInRoot?: boolean;
}

export function zeroVitePlugin(options?: ZeroVitePluginOptions): PluginOption {
const {
cssVariablesPrefix = 'mui',
themeArgs = {},
injectDefaultThemeInRoot = true,
} = options ?? {};

function injectMUITokensPlugin(): PluginOption {
return {
name: 'vite-mui-theme-injection-plugin',
load(id) {
if (id.endsWith('@mui/zero-runtime/styles.css')) {
return {
code: generateCss(
{
cssVariablesPrefix,
themeArgs,
},
{
defaultThemeKey: 'theme',
injectInRoot: injectDefaultThemeInRoot,
},
),
map: null,
};
}
return null;
},
};
}
const extensions = ['.ts', '.tsx', '.js', '.jsx', '.mts', '.mjs', '.cts', '.cjs', '.mtsx'];

function intermediateBabelPlugin(): PluginOption {
return {
name: 'vite-intermediate-plugin',
async transform(code, id) {
const [filename] = id.split('?');
if (!extensions.some((ext) => filename.endsWith(ext))) {
return null;
}
const result = await transformAsync(code, {
filename,
babelrc: false,
configFile: false,
plugins: [['@mui/zero-tag-processor/pre-linaria-plugin']],
});
return {
code: result?.code ?? code,
map: result?.map,
};
},
};
}

const linariaPlugin = linaria({
cssVariablesPrefix,
themeArgs,
...options,
babelOptions: {
...options?.babelOptions,
plugins: ['@babel/plugin-syntax-jsx'],
},
});

return [injectMUITokensPlugin(), intermediateBabelPlugin(), linariaPlugin];
}
21 changes: 21 additions & 0 deletions packages/zero-vite-plugin/tsconfig.build.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
// This config is for emitting declarations (.d.ts) only
// Actual .ts source files are transpiled via babel
"extends": "./tsconfig",
"compilerOptions": {
"target": "ES2015",
"composite": true,
"declaration": true,
"noEmit": false,
"emitDeclarationOnly": true,
"outDir": "build",
"rootDir": "./src"
},
"include": ["./src/**/*.ts*"],
"exclude": ["src/**/*.spec.ts*", "src/**/*.test.ts*"],
"references": [
{ "path": "../mui-system/tsconfig.build.json" },
{ "path": "../mui-material/tsconfig.build.json" },
{ "path": "../zero-tag-processor/tsconfig.build.json" }
]
}
9 changes: 9 additions & 0 deletions packages/zero-vite-plugin/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "../../tsconfig",
"include": ["src/**/*", "test/**/*"],
"compilerOptions": {
"lib": ["ES2022", "DOM"],
"target": "ES2015",
"types": ["mocha", "node", "chai"]
}
}
3 changes: 3 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@
"@mui/material-next/*": ["./packages/mui-material-next/src/*"],
"@mui/joy": ["./packages/mui-joy/src"],
"@mui/joy/*": ["./packages/mui-joy/src/*"],
"@mui/zero-runtime/*": ["./packages/zero-runtime/src/*"],
"@mui/zero-tag-processor/*": ["./packages/zero-tag-processor/src/*"],
"@mui/zero-vite-plugin/*": ["./packages/zero-vite-plugin/src/*"],
"test/*": ["./test/*"],
"typescript-to-proptypes": ["./packages/typescript-to-proptypes/src"]
},
Expand Down
Loading

0 comments on commit 243469d

Please sign in to comment.