From 97e95252910a62b7ab6e0f37e7f60248d48ca9e6 Mon Sep 17 00:00:00 2001 From: Cody Olsen Date: Fri, 25 Jul 2025 15:07:13 +0200 Subject: [PATCH] feat: remove `styled-components` dependency --- README.md | 2 +- package.config.ts | 13 +- package.json | 11 +- pnpm-lock.yaml | 44 +++--- src/core/GlobalStyle.ts | 106 +++----------- src/core/WorkshopCanvas.tsx | 53 +++---- src/core/inspector/InspectorHeader.tsx | 49 +++---- src/core/inspector/WorkshopInspector.tsx | 26 ++-- src/core/navigator/WorkshopNavigator.tsx | 29 ++-- src/core/styles.css.ts | 171 +++++++++++++++++++++++ src/runtime/runtime/_writeFrameHTML.ts | 14 -- src/runtime/runtime/_writeHTML.ts | 14 -- tsconfig.dist.json | 2 +- tsconfig.json | 1 - typings/sanity-env.d.ts | 5 - 15 files changed, 283 insertions(+), 257 deletions(-) create mode 100644 src/core/styles.css.ts delete mode 100644 typings/sanity-env.d.ts diff --git a/README.md b/README.md index 4249ba2f..2e147349 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/ui react react-dom styled-components +npm install @sanity/ui react react-dom ``` [![npm version](https://img.shields.io/npm/v/@sanity/ui-workshop.svg?style=flat-square)](https://www.npmjs.com/package/@sanity/ui-workshop) diff --git a/package.config.ts b/package.config.ts index 95fe3189..3fc1d3f5 100644 --- a/package.config.ts +++ b/package.config.ts @@ -14,8 +14,19 @@ export default defineConfig({ }, }, tsconfig: 'tsconfig.dist.json', - babel: {reactCompiler: true, styledComponents: true}, + babel: {reactCompiler: true}, reactCompilerOptions: {target: '19'}, + rollup: { + output: { + intro: (chunkInfo) => { + if (chunkInfo.isEntry === true && chunkInfo.name === 'index') { + return `import './bundle.css'` + } + return '' + }, + }, + vanillaExtract: true, + }, dts: 'rolldown', strictOptions: {noImplicitSideEffects: 'off'}, }) diff --git a/package.json b/package.json index e017468c..bf175ead 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,9 @@ "license": "MIT", "author": "Sanity.io ", "type": "module", + "imports": { + "#styles": "./src/core/styles.css.ts" + }, "exports": { ".": { "source": "./exports/index.ts", @@ -105,6 +108,9 @@ }, "dependencies": { "@sanity/icons": "^3.7.4", + "@vanilla-extract/css": "^1.17.4", + "@vanilla-extract/css-utils": "^0.1.6", + "@vanilla-extract/dynamic": "^2.1.5", "@vanilla-extract/vite-plugin": "^5.1.1", "@vitejs/plugin-react": "^4.7.0", "axe-core": "^4.10.3", @@ -140,7 +146,6 @@ "@typescript-eslint/eslint-plugin": "^7.18.0", "@typescript-eslint/parser": "^7.18.0", "babel-plugin-react-compiler": "19.1.0-rc.2", - "babel-plugin-styled-components": "^2.1.4", "commitizen": "^4.3.1", "commitlint": "^19.8.1", "eslint": "^8.57.1", @@ -160,7 +165,6 @@ "react-dom": "^19.1.1", "react-is": "^19.1.1", "semantic-release": "^23.1.1", - "styled-components": "^6.1.19", "tsconfig-paths": "^4.2.0", "typescript": "5.9.2", "vitest": "^3.2.4" @@ -168,8 +172,7 @@ "peerDependencies": { "@sanity/ui": "^3", "react": "^19", - "react-dom": "^19", - "styled-components": "^6.1" + "react-dom": "^19" }, "packageManager": "pnpm@9.15.9", "publishConfig": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 60cac740..e61f5830 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,6 +11,15 @@ importers: '@sanity/icons': specifier: ^3.7.4 version: 3.7.4(react@19.1.1) + '@vanilla-extract/css': + specifier: ^1.17.4 + version: 1.17.4 + '@vanilla-extract/css-utils': + specifier: ^0.1.6 + version: 0.1.6 + '@vanilla-extract/dynamic': + specifier: ^2.1.5 + version: 2.1.5 '@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)) @@ -111,9 +120,6 @@ importers: babel-plugin-react-compiler: specifier: 19.1.0-rc.2 version: 19.1.0-rc.2 - babel-plugin-styled-components: - specifier: ^2.1.4 - version: 2.1.4(@babel/core@7.28.0)(styled-components@6.1.19(react-dom@19.1.1(react@19.1.1))(react@19.1.1)) commitizen: specifier: ^4.3.1 version: 4.3.1(@types/node@20.19.9)(typescript@5.9.2) @@ -171,9 +177,6 @@ importers: semantic-release: specifier: ^23.1.1 version: 23.1.1(typescript@5.9.2) - styled-components: - specifier: ^6.1.19 - version: 6.1.19(react-dom@19.1.1(react@19.1.1))(react@19.1.1) tsconfig-paths: specifier: ^4.2.0 version: 4.2.0 @@ -1347,9 +1350,15 @@ packages: '@vanilla-extract/compiler@0.3.1': resolution: {integrity: sha512-KZ67DZQu58dMo7Jv4PNMPG5TbMOXB68xxVYV2cRJvUdPeiOmX0FOaPgEsYBAZUgd/oLEx4IyV0AvlvsxJ1akfQ==} + '@vanilla-extract/css-utils@0.1.6': + resolution: {integrity: sha512-iICpaHma0s2EEnQDw/JRqudQJwYw1JERyWfIllNQplps226KVphjGb3jyGMiBK5Waw69RD3q4gulgRVQAQmKmA==} + '@vanilla-extract/css@1.17.4': resolution: {integrity: sha512-m3g9nQDWPtL+sTFdtCGRMI1Vrp86Ay4PBYq1Bo7Bnchj5ElNtAJpOqD+zg+apthVA4fB7oVpMWNjwpa6ElDWFQ==} + '@vanilla-extract/dynamic@2.1.5': + resolution: {integrity: sha512-QGIFGb1qyXQkbzx6X6i3+3LMc/iv/ZMBttMBL+Wm/DetQd36KsKsFg5CtH3qy+1hCA/5w93mEIIAiL4fkM8ycw==} + '@vanilla-extract/integration@8.0.4': resolution: {integrity: sha512-cmOb7tR+g3ulKvFtSbmdw3YUyIS1d7MQqN+FcbwNhdieyno5xzUyfDCMjeWJhmCSMvZ6WlinkrOkgs6SHB+FRg==} @@ -1641,11 +1650,6 @@ packages: babel-plugin-react-compiler@19.1.0-rc.2: resolution: {integrity: sha512-kSNA//p5fMO6ypG8EkEVPIqAjwIXm5tMjfD1XRPL/sRjYSbJ6UsvORfaeolNWnZ9n310aM0xJP7peW26BuCVzA==} - babel-plugin-styled-components@2.1.4: - resolution: {integrity: sha512-Xgp9g+A/cG47sUyRwwYxGM4bR/jDRg5N6it/8+HxCnbT5XNKSKDT9xm4oag/osgqjC2It/vH0yXsomOG6k558g==} - peerDependencies: - styled-components: '>= 2' - babel-runtime@6.26.0: resolution: {integrity: sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==} @@ -6805,6 +6809,8 @@ snapshots: - tsx - yaml + '@vanilla-extract/css-utils@0.1.6': {} + '@vanilla-extract/css@1.17.4': dependencies: '@emotion/hash': 0.9.2 @@ -6822,6 +6828,10 @@ snapshots: transitivePeerDependencies: - babel-plugin-macros + '@vanilla-extract/dynamic@2.1.5': + dependencies: + '@vanilla-extract/private': 1.0.9 + '@vanilla-extract/integration@8.0.4': dependencies: '@babel/core': 7.28.0 @@ -7165,18 +7175,6 @@ snapshots: dependencies: '@babel/types': 7.28.2 - babel-plugin-styled-components@2.1.4(@babel/core@7.28.0)(styled-components@6.1.19(react-dom@19.1.1(react@19.1.1))(react@19.1.1)): - dependencies: - '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-module-imports': 7.27.1 - '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.0) - lodash: 4.17.21 - picomatch: 2.3.1 - styled-components: 6.1.19(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - transitivePeerDependencies: - - '@babel/core' - - supports-color - babel-runtime@6.26.0: dependencies: core-js: 2.6.12 diff --git a/src/core/GlobalStyle.ts b/src/core/GlobalStyle.ts index 8e5a6bad..fccd143e 100644 --- a/src/core/GlobalStyle.ts +++ b/src/core/GlobalStyle.ts @@ -1,92 +1,18 @@ -import {createGlobalStyle} from 'styled-components' +import {useRootTheme} from '@sanity/ui' +import {setElementVars} from '@vanilla-extract/dynamic' +import {useInsertionEffect} from 'react' -export const GlobalStyle = createGlobalStyle` - @font-face { - font-family: Inter; - font-style: normal; - font-weight: 400; - font-display: swap; - src: url("https://studio-static.sanity.io/Inter-Regular.woff2") format("woff2"); - } - @font-face { - font-family: Inter; - font-style: italic; - font-weight: 400; - font-display: swap; - src: url("https://studio-static.sanity.io/Inter-Italic.woff2") format("woff2"); - } - @font-face { - font-family: Inter; - font-style: normal; - font-weight: 500; - font-display: swap; - src: url("https://studio-static.sanity.io/Inter-Medium.woff2") format("woff2"); - } - @font-face { - font-family: Inter; - font-style: italic; - font-weight: 500; - font-display: swap; - src: url("https://studio-static.sanity.io/Inter-MediumItalic.woff2") format("woff2"); - } - @font-face { - font-family: Inter; - font-style: normal; - font-weight: 600; - font-display: swap; - src: url("https://studio-static.sanity.io/Inter-SemiBold.woff2") format("woff2"); - } - @font-face { - font-family: Inter; - font-style: italic; - font-weight: 600; - font-display: swap; - src: url("https://studio-static.sanity.io/Inter-SemiBoldItalic.woff2") format("woff2"); - } - @font-face { - font-family: Inter; - font-style: normal; - font-weight: 700; - font-display: swap; - src: url("https://studio-static.sanity.io/Inter-Bold.woff2") format("woff2"); - } - @font-face { - font-family: Inter; - font-style: italic; - font-weight: 700; - font-display: swap; - src: url("https://studio-static.sanity.io/Inter-BoldItalic.woff2") format("woff2"); - } - @font-face { - font-family: Inter; - font-style: normal; - font-weight: 800; - font-display: swap; - src: url("https://studio-static.sanity.io/Inter-ExtraBold.woff2") format("woff2"); - } - @font-face { - font-family: Inter; - font-style: italic; - font-weight: 800; - font-display: swap; - src: url("https://studio-static.sanity.io/Inter-ExtraBoldItalic.woff2") format("woff2"); - } - @font-face { - font-family: Inter; - font-style: normal; - font-weight: 900; - font-display: swap; - src: url("https://studio-static.sanity.io/Inter-Black.woff2") format("woff2"); - } - @font-face { - font-family: Inter; - font-style: italic; - font-weight: 900; - font-display: swap; - src: url("https://studio-static.sanity.io/Inter-BlackItalic.woff2") format("woff2"); - } +import {bodyBackgroundColor} from '#styles' - body { - background-color: ${({theme}) => theme.sanity.color.base.bg}; - } -` +export function GlobalStyle(): null { + const {scheme, theme} = useRootTheme() + const bg = theme.v2!.color[scheme].default.bg! + + useInsertionEffect(() => { + setElementVars(document.body, { + [bodyBackgroundColor]: bg, + }) + }, [bg]) + + return null +} diff --git a/src/core/WorkshopCanvas.tsx b/src/core/WorkshopCanvas.tsx index 2326204c..1ca80c7b 100644 --- a/src/core/WorkshopCanvas.tsx +++ b/src/core/WorkshopCanvas.tsx @@ -1,19 +1,19 @@ -import {BoxDisplay, Card, Container, Flex, Heading, Spinner, Stack, Text} from '@sanity/ui' -import {memo, useMemo, useState} from 'react' -import {styled} from 'styled-components' +import {Card, Container, Flex, Heading, Spinner, Stack, Text} from '@sanity/ui' +import {assignInlineVars} from '@vanilla-extract/dynamic' +import {memo, useState} from 'react' + +import { + iframe, + iframeContainer, + viewportMaxHeight, + viewportMaxWidth, + zoom as zoomVar, +} from '#styles' import {VIEWPORT_OPTIONS} from './constants' import {buildFrameUrl} from './helpers' import {useWorkshop} from './useWorkshop' -const Frame = styled.iframe` - display: block; - border: 0; - height: 100%; - width: 100%; - view-transition-name: canvas; -` - /** @internal */ export const WorkshopCanvas = memo(function WorkshopCanvas(props: { frameRef: React.Ref @@ -29,28 +29,8 @@ export const WorkshopCanvas = memo(function WorkshopCanvas(props: { buildFrameUrl({baseUrl: frameUrl, path, payload, scheme, viewport, zoom}), ) - const containerStyle = useMemo( - () => ({ - maxWidth: viewportW === 'auto' ? undefined : `${(viewportW || 1) * zoom}px`, - maxHeight: viewportH ? `${(viewportH || 1) * zoom}px` : undefined, - }), - [viewportW, viewportH, zoom], - ) - - const display: BoxDisplay = useMemo(() => (hidden ? 'none' : 'block'), [hidden]) - - const frameStyle = useMemo( - () => ({ - transform: `scale(${zoom})`, - transformOrigin: '0 0', - width: `${100 / zoom}%`, - height: `${100 / zoom}%`, - }), - [zoom], - ) - return ( - + {path === '/' && ( @@ -66,13 +46,18 @@ export const WorkshopCanvas = memo(function WorkshopCanvas(props: { {!frameReady && path !== '/' && }