Skip to content

fix(forms): allow hash-based field focus#108376

Merged
natemoo-re merged 6 commits intomasterfrom
scraps/form/hash
Feb 17, 2026
Merged

fix(forms): allow hash-based field focus#108376
natemoo-re merged 6 commits intomasterfrom
scraps/form/hash

Conversation

@natemoo-re
Copy link
Member

@natemoo-re natemoo-re commented Feb 17, 2026

Follow-up to #107264.

The previous JSONForm system managed automatic scrolling based on the URL hash.
In #107264, we tried to replicate that but overcomplicated things with a useEffect call.
In this PR, we introduce a ref callback on the label element, automatically handle hash scrolling, and call label.control.focus() to focus on the form field's input.

@natemoo-re natemoo-re requested a review from a team as a code owner February 17, 2026 20:54
@github-actions github-actions bot added the Scope: Frontend Automatically applied to PRs that change frontend components label Feb 17, 2026
Copy link
Contributor

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

Copy link
Member

@JonasBa JonasBa left a comment

Choose a reason for hiding this comment

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

Nice 🙏🏼

return;
}
if (hash === node.dataset.field) {
node.scrollIntoView({block: 'center', behavior: 'smooth'});
Copy link
Contributor

Choose a reason for hiding this comment

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

Bug: The scrollIntoView call inside the ref callback executes before browser layout is complete, which can lead to scrolling to an incorrect position when navigating to a field.
Severity: MEDIUM

Suggested Fix

Defer the scrollIntoView call to ensure it executes after the browser has completed layout calculations. This can be achieved by wrapping the call in requestAnimationFrame, as was done in the previous implementation, or by using a setTimeout with a small delay.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: static/app/components/core/form/field/meta.tsx#L42

Potential issue: The `scrollToFieldRef` function calls `node.scrollIntoView` immediately
within a ref callback. Ref callbacks in React execute during the synchronous commit
phase, which occurs before the browser has performed layout calculations. Calling
`scrollIntoView` on an element whose final position has not yet been determined by the
browser can cause the page to scroll to an incorrect or inaccurate position. This is a
regression, as the previous implementation used `requestAnimationFrame` to defer the
scroll until after layout was complete. A similar pattern in `FoldSection.tsx` uses
`setTimeout` to explicitly delay scrolling for the same reason.

Comment on lines +35 to +45
let hash: string;
try {
hash = decodeURIComponent(window.location.hash.slice(1));
} catch {
return;
}
if (hash === node.dataset.field) {
node.scrollIntoView({block: 'center', behavior: 'smooth'});
node.control?.focus({focusVisible: true});
}
};
Copy link
Contributor

Choose a reason for hiding this comment

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

Bug: A race condition in the scrollToFieldRef callback prevents field focusing. The label's ref executes before the associated input control is mounted, causing node.control to be null.
Severity: MEDIUM

Suggested Fix

Wrap the focus logic within requestAnimationFrame or setTimeout(..., 0). This will defer the execution until after the browser has painted and the input element has been mounted in the DOM, ensuring node.control is available. For example: requestAnimationFrame(() => node.control?.focus());.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: static/app/components/core/form/field/meta.tsx#L31-L45

Potential issue: A race condition exists in the `scrollToFieldRef` callback. The
callback is attached to a `Label` component and executes immediately when the label
mounts. However, due to React's rendering order, the associated input element has not
yet mounted in the DOM. This results in `node.control` being `null` at the time of
execution. Consequently, the `node.control?.focus()` call fails silently, and the input
field does not receive focus as intended, even though the page correctly scrolls to the
field. This issue was introduced by the removal of `requestAnimationFrame`, which
previously delayed execution until the DOM was fully rendered.

@natemoo-re natemoo-re merged commit 66ce5a0 into master Feb 17, 2026
60 checks passed
@natemoo-re natemoo-re deleted the scraps/form/hash branch February 17, 2026 21:54
@TkDodo
Copy link
Collaborator

TkDodo commented Feb 18, 2026

great use of a callback ref! ignore my comment on the original commit then, I wrote that before I saw this PR ❤️

natemoo-re added a commit that referenced this pull request Feb 18, 2026
Follow-up to #108376, which merged before I was able to fix the scroll
behavior. Using `requestAnimationFrame` delays the `scrollIntoView()`
and `focus()` until rendering is complete.
mchen-sentry pushed a commit that referenced this pull request Feb 24, 2026
Follow-up to #107264.

The previous `JSONForm` system managed automatic scrolling based on the
URL hash.
In #107264, we tried to replicate that but overcomplicated things with a
`useEffect` call.
In this PR, we introduce a ref callback on the `label` element,
automatically handle hash scrolling, and call `label.control.focus()` to
focus on the form field's input.
mchen-sentry pushed a commit that referenced this pull request Feb 24, 2026
Follow-up to #108376, which merged before I was able to fix the scroll
behavior. Using `requestAnimationFrame` delays the `scrollIntoView()`
and `focus()` until rendering is complete.
natemoo-re added a commit that referenced this pull request Feb 24, 2026
Follow-up to #108414,
#108376

Implements hash-based scroll and focus with a highlight animation for
new Scraps forms

Adds refs to all base form fields.


https://github.com/user-attachments/assets/ac4c5dbd-72c5-4616-b46f-624f584e2872

Closes DE-954

---------

Co-authored-by: getsantry[bot] <66042841+getsantry[bot]@users.noreply.github.com>
@github-actions github-actions bot locked and limited conversation to collaborators Mar 5, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Scope: Frontend Automatically applied to PRs that change frontend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants