Skip to content

fix(core): harden composition and animation hooks#264

Merged
RtlZeroMemory merged 5 commits intomainfrom
fix/composition-animation-hardening
Mar 6, 2026
Merged

fix(core): harden composition and animation hooks#264
RtlZeroMemory merged 5 commits intomainfrom
fix/composition-animation-hardening

Conversation

@RtlZeroMemory
Copy link
Owner

@RtlZeroMemory RtlZeroMemory commented Mar 6, 2026

Summary

  • make composite widgets layout-transparent by default with a fragment wrapper and align the widget context contract around useViewport
  • harden animation hooks with a shared frame driver, semantic input tracking, latest-callback handling, and retained transition progress for useAnimatedValue
  • harden streaming hook reconnect behavior, expand regression coverage, and sync composition/animation/hooks docs plus changelog entries

What changed

  • defineWidget(...) now defaults to a layout-transparent fragment wrapper instead of silently inserting a column
  • WidgetContext.useViewport is required and createWidgetContext(...) now supplies it consistently
  • animation hooks no longer depend on stringified config signatures for invalidation
  • useParallel and useChain read latest callbacks without stale-closure behavior
  • useAnimatedValue(..., { mode: "transition" }) preserves pause/resume progress
  • useStagger(...) restarts on same-length item identity changes instead of only count changes
  • useEventSource(...) and useWebSocket(...) clamp reconnect delays away from tight-loop reconnects
  • docs now reflect the real hook surface, easing presets, viewport availability, callback behavior, and stable parser guidance

Validation

  • npx tsx --test packages/core/src/widgets/__tests__/composition.test.ts packages/core/src/runtime/__tests__/reconcile.composite.test.ts packages/core/src/widgets/__tests__/composition.useAnimatedValue.test.ts packages/core/src/widgets/__tests__/composition.animationOrchestration.test.ts packages/core/src/widgets/__tests__/composition.animationHooks.test.ts packages/core/src/widgets/__tests__/composition.animationPlayback.test.ts packages/core/src/widgets/__tests__/composition.streamingHooks.test.ts
  • npx tsx --test packages/core/src/forms/__tests__/useForm.test.ts packages/core/src/forms/__tests__/form.disabled.test.ts packages/core/src/forms/__tests__/form.fieldArray.test.ts packages/core/src/forms/__tests__/form.wizard.test.ts
  • node scripts/run-tests.mjs
    • current tree result: 4866 pass / 54 fail
    • failures are outside this staged slice and are dominated by unrelated dirty-tree source/dist tests already present in the repo state
  • Live PTY worker/frame-audit pass:
    • deterministic viewport 300x68
    • exercised route switch (bridge -> engineering), theme cycle, and quit
    • backend_submitted=877, worker_completed=877, hash_mismatch_backend_vs_worker=0

Notes

  • I committed only the module-focused files for this PR because the worktree also contains many unrelated modifications.

Summary by CodeRabbit

  • Breaking Changes

    • Widget context now requires useViewport; default widget wrapper is layout‑transparent "fragment".
  • New Features

    • Added useAnimatedValue, useParallel, and useChain for advanced animation orchestration.
    • Added Expo, Back, and Bounce easing presets.
    • Fragment vnode kind added for layout-transparent grouping.
  • Bug Fixes

    • Preserve animation progress across pause/resume and avoid stale callbacks.
    • Restart stagger on same‑length replacements.
    • Clamp streaming reconnect delays to a 10ms minimum.
  • Documentation

    • Updated guides and examples for composition, animation, and streaming hooks.

@coderabbitai
Copy link

coderabbitai bot commented Mar 6, 2026

Warning

Rate limit exceeded

@RtlZeroMemory has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 1 minutes and 52 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 316fb571-9187-43b3-87de-26494b0e2048

📥 Commits

Reviewing files that changed from the base of the PR and between 9affe5c and 57b7a36.

📒 Files selected for processing (9)
  • CHANGELOG.md
  • packages/core/src/layout/engine/layoutEngine.ts
  • packages/core/src/router/__tests__/helpers.test.ts
  • packages/core/src/runtime/commit.ts
  • packages/core/src/widgets/__tests__/accordion.test.ts
  • packages/core/src/widgets/__tests__/breadcrumb.test.ts
  • packages/core/src/widgets/__tests__/pagination.test.ts
  • packages/core/src/widgets/__tests__/tabs.test.ts
  • packages/jsx/src/__tests__/navigation.test.tsx
📝 Walkthrough

Walkthrough

This PR adds fragment-based container support, makes WidgetContext.useViewport required, replaces per-hook timers with a shared frame-driven animation scheduler, introduces/clarifies animation utility hooks and docs, clamps streaming reconnect delays, and adds tests and harness updates for layout and animation behavior.

Changes

Cohort / File(s) Summary
Docs & Changelog
CHANGELOG.md, CLAUDE.md, docs/guide/animation.md, docs/guide/composition.md, docs/guide/hooks-reference.md
Added Unreleased changelog entries and documentation updates: shared frame-driven animation narrative, new easing presets, introduced/clarified hooks (useViewport, useAnimatedValue, useParallel, useChain), playback semantics, and streaming reconnect guidance.
Types & Composition
packages/core/src/widgets/types.ts, packages/core/src/widgets/composition.ts, packages/core/src/widgets/protocol.ts
Added fragment VNode variant and registered it in widget protocol; expanded WidgetWrapperKind to include "fragment"; changed WidgetContext.useViewport from optional to required and changed default wrapper to fragment.
Renderer & Layout
packages/core/src/renderer/.../renderTree.ts, packages/core/src/renderer/renderToDrawlist/overflowCulling.ts, packages/core/src/layout/engine/layoutEngine.ts, packages/core/src/runtime/commit.ts
Unified handling of fragment with themed/container paths: rendering case, overflow culling, synthetic-column cache & helpers, layout branches, and commit/fast-reuse container logic updated to treat fragments as transparent containers.
Animation subsystem
packages/core/src/widgets/hooks/animation.ts
Replaced per-hook timers with a shared frame scheduler and AnimationLoopHandle; added subscribe/unsubscribe, batched frame scheduling, safe onComplete wrappers, richer run/track state, input-equality checks, and unified pause/resume/cancel semantics across transitions, sequences, parallels, staggers, springs, and animated values.
Streaming / Data hooks
packages/core/src/widgets/hooks/data.ts
Introduced MIN_STREAM_RECONNECT_MS and normalizeReconnectDelayMs; enforced a minimum reconnect delay for EventSource/WebSocket reconnections.
Layout/Render internals
packages/core/src/layout/engine/layoutEngine.ts, packages/core/src/renderer/.../renderTree.ts, packages/core/src/renderer/renderToDrawlist/overflowCulling.ts
Renamed synthetic-themed cache to synthetic-transparent, introduced TransparentVNode union to treat fragment/themed uniformly, and updated call sites to use the new types and cache.
Tests
packages/core/src/widgets/__tests__/*, packages/core/src/runtime/__tests__/reconcile.composite.test.ts, packages/core/src/widgets/tests/protocol.test.ts, packages/core/src/forms/__tests__/*
Added/updated tests for default wrapper layout transparency, fragment protocol coverage, animation orchestration/playback/useAnimatedValue/useStagger behaviors; added useViewport stubs to form test harnesses; some duplicated tests observed.
Test harness & forms tests
packages/core/src/forms/__tests__/harness.ts, packages/core/src/forms/__tests__/*.test.ts
Exposed useViewport on form harness (returns { width: 80, height: 24, breakpoint: "md" }) and migrated certain tests to use the harness.

Sequence Diagram(s)

sequenceDiagram
    rect rgba(200,230,255,0.5)
    participant Hook as Hook (useTransition / useParallel / useStagger)
    end
    rect rgba(200,255,200,0.5)
    participant Scheduler as AnimationLoopScheduler
    end
    rect rgba(255,230,200,0.5)
    participant Frame as Frame Source (rAF / tick)
    end

    Hook->>Scheduler: subscribe(callback, handle)
    Scheduler->>Frame: requestFrame() when first subscriber
    Frame-->>Scheduler: frameTick(timestamp)
    Scheduler->>Hook: invoke callback(step, timestamp)
    alt animation complete
        Hook->>Scheduler: unsubscribe(callback)
        Hook->>Hook: safeInvoke(onComplete)
    end
    Scheduler->>Frame: requestFrame() while subscribers exist
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Poem

🐇 I hop on frames, one steady beat,

No stray timers now — rhythms meet.
Fragments weave where columns stood,
Viewports steady, tests feel good.
A little rabbit cheers the code.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 26.42% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix(core): harden composition and animation hooks' directly reflects the main objectives of the PR, which center on hardening composition and animation hooks with defensive improvements.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/composition-animation-hardening

Warning

Review ran into problems

🔥 Problems

Git: Failed to clone repository. Please run the @coderabbitai full review command to re-trigger a full review. If the issue persists, set path_filters to include or exclude specific files.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
CHANGELOG.md (1)

11-11: Break the dense sentence into bullet points for readability and consistency.

The Bug Fixes entry condenses 6+ distinct changes into a single 160+ word sentence. Previous releases (e.g., lines 42-44, 71-74) use bullet points to list multiple fixes, making them easier to scan and reference.

♻️ Proposed refactor for improved readability
-  - **core/composition + hooks**: Composite widgets now use a layout-transparent default wrapper, animation hooks share a frame driver, transition/orchestration hooks stop relying on stringified config signatures, `useAnimatedValue` transition playback preserves progress across pause/resume, `useStagger` restarts on same-length item replacement, and streaming hook reconnect delays clamp away tight-loop reconnects.
+  - **core/composition**: Composite widgets now use a layout-transparent default wrapper (fragment) instead of implicit column layout.
+  - **hooks/animation**: Animation hooks now share a unified frame driver for frame-based scheduling, replacing prior timer mechanisms.
+  - **hooks/animation**: Transition and orchestration hooks no longer rely on stringified config signatures for invalidation.
+  - **hooks/animation**: `useAnimatedValue` with `mode: "transition"` now preserves playback progress across pause/resume.
+  - **hooks/animation**: `useParallel` and `useChain` now read latest callbacks to prevent stale closures.
+  - **hooks/animation**: `useStagger` now restarts when item identity changes for the same-length array.
+  - **hooks/streaming**: `useEventSource` and `useWebSocket` now clamp reconnect delays to prevent tight-loop reconnections.

Note: This refactor also adds the missing useParallel/useChain callback behavior mentioned in the PR objectives.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@CHANGELOG.md` at line 11, Split the long Bug Fixes sentence under
"core/composition + hooks" into separate bullet points so each distinct change
is its own line: create bullets for "Composite widgets now use a
layout-transparent default wrapper", "animation hooks share a frame driver",
"transition/orchestration hooks stop relying on stringified config signatures",
"`useAnimatedValue` transition playback preserves progress across pause/resume",
"`useStagger` restarts on same-length item replacement", "streaming hook
reconnect delays clamp away tight-loop reconnects", and add the missing bullet
about `useParallel`/`useChain` callback behavior; preserve the original wording
for each item and follow the existing bullet style used elsewhere in the
changelog.
packages/core/src/forms/__tests__/form.fieldArray.test.ts (1)

25-78: Consider using the shared createFormHarness from harness.ts.

This file defines its own createTestContext function which largely duplicates createFormHarness in harness.ts. Both now provide identical useViewport implementations. Using the shared harness would reduce duplication and ensure consistency when the test harness evolves.

♻️ Suggested refactor
-import {
-  createCompositeInstanceRegistry,
-  createHookContext,
-  runPendingEffects,
-} from "../../runtime/instances.js";
-import type { WidgetContext } from "../../widgets/composition.js";
 import type { UseFormOptions, UseFormReturn } from "../types.js";
-import { useForm } from "../useForm.js";
+import { createFormHarness } from "./harness.js";

Then replace createTestContext() calls with createFormHarness().

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/forms/__tests__/form.fieldArray.test.ts` around lines 25 -
78, The test file defines a duplicate createTestContext function that mirrors
the shared createFormHarness in harness.ts (including the same useViewport
behavior); replace the local createTestContext with the shared createFormHarness
to remove duplication: remove or stop exporting the local createTestContext,
import and call createFormHarness instead of createTestContext in this test, and
ensure the same generic typing and return shape are preserved so existing usages
of createTestContext (and calls to methods like render, unmount,
getInvalidateCount) continue to work unchanged; verify useViewport behavior
matches by using the harness implementation.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@CHANGELOG.md`:
- Around line 9-11: Add a user-visible change note to the changelog documenting
that WidgetContext.useViewport is now required and createWidgetContext(...) will
always supply it; update the "Bug Fixes" entry or add a "Breaking Changes"
section that explicitly lists "Require WidgetContext.useViewport" and describes
that callers creating custom widget contexts must now provide a useViewport
implementation (mention createWidgetContext as the helper that will supply it
going forward). Ensure the language is concise and flagged as a breaking change
so users know to update existing code that constructs widget contexts.

In
`@packages/core/src/widgets/__tests__/composition.animationOrchestration.test.ts`:
- Around line 165-174: The test file formatting is out of sync for the
"useParallel playback pause and resume preserves elapsed progress" test: run the
project formatter (e.g., biome format --write or your repo's configured
formatter) on this file to reformat the block that declares running, paused, and
the render call (variables running, paused, and render and functions
createHarness and useParallel) so the CI no longer flags lines 166-170; commit
the formatted changes.

---

Nitpick comments:
In `@CHANGELOG.md`:
- Line 11: Split the long Bug Fixes sentence under "core/composition + hooks"
into separate bullet points so each distinct change is its own line: create
bullets for "Composite widgets now use a layout-transparent default wrapper",
"animation hooks share a frame driver", "transition/orchestration hooks stop
relying on stringified config signatures", "`useAnimatedValue` transition
playback preserves progress across pause/resume", "`useStagger` restarts on
same-length item replacement", "streaming hook reconnect delays clamp away
tight-loop reconnects", and add the missing bullet about
`useParallel`/`useChain` callback behavior; preserve the original wording for
each item and follow the existing bullet style used elsewhere in the changelog.

In `@packages/core/src/forms/__tests__/form.fieldArray.test.ts`:
- Around line 25-78: The test file defines a duplicate createTestContext
function that mirrors the shared createFormHarness in harness.ts (including the
same useViewport behavior); replace the local createTestContext with the shared
createFormHarness to remove duplication: remove or stop exporting the local
createTestContext, import and call createFormHarness instead of
createTestContext in this test, and ensure the same generic typing and return
shape are preserved so existing usages of createTestContext (and calls to
methods like render, unmount, getInvalidateCount) continue to work unchanged;
verify useViewport behavior matches by using the harness implementation.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4ba29812-d3d2-4b36-b512-8e4c457dda96

📥 Commits

Reviewing files that changed from the base of the PR and between e898663 and b85abaf.

📒 Files selected for processing (19)
  • CHANGELOG.md
  • CLAUDE.md
  • docs/guide/animation.md
  • docs/guide/composition.md
  • docs/guide/hooks-reference.md
  • packages/core/src/forms/__tests__/form.disabled.test.ts
  • packages/core/src/forms/__tests__/form.fieldArray.test.ts
  • packages/core/src/forms/__tests__/form.wizard.test.ts
  • packages/core/src/forms/__tests__/harness.ts
  • packages/core/src/forms/__tests__/useForm.test.ts
  • packages/core/src/runtime/__tests__/reconcile.composite.test.ts
  • packages/core/src/widgets/__tests__/composition.animationHooks.test.ts
  • packages/core/src/widgets/__tests__/composition.animationOrchestration.test.ts
  • packages/core/src/widgets/__tests__/composition.animationPlayback.test.ts
  • packages/core/src/widgets/__tests__/composition.test.ts
  • packages/core/src/widgets/__tests__/composition.useAnimatedValue.test.ts
  • packages/core/src/widgets/composition.ts
  • packages/core/src/widgets/hooks/animation.ts
  • packages/core/src/widgets/hooks/data.ts

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b85abaf1f7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
packages/core/src/widgets/__tests__/composition.animationOrchestration.test.ts (1)

355-397: ⚠️ Potential issue | 🟡 Minor

Fix formatting issues flagged by CI.

The pipeline reports that Biome formatter would have printed different content for lines 356-377. Run the formatter before merging.

Suggested fix

Run the project formatter to resolve the formatting discrepancy:

npx biome format --write packages/core/src/widgets/__tests__/composition.animationOrchestration.test.ts

Or use the project's lint script if configured.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/core/src/widgets/__tests__/composition.animationOrchestration.test.ts`
around lines 355 - 397, The test "useChain playback changes do not reset the
active step" has formatting differences flagged by CI; run the project formatter
(e.g. npx biome format --write) or the repo's lint/format script to reformat
packages/core/src/widgets/__tests__/composition.animationOrchestration.test.ts
so the block containing the running/paused arrays and the test body matches the
project's style, then re-add the formatted file to the PR and push the changes.
🧹 Nitpick comments (2)
packages/core/src/widgets/hooks/animation.ts (1)

574-597: Deduplicate transition state sync logic to avoid drift.

The transition reset/sync block is duplicated in useTransition and useAnimatedValue (transition mode) even though syncTransitionRunState(...) exists. Reusing the helper in both places will keep behavior aligned long-term.

♻️ Refactor sketch
-    const state = transitionStateRef.current;
-    const shouldReset =
-      !state.initialized ||
-      !Object.is(state.to, value) ||
-      state.durationMs !== durationMs ||
-      state.delayMs !== delayMs ||
-      state.easing !== easing;
-
-    if (shouldReset) {
-      state.initialized = true;
-      state.from = currentRef.current;
-      state.to = value;
-      state.durationMs = durationMs;
-      state.delayMs = delayMs;
-      state.easing = easing;
-      state.elapsedMs = playback.reversed ? durationMs : 0;
-      state.pendingDelayMs = delayMs;
-    } else {
-      state.durationMs = durationMs;
-      state.delayMs = delayMs;
-      state.easing = easing;
-      if (state.elapsedMs < 0) state.elapsedMs = 0;
-      if (state.elapsedMs > state.durationMs) state.elapsedMs = state.durationMs;
-    }
+    const state = transitionStateRef.current;
+    syncTransitionRunState(
+      state,
+      currentRef.current,
+      value,
+      durationMs,
+      easing,
+      delayMs,
+      playback.reversed,
+    );

Also applies to: 1068-1091

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/widgets/hooks/animation.ts` around lines 574 - 597, Replace
the duplicated transition reset/sync logic in useTransition and useAnimatedValue
(transition mode) by calling the existing helper syncTransitionRunState instead
of manually mutating transitionStateRef.current; pass the current transition
state and the relevant inputs (new target value, durationMs, delayMs, easing,
currentRef/current value, and playback/reversed) so syncTransitionRunState
performs the initialization/update and clamping of elapsed/pendingDelay
consistently across both hooks and avoids drift.
CHANGELOG.md (1)

16-21: Optional: compact repeated animation bullets for readability.

These lines repeat the same prefix many times; grouping can make the section easier to scan.

📝 Optional wording cleanup
-- **hooks/animation**: Animation hooks now share a frame driver.
-- **hooks/animation**: Transition/orchestration hooks stop relying on stringified config signatures.
-- **hooks/animation**: `useAnimatedValue` transition playback preserves progress across pause/resume.
-- **hooks/animation**: `useParallel` and `useChain` now read the latest callbacks without stale-closure behavior.
-- **hooks/animation**: `useStagger` restarts on same-length item replacement.
+- **hooks/animation**:
+  - Animation hooks now share a frame driver.
+  - Transition/orchestration hooks stop relying on stringified config signatures.
+  - `useAnimatedValue` transition playback preserves progress across pause/resume.
+  - `useParallel` and `useChain` now read the latest callbacks without stale-closure behavior.
+  - `useStagger` restarts on same-length item replacement.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@CHANGELOG.md` around lines 16 - 21, The changelog repeats the
"hooks/animation" prefix across multiple lines; consolidate these into a single
"hooks/animation" entry followed by comma-separated or semicolon-separated
sub-items for the specific changes (e.g., "shared frame driver", "no stringified
config signatures", "`useAnimatedValue` preserves progress on pause/resume",
"`useParallel`/`useChain` avoid stale closures", "`useStagger` restarts on
same-length replacement") and keep the existing "hooks/streaming" line separate;
update the text so the unique symbols `useAnimatedValue`, `useParallel`,
`useChain`, and `useStagger` are still mentioned for clarity.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In
`@packages/core/src/widgets/__tests__/composition.animationOrchestration.test.ts`:
- Around line 355-397: The test "useChain playback changes do not reset the
active step" has formatting differences flagged by CI; run the project formatter
(e.g. npx biome format --write) or the repo's lint/format script to reformat
packages/core/src/widgets/__tests__/composition.animationOrchestration.test.ts
so the block containing the running/paused arrays and the test body matches the
project's style, then re-add the formatted file to the PR and push the changes.

---

Nitpick comments:
In `@CHANGELOG.md`:
- Around line 16-21: The changelog repeats the "hooks/animation" prefix across
multiple lines; consolidate these into a single "hooks/animation" entry followed
by comma-separated or semicolon-separated sub-items for the specific changes
(e.g., "shared frame driver", "no stringified config signatures",
"`useAnimatedValue` preserves progress on pause/resume",
"`useParallel`/`useChain` avoid stale closures", "`useStagger` restarts on
same-length replacement") and keep the existing "hooks/streaming" line separate;
update the text so the unique symbols `useAnimatedValue`, `useParallel`,
`useChain`, and `useStagger` are still mentioned for clarity.

In `@packages/core/src/widgets/hooks/animation.ts`:
- Around line 574-597: Replace the duplicated transition reset/sync logic in
useTransition and useAnimatedValue (transition mode) by calling the existing
helper syncTransitionRunState instead of manually mutating
transitionStateRef.current; pass the current transition state and the relevant
inputs (new target value, durationMs, delayMs, easing, currentRef/current value,
and playback/reversed) so syncTransitionRunState performs the
initialization/update and clamping of elapsed/pendingDelay consistently across
both hooks and avoids drift.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 984f1952-3846-47b3-b04f-3a7254aa2ff4

📥 Commits

Reviewing files that changed from the base of the PR and between b85abaf and 1c90b03.

📒 Files selected for processing (16)
  • CHANGELOG.md
  • packages/core/src/forms/__tests__/form.disabled.test.ts
  • packages/core/src/forms/__tests__/form.fieldArray.test.ts
  • packages/core/src/forms/__tests__/form.wizard.test.ts
  • packages/core/src/forms/__tests__/harness.ts
  • packages/core/src/forms/__tests__/useForm.test.ts
  • packages/core/src/layout/engine/layoutEngine.ts
  • packages/core/src/renderer/renderToDrawlist/overflowCulling.ts
  • packages/core/src/renderer/renderToDrawlist/renderTree.ts
  • packages/core/src/runtime/commit.ts
  • packages/core/src/widgets/__tests__/composition.animationOrchestration.test.ts
  • packages/core/src/widgets/__tests__/composition.useAnimatedValue.test.ts
  • packages/core/src/widgets/hooks/animation.ts
  • packages/core/src/widgets/protocol.ts
  • packages/core/src/widgets/tests/protocol.test.ts
  • packages/core/src/widgets/types.ts
🚧 Files skipped from review as they are similar to previous changes (5)
  • packages/core/src/forms/tests/form.wizard.test.ts
  • packages/core/src/widgets/tests/composition.useAnimatedValue.test.ts
  • packages/core/src/forms/tests/harness.ts
  • packages/core/src/forms/tests/useForm.test.ts
  • packages/core/src/forms/tests/form.disabled.test.ts

@RtlZeroMemory RtlZeroMemory merged commit b697ff0 into main Mar 6, 2026
31 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant