From 2f2591a4833e8bb923eef4c83c441dbe3a73a499 Mon Sep 17 00:00:00 2001 From: Alexandre Alves Date: Thu, 16 Jan 2025 18:06:03 +0000 Subject: [PATCH] fix key nav on charts page in cluster --- shell/assets/styles/global/_button.scss | 5 ++ shell/assets/styles/vendor/vue-select.scss | 1 + shell/assets/translations/en-us.yaml | 8 ++- shell/components/ButtonGroup.vue | 2 + shell/components/Carousel.vue | 65 +++++++++++--------- shell/components/SelectIconGrid.vue | 13 +++- shell/components/form/Select.vue | 36 +++++++++-- shell/mixins/vue-select-overrides.js | 26 +++----- shell/pages/c/_cluster/apps/charts/index.vue | 4 ++ 9 files changed, 108 insertions(+), 52 deletions(-) diff --git a/shell/assets/styles/global/_button.scss b/shell/assets/styles/global/_button.scss index fd8528a2731..03692e64851 100644 --- a/shell/assets/styles/global/_button.scss +++ b/shell/assets/styles/global/_button.scss @@ -185,6 +185,11 @@ fieldset[disabled] .btn { z-index: 1; } + &:focus-visible { + z-index: 1; + @include focus-outline; + } + &.active { @extend .bg-primary; } diff --git a/shell/assets/styles/vendor/vue-select.scss b/shell/assets/styles/vendor/vue-select.scss index 4dc95331e7c..c40e5e4766e 100644 --- a/shell/assets/styles/vendor/vue-select.scss +++ b/shell/assets/styles/vendor/vue-select.scss @@ -74,6 +74,7 @@ color: var(--dropdown-text); white-space: nowrap; z-index: 1000; + overflow: auto; &:hover { cursor: pointer; diff --git a/shell/assets/translations/en-us.yaml b/shell/assets/translations/en-us.yaml index bc4f0cf6a7b..63abd746dbe 100644 --- a/shell/assets/translations/en-us.yaml +++ b/shell/assets/translations/en-us.yaml @@ -931,6 +931,7 @@ catalog: experimentalWarning: '{chartName} has been marked as experimental. Use caution when installing this helm chart as it might not function as expected.' deprecatedAndExperimentalWarning: '{chartName} has been marked as deprecated and experimental. Use caution when installing this helm chart as it might be removed in the future and might not function as expected.' charts: + refresh: refresh charts all: All categories: all: All Categories @@ -950,7 +951,7 @@ catalog: all: All Operating Systems linux: Linux windows: Windows - search: Filter + search: Filter charts results deprecatedChartsFilter: label: Show deprecated apps install: @@ -6129,6 +6130,11 @@ validation: interval: '"{key}" must be of a format with digits followed by a unit i.e. 1h, 2m, 30s' tab: "One or more fields in this tab contain a form validation error" +carousel: + previous: Previous + next: Next + controlItem: Go to slide nÂș {number} + wizard: previous: Previous finish: Finish diff --git a/shell/components/ButtonGroup.vue b/shell/components/ButtonGroup.vue index 0408c97fc16..f2c86238cfa 100644 --- a/shell/components/ButtonGroup.vue +++ b/shell/components/ButtonGroup.vue @@ -82,6 +82,8 @@ export default { type="button" :class="opt.class" :disabled="disabled || opt.disabled" + role="button" + :aria-label="opt.labelKey ? t(opt.labelKey) : opt.label" @click="change(opt.value)" > -
-
-
+
- +
@@ -240,20 +258,6 @@ export default { &.disable::after { display: none; } - - &.disable:hover { - .prev, - .next { - display: none; - } - } - - &:hover { - .prev, - .next { - display: block; - } - } } .slide-track { @@ -367,13 +371,16 @@ export default { position: absolute; z-index: 20; top: 90px; - display: none; cursor: pointer; &.disabled .icon { color: var(--disabled-bg); cursor: not-allowed; } + + .icon:focus-visible { + @include focus-outline; + } } .next { diff --git a/shell/components/SelectIconGrid.vue b/shell/components/SelectIconGrid.vue index ce270669932..85f15496507 100644 --- a/shell/components/SelectIconGrid.vue +++ b/shell/components/SelectIconGrid.vue @@ -104,6 +104,10 @@ export default { :is="asLink ? 'a' : 'div'" v-for="(r, idx) in rows" :key="get(r, keyField)" + :role="asLink ? 'link' : null" + :aria-disabled="asLink && get(r, disabledField) === true ? true : null" + :aria-label="get(r, nameField)" + :tabindex="get(r, disabledField) === true ? -1 : 0" :href="asLink ? get(r, linkField) : null" :target="get(r, targetField)" :rel="rel" @@ -111,9 +115,12 @@ export default { :data-testid="componentTestid + '-' + get(r, nameField)" :class="{ 'has-description': !!get(r, descriptionField), - 'has-side-label': !!get(r, sideLabelField), [colorFor(r, idx)]: true, disabled: get(r, disabledField) === true + 'has-side-label': !!get(r, sideLabelField), + [colorFor(r, idx)]: true, + disabled: get(r, disabledField) === true }" @click="select(r, idx)" + @keyup.enter.space="select(r, idx)" >
{ + const el = this.$refs['select']; + + if ( el ) { + el.focus(); + } + + this.overridesMixinPreventDoubleTriggerKeysOpen = false; + }); + + return; + } + this.$refs['select-input'].open = true; + this.$nextTick(() => { const el = this.$refs['select-input']?.searchEl; @@ -176,6 +189,11 @@ export default { }, report(e) { alert(e); + }, + handleDropdownOpen(args) { + // function that prevents the "opening dropdown on focus" + // default behaviour of v-select + return args.noDrop || args.disabled ? false : args.open; } }, computed: { @@ -236,7 +254,9 @@ export default { 'compact-input': compact, [$attrs.class]: $attrs.class }" - @focus="focusSearch" + :tabindex="disabled ? -1 : 0" + @click="focusSearch" + @keyup.enter.space.down="focusSearch" > { vm.open = false; vm.search = ''; + this.$refs.select.focus(); + return false; }); + // enter (out[13] = (e, opt) => { if (!vm.open) { vm.open = true; @@ -60,6 +51,9 @@ export default { vm.$emit('option:selected', option); if (vm.closeOnSelect) { + // this ties in to the Select component implementation + // so that the enter key handler doesn't open the dropdown again + this.overridesMixinPreventDoubleTriggerKeysOpen = true; vm.open = false; vm.typeAheadPointer = -1; } diff --git a/shell/pages/c/_cluster/apps/charts/index.vue b/shell/pages/c/_cluster/apps/charts/index.vue index 528a591cf3e..af5722521c2 100644 --- a/shell/pages/c/_cluster/apps/charts/index.vue +++ b/shell/pages/c/_cluster/apps/charts/index.vue @@ -455,6 +455,8 @@ export default { class="input-sm" :placeholder="t('catalog.charts.search')" data-testid="charts-filter-input" + :aria-label="t('catalog.charts.search')" + role="textbox" >