├── 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 |
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 |
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 |
--------------------------------------------------------------------------------