Skip to content

fix: set the focus starting point without a fragment navigation - #16992

Open
Nic-Polumeyv wants to merge 3 commits into
client-focus-designfrom
client-focus-starting-point
Open

fix: set the focus starting point without a fragment navigation#16992
Nic-Polumeyv wants to merge 3 commits into
client-focus-designfrom
client-focus-starting-point

Conversation

@Nic-Polumeyv

@Nic-Polumeyv Nic-Polumeyv commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Fixes #16982.

Firefox and WebKit drop the focus a frame after tabindex is removed rather than synchronously, so the two starting-point tests poll for <body> instead of reading activeElement once. The target now receives a focus/blur pair it never got from a fragment navigation, which is the trade-off teemingc named in #10856.

@pkg-svelte-dev

pkg-svelte-dev Bot commented Sep 1, 2026

Copy link
Copy Markdown

Install the latest version of @sveltejs/kit from 942509e:

pnpm add https://pkg.svelte.dev/@sveltejs/kit/c/942509eee2372428e7452642821c780b9764e8a1

Open in pkg.svelte.dev: https://pkg.svelte.dev/repos/kit/pr/16992

@changeset-bot

changeset-bot Bot commented Sep 1, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 942509e

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@sveltejs/kit Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai

coderabbitai Bot commented Sep 1, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

SvelteKit now sets the sequential focus starting point directly on the hash target or document body. The focus helper preserves the target’s original tabindex state. Navigation no longer uses temporary fragment navigation or focus-reset state. Scroll restoration no longer returns a hash target. Tests verify focus, tabindex restoration, scroll behaviour, and the absence of leaked hashchange events.

Merge Risk: 🔵 Low · up to 94250

Direct focus reset avoids fragment-navigation side effects, but application focus handlers cannot reliably retain a tabindex change made during focus. This can affect keyboard-navigation behavior and should be corrected before merge.

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Backward Compatibility Impact Disclosure ✅ Passed No breaking public interface change is present. The changed reset_focus and restore_scroll functions are internal runtime modules, are not exposed through packages/kit/package.json export paths,…
Title check ✅ Passed The title uses the required fix: prefix and clearly summarises the focus-starting-point change.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@svelte-docs-bot

Copy link
Copy Markdown

@teemingc
teemingc force-pushed the client-focus-starting-point branch from 9a1d481 to 39d10d1 Compare September 7, 2026 05:38

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Note

Quiet mode is enabled, so only the most important comments were posted inline. Other review comments are grouped below.

🟡 Other comments (1)
packages/kit/src/runtime/client/focus.js-32-35 (1)

32-35: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Preserve tabindex changes made by focus handlers.

element.focus() runs application focus handlers before Line 32. If a handler changes tabindex, this branch restores the captured value and discards the handler change. For example, a handler that adds tabindex="0" to a target that initially has no attribute will have the attribute removed.

Restore the original value only if the temporary tabindex="-1" is still present. Add a regression test with a synchronous focus handler.

Proposed fix
-	if (tabindex !== null) {
-		element.setAttribute('tabindex', tabindex);
-	} else {
-		element.removeAttribute('tabindex');
+	if (element.getAttribute('tabindex') === '-1') {
+		if (tabindex !== null) {
+			element.setAttribute('tabindex', tabindex);
+		} else {
+			element.removeAttribute('tabindex');
+		}
 	}

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: QUIET

Plan: Advanced

Run ID: fa011ccf-7701-40e4-acc5-7637b41897e5

📥 Commits

Reviewing files that changed from the base of the PR and between b75501c and 39d10d1.

📒 Files selected for processing (8)
  • .changeset/focus-starting-point.md
  • packages/kit/src/runtime/client/client.js
  • packages/kit/src/runtime/client/focus.js
  • packages/kit/src/runtime/client/focus.spec.js
  • packages/kit/src/runtime/client/scroll.js
  • packages/kit/src/runtime/client/scroll.spec.js
  • packages/kit/test/apps/basics/test/cross-platform/client.test.js
  • packages/kit/test/apps/hash-based-routing/test/test.js
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • sveltejs/vite-plugin-svelte (manual)
  • vitejs/vite (manual)
  • sveltejs/svelte (manual)

Included review availability: Your plan provides up to 10 included reviews per hour; 7 remain after this review.

@teemingc
teemingc force-pushed the client-focus-starting-point branch from 39d10d1 to 942509e Compare September 8, 2026 11:58
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.

Set the sequential focus navigation starting point without location.replace

1 participant