@@ -16,6 +16,7 @@ module Internal.Model exposing
1616 , LayoutContext(..)
1717 , Length(..)
1818 , Location(..)
19+ , NearbyChildren(..)
1920 , NodeName(..)
2021 , Option(..)
2122 , OptionRecord
@@ -29,6 +30,7 @@ module Internal.Model exposing
2930 , TransformComponent(..)
3031 , Transformation(..)
3132 , VAlign(..)
33+ , Variant(..)
3234 , XYZ
3335 , addNodeName
3436 , addWhen
@@ -40,7 +42,7 @@ module Internal.Model exposing
4042 , asParagraph
4143 , asRow
4244 , asTextColumn
43− , boxShadowName
45+ , boxShadowClass
4446 , columnClass
4547 , composeTransformation
4648 , contextClasses
@@ -77,31 +79,30 @@ module Internal.Model exposing
7779 , onlyStyles
7880 , optionsToRecord
7981 , paddingName
82+ , paddingNameFloat
8083 , pageClass
8184 , paragraphClass
8285 , reduceRecursive
8386 , reduceStyles
8487 , reduceStylesRecursive
8588 , removeNever
86− , renderFocusStyle
87− -- , renderFont
88−
8989 , renderFontClassName
9090 , renderHeight
9191 , renderRoot
92+ , renderVariant
9293 , renderWidth
9394 , rootStyle
9495 , rowClass
9596 , singleClass
9697 , spacingName
97− , staticRoot
9898 , tag
99− , textShadowName
99+ , textShadowClass
100100 , toHtml
101101 , toStyleSheet
102102 , transformClass
103103 , unstyled
104104 , unwrapDecorations
105+ , variantName
105106 )
106107
107108{-| -}
@@ -111,7 +112,7 @@ import Html.Attributes
111112import Html.Keyed
112113import Internal.Flag as Flag exposing (Flag)
113114import Internal.Style exposing (classes, dot)
114−import Json.Encode as Json
115+import Json.Encode as Encode
115116import Set exposing (Set)
116117import VirtualDom
117118
@@ -173,7 +174,7 @@ type Style
173174 | Colored String String Color
174175 | SpacingStyle String Int Int
175176 | BorderWidth String Int Int Int Int
176− | PaddingStyle String Int Int Int Int
177+ | PaddingStyle String Float Float Float Float
177178 | GridTemplateStyle
178179 { spacing : ( Length, Length )
179180 , columns : List Length
@@ -221,11 +222,71 @@ type Font
221222 | ImportFont String String
222223 | FontWith
223224 { name : String
224− , url : Maybe String
225− , adjustment : Adjustment
225+ , adjustment : Maybe Adjustment
226+ , variants : List Variant
226227 }
227228
228229
230+type Variant
231+ = VariantActive String
232+ | VariantOff String
233+ | VariantIndexed String Int
234+
235+
236+renderVariant var =
237+ case var of
238+ VariantActive name ->
239+ "\"" ++ name ++ "\""
240+
241+ VariantOff name ->
242+ "\"" ++ name ++ "\" 0"
243+
244+ VariantIndexed name index ->
245+ "\"" ++ name ++ "\" " ++ String.fromInt index
246+
247+
248+variantName var =
249+ case var of
250+ VariantActive name ->
251+ name
252+
253+ VariantOff name ->
254+ name ++ "-0"
255+
256+ VariantIndexed name index ->
257+ name ++ "-" ++ String.fromInt index
258+
259+
260+renderVariants typeface =
261+ case typeface of
262+ FontWith font ->
263+ Just (String.join ", " (List.map renderVariant font.variants))
264+
265+ _ ->
266+ Nothing
267+
268+
269+isSmallCaps var =
270+ case var of
271+ VariantActive name ->
272+ name == "smcp"
273+
274+ VariantOff name ->
275+ False
276+
277+ VariantIndexed name index ->
278+ name == "smcp" && index == 1
279+
280+
281+hasSmallCaps typeface =
282+ case typeface of
283+ FontWith font ->
284+ List.any isSmallCaps font.variants
285+
286+ _ ->
287+ False
288+
289+
229290type Property
230291 = Property String String
231292
@@ -311,6 +372,13 @@ type NodeName
311372 | Embedded String String
312373
313374
375+type NearbyChildren msg
376+ = NoNearbyChildren
377+ | ChildrenBehind (List (Html.Html msg))
378+ | ChildrenInFront (List (Html.Html msg))
379+ | ChildrenBehindAndInFront (List (Html.Html msg)) (List (Html.Html msg))
380+
381+
314382div =
315383 Generic
316384
@@ -319,7 +387,7 @@ type alias Gathered msg =
319387 { node : NodeName
320388 , attributes : List (VirtualDom.Attribute msg)
321389 , styles : List Style
322− , children : List (VirtualDom.Node msg)
390+ , children : NearbyChildren msg
323391 , has : Flag.Field
324392 }
325393
@@ -387,7 +455,10 @@ finalizeNode has node attributes children embedMode parentContext =
387455 Embedded nodeName internal ->
388456 VirtualDom.node nodeName
389457 attributes
390− [ createNode internal [ Html.Attributes.class (classes.any ++ " " ++ classes.single) ]
458+ [ createNode internal
459+ [ Html.Attributes.class
460+ (classes.any ++ " " ++ classes.single)
461+ ]
391462 ]
392463 in
393464 case parentContext of
@@ -464,49 +535,45 @@ finalizeNode has node attributes children embedMode parentContext =
464535
465536
466537embedWith static opts styles children =
538+ let
539+ dynamicStyleSheet =
540+ styles
541+ |> List.foldl reduceStyles ( Set.empty, renderFocusStyle opts.focus )
542+ |> Tuple.second
543+ -- |> reduceStylesRecursive Set.empty [ ]) --renderFocusStyle opts.focus ]
544+ -- |> sortedReduce
545+ |> toStyleSheet opts
546+ in
467547 if static then
468− staticRoot
469− :: (styles
470− |> List.foldl reduceStyles ( Set.empty, [ renderFocusStyle opts.focus ] )
471− |> Tuple.second
472− -- |> reduceStylesRecursive Set.empty [ ]) --renderFocusStyle opts.focus ]
473− -- |> sortedReduce
474− |> toStyleSheet opts
475− )
548+ staticRoot opts
549+ :: dynamicStyleSheet
476550 :: children
477551
478552 else
479− (styles
480− |> List.foldl reduceStyles ( Set.empty, [ renderFocusStyle opts.focus ] )
481− |> Tuple.second
482− -- |> reduceStylesRecursive Set.empty [ ]) --renderFocusStyle opts.focus ]
483− -- |> sortedReduce
484− |> toStyleSheet opts
485− )
553+ dynamicStyleSheet
486554 :: children
487555
488556
489557embedKeyed static opts styles children =
558+ let
559+ dynamicStyleSheet =
560+ styles
561+ |> List.foldl reduceStyles ( Set.empty, renderFocusStyle opts.focus )
562+ |> Tuple.second
563+ -- |> reduceStylesRecursive Set.empty [ ]) --renderFocusStyle opts.focus ]
564+ -- |> sortedReduce
565+ |> toStyleSheet opts
566+ in
490567 if static then
491− ( "static-stylesheet", staticRoot )
568+ ( "static-stylesheet", staticRoot opts )
492569 :: ( "dynamic-stylesheet"
493− , styles
494− |> List.foldl reduceStyles ( Set.empty, [ renderFocusStyle opts.focus ] )
495− |> Tuple.second
496− -- |> reduceStylesRecursive Set.empty [ ]) --renderFocusStyle opts.focus ]
497− -- |> sortedReduce
498− |> toStyleSheet opts
570+ , dynamicStyleSheet
499571 )
500572 :: children
501573
502574 else
503575 ( "dynamic-stylesheet"
504− , styles
505− |> List.foldl reduceStyles ( Set.empty, [ renderFocusStyle opts.focus ] )
506− |> Tuple.second
507− -- |> reduceStylesRecursive Set.empty [ ]) --renderFocusStyle opts.focus ]
508− -- |> sortedReduce
509− |> toStyleSheet opts
576+ , dynamicStyleSheet
510577 )
511578 :: children
512579
@@ -822,7 +889,16 @@ skippable flag style =
822889 False
823890
824891
825−gatherAttrRecursive : String -> NodeName -> Flag.Field -> Transformation -> List Style -> List (VirtualDom.Attribute msg) -> List (VirtualDom.Node msg) -> List (Attribute aligned msg) -> Gathered msg
892+gatherAttrRecursive :
893+ String
894+ -> NodeName
895+ -> Flag.Field
896+ -> Transformation
897+ -> List Style
898+ -> List (VirtualDom.Attribute msg)
899+ -> NearbyChildren msg
900+ -> List (Attribute aligned msg)
901+ -> Gathered msg
826902gatherAttrRecursive classes node has transform styles attrs children elementAttrs =
827903 case elementAttrs of
828904 [] ->
@@ -956,7 +1032,7 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
9561032 in
9571033 gatherAttrRecursive (classes ++ " " ++ newClass)
9581034 node
959− (Flag.merge addToFlags has)
1035+ (Flag.merge addToFlags (Flag.add Flag.width has))
9601036 transform
9611037 (newStyles ++ styles)
9621038 attrs
@@ -977,7 +1053,7 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
9771053 name =
9781054 "height-px-" ++ val
9791055 in
980− gatherAttrRecursive (name ++ " " ++ classes)
1056+ gatherAttrRecursive (Internal.Style.classes.heightExact ++ " " ++ name ++ " " ++ classes)
9811057 node
9821058 (Flag.add Flag.height has)
9831059 transform
@@ -1034,7 +1110,7 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
10341110 in
10351111 gatherAttrRecursive (classes ++ " " ++ newClass)
10361112 node
1037− (Flag.merge addToFlags has)
1113+ (Flag.merge addToFlags (Flag.add Flag.height has))
10381114 transform
10391115 (newStyles ++ styles)
10401116 attrs
@@ -1066,20 +1142,15 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
10661142 gatherAttrRecursive classes (addNodeName "h6" node) has transform styles attrs children remaining
10671143
10681144 Paragraph ->
1069− let
1070− newNode =
1071− case node of
1072− Generic ->
1073− NodeName "p"
1074−
1075− NodeName name ->
1076− NodeName name
1077−
1078− Embedded x y ->
1079− Embedded x y
1080− in
1081− gatherAttrRecursive classes
1082− newNode
1145+ -- previously we rendered a <p> tag, though apparently this invalidates the html if it has <div>s inside.
1146+ -- Since we can't guaranteee that there are no divs, we need another strategy.
1147+ -- While it's not documented in many places, there apparently is a paragraph aria role
1148+ -- https://github.com/w3c/aria/blob/11f85f41a5b621fdbe85fc9bcdcd270e653a48ba/common/script/roleInfo.js
1149+ -- Though we'll need to wait till it gets released in an official wai-aria spec to use it.
1150+ -- If it's used at the moment, then Lighthouse complains (likely rightfully) that role paragraph is not recognized.
1151+ gatherAttrRecursive
1152+ classes
1153+ node
10831154 has
10841155 transform
10851156 styles
@@ -1114,75 +1185,16 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
11141185
11151186 Styled styled ->
11161187 styles ++ styled.styles
1117−
1118− nearbyElement =
1119− Html.div
1120− [ Html.Attributes.class <|
1121− case location of
1122− Above ->
1123− String.join " "
1124− [ Internal.Style.classes.nearby
1125− , Internal.Style.classes.single
1126− , Internal.Style.classes.above
1127− ]
1128−
1129− Below ->
1130− String.join " "
1131− [ Internal.Style.classes.nearby
1132− , Internal.Style.classes.single
1133− , Internal.Style.classes.below
1134− ]
1135−
1136− OnRight ->
1137− String.join " "
1138− [ Internal.Style.classes.nearby
1139− , Internal.Style.classes.single
1140− , Internal.Style.classes.onRight
1141− ]
1142−
1143− OnLeft ->
1144− String.join " "
1145− [ Internal.Style.classes.nearby
1146− , Internal.Style.classes.single
1147− , Internal.Style.classes.onLeft
1148− ]
1149−
1150− InFront ->
1151− String.join " "
1152− [ Internal.Style.classes.nearby
1153− , Internal.Style.classes.single
1154− , Internal.Style.classes.inFront
1155− ]
1156−
1157− Behind ->
1158− String.join " "
1159− [ Internal.Style.classes.nearby
1160− , Internal.Style.classes.single
1161− , Internal.Style.classes.behind
1162− ]
1163− ]
1164− [ case elem of
1165− Empty ->
1166− VirtualDom.text ""
1167−
1168− Text str ->
1169− textElement str
1170−
1171− Unstyled html ->
1172− html asEl
1173−
1174− Styled styled ->
1175− styled.html NoStyleSheet asEl
1176− ]
1177−
1178− newClasses =
1179− if location == Behind then
1180− Internal.Style.classes.hasBehind ++ " " ++ classes
1181−
1182− else
1183− classes
11841188 in
1185− gatherAttrRecursive newClasses node has transform newStyles attrs (nearbyElement :: children) remaining
1189+ gatherAttrRecursive
1190+ classes
1191+ node
1192+ has
1193+ transform
1194+ newStyles
1195+ attrs
1196+ (addNearbyElement location elem children)
1197+ remaining
11861198
11871199 AlignX x ->
11881200 if Flag.present Flag.xAlign has then
@@ -1238,6 +1250,106 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
12381250 remaining
12391251
12401252
1253+addNearbyElement location elem existing =
1254+ let
1255+ nearby =
1256+ nearbyElement location elem
1257+ in
1258+ case existing of
1259+ NoNearbyChildren ->
1260+ case location of
1261+ Behind ->
1262+ ChildrenBehind [ nearby ]
1263+
1264+ _ ->
1265+ ChildrenInFront [ nearby ]
1266+
1267+ ChildrenBehind existingBehind ->
1268+ case location of
1269+ Behind ->
1270+ ChildrenBehind (nearby :: existingBehind)
1271+
1272+ _ ->
1273+ ChildrenBehindAndInFront existingBehind [ nearby ]
1274+
1275+ ChildrenInFront existingInFront ->
1276+ case location of
1277+ Behind ->
1278+ ChildrenBehindAndInFront [ nearby ] existingInFront
1279+
1280+ _ ->
1281+ ChildrenInFront (nearby :: existingInFront)
1282+
1283+ ChildrenBehindAndInFront existingBehind existingInFront ->
1284+ case location of
1285+ Behind ->
1286+ ChildrenBehindAndInFront (nearby :: existingBehind) existingInFront
1287+
1288+ _ ->
1289+ ChildrenBehindAndInFront existingBehind (nearby :: existingInFront)
1290+
1291+
1292+nearbyElement location elem =
1293+ Html.div
1294+ [ Html.Attributes.class <|
1295+ case location of
1296+ Above ->
1297+ String.join " "
1298+ [ Internal.Style.classes.nearby
1299+ , Internal.Style.classes.single
1300+ , Internal.Style.classes.above
1301+ ]
1302+
1303+ Below ->
1304+ String.join " "
1305+ [ Internal.Style.classes.nearby
1306+ , Internal.Style.classes.single
1307+ , Internal.Style.classes.below
1308+ ]
1309+
1310+ OnRight ->
1311+ String.join " "
1312+ [ Internal.Style.classes.nearby
1313+ , Internal.Style.classes.single
1314+ , Internal.Style.classes.onRight
1315+ ]
1316+
1317+ OnLeft ->
1318+ String.join " "
1319+ [ Internal.Style.classes.nearby
1320+ , Internal.Style.classes.single
1321+ , Internal.Style.classes.onLeft
1322+ ]
1323+
1324+ InFront ->
1325+ String.join " "
1326+ [ Internal.Style.classes.nearby
1327+ , Internal.Style.classes.single
1328+ , Internal.Style.classes.inFront
1329+ ]
1330+
1331+ Behind ->
1332+ String.join " "
1333+ [ Internal.Style.classes.nearby
1334+ , Internal.Style.classes.single
1335+ , Internal.Style.classes.behind
1336+ ]
1337+ ]
1338+ [ case elem of
1339+ Empty ->
1340+ VirtualDom.text ""
1341+
1342+ Text str ->
1343+ textElement str
1344+
1345+ Unstyled html ->
1346+ html asEl
1347+
1348+ Styled styled ->
1349+ styled.html NoStyleSheet asEl
1350+ ]
1351+
1352+
12411353renderWidth w =
12421354 case w of
12431355 Px px ->
@@ -1324,7 +1436,7 @@ renderHeight h =
13241436 "height-px-" ++ val
13251437 in
13261438 ( Flag.none
1327− , name
1439+ , Internal.Style.classes.heightExact ++ " " ++ name
13281440 , [ Single name "height" (val ++ "px") ]
13291441 )
13301442
@@ -1347,7 +1459,7 @@ renderHeight h =
13471459 , [ Single
13481460 (Internal.Style.classes.any
13491461 ++ "."
1350− ++ Internal.Style.classes.row
1462+ ++ Internal.Style.classes.column
13511463 ++ " > "
13521464 ++ (Internal.Style.dot <| "height-fill-" ++ String.fromInt portion)
13531465 )
@@ -1366,7 +1478,9 @@ renderHeight h =
13661478 Single
13671479 cls
13681480 "min-height"
1369− (String.fromInt minSize ++ "px")
1481+ -- This needs to be !important because we're using `min-height: min-content`
1482+ -- to correct for safari's incorrect implementation of flexbox.
1483+ (String.fromInt minSize ++ "px !important")
13701484
13711485 ( newFlag, newAttrs, newStyle ) =
13721486 renderHeight len
@@ -1444,7 +1558,7 @@ element : LayoutContext -> NodeName -> List (Attribute aligned msg) -> Children
14441558element context node attributes children =
14451559 attributes
14461560 |> List.reverse
1447− |> gatherAttrRecursive (contextClasses context) node Flag.none untransformed [] [] []
1561+ |> gatherAttrRecursive (contextClasses context) node Flag.none untransformed [] [] NoNearbyChildren
14481562 |> createElement context children
14491563
14501564
@@ -1511,13 +1625,12 @@ createElement context children rendered =
15111625 -- , existingStyles
15121626 -- )
15131627 -- else
1514− ( textElement
1515− (if context == asParagraph then
1516− str
1628+ ( (if context == asEl then
1629+ textElementFill str
15171630
1518− else
1519− str
1520− )
1631+ else
1632+ textElement str
1633+ )
15211634 :: htmls
15221635 , existingStyles
15231636 )
@@ -1577,8 +1690,11 @@ createElement context children rendered =
15771690 -- )
15781691 -- else
15791692 ( ( key
1580− , textElement
1581− str
1693+ , if context == asEl then
1694+ textElementFill str
1695+
1696+ else
1697+ textElement str
15821698 )
15831699 :: htmls
15841700 , existingStyles
@@ -1605,13 +1721,8 @@ createElement context children rendered =
16051721 (finalizeNode rendered.has
16061722 rendered.node
16071723 rendered.attributes
1608− (Keyed <|
1609− keyed
1610− ++ List.map
1611− (\x ->
1612− ( "nearby-elements-pls", x )
1613− )
1614− rendered.children
1724+ (Keyed
1725+ (addKeyedChildren "nearby-element-pls" keyed rendered.children)
16151726 )
16161727 NoStyleSheet
16171728 )
@@ -1625,13 +1736,7 @@ createElement context children rendered =
16251736 rendered.node
16261737 rendered.attributes
16271738 (Keyed
1628− (keyed
1629− ++ List.map
1630− (\x ->
1631− ( "nearby-elements-pls", x )
1632− )
1633− rendered.children
1634− )
1739+ (addKeyedChildren "nearby-element-pls" keyed rendered.children)
16351740 )
16361741 }
16371742
@@ -1653,7 +1758,7 @@ createElement context children rendered =
16531758 rendered.has
16541759 rendered.node
16551760 rendered.attributes
1656− (Unkeyed <| unkeyed ++ rendered.children)
1761+ (Unkeyed (addChildren unkeyed rendered.children))
16571762 NoStyleSheet
16581763 )
16591764
@@ -1665,10 +1770,42 @@ createElement context children rendered =
16651770 rendered.has
16661771 rendered.node
16671772 rendered.attributes
1668− (Unkeyed (unkeyed ++ rendered.children))
1773+ (Unkeyed (addChildren unkeyed rendered.children))
16691774 }
16701775
16711776
1777+addChildren existing nearbyChildren =
1778+ case nearbyChildren of
1779+ NoNearbyChildren ->
1780+ existing
1781+
1782+ ChildrenBehind behind ->
1783+ behind ++ existing
1784+
1785+ ChildrenInFront inFront ->
1786+ existing ++ inFront
1787+
1788+ ChildrenBehindAndInFront behind inFront ->
1789+ behind ++ existing ++ inFront
1790+
1791+
1792+addKeyedChildren key existing nearbyChildren =
1793+ case nearbyChildren of
1794+ NoNearbyChildren ->
1795+ existing
1796+
1797+ ChildrenBehind behind ->
1798+ List.map (\x -> ( key, x )) behind ++ existing
1799+
1800+ ChildrenInFront inFront ->
1801+ existing ++ List.map (\x -> ( key, x )) inFront
1802+
1803+ ChildrenBehindAndInFront behind inFront ->
1804+ List.map (\x -> ( key, x )) behind
1805+ ++ existing
1806+ ++ List.map (\x -> ( key, x )) inFront
1807+
1808+
16721809unit =
16731810 0
16741811
@@ -1680,8 +1817,20 @@ defaultOptions =
16801817 }
16811818
16821819
1683−staticRoot =
1684− VirtualDom.node "style" [] [ VirtualDom.text Internal.Style.rules ]
1820+staticRoot : OptionRecord -> VirtualDom.Node msg
1821+staticRoot opts =
1822+ case opts.mode of
1823+ Layout ->
1824+ -- wrap the style node in a div to prevent `Dark Reader` from blowin up the dom.
1825+ VirtualDom.node "div"
1826+ []
1827+ [ VirtualDom.node "style" [] [ VirtualDom.text Internal.Style.rules ] ]
1828+
1829+ NoStaticStyleSheet ->
1830+ VirtualDom.text ""
1831+
1832+ WithVirtualCss ->
1833+ VirtualDom.node "elm-ui-static-rules" [ VirtualDom.property "rules" (Encode.string Internal.Style.rules) ] []
16851834
16861835
16871836addWhen ifThis x to =
@@ -1799,7 +1948,7 @@ type Spacing
17991948
18001949
18011950type Padding
1802− = Padding String Int Int Int Int
1951+ = Padding String Float Float Float Float
18031952
18041953
18051954extractSpacingAndPadding : List (Attribute aligned msg) -> ( Maybe Padding, Maybe Spacing )
@@ -1895,35 +2044,44 @@ getHeight attrs =
18952044 Nothing
18962045
18972046
2047+textElementClasses : String
2048+textElementClasses =
2049+ classes.any
2050+ ++ " "
2051+ ++ classes.text
2052+ ++ " "
2053+ ++ classes.widthContent
2054+ ++ " "
2055+ ++ classes.heightContent
2056+
2057+
18982058textElement : String -> VirtualDom.Node msg
18992059textElement str =
19002060 Html.div
19012061 [ Html.Attributes.class
1902− (String.join " "
1903− [ classes.any
1904− , classes.text
1905− , classes.widthContent
1906− , classes.heightContent
1907− ]
1908− )
2062+ textElementClasses
19092063 ]
19102064 [ Html.text str ]
19112065
19122066
2067+textElementFillClasses : String
2068+textElementFillClasses =
2069+ classes.any
2070+ ++ " "
2071+ ++ classes.text
2072+ ++ " "
2073+ ++ classes.widthFill
2074+ ++ " "
2075+ ++ classes.heightFill
2076+
2077+
19132078textElementFill : String -> VirtualDom.Node msg
19142079textElementFill str =
1915− VirtualDom.node "div"
1916− [ VirtualDom.property "className"
1917− (Json.string <|
1918− String.join " "
1919− [ classes.any
1920− , classes.text
1921− , classes.widthFill
1922− , classes.heightFill
1923− ]
1924− )
2080+ Html.div
2081+ [ Html.Attributes.class
2082+ textElementFillClasses
19252083 ]
1926− [ VirtualDom.text str ]
2084+ [ Html.text str ]
19272085
19282086
19292087type Children x
@@ -1931,10 +2089,6 @@ type Children x
19312089 | Keyed (List ( String, x ))
19322090
19332091
1934−
1935−-- toHtml : OptionRecord -> Element msg -> VirtualDom.Node msg
1936−
1937−
19382092toHtml mode el =
19392093 case el of
19402094 Unstyled html ->
@@ -1970,8 +2124,7 @@ renderRoot optionList attributes child =
19702124
19712125
19722126type RenderMode
1973− = Viewport
1974− | Layout
2127+ = Layout
19752128 | NoStaticStyleSheet
19762129 | WithVirtualCss
19772130
@@ -2020,8 +2173,8 @@ rootStyle =
20202173 , SansSerif
20212174 ]
20222175 in
2023− [ StyleClass Flag.bgColor (Colored ("bg-color-" ++ formatColorClass (Rgba 1 1 1 0)) "background-color" (Rgba 1 1 1 0))
2024− , StyleClass Flag.fontColor (Colored ("font-color-" ++ formatColorClass (Rgba 0 0 0 1)) "color" (Rgba 0 0 0 1))
2176+ [ StyleClass Flag.bgColor (Colored ("bg-" ++ formatColorClass (Rgba 1 1 1 0)) "background-color" (Rgba 1 1 1 0))
2177+ , StyleClass Flag.fontColor (Colored ("fc-" ++ formatColorClass (Rgba 0 0 0 1)) "color" (Rgba 0 0 0 1))
20252178 , StyleClass Flag.fontSize (FontSize 20)
20262179 , StyleClass Flag.fontFamily <|
20272180 FontFamily (List.foldl renderFontClassName "font-" families)
@@ -2064,9 +2217,38 @@ renderFontClassName font current =
20642217
20652218renderFocusStyle :
20662219 FocusStyle
2067− -> Style
2220+ -> List Style
20682221renderFocusStyle focus =
2069− Style (Internal.Style.dot classes.any ++ ":focus .focusable, " ++ Internal.Style.dot classes.any ++ ".focusable: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
2226+ , Maybe.map
2227+ (\shadow ->
2228+ Property "box-shadow"
2229+ (formatBoxShadow
2230+ { color = shadow.color
2231+ , offset =
2232+ shadow.offset
2233+ |> Tuple.mapFirst toFloat
2234+ |> Tuple.mapSecond toFloat
2235+ , inset = False
2236+ , blur =
2237+ toFloat shadow.blur
2238+ , size =
2239+ toFloat shadow.size
2240+ }
2241+ )
2242+ )
2243+ focus.shadow
2244+ , Just <| Property "outline" "none"
2245+ ]
2246+ )
2247+ , Style
2248+ ((Internal.Style.dot classes.any ++ ":focus .focusable, ")
2249+ ++ (Internal.Style.dot classes.any ++ ".focusable:focus, ")
2250+ ++ (".ui-slide-bar:focus + " ++ Internal.Style.dot classes.any ++ " .focusable-thumb")
2251+ )
20702252 (List.filterMap identity
20712253 [ Maybe.map (\color -> Property "border-color" (formatColor color)) focus.borderColor
20722254 , Maybe.map (\color -> Property "background-color" (formatColor color)) focus.backgroundColor
@@ -2089,6 +2271,7 @@ renderFocusStyle focus =
20892271 , Just <| Property "outline" "none"
20902272 ]
20912273 )
2274+ ]
20922275
20932276
20942277focusDefaultStyle : { backgroundColor : Maybe Color, borderColor : Maybe Color, shadow : Maybe Shadow }
@@ -2100,7 +2283,7 @@ focusDefaultStyle =
21002283 { color =
21012284 Rgba (155 / 255) (203 / 255) 1 1
21022285 , offset = ( 0, 0 )
2103− , blur = 3
2286+ , blur = 0
21042287 , size = 3
21052288 }
21062289 }
@@ -2170,7 +2353,31 @@ optionsToRecord options =
21702353
21712354toStyleSheet : OptionRecord -> List Style -> VirtualDom.Node msg
21722355toStyleSheet options styleSheet =
2173− VirtualDom.node "style" [] [ VirtualDom.text (toStyleSheetString options styleSheet) ]
2356+ case options.mode of
2357+ Layout ->
2358+ -- wrap the style node in a div to prevent `Dark Reader` from blowin up the dom.
2359+ VirtualDom.node "div"
2360+ []
2361+ [ VirtualDom.node "style"
2362+ []
2363+ [ VirtualDom.text (toStyleSheetString options styleSheet) ]
2364+ ]
2365+
2366+ NoStaticStyleSheet ->
2367+ -- wrap the style node in a div to prevent `Dark Reader` from blowin up the dom.
2368+ VirtualDom.node "div"
2369+ []
2370+ [ VirtualDom.node "style"
2371+ []
2372+ [ VirtualDom.text (toStyleSheetString options styleSheet) ]
2373+ ]
2374+
2375+ WithVirtualCss ->
2376+ VirtualDom.node "elm-ui-rules"
2377+ [ VirtualDom.property "rules"
2378+ (encodeStyles options styleSheet)
2379+ ]
2380+ []
21742381
21752382
21762383renderTopLevelValues rules =
@@ -2180,14 +2387,12 @@ renderTopLevelValues rules =
21802387 ImportFont _ url ->
21812388 Just ("@import url('" ++ url ++ "');")
21822389
2183− FontWith with ->
2184− case with.url of
2185− Just x ->
2186− Just ("@import url('" ++ x ++ "');")
2187−
2188− Nothing ->
2189− Nothing
2190−
2390+ -- FontWith with ->
2391+ -- case with.url of
2392+ -- Just x ->
2393+ -- Just ("@import url('" ++ x ++ "');")
2394+ -- Nothing ->
2395+ -- Nothing
21912396 _ ->
21922397 Nothing
21932398
@@ -2258,7 +2463,38 @@ renderNullAdjustmentRule fontToAdjust otherFontName =
22582463 ]
22592464
22602465
2261−renderFontAdjustmentRule fontToAdjust ( parentAdj, textAdjustment ) otherFontName =
2466+fontRule name modifier ( parentAdj, textAdjustment ) =
2467+ [ bracket
2468+ ("."
2469+ ++ name
2470+ ++ "."
2471+ ++ modifier
2472+ ++ ", "
2473+ ++ "."
2474+ ++ name
2475+ ++ " ."
2476+ ++ modifier
2477+ )
2478+ parentAdj
2479+ , bracket
2480+ ("."
2481+ ++ name
2482+ ++ "."
2483+ ++ modifier
2484+ ++ "> ."
2485+ ++ Internal.Style.classes.text
2486+ ++ ", ."
2487+ ++ name
2488+ ++ " ."
2489+ ++ modifier
2490+ ++ " > ."
2491+ ++ Internal.Style.classes.text
2492+ )
2493+ textAdjustment
2494+ ]
2495+
2496+
2497+renderFontAdjustmentRule fontToAdjust ( full, capital ) otherFontName =
22622498 let
22632499 name =
22642500 if fontToAdjust == otherFontName then
@@ -2268,34 +2504,7 @@ renderFontAdjustmentRule fontToAdjust ( parentAdj, textAdjustment ) otherFontNam
22682504 otherFontName ++ " ." ++ fontToAdjust
22692505 in
22702506 String.join " "
2271− [ bracket
2272− ("."
2273− ++ name
2274− ++ "."
2275− ++ classes.sizeByCapital
2276− ++ ", "
2277− ++ "."
2278− ++ name
2279− ++ " ."
2280− ++ classes.sizeByCapital
2281− )
2282− parentAdj
2283− , bracket
2284− ("."
2285− ++ name
2286− ++ "."
2287− ++ classes.sizeByCapital
2288− ++ "> ."
2289− ++ Internal.Style.classes.text
2290− ++ ", ."
2291− ++ name
2292− ++ " ."
2293− ++ classes.sizeByCapital
2294− ++ " > ."
2295− ++ Internal.Style.classes.text
2296− )
2297− textAdjustment
2298− ]
2507+ (fontRule name classes.sizeByCapital capital ++ fontRule name classes.fullSize full)
22992508
23002509
23012510bracket selector rules =
@@ -2308,17 +2517,12 @@ bracket selector rules =
23082517
23092518fontAdjustmentRules converted =
23102519 ( [ ( "display", "block" )
2311−
2312− -- , ( "line-height", String.fromFloat converted.height )
2313− -- , ( "font-size", String.fromFloat (1 + converted.height + converted.vertical) ++ "em" )
23142520 ]
23152521 , [ ( "display", "inline-block" )
23162522 , ( "line-height", String.fromFloat converted.height )
23172523 , ( "vertical-align", String.fromFloat converted.vertical ++ "em" )
23182524 , ( "font-size", String.fromFloat converted.size ++ "em" )
23192525 ]
2320− -- , [ ( "font-size", String.fromFloat converted.size ++ "em" )
2321− -- ]
23222526 )
23232527
23242528
@@ -2329,10 +2533,17 @@ typefaceAdjustment typefaces =
23292533 Nothing ->
23302534 case face of
23312535 FontWith with ->
2332− Just
2333− (fontAdjustmentRules
2334− (.capital (convertAdjustment with.adjustment))
2335− )
2536+ case with.adjustment of
2537+ Nothing ->
2538+ found
2539+
2540+ Just adjustment ->
2541+ Just
2542+ ( fontAdjustmentRules
2543+ (.full (convertAdjustment adjustment))
2544+ , fontAdjustmentRules
2545+ (.capital (convertAdjustment adjustment))
2546+ )
23362547
23372548 _ ->
23382549 found
@@ -2382,475 +2593,492 @@ renderProps force (Property key val) existing =
23822593 existing ++ "\n " ++ key ++ ": " ++ val ++ ";"
23832594
23842595
2596+encodeStyles options stylesheet =
2597+ stylesheet
2598+ |> List.map
2599+ (\style ->
2600+ let
2601+ styled =
2602+ renderStyleRule options style Nothing
2603+ in
2604+ ( getStyleName style, Encode.list Encode.string styled )
2605+ )
2606+ |> Encode.object
2607+
2608+
23852609toStyleSheetString : OptionRecord -> List Style -> String
23862610toStyleSheetString options stylesheet =
23872611 let
2388− renderStyle maybePseudo selector props =
2389− case maybePseudo of
2390− Nothing ->
2391− selector ++ "{" ++ List.foldl (renderProps False) "" props ++ "\n}"
2392−
2393− Just pseudo ->
2394− case pseudo of
2395− Hover ->
2396− case options.hover of
2397− NoHover ->
2398− ""
2612+ combine style rendered =
2613+ { rules = rendered.rules ++ renderStyleRule options style Nothing
2614+ , topLevel =
2615+ case topLevelValue style of
2616+ Nothing ->
2617+ rendered.topLevel
23992618
2400− ForceHover ->
2401− selector ++ "-hv {" ++ List.foldl (renderProps True) "" props ++ "\n}"
2619+ Just topLevel ->
2620+ topLevel :: rendered.topLevel
2621+ }
2622+ in
2623+ case List.foldl combine { topLevel = [], rules = [] } stylesheet of
2624+ { topLevel, rules } ->
2625+ renderTopLevelValues topLevel ++ String.concat rules
24022626
2403− AllowHover ->
2404− selector ++ "-hv:hover {" ++ List.foldl (renderProps False) "" props ++ "\n}"
24052627
2406− Focus ->
2407− let
2408− renderedProps =
2409− List.foldl (renderProps False) "" props
2410− in
2411− String.join "\n"
2412− [ selector
2413− ++ "-fs:focus {"
2414− ++ renderedProps
2415− ++ "\n}"
2416− , "."
2417− ++ classes.any
2418− ++ ":focus ~ "
2419− ++ selector
2420− ++ "-fs:not(.focus) {"
2421− ++ renderedProps
2422− ++ "\n}"
2423− , "."
2424− ++ classes.any
2425− ++ ":focus "
2426− ++ selector
2427− ++ "-fs {"
2428− ++ renderedProps
2429− ++ "\n}"
2430− , ".focusable-parent:focus ~ "
2431− ++ "."
2432− ++ classes.any
2433− ++ " "
2434− ++ selector
2435− ++ "-fs {"
2436− ++ renderedProps
2437− ++ "\n}"
2438− ]
2628+renderStyle : OptionRecord -> Maybe PseudoClass -> String -> List Property -> List String
2629+renderStyle options maybePseudo selector props =
2630+ case maybePseudo of
2631+ Nothing ->
2632+ [ selector ++ "{" ++ List.foldl (renderProps False) "" props ++ "\n}" ]
24392633
2440− Active ->
2441− selector ++ "-act:active {" ++ List.foldl (renderProps False) "" props ++ "\n}"
2634+ Just pseudo ->
2635+ case pseudo of
2636+ Hover ->
2637+ case options.hover of
2638+ NoHover ->
2639+ []
24422640
2443− renderStyleRule rule maybePseudo =
2444− case rule of
2445− Style selector props ->
2446− renderStyle maybePseudo selector props
2641+ ForceHover ->
2642+ [ selector ++ "-hv {" ++ List.foldl (renderProps True) "" props ++ "\n}" ]
24472643
2448− Shadows name prop ->
2449− renderStyle
2450− maybePseudo
2451− ("." ++ name)
2452− [ Property "box-shadow" prop
2453− ]
2644+ AllowHover ->
2645+ [ selector ++ "-hv:hover {" ++ List.foldl (renderProps False) "" props ++ "\n}" ]
24542646
2455− Transparency name transparency ->
2647+ Focus ->
24562648 let
2457− opacity =
2458− (1 - transparency)
2459− |> min 1
2460− |> max 0
2649+ renderedProps =
2650+ List.foldl (renderProps False) "" props
24612651 in
2462− renderStyle
2463− maybePseudo
2464− ("." ++ name)
2465− [ Property "opacity" (String.fromFloat opacity)
2466− ]
2652+ [ selector ++ "-fs:focus {" ++ renderedProps ++ "\n}"
2653+ , ("." ++ classes.any ++ ":focus " ++ selector ++ "-fs {")
2654+ ++ renderedProps
2655+ ++ "\n}"
2656+ , (selector ++ "-fs:focus-within {")
2657+ ++ renderedProps
2658+ ++ "\n}"
2659+ , (".ui-slide-bar:focus + " ++ Internal.Style.dot classes.any ++ " .focusable-thumb" ++ selector ++ "-fs {")
2660+ ++ renderedProps
2661+ ++ "\n}"
2662+ ]
24672663
2468− FontSize i ->
2469− renderStyle
2470− maybePseudo
2471− (".font-size-" ++ String.fromInt i)
2472− [ Property "font-size" (String.fromInt i ++ "px")
2473− ]
2664+ Active ->
2665+ [ selector ++ "-act:active {" ++ List.foldl (renderProps False) "" props ++ "\n}" ]
24742666
2475− FontFamily name typefaces ->
2476− let
2477− families =
2478− Property "font-family"
2479− (typefaces
2480− |> List.map fontName
2481− |> String.join ", "
2482− )
2483− in
2484− String.join " "
2485− [ renderStyle
2486− maybePseudo
2487− ("." ++ name)
2488− [ families ]
2489− ]
24902667
2491− Single class prop val ->
2492− renderStyle
2493− maybePseudo
2494− ("." ++ class)
2495− [ Property prop val
2496− ]
2668+renderStyleRule : OptionRecord -> Style -> Maybe PseudoClass -> List String
2669+renderStyleRule options rule maybePseudo =
2670+ case rule of
2671+ Style selector props ->
2672+ renderStyle options maybePseudo selector props
2673+
2674+ Shadows name prop ->
2675+ renderStyle options
2676+ maybePseudo
2677+ ("." ++ name)
2678+ [ Property "box-shadow" prop
2679+ ]
24972680
2498− Colored class prop color ->
2499− renderStyle
2500− maybePseudo
2501− ("." ++ class)
2502− [ Property prop (formatColor color)
2503− ]
2681+ Transparency name transparency ->
2682+ let
2683+ opacity =
2684+ (1 - transparency)
2685+ |> min 1
2686+ |> max 0
2687+ in
2688+ renderStyle options
2689+ maybePseudo
2690+ ("." ++ name)
2691+ [ Property "opacity" (String.fromFloat opacity)
2692+ ]
25042693
2505− SpacingStyle cls x y ->
2506− let
2507− class =
2508− "." ++ cls
2694+ FontSize i ->
2695+ renderStyle options
2696+ maybePseudo
2697+ (".font-size-" ++ String.fromInt i)
2698+ [ Property "font-size" (String.fromInt i ++ "px")
2699+ ]
25092700
2510− halfX =
2511− String.fromFloat (toFloat x / 2) ++ "px"
2701+ FontFamily name typefaces ->
2702+ let
2703+ features =
2704+ typefaces
2705+ |> List.filterMap renderVariants
2706+ |> String.join ", "
2707+
2708+ families =
2709+ [ Property "font-family"
2710+ (typefaces
2711+ |> List.map fontName
2712+ |> String.join ", "
2713+ )
2714+ , Property "font-feature-settings" features
2715+ , Property "font-variant"
2716+ (if List.any hasSmallCaps typefaces then
2717+ "small-caps"
25122718
2513− halfY =
2514− String.fromFloat (toFloat y / 2) ++ "px"
2719+ else
2720+ "normal"
2721+ )
2722+ ]
2723+ in
2724+ renderStyle options
2725+ maybePseudo
2726+ ("." ++ name)
2727+ families
25152728
2516− xPx =
2517− String.fromInt x ++ "px"
2729+ Single class prop val ->
2730+ renderStyle options
2731+ maybePseudo
2732+ ("." ++ class)
2733+ [ Property prop val
2734+ ]
25182735
2519− yPx =
2520− String.fromInt y ++ "px"
2736+ Colored class prop color ->
2737+ renderStyle options
2738+ maybePseudo
2739+ ("." ++ class)
2740+ [ Property prop (formatColor color)
2741+ ]
25212742
2522− row =
2523− "." ++ Internal.Style.classes.row
2743+ SpacingStyle cls x y ->
2744+ let
2745+ class =
2746+ "." ++ cls
25242747
2525− wrappedRow =
2526− "." ++ Internal.Style.classes.wrapped ++ row
2748+ halfX =
2749+ String.fromFloat (toFloat x / 2) ++ "px"
25272750
2528− column =
2529− "." ++ Internal.Style.classes.column
2751+ halfY =
2752+ String.fromFloat (toFloat y / 2) ++ "px"
25302753
2531− page =
2532− "." ++ Internal.Style.classes.page
2754+ xPx =
2755+ String.fromInt x ++ "px"
25332756
2534− paragraph =
2535− "." ++ Internal.Style.classes.paragraph
2757+ yPx =
2758+ String.fromInt y ++ "px"
25362759
2537− left =
2538− "." ++ Internal.Style.classes.alignLeft
2760+ row =
2761+ "." ++ Internal.Style.classes.row
25392762
2540− right =
2541− "." ++ Internal.Style.classes.alignRight
2763+ wrappedRow =
2764+ "." ++ Internal.Style.classes.wrapped ++ row
25422765
2543− any =
2544− "." ++ Internal.Style.classes.any
2766+ column =
2767+ "." ++ Internal.Style.classes.column
25452768
2546− single =
2547− "." ++ Internal.Style.classes.single
2548− in
2549− String.concat
2550− [ renderStyle maybePseudo (class ++ row ++ " > " ++ any ++ " + " ++ any) [ Property "margin-left" xPx ]
2551−
2552− -- margins don't apply to last element of normal, unwrapped rows
2553− -- , renderStyle maybePseudo (class ++ row ++ " > " ++ any ++ ":first-child") [ Property "margin" "0" ]
2554− -- For wrapped rows, margins always apply because we handle "canceling out" the other margins manually in the element.
2555− , renderStyle maybePseudo
2556− (class ++ wrappedRow ++ " > " ++ any)
2557− [ Property "margin" (halfY ++ " " ++ halfX)
2558− ]
2769+ page =
2770+ "." ++ Internal.Style.classes.page
25592771
2560− -- , renderStyle maybePseudo
2561− -- (class ++ wrappedRow ++ " > " ++ any ++ ":last-child")
2562− -- [ Property "margin-right" "0"
2563− -- ]
2564− -- columns
2565− , renderStyle maybePseudo (class ++ column ++ " > " ++ any ++ " + " ++ any) [ Property "margin-top" yPx ]
2566− , renderStyle maybePseudo (class ++ page ++ " > " ++ any ++ " + " ++ any) [ Property "margin-top" yPx ]
2567− , renderStyle maybePseudo (class ++ page ++ " > " ++ left) [ Property "margin-right" xPx ]
2568− , renderStyle maybePseudo (class ++ page ++ " > " ++ right) [ Property "margin-left" xPx ]
2569− , renderStyle
2570− maybePseudo
2571− (class ++ paragraph)
2572− [ Property "line-height" ("calc(1em + " ++ String.fromInt y ++ "px)")
2573− ]
2574− , renderStyle
2575− maybePseudo
2576− ("textarea" ++ class)
2577− [ Property "line-height" ("calc(1em + " ++ String.fromInt y ++ "px)")
2578− ]
2772+ paragraph =
2773+ "." ++ Internal.Style.classes.paragraph
25792774
2580− -- , renderStyle
2581− -- maybePseudo
2582− -- (class ++ paragraph ++ " > " ++ any)
2583− -- [ Property "margin-right" xPx
2584− -- , Property "margin-bottom" yPx
2585− -- ]
2586− , renderStyle
2587− maybePseudo
2588− (class ++ paragraph ++ " > " ++ left)
2589− [ Property "margin-right" xPx
2590− ]
2591− , renderStyle
2592− maybePseudo
2593− (class ++ paragraph ++ " > " ++ right)
2594− [ Property "margin-left" xPx
2595− ]
2596− , renderStyle
2597− maybePseudo
2598− (class ++ paragraph ++ "::after")
2599− [ Property "content" "''"
2600− , Property "display" "block"
2601− , Property "height" "0"
2602− , Property "width" "0"
2603− , Property "margin-top" (String.fromInt (-1 * (y // 2)) ++ "px")
2604− ]
2605− , renderStyle
2606− maybePseudo
2607− (class ++ paragraph ++ "::before")
2608− [ Property "content" "''"
2609− , Property "display" "block"
2610− , Property "height" "0"
2611− , Property "width" "0"
2612− , Property "margin-bottom" (String.fromInt (-1 * (y // 2)) ++ "px")
2613− ]
2614− ]
2775+ left =
2776+ "." ++ Internal.Style.classes.alignLeft
26152777
2616− PaddingStyle cls top right bottom left ->
2617− let
2618− class =
2619− "."
2620− ++ cls
2621− in
2622− renderStyle
2623− maybePseudo
2624− class
2625− [ Property "padding"
2626− (String.fromInt top
2627− ++ "px "
2628− ++ String.fromInt right
2629− ++ "px "
2630− ++ String.fromInt bottom
2631− ++ "px "
2632− ++ String.fromInt left
2633− ++ "px"
2634− )
2635− ]
2778+ right =
2779+ "." ++ Internal.Style.classes.alignRight
26362780
2637− BorderWidth cls top right bottom left ->
2638− let
2639− class =
2640− "."
2641− ++ cls
2642− in
2643− renderStyle
2644− maybePseudo
2645− class
2646− [ Property "border-width"
2647− (String.fromInt top
2648− ++ "px "
2649− ++ String.fromInt right
2650− ++ "px "
2651− ++ String.fromInt bottom
2652− ++ "px "
2653− ++ String.fromInt left
2654− ++ "px"
2655− )
2656− ]
2781+ any =
2782+ "." ++ Internal.Style.classes.any
26572783
2658− GridTemplateStyle template ->
2659− let
2660− class =
2661− ".grid-rows-"
2662− ++ String.join "-" (List.map lengthClassName template.rows)
2663− ++ "-cols-"
2664− ++ String.join "-" (List.map lengthClassName template.columns)
2665− ++ "-space-x-"
2666− ++ lengthClassName (Tuple.first template.spacing)
2667− ++ "-space-y-"
2668− ++ lengthClassName (Tuple.second template.spacing)
2669−
2670− ySpacing =
2671− toGridLength (Tuple.second template.spacing)
2672−
2673− xSpacing =
2674− toGridLength (Tuple.first template.spacing)
2675−
2676− toGridLength x =
2677− toGridLengthHelper Nothing Nothing x
2678−
2679− toGridLengthHelper minimum maximum x =
2680− case x of
2681− Px px ->
2682− String.fromInt px ++ "px"
2683−
2684− Content ->
2685− case ( minimum, maximum ) of
2686− ( Nothing, Nothing ) ->
2687− "max-content"
2688−
2689− ( Just minSize, Nothing ) ->
2690− "minmax(" ++ String.fromInt minSize ++ "px, " ++ "max-content)"
2691−
2692− ( Nothing, Just maxSize ) ->
2693− "minmax(max-content, " ++ String.fromInt maxSize ++ "px)"
2694−
2695− ( Just minSize, Just maxSize ) ->
2696− "minmax(" ++ String.fromInt minSize ++ "px, " ++ String.fromInt maxSize ++ "px)"
2697−
2698− Fill i ->
2699− case ( minimum, maximum ) of
2700− ( Nothing, Nothing ) ->
2701− String.fromInt i ++ "fr"
2702−
2703− ( Just minSize, Nothing ) ->
2704− "minmax(" ++ String.fromInt minSize ++ "px, " ++ String.fromInt i ++ "fr" ++ "fr)"
2705−
2706− ( Nothing, Just maxSize ) ->
2707− "minmax(max-content, " ++ String.fromInt maxSize ++ "px)"
2708−
2709− ( Just minSize, Just maxSize ) ->
2710− "minmax(" ++ String.fromInt minSize ++ "px, " ++ String.fromInt maxSize ++ "px)"
2711−
2712− Min m len ->
2713− toGridLengthHelper (Just m) maximum len
2714−
2715− Max m len ->
2716− toGridLengthHelper minimum (Just m) len
2717−
2718− msColumns =
2719− template.columns
2720− |> List.map toGridLength
2721− |> String.join ySpacing
2722− |> (\x -> "-ms-grid-columns: " ++ x ++ ";")
2723−
2724− msRows =
2725− template.columns
2726− |> List.map toGridLength
2727− |> String.join ySpacing
2728− |> (\x -> "-ms-grid-rows: " ++ x ++ ";")
2729−
2730− base =
2731− class ++ "{" ++ msColumns ++ msRows ++ "}"
2732−
2733− columns =
2734− template.columns
2735− |> List.map toGridLength
2736− |> String.join " "
2737− |> (\x -> "grid-template-columns: " ++ x ++ ";")
2738−
2739− rows =
2740− template.rows
2741− |> List.map toGridLength
2742− |> String.join " "
2743− |> (\x -> "grid-template-rows: " ++ x ++ ";")
2744−
2745− gapX =
2746− "grid-column-gap:" ++ toGridLength (Tuple.first template.spacing) ++ ";"
2747−
2748− gapY =
2749− "grid-row-gap:" ++ toGridLength (Tuple.second template.spacing) ++ ";"
2750−
2751− modernGrid =
2752− class ++ "{" ++ columns ++ rows ++ gapX ++ gapY ++ "}"
2753−
2754− supports =
2755− "@supports (display:grid) {" ++ modernGrid ++ "}"
2756− in
2757− base ++ supports
2784+ single =
2785+ "." ++ Internal.Style.classes.single
2786+ in
2787+ List.concat
2788+ [ renderStyle options maybePseudo (class ++ row ++ " > " ++ any ++ " + " ++ any) [ Property "margin-left" xPx ]
2789+
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
2794+ maybePseudo
2795+ (class ++ wrappedRow ++ " > " ++ any)
2796+ [ Property "margin" (halfY ++ " " ++ halfX)
2797+ ]
27582798
2759− GridPosition position ->
2760− let
2761− class =
2762− ".grid-pos-"
2763− ++ String.fromInt position.row
2764− ++ "-"
2765− ++ String.fromInt position.col
2766− ++ "-"
2767− ++ String.fromInt position.width
2768− ++ "-"
2769− ++ String.fromInt position.height
2770−
2771− msPosition =
2772− String.join " "
2773− [ "-ms-grid-row: "
2774− ++ String.fromInt position.row
2775− ++ ";"
2776− , "-ms-grid-row-span: "
2777− ++ String.fromInt position.height
2778− ++ ";"
2779− , "-ms-grid-column: "
2780− ++ String.fromInt position.col
2781− ++ ";"
2782− , "-ms-grid-column-span: "
2783− ++ String.fromInt position.width
2784− ++ ";"
2785− ]
2786−
2787− base =
2788− class ++ "{" ++ msPosition ++ "}"
2789−
2790− modernPosition =
2791− String.join " "
2792− [ "grid-row: "
2793− ++ String.fromInt position.row
2794− ++ " / "
2795− ++ String.fromInt (position.row + position.height)
2796− ++ ";"
2797− , "grid-column: "
2798− ++ String.fromInt position.col
2799− ++ " / "
2800− ++ String.fromInt (position.col + position.width)
2801− ++ ";"
2802− ]
2803−
2804− modernGrid =
2805− class ++ "{" ++ modernPosition ++ "}"
2806−
2807− supports =
2808− "@supports (display:grid) {" ++ modernGrid ++ "}"
2809− in
2810− base ++ supports
2799+ -- , renderStyle options maybePseudo
2800+ -- (class ++ wrappedRow ++ " > " ++ any ++ ":last-child")
2801+ -- [ Property "margin-right" "0"
2802+ -- ]
2803+ -- columns
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
2809+ maybePseudo
2810+ (class ++ paragraph)
2811+ [ Property "line-height" ("calc(1em + " ++ String.fromInt y ++ "px)")
2812+ ]
2813+ , renderStyle options
2814+ maybePseudo
2815+ ("textarea" ++ any ++ class)
2816+ [ Property "line-height" ("calc(1em + " ++ String.fromInt y ++ "px)")
2817+ , Property "height" ("calc(100% + " ++ String.fromInt y ++ "px)")
2818+ ]
28112819
2812− PseudoSelector class styles ->
2813− let
2814− renderPseudoRule style =
2815− renderStyleRule style (Just class)
2816− in
2817− List.map renderPseudoRule styles
2820+ -- , renderStyle options
2821+ -- maybePseudo
2822+ -- (class ++ paragraph ++ " > " ++ any)
2823+ -- [ Property "margin-right" xPx
2824+ -- , Property "margin-bottom" yPx
2825+ -- ]
2826+ , renderStyle options
2827+ maybePseudo
2828+ (class ++ paragraph ++ " > " ++ left)
2829+ [ Property "margin-right" xPx
2830+ ]
2831+ , renderStyle options
2832+ maybePseudo
2833+ (class ++ paragraph ++ " > " ++ right)
2834+ [ Property "margin-left" xPx
2835+ ]
2836+ , renderStyle options
2837+ maybePseudo
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")
2844+ ]
2845+ , renderStyle options
2846+ maybePseudo
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")
2853+ ]
2854+ ]
2855+
2856+ PaddingStyle cls top right bottom left ->
2857+ let
2858+ class =
2859+ "."
2860+ ++ cls
2861+ in
2862+ renderStyle options
2863+ maybePseudo
2864+ class
2865+ [ Property "padding"
2866+ (String.fromFloat top
2867+ ++ "px "
2868+ ++ String.fromFloat right
2869+ ++ "px "
2870+ ++ String.fromFloat bottom
2871+ ++ "px "
2872+ ++ String.fromFloat left
2873+ ++ "px"
2874+ )
2875+ ]
2876+
2877+ BorderWidth cls top right bottom left ->
2878+ let
2879+ class =
2880+ "."
2881+ ++ cls
2882+ in
2883+ renderStyle options
2884+ maybePseudo
2885+ class
2886+ [ Property "border-width"
2887+ (String.fromInt top
2888+ ++ "px "
2889+ ++ String.fromInt right
2890+ ++ "px "
2891+ ++ String.fromInt bottom
2892+ ++ "px "
2893+ ++ String.fromInt left
2894+ ++ "px"
2895+ )
2896+ ]
2897+
2898+ GridTemplateStyle template ->
2899+ let
2900+ class =
2901+ ".grid-rows-"
2902+ ++ String.join "-" (List.map lengthClassName template.rows)
2903+ ++ "-cols-"
2904+ ++ String.join "-" (List.map lengthClassName template.columns)
2905+ ++ "-space-x-"
2906+ ++ lengthClassName (Tuple.first template.spacing)
2907+ ++ "-space-y-"
2908+ ++ lengthClassName (Tuple.second template.spacing)
2909+
2910+ ySpacing =
2911+ toGridLength (Tuple.second template.spacing)
2912+
2913+ xSpacing =
2914+ toGridLength (Tuple.first template.spacing)
2915+
2916+ toGridLength x =
2917+ toGridLengthHelper Nothing Nothing x
2918+
2919+ toGridLengthHelper minimum maximum x =
2920+ case x of
2921+ Px px ->
2922+ String.fromInt px ++ "px"
2923+
2924+ Content ->
2925+ case ( minimum, maximum ) of
2926+ ( Nothing, Nothing ) ->
2927+ "max-content"
2928+
2929+ ( Just minSize, Nothing ) ->
2930+ "minmax(" ++ String.fromInt minSize ++ "px, " ++ "max-content)"
2931+
2932+ ( Nothing, Just maxSize ) ->
2933+ "minmax(max-content, " ++ String.fromInt maxSize ++ "px)"
2934+
2935+ ( Just minSize, Just maxSize ) ->
2936+ "minmax(" ++ String.fromInt minSize ++ "px, " ++ String.fromInt maxSize ++ "px)"
2937+
2938+ Fill i ->
2939+ case ( minimum, maximum ) of
2940+ ( Nothing, Nothing ) ->
2941+ String.fromInt i ++ "fr"
2942+
2943+ ( Just minSize, Nothing ) ->
2944+ "minmax(" ++ String.fromInt minSize ++ "px, " ++ String.fromInt i ++ "fr" ++ "fr)"
2945+
2946+ ( Nothing, Just maxSize ) ->
2947+ "minmax(max-content, " ++ String.fromInt maxSize ++ "px)"
2948+
2949+ ( Just minSize, Just maxSize ) ->
2950+ "minmax(" ++ String.fromInt minSize ++ "px, " ++ String.fromInt maxSize ++ "px)"
2951+
2952+ Min m len ->
2953+ toGridLengthHelper (Just m) maximum len
2954+
2955+ Max m len ->
2956+ toGridLengthHelper minimum (Just m) len
2957+
2958+ msColumns =
2959+ template.columns
2960+ |> List.map toGridLength
2961+ |> String.join ySpacing
2962+ |> (\x -> "-ms-grid-columns: " ++ x ++ ";")
2963+
2964+ msRows =
2965+ template.columns
2966+ |> List.map toGridLength
2967+ |> String.join ySpacing
2968+ |> (\x -> "-ms-grid-rows: " ++ x ++ ";")
2969+
2970+ base =
2971+ class ++ "{" ++ msColumns ++ msRows ++ "}"
2972+
2973+ columns =
2974+ template.columns
2975+ |> List.map toGridLength
28182976 |> String.join " "
2977+ |> (\x -> "grid-template-columns: " ++ x ++ ";")
28192978
2820− Transform transform ->
2821− let
2822− val =
2823− transformValue transform
2979+ rows =
2980+ template.rows
2981+ |> List.map toGridLength
2982+ |> String.join " "
2983+ |> (\x -> "grid-template-rows: " ++ x ++ ";")
28242984
2825− class =
2826− transformClass transform
2827− in
2828− case ( class, val ) of
2829− ( Just cls, Just v ) ->
2830− renderStyle
2831− maybePseudo
2832− ("." ++ cls)
2833− [ Property "transform"
2834− v
2835− ]
2985+ gapX =
2986+ "grid-column-gap:" ++ toGridLength (Tuple.first template.spacing) ++ ";"
28362987
2837− _ ->
2838− ""
2988+ gapY =
2989+ "grid-row-gap:" ++ toGridLength (Tuple.second template.spacing) ++ ";"
28392990
2840− combine style rendered =
2841− { rules = rendered.rules ++ renderStyleRule style Nothing
2842− , topLevel =
2843− case topLevelValue style of
2844− Nothing ->
2845− rendered.topLevel
2991+ modernGrid =
2992+ class ++ "{" ++ columns ++ rows ++ gapX ++ gapY ++ "}"
28462993
2847− Just topLevel ->
2848− topLevel :: rendered.topLevel
2849− }
2850− in
2851− case List.foldl combine { topLevel = [], rules = "" } stylesheet of
2852− { topLevel, rules } ->
2853− renderTopLevelValues topLevel ++ rules
2994+ supports =
2995+ "@supports (display:grid) {" ++ modernGrid ++ "}"
2996+ in
2997+ [ base
2998+ , supports
2999+ ]
3000+
3001+ GridPosition position ->
3002+ let
3003+ class =
3004+ ".grid-pos-"
3005+ ++ String.fromInt position.row
3006+ ++ "-"
3007+ ++ String.fromInt position.col
3008+ ++ "-"
3009+ ++ String.fromInt position.width
3010+ ++ "-"
3011+ ++ String.fromInt position.height
3012+
3013+ msPosition =
3014+ String.join " "
3015+ [ "-ms-grid-row: "
3016+ ++ String.fromInt position.row
3017+ ++ ";"
3018+ , "-ms-grid-row-span: "
3019+ ++ String.fromInt position.height
3020+ ++ ";"
3021+ , "-ms-grid-column: "
3022+ ++ String.fromInt position.col
3023+ ++ ";"
3024+ , "-ms-grid-column-span: "
3025+ ++ String.fromInt position.width
3026+ ++ ";"
3027+ ]
3028+
3029+ base =
3030+ class ++ "{" ++ msPosition ++ "}"
3031+
3032+ modernPosition =
3033+ String.join " "
3034+ [ "grid-row: "
3035+ ++ String.fromInt position.row
3036+ ++ " / "
3037+ ++ String.fromInt (position.row + position.height)
3038+ ++ ";"
3039+ , "grid-column: "
3040+ ++ String.fromInt position.col
3041+ ++ " / "
3042+ ++ String.fromInt (position.col + position.width)
3043+ ++ ";"
3044+ ]
3045+
3046+ modernGrid =
3047+ class ++ "{" ++ modernPosition ++ "}"
3048+
3049+ supports =
3050+ "@supports (display:grid) {" ++ modernGrid ++ "}"
3051+ in
3052+ [ base
3053+ , supports
3054+ ]
3055+
3056+ PseudoSelector class styles ->
3057+ let
3058+ renderPseudoRule style =
3059+ renderStyleRule options style (Just class)
3060+ in
3061+ List.concatMap renderPseudoRule styles
3062+
3063+ Transform transform ->
3064+ let
3065+ val =
3066+ transformValue transform
3067+
3068+ class =
3069+ transformClass transform
3070+ in
3071+ case ( class, val ) of
3072+ ( Just cls, Just v ) ->
3073+ renderStyle options
3074+ maybePseudo
3075+ ("." ++ cls)
3076+ [ Property "transform"
3077+ v
3078+ ]
3079+
3080+ _ ->
3081+ []
28543082
28553083
28563084lengthClassName : Length -> String
@@ -2890,12 +3118,12 @@ formatTextShadow shadow =
28903118 ]
28913119
28923120
2893−textShadowName shadow =
3121+textShadowClass shadow =
28943122 String.concat
28953123 [ "txt"
2896− , String.fromFloat (Tuple.first shadow.offset) ++ "px"
2897− , String.fromFloat (Tuple.second shadow.offset) ++ "px"
2898− , String.fromFloat shadow.blur ++ "px"
3124+ , floatClass (Tuple.first shadow.offset) ++ "px"
3125+ , floatClass (Tuple.second shadow.offset) ++ "px"
3126+ , floatClass shadow.blur ++ "px"
28993127 , formatColorClass shadow.color
29003128 ]
29013129
@@ -2916,17 +3144,17 @@ formatBoxShadow shadow =
29163144 ]
29173145
29183146
2919−boxShadowName shadow =
3147+boxShadowClass shadow =
29203148 String.concat <|
29213149 [ if shadow.inset then
29223150 "box-inset"
29233151
29243152 else
29253153 "box-"
2926− , String.fromFloat (Tuple.first shadow.offset) ++ "px"
2927− , String.fromFloat (Tuple.second shadow.offset) ++ "px"
2928− , String.fromFloat shadow.blur ++ "px"
2929− , String.fromFloat shadow.size ++ "px"
3154+ , floatClass (Tuple.first shadow.offset) ++ "px"
3155+ , floatClass (Tuple.second shadow.offset) ++ "px"
3156+ , floatClass shadow.blur ++ "px"
3157+ , floatClass shadow.size ++ "px"
29303158 , formatColorClass shadow.color
29313159 ]
29323160
@@ -2971,6 +3199,17 @@ paddingName top right bottom left =
29713199 ++ String.fromInt left
29723200
29733201
3202+paddingNameFloat top right bottom left =
3203+ "pad-"
3204+ ++ floatClass top
3205+ ++ "-"
3206+ ++ floatClass right
3207+ ++ "-"
3208+ ++ floatClass bottom
3209+ ++ "-"
3210+ ++ floatClass left
3211+
3212+
29743213getStyleName : Style -> String
29753214getStyleName style =
29763215 case style of
@@ -3285,20 +3524,19 @@ convertAdjustment adjustment =
32853524 capitalVertical =
32863525 1 - ascender
32873526
3288−
32893527 capitalSize =
32903528 1 / (ascender - newBaseline)
32913529
3530+ fullSize =
3531+ 1 / (ascender - descender)
3532+
32923533 fullVertical =
3293− (oldMiddle - newFullMiddle) * 2
3534+ 1 - ascender
3535+
3536+ -- (oldMiddle - newFullMiddle) * 2
32943537 in
32953538 { full =
3296− { vertical = fullVertical
3297− , height =
3298− (ascender - descender)
3299− - abs fullVertical
3300− , size = 1.0
3301− }
3539+ adjust fullSize (ascender - descender) fullVertical
33023540 , capital =
33033541 adjust capitalSize (ascender - newBaseline) capitalVertical
33043542 }
@@ -3308,7 +3546,5 @@ adjust size height vertical =
33083546 { vertical = vertical
33093547 , height =
33103548 height / size
3311−
3312− -- vertical
33133549 , size = size
33143550 }