├── .changeset ├── README.md └── config.json ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ └── config.yml └── workflows │ ├── deploy-site.yml │ ├── release.yml │ ├── snapshot.yml │ └── validate.yml ├── .gitignore ├── .npmrc ├── .nvmrc ├── .prettierignore ├── .vscode └── settings.json ├── LICENSE ├── README.md ├── babel-jest.config.js ├── babel.config.js ├── benchmarks ├── README.md ├── package.json ├── src │ └── css-var-string-literal.ts └── tsconfig.json ├── docs └── treat-migration-guide.md ├── examples ├── next │ ├── components │ │ ├── HelloWorld.css.ts │ │ └── HelloWorld.tsx │ ├── next-env.d.ts │ ├── next.config.js │ ├── package.json │ ├── pages │ │ └── index.tsx │ ├── public │ │ └── favicon.ico │ └── tsconfig.json ├── remix │ ├── .gitignore │ ├── CHANGELOG.md │ ├── app │ │ ├── components │ │ │ ├── HelloWorld.css.ts │ │ │ └── HelloWorld.tsx │ │ ├── root.tsx │ │ └── routes │ │ │ └── _index.tsx │ ├── env.d.ts │ ├── package.json │ ├── public │ │ └── favicon.ico │ ├── tsconfig.json │ └── vite.config.ts └── webpack-react │ ├── CHANGELOG.md │ ├── package.json │ ├── sandbox.config.json │ ├── src │ ├── App.css.ts │ ├── App.tsx │ ├── global.css.ts │ ├── index.tsx │ ├── sprinkles.css.ts │ └── vars.css.ts │ └── webpack.config.js ├── fixtures ├── features │ ├── CHANGELOG.md │ ├── index.html │ ├── package.json │ ├── src │ │ ├── features.css.ts │ │ ├── html.ts │ │ └── index.ts │ └── test-nodes.json ├── layers │ ├── CHANGELOG.md │ ├── index.html │ ├── package.json │ └── src │ │ ├── index.ts │ │ └── styles.css.ts ├── low-level │ ├── CHANGELOG.md │ ├── index.html │ ├── package.json │ ├── src │ │ ├── index.ts │ │ └── styles.css.ts │ └── test-nodes.json ├── next-app-router │ ├── CHANGELOG.md │ ├── next-env.d.ts │ ├── next.config.js │ ├── package.json │ ├── src │ │ └── app │ │ │ ├── features │ │ │ └── page.tsx │ │ │ ├── layout.tsx │ │ │ ├── page.tsx │ │ │ ├── recipes │ │ │ └── page.tsx │ │ │ └── sprinkles │ │ │ └── page.tsx │ └── tsconfig.json ├── next-pages-router │ ├── CHANGELOG.md │ ├── next-env.d.ts │ ├── next.config.js │ ├── package.json │ ├── src │ │ └── pages │ │ │ ├── features │ │ │ └── index.tsx │ │ │ ├── index.tsx │ │ │ ├── recipes │ │ │ └── index.tsx │ │ │ └── sprinkles │ │ │ └── index.tsx │ └── tsconfig.json ├── recipes │ ├── CHANGELOG.md │ ├── index.html │ ├── package.json │ └── src │ │ ├── html.ts │ │ ├── index.ts │ │ └── styles.css.ts ├── sprinkles │ ├── CHANGELOG.md │ ├── index.html │ ├── package.json │ ├── src │ │ ├── html.ts │ │ ├── index.ts │ │ └── styles.css.ts │ └── test-nodes.json ├── template-string-paths │ ├── CHANGELOG.md │ ├── index.html │ ├── package.json │ └── src │ │ ├── [...slug] │ │ └── index.css.ts │ │ ├── [[...slug]] │ │ └── index.css.ts │ │ ├── [[id]] │ │ └── index.css.ts │ │ ├── [] │ │ └── index.css.ts │ │ ├── [blog-id] │ │ └── index.css.ts │ │ ├── [id] │ │ └── index.css.ts │ │ └── index.ts ├── themed │ ├── CHANGELOG.md │ ├── index.html │ ├── package.json │ ├── src │ │ ├── index.ts │ │ ├── shared.css.ts │ │ ├── styles.css.ts │ │ └── themes.css.ts │ └── test-nodes.json ├── thirdparty │ ├── CHANGELOG.md │ ├── index.html │ ├── package.json │ ├── src │ │ ├── index.ts │ │ └── styles.css.ts │ ├── test-nodes.json │ └── thirdparty-dep │ │ ├── CHANGELOG.md │ │ ├── index.mjs │ │ ├── package.json │ │ ├── styles.css.mjs │ │ └── thirdparty-dep-dep │ │ ├── CHANGELOG.md │ │ ├── index.mjs │ │ ├── package.json │ │ └── styles.css.mjs └── unused-modules │ ├── CHANGELOG.md │ ├── index.html │ ├── package.json │ ├── src │ ├── global.css.ts │ ├── index.ts │ ├── lookup.ts │ ├── reset │ │ ├── index.ts │ │ └── reset.css.ts │ ├── shared │ │ ├── index.ts │ │ └── shared.css.ts │ ├── unused │ │ ├── index.ts │ │ └── unused.css.ts │ └── used │ │ ├── index.ts │ │ └── used.css.ts │ └── test-nodes.json ├── jest.config.js ├── jest.setup.ts ├── package.json ├── packages ├── babel-plugin-debug-ids │ ├── CHANGELOG.md │ ├── package.json │ └── src │ │ ├── index.test.ts │ │ └── index.ts ├── compiler │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ └── src │ │ ├── compiler.ts │ │ ├── index.ts │ │ └── lock.ts ├── css │ ├── CHANGELOG.md │ ├── adapter │ │ └── package.json │ ├── disableRuntimeStyles │ │ └── package.json │ ├── fileScope │ │ └── package.json │ ├── functionSerializer │ │ └── package.json │ ├── injectStyles │ │ └── package.json │ ├── package.json │ ├── recipe │ │ └── package.json │ ├── src │ │ ├── adapter.ts │ │ ├── conditionalRulesets.ts │ │ ├── container.ts │ │ ├── disableRuntimeStyles.ts │ │ ├── fileScope.ts │ │ ├── functionSerializer.ts │ │ ├── getDebugFileName.test.ts │ │ ├── getDebugFileName.ts │ │ ├── identifier.test.ts │ │ ├── identifier.ts │ │ ├── index.ts │ │ ├── injectStyles.ts │ │ ├── layer.test.ts │ │ ├── layer.ts │ │ ├── recipe.ts │ │ ├── runtimeAdapter.ts │ │ ├── simplePseudos.ts │ │ ├── style.ts │ │ ├── theme.ts │ │ ├── transformCss.test.ts │ │ ├── transformCss.ts │ │ ├── types.ts │ │ ├── utils.test.ts │ │ ├── utils.ts │ │ ├── validateContract.test.ts │ │ ├── validateContract.ts │ │ ├── validateMediaQuery.test.ts │ │ ├── validateMediaQuery.ts │ │ ├── validateSelector.test.ts │ │ ├── validateSelector.ts │ │ ├── vars.test.ts │ │ ├── vars.ts │ │ └── viewTransition.ts │ └── transformCss │ │ └── package.json ├── dynamic │ ├── CHANGELOG.md │ ├── package.json │ └── src │ │ ├── assignInlineVars.test.css.ts │ │ ├── assignInlineVars.test.ts │ │ ├── assignInlineVars.ts │ │ ├── index.ts │ │ ├── setElementVars.test.ts │ │ ├── setElementVars.ts │ │ └── setElementVarts.test.css.ts ├── esbuild-plugin-next │ ├── CHANGELOG.md │ ├── package.json │ └── src │ │ └── index.ts ├── esbuild-plugin │ ├── CHANGELOG.md │ ├── package.json │ └── src │ │ └── index.ts ├── integration │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ └── src │ │ ├── addFileScope.test.ts │ │ ├── addFileScope.ts │ │ ├── compile.ts │ │ ├── filters.ts │ │ ├── hash.ts │ │ ├── index.ts │ │ ├── packageInfo.ts │ │ ├── processVanillaFile.test.ts │ │ ├── processVanillaFile.ts │ │ ├── serialize.ts │ │ ├── transform.ts │ │ ├── types.ts │ │ └── virtualFile.ts ├── jest-transform │ ├── CHANGELOG.md │ ├── package.json │ └── src │ │ └── index.ts ├── next-plugin │ ├── CHANGELOG.md │ ├── package.json │ └── src │ │ └── index.ts ├── parcel-transformer │ ├── CHANGELOG.md │ ├── package.json │ └── src │ │ └── index.ts ├── private │ ├── CHANGELOG.md │ ├── package.json │ └── src │ │ ├── get.ts │ │ ├── getVarName.ts │ │ ├── index.ts │ │ ├── types.ts │ │ └── walkObject.ts ├── recipes │ ├── CHANGELOG.md │ ├── createRuntimeFn │ │ └── package.json │ ├── package.json │ └── src │ │ ├── createRuntimeFn.ts │ │ ├── index.ts │ │ ├── types.ts │ │ └── utils.ts ├── rollup-plugin │ ├── CHANGELOG.md │ ├── package.json │ ├── src │ │ └── index.ts │ └── test │ │ ├── __snapshots__ │ │ └── rollup-plugin.test.ts.snap │ │ └── rollup-plugin.test.ts ├── sprinkles │ ├── CHANGELOG.md │ ├── README.md │ ├── createRuntimeSprinkles │ │ └── package.json │ ├── createUtils │ │ └── package.json │ ├── package.json │ └── src │ │ ├── createRuntimeSprinkles.ts │ │ ├── createSprinkles.ts │ │ ├── createUtils.ts │ │ ├── index.ts │ │ └── types.ts ├── utils │ ├── CHANGELOG.md │ ├── package.json │ └── src │ │ ├── index.test.ts │ │ └── index.ts ├── vite-plugin │ ├── CHANGELOG.md │ ├── package.json │ └── src │ │ └── index.ts └── webpack-plugin │ ├── CHANGELOG.md │ ├── extracted.js │ ├── loader │ └── package.json │ ├── next │ └── package.json │ ├── package.json │ ├── src │ ├── __snapshots__ │ │ └── compiler.test.ts.snap │ ├── compat.ts │ ├── compiler.test.ts │ ├── compiler.ts │ ├── index.ts │ ├── loader.ts │ ├── logger.ts │ ├── next.ts │ ├── plugin.ts │ ├── types.ts │ ├── virtualFileLoader.ts │ └── virtualNextFileLoader.ts │ ├── vanilla.virtual.css │ ├── virtualFileLoader │ └── package.json │ └── virtualNextFileLoader │ └── package.json ├── playwright.config.ts ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── prettier.config.js ├── scripts ├── build-dts.ts ├── copy-next-plugin.ts ├── copy-readme-to-packages.ts └── package.json ├── site ├── .gitignore ├── babel.config.js ├── code-block-loader.js ├── contents.js ├── docs │ ├── api │ │ ├── add-function-serializer.md │ │ ├── assign-vars.md │ │ ├── create-container.md │ │ ├── create-theme-contract.md │ │ ├── create-theme.md │ │ ├── create-var.md │ │ ├── create-view-transition.md │ │ ├── fallback-var.md │ │ ├── font-face.md │ │ ├── keyframes.md │ │ ├── layer.md │ │ ├── style-variants.md │ │ └── style.md │ ├── global-api │ │ ├── create-global-theme-contract.md │ │ ├── create-global-theme.md │ │ ├── create-global-var.md │ │ ├── global-font-face.md │ │ ├── global-keyframes.md │ │ ├── global-layer.md │ │ └── global-style.md │ ├── integrations │ │ ├── astro.md │ │ ├── esbuild.md │ │ ├── gatsby.md │ │ ├── next.md │ │ ├── parcel.md │ │ ├── remix.md │ │ ├── rollup.md │ │ ├── vite.md │ │ └── webpack.md │ ├── overview │ │ ├── getting-started.md │ │ ├── style-composition.md │ │ ├── styling.md │ │ ├── test-environments.md │ │ └── theming.md │ └── packages │ │ ├── css-utils.md │ │ ├── dynamic.md │ │ ├── recipes.md │ │ └── sprinkles.md ├── documentIndexer.js ├── legacy-routes.json ├── logo.png ├── logo.svg ├── makeDocsManifest.js ├── package.json ├── src │ ├── App.css.ts │ ├── App.tsx │ ├── Blockquote │ │ ├── Blockquote.css.ts │ │ └── Blockquote.tsx │ ├── Chevron │ │ ├── Chevron.css.ts │ │ └── Chevron.tsx │ ├── Code │ │ ├── CompiledCode.css.ts │ │ ├── CompiledCode.tsx │ │ ├── ErrorHighlighter.css.ts │ │ ├── ErrorHighlighter.tsx │ │ ├── SyntaxHighlighter.css.ts │ │ └── SyntaxHighlighter.tsx │ ├── ColorModeToggle │ │ ├── ColorModeToggle.css.ts │ │ └── ColorModeToggle.tsx │ ├── Divider │ │ ├── Divider.css.ts │ │ └── Divider.tsx │ ├── DocsPage │ │ ├── DocsPage.css.ts │ │ ├── DocsPage.tsx │ │ └── SiblingDoc │ │ │ └── SiblingDoc.tsx │ ├── Fab │ │ ├── Fab.css.ts │ │ └── Fab.tsx │ ├── GitHubStars │ │ └── GitHubStars.tsx │ ├── HomePage │ │ ├── HomePage.css.ts │ │ └── HomePage.tsx │ ├── InlineCode │ │ ├── InlineCode.css.ts │ │ └── InlineCode.tsx │ ├── Logo │ │ └── Logo.tsx │ ├── SearchInput │ │ ├── SearchInput.css.ts │ │ └── SearchInput.tsx │ ├── Tweet │ │ ├── Tweet.css.ts │ │ └── Tweet.tsx │ ├── Typography │ │ ├── Heading.tsx │ │ ├── Link.css.ts │ │ ├── Link.tsx │ │ ├── Text.tsx │ │ └── typography.css.ts │ ├── assets │ │ ├── android-chrome-192x192.png │ │ ├── android-chrome-512x512.png │ │ ├── apple-touch-icon.png │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── favicon.ico │ │ ├── og-image.png │ │ └── site.webmanifest │ ├── client.tsx │ ├── docs-store.ts │ ├── index.d.ts │ ├── mdx-components.css.ts │ ├── mdx-components.tsx │ ├── render.tsx │ ├── system │ │ ├── Box │ │ │ └── Box.tsx │ │ ├── ButtonLink │ │ │ ├── ButtonLink.css.ts │ │ │ └── ButtonLink.tsx │ │ ├── Columns │ │ │ └── Columns.tsx │ │ ├── ContentBlock │ │ │ ├── ContentBlock.css.ts │ │ │ └── ContentBlock.tsx │ │ ├── Stack │ │ │ └── Stack.tsx │ │ ├── index.ts │ │ └── styles │ │ │ ├── reset.css.ts │ │ │ └── sprinkles.css.ts │ ├── themeUtils.ts │ ├── themes.css.ts │ └── useHeadingRoute.ts └── webpack.config.js ├── test-helpers ├── CHANGELOG.md ├── package.json └── src │ ├── getStylesheet.ts │ ├── index.ts │ ├── startFixture │ ├── esbuild.ts │ ├── index.ts │ ├── next.ts │ ├── parcel-config.json │ ├── parcel.ts │ ├── types.ts │ ├── vite.ts │ └── webpack.ts │ └── startFixtureCLI.ts ├── tests ├── CHANGELOG.md ├── compiler │ ├── compiler.test.ts │ ├── compiler.vitest.test.ts │ └── fixtures │ │ ├── class-composition │ │ ├── base.css.ts │ │ ├── button.css.ts │ │ ├── shared.css.ts │ │ ├── stepper.css.ts │ │ └── styles.css.ts │ │ ├── recipes │ │ └── recipeClassNames.css.ts │ │ ├── selectors │ │ └── getter.css.ts │ │ ├── tsconfig-paths │ │ ├── src │ │ │ ├── main.css.ts │ │ │ └── main.tsx │ │ └── tsconfig.json │ │ ├── unused-compositions │ │ ├── shared.css.ts │ │ ├── styles_a.css.ts │ │ └── styles_b.css.ts │ │ └── vite-config │ │ ├── alias.css.ts │ │ ├── image.css.ts │ │ ├── plugin.css.ts │ │ ├── test.jpg │ │ └── util │ │ └── vars.css.ts ├── e2e │ ├── features.playwright.ts │ ├── features.playwright.ts-snapshots │ │ ├── features-esbuild--development.css │ │ ├── features-esbuild--production.css │ │ ├── features-esbuild-next--development.css │ │ ├── features-esbuild-next--production.css │ │ ├── features-mini-css-extract--development.css │ │ ├── features-mini-css-extract--production.css │ │ ├── features-parcel--development.css │ │ ├── features-parcel--production.css │ │ └── features-vite--production.css │ ├── fixture.ts │ ├── fixtures-next-development.playwright.ts │ ├── fixtures-next-production.playwright.ts │ ├── layers.playwright.ts │ ├── layers.playwright.ts-snapshots │ │ ├── layers-esbuild--development.css │ │ ├── layers-esbuild--production.css │ │ ├── layers-esbuild-next--development.css │ │ ├── layers-esbuild-next--production.css │ │ ├── layers-mini-css-extract--development.css │ │ ├── layers-mini-css-extract--production.css │ │ ├── layers-parcel--development.css │ │ ├── layers-parcel--production.css │ │ └── layers-vite--production.css │ ├── low-level.playwright.ts │ ├── low-level.playwright.ts-snapshots │ │ ├── low-level-esbuild--development.css │ │ ├── low-level-esbuild--production.css │ │ ├── low-level-esbuild-next--development.css │ │ ├── low-level-esbuild-next--production.css │ │ ├── low-level-mini-css-extract--development.css │ │ ├── low-level-mini-css-extract--production.css │ │ ├── low-level-parcel--development.css │ │ ├── low-level-parcel--production.css │ │ └── low-level-vite--production.css │ ├── recipes.playwright.ts │ ├── recipes.playwright.ts-snapshots │ │ ├── recipes-esbuild--development.css │ │ ├── recipes-esbuild--production.css │ │ ├── recipes-esbuild-next--development.css │ │ ├── recipes-esbuild-next--production.css │ │ ├── recipes-mini-css-extract--development.css │ │ ├── recipes-mini-css-extract--production.css │ │ ├── recipes-parcel--development.css │ │ ├── recipes-parcel--production.css │ │ └── recipes-vite--production.css │ ├── snapshots │ │ ├── features-Desktop---Chromium-darwin.png │ │ ├── features-Mobile---Chromium-darwin.png │ │ ├── layers-Desktop---Chromium-darwin.png │ │ ├── layers-Mobile---Chromium-darwin.png │ │ ├── low-level-Desktop---Chromium-darwin.png │ │ ├── low-level-Mobile---Chromium-darwin.png │ │ ├── recipes-Desktop---Chromium-darwin.png │ │ ├── recipes-Mobile---Chromium-darwin.png │ │ ├── sprinkles-Desktop---Chromium-darwin.png │ │ ├── sprinkles-Mobile---Chromium-darwin.png │ │ ├── template-string-paths-Desktop---Chromium-darwin.png │ │ ├── template-string-paths-Mobile---Chromium-darwin.png │ │ ├── themed-Desktop---Chromium-darwin.png │ │ ├── themed-Mobile---Chromium-darwin.png │ │ ├── thirdparty-Desktop---Chromium-darwin.png │ │ └── thirdparty-Mobile---Chromium-darwin.png │ ├── sprinkles.playwright.ts │ ├── sprinkles.playwright.ts-snapshots │ │ ├── sprinkles-esbuild--development.css │ │ ├── sprinkles-esbuild--production.css │ │ ├── sprinkles-esbuild-next--development.css │ │ ├── sprinkles-esbuild-next--production.css │ │ ├── sprinkles-mini-css-extract--development.css │ │ ├── sprinkles-mini-css-extract--production.css │ │ ├── sprinkles-parcel--development.css │ │ ├── sprinkles-parcel--production.css │ │ └── sprinkles-vite--production.css │ ├── template-string-paths.playwright.ts │ ├── template-string-paths.playwright.ts-snapshots │ │ ├── template-string-paths-mini-css-extract--development.css │ │ └── template-string-paths-mini-css-extract--production.css │ ├── testCases.ts │ ├── themed.playwright.ts │ ├── themed.playwright.ts-snapshots │ │ ├── themed-esbuild--development.css │ │ ├── themed-esbuild--production.css │ │ ├── themed-esbuild-next--development.css │ │ ├── themed-esbuild-next--production.css │ │ ├── themed-mini-css-extract--development.css │ │ ├── themed-mini-css-extract--production.css │ │ ├── themed-parcel--development.css │ │ ├── themed-parcel--production.css │ │ └── themed-vite--production.css │ ├── thirdparty.playwright.ts │ └── thirdparty.playwright.ts-snapshots │ │ ├── thirdparty-esbuild--development.css │ │ ├── thirdparty-esbuild--production.css │ │ ├── thirdparty-esbuild-next--development.css │ │ ├── thirdparty-esbuild-next--production.css │ │ ├── thirdparty-mini-css-extract--development.css │ │ ├── thirdparty-mini-css-extract--production.css │ │ ├── thirdparty-parcel--development.css │ │ ├── thirdparty-parcel--production.css │ │ └── thirdparty-vite--production.css ├── jest-dom │ ├── jest-dom.css.ts │ └── jest-dom.test.ts ├── package.json ├── recipes │ ├── recipes-type-tests.ts │ ├── recipes.css.ts │ └── recipes.test.ts ├── sprinkles │ ├── index.css.ts │ ├── sprinkles-type-tests.ts │ └── sprinkles.test.ts ├── types │ └── type-tests.ts └── walkObject │ ├── tokens.ts │ └── walkObject.vitest.test.ts ├── tsconfig.json └── vitest.config.ts /.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/master/docs/common-questions.md) 9 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@3.0.3/schema.json", 3 | "changelog": [ 4 | "@changesets/changelog-github", 5 | { "repo": "vanilla-extract-css/vanilla-extract" } 6 | ], 7 | "commit": false, 8 | "linked": [], 9 | "access": "public", 10 | "baseBranch": "master", 11 | "updateInternalDependencies": "patch", 12 | "snapshot": { 13 | "useCalculatedVersion": true 14 | }, 15 | "privatePackages": { 16 | "tag": false, "version": false 17 | }, 18 | "___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": { 19 | "onlyUpdatePeerDependentsWhenOutOfRange": true 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Feature requests, Questions & Discussions 4 | url: https://github.com/vanilla-extract-css/vanilla-extract/discussions 5 | about: Use GitHub discussions for message-board style questions and discussions 6 | - name: Discord Chat 7 | url: https://discord.gg/6nCfPwwz6w 8 | about: Ask questions and discuss with other vanilla-extract users in real time. -------------------------------------------------------------------------------- /.github/workflows/deploy-site.yml: -------------------------------------------------------------------------------- 1 | name: Deploy site 2 | 3 | on: push 4 | 5 | jobs: 6 | deploy-site: 7 | name: Deploy site 8 | runs-on: ubuntu-latest 9 | env: 10 | CI: true 11 | steps: 12 | - name: Checkout Repo 13 | uses: actions/checkout@v4 14 | 15 | - name: Set up PNPM 16 | uses: pnpm/action-setup@v4 17 | 18 | - name: Set up Node.js 19 | uses: actions/setup-node@v4 20 | with: 21 | node-version-file: '.nvmrc' 22 | cache: 'pnpm' 23 | 24 | - name: Install Dependencies 25 | run: pnpm install 26 | 27 | - name: Build packages 28 | run: pnpm run build 29 | 30 | - name: Build site 31 | run: pnpm --filter "./site" build 32 | 33 | - name: Draft deploy site to Netlify 34 | run: pnpm --filter "./site" deploy:branch 35 | if: github.ref != 'refs/heads/master' 36 | env: 37 | NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} 38 | 39 | - name: Deploy site to Netlify 40 | run: pnpm --filter "./site" deploy:prod 41 | if: github.ref == 'refs/heads/master' 42 | env: 43 | NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} 44 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | release: 10 | name: Publish & Deploy 11 | runs-on: ubuntu-latest 12 | env: 13 | CI: true 14 | steps: 15 | - name: Checkout Repo 16 | uses: actions/checkout@v4 17 | with: 18 | fetch-depth: 0 19 | token: ${{ secrets.VANILLA_EXTRACT_CI_GITHUB_TOKEN }} 20 | 21 | - name: Set up PNPM 22 | uses: pnpm/action-setup@v4 23 | 24 | - name: Set up Node.js 25 | uses: actions/setup-node@v4 26 | with: 27 | node-version-file: '.nvmrc' 28 | cache: 'pnpm' 29 | 30 | - name: Install Dependencies 31 | run: pnpm install 32 | 33 | - name: Create release PR or publish to npm 34 | uses: changesets/action@v1 35 | with: 36 | version: pnpm run version 37 | publish: pnpm release 38 | env: 39 | GITHUB_TOKEN: ${{ secrets.VANILLA_EXTRACT_CI_GITHUB_TOKEN }} 40 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 41 | -------------------------------------------------------------------------------- /.github/workflows/snapshot.yml: -------------------------------------------------------------------------------- 1 | name: Snapshot 2 | 3 | on: workflow_dispatch 4 | 5 | jobs: 6 | publish: 7 | name: Publish snapshot version 8 | runs-on: ubuntu-latest 9 | env: 10 | CI: true 11 | steps: 12 | - name: Checkout Repo 13 | uses: actions/checkout@v4 14 | with: 15 | # This makes Actions fetch all Git history so that Changesets can generate changelogs with the correct commits 16 | fetch-depth: 0 17 | token: ${{ secrets.VANILLA_EXTRACT_CI_GITHUB_TOKEN }} 18 | 19 | - name: Set up PNPM 20 | uses: pnpm/action-setup@v4 21 | 22 | - name: Set up Node.js 23 | uses: actions/setup-node@v4 24 | with: 25 | node-version-file: '.nvmrc' 26 | cache: 'pnpm' 27 | 28 | - name: Install Dependencies 29 | run: pnpm install 30 | 31 | - name: Publish 32 | uses: seek-oss/changesets-snapshot@v0 33 | with: 34 | pre-publish: pnpm prepare-release 35 | env: 36 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 37 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 38 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | tsconfig.tsbuildinfo 4 | packages/**/README.md 5 | !packages/sprinkles/README.md 6 | !packages/integration/README.md 7 | !packages/compiler/README.md 8 | test-results 9 | .parcel-cache 10 | 11 | .pnp.* 12 | .next 13 | .DS_Store 14 | .idea 15 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | registry=https://registry.npmjs.org/ 2 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 22.15.0 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .vscode/ 3 | node_modules 4 | dist 5 | CHANGELOG.md 6 | README.md 7 | .github/ISSUE_TEMPLATE 8 | site/docs-manifest.json 9 | .changeset 10 | .next 11 | pnpm-lock.yaml 12 | *-snapshots 13 | test-results 14 | examples/remix/build 15 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "node_modules/typescript/lib", 3 | "vitest.enable": true, 4 | "vitest.commandLine": "pnpm test:vitest" 5 | } 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 SEEK 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /babel-jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: './babel.config', 3 | presets: [['@babel/preset-env', { targets: { node: 'current' } }]], 4 | }; 5 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | ['@babel/preset-env', { targets: { node: '14.21' } }], 4 | '@babel/preset-typescript', 5 | ], 6 | overrides: [ 7 | { 8 | include: [ 9 | './packages/css', 10 | './packages/dynamic', 11 | './packages/private', 12 | './packages/recipes', 13 | './packages/sprinkles', 14 | './packages/utils', 15 | ], 16 | presets: [['@babel/preset-env', { targets: { esmodules: true } }]], 17 | }, 18 | ], 19 | }; 20 | -------------------------------------------------------------------------------- /benchmarks/README.md: -------------------------------------------------------------------------------- 1 | # Benchmarks 2 | 3 | This package contains scripts for benchmarking the runtime and type-checking performance of Vanilla Extract APIs. 4 | 5 | ## Running a Benchmark 6 | 7 | Run a benchmark by executing it with `tsx`: 8 | 9 | ```sh 10 | pnpm tsx ./src/css-var-string-literal.ts 11 | ``` 12 | -------------------------------------------------------------------------------- /benchmarks/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@vanilla-extract-private/benchmarks", 3 | "private": true, 4 | "version": "0.0.1", 5 | "author": "SEEK", 6 | "license": "MIT", 7 | "dependencies": { 8 | "@arktype/attest": "^0.43.3", 9 | "@vanilla-extract/css": "workspace:*", 10 | "tsx": "^4.17.0", 11 | "typescript": "^5.8.3" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /benchmarks/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "include": ["src"] 4 | } 5 | -------------------------------------------------------------------------------- /examples/next/components/HelloWorld.css.ts: -------------------------------------------------------------------------------- 1 | import { style, createVar, keyframes, fallbackVar } from '@vanilla-extract/css'; 2 | 3 | const color = createVar(); 4 | const angle = createVar({ 5 | syntax: '', 6 | inherits: false, 7 | initialValue: '0deg', 8 | }); 9 | 10 | const angleKeyframes = keyframes({ 11 | '100%': { 12 | vars: { 13 | [angle]: '360deg', 14 | }, 15 | }, 16 | }); 17 | 18 | export const root = style({ 19 | background: 'pink', 20 | color: 'blue', 21 | padding: '16px', 22 | transition: `opacity .1s ease, color .1s ease`, // Testing autoprefixer 23 | backgroundImage: `linear-gradient(${angle}, rgba(153, 70, 198, 0.35) 0%, rgba(28, 56, 240, 0.46) 100%)`, 24 | animation: `${angleKeyframes} 7s infinite ease-in-out both`, 25 | ':hover': { 26 | opacity: 0.8, 27 | color: color, 28 | }, 29 | 30 | vars: { 31 | [color]: '#fef', 32 | [angle]: fallbackVar(angle, '138deg'), 33 | }, 34 | }); 35 | -------------------------------------------------------------------------------- /examples/next/components/HelloWorld.tsx: -------------------------------------------------------------------------------- 1 | import * as styles from './HelloWorld.css'; 2 | 3 | export function HelloWorld() { 4 | return ( 5 |
6 |

🧁 Hello from vanilla-extract!

7 |
8 | ); 9 | } 10 | -------------------------------------------------------------------------------- /examples/next/next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/basic-features/typescript for more information. 6 | -------------------------------------------------------------------------------- /examples/next/next.config.js: -------------------------------------------------------------------------------- 1 | const { createVanillaExtractPlugin } = require('@vanilla-extract/next-plugin'); 2 | const withVanillaExtract = createVanillaExtractPlugin(); 3 | 4 | module.exports = withVanillaExtract(); 5 | -------------------------------------------------------------------------------- /examples/next/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vanilla-extract-example-next", 3 | "description": "Example project using vanilla-extract, compiling with Next.js", 4 | "version": "0.0.0", 5 | "private": true, 6 | "scripts": { 7 | "dev": "next dev", 8 | "build": "next build", 9 | "start": "next start" 10 | }, 11 | "dependencies": { 12 | "next": "12.3.4", 13 | "react": "^18.2.0", 14 | "react-dom": "^18.2.0" 15 | }, 16 | "devDependencies": { 17 | "@types/react": "^18.2.55", 18 | "@vanilla-extract/css": "workspace:^", 19 | "@vanilla-extract/next-plugin": "workspace:^" 20 | }, 21 | "browserslist": [ 22 | ">0.3%", 23 | "ie 11", 24 | "safari 4", 25 | "not op_mini all" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /examples/next/pages/index.tsx: -------------------------------------------------------------------------------- 1 | import { HelloWorld } from '../components/HelloWorld'; 2 | 3 | export default function Home() { 4 | return ; 5 | } 6 | -------------------------------------------------------------------------------- /examples/next/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanilla-extract-css/vanilla-extract/7efce3a9e733f4a5cc1322541d6e7774ea2d2df0/examples/next/public/favicon.ico -------------------------------------------------------------------------------- /examples/next/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": false, 8 | "forceConsistentCasingInFileNames": true, 9 | "noEmit": true, 10 | "esModuleInterop": true, 11 | "module": "esnext", 12 | "moduleResolution": "node", 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "jsx": "preserve", 16 | "incremental": true 17 | }, 18 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], 19 | "exclude": ["node_modules"] 20 | } 21 | -------------------------------------------------------------------------------- /examples/remix/.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | -------------------------------------------------------------------------------- /examples/remix/app/components/HelloWorld.css.ts: -------------------------------------------------------------------------------- 1 | import { style } from '@vanilla-extract/css'; 2 | 3 | export const root = style({ 4 | background: 'lightcyan', 5 | color: 'oklab(59.686% 0.1009 0.1192)', // Testing Lightning CSS 6 | padding: '16px', 7 | transition: 'opacity .1s ease', 8 | ':hover': { 9 | opacity: 0.8, 10 | }, 11 | }); 12 | -------------------------------------------------------------------------------- /examples/remix/app/components/HelloWorld.tsx: -------------------------------------------------------------------------------- 1 | import * as styles from './HelloWorld.css'; 2 | 3 | export function HelloWorld() { 4 | return ( 5 |
6 |

🧁 Hello from vanilla-extract!

7 |
8 | ); 9 | } 10 | -------------------------------------------------------------------------------- /examples/remix/app/root.tsx: -------------------------------------------------------------------------------- 1 | import { Links, Meta, Outlet, Scripts } from '@remix-run/react'; 2 | 3 | export default function App() { 4 | return ( 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /examples/remix/app/routes/_index.tsx: -------------------------------------------------------------------------------- 1 | import type { MetaFunction } from '@remix-run/node'; 2 | 3 | import { HelloWorld } from '../components/HelloWorld'; 4 | 5 | export const meta: MetaFunction = () => { 6 | return [{ title: 'Remix Example' }]; 7 | }; 8 | 9 | export default function Index() { 10 | return ; 11 | } 12 | -------------------------------------------------------------------------------- /examples/remix/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | -------------------------------------------------------------------------------- /examples/remix/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vanilla-extract-example-remix", 3 | "version": "0.0.6", 4 | "private": true, 5 | "type": "module", 6 | "scripts": { 7 | "dev": "remix vite:dev", 8 | "build": "remix vite:build", 9 | "start": "remix-serve ./build/server/index.js" 10 | }, 11 | "dependencies": { 12 | "@remix-run/node": "^2.8.0", 13 | "@remix-run/react": "^2.8.0", 14 | "@remix-run/serve": "^2.8.0", 15 | "@vanilla-extract/css": "workspace:*", 16 | "isbot": "^4", 17 | "react": "^18.2.0", 18 | "react-dom": "^18.2.0" 19 | }, 20 | "devDependencies": { 21 | "@remix-run/dev": "^2.8.0", 22 | "@types/react": "^18.2.55", 23 | "@vanilla-extract/vite-plugin": "workspace:*", 24 | "vite": "^5.0.0 || ^6.0.0" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /examples/remix/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanilla-extract-css/vanilla-extract/7efce3a9e733f4a5cc1322541d6e7774ea2d2df0/examples/remix/public/favicon.ico -------------------------------------------------------------------------------- /examples/remix/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["env.d.ts", "**/*.ts", "**/*.tsx"], 3 | "compilerOptions": { 4 | "lib": ["DOM", "DOM.Iterable", "ES2022"], 5 | "isolatedModules": true, 6 | "esModuleInterop": true, 7 | "jsx": "react-jsx", 8 | "module": "ESNext", 9 | "moduleResolution": "Bundler", 10 | "resolveJsonModule": true, 11 | "target": "ES2022", 12 | "strict": true, 13 | "allowJs": true, 14 | "forceConsistentCasingInFileNames": true, 15 | "baseUrl": ".", 16 | "paths": { 17 | "~/*": ["./app/*"] 18 | }, 19 | 20 | // Remix takes care of building everything in `remix build`. 21 | "noEmit": true 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /examples/remix/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import { vanillaExtractPlugin } from '@vanilla-extract/vite-plugin'; 3 | import { vitePlugin as remix } from '@remix-run/dev'; 4 | 5 | export default defineConfig({ 6 | css: { 7 | transformer: 'lightningcss', 8 | lightningcss: { 9 | targets: { 10 | ios_saf: 12, 11 | }, 12 | }, 13 | }, 14 | plugins: [remix(), vanillaExtractPlugin()], 15 | }); 16 | -------------------------------------------------------------------------------- /examples/webpack-react/sandbox.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "template": "node", 3 | "node": "14", 4 | "container": { 5 | "node": "14" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /examples/webpack-react/src/App.css.ts: -------------------------------------------------------------------------------- 1 | import { style } from '@vanilla-extract/css'; 2 | import { sprinkles } from './sprinkles.css'; 3 | 4 | export const card = style([ 5 | sprinkles({ 6 | background: { 7 | lightMode: 'green-50', 8 | darkMode: 'gray-800', 9 | }, 10 | borderRadius: { 11 | mobile: '4x', 12 | desktop: '5x', 13 | }, 14 | padding: { 15 | mobile: '7x', 16 | desktop: '8x', 17 | }, 18 | }), 19 | { 20 | transition: 'transform 4s ease-in-out', 21 | ':hover': { 22 | cursor: 'default', 23 | transform: 'scale(2) rotate(720deg)', 24 | }, 25 | }, 26 | ]); 27 | -------------------------------------------------------------------------------- /examples/webpack-react/src/global.css.ts: -------------------------------------------------------------------------------- 1 | import { globalStyle } from '@vanilla-extract/css'; 2 | 3 | globalStyle('body, body *', { 4 | all: 'unset', 5 | boxSizing: 'border-box', 6 | }); 7 | -------------------------------------------------------------------------------- /examples/webpack-react/src/index.tsx: -------------------------------------------------------------------------------- 1 | import { render } from 'react-dom'; 2 | import './global.css'; 3 | import { App } from './App'; 4 | 5 | const root = document.createElement('div'); 6 | document.body.appendChild(root); 7 | 8 | render(, root); 9 | -------------------------------------------------------------------------------- /fixtures/features/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Vite App 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /fixtures/features/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@fixtures/features", 3 | "version": "0.0.31", 4 | "main": "src/index.ts", 5 | "sideEffects": true, 6 | "author": "SEEK", 7 | "private": true, 8 | "dependencies": { 9 | "@vanilla-extract/css": "workspace:^", 10 | "@vanilla-extract/dynamic": "workspace:^" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /fixtures/features/src/html.ts: -------------------------------------------------------------------------------- 1 | import * as styles from './features.css'; 2 | import testNodes from '../test-nodes.json'; 3 | 4 | export default ` 5 |
Merged style
6 |
Style with composition
7 |
Style variants with composition
8 |
Style variants with mapped composition
9 |
Composition only
10 |
Style composition in selector
11 |
Style variants composition in selector
12 | `; 13 | 14 | // @ts-expect-error Vite env not defined 15 | if (import.meta.hot) { 16 | // @ts-expect-error Vite env not defined 17 | import.meta.hot.accept(); 18 | } 19 | -------------------------------------------------------------------------------- /fixtures/features/src/index.ts: -------------------------------------------------------------------------------- 1 | import html from './html'; 2 | 3 | function render() { 4 | document.body.innerHTML = html; 5 | } 6 | 7 | render(); 8 | -------------------------------------------------------------------------------- /fixtures/features/test-nodes.json: -------------------------------------------------------------------------------- 1 | { 2 | "mergedStyle": "mergedStyle", 3 | "styleWithComposition": "styleWithComposition", 4 | "styleVariantsWithComposition": "styleVariantsWithComposition", 5 | "styleVariantsWithMappedComposition": "styleVariantsWithMappedComposition", 6 | "compositionOnly": "compositionOnly", 7 | "styleCompositionInSelector": "styleCompositionInSelector", 8 | "styleVariantsCompositionInSelector": "styleVariantsCompositionInSelector" 9 | } 10 | -------------------------------------------------------------------------------- /fixtures/layers/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Layers 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /fixtures/layers/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@fixtures/layers", 3 | "version": "0.0.14", 4 | "main": "src/index.ts", 5 | "author": "SEEK", 6 | "private": true, 7 | "dependencies": { 8 | "@vanilla-extract/css": "workspace:^" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /fixtures/layers/src/index.ts: -------------------------------------------------------------------------------- 1 | import { link, pink } from './styles.css'; 2 | 3 | const html = String.raw; 4 | 5 | document.body.innerHTML = html` 6 |
7 |

8 | This link should be red on mobile, green on 9 | desktop. 10 |

11 |

12 | This link with class of link 13 | should be blue on mobile, green on desktop. 14 |

15 |

16 | This link with class of pink 17 | should be pink on mobile, green on desktop. 18 |

19 |
20 | `; 21 | -------------------------------------------------------------------------------- /fixtures/layers/src/styles.css.ts: -------------------------------------------------------------------------------- 1 | import { style, globalStyle, layer, globalLayer } from '@vanilla-extract/css'; 2 | 3 | /* 4 | The resulting layer order: 5 | 1. lib 6 | 2. base 7 | 3. typography (when above 600px) 8 | 4. utilities 9 | 5. typography (when below 600px) 10 | 11 | This will make links red/blue/pink when below 600px and green when above 600px. 12 | */ 13 | 14 | const typography = 'typography'; // this layer is defined conditionally 15 | 16 | const lib = globalLayer('lib'); 17 | const base = layer({ parent: lib }); 18 | 19 | globalStyle('a', { 20 | '@media': { 21 | 'screen and (min-width: 600px)': { 22 | '@layer': { 23 | [typography]: { 24 | color: 'green', // styles *all* links 25 | fontSize: '1.5rem', 26 | }, 27 | }, 28 | }, 29 | }, 30 | '@layer': { 31 | [base]: { 32 | fontWeight: 800, 33 | color: 'red', 34 | }, 35 | }, 36 | }); 37 | 38 | export const link = style({ 39 | '@layer': { 40 | [base]: { 41 | color: 'blue', 42 | }, 43 | }, 44 | }); 45 | 46 | const utilities = layer({ parent: lib }); 47 | 48 | export const pink = style({ 49 | '@layer': { 50 | [utilities]: { 51 | color: 'hotpink', // styles *all* .pink's 52 | }, 53 | }, 54 | }); 55 | 56 | globalLayer(typography); 57 | -------------------------------------------------------------------------------- /fixtures/low-level/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Vite App 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /fixtures/low-level/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@fixtures/low-level", 3 | "version": "0.0.31", 4 | "main": "src/index.ts", 5 | "author": "SEEK", 6 | "private": true, 7 | "dependencies": { 8 | "@vanilla-extract/css": "workspace:^" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /fixtures/low-level/src/index.ts: -------------------------------------------------------------------------------- 1 | import { block, container } from './styles.css'; 2 | import testNodes from '../test-nodes.json'; 3 | 4 | document.body.innerHTML = ` 5 |
6 |
7 | I'm a block 8 |
9 |
10 | `; 11 | -------------------------------------------------------------------------------- /fixtures/low-level/src/styles.css.ts: -------------------------------------------------------------------------------- 1 | import { style, createVar, createContainer } from '@vanilla-extract/css'; 2 | 3 | const color = createVar(); 4 | 5 | const myContainer = createContainer('my-container'); 6 | 7 | export const container = style({ 8 | containerType: 'size', 9 | containerName: myContainer, 10 | width: 500, 11 | }); 12 | 13 | export const block = style({ 14 | vars: { 15 | [color]: 'blue', 16 | }, 17 | backgroundColor: color, 18 | padding: 20, 19 | '@media': { 20 | 'screen and (min-width: 200px)': { 21 | '@container': { 22 | [`${myContainer} (min-width: 400px)`]: { 23 | color: 'white', 24 | }, 25 | }, 26 | }, 27 | }, 28 | }); 29 | -------------------------------------------------------------------------------- /fixtures/low-level/test-nodes.json: -------------------------------------------------------------------------------- 1 | { 2 | "block": "block" 3 | } 4 | -------------------------------------------------------------------------------- /fixtures/next-app-router/next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/basic-features/typescript for more information. 6 | -------------------------------------------------------------------------------- /fixtures/next-app-router/next.config.js: -------------------------------------------------------------------------------- 1 | const { 2 | createVanillaExtractPlugin, 3 | } = require('./next-plugin/dist/vanilla-extract-next-plugin.cjs.js'); 4 | 5 | const withVanillaExtract = createVanillaExtractPlugin(); 6 | 7 | /** @type {import('next').NextConfig} */ 8 | const config = withVanillaExtract({ 9 | // exporting a static build for next 13 10 | // due to issues with distDir on next custom server 11 | output: 'export', 12 | // we need to differentiate build and dev folders 13 | // so they don't overwrite eachother when running tests 14 | distDir: process.env.NODE_ENV === 'production' ? 'dist' : '.next', 15 | experimental: { 16 | externalDir: true, 17 | }, 18 | onDemandEntries: { 19 | // Make sure entries are not getting disposed. 20 | maxInactiveAge: 1000 * 60 * 60, 21 | }, 22 | }); 23 | 24 | module.exports = config; 25 | -------------------------------------------------------------------------------- /fixtures/next-app-router/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@fixtures/next-app-router", 3 | "description": "Next app router fixtures", 4 | "version": "0.0.7", 5 | "private": true, 6 | "scripts": { 7 | "dev": "next dev", 8 | "build": "next build", 9 | "start": "next start", 10 | "clean-build": "pnpm clean && pnpm build", 11 | "clean": "pnpm clean:dev && pnpm clean:prod", 12 | "clean:dev": "rm -rf .next", 13 | "clean:prod": "rm -rf dist" 14 | }, 15 | "dependencies": { 16 | "@fixtures/features": "workspace:*", 17 | "@fixtures/recipes": "workspace:*", 18 | "@fixtures/sprinkles": "workspace:*", 19 | "@vanilla-extract/css": "workspace:*", 20 | "@vanilla-extract/recipes": "workspace:*", 21 | "@vanilla-extract/sprinkles": "workspace:*", 22 | "next": "npm:next@13.5.4", 23 | "react": "^18.2.0", 24 | "react-dom": "^18.2.0" 25 | }, 26 | "devDependencies": { 27 | "@types/react": "^18.2.55", 28 | "@vanilla-extract/next-plugin": "workspace:*", 29 | "@vanilla-extract/webpack-plugin": "workspace:*" 30 | }, 31 | "browserslist": [ 32 | ">0.3%", 33 | "ie 11", 34 | "safari 4", 35 | "not op_mini all" 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /fixtures/next-app-router/src/app/features/page.tsx: -------------------------------------------------------------------------------- 1 | import html from '@fixtures/features/src/html'; 2 | 3 | export default function Features() { 4 | return ( 5 | <> 6 | 7 |
8 | 9 | ); 10 | } 11 | -------------------------------------------------------------------------------- /fixtures/next-app-router/src/app/layout.tsx: -------------------------------------------------------------------------------- 1 | export default function RootLayout({ 2 | children, 3 | }: { 4 | children: React.ReactNode; 5 | }) { 6 | return ( 7 | 8 | {children} 9 | 10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /fixtures/next-app-router/src/app/page.tsx: -------------------------------------------------------------------------------- 1 | import Link from 'next/link'; 2 | 3 | export default function Home() { 4 | return ( 5 | <> 6 | sprinkles 7 |
8 | recipes 9 |
10 | features 11 | 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /fixtures/next-app-router/src/app/recipes/page.tsx: -------------------------------------------------------------------------------- 1 | import html from '@fixtures/recipes/src/html'; 2 | 3 | export default function Recipes() { 4 | return ( 5 | <> 6 | 7 |
8 | 9 | ); 10 | } 11 | -------------------------------------------------------------------------------- /fixtures/next-app-router/src/app/sprinkles/page.tsx: -------------------------------------------------------------------------------- 1 | import html from '@fixtures/sprinkles/src/html'; 2 | 3 | export default function Sprinkles() { 4 | return ( 5 | <> 6 | 7 |
8 | 9 | ); 10 | } 11 | -------------------------------------------------------------------------------- /fixtures/next-app-router/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "forceConsistentCasingInFileNames": true, 5 | "jsx": "preserve", 6 | "plugins": [ 7 | { 8 | "name": "next" 9 | } 10 | ], 11 | "strictNullChecks": true 12 | }, 13 | "include": [ 14 | "next-env.d.ts", 15 | "**/*.ts", 16 | "**/*.tsx", 17 | ".next/types/**/*.ts", 18 | "dist/types/**/*.ts" 19 | ], 20 | "exclude": ["node_modules"] 21 | } 22 | -------------------------------------------------------------------------------- /fixtures/next-pages-router/next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/basic-features/typescript for more information. 6 | -------------------------------------------------------------------------------- /fixtures/next-pages-router/next.config.js: -------------------------------------------------------------------------------- 1 | const { 2 | createVanillaExtractPlugin, 3 | } = require('./next-plugin/dist/vanilla-extract-next-plugin.cjs.js'); 4 | 5 | const withVanillaExtract = createVanillaExtractPlugin(); 6 | 7 | /** @type {import('next').NextConfig} */ 8 | const config = withVanillaExtract({ 9 | // we need to differentiate build and dev folders 10 | // so they don't overwrite eachother when running tests 11 | distDir: process.env.NODE_ENV === 'production' ? 'dist' : '.next', 12 | experimental: { 13 | externalDir: true, 14 | }, 15 | onDemandEntries: { 16 | // Make sure entries are not getting disposed. 17 | maxInactiveAge: 1000 * 60 * 60, 18 | }, 19 | }); 20 | 21 | module.exports = config; 22 | -------------------------------------------------------------------------------- /fixtures/next-pages-router/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@fixtures/next-pages-router", 3 | "description": "Next pages router fixtures", 4 | "version": "0.0.7", 5 | "private": true, 6 | "scripts": { 7 | "dev": "next dev", 8 | "build": "next build", 9 | "start": "next start", 10 | "clean-build": "pnpm clean && next build", 11 | "clean": "pnpm clean:dev && pnpm clean:prod", 12 | "clean:dev": "rm -rf .next", 13 | "clean:prod": "rm -rf dist" 14 | }, 15 | "dependencies": { 16 | "@fixtures/features": "workspace:*", 17 | "@fixtures/recipes": "workspace:*", 18 | "@fixtures/sprinkles": "workspace:*", 19 | "@vanilla-extract/css": "workspace:*", 20 | "@vanilla-extract/recipes": "workspace:*", 21 | "@vanilla-extract/sprinkles": "workspace:*", 22 | "next": "12.3.4", 23 | "react": "^18.2.0", 24 | "react-dom": "^18.2.0" 25 | }, 26 | "devDependencies": { 27 | "@types/react": "^18.2.55", 28 | "@vanilla-extract/next-plugin": "workspace:*", 29 | "@vanilla-extract/webpack-plugin": "workspace:*" 30 | }, 31 | "browserslist": [ 32 | ">0.3%", 33 | "ie 11", 34 | "safari 4", 35 | "not op_mini all" 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /fixtures/next-pages-router/src/pages/features/index.tsx: -------------------------------------------------------------------------------- 1 | import html from '@fixtures/features/src/html'; 2 | 3 | export default function Features() { 4 | return ( 5 | <> 6 | 7 |
8 | 9 | ); 10 | } 11 | -------------------------------------------------------------------------------- /fixtures/next-pages-router/src/pages/index.tsx: -------------------------------------------------------------------------------- 1 | import Link from 'next/link'; 2 | 3 | export default function Home() { 4 | return ( 5 | <> 6 | sprinkles 7 |
8 | recipes 9 |
10 | features 11 | 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /fixtures/next-pages-router/src/pages/recipes/index.tsx: -------------------------------------------------------------------------------- 1 | import html from '@fixtures/recipes/src/html'; 2 | 3 | export default function Recipes() { 4 | return ( 5 | <> 6 | 7 |
8 | 9 | ); 10 | } 11 | -------------------------------------------------------------------------------- /fixtures/next-pages-router/src/pages/sprinkles/index.tsx: -------------------------------------------------------------------------------- 1 | import html from '@fixtures/sprinkles/src/html'; 2 | 3 | export default function Sprinkles() { 4 | return ( 5 | <> 6 | 7 |
8 | 9 | ); 10 | } 11 | -------------------------------------------------------------------------------- /fixtures/next-pages-router/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "forceConsistentCasingInFileNames": true, 5 | "jsx": "preserve", 6 | "strictNullChecks": true 7 | }, 8 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], 9 | "exclude": ["node_modules"] 10 | } 11 | -------------------------------------------------------------------------------- /fixtures/recipes/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Vite App 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /fixtures/recipes/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@fixtures/recipes", 3 | "version": "0.0.36", 4 | "main": "src/index.ts", 5 | "sideEffects": true, 6 | "author": "SEEK", 7 | "private": true, 8 | "dependencies": { 9 | "@vanilla-extract/css": "workspace:^", 10 | "@vanilla-extract/recipes": "workspace:^" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /fixtures/recipes/src/html.ts: -------------------------------------------------------------------------------- 1 | import { button, stack } from './styles.css'; 2 | 3 | export default `
4 | 7 | 10 | 13 | 20 |
`; 21 | -------------------------------------------------------------------------------- /fixtures/recipes/src/index.ts: -------------------------------------------------------------------------------- 1 | import html from './html'; 2 | 3 | function render() { 4 | document.body.innerHTML = html; 5 | } 6 | 7 | render(); 8 | -------------------------------------------------------------------------------- /fixtures/sprinkles/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Vite App 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /fixtures/sprinkles/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@fixtures/sprinkles", 3 | "version": "0.0.36", 4 | "main": "src/index.ts", 5 | "sideEffects": true, 6 | "author": "SEEK", 7 | "private": true, 8 | "dependencies": { 9 | "@vanilla-extract/css": "workspace:^", 10 | "@vanilla-extract/sprinkles": "workspace:^" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /fixtures/sprinkles/src/html.ts: -------------------------------------------------------------------------------- 1 | import { 2 | sprinkles, 3 | mapResponsiveValue, 4 | normalizeResponsiveValue, 5 | preComposedSprinkles, 6 | preComposedSprinklesUsedInSelector, 7 | container, 8 | } from './styles.css'; 9 | import testNodes from '../test-nodes.json'; 10 | 11 | export default ` 12 |
13 |
23 | Sprinkles 24 |
25 |
Precomposed sprinkles
26 |
Precomposed Sprinkles Used In Selector
27 |
28 | `; 29 | -------------------------------------------------------------------------------- /fixtures/sprinkles/src/index.ts: -------------------------------------------------------------------------------- 1 | import html from './html'; 2 | 3 | function render() { 4 | document.body.innerHTML = html; 5 | } 6 | 7 | render(); 8 | -------------------------------------------------------------------------------- /fixtures/sprinkles/test-nodes.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": "root" 3 | } 4 | -------------------------------------------------------------------------------- /fixtures/template-string-paths/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Vite App 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /fixtures/template-string-paths/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@fixtures/template-string-paths", 3 | "version": "0.0.8", 4 | "main": "src/index.ts", 5 | "sideEffects": true, 6 | "author": "SEEK", 7 | "private": true, 8 | "dependencies": { 9 | "@vanilla-extract/css": "workspace:^" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /fixtures/template-string-paths/src/[...slug]/index.css.ts: -------------------------------------------------------------------------------- 1 | import { style } from '@vanilla-extract/css'; 2 | 3 | export const catchAllSegment = style({ color: 'lime' }); 4 | -------------------------------------------------------------------------------- /fixtures/template-string-paths/src/[[...slug]]/index.css.ts: -------------------------------------------------------------------------------- 1 | import { style } from '@vanilla-extract/css'; 2 | 3 | export const optionalCatchAllSegment = style({ color: 'orchid' }); 4 | -------------------------------------------------------------------------------- /fixtures/template-string-paths/src/[[id]]/index.css.ts: -------------------------------------------------------------------------------- 1 | import { style } from '@vanilla-extract/css'; 2 | 3 | export const doubleSquareBracketId = style({ color: 'darkkhaki' }); 4 | -------------------------------------------------------------------------------- /fixtures/template-string-paths/src/[]/index.css.ts: -------------------------------------------------------------------------------- 1 | import { style } from '@vanilla-extract/css'; 2 | 3 | export const emptySquareBrackets = style({ color: 'blue' }); 4 | -------------------------------------------------------------------------------- /fixtures/template-string-paths/src/[blog-id]/index.css.ts: -------------------------------------------------------------------------------- 1 | import { style } from '@vanilla-extract/css'; 2 | 3 | export const withHyphen = style({ color: 'indigo' }); 4 | -------------------------------------------------------------------------------- /fixtures/template-string-paths/src/[id]/index.css.ts: -------------------------------------------------------------------------------- 1 | import { style } from '@vanilla-extract/css'; 2 | 3 | export const singleSquareBracketsId = style({ color: 'tomato' }); 4 | -------------------------------------------------------------------------------- /fixtures/template-string-paths/src/index.ts: -------------------------------------------------------------------------------- 1 | import { emptySquareBrackets } from './[]/index.css'; 2 | import { singleSquareBracketsId } from './[id]/index.css'; 3 | import { doubleSquareBracketId } from './[[id]]/index.css'; 4 | import { catchAllSegment } from './[...slug]/index.css'; 5 | import { optionalCatchAllSegment } from './[[...slug]]/index.css'; 6 | import { withHyphen } from './[blog-id]/index.css'; 7 | 8 | // Fixture for testing escaping of webpack template strings and Next.js dyanmic routes 9 | // https://webpack.js.org/configuration/output/#template-strings 10 | // https://nextjs.org/docs/app/building-your-application/routing/dynamic-routes 11 | function render() { 12 | document.body.innerHTML = ` 13 |
[] path
14 |
[id] path
15 |
[[id]] path
16 |
[...slug] path
17 |
[[...slug]] path
18 |
[blog-id] path
19 | `; 20 | } 21 | 22 | render(); 23 | -------------------------------------------------------------------------------- /fixtures/themed/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Vite App 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /fixtures/themed/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@fixtures/themed", 3 | "version": "0.0.31", 4 | "main": "src/index.ts", 5 | "sideEffects": true, 6 | "author": "SEEK", 7 | "private": true, 8 | "dependencies": { 9 | "@vanilla-extract/css": "workspace:^", 10 | "@vanilla-extract/dynamic": "workspace:^" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /fixtures/themed/src/shared.css.ts: -------------------------------------------------------------------------------- 1 | import { globalStyle, style } from '@vanilla-extract/css'; 2 | 3 | export const shadow: string = style({ 4 | boxShadow: '0 0 5px red', 5 | }); 6 | 7 | globalStyle('body', { 8 | backgroundColor: 'skyblue', 9 | }); 10 | 11 | // make the screenshot less flaky in CI 12 | globalStyle('body, button', { 13 | lineHeight: '16px', 14 | }); 15 | -------------------------------------------------------------------------------- /fixtures/themed/test-nodes.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": "root", 3 | "rootContainer": "rootContainer", 4 | "rootButton": "rootButton", 5 | "altContainer": "altContainer", 6 | "altButton": "altButton", 7 | "nestedRootContainer": "nestedRootContainer", 8 | "nestedRootButton": "nestedRootButton", 9 | "inlineThemeContainer": "inlineThemeContainer", 10 | "inlineThemeButton": "inlineThemeButton", 11 | "dynamicVarsContainer": "dynamicVarsContainer", 12 | "dynamicVarsButton": "dynamicVarsButton", 13 | "responsiveThemeContainer": "responsiveThemeContainer", 14 | "responsiveThemeButton": "responsiveThemeButton" 15 | } 16 | -------------------------------------------------------------------------------- /fixtures/thirdparty/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Vite App 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /fixtures/thirdparty/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@fixtures/thirdparty", 3 | "version": "0.0.9", 4 | "main": "src/index.ts", 5 | "author": "SEEK", 6 | "private": true, 7 | "dependencies": { 8 | "@fixtures/thirdparty-dep": "workspace:*", 9 | "@vanilla-extract/css": "workspace:*" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /fixtures/thirdparty/src/index.ts: -------------------------------------------------------------------------------- 1 | import { block, depBlock, depdepBlock } from './styles.css'; 2 | import testNodes from '../test-nodes.json'; 3 | 4 | document.body.innerHTML = ` 5 |
6 | I'm a first-party block 7 |
8 | I'm a third party block 9 |
10 | I'm a third party of third party block 11 |
12 |
13 |
14 | `; 15 | -------------------------------------------------------------------------------- /fixtures/thirdparty/src/styles.css.ts: -------------------------------------------------------------------------------- 1 | import { style, createVar } from '@vanilla-extract/css'; 2 | 3 | export { 4 | depBlock, 5 | depColor, 6 | depdepBlock, 7 | depdepColor, 8 | } from '@fixtures/thirdparty-dep'; 9 | 10 | const color = createVar(); 11 | 12 | export const block = style({ 13 | vars: { 14 | [color]: 'red', 15 | }, 16 | backgroundColor: color, 17 | }); 18 | -------------------------------------------------------------------------------- /fixtures/thirdparty/test-nodes.json: -------------------------------------------------------------------------------- 1 | { 2 | "first": "first", 3 | "third": "third", 4 | "thirdThird": "thirdThird" 5 | } 6 | -------------------------------------------------------------------------------- /fixtures/thirdparty/thirdparty-dep/index.mjs: -------------------------------------------------------------------------------- 1 | export { depBlock, depColor } from './styles.css.mjs'; 2 | 3 | export { depdepBlock, depdepColor } from '@fixtures/thirdparty-dep-dep'; 4 | -------------------------------------------------------------------------------- /fixtures/thirdparty/thirdparty-dep/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@fixtures/thirdparty-dep", 3 | "version": "0.0.9", 4 | "exports": { 5 | ".": { 6 | "import": "./index.mjs" 7 | }, 8 | "./package.json": "./package.json" 9 | }, 10 | "author": "SEEK", 11 | "private": true, 12 | "dependencies": { 13 | "@fixtures/thirdparty-dep-dep": "workspace:*", 14 | "@vanilla-extract/css": "workspace:^" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /fixtures/thirdparty/thirdparty-dep/styles.css.mjs: -------------------------------------------------------------------------------- 1 | import { style, createVar } from '@vanilla-extract/css'; 2 | 3 | export const depColor = createVar(); 4 | 5 | export const depBlock = style({ 6 | vars: { 7 | [depColor]: 'green', 8 | }, 9 | backgroundColor: depColor, 10 | }); 11 | -------------------------------------------------------------------------------- /fixtures/thirdparty/thirdparty-dep/thirdparty-dep-dep/index.mjs: -------------------------------------------------------------------------------- 1 | export { depdepBlock, depdepColor } from './styles.css.mjs'; 2 | -------------------------------------------------------------------------------- /fixtures/thirdparty/thirdparty-dep/thirdparty-dep-dep/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@fixtures/thirdparty-dep-dep", 3 | "version": "0.0.9", 4 | "exports": { 5 | ".": { 6 | "import": "./index.mjs" 7 | }, 8 | "./package.json": "./package.json" 9 | }, 10 | "author": "SEEK", 11 | "private": true, 12 | "dependencies": { 13 | "@vanilla-extract/css": "workspace:^" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /fixtures/thirdparty/thirdparty-dep/thirdparty-dep-dep/styles.css.mjs: -------------------------------------------------------------------------------- 1 | import { style, createVar } from '@vanilla-extract/css'; 2 | 3 | export const depdepColor = createVar(); 4 | 5 | export const depdepBlock = style({ 6 | vars: { 7 | [depdepColor]: 'blue', 8 | }, 9 | backgroundColor: depdepColor, 10 | }); 11 | -------------------------------------------------------------------------------- /fixtures/unused-modules/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Vite App 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /fixtures/unused-modules/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@fixtures/unused-modules", 3 | "version": "1.0.31", 4 | "main": "src/index.ts", 5 | "sideEffects": [ 6 | "src/global.css.ts" 7 | ], 8 | "author": "SEEK", 9 | "private": true, 10 | "dependencies": { 11 | "@vanilla-extract/css": "workspace:^" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /fixtures/unused-modules/src/global.css.ts: -------------------------------------------------------------------------------- 1 | import { globalStyle } from '@vanilla-extract/css'; 2 | 3 | globalStyle('body', { 4 | backgroundColor: 'lavender', 5 | }); 6 | -------------------------------------------------------------------------------- /fixtures/unused-modules/src/index.ts: -------------------------------------------------------------------------------- 1 | import './global.css'; 2 | import { usedStyle } from './lookup'; 3 | import { resetStyle } from './reset'; 4 | import testNodes from '../test-nodes.json'; 5 | 6 | const node = document.createElement('div'); 7 | 8 | node.setAttribute('id', testNodes.root); 9 | node.setAttribute('class', `${resetStyle} ${usedStyle}`); 10 | 11 | document.body.appendChild(node); 12 | -------------------------------------------------------------------------------- /fixtures/unused-modules/src/lookup.ts: -------------------------------------------------------------------------------- 1 | export * from './unused'; 2 | export * from './used'; 3 | export * from './reset'; 4 | -------------------------------------------------------------------------------- /fixtures/unused-modules/src/reset/index.ts: -------------------------------------------------------------------------------- 1 | export { default as resetStyle } from './reset.css'; 2 | -------------------------------------------------------------------------------- /fixtures/unused-modules/src/reset/reset.css.ts: -------------------------------------------------------------------------------- 1 | import { style } from '@vanilla-extract/css'; 2 | 3 | export default style({ 4 | boxSizing: 'border-box', 5 | }); 6 | -------------------------------------------------------------------------------- /fixtures/unused-modules/src/shared/index.ts: -------------------------------------------------------------------------------- 1 | export { default as sharedStyle } from './shared.css'; 2 | -------------------------------------------------------------------------------- /fixtures/unused-modules/src/shared/shared.css.ts: -------------------------------------------------------------------------------- 1 | import { globalStyle, style } from '@vanilla-extract/css'; 2 | 3 | globalStyle('body', { 4 | border: '5px solid black', 5 | }); 6 | 7 | export default style({ 8 | display: 'flex', 9 | }); 10 | -------------------------------------------------------------------------------- /fixtures/unused-modules/src/unused/index.ts: -------------------------------------------------------------------------------- 1 | export { default as unusedStyle } from './unused.css'; 2 | -------------------------------------------------------------------------------- /fixtures/unused-modules/src/unused/unused.css.ts: -------------------------------------------------------------------------------- 1 | import { style } from '@vanilla-extract/css'; 2 | import { sharedStyle } from '../shared'; 3 | 4 | const className = style({ 5 | color: 'red', 6 | backgroundColor: 'blue', 7 | }); 8 | 9 | export default `${className} ${sharedStyle}`; 10 | -------------------------------------------------------------------------------- /fixtures/unused-modules/src/used/index.ts: -------------------------------------------------------------------------------- 1 | export { default as usedStyle } from './used.css'; 2 | -------------------------------------------------------------------------------- /fixtures/unused-modules/src/used/used.css.ts: -------------------------------------------------------------------------------- 1 | import { style } from '@vanilla-extract/css'; 2 | import { sharedStyle } from '../shared'; 3 | 4 | const className = style({ 5 | height: 100, 6 | width: 100, 7 | background: 'green', 8 | }); 9 | 10 | export default `${className} ${sharedStyle}`; 11 | -------------------------------------------------------------------------------- /fixtures/unused-modules/test-nodes.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": "root" 3 | } 4 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | setupFilesAfterEnv: ['./jest.setup.ts'], 3 | transform: { 4 | '\\.css\\.ts$': '@vanilla-extract/jest-transform', 5 | '\\.tsx?$': ['babel-jest', { configFile: './babel-jest.config.js' }], 6 | }, 7 | testMatch: ['**/?(*.)+(test).[jt]s?(x)', '!**/*.vitest.test*'], 8 | testTimeout: 10000, 9 | }; 10 | -------------------------------------------------------------------------------- /jest.setup.ts: -------------------------------------------------------------------------------- 1 | import '@testing-library/jest-dom'; 2 | -------------------------------------------------------------------------------- /packages/babel-plugin-debug-ids/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@vanilla-extract/babel-plugin-debug-ids", 3 | "version": "1.2.0", 4 | "description": "Zero-runtime Stylesheets-in-TypeScript", 5 | "main": "dist/vanilla-extract-babel-plugin-debug-ids.cjs.js", 6 | "module": "dist/vanilla-extract-babel-plugin-debug-ids.esm.js", 7 | "types": "dist/vanilla-extract-babel-plugin-debug-ids.cjs.d.ts", 8 | "preconstruct": { 9 | "entrypoints": [ 10 | "index.ts" 11 | ] 12 | }, 13 | "files": [ 14 | "/dist" 15 | ], 16 | "repository": { 17 | "type": "git", 18 | "url": "https://github.com/vanilla-extract-css/vanilla-extract.git", 19 | "directory": "packages/babel-plugin-debug-ids" 20 | }, 21 | "author": "SEEK", 22 | "license": "MIT", 23 | "dependencies": { 24 | "@babel/core": "^7.23.9" 25 | }, 26 | "devDependencies": { 27 | "@types/babel__core": "^7.20.5" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/compiler/README.md: -------------------------------------------------------------------------------- 1 | # @vanilla-extract/compiler 2 | 3 | This package is not intended for public consumption. 4 | -------------------------------------------------------------------------------- /packages/compiler/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@vanilla-extract/compiler", 3 | "version": "0.2.0", 4 | "description": "Zero-runtime Stylesheets-in-TypeScript", 5 | "main": "dist/vanilla-extract-compiler.cjs.js", 6 | "module": "dist/vanilla-extract-compiler.esm.js", 7 | "types": "dist/vanilla-extract-compiler.cjs.d.ts", 8 | "files": [ 9 | "/dist" 10 | ], 11 | "repository": { 12 | "type": "git", 13 | "url": "https://github.com/vanilla-extract-css/vanilla-extract.git", 14 | "directory": "packages/compiler" 15 | }, 16 | "author": "SEEK", 17 | "license": "MIT", 18 | "dependencies": { 19 | "@vanilla-extract/css": "workspace:^", 20 | "@vanilla-extract/integration": "workspace:^", 21 | "vite": "^5.0.0 || ^6.0.0", 22 | "vite-node": "^3.0.4" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/compiler/src/index.ts: -------------------------------------------------------------------------------- 1 | export { 2 | createCompiler, 3 | type Compiler, 4 | type CreateCompilerOptions, 5 | } from './compiler'; 6 | -------------------------------------------------------------------------------- /packages/compiler/src/lock.ts: -------------------------------------------------------------------------------- 1 | type AsyncFunction = () => Promise; 2 | 3 | const queue: Array<() => void> = []; 4 | let isProcessingQueue = false; 5 | 6 | export async function lock(fn: AsyncFunction): Promise { 7 | return new Promise((resolve, reject) => { 8 | const queueFn = async () => { 9 | try { 10 | const result = await fn(); 11 | resolve(result); 12 | } catch (error) { 13 | reject(error); 14 | } finally { 15 | isProcessingQueue = false; 16 | processQueue(); 17 | } 18 | }; 19 | 20 | queue.push(queueFn); 21 | 22 | if (!isProcessingQueue) { 23 | processQueue(); 24 | } 25 | }); 26 | } 27 | 28 | async function processQueue() { 29 | if (isProcessingQueue || queue.length === 0) { 30 | return; 31 | } 32 | 33 | isProcessingQueue = true; 34 | const fn = queue.shift()!; 35 | 36 | await fn(); 37 | } 38 | -------------------------------------------------------------------------------- /packages/css/adapter/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "dist/vanilla-extract-css-adapter.cjs.js", 3 | "module": "dist/vanilla-extract-css-adapter.esm.js", 4 | "browser": { 5 | "./dist/vanilla-extract-css-adapter.cjs.js": "./dist/vanilla-extract-css-adapter.browser.cjs.js", 6 | "./dist/vanilla-extract-css-adapter.esm.js": "./dist/vanilla-extract-css-adapter.browser.esm.js" 7 | }, 8 | "sideEffects": false, 9 | "exports": { 10 | "./package.json": "./package.json", 11 | ".": { 12 | "browser": { 13 | "module": "./dist/vanilla-extract-css-adapter.browser.esm.js", 14 | "default": "./dist/vanilla-extract-css-adapter.browser.cjs.js" 15 | }, 16 | "module": "./dist/vanilla-extract-css-adapter.esm.js", 17 | "default": "./dist/vanilla-extract-css-adapter.cjs.js" 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/css/disableRuntimeStyles/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "dist/vanilla-extract-css-disableRuntimeStyles.cjs.js", 3 | "module": "dist/vanilla-extract-css-disableRuntimeStyles.esm.js", 4 | "browser": { 5 | "./dist/vanilla-extract-css-disableRuntimeStyles.cjs.js": "./dist/vanilla-extract-css-disableRuntimeStyles.browser.cjs.js", 6 | "./dist/vanilla-extract-css-disableRuntimeStyles.esm.js": "./dist/vanilla-extract-css-disableRuntimeStyles.browser.esm.js" 7 | }, 8 | "exports": { 9 | "./package.json": "./package.json", 10 | ".": { 11 | "browser": { 12 | "module": "./dist/vanilla-extract-css-disableRuntimeStyles.browser.esm.js", 13 | "default": "./dist/vanilla-extract-css-disableRuntimeStyles.browser.cjs.js" 14 | }, 15 | "module": "./dist/vanilla-extract-css-disableRuntimeStyles.esm.js", 16 | "default": "./dist/vanilla-extract-css-disableRuntimeStyles.cjs.js" 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/css/fileScope/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "dist/vanilla-extract-css-fileScope.cjs.js", 3 | "module": "dist/vanilla-extract-css-fileScope.esm.js", 4 | "browser": { 5 | "./dist/vanilla-extract-css-fileScope.cjs.js": "./dist/vanilla-extract-css-fileScope.browser.cjs.js", 6 | "./dist/vanilla-extract-css-fileScope.esm.js": "./dist/vanilla-extract-css-fileScope.browser.esm.js" 7 | }, 8 | "sideEffects": false, 9 | "exports": { 10 | "./package.json": "./package.json", 11 | ".": { 12 | "browser": { 13 | "module": "./dist/vanilla-extract-css-fileScope.browser.esm.js", 14 | "default": "./dist/vanilla-extract-css-fileScope.browser.cjs.js" 15 | }, 16 | "module": "./dist/vanilla-extract-css-fileScope.esm.js", 17 | "default": "./dist/vanilla-extract-css-fileScope.cjs.js" 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/css/functionSerializer/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "dist/vanilla-extract-css-functionSerializer.cjs.js", 3 | "module": "dist/vanilla-extract-css-functionSerializer.esm.js", 4 | "browser": { 5 | "./dist/vanilla-extract-css-functionSerializer.cjs.js": "./dist/vanilla-extract-css-functionSerializer.browser.cjs.js", 6 | "./dist/vanilla-extract-css-functionSerializer.esm.js": "./dist/vanilla-extract-css-functionSerializer.browser.esm.js" 7 | }, 8 | "exports": { 9 | "./package.json": "./package.json", 10 | ".": { 11 | "browser": { 12 | "module": "./dist/vanilla-extract-css-functionSerializer.browser.esm.js", 13 | "default": "./dist/vanilla-extract-css-functionSerializer.browser.cjs.js" 14 | }, 15 | "module": "./dist/vanilla-extract-css-functionSerializer.esm.js", 16 | "default": "./dist/vanilla-extract-css-functionSerializer.cjs.js" 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/css/injectStyles/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "dist/vanilla-extract-css-injectStyles.cjs.js", 3 | "module": "dist/vanilla-extract-css-injectStyles.esm.js", 4 | "browser": { 5 | "./dist/vanilla-extract-css-injectStyles.cjs.js": "./dist/vanilla-extract-css-injectStyles.browser.cjs.js", 6 | "./dist/vanilla-extract-css-injectStyles.esm.js": "./dist/vanilla-extract-css-injectStyles.browser.esm.js" 7 | }, 8 | "exports": { 9 | "./package.json": "./package.json", 10 | ".": { 11 | "browser": { 12 | "module": "./dist/vanilla-extract-css-injectStyles.browser.esm.js", 13 | "default": "./dist/vanilla-extract-css-injectStyles.browser.cjs.js" 14 | }, 15 | "module": "./dist/vanilla-extract-css-injectStyles.esm.js", 16 | "default": "./dist/vanilla-extract-css-injectStyles.cjs.js" 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/css/recipe/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "dist/vanilla-extract-css-recipe.cjs.js", 3 | "module": "dist/vanilla-extract-css-recipe.esm.js", 4 | "browser": { 5 | "./dist/vanilla-extract-css-recipe.cjs.js": "./dist/vanilla-extract-css-recipe.browser.cjs.js", 6 | "./dist/vanilla-extract-css-recipe.esm.js": "./dist/vanilla-extract-css-recipe.browser.esm.js" 7 | }, 8 | "exports": { 9 | "./package.json": "./package.json", 10 | ".": { 11 | "browser": { 12 | "module": "./dist/vanilla-extract-css-recipe.browser.esm.js", 13 | "default": "./dist/vanilla-extract-css-recipe.browser.cjs.js" 14 | }, 15 | "module": "./dist/vanilla-extract-css-recipe.esm.js", 16 | "default": "./dist/vanilla-extract-css-recipe.cjs.js" 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/css/src/container.ts: -------------------------------------------------------------------------------- 1 | import { generateIdentifier } from './identifier'; 2 | 3 | // createContainer is used for local scoping of CSS containers 4 | // For now it is mostly just an alias of generateIdentifier 5 | export const createContainer = (debugId?: string) => 6 | generateIdentifier(debugId); 7 | -------------------------------------------------------------------------------- /packages/css/src/disableRuntimeStyles.ts: -------------------------------------------------------------------------------- 1 | import { setAdapter, mockAdapter } from './adapter'; 2 | 3 | setAdapter(mockAdapter); 4 | -------------------------------------------------------------------------------- /packages/css/src/fileScope.ts: -------------------------------------------------------------------------------- 1 | import dedent from 'dedent'; 2 | import { onBeginFileScope, onEndFileScope } from './adapter'; 3 | import type { FileScope } from './types'; 4 | 5 | let refCounter = 0; 6 | 7 | const fileScopes: Array = []; 8 | 9 | export function setFileScope(filePath: string, packageName?: string) { 10 | refCounter = 0; 11 | const fileScope = { 12 | filePath, 13 | packageName, 14 | }; 15 | fileScopes.unshift(fileScope); 16 | onBeginFileScope(fileScope); 17 | } 18 | 19 | export function endFileScope() { 20 | onEndFileScope(getFileScope()); 21 | refCounter = 0; 22 | fileScopes.splice(0, 1); 23 | } 24 | 25 | export function hasFileScope() { 26 | return fileScopes.length > 0; 27 | } 28 | 29 | export function getFileScope(): FileScope { 30 | if (fileScopes.length === 0) { 31 | throw new Error( 32 | dedent` 33 | Styles were unable to be assigned to a file. This is generally caused by one of the following: 34 | 35 | - You may have created styles outside of a '.css.ts' context 36 | - You may have incorrect configuration. See https://vanilla-extract.style/documentation/getting-started 37 | `, 38 | ); 39 | } 40 | 41 | return fileScopes[0]; 42 | } 43 | 44 | export function getAndIncrementRefCounter() { 45 | return refCounter++; 46 | } 47 | -------------------------------------------------------------------------------- /packages/css/src/functionSerializer.ts: -------------------------------------------------------------------------------- 1 | type Primitive = string | number | boolean | null | undefined; 2 | 3 | type Serializable = 4 | | { 5 | [Key in string | number]: Primitive | Serializable; 6 | } 7 | | ReadonlyArray; 8 | 9 | interface SerializerConfig { 10 | importPath: string; 11 | importName: string; 12 | args: ReadonlyArray; 13 | } 14 | 15 | export function addFunctionSerializer( 16 | target: Target, 17 | recipe: SerializerConfig, 18 | ) { 19 | // TODO: Update to "__function_serializer__" in future. 20 | // __recipe__ is the backwards compatible name 21 | Object.defineProperty(target, '__recipe__', { 22 | value: recipe, 23 | writable: false, 24 | }); 25 | 26 | return target; 27 | } 28 | -------------------------------------------------------------------------------- /packages/css/src/index.ts: -------------------------------------------------------------------------------- 1 | import './runtimeAdapter'; 2 | 3 | export type { 4 | StyleRule, 5 | ComplexStyleRule, 6 | GlobalStyleRule, 7 | Adapter, 8 | FileScope, 9 | CSSProperties, 10 | } from './types'; 11 | export * from './identifier'; 12 | export * from './theme'; 13 | export * from './style'; 14 | export * from './vars'; 15 | export { createContainer } from './container'; 16 | export { createViewTransition } from './viewTransition'; 17 | export * from './layer'; 18 | -------------------------------------------------------------------------------- /packages/css/src/injectStyles.ts: -------------------------------------------------------------------------------- 1 | import type { FileScope } from './types'; 2 | 3 | const stylesheets: Record = {}; 4 | 5 | interface InjectStylesOptions { 6 | fileScope: FileScope; 7 | css: string; 8 | } 9 | export const injectStyles = ({ fileScope, css }: InjectStylesOptions) => { 10 | const fileScopeId = fileScope.packageName 11 | ? [fileScope.packageName, fileScope.filePath].join('/') 12 | : fileScope.filePath; 13 | 14 | let stylesheet = stylesheets[fileScopeId]; 15 | 16 | if (!stylesheet) { 17 | const styleEl = document.createElement('style'); 18 | 19 | if (fileScope.packageName) { 20 | styleEl.setAttribute('data-package', fileScope.packageName); 21 | } 22 | 23 | styleEl.setAttribute('data-file', fileScope.filePath); 24 | styleEl.setAttribute('type', 'text/css'); 25 | stylesheet = stylesheets[fileScopeId] = styleEl; 26 | document.head.appendChild(styleEl); 27 | } 28 | 29 | stylesheet.innerHTML = css; 30 | }; 31 | -------------------------------------------------------------------------------- /packages/css/src/recipe.ts: -------------------------------------------------------------------------------- 1 | import { addFunctionSerializer } from './functionSerializer'; 2 | 3 | /** 4 | * @deprecated Use 'addFunctionSerializer' from '@vanilla-extract/css/functionSerializer' 5 | */ 6 | export const addRecipe = addFunctionSerializer; 7 | -------------------------------------------------------------------------------- /packages/css/src/runtimeAdapter.ts: -------------------------------------------------------------------------------- 1 | import type { Adapter, Composition, CSS } from './types'; 2 | import { injectStyles } from './injectStyles'; 3 | import { transformCss } from './transformCss'; 4 | import { setAdapterIfNotSet } from './adapter'; 5 | 6 | const localClassNames = new Set(); 7 | const composedClassLists: Array = []; 8 | let bufferedCSSObjs: Array = []; 9 | 10 | const browserRuntimeAdapter: Adapter = { 11 | appendCss: (cssObj: CSS) => { 12 | bufferedCSSObjs.push(cssObj); 13 | }, 14 | registerClassName: (className) => { 15 | localClassNames.add(className); 16 | }, 17 | registerComposition: (composition) => { 18 | composedClassLists.push(composition); 19 | }, 20 | markCompositionUsed: () => {}, 21 | onEndFileScope: (fileScope) => { 22 | const css = transformCss({ 23 | localClassNames: Array.from(localClassNames), 24 | composedClassLists, 25 | cssObjs: bufferedCSSObjs, 26 | }).join('\n'); 27 | 28 | injectStyles({ fileScope, css }); 29 | 30 | bufferedCSSObjs = []; 31 | }, 32 | getIdentOption: () => 33 | process.env.NODE_ENV === 'production' ? 'short' : 'debug', 34 | }; 35 | 36 | if (typeof window !== 'undefined') { 37 | setAdapterIfNotSet(browserRuntimeAdapter); 38 | } 39 | -------------------------------------------------------------------------------- /packages/css/src/validateMediaQuery.ts: -------------------------------------------------------------------------------- 1 | import dedent from 'dedent'; 2 | import { toAST } from 'media-query-parser'; 3 | 4 | const createMediaQueryError = (mediaQuery: string, msg: string) => 5 | new Error( 6 | dedent` 7 | Invalid media query: "${mediaQuery}" 8 | 9 | ${msg} 10 | 11 | Read more on MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries 12 | `, 13 | ); 14 | 15 | export const validateMediaQuery = (mediaQuery: string) => { 16 | // Empty queries will start with '@media ' 17 | if (mediaQuery === '@media ') { 18 | throw createMediaQueryError(mediaQuery, 'Query is empty'); 19 | } 20 | 21 | try { 22 | toAST(mediaQuery); 23 | } catch (e: any) { 24 | throw createMediaQueryError(mediaQuery, e.message); 25 | } 26 | }; 27 | -------------------------------------------------------------------------------- /packages/css/src/viewTransition.ts: -------------------------------------------------------------------------------- 1 | import { generateIdentifier } from './identifier'; 2 | 3 | // createViewTransition is used for locally scoping CSS view transitions 4 | // For now it is mostly just an alias of generateIdentifier 5 | export const createViewTransition = (debugId?: string) => 6 | generateIdentifier(debugId); 7 | -------------------------------------------------------------------------------- /packages/css/transformCss/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "dist/vanilla-extract-css-transformCss.cjs.js", 3 | "module": "dist/vanilla-extract-css-transformCss.esm.js", 4 | "browser": { 5 | "./dist/vanilla-extract-css-transformCss.cjs.js": "./dist/vanilla-extract-css-transformCss.browser.cjs.js", 6 | "./dist/vanilla-extract-css-transformCss.esm.js": "./dist/vanilla-extract-css-transformCss.browser.esm.js" 7 | }, 8 | "sideEffects": false, 9 | "exports": { 10 | "./package.json": "./package.json", 11 | ".": { 12 | "browser": { 13 | "module": "./dist/vanilla-extract-css-transformCss.browser.esm.js", 14 | "default": "./dist/vanilla-extract-css-transformCss.browser.cjs.js" 15 | }, 16 | "module": "./dist/vanilla-extract-css-transformCss.esm.js", 17 | "default": "./dist/vanilla-extract-css-transformCss.cjs.js" 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/dynamic/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@vanilla-extract/dynamic", 3 | "version": "2.1.3", 4 | "description": "Zero-runtime Stylesheets-in-TypeScript", 5 | "sideEffects": false, 6 | "main": "dist/vanilla-extract-dynamic.cjs.js", 7 | "module": "dist/vanilla-extract-dynamic.esm.js", 8 | "types": "dist/vanilla-extract-dynamic.cjs.d.ts", 9 | "exports": { 10 | "./package.json": "./package.json", 11 | ".": { 12 | "types": "./dist/vanilla-extract-dynamic.cjs.d.ts", 13 | "module": "./dist/vanilla-extract-dynamic.esm.js", 14 | "default": "./dist/vanilla-extract-dynamic.cjs.js" 15 | } 16 | }, 17 | "files": [ 18 | "/dist" 19 | ], 20 | "repository": { 21 | "type": "git", 22 | "url": "https://github.com/vanilla-extract-css/vanilla-extract.git", 23 | "directory": "packages/dynamic" 24 | }, 25 | "author": "SEEK", 26 | "license": "MIT", 27 | "dependencies": { 28 | "@vanilla-extract/private": "workspace:^" 29 | }, 30 | "devDependencies": { 31 | "@vanilla-extract/css": "workspace:^" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /packages/dynamic/src/assignInlineVars.test.css.ts: -------------------------------------------------------------------------------- 1 | import { createThemeContract } from '@vanilla-extract/css'; 2 | 3 | export const vars = createThemeContract({ 4 | foo: { bar: null }, 5 | baz: { qux: null }, 6 | }); 7 | -------------------------------------------------------------------------------- /packages/dynamic/src/index.ts: -------------------------------------------------------------------------------- 1 | export { assignInlineVars } from './assignInlineVars'; 2 | export { setElementVars } from './setElementVars'; 3 | -------------------------------------------------------------------------------- /packages/dynamic/src/setElementVars.test.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @jest-environment jsdom 3 | */ 4 | import { setElementVars } from './'; 5 | import { vars } from './assignInlineVars.test.css'; 6 | 7 | describe('setElementVars', () => { 8 | it('assigns vars', () => { 9 | const el = document.body.appendChild(document.createElement('div')); 10 | 11 | setElementVars(el, { 12 | [vars.foo.bar]: '1', 13 | [vars.baz.qux]: '2', 14 | '--global-var-1': '3', 15 | '--global-var-2': '4', 16 | '--global-var-3': undefined, 17 | '--global-var-4': null, 18 | }); 19 | 20 | // Can't query CSS vars directly as jsdom doesn't support it 21 | expect(el.getAttribute('style')).toMatchInlineSnapshot( 22 | `"--foo-bar__1byvgzh0: 1; --baz-qux__1byvgzh1: 2; --global-var-1: 3; --global-var-2: 4;"`, 23 | ); 24 | }); 25 | 26 | it('assigns contract vars', () => { 27 | const el = document.body.appendChild(document.createElement('div')); 28 | 29 | setElementVars(el, vars, { 30 | foo: { bar: '1' }, 31 | baz: { qux: '2' }, 32 | }); 33 | 34 | // Can't query CSS vars directly as jsdom doesn't support it 35 | expect(el.getAttribute('style')).toMatchInlineSnapshot( 36 | `"--foo-bar__1byvgzh0: 1; --baz-qux__1byvgzh1: 2;"`, 37 | ); 38 | }); 39 | }); 40 | -------------------------------------------------------------------------------- /packages/dynamic/src/setElementVarts.test.css.ts: -------------------------------------------------------------------------------- 1 | import { createThemeContract } from '@vanilla-extract/css'; 2 | 3 | export const vars = createThemeContract({ 4 | foo: { bar: null }, 5 | baz: { qux: null }, 6 | }); 7 | -------------------------------------------------------------------------------- /packages/esbuild-plugin-next/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "@vanilla-extract/esbuild-plugin-next", 4 | "version": "0.0.10", 5 | "description": "Zero-runtime Stylesheets-in-TypeScript", 6 | "main": "dist/vanilla-extract-esbuild-plugin-next.cjs.js", 7 | "module": "dist/vanilla-extract-esbuild-plugin-next.esm.js", 8 | "types": "dist/vanilla-extract-esbuild-plugin-next.cjs.d.ts", 9 | "files": [ 10 | "/dist" 11 | ], 12 | "repository": { 13 | "type": "git", 14 | "url": "https://github.com/vanilla-extract-css/vanilla-extract.git", 15 | "directory": "packages/esbuild-plugin-next" 16 | }, 17 | "author": "SEEK", 18 | "license": "MIT", 19 | "dependencies": { 20 | "@vanilla-extract/compiler": "workspace:^", 21 | "@vanilla-extract/integration": "workspace:^" 22 | }, 23 | "peerDependencies": { 24 | "esbuild": ">=0.17.6" 25 | }, 26 | "peerDependenciesMeta": { 27 | "esbuild": { 28 | "optional": true 29 | } 30 | }, 31 | "devDependencies": { 32 | "esbuild": "~0.25.0" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/esbuild-plugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@vanilla-extract/esbuild-plugin", 3 | "version": "2.3.16", 4 | "description": "Zero-runtime Stylesheets-in-TypeScript", 5 | "main": "dist/vanilla-extract-esbuild-plugin.cjs.js", 6 | "module": "dist/vanilla-extract-esbuild-plugin.esm.js", 7 | "types": "dist/vanilla-extract-esbuild-plugin.cjs.d.ts", 8 | "files": [ 9 | "/dist" 10 | ], 11 | "repository": { 12 | "type": "git", 13 | "url": "https://github.com/vanilla-extract-css/vanilla-extract.git", 14 | "directory": "packages/esbuild-plugin" 15 | }, 16 | "author": "SEEK", 17 | "license": "MIT", 18 | "dependencies": { 19 | "@vanilla-extract/integration": "workspace:^" 20 | }, 21 | "peerDependencies": { 22 | "esbuild": ">=0.17.6" 23 | }, 24 | "peerDependenciesMeta": { 25 | "esbuild": { 26 | "optional": true 27 | } 28 | }, 29 | "devDependencies": { 30 | "esbuild": "~0.25.0" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /packages/integration/README.md: -------------------------------------------------------------------------------- 1 | # @vanilla-extract/integration 2 | 3 | This package is not intended for public consumption. -------------------------------------------------------------------------------- /packages/integration/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@vanilla-extract/integration", 3 | "version": "8.0.2", 4 | "description": "Zero-runtime Stylesheets-in-TypeScript", 5 | "main": "dist/vanilla-extract-integration.cjs.js", 6 | "types": "dist/vanilla-extract-integration.cjs.d.ts", 7 | "files": [ 8 | "/dist" 9 | ], 10 | "repository": { 11 | "type": "git", 12 | "url": "https://github.com/vanilla-extract-css/vanilla-extract.git", 13 | "directory": "packages/integration" 14 | }, 15 | "author": "SEEK", 16 | "license": "MIT", 17 | "dependencies": { 18 | "@babel/core": "^7.23.9", 19 | "@babel/plugin-syntax-typescript": "^7.23.3", 20 | "@vanilla-extract/babel-plugin-debug-ids": "workspace:^", 21 | "@vanilla-extract/css": "workspace:^", 22 | "dedent": "^1.5.3", 23 | "esbuild": "npm:esbuild@>=0.17.6 <0.26.0", 24 | "eval": "0.1.8", 25 | "find-up": "^5.0.0", 26 | "javascript-stringify": "^2.0.1", 27 | "mlly": "^1.4.2" 28 | }, 29 | "devDependencies": { 30 | "@types/babel__core": "^7.20.5" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /packages/integration/src/filters.ts: -------------------------------------------------------------------------------- 1 | // Vite adds a "?used" to CSS files it detects, this isn't relevant for 2 | // .css.ts files but it's added anyway so we need to allow for it in the file match 3 | export const cssFileFilter = /\.css\.(js|cjs|mjs|jsx|ts|tsx)(\?used)?$/; 4 | export const virtualCssFileFilter = /\.vanilla\.css\?source=.*$/; 5 | -------------------------------------------------------------------------------- /packages/integration/src/hash.ts: -------------------------------------------------------------------------------- 1 | import crypto from 'crypto'; 2 | 3 | export const hash = (value: string) => 4 | crypto.createHash('md5').update(value).digest('hex'); 5 | -------------------------------------------------------------------------------- /packages/integration/src/index.ts: -------------------------------------------------------------------------------- 1 | export { 2 | processVanillaFile, 3 | parseFileScope, 4 | stringifyFileScope, 5 | serializeVanillaModule, 6 | } from './processVanillaFile'; 7 | export { getSourceFromVirtualCssFile } from './virtualFile'; 8 | export { getPackageInfo, type PackageInfo } from './packageInfo'; 9 | export { 10 | compile, 11 | vanillaExtractTransformPlugin, 12 | type CompileOptions, 13 | } from './compile'; 14 | export { hash } from './hash'; 15 | export { addFileScope, normalizePath } from './addFileScope'; 16 | export { serializeCss, deserializeCss } from './serialize'; 17 | export { transformSync, transform } from './transform'; 18 | export { cssFileFilter, virtualCssFileFilter } from './filters'; 19 | export type { IdentifierOption } from './types'; 20 | -------------------------------------------------------------------------------- /packages/integration/src/serialize.ts: -------------------------------------------------------------------------------- 1 | import { gzip, gunzip } from 'zlib'; 2 | import { promisify } from 'util'; 3 | 4 | const zip = promisify(gzip); 5 | const unzip = promisify(gunzip); 6 | 7 | // The byte threshold for applying compression, below which compressing would out-weigh its value. 8 | const compressionThreshold = 1000; 9 | const compressionFlag = '#'; 10 | 11 | export async function serializeCss(source: string) { 12 | if (source.length > compressionThreshold) { 13 | const compressedSource = await zip(source); 14 | 15 | return compressionFlag + compressedSource.toString('base64'); 16 | } 17 | 18 | return Buffer.from(source, 'utf-8').toString('base64'); 19 | } 20 | 21 | export async function deserializeCss(source: string) { 22 | if (source.indexOf(compressionFlag) > -1) { 23 | const decompressedSource = await unzip( 24 | Buffer.from(source.replace(compressionFlag, ''), 'base64'), 25 | ); 26 | 27 | return decompressedSource.toString('utf-8'); 28 | } 29 | 30 | return Buffer.from(source, 'base64').toString('utf-8'); 31 | } 32 | -------------------------------------------------------------------------------- /packages/integration/src/types.ts: -------------------------------------------------------------------------------- 1 | import type { Adapter } from '@vanilla-extract/css'; 2 | 3 | export type IdentifierOption = ReturnType; 4 | -------------------------------------------------------------------------------- /packages/integration/src/virtualFile.ts: -------------------------------------------------------------------------------- 1 | import { deserializeCss } from './serialize'; 2 | 3 | export async function getSourceFromVirtualCssFile(id: string) { 4 | const match = id.match(/^(?.*)\?source=(?.*)$/); 5 | 6 | if (!match || !match.groups) { 7 | throw new Error('No source in vanilla CSS file'); 8 | } 9 | 10 | const source = await deserializeCss(match.groups.source); 11 | 12 | return { 13 | fileName: match.groups.fileName, 14 | source, 15 | }; 16 | } 17 | -------------------------------------------------------------------------------- /packages/jest-transform/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@vanilla-extract/jest-transform", 3 | "version": "1.1.15", 4 | "description": "Jest transformer for vanilla-extract", 5 | "main": "dist/vanilla-extract-jest-transform.cjs.js", 6 | "module": "dist/vanilla-extract-jest-transform.esm.js", 7 | "types": "dist/vanilla-extract-jest-transform.cjs.d.ts", 8 | "preconstruct": { 9 | "entrypoints": [ 10 | "index.ts" 11 | ] 12 | }, 13 | "files": [ 14 | "/dist" 15 | ], 16 | "repository": { 17 | "type": "git", 18 | "url": "https://github.com/vanilla-extract-css/vanilla-extract.git", 19 | "directory": "packages/jest-transform" 20 | }, 21 | "author": "SEEK", 22 | "license": "MIT", 23 | "dependencies": { 24 | "@vanilla-extract/integration": "workspace:^", 25 | "esbuild": "npm:esbuild@>=0.17.6 <0.26.0" 26 | }, 27 | "devDependencies": { 28 | "@jest/transform": "^29.0.3" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /packages/jest-transform/src/index.ts: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | import type { Transformer } from '@jest/transform'; 3 | import { 4 | transformSync, 5 | getPackageInfo, 6 | cssFileFilter, 7 | } from '@vanilla-extract/integration'; 8 | import * as esbuild from 'esbuild'; 9 | 10 | const vanillaTransformer: Transformer = { 11 | canInstrument: false, 12 | process(source, filePath, options) { 13 | if (!cssFileFilter.test(filePath)) { 14 | // If the file that passes through to the transformer is not a VE file, 15 | // then it's likely a vanilla .css file (because Jest can't differentiate 16 | // between them) 17 | return { 18 | code: `module.exports = ${JSON.stringify(path.basename(filePath))};`, 19 | }; 20 | } 21 | 22 | const { name: packageName } = getPackageInfo(options.config.rootDir); 23 | 24 | const code = transformSync({ 25 | source, 26 | filePath, 27 | rootPath: options.config.rootDir, 28 | packageName: packageName, 29 | identOption: 'debug', 30 | }); 31 | 32 | const result = esbuild.transformSync(code, { 33 | format: options.supportsStaticESM ? 'esm' : 'cjs', 34 | target: 'es2018', 35 | loader: 'ts', 36 | }); 37 | 38 | return result; 39 | }, 40 | }; 41 | 42 | export default vanillaTransformer; 43 | -------------------------------------------------------------------------------- /packages/next-plugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@vanilla-extract/next-plugin", 3 | "version": "2.4.11", 4 | "description": "Zero-runtime Stylesheets-in-TypeScript", 5 | "main": "dist/vanilla-extract-next-plugin.cjs.js", 6 | "module": "dist/vanilla-extract-next-plugin.esm.js", 7 | "types": "dist/vanilla-extract-next-plugin.cjs.d.ts", 8 | "preconstruct": { 9 | "entrypoints": [ 10 | "index.ts" 11 | ] 12 | }, 13 | "files": [ 14 | "/dist" 15 | ], 16 | "repository": { 17 | "type": "git", 18 | "url": "https://github.com/vanilla-extract-css/vanilla-extract.git", 19 | "directory": "packages/next-plugin" 20 | }, 21 | "author": "SEEK", 22 | "license": "MIT", 23 | "dependencies": { 24 | "@vanilla-extract/webpack-plugin": "workspace:^" 25 | }, 26 | "peerDependencies": { 27 | "next": ">=12.1.7" 28 | }, 29 | "devDependencies": { 30 | "next": "12.3.4", 31 | "webpack": "^5.90.0" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /packages/parcel-transformer/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@vanilla-extract/parcel-transformer", 3 | "version": "1.0.15", 4 | "description": "Zero-runtime Stylesheets-in-TypeScript", 5 | "main": "dist/vanilla-extract-parcel-transformer.cjs.js", 6 | "module": "dist/vanilla-extract-parcel-transformer.esm.js", 7 | "types": "dist/vanilla-extract-parcel-transformer.cjs.d.ts", 8 | "files": [ 9 | "/dist" 10 | ], 11 | "engines": { 12 | "parcel": "2.x" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "https://github.com/vanilla-extract-css/vanilla-extract.git", 17 | "directory": "packages/parcel-transformer" 18 | }, 19 | "author": "mattcompiles", 20 | "license": "MIT", 21 | "dependencies": { 22 | "@parcel/plugin": "^2.7.0", 23 | "@vanilla-extract/integration": "workspace:^" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/private/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@vanilla-extract/private", 3 | "version": "1.0.7", 4 | "description": "Zero-runtime Stylesheets-in-TypeScript", 5 | "sideEffects": false, 6 | "main": "dist/vanilla-extract-private.cjs.js", 7 | "module": "dist/vanilla-extract-private.esm.js", 8 | "types": "dist/vanilla-extract-private.cjs.d.ts", 9 | "preconstruct": { 10 | "entrypoints": [ 11 | "index.ts" 12 | ] 13 | }, 14 | "files": [ 15 | "/dist" 16 | ], 17 | "repository": { 18 | "type": "git", 19 | "url": "https://github.com/vanilla-extract-css/vanilla-extract.git", 20 | "directory": "packages/private" 21 | }, 22 | "author": "SEEK", 23 | "license": "MIT" 24 | } 25 | -------------------------------------------------------------------------------- /packages/private/src/get.ts: -------------------------------------------------------------------------------- 1 | export function get(obj: any, path: Array) { 2 | let result = obj; 3 | 4 | for (const key of path) { 5 | if (!(key in result)) { 6 | throw new Error(`Path ${path.join(' -> ')} does not exist in object`); 7 | } 8 | result = result[key]; 9 | } 10 | 11 | return result; 12 | } 13 | -------------------------------------------------------------------------------- /packages/private/src/getVarName.ts: -------------------------------------------------------------------------------- 1 | export function getVarName(variable: string) { 2 | const matches = variable.match(/^var\((.*)\)$/); 3 | 4 | if (matches) { 5 | return matches[1]; 6 | } 7 | 8 | return variable; 9 | } 10 | -------------------------------------------------------------------------------- /packages/private/src/index.ts: -------------------------------------------------------------------------------- 1 | export type { Contract, MapLeafNodes, CSSVarFunction } from './types'; 2 | export { getVarName } from './getVarName'; 3 | export { get } from './get'; 4 | export { walkObject } from './walkObject'; 5 | -------------------------------------------------------------------------------- /packages/private/src/types.ts: -------------------------------------------------------------------------------- 1 | export type CSSVarFunction = `var(--${string})` | `var(--${string}, ${string})`; 2 | 3 | export type Contract = { 4 | [key: string]: CSSVarFunction | null | Contract; 5 | }; 6 | 7 | type Primitive = string | boolean | number | null | undefined; 8 | 9 | export type MapLeafNodes = { 10 | [Prop in keyof Obj]: Obj[Prop] extends Primitive 11 | ? LeafType 12 | : Obj[Prop] extends Record 13 | ? MapLeafNodes 14 | : never; 15 | }; 16 | -------------------------------------------------------------------------------- /packages/private/src/walkObject.ts: -------------------------------------------------------------------------------- 1 | import type { MapLeafNodes } from './types'; 2 | 3 | type Primitive = string | number | null | undefined; 4 | 5 | type Walkable = { 6 | [Key in string | number]: Primitive | Walkable; 7 | }; 8 | 9 | export function walkObject( 10 | obj: T, 11 | fn: (value: Primitive, path: Array) => MapTo, 12 | path: Array = [], 13 | ): MapLeafNodes { 14 | const clone = {} as any; 15 | 16 | for (let key in obj) { 17 | const value = obj[key]; 18 | const currentPath = [...path, key]; 19 | 20 | if ( 21 | typeof value === 'string' || 22 | typeof value === 'number' || 23 | value == null 24 | ) { 25 | clone[key] = fn(value as Primitive, currentPath); 26 | } else if (typeof value === 'object' && !Array.isArray(value)) { 27 | clone[key] = walkObject(value as Walkable, fn, currentPath); 28 | } else { 29 | console.warn( 30 | `Skipping invalid key "${currentPath.join( 31 | '.', 32 | )}". Should be a string, number, null or object. Received: "${ 33 | Array.isArray(value) ? 'Array' : typeof value 34 | }"`, 35 | ); 36 | } 37 | } 38 | 39 | return clone; 40 | } 41 | -------------------------------------------------------------------------------- /packages/recipes/createRuntimeFn/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "dist/vanilla-extract-recipes-createRuntimeFn.cjs.js", 3 | "module": "dist/vanilla-extract-recipes-createRuntimeFn.esm.js" 4 | } 5 | -------------------------------------------------------------------------------- /packages/recipes/src/utils.ts: -------------------------------------------------------------------------------- 1 | export function mapValues, OutputValue>( 2 | input: Input, 3 | fn: (value: Input[keyof Input], key: keyof Input) => OutputValue, 4 | ): Record { 5 | const result: any = {}; 6 | 7 | for (const key in input) { 8 | result[key] = fn(input[key], key); 9 | } 10 | 11 | return result; 12 | } 13 | -------------------------------------------------------------------------------- /packages/rollup-plugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@vanilla-extract/rollup-plugin", 3 | "version": "1.3.15", 4 | "description": "Zero-runtime Stylesheets-in-TypeScript", 5 | "main": "dist/vanilla-extract-rollup-plugin.cjs.js", 6 | "module": "dist/vanilla-extract-rollup-plugin.esm.js", 7 | "types": "dist/vanilla-extract-rollup-plugin.cjs.d.ts", 8 | "files": [ 9 | "/dist" 10 | ], 11 | "repository": { 12 | "type": "git", 13 | "url": "https://github.com/vanilla-extract-css/vanilla-extract.git", 14 | "directory": "packages/rollup-plugin" 15 | }, 16 | "author": "SEEK", 17 | "license": "MIT", 18 | "dependencies": { 19 | "@vanilla-extract/integration": "workspace:^" 20 | }, 21 | "devDependencies": { 22 | "@fixtures/themed": "workspace:*", 23 | "@rollup/plugin-json": "^6.1.0", 24 | "@vanilla-extract/css": "workspace:^", 25 | "esbuild": "~0.25.0", 26 | "rollup": "^4.20.0", 27 | "rollup-plugin-esbuild": "^6.1.1" 28 | }, 29 | "peerDependencies": { 30 | "rollup": "^2.0.0 || ^3.0.0 || ^4.0.0" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /packages/sprinkles/createRuntimeSprinkles/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "dist/vanilla-extract-sprinkles-createRuntimeSprinkles.cjs.js", 3 | "module": "dist/vanilla-extract-sprinkles-createRuntimeSprinkles.esm.js" 4 | } 5 | -------------------------------------------------------------------------------- /packages/sprinkles/createUtils/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "dist/vanilla-extract-sprinkles-createUtils.cjs.js", 3 | "module": "dist/vanilla-extract-sprinkles-createUtils.esm.js" 4 | } 5 | -------------------------------------------------------------------------------- /packages/sprinkles/src/createRuntimeSprinkles.ts: -------------------------------------------------------------------------------- 1 | import { 2 | createSprinkles as internalCreateSprinkles, 3 | type SprinklesFn, 4 | } from './createSprinkles'; 5 | import type { SprinklesProperties } from './types'; 6 | 7 | const composeStyles = (classList: string) => classList; 8 | 9 | export const createSprinkles = < 10 | Args extends ReadonlyArray, 11 | >( 12 | ...args: Args 13 | ): SprinklesFn => internalCreateSprinkles(composeStyles)(...args); 14 | 15 | /** @deprecated - Use `createSprinkles` */ 16 | export const createAtomsFn = createSprinkles; 17 | -------------------------------------------------------------------------------- /packages/utils/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@vanilla-extract/css-utils", 3 | "version": "0.1.4", 4 | "description": "Zero-runtime Stylesheets-in-TypeScript", 5 | "sideEffects": false, 6 | "main": "dist/vanilla-extract-css-utils.cjs.js", 7 | "module": "dist/vanilla-extract-css-utils.esm.js", 8 | "types": "dist/vanilla-extract-css-utils.cjs.d.ts", 9 | "preconstruct": { 10 | "entrypoints": [ 11 | "index.ts" 12 | ] 13 | }, 14 | "files": [ 15 | "/dist" 16 | ], 17 | "repository": { 18 | "type": "git", 19 | "url": "https://github.com/vanilla-extract-css/vanilla-extract.git", 20 | "directory": "packages/utils" 21 | }, 22 | "author": "SEEK", 23 | "license": "MIT" 24 | } 25 | -------------------------------------------------------------------------------- /packages/vite-plugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@vanilla-extract/vite-plugin", 3 | "version": "5.0.3", 4 | "description": "Zero-runtime Stylesheets-in-TypeScript", 5 | "main": "dist/vanilla-extract-vite-plugin.cjs.js", 6 | "module": "dist/vanilla-extract-vite-plugin.esm.js", 7 | "types": "dist/vanilla-extract-vite-plugin.cjs.d.ts", 8 | "files": [ 9 | "/dist" 10 | ], 11 | "repository": { 12 | "type": "git", 13 | "url": "https://github.com/vanilla-extract-css/vanilla-extract.git", 14 | "directory": "packages/vite-plugin" 15 | }, 16 | "author": "SEEK", 17 | "license": "MIT", 18 | "dependencies": { 19 | "@vanilla-extract/compiler": "workspace:^", 20 | "@vanilla-extract/integration": "workspace:^" 21 | }, 22 | "devDependencies": { 23 | "vite": "^5.0.0 || ^6.0.0" 24 | }, 25 | "peerDependencies": { 26 | "vite": "^5.0.0 || ^6.0.0" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /packages/webpack-plugin/extracted.js: -------------------------------------------------------------------------------- 1 | // This is a noop file for extracted CSS source to point to 2 | // Webpack requires a file to exist on disk for virtual source files 3 | -------------------------------------------------------------------------------- /packages/webpack-plugin/loader/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "dist/vanilla-extract-webpack-plugin-loader.cjs.js", 3 | "module": "dist/vanilla-extract-webpack-plugin-loader.esm.js" 4 | } 5 | -------------------------------------------------------------------------------- /packages/webpack-plugin/next/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "dist/vanilla-extract-webpack-plugin-next.cjs.js", 3 | "module": "dist/vanilla-extract-webpack-plugin-next.esm.js" 4 | } 5 | -------------------------------------------------------------------------------- /packages/webpack-plugin/src/__snapshots__/compiler.test.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`escapeWebpackTemplateString() /some/path/[...slug].js pattern 1`] = `"/some/path/[...slug].js"`; 4 | 5 | exports[`escapeWebpackTemplateString() /some/path/[[...slug]]/index.js pattern 1`] = `"/some/path/[[...slug]]/index.js"`; 6 | 7 | exports[`escapeWebpackTemplateString() /some/path[]/[slug]/[[foo]]/index.js pattern 1`] = `"/some/path[]/[\\slug\\]/[[\\foo\\]]/index.js"`; 8 | -------------------------------------------------------------------------------- /packages/webpack-plugin/src/compiler.test.ts: -------------------------------------------------------------------------------- 1 | import { escapeWebpackTemplateString } from './compiler'; 2 | 3 | describe('escapeWebpackTemplateString()', () => { 4 | test.each([ 5 | '/some/path/[...slug].js', 6 | '/some/path/[[...slug]]/index.js', 7 | '/some/path[]/[slug]/[[foo]]/index.js', 8 | ])('%s pattern', (filePath) => { 9 | expect(escapeWebpackTemplateString(filePath)).toMatchSnapshot(); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /packages/webpack-plugin/src/index.ts: -------------------------------------------------------------------------------- 1 | import type { Compiler } from 'webpack'; 2 | import { AbstractVanillaExtractPlugin } from './plugin'; 3 | 4 | export class VanillaExtractPlugin extends AbstractVanillaExtractPlugin { 5 | apply(compiler: Compiler) { 6 | this.inject(compiler, 'virtualFileLoader'); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/webpack-plugin/src/logger.ts: -------------------------------------------------------------------------------- 1 | import createDebug from 'debug'; 2 | import pc from 'picocolors'; 3 | 4 | export const formatResourcePath = (i: string) => 5 | pc.blue(`"${i.replace(/.*\//, '')}"`); 6 | 7 | createDebug.formatters.r = (r: string) => formatResourcePath(r); 8 | 9 | export const debug = createDebug; 10 | -------------------------------------------------------------------------------- /packages/webpack-plugin/src/next.ts: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | import { AbstractVanillaExtractPlugin } from './plugin'; 3 | import type { Compiler } from 'webpack'; 4 | 5 | const virtualNextFileLoader = require.resolve( 6 | path.join( 7 | path.dirname(require.resolve('../../package.json')), 8 | 'virtualNextFileLoader', 9 | ), 10 | ); 11 | 12 | export class VanillaExtractPlugin extends AbstractVanillaExtractPlugin { 13 | static loader = virtualNextFileLoader; 14 | 15 | apply(compiler: Compiler) { 16 | this.inject(compiler, 'virtualNextFileLoader'); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/webpack-plugin/src/types.ts: -------------------------------------------------------------------------------- 1 | import type { Compilation, Compiler } from 'webpack'; 2 | 3 | export interface LoaderContext { 4 | addDependency: (filePath: string) => void; 5 | addContextDependency: (filePath: string) => void; 6 | cacheable: (value: boolean) => void; 7 | target: string; 8 | resourcePath: string; 9 | context: string; 10 | rootContext: string; 11 | async: () => (err: unknown, result?: string) => void; 12 | hot: boolean; 13 | loaders: any[]; 14 | emitError: (error: Error) => void; 15 | _compiler: Compiler; 16 | _compilation: Compilation; 17 | mode: 'production' | 'development' | 'none'; 18 | } 19 | -------------------------------------------------------------------------------- /packages/webpack-plugin/src/virtualFileLoader.ts: -------------------------------------------------------------------------------- 1 | import { deserializeCss } from '@vanilla-extract/integration'; 2 | // @ts-expect-error 3 | import { getOptions } from 'loader-utils'; 4 | 5 | export default function (this: any) { 6 | const { source } = getOptions(this); 7 | const callback = this.async(); 8 | 9 | deserializeCss(source).then((deserializedCss) => { 10 | callback(null, deserializedCss); 11 | }); 12 | } 13 | -------------------------------------------------------------------------------- /packages/webpack-plugin/src/virtualNextFileLoader.ts: -------------------------------------------------------------------------------- 1 | import { deserializeCss } from '@vanilla-extract/integration'; 2 | 3 | export default function (this: any) { 4 | const callback = this.async(); 5 | const resourceQuery = this.resourceQuery.slice(1); 6 | 7 | try { 8 | const { source } = JSON.parse(decodeURIComponent(resourceQuery)); 9 | deserializeCss(source) 10 | .then((deserializedCss) => { 11 | callback(null, deserializedCss); 12 | }) 13 | .catch((e) => { 14 | callback(e as Error); 15 | }); 16 | } catch (e) { 17 | callback(e as Error); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/webpack-plugin/vanilla.virtual.css: -------------------------------------------------------------------------------- 1 | /* This is a noop file for extracted CSS source to point to */ 2 | /* Webpack requires a file to exist on disk for virtual source files */ 3 | -------------------------------------------------------------------------------- /packages/webpack-plugin/virtualFileLoader/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "dist/vanilla-extract-webpack-plugin-virtualFileLoader.cjs.js", 3 | "module": "dist/vanilla-extract-webpack-plugin-virtualFileLoader.esm.js" 4 | } 5 | -------------------------------------------------------------------------------- /packages/webpack-plugin/virtualNextFileLoader/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "dist/vanilla-extract-webpack-plugin-virtualNextFileLoader.cjs.js", 3 | "module": "dist/vanilla-extract-webpack-plugin-virtualNextFileLoader.esm.js" 4 | } 5 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | preferWorkspacePackages: true 2 | packages: 3 | - 'packages/*' 4 | - 'test-helpers' 5 | - 'fixtures/*' 6 | - 'fixtures/thirdparty/**' 7 | - 'site' 8 | - 'examples/*' 9 | - 'tests' 10 | - 'benchmarks' 11 | - 'scripts' 12 | -------------------------------------------------------------------------------- /prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | singleQuote: true, 3 | tabWidth: 2, 4 | trailingComma: 'all', 5 | overrides: [ 6 | { 7 | files: '*.md', 8 | options: { 9 | printWidth: 60, 10 | trailingComma: 'none', 11 | }, 12 | }, 13 | ], 14 | }; 15 | -------------------------------------------------------------------------------- /scripts/copy-next-plugin.ts: -------------------------------------------------------------------------------- 1 | import { glob } from 'tinyglobby'; 2 | import { existsSync } from 'fs'; 3 | import fs from 'fs/promises'; 4 | import path from 'path'; 5 | 6 | // We need to use distinct next plugins for each next fixutre 7 | // due to different next versions / mini-css-extract-plugin serializer registration 8 | const nextPluginDistDir = path.join( 9 | import.meta.dirname, 10 | '../packages/next-plugin/dist', 11 | ); 12 | 13 | if (!existsSync(nextPluginDistDir)) { 14 | throw new Error('packages/next-plugin/dist is missing.'); 15 | } 16 | 17 | const nextFixtureDirs = await glob('fixtures/next-*', { 18 | onlyDirectories: true, 19 | absolute: true, 20 | }); 21 | 22 | if (nextFixtureDirs.length === 0) { 23 | throw new Error('No next fixtures found.'); 24 | } 25 | 26 | for (const dir of nextFixtureDirs) { 27 | await fs.cp(nextPluginDistDir, path.join(dir, 'next-plugin', 'dist'), { 28 | recursive: true, 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /scripts/copy-readme-to-packages.ts: -------------------------------------------------------------------------------- 1 | import fs from 'fs/promises'; 2 | import path from 'path'; 3 | 4 | import { glob } from 'tinyglobby'; 5 | 6 | const packages = await glob('packages/*', { 7 | onlyDirectories: true, 8 | absolute: true, 9 | ignore: ['packages/sprinkles', 'packages/integration', 'packages/compiler'], 10 | }); 11 | 12 | for (const packageDir of packages) { 13 | await fs.copyFile( 14 | path.join(import.meta.dirname, '../README.md'), 15 | path.join(packageDir, 'README.md'), 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /scripts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@vanilla-extract/scripts", 3 | "private": true, 4 | "type": "module", 5 | "devDependencies": { 6 | "resolve.exports": "^2.0.2", 7 | "rollup": "^4.20.0", 8 | "rollup-plugin-dts": "^6.1.1", 9 | "rollup-plugin-node-externals": "^7.1.3", 10 | "tinyglobby": "^0.2.13" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /site/.gitignore: -------------------------------------------------------------------------------- 1 | docs-manifest.json 2 | -------------------------------------------------------------------------------- /site/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | [ 4 | '@babel/preset-env', 5 | { bugfixes: true, targets: 'last 2 Chrome versions' }, 6 | ], 7 | '@babel/preset-typescript', 8 | ['@babel/preset-react', { runtime: 'automatic' }], 9 | ], 10 | }; 11 | -------------------------------------------------------------------------------- /site/docs/api/create-container.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: createContainer 3 | parent: api 4 | --- 5 | 6 | # createContainer 7 | 8 | Creates a single scoped container name for use with [CSS Container Queries]. This avoids potential naming collisions with other containers. 9 | 10 | > 🚧  Ensure your target browsers [support container queries]. 11 | > Vanilla-extract supports the [container query syntax][css container queries] but does not polyfill the feature in unsupported browsers. 12 | 13 | ```ts compiled 14 | // sidebar.css.ts 15 | import { 16 | style, 17 | createContainer 18 | } from '@vanilla-extract/css'; 19 | 20 | export const sidebarContainer = createContainer(); 21 | 22 | export const sidebar = style({ 23 | containerName: sidebarContainer, 24 | containerType: 'inline-size' 25 | }); 26 | 27 | // navigation.css.ts 28 | import { 29 | style, 30 | createContainer 31 | } from '@vanilla-extract/css'; 32 | import { sidebarContainer } from './sidebar.css.ts'; 33 | 34 | export const navigation = style({ 35 | '@container': { 36 | [`${sidebarContainer} (min-width: 400px)`]: { 37 | display: 'flex' 38 | } 39 | } 40 | }); 41 | ``` 42 | 43 | [css container queries]: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Container_Queries 44 | [support container queries]: https://caniuse.com/css-container-queries 45 | -------------------------------------------------------------------------------- /site/docs/api/create-theme-contract.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: createThemeContract 3 | parent: api 4 | --- 5 | 6 | # createThemeContract 7 | 8 | Creates a contract of locally scoped variable names for themes to implement. 9 | 10 | This is useful if you want to split your themes into different bundles. In this case, your themes would be defined in separate files, but we'll keep this example simple. 11 | 12 | > 🎨  New to theming in vanilla-extract? Make sure you’ve read the [theming overview](/documentation/theming) first. 13 | 14 | ```ts compiled 15 | // themes.css.ts 16 | import { 17 | createThemeContract, 18 | createTheme, 19 | style 20 | } from '@vanilla-extract/css'; 21 | 22 | export const vars = createThemeContract({ 23 | color: { 24 | brand: null 25 | }, 26 | font: { 27 | body: null 28 | } 29 | }); 30 | 31 | export const themeA = createTheme(vars, { 32 | color: { 33 | brand: 'blue' 34 | }, 35 | font: { 36 | body: 'arial' 37 | } 38 | }); 39 | 40 | export const themeB = createTheme(vars, { 41 | color: { 42 | brand: 'pink' 43 | }, 44 | font: { 45 | body: 'comic sans ms' 46 | } 47 | }); 48 | 49 | export const brandText = style({ 50 | color: vars.color.brand, 51 | fontFamily: vars.font.body 52 | }); 53 | ``` 54 | -------------------------------------------------------------------------------- /site/docs/api/create-view-transition.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: createViewTransition 3 | parent: api 4 | --- 5 | 6 | # createViewTransition 7 | 8 | Creates a single scoped view transition name for use with [CSS View Transitions]. 9 | This avoids potential naming collisions with other view transitions. 10 | 11 | > 🚧  Ensure your target browsers [support view transitions]. 12 | > Vanilla-extract supports the [view transition syntax][css view transitions] but does not polyfill the feature in unsupported browsers. 13 | 14 | ```ts compiled 15 | // itemPage.css.ts 16 | import { 17 | style, 18 | createViewTransition 19 | } from '@vanilla-extract/css'; 20 | 21 | export const titleViewTransition = createViewTransition(); 22 | 23 | export const pageTitle = style({ 24 | viewTransitionName: titleViewTransition 25 | }); 26 | 27 | // navigation.css.ts 28 | import { style } from '@vanilla-extract/css'; 29 | import { titleViewTransition } from './itemPage.css.ts'; 30 | 31 | export const navigationLinkTitle = style({ 32 | viewTransitionName: titleViewTransition 33 | }); 34 | ``` 35 | 36 | [css view transitions]: https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API#css_additions 37 | [support view transitions]: https://caniuse.com/view-transitions 38 | -------------------------------------------------------------------------------- /site/docs/api/fallback-var.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: fallbackVar 3 | parent: api 4 | --- 5 | 6 | # fallbackVar 7 | 8 | Provides fallback values for variables that have been created using vanilla-extract APIs, e.g. `createVar`, `createTheme`, etc. 9 | 10 | As these APIs produce variable references that contain the CSS var function, e.g. `var(--colorVar__qzfheg0)`, it is necessary to handle the wrapping function when providing a fallback. 11 | 12 | ```ts compiled 13 | // style.css.ts 14 | 15 | import { 16 | createVar, 17 | fallbackVar, 18 | style 19 | } from '@vanilla-extract/css'; 20 | 21 | export const colorVar = createVar(); 22 | 23 | export const color = style({ 24 | color: fallbackVar(colorVar, 'blue') 25 | }); 26 | ``` 27 | 28 | ## Multiple fallback values 29 | 30 | The `fallbackVar` function handles falling back across multiple variables by providing multiple parameters. 31 | 32 | ```ts compiled 33 | // style.css.ts 34 | 35 | import { 36 | createVar, 37 | fallbackVar, 38 | style 39 | } from '@vanilla-extract/css'; 40 | 41 | export const primaryVar = createVar(); 42 | export const secondaryVar = createVar(); 43 | 44 | export const color = style({ 45 | color: fallbackVar(primaryVar, secondaryVar, 'blue') 46 | }); 47 | ``` 48 | -------------------------------------------------------------------------------- /site/docs/api/font-face.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: fontFace 3 | parent: api 4 | --- 5 | 6 | # fontFace 7 | 8 | Creates a locally scoped [font-family](https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-family) for the defined [@font-face](https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face). 9 | 10 | ```ts compiled 11 | // text.css.ts 12 | 13 | import { fontFace, style } from '@vanilla-extract/css'; 14 | 15 | const comicSans = fontFace({ 16 | src: 'local("Comic Sans MS")' 17 | }); 18 | 19 | export const font = style({ 20 | fontFamily: comicSans 21 | }); 22 | ``` 23 | 24 | ## Multiple Fonts with Single Family 25 | 26 | The `fontFace` function allows you to pass an array of font-face rules that may contain different rules but treat them as if they are from one font family. 27 | 28 | ```ts compiled 29 | // text.css.ts 30 | import { fontFace, style } from '@vanilla-extract/css'; 31 | 32 | const gentium = fontFace([ 33 | { 34 | src: 'local("Gentium")', 35 | fontWeight: 'normal' 36 | }, 37 | { 38 | src: 'local("Gentium Bold")', 39 | fontWeight: 'bold' 40 | } 41 | ]); 42 | 43 | export const font = style({ 44 | fontFamily: gentium 45 | }); 46 | ``` 47 | -------------------------------------------------------------------------------- /site/docs/global-api/create-global-var.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: createGlobalVar 3 | parent: global-api 4 | --- 5 | 6 | # createGlobalVar 7 | 8 | Similar to [`createVar`], `createGlobalVar` creates a global CSS variable reference: 9 | 10 | ```ts compiled 11 | // vars.css.ts 12 | 13 | import { 14 | createGlobalVar, 15 | style 16 | } from '@vanilla-extract/css'; 17 | 18 | const opacityVar = createGlobalVar('opacity'); 19 | 20 | export const content = style({ 21 | opacity: opacityVar 22 | }); 23 | ``` 24 | 25 | [@property] rules can also be created using `createGlobalVar`: 26 | 27 | ```ts compiled 28 | // vars.css.ts 29 | 30 | import { 31 | createGlobalVar, 32 | style 33 | } from '@vanilla-extract/css'; 34 | 35 | const opacityVar = createGlobalVar('opacity', { 36 | syntax: '', 37 | inherits: false, 38 | initialValue: '0.5' 39 | }); 40 | 41 | export const content = style({ 42 | opacity: opacityVar 43 | }); 44 | ``` 45 | 46 | [`createVar`]: /documentation/api/create-var 47 | [@property]: https://developer.mozilla.org/en-US/docs/Web/CSS/@property 48 | -------------------------------------------------------------------------------- /site/docs/global-api/global-font-face.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: globalFontFace 3 | parent: global-api 4 | --- 5 | 6 | # globalFontFace 7 | 8 | Creates a globally scoped custom font. 9 | 10 | ```ts compiled 11 | // text.css.ts 12 | 13 | import { 14 | globalFontFace, 15 | style 16 | } from '@vanilla-extract/css'; 17 | 18 | const comicSans = 'GlobalComicSans'; 19 | 20 | globalFontFace(comicSans, { 21 | src: 'local("Comic Sans MS")' 22 | }); 23 | 24 | export const font = style({ 25 | fontFamily: comicSans 26 | }); 27 | ``` 28 | 29 | ## Multiple Global Fonts with Single Family 30 | 31 | The `globalFontFace` function allows you to pass an array of font-face rules that may contain different rules but treat them as if they are from one font family. 32 | 33 | ```ts compiled 34 | // text.css.ts 35 | 36 | import { 37 | globalFontFace, 38 | style 39 | } from '@vanilla-extract/css'; 40 | 41 | const gentium = 'GlobalGentium'; 42 | 43 | globalFontFace(gentium, [ 44 | { 45 | src: 'local("Gentium")', 46 | fontWeight: 'normal' 47 | }, 48 | { 49 | src: 'local("Gentium Bold")', 50 | fontWeight: 'bold' 51 | } 52 | ]); 53 | 54 | export const font = style({ 55 | fontFamily: gentium 56 | }); 57 | ``` 58 | -------------------------------------------------------------------------------- /site/docs/global-api/global-keyframes.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: globalKeyframes 3 | parent: global-api 4 | --- 5 | 6 | # globalKeyframes 7 | 8 | Creates a globally scoped set of keyframes. 9 | 10 | ```ts compiled 11 | // animation.css.ts 12 | 13 | import { 14 | globalKeyframes, 15 | style 16 | } from '@vanilla-extract/css'; 17 | 18 | const rotate = 'globalRotate'; 19 | 20 | globalKeyframes(rotate, { 21 | '0%': { transform: 'rotate(0deg)' }, 22 | '100%': { transform: 'rotate(360deg)' } 23 | }); 24 | 25 | export const spin = style({ 26 | animation: `3s infinite ${rotate}` 27 | }); 28 | ``` 29 | -------------------------------------------------------------------------------- /site/docs/global-api/global-style.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: globalStyle 3 | parent: global-api 4 | --- 5 | 6 | # globalStyle 7 | 8 | Creates styles attached to a global selector. 9 | 10 | Requires a selector string as the first parameter, followed by a style object. 11 | 12 | ```ts compiled 13 | // app.css.ts 14 | 15 | import { globalStyle } from '@vanilla-extract/css'; 16 | 17 | globalStyle('html, body', { 18 | margin: 0 19 | }); 20 | ``` 21 | 22 | > 🧠  The global style object cannot use [simple pseudo](/documentation/styling#simple-pseudo-selectors) or [complex selectors](/documentation/styling/#complex-selectors). 23 | > This avoids unexpected results when merging with the global selector, e.g. `ul li:first-child, a > span`. 24 | 25 | Global selectors can also contain references to other scoped class names. 26 | 27 | ```ts compiled 28 | // app.css.ts 29 | 30 | import { style, globalStyle } from '@vanilla-extract/css'; 31 | 32 | export const parentClass = style({}); 33 | 34 | globalStyle(`${parentClass} > a`, { 35 | color: 'pink' 36 | }); 37 | ``` 38 | -------------------------------------------------------------------------------- /site/docs/integrations/gatsby.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Gatsby 3 | parent: integrations 4 | --- 5 | 6 | # Gatsby 7 | 8 | A plugin for integrating vanilla-extract with [Gatsby](https://www.gatsbyjs.com). 9 | 10 | ## Installation 11 | 12 | ```bash 13 | npm install @vanilla-extract/css @vanilla-extract/webpack-plugin gatsby-plugin-vanilla-extract 14 | ``` 15 | 16 | ## Setup 17 | 18 | Add the plugin to your Gatsby configuration. 19 | 20 | ```js 21 | // gatsby-config.js 22 | 23 | module.exports = { 24 | plugins: [`gatsby-plugin-vanilla-extract`] 25 | }; 26 | ``` 27 | 28 | ## Configuration 29 | 30 | See [plugin documentation](https://github.com/gatsby-uc/plugins/tree/main/packages/gatsby-plugin-vanilla-extract). 31 | -------------------------------------------------------------------------------- /site/docs/integrations/parcel.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Parcel 3 | parent: integrations 4 | --- 5 | 6 | # Parcel 7 | 8 | A Parcel transformer for integrating vanilla-extract with [Parcel](https://parceljs.org/). 9 | 10 | ## Installation 11 | 12 | ```bash 13 | npm install --save-dev @vanilla-extract/parcel-transformer 14 | ``` 15 | 16 | ## Setup 17 | 18 | Add the transformer to your Parcel configuration. 19 | 20 | ```json 21 | // .parcelrc 22 | { 23 | "transformers": { 24 | "*.css.ts": ["@vanilla-extract/parcel-transformer"] 25 | } 26 | } 27 | ``` 28 | -------------------------------------------------------------------------------- /site/docs/integrations/remix.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Remix 3 | parent: integrations 4 | --- 5 | 6 | # Remix 7 | 8 | [Remix](https://remix.run) provides support for Vanilla Extract out of the box. See [Vanilla Extract | Remix](https://remix.run/docs/en/main/styling/vanilla-extract) for details. 9 | 10 | Remix's (unstable) Vite compiler works with the [Vite integration]. It's as simple as adding the `@vanilla-extract/vite-plugin` to your Vite config: 11 | 12 | ```js 13 | import { unstable_vitePlugin as remix } from '@remix-run/dev'; 14 | import { vanillaExtractPlugin } from '@vanilla-extract/vite-plugin'; 15 | import { defineConfig } from 'vite'; 16 | 17 | export default defineConfig({ 18 | plugins: [remix(), vanillaExtractPlugin()] 19 | }); 20 | ``` 21 | 22 | See [Vite (Unstable) | Remix](https://remix.run/docs/en/main/future/vite#add-vanilla-extract-plugin) for more details. 23 | 24 | [vite integration]: /documentation/integrations/vite 25 | -------------------------------------------------------------------------------- /site/docs/packages/css-utils.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: CSS Utils 3 | parent: packages 4 | --- 5 | 6 | # CSS Utils 7 | 8 | An optional package providing utility functions that make it easier to work with CSS in TypeScript. 9 | 10 | ```bash 11 | npm install @vanilla-extract/css-utils 12 | ``` 13 | 14 | This package is not limited to vanilla-extract—it can be used with any CSS-in-JS library. 15 | 16 | ## calc 17 | 18 | Streamlines the creation of CSS calc expressions. 19 | 20 | ### Simple expressions 21 | 22 | ```tsx 23 | import { calc } from '@vanilla-extract/css-utils'; 24 | 25 | const styles = { 26 | height: calc.multiply('var(--grid-unit)', 2) 27 | }; 28 | ``` 29 | 30 | The following functions are available. 31 | 32 | - `calc.add` 33 | - `calc.subtract` 34 | - `calc.multiply` 35 | - `calc.divide` 36 | - `calc.negate` 37 | 38 | ### Chainable expressions 39 | 40 | The `calc` export is also a function, providing a chainable API for complex calc expressions. 41 | 42 | > When using expression chains it is necessary to call `toString()` to return the constructed expression as the final value. 43 | 44 | ```tsx 45 | import { calc } from '@vanilla-extract/css-utils'; 46 | 47 | const styles = { 48 | marginTop: calc('var(--space-large)') 49 | .divide(2) 50 | .negate() 51 | .toString() 52 | }; 53 | ``` 54 | -------------------------------------------------------------------------------- /site/legacy-routes.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "from": "/documentation/styling-api", "to": "/documentation/styling/" }, 3 | { 4 | "from": "/documentation/sprinkles-api/", 5 | "to": "/documentation/packages/sprinkles/" 6 | }, 7 | { 8 | "from": "/documentation/recipes-api/", 9 | "to": "/documentation/packages/recipes/" 10 | }, 11 | { 12 | "from": "/documentation/dynamic-api/", 13 | "to": "/documentation/packages/dynamic/" 14 | }, 15 | { 16 | "from": "/documentation/utility-functions/", 17 | "to": "/documentation/packages/css-utils/" 18 | }, 19 | { 20 | "from": "/documentation/setup/", 21 | "to": "/documentation/getting-started/#bundler-integration" 22 | } 23 | ] 24 | -------------------------------------------------------------------------------- /site/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanilla-extract-css/vanilla-extract/7efce3a9e733f4a5cc1322541d6e7774ea2d2df0/site/logo.png -------------------------------------------------------------------------------- /site/makeDocsManifest.js: -------------------------------------------------------------------------------- 1 | const { resolve, join } = require('path'); 2 | const { promises } = require('fs'); 3 | const makeDocumentIndex = require('./documentIndexer'); 4 | const contents = require('./contents'); 5 | 6 | (async () => { 7 | const manifest = { groups: [], pages: [] }; 8 | 9 | for (const { group, label, pages } of contents) { 10 | manifest.groups.push(label); 11 | 12 | for (const page of pages) { 13 | console.log('Loading', page); 14 | const fileName = join(group, `${page}.md`); 15 | const fileContents = await promises.readFile( 16 | join(__dirname, './docs', fileName), 17 | ); 18 | 19 | const { sections, parent } = makeDocumentIndex(fileContents); 20 | 21 | const route = parent 22 | ? `/documentation/${parent}/${page}/` 23 | : `/documentation/${page}/`; 24 | 25 | manifest.pages.push({ 26 | group, 27 | label, 28 | fileName, 29 | route, 30 | sections, 31 | }); 32 | } 33 | } 34 | 35 | await promises.writeFile( 36 | resolve(__dirname, 'docs-manifest.json'), 37 | JSON.stringify(manifest, null, 2), 38 | ); 39 | })(); 40 | -------------------------------------------------------------------------------- /site/src/App.css.ts: -------------------------------------------------------------------------------- 1 | import { globalStyle } from '@vanilla-extract/css'; 2 | import { darkMode } from './system/styles/sprinkles.css'; 3 | import { vars } from './themes.css'; 4 | 5 | globalStyle('html, body', { 6 | margin: 0, 7 | padding: 0, 8 | }); 9 | 10 | globalStyle(`.${darkMode}`, { 11 | background: vars.palette.black, 12 | color: vars.palette.gray50, 13 | colorScheme: 'dark', 14 | }); 15 | 16 | globalStyle('html', { 17 | background: vars.palette.white, 18 | color: vars.palette.coolGray900, 19 | }); 20 | -------------------------------------------------------------------------------- /site/src/Blockquote/Blockquote.css.ts: -------------------------------------------------------------------------------- 1 | import { globalStyle, style } from '@vanilla-extract/css'; 2 | import { darkMode } from '../system/styles/sprinkles.css'; 3 | import { vars } from '../themes.css'; 4 | 5 | export const root = style({ 6 | '::before': { 7 | content: '""', 8 | position: 'absolute', 9 | background: vars.palette.pink100, 10 | top: 0, 11 | bottom: 0, 12 | left: 0, 13 | right: 0, 14 | zIndex: -1, 15 | transform: 'skewX(-2deg) skewY(-0.75deg)', 16 | }, 17 | selectors: { 18 | [`.${darkMode} &::before`]: { 19 | background: vars.palette.blueGray900, 20 | }, 21 | }, 22 | }); 23 | 24 | globalStyle(`${root} code`, { 25 | background: vars.palette.pink200, 26 | color: 'inherit', 27 | }); 28 | 29 | globalStyle(`.${darkMode} ${root} code`, { 30 | background: vars.palette.blueGray800, 31 | color: 'inherit', 32 | }); 33 | -------------------------------------------------------------------------------- /site/src/Blockquote/Blockquote.tsx: -------------------------------------------------------------------------------- 1 | import type { ReactNode } from 'react'; 2 | import { Box } from '../system'; 3 | import * as styles from './Blockquote.css'; 4 | 5 | export default (props: { children: ReactNode }) => { 6 | return ( 7 | 13 | {props.children} 14 | 15 | ); 16 | }; 17 | -------------------------------------------------------------------------------- /site/src/Chevron/Chevron.css.ts: -------------------------------------------------------------------------------- 1 | import { style, styleVariants } from '@vanilla-extract/css'; 2 | 3 | export const root = style({ 4 | transition: 'transform .15s ease', 5 | position: 'relative', 6 | top: '1px', 7 | }); 8 | 9 | export const direction = styleVariants({ 10 | down: {}, 11 | up: { transform: 'rotate(180deg)' }, 12 | left: { transform: 'rotate(90deg)' }, 13 | right: { transform: 'rotate(270deg)' }, 14 | }); 15 | -------------------------------------------------------------------------------- /site/src/Chevron/Chevron.tsx: -------------------------------------------------------------------------------- 1 | import classnames from 'classnames'; 2 | import * as styles from './Chevron.css'; 3 | 4 | export interface ChevronProps { 5 | direction: 'up' | 'down' | 'left' | 'right'; 6 | } 7 | 8 | export const Chevron = ({ direction = 'down' }: ChevronProps) => ( 9 | 16 | 17 | 18 | ); 19 | -------------------------------------------------------------------------------- /site/src/Code/ErrorHighlighter.css.ts: -------------------------------------------------------------------------------- 1 | import { style } from '@vanilla-extract/css'; 2 | import { vars } from '../themes.css'; 3 | 4 | export const errorUnderline = style({ 5 | textDecorationStyle: 'dashed', 6 | textDecorationColor: vars.palette.red, 7 | textDecorationThickness: '3px', 8 | textDecorationLine: 'underline', 9 | textDecorationSkipInk: 'none', 10 | textUnderlineOffset: '2px', 11 | }); 12 | -------------------------------------------------------------------------------- /site/src/Code/ErrorHighlighter.tsx: -------------------------------------------------------------------------------- 1 | import { useRef, useEffect, type ReactNode } from 'react'; 2 | import * as styles from './ErrorHighlighter.css'; 3 | 4 | export interface CodeProps { 5 | children: ReactNode; 6 | tokens: Array; 7 | } 8 | 9 | export const ErrorHighlighter = ({ tokens, children }: CodeProps) => { 10 | const rootRef = useRef(null); 11 | 12 | useEffect(() => { 13 | if (rootRef.current === null || tokens.length === 0) { 14 | return; 15 | } 16 | 17 | const spans = rootRef.current.querySelectorAll('code span'); 18 | 19 | if (!spans) { 20 | return; 21 | } 22 | 23 | const errorNodes: Array = []; 24 | for (const span of Array.from(spans)) { 25 | if (span.innerHTML && tokens.includes(span.innerHTML.trim())) { 26 | span.classList.add(styles.errorUnderline); 27 | errorNodes.push(span); 28 | } 29 | } 30 | 31 | return () => { 32 | errorNodes.forEach((errorNode) => { 33 | errorNode.classList.remove(styles.errorUnderline); 34 | }); 35 | }; 36 | }, [rootRef.current, tokens]); 37 | 38 | return
{children}
; 39 | }; 40 | -------------------------------------------------------------------------------- /site/src/ColorModeToggle/ColorModeToggle.css.ts: -------------------------------------------------------------------------------- 1 | import { assignVars, createThemeContract, style } from '@vanilla-extract/css'; 2 | import { darkMode } from '../system/styles/sprinkles.css'; 3 | import { vars } from '../themes.css'; 4 | 5 | const themeVars = createThemeContract({ 6 | toggleBrightness: null, 7 | toggleContent: null, 8 | focusRingColor: null, 9 | }); 10 | 11 | const lightVars = assignVars(themeVars, { 12 | toggleBrightness: '0', 13 | toggleContent: '"☀️"', 14 | focusRingColor: vars.palette.pink400, 15 | }); 16 | 17 | const darkVars = assignVars(themeVars, { 18 | toggleBrightness: '10', 19 | toggleContent: '"🌙"', 20 | focusRingColor: vars.palette.pink500, 21 | }); 22 | 23 | export const root = style({ 24 | outline: 'none', 25 | fontSize: 24, 26 | height: 42, 27 | width: 42, 28 | vars: lightVars, 29 | ':focus-visible': { 30 | boxShadow: `0px 0px 0px 3px ${themeVars.focusRingColor}`, 31 | }, 32 | '::before': { 33 | content: themeVars.toggleContent, 34 | filter: `contrast(0) brightness(${themeVars.toggleBrightness})`, 35 | }, 36 | selectors: { 37 | [`.${darkMode} &`]: { 38 | vars: darkVars, 39 | }, 40 | }, 41 | }); 42 | -------------------------------------------------------------------------------- /site/src/Divider/Divider.css.ts: -------------------------------------------------------------------------------- 1 | import { calc } from '@vanilla-extract/css-utils'; 2 | import { style } from '@vanilla-extract/css'; 3 | import { vars } from '../themes.css'; 4 | 5 | export const root = style({ 6 | height: `${calc(vars.grid).multiply(2)}`, 7 | width: 120, 8 | }); 9 | -------------------------------------------------------------------------------- /site/src/Divider/Divider.tsx: -------------------------------------------------------------------------------- 1 | import { Box } from '../system'; 2 | import * as styles from './Divider.css'; 3 | 4 | export default () => { 5 | return ( 6 | 12 | ); 13 | }; 14 | -------------------------------------------------------------------------------- /site/src/DocsPage/SiblingDoc/SiblingDoc.tsx: -------------------------------------------------------------------------------- 1 | import Link from '../../Typography/Link'; 2 | import Text from '../../Typography/Text'; 3 | import { Chevron } from '../../Chevron/Chevron'; 4 | import { Box } from '../../system'; 5 | 6 | export interface SiblingDocProps { 7 | title: string; 8 | route: string; 9 | direction: 'left' | 'right'; 10 | subtitle?: string; 11 | } 12 | export default ({ title, route, subtitle, direction }: SiblingDocProps) => ( 13 | 20 | 21 | {direction === 'left' ? : null} 22 | 28 | 29 | {subtitle} 30 | 31 | {title} 32 | 33 | {direction === 'right' ? : null} 34 | 35 | 36 | ); 37 | -------------------------------------------------------------------------------- /site/src/InlineCode/InlineCode.css.ts: -------------------------------------------------------------------------------- 1 | import { style } from '@vanilla-extract/css'; 2 | import { darkMode } from '../system/styles/sprinkles.css'; 3 | import { vars } from '../themes.css'; 4 | 5 | export const code = style({ 6 | fontFamily: vars.fonts.code, 7 | wordWrap: 'break-word', 8 | '::before': { 9 | content: '""', 10 | position: 'absolute', 11 | background: vars.palette.pink100, 12 | top: 0, 13 | bottom: 0, 14 | left: 0, 15 | right: 0, 16 | zIndex: -1, 17 | margin: '2px 0', 18 | clipPath: 'polygon(0 0, 100% 0, calc(100% - 3px) 100%, 3px 100%)', 19 | transform: 'skewY(-0.25deg)', 20 | }, 21 | selectors: { 22 | [`.${darkMode} &::before`]: { 23 | background: vars.palette.gray800, 24 | }, 25 | [`a > &`]: { 26 | textDecoration: 'underline 0.05em', 27 | }, 28 | ['a:hover > &']: { 29 | color: 'currentcolor', 30 | }, 31 | ['a:focus > &']: { 32 | outline: 'none', 33 | color: 'currentcolor', 34 | }, 35 | }, 36 | }); 37 | -------------------------------------------------------------------------------- /site/src/InlineCode/InlineCode.tsx: -------------------------------------------------------------------------------- 1 | import type { ReactNode } from 'react'; 2 | import { Box } from '../system'; 3 | import * as styles from './InlineCode.css'; 4 | 5 | export interface InlineCodeProps { 6 | children: ReactNode; 7 | inline?: boolean; 8 | } 9 | export default ({ children }: InlineCodeProps) => { 10 | return ( 11 | 21 | {children} 22 | 23 | ); 24 | }; 25 | -------------------------------------------------------------------------------- /site/src/SearchInput/SearchInput.tsx: -------------------------------------------------------------------------------- 1 | import { DocSearch } from '@docsearch/react'; 2 | import '@docsearch/css'; 3 | import type { ComponentProps } from 'react'; 4 | 5 | import './SearchInput.css'; 6 | 7 | type DocSearchProps = ComponentProps; 8 | 9 | // Make search item URLs relative so the local site doesn't take you back to prod 10 | const transformSearchResultItems: DocSearchProps['transformItems'] = (items) => 11 | items.map((item) => { 12 | const url = new URL(item.url); 13 | 14 | return { 15 | ...item, 16 | url: `${url.pathname}${url.hash}`, 17 | }; 18 | }); 19 | 20 | const getMissingResultsUrl: DocSearchProps['getMissingResultsUrl'] = ({ 21 | query, 22 | }) => 23 | `https://github.com/vanilla-extract-css/vanilla-extract/issues/new?assignees=&labels=pending+triage&template=bug_report.yml&bug-description=Search query \`${encodeURIComponent( 24 | query, 25 | )}\` should return search results.`; 26 | 27 | export const SearchInput = () => ( 28 | 36 | ); 37 | -------------------------------------------------------------------------------- /site/src/Tweet/Tweet.css.ts: -------------------------------------------------------------------------------- 1 | import { createVar, style } from '@vanilla-extract/css'; 2 | import { darkMode } from '../system/styles/sprinkles.css'; 3 | import { vars } from '../themes.css'; 4 | 5 | export const tweetLink = style({ 6 | ':hover': { 7 | textDecoration: 'none', 8 | }, 9 | ':focus': { 10 | outline: 'none', 11 | }, 12 | }); 13 | 14 | export const shadowColorVar = createVar(); 15 | 16 | export const tweet = style({ 17 | maxWidth: 440, 18 | boxShadow: `0 0 30px -10px ${shadowColorVar}`, 19 | vars: { 20 | [shadowColorVar]: vars.palette.blue300, 21 | }, 22 | selectors: { 23 | [`.${darkMode} &`]: { 24 | vars: { 25 | [shadowColorVar]: vars.palette.gray900, 26 | }, 27 | }, 28 | [`${tweetLink}:focus &`]: { 29 | vars: { 30 | [shadowColorVar]: vars.palette.pink400, 31 | }, 32 | }, 33 | [`.${darkMode} ${tweetLink}:focus &`]: { 34 | vars: { 35 | [shadowColorVar]: vars.palette.pink400, 36 | }, 37 | }, 38 | }, 39 | }); 40 | 41 | export const avatar = style({ 42 | backgroundRepeat: 'no-repeat', 43 | backgroundPosition: 'center center', 44 | backgroundSize: 'cover', 45 | height: 60, 46 | width: 60, 47 | overflow: 'hidden', 48 | clipPath: 'polygon(3% 2%, 100% 0, 94% 94%, 0 100%)', 49 | }); 50 | -------------------------------------------------------------------------------- /site/src/Typography/Link.css.ts: -------------------------------------------------------------------------------- 1 | import { style } from '@vanilla-extract/css'; 2 | import { vars } from '../themes.css'; 3 | 4 | export const underlineOnHover = style({ 5 | selectors: { 6 | ['&:not(:hover)']: { 7 | textDecoration: 'none', 8 | }, 9 | }, 10 | }); 11 | 12 | export const underlineNever = style({ 13 | textDecoration: 'none', 14 | ':hover': { 15 | textDecoration: 'none', 16 | }, 17 | }); 18 | 19 | export const highlightOnHover = style({ 20 | ':hover': { 21 | color: vars.palette.pink500, 22 | }, 23 | ':focus': { 24 | outline: 'none', 25 | color: vars.palette.pink500, 26 | }, 27 | }); 28 | -------------------------------------------------------------------------------- /site/src/assets/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanilla-extract-css/vanilla-extract/7efce3a9e733f4a5cc1322541d6e7774ea2d2df0/site/src/assets/android-chrome-192x192.png -------------------------------------------------------------------------------- /site/src/assets/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanilla-extract-css/vanilla-extract/7efce3a9e733f4a5cc1322541d6e7774ea2d2df0/site/src/assets/android-chrome-512x512.png -------------------------------------------------------------------------------- /site/src/assets/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanilla-extract-css/vanilla-extract/7efce3a9e733f4a5cc1322541d6e7774ea2d2df0/site/src/assets/apple-touch-icon.png -------------------------------------------------------------------------------- /site/src/assets/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanilla-extract-css/vanilla-extract/7efce3a9e733f4a5cc1322541d6e7774ea2d2df0/site/src/assets/favicon-16x16.png -------------------------------------------------------------------------------- /site/src/assets/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanilla-extract-css/vanilla-extract/7efce3a9e733f4a5cc1322541d6e7774ea2d2df0/site/src/assets/favicon-32x32.png -------------------------------------------------------------------------------- /site/src/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanilla-extract-css/vanilla-extract/7efce3a9e733f4a5cc1322541d6e7774ea2d2df0/site/src/assets/favicon.ico -------------------------------------------------------------------------------- /site/src/assets/og-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanilla-extract-css/vanilla-extract/7efce3a9e733f4a5cc1322541d6e7774ea2d2df0/site/src/assets/og-image.png -------------------------------------------------------------------------------- /site/src/assets/site.webmanifest: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Vanilla Extract", 3 | "short_name": "vanilla-extract", 4 | "description": "Zero-runtime Stylesheets-in-TypeScript.", 5 | "start_url": "/", 6 | "background_color": "transparent", 7 | "theme_color": "#fff", 8 | "display": "standalone", 9 | "icons": [ 10 | { 11 | "src": "/android-chrome-192x192.png", 12 | "sizes": "192x192", 13 | "type": "image/png" 14 | }, 15 | { 16 | "src": "/android-chrome-512x512.png", 17 | "sizes": "512x512", 18 | "type": "image/png" 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /site/src/client.tsx: -------------------------------------------------------------------------------- 1 | import ReactDOM from 'react-dom/client'; 2 | import { BrowserRouter } from 'react-router-dom'; 3 | import { HeadProvider } from 'react-head'; 4 | import App from './App'; 5 | 6 | ReactDOM.hydrateRoot( 7 | document.getElementById('app')!, 8 | 9 | 10 | 11 | 12 | , 13 | ); 14 | -------------------------------------------------------------------------------- /site/src/docs-store.ts: -------------------------------------------------------------------------------- 1 | import docsManifest from '../docs-manifest.json'; 2 | 3 | export const groups = docsManifest.groups; 4 | 5 | export const pages = docsManifest.pages.map( 6 | ({ group, label, fileName, route, sections }) => { 7 | const { frontMatter, default: component } = require(`../docs/${fileName}`); 8 | 9 | return { 10 | group, 11 | label, 12 | Component: component as (props: any) => JSX.Element, 13 | title: frontMatter.title as string, 14 | route, 15 | sections, 16 | }; 17 | }, 18 | ); 19 | -------------------------------------------------------------------------------- /site/src/index.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.md' { 2 | let MDXComponent: (props: any) => JSX.Element; 3 | export default MDXComponent; 4 | } 5 | 6 | declare module '*.png' { 7 | let ImageSrc: string; 8 | export default ImageSrc; 9 | } 10 | -------------------------------------------------------------------------------- /site/src/mdx-components.css.ts: -------------------------------------------------------------------------------- 1 | import { calc } from '@vanilla-extract/css-utils'; 2 | import { style } from '@vanilla-extract/css'; 3 | import { headerHeight } from './DocsPage/DocsPage.css'; 4 | import { vars } from './themes.css'; 5 | 6 | export const headingScrollTop = style({ 7 | scrollMarginTop: calc.add(headerHeight, vars.spacing.xxlarge), 8 | }); 9 | -------------------------------------------------------------------------------- /site/src/system/ContentBlock/ContentBlock.css.ts: -------------------------------------------------------------------------------- 1 | import { style } from '@vanilla-extract/css'; 2 | 3 | export const root = style({ 4 | margin: '0 auto', 5 | }); 6 | -------------------------------------------------------------------------------- /site/src/system/ContentBlock/ContentBlock.tsx: -------------------------------------------------------------------------------- 1 | import type { ReactNode } from 'react'; 2 | import { Box } from '../'; 3 | import * as styles from './ContentBlock.css'; 4 | import type { BoxProps } from '../Box/Box'; 5 | 6 | export const ContentBlock = ({ 7 | children, 8 | withGutters = false, 9 | size = 'standard', 10 | }: { 11 | children: ReactNode; 12 | withGutters?: boolean; 13 | size?: BoxProps['maxWidth']; 14 | }) => { 15 | return ( 16 | 25 | {children} 26 | 27 | ); 28 | }; 29 | -------------------------------------------------------------------------------- /site/src/system/Stack/Stack.tsx: -------------------------------------------------------------------------------- 1 | import { Children, type ReactNode } from 'react'; 2 | import { Box } from '../'; 3 | import type { BoxProps } from '../Box/Box'; 4 | import { 5 | mapResponsiveValue, 6 | type ResponsiveValue, 7 | } from '../styles/sprinkles.css'; 8 | 9 | const alignToFlexAlign = { 10 | left: 'flex-start', 11 | center: 'center', 12 | right: 'flex-end', 13 | } as const; 14 | 15 | export const Stack = ({ 16 | children, 17 | space, 18 | align, 19 | }: { 20 | children: ReactNode; 21 | space: BoxProps['paddingBottom']; 22 | align?: ResponsiveValue<'left' | 'center' | 'right'>; 23 | }) => { 24 | const stackItems = Children.toArray(children); 25 | const alignItems = align 26 | ? mapResponsiveValue(align, (value) => alignToFlexAlign[value]) 27 | : undefined; 28 | 29 | return ( 30 | 31 | {stackItems.map((item, index) => ( 32 | 36 | {item} 37 | 38 | ))} 39 | 40 | ); 41 | }; 42 | -------------------------------------------------------------------------------- /site/src/system/index.ts: -------------------------------------------------------------------------------- 1 | export { Box } from './Box/Box'; 2 | export { ButtonLink } from './ButtonLink/ButtonLink'; 3 | export { ContentBlock } from './ContentBlock/ContentBlock'; 4 | export { Columns } from './Columns/Columns'; 5 | export { Stack } from './Stack/Stack'; 6 | -------------------------------------------------------------------------------- /test-helpers/src/getStylesheet.ts: -------------------------------------------------------------------------------- 1 | import postcss from 'postcss'; 2 | import prettier from 'prettier'; 3 | import litePreset from 'cssnano-preset-lite'; 4 | import cssnano from 'cssnano'; 5 | import got from 'got'; 6 | 7 | export const stylesheetName = 'main.css'; 8 | 9 | export async function getStylesheet(url: string, stylesheetName = 'main.css') { 10 | const response = await got(`${url}/${stylesheetName}`); 11 | // Just remove comments and normalize whitespace 12 | // https://cssnano.co/docs/what-are-optimisations/#what-optimisations-do-you-support%3F 13 | const { css } = await postcss([cssnano({ preset: litePreset() })]).process( 14 | response.body, 15 | { 16 | from: undefined, 17 | }, 18 | ); 19 | 20 | return prettier.format(css, { parser: 'css' }); 21 | } 22 | -------------------------------------------------------------------------------- /test-helpers/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './startFixture'; 2 | export * from './startFixture/next'; 3 | export * from './getStylesheet'; 4 | 5 | export const getTestNodes = (fixture: string) => 6 | require(`@fixtures/${fixture}/test-nodes.json`); 7 | -------------------------------------------------------------------------------- /test-helpers/src/startFixture/parcel-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@parcel/config-default", 3 | "transformers": { 4 | "*.css.ts": ["@vanilla-extract/parcel-transformer"] 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test-helpers/src/startFixture/types.ts: -------------------------------------------------------------------------------- 1 | import type { EsbuildFixtureOptions } from './esbuild'; 2 | import type { NextFixtureOptions } from './next'; 3 | import type { ParcelFixtureOptions } from './parcel'; 4 | import type { ViteFixtureOptions } from './vite'; 5 | import type { WebpackFixtureOptions } from './webpack'; 6 | 7 | type BuildType = 8 | | WebpackFixtureOptions['type'] 9 | | EsbuildFixtureOptions['type'] 10 | | ViteFixtureOptions['type'] 11 | | ParcelFixtureOptions['type'] 12 | | NextFixtureOptions['type']; 13 | 14 | export interface TestServer { 15 | type: BuildType; 16 | url: string; 17 | close: () => Promise; 18 | stylesheet?: string; 19 | } 20 | -------------------------------------------------------------------------------- /test-helpers/src/startFixtureCLI.ts: -------------------------------------------------------------------------------- 1 | import parseArgs from 'minimist'; 2 | import { startFixture } from './startFixture'; 3 | 4 | const { 5 | _: [fixtureName], 6 | type, 7 | hot, 8 | mode, 9 | } = parseArgs(process.argv.slice(2)); 10 | 11 | startFixture(fixtureName, { type, hot, mode } as any).then((server) => { 12 | // eslint-disable-next-line no-console 13 | console.log('Fixture running on', server.url); 14 | }); 15 | -------------------------------------------------------------------------------- /tests/compiler/fixtures/class-composition/base.css.ts: -------------------------------------------------------------------------------- 1 | import { style } from '@vanilla-extract/css'; 2 | 3 | export const fontFamilyBase = style({ 4 | fontFamily: 'Arial, sans-serif', 5 | }); 6 | 7 | export const base = style([fontFamilyBase, { background: 'blue' }]); 8 | -------------------------------------------------------------------------------- /tests/compiler/fixtures/class-composition/button.css.ts: -------------------------------------------------------------------------------- 1 | import { style } from '@vanilla-extract/css'; 2 | import { base } from './base.css'; 3 | 4 | export const button = style([ 5 | base, 6 | { 7 | color: 'red', 8 | }, 9 | ]); 10 | -------------------------------------------------------------------------------- /tests/compiler/fixtures/class-composition/shared.css.ts: -------------------------------------------------------------------------------- 1 | import { style } from '@vanilla-extract/css'; 2 | 3 | export const shared = style({ background: 'blue' }); 4 | -------------------------------------------------------------------------------- /tests/compiler/fixtures/class-composition/stepper.css.ts: -------------------------------------------------------------------------------- 1 | import { style } from '@vanilla-extract/css'; 2 | import { base } from './base.css'; 3 | import { button } from './button.css'; 4 | 5 | export const stepperContainer = style([ 6 | base, 7 | { 8 | fontSize: '32px', 9 | }, 10 | ]); 11 | 12 | export const stepperButton = style({ 13 | selectors: { 14 | [`${stepperContainer} ${button}&`]: { 15 | border: '1px solid black', 16 | }, 17 | }, 18 | }); 19 | -------------------------------------------------------------------------------- /tests/compiler/fixtures/class-composition/styles.css.ts: -------------------------------------------------------------------------------- 1 | import { style } from '@vanilla-extract/css'; 2 | import { shared } from './shared.css'; 3 | 4 | export const className = style([shared, { color: 'red' }]); 5 | -------------------------------------------------------------------------------- /tests/compiler/fixtures/selectors/getter.css.ts: -------------------------------------------------------------------------------- 1 | import { style } from '@vanilla-extract/css'; 2 | 3 | export const child = style({ 4 | background: 'blue', 5 | get selectors() { 6 | return { 7 | [`${parent} &`]: { 8 | color: 'red', 9 | }, 10 | }; 11 | }, 12 | }); 13 | 14 | export const parent = style({ 15 | background: 'yellow', 16 | selectors: { 17 | [`&:has(${child})`]: { 18 | padding: 10, 19 | }, 20 | }, 21 | }); 22 | -------------------------------------------------------------------------------- /tests/compiler/fixtures/tsconfig-paths/src/main.css.ts: -------------------------------------------------------------------------------- 1 | import { style } from '@vanilla-extract/css'; 2 | 3 | export const box = style({ 4 | boxSizing: 'border-box', 5 | margin: 0, 6 | padding: 0, 7 | }); 8 | -------------------------------------------------------------------------------- /tests/compiler/fixtures/tsconfig-paths/src/main.tsx: -------------------------------------------------------------------------------- 1 | import { box } from 'main.css'; 2 | 3 | document.getElementById('root')!.innerHTML = ` 4 |
hello world
5 | `; 6 | -------------------------------------------------------------------------------- /tests/compiler/fixtures/tsconfig-paths/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "isolatedModules": true, 4 | "module": "ESNext", 5 | "moduleResolution": "Bundler", 6 | "baseUrl": "./src" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /tests/compiler/fixtures/unused-compositions/shared.css.ts: -------------------------------------------------------------------------------- 1 | import { style } from '@vanilla-extract/css'; 2 | 3 | export const shared = style({ 4 | padding: '20px', 5 | background: 'peachpuff', 6 | }); 7 | -------------------------------------------------------------------------------- /tests/compiler/fixtures/unused-compositions/styles_a.css.ts: -------------------------------------------------------------------------------- 1 | import { style } from '@vanilla-extract/css'; 2 | import { shared } from './shared.css'; 3 | 4 | export const root = style([shared]); 5 | -------------------------------------------------------------------------------- /tests/compiler/fixtures/unused-compositions/styles_b.css.ts: -------------------------------------------------------------------------------- 1 | import { style } from '@vanilla-extract/css'; 2 | import { shared } from './shared.css'; 3 | 4 | export const root = style([shared]); 5 | -------------------------------------------------------------------------------- /tests/compiler/fixtures/vite-config/alias.css.ts: -------------------------------------------------------------------------------- 1 | import { style } from '@vanilla-extract/css'; 2 | // @ts-expect-error aliased path 3 | import { border } from '@util/vars.css'; 4 | 5 | export const root = style({ 6 | vars: { 7 | [border]: '1px solid black', 8 | }, 9 | border, 10 | }); 11 | -------------------------------------------------------------------------------- /tests/compiler/fixtures/vite-config/image.css.ts: -------------------------------------------------------------------------------- 1 | import { style } from '@vanilla-extract/css'; 2 | // @ts-expect-error No type definition for image assets 3 | import testImage from './test.jpg'; 4 | 5 | export const imageStyle1 = style({ 6 | backgroundImage: `url('${testImage}')`, 7 | }); 8 | 9 | export const imageStyle2 = style({ 10 | backgroundImage: `url('/fixtures/vite-config/test.jpg')`, 11 | }); 12 | -------------------------------------------------------------------------------- /tests/compiler/fixtures/vite-config/plugin.css.ts: -------------------------------------------------------------------------------- 1 | import { style } from '@vanilla-extract/css'; 2 | // @ts-expect-error virtual module 3 | import { color } from '~/vars'; 4 | 5 | export const root = style({ 6 | color, 7 | }); 8 | -------------------------------------------------------------------------------- /tests/compiler/fixtures/vite-config/test.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanilla-extract-css/vanilla-extract/7efce3a9e733f4a5cc1322541d6e7774ea2d2df0/tests/compiler/fixtures/vite-config/test.jpg -------------------------------------------------------------------------------- /tests/compiler/fixtures/vite-config/util/vars.css.ts: -------------------------------------------------------------------------------- 1 | import { createVar } from '@vanilla-extract/css'; 2 | 3 | export const border = createVar(); 4 | -------------------------------------------------------------------------------- /tests/e2e/features.playwright.ts: -------------------------------------------------------------------------------- 1 | import { expect } from '@playwright/test'; 2 | import { 3 | getStylesheet, 4 | startFixture, 5 | type TestServer, 6 | } from '@vanilla-extract-private/test-helpers'; 7 | 8 | import test from './fixture'; 9 | import { all as testCases } from './testCases'; 10 | 11 | testCases.forEach(({ type, mode, snapshotCss = true }) => { 12 | test.describe(`features - ${type} (${mode})`, () => { 13 | let server: TestServer; 14 | 15 | test.beforeAll(async ({ port }) => { 16 | server = await startFixture('features', { 17 | type, 18 | mode, 19 | basePort: port, 20 | }); 21 | }); 22 | 23 | test('screenshot', async ({ page }) => { 24 | await page.goto(server.url); 25 | 26 | expect(await page.screenshot()).toMatchSnapshot('features.png'); 27 | }); 28 | 29 | if (snapshotCss) { 30 | test('CSS @agnostic', async () => { 31 | expect( 32 | await getStylesheet(server.url, server.stylesheet), 33 | ).toMatchSnapshot(`features-${type}--${mode}.css`); 34 | }); 35 | } 36 | 37 | test.afterAll(async () => { 38 | await server.close(); 39 | }); 40 | }); 41 | }); 42 | -------------------------------------------------------------------------------- /tests/e2e/features.playwright.ts-snapshots/features-esbuild--production.css: -------------------------------------------------------------------------------- 1 | ._1o6ek500 { 2 | height: 50px; 3 | } 4 | ._1o6ek500:after { 5 | content: "Below 700px"; 6 | display: block; 7 | } 8 | ._1o6ek501 { 9 | background-color: powderblue; 10 | } 11 | ._1o6ek501:hover { 12 | background-color: slategray; 13 | } 14 | ._1o6ek502 { 15 | background-color: powderblue; 16 | } 17 | ._1o6ek502:hover { 18 | background-color: slategray; 19 | } 20 | ._1o6ek503 { 21 | background-color: powderblue; 22 | } 23 | ._1o6ek503:hover { 24 | background-color: slategray; 25 | } 26 | ._1o6ek505 { 27 | color: white; 28 | } 29 | ._1o6ek506 { 30 | background-color: black; 31 | } 32 | body ._1o6ek507 { 33 | font-size: 24px; 34 | } 35 | ._1o6ek508 { 36 | color: white; 37 | } 38 | ._1o6ek509 { 39 | background-color: black; 40 | } 41 | body ._1o6ek50a { 42 | font-size: 24px; 43 | } 44 | @media screen and (min-width: 700px) { 45 | ._1o6ek500 { 46 | color: plum; 47 | } 48 | ._1o6ek500:after { 49 | content: "Above 700px"; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /tests/e2e/features.playwright.ts-snapshots/features-esbuild-next--production.css: -------------------------------------------------------------------------------- 1 | ._1o6ek500 { 2 | height: 50px; 3 | } 4 | ._1o6ek500:after { 5 | content: "Below 700px"; 6 | display: block; 7 | } 8 | ._1o6ek501 { 9 | background-color: powderblue; 10 | } 11 | ._1o6ek501:hover { 12 | background-color: slategray; 13 | } 14 | ._1o6ek502 { 15 | background-color: powderblue; 16 | } 17 | ._1o6ek502:hover { 18 | background-color: slategray; 19 | } 20 | ._1o6ek503 { 21 | background-color: powderblue; 22 | } 23 | ._1o6ek503:hover { 24 | background-color: slategray; 25 | } 26 | ._1o6ek505 { 27 | color: white; 28 | } 29 | ._1o6ek506 { 30 | background-color: black; 31 | } 32 | body ._1o6ek507 { 33 | font-size: 24px; 34 | } 35 | ._1o6ek508 { 36 | color: white; 37 | } 38 | ._1o6ek509 { 39 | background-color: black; 40 | } 41 | body ._1o6ek50a { 42 | font-size: 24px; 43 | } 44 | @media screen and (min-width: 700px) { 45 | ._1o6ek500 { 46 | color: plum; 47 | } 48 | ._1o6ek500:after { 49 | content: "Above 700px"; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /tests/e2e/features.playwright.ts-snapshots/features-mini-css-extract--production.css: -------------------------------------------------------------------------------- 1 | ._87f2ru0 { 2 | height: 50px; 3 | } 4 | ._87f2ru0:after { 5 | content: "Below 700px"; 6 | display: block; 7 | } 8 | ._87f2ru1 { 9 | background-color: powderblue; 10 | } 11 | ._87f2ru1:hover { 12 | background-color: slategray; 13 | } 14 | ._87f2ru2 { 15 | background-color: powderblue; 16 | } 17 | ._87f2ru2:hover { 18 | background-color: slategray; 19 | } 20 | ._87f2ru3 { 21 | background-color: powderblue; 22 | } 23 | ._87f2ru3:hover { 24 | background-color: slategray; 25 | } 26 | ._87f2ru5 { 27 | color: white; 28 | } 29 | ._87f2ru6 { 30 | background-color: black; 31 | } 32 | body ._87f2ru7 { 33 | font-size: 24px; 34 | } 35 | ._87f2ru8 { 36 | color: white; 37 | } 38 | ._87f2ru9 { 39 | background-color: black; 40 | } 41 | body ._87f2rua { 42 | font-size: 24px; 43 | } 44 | @media screen and (min-width: 700px) { 45 | ._87f2ru0 { 46 | color: plum; 47 | } 48 | ._87f2ru0:after { 49 | content: "Above 700px"; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /tests/e2e/features.playwright.ts-snapshots/features-parcel--production.css: -------------------------------------------------------------------------------- 1 | ._87f2ru0 { 2 | height: 50px; 3 | } 4 | ._87f2ru0:after { 5 | content: "Below 700px"; 6 | display: block; 7 | } 8 | ._87f2ru1 { 9 | background-color: #b0e0e6; 10 | } 11 | ._87f2ru1:hover { 12 | background-color: #708090; 13 | } 14 | ._87f2ru2 { 15 | background-color: #b0e0e6; 16 | } 17 | ._87f2ru2:hover { 18 | background-color: #708090; 19 | } 20 | ._87f2ru3 { 21 | background-color: #b0e0e6; 22 | } 23 | ._87f2ru3:hover { 24 | background-color: #708090; 25 | } 26 | ._87f2ru5 { 27 | color: #fff; 28 | } 29 | ._87f2ru6 { 30 | background-color: #000; 31 | } 32 | body ._87f2ru7 { 33 | font-size: 24px; 34 | } 35 | ._87f2ru8 { 36 | color: #fff; 37 | } 38 | ._87f2ru9 { 39 | background-color: #000; 40 | } 41 | body ._87f2rua { 42 | font-size: 24px; 43 | } 44 | @media screen and (min-width: 700px) { 45 | ._87f2ru0 { 46 | color: plum; 47 | } 48 | ._87f2ru0:after { 49 | content: "Above 700px"; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /tests/e2e/features.playwright.ts-snapshots/features-vite--production.css: -------------------------------------------------------------------------------- 1 | ._1o6ek500 { 2 | height: 50px; 3 | } 4 | ._1o6ek500:after { 5 | content: "Below 700px"; 6 | display: block; 7 | } 8 | ._1o6ek501 { 9 | background-color: powderblue; 10 | } 11 | ._1o6ek501:hover { 12 | background-color: slategray; 13 | } 14 | ._1o6ek502 { 15 | background-color: powderblue; 16 | } 17 | ._1o6ek502:hover { 18 | background-color: slategray; 19 | } 20 | ._1o6ek503 { 21 | background-color: powderblue; 22 | } 23 | ._1o6ek503:hover { 24 | background-color: slategray; 25 | } 26 | ._1o6ek505 { 27 | color: white; 28 | } 29 | ._1o6ek506 { 30 | background-color: black; 31 | } 32 | body ._1o6ek507 { 33 | font-size: 24px; 34 | } 35 | ._1o6ek508 { 36 | color: white; 37 | } 38 | ._1o6ek509 { 39 | background-color: black; 40 | } 41 | body ._1o6ek50a { 42 | font-size: 24px; 43 | } 44 | @media screen and (min-width: 700px) { 45 | ._1o6ek500 { 46 | color: plum; 47 | } 48 | ._1o6ek500:after { 49 | content: "Above 700px"; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /tests/e2e/fixture.ts: -------------------------------------------------------------------------------- 1 | import { test as base } from '@playwright/test'; 2 | 3 | type TestFixtures = { 4 | port: number; 5 | }; 6 | 7 | let testCounter = 0; 8 | 9 | const test = base.extend({ 10 | port: async ({}, use, workerInfo) => { 11 | const portRange = 100 * workerInfo.workerIndex; 12 | await use(9000 + portRange + testCounter++); 13 | }, 14 | }); 15 | 16 | export default test; 17 | -------------------------------------------------------------------------------- /tests/e2e/fixtures-next-production.playwright.ts: -------------------------------------------------------------------------------- 1 | import { 2 | nextFixtures, 3 | startFixture, 4 | type TestServer, 5 | } from '@vanilla-extract-private/test-helpers'; 6 | import { expect } from '@playwright/test'; 7 | 8 | import test from './fixture'; 9 | 10 | const testCases = [ 11 | { 12 | type: 'next-pages-router', 13 | mode: 'production', 14 | }, 15 | { 16 | type: 'next-app-router', 17 | mode: 'production', 18 | }, 19 | ] as const; 20 | 21 | testCases.forEach(({ type, mode }) => { 22 | test.describe.serial(`${type} (${mode})`, async () => { 23 | let server: TestServer; 24 | 25 | test.beforeAll(async ({ port }) => { 26 | server = await startFixture('', { 27 | type, 28 | basePort: port, 29 | mode, 30 | }); 31 | }); 32 | 33 | test(`screenshot`, async ({ page }) => { 34 | for await (const fixture of nextFixtures) { 35 | await page.goto(`${server.url}/${fixture}`); 36 | // make sure the fixture is visible 37 | await page.waitForSelector(`#${fixture}`, { state: 'attached' }); 38 | expect(await page.screenshot()).toMatchSnapshot(`${fixture}.png`); 39 | } 40 | }); 41 | 42 | test.afterAll(async () => { 43 | await server.close(); 44 | }); 45 | }); 46 | }); 47 | -------------------------------------------------------------------------------- /tests/e2e/layers.playwright.ts: -------------------------------------------------------------------------------- 1 | import { expect } from '@playwright/test'; 2 | import { 3 | getStylesheet, 4 | startFixture, 5 | type TestServer, 6 | } from '@vanilla-extract-private/test-helpers'; 7 | 8 | import test from './fixture'; 9 | import { all as testCases } from './testCases'; 10 | 11 | testCases.forEach(({ type, mode, snapshotCss = true }) => { 12 | test.describe(`layers - ${type} (${mode})`, () => { 13 | let server: TestServer; 14 | 15 | test.beforeAll(async ({ port }) => { 16 | server = await startFixture('layers', { 17 | type, 18 | mode, 19 | basePort: port, 20 | }); 21 | }); 22 | 23 | test('screenshot', async ({ page }) => { 24 | await page.goto(server.url); 25 | 26 | expect(await page.screenshot()).toMatchSnapshot('layers.png'); 27 | }); 28 | 29 | if (snapshotCss) { 30 | test('CSS @agnostic', async () => { 31 | expect( 32 | await getStylesheet(server.url, server.stylesheet), 33 | ).toMatchSnapshot(`layers-${type}--${mode}.css`); 34 | }); 35 | } 36 | 37 | test.afterAll(async () => { 38 | await server.close(); 39 | }); 40 | }); 41 | }); 42 | -------------------------------------------------------------------------------- /tests/e2e/layers.playwright.ts-snapshots/layers-esbuild--development.css: -------------------------------------------------------------------------------- 1 | @layer lib; 2 | @layer lib.styles_base__1sqkzjx0; 3 | @media screen and (min-width: 600px) { 4 | @layer typography; 5 | } 6 | @layer lib.styles_utilities__1sqkzjx2; 7 | @layer typography; 8 | @layer lib.styles_base__1sqkzjx0 { 9 | a { 10 | font-weight: 800; 11 | color: red; 12 | } 13 | .styles_link__1sqkzjx1 { 14 | color: blue; 15 | } 16 | } 17 | @media screen and (min-width: 600px) { 18 | @layer typography { 19 | a { 20 | color: green; 21 | font-size: 1.5rem; 22 | } 23 | } 24 | } 25 | @layer lib.styles_utilities__1sqkzjx2 { 26 | .styles_pink__1sqkzjx3 { 27 | color: hotpink; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tests/e2e/layers.playwright.ts-snapshots/layers-esbuild--production.css: -------------------------------------------------------------------------------- 1 | @layer lib; 2 | @layer lib._1sqkzjx0; 3 | @media screen and (min-width: 600px) { 4 | @layer typography; 5 | } 6 | @layer lib._1sqkzjx2; 7 | @layer typography; 8 | @layer lib._1sqkzjx0 { 9 | a { 10 | font-weight: 800; 11 | color: red; 12 | } 13 | ._1sqkzjx1 { 14 | color: blue; 15 | } 16 | } 17 | @media screen and (min-width: 600px) { 18 | @layer typography { 19 | a { 20 | color: green; 21 | font-size: 1.5rem; 22 | } 23 | } 24 | } 25 | @layer lib._1sqkzjx2 { 26 | ._1sqkzjx3 { 27 | color: hotpink; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tests/e2e/layers.playwright.ts-snapshots/layers-esbuild-next--development.css: -------------------------------------------------------------------------------- 1 | @layer lib; 2 | @layer lib.styles_base__1sqkzjx0; 3 | @media screen and (min-width: 600px) { 4 | @layer typography; 5 | } 6 | @layer lib.styles_utilities__1sqkzjx2; 7 | @layer typography; 8 | @layer lib.styles_base__1sqkzjx0 { 9 | a { 10 | font-weight: 800; 11 | color: red; 12 | } 13 | .styles_link__1sqkzjx1 { 14 | color: blue; 15 | } 16 | } 17 | @media screen and (min-width: 600px) { 18 | @layer typography { 19 | a { 20 | color: green; 21 | font-size: 1.5rem; 22 | } 23 | } 24 | } 25 | @layer lib.styles_utilities__1sqkzjx2 { 26 | .styles_pink__1sqkzjx3 { 27 | color: hotpink; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tests/e2e/layers.playwright.ts-snapshots/layers-esbuild-next--production.css: -------------------------------------------------------------------------------- 1 | @layer lib; 2 | @layer lib._1sqkzjx0; 3 | @media screen and (min-width: 600px) { 4 | @layer typography; 5 | } 6 | @layer lib._1sqkzjx2; 7 | @layer typography; 8 | @layer lib._1sqkzjx0 { 9 | a { 10 | font-weight: 800; 11 | color: red; 12 | } 13 | ._1sqkzjx1 { 14 | color: blue; 15 | } 16 | } 17 | @media screen and (min-width: 600px) { 18 | @layer typography { 19 | a { 20 | color: green; 21 | font-size: 1.5rem; 22 | } 23 | } 24 | } 25 | @layer lib._1sqkzjx2 { 26 | ._1sqkzjx3 { 27 | color: hotpink; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tests/e2e/layers.playwright.ts-snapshots/layers-mini-css-extract--development.css: -------------------------------------------------------------------------------- 1 | @layer lib; 2 | @layer lib.styles_base__18onbx40; 3 | @media screen and (min-width: 600px) { 4 | @layer typography; 5 | } 6 | @layer lib.styles_utilities__18onbx42; 7 | @layer typography; 8 | @layer lib.styles_base__18onbx40 { 9 | a { 10 | font-weight: 800; 11 | color: red; 12 | } 13 | .styles_link__18onbx41 { 14 | color: blue; 15 | } 16 | } 17 | @media screen and (min-width: 600px) { 18 | @layer typography { 19 | a { 20 | color: green; 21 | font-size: 1.5rem; 22 | } 23 | } 24 | } 25 | @layer lib.styles_utilities__18onbx42 { 26 | .styles_pink__18onbx43 { 27 | color: hotpink; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tests/e2e/layers.playwright.ts-snapshots/layers-mini-css-extract--production.css: -------------------------------------------------------------------------------- 1 | @layer lib; 2 | @layer lib._18onbx40; 3 | @media screen and (min-width: 600px) { 4 | @layer typography; 5 | } 6 | @layer lib._18onbx42; 7 | @layer typography; 8 | @layer lib._18onbx40 { 9 | a { 10 | font-weight: 800; 11 | color: red; 12 | } 13 | ._18onbx41 { 14 | color: blue; 15 | } 16 | } 17 | @media screen and (min-width: 600px) { 18 | @layer typography { 19 | a { 20 | color: green; 21 | font-size: 1.5rem; 22 | } 23 | } 24 | } 25 | @layer lib._18onbx42 { 26 | ._18onbx43 { 27 | color: hotpink; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tests/e2e/layers.playwright.ts-snapshots/layers-parcel--development.css: -------------------------------------------------------------------------------- 1 | @layer lib; 2 | @layer lib.styles_base__18onbx40; 3 | @media screen and (min-width: 600px) { 4 | @layer typography; 5 | } 6 | @layer lib.styles_utilities__18onbx42; 7 | @layer typography; 8 | @layer lib.styles_base__18onbx40 { 9 | a { 10 | color: red; 11 | font-weight: 800; 12 | } 13 | .styles_link__18onbx41 { 14 | color: #00f; 15 | } 16 | } 17 | @media screen and (min-width: 600px) { 18 | @layer typography { 19 | a { 20 | color: green; 21 | font-size: 1.5rem; 22 | } 23 | } 24 | } 25 | @layer lib.styles_utilities__18onbx42 { 26 | .styles_pink__18onbx43 { 27 | color: #ff69b4; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tests/e2e/layers.playwright.ts-snapshots/layers-parcel--production.css: -------------------------------------------------------------------------------- 1 | @layer lib; 2 | @layer lib._18onbx40; 3 | @media screen and (min-width: 600px) { 4 | @layer typography; 5 | } 6 | @layer lib._18onbx42; 7 | @layer typography; 8 | @layer lib._18onbx40 { 9 | a { 10 | color: red; 11 | font-weight: 800; 12 | } 13 | ._18onbx41 { 14 | color: #00f; 15 | } 16 | } 17 | @media screen and (min-width: 600px) { 18 | @layer typography { 19 | a { 20 | color: green; 21 | font-size: 1.5rem; 22 | } 23 | } 24 | } 25 | @layer lib._18onbx42 { 26 | ._18onbx43 { 27 | color: #ff69b4; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tests/e2e/layers.playwright.ts-snapshots/layers-vite--production.css: -------------------------------------------------------------------------------- 1 | @layer lib; 2 | @layer lib._1sqkzjx0; 3 | @media screen and (min-width: 600px) { 4 | @layer typography; 5 | } 6 | @layer lib._1sqkzjx2; 7 | @layer typography; 8 | @layer lib._1sqkzjx0 { 9 | a { 10 | font-weight: 800; 11 | color: red; 12 | } 13 | ._1sqkzjx1 { 14 | color: blue; 15 | } 16 | } 17 | @media screen and (min-width: 600px) { 18 | @layer typography { 19 | a { 20 | color: green; 21 | font-size: 1.5rem; 22 | } 23 | } 24 | } 25 | @layer lib._1sqkzjx2 { 26 | ._1sqkzjx3 { 27 | color: hotpink; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tests/e2e/low-level.playwright.ts: -------------------------------------------------------------------------------- 1 | import { expect } from '@playwright/test'; 2 | import { 3 | getStylesheet, 4 | startFixture, 5 | type TestServer, 6 | } from '@vanilla-extract-private/test-helpers'; 7 | 8 | import test from './fixture'; 9 | import { all as testCases } from './testCases'; 10 | 11 | testCases.forEach(({ type, mode, snapshotCss = true }) => { 12 | test.describe(`low-level - ${type} (${mode})`, () => { 13 | let server: TestServer; 14 | 15 | test.beforeAll(async ({ port }) => { 16 | server = await startFixture('low-level', { 17 | type, 18 | mode, 19 | basePort: port, 20 | }); 21 | }); 22 | 23 | test('screenshot', async ({ page }) => { 24 | await page.goto(server.url); 25 | 26 | expect(await page.screenshot()).toMatchSnapshot('low-level.png'); 27 | }); 28 | 29 | if (snapshotCss) { 30 | test('CSS @agnostic', async () => { 31 | expect( 32 | await getStylesheet(server.url, server.stylesheet), 33 | ).toMatchSnapshot(`low-level-${type}--${mode}.css`); 34 | }); 35 | } 36 | 37 | test.afterAll(async () => { 38 | await server.close(); 39 | }); 40 | }); 41 | }); 42 | -------------------------------------------------------------------------------- /tests/e2e/low-level.playwright.ts-snapshots/low-level-esbuild--development.css: -------------------------------------------------------------------------------- 1 | .styles_container__1amv5mo2 { 2 | container-type: size; 3 | container-name: styles_my-container__1amv5mo1; 4 | width: 500px; 5 | } 6 | .styles_block__1amv5mo3 { 7 | --color__1amv5mo0: blue; 8 | background-color: var(--color__1amv5mo0); 9 | padding: 20px; 10 | } 11 | @media screen and (min-width: 200px) { 12 | @container styles_my-container__1amv5mo1 (min-width: 400px) { 13 | .styles_block__1amv5mo3 { 14 | color: white; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/e2e/low-level.playwright.ts-snapshots/low-level-esbuild--production.css: -------------------------------------------------------------------------------- 1 | ._1amv5mo2 { 2 | container-type: size; 3 | container-name: _1amv5mo1; 4 | width: 500px; 5 | } 6 | ._1amv5mo3 { 7 | --_1amv5mo0: blue; 8 | background-color: var(--_1amv5mo0); 9 | padding: 20px; 10 | } 11 | @media screen and (min-width: 200px) { 12 | @container _1amv5mo1 (min-width: 400px) { 13 | ._1amv5mo3 { 14 | color: white; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/e2e/low-level.playwright.ts-snapshots/low-level-esbuild-next--development.css: -------------------------------------------------------------------------------- 1 | .styles_container__1amv5mo2 { 2 | container-type: size; 3 | container-name: styles_my-container__1amv5mo1; 4 | width: 500px; 5 | } 6 | .styles_block__1amv5mo3 { 7 | --color__1amv5mo0: blue; 8 | background-color: var(--color__1amv5mo0); 9 | padding: 20px; 10 | } 11 | @media screen and (min-width: 200px) { 12 | @container styles_my-container__1amv5mo1 (min-width: 400px) { 13 | .styles_block__1amv5mo3 { 14 | color: white; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/e2e/low-level.playwright.ts-snapshots/low-level-esbuild-next--production.css: -------------------------------------------------------------------------------- 1 | ._1amv5mo2 { 2 | container-type: size; 3 | container-name: _1amv5mo1; 4 | width: 500px; 5 | } 6 | ._1amv5mo3 { 7 | --_1amv5mo0: blue; 8 | background-color: var(--_1amv5mo0); 9 | padding: 20px; 10 | } 11 | @media screen and (min-width: 200px) { 12 | @container _1amv5mo1 (min-width: 400px) { 13 | ._1amv5mo3 { 14 | color: white; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/e2e/low-level.playwright.ts-snapshots/low-level-mini-css-extract--development.css: -------------------------------------------------------------------------------- 1 | .styles_container__cj5d032 { 2 | container-type: size; 3 | container-name: styles_my-container__cj5d031; 4 | width: 500px; 5 | } 6 | .styles_block__cj5d033 { 7 | --color__cj5d030: blue; 8 | background-color: var(--color__cj5d030); 9 | padding: 20px; 10 | } 11 | @media screen and (min-width: 200px) { 12 | @container styles_my-container__cj5d031 (min-width: 400px) { 13 | .styles_block__cj5d033 { 14 | color: white; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/e2e/low-level.playwright.ts-snapshots/low-level-mini-css-extract--production.css: -------------------------------------------------------------------------------- 1 | .cj5d032 { 2 | container-type: size; 3 | container-name: cj5d031; 4 | width: 500px; 5 | } 6 | .cj5d033 { 7 | --cj5d030: blue; 8 | background-color: var(--cj5d030); 9 | padding: 20px; 10 | } 11 | @media screen and (min-width: 200px) { 12 | @container cj5d031 (min-width: 400px) { 13 | .cj5d033 { 14 | color: white; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/e2e/low-level.playwright.ts-snapshots/low-level-parcel--development.css: -------------------------------------------------------------------------------- 1 | .styles_container__cj5d032 { 2 | width: 500px; 3 | container: styles_my-container__cj5d031/size; 4 | } 5 | .styles_block__cj5d033 { 6 | --color__cj5d030: blue; 7 | background-color: var(--color__cj5d030); 8 | padding: 20px; 9 | } 10 | @media screen and (min-width: 200px) { 11 | @container styles_my-container__cj5d031 (min-width: 400px) { 12 | .styles_block__cj5d033 { 13 | color: #fff; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/e2e/low-level.playwright.ts-snapshots/low-level-parcel--production.css: -------------------------------------------------------------------------------- 1 | .cj5d032 { 2 | width: 500px; 3 | container: cj5d031/size; 4 | } 5 | .cj5d033 { 6 | --cj5d030: blue; 7 | background-color: var(--cj5d030); 8 | padding: 20px; 9 | } 10 | @media screen and (min-width: 200px) { 11 | @container cj5d031 (min-width: 400px) { 12 | .cj5d033 { 13 | color: #fff; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/e2e/low-level.playwright.ts-snapshots/low-level-vite--production.css: -------------------------------------------------------------------------------- 1 | ._1amv5mo2 { 2 | container-type: size; 3 | container-name: _1amv5mo1; 4 | width: 500px; 5 | } 6 | ._1amv5mo3 { 7 | --_1amv5mo0: blue; 8 | background-color: var(--_1amv5mo0); 9 | padding: 20px; 10 | } 11 | @media screen and (min-width: 200px) { 12 | @container _1amv5mo1 (min-width: 400px) { 13 | ._1amv5mo3 { 14 | color: white; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/e2e/recipes.playwright.ts: -------------------------------------------------------------------------------- 1 | import { expect } from '@playwright/test'; 2 | import { 3 | getStylesheet, 4 | startFixture, 5 | type TestServer, 6 | } from '@vanilla-extract-private/test-helpers'; 7 | 8 | import test from './fixture'; 9 | import { all as testCases } from './testCases'; 10 | 11 | testCases.forEach(({ type, mode, snapshotCss = true }) => { 12 | test.describe(`recipes - ${type} (${mode})`, () => { 13 | let server: TestServer; 14 | 15 | test.beforeAll(async ({ port }) => { 16 | server = await startFixture('recipes', { 17 | type, 18 | mode, 19 | basePort: port, 20 | }); 21 | }); 22 | 23 | test('screenshot', async ({ page }) => { 24 | await page.goto(server.url); 25 | 26 | expect(await page.screenshot()).toMatchSnapshot('recipes.png'); 27 | }); 28 | 29 | if (snapshotCss) { 30 | test('CSS @agnostic', async () => { 31 | expect( 32 | await getStylesheet(server.url, server.stylesheet), 33 | ).toMatchSnapshot(`recipes-${type}--${mode}.css`); 34 | }); 35 | } 36 | 37 | test.afterAll(async () => { 38 | await server.close(); 39 | }); 40 | }); 41 | }); 42 | -------------------------------------------------------------------------------- /tests/e2e/recipes.playwright.ts-snapshots/recipes-esbuild--development.css: -------------------------------------------------------------------------------- 1 | .styles_calm__103pmpm2 { 2 | --bg__103pmpm0: powderblue; 3 | --fg__103pmpm1: white; 4 | } 5 | .styles_angry__103pmpm3 { 6 | --bg__103pmpm0: crimson; 7 | --fg__103pmpm1: black; 8 | } 9 | .styles_reset__103pmpm4 { 10 | border: 0; 11 | } 12 | .styles_button__103pmpm5 { 13 | border-radius: 6px; 14 | background: var(--bg__103pmpm0); 15 | color: var(--fg__103pmpm1); 16 | transition: all 0.2s ease; 17 | } 18 | .styles_button__103pmpm5:hover { 19 | transform: translateY(-3px); 20 | } 21 | .styles_button_size_small__103pmpm6 { 22 | font-size: 16px; 23 | line-height: 24px; 24 | } 25 | .styles_button_size_standard__103pmpm7 { 26 | font-size: 24px; 27 | line-height: 40px; 28 | } 29 | .styles_button_tone_angry__103pmpm9:hover { 30 | box-shadow: 0 10px 6px -6px #777; 31 | } 32 | .styles_button_bold_true__103pmpma { 33 | font-weight: bold; 34 | } 35 | .styles_stack__103pmpmc { 36 | display: flex; 37 | flex-direction: column; 38 | align-items: flex-start; 39 | } 40 | .styles_stack_space_medium__103pmpmd { 41 | gap: 20px; 42 | } 43 | @media only screen and (min-width: 600px) { 44 | .styles_button_compound_0__103pmpmb { 45 | border: 2px green solid; 46 | } 47 | .styles_stack_space_medium__103pmpmd { 48 | gap: 30px; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /tests/e2e/recipes.playwright.ts-snapshots/recipes-esbuild--production.css: -------------------------------------------------------------------------------- 1 | ._103pmpm2 { 2 | --_103pmpm0: powderblue; 3 | --_103pmpm1: white; 4 | } 5 | ._103pmpm3 { 6 | --_103pmpm0: crimson; 7 | --_103pmpm1: black; 8 | } 9 | ._103pmpm4 { 10 | border: 0; 11 | } 12 | ._103pmpm5 { 13 | border-radius: 6px; 14 | background: var(--_103pmpm0); 15 | color: var(--_103pmpm1); 16 | transition: all 0.2s ease; 17 | } 18 | ._103pmpm5:hover { 19 | transform: translateY(-3px); 20 | } 21 | ._103pmpm6 { 22 | font-size: 16px; 23 | line-height: 24px; 24 | } 25 | ._103pmpm7 { 26 | font-size: 24px; 27 | line-height: 40px; 28 | } 29 | ._103pmpm9:hover { 30 | box-shadow: 0 10px 6px -6px #777; 31 | } 32 | ._103pmpma { 33 | font-weight: bold; 34 | } 35 | ._103pmpmc { 36 | display: flex; 37 | flex-direction: column; 38 | align-items: flex-start; 39 | } 40 | ._103pmpmd { 41 | gap: 20px; 42 | } 43 | @media only screen and (min-width: 600px) { 44 | ._103pmpmb { 45 | border: 2px green solid; 46 | } 47 | ._103pmpmd { 48 | gap: 30px; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /tests/e2e/recipes.playwright.ts-snapshots/recipes-esbuild-next--development.css: -------------------------------------------------------------------------------- 1 | .styles_calm__103pmpm2 { 2 | --bg__103pmpm0: powderblue; 3 | --fg__103pmpm1: white; 4 | } 5 | .styles_angry__103pmpm3 { 6 | --bg__103pmpm0: crimson; 7 | --fg__103pmpm1: black; 8 | } 9 | .styles_reset__103pmpm4 { 10 | border: 0; 11 | } 12 | .styles_button__103pmpm5 { 13 | border-radius: 6px; 14 | background: var(--bg__103pmpm0); 15 | color: var(--fg__103pmpm1); 16 | transition: all 0.2s ease; 17 | } 18 | .styles_button__103pmpm5:hover { 19 | transform: translateY(-3px); 20 | } 21 | .styles_button_size_small__103pmpm6 { 22 | font-size: 16px; 23 | line-height: 24px; 24 | } 25 | .styles_button_size_standard__103pmpm7 { 26 | font-size: 24px; 27 | line-height: 40px; 28 | } 29 | .styles_button_tone_angry__103pmpm9:hover { 30 | box-shadow: 0 10px 6px -6px #777; 31 | } 32 | .styles_button_bold_true__103pmpma { 33 | font-weight: bold; 34 | } 35 | .styles_stack__103pmpmc { 36 | display: flex; 37 | flex-direction: column; 38 | align-items: flex-start; 39 | } 40 | .styles_stack_space_medium__103pmpmd { 41 | gap: 20px; 42 | } 43 | @media only screen and (min-width: 600px) { 44 | .styles_button_compound_0__103pmpmb { 45 | border: 2px green solid; 46 | } 47 | .styles_stack_space_medium__103pmpmd { 48 | gap: 30px; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /tests/e2e/recipes.playwright.ts-snapshots/recipes-esbuild-next--production.css: -------------------------------------------------------------------------------- 1 | ._103pmpm2 { 2 | --_103pmpm0: powderblue; 3 | --_103pmpm1: white; 4 | } 5 | ._103pmpm3 { 6 | --_103pmpm0: crimson; 7 | --_103pmpm1: black; 8 | } 9 | ._103pmpm4 { 10 | border: 0; 11 | } 12 | ._103pmpm5 { 13 | border-radius: 6px; 14 | background: var(--_103pmpm0); 15 | color: var(--_103pmpm1); 16 | transition: all 0.2s ease; 17 | } 18 | ._103pmpm5:hover { 19 | transform: translateY(-3px); 20 | } 21 | ._103pmpm6 { 22 | font-size: 16px; 23 | line-height: 24px; 24 | } 25 | ._103pmpm7 { 26 | font-size: 24px; 27 | line-height: 40px; 28 | } 29 | ._103pmpm9:hover { 30 | box-shadow: 0 10px 6px -6px #777; 31 | } 32 | ._103pmpma { 33 | font-weight: bold; 34 | } 35 | ._103pmpmc { 36 | display: flex; 37 | flex-direction: column; 38 | align-items: flex-start; 39 | } 40 | ._103pmpmd { 41 | gap: 20px; 42 | } 43 | @media only screen and (min-width: 600px) { 44 | ._103pmpmb { 45 | border: 2px green solid; 46 | } 47 | ._103pmpmd { 48 | gap: 30px; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /tests/e2e/recipes.playwright.ts-snapshots/recipes-mini-css-extract--development.css: -------------------------------------------------------------------------------- 1 | .styles_calm__spi1fr2 { 2 | --bg__spi1fr0: powderblue; 3 | --fg__spi1fr1: white; 4 | } 5 | .styles_angry__spi1fr3 { 6 | --bg__spi1fr0: crimson; 7 | --fg__spi1fr1: black; 8 | } 9 | .styles_reset__spi1fr4 { 10 | border: 0; 11 | } 12 | .styles_button__spi1fr5 { 13 | border-radius: 6px; 14 | background: var(--bg__spi1fr0); 15 | color: var(--fg__spi1fr1); 16 | transition: all 0.2s ease; 17 | } 18 | .styles_button__spi1fr5:hover { 19 | transform: translateY(-3px); 20 | } 21 | .styles_button_size_small__spi1fr6 { 22 | font-size: 16px; 23 | line-height: 24px; 24 | } 25 | .styles_button_size_standard__spi1fr7 { 26 | font-size: 24px; 27 | line-height: 40px; 28 | } 29 | .styles_button_tone_angry__spi1fr9:hover { 30 | box-shadow: 0 10px 6px -6px #777; 31 | } 32 | .styles_button_bold_true__spi1fra { 33 | font-weight: bold; 34 | } 35 | .styles_stack__spi1frc { 36 | display: flex; 37 | flex-direction: column; 38 | align-items: flex-start; 39 | } 40 | .styles_stack_space_medium__spi1frd { 41 | gap: 20px; 42 | } 43 | @media only screen and (min-width: 600px) { 44 | .styles_button_compound_0__spi1frb { 45 | border: 2px green solid; 46 | } 47 | .styles_stack_space_medium__spi1frd { 48 | gap: 30px; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /tests/e2e/recipes.playwright.ts-snapshots/recipes-mini-css-extract--production.css: -------------------------------------------------------------------------------- 1 | .spi1fr2 { 2 | --spi1fr0: powderblue; 3 | --spi1fr1: white; 4 | } 5 | .spi1fr3 { 6 | --spi1fr0: crimson; 7 | --spi1fr1: black; 8 | } 9 | .spi1fr4 { 10 | border: 0; 11 | } 12 | .spi1fr5 { 13 | border-radius: 6px; 14 | background: var(--spi1fr0); 15 | color: var(--spi1fr1); 16 | transition: all 0.2s ease; 17 | } 18 | .spi1fr5:hover { 19 | transform: translateY(-3px); 20 | } 21 | .spi1fr6 { 22 | font-size: 16px; 23 | line-height: 24px; 24 | } 25 | .spi1fr7 { 26 | font-size: 24px; 27 | line-height: 40px; 28 | } 29 | .spi1fr9:hover { 30 | box-shadow: 0 10px 6px -6px #777; 31 | } 32 | .spi1fra { 33 | font-weight: bold; 34 | } 35 | .spi1frc { 36 | display: flex; 37 | flex-direction: column; 38 | align-items: flex-start; 39 | } 40 | .spi1frd { 41 | gap: 20px; 42 | } 43 | @media only screen and (min-width: 600px) { 44 | .spi1frb { 45 | border: 2px green solid; 46 | } 47 | .spi1frd { 48 | gap: 30px; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /tests/e2e/recipes.playwright.ts-snapshots/recipes-parcel--development.css: -------------------------------------------------------------------------------- 1 | .styles_calm__spi1fr2 { 2 | --bg__spi1fr0: powderblue; 3 | --fg__spi1fr1: white; 4 | } 5 | .styles_angry__spi1fr3 { 6 | --bg__spi1fr0: crimson; 7 | --fg__spi1fr1: black; 8 | } 9 | .styles_reset__spi1fr4 { 10 | border: 0; 11 | } 12 | .styles_button__spi1fr5 { 13 | background: var(--bg__spi1fr0); 14 | color: var(--fg__spi1fr1); 15 | border-radius: 6px; 16 | transition: all 0.2s; 17 | } 18 | .styles_button__spi1fr5:hover { 19 | transform: translateY(-3px); 20 | } 21 | .styles_button_size_small__spi1fr6 { 22 | font-size: 16px; 23 | line-height: 24px; 24 | } 25 | .styles_button_size_standard__spi1fr7 { 26 | font-size: 24px; 27 | line-height: 40px; 28 | } 29 | .styles_button_tone_angry__spi1fr9:hover { 30 | box-shadow: 0 10px 6px -6px #777; 31 | } 32 | .styles_button_bold_true__spi1fra { 33 | font-weight: bold; 34 | } 35 | .styles_stack__spi1frc { 36 | flex-direction: column; 37 | align-items: flex-start; 38 | display: flex; 39 | } 40 | .styles_stack_space_medium__spi1frd { 41 | gap: 20px; 42 | } 43 | @media only screen and (min-width: 600px) { 44 | .styles_button_compound_0__spi1frb { 45 | border: 2px solid green; 46 | } 47 | .styles_stack_space_medium__spi1frd { 48 | gap: 30px; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /tests/e2e/recipes.playwright.ts-snapshots/recipes-parcel--production.css: -------------------------------------------------------------------------------- 1 | .spi1fr2 { 2 | --spi1fr0: powderblue; 3 | --spi1fr1: white; 4 | } 5 | .spi1fr3 { 6 | --spi1fr0: crimson; 7 | --spi1fr1: black; 8 | } 9 | .spi1fr4 { 10 | border: 0; 11 | } 12 | .spi1fr5 { 13 | background: var(--spi1fr0); 14 | color: var(--spi1fr1); 15 | border-radius: 6px; 16 | transition: all 0.2s; 17 | } 18 | .spi1fr5:hover { 19 | transform: translateY(-3px); 20 | } 21 | .spi1fr6 { 22 | font-size: 16px; 23 | line-height: 24px; 24 | } 25 | .spi1fr7 { 26 | font-size: 24px; 27 | line-height: 40px; 28 | } 29 | .spi1fr9:hover { 30 | box-shadow: 0 10px 6px -6px #777; 31 | } 32 | .spi1fra { 33 | font-weight: bold; 34 | } 35 | .spi1frc { 36 | flex-direction: column; 37 | align-items: flex-start; 38 | display: flex; 39 | } 40 | .spi1frd { 41 | gap: 20px; 42 | } 43 | @media only screen and (min-width: 600px) { 44 | .spi1frb { 45 | border: 2px solid green; 46 | } 47 | .spi1frd { 48 | gap: 30px; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /tests/e2e/recipes.playwright.ts-snapshots/recipes-vite--production.css: -------------------------------------------------------------------------------- 1 | ._103pmpm2 { 2 | --_103pmpm0: powderblue; 3 | --_103pmpm1: white; 4 | } 5 | ._103pmpm3 { 6 | --_103pmpm0: crimson; 7 | --_103pmpm1: black; 8 | } 9 | ._103pmpm4 { 10 | border: 0; 11 | } 12 | ._103pmpm5 { 13 | border-radius: 6px; 14 | background: var(--_103pmpm0); 15 | color: var(--_103pmpm1); 16 | transition: all 0.2s ease; 17 | } 18 | ._103pmpm5:hover { 19 | transform: translateY(-3px); 20 | } 21 | ._103pmpm6 { 22 | font-size: 16px; 23 | line-height: 24px; 24 | } 25 | ._103pmpm7 { 26 | font-size: 24px; 27 | line-height: 40px; 28 | } 29 | ._103pmpm9:hover { 30 | box-shadow: 0 10px 6px -6px #777; 31 | } 32 | ._103pmpma { 33 | font-weight: bold; 34 | } 35 | ._103pmpmc { 36 | display: flex; 37 | flex-direction: column; 38 | align-items: flex-start; 39 | } 40 | ._103pmpmd { 41 | gap: 20px; 42 | } 43 | @media only screen and (min-width: 600px) { 44 | ._103pmpmb { 45 | border: 2px green solid; 46 | } 47 | ._103pmpmd { 48 | gap: 30px; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /tests/e2e/snapshots/features-Desktop---Chromium-darwin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanilla-extract-css/vanilla-extract/7efce3a9e733f4a5cc1322541d6e7774ea2d2df0/tests/e2e/snapshots/features-Desktop---Chromium-darwin.png -------------------------------------------------------------------------------- /tests/e2e/snapshots/features-Mobile---Chromium-darwin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanilla-extract-css/vanilla-extract/7efce3a9e733f4a5cc1322541d6e7774ea2d2df0/tests/e2e/snapshots/features-Mobile---Chromium-darwin.png -------------------------------------------------------------------------------- /tests/e2e/snapshots/layers-Desktop---Chromium-darwin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanilla-extract-css/vanilla-extract/7efce3a9e733f4a5cc1322541d6e7774ea2d2df0/tests/e2e/snapshots/layers-Desktop---Chromium-darwin.png -------------------------------------------------------------------------------- /tests/e2e/snapshots/layers-Mobile---Chromium-darwin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanilla-extract-css/vanilla-extract/7efce3a9e733f4a5cc1322541d6e7774ea2d2df0/tests/e2e/snapshots/layers-Mobile---Chromium-darwin.png -------------------------------------------------------------------------------- /tests/e2e/snapshots/low-level-Desktop---Chromium-darwin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanilla-extract-css/vanilla-extract/7efce3a9e733f4a5cc1322541d6e7774ea2d2df0/tests/e2e/snapshots/low-level-Desktop---Chromium-darwin.png -------------------------------------------------------------------------------- /tests/e2e/snapshots/low-level-Mobile---Chromium-darwin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanilla-extract-css/vanilla-extract/7efce3a9e733f4a5cc1322541d6e7774ea2d2df0/tests/e2e/snapshots/low-level-Mobile---Chromium-darwin.png -------------------------------------------------------------------------------- /tests/e2e/snapshots/recipes-Desktop---Chromium-darwin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanilla-extract-css/vanilla-extract/7efce3a9e733f4a5cc1322541d6e7774ea2d2df0/tests/e2e/snapshots/recipes-Desktop---Chromium-darwin.png -------------------------------------------------------------------------------- /tests/e2e/snapshots/recipes-Mobile---Chromium-darwin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanilla-extract-css/vanilla-extract/7efce3a9e733f4a5cc1322541d6e7774ea2d2df0/tests/e2e/snapshots/recipes-Mobile---Chromium-darwin.png -------------------------------------------------------------------------------- /tests/e2e/snapshots/sprinkles-Desktop---Chromium-darwin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanilla-extract-css/vanilla-extract/7efce3a9e733f4a5cc1322541d6e7774ea2d2df0/tests/e2e/snapshots/sprinkles-Desktop---Chromium-darwin.png -------------------------------------------------------------------------------- /tests/e2e/snapshots/sprinkles-Mobile---Chromium-darwin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanilla-extract-css/vanilla-extract/7efce3a9e733f4a5cc1322541d6e7774ea2d2df0/tests/e2e/snapshots/sprinkles-Mobile---Chromium-darwin.png -------------------------------------------------------------------------------- /tests/e2e/snapshots/template-string-paths-Desktop---Chromium-darwin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanilla-extract-css/vanilla-extract/7efce3a9e733f4a5cc1322541d6e7774ea2d2df0/tests/e2e/snapshots/template-string-paths-Desktop---Chromium-darwin.png -------------------------------------------------------------------------------- /tests/e2e/snapshots/template-string-paths-Mobile---Chromium-darwin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanilla-extract-css/vanilla-extract/7efce3a9e733f4a5cc1322541d6e7774ea2d2df0/tests/e2e/snapshots/template-string-paths-Mobile---Chromium-darwin.png -------------------------------------------------------------------------------- /tests/e2e/snapshots/themed-Desktop---Chromium-darwin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanilla-extract-css/vanilla-extract/7efce3a9e733f4a5cc1322541d6e7774ea2d2df0/tests/e2e/snapshots/themed-Desktop---Chromium-darwin.png -------------------------------------------------------------------------------- /tests/e2e/snapshots/themed-Mobile---Chromium-darwin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanilla-extract-css/vanilla-extract/7efce3a9e733f4a5cc1322541d6e7774ea2d2df0/tests/e2e/snapshots/themed-Mobile---Chromium-darwin.png -------------------------------------------------------------------------------- /tests/e2e/snapshots/thirdparty-Desktop---Chromium-darwin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanilla-extract-css/vanilla-extract/7efce3a9e733f4a5cc1322541d6e7774ea2d2df0/tests/e2e/snapshots/thirdparty-Desktop---Chromium-darwin.png -------------------------------------------------------------------------------- /tests/e2e/snapshots/thirdparty-Mobile---Chromium-darwin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanilla-extract-css/vanilla-extract/7efce3a9e733f4a5cc1322541d6e7774ea2d2df0/tests/e2e/snapshots/thirdparty-Mobile---Chromium-darwin.png -------------------------------------------------------------------------------- /tests/e2e/sprinkles.playwright.ts: -------------------------------------------------------------------------------- 1 | import { expect } from '@playwright/test'; 2 | import { 3 | getStylesheet, 4 | startFixture, 5 | type TestServer, 6 | } from '@vanilla-extract-private/test-helpers'; 7 | 8 | import test from './fixture'; 9 | import { all as testCases } from './testCases'; 10 | 11 | testCases.forEach(({ type, mode, snapshotCss = true }) => { 12 | test.describe(`sprinkles - ${type} (${mode})`, () => { 13 | let server: TestServer; 14 | 15 | test.beforeAll(async ({ port }) => { 16 | server = await startFixture('sprinkles', { 17 | type, 18 | mode, 19 | basePort: port, 20 | }); 21 | }); 22 | 23 | test('screenshot', async ({ page }) => { 24 | await page.goto(server.url); 25 | 26 | expect(await page.screenshot()).toMatchSnapshot('sprinkles.png'); 27 | }); 28 | 29 | if (snapshotCss) { 30 | test('CSS @agnostic', async () => { 31 | expect( 32 | await getStylesheet(server.url, server.stylesheet), 33 | ).toMatchSnapshot(`sprinkles-${type}--${mode}.css`); 34 | }); 35 | } 36 | 37 | test.afterAll(async () => { 38 | await server.close(); 39 | }); 40 | }); 41 | }); 42 | -------------------------------------------------------------------------------- /tests/e2e/template-string-paths.playwright.ts: -------------------------------------------------------------------------------- 1 | import { expect } from '@playwright/test'; 2 | import { 3 | getStylesheet, 4 | startFixture, 5 | type TestServer, 6 | } from '@vanilla-extract-private/test-helpers'; 7 | 8 | import test from './fixture'; 9 | import { webpack as testCases } from './testCases'; 10 | 11 | testCases.forEach(({ type, mode, snapshotCss = true }) => { 12 | test.describe(`template-string-paths - ${type} (${mode})`, () => { 13 | let server: TestServer; 14 | 15 | test.beforeAll(async ({ port }) => { 16 | server = await startFixture('template-string-paths', { 17 | type, 18 | mode, 19 | basePort: port, 20 | }); 21 | }); 22 | 23 | test('screenshot', async ({ page }) => { 24 | await page.goto(server.url); 25 | 26 | expect(await page.screenshot()).toMatchSnapshot( 27 | 'template-string-paths.png', 28 | ); 29 | }); 30 | 31 | if (snapshotCss) { 32 | test('CSS @agnostic', async () => { 33 | expect( 34 | await getStylesheet(server.url, server.stylesheet), 35 | ).toMatchSnapshot(`template-string-paths-${type}--${mode}.css`); 36 | }); 37 | } 38 | 39 | test.afterAll(async () => { 40 | await server.close(); 41 | }); 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /tests/e2e/template-string-paths.playwright.ts-snapshots/template-string-paths-mini-css-extract--development.css: -------------------------------------------------------------------------------- 1 | .\[\]_emptySquareBrackets__13abg9g0 { 2 | color: blue; 3 | } 4 | .\[id\]_singleSquareBracketsId__1d2wsrw0 { 5 | color: tomato; 6 | } 7 | .\[\[id\]\]_doubleSquareBracketId__1aosxxv0 { 8 | color: darkkhaki; 9 | } 10 | .\[\.\.\.slug\]_catchAllSegment__169etlp0 { 11 | color: lime; 12 | } 13 | .\[\[\.\.\.slug\]\]_optionalCatchAllSegment__1kvknas0 { 14 | color: orchid; 15 | } 16 | .\[blog-id\]_withHyphen__1e83mlh0 { 17 | color: indigo; 18 | } 19 | -------------------------------------------------------------------------------- /tests/e2e/template-string-paths.playwright.ts-snapshots/template-string-paths-mini-css-extract--production.css: -------------------------------------------------------------------------------- 1 | ._13abg9g0 { 2 | color: blue; 3 | } 4 | ._1d2wsrw0 { 5 | color: tomato; 6 | } 7 | ._1aosxxv0 { 8 | color: darkkhaki; 9 | } 10 | ._169etlp0 { 11 | color: lime; 12 | } 13 | ._1kvknas0 { 14 | color: orchid; 15 | } 16 | ._1e83mlh0 { 17 | color: indigo; 18 | } 19 | -------------------------------------------------------------------------------- /tests/e2e/testCases.ts: -------------------------------------------------------------------------------- 1 | export const webpack = [ 2 | { type: 'mini-css-extract', mode: 'development', snapshotCss: true }, 3 | { type: 'mini-css-extract', mode: 'production', snapshotCss: true }, 4 | { type: 'style-loader', mode: 'development', snapshotCss: false }, 5 | ] as const; 6 | 7 | export const all = [ 8 | ...webpack, 9 | { type: 'esbuild', mode: 'development', snapshotCss: true }, 10 | { type: 'esbuild', mode: 'production', snapshotCss: true }, 11 | { type: 'esbuild-runtime', mode: 'development', snapshotCss: false }, 12 | { type: 'esbuild-runtime', mode: 'production', snapshotCss: false }, 13 | { type: 'esbuild-next', mode: 'development', snapshotCss: true }, 14 | { type: 'esbuild-next', mode: 'production', snapshotCss: true }, 15 | { type: 'esbuild-next-runtime', mode: 'development', snapshotCss: false }, 16 | { type: 'esbuild-next-runtime', mode: 'production', snapshotCss: false }, 17 | { type: 'vite', mode: 'development', snapshotCss: false }, 18 | { type: 'vite', mode: 'production', snapshotCss: true }, 19 | { type: 'parcel', mode: 'development', snapshotCss: true }, 20 | { type: 'parcel', mode: 'production', snapshotCss: true }, 21 | ] as const; 22 | -------------------------------------------------------------------------------- /tests/e2e/themed.playwright.ts: -------------------------------------------------------------------------------- 1 | import { expect } from '@playwright/test'; 2 | import { 3 | getStylesheet, 4 | startFixture, 5 | type TestServer, 6 | } from '@vanilla-extract-private/test-helpers'; 7 | 8 | import test from './fixture'; 9 | import { all as testCases } from './testCases'; 10 | 11 | testCases.forEach(({ type, mode, snapshotCss = true }) => { 12 | test.describe(`themed - ${type} (${mode})`, () => { 13 | let server: TestServer; 14 | 15 | test.beforeAll(async ({ port }) => { 16 | server = await startFixture('themed', { 17 | type, 18 | mode, 19 | basePort: port, 20 | }); 21 | }); 22 | 23 | test('screenshot', async ({ page }) => { 24 | await page.goto(server.url); 25 | 26 | expect(await page.screenshot()).toMatchSnapshot('themed.png'); 27 | }); 28 | 29 | if (snapshotCss) { 30 | test('CSS @agnostic', async () => { 31 | expect( 32 | await getStylesheet(server.url, server.stylesheet), 33 | ).toMatchSnapshot(`themed-${type}--${mode}.css`); 34 | }); 35 | } 36 | 37 | test.afterAll(async () => { 38 | await server.close(); 39 | }); 40 | }); 41 | }); 42 | -------------------------------------------------------------------------------- /tests/e2e/thirdparty.playwright.ts: -------------------------------------------------------------------------------- 1 | import { expect } from '@playwright/test'; 2 | import { 3 | getStylesheet, 4 | startFixture, 5 | type TestServer, 6 | } from '@vanilla-extract-private/test-helpers'; 7 | 8 | import test from './fixture'; 9 | import { all as testCases } from './testCases'; 10 | 11 | testCases.forEach(({ type, mode, snapshotCss = true }) => { 12 | test.describe(`thirdparty - ${type} (${mode})`, () => { 13 | let server: TestServer; 14 | 15 | test.beforeAll(async ({ port }) => { 16 | server = await startFixture('thirdparty', { 17 | type, 18 | mode, 19 | basePort: port, 20 | }); 21 | }); 22 | 23 | test('screenshot', async ({ page }) => { 24 | await page.goto(server.url); 25 | 26 | expect(await page.screenshot()).toMatchSnapshot('thirdparty.png'); 27 | }); 28 | 29 | if (snapshotCss) { 30 | test('CSS @agnostic', async () => { 31 | expect( 32 | await getStylesheet(server.url, server.stylesheet), 33 | ).toMatchSnapshot(`thirdparty-${type}--${mode}.css`); 34 | }); 35 | } 36 | 37 | test.afterAll(async () => { 38 | await server.close(); 39 | }); 40 | }); 41 | }); 42 | -------------------------------------------------------------------------------- /tests/e2e/thirdparty.playwright.ts-snapshots/thirdparty-esbuild--development.css: -------------------------------------------------------------------------------- 1 | .styles_depBlock__vg1esd1 { 2 | --depColor__vg1esd0: green; 3 | background-color: var(--depColor__vg1esd0); 4 | } 5 | .styles_depdepBlock__7q0fkw1 { 6 | --depdepColor__7q0fkw0: blue; 7 | background-color: var(--depdepColor__7q0fkw0); 8 | } 9 | .styles_block__1vrxmse1 { 10 | --color__1vrxmse0: red; 11 | background-color: var(--color__1vrxmse0); 12 | } 13 | -------------------------------------------------------------------------------- /tests/e2e/thirdparty.playwright.ts-snapshots/thirdparty-esbuild--production.css: -------------------------------------------------------------------------------- 1 | .vg1esd1 { 2 | --vg1esd0: green; 3 | background-color: var(--vg1esd0); 4 | } 5 | ._7q0fkw1 { 6 | --_7q0fkw0: blue; 7 | background-color: var(--_7q0fkw0); 8 | } 9 | ._1vrxmse1 { 10 | --_1vrxmse0: red; 11 | background-color: var(--_1vrxmse0); 12 | } 13 | -------------------------------------------------------------------------------- /tests/e2e/thirdparty.playwright.ts-snapshots/thirdparty-esbuild-next--development.css: -------------------------------------------------------------------------------- 1 | .styles_depBlock__vg1esd1 { 2 | --depColor__vg1esd0: green; 3 | background-color: var(--depColor__vg1esd0); 4 | } 5 | .styles_depdepBlock__7q0fkw1 { 6 | --depdepColor__7q0fkw0: blue; 7 | background-color: var(--depdepColor__7q0fkw0); 8 | } 9 | .styles_block__1vrxmse1 { 10 | --color__1vrxmse0: red; 11 | background-color: var(--color__1vrxmse0); 12 | } 13 | -------------------------------------------------------------------------------- /tests/e2e/thirdparty.playwright.ts-snapshots/thirdparty-esbuild-next--production.css: -------------------------------------------------------------------------------- 1 | .vg1esd1 { 2 | --vg1esd0: green; 3 | background-color: var(--vg1esd0); 4 | } 5 | ._7q0fkw1 { 6 | --_7q0fkw0: blue; 7 | background-color: var(--_7q0fkw0); 8 | } 9 | ._1vrxmse1 { 10 | --_1vrxmse0: red; 11 | background-color: var(--_1vrxmse0); 12 | } 13 | -------------------------------------------------------------------------------- /tests/e2e/thirdparty.playwright.ts-snapshots/thirdparty-mini-css-extract--development.css: -------------------------------------------------------------------------------- 1 | .styles_depBlock__1diaba71 { 2 | --depColor__1diaba70: green; 3 | background-color: var(--depColor__1diaba70); 4 | } 5 | .styles_depdepBlock__rn5a421 { 6 | --depdepColor__rn5a420: blue; 7 | background-color: var(--depdepColor__rn5a420); 8 | } 9 | .styles_block__19mmd6u1 { 10 | --color__19mmd6u0: red; 11 | background-color: var(--color__19mmd6u0); 12 | } 13 | -------------------------------------------------------------------------------- /tests/e2e/thirdparty.playwright.ts-snapshots/thirdparty-mini-css-extract--production.css: -------------------------------------------------------------------------------- 1 | ._1diaba71 { 2 | --_1diaba70: green; 3 | background-color: var(--_1diaba70); 4 | } 5 | .rn5a421 { 6 | --rn5a420: blue; 7 | background-color: var(--rn5a420); 8 | } 9 | ._19mmd6u1 { 10 | --_19mmd6u0: red; 11 | background-color: var(--_19mmd6u0); 12 | } 13 | -------------------------------------------------------------------------------- /tests/e2e/thirdparty.playwright.ts-snapshots/thirdparty-parcel--development.css: -------------------------------------------------------------------------------- 1 | .styles_depBlock__1diaba71 { 2 | --depColor__1diaba70: green; 3 | background-color: var(--depColor__1diaba70); 4 | } 5 | .styles_depdepBlock__rn5a421 { 6 | --depdepColor__rn5a420: blue; 7 | background-color: var(--depdepColor__rn5a420); 8 | } 9 | .styles_block__19mmd6u1 { 10 | --color__19mmd6u0: red; 11 | background-color: var(--color__19mmd6u0); 12 | } 13 | -------------------------------------------------------------------------------- /tests/e2e/thirdparty.playwright.ts-snapshots/thirdparty-parcel--production.css: -------------------------------------------------------------------------------- 1 | ._1diaba71 { 2 | --_1diaba70: green; 3 | background-color: var(--_1diaba70); 4 | } 5 | .rn5a421 { 6 | --rn5a420: blue; 7 | background-color: var(--rn5a420); 8 | } 9 | ._19mmd6u1 { 10 | --_19mmd6u0: red; 11 | background-color: var(--_19mmd6u0); 12 | } 13 | -------------------------------------------------------------------------------- /tests/e2e/thirdparty.playwright.ts-snapshots/thirdparty-vite--production.css: -------------------------------------------------------------------------------- 1 | .vg1esd1 { 2 | --vg1esd0: green; 3 | background-color: var(--vg1esd0); 4 | } 5 | ._7q0fkw1 { 6 | --_7q0fkw0: blue; 7 | background-color: var(--_7q0fkw0); 8 | } 9 | ._1vrxmse1 { 10 | --_1vrxmse0: red; 11 | background-color: var(--_1vrxmse0); 12 | } 13 | -------------------------------------------------------------------------------- /tests/jest-dom/jest-dom.css.ts: -------------------------------------------------------------------------------- 1 | import { style, createTheme, createGlobalTheme } from '@vanilla-extract/css'; 2 | 3 | export const vars = createGlobalTheme(':root', { 4 | space: `10px`, 5 | }); 6 | 7 | export const twentyTheme = createTheme(vars, { 8 | space: `20px`, 9 | }); 10 | 11 | export const hide = style({ display: 'none' }); 12 | 13 | export const blackBg = style({ backgroundColor: '#000' }); 14 | 15 | export const padding = style({ paddingTop: vars.space }); 16 | -------------------------------------------------------------------------------- /tests/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@vanilla-extract-private/tests", 3 | "private": true, 4 | "version": "0.0.58", 5 | "author": "SEEK", 6 | "license": "MIT", 7 | "dependencies": { 8 | "@playwright/test": "^1.43.1", 9 | "@testing-library/dom": "^10.0.0", 10 | "@testing-library/jest-dom": "^6.4.2", 11 | "@vanilla-extract-private/test-helpers": "workspace:*", 12 | "@vanilla-extract/compiler": "workspace:*", 13 | "@vanilla-extract/css": "workspace:*", 14 | "@vanilla-extract/dynamic": "workspace:*", 15 | "@vanilla-extract/integration": "workspace:*", 16 | "@vanilla-extract/private": "workspace:*", 17 | "@vanilla-extract/recipes": "workspace:*", 18 | "@vanilla-extract/sprinkles": "workspace:*", 19 | "vite-tsconfig-paths": "^5.1.4" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /tests/recipes/recipes.css.ts: -------------------------------------------------------------------------------- 1 | import { recipe } from '@vanilla-extract/recipes'; 2 | 3 | export const basic = recipe({ 4 | base: {}, 5 | 6 | variants: { 7 | spaceWithDefault: { 8 | small: {}, 9 | large: {}, 10 | }, 11 | spaceWithoutDefault: { 12 | small: {}, 13 | large: {}, 14 | }, 15 | color: { 16 | red: {}, 17 | blue: {}, 18 | }, 19 | rounded: { 20 | true: { borderRadius: 999 }, 21 | }, 22 | }, 23 | 24 | defaultVariants: { 25 | spaceWithDefault: 'small', 26 | }, 27 | 28 | compoundVariants: [ 29 | { 30 | variants: { color: 'red', spaceWithDefault: 'small' }, 31 | style: {}, 32 | }, 33 | ], 34 | }); 35 | 36 | export const empty = recipe({}); 37 | 38 | export const definedStringBase = recipe({ 39 | base: 'definedStringBase', 40 | variants: { 41 | variant: { 42 | simple: 'simple-one', 43 | }, 44 | }, 45 | }); 46 | 47 | export const definedStringBaseArray = recipe({ 48 | base: ['definedStringBaseInArray_1', 'definedStringBaseInArray_2'], 49 | variants: { 50 | variant: { 51 | simple: ['simple-one', 'simple-two'], 52 | }, 53 | }, 54 | }); 55 | -------------------------------------------------------------------------------- /tests/types/type-tests.ts: -------------------------------------------------------------------------------- 1 | import { 2 | createTheme, 3 | createThemeContract, 4 | createGlobalTheme, 5 | } from '@vanilla-extract/css'; 6 | 7 | const vars = createThemeContract({ 8 | shouldSupportNull: null, 9 | shouldSupportNestedNull: { 10 | nested: null, 11 | }, 12 | shouldSupportString: '', 13 | shouldSupportNestedString: { 14 | nested: '', 15 | }, 16 | }); 17 | 18 | createGlobalTheme(':root', vars, { 19 | shouldSupportNull: 'some-value', 20 | shouldSupportNestedNull: { nested: 'some-value' }, 21 | shouldSupportString: 'some-value', 22 | shouldSupportNestedString: { nested: 'some-value' }, 23 | }); 24 | 25 | createTheme(vars, { 26 | shouldSupportNull: 'some-value', 27 | shouldSupportNestedNull: { nested: 'some-value' }, 28 | shouldSupportString: 'some-value', 29 | shouldSupportNestedString: { nested: 'some-value' }, 30 | }); 31 | -------------------------------------------------------------------------------- /tests/walkObject/tokens.ts: -------------------------------------------------------------------------------- 1 | export const space = { small: '8px', large: '16px' }; 2 | -------------------------------------------------------------------------------- /tests/walkObject/walkObject.vitest.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, test, expect } from 'vitest'; 2 | import { walkObject } from '@vanilla-extract/private'; 3 | import * as tokens from './tokens'; 4 | 5 | describe('walkObject', () => { 6 | test('walkObject', () => { 7 | const obj = { 8 | a: { 9 | b: { 10 | c: 1, 11 | }, 12 | d: 2, 13 | }, 14 | e: 3, 15 | }; 16 | 17 | const result = walkObject(obj, (value) => String(value)); 18 | 19 | expect(result).toMatchInlineSnapshot(` 20 | { 21 | "a": { 22 | "b": { 23 | "c": "1", 24 | }, 25 | "d": "2", 26 | }, 27 | "e": "3", 28 | } 29 | `); 30 | }); 31 | 32 | test('walkObject module namespace object', () => { 33 | const result = walkObject(tokens, (value) => `foo${value}`); 34 | 35 | expect(result).toMatchInlineSnapshot(` 36 | { 37 | "space": { 38 | "large": "foo16px", 39 | "small": "foo8px", 40 | }, 41 | } 42 | `); 43 | }); 44 | }); 45 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2022", 4 | "module": "Preserve", // Vanilla Extract is bundled with preconstruct (effectively Rollup) 5 | "lib": ["ES2023", "dom", "dom.iterable"], // ES2023 aligns with Node 22, and we need DOM APIs for fixtures and the docs site 6 | "noEmit": true, 7 | "noImplicitAny": true, 8 | "noUnusedLocals": true, 9 | "noUnusedParameters": true, 10 | "strict": true, 11 | "esModuleInterop": true, 12 | "moduleResolution": "bundler", // Again, bundling handles module resolution 13 | "jsx": "react-jsx", 14 | "allowJs": true, 15 | "incremental": true, 16 | "resolveJsonModule": true, 17 | "skipLibCheck": true, 18 | "moduleDetection": "force", 19 | "isolatedModules": true, 20 | "verbatimModuleSyntax": true 21 | }, 22 | "exclude": [ 23 | "node_modules", 24 | "**/dist/**", 25 | "tests/compiler/fixtures/tsconfig-paths/**" 26 | ], 27 | "include": [ 28 | "@types/testing-library__jest-dom", 29 | "./jest.setup.ts", 30 | "packages/**/*", 31 | "examples/*/app/**/*", 32 | "examples/*/src/**/*", 33 | "fixtures/*/src/**/*", 34 | "test-helpers/**/*", 35 | "site/**/*", 36 | "tests/**/*", 37 | "scripts/*" 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /vitest.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vitest/config'; 2 | import { join, dirname, basename } from 'path'; 3 | 4 | export default defineConfig({ 5 | test: { 6 | include: ['**/*.vitest.test.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'], 7 | resolveSnapshotPath: (testPath, snapExtension) => { 8 | return join( 9 | join(dirname(testPath), '__vitestSnapshots__'), 10 | `${basename(testPath)}${snapExtension}`, 11 | ); 12 | }, 13 | }, 14 | }); 15 | --------------------------------------------------------------------------------