From cf1ed1b36fd0b176291079ecae7adbc76a796b1b Mon Sep 17 00:00:00 2001 From: "ala'n (Alexey Stsefanovich)" Date: Thu, 14 Nov 2024 23:31:17 +0100 Subject: [PATCH] style(esl-toggleable): fix focus behavior for chain focus flow --- src/modules/esl-popup/core/esl-popup.ts | 3 ++- .../core/esl-toggleable.shape.ts | 3 ++- .../esl-toggleable/core/esl-toggleable.ts | 19 ++++++++++--------- src/modules/esl-tooltip/core/esl-tooltip.ts | 1 + src/modules/esl-utils/dom/focus.ts | 4 ++-- 5 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/modules/esl-popup/core/esl-popup.ts b/src/modules/esl-popup/core/esl-popup.ts index 3af3471d7..48e1b131e 100644 --- a/src/modules/esl-popup/core/esl-popup.ts +++ b/src/modules/esl-popup/core/esl-popup.ts @@ -113,10 +113,11 @@ export class ESLPopup extends ESLToggleable { /** * Focus behavior. Available values: * - 'none' - no focus management + * - 'grab' - focus on the first focusable element * - 'chain' (default) - focus on the first focusable element first and return focus to the activator after the last focusable element * - 'loop' - focus on the first focusable element and loop through the focusable elements */ - @attr({defaultValue: 'none'}) + @attr({defaultValue: 'chain'}) public override focusBehavior: FocusFlowType; public $placeholder: ESLPopupPlaceholder | null; diff --git a/src/modules/esl-toggleable/core/esl-toggleable.shape.ts b/src/modules/esl-toggleable/core/esl-toggleable.shape.ts index 54dfe0ab2..967775fe8 100644 --- a/src/modules/esl-toggleable/core/esl-toggleable.shape.ts +++ b/src/modules/esl-toggleable/core/esl-toggleable.shape.ts @@ -22,10 +22,11 @@ export interface ESLToggleableTagShape /** * Define focus behavior * - 'none' - no focus management + * - 'grab' - focus on the first focusable element * - 'chain' - focus on the first focusable element first and return focus to the activator after the last focusable element * - 'loop' - focus on the first focusable element and loop through the focusable elements */ - 'focus-behaviour'?: 'none' | 'chain' | 'loop'; + 'focus-behavior'?: 'none' | 'chain' | 'loop'; /** Define Toggleable group meta information to organize groups */ 'group'?: string; diff --git a/src/modules/esl-toggleable/core/esl-toggleable.ts b/src/modules/esl-toggleable/core/esl-toggleable.ts index 558f771ee..d57db5b51 100644 --- a/src/modules/esl-toggleable/core/esl-toggleable.ts +++ b/src/modules/esl-toggleable/core/esl-toggleable.ts @@ -119,6 +119,7 @@ export class ESLToggleable extends ESLBaseElement { /** * Focus behavior. Available values: * - 'none' - no focus management + * - 'grab' - focus on the first focusable element * - 'chain' - focus on the first focusable element first and return focus to the activator after the last focusable element * - 'loop' - focus on the first focusable element and loop through the focusable elements */ @@ -284,7 +285,7 @@ export class ESLToggleable extends ESLBaseElement { /** * Actions to execute on show toggleable. * Inner state and 'open' attribute are not affected and updated before `onShow` execution. - * Adds CSS classes, update a11y and fire {@link ESLToggleable.REFRESH_EVENT} event by default. + * Adds CSS classes, update a11y and fire {@link ESLBaseElement.REFRESH_EVENT} event by default. */ protected onShow(params: ESLToggleableActionParams): void { this.open = true; @@ -417,15 +418,15 @@ export class ESLToggleable extends ESLBaseElement { @listen('focusout') protected _onFocusOut(e: FocusEvent): void { if (!this.open) return; - if (this.focusBehavior === 'chain') { - afterNextRender(() => { - if (this.hasFocus) return; + afterNextRender(() => { + if (this.hasFocus) return; + if (this.focusBehavior === 'chain') { this.hide({initiator: 'focusout', event: e}); - }); - } - if (this.focusBehavior === 'loop') { - this.focus({preventScroll: true}); - } + } + if (this.focusBehavior === 'loop') { + this.focus({preventScroll: true}); + } + }); } @listen({auto: false, event: 'mouseenter'}) diff --git a/src/modules/esl-tooltip/core/esl-tooltip.ts b/src/modules/esl-tooltip/core/esl-tooltip.ts index 2af19ab2e..25111e4cc 100644 --- a/src/modules/esl-tooltip/core/esl-tooltip.ts +++ b/src/modules/esl-tooltip/core/esl-tooltip.ts @@ -75,6 +75,7 @@ export class ESLTooltip extends ESLPopup { this.dir = params.dir || ''; this.lang = params.lang || ''; this.parentNode !== document.body && document.body.appendChild(this); + super.onShow(params); } diff --git a/src/modules/esl-utils/dom/focus.ts b/src/modules/esl-utils/dom/focus.ts index a47644c7f..58f39a839 100644 --- a/src/modules/esl-utils/dom/focus.ts +++ b/src/modules/esl-utils/dom/focus.ts @@ -34,8 +34,8 @@ export const handleFocusFlow = ( if (type === 'loop') return handleFocusChain(e, $first, $last); - if (type === 'chain' && $last && $fallback) { - if (e.target !== (e.shiftKey ? $first : $last)) return; + if (type === 'chain' && $fallback) { + if ($last && e.target !== (e.shiftKey ? $first : $last)) return; $fallback.focus(); e.preventDefault(); }