Skip to content

Disable autofocus of step content via step options #2117

Open

Description

@DaDom

Hey there!

I'd like to "re-discuss" #1588 - I have the same use case, in which I would like to keep an input in the highlighted app part focused, and not have the step popup take focus away. Currently, you use floating-ui to focus the step element after 300ms timeout (see here).

I understand that this is something where you would like to figure out a general strategy around a11y. In my case, I would however rather disable this behavior entirely via some step option autoFocus = false or something like that.
Would you accept a PR that introduces this ability, or you would not like to have such changes until you have a clearer position on this topic overall?

Activity

  1. RobbieTheWagner commented on Oct 24, 2022

    @RobbieTheWagner
    Member

    @DaDom I think we should find a way to add arbitrary elements into the focus trap that we implement. That way, we can keep what we have, but also allow adding more possible focus targets into the mix.

  2. DaDom commented on Oct 24, 2022

    @DaDom
    Author

    Great, that makes sense.
    So, equivalent to StepOptionsAttachTo.element it might be a new step option like this - assuming that you may provide more than one selector/element:

    focusableElements?: HTMLElement | HTMLElement[] | string | string[] | (() => HTMLElement | HTMLElement[] | string | string[] | null | undefined)

    Providing a value for this option will:

    • Include all matching elements into the focus trap
    • Auto-focus the first matching element when the step is shown

    Is that what you had in mind?
    Btw., am I correct that you have chosen 300ms as delay before applying focus due to the css transition duration of 0.3s for shepherd-modal-overlay-container?

  3. DaDom commented on Oct 24, 2022

    @DaDom
    Author

    Alternatively, following your existing approach of finding all focusable elements here, we might also do the same inside of the resulting HTMLElement of StepOptionsAttachTo.element.
    This could then be toggled with a simple boolean flag like this:

    interface StepOptionsAttachTo {
      element?: HTMLElement | string | (() => HTMLElement | string | null | undefined);
      on?: PopperPlacement;
      focusable?: boolean;
    }

    Let me know what you think!

  4. MaggusK commented on Feb 12, 2023

    @MaggusK

    Me too!!
    I'm new with shepherd, its the best js guiding tool (and I tested a lot!) but this described behavior, from my point of view, is a bug.
    I have inputs that start an ajax action (saving) on focus lost. So currently I can not use them during highlighting.

    (Exact workflow: click an element inside the highlighted element -> an input appears that increases the highlighted element -> the input gets focused -> shepherd does a redraw -> the focus of input gets lost -> input disappear)

  5. amitPurohit01 commented on Aug 4, 2023

    @amitPurohit01

    hi , is there any update on this bug, i am not able to highlight input element, but for text area it works fine

  6. amitPurohit01 commented on Aug 4, 2023

    @amitPurohit01

    hi this is reply to my question , for me it was not working because i was trying to open them in mat-dialog but and i had to remove and it started working , thank you

  7. crudobaker commented on Sep 17, 2023

    @crudobaker

    Hey!

    I think the option of configuring the autofocus property on step declaration is the best choice, like @DaDom proposal.

    For the moment, what works for my case is set the focus with a timeout, to override the autofocus on the current step.

    In this example the PressEnterOnTarget advance on action listens the Enter event on the target element to continue the tour.

    export const PressEnterOnTarget = {
      configure: () => {
        const currentStep = Shepherd.activeTour?.getCurrentStep();
        const pressEnterListener = event => {
          if (event.key === 'Enter') {
            currentStep.getTour().next();
          }
        };
        currentStep.getTarget().addEventListener('keypress', pressEnterListener);
    
        // it adds the focus on the target element
        setTimeout(() => currentStep.getTarget().focus(), 500);
    
        return () => currentStep.getTarget().removeEventListener('keypress', pressEnterListener);
      },
    };
    

    Hope it helps, and keep waiting for the improvement!

  8. JakeThurman commented on Mar 27, 2025

    @JakeThurman
    Contributor

    Running into some bugs because of the autofocus as well. I would love to see an option to disable it for a step.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions