dowel-ui 0.13.0 → 0.14.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/README.md +27 -0
- package/dist/cli/bin.d.ts +3 -0
- package/dist/cli/bin.d.ts.map +1 -0
- package/dist/cli/bin.js +9 -0
- package/dist/cli/bin.js.map +1 -0
- package/dist/cli/codemod.d.ts +22 -0
- package/dist/cli/codemod.d.ts.map +1 -0
- package/dist/cli/codemod.js +69 -0
- package/dist/cli/codemod.js.map +1 -0
- package/dist/cli/diff.d.ts +23 -0
- package/dist/cli/diff.d.ts.map +1 -0
- package/dist/cli/diff.js +122 -0
- package/dist/cli/diff.js.map +1 -0
- package/dist/cli/doctor.d.ts +81 -0
- package/dist/cli/doctor.d.ts.map +1 -0
- package/dist/cli/doctor.js +185 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/index.d.ts +8 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +362 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/scan.d.ts +43 -0
- package/dist/cli/scan.d.ts.map +1 -0
- package/dist/cli/scan.js +265 -0
- package/dist/cli/scan.js.map +1 -0
- package/dist/cli/stock.d.ts +29 -0
- package/dist/cli/stock.d.ts.map +1 -0
- package/dist/cli/stock.js +104 -0
- package/dist/cli/stock.js.map +1 -0
- package/dist/registry.json +25 -25
- package/package.json +8 -1
package/dist/cli/scan.js
ADDED
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import { readdirSync, readFileSync, statSync } from 'node:fs';
|
|
2
|
+
import { relative, resolve, sep } from 'node:path';
|
|
3
|
+
import { findRawColor } from '../eslint/no-raw-color.js';
|
|
4
|
+
import { stockNames, stockTokens } from './stock.js';
|
|
5
|
+
/** Which files are worth reading.
|
|
6
|
+
*
|
|
7
|
+
* CSS is here because the stock vocabulary lives in a stylesheet: a project
|
|
8
|
+
* migrating from shadcn has `--background: 0 0% 100%` in its own theme file,
|
|
9
|
+
* and that is the first thing to find. */
|
|
10
|
+
const EXTENSIONS = new Set(['.ts', '.tsx', '.js', '.jsx', '.css', '.mdx']);
|
|
11
|
+
/** A test file, where a colour is the subject rather than the styling.
|
|
12
|
+
*
|
|
13
|
+
* The linter already exempts these - a test about the accent has to write a
|
|
14
|
+
* hex down to have something to assert - and this has to exempt exactly the
|
|
15
|
+
* same files. Sharing `findRawColor` keeps the two agreeing on what a colour
|
|
16
|
+
* *is*; it cannot make them agree on where one is allowed, and the first live
|
|
17
|
+
* run of `check` reported six violations in dowel's own stand that the linter
|
|
18
|
+
* passes. A report stricter than the build it precedes teaches a reader to
|
|
19
|
+
* ignore it. */
|
|
20
|
+
const TEST_FILE = /\.(?:test|spec)\.[jt]sx?$/;
|
|
21
|
+
/** Directories never worth walking into.
|
|
22
|
+
*
|
|
23
|
+
* `node_modules` would otherwise dominate the report with other people's
|
|
24
|
+
* colours, and a build output would report the same finding a second time from
|
|
25
|
+
* the compiled copy - which reads as two problems where there is one. */
|
|
26
|
+
const SKIP_DIRECTORIES = new Set([
|
|
27
|
+
'node_modules',
|
|
28
|
+
'.git',
|
|
29
|
+
'dist',
|
|
30
|
+
'build',
|
|
31
|
+
'out',
|
|
32
|
+
'.next',
|
|
33
|
+
'.astro',
|
|
34
|
+
'.turbo',
|
|
35
|
+
'coverage',
|
|
36
|
+
'target',
|
|
37
|
+
]);
|
|
38
|
+
/** Every file under `root` worth scanning, as absolute paths, in a stable
|
|
39
|
+
* order - a report that reshuffles between runs cannot be diffed. */
|
|
40
|
+
export function collectFiles(root) {
|
|
41
|
+
const found = [];
|
|
42
|
+
const walk = (directory) => {
|
|
43
|
+
let entries;
|
|
44
|
+
try {
|
|
45
|
+
entries = readdirSync(directory).sort();
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// A directory that cannot be read is not a finding: it is somebody's
|
|
49
|
+
// permissions, and stopping the whole report over it would be worse
|
|
50
|
+
// than the gap.
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
for (const entry of entries) {
|
|
54
|
+
const path = resolve(directory, entry);
|
|
55
|
+
let isDirectory;
|
|
56
|
+
try {
|
|
57
|
+
isDirectory = statSync(path).isDirectory();
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
if (isDirectory) {
|
|
63
|
+
if (SKIP_DIRECTORIES.has(entry) || entry.startsWith('.'))
|
|
64
|
+
continue;
|
|
65
|
+
walk(path);
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
const dot = entry.lastIndexOf('.');
|
|
69
|
+
if (dot < 0)
|
|
70
|
+
continue;
|
|
71
|
+
if (!EXTENSIONS.has(entry.slice(dot)))
|
|
72
|
+
continue;
|
|
73
|
+
found.push(path);
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
walk(root);
|
|
77
|
+
return found;
|
|
78
|
+
}
|
|
79
|
+
/** A stock custom property, as it appears in either half of a project:
|
|
80
|
+
* `--muted-foreground` in a stylesheet, `var(--muted-foreground)` in a style
|
|
81
|
+
* object.
|
|
82
|
+
*
|
|
83
|
+
* Built from the table rather than written out, so a name added there is found
|
|
84
|
+
* here without a second edit. */
|
|
85
|
+
const STOCK_PROPERTY = new RegExp(`--(${stockNames.join('|')})\\b`, 'g');
|
|
86
|
+
/** The same names as Tailwind utilities, which is how they reach a component:
|
|
87
|
+
* `bg-muted`, `text-muted-foreground`, `border-input`, `hover:bg-accent`.
|
|
88
|
+
*
|
|
89
|
+
* The prefix list is what Tailwind actually generates from a colour token, and
|
|
90
|
+
* the opening character class is what keeps `bg-primary` from matching inside
|
|
91
|
+
* `custom-bg-primary`. */
|
|
92
|
+
const UTILITY_PREFIXES = 'bg|text|border|fill|stroke|ring|outline|divide|shadow|from|via|to|accent|caret|decoration';
|
|
93
|
+
const STOCK_UTILITY = new RegExp(`(?:^|[\\s"'\`:\\[({])((?:${UTILITY_PREFIXES})-(?:${stockNames.join('|')}))\\b`, 'g');
|
|
94
|
+
/** Turn an offset into a 1-based line and column. */
|
|
95
|
+
function locate(source, index) {
|
|
96
|
+
let line = 1;
|
|
97
|
+
let lineStart = 0;
|
|
98
|
+
for (let i = 0; i < index; i += 1) {
|
|
99
|
+
if (source.charCodeAt(i) === 10 /* \n */) {
|
|
100
|
+
line += 1;
|
|
101
|
+
lineStart = i + 1;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return { line, column: index - lineStart + 1 };
|
|
105
|
+
}
|
|
106
|
+
/** Every string literal in a source file, with where it starts.
|
|
107
|
+
*
|
|
108
|
+
* This is the textual stand-in for the rule's `Literal` and `TemplateElement`
|
|
109
|
+
* visitors, and it exists so that a colour is only reported where a colour
|
|
110
|
+
* could actually be written - in a string - rather than anywhere the
|
|
111
|
+
* characters happen to appear. Without it, a comment explaining the rule would
|
|
112
|
+
* be a finding: it has to write a colour down to say which ones are forbidden.
|
|
113
|
+
*
|
|
114
|
+
* It is a small scanner rather than a regular expression because quotes nest:
|
|
115
|
+
* an apostrophe inside double quotes is one string, not two.
|
|
116
|
+
*/
|
|
117
|
+
export function stringLiterals(source) {
|
|
118
|
+
const literals = [];
|
|
119
|
+
let i = 0;
|
|
120
|
+
while (i < source.length) {
|
|
121
|
+
const char = source[i];
|
|
122
|
+
// A line comment: skip to the newline. Nothing in it is a literal, and a
|
|
123
|
+
// commented-out colour is not a colour on a screen.
|
|
124
|
+
if (char === '/' && source[i + 1] === '/') {
|
|
125
|
+
while (i < source.length && source[i] !== '\n')
|
|
126
|
+
i += 1;
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
// A block comment. An opener inside a string is handled by the branch
|
|
130
|
+
// below taking the whole string first.
|
|
131
|
+
if (char === '/' && source[i + 1] === '*') {
|
|
132
|
+
const end = source.indexOf('*/', i + 2);
|
|
133
|
+
i = end < 0 ? source.length : end + 2;
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
if (char === '"' || char === "'" || char === '`') {
|
|
137
|
+
const quote = char;
|
|
138
|
+
const start = i + 1;
|
|
139
|
+
i = start;
|
|
140
|
+
while (i < source.length) {
|
|
141
|
+
if (source[i] === '\\') {
|
|
142
|
+
i += 2;
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
if (source[i] === quote)
|
|
146
|
+
break;
|
|
147
|
+
i += 1;
|
|
148
|
+
}
|
|
149
|
+
literals.push({ text: source.slice(start, i), index: start });
|
|
150
|
+
i += 1;
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
i += 1;
|
|
154
|
+
}
|
|
155
|
+
return literals;
|
|
156
|
+
}
|
|
157
|
+
/** What to say about one match.
|
|
158
|
+
*
|
|
159
|
+
* One builder for both shapes a stock name takes, so that a custom property
|
|
160
|
+
* and the utility spelling of the same name cannot end up described
|
|
161
|
+
* differently - which they were, and the ambiguous case was the one that
|
|
162
|
+
* suffered: both branches said "has no dowel equivalent", and a name that
|
|
163
|
+
* exists in both vocabularies has the opposite problem.
|
|
164
|
+
*
|
|
165
|
+
* `subject` is the text as it was written, `prefix` is what a replacement has
|
|
166
|
+
* to keep in front of the token (`--`, or `bg-`). */
|
|
167
|
+
function describe(subject, prefix, replacement) {
|
|
168
|
+
switch (replacement.kind) {
|
|
169
|
+
case 'token':
|
|
170
|
+
return `\`${subject}\` is the stock shadcn vocabulary; dowel calls this \`${prefix}${replacement.token}\`.`;
|
|
171
|
+
case 'unmapped':
|
|
172
|
+
return `\`${subject}\` is the stock shadcn vocabulary and has no dowel equivalent - ${replacement.note}`;
|
|
173
|
+
case 'ambiguous':
|
|
174
|
+
return `\`${subject}\` exists in both vocabularies: ${replacement.note}`;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
/** Read one file and say what is wrong with it. */
|
|
178
|
+
export function scanSource(source, file) {
|
|
179
|
+
const findings = [];
|
|
180
|
+
const isStylesheet = file.endsWith('.css');
|
|
181
|
+
/* Stock names are still reported in a test - a test on the old vocabulary
|
|
182
|
+
* has to be migrated with everything else. Only the colour pass is exempt. */
|
|
183
|
+
const isTest = TEST_FILE.test(file);
|
|
184
|
+
const add = (kind, index, text, message, replacement) => {
|
|
185
|
+
const { line, column } = locate(source, index);
|
|
186
|
+
findings.push({ file, line, column, kind, text, message, replacement });
|
|
187
|
+
};
|
|
188
|
+
/* Stock custom properties, anywhere in the file. In a stylesheet that is a
|
|
189
|
+
* declaration; in a component it is a `var()` call. Both are the same
|
|
190
|
+
* finding and take the same fix. */
|
|
191
|
+
for (const match of source.matchAll(STOCK_PROPERTY)) {
|
|
192
|
+
const name = match[1];
|
|
193
|
+
const replacement = stockTokens[name];
|
|
194
|
+
add('stock', match.index, match[0], describe(`--${name}`, '--', replacement), replacement);
|
|
195
|
+
}
|
|
196
|
+
/* The same names as utilities. Only in code: a stylesheet writing
|
|
197
|
+
* `bg-primary` is writing about a class, usually in an `@apply`, and the
|
|
198
|
+
* custom-property pass above has already spoken about the same file. */
|
|
199
|
+
if (!isStylesheet) {
|
|
200
|
+
for (const match of source.matchAll(STOCK_UTILITY)) {
|
|
201
|
+
const utility = match[1];
|
|
202
|
+
const name = stockNames.find((candidate) => utility.endsWith(`-${candidate}`));
|
|
203
|
+
if (!name)
|
|
204
|
+
continue;
|
|
205
|
+
const replacement = stockTokens[name];
|
|
206
|
+
const prefix = utility.slice(0, utility.length - name.length);
|
|
207
|
+
add('stock', match.index + match[0].indexOf(utility), utility, describe(utility, prefix, replacement), replacement);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
/* Colours written down. In code this reads string literals, exactly like the
|
|
211
|
+
* rule does; a stylesheet is read whole, because that is where a colour
|
|
212
|
+
* appears outside any string - and where, in a theme file, it is supposed
|
|
213
|
+
* to. */
|
|
214
|
+
if (isTest) {
|
|
215
|
+
// Nothing: a test writes colours down on purpose, and the linter exempts
|
|
216
|
+
// the same files.
|
|
217
|
+
}
|
|
218
|
+
else if (isStylesheet) {
|
|
219
|
+
// A stylesheet that defines the dowel tokens is the one place raw colour
|
|
220
|
+
// belongs. Recognised by what it declares rather than by its name: a
|
|
221
|
+
// product may call its theme anything.
|
|
222
|
+
const definesTheme = /--accent-base\s*:/.test(source);
|
|
223
|
+
if (!definesTheme) {
|
|
224
|
+
for (const [index, line] of source.split('\n').entries()) {
|
|
225
|
+
const finding = findRawColor(line);
|
|
226
|
+
if (finding) {
|
|
227
|
+
findings.push({
|
|
228
|
+
file,
|
|
229
|
+
line: index + 1,
|
|
230
|
+
column: 1,
|
|
231
|
+
kind: 'color',
|
|
232
|
+
text: line.trim(),
|
|
233
|
+
message: finding.message,
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
for (const literal of stringLiterals(source)) {
|
|
241
|
+
const finding = findRawColor(literal.text);
|
|
242
|
+
if (finding)
|
|
243
|
+
add('color', literal.index, literal.text.trim(), finding.message);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return findings.sort((a, b) => a.line - b.line || a.column - b.column);
|
|
247
|
+
}
|
|
248
|
+
/** Scan a whole project. Paths in the findings are relative to `root`, with
|
|
249
|
+
* forward slashes, so a report reads the same on either platform. */
|
|
250
|
+
export function scanProject(root) {
|
|
251
|
+
const findings = [];
|
|
252
|
+
for (const file of collectFiles(root)) {
|
|
253
|
+
let source;
|
|
254
|
+
try {
|
|
255
|
+
source = readFileSync(file, 'utf8');
|
|
256
|
+
}
|
|
257
|
+
catch {
|
|
258
|
+
continue;
|
|
259
|
+
}
|
|
260
|
+
const name = relative(root, file).split(sep).join('/');
|
|
261
|
+
findings.push(...scanSource(source, name));
|
|
262
|
+
}
|
|
263
|
+
return findings;
|
|
264
|
+
}
|
|
265
|
+
//# sourceMappingURL=scan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../../src/cli/scan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/** What to do with a stock name that has been found. */
|
|
2
|
+
export type Replacement =
|
|
3
|
+
/** A straight rename: this stock name means that dowel token. */
|
|
4
|
+
{
|
|
5
|
+
readonly kind: 'token';
|
|
6
|
+
readonly token: string;
|
|
7
|
+
readonly note?: string;
|
|
8
|
+
}
|
|
9
|
+
/** Stock-only, and dowel has nothing that means it yet. */
|
|
10
|
+
| {
|
|
11
|
+
readonly kind: 'unmapped';
|
|
12
|
+
readonly note: string;
|
|
13
|
+
}
|
|
14
|
+
/** The name exists in both vocabularies. Reported with its ambiguity spelled
|
|
15
|
+
* out; never rewritten, because the tool cannot tell which one it is
|
|
16
|
+
* looking at and a wrong guess breaks a correct project. */
|
|
17
|
+
| {
|
|
18
|
+
readonly kind: 'ambiguous';
|
|
19
|
+
readonly stockMeaning: string;
|
|
20
|
+
readonly note: string;
|
|
21
|
+
};
|
|
22
|
+
export declare const stockTokens: Readonly<Record<string, Replacement>>;
|
|
23
|
+
/** The stock names, longest first.
|
|
24
|
+
*
|
|
25
|
+
* Order matters wherever these are matched one after another: `--sidebar` is a
|
|
26
|
+
* prefix of `--sidebar-border`, and trying the short one first would rewrite
|
|
27
|
+
* half of the long one and leave `-border` dangling. */
|
|
28
|
+
export declare const stockNames: readonly string[];
|
|
29
|
+
//# sourceMappingURL=stock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stock.d.ts","sourceRoot":"","sources":["../../src/cli/stock.ts"],"names":[],"mappings":"AAoCA,wDAAwD;AACxD,MAAM,MAAM,WAAW;AACrB,iEAAiE;AAC/D;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE;AAC5E,2DAA2D;GACzD;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE;AACtD;;4DAE4D;GAC1D;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAYxF,eAAO,MAAM,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CA2D7D,CAAA;AAED;;;;wDAIwD;AACxD,eAAO,MAAM,UAAU,EAAE,SAAS,MAAM,EAEvC,CAAA"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* The stock shadcn vocabulary, and what it means here.
|
|
3
|
+
*
|
|
4
|
+
* A product arriving at dowel almost never arrives from nothing. It arrives
|
|
5
|
+
* from stock shadcn/ui, whose theme names colours by their role in a page -
|
|
6
|
+
* `--background`, `--muted-foreground`, `--card` - and whose components are
|
|
7
|
+
* written against those names. dowel names them by what they are on a screen
|
|
8
|
+
* instead: a ground, a raised surface, dimmed ink. The two vocabularies
|
|
9
|
+
* overlap almost entirely in meaning and not at all in spelling.
|
|
10
|
+
*
|
|
11
|
+
* So the first thing a migration needs is this table, and it has to live in
|
|
12
|
+
* one place: `check` reports what it finds, `codemod` rewrites it, and the two
|
|
13
|
+
* disagreeing would be worse than either alone - a report that names a
|
|
14
|
+
* replacement the rewriter does not make.
|
|
15
|
+
*
|
|
16
|
+
* The mapping is deliberately incomplete in two directions.
|
|
17
|
+
*
|
|
18
|
+
* Every stock name is listed, because the point is to find all of them; but a
|
|
19
|
+
* few have no honest equivalent and say so, because guessing one would put a
|
|
20
|
+
* wrong colour on a screen and call the migration done. `--chart-1` is the
|
|
21
|
+
* clearest case: dowel has no chart palette until the charts version, and
|
|
22
|
+
* mapping it to the accent would make five series the same colour.
|
|
23
|
+
*
|
|
24
|
+
* And two names exist in *both* vocabularies meaning different things, which a
|
|
25
|
+
* table keyed by name cannot resolve. `--accent` is stock shadcn's hover fill
|
|
26
|
+
* and it is also dowel's flagship token - the product's own hue. A scanner
|
|
27
|
+
* reading names alone sees no difference between a project that has not
|
|
28
|
+
* migrated and one that has, so these are reported for a human to judge and
|
|
29
|
+
* never rewritten.
|
|
30
|
+
*
|
|
31
|
+
* That distinction is not theoretical: the first live run of `check` reported
|
|
32
|
+
* twenty-four violations in dowel's own stand, every one of them a correct use
|
|
33
|
+
* of `--accent`, and `codemod --write` would have rewritten them to `--soft`
|
|
34
|
+
* and broken a project that was already right.
|
|
35
|
+
*/
|
|
36
|
+
/*
|
|
37
|
+
* The table, in the order the tokens read on a screen: grounds, then surfaces,
|
|
38
|
+
* then ink, then the accent, then status, then the odd ones out.
|
|
39
|
+
*
|
|
40
|
+
* `--foreground` and `--background` are the pair everything else is defined
|
|
41
|
+
* against in stock shadcn, and they are the pair that most often survives a
|
|
42
|
+
* half-finished migration: a product swaps its components over and leaves the
|
|
43
|
+
* page itself on the old names, so the screen has two grounds that agree only
|
|
44
|
+
* by accident of both being near-black.
|
|
45
|
+
*/
|
|
46
|
+
export const stockTokens = {
|
|
47
|
+
background: { kind: 'token', token: 'bg' },
|
|
48
|
+
foreground: { kind: 'token', token: 'text' },
|
|
49
|
+
card: { kind: 'token', token: 'raise' },
|
|
50
|
+
'card-foreground': { kind: 'token', token: 'text' },
|
|
51
|
+
popover: { kind: 'token', token: 'raise' },
|
|
52
|
+
'popover-foreground': { kind: 'token', token: 'text' },
|
|
53
|
+
muted: { kind: 'token', token: 'soft' },
|
|
54
|
+
'muted-foreground': { kind: 'token', token: 'dim' },
|
|
55
|
+
border: { kind: 'token', token: 'line' },
|
|
56
|
+
input: { kind: 'token', token: 'line' },
|
|
57
|
+
ring: {
|
|
58
|
+
kind: 'token',
|
|
59
|
+
token: 'accent',
|
|
60
|
+
note: 'dowel draws focus from the accent; there is no separate ring colour.',
|
|
61
|
+
},
|
|
62
|
+
primary: { kind: 'token', token: 'accent' },
|
|
63
|
+
'primary-foreground': { kind: 'token', token: 'on-accent' },
|
|
64
|
+
secondary: { kind: 'token', token: 'soft' },
|
|
65
|
+
'secondary-foreground': { kind: 'token', token: 'text' },
|
|
66
|
+
/* The collision. Both vocabularies have this name and they mean opposite
|
|
67
|
+
* things: stock `--accent` is the quiet fill a row takes on hover, dowel's
|
|
68
|
+
* `--accent` is the product's own colour - the loudest thing on the screen.
|
|
69
|
+
* Rewriting it blindly turns every accent in a migrated project into a grey,
|
|
70
|
+
* so it is reported and left alone. */
|
|
71
|
+
accent: {
|
|
72
|
+
kind: 'ambiguous',
|
|
73
|
+
stockMeaning: 'soft',
|
|
74
|
+
note: "stock `--accent` is a hover fill; dowel's `--accent` is the product's own hue. If this project has not migrated yet, it means `--soft`; if it has, it is already right.",
|
|
75
|
+
},
|
|
76
|
+
'accent-foreground': {
|
|
77
|
+
kind: 'ambiguous',
|
|
78
|
+
stockMeaning: 'text',
|
|
79
|
+
note: "stock `--accent-foreground` is ink on a hover fill; dowel has `--on-accent` for ink on the accent itself. Which one this is depends on whether the project has migrated.",
|
|
80
|
+
},
|
|
81
|
+
destructive: { kind: 'token', token: 'bad' },
|
|
82
|
+
'destructive-foreground': { kind: 'token', token: 'on-bad' },
|
|
83
|
+
radius: { kind: 'token', token: 'radius-md', note: 'the control radius.' },
|
|
84
|
+
'chart-1': { kind: 'unmapped', note: 'dowel has no chart palette yet; leave it until the charts version.' },
|
|
85
|
+
'chart-2': { kind: 'unmapped', note: 'dowel has no chart palette yet; leave it until the charts version.' },
|
|
86
|
+
'chart-3': { kind: 'unmapped', note: 'dowel has no chart palette yet; leave it until the charts version.' },
|
|
87
|
+
'chart-4': { kind: 'unmapped', note: 'dowel has no chart palette yet; leave it until the charts version.' },
|
|
88
|
+
'chart-5': { kind: 'unmapped', note: 'dowel has no chart palette yet; leave it until the charts version.' },
|
|
89
|
+
sidebar: { kind: 'token', token: 'raise' },
|
|
90
|
+
'sidebar-foreground': { kind: 'token', token: 'text' },
|
|
91
|
+
'sidebar-primary': { kind: 'token', token: 'accent' },
|
|
92
|
+
'sidebar-primary-foreground': { kind: 'token', token: 'on-accent' },
|
|
93
|
+
'sidebar-accent': { kind: 'token', token: 'soft' },
|
|
94
|
+
'sidebar-accent-foreground': { kind: 'token', token: 'text' },
|
|
95
|
+
'sidebar-border': { kind: 'token', token: 'line' },
|
|
96
|
+
'sidebar-ring': { kind: 'token', token: 'accent' },
|
|
97
|
+
};
|
|
98
|
+
/** The stock names, longest first.
|
|
99
|
+
*
|
|
100
|
+
* Order matters wherever these are matched one after another: `--sidebar` is a
|
|
101
|
+
* prefix of `--sidebar-border`, and trying the short one first would rewrite
|
|
102
|
+
* half of the long one and leave `-border` dangling. */
|
|
103
|
+
export const stockNames = Object.keys(stockTokens).sort((a, b) => b.length - a.length || a.localeCompare(b));
|
|
104
|
+
//# sourceMappingURL=stock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stock.js","sourceRoot":"","sources":["../../src/cli/stock.ts"],"names":[],"mappings":"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"}
|
package/dist/registry.json
CHANGED
|
@@ -222,7 +222,7 @@
|
|
|
222
222
|
"description": "A message that stays on the screen, in the flow of the page, about the thing next to it: this field could not be saved, this profile has no axes yet, this export is out of date.",
|
|
223
223
|
"dependencies": [
|
|
224
224
|
"class-variance-authority",
|
|
225
|
-
"dowel-ui@^0.
|
|
225
|
+
"dowel-ui@^0.14.0"
|
|
226
226
|
],
|
|
227
227
|
"registryDependencies": [],
|
|
228
228
|
"files": [
|
|
@@ -241,7 +241,7 @@
|
|
|
241
241
|
"description": "A small piece of state attached to something else: a count, a status, a label. It is not a button and never was - if it can be clicked it is a Chip.",
|
|
242
242
|
"dependencies": [
|
|
243
243
|
"class-variance-authority",
|
|
244
|
-
"dowel-ui@^0.
|
|
244
|
+
"dowel-ui@^0.14.0"
|
|
245
245
|
],
|
|
246
246
|
"registryDependencies": [],
|
|
247
247
|
"files": [
|
|
@@ -260,7 +260,7 @@
|
|
|
260
260
|
"description": "A strip across the top of the application, about the application: you are offline, this build is a preview, your licence expires on Friday, a new version is ready to install.",
|
|
261
261
|
"dependencies": [
|
|
262
262
|
"class-variance-authority",
|
|
263
|
-
"dowel-ui@^0.
|
|
263
|
+
"dowel-ui@^0.14.0"
|
|
264
264
|
],
|
|
265
265
|
"registryDependencies": [],
|
|
266
266
|
"files": [
|
|
@@ -280,7 +280,7 @@
|
|
|
280
280
|
"dependencies": [
|
|
281
281
|
"@base-ui/react",
|
|
282
282
|
"class-variance-authority",
|
|
283
|
-
"dowel-ui@^0.
|
|
283
|
+
"dowel-ui@^0.14.0"
|
|
284
284
|
],
|
|
285
285
|
"registryDependencies": [],
|
|
286
286
|
"files": [
|
|
@@ -299,7 +299,7 @@
|
|
|
299
299
|
"description": "A badge you can act on: a filter that can be removed, a tag with a count, a selected value in a field. The difference from a Badge is entirely about whether something happens when you click it - and if something does, that part is a real `<button>` with a real label, not a decorative cross.",
|
|
300
300
|
"dependencies": [
|
|
301
301
|
"class-variance-authority",
|
|
302
|
-
"dowel-ui@^0.
|
|
302
|
+
"dowel-ui@^0.14.0"
|
|
303
303
|
],
|
|
304
304
|
"registryDependencies": [],
|
|
305
305
|
"files": [
|
|
@@ -319,7 +319,7 @@
|
|
|
319
319
|
"dependencies": [
|
|
320
320
|
"@base-ui/react",
|
|
321
321
|
"class-variance-authority",
|
|
322
|
-
"dowel-ui@^0.
|
|
322
|
+
"dowel-ui@^0.14.0"
|
|
323
323
|
],
|
|
324
324
|
"registryDependencies": [
|
|
325
325
|
"https://lacodda.github.io/dowel/r/input.json",
|
|
@@ -342,7 +342,7 @@
|
|
|
342
342
|
"dependencies": [
|
|
343
343
|
"@base-ui/react",
|
|
344
344
|
"class-variance-authority",
|
|
345
|
-
"dowel-ui@^0.
|
|
345
|
+
"dowel-ui@^0.14.0"
|
|
346
346
|
],
|
|
347
347
|
"registryDependencies": [
|
|
348
348
|
"https://lacodda.github.io/dowel/r/combobox.json",
|
|
@@ -365,7 +365,7 @@
|
|
|
365
365
|
"dependencies": [
|
|
366
366
|
"@base-ui/react",
|
|
367
367
|
"class-variance-authority",
|
|
368
|
-
"dowel-ui@^0.
|
|
368
|
+
"dowel-ui@^0.14.0"
|
|
369
369
|
],
|
|
370
370
|
"registryDependencies": [],
|
|
371
371
|
"files": [
|
|
@@ -384,7 +384,7 @@
|
|
|
384
384
|
"description": "The same list of actions as Menu, opened the other way round: by right click, or by a long press on a touch screen, over an *area* rather than from a button. So the trigger is not a control - it is the region the menu belongs to, a row, a canvas, a file tile - and it renders a `<div>`.",
|
|
385
385
|
"dependencies": [
|
|
386
386
|
"@base-ui/react",
|
|
387
|
-
"dowel-ui@^0.
|
|
387
|
+
"dowel-ui@^0.14.0"
|
|
388
388
|
],
|
|
389
389
|
"registryDependencies": [
|
|
390
390
|
"https://lacodda.github.io/dowel/r/menu.json"
|
|
@@ -404,7 +404,7 @@
|
|
|
404
404
|
"title": "Copyable",
|
|
405
405
|
"description": "Any text that someone will eventually want to copy - an id, a path, a hash, a token - copied with one click. The rule comes from nitid: if a value is worth showing, it is worth being able to take away, and selecting a monospaced id by hand is a small daily tax.",
|
|
406
406
|
"dependencies": [
|
|
407
|
-
"dowel-ui@^0.
|
|
407
|
+
"dowel-ui@^0.14.0"
|
|
408
408
|
],
|
|
409
409
|
"registryDependencies": [],
|
|
410
410
|
"files": [
|
|
@@ -424,7 +424,7 @@
|
|
|
424
424
|
"dependencies": [
|
|
425
425
|
"@base-ui/react",
|
|
426
426
|
"class-variance-authority",
|
|
427
|
-
"dowel-ui@^0.
|
|
427
|
+
"dowel-ui@^0.14.0"
|
|
428
428
|
],
|
|
429
429
|
"registryDependencies": [],
|
|
430
430
|
"files": [
|
|
@@ -444,7 +444,7 @@
|
|
|
444
444
|
"dependencies": [
|
|
445
445
|
"@base-ui/react",
|
|
446
446
|
"class-variance-authority",
|
|
447
|
-
"dowel-ui@^0.
|
|
447
|
+
"dowel-ui@^0.14.0"
|
|
448
448
|
],
|
|
449
449
|
"registryDependencies": [],
|
|
450
450
|
"files": [
|
|
@@ -462,7 +462,7 @@
|
|
|
462
462
|
"title": "Input",
|
|
463
463
|
"description": "A single-line field. It is a plain `<input>` with the line's clothes on, so everything a browser gives an input for free - autofill, spellcheck, the right keyboard on a phone, `type=\"email\"` validation - still works.",
|
|
464
464
|
"dependencies": [
|
|
465
|
-
"dowel-ui@^0.
|
|
465
|
+
"dowel-ui@^0.14.0"
|
|
466
466
|
],
|
|
467
467
|
"registryDependencies": [],
|
|
468
468
|
"files": [
|
|
@@ -480,7 +480,7 @@
|
|
|
480
480
|
"title": "Kbd",
|
|
481
481
|
"description": "A key, as printed in a menu or a hint: `Ctrl` `K`. It is a `<kbd>` element because that is what the element is for - a screen reader announces it as keyboard input rather than reading a stray capital letter.",
|
|
482
482
|
"dependencies": [
|
|
483
|
-
"dowel-ui@^0.
|
|
483
|
+
"dowel-ui@^0.14.0"
|
|
484
484
|
],
|
|
485
485
|
"registryDependencies": [],
|
|
486
486
|
"files": [
|
|
@@ -500,7 +500,7 @@
|
|
|
500
500
|
"dependencies": [
|
|
501
501
|
"@base-ui/react",
|
|
502
502
|
"class-variance-authority",
|
|
503
|
-
"dowel-ui@^0.
|
|
503
|
+
"dowel-ui@^0.14.0"
|
|
504
504
|
],
|
|
505
505
|
"registryDependencies": [],
|
|
506
506
|
"files": [
|
|
@@ -519,7 +519,7 @@
|
|
|
519
519
|
"description": "The raised surface everything else sits on. It is the one place a screen gets its structure from, so it stays deliberately plain: a ground, a hairline, a corner.",
|
|
520
520
|
"dependencies": [
|
|
521
521
|
"class-variance-authority",
|
|
522
|
-
"dowel-ui@^0.
|
|
522
|
+
"dowel-ui@^0.14.0"
|
|
523
523
|
],
|
|
524
524
|
"registryDependencies": [],
|
|
525
525
|
"files": [
|
|
@@ -539,7 +539,7 @@
|
|
|
539
539
|
"dependencies": [
|
|
540
540
|
"@base-ui/react",
|
|
541
541
|
"class-variance-authority",
|
|
542
|
-
"dowel-ui@^0.
|
|
542
|
+
"dowel-ui@^0.14.0"
|
|
543
543
|
],
|
|
544
544
|
"registryDependencies": [],
|
|
545
545
|
"files": [
|
|
@@ -559,7 +559,7 @@
|
|
|
559
559
|
"dependencies": [
|
|
560
560
|
"@base-ui/react",
|
|
561
561
|
"class-variance-authority",
|
|
562
|
-
"dowel-ui@^0.
|
|
562
|
+
"dowel-ui@^0.14.0"
|
|
563
563
|
],
|
|
564
564
|
"registryDependencies": [],
|
|
565
565
|
"files": [
|
|
@@ -577,7 +577,7 @@
|
|
|
577
577
|
"title": "Search-field",
|
|
578
578
|
"description": "An Input that knows it is a search box, which is three small things the products kept not doing:\n * - a magnifier, so the field is recognisable before it is read; - a way to clear it that is not \"select all and delete\" - and one that a keyboard can reach, which a decorative `<span>` cannot; - the shortcut that focuses it, shown in the field rather than learned.",
|
|
579
579
|
"dependencies": [
|
|
580
|
-
"dowel-ui@^0.
|
|
580
|
+
"dowel-ui@^0.14.0"
|
|
581
581
|
],
|
|
582
582
|
"registryDependencies": [
|
|
583
583
|
"https://lacodda.github.io/dowel/r/input.json",
|
|
@@ -601,7 +601,7 @@
|
|
|
601
601
|
"dependencies": [
|
|
602
602
|
"@base-ui/react",
|
|
603
603
|
"class-variance-authority",
|
|
604
|
-
"dowel-ui@^0.
|
|
604
|
+
"dowel-ui@^0.14.0"
|
|
605
605
|
],
|
|
606
606
|
"registryDependencies": [
|
|
607
607
|
"https://lacodda.github.io/dowel/r/input.json"
|
|
@@ -638,7 +638,7 @@
|
|
|
638
638
|
"description": "Something is happening and the answer has not arrived. It carries no text of its own - what is loading is the product's word, not the system's - but it does have to say *something* to a screen reader, or a page that is busy is silently identical to a page that is empty.",
|
|
639
639
|
"dependencies": [
|
|
640
640
|
"class-variance-authority",
|
|
641
|
-
"dowel-ui@^0.
|
|
641
|
+
"dowel-ui@^0.14.0"
|
|
642
642
|
],
|
|
643
643
|
"registryDependencies": [],
|
|
644
644
|
"files": [
|
|
@@ -656,7 +656,7 @@
|
|
|
656
656
|
"title": "Textarea",
|
|
657
657
|
"description": "A multi-line field that can grow with what is typed into it, which is the only interesting part: a fixed box makes someone scroll inside a scroll, and a box that grows without limit pushes the button they are trying to reach off the screen. `autoResize` grows it; `maxRows` says when to stop and let it scroll after all.",
|
|
658
658
|
"dependencies": [
|
|
659
|
-
"dowel-ui@^0.
|
|
659
|
+
"dowel-ui@^0.14.0"
|
|
660
660
|
],
|
|
661
661
|
"registryDependencies": [
|
|
662
662
|
"https://lacodda.github.io/dowel/r/input.json"
|
|
@@ -678,7 +678,7 @@
|
|
|
678
678
|
"dependencies": [
|
|
679
679
|
"@base-ui/react",
|
|
680
680
|
"class-variance-authority",
|
|
681
|
-
"dowel-ui@^0.
|
|
681
|
+
"dowel-ui@^0.14.0"
|
|
682
682
|
],
|
|
683
683
|
"registryDependencies": [],
|
|
684
684
|
"files": [
|
|
@@ -698,7 +698,7 @@
|
|
|
698
698
|
"dependencies": [
|
|
699
699
|
"@base-ui/react",
|
|
700
700
|
"class-variance-authority",
|
|
701
|
-
"dowel-ui@^0.
|
|
701
|
+
"dowel-ui@^0.14.0"
|
|
702
702
|
],
|
|
703
703
|
"registryDependencies": [],
|
|
704
704
|
"files": [
|
|
@@ -716,7 +716,7 @@
|
|
|
716
716
|
"title": "Truncate",
|
|
717
717
|
"description": "Text that does not fit, cut with an ellipsis - and, importantly, still readable in full: the element carries its own text as a `title`, so hovering shows what was cut. Every product wrote the one-line version of this and none of them remembered the title.",
|
|
718
718
|
"dependencies": [
|
|
719
|
-
"dowel-ui@^0.
|
|
719
|
+
"dowel-ui@^0.14.0"
|
|
720
720
|
],
|
|
721
721
|
"registryDependencies": [],
|
|
722
722
|
"files": [
|