rainbowindex 0.5.1 → 0.6.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 +333 -0
- package/README.md +6 -4
- package/dist/browser.d.ts +2 -2
- package/dist/browser.mjs +1 -3
- package/dist/{chunk-4CTJLMYM.mjs → chunk-3LWJTLOJ.mjs} +17 -11
- package/dist/{chunk-4UKFK2GE.mjs → chunk-6U4IOFOS.mjs} +682 -869
- package/dist/{chunk-PDORZSQX.mjs → chunk-KSNYSR3C.mjs} +5547 -5077
- package/dist/{chunk-F4VCBISU.mjs → chunk-WK6S4HTC.mjs} +97 -42
- package/dist/{chunk-RU4756NG.mjs → chunk-ZR7XJMUN.mjs} +14 -6
- package/dist/cli.mjs +31 -9
- package/dist/editor.d.ts +30 -7
- package/dist/editor.mjs +29 -7
- package/dist/{index-Dx-NpFFx.d.ts → index-4Kyaq3IZ.d.ts} +25 -2
- package/dist/{context-B9yhJxd5.d.ts → index-DSgpB6bS.d.ts} +91 -88
- package/dist/index.d.ts +7 -4
- package/dist/index.mjs +12 -9
- package/dist/{safelist-DAkKuxCk.d.ts → safelist-CGCtF-Fr.d.ts} +1 -1
- package/dist/vite.mjs +19 -7
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,339 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.6.0] - 2026-09-01
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **Numeric font weights, checked against the fonts you load.** `font-<number>`
|
|
13
|
+
now sets `font-weight` directly, for any weight from 1 to 1000 —
|
|
14
|
+
`font-300`, `font-500`, `font-617`. A named `@weight` token of the same
|
|
15
|
+
spelling still wins, and `font-[850]` is unchanged.
|
|
16
|
+
|
|
17
|
+
The number is compared against the `weight` of every loaded `@font` face. A
|
|
18
|
+
range (`weight: 300 900`, the variable-font case) accepts every number
|
|
19
|
+
between its bounds; a list or a single value (`weight: 400,700`) accepts
|
|
20
|
+
only those numbers. A weight that no face provides warns with the new
|
|
21
|
+
`[RI-1504]`, and the message names the weights that are available.
|
|
22
|
+
|
|
23
|
+
A class on its own carries no family, and a page can load several fonts, so
|
|
24
|
+
that check is a union: one covering face is enough. It stays quiet with no
|
|
25
|
+
`@font` block, and with a `system` slot, whose OS font has every weight.
|
|
26
|
+
|
|
27
|
+
Where the family *is* named — a `font-<slot>` beside the weight in one
|
|
28
|
+
`@apply` / `@a` / `@utility` class list — that family alone decides:
|
|
29
|
+
|
|
30
|
+
```css
|
|
31
|
+
[data-slot="code"] {
|
|
32
|
+
@a font-mono font-550; /* Fira Code does not provide weight 550. It has 400, 700. */
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The last family in the list wins, and the two classes must share a variant
|
|
37
|
+
prefix (`md:font-mono` does not set the family for a plain `font-550`). A
|
|
38
|
+
weight no font provides is still reported once, by the union check. A class
|
|
39
|
+
written in markup has no list — the scanner keeps only the set of names — so
|
|
40
|
+
the union check governs there.
|
|
41
|
+
|
|
42
|
+
Completions and the generated class types offer `font-100` … `font-900`
|
|
43
|
+
beside the named `@weight` tokens, and read `font-<number>` as an open
|
|
44
|
+
numeric template.
|
|
45
|
+
|
|
46
|
+
- **Three editor capabilities.** `rainbowindex/editor` gains `isSuppressible`
|
|
47
|
+
(`diagnostic-suppression`), so an editor offers a `ri-disable` comment only
|
|
48
|
+
where one would work; `weightIsLoaded` and `describeLoadedWeights`
|
|
49
|
+
(`font-weight-coverage`), the `[RI-1504]` check, so it can answer which
|
|
50
|
+
loaded fonts carry a weight; and `ThemeTokens.radii` / `ThemeTokens.fluidRanges`
|
|
51
|
+
(`named-radii-and-fluid-ranges`), which named radii and named `@fluid` ranges
|
|
52
|
+
had no token surface for. Gate on the capability strings, never on `version`.
|
|
53
|
+
|
|
54
|
+
- **`ri-disable` comments.** Two plain CSS comments silence a diagnostic, so a
|
|
55
|
+
stylesheet carrying them stays valid CSS for every other tool.
|
|
56
|
+
|
|
57
|
+
`/* ri-disable RI-1124 */` anywhere in the CSS entry silences that code
|
|
58
|
+
everywhere. It is the only form that reaches the scanner and compile codes
|
|
59
|
+
(14xx, 15xx), which carry no position in your CSS. One comment may name
|
|
60
|
+
several codes: `/* ri-disable RI-1124, RI-1122 */`.
|
|
61
|
+
|
|
62
|
+
`/* ri-disable-next-line RI-1124 */` silences one place. Inside a scale body
|
|
63
|
+
it guards the entry that follows; outside a body it guards the next
|
|
64
|
+
directive:
|
|
65
|
+
|
|
66
|
+
```css
|
|
67
|
+
@rounded {
|
|
68
|
+
roof: 24px;
|
|
69
|
+
/* ri-disable-next-line RI-1124 */
|
|
70
|
+
full: 30px;
|
|
71
|
+
hut: 8px; /* still checked */
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Entry precision is available where the emitter knows the entry —
|
|
76
|
+
`[RI-1035]`, `[RI-1121]`, `[RI-1122]`, `[RI-1124]`. Other codes fall back to
|
|
77
|
+
the directive.
|
|
78
|
+
|
|
79
|
+
`RI-00xx` and `RI-20xx` cannot be silenced: they report a broken build or a
|
|
80
|
+
broken call, not a style choice. Naming one warns with the new `[RI-1040]`,
|
|
81
|
+
as does a comment that names no readable code.
|
|
82
|
+
|
|
83
|
+
- **`compileProject()` reports what it silenced.** The result gains
|
|
84
|
+
`suppressed`, the set of codes the entry's `ri-disable` comments named, so
|
|
85
|
+
a caller that pushes warnings of its own can drop the ones the author
|
|
86
|
+
hid. Every stage inside the compile already pushes through it.
|
|
87
|
+
|
|
88
|
+
- **Fluid endpoint pairs.** Fluid utilities take both ends of the ramp:
|
|
89
|
+
`p-fluid-4/8` grows from step 4 to step 8 across the `@fluid` range, and
|
|
90
|
+
`text-fluid-sm/3xl` ramps between two type steps. Arbitrary lengths and
|
|
91
|
+
`(--var)` endpoints mix (`p-fluid-[0.5rem]/(--x)`), zero is a legal
|
|
92
|
+
endpoint, and a descending pair (`p-fluid-8/4`) shrinks as the viewport
|
|
93
|
+
grows. Fluid type also takes the line-height modifier now:
|
|
94
|
+
`text-fluid-lg/7`, `text-fluid-sm/3xl/tight`.
|
|
95
|
+
|
|
96
|
+
- **Named `@fluid` ranges and scope classes.** `@fluid compact { min: 20rem;
|
|
97
|
+
max: 48rem; }` defines a range, the tokens `--fluid-compact-{min,max}`, and
|
|
98
|
+
the scope class `fluid-compact`, which points every fluid utility on the
|
|
99
|
+
element and its descendants at that range through the inherited
|
|
100
|
+
`--fluid-scope-{min,max}` pair. A unit on a named range warns with
|
|
101
|
+
`RI-1039`; an unknown range name on the class warns with `RI-1503`.
|
|
102
|
+
|
|
103
|
+
- **Container-query units in `@fluid`.** `unit` accepts `cqw`, `cqi`,
|
|
104
|
+
`cqmin`, and `cqmax`, so fluid ramps can track a container instead of the
|
|
105
|
+
viewport.
|
|
106
|
+
|
|
107
|
+
- **Named radii in `@rounded`.** A key without a `--` prefix now names a
|
|
108
|
+
radius: `@rounded { roof: 24px; }` gives the class `rounded-roof` and the
|
|
109
|
+
token `--rounded-roof`, and the name works with the side and corner
|
|
110
|
+
suffixes (`rounded-tl-roof`). `--corner-scale` is still the only option;
|
|
111
|
+
any other `--` key still warns with `[RI-1122]`. Radii without a name stay
|
|
112
|
+
spacing multiples, so `rounded-4` is unchanged.
|
|
113
|
+
|
|
114
|
+
- **Utility blocks in every named scale.** A `name { … }` or `name-* { … }`
|
|
115
|
+
block in a scale body defines a utility in that scale's class family, so the
|
|
116
|
+
math sits next to the tokens it reads:
|
|
117
|
+
|
|
118
|
+
```css
|
|
119
|
+
@rounded {
|
|
120
|
+
roof: 24px;
|
|
121
|
+
roof-minus-* {
|
|
122
|
+
border-radius: calc(var(--rounded-roof) - var(--value) * var(--spacing));
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
`rounded-roof-minus-2` subtracts two spacing steps from `--rounded-roof`.
|
|
128
|
+
The block uses the `@utility` grammar and the name takes the family's
|
|
129
|
+
prefix. `@rounded`, `@shadow`, `@blur`, `@z`, `@leading`, `@tracking`,
|
|
130
|
+
`@opacity`, `@duration`, `@ease`, `@weight`, `@text` and `@animate` all
|
|
131
|
+
accept them; `@weight` blocks land under `font-`.
|
|
132
|
+
|
|
133
|
+
`@color` does not: a colour name feeds `bg-`, `text-`, `border-`, `ring-`
|
|
134
|
+
and more, so a block would have no one family to land in. `@breakpoint`
|
|
135
|
+
names variants rather than utilities, and `@spacing` holds a single base
|
|
136
|
+
value.
|
|
137
|
+
|
|
138
|
+
A colon is what separates a utility block from the two block grammars that
|
|
139
|
+
already existed. `key: value { … }` stays what it was — `@color` options,
|
|
140
|
+
`@animate` keyframes — and only a block with no key before it is a utility.
|
|
141
|
+
|
|
142
|
+
Radius tokens are written to `:root` whether used or not, because a block
|
|
143
|
+
body is raw CSS that no usage pass can read.
|
|
144
|
+
|
|
145
|
+
- **`@shadow` aliases.** A shadow value that is only another shadow's class
|
|
146
|
+
name now emits a reference to it: `@shadow { md: …; card: shadow-md; }`
|
|
147
|
+
gives `--shadow-card: var(--shadow-md)`. Using `shadow-card` pulls
|
|
148
|
+
`--shadow-md` into `:root` alongside it, so an alias never renders against
|
|
149
|
+
an undefined variable. The target may be defined in a later `@shadow`
|
|
150
|
+
block. An alias to a token that does not exist warns with the new
|
|
151
|
+
`[RI-1123]` and keeps its value verbatim.
|
|
152
|
+
|
|
153
|
+
### Removed
|
|
154
|
+
|
|
155
|
+
- **`@utility` no longer accepts a leading `.` on the name.** `@utility .card`
|
|
156
|
+
used to be silently treated as `@utility card`. No other directive did
|
|
157
|
+
this, and the dot was ignored without a word in `@source inline(".card")`,
|
|
158
|
+
`safelist(".card")`, and `class=".card"` markup, so the one exception
|
|
159
|
+
taught a rule that held nowhere else. A dotted name now warns with
|
|
160
|
+
`[RI-1035]` and is skipped, like every other invalid name. Write
|
|
161
|
+
`@utility card`.
|
|
162
|
+
|
|
163
|
+
- **The shipped shadow scales are gone.** No `shadow-*` tokens ship any more:
|
|
164
|
+
the layered `px`–`2xl` scale and its building blocks (`line`, `drop`,
|
|
165
|
+
`hi-1`–`hi-4`, `dark-line`, `ring`, `layer-1`–`layer-7`) are removed, along
|
|
166
|
+
with the hardcoded `inset-shadow-*`, `text-shadow-*`, and `drop-shadow-*`
|
|
167
|
+
size scales. A shadow is now a project decision, not a shipped opinion.
|
|
168
|
+
Every value form still works — `shadow-none`, `shadow-{color}`,
|
|
169
|
+
`shadow-[v]`, and the same forms for the other three families — and `ring`
|
|
170
|
+
and `inset-ring` are untouched. Named sizes come back with
|
|
171
|
+
`@shadow md: …;`, and bare `shadow` reads the `DEFAULT` token.
|
|
172
|
+
Because the scale is empty by default, bare `shadow` is no longer a
|
|
173
|
+
built-in static utility: it resolves only when the theme defines
|
|
174
|
+
`DEFAULT` (or `md`).
|
|
175
|
+
|
|
176
|
+
- **The last shipped scales are gone: breakpoints, weights, easing, blur,
|
|
177
|
+
animations, and the fluid range.** The package now ships exactly two
|
|
178
|
+
defaults — the colour palette and the `0.25rem` spacing base. Everything
|
|
179
|
+
else is a project decision:
|
|
180
|
+
|
|
181
|
+
| Gone | Was | Comes back with |
|
|
182
|
+
| --- | --- | --- |
|
|
183
|
+
| `sm:` `md:` `lg:` `xl:` and `@sm:` `@md:` … | 40/48/64/80rem | `@breakpoint { sm: 40rem; … }` |
|
|
184
|
+
| `font-thin` … `font-black` | 100–900 | `@weight { bold: 700; … }` |
|
|
185
|
+
| `ease-in`, `ease-out`, `ease-in-out` | cubic-beziers | `@ease { in: cubic-bezier(0.4, 0, 1, 1); … }` |
|
|
186
|
+
| `blur-xs` … `blur-3xl`, bare `blur` | 2px–64px, 8px | `@blur { md: 12px; … }` |
|
|
187
|
+
| `animate-spin`, `animate-pulse`, `animate-bounce`, `animate-ping` | four loops | `@animate { spin: spin 1s linear infinite { … } }` |
|
|
188
|
+
| `p-fluid-*`, `text-fluid-*`, `fluid-<name>` | 20rem–80rem ramp | `@fluid { min: 20rem; max: 80rem; }` |
|
|
189
|
+
|
|
190
|
+
The keyword and arbitrary forms are untouched: `blur-none`, `blur-[3px]`,
|
|
191
|
+
`ease-linear`, `ease-[cubic-bezier(…)]`, `animate-none`, `animate-[…]`,
|
|
192
|
+
`font-[850]`, and the whole enter/exit system (`animate-in`, `fade-in-50`,
|
|
193
|
+
`slide-in-from-top-4`, `blur-in-8`) need no tokens and keep working.
|
|
194
|
+
`max-w-sm` is a container width, not a breakpoint, and is unchanged.
|
|
195
|
+
|
|
196
|
+
Two consequences worth naming. A `@fluid` range no longer half-exists: with
|
|
197
|
+
no `min`/`max` the `--fluid-*` tokens are not written and every fluid
|
|
198
|
+
utility resolves to nothing, rather than ramping across a range nobody
|
|
199
|
+
chose. And `@fluid text`/`@fluid spacing`/named ranges no longer inherit a
|
|
200
|
+
shipped range to fill their gaps — a bound that is absent is simply not
|
|
201
|
+
configured, so `[RI-1022]`/`[RI-1023]` now fire only on a bound you
|
|
202
|
+
actually wrote.
|
|
203
|
+
|
|
204
|
+
- **The shipped type scale is gone.** No `--text-*` tokens ship any more: the
|
|
205
|
+
14-step `2xs`–`9xl` text scale, the `leading-*` scale (`3`–`10`, `none`,
|
|
206
|
+
`tight`, `snug`, `normal`, `relaxed`, `loose`), and the `tracking-*` scale
|
|
207
|
+
(`tighter`–`widest`) are removed. Type is now a project decision, not a
|
|
208
|
+
shipped opinion. Every value form still works — `text-[18px]`,
|
|
209
|
+
`text-lg/[1.5]`, `leading-px`, `leading-[1.5]`, `tracking-[0.1em]` — and
|
|
210
|
+
`text-{color}` is untouched. Named sizes come back with `@text lg: 1.25rem,
|
|
211
|
+
1.4;`, `@leading tight: 1.25;`, and `@tracking wide: 0.025em;`.
|
|
212
|
+
`text-fluid-{size}` needs at least two `@text` steps to interpolate
|
|
213
|
+
between, and the `text-lg/7` modifier reads `@leading` tokens.
|
|
214
|
+
|
|
215
|
+
- **`DEFAULT_TEXT_SIZES` is no longer exported.** `ri()` classified
|
|
216
|
+
`text-{name}` as a size against a hardcoded list that never matched the
|
|
217
|
+
shipped scale (it held `base`, which the scale lacked, and lacked `md`,
|
|
218
|
+
which the scale had). The merger now learns every size name from the
|
|
219
|
+
compiled theme, the way it already learns custom colors and font slots.
|
|
220
|
+
Before the first compile, `text-{name}` reads as a color.
|
|
221
|
+
|
|
222
|
+
### Fixed
|
|
223
|
+
|
|
224
|
+
- **A rejected utility block no longer corrupts the entries beside it.** A
|
|
225
|
+
block is cut from the directive body whether or not its name survived, but
|
|
226
|
+
the body was only swapped in when at least one block parsed. So a scale whose
|
|
227
|
+
blocks were *all* rejected kept its raw `{ … }` text, and the key/value
|
|
228
|
+
parsers — which do not read braces — took the block's own declarations for
|
|
229
|
+
scale entries: `@shadow { bad.name-* { box-shadow: … } }` defined a shadow
|
|
230
|
+
called `box-shadow`. Ten of the twelve block-taking scales were affected;
|
|
231
|
+
`@rounded` and `@animate` parse braces themselves and were not.
|
|
232
|
+
|
|
233
|
+
- **A circular `@shadow` alias chain is reported.** `a: shadow-b; b: shadow-a`
|
|
234
|
+
and the self-alias `a: shadow-a` were accepted and rewritten into `var()`
|
|
235
|
+
references that point at each other, which CSS treats as guaranteed-invalid —
|
|
236
|
+
the shadow resolved to nothing, with nothing said. Both now warn with the new
|
|
237
|
+
`[RI-1125]` and keep their value verbatim, the way `@color` has always
|
|
238
|
+
reported the same shape with `[RI-1107]`. A chain that is not a cycle still
|
|
239
|
+
resolves.
|
|
240
|
+
|
|
241
|
+
- **`FluidUnit` admits the container-query units.** `@fluid { unit: cqw; }`
|
|
242
|
+
validated and emitted correctly, but the exported type still listed only the
|
|
243
|
+
four viewport units, so a `FluidConfig` held a value its own type rejected.
|
|
244
|
+
|
|
245
|
+
- **An empty weight in a `@font` face is no longer read as weight zero.**
|
|
246
|
+
`Number("")` is `0` and finite, so the trailing comma in `weight: 400,700,`
|
|
247
|
+
produced a face covering weight 0 and listed it in the `[RI-1504]` inventory.
|
|
248
|
+
A range is also read either way round now, so `weight: 900 300` describes the
|
|
249
|
+
same span as `300 900`.
|
|
250
|
+
|
|
251
|
+
- **Named radii reach completions.** `@rounded { roof: 24px; }` compiled
|
|
252
|
+
`rounded-roof` and resolved it on hover, but class enumeration never read
|
|
253
|
+
`theme.radii`, so the name was offered by neither the completion list nor the
|
|
254
|
+
generated types — unlike every sibling scale, which reads its own record.
|
|
255
|
+
|
|
256
|
+
- **`ri-disable` now reaches the scanner codes on every surface.** The
|
|
257
|
+
file-wide comment is the only form that can silence a scan warning
|
|
258
|
+
(`RI-14xx`), because those codes carry no position in your CSS — but the
|
|
259
|
+
scanned build path pushed them without consulting it, so
|
|
260
|
+
`/* ri-disable RI-1408 */` worked headless and did nothing under the CLI,
|
|
261
|
+
PostCSS, and Vite. The scan warnings now enter through the same filter as
|
|
262
|
+
every other stage. Vite's `@apply` expansion runs before any compile, so it
|
|
263
|
+
reads the codes straight out of the entry it holds.
|
|
264
|
+
|
|
265
|
+
- **A `ri-disable-next-line` comment outside a directive body reports its own
|
|
266
|
+
mistakes.** Only directive bodies were read for pragma errors, so a typo or
|
|
267
|
+
an unsilenceable code in a top-level comment was ignored without the
|
|
268
|
+
`[RI-1040]` it promises. Such a comment is read once now, and an in-body
|
|
269
|
+
comment still warns exactly once.
|
|
270
|
+
|
|
271
|
+
- **A named scale entry no longer loses to the built-in it shadows.**
|
|
272
|
+
`@shadow { none: … }`, `@blur { none: … }` and `@duration { initial: … }`
|
|
273
|
+
parsed and resolved, then the generator's own keyword branch answered
|
|
274
|
+
first and the value was dropped without a word. Every named scale now
|
|
275
|
+
resolves theme-first, matching `@z`, `@leading`, `@opacity`, and `@ease`,
|
|
276
|
+
which already did.
|
|
277
|
+
|
|
278
|
+
- **`[RI-1408]` no longer fires on large files that hold no variant groups.**
|
|
279
|
+
The expansion budget counted plain pass-through text toward its 100,000
|
|
280
|
+
character limit, so any scanned file over that size warned as soon as it
|
|
281
|
+
held a single `{` — which every JavaScript and TypeScript file does. The
|
|
282
|
+
budget now counts only what expansion adds, so it measures the growth it
|
|
283
|
+
was written to bound. Input (500,000, `[RI-1407]`) and brace depth (10,
|
|
284
|
+
`[RI-1409]`) are unchanged.
|
|
285
|
+
- **A single oversized variant group is measured before it is built.** The
|
|
286
|
+
budget was only read between groups, so one group — its prefix copied onto
|
|
287
|
+
every member — could allocate far past the limit before anything stopped
|
|
288
|
+
it. Each group is now sized first and left verbatim when it does not fit.
|
|
289
|
+
|
|
290
|
+
### Changed
|
|
291
|
+
|
|
292
|
+
- **Clashing with a built-in class name now warns with the new `[RI-1124]`.**
|
|
293
|
+
`@rounded { full: 30px; }` takes over `rounded-full`; the warning names the
|
|
294
|
+
class so the takeover is a choice, not a surprise. It fires for every named
|
|
295
|
+
scale, and only for names the consumer actually wrote — replacing a default
|
|
296
|
+
token such as `@color { red: … }` or `@blur { sm: … }` stays quiet. The set
|
|
297
|
+
of built-in names is read from the generators themselves rather than from a
|
|
298
|
+
hand-kept list, so it cannot drift. Where the built-in belongs to another
|
|
299
|
+
family and keeps the class — `blur-in` is an enter-animation utility that
|
|
300
|
+
only shares the `blur-` prefix — the warning says so instead of claiming a
|
|
301
|
+
takeover that did not happen.
|
|
302
|
+
|
|
303
|
+
- **`ri()` resolves a named animation as an animation.** `animate-{name}`
|
|
304
|
+
merged through a hand-kept list of the shipped names, so a name from
|
|
305
|
+
`@animate` — and now every animation name, since none ships — was not
|
|
306
|
+
classified at all and could not replace another. The `animate-` prefix now
|
|
307
|
+
carries `animation`, the way `ease-` and `blur-` already carried theirs.
|
|
308
|
+
|
|
309
|
+
- **`[RI-1004]` no longer names `sm/md/lg/xl` as built-in variants.** No
|
|
310
|
+
breakpoint ships, so the suggestion pointed at variants that do not exist
|
|
311
|
+
until `@breakpoint` names them. It now says so.
|
|
312
|
+
|
|
313
|
+
- **Variant-group diagnostics name their source file.** `[RI-1407]`,
|
|
314
|
+
`[RI-1408]` and `[RI-1409]` now read `[RI-1408] src/App.tsx: …`, matching
|
|
315
|
+
`[RI-1411]`. Under PostCSS and Vite these warnings carried no location at
|
|
316
|
+
all, so a project-wide warning gave nothing to search for. Warnings
|
|
317
|
+
deduplicate on the full text, so a repeated breach now reports once per
|
|
318
|
+
file instead of once per project.
|
|
319
|
+
|
|
320
|
+
- **A rebuild reads only the files that changed.** `rainbowindex --watch`
|
|
321
|
+
and the Vite dev server now let the watcher own cache invalidation. The
|
|
322
|
+
source file list is cached until a file is added or removed — the CLI
|
|
323
|
+
watcher joins the Vite plugin, which already cached it — and a file's
|
|
324
|
+
scanned classes are trusted until the watcher reports that file changed,
|
|
325
|
+
so a rebuild no longer runs a `stat()` on every source file to learn that
|
|
326
|
+
one of them moved. The union of scanned classes is also kept between
|
|
327
|
+
rebuilds as a multiset, and only the files whose result changed are folded
|
|
328
|
+
again: re-unioning from scratch costs one set insert per class occurrence,
|
|
329
|
+
which on a 2000-file project is roughly 480,000 inserts to rediscover the
|
|
330
|
+
same few hundred names. A one-shot build arms neither cache — with no
|
|
331
|
+
watcher to evict entries, it would serve whatever it read last.
|
|
332
|
+
|
|
333
|
+
- **`compileProject()` reuses its analysis when the CSS is byte-identical.**
|
|
334
|
+
The memo that the CLI, PostCSS, and Vite builds already shared now sits
|
|
335
|
+
with the analysis itself, so the headless API gets it too. Repeat compiles
|
|
336
|
+
of one entry keep a single theme object, which is what every downstream
|
|
337
|
+
cache is keyed on — custom utilities, variants, and the per-class compile
|
|
338
|
+
memo. Warnings and diagnostics are still copied per call, so a caller that
|
|
339
|
+
mutates them cannot corrupt the memo.
|
|
340
|
+
|
|
8
341
|
## [0.5.1] - 2026-08-28
|
|
9
342
|
|
|
10
343
|
### Fixed
|
package/README.md
CHANGED
|
@@ -187,8 +187,8 @@ Supported variants:
|
|
|
187
187
|
- **Pseudo-classes** — `hover`, `focus`, `focus-visible`, `active`, `visited`, `disabled`, `enabled`, `checked`, `empty`, `first`, `last`, `odd`, `even`, `only`
|
|
188
188
|
- **Pseudo-elements** — `before`, `after`, `placeholder`, `file`, `marker`, `selection`, `first-line`, `first-letter`, `backdrop`
|
|
189
189
|
- **Media** — `dark`, `print`, `portrait`, `landscape`, `motion-safe`, `motion-reduce`, `starting`
|
|
190
|
-
- **Breakpoints** —
|
|
191
|
-
- **Container queries** —
|
|
190
|
+
- **Breakpoints** — every name from `@breakpoint`; none ships
|
|
191
|
+
- **Container queries** — the same names with an `@` prefix
|
|
192
192
|
- **Attribute selectors** — `data-[state=open]`, `aria-[pressed=true]`
|
|
193
193
|
- **Arbitrary** — `[selector]`, `[@media(...)]`
|
|
194
194
|
|
|
@@ -238,7 +238,7 @@ Customization happens in your CSS input, not a JS config. The engine recognizes:
|
|
|
238
238
|
| `@spacing` | Set the spacing base unit. |
|
|
239
239
|
| `@text` | Define text size tokens (`size, line-height`). |
|
|
240
240
|
| `@font` | Register font families inside a single `@font { … }` block. Local files are repeatable `face:` entries (e.g. upright + italic). Known families get an automatic zero-CLS metrics fallback (`metrics: none` opts out). Plain `@font-face` rules are standard CSS and pass through untouched. |
|
|
241
|
-
| `@rounded` | Corner shape (`round`, `squircle`, `superellipse(N)`, etc)
|
|
241
|
+
| `@rounded` | Corner shape (`round`, `squircle`, `superellipse(N)`, etc), and named radii. Unnamed radii are spacing multiples: `rounded-4`. |
|
|
242
242
|
| `@fluid` | Configure fluid type/spacing range. |
|
|
243
243
|
| `@animate` | Register named animations with inline `@keyframes`. |
|
|
244
244
|
| `@utility` | Define a custom utility (static or functional `name-*`). |
|
|
@@ -252,6 +252,8 @@ Customization happens in your CSS input, not a JS config. The engine recognizes:
|
|
|
252
252
|
| `@layer` | Place the generated output in cascade layers (intercepted, own grammar). |
|
|
253
253
|
| `@media`, `@import`, other standard at-rules | Standard CSS — passed through untouched. |
|
|
254
254
|
|
|
255
|
+
A named scale can also hold utilities. A `name { … }` block with no colon before it defines a utility in that scale's class family, so `@shadow { lifted-* { … } }` makes `shadow-lifted-*`. See [theming.md](docs/theming.md#utility-blocks).
|
|
256
|
+
|
|
255
257
|
Example:
|
|
256
258
|
|
|
257
259
|
```css
|
|
@@ -283,7 +285,7 @@ Example:
|
|
|
283
285
|
@source not "src/**/legacy/*";
|
|
284
286
|
```
|
|
285
287
|
|
|
286
|
-
|
|
288
|
+
The package ships two defaults: the `colors` palette and the `spacing` base. Every other scale — `text`, `leading`, `tracking`, `shadows`, `radii`, `breakpoints`, `weights`, `easing`, `blur`, `animations`, `fluid`, `z`, `opacity`, `duration` — starts empty, and its directive defines the named tokens. Numeric and keyword class forms are computed, so they work with no theme at all.
|
|
287
289
|
|
|
288
290
|
## `ri()` — runtime class merger
|
|
289
291
|
|
package/dist/browser.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { C as ColorDefinition, a as CompilationContext, b as CompilationSnapshot,
|
|
2
|
-
export { c as createRi, r as ri, s as safelist } from './safelist-
|
|
1
|
+
export { C as ColorDefinition, a as CompilationContext, b as CompilationSnapshot, F as FluidConfig, T as TextSize, c as Theme, d as createCompilationContext, e as defaultTheme, f as finalizeCompilationContext, r as registerColorNames, g as registerCustomFontFamilies, h as registerCustomTextSizes, i as registerCustomUtility } from './index-DSgpB6bS.js';
|
|
2
|
+
export { c as createRi, r as ri, s as safelist } from './safelist-CGCtF-Fr.js';
|
|
3
3
|
|
|
4
4
|
declare function browserEntryUnavailable(): never;
|
|
5
5
|
|
package/dist/browser.mjs
CHANGED
|
@@ -2,7 +2,6 @@ import {
|
|
|
2
2
|
safelist
|
|
3
3
|
} from "./chunk-PD4ZXGJ6.mjs";
|
|
4
4
|
import {
|
|
5
|
-
DEFAULT_TEXT_SIZES,
|
|
6
5
|
createCompilationContext,
|
|
7
6
|
createRi,
|
|
8
7
|
defaultTheme,
|
|
@@ -13,7 +12,7 @@ import {
|
|
|
13
12
|
registerCustomTextSizes,
|
|
14
13
|
registerCustomUtility,
|
|
15
14
|
ri
|
|
16
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-6U4IOFOS.mjs";
|
|
17
16
|
|
|
18
17
|
// src/entries/browser.ts
|
|
19
18
|
function browserEntryUnavailable() {
|
|
@@ -26,7 +25,6 @@ function browserEntryUnavailable() {
|
|
|
26
25
|
}
|
|
27
26
|
var browser_default = browserEntryUnavailable;
|
|
28
27
|
export {
|
|
29
|
-
DEFAULT_TEXT_SIZES,
|
|
30
28
|
createCompilationContext,
|
|
31
29
|
createRi,
|
|
32
30
|
browser_default as default,
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
compileScannedProject
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-WK6S4HTC.mjs";
|
|
4
4
|
import {
|
|
5
5
|
APPLY_ALIASES,
|
|
6
6
|
DIRECTIVE_NAMES_SET,
|
|
7
7
|
MAX_DIRECTIVE_INPUT_SIZE,
|
|
8
8
|
RI_IMPORT_SPECIFIER_ALTERNATION,
|
|
9
9
|
applyVariantWrappers,
|
|
10
|
+
checkAppliedFontWeights,
|
|
10
11
|
compileCSSFunctions,
|
|
11
12
|
computeSortKey,
|
|
12
13
|
expandVariantGroups,
|
|
13
|
-
|
|
14
|
+
forEachApplyClassList,
|
|
14
15
|
hasApplyLikeDirective,
|
|
15
16
|
hasCSSFunctions,
|
|
16
17
|
hasRIActivation,
|
|
@@ -20,7 +21,7 @@ import {
|
|
|
20
21
|
resolveUtilityDeclarations,
|
|
21
22
|
resolveVariant,
|
|
22
23
|
splitSelectorList
|
|
23
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-KSNYSR3C.mjs";
|
|
24
25
|
|
|
25
26
|
// src/integrations/postcss/index.ts
|
|
26
27
|
import postcss2 from "postcss";
|
|
@@ -95,7 +96,7 @@ function resolveFullNestingSelector(rule) {
|
|
|
95
96
|
}
|
|
96
97
|
return composeNestedSelectors(parts);
|
|
97
98
|
}
|
|
98
|
-
function processApply(root, theme, warnings) {
|
|
99
|
+
function processApply(root, theme, warnings, cssPath) {
|
|
99
100
|
for (const alias of APPLY_ALIASES) {
|
|
100
101
|
root.walkAtRules(alias, (atRule) => {
|
|
101
102
|
atRule.name = "apply";
|
|
@@ -117,7 +118,7 @@ function processApply(root, theme, warnings) {
|
|
|
117
118
|
const groupRoots = /* @__PURE__ */ new Set();
|
|
118
119
|
root.walkAtRules("apply", (atRule) => {
|
|
119
120
|
applyNodes.push(atRule);
|
|
120
|
-
const params = expandVariantGroups(atRule.params, warnings);
|
|
121
|
+
const params = expandVariantGroups(atRule.params, warnings, cssPath);
|
|
121
122
|
const classNames = params.trim().split(/\s+/).filter(Boolean);
|
|
122
123
|
classListByNode.set(atRule, classNames);
|
|
123
124
|
if (classNames.includes("group")) {
|
|
@@ -174,6 +175,7 @@ function expandApply(atRule, classNames, theme, warnings, customVariantMap, grou
|
|
|
174
175
|
atRule.remove();
|
|
175
176
|
return;
|
|
176
177
|
}
|
|
178
|
+
checkAppliedFontWeights(classNames, theme, warnings);
|
|
177
179
|
const resolved = [];
|
|
178
180
|
for (const className of classNames) {
|
|
179
181
|
let entry = resolveCache.get(className);
|
|
@@ -374,7 +376,10 @@ function findCustomUtility(utility, value, negative, theme) {
|
|
|
374
376
|
function checkCustomApplyWarnings(cu, theme, warnings, visiting = /* @__PURE__ */ new Set()) {
|
|
375
377
|
if (!hasApplyLikeDirective(cu.body)) return;
|
|
376
378
|
const innerClasses = [];
|
|
377
|
-
|
|
379
|
+
forEachApplyClassList(cu.body, (classes) => {
|
|
380
|
+
checkAppliedFontWeights(classes, theme, warnings);
|
|
381
|
+
innerClasses.push(...classes);
|
|
382
|
+
});
|
|
378
383
|
if (innerClasses.length === 0) return;
|
|
379
384
|
if (visiting.has(cu.name)) {
|
|
380
385
|
warnings.push(
|
|
@@ -582,28 +587,29 @@ var rainbowindex = (options = {}) => {
|
|
|
582
587
|
if (!hasActivation) {
|
|
583
588
|
return;
|
|
584
589
|
}
|
|
590
|
+
const from = root.source?.input?.file ?? root.source?.input?.id ?? root.source?.input?.from ?? "<rainbowindex>";
|
|
585
591
|
const { compiled, warningSeen } = await compileScannedProject({
|
|
586
592
|
css: rawCSS,
|
|
587
593
|
cwd,
|
|
594
|
+
cssPath: from,
|
|
588
595
|
surfacePatterns: options.sources,
|
|
589
596
|
onInvalidPattern: (err) => `[RI-1015] ${err}`
|
|
590
597
|
});
|
|
591
598
|
const compilationWarnings = compiled.warnings;
|
|
592
|
-
const from = root.source?.input?.file ?? root.source?.input?.id ?? root.source?.input?.from ?? "<rainbowindex>";
|
|
593
599
|
stripRIDirectiveNodes(root);
|
|
594
600
|
const slotWarnings = [];
|
|
595
601
|
warnStandaloneSlots(root, slotWarnings);
|
|
596
|
-
pushWarningsDeduped(compilationWarnings, slotWarnings, warningSeen);
|
|
602
|
+
pushWarningsDeduped(compilationWarnings, slotWarnings, warningSeen, compiled.suppressed);
|
|
597
603
|
const applyWarnings = [];
|
|
598
|
-
processApply(root, compiled.theme, applyWarnings);
|
|
599
|
-
pushWarningsDeduped(compilationWarnings, applyWarnings, warningSeen);
|
|
604
|
+
processApply(root, compiled.theme, applyWarnings, from);
|
|
605
|
+
pushWarningsDeduped(compilationWarnings, applyWarnings, warningSeen, compiled.suppressed);
|
|
600
606
|
if (compiled.sections.length > 0) {
|
|
601
607
|
const generatedRoot = postcss2.parse(compiled.sections.join("\n\n"), { from });
|
|
602
608
|
root.prepend(generatedRoot.nodes);
|
|
603
609
|
}
|
|
604
610
|
const cssFnWarnings = [];
|
|
605
611
|
processCSSFunctions(root, compiled.theme, cssFnWarnings);
|
|
606
|
-
pushWarningsDeduped(compilationWarnings, cssFnWarnings, warningSeen);
|
|
612
|
+
pushWarningsDeduped(compilationWarnings, cssFnWarnings, warningSeen, compiled.suppressed);
|
|
607
613
|
for (const warning of compilationWarnings) {
|
|
608
614
|
result.warn(warning);
|
|
609
615
|
}
|