From accd7152a893d420c59f03f9a0a20e501ff5e59a Mon Sep 17 00:00:00 2001 From: Cody Olsen Date: Wed, 6 Aug 2025 13:29:00 +0200 Subject: [PATCH] feat: support vanilla extract --- README.md | 81 +++++++++++++++++++++++++++++- package.config.ts | 1 + package.json | 6 +-- pnpm-lock.yaml | 52 +++++++++++++++++++ src/core/frame/formatStack.ts | 2 +- src/core/plugins/props/helpers.ts | 2 +- src/runtime/config/_loadConfig.ts | 4 +- src/runtime/config/_loadRuntime.ts | 4 +- src/runtime/lib/_fileExists.ts | 2 +- src/runtime/viteConfig.ts | 2 + 10 files changed, 145 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index f6611b1e..4249ba2f 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ An environment for designing, reviewing, and quality-testing React components. npm install @sanity/ui-workshop -D # Install peer dependencies -npm install @sanity/icons @sanity/ui react react-dom styled-components +npm install @sanity/ui react react-dom styled-components ``` [![npm version](https://img.shields.io/npm/v/@sanity/ui-workshop.svg?style=flat-square)](https://www.npmjs.com/package/@sanity/ui-workshop) @@ -88,6 +88,85 @@ function TestStory() { } ``` +## Styling + +In addition to the [CSS features that `vite` supports](https://vite.dev/guide/features.html#css), you can also use [Vanilla Extract](https://vanilla-extract.style/) for styling. + +First install the `@vanilla-extract/css` package: + +```sh +npm install @vanilla-extract/css +``` + +Then, add a `style.css.ts` file for your workshop: + +```ts +// src/__workshop__/style.css.ts + +import {style} from '@vanilla-extract/css' + +export const container = style({ + display: 'grid', + alignItems: 'center', + justifyContent: 'center', + height: '100%', + width: '100%', +}) +``` + +And finally, import the `container` className and use it in your workshop: + +```diff +import { + defineScope, + useBoolean, + useNumber, + useSelect, + useString, + useText, +} from '@sanity/ui-workshop' ++import {container} from './style.css' + +export default defineScope({ + name: 'test', + title: 'Test', + stories: [ + { + name: 'test', + title: 'Test', + component: TestStory, + }, + ], +}) + +const options = { + None: '', + Small: 'sm', + Medium: 'md', + Large: 'lg', +} + +function TestStory() { + const text = useText('Text', 'Hello, world') + const boolean = useBoolean('Boolean', true) + const number = useNumber('Number', 1234) + const string = useString('String', '...') + const option = useSelect('Select option', options) + + return ( +-
++
+

This is my first story.

+

Some text: {text}

+

A boolean: {boolean ? 'true' : 'false'}

+

A number: {number}

+

A string: {string}

+

An option: {option}

+
+ ) +} +``` + ## License [MIT](LICENSE) diff --git a/package.config.ts b/package.config.ts index 9fbe3a0d..95fe3189 100644 --- a/package.config.ts +++ b/package.config.ts @@ -17,4 +17,5 @@ export default defineConfig({ babel: {reactCompiler: true, styledComponents: true}, reactCompilerOptions: {target: '19'}, dts: 'rolldown', + strictOptions: {noImplicitSideEffects: 'off'}, }) diff --git a/package.json b/package.json index 2a77809c..6684c564 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@sanity/ui-workshop", - "version": "3.1.2", + "version": "3.1.3-canary.0", "keywords": [ "sanity", "ui", @@ -20,7 +20,6 @@ }, "license": "MIT", "author": "Sanity.io ", - "sideEffects": false, "type": "module", "exports": { ".": { @@ -73,7 +72,7 @@ "format": "prettier --write --cache --ignore-unknown .", "lint": "eslint . --ext .cjs,.js,.jsx,.mjs,.ts,.tsx", "prepare": "husky install", - "prepublishOnly": "pnpm run build", + "prepack": "pnpm run build", "release": "semantic-release", "test": "vitest", "watch": "pkg watch --strict", @@ -106,6 +105,7 @@ }, "dependencies": { "@sanity/icons": "^3.7.4", + "@vanilla-extract/vite-plugin": "^5.1.1", "@vitejs/plugin-react": "^4.7.0", "axe-core": "^4.10.3", "cac": "^6.7.14", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1cdf0230..60cac740 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,6 +11,9 @@ importers: '@sanity/icons': specifier: ^3.7.4 version: 3.7.4(react@19.1.1) + '@vanilla-extract/vite-plugin': + specifier: ^5.1.1 + version: 5.1.1(@types/node@20.19.9)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(vite@7.0.6(@types/node@20.19.9)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)) '@vitejs/plugin-react': specifier: ^4.7.0 version: 4.7.0(vite@7.0.6(@types/node@20.19.9)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)) @@ -1341,6 +1344,9 @@ packages: '@vanilla-extract/babel-plugin-debug-ids@1.2.2': resolution: {integrity: sha512-MeDWGICAF9zA/OZLOKwhoRlsUW+fiMwnfuOAqFVohL31Agj7Q/RBWAYweqjHLgFBCsdnr6XIfwjJnmb2znEWxw==} + '@vanilla-extract/compiler@0.3.1': + resolution: {integrity: sha512-KZ67DZQu58dMo7Jv4PNMPG5TbMOXB68xxVYV2cRJvUdPeiOmX0FOaPgEsYBAZUgd/oLEx4IyV0AvlvsxJ1akfQ==} + '@vanilla-extract/css@1.17.4': resolution: {integrity: sha512-m3g9nQDWPtL+sTFdtCGRMI1Vrp86Ay4PBYq1Bo7Bnchj5ElNtAJpOqD+zg+apthVA4fB7oVpMWNjwpa6ElDWFQ==} @@ -1355,6 +1361,11 @@ packages: peerDependencies: rollup: ^2.0.0 || ^3.0.0 || ^4.0.0 + '@vanilla-extract/vite-plugin@5.1.1': + resolution: {integrity: sha512-Nd1worqkHrd8XED4ZAA7Wmkd3pCqCwpmzCBVF8v6T1BSLHGXQE5HYflVgygw0CsIAbFRMS6zQBIk4F4/r/YKIw==} + peerDependencies: + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 + '@vitejs/plugin-react@4.7.0': resolution: {integrity: sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==} engines: {node: ^14.18.0 || >=16.0.0} @@ -6773,6 +6784,27 @@ snapshots: transitivePeerDependencies: - supports-color + '@vanilla-extract/compiler@0.3.1(@types/node@20.19.9)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)': + dependencies: + '@vanilla-extract/css': 1.17.4 + '@vanilla-extract/integration': 8.0.4 + vite: 7.0.6(@types/node@20.19.9)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1) + vite-node: 3.2.4(@types/node@20.19.9)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1) + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - jiti + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + '@vanilla-extract/css@1.17.4': dependencies: '@emotion/hash': 0.9.2 @@ -6817,6 +6849,26 @@ snapshots: - babel-plugin-macros - supports-color + '@vanilla-extract/vite-plugin@5.1.1(@types/node@20.19.9)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(vite@7.0.6(@types/node@20.19.9)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1))': + dependencies: + '@vanilla-extract/compiler': 0.3.1(@types/node@20.19.9)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1) + '@vanilla-extract/integration': 8.0.4 + vite: 7.0.6(@types/node@20.19.9)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1) + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - jiti + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + '@vitejs/plugin-react@4.7.0(vite@7.0.6(@types/node@20.19.9)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1))': dependencies: '@babel/core': 7.28.0 diff --git a/src/core/frame/formatStack.ts b/src/core/frame/formatStack.ts index 1bf84ee3..b69b9821 100644 --- a/src/core/frame/formatStack.ts +++ b/src/core/frame/formatStack.ts @@ -2,7 +2,7 @@ const ROOT_PATH = (() => { // Wrap in try/catch to avoid throwing exception in environments that don’t have `process.env`. try { return process.env.ROOT_PATH - } catch (_) { + } catch { return undefined } })() diff --git a/src/core/plugins/props/helpers.ts b/src/core/plugins/props/helpers.ts index ae149b24..0382d826 100644 --- a/src/core/plugins/props/helpers.ts +++ b/src/core/plugins/props/helpers.ts @@ -10,7 +10,7 @@ export function encodeValue(val: Record): string { export function decodeValue(val: string): Record { try { return JSON.parse(decode(val)) - } catch (_) { + } catch { return EMPTY_RECORD } } diff --git a/src/runtime/config/_loadConfig.ts b/src/runtime/config/_loadConfig.ts index 5c167969..45e31a31 100644 --- a/src/runtime/config/_loadConfig.ts +++ b/src/runtime/config/_loadConfig.ts @@ -1,7 +1,7 @@ import {createRequire} from 'node:module' -import {WorkshopConfigOptions} from '@sanity/ui-workshop' -import {TransformOptions} from 'esbuild' +import type {WorkshopConfigOptions} from '@sanity/ui-workshop' +import type {TransformOptions} from 'esbuild' import {_findConfigFile} from './_findConfigFile' diff --git a/src/runtime/config/_loadRuntime.ts b/src/runtime/config/_loadRuntime.ts index fa37f619..d3a2dd77 100644 --- a/src/runtime/config/_loadRuntime.ts +++ b/src/runtime/config/_loadRuntime.ts @@ -1,7 +1,7 @@ import {createRequire} from 'node:module' -import {WorkshopRuntimeOptions} from '@sanity/ui-workshop' -import {TransformOptions} from 'esbuild' +import type {WorkshopRuntimeOptions} from '@sanity/ui-workshop' +import type {TransformOptions} from 'esbuild' import {_findRuntimeFile} from './_findRuntimeFile' diff --git a/src/runtime/lib/_fileExists.ts b/src/runtime/lib/_fileExists.ts index 29bfb19b..a7c6202a 100644 --- a/src/runtime/lib/_fileExists.ts +++ b/src/runtime/lib/_fileExists.ts @@ -6,7 +6,7 @@ export function _fileExists(file: string): boolean { accessSync(file) return true - } catch (_) { + } catch { return false } } diff --git a/src/runtime/viteConfig.ts b/src/runtime/viteConfig.ts index 83a49da3..272779a9 100644 --- a/src/runtime/viteConfig.ts +++ b/src/runtime/viteConfig.ts @@ -1,3 +1,4 @@ +import {vanillaExtractPlugin} from '@vanilla-extract/vite-plugin' import react from '@vitejs/plugin-react' import path from 'path' import {UserConfig} from 'vite' @@ -26,6 +27,7 @@ export function createViteConfig(options: { }, }, plugins: [ + vanillaExtractPlugin(), react({ babel: {plugins: [['babel-plugin-react-compiler', {target: '19'}]]}, }),