@rootnative/inertia 0.0.0-alpha.4 → 0.0.0-alpha.6
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 +22 -0
- package/dist/{chunk-5I3G43XA.js → chunk-2HYD2ZBK.js} +2 -2
- package/dist/chunk-3UTJJ4A3.js +8 -0
- package/dist/{chunk-Q6ZTMLTI.js → chunk-4PEHWDAZ.js} +7 -7
- package/dist/chunk-4QGXK6TF.js +8 -0
- package/dist/{chunk-WPPLZNM4.mjs → chunk-6SMPIOIC.mjs} +1 -1
- package/dist/{chunk-6EP3S2PN.js → chunk-7AOERN53.js} +3 -3
- package/dist/{chunk-6UQ4KA6V.js → chunk-7UDYEFBU.js} +22 -22
- package/dist/{chunk-K4KR5BIS.mjs → chunk-ALRHDFZE.mjs} +1 -1
- package/dist/{chunk-QQJSBIXV.mjs → chunk-CWLFUYIY.mjs} +1 -1
- package/dist/{chunk-6FENLMCA.mjs → chunk-CY7Y64C3.mjs} +17 -1
- package/dist/{chunk-I76OC6RX.mjs → chunk-DWCLIBYO.mjs} +2 -2
- package/dist/{chunk-IJNVUM5U.mjs → chunk-JVBXPF2G.mjs} +1 -1
- package/dist/{chunk-OBE7KTMK.mjs → chunk-NXDJZD6A.mjs} +1 -1
- package/dist/{chunk-SFRNO6AW.js → chunk-PTRF47DA.js} +17 -0
- package/dist/{chunk-L2EVRKSC.mjs → chunk-R63GIUNU.mjs} +1 -1
- package/dist/{chunk-ZQUCQRZT.mjs → chunk-RGNX6UZN.mjs} +2 -2
- package/dist/{chunk-OM5FXU4I.js → chunk-TDSO63CJ.js} +2 -2
- package/dist/chunk-Z7HIOFKQ.js +8 -0
- package/dist/gestureLayer/index.js +10 -10
- package/dist/gestureLayer/index.mjs +3 -3
- package/dist/index.d.mts +78 -13
- package/dist/index.d.ts +78 -13
- package/dist/index.js +202 -44
- package/dist/index.mjs +178 -20
- package/dist/motion/Image.js +5 -5
- package/dist/motion/Image.mjs +4 -4
- package/dist/motion/Pressable.js +5 -5
- package/dist/motion/Pressable.mjs +4 -4
- package/dist/motion/ScrollView.js +5 -5
- package/dist/motion/ScrollView.mjs +4 -4
- package/dist/motion/Text.js +5 -5
- package/dist/motion/Text.mjs +4 -4
- package/dist/motion/View.js +5 -5
- package/dist/motion/View.mjs +4 -4
- package/dist/touch/index.js +3 -3
- package/dist/touch/index.mjs +1 -1
- package/llms.txt +1 -1
- package/package.json +2 -2
- package/src/index.ts +1 -0
- package/src/internal/boxShadow.ts +204 -0
- package/src/internal/nonWorkletWarning.ts +41 -0
- package/src/layout/resolveLayout.ts +3 -2
- package/src/transitions/easing.ts +13 -8
- package/src/values/index.ts +1 -0
- package/src/values/useShadow.ts +76 -1
- package/src/values/useTransform.ts +28 -12
- package/dist/chunk-NDKVHL3N.js +0 -8
- package/dist/chunk-SCTX5Z7I.js +0 -8
- package/dist/chunk-WZGMAXKC.js +0 -8
package/dist/index.mjs
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
export { useGesture } from './chunk-
|
|
2
|
-
import { MotionView } from './chunk-
|
|
3
|
-
export { MotionView } from './chunk-
|
|
4
|
-
import { MotionText } from './chunk-
|
|
5
|
-
export { MotionText } from './chunk-
|
|
6
|
-
import { MotionImage } from './chunk-
|
|
7
|
-
export { MotionImage } from './chunk-
|
|
8
|
-
import { MotionPressable } from './chunk-
|
|
9
|
-
export { MotionPressable } from './chunk-
|
|
10
|
-
import { MotionScrollView } from './chunk-
|
|
11
|
-
export { MotionScrollView } from './chunk-
|
|
12
|
-
export { Presence, createMotionComponent, usePresence } from './chunk-
|
|
13
|
-
import { useShouldReduceMotion, resolveNamedTransition, useNamedTransitions, lookupNamedTransition } from './chunk-
|
|
14
|
-
export { MotionConfig, resolveNamedTransition, useMotionConfig, useNamedTransitions, useShouldReduceMotion } from './chunk-
|
|
15
|
-
import { stableSig, resolveTransition, springToReanimated } from './chunk-
|
|
16
|
-
export { buildReleaseAnimation, cubicBezier, ensureWorkletEasing, resolveAnimatableValue, resolveTransition } from './chunk-
|
|
1
|
+
export { useGesture } from './chunk-RGNX6UZN.mjs';
|
|
2
|
+
import { MotionView } from './chunk-6SMPIOIC.mjs';
|
|
3
|
+
export { MotionView } from './chunk-6SMPIOIC.mjs';
|
|
4
|
+
import { MotionText } from './chunk-JVBXPF2G.mjs';
|
|
5
|
+
export { MotionText } from './chunk-JVBXPF2G.mjs';
|
|
6
|
+
import { MotionImage } from './chunk-ALRHDFZE.mjs';
|
|
7
|
+
export { MotionImage } from './chunk-ALRHDFZE.mjs';
|
|
8
|
+
import { MotionPressable } from './chunk-NXDJZD6A.mjs';
|
|
9
|
+
export { MotionPressable } from './chunk-NXDJZD6A.mjs';
|
|
10
|
+
import { MotionScrollView } from './chunk-CWLFUYIY.mjs';
|
|
11
|
+
export { MotionScrollView } from './chunk-CWLFUYIY.mjs';
|
|
12
|
+
export { Presence, createMotionComponent, usePresence } from './chunk-DWCLIBYO.mjs';
|
|
13
|
+
import { useShouldReduceMotion, resolveNamedTransition, useNamedTransitions, lookupNamedTransition } from './chunk-R63GIUNU.mjs';
|
|
14
|
+
export { MotionConfig, resolveNamedTransition, useMotionConfig, useNamedTransitions, useShouldReduceMotion } from './chunk-R63GIUNU.mjs';
|
|
15
|
+
import { stableSig, resolveTransition, springToReanimated, warnNonWorkletOnce } from './chunk-CY7Y64C3.mjs';
|
|
16
|
+
export { buildReleaseAnimation, cubicBezier, ensureWorkletEasing, resolveAnimatableValue, resolveTransition } from './chunk-CY7Y64C3.mjs';
|
|
17
17
|
import { useEffect, useMemo, useRef } from 'react';
|
|
18
18
|
import { useSharedValue, withSpring, useAnimatedReaction, useAnimatedStyle, interpolateColor, useDerivedValue, Extrapolation, useAnimatedScrollHandler, interpolate } from 'react-native-reanimated';
|
|
19
19
|
import { isWorkletFunction } from 'react-native-worklets';
|
|
@@ -112,10 +112,18 @@ function useTransform(arg1, inputRange, outputRange, options) {
|
|
|
112
112
|
let producer;
|
|
113
113
|
if (typeof arg1 === "function") {
|
|
114
114
|
const userFn = arg1;
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
115
|
+
if (isWorkletFunction(userFn)) {
|
|
116
|
+
producer = userFn;
|
|
117
|
+
} else {
|
|
118
|
+
warnNonWorkletOnce(
|
|
119
|
+
"useTransform-transformer",
|
|
120
|
+
"[inertia] useTransform: the transformer is not a worklet, so the shared values it reads can't be tracked as dependencies \u2014 the derived value will only refresh on React re-renders, and native builds reject plain functions on the UI thread. Add the 'worklet' directive as the first statement of the transformer."
|
|
121
|
+
);
|
|
122
|
+
producer = () => {
|
|
123
|
+
"worklet";
|
|
124
|
+
return userFn();
|
|
125
|
+
};
|
|
126
|
+
}
|
|
119
127
|
} else {
|
|
120
128
|
const source = arg1;
|
|
121
129
|
const input = inputRange;
|
|
@@ -163,6 +171,127 @@ function useScroll() {
|
|
|
163
171
|
onScroll: handler
|
|
164
172
|
};
|
|
165
173
|
}
|
|
174
|
+
|
|
175
|
+
// src/internal/boxShadow.ts
|
|
176
|
+
var LENGTH = /^[+-]?(\d+\.?\d*|\.\d+)(px)?$/i;
|
|
177
|
+
var UNIT_LIKE = /^[+-]?(\d+\.?\d*|\.\d+)[a-z%]+$/i;
|
|
178
|
+
function invalid(input, reason) {
|
|
179
|
+
return new Error(
|
|
180
|
+
`[inertia] parseBoxShadow: ${reason} in ${JSON.stringify(input)}. Expected CSS box-shadow syntax with px lengths: '[inset] <offset-x> <offset-y> [blur] [spread] [color], ...'`
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
function splitLayers(input) {
|
|
184
|
+
const layers = [];
|
|
185
|
+
let depth = 0;
|
|
186
|
+
let start = 0;
|
|
187
|
+
for (let i = 0; i < input.length; i++) {
|
|
188
|
+
const ch = input[i];
|
|
189
|
+
if (ch === "(") depth++;
|
|
190
|
+
else if (ch === ")") depth--;
|
|
191
|
+
else if (ch === "," && depth === 0) {
|
|
192
|
+
layers.push(input.slice(start, i));
|
|
193
|
+
start = i + 1;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
layers.push(input.slice(start));
|
|
197
|
+
return layers;
|
|
198
|
+
}
|
|
199
|
+
function tokenize(layer) {
|
|
200
|
+
const tokens = [];
|
|
201
|
+
let depth = 0;
|
|
202
|
+
let current = "";
|
|
203
|
+
for (const ch of layer) {
|
|
204
|
+
if (ch === "(") depth++;
|
|
205
|
+
else if (ch === ")") depth--;
|
|
206
|
+
if (depth === 0 && /\s/.test(ch)) {
|
|
207
|
+
if (current) tokens.push(current);
|
|
208
|
+
current = "";
|
|
209
|
+
} else {
|
|
210
|
+
current += ch;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
if (current) tokens.push(current);
|
|
214
|
+
return tokens;
|
|
215
|
+
}
|
|
216
|
+
function parseBoxShadow(input) {
|
|
217
|
+
const trimmed = input.trim();
|
|
218
|
+
if (trimmed === "") throw invalid(input, "empty string");
|
|
219
|
+
if (trimmed.toLowerCase() === "none") return [];
|
|
220
|
+
return splitLayers(trimmed).map((layerString) => {
|
|
221
|
+
const tokens = tokenize(layerString.trim());
|
|
222
|
+
if (tokens.length === 0) throw invalid(input, "empty layer");
|
|
223
|
+
const lengths = [];
|
|
224
|
+
let color;
|
|
225
|
+
let inset = false;
|
|
226
|
+
for (const token of tokens) {
|
|
227
|
+
if (token.toLowerCase() === "inset") {
|
|
228
|
+
if (inset) throw invalid(input, "duplicate 'inset'");
|
|
229
|
+
inset = true;
|
|
230
|
+
} else if (LENGTH.test(token)) {
|
|
231
|
+
lengths.push(parseFloat(token));
|
|
232
|
+
} else if (UNIT_LIKE.test(token)) {
|
|
233
|
+
throw invalid(input, `unsupported unit in ${JSON.stringify(token)}`);
|
|
234
|
+
} else {
|
|
235
|
+
if (color !== void 0) throw invalid(input, "multiple colors");
|
|
236
|
+
color = token;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
if (lengths.length < 2 || lengths.length > 4) {
|
|
240
|
+
throw invalid(input, `expected 2-4 lengths, got ${lengths.length}`);
|
|
241
|
+
}
|
|
242
|
+
const [offsetX = 0, offsetY = 0, blurRadius = 0, spreadDistance = 0] = lengths;
|
|
243
|
+
if (blurRadius < 0) throw invalid(input, "negative blur radius");
|
|
244
|
+
return {
|
|
245
|
+
offsetX,
|
|
246
|
+
offsetY,
|
|
247
|
+
blurRadius,
|
|
248
|
+
spreadDistance,
|
|
249
|
+
color: color ?? "black",
|
|
250
|
+
inset
|
|
251
|
+
};
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
function resolveBoxShadowInput(input) {
|
|
255
|
+
if (input === void 0) return [];
|
|
256
|
+
if (typeof input === "string") return parseBoxShadow(input);
|
|
257
|
+
return input.map((layer) => ({
|
|
258
|
+
offsetX: layer.offsetX,
|
|
259
|
+
offsetY: layer.offsetY,
|
|
260
|
+
blurRadius: layer.blurRadius ?? 0,
|
|
261
|
+
spreadDistance: layer.spreadDistance ?? 0,
|
|
262
|
+
color: layer.color ?? "black",
|
|
263
|
+
inset: layer.inset ?? false
|
|
264
|
+
}));
|
|
265
|
+
}
|
|
266
|
+
function pairBoxShadowLayers(from, to) {
|
|
267
|
+
const count = Math.max(from.length, to.length);
|
|
268
|
+
const pairs = [];
|
|
269
|
+
for (let i = 0; i < count; i++) {
|
|
270
|
+
const a = from[i];
|
|
271
|
+
const b = to[i];
|
|
272
|
+
const fromLayer = a ?? invisibleLayer(b.inset);
|
|
273
|
+
const toLayer = b ?? invisibleLayer(a.inset);
|
|
274
|
+
if (fromLayer.inset !== toLayer.inset) {
|
|
275
|
+
throw new Error(
|
|
276
|
+
`[inertia] useShadow: boxShadow layer ${i} is 'inset' on one side but not the other \u2014 inset cannot be interpolated. Give both sides the same inset-ness (pad with a transparent layer if needed).`
|
|
277
|
+
);
|
|
278
|
+
}
|
|
279
|
+
pairs.push({ from: fromLayer, to: toLayer });
|
|
280
|
+
}
|
|
281
|
+
return pairs;
|
|
282
|
+
}
|
|
283
|
+
function invisibleLayer(inset) {
|
|
284
|
+
return {
|
|
285
|
+
offsetX: 0,
|
|
286
|
+
offsetY: 0,
|
|
287
|
+
blurRadius: 0,
|
|
288
|
+
spreadDistance: 0,
|
|
289
|
+
color: "transparent",
|
|
290
|
+
inset
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// src/values/useShadow.ts
|
|
166
295
|
function useShadow({
|
|
167
296
|
from,
|
|
168
297
|
to,
|
|
@@ -173,6 +302,10 @@ function useShadow({
|
|
|
173
302
|
const hasElevation = from.elevation !== void 0 || to.elevation !== void 0;
|
|
174
303
|
const hasColor = from.shadowColor !== void 0 || to.shadowColor !== void 0;
|
|
175
304
|
const hasOffset = from.shadowOffset !== void 0 || to.shadowOffset !== void 0;
|
|
305
|
+
const boxShadowPairs = from.boxShadow !== void 0 || to.boxShadow !== void 0 ? pairBoxShadowLayers(
|
|
306
|
+
resolveBoxShadowInput(from.boxShadow),
|
|
307
|
+
resolveBoxShadowInput(to.boxShadow)
|
|
308
|
+
) : [];
|
|
176
309
|
const opacityFrom = from.shadowOpacity ?? 0;
|
|
177
310
|
const opacityTo = to.shadowOpacity ?? 0;
|
|
178
311
|
const radiusFrom = from.shadowRadius ?? 0;
|
|
@@ -207,6 +340,31 @@ function useShadow({
|
|
|
207
340
|
height: interpolate(t, [0, 1], [offsetHFrom, offsetHTo])
|
|
208
341
|
};
|
|
209
342
|
}
|
|
343
|
+
if (boxShadowPairs.length > 0) {
|
|
344
|
+
let css = "";
|
|
345
|
+
let first = true;
|
|
346
|
+
for (const pair of boxShadowPairs) {
|
|
347
|
+
const x = interpolate(t, [0, 1], [pair.from.offsetX, pair.to.offsetX]);
|
|
348
|
+
const y = interpolate(t, [0, 1], [pair.from.offsetY, pair.to.offsetY]);
|
|
349
|
+
const blur = Math.max(
|
|
350
|
+
0,
|
|
351
|
+
interpolate(t, [0, 1], [pair.from.blurRadius, pair.to.blurRadius])
|
|
352
|
+
);
|
|
353
|
+
const spread = interpolate(
|
|
354
|
+
t,
|
|
355
|
+
[0, 1],
|
|
356
|
+
[pair.from.spreadDistance, pair.to.spreadDistance]
|
|
357
|
+
);
|
|
358
|
+
const color = interpolateColor(
|
|
359
|
+
t,
|
|
360
|
+
[0, 1],
|
|
361
|
+
[pair.from.color, pair.to.color]
|
|
362
|
+
);
|
|
363
|
+
css += (first ? "" : ", ") + (pair.from.inset ? "inset " : "") + `${x}px ${y}px ${blur}px ${spread}px ${color}`;
|
|
364
|
+
first = false;
|
|
365
|
+
}
|
|
366
|
+
out.boxShadow = css;
|
|
367
|
+
}
|
|
210
368
|
return out;
|
|
211
369
|
});
|
|
212
370
|
}
|
package/dist/motion/Image.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
require('../chunk-
|
|
5
|
-
require('../chunk-
|
|
6
|
-
require('../chunk-
|
|
3
|
+
var chunk3UTJJ4A3_js = require('../chunk-3UTJJ4A3.js');
|
|
4
|
+
require('../chunk-7UDYEFBU.js');
|
|
5
|
+
require('../chunk-7AOERN53.js');
|
|
6
|
+
require('../chunk-PTRF47DA.js');
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
Object.defineProperty(exports, "MotionImage", {
|
|
11
11
|
enumerable: true,
|
|
12
|
-
get: function () { return
|
|
12
|
+
get: function () { return chunk3UTJJ4A3_js.MotionImage; }
|
|
13
13
|
});
|
package/dist/motion/Image.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { MotionImage } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
3
|
-
import '../chunk-
|
|
4
|
-
import '../chunk-
|
|
1
|
+
export { MotionImage } from '../chunk-ALRHDFZE.mjs';
|
|
2
|
+
import '../chunk-DWCLIBYO.mjs';
|
|
3
|
+
import '../chunk-R63GIUNU.mjs';
|
|
4
|
+
import '../chunk-CY7Y64C3.mjs';
|
package/dist/motion/Pressable.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
require('../chunk-
|
|
5
|
-
require('../chunk-
|
|
6
|
-
require('../chunk-
|
|
3
|
+
var chunkTDSO63CJ_js = require('../chunk-TDSO63CJ.js');
|
|
4
|
+
require('../chunk-7UDYEFBU.js');
|
|
5
|
+
require('../chunk-7AOERN53.js');
|
|
6
|
+
require('../chunk-PTRF47DA.js');
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
Object.defineProperty(exports, "MotionPressable", {
|
|
11
11
|
enumerable: true,
|
|
12
|
-
get: function () { return
|
|
12
|
+
get: function () { return chunkTDSO63CJ_js.MotionPressable; }
|
|
13
13
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { MotionPressable } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
3
|
-
import '../chunk-
|
|
4
|
-
import '../chunk-
|
|
1
|
+
export { MotionPressable } from '../chunk-NXDJZD6A.mjs';
|
|
2
|
+
import '../chunk-DWCLIBYO.mjs';
|
|
3
|
+
import '../chunk-R63GIUNU.mjs';
|
|
4
|
+
import '../chunk-CY7Y64C3.mjs';
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
require('../chunk-
|
|
5
|
-
require('../chunk-
|
|
6
|
-
require('../chunk-
|
|
3
|
+
var chunk2HYD2ZBK_js = require('../chunk-2HYD2ZBK.js');
|
|
4
|
+
require('../chunk-7UDYEFBU.js');
|
|
5
|
+
require('../chunk-7AOERN53.js');
|
|
6
|
+
require('../chunk-PTRF47DA.js');
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
Object.defineProperty(exports, "MotionScrollView", {
|
|
11
11
|
enumerable: true,
|
|
12
|
-
get: function () { return
|
|
12
|
+
get: function () { return chunk2HYD2ZBK_js.MotionScrollView; }
|
|
13
13
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { MotionScrollView } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
3
|
-
import '../chunk-
|
|
4
|
-
import '../chunk-
|
|
1
|
+
export { MotionScrollView } from '../chunk-CWLFUYIY.mjs';
|
|
2
|
+
import '../chunk-DWCLIBYO.mjs';
|
|
3
|
+
import '../chunk-R63GIUNU.mjs';
|
|
4
|
+
import '../chunk-CY7Y64C3.mjs';
|
package/dist/motion/Text.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
require('../chunk-
|
|
5
|
-
require('../chunk-
|
|
6
|
-
require('../chunk-
|
|
3
|
+
var chunkZ7HIOFKQ_js = require('../chunk-Z7HIOFKQ.js');
|
|
4
|
+
require('../chunk-7UDYEFBU.js');
|
|
5
|
+
require('../chunk-7AOERN53.js');
|
|
6
|
+
require('../chunk-PTRF47DA.js');
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
Object.defineProperty(exports, "MotionText", {
|
|
11
11
|
enumerable: true,
|
|
12
|
-
get: function () { return
|
|
12
|
+
get: function () { return chunkZ7HIOFKQ_js.MotionText; }
|
|
13
13
|
});
|
package/dist/motion/Text.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { MotionText } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
3
|
-
import '../chunk-
|
|
4
|
-
import '../chunk-
|
|
1
|
+
export { MotionText } from '../chunk-JVBXPF2G.mjs';
|
|
2
|
+
import '../chunk-DWCLIBYO.mjs';
|
|
3
|
+
import '../chunk-R63GIUNU.mjs';
|
|
4
|
+
import '../chunk-CY7Y64C3.mjs';
|
package/dist/motion/View.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
require('../chunk-
|
|
5
|
-
require('../chunk-
|
|
6
|
-
require('../chunk-
|
|
3
|
+
var chunk4QGXK6TF_js = require('../chunk-4QGXK6TF.js');
|
|
4
|
+
require('../chunk-7UDYEFBU.js');
|
|
5
|
+
require('../chunk-7AOERN53.js');
|
|
6
|
+
require('../chunk-PTRF47DA.js');
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
Object.defineProperty(exports, "MotionView", {
|
|
11
11
|
enumerable: true,
|
|
12
|
-
get: function () { return
|
|
12
|
+
get: function () { return chunk4QGXK6TF_js.MotionView; }
|
|
13
13
|
});
|
package/dist/motion/View.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { MotionView } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
3
|
-
import '../chunk-
|
|
4
|
-
import '../chunk-
|
|
1
|
+
export { MotionView } from '../chunk-6SMPIOIC.mjs';
|
|
2
|
+
import '../chunk-DWCLIBYO.mjs';
|
|
3
|
+
import '../chunk-R63GIUNU.mjs';
|
|
4
|
+
import '../chunk-CY7Y64C3.mjs';
|
package/dist/touch/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkPTRF47DA_js = require('../chunk-PTRF47DA.js');
|
|
4
4
|
var react = require('react');
|
|
5
5
|
var reactNative = require('react-native');
|
|
6
6
|
var reactNativeReanimated = require('react-native-reanimated');
|
|
@@ -48,14 +48,14 @@ function useTouchDrag(options = {}) {
|
|
|
48
48
|
if (result) {
|
|
49
49
|
if (result.x && lockX) {
|
|
50
50
|
const toX = "to" in result.x ? result.x.to : x;
|
|
51
|
-
dragX.value =
|
|
51
|
+
dragX.value = chunkPTRF47DA_js.buildReleaseAnimation(
|
|
52
52
|
result.x,
|
|
53
53
|
toX
|
|
54
54
|
);
|
|
55
55
|
}
|
|
56
56
|
if (result.y && lockY) {
|
|
57
57
|
const toY = "to" in result.y ? result.y.to : y;
|
|
58
|
-
dragY.value =
|
|
58
|
+
dragY.value = chunkPTRF47DA_js.buildReleaseAnimation(
|
|
59
59
|
result.y,
|
|
60
60
|
toY
|
|
61
61
|
);
|
package/dist/touch/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { buildReleaseAnimation } from '../chunk-
|
|
1
|
+
import { buildReleaseAnimation } from '../chunk-CY7Y64C3.mjs';
|
|
2
2
|
import { useMemo } from 'react';
|
|
3
3
|
import { PanResponder } from 'react-native';
|
|
4
4
|
import { useSharedValue, useAnimatedStyle } from 'react-native-reanimated';
|
package/llms.txt
CHANGED
|
@@ -51,7 +51,7 @@ import { MotionScrollView } from '@rootnative/inertia/scroll-view'
|
|
|
51
51
|
- `useSpring(target, config?)` — spring-only shorthand. Animates a `SharedValue<number>` toward `target` with react-spring vocab (or a spring-typed registered `TransitionName`; non-spring names warn and fall back to the default spring). `target` may be a plain number (effect-driven) or a `SharedValue<number>` (UI-thread reaction); the latter is the gesture-smoothing path.
|
|
52
52
|
- `useBooleanSpring(active, config?)` — sugar over `useSpring` for the recurring "spring 0↔1 progress from a boolean" shape (checkbox checks, accordion expansions, drawer open/closed). Identical mechanics to `useSpring(active ? 1 : 0, config)` — the named form so the call site reads as the boolean it represents.
|
|
53
53
|
- `useTransform(value, inputRange, outputRange, options?)` / `useTransform(transformer)` — interpolate a numeric shared value onto a number or color range, or derive any value from any number of shared values via a worklet. Non-worklet transformers are auto-wrapped.
|
|
54
|
-
- `useShadow({ from, to, progress })` — pure value-layer interpolator between two `ShadowConfig`s (`shadowOpacity` / `shadowRadius` / `shadowOffset` / `elevation` / `shadowColor`) driven by a `SharedValue<number>` (0→1). Returns an animated style fragment to spread onto `style`; only emits keys present on either side, absent sides default to natural zero. The hook does not animate on its own — drive `progress` with a spring, a scroll-derived `useTransform`, or any other shared value source.
|
|
54
|
+
- `useShadow({ from, to, progress })` — pure value-layer interpolator between two `ShadowConfig`s (`shadowOpacity` / `shadowRadius` / `shadowOffset` / `elevation` / `shadowColor`, plus `boxShadow` as a CSS string or `BoxShadowLayer[]` — the shadow surface on web and RN 0.76+ new-arch; multi-layer, CSS-transition padding semantics, malformed strings throw at setup) driven by a `SharedValue<number>` (0→1). Returns an animated style fragment to spread onto `style`; only emits keys present on either side, absent sides default to natural zero. The hook does not animate on its own — drive `progress` with a spring, a scroll-derived `useTransform`, or any other shared value source.
|
|
55
55
|
- `useColorTransition(progress, [from, to], options?)` — pure value-layer interpolator for a single color channel, driven by a `SharedValue<number>` (0→1). Returns an animated style fragment with one color key (default `backgroundColor`; configurable via `options.key` to `color` / `borderColor` / `tintColor` / `shadowColor` / per-side border colors). For raw `SharedValue<string>` output, use `useTransform(progress, [0, 1], [from, to])` instead.
|
|
56
56
|
- `useScroll()` — returns `{ scrollX, scrollY, onScroll }` for use with `Motion.ScrollView`. Scroll events fire on the UI thread.
|
|
57
57
|
- `createMotionComponent<C>(C)` — wrap any component with the same Motion prop surface, inferring style from `C`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rootnative/inertia",
|
|
3
|
-
"version": "0.0.0-alpha.
|
|
3
|
+
"version": "0.0.0-alpha.6",
|
|
4
4
|
"description": "Declarative animation primitives for React Native, built on react-native-reanimated.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "RootNative",
|
|
@@ -142,7 +142,7 @@
|
|
|
142
142
|
"scripts": {
|
|
143
143
|
"build": "tsup",
|
|
144
144
|
"dev": "tsup --watch",
|
|
145
|
-
"typecheck": "tsc --noEmit",
|
|
145
|
+
"typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.test.json",
|
|
146
146
|
"test": "jest",
|
|
147
147
|
"size": "size-limit",
|
|
148
148
|
"size:why": "size-limit --why",
|
package/src/index.ts
CHANGED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CSS `box-shadow` parsing + pairing for `useShadow`.
|
|
3
|
+
*
|
|
4
|
+
* Design systems store web elevation tokens as CSS `box-shadow` strings
|
|
5
|
+
* (`'0px 1px 2px rgba(0,0,0,0.3), 0px 1px 3px 1px rgba(0,0,0,0.15)'`).
|
|
6
|
+
* Like `cubicBezier`, this module makes those tokens directly consumable:
|
|
7
|
+
* strings are parsed once on the JS thread into flat layer records the
|
|
8
|
+
* `useShadow` worklet can interpolate without any frame-time string work.
|
|
9
|
+
*
|
|
10
|
+
* Invalid input **throws** rather than warning — shadow tokens are
|
|
11
|
+
* constructed at theme/module setup, and a malformed token should fail
|
|
12
|
+
* loudly there, not silently render the wrong elevation.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* One layer of a `box-shadow`, structurally mirroring React Native's
|
|
17
|
+
* `BoxShadowValue` (RN 0.76+ `boxShadow` style). Lengths are px numbers.
|
|
18
|
+
*/
|
|
19
|
+
export interface BoxShadowLayer {
|
|
20
|
+
offsetX: number
|
|
21
|
+
offsetY: number
|
|
22
|
+
/** Must be >= 0, per CSS. @default 0 */
|
|
23
|
+
blurRadius?: number
|
|
24
|
+
/** @default 0 */
|
|
25
|
+
spreadDistance?: number
|
|
26
|
+
/** Any color string Reanimated's `interpolateColor` accepts. @default 'black' */
|
|
27
|
+
color?: string
|
|
28
|
+
/** @default false */
|
|
29
|
+
inset?: boolean
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** A layer with every field resolved to a concrete value. */
|
|
33
|
+
export interface ResolvedBoxShadowLayer {
|
|
34
|
+
offsetX: number
|
|
35
|
+
offsetY: number
|
|
36
|
+
blurRadius: number
|
|
37
|
+
spreadDistance: number
|
|
38
|
+
color: string
|
|
39
|
+
inset: boolean
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const LENGTH = /^[+-]?(\d+\.?\d*|\.\d+)(px)?$/i
|
|
43
|
+
const UNIT_LIKE = /^[+-]?(\d+\.?\d*|\.\d+)[a-z%]+$/i
|
|
44
|
+
|
|
45
|
+
function invalid(input: string, reason: string): Error {
|
|
46
|
+
return new Error(
|
|
47
|
+
`[inertia] parseBoxShadow: ${reason} in ${JSON.stringify(input)}. ` +
|
|
48
|
+
'Expected CSS box-shadow syntax with px lengths: ' +
|
|
49
|
+
"'[inset] <offset-x> <offset-y> [blur] [spread] [color], ...'",
|
|
50
|
+
)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Split a box-shadow string into layer strings on top-level commas —
|
|
55
|
+
* commas inside color functions (`rgba(0, 0, 0, 0.3)`) don't split.
|
|
56
|
+
*/
|
|
57
|
+
function splitLayers(input: string): string[] {
|
|
58
|
+
const layers: string[] = []
|
|
59
|
+
let depth = 0
|
|
60
|
+
let start = 0
|
|
61
|
+
for (let i = 0; i < input.length; i++) {
|
|
62
|
+
const ch = input[i]
|
|
63
|
+
if (ch === '(') depth++
|
|
64
|
+
else if (ch === ')') depth--
|
|
65
|
+
else if (ch === ',' && depth === 0) {
|
|
66
|
+
layers.push(input.slice(start, i))
|
|
67
|
+
start = i + 1
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
layers.push(input.slice(start))
|
|
71
|
+
return layers
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Split one layer into whitespace-separated tokens, keeping color
|
|
76
|
+
* functions (which may contain spaces: `rgb(0 0 0 / 40%)`) as one token.
|
|
77
|
+
*/
|
|
78
|
+
function tokenize(layer: string): string[] {
|
|
79
|
+
const tokens: string[] = []
|
|
80
|
+
let depth = 0
|
|
81
|
+
let current = ''
|
|
82
|
+
for (const ch of layer) {
|
|
83
|
+
if (ch === '(') depth++
|
|
84
|
+
else if (ch === ')') depth--
|
|
85
|
+
if (depth === 0 && /\s/.test(ch)) {
|
|
86
|
+
if (current) tokens.push(current)
|
|
87
|
+
current = ''
|
|
88
|
+
} else {
|
|
89
|
+
current += ch
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (current) tokens.push(current)
|
|
93
|
+
return tokens
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Parse a CSS `box-shadow` string into resolved layers. `'none'` parses to
|
|
98
|
+
* an empty list. Only px (and unitless) lengths are supported — other units
|
|
99
|
+
* depend on font/viewport context that a style value can't resolve.
|
|
100
|
+
*/
|
|
101
|
+
export function parseBoxShadow(input: string): ResolvedBoxShadowLayer[] {
|
|
102
|
+
const trimmed = input.trim()
|
|
103
|
+
if (trimmed === '') throw invalid(input, 'empty string')
|
|
104
|
+
if (trimmed.toLowerCase() === 'none') return []
|
|
105
|
+
|
|
106
|
+
return splitLayers(trimmed).map((layerString) => {
|
|
107
|
+
const tokens = tokenize(layerString.trim())
|
|
108
|
+
if (tokens.length === 0) throw invalid(input, 'empty layer')
|
|
109
|
+
|
|
110
|
+
const lengths: number[] = []
|
|
111
|
+
let color: string | undefined
|
|
112
|
+
let inset = false
|
|
113
|
+
for (const token of tokens) {
|
|
114
|
+
if (token.toLowerCase() === 'inset') {
|
|
115
|
+
if (inset) throw invalid(input, "duplicate 'inset'")
|
|
116
|
+
inset = true
|
|
117
|
+
} else if (LENGTH.test(token)) {
|
|
118
|
+
lengths.push(parseFloat(token))
|
|
119
|
+
} else if (UNIT_LIKE.test(token)) {
|
|
120
|
+
throw invalid(input, `unsupported unit in ${JSON.stringify(token)}`)
|
|
121
|
+
} else {
|
|
122
|
+
if (color !== undefined) throw invalid(input, 'multiple colors')
|
|
123
|
+
color = token
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (lengths.length < 2 || lengths.length > 4) {
|
|
128
|
+
throw invalid(input, `expected 2-4 lengths, got ${lengths.length}`)
|
|
129
|
+
}
|
|
130
|
+
// The `= 0` on the offsets never fires (length >= 2 is validated
|
|
131
|
+
// above); it's here for noUncheckedIndexedAccess.
|
|
132
|
+
const [offsetX = 0, offsetY = 0, blurRadius = 0, spreadDistance = 0] =
|
|
133
|
+
lengths
|
|
134
|
+
if (blurRadius < 0) throw invalid(input, 'negative blur radius')
|
|
135
|
+
|
|
136
|
+
return {
|
|
137
|
+
offsetX,
|
|
138
|
+
offsetY,
|
|
139
|
+
blurRadius,
|
|
140
|
+
spreadDistance,
|
|
141
|
+
color: color ?? 'black',
|
|
142
|
+
inset,
|
|
143
|
+
}
|
|
144
|
+
})
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/** Resolve either input form (CSS string or structured layers) to layers. */
|
|
148
|
+
export function resolveBoxShadowInput(
|
|
149
|
+
input: string | readonly BoxShadowLayer[] | undefined,
|
|
150
|
+
): ResolvedBoxShadowLayer[] {
|
|
151
|
+
if (input === undefined) return []
|
|
152
|
+
if (typeof input === 'string') return parseBoxShadow(input)
|
|
153
|
+
return input.map((layer) => ({
|
|
154
|
+
offsetX: layer.offsetX,
|
|
155
|
+
offsetY: layer.offsetY,
|
|
156
|
+
blurRadius: layer.blurRadius ?? 0,
|
|
157
|
+
spreadDistance: layer.spreadDistance ?? 0,
|
|
158
|
+
color: layer.color ?? 'black',
|
|
159
|
+
inset: layer.inset ?? false,
|
|
160
|
+
}))
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Pair up `from`/`to` layer lists for interpolation, CSS-transition style:
|
|
165
|
+
* the shorter list is padded with an invisible layer (all lengths 0,
|
|
166
|
+
* transparent color) matching the counterpart's `inset` flag. A genuine
|
|
167
|
+
* `inset` mismatch between paired layers is not interpolable and throws.
|
|
168
|
+
*/
|
|
169
|
+
export function pairBoxShadowLayers(
|
|
170
|
+
from: ResolvedBoxShadowLayer[],
|
|
171
|
+
to: ResolvedBoxShadowLayer[],
|
|
172
|
+
): Array<{ from: ResolvedBoxShadowLayer; to: ResolvedBoxShadowLayer }> {
|
|
173
|
+
const count = Math.max(from.length, to.length)
|
|
174
|
+
const pairs: Array<{
|
|
175
|
+
from: ResolvedBoxShadowLayer
|
|
176
|
+
to: ResolvedBoxShadowLayer
|
|
177
|
+
}> = []
|
|
178
|
+
for (let i = 0; i < count; i++) {
|
|
179
|
+
const a = from[i]
|
|
180
|
+
const b = to[i]
|
|
181
|
+
const fromLayer = a ?? invisibleLayer(b!.inset)
|
|
182
|
+
const toLayer = b ?? invisibleLayer(a!.inset)
|
|
183
|
+
if (fromLayer.inset !== toLayer.inset) {
|
|
184
|
+
throw new Error(
|
|
185
|
+
`[inertia] useShadow: boxShadow layer ${i} is 'inset' on one side ` +
|
|
186
|
+
'but not the other — inset cannot be interpolated. Give both ' +
|
|
187
|
+
'sides the same inset-ness (pad with a transparent layer if needed).',
|
|
188
|
+
)
|
|
189
|
+
}
|
|
190
|
+
pairs.push({ from: fromLayer, to: toLayer })
|
|
191
|
+
}
|
|
192
|
+
return pairs
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function invisibleLayer(inset: boolean): ResolvedBoxShadowLayer {
|
|
196
|
+
return {
|
|
197
|
+
offsetX: 0,
|
|
198
|
+
offsetY: 0,
|
|
199
|
+
blurRadius: 0,
|
|
200
|
+
spreadDistance: 0,
|
|
201
|
+
color: 'transparent',
|
|
202
|
+
inset,
|
|
203
|
+
}
|
|
204
|
+
}
|