@craft-ts/style 0.7.0-beta.15
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/package.json +41 -0
- package/src/index.d.ts +18 -0
- package/src/index.d.ts.map +1 -0
- package/src/index.js +18 -0
- package/src/index.js.map +1 -0
- package/src/lib/axes/define.d.ts +115 -0
- package/src/lib/axes/define.d.ts.map +1 -0
- package/src/lib/axes/define.js +81 -0
- package/src/lib/axes/define.js.map +1 -0
- package/src/lib/axes/index.d.ts +4 -0
- package/src/lib/axes/index.d.ts.map +1 -0
- package/src/lib/axes/index.js +4 -0
- package/src/lib/axes/index.js.map +1 -0
- package/src/lib/axes/standard.d.ts +85 -0
- package/src/lib/axes/standard.d.ts.map +1 -0
- package/src/lib/axes/standard.js +109 -0
- package/src/lib/axes/standard.js.map +1 -0
- package/src/lib/axes/types.d.ts +67 -0
- package/src/lib/axes/types.d.ts.map +1 -0
- package/src/lib/axes/types.js +21 -0
- package/src/lib/axes/types.js.map +1 -0
- package/src/lib/css-vars.d.ts +100 -0
- package/src/lib/css-vars.d.ts.map +1 -0
- package/src/lib/css-vars.js +96 -0
- package/src/lib/css-vars.js.map +1 -0
- package/src/lib/kinds.d.ts +84 -0
- package/src/lib/kinds.d.ts.map +1 -0
- package/src/lib/kinds.js +44 -0
- package/src/lib/kinds.js.map +1 -0
- package/src/lib/obligations.d.ts +99 -0
- package/src/lib/obligations.d.ts.map +1 -0
- package/src/lib/obligations.js +69 -0
- package/src/lib/obligations.js.map +1 -0
- package/src/lib/props/factory.d.ts +61 -0
- package/src/lib/props/factory.d.ts.map +1 -0
- package/src/lib/props/factory.js +35 -0
- package/src/lib/props/factory.js.map +1 -0
- package/src/lib/props/generated.d.ts +974 -0
- package/src/lib/props/generated.d.ts.map +1 -0
- package/src/lib/props/generated.js +2478 -0
- package/src/lib/props/generated.js.map +1 -0
- package/src/lib/props/index.d.ts +37 -0
- package/src/lib/props/index.d.ts.map +1 -0
- package/src/lib/props/index.js +27 -0
- package/src/lib/props/index.js.map +1 -0
- package/src/lib/styles.d.ts +201 -0
- package/src/lib/styles.d.ts.map +1 -0
- package/src/lib/styles.js +247 -0
- package/src/lib/styles.js.map +1 -0
- package/src/lib/tokens/index.d.ts +4 -0
- package/src/lib/tokens/index.d.ts.map +1 -0
- package/src/lib/tokens/index.js +4 -0
- package/src/lib/tokens/index.js.map +1 -0
- package/src/lib/tokens/palette.d.ts +97 -0
- package/src/lib/tokens/palette.d.ts.map +1 -0
- package/src/lib/tokens/palette.js +61 -0
- package/src/lib/tokens/palette.js.map +1 -0
- package/src/lib/tokens/scales.d.ts +47 -0
- package/src/lib/tokens/scales.d.ts.map +1 -0
- package/src/lib/tokens/scales.js +51 -0
- package/src/lib/tokens/scales.js.map +1 -0
- package/src/lib/tokens/units.d.ts +114 -0
- package/src/lib/tokens/units.d.ts.map +1 -0
- package/src/lib/tokens/units.js +54 -0
- package/src/lib/tokens/units.js.map +1 -0
- package/src/plugin/emit.d.ts +64 -0
- package/src/plugin/emit.d.ts.map +1 -0
- package/src/plugin/emit.js +134 -0
- package/src/plugin/emit.js.map +1 -0
- package/src/plugin/vite.d.ts +66 -0
- package/src/plugin/vite.d.ts.map +1 -0
- package/src/plugin/vite.js +150 -0
- package/src/plugin/vite.js.map +1 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { rawLength } from "../tokens/units.js";
|
|
2
|
+
import { borderRadius, fontSize, gap, lineHeight, padding, paddingBlock, paddingInline, backgroundColor, } from "./generated.js";
|
|
3
|
+
export * from "./generated.js";
|
|
4
|
+
export { global, declaration, propertyName, } from "./factory.js";
|
|
5
|
+
/** `padding`. */
|
|
6
|
+
export const p = padding;
|
|
7
|
+
/** `padding-inline`. */
|
|
8
|
+
export const px = paddingInline;
|
|
9
|
+
/** `padding-block`. */
|
|
10
|
+
export const py = paddingBlock;
|
|
11
|
+
/** `background-color`. */
|
|
12
|
+
export const bg = backgroundColor;
|
|
13
|
+
/** `border-radius`. */
|
|
14
|
+
export const radius = borderRadius;
|
|
15
|
+
export { gap };
|
|
16
|
+
/**
|
|
17
|
+
* A size and its line height, together.
|
|
18
|
+
*
|
|
19
|
+
* Two declarations from one call is the only shape that cannot be half-applied.
|
|
20
|
+
* A component that sets `font-size` and forgets `line-height` is the most
|
|
21
|
+
* common way a type scale stops being a scale.
|
|
22
|
+
*/
|
|
23
|
+
export const font = (token) => [
|
|
24
|
+
fontSize(token),
|
|
25
|
+
lineHeight(rawLength(token.lineHeight)),
|
|
26
|
+
];
|
|
27
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../libs/style/src/lib/props/index.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,OAAO,EACL,YAAY,EACZ,QAAQ,EACR,GAAG,EACH,UAAU,EACV,OAAO,EACP,YAAY,EACZ,aAAa,EACb,eAAe,GAChB,MAAM,gBAAgB,CAAC;AAExB,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EACL,MAAM,EACN,WAAW,EACX,YAAY,GAGb,MAAM,cAAc,CAAC;AAEtB,iBAAiB;AACjB,MAAM,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC;AACzB,wBAAwB;AACxB,MAAM,CAAC,MAAM,EAAE,GAAG,aAAa,CAAC;AAChC,uBAAuB;AACvB,MAAM,CAAC,MAAM,EAAE,GAAG,YAAY,CAAC;AAC/B,0BAA0B;AAC1B,MAAM,CAAC,MAAM,EAAE,GAAG,eAAe,CAAC;AAClC,uBAAuB;AACvB,MAAM,CAAC,MAAM,MAAM,GAAG,YAAY,CAAC;AAEnC,OAAO,EAAE,GAAG,EAAE,CAAC;AAEf;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,KAAoB,EAA0B,EAAE,CAAC;IACpE,QAAQ,CAAC,KAAK,CAAC;IACf,UAAU,CAAC,SAAS,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;CACxC,CAAC","sourcesContent":["/**\n * The property table, plus the handful of short names worth having.\n *\n * Everything below is an **alias of a generated helper**, never a new helper:\n * `p` is `padding`, not a second definition of padding that could drift from\n * the spec. The only thing written by hand here is `font`, which pairs two\n * generated helpers because a size and its line height must not drift apart.\n *\n * `overflow` is absent, here and in the generated table. The single path to\n * `overflow: auto` is `provides(scrollPort.block)`, which lays down the CSS\n * effect and the discharge in the same object.\n */\nimport type { FontSizeToken } from '../tokens/scales.ts';\nimport { rawLength } from '../tokens/units.ts';\nimport type { Declaration } from './factory.ts';\nimport {\n borderRadius,\n fontSize,\n gap,\n lineHeight,\n padding,\n paddingBlock,\n paddingInline,\n backgroundColor,\n} from './generated.ts';\n\nexport * from './generated.ts';\nexport {\n global,\n declaration,\n propertyName,\n type Declaration,\n type PropertyToken,\n} from './factory.ts';\n\n/** `padding`. */\nexport const p = padding;\n/** `padding-inline`. */\nexport const px = paddingInline;\n/** `padding-block`. */\nexport const py = paddingBlock;\n/** `background-color`. */\nexport const bg = backgroundColor;\n/** `border-radius`. */\nexport const radius = borderRadius;\n\nexport { gap };\n\n/**\n * A size and its line height, together.\n *\n * Two declarations from one call is the only shape that cannot be half-applied.\n * A component that sets `font-size` and forgets `line-height` is the most\n * common way a type scale stops being a scale.\n */\nexport const font = (token: FontSizeToken): readonly Declaration[] => [\n fontSize(token),\n lineHeight(rawLength(token.lineHeight)),\n];\n"]}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `craftStyles`: a sheet whose **variant contract** is inferred, not declared,
|
|
3
|
+
* and whose CSS is atomic and deduplicated.
|
|
4
|
+
*
|
|
5
|
+
* Two properties make the rest of the system possible:
|
|
6
|
+
*
|
|
7
|
+
* - Only the breakpoints **actually used** enter the contract. An axis that
|
|
8
|
+
* defines six points but which a component crosses at one does not produce
|
|
9
|
+
* six scenarios; it produces two (`base` and that one).
|
|
10
|
+
* - A declaration under a condition is one **atomic class**, shared by every
|
|
11
|
+
* sheet that writes it. Output then grows with the vocabulary, not with the
|
|
12
|
+
* number of components — which is what keeps the emitted stylesheet flat as
|
|
13
|
+
* the app grows.
|
|
14
|
+
*
|
|
15
|
+
* Conjunction is nesting and nothing else — `when(a, [when(b, […])])`. A second
|
|
16
|
+
* spelling would mean two identical components could produce two different
|
|
17
|
+
* contracts.
|
|
18
|
+
*/
|
|
19
|
+
import type { ChannelsOf, CraftChannels, CraftChannelsCarrier, MergeChannelUnion } from '@craft-ts/core';
|
|
20
|
+
import type { AnyAxisPoint, AxisPoint, WritesSyntaxOf } from './axes/index.ts';
|
|
21
|
+
import type { VarWrite } from './css-vars.ts';
|
|
22
|
+
import type { Declaration } from './props/factory.ts';
|
|
23
|
+
import type { Obligation, ObligationEntry } from './obligations.ts';
|
|
24
|
+
declare const VARIANTS: unique symbol;
|
|
25
|
+
export interface Conditional<Point extends AnyAxisPoint, Items extends readonly unknown[]> {
|
|
26
|
+
readonly kind: 'when';
|
|
27
|
+
readonly at: Point;
|
|
28
|
+
readonly items: Items;
|
|
29
|
+
}
|
|
30
|
+
export type SheetItem = Declaration | readonly Declaration[] | ObligationEntry | Conditional<AnyAxisPoint, readonly any[]>;
|
|
31
|
+
/**
|
|
32
|
+
* What an axis is allowed to contain.
|
|
33
|
+
*
|
|
34
|
+
* An unconstrained axis takes anything a sheet takes. An axis declared with
|
|
35
|
+
* `writes: onlyVarsOfKind(kind.color)` takes **only** writes of that kind —
|
|
36
|
+
* no properties, and no nesting, because an axis that may only repaint has
|
|
37
|
+
* nothing to conjoin with. That constraint is what makes such an axis provably
|
|
38
|
+
* orthogonal to the axes that move boxes, without analysing any CSS.
|
|
39
|
+
*/
|
|
40
|
+
export type AllowedItems<Point> = [WritesSyntaxOf<Point>] extends [never] ? readonly SheetItem[] : readonly VarWrite<WritesSyntaxOf<Point>>[];
|
|
41
|
+
/** Applies declarations under a condition. Nestable, and nothing else. */
|
|
42
|
+
export declare function when<const Point extends AnyAxisPoint, const Items extends readonly SheetItem[]>(at: Point, items: Items & AllowedItems<Point>): Conditional<Point, Items>;
|
|
43
|
+
type PointsIn<Item> = Item extends Conditional<infer Point, infer Items> ? Point | PointsIn<Items[number]> : Item extends readonly (infer Child)[] ? PointsIn<Child> : never;
|
|
44
|
+
/** axis → the points **actually** used. Never all the points of the axis. */
|
|
45
|
+
export type VariantContract<Points extends AnyAxisPoint> = {
|
|
46
|
+
readonly [Axis in Points['axis']]: Extract<Points, AxisPoint<Axis, string>>['point'];
|
|
47
|
+
};
|
|
48
|
+
type EntriesIn<Item, Kind extends string> = Item extends Conditional<AnyAxisPoint, infer Items> ? EntriesIn<Items[number], Kind> : Item extends readonly (infer Child)[] ? EntriesIn<Child, Kind> : Item extends {
|
|
49
|
+
readonly kind: Kind;
|
|
50
|
+
readonly spec: {
|
|
51
|
+
readonly id: infer Id extends string;
|
|
52
|
+
readonly explain: infer Explain extends string;
|
|
53
|
+
};
|
|
54
|
+
} ? Obligation<Id, Explain> : never;
|
|
55
|
+
/**
|
|
56
|
+
* The channel a class lays on the node carrying it. The core does not know what
|
|
57
|
+
* it transports: to it, `Obligation<'scrollPort.block'>` is an opaque payload
|
|
58
|
+
* that an `Exclude` cancels.
|
|
59
|
+
*/
|
|
60
|
+
export type ChannelsOfSheet<Item> = MergeChannelUnion<{
|
|
61
|
+
readonly accumulate: never;
|
|
62
|
+
readonly obligations: EntriesIn<Item, 'requires'>;
|
|
63
|
+
readonly discharges: EntriesIn<Item, 'provides'>;
|
|
64
|
+
readonly violates: EntriesIn<Item, 'violates'>;
|
|
65
|
+
}>;
|
|
66
|
+
/**
|
|
67
|
+
* A branded class. At runtime it is a string — the existing renderer sets it
|
|
68
|
+
* as-is — but its type carries the variants it produces and the channel it
|
|
69
|
+
* opens. What typing cannot prevent (writing `class: 'badge'` by hand) the
|
|
70
|
+
* `no-raw-class` ESLint rule forbids: partial tightness buys 0 % of the
|
|
71
|
+
* guarantee, not 90 %.
|
|
72
|
+
*/
|
|
73
|
+
export type CraftClass<Points extends AnyAxisPoint = never, Channels extends CraftChannels = never> = string & CraftChannelsCarrier<Channels> & {
|
|
74
|
+
readonly [VARIANTS]?: Points;
|
|
75
|
+
};
|
|
76
|
+
/** A class's contract, readable from outside — what the matrix unfolds. */
|
|
77
|
+
export type VariantsOf<Class> = typeof VARIANTS extends keyof Class ? Class extends {
|
|
78
|
+
readonly [VARIANTS]?: infer Points;
|
|
79
|
+
} ? [Points] extends [AnyAxisPoint] ? VariantContract<Points> : Record<never, never> : Record<never, never> : Record<never, never>;
|
|
80
|
+
export type StyleSheet = Readonly<Record<string, readonly SheetItem[]>>;
|
|
81
|
+
export type CraftStyles<Sheet extends StyleSheet> = {
|
|
82
|
+
readonly [Key in keyof Sheet]: CraftClass<PointsIn<Sheet[Key][number]>, ChannelsOfSheet<Sheet[Key][number]>>;
|
|
83
|
+
};
|
|
84
|
+
export interface AtomicRule {
|
|
85
|
+
readonly className: string;
|
|
86
|
+
/** Outer to inner, in nesting order. */
|
|
87
|
+
readonly conditions: readonly AnyAxisPoint[];
|
|
88
|
+
readonly property: string;
|
|
89
|
+
readonly value: string;
|
|
90
|
+
readonly unproven: string;
|
|
91
|
+
}
|
|
92
|
+
export interface RegisteredClass {
|
|
93
|
+
/** `badge-root` — stable, human-readable, and the key the matrix uses. */
|
|
94
|
+
readonly key: string;
|
|
95
|
+
/** The space-separated atomic classes actually set on the element. */
|
|
96
|
+
readonly className: string;
|
|
97
|
+
readonly rules: readonly AtomicRule[];
|
|
98
|
+
readonly axes: Readonly<Record<string, readonly string[]>>;
|
|
99
|
+
readonly unproven: readonly string[];
|
|
100
|
+
readonly requires: readonly string[];
|
|
101
|
+
readonly provides: readonly string[];
|
|
102
|
+
readonly violates: readonly string[];
|
|
103
|
+
/**
|
|
104
|
+
* Axes the sheet declared and never used. Not an error — a budget is an
|
|
105
|
+
* upper bound — but it is dead weight a reader takes for a real variation,
|
|
106
|
+
* so the graph reports it in wave 4.
|
|
107
|
+
*/
|
|
108
|
+
readonly unusedAxes: readonly string[];
|
|
109
|
+
}
|
|
110
|
+
export declare const registeredClasses: () => readonly RegisteredClass[];
|
|
111
|
+
/** Every distinct atomic rule in the build — the unit of deduplication. */
|
|
112
|
+
export declare const registeredAtoms: () => readonly AtomicRule[];
|
|
113
|
+
/** From the rendered class string back to the sheet key, for the matrix. */
|
|
114
|
+
export declare const classKeyOf: (className: string) => string | undefined;
|
|
115
|
+
/** Test-only: the registry is module state, and a spec must be able to reset it. */
|
|
116
|
+
export declare const resetStyleRegistry: () => void;
|
|
117
|
+
/**
|
|
118
|
+
* A budget of axes, declared by the sheet that spends it.
|
|
119
|
+
*
|
|
120
|
+
* Without it a component can multiply the matrix of every page that composes
|
|
121
|
+
* it, and nobody decided that: an axis added deep in a leaf shows up as a
|
|
122
|
+
* doubled capture bill three levels up. Declaring the axes makes the cost a
|
|
123
|
+
* choice rather than a consequence.
|
|
124
|
+
*
|
|
125
|
+
* The plan puts the budget on `craftComponent(..., { axes })`. It lives on the
|
|
126
|
+
* sheet here for the same reason the matrix takes sheets rather than
|
|
127
|
+
* components: a component's classes are only knowable by rendering it, and a
|
|
128
|
+
* budget that silently missed a child's sheet would read as a guarantee while
|
|
129
|
+
* being none.
|
|
130
|
+
*/
|
|
131
|
+
export type AxisSet = Readonly<Record<string, AnyAxisPoint>>;
|
|
132
|
+
/**
|
|
133
|
+
* Distributes over the union of declared sets on purpose.
|
|
134
|
+
*
|
|
135
|
+
* `Budget[number]` is a union, and `keyof` a union is the keys the members
|
|
136
|
+
* share — none, for two different axes. Read without distributing, a budget of
|
|
137
|
+
* two axes therefore declares nothing at all, and every sheet using it reports
|
|
138
|
+
* every axis as out of budget. The naked parameter is what makes it distribute.
|
|
139
|
+
*/
|
|
140
|
+
type AxesOfSet<Set> = Set extends AxisSet ? Set[keyof Set]['axis'] : never;
|
|
141
|
+
export type DeclaredAxes<Budget extends readonly AxisSet[]> = AxesOfSet<Budget[number]>;
|
|
142
|
+
/** The axes a sheet actually varies on, read off its declaration. */
|
|
143
|
+
export type PointsUsedIn<Sheet extends StyleSheet> = PointsIn<Sheet[keyof Sheet][number]>['axis'];
|
|
144
|
+
export type WithinBudget<Sheet extends StyleSheet, Budget extends readonly AxisSet[]> = [Budget] extends [never] ? unknown : [Exclude<PointsUsedIn<Sheet>, DeclaredAxes<Budget>>] extends [never] ? unknown : {
|
|
145
|
+
readonly [Axis in Exclude<PointsUsedIn<Sheet>, DeclaredAxes<Budget>> as `ERROR_axis_${Axis}_is_not_in_this_sheet_s_budget`]: 'Add it to the axes option, or stop varying on it. Every axis a sheet uses multiplies the visual matrix of every page that composes it.';
|
|
146
|
+
};
|
|
147
|
+
export interface StyleSheetOptions<Budget extends readonly AxisSet[]> {
|
|
148
|
+
/** The axes this sheet is allowed to vary on. */
|
|
149
|
+
readonly axes?: Budget;
|
|
150
|
+
}
|
|
151
|
+
export declare function craftStyles<const Sheet extends StyleSheet, const Budget extends readonly AxisSet[] = never>(prefix: string, sheet: Sheet, options?: StyleSheetOptions<Budget> & WithinBudget<Sheet, Budget>): CraftStyles<Sheet>;
|
|
152
|
+
export interface VisualScenario {
|
|
153
|
+
/** `base|dark|md` — sorted, stable, and the name of the baseline. */
|
|
154
|
+
readonly id: string;
|
|
155
|
+
readonly axes: Readonly<Record<string, string>>;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* The **full** cartesian product. No clever reduction here: a coverage that
|
|
159
|
+
* claims to be complete without being complete is worse than no coverage. The
|
|
160
|
+
* one reduction already banked happens upstream — only the points actually
|
|
161
|
+
* used are in the contract.
|
|
162
|
+
*
|
|
163
|
+
* `base` is implicit on every axis, hence the extra value: two axes with one
|
|
164
|
+
* point each make four scenarios, not one.
|
|
165
|
+
*/
|
|
166
|
+
export declare function scenarios(...keys: readonly string[]): VisualScenario[];
|
|
167
|
+
/**
|
|
168
|
+
* The error message **is** the API here.
|
|
169
|
+
*
|
|
170
|
+
* It has to say *where* to declare, why not elsewhere, and name the requester.
|
|
171
|
+
* Verbose for a human who already knows the answer; exactly right for an agent
|
|
172
|
+
* that would otherwise drop an `overflow` on the nearest parent — which is to
|
|
173
|
+
* say, write the next bug.
|
|
174
|
+
*
|
|
175
|
+
* The message is the **key** rather than the value, unlike the `ERROR_…`
|
|
176
|
+
* markers elsewhere in the repo. That is what makes it come out at the head of
|
|
177
|
+
* `Property '…' is missing` instead of being buried under the printed node type.
|
|
178
|
+
*/
|
|
179
|
+
export type ContextError<Message extends string> = {
|
|
180
|
+
readonly [Key in Message]: never;
|
|
181
|
+
};
|
|
182
|
+
/**
|
|
183
|
+
* The bare parameter `Payload` is not a flourish: a conditional distributes
|
|
184
|
+
* only over a bare parameter. Written straight onto
|
|
185
|
+
* `ChannelsOf<Node>['obligations']`, the test does not distribute, and
|
|
186
|
+
* `never extends Obligation<infer Id>` is **true** — `Id` then falls back to its
|
|
187
|
+
* constraint and is `string`. A tree with no open obligation would fail to
|
|
188
|
+
* seal, complaining about an obligation named `string`.
|
|
189
|
+
*/
|
|
190
|
+
type IdOf<Payload> = Payload extends Obligation<infer Id extends string> ? Id : never;
|
|
191
|
+
type UndischargedIds<Node> = IdOf<ChannelsOf<Node>['obligations']>;
|
|
192
|
+
export type SealCheck<Node> = [UndischargedIds<Node>] extends [never] ? unknown : ContextError<`'${UndischargedIds<Node>}' is required by a class in this subtree and nobody provides it. Add provides(${UndischargedIds<Node>}) on the layout component that owns the area — not on the direct parent, where the CSS effect would create a second context and move the bug instead of fixing it.`>;
|
|
193
|
+
/**
|
|
194
|
+
* Closes a tree: from here up, nobody else will answer.
|
|
195
|
+
*
|
|
196
|
+
* This is the only place an obligation becomes an error — until then it
|
|
197
|
+
* travels, because an ancestor still has the right to answer it.
|
|
198
|
+
*/
|
|
199
|
+
export declare function seal<const Node>(node: Node & SealCheck<Node>): Node;
|
|
200
|
+
export {};
|
|
201
|
+
//# sourceMappingURL=styles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../../../libs/style/src/lib/styles.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
/** Applies declarations under a condition. Nestable, and nothing else. */
|
|
2
|
+
export function when(at,
|
|
3
|
+
// The constraint is intersected on the parameter rather than placed on the
|
|
4
|
+
// type parameter: as a constraint it is resolved while `Point` is still being
|
|
5
|
+
// inferred, so `AllowedItems<Point>` falls back to the unconstrained branch
|
|
6
|
+
// and checks nothing. On the parameter it is checked once `Point` is known.
|
|
7
|
+
items) {
|
|
8
|
+
assertLive(at, items);
|
|
9
|
+
return { kind: 'when', at, items };
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* An intersection that no viewport can satisfy is a rule that will never apply.
|
|
13
|
+
*
|
|
14
|
+
* `when(above(bp.lg), [when(below(bp.sm), […])])` asks for "at least lg and
|
|
15
|
+
* under sm" — dead CSS that no test will ever catch, because there is nothing
|
|
16
|
+
* to see. It throws at sheet registration, which under the build plugin is a
|
|
17
|
+
* build failure: the plugin imports every `*.style.ts` in Node before emitting.
|
|
18
|
+
*
|
|
19
|
+
* The check is a runtime one rather than a type-level one because comparing two
|
|
20
|
+
* breakpoint positions in the type system needs their order as literals, and
|
|
21
|
+
* `defineBreakpoints` cannot hand those back — object key order is not a tuple.
|
|
22
|
+
*/
|
|
23
|
+
function assertLive(at, items) {
|
|
24
|
+
if (at.order === undefined)
|
|
25
|
+
return;
|
|
26
|
+
for (const item of items) {
|
|
27
|
+
if (!isConditional(item))
|
|
28
|
+
continue;
|
|
29
|
+
const inner = item.at;
|
|
30
|
+
if (inner.axis !== at.axis || inner.order === undefined)
|
|
31
|
+
continue;
|
|
32
|
+
const outerFloor = at.bound === 'above';
|
|
33
|
+
const innerCeiling = inner.bound === 'below';
|
|
34
|
+
if (outerFloor && innerCeiling && inner.order <= at.order) {
|
|
35
|
+
throw new Error(`craftStyles: '${at.axis}' is asked for at least '${at.point}' and below '${inner.point}' at once, which no viewport satisfies. The rule inside would never apply; drop it, or widen one of the two bounds.`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const classes = new Map();
|
|
40
|
+
const atoms = new Map();
|
|
41
|
+
const byClassName = new Map();
|
|
42
|
+
export const registeredClasses = () => [
|
|
43
|
+
...classes.values(),
|
|
44
|
+
];
|
|
45
|
+
/** Every distinct atomic rule in the build — the unit of deduplication. */
|
|
46
|
+
export const registeredAtoms = () => [...atoms.values()];
|
|
47
|
+
/** From the rendered class string back to the sheet key, for the matrix. */
|
|
48
|
+
export const classKeyOf = (className) => byClassName.get(className);
|
|
49
|
+
/** Test-only: the registry is module state, and a spec must be able to reset it. */
|
|
50
|
+
export const resetStyleRegistry = () => {
|
|
51
|
+
classes.clear();
|
|
52
|
+
atoms.clear();
|
|
53
|
+
byClassName.clear();
|
|
54
|
+
};
|
|
55
|
+
// ─── atomic class names ─────────────────────────────────────────────────────
|
|
56
|
+
const hash = (input) => {
|
|
57
|
+
let value = 0x811c9dc5;
|
|
58
|
+
for (let index = 0; index < input.length; index += 1) {
|
|
59
|
+
value ^= input.charCodeAt(index);
|
|
60
|
+
value = Math.imul(value, 0x01000193) >>> 0;
|
|
61
|
+
}
|
|
62
|
+
return value.toString(36).padStart(6, '0').slice(-6);
|
|
63
|
+
};
|
|
64
|
+
const slugify = (text) => text
|
|
65
|
+
.replace(/[^a-zA-Z0-9]+/g, '-')
|
|
66
|
+
.replace(/^-+|-+$/g, '')
|
|
67
|
+
.slice(0, 56);
|
|
68
|
+
/**
|
|
69
|
+
* The name is readable **and** collision-proof: a slug so that the DOM says
|
|
70
|
+
* what it applies, a hash of the full rule so two different rules cannot land
|
|
71
|
+
* on the same name after slugging. Being a pure function of the rule is what
|
|
72
|
+
* makes the name identical in the Node evaluation and in the browser — the
|
|
73
|
+
* build and the runtime agree without sharing anything.
|
|
74
|
+
*/
|
|
75
|
+
const atomicName = (conditions, property, value) => {
|
|
76
|
+
const scope = conditions
|
|
77
|
+
.map((point) => `${point.axis}:${point.point}`)
|
|
78
|
+
.join('|');
|
|
79
|
+
const identity = `${scope}{${property}:${value}}`;
|
|
80
|
+
return `${slugify(`${scope}-${property}-${value}`)}-${hash(identity)}`;
|
|
81
|
+
};
|
|
82
|
+
const isDeclaration = (item) => typeof item === 'object' &&
|
|
83
|
+
item !== null &&
|
|
84
|
+
typeof item.property === 'string' &&
|
|
85
|
+
typeof item.value === 'string';
|
|
86
|
+
const isConditional = (item) => typeof item === 'object' &&
|
|
87
|
+
item !== null &&
|
|
88
|
+
item.kind === 'when';
|
|
89
|
+
const isObligation = (item) => typeof item === 'object' &&
|
|
90
|
+
item !== null &&
|
|
91
|
+
typeof item.spec === 'object';
|
|
92
|
+
function addRule(walked, conditions, declaration) {
|
|
93
|
+
const className = atomicName(conditions, declaration.property, declaration.value);
|
|
94
|
+
const rule = {
|
|
95
|
+
className,
|
|
96
|
+
conditions,
|
|
97
|
+
property: declaration.property,
|
|
98
|
+
value: declaration.value,
|
|
99
|
+
unproven: declaration.unproven,
|
|
100
|
+
};
|
|
101
|
+
// Deduplication happens here, not in the emitter: two sheets writing
|
|
102
|
+
// `padding: 1rem` under the same condition converge on the same atom.
|
|
103
|
+
if (!atoms.has(className))
|
|
104
|
+
atoms.set(className, rule);
|
|
105
|
+
walked.rules.push(rule);
|
|
106
|
+
if (declaration.unproven)
|
|
107
|
+
walked.unproven.push(declaration.unproven);
|
|
108
|
+
}
|
|
109
|
+
function walk(items, conditions, walked) {
|
|
110
|
+
for (const item of items) {
|
|
111
|
+
if (Array.isArray(item)) {
|
|
112
|
+
walk(item, conditions, walked);
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
if (isConditional(item)) {
|
|
116
|
+
const points = walked.axes.get(item.at.axis) ?? new Set();
|
|
117
|
+
points.add(item.at.point);
|
|
118
|
+
walked.axes.set(item.at.axis, points);
|
|
119
|
+
walk(item.items, [...conditions, item.at], walked);
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
if (isDeclaration(item)) {
|
|
123
|
+
addRule(walked, conditions, item);
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
if (isObligation(item)) {
|
|
127
|
+
const entry = item;
|
|
128
|
+
if (entry.kind === 'requires')
|
|
129
|
+
walked.requires.push(entry.spec.id);
|
|
130
|
+
if (entry.kind === 'violates')
|
|
131
|
+
walked.violates.push(entry.spec.id);
|
|
132
|
+
if (entry.kind === 'provides') {
|
|
133
|
+
walked.provides.push(entry.spec.id);
|
|
134
|
+
// The discharge and its CSS effect are inseparable: claiming to
|
|
135
|
+
// provide a scroll port without laying down the overflow would be a
|
|
136
|
+
// lie the type system could not catch.
|
|
137
|
+
for (const declaration of entry.spec.effect) {
|
|
138
|
+
addRule(walked, conditions, declaration);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
export function craftStyles(prefix, sheet,
|
|
145
|
+
// The budget check rides on the **third** parameter, not the second: on the
|
|
146
|
+
// sheet it would be evaluated while `Budget` is still being inferred from
|
|
147
|
+
// `options`, and would check nothing. Same inference-order trap as the axis
|
|
148
|
+
// write constraint, and the same fix — check where both are known.
|
|
149
|
+
options = {}) {
|
|
150
|
+
const budget = options.axes
|
|
151
|
+
? new Set(options.axes.flatMap((set) => Object.values(set).map((point) => point.axis)))
|
|
152
|
+
: undefined;
|
|
153
|
+
const entries = Object.entries(sheet).map(([key, items]) => {
|
|
154
|
+
const classKey = `${prefix}-${key}`;
|
|
155
|
+
if (classes.has(classKey)) {
|
|
156
|
+
throw new Error(`craftStyles: class '${classKey}' is already declared. Two sheets share the prefix '${prefix}'.`);
|
|
157
|
+
}
|
|
158
|
+
const walked = {
|
|
159
|
+
rules: [],
|
|
160
|
+
axes: new Map(),
|
|
161
|
+
unproven: [],
|
|
162
|
+
requires: [],
|
|
163
|
+
provides: [],
|
|
164
|
+
violates: [],
|
|
165
|
+
};
|
|
166
|
+
walk(items, [], walked);
|
|
167
|
+
// Within one class, a later declaration replaces an earlier one for the
|
|
168
|
+
// same property under the same conditions. Keeping both would leave the
|
|
169
|
+
// winner to stylesheet order — which is alphabetical here, so `font(text.xs)`
|
|
170
|
+
// followed by `lineHeight(num(1))` would silently resolve the wrong way.
|
|
171
|
+
// Cascade order inside a sheet must be the order that was written.
|
|
172
|
+
const kept = new Map();
|
|
173
|
+
for (const rule of walked.rules) {
|
|
174
|
+
const scope = rule.conditions
|
|
175
|
+
.map((point) => `${point.axis}:${point.point}`)
|
|
176
|
+
.join('|');
|
|
177
|
+
kept.set(`${scope}|${rule.property}`, rule);
|
|
178
|
+
}
|
|
179
|
+
const rules = [...kept.values()];
|
|
180
|
+
if (budget) {
|
|
181
|
+
for (const axis of walked.axes.keys()) {
|
|
182
|
+
if (!budget.has(axis)) {
|
|
183
|
+
throw new Error(`craftStyles: '${classKey}' varies on the axis '${axis}', which is not in its budget. Every axis a sheet uses multiplies the visual matrix of every page that composes it, so the cost has to be a decision: add '${axis}' to the axes option, or stop varying on it.`);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
const className = rules.map((rule) => rule.className).join(' ');
|
|
188
|
+
classes.set(classKey, {
|
|
189
|
+
key: classKey,
|
|
190
|
+
className,
|
|
191
|
+
rules,
|
|
192
|
+
axes: Object.fromEntries([...walked.axes].map(([axis, points]) => [axis, [...points].sort()])),
|
|
193
|
+
unproven: walked.unproven,
|
|
194
|
+
requires: walked.requires,
|
|
195
|
+
provides: walked.provides,
|
|
196
|
+
violates: walked.violates,
|
|
197
|
+
unusedAxes: budget
|
|
198
|
+
? [...budget].filter((axis) => !walked.axes.has(axis)).sort()
|
|
199
|
+
: [],
|
|
200
|
+
});
|
|
201
|
+
byClassName.set(className, classKey);
|
|
202
|
+
return [key, className];
|
|
203
|
+
});
|
|
204
|
+
return Object.fromEntries(entries);
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* The **full** cartesian product. No clever reduction here: a coverage that
|
|
208
|
+
* claims to be complete without being complete is worse than no coverage. The
|
|
209
|
+
* one reduction already banked happens upstream — only the points actually
|
|
210
|
+
* used are in the contract.
|
|
211
|
+
*
|
|
212
|
+
* `base` is implicit on every axis, hence the extra value: two axes with one
|
|
213
|
+
* point each make four scenarios, not one.
|
|
214
|
+
*/
|
|
215
|
+
export function scenarios(...keys) {
|
|
216
|
+
const axes = new Map();
|
|
217
|
+
for (const key of keys) {
|
|
218
|
+
const registered = classes.get(key) ?? classes.get(classKeyOf(key) ?? '');
|
|
219
|
+
if (!registered)
|
|
220
|
+
continue;
|
|
221
|
+
for (const [axis, points] of Object.entries(registered.axes)) {
|
|
222
|
+
const known = axes.get(axis) ?? new Set();
|
|
223
|
+
points.forEach((point) => known.add(point));
|
|
224
|
+
axes.set(axis, known);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
const ordered = [...axes].sort(([left], [right]) => left.localeCompare(right));
|
|
228
|
+
let combinations = [{}];
|
|
229
|
+
for (const [axis, points] of ordered) {
|
|
230
|
+
const values = ['base', ...[...points].sort()];
|
|
231
|
+
combinations = combinations.flatMap((combination) => values.map((value) => ({ ...combination, [axis]: value })));
|
|
232
|
+
}
|
|
233
|
+
return combinations.map((combination) => ({
|
|
234
|
+
id: ordered.map(([axis]) => combination[axis]).join('|') || 'base',
|
|
235
|
+
axes: combination,
|
|
236
|
+
}));
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Closes a tree: from here up, nobody else will answer.
|
|
240
|
+
*
|
|
241
|
+
* This is the only place an obligation becomes an error — until then it
|
|
242
|
+
* travels, because an ancestor still has the right to answer it.
|
|
243
|
+
*/
|
|
244
|
+
export function seal(node) {
|
|
245
|
+
return node;
|
|
246
|
+
}
|
|
247
|
+
//# sourceMappingURL=styles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styles.js","sourceRoot":"","sources":["../../../../../libs/style/src/lib/styles.ts"],"names":[],"mappings":"AA+DA,0EAA0E;AAC1E,MAAM,UAAU,IAAI,CAIlB,EAAS;AACT,2EAA2E;AAC3E,8EAA8E;AAC9E,4EAA4E;AAC5E,4EAA4E;AAC5E,KAAkC;IAElC,UAAU,CAAC,EAAE,EAAE,KAA6B,CAAC,CAAC;IAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;AACrC,CAAC;AAED;;;;;;;;;;;GAWG;AACH,SAAS,UAAU,CAAC,EAAgB,EAAE,KAA2B;IAC/D,IAAI,EAAE,CAAC,KAAK,KAAK,SAAS;QAAE,OAAO;IACnC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;YAAE,SAAS;QACnC,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC;QACtB,IAAI,KAAK,CAAC,IAAI,KAAK,EAAE,CAAC,IAAI,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS;YAAE,SAAS;QAClE,MAAM,UAAU,GAAG,EAAE,CAAC,KAAK,KAAK,OAAO,CAAC;QACxC,MAAM,YAAY,GAAG,KAAK,CAAC,KAAK,KAAK,OAAO,CAAC;QAC7C,IAAI,UAAU,IAAI,YAAY,IAAI,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,KAAK,EAAE,CAAC;YAC1D,MAAM,IAAI,KAAK,CACb,iBAAiB,EAAE,CAAC,IAAI,4BAA4B,EAAE,CAAC,KAAK,gBAAgB,KAAK,CAAC,KAAK,qHAAqH,CAC7M,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC;AAgHD,MAAM,OAAO,GAAG,IAAI,GAAG,EAA2B,CAAC;AACnD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAsB,CAAC;AAC5C,MAAM,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAC;AAE9C,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAA+B,EAAE,CAAC;IACjE,GAAG,OAAO,CAAC,MAAM,EAAE;CACpB,CAAC;AAEF,2EAA2E;AAC3E,MAAM,CAAC,MAAM,eAAe,GAAG,GAA0B,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;AAEhF,4EAA4E;AAC5E,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,SAAiB,EAAsB,EAAE,CAClE,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;AAE7B,oFAAoF;AACpF,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAS,EAAE;IAC3C,OAAO,CAAC,KAAK,EAAE,CAAC;IAChB,KAAK,CAAC,KAAK,EAAE,CAAC;IACd,WAAW,CAAC,KAAK,EAAE,CAAC;AACtB,CAAC,CAAC;AAEF,+EAA+E;AAE/E,MAAM,IAAI,GAAG,CAAC,KAAa,EAAU,EAAE;IACrC,IAAI,KAAK,GAAG,UAAU,CAAC;IACvB,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACrD,KAAK,IAAI,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QACjC,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC;IAC7C,CAAC;IACD,OAAO,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AACvD,CAAC,CAAC;AAEF,MAAM,OAAO,GAAG,CAAC,IAAY,EAAU,EAAE,CACvC,IAAI;KACD,OAAO,CAAC,gBAAgB,EAAE,GAAG,CAAC;KAC9B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;KACvB,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAElB;;;;;;GAMG;AACH,MAAM,UAAU,GAAG,CACjB,UAAmC,EACnC,QAAgB,EAChB,KAAa,EACL,EAAE;IACV,MAAM,KAAK,GAAG,UAAU;SACrB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;SAC9C,IAAI,CAAC,GAAG,CAAC,CAAC;IACb,MAAM,QAAQ,GAAG,GAAG,KAAK,IAAI,QAAQ,IAAI,KAAK,GAAG,CAAC;IAClD,OAAO,GAAG,OAAO,CAAC,GAAG,KAAK,IAAI,QAAQ,IAAI,KAAK,EAAE,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;AACzE,CAAC,CAAC;AAaF,MAAM,aAAa,GAAG,CAAC,IAAa,EAAuB,EAAE,CAC3D,OAAO,IAAI,KAAK,QAAQ;IACxB,IAAI,KAAK,IAAI;IACb,OAAQ,IAAoB,CAAC,QAAQ,KAAK,QAAQ;IAClD,OAAQ,IAAoB,CAAC,KAAK,KAAK,QAAQ,CAAC;AAElD,MAAM,aAAa,GAAG,CACpB,IAAa,EAC4C,EAAE,CAC3D,OAAO,IAAI,KAAK,QAAQ;IACxB,IAAI,KAAK,IAAI;IACZ,IAA2B,CAAC,IAAI,KAAK,MAAM,CAAC;AAE/C,MAAM,YAAY,GAAG,CACnB,IAAa,EAC6D,EAAE,CAC5E,OAAO,IAAI,KAAK,QAAQ;IACxB,IAAI,KAAK,IAAI;IACb,OAAQ,IAA2B,CAAC,IAAI,KAAK,QAAQ,CAAC;AAExD,SAAS,OAAO,CACd,MAAc,EACd,UAAmC,EACnC,WAAwB;IAExB,MAAM,SAAS,GAAG,UAAU,CAC1B,UAAU,EACV,WAAW,CAAC,QAAQ,EACpB,WAAW,CAAC,KAAK,CAClB,CAAC;IACF,MAAM,IAAI,GAAe;QACvB,SAAS;QACT,UAAU;QACV,QAAQ,EAAE,WAAW,CAAC,QAAQ;QAC9B,KAAK,EAAE,WAAW,CAAC,KAAK;QACxB,QAAQ,EAAE,WAAW,CAAC,QAAQ;KAC/B,CAAC;IACF,qEAAqE;IACrE,sEAAsE;IACtE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC;QAAE,KAAK,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IACtD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxB,IAAI,WAAW,CAAC,QAAQ;QAAE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;AACvE,CAAC;AAED,SAAS,IAAI,CACX,KAA2B,EAC3B,UAAmC,EACnC,MAAc;IAEd,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,IAAI,CAAC,IAA4B,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;YACvD,SAAS;QACX,CAAC;QACD,IAAI,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,EAAU,CAAC;YAClE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;YAC1B,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YACtC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,UAAU,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;YACnD,SAAS;QACX,CAAC;QACD,IAAI,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;YAClC,SAAS;QACX,CAAC;QACD,IAAI,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,MAAM,KAAK,GAAG,IAGb,CAAC;YACF,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU;gBAAE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACnE,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU;gBAAE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACnE,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;gBAC9B,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACpC,gEAAgE;gBAChE,oEAAoE;gBACpE,uCAAuC;gBACvC,KAAK,MAAM,WAAW,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;oBAC5C,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;gBAC3C,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AA2DD,MAAM,UAAU,WAAW,CAIzB,MAAc,EACd,KAAY;AACZ,4EAA4E;AAC5E,0EAA0E;AAC1E,4EAA4E;AAC5E,mEAAmE;AACnE,UACgC,EAAW;IAE3C,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI;QACzB,CAAC,CAAC,IAAI,GAAG,CACL,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAC3B,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAC9C,CACF;QACH,CAAC,CAAC,SAAS,CAAC;IACd,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;QACzD,MAAM,QAAQ,GAAG,GAAG,MAAM,IAAI,GAAG,EAAE,CAAC;QACpC,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CACb,uBAAuB,QAAQ,uDAAuD,MAAM,IAAI,CACjG,CAAC;QACJ,CAAC;QACD,MAAM,MAAM,GAAW;YACrB,KAAK,EAAE,EAAE;YACT,IAAI,EAAE,IAAI,GAAG,EAAE;YACf,QAAQ,EAAE,EAAE;YACZ,QAAQ,EAAE,EAAE;YACZ,QAAQ,EAAE,EAAE;YACZ,QAAQ,EAAE,EAAE;SACb,CAAC;QACF,IAAI,CAAC,KAAK,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;QAExB,wEAAwE;QACxE,wEAAwE;QACxE,8EAA8E;QAC9E,yEAAyE;QACzE,mEAAmE;QACnE,MAAM,IAAI,GAAG,IAAI,GAAG,EAAsB,CAAC;QAC3C,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YAChC,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU;iBAC1B,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;iBAC9C,IAAI,CAAC,GAAG,CAAC,CAAC;YACb,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE,EAAE,IAAI,CAAC,CAAC;QAC9C,CAAC;QACD,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QACjC,IAAI,MAAM,EAAE,CAAC;YACX,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;gBACtC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;oBACtB,MAAM,IAAI,KAAK,CACb,iBAAiB,QAAQ,yBAAyB,IAAI,8JAA8J,IAAI,8CAA8C,CACvQ,CAAC;gBACJ,CAAC;YACH,CAAC;QACH,CAAC;QAED,MAAM,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChE,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE;YACpB,GAAG,EAAE,QAAQ;YACb,SAAS;YACT,KAAK;YACL,IAAI,EAAE,MAAM,CAAC,WAAW,CACtB,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CACrE;YACD,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,UAAU,EAAE,MAAM;gBAChB,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE;gBAC7D,CAAC,CAAC,EAAE;SACP,CAAC,CAAC;QACH,WAAW,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QACrC,OAAO,CAAC,GAAG,EAAE,SAAS,CAAU,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC,WAAW,CAAC,OAAO,CAAuB,CAAC;AAC3D,CAAC;AAUD;;;;;;;;GAQG;AACH,MAAM,UAAU,SAAS,CAAC,GAAG,IAAuB;IAClD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAuB,CAAC;IAC5C,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1E,IAAI,CAAC,UAAU;YAAE,SAAS;QAC1B,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,EAAU,CAAC;YAClD,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;YAC5C,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,CACjD,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAC1B,CAAC;IACF,IAAI,YAAY,GAA6B,CAAC,EAAE,CAAC,CAAC;IAClD,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACrC,MAAM,MAAM,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAC/C,YAAY,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,EAAE,CAClD,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,WAAW,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAC3D,CAAC;IACJ,CAAC;IAED,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QACxC,EAAE,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,MAAM;QAClE,IAAI,EAAE,WAAW;KAClB,CAAC,CAAC,CAAC;AACN,CAAC;AAqCD;;;;;GAKG;AACH,MAAM,UAAU,IAAI,CAAa,IAA4B;IAC3D,OAAO,IAAY,CAAC;AACtB,CAAC","sourcesContent":["/**\n * `craftStyles`: a sheet whose **variant contract** is inferred, not declared,\n * and whose CSS is atomic and deduplicated.\n *\n * Two properties make the rest of the system possible:\n *\n * - Only the breakpoints **actually used** enter the contract. An axis that\n * defines six points but which a component crosses at one does not produce\n * six scenarios; it produces two (`base` and that one).\n * - A declaration under a condition is one **atomic class**, shared by every\n * sheet that writes it. Output then grows with the vocabulary, not with the\n * number of components — which is what keeps the emitted stylesheet flat as\n * the app grows.\n *\n * Conjunction is nesting and nothing else — `when(a, [when(b, […])])`. A second\n * spelling would mean two identical components could produce two different\n * contracts.\n */\nimport type {\n ChannelsOf,\n CraftChannels,\n CraftChannelsCarrier,\n MergeChannelUnion,\n} from '@craft-ts/core';\nimport type { AnyAxisPoint, AxisPoint, WritesSyntaxOf } from './axes/index.ts';\nimport type { VarWrite } from './css-vars.ts';\nimport type { Declaration } from './props/factory.ts';\nimport type {\n Obligation,\n ObligationEntry,\n ObligationSpec,\n} from './obligations.ts';\n\ndeclare const VARIANTS: unique symbol;\n\nexport interface Conditional<\n Point extends AnyAxisPoint,\n Items extends readonly unknown[],\n> {\n readonly kind: 'when';\n readonly at: Point;\n readonly items: Items;\n}\n\nexport type SheetItem =\n | Declaration\n | readonly Declaration[]\n | ObligationEntry\n | Conditional<AnyAxisPoint, readonly any[]>;\n\n/**\n * What an axis is allowed to contain.\n *\n * An unconstrained axis takes anything a sheet takes. An axis declared with\n * `writes: onlyVarsOfKind(kind.color)` takes **only** writes of that kind —\n * no properties, and no nesting, because an axis that may only repaint has\n * nothing to conjoin with. That constraint is what makes such an axis provably\n * orthogonal to the axes that move boxes, without analysing any CSS.\n */\nexport type AllowedItems<Point> = [WritesSyntaxOf<Point>] extends [never]\n ? readonly SheetItem[]\n : readonly VarWrite<WritesSyntaxOf<Point>>[];\n\n/** Applies declarations under a condition. Nestable, and nothing else. */\nexport function when<\n const Point extends AnyAxisPoint,\n const Items extends readonly SheetItem[],\n>(\n at: Point,\n // The constraint is intersected on the parameter rather than placed on the\n // type parameter: as a constraint it is resolved while `Point` is still being\n // inferred, so `AllowedItems<Point>` falls back to the unconstrained branch\n // and checks nothing. On the parameter it is checked once `Point` is known.\n items: Items & AllowedItems<Point>,\n): Conditional<Point, Items> {\n assertLive(at, items as readonly SheetItem[]);\n return { kind: 'when', at, items };\n}\n\n/**\n * An intersection that no viewport can satisfy is a rule that will never apply.\n *\n * `when(above(bp.lg), [when(below(bp.sm), […])])` asks for \"at least lg and\n * under sm\" — dead CSS that no test will ever catch, because there is nothing\n * to see. It throws at sheet registration, which under the build plugin is a\n * build failure: the plugin imports every `*.style.ts` in Node before emitting.\n *\n * The check is a runtime one rather than a type-level one because comparing two\n * breakpoint positions in the type system needs their order as literals, and\n * `defineBreakpoints` cannot hand those back — object key order is not a tuple.\n */\nfunction assertLive(at: AnyAxisPoint, items: readonly SheetItem[]): void {\n if (at.order === undefined) return;\n for (const item of items) {\n if (!isConditional(item)) continue;\n const inner = item.at;\n if (inner.axis !== at.axis || inner.order === undefined) continue;\n const outerFloor = at.bound === 'above';\n const innerCeiling = inner.bound === 'below';\n if (outerFloor && innerCeiling && inner.order <= at.order) {\n throw new Error(\n `craftStyles: '${at.axis}' is asked for at least '${at.point}' and below '${inner.point}' at once, which no viewport satisfies. The rule inside would never apply; drop it, or widen one of the two bounds.`,\n );\n }\n }\n}\n\n// ─── contract inference ─────────────────────────────────────────────────────\n\ntype PointsIn<Item> =\n Item extends Conditional<infer Point, infer Items>\n ? Point | PointsIn<Items[number]>\n : Item extends readonly (infer Child)[]\n ? PointsIn<Child>\n : never;\n\n/** axis → the points **actually** used. Never all the points of the axis. */\nexport type VariantContract<Points extends AnyAxisPoint> = {\n readonly [Axis in Points['axis']]: Extract<\n Points,\n AxisPoint<Axis, string>\n >['point'];\n};\n\ntype EntriesIn<Item, Kind extends string> =\n Item extends Conditional<AnyAxisPoint, infer Items>\n ? EntriesIn<Items[number], Kind>\n : Item extends readonly (infer Child)[]\n ? EntriesIn<Child, Kind>\n : Item extends {\n readonly kind: Kind;\n readonly spec: {\n readonly id: infer Id extends string;\n readonly explain: infer Explain extends string;\n };\n }\n ? Obligation<Id, Explain>\n : never;\n\n/**\n * The channel a class lays on the node carrying it. The core does not know what\n * it transports: to it, `Obligation<'scrollPort.block'>` is an opaque payload\n * that an `Exclude` cancels.\n */\nexport type ChannelsOfSheet<Item> = MergeChannelUnion<{\n readonly accumulate: never;\n readonly obligations: EntriesIn<Item, 'requires'>;\n readonly discharges: EntriesIn<Item, 'provides'>;\n readonly violates: EntriesIn<Item, 'violates'>;\n}>;\n\n/**\n * A branded class. At runtime it is a string — the existing renderer sets it\n * as-is — but its type carries the variants it produces and the channel it\n * opens. What typing cannot prevent (writing `class: 'badge'` by hand) the\n * `no-raw-class` ESLint rule forbids: partial tightness buys 0 % of the\n * guarantee, not 90 %.\n */\nexport type CraftClass<\n Points extends AnyAxisPoint = never,\n Channels extends CraftChannels = never,\n> = string &\n CraftChannelsCarrier<Channels> & {\n readonly [VARIANTS]?: Points;\n };\n\n/** A class's contract, readable from outside — what the matrix unfolds. */\nexport type VariantsOf<Class> = typeof VARIANTS extends keyof Class\n ? Class extends { readonly [VARIANTS]?: infer Points }\n ? [Points] extends [AnyAxisPoint]\n ? VariantContract<Points>\n : Record<never, never>\n : Record<never, never>\n : Record<never, never>;\n\nexport type StyleSheet = Readonly<Record<string, readonly SheetItem[]>>;\n\nexport type CraftStyles<Sheet extends StyleSheet> = {\n readonly [Key in keyof Sheet]: CraftClass<\n PointsIn<Sheet[Key][number]>,\n ChannelsOfSheet<Sheet[Key][number]>\n >;\n};\n\n// ─── the atomic registry ────────────────────────────────────────────────────\n// A class is a string, so it cannot carry its own rules. The registry holds\n// them instead — and it is also what the build plugin reads to emit the CSS\n// and the JSON dump the dependency graph consumes.\n\nexport interface AtomicRule {\n readonly className: string;\n /** Outer to inner, in nesting order. */\n readonly conditions: readonly AnyAxisPoint[];\n readonly property: string;\n readonly value: string;\n readonly unproven: string;\n}\n\nexport interface RegisteredClass {\n /** `badge-root` — stable, human-readable, and the key the matrix uses. */\n readonly key: string;\n /** The space-separated atomic classes actually set on the element. */\n readonly className: string;\n readonly rules: readonly AtomicRule[];\n readonly axes: Readonly<Record<string, readonly string[]>>;\n readonly unproven: readonly string[];\n readonly requires: readonly string[];\n readonly provides: readonly string[];\n readonly violates: readonly string[];\n /**\n * Axes the sheet declared and never used. Not an error — a budget is an\n * upper bound — but it is dead weight a reader takes for a real variation,\n * so the graph reports it in wave 4.\n */\n readonly unusedAxes: readonly string[];\n}\n\nconst classes = new Map<string, RegisteredClass>();\nconst atoms = new Map<string, AtomicRule>();\nconst byClassName = new Map<string, string>();\n\nexport const registeredClasses = (): readonly RegisteredClass[] => [\n ...classes.values(),\n];\n\n/** Every distinct atomic rule in the build — the unit of deduplication. */\nexport const registeredAtoms = (): readonly AtomicRule[] => [...atoms.values()];\n\n/** From the rendered class string back to the sheet key, for the matrix. */\nexport const classKeyOf = (className: string): string | undefined =>\n byClassName.get(className);\n\n/** Test-only: the registry is module state, and a spec must be able to reset it. */\nexport const resetStyleRegistry = (): void => {\n classes.clear();\n atoms.clear();\n byClassName.clear();\n};\n\n// ─── atomic class names ─────────────────────────────────────────────────────\n\nconst hash = (input: string): string => {\n let value = 0x811c9dc5;\n for (let index = 0; index < input.length; index += 1) {\n value ^= input.charCodeAt(index);\n value = Math.imul(value, 0x01000193) >>> 0;\n }\n return value.toString(36).padStart(6, '0').slice(-6);\n};\n\nconst slugify = (text: string): string =>\n text\n .replace(/[^a-zA-Z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 56);\n\n/**\n * The name is readable **and** collision-proof: a slug so that the DOM says\n * what it applies, a hash of the full rule so two different rules cannot land\n * on the same name after slugging. Being a pure function of the rule is what\n * makes the name identical in the Node evaluation and in the browser — the\n * build and the runtime agree without sharing anything.\n */\nconst atomicName = (\n conditions: readonly AnyAxisPoint[],\n property: string,\n value: string,\n): string => {\n const scope = conditions\n .map((point) => `${point.axis}:${point.point}`)\n .join('|');\n const identity = `${scope}{${property}:${value}}`;\n return `${slugify(`${scope}-${property}-${value}`)}-${hash(identity)}`;\n};\n\n// ─── sheet walking ──────────────────────────────────────────────────────────\n\ninterface Walked {\n readonly rules: AtomicRule[];\n readonly axes: Map<string, Set<string>>;\n readonly unproven: string[];\n readonly requires: string[];\n readonly provides: string[];\n readonly violates: string[];\n}\n\nconst isDeclaration = (item: unknown): item is Declaration =>\n typeof item === 'object' &&\n item !== null &&\n typeof (item as Declaration).property === 'string' &&\n typeof (item as Declaration).value === 'string';\n\nconst isConditional = (\n item: unknown,\n): item is Conditional<AnyAxisPoint, readonly SheetItem[]> =>\n typeof item === 'object' &&\n item !== null &&\n (item as { kind?: unknown }).kind === 'when';\n\nconst isObligation = (\n item: unknown,\n): item is { readonly kind: string; readonly spec: ObligationSpec<string> } =>\n typeof item === 'object' &&\n item !== null &&\n typeof (item as { spec?: unknown }).spec === 'object';\n\nfunction addRule(\n walked: Walked,\n conditions: readonly AnyAxisPoint[],\n declaration: Declaration,\n): void {\n const className = atomicName(\n conditions,\n declaration.property,\n declaration.value,\n );\n const rule: AtomicRule = {\n className,\n conditions,\n property: declaration.property,\n value: declaration.value,\n unproven: declaration.unproven,\n };\n // Deduplication happens here, not in the emitter: two sheets writing\n // `padding: 1rem` under the same condition converge on the same atom.\n if (!atoms.has(className)) atoms.set(className, rule);\n walked.rules.push(rule);\n if (declaration.unproven) walked.unproven.push(declaration.unproven);\n}\n\nfunction walk(\n items: readonly SheetItem[],\n conditions: readonly AnyAxisPoint[],\n walked: Walked,\n): void {\n for (const item of items) {\n if (Array.isArray(item)) {\n walk(item as readonly SheetItem[], conditions, walked);\n continue;\n }\n if (isConditional(item)) {\n const points = walked.axes.get(item.at.axis) ?? new Set<string>();\n points.add(item.at.point);\n walked.axes.set(item.at.axis, points);\n walk(item.items, [...conditions, item.at], walked);\n continue;\n }\n if (isDeclaration(item)) {\n addRule(walked, conditions, item);\n continue;\n }\n if (isObligation(item)) {\n const entry = item as {\n readonly kind: string;\n readonly spec: ObligationSpec<string>;\n };\n if (entry.kind === 'requires') walked.requires.push(entry.spec.id);\n if (entry.kind === 'violates') walked.violates.push(entry.spec.id);\n if (entry.kind === 'provides') {\n walked.provides.push(entry.spec.id);\n // The discharge and its CSS effect are inseparable: claiming to\n // provide a scroll port without laying down the overflow would be a\n // lie the type system could not catch.\n for (const declaration of entry.spec.effect) {\n addRule(walked, conditions, declaration);\n }\n }\n }\n }\n}\n\n/**\n * A budget of axes, declared by the sheet that spends it.\n *\n * Without it a component can multiply the matrix of every page that composes\n * it, and nobody decided that: an axis added deep in a leaf shows up as a\n * doubled capture bill three levels up. Declaring the axes makes the cost a\n * choice rather than a consequence.\n *\n * The plan puts the budget on `craftComponent(..., { axes })`. It lives on the\n * sheet here for the same reason the matrix takes sheets rather than\n * components: a component's classes are only knowable by rendering it, and a\n * budget that silently missed a child's sheet would read as a guarantee while\n * being none.\n */\nexport type AxisSet = Readonly<Record<string, AnyAxisPoint>>;\n\n/**\n * Distributes over the union of declared sets on purpose.\n *\n * `Budget[number]` is a union, and `keyof` a union is the keys the members\n * share — none, for two different axes. Read without distributing, a budget of\n * two axes therefore declares nothing at all, and every sheet using it reports\n * every axis as out of budget. The naked parameter is what makes it distribute.\n */\ntype AxesOfSet<Set> = Set extends AxisSet ? Set[keyof Set]['axis'] : never;\n\nexport type DeclaredAxes<Budget extends readonly AxisSet[]> = AxesOfSet<\n Budget[number]\n>;\n\n/** The axes a sheet actually varies on, read off its declaration. */\nexport type PointsUsedIn<Sheet extends StyleSheet> = PointsIn<\n Sheet[keyof Sheet][number]\n>['axis'];\n\nexport type WithinBudget<\n Sheet extends StyleSheet,\n Budget extends readonly AxisSet[],\n> = [Budget] extends [never]\n ? // No budget declared: the sheet is unbudgeted, and nothing is checked.\n // `axes: []` is not the same thing — that declares a budget of nothing,\n // and any axis the sheet uses is then out of it.\n unknown\n : [Exclude<PointsUsedIn<Sheet>, DeclaredAxes<Budget>>] extends [never]\n ? unknown\n : {\n readonly [Axis in Exclude<\n PointsUsedIn<Sheet>,\n DeclaredAxes<Budget>\n > as `ERROR_axis_${Axis}_is_not_in_this_sheet_s_budget`]: 'Add it to the axes option, or stop varying on it. Every axis a sheet uses multiplies the visual matrix of every page that composes it.';\n };\n\nexport interface StyleSheetOptions<Budget extends readonly AxisSet[]> {\n /** The axes this sheet is allowed to vary on. */\n readonly axes?: Budget;\n}\n\nexport function craftStyles<\n const Sheet extends StyleSheet,\n const Budget extends readonly AxisSet[] = never,\n>(\n prefix: string,\n sheet: Sheet,\n // The budget check rides on the **third** parameter, not the second: on the\n // sheet it would be evaluated while `Budget` is still being inferred from\n // `options`, and would check nothing. Same inference-order trap as the axis\n // write constraint, and the same fix — check where both are known.\n options: StyleSheetOptions<Budget> &\n WithinBudget<Sheet, Budget> = {} as never,\n): CraftStyles<Sheet> {\n const budget = options.axes\n ? new Set(\n options.axes.flatMap((set) =>\n Object.values(set).map((point) => point.axis),\n ),\n )\n : undefined;\n const entries = Object.entries(sheet).map(([key, items]) => {\n const classKey = `${prefix}-${key}`;\n if (classes.has(classKey)) {\n throw new Error(\n `craftStyles: class '${classKey}' is already declared. Two sheets share the prefix '${prefix}'.`,\n );\n }\n const walked: Walked = {\n rules: [],\n axes: new Map(),\n unproven: [],\n requires: [],\n provides: [],\n violates: [],\n };\n walk(items, [], walked);\n\n // Within one class, a later declaration replaces an earlier one for the\n // same property under the same conditions. Keeping both would leave the\n // winner to stylesheet order — which is alphabetical here, so `font(text.xs)`\n // followed by `lineHeight(num(1))` would silently resolve the wrong way.\n // Cascade order inside a sheet must be the order that was written.\n const kept = new Map<string, AtomicRule>();\n for (const rule of walked.rules) {\n const scope = rule.conditions\n .map((point) => `${point.axis}:${point.point}`)\n .join('|');\n kept.set(`${scope}|${rule.property}`, rule);\n }\n const rules = [...kept.values()];\n if (budget) {\n for (const axis of walked.axes.keys()) {\n if (!budget.has(axis)) {\n throw new Error(\n `craftStyles: '${classKey}' varies on the axis '${axis}', which is not in its budget. Every axis a sheet uses multiplies the visual matrix of every page that composes it, so the cost has to be a decision: add '${axis}' to the axes option, or stop varying on it.`,\n );\n }\n }\n }\n\n const className = rules.map((rule) => rule.className).join(' ');\n classes.set(classKey, {\n key: classKey,\n className,\n rules,\n axes: Object.fromEntries(\n [...walked.axes].map(([axis, points]) => [axis, [...points].sort()]),\n ),\n unproven: walked.unproven,\n requires: walked.requires,\n provides: walked.provides,\n violates: walked.violates,\n unusedAxes: budget\n ? [...budget].filter((axis) => !walked.axes.has(axis)).sort()\n : [],\n });\n byClassName.set(className, classKey);\n return [key, className] as const;\n });\n\n return Object.fromEntries(entries) as CraftStyles<Sheet>;\n}\n\n// ─── scenario matrix ────────────────────────────────────────────────────────\n\nexport interface VisualScenario {\n /** `base|dark|md` — sorted, stable, and the name of the baseline. */\n readonly id: string;\n readonly axes: Readonly<Record<string, string>>;\n}\n\n/**\n * The **full** cartesian product. No clever reduction here: a coverage that\n * claims to be complete without being complete is worse than no coverage. The\n * one reduction already banked happens upstream — only the points actually\n * used are in the contract.\n *\n * `base` is implicit on every axis, hence the extra value: two axes with one\n * point each make four scenarios, not one.\n */\nexport function scenarios(...keys: readonly string[]): VisualScenario[] {\n const axes = new Map<string, Set<string>>();\n for (const key of keys) {\n const registered = classes.get(key) ?? classes.get(classKeyOf(key) ?? '');\n if (!registered) continue;\n for (const [axis, points] of Object.entries(registered.axes)) {\n const known = axes.get(axis) ?? new Set<string>();\n points.forEach((point) => known.add(point));\n axes.set(axis, known);\n }\n }\n\n const ordered = [...axes].sort(([left], [right]) =>\n left.localeCompare(right),\n );\n let combinations: Record<string, string>[] = [{}];\n for (const [axis, points] of ordered) {\n const values = ['base', ...[...points].sort()];\n combinations = combinations.flatMap((combination) =>\n values.map((value) => ({ ...combination, [axis]: value })),\n );\n }\n\n return combinations.map((combination) => ({\n id: ordered.map(([axis]) => combination[axis]).join('|') || 'base',\n axes: combination,\n }));\n}\n\n// ─── sealing ────────────────────────────────────────────────────────────────\n\n/**\n * The error message **is** the API here.\n *\n * It has to say *where* to declare, why not elsewhere, and name the requester.\n * Verbose for a human who already knows the answer; exactly right for an agent\n * that would otherwise drop an `overflow` on the nearest parent — which is to\n * say, write the next bug.\n *\n * The message is the **key** rather than the value, unlike the `ERROR_…`\n * markers elsewhere in the repo. That is what makes it come out at the head of\n * `Property '…' is missing` instead of being buried under the printed node type.\n */\nexport type ContextError<Message extends string> = {\n readonly [Key in Message]: never;\n};\n\n/**\n * The bare parameter `Payload` is not a flourish: a conditional distributes\n * only over a bare parameter. Written straight onto\n * `ChannelsOf<Node>['obligations']`, the test does not distribute, and\n * `never extends Obligation<infer Id>` is **true** — `Id` then falls back to its\n * constraint and is `string`. A tree with no open obligation would fail to\n * seal, complaining about an obligation named `string`.\n */\ntype IdOf<Payload> =\n Payload extends Obligation<infer Id extends string> ? Id : never;\n\ntype UndischargedIds<Node> = IdOf<ChannelsOf<Node>['obligations']>;\n\nexport type SealCheck<Node> = [UndischargedIds<Node>] extends [never]\n ? unknown\n : ContextError<`'${UndischargedIds<Node>}' is required by a class in this subtree and nobody provides it. Add provides(${UndischargedIds<Node>}) on the layout component that owns the area — not on the direct parent, where the CSS effect would create a second context and move the bug instead of fixing it.`>;\n\n/**\n * Closes a tree: from here up, nobody else will answer.\n *\n * This is the only place an obligation becomes an error — until then it\n * travels, because an ancestor still has the right to answer it.\n */\nexport function seal<const Node>(node: Node & SealCheck<Node>): Node {\n return node as Node;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../libs/style/src/lib/tokens/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../libs/style/src/lib/tokens/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC","sourcesContent":["export * from './units.ts';\nexport * from './scales.ts';\nexport * from './palette.ts';\n"]}
|