mirror of
https://github.com/penpot/penpot.git
synced 2025-06-08 16:01:38 +02:00
✨ Improve dashboard accessibility
This commit is contained in:
parent
2ce36ce052
commit
7045496a39
28 changed files with 761 additions and 283 deletions
|
@ -12,7 +12,7 @@
|
|||
(mf/defc button-link [{:keys [action icon name klass]}]
|
||||
[:a.btn-primary.btn-large.button-link
|
||||
{:class klass
|
||||
:tabindex "0"
|
||||
:tab-index "0"
|
||||
:on-click action
|
||||
:on-key-down (fn [event]
|
||||
(when (kbd/enter? event)
|
||||
|
|
121
frontend/src/app/main/ui/components/dropdown_menu.cljs
Normal file
121
frontend/src/app/main/ui/components/dropdown_menu.cljs
Normal file
|
@ -0,0 +1,121 @@
|
|||
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;;
|
||||
;; Copyright (c) KALEIDOS INC
|
||||
|
||||
(ns app.main.ui.components.dropdown-menu
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.config :as cfg]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.globals :as globals]
|
||||
[app.util.keyboard :as kbd]
|
||||
[goog.events :as events]
|
||||
[goog.object :as gobj]
|
||||
[rumext.v2 :as mf])
|
||||
(:import goog.events.EventType))
|
||||
|
||||
(mf/defc dropdown-menu-item
|
||||
{::mf/wrap-props false}
|
||||
[props]
|
||||
|
||||
(let [children (gobj/get props "children")
|
||||
on-click (gobj/get props "on-click")
|
||||
on-key-down (gobj/get props "on-key-down")
|
||||
id (gobj/get props "id")
|
||||
klass (gobj/get props "klass")
|
||||
key (gobj/get props "klass")
|
||||
data-test (gobj/get props "data-test")]
|
||||
[:li {:id id
|
||||
:class klass
|
||||
:tab-index "0"
|
||||
:on-key-down on-key-down
|
||||
:on-click on-click
|
||||
:key key
|
||||
:role "menuitem"
|
||||
:data-test data-test}
|
||||
children]))
|
||||
|
||||
(mf/defc dropdown-menu'
|
||||
{::mf/wrap-props false}
|
||||
[props]
|
||||
(let [children (gobj/get props "children")
|
||||
on-close (gobj/get props "on-close")
|
||||
ref (gobj/get props "container")
|
||||
ids (gobj/get props "ids")
|
||||
list-class (gobj/get props "list-class")
|
||||
|
||||
on-click
|
||||
(fn [event]
|
||||
(let [target (dom/get-target event)
|
||||
|
||||
;; MacOS ctrl+click sends two events: context-menu and click.
|
||||
;; In order to not have two handlings we ignore ctrl+click for this platform
|
||||
mac-ctrl-click? (and (cfg/check-platform? :macos) (kbd/ctrl? event))]
|
||||
(when (and (not mac-ctrl-click?)
|
||||
(not (.-data-no-close ^js target)))
|
||||
(if ref
|
||||
(let [parent (mf/ref-val ref)]
|
||||
(when-not (or (not parent) (.contains parent target))
|
||||
(on-close)))
|
||||
(on-close)))))
|
||||
|
||||
on-keyup
|
||||
(fn [event]
|
||||
(when (kbd/esc? event)
|
||||
(on-close)))
|
||||
|
||||
on-key-down
|
||||
(fn [event]
|
||||
(let [first-id (dom/get-element (first ids))
|
||||
first-element (dom/get-element first-id)
|
||||
len (count ids)]
|
||||
|
||||
(when (kbd/home? event)
|
||||
(when first-element
|
||||
(dom/focus! first-element)))
|
||||
|
||||
(when (kbd/up-arrow? event)
|
||||
(let [actual-selected (dom/get-active)
|
||||
actual-id (dom/get-attribute actual-selected "id")
|
||||
actual-index (d/index-of ids actual-id)
|
||||
previous-id (if (= 0 actual-index)
|
||||
(last ids)
|
||||
(nth ids (- actual-index 1)))]
|
||||
(dom/focus! (dom/get-element previous-id))))
|
||||
|
||||
(when (kbd/down-arrow? event)
|
||||
(let [actual-selected (dom/get-active)
|
||||
actual-id (dom/get-attribute actual-selected "id")
|
||||
actual-index (d/index-of ids actual-id)
|
||||
next-id (if (= (- len 1) actual-index)
|
||||
(first ids)
|
||||
(nth ids (+ 1 actual-index)))]
|
||||
(dom/focus! (dom/get-element next-id))))
|
||||
|
||||
(when (kbd/tab? event)
|
||||
(on-close))))
|
||||
|
||||
on-mount
|
||||
(fn []
|
||||
(let [keys [(events/listen globals/document EventType.CLICK on-click)
|
||||
(events/listen globals/document EventType.CONTEXTMENU on-click)
|
||||
(events/listen globals/document EventType.KEYUP on-keyup)
|
||||
(events/listen globals/document EventType.KEYDOWN on-key-down)]]
|
||||
#(doseq [key keys]
|
||||
(events/unlistenByKey key))))]
|
||||
|
||||
(mf/use-effect on-mount)
|
||||
[:ul {:class list-class
|
||||
:role "menu"}
|
||||
children]))
|
||||
|
||||
(mf/defc dropdown-menu
|
||||
{::mf/wrap-props false}
|
||||
[props]
|
||||
(assert (fn? (gobj/get props "on-close")) "missing `on-close` prop")
|
||||
(assert (boolean? (gobj/get props "show")) "missing `show` prop")
|
||||
|
||||
(when (gobj/get props "show")
|
||||
(mf/element dropdown-menu' props)))
|
|
@ -39,5 +39,6 @@
|
|||
:type "file"
|
||||
:ref input-ref
|
||||
:on-change on-files-selected
|
||||
:data-test data-test}]]))
|
||||
:data-test data-test
|
||||
:aria-label "uploader"}]]))
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@
|
|||
:placeholder label
|
||||
:on-change on-change
|
||||
:type @type'
|
||||
:tabindex "0")
|
||||
:tab-index "0")
|
||||
(cond-> (and value is-checkbox?) (assoc :default-checked value))
|
||||
(cond-> (and touched? (:message error)) (assoc "aria-invalid" "true"
|
||||
"aria-describedby" (dm/str "error-" input-name)))
|
||||
|
@ -224,7 +224,7 @@
|
|||
{:name "submit"
|
||||
:class (when (or (not (:valid @form)) (true? disabled)) "btn-disabled")
|
||||
:disabled (or (not (:valid @form)) (true? disabled))
|
||||
:tabindex "0"
|
||||
:tab-index "0"
|
||||
:on-click on-click
|
||||
:on-key-down (fn [event]
|
||||
(when (kbd/enter? event)
|
||||
|
|
|
@ -9,12 +9,13 @@
|
|||
[app.util.keyboard :as kbd]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(mf/defc link [{:keys [action name klass data-test]}]
|
||||
[:a {:on-click action
|
||||
:klass klass
|
||||
:on-key-down (fn [event]
|
||||
(when (kbd/enter? event)
|
||||
(action event)))
|
||||
:tabindex "0"
|
||||
:data-test data-test}
|
||||
name])
|
||||
(mf/defc link [{:keys [action klass data-test keyboard-action children]}]
|
||||
(let [keyboard-action (or keyboard-action action)]
|
||||
[:a {:on-click action
|
||||
:class klass
|
||||
:on-key-down (fn [event]
|
||||
(when (kbd/enter? event)
|
||||
(keyboard-action event)))
|
||||
:tab-index "0"
|
||||
:data-test data-test}
|
||||
[:* children]]))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue