mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 22:12:21 -04:00
Resolve a11y for tag options buttons (#2787)
* resolve TagAddButton a11y better comments to document tagindex reasoning * resolved a11y for TagsSelectedButton allow focus to TagsSelectedButton with Shift+Tab and Enter or Space to show popover * safely ignore a11y warning as container for interactables is not itself interactable * Update CONTRIBUTORS * quick fix syntax * quick fix syntax * quick fix syntax * quick fix syntax * resolved a11y in accordance with ARIA APG Disclure pattern * resolved a11y ideally should replace with with a11y-click-events-have-key-events is explicitly ignored as the alternative (adding ) seems more clunky * resolved SpinBox a11y cannot focus on these buttons, so no key event handling needed (keyboard editting already possible by just typing in the field) widget already properly follows ARIA APG Spinbutton pattern * cleanup * onEnterOrSpace() function implemented as discussed in #2787 and #2564 * quick syntax and such changes
This commit is contained in:
parent
9cd4f04677
commit
7bcb57b89e
8 changed files with 43 additions and 5 deletions
|
@ -148,6 +148,7 @@ user1823 <92206575+user1823@users.noreply.github.com>
|
||||||
Gustaf Carefall <https://github.com/Gustaf-C>
|
Gustaf Carefall <https://github.com/Gustaf-C>
|
||||||
virinci <github.com/virinci>
|
virinci <github.com/virinci>
|
||||||
snowtimeglass <snowtimeglass@gmail.com>
|
snowtimeglass <snowtimeglass@gmail.com>
|
||||||
|
Ben Olson <github.com/grepgrok>
|
||||||
|
|
||||||
********************
|
********************
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import * as tr from "@tslib/ftl";
|
import * as tr from "@tslib/ftl";
|
||||||
|
import { onEnterOrSpace } from "@tslib/keys";
|
||||||
import { slide } from "svelte/transition";
|
import { slide } from "svelte/transition";
|
||||||
|
|
||||||
import Badge from "../components/Badge.svelte";
|
import Badge from "../components/Badge.svelte";
|
||||||
|
@ -29,7 +30,14 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
|
||||||
<div class="alert alert-warning" in:slide out:slide>
|
<div class="alert alert-warning" in:slide out:slide>
|
||||||
{#if unused.length > maxItems}
|
{#if unused.length > maxItems}
|
||||||
<div class="clickable" on:click={() => (collapsed = !collapsed)}>
|
<div
|
||||||
|
class="clickable"
|
||||||
|
on:click={() => (collapsed = !collapsed)}
|
||||||
|
on:keydown={onEnterOrSpace(() => (collapsed = !collapsed))}
|
||||||
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
|
aria-expanded={!collapsed}
|
||||||
|
>
|
||||||
<Badge iconSize={80}>
|
<Badge iconSize={80}>
|
||||||
{@html icon}
|
{@html icon}
|
||||||
</Badge>
|
</Badge>
|
||||||
|
|
|
@ -96,11 +96,13 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
on:focusout={() => (focused = false)}
|
on:focusout={() => (focused = false)}
|
||||||
/>
|
/>
|
||||||
{#if isDesktop()}
|
{#if isDesktop()}
|
||||||
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||||
<div
|
<div
|
||||||
class="spinner decrement"
|
class="spinner decrement"
|
||||||
class:active={value > min}
|
class:active={value > min}
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
title={tr.actionsDecrementValue()}
|
title={tr.actionsDecrementValue()}
|
||||||
|
role="button"
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
input.focus();
|
input.focus();
|
||||||
if (value > min) {
|
if (value > min) {
|
||||||
|
@ -122,11 +124,13 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
{@html chevronDown}
|
{@html chevronDown}
|
||||||
</IconConstrain>
|
</IconConstrain>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||||
<div
|
<div
|
||||||
class="spinner increment"
|
class="spinner increment"
|
||||||
class:active={value < max}
|
class:active={value < max}
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
title={tr.actionsIncrementValue()}
|
title={tr.actionsIncrementValue()}
|
||||||
|
role="button"
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
input.focus();
|
input.focus();
|
||||||
if (value < max) {
|
if (value < max) {
|
||||||
|
|
|
@ -120,3 +120,14 @@ export function isArrowDown(event: KeyboardEvent): boolean {
|
||||||
|
|
||||||
return isApplePlatform() && metaPressed(event) && event.code === "KeyN";
|
return isApplePlatform() && metaPressed(event) && event.code === "KeyN";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function onEnterOrSpace(callback: () => void): (event: KeyboardEvent) => void {
|
||||||
|
return (event: KeyboardEvent) => {
|
||||||
|
switch (event.code) {
|
||||||
|
case "Enter":
|
||||||
|
case "Space":
|
||||||
|
callback();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -2,7 +2,9 @@
|
||||||
Copyright: Ankitects Pty Ltd and contributors
|
Copyright: Ankitects Pty Ltd and contributors
|
||||||
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
-->
|
-->
|
||||||
<div class="tag-spacer" on:click>
|
<!-- on:click allows clicking focus to the tag editor -->
|
||||||
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||||
|
<div class="tag-spacer" on:click role="textbox" tabindex="-1">
|
||||||
<br />
|
<br />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -21,10 +21,13 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- toggle tabindex to allow Shift+Tab to move focus to the last field -->
|
<!-- toggle tabindex to allow Tab to move focus to the tag editor from the last field -->
|
||||||
|
<!-- and allow Shift+Tab to move focus to the last field while inputting tag -->
|
||||||
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||||
<div
|
<div
|
||||||
class="tag-add-button"
|
class="tag-add-button"
|
||||||
title="{tr.editingTagsAdd()} ({getPlatformString(keyCombination)})"
|
title="{tr.editingTagsAdd()} ({getPlatformString(keyCombination)})"
|
||||||
|
role="button"
|
||||||
tabindex={$currentTagInput ? -1 : 0}
|
tabindex={$currentTagInput ? -1 : 0}
|
||||||
on:click={appendTag}
|
on:click={appendTag}
|
||||||
on:focus={appendTag}
|
on:focus={appendTag}
|
||||||
|
|
|
@ -11,6 +11,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
export let keyCombination: string;
|
export let keyCombination: string;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||||
<div
|
<div
|
||||||
class="tag-options-button gap"
|
class="tag-options-button gap"
|
||||||
bind:offsetHeight={badgeHeight}
|
bind:offsetHeight={badgeHeight}
|
||||||
|
|
|
@ -13,6 +13,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
import * as tr from "@tslib/ftl";
|
import * as tr from "@tslib/ftl";
|
||||||
import { getPlatformString } from "@tslib/shortcuts";
|
import { getPlatformString } from "@tslib/shortcuts";
|
||||||
import { dotsIcon } from "./icons";
|
import { dotsIcon } from "./icons";
|
||||||
|
import { onEnterOrSpace } from "@tslib/keys";
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
|
@ -29,7 +30,14 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
shift={0}
|
shift={0}
|
||||||
let:asReference
|
let:asReference
|
||||||
>
|
>
|
||||||
<div class="tags-selected-button" use:asReference on:click={() => (show = !show)}>
|
<div
|
||||||
|
class="tags-selected-button"
|
||||||
|
use:asReference
|
||||||
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
|
on:click={() => (show = !show)}
|
||||||
|
on:keydown={onEnterOrSpace(() => (show = !show))}
|
||||||
|
>
|
||||||
<IconConstrain>{@html dotsIcon}</IconConstrain>
|
<IconConstrain>{@html dotsIcon}</IconConstrain>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -50,8 +58,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.tags-selected-button {
|
.tags-selected-button {
|
||||||
|
line-height: 1;
|
||||||
:global(svg) {
|
:global(svg) {
|
||||||
padding-bottom: 2px;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
fill: currentColor;
|
fill: currentColor;
|
||||||
opacity: 0.6;
|
opacity: 0.6;
|
||||||
|
|
Loading…
Reference in a new issue