Skip to content

feat(themer): import themer.sanity.build URLs in the themer tool - #2064

Draft
stipsan wants to merge 1 commit into
cody/themer-css-modules-3ea2from
cody/themer-legacy-url-import-41ad
Draft

stipsan wants to merge 1 commit into
cody/themer-css-modules-3ea2from
cody/themer-legacy-url-import-41ad

Conversation

@stipsan

@stipsan stipsan commented Sep 30, 2026 •

Copy link
Copy Markdown
Member

Ports sanity-io/ui#3009, with the same title and intent. It's stacked on #2202 (vanilla-extract to CSS modules), so its base is cody/themer-css-modules-3ea2. Once #2202 merges, the base can go back to main.

What it does

With the themer sidebar open, paste a https://themer.sanity.build/api/hues?… URL, or a snippet that contains one, anywhere except a text field. The tool converts the theme to buildTheme options, adds it and opens it in the editor. Add from URL in the list's menu opens a dialog that previews the converted theme first.

src/tool/legacyTheme.ts parses the URL with parseHuesFromUrl from @sanity/themer-legacy, the hosted service's own parser. The primary hue becomes the accent, the default hue the text color, and the default hue's lightest and darkest colors the backgrounds.

Add from URL in the theme list
The import dialog previewing a converted Pink Synth theme

Changes from ui#3009

The themer changed a lot after ui#3009 branched, so the port follows the current code:

  • The entry point is Add from URL in the list's footer menu, next to Add from code, instead of a button below the cards.
  • The import dialog is a state of the machine's list flow (dialog.import), like the paste and snippet dialogs. Adding the theme leaves the list, which closes the dialog.
  • The closing menu takes focus back after the dialog's autoFocus, so the text area refocuses on the next frame.
  • The paste hook and the dialog go through actorRef, and the hook lives in ThemerSidebar.
  • The dialog's style is ImportThemeDialog.module.css, with committed css-modules-kit typings. Nothing imports vanilla-extract.
  • The theme-code paste listener skips pastes that something else already handled. Otherwise a code pasted on the import dialog would go into the dialog's field and also be imported.
  • The README's migration section already shows buildThemeFromUrl. This adds a short part on converting the theme in the tool.
  • ui#3009's long-title grid fix is dropped, since the themer already has it. Its paragraph in the themer-legacy README isn't here either, because that package lives in sanity-io/themer.

Checks

pnpm lint (typings, stylelint, oxlint), pnpm knip, pnpm --filter @sanity/themer build (publint) and the themer's tests (15 files, 168 tests) pass. A temporary Storybook harness, not committed, drove the real sidebar with Playwright, and all 8 checks passed. They cover the menu item, focus, the CSS module class, import, pasting a URL anywhere, and a code pasted on the dialog. There are no dependency, lockfile, Vercel or Sanity changes.

To show artifacts inline, enable in settings.

Open in Web Open in Cursor 

@changeset-bot

changeset-bot Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 453675f

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@sanity/themer Minor

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

@vercel

vercel Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
plugins-studio Ready Ready Preview Oct 22, 2026 1:10pm UTC
1 Skipped Deployment
Project Deployment Actions Updated
plugins-e2e-test-studio Ignored Ignored Oct 22, 2026 1:10pm UTC

Request Review

@github-actions

github-actions Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

✅ E2E Tests

🟢 46 passed • view full report • view run

Studio: https://plugins-e2e-test-studio-poxbv1b95.sanity.dev

Datasets: pr-2064-chromium-39784433608, pr-2064-firefox-39784433608

@github-actions

github-actions Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 38.14% 7696 / 20174
🔵 Statements 38.13% 8284 / 21725
🔵 Functions 33.79% 2097 / 6205
🔵 Branches 30.26% 4442 / 14679
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
plugins/@sanity/themer/src/theme/options.ts 100% 100% 100% 100%
plugins/@sanity/themer/src/tool/legacyTheme.ts 100% 95% 100% 100%
plugins/@sanity/themer/src/tool/machine.ts 98.82% 98.03% 98.43% 98.7% 389
plugins/@sanity/themer/src/tool/plugin.tsx 71.42% 100% 66.66% 71.42% 69-71
Generated in workflow #11228 for commit 4d6a38a by the Vitest Coverage Report Action

Ported from sanity-io/ui#3009. With the themer sidebar open, pasting a
themer.sanity.build URL, or a snippet that contains one, anywhere except
a text field converts its theme to buildTheme options, adds it and opens
it in the editor. "Add from URL" in the list's menu opens a dialog that
previews the converted theme first. The URL is parsed by
parseHuesFromUrl from @sanity/themer-legacy, the hosted service's own
parser.

The theme code paste listener now skips pastes that something else has
already handled, like the import dialog.

Co-authored-by: Cody Olsen <stipsan@users.noreply.github.com>
@cursor
cursor Bot force-pushed the cody/themer-legacy-url-import-41ad branch from 453675f to 4d6a38a Compare October 22, 2026 13:09
@stipsan stipsan added the ✨ ai PR authored by an AI agent (🤖 bot is for CI automation/Renovate) label Oct 22, 2026

This branch was successfully deployed

1 active deployment
Preview – plugins-studio — 4d6a38a9 Deployed Oct 22, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨ ai PR authored by an AI agent (🤖 bot is for CI automation/Renovate)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants