@teacss/classes 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +394 -0
- package/dist/index.d.ts +255 -0
- package/dist/index.js +1 -0
- package/package.json +33 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2021-PRESENT Anthony Fu <https://github.com/antfu>
|
|
4
|
+
Copyright (c) 2026-PRESENT Billgo <hi@billgo.me>
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
in the Software without restriction, including without limitation the rights
|
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
furnished to do so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
# @teacss/classes
|
|
2
|
+
|
|
3
|
+
**Typed class composition and semantic merging for TeaCSS.**
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
This package joins nested class-value inputs and removes earlier TeaCSS tokens
|
|
8
|
+
that are overridden by later tokens under the same condition sequence. The
|
|
9
|
+
algorithm is independent of CSS generation and ships with no runtime
|
|
10
|
+
dependencies: callers provide vocabulary-specific conflict metadata and optional
|
|
11
|
+
merger plugins.
|
|
12
|
+
|
|
13
|
+
It is the low-level package for custom integration and merger authors.
|
|
14
|
+
Applications and component libraries built on the official vocabulary use the
|
|
15
|
+
pre-bound `cn` and `recipe` exports from `teacss`. This package does not
|
|
16
|
+
generate CSS, validate whether a class value is supported, or own the Standard
|
|
17
|
+
and icon vocabularies.
|
|
18
|
+
|
|
19
|
+
## Recipe composition
|
|
20
|
+
|
|
21
|
+
Most applications should use `recipe` from `teacss`. It is pre-bound to
|
|
22
|
+
the official standard-and-icon `cn`, so conflicts are resolved inside each
|
|
23
|
+
recipe output.
|
|
24
|
+
|
|
25
|
+
Use a primitive string for `styles` when a recipe styles one element. Variant
|
|
26
|
+
choices and compound outputs are strings, and calling the recipe returns the
|
|
27
|
+
merged string directly. The call also accepts `className`:
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
import { recipe, type ClassProp, type VariantProps } from "teacss";
|
|
31
|
+
|
|
32
|
+
const badge = recipe({
|
|
33
|
+
styles: "d:inline-flex align-items:center radius:full p-x:2",
|
|
34
|
+
variants: {
|
|
35
|
+
tone: {
|
|
36
|
+
neutral: "bg-color:gray-100 text-color:gray-900",
|
|
37
|
+
accent: "bg-color:blue-500 text-color:white",
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
compoundVariants: [
|
|
41
|
+
{
|
|
42
|
+
tone: "accent",
|
|
43
|
+
className: "font-weight:700",
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
badge({
|
|
49
|
+
tone: "accent",
|
|
50
|
+
className: "p-x:3",
|
|
51
|
+
}); // "d:inline-flex align-items:center radius:full bg-color:blue-500 text-color:white font-weight:700 p-x:3"
|
|
52
|
+
|
|
53
|
+
type BadgeProps = VariantProps<typeof badge> & ClassProp;
|
|
54
|
+
|
|
55
|
+
function badgeClassName({ className, ...variants }: BadgeProps) {
|
|
56
|
+
return badge({ ...variants, className });
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Use a non-empty object for `styles` when a recipe has multiple elements. There
|
|
61
|
+
is no distinguished or required `root` key: every declared key is an ordinary
|
|
62
|
+
style name and becomes a resolver in the result. Variant choices target those
|
|
63
|
+
names with maps; compounds support a targeted map or a shared broadcast:
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
const button = recipe({
|
|
67
|
+
styles: {
|
|
68
|
+
container: "d:inline-flex align-items:center p:2 p:4@md",
|
|
69
|
+
icon: "inline-size:4x",
|
|
70
|
+
label: "",
|
|
71
|
+
},
|
|
72
|
+
variants: {
|
|
73
|
+
size: {
|
|
74
|
+
small: {
|
|
75
|
+
container: "p:2",
|
|
76
|
+
icon: "inline-size:3x",
|
|
77
|
+
},
|
|
78
|
+
large: {
|
|
79
|
+
container: "p:4",
|
|
80
|
+
icon: "inline-size:5x",
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
disabled: {
|
|
84
|
+
true: {
|
|
85
|
+
container: "opacity:50 pointer-events:none",
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
defaultVariants: {
|
|
90
|
+
size: "small",
|
|
91
|
+
disabled: false,
|
|
92
|
+
},
|
|
93
|
+
compoundVariants: [
|
|
94
|
+
{
|
|
95
|
+
size: "large",
|
|
96
|
+
disabled: true,
|
|
97
|
+
className: {
|
|
98
|
+
container: "font-weight:700",
|
|
99
|
+
icon: "inline-size:6x",
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
disabled: true,
|
|
104
|
+
parts: ["container", "icon"],
|
|
105
|
+
className: "opacity:80",
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
const large = button({
|
|
111
|
+
size: "large",
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
large.container({
|
|
115
|
+
disabled: true,
|
|
116
|
+
className: "p:6",
|
|
117
|
+
});
|
|
118
|
+
large.icon();
|
|
119
|
+
large.label();
|
|
120
|
+
|
|
121
|
+
type ButtonProps = VariantProps<typeof button> & ClassProp;
|
|
122
|
+
|
|
123
|
+
function buttonClassName({ className, ...variants }: ButtonProps) {
|
|
124
|
+
const styles = button(variants);
|
|
125
|
+
return styles.container({ className });
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
For an object-style recipe, the recipe call accepts only shared variant
|
|
130
|
+
selections. Each resolver accepts all recipe selections plus `ClassProp`; its
|
|
131
|
+
local selections and `className` apply only to that resolver invocation.
|
|
132
|
+
Compounds are re-evaluated against that local selection without mutating the
|
|
133
|
+
captured recipe result or sibling resolvers. A string-style recipe has no
|
|
134
|
+
resolver layer, so its recipe call accepts `className` and returns a string.
|
|
135
|
+
|
|
136
|
+
Multi-element variant choices are always style-target maps. Each compound uses
|
|
137
|
+
exactly one of two forms: a non-empty `className` target map, or a
|
|
138
|
+
primitive-string `className` paired with a non-empty `parts` array that
|
|
139
|
+
broadcasts the class to every listed effective style. `parts` may contain
|
|
140
|
+
declared or inherited style names and must be dense, duplicate-free, and free
|
|
141
|
+
of unknown names. Matching entries contribute to the selected styles in
|
|
142
|
+
compound declaration order. The two forms cannot be combined, and `parts` is
|
|
143
|
+
reserved as a variant name.
|
|
144
|
+
|
|
145
|
+
The one-sided `disabled` variant above is boolean-capable. `true` is
|
|
146
|
+
branch-backed and emits its fragment; boolean `false` is a distinct branchless
|
|
147
|
+
state that emits no variant fragment but remains available to defaults,
|
|
148
|
+
resolver-local selections, and compound matching. The undeclared string
|
|
149
|
+
`"false"` is not an alias for that branchless state.
|
|
150
|
+
|
|
151
|
+
Responsive and stateful behavior stays in static TeaCSS class values using
|
|
152
|
+
suffix conditions such as `p:4@md` and `bg-color:blue-600@hover`; recipe props
|
|
153
|
+
do not introduce responsive objects.
|
|
154
|
+
|
|
155
|
+
Recipes extend one parent created by the exact same definer. An extending child
|
|
156
|
+
may omit `styles` to inherit the parent's string or object mode, base fragments,
|
|
157
|
+
and existing named styles. If a child declares `styles`, it must preserve that
|
|
158
|
+
mode; an object child may add new names:
|
|
159
|
+
|
|
160
|
+
```ts
|
|
161
|
+
const primaryButton = recipe({
|
|
162
|
+
extend: button,
|
|
163
|
+
variants: {
|
|
164
|
+
emphasis: {
|
|
165
|
+
strong: {
|
|
166
|
+
container: "font-weight:700",
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
const strongBadge = recipe({
|
|
173
|
+
extend: badge,
|
|
174
|
+
styles: "font-weight:700",
|
|
175
|
+
});
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Typed definitions require one finite, statically stable schema. Optional,
|
|
179
|
+
union-valued, or open index-signature key sets for object `styles`, `variants`,
|
|
180
|
+
or variant choices are rejected because they could promise resolvers or
|
|
181
|
+
selections absent from the runtime branch. A `string | object` styles value and
|
|
182
|
+
a union-typed `extend` parent must be narrowed before calling `recipe()`. Finite
|
|
183
|
+
required named interfaces are accepted without an artificial string index
|
|
184
|
+
signature. `__proto__` is reserved as a statically unsafe schema name because
|
|
185
|
+
ordinary object-literal syntax does not create a predictable own property for
|
|
186
|
+
it; an explicitly constructed null-prototype runtime record can still carry
|
|
187
|
+
that own name safely.
|
|
188
|
+
|
|
189
|
+
Every definition without `extend` requires its own `styles` field. An explicitly
|
|
190
|
+
declared object `styles` value must contain at least one key. The superseded
|
|
191
|
+
top-level definition field `parts` is not accepted as a compatibility alias;
|
|
192
|
+
it is distinct from supported nested `compoundVariants[].parts`.
|
|
193
|
+
|
|
194
|
+
### Definer creation
|
|
195
|
+
|
|
196
|
+
`@teacss/classes` exports the `createDefiner` factory and no pre-bound
|
|
197
|
+
definer. Each integration binds its own merger once and exports the
|
|
198
|
+
result under the name appropriate for that integration:
|
|
199
|
+
|
|
200
|
+
```ts
|
|
201
|
+
import { createDefiner, createMerger } from "@teacss/classes";
|
|
202
|
+
|
|
203
|
+
export const merge = createMerger({ conflicts, plugins });
|
|
204
|
+
export const recipe = createDefiner({ merge });
|
|
205
|
+
|
|
206
|
+
export const libraryButton = recipe({
|
|
207
|
+
styles: "p:2",
|
|
208
|
+
});
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
`createDefiner` accepts the required `merge` field; there is no default merger
|
|
212
|
+
and no `merger` alias. Extension identity belongs to the exact definer function,
|
|
213
|
+
not merely to the merger. Its return type is the type-only `RecipeDefiner`
|
|
214
|
+
export, so an integration can re-export its definer without inlining the
|
|
215
|
+
complete generic recipe contract into generated declarations.
|
|
216
|
+
|
|
217
|
+
Libraries that export official recipes for downstream extension peer-depend on
|
|
218
|
+
and externalize `teacss`, which owns the official definer. A custom integration
|
|
219
|
+
peer-depends on `@teacss/classes` and exports the exact definer used to create
|
|
220
|
+
its parents. Consumers deduplicate that owning integration. Recreating a
|
|
221
|
+
definer, loading another physical or versioned runtime, or loading the parent
|
|
222
|
+
and definer from different provider-package instances breaks extension
|
|
223
|
+
identity even when declarations and merger behavior match. Deduplicating only
|
|
224
|
+
`@teacss/classes` does not repair a duplicated custom-definer provider.
|
|
225
|
+
`VariantProps` extraction is type-only and needs no runtime identity; only
|
|
226
|
+
`extend` has this exact-identity requirement.
|
|
227
|
+
|
|
228
|
+
## Class merging
|
|
229
|
+
|
|
230
|
+
```sh
|
|
231
|
+
bun add @teacss/classes
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
```ts
|
|
235
|
+
import { createMerger } from "@teacss/classes";
|
|
236
|
+
|
|
237
|
+
const cn = createMerger({
|
|
238
|
+
conflicts: {
|
|
239
|
+
keywords: {
|
|
240
|
+
flex: "display",
|
|
241
|
+
hidden: "display",
|
|
242
|
+
},
|
|
243
|
+
overlaps: {
|
|
244
|
+
p: ["padding-top", "padding-right", "padding-bottom", "padding-left"],
|
|
245
|
+
"p-x": ["padding-left", "padding-right"],
|
|
246
|
+
},
|
|
247
|
+
},
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
cn("p:4 flex", "p:8"); // "flex p:8"
|
|
251
|
+
cn("p:4", "p-x:8"); // "p:4 p-x:8"
|
|
252
|
+
cn("p:4", "p-x:8!"); // "p:4 p-x:8!"
|
|
253
|
+
cn('content:["hello world"]', 'content:["good bye"]'); // 'content:["good bye"]'
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
Attached `[]` literal regions keep their internal whitespace in one token and
|
|
257
|
+
protect braces and semicolons from group expansion. Braces inside attached
|
|
258
|
+
`()` CSS functions are likewise not mistaken for groups. Top-level
|
|
259
|
+
`{p:4;m:2}@hover` group syntax still expands normally.
|
|
260
|
+
|
|
261
|
+
For the standard TeaCSS vocabulary, use the pre-bound merger instead:
|
|
262
|
+
|
|
263
|
+
```ts
|
|
264
|
+
import { cn } from "@teacss/preset-standard/merge";
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
## Merger API
|
|
268
|
+
|
|
269
|
+
`createMerger(options?)` returns a callable `Merger` that accepts strings,
|
|
270
|
+
mutable or readonly nested arrays and tuples, conditional class dictionaries,
|
|
271
|
+
falsy values, numbers, and tagged templates. It preserves the order of
|
|
272
|
+
surviving tokens; it does not sort them. Finite named interfaces are valid
|
|
273
|
+
class dictionaries and conflict tables; runtime protocol validation still
|
|
274
|
+
checks every supplied conflict atom.
|
|
275
|
+
|
|
276
|
+
Tagged-template literal segments and resolved expressions concatenate exactly.
|
|
277
|
+
Put whitespace in the template wherever two class tokens need a boundary:
|
|
278
|
+
|
|
279
|
+
```ts
|
|
280
|
+
cn`p:${0}`; // "p:0"
|
|
281
|
+
cn`p:4@${"hover"}`; // "p:4@hover"
|
|
282
|
+
cn`${"p:4"} ${"m:2"}`; // "p:4 m:2"
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
Options:
|
|
286
|
+
|
|
287
|
+
- `conflicts`: keyword and shorthand/longhand conflict footprints.
|
|
288
|
+
- `overlap`: `"precise"` by default, or `"symmetric"` for last-intersection
|
|
289
|
+
wins between equal-importance tokens. Differing importance still requires
|
|
290
|
+
full winner coverage.
|
|
291
|
+
- `plugins`: ordered, uniquely named plugins with optional static `conflicts`,
|
|
292
|
+
token transforms, dynamic groups, drop-only finalizers, and pair resolvers.
|
|
293
|
+
- `cache`: one input LRU shared by normal and tagged-template calls, or `false`
|
|
294
|
+
to disable caching. `cache.max` defaults to `1500` and must be a finite
|
|
295
|
+
non-negative integer; `0` disables caching.
|
|
296
|
+
|
|
297
|
+
Each static conflict value is one atom or a readonly atom array. Static metadata
|
|
298
|
+
is composed once from top-level options and then plugins. Identical atom sets
|
|
299
|
+
deduplicate; a different set for the same keyword or declaration key is a
|
|
300
|
+
protocol error. Keyword and declaration keys are separate namespaces.
|
|
301
|
+
Shared CSS atoms use CSS property names; a third-party private atom must begin
|
|
302
|
+
with that plugin's unique name.
|
|
303
|
+
|
|
304
|
+
```ts
|
|
305
|
+
import {
|
|
306
|
+
createMerger,
|
|
307
|
+
MERGE_OPAQUE,
|
|
308
|
+
type MergerPlugin,
|
|
309
|
+
} from "@teacss/classes";
|
|
310
|
+
|
|
311
|
+
const plugin: MergerPlugin = {
|
|
312
|
+
name: "example-icons",
|
|
313
|
+
conflicts: {
|
|
314
|
+
keywords: {},
|
|
315
|
+
overlaps: { icon: "example-icons:icon" },
|
|
316
|
+
},
|
|
317
|
+
group(token) {
|
|
318
|
+
if (token.keyword || token.prefix !== "icon") return null;
|
|
319
|
+
return token.value?.includes("-") ? null : MERGE_OPAQUE;
|
|
320
|
+
},
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
const cn = createMerger({ plugins: [plugin] });
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
`MERGE_OPAQUE` is terminal classification. Different opaque raw strings survive;
|
|
327
|
+
an exact duplicate keeps only its last occurrence and never enters finalizers or
|
|
328
|
+
pair resolution. Import and return the named marker rather than raw `false`.
|
|
329
|
+
|
|
330
|
+
Token transforms receive a readonly token list and a run-local `viewToken()`
|
|
331
|
+
function. Their result must be an array of individual non-empty class tokens;
|
|
332
|
+
whitespace is valid only inside an attached `[]` literal region. Transform
|
|
333
|
+
output is not split or group-expanded again. Dynamic
|
|
334
|
+
`group()` hooks return atoms, `MERGE_OPAQUE`, or `null`. `finalize()` receives
|
|
335
|
+
current non-opaque occurrences with stable ids and may only return ids to drop;
|
|
336
|
+
`null` and `[]` both drop nothing. Every returned id must be an integer, unique,
|
|
337
|
+
and present in that exact input. Core validates the whole result before applying
|
|
338
|
+
any drop. `resolve()` may return `"earlier"`, `"later"`, `"none"`, or `null`.
|
|
339
|
+
Its context reports real full coverage in both directions through `covers`
|
|
340
|
+
(later over earlier) and `earlierCoversLater`, independently of symmetric mode.
|
|
341
|
+
|
|
342
|
+
A resolver is global by default. A plugin may add `resolveFamily(token)` to
|
|
343
|
+
scope it: the family hook runs once per non-opaque occurrence, and `resolve()`
|
|
344
|
+
is considered only when both tokens return the same non-empty family. A
|
|
345
|
+
`resolveFamily` hook requires a `resolve` hook. Use this metadata whenever a
|
|
346
|
+
resolver owns a finite semantic family. A run made entirely of one unowned
|
|
347
|
+
static prefix, such as standard `p:*`, can then use the linear winner path;
|
|
348
|
+
dynamic groups and resolver-owned families still use pair resolution.
|
|
349
|
+
|
|
350
|
+
The package exports the `MergerProtocolError` class and the
|
|
351
|
+
`MergerProtocolErrorCode` type. Errors expose `code` plus optional `plugin` and
|
|
352
|
+
`hook` fields. Stable codes distinguish malformed options, cache bounds,
|
|
353
|
+
conflict metadata, plugin names and hooks, static conflicts, and invalid
|
|
354
|
+
transform, group, finalizer, resolver-family, or resolver results. Hook
|
|
355
|
+
exceptions are propagated unchanged. A failed run writes no input-LRU entry.
|
|
356
|
+
|
|
357
|
+
Only own option, cache, conflict-shape, plugin-name, and plugin-hook fields are
|
|
358
|
+
used; inherited prototype fields cannot alter a merger. Plugin arrays, own hook
|
|
359
|
+
references, static records, and atom arrays are snapshotted when
|
|
360
|
+
`createMerger()` runs. Array-shaped protocol results are validated from a fixed
|
|
361
|
+
length and own numeric indexes; custom iterators and inherited sparse entries
|
|
362
|
+
are not trusted. Every accepted array length must be an integer from `0` through
|
|
363
|
+
`4294967294`; malformed plugin, metadata, and hook arrays retain their
|
|
364
|
+
surface-specific protocol codes, while malformed class-value and tagged-template
|
|
365
|
+
arrays report `INVALID_ARRAY_LENGTH`. Hooks are called with
|
|
366
|
+
`this === undefined` and should be pure. If a hook closes over mutable state,
|
|
367
|
+
use `cache: false`.
|
|
368
|
+
|
|
369
|
+
## Conflict Semantics
|
|
370
|
+
|
|
371
|
+
Only tokens with the same ordered condition sequence and intersecting atom
|
|
372
|
+
footprints are candidates. When importance differs, the important token removes
|
|
373
|
+
the non-important token only when its footprint fully covers the token being
|
|
374
|
+
removed; partial overlaps survive so unrelated declarations are not lost. With
|
|
375
|
+
equal importance, precise mode drops an earlier token only when the later
|
|
376
|
+
footprint covers it; symmetric mode treats any intersection as coverage.
|
|
377
|
+
Surviving tokens keep their original order. A custom `resolve()` hook remains an
|
|
378
|
+
explicit override of the default verdict.
|
|
379
|
+
|
|
380
|
+
Merge never validates TeaCSS or CSS values. A structurally parsed declaration
|
|
381
|
+
uses its declared or fallback footprint even when the value is unsupported or
|
|
382
|
+
empty:
|
|
383
|
+
|
|
384
|
+
```ts
|
|
385
|
+
cn("p:4", "p:invalid"); // "p:invalid"
|
|
386
|
+
cn("p:4", "p:"); // "p:"
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
Run `bun run bench:merger` from the workspace root to measure the uncached
|
|
390
|
+
standard static-prefix `p:*` path at 500, 1,000, 2,000, and 4,000 tokens.
|
|
391
|
+
|
|
392
|
+
## Status
|
|
393
|
+
|
|
394
|
+
Pre-1.0. Public recipe and merge APIs may change before the stable release.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
//#region src/merge.d.ts
|
|
2
|
+
type ClassDict = Record<string, any>;
|
|
3
|
+
type ClassValue = string | number | bigint | null | undefined | boolean | readonly ClassValue[] | ClassDict;
|
|
4
|
+
type ConflictAtoms = string | readonly string[];
|
|
5
|
+
type ConflictTable = Readonly<Record<string, ConflictAtoms>>;
|
|
6
|
+
type IsAny$1<Value> = 0 extends 1 & Value ? true : false;
|
|
7
|
+
type NonRecordObject = readonly unknown[] | ((...args: any[]) => any) | (abstract new (...args: any[]) => any);
|
|
8
|
+
type ValidateConflictTable<Table extends object> = Table extends NonRecordObject ? never : { readonly [Key in keyof Table]: IsAny$1<Table[Key]> extends true ? Table[Key] : Table[Key] extends ConflictAtoms ? Table[Key] : never; };
|
|
9
|
+
interface ConflictMeta<Keywords extends object = ConflictTable, Overlaps extends object = ConflictTable> {
|
|
10
|
+
readonly keywords: ValidateConflictTable<Keywords>;
|
|
11
|
+
readonly overlaps: ValidateConflictTable<Overlaps>;
|
|
12
|
+
}
|
|
13
|
+
interface MergerTokenView {
|
|
14
|
+
readonly raw: string;
|
|
15
|
+
readonly prefix: string;
|
|
16
|
+
readonly body: string;
|
|
17
|
+
readonly value?: string;
|
|
18
|
+
readonly keyword: boolean;
|
|
19
|
+
readonly conditions: readonly string[];
|
|
20
|
+
readonly important: boolean;
|
|
21
|
+
}
|
|
22
|
+
interface MergerTokenOccurrence {
|
|
23
|
+
/** Zero-based ordinal in the final transformed raw list and stable run-local id. */
|
|
24
|
+
readonly id: number;
|
|
25
|
+
readonly view: MergerTokenView;
|
|
26
|
+
readonly atoms: readonly string[];
|
|
27
|
+
}
|
|
28
|
+
type ResolveVerdict = "earlier" | "later" | "none";
|
|
29
|
+
/** Dedicated, allocation-free classification result. */
|
|
30
|
+
declare const MERGE_OPAQUE: false;
|
|
31
|
+
interface MergerPlugin<Keywords extends object = ConflictTable, Overlaps extends object = ConflictTable> {
|
|
32
|
+
readonly name: string;
|
|
33
|
+
readonly conflicts?: ConflictMeta<Keywords, Overlaps>;
|
|
34
|
+
readonly tokens?: (this: void, tokens: readonly string[], context: {
|
|
35
|
+
readonly viewToken: (raw: string) => MergerTokenView;
|
|
36
|
+
}) => readonly string[];
|
|
37
|
+
readonly group?: (this: void, token: MergerTokenView) => ConflictAtoms | typeof MERGE_OPAQUE | null;
|
|
38
|
+
readonly finalize?: (this: void, tokens: readonly MergerTokenOccurrence[]) => readonly number[] | null;
|
|
39
|
+
/**
|
|
40
|
+
* Optionally scope this plugin's resolver. The resolver is considered only
|
|
41
|
+
* when both tokens return the same non-empty family.
|
|
42
|
+
*/
|
|
43
|
+
readonly resolveFamily?: (this: void, token: MergerTokenView) => string | null;
|
|
44
|
+
readonly resolve?: (this: void, earlier: MergerTokenView, later: MergerTokenView, context: {
|
|
45
|
+
/** Whether the later footprint fully covers the earlier footprint. */
|
|
46
|
+
readonly covers: boolean;
|
|
47
|
+
/** Whether the earlier footprint fully covers the later footprint. */
|
|
48
|
+
readonly earlierCoversLater: boolean;
|
|
49
|
+
readonly defaultDrop: ResolveVerdict;
|
|
50
|
+
}) => ResolveVerdict | null;
|
|
51
|
+
}
|
|
52
|
+
type OverlapMode = "precise" | "symmetric";
|
|
53
|
+
interface MergerOptions<Keywords extends object = ConflictTable, Overlaps extends object = ConflictTable> {
|
|
54
|
+
/** Keyword + overlap tables. Absent means generic same-prefix merging only. */
|
|
55
|
+
readonly conflicts?: ConflictMeta<Keywords, Overlaps>;
|
|
56
|
+
/** Equal-importance overlap rule. Default `"precise"` (asymmetric containment). */
|
|
57
|
+
readonly overlap?: OverlapMode;
|
|
58
|
+
readonly plugins?: readonly MergerPlugin[];
|
|
59
|
+
/** Shared input-LRU bound. `max` is a finite non-negative integer; default 1500. */
|
|
60
|
+
readonly cache?: {
|
|
61
|
+
readonly max?: number;
|
|
62
|
+
} | false;
|
|
63
|
+
}
|
|
64
|
+
type ConflictMetaCarrier = {
|
|
65
|
+
readonly keywords: Readonly<Record<string, any>>;
|
|
66
|
+
readonly overlaps: Readonly<Record<string, any>>;
|
|
67
|
+
};
|
|
68
|
+
type MergerPluginCarrier = {
|
|
69
|
+
readonly name: string;
|
|
70
|
+
readonly conflicts?: ConflictMetaCarrier;
|
|
71
|
+
readonly tokens?: MergerPlugin["tokens"];
|
|
72
|
+
readonly group?: MergerPlugin["group"];
|
|
73
|
+
readonly finalize?: MergerPlugin["finalize"];
|
|
74
|
+
readonly resolveFamily?: MergerPlugin["resolveFamily"];
|
|
75
|
+
readonly resolve?: MergerPlugin["resolve"];
|
|
76
|
+
};
|
|
77
|
+
type MergerOptionsCarrier = {
|
|
78
|
+
readonly conflicts?: ConflictMetaCarrier;
|
|
79
|
+
readonly overlap?: OverlapMode;
|
|
80
|
+
readonly plugins?: readonly MergerPluginCarrier[];
|
|
81
|
+
readonly cache?: {
|
|
82
|
+
readonly max?: number;
|
|
83
|
+
} | false;
|
|
84
|
+
};
|
|
85
|
+
type InvalidConflictTable<Table> = IsAny$1<Table> extends true ? never : Table extends NonRecordObject ? "invalid conflict table" : Table extends object ? { readonly [Key in Extract<keyof Table, string | number>]-?: IsAny$1<Table[Key]> extends true ? never : Table[Key] extends ConflictAtoms ? never : Key; }[Extract<keyof Table, string | number>] : "invalid conflict table";
|
|
86
|
+
type InvalidConflictMeta<Meta> = IsAny$1<Meta> extends true ? never : Meta extends {
|
|
87
|
+
readonly keywords: infer Keywords;
|
|
88
|
+
readonly overlaps: infer Overlaps;
|
|
89
|
+
} ? Exclude<Extract<keyof Meta, string | number>, "keywords" | "overlaps"> | InvalidConflictTable<Keywords> | InvalidConflictTable<Overlaps> : "invalid conflict metadata";
|
|
90
|
+
type InvalidPlugin<Plugin> = Plugin extends unknown ? IsAny$1<Plugin> extends true ? never : Plugin extends MergerPluginCarrier ? Exclude<Extract<keyof Plugin, string | number>, Extract<keyof MergerPluginCarrier, string | number>> | ("conflicts" extends keyof Plugin ? InvalidConflictMeta<Exclude<Plugin["conflicts"], undefined>> : never) : "invalid plugin" : never;
|
|
91
|
+
type InvalidPlugins<Plugins> = Plugins extends readonly (infer Plugin)[] ? InvalidPlugin<Plugin> : "invalid plugins";
|
|
92
|
+
type InvalidMergerOptions<Options> = IsAny$1<Options> extends true ? never : Options extends MergerOptionsCarrier ? Exclude<Extract<keyof Options, string | number>, Extract<keyof MergerOptionsCarrier, string | number>> | ("conflicts" extends keyof Options ? InvalidConflictMeta<Exclude<Options["conflicts"], undefined>> : never) | ("plugins" extends keyof Options ? InvalidPlugins<Exclude<Options["plugins"], undefined>> : never) : "invalid merger options";
|
|
93
|
+
interface Merger {
|
|
94
|
+
(strings: TemplateStringsArray, ...expressions: ClassValue[]): string;
|
|
95
|
+
(...inputs: ClassValue[]): string;
|
|
96
|
+
}
|
|
97
|
+
type MergerProtocolErrorCode = "INVALID_ARRAY_LENGTH" | "INVALID_OPTIONS" | "INVALID_CACHE_OPTIONS" | "INVALID_CONFLICT_META" | "INVALID_PLUGIN_NAME" | "DUPLICATE_PLUGIN_NAME" | "INVALID_PLUGIN_HOOK" | "INVALID_STATIC_CONFLICT" | "STATIC_CONFLICT_COLLISION" | "INVALID_TOKEN_TRANSFORM_RESULT" | "INVALID_GROUP_RESULT" | "INVALID_FINALIZER_RESULT" | "INVALID_RESOLVE_FAMILY_RESULT" | "INVALID_RESOLVE_RESULT";
|
|
98
|
+
declare class MergerProtocolError extends TypeError {
|
|
99
|
+
readonly name: "MergerProtocolError";
|
|
100
|
+
readonly code: MergerProtocolErrorCode;
|
|
101
|
+
readonly plugin?: string;
|
|
102
|
+
readonly hook?: "tokens" | "group" | "finalize" | "resolveFamily" | "resolve";
|
|
103
|
+
constructor(code: MergerProtocolErrorCode, detail: string, plugin?: string, hook?: "tokens" | "group" | "finalize" | "resolveFamily" | "resolve");
|
|
104
|
+
}
|
|
105
|
+
/** Build a merger bound to static footprints, overlap mode, plugins, and cache. */
|
|
106
|
+
declare function createMerger<const Options extends MergerOptionsCarrier = {}>(options?: MergerOptionsCarrier & Options & (InvalidMergerOptions<Options> extends never ? unknown : never)): Merger;
|
|
107
|
+
declare function createMerger(options?: MergerOptions): Merger;
|
|
108
|
+
//#endregion
|
|
109
|
+
//#region src/recipe.d.ts
|
|
110
|
+
type ClassProp = {
|
|
111
|
+
className?: ClassValue;
|
|
112
|
+
};
|
|
113
|
+
type RecipeMerger = (this: void, ...inputs: ClassValue[]) => string;
|
|
114
|
+
type RecipeDefinerOptions = {
|
|
115
|
+
readonly apply?: never;
|
|
116
|
+
readonly bind?: never;
|
|
117
|
+
readonly call?: never;
|
|
118
|
+
readonly length?: never;
|
|
119
|
+
readonly merge: RecipeMerger;
|
|
120
|
+
readonly prototype?: never;
|
|
121
|
+
};
|
|
122
|
+
type ReservedPartName = "class" | "className" | "then" | "toJSON" | "toString" | "valueOf";
|
|
123
|
+
type ReservedVariantName = "class" | "className" | "parts";
|
|
124
|
+
type StaticallyUnsafeSchemaName = "__proto__";
|
|
125
|
+
type CanonicalKey<Key> = Key extends string ? Key : Key extends number ? `${Key}` : never;
|
|
126
|
+
type CanonicalKeys<Value> = CanonicalKey<Extract<keyof Value, string | number>>;
|
|
127
|
+
type SchemaWhitespace = "\t" | "\v" | "\f" | " " | " " | " " | " " | " " | " " | " " | " " | " " | " " | " " | " " | " " | " " | "
" | "
" | " " | " " | " " | "" | "\n" | "\r";
|
|
128
|
+
type StripLeadingWhitespace<Value extends string> = Value extends `${SchemaWhitespace}${infer Rest}` ? StripLeadingWhitespace<Rest> : Value;
|
|
129
|
+
type WhitespaceOnlyName<Name extends string> = Name extends unknown ? (StripLeadingWhitespace<Name> extends "" ? Name : never) : never;
|
|
130
|
+
type NumericChoiceInput<Key extends string> = Key extends `${infer Numeric extends number}` ? (number extends Numeric ? never : `${Numeric}` extends Key ? Numeric : never) : never;
|
|
131
|
+
type ChoiceInput<Choices extends string> = Choices | NumericChoiceInput<Choices> | (Extract<Choices, "true" | "false"> extends never ? never : boolean);
|
|
132
|
+
type VariantSelection<Choices extends string> = ChoiceInput<Choices> | null;
|
|
133
|
+
type VariantSchema = Readonly<Record<string, string>>;
|
|
134
|
+
type RecordInput = Readonly<Record<string, any>>;
|
|
135
|
+
type NonRecordInput = readonly unknown[] | ((...args: any[]) => any) | (abstract new (...args: any[]) => any);
|
|
136
|
+
type VariantSelections<Variants extends VariantSchema> = keyof Variants extends never ? Readonly<Record<symbol, unknown>> : { readonly [Name in keyof Variants]?: VariantSelection<Extract<Variants[Name], string>> | undefined; };
|
|
137
|
+
type DefinitionVariantSelections<Variants extends VariantSchema> = VariantSelections<Variants> & Readonly<Record<symbol, unknown>>;
|
|
138
|
+
type RecipeCarrier = {
|
|
139
|
+
readonly [Symbol.unscopables]: never;
|
|
140
|
+
};
|
|
141
|
+
type IsAny<Value> = 0 extends 1 & Value ? true : false;
|
|
142
|
+
type IsUnion<Value, Whole = Value> = IsAny<Value> extends true ? false : Value extends Whole ? ([Whole] extends [Value] ? false : true) : never;
|
|
143
|
+
type InvalidRecordShape<Value> = Value extends unknown ? (Value extends NonRecordInput ? true : false) : never;
|
|
144
|
+
type OptionalSchemaKeys<Value> = Value extends unknown ? { [Key in Extract<keyof Value, string | number>]-?: {} extends Pick<Value, Key> ? Key : never; }[Extract<keyof Value, string | number>] : never;
|
|
145
|
+
type OpenSchemaKeys<Value> = string extends keyof Value ? string : number extends keyof Value ? number : never;
|
|
146
|
+
type ValidateStableSchema<Value> = IsAny<Value> extends true ? unknown : true extends IsUnion<Value> ? never : true extends InvalidRecordShape<Value> ? never : OpenSchemaKeys<Value> extends never ? (OptionalSchemaKeys<Value> extends never ? unknown : never) : never;
|
|
147
|
+
type ValidateNonUnion<Value> = IsAny<Value> extends true ? unknown : true extends IsUnion<Value> ? never : unknown;
|
|
148
|
+
type ValidateRecordShape<Value> = IsAny<Value> extends true ? unknown : true extends InvalidRecordShape<Value> ? never : unknown;
|
|
149
|
+
type ValidateKnownKeys<Value, Keys extends PropertyKey> = IsAny<Value> extends true ? unknown : Exclude<Extract<keyof Value, string | number>, Keys> extends never ? unknown : never;
|
|
150
|
+
type ValidatePropsInput<Input, Props> = IsAny<Input> extends true ? unknown : true extends InvalidRecordShape<Exclude<Input, undefined>> ? never : Exclude<CanonicalKeys<Exclude<Input, undefined>>, CanonicalKeys<Props>> extends never ? unknown : never;
|
|
151
|
+
type PartProps<Variants extends VariantSchema> = keyof Variants extends never ? ClassProp : VariantSelections<Variants> & ClassProp;
|
|
152
|
+
type SingleRecipeProps<Variants extends VariantSchema> = VariantSelections<Variants> & ClassProp;
|
|
153
|
+
type RecipeResult<Parts extends string, Variants extends VariantSchema> = { readonly [Part in Parts]: <const Input>(props?: Input & PartProps<Variants> & NoInfer<ValidatePropsInput<Input, PartProps<Variants>>>) => string; };
|
|
154
|
+
type TeaRecipeResult<Parts extends string, Variants extends VariantSchema> = RecipeResult<Parts, Variants>;
|
|
155
|
+
type TeaSingleRecipe<Variants extends VariantSchema> = (<const Input>(props?: Input & SingleRecipeProps<Variants> & NoInfer<ValidatePropsInput<Input, SingleRecipeProps<Variants>>>) => string) & RecipeCarrier;
|
|
156
|
+
type TeaMultipartRecipe<Parts extends string, Variants extends VariantSchema> = (<const Input>(props?: Input & VariantSelections<Variants> & NoInfer<ValidatePropsInput<Input, VariantSelections<Variants>>>) => TeaRecipeResult<Parts, Variants>) & RecipeCarrier;
|
|
157
|
+
type BrandedRecipe = Function & RecipeCarrier;
|
|
158
|
+
type SingleBrandedRecipe = BrandedRecipe & ((props?: any) => string);
|
|
159
|
+
type MultipartBrandedRecipe = BrandedRecipe & ((props?: any) => Readonly<Record<string, (props?: any) => string>>);
|
|
160
|
+
type SchemaFromSelections<Selections> = { readonly [Name in Exclude<Extract<keyof NonNullable<Selections>, string>, keyof ClassProp>]: Extract<NonNullable<Selections>[Name], string>; };
|
|
161
|
+
type ParentSchema<Parent> = [Parent] extends [RecipeCarrier & ((props?: infer Selections) => infer Result)] ? {
|
|
162
|
+
readonly styles: Result extends string ? never : Extract<keyof Result, string>;
|
|
163
|
+
readonly variants: SchemaFromSelections<Selections>;
|
|
164
|
+
} : {
|
|
165
|
+
readonly styles: never;
|
|
166
|
+
readonly variants: {};
|
|
167
|
+
};
|
|
168
|
+
type ParentStyles<Parent> = Extract<ParentSchema<Parent>["styles"], string>;
|
|
169
|
+
type ParentVariants<Parent> = ParentSchema<Parent>["variants"] extends (infer Variants extends VariantSchema) ? Variants : {};
|
|
170
|
+
type StylesInput = RecordInput;
|
|
171
|
+
type PartNames<Styles> = CanonicalKeys<Styles>;
|
|
172
|
+
type EffectiveParts<Parent, Styles> = ParentStyles<Parent> | PartNames<Styles>;
|
|
173
|
+
type PartTargetMap<Parts extends string> = Readonly<Partial<Record<Parts, ClassValue>>>;
|
|
174
|
+
type VariantsInput = RecordInput;
|
|
175
|
+
type OwnVariantSchema<Variants> = [Variants] extends [VariantsInput] ? { readonly [Name in keyof Variants as CanonicalKey<Name>]: CanonicalKeys<Variants[Name]>; } : {};
|
|
176
|
+
type VariantChoicesAt<Schema, Name extends PropertyKey> = Extract<Schema extends Readonly<Record<Name, infer Choices>> ? Choices : never, string>;
|
|
177
|
+
type MergeVariantSchemas<Parent, Child> = { readonly [Name in Extract<keyof Parent | keyof Child, string>]: VariantChoicesAt<Parent, Name> | VariantChoicesAt<Child, Name>; };
|
|
178
|
+
type EffectiveVariants<Parent, Variants> = MergeVariantSchemas<ParentVariants<Parent>, OwnVariantSchema<Variants>>;
|
|
179
|
+
type CompoundConditions<Variants extends VariantSchema> = { readonly [Name in keyof Variants]?: VariantSelection<Extract<Variants[Name], string>> | readonly [VariantSelection<Extract<Variants[Name], string>>, ...VariantSelection<Extract<Variants[Name], string>>[]]; };
|
|
180
|
+
type SingleCompoundDefinition<Variants extends VariantSchema> = {
|
|
181
|
+
readonly className: string;
|
|
182
|
+
} & CompoundConditions<Variants>;
|
|
183
|
+
type MultipartCompoundDefinition<Parts extends string, Variants extends VariantSchema> = ({
|
|
184
|
+
readonly className: PartTargetMap<NoInfer<Parts>>;
|
|
185
|
+
readonly parts?: never;
|
|
186
|
+
} | {
|
|
187
|
+
readonly className: string;
|
|
188
|
+
readonly parts: readonly [NoInfer<Parts>, ...NoInfer<Parts>[]];
|
|
189
|
+
}) & CompoundConditions<Variants>;
|
|
190
|
+
type InvalidPartNames<Styles> = Extract<PartNames<Styles>, ReservedPartName | StaticallyUnsafeSchemaName> | WhitespaceOnlyName<PartNames<Styles>>;
|
|
191
|
+
type InvalidVariantNames<Variants> = Extract<CanonicalKeys<NonNullable<Variants>>, ReservedVariantName | StaticallyUnsafeSchemaName> | WhitespaceOnlyName<CanonicalKeys<NonNullable<Variants>>>;
|
|
192
|
+
type InvalidChoiceNames<Choices> = Extract<CanonicalKeys<Choices>, StaticallyUnsafeSchemaName>;
|
|
193
|
+
type AllowedPartNames<Styles> = InvalidPartNames<Styles> extends never ? unknown : never;
|
|
194
|
+
type AllowedVariantNames<Variants> = InvalidVariantNames<Variants> extends never ? unknown : never;
|
|
195
|
+
type ValidateStyles<Styles> = PartNames<Styles> extends never ? never : Styles extends Readonly<Record<Extract<keyof Styles, string | number>, ClassValue>> ? unknown : never;
|
|
196
|
+
type PartTargetNames<Targets> = Targets extends unknown ? CanonicalKeys<Targets> : never;
|
|
197
|
+
type ValidatePartTargetValues<Targets> = Targets extends RecordInput ? { readonly [Name in keyof Targets]: Name extends symbol ? Targets[Name] : Targets[Name] extends ClassValue ? Targets[Name] : never; } : never;
|
|
198
|
+
type InvalidPartTargetValueNames<Targets> = Targets extends RecordInput ? { readonly [Name in Extract<keyof Targets, string | number>]-?: IsAny<Targets[Name]> extends true ? never : Targets[Name] extends ClassValue ? never : Name; }[Extract<keyof Targets, string | number>] : never;
|
|
199
|
+
type ValidatePartTargets<Targets, Parts extends string> = IsAny<Targets> extends true ? unknown : true extends InvalidRecordShape<Targets> ? never : [Targets] extends [RecordInput] ? (Exclude<PartTargetNames<Targets>, Parts> extends never ? (InvalidPartTargetValueNames<Targets> extends never ? ValidatePartTargetValues<Targets> : never) : never) : never;
|
|
200
|
+
type ValidateSingleChoices<Choices> = ValidateStableSchema<Choices> extends never ? never : InvalidChoiceNames<Choices> extends never ? CanonicalKeys<Choices> extends never ? never : Choices extends RecordInput ? { readonly [Name in keyof Choices]: Name extends symbol ? Choices[Name] : IsAny<Choices[Name]> extends true ? unknown : [Choices[Name]] extends [string] ? Choices[Name] : never; } : never : never;
|
|
201
|
+
type ValidateMultipartChoices<Choices, Parts extends string> = ValidateStableSchema<Choices> extends never ? never : InvalidChoiceNames<Choices> extends never ? CanonicalKeys<Choices> extends never ? never : Choices extends RecordInput ? { readonly [Name in keyof Choices]: ValidatePartTargets<Choices[Name], Parts>; } : never : never;
|
|
202
|
+
type ValidateSingleVariants<Variants> = [Variants] extends [VariantsInput] ? { readonly [Name in keyof Variants]: ValidateSingleChoices<Variants[Name]>; } : unknown;
|
|
203
|
+
type ValidateMultipartVariants<Variants, Parts extends string> = [Variants] extends [VariantsInput] ? { readonly [Name in keyof Variants]: ValidateMultipartChoices<Variants[Name], Parts>; } : unknown;
|
|
204
|
+
type ValidateCompoundCondition<Condition> = undefined extends Condition ? never : Condition extends readonly [] ? never : Condition;
|
|
205
|
+
type ValidateSingleCompoundOutput<Output> = IsAny<Output> extends true ? unknown : [Output] extends [string] ? Output : never;
|
|
206
|
+
type ValidateMultipartCompoundOutput<Output, Parts extends string> = PartTargetNames<Output> extends never ? never : ValidatePartTargets<Output, Parts>;
|
|
207
|
+
type ValidateCompoundParts<Targets, Parts extends string> = IsAny<Targets> extends true ? unknown : Targets extends readonly [unknown, ...unknown[]] ? (Exclude<Targets[number], Parts> extends never ? Targets : never) : never;
|
|
208
|
+
type ValidateSingleCompoundEntry<Entry, Variants extends VariantSchema> = true extends InvalidRecordShape<Entry> ? never : Entry extends RecordInput ? { readonly [Name in keyof Entry]: Name extends symbol ? Entry[Name] : Name extends "className" ? ValidateSingleCompoundOutput<Entry[Name]> : Name extends string | number ? (CanonicalKey<Name> extends keyof Variants ? ValidateCompoundCondition<Entry[Name]> : never) : never; } : never;
|
|
209
|
+
type ValidateMultipartCompoundEntry<Entry, Parts extends string, Variants extends VariantSchema> = true extends InvalidRecordShape<Entry> ? never : Entry extends RecordInput ? "parts" extends OptionalSchemaKeys<Entry> ? never : { readonly [Name in keyof Entry]: Name extends symbol ? Entry[Name] : Name extends "className" ? "parts" extends keyof Entry ? ValidateSingleCompoundOutput<Entry[Name]> : ValidateMultipartCompoundOutput<Entry[Name], Parts> : Name extends "parts" ? ValidateCompoundParts<Entry[Name], Parts> : Name extends string | number ? CanonicalKey<Name> extends keyof Variants ? ValidateCompoundCondition<Entry[Name]> : never : never; } : never;
|
|
210
|
+
type ValidateSingleCompounds<Compounds, Variants extends VariantSchema> = Compounds extends readonly unknown[] ? { readonly [Index in keyof Compounds]: ValidateSingleCompoundEntry<Compounds[Index], Variants>; } : unknown;
|
|
211
|
+
type ValidateMultipartCompounds<Compounds, Parts extends string, Variants extends VariantSchema> = Compounds extends readonly unknown[] ? { readonly [Index in keyof Compounds]: ValidateMultipartCompoundEntry<Compounds[Index], Parts, Variants>; } : unknown;
|
|
212
|
+
type SingleRecipeDefinition<Style extends string, Parent extends SingleBrandedRecipe | undefined, Variants extends VariantsInput | undefined, Compounds extends readonly SingleCompoundDefinition<EffectiveVariants<Parent, Variants>>[] | undefined> = {
|
|
213
|
+
readonly styles: Style;
|
|
214
|
+
readonly variants?: (Variants & ValidateStableSchema<Exclude<Variants, undefined>> & AllowedVariantNames<Variants> & ValidateSingleVariants<Variants>) | undefined;
|
|
215
|
+
readonly defaultVariants?: DefinitionVariantSelections<NoInfer<EffectiveVariants<Parent, Variants>>> | undefined;
|
|
216
|
+
readonly compoundVariants?: (Compounds & ValidateSingleCompounds<Compounds, EffectiveVariants<Parent, Variants>>) | undefined;
|
|
217
|
+
readonly extend?: (Parent & ValidateNonUnion<Parent>) | undefined;
|
|
218
|
+
};
|
|
219
|
+
type MultipartRecipeDefinition<Styles extends StylesInput, Parent extends MultipartBrandedRecipe | undefined, Variants extends VariantsInput | undefined, Compounds extends readonly MultipartCompoundDefinition<EffectiveParts<Parent, Styles>, EffectiveVariants<Parent, Variants>>[] | undefined> = {
|
|
220
|
+
readonly styles: Styles & ValidateStyles<Styles> & ValidateStableSchema<Styles> & AllowedPartNames<Styles>;
|
|
221
|
+
readonly variants?: (Variants & ValidateStableSchema<Exclude<Variants, undefined>> & AllowedVariantNames<Variants> & ValidateMultipartVariants<Variants, EffectiveParts<Parent, Styles>>) | undefined;
|
|
222
|
+
readonly defaultVariants?: DefinitionVariantSelections<NoInfer<EffectiveVariants<Parent, Variants>>> | undefined;
|
|
223
|
+
readonly compoundVariants?: (Compounds & ValidateMultipartCompounds<Compounds, EffectiveParts<Parent, Styles>, EffectiveVariants<Parent, Variants>>) | undefined;
|
|
224
|
+
readonly extend?: (Parent & ValidateNonUnion<Parent>) | undefined;
|
|
225
|
+
};
|
|
226
|
+
type RecipeInference<Styles, Parent, Variants, Compounds> = {
|
|
227
|
+
readonly styles: Styles;
|
|
228
|
+
readonly variants?: Variants | undefined;
|
|
229
|
+
readonly compoundVariants?: Compounds | undefined;
|
|
230
|
+
readonly extend?: Parent;
|
|
231
|
+
};
|
|
232
|
+
type ExtendedRecipeInference<Styles, Parent, Variants, Compounds> = Omit<RecipeInference<Styles, Parent, Variants, Compounds>, "extend"> & {
|
|
233
|
+
readonly extend: Parent;
|
|
234
|
+
};
|
|
235
|
+
type InheritedRecipeInference<Parent, Variants, Compounds> = Omit<ExtendedRecipeInference<never, Parent, Variants, Compounds>, "styles">;
|
|
236
|
+
type InheritedSingleRecipeDefinition<Parent extends SingleBrandedRecipe, Variants extends VariantsInput | undefined, Compounds extends readonly SingleCompoundDefinition<EffectiveVariants<Parent, Variants>>[] | undefined> = Omit<SingleRecipeDefinition<string, Parent, Variants, Compounds>, "styles">;
|
|
237
|
+
type InheritedMultipartRecipeDefinition<Parent extends MultipartBrandedRecipe, Variants extends VariantsInput | undefined, Compounds extends readonly MultipartCompoundDefinition<ParentStyles<Parent>, EffectiveVariants<Parent, Variants>>[] | undefined> = Omit<MultipartRecipeDefinition<{}, Parent, Variants, Compounds>, "styles">;
|
|
238
|
+
type RecipeDefinitionField = "compoundVariants" | "defaultVariants" | "extend" | "styles" | "variants";
|
|
239
|
+
type ValidateDefinitionInput<Definition> = ValidateRecordShape<Definition> & ValidateKnownKeys<Definition, RecipeDefinitionField>;
|
|
240
|
+
type ValidateInheritedDefinitionInput<Definition> = ValidateRecordShape<Definition> & ValidateKnownKeys<Definition, Exclude<RecipeDefinitionField, "styles">>;
|
|
241
|
+
type RecipeDefiner = {
|
|
242
|
+
<const Style extends string, const Variants extends VariantsInput | undefined = undefined, const Compounds extends readonly SingleCompoundDefinition<EffectiveVariants<undefined, Variants>>[] | undefined = undefined, const Definition = unknown>(definition: RecipeInference<Style, undefined, Variants, Compounds> & Definition & NoInfer<SingleRecipeDefinition<Style, undefined, Variants, Compounds>> & NoInfer<ValidateDefinitionInput<Definition>>): TeaSingleRecipe<EffectiveVariants<undefined, Variants>>;
|
|
243
|
+
<const Parent extends SingleBrandedRecipe, const Style extends string, const Variants extends VariantsInput | undefined = undefined, const Compounds extends readonly SingleCompoundDefinition<EffectiveVariants<Parent, Variants>>[] | undefined = undefined, const Definition = unknown>(definition: ExtendedRecipeInference<Style, Parent, Variants, Compounds> & Definition & NoInfer<SingleRecipeDefinition<Style, Parent, Variants, Compounds>> & NoInfer<ValidateDefinitionInput<Definition>>): TeaSingleRecipe<EffectiveVariants<Parent, Variants>>;
|
|
244
|
+
<const Parent extends SingleBrandedRecipe, const Variants extends VariantsInput | undefined = undefined, const Compounds extends readonly SingleCompoundDefinition<EffectiveVariants<Parent, Variants>>[] | undefined = undefined, const Definition = unknown>(definition: InheritedRecipeInference<Parent, Variants, Compounds> & Definition & NoInfer<InheritedSingleRecipeDefinition<Parent, Variants, Compounds>> & NoInfer<ValidateInheritedDefinitionInput<Definition>>): TeaSingleRecipe<EffectiveVariants<Parent, Variants>>;
|
|
245
|
+
<const Styles extends StylesInput, const Variants extends VariantsInput | undefined = undefined, const Compounds extends readonly MultipartCompoundDefinition<EffectiveParts<undefined, Styles>, EffectiveVariants<undefined, Variants>>[] | undefined = undefined, const Definition = unknown>(definition: RecipeInference<Styles, undefined, Variants, Compounds> & Definition & NoInfer<MultipartRecipeDefinition<Styles, undefined, Variants, Compounds>> & NoInfer<ValidateDefinitionInput<Definition>>): TeaMultipartRecipe<EffectiveParts<undefined, Styles>, EffectiveVariants<undefined, Variants>>;
|
|
246
|
+
<const Parent extends MultipartBrandedRecipe, const Variants extends VariantsInput | undefined = undefined, const Compounds extends readonly MultipartCompoundDefinition<ParentStyles<Parent>, EffectiveVariants<Parent, Variants>>[] | undefined = undefined, const Definition = unknown>(definition: InheritedRecipeInference<Parent, Variants, Compounds> & Definition & NoInfer<InheritedMultipartRecipeDefinition<Parent, Variants, Compounds>> & NoInfer<ValidateInheritedDefinitionInput<Definition>>): TeaMultipartRecipe<ParentStyles<Parent>, EffectiveVariants<Parent, Variants>>;
|
|
247
|
+
<const Parent extends MultipartBrandedRecipe, const Styles extends StylesInput, const Variants extends VariantsInput | undefined = undefined, const Compounds extends readonly MultipartCompoundDefinition<EffectiveParts<Parent, Styles>, EffectiveVariants<Parent, Variants>>[] | undefined = undefined, const Definition = unknown>(definition: ExtendedRecipeInference<Styles, Parent, Variants, Compounds> & Definition & NoInfer<MultipartRecipeDefinition<Styles, Parent, Variants, Compounds>> & NoInfer<ValidateDefinitionInput<Definition>>): TeaMultipartRecipe<EffectiveParts<Parent, Styles>, EffectiveVariants<Parent, Variants>>;
|
|
248
|
+
};
|
|
249
|
+
type VariantProps<Recipe> = Recipe extends RecipeCarrier & ((props?: infer Props) => unknown) ? VariantSelections<SchemaFromSelections<Props>> : never;
|
|
250
|
+
declare function createDefiner<const Options = unknown>(options: {
|
|
251
|
+
readonly merge: RecipeMerger;
|
|
252
|
+
} & Options & NoInfer<ValidateRecordShape<Options> & ValidateKnownKeys<Options, "merge">>): RecipeDefiner;
|
|
253
|
+
declare function createDefiner(options: RecipeDefinerOptions): RecipeDefiner;
|
|
254
|
+
//#endregion
|
|
255
|
+
export { type ClassDict, type ClassProp, type ClassValue, type ConflictAtoms, type ConflictMeta, MERGE_OPAQUE, type Merger, type MergerOptions, type MergerPlugin, MergerProtocolError, type MergerProtocolErrorCode, type MergerTokenOccurrence, type MergerTokenView, type OverlapMode, type RecipeDefiner, type ResolveVerdict, type VariantProps, createDefiner, createMerger };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function e(e,t,n){Object.defineProperty(e,t,{configurable:!0,enumerable:!0,value:n,writable:!0})}function t(t,n){let r=t.length;r in t?e(t,r,n):t[r]=n}function n(e){let n=``,r,i=-1,a=-1,o=-1,s=[];for(let c=0;c<e.length;c++){let l=e[c];if(r){l===`\\`?c++:l===r&&(r=void 0);continue}if(n.length>0&&l===`\\`){c++;continue}if(n.length>0&&(l===`"`||l===`'`)){r=l;continue}if(n.length>0&&l===`/`&&e[c+1]===`*`){let t=e.indexOf(`*/`,c+2);if(t<0)break;c=t+1;continue}l===`(`||l===`[`?n+=l===`(`?`)`:`]`:l===n.at(-1)?n=n.slice(0,-1):n.length===0&&(l===`@`?(a===-1&&(a=c),t(s,c)):a===-1&&(l===`:`&&i===-1?i=c:l===`!`&&(o=c)))}let c=a===-1?e.length:a,l=e.slice(0,c),u=!1;o===c-1&&(u=!0,l=l.slice(0,-1));let d=[];for(let n=0;n<s.length;n++){let r=s[n]+1,i=n+1<s.length?s[n+1]:e.length;t(d,e.slice(r,i))}return i!==-1&&i<c?{raw:e,body:l,property:e.slice(0,i),value:l.slice(i+1),keyword:!1,important:u,conditions:d}:{raw:e,body:l,keyword:!0,important:u,conditions:d}}function r(e,t){let n=e.length;n in e?Object.defineProperty(e,n,{configurable:!0,enumerable:!0,value:t,writable:!0}):e[n]=t}function i(e){let t=[],n=[],i=new Map,a=!1,o,s;for(let c=0;c<e.length;c++){let l=e[c];if(n.length===0){l===`\\`?(/\s/.test(e[c+1]??``)&&(o=void 0),c++):/\s/.test(l)?o=void 0:l===`"`||l===`'`?o=o===l?void 0:o??l:!o&&l===`[`&&r(n,c);continue}if((s||a)&&l===`[`&&/[:@\s]/.test(e[c-1])){r(n,c),i.set(c,s??a),a=!1,s=void 0;continue}if(a){l===`*`&&e[c+1]===`/`&&(a=!1,c++);continue}if(s){l===`\\`?c++:l===s&&(s=void 0);continue}if(l===`/`&&e[c+1]===`*`)a=!0,c++;else if(l===`"`||l===`'`)s=l;else if(l===`\\`)c++;else if(l===`[`)r(n,c);else if(l===`]`){let o=n.pop(),l=i.get(o);(/[:@]/.test(e[o-1])||e[c+1]===`:`)&&r(t,{end:c+1,start:o}),l===!0?a=!0:l&&(s=l)}}let c=[];for(let e of t.sort((e,t)=>e.start-t.start||t.end-e.end))(!c.length||e.start>=c.at(-1).end)&&r(c,e);return c}function a(e,t,n){let r=e[t];if(n.blockComment)return r===`*`&&e[t+1]===`/`?(n.blockComment=!1,t+1):t;if(n.quote)return r===`\\`?t+1:(r===n.quote&&(n.quote=void 0),t);if(n.closers.length>0&&r===`/`&&e[t+1]===`*`)return n.blockComment=!0,t+1;if(n.closers.length>0&&(r===`"`||r===`'`))return n.quote=r,t;if(n.closers.length>0&&r===`\\`)return t+1;if(r===`(`||r===`[`)return u(n.closers,r===`(`?`)`:`]`),t;if(r===n.closers.at(-1))return n.closers.pop(),t}function o(e,t,n=e.length){let r={closers:[]};for(let i=t+1;i<n;i++){let t=e[i],n=a(e,i,r);if(n!==void 0){i=n;continue}if(r.closers.length===0){if(t===`}`)return{index:i,kind:`close`};if(t===`{`)return{index:i,kind:`open`}}}return{index:n,kind:`limit`}}const s=/[\s'"`;{},\])]/;function c(e,t,n=e.length){if(e[t]!==`@`)return{conds:``,end:t};let r={closers:[]},i=t;for(;i<n;i++){let t=e[i],n=a(e,i,r);if(n!==void 0){i=n;continue}if(t===`/`&&(e[i+1]===`/`||e[i+1]===`*`)&&r.closers.length===0||s.test(t)&&r.closers.length===0)break}return{conds:e.slice(t,i),end:i}}function l(e){let t=[],n={closers:[]},r=0;for(let i=0;i<e.length;i++){let o=e[i],s=a(e,i,n);if(s!==void 0){i=s;continue}o===`;`&&n.closers.length===0&&(u(t,e.slice(r,i)),r=i+1)}return u(t,e.slice(r)),t.map(e=>e.trim()).filter(Boolean)}function u(e,t){Object.defineProperty(e,e.length,{configurable:!0,enumerable:!0,value:t,writable:!0})}const d=/^(?:--?[\w-]+|[A-Z_$][\w$-]*|@teacss-skip-bracket-[\da-z]{6})$/i;function f(e,t){let n=t;for(;n>0&&/[\w-]/.test(e[n-1]);)n--;if(n===t||e[n-1]!==`:`)return!1;let r=n-1,i=r;for(;i>0&&/[\w$@-]/.test(e[i-1]);)i--;if(!d.test(e.slice(i,r)))return!1;let a=i-1;for(;a>=0&&/\s/.test(e[a]);)a--;return a<0||!`{,?`.includes(e[a])}function p(e){let t=[],n=[],r=[],i=!1,a;for(let o=0;o<e.length;o++){let s=e[o],c=e[o+1];if(n.length===0){s===`(`&&f(e,o)&&u(n,{attached:!0,start:o});continue}if(i)s===`*`&&c===`/`&&(i=!1,o++);else if(a)s===`\\`?o++:s===a&&(a=void 0);else if(s===`\\`)o++;else if(s===`/`&&c===`*`)i=!0,o++;else if(s===`'`||s===`"`||s==="`")a=s;else if(r.length>0)s===`[`||s===`(`?u(r,s===`[`?`]`:`)`):s===r.at(-1)&&r.pop();else if(s===`[`)u(r,`]`);else if(s===`(`)u(n,{attached:f(e,o),start:o});else if(s===`)`){let e=n.pop();e.attached&&u(t,{end:o+1,start:e.start})}}let o=[];for(let e of t.sort((e,t)=>e.start-t.start||t.end-e.end))(o.length===0||e.start>=o.at(-1).end)&&u(o,e);return o}function m(e){if(!e.includes(`{`))return e;let t=``,n=0,r=-1,s=0,u=0,d=e.includes(`[`)?i(e):[],f=e.includes(`(`)?p(e):[],m={closers:[]};for(;n<e.length;){for(;s<d.length&&d[s].end<=n;)s++;for(;u<f.length&&f[u].end<=n;)u++;let i=s<d.length?d[s]:void 0,p=u<f.length?f[u]:void 0,h=i?.start===n?i:p?.start===n?p:void 0;if(h&&m.blockComment!==!0&&m.quote===void 0){t+=e.slice(n,h.end),n=h.end;continue}m.closers.length>0&&/\s/.test(e[n])&&(m.blockComment=!1,m.closers.length=0,m.quote=void 0);let g=a(e,n,m);if(g!==void 0){t+=e.slice(n,g+1),n=g+1;continue}let _=e[n];if(m.closers.length>0||_!==`{`){t+=_,n++;continue}let v=o(e,n);if(v.kind!==`close`){t+=e.slice(n,v.index),n=v.index;continue}let y=v.index,b=e.slice(n+1,y),{conds:x,end:S}=c(e,y+1),C=l(b);if(C.length===0){t+=_,n++;continue}r===n&&t.length>0&&!/\s/.test(t.at(-1))&&(t+=` `),t+=C.map(e=>`${e}${x}`).join(` `),r=S,n=S}return t}function h(e){let t=e.split(/\s+/);return t[0]===``&&t.shift(),t.at(-1)===``&&t.pop(),t}function g(e){if(!e.includes(`[`))return h(e);let t=i(e);if(t.length===0)return h(e);let n=[],a=0,o=-1;for(let i=0;i<e.length;i++){let s=t[a];if(s&&i===s.start){o<0&&(o=i),i=s.end-1,a++;continue}/\s/.test(e[i])?(o>=0&&r(n,e.slice(o,i)),o=-1):o<0&&(o=i)}return o>=0&&r(n,e.slice(o)),n}const _=!1;var v=class extends TypeError{name=`MergerProtocolError`;code;plugin;hook;constructor(e,t,n,r){super(`[TeaCSS merge:${e}] ${t}`),this.code=e,n!==void 0&&(this.plugin=n),r!==void 0&&(this.hook=r)}};function y(){return Object.create(null)}const b=`must have an integer length from 0 through 4294967294`,x=Symbol(`missing-own-value`);function S(e,t){return`value`in t?t.value:t.get===void 0?void 0:Reflect.apply(t.get,e,[])}function C(e,t){let n=Reflect.getOwnPropertyDescriptor(e,t);return n===void 0?x:S(e,n)}function w(e,t){let n=C(e,t);return n===x?void 0:n}function ee(e,t,n){Object.defineProperty(e,t,{configurable:!0,enumerable:!0,value:n,writable:!0})}function T(e,t){let n=e.length;n in e?ee(e,n,t):e[n]=t}function E(e){let t=C(e,`length`);return typeof t==`number`&&Number.isInteger(t)&&t>=0&&t<4294967295?t:null}function te(e){let t=``,n=E(e);if(n===null)throw new v(`INVALID_ARRAY_LENGTH`,`class-value array ${b}`);for(let r=0;r<n;r++){let n=C(e,r);if(n===x)continue;let i=ne(n);i&&(t+=(t&&` `)+i)}return t}function ne(e){if(!e)return``;if(typeof e==`string`)return e;if(typeof e==`number`||typeof e==`bigint`)return String(e);if(Array.isArray(e))return te(e);if(typeof e==`object`){let t=e,n=``;for(let e of Reflect.ownKeys(t)){if(typeof e!=`string`)continue;let r=Reflect.getOwnPropertyDescriptor(t,e);r===void 0||!r.enumerable||S(t,r)&&(n+=(n&&` `)+e)}return n}return``}function re(e,t){let n=e;for(let e of t){let t=n.children??=new Map,r=t.get(e);r===void 0&&(r=y(),t.set(e,r)),n=r}return n}function ie(e,t,n){let r=re(e,t);return n?r.keywords??=new Map:r.declarations??=new Map}function ae(e){if(e.length===0)return``;if(e.length===1){let t=C(e,0);return t===x?``:t??``}let t=y(),r=new Uint8Array(e.length),i=new Uint8Array(e.length);for(let a=0;a<e.length;a++){let o=n(e[a]),s=ie(t,o.conditions,o.keyword),c=o.property??o.body,l=s.get(c);r[a]=+!!o.important,l===void 0?s.set(c,a):r[l]!==0&&r[a]===0?i[a]=1:(i[l]=1,s.set(c,a))}let a=[];for(let t=0;t<e.length;t++)i[t]===0&&T(a,e[t]);return a.join(` `)}function oe(e,t){if(typeof e==`string`)return e.length===0?null:[e];if(!Array.isArray(e))return null;let n=E(e);if(n===null||n===0)return null;let r=[],i=null;for(let a=0;a<n;a++){let n=C(e,a);if(n===x||typeof n!=`string`||n.length===0)return null;(i===null?r.includes(n):i.has(n))||(T(r,n),i===null?r.length===(t?64:4)&&(i=new Set(r)):i.add(n))}return t&&r.length>1&&r.sort(),r}function se(e,t){if(e.length!==t.length)return!1;for(let n=0;n<e.length;n++)if(e[n]!==t[n])return!1;return!0}function D(e,t,n,r,i){for(let a of Reflect.ownKeys(t)){if(typeof a!=`string`)continue;let o=Reflect.getOwnPropertyDescriptor(t,a);if(o===void 0||!o.enumerable)continue;let s=oe(S(t,o),!0);if(s===null)throw new v(`INVALID_STATIC_CONFLICT`,`"${r}" ${n} "${a}" must contain at least one non-empty atom`,i);let c=e.get(a);if(c===void 0){e.set(a,{atoms:s,atomSet:s.length>4?new Set(s):null,source:r});continue}if(!se(c.atoms,s))throw new v(`STATIC_CONFLICT_COLLISION`,`static ${n} "${a}" has conflicting atom sets from "${c.source}" and "${r}"`,i)}}function O(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function k(e){if(!O(e))return!1;let t=Object.getPrototypeOf(e);return t===null||t===Object.prototype}function ce(e,t,n){if(!O(e))throw new v(`INVALID_CONFLICT_META`,`"${t}" conflicts must be an object`,n);let r=w(e,`keywords`);if(!k(r))throw new v(`INVALID_CONFLICT_META`,`"${t}" keywords must be a record`,n);let i=w(e,`overlaps`);if(!k(i))throw new v(`INVALID_CONFLICT_META`,`"${t}" overlaps must be a record`,n);return{keywords:r,overlaps:i}}function A(e,t,n,r){if(n!==void 0){if(typeof n!=`function`)throw new v(`INVALID_PLUGIN_HOOK`,`plugin "${e}" ${t} must be a function`,e,r);return n}}function le(e){let t=[],n=[],r=[],i=[],a=[],o=new Set,s=E(e);if(s===null)throw new v(`INVALID_OPTIONS`,`options.plugins must be an array with an integer length from 0 through 4294967294`);for(let c=0;c<s;c++){let s=C(e,c),l=s===x?void 0:s;if(!O(l))throw new v(`INVALID_PLUGIN_NAME`,`plugin at index ${c} must have a non-empty name`);let u=w(l,`name`);if(typeof u!=`string`||u.length===0)throw new v(`INVALID_PLUGIN_NAME`,`plugin at index ${c} must have a non-empty name`);if(o.has(u))throw new v(`DUPLICATE_PLUGIN_NAME`,`duplicate plugin name "${u}"`,u);o.add(u);let d=w(l,`conflicts`),f=A(u,`tokens`,w(l,`tokens`),`tokens`),p=A(u,`group`,w(l,`group`),`group`),m=A(u,`finalize`,w(l,`finalize`),`finalize`),h=A(u,`resolveFamily`,w(l,`resolveFamily`),`resolveFamily`),g=A(u,`resolve`,w(l,`resolve`),`resolve`);if(h!==void 0&&g===void 0)throw new v(`INVALID_PLUGIN_HOOK`,`plugin "${u}" resolveFamily requires resolve`,u,`resolveFamily`);T(t,{name:u,conflicts:d===void 0?void 0:ce(d,u,u)}),f!==void 0&&T(n,{name:u,hook:f}),p!==void 0&&T(r,{name:u,hook:p}),m!==void 0&&T(i,{name:u,hook:m}),g!==void 0&&T(a,{name:u,hook:g,family:h})}return{metadata:t,tokens:n,groups:r,finalizers:i,resolvers:a}}function ue(e,t){let n=new Map,r=new Map;e!==void 0&&(D(n,e.keywords,`keyword`,`<options.conflicts>`),D(r,e.overlaps,`declaration`,`<options.conflicts>`));for(let e of t)e.conflicts!==void 0&&(D(n,e.conflicts.keywords,`keyword`,e.name,e.name),D(r,e.conflicts.overlaps,`declaration`,e.name,e.name));return{keywords:n,overlaps:r}}function de(e){let t=n(e);return{raw:e,prefix:t.property??t.body,body:t.body,value:t.value,keyword:t.keyword,conditions:t.conditions,important:t.important}}function fe(){let e=new Map;return t=>{let n=e.get(t);if(n!==void 0)return n;let r=de(t);return e.set(t,r),r}}function pe(e,t,n){if(t.length===0)return e;let r=e,i={viewToken:n};for(let e of t){let t=e.hook,n=t(r,i),a=`plugin "${e.name}" tokens() must return an array of individual non-empty class tokens`;if(!Array.isArray(n))throw new v(`INVALID_TOKEN_TRANSFORM_RESULT`,a,e.name,`tokens`);let o=[],s=E(n);if(s===null)throw new v(`INVALID_TOKEN_TRANSFORM_RESULT`,a,e.name,`tokens`);for(let t=0;t<s;t++){let r=C(n,t);if(r===x||typeof r!=`string`||r.length===0)throw new v(`INVALID_TOKEN_TRANSFORM_RESULT`,a,e.name,`tokens`);let i=g(r);if(i.length!==1||i[0]!==r)throw new v(`INVALID_TOKEN_TRANSFORM_RESULT`,a,e.name,`tokens`);T(o,r)}r=o}return r}function j(e,t){let n=null;for(let r=0;r<t.length;r++){let i=t[r];if(i.family===void 0)continue;let a=i.family,o=a(e);if(o!==null&&(typeof o!=`string`||o.length===0))throw new v(`INVALID_RESOLVE_FAMILY_RESULT`,`plugin "${i.name}" resolveFamily() must return null or a non-empty string`,i.name,`resolveFamily`);o!==null&&((n??=Array.from({length:t.length},()=>null))[r]=o)}return n}function me(e,t,n,r,i,a){let o=a(e),s;for(let e of n){let n=e.hook,i=n(o);if(i===null)continue;if(i===!1)return s={id:t,view:o,atoms:[],atomSet:null,dynamic:!0,opaque:!0},{...s,resolverFamilies:null};let a=oe(i,!1);if(a===null)throw new v(`INVALID_GROUP_RESULT`,`plugin "${e.name}" group() must return null, MERGE_OPAQUE, or at least one non-empty atom`,e.name,`group`);return s={id:t,view:o,atoms:a,atomSet:a.length>4?new Set(a):null,dynamic:!0,opaque:!1},{...s,resolverFamilies:j(o,r)}}let c=o.keyword?i.keywords.get(o.prefix):i.overlaps.get(o.prefix);return c===void 0?(s={id:t,view:o,atoms:[o.keyword?`@teacss/classes:keyword:${o.prefix}`:`@teacss/classes:declaration:${o.prefix}`],atomSet:null,opaque:!1},{...s,resolverFamilies:j(o,r)}):(s={id:t,view:o,atoms:c.atoms,atomSet:c.atomSet,opaque:!1},{...s,resolverFamilies:j(o,r)})}function he(e,t){let n=new Map;for(let r of e){if(!r.opaque)continue;let e=n.get(r.view.raw);e!==void 0&&(t[e]=1),n.set(r.view.raw,r.id)}}function M(e,t){return new v(`INVALID_FINALIZER_RESULT`,`plugin "${e}" finalize() returned invalid occurrence id ${typeof t==`bigint`?`${t}n`:typeof t==`number`||typeof t==`boolean`||t==null?String(t):typeof t}`,e,`finalize`)}function ge(e,t){let n=[];for(let r of e)!r.opaque&&t[r.id]===0&&T(n,r);return n}function _e(e,t,n,r){let i=!1,a=r;for(let r of t){let t=r.hook,o=t(a?ge(e,n):e.slice());if(o===null)continue;if(!Array.isArray(o))throw M(r.name,o);let s=E(o);if(s===null)throw new v(`INVALID_FINALIZER_RESULT`,`plugin "${r.name}" finalize() result ${b}`,r.name,`finalize`);if(s===0)continue;let c=new Set;for(let t=0;t<s;t++){let i=C(o,t);if(i===x)throw M(r.name,void 0);let a=i;if(!Number.isInteger(a))throw M(r.name,a);let s=a,l=e[s];if(l===void 0||l.opaque||n[s]!==0||c.has(s))throw M(r.name,a);c.add(s)}for(let e of c)n[e]=1;c.size!==0&&(i=!0,a=!0)}return i}function ve(e,t){return e.atomSet?.has(t)??e.atoms.includes(t)}function ye(e,t){return e.dynamic!==!0&&t.dynamic!==!0&&e.view.keyword===t.view.keyword&&e.view.prefix===t.view.prefix}function be(e,t){if(ye(e,t))return!0;if(e.atoms.length<t.atoms.length)return!1;for(let n of t.atoms)if(!ve(e,n))return!1;return!0}function xe(e,t){if(e.atomSet!==null){for(let n of t.atoms)if(e.atomSet.has(n))return!0;return!1}if(t.atomSet!==null){for(let n of e.atoms)if(t.atomSet.has(n))return!0;return!1}for(let n of t.atoms)if(e.atoms.includes(n))return!0;return!1}function Se(e,t){let n=re(e,t);return n.winners??=new Map}function Ce(e,t,n){let r=y();for(let i of e){if(i.opaque||t[i.id]!==0)continue;let a=Se(r,i.view.conditions),o=n?`${i.view.keyword?`keyword`:`declaration`}:${i.view.prefix}`:i.atoms[0],s=a.get(o);if(s===void 0){a.set(o,i.id);continue}e[s].view.important&&!i.view.important?t[i.id]=1:(t[s]=1,a.set(o,i.id))}}function we(e,t,n,r,i){return e.view.important===t.view.important?n||i===`symmetric`?`earlier`:`none`:t.view.important?n?`earlier`:`none`:r?`later`:`none`}function Te(e,t,n,r){let i=be(t,e),a=be(e,t),o=we(e,t,i,a,n);for(let n=0;n<r.length;n++){let s=r[n];if(s.family!==void 0){let r=e.resolverFamilies?.[n]??null,i=t.resolverFamilies?.[n]??null;if(r===null||r!==i)continue}let c=s.hook,l=c(e.view,t.view,{covers:i,earlierCoversLater:a,defaultDrop:o});if(l!==null){if(l===`earlier`||l===`later`||l===`none`)return l;throw new v(`INVALID_RESOLVE_RESULT`,`plugin "${s.name}" resolve() must return null, "earlier", "later", or "none"`,s.name,`resolve`)}}return o}function N(e,t,n,r,i){let a=Te(e,t,n,r);a===`earlier`?i[e.id]=1:a===`later`&&(i[t.id]=1)}function Ee(e,t,n,r,i){let a=t[e];for(let o=e+1;o<t.length;o++){let e=t[o];se(a.view.conditions,e.view.conditions)&&(!ye(a,e)&&!xe(a,e)||N(a,e,n,r,i))}}function De(e,t){let n=re(e,t);return n.postings??=new Map}function Oe(e){let t=y(),n=[],r=[],i=e.length*(e.length-1)/2,a=0;for(let o=0;o<e.length;o++){let s=e[o],c=De(t,s.view.conditions),l=[];T(n,c),T(r,l);for(let e of s.atoms){let t=c.get(e);if(t===void 0&&(t=[],c.set(e,t)),a+=t.length,a>i)return null;T(l,t.length),T(t,o)}}return{postingMaps:n,positions:r,postingPairVisits:a}}function ke(e,t,n,r){for(let i=0;i<e.length;i++)Ee(i,e,t,n,r)}function Ae(e,t,n,r,i,a){if(a!==null){Ce(e,r,a===`static-prefix`);return}let o=e;if(i){let t=[];for(let n of e)!n.opaque&&r[n.id]===0&&T(t,n);o=t}if(o.length<16){ke(o,t,n,r);return}let s=Oe(o);if(s===null){ke(o,t,n,r);return}if(s.postingPairVisits===0)return;let c=new Uint32Array(o.length),l=[];for(let e=0;e<o.length;e++){let i=o[e],a=s.postingMaps[e],u=s.positions[e];if(i.atoms.length===1){let e=a.get(i.atoms[0]);for(let a=u[0]+1;a<e.length;a++)N(i,o[e[a]],t,n,r);continue}let d=0;for(let e=0;e<i.atoms.length;e++){let t=a.get(i.atoms[e]);d+=t.length-u[e]-1}if(d>=o.length-e-1){Ee(e,o,t,n,r);continue}l.length=0;let f=!0,p=e+1;for(let e=0;e<i.atoms.length;e++){let t=a.get(i.atoms[e]);for(let n=u[e]+1;n<t.length;n++){let e=t[n];c[e]!==p&&(c[e]=p,l.length!==0&&e<l[l.length-1]&&(f=!1),T(l,e))}}f||l.sort((e,t)=>e-t);for(let e of l)N(i,o[e],t,n,r)}}function je(e,t,n,r,i){let a=pe(e,r.tokens,i);if(a.length<2&&r.groups.length===0&&r.finalizers.length===0&&r.resolvers.length===0){if(a.length===0)return``;let e=C(a,0);return e===x?``:e??``}let o=[],s=!1,c=a.length>=16&&r.resolvers.every(e=>e.family!==void 0),l=c,u=c,d,f,p=0;for(let e=0;e<a.length;e++){let n=me(a[e],e,r.groups,r.resolvers,t,i);if(n.opaque)s=!0;else if(p++,n.atoms.length!==1&&(l=!1),n.dynamic===!0?u=!1:d===void 0?(d=n.view.prefix,f=n.view.keyword):(n.view.prefix!==d||n.view.keyword!==f)&&(u=!1),n.resolverFamilies!==null){for(let e of n.resolverFamilies)if(e!==null){l=!1,u=!1;break}}T(o,n)}let m=new Uint8Array(o.length);s&&he(o,m);let h=_e(o,r.finalizers,m,s),g=p<16?null:l?`singleton`:u?`static-prefix`:null;Ae(o,n,r.resolvers,m,s||h,g);let _=[];for(let e of o)m[e.id]===0&&T(_,e.view.raw);return _.join(` `)}function Me(e,t,n){let r=C(e,n);if(r===x)return``;if(typeof r==`string`)return r;if(Array.isArray(t)){let e=C(t,n);if(typeof e==`string`)return e}return``}function Ne(e){return typeof e==`number`||typeof e==`bigint`?String(e):ne(e)}function Pe(e,t,n){let r=``,i=E(e);if(i===null)throw new v(`INVALID_ARRAY_LENGTH`,`tagged-template strings ${b}`);for(let a=0;a<i;a++)if(r+=Me(e,t,a),a+1<i&&a+1<n.length){let e=Ne(n[a+1]);r+=e}return r}function Fe(e={}){if(!k(e))throw new v(`INVALID_OPTIONS`,`options must be an object`);let t=w(e,`conflicts`),n=w(e,`overlap`),r=w(e,`plugins`),i=w(e,`cache`);if(n!==void 0&&n!==`precise`&&n!==`symmetric`)throw new v(`INVALID_OPTIONS`,`options.overlap must be "precise" or "symmetric"`);if(r!==void 0&&!Array.isArray(r))throw new v(`INVALID_OPTIONS`,`options.plugins must be an array`);let a=le(r===void 0?[]:r),o=ue(t===void 0?void 0:ce(t,`<options.conflicts>`),a.metadata),s=a.tokens.length!==0||a.groups.length!==0||a.finalizers.length!==0||a.resolvers.length!==0,c=!s&&o.keywords.size===0&&o.overlaps.size===0,l=n??`precise`,u=1500;if(i===!1)u=0;else if(i!==void 0){if(!k(i))throw new v(`INVALID_CACHE_OPTIONS`,`options.cache must be false or an object`);let e=w(i,`max`);if(e!==void 0){if(typeof e!=`number`||!Number.isFinite(e)||!Number.isInteger(e)||e<0)throw new v(`INVALID_CACHE_OPTIONS`,`options.cache.max must be a finite non-negative integer`);u=e}}let d=u>0?new Map:null;function f(e){if(d!==null){let t=d.get(e);if(t!==void 0)return d.delete(e),d.set(e,t),t}let t=g(m(e).trim()),n=c?ae(t):je(t,o,l,a,s?fe():de);return d!==null&&(d.set(e,n),d.size>u&&d.delete(d.keys().next().value)),n}function p(...e){let t=e[0],n=Array.isArray(t)?C(t,`raw`):x;return f(Array.isArray(n)?Pe(t,n,e):te(e))}return p}const P=Object.prototype.propertyIsEnumerable,F=`definition.styles`,I=`definition.variants`,L=`definition.defaultVariants`,R=`definition.compoundVariants`,z=`createDefiner options`,B=`${z}.merge`,V=`recipe props`,H=`className`,Ie=`parts`,Le=`null is not allowed`,Re=`required own enumerable field`,ze=new Set([`styles`,`variants`,`defaultVariants`,`compoundVariants`,`extend`]),Be=new Set([`class`,`className`,`then`,`toJSON`,`toString`,`valueOf`]),Ve=new Set([`class`,`className`,`parts`]);function U(e){return e.length>16?new Set(e):void 0}function W(e,t,n){return t?.has(n)??e.includes(n)}function G(e,t){return TypeError(`[TeaCSS recipe] ${e}: ${t}`)}function K(e,t){if(typeof e!=`object`||!e||Array.isArray(e))throw G(t,`expected a plain record`);let n=Object.getPrototypeOf(e);if(n!==Object.prototype&&n!==null)throw G(t,`expected Object.prototype or null prototype`);return Object.keys(e)}function He(e,t){if(typeof e!=`object`||!e||Array.isArray(e))throw G(t,`expected a non-null, non-array object`);return Object.keys(e)}function q(e,t,n){let r=Reflect.getOwnPropertyDescriptor(e,t);if(r===void 0||!r.enumerable)throw G(n,`expected an own enumerable field`);return`value`in r?r.value:r.get===void 0?void 0:Reflect.apply(r.get,e,[])}function Ue(e,t){let n=Reflect.getOwnPropertyDescriptor(e,`length`),r=n!==void 0&&`value`in n?n.value:void 0;if(typeof r!=`number`||!Number.isInteger(r)||r<0||r>=4294967295)throw G(t,`expected an array with a valid own length`);return r}function We(e,t,n){if(!Array.isArray(e))throw G(t,`expected an array`);let r=Object.keys(e),i=Ue(e,t);if(!n&&i===0)throw G(t,`expected a non-empty array`);if(r.length!==i)throw G(t,`expected a dense own-indexed array`);for(let e of r){let n=Number(e);if(!Number.isInteger(n)||n<0||n>=i||String(n)!==e)throw G(t,`expected a dense own-indexed array`)}let a=Z(i);for(let n=0;n<i;n++)a[n]=q(e,n,`${t}[${n}]`);return a}function Ge(e,t){if(e.trim().length===0)throw G(t,`name must contain a non-whitespace character`)}function J(e){let t=te([e]);return t.length===0?void 0:t}function Y(e,t,n){if(n===void 0)return;let r=P.call(e,t)?e[t]:void 0;e[t]=r===void 0?[n]:[...r,n]}function Ke(e,t,n){Object.defineProperty(e,t,{configurable:!0,enumerable:!0,value:n,writable:!0})}function X(e,t){let n=e.length;n in e?Ke(e,n,t):e[n]=t}function Z(e){return Array.from({length:e},()=>void 0)}function qe(){return[void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0]}const Je=qe().length;function Ye(e,t,n){t<Je||!(t in e)?e[t]=n:Ke(e,t,n)}function Q(e,t=e.length){let n=Z(t),r=Math.min(e.length,t);for(let t=0;t<r;t++){if(!P.call(e,t))continue;let r=e[t];r!==void 0&&(n[t]=[...r])}return n}function Xe(e,t){return e.map(e=>{let n=Object.create(null);for(let r of Object.keys(e.choices))n[r]={fragmentsByPart:Q(e.choices[r].fragmentsByPart,t)};return{name:e.name,choices:n,booleanCapable:e.booleanCapable}})}function $(e,t,n){if(e===null)return null;if(typeof e==`string`){if(!P.call(t.choices,e))throw G(n,`unknown choice ${JSON.stringify(e)}`);return e}if(typeof e==`number`){if(!Number.isFinite(e))throw G(n,`expected a finite numeric choice`);let r=String(e);if(!P.call(t.choices,r))throw G(n,`unknown choice ${JSON.stringify(r)}`);return r}if(typeof e==`boolean`){if(!t.booleanCapable)throw G(n,`boolean selection requires a true or false choice`);return String(e)}throw G(n,`expected null, a declared string or finite numeric choice, or a supported boolean state`)}function Ze(e,t,n){if(n&&(e=t.partNames.length===0?``:{}),typeof e==`string`){if(t!==void 0&&t.partNames.length>0)throw G(F,`must be a record when extending a multi-element recipe`);let n=t===void 0?Z(1):Q(t.baseFragmentsByPart,1);return Y(n,0,J(e)),{names:[],indexes:Object.create(null),baseFragments:n}}let r=K(e,F);if(t!==void 0&&t.partNames.length===0)throw G(F,`must be a string when extending a single-element recipe`);if(!n&&r.length===0)throw G(F,`expected at least one named style`);for(let e of r){let t=`${F}.${e}`;if(Ge(e,t),Be.has(e))throw G(t,`reserved style name`)}let i=t===void 0?[]:[...t.partNames],a=Object.create(null);for(let e=0;e<i.length;e++)a[i[e]]=e;let o=t===void 0?[]:Q(t.baseFragmentsByPart),s=e;for(let e of r){let t=a[e];t===void 0&&(t=i.length,X(i,e),a[e]=t,X(o,void 0)),Y(o,t,J(q(s,e,`${F}.${e}`)))}return{names:i,indexes:a,baseFragments:o}}function Qe(e,t,n,r,i,a){if(n){if(typeof t!=`string`)throw G(i,`expected a primitive string`);Y(e,0,J(t));return}let o=K(t,i);if(a&&o.length===0)throw G(i,`expected at least one style target`);let s=t;for(let t of o){let n=r[t];if(n===void 0)throw G(`${i}.${t}`,`unknown style target`);Y(e,n,J(q(s,t,`${i}.${t}`)))}}function $e(e,t,n,r,i){let a=t===void 0?[]:Xe(t.variants,i),o=Object.create(null);for(let e=0;e<a.length;e++)o[a[e].name]=e;if(e===void 0)return{variants:a,indexes:o};if(e===null)throw G(I,Le);let s=K(e,I),c=e;for(let e of s){let t=`${I}.${e}`;if(Ge(e,t),Ve.has(e))throw G(t,`reserved variant name`);let s=q(c,e,t),l=K(s,t);if(l.length===0)throw G(t,`expected at least one choice`);let u=s,d=o[e],f;d===void 0?(d=a.length,o[e]=d,f=Object.create(null),X(a,{name:e,choices:f,booleanCapable:!1})):f=a[d].choices;for(let e of l){let a=`${t}.${e}`,o=q(u,e,a),s=f[e],c=s===void 0?Z(i):Q(s.fragmentsByPart,i);Qe(c,o,n,r,a,!1),f[e]={fragmentsByPart:c}}a[d]={name:e,choices:f,booleanCapable:P.call(f,`true`)||P.call(f,`false`)}}return{variants:a,indexes:o}}function et(e,t,n,r){let i=Z(n.length);if(t!==void 0){let e=Math.min(t.defaultStates.length,n.length);for(let n=0;n<e;n++)P.call(t.defaultStates,n)&&(i[n]=t.defaultStates[n])}if(e===void 0)return i;if(e===null)throw G(L,Le);let a=K(e,L),o=U(a);for(let e of a)if(r[e]===void 0)throw G(`${L}.${e}`,`unknown variant`);let s=e;for(let e=0;e<n.length;e++){let t=n[e];if(!W(a,o,t.name))continue;let r=`${L}.${t.name}`,c=q(s,t.name,r);c!==void 0&&(i[e]=$(c,t,r))}return i}function tt(e,t,n){if(!Array.isArray(e)){if(e===void 0)throw G(n,`undefined is not a condition`);return[$(e,t,n)]}let r=We(e,n,!1),i=[];for(let e=0;e<r.length;e++){let a=r[e];if(a===void 0)throw G(`${n}[${e}]`,`undefined is not a condition`);X(i,$(a,t,`${n}[${e}]`))}return i}function nt(e,t,n,r,i,a,o){let s=t===void 0?[]:t.compounds.map(e=>({conditions:e.conditions,fragmentsByPart:Q(e.fragmentsByPart,i)}));if(e===void 0)return s;if(e===null)throw G(R,Le);let c=We(e,R,!0);for(let e=0;e<c.length;e++){let t=c[e],l=`${R}[${e}]`,u=K(t,l),d=U(u),f=W(u,d,Ie);if(!W(u,d,H))throw G(`${l}.className`,n||f?`required own enumerable string`:`required own enumerable style map`);for(let e of u)if(e!==H&&e!==Ie&&o[e]===void 0)throw G(`${l}.${e}`,`unknown variant condition`);let p=t,m=[];for(let e=0;e<a.length;e++){let t=a[e];if(!W(u,d,t.name))continue;let n=`${l}.${t.name}`;X(m,{variantIndex:e,states:tt(q(p,t.name,n),t,n)})}let h=`${l}.className`,g=q(p,H,h),_=Z(i);if(f){let e=`${l}.parts`;if(n)throw G(e,`only valid for multi-element recipes`);if(typeof g!=`string`)throw G(h,`expected a primitive string when parts is present`);let t=We(q(p,Ie,e),e,!1),i=J(g);for(let n=0;n<t.length;n++){let a=t[n],o=`${e}[${n}]`;if(typeof a!=`string`)throw G(o,`expected a declared style name`);let s=r[a];if(s===void 0)throw G(o,`unknown style target`);if(t.indexOf(a)!==n)throw G(o,`duplicate style target ${JSON.stringify(a)}`);Y(_,s,i)}}else Qe(_,g,n,r,h,!0);X(s,{conditions:m,fragmentsByPart:_})}return s}function rt(e,t){let n=K(e,`definition`);for(let e of n)if(!ze.has(e))throw G(`definition.${e}`,`unknown field`);let r=e,i;if(n.includes(`extend`)){let e=q(r,`extend`,`definition.extend`);if(e!==void 0&&(typeof e!=`function`||(i=t.get(e))===void 0))throw G(`definition.extend`,`expected a recipe from this exact definer`)}let a=n.includes(`styles`);if(!a&&i===void 0)throw G(F,Re);let o=Ze(a?q(r,`styles`,F):void 0,i,!a),s=o.baseFragments.length,c=o.names.length===0,l=$e(n.includes(`variants`)?q(r,`variants`,I):void 0,i,c,o.indexes,s),u=et(n.includes(`defaultVariants`)?q(r,`defaultVariants`,L):void 0,i,l.variants,l.indexes),d=nt(n.includes(`compoundVariants`)?q(r,`compoundVariants`,R):void 0,i,c,o.indexes,s,l.variants,l.indexes),f=Z(s);for(let e of d)for(let t=0;t<s;t++)e.fragmentsByPart[t]!==void 0&&X(f[t]??=[],e);return{partNames:o.names,baseFragmentsByPart:o.baseFragments,variants:l.variants,defaultStates:u,compounds:d,compoundsByPart:f}}function it(e,t){if(e===void 0)return t.defaultStates;let n=He(e,V),r=U(n);if(W(n,r,`class`))throw G(`${V}.class`,`reserved field`);if(W(n,r,H))throw G(`${V}.className`,`caller classes belong to a style resolver`);let i=e,a;for(let e=0;e<t.variants.length;e++){let o=t.variants[e];if(!W(n,r,o.name))continue;let s=`${V}.${o.name}`,c=q(i,o.name,s);c!==void 0&&(a??=[...t.defaultStates],a[e]=$(c,o,s))}return a??t.defaultStates}function at(e,t,n){if(t!==void 0){let e=n<Je||P.call(t,n)?t[n]:void 0;if(e!==void 0)return e}return e[n]}function ot(e,t,n){for(let r of e.conditions){let e=at(t,n,r.variantIndex),i=!1;for(let t of r.states)if(e===t){i=!0;break}if(!i)return!1}return!0}function st(e,t,n){if(n===void 0)return t;for(let r of n)Ye(e,t,r),t++;return t}function ct(e,t,n,r,i,a,o){let s,c;if(r!==void 0){let t=He(r,a),n=U(t);if(W(t,n,`class`))throw G(`${a}.class`,`reserved field`);let i=r;for(let r=0;r<e.variants.length;r++){let o=e.variants[r];if(!W(t,n,o.name))continue;let c=`${a}.${o.name}`,l=q(i,o.name,c);l!==void 0&&(s??=qe(),Ye(s,r,$(l,o,c)))}W(t,n,`className`)&&(c=q(i,`className`,`${a}.className`))}let l=qe(),u=st(l,0,e.baseFragmentsByPart[t]);for(let r=0;r<e.variants.length;r++){let i=at(n,s,r);if(i==null)continue;let a=e.variants[r].choices[i];a!==void 0&&(u=st(l,u,a.fragmentsByPart[t]))}for(let r of e.compoundsByPart[t]??[])ot(r,n,s)&&(u=st(l,u,r.fragmentsByPart[t]));c!==void 0&&(Ye(l,u,c),u++),l.length=u;let d=Reflect.apply(i,void 0,l);if(typeof d!=`string`)throw G(o,`merger must return a primitive string`);return d}function lt(e,t){return e.partNames.length===0?(n=>ct(e,0,e.defaultStates,n,t,V,`recipe result`)):(n=>{let r=it(n,e),i=Object.create(null);for(let n=0;n<e.partNames.length;n++){let a=e.partNames[n];i[a]=i=>ct(e,n,r,i,t,`style props.${a}`,`style result.${a}`)}return i})}function ut(e){let t=K(e,z);for(let e of t)if(e!==`merge`)throw G(z,`unknown field ${JSON.stringify(e)}`);if(!t.includes(`merge`))throw G(B,Re);let n=q(e,`merge`,B);if(typeof n!=`function`)throw G(B,`expected a callable merger`);let r=n,i=new WeakMap;return(e=>{let t=rt(e,i),n=lt(t,r);return i.set(n,t),n})}export{_ as MERGE_OPAQUE,v as MergerProtocolError,ut as createDefiner,Fe as createMerger};
|
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@teacss/classes",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "TeaCSS class composition — typed recipes, nested class-value joining, and semantic conflict resolution.",
|
|
5
|
+
"homepage": "https://css.teasim.com",
|
|
6
|
+
"funding": "https://github.com/sponsors/billgo",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"author": "Billgo <hi@billgo.me>",
|
|
9
|
+
"sideEffects": false,
|
|
10
|
+
"type": "module",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": "./dist/index.js",
|
|
13
|
+
"./package.json": "./package.json"
|
|
14
|
+
},
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"README.md"
|
|
19
|
+
],
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "bunx rimraf dist && bunx tsdown --config tsdown.config.mts",
|
|
22
|
+
"dev": "tsdown --watch"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@teacss/core": "0.3.0"
|
|
26
|
+
},
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">=22.12.0"
|
|
29
|
+
},
|
|
30
|
+
"publishConfig": {
|
|
31
|
+
"access": "public"
|
|
32
|
+
}
|
|
33
|
+
}
|