From 9c689a18305f0daf216c598c2a346c215e6fc89d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivica=20Batini=C4=87?= Date: Wed, 31 Jan 2024 21:52:46 +0100 Subject: [PATCH] feat: add panda-css --- CONTRIBUTING.md | 2 +- .../components/TechnologiesForm.tsx | 7 + packages/create-next-stack/README.md | 3 +- .../src/main/create-next-stack-types.ts | 1 + .../sort-orders/technologies.ts | 1 + .../add-content/pages/generate-index.ts | 23 ++++ .../src/main/plugins/panda-css/panda-css.ts | 121 ++++++++++++++++++ .../create-next-stack/src/main/setup/setup.ts | 2 + packages/create-next-stack/src/main/steps.ts | 2 + .../panda-css/panda-css-all-flags.test.ts | 26 ++++ .../tests/panda-css/panda-css-only.test.ts | 16 +++ 11 files changed, 202 insertions(+), 2 deletions(-) create mode 100644 packages/create-next-stack/src/main/plugins/panda-css/add-content/pages/generate-index.ts create mode 100644 packages/create-next-stack/src/main/plugins/panda-css/panda-css.ts create mode 100644 packages/create-next-stack/src/tests/e2e/tests/panda-css/panda-css-all-flags.test.ts create mode 100644 packages/create-next-stack/src/tests/e2e/tests/panda-css/panda-css-only.test.ts diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7aef8ec..26676d2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -87,7 +87,7 @@ Make sure you are set up locally by following the [Getting Started](#getting-sta - `e2e` - Runs e2e tests. Note that this will run all e2e tests, which can take quite a while. - `e2e:manual` - This is performing a manual run of the CLI. Pass flags to the CLI that you want to test. - - For example, `pnpm run test:manual --package-manager=pnpm --styling=emotion`. + - For example, `pnpm run e2e:manual --package-manager=pnpm --styling=emotion`. - `clean` - Removes all generated files, including build files and the `create-next-stack-tests` directory created by the e2e tests. 3. Add a new .ts file for your plugin in the plugins directory at [`packages/create-next-stack/src/main/plugins`](packages/create-next-stack/src/main/plugins) diff --git a/apps/website/templates/LandingPage/components/TechnologiesForm.tsx b/apps/website/templates/LandingPage/components/TechnologiesForm.tsx index 1921eae..85500f7 100644 --- a/apps/website/templates/LandingPage/components/TechnologiesForm.tsx +++ b/apps/website/templates/LandingPage/components/TechnologiesForm.tsx @@ -32,6 +32,7 @@ type OptionKey = | "cssModules" | "tailwindCss" | "cssModulesWithSass" + | "pandaCss" | "noStyling" | "reactHookForm" | "formik" @@ -73,6 +74,11 @@ const options = { value: "css-modules-with-sass", label: "CSS Modules with Sass", }, + pandaCss: { + key: "pandaCss", + value: "panda-css", + label: "Panda CSS", + }, noStyling: { key: "noStyling", value: cssModulesValue, @@ -145,6 +151,7 @@ const stylingOptionKeys = [ optionKeys.tailwindCss, optionKeys.cssModules, optionKeys.cssModulesWithSass, + optionKeys.pandaCss, optionKeys.noStyling, ] satisfies OptionKey[] const formStateManagementOptionKeys = [ diff --git a/packages/create-next-stack/README.md b/packages/create-next-stack/README.md index ff5a718..6cd6ccb 100644 --- a/packages/create-next-stack/README.md +++ b/packages/create-next-stack/README.md @@ -44,6 +44,7 @@ The table below provides an overview of the technologies currently supported by | Sass | [Website](https://sass-lang.com/) - [Docs](https://sass-lang.com/documentation) - [Next.js-specific docs](https://nextjs.org/docs/basic-features/built-in-css-support#sass-support) | | CSS Modules | [Website](https://github.com/css-modules/css-modules) - [Docs](https://github.com/css-modules/css-modules) - [Next.js-specific docs](https://nextjs.org/docs/basic-features/built-in-css-support#adding-component-level-css) | | CSS Modules | [Website](https://github.com/css-modules/css-modules) - [Docs](https://github.com/css-modules/css-modules) - [Next.js-specific docs](https://nextjs.org/docs/basic-features/built-in-css-support#adding-component-level-css) | +| Panda CSS | [Website](https://panda-css.com) - [Docs](https://panda-css.com/docs) - [GitHub](https://github.com/chakra-ui/panda) | | Mantine | [Website](https://mantine.dev/) - [Docs](https://mantine.dev/pages/getting-started/) - [GitHub](https://github.com/mantinedev/mantine) | | Chakra UI | [Website](https://chakra-ui.com/) - [Docs](https://chakra-ui.com/docs/getting-started) - [GitHub](https://github.com/chakra-ui/chakra-ui) | | Material UI | [Website](https://material-ui.com/) - [Docs](https://material-ui.com/getting-started/installation/) - [GitHub](https://github.com/mui-org/material-ui) | @@ -111,7 +112,7 @@ FLAGS --styling= (required) Sets the preferred styling method. (Required) = emotion|styled-components|tailwind-css|css-modul - es|css-modules-with-sass + es|css-modules-with-sass|panda-css --vercel Adds Vercel. (Hosting) ``` diff --git a/packages/create-next-stack/src/main/create-next-stack-types.ts b/packages/create-next-stack/src/main/create-next-stack-types.ts index 92b312a..8a91cb3 100644 --- a/packages/create-next-stack/src/main/create-next-stack-types.ts +++ b/packages/create-next-stack/src/main/create-next-stack-types.ts @@ -37,6 +37,7 @@ export const stylingOptions = [ "tailwind-css", "css-modules", "css-modules-with-sass", + "panda-css", ] as const export type StylingOption = (typeof stylingOptions)[number] export const writableStylingOptions = stylingOptions as Writable< diff --git a/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/technologies.ts b/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/technologies.ts index 8dfc4bf..ffcbcda 100644 --- a/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/technologies.ts +++ b/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/technologies.ts @@ -14,6 +14,7 @@ export const technologiesSortOrder: string[] = [ "tailwindCSS", "sass", "cssModules", + "pandaCSS", "mantine", "chakraUI", "materialUI", diff --git a/packages/create-next-stack/src/main/plugins/panda-css/add-content/pages/generate-index.ts b/packages/create-next-stack/src/main/plugins/panda-css/add-content/pages/generate-index.ts new file mode 100644 index 0000000..56bb47c --- /dev/null +++ b/packages/create-next-stack/src/main/plugins/panda-css/add-content/pages/generate-index.ts @@ -0,0 +1,23 @@ +import endent from "endent" +import { ValidCNSInputs } from "../../../../create-next-stack-types" +import { getProjectNameOfPath } from "../../../../helpers/get-project-name-of-path" + +export const generateIndexPage = ({ args }: ValidCNSInputs): string => endent` + import { NextPage } from "next"; + import Head from "next/head"; + import { css } from '../../styled-system/css'; + + const Index: NextPage = () => { + return ( + <> + + ${getProjectNameOfPath(args.app_name)} + + +
Hello 🐼!
+ + ); + }; + + export default Index; +` diff --git a/packages/create-next-stack/src/main/plugins/panda-css/panda-css.ts b/packages/create-next-stack/src/main/plugins/panda-css/panda-css.ts new file mode 100644 index 0000000..0ceff81 --- /dev/null +++ b/packages/create-next-stack/src/main/plugins/panda-css/panda-css.ts @@ -0,0 +1,121 @@ +import endent from "endent" +import { makeDirectory, writeFile } from "../../helpers/io" +import { createPlugin } from "../../plugin" +import { generateIndexPage } from "./add-content/pages/generate-index" + +export const pandaCSSPlugin = createPlugin({ + id: "panda-css", + name: "Panda CSS", + description: "Adds support for Panda CSS", + active: ({ flags }) => flags["styling"] === "panda-css", + devDependencies: { + pandacss: { + name: "@pandacss/dev", + version: "^0.x.x", + }, + autoprefixer: { + name: "autoprefixer", + version: "^10.0.0", + }, + postcss: { + name: "postcss", + version: "^8.0.0", + }, + }, + technologies: [ + { + id: "pandaCSS", + name: "Panda CSS", + description: + "🐼 Universal, Type-Safe, CSS-in-JS Framework for Product Teams ⚡️", + links: [ + { title: "Website", url: "https://panda-css.com" }, + { title: "Docs", url: "https://panda-css.com/docs" }, + { title: "GitHub", url: "https://github.com/chakra-ui/panda" }, + ], + }, + ], + steps: { + setUpPandaCss: { + id: "setUpPandaCss", + description: "setting up panda CSS", + run: async () => { + await Promise.all([ + addPandaConfig(), + addPostcssConfig(), + addStylesGlobalsCss(), + ]) + }, + }, + addContent: { + id: "addContent", + description: "adding content", + run: async (inputs) => { + await Promise.all([ + writeFile("pages/index.tsx", generateIndexPage(inputs)), + ]) + }, + }, + }, + scripts: [ + { + name: "prepare", + description: "Run panda codegen after dependencies are installed", + command: "panda codegen", + }, + ], + slots: { + app: { + imports: `import "../styles/globals.css";`, + }, + }, +} as const) + +const addPandaConfig = async () => { + // From running `npx panda init --postcss` and adding globs to the include array according to https://panda-css.com/docs/installation/nextjs?value=pages-dir#configure-the-content + const pandaConfigString = endent` + import { defineConfig } from "@pandacss/dev"; + + export default defineConfig({ + // Whether to use css reset + preflight: true, + + // Where to look for your css declarations + include: ["./src/**/*.{js,jsx,ts,tsx}", "./pages/**/*.{js,jsx,ts,tsx}"], + + // Files to exclude + exclude: [], + + // Useful for theme customization + theme: { + extend: {}, + }, + + // The output directory for your css system + outdir: "styled-system", + }); + ` + await writeFile("panda.config.ts", pandaConfigString) +} + +const addPostcssConfig = async () => { + // From https://panda-css.com/docs/installation/nextjs?value=pages-dir#install-panda-css + const postcssConfigString = endent` + module.exports = { + plugins: { + '@pandacss/dev/postcss': {}, + autoprefixer: {}, + }, + } + ` + await writeFile("postcss.config.js", postcssConfigString) +} + +const addStylesGlobalsCss = async () => { + // From https://panda-css.com/docs/installation/nextjs?value=pages-dir#configure-the-entry-css-with-layers + const stylesGlobalsCssString = endent` + @layer reset, base, tokens, recipes, utilities; + ` + await makeDirectory("styles") + await writeFile("styles/globals.css", stylesGlobalsCssString) +} diff --git a/packages/create-next-stack/src/main/setup/setup.ts b/packages/create-next-stack/src/main/setup/setup.ts index 4025402..fbcbbbe 100644 --- a/packages/create-next-stack/src/main/setup/setup.ts +++ b/packages/create-next-stack/src/main/setup/setup.ts @@ -35,6 +35,7 @@ import { vercelPlugin } from "../plugins/vercel" import { yarnPlugin } from "../plugins/yarn" import { steps } from "../steps" import { printFinalMessages } from "./print-final-messages" +import { pandaCSSPlugin } from "../plugins/panda-css/panda-css" export const plugins: Plugin[] = [ createNextStackPlugin, @@ -46,6 +47,7 @@ export const plugins: Plugin[] = [ tailwindCSSPlugin, cssModulesPlugin, sassPlugin, + pandaCSSPlugin, mantinePlugin, chakraUIPlugin, materialUIPlugin, diff --git a/packages/create-next-stack/src/main/steps.ts b/packages/create-next-stack/src/main/steps.ts index 5223092..f33ffe0 100644 --- a/packages/create-next-stack/src/main/steps.ts +++ b/packages/create-next-stack/src/main/steps.ts @@ -8,6 +8,7 @@ import { githubActionsPlugin } from "./plugins/github-actions" import { mantinePlugin } from "./plugins/mantine/mantine" import { materialUIPlugin } from "./plugins/material-ui/material-ui" import { nextPlugin } from "./plugins/next" +import { pandaCSSPlugin } from "./plugins/panda-css/panda-css" import { pnpmPlugin } from "./plugins/pnpm" import { prettierPlugin } from "./plugins/prettier" import { sassPlugin } from "./plugins/sass/sass" @@ -36,6 +37,7 @@ export const steps: Step[] = [ cssModulesPlugin.steps.setUpCssModules, sassPlugin.steps.setUpSass, emotionPlugin.steps.setUpEmotion, + pandaCSSPlugin.steps.setUpPandaCss, // Formatting prettierPlugin.steps.setUpPrettier, diff --git a/packages/create-next-stack/src/tests/e2e/tests/panda-css/panda-css-all-flags.test.ts b/packages/create-next-stack/src/tests/e2e/tests/panda-css/panda-css-all-flags.test.ts new file mode 100644 index 0000000..871c977 --- /dev/null +++ b/packages/create-next-stack/src/tests/e2e/tests/panda-css/panda-css-all-flags.test.ts @@ -0,0 +1,26 @@ +import { test } from "@jest/globals" +import { testArgsWithFinalChecks } from "../../helpers/test-args" +import { twentyMinutes } from "../../helpers/timeout" + +test( + "testPandaCssAllFlags", + async () => { + await testArgsWithFinalChecks([ + "--debug", + "--package-manager=pnpm", + "--prettier", + "--styling=panda-css", + "--react-hook-form", + "--formik", + "--framer-motion", + "--formatting-pre-commit-hook", + "--react-icons", + "--react-query", + "--plausible", + "--vercel", + "--netlify", + ".", + ]) + }, + twentyMinutes +) diff --git a/packages/create-next-stack/src/tests/e2e/tests/panda-css/panda-css-only.test.ts b/packages/create-next-stack/src/tests/e2e/tests/panda-css/panda-css-only.test.ts new file mode 100644 index 0000000..0739f96 --- /dev/null +++ b/packages/create-next-stack/src/tests/e2e/tests/panda-css/panda-css-only.test.ts @@ -0,0 +1,16 @@ +import { test } from "@jest/globals" +import { testArgsWithFinalChecks } from "../../helpers/test-args" +import { twentyMinutes } from "../../helpers/timeout" + +test( + "testPandaCssOnly", + async () => { + await testArgsWithFinalChecks([ + "--debug", + "--package-manager=pnpm", + "--styling=panda-css", + ".", + ]) + }, + twentyMinutes +)