⬆️ react-spring 10.0.3 (#7224)

* react-spring (10.0.0 -> ^10.0.3)

* note

* fix VRT

* fix more animations

* fix budget month colouring
This commit is contained in:
Matt Fiddaman
2026-03-17 16:00:27 +00:00
committed by GitHub
parent 5b227f5fa1
commit dfd6e468a6
8 changed files with 138 additions and 117 deletions

View File

@@ -86,7 +86,7 @@
"react-redux": "^9.2.0",
"react-router": "7.13.0",
"react-simple-pull-to-refresh": "^1.3.4",
"react-spring": "10.0.0",
"react-spring": "^10.0.3",
"react-swipeable": "^7.0.2",
"react-virtualized-auto-sizer": "^2.0.2",
"recharts": "^3.7.0",

View File

@@ -153,22 +153,27 @@ function Notification({
const yOffset = index * Y_OFFSET_PER_LEVEL;
const [isSwiped, setIsSwiped] = useState(false);
const [spring, api] = useSpring(() => ({
x: 0,
y: yOffset,
opacity: stackOpacity,
scale,
}));
const [spring, api] = useSpring(
() => ({
from: {
x: 0,
y: yOffset,
opacity: stackOpacity,
scale,
},
}),
[],
);
// Update scale, opacity, and y-position when index changes
useEffect(() => {
void api.start({ scale, opacity: stackOpacity, y: yOffset });
void api.start({ to: { scale, opacity: stackOpacity, y: yOffset } });
}, [index, scale, stackOpacity, yOffset, api]);
const swipeHandlers = useSwipeable({
onSwiping: ({ deltaX }) => {
if (!isSwiped) {
void api.start({ x: deltaX });
void api.start({ to: { x: deltaX } });
}
},
onSwiped: ({ velocity, deltaX }) => {
@@ -179,14 +184,13 @@ function Notification({
if (Math.abs(deltaX) > threshold || velocity > 0.5) {
// Animate out & remove item after animation
void api.start({
x: direction * 1000,
opacity: 0,
to: { x: direction * 1000, opacity: 0 },
onRest: onRemove,
});
setIsSwiped(true);
} else {
// Reset position if not swiped far enough
void api.start({ x: 0 });
void api.start({ to: { x: 0 } });
}
},
trackMouse: true,

View File

@@ -24,10 +24,13 @@ export function BudgetSummaries() {
const [firstMonth] = months;
const [widthState, setWidthState] = useState(0);
const [styles, spring] = useSpring(() => ({
x: 0,
config: { mass: 3, tension: 600, friction: 80 },
}));
const [styles, spring] = useSpring(
() => ({
from: { x: 0 },
config: { mass: 3, tension: 600, friction: 80 },
}),
[],
);
const containerRef = useResizeObserver<HTMLDivElement>(
useCallback(rect => {
@@ -55,7 +58,9 @@ export function BudgetSummaries() {
}
const to = -offsetX;
void spring.start({ from: { x: from }, x: to });
if (from !== to) {
void spring.start({ from: { x: from }, to: { x: to } });
}
}, [spring, firstMonth, monthWidth, allMonths]);
useLayoutEffect(() => {
@@ -63,7 +68,7 @@ export function BudgetSummaries() {
}, [firstMonth]);
useLayoutEffect(() => {
void spring.start({ from: { x: -monthWidth }, to: { x: -monthWidth } });
void spring.start({ to: { x: -monthWidth }, immediate: true });
}, [spring, monthWidth]);
const { SummaryComponent } = useBudgetComponents();

View File

@@ -34,10 +34,13 @@ export function ActionableGridListItem<T extends object>({
const hasActions = !!actions;
// Spring animation for the swipe
const [{ x }, api] = useSpring(() => ({
x: 0,
config: config.stiff,
}));
const [{ x }, api] = useSpring(
() => ({
from: { x: 0 },
config: config.stiff,
}),
[],
);
// Handle drag gestures
const bind = useDrag(
@@ -48,7 +51,7 @@ export function ActionableGridListItem<T extends object>({
if (active) {
dragStartedRef.current = true;
void api.start({
x: Math.max(-actionsWidth, Math.min(0, currentX)),
to: { x: Math.max(-actionsWidth, Math.min(0, currentX)) },
onRest: () => {
dragStartedRef.current = false;
},
@@ -62,7 +65,7 @@ export function ActionableGridListItem<T extends object>({
(vx < -0.5 && currentX < -actionsWidth / 5);
void api.start({
x: shouldReveal ? -actionsWidth : 0,
to: { x: shouldReveal ? -actionsWidth : 0 },
onRest: () => {
dragStartedRef.current = false;
setIsRevealed(shouldReveal);
@@ -141,7 +144,7 @@ export function ActionableGridListItem<T extends object>({
? actions({
close: () => {
void api.start({
x: 0,
to: { x: 0 },
onRest: () => {
setIsRevealed(false);
},

View File

@@ -52,7 +52,7 @@ export function MobileNavTabs() {
maxWidth: `${100 / COLUMN_COUNT}%`,
};
const [{ y }, api] = useSpring(() => ({ y: OPEN_DEFAULT_Y }));
const [{ y }, api] = useSpring(() => ({ from: { y: OPEN_DEFAULT_Y } }), []);
const openFull = useCallback(
({ canceled }: { canceled?: boolean }) => {
@@ -60,7 +60,7 @@ export function MobileNavTabs() {
// so we change the spring config to create a nice wobbly effect
setNavbarState('open');
void api.start({
y: OPEN_FULL_Y,
to: { y: OPEN_FULL_Y },
immediate: isTestEnv,
config: canceled ? config.wobbly : config.stiff,
});
@@ -72,7 +72,7 @@ export function MobileNavTabs() {
(velocity = 0) => {
setNavbarState('default');
void api.start({
y: OPEN_DEFAULT_Y,
to: { y: OPEN_DEFAULT_Y },
immediate: isTestEnv,
config: { ...config.stiff, velocity },
});
@@ -84,7 +84,7 @@ export function MobileNavTabs() {
(velocity = 0) => {
setNavbarState('hidden');
void api.start({
y: HIDDEN_Y,
to: { y: HIDDEN_Y },
immediate: isTestEnv,
config: { ...config.stiff, velocity },
});
@@ -199,7 +199,7 @@ export function MobileNavTabs() {
} else {
// when the user keeps dragging, we just move the sheet according to
// the cursor position
void api.start({ y: oy, immediate: true });
void api.start({ to: { y: oy }, immediate: true });
}
},
{

View File

@@ -447,15 +447,18 @@ function CalendarInner({ widget, parameters }: CalendarInnerProps) {
const openY = 0;
const [mobileTransactionsOpen, setMobileTransactionsOpen] = useState(false);
const [{ y }, api] = useSpring(() => ({
y: closeY.current,
immediate: false,
}));
const [{ y }, api] = useSpring(
() => ({
from: { y: closeY.current },
immediate: false,
}),
[],
);
useEffect(() => {
closeY.current = totalHeight;
void api.start({
y: mobileTransactionsOpen ? openY : closeY.current,
to: { y: mobileTransactionsOpen ? openY : closeY.current },
immediate: false,
});
}, [totalHeight, mobileTransactionsOpen, api]);
@@ -463,7 +466,7 @@ function CalendarInner({ widget, parameters }: CalendarInnerProps) {
const open = useCallback(
({ canceled }: { canceled: boolean }) => {
void api.start({
y: openY,
to: { y: openY },
immediate: false,
config: canceled ? config.wobbly : config.stiff,
});
@@ -475,7 +478,7 @@ function CalendarInner({ widget, parameters }: CalendarInnerProps) {
const close = useCallback(
(velocity = 0) => {
void api.start({
y: closeY.current,
to: { y: closeY.current },
config: { ...config.stiff, velocity },
});
setMobileTransactionsOpen(false);
@@ -487,7 +490,7 @@ function CalendarInner({ widget, parameters }: CalendarInnerProps) {
({ offset: [, oy], cancel }) => {
if (oy < 0) {
cancel();
void api.start({ y: 0, immediate: true });
void api.start({ to: { y: 0 }, immediate: true });
return;
}
@@ -501,7 +504,7 @@ function CalendarInner({ widget, parameters }: CalendarInnerProps) {
open({ canceled: true });
setMobileTransactionsOpen(true);
} else {
void api.start({ y: oy, immediate: true });
void api.start({ to: { y: oy }, immediate: true });
}
}
},