@@ -1,4 +1,109 @@
1−module Internal.Model exposing (..)
1+module Internal.Model exposing
30+ , TransformComponent(..)
47+ , composeTransformation
55+ , extractSpacingAndPadding
65+ , gatherAttrRecursive
87+ , reduceStylesRecursive
89+ , renderFontClassName
@@ -7,7 +112,7 @@ import Html.Attributes
7import Html.Keyed
112import Html.Keyed
8import Internal.Flag as Flag exposing (Flag)
113import Internal.Flag as Flag exposing (Flag)
9import Internal.Style exposing (classes, dot)
114import Internal.Style exposing (classes, dot)
10−import Json.Encode as Json
115+import Json.Encode as Encode
11import Set exposing (Set)
116import Set exposing (Set)
12import VirtualDom
117import VirtualDom
@@ -68,7 +173,8 @@ type Style
68 | Single String String String
173 | Single String String String
69 | Colored String String Color
174 | Colored String String Color
70 | SpacingStyle String Int Int
175 | SpacingStyle String Int Int
176+ | BorderWidth String Int Int Int Int
71− | PaddingStyle String Int Int Int Int
177+ | PaddingStyle String Float Float Float Float
72 | GridTemplateStyle
178 | GridTemplateStyle
73 { spacing : ( Length, Length )
179 { spacing : ( Length, Length )
74 , columns : List Length
180 , columns : List Length
@@ -99,12 +205,86 @@ type PseudoClass
209+type alias Adjustment =
104 | SansSerif
219 | SansSerif
105 | Monospace
220 | Monospace
106 | Typeface String
221 | Typeface String
107 | ImportFont String String
222 | ImportFont String String
225+ , adjustment : Maybe Adjustment
226+ , variants : List Variant
231+ = VariantActive String
233+ | VariantIndexed String Int
238+ VariantActive name ->
239+ "\"" ++ name ++ "\""
242+ "\"" ++ name ++ "\" 0"
244+ VariantIndexed name index ->
245+ "\"" ++ name ++ "\" " ++ String.fromInt index
250+ VariantActive name ->
256+ VariantIndexed name index ->
257+ name ++ "-" ++ String.fromInt index
260+renderVariants typeface =
263+ Just (String.join ", " (List.map renderVariant font.variants))
271+ VariantActive name ->
277+ VariantIndexed name index ->
278+ name == "smcp" && index == 1
281+hasSmallCaps typeface =
284+ List.any isSmallCaps font.variants
110type Property
290type Property
@@ -192,6 +372,13 @@ type NodeName
192 | Embedded String String
372 | Embedded String String
375+type NearbyChildren msg
377+ | ChildrenBehind (List (Html.Html msg))
378+ | ChildrenInFront (List (Html.Html msg))
379+ | ChildrenBehindAndInFront (List (Html.Html msg)) (List (Html.Html msg))
@@ -200,7 +387,7 @@ type alias Gathered msg =
200 { node : NodeName
387 { node : NodeName
201 , attributes : List (VirtualDom.Attribute msg)
388 , attributes : List (VirtualDom.Attribute msg)
202 , styles : List Style
389 , styles : List Style
203− , children : List (VirtualDom.Node msg)
390+ , children : NearbyChildren msg
204 , has : Flag.Field
391 , has : Flag.Field
@@ -268,13 +455,17 @@ finalizeNode has node attributes children embedMode parentContext =
268 Embedded nodeName internal ->
455 Embedded nodeName internal ->
269 VirtualDom.node nodeName
456 VirtualDom.node nodeName
270 attributes
457 attributes
458+ [ createNode internal
459+ [ Html.Attributes.class
271− [ createNode internal [ Html.Attributes.class (classes.any ++ " " ++ classes.single) ]
460+ (classes.any ++ " " ++ classes.single)
274 case parentContext of
464 case parentContext of
276 if Flag.present Flag.widthFill has && not (Flag.present Flag.widthBetween has) then
466 if Flag.present Flag.widthFill has && not (Flag.present Flag.widthBetween has) then
278 else if Flag.present Flag.alignRight has then
469 else if Flag.present Flag.alignRight has then
280 [ Html.Attributes.class
471 [ Html.Attributes.class
@@ -288,6 +479,7 @@ finalizeNode has node attributes children embedMode parentContext =
291 else if Flag.present Flag.centerX has then
483 else if Flag.present Flag.centerX has then
293 [ Html.Attributes.class
485 [ Html.Attributes.class
@@ -301,12 +493,14 @@ finalizeNode has node attributes children embedMode parentContext =
307 AsColumn ->
500 AsColumn ->
308 if Flag.present Flag.heightFill has && not (Flag.present Flag.heightBetween has) then
501 if Flag.present Flag.heightFill has && not (Flag.present Flag.heightBetween has) then
310 else if Flag.present Flag.centerY has then
504 else if Flag.present Flag.centerY has then
312 [ Html.Attributes.class
506 [ Html.Attributes.class
@@ -319,6 +513,7 @@ finalizeNode has node attributes children embedMode parentContext =
322 else if Flag.present Flag.alignBottom has then
517 else if Flag.present Flag.alignBottom has then
324 [ Html.Attributes.class
519 [ Html.Attributes.class
@@ -331,6 +526,7 @@ finalizeNode has node attributes children embedMode parentContext =
@@ -339,47 +535,45 @@ finalizeNode has node attributes children embedMode parentContext =
341embedWith static opts styles children =
537embedWith static opts styles children =
541+ |> List.foldl reduceStyles ( Set.empty, renderFocusStyle opts.focus )
543+ -- |> reduceStylesRecursive Set.empty [ ]) --renderFocusStyle opts.focus ]
545+ |> toStyleSheet opts
342 if static then
547 if static then
343− staticRoot
548+ staticRoot opts
344− :: (styles
549+ :: dynamicStyleSheet
345− |> List.foldl reduceStyles ( Set.empty, [ renderFocusStyle opts.focus ] )
347− -- |> reduceStylesRecursive Set.empty [ ]) --renderFocusStyle opts.focus ]
349− |> toStyleSheet opts
351 :: children
550 :: children
353− (styles
553+ dynamicStyleSheet
354− |> List.foldl reduceStyles ( Set.empty, [ renderFocusStyle opts.focus ] )
356− -- |> reduceStylesRecursive Set.empty [ ]) --renderFocusStyle opts.focus ]
358− |> toStyleSheet opts
360 :: children
554 :: children
363embedKeyed static opts styles children =
557embedKeyed static opts styles children =
561+ |> List.foldl reduceStyles ( Set.empty, renderFocusStyle opts.focus )
563+ -- |> reduceStylesRecursive Set.empty [ ]) --renderFocusStyle opts.focus ]
565+ |> toStyleSheet opts
364 if static then
567 if static then
365− ( "static-stylesheet", staticRoot )
568+ ( "static-stylesheet", staticRoot opts )
366 :: ( "dynamic-stylesheet"
569 :: ( "dynamic-stylesheet"
367− , styles
570+ , dynamicStyleSheet
368− |> List.foldl reduceStyles ( Set.empty, [ renderFocusStyle opts.focus ] )
370− -- |> reduceStylesRecursive Set.empty [ ]) --renderFocusStyle opts.focus ]
372− |> toStyleSheet opts
374 :: children
572 :: children
376 ( "dynamic-stylesheet"
575 ( "dynamic-stylesheet"
377− , styles
576+ , dynamicStyleSheet
378− |> List.foldl reduceStyles ( Set.empty, [ renderFocusStyle opts.focus ] )
380− -- |> reduceStylesRecursive Set.empty [ ]) --renderFocusStyle opts.focus ]
382− |> toStyleSheet opts
384 :: children
578 :: children
@@ -397,6 +591,7 @@ reduceStylesRecursive cache found styles =
398 if Set.member styleName cache then
592 if Set.member styleName cache then
399 reduceStylesRecursive cache found remaining
593 reduceStylesRecursive cache found remaining
401 reduceStylesRecursive (Set.insert styleName cache) (head :: found) remaining
596 reduceStylesRecursive (Set.insert styleName cache) (head :: found) remaining
@@ -409,6 +604,7 @@ reduceStyles style (( cache, existing ) as nevermind) =
410 if Set.member styleName cache then
605 if Set.member styleName cache then
411 nevermind
606 nevermind
413 ( Set.insert styleName cache
609 ( Set.insert styleName cache
414 , style :: existing
610 , style :: existing
@@ -434,6 +630,7 @@ reduceRecursiveCalcName found styles =
434 headOfList :: other :: remaining ->
630 headOfList :: other :: remaining ->
435 if headOfList /= other then
631 if headOfList /= other then
436 reduceRecursiveCalcName (headOfList :: found) (other :: remaining)
632 reduceRecursiveCalcName (headOfList :: found) (other :: remaining)
438 reduceRecursiveCalcName found (other :: remaining)
635 reduceRecursiveCalcName found (other :: remaining)
@@ -450,6 +647,7 @@ reduceRecursive found styles =
450 ( headOfListName, headOfList ) :: ( otherName, other ) :: remaining ->
647 ( headOfListName, headOfList ) :: ( otherName, other ) :: remaining ->
451 if headOfListName /= otherName then
648 if headOfListName /= otherName then
452 reduceRecursive (headOfList :: found) (( otherName, other ) :: remaining)
649 reduceRecursive (headOfList :: found) (( otherName, other ) :: remaining)
454 reduceRecursive found (( otherName, other ) :: remaining)
652 reduceRecursive found (( otherName, other ) :: remaining)
@@ -674,6 +872,7 @@ skippable flag style =
678 case style of
877 case style of
679 FontSize i ->
878 FontSize i ->
@@ -690,7 +889,16 @@ skippable flag style =
693−gatherAttrRecursive : String -> NodeName -> Flag.Field -> Transformation -> List Style -> List (VirtualDom.Attribute msg) -> List (VirtualDom.Node msg) -> List (Attribute aligned msg) -> Gathered msg
892+gatherAttrRecursive :
898+ -> List (VirtualDom.Attribute msg)
899+ -> NearbyChildren msg
900+ -> List (Attribute aligned msg)
694gatherAttrRecursive classes node has transform styles attrs children elementAttrs =
902gatherAttrRecursive classes node has transform styles attrs children elementAttrs =
695 case elementAttrs of
903 case elementAttrs of
@@ -719,6 +927,7 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
719 Class flag exactClassName ->
927 Class flag exactClassName ->
720 if Flag.present flag has then
928 if Flag.present flag has then
721 gatherAttrRecursive classes node has transform styles attrs children remaining
929 gatherAttrRecursive classes node has transform styles attrs children remaining
723 gatherAttrRecursive (exactClassName ++ " " ++ classes) node (Flag.add flag has) transform styles attrs children remaining
932 gatherAttrRecursive (exactClassName ++ " " ++ classes) node (Flag.add flag has) transform styles attrs children remaining
@@ -728,6 +937,7 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
728 StyleClass flag style ->
937 StyleClass flag style ->
729 if Flag.present flag has then
938 if Flag.present flag has then
730 gatherAttrRecursive classes node has transform styles attrs children remaining
939 gatherAttrRecursive classes node has transform styles attrs children remaining
731 else if skippable flag style then
941 else if skippable flag style then
732 gatherAttrRecursive (getStyleName style ++ " " ++ classes)
942 gatherAttrRecursive (getStyleName style ++ " " ++ classes)
@@ -737,6 +947,7 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
739 remaining
949 remaining
741 gatherAttrRecursive (getStyleName style ++ " " ++ classes)
952 gatherAttrRecursive (getStyleName style ++ " " ++ classes)
@@ -760,6 +971,7 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
760 Width width ->
971 Width width ->
761 if Flag.present Flag.width has then
972 if Flag.present Flag.width has then
762 gatherAttrRecursive classes node has transform styles attrs children remaining
973 gatherAttrRecursive classes node has transform styles attrs children remaining
764 case width of
976 case width of
@@ -792,6 +1004,7 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
793 children
1005 children
794 remaining
1006 remaining
796 gatherAttrRecursive (classes ++ " " ++ Internal.Style.classes.widthFillPortion ++ " width-fill-" ++ String.fromInt portion)
1009 gatherAttrRecursive (classes ++ " " ++ Internal.Style.classes.widthFillPortion ++ " width-fill-" ++ String.fromInt portion)
@@ -819,7 +1032,7 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
820 gatherAttrRecursive (classes ++ " " ++ newClass)
1033 gatherAttrRecursive (classes ++ " " ++ newClass)
822− (Flag.merge addToFlags has)
1035+ (Flag.merge addToFlags (Flag.add Flag.width has))
823 transform
1036 transform
824 (newStyles ++ styles)
1037 (newStyles ++ styles)
@@ -829,6 +1042,7 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
829 Height height ->
1042 Height height ->
830 if Flag.present Flag.height has then
1043 if Flag.present Flag.height has then
831 gatherAttrRecursive classes node has transform styles attrs children remaining
1044 gatherAttrRecursive classes node has transform styles attrs children remaining
833 case height of
1047 case height of
834 Px px ->
1048 Px px ->
@@ -839,7 +1053,7 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
840 "height-px-" ++ val
1054 "height-px-" ++ val
842− gatherAttrRecursive (name ++ " " ++ classes)
1056+ gatherAttrRecursive (Internal.Style.classes.heightExact ++ " " ++ name ++ " " ++ classes)
844 (Flag.add Flag.height has)
1058 (Flag.add Flag.height has)
845 transform
1059 transform
@@ -868,6 +1082,7 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
869 children
1083 children
870 remaining
1084 remaining
872 gatherAttrRecursive (classes ++ " " ++ (Internal.Style.classes.heightFillPortion ++ " height-fill-" ++ String.fromInt portion))
1087 gatherAttrRecursive (classes ++ " " ++ (Internal.Style.classes.heightFillPortion ++ " height-fill-" ++ String.fromInt portion))
@@ -895,7 +1110,7 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
896 gatherAttrRecursive (classes ++ " " ++ newClass)
1111 gatherAttrRecursive (classes ++ " " ++ newClass)
898− (Flag.merge addToFlags has)
1113+ (Flag.merge addToFlags (Flag.add Flag.height has))
899 transform
1114 transform
900 (newStyles ++ styles)
1115 (newStyles ++ styles)
@@ -919,26 +1134,23 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
919 Heading i ->
1134 Heading i ->
920 if i <= 1 then
1135 if i <= 1 then
921 gatherAttrRecursive classes (addNodeName "h1" node) has transform styles attrs children remaining
1136 gatherAttrRecursive classes (addNodeName "h1" node) has transform styles attrs children remaining
922 else if i < 7 then
1138 else if i < 7 then
923 gatherAttrRecursive classes (addNodeName ("h" ++ String.fromInt i) node) has transform styles attrs children remaining
1139 gatherAttrRecursive classes (addNodeName ("h" ++ String.fromInt i) node) has transform styles attrs children remaining
925 gatherAttrRecursive classes (addNodeName "h6" node) has transform styles attrs children remaining
1142 gatherAttrRecursive classes (addNodeName "h6" node) has transform styles attrs children remaining
927 Paragraph ->
1144 Paragraph ->
928− let
1145+ -- previously we rendered a <p> tag, though apparently this invalidates the html if it has <div>s inside.
929− newNode =
1146+ -- Since we can't guaranteee that there are no divs, we need another strategy.
930− case node of
1147+ -- While it's not documented in many places, there apparently is a paragraph aria role
931− Generic ->
1148+ -- https://github.com/w3c/aria/blob/11f85f41a5b621fdbe85fc9bcdcd270e653a48ba/common/script/roleInfo.js
932− NodeName "p"
1149+ -- Though we'll need to wait till it gets released in an official wai-aria spec to use it.
933−
1150+ -- If it's used at the moment, then Lighthouse complains (likely rightfully) that role paragraph is not recognized.
940− gatherAttrRecursive classes
1151+ gatherAttrRecursive
941− newNode
1152+ classes
943 transform
1155 transform
@@ -973,78 +1185,21 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
974 Styled styled ->
1186 Styled styled ->
975 styles ++ styled.styles
1187 styles ++ styled.styles
979− [ Html.Attributes.class <|
983− [ Internal.Style.classes.any
984− , Internal.Style.classes.single
985− , Internal.Style.classes.above
990− [ Internal.Style.classes.any
991− , Internal.Style.classes.single
992− , Internal.Style.classes.below
997− [ Internal.Style.classes.any
998− , Internal.Style.classes.single
999− , Internal.Style.classes.onRight
1004− [ Internal.Style.classes.any
1005− , Internal.Style.classes.single
1006− , Internal.Style.classes.onLeft
1011− [ Internal.Style.classes.any
1012− , Internal.Style.classes.single
1013− , Internal.Style.classes.inFront
1018− [ Internal.Style.classes.any
1019− , Internal.Style.classes.single
1020− , Internal.Style.classes.behind
1034− styled.html NoStyleSheet asEl
1038− if location == Behind then
1039− Internal.Style.classes.hasBehind ++ " " ++ classes
1043− gatherAttrRecursive newClasses node has transform newStyles attrs (nearbyElement :: children) remaining
1189+ gatherAttrRecursive
1196+ (addNearbyElement location elem children)
1045 AlignX x ->
1199 AlignX x ->
1046 if Flag.present Flag.xAlign has then
1200 if Flag.present Flag.xAlign has then
1047 gatherAttrRecursive classes node has transform styles attrs children remaining
1201 gatherAttrRecursive classes node has transform styles attrs children remaining
1049 gatherAttrRecursive (alignXName x ++ " " ++ classes)
1204 gatherAttrRecursive (alignXName x ++ " " ++ classes)
@@ -1071,6 +1226,7 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
1071 AlignY y ->
1226 AlignY y ->
1072 if Flag.present Flag.yAlign has then
1227 if Flag.present Flag.yAlign has then
1073 gatherAttrRecursive classes node has transform styles attrs children remaining
1228 gatherAttrRecursive classes node has transform styles attrs children remaining
1075 gatherAttrRecursive (alignYName y ++ " " ++ classes)
1231 gatherAttrRecursive (alignYName y ++ " " ++ classes)
@@ -1094,6 +1250,106 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
1094 remaining
1250 remaining
1253+addNearbyElement location elem existing =
1256+ nearbyElement location elem
1259+ NoNearbyChildren ->
1262+ ChildrenBehind [ nearby ]
1265+ ChildrenInFront [ nearby ]
1267+ ChildrenBehind existingBehind ->
1270+ ChildrenBehind (nearby :: existingBehind)
1273+ ChildrenBehindAndInFront existingBehind [ nearby ]
1275+ ChildrenInFront existingInFront ->
1278+ ChildrenBehindAndInFront [ nearby ] existingInFront
1281+ ChildrenInFront (nearby :: existingInFront)
1283+ ChildrenBehindAndInFront existingBehind existingInFront ->
1286+ ChildrenBehindAndInFront (nearby :: existingBehind) existingInFront
1289+ ChildrenBehindAndInFront existingBehind (nearby :: existingInFront)
1292+nearbyElement location elem =
1294+ [ Html.Attributes.class <|
1298+ [ Internal.Style.classes.nearby
1299+ , Internal.Style.classes.single
1300+ , Internal.Style.classes.above
1305+ [ Internal.Style.classes.nearby
1306+ , Internal.Style.classes.single
1307+ , Internal.Style.classes.below
1312+ [ Internal.Style.classes.nearby
1313+ , Internal.Style.classes.single
1314+ , Internal.Style.classes.onRight
1319+ [ Internal.Style.classes.nearby
1320+ , Internal.Style.classes.single
1321+ , Internal.Style.classes.onLeft
1326+ [ Internal.Style.classes.nearby
1327+ , Internal.Style.classes.single
1328+ , Internal.Style.classes.inFront
1333+ [ Internal.Style.classes.nearby
1334+ , Internal.Style.classes.single
1335+ , Internal.Style.classes.behind
1349+ styled.html NoStyleSheet asEl
1097renderWidth w =
1353renderWidth w =
1098 case w of
1354 case w of
1099 Px px ->
1355 Px px ->
@@ -1114,6 +1370,7 @@ renderWidth w =
1114 , Internal.Style.classes.widthFill
1370 , Internal.Style.classes.widthFill
1118 ( Flag.add Flag.widthFill Flag.none
1375 ( Flag.add Flag.widthFill Flag.none
1119 , Internal.Style.classes.widthFillPortion ++ " width-fill-" ++ String.fromInt portion
1376 , Internal.Style.classes.widthFillPortion ++ " width-fill-" ++ String.fromInt portion
@@ -1179,7 +1436,7 @@ renderHeight h =
1179 "height-px-" ++ val
1436 "height-px-" ++ val
1181 ( Flag.none
1438 ( Flag.none
1182− , name
1439+ , Internal.Style.classes.heightExact ++ " " ++ name
1183 , [ Single name "height" (val ++ "px") ]
1440 , [ Single name "height" (val ++ "px") ]
@@ -1195,13 +1452,14 @@ renderHeight h =
1195 , Internal.Style.classes.heightFill
1452 , Internal.Style.classes.heightFill
1199 ( Flag.add Flag.heightFill Flag.none
1457 ( Flag.add Flag.heightFill Flag.none
1200 , Internal.Style.classes.heightFillPortion ++ " height-fill-" ++ String.fromInt portion
1458 , Internal.Style.classes.heightFillPortion ++ " height-fill-" ++ String.fromInt portion
1201 , [ Single
1459 , [ Single
1202 (Internal.Style.classes.any
1460 (Internal.Style.classes.any
1204− ++ Internal.Style.classes.row
1462+ ++ Internal.Style.classes.column
1205 ++ " > "
1463 ++ " > "
1206 ++ (Internal.Style.dot <| "height-fill-" ++ String.fromInt portion)
1464 ++ (Internal.Style.dot <| "height-fill-" ++ String.fromInt portion)
@@ -1220,7 +1478,9 @@ renderHeight h =
1222 "min-height"
1480 "min-height"
1481+ -- This needs to be !important because we're using `min-height: min-content`
1482+ -- to correct for safari's incorrect implementation of flexbox.
1223− (String.fromInt minSize ++ "px")
1483+ (String.fromInt minSize ++ "px !important")
1225 ( newFlag, newAttrs, newStyle ) =
1485 ( newFlag, newAttrs, newStyle ) =
1226 renderHeight len
1486 renderHeight len
@@ -1298,7 +1558,7 @@ element : LayoutContext -> NodeName -> List (Attribute aligned msg) -> Children
1298element context node attributes children =
1558element context node attributes children =
1299 attributes
1559 attributes
1300 |> List.reverse
1560 |> List.reverse
1301− |> gatherAttrRecursive (contextClasses context) node Flag.none untransformed [] [] []
1561+ |> gatherAttrRecursive (contextClasses context) node Flag.none untransformed [] [] NoNearbyChildren
1302 |> createElement context children
1562 |> createElement context children
@@ -1306,13 +1566,6 @@ untransformed =
1306 Untransformed
1566 Untransformed
1311−-- VirtualDom.text " "
1316createElement : LayoutContext -> Children (Element msg) -> Gathered msg -> Element msg
1569createElement : LayoutContext -> Children (Element msg) -> Gathered msg -> Element msg
1317createElement context children rendered =
1570createElement context children rendered =
@@ -1323,6 +1576,7 @@ createElement context children rendered =
1323 ( html context :: htmls
1576 ( html context :: htmls
1324 , existingStyles
1577 , existingStyles
1327 ( html context :: htmls
1581 ( html context :: htmls
1328 , existingStyles
1582 , existingStyles
@@ -1333,13 +1587,16 @@ createElement context children rendered =
1333 ( styled.html NoStyleSheet context :: htmls
1587 ( styled.html NoStyleSheet context :: htmls
1334 , if List.isEmpty existingStyles then
1588 , if List.isEmpty existingStyles then
1335 styled.styles
1589 styled.styles
1337 styled.styles ++ existingStyles
1592 styled.styles ++ existingStyles
1340 ( styled.html NoStyleSheet context :: htmls
1596 ( styled.html NoStyleSheet context :: htmls
1341 , if List.isEmpty existingStyles then
1597 , if List.isEmpty existingStyles then
1342 styled.styles
1598 styled.styles
1344 styled.styles ++ existingStyles
1601 styled.styles ++ existingStyles
@@ -1350,33 +1607,33 @@ createElement context children rendered =
1350 -- Same if it's a column or row with one child and width-content, height-content
1607 -- Same if it's a column or row with one child and width-content, height-content
1351 -- interferes with css grid
1608 -- interferes with css grid
1352 -- Maybe we could unpack text elements in a paragraph as well,
1609 -- Maybe we could unpack text elements in a paragraph as well,
1353− -- however embedded style elements that are larger than the line height will overlap with exisitng text.
1610+ -- however, embedded elements that are larger than the line height will overlap with exisitng text.
1354 -- I don't think that's what we want.
1611 -- I don't think that's what we want.
1356− context
1613+ -- context
1357− == asEl
1614+ -- == asEl
1358− || context
1615+ -- || context
1359− == asParagraph
1616+ -- == asParagraph
1361− ( VirtualDom.text
1618+ -- ( VirtualDom.text
1362− (if context == asParagraph then
1619+ -- (if context == asParagraph then
1363− str ++ " "
1620+ -- str
1367− :: htmls
1624+ -- :: htmls
1368− , existingStyles
1625+ -- , existingStyles
1628+ ( (if context == asEl then
1629+ textElementFill str
1371− ( textElement
1632+ textElement str
1372− (if context == asParagraph then
1377− :: htmls
1634+ :: htmls
1378− , existingStyles
1635+ , existingStyles
1381 Empty ->
1638 Empty ->
1382 ( htmls, existingStyles )
1639 ( htmls, existingStyles )
@@ -1388,6 +1645,7 @@ createElement context children rendered =
1388 ( ( key, html context ) :: htmls
1645 ( ( key, html context ) :: htmls
1389 , existingStyles
1646 , existingStyles
1392 ( ( key, html context ) :: htmls
1650 ( ( key, html context ) :: htmls
1393 , existingStyles
1651 , existingStyles
@@ -1399,13 +1657,16 @@ createElement context children rendered =
1399 :: htmls
1657 :: htmls
1400 , if List.isEmpty existingStyles then
1658 , if List.isEmpty existingStyles then
1401 styled.styles
1659 styled.styles
1403 styled.styles ++ existingStyles
1662 styled.styles ++ existingStyles
1406 ( ( key, styled.html NoStyleSheet context ) :: htmls
1666 ( ( key, styled.html NoStyleSheet context ) :: htmls
1407 , if List.isEmpty existingStyles then
1667 , if List.isEmpty existingStyles then
1408 styled.styles
1668 styled.styles
1410 styled.styles ++ existingStyles
1671 styled.styles ++ existingStyles
@@ -1414,35 +1675,30 @@ createElement context children rendered =
1414 -- TEXT OPTIMIZATION
1675 -- TEXT OPTIMIZATION
1415 -- You can have raw text if the element is an el, and has `width-content` and `height-content`
1676 -- You can have raw text if the element is an el, and has `width-content` and `height-content`
1416 -- Same if it's a column or row with one child and width-content, height-content
1677 -- Same if it's a column or row with one child and width-content, height-content
1418− context
1679+ -- context
1419− == asEl
1680+ -- == asEl
1420− || context
1681+ -- || context
1421− == asParagraph
1682+ -- == asParagraph
1423− ( ( key
1684+ -- ( ( key
1424− , VirtualDom.text
1685+ -- , VirtualDom.text
1425− (if context == asParagraph then
1431− :: htmls
1688+ -- :: htmls
1432− , existingStyles
1689+ -- , existingStyles
1435− ( ( key
1692+ ( ( key
1693+ , if context == asEl then
1694+ textElementFill str
1436− , textElement
1697+ textElement str
1437− (if context == asParagraph then
1443− :: htmls
1699+ :: htmls
1444− , existingStyles
1700+ , existingStyles
1447 Empty ->
1703 Empty ->
1448 ( htmls, existingStyles )
1704 ( htmls, existingStyles )
@@ -1455,6 +1711,7 @@ createElement context children rendered =
1455 newStyles =
1711 newStyles =
1456 if List.isEmpty styles then
1712 if List.isEmpty styles then
1457 rendered.styles
1713 rendered.styles
1459 rendered.styles ++ styles
1716 rendered.styles ++ styles
@@ -1464,7 +1721,9 @@ createElement context children rendered =
1464 (finalizeNode rendered.has
1721 (finalizeNode rendered.has
1465 rendered.node
1722 rendered.node
1466 rendered.attributes
1723 rendered.attributes
1467− (Keyed <| List.map (\x -> ( "nearby-elements-pls", x )) rendered.children ++ keyed)
1725+ (addKeyedChildren "nearby-element-pls" keyed rendered.children)
1468 NoStyleSheet
1727 NoStyleSheet
@@ -1472,7 +1731,13 @@ createElement context children rendered =
1473 { styles = allStyles
1732 { styles = allStyles
1474 , html =
1733 , html =
1475− finalizeNode rendered.has rendered.node rendered.attributes (Keyed (List.map (\x -> ( "nearby-elements-pls", x )) rendered.children ++ keyed))
1734+ finalizeNode
1737+ rendered.attributes
1739+ (addKeyedChildren "nearby-element-pls" keyed rendered.children)
1478 Unkeyed unkeyedChildren ->
1743 Unkeyed unkeyedChildren ->
@@ -1482,26 +1747,65 @@ createElement context children rendered =
1482 newStyles =
1747 newStyles =
1483 if List.isEmpty styles then
1748 if List.isEmpty styles then
1484 rendered.styles
1749 rendered.styles
1486 rendered.styles ++ styles
1752 rendered.styles ++ styles
1488 case newStyles of
1754 case newStyles of
1490 Unstyled
1756 Unstyled
1491− (finalizeNode rendered.has
1757+ (finalizeNode
1492 rendered.node
1759 rendered.node
1493 rendered.attributes
1760 rendered.attributes
1494− (Unkeyed <| rendered.children ++ unkeyed)
1761+ (Unkeyed (addChildren unkeyed rendered.children))
1495 NoStyleSheet
1762 NoStyleSheet
1498 allStyles ->
1765 allStyles ->
1500 { styles = allStyles
1767 { styles = allStyles
1501− , html = finalizeNode rendered.has rendered.node rendered.attributes (Unkeyed (rendered.children ++ unkeyed))
1768+ , html =
1772+ rendered.attributes
1773+ (Unkeyed (addChildren unkeyed rendered.children))
1777+addChildren existing nearbyChildren =
1778+ case nearbyChildren of
1779+ NoNearbyChildren ->
1782+ ChildrenBehind behind ->
1785+ ChildrenInFront inFront ->
1786+ existing ++ inFront
1788+ ChildrenBehindAndInFront behind inFront ->
1789+ behind ++ existing ++ inFront
1792+addKeyedChildren key existing nearbyChildren =
1793+ case nearbyChildren of
1794+ NoNearbyChildren ->
1797+ ChildrenBehind behind ->
1798+ List.map (\x -> ( key, x )) behind ++ existing
1800+ ChildrenInFront inFront ->
1801+ existing ++ List.map (\x -> ( key, x )) inFront
1803+ ChildrenBehindAndInFront behind inFront ->
1804+ List.map (\x -> ( key, x )) behind
1806+ ++ List.map (\x -> ( key, x )) inFront
@@ -1513,13 +1817,26 @@ defaultOptions =
1516−staticRoot =
1820+staticRoot : OptionRecord -> VirtualDom.Node msg
1824+ -- wrap the style node in a div to prevent `Dark Reader` from blowin up the dom.
1825+ VirtualDom.node "div"
1517− VirtualDom.node "style" [] [ VirtualDom.text Internal.Style.rules ]
1827+ [ VirtualDom.node "style" [] [ VirtualDom.text Internal.Style.rules ] ]
1829+ NoStaticStyleSheet ->
1833+ VirtualDom.node "elm-ui-static-rules" [ VirtualDom.property "rules" (Encode.string Internal.Style.rules) ] []
1520addWhen ifThis x to =
1836addWhen ifThis x to =
1521 if ifThis then
1837 if ifThis then
@@ -1550,18 +1867,21 @@ filter attrs =
1550 Width width ->
1867 Width width ->
1551 if Set.member "width" has then
1868 if Set.member "width" has then
1552 ( found, has )
1869 ( found, has )
1554 ( x :: found, Set.insert "width" has )
1872 ( x :: found, Set.insert "width" has )
1556 Height height ->
1874 Height height ->
1557 if Set.member "height" has then
1875 if Set.member "height" has then
1558 ( found, has )
1876 ( found, has )
1560 ( x :: found, Set.insert "height" has )
1879 ( x :: found, Set.insert "height" has )
1562 Describe description ->
1881 Describe description ->
1563 if Set.member "described" has then
1882 if Set.member "described" has then
1564 ( found, has )
1883 ( found, has )
1566 ( x :: found, Set.insert "described" has )
1886 ( x :: found, Set.insert "described" has )
@@ -1571,18 +1891,21 @@ filter attrs =
1571 AlignX _ ->
1891 AlignX _ ->
1572 if Set.member "align-x" has then
1892 if Set.member "align-x" has then
1573 ( found, has )
1893 ( found, has )
1575 ( x :: found, Set.insert "align-x" has )
1896 ( x :: found, Set.insert "align-x" has )
1577 AlignY _ ->
1898 AlignY _ ->
1578 if Set.member "align-y" has then
1899 if Set.member "align-y" has then
1579 ( found, has )
1900 ( found, has )
1581 ( x :: found, Set.insert "align-y" has )
1903 ( x :: found, Set.insert "align-y" has )
1583 TransformComponent _ _ ->
1905 TransformComponent _ _ ->
1584 if Set.member "transform" has then
1906 if Set.member "transform" has then
1585 ( found, has )
1907 ( found, has )
1587 ( x :: found, Set.insert "transform" has )
1910 ( x :: found, Set.insert "transform" has )
@@ -1590,6 +1913,21 @@ filter attrs =
1593get : List (Attribute aligned msg) -> (Attribute aligned msg -> Bool) -> List (Attribute aligned msg)
1931get : List (Attribute aligned msg) -> (Attribute aligned msg -> Bool) -> List (Attribute aligned msg)
1594get attrs isAttr =
1932get attrs isAttr =
@@ -1598,6 +1936,7 @@ get attrs isAttr =
1598 (\x found ->
1936 (\x found ->
1599 if isAttr x then
1937 if isAttr x then
1600 x :: found
1938 x :: found
@@ -1609,7 +1948,7 @@ type Spacing
1611type Padding
1950type Padding
1612− = Padding String Int Int Int Int
1951+ = Padding String Float Float Float Float
1615extractSpacingAndPadding : List (Attribute aligned msg) -> ( Maybe Padding, Maybe Spacing )
1954extractSpacingAndPadding : List (Attribute aligned msg) -> ( Maybe Padding, Maybe Spacing )
@@ -1705,35 +2044,44 @@ getHeight attrs =
2047+textElementClasses : String
2048+textElementClasses =
2053+ ++ classes.widthContent
2055+ ++ classes.heightContent
1708textElement : String -> VirtualDom.Node msg
2058textElement : String -> VirtualDom.Node msg
1709textElement str =
2059textElement str =
1710 Html.div
2060 Html.div
1711 [ Html.Attributes.class
2061 [ Html.Attributes.class
1712− (String.join " "
2062+ textElementClasses
1715− , classes.widthContent
1716− , classes.heightContent
1720 [ Html.text str ]
2064 [ Html.text str ]
2067+textElementFillClasses : String
2068+textElementFillClasses =
2073+ ++ classes.widthFill
2075+ ++ classes.heightFill
1723textElementFill : String -> VirtualDom.Node msg
2078textElementFill : String -> VirtualDom.Node msg
1724textElementFill str =
2079textElementFill str =
1725− VirtualDom.node "div"
2080+ Html.div
1726− [ VirtualDom.property "className"
2081+ [ Html.Attributes.class
1727− (Json.string <|
2082+ textElementFillClasses
1731− , classes.widthFill
1732− , classes.heightFill
1736− [ VirtualDom.text str ]
2084+ [ Html.text str ]
1739type Children x
2087type Children x
@@ -1741,10 +2089,6 @@ type Children x
1741 | Keyed (List ( String, x ))
2089 | Keyed (List ( String, x ))
1745−-- toHtml : OptionRecord -> Element msg -> VirtualDom.Node msg
1748toHtml mode el =
2092toHtml mode el =
1749 case el of
2093 case el of
1750 Unstyled html ->
2094 Unstyled html ->
@@ -1780,8 +2124,7 @@ renderRoot optionList attributes child =
1782type RenderMode
2126type RenderMode
1784− | Layout
2127+ = Layout
1785 | NoStaticStyleSheet
2128 | NoStaticStyleSheet
1786 | WithVirtualCss
2129 | WithVirtualCss
@@ -1830,10 +2173,8 @@ rootStyle =
1830 , SansSerif
2173 , SansSerif
1833− [ StyleClass Flag.bgColor (Colored ("bg-color-" ++ formatColorClass (Rgba 1 1 1 1)) "background-color" (Rgba 1 1 1 1))
2176+ [ StyleClass Flag.bgColor (Colored ("bg-" ++ formatColorClass (Rgba 1 1 1 0)) "background-color" (Rgba 1 1 1 0))
1834− , StyleClass Flag.fontColor (Colored ("font-color-" ++ formatColorClass (Rgba 0 0 0 1)) "color" (Rgba 0 0 0 1))
2177+ , StyleClass Flag.fontColor (Colored ("fc-" ++ formatColorClass (Rgba 0 0 0 1)) "color" (Rgba 0 0 0 1))
1836− -- , StyleClass Flag.fontSize (Single "font-size-20" "font-size" "20px")
1837 , StyleClass Flag.fontSize (FontSize 20)
2178 , StyleClass Flag.fontSize (FontSize 20)
1838 , StyleClass Flag.fontFamily <|
2179 , StyleClass Flag.fontFamily <|
1839 FontFamily (List.foldl renderFontClassName "font-" families)
2180 FontFamily (List.foldl renderFontClassName "font-" families)
@@ -1865,14 +2206,49 @@ renderFontClassName font current =
1865 |> String.toLower
2206 |> String.toLower
1866 |> String.words
2207 |> String.words
1867 |> String.join "-"
2208 |> String.join "-"
2210+ FontWith { name } ->
1871renderFocusStyle :
2218renderFocusStyle :
1872 FocusStyle
2219 FocusStyle
1873− -> Style
2220+ -> List Style
1874renderFocusStyle focus =
2221renderFocusStyle focus =
2222+ [ Style (Internal.Style.dot classes.focusedWithin ++ ":focus-within")
2223+ (List.filterMap identity
2224+ [ Maybe.map (\color -> Property "border-color" (formatColor color)) focus.borderColor
2225+ , Maybe.map (\color -> Property "background-color" (formatColor color)) focus.backgroundColor
2228+ Property "box-shadow"
2230+ { color = shadow.color
2233+ |> Tuple.mapFirst toFloat
2234+ |> Tuple.mapSecond toFloat
2237+ toFloat shadow.blur
2239+ toFloat shadow.size
2244+ , Just <| Property "outline" "none"
2248+ ((Internal.Style.dot classes.any ++ ":focus .focusable, ")
1875− Style (Internal.Style.dot classes.any ++ ":focus .focusable, " ++ Internal.Style.dot classes.any ++ ".focusable:focus")
2249+ ++ (Internal.Style.dot classes.any ++ ".focusable:focus, ")
2250+ ++ (".ui-slide-bar:focus + " ++ Internal.Style.dot classes.any ++ " .focusable-thumb")
1876 (List.filterMap identity
2252 (List.filterMap identity
1877 [ Maybe.map (\color -> Property "border-color" (formatColor color)) focus.borderColor
2253 [ Maybe.map (\color -> Property "border-color" (formatColor color)) focus.borderColor
1878 , Maybe.map (\color -> Property "background-color" (formatColor color)) focus.backgroundColor
2254 , Maybe.map (\color -> Property "background-color" (formatColor color)) focus.backgroundColor
@@ -1895,6 +2271,7 @@ renderFocusStyle focus =
1895 , Just <| Property "outline" "none"
2271 , Just <| Property "outline" "none"
1900focusDefaultStyle : { backgroundColor : Maybe Color, borderColor : Maybe Color, shadow : Maybe Shadow }
2277focusDefaultStyle : { backgroundColor : Maybe Color, borderColor : Maybe Color, shadow : Maybe Shadow }
@@ -1906,7 +2283,7 @@ focusDefaultStyle =
1906 { color =
2283 { color =
1907 Rgba (155 / 255) (203 / 255) 1 1
2284 Rgba (155 / 255) (203 / 255) 1 1
1908 , offset = ( 0, 0 )
2285 , offset = ( 0, 0 )
1909− , blur = 3
2286+ , blur = 0
1910 , size = 3
2287 , size = 3
@@ -1974,497 +2351,734 @@ optionsToRecord options =
1977−renderFont : List Font -> String
2354+toStyleSheet : OptionRecord -> List Style -> VirtualDom.Node msg
1978−renderFont families =
2355+toStyleSheet options styleSheet =
2356+ case options.mode of
2358+ -- wrap the style node in a div to prevent `Dark Reader` from blowin up the dom.
2359+ VirtualDom.node "div"
2361+ [ VirtualDom.node "style"
2363+ [ VirtualDom.text (toStyleSheetString options styleSheet) ]
2366+ NoStaticStyleSheet ->
2367+ -- wrap the style node in a div to prevent `Dark Reader` from blowin up the dom.
2368+ VirtualDom.node "div"
2370+ [ VirtualDom.node "style"
2372+ [ VirtualDom.text (toStyleSheetString options styleSheet) ]
2376+ VirtualDom.node "elm-ui-rules"
2377+ [ VirtualDom.property "rules"
2378+ (encodeStyles options styleSheet)
2383+renderTopLevelValues rules =
1980− fontName font =
2385+ withImport font =
1981 case font of
2386 case font of
1982− Serif ->
2387+ ImportFont _ url ->
1983− "serif"
2388+ Just ("@import url('" ++ url ++ "');")
2390+ -- FontWith with ->
2391+ -- case with.url of
2393+ -- Just ("@import url('" ++ x ++ "');")
1985− SansSerif ->
2399+ allNames =
1986− "sans-serif"
2400+ List.map Tuple.first rules
1988− Monospace ->
2402+ fontImports ( name, typefaces ) =
1989− "monospace"
2403+ let
2405+ String.join "\n" (List.filterMap withImport typefaces)
1991− Typeface name ->
2409+ fontAdjustments ( name, typefaces ) =
1992− "\"" ++ name ++ "\""
2410+ case typefaceAdjustment typefaces of
2413+ (List.map (renderNullAdjustmentRule name) allNames)
1994− ImportFont name url ->
2415+ Just adjustment ->
1995− "\"" ++ name ++ "\""
2416+ String.join ""
2417+ (List.map (renderFontAdjustmentRule name adjustment) allNames)
1997− families
2419+ String.join "\n" (List.map fontImports rules)
1998− |> List.map fontName
1999− |> String.join ", "
2420+ ++ String.join "\n" (List.map fontAdjustments rules)
2002−toStyleSheet : OptionRecord -> List Style -> VirtualDom.Node msg
2423+renderNullAdjustmentRule fontToAdjust otherFontName =
2003−toStyleSheet options styleSheet =
2424+ let
2004− VirtualDom.node "style" [] [ VirtualDom.text (toStyleSheetString options styleSheet) ]
2425+ name =
2426+ if fontToAdjust == otherFontName then
2430+ otherFontName ++ " ." ++ fontToAdjust
2437+ ++ classes.sizeByCapital
2442+ ++ classes.sizeByCapital
2444+ [ ( "line-height", "1" )
2450+ ++ classes.sizeByCapital
2452+ ++ Internal.Style.classes.text
2456+ ++ classes.sizeByCapital
2458+ ++ Internal.Style.classes.text
2460+ [ ( "vertical-align", "0" )
2461+ , ( "line-height", "1" )
2007−toStyleSheetString : OptionRecord -> List Style -> String
2008−toStyleSheetString options stylesheet =
2010− renderTopLevels rule =
2012− FontFamily name typefaces ->
2016− ImportFont _ url ->
2017− Just ("@import url('" ++ url ++ "');")
2019− _ ->
2466+fontRule name modifier ( parentAdj, textAdjustment ) =
2020− Nothing
2467+ [ bracket
2022− typefaces
2469+ ++ name
2023− |> List.filterMap getImports
2470+ ++ "."
2024− |> String.join "\n"
2471+ ++ modifier
2025− |> Just
2472+ ++ ", "
2485+ ++ Internal.Style.classes.text
2491+ ++ Internal.Style.classes.text
2030− renderProps force (Property key val) existing =
2497+renderFontAdjustmentRule fontToAdjust ( full, capital ) otherFontName =
2031− if force then
2498+ let
2032− existing ++ "\n " ++ key ++ ": " ++ val ++ " !important;"
2499+ name =
2500+ if fontToAdjust == otherFontName then
2034− existing ++ "\n " ++ key ++ ": " ++ val ++ ";"
2504+ otherFontName ++ " ." ++ fontToAdjust
2507+ (fontRule name classes.sizeByCapital capital ++ fontRule name classes.fullSize full)
2036− renderStyle maybePseudo selector props =
2510+bracket selector rules =
2512+ renderPair ( name, val ) =
2513+ name ++ ": " ++ val ++ ";"
2515+ selector ++ " {" ++ String.join "" (List.map renderPair rules) ++ "}"
2518+fontAdjustmentRules converted =
2519+ ( [ ( "display", "block" )
2521+ , [ ( "display", "inline-block" )
2522+ , ( "line-height", String.fromFloat converted.height )
2523+ , ( "vertical-align", String.fromFloat converted.vertical ++ "em" )
2524+ , ( "font-size", String.fromFloat converted.size ++ "em" )
2529+typefaceAdjustment typefaces =
2037− case maybePseudo of
2532+ case found of
2038 Nothing ->
2533 Nothing ->
2039− selector ++ "{" ++ List.foldl (renderProps False) "" props ++ "\n}"
2534+ case face of
2536+ case with.adjustment of
2542+ ( fontAdjustmentRules
2543+ (.full (convertAdjustment adjustment))
2544+ , fontAdjustmentRules
2545+ (.capital (convertAdjustment adjustment))
2041− Just pseudo ->
2548+ _ ->
2042− case pseudo of
2549+ found
2044− case options.hover of
2048− ForceHover ->
2551+ Just _ ->
2049− selector ++ "-hv {" ++ List.foldl (renderProps True) "" props ++ "\n}"
2552+ found
2052− selector ++ "-hv:hover {" ++ List.foldl (renderProps False) "" props ++ "\n}"
2054− Focus ->
2558+fontName font =
2055− let
2559+ case font of
2056− renderedProps =
2560+ Serif ->
2057− List.foldl (renderProps False) "" props
2561+ "serif"
2068− ++ "-fs:not(.focus) {"
2078− , ".focusable-parent:focus ~ "
2088− Active ->
2563+ SansSerif ->
2089− selector ++ "-act:active {" ++ List.foldl (renderProps False) "" props ++ "\n}"
2564+ "sans-serif"
2091− renderStyleRule rule maybePseudo =
2566+ Monospace ->
2092− case rule of
2567+ "monospace"
2093− Style selector props ->
2094− renderStyle maybePseudo selector props
2096− Shadows name prop ->
2569+ Typeface name ->
2097− renderStyle
2570+ "\"" ++ name ++ "\""
2572+ ImportFont name url ->
2573+ "\"" ++ name ++ "\""
2575+ FontWith { name } ->
2099− ("." ++ name)
2576+ "\"" ++ name ++ "\""
2100− [ Property "box-shadow" prop
2577+
2579+topLevelValue rule =
2581+ FontFamily name typefaces ->
2582+ Just ( name, typefaces )
2588+renderProps force (Property key val) existing =
2590+ existing ++ "\n " ++ key ++ ": " ++ val ++ " !important;"
2593+ existing ++ "\n " ++ key ++ ": " ++ val ++ ";"
2596+encodeStyles options stylesheet =
2602+ renderStyleRule options style Nothing
2604+ ( getStyleName style, Encode.list Encode.string styled )
2103− Transparency name transparency ->
2608+
2609+toStyleSheetString : OptionRecord -> List Style -> String
2610+toStyleSheetString options stylesheet =
2612+ combine style rendered =
2613+ { rules = rendered.rules ++ renderStyleRule options style Nothing
2615+ case topLevelValue style of
2620+ topLevel :: rendered.topLevel
2623+ case List.foldl combine { topLevel = [], rules = [] } stylesheet of
2624+ { topLevel, rules } ->
2625+ renderTopLevelValues topLevel ++ String.concat rules
2628+renderStyle : OptionRecord -> Maybe PseudoClass -> String -> List Property -> List String
2629+renderStyle options maybePseudo selector props =
2630+ case maybePseudo of
2632+ [ selector ++ "{" ++ List.foldl (renderProps False) "" props ++ "\n}" ]
2637+ case options.hover of
2642+ [ selector ++ "-hv {" ++ List.foldl (renderProps True) "" props ++ "\n}" ]
2645+ [ selector ++ "-hv:hover {" ++ List.foldl (renderProps False) "" props ++ "\n}" ]
2105− opacity =
2649+ renderedProps =
2106− (1 - transparency)
2650+ List.foldl (renderProps False) "" props
2110− renderStyle
2652+ [ selector ++ "-fs:focus {" ++ renderedProps ++ "\n}"
2111− maybePseudo
2653+ , ("." ++ classes.any ++ ":focus " ++ selector ++ "-fs {")
2112− ("." ++ name)
2654+ ++ renderedProps
2113− [ Property "opacity" (String.fromFloat opacity)
2655+ ++ "\n}"
2656+ , (selector ++ "-fs:focus-within {")
2659+ , (".ui-slide-bar:focus + " ++ Internal.Style.dot classes.any ++ " .focusable-thumb" ++ selector ++ "-fs {")
2116− FontSize i ->
2664+ Active ->
2117− renderStyle
2665+ [ selector ++ "-act:active {" ++ List.foldl (renderProps False) "" props ++ "\n}" ]
2119− (".font-size-" ++ String.fromInt i)
2120− [ Property "font-size" (String.fromInt i ++ "px")
2123− FontFamily name typefaces ->
2127− [ Property "font-family" (renderFont typefaces)
2130− Single class prop val ->
2668+renderStyleRule : OptionRecord -> Style -> Maybe PseudoClass -> List String
2669+renderStyleRule options rule maybePseudo =
2671+ Style selector props ->
2131− renderStyle
2672+ renderStyle options maybePseudo selector props
2134− [ Property prop val
2137− Colored class prop color ->
2674+ Shadows name prop ->
2138− renderStyle
2675+ renderStyle options
2139− maybePseudo
2676+ maybePseudo
2140− ("." ++ class)
2677+ ("." ++ name)
2141− [ Property prop (formatColor color)
2678+ [ Property "box-shadow" prop
2144− SpacingStyle cls x y ->
2681+ Transparency name transparency ->
2146− class =
2683+ opacity =
2147− "." ++ cls
2684+ (1 - transparency)
2688+ renderStyle options
2691+ [ Property "opacity" (String.fromFloat opacity)
2149− xPx =
2694+ FontSize i ->
2695+ renderStyle options
2697+ (".font-size-" ++ String.fromInt i)
2150− String.fromInt x ++ "px"
2698+ [ Property "font-size" (String.fromInt i ++ "px")
2152− yPx =
2701+ FontFamily name typefaces ->
2705+ |> List.filterMap renderVariants
2706+ |> String.join ", "
2709+ [ Property "font-family"
2711+ |> List.map fontName
2153− String.fromInt y ++ "px"
2712+ |> String.join ", "
2714+ , Property "font-feature-settings" features
2715+ , Property "font-variant"
2716+ (if List.any hasSmallCaps typefaces then
2156− "." ++ Internal.Style.classes.row
2720+ "normal"
2724+ renderStyle options
2158− wrappedRow =
2729+ Single class prop val ->
2159− "." ++ Internal.Style.classes.wrapped ++ row
2730+ renderStyle options
2733+ [ Property prop val
2161− column =
2736+ Colored class prop color ->
2162− "." ++ Internal.Style.classes.column
2737+ renderStyle options
2740+ [ Property prop (formatColor color)
2164− page =
2743+ SpacingStyle cls x y ->
2165− "." ++ Internal.Style.classes.page
2744+ let
2167− paragraph =
2748+ halfX =
2168− "." ++ Internal.Style.classes.paragraph
2749+ String.fromFloat (toFloat x / 2) ++ "px"
2170− left =
2751+ halfY =
2171− "." ++ Internal.Style.classes.alignLeft
2752+ String.fromFloat (toFloat y / 2) ++ "px"
2174− "." ++ Internal.Style.classes.alignRight
2755+ String.fromInt x ++ "px"
2177− "." ++ Internal.Style.classes.any
2758+ String.fromInt y ++ "px"
2179− single =
2760+ row =
2180− "." ++ Internal.Style.classes.single
2761+ "." ++ Internal.Style.classes.row
2183− [ renderStyle maybePseudo (class ++ row ++ " > " ++ any) [ Property "margin-right" xPx ]
2185− -- margins don't apply to last element of normal, unwrapped rows
2763+ wrappedRow =
2186− , renderStyle maybePseudo (class ++ row ++ " > " ++ any ++ ":last-child") [ Property "margin" "0" ]
2764+ "." ++ Internal.Style.classes.wrapped ++ row
2188− -- For wrapped rows, margins always apply because we handle "canceling out" the other margins manually in the element.
2766+ column =
2189− , renderStyle maybePseudo
2767+ "." ++ Internal.Style.classes.column
2190− (class ++ wrappedRow ++ " > " ++ any)
2191− [ Property "margin" ("0 " ++ xPx ++ " " ++ yPx ++ " 0")
2193− , renderStyle maybePseudo
2194− (class ++ wrappedRow ++ " > " ++ any ++ ":last-child")
2195− [ Property "margin-right" "0"
2198− -- columns
2769+ page =
2199− , renderStyle maybePseudo (class ++ column ++ " > " ++ any ++ " + " ++ any) [ Property "margin-top" yPx ]
2770+ "." ++ Internal.Style.classes.page
2200− , renderStyle maybePseudo (class ++ page ++ " > " ++ any ++ " + " ++ any) [ Property "margin-top" yPx ]
2201− , renderStyle maybePseudo (class ++ page ++ " > " ++ left) [ Property "margin-right" xPx ]
2202− , renderStyle maybePseudo (class ++ page ++ " > " ++ right) [ Property "margin-left" xPx ]
2205− (class ++ paragraph)
2206− [ Property "line-height" ("calc(1em + " ++ String.fromInt y ++ "px)")
2210− ("textarea" ++ class)
2211− [ Property "line-height" ("calc(1em + " ++ String.fromInt y ++ "px)")
2216− -- (class ++ paragraph ++ " > " ++ any)
2217− -- [ Property "margin-right" xPx
2218− -- , Property "margin-bottom" yPx
2222− (class ++ paragraph ++ " > " ++ left)
2223− [ Property "margin-right" xPx
2227− (class ++ paragraph ++ " > " ++ right)
2228− [ Property "margin-left" xPx
2232− (class ++ paragraph ++ "::after")
2772+ paragraph =
2233− [ Property "content" "''"
2773+ "." ++ Internal.Style.classes.paragraph
2234− , Property "display" "block"
2235− , Property "height" "0"
2236− , Property "width" "0"
2237− , Property "margin-top" (String.fromInt (-1 * (y // 2)) ++ "px")
2241− (class ++ paragraph ++ "::before")
2242− [ Property "content" "''"
2243− , Property "display" "block"
2244− , Property "height" "0"
2245− , Property "width" "0"
2246− , Property "margin-bottom" (String.fromInt (-1 * (y // 2)) ++ "px")
2250− PaddingStyle cls top right bottom left ->
2775+ left =
2251− let
2776+ "." ++ Internal.Style.classes.alignLeft
2259− [ Property "padding"
2260− (String.fromInt top
2262− ++ String.fromInt right
2264− ++ String.fromInt bottom
2266− ++ String.fromInt left
2271− GridTemplateStyle template ->
2778+ right =
2272− let
2779+ "." ++ Internal.Style.classes.alignRight
2275− ++ String.join "-" (List.map lengthClassName template.rows)
2277− ++ String.join "-" (List.map lengthClassName template.columns)
2279− ++ lengthClassName (Tuple.first template.spacing)
2281− ++ lengthClassName (Tuple.second template.spacing)
2284− toGridLength (Tuple.second template.spacing)
2287− toGridLength (Tuple.first template.spacing)
2290− toGridLengthHelper Nothing Nothing x
2292− toGridLengthHelper minimum maximum x =
2295− String.fromInt px ++ "px"
2298− case ( minimum, maximum ) of
2299− ( Nothing, Nothing ) ->
2302− ( Just minSize, Nothing ) ->
2303− "minmax(" ++ String.fromInt minSize ++ "px, " ++ "max-content)"
2305− ( Nothing, Just maxSize ) ->
2306− "minmax(max-content, " ++ String.fromInt maxSize ++ "px)"
2308− ( Just minSize, Just maxSize ) ->
2309− "minmax(" ++ String.fromInt minSize ++ "px, " ++ String.fromInt maxSize ++ "px)"
2312− case ( minimum, maximum ) of
2313− ( Nothing, Nothing ) ->
2314− String.fromInt i ++ "fr"
2316− ( Just minSize, Nothing ) ->
2317− "minmax(" ++ String.fromInt minSize ++ "px, " ++ String.fromInt i ++ "fr" ++ "fr)"
2319− ( Nothing, Just maxSize ) ->
2320− "minmax(max-content, " ++ String.fromInt maxSize ++ "px)"
2322− ( Just minSize, Just maxSize ) ->
2323− "minmax(" ++ String.fromInt minSize ++ "px, " ++ String.fromInt maxSize ++ "px)"
2326− toGridLengthHelper (Just m) maximum len
2329− toGridLengthHelper minimum (Just m) len
2333− |> List.map toGridLength
2334− |> String.join ySpacing
2335− |> (\x -> "-ms-grid-columns: " ++ x ++ ";")
2339− |> List.map toGridLength
2340− |> String.join ySpacing
2341− |> (\x -> "-ms-grid-rows: " ++ x ++ ";")
2344− class ++ "{" ++ msColumns ++ msRows ++ "}"
2348− |> List.map toGridLength
2350− |> (\x -> "grid-template-columns: " ++ x ++ ";")
2354− |> List.map toGridLength
2356− |> (\x -> "grid-template-rows: " ++ x ++ ";")
2359− "grid-column-gap:" ++ toGridLength (Tuple.first template.spacing) ++ ";"
2362− "grid-row-gap:" ++ toGridLength (Tuple.second template.spacing) ++ ";"
2365− class ++ "{" ++ columns ++ rows ++ gapX ++ gapY ++ "}"
2368− "@supports (display:grid) {" ++ modernGrid ++ "}"
2372− GridPosition position ->
2781+ any =
2373− let
2782+ "." ++ Internal.Style.classes.any
2376− ++ String.fromInt position.row
2378− ++ String.fromInt position.col
2380− ++ String.fromInt position.width
2382− ++ String.fromInt position.height
2387− ++ String.fromInt position.row
2389− , "-ms-grid-row-span: "
2390− ++ String.fromInt position.height
2392− , "-ms-grid-column: "
2393− ++ String.fromInt position.col
2395− , "-ms-grid-column-span: "
2396− ++ String.fromInt position.width
2401− class ++ "{" ++ msPosition ++ "}"
2406− ++ String.fromInt position.row
2408− ++ String.fromInt (position.row + position.height)
2411− ++ String.fromInt position.col
2413− ++ String.fromInt (position.col + position.width)
2418− class ++ "{" ++ modernPosition ++ "}"
2421− "@supports (display:grid) {" ++ modernGrid ++ "}"
2425− PseudoSelector class styles ->
2784+ single =
2785+ "." ++ Internal.Style.classes.single
2788+ [ renderStyle options maybePseudo (class ++ row ++ " > " ++ any ++ " + " ++ any) [ Property "margin-left" xPx ]
2790+ -- margins don't apply to last element of normal, unwrapped rows
2791+ -- , renderStyle options maybePseudo (class ++ row ++ " > " ++ any ++ ":first-child") [ Property "margin" "0" ]
2792+ -- For wrapped rows, margins always apply because we handle "canceling out" the other margins manually in the element.
2793+ , renderStyle options
2795+ (class ++ wrappedRow ++ " > " ++ any)
2796+ [ Property "margin" (halfY ++ " " ++ halfX)
2799+ -- , renderStyle options maybePseudo
2800+ -- (class ++ wrappedRow ++ " > " ++ any ++ ":last-child")
2801+ -- [ Property "margin-right" "0"
2804+ , renderStyle options maybePseudo (class ++ column ++ " > " ++ any ++ " + " ++ any) [ Property "margin-top" yPx ]
2805+ , renderStyle options maybePseudo (class ++ page ++ " > " ++ any ++ " + " ++ any) [ Property "margin-top" yPx ]
2806+ , renderStyle options maybePseudo (class ++ page ++ " > " ++ left) [ Property "margin-right" xPx ]
2807+ , renderStyle options maybePseudo (class ++ page ++ " > " ++ right) [ Property "margin-left" xPx ]
2808+ , renderStyle options
2810+ (class ++ paragraph)
2811+ [ Property "line-height" ("calc(1em + " ++ String.fromInt y ++ "px)")
2813+ , renderStyle options
2815+ ("textarea" ++ any ++ class)
2816+ [ Property "line-height" ("calc(1em + " ++ String.fromInt y ++ "px)")
2817+ , Property "height" ("calc(100% + " ++ String.fromInt y ++ "px)")
2820+ -- , renderStyle options
2822+ -- (class ++ paragraph ++ " > " ++ any)
2823+ -- [ Property "margin-right" xPx
2824+ -- , Property "margin-bottom" yPx
2826+ , renderStyle options
2828+ (class ++ paragraph ++ " > " ++ left)
2829+ [ Property "margin-right" xPx
2831+ , renderStyle options
2833+ (class ++ paragraph ++ " > " ++ right)
2834+ [ Property "margin-left" xPx
2836+ , renderStyle options
2838+ (class ++ paragraph ++ "::after")
2839+ [ Property "content" "''"
2840+ , Property "display" "block"
2841+ , Property "height" "0"
2842+ , Property "width" "0"
2843+ , Property "margin-top" (String.fromInt (-1 * (y // 2)) ++ "px")
2845+ , renderStyle options
2847+ (class ++ paragraph ++ "::before")
2848+ [ Property "content" "''"
2849+ , Property "display" "block"
2850+ , Property "height" "0"
2851+ , Property "width" "0"
2852+ , Property "margin-bottom" (String.fromInt (-1 * (y // 2)) ++ "px")
2856+ PaddingStyle cls top right bottom left ->
2862+ renderStyle options
2865+ [ Property "padding"
2866+ (String.fromFloat top
2868+ ++ String.fromFloat right
2870+ ++ String.fromFloat bottom
2872+ ++ String.fromFloat left
2877+ BorderWidth cls top right bottom left ->
2427− renderPseudoRule style =
2879+ class =
2428− renderStyleRule style (Just class)
2880+ "."
2430− List.map renderPseudoRule styles
2882+ in
2883+ renderStyle options
2886+ [ Property "border-width"
2887+ (String.fromInt top
2889+ ++ String.fromInt right
2891+ ++ String.fromInt bottom
2893+ ++ String.fromInt left
2898+ GridTemplateStyle template ->
2902+ ++ String.join "-" (List.map lengthClassName template.rows)
2904+ ++ String.join "-" (List.map lengthClassName template.columns)
2906+ ++ lengthClassName (Tuple.first template.spacing)
2908+ ++ lengthClassName (Tuple.second template.spacing)
2911+ toGridLength (Tuple.second template.spacing)
2914+ toGridLength (Tuple.first template.spacing)
2917+ toGridLengthHelper Nothing Nothing x
2919+ toGridLengthHelper minimum maximum x =
2922+ String.fromInt px ++ "px"
2925+ case ( minimum, maximum ) of
2926+ ( Nothing, Nothing ) ->
2929+ ( Just minSize, Nothing ) ->
2930+ "minmax(" ++ String.fromInt minSize ++ "px, " ++ "max-content)"
2932+ ( Nothing, Just maxSize ) ->
2933+ "minmax(max-content, " ++ String.fromInt maxSize ++ "px)"
2935+ ( Just minSize, Just maxSize ) ->
2936+ "minmax(" ++ String.fromInt minSize ++ "px, " ++ String.fromInt maxSize ++ "px)"
2939+ case ( minimum, maximum ) of
2940+ ( Nothing, Nothing ) ->
2941+ String.fromInt i ++ "fr"
2943+ ( Just minSize, Nothing ) ->
2944+ "minmax(" ++ String.fromInt minSize ++ "px, " ++ String.fromInt i ++ "fr" ++ "fr)"
2946+ ( Nothing, Just maxSize ) ->
2947+ "minmax(max-content, " ++ String.fromInt maxSize ++ "px)"
2949+ ( Just minSize, Just maxSize ) ->
2950+ "minmax(" ++ String.fromInt minSize ++ "px, " ++ String.fromInt maxSize ++ "px)"
2953+ toGridLengthHelper (Just m) maximum len
2956+ toGridLengthHelper minimum (Just m) len
2960+ |> List.map toGridLength
2961+ |> String.join ySpacing
2962+ |> (\x -> "-ms-grid-columns: " ++ x ++ ";")
2966+ |> List.map toGridLength
2967+ |> String.join ySpacing
2968+ |> (\x -> "-ms-grid-rows: " ++ x ++ ";")
2971+ class ++ "{" ++ msColumns ++ msRows ++ "}"
2975+ |> List.map toGridLength
2431 |> String.join " "
2976 |> String.join " "
2977+ |> (\x -> "grid-template-columns: " ++ x ++ ";")
2433− Transform transform ->
2979+ rows =
2434− let
2980+ template.rows
2435− val =
2981+ |> List.map toGridLength
2436− transformValue transform
2982+ |> String.join " "
2983+ |> (\x -> "grid-template-rows: " ++ x ++ ";")
2438− class =
2985+ gapX =
2439− transformClass transform
2986+ "grid-column-gap:" ++ toGridLength (Tuple.first template.spacing) ++ ";"
2441− case ( class, val ) of
2442− ( Just cls, Just v ) ->
2446− [ Property "transform"
2451− ""
2989+ "grid-row-gap:" ++ toGridLength (Tuple.second template.spacing) ++ ";"
2453− combine style rendered =
2991+ modernGrid =
2454− { rendered
2992+ class ++ "{" ++ columns ++ rows ++ gapX ++ gapY ++ "}"
2455− | rules = rendered.rules ++ renderStyleRule style Nothing
2457− case renderTopLevels style of
2461− Just topLevel ->
2994+ supports =
2462− rendered.topLevel ++ topLevel
2995+ "@supports (display:grid) {" ++ modernGrid ++ "}"
3001+ GridPosition position ->
3005+ ++ String.fromInt position.row
3007+ ++ String.fromInt position.col
3009+ ++ String.fromInt position.width
3011+ ++ String.fromInt position.height
3016+ ++ String.fromInt position.row
3018+ , "-ms-grid-row-span: "
3019+ ++ String.fromInt position.height
3021+ , "-ms-grid-column: "
3022+ ++ String.fromInt position.col
3024+ , "-ms-grid-column-span: "
3025+ ++ String.fromInt position.width
3030+ class ++ "{" ++ msPosition ++ "}"
3035+ ++ String.fromInt position.row
3037+ ++ String.fromInt (position.row + position.height)
3040+ ++ String.fromInt position.col
3042+ ++ String.fromInt (position.col + position.width)
3047+ class ++ "{" ++ modernPosition ++ "}"
3050+ "@supports (display:grid) {" ++ modernGrid ++ "}"
2465− case List.foldl combine { rules = "", topLevel = "" } stylesheet of
3052+ [ base
2466− { topLevel, rules } ->
3053+ , supports
2467− topLevel ++ rules
3054+ ]
3056+ PseudoSelector class styles ->
3058+ renderPseudoRule style =
3059+ renderStyleRule options style (Just class)
3061+ List.concatMap renderPseudoRule styles
3063+ Transform transform ->
3066+ transformValue transform
3069+ transformClass transform
3071+ case ( class, val ) of
3072+ ( Just cls, Just v ) ->
3073+ renderStyle options
3076+ [ Property "transform"
2470lengthClassName : Length -> String
3084lengthClassName : Length -> String
@@ -2504,12 +3118,12 @@ formatTextShadow shadow =
2507−textShadowName shadow =
3121+textShadowClass shadow =
2508 String.concat
3122 String.concat
2510− , String.fromFloat (Tuple.first shadow.offset) ++ "px"
3124+ , floatClass (Tuple.first shadow.offset) ++ "px"
2511− , String.fromFloat (Tuple.second shadow.offset) ++ "px"
3125+ , floatClass (Tuple.second shadow.offset) ++ "px"
2512− , String.fromFloat shadow.blur ++ "px"
3126+ , floatClass shadow.blur ++ "px"
2513 , formatColorClass shadow.color
3127 , formatColorClass shadow.color
@@ -2519,6 +3133,7 @@ formatBoxShadow shadow =
2519 List.filterMap identity
3133 List.filterMap identity
2520 [ if shadow.inset then
3134 [ if shadow.inset then
2521 Just "inset"
3135 Just "inset"
2524 , Just <| String.fromFloat (Tuple.first shadow.offset) ++ "px"
3139 , Just <| String.fromFloat (Tuple.first shadow.offset) ++ "px"
@@ -2529,16 +3144,17 @@ formatBoxShadow shadow =
2532−boxShadowName shadow =
3147+boxShadowClass shadow =
2533 String.concat <|
3148 String.concat <|
2534 [ if shadow.inset then
3149 [ if shadow.inset then
2535 "box-inset"
3150 "box-inset"
2538− , String.fromFloat (Tuple.first shadow.offset) ++ "px"
3154+ , floatClass (Tuple.first shadow.offset) ++ "px"
2539− , String.fromFloat (Tuple.second shadow.offset) ++ "px"
3155+ , floatClass (Tuple.second shadow.offset) ++ "px"
2540− , String.fromFloat shadow.blur ++ "px"
3156+ , floatClass shadow.blur ++ "px"
2541− , String.fromFloat shadow.size ++ "px"
3157+ , floatClass shadow.size ++ "px"
2542 , formatColorClass shadow.color
3158 , formatColorClass shadow.color
@@ -2583,6 +3199,17 @@ paddingName top right bottom left =
2583 ++ String.fromInt left
3199 ++ String.fromInt left
3202+paddingNameFloat top right bottom left =
3206+ ++ floatClass right
3208+ ++ floatClass bottom
2586getStyleName : Style -> String
3213getStyleName : Style -> String
2587getStyleName style =
3214getStyleName style =
2588 case style of
3215 case style of
@@ -2613,6 +3240,9 @@ getStyleName style =
2613 PaddingStyle cls top right bottom left ->
3240 PaddingStyle cls top right bottom left ->
3243+ BorderWidth cls top right bottom left ->
2616 GridTemplateStyle template ->
3246 GridTemplateStyle template ->
2617 "grid-rows-"
3247 "grid-rows-"
2618 ++ String.join "-" (List.map lengthClassName template.rows)
3248 ++ String.join "-" (List.map lengthClassName template.rows)
@@ -2845,3 +3475,76 @@ onlyStyles attr =
3481+{- Font Adjustments -}
3484+convertAdjustment adjustment =
3500+ ((ascender - newBaseline) / 2) + newBaseline
3503+ ((ascender - descender) / 2) + descender
3506+ [ adjustment.capital
3507+ , adjustment.baseline
3508+ , adjustment.descender
3509+ , adjustment.lowercase
3513+ Maybe.withDefault adjustment.capital (List.maximum lines)
3516+ Maybe.withDefault adjustment.descender (List.minimum lines)
3520+ |> List.filter (\x -> x /= descender)
3522+ |> Maybe.withDefault adjustment.baseline
3528+ 1 / (ascender - newBaseline)
3531+ 1 / (ascender - descender)
3536+ -- (oldMiddle - newFullMiddle) * 2
3539+ adjust fullSize (ascender - descender) fullVertical
3541+ adjust capitalSize (ascender - newBaseline) capitalVertical
3545+adjust size height vertical =
3546+ { vertical = vertical