fashionable 0.2.0 → 0.4.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/dist/calc/index.d.mts +1 -1
- package/dist/calc/index.mjs +1 -1
- package/dist/data/index.d.mts +2 -208
- package/dist/data/index.mjs +73 -54
- package/dist/data/index.mjs.map +1 -1
- package/dist/declaration/index.d.mts +1 -1
- package/dist/declaration/index.mjs +9 -28
- package/dist/declaration/index.mjs.map +1 -1
- package/dist/fontFace/index.d.mts +1 -1
- package/dist/property/index.d.mts +1 -1
- package/dist/property/index.mjs +1 -1
- package/dist/property/index.mjs.map +1 -1
- package/dist/query/index.d.mts +1 -1
- package/dist/query/index.mjs +137 -3
- package/dist/query/index.mjs.map +1 -1
- package/dist/rule/index.d.mts +1 -1
- package/dist/rule/index.mjs +45 -33
- package/dist/rule/index.mjs.map +1 -1
- package/dist/selector/index.d.mts +1 -1
- package/dist/selector/index.mjs +117 -21
- package/dist/selector/index.mjs.map +1 -1
- package/dist/shared/{calc-Cih4o2r7.mjs → calc-Uwbxd7CS.mjs} +233 -165
- package/dist/shared/calc-Uwbxd7CS.mjs.map +1 -0
- package/dist/shared/{color.internal-Dts5ycTm.mjs → color.internal-CxjlaRqR.mjs} +48 -13
- package/dist/shared/color.internal-CxjlaRqR.mjs.map +1 -0
- package/dist/shared/declaration-CqRm38oZ.d.mts +264 -0
- package/dist/shared/declaration.internal-bHzvbanA.mjs +121 -0
- package/dist/shared/declaration.internal-bHzvbanA.mjs.map +1 -0
- package/dist/shared/{fontFaceRule-C7nYgH6X.d.mts → fontFaceRule-BOgUM4PF.d.mts} +3 -3
- package/dist/shared/index-D-hVWDgZ.d.mts +2289 -0
- package/dist/shared/mediaQuery-VDIAHnM1.d.mts +333 -0
- package/dist/shared/{mediaQuery.internal-B6iuMd75.mjs → mediaQuery.internal-CKTmLVxL.mjs} +70 -6
- package/dist/shared/mediaQuery.internal-CKTmLVxL.mjs.map +1 -0
- package/dist/shared/{mediaRule-BDB4WCYy.d.mts → mediaRule-2K7Ggwe4.d.mts} +169 -105
- package/dist/shared/{propertyRule-BbkFh9b9.d.mts → propertyRule-B9ii0mv4.d.mts} +56 -21
- package/dist/shared/{propertyRule.internal-Bc_HrfcL.mjs → propertyRule.internal-ncYCWUar.mjs} +31 -4
- package/dist/shared/propertyRule.internal-ncYCWUar.mjs.map +1 -0
- package/dist/shared/{ruleSet.internal-DodzVMUU.mjs → ruleSet.internal-Cj4yIYFI.mjs} +31 -18
- package/dist/shared/ruleSet.internal-Cj4yIYFI.mjs.map +1 -0
- package/dist/shared/selector-BkxnzX_6.d.mts +615 -0
- package/dist/shared/{selector.internal-ESe9s0IH.mjs → selector.internal-B3iu_RpX.mjs} +144 -30
- package/dist/shared/selector.internal-B3iu_RpX.mjs.map +1 -0
- package/dist/shared/{utils-BKm298I-.d.mts → utils-DpN6qr94.d.mts} +4 -4
- package/dist/shared/var.internal-DSxAzEFN.mjs +119 -0
- package/dist/shared/var.internal-DSxAzEFN.mjs.map +1 -0
- package/dist/stylesheet/index.d.mts +93 -60
- package/dist/stylesheet/index.mjs +111 -35
- package/dist/stylesheet/index.mjs.map +1 -1
- package/dist/utils.d.mts +1 -1
- package/dist/utils.mjs.map +1 -1
- package/dist/var/index.d.mts +2 -0
- package/dist/var/index.mjs +177 -0
- package/dist/var/index.mjs.map +1 -0
- package/package.json +8 -2
- package/dist/shared/calc-Cih4o2r7.mjs.map +0 -1
- package/dist/shared/color-BvNJ2YqL.d.mts +0 -590
- package/dist/shared/color.internal-Dts5ycTm.mjs.map +0 -1
- package/dist/shared/declaration-1DlO_ltT.d.mts +0 -166
- package/dist/shared/declaration.internal-wLB4ssxC.mjs +0 -73
- package/dist/shared/declaration.internal-wLB4ssxC.mjs.map +0 -1
- package/dist/shared/index-BvtwY4FQ.d.mts +0 -841
- package/dist/shared/mediaQuery-BYR1z-iD.d.mts +0 -145
- package/dist/shared/mediaQuery.internal-B6iuMd75.mjs.map +0 -1
- package/dist/shared/propertyRule.internal-Bc_HrfcL.mjs.map +0 -1
- package/dist/shared/ruleSet.internal-DodzVMUU.mjs.map +0 -1
- package/dist/shared/selector-HZY-W6l6.d.mts +0 -346
- package/dist/shared/selector.internal-ESe9s0IH.mjs.map +0 -1
package/dist/selector/index.mjs
CHANGED
|
@@ -1,27 +1,37 @@
|
|
|
1
1
|
import { t as __exportAll } from "../shared/rolldown-runtime-D7D4PA-g.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { C as universal$1, D as isSpecificity$1, E as equals$3, O as make$1, S as under$1, T as compare$1, _ as render$1, a as descendant$1, b as subsequentSibling$1, c as id$1, f as nest$1, g as pseudoElement$1, h as pseudoClass$1, i as child$1, l as is$1, m as not$1, n as and$1, o as equals$2, p as nextSibling$1, r as attribute$1, s as has$1, t as _class$1, u as isSelector$1, v as root$1, w as where$1, x as type$1, y as specificity$1 } from "../shared/selector.internal-B3iu_RpX.mjs";
|
|
3
3
|
//#region src/selector/selector.ts
|
|
4
4
|
var selector_exports = /* @__PURE__ */ __exportAll({
|
|
5
5
|
and: () => and,
|
|
6
6
|
attribute: () => attribute,
|
|
7
|
+
child: () => child,
|
|
7
8
|
class: () => _class,
|
|
9
|
+
descendant: () => descendant,
|
|
8
10
|
equals: () => equals$1,
|
|
11
|
+
has: () => has,
|
|
9
12
|
id: () => id,
|
|
13
|
+
is: () => is,
|
|
10
14
|
isSelector: () => isSelector,
|
|
15
|
+
nest: () => nest,
|
|
16
|
+
nextSibling: () => nextSibling,
|
|
11
17
|
not: () => not,
|
|
12
18
|
pseudoClass: () => pseudoClass,
|
|
13
19
|
pseudoElement: () => pseudoElement,
|
|
14
20
|
render: () => render,
|
|
15
21
|
root: () => root,
|
|
16
22
|
specificity: () => specificity,
|
|
23
|
+
subsequentSibling: () => subsequentSibling,
|
|
17
24
|
type: () => type,
|
|
18
|
-
|
|
25
|
+
under: () => under,
|
|
26
|
+
universal: () => universal,
|
|
27
|
+
where: () => where
|
|
19
28
|
});
|
|
20
29
|
/**
|
|
21
30
|
* Checks if a value is a `Selector`.
|
|
22
31
|
*
|
|
23
32
|
* True only for values built by this module's constructors, which carry
|
|
24
|
-
* the brand.
|
|
33
|
+
* the brand. The guard widens to `Selector<Requirement>` — it proves the
|
|
34
|
+
* brand, not closedness.
|
|
25
35
|
*
|
|
26
36
|
* @param u - The value to check.
|
|
27
37
|
* @returns `true` if the value is a `Selector`, `false` otherwise.
|
|
@@ -35,6 +45,23 @@ const isSelector = isSelector$1;
|
|
|
35
45
|
*/
|
|
36
46
|
const universal = universal$1;
|
|
37
47
|
/**
|
|
48
|
+
* The nesting selector, `&` — a reference to the enclosing rule's
|
|
49
|
+
* selector, usable anywhere a simple selector is: merged into a compound
|
|
50
|
+
* (`&.active`), under a combinator (`& *`), or inside a selector list
|
|
51
|
+
* (`:is(&, & *)`).
|
|
52
|
+
*
|
|
53
|
+
* Carrying it marks the selector `Parent`-requiring: nested style rules
|
|
54
|
+
* must reference it, and top-level positions reject it. Its specificity
|
|
55
|
+
* is the parent selector's, so `specificity` refuses it unresolved —
|
|
56
|
+
* substitute the parent with `under` first.
|
|
57
|
+
*
|
|
58
|
+
* In a compound it sorts just after the type slot: a type selector must
|
|
59
|
+
* come first even beside `&` (`div&`, never `&div`).
|
|
60
|
+
*
|
|
61
|
+
* @since 0.4.0
|
|
62
|
+
*/
|
|
63
|
+
const nest = nest$1;
|
|
64
|
+
/**
|
|
38
65
|
* Creates a type (element) selector, such as `div`.
|
|
39
66
|
*
|
|
40
67
|
* A compound may contain at most one type or universal selector; `and`
|
|
@@ -69,8 +96,8 @@ const _class = _class$1;
|
|
|
69
96
|
/**
|
|
70
97
|
* Creates a pseudo-class selector, rendered `:name`.
|
|
71
98
|
*
|
|
72
|
-
* For the functional
|
|
73
|
-
* typed selector
|
|
99
|
+
* For the functional pseudo-classes over selector lists, use `is`,
|
|
100
|
+
* `where`, `has`, or `not`, which take typed selector arguments.
|
|
74
101
|
*
|
|
75
102
|
* @param name - The pseudo-class name, without the `:` prefix. Must be non-empty.
|
|
76
103
|
* @returns A one-part `Selector`.
|
|
@@ -80,19 +107,76 @@ const _class = _class$1;
|
|
|
80
107
|
const pseudoClass = pseudoClass$1;
|
|
81
108
|
const attribute = attribute$1;
|
|
82
109
|
/**
|
|
83
|
-
* Creates a
|
|
84
|
-
*
|
|
85
|
-
*
|
|
110
|
+
* Creates a matches-any pseudo-class, rendered `:is(a, b, ...)`. The
|
|
111
|
+
* arguments form a selector list — compound or complex alike — and the
|
|
112
|
+
* part matches an element matching any of them.
|
|
86
113
|
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
114
|
+
* The list canonically sorts (matching is order-independent), so
|
|
115
|
+
* `is(a, b)` equals `is(b, a)`. The part's specificity is its most
|
|
116
|
+
* specific argument's. Requirements union across arguments — an `&`
|
|
117
|
+
* inside the list marks the whole selector `Parent`-requiring.
|
|
118
|
+
*
|
|
119
|
+
* @param selectors - The selector list. At least one.
|
|
120
|
+
* @returns A one-part `Selector` carrying the arguments' requirements.
|
|
121
|
+
* @throws `Error` when called with no arguments.
|
|
122
|
+
* @example
|
|
123
|
+
* ```ts
|
|
124
|
+
* Selector.render(Selector.is(Selector.nest, Selector.descendant(Selector.nest, Selector.universal)))
|
|
125
|
+
* // ':is(&, & *)'
|
|
126
|
+
* ```
|
|
127
|
+
* @since 0.4.0
|
|
128
|
+
*/
|
|
129
|
+
const is = is$1;
|
|
130
|
+
/**
|
|
131
|
+
* Creates a zero-specificity matches-any pseudo-class, rendered
|
|
132
|
+
* `:where(a, b, ...)`. Matching is identical to `is`; the part
|
|
133
|
+
* contributes nothing to specificity regardless of its arguments.
|
|
134
|
+
*
|
|
135
|
+
* The list canonically sorts, and requirements union across arguments.
|
|
136
|
+
*
|
|
137
|
+
* @param selectors - The selector list. At least one.
|
|
138
|
+
* @returns A one-part `Selector` carrying the arguments' requirements.
|
|
139
|
+
* @throws `Error` when called with no arguments.
|
|
140
|
+
* @since 0.4.0
|
|
141
|
+
*/
|
|
142
|
+
const where = where$1;
|
|
143
|
+
/**
|
|
144
|
+
* Creates a relational pseudo-class, rendered `:has(a, b, ...)`: the
|
|
145
|
+
* part matches an element whose subtree contains a match for any
|
|
146
|
+
* argument.
|
|
147
|
+
*
|
|
148
|
+
* Arguments are ordinary selectors — the relative forms with a leading
|
|
149
|
+
* combinator (`:has(> .x)`) are not modeled. The list canonically
|
|
150
|
+
* sorts, the part's specificity is its most specific argument's, and
|
|
151
|
+
* requirements union across arguments.
|
|
152
|
+
*
|
|
153
|
+
* @param selectors - The selector list. At least one.
|
|
154
|
+
* @returns A one-part `Selector` carrying the arguments' requirements.
|
|
155
|
+
* @throws `Error` when called with no arguments.
|
|
156
|
+
* @since 0.4.0
|
|
157
|
+
*/
|
|
158
|
+
const has = has$1;
|
|
159
|
+
/**
|
|
160
|
+
* Creates a functional negation, rendered `:not(a, b, ...)`. The
|
|
161
|
+
* arguments form a selector list; the part matches an element matching
|
|
162
|
+
* none of them.
|
|
163
|
+
*
|
|
164
|
+
* The list canonically sorts, the part's specificity is its most
|
|
165
|
+
* specific argument's (`:not` itself contributes none), and
|
|
166
|
+
* requirements union across arguments.
|
|
167
|
+
*
|
|
168
|
+
* @param selectors - The selector list to negate. At least one.
|
|
169
|
+
* @returns A one-part `Selector` carrying the arguments' requirements.
|
|
170
|
+
* @throws `Error` when called with no arguments.
|
|
89
171
|
* @since 0.1.0
|
|
90
172
|
*/
|
|
91
173
|
const not = not$1;
|
|
92
174
|
/**
|
|
93
175
|
* Creates a pseudo-element selector, rendered `::name`.
|
|
94
176
|
*
|
|
95
|
-
* A compound may contain at most one pseudo-element; `and` enforces
|
|
177
|
+
* A compound may contain at most one pseudo-element; `and` enforces
|
|
178
|
+
* this. No combinator may follow one — the combinator constructors
|
|
179
|
+
* enforce that.
|
|
96
180
|
*
|
|
97
181
|
* @param name - The pseudo-element name, without the `::` prefix. Must be non-empty.
|
|
98
182
|
* @returns A one-part `Selector`.
|
|
@@ -108,26 +192,38 @@ const pseudoElement = pseudoElement$1;
|
|
|
108
192
|
*/
|
|
109
193
|
const root = root$1;
|
|
110
194
|
const and = and$1;
|
|
195
|
+
const descendant = descendant$1;
|
|
196
|
+
const child = child$1;
|
|
197
|
+
const nextSibling = nextSibling$1;
|
|
198
|
+
const subsequentSibling = subsequentSibling$1;
|
|
199
|
+
const under = under$1;
|
|
111
200
|
/**
|
|
112
|
-
* Computes the selector's specificity: ids into `a`;
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
201
|
+
* Computes the selector's specificity: ids into `a`; classes,
|
|
202
|
+
* attributes, and pseudo-classes into `b`; types and pseudo-elements
|
|
203
|
+
* into `c`. Compounds in a complex selector sum. `:is()`, `:has()`, and
|
|
204
|
+
* `:not()` add their most specific argument; `:where()` and the
|
|
205
|
+
* universal selector add nothing; duplicate parts count each time.
|
|
206
|
+
*
|
|
207
|
+
* Closed selectors only: an `&`-bearing selector takes its specificity
|
|
208
|
+
* from the parent rule, so the parameter rejects `Parent`-requiring
|
|
209
|
+
* selectors at compile time — resolve them with `under` first.
|
|
116
210
|
*
|
|
117
211
|
* This is what lets a consumer turn "these rules tie, so their order
|
|
118
212
|
* encodes the override direction" into something checkable.
|
|
119
213
|
*
|
|
120
|
-
* @param selector - The selector to measure.
|
|
214
|
+
* @param selector - The selector to measure. Must be closed (no `&`).
|
|
121
215
|
* @returns The computed `Specificity`.
|
|
122
216
|
* @since 0.1.0
|
|
123
217
|
*/
|
|
124
218
|
const specificity = specificity$1;
|
|
125
219
|
/**
|
|
126
|
-
* Renders the selector as CSS text: parts concatenated
|
|
127
|
-
* order — type first, then ids, classes,
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
*
|
|
220
|
+
* Renders the selector as CSS text: each compound's parts concatenated
|
|
221
|
+
* in canonical order — type first, then `&`, ids, classes,
|
|
222
|
+
* pseudo-classes, attributes, functional pseudo-classes, and the
|
|
223
|
+
* pseudo-element last, alphabetically within each kind — and compounds
|
|
224
|
+
* joined by their combinators in authored order. Any fixed part order
|
|
225
|
+
* matches identically; this one keeps root-scoped shapes in their
|
|
226
|
+
* conventional spelling.
|
|
131
227
|
*
|
|
132
228
|
* @param selector - The selector to render.
|
|
133
229
|
* @returns Deterministic CSS text.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["internal.isSelector","internal.universal","internal.type","internal.id","internal._class","internal.pseudoClass","internal.attribute","internal.not","internal.pseudoElement","internal.root","internal.and","internal.specificity","internal.render","equals","internal.equals","internal.isSpecificity","internal.make","internal.compare","internal.equals"],"sources":["../../src/selector/selector.ts","../../src/selector/specificity.ts"],"sourcesContent":["import type { Pipeable } from '#util'\nimport type { SelectorTypeId } from './selector.internal.ts'\nimport * as internal from './selector.internal.ts'\nimport type { Specificity } from './specificity.ts'\n\n/**\n * A compound selector: a canonically ordered, non-empty collection of\n * simple-selector parts, all constraining the same element.\n *\n * Part constructors (`type`, `id`, `class`, `attribute`,\n * `pseudoClass`, `not`, `pseudoElement`, `universal`) return one-part\n * selectors; `and` merges compounds. Construction canonically orders the\n * parts, so structurally equal selectors compare equal however they were\n * built, and rendering is deterministic. Duplicate parts are kept —\n * `.a.a` legally has specificity `(0, 2, 0)`.\n *\n * Combinators (descendant, child) are a later extension layered above\n * this type; a `Selector` always describes one compound.\n *\n * @since 0.1.0\n */\nexport interface Selector extends Pipeable {\n readonly [SelectorTypeId]: SelectorTypeId\n}\n\n/**\n * CSS's six attribute-match operators: exact (`=`), word (`~=`),\n * hyphen-prefix (`|=`), prefix (`^=`), suffix (`$=`), and substring\n * (`*=`).\n *\n * @since 0.1.0\n */\nexport type AttributeOperator = '=' | '~=' | '|=' | '^=' | '$=' | '*='\n\n/**\n * Checks if a value is a `Selector`.\n *\n * True only for values built by this module's constructors, which carry\n * the brand.\n *\n * @param u - The value to check.\n * @returns `true` if the value is a `Selector`, `false` otherwise.\n * @since 0.1.0\n */\nexport const isSelector: (u: unknown) => u is Selector = internal.isSelector\n\n/**\n * The universal selector, `*`. Contributes nothing to specificity.\n *\n * @since 0.1.0\n */\nexport const universal: Selector = internal.universal\n\n/**\n * Creates a type (element) selector, such as `div`.\n *\n * A compound may contain at most one type or universal selector; `and`\n * enforces this.\n *\n * @param name - The element name. Must be non-empty; passed through unescaped.\n * @returns A one-part `Selector`.\n * @throws `Error` when `name` is empty.\n * @since 0.1.0\n */\nexport const type: (name: string) => Selector = internal.type\n\n/**\n * Creates an id selector, rendered `#name`.\n *\n * @param name - The id, without the `#` prefix. Must be non-empty; passed through unescaped.\n * @returns A one-part `Selector`.\n * @throws `Error` when `name` is empty.\n * @since 0.1.0\n */\nexport const id: (name: string) => Selector = internal.id\n\n/**\n * Creates a class selector, rendered `.name`. Exported as `class`\n * (`Selector.class('btn')`) because `class` is reserved in declaration\n * position.\n *\n * @param name - The class name, without the `.` prefix. Must be non-empty; passed through unescaped.\n * @returns A one-part `Selector`.\n * @throws `Error` when `name` is empty.\n * @since 0.1.0\n */\nconst _class: (name: string) => Selector = internal._class\nexport { _class as class }\n\n/**\n * Creates a pseudo-class selector, rendered `:name`.\n *\n * For the functional negation pseudo-class, use `not`, which takes a\n * typed selector argument.\n *\n * @param name - The pseudo-class name, without the `:` prefix. Must be non-empty.\n * @returns A one-part `Selector`.\n * @throws `Error` when `name` is empty.\n * @since 0.1.0\n */\nexport const pseudoClass: (name: string) => Selector = internal.pseudoClass\n\nexport const attribute: {\n /**\n * Creates a presence-only attribute selector, rendered `[name]`.\n *\n * @param name - The attribute name. Must be non-empty; passed through unescaped.\n * @returns A one-part `Selector`.\n * @throws `Error` when `name` is empty.\n * @since 0.1.0\n */\n (name: string): Selector\n /**\n * Creates an exact-match attribute selector, rendered `[name='value']`.\n * The two-argument form assumes the `=` operator.\n *\n * @param name - The attribute name. Must be non-empty; passed through unescaped.\n * @param value - The value to match. Renders single-quoted with embedded quotes and backslashes escaped.\n * @returns A one-part `Selector`.\n * @throws `Error` when `name` is empty.\n * @example\n * ```ts\n * Selector.render(Selector.attribute('data-scheme', 'dark')) // \"[data-scheme='dark']\"\n * ```\n * @since 0.1.0\n */\n (name: string, value: string): Selector\n /**\n * Creates an attribute selector with an explicit operator, rendered\n * `[name<operator>'value']`.\n *\n * @param name - The attribute name. Must be non-empty; passed through unescaped.\n * @param operator - One of the six `AttributeOperator` spellings.\n * @param value - The value to match. Renders single-quoted with embedded quotes and backslashes escaped.\n * @returns A one-part `Selector`.\n * @throws `Error` when `name` is empty or `operator` is not an attribute operator.\n * @example\n * ```ts\n * Selector.render(Selector.attribute('href', '^=', 'https:')) // \"[href^='https:']\"\n * ```\n * @since 0.1.0\n */\n (name: string, operator: AttributeOperator, value: string): Selector\n} = internal.attribute\n\n/**\n * Creates a functional negation, rendered `:not(argument)`. The argument\n * is a full compound selector, and contributes its own specificity to the\n * enclosing selector (`:not` itself contributes none).\n *\n * @param argument - The selector to negate.\n * @returns A one-part `Selector`.\n * @since 0.1.0\n */\nexport const not: (argument: Selector) => Selector = internal.not\n\n/**\n * Creates a pseudo-element selector, rendered `::name`.\n *\n * A compound may contain at most one pseudo-element; `and` enforces this.\n *\n * @param name - The pseudo-element name, without the `::` prefix. Must be non-empty.\n * @returns A one-part `Selector`.\n * @throws `Error` when `name` is empty.\n * @since 0.1.0\n */\nexport const pseudoElement: (name: string) => Selector = internal.pseudoElement\n\n/**\n * The `:root` pseudo-class selector — sugar for `pseudoClass('root')`,\n * the usual anchor for custom-property rules.\n *\n * @since 0.1.0\n */\nexport const root: Selector = internal.root\n\nexport const and: {\n /**\n * Returns a function that merges `that` into its argument.\n *\n * @param that - The selector to merge in.\n * @returns A function producing the merged compound.\n * @since 0.1.0\n */\n (that: Selector): (self: Selector) => Selector\n /**\n * Merges two compounds into one, constraining the same element with\n * every part of both. Parts re-sort into canonical order, so `and` is\n * commutative; duplicates are kept.\n *\n * @param self - The first compound.\n * @param that - The second compound.\n * @returns The merged compound.\n * @throws `Error` when the merge would contain two type/universal selectors or two pseudo-elements.\n * @example\n * ```ts\n * Selector.root.pipe(\n * Selector.and(Selector.attribute('data-scheme', 'dark')),\n * Selector.render,\n * ) // \":root[data-scheme='dark']\"\n * ```\n * @since 0.1.0\n */\n (self: Selector, that: Selector): Selector\n} = internal.and\n\n/**\n * Computes the selector's specificity: ids into `a`;\n * classes, attributes, and pseudo-classes into `b`; types and\n * pseudo-elements into `c`. `:not(...)` adds its argument's specificity;\n * the universal selector adds nothing; duplicate parts count each time.\n *\n * This is what lets a consumer turn \"these rules tie, so their order\n * encodes the override direction\" into something checkable.\n *\n * @param selector - The selector to measure.\n * @returns The computed `Specificity`.\n * @since 0.1.0\n */\nexport const specificity: (selector: Selector) => Specificity = internal.specificity\n\n/**\n * Renders the selector as CSS text: parts concatenated in canonical\n * order — type first, then ids, classes, pseudo-classes, attributes,\n * negations, and the pseudo-element last, alphabetically within each\n * kind. Any fixed order matches identically; this one keeps root-scoped\n * shapes in their conventional spelling.\n *\n * @param selector - The selector to render.\n * @returns Deterministic CSS text.\n * @example\n * ```ts\n * Selector.render(Selector.and(Selector.pseudoClass('hover'), Selector.class('btn')))\n * // '.btn:hover'\n * ```\n * @since 0.1.0\n */\nexport const render: (selector: Selector) => string = internal.render\n\nexport const equals: {\n /**\n * Returns a function that checks structural equality against `that`.\n *\n * @param that - The selector to compare against.\n * @returns A function testing its argument for structural equality with `that`.\n * @since 0.1.0\n */\n (that: Selector): (self: Selector) => boolean\n /**\n * Structural equality over canonically ordered parts: two selectors\n * built from the same parts compare equal regardless of construction\n * order.\n *\n * @param self - The first selector.\n * @param that - The second selector.\n * @returns `true` if the selectors are structurally equal.\n * @since 0.1.0\n */\n (self: Selector, that: Selector): boolean\n} = internal.equals\n","import type { Pipeable } from '#util'\nimport type { SpecificityTypeId } from './specificity.internal.ts'\nimport * as internal from './specificity.internal.ts'\n\n/**\n * A selector specificity: the `(a, b, c)` triple the cascade compares\n * lexicographically — id count, then class/attribute/pseudo-class count,\n * then type/pseudo-element count.\n *\n * Computed from selectors via `Selector.specificity`; construct directly\n * with `make` when asserting expectations.\n *\n * @since 0.1.0\n */\nexport interface Specificity extends Pipeable {\n readonly [SpecificityTypeId]: SpecificityTypeId\n /**\n * The id-selector count.\n */\n readonly a: number\n /**\n * The class, attribute, and pseudo-class count.\n */\n readonly b: number\n /**\n * The type and pseudo-element count.\n */\n readonly c: number\n}\n\n/**\n * Checks if a value is a `Specificity`.\n *\n * True only for values built by this module's constructors, which carry\n * the brand.\n *\n * @param u - The value to check.\n * @returns `true` if the value is a `Specificity`, `false` otherwise.\n * @since 0.1.0\n */\nexport const isSpecificity: (u: unknown) => u is Specificity = internal.isSpecificity\n\n/**\n * Creates a `Specificity` from its three components.\n *\n * @param a - The id-selector count. Must be a non-negative integer.\n * @param b - The class/attribute/pseudo-class count. Must be a non-negative integer.\n * @param c - The type/pseudo-element count. Must be a non-negative integer.\n * @returns A new `Specificity`.\n * @throws `Error` when any component is not a non-negative integer.\n * @since 0.1.0\n */\nexport const make: (a: number, b: number, c: number) => Specificity = internal.make\n\nexport const compare: {\n /**\n * Returns a function that compares its argument against `that`.\n *\n * @param that - The specificity to compare against.\n * @returns A function returning the cascade ordering of its argument relative to `that`.\n * @since 0.1.0\n */\n (that: Specificity): (self: Specificity) => -1 | 0 | 1\n /**\n * Compares two specificities the way the cascade does: lexicographically\n * by `a`, then `b`, then `c`.\n *\n * @param self - The first specificity.\n * @param that - The second specificity.\n * @returns `-1` if `self` is less specific, `1` if more, `0` if equal.\n * @example\n * ```ts\n * Specificity.compare(Specificity.make(1, 0, 0), Specificity.make(0, 9, 9)) // 1\n * ```\n * @since 0.1.0\n */\n (self: Specificity, that: Specificity): -1 | 0 | 1\n} = internal.compare\n\nexport const equals: {\n /**\n * Returns a function that checks equality against `that`.\n *\n * @param that - The specificity to compare against.\n * @returns A function testing its argument for equality with `that`.\n * @since 0.1.0\n */\n (that: Specificity): (self: Specificity) => boolean\n /**\n * Component-wise equality of two specificities.\n *\n * @param self - The first specificity.\n * @param that - The second specificity.\n * @returns `true` if all three components match.\n * @since 0.1.0\n */\n (self: Specificity, that: Specificity): boolean\n} = internal.equals\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4CA,MAAa,aAA4CA;;;;;;AAOzD,MAAa,YAAsBC;;;;;;;;;;;;AAanC,MAAa,OAAmCC;;;;;;;;;AAUhD,MAAa,KAAiCC;;;;;;;;;;;AAY9C,MAAM,SAAqCC;;;;;;;;;;;;AAc3C,MAAa,cAA0CC;AAEvD,MAAa,YAyCTC;;;;;;;;;;AAWJ,MAAa,MAAwCC;;;;;;;;;;;AAYrD,MAAa,gBAA4CC;;;;;;;AAQzD,MAAa,OAAiBC;AAE9B,MAAa,MA4BTC;;;;;;;;;;;;;;AAeJ,MAAa,cAAmDC;;;;;;;;;;;;;;;;;AAkBhE,MAAa,SAAyCC;AAEtD,MAAaC,WAoBTC;;;;;;;;;;;;;;;;;;;AC3NJ,MAAa,gBAAkDC;;;;;;;;;;;AAY/D,MAAa,OAAyDC;AAEtE,MAAa,UAuBTC;AAEJ,MAAa,SAkBTC"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["internal.isSelector","internal.universal","internal.nest","internal.type","internal.id","internal._class","internal.pseudoClass","internal.attribute","internal.is","internal.where","internal.has","internal.not","internal.pseudoElement","internal.root","internal.and","internal.descendant","internal.child","internal.nextSibling","internal.subsequentSibling","internal.under","internal.specificity","internal.render","equals","internal.equals","internal.isSpecificity","internal.make","internal.compare","internal.equals"],"sources":["../../src/selector/selector.ts","../../src/selector/specificity.ts"],"sourcesContent":["import type { Pipeable } from '#util'\nimport type { SelectorTypeId } from './selector.internal.ts'\nimport * as internal from './selector.internal.ts'\nimport type { Specificity } from './specificity.ts'\n\ndeclare const ParentId: unique symbol\ndeclare const SelectorRequires: unique symbol\n\n/**\n * The requirement carried by a selector that references the nesting\n * selector (`&`): a parent rule must bind the reference before the\n * selector means anything on its own.\n *\n * Nesting the selector's rule inside another style rule discharges it —\n * the enclosing rule's selector is what `&` reads. Top-level positions\n * and `specificity` reject selectors that still carry it. The channel's\n * design is derived in `docs/selector-nesting.md`.\n *\n * @since 0.4.0\n */\nexport type Parent = { readonly [ParentId]: 'parent' }\n\n/**\n * The union of context requirements a selector can carry — `Parent`\n * today, joined by sibling brands if the model grows other\n * context-dependent selectors.\n *\n * A parameter typed `Selector<Requirement>` admits every selector; bare\n * `Selector` (`Requires = never`) admits only closed ones.\n *\n * @since 0.4.0\n */\nexport type Requirement = Parent\n\n/**\n * The requirements of a `Selector`, or the union of them for a union of\n * selectors — the type-level extractor the list and combinator\n * constructors use to thread their arguments' requirements into the\n * result.\n *\n * @since 0.4.0\n */\nexport type SelectorRequires<S extends Selector<Requirement>> =\n S extends Selector<infer R> ? R : never\n\n/**\n * A CSS selector: one compound, or a sequence of compounds joined by\n * combinators, canonically ordered within each compound.\n *\n * Part constructors (`type`, `id`, `class`, `attribute`, `pseudoClass`,\n * `pseudoElement`, `universal`, `nest`) return one-part compounds; `and`\n * merges compounds; `descendant`, `child`, `nextSibling`, and\n * `subsequentSibling` join selectors into complex selectors; `is`,\n * `where`, `has`, and `not` wrap selector lists. Construction\n * canonically orders compound parts and list arguments, so structurally\n * equal selectors compare equal however they were built, and rendering\n * is deterministic. Combinator sequences are never reordered — their\n * order is their meaning. Duplicate parts are kept — `.a.a` legally has\n * specificity `(0, 2, 0)`.\n *\n * `Requires` is the requirements channel: `Parent` while the selector\n * references `&`, `never` once nothing outside the selector is needed.\n * Positions gate by covariance — a parameter typed `Selector` admits\n * only closed selectors, one typed `Selector<Requirement>` admits any.\n *\n * @since 0.1.0\n */\nexport interface Selector<out Requires extends Requirement = never> extends Pipeable {\n readonly [SelectorTypeId]: SelectorTypeId\n readonly [SelectorRequires]?: Requires\n}\n\n/**\n * CSS's six attribute-match operators: exact (`=`), word (`~=`),\n * hyphen-prefix (`|=`), prefix (`^=`), suffix (`$=`), and substring\n * (`*=`).\n *\n * @since 0.1.0\n */\nexport type AttributeOperator = '=' | '~=' | '|=' | '^=' | '$=' | '*='\n\n/**\n * Checks if a value is a `Selector`.\n *\n * True only for values built by this module's constructors, which carry\n * the brand. The guard widens to `Selector<Requirement>` — it proves the\n * brand, not closedness.\n *\n * @param u - The value to check.\n * @returns `true` if the value is a `Selector`, `false` otherwise.\n * @since 0.1.0\n */\nexport const isSelector: (u: unknown) => u is Selector<Requirement> = internal.isSelector\n\n/**\n * The universal selector, `*`. Contributes nothing to specificity.\n *\n * @since 0.1.0\n */\nexport const universal: Selector = internal.universal\n\n/**\n * The nesting selector, `&` — a reference to the enclosing rule's\n * selector, usable anywhere a simple selector is: merged into a compound\n * (`&.active`), under a combinator (`& *`), or inside a selector list\n * (`:is(&, & *)`).\n *\n * Carrying it marks the selector `Parent`-requiring: nested style rules\n * must reference it, and top-level positions reject it. Its specificity\n * is the parent selector's, so `specificity` refuses it unresolved —\n * substitute the parent with `under` first.\n *\n * In a compound it sorts just after the type slot: a type selector must\n * come first even beside `&` (`div&`, never `&div`).\n *\n * @since 0.4.0\n */\nexport const nest: Selector<Parent> = internal.nest\n\n/**\n * Creates a type (element) selector, such as `div`.\n *\n * A compound may contain at most one type or universal selector; `and`\n * enforces this.\n *\n * @param name - The element name. Must be non-empty; passed through unescaped.\n * @returns A one-part `Selector`.\n * @throws `Error` when `name` is empty.\n * @since 0.1.0\n */\nexport const type: (name: string) => Selector = internal.type\n\n/**\n * Creates an id selector, rendered `#name`.\n *\n * @param name - The id, without the `#` prefix. Must be non-empty; passed through unescaped.\n * @returns A one-part `Selector`.\n * @throws `Error` when `name` is empty.\n * @since 0.1.0\n */\nexport const id: (name: string) => Selector = internal.id\n\n/**\n * Creates a class selector, rendered `.name`. Exported as `class`\n * (`Selector.class('btn')`) because `class` is reserved in declaration\n * position.\n *\n * @param name - The class name, without the `.` prefix. Must be non-empty; passed through unescaped.\n * @returns A one-part `Selector`.\n * @throws `Error` when `name` is empty.\n * @since 0.1.0\n */\nconst _class: (name: string) => Selector = internal._class\nexport { _class as class }\n\n/**\n * Creates a pseudo-class selector, rendered `:name`.\n *\n * For the functional pseudo-classes over selector lists, use `is`,\n * `where`, `has`, or `not`, which take typed selector arguments.\n *\n * @param name - The pseudo-class name, without the `:` prefix. Must be non-empty.\n * @returns A one-part `Selector`.\n * @throws `Error` when `name` is empty.\n * @since 0.1.0\n */\nexport const pseudoClass: (name: string) => Selector = internal.pseudoClass\n\nexport const attribute: {\n /**\n * Creates a presence-only attribute selector, rendered `[name]`.\n *\n * @param name - The attribute name. Must be non-empty; passed through unescaped.\n * @returns A one-part `Selector`.\n * @throws `Error` when `name` is empty.\n * @since 0.1.0\n */\n (name: string): Selector\n /**\n * Creates an exact-match attribute selector, rendered `[name='value']`.\n * The two-argument form assumes the `=` operator.\n *\n * @param name - The attribute name. Must be non-empty; passed through unescaped.\n * @param value - The value to match. Renders single-quoted with embedded quotes and backslashes escaped.\n * @returns A one-part `Selector`.\n * @throws `Error` when `name` is empty.\n * @example\n * ```ts\n * Selector.render(Selector.attribute('data-scheme', 'dark')) // \"[data-scheme='dark']\"\n * ```\n * @since 0.1.0\n */\n (name: string, value: string): Selector\n /**\n * Creates an attribute selector with an explicit operator, rendered\n * `[name<operator>'value']`.\n *\n * @param name - The attribute name. Must be non-empty; passed through unescaped.\n * @param operator - One of the six `AttributeOperator` spellings.\n * @param value - The value to match. Renders single-quoted with embedded quotes and backslashes escaped.\n * @returns A one-part `Selector`.\n * @throws `Error` when `name` is empty or `operator` is not an attribute operator.\n * @example\n * ```ts\n * Selector.render(Selector.attribute('href', '^=', 'https:')) // \"[href^='https:']\"\n * ```\n * @since 0.1.0\n */\n (name: string, operator: AttributeOperator, value: string): Selector\n} = internal.attribute\n\n/**\n * Creates a matches-any pseudo-class, rendered `:is(a, b, ...)`. The\n * arguments form a selector list — compound or complex alike — and the\n * part matches an element matching any of them.\n *\n * The list canonically sorts (matching is order-independent), so\n * `is(a, b)` equals `is(b, a)`. The part's specificity is its most\n * specific argument's. Requirements union across arguments — an `&`\n * inside the list marks the whole selector `Parent`-requiring.\n *\n * @param selectors - The selector list. At least one.\n * @returns A one-part `Selector` carrying the arguments' requirements.\n * @throws `Error` when called with no arguments.\n * @example\n * ```ts\n * Selector.render(Selector.is(Selector.nest, Selector.descendant(Selector.nest, Selector.universal)))\n * // ':is(&, & *)'\n * ```\n * @since 0.4.0\n */\nexport const is: <Args extends ReadonlyArray<Selector<Requirement>>>(\n ...selectors: Args\n) => Selector<SelectorRequires<Args[number]>> = internal.is\n\n/**\n * Creates a zero-specificity matches-any pseudo-class, rendered\n * `:where(a, b, ...)`. Matching is identical to `is`; the part\n * contributes nothing to specificity regardless of its arguments.\n *\n * The list canonically sorts, and requirements union across arguments.\n *\n * @param selectors - The selector list. At least one.\n * @returns A one-part `Selector` carrying the arguments' requirements.\n * @throws `Error` when called with no arguments.\n * @since 0.4.0\n */\nexport const where: <Args extends ReadonlyArray<Selector<Requirement>>>(\n ...selectors: Args\n) => Selector<SelectorRequires<Args[number]>> = internal.where\n\n/**\n * Creates a relational pseudo-class, rendered `:has(a, b, ...)`: the\n * part matches an element whose subtree contains a match for any\n * argument.\n *\n * Arguments are ordinary selectors — the relative forms with a leading\n * combinator (`:has(> .x)`) are not modeled. The list canonically\n * sorts, the part's specificity is its most specific argument's, and\n * requirements union across arguments.\n *\n * @param selectors - The selector list. At least one.\n * @returns A one-part `Selector` carrying the arguments' requirements.\n * @throws `Error` when called with no arguments.\n * @since 0.4.0\n */\nexport const has: <Args extends ReadonlyArray<Selector<Requirement>>>(\n ...selectors: Args\n) => Selector<SelectorRequires<Args[number]>> = internal.has\n\n/**\n * Creates a functional negation, rendered `:not(a, b, ...)`. The\n * arguments form a selector list; the part matches an element matching\n * none of them.\n *\n * The list canonically sorts, the part's specificity is its most\n * specific argument's (`:not` itself contributes none), and\n * requirements union across arguments.\n *\n * @param selectors - The selector list to negate. At least one.\n * @returns A one-part `Selector` carrying the arguments' requirements.\n * @throws `Error` when called with no arguments.\n * @since 0.1.0\n */\nexport const not: <Args extends ReadonlyArray<Selector<Requirement>>>(\n ...selectors: Args\n) => Selector<SelectorRequires<Args[number]>> = internal.not\n\n/**\n * Creates a pseudo-element selector, rendered `::name`.\n *\n * A compound may contain at most one pseudo-element; `and` enforces\n * this. No combinator may follow one — the combinator constructors\n * enforce that.\n *\n * @param name - The pseudo-element name, without the `::` prefix. Must be non-empty.\n * @returns A one-part `Selector`.\n * @throws `Error` when `name` is empty.\n * @since 0.1.0\n */\nexport const pseudoElement: (name: string) => Selector = internal.pseudoElement\n\n/**\n * The `:root` pseudo-class selector — sugar for `pseudoClass('root')`,\n * the usual anchor for custom-property rules.\n *\n * @since 0.1.0\n */\nexport const root: Selector = internal.root\n\nexport const and: {\n /**\n * Returns a function that merges `that` into its argument.\n *\n * @param that - The compound to merge in.\n * @returns A function that takes a compound and returns the merged compound.\n * @since 0.1.0\n */\n <B extends Requirement>(\n that: Selector<B>,\n ): <A extends Requirement>(self: Selector<A>) => Selector<A | B>\n /**\n * Merges two compounds into one, constraining the same element with\n * every part of both. Parts re-sort into canonical order, so `and` is\n * commutative; duplicates are kept. Requirements union across the two\n * sides.\n *\n * Compounds only: a complex selector has no single element to\n * constrain. Join complex selectors with a combinator, or wrap them\n * in a selector list.\n *\n * @param self - The first compound.\n * @param that - The second compound.\n * @returns The merged compound, carrying both sides' requirements.\n * @throws `Error` when either operand is a complex selector, or when the merge would contain two type/universal selectors or two pseudo-elements.\n * @example\n * ```ts\n * Selector.root.pipe(\n * Selector.and(Selector.attribute('data-scheme', 'dark')),\n * Selector.render,\n * ) // \":root[data-scheme='dark']\"\n * ```\n * @since 0.1.0\n */\n <A extends Requirement, B extends Requirement>(\n self: Selector<A>,\n that: Selector<B>,\n ): Selector<A | B>\n} = internal.and\n\nexport const descendant: {\n /**\n * Returns a function that joins its argument to `that` with the\n * descendant combinator.\n *\n * @param that - The right (descendant) side.\n * @returns A function that takes a selector and returns the complex selector `self that`.\n * @since 0.4.0\n */\n <B extends Requirement>(\n that: Selector<B>,\n ): <A extends Requirement>(self: Selector<A>) => Selector<A | B>\n /**\n * Joins two selectors with the descendant combinator, rendered\n * `self that`: the right side matches anywhere inside the left side's\n * subtree.\n *\n * Either side may itself be complex; the compound sequence\n * concatenates in order, and nothing re-sorts across a combinator.\n * Requirements union across the two sides.\n *\n * @param self - The left (ancestor) side. Must not end in a compound containing a pseudo-element.\n * @param that - The right (descendant) side.\n * @returns The complex selector `self that`, carrying both sides' requirements.\n * @throws `Error` when `self` ends in a compound containing a pseudo-element — no combinator may follow one.\n * @example\n * ```ts\n * Selector.render(Selector.descendant(Selector.class('sidebar'), Selector.type('a')))\n * // '.sidebar a'\n * ```\n * @since 0.4.0\n */\n <A extends Requirement, B extends Requirement>(\n self: Selector<A>,\n that: Selector<B>,\n ): Selector<A | B>\n} = internal.descendant\n\nexport const child: {\n /**\n * Returns a function that joins its argument to `that` with the child\n * combinator.\n *\n * @param that - The right (child) side.\n * @returns A function that takes a selector and returns the complex selector `self > that`.\n * @since 0.4.0\n */\n <B extends Requirement>(\n that: Selector<B>,\n ): <A extends Requirement>(self: Selector<A>) => Selector<A | B>\n /**\n * Joins two selectors with the child combinator, rendered\n * `self > that`: the right side matches direct children of the left\n * side's matches. Composition rules are `descendant`'s.\n *\n * @param self - The left (parent) side. Must not end in a compound containing a pseudo-element.\n * @param that - The right (child) side.\n * @returns The complex selector `self > that`, carrying both sides' requirements.\n * @throws `Error` when `self` ends in a compound containing a pseudo-element — no combinator may follow one.\n * @since 0.4.0\n */\n <A extends Requirement, B extends Requirement>(\n self: Selector<A>,\n that: Selector<B>,\n ): Selector<A | B>\n} = internal.child\n\nexport const nextSibling: {\n /**\n * Returns a function that joins its argument to `that` with the\n * next-sibling combinator.\n *\n * @param that - The right (following sibling) side.\n * @returns A function that takes a selector and returns the complex selector `self + that`.\n * @since 0.4.0\n */\n <B extends Requirement>(\n that: Selector<B>,\n ): <A extends Requirement>(self: Selector<A>) => Selector<A | B>\n /**\n * Joins two selectors with the next-sibling combinator, rendered\n * `self + that`: the right side matches the element immediately\n * following a left-side match. Composition rules are `descendant`'s.\n *\n * @param self - The left side. Must not end in a compound containing a pseudo-element.\n * @param that - The right (following sibling) side.\n * @returns The complex selector `self + that`, carrying both sides' requirements.\n * @throws `Error` when `self` ends in a compound containing a pseudo-element — no combinator may follow one.\n * @since 0.4.0\n */\n <A extends Requirement, B extends Requirement>(\n self: Selector<A>,\n that: Selector<B>,\n ): Selector<A | B>\n} = internal.nextSibling\n\nexport const subsequentSibling: {\n /**\n * Returns a function that joins its argument to `that` with the\n * subsequent-sibling combinator.\n *\n * @param that - The right (later sibling) side.\n * @returns A function that takes a selector and returns the complex selector `self ~ that`.\n * @since 0.4.0\n */\n <B extends Requirement>(\n that: Selector<B>,\n ): <A extends Requirement>(self: Selector<A>) => Selector<A | B>\n /**\n * Joins two selectors with the subsequent-sibling combinator, rendered\n * `self ~ that`: the right side matches any later sibling of a\n * left-side match. Composition rules are `descendant`'s.\n *\n * @param self - The left side. Must not end in a compound containing a pseudo-element.\n * @param that - The right (later sibling) side.\n * @returns The complex selector `self ~ that`, carrying both sides' requirements.\n * @throws `Error` when `self` ends in a compound containing a pseudo-element — no combinator may follow one.\n * @since 0.4.0\n */\n <A extends Requirement, B extends Requirement>(\n self: Selector<A>,\n that: Selector<B>,\n ): Selector<A | B>\n} = internal.subsequentSibling\n\nexport const under: {\n /**\n * Returns a function that resolves its argument against `parent`.\n *\n * @param parent - The parent selector to substitute for `&`.\n * @returns A function that takes a nested selector and returns it resolved against `parent`.\n * @since 0.4.0\n */\n <P extends Requirement>(\n parent: Selector<P>,\n ): <C extends Requirement>(child: Selector<C>) => Selector<Exclude<C, Parent> | P>\n /**\n * Resolves a nested selector against its parent: every `&` in `child`,\n * including inside `is`/`where`/`has`/`not` argument lists, is\n * replaced by `parent`, discharging the `Parent` requirement.\n *\n * A compound parent merges in place (`&.active` under `.btn` is\n * `.btn.active`); a complex parent substitutes as `:is(parent)`, which\n * matches and scores identically. The result's specificity is\n * therefore the spec's — `&` counts as the parent selector. A child\n * without `&` returns unchanged. Chained nesting resolves innermost\n * binder first: resolve the grandchild against its parent, then the\n * result against the grandparent.\n *\n * @param child - The nested selector to resolve.\n * @param parent - The parent selector to substitute for `&`. May itself reference `&`; the result then still carries `Parent`.\n * @returns The resolved selector, carrying `child`'s requirements minus `Parent`, plus `parent`'s.\n * @throws `Error` when a substitution produces an invalid compound — merging a typed parent into a compound that already has a type selector, say.\n * @example\n * ```ts\n * const nested = Selector.is(Selector.nest, Selector.descendant(Selector.nest, Selector.universal))\n * Selector.render(Selector.under(nested, Selector.class('red')))\n * // ':is(.red, .red *)'\n * ```\n * @since 0.4.0\n */\n <C extends Requirement, P extends Requirement>(\n child: Selector<C>,\n parent: Selector<P>,\n ): Selector<Exclude<C, Parent> | P>\n} = internal.under\n\n/**\n * Computes the selector's specificity: ids into `a`; classes,\n * attributes, and pseudo-classes into `b`; types and pseudo-elements\n * into `c`. Compounds in a complex selector sum. `:is()`, `:has()`, and\n * `:not()` add their most specific argument; `:where()` and the\n * universal selector add nothing; duplicate parts count each time.\n *\n * Closed selectors only: an `&`-bearing selector takes its specificity\n * from the parent rule, so the parameter rejects `Parent`-requiring\n * selectors at compile time — resolve them with `under` first.\n *\n * This is what lets a consumer turn \"these rules tie, so their order\n * encodes the override direction\" into something checkable.\n *\n * @param selector - The selector to measure. Must be closed (no `&`).\n * @returns The computed `Specificity`.\n * @since 0.1.0\n */\nexport const specificity: (selector: Selector) => Specificity = internal.specificity\n\n/**\n * Renders the selector as CSS text: each compound's parts concatenated\n * in canonical order — type first, then `&`, ids, classes,\n * pseudo-classes, attributes, functional pseudo-classes, and the\n * pseudo-element last, alphabetically within each kind — and compounds\n * joined by their combinators in authored order. Any fixed part order\n * matches identically; this one keeps root-scoped shapes in their\n * conventional spelling.\n *\n * @param selector - The selector to render.\n * @returns Deterministic CSS text.\n * @example\n * ```ts\n * Selector.render(Selector.and(Selector.pseudoClass('hover'), Selector.class('btn')))\n * // '.btn:hover'\n * ```\n * @since 0.1.0\n */\nexport const render: (selector: Selector<Requirement>) => string = internal.render\n\nexport const equals: {\n /**\n * Returns a function that checks structural equality against `that`.\n *\n * @param that - The selector to compare against.\n * @returns A function testing its argument for structural equality with `that`.\n * @since 0.1.0\n */\n (that: Selector<Requirement>): (self: Selector<Requirement>) => boolean\n /**\n * Structural equality over canonically ordered parts: two selectors\n * built from the same parts compare equal regardless of construction\n * order. Combinator sequences compare in order — `a b` and `b a` are\n * different selectors.\n *\n * @param self - The first selector.\n * @param that - The second selector.\n * @returns `true` if the selectors are structurally equal.\n * @since 0.1.0\n */\n (self: Selector<Requirement>, that: Selector<Requirement>): boolean\n} = internal.equals\n","import type { Pipeable } from '#util'\nimport type { SpecificityTypeId } from './specificity.internal.ts'\nimport * as internal from './specificity.internal.ts'\n\n/**\n * A selector specificity: the `(a, b, c)` triple the cascade compares\n * lexicographically — id count, then class/attribute/pseudo-class count,\n * then type/pseudo-element count.\n *\n * Computed from selectors via `Selector.specificity`; construct directly\n * with `make` when asserting expectations.\n *\n * @since 0.1.0\n */\nexport interface Specificity extends Pipeable {\n readonly [SpecificityTypeId]: SpecificityTypeId\n /**\n * The id-selector count.\n */\n readonly a: number\n /**\n * The class, attribute, and pseudo-class count.\n */\n readonly b: number\n /**\n * The type and pseudo-element count.\n */\n readonly c: number\n}\n\n/**\n * Checks if a value is a `Specificity`.\n *\n * True only for values built by this module's constructors, which carry\n * the brand.\n *\n * @param u - The value to check.\n * @returns `true` if the value is a `Specificity`, `false` otherwise.\n * @since 0.1.0\n */\nexport const isSpecificity: (u: unknown) => u is Specificity = internal.isSpecificity\n\n/**\n * Creates a `Specificity` from its three components.\n *\n * @param a - The id-selector count. Must be a non-negative integer.\n * @param b - The class/attribute/pseudo-class count. Must be a non-negative integer.\n * @param c - The type/pseudo-element count. Must be a non-negative integer.\n * @returns A new `Specificity`.\n * @throws `Error` when any component is not a non-negative integer.\n * @since 0.1.0\n */\nexport const make: (a: number, b: number, c: number) => Specificity = internal.make\n\nexport const compare: {\n /**\n * Returns a function that compares its argument against `that`.\n *\n * @param that - The specificity to compare against.\n * @returns A function returning the cascade ordering of its argument relative to `that`.\n * @since 0.1.0\n */\n (that: Specificity): (self: Specificity) => -1 | 0 | 1\n /**\n * Compares two specificities the way the cascade does: lexicographically\n * by `a`, then `b`, then `c`.\n *\n * @param self - The first specificity.\n * @param that - The second specificity.\n * @returns `-1` if `self` is less specific, `1` if more, `0` if equal.\n * @example\n * ```ts\n * Specificity.compare(Specificity.make(1, 0, 0), Specificity.make(0, 9, 9)) // 1\n * ```\n * @since 0.1.0\n */\n (self: Specificity, that: Specificity): -1 | 0 | 1\n} = internal.compare\n\nexport const equals: {\n /**\n * Returns a function that checks equality against `that`.\n *\n * @param that - The specificity to compare against.\n * @returns A function testing its argument for equality with `that`.\n * @since 0.1.0\n */\n (that: Specificity): (self: Specificity) => boolean\n /**\n * Component-wise equality of two specificities.\n *\n * @param self - The first specificity.\n * @param that - The second specificity.\n * @returns `true` if all three components match.\n * @since 0.1.0\n */\n (self: Specificity, that: Specificity): boolean\n} = internal.equals\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4FA,MAAa,aAAyDA;;;;;;AAOtE,MAAa,YAAsBC;;;;;;;;;;;;;;;;;AAkBnC,MAAa,OAAyBC;;;;;;;;;;;;AAatC,MAAa,OAAmCC;;;;;;;;;AAUhD,MAAa,KAAiCC;;;;;;;;;;;AAY9C,MAAM,SAAqCC;;;;;;;;;;;;AAc3C,MAAa,cAA0CC;AAEvD,MAAa,YAyCTC;;;;;;;;;;;;;;;;;;;;;AAsBJ,MAAa,KAEmCC;;;;;;;;;;;;;AAchD,MAAa,QAEmCC;;;;;;;;;;;;;;;;AAiBhD,MAAa,MAEmCC;;;;;;;;;;;;;;;AAgBhD,MAAa,MAEmCC;;;;;;;;;;;;;AAchD,MAAa,gBAA4CC;;;;;;;AAQzD,MAAa,OAAiBC;AAE9B,MAAa,MAsCTC;AAEJ,MAAa,aAoCTC;AAEJ,MAAa,QA2BTC;AAEJ,MAAa,cA2BTC;AAEJ,MAAa,oBA2BTC;AAEJ,MAAa,QAwCTC;;;;;;;;;;;;;;;;;;;AAoBJ,MAAa,cAAmDC;;;;;;;;;;;;;;;;;;;AAoBhE,MAAa,SAAsDC;AAEnE,MAAaC,WAqBTC;;;;;;;;;;;;;;;;;;;AC1hBJ,MAAa,gBAAkDC;;;;;;;;;;;AAY/D,MAAa,OAAyDC;AAEtE,MAAa,UAuBTC;AAEJ,MAAa,SAkBTC"}
|