@@ -1,186 +1,51 @@
1module Element.Input exposing
1module Element.Input exposing
4 , checkbox, defaultCheckbox
3 , checkbox, defaultCheckbox
6− , Placeholder, placeholder
4+ , text, Placeholder, placeholder
7 , username, newPassword, currentPassword, email, search, spellChecked
5 , username, newPassword, currentPassword, email, search, spellChecked
8 , slider, Thumb, thumb, defaultThumb
7 , slider, Thumb, thumb, defaultThumb
9 , radio, radioRow, Option, option, optionWith, OptionState(..)
8 , radio, radioRow, Option, option, optionWith, OptionState(..)
10 , Label, labelAbove, labelBelow, labelLeft, labelRight, labelHidden
9 , Label, labelAbove, labelBelow, labelLeft, labelRight, labelHidden
13−{-| Input elements have a lot of constraints!
13+{-|
15−We want all of our input elements to:
17− - _Always be accessible_
18− - _Behave intuitively_
19− - _Be completely restyleable_
21−While these three goals may seem pretty obvious, Html and CSS have made it surprisingly difficult to achieve!
23−And incredibly difficult for developers to remember all the tricks necessary to make things work. If you've every tried to make a `<textarea>` be the height of it's content or restyle a radio button while maintaining accessibility, you may be familiar.
25−This module is intended to be accessible by default. You shouldn't have to wade through docs, articles, and books to find out [exactly how accessible your html actually is](https://www.powermapper.com/tests/screen-readers/aria/index.html).
30−All Elements can be styled on focus by using [`Element.focusStyle`](Element#focusStyle) to set a global focus style or [`Element.focused`](Element#focused) to set a focus style individually for an element.
37@docs button
15@docs button
42−A checkbox requires you to store a `Bool` in your model.
44−This is also the first input element that has a [`required label`](#Label).
46− import Element exposing (text)
47− import Element.Input as Input
50− = GuacamoleChecked Bool
54− { onChange = GuacamoleChecked
55− , icon = Input.defaultCheckbox
56− , checked = model.guacamole
59− (text "Do you want Guacamole?")
62@docs checkbox, defaultCheckbox
17@docs checkbox, defaultCheckbox
65−# Text
20+## Text Input
69−@docs Placeholder, placeholder
72−## Text with autofill
22+@docs text, Placeholder, placeholder
74−If we want to play nicely with a browser's ability to autofill a form, we need to be able to give it a hint about what we're expecting.
24+We can also give a hint about what type of content our text field contains. This will allow things like autofill to work correctly.
76−The following inputs are very similar to `Input.text`, but they give the browser a hint to allow autofill to work correctly.
78@docs username, newPassword, currentPassword, email, search, spellChecked
26@docs username, newPassword, currentPassword, email, search, spellChecked
81−# Sliders
29+## Multiline Text
83−A slider is great for choosing between a range of numerical values.
85− - **thumb** - The icon that you click and drag to change the value.
31+@docs multiline
86− - **track** - The line behind the thumb denoting where you can slide to.
88−@docs slider, Thumb, thumb, defaultThumb
91−# Radio Selection
36+@docs slider, Thumb, thumb, defaultThumb
93−The fact that we still call this a radio selection is fascinating. I can't remember the last time I actually used an honest-to-goodness button on a radio. Chalk it up along with the floppy disk save icon or the word [Dashboard](https://en.wikipedia.org/wiki/Dashboard).
95−Perhaps a better name would be `Input.chooseOne`, because this allows you to select one of a set of options!
97−Nevertheless, here we are. Here's how you put one together
39+## Radio Buttons
103− { onChange = ChooseLunch
104− , selected = Just model.lunch
105− , label = Input.labelAbove [] (text "Lunch")
107− [ Input.option Burrito (text "Burrito")
108− , Input.option Taco (text "Taco!")
109− , Input.option Gyro (text "Gyro")
113−**Note** we're using `Input.option`, which will render the default radio icon you're probably used to. If you want compeltely custom styling, use `Input.optionWith`!
115@docs radio, radioRow, Option, option, optionWith, OptionState
41@docs radio, radioRow, Option, option, optionWith, OptionState
120−Every input has a required `Label`.
122@docs Label, labelAbove, labelBelow, labelLeft, labelRight, labelHidden
46@docs Label, labelAbove, labelBelow, labelLeft, labelRight, labelHidden
124−
48+@docs focusedOnLoad
127−You might be wondering where something like `<form>` is.
129−What I've found is that most people who want `<form>` usually want it for the [implicit submission behavior](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#implicit-submission) or to be clearer, they want to do something when the `Enter` key is pressed.
131−Instead of implicit submission behavior, [try making an `onEnter` event handler like in this Ellie Example](https://ellie-app.com/5X6jBKtxzdpa1). Then everything is explicit!
133−And no one has to look up obtuse html documentation to understand the behavior of their code :).
138−Presently, elm-ui does not expose a replacement for `<input type="file">`; in the meantime, an `Input.button` and `elm/file`'s `File.Select` may meet your needs.
143−You also might be wondering how to disable an input.
145−Disabled inputs can be a little problematic for user experience, and doubly so for accessibility. This is because it's now your priority to inform the user _why_ some field is disabled.
147−If an input is truly disabled, meaning it's not focusable or doesn't send off a `Msg`, you actually lose your ability to help the user out! For those wary about accessibility [this is a big problem.](https://ux.stackexchange.com/questions/103239/should-disabled-elements-be-focusable-for-accessibility-purposes)
149−Here are some alternatives to think about that don't involve explicitly disabling an input.
151−**Disabled Buttons** - Change the `Msg` it fires, the text that is rendered, and optionally set a `Region.description` which will be available to screen readers.
153− import Element.Input as Input
154− import Element.Region as Region
159− [ Background.color blue
162− Just SaveButtonPressed
164− text "Save blog post"
169− [ Background.color grey
170− , Region.description
171− "A publish date is required before saving a blogpost."
174− Just DisabledSaveButtonPressed
179−Consider showing a hint if `DisabledSaveButtonPressed` is sent.
181−For other inputs such as `Input.text`, consider simply rendering it in a normal `paragraph` or `el` if it's not editable.
183−Alternatively, see if it's reasonable to _not_ display an input if you'd normally disable it. Is there an option where it's only visible when it's editable?
@@ -232,33 +97,13 @@ type LabelLocation
100+{-| Every input has a required `label`.
236type Label msg
102type Label msg
237 = Label LabelLocation (List (Attribute msg)) (Element msg)
103 = Label LabelLocation (List (Attribute msg)) (Element msg)
238 | HiddenLabel String
104 | HiddenLabel String
241−isStacked : Label msg -> Bool
263labelRight : List (Attribute msg) -> Element msg -> Label msg
108labelRight : List (Attribute msg) -> Element msg -> Label msg
264labelRight =
109labelRight =
@@ -311,26 +156,16 @@ hiddenLabelAttribute label =
312{-| A standard button.
157{-| A standard button.
314−The `onPress` handler will be fired either `onClick` or when the element is focused and the `Enter` key has been pressed.
159+The `onPress` handler will be fired either `onClick` or when the element is focused and the enter key has been pressed.
316− import Element exposing (rgb255, text)
317− import Element.Background as Background
318 import Element.Input as Input
161 import Element.Input as Input
321− Element.rgb255 238 238 238
324− Input.button
163+ Input.button []
325− [ Background.color blue
327− [ Background.color purple ]
329− { onPress = Just ClickMsg
164+ { onPress = ClickMsg
330− , label = text "My Button"
165+ , label = text "My Button"
333−**Note** If you have an icon button but want it to be accessible, consider adding a [`Region.description`](Element-Region#description), which will describe the button to screen readers.
168+`onPress` takes a `Maybe msg`. If you provide the value `Nothing`, then the button will be disabled.
@@ -369,17 +204,7 @@ button attrs { onPress, label } =
370 Just msg ->
205 Just msg ->
371 Events.onClick msg
206 Events.onClick msg
372− :: onKeyLookup
207+ :: onEnter msg
374− if code == enter then
377− else if code == space then
@@ -412,14 +237,7 @@ type alias Checkbox msg =
417− - **onChange** - The `Msg` to send.
418− - **icon** - The checkbox icon to show. This can be whatever you'd like, but `Input.defaultCheckbox` is included to get you started.
419− - **checked** - The current checked state.
420− - **label** - The [`Label`](#Label) for this checkbox
423checkbox :
241checkbox :
424 List (Attribute msg)
242 List (Attribute msg)
@@ -457,24 +275,22 @@ checkbox attrs { label, icon, checked, onChange } =
460− applyLabel
278+ applyLabel attributes
461− (Internal.Attr (Html.Attributes.attribute "role" "checkbox")
284+ Html.Attributes.attribute "role" "checkbox"
462− :: Internal.Attr
285+ , Internal.Attr <|
463− (Html.Attributes.attribute "aria-checked" <|
286+ Html.Attributes.attribute "aria-checked" <|
464 if checked then
287 if checked then
470− :: hiddenLabelAttribute label
292+ , hiddenLabelAttribute label
477− [ Element.centerY
293+ , Element.centerY
478 , Element.height Element.fill
294 , Element.height Element.fill
479 , Element.width Element.shrink
295 , Element.width Element.shrink
@@ -527,9 +343,7 @@ defaultThumb =
529 { onChange = AdjustValue
345 { onChange = AdjustValue
532− (text "My Slider Value")
346+ , label = Input.labelAbove [] (text "My Slider Value")
533 , min = 0
347 , min = 0
534 , max = 75
348 , max = 75
535 , step = Nothing
349 , step = Nothing
@@ -546,7 +360,7 @@ The slider can be vertical or horizontal depending on the width/height of the sl
546 - `height (px someHeight)` and `width (px someWidth)` where `someHeight` > `someWidth` will also do it.
360 - `height (px someHeight)` and `width (px someWidth)` where `someHeight` > `someWidth` will also do it.
547 - otherwise, the slider will be horizontal.
361 - otherwise, the slider will be horizontal.
549−**Note** If you want a slider for an `Int` value:
363+**Note:** If you want a slider for an `Int` value:
551 - set `step` to be `Just 1`, or some other whole value
365 - set `step` to be `Just 1`, or some other whole value
552 - `value = toFloat model.myInt`
366 - `value = toFloat model.myInt`
@@ -713,7 +527,7 @@ slider attributes input =
713 ("input[type=\"range\"]." ++ className ++ "::-ms-thumb")
527 ("input[type=\"range\"]." ++ className ++ "::-ms-thumb")
714 thumbShadowStyle
528 thumbShadowStyle
716− , Internal.Attr (Html.Attributes.class (className ++ " ui-slide-bar focusable-parent"))
530+ , Internal.Attr (Html.Attributes.class (className ++ " focusable-parent"))
717 , Internal.Attr
531 , Internal.Attr
718 (Html.Events.onInput
532 (Html.Events.onInput
@@ -779,10 +593,10 @@ slider attributes input =
779 -- This is after `attributes` because the thumb should be in front of everything.
593 -- This is after `attributes` because the thumb should be in front of everything.
780 ++ [ Element.behindContent <|
594 ++ [ Element.behindContent <|
781 if vertical then
595 if vertical then
782− viewVerticalThumb factor (Internal.htmlClass "focusable-thumb" :: thumbAttributes) trackWidth
596+ viewVerticalThumb factor thumbAttributes trackWidth
785− viewHorizontalThumb factor (Internal.htmlClass "focusable-thumb" :: thumbAttributes) trackHeight
599+ viewHorizontalThumb factor thumbAttributes trackHeight
788 Element.none
602 Element.none
@@ -863,9 +677,10 @@ textHelper textInput attrs textOptions =
863 defaultTextBoxStyle ++ attrs
677 defaultTextBoxStyle ++ attrs
865 redistributed =
679 redistributed =
866− redistribute (textInput.type_ == TextArea)
680+ redistribute withDefaults
867− (isStacked textOptions.label)
681+
682+ moveUpToCompensateForPadding =
868− withDefaults
683+ calcMoveToCompensateForPadding withDefaults
870 onlySpacing attr =
685 onlySpacing attr =
871 case attr of
686 case attr of
@@ -875,46 +690,35 @@ textHelper textInput attrs textOptions =
878− getPadding attr =
693+ isHeightContent attr =
695+ Internal.Height Internal.Content ->
701+ bottomPadding attr =
879 case attr of
702 case attr of
880 Internal.StyleClass cls (Internal.PaddingStyle pad t r b l) ->
703 Internal.StyleClass cls (Internal.PaddingStyle pad t r b l) ->
881− -- The - 3 is here to prevent accidental triggering of scrollbars
882− -- when things are off by a pixel or two.
883− -- (or at least when the browser *thinks* it's off by a pixel or two)
885− { top = max 0 (floor (t - 3))
706+ { top = 0
886− , right = max 0 (floor (r - 3))
707+ , right = 0
887− , bottom = max 0 (floor (b - 3))
708+ , bottom = b
888− , left = max 0 (floor (l - 3))
709+ , left = 0
894− heightConstrained =
715+ heightContent =
895 case textInput.type_ of
716 case textInput.type_ of
896 TextInputNode inputType ->
717 TextInputNode inputType ->
899 TextArea ->
720 TextArea ->
901− |> List.filterMap getHeight
904− |> Maybe.map isConstrained
905− |> Maybe.withDefault False
908− withDefaults
721+ List.any isHeightContent withDefaults
909− |> List.filterMap getPadding
912− |> Maybe.withDefault
919 inputElement =
723 inputElement =
920 Internal.element
724 Internal.element
@@ -926,63 +730,47 @@ textHelper textInput attrs textOptions =
926 TextArea ->
730 TextArea ->
927 Internal.NodeName "textarea"
731 Internal.NodeName "textarea"
733+ ([ value textOptions.text
734+ , Internal.Attr (Html.Events.onInput textOptions.onChange)
735+ , hiddenLabelAttribute textOptions.label
736+ , spellcheck textInput.spellchecked
737+ , Maybe.map autofill textInput.autofill
738+ |> Maybe.withDefault Internal.NoAttribute
929− ((case textInput.type_ of
740+ ++ (case textInput.type_ of
930− TextInputNode inputType ->
741+ TextInputNode inputType ->
931− -- Note: Due to a weird edgecase in...Edge...
932− -- `type` needs to come _before_ `value`
933− -- More reading: https://github.com/mdgriffith/elm-ui/pull/94/commits/4f493a27001ccc3cf1f2baa82e092c35d3811876
934− [ Internal.Attr (Html.Attributes.type_ inputType)
742+ [ Internal.Attr (Html.Attributes.type_ inputType)
935− , Internal.htmlClass classes.inputText
743+ , Internal.htmlClass classes.inputText
744+ , Internal.htmlClass "focusable"
938− TextArea ->
747+ TextArea ->
939− [ Element.clip
748+ [ Element.clip
940− , Element.height Element.fill
749+ , Element.height Element.fill
941− , Internal.htmlClass classes.inputMultiline
750+ , Internal.htmlClass classes.inputMultiline
942− , calcMoveToCompensateForPadding withDefaults
751+ , Element.alpha 0.3
943−
752+ , moveUpToCompensateForPadding
944− -- The only reason we do this padding trick is so that when the user clicks in the padding,
945− -- that the cursor will reset correctly.
946− -- This could probably be combined with the above `calcMoveToCompensateForPadding`
947− , Element.paddingEach parentPadding
948− , Internal.Attr (Html.Attributes.style "margin" (renderBox (negateBox parentPadding)))
949− , Internal.Attr (Html.Attributes.style "box-sizing" "content-box")
952− ++ [ value textOptions.text
953− , Internal.Attr (Html.Events.onInput textOptions.onChange)
954− , hiddenLabelAttribute textOptions.label
955− , spellcheck textInput.spellchecked
956− , Maybe.map autofill textInput.autofill
957− |> Maybe.withDefault Internal.NoAttribute
959 ++ redistributed.input
755 ++ redistributed.input
961 (Internal.Unkeyed [])
757 (Internal.Unkeyed [])
963 wrappedInput =
759 wrappedInput =
760+ -- if heightContent then
964 case textInput.type_ of
761 case textInput.type_ of
965 TextArea ->
762 TextArea ->
966 -- textarea with height-content means that
763 -- textarea with height-content means that
967− -- the input element is rendered `inFront` with a transparent background
764+ -- the input element is rendered `inFront` and transparently.
968− -- Then the input text is rendered as the space filling element.
765+ -- Then the input text is rendered as the actual element.
969 Internal.element
766 Internal.element
970 Internal.asEl
767 Internal.asEl
971 Internal.div
768 Internal.div
972− ((if heightConstrained then
973− (::) Element.scrollbarY
978− [ Element.width Element.fill
769+ ([ Element.width Element.fill
979− , if List.any hasFocusStyle withDefaults then
770+ , Element.height (Element.px 100)
980− Internal.NoAttribute
771+ , Element.scrollbarY
983− Internal.htmlClass classes.focusedWithin
772+ , Internal.htmlClass classes.focusedWithin
984− , Internal.htmlClass classes.inputMultilineWrapper
986 ++ redistributed.parent
774 ++ redistributed.parent
988 (Internal.Unkeyed
776 (Internal.Unkeyed
@@ -992,33 +780,25 @@ textHelper textInput attrs textOptions =
992 (Element.width Element.fill
780 (Element.width Element.fill
993 :: Element.height Element.fill
781 :: Element.height Element.fill
994 :: Element.inFront inputElement
782 :: Element.inFront inputElement
995− :: Internal.htmlClass classes.inputMultilineParent
783+ :: Internal.htmlClass classes.inputMultiline
996− :: redistributed.wrapper
784+ :: List.concat
997− )
785+ [ if heightContent then
998− (Internal.Unkeyed
786+ redistributed.wrapper
999− (if textOptions.text == "" then
787+
789+ redistributed.wrapper
790+ ++ List.filterMap bottomPadding redistributed.parent
1000− case textOptions.placeholder of
791+ , case textOptions.placeholder of
1001 Nothing ->
792 Nothing ->
1002− -- Without this, firefox will make the text area lose focus
1003− -- if the input is empty and you mash the keyboard
1004− [ Element.text "\u{00A0}"
1007 Just place ->
795 Just place ->
1008− [ renderPlaceholder place
796+ [ renderPlaceholder place redistributed.cover (textOptions.text == "")
1010− (textOptions.text == "")
1014− [ Internal.unstyled
1015− (Html.span [ Html.Attributes.class classes.inputMultilineFiller ]
1016− -- We append a non-breaking space to the end of the content so that newlines don't get chomped.
1017− [ Html.text (textOptions.text ++ "\u{00A0}")
801+ [ Internal.unstyled (Html.text textOptions.text) ]
@@ -1028,12 +808,6 @@ textHelper textInput attrs textOptions =
1028 Internal.asEl
808 Internal.asEl
1029 Internal.div
809 Internal.div
1030 (Element.width Element.fill
810 (Element.width Element.fill
1031− :: (if List.any hasFocusStyle withDefaults then
1032− Internal.NoAttribute
1035− Internal.htmlClass classes.focusedWithin
1037 :: List.concat
811 :: List.concat
1038 [ redistributed.parent
812 [ redistributed.parent
1039 , case textOptions.placeholder of
813 , case textOptions.placeholder of
@@ -1041,8 +815,7 @@ textHelper textInput attrs textOptions =
1043 Just place ->
817 Just place ->
1044− [ Element.behindContent
1045− (renderPlaceholder place redistributed.cover (textOptions.text == ""))
818+ [ renderPlaceholder place redistributed.cover (textOptions.text == "")
@@ -1064,55 +837,29 @@ textHelper textInput attrs textOptions =
1064 wrappedInput
837 wrappedInput
1069− Internal.Height h ->
1077− { top = negate box.top
1078− , right = negate box.right
1079− , bottom = negate box.bottom
1080− , left = negate box.left
1084−renderBox { top, right, bottom, left } =
1087− ++ String.fromInt right
1089− ++ String.fromInt bottom
1091− ++ String.fromInt left
1095renderPlaceholder (Placeholder placeholderAttrs placeholderEl) forPlaceholder on =
840renderPlaceholder (Placeholder placeholderAttrs placeholderEl) forPlaceholder on =
1096− Element.el
841+ Element.inFront
1097− (forPlaceholder
844+ :: forPlaceholder
1098− ++ [ Font.color charcoal
845+ ++ [ Font.color charcoal
1099− , Internal.htmlClass (classes.noTextSelection ++ " " ++ classes.passPointerEvents)
846+ , Internal.htmlClass (classes.noTextSelection ++ " " ++ classes.passPointerEvents)
1101− , Border.color (Element.rgba 0 0 0 0)
847+ , Border.color (Element.rgba 0 0 0 0)
1102− , Background.color (Element.rgba 0 0 0 0)
848+ , Background.color (Element.rgba 0 0 0 0)
1103− , Element.height Element.fill
849+ , Element.height Element.fill
1104− , Element.width Element.fill
850+ , Element.width Element.fill
1105− , Element.alpha
851+ , Element.alpha
1106− (if on then
852+ (if on then
1113− ++ placeholderAttrs
859+ ++ placeholderAttrs
1118{-| Because textareas are now shadowed, where they're rendered twice,
865{-| Because textareas are now shadowed, where they're rendered twice,
@@ -1139,7 +886,7 @@ calcMoveToCompensateForPadding attrs =
1139 Internal.NoAttribute
886 Internal.NoAttribute
1141 Just vSpace ->
888 Just vSpace ->
1142− Element.moveUp (toFloat (floor (toFloat vSpace / 2)))
889+ Element.moveUp (toFloat vSpace / 2)
1145{-| Given the list of attributes provided to `Input.multiline` or `Input.text`,
892{-| Given the list of attributes provided to `Input.multiline` or `Input.text`,
@@ -1154,9 +901,7 @@ redistribute them to the parent, the input, or the cover.
1156redistribute :
903redistribute :
1159− -> List (Attribute msg)
904+ List (Attribute msg)
1161 { fullParent : List (Attribute msg)
906 { fullParent : List (Attribute msg)
1162 , parent : List (Attribute msg)
907 , parent : List (Attribute msg)
@@ -1164,8 +909,8 @@ redistribute :
1164 , input : List (Attribute msg)
909 , input : List (Attribute msg)
1165 , cover : List (Attribute msg)
910 , cover : List (Attribute msg)
1167−redistribute isMultiline stacked attrs =
912+redistribute attrs =
1168− List.foldl (redistributeOver isMultiline stacked)
913+ List.foldl redistributeOver
1169 { fullParent = []
914 { fullParent = []
1170 , parent = []
915 , parent = []
1171 , input = []
916 , input = []
@@ -1183,123 +928,27 @@ redistribute isMultiline stacked attrs =
1191− Internal.Content ->
1197− Internal.Min _ l ->
1200− Internal.Max _ l ->
1206− Internal.Content ->
1215− Internal.Min _ l ->
1218− Internal.Max _ l ->
1224− Internal.Content ->
1233− Internal.Min _ l ->
1236− Internal.Max _ l ->
1242− Internal.Content ->
1251− Internal.Min _ l ->
1254− Internal.Max _ l ->
1258−{-| isStacked means that the label is above or below
1260−redistributeOver isMultiline stacked attr els =
931+redistributeOver attr els =
1261 case attr of
932 case attr of
1262 Internal.Nearby _ _ ->
933 Internal.Nearby _ _ ->
1263 { els | parent = attr :: els.parent }
934 { els | parent = attr :: els.parent }
1265− Internal.Width width ->
936+ Internal.Width (Internal.Fill _) ->
1266− if isFill width then
1268− | fullParent = attr :: els.fullParent
1269− , parent = attr :: els.parent
1270− , input = attr :: els.input
1273− else if stacked then
1275− | fullParent = attr :: els.fullParent
1280− | parent = attr :: els.parent
1283− Internal.Height height ->
1284− if not stacked then
1286− | fullParent = attr :: els.fullParent
937+ { els | fullParent = attr :: els.fullParent }
1287− , parent = attr :: els.parent
1290− else if isFill height then
939+ Internal.Width _ ->
1291− { els
940+ { els | parent = attr :: els.parent }
1292− | fullParent = attr :: els.fullParent
1293− , parent = attr :: els.parent
1296− else if isPixel height then
942+ Internal.Height (Internal.Fill _) ->
944+ | fullParent = attr :: els.fullParent
1297− { els | parent = attr :: els.parent }
945+ , parent = attr :: els.parent
1299− else
948+ Internal.Height h ->
1301− | parent = attr :: els.parent
950+ | parent = attr :: els.parent
1304 Internal.AlignX _ ->
953 Internal.AlignX _ ->
1305 { els | fullParent = attr :: els.fullParent }
954 { els | fullParent = attr :: els.fullParent }
@@ -1315,55 +964,14 @@ redistributeOver isMultiline stacked attr els =
1315 , wrapper = attr :: els.wrapper
964 , wrapper = attr :: els.wrapper
1318− Internal.StyleClass cls (Internal.PaddingStyle pad t r b l) ->
967+ Internal.StyleClass _ (Internal.PaddingStyle _ _ _ _ _) ->
1319− if isMultiline then
1321− | parent = attr :: els.parent
969+ | parent = attr :: els.parent
1322− , cover = attr :: els.cover
1325− else
971+ -- input = attr :: els.input
1326− let
972+ -- , wrapper = attr :: els.wrapper
1327− newHeight =
973+ , cover = attr :: els.cover
1328− Element.htmlAttribute
1329− (Html.Attributes.style
1331− ("calc(1.0em + " ++ String.fromFloat (2 * min t b) ++ "px)")
1335− Element.htmlAttribute
1336− (Html.Attributes.style
1338− ("calc(1.0em + " ++ String.fromFloat (2 * min t b) ++ "px)")
1347− reducedVerticalPadding =
1348− Internal.StyleClass Flag.padding
1349− (Internal.PaddingStyle
1350− (Internal.paddingNameFloat
1363− | parent = reducedVerticalPadding :: els.parent
1364− , input = newHeight :: newLineHeight :: els.input
1365− , cover = attr :: els.cover
1368 Internal.StyleClass _ (Internal.BorderWidth _ _ _ _ _) ->
976 Internal.StyleClass _ (Internal.BorderWidth _ _ _ _ _) ->
@@ -1383,7 +991,7 @@ redistributeOver isMultiline stacked attr els =
1383 Internal.StyleClass _ (Internal.FontFamily _ _) ->
991 Internal.StyleClass _ (Internal.FontFamily _ _) ->
1384 { els | fullParent = attr :: els.fullParent }
992 { els | fullParent = attr :: els.fullParent }
1386− Internal.StyleClass flag cls ->
994+ Internal.StyleClass _ _ ->
1387 { els | parent = attr :: els.parent }
995 { els | parent = attr :: els.parent }
1389 Internal.NoAttribute ->
997 Internal.NoAttribute ->
@@ -1402,6 +1010,30 @@ redistributeOver isMultiline stacked attr els =
1402 { els | input = attr :: els.input }
1010 { els | input = attr :: els.input }
1013+orElse thing maybe =
1022+inheritablePlaceholderAttributes attr =
1024+ Internal.StyleClass _ (Internal.PaddingStyle _ _ _ _ _) ->
1027+ Internal.StyleClass _ (Internal.BorderWidth _ _ _ _ _) ->
1030+ Internal.StyleClass _ (Internal.Transform _) ->
1407 List (Attribute msg)
1039 List (Attribute msg)
@@ -1461,7 +1093,7 @@ search =
1462It's `newPassword` instead of just `password` because it gives the browser a hint on what type of password input it is.
1094It's `newPassword` instead of just `password` because it gives the browser a hint on what type of password input it is.
1464−A password takes all the arguments a normal `Input.text` would, and also **show**, which will remove the password mask (e.g. `****` vs `pass1234`)
1096+A password takes all the arguments a normal `Input.text` would, and also `show`, which will remove the password mask (e.g. `****` vs `pass1234`)
1467newPassword :
1099newPassword :
@@ -1561,13 +1193,7 @@ email =
1564−{-| A multiline text input.
1566−By default it will have a minimum height of one line and resize based on it's contents.
1568−Use `Element.spacing` to change its line-height.
1571multiline :
1197multiline :
1572 List (Attribute msg)
1198 List (Attribute msg)
@@ -1628,32 +1254,33 @@ applyLabel attrs label input =
1628 Internal.element
1254 Internal.element
1629 Internal.asColumn
1255 Internal.asColumn
1630 (Internal.NodeName "label")
1256 (Internal.NodeName "label")
1631− (Internal.htmlClass classes.inputLabel :: attrs)
1257+ attrs
1632 (Internal.Unkeyed [ labelElement, input ])
1258 (Internal.Unkeyed [ labelElement, input ])
1634 Below ->
1260 Below ->
1635 Internal.element
1261 Internal.element
1636 Internal.asColumn
1262 Internal.asColumn
1637 (Internal.NodeName "label")
1263 (Internal.NodeName "label")
1638− (Internal.htmlClass classes.inputLabel :: attrs)
1264+ attrs
1639 (Internal.Unkeyed [ input, labelElement ])
1265 (Internal.Unkeyed [ input, labelElement ])
1641 OnRight ->
1267 OnRight ->
1642 Internal.element
1268 Internal.element
1643 Internal.asRow
1269 Internal.asRow
1644 (Internal.NodeName "label")
1270 (Internal.NodeName "label")
1645− (Internal.htmlClass classes.inputLabel :: attrs)
1271+ attrs
1646 (Internal.Unkeyed [ input, labelElement ])
1272 (Internal.Unkeyed [ input, labelElement ])
1648 OnLeft ->
1274 OnLeft ->
1649 Internal.element
1275 Internal.element
1650 Internal.asRow
1276 Internal.asRow
1651 (Internal.NodeName "label")
1277 (Internal.NodeName "label")
1652− (Internal.htmlClass classes.inputLabel :: attrs)
1278+ attrs
1653 (Internal.Unkeyed [ labelElement, input ])
1279 (Internal.Unkeyed [ labelElement, input ])
1282+{-| Add choices to your radio and select menus.
1657type Option value msg
1284type Option value msg
1658 = Option value (OptionState -> Element msg)
1285 = Option value (OptionState -> Element msg)
@@ -1665,21 +1292,35 @@ type OptionState
1665 | Selected
1292 | Selected
1668−{-| Add a choice to your radio element. This will be rendered with the default radio icon.
1670option : value -> Element msg -> Option value msg
1296option : value -> Element msg -> Option value msg
1671option val txt =
1297option val txt =
1672 Option val (defaultRadioOption txt)
1298 Option val (defaultRadioOption txt)
1675−{-| Customize exactly what your radio option should look like in different states.
1677optionWith : value -> (OptionState -> Element msg) -> Option value msg
1302optionWith : value -> (OptionState -> Element msg) -> Option value msg
1678optionWith val view =
1303optionWith val view =
1679 Option val view
1304 Option val view
1313+ { onChange = ChooseLunch
1314+ , selected = Just model.lunch
1315+ , label = Input.labelAbove [] (text "Lunch")
1317+ [ Input.option Burrito (text "Burrito")
1318+ , Input.option Taco (text "Taco!")
1319+ , Input.option Gyro (text "Gyro")
1684 List (Attribute msg)
1325 List (Attribute msg)
@@ -2105,11 +1746,7 @@ onKeyLookup lookup =
2105 Json.field "key" Json.string
1746 Json.field "key" Json.string
2106 |> Json.andThen decode
1747 |> Json.andThen decode
2108− -- We generally want these attached to the keydown event becaues it allows us to prevent default on things like spacebar scrolling the page.
2109− -- https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/button_role
2110− Internal.Attr <|
1749+ Internal.Attr <| Html.Events.on "keyup" isKey
2111− Html.Events.preventDefaultOn "keydown"
2112− (Json.map (\fired -> ( fired, True )) isKey)
@@ -2124,6 +1761,17 @@ onFocusIn msg =
2124 Internal.Attr <| Html.Events.on "focusin" (Json.succeed msg)
1761 Internal.Attr <| Html.Events.on "focusin" (Json.succeed msg)
1764+type_ : String -> Attribute msg
1766+ Internal.Attr << Html.Attributes.type_
1770+-- checked : Bool -> Attribute msg
1772+-- Internal.Attr << Html.Attributes.checked
2127selected : Bool -> Attribute msg
1775selected : Bool -> Attribute msg
2128selected =
1776selected =
2129 Internal.Attr << Html.Attributes.selected
1777 Internal.Attr << Html.Attributes.selected
@@ -2164,11 +1812,7 @@ autofill =
2164 Internal.Attr << Html.Attributes.attribute "autocomplete"
1812 Internal.Attr << Html.Attributes.attribute "autocomplete"
2167−{-| Attach this attribute to any `Input` that you would like to be automatically focused when the page loads.
2169−You should only have a maximum of one per page.
2172focusedOnLoad : Attribute msg
1816focusedOnLoad : Attribute msg
2173focusedOnLoad =
1817focusedOnLoad =
2174 Internal.Attr <| Html.Attributes.autofocus True
1818 Internal.Attr <| Html.Attributes.autofocus True
@@ -2185,9 +1829,8 @@ defaultTextBoxStyle =
2185 , Border.color darkGrey
1829 , Border.color darkGrey
2186 , Background.color white
1830 , Background.color white
2187 , Border.width 1
1831 , Border.width 1
2188− , Element.spacing 5
1832+ , Element.spacing 3
2189 , Element.width Element.fill
1833 , Element.width Element.fill
2190− , Element.height Element.shrink
@@ -2196,17 +1839,12 @@ defaultTextPadding =
2196 Element.paddingXY 12 12
1839 Element.paddingXY 12 12
2199−{-| The blue default checked box icon.
2201−You'll likely want to make your own checkbox at some point that fits your design.
2204defaultCheckbox : Bool -> Element msg
1843defaultCheckbox : Bool -> Element msg
2205defaultCheckbox checked =
1844defaultCheckbox checked =
2206 Element.el
1845 Element.el
2207 [ Internal.htmlClass "focusable"
1846 [ Internal.htmlClass "focusable"
2208− , Element.width
1847+ , Element.width (Element.px 14)
2210 , Element.height (Element.px 14)
1848 , Element.height (Element.px 14)
2211 , Font.color white
1849 , Font.color white
2212 , Element.centerY
1850 , Element.centerY
@@ -2219,7 +1857,7 @@ defaultCheckbox checked =
2221 Element.rgb (211 / 255) (211 / 255) (211 / 255)
1859 Element.rgb (211 / 255) (211 / 255) (211 / 255)
2222− , Border.shadow
1860+ , Border.shadow <|
2223 { offset = ( 0, 0 )
1861 { offset = ( 0, 0 )
2224 , blur = 1
1862 , blur = 1
2225 , size = 1
1863 , size = 1
@@ -2242,8 +1880,9 @@ defaultCheckbox checked =
2245− , Element.inFront
1883+ ]
2246− (Element.el
1885+ Element.el
2247 [ Border.color white
1886 [ Border.color white
2248 , Element.height (Element.px 6)
1887 , Element.height (Element.px 6)
2249 , Element.width (Element.px 9)
1888 , Element.width (Element.px 9)
@@ -2251,7 +1890,6 @@ defaultCheckbox checked =
2251 , Element.centerX
1890 , Element.centerX
2252 , Element.centerY
1891 , Element.centerY
2253 , Element.moveUp 1
1892 , Element.moveUp 1
2254− , Element.transparent (not checked)
2255 , Border.widthEach
1893 , Border.widthEach
2256 { top = 0
1894 { top = 0
2257 , left = 2
1895 , left = 2
@@ -2260,6 +1898,7 @@ defaultCheckbox checked =
2262 Element.none
1900 Element.none
2265− Element.none
1903+ Element.none