Skip to content
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

Optional keyboard left/right arrow key navigation #53

Closed
blimpmason opened this issue Mar 25, 2020 · 14 comments
Closed

Optional keyboard left/right arrow key navigation #53

blimpmason opened this issue Mar 25, 2020 · 14 comments
Labels
feature request New feature or request not planned Won't be investigated unless it gets lots of traction

Comments

@blimpmason
Copy link

It would be great to be able to use the left/right arrow keys to navigate slides by default when the carousel is in focus.

@davidjerleke davidjerleke added the feature request New feature or request label Mar 26, 2020
@davidjerleke
Copy link
Owner

davidjerleke commented Mar 26, 2020

Hello David (@blimpmason),

Thank you for this feature request. I think this feature is quite possible to implement by utilising the Embla API and not necessary to build into the Embla core. Because Embla's vision is extensible bare bones carousels:

Extensible bare bone carousels for the web. Build awesome carousels by extending them with your own CSS and JavaScript.

With that said, I'd be happy to help you creating a CodeSandbox demonstrating how to achieve this with the API methods scrollPrev and scrollNext.

In order to help you though, I need to know when you would consider the carousel to be in focus?

Best
David

@davidjerleke davidjerleke added the not planned Won't be investigated unless it gets lots of traction label Mar 26, 2020
@davidjerleke davidjerleke changed the title Feature request: optional keyboard left/right arrow key navigation Optional keyboard left/right arrow key navigation Mar 26, 2020
@blimpmason
Copy link
Author

Thanks for the quick response! I was able to implement my own event listeners. I just thought it could be considered since I personally like even my barebones tools to have as much accessibility optimization legwork done as possible.

@davidjerleke
Copy link
Owner

davidjerleke commented Mar 27, 2020

Thank you for your input David (@blimpmason) 👍.

I agree with you that accessibility is important and I think this relates to issue #6 in a way. If we were to consider adding accessibility features to the Embla Core, it raises a lot of questions like how much accessibility should Embla be responsible for? Also, some users don't care much about it and would argue that this adds to the bundle size and should be up to every user to implement.

Kindly,
David

@ruijadom
Copy link

Hello! I'm interested in the same feature! I would like to be able to navigate using the left and right key on the keyboard. There are examples?

@davidjerleke
Copy link
Owner

davidjerleke commented Nov 28, 2020

Hi Rui (@ruijadom),

Lately, I’ve been considering adding accessibility to the Embla core. But at the time of writing, it’s an ongoing conversation about what should be included or not (issue #6), so in other words it’s in a very early stage.

Maybe @blimpmason can share his solution?

Best,
David

@ruijadom
Copy link

ruijadom commented Nov 28, 2020

@davidjerleke already got through the methods scrollNext () and scrollPrev () and hook for keypress! thanks! thanks for this wonderfull lib

@davidjerleke
Copy link
Owner

I'm happy to hear that Rui (@ruijadom). If you don't mind, feel free to share how you solved it here. It may help other users to implement this.

Kindly,
David

@mister-cairns
Copy link

mister-cairns commented Jul 30, 2021

I managed to get it working using the below:

document.onkeydown = checkKey;

function checkKey(e) {
    
  e = e || window.event;
    
  if (e.keyCode == '37') {
    embla.scrollPrev();
  }
  else if (e.keyCode == '39') {
   embla.scrollNext();
  }
    
}

@davidjerleke
Copy link
Owner

Hello Mike (@mister-cairns),

Thank you for sharing your code snippet. I would probably add more logic to the snippet. For example, you probably want the arrow keys to scroll the carousel only when it's in view, or if it has focus.

One additional detail:
The event.keyCode property is deprecated so I would probably change it to the event.code property.

Thank you.
David

@mister-cairns
Copy link

mister-cairns commented Aug 3, 2021

@davidjerleke thanks for your feedback. I've updated the snippet to use event.code but in my instance, there is only the slider on the page so in view and focus isn't needed. I'm a novice at javascript so if you could indicate how I would add those features to the below code that would be helpful.

window.addEventListener("keydown", function(event) {
      if (event.defaultPrevented) {
        return;
      }
    
      switch(event.code) {
        case "ArrowLeft":
          mainCarousel.scrollPrev();
          break;
        case "ArrowRight":
          mainCarousel.scrollNext();
          break;
      }
    
      event.preventDefault();
}, true);

@davidjerleke
Copy link
Owner

davidjerleke commented Aug 9, 2021

Hello Mike (@mister-cairns),

This is one way to do it:

HTML
This solution is based on the assumption that your markup is setup like below. Please note the tabindex property on the <div> element with the embla__viewport class name. This enables focusing on the <div> element. If this isn't specified you won't be able to focus on it. This is because only interactive elements like anchor tags, buttons and inputs are focusable in a browser by default.

<div class="embla">
  <div class="embla__viewport" tabindex="0">
    <div class="embla__container">
       <!-- Slides go here -->
    </div>
  </div>
</div>

JS
We can create functions that we can re-use to enable keyboard navigation for all carousels on a page:

// Focusing on a`<div>` element with the `tabindex` property will only work when you use the tab key and navigate to it.
// We can add a click handler that triggers focus on our carousel whenever a user clicks on it, which will be there for convenience.

const setupClickEventsForCarousels = (carousels) => {
  carousels.forEach((carousel) => {
    const rootNode = carousel.rootNode();
    rootNode.addEventListener("click", rootNode.focus);
  });
};

const setupKeyEventsForCarousels = (carousels) => {
  document.addEventListener("keyup", (event) => {
    const focusedCarousel = carousels.find((carousel) => document.activeElement === carousel.rootNode());
    if (!focusedCarousel) return;

    switch (event.code) {
      case "ArrowLeft":
        focusedCarousel.scrollPrev();
        break;
      case "ArrowRight":
        focusedCarousel.scrollNext();
        break;
    }
  });
};

const options = { skipSnaps: false }; // Carousel options
const carouselNodes = [].slice.call(document.querySelectorAll(".embla__viewport")); // Grab all carousel elements and store them in this array
const carousels = carouselNodes.map((carouselNode) => EmblaCarousel(carouselNode, options)); // Initialize all carousels and store the instances in this array

setupClickEventsForCarousels(carousels);
setupKeyEventsForCarousels(carousels);

I hope this helps.

Cheers,
David

@davidjerleke
Copy link
Owner

For anyone interested:

As of v.6 it’s possible to provide plugins to Embla. That means that you can build a plugin called embla-carousel-keyboard-nav or similar if you like.

@RichardSPrins
Copy link

To add to this discussion, it would be remiss for the maintainers to ignore the a11y needs of users and I would argue that it should absolutely be baked into the core package.

@davidjerleke
Copy link
Owner

davidjerleke commented Mar 17, 2023

Hi @RichardSPrins,

Thanks for joining the discussion. Although I don’t doubt that you mean well, I don’t think that just saying yes or no - it should be included in the core package or not is adding anything to the discussion.

Please read my response here and feel free to join the discussion if you have anything to add.

Additionally, I’m the sole maintainer of this project so I have an insanely big to do for this library (everything from documentation, the library core and all its related plugins and packages) which is why stuff is moving very slow.

Best,
David

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request New feature or request not planned Won't be investigated unless it gets lots of traction
Projects
None yet
Development

No branches or pull requests

5 participants