vue.js 如何允许标签聚焦在带有可见标签的隐藏复选框上

wz3gfoph  于 2023-08-07  发布在  Vue.js
关注(0)|答案(1)|浏览(119)

我有这个组件,是生产一个药丸检查组。我通过隐藏复选框本身来实现它,但将标签显示为具有选中和未选中状态的格式良好的框。下面是组件InputCheckGroupPill.vue

<div class="grid grid-cols-3 sm:grid-cols-4">
            <div v-for="(option, index) in options" :key="option[valueAttribute]">

                <div class="text-sm ">
                    <input :id="'check-option-' + option[valueAttribute] + index"
                           :aria-describedby="'check-label-' + option[valueAttribute] + index"
                           :aria-activedescendant="'check-label-' + option[valueAttribute] + index"
                           :aria-labelledby="'check-label-' + option[valueAttribute] + index"
                           :value="option[valueAttribute]"
                           v-model="selectedOptions"
                           class="hidden"
                           type="checkbox"/>
                    <label :id="'check-label-' + option[valueAttribute] + index"
                           :for="'check-option-' + option[valueAttribute] + index"
                           :class="[ selectedOptions.includes(option[valueAttribute]) ? 'bg-primary-600 text-white hover:bg-primary-500 border border-r-1 border-gray-100' : 'ring-1 ring-inset ring-gray-300 bg-white text-gray-900 hover:bg-gray-50', index === 0 ? 'rounded-l-md': '', index === options.length-1 ? 'rounded-r-md': '', 'flex items-center justify-center  py-3 px-3 text-sm font-semibold uppercase sm:flex-1 focus-visible:ring-2 focus-visible:ring-primary-600 focus-visible:ring-offset-2 cursor-pointer']">
                        {{option[labelAttribute]}}
                    </label>

                </div>
            </div>
        </div>

字符串
这里是生成的可见组件


的数据
问题是当我使用tab键导航时,复选框被跳过,就像它们不在那里一样。
我已经用尽了所有可能的ARIA描述符从MDN无济于事,你怎么能帮助?
注意:当我使用鼠标时,该组件工作得很好,但我希望它能与键盘一起工作。
我正在使用VueJs和Tailwind CSS进行样式化

hivapdat

hivapdat1#

不要使用display: none隐藏复选框,而是使用sr-only在视觉上隐藏元素,但屏幕阅读器等仍然可以访问它。这也意味着我们可以在聚焦时使用peer样式,如:

<input … class="… peer"/>
<label … class="… peer-focus-visible:ring-2 peer-focus-visible:ring-primary-600 peer-focus-visible:ring-offset-2"/>

字符串

Vue.createApp({
  data() {
    return {
      selectedOptions: [],
      options: {
        foo: {
          valueAttribute: 'foo',
          labelAttribute: 'Foo',
        },
        bar: {
          valueAttribute: 'bar',
          labelAttribute: 'Bar',
        },
      },
    };
  },
}).mount('#app');

tailwind.config = {
  theme: {
    extend: {
      colors: {
        primary: tailwind.colors.blue,
      }
    }
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.3.4/vue.global.prod.min.js" integrity="sha512-39BSQXI5q1XlvVhLfFRidKG8KM6Tr6VS/XSnNo6N/A0ZXexHCeoUI/s+ulujQy3UREjoLNrMnFat8VI0mMugWA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdn.tailwindcss.com/3.3.2"></script>

<div id="app">
  <div class="grid grid-cols-3 sm:grid-cols-4">
    <div v-for="(option, index) in options" :key="option.valueAttribute">

      <div class="text-sm ">
        <input
          :id="'check-option-' + option.valueAttribute + index"
          :aria-describedby="'check-label-' + option.valueAttribute + index"
          :aria-activedescendant="'check-label-' + option.valueAttribute + index"
          :aria-labelledby="'check-label-' + option.valueAttribute + index"
          :value="option.valueAttribute"
          v-model="selectedOptions"
          class="sr-only peer"
          type="checkbox"
        />
        <label
          :id="'check-label-' + option.valueAttribute + index"
          :for="'check-option-' + option.valueAttribute + index"
          :class="[
            selectedOptions.includes(option.valueAttribute)
              ? 'bg-primary-600 text-white hover:bg-primary-500 border border-r-1 border-gray-100'
              : 'ring-1 ring-inset ring-gray-300 bg-white text-gray-900 hover:bg-gray-50',
            index === 0
              ? 'rounded-l-md'
              : '',
            index === options.length-1 ?
              'rounded-r-md'
              : '',
            'flex items-center justify-center py-3 px-3 text-sm font-semibold uppercase sm:flex-1 peer-focus-visible:ring-2 peer-focus-visible:ring-primary-600 peer-focus-visible:ring-offset-2 cursor-pointer'
            ]"
        >
          {{ option.labelAttribute }}
        </label>
      </div>
    </div>
  </div>
</div>

的数据

相关问题