Skip to content
This repository has been archived by the owner on Mar 6, 2024. It is now read-only.

Create autoconfig script for tailwindcss & Material UI #42

Merged
merged 24 commits into from
Jun 8, 2023
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add strategies for mui and sass
Shaun Lloyd committed Jun 6, 2023

Verified

This commit was signed with the committer’s verified signature.
SorsOps SorsOps
commit 43675f893f09162aea5005a07cac7fecd776737c
10 changes: 8 additions & 2 deletions src/postinstall.ts
Original file line number Diff line number Diff line change
@@ -11,8 +11,14 @@ import {
import { determineBuilder } from "./postinstall/utils/dependencies.utils";

import { tailwindStrategy } from "./postinstall/tailwind/tailwind.strategy";

const AUTO_CONFIG_STRATEGIES: ToolConfigurationStrategy[] = [tailwindStrategy];
import { materialUIStrategy } from "./postinstall/material-ui/material-ui.strategy";
import { sassStrategy } from "./postinstall/sass/sass.strategy";

const AUTO_CONFIG_STRATEGIES: ToolConfigurationStrategy[] = [
tailwindStrategy,
materialUIStrategy,
sassStrategy,
];

const selectStrategy = (packageJson: PackageJson) =>
AUTO_CONFIG_STRATEGIES.find(({ predicate }) => predicate(packageJson));
ShaunEvening marked this conversation as resolved.
Show resolved Hide resolved
97 changes: 97 additions & 0 deletions src/postinstall/material-ui/material-ui.strategy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { PackageJson } from "@storybook/types";
import * as t from "@babel/types";

import { hasDependency } from "../utils/dependencies.utils";
import { SUPPORTED_STYLING_TOOLS, ToolConfigurationStrategy } from "../types";
import { addImports, stringToNode } from "../utils/babel.utils";

const projectHasMaterialUI = (packageJson: PackageJson) =>
hasDependency(packageJson, "@mui/material") &&
hasDependency(packageJson, "@emotion/react") &&
hasDependency(packageJson, "@emotion/styled");

export const materialUIStrategy: ToolConfigurationStrategy = {
name: SUPPORTED_STYLING_TOOLS.MATERIAL_UI,
predicate: projectHasMaterialUI,
main: (mainConfig, packageJson, builder, { logger, colors }) => {
ShaunEvening marked this conversation as resolved.
Show resolved Hide resolved
logger.plain(` • No changes required.`);
return;
},
preview: (previewConfig, packageJson, builder, { logger, colors }) => {
logger.plain(
` • Adding imports for ${colors.green(
SUPPORTED_STYLING_TOOLS.MATERIAL_UI
)} ${colors.blue("ThemeProvider")} and ${colors.blue(
"CssBaseline"
)} components`
ShaunEvening marked this conversation as resolved.
Show resolved Hide resolved
);
logger.plain(
` • Adding import for ${colors.blue(
"withThemeFromJSXProvider"
)} decorator`
);
hasDependency(packageJson, "@fontsource/roboto")
? logger.plain(` • importing ${colors.blue("roboto")} font files.`)
: logger.plain(
` • Could not detect ${colors.blue(
"roboto"
)} font. Skipping font import`
);

const importsNode = hasDependency(packageJson, "@fontsource/roboto")
? stringToNode`
import { ThemeProvider, CssBaseline } from '@mui/material';
import { withThemeFromJSXProvider } from '@storybook/addon-styling';
// TODO: update import for your custom Material UI themes
// import { lightTheme, darkTheme } from '../path/to/themes';
ShaunEvening marked this conversation as resolved.
Show resolved Hide resolved
import '@fontsource/roboto/300.css';
import '@fontsource/roboto/400.css';
import '@fontsource/roboto/500.css';
import '@fontsource/roboto/700.css';
`
: stringToNode`
import { ThemeProvider, CssBaseline } from '@mui/material';
import { withThemeFromJSXProvider } from '@storybook/addon-styling';
// TODO: update import for your custom Material UI themes
// import { lightTheme, darkTheme } from '../path/to/themes';
// Import your fontface CSS files here
// Don't have any? We recommend installing and using @fontsource/roboto`;

addImports(previewConfig._ast, importsNode);

logger.plain(
` • Adding ${colors.blue(
"withThemeFromJSXProvider"
)} decorator to config`
);
const [
decoratorNode,
] = stringToNode`// Adds global styles and theme switching support.
withThemeFromJSXProvider({
GlobalStyles: CssBaseline,
// Uncomment for theme switching
// Provider: ThemeProvider,
// themes: {
// Provide your custom themes here
// light: lightTheme,
// dark: darkTheme,
// },
// defaultTheme: 'light',
})`;

const decoratorNodePath = ["decorators"];
let decoratorArrayNode = previewConfig.getFieldNode(decoratorNodePath);

if (!decoratorArrayNode) {
previewConfig.setFieldNode(decoratorNodePath, t.arrayExpression());
decoratorArrayNode = previewConfig.getFieldNode(decoratorNodePath);
}

// @ts-expect-error
decoratorArrayNode.elements.push(decoratorNode);
},
};
88 changes: 88 additions & 0 deletions src/postinstall/sass/sass.strategy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { PackageJson } from "@storybook/types";
import * as t from "@babel/types";

import { hasDependency } from "../utils/dependencies.utils";
import {
SUPPORTED_BUILDERS,
SUPPORTED_STYLING_TOOLS,
ToolConfigurationStrategy,
} from "../types";
import { addImports, stringToNode } from "../utils/babel.utils";

const projectHasSass = (packageJson: PackageJson) =>
hasDependency(packageJson, "sass");

export const sassStrategy: ToolConfigurationStrategy = {
name: SUPPORTED_STYLING_TOOLS.MATERIAL_UI,
predicate: projectHasSass,
main: (mainConfig, packageJson, builder, { logger, colors }) => {
if (builder === SUPPORTED_BUILDERS.VITE) {
// Vite does not require extra configuration
logger.plain(` • No changes required.`);
return;
}

logger.plain(` • Configuring ${colors.green("postcss")}.`);

const [addonConfigNode] = stringToNode`({
name: "@storybook/addon-styling",
options: {
sass: {
implementation: require.resolve("sass")
}
}
})`;

console.log(addonConfigNode);

const addonsNodePath = ["addons"];
let addonsArrayNode = mainConfig.getFieldNode(addonsNodePath);

if (!addonsArrayNode) {
mainConfig.setFieldNode(addonsNodePath, t.arrayExpression());
addonsArrayNode = mainConfig.getFieldNode(addonsNodePath);
}

// @ts-expect-error
addonsArrayNode.elements.push(addonConfigNode);
},
preview: (previewConfig, packageJson, builder, { logger, colors }) => {
logger.plain(
` • Adding imports for ${colors.green(SUPPORTED_STYLING_TOOLS.SASS)}`
);

const importsNode = stringToNode`
import { withThemeByClassName } from '@storybook/addon-styling';
// TODO: update import for your sass stylesheet
import '../path/to/styles.sass';`;

addImports(previewConfig._ast, importsNode);

logger.plain(
` • Adding ${colors.blue("withThemeByClassName")} decorator to config`
);
const [
decoratorNode,
] = stringToNode`// Uncomment to add theme switching support.
// withThemeByClassName({
// themes: {
// // Provide the classes for your themes
// light: "light-mode",
// dark: "dark-mode",
// },
// defaultTheme: 'light',
})`;

const decoratorNodePath = ["decorators"];
let decoratorArrayNode = previewConfig.getFieldNode(decoratorNodePath);

if (!decoratorArrayNode) {
previewConfig.setFieldNode(decoratorNodePath, t.arrayExpression());
decoratorArrayNode = previewConfig.getFieldNode(decoratorNodePath);
}

// @ts-expect-error
decoratorArrayNode.elements.push(decoratorNode);
},
};
2 changes: 2 additions & 0 deletions src/postinstall/types.ts
Original file line number Diff line number Diff line change
@@ -17,6 +17,8 @@ export type SupportedBuilders =

export const SUPPORTED_STYLING_TOOLS = {
TAILWIND: "tailwind",
MATERIAL_UI: "material-ui",
SASS: "sass",
} as const;

export type SupportedStylingTools =