carbon-design-system / carbon-components-vue

Vue implementation of the Carbon Design System
http://vue.carbondesignsystem.com
Apache License 2.0
600 stars 178 forks source link

[Bug] Clickable Cv-tile doesn't properly raise keyboard enter/space events. #980

Open jungleBadger opened 3 years ago

jungleBadger commented 3 years ago

Detailed description

Describe in detail the issue you're having.

I can't use the aria-pressed events on cv-tiles clickable components.

  1. If I click the component beforehand, then the spacebar will toggle the select.
  2. I tried to attach keyup/keypress events directly to the cv-tile component

Is this a feature request (new component, new icon), a bug, or a general issue?

Bug

Is this issue related to a specific component?

<cv-tile>

What did you expect to happen? What happened instead? What would you like to see changed?

When I have a set of <cv-tiles> laid out as a form field option I can't use then completely through the keyboard. If I click in the tile, then space/enter events will work, but if I reach the tile through the tab key, this won't work.

What browser are you working in?

Chrome Version 84.0.4147.105 (Official Build) (64-bit)

What version of the Carbon Design System are you using?

"@carbon/vue": "^2.30.1",

Steps to reproduce the issue

  1. Create a basic div grouping two or more cv tiles
  2. Reach the tile without using the mouse, only the keyboard.
  3. Pressing space/enter won't trigger the change event

Additional information

I was able to work around this by wrapping up the element into a div block and attaching the keyup listeners on that div instead.

<template>
    <div
    v-for="(option, index) in options"
    @keyup.enter.space="applyOption(option.id, selectedOption !== option.id)"
        :key="mood.id"
        :aria-pressed="selectedOption === 'option.id'"
        role="button">
    <cv-tile
        @change="applyOption(option.id, $event)"
        :selected="selectedOption === option.id"
        :value="option.id"
        kind="selectable"
        :aria-label="`${option.id} option`">
        <div>
                    <h5>{{option.title}}</h5>
        </div>
    </cv-tile>
   </div>
</template>
<script>
"use strict";
export default {
    "name": "SurveySample",
    "data": function () {
          "options": [{"id": "x", "title": "x"}, {"id": "y", "title": "y"}, {"id": "w", "title": "w"}],
          "selectedOption": ""
    },
    "methods": {
         applyMoodOption(option, state) {
         this.selectedOption = state ? option : "";
     }
     }
};
</script>

If wrapping up the cv-tile into a div and declaring the aria attributes there as demonstrated above is a valid solution on your perspective, I can prepare the PR.

github-actions[bot] commented 3 weeks ago

This issue has been marked as stale because it has required additional info or a response from the author for over 14 days. When you get the chance, please comment with the additional info requested. Otherwise, this issue will be closed in 14 days.