Skip to content

Commit

Permalink
fix: no focus after open new page (#330)
Browse files Browse the repository at this point in the history
* fix: no focus after open new page

* feat: focus menu button on back

* fix(ts): tabindex in menuItems

* fix: use nextTick to prevent to fast focusing

* fix(ts): solve TS18047 and TS2464 errors

* fix(ts): solve TS7053 error
  • Loading branch information
pspaczek authored Jan 15, 2024
1 parent 75a85b4 commit f01a871
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 2 deletions.
26 changes: 26 additions & 0 deletions src/components/organisms/UiHorizontalPaging/UiHorizontalPaging.vue
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
v-bind="{ items: menuItems }"
>
<UiMenu
ref="menu"
:items="menuItems"
class="ui-horizontal-paging__menu"
/>
Expand Down Expand Up @@ -96,10 +97,13 @@ import {
computed,
provide,
inject,
watch,
type ComputedRef,
type WritableComputedRef,
type Ref,
nextTick,
} from 'vue';
import { focusElement } from '../../../utilities/helpers';
import type {
Icon,
DefineAttrsProps,
Expand Down Expand Up @@ -226,9 +230,31 @@ const menuItems = computed<MenuItemAttrsProps[]>(() => itemsAsArray.value.map((i
item,
];
},
...(isActive.value ? { tabindex: '-1' } : {}),
...rest,
};
}));
const menu = ref<InstanceType<typeof UiMenu> | null>(null);
const menuButtons = computed < Record<string, any>>(() => {
if (!menu.value) return {};
return itemsAsArray.value.reduce((elements, { name }, order) => {
if (!name
|| !menu.value
|| !menu.value.menuItems) {
return elements;
}
return {
...elements,
[name]: menu.value.menuItems[order].$el.querySelector('button'),
};
}, {});
});
watch(activeItemName, async (moveTo, backFrom) => {
if (backFrom) {
await nextTick();
focusElement(menuButtons.value[backFrom]);
}
});
</script>

<style lang="scss">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
<template>
<span
ref="el"
class="visual-hidden"
:tabindex="tabindex"
@blur="handleA11YHelperBlur"
/>
<slot v-if="isActive" />
</template>

<script setup lang="ts">
import {
computed,
watch,
ref,
inject,
onBeforeUnmount,
type Ref,
type ComputedRef,
nextTick,
} from 'vue';
import type { HorizontalPangingHandleItems } from '../UiHorizontalPaging.vue';
import { focusElement } from '../../../../utilities/helpers';
export interface HorizontalPangingItemProps {
/**
Expand All @@ -35,6 +44,17 @@ const props = withDefaults(defineProps<HorizontalPangingItemProps>(), {
});
const activeItemName = inject<ComputedRef<string>>('activeItemName', computed(() => ''));
const isActive = computed(() => activeItemName.value === props.name);
const el = ref<HTMLSpanElement | null>(null);
const tabindex = ref(0);
watch(isActive, async (value) => {
tabindex.value = 0;
if (!value) return;
await nextTick();
focusElement(el.value);
});
const handleA11YHelperBlur = () => {
tabindex.value = -1;
};
const item = computed(() => ({
label: props.label,
title: props.title,
Expand Down
8 changes: 7 additions & 1 deletion src/components/organisms/UiMenu/UiMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
:key="key"
>
<UiMenuItem
ref="menuItems"
v-bind="menuItemAttrs(item)"
>
<template
Expand All @@ -32,7 +33,10 @@
</template>

<script setup lang="ts">
import { computed } from 'vue';
import {
ref,
computed,
} from 'vue';
import UiList from '../UiList/UiList.vue';
import type { ListAttrsProps } from '../UiList/UiList.vue';
import UiMenuItem from './_internal/UiMenuItem.vue';
Expand All @@ -52,6 +56,8 @@ export interface MenuProps {
export type MenuAttrsProps = DefineAttrsProps<MenuProps, ListAttrsProps>;
const props = withDefaults(defineProps<MenuProps>(), { items: () => ([]) });
const menuItems = ref<InstanceType<typeof UiMenuItem>[] | null>(null);
defineExpose({ menuItems });
const menuItemAttrs = ({
/* eslint-disable-next-line @typescript-eslint/no-unused-vars */
name, label, ...itemAttrs
Expand Down
2 changes: 1 addition & 1 deletion src/utilities/helpers/focus-element/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-disable import/prefer-default-export */
export const focusElement = (el: HTMLElement, focusVisible = false): Promise<void> => {
export const focusElement = (el: HTMLElement | null, focusVisible = false): Promise<void> => {
if (el) {
if (focusVisible) {
document.body.classList.remove('focus-hidden');
Expand Down

0 comments on commit f01a871

Please sign in to comment.