Skip to content

Add keydown listener to backdrop to enable static offcanvas to close on Esc #37968

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

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

Ronid1
Copy link
Contributor

@Ronid1 Ronid1 commented Jan 28, 2023

Description

Added keydown event listener to backdrop.
Updated static offcanvas to close on esc when data-bs-keyboard = true, which is also the current default setting for this attribute.
If data-bs-keyboard = false the offcanvas will not close on any esc press.

Motivation & Context

This is a bug fix and provides offcanvas with similar behavior on esc keydown to modal, esc pressed on either static offcanvas or its backdrop will close it.

Type of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Refactoring (non-breaking change)
  • Breaking change (fix or feature that would change existing functionality)

Checklist

  • I have read the contributing guidelines
  • My code follows the code style of the project (using npm run lint)
  • My change introduces changes to the documentation
  • I have updated the documentation accordingly
  • I have added tests to cover my changes
  • All new and existing tests passed

Live previews

Change can be verified using this code snippet (showcases all scenarios):

<!--Static offcanvs with data-bs-keyboard=true closes on esc-->
    <button class="btn btn-primary" type="button" data-bs-toggle="offcanvas" data-bs-target="#staticBackdrop"
        aria-controls="staticBackdrop">
        static offcanvas closes on esc
    </button>
    <div class="offcanvas offcanvas-start" data-bs-backdrop="static" data-bs-keyboard="true" tabindex="-1"
        id="staticBackdrop" aria-labelledby="staticBackdropLabel">
        <div class="offcanvas-header">
            <h5 class="offcanvas-title" id="staticBackdropLabel">Offcanvas</h5>
            <button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
        </div>
        <div class="offcanvas-body">
            <div>
                I will not close if you click outside of me, but will close on esc
            </div>
        </div>
    </div>

    <!--Static offcanvs with data-bs-keyboard=false attribute dosen't close on esc-->
    <button class="btn btn-primary" type="button" data-bs-toggle="offcanvas" data-bs-keyboard="false"
        data-bs-target="#staticBackdropNoKeyboard" aria-controls="staticBackdrop">
        static offcanvas closes on esc
    </button>
    <div class="offcanvas offcanvas-start" data-bs-backdrop="static" tabindex="-1" id="staticBackdropNoKeyboard"
        aria-labelledby="staticBackdropLabel">
        <div class="offcanvas-header">
            <h5 class="offcanvas-title" id="staticBackdropLabel">Offcanvas</h5>
            <button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
        </div>
        <div class="offcanvas-body">
            <div>I will not close if you click on press esc outside of me.</div>
        </div>
    </div>

    <!--Non-static offcanvs behavior not changed-->
    <button class="btn btn-primary" type="button" data-bs-toggle="offcanvas" data-bs-target="#nonStaticBackdrop"
        aria-controls="staticBackdrop">
        non-static offcanvas
    </button>
    <div class="offcanvas offcanvas-start" tabindex="-1" id="nonStaticBackdrop" aria-labelledby="staticBackdropLabel">
        <div class="offcanvas-header">
            <h5 class="offcanvas-title" id="staticBackdropLabel">Offcanvas</h5>
            <button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
        </div>
        <div class="offcanvas-body">
            <div>I will close if you click outside of me.</div>
        </div>
    </div>

Related issues

Closes #37155

@Ronid1 Ronid1 requested a review from a team as a code owner January 28, 2023 17:46
@@ -138,6 +142,12 @@ class Backdrop extends Config {
execute(this._config.clickCallback)
})

if (this._config.keydownCallback) {
EventHandler.on(element.parentElement, EVENT_KEYDOWN, event => {
Copy link
Member

Choose a reason for hiding this comment

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

Can you explain me, why you set the listener over the parent element?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can you explain me, why you set the listener over the parent element?

The backdrop, being a part of another element, is always out of focus (e.g. the focus is on the modal/offcanvas element itself), and therefore a keydown event will not be triggered on it.
I double-checked my code and I agree that using the parent element isn't the best approach, since it doesn't work if the offcanvas is placed in another div.
According to the documentation only one offcanvas/ modal can be opened at once, and these are the only two elements using the backdrop so I think a safe solution is setting the event listener on the document element.

Copy link
Member

@GeoSot GeoSot Feb 8, 2023

Choose a reason for hiding this comment

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

this being said, I am not sure if we need to change something on offcanvas.

The initial point is to enable esc behavior in case of static backdrop. Another approach that seems fine too, is focusTrap to trap clicks too, in order not to let user get focus from the trapped element. Esc would work in that case too

/cc @patrickhlauke @julien-deramond

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The initial point is to enable esc behavior in case of static backdrop. Another approach that seems fine too, is focusTrap to trap clicks too, in order not to let user get focus from the trapped element. Esc would work in that case too

I've explored the second approach as well, and it is also a possibility. Personally, I think this should remain a backdrop functionality for now, since this discussion is about the wanted behavior of the backdrop and not of any element in focus. There might be a place in the future for extending the focustrap but I'm not sure it is currently needed.

Copy link
Member

Choose a reason for hiding this comment

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

@patrickhlauke @twbs/js-review your opinion would help here

@GeoSot
Copy link
Member

GeoSot commented Feb 3, 2023

Hey @Ronid1 . Thanks for the effort here.
I checked some things, but in the end you will need to add the proper tests too

@XhmikosR XhmikosR changed the title Add keydown listener to backdrop to enable static offcanvas to close on Esc Add keydown listener to backdrop to enable static offcanvas to close on Esc Feb 11, 2023
@Ronid1 Ronid1 force-pushed the ronid1/offcanvas_static_backdrop branch from 7e34f44 to 7ba6b39 Compare February 15, 2023 12:34
@Ronid1
Copy link
Contributor Author

Ronid1 commented Feb 15, 2023

@GeoSot I made changes according to your review and added tests. The pipeline is clear now.

@GeoSot GeoSot force-pushed the ronid1/offcanvas_static_backdrop branch from 7ba6b39 to 0f27ab9 Compare February 17, 2023 12:10
Copy link
Member

@louismaximepiton louismaximepiton left a comment

Choose a reason for hiding this comment

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

The changes look great to me !

I don't know if it is wanted since it's not the case for modals but clicking on the static backdrop sets the focus on the close button. It leads to a display of a box-shadow. Feels a bit weird using this but why not.

It could be tackled in another PR but my only question here is: Should we use this new functionality in the modals as well ? Because it seems like the backdrop escape event is handled differently in the 2 components.

@Ronid1 Ronid1 force-pushed the ronid1/offcanvas_static_backdrop branch from 0f27ab9 to 7e32458 Compare March 28, 2023 18:14
@Ronid1
Copy link
Contributor Author

Ronid1 commented Mar 28, 2023

Made changes requested by @louismaximepiton. Bundlewatch seems to be failing due to max size. Can you please help? @GeoSot

@GeoSot
Copy link
Member

GeoSot commented Mar 28, 2023

I have it in my mind, and I apologize for the delay. Team, at this point, has as priority the major css changes.
So I have postponed it, in order to discuss it later. And of course, we will handle the bundlewatch then 😄

Many many thanks for your patience

GeoSot
GeoSot previously approved these changes Mar 28, 2023
@GeoSot GeoSot self-requested a review March 28, 2023 23:02
@GeoSot GeoSot dismissed their stale review March 29, 2023 07:57

I was made by accident

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.

Offcanvas with static backdrop doesn't close on Esc if you click on the backdrop
5 participants