git.iko.soy/typeable/elm-ui
on master help sign in
Merge remote-tracking branch 'mdgriffith/master'
commitb0607654479ce16ca5b0c7056c5459c96cde77ff authorTom Stejskal <tom.stejskal@gmail.com> dateSat 22 Jun 2019, 07:25 (7 years ago) parent87484092b3a972
6 files changed+489−317
cases/elm.json+25 cases/open/MultilineInput.elm+89 src/Element.elm+21−7 src/Element/Input.elm+316−301 src/Internal/Model.elm+34−9 src/Internal/Style.elm+4
cases/elm.jsonnew file+25
@@ -0,0 +1,25 @@
1+{
2+ "type": "application",
3+ "source-directories": [
4+ "open",
5+ "../src/"
6+ ],
7+ "elm-version": "0.19.0",
8+ "dependencies": {
9+ "direct": {
10+ "elm/browser": "1.0.0",
11+ "elm/core": "1.0.0",
12+ "elm/html": "1.0.0",
13+ "elm/json": "1.0.0",
14+ "elm/virtual-dom": "1.0.0"
15+ },
16+ "indirect": {
17+ "elm/time": "1.0.0",
18+ "elm/url": "1.0.0"
19+ }
20+ },
21+ "test-dependencies": {
22+ "direct": {},
23+ "indirect": {}
24+ }
25+}
cases/open/MultilineInput.elmnew file+89
@@ -0,0 +1,89 @@
1+module Main exposing (main)
2+
3+import Browser
4+import Element exposing (..)
5+import Element.Input exposing (labelLeft, multiline)
6+import Html exposing (Html)
7+import Html.Events exposing (onClick)
8+
9+
10+type alias Model =
11+ { count : Int }
12+
13+
14+initialModel : Model
15+initialModel =
16+ { count = 0 }
17+
18+
19+type Msg
20+ = Increment
21+ | Decrement
22+ | MLChanged String
23+
24+
25+update : Msg -> Model -> Model
26+update msg model =
27+ case msg of
28+ Increment ->
29+ { model | count = model.count + 1 }
30+
31+ Decrement ->
32+ { model | count = model.count - 1 }
33+
34+ MLChanged s ->
35+ model
36+
37+
38+testtxt =
39+ "orem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. Why do we use it?"
40+
41+
42+testtxtnewlines =
43+ """orem Ipsum is simply dummy text of the printing
44+and typesetting industry. Lorem Ipsum has been the industry's
45+standard dummy text ever since the 1500s, when an unknown
46+printer took a galley of type and scrambled it to make a type specimen book.
47+It has survived not only five centuries, but also the leap into electronic
48+typesetting
49+, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. Why do we use it?"""
50+
51+
52+view : Model -> Html Msg
53+view model =
54+ layout [] <|
55+ column
56+ [ width (px 500)
57+ , spacing 50
58+ ]
59+ [ multiline []
60+ { onChange = MLChanged
61+ , text = testtxt
62+ , placeholder = Nothing
63+ , spellcheck = False
64+ , label = labelLeft [ width (px 200) ] <| text "Default height"
65+ }
66+ , multiline [ height shrink ]
67+ { onChange = MLChanged
68+ , text = testtxt
69+ , placeholder = Nothing
70+ , spellcheck = False
71+ , label = labelLeft [ width (px 200) ] <| text "Shrink - no nl"
72+ }
73+ , multiline [ height shrink ]
74+ { onChange = MLChanged
75+ , text = testtxtnewlines
76+ , placeholder = Nothing
77+ , spellcheck = False
78+ , label = labelLeft [ width (px 200) ] <| text "Shrink - w/nl"
79+ }
80+ ]
81+
82+
83+main : Program () Model Msg
84+main =
85+ Browser.sandbox
86+ { init = initialModel
87+ , view = view
88+ , update = update
89+ }
src/Element.elm+21−7
@@ -1226,28 +1226,42 @@ downloadAs attrs { url, filename, label } =
12261226 (Internal.Unkeyed [ label ])
12271227
12281228
1229+
1230+{- NEARBYS -}
1231+
1232+
1233+createNearby : Internal.Location -> Element msg -> Attribute msg
1234+createNearby loc element =
1235+ case element of
1236+ Internal.Empty ->
1237+ Internal.NoAttribute
1238+
1239+ _ ->
1240+ Internal.Nearby loc element
1241+
1242+
12291243{-| -}
12301244below : Element msg -> Attribute msg
12311245below element =
1232− Internal.Nearby Internal.Below element
1246+ createNearby Internal.Below element
12331247
12341248
12351249{-| -}
12361250above : Element msg -> Attribute msg
12371251above element =
1238− Internal.Nearby Internal.Above element
1252+ createNearby Internal.Above element
12391253
12401254
12411255{-| -}
12421256onRight : Element msg -> Attribute msg
12431257onRight element =
1244− Internal.Nearby Internal.OnRight element
1258+ createNearby Internal.OnRight element
12451259
12461260
12471261{-| -}
12481262onLeft : Element msg -> Attribute msg
12491263onLeft element =
1250− Internal.Nearby Internal.OnLeft element
1264+ createNearby Internal.OnLeft element
12511265
12521266
12531267{-| This will place an element in front of another.
@@ -1257,14 +1271,14 @@ onLeft element =
12571271-}
12581272inFront : Element msg -> Attribute msg
12591273inFront element =
1260− Internal.Nearby Internal.InFront element
1274+ createNearby Internal.InFront element
12611275
12621276
12631277{-| This will place an element between the background and the content of an element.
12641278-}
12651279behindContent : Element msg -> Attribute msg
12661280behindContent element =
1267− Internal.Nearby Internal.Behind element
1281+ createNearby Internal.Behind element
12681282
12691283
12701284{-| -}
@@ -1285,7 +1299,7 @@ scale n =
12851299 Internal.TransformComponent Flag.scale (Internal.Scale ( n, n, 1 ))
12861300
12871301
1288−{-| Angle is given in radians. [Here are some conversion functions if you want another unit.](https://package.elm-lang.org/packages/elm/core/latest/Basics#degrees)
1302+{-| Angle is given in radians. [Here are some conversion functions if you want to use another unit.](https://package.elm-lang.org/packages/elm/core/latest/Basics#degrees)
12891303-}
12901304rotate : Float -> Attr decorative msg
12911305rotate angle =
src/Element/Input.elm+316−301
@@ -669,304 +669,157 @@ type alias Text msg =
669669 }
670670
671671
672−type Padding
673− = Padding Int Int Int Int
674−
675−
676−inheritablePlaceholderAttributes attr =
677− case attr of
678− Internal.StyleClass _ (Internal.PaddingStyle _ _ _ _ _) ->
679− True
680−
681− Internal.StyleClass _ (Internal.BorderWidth _ _ _ _ _) ->
682− True
683−
684− Internal.StyleClass _ (Internal.Transform _) ->
685− True
686−
687− _ ->
688− False
689−
690−
691−{-|
692−
693− attributes
694−
695− <parent>
696− attribute::width/height fill
697− attribtue::alignment
698− attribute::spacing
699− attribute::fontsize/family/lineheight
700− <el-wrapper>
701− attribute::nearby(placeholder)
702− attribute::width/height fill
703− inFront ->
704− placeholder
705− attribute::padding
706−
707−
708− <input>
709− textarea ->
710− special height for height-content
711− attribtue::padding
712− attribute::lineHeight
713− attributes
714− <label>
715−
716−-}
672+{-| -}
717673textHelper : TextInput -> List (Attribute msg) -> Text msg -> Element msg
718674textHelper textInput attrs textOptions =
719675 let
720− attributes =
676+ withDefaults =
721677 defaultTextBoxStyle ++ attrs
722678
723− behavior =
724− [ Internal.Attr (Html.Events.onInput textOptions.onChange) ]
679+ redistributed =
680+ redistribute withDefaults
725681
726− forPlaceholder =
727− List.filter inheritablePlaceholderAttributes attributes
682+ moveUpToCompensateForPadding =
683+ calcMoveToCompensateForPadding withDefaults
728684
729− noNearbys =
730− List.filter (not << forNearby) attributes
731−
732− forNearby attr =
685+ onlySpacing attr =
733686 case attr of
734− Internal.Nearby _ _ ->
687+ Internal.StyleClass _ (Internal.SpacingStyle _ _ _) ->
735688 True
736689
737690 _ ->
738691 False
739692
740− ( inputNode, inputAttrs, inputChildren ) =
741− case textInput.type_ of
742− TextInputNode inputType ->
743− ( "input"
744− , [ Internal.Attr (Html.Attributes.type_ inputType)
745− , value textOptions.text
746− , spellcheck textInput.spellchecked
747− , Internal.htmlClass classes.inputText
748− , case textInput.autofill of
749− Nothing ->
750− Internal.NoAttribute
751−
752− Just fill ->
753− autofill fill
754− ]
755− ++ noNearbys
756− , []
757− )
758−
759− TextArea ->
760− let
761− { maybePadding, heightContent, maybeSpacing, adjustedAttributes, maybeBorder } =
762− (value textOptions.text :: attributes)
763− |> List.foldr
764− (\attr found ->
765− case attr of
766− Internal.Describe _ ->
767− found
768−
769− Internal.Height len ->
770− case found.heightContent of
771− Nothing ->
772− { found
773− | heightContent = Just (Internal.isContent len)
774− , adjustedAttributes = attr :: found.adjustedAttributes
775− }
776−
777− _ ->
778− found
779−
780− Internal.StyleClass _ (Internal.BorderWidth _ t r b l) ->
781− case found.maybeBorder of
782− Nothing ->
783− { found
784− | maybeBorder = Just (Padding t r b l)
785− , adjustedAttributes = attr :: found.adjustedAttributes
786− }
787−
788− _ ->
789− found
790−
791− Internal.StyleClass _ (Internal.PaddingStyle _ t r b l) ->
792− case found.maybePadding of
793− Nothing ->
794− { found
795− | maybePadding = Just (Padding t r b l)
796−
797− -- Skip storing padding because it's being customized later
798− , adjustedAttributes = found.adjustedAttributes
799− }
800−
801− _ ->
802− found
803−
804− Internal.StyleClass _ (Internal.SpacingStyle _ x y) ->
805− case found.maybeSpacing of
806− Nothing ->
807− { found
808− | maybeSpacing = Just y
809− , adjustedAttributes = attr :: found.adjustedAttributes
810− }
811−
812− _ ->
813− found
814−
815− _ ->
816− { found | adjustedAttributes = attr :: found.adjustedAttributes }
817− )
818− { maybePadding = Nothing
819− , heightContent = Nothing
820− , maybeBorder = Nothing
821− , maybeSpacing = Nothing
822− , adjustedAttributes = []
823− }
824−
825− -- NOTE: This is where default text spacing is set
826− spacing =
827− Maybe.withDefault 5 maybeSpacing
828− in
829− ( "textarea"
830− , [ spellcheck textInput.spellchecked
831− , Internal.htmlClass classes.inputMultiline
832− , Maybe.map autofill textInput.autofill
833− |> Maybe.withDefault Internal.NoAttribute
834− , case maybePadding of
835− Nothing ->
836− Internal.NoAttribute
837−
838− Just (Padding t r b l) ->
839− Element.paddingEach
840− { top = max 0 (t - (spacing // 2))
841− , bottom = max 0 (b - (spacing // 2))
842− , left = l
843− , right = r
844− }
845− , case heightContent of
846− Nothing ->
847− Internal.NoAttribute
848−
849− Just True ->
850− textHeightContent textOptions.text spacing maybePadding maybeBorder
851−
852− Just False ->
853− Internal.NoAttribute
854− ]
855− ++ adjustedAttributes
856− , []
857− )
858−
859− heightFillFromChild =
860− Internal.get attributes <|
861− \attr ->
862− case attr of
863− Internal.Height (Internal.Fill _) ->
864− True
865−
866− _ ->
867− False
868−
869− attributesFromChild =
870− Internal.get attributes <|
871− \attr ->
872− case attr of
873− Internal.Width (Internal.Fill _) ->
874− True
875−
876− Internal.Height (Internal.Fill _) ->
877− True
878−
879− Internal.AlignX _ ->
880− True
881−
882− Internal.AlignY _ ->
883− True
884−
885− Internal.StyleClass _ (Internal.SpacingStyle _ _ _) ->
886− True
887−
888− Internal.StyleClass _ (Internal.FontSize _) ->
889− True
890−
891− Internal.StyleClass _ (Internal.FontFamily _ _) ->
892− True
693+ isHeightContent attr =
694+ case attr of
695+ Internal.Height Internal.Content ->
696+ True
893697
894− _ ->
895− False
698+ _ ->
699+ False
896700
897− nearbys =
898− Internal.get attributes <|
899− \attr ->
900− case attr of
901− Internal.Nearby _ _ ->
902− True
701+ bottomPadding attr =
702+ case attr of
703+ Internal.StyleClass cls (Internal.PaddingStyle pad t r b l) ->
704+ Just <|
705+ Element.paddingEach
706+ { top = 0
707+ , right = 0
708+ , bottom = b
709+ , left = 0
710+ }
903711
904− _ ->
905− False
712+ _ ->
713+ Nothing
906714
907− inputPadding =
908− Internal.get attributes <|
909− \attr ->
910− case attr of
911− Internal.StyleClass _ (Internal.PaddingStyle _ _ _ _ _) ->
912− True
715+ heightContent =
716+ case textInput.type_ of
717+ TextInputNode inputType ->
718+ False
913719
914− _ ->
915− False
720+ TextArea ->
721+ List.any isHeightContent withDefaults
916722
917723 inputElement =
918724 Internal.element
919725 Internal.asEl
920− Internal.div
921− (Element.width Element.fill
922− :: List.concat
923− [ nearbys
924− , heightFillFromChild
925− , case textOptions.placeholder of
926− Nothing ->
927− []
928−
929− Just (Placeholder placeholderAttrs placeholderEl) ->
930− [ Element.inFront
931− (Element.el
932− (defaultTextPadding
933− :: forPlaceholder
934− ++ [ Font.color charcoal
935− , Internal.htmlClass (classes.noTextSelection ++ " " ++ classes.passPointerEvents)
936− , Border.color (Element.rgba 0 0 0 0)
937− , Background.color (Element.rgba 0 0 0 0)
938− , Element.height Element.fill
939− , Element.width Element.fill
940− , Element.alpha
941− (if textOptions.text == "" then
942− 1
943−
944− else
945− 0
946− )
947− ]
948− ++ placeholderAttrs
949− )
950− placeholderEl
951− )
726+ (case textInput.type_ of
727+ TextInputNode inputType ->
728+ Internal.NodeName "input"
729+
730+ TextArea ->
731+ Internal.NodeName "textarea"
732+ )
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
739+ ]
740+ ++ (case textInput.type_ of
741+ TextInputNode inputType ->
742+ [ Internal.Attr (Html.Attributes.type_ inputType)
743+ , Internal.htmlClass classes.inputText
744+ , Internal.htmlClass "focusable"
745+ ]
746+
747+ TextArea ->
748+ [ Element.clip
749+ , Element.height Element.fill
750+ , Internal.htmlClass classes.inputMultiline
751+ , Element.alpha 0.3
752+ , moveUpToCompensateForPadding
952753 ]
953− ]
754+ )
755+ ++ redistributed.input
954756 )
955− (Internal.Unkeyed
956− [ Internal.element
757+ (Internal.Unkeyed [])
758+
759+ wrappedInput =
760+ -- if heightContent then
761+ case textInput.type_ of
762+ TextArea ->
763+ -- textarea with height-content means that
764+ -- the input element is rendered `inFront` and transparently.
765+ -- Then the input text is rendered as the actual element.
766+ Internal.element
957767 Internal.asEl
958− (Internal.NodeName inputNode)
959− (List.concat
960− [ [ focusDefault attrs
961− , hiddenLabelAttribute textOptions.label
962− ]
963− , inputAttrs
964− , behavior
768+ Internal.div
769+ ([ Element.width Element.fill
770+ , Element.height (Element.px 100)
771+ , Element.scrollbarY
772+ , Internal.htmlClass classes.focusedWithin
773+ ]
774+ ++ redistributed.parent
775+ )
776+ (Internal.Unkeyed
777+ [ Internal.element
778+ Internal.asParagraph
779+ Internal.div
780+ (Element.width Element.fill
781+ :: Element.height Element.fill
782+ :: Element.inFront inputElement
783+ :: Internal.htmlClass classes.inputMultiline
784+ :: List.concat
785+ [ if heightContent then
786+ redistributed.wrapper
787+
788+ else
789+ redistributed.wrapper
790+ ++ List.filterMap bottomPadding redistributed.parent
791+ , case textOptions.placeholder of
792+ Nothing ->
793+ []
794+
795+ Just place ->
796+ [ renderPlaceholder place redistributed.cover (textOptions.text == "")
797+ ]
798+ ]
799+ )
800+ (Internal.Unkeyed
801+ [ Internal.unstyled (Html.text textOptions.text) ]
802+ )
965803 ]
966804 )
967− (Internal.Unkeyed inputChildren)
968− ]
969− )
805+
806+ TextInputNode inputType ->
807+ Internal.element
808+ Internal.asEl
809+ Internal.div
810+ (Element.width Element.fill
811+ :: List.concat
812+ [ redistributed.parent
813+ , case textOptions.placeholder of
814+ Nothing ->
815+ []
816+
817+ Just place ->
818+ [ renderPlaceholder place redistributed.cover (textOptions.text == "")
819+ ]
820+ ]
821+ )
822+ (Internal.Unkeyed [ inputElement ])
970823 in
971824 applyLabel
972825 (Internal.Class Flag.cursor classes.cursorText
@@ -978,45 +831,207 @@ textHelper textInput attrs textOptions =
978831 5
979832 )
980833 :: Region.announce
981− :: attributesFromChild
834+ :: redistributed.fullParent
982835 )
983836 textOptions.label
984− inputElement
837+ wrappedInput
838+
839+
840+renderPlaceholder (Placeholder placeholderAttrs placeholderEl) forPlaceholder on =
841+ Element.inFront
842+ (Element.el
843+ (defaultTextPadding
844+ :: forPlaceholder
845+ ++ [ Font.color charcoal
846+ , Internal.htmlClass (classes.noTextSelection ++ " " ++ classes.passPointerEvents)
847+ , Border.color (Element.rgba 0 0 0 0)
848+ , Background.color (Element.rgba 0 0 0 0)
849+ , Element.height Element.fill
850+ , Element.width Element.fill
851+ , Element.alpha
852+ (if on then
853+ 1
854+
855+ else
856+ 0
857+ )
858+ ]
859+ ++ placeholderAttrs
860+ )
861+ placeholderEl
862+ )
985863
986864
987−textHeightContent textValue spacing maybePadding maybeBorder =
865+{-| Because textareas are now shadowed, where they're rendered twice,
866+we to move the literal text area up because spacing is based on line height.
867+-}
868+calcMoveToCompensateForPadding : List (Attribute msg) -> Attribute msg
869+calcMoveToCompensateForPadding attrs =
988870 let
989− newlineCount =
990− String.lines textValue
991− |> List.length
992− |> (\x ->
993− if x < 1 then
994− 1
871+ gatherSpacing attr found =
872+ case attr of
873+ Internal.StyleClass _ (Internal.SpacingStyle _ x y) ->
874+ case found of
875+ Nothing ->
876+ Just y
995877
996− else
997− x
998− )
878+ _ ->
879+ found
999880
1000− topBottom (Padding t _ b _) =
1001− t + b
881+ _ ->
882+ found
883+ in
884+ case List.foldr gatherSpacing Nothing attrs of
885+ Nothing ->
886+ Internal.NoAttribute
1002887
1003− additionalSpacing =
1004− ((newlineCount - 1) * spacing)
1005− + Maybe.withDefault 0 (Maybe.map topBottom maybePadding)
1006− + Maybe.withDefault 0 (Maybe.map topBottom maybeBorder)
888+ Just vSpace ->
889+ Element.moveUp (toFloat vSpace / 2)
1007890
1008− heightValue count =
1009− "calc("
1010− ++ String.fromInt count
1011− ++ "em + "
1012− ++ String.fromInt additionalSpacing
1013− ++ "px) !important"
1014− in
1015− Internal.StyleClass Flag.heightTextAreaContent
1016− (Internal.Single ("textarea-height-" ++ String.fromInt newlineCount)
1017− "height"
1018− (heightValue newlineCount)
1019− )
891+
892+{-| Given the list of attributes provided to `Input.multiline` or `Input.text`,
893+
894+redistribute them to the parent, the input, or the cover.
895+
896+ - fullParent -> Wrapper around label and input
897+ - parent -> parent of wrapper
898+ - wrapper -> the element that is here to take up space.
899+ - cover -> things like placeholders or text areas which are layered on top of input.
900+ - input -> actual input element
901+
902+-}
903+redistribute :
904+ List (Attribute msg)
905+ ->
906+ { fullParent : List (Attribute msg)
907+ , parent : List (Attribute msg)
908+ , wrapper : List (Attribute msg)
909+ , input : List (Attribute msg)
910+ , cover : List (Attribute msg)
911+ }
912+redistribute attrs =
913+ List.foldl redistributeOver
914+ { fullParent = []
915+ , parent = []
916+ , input = []
917+ , cover = []
918+ , wrapper = []
919+ }
920+ attrs
921+ |> (\redist ->
922+ { parent = List.reverse redist.parent
923+ , fullParent = List.reverse redist.fullParent
924+ , wrapper = List.reverse redist.wrapper
925+ , input = List.reverse redist.input
926+ , cover = List.reverse redist.cover
927+ }
928+ )
929+
930+
931+redistributeOver attr els =
932+ case attr of
933+ Internal.Nearby _ _ ->
934+ { els | parent = attr :: els.parent }
935+
936+ Internal.Width (Internal.Fill _) ->
937+ { els | fullParent = attr :: els.fullParent }
938+
939+ Internal.Width _ ->
940+ { els | parent = attr :: els.parent }
941+
942+ Internal.Height (Internal.Fill _) ->
943+ { els
944+ | fullParent = attr :: els.fullParent
945+ , parent = attr :: els.parent
946+ }
947+
948+ Internal.Height h ->
949+ { els
950+ | parent = attr :: els.parent
951+ }
952+
953+ Internal.AlignX _ ->
954+ { els | fullParent = attr :: els.fullParent }
955+
956+ Internal.AlignY _ ->
957+ { els | fullParent = attr :: els.fullParent }
958+
959+ Internal.StyleClass _ (Internal.SpacingStyle _ _ _) ->
960+ { els
961+ | fullParent = attr :: els.fullParent
962+ , parent = attr :: els.parent
963+ , input = attr :: els.input
964+ , wrapper = attr :: els.wrapper
965+ }
966+
967+ Internal.StyleClass _ (Internal.PaddingStyle _ _ _ _ _) ->
968+ { els
969+ | parent = attr :: els.parent
970+
971+ -- input = attr :: els.input
972+ -- , wrapper = attr :: els.wrapper
973+ , cover = attr :: els.cover
974+ }
975+
976+ Internal.StyleClass _ (Internal.BorderWidth _ _ _ _ _) ->
977+ { els
978+ | parent = attr :: els.parent
979+ , cover = attr :: els.cover
980+ }
981+
982+ Internal.StyleClass _ (Internal.Transform _) ->
983+ { els
984+ | parent = attr :: els.parent
985+ , cover = attr :: els.cover
986+ }
987+
988+ Internal.StyleClass _ (Internal.FontSize _) ->
989+ { els | fullParent = attr :: els.fullParent }
990+
991+ Internal.StyleClass _ (Internal.FontFamily _ _) ->
992+ { els | fullParent = attr :: els.fullParent }
993+
994+ Internal.StyleClass _ _ ->
995+ { els | parent = attr :: els.parent }
996+
997+ Internal.NoAttribute ->
998+ els
999+
1000+ Internal.Attr a ->
1001+ { els | input = attr :: els.input }
1002+
1003+ Internal.Describe _ ->
1004+ { els | input = attr :: els.input }
1005+
1006+ Internal.Class _ _ ->
1007+ { els | parent = attr :: els.parent }
1008+
1009+ Internal.TransformComponent _ _ ->
1010+ { els | input = attr :: els.input }
1011+
1012+
1013+orElse thing maybe =
1014+ case maybe of
1015+ Nothing ->
1016+ Just thing
1017+
1018+ _ ->
1019+ maybe
1020+
1021+
1022+inheritablePlaceholderAttributes attr =
1023+ case attr of
1024+ Internal.StyleClass _ (Internal.PaddingStyle _ _ _ _ _) ->
1025+ True
1026+
1027+ Internal.StyleClass _ (Internal.BorderWidth _ _ _ _ _) ->
1028+ True
1029+
1030+ Internal.StyleClass _ (Internal.Transform _) ->
1031+ True
1032+
1033+ _ ->
1034+ False
10201035
10211036
10221037{-| -}
src/Internal/Model.elm+34−9
@@ -83,8 +83,7 @@ module Internal.Model exposing
8383 , reduceRecursive
8484 , reduceStyles
8585 , reduceStylesRecursive
86− , removeNever
87− , renderFocusStyle
86+ , removeNever
8887 -- , renderFont
8988
9089 , renderFontClassName
@@ -537,7 +536,7 @@ embedWith static opts styles children =
537536 if static then
538537 staticRoot
539538 :: (styles
540− |> List.foldl reduceStyles ( Set.empty, [ renderFocusStyle opts.focus ] )
539+ |> List.foldl reduceStyles ( Set.empty, renderFocusStyle opts.focus )
541540 |> Tuple.second
542541 -- |> reduceStylesRecursive Set.empty [ ]) --renderFocusStyle opts.focus ]
543542 -- |> sortedReduce
@@ -547,7 +546,7 @@ embedWith static opts styles children =
547546
548547 else
549548 (styles
550− |> List.foldl reduceStyles ( Set.empty, [ renderFocusStyle opts.focus ] )
549+ |> List.foldl reduceStyles ( Set.empty, renderFocusStyle opts.focus )
551550 |> Tuple.second
552551 -- |> reduceStylesRecursive Set.empty [ ]) --renderFocusStyle opts.focus ]
553552 -- |> sortedReduce
@@ -561,7 +560,7 @@ embedKeyed static opts styles children =
561560 ( "static-stylesheet", staticRoot )
562561 :: ( "dynamic-stylesheet"
563562 , styles
564− |> List.foldl reduceStyles ( Set.empty, [ renderFocusStyle opts.focus ] )
563+ |> List.foldl reduceStyles ( Set.empty, renderFocusStyle opts.focus )
565564 |> Tuple.second
566565 -- |> reduceStylesRecursive Set.empty [ ]) --renderFocusStyle opts.focus ]
567566 -- |> sortedReduce
@@ -572,7 +571,7 @@ embedKeyed static opts styles children =
572571 else
573572 ( "dynamic-stylesheet"
574573 , styles
575− |> List.foldl reduceStyles ( Set.empty, [ renderFocusStyle opts.focus ] )
574+ |> List.foldl reduceStyles ( Set.empty, renderFocusStyle opts.focus )
576575 |> Tuple.second
577576 -- |> reduceStylesRecursive Set.empty [ ]) --renderFocusStyle opts.focus ]
578577 -- |> sortedReduce
@@ -2206,9 +2205,34 @@ renderFontClassName font current =
22062205
22072206renderFocusStyle :
22082207 FocusStyle
2209− -> Style
2208+ -> List Style
22102209renderFocusStyle focus =
2211− Style (Internal.Style.dot classes.any ++ ":focus .focusable, " ++ Internal.Style.dot classes.any ++ ".focusable:focus")
2210+ [ Style (Internal.Style.dot classes.focusedWithin ++ ":focus-within")
2211+ (List.filterMap identity
2212+ [ Maybe.map (\color -> Property "border-color" (formatColor color)) focus.borderColor
2213+ , Maybe.map (\color -> Property "background-color" (formatColor color)) focus.backgroundColor
2214+ , Maybe.map
2215+ (\shadow ->
2216+ Property "box-shadow"
2217+ (formatBoxShadow
2218+ { color = shadow.color
2219+ , offset =
2220+ shadow.offset
2221+ |> Tuple.mapFirst toFloat
2222+ |> Tuple.mapSecond toFloat
2223+ , inset = False
2224+ , blur =
2225+ toFloat shadow.blur
2226+ , size =
2227+ toFloat shadow.size
2228+ }
2229+ )
2230+ )
2231+ focus.shadow
2232+ , Just <| Property "outline" "none"
2233+ ]
2234+ )
2235+ , Style (Internal.Style.dot classes.any ++ ":focus .focusable, " ++ Internal.Style.dot classes.any ++ ".focusable:focus")
22122236 (List.filterMap identity
22132237 [ Maybe.map (\color -> Property "border-color" (formatColor color)) focus.borderColor
22142238 , Maybe.map (\color -> Property "background-color" (formatColor color)) focus.backgroundColor
@@ -2231,6 +2255,7 @@ renderFocusStyle focus =
22312255 , Just <| Property "outline" "none"
22322256 ]
22332257 )
2258+ ]
22342259
22352260
22362261focusDefaultStyle : { backgroundColor : Maybe Color, borderColor : Maybe Color, shadow : Maybe Shadow }
@@ -2242,7 +2267,7 @@ focusDefaultStyle =
22422267 { color =
22432268 Rgba (155 / 255) (203 / 255) 1 1
22442269 , offset = ( 0, 0 )
2245− , blur = 3
2270+ , blur = 0
22462271 , size = 3
22472272 }
22482273 }
src/Internal/Style.elm+4
@@ -204,6 +204,7 @@ classes =
204204
205205 -- , hoverOpaque = "hover-opaque"
206206 , focus = "fcs"
207+ , focusedWithin = "focus-within"
207208
208209 -- , focusOpaque = "focus-opaque"
209210 , active = "atv"
@@ -1522,6 +1523,9 @@ baseSheet =
15221523 ]
15231524 , Descriptor (dot classes.inputMultiline)
15241525 [ Prop "white-space" "pre-wrap"
1526+ , Descriptor (dot classes.paragraph)
1527+ [ Prop "white-space" "pre-wrap"
1528+ ]
15251529 ]
15261530 , Descriptor (dot classes.paragraph)
15271531 [ Prop "display" "block"