summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2019-11-28 11:21:19 +0100
committerYorhel <git@yorhel.nl>2019-11-28 11:21:23 +0100
commit8825bb9df2487057bb65b69df67c93e7d793a37a (patch)
tree0a070d68abd5daf67f1526d5a7be3fa610d1d9c8
parent4067f0a73a55e898def7320976781a2b8bf6710b (diff)
Use plain links for JS-ified linkradio inputs + fix focus of non-JS linkradios
Kind of backwards to use input elements to display a link when they're backed by Javascript anyway. This also avoids the need to create a unique id for each linkradio element.
-rw-r--r--data/style.css25
-rw-r--r--elm/ColSelect.elm9
-rw-r--r--elm/Lib/Html.elm6
-rw-r--r--elm/UList/LabelEdit.elm21
-rw-r--r--elm/UList/ManageLabels.elm5
-rw-r--r--elm/UList/Opt.elm31
6 files changed, 56 insertions, 41 deletions
diff --git a/data/style.css b/data/style.css
index 63eb728f..87cab868 100644
--- a/data/style.css
+++ b/data/style.css
@@ -42,6 +42,7 @@ table.stripe tbody tr:nth-child(odd):not(.nostripe),
#debug h2 { color: #f00!important; font-size: 20px; }
#debug, #debug a { color: #fff!important; }
+/* https://snook.ca/archives/html_and_css/hiding-content-for-accessibility */
.visuallyhidden, .linkradio input {
position: absolute !important;
left: 0;
@@ -167,13 +168,35 @@ table.formtable td { padding: 0; }
table.formtable tr.newfield td { padding-top: 5px; }
table.formtable tr.newpart td { padding-top: 20px; font-weight: bold; }
+/* Format checkboxes and radio buttons as if they were normal links with unicode icons.
+ * Usage:
+ *
+ * <container class="linkradio">
+ * <input type="checkbox|radio" id="xyz">
+ * <label for="xyz">Text</label>
+ * <em>(optional option separator)</em>
+ * </container>
+ */
p.linkradio { padding: 2px }
.linkradio label { color: $link$; cursor: pointer }
.linkradio label:before { content: '✗' }
.linkradio input:checked + label { color: $maintext$ }
.linkradio input:checked + label:before { content: '✓' }
+.linkradio input:focus + label { outline: 1px dotted $link$ }
+.linkradio input:focus:checked + label { outline: 1px dotted $maintext$ }
.linkradio em { font-weight: normal; font-style: normal; color: $grayedout$ }
+/* Same styling, but for regular links.
+ * Usage:
+ *
+ * <a href="#" class="linkradio">Unchecked option</a>
+ * <a href="#" class="linkradio checked">Checked option</a>
+ */
+a.linkradio:before { content: '✗' }
+a.linkradio.checked { color: $maintext$ }
+a.linkradio.checked:before { content: '✓' }
+
+/* Spinner, <div class="spinner"></div> for a large one, <span> for a smaller inline-text version */
.spinner { content: ''; box-sizing: border-box; border: 3px solid #9eaebd; border-bottom-color: transparent; border-radius: 100%; animation: spin 1s infinite linear; width: 16px; height: 16px; display: inline-block; margin: auto }
span.spinner { width: 1em; height: 1em }
@keyframes spin { from { transform:rotate(0deg); } to { transform:rotate(360deg); } }
@@ -184,6 +207,8 @@ span.spinner { width: 1em; height: 1em }
.textpreview .preview { width: 100%; box-sizing: border-box; border: 1px solid $secborder$; margin: 1px; padding: 5px }
fieldset.submit .textpreview { margin: -15px auto 0 auto }
+/* .compact input elements are smaller and can be embedded in tables/inline text
+ * .stealth input elements pretend to be just regular text, but turn into visibile input elements on mouse-over */
.compact input.text, .compact select { margin: -2px -1px; padding: 1px 0 }
.stealth input, .stealth select { font: inherit; background: none; border: 1px solid transparent; -moz-appearance: none; -webkit-appearance: none; appearance: none }
.stealth input:hover, .stealth input:focus,
diff --git a/elm/ColSelect.elm b/elm/ColSelect.elm
index d8be329b..049cc369 100644
--- a/elm/ColSelect.elm
+++ b/elm/ColSelect.elm
@@ -68,14 +68,7 @@ update msg model =
view : Model -> Html Msg
view model =
- let
- item (cid, cname) =
- let selid = "colselect_" ++ cid
- in
- li [ class "linkradio" ]
- [ inputCheck selid (Set.member cid model.sel) (Toggle cid)
- , label [ for selid ] [ text cname ]
- ]
+ let item (cid, cname) = li [ ] [ linkRadio (Set.member cid model.sel) (Toggle cid) [ text cname ] ]
in
DD.view model.dd Api.Normal
(text "Select columns")
diff --git a/elm/Lib/Html.elm b/elm/Lib/Html.elm
index 86c0f8f7..d75dced4 100644
--- a/elm/Lib/Html.elm
+++ b/elm/Lib/Html.elm
@@ -150,6 +150,12 @@ inputWikidata nam val onch =
[ pattern "^Q?[1-9][0-9]{0,8}$" ]
+-- Similar to inputCheck and inputRadio with a label, except this is just a link.
+linkRadio : Bool -> (Bool -> m) -> List (Html m) -> Html m
+linkRadio val onch content =
+ a [ href "#", onClickD (onch (not val)), class "linkradio", classList [("checked", val)] ] content
+
+
-- Generate a form field (table row) with a label. The `label` string can be:
--
-- "none" -> To generate a full-width field (colspan=2)
diff --git a/elm/UList/LabelEdit.elm b/elm/UList/LabelEdit.elm
index 1f2c229d..28f2cc68 100644
--- a/elm/UList/LabelEdit.elm
+++ b/elm/UList/LabelEdit.elm
@@ -76,19 +76,16 @@ view model =
str = String.join ", " <| List.filterMap (\l -> if Set.member l.id model.sel then Just l.label else Nothing) model.labels
item l =
- let lid = "label_edit_" ++ String.fromInt model.vid ++ "_" ++ String.fromInt l.id
- in
- li [ class "linkradio" ]
- [ inputCheck lid (Set.member l.id model.tsel) (Toggle l.id)
- , label [ for lid ]
- [ text l.label
- , text " "
- , span [ class "spinner", classList [("invisible", Dict.get l.id model.state /= Just Api.Loading)] ] []
- , case Dict.get l.id model.state of
- Just (Api.Error _) -> b [ class "standout" ] [ text "error" ] -- Need something better
- _ -> text ""
- ]
+ li [ ]
+ [ linkRadio (Set.member l.id model.tsel) (Toggle l.id)
+ [ text l.label
+ , text " "
+ , span [ class "spinner", classList [("invisible", Dict.get l.id model.state /= Just Api.Loading)] ] []
+ , case Dict.get l.id model.state of
+ Just (Api.Error _) -> b [ class "standout" ] [ text "error" ] -- Need something better
+ _ -> text ""
]
+ ]
in
DD.view model.dd
(if List.any (\s -> s == Api.Loading) <| Dict.values model.state then Api.Loading else Api.Normal)
diff --git a/elm/UList/ManageLabels.elm b/elm/UList/ManageLabels.elm
index e2824ea2..7f951389 100644
--- a/elm/UList/ManageLabels.elm
+++ b/elm/UList/ManageLabels.elm
@@ -69,14 +69,13 @@ view : Model -> Html Msg
view model =
let
item n l =
- let strid = "form_pr" ++ String.fromInt n
- in tr [ class "compact" ]
+ tr [ class "compact" ]
[ td [] [ text <| if l.count == 0 then "" else String.fromInt l.count ]
, td [ class "stealth" ]
[ if l.id > 0 && l.id < 10 then text l.label
else inputText ("label_txt_"++String.fromInt n) l.label (Label n) GML.valLabelsLabel
]
- , td [ class "linkradio" ] [ inputCheck strid l.private (Private n), label [ for strid ] [ text "private" ] ]
+ , td [ ] [ linkRadio l.private (Private n) [ text "private" ] ]
, td [ class "stealth" ]
[ if l.id == 7 then b [ class "grayedout" ] [ text "applied when you vote" ]
else if l.id > 0 && l.id < 10 then b [ class "grayedout" ] [ text "built-in" ]
diff --git a/elm/UList/Opt.elm b/elm/UList/Opt.elm
index c1f488a0..f5ed7303 100644
--- a/elm/UList/Opt.elm
+++ b/elm/UList/Opt.elm
@@ -203,25 +203,20 @@ view model =
Just nfo -> relnfo r nfo
relnfo r nfo =
- let name = "ulist_relstatus" ++ String.fromInt model.flags.vid ++ "_" ++ String.fromInt nfo.id ++ "_"
- in
- tr []
- [ td [ class "tco1" ]
- [ DD.view r.dd r.state (text <| Maybe.withDefault "removing" <| lookup r.status T.rlistStatus)
- <| \_ ->
- [ ul [] <| List.map (\(n, status) ->
- li [ class "linkradio" ]
- [ inputCheck (name ++ String.fromInt n) (n == r.status) (RelSet r.id n)
- , label [ for <| name ++ String.fromInt n ] [ text status ]
- ]
- ) T.rlistStatus
- ++ [ li [] [ a [ href "#", onClickD (RelSet r.id -1 True) ] [ text "remove" ] ] ]
- ]
- ]
- , td [ class "tco2" ] [ RDate.display model.today nfo.released ]
- , td [ class "tco3" ] <| List.map langIcon nfo.lang ++ [ releaseTypeIcon nfo.rtype ]
- , td [ class "tco4" ] [ a [ href ("/r"++String.fromInt nfo.id), title nfo.original ] [ text nfo.title ] ]
+ tr []
+ [ td [ class "tco1" ]
+ [ DD.view r.dd r.state (text <| Maybe.withDefault "removing" <| lookup r.status T.rlistStatus)
+ <| \_ ->
+ [ ul [] <| List.map (\(n, status) ->
+ li [ ] [ linkRadio (n == r.status) (RelSet r.id n) [ text status ] ]
+ ) T.rlistStatus
+ ++ [ li [] [ a [ href "#", onClickD (RelSet r.id -1 True) ] [ text "remove" ] ] ]
+ ]
]
+ , td [ class "tco2" ] [ RDate.display model.today nfo.released ]
+ , td [ class "tco3" ] <| List.map langIcon nfo.lang ++ [ releaseTypeIcon nfo.rtype ]
+ , td [ class "tco4" ] [ a [ href ("/r"++String.fromInt nfo.id), title nfo.original ] [ text nfo.title ] ]
+ ]
confirm =
div []