├── packages ├── define-recipe │ ├── .gitignore │ ├── src │ │ ├── index.ts │ │ ├── type-helpers.ts │ │ └── define-recipe.ts │ ├── tsconfig.json │ ├── tsup.config.ts │ ├── tsconfig.bench.json │ ├── CHANGELOG.md │ └── package.json ├── define-theme │ ├── .gitignore │ ├── src │ │ ├── index.ts │ │ ├── runtime.ts │ │ └── selectors.ts │ ├── sandbox │ │ ├── preset-panda │ │ │ ├── borders.ts │ │ │ ├── breakpoints.ts │ │ │ ├── aspect-ratios.ts │ │ │ ├── index.ts │ │ │ ├── shadows.ts │ │ │ ├── sizes.ts │ │ │ ├── keyframes.ts │ │ │ ├── spacing.ts │ │ │ └── tokens.ts │ │ ├── tsconfig.json │ │ ├── preset-base │ │ │ ├── utilities │ │ │ │ ├── list.ts │ │ │ │ ├── svg.ts │ │ │ │ ├── outline.ts │ │ │ │ ├── tables.ts │ │ │ │ ├── display.ts │ │ │ │ ├── helpers.ts │ │ │ │ ├── divide.ts │ │ │ │ ├── polyfill.ts │ │ │ │ ├── index.ts │ │ │ │ └── transforms.ts │ │ │ └── index.ts │ │ ├── define-theme.bench.ts │ │ ├── theme-preset.ts │ │ ├── theme-preset-demo.ts │ │ ├── strict-property-values.ts │ │ ├── token-paths.ts │ │ └── strict-tokens.ts │ ├── tsup.config.ts │ ├── tsconfig.json │ ├── CHANGELOG.md │ ├── tsconfig.bench.json │ └── package.json ├── presets │ ├── src │ │ └── index.ts │ ├── tsconfig.json │ ├── tsup.config.ts │ ├── CHANGELOG.md │ └── package.json ├── prettier-plugin │ ├── src │ │ ├── index.ts │ │ └── plugin.ts │ ├── __tests__ │ │ ├── tsconfig.json │ │ └── panda.config.ts │ ├── tsup.config.ts │ ├── tsconfig.json │ ├── package.json │ └── CHANGELOG.md ├── fixtures │ ├── src │ │ ├── index.ts │ │ └── utils.ts │ ├── tsconfig.json │ └── package.json ├── panda-plugins │ ├── __tests__ │ │ ├── scenarios │ │ │ ├── .gitignore │ │ │ ├── missing-css-warnings.config.ts │ │ │ ├── remove-negative-spacing.config.ts │ │ │ ├── restrict-styled-props.config.ts │ │ │ ├── strict-tokens-scope.test.ts │ │ │ ├── remove-negative-spacing.test.ts │ │ │ ├── strict-tokens-scope.config.ts │ │ │ ├── strict-tokens-runtime.config.ts │ │ │ ├── restrict-styled-props.test.tsx │ │ │ └── missing-css-warnings.test.ts │ │ └── tsconfig.json │ ├── tsconfig.json │ ├── tsup.config.ts │ ├── src │ │ ├── index.ts │ │ ├── minimal-setup.ts │ │ └── remove-unused-css.ts │ ├── test-cli.md │ ├── vitest.config.ts │ ├── README.md │ └── package.json ├── codemods │ ├── src │ │ └── index.ts │ ├── CHANGELOG.md │ ├── tsconfig.json │ ├── tsup.config.ts │ ├── __tests__ │ │ └── template-to-object-syntax.test.ts │ └── package.json ├── unplugin │ ├── __tests__ │ │ ├── env.d.ts │ │ ├── tsconfig.json │ │ └── samples │ │ │ ├── only-recipe.tsx │ │ │ ├── only-pattern.tsx │ │ │ ├── only-css-raw.tsx │ │ │ ├── only-css.tsx │ │ │ ├── only-styled.tsx │ │ │ ├── css-with-raw.tsx │ │ │ ├── only-cva.tsx │ │ │ └── full.tsx │ ├── e2e │ │ ├── scenarios │ │ │ ├── outfile │ │ │ │ ├── index.html │ │ │ │ ├── main.tsx │ │ │ │ ├── hello.tsx │ │ │ │ ├── vite.config.ts │ │ │ │ ├── panda.config.ts │ │ │ │ └── outfile.test.ts │ │ │ └── virtual-file │ │ │ │ ├── index.html │ │ │ │ ├── main.tsx │ │ │ │ ├── hello.tsx │ │ │ │ ├── vite.config.ts │ │ │ │ ├── panda.config.ts │ │ │ │ └── virtual-file.test.ts │ │ ├── package.json │ │ ├── tsconfig.json │ │ ├── test-elements.ts │ │ ├── test-utils.ts │ │ └── test-global-setup.ts │ ├── src │ │ ├── vite.ts │ │ ├── rollup.ts │ │ ├── rspack.ts │ │ ├── esbuild.ts │ │ ├── webpack.ts │ │ ├── plugin │ │ │ ├── ensure-absolute.ts │ │ │ ├── get-module-specifier-value.ts │ │ │ ├── get-cva-var-name.ts │ │ │ ├── unbox-combine-result.ts │ │ │ ├── has-macro-attribute.ts │ │ │ ├── cva-fns.ts │ │ │ └── get-import-declarations.ts │ │ ├── index.ts │ │ ├── astro.ts │ │ └── nuxt.ts │ ├── tsconfig.json │ ├── tsup.config.ts │ ├── playground │ │ ├── main.tsx │ │ ├── minimal.tsx │ │ ├── vite.config.ts │ │ ├── package.json │ │ ├── index.html │ │ ├── tsconfig.json │ │ ├── panda.config.ts │ │ └── App.tsx │ ├── vitest.config.e2e.ts │ ├── README.md │ ├── scripts │ │ └── postbuild.ts │ └── .gitignore ├── postcss-plugins │ ├── src │ │ ├── index.ts │ │ └── remove-unused-keyframes.ts │ ├── README.md │ ├── tsconfig.json │ ├── tsup.config.ts │ ├── CHANGELOG.md │ └── package.json ├── unplugin-panda-macro │ ├── __tests__ │ │ ├── env.d.ts │ │ ├── tsconfig.json │ │ └── samples │ │ │ ├── only-recipe.tsx │ │ │ ├── only-pattern.tsx │ │ │ ├── only-css-raw.tsx │ │ │ ├── only-css.tsx │ │ │ ├── only-styled.tsx │ │ │ ├── css-with-raw.tsx │ │ │ ├── only-cva.tsx │ │ │ └── full.tsx │ ├── src │ │ ├── vite.ts │ │ ├── esbuild.ts │ │ ├── rollup.ts │ │ ├── rspack.ts │ │ ├── webpack.ts │ │ ├── index.ts │ │ ├── plugin │ │ │ ├── get-module-specifier-value.ts │ │ │ ├── get-cva-var-name.ts │ │ │ ├── unbox-combine-result.ts │ │ │ ├── has-macro-attribute.ts │ │ │ ├── create-cva.ts │ │ │ ├── get-import-declarations.ts │ │ │ └── create-context.ts │ │ ├── astro.ts │ │ └── nuxt.ts │ ├── tsconfig.json │ ├── tsup.config.ts │ ├── playground │ │ ├── main.tsx │ │ ├── vite.config.ts │ │ ├── minimal.tsx │ │ ├── package.json │ │ ├── index.html │ │ ├── tsconfig.json │ │ ├── panda.config.ts │ │ └── App.tsx │ ├── scripts │ │ └── postbuild.ts │ ├── CHANGELOG.md │ └── .gitignore └── utils │ ├── src │ ├── index.ts │ ├── wrap-value.ts │ ├── assign-inline-vars.ts │ └── css-var.ts │ ├── tsconfig.json │ ├── tsup.config.ts │ ├── CHANGELOG.md │ ├── README.md │ ├── __tests__ │ └── assign-inline-vars.test.ts │ └── package.json ├── sandbox └── react │ ├── src │ ├── vite-env.d.ts │ ├── main.tsx │ ├── App.tsx │ └── index.css │ ├── postcss.config.cjs │ ├── vite.config.ts │ ├── tsconfig.node.json │ ├── .gitignore │ ├── index.html │ ├── tsconfig.json │ ├── package.json │ ├── panda.config.ts │ ├── README.md │ └── public │ └── vite.svg ├── examples ├── unplugin │ ├── src │ │ ├── vite-env.d.ts │ │ ├── main.tsx │ │ └── App.tsx │ ├── tsconfig.node.json │ ├── vite.config.ts │ ├── .gitignore │ ├── index.html │ ├── .eslintrc.cjs │ ├── tsconfig.json │ ├── package.json │ ├── README.md │ ├── public │ │ └── vite.svg │ └── panda.config.ts └── solid-start-unplugin │ ├── src │ ├── global.d.ts │ ├── entry-client.tsx │ ├── routes │ │ ├── about.tsx │ │ ├── index.tsx │ │ └── [...404].tsx │ ├── components │ │ ├── Counter.tsx │ │ ├── Counter.css │ │ └── App.tsx │ ├── app.tsx │ ├── entry-server.tsx │ └── app.css │ ├── public │ └── favicon.ico │ ├── .gitignore │ ├── app.config.ts │ ├── tsconfig.json │ ├── package.json │ ├── README.md │ └── panda.config.ts ├── .vscode ├── extensions.json └── settings.json ├── pnpm-workspace.yaml ├── website ├── vercel.json ├── env.d.ts ├── public │ ├── favicon.ico │ └── favicon.png ├── CHANGELOG.md ├── .gitignore ├── .prettierrc ├── app │ ├── components │ │ ├── input.tsx │ │ ├── twitter-icon.tsx │ │ ├── github-icon.tsx │ │ ├── icon-button.tsx │ │ └── switch.tsx │ ├── playground │ │ └── initial-input.ts │ ├── entry.client.tsx │ ├── root.tsx │ ├── routes │ │ └── styled2panda.tsx │ └── vite-themes │ │ └── vite-themes-types.ts ├── vite.config.ts ├── README.md ├── tsconfig.json ├── scripts │ └── bundle-types.mts └── package.json ├── .prettierrc ├── tsconfig.json ├── tsconfig.test.json ├── .changeset ├── config.json └── README.md ├── .gitignore ├── .npmrc ├── vitest.config.ts ├── tsconfig.build.json ├── package.json └── .github └── workflows └── publish.yml /packages/define-recipe/.gitignore: -------------------------------------------------------------------------------- 1 | trace-dir 2 | -------------------------------------------------------------------------------- /packages/define-theme/.gitignore: -------------------------------------------------------------------------------- 1 | trace-dir 2 | -------------------------------------------------------------------------------- /packages/presets/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './utopia' 2 | -------------------------------------------------------------------------------- /packages/prettier-plugin/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './plugin' 2 | -------------------------------------------------------------------------------- /packages/define-theme/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './define-theme' 2 | -------------------------------------------------------------------------------- /packages/fixtures/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './create-config-result' 2 | -------------------------------------------------------------------------------- /packages/panda-plugins/__tests__/scenarios/.gitignore: -------------------------------------------------------------------------------- 1 | styled-system-* 2 | -------------------------------------------------------------------------------- /sandbox/react/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /examples/unplugin/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["esbenp.prettier-vscode"] 3 | } 4 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - "packages/**" 3 | - "sandbox/*" 4 | - "website" 5 | -------------------------------------------------------------------------------- /website/vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "rewrites": [{ "source": "/(.*)", "destination": "/" }] 3 | } 4 | -------------------------------------------------------------------------------- /examples/solid-start-unplugin/src/global.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /website/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | -------------------------------------------------------------------------------- /website/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/astahmer/pandabox/HEAD/website/public/favicon.ico -------------------------------------------------------------------------------- /website/public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/astahmer/pandabox/HEAD/website/public/favicon.png -------------------------------------------------------------------------------- /packages/codemods/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './styled2panda' 2 | export * from './template-to-object-syntax' 3 | -------------------------------------------------------------------------------- /packages/define-recipe/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './define-recipe' 2 | export * from './define-slot-recipe' 3 | -------------------------------------------------------------------------------- /packages/define-theme/sandbox/preset-panda/borders.ts: -------------------------------------------------------------------------------- 1 | export const borders = { 2 | none: { value: 'none' }, 3 | } 4 | -------------------------------------------------------------------------------- /packages/unplugin/__tests__/env.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*?raw' { 2 | const src: string 3 | export default src 4 | } 5 | -------------------------------------------------------------------------------- /sandbox/react/postcss.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | '@pandacss/dev/postcss': {}, 4 | }, 5 | } -------------------------------------------------------------------------------- /packages/postcss-plugins/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './remove-unused-css-vars' 2 | export * from './remove-unused-keyframes' 3 | -------------------------------------------------------------------------------- /packages/unplugin/__tests__/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.test.json", 3 | "include": ["."] 4 | } 5 | -------------------------------------------------------------------------------- /packages/postcss-plugins/README.md: -------------------------------------------------------------------------------- 1 | # @pandabox/postcss-plugins 2 | 3 | - `removeUnusedCssVars` 4 | - `removeUnusedKeyframes` 5 | -------------------------------------------------------------------------------- /packages/unplugin-panda-macro/__tests__/env.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*?raw' { 2 | const src: string 3 | export default src 4 | } 5 | -------------------------------------------------------------------------------- /packages/unplugin/e2e/scenarios/outfile/index.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | -------------------------------------------------------------------------------- /packages/utils/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './assign-inline-vars' 2 | export * from './css-var' 3 | export * from './wrap-value' 4 | -------------------------------------------------------------------------------- /packages/unplugin-panda-macro/__tests__/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.test.json", 3 | "include": ["."] 4 | } 5 | -------------------------------------------------------------------------------- /packages/unplugin/e2e/scenarios/virtual-file/index.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | -------------------------------------------------------------------------------- /packages/prettier-plugin/__tests__/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.test.json", 3 | "include": [".", "../src"] 4 | } 5 | -------------------------------------------------------------------------------- /examples/solid-start-unplugin/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/astahmer/pandabox/HEAD/examples/solid-start-unplugin/public/favicon.ico -------------------------------------------------------------------------------- /website/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # website 2 | 3 | ## null 4 | 5 | ### Patch Changes 6 | 7 | - Updated dependencies [300266f] 8 | - @pandabox/codemods@0.0.1 9 | -------------------------------------------------------------------------------- /packages/codemods/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @pandabox/codemods 2 | 3 | ## 0.0.1 4 | 5 | ### Patch Changes 6 | 7 | - 300266f: bump versions & publish new packages 8 | -------------------------------------------------------------------------------- /website/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | 8 | ## Panda 9 | styled-system 10 | styled-system-studio -------------------------------------------------------------------------------- /packages/fixtures/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.build.json", 3 | "include": ["src"], 4 | "exclude": ["node_modules", "styled-system", "dist"] 5 | } 6 | -------------------------------------------------------------------------------- /packages/unplugin/src/vite.ts: -------------------------------------------------------------------------------- 1 | import { createVitePlugin } from 'unplugin' 2 | import { unpluginFactory } from './plugin/core' 3 | 4 | export default createVitePlugin(unpluginFactory) 5 | -------------------------------------------------------------------------------- /packages/unplugin/src/rollup.ts: -------------------------------------------------------------------------------- 1 | import { createRollupPlugin } from 'unplugin' 2 | import { unpluginFactory } from './plugin/core' 3 | 4 | export default createRollupPlugin(unpluginFactory) 5 | -------------------------------------------------------------------------------- /packages/unplugin/src/rspack.ts: -------------------------------------------------------------------------------- 1 | import { createRspackPlugin } from 'unplugin' 2 | import { unpluginFactory } from './plugin/core' 3 | 4 | export default createRspackPlugin(unpluginFactory) 5 | -------------------------------------------------------------------------------- /packages/define-theme/sandbox/preset-panda/breakpoints.ts: -------------------------------------------------------------------------------- 1 | export const breakpoints = { 2 | sm: '640px', 3 | md: '768px', 4 | lg: '1024px', 5 | xl: '1280px', 6 | '2xl': '1536px', 7 | } 8 | -------------------------------------------------------------------------------- /packages/prettier-plugin/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup' 2 | 3 | export default defineConfig({ 4 | entry: ['src/index.ts'], 5 | format: ['cjs'], 6 | clean: true, 7 | }) 8 | -------------------------------------------------------------------------------- /packages/unplugin/src/esbuild.ts: -------------------------------------------------------------------------------- 1 | import { createEsbuildPlugin } from 'unplugin' 2 | import { unpluginFactory } from './plugin/core' 3 | 4 | export default createEsbuildPlugin(unpluginFactory) 5 | -------------------------------------------------------------------------------- /packages/unplugin/src/webpack.ts: -------------------------------------------------------------------------------- 1 | import { createWebpackPlugin } from 'unplugin' 2 | import { unpluginFactory } from './plugin/core' 3 | 4 | export default createWebpackPlugin(unpluginFactory) 5 | -------------------------------------------------------------------------------- /packages/utils/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.build.json", 3 | "compilerOptions": { 4 | "noEmit": false, 5 | "outDir": "dist" 6 | }, 7 | "include": ["src"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/codemods/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.build.json", 3 | "compilerOptions": { 4 | "noEmit": false, 5 | "outDir": "dist" 6 | }, 7 | "include": ["src"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/presets/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.build.json", 3 | "compilerOptions": { 4 | "noEmit": false, 5 | "outDir": "dist" 6 | }, 7 | "include": ["src"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/unplugin-panda-macro/src/vite.ts: -------------------------------------------------------------------------------- 1 | import { createVitePlugin } from 'unplugin' 2 | import { unpluginFactory } from './plugin/core' 3 | 4 | export default createVitePlugin(unpluginFactory) 5 | -------------------------------------------------------------------------------- /packages/define-recipe/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.build.json", 3 | "compilerOptions": { 4 | "noEmit": false, 5 | "outDir": "dist" 6 | }, 7 | "include": ["src"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/panda-plugins/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.build.json", 3 | "compilerOptions": { 4 | "noEmit": false, 5 | "outDir": "dist" 6 | }, 7 | "include": ["src"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/postcss-plugins/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.build.json", 3 | "compilerOptions": { 4 | "noEmit": false, 5 | "outDir": "dist" 6 | }, 7 | "include": ["src"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/prettier-plugin/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.build.json", 3 | "compilerOptions": { 4 | "noEmit": false, 5 | "outDir": "dist" 6 | }, 7 | "include": ["src"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/unplugin-panda-macro/src/esbuild.ts: -------------------------------------------------------------------------------- 1 | import { createEsbuildPlugin } from 'unplugin' 2 | import { unpluginFactory } from './plugin/core' 3 | 4 | export default createEsbuildPlugin(unpluginFactory) 5 | -------------------------------------------------------------------------------- /packages/unplugin-panda-macro/src/rollup.ts: -------------------------------------------------------------------------------- 1 | import { createRollupPlugin } from 'unplugin' 2 | import { unpluginFactory } from './plugin/core' 3 | 4 | export default createRollupPlugin(unpluginFactory) 5 | -------------------------------------------------------------------------------- /packages/unplugin-panda-macro/src/rspack.ts: -------------------------------------------------------------------------------- 1 | import { createRspackPlugin } from 'unplugin' 2 | import { unpluginFactory } from './plugin/core' 3 | 4 | export default createRspackPlugin(unpluginFactory) 5 | -------------------------------------------------------------------------------- /packages/unplugin-panda-macro/src/webpack.ts: -------------------------------------------------------------------------------- 1 | import { createWebpackPlugin } from 'unplugin' 2 | import { unpluginFactory } from './plugin/core' 3 | 4 | export default createWebpackPlugin(unpluginFactory) 5 | -------------------------------------------------------------------------------- /examples/solid-start-unplugin/src/entry-client.tsx: -------------------------------------------------------------------------------- 1 | // @refresh reload 2 | import { mount, StartClient } from "@solidjs/start/client"; 3 | 4 | mount(() => , document.getElementById("app")!); 5 | -------------------------------------------------------------------------------- /packages/codemods/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup' 2 | 3 | export default defineConfig({ 4 | clean: true, 5 | entry: ['src/*.ts'], 6 | format: ['cjs', 'esm'], 7 | dts: true, 8 | }) 9 | -------------------------------------------------------------------------------- /packages/utils/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup' 2 | 3 | export default defineConfig({ 4 | clean: true, 5 | entry: ['src/index.ts'], 6 | format: ['cjs', 'esm'], 7 | dts: true, 8 | }) 9 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "printWidth": 120, 4 | "bracketSpacing": true, 5 | "jsxSingleQuote": false, 6 | "proseWrap": "always", 7 | "semi": false, 8 | "tabWidth": 2 9 | } 10 | -------------------------------------------------------------------------------- /packages/panda-plugins/__tests__/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.test.json", 3 | "compilerOptions": { 4 | "jsx": "react-jsx" 5 | }, 6 | "include": ["*", "../src", "./scenarios"] 7 | } 8 | -------------------------------------------------------------------------------- /packages/presets/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup' 2 | 3 | export default defineConfig({ 4 | clean: true, 5 | entry: ['src/index.ts'], 6 | format: ['cjs', 'esm'], 7 | dts: true, 8 | }) 9 | -------------------------------------------------------------------------------- /packages/define-recipe/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup' 2 | 3 | export default defineConfig({ 4 | clean: true, 5 | entry: ['src/index.ts'], 6 | format: ['cjs', 'esm'], 7 | dts: true, 8 | }) 9 | -------------------------------------------------------------------------------- /packages/define-theme/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup' 2 | 3 | export default defineConfig({ 4 | clean: true, 5 | entry: ['src/index.ts'], 6 | format: ['cjs', 'esm'], 7 | dts: true, 8 | }) 9 | -------------------------------------------------------------------------------- /packages/panda-plugins/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup' 2 | 3 | export default defineConfig({ 4 | clean: true, 5 | entry: ['src/index.ts'], 6 | format: ['cjs', 'esm'], 7 | dts: true, 8 | }) 9 | -------------------------------------------------------------------------------- /packages/postcss-plugins/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup' 2 | 3 | export default defineConfig({ 4 | clean: true, 5 | entry: ['src/index.ts'], 6 | format: ['cjs', 'esm'], 7 | dts: true, 8 | }) 9 | -------------------------------------------------------------------------------- /sandbox/react/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react-swc' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()], 7 | }) 8 | -------------------------------------------------------------------------------- /packages/unplugin/src/plugin/ensure-absolute.ts: -------------------------------------------------------------------------------- 1 | import { isAbsolute, resolve } from 'path' 2 | export const ensureAbsolute = (path: string, root: string) => 3 | path ? (isAbsolute(path) ? path : resolve(root, path)) : root 4 | -------------------------------------------------------------------------------- /packages/unplugin/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.build.json", 3 | "compilerOptions": { 4 | "noEmit": false, 5 | "outDir": "dist" 6 | }, 7 | "include": ["src"], 8 | "exclude": ["dist"] 9 | } 10 | -------------------------------------------------------------------------------- /packages/unplugin/src/index.ts: -------------------------------------------------------------------------------- 1 | import { createUnplugin } from 'unplugin' 2 | import { unpluginFactory } from './plugin/core' 3 | 4 | export const unplugin = /* #__PURE__ */ createUnplugin(unpluginFactory) 5 | 6 | export default unplugin 7 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.build.json", 3 | "include": ["packages/**/*.ts"], 4 | "exclude": ["node_modules", "styled-system", "dist"], 5 | "compilerOptions": { 6 | "customConditions": ["source"] 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/unplugin-panda-macro/src/index.ts: -------------------------------------------------------------------------------- 1 | import { createUnplugin } from 'unplugin' 2 | import { unpluginFactory } from './plugin/core' 3 | 4 | export const unplugin = /* #__PURE__ */ createUnplugin(unpluginFactory) 5 | 6 | export default unplugin 7 | -------------------------------------------------------------------------------- /examples/solid-start-unplugin/src/routes/about.tsx: -------------------------------------------------------------------------------- 1 | import { Title } from "@solidjs/meta"; 2 | 3 | export default function Home() { 4 | return ( 5 |
6 | About 7 |

About

8 |
9 | ); 10 | } 11 | -------------------------------------------------------------------------------- /packages/define-theme/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.build.json", 3 | "compilerOptions": { 4 | "noEmit": false, 5 | "outDir": "dist" 6 | }, 7 | "include": ["src"], 8 | "exclude": ["scripts/trace-report.ts"] 9 | } 10 | -------------------------------------------------------------------------------- /packages/unplugin/__tests__/samples/only-recipe.tsx: -------------------------------------------------------------------------------- 1 | import 'virtual:panda.css' 2 | import { button } from '../styled-system/recipes' 3 | 4 | export const App = () => { 5 | return
Button
6 | } 7 | -------------------------------------------------------------------------------- /packages/unplugin/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import type { Options } from 'tsup' 2 | 3 | export default { 4 | entryPoints: ['src/*.ts'], 5 | clean: true, 6 | format: ['cjs', 'esm'], 7 | dts: true, 8 | onSuccess: 'npm run build:fix', 9 | } 10 | -------------------------------------------------------------------------------- /packages/unplugin-panda-macro/__tests__/samples/only-recipe.tsx: -------------------------------------------------------------------------------- 1 | import 'virtual:panda.css' 2 | import { button } from '../styled-system/recipes' 3 | 4 | export const App = () => { 5 | return
Button
6 | } 7 | -------------------------------------------------------------------------------- /packages/unplugin-panda-macro/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.build.json", 3 | "compilerOptions": { 4 | "noEmit": false, 5 | "outDir": "dist" 6 | }, 7 | "include": ["src"], 8 | "exclude": ["dist", "__tests__/samples"] 9 | } 10 | -------------------------------------------------------------------------------- /packages/unplugin-panda-macro/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import type { Options } from 'tsup' 2 | 3 | export default { 4 | entryPoints: ['src/*.ts'], 5 | clean: true, 6 | format: ['cjs', 'esm'], 7 | dts: true, 8 | onSuccess: 'npm run build:fix', 9 | } 10 | -------------------------------------------------------------------------------- /website/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "printWidth": 120, 4 | "bracketSpacing": true, 5 | "jsxSingleQuote": false, 6 | "proseWrap": "always", 7 | "semi": false, 8 | "tabWidth": 2, 9 | "plugins": ["@pandabox/prettier-plugin"] 10 | } 11 | -------------------------------------------------------------------------------- /tsconfig.test.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.build.json", 3 | "compilerOptions": { 4 | "paths": { 5 | "#pandabox/fixtures": ["./packages/fixtures/src/index.ts"] 6 | } 7 | }, 8 | "exclude": ["node_modules", "styled-system", "dist"] 9 | } 10 | -------------------------------------------------------------------------------- /packages/define-theme/sandbox/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.test.json", 3 | "compilerOptions": { 4 | "declaration": false 5 | }, 6 | "include": ["./*.ts", "./preset-base", "./preset-panda"], 7 | "exclude": ["node_modules", "styled-system", "dist"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/unplugin/src/plugin/get-module-specifier-value.ts: -------------------------------------------------------------------------------- 1 | import type { ImportDeclaration } from 'ts-morph' 2 | 3 | export const getModuleSpecifierValue = (node: ImportDeclaration) => { 4 | try { 5 | return node.getModuleSpecifierValue() 6 | } catch { 7 | return 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /examples/unplugin/src/main.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import { App } from './App.tsx' 4 | 5 | ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( 6 | 7 | 8 | , 9 | ) 10 | -------------------------------------------------------------------------------- /packages/unplugin/src/plugin/get-cva-var-name.ts: -------------------------------------------------------------------------------- 1 | import { Node } from 'ts-morph' 2 | 3 | export const getVariableName = (node: Node) => { 4 | const parent = node.getParent() 5 | if (!Node.isVariableDeclaration(parent)) return 6 | 7 | const name = parent.getName() 8 | return name 9 | } 10 | -------------------------------------------------------------------------------- /sandbox/react/src/main.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import App from './App.tsx' 4 | import './index.css' 5 | 6 | ReactDOM.createRoot(document.getElementById('root')!).render( 7 | 8 | 9 | , 10 | ) 11 | -------------------------------------------------------------------------------- /packages/define-theme/sandbox/preset-panda/aspect-ratios.ts: -------------------------------------------------------------------------------- 1 | export const aspectRatios = { 2 | square: { value: '1 / 1' }, 3 | landscape: { value: '4 / 3' }, 4 | portrait: { value: '3 / 4' }, 5 | wide: { value: '16 / 9' }, 6 | ultrawide: { value: '18 / 5' }, 7 | golden: { value: '1.618 / 1' }, 8 | } 9 | -------------------------------------------------------------------------------- /packages/unplugin-panda-macro/src/plugin/get-module-specifier-value.ts: -------------------------------------------------------------------------------- 1 | import type { ImportDeclaration } from 'ts-morph' 2 | 3 | export const getModuleSpecifierValue = (node: ImportDeclaration) => { 4 | try { 5 | return node.getModuleSpecifierValue() 6 | } catch { 7 | return 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/unplugin/playground/main.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import { App } from './App.tsx' 4 | 5 | ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( 6 | 7 | 8 | , 9 | ) 10 | -------------------------------------------------------------------------------- /packages/unplugin-panda-macro/src/plugin/get-cva-var-name.ts: -------------------------------------------------------------------------------- 1 | import { Node } from 'ts-morph' 2 | 3 | export const getVariableName = (node: Node) => { 4 | const parent = node.getParent() 5 | if (!Node.isVariableDeclaration(parent)) return 6 | 7 | const name = parent.getName() 8 | return name 9 | } 10 | -------------------------------------------------------------------------------- /packages/unplugin/__tests__/samples/only-pattern.tsx: -------------------------------------------------------------------------------- 1 | import { center } from '../styled-system/patterns' 2 | 3 | import 'virtual:panda.css' 4 | 5 | export const App = () => { 6 | return ( 7 |
8 | Hello from Panda 9 |
10 | ) 11 | } 12 | -------------------------------------------------------------------------------- /sandbox/react/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "module": "ESNext", 6 | "moduleResolution": "bundler", 7 | "allowSyntheticDefaultImports": true, 8 | "strict": true 9 | }, 10 | "include": ["vite.config.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": true, 3 | "editor.defaultFormatter": "esbenp.prettier-vscode", 4 | "[typescript]": { 5 | "editor.defaultFormatter": "esbenp.prettier-vscode" 6 | }, 7 | "[typescriptreact]": { 8 | "editor.defaultFormatter": "esbenp.prettier-vscode" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /examples/unplugin/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "module": "ESNext", 6 | "moduleResolution": "bundler", 7 | "allowSyntheticDefaultImports": true, 8 | "strict": true 9 | }, 10 | "include": ["vite.config.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /packages/define-recipe/tsconfig.bench.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": ["dom", "dom.iterable", "esnext"], 4 | "target": "esnext", 5 | "moduleResolution": "Bundler", 6 | "module": "ESNext", 7 | "noEmit": true, 8 | "skipLibCheck": true 9 | }, 10 | "include": ["src"] 11 | } 12 | -------------------------------------------------------------------------------- /packages/unplugin-panda-macro/playground/main.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import { App } from './App.tsx' 4 | 5 | ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( 6 | 7 | 8 | , 9 | ) 10 | -------------------------------------------------------------------------------- /packages/unplugin/vitest.config.e2e.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vitest/config' 2 | 3 | export default defineConfig({ 4 | root: process.cwd(), 5 | test: { 6 | hideSkippedTests: true, 7 | setupFiles: ['./e2e/test-setup.ts'], 8 | globalSetup: ['./e2e/test-global-setup.ts'], 9 | }, 10 | }) 11 | -------------------------------------------------------------------------------- /packages/unplugin/e2e/scenarios/outfile/main.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import { App } from './hello.tsx' 4 | 5 | ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( 6 | 7 | 8 | , 9 | ) 10 | -------------------------------------------------------------------------------- /packages/unplugin-panda-macro/__tests__/samples/only-pattern.tsx: -------------------------------------------------------------------------------- 1 | import { center } from '../styled-system/patterns' 2 | 3 | import 'virtual:panda.css' 4 | 5 | export const App = () => { 6 | return ( 7 |
8 | Hello from Panda 9 |
10 | ) 11 | } 12 | -------------------------------------------------------------------------------- /packages/unplugin/e2e/scenarios/virtual-file/main.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import { App } from './hello.tsx' 4 | 5 | ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( 6 | 7 | 8 | , 9 | ) 10 | -------------------------------------------------------------------------------- /packages/panda-plugins/__tests__/scenarios/missing-css-warnings.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from '@pandacss/dev' 2 | import { pluginMissingCssWarnings } from '../../src/missing-css-warnings' 3 | 4 | export default defineConfig({ 5 | plugins: [pluginMissingCssWarnings()], 6 | outdir: 'styled-system-missing-css-warnings', 7 | }) 8 | -------------------------------------------------------------------------------- /packages/unplugin-panda-macro/playground/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import Inspect from 'vite-plugin-inspect' 3 | import react from '@vitejs/plugin-react-swc' 4 | import panda from '../dist/vite' 5 | 6 | export default defineConfig({ 7 | plugins: [Inspect(), panda({ output: 'atomic' }), react()], 8 | }) 9 | -------------------------------------------------------------------------------- /website/app/components/input.tsx: -------------------------------------------------------------------------------- 1 | import { ark } from '@ark-ui/react/factory' 2 | import type { ComponentProps } from 'react' 3 | import { styled } from '#styled-system/jsx' 4 | import { input } from '#styled-system/recipes' 5 | 6 | export const Input = styled(ark.input, input) 7 | export type InputProps = ComponentProps 8 | -------------------------------------------------------------------------------- /packages/prettier-plugin/__tests__/panda.config.ts: -------------------------------------------------------------------------------- 1 | // import { defineConfig } from '@pandacss/dev' 2 | 3 | // export default defineConfig({ 4 | export default { 5 | preflight: true, 6 | include: ['./src/**/*.{tsx,jsx}', './pages/**/*.{jsx,tsx}'], 7 | exclude: [], 8 | outdir: 'styled-system', 9 | jsxFramework: 'react', 10 | } 11 | -------------------------------------------------------------------------------- /packages/unplugin/src/plugin/unbox-combine-result.ts: -------------------------------------------------------------------------------- 1 | import type { Unboxed } from '@pandacss/extractor' 2 | 3 | export const combineResult = (unboxed: Unboxed) => { 4 | return [...unboxed.conditions, unboxed.raw, ...unboxed.spreadConditions] as LiteralObject[] 5 | } 6 | 7 | interface LiteralObject { 8 | [key: string]: any 9 | } 10 | -------------------------------------------------------------------------------- /packages/define-recipe/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @pandabox/define-recipe 2 | 3 | ## 0.0.3 4 | 5 | ### Patch Changes 6 | 7 | - 25fed76: Update to panda 0.36.1 8 | 9 | ## 0.0.2 10 | 11 | ### Patch Changes 12 | 13 | - 300266f: bump versions & publish new packages 14 | 15 | ## 0.0.1 16 | 17 | ### Patch Changes 18 | 19 | - f624d43: Initial release 20 | -------------------------------------------------------------------------------- /packages/define-theme/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @pandabox/define-theme 2 | 3 | ## 0.0.4 4 | 5 | ### Patch Changes 6 | 7 | - 25fed76: Update to panda 0.36.1 8 | 9 | ## 0.0.3 10 | 11 | ### Patch Changes 12 | 13 | - 300266f: bump versions & publish new packages 14 | 15 | ## 0.0.2 16 | 17 | ### Patch Changes 18 | 19 | - f624d43: Initial release 20 | -------------------------------------------------------------------------------- /packages/panda-plugins/__tests__/scenarios/remove-negative-spacing.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from '@pandacss/dev' 2 | import { pluginRemoveNegativeSpacing } from '../../src/remove-negative-spacing' 3 | 4 | export default defineConfig({ 5 | plugins: [pluginRemoveNegativeSpacing()], 6 | outdir: 'styled-system-remove-negative-spacing', 7 | }) 8 | -------------------------------------------------------------------------------- /packages/panda-plugins/__tests__/scenarios/restrict-styled-props.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from '@pandacss/dev' 2 | import { pluginRestrictStyledProps } from '../../src' 3 | 4 | export default defineConfig({ 5 | plugins: [pluginRestrictStyledProps()], 6 | outdir: 'styled-system-restrict-styled-props', 7 | jsxFramework: 'react', 8 | }) 9 | -------------------------------------------------------------------------------- /packages/unplugin-panda-macro/src/plugin/unbox-combine-result.ts: -------------------------------------------------------------------------------- 1 | import { type Unboxed } from '@pandacss/extractor' 2 | 3 | export const combineResult = (unboxed: Unboxed) => { 4 | return [...unboxed.conditions, unboxed.raw, ...unboxed.spreadConditions] as LiteralObject[] 5 | } 6 | 7 | interface LiteralObject { 8 | [key: string]: any 9 | } 10 | -------------------------------------------------------------------------------- /packages/panda-plugins/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './minimal-setup' 2 | export * from './missing-css-warnings' 3 | export * from './remove-features' 4 | export * from './remove-negative-spacing' 5 | export * from './remove-unused-css' 6 | export * from './restrict-styled-props' 7 | export * from './strict-tokens-runtime' 8 | export * from './strict-tokens-scope' 9 | -------------------------------------------------------------------------------- /packages/unplugin/e2e/scenarios/outfile/hello.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { css } from './styled-system/css' 3 | import './panda.css' 4 | 5 | export const App = () => { 6 | return ( 7 | <> 8 |
9 | Hello from Panda 10 |
11 | 12 | ) 13 | } 14 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json", 3 | "changelog": "@changesets/cli/changelog", 4 | "commit": false, 5 | "fixed": [], 6 | "linked": [], 7 | "access": "restricted", 8 | "baseBranch": "main", 9 | "updateInternalDependencies": "patch", 10 | "ignore": ["sandbox-*", "website"] 11 | } 12 | -------------------------------------------------------------------------------- /packages/panda-plugins/__tests__/scenarios/strict-tokens-scope.test.ts: -------------------------------------------------------------------------------- 1 | import { test } from 'vitest' 2 | import { css } from './styled-system-strict-tokens-scope/css' 3 | 4 | test('runtime', () => { 5 | css({ 6 | // @ts-expect-error 7 | color: '#fff', 8 | fontSize: '123px', 9 | // @ts-expect-error 10 | margin: '-5px', 11 | }) 12 | }) 13 | -------------------------------------------------------------------------------- /packages/unplugin/e2e/scenarios/virtual-file/hello.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { css } from './styled-system/css' 3 | import 'virtual:panda.css' 4 | 5 | export const App = () => { 6 | return ( 7 | <> 8 |
9 | Hello from Panda 10 |
11 | 12 | ) 13 | } 14 | -------------------------------------------------------------------------------- /packages/unplugin/playground/minimal.tsx: -------------------------------------------------------------------------------- 1 | import { css } from './styled-system/css' 2 | import 'virtual:panda.css' 3 | 4 | export const App = () => { 5 | return ( 6 | <> 7 |
12 | Hello from Panda 13 |
14 | 15 | ) 16 | } 17 | -------------------------------------------------------------------------------- /examples/solid-start-unplugin/src/components/Counter.tsx: -------------------------------------------------------------------------------- 1 | import { createSignal } from "solid-js"; 2 | import "./Counter.css"; 3 | 4 | export default function Counter() { 5 | const [count, setCount] = createSignal(0); 6 | return ( 7 | 10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /packages/panda-plugins/__tests__/scenarios/remove-negative-spacing.test.ts: -------------------------------------------------------------------------------- 1 | import { expectTypeOf, test } from 'vitest' 2 | import type { SpacingToken } from './styled-system-remove-negative-spacing/tokens' 3 | 4 | type ContainsNegative = `-${string}` extends SpacingToken ? true : false 5 | 6 | test('runtime', () => { 7 | expectTypeOf().toMatchTypeOf() 8 | }) 9 | -------------------------------------------------------------------------------- /packages/unplugin/e2e/scenarios/virtual-file/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | // import Inspect from 'vite-plugin-inspect' 3 | // import react from '@vitejs/plugin-react-swc' 4 | import panda from '../../../dist/vite' 5 | 6 | export default defineConfig({ 7 | plugins: [ 8 | // Inspect(), 9 | panda({}), 10 | // react(), 11 | ], 12 | }) 13 | -------------------------------------------------------------------------------- /packages/unplugin-panda-macro/playground/minimal.tsx: -------------------------------------------------------------------------------- 1 | import { css } from './styled-system/css' 2 | import 'virtual:panda.css' 3 | 4 | export const App = () => { 5 | return ( 6 | <> 7 |
12 | Hello from Panda 13 |
14 | 15 | ) 16 | } 17 | -------------------------------------------------------------------------------- /packages/panda-plugins/__tests__/scenarios/strict-tokens-scope.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from '@pandacss/dev' 2 | import { pluginStrictTokensScope } from '../../src/strict-tokens-scope' 3 | 4 | export default defineConfig({ 5 | plugins: [pluginStrictTokensScope({ categories: ['colors', 'spacing'] })], 6 | strictTokens: true, 7 | outdir: 'styled-system-strict-tokens-scope', 8 | }) 9 | -------------------------------------------------------------------------------- /packages/unplugin/playground/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import Inspect from 'vite-plugin-inspect' 3 | import react from '@vitejs/plugin-react-swc' 4 | import panda from '../dist/vite' 5 | 6 | export default defineConfig({ 7 | plugins: [ 8 | Inspect(), 9 | panda({ 10 | outfile: './panda.css', 11 | }), 12 | react(), 13 | ], 14 | }) 15 | -------------------------------------------------------------------------------- /packages/utils/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @pandabox/utils 2 | 3 | ## 0.0.5 4 | 5 | ### Patch Changes 6 | 7 | - 25fed76: Update to panda 0.36.1 8 | 9 | ## 0.0.4 10 | 11 | ### Patch Changes 12 | 13 | - 9b66e69: Fix `assignInlineVars` return, use `--xxx` as keys instead of `var(--xxx)` 14 | 15 | ## 0.0.3 16 | 17 | ### Patch Changes 18 | 19 | - 300266f: bump versions & publish new packages 20 | -------------------------------------------------------------------------------- /examples/unplugin/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import Inspect from 'vite-plugin-inspect' 3 | import react from '@vitejs/plugin-react-swc' 4 | import pandabox from '@pandabox/unplugin' 5 | 6 | export default defineConfig({ 7 | plugins: [ 8 | Inspect(), 9 | pandabox.vite({ 10 | outfile: './src/panda.css', 11 | }), 12 | react(), 13 | ], 14 | }) 15 | -------------------------------------------------------------------------------- /packages/define-theme/sandbox/preset-base/utilities/list.ts: -------------------------------------------------------------------------------- 1 | import type { UtilityConfig } from '@pandacss/types' 2 | 3 | export const list = { 4 | listStyleType: { 5 | className: 'list', 6 | }, 7 | listStylePosition: { 8 | className: 'list', 9 | }, 10 | listStyleImage: { 11 | className: 'list-img', 12 | values: 'assets', 13 | }, 14 | } as const satisfies UtilityConfig 15 | -------------------------------------------------------------------------------- /packages/panda-plugins/__tests__/scenarios/strict-tokens-runtime.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from '@pandacss/dev' 2 | import { pluginStrictTokensRuntime } from '../../src/strict-tokens-runtime' 3 | 4 | export default defineConfig({ 5 | plugins: [pluginStrictTokensRuntime({ categories: ['colors', 'spacing'] })], 6 | strictTokens: true, 7 | outdir: 'styled-system-strict-tokens-runtime', 8 | }) 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # build output 2 | dist/ 3 | 4 | # generated types 5 | .astro/ 6 | 7 | # dependencies 8 | node_modules/ 9 | 10 | # logs 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | pnpm-debug.log* 15 | 16 | # environment variables 17 | .env 18 | .env.production 19 | 20 | # macOS-specific files 21 | .DS_Store 22 | styled-system 23 | .vercel 24 | .turbo 25 | scenarios-temp 26 | panda.css 27 | -------------------------------------------------------------------------------- /packages/unplugin/src/astro.ts: -------------------------------------------------------------------------------- 1 | import unplugin from '.' 2 | import type { PandaPluginOptions } from './plugin/core' 3 | 4 | export default (options: PandaPluginOptions) => ({ 5 | name: 'unplugin-starter', 6 | hooks: { 7 | 'astro:config:setup': async (astro: any) => { 8 | astro.config.vite.plugins ||= [] 9 | astro.config.vite.plugins.push(unplugin.vite(options)) 10 | }, 11 | }, 12 | }) 13 | -------------------------------------------------------------------------------- /packages/unplugin-panda-macro/src/astro.ts: -------------------------------------------------------------------------------- 1 | import unplugin from '.' 2 | import type { PluginOptions } from './plugin/core' 3 | 4 | export default (options: PluginOptions) => ({ 5 | name: 'unplugin-starter', 6 | hooks: { 7 | 'astro:config:setup': async (astro: any) => { 8 | astro.config.vite.plugins ||= [] 9 | astro.config.vite.plugins.push(unplugin.vite(options)) 10 | }, 11 | }, 12 | }) 13 | -------------------------------------------------------------------------------- /packages/unplugin/e2e/scenarios/outfile/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | // import Inspect from 'vite-plugin-inspect' 3 | // import react from '@vitejs/plugin-react-swc' 4 | import panda from '../../../dist/vite' 5 | 6 | export default defineConfig({ 7 | plugins: [ 8 | // Inspect(), 9 | panda({ 10 | outfile: './panda.css', 11 | }), 12 | // react(), 13 | ], 14 | }) 15 | -------------------------------------------------------------------------------- /packages/define-theme/sandbox/preset-base/utilities/svg.ts: -------------------------------------------------------------------------------- 1 | import type { UtilityConfig } from '@pandacss/types' 2 | 3 | export const svg = { 4 | fill: { 5 | className: 'fill', 6 | values: 'colors', 7 | }, 8 | stroke: { 9 | className: 'stroke', 10 | values: 'colors', 11 | }, 12 | strokeWidth: { 13 | className: 'stroke-w', 14 | values: 'borderWidths', 15 | }, 16 | } as const satisfies UtilityConfig 17 | -------------------------------------------------------------------------------- /packages/fixtures/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@pandabox/fixtures", 3 | "private": true, 4 | "exports": { 5 | ".": "./src/index.ts" 6 | }, 7 | "devDependencies": { 8 | "@pandacss/config": "^0.36.1", 9 | "@pandacss/node": "^0.36.1", 10 | "@pandacss/preset-base": "^0.36.1", 11 | "@pandacss/preset-panda": "^0.36.1", 12 | "@pandacss/shared": "^0.36.1", 13 | "@pandacss/types": "^0.36.1" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/define-theme/sandbox/preset-base/index.ts: -------------------------------------------------------------------------------- 1 | import type { Preset } from '@pandacss/types' 2 | 3 | import { conditions } from './conditions' 4 | import { utilities } from './utilities' 5 | import { patterns } from './patterns' 6 | 7 | const definePreset = (preset: T) => preset 8 | 9 | export const preset = definePreset({ 10 | conditions, 11 | utilities, 12 | patterns, 13 | }) 14 | 15 | export default preset 16 | -------------------------------------------------------------------------------- /sandbox/react/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | 26 | ## Panda 27 | styled-system 28 | styled-system-studio -------------------------------------------------------------------------------- /sandbox/react/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + React + TS 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | ignore-workspace-root-check=true 2 | strict-peer-dependencies=false 3 | auto-install-peers=true 4 | # 5 | link-workspace-packages=false 6 | prefer-workspace-packages=true 7 | # 8 | hoist-pattern[]=@arktype/attest 9 | hoist-pattern[]=*@pandacss/* 10 | hoist-pattern[]=prettier 11 | hoist-pattern[]=vitest 12 | hoist-pattern[]=tsx 13 | hoist-pattern[]=typescript 14 | hoist-pattern[]=@types/react 15 | hoist-pattern[]=@types/react-dom 16 | 17 | -------------------------------------------------------------------------------- /examples/unplugin/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | 26 | ## Panda 27 | styled-system 28 | styled-system-studio -------------------------------------------------------------------------------- /examples/unplugin/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + React + TS 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/solid-start-unplugin/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | dist 3 | .solid 4 | .output 5 | .vercel 6 | .netlify 7 | netlify 8 | .vinxi 9 | 10 | # Environment 11 | .env 12 | .env*.local 13 | 14 | # dependencies 15 | /node_modules 16 | 17 | # IDEs and editors 18 | /.idea 19 | .project 20 | .classpath 21 | *.launch 22 | .settings/ 23 | 24 | # Temp 25 | gitignore 26 | 27 | # System Files 28 | .DS_Store 29 | Thumbs.db 30 | 31 | ## Panda 32 | styled-system 33 | styled-system-studio -------------------------------------------------------------------------------- /packages/unplugin/__tests__/samples/only-css-raw.tsx: -------------------------------------------------------------------------------- 1 | import 'virtual:panda.css' 2 | import { css } from '../styled-system/css' 3 | 4 | const styles = css.raw({ 5 | display: 'flex', 6 | flexDirection: 'column', 7 | fontWeight: 'semibold', 8 | color: 'green.300', 9 | textAlign: 'center', 10 | textStyle: '4xl', 11 | }) 12 | 13 | export const App = () => { 14 | return ( 15 |
16 | Hello from Panda 17 |
18 | ) 19 | } 20 | -------------------------------------------------------------------------------- /packages/fixtures/src/utils.ts: -------------------------------------------------------------------------------- 1 | import { traverse } from '@pandacss/shared' 2 | 3 | const omit = (obj: T, paths: K[]): Omit => { 4 | const result = { ...obj } 5 | 6 | traverse(result, ({ path, parent, key }) => { 7 | if (paths.includes(path as K)) { 8 | delete (parent as any)[key] 9 | } 10 | }) 11 | 12 | return result as Omit 13 | } 14 | 15 | export const utils = { 16 | omit, 17 | traverse, 18 | } 19 | -------------------------------------------------------------------------------- /packages/unplugin-panda-macro/__tests__/samples/only-css-raw.tsx: -------------------------------------------------------------------------------- 1 | import 'virtual:panda.css' 2 | import { css } from '../styled-system/css' 3 | 4 | const styles = css.raw({ 5 | display: 'flex', 6 | flexDirection: 'column', 7 | fontWeight: 'semibold', 8 | color: 'green.300', 9 | textAlign: 'center', 10 | textStyle: '4xl', 11 | }) 12 | 13 | export const App = () => { 14 | return ( 15 |
16 | Hello from Panda 17 |
18 | ) 19 | } 20 | -------------------------------------------------------------------------------- /website/app/playground/initial-input.ts: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components' 2 | 3 | const Link = styled.a` 4 | background: papayawhip; 5 | color: #bf4f74; 6 | ` 7 | 8 | const Icon = styled.svg` 9 | width: 48px; 10 | height: 48px; 11 | 12 | ${Link}:hover & { 13 | fill: rebeccapurple; 14 | } 15 | ` 16 | 17 | const TomatoButton = styled(Link)` 18 | color: tomato; 19 | border-color: tomato; 20 | ` 21 | 22 | const Thingy = styled('div')` 23 | font-size: 1.5em; 24 | ` 25 | -------------------------------------------------------------------------------- /packages/presets/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @pandabox/presets 2 | 3 | ## 0.0.2 4 | 5 | ### Patch Changes 6 | 7 | - 25fed76: Update to panda 0.36.1 8 | 9 | ## 0.0.1 10 | 11 | ### Patch Changes 12 | 13 | - 91b4f3a: Add `@pandabox/presets` with `createUtopia`, see https://utopia.fyi/ 14 | 15 | BREAKING: Update `@pandabox/postcss-plugins` `removeUnusedCssVars` API to directly return a postcss plugin 16 | 17 | Add `pluginRemoveUnusedCss` to `@pandabox/panda-plugins` that uses `@pandabox/postcss-plugins` 18 | -------------------------------------------------------------------------------- /examples/solid-start-unplugin/app.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from '@solidjs/start/config' 2 | import pandabox from '@pandabox/unplugin' 3 | 4 | const isDev = process.env.NODE_ENV === 'development' 5 | 6 | export default defineConfig({ 7 | // middleware: './src/middleware.ts', 8 | // server: { 9 | // preset: 'cloudflare-module', 10 | // }, 11 | vite: { 12 | plugins: [ 13 | pandabox.vite({ 14 | optimizeCss: !isDev, 15 | }), 16 | ], 17 | }, 18 | }) 19 | -------------------------------------------------------------------------------- /packages/postcss-plugins/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @pandabox/postcss-plugins 2 | 3 | ## 0.0.2 4 | 5 | ### Patch Changes 6 | 7 | - 91b4f3a: Add `@pandabox/presets` with `createUtopia`, see https://utopia.fyi/ 8 | 9 | BREAKING: Update `@pandabox/postcss-plugins` `removeUnusedCssVars` API to directly return a postcss plugin 10 | 11 | Add `pluginRemoveUnusedCss` to `@pandabox/panda-plugins` that uses `@pandabox/postcss-plugins` 12 | 13 | ## 0.0.1 14 | 15 | ### Patch Changes 16 | 17 | - ed8bfb4: initial release 18 | -------------------------------------------------------------------------------- /packages/unplugin/__tests__/samples/only-css.tsx: -------------------------------------------------------------------------------- 1 | import 'virtual:panda.css' 2 | import { css } from '../styled-system/css' 3 | 4 | export const App = () => { 5 | return ( 6 |
16 | Hello from Panda 17 |
18 | ) 19 | } 20 | -------------------------------------------------------------------------------- /examples/solid-start-unplugin/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "module": "ESNext", 5 | "moduleResolution": "node", 6 | "allowSyntheticDefaultImports": true, 7 | "esModuleInterop": true, 8 | "jsx": "preserve", 9 | "jsxImportSource": "solid-js", 10 | "allowJs": true, 11 | "strict": true, 12 | "noEmit": true, 13 | "types": ["vinxi/client", "vite/client"], 14 | "isolatedModules": true, 15 | "paths": { 16 | "~/*": ["./src/*"] 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/utils/src/wrap-value.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Recursively wraps each value in a { value: xxx } object 3 | */ 4 | export const wrapValue = (obj: Record) => { 5 | const newObj: Record = {} 6 | 7 | for (const key in obj) { 8 | if (typeof obj[key] === 'object' && !Array.isArray(obj[key])) { 9 | newObj[key] = wrapValue(obj[key]) // Recursive call for nested objects 10 | } else { 11 | newObj[key] = { value: obj[key] } 12 | } 13 | } 14 | 15 | return newObj 16 | } 17 | -------------------------------------------------------------------------------- /packages/define-recipe/src/type-helpers.ts: -------------------------------------------------------------------------------- 1 | type Pick_ = Pick> 2 | type Omit_ = Omit> 3 | 4 | export type DistributivePick = T extends unknown 5 | ? keyof Pick_ extends never 6 | ? never 7 | : { [P in keyof Pick_]: Pick_[P] } 8 | : never 9 | 10 | export type DistributiveOmit = T extends unknown 11 | ? keyof Omit_ extends never 12 | ? never 13 | : { [P in keyof Omit_]: Omit_[P] } 14 | : never 15 | -------------------------------------------------------------------------------- /packages/unplugin-panda-macro/__tests__/samples/only-css.tsx: -------------------------------------------------------------------------------- 1 | import 'virtual:panda.css' 2 | import { css } from '../styled-system/css' 3 | 4 | export const App = () => { 5 | return ( 6 |
16 | Hello from Panda 17 |
18 | ) 19 | } 20 | -------------------------------------------------------------------------------- /website/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { vitePlugin as remix } from '@remix-run/dev' 2 | import { installGlobals } from '@remix-run/node' 3 | import { defineConfig } from 'vite' 4 | import Inspect from 'vite-plugin-inspect' 5 | // import panda from '@pandabox/unplugin-panda-macro/vite' 6 | 7 | installGlobals() 8 | 9 | export default defineConfig({ 10 | plugins: [ 11 | Inspect(), 12 | // panda({ output: 'atomic' }), 13 | remix({ ssr: false }), 14 | ], 15 | resolve: { 16 | conditions: ['source'], 17 | }, 18 | }) 19 | -------------------------------------------------------------------------------- /examples/solid-start-unplugin/src/components/Counter.css: -------------------------------------------------------------------------------- 1 | .increment { 2 | font-family: inherit; 3 | font-size: inherit; 4 | padding: 1em 2em; 5 | color: #335d92; 6 | background-color: rgba(68, 107, 158, 0.1); 7 | border-radius: 2em; 8 | border: 2px solid rgba(68, 107, 158, 0); 9 | outline: none; 10 | width: 200px; 11 | font-variant-numeric: tabular-nums; 12 | } 13 | 14 | .increment:focus { 15 | border: 2px solid #335d92; 16 | } 17 | 18 | .increment:active { 19 | background-color: rgba(68, 107, 158, 0.2); 20 | } -------------------------------------------------------------------------------- /packages/define-theme/sandbox/preset-panda/index.ts: -------------------------------------------------------------------------------- 1 | import type { Preset } from '@pandacss/types' 2 | import { breakpoints } from './breakpoints' 3 | import { keyframes } from './keyframes' 4 | import { tokens } from './tokens' 5 | import { textStyles } from './typography' 6 | 7 | const definePreset = (config: T) => config 8 | 9 | export const preset = definePreset({ 10 | theme: { 11 | keyframes, 12 | breakpoints, 13 | tokens, 14 | textStyles, 15 | }, 16 | }) 17 | 18 | export default preset 19 | -------------------------------------------------------------------------------- /vitest.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vitest/config' 2 | 3 | export default defineConfig({ 4 | root: process.cwd(), 5 | test: { 6 | hideSkippedTests: true, 7 | exclude: [ 8 | '**/node_modules/**', 9 | '**/dist/**', 10 | '**/cypress/**', 11 | '**/.{idea,git,cache,output,temp}/**', 12 | '**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build}.config.*', 13 | ].concat(['./packages/panda-plugins/__tests__/scenarios', './packages/unplugin/e2e']), 14 | }, 15 | }) 16 | -------------------------------------------------------------------------------- /examples/unplugin/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { browser: true, es2020: true }, 4 | extends: [ 5 | 'eslint:recommended', 6 | 'plugin:@typescript-eslint/recommended', 7 | 'plugin:react-hooks/recommended', 8 | ], 9 | ignorePatterns: ['dist', '.eslintrc.cjs'], 10 | parser: '@typescript-eslint/parser', 11 | plugins: ['react-refresh'], 12 | rules: { 13 | 'react-refresh/only-export-components': [ 14 | 'warn', 15 | { allowConstantExport: true }, 16 | ], 17 | }, 18 | } 19 | -------------------------------------------------------------------------------- /.changeset/README.md: -------------------------------------------------------------------------------- 1 | # Changesets 2 | 3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works 4 | with multi-package repos, or single-package repos to help you version and publish your code. You can 5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets) 6 | 7 | We have a quick list of common questions to get you started engaging with this project in 8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) 9 | -------------------------------------------------------------------------------- /packages/define-theme/tsconfig.bench.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": ["dom", "dom.iterable", "esnext"], 4 | "target": "esnext", 5 | "moduleResolution": "Bundler", 6 | "module": "ESNext", 7 | "noEmit": true, 8 | "skipLibCheck": true 9 | }, 10 | // "include": ["./src/define-theme.ts", "./sandbox/theme-preset.ts"] 11 | // "include": ["./theme-demo.ts", "./preset-base", "./preset-panda"], 12 | "include": ["./src/define-theme.ts", "./sandbox/theme-preset.ts", "./sandbox/theme-preset-stresstest.ts"] 13 | } 14 | -------------------------------------------------------------------------------- /packages/unplugin/playground/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "unplugin-playground", 3 | "private": true, 4 | "scripts": { 5 | "dev": "nodemon -w '../src/**/*.ts' -e .ts -x vite" 6 | }, 7 | "devDependencies": { 8 | "@pandacss/dev": "^0.36.1", 9 | "@types/react": "^18.2.60", 10 | "@types/react-dom": "^18.2.19", 11 | "@vitejs/plugin-react-swc": "^3.6.0", 12 | "nodemon": "^3.1.0", 13 | "react": "^18.2.0", 14 | "react-dom": "^18.2.0", 15 | "vite": "^5.1.4", 16 | "vite-plugin-inspect": "^0.8.3" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /examples/solid-start-unplugin/src/routes/index.tsx: -------------------------------------------------------------------------------- 1 | import { Title } from "@solidjs/meta"; 2 | import Counter from "~/components/Counter"; 3 | 4 | export default function Home() { 5 | return ( 6 |
7 | Hello World 8 |

Hello world!

9 | 10 |

11 | Visit{" "} 12 | 13 | start.solidjs.com 14 | {" "} 15 | to learn how to build SolidStart apps. 16 |

17 |
18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /packages/unplugin-panda-macro/playground/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "macro-playground", 3 | "private": true, 4 | "scripts": { 5 | "dev": "nodemon -w '../src/**/*.ts' -e .ts -x vite" 6 | }, 7 | "devDependencies": { 8 | "@pandacss/dev": "^0.36.1", 9 | "@types/react": "^18.2.60", 10 | "@types/react-dom": "^18.2.19", 11 | "@vitejs/plugin-react-swc": "^3.6.0", 12 | "nodemon": "^3.1.0", 13 | "react": "^18.2.0", 14 | "react-dom": "^18.2.0", 15 | "vite": "^5.1.4", 16 | "vite-plugin-inspect": "^0.8.3" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/unplugin/e2e/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "unplugin-scenarios", 3 | "private": true, 4 | "scripts": { 5 | "outfile": "pnpm vite ./scenarios/outfile", 6 | "virtual-file": "pnpm vite ./scenarios/virtual-file" 7 | }, 8 | "devDependencies": { 9 | "@pandacss/dev": "^0.36.1", 10 | "@types/react": "^18.2.60", 11 | "@types/react-dom": "^18.2.19", 12 | "@vitejs/plugin-react-swc": "^3.6.0", 13 | "react": "^18.2.0", 14 | "react-dom": "^18.2.0", 15 | "vite": "^5.1.4", 16 | "vite-plugin-inspect": "^0.8.3" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/utils/README.md: -------------------------------------------------------------------------------- 1 | # @pandabox/utils 2 | 3 | - `assignInlineVars` is like 4 | [the one from vanilla-extract](https://vanilla-extract.style/documentation/packages/dynamic/#assigninlinevars) but 5 | type-safe with typings using your own panda.config tokens 6 | - `cssVar` allows creating creating css vars as JS objects so you can reference them in your panda config or at runtime 7 | - `wrapValue` will wrap every objects inside the first argument with a { value: xxx }, mostly meant to easily migrate 8 | from a chakra theme tokens object to a panda.config tokens object 9 | -------------------------------------------------------------------------------- /examples/solid-start-unplugin/src/routes/[...404].tsx: -------------------------------------------------------------------------------- 1 | import { Title } from "@solidjs/meta"; 2 | import { HttpStatusCode } from "@solidjs/start"; 3 | 4 | export default function NotFound() { 5 | return ( 6 |
7 | Not Found 8 | 9 |

Page Not Found

10 |

11 | Visit{" "} 12 | 13 | start.solidjs.com 14 | {" "} 15 | to learn how to build SolidStart apps. 16 |

17 |
18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /packages/unplugin/__tests__/samples/only-styled.tsx: -------------------------------------------------------------------------------- 1 | import 'virtual:panda.css' 2 | import { styled } from '../styled-system/jsx' 3 | import { something } from 'some-module' 4 | 5 | export const App = () => { 6 | return ( 7 | console.log('hello')} 15 | unresolvable={something} 16 | > 17 | Hello from Panda 18 | 19 | ) 20 | } 21 | -------------------------------------------------------------------------------- /packages/unplugin/playground/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | visit /__inspect/ to inspect the intermediate state 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /packages/unplugin/README.md: -------------------------------------------------------------------------------- 1 | # @pandabox/unplugin 2 | 3 | Alternative distribution entrypoint for Panda CSS (other than the [CLI](https://panda-css.com/docs/installation/cli) and 4 | [PostCSS plugin](https://panda-css.com/docs/installation/postcss)). 5 | 6 | ## Installation 7 | 8 | ```bash 9 | npm i @pandabox/unplugin 10 | ``` 11 | 12 | ## Usage 13 | 14 | ```ts 15 | import { defineConfig } from 'vite' 16 | import pandabox from '@pandabox/unplugin' 17 | 18 | export default defineConfig({ 19 | plugins: [ 20 | pandabox.vite({ 21 | /* options */ 22 | }), 23 | ], 24 | }) 25 | ``` 26 | -------------------------------------------------------------------------------- /tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowJs": false, 4 | "allowSyntheticDefaultImports": true, 5 | "declaration": true, 6 | "downlevelIteration": true, 7 | "esModuleInterop": true, 8 | "jsx": "preserve", 9 | "noEmit": true, 10 | "lib": ["dom", "dom.iterable", "esnext"], 11 | "target": "esnext", 12 | "noImplicitReturns": false, 13 | "resolveJsonModule": true, 14 | "skipLibCheck": true, 15 | "strict": true, 16 | "verbatimModuleSyntax": true, 17 | "moduleResolution": "Bundler", 18 | "module": "ESNext" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/unplugin-panda-macro/__tests__/samples/only-styled.tsx: -------------------------------------------------------------------------------- 1 | import 'virtual:panda.css' 2 | import { styled } from '../styled-system/jsx' 3 | import { something } from 'some-module' 4 | 5 | export const App = () => { 6 | return ( 7 | console.log('hello')} 15 | unresolvable={something} 16 | > 17 | Hello from Panda 18 | 19 | ) 20 | } 21 | -------------------------------------------------------------------------------- /packages/unplugin-panda-macro/playground/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | visit /__inspect/ to inspect the intermediate state 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /packages/unplugin/e2e/scenarios/outfile/panda.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from '@pandacss/dev' 2 | 3 | export default defineConfig({ 4 | // Whether to use css reset 5 | preflight: true, 6 | 7 | // Where to look for your css declarations 8 | include: ['./src/**/*.{js,jsx,ts,tsx}'], 9 | 10 | // Files to exclude 11 | exclude: [], 12 | 13 | // Useful for theme customization 14 | theme: { 15 | extend: {}, 16 | }, 17 | 18 | // The output directory for your css system 19 | outdir: 'styled-system', 20 | 21 | // The JSX framework to use 22 | jsxFramework: 'react', 23 | }) 24 | -------------------------------------------------------------------------------- /packages/unplugin/e2e/scenarios/virtual-file/panda.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from '@pandacss/dev' 2 | 3 | export default defineConfig({ 4 | // Whether to use css reset 5 | preflight: true, 6 | 7 | // Where to look for your css declarations 8 | include: ['./src/**/*.{js,jsx,ts,tsx}'], 9 | 10 | // Files to exclude 11 | exclude: [], 12 | 13 | // Useful for theme customization 14 | theme: { 15 | extend: {}, 16 | }, 17 | 18 | // The output directory for your css system 19 | outdir: 'styled-system', 20 | 21 | // The JSX framework to use 22 | jsxFramework: 'react', 23 | }) 24 | -------------------------------------------------------------------------------- /packages/define-theme/sandbox/preset-panda/shadows.ts: -------------------------------------------------------------------------------- 1 | export const shadows = { 2 | xs: { value: '0 1px 2px 0 rgb(0 0 0 / 0.05)' }, 3 | sm: { value: ['0 1px 3px 0 rgb(0 0 0 / 0.1)', '0 1px 2px -1px rgb(0 0 0 / 0.1)'] }, 4 | md: { value: ['0 4px 6px -1px rgb(0 0 0 / 0.1)', '0 2px 4px -2px rgb(0 0 0 / 0.1)'] }, 5 | lg: { value: ['0 10px 15px -3px rgb(0 0 0 / 0.1)', '0 4px 6px -4px rgb(0 0 0 / 0.1)'] }, 6 | xl: { value: ['0 20px 25px -5px rgb(0 0 0 / 0.1)', '0 8px 10px -6px rgb(0 0 0 / 0.1)'] }, 7 | '2xl': { value: '0 25px 50px -12px rgb(0 0 0 / 0.25)' }, 8 | inner: { value: 'inset 0 2px 4px 0 rgb(0 0 0 / 0.05)' }, 9 | } 10 | -------------------------------------------------------------------------------- /website/app/entry.client.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * By default, Remix will handle hydrating your app on the client for you. 3 | * You are free to delete this file if you'd like to, but if you ever want it revealed again, you can run `npx remix reveal` ✨ 4 | * For more information, see https://remix.run/file-conventions/entry.client 5 | */ 6 | 7 | import { RemixBrowser } from "@remix-run/react"; 8 | import { startTransition, StrictMode } from "react"; 9 | import { hydrateRoot } from "react-dom/client"; 10 | 11 | startTransition(() => { 12 | hydrateRoot( 13 | document, 14 | 15 | 16 | 17 | ); 18 | }); 19 | -------------------------------------------------------------------------------- /examples/solid-start-unplugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example-basic", 3 | "type": "module", 4 | "scripts": { 5 | "prepare": "panda", 6 | "dev": "vinxi dev", 7 | "build": "vinxi build", 8 | "start": "vinxi start", 9 | "version": "vinxi version" 10 | }, 11 | "dependencies": { 12 | "@solidjs/meta": "^0.29.2", 13 | "@solidjs/router": "^0.13.1", 14 | "@solidjs/start": "^1.0.0-rc.0", 15 | "solid-js": "^1.8.16", 16 | "vinxi": "^0.3.10" 17 | }, 18 | "engines": { 19 | "node": ">=18" 20 | }, 21 | "devDependencies": { 22 | "@pandabox/unplugin": "0.1.2", 23 | "@pandacss/dev": "^0.37.2" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/unplugin/playground/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "noEmit": true, 15 | "jsx": "react-jsx", 16 | 17 | /* Linting */ 18 | "strict": true, 19 | "noUnusedLocals": true, 20 | "noUnusedParameters": true, 21 | "noFallthroughCasesInSwitch": true 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/define-theme/sandbox/define-theme.bench.ts: -------------------------------------------------------------------------------- 1 | import { bench } from '@arktype/attest' 2 | 3 | import { preset as presetBase } from './preset-base' 4 | import { preset as presetPanda } from './preset-panda' 5 | 6 | import { defineTheme } from '../src/define-theme' 7 | 8 | const { conditions, utilities } = presetBase 9 | const { tokens } = presetPanda.theme 10 | 11 | bench('defineTheme conditions + tokens + utilities', () => { 12 | const t = defineTheme() 13 | 14 | const builder = t.conditions(conditions).tokens(tokens).utilities(utilities) 15 | const config = builder.build() 16 | 17 | return {} as any as typeof config 18 | }).types([285, 'instantiations']) 19 | -------------------------------------------------------------------------------- /examples/solid-start-unplugin/src/app.tsx: -------------------------------------------------------------------------------- 1 | import { MetaProvider, Title } from "@solidjs/meta"; 2 | import { Router } from "@solidjs/router"; 3 | import { FileRoutes } from "@solidjs/start/router"; 4 | import { Suspense } from "solid-js"; 5 | import "./app.css"; 6 | 7 | export default function App() { 8 | return ( 9 | ( 11 | 12 | SolidStart - Basic 13 | Index 14 | About 15 | {props.children} 16 | 17 | )} 18 | > 19 | 20 | 21 | ); 22 | } 23 | -------------------------------------------------------------------------------- /packages/unplugin-panda-macro/playground/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "noEmit": true, 15 | "jsx": "react-jsx", 16 | 17 | /* Linting */ 18 | "strict": true, 19 | "noUnusedLocals": true, 20 | "noUnusedParameters": true, 21 | "noFallthroughCasesInSwitch": true 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /examples/solid-start-unplugin/src/entry-server.tsx: -------------------------------------------------------------------------------- 1 | // @refresh reload 2 | import { createHandler, StartServer } from "@solidjs/start/server"; 3 | 4 | export default createHandler(() => ( 5 | ( 7 | 8 | 9 | 10 | 11 | 12 | {assets} 13 | 14 | 15 |
{children}
16 | {scripts} 17 | 18 | 19 | )} 20 | /> 21 | )); 22 | -------------------------------------------------------------------------------- /packages/define-theme/sandbox/theme-preset.ts: -------------------------------------------------------------------------------- 1 | import { defineTheme } from '../src/define-theme' 2 | import { preset as presetBase } from './preset-base' 3 | import { preset as presetPanda } from './preset-panda' 4 | 5 | const t = defineTheme() 6 | 7 | const { conditions, utilities } = presetBase 8 | const { tokens, breakpoints, textStyles } = presetPanda.theme 9 | 10 | // Define tokens with the builder. TypeScript infers the structure. 11 | const builder = t 12 | .conditions(conditions) 13 | .breakpoints(breakpoints) 14 | .tokens(tokens) 15 | .utilities(utilities) 16 | .textStyles(textStyles) 17 | 18 | // const config = defineTheme(builder) 19 | export const config = builder.build() 20 | -------------------------------------------------------------------------------- /packages/unplugin-panda-macro/src/nuxt.ts: -------------------------------------------------------------------------------- 1 | import { addVitePlugin, addWebpackPlugin, defineNuxtModule } from '@nuxt/kit' 2 | import vite from './vite' 3 | import webpack from './webpack' 4 | import '@nuxt/schema' 5 | import type { PluginOptions } from './plugin/core' 6 | 7 | export interface ModuleOptions extends PluginOptions {} 8 | 9 | export default defineNuxtModule({ 10 | meta: { 11 | name: 'nuxt-unplugin-starter', 12 | configKey: 'unpluginStarter', 13 | }, 14 | defaults: { 15 | // ...default options 16 | }, 17 | setup(options, _nuxt) { 18 | addVitePlugin(() => vite(options)) 19 | addWebpackPlugin(() => webpack(options)) 20 | 21 | // ... 22 | }, 23 | }) 24 | -------------------------------------------------------------------------------- /packages/unplugin/src/nuxt.ts: -------------------------------------------------------------------------------- 1 | import { addVitePlugin, addWebpackPlugin, defineNuxtModule } from '@nuxt/kit' 2 | import vite from './vite' 3 | import webpack from './webpack' 4 | import '@nuxt/schema' 5 | import type { PandaPluginOptions } from './plugin/core' 6 | 7 | export interface ModuleOptions extends PandaPluginOptions {} 8 | 9 | export default defineNuxtModule({ 10 | meta: { 11 | name: 'nuxt-unplugin-starter', 12 | configKey: 'unpluginStarter', 13 | }, 14 | defaults: { 15 | // ...default options 16 | }, 17 | setup(options, _nuxt) { 18 | addVitePlugin(() => vite(options)) 19 | addWebpackPlugin(() => webpack(options)) 20 | 21 | // ... 22 | }, 23 | }) 24 | -------------------------------------------------------------------------------- /packages/unplugin-panda-macro/src/plugin/has-macro-attribute.ts: -------------------------------------------------------------------------------- 1 | import type { ImportDeclaration } from 'ts-morph' 2 | import { Node } from 'ts-morph' 3 | 4 | export const hasMacroAttribute = (node: ImportDeclaration) => { 5 | const attrs = node.getAttributes() 6 | if (!attrs) return 7 | 8 | const elements = attrs.getElements() 9 | if (!elements.length) return 10 | 11 | return elements.some((n) => { 12 | const name = n.getName() 13 | if (name === 'type') { 14 | const value = n.getValue() 15 | if (!Node.isStringLiteral(value)) return 16 | 17 | const type = value.getLiteralText() 18 | if (type === 'macro') { 19 | return true 20 | } 21 | } 22 | }) 23 | } 24 | -------------------------------------------------------------------------------- /packages/define-theme/sandbox/theme-preset-demo.ts: -------------------------------------------------------------------------------- 1 | import { config } from './theme-preset' 2 | 3 | config.defineStyles({ 4 | bg: 'blue.100', 5 | fontSize: 'xxx-large', 6 | color: 'blue.300', 7 | // backgroundGradient: "", 8 | background: 'text.foreground', 9 | _hover: { 10 | _dark: { 11 | bg: 'text.background', 12 | }, 13 | }, 14 | }) 15 | 16 | config.defineRecipe({ 17 | className: 'aaa', 18 | base: { 19 | display: 'flex', 20 | background: 'text', 21 | }, 22 | variants: { 23 | type: { 24 | success: { 25 | bg: 'rose.200', 26 | background: 'tex.', 27 | }, 28 | }, 29 | }, 30 | defaultVariants: { 31 | type: 'success', 32 | }, 33 | }) 34 | -------------------------------------------------------------------------------- /examples/solid-start-unplugin/src/app.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: Gordita, Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; 3 | } 4 | 5 | a { 6 | margin-right: 1rem; 7 | } 8 | 9 | main { 10 | text-align: center; 11 | padding: 1em; 12 | margin: 0 auto; 13 | } 14 | 15 | h1 { 16 | color: #335d92; 17 | text-transform: uppercase; 18 | font-size: 4rem; 19 | font-weight: 100; 20 | line-height: 1.1; 21 | margin: 4rem auto; 22 | max-width: 14rem; 23 | } 24 | 25 | p { 26 | max-width: 14rem; 27 | margin: 2rem auto; 28 | line-height: 1.35; 29 | } 30 | 31 | @media (min-width: 480px) { 32 | h1 { 33 | max-width: none; 34 | } 35 | 36 | p { 37 | max-width: none; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /examples/unplugin/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "noEmit": true, 15 | "jsx": "react-jsx", 16 | 17 | /* Linting */ 18 | "strict": true, 19 | "noUnusedLocals": true, 20 | "noUnusedParameters": true, 21 | "noFallthroughCasesInSwitch": true 22 | }, 23 | "include": ["src"], 24 | "references": [{ "path": "./tsconfig.node.json" }] 25 | } 26 | -------------------------------------------------------------------------------- /packages/unplugin/src/plugin/has-macro-attribute.ts: -------------------------------------------------------------------------------- 1 | import type { ImportDeclaration } from 'ts-morph' 2 | import { Node } from 'ts-morph' 3 | 4 | export const getMacroAttribute = (node: ImportDeclaration, attrName = 'type') => { 5 | const attrs = node.getAttributes() 6 | if (!attrs) return null 7 | 8 | const elements = attrs.getElements() 9 | if (!elements.length) return null 10 | 11 | let withAttr: string | null = null 12 | elements.some((n) => { 13 | const name = n.getName() 14 | if (name !== attrName) return 15 | 16 | const value = n.getValue() 17 | if (!Node.isStringLiteral(value)) return 18 | 19 | withAttr = value.getLiteralText() 20 | return true 21 | }) 22 | 23 | return withAttr 24 | } 25 | -------------------------------------------------------------------------------- /packages/unplugin/__tests__/samples/css-with-raw.tsx: -------------------------------------------------------------------------------- 1 | import 'virtual:panda.css' 2 | import { css } from '../styled-system/css' 3 | 4 | const overrides = css.raw({ 5 | bg: 'green.100', 6 | }) 7 | 8 | export const App = () => { 9 | return ( 10 |
27 | Hello from Panda 28 |
29 | ) 30 | } 31 | -------------------------------------------------------------------------------- /packages/unplugin-panda-macro/__tests__/samples/css-with-raw.tsx: -------------------------------------------------------------------------------- 1 | import 'virtual:panda.css' 2 | import { css } from '../styled-system/css' 3 | 4 | const overrides = css.raw({ 5 | bg: 'green.100', 6 | }) 7 | 8 | export const App = () => { 9 | return ( 10 |
27 | Hello from Panda 28 |
29 | ) 30 | } 31 | -------------------------------------------------------------------------------- /packages/define-theme/sandbox/preset-panda/sizes.ts: -------------------------------------------------------------------------------- 1 | import { spacing } from './spacing' 2 | 3 | const largeSizes = { 4 | xs: { value: '20rem' }, 5 | sm: { value: '24rem' }, 6 | md: { value: '28rem' }, 7 | lg: { value: '32rem' }, 8 | xl: { value: '36rem' }, 9 | '2xl': { value: '42rem' }, 10 | '3xl': { value: '48rem' }, 11 | '4xl': { value: '56rem' }, 12 | '5xl': { value: '64rem' }, 13 | '6xl': { value: '72rem' }, 14 | '7xl': { value: '80rem' }, 15 | '8xl': { value: '90rem' }, 16 | prose: { value: '65ch' }, 17 | } 18 | 19 | export const sizes = { 20 | ...spacing, 21 | ...largeSizes, 22 | full: { value: '100%' }, 23 | min: { value: 'min-content' }, 24 | max: { value: 'max-content' }, 25 | fit: { value: 'fit-content' }, 26 | } 27 | -------------------------------------------------------------------------------- /website/README.md: -------------------------------------------------------------------------------- 1 | # Welcome to Remix! 2 | 3 | - [Remix Docs](https://remix.run/docs) 4 | 5 | ## Development 6 | 7 | From your terminal: 8 | 9 | ```sh 10 | npm run dev 11 | ``` 12 | 13 | This starts your app in development mode, rebuilding assets on file changes. 14 | 15 | ## Deployment 16 | 17 | First, build your app for production: 18 | 19 | ```sh 20 | npm run build 21 | ``` 22 | 23 | Then run the app in production mode: 24 | 25 | ```sh 26 | npm start 27 | ``` 28 | 29 | Now you'll need to pick a host to deploy it to. 30 | 31 | ### DIY 32 | 33 | If you're familiar with deploying node applications, the built-in Remix app server is production-ready. 34 | 35 | Make sure to deploy the output of `remix build` 36 | 37 | - `build/` 38 | - `public/build/` 39 | -------------------------------------------------------------------------------- /packages/utils/__tests__/assign-inline-vars.test.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from 'vitest' 2 | import { assignInlineVars } from '../src/assign-inline-vars' 3 | 4 | // https://play.panda-css.com/TkiN7P8XZg 5 | test('assign-inline-vars', () => { 6 | expect( 7 | assignInlineVars({ 8 | colors: { 9 | primary: 'red', 10 | secondary: 'blue', 11 | 'some.very.nested.path': 'green', 12 | }, 13 | sizes: { 14 | sm: 10, 15 | md: 20, 16 | }, 17 | }), 18 | ).toMatchInlineSnapshot(` 19 | { 20 | "--colors-primary": "red", 21 | "--colors-secondary": "blue", 22 | "--colors-some\\.very\\.nested\\.path": "green", 23 | "--sizes-md": 20, 24 | "--sizes-sm": 10, 25 | } 26 | `) 27 | }) 28 | -------------------------------------------------------------------------------- /sandbox/react/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "noEmit": true, 15 | "jsx": "react-jsx", 16 | 17 | /* Linting */ 18 | "strict": true, 19 | "noUnusedLocals": true, 20 | "noUnusedParameters": true, 21 | "noFallthroughCasesInSwitch": true 22 | }, 23 | "include": ["src", "panda.config.ts", "./styled-system"], 24 | "references": [{ "path": "./tsconfig.node.json" }] 25 | } 26 | -------------------------------------------------------------------------------- /packages/panda-plugins/test-cli.md: -------------------------------------------------------------------------------- 1 | # test-cli 2 | 3 | A CLI to test different runtime scenarios of the `panda-plugins` 4 | 5 | ## Usage 6 | 7 | - `bun cli.ts -h` will show the helper 8 | - `bun cli.ts codegen` will generate every scenarios `outdir` 9 | - `bun cli.ts test` will test every scenarios 10 | 11 | ## Adding a scenario 12 | 13 | - Create a `./__tests__/scenarios/{scenario}.config.ts` with your specific options 14 | - Add it in the `scenarioList` inside `cli.ts` 15 | - Add it in the `options` inside `vitest.config.ts` with the `test.include` to match specific tests files 16 | - You're done ! You can run `bun cli.ts codegen {scenario}` and `bun cli.ts test {scenario}` 17 | 18 | > Pro tip: You can use `-u` or `--update` with `bun cli.ts test` to update every snapshots 19 | -------------------------------------------------------------------------------- /website/app/components/twitter-icon.tsx: -------------------------------------------------------------------------------- 1 | import type { ComponentPropsWithoutRef } from 'react' 2 | 3 | export const TwitterIcon = (props: ComponentPropsWithoutRef<'svg'>) => ( 4 | 5 | 6 | 7 | ) 8 | -------------------------------------------------------------------------------- /packages/unplugin/scripts/postbuild.ts: -------------------------------------------------------------------------------- 1 | import { basename, dirname, resolve } from 'node:path' 2 | import { promises as fs } from 'node:fs' 3 | import { fileURLToPath } from 'node:url' 4 | import fg from 'fast-glob' 5 | import chalk from 'chalk' 6 | 7 | async function run() { 8 | // fix cjs exports 9 | const files = await fg('*.cjs', { 10 | ignore: ['chunk-*'], 11 | absolute: true, 12 | cwd: resolve(dirname(fileURLToPath(import.meta.url)), '../dist'), 13 | }) 14 | for (const file of files) { 15 | console.log(chalk.cyan.inverse(' POST '), `Fix ${basename(file)}`) 16 | let code = await fs.readFile(file, 'utf8') 17 | code = code.replace('exports.default =', 'module.exports =') 18 | code += 'exports.default = module.exports;' 19 | await fs.writeFile(file, code) 20 | } 21 | } 22 | 23 | run() 24 | -------------------------------------------------------------------------------- /packages/unplugin-panda-macro/scripts/postbuild.ts: -------------------------------------------------------------------------------- 1 | import { basename, dirname, resolve } from 'node:path' 2 | import { promises as fs } from 'node:fs' 3 | import { fileURLToPath } from 'node:url' 4 | import fg from 'fast-glob' 5 | import chalk from 'chalk' 6 | 7 | async function run() { 8 | // fix cjs exports 9 | const files = await fg('*.cjs', { 10 | ignore: ['chunk-*'], 11 | absolute: true, 12 | cwd: resolve(dirname(fileURLToPath(import.meta.url)), '../dist'), 13 | }) 14 | for (const file of files) { 15 | console.log(chalk.cyan.inverse(' POST '), `Fix ${basename(file)}`) 16 | let code = await fs.readFile(file, 'utf8') 17 | code = code.replace('exports.default =', 'module.exports =') 18 | code += 'exports.default = module.exports;' 19 | await fs.writeFile(file, code) 20 | } 21 | } 22 | 23 | run() 24 | -------------------------------------------------------------------------------- /website/app/root.tsx: -------------------------------------------------------------------------------- 1 | import type { LinksFunction } from '@remix-run/node' 2 | import { Links, Meta, Outlet, Scripts, ScrollRestoration } from '@remix-run/react' 3 | import pandaCss from '../styled-system/styles.css?url' 4 | import inter from '@fontsource/inter?url' 5 | 6 | export const links: LinksFunction = () => [ 7 | { rel: 'stylesheet', href: pandaCss }, 8 | { rel: 'stylesheet', href: inter }, 9 | ] 10 | 11 | export default function App() { 12 | return ( 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | ) 27 | } 28 | -------------------------------------------------------------------------------- /sandbox/react/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { styled } from '../styled-system/jsx' 2 | 3 | const Button = styled('button', { 4 | base: { 5 | color: 'red.200', 6 | }, 7 | props: ['color', 'bg', 'css'], 8 | }) 9 | 10 | const Basic = styled('div', { 11 | base: { 12 | color: 'red.200', 13 | }, 14 | }) 15 | 16 | function App() { 17 | return ( 18 | <> 19 | 29 |

30 | 36 | basic 37 | 38 | 39 | ) 40 | } 41 | 42 | export default App 43 | -------------------------------------------------------------------------------- /packages/define-theme/sandbox/preset-base/utilities/outline.ts: -------------------------------------------------------------------------------- 1 | import type { UtilityConfig } from '@pandacss/types' 2 | 3 | export const outline = { 4 | outlineWidth: { 5 | className: 'ring', 6 | shorthand: 'ringWidth', 7 | values: 'borderWidths', 8 | }, 9 | outlineColor: { 10 | className: 'ring', 11 | values: 'colors', 12 | shorthand: 'ringColor', 13 | }, 14 | outline: { 15 | className: 'ring', 16 | shorthand: 'ring', 17 | values: 'borders', 18 | transform(value) { 19 | if (value === 'none') { 20 | return { outline: '2px solid transparent', outlineOffset: '2px' } 21 | } 22 | return { outline: value } 23 | }, 24 | }, 25 | outlineOffset: { 26 | className: 'ring', 27 | shorthand: 'ringOffset', 28 | values: 'spacing', 29 | }, 30 | } as const satisfies UtilityConfig 31 | -------------------------------------------------------------------------------- /packages/define-theme/sandbox/preset-base/utilities/tables.ts: -------------------------------------------------------------------------------- 1 | import type { UtilityConfig } from '@pandacss/types' 2 | 3 | export const tables = { 4 | borderCollapse: { 5 | className: 'border', 6 | }, 7 | borderSpacing: { 8 | className: 'border-spacing', 9 | values: 'spacing', 10 | }, 11 | borderSpacingX: { 12 | className: 'border-spacing-x', 13 | values: 'spacing', 14 | transform(value) { 15 | return { 16 | borderSpacing: `${value} var(--border-spacing-y)`, 17 | } 18 | }, 19 | }, 20 | borderSpacingY: { 21 | className: 'border-spacing-y', 22 | values: 'spacing', 23 | transform(value) { 24 | return { 25 | borderSpacing: `var(--border-spacing-x) ${value}`, 26 | } 27 | }, 28 | }, 29 | tableLayout: { 30 | className: 'table', 31 | }, 32 | } as const satisfies UtilityConfig 33 | -------------------------------------------------------------------------------- /website/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | // "extends": "../tsconfig.json", 3 | "include": ["env.d.ts", "**/*.ts", "**/*.tsx"], 4 | "compilerOptions": { 5 | "target": "ESNext", 6 | "useDefineForClassFields": true, 7 | "lib": ["DOM", "DOM.Iterable", "ESNext"], 8 | "allowJs": false, 9 | "skipLibCheck": true, 10 | "esModuleInterop": false, 11 | "allowSyntheticDefaultImports": true, 12 | "strict": true, 13 | "forceConsistentCasingInFileNames": true, 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "jsx": "react-jsx", 17 | "moduleResolution": "Bundler", 18 | "module": "ESNext", 19 | "paths": { 20 | "#styled-system/*": ["./styled-system/*"] 21 | }, 22 | 23 | // Remix takes care of building everything in `remix build`. 24 | "noEmit": true 25 | }, 26 | "exclude": ["./app/playground/initial-input.ts"] 27 | } 28 | -------------------------------------------------------------------------------- /packages/unplugin/__tests__/samples/only-cva.tsx: -------------------------------------------------------------------------------- 1 | import 'virtual:panda.css' 2 | import { cva } from '../styled-system/css' 3 | 4 | const atomicRecipe = cva({ 5 | base: { 6 | display: 'flex', 7 | }, 8 | variants: { 9 | visual: { 10 | solid: { bg: 'red.200', color: 'white' }, 11 | outline: { borderWidth: '1px', borderColor: 'red.200' }, 12 | }, 13 | size: { 14 | sm: { padding: '4', fontSize: '12px' }, 15 | lg: { padding: '8', fontSize: '24px' }, 16 | }, 17 | }, 18 | compoundVariants: [ 19 | { 20 | visual: 'outline', 21 | size: 'lg', 22 | css: { 23 | borderWidth: '3px', 24 | }, 25 | }, 26 | ], 27 | defaultVariants: { 28 | visual: 'solid', 29 | }, 30 | }) 31 | 32 | export const App = () => { 33 | return
Atomic Button
34 | } 35 | -------------------------------------------------------------------------------- /packages/unplugin-panda-macro/__tests__/samples/only-cva.tsx: -------------------------------------------------------------------------------- 1 | import 'virtual:panda.css' 2 | import { cva } from '../styled-system/css' 3 | 4 | const atomicRecipe = cva({ 5 | base: { 6 | display: 'flex', 7 | }, 8 | variants: { 9 | visual: { 10 | solid: { bg: 'red.200', color: 'white' }, 11 | outline: { borderWidth: '1px', borderColor: 'red.200' }, 12 | }, 13 | size: { 14 | sm: { padding: '4', fontSize: '12px' }, 15 | lg: { padding: '8', fontSize: '24px' }, 16 | }, 17 | }, 18 | compoundVariants: [ 19 | { 20 | visual: 'outline', 21 | size: 'lg', 22 | css: { 23 | borderWidth: '3px', 24 | }, 25 | }, 26 | ], 27 | defaultVariants: { 28 | visual: 'solid', 29 | }, 30 | }) 31 | 32 | export const App = () => { 33 | return
Atomic Button
34 | } 35 | -------------------------------------------------------------------------------- /website/app/routes/styled2panda.tsx: -------------------------------------------------------------------------------- 1 | import type { MetaFunction } from '@remix-run/node' 2 | import { Link } from '@remix-run/react' 3 | import { LuChevronLeft } from 'react-icons/lu' 4 | import { IconButton } from '../components/icon-button' 5 | import { Layout } from '../components/layout' 6 | import { Playground } from '../playground/playground' 7 | 8 | export const meta: MetaFunction = () => { 9 | return [ 10 | { title: 'styled2panda' }, 11 | { name: 'description', content: 'Template literal to Object syntax with Panda CSS' }, 12 | ] 13 | } 14 | 15 | export default function Index() { 16 | return ( 17 | 20 | 21 | 22 | 23 | 24 | } 25 | > 26 | 27 | 28 | ) 29 | } 30 | -------------------------------------------------------------------------------- /packages/unplugin/e2e/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "noEmit": true, 15 | "jsx": "react-jsx", 16 | 17 | /* Linting */ 18 | "strict": true, 19 | "noUnusedLocals": true, 20 | "noUnusedParameters": true, 21 | "noFallthroughCasesInSwitch": true, 22 | 23 | "checkJs": true, 24 | "allowJs": true, 25 | "esModuleInterop": true, 26 | "types": ["vite/client", "node"] 27 | }, 28 | "include": ["**/vite*config*", "**/panda*config*", "**/*.ts", "scenarios/**/*.ts"], 29 | "exclude": ["**/dist/**"] 30 | } 31 | -------------------------------------------------------------------------------- /packages/define-theme/sandbox/preset-panda/keyframes.ts: -------------------------------------------------------------------------------- 1 | export const keyframes = { 2 | spin: { 3 | to: { 4 | transform: 'rotate(360deg)', 5 | }, 6 | }, 7 | ping: { 8 | '75%, 100%': { 9 | transform: 'scale(2)', 10 | opacity: '0', 11 | }, 12 | }, 13 | pulse: { 14 | '50%': { 15 | opacity: '.5', 16 | }, 17 | }, 18 | bounce: { 19 | '0%, 100%': { 20 | transform: 'translateY(-25%)', 21 | animationTimingFunction: 'cubic-bezier(0.8,0,1,1)', 22 | }, 23 | '50%': { 24 | transform: 'none', 25 | animationTimingFunction: 'cubic-bezier(0,0,0.2,1)', 26 | }, 27 | }, 28 | } 29 | 30 | export const animations = { 31 | spin: { value: 'spin 1s linear infinite' }, 32 | ping: { value: 'ping 1s cubic-bezier(0, 0, 0.2, 1) infinite' }, 33 | pulse: { value: 'pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite' }, 34 | bounce: { value: 'bounce 1s infinite' }, 35 | } 36 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pandabox", 3 | "private": true, 4 | "packageManager": "pnpm@8.6.6+sha256.52f3e7d33884929f1902a7494a616d844b506ed46592e65463ba45e97cc25a1b", 5 | "scripts": { 6 | "define-theme": "pnpm --filter @pandabox/define-theme", 7 | "knip": "knip", 8 | "release": "changeset publish", 9 | "fmt": "prettier --write packages/**/*.{ts,tsx}", 10 | "dev": "pnpm --parallel --filter=./packages/* dev", 11 | "build": "pnpm --filter @pandabox/* run build", 12 | "typecheck": "pnpm --filter @pandabox/* run typecheck", 13 | "test": "vitest", 14 | "test:run": "vitest --run", 15 | "check": "pnpm typecheck && pnpm test:run" 16 | }, 17 | "devDependencies": { 18 | "@arktype/attest": "^0.6.2", 19 | "@changesets/cli": "^2.27.1", 20 | "@types/node": "^20.11.21", 21 | "knip": "^5.0.2", 22 | "prettier": "^3.2.5", 23 | "tsx": "^4.7.1", 24 | "typescript": "^5.3.3", 25 | "vitest": "^1.3.1" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /packages/define-theme/sandbox/strict-property-values.ts: -------------------------------------------------------------------------------- 1 | import { defineTheme } from '../src/define-theme' 2 | 3 | const t = defineTheme({ strictPropertyValues: false }) 4 | 5 | const builder = t 6 | .conditions({ 7 | hover: '&:hover', 8 | }) 9 | .utilities({ 10 | display: { 11 | className: 'd', 12 | }, 13 | }) 14 | 15 | const config = builder.build() 16 | 17 | config.defineStyles({ 18 | display: 'flex', 19 | }) 20 | 21 | // 22 | 23 | const withStrictTokens = defineTheme({ strictPropertyValues: true }) 24 | .conditions({ 25 | hover: '&:hover', 26 | }) 27 | .utilities({ 28 | display: { 29 | className: 'd', 30 | }, 31 | }) 32 | .build() 33 | 34 | withStrictTokens.defineStyles({ 35 | background: 'blue', 36 | color: 'aaa', 37 | // @ts-expect-error 38 | display: 'xxx', 39 | _hover: { 40 | // @ts-expect-error 41 | display: 'bbb', 42 | }, 43 | '&:hover': { 44 | display: 'flex', 45 | }, 46 | }) 47 | -------------------------------------------------------------------------------- /packages/unplugin/e2e/scenarios/outfile/outfile.test.ts: -------------------------------------------------------------------------------- 1 | import { expect } from '@playwright/test' 2 | import { describe, test } from 'vitest' 3 | import { getClassName, getElementStyle } from '../../test-elements' 4 | import { page } from '../../test-setup' 5 | import { editFile, withRetry } from '../../test-utils' 6 | 7 | describe('unplugin with outfile', () => { 8 | test('HMR on file change', async () => { 9 | expect(await getClassName(page, "[data-testid='hello']")).toBe('fs_12px') 10 | expect(await getElementStyle(page, "[data-testid='hello']")).toMatchObject({ 11 | fontSize: '12px', 12 | }) 13 | 14 | editFile('hello.tsx', (content) => content.replace('12px', '14px')) 15 | await withRetry(async () => { 16 | expect(await getClassName(page, "[data-testid='hello']")).toBe('fs_14px') 17 | expect(await getElementStyle(page, "[data-testid='hello']")).toMatchObject({ 18 | fontSize: '14px', 19 | }) 20 | }) 21 | }) 22 | }) 23 | -------------------------------------------------------------------------------- /sandbox/react/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sandbox-react", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "tsc && vite build", 9 | "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "react": "^18.2.0", 14 | "react-dom": "^18.2.0" 15 | }, 16 | "devDependencies": { 17 | "@pandabox/panda-plugins": "workspace:^", 18 | "@pandacss/dev": "^0.36.1", 19 | "@types/react": "^18.2.60", 20 | "@types/react-dom": "^18.2.19", 21 | "@typescript-eslint/eslint-plugin": "^7.1.0", 22 | "@typescript-eslint/parser": "^7.1.0", 23 | "@vitejs/plugin-react-swc": "^3.6.0", 24 | "eslint": "^8.57.0", 25 | "eslint-plugin-react-hooks": "^4.6.0", 26 | "eslint-plugin-react-refresh": "^0.4.5", 27 | "typescript": "^5.3.3", 28 | "vite": "^5.1.4" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /packages/unplugin/e2e/scenarios/virtual-file/virtual-file.test.ts: -------------------------------------------------------------------------------- 1 | import { expect } from '@playwright/test' 2 | import { describe, test } from 'vitest' 3 | import { getClassName, getElementStyle } from '../../test-elements' 4 | import { page } from '../../test-setup' 5 | import { editFile, withRetry } from '../../test-utils' 6 | 7 | describe('unplugin with virtual-file', () => { 8 | test('HMR on file change', async () => { 9 | expect(await getClassName(page, "[data-testid='hello']")).toBe('fs_12px') 10 | expect(await getElementStyle(page, "[data-testid='hello']")).toMatchObject({ 11 | fontSize: '12px', 12 | }) 13 | 14 | editFile('hello.tsx', (content) => content.replace('12px', '14px')) 15 | await withRetry(async () => { 16 | expect(await getClassName(page, "[data-testid='hello']")).toBe('fs_14px') 17 | expect(await getElementStyle(page, "[data-testid='hello']")).toMatchObject({ 18 | fontSize: '14px', 19 | }) 20 | }) 21 | }) 22 | }) 23 | -------------------------------------------------------------------------------- /packages/unplugin/src/plugin/cva-fns.ts: -------------------------------------------------------------------------------- 1 | // @ts-nocheck 2 | export function addCompoundVariantCss(compoundVariants, variants, classList) { 3 | compoundVariants.forEach(({ css, ...compoundVariant }) => { 4 | if (css) { 5 | const isMatching = Object.entries(compoundVariant).every(([key, value]) => { 6 | const values = Array.isArray(value) ? value : [value] 7 | return values.some((value) => variants[key] === value) 8 | }) 9 | 10 | if (isMatching) { 11 | classList.push(css) 12 | } 13 | } 14 | }) 15 | } 16 | 17 | // @ts-expect-error 18 | export function inlineCva(base, defaultVariants, variantStyles, variants) { 19 | const classList = [base] 20 | const variantProps = { ...defaultVariants, ...variants } 21 | 22 | for (const [key, value] of Object.entries(variantProps)) { 23 | if (variantStyles[key][value]) { 24 | classList.push(variantStyles[key][value]) 25 | } 26 | } 27 | 28 | return classList.join(' ') 29 | } 30 | -------------------------------------------------------------------------------- /packages/unplugin/e2e/test-elements.ts: -------------------------------------------------------------------------------- 1 | import type { ElementHandle, Locator, Page } from '@playwright/test' 2 | 3 | async function getEl(page: Page, el: string | ElementHandle | Locator): Promise { 4 | if (typeof el === 'string') { 5 | const realEl = await page.$(el) 6 | if (realEl == null) { 7 | throw new Error(`Cannot find element: "${el}"`) 8 | } 9 | return realEl 10 | } 11 | if ('elementHandle' in el) { 12 | return el.elementHandle() as Promise 13 | } 14 | 15 | return el 16 | } 17 | 18 | export async function getElementStyle(page: Page, el: string | ElementHandle | Locator): Promise { 19 | el = await getEl(page, el) 20 | return el.evaluate((el) => getComputedStyle(el as Element)) 21 | } 22 | 23 | export const getClassName = async (page: Page, el: string | ElementHandle | Locator): Promise => { 24 | el = await getEl(page, el) 25 | return el.evaluate((el) => (el as Element).className) 26 | } 27 | -------------------------------------------------------------------------------- /packages/panda-plugins/__tests__/scenarios/restrict-styled-props.test.tsx: -------------------------------------------------------------------------------- 1 | import { test } from 'vitest' 2 | import { styled } from './styled-system-restrict-styled-props/jsx' 3 | 4 | test('runtime', () => { 5 | const Button = styled('button', { 6 | base: { 7 | color: 'red.200', 8 | }, 9 | props: ['color', 'bg', 'css'], 10 | }) 11 | 12 | const Basic = styled('div', { 13 | base: { 14 | color: 'red.200', 15 | }, 16 | }) 17 | 18 | function App() { 19 | return ( 20 | <> 21 | 31 | 37 | basic 38 | 39 | 40 | ) 41 | } 42 | }) 43 | -------------------------------------------------------------------------------- /website/app/components/github-icon.tsx: -------------------------------------------------------------------------------- 1 | import type { ComponentPropsWithoutRef } from 'react' 2 | 3 | export const GithubIcon = (props: ComponentPropsWithoutRef<'svg'>) => ( 4 | 5 | 6 | 7 | ) 8 | -------------------------------------------------------------------------------- /packages/define-theme/sandbox/preset-base/utilities/display.ts: -------------------------------------------------------------------------------- 1 | import type { UtilityConfig } from '@pandacss/types' 2 | 3 | export const display = { 4 | display: { 5 | className: 'd', 6 | }, 7 | 8 | hideFrom: { 9 | className: 'hide', 10 | values: 'breakpoints', 11 | transform(value, { raw, token }) { 12 | const bp = token.raw(`breakpoints.${raw}`) 13 | const media = bp ? `@breakpoint ${raw}` : `@media screen and (min-width: ${value})` 14 | return { 15 | [media]: { 16 | display: 'none', 17 | }, 18 | } 19 | }, 20 | }, 21 | 22 | hideBelow: { 23 | className: 'show', 24 | values: 'breakpoints', 25 | transform(value, { raw, token }) { 26 | const bp = token.raw(`breakpoints.${raw}`) 27 | const media = bp ? `@breakpoint ${raw}Down` : `@media screen and (max-width: ${value})` 28 | return { 29 | [media]: { 30 | display: 'none', 31 | }, 32 | } 33 | }, 34 | }, 35 | } as const satisfies UtilityConfig 36 | -------------------------------------------------------------------------------- /examples/unplugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example-unplugin", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "tsc && vite build", 9 | "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "@pandabox/unplugin": "0.1.2", 14 | "react": "^18.2.0", 15 | "react-dom": "^18.2.0" 16 | }, 17 | "devDependencies": { 18 | "@pandacss/dev": "^0.36.1", 19 | "@types/react": "^18.2.66", 20 | "@types/react-dom": "^18.2.22", 21 | "@typescript-eslint/eslint-plugin": "^7.2.0", 22 | "@typescript-eslint/parser": "^7.2.0", 23 | "@vitejs/plugin-react": "^4.2.1", 24 | "@vitejs/plugin-react-swc": "^3.6.0", 25 | "eslint": "^8.57.0", 26 | "eslint-plugin-react-hooks": "^4.6.0", 27 | "eslint-plugin-react-refresh": "^0.4.6", 28 | "typescript": "^5.2.2", 29 | "vite": "^5.2.0", 30 | "vite-plugin-inspect": "^0.8.3" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /packages/postcss-plugins/src/remove-unused-keyframes.ts: -------------------------------------------------------------------------------- 1 | import type { TransformCallback } from 'postcss' 2 | 3 | export const removeUnusedKeyframes: TransformCallback = (root) => { 4 | // Store all keyframes and their usage status 5 | const keyframes = new Map() 6 | 7 | root.walk((node) => { 8 | if (node.type === 'atrule' && node.name === 'keyframes') { 9 | // Record the keyframe and mark it as unused 10 | keyframes.set(node.params, false) 11 | } else if (node.type === 'decl') { 12 | const decl = node 13 | const animationName = decl.prop === 'animation' ? decl.value.split(' ')[0] : decl.value 14 | 15 | if ((decl.prop === 'animation' || decl.prop === 'animation-name') && keyframes.has(animationName)) { 16 | // Mark the keyframe as used 17 | keyframes.set(animationName, true) 18 | } 19 | } 20 | }) 21 | 22 | // Remove unused keyframes 23 | root.walkAtRules('keyframes', (rule) => { 24 | if (keyframes.get(rule.params) === false) { 25 | rule.remove() 26 | } 27 | }) 28 | } 29 | -------------------------------------------------------------------------------- /examples/solid-start-unplugin/README.md: -------------------------------------------------------------------------------- 1 | # SolidStart 2 | 3 | Everything you need to build a Solid project, powered by [`solid-start`](https://start.solidjs.com); 4 | 5 | ## Creating a project 6 | 7 | ```bash 8 | # create a new project in the current directory 9 | npm init solid@latest 10 | 11 | # create a new project in my-app 12 | npm init solid@latest my-app 13 | ``` 14 | 15 | ## Developing 16 | 17 | Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server: 18 | 19 | ```bash 20 | npm run dev 21 | 22 | # or start the server and open the app in a new browser tab 23 | npm run dev -- --open 24 | ``` 25 | 26 | ## Building 27 | 28 | Solid apps are built with _presets_, which optimise your project for deployment to different environments. 29 | 30 | By default, `npm run build` will generate a Node app that you can run with `npm start`. To use a different preset, add it to the `devDependencies` in `package.json` and specify in your `app.config.js`. 31 | 32 | ## This project was created with the [Solid CLI](https://solid-cli.netlify.app) 33 | -------------------------------------------------------------------------------- /packages/define-theme/sandbox/preset-panda/spacing.ts: -------------------------------------------------------------------------------- 1 | export const spacing = { 2 | 0: { value: '0rem' }, 3 | 0.5: { value: '0.125rem' }, 4 | 1: { value: '0.25rem' }, 5 | 1.5: { value: '0.375rem' }, 6 | 2: { value: '0.5rem' }, 7 | 2.5: { value: '0.625rem' }, 8 | 3: { value: '0.75rem' }, 9 | 3.5: { value: '0.875rem' }, 10 | 4: { value: '1rem' }, 11 | 5: { value: '1.25rem' }, 12 | 6: { value: '1.5rem' }, 13 | 7: { value: '1.75rem' }, 14 | 8: { value: '2rem' }, 15 | 9: { value: '2.25rem' }, 16 | 10: { value: '2.5rem' }, 17 | 11: { value: '2.75rem' }, 18 | 12: { value: '3rem' }, 19 | 14: { value: '3.5rem' }, 20 | 16: { value: '4rem' }, 21 | 20: { value: '5rem' }, 22 | 24: { value: '6rem' }, 23 | 28: { value: '7rem' }, 24 | 32: { value: '8rem' }, 25 | 36: { value: '9rem' }, 26 | 40: { value: '10rem' }, 27 | 44: { value: '11rem' }, 28 | 48: { value: '12rem' }, 29 | 52: { value: '13rem' }, 30 | 56: { value: '14rem' }, 31 | 60: { value: '15rem' }, 32 | 64: { value: '16rem' }, 33 | 72: { value: '18rem' }, 34 | 80: { value: '20rem' }, 35 | 96: { value: '24rem' }, 36 | } 37 | -------------------------------------------------------------------------------- /website/app/components/icon-button.tsx: -------------------------------------------------------------------------------- 1 | import { css, cx } from '#styled-system/css' 2 | import type { SystemStyleObject } from '#styled-system/types' 3 | 4 | interface IconButtonProps extends React.ButtonHTMLAttributes { 5 | children: React.ReactNode 6 | css?: SystemStyleObject 7 | } 8 | 9 | export function IconButton(props: IconButtonProps) { 10 | const { children, className, css: cssProp, ...rest } = props 11 | return ( 12 | 15 | ) 16 | } 17 | 18 | export const iconButton = css.raw({ 19 | colorPalette: 'gray', 20 | display: 'flex', 21 | position: 'relative', 22 | justifyContent: 'center', 23 | alignItems: 'center', 24 | borderRadius: 'md', 25 | w: '40px', 26 | h: '40px', 27 | bg: { base: 'gray.100', _dark: 'gray.700' }, 28 | transition: 'colors', 29 | transitionDuration: '100ms', 30 | cursor: 'pointer', 31 | _hover: { 32 | color: 'white', 33 | bg: 'colorPalette.400', 34 | _dark: { 35 | bg: 'colorPalette.600', 36 | }, 37 | }, 38 | }) 39 | -------------------------------------------------------------------------------- /packages/panda-plugins/__tests__/scenarios/missing-css-warnings.test.ts: -------------------------------------------------------------------------------- 1 | import { expect, test, vi } from 'vitest' 2 | import { css } from './styled-system-missing-css-warnings/css' 3 | 4 | test('runtime', () => { 5 | const spy = vi.spyOn(console, 'error') 6 | 7 | const styleSheet = document.createElement('style') 8 | styleSheet.appendChild( 9 | document.createTextNode(` 10 | .fs_456px { 11 | font-size: 456px; 12 | }`), 13 | ) 14 | document.head.appendChild(styleSheet) 15 | 16 | expect(css({ fontSize: '123px' })).toMatchInlineSnapshot(`"fs_123px"`) 17 | expect(css({ fontSize: '456px', color: 'red' })).toMatchInlineSnapshot(`"fs_456px text_red"`) 18 | 19 | expect(console.error).toHaveBeenCalledWith('No matching CSS rule found for "fs_123px"') 20 | expect(console.error).not.toHaveBeenCalledWith('No matching CSS rule found for "fs_456px"') 21 | 22 | expect(spy.mock.calls).toMatchInlineSnapshot(` 23 | [ 24 | [ 25 | "No matching CSS rule found for "fs_123px"", 26 | ], 27 | [ 28 | "No matching CSS rule found for "text_red"", 29 | ], 30 | ] 31 | `) 32 | }) 33 | -------------------------------------------------------------------------------- /packages/unplugin-panda-macro/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @pandabox/unplugin-panda-macro 2 | 3 | ## 0.0.4 4 | 5 | ### Patch Changes 6 | 7 | - 4af7ef7: Fix an issue where some unrelated components from Panda would be transformed due to having the same name as some Panda components (JSX Patterns like Stack) 8 | - 25fed76: Update to panda 0.36.1 9 | 10 | ## 0.0.3 11 | 12 | ### Patch Changes 13 | 14 | - Updated dependencies [91b4f3a] 15 | - @pandabox/postcss-plugins@0.0.2 16 | 17 | ## 0.0.2 18 | 19 | ### Patch Changes 20 | 21 | - e99bf0e: Allow only inlining macro imports 22 | 23 | ```ts 24 | import { css } from "../styled-system/css" with { type: "macro" }; 25 | // ^^^^^^^^^^^^^^^^^^^^ 26 | // without this, the plugin will not transform the `css` usage 27 | 28 | const className = css({ 29 | display: "flex", 30 | flexDirection: "column", 31 | color: "red.300", 32 | }); 33 | // -> `const className = 'd_flex flex_column text_red.300'` 34 | ``` 35 | 36 | ## 0.0.1 37 | 38 | ### Patch Changes 39 | 40 | - ed8bfb4: initial release 41 | - Updated dependencies [ed8bfb4] 42 | - @pandabox/postcss-plugins@0.0.1 43 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | concurrency: ${{ github.workflow }}-${{ github.ref }} 9 | 10 | jobs: 11 | release: 12 | name: Release 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: Checkout Repo 16 | uses: actions/checkout@v4 17 | 18 | - name: Setup Node.js 20.x 19 | uses: actions/setup-node@v4 20 | with: 21 | node-version: 20.x 22 | 23 | - name: Install pnpm 24 | uses: pnpm/action-setup@v3 25 | with: 26 | version: 8 27 | 28 | - name: Install dependencies 29 | run: pnpm install --frozen-lockfile --ignore-scripts 30 | 31 | - name: Build 32 | run: pnpm build 33 | 34 | - name: Typecheck 35 | run: pnpm typecheck 36 | 37 | - name: Tests 38 | run: pnpm test 39 | 40 | - name: Create Release Pull Request or Publish to npm 41 | id: changesets 42 | uses: changesets/action@v1 43 | with: 44 | publish: pnpm release 45 | env: 46 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 47 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 48 | -------------------------------------------------------------------------------- /packages/utils/src/assign-inline-vars.ts: -------------------------------------------------------------------------------- 1 | import { traverse } from '@pandacss/shared' 2 | import { type TokenCategory } from '@pandacss/types' 3 | import { cssVar, type CssVarsOptions } from './css-var' 4 | 5 | interface TokenRecord extends Record> {} 6 | 7 | export type ToTokenRecord> = { 8 | [Category in TokenCategory]-?: { 9 | [TokenName in TTokens[Category]]?: number | string 10 | } 11 | } 12 | 13 | export const assignInlineVars = ( 14 | userVars?: Partial, 15 | options?: CssVarsOptions & { separator?: string }, 16 | ) => { 17 | const vars = {} as TokenRecord 18 | 19 | for (const [category, tokens] of Object.entries(userVars ?? {})) { 20 | traverse( 21 | tokens, 22 | ({ value, path }) => { 23 | if (typeof value === 'string' || typeof value === 'number') { 24 | const cssVarRef = cssVar.create(category + '-' + path, options).var 25 | vars[cssVarRef] = value as any 26 | } 27 | }, 28 | { separator: options?.separator ?? '-' }, 29 | ) 30 | } 31 | 32 | return vars as Record 33 | } 34 | -------------------------------------------------------------------------------- /packages/define-theme/sandbox/preset-base/utilities/helpers.ts: -------------------------------------------------------------------------------- 1 | import type { UtilityConfig } from '@pandacss/types' 2 | 3 | const srMapping: Record = { 4 | true: { 5 | position: 'absolute', 6 | width: '1px', 7 | height: '1px', 8 | padding: '0', 9 | margin: '-1px', 10 | overflow: 'hidden', 11 | clip: 'rect(0, 0, 0, 0)', 12 | whiteSpace: 'nowrap', 13 | borderWidth: '0', 14 | }, 15 | false: { 16 | position: 'static', 17 | width: 'auto', 18 | height: 'auto', 19 | padding: '0', 20 | margin: '0', 21 | overflow: 'visible', 22 | clip: 'auto', 23 | whiteSpace: 'normal', 24 | }, 25 | } 26 | 27 | export const helpers = { 28 | srOnly: { 29 | className: 'sr', 30 | values: { type: 'boolean' }, 31 | transform(value) { 32 | return srMapping[value] || {} 33 | }, 34 | }, 35 | debug: { 36 | className: 'debug', 37 | values: { type: 'boolean' }, 38 | transform(value) { 39 | if (!value) return {} 40 | return { 41 | outline: '1px solid blue !important', 42 | '&>*': { 43 | outline: '1px solid red !important', 44 | }, 45 | } 46 | }, 47 | }, 48 | } as const satisfies UtilityConfig 49 | -------------------------------------------------------------------------------- /sandbox/react/panda.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from '@pandacss/dev' 2 | import { 3 | pluginStrictTokensScope, 4 | pluginRemoveNegativeSpacing, 5 | pluginRemoveFeatures, 6 | pluginRestrictStyledProps, 7 | pluginStrictTokensRuntime, 8 | } from '@pandabox/panda-plugins' 9 | 10 | export default defineConfig({ 11 | // Whether to use css reset 12 | preflight: true, 13 | // shorthands: false, 14 | 15 | // Where to look for your css declarations 16 | include: ['./src/**/*.{js,jsx,ts,tsx}', './pages/**/*.{js,jsx,ts,tsx}'], 17 | 18 | // Files to exclude 19 | exclude: [], 20 | 21 | // Useful for theme customization 22 | theme: { 23 | extend: {}, 24 | }, 25 | 26 | // The output directory for your css system 27 | outdir: 'styled-system', 28 | 29 | // 30 | plugins: [ 31 | pluginStrictTokensScope({ categories: ['colors', 'spacing'] }), 32 | pluginStrictTokensRuntime({ categories: ['colors', 'spacing'] }), 33 | // pluginRemoveFeatures({ features: ['no-jsx', 'no-cva'] }), 34 | pluginRemoveNegativeSpacing({ spacingTokenType: true, tokenType: true }), 35 | pluginRestrictStyledProps(), 36 | ], 37 | jsxFramework: 'react', 38 | strictTokens: true, 39 | // outExtension: 'js', 40 | }) 41 | -------------------------------------------------------------------------------- /packages/codemods/__tests__/template-to-object-syntax.test.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from 'vitest' 2 | import { templateLiteralToObjectSyntax } from '../src/template-to-object-syntax' 3 | import { Project } from 'ts-morph' 4 | import outdent from 'outdent' 5 | 6 | const project = new Project() 7 | const createSourceFile = (content: string) => project.createSourceFile('app.tsx', content, { overwrite: true }) 8 | 9 | test('simple', () => { 10 | const sourceFile = createSourceFile(outdent` 11 | import { styled } from '../styled-system/jsx' 12 | 13 | const Button = styled.button\` 14 | background-color: #fff; 15 | border: 1px solid #000; 16 | color: #000; 17 | padding: 0.5rem 1rem; 18 | 19 | @media (min-width: 768px) { 20 | padding: 1rem 2rem; 21 | } 22 | \` 23 | `) 24 | 25 | expect(templateLiteralToObjectSyntax({ sourceFile }).code).toMatchInlineSnapshot(` 26 | "import { styled } from '../styled-system/jsx' 27 | 28 | const Button = styled('button', { base: { 29 | "backgroundColor": "#fff", 30 | "border": "1px solid #000", 31 | "color": "#000", 32 | "padding": "0.5rem 1rem", 33 | "@media (min-width: 768px)": { 34 | "padding": "1rem 2rem" 35 | } 36 | } })" 37 | `) 38 | }) 39 | -------------------------------------------------------------------------------- /packages/define-theme/sandbox/token-paths.ts: -------------------------------------------------------------------------------- 1 | import type { TokenPaths } from '../src/define-theme' 2 | 3 | type ExampleInput = { 4 | blue: { 5 | 500: { value: '#0000ff' } 6 | } 7 | primary: { 8 | value: 'red' 9 | } 10 | text: { 11 | DEFAULT: { value: 'xxx' } 12 | foreground: { value: 'xxx' } 13 | background: { value: 'xxx' } 14 | heading: { 15 | DEFAULT: { value: 'xxx' } 16 | subheading: { value: 'xxx' } 17 | nested: { 18 | DEFAULT: { value: 'xxx' } 19 | very: { 20 | DEFAULT: { value: 'xxx' } 21 | deep: { value: 'xxx' } 22 | } 23 | } 24 | } 25 | } 26 | } 27 | type ExamplePaths = TokenPaths 28 | // ^? 29 | 30 | // type ExamplePaths = "blue.500" | "primary" | "text.background" | "text.foreground" | "text.heading.subheading" | "text.heading.nested.very.deep" 31 | // type ExamplePaths = "blue" | "blue.500" | "primary" | "text" | "text.background" | "text.foreground" | "text.heading" | "text.heading.subheading" | "text.heading.nested" | "text.heading.nested.very" | "text.heading.nested.very.deep" 32 | // "blue.500" | "primary" | "text" | "text.background" | "text.foreground" | "text.heading" | "text.heading.subheading" | "text.heading.nested" | "text.heading.nested.very" | "text.heading.nested.very.deep" 33 | -------------------------------------------------------------------------------- /packages/define-theme/src/runtime.ts: -------------------------------------------------------------------------------- 1 | import deepmerge from 'lodash.merge' 2 | 3 | export class ThemeBuilderImpl { 4 | _conditions: any 5 | _breakpoints: any 6 | _tokens: any 7 | _semanticTokens: any 8 | _utilities: any 9 | _textStyles: any 10 | 11 | constructor(public _options: any = {}) {} 12 | 13 | conditions(defs: any) { 14 | this._conditions = deepmerge(this._conditions ?? {}, defs) 15 | return this 16 | } 17 | 18 | breakpoints(defs: any) { 19 | this._breakpoints = deepmerge(this._breakpoints ?? {}, defs) 20 | return this 21 | } 22 | 23 | tokens(tokens: any) { 24 | this._tokens = deepmerge(this._tokens ?? {}, tokens) 25 | return this 26 | } 27 | 28 | semanticTokens(tokens: any) { 29 | this._semanticTokens = deepmerge(this._semanticTokens ?? {}, tokens) 30 | return this 31 | } 32 | 33 | utilities(utilities: any) { 34 | this._utilities = deepmerge(this._utilities ?? {}, utilities) 35 | return this 36 | } 37 | 38 | textStyles(textStyles: any) { 39 | this._textStyles = deepmerge(this._textStyles ?? {}, textStyles) 40 | return this 41 | } 42 | 43 | build() { 44 | return new ThemeConfigImpl() 45 | } 46 | } 47 | 48 | const identity = (x: any) => x 49 | class ThemeConfigImpl { 50 | defineRecipe = identity 51 | defineStyles = identity 52 | } 53 | -------------------------------------------------------------------------------- /packages/define-theme/sandbox/preset-base/utilities/divide.ts: -------------------------------------------------------------------------------- 1 | import type { UtilityConfig } from '@pandacss/types' 2 | 3 | export const divide = { 4 | divideX: { 5 | className: 'divide-x', 6 | values: { type: 'string' }, 7 | transform(value) { 8 | return { 9 | '& > :not([hidden]) ~ :not([hidden])': { 10 | borderInlineStartWidth: value, 11 | borderInlineEndWidth: '0px', 12 | }, 13 | } 14 | }, 15 | }, 16 | divideY: { 17 | className: 'divide-y', 18 | values: { type: 'string' }, 19 | transform(value) { 20 | return { 21 | '& > :not([hidden]) ~ :not([hidden])': { 22 | borderTopWidth: value, 23 | borderBottomWidth: '0px', 24 | }, 25 | } 26 | }, 27 | }, 28 | divideColor: { 29 | className: 'divide', 30 | values: 'colors', 31 | transform(value) { 32 | return { 33 | '& > :not([hidden]) ~ :not([hidden])': { 34 | borderColor: value, 35 | }, 36 | } 37 | }, 38 | }, 39 | divideStyle: { 40 | className: 'divide', 41 | property: 'borderStyle', 42 | transform(value) { 43 | return { 44 | '& > :not([hidden]) ~ :not([hidden])': { 45 | borderStyle: value, 46 | }, 47 | } 48 | }, 49 | }, 50 | } as const satisfies UtilityConfig 51 | -------------------------------------------------------------------------------- /packages/postcss-plugins/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@pandabox/postcss-plugins", 3 | "version": "0.0.2", 4 | "exports": { 5 | ".": { 6 | "source": "./src/index.ts", 7 | "types": "./dist/index.d.ts", 8 | "import": { 9 | "types": "./dist/index.d.mts", 10 | "default": "./dist/index.mjs" 11 | }, 12 | "require": { 13 | "types": "./dist/index.d.ts", 14 | "default": "./dist/index.js" 15 | } 16 | } 17 | }, 18 | "scripts": { 19 | "build": "tsup", 20 | "dev": "tsup --watch src", 21 | "typecheck": "tsc --noEmit", 22 | "test": "vitest" 23 | }, 24 | "homepage": "https://astahmer.dev", 25 | "repository": { 26 | "type": "git", 27 | "url": "git+https://github.com/astahmer/pandabox.git", 28 | "directory": "packages/postcss-plugins" 29 | }, 30 | "author": "Alexandre Stahmer", 31 | "publishConfig": { 32 | "access": "public" 33 | }, 34 | "sideEffects": false, 35 | "files": [ 36 | "src", 37 | "dist" 38 | ], 39 | "keywords": [ 40 | "pandacss", 41 | "pandabox", 42 | "panda", 43 | "postcss", 44 | "plugins", 45 | "typesafety", 46 | "typescript" 47 | ], 48 | "peerDependencies": { 49 | "postcss": "^8.4.35" 50 | }, 51 | "devDependencies": { 52 | "tsup": "^8.0.2", 53 | "vitest": "^1.3.1" 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /website/app/components/switch.tsx: -------------------------------------------------------------------------------- 1 | import { css, cx } from '#styled-system/css' 2 | import { splitCssProps } from '#styled-system/jsx' 3 | import { switchRecipe, type SwitchRecipeVariantProps } from '#styled-system/recipes' 4 | import type { Assign, JsxStyleProps } from '#styled-system/types' 5 | import { Switch as ArkSwitch, type SwitchRootProps } from '@ark-ui/react/switch' 6 | import { type ReactNode } from 'react' 7 | 8 | export interface SwitchProps extends Assign, SwitchRecipeVariantProps { 9 | children?: ReactNode 10 | } 11 | 12 | export const Switch = (props: SwitchProps) => { 13 | const [variantProps, switchProps] = switchRecipe.splitVariantProps(props) 14 | const [cssProps, localProps] = splitCssProps(switchProps) 15 | const { css: cssProp, ...restCssProps } = cssProps 16 | const { children, className, ...rootProps } = localProps 17 | const styles = switchRecipe(variantProps) 18 | 19 | return ( 20 | 21 | 22 | 23 | 24 | {children && {children}} 25 | 26 | ) 27 | } 28 | 29 | // Switch.displayName = 'Switch' 30 | -------------------------------------------------------------------------------- /packages/utils/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@pandabox/utils", 3 | "version": "0.0.5", 4 | "description": "A bunch of utilities", 5 | "exports": { 6 | ".": { 7 | "source": "./src/index.ts", 8 | "types": "./dist/index.d.ts", 9 | "import": { 10 | "types": "./dist/index.d.mts", 11 | "default": "./dist/index.mjs" 12 | }, 13 | "require": { 14 | "types": "./dist/index.d.ts", 15 | "default": "./dist/index.js" 16 | } 17 | } 18 | }, 19 | "scripts": { 20 | "build": "tsup", 21 | "dev": "tsup --watch src", 22 | "test": "vitest", 23 | "typecheck": "tsc --noEmit" 24 | }, 25 | "dependencies": { 26 | "@pandacss/shared": "^0.36.1", 27 | "@pandacss/types": "^0.36.1" 28 | }, 29 | "devDependencies": { 30 | "tsup": "^8.0.2", 31 | "vitest": "^1.3.1" 32 | }, 33 | "homepage": "https://astahmer.dev", 34 | "repository": { 35 | "type": "git", 36 | "url": "git+https://github.com/astahmer/pandabox.git", 37 | "directory": "packages/utils" 38 | }, 39 | "author": "Alexandre Stahmer", 40 | "publishConfig": { 41 | "access": "public" 42 | }, 43 | "sideEffects": false, 44 | "files": [ 45 | "src", 46 | "dist" 47 | ], 48 | "keywords": [ 49 | "pandacss", 50 | "pandabox", 51 | "panda", 52 | "utils", 53 | "typesafety", 54 | "typescript" 55 | ] 56 | } 57 | -------------------------------------------------------------------------------- /packages/panda-plugins/src/minimal-setup.ts: -------------------------------------------------------------------------------- 1 | import type { PandaPlugin } from '@pandacss/types' 2 | import { transformFeatures, type RemoveFeaturesOptions } from './remove-features' 3 | 4 | /** 5 | * Enables a minimal setup for Panda CSS. 6 | * @see https://panda-css.com/docs/guides/minimal-setup 7 | * 8 | * - Removes the `@pandacss/preset-base` preset with `eject: true` 9 | * @see https://panda-css.com/docs/references/config#eject 10 | * 11 | * - Removes the built-in `@pandacss/preset-panda` by setting `presets: []` if not defined 12 | * @see https://panda-css.com/docs/customization/presets#which-panda-presets-will-be-included- 13 | * 14 | * - Allows removing features from the `styled-system` generated folder 15 | * 16 | */ 17 | export const pluginMinimalSetup = (options: RemoveFeaturesOptions): PandaPlugin => { 18 | return { 19 | name: 'minimal-setup', 20 | hooks: { 21 | 'config:resolved': (args) => { 22 | // Eject `@pandacss/preset-base` 23 | args.config.eject = true 24 | 25 | // If the user has not defined presets, we need to define it as an empty array 26 | // to remove the built-in `@pandacss/preset-panda` 27 | if (!args.config.presets) { 28 | args.config.presets = [] 29 | } 30 | }, 31 | 'codegen:prepare': (args) => { 32 | return transformFeatures(args, options) 33 | }, 34 | }, 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /packages/presets/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@pandabox/presets", 3 | "version": "0.0.2", 4 | "exports": { 5 | ".": { 6 | "source": "./src/index.ts", 7 | "types": "./dist/index.d.ts", 8 | "import": { 9 | "types": "./dist/index.d.mts", 10 | "default": "./dist/index.mjs" 11 | }, 12 | "require": { 13 | "types": "./dist/index.d.ts", 14 | "default": "./dist/index.js" 15 | } 16 | } 17 | }, 18 | "scripts": { 19 | "build": "tsup", 20 | "dev": "tsup --watch src", 21 | "typecheck": "tsc --noEmit", 22 | "test": "vitest" 23 | }, 24 | "dependencies": { 25 | "utopia-core": "^1.3.0" 26 | }, 27 | "devDependencies": { 28 | "@pandacss/dev": "^0.36.1", 29 | "@pandacss/types": "^0.36.1", 30 | "tsup": "^8.0.2", 31 | "vitest": "^1.3.1" 32 | }, 33 | "homepage": "https://astahmer.dev", 34 | "repository": { 35 | "type": "git", 36 | "url": "git+https://github.com/astahmer/pandabox.git", 37 | "directory": "packages/presets" 38 | }, 39 | "author": "Alexandre Stahmer", 40 | "publishConfig": { 41 | "access": "public" 42 | }, 43 | "sideEffects": false, 44 | "files": [ 45 | "src", 46 | "dist" 47 | ], 48 | "keywords": [ 49 | "pandacss", 50 | "pandabox", 51 | "panda", 52 | "panda", 53 | "presets", 54 | "typesafety", 55 | "typescript" 56 | ] 57 | } 58 | -------------------------------------------------------------------------------- /packages/panda-plugins/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import type { UserConfig } from 'vitest' 2 | 3 | const options: UserConfig = { 4 | 'missing-css-warnings': { 5 | test: { 6 | environment: 'happy-dom', 7 | include: ['**/__tests__/scenarios/missing-css-warnings.{test,spec}.{j,t}s?(x)'], 8 | }, 9 | }, 10 | 'remove-negative-spacing': { 11 | test: { 12 | typecheck: { 13 | enabled: true, 14 | }, 15 | include: ['**/__tests__/scenarios/remove-negative-spacing.{test,spec}.{j,t}s?(x)'], 16 | }, 17 | }, 18 | 'strict-tokens-scope': { 19 | test: { 20 | typecheck: { 21 | enabled: true, 22 | }, 23 | include: ['**/__tests__/scenarios/strict-tokens-scope.{test,spec}.{j,t}s?(x)'], 24 | }, 25 | }, 26 | 'strict-tokens-runtime': { 27 | test: { 28 | typecheck: { 29 | enabled: true, 30 | }, 31 | include: ['**/__tests__/scenarios/strict-tokens-runtime.{test,spec}.{j,t}s?(x)'], 32 | }, 33 | }, 34 | 'restrict-styled-props': { 35 | test: { 36 | typecheck: { 37 | enabled: true, 38 | }, 39 | include: ['**/__tests__/scenarios/restrict-styled-props.{test,spec}.{j,t}s?(x)'], 40 | }, 41 | }, 42 | } as Record 43 | 44 | const mode = process.env.MODE ?? 'missing-css-warnings' 45 | const config = (options as any)[mode] 46 | console.log({ mode }) 47 | 48 | export default config 49 | -------------------------------------------------------------------------------- /packages/unplugin/e2e/test-utils.ts: -------------------------------------------------------------------------------- 1 | // https://github.com/vitejs/vite/blob/17d71ecf74bdcb16fd1d80c13106a28f804c325f/playground/test-utils.ts 2 | 3 | import fs from 'node:fs' 4 | import path from 'node:path' 5 | import { testDir } from './test-setup' 6 | 7 | const timeout = (n: number) => new Promise((r) => setTimeout(r, n)) 8 | 9 | export function readFile(filename: string): string { 10 | return fs.readFileSync(path.resolve(testDir, filename), 'utf-8') 11 | } 12 | 13 | export function editFile(filename: string, replacer: (str: string) => string): void { 14 | filename = path.resolve(testDir, filename) 15 | const content = fs.readFileSync(filename, 'utf-8') 16 | const modified = replacer(content) 17 | fs.writeFileSync(filename, modified) 18 | } 19 | 20 | export function addFile(filename: string, content: string): void { 21 | fs.writeFileSync(path.resolve(testDir, filename), content) 22 | } 23 | 24 | export function removeFile(filename: string): void { 25 | fs.unlinkSync(path.resolve(testDir, filename)) 26 | } 27 | 28 | /** 29 | * Retry `func` until it does not throw error. 30 | */ 31 | export async function withRetry(func: () => Promise): Promise { 32 | const maxTries = process.env.CI ? 200 : 50 33 | for (let tries = 0; tries < maxTries; tries++) { 34 | try { 35 | await func() 36 | return 37 | } catch {} 38 | await timeout(50) 39 | } 40 | await func() 41 | } 42 | -------------------------------------------------------------------------------- /examples/unplugin/README.md: -------------------------------------------------------------------------------- 1 | # React + TypeScript + Vite 2 | 3 | This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. 4 | 5 | Currently, two official plugins are available: 6 | 7 | - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh 8 | - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh 9 | 10 | ## Expanding the ESLint configuration 11 | 12 | If you are developing a production application, we recommend updating the configuration to enable type aware lint rules: 13 | 14 | - Configure the top-level `parserOptions` property like this: 15 | 16 | ```js 17 | export default { 18 | // other rules... 19 | parserOptions: { 20 | ecmaVersion: 'latest', 21 | sourceType: 'module', 22 | project: ['./tsconfig.json', './tsconfig.node.json'], 23 | tsconfigRootDir: __dirname, 24 | }, 25 | } 26 | ``` 27 | 28 | - Replace `plugin:@typescript-eslint/recommended` to `plugin:@typescript-eslint/recommended-type-checked` or `plugin:@typescript-eslint/strict-type-checked` 29 | - Optionally add `plugin:@typescript-eslint/stylistic-type-checked` 30 | - Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and add `plugin:react/recommended` & `plugin:react/jsx-runtime` to the `extends` list 31 | -------------------------------------------------------------------------------- /sandbox/react/README.md: -------------------------------------------------------------------------------- 1 | # React + TypeScript + Vite 2 | 3 | This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. 4 | 5 | Currently, two official plugins are available: 6 | 7 | - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh 8 | - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh 9 | 10 | ## Expanding the ESLint configuration 11 | 12 | If you are developing a production application, we recommend updating the configuration to enable type aware lint rules: 13 | 14 | - Configure the top-level `parserOptions` property like this: 15 | 16 | ```js 17 | export default { 18 | // other rules... 19 | parserOptions: { 20 | ecmaVersion: 'latest', 21 | sourceType: 'module', 22 | project: ['./tsconfig.json', './tsconfig.node.json'], 23 | tsconfigRootDir: __dirname, 24 | }, 25 | } 26 | ``` 27 | 28 | - Replace `plugin:@typescript-eslint/recommended` to `plugin:@typescript-eslint/recommended-type-checked` or `plugin:@typescript-eslint/strict-type-checked` 29 | - Optionally add `plugin:@typescript-eslint/stylistic-type-checked` 30 | - Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and add `plugin:react/recommended` & `plugin:react/jsx-runtime` to the `extends` list 31 | -------------------------------------------------------------------------------- /website/scripts/bundle-types.mts: -------------------------------------------------------------------------------- 1 | // import { generateDtsBundle } from 'dts-bundle-generator' 2 | import path from 'path' 3 | import fs from 'fs/promises' 4 | 5 | console.time('bundle-types') 6 | const __dirname = new URL('.', import.meta.url).pathname 7 | // const tsconfigPath = path.join(__dirname, '../tsconfig.json') 8 | const dts = (relative: string) => path.join(__dirname, '../node_modules/' + relative) 9 | 10 | const dtsFiles = { 11 | // ['@pandacss/dev']: dts('@pandacss/dev/dist/index.d.ts'), 12 | ['react']: dts('@types/react/index.d.ts'), 13 | } 14 | 15 | // console.log('Generating dts bundles...') 16 | // const bundledDts = generateDtsBundle([{ filePath: path.join(__dirname, 'panda-types.ts') }], { 17 | // preferredConfigPath: tsconfigPath, 18 | // }) 19 | 20 | const outdir = path.join(__dirname, '../dts/') 21 | console.log('Writing dts bundles in', outdir) 22 | 23 | await getOrCreateDir(outdir) 24 | // await fs.writeFile(outdir + '@pandacss/types'.replace('/', '_') + '.d.ts', bundledDts[0]) 25 | await Promise.all( 26 | Object.keys(dtsFiles).map((name) => { 27 | console.log('Copying', name) 28 | return fs.copyFile((dtsFiles as any)[name], outdir + name.replace('/', '_') + '.d.ts') 29 | }), 30 | ) 31 | 32 | console.log('Done !') 33 | console.timeEnd('bundle-types') 34 | 35 | async function getOrCreateDir(dir: string) { 36 | try { 37 | await fs.mkdir(dir) 38 | } catch (e) { 39 | // ignore 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /sandbox/react/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/unplugin/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/define-theme/sandbox/preset-base/utilities/polyfill.ts: -------------------------------------------------------------------------------- 1 | import type { UtilityConfig } from '@pandacss/types' 2 | 3 | export const polyfill = { 4 | appearance: { 5 | className: 'appearance', 6 | transform(value) { 7 | return { appearance: value, WebkitAppearance: value } 8 | }, 9 | }, 10 | backfaceVisibility: { 11 | className: 'backface', 12 | transform(value) { 13 | return { backfaceVisibility: value, WebkitBackfaceVisibility: value } 14 | }, 15 | }, 16 | clipPath: { 17 | className: 'clip-path', 18 | transform(value) { 19 | return { clipPath: value, WebkitClipPath: value } 20 | }, 21 | }, 22 | hyphens: { 23 | className: 'hyphens', 24 | transform(value) { 25 | return { hyphens: value, WebkitHyphens: value } 26 | }, 27 | }, 28 | mask: { 29 | className: 'mask', 30 | transform(value) { 31 | return { mask: value, WebkitMask: value } 32 | }, 33 | }, 34 | maskImage: { 35 | className: 'mask-image', 36 | transform(value) { 37 | return { maskImage: value, WebkitMaskImage: value } 38 | }, 39 | }, 40 | maskSize: { 41 | className: 'mask-size', 42 | transform(value) { 43 | return { maskSize: value, WebkitMaskSize: value } 44 | }, 45 | }, 46 | textSizeAdjust: { 47 | className: 'text-size-adjust', 48 | transform(value) { 49 | return { textSizeAdjust: value, WebkitTextSizeAdjust: value } 50 | }, 51 | }, 52 | } as const satisfies UtilityConfig 53 | -------------------------------------------------------------------------------- /packages/panda-plugins/README.md: -------------------------------------------------------------------------------- 1 | # @pandabox/panda-plugins 2 | 3 | - `missing-css-warnings` - Logs a warning message when a CSS rule was used at runtime but couldn't be statically 4 | extracted 5 | - `strict-tokens-scope` - Enforce `strictTokens` only for a set of `TokenCategory` or style props 6 | - `strict-tokens-runtime` - Enforce `strictTokens` at runtime, optionally scope this behaviour to a set of 7 | `TokenCategory` or style props 8 | - `restrict-styled-props` - Adds a `props` on the `styled` JSX Factory to restrict the props that can be passed to the 9 | component 10 | - `remove-negative-spacing` - Removes negative spacing tokens 11 | - `remove-features` - Removes features from the `styled-system` 12 | - `minimal-setup` - Removes the built-in presets and allow removing features from the `styled-system` 13 | 14 | ## Installation 15 | 16 | ```bash 17 | pnpm add -D @pandabox/panda-plugins 18 | ``` 19 | 20 | ## Usage 21 | 22 | ```tsx 23 | import { defineConfig } from '@pandacss/dev' 24 | import { pluginStrictTokensScope, pluginRemoveNegativeSpacing, pluginRemoveFeatures } from '@pandabox/panda-plugins' 25 | 26 | export default defineConfig({ 27 | // ... 28 | strictTokens: true, 29 | // can also be used together with 30 | // strictPropertyValues: true, 31 | // 32 | plugins: [ 33 | pluginStrictTokensScope({ categories: ['colors', 'spacing'] }), 34 | pluginRemoveFeatures({ features: ['no-jsx', 'no-cva'] }), 35 | pluginRemoveNegativeSpacing({ spacingTokenType: true, tokenType: true }), 36 | ], 37 | }) 38 | ``` 39 | -------------------------------------------------------------------------------- /packages/unplugin/__tests__/samples/full.tsx: -------------------------------------------------------------------------------- 1 | import { css, cva } from '../styled-system/css' 2 | import { center } from '../styled-system/patterns' 3 | import { button } from '../styled-system/recipes' 4 | import 'virtual:panda.css' 5 | 6 | const overrides = css.raw({ 7 | bg: 'green.100', 8 | }) 9 | 10 | const atomicRecipe = cva({ 11 | base: { 12 | display: 'flex', 13 | }, 14 | variants: { 15 | visual: { 16 | solid: { bg: 'red.200', color: 'white' }, 17 | outline: { borderWidth: '1px', borderColor: 'red.200' }, 18 | }, 19 | size: { 20 | sm: { padding: '4', fontSize: '12px' }, 21 | lg: { padding: '8', fontSize: '24px' }, 22 | }, 23 | }, 24 | }) 25 | 26 | export const App = () => { 27 | return ( 28 |
29 |
46 | 🐼 47 | Hello from Panda 48 |
49 |
Button
50 |
Atomic Button
51 |
52 | ) 53 | } 54 | -------------------------------------------------------------------------------- /sandbox/react/src/index.css: -------------------------------------------------------------------------------- 1 | @layer reset, base, tokens, recipes, utilities; 2 | 3 | :root { 4 | font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; 5 | line-height: 1.5; 6 | font-weight: 400; 7 | 8 | color-scheme: light dark; 9 | color: rgba(255, 255, 255, 0.87); 10 | background-color: #242424; 11 | 12 | font-synthesis: none; 13 | text-rendering: optimizeLegibility; 14 | -webkit-font-smoothing: antialiased; 15 | -moz-osx-font-smoothing: grayscale; 16 | } 17 | 18 | a { 19 | font-weight: 500; 20 | color: #646cff; 21 | text-decoration: inherit; 22 | } 23 | a:hover { 24 | color: #535bf2; 25 | } 26 | 27 | body { 28 | margin: 0; 29 | display: flex; 30 | place-items: center; 31 | min-width: 320px; 32 | min-height: 100vh; 33 | } 34 | 35 | h1 { 36 | font-size: 3.2em; 37 | line-height: 1.1; 38 | } 39 | 40 | button { 41 | border-radius: 8px; 42 | border: 1px solid transparent; 43 | padding: 0.6em 1.2em; 44 | font-size: 1em; 45 | font-weight: 500; 46 | font-family: inherit; 47 | background-color: #1a1a1a; 48 | cursor: pointer; 49 | transition: border-color 0.25s; 50 | } 51 | button:hover { 52 | border-color: #646cff; 53 | } 54 | button:focus, 55 | button:focus-visible { 56 | outline: 4px auto -webkit-focus-ring-color; 57 | } 58 | 59 | @media (prefers-color-scheme: light) { 60 | :root { 61 | color: #213547; 62 | background-color: #ffffff; 63 | } 64 | a:hover { 65 | color: #747bff; 66 | } 67 | button { 68 | background-color: #f9f9f9; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /packages/unplugin-panda-macro/__tests__/samples/full.tsx: -------------------------------------------------------------------------------- 1 | import { css, cva } from '../styled-system/css' 2 | import { center } from '../styled-system/patterns' 3 | import { button } from '../styled-system/recipes' 4 | import 'virtual:panda.css' 5 | 6 | const overrides = css.raw({ 7 | bg: 'green.100', 8 | }) 9 | 10 | const atomicRecipe = cva({ 11 | base: { 12 | display: 'flex', 13 | }, 14 | variants: { 15 | visual: { 16 | solid: { bg: 'red.200', color: 'white' }, 17 | outline: { borderWidth: '1px', borderColor: 'red.200' }, 18 | }, 19 | size: { 20 | sm: { padding: '4', fontSize: '12px' }, 21 | lg: { padding: '8', fontSize: '24px' }, 22 | }, 23 | }, 24 | }) 25 | 26 | export const App = () => { 27 | return ( 28 |
29 |
46 | 🐼 47 | Hello from Panda 48 |
49 |
Button
50 |
Atomic Button
51 |
52 | ) 53 | } 54 | -------------------------------------------------------------------------------- /packages/codemods/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@pandabox/codemods", 3 | "version": "0.0.1", 4 | "description": "A collection of codemods for Panda CSS", 5 | "exports": { 6 | ".": { 7 | "source": "./src/index.ts", 8 | "types": "./dist/index.d.ts", 9 | "import": { 10 | "types": "./dist/index.d.mts", 11 | "default": "./dist/index.mjs" 12 | }, 13 | "require": { 14 | "types": "./dist/index.d.ts", 15 | "default": "./dist/index.js" 16 | } 17 | } 18 | }, 19 | "scripts": { 20 | "build": "tsup", 21 | "dev": "tsup --watch src", 22 | "test": "vitest", 23 | "typecheck": "tsc --noEmit" 24 | }, 25 | "dependencies": { 26 | "magic-string": "0.30.7", 27 | "postcss": "^8.4.35", 28 | "postcss-js": "^4.0.1", 29 | "ts-morph": "21.0.1" 30 | }, 31 | "devDependencies": { 32 | "@types/postcss-js": "^4.0.4", 33 | "outdent": "^0.8.0", 34 | "tsup": "^8.0.2", 35 | "vitest": "^1.3.1" 36 | }, 37 | "homepage": "https://astahmer.dev", 38 | "repository": { 39 | "type": "git", 40 | "url": "git+https://github.com/astahmer/pandabox.git", 41 | "directory": "packages/codemods" 42 | }, 43 | "author": "Alexandre Stahmer", 44 | "publishConfig": { 45 | "access": "public" 46 | }, 47 | "sideEffects": false, 48 | "files": [ 49 | "src", 50 | "dist" 51 | ], 52 | "keywords": [ 53 | "pandacss", 54 | "pandabox", 55 | "panda", 56 | "codemod", 57 | "styled2panda", 58 | "typesafety", 59 | "typescript" 60 | ] 61 | } 62 | -------------------------------------------------------------------------------- /packages/define-theme/sandbox/preset-base/utilities/index.ts: -------------------------------------------------------------------------------- 1 | import { background } from './background' 2 | import { border } from './border' 3 | import { display } from './display' 4 | import { divide } from './divide' 5 | import { effects } from './effects' 6 | import { flexGrid } from './flex-and-grid' 7 | import { helpers } from './helpers' 8 | import { interactivity } from './interactivity' 9 | import { layout } from './layout' 10 | import { list } from './list' 11 | import { outline } from './outline' 12 | import { sizing } from './sizing' 13 | import { spacing } from './spacing' 14 | import { svg } from './svg' 15 | import { tables } from './tables' 16 | import { transforms } from './transforms' 17 | import { transitions } from './transitions' 18 | import { typography } from './typography' 19 | import { polyfill } from './polyfill' 20 | 21 | export const utilities = { 22 | ...layout, 23 | ...display, 24 | ...flexGrid, 25 | ...spacing, 26 | ...outline, 27 | ...divide, 28 | ...sizing, 29 | ...typography, 30 | ...list, 31 | ...background, 32 | ...border, 33 | ...effects, 34 | ...tables, 35 | ...transitions, 36 | ...transforms, 37 | ...interactivity, 38 | ...svg, 39 | ...helpers, 40 | ...polyfill, 41 | } 42 | 43 | export const utilitiesGroup = { 44 | layout, 45 | display, 46 | flexGrid, 47 | spacing, 48 | outline, 49 | divide, 50 | sizing, 51 | typography, 52 | list, 53 | background, 54 | border, 55 | effects, 56 | tables, 57 | transitions, 58 | transforms, 59 | interactivity, 60 | svg, 61 | helpers, 62 | polyfill, 63 | } 64 | -------------------------------------------------------------------------------- /examples/unplugin/panda.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from '@pandacss/dev' 2 | 3 | export default defineConfig({ 4 | // Whether to use css reset 5 | preflight: true, 6 | 7 | // Where to look for your css declarations 8 | include: ['./src/**/*.{js,jsx,ts,tsx}', './{App,main,minimal}*.{js,jsx,ts,tsx}'], 9 | 10 | // Files to exclude 11 | exclude: [], 12 | 13 | // Useful for theme customization 14 | theme: { 15 | extend: { 16 | recipes: { 17 | button: { 18 | className: 'button', 19 | description: 'The styles for the Button component', 20 | base: { 21 | display: 'flex', 22 | cursor: 'pointer', 23 | fontWeight: 'bold', 24 | }, 25 | variants: { 26 | visual: { 27 | funky: { bg: 'blue.200', color: 'slate.800' }, 28 | edgy: { border: '1px solid {colors.red.500}' }, 29 | }, 30 | size: { 31 | sm: { padding: '4', fontSize: '12px' }, 32 | lg: { padding: '8', fontSize: '40px' }, 33 | }, 34 | shape: { 35 | square: { borderRadius: '0' }, 36 | circle: { borderRadius: 'full' }, 37 | }, 38 | }, 39 | defaultVariants: { 40 | visual: 'funky', 41 | size: 'sm', 42 | shape: 'circle', 43 | }, 44 | }, 45 | }, 46 | }, 47 | }, 48 | 49 | // The output directory for your css system 50 | outdir: 'styled-system', 51 | 52 | // The JSX framework to use 53 | jsxFramework: 'react', 54 | }) 55 | -------------------------------------------------------------------------------- /examples/solid-start-unplugin/panda.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from '@pandacss/dev' 2 | 3 | export default defineConfig({ 4 | // Whether to use css reset 5 | preflight: true, 6 | 7 | // Where to look for your css declarations 8 | include: ['./src/**/*.{js,jsx,ts,tsx}', './{App,main,minimal}*.{js,jsx,ts,tsx}'], 9 | 10 | // Files to exclude 11 | exclude: [], 12 | 13 | // Useful for theme customization 14 | theme: { 15 | extend: { 16 | recipes: { 17 | button: { 18 | className: 'button', 19 | description: 'The styles for the Button component', 20 | base: { 21 | display: 'flex', 22 | cursor: 'pointer', 23 | fontWeight: 'bold', 24 | }, 25 | variants: { 26 | visual: { 27 | funky: { bg: 'blue.200', color: 'slate.800' }, 28 | edgy: { border: '1px solid {colors.red.500}' }, 29 | }, 30 | size: { 31 | sm: { padding: '4', fontSize: '12px' }, 32 | lg: { padding: '8', fontSize: '40px' }, 33 | }, 34 | shape: { 35 | square: { borderRadius: '0' }, 36 | circle: { borderRadius: 'full' }, 37 | }, 38 | }, 39 | defaultVariants: { 40 | visual: 'funky', 41 | size: 'sm', 42 | shape: 'circle', 43 | }, 44 | }, 45 | }, 46 | }, 47 | }, 48 | 49 | // The output directory for your css system 50 | outdir: 'styled-system', 51 | 52 | // The JSX framework to use 53 | jsxFramework: 'react', 54 | }) 55 | -------------------------------------------------------------------------------- /packages/unplugin/playground/panda.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from '@pandacss/dev' 2 | 3 | export default defineConfig({ 4 | // Whether to use css reset 5 | preflight: true, 6 | 7 | // Where to look for your css declarations 8 | include: ['./src/**/*.{js,jsx,ts,tsx}', './{App,main,minimal}*.{js,jsx,ts,tsx}'], 9 | 10 | // Files to exclude 11 | exclude: [], 12 | 13 | // Useful for theme customization 14 | theme: { 15 | extend: { 16 | recipes: { 17 | button: { 18 | className: 'button', 19 | description: 'The styles for the Button component', 20 | base: { 21 | display: 'flex', 22 | cursor: 'pointer', 23 | fontWeight: 'bold', 24 | }, 25 | variants: { 26 | visual: { 27 | funky: { bg: 'blue.200', color: 'slate.800' }, 28 | edgy: { border: '1px solid {colors.red.500}' }, 29 | }, 30 | size: { 31 | sm: { padding: '4', fontSize: '12px' }, 32 | lg: { padding: '8', fontSize: '40px' }, 33 | }, 34 | shape: { 35 | square: { borderRadius: '0' }, 36 | circle: { borderRadius: 'full' }, 37 | }, 38 | }, 39 | defaultVariants: { 40 | visual: 'funky', 41 | size: 'sm', 42 | shape: 'circle', 43 | }, 44 | }, 45 | }, 46 | }, 47 | }, 48 | 49 | // The output directory for your css system 50 | outdir: 'styled-system', 51 | 52 | // The JSX framework to use 53 | jsxFramework: 'react', 54 | }) 55 | -------------------------------------------------------------------------------- /packages/unplugin-panda-macro/.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Node template 3 | # Logs 4 | logs 5 | *.log 6 | npm-debug.log* 7 | yarn-debug.log* 8 | yarn-error.log* 9 | 10 | # Runtime data 11 | pids 12 | *.pid 13 | *.seed 14 | *.pid.lock 15 | 16 | # Directory for instrumented libs generated by jscoverage/JSCover 17 | lib-cov 18 | 19 | # Coverage directory used by tools like istanbul 20 | coverage 21 | 22 | # nyc test coverage 23 | .nyc_output 24 | 25 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 26 | .grunt 27 | 28 | # Bower dependency directory (https://bower.io/) 29 | bower_components 30 | 31 | # node-waf configuration 32 | .lock-wscript 33 | 34 | # Compiled binary addons (https://nodejs.org/api/addons.html) 35 | build/Release 36 | 37 | # Dependency directories 38 | node_modules/ 39 | jspm_packages/ 40 | 41 | # TypeScript v1 declaration files 42 | typings/ 43 | 44 | # Optional npm cache directory 45 | .npm 46 | 47 | # Optional eslint cache 48 | .eslintcache 49 | 50 | # Optional REPL history 51 | .node_repl_history 52 | 53 | # Output of 'npm pack' 54 | *.tgz 55 | 56 | # Yarn Integrity file 57 | .yarn-integrity 58 | 59 | # dotenv environment variables file 60 | .env 61 | 62 | # parcel-bundler cache (https://parceljs.org/) 63 | .cache 64 | 65 | # next.js build output 66 | .next 67 | 68 | # nuxt.js build output 69 | .nuxt 70 | 71 | # Nuxt generate 72 | dist 73 | 74 | # vuepress build output 75 | .vuepress/dist 76 | 77 | # Serverless directories 78 | .serverless 79 | 80 | # IDE 81 | .idea 82 | 83 | ## Panda 84 | styled-system 85 | styled-system-studio -------------------------------------------------------------------------------- /packages/unplugin-panda-macro/playground/panda.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from '@pandacss/dev' 2 | 3 | export default defineConfig({ 4 | // Whether to use css reset 5 | preflight: true, 6 | 7 | // Where to look for your css declarations 8 | include: ['./src/**/*.{js,jsx,ts,tsx}', './pages/**/*.{js,jsx,ts,tsx}'], 9 | 10 | // Files to exclude 11 | exclude: [], 12 | 13 | // Useful for theme customization 14 | theme: { 15 | extend: { 16 | recipes: { 17 | button: { 18 | className: 'button', 19 | description: 'The styles for the Button component', 20 | base: { 21 | display: 'flex', 22 | cursor: 'pointer', 23 | fontWeight: 'bold', 24 | }, 25 | variants: { 26 | visual: { 27 | funky: { bg: 'red.200', color: 'slate.800' }, 28 | edgy: { border: '1px solid {colors.red.500}' }, 29 | }, 30 | size: { 31 | sm: { padding: '4', fontSize: '12px' }, 32 | lg: { padding: '8', fontSize: '40px' }, 33 | }, 34 | shape: { 35 | square: { borderRadius: '0' }, 36 | circle: { borderRadius: 'full' }, 37 | }, 38 | }, 39 | defaultVariants: { 40 | visual: 'funky', 41 | size: 'sm', 42 | shape: 'circle', 43 | }, 44 | }, 45 | }, 46 | }, 47 | }, 48 | 49 | // The output directory for your css system 50 | outdir: 'styled-system', 51 | 52 | // The JSX framework to use 53 | jsxFramework: 'react', 54 | }) 55 | -------------------------------------------------------------------------------- /packages/utils/src/css-var.ts: -------------------------------------------------------------------------------- 1 | import { cssVar as createVar, type CssVarOptions } from '@pandacss/shared' 2 | 3 | const cssVarRef = (value: Value, fallback?: string) => 4 | `var(--${value}${fallback ? ', ' + fallback : ''})` as const 5 | const cssVarName = (value: Value) => `--${value}` as const 6 | 7 | const createCssVar = (value: Value, options: CssVarOptions = {}) => 8 | createVar(value, options) as CssVar 9 | 10 | export type CssVar = { 11 | var: `--${Name}` 12 | ref: `var(--${Name})` 13 | } 14 | export type ToCssVar = `--${Cat}-${T}` 15 | 16 | export type CssVarsOptions = Omit 17 | 18 | function defineCssVars(scope: string, keys: Array, options?: CssVarsOptions) { 19 | const vars = {} as Record> 20 | for (const key of keys) { 21 | if (Array.isArray(key)) { 22 | const [name, fallback] = key 23 | vars[name] = cssVar.create(`${scope}-${name}`, { ...options, fallback }) as CssVar 24 | continue 25 | } 26 | 27 | vars[key] = cssVar.create(`${scope}-${key}`) as CssVar 28 | } 29 | return vars as { 30 | [Var in K]: CssVar 31 | } 32 | } 33 | 34 | export const cssVar = { 35 | /** 36 | * ⚠️ doesn't handle prefixing/hashing, instead use `cssVar.create` for that 37 | */ 38 | ref: cssVarRef, 39 | /** 40 | * ⚠️ doesn't handle prefixing/hashing, instead use `cssVar.create` for that 41 | */ 42 | name: cssVarName, 43 | 44 | create: createCssVar, 45 | scope: defineCssVars, 46 | } 47 | -------------------------------------------------------------------------------- /packages/unplugin/.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Node template 3 | # Logs 4 | logs 5 | *.log 6 | npm-debug.log* 7 | yarn-debug.log* 8 | yarn-error.log* 9 | 10 | # Runtime data 11 | pids 12 | *.pid 13 | *.seed 14 | *.pid.lock 15 | 16 | # Directory for instrumented libs generated by jscoverage/JSCover 17 | lib-cov 18 | 19 | # Coverage directory used by tools like istanbul 20 | coverage 21 | 22 | # nyc test coverage 23 | .nyc_output 24 | 25 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 26 | .grunt 27 | 28 | # Bower dependency directory (https://bower.io/) 29 | bower_components 30 | 31 | # node-waf configuration 32 | .lock-wscript 33 | 34 | # Compiled binary addons (https://nodejs.org/api/addons.html) 35 | build/Release 36 | 37 | # Dependency directories 38 | node_modules/ 39 | jspm_packages/ 40 | 41 | # TypeScript v1 declaration files 42 | typings/ 43 | 44 | # Optional npm cache directory 45 | .npm 46 | 47 | # Optional eslint cache 48 | .eslintcache 49 | 50 | # Optional REPL history 51 | .node_repl_history 52 | 53 | # Output of 'npm pack' 54 | *.tgz 55 | 56 | # Yarn Integrity file 57 | .yarn-integrity 58 | 59 | # dotenv environment variables file 60 | .env 61 | 62 | # parcel-bundler cache (https://parceljs.org/) 63 | .cache 64 | 65 | # next.js build output 66 | .next 67 | 68 | # nuxt.js build output 69 | .nuxt 70 | 71 | # Nuxt generate 72 | dist 73 | 74 | # vuepress build output 75 | .vuepress/dist 76 | 77 | # Serverless directories 78 | .serverless 79 | 80 | # IDE 81 | .idea 82 | 83 | ## Panda 84 | styled-system 85 | styled-system-studio 86 | 87 | src/panda.css 88 | playground/panda.css 89 | panda.css 90 | -------------------------------------------------------------------------------- /packages/unplugin-panda-macro/playground/App.tsx: -------------------------------------------------------------------------------- 1 | import { css, cva } from './styled-system/css' 2 | import { center } from './styled-system/patterns' 3 | import { button } from './styled-system/recipes' 4 | import { Stack, styled } from './styled-system/jsx' 5 | import 'virtual:panda.css' 6 | 7 | const overrides = css.raw({ 8 | bg: 'green.100', 9 | }) 10 | 11 | const atomicRecipe = cva({ 12 | base: { 13 | display: 'flex', 14 | }, 15 | variants: { 16 | visual: { 17 | solid: { bg: 'red.200', color: 'white' }, 18 | outline: { borderWidth: '1px', borderColor: 'red.200' }, 19 | }, 20 | size: { 21 | sm: { padding: '4', fontSize: '12px' }, 22 | lg: { padding: '8', fontSize: '24px' }, 23 | }, 24 | }, 25 | }) 26 | 27 | export const App = () => { 28 | return ( 29 |
30 |
47 | 48 | 🐼 49 | Hello from Panda 50 | 51 |
52 |
Button
53 |
Atomic Button
54 |
55 | ) 56 | } 57 | -------------------------------------------------------------------------------- /packages/panda-plugins/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@pandabox/panda-plugins", 3 | "version": "0.0.8", 4 | "exports": { 5 | ".": { 6 | "source": "./src/index.ts", 7 | "types": "./dist/index.d.ts", 8 | "import": { 9 | "types": "./dist/index.d.mts", 10 | "default": "./dist/index.mjs" 11 | }, 12 | "require": { 13 | "types": "./dist/index.d.ts", 14 | "default": "./dist/index.js" 15 | } 16 | } 17 | }, 18 | "scripts": { 19 | "build": "tsup", 20 | "dev": "tsup --watch src", 21 | "typecheck": "tsc --noEmit", 22 | "test": "bun ./test-cli.ts test", 23 | "codegen": "bun ./test-cli.ts codegen" 24 | }, 25 | "imports": { 26 | "#pandabox/fixtures": "../fixtures/src/index.ts" 27 | }, 28 | "dependencies": { 29 | "@pandabox/postcss-plugins": "workspace:^", 30 | "postcss": "^8.4.35" 31 | }, 32 | "devDependencies": { 33 | "@pandacss/core": "^0.36.1", 34 | "@pandacss/dev": "^0.36.1", 35 | "@pandacss/node": "^0.36.1", 36 | "@pandacss/types": "^0.36.1", 37 | "cac": "^6.7.14", 38 | "happy-dom": "^13.6.2", 39 | "tsup": "^8.0.2", 40 | "vitest": "^1.3.1" 41 | }, 42 | "homepage": "https://astahmer.dev", 43 | "repository": { 44 | "type": "git", 45 | "url": "git+https://github.com/astahmer/pandabox.git", 46 | "directory": "packages/panda-plugins" 47 | }, 48 | "author": "Alexandre Stahmer", 49 | "publishConfig": { 50 | "access": "public" 51 | }, 52 | "sideEffects": false, 53 | "files": [ 54 | "src", 55 | "dist" 56 | ], 57 | "keywords": [ 58 | "pandacss", 59 | "pandabox", 60 | "panda", 61 | "plugins", 62 | "typesafety", 63 | "typescript" 64 | ] 65 | } 66 | -------------------------------------------------------------------------------- /packages/define-theme/sandbox/strict-tokens.ts: -------------------------------------------------------------------------------- 1 | import { defineTheme } from '../src/define-theme' 2 | 3 | const t = defineTheme({ strictTokens: false }) 4 | 5 | const builder = t 6 | .conditions({ 7 | hover: '&:hover', 8 | }) 9 | .tokens({ 10 | colors: { 11 | blue: { 12 | 500: { value: '#0000ff' }, 13 | }, 14 | }, 15 | }) 16 | 17 | const config = builder.build() 18 | 19 | config.defineStyles({ 20 | color: 'xxx', 21 | }) 22 | 23 | // 24 | 25 | const withStrictTokens = defineTheme({ strictTokens: true }) 26 | .conditions({ 27 | hover: '&:hover', 28 | }) 29 | .tokens({ 30 | colors: { 31 | blue: { 32 | 500: { value: '#0000ff' }, 33 | }, 34 | red: { 35 | DEFAULT: { value: 'red' }, 36 | 400: { value: 'xxx' }, 37 | }, 38 | }, 39 | }) 40 | .utilities({ 41 | display: { 42 | className: 'd', 43 | }, 44 | color: { 45 | className: 'c', 46 | values: 'colors', 47 | }, 48 | background: { 49 | className: 'bg', 50 | values: 'colors', 51 | }, 52 | }) 53 | .build() 54 | 55 | type ColorPropValue = (typeof withStrictTokens)['_propertyValues']['color'] 56 | type ColorProp = (typeof withStrictTokens)['_properties']['color'] 57 | 58 | // type DisplayPropValue = (typeof withStrictTokens)['_propertyValues']['display'] 59 | // type DisplayProp = (typeof withStrictTokens)['_properties']['display'] 60 | 61 | withStrictTokens.defineStyles({ 62 | background: 'blue.500', 63 | color: 'red', 64 | display: 'aaa', 65 | _hover: { 66 | background: 'red.400', 67 | // @ts-expect-error 68 | color: 'aaa', 69 | display: 'bbb', 70 | }, 71 | '&:hover': { 72 | display: 'flex', 73 | }, 74 | }) 75 | -------------------------------------------------------------------------------- /examples/unplugin/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { css, cva } from '../styled-system/css' 2 | import { center } from '../styled-system/patterns' 3 | import { button } from '../styled-system/recipes' 4 | import { Stack, styled } from '../styled-system/jsx' 5 | // import 'virtual:panda.css' 6 | import './panda.css' 7 | 8 | const overrides = css.raw({ 9 | bg: 'purple.500', 10 | }) 11 | 12 | const atomicRecipe = cva({ 13 | base: { 14 | display: 'flex', 15 | }, 16 | variants: { 17 | visual: { 18 | solid: { bg: 'red.200', color: 'white' }, 19 | outline: { borderWidth: '1px', borderColor: 'red.200' }, 20 | }, 21 | size: { 22 | sm: { padding: '4', fontSize: '12px' }, 23 | lg: { padding: '8', fontSize: '24px' }, 24 | }, 25 | }, 26 | }) 27 | 28 | console.log(atomicRecipe({ visual: 'outline' })) 29 | 30 | export const App = () => { 31 | return ( 32 |
33 |
50 | 51 | 🐼 52 | Hello from Panda 53 | 54 |
55 |
Button
56 |
Atomic Button
57 |
58 | ) 59 | } 60 | -------------------------------------------------------------------------------- /packages/unplugin/playground/App.tsx: -------------------------------------------------------------------------------- 1 | import { css, cva } from './styled-system/css' 2 | import { center } from './styled-system/patterns' 3 | import { button } from './styled-system/recipes' 4 | import { Stack, styled } from './styled-system/jsx' 5 | // import 'virtual:panda.css' 6 | import './panda.css' 7 | 8 | const overrides = css.raw({ 9 | bg: 'purple.500', 10 | }) 11 | 12 | const atomicRecipe = cva({ 13 | base: { 14 | display: 'flex', 15 | }, 16 | variants: { 17 | visual: { 18 | solid: { bg: 'red.200', color: 'white' }, 19 | outline: { borderWidth: '1px', borderColor: 'red.200' }, 20 | }, 21 | size: { 22 | sm: { padding: '4', fontSize: '12px' }, 23 | lg: { padding: '8', fontSize: '24px' }, 24 | }, 25 | }, 26 | }) 27 | 28 | console.log(atomicRecipe({ visual: 'outline' })) 29 | 30 | export const App = () => { 31 | return ( 32 |
33 |
50 | 51 | 🐼 52 | Hello from Panda 53 | 54 |
55 |
Button
56 |
Atomic Button
57 |
58 | ) 59 | } 60 | -------------------------------------------------------------------------------- /examples/solid-start-unplugin/src/components/App.tsx: -------------------------------------------------------------------------------- 1 | import { css, cva } from '../../styled-system/css' 2 | import { center } from '../../styled-system/patterns' 3 | import { button } from '../../styled-system/recipes' 4 | import { Stack, styled } from '../../styled-system/jsx' 5 | // import 'virtual:panda.css' 6 | import './panda.css' 7 | 8 | const overrides = css.raw({ 9 | bg: 'purple.500', 10 | }) 11 | 12 | const atomicRecipe = cva({ 13 | base: { 14 | display: 'flex', 15 | }, 16 | variants: { 17 | visual: { 18 | solid: { bg: 'red.200', color: 'white' }, 19 | outline: { borderWidth: '1px', borderColor: 'red.200' }, 20 | }, 21 | size: { 22 | sm: { padding: '4', fontSize: '12px' }, 23 | lg: { padding: '8', fontSize: '24px' }, 24 | }, 25 | }, 26 | }) 27 | 28 | console.log(atomicRecipe({ visual: 'outline' })) 29 | 30 | export const App = () => { 31 | return ( 32 |
33 |
50 | 51 | 🐼 52 | Hello from Panda 53 | 54 |
55 |
Button
56 |
Atomic Button
57 |
58 | ) 59 | } 60 | -------------------------------------------------------------------------------- /packages/unplugin-panda-macro/src/plugin/create-cva.ts: -------------------------------------------------------------------------------- 1 | import { compact } from '@pandacss/shared' 2 | import { type RecipeConfig } from '@pandacss/types' 3 | import { type MacroContext } from './create-context' 4 | 5 | type Cva = Pick 6 | 7 | const defaults = (conf: Cva) => ({ 8 | base: {}, 9 | variants: {}, 10 | defaultVariants: {}, 11 | compoundVariants: [], 12 | ...conf, 13 | }) 14 | 15 | export const createCva = (config: Cva, mergeCss: MacroContext['mergeCss']) => { 16 | const { base, variants, defaultVariants, compoundVariants } = defaults(config) 17 | 18 | function resolve(props = {}) { 19 | const computedVariants = { ...defaultVariants, ...compact(props) } 20 | let variantCss = { ...base } 21 | for (const [key, value] of Object.entries(computedVariants)) { 22 | const variantStyleObj = variants[key]?.[value as any] 23 | if (variantStyleObj) { 24 | variantCss = mergeCss(variantCss, variantStyleObj) 25 | } 26 | } 27 | const compoundVariantCss = getCompoundVariantCss(compoundVariants, computedVariants, mergeCss) 28 | return mergeCss(variantCss, compoundVariantCss) 29 | } 30 | 31 | return resolve 32 | } 33 | 34 | function getCompoundVariantCss( 35 | compoundVariants: any[], 36 | variantMap: Record, 37 | mergeCss: MacroContext['mergeCss'], 38 | ) { 39 | let result = {} 40 | compoundVariants.forEach((compoundVariant) => { 41 | const isMatching = Object.entries(compoundVariant).every(([key, value]) => { 42 | if (key === 'css') return true 43 | 44 | const values = Array.isArray(value) ? value : [value] 45 | return values.some((value) => variantMap[key] === value) 46 | }) 47 | 48 | if (isMatching) { 49 | result = mergeCss(result, compoundVariant.css) 50 | } 51 | }) 52 | 53 | return result 54 | } 55 | -------------------------------------------------------------------------------- /packages/define-theme/sandbox/preset-panda/tokens.ts: -------------------------------------------------------------------------------- 1 | import type { Tokens } from '@pandacss/types' 2 | import { aspectRatios } from './aspect-ratios' 3 | import { borders } from './borders' 4 | import { colors } from './colors' 5 | import { animations } from './keyframes' 6 | import { shadows } from './shadows' 7 | import { sizes } from './sizes' 8 | import { spacing } from './spacing' 9 | import { fonts, fontSizes, fontWeights, letterSpacings, lineHeights } from './typography' 10 | 11 | const defineTokens = (v: T) => v 12 | 13 | export const tokens = defineTokens({ 14 | aspectRatios, 15 | borders, 16 | easings: { 17 | default: { value: 'cubic-bezier(0.4, 0, 0.2, 1)' }, 18 | linear: { value: 'linear' }, 19 | in: { value: 'cubic-bezier(0.4, 0, 1, 1)' }, 20 | out: { value: 'cubic-bezier(0, 0, 0.2, 1)' }, 21 | 'in-out': { value: 'cubic-bezier(0.4, 0, 0.2, 1)' }, 22 | }, 23 | durations: { 24 | fastest: { value: '50ms' }, 25 | faster: { value: '100ms' }, 26 | fast: { value: '150ms' }, 27 | normal: { value: '200ms' }, 28 | slow: { value: '300ms' }, 29 | slower: { value: '400ms' }, 30 | slowest: { value: '500ms' }, 31 | }, 32 | radii: { 33 | xs: { value: '0.125rem' }, 34 | sm: { value: '0.25rem' }, 35 | md: { value: '0.375rem' }, 36 | lg: { value: '0.5rem' }, 37 | xl: { value: '0.75rem' }, 38 | '2xl': { value: '1rem' }, 39 | '3xl': { value: '1.5rem' }, 40 | full: { value: '9999px' }, 41 | }, 42 | fontWeights, 43 | lineHeights, 44 | fonts, 45 | letterSpacings, 46 | fontSizes, 47 | shadows, 48 | colors, 49 | blurs: { 50 | sm: { value: '4px' }, 51 | base: { value: '8px' }, 52 | md: { value: '12px' }, 53 | lg: { value: '16px' }, 54 | xl: { value: '24px' }, 55 | '2xl': { value: '40px' }, 56 | '3xl': { value: '64px' }, 57 | }, 58 | spacing, 59 | sizes, 60 | animations, 61 | }) 62 | -------------------------------------------------------------------------------- /packages/define-theme/sandbox/preset-base/utilities/transforms.ts: -------------------------------------------------------------------------------- 1 | import type { UtilityConfig } from '@pandacss/types' 2 | 3 | const positiveFractions = { 4 | '1/2': '50%', 5 | '1/3': '33.333333%', 6 | '2/3': '66.666667%', 7 | '1/4': '25%', 8 | '2/4': '50%', 9 | '3/4': '75%', 10 | full: '100%', 11 | } 12 | const negativeFractions = Object.fromEntries( 13 | Object.entries(positiveFractions).map(([key, value]) => [`-${key}`, `-${value}`]), 14 | ) 15 | const fractions = { ...positiveFractions, ...negativeFractions } 16 | 17 | export const transforms = { 18 | transformOrigin: { 19 | className: 'origin', 20 | }, 21 | scale: { 22 | className: 'scale', 23 | property: 'scale', 24 | values: { 25 | auto: 'var(--scale-x) var(--scale-y)', 26 | }, 27 | }, 28 | scaleX: { 29 | className: 'scale-x', 30 | transform(value) { 31 | return { 32 | '--scale-x': value, 33 | } 34 | }, 35 | }, 36 | scaleY: { 37 | className: 'scale-y', 38 | transform(value) { 39 | return { 40 | '--scale-y': value, 41 | } 42 | }, 43 | }, 44 | translate: { 45 | className: 'translate', 46 | property: 'translate', 47 | values: { 48 | auto: 'var(--translate-x) var(--translate-y)', 49 | }, 50 | }, 51 | translateX: { 52 | shorthand: 'x', 53 | className: 'translate-x', 54 | values(theme) { 55 | return { 56 | ...theme('spacing'), 57 | ...fractions, 58 | } 59 | }, 60 | transform(value) { 61 | return { 62 | '--translate-x': value, 63 | } 64 | }, 65 | }, 66 | translateY: { 67 | shorthand: 'y', 68 | className: 'translate-y', 69 | values(theme) { 70 | return { 71 | ...theme('spacing'), 72 | ...fractions, 73 | } 74 | }, 75 | transform(value) { 76 | return { 77 | '--translate-y': value, 78 | } 79 | }, 80 | }, 81 | } as const satisfies UtilityConfig 82 | -------------------------------------------------------------------------------- /packages/unplugin/e2e/test-global-setup.ts: -------------------------------------------------------------------------------- 1 | // https://github.com/vitejs/vite/blob/bf1e9c2fd7b05f84d05e59f72b3fc26ca22807bb/playground/vitestGlobalSetup.ts 2 | 3 | import path from 'node:path' 4 | import fs from 'fs-extra' 5 | import type { GlobalSetupContext } from 'vitest/node' 6 | import type { BrowserServer } from '@playwright/test' 7 | import { chromium } from '@playwright/test' 8 | 9 | let browserServer: BrowserServer | undefined 10 | 11 | const scenarioDir = 'scenarios' 12 | const tempDir = path.resolve(__dirname, './' + scenarioDir + '-temp') 13 | 14 | export async function setup({ provide }: GlobalSetupContext): Promise { 15 | process.env.NODE_ENV = process.env.VITE_TEST_BUILD ? 'production' : 'development' 16 | 17 | browserServer = await chromium.launchServer({ 18 | headless: !process.env.VITE_DEBUG_SERVE, 19 | args: process.env.CI ? ['--no-sandbox', '--disable-setuid-sandbox'] : undefined, 20 | }) 21 | 22 | provide('wsEndpoint', browserServer.wsEndpoint()) 23 | 24 | await fs.ensureDir(tempDir) 25 | await fs.emptyDir(tempDir) 26 | await fs 27 | .copy(path.resolve(__dirname, './' + scenarioDir), tempDir, { 28 | dereference: false, 29 | filter(file) { 30 | file = file.replace(/\\/g, '/') 31 | return !file.includes('.test.ts') && !/dist(?:\/|$)/.test(file) 32 | }, 33 | }) 34 | .catch(async (error) => { 35 | if (error.code === 'EPERM' && error.syscall === 'symlink') { 36 | throw new Error( 37 | 'Could not create symlinks. On Windows, consider activating Developer Mode to allow non-admin users to create symlinks by following the instructions at https://docs.microsoft.com/en-us/windows/apps/get-started/enable-your-device-for-development.', 38 | ) 39 | } else { 40 | throw error 41 | } 42 | }) 43 | } 44 | 45 | export async function teardown(): Promise { 46 | await browserServer?.close() 47 | if (!process.env.VITE_PRESERVE_BUILD_ARTIFACTS) { 48 | await fs.remove(tempDir) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /packages/prettier-plugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@pandabox/prettier-plugin", 3 | "version": "0.1.3", 4 | "description": "Prettier plugin for Panda css", 5 | "main": "dist/index.js", 6 | "module": "dist/index.js", 7 | "types": "dist/index.d.ts", 8 | "exports": { 9 | ".": { 10 | "source": "./src/index.ts", 11 | "types": "./dist/index.d.ts", 12 | "import": { 13 | "types": "./dist/index.d.mts", 14 | "default": "./dist/index.js" 15 | }, 16 | "require": { 17 | "types": "./dist/index.d.ts", 18 | "default": "./dist/index.js" 19 | } 20 | } 21 | }, 22 | "scripts": { 23 | "build": "tsup", 24 | "build-fast": "tsup --no-dts", 25 | "dev": "pnpm build-fast --watch", 26 | "typecheck": "tsc --noEmit", 27 | "test": "vitest" 28 | }, 29 | "imports": { 30 | "#pandabox/fixtures": "../fixtures/src/index.ts" 31 | }, 32 | "peerDependencies": { 33 | "@pandacss/config": ">=0.36.1", 34 | "@pandacss/core": ">=0.36.1", 35 | "@pandacss/is-valid-prop": ">=0.36.1", 36 | "@pandacss/node": ">=0.36.1", 37 | "@pandacss/preset-base": ">=0.36.1", 38 | "@pandacss/shared": ">=0.36.1" 39 | }, 40 | "devDependencies": { 41 | "@pandacss/types": "^0.35.0", 42 | "@types/micromatch": "^4.0.6", 43 | "prettier": "3.2.5", 44 | "tsup": "^8.0.2", 45 | "vitest": "1.3.1" 46 | }, 47 | "dependencies": { 48 | "micromatch": "^4.0.5" 49 | }, 50 | "homepage": "https://astahmer.dev", 51 | "repository": { 52 | "type": "git", 53 | "url": "git+https://github.com/astahmer/pandabox.git", 54 | "directory": "packages/prettier-plugin" 55 | }, 56 | "author": "Alexandre Stahmer", 57 | "publishConfig": { 58 | "access": "public" 59 | }, 60 | "sideEffects": false, 61 | "files": [ 62 | "src", 63 | "dist" 64 | ], 65 | "keywords": [ 66 | "pandacss", 67 | "pandabox", 68 | "panda", 69 | "prettier", 70 | "plugin", 71 | "typesafety", 72 | "typescript" 73 | ] 74 | } 75 | -------------------------------------------------------------------------------- /packages/define-theme/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@pandabox/define-theme", 3 | "version": "0.0.4", 4 | "description": "End-to-end type-safe theming for PandaCSS", 5 | "exports": { 6 | ".": { 7 | "source": "./src/index.ts", 8 | "types": "./dist/index.d.ts", 9 | "import": { 10 | "types": "./dist/index.d.mts", 11 | "default": "./dist/index.mjs" 12 | }, 13 | "require": { 14 | "types": "./dist/index.d.ts", 15 | "default": "./dist/index.js" 16 | } 17 | } 18 | }, 19 | "scripts": { 20 | "trace-dir": "pnpm tsc -p tsconfig.bench.json --extendedDiagnostics --generateTrace trace-dir", 21 | "analyze": "analyze-trace trace-dir --forceMillis=50 --skipMillis=50", 22 | "simplify": "simplify-trace-types trace-dir/types.json trace-dir/simple.json", 23 | "report": "tsx ./scripts/trace-report.ts", 24 | "trace": "pnpm trace-dir && pnpm analyze && pnpm simplify && pnpm report", 25 | "bench": "tsx ./sandbox/define-theme.bench.ts", 26 | "build": "tsup", 27 | "dev": "tsup --watch src", 28 | "typecheck": "tsc --noEmit" 29 | }, 30 | "dependencies": { 31 | "@pandacss/types": "^0.36.1", 32 | "lodash.merge": "^4.6.2" 33 | }, 34 | "devDependencies": { 35 | "@arethetypeswrong/cli": "^0.15.0", 36 | "@types/lodash.merge": "^4.6.9", 37 | "@typescript/analyze-trace": "^0.10.1", 38 | "publint": "^0.2.7", 39 | "tsup": "^8.0.2" 40 | }, 41 | "homepage": "https://astahmer.dev", 42 | "repository": { 43 | "type": "git", 44 | "url": "git+https://github.com/astahmer/pandabox.git", 45 | "directory": "packages/define-theme" 46 | }, 47 | "author": "Alexandre Stahmer", 48 | "publishConfig": { 49 | "access": "public" 50 | }, 51 | "sideEffects": false, 52 | "files": [ 53 | "src", 54 | "dist" 55 | ], 56 | "keywords": [ 57 | "pandacss", 58 | "pandabox", 59 | "panda", 60 | "defineTheme", 61 | "theme", 62 | "config", 63 | "typesafety", 64 | "typescript" 65 | ] 66 | } 67 | -------------------------------------------------------------------------------- /packages/prettier-plugin/src/plugin.ts: -------------------------------------------------------------------------------- 1 | import type { ParserOptions, Plugin } from 'prettier' 2 | import typescriptParser from 'prettier/plugins/typescript' 3 | import { BuilderResolver } from './builder-resolver' 4 | import type { PluginOptions } from './options' 5 | import { PrettyPanda } from './pretty-panda' 6 | import { Builder } from '@pandacss/node' 7 | 8 | export { options } from './options' 9 | export type { PluginOptions } 10 | 11 | // Programatic usage 12 | const builder = new Builder() 13 | let configPath: string | undefined 14 | 15 | // CLI/VSCode usage 16 | const resolver = new BuilderResolver() 17 | 18 | export const parsers: Plugin['parsers'] = { 19 | typescript: { 20 | ...typescriptParser.parsers.typescript, 21 | async parse(text, options: ParserOptions & Partial) { 22 | const ast = typescriptParser.parsers.typescript.parse(text, options) 23 | const filePath = options.filepath 24 | 25 | // Programatic usage 26 | if (!options.filepath) { 27 | if (options.pandaConfigPath) { 28 | configPath = options.pandaConfigPath 29 | } 30 | 31 | const setupOptions = { configPath: options.pandaConfigPath, cwd: options.pandaCwd } 32 | const ctx = (await builder.setup(setupOptions)) || builder.context 33 | if (!ctx) return ast 34 | 35 | // cache the config path 36 | if (!configPath) configPath = ctx.conf.path 37 | 38 | const pretty = new PrettyPanda(ast, ctx, options as any) 39 | return pretty.format(text) 40 | } 41 | 42 | // CLI/VSCode usage 43 | try { 44 | const ctx = await resolver.getOrCreate(filePath) 45 | if (!ctx) return ast 46 | if (options.pandaOnlyIncluded && !resolver.isIncluded(filePath)) return ast 47 | 48 | const pretty = new PrettyPanda(ast, ctx, options as any) 49 | return pretty.format(text) 50 | } catch (err) { 51 | console.log('prettier-plugin error') 52 | console.error(err) 53 | return ast 54 | } 55 | }, 56 | }, 57 | } 58 | -------------------------------------------------------------------------------- /packages/define-recipe/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@pandabox/define-recipe", 3 | "version": "0.0.3", 4 | "description": "End-to-end type-safe theming for PandaCSS", 5 | "exports": { 6 | ".": { 7 | "source": "./src/index.ts", 8 | "types": "./dist/index.d.ts", 9 | "import": { 10 | "types": "./dist/index.d.mts", 11 | "default": "./dist/index.mjs" 12 | }, 13 | "require": { 14 | "types": "./dist/index.d.ts", 15 | "default": "./dist/index.js" 16 | } 17 | } 18 | }, 19 | "scripts": { 20 | "trace-dir": "pnpm tsc -p tsconfig.bench.json --extendedDiagnostics --generateTrace trace-dir", 21 | "analyze": "analyze-trace trace-dir --forceMillis=50 --skipMillis=50", 22 | "simplify": "simplify-trace-types trace-dir/types.json trace-dir/simple.json", 23 | "report": "tsx ./scripts/trace-report.ts", 24 | "trace": "pnpm trace-dir && pnpm analyze && pnpm simplify && pnpm report", 25 | "bench": "echo TODO && tsx ./sandbox/define-theme.bench.ts", 26 | "build": "tsup", 27 | "dev": "tsup --watch src", 28 | "typecheck": "tsc --noEmit", 29 | "test": "vitest" 30 | }, 31 | "dependencies": { 32 | "@pandacss/types": "^0.36.1", 33 | "lodash.merge": "^4.6.2" 34 | }, 35 | "devDependencies": { 36 | "@arethetypeswrong/cli": "^0.15.0", 37 | "@types/lodash.merge": "^4.6.9", 38 | "@typescript/analyze-trace": "^0.10.1", 39 | "publint": "^0.2.7", 40 | "tsup": "^8.0.2", 41 | "vitest": "^1.3.1" 42 | }, 43 | "homepage": "https://astahmer.dev", 44 | "repository": { 45 | "type": "git", 46 | "url": "git+https://github.com/astahmer/pandabox.git", 47 | "directory": "packages/define-recipe" 48 | }, 49 | "author": "Alexandre Stahmer", 50 | "publishConfig": { 51 | "access": "public" 52 | }, 53 | "sideEffects": false, 54 | "files": [ 55 | "src", 56 | "dist" 57 | ], 58 | "keywords": [ 59 | "pandacss", 60 | "pandabox", 61 | "panda", 62 | "defineRecipe", 63 | "recipe", 64 | "extension", 65 | "config", 66 | "typesafety", 67 | "typescript" 68 | ] 69 | } 70 | -------------------------------------------------------------------------------- /packages/define-theme/src/selectors.ts: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------------- 2 | * Selectors (not exported from `@pandacss/types`) 3 | * -----------------------------------------------------------------------------*/ 4 | 5 | import type { Pseudos } from './pseudos' 6 | 7 | type AriaAttributes = 8 | | '[aria-disabled]' 9 | | '[aria-hidden]' 10 | | '[aria-invalid]' 11 | | '[aria-readonly]' 12 | | '[aria-required]' 13 | | '[aria-selected]' 14 | | '[aria-checked]' 15 | | '[aria-expanded]' 16 | | '[aria-pressed]' 17 | | `[aria-current=${'page' | 'step' | 'location' | 'date' | 'time'}]` 18 | | '[aria-invalid]' 19 | | `[aria-sort=${'ascending' | 'descending'}]` 20 | 21 | type DataAttributes = 22 | | '[data-selected]' 23 | | '[data-highlighted]' 24 | | '[data-hover]' 25 | | '[data-active]' 26 | | '[data-checked]' 27 | | '[data-disabled]' 28 | | '[data-readonly]' 29 | | '[data-focus]' 30 | | '[data-focus-visible]' 31 | | '[data-focus-visible-added]' 32 | | '[data-invalid]' 33 | | '[data-pressed]' 34 | | '[data-expanded]' 35 | | '[data-grabbed]' 36 | | '[data-dragged]' 37 | | '[data-orientation=horizontal]' 38 | | '[data-orientation=vertical]' 39 | | '[data-in-range]' 40 | | '[data-out-of-range]' 41 | | '[data-placeholder-shown]' 42 | | `[data-part=${string}]` 43 | | `[data-attr=${string}]` 44 | | `[data-placement=${string}]` 45 | | `[data-theme=${string}]` 46 | | `[data-size=${string}]` 47 | | `[data-state=${string}]` 48 | | '[data-empty]' 49 | | '[data-loading]' 50 | | '[data-loaded]' 51 | | '[data-enter]' 52 | | '[data-entering]' 53 | | '[data-exited]' 54 | | '[data-exiting]' 55 | 56 | type AttributeSelector = `&${Pseudos | DataAttributes | AriaAttributes}` 57 | type ParentSelector = `${DataAttributes | AriaAttributes} &` 58 | 59 | type AtRuleType = 'media' | 'layer' | 'container' | 'supports' | 'page' 60 | 61 | // TODO ? those types are currently not exported from `@pandacss/types` 62 | export type AnySelector = `${string}&` | `&${string}` | `@${AtRuleType}${string}` 63 | export type Selectors = AttributeSelector | ParentSelector 64 | -------------------------------------------------------------------------------- /packages/unplugin-panda-macro/src/plugin/get-import-declarations.ts: -------------------------------------------------------------------------------- 1 | // https://github.com/chakra-ui/panda/blob/0bf09f214ec25ff3ea74b8e432bd10c7c9453805/packages/parser/src/get-import-declarations.ts 2 | import { resolveTsPathPattern } from '@pandacss/config/ts-path' 3 | import type { ImportResult, ParserOptions } from '@pandacss/core' 4 | import type { SourceFile } from 'ts-morph' 5 | import { getModuleSpecifierValue } from './get-module-specifier-value' 6 | import { hasMacroAttribute } from './has-macro-attribute' 7 | 8 | export function getImportDeclarations(context: ParserOptions, sourceFile: SourceFile, onlyMacroImports = false) { 9 | const { imports, tsOptions } = context 10 | 11 | const importDeclarations: ImportResult[] = [] 12 | 13 | sourceFile.getImportDeclarations().forEach((node) => { 14 | const mod = getModuleSpecifierValue(node) 15 | if (!mod) return 16 | if (onlyMacroImports && !hasMacroAttribute(node)) return 17 | 18 | // import { flex, stack } from "styled-system/patterns" 19 | node.getNamedImports().forEach((specifier) => { 20 | const name = specifier.getNameNode().getText() 21 | const alias = specifier.getAliasNode()?.getText() || name 22 | 23 | const result: ImportResult = { name, alias, mod, kind: 'named' } 24 | 25 | const found = imports.match(result, (mod) => { 26 | if (!tsOptions?.pathMappings) return 27 | return resolveTsPathPattern(tsOptions.pathMappings, mod) 28 | }) 29 | 30 | if (!found) return 31 | 32 | importDeclarations.push(result) 33 | }) 34 | 35 | // import * as p from "styled-system/patterns 36 | const namespace = node.getNamespaceImport() 37 | if (namespace) { 38 | const name = namespace.getText() 39 | const result: ImportResult = { name, alias: name, mod, kind: 'namespace' } 40 | 41 | const found = imports.match(result, (mod) => { 42 | if (!tsOptions?.pathMappings) return 43 | return resolveTsPathPattern(tsOptions.pathMappings, mod) 44 | }) 45 | 46 | if (!found) return 47 | 48 | importDeclarations.push(result) 49 | } 50 | }) 51 | 52 | return importDeclarations 53 | } 54 | -------------------------------------------------------------------------------- /packages/prettier-plugin/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @pandabox/prettier-plugin 2 | 3 | ## 0.1.3 4 | 5 | ### Patch Changes 6 | 7 | - f080836: Add `pandaIgnoreComponents` option to ignore sorting some components 8 | 9 | ## 0.1.2 10 | 11 | ### Patch Changes 12 | 13 | - 581c38c: fix(prettier-plugin): sort compoundVariants/staticCss last for cva/recipes 14 | 15 | ## 0.1.1 16 | 17 | ### Patch Changes 18 | 19 | - 25fed76: Update to panda 0.36.1 20 | 21 | ## 0.1.0 22 | 23 | ### Minor Changes 24 | 25 | - e404253: Better sorting for sva/defineSlotRecipe sorting + allow sorting custom functions using the `pandaFunctions` option 26 | 27 | ## 0.0.6 28 | 29 | ### Patch Changes 30 | 31 | - 30e511c: Sort pattern specific properties that are bound to a CSS property 32 | 33 | ex: `stack` pattern (from `@pandacss/preset-base`) has a `direction` property bound to the `flexDirection`, it will be 34 | sorted near the `flexDirection` property. 35 | 36 | *** 37 | 38 | Fix an issue where some CSS properties were sorted after conditions due to not being tied to a utility (ex: `cursor`). 39 | -> Now if a property is not tied to a utility but is a valid CSS property, it will be sorted in the `Other` group. 40 | 41 | *** 42 | 43 | Change the default `pandaStylePropsFirst` and `pandaSortOtherProps` options to `false`. 44 | 45 | Change `pandaFirstProps` defaults to `['as', 'asChild', 'ref', 'className', 'layerStyle', 'textStyle']`. 46 | 47 | ## 0.0.5 48 | 49 | ### Patch Changes 50 | 51 | - 31ea13e: feat(prettier): sort nested objects / cva / defineStyles / defineRecipe / defineSlotRecipes 52 | - 771ff92: Set `cwd` to the config dirpath so that the plugin can resolve the config file when using `presets` from npm 53 | 54 | ## 0.0.4 55 | 56 | ### Patch Changes 57 | 58 | - 91b4f3a: rename to `@pandabox/prettier-plugin` instead of `@pandabox/prettier-plugin-panda` 59 | 60 | ## 0.0.3 61 | 62 | ### Patch Changes 63 | 64 | - c68aade: Add `pandaStylePropsFirst` / `pandaSortOtherProps` / `pandaGroupOrder` options 65 | 66 | ## 0.0.2 67 | 68 | ### Patch Changes 69 | 70 | - 5e3d5cb: Fix CLI/VSCode usage & automatically detect / lazy load config by filepath (share context when possible) 71 | -------------------------------------------------------------------------------- /packages/define-recipe/src/define-recipe.ts: -------------------------------------------------------------------------------- 1 | import type { RecipeConfig, RecipeVariantRecord } from '@pandacss/types' 2 | import deepmerge from 'lodash.merge' 3 | 4 | import type { RecipeBuilder } from './builder-typings' 5 | 6 | export { type RecipeBuilder } 7 | 8 | export type { 9 | RecipeCompoundSelection, 10 | RecipeCompoundVariant, 11 | RecipeConfig, 12 | RecipeSelection, 13 | RecipeVariantRecord, 14 | } from '@pandacss/types' 15 | 16 | export function defineRecipe(config: RecipeConfig): RecipeBuilder { 17 | return Object.assign( 18 | { 19 | extend: function (variants) { 20 | return defineRecipe(Object.assign({}, config, deepmerge({ variants: config.variants }, { variants }))) 21 | }, 22 | merge: function (extension) { 23 | return defineRecipe(deepmerge({}, config, extension as any)) 24 | }, 25 | pick: function (...keys) { 26 | return defineRecipe( 27 | Object.assign({}, config, { 28 | variants: keys.reduce((acc, key) => ({ ...acc, [key]: config.variants?.[key] }), {}), 29 | compoundVariants: config.compoundVariants?.filter((compound) => { 30 | return Object.keys(compound).some((variant) => keys.includes(variant as (typeof keys)[number])) 31 | }), 32 | }), 33 | ) 34 | }, 35 | omit: function (...keys) { 36 | return defineRecipe( 37 | Object.assign({}, config, { 38 | variants: Object.entries(config.variants ?? {}).reduce((acc, [key, value]) => { 39 | if (keys.includes(key as (typeof keys)[number])) return acc 40 | return Object.assign({}, acc, { [key]: value }) 41 | }, {}), 42 | compoundVariants: config.compoundVariants?.filter((compound) => { 43 | return !Object.keys(compound).some((variant) => keys.includes(variant as (typeof keys)[number])) 44 | }), 45 | }), 46 | ) 47 | }, 48 | cast: function () { 49 | return config as RecipeConfig 50 | }, 51 | } as RecipeBuilder, 52 | config, 53 | ) as RecipeBuilder 54 | } 55 | -------------------------------------------------------------------------------- /website/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "website", 3 | "private": true, 4 | "sideEffects": false, 5 | "type": "module", 6 | "scripts": { 7 | "dev": "remix vite:dev", 8 | "prebuild": "pnpm --filter @pandabox/* run build", 9 | "vercel:build": "pnpm prebuild && pnpm panda && remix vite:build", 10 | "build": "remix vite:build", 11 | "start": "npx http-server build/client/", 12 | "start-server": "remix-serve ./build/server/index.js", 13 | "typecheck": "tsc --noEmit", 14 | "types:codegen": "tsx scripts/bundle-types.mts", 15 | "fmt": "prettier --write app/components app/routes" 16 | }, 17 | "imports": { 18 | "#styled-system/*": "./styled-system/*" 19 | }, 20 | "dependencies": { 21 | "@ark-ui/anatomy": "^2.3.1", 22 | "@ark-ui/react": "^2.2.2", 23 | "@fontsource/inter": "^5.0.16", 24 | "@monaco-editor/react": "^4.6.0", 25 | "@pandabox/codemods": "workspace:^", 26 | "@pandabox/prettier-plugin": "workspace:^", 27 | "@remix-run/css-bundle": "^2.8.0", 28 | "@remix-run/node": "^2.8.0", 29 | "@remix-run/react": "^2.8.0", 30 | "@remix-run/serve": "^2.8.0", 31 | "@xstate/react": "^4.1.0", 32 | "isbot": "^5.1.1", 33 | "lz-string": "^1.5.0", 34 | "monaco-editor": "^0.46.0", 35 | "pastable": "^2.2.1", 36 | "react": "^18.2.0", 37 | "react-dom": "^18.2.0", 38 | "react-icons": "^5.0.1", 39 | "react-resizable-panels": "^2.0.11", 40 | "ts-morph": "21.0.1", 41 | "xstate": "^5.8.2" 42 | }, 43 | "devDependencies": { 44 | "@pandabox/panda-plugins": "workspace:^", 45 | "@pandabox/presets": "workspace:^", 46 | "@pandabox/unplugin-panda-macro": "workspace:^", 47 | "@pandacss/dev": "^0.36.1", 48 | "@pandacss/preset-base": "^0.36.1", 49 | "@pandacss/studio": "^0.36.1", 50 | "@park-ui/panda-preset": "^0.36.1", 51 | "@remix-run/dev": "^2.8.0", 52 | "@types/react": "^18.2.61", 53 | "@types/react-dom": "^18.2.19", 54 | "dts-bundle-generator": "^9.3.1", 55 | "typescript": "^5.3.3", 56 | "vite": "^5.1.4", 57 | "vite-plugin-inspect": "^0.8.3", 58 | "vite-tsconfig-paths": "^4.3.1" 59 | }, 60 | "engines": { 61 | "node": ">=18.0.0" 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /website/app/vite-themes/vite-themes-types.ts: -------------------------------------------------------------------------------- 1 | /** Adapted from https://github.com/pacocoursey/next-themes/blob/a385b8d865bbb317ff73a5b6c1319ae566f7d6f1/src/types.ts */ 2 | 3 | interface ValueObject { 4 | [themeName: string]: string; 5 | } 6 | 7 | export interface UseThemeProps { 8 | /** List of all available theme names */ 9 | themes: string[]; 10 | /** Forced theme name for the current page */ 11 | forcedTheme?: string; 12 | /** Update the theme */ 13 | setTheme: (theme: string) => void; 14 | /** Active theme name */ 15 | theme?: string; 16 | /** If `enableSystem` is true and the active theme is "system", this returns whether the system preference resolved to "dark" or "light". Otherwise, identical to `theme` */ 17 | resolvedTheme?: string; 18 | /** If enableSystem is true, returns the System theme preference ("dark" or "light"), regardless what the active theme is */ 19 | systemTheme?: "dark" | "light"; 20 | } 21 | 22 | export interface ThemeProviderProps { 23 | /** List of all available theme names */ 24 | themes?: string[]; 25 | /** Forced theme name for the current page */ 26 | forcedTheme?: string; 27 | /** Whether to switch between dark and light themes based on prefers-color-scheme */ 28 | enableSystem?: boolean; 29 | /** Disable all CSS transitions when switching themes */ 30 | disableTransitionOnChange?: boolean; 31 | /** Whether to indicate to browsers which color scheme is used (dark or light) for built-in UI like inputs and buttons */ 32 | enableColorScheme?: boolean; 33 | /** Key used to store theme setting in localStorage */ 34 | storageKey?: string; 35 | /** Default theme name (for v0.0.12 and lower the default was light). If `enableSystem` is false, the default theme is light */ 36 | defaultTheme?: string; 37 | /** HTML attribute modified based on the active theme. Accepts `class` and `data-*` (meaning any data attribute, `data-mode`, `data-color`, etc.) */ 38 | attribute?: string | "class"; 39 | /** Mapping of theme name to HTML attribute value. Object where key is the theme name and value is the attribute value */ 40 | value?: ValueObject; 41 | /** Nonce string to pass to the inline script for CSP headers */ 42 | nonce?: string; 43 | 44 | children?: React.ReactNode; 45 | } 46 | -------------------------------------------------------------------------------- /packages/panda-plugins/src/remove-unused-css.ts: -------------------------------------------------------------------------------- 1 | import type { PandaPlugin } from '@pandacss/types' 2 | import { removeUnusedCssVars, removeUnusedKeyframes } from '@pandabox/postcss-plugins' 3 | import postcss from 'postcss' 4 | 5 | export interface RemoveUnusedCssOptions { 6 | /** 7 | * Remove unused CSS variables 8 | * @default true 9 | * 10 | * NOTE: using this means you can't use the JS function `token.var(xxx)` / `token(xxx)` from `styled-system/tokens` 11 | * where `xxx` is the path to a semanticToken 12 | * 13 | * since the CSS variables will be removed based on the usage found in the generated CSS only 14 | * without looking at your style usage in your source files 15 | */ 16 | removeCssVars?: boolean 17 | /** 18 | * Remove unused keyframes 19 | * @default true 20 | */ 21 | removeKeyframes?: boolean 22 | } 23 | 24 | const defaultOptions: RemoveUnusedCssOptions = { 25 | removeCssVars: true, 26 | removeKeyframes: true, 27 | } 28 | 29 | /** 30 | * Removes unused CSS vars and/or @keyframes 31 | * 32 | * @see https://panda-css.com/docs/concepts/hooks#remove-unused-variables-from-final-css 33 | * 34 | * NOTE: using this means you can't use the JS function `token.var(xxx)` / `token(xxx)` from `styled-system/tokens` 35 | * where `xxx` is the path to a semanticToken 36 | * 37 | * since the CSS variables will be removed based on the usage found in the generated CSS only 38 | * without looking at your style usage in your source files 39 | */ 40 | export const pluginRemoveUnusedCss = (options: RemoveUnusedCssOptions = defaultOptions): PandaPlugin => { 41 | return { 42 | name: 'remove-unused-css', 43 | hooks: { 44 | 'cssgen:done': ({ artifact, content }) => { 45 | const isEnabled = options.removeCssVars || options.removeKeyframes 46 | if (!isEnabled) return 47 | 48 | if (artifact !== 'styles.css') return 49 | 50 | let css = content 51 | const plugins = [] 52 | 53 | if (options.removeCssVars) { 54 | plugins.push(removeUnusedCssVars) 55 | } else if (options.removeKeyframes) { 56 | plugins.push(removeUnusedKeyframes) 57 | } 58 | 59 | return postcss(plugins).process(css).toString() 60 | }, 61 | }, 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /packages/unplugin-panda-macro/src/plugin/create-context.ts: -------------------------------------------------------------------------------- 1 | import { removeUnusedCssVars, removeUnusedKeyframes } from '@pandabox/postcss-plugins' 2 | import { PandaContext } from '@pandacss/node' 3 | import { createCss, createMergeCss } from '@pandacss/shared' 4 | import { type LoadConfigResult } from '@pandacss/types' 5 | import { isAbsolute, resolve } from 'path' 6 | import postcss from 'postcss' 7 | import path from 'node:path' 8 | 9 | import type { PluginOptions } from './core' 10 | 11 | const ensureAbsolute = (path: string, root: string) => (path ? (isAbsolute(path) ? path : resolve(root, path)) : root) 12 | 13 | export interface MacroContextOptions { 14 | root: string 15 | conf: LoadConfigResult 16 | } 17 | 18 | export const createMacroContext = (options: MacroContextOptions) => { 19 | const { conf } = options 20 | const panda = new PandaContext(conf) 21 | 22 | const root = ensureAbsolute('', options.root) 23 | const sheet = panda.createSheet() 24 | 25 | const css = createCss(panda.baseSheetContext) 26 | const mergeFns = createMergeCss(panda.baseSheetContext) 27 | const mergeCss: (...styles: StyleObject[]) => StyleObject = mergeFns.mergeCss 28 | 29 | const styles = new Map() 30 | const files = new Set() 31 | 32 | const toCss = (opts: PluginOptions) => { 33 | panda.appendLayerParams(sheet) 34 | panda.appendBaselineCss(sheet) 35 | 36 | if (opts.output === 'atomic') { 37 | panda.appendParserCss(sheet) 38 | } else { 39 | styles.forEach((serialized) => { 40 | sheet.layers.utilities.append(serialized) 41 | }) 42 | } 43 | 44 | const css = panda.getCss(sheet) 45 | if (!opts.optimizeCss) return css 46 | 47 | const optimized = postcss([removeUnusedCssVars, removeUnusedKeyframes]).process(css) 48 | return optimized.toString() 49 | } 50 | 51 | const outfile = path.join(...panda.paths.getFilePath('panda.css')) 52 | const outdir = path.dirname(outfile) 53 | 54 | return { 55 | panda, 56 | root, 57 | sheet, 58 | css, 59 | mergeCss, 60 | styles, 61 | files, 62 | toCss, 63 | paths: { 64 | outfile, 65 | outdir, 66 | root, 67 | }, 68 | } 69 | } 70 | 71 | export type MacroContext = Awaited> 72 | 73 | export interface StyleObject { 74 | [key: string]: any 75 | } 76 | -------------------------------------------------------------------------------- /packages/unplugin/src/plugin/get-import-declarations.ts: -------------------------------------------------------------------------------- 1 | // https://github.com/chakra-ui/panda/blob/0bf09f214ec25ff3ea74b8e432bd10c7c9453805/packages/parser/src/get-import-declarations.ts 2 | import { resolveTsPathPattern } from '@pandacss/config/ts-path' 3 | import type { ImportResult, ParserOptions } from '@pandacss/core' 4 | import type { SourceFile } from 'ts-morph' 5 | import { getModuleSpecifierValue } from './get-module-specifier-value' 6 | import { getMacroAttribute } from './has-macro-attribute' 7 | 8 | export function getImportDeclarations(context: ParserOptions, sourceFile: SourceFile, onlyMacroImports = false) { 9 | const { imports, tsOptions } = context 10 | 11 | const importDeclarations: ImportResultWithAttribute[] = [] 12 | 13 | sourceFile.getImportDeclarations().forEach((node) => { 14 | const mod = getModuleSpecifierValue(node) 15 | if (!mod) return 16 | 17 | // Keep track of the presence of `with { type: "xxx" }` 18 | const withAttr = getMacroAttribute(node) as ImportResultWithAttribute['withAttr'] 19 | 20 | // import { flex, stack } from "styled-system/patterns" 21 | node.getNamedImports().forEach((specifier) => { 22 | const name = specifier.getNameNode().getText() 23 | const alias = specifier.getAliasNode()?.getText() || name 24 | 25 | const result: ImportResultWithAttribute = { name, alias, mod, kind: 'named', withAttr } 26 | 27 | const found = imports.match(result, (mod) => { 28 | if (!tsOptions?.pathMappings) return 29 | return resolveTsPathPattern(tsOptions.pathMappings, mod) 30 | }) 31 | 32 | if (!found) return 33 | 34 | importDeclarations.push(result) 35 | }) 36 | 37 | // import * as p from "styled-system/patterns 38 | const namespace = node.getNamespaceImport() 39 | if (namespace) { 40 | const name = namespace.getText() 41 | const result: ImportResultWithAttribute = { name, alias: name, mod, kind: 'namespace', withAttr } 42 | 43 | const found = imports.match(result, (mod) => { 44 | if (!tsOptions?.pathMappings) return 45 | return resolveTsPathPattern(tsOptions.pathMappings, mod) 46 | }) 47 | 48 | if (!found) return 49 | 50 | importDeclarations.push(result) 51 | } 52 | }) 53 | 54 | return importDeclarations 55 | } 56 | 57 | export interface ImportResultWithAttribute extends ImportResult { 58 | withAttr: 'macro' | 'runtime' | null 59 | } 60 | --------------------------------------------------------------------------------