Skip to content

Commit

Permalink
Merge pull request #3791 from finnishtransportagency/HARJA-907-modaal…
Browse files Browse the repository at this point in the history
…in-saavutettavuus

HARJA-907-modaalin-saavutettavuus
  • Loading branch information
samnes authored Feb 5, 2025
2 parents 54649fc + 1669175 commit 30d2119
Show file tree
Hide file tree
Showing 5 changed files with 337 additions and 262 deletions.
27 changes: 27 additions & 0 deletions src/cljs/harja/ui/dom.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,33 @@
leveys (.-width r)]
leveys))

(defn hae-nakyman-elementit [nakyma]
(->> (.querySelectorAll nakyma "button, [href], input, select, textarea")
array-seq
(filter #(not (.-disabled %)))
(filter #(not (.-hidden %)))))

(defn siirra-fokus-nakymaan [nakyma siirra-fokus-elementtiin]
(let [focusable-elementit (hae-nakyman-elementit nakyma)]
(when focusable-elementit
(cond
(= siirra-fokus-elementtiin :last) (.focus (last focusable-elementit))
(= siirra-fokus-elementtiin :second) (.focus (second focusable-elementit))
:else (.focus (first focusable-elementit))))))

(defn tee-fokus-ansa
"Fokusoidaan elementti, mutta jos käyttäjä yrittää siirtää fokusta pois, se palautetaan takaisin."
[ref]
(let [focusable-elementit (when @ref (hae-nakyman-elementit @ref))]
(set! (.-onkeydown js/document)
(fn [e]
(when (and (tab+shift-nappaimet? e) (= (.-activeElement js/document) (first focusable-elementit)))
(.preventDefault e)
(.focus (last focusable-elementit)))
(when (and (tab-nappain-ilman-shiftia? e) (= (.-activeElement js/document) (last focusable-elementit)))
(.preventDefault e)
(.focus (first focusable-elementit)))))))

(defn lataus-komponentille
"Jos komponentin luominen kestää pitkää, tämän voi wrapata komponentin ympärille, jolloinka
näytetään lataus gif sen aikaa, että react on kerennyt mountata komponentin."
Expand Down
251 changes: 128 additions & 123 deletions src/cljs/harja/ui/grid/perus.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -227,129 +227,133 @@
mahdollista-rivin-valinta? rivin-infolaatikko solun-luokka infolaatikon-tila-muuttui
data esta-tiivis-grid? piilota-border? avattavat-rivit isanta-rivin-id] :as rivin-data}
skeema rivi index]
[:tr {:class (str luokka
(when piilota-border? " valiotsikko ")
(when (= id @valittu-rivi)
" rivi-valittu ")
;; Avattavia rivejä ei näytetä, mikäli niitä ei ole avattu. Eli rivit on olemassa,
;; mutta ne piilotetaan taulukon eheyden säilyttämiseksi.
(when (and isanta-rivin-id (not= isanta-rivin-id (avattavat-rivit-auki? ohjaus isanta-rivin-id)))
" piilota ")
(when isanta-rivin-id
" avattava-rivi "))
:on-click #(kasittele-rivin-klikkaus
{:rivi-klikattu rivi-klikattu
:rivi-valinta-peruttu rivi-valinta-peruttu
:infolaatikko-nakyvissa? infolaatikko-nakyvissa?
:valittu-rivi valittu-rivi
:id id
:mahdollista-rivin-valinta? mahdollista-rivin-valinta?
:rivin-infolaatikko rivin-infolaatikko
:infolaatikon-tila-muuttui infolaatikon-tila-muuttui
:rivi rivi})}

(doall (map-indexed
(fn [i {:keys [nimi hae fmt tasaa tyyppi komponentti komponentti-args
solu-klikattu solun-luokka huomio
pakota-rivitys? reunus luokka solun-tooltip]}]
(let [kentan-skeema (get skeema i)
haettu-arvo (if hae
(hae rivi)
(get rivi nimi))
solun-tooltip? (and solun-tooltip (solun-tooltip rivi))
tooltip-params {:tooltip-disabloitu? (when-not solun-tooltip? true)}
tooltip-suunta-fn (fn [rivi] (:suunta (solun-tooltip rivi)))
tooltip-params (if (and solun-tooltip? (tooltip-suunta-fn rivi))
(assoc tooltip-params :suunta (tooltip-suunta-fn rivi))
tooltip-params)]
(cond
(and (= :avattava-rivi tyyppi) (not isanta-rivin-id))
^{:key (str "avattava-rivi-tila" id)}
[avattavat-rivi-tila ohjaus avattavat-rivit id (y/luokat "vetolaatikon-tila"
(grid-yleiset/tiivis-tyyli skeema esta-tiivis-grid?))]

(= :vetolaatikon-tila tyyppi)
^{:key (str "vetolaatikontila" id)}
[vetolaatikon-tila ohjaus vetolaatikot id (y/luokat "vetolaatikon-tila"
(grid-yleiset/tiivis-tyyli skeema esta-tiivis-grid?))]
:else
^{:key (str i nimi)}
;; Solu
[:td {:on-click (when solu-klikattu
#(do
(.preventDefault %)
(.stopPropagation %)
(solu-klikattu rivi)))
:col-span (if-let [leveys (get (:colspan rivi) nimi)]
leveys
1)
:class (y/luokat
(y/tasaus-luokka tasaa)
(when pakota-rivitys? "grid-pakota-rivitys")
(when solu-klikattu "klikattava")
(grid-yleiset/tiivis-tyyli skeema esta-tiivis-grid?)
(case reunus
:ei "grid-reunus-ei"
:vasen "grid-reunus-vasen"
:oikea "grid-reunus-oikea"
nil)
(when solun-luokka
(solun-luokka haettu-arvo rivi))
(if (fn? luokka)
(luokka rivi)
luokka))}
;; Solun sisältö
[yleiset/tooltip tooltip-params
[:div (when (and (:oikealle? rivi) ((:oikealle? rivi) nimi)) {:style {:float "right"}})
;; Sijoitetaan infolaatikko suhteessa viimeiseen soluun.
;; Semanttisesti sen kuuluisi olla suhteessa riviin (koska laatikko kuvaa rivin lisätietoa).
;; mutta HTML:n säännöt kieltävät div-elementit suoraan tr:n lapsena
(when (and
(= id @valittu-rivi)
(= (inc i) (count skeema))
rivin-infolaatikko
@infolaatikko-nakyvissa?)
[rivin-infolaatikko* rivin-infolaatikko rivi data])
(cond
(= tyyppi :komponentti) (apply komponentti rivi {:index index
:muokataan? false}
komponentti-args)
(= tyyppi :reagent-komponentti) (vec (concat [komponentti rivi {:index index
:muokataan? false}]
komponentti-args))
:else
(if fmt
(fmt haettu-arvo)
[nayta-arvo kentan-skeema (vain-luku-atomina haettu-arvo)]))
(when huomio
(when-let [huomion-tiedot (huomio rivi)]
(let [ikoni (case (:tyyppi huomion-tiedot)
:varoitus (ui-ikonit/livicon-warning-sign)
:info (ui-ikonit/livicon-info-circle)
(ui-ikonit/livicon-info))
teksti (:teksti huomion-tiedot)]
(when teksti
[yleiset/tooltip {} [:span {:style {:margin-left "3px"}
:class (str "grid-huomio-"
(name (:tyyppi huomion-tiedot)))}
ikoni]
teksti]))))]
(when solun-tooltip
(when-let [solun-tooltip-tiedot (solun-tooltip rivi)]
(let [teksti (:teksti solun-tooltip-tiedot)
tooltip-tyyppi (:tooltip-tyyppi solun-tooltip-tiedot)
tooltip-komponentti (:tooltip-komponentti solun-tooltip-tiedot)]
(cond
(= tooltip-tyyppi :komponentti) tooltip-komponentti
:else
(or teksti "-")))))]])))
(if (:colspan rivi)
(filter #(contains? (:colspan rivi) (:nimi %)) skeema)
skeema)))
(when (or nayta-toimintosarake?
(let [rivin-klikkaus #(kasittele-rivin-klikkaus
{:rivi-klikattu rivi-klikattu
:rivi-valinta-peruttu rivi-valinta-peruttu
:infolaatikko-nakyvissa? infolaatikko-nakyvissa?
:valittu-rivi valittu-rivi
:id id
:mahdollista-rivin-valinta? mahdollista-rivin-valinta?
:rivin-infolaatikko rivin-infolaatikko
:infolaatikon-tila-muuttui infolaatikon-tila-muuttui
:rivi rivi})]
[:tr {:class (str luokka
(when piilota-border? " valiotsikko ")
(when (= id @valittu-rivi)
" rivi-valittu ")
;; Avattavia rivejä ei näytetä, mikäli niitä ei ole avattu. Eli rivit on olemassa,
;; mutta ne piilotetaan taulukon eheyden säilyttämiseksi.
(when (and isanta-rivin-id (not= isanta-rivin-id (avattavat-rivit-auki? ohjaus isanta-rivin-id)))
" piilota ")
(when isanta-rivin-id
" avattava-rivi "))
:tabIndex (when rivi-klikattu "0")
:on-key-down #(when (and rivi-klikattu (dom/enter-nappain? %))
(rivin-klikkaus))
:on-click rivin-klikkaus}

(doall (map-indexed
(fn [i {:keys [nimi hae fmt tasaa tyyppi komponentti komponentti-args
solu-klikattu solun-luokka huomio
pakota-rivitys? reunus luokka solun-tooltip]}]
(let [kentan-skeema (get skeema i)
haettu-arvo (if hae
(hae rivi)
(get rivi nimi))
solun-tooltip? (and solun-tooltip (solun-tooltip rivi))
tooltip-params {:tooltip-disabloitu? (when-not solun-tooltip? true)}
tooltip-suunta-fn (fn [rivi] (:suunta (solun-tooltip rivi)))
tooltip-params (if (and solun-tooltip? (tooltip-suunta-fn rivi))
(assoc tooltip-params :suunta (tooltip-suunta-fn rivi))
tooltip-params)]
(cond
(and (= :avattava-rivi tyyppi) (not isanta-rivin-id))
^{:key (str "avattava-rivi-tila" id)}
[avattavat-rivi-tila ohjaus avattavat-rivit id (y/luokat "vetolaatikon-tila"
(grid-yleiset/tiivis-tyyli skeema esta-tiivis-grid?))]

(= :vetolaatikon-tila tyyppi)
^{:key (str "vetolaatikontila" id)}
[vetolaatikon-tila ohjaus vetolaatikot id (y/luokat "vetolaatikon-tila"
(grid-yleiset/tiivis-tyyli skeema esta-tiivis-grid?))]
:else
^{:key (str i nimi)}
;; Solu
[:td {:on-click (when solu-klikattu
#(do
(.preventDefault %)
(.stopPropagation %)
(solu-klikattu rivi)))
:col-span (if-let [leveys (get (:colspan rivi) nimi)]
leveys
1)
:class (y/luokat
(y/tasaus-luokka tasaa)
(when pakota-rivitys? "grid-pakota-rivitys")
(when solu-klikattu "klikattava")
(grid-yleiset/tiivis-tyyli skeema esta-tiivis-grid?)
(case reunus
:ei "grid-reunus-ei"
:vasen "grid-reunus-vasen"
:oikea "grid-reunus-oikea"
nil)
(when solun-luokka
(solun-luokka haettu-arvo rivi))
(if (fn? luokka)
(luokka rivi)
luokka))}
;; Solun sisältö
[yleiset/tooltip tooltip-params
[:div (when (and (:oikealle? rivi) ((:oikealle? rivi) nimi)) {:style {:float "right"}})
;; Sijoitetaan infolaatikko suhteessa viimeiseen soluun.
;; Semanttisesti sen kuuluisi olla suhteessa riviin (koska laatikko kuvaa rivin lisätietoa).
;; mutta HTML:n säännöt kieltävät div-elementit suoraan tr:n lapsena
(when (and
(= id @valittu-rivi)
(= (inc i) (count skeema))
rivin-infolaatikko
@infolaatikko-nakyvissa?)
[rivin-infolaatikko* rivin-infolaatikko rivi data])
(cond
(= tyyppi :komponentti) (apply komponentti rivi {:index index
:muokataan? false}
komponentti-args)
(= tyyppi :reagent-komponentti) (vec (concat [komponentti rivi {:index index
:muokataan? false}]
komponentti-args))
:else
(if fmt
(fmt haettu-arvo)
[nayta-arvo kentan-skeema (vain-luku-atomina haettu-arvo)]))
(when huomio
(when-let [huomion-tiedot (huomio rivi)]
(let [ikoni (case (:tyyppi huomion-tiedot)
:varoitus (ui-ikonit/livicon-warning-sign)
:info (ui-ikonit/livicon-info-circle)
(ui-ikonit/livicon-info))
teksti (:teksti huomion-tiedot)]
(when teksti
[yleiset/tooltip {} [:span {:style {:margin-left "3px"}
:class (str "grid-huomio-"
(name (:tyyppi huomion-tiedot)))}
ikoni]
teksti]))))]
(when solun-tooltip
(when-let [solun-tooltip-tiedot (solun-tooltip rivi)]
(let [teksti (:teksti solun-tooltip-tiedot)
tooltip-tyyppi (:tooltip-tyyppi solun-tooltip-tiedot)
tooltip-komponentti (:tooltip-komponentti solun-tooltip-tiedot)]
(cond
(= tooltip-tyyppi :komponentti) tooltip-komponentti
:else
(or teksti "-")))))]])))
(if (:colspan rivi)
(filter #(contains? (:colspan rivi) (:nimi %)) skeema)
skeema)))
(when (or nayta-toimintosarake?
(and (not piilota-toiminnot?)
tallenna))
[:th.toiminnot {:width "40px"} " "])])
tallenna))
[:th.toiminnot {:width "40px"} " "])]))


(def renderoi-rivia-kerralla 100)
Expand Down Expand Up @@ -550,13 +554,14 @@
(y/tasaus-luokka tasaa)
(grid-yleiset/tiivis-tyyli skeema esta-tiivis-grid?))
:width (or leveys "5%")
:tabIndex (when otsikkorivi-klikattu "0")
:on-key-down #(when (and otsikkorivi-klikattu (dom/enter-nappain? %)) (otsikkorivi-klikattu s-opts))
:on-click (when otsikkorivi-klikattu #(otsikkorivi-klikattu s-opts))}
(if otsikko-komp
[otsikko-komp]
(if-not sarake-sort
[:div otsikko]
[:div.ilmoitukset-sort
;;TODO: Muuta span.klikattava buttoniksi jossakin vaiheessa.
[:span.klikattava {:on-click (:fn sarake-sort)}
otsikko " " (sort-ikoni (:suunta sarake-sort)) " "]]))]) skeema)
(when (or nayta-toimintosarake?
Expand Down
Loading

0 comments on commit 30d2119

Please sign in to comment.