solid-drift 0.2.0 → 0.8.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/README.md +933 -10
- package/dist/ai.d.ts +207 -0
- package/dist/ai.js +570 -0
- package/dist/animate.d.ts +2 -2
- package/dist/animate.js +2 -2
- package/dist/cartoon.d.ts +190 -0
- package/dist/cartoon.js +334 -0
- package/dist/color.d.ts +53 -0
- package/dist/color.js +391 -0
- package/dist/directive.d.ts +5 -5
- package/dist/directive.js +15 -7
- package/dist/easing.d.ts +22 -1
- package/dist/easing.js +49 -1
- package/dist/flip.d.ts +44 -0
- package/dist/flip.js +108 -0
- package/dist/horizontal.d.ts +107 -0
- package/dist/horizontal.js +208 -0
- package/dist/index.d.ts +20 -3
- package/dist/index.js +17 -3
- package/dist/inview.d.ts +4 -4
- package/dist/inview.js +5 -5
- package/dist/motion.d.ts +404 -0
- package/dist/motion.js +761 -0
- package/dist/physics.d.ts +146 -0
- package/dist/physics.js +352 -0
- package/dist/pointer.d.ts +76 -0
- package/dist/pointer.js +123 -0
- package/dist/reduced-motion.d.ts +3 -3
- package/dist/reduced-motion.js +5 -4
- package/dist/scroll.d.ts +3 -3
- package/dist/scroll.js +5 -5
- package/dist/scrollfx.d.ts +156 -0
- package/dist/scrollfx.js +148 -0
- package/dist/scrub.d.ts +51 -0
- package/dist/scrub.js +67 -0
- package/dist/spring.d.ts +39 -4
- package/dist/spring.js +26 -7
- package/dist/stagger.d.ts +4 -4
- package/dist/stagger.js +4 -4
- package/dist/text.d.ts +27 -0
- package/dist/text.js +84 -0
- package/dist/timeline.d.ts +45 -0
- package/dist/timeline.js +93 -0
- package/dist/trail.d.ts +27 -0
- package/dist/trail.js +75 -0
- package/dist/tween.d.ts +3 -3
- package/dist/tween.js +3 -3
- package/dist/typography.d.ts +241 -0
- package/dist/typography.js +812 -0
- package/dist/velocity.d.ts +44 -0
- package/dist/velocity.js +88 -0
- package/dist/web3.d.ts +213 -0
- package/dist/web3.js +640 -0
- package/package.json +1 -1
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { type Accessor } from "solid-js";
|
|
2
|
+
export interface VelocityOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Exponential smoothing of the raw velocity, 0 to 1. Higher values
|
|
5
|
+
* react slower and ride smoother. Default 0.8.
|
|
6
|
+
*/
|
|
7
|
+
smoothing?: number;
|
|
8
|
+
/** Multiplier applied to the raw units per second. Default 1. */
|
|
9
|
+
scale?: number;
|
|
10
|
+
/**
|
|
11
|
+
* Seconds of stillness after which the velocity settles to exactly 0.
|
|
12
|
+
* Default 0.12.
|
|
13
|
+
*/
|
|
14
|
+
settleAfter?: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* A signal tracking how fast another signal is changing, in scaled units
|
|
18
|
+
* per second, smoothed with an exponential moving average.
|
|
19
|
+
*
|
|
20
|
+
* The classic use is scroll velocity: it spikes while the user flings the
|
|
21
|
+
* page and eases back to 0 when scrolling stops, which makes it perfect
|
|
22
|
+
* for velocity-driven skew, stretch, or motion blur that intensifies with
|
|
23
|
+
* speed. With no source it measures page scroll in pixels per second.
|
|
24
|
+
*
|
|
25
|
+
* The measurement loop runs on the shared clock only while the value is
|
|
26
|
+
* live: it kicks off when the source changes and parks itself once the
|
|
27
|
+
* velocity settles back to 0.
|
|
28
|
+
*
|
|
29
|
+
* SSR-safe: returns a constant `0` accessor on the server. Under reduced
|
|
30
|
+
* motion it also returns constant `0`, since velocity-reactive effects
|
|
31
|
+
* are motion by another name.
|
|
32
|
+
*
|
|
33
|
+
* ```tsx
|
|
34
|
+
* // Skew a list while the user scrolls fast, relax when they stop.
|
|
35
|
+
* const velocity = createVelocity() // px per second of page scroll
|
|
36
|
+
* const skew = () => Math.max(-8, Math.min(8, velocity() / 120))
|
|
37
|
+
* <ul style={{ transform: `skewY(${skew()}deg)` }}>…</ul>
|
|
38
|
+
*
|
|
39
|
+
* // Velocity of any signal, in its own units per second.
|
|
40
|
+
* const [n, setN] = createSignal(0)
|
|
41
|
+
* const speed = createVelocity(n, { smoothing: 0.7 })
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export declare function createVelocity(source?: Accessor<number>, options?: VelocityOptions): Accessor<number>;
|
package/dist/velocity.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { createEffect, createSignal, onCleanup, untrack, } from "solid-js";
|
|
2
|
+
import { now, schedule } from "./engine.js";
|
|
3
|
+
import { prefersReducedMotion } from "./reduced-motion.js";
|
|
4
|
+
/**
|
|
5
|
+
* A signal tracking how fast another signal is changing, in scaled units
|
|
6
|
+
* per second, smoothed with an exponential moving average.
|
|
7
|
+
*
|
|
8
|
+
* The classic use is scroll velocity: it spikes while the user flings the
|
|
9
|
+
* page and eases back to 0 when scrolling stops, which makes it perfect
|
|
10
|
+
* for velocity-driven skew, stretch, or motion blur that intensifies with
|
|
11
|
+
* speed. With no source it measures page scroll in pixels per second.
|
|
12
|
+
*
|
|
13
|
+
* The measurement loop runs on the shared clock only while the value is
|
|
14
|
+
* live: it kicks off when the source changes and parks itself once the
|
|
15
|
+
* velocity settles back to 0.
|
|
16
|
+
*
|
|
17
|
+
* SSR-safe: returns a constant `0` accessor on the server. Under reduced
|
|
18
|
+
* motion it also returns constant `0`, since velocity-reactive effects
|
|
19
|
+
* are motion by another name.
|
|
20
|
+
*
|
|
21
|
+
* ```tsx
|
|
22
|
+
* // Skew a list while the user scrolls fast, relax when they stop.
|
|
23
|
+
* const velocity = createVelocity() // px per second of page scroll
|
|
24
|
+
* const skew = () => Math.max(-8, Math.min(8, velocity() / 120))
|
|
25
|
+
* <ul style={{ transform: `skewY(${skew()}deg)` }}>…</ul>
|
|
26
|
+
*
|
|
27
|
+
* // Velocity of any signal, in its own units per second.
|
|
28
|
+
* const [n, setN] = createSignal(0)
|
|
29
|
+
* const speed = createVelocity(n, { smoothing: 0.7 })
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export function createVelocity(source, options = {}) {
|
|
33
|
+
if (typeof window === "undefined" || prefersReducedMotion()) {
|
|
34
|
+
return () => 0;
|
|
35
|
+
}
|
|
36
|
+
const { smoothing = 0.8, scale = 1, settleAfter = 0.12 } = options;
|
|
37
|
+
const read = source ?? (() => window.scrollY);
|
|
38
|
+
const [velocity, setVelocity] = createSignal(0);
|
|
39
|
+
let current = 0;
|
|
40
|
+
let lastValue = untrack(read);
|
|
41
|
+
let lastT = now();
|
|
42
|
+
let lastChangeT = lastT;
|
|
43
|
+
let cancel = null;
|
|
44
|
+
const loop = (t) => {
|
|
45
|
+
const value = untrack(read);
|
|
46
|
+
const dt = Math.max((t - lastT) / 1000, 0.0001);
|
|
47
|
+
if (value !== lastValue) {
|
|
48
|
+
const instant = ((value - lastValue) / dt) * scale;
|
|
49
|
+
current = current * smoothing + instant * (1 - smoothing);
|
|
50
|
+
lastValue = value;
|
|
51
|
+
lastChangeT = t;
|
|
52
|
+
}
|
|
53
|
+
else if (t - lastChangeT > settleAfter * 1000) {
|
|
54
|
+
current = 0;
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
// Coast down smoothly between samples instead of holding stale speed.
|
|
58
|
+
current *= Math.pow(0.02, dt);
|
|
59
|
+
}
|
|
60
|
+
lastT = t;
|
|
61
|
+
setVelocity(current);
|
|
62
|
+
const settled = Math.abs(current) < 0.001 && t - lastChangeT > settleAfter * 1000;
|
|
63
|
+
if (settled) {
|
|
64
|
+
setVelocity(0);
|
|
65
|
+
cancel = null;
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
return true;
|
|
69
|
+
};
|
|
70
|
+
const kick = () => {
|
|
71
|
+
if (cancel)
|
|
72
|
+
return;
|
|
73
|
+
lastT = now();
|
|
74
|
+
cancel = schedule(loop);
|
|
75
|
+
};
|
|
76
|
+
createEffect(() => {
|
|
77
|
+
read(); // track the source so any change kicks the loop
|
|
78
|
+
kick();
|
|
79
|
+
});
|
|
80
|
+
if (!source) {
|
|
81
|
+
// The default page-scroll source is not a reactive signal, so scroll
|
|
82
|
+
// events kick the loop explicitly.
|
|
83
|
+
window.addEventListener("scroll", kick, { passive: true });
|
|
84
|
+
onCleanup(() => window.removeEventListener("scroll", kick));
|
|
85
|
+
}
|
|
86
|
+
onCleanup(() => cancel?.());
|
|
87
|
+
return velocity;
|
|
88
|
+
}
|
package/dist/web3.d.ts
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* web3 family: motion primitives for onchain product UI.
|
|
3
|
+
*
|
|
4
|
+
* Transaction lifecycle, price tickers, mint reveals, and wallet
|
|
5
|
+
* button micro-interactions, without depending on any wallet or chain
|
|
6
|
+
* library. State arrives through accessors in a wagmi/viem-style
|
|
7
|
+
* shape (the adapter pattern), so the primitives stay zero-dependency
|
|
8
|
+
* while your app keeps its own stack.
|
|
9
|
+
*
|
|
10
|
+
* All primitives are signal-native, SSR-safe, dependency-free, and
|
|
11
|
+
* define sensible static behavior under `prefers-reduced-motion`.
|
|
12
|
+
*/
|
|
13
|
+
import { type Accessor } from "solid-js";
|
|
14
|
+
import { type Easing, type EasingName } from "./easing.js";
|
|
15
|
+
type MaybeElement = () => Element | null | undefined;
|
|
16
|
+
/** Stages of a transaction's life, from wallet prompt to finality. */
|
|
17
|
+
export type TxState = "idle" | "signing" | "pending" | "confirming" | "success" | "failed";
|
|
18
|
+
/** wagmi/viem-style transaction status fed through `source`. */
|
|
19
|
+
export interface TxStatusInput {
|
|
20
|
+
/** Transaction status from the wallet/chain adapter. */
|
|
21
|
+
status?: "pending" | "success" | "error" | "idle";
|
|
22
|
+
/** Confirmations seen so far, once a hash exists. */
|
|
23
|
+
confirmations?: number;
|
|
24
|
+
}
|
|
25
|
+
export interface TxLifecycleOptions {
|
|
26
|
+
/**
|
|
27
|
+
* wagmi/viem-style state accessor. Omit for fully manual control
|
|
28
|
+
* through `set()`.
|
|
29
|
+
*/
|
|
30
|
+
source?: Accessor<TxStatusInput>;
|
|
31
|
+
/** Confirmations that promote "pending" to "confirming". Default 1. */
|
|
32
|
+
requiredConfirmations?: number;
|
|
33
|
+
/** Spring stiffness for the progress ring. Default 170. */
|
|
34
|
+
stiffness?: number;
|
|
35
|
+
/** Spring damping for the progress ring. Default 26. */
|
|
36
|
+
damping?: number;
|
|
37
|
+
/** Called after entering a state, with the previous state. */
|
|
38
|
+
onEnter?: (state: TxState, prev: TxState) => void;
|
|
39
|
+
}
|
|
40
|
+
export interface TxLifecycleControls {
|
|
41
|
+
/** Current lifecycle state. */
|
|
42
|
+
state: Accessor<TxState>;
|
|
43
|
+
/**
|
|
44
|
+
* Set the state manually, for stages the chain never reports
|
|
45
|
+
* (for example "signing" when the wallet prompt opens).
|
|
46
|
+
*/
|
|
47
|
+
set: (next: TxState) => void;
|
|
48
|
+
/** Return to "idle". */
|
|
49
|
+
reset: () => void;
|
|
50
|
+
/**
|
|
51
|
+
* 0 to 1 across the lifecycle, spring-smoothed for progress rings
|
|
52
|
+
* and bars: idle 0, signing 0.25, pending 0.5, confirming 0.75,
|
|
53
|
+
* success/failed 1.
|
|
54
|
+
*/
|
|
55
|
+
progress: Accessor<number>;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Signal-native transaction lifecycle.
|
|
59
|
+
*
|
|
60
|
+
* Feed it wagmi/viem-style state through `source` and it derives the
|
|
61
|
+
* stage: a reported hash with too few confirmations is "pending",
|
|
62
|
+
* enough confirmations is "confirming", success/error map to
|
|
63
|
+
* "success"/"failed". Stages the chain never reports, like "signing"
|
|
64
|
+
* while the wallet prompt is open, are set manually.
|
|
65
|
+
*
|
|
66
|
+
* ```ts
|
|
67
|
+
* const tx = createTxLifecycle({
|
|
68
|
+
* source: () => ({
|
|
69
|
+
* status: receiptQuery.status, // "pending" | "success" | "error" | "idle"
|
|
70
|
+
* confirmations: receiptQuery.confirmations,
|
|
71
|
+
* }),
|
|
72
|
+
* requiredConfirmations: 2,
|
|
73
|
+
* })
|
|
74
|
+
* const openWallet = () => {
|
|
75
|
+
* tx.set("signing")
|
|
76
|
+
* sendTransaction()
|
|
77
|
+
* }
|
|
78
|
+
* // <ProgressRing value={tx.progress()} state={tx.state()} />
|
|
79
|
+
* ```
|
|
80
|
+
*
|
|
81
|
+
* SSR-safe: "idle" with `progress()` 0. Under reduced motion state
|
|
82
|
+
* changes apply instantly and `progress()` jumps to its target.
|
|
83
|
+
*/
|
|
84
|
+
export declare function createTxLifecycle(options?: TxLifecycleOptions): TxLifecycleControls;
|
|
85
|
+
export interface TickerOptions {
|
|
86
|
+
/** Decimals in the formatted output. Default 2. */
|
|
87
|
+
decimals?: number;
|
|
88
|
+
/** Roll duration per digit, in ms. Default 400. */
|
|
89
|
+
duration?: number;
|
|
90
|
+
/** Flash color when the value rises. Default "#16a34a". */
|
|
91
|
+
upColor?: string;
|
|
92
|
+
/** Flash color when the value falls. Default "#dc2626". */
|
|
93
|
+
downColor?: string;
|
|
94
|
+
/** How long the flash color holds, in ms. Default 600. */
|
|
95
|
+
flashMs?: number;
|
|
96
|
+
/** Locale for grouping separators. Default "en-US". */
|
|
97
|
+
locale?: string;
|
|
98
|
+
}
|
|
99
|
+
export interface TickerControls {
|
|
100
|
+
/** Formatted value, SSR-safe. */
|
|
101
|
+
display: Accessor<string>;
|
|
102
|
+
/** Direction of the last update: "up" | "down" | "flat". */
|
|
103
|
+
direction: Accessor<"up" | "down" | "flat">;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Animated price/balance ticker: per-digit roll, direction flash.
|
|
107
|
+
*
|
|
108
|
+
* Each digit is a 0-9 strip in an overflow-hidden column, driven by a
|
|
109
|
+
* single rAF task for the whole ticker. Rapid source updates batch to
|
|
110
|
+
* one render per frame, keeping only the latest value, so a hot price
|
|
111
|
+
* feed never queues animation debt. Non-digit characters (decimal
|
|
112
|
+
* point, grouping separators, minus sign) render statically.
|
|
113
|
+
*
|
|
114
|
+
* ```tsx
|
|
115
|
+
* let el!: HTMLSpanElement
|
|
116
|
+
* const [price, setPrice] = createSignal(48210.5)
|
|
117
|
+
* const ticker = createTicker(price, () => el, { decimals: 2 })
|
|
118
|
+
* <span ref={el} style={{ color: ticker.direction() === "up" ? "green" : "red" }}>
|
|
119
|
+
* {ticker.display()}
|
|
120
|
+
* </span>
|
|
121
|
+
* ```
|
|
122
|
+
*
|
|
123
|
+
* SSR-safe: `display()` returns the formatted string with no DOM.
|
|
124
|
+
* Under reduced motion the text swaps instantly: no roll, no flash.
|
|
125
|
+
*/
|
|
126
|
+
export declare function createTicker(source: Accessor<number>, ref: MaybeElement, options?: TickerOptions): TickerControls;
|
|
127
|
+
export type MintRevealStatus = "idle" | "anticipating" | "flipping" | "revealed";
|
|
128
|
+
export interface MintRevealOptions {
|
|
129
|
+
/** Anticipation shake duration, in ms. Default 500. */
|
|
130
|
+
shakeDuration?: number;
|
|
131
|
+
/** rotateY flip duration, in ms. Default 700. */
|
|
132
|
+
flipDuration?: number;
|
|
133
|
+
/** Squash and stretch on landing. Default true. */
|
|
134
|
+
squash?: boolean;
|
|
135
|
+
/** Easing for the flip. Default "easeOutCubic". */
|
|
136
|
+
easing?: Easing | EasingName;
|
|
137
|
+
/** Called at the flip midpoint: swap the card faces here. */
|
|
138
|
+
onFlip?: () => void;
|
|
139
|
+
}
|
|
140
|
+
export interface MintRevealControls {
|
|
141
|
+
/** Play the full reveal choreography. Resolves when revealed. */
|
|
142
|
+
play: () => Promise<void>;
|
|
143
|
+
/** Return to "idle". */
|
|
144
|
+
reset: () => void;
|
|
145
|
+
/** Reactive status. */
|
|
146
|
+
status: Accessor<MintRevealStatus>;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Pack-open / card-reveal choreography, built on the cartoon family:
|
|
150
|
+
* an anticipation shake, a rotateY flip with a face swap at the
|
|
151
|
+
* midpoint, and squash and stretch driven by the flip's own velocity
|
|
152
|
+
* as the card lands. Everything stays on compositor-friendly
|
|
153
|
+
* properties (transform, and the CSS `scale` property for the deform).
|
|
154
|
+
*
|
|
155
|
+
* ```tsx
|
|
156
|
+
* let card!: HTMLDivElement
|
|
157
|
+
* const [face, setFace] = createSignal<"back" | "front">("back")
|
|
158
|
+
* const reveal = createMintReveal(() => card, {
|
|
159
|
+
* onFlip: () => setFace("front"), // swap faces mid-flip
|
|
160
|
+
* })
|
|
161
|
+
* <button onClick={() => reveal.play()}>Reveal</button>
|
|
162
|
+
* <div ref={card} style={{ "backface-visibility": "hidden" }}>
|
|
163
|
+
* {face() === "back" ? <CardBack /> : <NftFront />}
|
|
164
|
+
* </div>
|
|
165
|
+
* ```
|
|
166
|
+
*
|
|
167
|
+
* SSR-safe: no-op on the server, `status()` is "revealed" so the face
|
|
168
|
+
* renders statically. Under reduced motion the shake and flip are
|
|
169
|
+
* skipped and the final face shows at once.
|
|
170
|
+
*/
|
|
171
|
+
export declare function createMintReveal(ref: MaybeElement, options?: MintRevealOptions): MintRevealControls;
|
|
172
|
+
export interface ConnectButtonOptions {
|
|
173
|
+
/** Magnetic pull strength, 0 to 1. Default 0.35. */
|
|
174
|
+
strength?: number;
|
|
175
|
+
/** Scale while pressed. Default 0.96. */
|
|
176
|
+
pressScale?: number;
|
|
177
|
+
}
|
|
178
|
+
export type ConnectButtonStatus = "idle" | "ticking" | "pulsing";
|
|
179
|
+
export interface ConnectButtonControls {
|
|
180
|
+
/** Checkmark tick for copy-address feedback. */
|
|
181
|
+
copyTick: () => void;
|
|
182
|
+
/** Expanding ring pulse for chain switches. */
|
|
183
|
+
chainPulse: () => void;
|
|
184
|
+
/** Reactive status: "idle" | "ticking" | "pulsing". */
|
|
185
|
+
status: Accessor<ConnectButtonStatus>;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Wallet connect-button micro-interactions: magnetic hover pull,
|
|
189
|
+
* press scale, a checkmark tick for copy-address feedback, and an
|
|
190
|
+
* expanding ring pulse for chain switches.
|
|
191
|
+
*
|
|
192
|
+
* The button's transform is owned by the primitive (magnetic pull
|
|
193
|
+
* plus press scale); the tick and pulse animate overlay spans so
|
|
194
|
+
* they never fight the hover motion. The button is given
|
|
195
|
+
* `position: relative` the first time a tick or pulse runs, to stage
|
|
196
|
+
* the overlays.
|
|
197
|
+
*
|
|
198
|
+
* ```tsx
|
|
199
|
+
* let btn!: HTMLButtonElement
|
|
200
|
+
* const connect = createConnectButton(() => btn)
|
|
201
|
+
* const copy = async () => {
|
|
202
|
+
* await navigator.clipboard.writeText(address())
|
|
203
|
+
* connect.copyTick()
|
|
204
|
+
* }
|
|
205
|
+
* <button ref={btn} onClick={copy}>0x7a…f3c2</button>
|
|
206
|
+
* ```
|
|
207
|
+
*
|
|
208
|
+
* SSR-safe: no-op on the server. Under reduced motion the magnetic
|
|
209
|
+
* pull is off and the tick/pulse become instant state changes (the
|
|
210
|
+
* check shows statically, then hides).
|
|
211
|
+
*/
|
|
212
|
+
export declare function createConnectButton(ref: MaybeElement, options?: ConnectButtonOptions): ConnectButtonControls;
|
|
213
|
+
export {};
|