feat(sanity-plugin-markdown): migrate styling to vanilla-extract - #1844
feat(sanity-plugin-markdown): migrate styling to vanilla-extract#1844stipsan wants to merge 4 commits into
Conversation
Replace styled-components EasyMDE theme overrides with colocated vanilla-extract styles, bridging Studio theme tokens via CSS variables.
🦋 Changeset detectedLatest commit: 996745c The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
1 Skipped Deployment
|
✅ E2E Tests🟢 24 passed • 🟡 2 flaky • view full report • view run Studio: https://plugins-e2e-test-studio-26fmwissd.sanity.dev Datasets: |
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
Coverage Report
File Coverage
|
||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Pull request overview
Migrates sanity-plugin-markdown styling from styled-components to vanilla-extract to align with the monorepo’s zero-runtime CSS approach, including theme-token bridging and CSS bundle export wiring.
Changes:
- Replaced
styled(Box)-based editor overrides withMarkdownInput.css.ts(globalStyle) scoped under a wrapper class and theme variables viacreateVar()+assignInlineVars()+useTheme_v2(). - Enabled vanilla-extract in build + tests (
tsdownvanillaExtract: true, VitestvanillaExtractPlugin()+ runtime-style disabling). - Added
./bundle.csspackage export and updated the package-exports snapshot + changeset.
Reviewed changes
Copilot reviewed 8 out of 10 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| pnpm-lock.yaml | Lockfile updates for added vanilla-extract deps and related workspace resolution changes. |
| plugins/sanity-plugin-markdown/vitest.config.ts | Registers vanilla-extract Vite plugin for Vitest and disables runtime CSS injection in tests. |
| plugins/sanity-plugin-markdown/tsdown.config.ts | Switches build pipeline from styled-components mode to vanillaExtract: true. |
| plugins/sanity-plugin-markdown/tsconfig.json | Simplifies include after removing the styled-components theme typing shim. |
| plugins/sanity-plugin-markdown/src/typings.d.ts | Removes styled-components theme augmentation no longer needed post-migration. |
| plugins/sanity-plugin-markdown/src/index.test.ts | Updates exports snapshot to include ./bundle.css. |
| plugins/sanity-plugin-markdown/src/components/MarkdownInput.tsx | Replaces styled wrapper with vanilla-extract wrapper + theme variable assignment. |
| plugins/sanity-plugin-markdown/src/components/MarkdownInput.css.ts | Adds scoped global editor/theme override rules via vanilla-extract. |
| plugins/sanity-plugin-markdown/package.json | Adds ./bundle.css export and vanilla-extract dependencies; removes styled-components from peers. |
| .changeset/markdown-vanilla-extract.md | Patch changeset documenting the migration. |
Files not reviewed (1)
- pnpm-lock.yaml: Generated file
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Strip the auto-injected bundle.css import from the next entry so Next.js pages consumers can keep importing CSS from _app, and merge caller style with assignInlineVars so inline styles are not discarded.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 11 changed files in this pull request and generated no new comments.
Files not reviewed (1)
- pnpm-lock.yaml: Generated file
Suppressed comments (2)
plugins/sanity-plugin-markdown/tsdown.config.ts:15
- The
/nextentry relies on a string replace to remove the injectedbundle.cssimport. The current regex only matches when the import is the very first line and uses\n, so it may fail if tsdown ever reorders imports or emits CRLF line endings, leaving/nextnon–CSS-import-free.
generateBundle(_options, bundle) {
const chunk = bundle['next.js']
if (chunk?.type !== 'chunk') return
chunk.code = chunk.code.replace(/^import ["']sanity-plugin-markdown\/bundle\.css["'];\n/, '')
},
plugins/sanity-plugin-markdown/src/index.test.ts:24
- This PR introduces a custom tsdown plugin to ensure
dist/next.jsis CSS-import-free. The existing test only snapshots the package exports manifest; it doesn’t assert the key behavioral requirement thatdist/index.jsimportsbundle.csswhiledist/next.jsdoes not. Adding a small dist-output assertion would guard against regressions in the strip logic.
"./bundle.css": {},
"./next": {
"MarkdownInput": "function",
"defaultMdeTools": "object",
"markdownSchema": "function",
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 00479cf. Configure here.
Add react-dom and @types/react-dom so the workspace's sanity peer variant matches other @sanity/ui consumers in the lockfile.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 11 changed files in this pull request and generated no new comments.
Files not reviewed (1)
- pnpm-lock.yaml: Generated file
Suppressed comments (2)
plugins/sanity-plugin-markdown/src/components/MarkdownInput.tsx:45
useTheme_v2().color.selectablewas previously treated as optional; accessingcolor.selectable.primary.hovered.bgwithout optional chaining can throw at runtime ifselectableis undefined. Use optional chaining with a safe fallback (egcolor.bg) when assigning the CSS var.
[fgVar]: color.fg,
[borderVar]: color.border,
[bgVar]: color.bg,
[selectionHoveredBgVar]: color.selectable.primary.hovered.bg,
}),
plugins/sanity-plugin-markdown/src/index.test.ts:22
- The build behavior that
/nextmust remain CSS-import-free (by stripping the auto-injectedbundle.cssimport) is new but currently untested. Add a regression assertion againstdist/next.jsso accidental reintroduction of the CSS import is caught.
"markdownSchemaType": "object",
},
"./bundle.css": {},
"./next": {
"MarkdownInput": "function",

Summary
Migrates
sanity-plugin-markdownoffstyled-componentsto vanilla-extract (zero-runtime CSS), following the monorepo migration skill.Changes
styled(Box)EasyMDE/CodeMirror theme overrides with colocatedMarkdownInput.css.tsusingglobalStyle()scoped under a local wrapper classcreateVar()+assignInlineVars()+useTheme_v2()(color.fg/border/bg/selectable.primary.hovered.bg)tsdowntovanillaExtract: true; registeredvanillaExtractPlugin()in Viteststyled-componentspeer dependency (kept asdevDependencyfor@sanity/uipeer alignment)./bundle.cssexport (auto-synced by tsdown) and package-exports snapshot updatesanity-plugin-markdown/nextCSS-import-free (strips auto-injectedbundle.cssfromdist/next.js); README documents importingbundle.cssfrom_app.tsxalongside easymdeVerification
pnpm format/pnpm lint/pnpm knippnpm build --filter=sanity-plugin-markdownemitsdist/bundle.css;dist/index.jsimports it;dist/next.jsdoes not/nextCSS regression)Edit mode:
Markdown editor edit mode
Side-by-side preview:
Markdown editor side-by-side preview
Note
With
unstable_bundledDev: true(test-studio default), lazy-loadingreact-simplemde-editorcurrently fails under Vite 8/rolldown (__toCommonJS/Cannot convert undefined or null to object). Confirmed the same failure on the pre-migration styled-components component — not introduced by this PR. Visual check was done with bundledDev temporarily disabled for that session only.To show artifacts inline, enable in settings.