rainbowindex 0.2.0 → 0.2.2
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/CHANGELOG.md +152 -0
- package/README.md +34 -0
- package/dist/browser.d.ts +2 -1
- package/dist/browser.mjs +1 -1
- package/dist/{chunk-KCSNR2TV.mjs → chunk-CUUW2K35.mjs} +17 -7
- package/dist/chunk-FHATRQMN.mjs +1635 -0
- package/dist/chunk-KYDEHYIE.mjs +691 -0
- package/dist/{chunk-5N4GPK26.mjs → chunk-SOMDX7V6.mjs} +74 -16
- package/dist/{chunk-RPXZ3O6R.mjs → chunk-W6XIBM4M.mjs} +6118 -7201
- package/dist/cli.mjs +72 -40
- package/dist/editor.d.ts +464 -0
- package/dist/editor.mjs +402 -0
- package/dist/{safelist-DRk1XXxi.d.ts → index-CfDtWufj.d.ts} +29 -43
- package/dist/index-DK6APAGD.d.ts +260 -0
- package/dist/index.d.ts +5 -253
- package/dist/index.mjs +8 -6
- package/dist/safelist-CH3_PywB.d.ts +43 -0
- package/dist/vite.mjs +4 -3
- package/package.json +107 -101
package/dist/editor.mjs
ADDED
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CSS_ENTRY_CANDIDATES,
|
|
3
|
+
UTILITY_VALUE_SPACES,
|
|
4
|
+
enumerateClassNames
|
|
5
|
+
} from "./chunk-KYDEHYIE.mjs";
|
|
6
|
+
import {
|
|
7
|
+
CLASS_HELPER_NAMES,
|
|
8
|
+
RI_IMPORT_SPECIFIERS,
|
|
9
|
+
STATIC_UTILITIES,
|
|
10
|
+
VARIANT_HELPER_NAMES,
|
|
11
|
+
analyzeProjectCSS,
|
|
12
|
+
buildBreakpointWeights,
|
|
13
|
+
compileUtility,
|
|
14
|
+
createEmptyCompilationResult,
|
|
15
|
+
createThemeSnapshot,
|
|
16
|
+
diagnosticFromWarning,
|
|
17
|
+
expandVariantGroups,
|
|
18
|
+
extractClassCandidates,
|
|
19
|
+
extractClasses,
|
|
20
|
+
extractClassesFromSource,
|
|
21
|
+
findClosest,
|
|
22
|
+
hasRIActivation,
|
|
23
|
+
isSourceFile,
|
|
24
|
+
listVariants,
|
|
25
|
+
parseUtility,
|
|
26
|
+
severityForCode,
|
|
27
|
+
warningCode
|
|
28
|
+
} from "./chunk-W6XIBM4M.mjs";
|
|
29
|
+
import {
|
|
30
|
+
analyzeMerge,
|
|
31
|
+
computeDarkStop,
|
|
32
|
+
defaultTheme,
|
|
33
|
+
formatOklch,
|
|
34
|
+
generateStop,
|
|
35
|
+
linearToSrgb,
|
|
36
|
+
oklabToLinearSrgb,
|
|
37
|
+
oklchToOklab
|
|
38
|
+
} from "./chunk-SOMDX7V6.mjs";
|
|
39
|
+
|
|
40
|
+
// src/engine/inspector.ts
|
|
41
|
+
var RESOLUTION_CACHE_CAP = 1e4;
|
|
42
|
+
var OK = Object.freeze({ ok: true });
|
|
43
|
+
function createClassInspector(theme) {
|
|
44
|
+
const customVariantMap = new Map(theme.customVariants.map((cv) => [cv.name, cv]));
|
|
45
|
+
const breakpointWeights = buildBreakpointWeights(theme.breakpoints);
|
|
46
|
+
const variantMemo = /* @__PURE__ */ new Map();
|
|
47
|
+
const scratch = createEmptyCompilationResult();
|
|
48
|
+
const warnSeen = /* @__PURE__ */ new Set();
|
|
49
|
+
const detail = { reason: null, variant: null, declarations: null };
|
|
50
|
+
const cache = /* @__PURE__ */ new Map();
|
|
51
|
+
let variantList = null;
|
|
52
|
+
let variantNames = null;
|
|
53
|
+
let utilityCorpus = null;
|
|
54
|
+
function variants() {
|
|
55
|
+
if (!variantList) variantList = Object.freeze(listVariants(theme));
|
|
56
|
+
return variantList;
|
|
57
|
+
}
|
|
58
|
+
function variantSuggestionCorpus() {
|
|
59
|
+
if (!variantNames) {
|
|
60
|
+
variantNames = variants().filter((v) => v.kind !== "pattern").map((v) => v.name);
|
|
61
|
+
}
|
|
62
|
+
return variantNames;
|
|
63
|
+
}
|
|
64
|
+
function utilitySuggestionCorpus() {
|
|
65
|
+
if (!utilityCorpus) {
|
|
66
|
+
utilityCorpus = [
|
|
67
|
+
...STATIC_UTILITIES,
|
|
68
|
+
...theme.customUtilities.filter((u) => !u.functional).map((u) => u.name)
|
|
69
|
+
];
|
|
70
|
+
}
|
|
71
|
+
return utilityCorpus;
|
|
72
|
+
}
|
|
73
|
+
function baseName(raw, parsed) {
|
|
74
|
+
let base = raw;
|
|
75
|
+
if (parsed.variants.length > 0) {
|
|
76
|
+
const prefix = `${parsed.variants.join(":")}:`;
|
|
77
|
+
if (base.startsWith(prefix)) base = base.slice(prefix.length);
|
|
78
|
+
}
|
|
79
|
+
if (parsed.important && base.endsWith("!")) base = base.slice(0, -1);
|
|
80
|
+
return base;
|
|
81
|
+
}
|
|
82
|
+
function resolve(className) {
|
|
83
|
+
const cached = cache.get(className);
|
|
84
|
+
if (cached) return cached;
|
|
85
|
+
if (cache.size >= RESOLUTION_CACHE_CAP) {
|
|
86
|
+
cache.clear();
|
|
87
|
+
variantMemo.clear();
|
|
88
|
+
}
|
|
89
|
+
scratch.warnings.length = 0;
|
|
90
|
+
warnSeen.clear();
|
|
91
|
+
const parsed = parseUtility(className);
|
|
92
|
+
const rule = compileUtility(
|
|
93
|
+
parsed,
|
|
94
|
+
theme,
|
|
95
|
+
scratch,
|
|
96
|
+
customVariantMap,
|
|
97
|
+
warnSeen,
|
|
98
|
+
breakpointWeights,
|
|
99
|
+
variantMemo,
|
|
100
|
+
detail
|
|
101
|
+
);
|
|
102
|
+
let entry;
|
|
103
|
+
if (rule) {
|
|
104
|
+
entry = {
|
|
105
|
+
validation: OK,
|
|
106
|
+
explanation: {
|
|
107
|
+
parsed,
|
|
108
|
+
declarations: detail.declarations ? [...detail.declarations] : [],
|
|
109
|
+
selector: rule.selector,
|
|
110
|
+
css: rule.css,
|
|
111
|
+
sortKey: rule.sortKey
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
} else if (detail.reason === "unknown-variant" && detail.variant !== null) {
|
|
115
|
+
const suggestion = findClosest(detail.variant, variantSuggestionCorpus());
|
|
116
|
+
entry = {
|
|
117
|
+
validation: {
|
|
118
|
+
ok: false,
|
|
119
|
+
reason: "unknown-variant",
|
|
120
|
+
offender: detail.variant,
|
|
121
|
+
...suggestion ? { suggestion } : {}
|
|
122
|
+
},
|
|
123
|
+
explanation: null
|
|
124
|
+
};
|
|
125
|
+
} else {
|
|
126
|
+
const base = baseName(className, parsed);
|
|
127
|
+
if (parsed.arbitrary || parsed.arbitraryProperty !== null) {
|
|
128
|
+
entry = {
|
|
129
|
+
validation: { ok: false, reason: "invalid-arbitrary", offender: base },
|
|
130
|
+
explanation: null
|
|
131
|
+
};
|
|
132
|
+
} else {
|
|
133
|
+
const suggestion = findClosest(base, utilitySuggestionCorpus());
|
|
134
|
+
entry = {
|
|
135
|
+
validation: {
|
|
136
|
+
ok: false,
|
|
137
|
+
reason: "unknown-utility",
|
|
138
|
+
offender: base,
|
|
139
|
+
...suggestion ? { suggestion } : {}
|
|
140
|
+
},
|
|
141
|
+
explanation: null
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
cache.set(className, entry);
|
|
146
|
+
return entry;
|
|
147
|
+
}
|
|
148
|
+
return {
|
|
149
|
+
theme,
|
|
150
|
+
validate: (className) => resolve(className).validation,
|
|
151
|
+
explain: (className) => resolve(className).explanation,
|
|
152
|
+
variants
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// src/theme/swatch.ts
|
|
157
|
+
var CANONICAL_COLOR_STOPS = Object.freeze([
|
|
158
|
+
50,
|
|
159
|
+
100,
|
|
160
|
+
150,
|
|
161
|
+
200,
|
|
162
|
+
250,
|
|
163
|
+
300,
|
|
164
|
+
350,
|
|
165
|
+
400,
|
|
166
|
+
450,
|
|
167
|
+
500,
|
|
168
|
+
550,
|
|
169
|
+
600,
|
|
170
|
+
650,
|
|
171
|
+
700,
|
|
172
|
+
750,
|
|
173
|
+
800,
|
|
174
|
+
850,
|
|
175
|
+
900,
|
|
176
|
+
950
|
|
177
|
+
]);
|
|
178
|
+
function channelHex(value) {
|
|
179
|
+
return Math.round(Math.min(1, Math.max(0, value)) * 255).toString(16).padStart(2, "0");
|
|
180
|
+
}
|
|
181
|
+
function oklchToHex(l, c, h) {
|
|
182
|
+
const [labL, labA, labB] = oklchToOklab(l, c, h);
|
|
183
|
+
const [r, g, b] = oklabToLinearSrgb(labL, labA, labB);
|
|
184
|
+
return `#${channelHex(linearToSrgb(r))}${channelHex(linearToSrgb(g))}${channelHex(linearToSrgb(b))}`;
|
|
185
|
+
}
|
|
186
|
+
var OKLCH_TEXT_RE = /^oklch\(\s*([\d.]+%?)\s+([\d.]+)\s+([\d.-]+)\s*(?:\/\s*[\d.]+%?\s*)?\)$/i;
|
|
187
|
+
var HEX_TEXT_RE = /^#(?:[0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/i;
|
|
188
|
+
function cssColorToHex(css) {
|
|
189
|
+
const text = css.trim();
|
|
190
|
+
if (HEX_TEXT_RE.test(text)) {
|
|
191
|
+
if (text.length === 4 || text.length === 5) {
|
|
192
|
+
return `#${text[1]}${text[1]}${text[2]}${text[2]}${text[3]}${text[3]}`.toLowerCase();
|
|
193
|
+
}
|
|
194
|
+
return text.slice(0, 7).toLowerCase();
|
|
195
|
+
}
|
|
196
|
+
const match = OKLCH_TEXT_RE.exec(text);
|
|
197
|
+
if (match) {
|
|
198
|
+
const rawL = match[1];
|
|
199
|
+
const l = rawL.endsWith("%") ? Number.parseFloat(rawL) / 100 : Number.parseFloat(rawL);
|
|
200
|
+
const c = Number.parseFloat(match[2]);
|
|
201
|
+
const h = Number.parseFloat(match[3]);
|
|
202
|
+
if (Number.isFinite(l) && Number.isFinite(c) && Number.isFinite(h)) {
|
|
203
|
+
return oklchToHex(l, c, h);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return null;
|
|
207
|
+
}
|
|
208
|
+
var MAX_ALIAS_HOPS = 8;
|
|
209
|
+
var SEMANTIC_SWATCHES = Object.freeze({
|
|
210
|
+
paper: {
|
|
211
|
+
light: { css: "oklch(1 0 0)", hex: "#ffffff" },
|
|
212
|
+
dark: { css: "oklch(0 0 0)", hex: "#000000" }
|
|
213
|
+
},
|
|
214
|
+
ink: {
|
|
215
|
+
light: { css: "oklch(0 0 0)", hex: "#000000" },
|
|
216
|
+
dark: { css: "oklch(1 0 0)", hex: "#ffffff" }
|
|
217
|
+
},
|
|
218
|
+
white: {
|
|
219
|
+
light: { css: "oklch(1 0 0)", hex: "#ffffff" },
|
|
220
|
+
dark: null
|
|
221
|
+
},
|
|
222
|
+
black: {
|
|
223
|
+
light: { css: "oklch(0 0 0)", hex: "#000000" },
|
|
224
|
+
dark: null
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
function swatchFromCss(css) {
|
|
228
|
+
return { css, hex: cssColorToHex(css) };
|
|
229
|
+
}
|
|
230
|
+
function resolveColorSwatch(theme, name, stop = 500) {
|
|
231
|
+
let def = theme.colors[name];
|
|
232
|
+
for (let hop = 0; def && def.type === "alias" && hop < MAX_ALIAS_HOPS; hop++) {
|
|
233
|
+
def = theme.colors[def.source];
|
|
234
|
+
}
|
|
235
|
+
if (!def || def.type === "alias") {
|
|
236
|
+
return SEMANTIC_SWATCHES[name] ?? null;
|
|
237
|
+
}
|
|
238
|
+
switch (def.type) {
|
|
239
|
+
case "generative": {
|
|
240
|
+
const light = generateStop(def, stop);
|
|
241
|
+
const lightSwatch = {
|
|
242
|
+
css: formatOklch(light.l, light.c, light.h),
|
|
243
|
+
hex: oklchToHex(light.l, light.c, light.h)
|
|
244
|
+
};
|
|
245
|
+
if (theme.darkConfig.mode === "off" || def.dark?.strategy === "fixed") {
|
|
246
|
+
return { light: lightSwatch, dark: null };
|
|
247
|
+
}
|
|
248
|
+
const dark = computeDarkStop(def, stop, theme.darkConfig, def.dark);
|
|
249
|
+
return {
|
|
250
|
+
light: lightSwatch,
|
|
251
|
+
dark: {
|
|
252
|
+
css: formatOklch(dark.l, dark.c, dark.h),
|
|
253
|
+
hex: oklchToHex(dark.l, dark.c, dark.h)
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
case "explicit":
|
|
258
|
+
return { light: swatchFromCss(def.value), dark: null };
|
|
259
|
+
case "pair":
|
|
260
|
+
return {
|
|
261
|
+
light: swatchFromCss(def.light),
|
|
262
|
+
dark: theme.darkConfig.mode === "off" ? null : swatchFromCss(def.dark)
|
|
263
|
+
};
|
|
264
|
+
case "keyword":
|
|
265
|
+
return null;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
function listThemeTokens(theme) {
|
|
269
|
+
return {
|
|
270
|
+
colors: Object.entries(theme.colors).map(([name, def]) => ({ name, kind: def.type })),
|
|
271
|
+
colorStops: CANONICAL_COLOR_STOPS,
|
|
272
|
+
spacingBase: theme.spacing.base,
|
|
273
|
+
textSizes: Object.entries(theme.text).map(([name, def]) => ({
|
|
274
|
+
name,
|
|
275
|
+
fontSize: def.fontSize,
|
|
276
|
+
lineHeight: def.lineHeight
|
|
277
|
+
})),
|
|
278
|
+
breakpoints: { ...theme.breakpoints },
|
|
279
|
+
rounded: { ...theme.rounded },
|
|
280
|
+
shadows: { ...theme.shadows },
|
|
281
|
+
weights: { ...theme.weights },
|
|
282
|
+
easing: { ...theme.easing },
|
|
283
|
+
blur: { ...theme.blur },
|
|
284
|
+
z: { ...theme.z },
|
|
285
|
+
leading: { ...theme.leading },
|
|
286
|
+
tracking: { ...theme.tracking },
|
|
287
|
+
opacity: { ...theme.opacity },
|
|
288
|
+
duration: { ...theme.duration },
|
|
289
|
+
fonts: theme.fonts.map((slot) => ({ slot: slot.slot, family: slot.family })),
|
|
290
|
+
animations: Object.keys(theme.animations)
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// src/editor/session.ts
|
|
295
|
+
function createEditorSession(options = {}) {
|
|
296
|
+
let css = options.css ?? "";
|
|
297
|
+
let analysis = null;
|
|
298
|
+
let inspector = null;
|
|
299
|
+
let enumeration = null;
|
|
300
|
+
let tokens = null;
|
|
301
|
+
let snapshot = null;
|
|
302
|
+
const ensureAnalysis = () => {
|
|
303
|
+
analysis ??= analyzeProjectCSS(css);
|
|
304
|
+
return analysis;
|
|
305
|
+
};
|
|
306
|
+
const ensureSnapshot = () => {
|
|
307
|
+
snapshot ??= createThemeSnapshot(ensureAnalysis().theme);
|
|
308
|
+
return snapshot;
|
|
309
|
+
};
|
|
310
|
+
return {
|
|
311
|
+
get css() {
|
|
312
|
+
return css;
|
|
313
|
+
},
|
|
314
|
+
setCss(next) {
|
|
315
|
+
if (next === css) return;
|
|
316
|
+
css = next;
|
|
317
|
+
analysis = null;
|
|
318
|
+
inspector = null;
|
|
319
|
+
enumeration = null;
|
|
320
|
+
tokens = null;
|
|
321
|
+
snapshot = null;
|
|
322
|
+
},
|
|
323
|
+
get theme() {
|
|
324
|
+
return ensureAnalysis().theme;
|
|
325
|
+
},
|
|
326
|
+
get diagnostics() {
|
|
327
|
+
return ensureAnalysis().diagnostics;
|
|
328
|
+
},
|
|
329
|
+
get inspector() {
|
|
330
|
+
inspector ??= createClassInspector(ensureAnalysis().theme);
|
|
331
|
+
return inspector;
|
|
332
|
+
},
|
|
333
|
+
enumerate() {
|
|
334
|
+
enumeration ??= enumerateClassNames(ensureAnalysis().theme);
|
|
335
|
+
return enumeration;
|
|
336
|
+
},
|
|
337
|
+
tokens() {
|
|
338
|
+
tokens ??= listThemeTokens(ensureAnalysis().theme);
|
|
339
|
+
return tokens;
|
|
340
|
+
},
|
|
341
|
+
snapshot: ensureSnapshot,
|
|
342
|
+
analyzeMerge(classes) {
|
|
343
|
+
return analyzeMerge(classes, ensureSnapshot());
|
|
344
|
+
},
|
|
345
|
+
extractCandidates(content, path) {
|
|
346
|
+
return extractClassCandidates({ content, path });
|
|
347
|
+
},
|
|
348
|
+
swatch(name, stop) {
|
|
349
|
+
return resolveColorSwatch(ensureAnalysis().theme, name, stop);
|
|
350
|
+
}
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// src/entries/editor.ts
|
|
355
|
+
var version = true ? "0.2.2" : "0.0.0-dev";
|
|
356
|
+
var EDITOR_API_VERSION = 1;
|
|
357
|
+
var editorCapabilities = Object.freeze([
|
|
358
|
+
"class-candidates",
|
|
359
|
+
"css-entry-detection",
|
|
360
|
+
"theme-analysis",
|
|
361
|
+
"class-inspection",
|
|
362
|
+
"variant-list",
|
|
363
|
+
"class-enumeration",
|
|
364
|
+
"merge-analysis",
|
|
365
|
+
"structured-diagnostics",
|
|
366
|
+
"color-swatches",
|
|
367
|
+
"editor-session"
|
|
368
|
+
]);
|
|
369
|
+
export {
|
|
370
|
+
CANONICAL_COLOR_STOPS,
|
|
371
|
+
CLASS_HELPER_NAMES,
|
|
372
|
+
CSS_ENTRY_CANDIDATES,
|
|
373
|
+
EDITOR_API_VERSION,
|
|
374
|
+
RI_IMPORT_SPECIFIERS,
|
|
375
|
+
UTILITY_VALUE_SPACES,
|
|
376
|
+
VARIANT_HELPER_NAMES,
|
|
377
|
+
analyzeMerge,
|
|
378
|
+
analyzeProjectCSS,
|
|
379
|
+
createClassInspector,
|
|
380
|
+
createEditorSession,
|
|
381
|
+
createThemeSnapshot,
|
|
382
|
+
cssColorToHex,
|
|
383
|
+
defaultTheme,
|
|
384
|
+
diagnosticFromWarning,
|
|
385
|
+
editorCapabilities,
|
|
386
|
+
enumerateClassNames,
|
|
387
|
+
expandVariantGroups,
|
|
388
|
+
extractClassCandidates,
|
|
389
|
+
extractClasses,
|
|
390
|
+
extractClassesFromSource,
|
|
391
|
+
findClosest,
|
|
392
|
+
hasRIActivation,
|
|
393
|
+
isSourceFile,
|
|
394
|
+
listThemeTokens,
|
|
395
|
+
listVariants,
|
|
396
|
+
oklchToHex,
|
|
397
|
+
parseUtility,
|
|
398
|
+
resolveColorSwatch,
|
|
399
|
+
severityForCode,
|
|
400
|
+
version,
|
|
401
|
+
warningCode
|
|
402
|
+
};
|
|
@@ -165,6 +165,34 @@ declare function ri(...inputs: ClassInput[]): string;
|
|
|
165
165
|
* ri('p-2 bg-red-500', 'p-4') // → 'bg-red-500 p-4'
|
|
166
166
|
*/
|
|
167
167
|
declare function createRi(snapshot?: CompilationSnapshot): (...inputs: ClassInput[]) => string;
|
|
168
|
+
interface MergeDrop {
|
|
169
|
+
index: number;
|
|
170
|
+
className: string;
|
|
171
|
+
/** Ascending indices of the surviving classes that together claimed every
|
|
172
|
+
* CSS property this class sets (px-4 + py-4 jointly dominate p-2). */
|
|
173
|
+
overriddenBy: number[];
|
|
174
|
+
}
|
|
175
|
+
interface MergeAnalysis {
|
|
176
|
+
/** The merged output — identical to ri()'s result for this token list. */
|
|
177
|
+
output: string;
|
|
178
|
+
/** Indices of surviving classes, ascending. */
|
|
179
|
+
kept: number[];
|
|
180
|
+
/** Dropped classes with attribution, ascending by index. */
|
|
181
|
+
dropped: MergeDrop[];
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Explain ri()'s conflict resolution for a list of class tokens — which
|
|
185
|
+
* classes the right-most-wins scan drops, and which survivors claimed their
|
|
186
|
+
* properties. Powers "this class is overridden" editor diagnostics.
|
|
187
|
+
*
|
|
188
|
+
* Unlike ri(), the input is pre-tokenized: one class per element, no falsy
|
|
189
|
+
* filtering, no whitespace splitting — exactly the token list an editor
|
|
190
|
+
* extracts from one class attribute. `snapshot` binds custom utilities, text
|
|
191
|
+
* sizes, and color names the same way createRi(snapshot) does (editors build
|
|
192
|
+
* one with createThemeSnapshot()); without it, the module-level state of the
|
|
193
|
+
* most recent compile applies. Uncached — call sites own their memoization.
|
|
194
|
+
*/
|
|
195
|
+
declare function analyzeMerge(classes: readonly string[], snapshot?: CompilationSnapshot): MergeAnalysis;
|
|
168
196
|
/**
|
|
169
197
|
* Create a fresh compilation context.
|
|
170
198
|
* Called at the start of each compile() pass.
|
|
@@ -194,46 +222,4 @@ declare function registerCustomFontFamilies(ctx: CompilationContext, families: s
|
|
|
194
222
|
declare function registerColorNames(ctx: CompilationContext, names: string[]): void;
|
|
195
223
|
declare function finalizeCompilationContext(ctx: CompilationContext): CompilationSnapshot;
|
|
196
224
|
|
|
197
|
-
|
|
198
|
-
* `safelist()` — declare utility classes that must be emitted regardless of
|
|
199
|
-
* whether the consumer's source files reference them directly.
|
|
200
|
-
*
|
|
201
|
-
* At runtime this is a plain identity-join: pass any number of strings (and
|
|
202
|
-
* falsy values, which are filtered) and receive a single space-joined string
|
|
203
|
-
* suitable for `className`. The function performs no global registration, has
|
|
204
|
-
* no side effects, and is tree-shake-safe.
|
|
205
|
-
*
|
|
206
|
-
* The build-time meaning comes from the scanner: when the source-file
|
|
207
|
-
* extractor encounters a `safelist(...)` call, it extracts every literal
|
|
208
|
-
* string argument as a class declaration — so the classes get emitted in the
|
|
209
|
-
* final CSS even though the consumer's source never names them literally.
|
|
210
|
-
*
|
|
211
|
-
* Primary use case is component libraries that ship classNames inside their
|
|
212
|
-
* bundled code (e.g. a curated icon set whose strokes are described by
|
|
213
|
-
* utility classes). The library wraps its declarations in `safelist(...)`,
|
|
214
|
-
* the consumer's setup points the scanner at the library's `dist/`, and the
|
|
215
|
-
* classes flow through unchanged. The Vite plugin auto-discovers libraries
|
|
216
|
-
* that opt in via a `rainbowindex.safelistSources` field in their
|
|
217
|
-
* `package.json`, so consumers typically don't have to add `@source` lines
|
|
218
|
-
* by hand.
|
|
219
|
-
*
|
|
220
|
-
* const ICON_BASE = safelist("stroke-cap-round", "stroke-join-round");
|
|
221
|
-
* const SidebarLeft = defineIcon({
|
|
222
|
-
* primitives: SIDEBAR,
|
|
223
|
-
* className: safelist(ICON_BASE, "-scale-x-100"),
|
|
224
|
-
* });
|
|
225
|
-
*
|
|
226
|
-
* Scanner contract:
|
|
227
|
-
* - Only STATIC string literals at the call site are extracted. Values
|
|
228
|
-
* passed through variables (`safelist(ICON_BASE, ...)`) won't be re-read
|
|
229
|
-
* at the outer call site, but the original `safelist("stroke-cap-round",
|
|
230
|
-
* ...)` that produced `ICON_BASE` is itself extracted, so the classes are
|
|
231
|
-
* still covered.
|
|
232
|
-
* - Template literals with no `${…}` interpolation are extracted; templates
|
|
233
|
-
* with interpolation are skipped.
|
|
234
|
-
* - Falsy arguments are dropped at runtime so conditional fragments compose
|
|
235
|
-
* naturally: `safelist("flex", side === "left" && "flex-row-reverse")`.
|
|
236
|
-
*/
|
|
237
|
-
declare function safelist(...parts: ReadonlyArray<string | false | null | undefined>): string;
|
|
238
|
-
|
|
239
|
-
export { type AnimationDefinition as A, type ColorDefinition as C, DEFAULT_TEXT_SIZES as D, type FluidConfig as F, type TextSize as T, type CompilationContext as a, type CompilationSnapshot as b, type Theme as c, createCompilationContext as d, createRi as e, defaultTheme as f, finalizeCompilationContext as g, registerCustomFontFamilies as h, registerCustomTextSizes as i, registerCustomUtility as j, ri as k, type DarkModeConfig as l, type CornerShape as m, registerColorNames as r, safelist as s };
|
|
225
|
+
export { type AnimationDefinition as A, type ColorDefinition as C, DEFAULT_TEXT_SIZES as D, type FluidConfig as F, type MergeAnalysis as M, type TextSize as T, type CompilationContext as a, type CompilationSnapshot as b, type Theme as c, createCompilationContext as d, createRi as e, defaultTheme as f, finalizeCompilationContext as g, registerCustomFontFamilies as h, registerCustomTextSizes as i, registerCustomUtility as j, ri as k, type DarkModeConfig as l, type CornerShape as m, type MergeDrop as n, analyzeMerge as o, registerColorNames as r };
|