rainbowindex 0.0.0 → 0.2.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/CHANGELOG.md +122 -0
- package/LICENSE +22 -0
- package/README.md +329 -0
- package/dist/browser.d.ts +5 -0
- package/dist/browser.mjs +41 -0
- package/dist/chunk-5N4GPK26.mjs +2664 -0
- package/dist/chunk-KCSNR2TV.mjs +671 -0
- package/dist/chunk-PD4ZXGJ6.mjs +14 -0
- package/dist/chunk-RPXZ3O6R.mjs +10518 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.mjs +1258 -0
- package/dist/index.css +2 -0
- package/dist/index.d.ts +289 -0
- package/dist/index.mjs +71 -0
- package/dist/optimize-6NWJVT6W.mjs +24 -0
- package/dist/safelist-DRk1XXxi.d.ts +239 -0
- package/dist/vite.d.ts +5 -0
- package/dist/vite.mjs +320 -0
- package/package.json +101 -4
package/dist/index.css
ADDED
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
import { PluginCreator } from 'postcss';
|
|
2
|
+
import { C as ColorDefinition, l as DarkModeConfig, m as CornerShape, A as AnimationDefinition, F as FluidConfig } from './safelist-DRk1XXxi.js';
|
|
3
|
+
export { a as CompilationContext, b as CompilationSnapshot, D as DEFAULT_TEXT_SIZES, T as TextSize, c as Theme, d as createCompilationContext, e as createRi, f as defaultTheme, g as finalizeCompilationContext, r as registerColorNames, h as registerCustomFontFamilies, i as registerCustomTextSizes, j as registerCustomUtility, k as ri, s as safelist } from './safelist-DRk1XXxi.js';
|
|
4
|
+
|
|
5
|
+
interface RainbowIndexOptions {
|
|
6
|
+
sources?: string[];
|
|
7
|
+
cwd?: string;
|
|
8
|
+
}
|
|
9
|
+
declare const rainbowindex: PluginCreator<RainbowIndexOptions>;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Font loading system — @font directive processing, @font-face generation,
|
|
13
|
+
* metrics-adjusted fallbacks for zero CLS.
|
|
14
|
+
*
|
|
15
|
+
* A slot (sans/serif/mono/custom) maps to one --font-<slot> variable and one
|
|
16
|
+
* family name, but can own multiple faces — e.g. an upright + an italic file,
|
|
17
|
+
* or split unicode ranges. Each FontFace emits one @font-face for local
|
|
18
|
+
* providers; google/system/manual slots carry a single face.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/** Provider discriminant for a slot, derived from its faces. */
|
|
22
|
+
type FontProviderKind = "google" | "system" | "local" | "manual";
|
|
23
|
+
interface FontFace {
|
|
24
|
+
/** Provider: "google", "system", a file path/URL, or "" (manual stack — no @font-face). */
|
|
25
|
+
provider: string;
|
|
26
|
+
/** Weight range ("300 900"), list ("400,700"), or single ("400"). */
|
|
27
|
+
weight: string;
|
|
28
|
+
/** A single valid font-style descriptor: "normal", "italic", or "oblique <range>".
|
|
29
|
+
* (Google faces may carry "normal italic" — that drives the URL's ital axis, not a descriptor.) */
|
|
30
|
+
style: string;
|
|
31
|
+
/** font-display strategy. */
|
|
32
|
+
display: string;
|
|
33
|
+
/** Unicode subsets — used as a Google Fonts URL hint. */
|
|
34
|
+
subset: string;
|
|
35
|
+
/** Optional unicode-range descriptor emitted into the @font-face (local subsetting). */
|
|
36
|
+
unicodeRange?: string;
|
|
37
|
+
/** Per-face preload override; when undefined the slot-level default applies. */
|
|
38
|
+
preload?: boolean;
|
|
39
|
+
/** Whether the weight was explicitly set by the user (not a default).
|
|
40
|
+
* Used by refreshFontWeightDefaults() to avoid overriding user intent. */
|
|
41
|
+
_weightExplicit?: boolean;
|
|
42
|
+
/** Whether the style was explicitly set by the user (not a default).
|
|
43
|
+
* Used by refreshFontWeightDefaults() to avoid overriding user intent. */
|
|
44
|
+
_styleExplicit?: boolean;
|
|
45
|
+
}
|
|
46
|
+
interface FontSlot {
|
|
47
|
+
/** Target slot: "sans", "serif", "mono", or custom like "display". */
|
|
48
|
+
slot: string;
|
|
49
|
+
/** Font family name — shared by every face in the slot. */
|
|
50
|
+
family: string;
|
|
51
|
+
/** Provider discriminant, derived from the slot's faces. */
|
|
52
|
+
kind: FontProviderKind;
|
|
53
|
+
/** Fallback font stack. */
|
|
54
|
+
fallback: string[];
|
|
55
|
+
/** Font feature settings — applied via the font-<slot> utility. */
|
|
56
|
+
features: string | null;
|
|
57
|
+
/** Font variation settings — applied via the font-<slot> utility. */
|
|
58
|
+
variation: string | null;
|
|
59
|
+
/** Slot-level preload default for faces that don't set their own. */
|
|
60
|
+
preload: boolean;
|
|
61
|
+
/** One or more faces — each emits an @font-face for local providers. */
|
|
62
|
+
faces: FontFace[];
|
|
63
|
+
/** User-specified fallback font for metrics-adjusted @font-face. */
|
|
64
|
+
metricsFallback?: string;
|
|
65
|
+
/** User-specified size-adjust percentage. */
|
|
66
|
+
sizeAdjust?: number;
|
|
67
|
+
/** User-specified ascent-override percentage. */
|
|
68
|
+
ascent?: number;
|
|
69
|
+
/** User-specified descent-override percentage. */
|
|
70
|
+
descent?: number;
|
|
71
|
+
/** User-specified line-gap-override percentage. */
|
|
72
|
+
lineGap?: number;
|
|
73
|
+
}
|
|
74
|
+
interface FontOutput {
|
|
75
|
+
imports: string[];
|
|
76
|
+
fontFaces: string[];
|
|
77
|
+
variables: string[];
|
|
78
|
+
warnings: string[];
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Raw-extractable directive names — the single source for the DirectiveType
|
|
83
|
+
* union and the name sets in directives/index.ts (which add the PostCSS-only
|
|
84
|
+
* apply/slot names on top for activation detection).
|
|
85
|
+
*/
|
|
86
|
+
declare const DIRECTIVE_TYPE_NAMES: readonly ["color", "text", "spacing", "breakpoint", "rounded", "shadow", "weight", "ease", "blur", "z", "animate", "fluid", "font", "preflight", "utility", "custom", "source", "leading", "tracking", "opacity", "duration", "layer", "register"];
|
|
87
|
+
type DirectiveType = (typeof DIRECTIVE_TYPE_NAMES)[number];
|
|
88
|
+
interface ParsedDirective {
|
|
89
|
+
type: DirectiveType;
|
|
90
|
+
body: string;
|
|
91
|
+
modifier?: string;
|
|
92
|
+
}
|
|
93
|
+
interface PreflightConfig {
|
|
94
|
+
core: boolean;
|
|
95
|
+
typography: boolean;
|
|
96
|
+
content: boolean;
|
|
97
|
+
forms: boolean;
|
|
98
|
+
interactive: boolean;
|
|
99
|
+
modern: boolean;
|
|
100
|
+
}
|
|
101
|
+
interface CustomUtility {
|
|
102
|
+
name: string;
|
|
103
|
+
functional: boolean;
|
|
104
|
+
body: string;
|
|
105
|
+
}
|
|
106
|
+
interface CustomVariant {
|
|
107
|
+
name: string;
|
|
108
|
+
selector: string;
|
|
109
|
+
}
|
|
110
|
+
interface SourceDirective {
|
|
111
|
+
pattern: string;
|
|
112
|
+
negated: boolean;
|
|
113
|
+
inline: boolean;
|
|
114
|
+
classes?: string[];
|
|
115
|
+
/**
|
|
116
|
+
* Marks the pattern as a trusted, fully-qualified absolute path produced
|
|
117
|
+
* by internal machinery (auto-discovery from installed deps). User-facing
|
|
118
|
+
* `@source` patterns are validated to be relative — this flag bypasses
|
|
119
|
+
* that check for patterns we generate ourselves and that intentionally
|
|
120
|
+
* point outside the project's cwd (into `node_modules`).
|
|
121
|
+
*/
|
|
122
|
+
absolute?: boolean;
|
|
123
|
+
}
|
|
124
|
+
interface LayerConfig {
|
|
125
|
+
order: string[] | null;
|
|
126
|
+
utilities: string | null;
|
|
127
|
+
base: string | null;
|
|
128
|
+
wrapAll: string | null;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* A custom-property registration produced by an `@register` directive — the
|
|
132
|
+
* structured form of a CSS `@property` rule. `syntax` is stored already quoted
|
|
133
|
+
* (e.g. `"<length>"`) so it can be emitted verbatim. `initialValue` is optional
|
|
134
|
+
* only when `syntax` is the universal `"*"`; the parser drops typed registrations
|
|
135
|
+
* that lack one (a typed `@property` without `initial-value` is invalid CSS and
|
|
136
|
+
* silently ignored by browsers).
|
|
137
|
+
*/
|
|
138
|
+
interface PropertyRegistration {
|
|
139
|
+
name: string;
|
|
140
|
+
syntax: string;
|
|
141
|
+
inherits: boolean;
|
|
142
|
+
initialValue?: string;
|
|
143
|
+
}
|
|
144
|
+
interface ResolvedTheme {
|
|
145
|
+
readonly colors: Readonly<Record<string, ColorDefinition>>;
|
|
146
|
+
readonly darkConfig: Readonly<DarkModeConfig>;
|
|
147
|
+
readonly text: Readonly<Record<string, {
|
|
148
|
+
fontSize: string;
|
|
149
|
+
lineHeight: string;
|
|
150
|
+
}>>;
|
|
151
|
+
readonly spacing: Readonly<{
|
|
152
|
+
base: string;
|
|
153
|
+
}>;
|
|
154
|
+
readonly breakpoints: Readonly<Record<string, string>>;
|
|
155
|
+
readonly rounded: Readonly<Record<string, string>>;
|
|
156
|
+
readonly roundedRoof: string;
|
|
157
|
+
/**
|
|
158
|
+
* Corner shape set via `@rounded <shape>`. `null` means no shape was configured —
|
|
159
|
+
* the compiler emits neither a `corner-shape` rule nor the fallback `@supports not`
|
|
160
|
+
* block. Non-null values trigger both.
|
|
161
|
+
*/
|
|
162
|
+
readonly roundedShape: CornerShape | null;
|
|
163
|
+
/**
|
|
164
|
+
* Multiplier applied to `border-radius` inside
|
|
165
|
+
* `@supports (corner-shape: <shape>)` so that — in browsers that do
|
|
166
|
+
* render the configured shape — radii are bumped to match the visual
|
|
167
|
+
* weight a plain round corner would have at the raw radius in
|
|
168
|
+
* non-supporting browsers. Derived from the per-shape default table,
|
|
169
|
+
* overridable via `--corner-scale` in the `@rounded` body. Ignored when
|
|
170
|
+
* `roundedShape` is null.
|
|
171
|
+
*/
|
|
172
|
+
readonly roundedShapeScale: number;
|
|
173
|
+
readonly shadows: Readonly<Record<string, string>>;
|
|
174
|
+
readonly weights: Readonly<Record<string, number>>;
|
|
175
|
+
readonly easing: Readonly<Record<string, string>>;
|
|
176
|
+
readonly blur: Readonly<Record<string, string>>;
|
|
177
|
+
readonly z: Readonly<Record<string, string>>;
|
|
178
|
+
readonly animations: Readonly<Record<string, AnimationDefinition>>;
|
|
179
|
+
readonly fluid: Readonly<FluidConfig>;
|
|
180
|
+
readonly textFluid?: Readonly<FluidConfig>;
|
|
181
|
+
readonly spacingFluid?: Readonly<FluidConfig>;
|
|
182
|
+
readonly fonts: readonly FontSlot[];
|
|
183
|
+
readonly preflight: Readonly<PreflightConfig>;
|
|
184
|
+
readonly customUtilities: readonly CustomUtility[];
|
|
185
|
+
readonly customVariants: readonly CustomVariant[];
|
|
186
|
+
readonly sources: readonly SourceDirective[];
|
|
187
|
+
readonly leading: Readonly<Record<string, string>>;
|
|
188
|
+
readonly tracking: Readonly<Record<string, string>>;
|
|
189
|
+
readonly opacity: Readonly<Record<string, string>>;
|
|
190
|
+
readonly duration: Readonly<Record<string, string>>;
|
|
191
|
+
readonly layer: Readonly<LayerConfig> | null;
|
|
192
|
+
/** Custom properties registered via `@register` → emitted as `@property` rules. */
|
|
193
|
+
readonly registeredProperties: readonly PropertyRegistration[];
|
|
194
|
+
readonly warnings: readonly string[];
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
type FontResolver = (fonts: ResolvedTheme["fonts"]) => Promise<ResolvedTheme["fonts"]> | ResolvedTheme["fonts"];
|
|
198
|
+
interface FinalizeProjectResult {
|
|
199
|
+
css: string;
|
|
200
|
+
/** Generated output only — user CSS is carried separately in `userCSS`. */
|
|
201
|
+
sections: string[];
|
|
202
|
+
/** The user's own CSS (RI directives stripped), appended after `sections` in `css`. */
|
|
203
|
+
userCSS: string;
|
|
204
|
+
classNames: string[];
|
|
205
|
+
theme: ResolvedTheme;
|
|
206
|
+
directives: ParsedDirective[];
|
|
207
|
+
warnings: string[];
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
interface SourceEntry {
|
|
211
|
+
path?: string;
|
|
212
|
+
content: string;
|
|
213
|
+
}
|
|
214
|
+
interface CompileProjectOptions {
|
|
215
|
+
css: string;
|
|
216
|
+
sources?: Iterable<SourceEntry>;
|
|
217
|
+
classNames?: Iterable<string>;
|
|
218
|
+
resolveFonts?: FontResolver;
|
|
219
|
+
processCssFunctions?: boolean;
|
|
220
|
+
}
|
|
221
|
+
/** compileProject returns the pipeline result unmodified — one shape, two names. */
|
|
222
|
+
type CompileProjectResult = FinalizeProjectResult;
|
|
223
|
+
declare function compileProject(options: CompileProjectOptions): Promise<CompileProjectResult>;
|
|
224
|
+
|
|
225
|
+
interface CompiledRule {
|
|
226
|
+
/** The original class name (escaped for CSS selector). */
|
|
227
|
+
selector: string;
|
|
228
|
+
/** Sort key for deterministic ordering. */
|
|
229
|
+
sortKey: number;
|
|
230
|
+
/** CSS declarations as a string block. */
|
|
231
|
+
css: string;
|
|
232
|
+
}
|
|
233
|
+
interface CompilationResult {
|
|
234
|
+
/** All compiled CSS rules. */
|
|
235
|
+
rules: CompiledRule[];
|
|
236
|
+
/** @keyframes blocks needed. */
|
|
237
|
+
keyframes: string[];
|
|
238
|
+
/** @property declarations needed. */
|
|
239
|
+
properties: string[];
|
|
240
|
+
/** Map of used color hue → set of used suffixes (for token pruning). */
|
|
241
|
+
usedColorStops: Map<string, Set<number>>;
|
|
242
|
+
/** Set of used text size names (for token pruning). */
|
|
243
|
+
usedTextSizes: Set<string>;
|
|
244
|
+
/** Set of used font slot names (for token pruning). */
|
|
245
|
+
usedFonts: Set<string>;
|
|
246
|
+
/** Set of used rounded value names (for token pruning). */
|
|
247
|
+
usedRounded: Set<string>;
|
|
248
|
+
/** Set of used shadow names (for token pruning). */
|
|
249
|
+
usedShadows: Set<string>;
|
|
250
|
+
/** Set of used animation shorthand names (for token pruning). */
|
|
251
|
+
usedAnimations: Set<string>;
|
|
252
|
+
/** Warnings emitted during compilation. */
|
|
253
|
+
warnings: string[];
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Create an isolated compiler instance for SSR / concurrent-compilation
|
|
258
|
+
* environments. Returns a `compile()` function that does NOT touch module-level
|
|
259
|
+
* state, and a `createRi()` that produces a merge function bound to the
|
|
260
|
+
* compilation's snapshot.
|
|
261
|
+
*
|
|
262
|
+
* **Isolation scope:** Compilation context, variant map cache, and font output
|
|
263
|
+
* cache are fully isolated per instance. Google Fonts metadata (from fonts.ts)
|
|
264
|
+
* is intentionally shared read-only across instances — it is populated once
|
|
265
|
+
* via atomic swap and never mutated afterward, so concurrent reads are safe.
|
|
266
|
+
*
|
|
267
|
+
* **Font output cache lifecycle:** `fontOutputCache` is cleared at the start
|
|
268
|
+
* of each `compile()` call, so it only caches within a single compilation pass.
|
|
269
|
+
* If the same compiler instance is reused across compilations (the expected SSR
|
|
270
|
+
* pattern), each compilation starts with a fresh font cache.
|
|
271
|
+
*
|
|
272
|
+
* @example
|
|
273
|
+
* ```ts
|
|
274
|
+
* import { createCompiler } from "rainbowindex";
|
|
275
|
+
*
|
|
276
|
+
* const compiler = createCompiler();
|
|
277
|
+
* const result = compiler.compile(classNames, theme);
|
|
278
|
+
* const ri = compiler.createRi();
|
|
279
|
+
* ```
|
|
280
|
+
*/
|
|
281
|
+
declare function createCompiler(): {
|
|
282
|
+
compile: (classNames: Iterable<string>, theme: ResolvedTheme) => CompilationResult;
|
|
283
|
+
createRi: () => (...inputs: (string | false | null | undefined)[]) => string;
|
|
284
|
+
/** Isolated font output cache for this compiler instance. Pass to
|
|
285
|
+
* `assembleSections()` to avoid sharing module-level font state. */
|
|
286
|
+
fontOutputCache: Map<string, FontOutput>;
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
export { ColorDefinition, type CompilationResult, type CompileProjectOptions, type CompileProjectResult, type CompiledRule, FluidConfig, type RainbowIndexOptions, compileProject, createCompiler, rainbowindex as default };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import {
|
|
2
|
+
safelist
|
|
3
|
+
} from "./chunk-PD4ZXGJ6.mjs";
|
|
4
|
+
import {
|
|
5
|
+
postcss_default
|
|
6
|
+
} from "./chunk-KCSNR2TV.mjs";
|
|
7
|
+
import {
|
|
8
|
+
analyzeProjectCSS,
|
|
9
|
+
createCompiler,
|
|
10
|
+
extractClassesFromSource,
|
|
11
|
+
finalizeProjectCompilation,
|
|
12
|
+
pushWarningsDeduped,
|
|
13
|
+
resolveGoogleFonts
|
|
14
|
+
} from "./chunk-RPXZ3O6R.mjs";
|
|
15
|
+
import {
|
|
16
|
+
DEFAULT_TEXT_SIZES,
|
|
17
|
+
createCompilationContext,
|
|
18
|
+
createRi,
|
|
19
|
+
defaultTheme,
|
|
20
|
+
finalizeCompilationContext,
|
|
21
|
+
registerColorNames,
|
|
22
|
+
registerCustomFontFamilies,
|
|
23
|
+
registerCustomTextSizes,
|
|
24
|
+
registerCustomUtility,
|
|
25
|
+
ri
|
|
26
|
+
} from "./chunk-5N4GPK26.mjs";
|
|
27
|
+
|
|
28
|
+
// src/project/index.ts
|
|
29
|
+
async function compileProject(options) {
|
|
30
|
+
const analysis = analyzeProjectCSS(options.css);
|
|
31
|
+
const classNames = /* @__PURE__ */ new Set();
|
|
32
|
+
if (options.classNames) {
|
|
33
|
+
for (const cls of options.classNames) {
|
|
34
|
+
classNames.add(cls);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (options.sources) {
|
|
38
|
+
const extractionWarnings = [];
|
|
39
|
+
for (const source of options.sources) {
|
|
40
|
+
for (const cls of extractClassesFromSource(source, extractionWarnings)) {
|
|
41
|
+
classNames.add(cls);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
pushWarningsDeduped(analysis.warnings, extractionWarnings, analysis.warningSeen);
|
|
45
|
+
}
|
|
46
|
+
return finalizeProjectCompilation({
|
|
47
|
+
css: options.css,
|
|
48
|
+
classNames,
|
|
49
|
+
analysis,
|
|
50
|
+
// Default to resolving google font weights so headless callers aren't silently
|
|
51
|
+
// stuck with "100 900" defaults; opt out with RI_OFFLINE / RI_FETCH_FONTS.
|
|
52
|
+
resolveFonts: options.resolveFonts ?? resolveGoogleFonts,
|
|
53
|
+
processCssFunctions: options.processCssFunctions
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
export {
|
|
57
|
+
DEFAULT_TEXT_SIZES,
|
|
58
|
+
compileProject,
|
|
59
|
+
createCompilationContext,
|
|
60
|
+
createCompiler,
|
|
61
|
+
createRi,
|
|
62
|
+
postcss_default as default,
|
|
63
|
+
defaultTheme,
|
|
64
|
+
finalizeCompilationContext,
|
|
65
|
+
registerColorNames,
|
|
66
|
+
registerCustomFontFamilies,
|
|
67
|
+
registerCustomTextSizes,
|
|
68
|
+
registerCustomUtility,
|
|
69
|
+
ri,
|
|
70
|
+
safelist
|
|
71
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// src/cli/optimize.ts
|
|
2
|
+
import { transform } from "lightningcss";
|
|
3
|
+
function optimizeCSS(css) {
|
|
4
|
+
try {
|
|
5
|
+
const result = transform({
|
|
6
|
+
filename: "output.css",
|
|
7
|
+
code: Buffer.from(css),
|
|
8
|
+
minify: true,
|
|
9
|
+
targets: {
|
|
10
|
+
chrome: 96 << 16,
|
|
11
|
+
firefox: 91 << 16,
|
|
12
|
+
safari: 15 << 16 | 4 << 8
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
return result.code.toString();
|
|
16
|
+
} catch (err) {
|
|
17
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
18
|
+
const sanitized = msg.replace(/\/[a-zA-Z][\w.-]*(?:\/[\w.-]+)+/g, "<path>").replace(/[A-Z]:\\[\w.-]+(?:\\[\w.-]+)+/gi, "<path>");
|
|
19
|
+
throw new Error(`CSS optimization failed: ${sanitized}`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export {
|
|
23
|
+
optimizeCSS
|
|
24
|
+
};
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generative color system — color domain model, OKLCH ramp generation,
|
|
3
|
+
* and light-dark() pairing.
|
|
4
|
+
*
|
|
5
|
+
* 2 numbers (chroma + hue) → 19-stop palette with automatic dark mode.
|
|
6
|
+
*
|
|
7
|
+
* The ramp is sampled from a fixed reference profile (`L_PROFILE` / `C_SHAPE` /
|
|
8
|
+
* `H_DRIFT`, captured from the reference palette): lightness is a curved,
|
|
9
|
+
* compressed scale (low suffix → light, high → dark), chroma is an asymmetric
|
|
10
|
+
* bell peaking at stop 500, and hue is near-flat. Dark mode is a simple ramp
|
|
11
|
+
* reversal — the dark value is the stop the ramp reaches at the mirror position
|
|
12
|
+
* (`1000 - suffix`), so stop 500 pivots to itself.
|
|
13
|
+
*/
|
|
14
|
+
/** Per-color dark mode override strategy. */
|
|
15
|
+
type ColorDarkOverride = {
|
|
16
|
+
strategy: "mirror";
|
|
17
|
+
} | {
|
|
18
|
+
strategy: "fixed";
|
|
19
|
+
} | {
|
|
20
|
+
strategy: "shift";
|
|
21
|
+
chromaDelta: number;
|
|
22
|
+
hueDelta: number;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Color definition — discriminated union supporting:
|
|
26
|
+
* - Generative: `brand: 0.18 330;` → 19-stop palette with auto dark mode
|
|
27
|
+
* - Explicit: `accent: oklch(0.72 0.21 330);` → single color value
|
|
28
|
+
* - Pair: `surface: oklch(0.98 0.01 260) / oklch(0.15 0.01 260);` → light/dark pair
|
|
29
|
+
* - Alias: `theme: brand;` → references another color's palette via var()
|
|
30
|
+
*/
|
|
31
|
+
type ColorDefinition = {
|
|
32
|
+
type: "generative";
|
|
33
|
+
chroma: number;
|
|
34
|
+
hue: number;
|
|
35
|
+
dark?: ColorDarkOverride;
|
|
36
|
+
inline?: boolean;
|
|
37
|
+
parabolic?: boolean;
|
|
38
|
+
chromaBoost?: boolean;
|
|
39
|
+
} | {
|
|
40
|
+
type: "explicit";
|
|
41
|
+
value: string;
|
|
42
|
+
} | {
|
|
43
|
+
type: "keyword";
|
|
44
|
+
value: string;
|
|
45
|
+
} | {
|
|
46
|
+
type: "pair";
|
|
47
|
+
light: string;
|
|
48
|
+
dark: string;
|
|
49
|
+
} | {
|
|
50
|
+
type: "alias";
|
|
51
|
+
source: string;
|
|
52
|
+
};
|
|
53
|
+
interface DarkModeConfig {
|
|
54
|
+
mode: "auto" | "off";
|
|
55
|
+
chromaBoost: number;
|
|
56
|
+
hueShift: number;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Default theme values — the static data that ships if the user writes no directives.
|
|
61
|
+
* `directives.ts` (Phase 5) parses user overrides and merges them with these defaults.
|
|
62
|
+
*/
|
|
63
|
+
|
|
64
|
+
interface TextSize {
|
|
65
|
+
fontSize: string;
|
|
66
|
+
lineHeight: string;
|
|
67
|
+
}
|
|
68
|
+
type FluidUnit = "vw" | "vi" | "vmin" | "vmax";
|
|
69
|
+
interface FluidConfig {
|
|
70
|
+
min: string;
|
|
71
|
+
max: string;
|
|
72
|
+
unit?: FluidUnit;
|
|
73
|
+
multiplier?: number;
|
|
74
|
+
}
|
|
75
|
+
interface AnimationDefinition {
|
|
76
|
+
shorthand: string;
|
|
77
|
+
keyframes: string;
|
|
78
|
+
}
|
|
79
|
+
interface Theme {
|
|
80
|
+
spacing: {
|
|
81
|
+
base: string;
|
|
82
|
+
};
|
|
83
|
+
colors: Record<string, ColorDefinition>;
|
|
84
|
+
text: Record<string, TextSize>;
|
|
85
|
+
breakpoints: Record<string, string>;
|
|
86
|
+
rounded: Record<string, string>;
|
|
87
|
+
shadows: Record<string, string>;
|
|
88
|
+
weights: Record<string, number>;
|
|
89
|
+
easing: Record<string, string>;
|
|
90
|
+
fluid: FluidConfig;
|
|
91
|
+
animations: Record<string, AnimationDefinition>;
|
|
92
|
+
blur: Record<string, string>;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Keyword corner-shape values. `superellipse(N)` is represented separately
|
|
96
|
+
* as `{ superellipse: N }` since the numeric parameter isn't a keyword.
|
|
97
|
+
* Single source for the type, the scale table below, and the @rounded
|
|
98
|
+
* modifier parser (directives/parsers.ts).
|
|
99
|
+
*/
|
|
100
|
+
declare const CORNER_SHAPE_KEYWORDS: readonly ["round", "scoop", "bevel", "notch", "square", "squircle"];
|
|
101
|
+
type CornerShapeKeyword = (typeof CORNER_SHAPE_KEYWORDS)[number];
|
|
102
|
+
type CornerShape = CornerShapeKeyword | {
|
|
103
|
+
superellipse: number;
|
|
104
|
+
};
|
|
105
|
+
declare const defaultTheme: Theme;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* ri() — class merge function.
|
|
109
|
+
* Replaces both tailwind-merge and clsx.
|
|
110
|
+
*
|
|
111
|
+
* Re-exported from the package's main and browser entries as `ri()`.
|
|
112
|
+
* Right-to-left scan: rightmost class wins when two classes set the same CSS property.
|
|
113
|
+
*
|
|
114
|
+
* ## Concurrency
|
|
115
|
+
*
|
|
116
|
+
* The default `ri()` export uses module-level state published by
|
|
117
|
+
* `finalizeCompilationContext()`. This is safe for single-compilation
|
|
118
|
+
* environments (typical browser usage, single Vite build, PostCSS).
|
|
119
|
+
*
|
|
120
|
+
* In multi-tenant / SSR / concurrent-compilation environments, use
|
|
121
|
+
* `createRi(snapshot)` instead — it captures a frozen snapshot of the
|
|
122
|
+
* compilation state and uses its own independent cache:
|
|
123
|
+
*
|
|
124
|
+
* const snapshot = finalizeCompilationContext(ctx);
|
|
125
|
+
* const ri = createRi(snapshot);
|
|
126
|
+
*/
|
|
127
|
+
type ClassInput = string | false | null | undefined | ClassInput[];
|
|
128
|
+
declare const DEFAULT_TEXT_SIZES: readonly ["xs", "sm", "base", "lg", "xl", "2xl", "3xl", "4xl", "5xl"];
|
|
129
|
+
interface CompilationContext {
|
|
130
|
+
customStaticProps: Record<string, string[]>;
|
|
131
|
+
textSizes: Set<string>;
|
|
132
|
+
fontFamilies: Set<string>;
|
|
133
|
+
colorNames: Set<string>;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Frozen snapshot of compilation state for SSR-safe ri() instances.
|
|
137
|
+
* Created by finalizeCompilationContext() and consumed by createRi().
|
|
138
|
+
*/
|
|
139
|
+
interface CompilationSnapshot {
|
|
140
|
+
readonly customStaticProps: Readonly<Record<string, string[]>>;
|
|
141
|
+
readonly textSizes: ReadonlySet<string>;
|
|
142
|
+
readonly fontFamilies: ReadonlySet<string>;
|
|
143
|
+
readonly colorNames: ReadonlySet<string>;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Merge class names with conflict resolution (replaces both tailwind-merge and clsx).
|
|
147
|
+
* Rightmost class wins when two classes set the same CSS property.
|
|
148
|
+
* Falsy values are filtered.
|
|
149
|
+
*
|
|
150
|
+
* @example
|
|
151
|
+
* ri('p-2 bg-red-500', 'p-4') // → 'bg-red-500 p-4'
|
|
152
|
+
* ri('px-2 py-1', 'p-4') // → 'p-4' (shorthand wins)
|
|
153
|
+
* ri('flex', isActive && 'bg-blue-500') // → 'flex bg-blue-500'
|
|
154
|
+
* ri('text-lg text-red-500') // → 'text-lg text-red-500' (different properties)
|
|
155
|
+
*/
|
|
156
|
+
declare function ri(...inputs: ClassInput[]): string;
|
|
157
|
+
/**
|
|
158
|
+
* Create an isolated ri() instance bound to a specific compilation snapshot.
|
|
159
|
+
* Use this in SSR or multi-compilation environments where the global ri()
|
|
160
|
+
* would be corrupted by concurrent compilations.
|
|
161
|
+
*
|
|
162
|
+
* @example
|
|
163
|
+
* const snapshot = finalizeCompilationContext(ctx);
|
|
164
|
+
* const ri = createRi(snapshot);
|
|
165
|
+
* ri('p-2 bg-red-500', 'p-4') // → 'bg-red-500 p-4'
|
|
166
|
+
*/
|
|
167
|
+
declare function createRi(snapshot?: CompilationSnapshot): (...inputs: ClassInput[]) => string;
|
|
168
|
+
/**
|
|
169
|
+
* Create a fresh compilation context.
|
|
170
|
+
* Called at the start of each compile() pass.
|
|
171
|
+
*/
|
|
172
|
+
declare function createCompilationContext(): CompilationContext;
|
|
173
|
+
/**
|
|
174
|
+
* Register a custom utility's CSS properties in the compilation context.
|
|
175
|
+
* Called by the engine when processing @utility directives.
|
|
176
|
+
*/
|
|
177
|
+
declare function registerCustomUtility(ctx: CompilationContext, name: string, properties: string[]): void;
|
|
178
|
+
/**
|
|
179
|
+
* Register custom text sizes so the merge function correctly classifies
|
|
180
|
+
* text-{custom} as a font-size utility rather than a color utility.
|
|
181
|
+
*/
|
|
182
|
+
declare function registerCustomTextSizes(ctx: CompilationContext, sizes: string[]): void;
|
|
183
|
+
/**
|
|
184
|
+
* Register custom font family names so the merge function correctly classifies
|
|
185
|
+
* font-{custom} as a font-family utility rather than a font-weight utility.
|
|
186
|
+
*/
|
|
187
|
+
declare function registerCustomFontFamilies(ctx: CompilationContext, families: string[]): void;
|
|
188
|
+
/**
|
|
189
|
+
* Register the resolved theme's color names so the merge function classifies
|
|
190
|
+
* bare flat colors (border-accent for `@color { accent: … }`) as color
|
|
191
|
+
* utilities rather than width/weight ones. Shaded forms (accent-500) already
|
|
192
|
+
* match the shade pattern and need no registration.
|
|
193
|
+
*/
|
|
194
|
+
declare function registerColorNames(ctx: CompilationContext, names: string[]): void;
|
|
195
|
+
declare function finalizeCompilationContext(ctx: CompilationContext): CompilationSnapshot;
|
|
196
|
+
|
|
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 };
|