fashionable 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/README.md +276 -0
  2. package/dist/calc/index.d.mts +2 -0
  3. package/dist/calc/index.mjs +1 -334
  4. package/dist/data/index.d.mts +208 -0
  5. package/dist/data/index.mjs +696 -0
  6. package/dist/data/index.mjs.map +1 -0
  7. package/dist/declaration/index.d.mts +2 -0
  8. package/dist/declaration/index.mjs +2 -2
  9. package/dist/declaration/index.mjs.map +1 -1
  10. package/dist/fontFace/index.d.mts +2 -0
  11. package/dist/fontFace/index.mjs +10 -8
  12. package/dist/fontFace/index.mjs.map +1 -1
  13. package/dist/property/index.d.mts +2 -0
  14. package/dist/property/index.mjs +13 -9
  15. package/dist/property/index.mjs.map +1 -1
  16. package/dist/query/index.d.mts +2 -0
  17. package/dist/query/index.mjs +142 -7
  18. package/dist/query/index.mjs.map +1 -1
  19. package/dist/rule/index.d.mts +2 -0
  20. package/dist/rule/index.mjs +19 -2
  21. package/dist/rule/index.mjs.map +1 -1
  22. package/dist/selector/index.d.mts +2 -0
  23. package/dist/selector/index.mjs +2 -2
  24. package/dist/shared/calc-Cih4o2r7.mjs +1145 -0
  25. package/dist/shared/calc-Cih4o2r7.mjs.map +1 -0
  26. package/dist/shared/color-BvNJ2YqL.d.mts +590 -0
  27. package/dist/shared/color.internal-9fpSiiJk.mjs +450 -0
  28. package/dist/shared/color.internal-9fpSiiJk.mjs.map +1 -0
  29. package/dist/shared/declaration-B-6Ykgs_.d.mts +166 -0
  30. package/dist/shared/{declaration.internal-DvZknsDc.mjs → declaration.internal-BeasYIJ0.mjs} +4 -4
  31. package/dist/shared/declaration.internal-BeasYIJ0.mjs.map +1 -0
  32. package/dist/shared/{equal-C96LR7p4.mjs → equal-U9G5LhtL.mjs} +2 -14
  33. package/dist/shared/{equal-C96LR7p4.mjs.map → equal-U9G5LhtL.mjs.map} +1 -1
  34. package/dist/shared/fontFaceRule-DdnLAuVw.d.mts +294 -0
  35. package/dist/shared/{fontFaceRule.internal-CgnEJbNS.mjs → fontFaceRule.internal-D5u48TUO.mjs} +51 -10
  36. package/dist/shared/fontFaceRule.internal-D5u48TUO.mjs.map +1 -0
  37. package/dist/shared/index-BvtwY4FQ.d.mts +841 -0
  38. package/dist/shared/mediaQuery-DsBivHi0.d.mts +333 -0
  39. package/dist/shared/{mediaQuery.internal-BZF1beZO.mjs → mediaQuery.internal-CKTmLVxL.mjs} +71 -7
  40. package/dist/shared/mediaQuery.internal-CKTmLVxL.mjs.map +1 -0
  41. package/dist/shared/mediaRule-4kY2IOq-.d.mts +558 -0
  42. package/dist/shared/precision.internal-0lv1nEpF.mjs +40 -0
  43. package/dist/shared/precision.internal-0lv1nEpF.mjs.map +1 -0
  44. package/dist/shared/propertyRule-B5pf7NgH.d.mts +466 -0
  45. package/dist/shared/{propertyRule.internal-BY1ghubC.mjs → propertyRule.internal-CRyFLwbn.mjs} +4 -4
  46. package/dist/shared/propertyRule.internal-CRyFLwbn.mjs.map +1 -0
  47. package/dist/shared/rolldown-runtime-D7D4PA-g.mjs +13 -0
  48. package/dist/shared/{ruleSet.internal-DQjyPgko.mjs → ruleSet.internal-a5m40W9E.mjs} +13 -7
  49. package/dist/shared/{ruleSet.internal-DQjyPgko.mjs.map → ruleSet.internal-a5m40W9E.mjs.map} +1 -1
  50. package/dist/shared/selector-HZY-W6l6.d.mts +346 -0
  51. package/dist/shared/{selector.internal-BLQtVoIM.mjs → selector.internal-ESe9s0IH.mjs} +2 -2
  52. package/dist/shared/{selector.internal-BLQtVoIM.mjs.map → selector.internal-ESe9s0IH.mjs.map} +1 -1
  53. package/dist/shared/utils-BKm298I-.d.mts +179 -0
  54. package/dist/stylesheet/index.d.mts +335 -0
  55. package/dist/stylesheet/index.mjs +118 -17
  56. package/dist/stylesheet/index.mjs.map +1 -1
  57. package/dist/utils.d.mts +2 -0
  58. package/package.json +16 -16
  59. package/dist/calc/calc.d.ts +0 -425
  60. package/dist/calc/calc.internal.d.ts +0 -2
  61. package/dist/calc/index.d.ts +0 -6
  62. package/dist/calc/index.mjs.map +0 -1
  63. package/dist/calc/precision.d.ts +0 -72
  64. package/dist/calc/precision.internal.d.ts +0 -2
  65. package/dist/color/color.d.ts +0 -121
  66. package/dist/color/color.internal.d.ts +0 -2
  67. package/dist/color/index.d.ts +0 -3
  68. package/dist/color/index.mjs +0 -73
  69. package/dist/color/index.mjs.map +0 -1
  70. package/dist/declaration/declaration.d.ts +0 -159
  71. package/dist/declaration/declaration.internal.d.ts +0 -2
  72. package/dist/declaration/index.d.ts +0 -3
  73. package/dist/fontFace/fontFaceRule.d.ts +0 -257
  74. package/dist/fontFace/fontFaceRule.internal.d.ts +0 -4
  75. package/dist/fontFace/index.d.ts +0 -3
  76. package/dist/internal/equal.d.ts +0 -13
  77. package/dist/internal/format.d.ts +0 -6
  78. package/dist/internal/refs.d.ts +0 -8
  79. package/dist/internal/render.d.ts +0 -6
  80. package/dist/property/index.d.ts +0 -6
  81. package/dist/property/propertyRule.d.ts +0 -174
  82. package/dist/property/propertyRule.internal.d.ts +0 -2
  83. package/dist/property/propertySyntax.d.ts +0 -282
  84. package/dist/property/propertySyntax.internal.d.ts +0 -2
  85. package/dist/query/index.d.ts +0 -3
  86. package/dist/query/mediaQuery.d.ts +0 -134
  87. package/dist/query/mediaQuery.internal.d.ts +0 -2
  88. package/dist/rule/index.d.ts +0 -9
  89. package/dist/rule/mediaRule.d.ts +0 -115
  90. package/dist/rule/mediaRule.internal.d.ts +0 -2
  91. package/dist/rule/rule.internal.d.ts +0 -13
  92. package/dist/rule/ruleSet.d.ts +0 -249
  93. package/dist/rule/ruleSet.internal.d.ts +0 -2
  94. package/dist/rule/styleRule.d.ts +0 -110
  95. package/dist/rule/styleRule.internal.d.ts +0 -2
  96. package/dist/selector/index.d.ts +0 -6
  97. package/dist/selector/selector.d.ts +0 -243
  98. package/dist/selector/selector.internal.d.ts +0 -2
  99. package/dist/selector/specificity.d.ts +0 -92
  100. package/dist/selector/specificity.internal.d.ts +0 -2
  101. package/dist/shared/calc.internal-C1g_NRsl.mjs +0 -568
  102. package/dist/shared/calc.internal-C1g_NRsl.mjs.map +0 -1
  103. package/dist/shared/color.internal-D7P91Rvv.mjs +0 -100
  104. package/dist/shared/color.internal-D7P91Rvv.mjs.map +0 -1
  105. package/dist/shared/declaration.internal-DvZknsDc.mjs.map +0 -1
  106. package/dist/shared/fontFaceRule.internal-CgnEJbNS.mjs.map +0 -1
  107. package/dist/shared/mediaQuery.internal-BZF1beZO.mjs.map +0 -1
  108. package/dist/shared/propertyRule.internal-BY1ghubC.mjs.map +0 -1
  109. package/dist/stylesheet/index.d.ts +0 -3
  110. package/dist/stylesheet/stylesheet.d.ts +0 -275
  111. package/dist/stylesheet/stylesheet.internal.d.ts +0 -2
  112. package/dist/utils.d.ts +0 -176
package/README.md ADDED
@@ -0,0 +1,276 @@
1
+ # fashionable
2
+
3
+ Structural stylesheet modeling and calc expression evaluation for TypeScript (npm: `fashionable`).
4
+
5
+ An Effect-style API for building CSS in code: a faithful structural model of the CSS language — rules, selectors, media queries, at-rules, nesting — unified with a `calc()` value-expression language that can be solved against bindings or serialized to CSS text. Immutable values, structural equality, deterministic output, zero runtime dependencies. No template literals anywhere.
6
+
7
+ ```sh
8
+ npm install fashionable
9
+ ```
10
+
11
+ ## Typed calc
12
+
13
+ A `Calc` is a CSS math expression you can serialize to CSS or solve to a number — the same tree, two projections, so the thing you verified is the thing you shipped. The type tracks the expression's unbound references, its dimension (`<number>`, `<length>`, `<angle>`, or `<percentage>`), and the units it mentions.
14
+
15
+ ```ts
16
+ import { Calc } from 'fashionable/calc'
17
+ import { Length } from 'fashionable/data'
18
+
19
+ const fluid = Calc.clamp(
20
+ Length.rem(1),
21
+ Calc.add(Length.rem(0.75), Length.vw(0.5)),
22
+ Length.rem(1.25),
23
+ )
24
+
25
+ Calc.serialize(fluid) // 'clamp(1rem, 0.75rem + 0.5vw, 1.25rem)'
26
+ Calc.solve(fluid, {}, { rem: 16, vw: 1280 / 100 }) // 18.4 — at a 1280px viewport, 16px root
27
+ ```
28
+
29
+ `solve` lowers relative units through a context of px ratios, typed by the expression's units so the context can neither miss nor mismatch a key. Absolute lengths and angles solve with no context. `Length`, `Angle`, and `Percentage` in `fashionable/data` supply the unit constructors — `Length.px` through `Length.vmax`, `Angle.rad` and `Angle.deg`, `Percentage.of` — with `Unit` naming the unit types. A percentage serializes but does not solve.
30
+
31
+ References are CSS custom properties: `Calc.ref('space')` reads `var(--space)`, and `bind` substitutes and partially evaluates.
32
+
33
+ ```ts
34
+ const gap = Calc.multiply(Calc.ref('space'), 2)
35
+
36
+ Calc.serialize(gap) // 'calc(var(--space) * 2)'
37
+ Calc.solve(gap.pipe(Calc.bind({ space: 4 }))) // 8
38
+ ```
39
+
40
+ The dimensional rules follow CSS and live in the types: `add`, `subtract`, `min`, `max`, and `clamp` require a shared kind, `multiply` scales a dimension by a number, and `divide` of two like dimensions is a number. Illegal combinations fail to typecheck rather than emitting invalid CSS.
41
+
42
+ ```ts
43
+ // @ts-expect-error — a <length> plus a <number> has no CSS meaning
44
+ Calc.add(Length.px(10), 5)
45
+ // @ts-expect-error — two lengths do not multiply
46
+ Calc.multiply(Length.px(10), Length.px(10))
47
+
48
+ const ratio = Calc.divide(Calc.subtract(Length.vw(100), Length.px(320)), Length.px(160))
49
+
50
+ Calc.serialize(ratio) // 'calc((100vw - 320px) / 160px)' — a <length> over a <length> is a <number>
51
+ Calc.solve(ratio, {}, { vw: 1280 / 100 }) // 6
52
+ ```
53
+
54
+ Firefox does not yet support `<length> / <length>` division in `calc()`; `tan(atan2(y, x))` is the portable spelling of the same ratio.
55
+
56
+ ```ts
57
+ const portable = Calc.tan(Calc.atan2(Calc.subtract(Length.vw(100), Length.px(320)), Length.px(160)))
58
+
59
+ Calc.serialize(portable) // 'tan(atan2(100vw - 320px, 160px))'
60
+ ```
61
+
62
+ `mod`, `pow`/`signedPow`, `lerp`, `abs`, and `sin`/`cos`/`acos` round out the combinators. Trig follows CSS's typing: `acos` and `atan2` return an `<angle>`, and `sin`/`cos`/`tan` accept an `<angle>` or a plain number in radians.
63
+
64
+ Constants format under an explicit precision model: five decimals by default, overridable per serialize call, and per constant with an annotation that carries through constant folding.
65
+
66
+ ```ts
67
+ import { Precision } from 'fashionable/calc'
68
+
69
+ Calc.serialize(Calc.of(0.8377580409572781)) // '0.83776'
70
+ Calc.serialize(Calc.of(0.8377580409572781, Precision.significant(10))) // '0.837758041'
71
+ ```
72
+
73
+ The full precision model lives in [docs/design.md](https://github.com/tkofh/fashionable/blob/main/docs/design.md).
74
+
75
+ ## Color
76
+
77
+ A `Color` models a CSS color value structurally. Channels are `Calc` number expressions, so a channel can be a constant, a reference, arithmetic, or CSS's `none` keyword. A `Color` serializes and binds; it does not solve.
78
+
79
+ ```ts
80
+ import { Calc } from 'fashionable/calc'
81
+ import { Channel, Color, ColorSpace, HueInterpolation, Keyword } from 'fashionable/data'
82
+
83
+ Color.serialize(Color.oklch(0.7, 0.15, Calc.ref('hue'))) // 'oklch(0.7 0.15 var(--hue))'
84
+ Color.serialize(Color.srgb(0.18, 0.34, 0.78)) // 'color(srgb 0.18 0.34 0.78)'
85
+ Color.serialize(Color.oklch(0.2, 0, Keyword.none)) // 'oklch(0.2 0 none)'
86
+
87
+ Color.oklch(Calc.ref('l'), 0.15, 250).pipe(Color.bind({ l: 0.7 })) // serializes 'oklch(0.7 0.15 250)'
88
+ ```
89
+
90
+ **Relative color syntax.** `Color.from` derives a color from another — including one the browser resolves from the cascade. The destination space exposes the origin's channels as `Channel` keywords and scopes them: `Channel.L` belongs to `oklch`, `Channel.R` to `srgb`, and a keyword the space does not name is a compile error.
91
+
92
+ ```ts
93
+ const hover = Color.from(
94
+ Color.ref('accent'), // reads the whole color from var(--accent)
95
+ ColorSpace.oklch,
96
+ Calc.multiply(Channel.L, 0.8),
97
+ Channel.C,
98
+ Channel.H,
99
+ )
100
+
101
+ Color.serialize(hover) // 'oklch(from var(--accent) calc(l * 0.8) c h)'
102
+ ```
103
+
104
+ **Mixing.** `Color.mix` models `color-mix()`. Arms are colors or `[color, weight]` tuples, weights read as percents. A polar space admits a `HueInterpolation` strategy after it; a strategy after a rectangular space is a compile error, matching the grammar.
105
+
106
+ ```ts
107
+ const wash = Color.mix(ColorSpace.oklch, [Color.ref('brand'), 60], Color.named('white'))
108
+
109
+ Color.serialize(wash) // 'color-mix(in oklch, var(--brand) 60%, white)'
110
+
111
+ const arc = Color.mix(
112
+ ColorSpace.oklch,
113
+ HueInterpolation.longer,
114
+ Color.oklch(0.7, 0.15, 30),
115
+ Color.oklch(0.7, 0.15, 330),
116
+ )
117
+
118
+ Color.serialize(arc) // 'color-mix(in oklch longer hue, oklch(0.7 0.15 30), oklch(0.7 0.15 330))'
119
+ ```
120
+
121
+ **Hue interpolation.** `HueInterpolation.interpolate` is the JS side of that hue arc: it builds the hue at `t` along the chosen strategy — the CSS Color 4 hue fixup written branchlessly with `mod` — folding to a constant when every argument is a number and staying symbolic otherwise. Your build and the browser compute the same fixup.
122
+
123
+ ```ts
124
+ const hue = HueInterpolation.interpolate(
125
+ HueInterpolation.shorter,
126
+ 30,
127
+ Calc.ref('to'),
128
+ Calc.ref('t'),
129
+ )
130
+
131
+ Calc.serialize(hue) // 'calc(30 + (mod(var(--to) - 30 + 180, 360) - 180) * var(--t))'
132
+ Calc.serialize(HueInterpolation.interpolate(HueInterpolation.increasing, 20, 350, 0.5)) // '185'
133
+ ```
134
+
135
+ **Whole-value colors.** `Color.lightDark` models scheme-conditional `light-dark()` with whole colors in each arm. `Color.ref` reads an entire color from a custom property, `Color.named` renders a named color bare, and `Color.transparent` is the blessed no-color constant. All of them compose anywhere a `Color` goes.
136
+
137
+ ```ts
138
+ const scheme = Color.lightDark(Color.oklch(0.98, 0.01, 250), Color.oklch(0.18, 0.02, 250))
139
+
140
+ Color.serialize(scheme) // 'light-dark(oklch(0.98 0.01 250), oklch(0.18 0.02 250))'
141
+ Color.serialize(Color.lightDark(Color.ref('surface'), Color.transparent))
142
+ // 'light-dark(var(--surface), transparent)'
143
+ ```
144
+
145
+ ## Stylesheets
146
+
147
+ Build a stylesheet from typed parts — selectors, declarations, rules, nested media — then render it to CSS.
148
+
149
+ ```ts
150
+ import { Calc } from 'fashionable/calc'
151
+ import { Length } from 'fashionable/data'
152
+ import { Declaration } from 'fashionable/declaration'
153
+ import { MediaQuery } from 'fashionable/query'
154
+ import { MediaRule, RuleSet, StyleRule } from 'fashionable/rule'
155
+ import { Selector } from 'fashionable/selector'
156
+ import { Stylesheet } from 'fashionable/stylesheet'
157
+
158
+ const card = StyleRule.make(
159
+ Selector.class('card'),
160
+ RuleSet.make(
161
+ Declaration.make('padding', Length.rem(1)),
162
+ Declaration.make('gap', Calc.multiply(Calc.ref('space'), 2)),
163
+ MediaRule.make(
164
+ MediaQuery.minWidth(768),
165
+ RuleSet.make(Declaration.make('gap', Calc.multiply(Calc.ref('space'), 3))),
166
+ ),
167
+ ),
168
+ )
169
+
170
+ const sheet = Stylesheet.make(card) // Stylesheet<'space'>
171
+
172
+ Stylesheet.render(sheet, { indent: ' ' })
173
+ ```
174
+
175
+ Nesting is preserved as authored — `@media` stays inside its rule:
176
+
177
+ ```css
178
+ .card {
179
+ padding: 1rem;
180
+ gap: calc(var(--space) * 2);
181
+ @media (min-width: 768px) {
182
+ gap: calc(var(--space) * 3);
183
+ }
184
+ }
185
+ ```
186
+
187
+ Selectors are compound selectors built from typed parts — `type`, `id`, `class`, `attribute`, `not`, pseudo-classes and pseudo-elements — with computed `Specificity`. Media queries are and-sets of `minWidth` and `prefersColorScheme`. Both canonicalize at construction, so structural equality holds regardless of construction order and rendering is deterministic. Declaration and rule order is never touched: member order is cascade behavior, and the library preserves it.
188
+
189
+ A block built up through `pipe` caps off as a rule with `forSelector` or `forMediaQuery`:
190
+
191
+ ```ts
192
+ RuleSet.make(Declaration.make('--depth', Calc.ref('depth'))).pipe(
193
+ RuleSet.forSelector(Selector.root),
194
+ ) // StyleRule<'depth'> — renders ':root { --depth: var(--depth); }'
195
+ ```
196
+
197
+ ## Refs
198
+
199
+ Every value and container is generic over `Refs`, the CSS custom properties it reads but has not bound. `Calc.ref('space')` is a `Calc<'space'>` and `Color.ref('accent')` is a `Color<'accent'>`. Combining values unions their `Refs`, and `bind` subtracts the names it binds. A closed expression — fully bound or constant — is a `Calc<never>`, which is what `solve` accepts with no bindings.
200
+
201
+ The parameter threads up through the model, so `Declaration<Refs>`, `RuleSet<Refs>`, `StyleRule<Refs>`, and `Stylesheet<Refs>` carry the union of the refs they contain. The `Stylesheet<'space'>` above is the compiler reporting that the sheet reads `var(--space)` and nothing else. `Stylesheet.refs` returns the same set at runtime. Unbound refs serialize as `var(--name)` — the reference channel is the custom-property channel.
202
+
203
+ ## `@property` and `@font-face`
204
+
205
+ `PropertyRule` models `@property`. The `PropertySyntax` value in the `syntax` slot types the initial value, and the spec's computational-independence rule rides along: `Length.px(8)` registers under `PropertySyntax.length`, and `Length.vw(8)` is a compile error. Rules register with `inherits: false`; pipe through `PropertyRule.inheritable` to opt in.
206
+
207
+ ```ts
208
+ import { PropertyRule, PropertySyntax } from 'fashionable/property'
209
+
210
+ const depth = PropertyRule.make('--depth', PropertySyntax.number, 0)
211
+
212
+ PropertyRule.render(depth, { indent: ' ' })
213
+ // @property --depth {
214
+ // syntax: '<number>';
215
+ // inherits: false;
216
+ // initial-value: 0;
217
+ // }
218
+ ```
219
+
220
+ `FontFaceRule` models `@font-face`: multi-source `src`, weight ranges, metric overrides, and `unicode-range`.
221
+
222
+ ```ts
223
+ import { FontFaceRule } from 'fashionable/font-face'
224
+
225
+ const inter = FontFaceRule.make({
226
+ family: 'Inter',
227
+ src: [FontFaceRule.url('/fonts/inter.woff2', 'woff2'), FontFaceRule.local('Inter')],
228
+ weight: [400, 700],
229
+ display: 'swap',
230
+ unicodeRange: [[0x400, 0x4ff]],
231
+ })
232
+
233
+ FontFaceRule.render(inter, { indent: ' ' })
234
+ // @font-face {
235
+ // font-family: 'Inter';
236
+ // font-weight: 400 700;
237
+ // font-display: swap;
238
+ // src:
239
+ // url('/fonts/inter.woff2') format('woff2'),
240
+ // local('Inter');
241
+ // unicode-range: U+400-4FF;
242
+ // }
243
+ ```
244
+
245
+ ## Merging and coalescing
246
+
247
+ `Stylesheet.merge` is a lawful monoid — associative, idempotent, `empty` as identity — that keeps both sides' order and collapses structural duplicates to their first occurrence. That is the multi-emitter fold: emitters that each register the rules they share merge to a sheet carrying one copy.
248
+
249
+ ```ts
250
+ import { Stylesheet } from 'fashionable/stylesheet'
251
+
252
+ const contract = Stylesheet.make(PropertyRule.make('--depth', PropertySyntax.number, 0))
253
+
254
+ Stylesheet.merge(contract, contract) === contract // true — idempotent, by reference
255
+ ```
256
+
257
+ `coalesce` folds style rules that share a selector into the first occurrence:
258
+
259
+ ```ts
260
+ const sheet = Stylesheet.make(
261
+ StyleRule.make(Selector.root, RuleSet.make(Declaration.make('--a', 1))),
262
+ StyleRule.make(Selector.root, RuleSet.make(Declaration.make('--b', 2))),
263
+ )
264
+
265
+ Stylesheet.render(Stylesheet.coalesce(sheet), { indent: ' ' })
266
+ // :root {
267
+ // --a: 1;
268
+ // --b: 2;
269
+ // }
270
+ ```
271
+
272
+ Coalescing is order-sensitive: pulling a block backward past a rule whose selector ties on specificity can change the cascade. So it stays an explicit opt-in, and `coalesce(sheet, { strict: true })` throws on any such pull — a build gate proving the normalization is cascade-preserving.
273
+
274
+ ## License
275
+
276
+ MIT
@@ -0,0 +1,2 @@
1
+ import { l as precision_d_exports, s as calc_d_exports } from "../shared/index-BvtwY4FQ.mjs";
2
+ export { calc_d_exports as Calc, precision_d_exports as Precision };
@@ -1,335 +1,2 @@
1
- import { c as __exportAll } from "../shared/equal-C96LR7p4.mjs";
2
- import { D as signedPow$1, E as sign$1, F as significant$1, N as decimals$1, O as sin$1, P as isPrecision$1, S as refs$1, a as clamp$1, b as pow$1, c as divide$1, d as lerp$1, f as max$1, i as bind$1, j as subtract$1, k as solve$1, l as equals$1, m as multiply$1, n as acos$1, p as min$1, r as add$1, s as cos$1, t as abs$1, u as isCalc$1, w as serialize$1, x as ref$1, y as of$1 } from "../shared/calc.internal-C1g_NRsl.mjs";
3
- //#region src/calc/calc.ts
4
- var calc_exports = /* @__PURE__ */ __exportAll({
5
- abs: () => abs,
6
- acos: () => acos,
7
- add: () => add,
8
- bind: () => bind,
9
- clamp: () => clamp,
10
- cos: () => cos,
11
- divide: () => divide,
12
- equals: () => equals,
13
- isCalc: () => isCalc,
14
- lerp: () => lerp,
15
- max: () => max,
16
- min: () => min,
17
- multiply: () => multiply,
18
- of: () => of,
19
- pow: () => pow,
20
- ref: () => ref,
21
- refs: () => refs,
22
- serialize: () => serialize,
23
- sign: () => sign,
24
- signedPow: () => signedPow,
25
- sin: () => sin,
26
- solve: () => solve,
27
- subtract: () => subtract
28
- });
29
- /**
30
- * Checks if a value is a `Calc`.
31
- *
32
- * True only for values built by this module's constructors, which carry
33
- * the brand.
34
- *
35
- * @param u - The value to check.
36
- * @returns `true` if the value is a `Calc`, `false` otherwise.
37
- * @since 0.1.0
38
- */
39
- const isCalc = isCalc$1;
40
- /**
41
- * Creates a constant expression, optionally annotated with a serialization
42
- * precision that overrides the context default wherever the constant lands
43
- * — including in constants produced by folding it with others (the
44
- * highest-fidelity operand annotation wins).
45
- *
46
- * Bare numbers passed to combinators become unannotated constants; `of`
47
- * exists to name a value or pin its precision.
48
- *
49
- * @param value - The constant value. Must be finite.
50
- * @param precision - Optional precision annotation.
51
- * @returns A constant `Calc<never>`.
52
- * @throws `Error` when `value` is not finite.
53
- * @example
54
- * ```ts
55
- * const k = Calc.of(0.8377580409572781, Precision.significant(10))
56
- * Calc.serialize(Calc.multiply(k, Calc.ref('t'))) // 'calc(0.837758041 * var(--t))'
57
- * ```
58
- * @since 0.1.0
59
- */
60
- const of = of$1;
61
- /**
62
- * Creates a reference to an unbound name. References serialize as
63
- * `var(--name)` and are the channel through which expressions read CSS
64
- * custom properties; `bind` replaces them with values or other
65
- * expressions.
66
- *
67
- * Repeated calls with the same name return the same instance.
68
- *
69
- * @param name - The reference name, without the `--` prefix. Must be non-empty.
70
- * @returns A `Calc` with `name` as its one unbound reference.
71
- * @throws `Error` when `name` is empty.
72
- * @example
73
- * ```ts
74
- * Calc.serialize(Calc.ref('width')) // 'var(--width)'
75
- * ```
76
- * @since 0.1.0
77
- */
78
- const ref = ref$1;
79
- /**
80
- * Adds expressions. Constant operands fold at construction.
81
- *
82
- * Serializes as `a + b + ...` inside a `calc()` wrapper; negative constant
83
- * terms (and products led by a negative constant) render subtractively:
84
- * `a + (-2)` serializes as `a - 2`.
85
- *
86
- * @param a - The first operand.
87
- * @param b - The second operand.
88
- * @returns The sum, with the operands' references unioned.
89
- * @example
90
- * ```ts
91
- * Calc.serialize(Calc.add(Calc.ref('x'), 10)) // 'calc(var(--x) + 10)'
92
- * ```
93
- * @since 0.1.0
94
- */
95
- const add = add$1;
96
- /**
97
- * Subtracts `right` from `left`. Constant operands fold at construction.
98
- *
99
- * @param left - The minuend.
100
- * @param right - The subtrahend.
101
- * @returns The difference, with the operands' references unioned.
102
- * @since 0.1.0
103
- */
104
- const subtract = subtract$1;
105
- /**
106
- * Multiplies expressions. Constant operands fold at construction.
107
- *
108
- * Addition and subtraction operands are parenthesized when serialized
109
- * under a product: `(a + b) * c`.
110
- *
111
- * @param left - The first factor.
112
- * @param right - The second factor.
113
- * @returns The product, with the operands' references unioned.
114
- * @since 0.1.0
115
- */
116
- const multiply = multiply$1;
117
- /**
118
- * Divides `left` by `right`. Constant operands fold at construction.
119
- *
120
- * @param left - The dividend.
121
- * @param right - The divisor.
122
- * @returns The quotient, with the operands' references unioned.
123
- * @since 0.1.0
124
- */
125
- const divide = divide$1;
126
- /**
127
- * Raises `base` to `exponent`. Serializes as the CSS `pow()` function.
128
- *
129
- * @param base - The base.
130
- * @param exponent - The exponent.
131
- * @returns The power, with the operands' references unioned.
132
- * @since 0.1.0
133
- */
134
- const pow = pow$1;
135
- /**
136
- * Sign-preserving power: `abs(base) ^ exponent * sign(base)`. Unlike
137
- * `pow`, well-defined for negative bases with fractional exponents.
138
- * Serializes as `pow(abs(base), exponent) * sign(base)`.
139
- *
140
- * @param base - The base.
141
- * @param exponent - The exponent.
142
- * @returns The signed power, with the operands' references unioned.
143
- * @since 0.1.0
144
- */
145
- const signedPow = signedPow$1;
146
- /**
147
- * The minimum of the operands. Serializes as the CSS `min()` function.
148
- *
149
- * @param a - The first operand.
150
- * @param b - The second operand.
151
- * @returns The minimum, with the operands' references unioned.
152
- * @since 0.1.0
153
- */
154
- const min = min$1;
155
- /**
156
- * The maximum of the operands. Serializes as the CSS `max()` function.
157
- *
158
- * @param a - The first operand.
159
- * @param b - The second operand.
160
- * @returns The maximum, with the operands' references unioned.
161
- * @since 0.1.0
162
- */
163
- const max = max$1;
164
- /**
165
- * Clamps `value` between `minimum` and `maximum`. Serializes as the CSS
166
- * `clamp()` function, with the CSS argument order `(min, value, max)`.
167
- *
168
- * @param minimum - The lower bound.
169
- * @param value - The value to clamp.
170
- * @param maximum - The upper bound.
171
- * @returns The clamped expression, with the operands' references unioned.
172
- * @example
173
- * ```ts
174
- * Calc.serialize(Calc.clamp(-1, Calc.ref('u'), 1)) // 'clamp(-1, var(--u), 1)'
175
- * ```
176
- * @since 0.1.0
177
- */
178
- const clamp = clamp$1;
179
- /**
180
- * Linear interpolation from `a` to `b` by `t`. This is sugar, not a node:
181
- * it desugars to `(1 - t) * a + t * b`, and serializes as that expanded
182
- * form.
183
- *
184
- * @param a - The value at `t = 0`.
185
- * @param b - The value at `t = 1`.
186
- * @param t - The interpolation parameter.
187
- * @returns The interpolated expression, with the operands' references unioned.
188
- * @since 0.1.0
189
- */
190
- const lerp = lerp$1;
191
- /**
192
- * The absolute value. Serializes as the CSS `abs()` function.
193
- *
194
- * @param argument - The operand.
195
- * @returns The absolute value expression.
196
- * @since 0.1.0
197
- */
198
- const abs = abs$1;
199
- /**
200
- * The sign (`-1`, `0`, or `1`). Serializes as the CSS `sign()` function.
201
- *
202
- * @param argument - The operand.
203
- * @returns The sign expression.
204
- * @since 0.1.0
205
- */
206
- const sign = sign$1;
207
- /**
208
- * The sine of an angle in radians. Serializes as the CSS `sin()`
209
- * function; CSS treats a plain-number argument as radians, so no unit
210
- * conversion is involved.
211
- *
212
- * @param argument - The angle, in radians.
213
- * @returns The sine expression.
214
- * @since 0.1.0
215
- */
216
- const sin = sin$1;
217
- /**
218
- * The cosine of an angle in radians. Serializes as the CSS `cos()`
219
- * function; CSS treats a plain-number argument as radians, so no unit
220
- * conversion is involved.
221
- *
222
- * @param argument - The angle, in radians.
223
- * @returns The cosine expression.
224
- * @since 0.1.0
225
- */
226
- const cos = cos$1;
227
- /**
228
- * The arccosine of a value in `[-1, 1]`, in radians. Solving evaluates
229
- * `Math.acos`.
230
- *
231
- * Serialization note: CSS's `acos()` returns an `<angle>`, not a number.
232
- * The serializer keeps such subtrees angle-typed — plain-number terms
233
- * added to or subtracted from an acos-carrying term are rendered with a
234
- * `rad` suffix (constants) or a `* 1rad` factor (anything else), so the
235
- * emitted CSS stays valid without typed division. In v1, consume
236
- * acos-carrying subtrees with `sin` or `cos`; feeding one into a plain
237
- * number context serializes to angle-typed CSS.
238
- *
239
- * @param argument - The cosine value, in `[-1, 1]`.
240
- * @returns The arccosine expression, in radians.
241
- * @example
242
- * ```ts
243
- * Calc.serialize(Calc.cos(Calc.subtract(Calc.divide(Calc.acos(Calc.ref('u')), 3), 2.0943951)))
244
- * // 'cos(acos(var(--u)) / 3 - 2.0944rad)'
245
- * ```
246
- * @since 0.1.0
247
- */
248
- const acos = acos$1;
249
- const bind = bind$1;
250
- const solve = solve$1;
251
- /**
252
- * Renders an expression as CSS text. Arithmetic gets a `calc()` wrapper;
253
- * function forms (`min`, `clamp`, `sin`, ...) and leaves stand alone.
254
- * References render as `var(--name)`.
255
- *
256
- * Bindings in `options` are applied first and may be partial — this is
257
- * the serialize half of the solve/serialize duality, and unbound
258
- * references are the values left for the browser. Constants render with
259
- * their annotated precision, or the context `precision` option (default
260
- * `Precision.decimals(5)`). Constants equal to pi render as the CSS
261
- * constant `pi` where a math function surrounds them.
262
- *
263
- * @param expr - The expression to render.
264
- * @param options - Optional bindings and precision context.
265
- * @returns Deterministic CSS text.
266
- * @example
267
- * ```ts
268
- * const fluid = Calc.add(10, Calc.ref('runtime'))
269
- * Calc.serialize(fluid) // 'calc(10 + var(--runtime))'
270
- * Calc.serialize(fluid, { bindings: { runtime: 4 } }) // '14'
271
- * ```
272
- * @since 0.1.0
273
- */
274
- const serialize = serialize$1;
275
- /**
276
- * The expression's unbound reference names.
277
- *
278
- * @param expr - The expression to inspect.
279
- * @returns The set of unbound reference names.
280
- * @since 0.1.0
281
- */
282
- const refs = refs$1;
283
- const equals = equals$1;
284
- //#endregion
285
- //#region src/calc/precision.ts
286
- var precision_exports = /* @__PURE__ */ __exportAll({
287
- decimals: () => decimals,
288
- isPrecision: () => isPrecision,
289
- significant: () => significant
290
- });
291
- /**
292
- * Checks if a value is a `Precision`.
293
- *
294
- * True only for values built by `decimals` or `significant`, which carry
295
- * the brand.
296
- *
297
- * @param u - The value to check.
298
- * @returns `true` if the value is a `Precision`, `false` otherwise.
299
- * @since 0.1.0
300
- */
301
- const isPrecision = isPrecision$1;
302
- /**
303
- * Creates a `Precision` fixing the count of digits after the decimal
304
- * point. The library default for unannotated constants is `decimals(5)`.
305
- *
306
- * @param digits - Digits after the decimal point. Must be an integer in `[0, 100]`.
307
- * @returns A `Precision` in `decimals` mode.
308
- * @throws `Error` when `digits` is not an integer in `[0, 100]`.
309
- * @example
310
- * ```ts
311
- * Calc.serialize(Calc.of(1 / 3), { precision: Precision.decimals(2) }) // '0.33'
312
- * ```
313
- * @since 0.1.0
314
- */
315
- const decimals = decimals$1;
316
- /**
317
- * Creates a `Precision` fixing the count of significant digits. Use it for
318
- * unit-free constants whose error is amplified downstream — solved curve
319
- * coefficients, for example — where fixed decimal places would truncate.
320
- *
321
- * @param digits - Significant digits. Must be an integer in `[1, 100]`.
322
- * @returns A `Precision` in `significant` mode.
323
- * @throws `Error` when `digits` is not an integer in `[1, 100]`.
324
- * @example
325
- * ```ts
326
- * const k = Calc.of(0.8377580409572781, Precision.significant(10))
327
- * Calc.serialize(k) // '0.837758041'
328
- * ```
329
- * @since 0.1.0
330
- */
331
- const significant = significant$1;
332
- //#endregion
1
+ import { r as calc_exports, t as precision_exports } from "../shared/calc-Cih4o2r7.mjs";
333
2
  export { calc_exports as Calc, precision_exports as Precision };
334
-
335
- //# sourceMappingURL=index.mjs.map