Skip to content

♿ Add checks on focusable elements to include target element #3222

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 7 commits into from

Conversation

chuckcarpenter
Copy link
Member

@chuckcarpenter chuckcarpenter commented Jul 11, 2025

Adds target element to focus trap to address #3202

Copy link

vercel bot commented Jul 11, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
shepherd-docs ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jul 17, 2025 11:45pm
shepherd-landing ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jul 17, 2025 11:45pm

@chuckcarpenter
Copy link
Member Author

@beltsofplenty been trying a few things, but nothing seems to be working to add the target element yet.

Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

A concise update to include the target element in the focus trap by assigning it a tabindex and extending the modal’s focus-cycling logic.

  • Adds tabindex="0" to non-body targets in Step so they become focusable.
  • Registers a new handleFocus listener in the Svelte component to wrap Tab navigation around the target.
  • Integrates the target into forward and backward Tab handling in shepherd-element.svelte.

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
shepherd.js/src/step.ts Adds tabindex="0" for non-document.body targets to include them in focus trap
shepherd.js/src/components/shepherd-element.svelte Registers a focus-trapping keydown listener and updates Tab navigation logic

@@ -649,6 +649,10 @@ export class Step extends Evented {

target.classList.add(`${this.classPrefix}shepherd-enabled`);
target.classList.add(`${this.classPrefix}shepherd-target`);
// adds the target element to the focus trap (if not body), but not for document.body
if (target !== document.body) {
target.setAttribute('tabindex', '0');
Copy link
Preview

Copilot AI Jul 15, 2025

Choose a reason for hiding this comment

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

[nitpick] Overwriting any existing tabindex may unintentionally change the element’s tab order. Consider checking for an existing tabindex attribute before setting or using tabindex="-1" if you only need programmatic focus.

Suggested change
target.setAttribute('tabindex', '0');
if (!target.hasAttribute('tabindex')) {
target.setAttribute('tabindex', '0');
}

Copilot uses AI. Check for mistakes.

* @private
*/
function handleFocus(e) {
if (e.keyCode === KEY_TAB) {
Copy link
Preview

Copilot AI Jul 15, 2025

Choose a reason for hiding this comment

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

[nitpick] Using keyCode is deprecated and less descriptive. Prefer checking e.key === 'Tab' or e.code === 'Tab' for clarity and future compatibility.

Copilot uses AI. Check for mistakes.

if (document.activeElement === lastFocusableElement) {
e.preventDefault();
// Focus target element when tabbing forward from last element
if (step.target) {
Copy link
Member

Choose a reason for hiding this comment

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

I am not sure step.target is what we want here. I believe that is usually document.body. I think we will have to grab the element from attachTo.

@RobbieTheWagner
Copy link
Member

Closing in favor of #3230

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants