From 7a5eb20924b8e631577df79209428e39306a3480 Mon Sep 17 00:00:00 2001 From: Antoine BERNIER Date: Mon, 3 Aug 2026 14:37:55 +0200 Subject: [PATCH 01/14] feat: add a ThemePanel bookmarklet for any shadcn site MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A javascript: loader injects dist/bookmarklet.global.js (self-contained IIFE, React bundled, Tailwind CSS compiled and inlined at build time via a tsup esbuild plugin) from jsDelivr. The panel mounts in a shadow root bottom-right, seeds its source color from the host's --primary, and on the first tweak forces the shadcn variables onto the page — unlayered !important :root/.dark blocks, re-appended last in , host document and same-origin iframes alike (ui.shadcn.com/create previews in one). Closing it (via its close button or clicking the bookmarklet again) restores the site untouched. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01G69EjEY89Q6nNGj1xvgeja --- .changeset/mtb-bookmarklet.md | 5 + README.md | 10 ++ src/Bookmarklet.stories.tsx | 53 +++++++++ src/bookmarklet.css | 58 ++++++++++ src/bookmarklet.tsx | 211 ++++++++++++++++++++++++++++++++++ src/components/ui/tooltip.tsx | 21 +++- src/lib/shadcnStyle.test.ts | 37 ++++++ src/lib/shadcnStyle.ts | 26 +++++ tsup.config.ts | 53 +++++++++ 9 files changed, 472 insertions(+), 2 deletions(-) create mode 100644 .changeset/mtb-bookmarklet.md create mode 100644 src/Bookmarklet.stories.tsx create mode 100644 src/bookmarklet.css create mode 100644 src/bookmarklet.tsx create mode 100644 src/lib/shadcnStyle.test.ts create mode 100644 src/lib/shadcnStyle.ts diff --git a/.changeset/mtb-bookmarklet.md b/.changeset/mtb-bookmarklet.md new file mode 100644 index 00000000..041a4ca2 --- /dev/null +++ b/.changeset/mtb-bookmarklet.md @@ -0,0 +1,5 @@ +--- +"material-theme-builder": minor +--- + +Add a `ThemePanel` bookmarklet: a `javascript:` snippet (see README) that mounts the panel on any shadcn-based site and re-themes it live by forcing the shadcn variables — same mapping as `toShadcn()`, same-origin preview iframes included. Ships as a self-contained `dist/bookmarklet.global.js` IIFE served from jsDelivr; the panel renders in a shadow root, styled by the very variables it edits, and closing it restores the site untouched. diff --git a/README.md b/README.md index 6329eed3..469424d4 100644 --- a/README.md +++ b/README.md @@ -137,6 +137,16 @@ import { Mtb, ThemePanel } from "material-theme-builder/react"; ; ``` +### Bookmarklet + +Try the `ThemePanel` on **any shadcn-based site** — no install. Create a bookmark with this URL: + +``` +javascript:(()=>{var s=document.createElement("script");s.src="https://cdn.jsdelivr.net/npm/material-theme-builder@3/dist/bookmarklet.global.js";document.body.append(s)})() +``` + +Click it on a shadcn site (try [ui.shadcn.com/create](https://ui.shadcn.com/create)): the panel mounts bottom-right and every tweak re-themes the page live, by forcing the [shadcn variables](https://ui.shadcn.com/docs/theming#list-of-variables) (same mapping as `toShadcn()`) on the page — same-origin preview iframes included. The panel itself lives in a shadow root and is styled by the very variables it edits. Click the bookmarklet again — or its ✕ button — to restore the site untouched. + ## Tailwind Compatible through [theme variables](https://tailwindcss.com/docs/theme): diff --git a/src/Bookmarklet.stories.tsx b/src/Bookmarklet.stories.tsx new file mode 100644 index 00000000..f7a996c8 --- /dev/null +++ b/src/Bookmarklet.stories.tsx @@ -0,0 +1,53 @@ +import type { Meta, StoryObj } from "@storybook/react-vite"; + +/** + * The `javascript:` snippet users paste (or drag) into their bookmarks bar. + * + * A bookmarklet URL can only hold a few KB, so it is a tiny loader: it + * injects a `