From ee65a5693c2fd2b6b0d58e13185c4a76acd4dff6 Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Thu, 16 Apr 2026 12:41:42 +0300 Subject: [PATCH] improve accessibility --- app/javascript/elements/download_button.js | 6 + app/javascript/elements/modal_button.js | 18 +++ app/javascript/elements/scroll_buttons.js | 2 + app/javascript/form.js | 2 + app/javascript/submission_form/area.vue | 17 ++- .../submission_form/attachment_step.vue | 12 +- app/javascript/submission_form/completed.vue | 7 +- app/javascript/submission_form/date_step.vue | 4 +- app/javascript/submission_form/dropzone.vue | 3 +- app/javascript/submission_form/form.vue | 36 ++++-- app/javascript/submission_form/i18n.js | 71 ++++++++++++ app/javascript/submission_form/image_step.vue | 3 +- .../submission_form/initials_step.vue | 56 +++++----- .../submission_form/multi_select_step.vue | 2 + .../submission_form/number_step.vue | 2 + app/javascript/submission_form/phone_step.vue | 18 +-- .../submission_form/signature_step.vue | 103 ++++++++++++------ app/javascript/submission_form/text_step.vue | 14 ++- .../submission_form/verification_step.vue | 1 + app/views/icons/_circle_check.html.erb | 2 +- app/views/icons/_download.html.erb | 2 +- app/views/icons/_info_circle.html.erb | 2 +- app/views/icons/_loader.html.erb | 2 +- app/views/icons/_mail_forward.html.erb | 2 +- app/views/icons/_reload.html.erb | 2 +- app/views/icons/_user_share.html.erb | 2 +- app/views/icons/_writing_sign.html.erb | 2 +- app/views/icons/_x.html.erb | 2 +- app/views/shared/_html_modal.html.erb | 16 ++- app/views/start_form/completed.html.erb | 4 +- .../start_form/email_verification.html.erb | 4 +- app/views/start_form/private.html.erb | 4 +- app/views/start_form/show.html.erb | 10 +- app/views/submissions/_value.html.erb | 4 +- app/views/submissions/show.html.erb | 28 ++--- app/views/submit_form/_decline_form.html.erb | 6 +- app/views/submit_form/completed.html.erb | 6 +- app/views/submit_form/email_2fa.html.erb | 8 +- app/views/submit_form/show.html.erb | 90 ++++++++------- config/locales/i18n.yml | 14 +++ 40 files changed, 408 insertions(+), 181 deletions(-) create mode 100644 app/javascript/elements/modal_button.js diff --git a/app/javascript/elements/download_button.js b/app/javascript/elements/download_button.js index 160fc770..2a4b6210 100644 --- a/app/javascript/elements/download_button.js +++ b/app/javascript/elements/download_button.js @@ -5,6 +5,12 @@ export default targetable(class extends HTMLElement { connectedCallback () { this.addEventListener('click', () => this.downloadFiles()) + this.addEventListener('keydown', (e) => { + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault() + this.downloadFiles() + } + }) } toggleState () { diff --git a/app/javascript/elements/modal_button.js b/app/javascript/elements/modal_button.js new file mode 100644 index 00000000..0dbc75a8 --- /dev/null +++ b/app/javascript/elements/modal_button.js @@ -0,0 +1,18 @@ +export default class extends HTMLElement { + connectedCallback () { + const dialog = document.getElementById(this.dataset.target) + + this.querySelector('button').addEventListener('click', () => { + if (dialog) { + dialog.inert = false + dialog.showModal() + } + }) + + if (dialog) { + dialog.addEventListener('close', () => { + dialog.inert = true + }) + } + } +} diff --git a/app/javascript/elements/scroll_buttons.js b/app/javascript/elements/scroll_buttons.js index 6525adf9..09e4796e 100644 --- a/app/javascript/elements/scroll_buttons.js +++ b/app/javascript/elements/scroll_buttons.js @@ -47,11 +47,13 @@ export default class extends HTMLElement { this.classList.remove('hidden', '-translate-y-10', 'opacity-0') this.classList.add('translate-y-0', 'opacity-100') + this.querySelectorAll('[tabindex]').forEach((el) => { el.tabIndex = 0 }) } hideButtons () { this.classList.remove('translate-y-0', 'opacity-100') this.classList.add('-translate-y-10', 'opacity-0') + this.querySelectorAll('[tabindex]').forEach((el) => { el.tabIndex = -1 }) setTimeout(() => { if (this.classList.contains('-translate-y-10')) { diff --git a/app/javascript/form.js b/app/javascript/form.js index f8561dc0..c8d5790e 100644 --- a/app/javascript/form.js +++ b/app/javascript/form.js @@ -7,6 +7,7 @@ import FetchForm from './elements/fetch_form' import ScrollButtons from './elements/scroll_buttons' import PageContainer from './elements/page_container' import SubmitForm from './elements/submit_form' +import ModalButton from './elements/modal_button' const safeRegisterElement = (name, element, options = {}) => !window.customElements.get(name) && window.customElements.define(name, element, options) @@ -16,6 +17,7 @@ safeRegisterElement('fetch-form', FetchForm) safeRegisterElement('scroll-buttons', ScrollButtons) safeRegisterElement('page-container', PageContainer) safeRegisterElement('submit-form', SubmitForm) +safeRegisterElement('modal-button', ModalButton) safeRegisterElement('submission-form', class extends HTMLElement { connectedCallback () { this.appElem = document.createElement('div') diff --git a/app/javascript/submission_form/area.vue b/app/javascript/submission_form/area.vue index affd57a6..a3e83b62 100644 --- a/app/javascript/submission_form/area.vue +++ b/app/javascript/submission_form/area.vue @@ -1,9 +1,14 @@ diff --git a/app/javascript/submission_form/verification_step.vue b/app/javascript/submission_form/verification_step.vue index 0e0bb767..59ae6c4c 100644 --- a/app/javascript/submission_form/verification_step.vue +++ b/app/javascript/submission_form/verification_step.vue @@ -30,6 +30,7 @@