@fluixi-ui/fx 0.1.0-alpha.2 → 0.1.0-alpha.4

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 (41) hide show
  1. package/README.md +57 -3
  2. package/dist/index.d.ts +7 -0
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +9 -0
  5. package/dist/lib/animations.d.ts +55 -0
  6. package/dist/lib/animations.d.ts.map +1 -0
  7. package/dist/lib/animations.js +73 -0
  8. package/dist/lib/keyframes.d.ts +70 -0
  9. package/dist/lib/keyframes.d.ts.map +1 -0
  10. package/dist/lib/keyframes.js +63 -0
  11. package/dist/lib/merge.d.ts +1 -1
  12. package/dist/lib/merge.js +1 -1
  13. package/dist/lib/presets.d.ts +67 -0
  14. package/dist/lib/presets.d.ts.map +1 -0
  15. package/dist/lib/presets.js +111 -0
  16. package/dist/lib/resolve.d.ts.map +1 -1
  17. package/dist/lib/resolve.js +23 -0
  18. package/dist/lib/scales.d.ts.map +1 -1
  19. package/dist/lib/scales.js +9 -1
  20. package/dist/lib/selectors.d.ts +9 -0
  21. package/dist/lib/selectors.d.ts.map +1 -1
  22. package/dist/lib/selectors.js +4 -0
  23. package/dist/lib/sheet.d.ts +7 -0
  24. package/dist/lib/sheet.d.ts.map +1 -1
  25. package/dist/lib/sheet.js +30 -1
  26. package/dist/lib/slots.d.ts +19 -0
  27. package/dist/lib/slots.d.ts.map +1 -0
  28. package/dist/lib/slots.js +29 -0
  29. package/dist/lib/types.d.ts +13 -1
  30. package/dist/lib/types.d.ts.map +1 -1
  31. package/dist/lib/utilities.d.ts +98 -0
  32. package/dist/lib/utilities.d.ts.map +1 -0
  33. package/dist/lib/utilities.js +114 -0
  34. package/dist/lib/variants.d.ts +41 -0
  35. package/dist/lib/variants.d.ts.map +1 -0
  36. package/dist/lib/variants.js +16 -0
  37. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  38. package/dist/vite.d.ts +41 -0
  39. package/dist/vite.d.ts.map +1 -0
  40. package/dist/vite.js +182 -0
  41. package/package.json +12 -2
package/README.md CHANGED
@@ -119,6 +119,50 @@ the way mixing with white or black does. They need relative colour syntax
119
119
  (Chrome 119+, Safari 16.4+, Firefox 128+); for a wider floor use
120
120
  `mix(color, 'white', n)`.
121
121
 
122
+ ## Ready-made objects
123
+
124
+ An `fx` value is a plain object, so a utility is just a named one — import it, spread
125
+ it, merge it:
126
+
127
+ ```tsx
128
+ import { flexBetween, muted, bordered, clickable, truncate, mergeFx } from '@fluixi-ui/fx';
129
+
130
+ <div {...fxProps(() => mergeFx(bordered, clickable, { p: 3 }))} />
131
+ ```
132
+
133
+ - **`utilities`** — the everyday one-liners: `flex*`, `fullWidth`, `stickyTop`,
134
+ `muted`, `bold`, `nowrap`, `bordered`, `rounded`, `pill`, `scrim`, `pointer`,
135
+ `clickable`, `focusRing`, `disabled`. The ones that carry a decision are the point:
136
+ `flexFill` includes the `min-width: 0` a flex child needs before its text will
137
+ truncate, `muted` is the token rather than a picked grey, `focusRing` is
138
+ `:focus-visible` only.
139
+ - **`presets`** — the recipes that only work as a set: `truncate`, `lineClamp`,
140
+ `visuallyHidden`, `stack`, `row`, `center`, `scrollY`, `scrollbarHidden`,
141
+ `gradientText`, `aspect`.
142
+ - **`variants`** — map a component's own props to `fx` without a ternary chain: later
143
+ groups win, `false` turns a defaulted group off.
144
+
145
+ ## Animation
146
+
147
+ `keyframes()` defines an animation and returns its name; `animate()` writes the
148
+ longhands. A bare second argument is the duration.
149
+
150
+ ```tsx
151
+ const pulse = keyframes({ from: { opacity: 0.4 }, to: { opacity: 1 } });
152
+
153
+ fx={animate(pulse, { repeat: 'infinite' })}
154
+ fx={fadeIn('slow')}
155
+ fx={slideIn('bottom', { distance: 16 })}
156
+ ```
157
+
158
+ Stop values go through the resolver, so tokens work inside them, and the name is
159
+ hashed from the resolved body so the same animation defined twice is one rule. The
160
+ stock set — `fadeIn`/`fadeOut`, `scaleIn`/`scaleOut`, `slideIn`/`slideOut`, `spin`,
161
+ `pulse`, `shimmer` — registers its rules on first use rather than on import.
162
+
163
+ `animate` returns an object rather than the `animation` shorthand string, so it merges
164
+ with what surrounds it instead of resetting the longhands it doesn't mention.
165
+
122
166
  ## How it lands on the page
123
167
 
124
168
  Flat declarations and every `base` value go to the `style` attribute — most `fx`
@@ -136,16 +180,26 @@ const { css, tokens } = collectFx();
136
180
  `<style data-fx-sheet data-fx-tokens="${tokens}">${css}</style>`;
137
181
  ```
138
182
 
139
- The client adopts that sheet instead of re-inserting its rules.
183
+ The client adopts that sheet instead of re-inserting its rules. `resetFx()` clears a
184
+ request's rules but keeps the animations — those are registered once at module scope,
185
+ so dropping them would leave every request after the first naming an animation nobody
186
+ emits.
140
187
 
141
188
  ## Composing
142
189
 
143
- `mergeFx` folds a component's own styling, its `slotProps`, and the consumer's
190
+ `mergeFx` folds a component's own styling, its `sp` entries, and the consumer's
144
191
  `fx` into one object — later wins per property, selector blocks and breakpoint
145
192
  records merge rather than replace:
146
193
 
147
194
  ```tsx
148
- resolveFx(mergeFx(componentOwn, slotProps.body?.fx, props.fx));
195
+ resolveFx(mergeFx(componentOwn, sp.body?.fx, props.fx));
196
+ ```
197
+
198
+ A compound component reaches its parts with `slot`, which takes both channels: the
199
+ part's own `sp` entry, and the styles a caller addressed to it through `fx.sp`.
200
+
201
+ ```tsx
202
+ <PageBody {...slot('body', local.fx, local.sp)} />
149
203
  ```
150
204
 
151
205
  ## Binding it to an element
package/dist/index.d.ts CHANGED
@@ -6,5 +6,12 @@ export * from './lib/sheet.js';
6
6
  export * from './lib/merge.js';
7
7
  export * from './lib/color.js';
8
8
  export * from './lib/props.js';
9
+ export * from './lib/slots.js';
10
+ export * from './lib/presets.js';
11
+ export * from './lib/keyframes.js';
12
+ export * from './lib/animations.js';
13
+ export * from './lib/utilities.js';
14
+ export * from './lib/variants.js';
15
+ export { vars } from '@fluixi-ui/tokens/vars';
9
16
  export { hash } from './lib/hash.js';
10
17
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAIlC,OAAO,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC"}
package/dist/index.js CHANGED
@@ -6,4 +6,13 @@ export * from './lib/sheet.js';
6
6
  export * from './lib/merge.js';
7
7
  export * from './lib/color.js';
8
8
  export * from './lib/props.js';
9
+ export * from './lib/slots.js';
10
+ export * from './lib/presets.js';
11
+ export * from './lib/keyframes.js';
12
+ export * from './lib/animations.js';
13
+ export * from './lib/utilities.js';
14
+ export * from './lib/variants.js';
15
+ // The token map, re-exported so the escape hatches — a raw `style`, an inline SVG, a
16
+ // canvas — can reach the same values without a second package import.
17
+ export { vars } from '@fluixi-ui/tokens/vars';
9
18
  export { hash } from './lib/hash.js';
@@ -0,0 +1,55 @@
1
+ import { type AnimationOptions } from './keyframes.js';
2
+ import type { FxObject, SizeValue } from './types.js';
3
+ /**
4
+ * The stock animations, as `fx` objects you can use directly or merge into one.
5
+ *
6
+ * Each is a function so the options stay open — `fadeIn('slow')`, `spin({ duration:
7
+ * 1200 })` — and so the `@keyframes` rule is registered on FIRST USE rather than on
8
+ * import. A module-scope `keyframes()` call in this file would put every animation's
9
+ * rule in the sheet of every app that imports anything from the package.
10
+ *
11
+ * They compose like any other `fx` object, and what merges after them wins:
12
+ *
13
+ * fx={mergeFx(fadeIn(), { p: 4 })}
14
+ *
15
+ * None of them opts out of motion for you: what "reduced motion" means depends on the
16
+ * animation (a decorative fade should stop, a loading spinner mostly shouldn't). Say it
17
+ * where you use it — `fx={{ ...pulse(), _motionReduce: { animationName: 'none' } }}`.
18
+ */
19
+ /** A bare duration is the common case, so it's accepted in place of the options. */
20
+ type Options = AnimationOptions | AnimationOptions['duration'];
21
+ export declare const fadeIn: (options?: Options) => FxObject;
22
+ export declare const fadeOut: (options?: Options) => FxObject;
23
+ /** The overlay/menu entrance: a fade with a slight scale, rather than a pop. */
24
+ export declare const scaleIn: (options?: Options) => FxObject;
25
+ export declare const scaleOut: (options?: Options) => FxObject;
26
+ /** Loaders: linear, or the rotation visibly eases and looks like it's stalling. */
27
+ export declare const spin: (options?: Options) => FxObject;
28
+ /** Attention without movement — safe where a transform would reflow or distract. */
29
+ export declare const pulse: (options?: Options) => FxObject;
30
+ export type SlideEdge = 'top' | 'bottom' | 'left' | 'right';
31
+ export interface SlideOptions extends AnimationOptions {
32
+ /** How far it travels. A number is pixels. */
33
+ distance?: SizeValue;
34
+ }
35
+ /**
36
+ * Slide in from an edge, fading as it goes. The edge is where it comes FROM, so
37
+ * `slideIn('bottom')` rises into place.
38
+ *
39
+ * The keyframes depend on the distance, so this can't be a fixed pair like the
40
+ * others — each distance is its own rule, deduped by the usual hash.
41
+ */
42
+ export declare function slideIn(from: SlideEdge, options?: SlideOptions): FxObject;
43
+ /** The reverse: `slideOut('top')` leaves upward. */
44
+ export declare function slideOut(to: SlideEdge, options?: SlideOptions): FxObject;
45
+ /**
46
+ * The loading sweep. Unlike the others this carries its own paint — the animation is
47
+ * only the moving half, and a bare `backgroundPosition` animation over an element with
48
+ * no gradient does nothing at all.
49
+ *
50
+ * It animates `background-position`, which doesn't invalidate layout, and leans on the
51
+ * token colours so it follows the theme.
52
+ */
53
+ export declare function shimmer(options?: Options): FxObject;
54
+ export {};
55
+ //# sourceMappingURL=animations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"animations.d.ts","sourceRoot":"","sources":["../../src/lib/animations.ts"],"names":[],"mappings":"AACA,OAAO,EAAsB,KAAK,gBAAgB,EAAsB,MAAM,gBAAgB,CAAC;AAC/F,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEtD;;;;;;;;;;;;;;;GAeG;AAEH,oFAAoF;AACpF,KAAK,OAAO,GAAG,gBAAgB,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC;AAiB/D,eAAO,MAAM,MAAM,aATA,OAAO,KAAQ,QASkD,CAAC;AAErF,eAAO,MAAM,OAAO,aAXD,OAAO,KAAQ,QAWmD,CAAC;AAEtF,gFAAgF;AAChF,eAAO,MAAM,OAAO,aAdD,OAAO,KAAQ,QAiBjC,CAAC;AAEF,eAAO,MAAM,QAAQ,aAnBF,OAAO,KAAQ,QAsBjC,CAAC;AAEF,mFAAmF;AACnF,eAAO,MAAM,IAAI,aAzBE,OAAO,KAAQ,QA4BjC,CAAC;AAEF,oFAAoF;AACpF,eAAO,MAAM,KAAK,aA/BC,OAAO,KAAQ,QAkCjC,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;AAY5D,MAAM,WAAW,YAAa,SAAQ,gBAAgB;IACpD,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,GAAE,YAAiB,GAAG,QAAQ,CAU7E;AAED,oDAAoD;AACpD,wBAAgB,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,OAAO,GAAE,YAAiB,GAAG,QAAQ,CAU5E;AAOD;;;;;;;GAOG;AACH,wBAAgB,OAAO,CAAC,OAAO,GAAE,OAAY,GAAG,QAAQ,CAMvD"}
@@ -0,0 +1,73 @@
1
+ import { vars } from '@fluixi-ui/tokens/vars';
2
+ import { animate, keyframes } from './keyframes.js';
3
+ function toConfig(options) {
4
+ return typeof options === 'object' ? options : { duration: options };
5
+ }
6
+ function animation(steps, defaults = {}) {
7
+ let name;
8
+ return (options = {}) => animate((name ??= keyframes(steps)), { ...defaults, ...toConfig(options) });
9
+ }
10
+ /**
11
+ * Enter animations hold both ends: without `fill` the element sits at its final
12
+ * style before the animation starts, which shows as a flash of the finished state.
13
+ */
14
+ const ENTER = { fill: 'both' };
15
+ export const fadeIn = animation({ from: { opacity: 0 }, to: { opacity: 1 } }, ENTER);
16
+ export const fadeOut = animation({ from: { opacity: 1 }, to: { opacity: 0 } }, ENTER);
17
+ /** The overlay/menu entrance: a fade with a slight scale, rather than a pop. */
18
+ export const scaleIn = animation({ from: { opacity: 0, transform: 'scale(0.96)' }, to: { opacity: 1, transform: 'scale(1)' } }, ENTER);
19
+ export const scaleOut = animation({ from: { opacity: 1, transform: 'scale(1)' }, to: { opacity: 0, transform: 'scale(0.96)' } }, ENTER);
20
+ /** Loaders: linear, or the rotation visibly eases and looks like it's stalling. */
21
+ export const spin = animation({ from: { transform: 'rotate(0deg)' }, to: { transform: 'rotate(360deg)' } }, { duration: 800, easing: 'linear', repeat: 'infinite' });
22
+ /** Attention without movement — safe where a transform would reflow or distract. */
23
+ export const pulse = animation({ '0%': { opacity: 1 }, '50%': { opacity: 0.5 }, '100%': { opacity: 1 } }, { duration: 1500, repeat: 'infinite' });
24
+ /** How far a slide travels when nothing says otherwise. Enough to read as motion. */
25
+ const SLIDE_DISTANCE = 8;
26
+ const OFFSET = {
27
+ top: (d) => `translateY(-${d})`,
28
+ bottom: (d) => `translateY(${d})`,
29
+ left: (d) => `translateX(-${d})`,
30
+ right: (d) => `translateX(${d})`,
31
+ };
32
+ /**
33
+ * Slide in from an edge, fading as it goes. The edge is where it comes FROM, so
34
+ * `slideIn('bottom')` rises into place.
35
+ *
36
+ * The keyframes depend on the distance, so this can't be a fixed pair like the
37
+ * others — each distance is its own rule, deduped by the usual hash.
38
+ */
39
+ export function slideIn(from, options = {}) {
40
+ const { distance = SLIDE_DISTANCE, ...rest } = options;
41
+ const offset = OFFSET[from](typeof distance === 'number' ? `${distance}px` : distance);
42
+ const name = keyframes({
43
+ from: { opacity: 0, transform: offset },
44
+ to: { opacity: 1, transform: 'translate(0)' },
45
+ });
46
+ return animate(name, { ...ENTER, ...rest });
47
+ }
48
+ /** The reverse: `slideOut('top')` leaves upward. */
49
+ export function slideOut(to, options = {}) {
50
+ const { distance = SLIDE_DISTANCE, ...rest } = options;
51
+ const offset = OFFSET[to](typeof distance === 'number' ? `${distance}px` : distance);
52
+ const name = keyframes({
53
+ from: { opacity: 1, transform: 'translate(0)' },
54
+ to: { opacity: 0, transform: offset },
55
+ });
56
+ return animate(name, { ...ENTER, ...rest });
57
+ }
58
+ const shimmerRun = animation({ from: { backgroundPosition: '200% 0' }, to: { backgroundPosition: '-200% 0' } }, { duration: 1500, easing: 'linear', repeat: 'infinite' });
59
+ /**
60
+ * The loading sweep. Unlike the others this carries its own paint — the animation is
61
+ * only the moving half, and a bare `backgroundPosition` animation over an element with
62
+ * no gradient does nothing at all.
63
+ *
64
+ * It animates `background-position`, which doesn't invalidate layout, and leans on the
65
+ * token colours so it follows the theme.
66
+ */
67
+ export function shimmer(options = {}) {
68
+ return {
69
+ backgroundImage: `linear-gradient(90deg, ${vars.color.bgSubtle} 25%, ${vars.color.bgMuted} 37%, ${vars.color.bgSubtle} 63%)`,
70
+ backgroundSize: '400% 100%',
71
+ ...shimmerRun(options),
72
+ };
73
+ }
@@ -0,0 +1,70 @@
1
+ import type { DurationToken, EasingToken } from './scales.js';
2
+ import type { FxDeclarations, FxObject } from './types.js';
3
+ /**
4
+ * Animation stops. `from`/`to` for the two-stop case, percentages for the rest —
5
+ * exactly what CSS accepts, so there is nothing to translate in your head.
6
+ *
7
+ * A stop is flat declarations only: selectors and breakpoints have no meaning
8
+ * inside `@keyframes`, and the type says so rather than dropping them silently.
9
+ */
10
+ export type KeyframeSteps = {
11
+ from?: FxDeclarations;
12
+ to?: FxDeclarations;
13
+ } & {
14
+ [K in `${number}%`]?: FxDeclarations;
15
+ };
16
+ /**
17
+ * Define an animation and get its name back.
18
+ *
19
+ * ```tsx
20
+ * const pulse = keyframes({ from: { opacity: 0.4 }, to: { opacity: 1 } });
21
+ *
22
+ * <Box fx={{ animationName: pulse, animationDuration: 600, animationIterationCount: 'infinite' }} />
23
+ * ```
24
+ *
25
+ * The name is hashed from the resolved stops, so defining the same animation twice —
26
+ * in two packages, or in a component rendered a hundred times — is one rule. Values
27
+ * go through the same resolver as `fx`, so tokens work inside a stop.
28
+ *
29
+ * Call it at module scope. It registers a rule for the life of the process, which is
30
+ * what an animation definition is; calling it per render would hash the same body
31
+ * over and over for nothing.
32
+ */
33
+ export declare function keyframes(steps: KeyframeSteps): string;
34
+ /** Keeps the token union's autocomplete while still accepting any raw CSS value. */
35
+ type Raw = string & {};
36
+ export interface AnimationOptions {
37
+ /** A duration token or milliseconds. Defaults to `normal`. */
38
+ duration?: DurationToken | number | Raw;
39
+ /** An easing token or any timing function. Defaults to `standard`. */
40
+ easing?: EasingToken | Raw;
41
+ delay?: DurationToken | number | Raw;
42
+ /** Iteration count. `'infinite'` for a loop. */
43
+ repeat?: number | 'infinite';
44
+ direction?: 'normal' | 'reverse' | 'alternate' | 'alternate-reverse';
45
+ /** Which end the animation holds outside its run. CSS defaults to `none`. */
46
+ fill?: 'none' | 'forwards' | 'backwards' | 'both';
47
+ /** Hold at the current frame — for an animation driven by state. */
48
+ paused?: boolean;
49
+ }
50
+ /**
51
+ * The longhands for running an animation, in one call.
52
+ *
53
+ * ```tsx
54
+ * <Box fx={animate(pulse, { repeat: 'infinite' })} />
55
+ * <Box fx={animate(slideIn, 'slow')} />
56
+ * <Box fx={mergeFx(animate(pulse, 600), { bg: 'primary' })} />
57
+ * ```
58
+ *
59
+ * A bare second argument is the duration, since that's the one you always set.
60
+ * Duration and easing default to the `normal`/`standard` tokens — a CSS animation
61
+ * with no duration doesn't run at all, and that silence is hard to debug. Everything
62
+ * else is left off unless you ask for it, so what lands is what CSS would do.
63
+ *
64
+ * It returns a plain object rather than the `animation` shorthand string, so it
65
+ * merges with, and can be overridden by, the properties around it — a shorthand
66
+ * would silently reset the longhands it doesn't mention.
67
+ */
68
+ export declare function animate(name: string, options?: AnimationOptions | AnimationOptions['duration']): FxObject;
69
+ export {};
70
+ //# sourceMappingURL=keyframes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keyframes.d.ts","sourceRoot":"","sources":["../../src/lib/keyframes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE9D,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3D;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,EAAE,CAAC,EAAE,cAAc,CAAC;CACrB,GAAG;KAAG,CAAC,IAAI,GAAG,MAAM,GAAG,CAAC,CAAC,EAAE,cAAc;CAAE,CAAC;AAE7C;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAYtD;AAED,oFAAoF;AACpF,KAAK,GAAG,GAAG,MAAM,GAAG,EAAE,CAAC;AAEvB,MAAM,WAAW,gBAAgB;IAC/B,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,aAAa,GAAG,MAAM,GAAG,GAAG,CAAC;IACxC,sEAAsE;IACtE,MAAM,CAAC,EAAE,WAAW,GAAG,GAAG,CAAC;IAC3B,KAAK,CAAC,EAAE,aAAa,GAAG,MAAM,GAAG,GAAG,CAAC;IACrC,gDAAgD;IAChD,MAAM,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC;IAC7B,SAAS,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,mBAAmB,CAAC;IACrE,6EAA6E;IAC7E,IAAI,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,WAAW,GAAG,MAAM,CAAC;IAClD,oEAAoE;IACpE,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,OAAO,CACrB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,gBAAgB,GAAG,gBAAgB,CAAC,UAAU,CAAM,GAC5D,QAAQ,CAcV"}
@@ -0,0 +1,63 @@
1
+ import { hash } from './hash.js';
2
+ import { resolveFx } from './resolve.js';
3
+ import { registerKeyframes } from './sheet.js';
4
+ /**
5
+ * Define an animation and get its name back.
6
+ *
7
+ * ```tsx
8
+ * const pulse = keyframes({ from: { opacity: 0.4 }, to: { opacity: 1 } });
9
+ *
10
+ * <Box fx={{ animationName: pulse, animationDuration: 600, animationIterationCount: 'infinite' }} />
11
+ * ```
12
+ *
13
+ * The name is hashed from the resolved stops, so defining the same animation twice —
14
+ * in two packages, or in a component rendered a hundred times — is one rule. Values
15
+ * go through the same resolver as `fx`, so tokens work inside a stop.
16
+ *
17
+ * Call it at module scope. It registers a rule for the life of the process, which is
18
+ * what an animation definition is; calling it per render would hash the same body
19
+ * over and over for nothing.
20
+ */
21
+ export function keyframes(steps) {
22
+ const body = Object.keys(steps)
23
+ .map((stop) => {
24
+ const declarations = resolveFx(steps[stop]).style;
25
+ return declarations ? `${stop}{${declarations}}` : '';
26
+ })
27
+ .join('');
28
+ // Named after the body, not the call site: two identical definitions collapse.
29
+ const name = `fx-${hash(body)}`;
30
+ registerKeyframes(name, body);
31
+ return name;
32
+ }
33
+ /**
34
+ * The longhands for running an animation, in one call.
35
+ *
36
+ * ```tsx
37
+ * <Box fx={animate(pulse, { repeat: 'infinite' })} />
38
+ * <Box fx={animate(slideIn, 'slow')} />
39
+ * <Box fx={mergeFx(animate(pulse, 600), { bg: 'primary' })} />
40
+ * ```
41
+ *
42
+ * A bare second argument is the duration, since that's the one you always set.
43
+ * Duration and easing default to the `normal`/`standard` tokens — a CSS animation
44
+ * with no duration doesn't run at all, and that silence is hard to debug. Everything
45
+ * else is left off unless you ask for it, so what lands is what CSS would do.
46
+ *
47
+ * It returns a plain object rather than the `animation` shorthand string, so it
48
+ * merges with, and can be overridden by, the properties around it — a shorthand
49
+ * would silently reset the longhands it doesn't mention.
50
+ */
51
+ export function animate(name, options = {}) {
52
+ const config = typeof options === 'object' ? options : { duration: options };
53
+ return {
54
+ animationName: name,
55
+ animationDuration: config.duration ?? 'normal',
56
+ animationTimingFunction: config.easing ?? 'standard',
57
+ ...(config.delay == null ? {} : { animationDelay: config.delay }),
58
+ ...(config.repeat == null ? {} : { animationIterationCount: config.repeat }),
59
+ ...(config.direction == null ? {} : { animationDirection: config.direction }),
60
+ ...(config.fill == null ? {} : { animationFillMode: config.fill }),
61
+ ...(config.paused ? { animationPlayState: 'paused' } : {}),
62
+ };
63
+ }
@@ -1,7 +1,7 @@
1
1
  import type { FxObject, FxProp } from './types.js';
2
2
  /**
3
3
  * Combine style objects, later winning per property. Used to fold a component's
4
- * own styling, its `slotProps`, and the consumer's `fx` into one object before
4
+ * own styling, its `sp`, and the consumer's `fx` into one object before
5
5
  * resolving — so all three compose instead of clobbering.
6
6
  */
7
7
  export declare function mergeFx(...inputs: FxProp[]): FxObject;
package/dist/lib/merge.js CHANGED
@@ -32,7 +32,7 @@ function mergeInto(target, source) {
32
32
  }
33
33
  /**
34
34
  * Combine style objects, later winning per property. Used to fold a component's
35
- * own styling, its `slotProps`, and the consumer's `fx` into one object before
35
+ * own styling, its `sp`, and the consumer's `fx` into one object before
36
36
  * resolving — so all three compose instead of clobbering.
37
37
  */
38
38
  export function mergeFx(...inputs) {
@@ -0,0 +1,67 @@
1
+ import type { FxObject, SizeValue, SpaceValue } from './types.js';
2
+ /**
3
+ * Ready-made `fx` objects for the patterns that take several declarations to express.
4
+ *
5
+ * These earn a name because the declarations only work together — `truncate` is three
6
+ * properties and dropping one silently does nothing, `visuallyHidden` is the clip
7
+ * recipe, `lineClamp` needs the `-webkit-*` trio. One-liners are deliberately absent:
8
+ * `{ display: 'flex' }` is already short, and a preset for it would only be a second
9
+ * vocabulary for the same thing.
10
+ *
11
+ * Each returns a plain `FxObject`, so they compose with `mergeFx`, nest inside `sp`,
12
+ * and are overridden by whatever the caller passes after them:
13
+ *
14
+ * fx={mergeFx(stack(3), props.fx)}
15
+ */
16
+ /** Column flex with a gap. */
17
+ export declare function stack(gap?: SpaceValue): FxObject;
18
+ /** Row flex with a gap, centred on the cross axis — the toolbar/label default. */
19
+ export declare function row(gap?: SpaceValue): FxObject;
20
+ /** Centre a single child both ways. */
21
+ export declare const center: FxObject;
22
+ /** Cover the nearest positioned ancestor. */
23
+ export declare const absoluteFill: FxObject;
24
+ /** Fixed box. One argument is a square. */
25
+ export declare function size(width: SizeValue, height?: SizeValue): FxObject;
26
+ /** Fixed square — `size(n)` under a name that says why. */
27
+ export declare function square(edge: SizeValue): FxObject;
28
+ /** Hold a ratio while the width is driven by the layout. */
29
+ export declare function aspect(ratio: number | string): FxObject;
30
+ /** One line, ellipsised. All three declarations are required for the effect. */
31
+ export declare const truncate: FxObject;
32
+ /**
33
+ * Ellipsis after `lines` lines. Still the `-webkit-box` recipe in every engine —
34
+ * `line-clamp` proper is not broadly supported yet.
35
+ */
36
+ export declare function lineClamp(lines: number): FxObject;
37
+ /**
38
+ * A scroll region. `overscrollBehavior` stops the scroll chaining to the page when
39
+ * the region hits its end, which is the part people forget.
40
+ */
41
+ export declare function scrollY(maxHeight?: SizeValue): FxObject;
42
+ /** Horizontal counterpart of {@link scrollY}. */
43
+ export declare function scrollX(maxWidth?: SizeValue): FxObject;
44
+ /**
45
+ * Out of sight, still read aloud. `display: none` and `visibility: hidden` both take
46
+ * it out of the accessibility tree, which is the opposite of the point.
47
+ */
48
+ export declare const visuallyHidden: FxObject;
49
+ /** Text that should not be selected by a drag — handles, chrome, controls. */
50
+ export declare const noSelect: FxObject;
51
+ /**
52
+ * Scroll without a visible scrollbar. Three vendors, three mechanisms, and the WebKit
53
+ * one is a pseudo-element rather than a property — which is why `_scrollbar` exists in
54
+ * the selector set.
55
+ */
56
+ export declare const scrollbarHidden: FxObject;
57
+ /**
58
+ * Paint text with a background. `background-clip: text` needs its WebKit twin (the
59
+ * resolver mirrors that) and the fill colour has to be transparent for the background
60
+ * to show through — `color: transparent` alone leaves WebKit painting the glyphs.
61
+ */
62
+ export declare function gradientText(image: string): FxObject;
63
+ /** Kill the grey flash iOS paints over a tapped element. */
64
+ export declare const noTapHighlight: FxObject;
65
+ /** Momentum scrolling on older iOS; inert everywhere else. */
66
+ export declare const touchScroll: FxObject;
67
+ //# sourceMappingURL=presets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["../../src/lib/presets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAElE;;;;;;;;;;;;;GAaG;AAEH,8BAA8B;AAC9B,wBAAgB,KAAK,CAAC,GAAG,GAAE,UAAc,GAAG,QAAQ,CAEnD;AAED,kFAAkF;AAClF,wBAAgB,GAAG,CAAC,GAAG,GAAE,UAAc,GAAG,QAAQ,CAEjD;AAED,uCAAuC;AACvC,eAAO,MAAM,MAAM,EAAE,QAAoD,CAAC;AAE1E,6CAA6C;AAC7C,eAAO,MAAM,YAAY,EAAE,QAA6C,CAAC;AAEzE,2CAA2C;AAC3C,wBAAgB,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,GAAE,SAAiB,GAAG,QAAQ,CAE1E;AAED,2DAA2D;AAC3D,wBAAgB,MAAM,CAAC,IAAI,EAAE,SAAS,GAAG,QAAQ,CAEhD;AAED,4DAA4D;AAC5D,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ,CAEvD;AAED,gFAAgF;AAChF,eAAO,MAAM,QAAQ,EAAE,QAItB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAOjD;AAED;;;GAGG;AACH,wBAAgB,OAAO,CAAC,SAAS,CAAC,EAAE,SAAS,GAAG,QAAQ,CAEvD;AAED,iDAAiD;AACjD,wBAAgB,OAAO,CAAC,QAAQ,CAAC,EAAE,SAAS,GAAG,QAAQ,CAEtD;AAED;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,QAU5B,CAAC;AAEF,8EAA8E;AAC9E,eAAO,MAAM,QAAQ,EAAE,QAAiC,CAAC;AAEzD;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,QAIjB,CAAC;AAEd;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAOpD;AAED,4DAA4D;AAC5D,eAAO,MAAM,cAAc,EAAE,QAAiE,CAAC;AAE/F,8DAA8D;AAC9D,eAAO,MAAM,WAAW,EAAE,QAA2D,CAAC"}
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Ready-made `fx` objects for the patterns that take several declarations to express.
3
+ *
4
+ * These earn a name because the declarations only work together — `truncate` is three
5
+ * properties and dropping one silently does nothing, `visuallyHidden` is the clip
6
+ * recipe, `lineClamp` needs the `-webkit-*` trio. One-liners are deliberately absent:
7
+ * `{ display: 'flex' }` is already short, and a preset for it would only be a second
8
+ * vocabulary for the same thing.
9
+ *
10
+ * Each returns a plain `FxObject`, so they compose with `mergeFx`, nest inside `sp`,
11
+ * and are overridden by whatever the caller passes after them:
12
+ *
13
+ * fx={mergeFx(stack(3), props.fx)}
14
+ */
15
+ /** Column flex with a gap. */
16
+ export function stack(gap = 0) {
17
+ return { display: 'flex', flexDirection: 'column', gap };
18
+ }
19
+ /** Row flex with a gap, centred on the cross axis — the toolbar/label default. */
20
+ export function row(gap = 0) {
21
+ return { display: 'flex', flexDirection: 'row', alignItems: 'center', gap };
22
+ }
23
+ /** Centre a single child both ways. */
24
+ export const center = { display: 'grid', placeItems: 'center' };
25
+ /** Cover the nearest positioned ancestor. */
26
+ export const absoluteFill = { position: 'absolute', inset: 0 };
27
+ /** Fixed box. One argument is a square. */
28
+ export function size(width, height = width) {
29
+ return { width, height };
30
+ }
31
+ /** Fixed square — `size(n)` under a name that says why. */
32
+ export function square(edge) {
33
+ return size(edge);
34
+ }
35
+ /** Hold a ratio while the width is driven by the layout. */
36
+ export function aspect(ratio) {
37
+ return { aspectRatio: String(ratio) };
38
+ }
39
+ /** One line, ellipsised. All three declarations are required for the effect. */
40
+ export const truncate = {
41
+ overflow: 'hidden',
42
+ textOverflow: 'ellipsis',
43
+ whiteSpace: 'nowrap',
44
+ };
45
+ /**
46
+ * Ellipsis after `lines` lines. Still the `-webkit-box` recipe in every engine —
47
+ * `line-clamp` proper is not broadly supported yet.
48
+ */
49
+ export function lineClamp(lines) {
50
+ return {
51
+ display: '-webkit-box',
52
+ webkitBoxOrient: 'vertical',
53
+ webkitLineClamp: lines,
54
+ overflow: 'hidden',
55
+ };
56
+ }
57
+ /**
58
+ * A scroll region. `overscrollBehavior` stops the scroll chaining to the page when
59
+ * the region hits its end, which is the part people forget.
60
+ */
61
+ export function scrollY(maxHeight) {
62
+ return { overflowY: 'auto', overscrollBehavior: 'contain', ...(maxHeight == null ? {} : { maxHeight }) };
63
+ }
64
+ /** Horizontal counterpart of {@link scrollY}. */
65
+ export function scrollX(maxWidth) {
66
+ return { overflowX: 'auto', overscrollBehavior: 'contain', ...(maxWidth == null ? {} : { maxWidth }) };
67
+ }
68
+ /**
69
+ * Out of sight, still read aloud. `display: none` and `visibility: hidden` both take
70
+ * it out of the accessibility tree, which is the opposite of the point.
71
+ */
72
+ export const visuallyHidden = {
73
+ position: 'absolute',
74
+ width: '1px',
75
+ height: '1px',
76
+ margin: '-1px',
77
+ padding: 0,
78
+ border: '0',
79
+ overflow: 'hidden',
80
+ whiteSpace: 'nowrap',
81
+ clipPath: 'inset(50%)',
82
+ };
83
+ /** Text that should not be selected by a drag — handles, chrome, controls. */
84
+ export const noSelect = { userSelect: 'none' };
85
+ /**
86
+ * Scroll without a visible scrollbar. Three vendors, three mechanisms, and the WebKit
87
+ * one is a pseudo-element rather than a property — which is why `_scrollbar` exists in
88
+ * the selector set.
89
+ */
90
+ export const scrollbarHidden = {
91
+ scrollbarWidth: 'none',
92
+ msOverflowStyle: 'none',
93
+ _scrollbar: { display: 'none' },
94
+ };
95
+ /**
96
+ * Paint text with a background. `background-clip: text` needs its WebKit twin (the
97
+ * resolver mirrors that) and the fill colour has to be transparent for the background
98
+ * to show through — `color: transparent` alone leaves WebKit painting the glyphs.
99
+ */
100
+ export function gradientText(image) {
101
+ return {
102
+ backgroundImage: image,
103
+ backgroundClip: 'text',
104
+ color: 'transparent',
105
+ webkitTextFillColor: 'transparent',
106
+ };
107
+ }
108
+ /** Kill the grey flash iOS paints over a tapped element. */
109
+ export const noTapHighlight = { webkitTapHighlightColor: 'transparent' };
110
+ /** Momentum scrolling on older iOS; inert everywhere else. */
111
+ export const touchScroll = { webkitOverflowScrolling: 'touch' };
@@ -1 +1 @@
1
- {"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/lib/resolve.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAqB,MAAM,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AA+ItE;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAkBjD"}
1
+ {"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/lib/resolve.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAqB,MAAM,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAuKtE;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAkBjD"}
@@ -5,6 +5,8 @@ import { composeSelectors, isSelectorKey, selectorEntry } from './selectors.js';
5
5
  const BREAKPOINTS = breakpoint;
6
6
  const ROOT = ['&'];
7
7
  const CONTAINER_KEY = '_container';
8
+ /** Slot styles are read by the component, not by the resolver — never a property. */
9
+ const SLOTS_KEY = 'sp';
8
10
  function isPlainObject(value) {
9
11
  return typeof value === 'object' && value !== null && !Array.isArray(value);
10
12
  }
@@ -57,6 +59,8 @@ function walk(object, selectors, atRules, buckets) {
57
59
  const value = object[name];
58
60
  if (value == null || value === false)
59
61
  continue;
62
+ if (name === SLOTS_KEY)
63
+ continue;
60
64
  if (name === CONTAINER_KEY) {
61
65
  if (isPlainObject(value))
62
66
  walkContainer(value, selectors, atRules, buckets);
@@ -114,7 +118,26 @@ function walkContainer(query, selectors, atRules, buckets) {
114
118
  walk(block, selectors, [...atRules, `@container ${name}${condition}`], buckets);
115
119
  }
116
120
  }
121
+ /**
122
+ * Properties Safari still only understands prefixed. Written before the standard name
123
+ * so the standard one wins wherever it is supported, and kept to the handful that
124
+ * actually need it — this is not a general autoprefixer, and a stale entry here is a
125
+ * declaration shipped to every user forever.
126
+ */
127
+ const MIRRORED = {
128
+ backdropFilter: 'webkitBackdropFilter',
129
+ backgroundClip: 'webkitBackgroundClip',
130
+ maskImage: 'webkitMaskImage',
131
+ userSelect: 'webkitUserSelect',
132
+ appearance: 'webkitAppearance',
133
+ hyphens: 'webkitHyphens',
134
+ textSizeAdjust: 'webkitTextSizeAdjust',
135
+ };
117
136
  function declare(bucket, property, value) {
137
+ const prefixed = MIRRORED[property];
138
+ if (prefixed) {
139
+ bucket.declarations.set(prefixed, `${cssProperty(prefixed)}:${resolveValue(property, value)}`);
140
+ }
118
141
  bucket.declarations.set(property, `${cssProperty(property)}:${resolveValue(property, value)}`);
119
142
  }
120
143
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"scales.d.ts","sourceRoot":"","sources":["../../src/lib/scales.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAE9C;;;GAGG;AACH,MAAM,MAAM,KAAK,GACb,OAAO,GACP,MAAM,GACN,OAAO,GACP,QAAQ,GACR,QAAQ,GACR,UAAU,GACV,YAAY,GACZ,YAAY,GACZ,eAAe,GACf,YAAY,GACZ,aAAa,GACb,UAAU,GACV,QAAQ,GACR,SAAS,GACT,QAAQ,GACR,UAAU,CAAC;AAEf,MAAM,MAAM,SAAS,GAAG,MAAM,OAAO,IAAI,CAAC,KAAK,CAAC;AAChD,MAAM,MAAM,UAAU,GAAG,MAAM,OAAO,IAAI,CAAC,KAAK,CAAC;AACjD,MAAM,MAAM,WAAW,GAAG,MAAM,OAAO,IAAI,CAAC,MAAM,CAAC;AACnD,MAAM,MAAM,WAAW,GAAG,MAAM,OAAO,IAAI,CAAC,MAAM,CAAC;AACnD,MAAM,MAAM,aAAa,GAAG,MAAM,OAAO,IAAI,CAAC,QAAQ,CAAC;AACvD,MAAM,MAAM,eAAe,GAAG,MAAM,OAAO,IAAI,CAAC,UAAU,CAAC;AAC3D,MAAM,MAAM,eAAe,GAAG,MAAM,OAAO,IAAI,CAAC,UAAU,CAAC;AAC3D,MAAM,MAAM,kBAAkB,GAAG,MAAM,OAAO,IAAI,CAAC,aAAa,CAAC;AACjE,MAAM,MAAM,eAAe,GAAG,MAAM,OAAO,IAAI,CAAC,UAAU,CAAC;AAC3D,MAAM,MAAM,gBAAgB,GAAG,MAAM,OAAO,IAAI,CAAC,WAAW,CAAC;AAC7D,MAAM,MAAM,aAAa,GAAG,MAAM,OAAO,IAAI,CAAC,QAAQ,CAAC;AACvD,MAAM,MAAM,WAAW,GAAG,MAAM,OAAO,IAAI,CAAC,MAAM,CAAC;AACnD,MAAM,MAAM,YAAY,GAAG,MAAM,OAAO,IAAI,CAAC,OAAO,CAAC;AACrD,MAAM,MAAM,WAAW,GAAG,MAAM,OAAO,IAAI,CAAC,MAAM,CAAC;AAEnD;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;AAE/F,QAAA,MAAM,WAAW,wiBAqCP,CAAC;AAEX,QAAA,MAAM,UAAU,0LAcN,CAAC;AAEX,QAAA,MAAM,WAAW,sYAsBP,CAAC;AAEX,QAAA,MAAM,YAAY,+NAUR,CAAC;AAEX,QAAA,MAAM,kBAAkB,iKASd,CAAC;AAEX,QAAA,MAAM,cAAc,8DAA+D,CAAC;AAEpF,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AACrD,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AACnD,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AACrD,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AACvD,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC;AAClE,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAM3D,sFAAsF;AACtF,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAqBzC,CAAC;AAEL;;;;GAIG;AACH,eAAO,MAAM,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAU1C,CAAC;AA0BF;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQlD;AAQD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CA2B7E;AAED,0EAA0E;AAC1E,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGhD"}
1
+ {"version":3,"file":"scales.d.ts","sourceRoot":"","sources":["../../src/lib/scales.ts"],"names":[],"mappings":"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"}