git.iko.soy/typeable/elm-ui
on master help sign in
labelHidden
commit192acf6a088c1d02f126d9dd39bf50ecd10e6d0e authorMatthew Griffith <mdg.griffith@gmail.com> dateMon 17 Sep 2018, 17:10 (8 years ago) parent531e23f
1 file changed+107−44
src/Element/Input.elm+107−44
src/Element/Input.elm+107−44
@@ -6,7 +6,7 @@ module Element.Input exposing
66 , multiline
77 , slider, Thumb, thumb, defaultThumb
88 , radio, radioRow, Option, option, optionWith, OptionState(..)
9− , Label, labelAbove, labelBelow, labelLeft, labelRight
9+ , Label, labelAbove, labelBelow, labelLeft, labelRight, labelHidden
1010 , focusedOnLoad
1111 )
1212
@@ -43,7 +43,7 @@ We can also give a hint about what type of content our text field contains. This
4343
4444## Labels
4545
46−@docs Label, labelAbove, labelBelow, labelLeft, labelRight
46+@docs Label, labelAbove, labelBelow, labelLeft, labelRight, labelHidden
4747
4848@docs focusedOnLoad
4949
@@ -90,34 +90,68 @@ placeholder =
9090 Placeholder
9191
9292
93+type LabelLocation
94+ = OnRight
95+ | OnLeft
96+ | Above
97+ | Below
98+
99+
93100{-| Every input has a required `label`.
94101-}
95102type Label msg
96− = Label Internal.Location (List (Attribute msg)) (Element msg)
103+ = Label LabelLocation (List (Attribute msg)) (Element msg)
104+ | HiddenLabel String
97105
98106
99107{-| -}
100108labelRight : List (Attribute msg) -> Element msg -> Label msg
101109labelRight =
102− Label Internal.OnRight
110+ Label OnRight
103111
104112
105113{-| -}
106114labelLeft : List (Attribute msg) -> Element msg -> Label msg
107115labelLeft =
108− Label Internal.OnLeft
116+ Label OnLeft
109117
110118
111119{-| -}
112120labelAbove : List (Attribute msg) -> Element msg -> Label msg
113121labelAbove =
114− Label Internal.Above
122+ Label Above
115123
116124
117125{-| -}
118126labelBelow : List (Attribute msg) -> Element msg -> Label msg
119127labelBelow =
120− Label Internal.Below
128+ Label Below
129+
130+
131+{-| Sometimes you may need to have a label which is not visible, but is still accessible to screen readers.
132+
133+Seriously consider a visible label before using this.
134+
135+The situations where a hidden label makes sense:
136+
137+ - A searchbar with a `search` button right next to it.
138+ - A `table` of inputs where the header gives the label.
139+
140+Basically, a hidden label makes sense when there are other contextual clues that sighted people can pick up on.
141+
142+-}
143+labelHidden : String -> Label msg
144+labelHidden =
145+ HiddenLabel
146+
147+
148+hiddenLabelAttribute label =
149+ case label of
150+ HiddenLabel textLabel ->
151+ Internal.Describe (Internal.Label textLabel)
152+
153+ Label _ _ _ ->
154+ Internal.NoAttribute
121155
122156
123157{-| A standard button.
@@ -216,21 +250,30 @@ checkbox :
216250checkbox attrs { label, icon, checked, onChange } =
217251 let
218252 attributes =
219− Element.spacing 6
220− :: [ Internal.Attr (Html.Events.onClick (onChange (not checked)))
221− , Region.announce
222− , onKeyLookup <|
223− \code ->
224− if code == enter then
225− Just <| onChange (not checked)
226−
227− else if code == space then
228− Just <| onChange (not checked)
253+ [ if isHiddenLabel label then
254+ Internal.NoAttribute
255+
256+ else
257+ Element.spacing
258+ 6
259+ , Internal.Attr (Html.Events.onClick (onChange (not checked)))
260+ , Region.announce
261+ , onKeyLookup <|
262+ \code ->
263+ if code == enter then
264+ Just <| onChange (not checked)
265+
266+ else if code == space then
267+ Just <| onChange (not checked)
229268
230− else
231− Nothing
232− ]
233− ++ (tabindex 0 :: Element.pointer :: Element.alignLeft :: Element.width Element.fill :: attrs)
269+ else
270+ Nothing
271+ , tabindex 0
272+ , Element.pointer
273+ , Element.alignLeft
274+ , Element.width Element.fill
275+ ]
276+ ++ attrs
234277 in
235278 applyLabel attributes
236279 label
@@ -246,6 +289,7 @@ checkbox attrs { label, icon, checked, onChange } =
246289
247290 else
248291 "false"
292+ , hiddenLabelAttribute label
249293 , Element.centerY
250294 , Element.height Element.fill
251295 , Element.width Element.shrink
@@ -428,7 +472,11 @@ slider attributes input =
428472 ]
429473 in
430474 applyLabel
431− [ Element.spacingXY spacingX spacingY
475+ [ if isHiddenLabel input.label then
476+ Internal.NoAttribute
477+
478+ else
479+ Element.spacingXY spacingX spacingY
432480 , Region.announce
433481 , Element.width
434482 (case trackWidth of
@@ -463,7 +511,8 @@ slider attributes input =
463511 [ Internal.element
464512 Internal.asEl
465513 (Internal.NodeName "input")
466− [ Internal.StyleClass Flag.active
514+ [ hiddenLabelAttribute input.label
515+ , Internal.StyleClass Flag.active
467516 (Internal.Style
468517 ("input[type=\"range\"]." ++ className ++ "::-moz-range-thumb")
469518 thumbShadowStyle
@@ -891,6 +940,7 @@ textHelper textInput attrs textOptions =
891940 (Internal.NodeName inputNode)
892941 (List.concat
893942 [ [ focusDefault attrs
943+ , hiddenLabelAttribute textOptions.label
894944 ]
895945 , inputAttrs
896946 , behavior
@@ -902,7 +952,13 @@ textHelper textInput attrs textOptions =
902952 in
903953 applyLabel
904954 (Internal.Class Flag.cursor classes.cursorText
905− :: Element.spacing 5
955+ :: (if isHiddenLabel textOptions.label then
956+ Internal.NoAttribute
957+
958+ else
959+ Element.spacing
960+ 5
961+ )
906962 :: Region.announce
907963 :: attributesFromChild
908964 )
@@ -1130,9 +1186,27 @@ multiline attrs multi =
11301186 }
11311187
11321188
1189+isHiddenLabel label =
1190+ case label of
1191+ HiddenLabel _ ->
1192+ True
1193+
1194+ _ ->
1195+ False
1196+
1197+
11331198applyLabel : List (Attribute msg) -> Label msg -> Element msg -> Element msg
11341199applyLabel attrs label input =
11351200 case label of
1201+ HiddenLabel labelText ->
1202+ -- NOTE: This means that the label is applied outside of this function!
1203+ -- It would be nice to unify this logic, but it's a little tricky
1204+ Internal.element
1205+ Internal.asColumn
1206+ (Internal.NodeName "label")
1207+ attrs
1208+ (Internal.Unkeyed [ input ])
1209+
11361210 Label position labelAttrs labelChild ->
11371211 let
11381212 labelElement =
@@ -1143,42 +1217,28 @@ applyLabel attrs label input =
11431217 (Internal.Unkeyed [ labelChild ])
11441218 in
11451219 case position of
1146− Internal.Above ->
1220+ Above ->
11471221 Internal.element
11481222 Internal.asColumn
11491223 (Internal.NodeName "label")
11501224 attrs
11511225 (Internal.Unkeyed [ labelElement, input ])
11521226
1153− Internal.Below ->
1227+ Below ->
11541228 Internal.element
11551229 Internal.asColumn
11561230 (Internal.NodeName "label")
11571231 attrs
11581232 (Internal.Unkeyed [ input, labelElement ])
11591233
1160− Internal.OnRight ->
1234+ OnRight ->
11611235 Internal.element
11621236 Internal.asRow
11631237 (Internal.NodeName "label")
11641238 attrs
11651239 (Internal.Unkeyed [ input, labelElement ])
11661240
1167− Internal.OnLeft ->
1168− Internal.element
1169− Internal.asRow
1170− (Internal.NodeName "label")
1171− attrs
1172− (Internal.Unkeyed [ labelElement, input ])
1173−
1174− Internal.InFront ->
1175− Internal.element
1176− Internal.asRow
1177− (Internal.NodeName "label")
1178− attrs
1179− (Internal.Unkeyed [ labelElement, input ])
1180−
1181− Internal.Behind ->
1241+ OnLeft ->
11821242 Internal.element
11831243 Internal.asRow
11841244 (Internal.NodeName "label")
@@ -1380,11 +1440,11 @@ radioHelper orientation attrs input =
13801440 optionArea =
13811441 case orientation of
13821442 Row ->
1383− row attrs
1443+ row (hiddenLabelAttribute input.label :: attrs)
13841444 (List.map renderOption input.options)
13851445
13861446 Column ->
1387− column attrs
1447+ column (hiddenLabelAttribute input.label :: attrs)
13881448 (List.map renderOption input.options)
13891449
13901450 prevNext =
@@ -1453,6 +1513,9 @@ radioHelper orientation attrs input =
14531513 _ ->
14541514 False
14551515
1516+ HiddenLabel _ ->
1517+ True
1518+
14561519 hideIfEverythingisInvisible =
14571520 if not labelVisible && not inputVisible then
14581521 let