@zakkster/lite-ui-fx 1.1.0 → 1.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.
package/CHANGELOG.md CHANGED
@@ -5,7 +5,97 @@ All notable changes to `@zakkster/lite-ui-fx` are documented here.
5
5
  The format follows Keep a Changelog; this project adheres to Semantic
6
6
  Versioning.
7
7
 
8
- ## [1.1.0] -- unreleased
8
+ ## [1.3.0] -- 2026-09-07
9
+
10
+ The recipe sweep (U3), first pass: zero per-frame allocation across all 50
11
+ recipes (U-03) and geometry derived from state (U-05). The `zero-gc` keyword is
12
+ true for the first time. Theming (U-06) and the blueprint-doc rewrite are a
13
+ deferred follow-up; `themeable` / `motionSafe` stay `false`.
14
+
15
+ ### Fixed
16
+
17
+ - U-03 (zero-GC): every built-in recipe now runs its per-frame body -- idle and
18
+ under interaction -- without allocating. Per-frame `rgba(...,${alpha})` colour
19
+ strings became a const colour + `globalAlpha`; recipes whose RGB varies with a
20
+ value (FlameCounter, HeatMap, DayNightToggle) use a precomputed colour LUT;
21
+ particle `push`/`splice` pools became fixed preallocated pools with a live
22
+ flag; per-frame gradients moved to `init` (VolumeKnob / RingProgress build
23
+ once; LaserSlider / AuroraSlider build a reference gradient in `init` and scale
24
+ it to the fill, AuroraSlider cycling a bounded set of phase gradients); value
25
+ labels read a precomputed `PCT` table or a change-detection cache instead of
26
+ building `${n}%` / `String(n)` / `.toFixed()` per frame; the GlitchButton
27
+ per-tick closure and the CompassKnob / ReactionPicker per-frame array literals
28
+ were hoisted; `setLineDash([4,3])` uses one shared module-level array.
29
+ - U-05 (size-true): spawn and inset positions derive from `st.w` -- NeonPulse
30
+ ring origin (was `46`/`18`), SparkSlider and ScratchReveal spark spawn (was
31
+ `val * 200`), BubbleRating bubble gap (was `200 / 5`).
32
+
33
+ ### Added
34
+
35
+ - `test/torture/t3-frame-alloc.mjs` (+ `t3-scan.mjs`): the U-03 gate. It runs in
36
+ a child process under `--max-semi-space-size=1` and gates each recipe on
37
+ `major === 0`, zero gradient constructions after `init`, and a bounded count of
38
+ distinct fill/stroke colour strings (a per-frame colour template mints
39
+ hundreds; a const palette or LUT a few dozen). Wired into `torture.mjs`.
40
+
41
+ ### Changed
42
+
43
+ - Harness: the recording `Ctx2DStub` backs numeric context properties
44
+ (`globalAlpha`, `lineWidth`, ...) with a `Float64Array` so writing a
45
+ non-integer never boxes a HeapNumber -- the gate measures the recipe, not the
46
+ stub. `gcGate` gained a warmup phase and an optional zero-alloc churn driver.
47
+ - `mountUIFX` forwards the validated options to the recipe factory, so a recipe
48
+ can read its own config (a no-arg or wrapped factory ignores the argument).
49
+ This is inert until the U-06 theming pass uses it.
50
+
51
+ ## [1.2.0] -- 2026-09-06
52
+
53
+ Recipes ship as code (U-13). The three GitHub-only recipe volumes are
54
+ consolidated into one `UIFXRecipes.js` at the package root, exposed as the
55
+ `./recipes` subpath export behind a registry. No recipe body changes -- the
56
+ zero-GC / size-true / theming sweep is U3.
57
+
58
+ ### Added
59
+
60
+ - `./recipes` subpath export: all 50 recipes ship in one `UIFXRecipes.js`
61
+ (with `UIFXRecipes.d.ts`), versioned, typed, and tree-shakeable
62
+ (`sideEffects: false`). `UIFX-RECIPE-GUIDE.md` moves to the package root and
63
+ ships as well.
64
+ - Recipe registry (ported from `@zakkster/lite-scratch-fx`): `RECIPES`
65
+ (null-prototype, id -> factory), `RECIPE_META` (`{ id, name, type, family,
66
+ themeable, motionSafe }`; `themeable` and `motionSafe` are `false` for all
67
+ until U3), `RECIPE_NAMES` (frozen), and `registerRecipe(id, factory, meta)`
68
+ with an in-place meta-merge.
69
+ - `mountRecipe(container, id, options?)`: resolves the id fail closed (an
70
+ unknown id throws with a did-you-mean; a non-string id gets the same clean
71
+ message), asserts any `options.type` matches the recipe's declared type, then
72
+ mounts via `mountUIFX`.
73
+ - Torture: `t0-lifecycle` and `t1-degenerate` iterate `RECIPE_META`, so all 50
74
+ recipes are mounted, exercised, and destroyed by construction. New
75
+ `test/registry.test.mjs` (registry + `mountRecipe` contract + a boundary
76
+ matrix) and `test/treeshake.test.mjs` (an esbuild proof that importing one
77
+ recipe drops the others).
78
+
79
+ ### Changed
80
+
81
+ - Fail closed on the element type: `mountUIFX` now throws on any `type` other
82
+ than `UIType.BUTTON` / `TOGGLE` / `SLIDER` (an unknown type previously became
83
+ a button silently), and `registerRecipe` rejects a recipe with no valid type
84
+ before any mutation.
85
+ - The recipes are no longer a GitHub ZIP / copy-paste. `README.md` and
86
+ `llms.txt` document the `./recipes` import and drop the "not included in the
87
+ npm package" wording.
88
+ - `package.json`: `exports["./recipes"]` added; `files[]` ships
89
+ `UIFXRecipes.js`, `UIFXRecipes.d.ts`, and `UIFX-RECIPE-GUIDE.md`; `esbuild`
90
+ added as a devDependency (the tree-shake proof only -- not shipped).
91
+ - Decision recorded in `decisions/0001-recipes-position.md`.
92
+
93
+ ### Removed
94
+
95
+ - The `recipes/` directory (three volumes plus their `.d.ts`). Their exports
96
+ are unchanged and now come from the root `UIFXRecipes.js`.
97
+
98
+ ## [1.1.0] -- 2026-09-06
9
99
 
10
100
  Controller correctness: the two S1 defects (U-01, U-02) and three
11
101
  controller-level S3s (U-09, U-10, U-11). No visual change at default mounts.
package/README.md CHANGED
@@ -40,26 +40,22 @@ https://cdpn.io/pen/debug/YPGEaYY
40
40
 
41
41
  Every recipe is zero-GC, uses `dt`-based animation, and includes accessibility indicators (focus rings, state labels).
42
42
 
43
- `@zakkster/lite-ui-fx` ships only the core controller on npm (zero bloat).
44
- All visual effects live in the GitHub repo as **recipes**.
43
+ All 50 recipes ship in the package on the `./recipes` subpath -- versioned,
44
+ typed, and tree-shakeable. With `sideEffects: false`, importing one recipe pulls
45
+ in only that recipe, so a controller-only install stays tiny.
45
46
 
46
- **Recipe Collections:**
47
- - Vol. 1 (10 recipes):
48
- https://github.com/PeshoVurtoleta/lite-ui-fx/blob/main/recipes/UIFXRecipes.js
49
- - Vol. 2 (20 recipes):
50
- https://github.com/PeshoVurtoleta/lite-ui-fx/blob/main/recipes/UIFXRecipes2.js
51
- - Vol. 3 (20 recipes):
52
- https://github.com/PeshoVurtoleta/lite-ui-fx/blob/main/recipes/UIFXRecipes3.js
53
-
54
- **How to write your own:**
55
- https://github.com/PeshoVurtoleta/lite-ui-fx/blob/main/recipes/UIFX-RECIPE-GUIDE.md
47
+ ```javascript
48
+ import { mountUIFX, UIType } from '@zakkster/lite-ui-fx';
49
+ import { SwarmToggle } from '@zakkster/lite-ui-fx/recipes';
50
+ ```
56
51
 
57
- Recipes are **optional**, **open-source**, and **not included in the npm package**
58
- to keep the install size tiny (<2 KB).
59
- You can copy/paste any recipe into your project or use them as inspiration.
52
+ The `./recipes` entry also exports a registry for data-driven pickers:
53
+ `RECIPES` (id -> factory), `RECIPE_META` (`{ id, name, type, family }`),
54
+ `RECIPE_NAMES`, `registerRecipe(id, factory, meta)`, and
55
+ `mountRecipe(container, id, options?)` -- which resolves the id fail-closed
56
+ (did-you-mean on a typo) and mounts it as its declared type.
60
57
 
61
- Download all recipes as a ZIP
62
- https://github.com/PeshoVurtoleta/lite-ui-fx/archive/refs/heads/main.zip
58
+ **How to write your own:** see [UIFX-RECIPE-GUIDE.md](UIFX-RECIPE-GUIDE.md), shipped in the package.
63
59
 
64
60
  Part of the [@zakkster/lite-*](https://www.npmjs.com/org/zakkster) ecosystem.
65
61
 
@@ -69,15 +65,15 @@ Part of the [@zakkster/lite-*](https://www.npmjs.com/org/zakkster) ecosystem.
69
65
  npm i @zakkster/lite-ui-fx
70
66
  ```
71
67
 
72
- > Looking for the visual effects?
73
- > Recipes live in the GitHub repo -- not in the npm package -- to keep the library tiny.
68
+ > The 50 recipes ship in the same package on the `./recipes` subpath and
69
+ > tree-shake, so importing one adds only that one.
74
70
 
75
71
 
76
72
  ## Quick Start
77
73
 
78
74
  ```javascript
79
75
  import { mountUIFX, UIType } from '@zakkster/lite-ui-fx';
80
- import { SwarmToggle } from './recipes/UIFXRecipes.js';
76
+ import { SwarmToggle } from '@zakkster/lite-ui-fx/recipes';
81
77
 
82
78
  // Mount a canvas-rendered toggle onto a container
83
79
  const instance = mountUIFX(
@@ -101,17 +97,13 @@ instance.destroy();
101
97
  // Controller (always needed)
102
98
  import { mountUIFX, UIType } from '@zakkster/lite-ui-fx';
103
99
 
104
- // Recipes are NOT included in the npm package.
105
- // Copy them from the GitHub repo into your own ./recipes folder:
106
-
107
- // Vol. 1 -- 10 recipes (toggles, buttons, sliders)
108
- import { SwarmToggle, MagneticButton, SparkSlider } from './recipes/UIFXRecipes.js';
109
-
110
- // Vol. 2 -- 20 recipes (+ loaders, checkboxes, counters, rating)
111
- import { PendulumToggle, HeartbeatButton, RippleCheck } from './recipes/UIFXRecipes2.js';
100
+ // All 50 recipes ship on the ./recipes subpath (tree-shakeable) -- import by name:
101
+ import { SwarmToggle, MagneticButton, SparkSlider } from '@zakkster/lite-ui-fx/recipes';
102
+ import { PendulumToggle, HeartbeatButton, RippleCheck } from '@zakkster/lite-ui-fx/recipes';
103
+ import { VolumeKnob, WaterLevel, TimerCountdown } from '@zakkster/lite-ui-fx/recipes';
112
104
 
113
- // Vol. 3 -- 20 recipes (knobs, progress, controls, indicators, mood, feedback, fun)
114
- import { VolumeKnob, WaterLevel, TimerCountdown } from './recipes/UIFXRecipes3.js';
105
+ // Registry surface for data-driven pickers:
106
+ import { RECIPES, RECIPE_META, RECIPE_NAMES, registerRecipe, mountRecipe } from '@zakkster/lite-ui-fx/recipes';
115
107
  ```
116
108
 
117
109
  ## How It Works
@@ -192,7 +184,7 @@ Returns `{ el, canvas, wrapper, state, destroy() }`.
192
184
 
193
185
  ## Writing Custom Recipes
194
186
 
195
- See the full [UIFX-RECIPE-GUIDE.md](recipes/UIFX-RECIPE-GUIDE.md) (included in the package).
187
+ See the full [UIFX-RECIPE-GUIDE.md](UIFX-RECIPE-GUIDE.md) (included in the package).
196
188
 
197
189
  Minimal recipe:
198
190
 
@@ -226,7 +218,7 @@ Full TypeScript declarations are included for:
226
218
  - `UIFXPointer`
227
219
  - `UIFXRecipe`
228
220
 
229
- (Recipes are not part of the npm package, so their types are not included.)
221
+ Recipe types ship too, on the `./recipes` subpath (`UIFXRecipes.d.ts`).
230
222
 
231
223
 
232
224
  ## LLM-Friendly Documentation
package/UIFXController.js CHANGED
@@ -22,7 +22,7 @@ import { Ticker } from '@zakkster/lite-ticker';
22
22
 
23
23
  // Three-place version sync: this constant, package.json "version", and the
24
24
  // VERSION line in llms.txt must always match. /release keeps them locked.
25
- export const VERSION = '1.1.0';
25
+ export const VERSION = '1.3.0';
26
26
 
27
27
  // ---------------------------------------------------------
28
28
  // SHARED TICKER (ref-counted, one RAF for all UI components)
@@ -177,6 +177,13 @@ export function mountUIFX(container, type, recipeFactory, options = {}) {
177
177
  throw new Error('mountUIFX: container must be a DOM element');
178
178
  }
179
179
 
180
+ // 1b. type: exactly one of the three known element types. An unknown or
181
+ // undefined type is an Error here, never a silent default to a button
182
+ // (fail closed -- the type selects the native element).
183
+ if (type !== UIType.BUTTON && type !== UIType.TOGGLE && type !== UIType.SLIDER) {
184
+ throw new Error('mountUIFX: type must be UIType.BUTTON, UIType.TOGGLE, or UIType.SLIDER');
185
+ }
186
+
180
187
  // 2. options: unknown keys -> did-you-mean; value/checked/disabled
181
188
  // validated and coerced HERE, before any element exists.
182
189
  for (const k in options) {
@@ -206,7 +213,10 @@ export function mountUIFX(container, type, recipeFactory, options = {}) {
206
213
 
207
214
  // 4. recipe object + hooks. Created now so a bad recipe throws BEFORE any
208
215
  // DOM/refcount side effect; .init is deferred to phase 2 (needs ctx).
209
- const recipe = recipeFactory();
216
+ // The validated options are forwarded so a recipe factory can read its
217
+ // own visual config and default a canvas `text` to the accessible
218
+ // `label`; a zero-arg or user-wrapped factory ignores the argument.
219
+ const recipe = recipeFactory(options);
210
220
  if (!recipe || typeof recipe !== 'object') {
211
221
  throw new Error('mountUIFX: recipe must be an object');
212
222
  }
@@ -0,0 +1,253 @@
1
+ import type { UIFXRecipe, UIFXInstance, MountOptions } from './UIFXController';
2
+
3
+ // ===========================================================
4
+ // RECIPE FACTORIES (all 50)
5
+ // ===========================================================
6
+
7
+ // -- Vol.1: Toggles --
8
+ export declare function SwarmToggle(options?: { seed?: number; count?: number }): UIFXRecipe;
9
+ export declare function LiquidToggle(): UIFXRecipe;
10
+ export declare function NeonPulseToggle(): UIFXRecipe;
11
+
12
+ // -- Vol.1: Buttons --
13
+ export declare function MagneticButton(options?: { maxPull?: number }): UIFXRecipe;
14
+ export declare function ShatterButton(options?: { seed?: number }): UIFXRecipe;
15
+ export declare function ConfettiButton(options?: { seed?: number; colors?: string[] }): UIFXRecipe;
16
+ export declare function GlitchButton(options?: { seed?: number }): UIFXRecipe;
17
+
18
+ // -- Vol.1: Sliders --
19
+ export declare function SparkSlider(options?: { seed?: number; color?: string }): UIFXRecipe;
20
+ export declare function CosmicSlider(options?: { seed?: number; dustCount?: number }): UIFXRecipe;
21
+ export declare function LaserSlider(): UIFXRecipe;
22
+
23
+ // -- Vol.2: Toggles --
24
+ export declare function PendulumToggle(): UIFXRecipe;
25
+ export declare function CircuitToggle(options?: { seed?: number }): UIFXRecipe;
26
+ export declare function LightningToggle(options?: { seed?: number }): UIFXRecipe;
27
+ export declare function DNAToggle(): UIFXRecipe;
28
+
29
+ // -- Vol.2: Buttons --
30
+ export declare function HeartbeatButton(options?: { seed?: number }): UIFXRecipe;
31
+ export declare function BreathingButton(): UIFXRecipe;
32
+ export declare function InkSplashButton(options?: { seed?: number }): UIFXRecipe;
33
+ export declare function PixelDissolveButton(options?: { seed?: number; cols?: number; rows?: number }): UIFXRecipe;
34
+ export declare function FireworkButton(options?: { seed?: number }): UIFXRecipe;
35
+
36
+ // -- Vol.2: Sliders --
37
+ export declare function AuroraSlider(): UIFXRecipe;
38
+ export declare function WaveSlider(options?: { seed?: number }): UIFXRecipe;
39
+ export declare function ElasticBandSlider(): UIFXRecipe;
40
+ export declare function GravitySlider(): UIFXRecipe;
41
+
42
+ // -- Vol.2: Loaders --
43
+ export declare function OrbitLoader(): UIFXRecipe;
44
+ export declare function HelixLoader(): UIFXRecipe;
45
+
46
+ // -- Vol.2: Checkboxes --
47
+ export declare function RippleCheck(): UIFXRecipe;
48
+ export declare function MorphCheck(): UIFXRecipe;
49
+
50
+ // -- Vol.2: Counters --
51
+ export declare function FlameCounter(options?: { seed?: number }): UIFXRecipe;
52
+ export declare function GlitchCounter(options?: { seed?: number }): UIFXRecipe;
53
+
54
+ // -- Vol.2: Rating --
55
+ export declare function BubbleRating(options?: { seed?: number }): UIFXRecipe;
56
+
57
+ // -- Vol.3: Knobs --
58
+ export declare function VolumeKnob(): UIFXRecipe;
59
+ export declare function CompassKnob(): UIFXRecipe;
60
+
61
+ // -- Vol.3: Progress --
62
+ export declare function RingProgress(options?: { seed?: number }): UIFXRecipe;
63
+ export declare function BatteryGauge(): UIFXRecipe;
64
+ export declare function SignalMeter(): UIFXRecipe;
65
+
66
+ // -- Vol.3: Controls --
67
+ export declare function PillTabs(): UIFXRecipe;
68
+ export declare function Stepper(): UIFXRecipe;
69
+ export declare function RadioOrbit(): UIFXRecipe;
70
+
71
+ // -- Vol.3: Indicators --
72
+ export declare function PasswordStrength(): UIFXRecipe;
73
+ export declare function WaterLevel(): UIFXRecipe;
74
+ export declare function HeatMap(options?: { seed?: number }): UIFXRecipe;
75
+
76
+ // -- Vol.3: Mood --
77
+ export declare function DayNightToggle(options?: { seed?: number }): UIFXRecipe;
78
+ export declare function ReactionPicker(): UIFXRecipe;
79
+ export declare function NotificationBell(): UIFXRecipe;
80
+
81
+ // -- Vol.3: Feedback --
82
+ export declare function TypewriterField(): UIFXRecipe;
83
+ export declare function SoundWaveBtn(): UIFXRecipe;
84
+ export declare function UploadProgress(): UIFXRecipe;
85
+
86
+ // -- Vol.3: Fun --
87
+ export declare function ScratchReveal(options?: { seed?: number }): UIFXRecipe;
88
+ export declare function TimerCountdown(): UIFXRecipe;
89
+ export declare function PullRefresh(): UIFXRecipe;
90
+
91
+ // ===========================================================
92
+ // BARREL OBJECTS (back-compat)
93
+ // ===========================================================
94
+
95
+ export declare const UIFXRecipes: {
96
+ SwarmToggle: typeof SwarmToggle;
97
+ LiquidToggle: typeof LiquidToggle;
98
+ NeonPulseToggle: typeof NeonPulseToggle;
99
+ MagneticButton: typeof MagneticButton;
100
+ ShatterButton: typeof ShatterButton;
101
+ ConfettiButton: typeof ConfettiButton;
102
+ GlitchButton: typeof GlitchButton;
103
+ SparkSlider: typeof SparkSlider;
104
+ CosmicSlider: typeof CosmicSlider;
105
+ LaserSlider: typeof LaserSlider;
106
+ };
107
+
108
+ export declare const UIFXRecipes2: {
109
+ PendulumToggle: typeof PendulumToggle;
110
+ CircuitToggle: typeof CircuitToggle;
111
+ LightningToggle: typeof LightningToggle;
112
+ DNAToggle: typeof DNAToggle;
113
+ HeartbeatButton: typeof HeartbeatButton;
114
+ BreathingButton: typeof BreathingButton;
115
+ InkSplashButton: typeof InkSplashButton;
116
+ PixelDissolveButton: typeof PixelDissolveButton;
117
+ FireworkButton: typeof FireworkButton;
118
+ AuroraSlider: typeof AuroraSlider;
119
+ WaveSlider: typeof WaveSlider;
120
+ ElasticBandSlider: typeof ElasticBandSlider;
121
+ GravitySlider: typeof GravitySlider;
122
+ OrbitLoader: typeof OrbitLoader;
123
+ HelixLoader: typeof HelixLoader;
124
+ RippleCheck: typeof RippleCheck;
125
+ MorphCheck: typeof MorphCheck;
126
+ FlameCounter: typeof FlameCounter;
127
+ GlitchCounter: typeof GlitchCounter;
128
+ BubbleRating: typeof BubbleRating;
129
+ };
130
+
131
+ export declare const UIFXRecipes3: {
132
+ VolumeKnob: typeof VolumeKnob;
133
+ CompassKnob: typeof CompassKnob;
134
+ RingProgress: typeof RingProgress;
135
+ BatteryGauge: typeof BatteryGauge;
136
+ SignalMeter: typeof SignalMeter;
137
+ PillTabs: typeof PillTabs;
138
+ Stepper: typeof Stepper;
139
+ RadioOrbit: typeof RadioOrbit;
140
+ PasswordStrength: typeof PasswordStrength;
141
+ WaterLevel: typeof WaterLevel;
142
+ HeatMap: typeof HeatMap;
143
+ DayNightToggle: typeof DayNightToggle;
144
+ ReactionPicker: typeof ReactionPicker;
145
+ NotificationBell: typeof NotificationBell;
146
+ TypewriterField: typeof TypewriterField;
147
+ SoundWaveBtn: typeof SoundWaveBtn;
148
+ UploadProgress: typeof UploadProgress;
149
+ ScratchReveal: typeof ScratchReveal;
150
+ TimerCountdown: typeof TimerCountdown;
151
+ PullRefresh: typeof PullRefresh;
152
+ };
153
+
154
+ // ===========================================================
155
+ // RECIPE REGISTRY
156
+ // ===========================================================
157
+
158
+ export type RecipeType = 'toggle' | 'button' | 'slider';
159
+
160
+ export type RecipeFactory = (options?: Record<string, unknown>) => UIFXRecipe;
161
+
162
+ export interface RecipeMeta {
163
+ id: string;
164
+ name: string;
165
+ type: RecipeType;
166
+ family: string;
167
+ themeable: boolean;
168
+ motionSafe: boolean;
169
+ }
170
+
171
+ /** Every recipe factory keyed by id. Null-prototype map. */
172
+ export declare const RECIPES: { [id: string]: RecipeFactory };
173
+
174
+ /** Live metadata array, one row per registered recipe. */
175
+ export declare const RECIPE_META: RecipeMeta[];
176
+
177
+ /** Frozen list of the built-in recipe ids at load time. */
178
+ export declare const RECIPE_NAMES: readonly string[];
179
+
180
+ /** Register a custom recipe, or override a built-in. Returns the factory. */
181
+ export declare function registerRecipe(
182
+ id: string,
183
+ factory: RecipeFactory,
184
+ meta?: Partial<Omit<RecipeMeta, 'id'>>,
185
+ ): RecipeFactory;
186
+
187
+ /**
188
+ * Resolve a recipe id to its factory + declared type and mount it via mountUIFX.
189
+ * Fail closed: unknown id or a conflicting options.type throws.
190
+ */
191
+ export declare function mountRecipe(
192
+ container: HTMLElement,
193
+ id: string,
194
+ options?: MountOptions & { type?: RecipeType },
195
+ ): UIFXInstance;
196
+
197
+ // ===========================================================
198
+ // DEFAULT EXPORT -- combined all-50 namespace
199
+ // ===========================================================
200
+
201
+ declare const UIFXAllRecipes: {
202
+ SwarmToggle: typeof SwarmToggle;
203
+ LiquidToggle: typeof LiquidToggle;
204
+ NeonPulseToggle: typeof NeonPulseToggle;
205
+ MagneticButton: typeof MagneticButton;
206
+ ShatterButton: typeof ShatterButton;
207
+ ConfettiButton: typeof ConfettiButton;
208
+ GlitchButton: typeof GlitchButton;
209
+ SparkSlider: typeof SparkSlider;
210
+ CosmicSlider: typeof CosmicSlider;
211
+ LaserSlider: typeof LaserSlider;
212
+ PendulumToggle: typeof PendulumToggle;
213
+ CircuitToggle: typeof CircuitToggle;
214
+ LightningToggle: typeof LightningToggle;
215
+ DNAToggle: typeof DNAToggle;
216
+ HeartbeatButton: typeof HeartbeatButton;
217
+ BreathingButton: typeof BreathingButton;
218
+ InkSplashButton: typeof InkSplashButton;
219
+ PixelDissolveButton: typeof PixelDissolveButton;
220
+ FireworkButton: typeof FireworkButton;
221
+ AuroraSlider: typeof AuroraSlider;
222
+ WaveSlider: typeof WaveSlider;
223
+ ElasticBandSlider: typeof ElasticBandSlider;
224
+ GravitySlider: typeof GravitySlider;
225
+ OrbitLoader: typeof OrbitLoader;
226
+ HelixLoader: typeof HelixLoader;
227
+ RippleCheck: typeof RippleCheck;
228
+ MorphCheck: typeof MorphCheck;
229
+ FlameCounter: typeof FlameCounter;
230
+ GlitchCounter: typeof GlitchCounter;
231
+ BubbleRating: typeof BubbleRating;
232
+ VolumeKnob: typeof VolumeKnob;
233
+ CompassKnob: typeof CompassKnob;
234
+ RingProgress: typeof RingProgress;
235
+ BatteryGauge: typeof BatteryGauge;
236
+ SignalMeter: typeof SignalMeter;
237
+ PillTabs: typeof PillTabs;
238
+ Stepper: typeof Stepper;
239
+ RadioOrbit: typeof RadioOrbit;
240
+ PasswordStrength: typeof PasswordStrength;
241
+ WaterLevel: typeof WaterLevel;
242
+ HeatMap: typeof HeatMap;
243
+ DayNightToggle: typeof DayNightToggle;
244
+ ReactionPicker: typeof ReactionPicker;
245
+ NotificationBell: typeof NotificationBell;
246
+ TypewriterField: typeof TypewriterField;
247
+ SoundWaveBtn: typeof SoundWaveBtn;
248
+ UploadProgress: typeof UploadProgress;
249
+ ScratchReveal: typeof ScratchReveal;
250
+ TimerCountdown: typeof TimerCountdown;
251
+ PullRefresh: typeof PullRefresh;
252
+ };
253
+ export default UIFXAllRecipes;