swatch-token 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +169 -2
- package/dist/cli.js +660 -0
- package/dist/client.js +81 -0
- package/dist/server/files.d.ts +16 -0
- package/dist/server/guard.d.ts +13 -0
- package/dist/server/project.d.ts +71 -0
- package/dist/server/requests.d.ts +42 -0
- package/dist/server/stylesheet.d.ts +51 -0
- package/dist/vite.d.ts +4 -0
- package/dist/vite.js +629 -0
- package/package.json +63 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 tyfoster
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,170 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Swatch
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Edit your CSS colour tokens live, on the page.
|
|
4
|
+
|
|
5
|
+
Swatch is a dev-only panel for [Vite](https://vite.dev) apps. It finds the
|
|
6
|
+
custom properties in your stylesheets, shows each one in light and dark,
|
|
7
|
+
previews every edit on the real app as you type, and writes the result back
|
|
8
|
+
to the file. A production build never contains it.
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install swatch-token -D
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
// vite.config.ts
|
|
18
|
+
import swatch from "swatch-token/vite"
|
|
19
|
+
|
|
20
|
+
export default {
|
|
21
|
+
plugins: [swatch()],
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Start your dev server. Swatch sits in the bottom-left corner.
|
|
26
|
+
|
|
27
|
+
There is nothing to configure: Swatch scans the project for stylesheets
|
|
28
|
+
that declare custom properties on a theme and lists the ones whose values
|
|
29
|
+
are colours.
|
|
30
|
+
|
|
31
|
+
## What it does
|
|
32
|
+
|
|
33
|
+
- **Live preview.** An edit shows on the page at once; nothing touches the
|
|
34
|
+
file until you press Save. Reset takes back everything the tab has saved.
|
|
35
|
+
- **Light and dark, side by side.** Dark is read from `.dark`,
|
|
36
|
+
`[data-theme="dark"]` (also `data-mode`, `data-color-scheme`), or
|
|
37
|
+
`@media (prefers-color-scheme: dark)`.
|
|
38
|
+
- **A colour picker** with alpha, in HEX, RGB, HSL or OKLCH.
|
|
39
|
+
- **Token references.** Type `-` in a value to search the other tokens and
|
|
40
|
+
insert `var(--name)`.
|
|
41
|
+
- **Contrast.** Each `--x-foreground` shows its WCAG ratio against `--x`.
|
|
42
|
+
- **Uses.** How many times each token is used across the project, by file,
|
|
43
|
+
counting `var(--x)` and Tailwind utilities (`bg-x`, `text-x/60`).
|
|
44
|
+
- **Inspect.** Hover the page to see the tokens behind an element and its
|
|
45
|
+
contrast; click to filter the list to them, shift-click to add more.
|
|
46
|
+
- **Find.** Hold it to paint a token magenta wherever it lands on the page.
|
|
47
|
+
|
|
48
|
+
## What counts as a token
|
|
49
|
+
|
|
50
|
+
Custom properties declared in:
|
|
51
|
+
|
|
52
|
+
| Where | Theme |
|
|
53
|
+
| --- | --- |
|
|
54
|
+
| `:root { … }` or `html { … }` (also inside `@layer`) | light |
|
|
55
|
+
| Tailwind's `@theme { … }` | light |
|
|
56
|
+
| `.dark { … }`, `[data-theme="dark"] { … }` | dark |
|
|
57
|
+
| `@media (prefers-color-scheme: dark) { :root { … } }` | dark |
|
|
58
|
+
|
|
59
|
+
`@theme inline { … }` is skipped: it maps utility names to tokens declared
|
|
60
|
+
elsewhere. A property is listed when its value comes to a colour in either
|
|
61
|
+
theme, as the browser reads it, so `red`, `currentColor`, `color-mix()` and
|
|
62
|
+
`color(display-p3 …)` all count, and `--radius: 10px` does not.
|
|
63
|
+
|
|
64
|
+
## How it writes
|
|
65
|
+
|
|
66
|
+
Stylesheets are parsed with PostCSS and printed back with every byte
|
|
67
|
+
outside the edited declaration unchanged: comments, formatting, `@media`
|
|
68
|
+
and `@layer` blocks all stay as they were. A value that would break the
|
|
69
|
+
file (an unclosed bracket, quote or comment) is refused before anything is
|
|
70
|
+
written.
|
|
71
|
+
|
|
72
|
+
## Options
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
swatch({
|
|
76
|
+
// the stylesheet(s) holding the tokens; default: found automatically
|
|
77
|
+
css: "src/styles/tokens.css",
|
|
78
|
+
// where uses are counted; default: the whole project
|
|
79
|
+
src: "src",
|
|
80
|
+
// section titles for the panel; default: grouped by the first word of each name
|
|
81
|
+
groups: { Surfaces: /^--(background|card|popover)/, Text: /-foreground$/ },
|
|
82
|
+
// show "Save & send to agent" and "Figma sync" (see below)
|
|
83
|
+
agent: true,
|
|
84
|
+
// folders to leave out of the search (node_modules, hidden folders and the build output already are)
|
|
85
|
+
ignore: ["storybook-static"],
|
|
86
|
+
// origins besides the dev server's own that may save, such as a tunnel
|
|
87
|
+
allowedOrigins: ["https://my-tunnel.example"],
|
|
88
|
+
})
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Saving is only accepted from the page on your dev server. Behind a tunnel
|
|
92
|
+
or a forwarded port, add its host to Vite's `server.allowedHosts` (which
|
|
93
|
+
Vite asks for anyway) or its origin to `allowedOrigins`. A dev server opened
|
|
94
|
+
to the network with `--host` takes saves from browsers on the page, but not
|
|
95
|
+
from scripts on other machines.
|
|
96
|
+
|
|
97
|
+
## Working with a coding agent
|
|
98
|
+
|
|
99
|
+
Swatch ships an [MCP](https://modelcontextprotocol.io) server, so a coding
|
|
100
|
+
agent can read your tokens, pick up what you ask for from the panel, and
|
|
101
|
+
send colours back for you to preview.
|
|
102
|
+
|
|
103
|
+
Run it from the project root. With Claude Code:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
claude mcp add swatch -- npx swatch-token mcp
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
For any other MCP client:
|
|
110
|
+
|
|
111
|
+
```json
|
|
112
|
+
{ "mcpServers": { "swatch": { "command": "npx", "args": ["swatch-token", "mcp"] } } }
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Then turn the panel's agent buttons on:
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
swatch({ agent: true })
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
- **Save & send to agent** saves your edits and asks the agent to commit
|
|
122
|
+
them, listing each token with its old and new value.
|
|
123
|
+
- **Figma sync** asks the agent to pull the colour variables from a Figma
|
|
124
|
+
file (the agent needs its own access to Figma). What it sends back loads
|
|
125
|
+
as unsaved edits, so you see every value on the page before saving.
|
|
126
|
+
|
|
127
|
+
The agent's tools:
|
|
128
|
+
|
|
129
|
+
| Tool | What it does |
|
|
130
|
+
| --- | --- |
|
|
131
|
+
| `swatch_list_tokens` | Every token: light and dark value, stylesheet, number of uses |
|
|
132
|
+
| `swatch_pending_requests` | What you asked for from the panel and nobody has handled |
|
|
133
|
+
| `swatch_wait_for_request` | Waits (up to 5 minutes) for the next request |
|
|
134
|
+
| `swatch_resolve_request` | Marks a request as handled |
|
|
135
|
+
| `swatch_propose_edits` | Shows values in the panel as unsaved edits; writes no file |
|
|
136
|
+
| `swatch_write_tokens` | Writes values straight into the stylesheets |
|
|
137
|
+
|
|
138
|
+
`npx swatch-token mcp` finds the stylesheets the same way the plugin does; pass
|
|
139
|
+
`--css src/tokens.css` (and `--src src`) if you set those options there.
|
|
140
|
+
|
|
141
|
+
Requests are kept in `.swatch/` at the project root: add it to
|
|
142
|
+
`.gitignore`.
|
|
143
|
+
|
|
144
|
+
## Frameworks
|
|
145
|
+
|
|
146
|
+
Swatch injects itself through Vite's `index.html`, which covers plain Vite
|
|
147
|
+
apps (React, Vue, Svelte, Solid, vanilla). Where the framework renders the
|
|
148
|
+
HTML itself (SvelteKit, Astro, Remix), add the script to your root layout
|
|
149
|
+
in development:
|
|
150
|
+
|
|
151
|
+
```html
|
|
152
|
+
<script type="module" src="/__swatch/client.js"></script>
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
The panel runs in a shadow root with its own copy of React, so it works the
|
|
156
|
+
same whatever the app is built with.
|
|
157
|
+
|
|
158
|
+
## Development
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
npm install
|
|
162
|
+
npm test # the stylesheet reader and writer, and the MCP server
|
|
163
|
+
npm run example # build, then run the example app with Swatch in it
|
|
164
|
+
npm run site # the website, which runs the real panel on itself
|
|
165
|
+
npm run site:build # the website as static files, in site/dist
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## Licence
|
|
169
|
+
|
|
170
|
+
MIT
|