fashionable 0.0.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +276 -0
  3. package/dist/calc/index.d.mts +2 -0
  4. package/dist/calc/index.mjs +2 -0
  5. package/dist/data/index.d.mts +208 -0
  6. package/dist/data/index.mjs +696 -0
  7. package/dist/data/index.mjs.map +1 -0
  8. package/dist/declaration/index.d.mts +2 -0
  9. package/dist/declaration/index.mjs +74 -0
  10. package/dist/declaration/index.mjs.map +1 -0
  11. package/dist/fontFace/index.d.mts +2 -0
  12. package/dist/fontFace/index.mjs +102 -0
  13. package/dist/fontFace/index.mjs.map +1 -0
  14. package/dist/property/index.d.mts +2 -0
  15. package/dist/property/index.mjs +293 -0
  16. package/dist/property/index.mjs.map +1 -0
  17. package/dist/query/index.d.mts +2 -0
  18. package/dist/query/index.mjs +62 -0
  19. package/dist/query/index.mjs.map +1 -0
  20. package/dist/rule/index.d.mts +2 -0
  21. package/dist/rule/index.mjs +234 -0
  22. package/dist/rule/index.mjs.map +1 -0
  23. package/dist/selector/index.d.mts +2 -0
  24. package/dist/selector/index.mjs +178 -0
  25. package/dist/selector/index.mjs.map +1 -0
  26. package/dist/shared/calc-Cih4o2r7.mjs +1145 -0
  27. package/dist/shared/calc-Cih4o2r7.mjs.map +1 -0
  28. package/dist/shared/color-BvNJ2YqL.d.mts +590 -0
  29. package/dist/shared/color.internal-Dts5ycTm.mjs +450 -0
  30. package/dist/shared/color.internal-Dts5ycTm.mjs.map +1 -0
  31. package/dist/shared/declaration-1DlO_ltT.d.mts +166 -0
  32. package/dist/shared/declaration.internal-wLB4ssxC.mjs +73 -0
  33. package/dist/shared/declaration.internal-wLB4ssxC.mjs.map +1 -0
  34. package/dist/shared/equal-U9G5LhtL.mjs +71 -0
  35. package/dist/shared/equal-U9G5LhtL.mjs.map +1 -0
  36. package/dist/shared/fontFaceRule-C7nYgH6X.d.mts +294 -0
  37. package/dist/shared/fontFaceRule.internal-D5u48TUO.mjs +214 -0
  38. package/dist/shared/fontFaceRule.internal-D5u48TUO.mjs.map +1 -0
  39. package/dist/shared/format-B9jsmCER.mjs +53 -0
  40. package/dist/shared/format-B9jsmCER.mjs.map +1 -0
  41. package/dist/shared/index-BvtwY4FQ.d.mts +841 -0
  42. package/dist/shared/mediaQuery-BYR1z-iD.d.mts +145 -0
  43. package/dist/shared/mediaQuery.internal-B6iuMd75.mjs +100 -0
  44. package/dist/shared/mediaQuery.internal-B6iuMd75.mjs.map +1 -0
  45. package/dist/shared/mediaRule-BDB4WCYy.d.mts +558 -0
  46. package/dist/shared/precision.internal-0lv1nEpF.mjs +40 -0
  47. package/dist/shared/precision.internal-0lv1nEpF.mjs.map +1 -0
  48. package/dist/shared/propertyRule-BbkFh9b9.d.mts +466 -0
  49. package/dist/shared/propertyRule.internal-Bc_HrfcL.mjs +246 -0
  50. package/dist/shared/propertyRule.internal-Bc_HrfcL.mjs.map +1 -0
  51. package/dist/shared/render-BqcFH9Vr.mjs +9 -0
  52. package/dist/shared/render-BqcFH9Vr.mjs.map +1 -0
  53. package/dist/shared/rolldown-runtime-D7D4PA-g.mjs +13 -0
  54. package/dist/shared/ruleSet.internal-DodzVMUU.mjs +218 -0
  55. package/dist/shared/ruleSet.internal-DodzVMUU.mjs.map +1 -0
  56. package/dist/shared/selector-HZY-W6l6.d.mts +346 -0
  57. package/dist/shared/selector.internal-ESe9s0IH.mjs +290 -0
  58. package/dist/shared/selector.internal-ESe9s0IH.mjs.map +1 -0
  59. package/dist/shared/utils-BKm298I-.d.mts +179 -0
  60. package/dist/stylesheet/index.d.mts +316 -0
  61. package/dist/stylesheet/index.mjs +296 -0
  62. package/dist/stylesheet/index.mjs.map +1 -0
  63. package/dist/utils.d.mts +2 -0
  64. package/dist/utils.mjs +131 -0
  65. package/dist/utils.mjs.map +1 -0
  66. package/package.json +96 -8
  67. package/index.js +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":["internal.isPropertyRule","internal.make","internal.inheritable","render","internal.render","equals","internal.equals","internal.isPropertySyntax","internal.universal","internal.angle","internal.color","internal.customIdent","internal.image","internal.integer","internal.length","internal.lengthPercentage","internal.number","internal.percentage","internal.resolution","internal.string","internal.time","internal.transformFunction","internal.transformList","internal.url","internal.keyword","internal.keywords","internal.oneOf","internal.listOf","internal.commaListOf","internal.render","internal.equals"],"sources":["../../src/property/propertyRule.ts","../../src/property/propertySyntax.ts"],"sourcesContent":["import type { Calc, Kind } from '#calc/calc'\nimport type { Color } from '#data/color'\nimport type { RenderOptions as DeclarationRenderOptions } from '#declaration/declaration'\nimport type { Pipeable } from '#util'\nimport type { PropertyRuleTypeId } from './propertyRule.internal.ts'\nimport * as internal from './propertyRule.internal.ts'\nimport type { PropertySyntax, Universal } from './propertySyntax.ts'\n\n/**\n * An `@property` rule: the registration that gives a custom property a\n * syntax, an inheritance behavior, and an initial value.\n *\n * A declaration-block at-rule lives at the top level of a stylesheet —\n * it is deliberately not a rule-block member, so it cannot nest.\n *\n * The registration is what turns a custom property into a typed,\n * animatable channel; a computed-property chain pairs one of these with\n * a `Declaration` writing the property and `Calc.ref` reads downstream.\n *\n * Construct via `make`.\n *\n * @since 0.1.0\n */\nexport interface PropertyRule extends Pipeable {\n readonly [PropertyRuleTypeId]: PropertyRuleTypeId\n /**\n * The registered custom property name, `--` prefix included.\n */\n readonly name: `--${string}`\n /**\n * The modeled `syntax` descriptor; `render` emits it single-quoted.\n */\n readonly syntax: PropertySyntax\n /**\n * The `inherits` descriptor. `make` registers `false`; `inheritable`\n * flips it.\n */\n readonly inherits: boolean\n /**\n * The `initial-value` descriptor: literal text or a closed expression.\n * Absent only under the universal syntax.\n */\n readonly initialValue: Value | undefined\n}\n\n/**\n * The value forms an `initial-value` descriptor can hold once\n * constructed. The closed (`never`-ref) parameter is the spec rule in the\n * types: `@property` initial values must be computationally independent, so\n * only closed expressions — no unbound references — are accepted. A `Calc`\n * of any dimension is admitted here; `make` narrows to the forms the declared\n * syntax accepts (the syntax's `V` parameter), where a `<length>` is limited\n * to absolute units.\n *\n * @since 0.1.0\n */\nexport type Value = string | Calc<never, Kind, unknown> | Color<never>\n\n/**\n * Options for `render`, in the render-options family rooted at\n * `MediaQuery.RenderOptions` (via `Declaration.RenderOptions`). This\n * renderer consumes `indent` and the inherited `precision` (for an\n * expression-valued `initial-value`); `mediaSyntax` is accepted and\n * ignored.\n *\n * @since 0.1.0\n */\nexport interface RenderOptions extends DeclarationRenderOptions {\n /**\n * The indentation unit for the block's declarations. Defaults to a tab.\n */\n readonly indent?: string\n}\n\n/**\n * Checks if a value is a `PropertyRule`.\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 `PropertyRule`, `false` otherwise.\n * @since 0.1.0\n */\nexport const isPropertyRule: (u: unknown) => u is PropertyRule = internal.isPropertyRule\n\nexport const make: {\n /**\n * Registers under the universal syntax — the default when `syntax` is\n * omitted — where the initial value is optional.\n *\n * @param name - The custom property name to register, `--` prefix included.\n * @param syntax - The universal syntax; omit for the same effect.\n * @param initialValue - Optional under the universal syntax: any value form.\n * @returns A `PropertyRule` with `inherits: false`.\n * @throws `Error` when `name` is not a `--`-prefixed custom property name (bare `--` included), or an expression value has unbound references.\n * @since 0.1.0\n */\n (name: `--${string}`, syntax?: Universal, initialValue?: Value | number): PropertyRule\n /**\n * Creates an `@property` rule.\n *\n * The syntax value types the initial value: only forms the syntax\n * accepts are admitted — numbers and closed `Calc` expressions under\n * `PropertySyntax.number`, exactly the declared literals under a\n * keyword set, and so on — and the computational-independence rule\n * rides along, since an expression with unbound references is not a\n * `Calc<never>` (backed by a runtime check for untyped callers). Bare\n * numbers coerce to unannotated constants. That literal-text values\n * parse under the syntax is not checked — this library does not parse\n * CSS.\n *\n * Rules register with `inherits: false`; pipe through `inheritable` to\n * opt in.\n *\n * @param name - The custom property name to register, `--` prefix included.\n * @param syntax - The modeled `syntax` descriptor; see `PropertySyntax`.\n * @param initialValue - The `initial-value` descriptor, required for every non-universal syntax and typed by it.\n * @returns A `PropertyRule` with `inherits: false`.\n * @throws `Error` when `name` is not a `--`-prefixed custom property name (bare `--` included), `initialValue` is missing under a non-universal syntax, or an expression value has unbound references.\n * @example\n * ```ts\n * PropertyRule.make('--depth', PropertySyntax.number, 0)\n * ```\n * @since 0.1.0\n */\n <V extends Value | number>(\n name: `--${string}`,\n syntax: PropertySyntax<V>,\n initialValue: NoInfer<V>,\n ): PropertyRule\n} = internal.make\n\n/**\n * Registers the rule as inheriting. `make` constructs every rule with\n * `inherits: false` — the safe default for computed channels, where\n * inheritance would leak intermediate values down the tree — so\n * inheritance is an explicit opt-in.\n *\n * @param rule - The rule to opt in.\n * @returns The inheriting rule; the same rule when it already inherits.\n * @example\n * ```ts\n * PropertyRule.make('--fill', PropertySyntax.color, 'red').pipe(PropertyRule.inheritable)\n * ```\n * @since 0.1.0\n */\nexport const inheritable: (rule: PropertyRule) => PropertyRule = internal.inheritable\n\n/**\n * Renders the rule as a complete `@property --name { ... }` block, the\n * descriptors in fixed order: `syntax`, `inherits`, `initial-value`.\n *\n * @param rule - The rule to render.\n * @param options - Optional indentation unit and precision context.\n * @returns Deterministic CSS text.\n * @example\n * ```ts\n * PropertyRule.render(PropertyRule.make('--depth', PropertySyntax.number, 0))\n * // \"@property --depth {\\n\\tsyntax: '<number>';\\n\\tinherits: false;\\n\\tinitial-value: 0;\\n}\"\n * ```\n * @since 0.1.0\n */\nexport const render: (rule: PropertyRule, options?: RenderOptions) => string = internal.render\n\nexport const equals: {\n /**\n * Returns a function that checks structural equality against `that`.\n *\n * @param that - The rule to compare against.\n * @returns A function testing its argument for structural equality with `that`.\n * @since 0.1.0\n */\n (that: PropertyRule): (self: PropertyRule) => boolean\n /**\n * Structural equality: `name` and `inherits` compare as data, the\n * syntax as its modeled grammar (`PropertySyntax.equals` semantics),\n * and expression initial values as expression trees (`Calc.equals`\n * semantics). Literal text never equals an expression.\n *\n * @param self - The first rule.\n * @param that - The second rule.\n * @returns `true` if the rules are structurally equal.\n * @since 0.1.0\n */\n (self: PropertyRule, that: PropertyRule): boolean\n} = internal.equals\n","import type { Calc, Kind } from '#calc/calc'\nimport type { Color } from '#data/color'\nimport type { AbsoluteLength, Angle, Percentage } from '#data/units'\nimport type { Pipeable } from '#util'\nimport type { PropertySyntaxTypeId } from './propertySyntax.internal.ts'\nimport * as internal from './propertySyntax.internal.ts'\n\ndeclare const AcceptedValue: unique symbol\ndeclare const UniversalMarker: unique symbol\n\n/**\n * A modeled `@property` syntax descriptor: the universal syntax, a data\n * type, a keyword, a multiplied list, or a `|` combination of these.\n *\n * The point of modeling the descriptor as a value is twofold. The\n * supported grammar becomes discoverable — the data types are constants\n * (`number`, `color`, `lengthPercentage`, ...), and the combinators\n * (`keyword`, `oneOf`, `listOf`, `commaListOf`) enforce the grammar's\n * constraints at construction. And the `V` parameter tracks the\n * initial-value forms the syntax accepts, so `PropertyRule.make` can\n * type its `initialValue` from the syntax it is registered under.\n *\n * Construct via the data type constants, `universal`, `keyword`,\n * `keywords`, `oneOf`, `listOf`, and `commaListOf`.\n *\n * @since 0.1.0\n */\nexport interface PropertySyntax<out V = Value> extends Pipeable {\n readonly [PropertySyntaxTypeId]: PropertySyntaxTypeId\n readonly [AcceptedValue]?: V\n}\n\n/**\n * The full initial-value domain — what the universal syntax accepts.\n * Individual syntaxes narrow this: number-land syntaxes take numbers and\n * closed `Calc` expressions, dimensioned syntaxes take a closed `Calc` of\n * their kind (a `<length>` initial value must be computationally independent,\n * so only absolute units), `color` takes closed `Color` expressions or text,\n * keyword sets take exactly their literals, and the rest take literal text.\n *\n * @since 0.1.0\n */\nexport type Value = string | number | Calc<never, Kind, unknown> | Color<never>\n\n/**\n * The initial-value forms a syntax accepts — the type-level counterpart\n * of the `V` parameter, extracted from a syntax (or union of syntaxes).\n *\n * @since 0.1.0\n */\nexport type ValueOf<S extends PropertySyntax<unknown>> =\n S extends PropertySyntax<infer V> ? V : never\n\n/**\n * Checks if a value is a `PropertySyntax`.\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 `PropertySyntax`, `false` otherwise.\n * @since 0.1.0\n */\nexport const isPropertySyntax: (u: unknown) => u is PropertySyntax = internal.isPropertySyntax\n\n/**\n * The type of `universal` alone. Naming it lets `PropertyRule.make`\n * recognize the universal syntax in overload resolution — the one syntax\n * under which the initial value is optional.\n *\n * @since 0.1.0\n */\nexport interface Universal extends PropertySyntax<Value> {\n readonly [UniversalMarker]: true\n}\n\n/**\n * The universal syntax, `*` — any value at all. The one syntax under\n * which `@property` may omit its initial value.\n *\n * @since 0.1.0\n */\nexport const universal: Universal = internal.universal\n\n/**\n * The `<angle>` data type. Initial values are a closed angle-kind `Calc`\n * (`Angle.rad(...)`) or literal text carrying an angle unit (`'90deg'`).\n *\n * @since 0.1.0\n */\nexport const angle: PropertySyntax<string | Calc<never, 'angle', Angle>> = internal.angle\n\n/**\n * The `<color>` data type. Initial values are closed `Color` expressions\n * or literal text (`'transparent'`, `'#fff'`).\n *\n * @since 0.1.0\n */\nexport const color: PropertySyntax<string | Color<never>> = internal.color\n\n/**\n * The `<custom-ident>` data type — any custom identifier. To accept a\n * fixed set of identifiers instead, combine `keyword` values with\n * `oneOf`.\n *\n * @since 0.1.0\n */\nexport const customIdent: PropertySyntax<string> = internal.customIdent\n\n/**\n * The `<image>` data type. Initial values are literal text.\n *\n * @since 0.1.0\n */\nexport const image: PropertySyntax<string> = internal.image\n\n/**\n * The `<integer>` data type. Initial values are numbers or closed `Calc`\n * expressions; that the value is a whole number is the browser's parse\n * check, not this library's.\n *\n * @since 0.1.0\n */\nexport const integer: PropertySyntax<number | Calc<never>> = internal.integer\n\n/**\n * The `<length>` data type. Initial values are a closed length-kind `Calc`\n * (`Length.px(8)`) or literal text carrying a length unit (`'8px'` — a bare\n * `0` is not a valid registered length). An `@property` initial value must be\n * computationally independent, so an expression may carry only absolute units\n * (`px`) — a viewport- or font-relative length (`Length.vw(8)`) is rejected.\n *\n * @since 0.1.0\n */\nexport const length: PropertySyntax<string | Calc<never, 'length', AbsoluteLength>> =\n internal.length\n\n/**\n * The `<length-percentage>` data type. Initial values are a closed\n * absolute-length or percentage `Calc`, or literal text.\n *\n * @since 0.1.0\n */\nexport const lengthPercentage: PropertySyntax<\n string | Calc<never, 'length', AbsoluteLength> | Calc<never, 'percentage', Percentage>\n> = internal.lengthPercentage\n\n/**\n * The `<number>` data type. Initial values are numbers or closed `Calc`\n * expressions — the typed channel this library models; text is not\n * accepted where the number form exists.\n *\n * @since 0.1.0\n */\nexport const number: PropertySyntax<number | Calc<never>> = internal.number\n\n/**\n * The `<percentage>` data type. Initial values are a closed percentage-kind\n * `Calc` (`Percentage.of(50)`) or literal text carrying the `%` unit (`'50%'`).\n *\n * @since 0.1.0\n */\nexport const percentage: PropertySyntax<string | Calc<never, 'percentage', Percentage>> =\n internal.percentage\n\n/**\n * The `<resolution>` data type. Initial values are literal text.\n *\n * @since 0.1.0\n */\nexport const resolution: PropertySyntax<string> = internal.resolution\n\n/**\n * The `<string>` data type. Initial values are literal text including\n * their own quotes (`'\"hello\"'`).\n *\n * @since 0.1.0\n */\nexport const string: PropertySyntax<string> = internal.string\n\n/**\n * The `<time>` data type. Initial values are literal text carrying a\n * time unit (`'200ms'`).\n *\n * @since 0.1.0\n */\nexport const time: PropertySyntax<string> = internal.time\n\n/**\n * The `<transform-function>` data type. Initial values are literal text.\n *\n * @since 0.1.0\n */\nexport const transformFunction: PropertySyntax<string> = internal.transformFunction\n\n/**\n * The `<transform-list>` data type — a list of transform functions. It\n * is pre-multiplied, so `listOf`/`commaListOf` reject it. Initial values\n * are literal text.\n *\n * @since 0.1.0\n */\nexport const transformList: PropertySyntax<string> = internal.transformList\n\n/**\n * The `<url>` data type. Initial values are literal text.\n *\n * @since 0.1.0\n */\nexport const url: PropertySyntax<string> = internal.url\n\n/**\n * A keyword component: one specific custom identifier, rendered bare.\n * Combined under `oneOf`, keywords give the registered property an\n * enum-like domain — and the `V` parameter carries the literal, so\n * `initialValue` autocompletes and checks against exactly the declared\n * set.\n *\n * @param name - The identifier. Must be non-empty and not a CSS-wide keyword (`inherit`, `initial`, `unset`, `revert`, `revert-layer`, `default`), which the specification excludes.\n * @returns A `PropertySyntax` accepting exactly `name`.\n * @throws `Error` when `name` is empty or a CSS-wide keyword.\n * @since 0.1.0\n */\nexport const keyword: <const K extends string>(name: K) => PropertySyntax<K> = internal.keyword\n\n/**\n * A keyword set: shorthand for `oneOf` over `keyword` values, accepting\n * — and narrowing `initialValue` to — exactly the given identifiers. A\n * single name is just that `keyword`.\n *\n * @param names - One or more identifiers, each under `keyword`'s constraints.\n * @returns A `PropertySyntax` accepting exactly the given names.\n * @throws `Error` when a name is empty or a CSS-wide keyword.\n * @example\n * ```ts\n * const size = PropertySyntax.keywords('small', 'medium', 'large')\n * PropertySyntax.render(size) // 'small | medium | large'\n * PropertyRule.make('--size', size, 'medium') // initialValue checks against the three names\n * ```\n * @since 0.1.0\n */\nexport const keywords: <const Names extends readonly [string, ...ReadonlyArray<string>]>(\n ...names: Names\n) => PropertySyntax<Names[number]> = internal.keywords\n\n/**\n * A `|` combination: the value may satisfy any one of the components,\n * tried in order — authored order is preserved (it is parse order, so\n * `'<length> | auto'` and `'auto | <length>'` are different syntaxes).\n * Nested combinations flatten into the enclosing one.\n *\n * @param components - Two or more components. The universal syntax stands alone and may not join a combination.\n * @returns A `PropertySyntax` accepting any component's values, unioned in `V`.\n * @throws `Error` when a component is the universal syntax.\n * @example\n * ```ts\n * const size = PropertySyntax.oneOf(PropertySyntax.keyword('small'), PropertySyntax.keyword('large'))\n * PropertySyntax.render(size) // 'small | large'\n * PropertyRule.make('--size', size, 'small') // initialValue is 'small' | 'large' only\n * ```\n * @since 0.1.0\n */\nexport const oneOf: <\n const Components extends readonly [\n PropertySyntax<unknown>,\n PropertySyntax<unknown>,\n ...ReadonlyArray<PropertySyntax<unknown>>,\n ],\n>(\n ...components: Components\n) => PropertySyntax<ValueOf<Components[number]>> = internal.oneOf\n\n/**\n * A space-separated list of one component, rendered with the `+`\n * multiplier (`'<length>+'`).\n *\n * A one-item list is valid, so the component's own value forms stay\n * accepted; longer lists are literal text.\n *\n * @param component - The repeated component. Must be a single unmultiplied component — not the universal syntax, a combination, a list, or the pre-multiplied `transformList`.\n * @returns A `PropertySyntax` accepting the component's values or list text.\n * @throws `Error` when the component cannot take a multiplier.\n * @since 0.1.0\n */\nexport const listOf: <V>(component: PropertySyntax<V>) => PropertySyntax<V | (string & {})> =\n internal.listOf\n\n/**\n * A comma-separated list of one component, rendered with the `#`\n * multiplier (`'<color>#'`). Constraints match `listOf`.\n *\n * @param component - The repeated component. Must be a single unmultiplied component — not the universal syntax, a combination, a list, or the pre-multiplied `transformList`.\n * @returns A `PropertySyntax` accepting the component's values or list text.\n * @throws `Error` when the component cannot take a multiplier.\n * @since 0.1.0\n */\nexport const commaListOf: <V>(component: PropertySyntax<V>) => PropertySyntax<V | (string & {})> =\n internal.commaListOf\n\n/**\n * Renders the syntax as its descriptor string, unquoted: `'*'`,\n * `'<number>'`, `'<length>+'`, `'small | large'`. `PropertyRule.render`\n * wraps this in the quotes the descriptor requires.\n *\n * @param syntax - The syntax to render.\n * @returns Deterministic descriptor text.\n * @since 0.1.0\n */\nexport const render: (syntax: PropertySyntax) => string = internal.render\n\nexport const equals: {\n /**\n * Returns a function that checks structural equality against `that`.\n *\n * @param that - The syntax to compare against.\n * @returns A function testing its argument for structural equality with `that`.\n * @since 0.1.0\n */\n (that: PropertySyntax): (self: PropertySyntax) => boolean\n /**\n * Structural equality over the modeled grammar. Combination order\n * participates — it is parse order.\n *\n * @param self - The first syntax.\n * @param that - The second syntax.\n * @returns `true` if the syntaxes are structurally equal.\n * @since 0.1.0\n */\n (self: PropertySyntax, that: PropertySyntax): boolean\n} = internal.equals\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAoFA,MAAa,iBAAoDA;AAEjE,MAAa,OA6CTC;;;;;;;;;;;;;;;AAgBJ,MAAa,cAAoDC;;;;;;;;;;;;;;;AAgBjE,MAAaC,WAAkEC;AAE/E,MAAaC,WAqBTC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC3HJ,MAAa,mBAAwDC;;;;;;;AAmBrE,MAAa,YAAuBC;;;;;;;AAQpC,MAAa,QAA8DC;;;;;;;AAQ3E,MAAa,QAA+CC;;;;;;;;AAS5D,MAAa,cAAsCC;;;;;;AAOnD,MAAa,QAAgCC;;;;;;;;AAS7C,MAAa,UAAgDC;;;;;;;;;;AAW7D,MAAa,SACXC;;;;;;;AAQF,MAAa,mBAETC;;;;;;;;AASJ,MAAa,SAA+CC;;;;;;;AAQ5D,MAAa,aACXC;;;;;;AAOF,MAAa,aAAqCC;;;;;;;AAQlD,MAAa,SAAiCC;;;;;;;AAQ9C,MAAa,OAA+BC;;;;;;AAO5C,MAAa,oBAA4CC;;;;;;;;AASzD,MAAa,gBAAwCC;;;;;;AAOrD,MAAa,MAA8BC;;;;;;;;;;;;;AAc3C,MAAa,UAAkEC;;;;;;;;;;;;;;;;;AAkB/E,MAAa,WAEwBC;;;;;;;;;;;;;;;;;;AAmBrC,MAAa,QAQsCC;;;;;;;;;;;;;AAcnD,MAAa,SACXC;;;;;;;;;;AAWF,MAAa,cACXC;;;;;;;;;;AAWF,MAAa,SAA6CC;AAE1D,MAAa,SAmBTC"}
@@ -0,0 +1,2 @@
1
+ import { r as mediaQuery_d_exports } from "../shared/mediaQuery-BYR1z-iD.mjs";
2
+ export { mediaQuery_d_exports as MediaQuery };
@@ -0,0 +1,62 @@
1
+ import { t as __exportAll } from "../shared/rolldown-runtime-D7D4PA-g.mjs";
2
+ import { a as prefersColorScheme$1, i as minWidth$1, n as equals$1, o as render$1, r as isMediaQuery$1, t as and$1 } from "../shared/mediaQuery.internal-B6iuMd75.mjs";
3
+ //#region src/query/mediaQuery.ts
4
+ var mediaQuery_exports = /* @__PURE__ */ __exportAll({
5
+ and: () => and,
6
+ equals: () => equals,
7
+ isMediaQuery: () => isMediaQuery,
8
+ minWidth: () => minWidth,
9
+ prefersColorScheme: () => prefersColorScheme,
10
+ render: () => render
11
+ });
12
+ /**
13
+ * Checks if a value is a `MediaQuery`.
14
+ *
15
+ * True only for values built by this module's constructors, which carry
16
+ * the brand.
17
+ *
18
+ * @param u - The value to check.
19
+ * @returns `true` if the value is a `MediaQuery`, `false` otherwise.
20
+ * @since 0.1.0
21
+ */
22
+ const isMediaQuery = isMediaQuery$1;
23
+ /**
24
+ * Creates a viewport-width lower bound.
25
+ *
26
+ * @param px - The threshold in CSS pixels. Must be a non-negative finite number.
27
+ * @returns A one-feature `MediaQuery`.
28
+ * @throws `Error` when `px` is negative or not finite.
29
+ * @example
30
+ * ```ts
31
+ * MediaQuery.render(MediaQuery.minWidth(768)) // '(min-width: 768px)'
32
+ * MediaQuery.render(MediaQuery.minWidth(768), { mediaSyntax: 'range' }) // '(width >= 768px)'
33
+ * ```
34
+ * @since 0.1.0
35
+ */
36
+ const minWidth = minWidth$1;
37
+ /**
38
+ * Creates a `prefers-color-scheme` condition.
39
+ *
40
+ * @param scheme - The scheme to match, `'dark'` or `'light'`.
41
+ * @returns A one-feature `MediaQuery`.
42
+ * @since 0.1.0
43
+ */
44
+ const prefersColorScheme = prefersColorScheme$1;
45
+ const and = and$1;
46
+ /**
47
+ * Renders the query as CSS text: features in canonical order —
48
+ * `min-width` ascending, then `prefers-color-scheme` — joined with
49
+ * ` and `. The `mediaSyntax` option picks the width-feature spelling
50
+ * (default `'prefix'`).
51
+ *
52
+ * @param query - The query to render.
53
+ * @param options - Optional syntax selection.
54
+ * @returns Deterministic CSS text, without the `@media ` prefix.
55
+ * @since 0.1.0
56
+ */
57
+ const render = render$1;
58
+ const equals = equals$1;
59
+ //#endregion
60
+ export { mediaQuery_exports as MediaQuery };
61
+
62
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":["internal.isMediaQuery","internal.minWidth","internal.prefersColorScheme","internal.and","internal.render","internal.equals"],"sources":["../../src/query/mediaQuery.ts"],"sourcesContent":["import type { Pipeable } from '#util'\nimport type { MediaQueryTypeId } from './mediaQuery.internal.ts'\nimport * as internal from './mediaQuery.internal.ts'\n\n/**\n * A media query: a canonically ordered, deduplicated and-set of media\n * features.\n *\n * Feature constructors (`minWidth`, `prefersColorScheme`) return\n * one-feature queries; `and` merges. Conjunction is commutative and\n * idempotent, so construction sorts features canonically and drops exact\n * duplicates — structurally equal queries compare equal however they\n * were built. The canonical order is stable public API: `min-width`\n * features first (ascending by threshold), then `prefers-color-scheme`\n * (schemes alphabetically). Distinct features always all render, even\n * when one subsumes another (`minWidth(768)` and `minWidth(1024)`):\n * simplification changes no meaning but is not this type's job.\n *\n * `or` and `not` become new node kinds when a consumer needs them.\n *\n * @since 0.1.0\n */\nexport interface MediaQuery extends Pipeable {\n readonly [MediaQueryTypeId]: MediaQueryTypeId\n}\n\n/**\n * Options for `render` — and the base of the library's render-options\n * family: every other module's `RenderOptions` extends this interface\n * (directly or through `Declaration.RenderOptions` and\n * `RuleSet.RenderOptions`), so an options object built for a bigger\n * renderer is accepted by every smaller one. A key means the same thing\n * wherever it appears; renderers ignore inherited keys that don't apply\n * to them.\n *\n * @since 0.1.0\n */\nexport interface RenderOptions {\n /**\n * The width-feature spelling: classic prefix syntax\n * (`(min-width: 768px)`, the default) or modern range syntax\n * (`(width >= 768px)`). Text only — the model is semantic and the two\n * spellings mean the same thing.\n */\n readonly mediaSyntax?: 'prefix' | 'range'\n}\n\n/**\n * Checks if a value is a `MediaQuery`.\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 `MediaQuery`, `false` otherwise.\n * @since 0.1.0\n */\nexport const isMediaQuery: (u: unknown) => u is MediaQuery = internal.isMediaQuery\n\n/**\n * Creates a viewport-width lower bound.\n *\n * @param px - The threshold in CSS pixels. Must be a non-negative finite number.\n * @returns A one-feature `MediaQuery`.\n * @throws `Error` when `px` is negative or not finite.\n * @example\n * ```ts\n * MediaQuery.render(MediaQuery.minWidth(768)) // '(min-width: 768px)'\n * MediaQuery.render(MediaQuery.minWidth(768), { mediaSyntax: 'range' }) // '(width >= 768px)'\n * ```\n * @since 0.1.0\n */\nexport const minWidth: (px: number) => MediaQuery = internal.minWidth\n\n/**\n * Creates a `prefers-color-scheme` condition.\n *\n * @param scheme - The scheme to match, `'dark'` or `'light'`.\n * @returns A one-feature `MediaQuery`.\n * @since 0.1.0\n */\nexport const prefersColorScheme: (scheme: 'dark' | 'light') => MediaQuery =\n internal.prefersColorScheme\n\nexport const and: {\n /**\n * Returns a function that conjoins `that` with its argument.\n *\n * @param that - The query to merge in.\n * @returns A function producing the conjunction.\n * @since 0.1.0\n */\n (that: MediaQuery): (self: MediaQuery) => MediaQuery\n /**\n * Conjoins two queries: the result matches where both match. Features\n * re-sort into canonical order and exact duplicates collapse, so `and`\n * is commutative and idempotent.\n *\n * @param self - The first query.\n * @param that - The second query.\n * @returns The conjunction.\n * @example\n * ```ts\n * MediaQuery.minWidth(1280).pipe(\n * MediaQuery.and(MediaQuery.prefersColorScheme('dark')),\n * MediaQuery.render,\n * ) // '(min-width: 1280px) and (prefers-color-scheme: dark)'\n * ```\n * @since 0.1.0\n */\n (self: MediaQuery, that: MediaQuery): MediaQuery\n} = internal.and\n\n/**\n * Renders the query as CSS text: features in canonical order —\n * `min-width` ascending, then `prefers-color-scheme` — joined with\n * ` and `. The `mediaSyntax` option picks the width-feature spelling\n * (default `'prefix'`).\n *\n * @param query - The query to render.\n * @param options - Optional syntax selection.\n * @returns Deterministic CSS text, without the `@media ` prefix.\n * @since 0.1.0\n */\nexport const render: (query: MediaQuery, options?: RenderOptions) => string = internal.render\n\nexport const equals: {\n /**\n * Returns a function that checks structural equality against `that`.\n *\n * @param that - The query to compare against.\n * @returns A function testing its argument for structural equality with `that`.\n * @since 0.1.0\n */\n (that: MediaQuery): (self: MediaQuery) => boolean\n /**\n * Structural equality over canonically ordered features: two queries\n * built from the same conditions compare equal regardless of\n * construction order.\n *\n * @param self - The first query.\n * @param that - The second query.\n * @returns `true` if the queries are structurally equal.\n * @since 0.1.0\n */\n (self: MediaQuery, that: MediaQuery): boolean\n} = internal.equals\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAyDA,MAAa,eAAgDA;;;;;;;;;;;;;;AAe7D,MAAa,WAAuCC;;;;;;;;AASpD,MAAa,qBACXC;AAEF,MAAa,MA2BTC;;;;;;;;;;;;AAaJ,MAAa,SAAiEC;AAE9E,MAAa,SAoBTC"}
@@ -0,0 +1,2 @@
1
+ import { i as ruleSet_d_exports, o as styleRule_d_exports, t as mediaRule_d_exports } from "../shared/mediaRule-BDB4WCYy.mjs";
2
+ export { mediaRule_d_exports as MediaRule, ruleSet_d_exports as RuleSet, styleRule_d_exports as StyleRule };
@@ -0,0 +1,234 @@
1
+ import { t as __exportAll } from "../shared/rolldown-runtime-D7D4PA-g.mjs";
2
+ import { _ as equals$3, a as forMediaQuery$1, b as refs$3, c as isRuleSet$1, d as render$4, f as equals$5, g as render$5, h as refs$5, i as equals$4, l as make$4, m as make$5, n as concat$1, o as forSelector$1, p as isStyleRule$1, r as empty$1, s as isEmpty$1, t as append$1, u as refs$4, v as isMediaRule$1, x as render$3, y as make$3 } from "../shared/ruleSet.internal-DodzVMUU.mjs";
3
+ //#region src/rule/mediaRule.ts
4
+ var mediaRule_exports = /* @__PURE__ */ __exportAll({
5
+ equals: () => equals$2,
6
+ isMediaRule: () => isMediaRule,
7
+ make: () => make$2,
8
+ refs: () => refs$2,
9
+ render: () => render$2
10
+ });
11
+ /**
12
+ * Checks if a value is a `MediaRule`.
13
+ *
14
+ * True only for values built by this module's constructors, which carry
15
+ * the brand.
16
+ *
17
+ * @param u - The value to check.
18
+ * @returns `true` if the value is a `MediaRule`, `false` otherwise.
19
+ * @since 0.1.0
20
+ */
21
+ const isMediaRule = isMediaRule$1;
22
+ /**
23
+ * Creates a nested `@media` rule.
24
+ *
25
+ * @param query - The media query gating the block.
26
+ * @param block - The rule's block.
27
+ * @returns A `MediaRule` carrying the block's reference names.
28
+ * @example
29
+ * ```ts
30
+ * MediaRule.make(
31
+ * MediaQuery.prefersColorScheme('dark'),
32
+ * RuleSet.make(Declaration.make('--scheme', 'dark')),
33
+ * )
34
+ * ```
35
+ * @since 0.1.0
36
+ */
37
+ const make$2 = make$3;
38
+ /**
39
+ * The rule's unbound reference names — the block's, since a query
40
+ * contributes none.
41
+ *
42
+ * @param rule - The rule to inspect.
43
+ * @returns The set of unbound reference names.
44
+ * @since 0.1.0
45
+ */
46
+ const refs$2 = refs$3;
47
+ /**
48
+ * Renders the rule in nested form: `@media query { ... }`, the body as
49
+ * `RuleSet.render` emits it, one level deeper — declarations directly
50
+ * inside the query block, the shape a media rule takes nested in a
51
+ * style rule (CSSNestedDeclarations). A rule whose block is empty
52
+ * renders as the empty string.
53
+ *
54
+ * A fragment renderer: whole sheets render via `Stylesheet.render`,
55
+ * which emits each rule's media in this same nested shape.
56
+ *
57
+ * @param rule - The rule to render.
58
+ * @param options - Optional indentation unit, precision context, and media syntax.
59
+ * @returns Deterministic CSS text.
60
+ * @throws `Error` when the block nests a style rule — selector composition (`&`) is a later extension, not part of v1 rendering.
61
+ * @example
62
+ * ```ts
63
+ * MediaRule.render(
64
+ * MediaRule.make(MediaQuery.minWidth(768), RuleSet.make(Declaration.make('--gutter', 24))),
65
+ * ) // '@media (min-width: 768px) {\n\t--gutter: 24;\n}'
66
+ * ```
67
+ * @since 0.1.0
68
+ */
69
+ const render$2 = render$3;
70
+ const equals$2 = equals$3;
71
+ //#endregion
72
+ //#region src/rule/ruleSet.ts
73
+ var ruleSet_exports = /* @__PURE__ */ __exportAll({
74
+ append: () => append,
75
+ concat: () => concat,
76
+ empty: () => empty,
77
+ equals: () => equals$1,
78
+ forMediaQuery: () => forMediaQuery,
79
+ forSelector: () => forSelector,
80
+ isEmpty: () => isEmpty,
81
+ isRuleSet: () => isRuleSet,
82
+ make: () => make$1,
83
+ refs: () => refs$1,
84
+ render: () => render$1
85
+ });
86
+ /**
87
+ * Checks if a value is a `RuleSet`.
88
+ *
89
+ * True only for values built by this module's constructors, which carry
90
+ * the brand.
91
+ *
92
+ * @param u - The value to check.
93
+ * @returns `true` if the value is a `RuleSet`, `false` otherwise.
94
+ * @since 0.1.0
95
+ */
96
+ const isRuleSet = isRuleSet$1;
97
+ /**
98
+ * The empty block — the identity for `concat`.
99
+ *
100
+ * @since 0.1.0
101
+ */
102
+ const empty = empty$1;
103
+ /**
104
+ * Checks if the block has no members.
105
+ *
106
+ * Structural emptiness only: a non-empty block can still *render* as the
107
+ * empty string, when every member is a nested rule whose block renders
108
+ * empty.
109
+ *
110
+ * @param set - The block to inspect.
111
+ * @returns `true` if the block has no members.
112
+ * @since 0.2.0
113
+ */
114
+ const isEmpty = isEmpty$1;
115
+ /**
116
+ * Creates a rule set holding the given members, in the given order.
117
+ *
118
+ * @param members - Declarations and nested rules, in authored order.
119
+ * @returns A `RuleSet` whose `Refs` unions the members' reference names.
120
+ * @example
121
+ * ```ts
122
+ * const block = RuleSet.make(
123
+ * Declaration.make('--depth', Calc.ref('depth')),
124
+ * Declaration.make('color', 'oklch(0.7 0.1 250)'),
125
+ * ) // RuleSet<'depth'>
126
+ * ```
127
+ * @since 0.1.0
128
+ */
129
+ const make$1 = make$4;
130
+ const append = append$1;
131
+ const concat = concat$1;
132
+ const forSelector = forSelector$1;
133
+ const forMediaQuery = forMediaQuery$1;
134
+ /**
135
+ * The block's unbound reference names, unioned across members —
136
+ * including everything nested rules contribute.
137
+ *
138
+ * @param set - The block to inspect.
139
+ * @returns The set of unbound reference names.
140
+ * @since 0.1.0
141
+ */
142
+ const refs$1 = refs$4;
143
+ /**
144
+ * Renders the block's body — the text between a rule's braces, without
145
+ * the braces: one line per declaration, nested `@media` rules as
146
+ * indented sub-blocks, in member order. Empty blocks (and nested rules
147
+ * whose blocks are empty) render as the empty string.
148
+ *
149
+ * A fragment renderer: use it to compose blocks the model does not
150
+ * represent. Whole sheets render via `Stylesheet.render`.
151
+ *
152
+ * @param set - The block to render.
153
+ * @param options - Optional indentation unit, precision context, and media syntax.
154
+ * @returns Deterministic CSS text.
155
+ * @throws `Error` when the block nests a style rule — selector composition (`&`) is a later extension, not part of v1 rendering.
156
+ * @example
157
+ * ```ts
158
+ * RuleSet.render(RuleSet.make(Declaration.make('--depth', 4), Declaration.make('color', 'red')))
159
+ * // '--depth: 4;\ncolor: red;'
160
+ * ```
161
+ * @since 0.1.0
162
+ */
163
+ const render$1 = render$4;
164
+ const equals$1 = equals$4;
165
+ //#endregion
166
+ //#region src/rule/styleRule.ts
167
+ var styleRule_exports = /* @__PURE__ */ __exportAll({
168
+ equals: () => equals,
169
+ isStyleRule: () => isStyleRule,
170
+ make: () => make,
171
+ refs: () => refs,
172
+ render: () => render
173
+ });
174
+ /**
175
+ * Checks if a value is a `StyleRule`.
176
+ *
177
+ * True only for values built by this module's constructors, which carry
178
+ * the brand.
179
+ *
180
+ * @param u - The value to check.
181
+ * @returns `true` if the value is a `StyleRule`, `false` otherwise.
182
+ * @since 0.1.0
183
+ */
184
+ const isStyleRule = isStyleRule$1;
185
+ /**
186
+ * Creates a style rule.
187
+ *
188
+ * @param selector - The compound selector the block applies to.
189
+ * @param block - The rule's block.
190
+ * @returns A `StyleRule` carrying the block's reference names.
191
+ * @example
192
+ * ```ts
193
+ * StyleRule.make(
194
+ * Selector.root,
195
+ * RuleSet.make(Declaration.make('--depth', Calc.ref('depth'))),
196
+ * ) // StyleRule<'depth'>
197
+ * ```
198
+ * @since 0.1.0
199
+ */
200
+ const make = make$5;
201
+ /**
202
+ * The rule's unbound reference names — the block's, since a selector
203
+ * contributes none.
204
+ *
205
+ * @param rule - The rule to inspect.
206
+ * @returns The set of unbound reference names.
207
+ * @since 0.1.0
208
+ */
209
+ const refs = refs$5;
210
+ /**
211
+ * Renders the rule in nested form: `selector { ... }`, the body as
212
+ * `RuleSet.render` emits it, one level deeper. A rule whose block is
213
+ * empty renders as the empty string.
214
+ *
215
+ * A fragment renderer: whole sheets render via `Stylesheet.render`,
216
+ * which emits each rule in this same nested shape.
217
+ *
218
+ * @param rule - The rule to render.
219
+ * @param options - Optional indentation unit, precision context, and media syntax.
220
+ * @returns Deterministic CSS text.
221
+ * @throws `Error` when the block nests a style rule — selector composition (`&`) is a later extension, not part of v1 rendering.
222
+ * @example
223
+ * ```ts
224
+ * StyleRule.render(StyleRule.make(Selector.root, RuleSet.make(Declaration.make('--depth', 4))))
225
+ * // ':root {\n\t--depth: 4;\n}'
226
+ * ```
227
+ * @since 0.1.0
228
+ */
229
+ const render = render$5;
230
+ const equals = equals$5;
231
+ //#endregion
232
+ export { mediaRule_exports as MediaRule, ruleSet_exports as RuleSet, styleRule_exports as StyleRule };
233
+
234
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":["internal.isMediaRule","make","internal.make","refs","internal.refs","render","internal.render","equals","internal.equals","internal.isRuleSet","internal.empty","internal.isEmpty","make","internal.make","internal.append","internal.concat","internal.forSelector","internal.forMediaQuery","refs","internal.refs","render","internal.render","equals","internal.equals","internal.isStyleRule","internal.make","internal.refs","internal.render","internal.equals"],"sources":["../../src/rule/mediaRule.ts","../../src/rule/ruleSet.ts","../../src/rule/styleRule.ts"],"sourcesContent":["import type { MediaQuery } from '#query/mediaQuery'\nimport type { Pipeable } from '#util'\nimport type { MediaRuleTypeId } from './mediaRule.internal.ts'\nimport * as internal from './mediaRule.internal.ts'\nimport type { RenderOptions as RuleSetRenderOptions, RuleSet } from './ruleSet.ts'\n\n/**\n * A nested `@media` rule: a media query and the block it gates.\n *\n * This is the nested form — a member of an enclosing style rule's block,\n * per the CSSNestedDeclarations grammar — not a top-level `@media`\n * statement. Media enters the model inside a style rule\n * (`:root { @media ... { ... } }`) and renders there, nested. The `Refs`\n * parameter is the block's.\n *\n * Construct via `make`.\n *\n * @since 0.1.0\n */\nexport interface MediaRule<out Refs extends string = string> extends Pipeable {\n readonly [MediaRuleTypeId]: MediaRuleTypeId\n /**\n * The media query gating the block.\n */\n readonly query: MediaQuery\n /**\n * The rule's block.\n */\n readonly block: RuleSet<Refs>\n}\n\n/**\n * Checks if a value is a `MediaRule`.\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 `MediaRule`, `false` otherwise.\n * @since 0.1.0\n */\nexport const isMediaRule: (u: unknown) => u is MediaRule<string> = internal.isMediaRule\n\n/**\n * Creates a nested `@media` rule.\n *\n * @param query - The media query gating the block.\n * @param block - The rule's block.\n * @returns A `MediaRule` carrying the block's reference names.\n * @example\n * ```ts\n * MediaRule.make(\n * MediaQuery.prefersColorScheme('dark'),\n * RuleSet.make(Declaration.make('--scheme', 'dark')),\n * )\n * ```\n * @since 0.1.0\n */\nexport const make: <Refs extends string>(\n query: MediaQuery,\n block: RuleSet<Refs>,\n) => MediaRule<Refs> = internal.make\n\n/**\n * The rule's unbound reference names — the block's, since a query\n * contributes none.\n *\n * @param rule - The rule to inspect.\n * @returns The set of unbound reference names.\n * @since 0.1.0\n */\nexport const refs: <Refs extends string>(rule: MediaRule<Refs>) => ReadonlySet<Refs> = internal.refs\n\n/**\n * Options for `render` — the block renderers' shared shape,\n * `RuleSet.RenderOptions`, unchanged.\n *\n * @since 0.1.0\n */\nexport type RenderOptions = RuleSetRenderOptions\n\n/**\n * Renders the rule in nested form: `@media query { ... }`, the body as\n * `RuleSet.render` emits it, one level deeper — declarations directly\n * inside the query block, the shape a media rule takes nested in a\n * style rule (CSSNestedDeclarations). A rule whose block is empty\n * renders as the empty string.\n *\n * A fragment renderer: whole sheets render via `Stylesheet.render`,\n * which emits each rule's media in this same nested shape.\n *\n * @param rule - The rule to render.\n * @param options - Optional indentation unit, precision context, and media syntax.\n * @returns Deterministic CSS text.\n * @throws `Error` when the block nests a style rule — selector composition (`&`) is a later extension, not part of v1 rendering.\n * @example\n * ```ts\n * MediaRule.render(\n * MediaRule.make(MediaQuery.minWidth(768), RuleSet.make(Declaration.make('--gutter', 24))),\n * ) // '@media (min-width: 768px) {\\n\\t--gutter: 24;\\n}'\n * ```\n * @since 0.1.0\n */\nexport const render: (rule: MediaRule<string>, options?: RenderOptions) => string = internal.render\n\nexport const equals: {\n /**\n * Returns a function that checks structural equality against `that`.\n *\n * @param that - The rule to compare against.\n * @returns A function testing its argument for structural equality with `that`.\n * @since 0.1.0\n */\n (that: MediaRule<string>): (self: MediaRule<string>) => boolean\n /**\n * Structural equality: queries compare as in `MediaQuery.equals`\n * (canonically ordered features), blocks as in `RuleSet.equals`\n * (members in order).\n *\n * @param self - The first rule.\n * @param that - The second rule.\n * @returns `true` if the rules are structurally equal.\n * @since 0.1.0\n */\n (self: MediaRule<string>, that: MediaRule<string>): boolean\n} = internal.equals\n","import type {\n Declaration,\n RenderOptions as DeclarationRenderOptions,\n} from '#declaration/declaration'\nimport type { MediaQuery } from '#query/mediaQuery'\nimport type { Selector } from '#selector/selector'\nimport type { Pipeable } from '#util'\nimport type { MediaRule } from './mediaRule.ts'\nimport type { RuleSetTypeId } from './ruleSet.internal.ts'\nimport * as internal from './ruleSet.internal.ts'\nimport type { StyleRule } from './styleRule.ts'\n\n/**\n * An ordered block of rule members — the nesting unit of the rule layer.\n *\n * Member order is preserved exactly as authored: never sorted, never\n * deduplicated. A block's order is cascade behavior, and since\n * CSSNestedDeclarations shipped (late 2024), declarations trailing a\n * nested rule keep their source position rather than hoisting above it —\n * so what you append is what renders.\n *\n * The `Refs` parameter unions the members' unbound reference names, as on\n * `Calc`; `refs` is the runtime set.\n *\n * Construct via `make` (or `empty` and `append`).\n *\n * @since 0.1.0\n */\nexport interface RuleSet<out Refs extends string = string> extends Pipeable {\n readonly [RuleSetTypeId]: RuleSetTypeId\n /**\n * The block's members, in authored order.\n */\n readonly members: ReadonlyArray<Member<Refs>>\n}\n\n/**\n * The forms a rule block may contain: declarations, nested style rules,\n * and nested `@media` rules.\n *\n * Deliberately absent are the declaration-block at-rules (`@font-face`,\n * `@property`) — the CSS grammar keeps them at the top level, so this\n * union keeps them out of blocks at the type level.\n *\n * @since 0.1.0\n */\nexport type Member<Refs extends string = string> =\n | Declaration<Refs>\n | StyleRule<Refs>\n | MediaRule<Refs>\n\n/**\n * The unbound reference names of a `Member`, or the union of them for a\n * union of members — the type-level counterpart of `refs`, used by the\n * container constructors to thread their members' names into the result.\n *\n * @since 0.1.0\n */\nexport type MemberRefs<M extends Member<string>> =\n M extends Declaration<infer R>\n ? R\n : M extends StyleRule<infer R>\n ? R\n : M extends MediaRule<infer R>\n ? R\n : never\n\n/**\n * Checks if a value is a `RuleSet`.\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 `RuleSet`, `false` otherwise.\n * @since 0.1.0\n */\nexport const isRuleSet: (u: unknown) => u is RuleSet<string> = internal.isRuleSet\n\n/**\n * The empty block — the identity for `concat`.\n *\n * @since 0.1.0\n */\nexport const empty: RuleSet<never> = internal.empty\n\n/**\n * Checks if the block has no members.\n *\n * Structural emptiness only: a non-empty block can still *render* as the\n * empty string, when every member is a nested rule whose block renders\n * empty.\n *\n * @param set - The block to inspect.\n * @returns `true` if the block has no members.\n * @since 0.2.0\n */\nexport const isEmpty: (set: RuleSet<string>) => boolean = internal.isEmpty\n\n/**\n * Creates a rule set holding the given members, in the given order.\n *\n * @param members - Declarations and nested rules, in authored order.\n * @returns A `RuleSet` whose `Refs` unions the members' reference names.\n * @example\n * ```ts\n * const block = RuleSet.make(\n * Declaration.make('--depth', Calc.ref('depth')),\n * Declaration.make('color', 'oklch(0.7 0.1 250)'),\n * ) // RuleSet<'depth'>\n * ```\n * @since 0.1.0\n */\nexport const make: <Members extends ReadonlyArray<Member<string>>>(\n ...members: Members\n) => RuleSet<MemberRefs<Members[number]>> = internal.make\n\nexport const append: {\n /**\n * Returns a function that appends `member` to its argument's block.\n *\n * @param member - The member to append.\n * @returns A function producing the extended block.\n * @since 0.1.0\n */\n <M extends Member<string>>(\n member: M,\n ): <Refs extends string>(self: RuleSet<Refs>) => RuleSet<Refs | MemberRefs<M>>\n /**\n * Returns a function that appends the style rule `selector { block }`\n * to its argument's block.\n *\n * @param selector - The nested rule's selector.\n * @param block - The nested rule's block.\n * @returns A function producing the extended block.\n * @since 0.1.0\n */\n <B extends string>(\n selector: Selector,\n block: RuleSet<B>,\n ): <Refs extends string>(self: RuleSet<Refs>) => RuleSet<Refs | B>\n /**\n * Returns a function that appends the media rule `@media query { block }`\n * to its argument's block.\n *\n * @param query - The nested rule's media query.\n * @param block - The nested rule's block.\n * @returns A function producing the extended block.\n * @since 0.1.0\n */\n <B extends string>(\n query: MediaQuery,\n block: RuleSet<B>,\n ): <Refs extends string>(self: RuleSet<Refs>) => RuleSet<Refs | B>\n /**\n * Appends a member at the end of the block. The result is a new set;\n * the original is untouched.\n *\n * @param self - The block to extend.\n * @param member - The member to append.\n * @returns The extended block, with the member's reference names joined in.\n * @example\n * ```ts\n * RuleSet.empty.pipe(\n * RuleSet.append(Declaration.make('color', 'red')),\n * RuleSet.append(Declaration.make('--depth', Calc.ref('depth'))),\n * ) // RuleSet<'depth'>\n * ```\n * @since 0.1.0\n */\n <Refs extends string, M extends Member<string>>(\n self: RuleSet<Refs>,\n member: M,\n ): RuleSet<Refs | MemberRefs<M>>\n /**\n * Appends a nested style rule from its parts — sugar for\n * `append(self, StyleRule.make(selector, block))`, so blocks compose\n * without naming `StyleRule` at the call site.\n *\n * @param self - The block to extend.\n * @param selector - The nested rule's selector.\n * @param block - The nested rule's block.\n * @returns The extended block, with the nested block's reference names joined in.\n * @example\n * ```ts\n * RuleSet.empty.pipe(RuleSet.append(Selector.class('btn'), RuleSet.make(Declaration.make('color', 'red'))))\n * ```\n * @since 0.1.0\n */\n <Refs extends string, B extends string>(\n self: RuleSet<Refs>,\n selector: Selector,\n block: RuleSet<B>,\n ): RuleSet<Refs | B>\n /**\n * Appends a nested media rule from its parts — sugar for\n * `append(self, MediaRule.make(query, block))`, so blocks compose\n * without naming `MediaRule` at the call site.\n *\n * @param self - The block to extend.\n * @param query - The nested rule's media query.\n * @param block - The nested rule's block.\n * @returns The extended block, with the nested block's reference names joined in.\n * @example\n * ```ts\n * RuleSet.make(Declaration.make('--gutter', 16)).pipe(\n * RuleSet.append(MediaQuery.minWidth(768), RuleSet.make(Declaration.make('--gutter', 24))),\n * )\n * ```\n * @since 0.1.0\n */\n <Refs extends string, B extends string>(\n self: RuleSet<Refs>,\n query: MediaQuery,\n block: RuleSet<B>,\n ): RuleSet<Refs | B>\n} = internal.append\n\nexport const concat: {\n /**\n * Returns a function that appends `that`'s members after its argument's.\n *\n * @param that - The block whose members come second.\n * @returns A function producing the concatenated block.\n * @since 0.1.0\n */\n <B extends string>(that: RuleSet<B>): <A extends string>(self: RuleSet<A>) => RuleSet<A | B>\n /**\n * Concatenates two blocks: `self`'s members followed by `that`'s, order\n * preserved on both sides. No deduplication happens here — repeated\n * declarations are legal CSS and their repetition is cascade behavior.\n *\n * @param self - The block whose members come first.\n * @param that - The block whose members come second.\n * @returns The concatenated block, with both sides' reference names unioned.\n * @since 0.1.0\n */\n <A extends string, B extends string>(self: RuleSet<A>, that: RuleSet<B>): RuleSet<A | B>\n} = internal.concat\n\nexport const forSelector: {\n /**\n * Returns a function that wraps its argument as the block of a style\n * rule applying to `selector`.\n *\n * @param selector - The selector the resulting rule's block applies to.\n * @returns A function that takes a block and returns the style rule applying it to `selector`.\n * @since 0.2.0\n */\n (selector: Selector): <Refs extends string>(self: RuleSet<Refs>) => StyleRule<Refs>\n /**\n * Lifts a block into a style rule applying to `selector` — sugar for\n * `StyleRule.make(selector, self)` with the arguments flipped, so a\n * block built up through `pipe` caps off as a rule without naming\n * `StyleRule` at the call site. The rule carries the block's reference\n * names unchanged; a selector contributes none.\n *\n * @param self - The block the rule applies.\n * @param selector - The selector the block applies to.\n * @returns The style rule pairing `selector` with the block.\n * @example\n * ```ts\n * RuleSet.make(Declaration.make('--depth', Calc.ref('depth'))).pipe(\n * RuleSet.forSelector(Selector.root),\n * ) // StyleRule<'depth'>\n * ```\n * @since 0.2.0\n */\n <Refs extends string>(self: RuleSet<Refs>, selector: Selector): StyleRule<Refs>\n} = internal.forSelector\n\nexport const forMediaQuery: {\n /**\n * Returns a function that wraps its argument as the block of a nested\n * `@media` rule gated by `query`.\n *\n * @param query - The media query gating the resulting rule's block.\n * @returns A function that takes a block and returns the media rule gating it by `query`.\n * @since 0.2.0\n */\n (query: MediaQuery): <Refs extends string>(self: RuleSet<Refs>) => MediaRule<Refs>\n /**\n * Lifts a block into a nested `@media` rule gated by `query` — sugar\n * for `MediaRule.make(query, self)` with the arguments flipped, so a\n * block built up through `pipe` caps off as a rule without naming\n * `MediaRule` at the call site. The rule carries the block's reference\n * names unchanged; a query contributes none.\n *\n * @param self - The block the rule gates.\n * @param query - The media query gating the block.\n * @returns The media rule pairing `query` with the block.\n * @example\n * ```ts\n * RuleSet.make(Declaration.make('--gutter', Calc.ref('gutter'))).pipe(\n * RuleSet.forMediaQuery(MediaQuery.minWidth(768)),\n * ) // MediaRule<'gutter'>\n * ```\n * @since 0.2.0\n */\n <Refs extends string>(self: RuleSet<Refs>, query: MediaQuery): MediaRule<Refs>\n} = internal.forMediaQuery\n\n/**\n * The block's unbound reference names, unioned across members —\n * including everything nested rules contribute.\n *\n * @param set - The block to inspect.\n * @returns The set of unbound reference names.\n * @since 0.1.0\n */\nexport const refs: <Refs extends string>(set: RuleSet<Refs>) => ReadonlySet<Refs> = internal.refs\n\n/**\n * Options for `render`, extending `Declaration.RenderOptions` (and\n * through it the family base, `MediaQuery.RenderOptions`) with the\n * indentation unit — the block renderers' shared shape, which\n * `StyleRule.render` and `MediaRule.render` take unchanged.\n *\n * @since 0.1.0\n */\nexport interface RenderOptions extends DeclarationRenderOptions {\n /**\n * The indentation unit, applied once per nesting level. Defaults to a\n * tab.\n */\n readonly indent?: string\n}\n\n/**\n * Renders the block's body — the text between a rule's braces, without\n * the braces: one line per declaration, nested `@media` rules as\n * indented sub-blocks, in member order. Empty blocks (and nested rules\n * whose blocks are empty) render as the empty string.\n *\n * A fragment renderer: use it to compose blocks the model does not\n * represent. Whole sheets render via `Stylesheet.render`.\n *\n * @param set - The block to render.\n * @param options - Optional indentation unit, precision context, and media syntax.\n * @returns Deterministic CSS text.\n * @throws `Error` when the block nests a style rule — selector composition (`&`) is a later extension, not part of v1 rendering.\n * @example\n * ```ts\n * RuleSet.render(RuleSet.make(Declaration.make('--depth', 4), Declaration.make('color', 'red')))\n * // '--depth: 4;\\ncolor: red;'\n * ```\n * @since 0.1.0\n */\nexport const render: (set: RuleSet<string>, options?: RenderOptions) => string = internal.render\n\nexport const equals: {\n /**\n * Returns a function that checks structural equality against `that`.\n *\n * @param that - The block to compare against.\n * @returns A function testing its argument for structural equality with `that`.\n * @since 0.1.0\n */\n (that: RuleSet<string>): (self: RuleSet<string>) => boolean\n /**\n * Structural equality over members, in order. Order participates —\n * `make(a, b)` and `make(b, a)` are different blocks, because they\n * cascade differently.\n *\n * @param self - The first block.\n * @param that - The second block.\n * @returns `true` if the blocks are structurally equal.\n * @since 0.1.0\n */\n (self: RuleSet<string>, that: RuleSet<string>): boolean\n} = internal.equals\n","import type { Selector } from '#selector/selector'\nimport type { Pipeable } from '#util'\nimport type { RenderOptions as RuleSetRenderOptions, RuleSet } from './ruleSet.ts'\nimport type { StyleRuleTypeId } from './styleRule.internal.ts'\nimport * as internal from './styleRule.internal.ts'\n\n/**\n * A style rule: a compound selector and the block it applies.\n *\n * The block is a full `RuleSet`, so a style rule holds declarations and\n * nested `@media` rules in one authored order. The `Refs` parameter is\n * the block's — a selector contributes no reference names.\n *\n * Construct via `make`.\n *\n * @since 0.1.0\n */\nexport interface StyleRule<out Refs extends string = string> extends Pipeable {\n readonly [StyleRuleTypeId]: StyleRuleTypeId\n /**\n * The compound selector the block applies to.\n */\n readonly selector: Selector\n /**\n * The rule's block.\n */\n readonly block: RuleSet<Refs>\n}\n\n/**\n * Checks if a value is a `StyleRule`.\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 `StyleRule`, `false` otherwise.\n * @since 0.1.0\n */\nexport const isStyleRule: (u: unknown) => u is StyleRule<string> = internal.isStyleRule\n\n/**\n * Creates a style rule.\n *\n * @param selector - The compound selector the block applies to.\n * @param block - The rule's block.\n * @returns A `StyleRule` carrying the block's reference names.\n * @example\n * ```ts\n * StyleRule.make(\n * Selector.root,\n * RuleSet.make(Declaration.make('--depth', Calc.ref('depth'))),\n * ) // StyleRule<'depth'>\n * ```\n * @since 0.1.0\n */\nexport const make: <Refs extends string>(\n selector: Selector,\n block: RuleSet<Refs>,\n) => StyleRule<Refs> = internal.make\n\n/**\n * The rule's unbound reference names — the block's, since a selector\n * contributes none.\n *\n * @param rule - The rule to inspect.\n * @returns The set of unbound reference names.\n * @since 0.1.0\n */\nexport const refs: <Refs extends string>(rule: StyleRule<Refs>) => ReadonlySet<Refs> = internal.refs\n\n/**\n * Options for `render` — the block renderers' shared shape,\n * `RuleSet.RenderOptions`, unchanged.\n *\n * @since 0.1.0\n */\nexport type RenderOptions = RuleSetRenderOptions\n\n/**\n * Renders the rule in nested form: `selector { ... }`, the body as\n * `RuleSet.render` emits it, one level deeper. A rule whose block is\n * empty renders as the empty string.\n *\n * A fragment renderer: whole sheets render via `Stylesheet.render`,\n * which emits each rule in this same nested shape.\n *\n * @param rule - The rule to render.\n * @param options - Optional indentation unit, precision context, and media syntax.\n * @returns Deterministic CSS text.\n * @throws `Error` when the block nests a style rule — selector composition (`&`) is a later extension, not part of v1 rendering.\n * @example\n * ```ts\n * StyleRule.render(StyleRule.make(Selector.root, RuleSet.make(Declaration.make('--depth', 4))))\n * // ':root {\\n\\t--depth: 4;\\n}'\n * ```\n * @since 0.1.0\n */\nexport const render: (rule: StyleRule<string>, options?: RenderOptions) => string = internal.render\n\nexport const equals: {\n /**\n * Returns a function that checks structural equality against `that`.\n *\n * @param that - The rule to compare against.\n * @returns A function testing its argument for structural equality with `that`.\n * @since 0.1.0\n */\n (that: StyleRule<string>): (self: StyleRule<string>) => boolean\n /**\n * Structural equality: selectors compare as in `Selector.equals`\n * (canonically ordered parts), blocks as in `RuleSet.equals` (members\n * in order).\n *\n * @param self - The first rule.\n * @param that - The second rule.\n * @returns `true` if the rules are structurally equal.\n * @since 0.1.0\n */\n (self: StyleRule<string>, that: StyleRule<string>): boolean\n} = internal.equals\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAyCA,MAAa,cAAsDA;;;;;;;;;;;;;;;;AAiBnE,MAAaC,SAGUC;;;;;;;;;AAUvB,MAAaC,SAA0EC;;;;;;;;;;;;;;;;;;;;;;;AAgCvF,MAAaC,WAAuEC;AAEpF,MAAaC,WAoBTC;;;;;;;;;;;;;;;;;;;;;;;;;;AChDJ,MAAa,YAAkDC;;;;;;AAO/D,MAAa,QAAwBC;;;;;;;;;;;;AAarC,MAAa,UAA6CC;;;;;;;;;;;;;;;AAgB1D,MAAaC,SAE+BC;AAE5C,MAAa,SAmGTC;AAEJ,MAAa,SAoBTC;AAEJ,MAAa,cA6BTC;AAEJ,MAAa,gBA6BTC;;;;;;;;;AAUJ,MAAaC,SAAuEC;;;;;;;;;;;;;;;;;;;;;AAsCpF,MAAaC,WAAoEC;AAEjF,MAAaC,WAoBTC;;;;;;;;;;;;;;;;;;;;AC3UJ,MAAa,cAAsDC;;;;;;;;;;;;;;;;AAiBnE,MAAa,OAGUC;;;;;;;;;AAUvB,MAAa,OAA0EC;;;;;;;;;;;;;;;;;;;;AA6BvF,MAAa,SAAuEC;AAEpF,MAAa,SAoBTC"}
@@ -0,0 +1,2 @@
1
+ import { n as selector_d_exports, r as specificity_d_exports } from "../shared/selector-HZY-W6l6.mjs";
2
+ export { selector_d_exports as Selector, specificity_d_exports as Specificity };
@@ -0,0 +1,178 @@
1
+ import { t as __exportAll } from "../shared/rolldown-runtime-D7D4PA-g.mjs";
2
+ import { _ as isSpecificity$1, a as id$1, c as pseudoClass$1, d as root$1, f as specificity$1, g as equals$3, h as compare$1, i as equals$2, l as pseudoElement$1, m as universal$1, n as and$1, o as isSelector$1, p as type$1, r as attribute$1, s as not$1, t as _class$1, u as render$1, v as make$1 } from "../shared/selector.internal-ESe9s0IH.mjs";
3
+ //#region src/selector/selector.ts
4
+ var selector_exports = /* @__PURE__ */ __exportAll({
5
+ and: () => and,
6
+ attribute: () => attribute,
7
+ class: () => _class,
8
+ equals: () => equals$1,
9
+ id: () => id,
10
+ isSelector: () => isSelector,
11
+ not: () => not,
12
+ pseudoClass: () => pseudoClass,
13
+ pseudoElement: () => pseudoElement,
14
+ render: () => render,
15
+ root: () => root,
16
+ specificity: () => specificity,
17
+ type: () => type,
18
+ universal: () => universal
19
+ });
20
+ /**
21
+ * Checks if a value is a `Selector`.
22
+ *
23
+ * True only for values built by this module's constructors, which carry
24
+ * the brand.
25
+ *
26
+ * @param u - The value to check.
27
+ * @returns `true` if the value is a `Selector`, `false` otherwise.
28
+ * @since 0.1.0
29
+ */
30
+ const isSelector = isSelector$1;
31
+ /**
32
+ * The universal selector, `*`. Contributes nothing to specificity.
33
+ *
34
+ * @since 0.1.0
35
+ */
36
+ const universal = universal$1;
37
+ /**
38
+ * Creates a type (element) selector, such as `div`.
39
+ *
40
+ * A compound may contain at most one type or universal selector; `and`
41
+ * enforces this.
42
+ *
43
+ * @param name - The element name. Must be non-empty; passed through unescaped.
44
+ * @returns A one-part `Selector`.
45
+ * @throws `Error` when `name` is empty.
46
+ * @since 0.1.0
47
+ */
48
+ const type = type$1;
49
+ /**
50
+ * Creates an id selector, rendered `#name`.
51
+ *
52
+ * @param name - The id, without the `#` prefix. Must be non-empty; passed through unescaped.
53
+ * @returns A one-part `Selector`.
54
+ * @throws `Error` when `name` is empty.
55
+ * @since 0.1.0
56
+ */
57
+ const id = id$1;
58
+ /**
59
+ * Creates a class selector, rendered `.name`. Exported as `class`
60
+ * (`Selector.class('btn')`) because `class` is reserved in declaration
61
+ * position.
62
+ *
63
+ * @param name - The class name, without the `.` prefix. Must be non-empty; passed through unescaped.
64
+ * @returns A one-part `Selector`.
65
+ * @throws `Error` when `name` is empty.
66
+ * @since 0.1.0
67
+ */
68
+ const _class = _class$1;
69
+ /**
70
+ * Creates a pseudo-class selector, rendered `:name`.
71
+ *
72
+ * For the functional negation pseudo-class, use `not`, which takes a
73
+ * typed selector argument.
74
+ *
75
+ * @param name - The pseudo-class name, without the `:` prefix. Must be non-empty.
76
+ * @returns A one-part `Selector`.
77
+ * @throws `Error` when `name` is empty.
78
+ * @since 0.1.0
79
+ */
80
+ const pseudoClass = pseudoClass$1;
81
+ const attribute = attribute$1;
82
+ /**
83
+ * Creates a functional negation, rendered `:not(argument)`. The argument
84
+ * is a full compound selector, and contributes its own specificity to the
85
+ * enclosing selector (`:not` itself contributes none).
86
+ *
87
+ * @param argument - The selector to negate.
88
+ * @returns A one-part `Selector`.
89
+ * @since 0.1.0
90
+ */
91
+ const not = not$1;
92
+ /**
93
+ * Creates a pseudo-element selector, rendered `::name`.
94
+ *
95
+ * A compound may contain at most one pseudo-element; `and` enforces this.
96
+ *
97
+ * @param name - The pseudo-element name, without the `::` prefix. Must be non-empty.
98
+ * @returns A one-part `Selector`.
99
+ * @throws `Error` when `name` is empty.
100
+ * @since 0.1.0
101
+ */
102
+ const pseudoElement = pseudoElement$1;
103
+ /**
104
+ * The `:root` pseudo-class selector — sugar for `pseudoClass('root')`,
105
+ * the usual anchor for custom-property rules.
106
+ *
107
+ * @since 0.1.0
108
+ */
109
+ const root = root$1;
110
+ const and = and$1;
111
+ /**
112
+ * Computes the selector's specificity: ids into `a`;
113
+ * classes, attributes, and pseudo-classes into `b`; types and
114
+ * pseudo-elements into `c`. `:not(...)` adds its argument's specificity;
115
+ * the universal selector adds nothing; duplicate parts count each time.
116
+ *
117
+ * This is what lets a consumer turn "these rules tie, so their order
118
+ * encodes the override direction" into something checkable.
119
+ *
120
+ * @param selector - The selector to measure.
121
+ * @returns The computed `Specificity`.
122
+ * @since 0.1.0
123
+ */
124
+ const specificity = specificity$1;
125
+ /**
126
+ * Renders the selector as CSS text: parts concatenated in canonical
127
+ * order — type first, then ids, classes, pseudo-classes, attributes,
128
+ * negations, and the pseudo-element last, alphabetically within each
129
+ * kind. Any fixed order matches identically; this one keeps root-scoped
130
+ * shapes in their conventional spelling.
131
+ *
132
+ * @param selector - The selector to render.
133
+ * @returns Deterministic CSS text.
134
+ * @example
135
+ * ```ts
136
+ * Selector.render(Selector.and(Selector.pseudoClass('hover'), Selector.class('btn')))
137
+ * // '.btn:hover'
138
+ * ```
139
+ * @since 0.1.0
140
+ */
141
+ const render = render$1;
142
+ const equals$1 = equals$2;
143
+ //#endregion
144
+ //#region src/selector/specificity.ts
145
+ var specificity_exports = /* @__PURE__ */ __exportAll({
146
+ compare: () => compare,
147
+ equals: () => equals,
148
+ isSpecificity: () => isSpecificity,
149
+ make: () => make
150
+ });
151
+ /**
152
+ * Checks if a value is a `Specificity`.
153
+ *
154
+ * True only for values built by this module's constructors, which carry
155
+ * the brand.
156
+ *
157
+ * @param u - The value to check.
158
+ * @returns `true` if the value is a `Specificity`, `false` otherwise.
159
+ * @since 0.1.0
160
+ */
161
+ const isSpecificity = isSpecificity$1;
162
+ /**
163
+ * Creates a `Specificity` from its three components.
164
+ *
165
+ * @param a - The id-selector count. Must be a non-negative integer.
166
+ * @param b - The class/attribute/pseudo-class count. Must be a non-negative integer.
167
+ * @param c - The type/pseudo-element count. Must be a non-negative integer.
168
+ * @returns A new `Specificity`.
169
+ * @throws `Error` when any component is not a non-negative integer.
170
+ * @since 0.1.0
171
+ */
172
+ const make = make$1;
173
+ const compare = compare$1;
174
+ const equals = equals$3;
175
+ //#endregion
176
+ export { selector_exports as Selector, specificity_exports as Specificity };
177
+
178
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +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"}