From 3bea2cd033361545601774a0221a08c1439a5128 Mon Sep 17 00:00:00 2001 From: Marien Fressinaud Date: Wed, 11 Oct 2023 12:01:42 +0200 Subject: [PATCH] dev: Provide a JS Switch controller --- assets/javascripts/application.js | 2 ++ .../controllers/modal_controller.js | 9 +------ .../controllers/switch_controller.js | 26 +++++++++++++++++++ assets/javascripts/query_selectors.js | 12 +++++++++ 4 files changed, 41 insertions(+), 8 deletions(-) create mode 100644 assets/javascripts/controllers/switch_controller.js create mode 100644 assets/javascripts/query_selectors.js diff --git a/assets/javascripts/application.js b/assets/javascripts/application.js index 840cfa3d..aba690f5 100644 --- a/assets/javascripts/application.js +++ b/assets/javascripts/application.js @@ -20,6 +20,7 @@ import NotificationsController from '@/controllers/notifications_controller.js'; import PasswordController from '@/controllers/password_controller.js'; import PopupController from '@/controllers/popup_controller.js'; import ScrollToController from '@/controllers/scroll_to_controller.js'; +import SwitchController from '@/controllers/switch_controller.js'; import TabsController from '@/controllers/tabs_controller.js'; import TinymceController from '@/controllers/tinymce_controller.js'; @@ -39,6 +40,7 @@ application.register('notifications', NotificationsController); application.register('password', PasswordController); application.register('popup', PopupController); application.register('scroll-to', ScrollToController); +application.register('switch', SwitchController); application.register('tabs', TabsController); application.register('tinymce', TinymceController); diff --git a/assets/javascripts/controllers/modal_controller.js b/assets/javascripts/controllers/modal_controller.js index 8aef4ff1..f676735b 100644 --- a/assets/javascripts/controllers/modal_controller.js +++ b/assets/javascripts/controllers/modal_controller.js @@ -5,14 +5,7 @@ import { Controller } from '@hotwired/stimulus'; -const FOCUSABLE_ELEMENTS = [ - 'a[href]:not([tabindex="-1"])', - 'button:not([disabled]):not([tabindex="-1"])', - 'input:not([disabled]):not([type="hidden"]):not([tabindex="-1"])', - 'select:not([disabled]):not([tabindex="-1"])', - 'textarea:not([disabled]):not([tabindex="-1"])', - '[tabindex]:not([tabindex="-1"])', -]; +import { FOCUSABLE_ELEMENTS } from '@/query_selectors.js'; // Credits to: // - JoliCode: https://jolicode.com/blog/une-fenetre-modale-accessible diff --git a/assets/javascripts/controllers/switch_controller.js b/assets/javascripts/controllers/switch_controller.js new file mode 100644 index 00000000..7f1d4481 --- /dev/null +++ b/assets/javascripts/controllers/switch_controller.js @@ -0,0 +1,26 @@ +// This file is part of Bileto. +// Copyright 2022-2023 Probesys +// SPDX-License-Identifier: AGPL-3.0-or-later + +import { Controller } from '@hotwired/stimulus'; + +import { FOCUSABLE_ELEMENTS } from '@/query_selectors.js'; + +export default class extends Controller { + static get targets () { + return ['panel']; + } + + change (event) { + this.panelTargets.forEach((panel) => { + panel.hidden = panel.id !== event.params.for; + + if (!panel.hidden) { + const focusableElements = Array.from(panel.querySelectorAll(FOCUSABLE_ELEMENTS)); + if (focusableElements.length > 0) { + focusableElements[0].focus(); + } + } + }); + } +} diff --git a/assets/javascripts/query_selectors.js b/assets/javascripts/query_selectors.js new file mode 100644 index 00000000..891b6e63 --- /dev/null +++ b/assets/javascripts/query_selectors.js @@ -0,0 +1,12 @@ +// This file is part of Bileto. +// Copyright 2022-2023 Probesys +// SPDX-License-Identifier: AGPL-3.0-or-later + +export const FOCUSABLE_ELEMENTS = [ + 'a[href]:not([tabindex="-1"])', + 'button:not([disabled]):not([tabindex="-1"])', + 'input:not([disabled]):not([type="hidden"]):not([tabindex="-1"])', + 'select:not([disabled]):not([tabindex="-1"])', + 'textarea:not([disabled]):not([tabindex="-1"])', + '[tabindex]:not([tabindex="-1"])', +];