@@ -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,68 +2353,31 @@ optionsToRecord options =
21702353
21712354toStyleSheet : OptionRecord -> List Style -> VirtualDom.Node msg
21722355toStyleSheet options styleSheet =
2173− VirtualDom.node "style" [] [ VirtualDom.text (toStyleSheetString options styleSheet) ]
2174−
2175−
2176−
2177−-- case typefaceAdjustment typefaces of
2178−-- Nothing ->
2179−-- ""
2180−-- Just ( parentAdj, textAdjustment ) ->
2181−-- String.join " "
2182−-- [ renderStyle
2183−-- maybePseudo
2184−-- ("."
2185−-- ++ name
2186−-- ++ "."
2187−-- ++ classes.sizeByCapital
2188−-- ++ ", "
2189−-- ++ "."
2190−-- ++ name
2191−-- ++ " ."
2192−-- ++ classes.sizeByCapital
2193−-- )
2194−-- parentAdj
2195−-- , renderStyle
2196−-- maybePseudo
2197−-- ("."
2198−-- ++ name
2199−-- ++ "."
2200−-- ++ classes.sizeByCapital
2201−-- ++ "> ."
2202−-- ++ Internal.Style.classes.text
2203−-- ++ ", ."
2204−-- ++ name
2205−-- ++ " ."
2206−-- ++ classes.sizeByCapital
2207−-- ++ " > ."
2208−-- ++ Internal.Style.classes.text
2209−-- )
2210−-- textAdjustment
2211−-- ]
2212−-- renderTopLevels rule =
2213−-- case rule of
2214−-- FontFamily name typefaces ->
2215−-- let
2216−-- getImports font =
2217−-- case font of
2218−-- ImportFont _ url ->
2219−-- Just ("@import url('" ++ url ++ "');")
2220−-- FontWith { url } ->
2221−-- case url of
2222−-- Just x ->
2223−-- Just ("@import url('" ++ x ++ "');")
2224−-- Nothing ->
2225−-- Nothing
2226−-- _ ->
2227−-- Nothing
2228−-- in
2229−-- typefaces
2230−-- |> List.filterMap getImports
2231−-- |> String.join "\n"
2232−-- |> Just
2233−-- _ ->
2234−-- Nothing
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+ []
22352381
22362382
22372383renderTopLevelValues rules =
@@ -2241,14 +2387,12 @@ renderTopLevelValues rules =
22412387 ImportFont _ url ->
22422388 Just ("@import url('" ++ url ++ "');")
22432389
2244− FontWith with ->
2245− case with.url of
2246− Just x ->
2247− Just ("@import url('" ++ x ++ "');")
2248−
2249− Nothing ->
2250− Nothing
2251−
2390+ -- FontWith with ->
2391+ -- case with.url of
2392+ -- Just x ->
2393+ -- Just ("@import url('" ++ x ++ "');")
2394+ -- Nothing ->
2395+ -- Nothing
22522396 _ ->
22532397 Nothing
22542398
@@ -2319,7 +2463,38 @@ renderNullAdjustmentRule fontToAdjust otherFontName =
23192463 ]
23202464
23212465
2322−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 =
23232498 let
23242499 name =
23252500 if fontToAdjust == otherFontName then
@@ -2329,34 +2504,7 @@ renderFontAdjustmentRule fontToAdjust ( parentAdj, textAdjustment ) otherFontNam
23292504 otherFontName ++ " ." ++ fontToAdjust
23302505 in
23312506 String.join " "
2332− [ bracket
2333− ("."
2334− ++ name
2335− ++ "."
2336− ++ classes.sizeByCapital
2337− ++ ", "
2338− ++ "."
2339− ++ name
2340− ++ " ."
2341− ++ classes.sizeByCapital
2342− )
2343− parentAdj
2344− , bracket
2345− ("."
2346− ++ name
2347− ++ "."
2348− ++ classes.sizeByCapital
2349− ++ "> ."
2350− ++ Internal.Style.classes.text
2351− ++ ", ."
2352− ++ name
2353− ++ " ."
2354− ++ classes.sizeByCapital
2355− ++ " > ."
2356− ++ Internal.Style.classes.text
2357− )
2358− textAdjustment
2359− ]
2507+ (fontRule name classes.sizeByCapital capital ++ fontRule name classes.fullSize full)
23602508
23612509
23622510bracket selector rules =
@@ -2369,11 +2517,11 @@ bracket selector rules =
23692517
23702518fontAdjustmentRules converted =
23712519 ( [ ( "display", "block" )
2372− , ( "line-height", String.fromFloat converted.height )
23732520 ]
23742521 , [ ( "display", "inline-block" )
23752522 , ( "line-height", String.fromFloat converted.height )
23762523 , ( "vertical-align", String.fromFloat converted.vertical ++ "em" )
2524+ , ( "font-size", String.fromFloat converted.size ++ "em" )
23772525 ]
23782526 )
23792527
@@ -2385,10 +2533,17 @@ typefaceAdjustment typefaces =
23852533 Nothing ->
23862534 case face of
23872535 FontWith with ->
2388− Just
2389− (fontAdjustmentRules
2390− (.capital (convertAdjustment with.adjustment))
2391− )
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+ )
23922547
23932548 _ ->
23942549 found
@@ -2438,475 +2593,492 @@ renderProps force (Property key val) existing =
24382593 existing ++ "\n " ++ key ++ ": " ++ val ++ ";"
24392594
24402595
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+
24412609toStyleSheetString : OptionRecord -> List Style -> String
24422610toStyleSheetString options stylesheet =
24432611 let
2444− renderStyle maybePseudo selector props =
2445− case maybePseudo of
2446− Nothing ->
2447− selector ++ "{" ++ List.foldl (renderProps False) "" props ++ "\n}"
2448−
2449− Just pseudo ->
2450− case pseudo of
2451− Hover ->
2452− case options.hover of
2453− NoHover ->
2454− ""
2612+ combine style rendered =
2613+ { rules = rendered.rules ++ renderStyleRule options style Nothing
2614+ , topLevel =
2615+ case topLevelValue style of
2616+ Nothing ->
2617+ rendered.topLevel
24552618
2456− ForceHover ->
2457− 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
24582626
2459− AllowHover ->
2460− selector ++ "-hv:hover {" ++ List.foldl (renderProps False) "" props ++ "\n}"
24612627
2462− Focus ->
2463− let
2464− renderedProps =
2465− List.foldl (renderProps False) "" props
2466− in
2467− String.join "\n"
2468− [ selector
2469− ++ "-fs:focus {"
2470− ++ renderedProps
2471− ++ "\n}"
2472− , "."
2473− ++ classes.any
2474− ++ ":focus ~ "
2475− ++ selector
2476− ++ "-fs:not(.focus) {"
2477− ++ renderedProps
2478− ++ "\n}"
2479− , "."
2480− ++ classes.any
2481− ++ ":focus "
2482− ++ selector
2483− ++ "-fs {"
2484− ++ renderedProps
2485− ++ "\n}"
2486− , ".focusable-parent:focus ~ "
2487− ++ "."
2488− ++ classes.any
2489− ++ " "
2490− ++ selector
2491− ++ "-fs {"
2492− ++ renderedProps
2493− ++ "\n}"
2494− ]
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}" ]
24952633
2496− Active ->
2497− 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+ []
24982640
2499− renderStyleRule rule maybePseudo =
2500− case rule of
2501− Style selector props ->
2502− renderStyle maybePseudo selector props
2641+ ForceHover ->
2642+ [ selector ++ "-hv {" ++ List.foldl (renderProps True) "" props ++ "\n}" ]
25032643
2504− Shadows name prop ->
2505− renderStyle
2506− maybePseudo
2507− ("." ++ name)
2508− [ Property "box-shadow" prop
2509− ]
2644+ AllowHover ->
2645+ [ selector ++ "-hv:hover {" ++ List.foldl (renderProps False) "" props ++ "\n}" ]
25102646
2511− Transparency name transparency ->
2647+ Focus ->
25122648 let
2513− opacity =
2514− (1 - transparency)
2515− |> min 1
2516− |> max 0
2649+ renderedProps =
2650+ List.foldl (renderProps False) "" props
25172651 in
2518− renderStyle
2519− maybePseudo
2520− ("." ++ name)
2521− [ Property "opacity" (String.fromFloat opacity)
2522− ]
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+ ]
25232663
2524− FontSize i ->
2525− renderStyle
2526− maybePseudo
2527− (".font-size-" ++ String.fromInt i)
2528− [ Property "font-size" (String.fromInt i ++ "px")
2529− ]
2664+ Active ->
2665+ [ selector ++ "-act:active {" ++ List.foldl (renderProps False) "" props ++ "\n}" ]
25302666
2531− FontFamily name typefaces ->
2532− let
2533− families =
2534− Property "font-family"
2535− (typefaces
2536− |> List.map fontName
2537− |> String.join ", "
2538− )
2539− in
2540− String.join " "
2541− [ renderStyle
2542− maybePseudo
2543− ("." ++ name)
2544− [ families ]
2545− ]
25462667
2547− Single class prop val ->
2548− renderStyle
2549− maybePseudo
2550− ("." ++ class)
2551− [ Property prop val
2552− ]
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+ ]
25532680
2554− Colored class prop color ->
2555− renderStyle
2556− maybePseudo
2557− ("." ++ class)
2558− [ Property prop (formatColor color)
2559− ]
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+ ]
25602693
2561− SpacingStyle cls x y ->
2562− let
2563− class =
2564− "." ++ cls
2694+ FontSize i ->
2695+ renderStyle options
2696+ maybePseudo
2697+ (".font-size-" ++ String.fromInt i)
2698+ [ Property "font-size" (String.fromInt i ++ "px")
2699+ ]
25652700
2566− halfX =
2567− 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"
25682718
2569− halfY =
2570− String.fromFloat (toFloat y / 2) ++ "px"
2719+ else
2720+ "normal"
2721+ )
2722+ ]
2723+ in
2724+ renderStyle options
2725+ maybePseudo
2726+ ("." ++ name)
2727+ families
25712728
2572− xPx =
2573− String.fromInt x ++ "px"
2729+ Single class prop val ->
2730+ renderStyle options
2731+ maybePseudo
2732+ ("." ++ class)
2733+ [ Property prop val
2734+ ]
25742735
2575− yPx =
2576− String.fromInt y ++ "px"
2736+ Colored class prop color ->
2737+ renderStyle options
2738+ maybePseudo
2739+ ("." ++ class)
2740+ [ Property prop (formatColor color)
2741+ ]
25772742
2578− row =
2579− "." ++ Internal.Style.classes.row
2743+ SpacingStyle cls x y ->
2744+ let
2745+ class =
2746+ "." ++ cls
25802747
2581− wrappedRow =
2582− "." ++ Internal.Style.classes.wrapped ++ row
2748+ halfX =
2749+ String.fromFloat (toFloat x / 2) ++ "px"
25832750
2584− column =
2585− "." ++ Internal.Style.classes.column
2751+ halfY =
2752+ String.fromFloat (toFloat y / 2) ++ "px"
25862753
2587− page =
2588− "." ++ Internal.Style.classes.page
2754+ xPx =
2755+ String.fromInt x ++ "px"
25892756
2590− paragraph =
2591− "." ++ Internal.Style.classes.paragraph
2757+ yPx =
2758+ String.fromInt y ++ "px"
25922759
2593− left =
2594− "." ++ Internal.Style.classes.alignLeft
2760+ row =
2761+ "." ++ Internal.Style.classes.row
25952762
2596− right =
2597− "." ++ Internal.Style.classes.alignRight
2763+ wrappedRow =
2764+ "." ++ Internal.Style.classes.wrapped ++ row
25982765
2599− any =
2600− "." ++ Internal.Style.classes.any
2766+ column =
2767+ "." ++ Internal.Style.classes.column
26012768
2602− single =
2603− "." ++ Internal.Style.classes.single
2604− in
2605− String.concat
2606− [ renderStyle maybePseudo (class ++ row ++ " > " ++ any ++ " + " ++ any) [ Property "margin-left" xPx ]
2607−
2608− -- margins don't apply to last element of normal, unwrapped rows
2609− -- , renderStyle maybePseudo (class ++ row ++ " > " ++ any ++ ":first-child") [ Property "margin" "0" ]
2610− -- For wrapped rows, margins always apply because we handle "canceling out" the other margins manually in the element.
2611− , renderStyle maybePseudo
2612− (class ++ wrappedRow ++ " > " ++ any)
2613− [ Property "margin" (halfY ++ " " ++ halfX)
2614− ]
2769+ page =
2770+ "." ++ Internal.Style.classes.page
26152771
2616− -- , renderStyle maybePseudo
2617− -- (class ++ wrappedRow ++ " > " ++ any ++ ":last-child")
2618− -- [ Property "margin-right" "0"
2619− -- ]
2620− -- columns
2621− , renderStyle maybePseudo (class ++ column ++ " > " ++ any ++ " + " ++ any) [ Property "margin-top" yPx ]
2622− , renderStyle maybePseudo (class ++ page ++ " > " ++ any ++ " + " ++ any) [ Property "margin-top" yPx ]
2623− , renderStyle maybePseudo (class ++ page ++ " > " ++ left) [ Property "margin-right" xPx ]
2624− , renderStyle maybePseudo (class ++ page ++ " > " ++ right) [ Property "margin-left" xPx ]
2625− , renderStyle
2626− maybePseudo
2627− (class ++ paragraph)
2628− [ Property "line-height" ("calc(1em + " ++ String.fromInt y ++ "px)")
2629− ]
2630− , renderStyle
2631− maybePseudo
2632− ("textarea" ++ class)
2633− [ Property "line-height" ("calc(1em + " ++ String.fromInt y ++ "px)")
2634− ]
2772+ paragraph =
2773+ "." ++ Internal.Style.classes.paragraph
26352774
2636− -- , renderStyle
2637− -- maybePseudo
2638− -- (class ++ paragraph ++ " > " ++ any)
2639− -- [ Property "margin-right" xPx
2640− -- , Property "margin-bottom" yPx
2641− -- ]
2642− , renderStyle
2643− maybePseudo
2644− (class ++ paragraph ++ " > " ++ left)
2645− [ Property "margin-right" xPx
2646− ]
2647− , renderStyle
2648− maybePseudo
2649− (class ++ paragraph ++ " > " ++ right)
2650− [ Property "margin-left" xPx
2651− ]
2652− , renderStyle
2653− maybePseudo
2654− (class ++ paragraph ++ "::after")
2655− [ Property "content" "''"
2656− , Property "display" "block"
2657− , Property "height" "0"
2658− , Property "width" "0"
2659− , Property "margin-top" (String.fromInt (-1 * (y // 2)) ++ "px")
2660− ]
2661− , renderStyle
2662− maybePseudo
2663− (class ++ paragraph ++ "::before")
2664− [ Property "content" "''"
2665− , Property "display" "block"
2666− , Property "height" "0"
2667− , Property "width" "0"
2668− , Property "margin-bottom" (String.fromInt (-1 * (y // 2)) ++ "px")
2669− ]
2670− ]
2775+ left =
2776+ "." ++ Internal.Style.classes.alignLeft
26712777
2672− PaddingStyle cls top right bottom left ->
2673− let
2674− class =
2675− "."
2676− ++ cls
2677− in
2678− renderStyle
2679− maybePseudo
2680− class
2681− [ Property "padding"
2682− (String.fromInt top
2683− ++ "px "
2684− ++ String.fromInt right
2685− ++ "px "
2686− ++ String.fromInt bottom
2687− ++ "px "
2688− ++ String.fromInt left
2689− ++ "px"
2690− )
2691− ]
2778+ right =
2779+ "." ++ Internal.Style.classes.alignRight
26922780
2693− BorderWidth cls top right bottom left ->
2694− let
2695− class =
2696− "."
2697− ++ cls
2698− in
2699− renderStyle
2700− maybePseudo
2701− class
2702− [ Property "border-width"
2703− (String.fromInt top
2704− ++ "px "
2705− ++ String.fromInt right
2706− ++ "px "
2707− ++ String.fromInt bottom
2708− ++ "px "
2709− ++ String.fromInt left
2710− ++ "px"
2711− )
2712− ]
2781+ any =
2782+ "." ++ Internal.Style.classes.any
27132783
2714− GridTemplateStyle template ->
2715− let
2716− class =
2717− ".grid-rows-"
2718− ++ String.join "-" (List.map lengthClassName template.rows)
2719− ++ "-cols-"
2720− ++ String.join "-" (List.map lengthClassName template.columns)
2721− ++ "-space-x-"
2722− ++ lengthClassName (Tuple.first template.spacing)
2723− ++ "-space-y-"
2724− ++ lengthClassName (Tuple.second template.spacing)
2725−
2726− ySpacing =
2727− toGridLength (Tuple.second template.spacing)
2728−
2729− xSpacing =
2730− toGridLength (Tuple.first template.spacing)
2731−
2732− toGridLength x =
2733− toGridLengthHelper Nothing Nothing x
2734−
2735− toGridLengthHelper minimum maximum x =
2736− case x of
2737− Px px ->
2738− String.fromInt px ++ "px"
2739−
2740− Content ->
2741− case ( minimum, maximum ) of
2742− ( Nothing, Nothing ) ->
2743− "max-content"
2744−
2745− ( Just minSize, Nothing ) ->
2746− "minmax(" ++ String.fromInt minSize ++ "px, " ++ "max-content)"
2747−
2748− ( Nothing, Just maxSize ) ->
2749− "minmax(max-content, " ++ String.fromInt maxSize ++ "px)"
2750−
2751− ( Just minSize, Just maxSize ) ->
2752− "minmax(" ++ String.fromInt minSize ++ "px, " ++ String.fromInt maxSize ++ "px)"
2753−
2754− Fill i ->
2755− case ( minimum, maximum ) of
2756− ( Nothing, Nothing ) ->
2757− String.fromInt i ++ "fr"
2758−
2759− ( Just minSize, Nothing ) ->
2760− "minmax(" ++ String.fromInt minSize ++ "px, " ++ String.fromInt i ++ "fr" ++ "fr)"
2761−
2762− ( Nothing, Just maxSize ) ->
2763− "minmax(max-content, " ++ String.fromInt maxSize ++ "px)"
2764−
2765− ( Just minSize, Just maxSize ) ->
2766− "minmax(" ++ String.fromInt minSize ++ "px, " ++ String.fromInt maxSize ++ "px)"
2767−
2768− Min m len ->
2769− toGridLengthHelper (Just m) maximum len
2770−
2771− Max m len ->
2772− toGridLengthHelper minimum (Just m) len
2773−
2774− msColumns =
2775− template.columns
2776− |> List.map toGridLength
2777− |> String.join ySpacing
2778− |> (\x -> "-ms-grid-columns: " ++ x ++ ";")
2779−
2780− msRows =
2781− template.columns
2782− |> List.map toGridLength
2783− |> String.join ySpacing
2784− |> (\x -> "-ms-grid-rows: " ++ x ++ ";")
2785−
2786− base =
2787− class ++ "{" ++ msColumns ++ msRows ++ "}"
2788−
2789− columns =
2790− template.columns
2791− |> List.map toGridLength
2792− |> String.join " "
2793− |> (\x -> "grid-template-columns: " ++ x ++ ";")
2794−
2795− rows =
2796− template.rows
2797− |> List.map toGridLength
2798− |> String.join " "
2799− |> (\x -> "grid-template-rows: " ++ x ++ ";")
2800−
2801− gapX =
2802− "grid-column-gap:" ++ toGridLength (Tuple.first template.spacing) ++ ";"
2803−
2804− gapY =
2805− "grid-row-gap:" ++ toGridLength (Tuple.second template.spacing) ++ ";"
2806−
2807− modernGrid =
2808− class ++ "{" ++ columns ++ rows ++ gapX ++ gapY ++ "}"
2809−
2810− supports =
2811− "@supports (display:grid) {" ++ modernGrid ++ "}"
2812− in
2813− 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+ ]
28142798
2815− GridPosition position ->
2816− let
2817− class =
2818− ".grid-pos-"
2819− ++ String.fromInt position.row
2820− ++ "-"
2821− ++ String.fromInt position.col
2822− ++ "-"
2823− ++ String.fromInt position.width
2824− ++ "-"
2825− ++ String.fromInt position.height
2826−
2827− msPosition =
2828− String.join " "
2829− [ "-ms-grid-row: "
2830− ++ String.fromInt position.row
2831− ++ ";"
2832− , "-ms-grid-row-span: "
2833− ++ String.fromInt position.height
2834− ++ ";"
2835− , "-ms-grid-column: "
2836− ++ String.fromInt position.col
2837− ++ ";"
2838− , "-ms-grid-column-span: "
2839− ++ String.fromInt position.width
2840− ++ ";"
2841− ]
2842−
2843− base =
2844− class ++ "{" ++ msPosition ++ "}"
2845−
2846− modernPosition =
2847− String.join " "
2848− [ "grid-row: "
2849− ++ String.fromInt position.row
2850− ++ " / "
2851− ++ String.fromInt (position.row + position.height)
2852− ++ ";"
2853− , "grid-column: "
2854− ++ String.fromInt position.col
2855− ++ " / "
2856− ++ String.fromInt (position.col + position.width)
2857− ++ ";"
2858− ]
2859−
2860− modernGrid =
2861− class ++ "{" ++ modernPosition ++ "}"
2862−
2863− supports =
2864− "@supports (display:grid) {" ++ modernGrid ++ "}"
2865− in
2866− 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+ ]
28672819
2868− PseudoSelector class styles ->
2869− let
2870− renderPseudoRule style =
2871− renderStyleRule style (Just class)
2872− in
2873− 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
28742976 |> String.join " "
2977+ |> (\x -> "grid-template-columns: " ++ x ++ ";")
28752978
2876− Transform transform ->
2877− let
2878− val =
2879− transformValue transform
2979+ rows =
2980+ template.rows
2981+ |> List.map toGridLength
2982+ |> String.join " "
2983+ |> (\x -> "grid-template-rows: " ++ x ++ ";")
28802984
2881− class =
2882− transformClass transform
2883− in
2884− case ( class, val ) of
2885− ( Just cls, Just v ) ->
2886− renderStyle
2887− maybePseudo
2888− ("." ++ cls)
2889− [ Property "transform"
2890− v
2891− ]
2985+ gapX =
2986+ "grid-column-gap:" ++ toGridLength (Tuple.first template.spacing) ++ ";"
28922987
2893− _ ->
2894− ""
2988+ gapY =
2989+ "grid-row-gap:" ++ toGridLength (Tuple.second template.spacing) ++ ";"
28952990
2896− combine style rendered =
2897− { rules = rendered.rules ++ renderStyleRule style Nothing
2898− , topLevel =
2899− case topLevelValue style of
2900− Nothing ->
2901− rendered.topLevel
2991+ modernGrid =
2992+ class ++ "{" ++ columns ++ rows ++ gapX ++ gapY ++ "}"
29022993
2903− Just topLevel ->
2904− topLevel :: rendered.topLevel
2905− }
2906− in
2907− case List.foldl combine { topLevel = [], rules = "" } stylesheet of
2908− { topLevel, rules } ->
2909− 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+ []
29103082
29113083
29123084lengthClassName : Length -> String
@@ -2946,12 +3118,12 @@ formatTextShadow shadow =
29463118 ]
29473119
29483120
2949−textShadowName shadow =
3121+textShadowClass shadow =
29503122 String.concat
29513123 [ "txt"
2952− , String.fromFloat (Tuple.first shadow.offset) ++ "px"
2953− , String.fromFloat (Tuple.second shadow.offset) ++ "px"
2954− , String.fromFloat shadow.blur ++ "px"
3124+ , floatClass (Tuple.first shadow.offset) ++ "px"
3125+ , floatClass (Tuple.second shadow.offset) ++ "px"
3126+ , floatClass shadow.blur ++ "px"
29553127 , formatColorClass shadow.color
29563128 ]
29573129
@@ -2972,17 +3144,17 @@ formatBoxShadow shadow =
29723144 ]
29733145
29743146
2975−boxShadowName shadow =
3147+boxShadowClass shadow =
29763148 String.concat <|
29773149 [ if shadow.inset then
29783150 "box-inset"
29793151
29803152 else
29813153 "box-"
2982− , String.fromFloat (Tuple.first shadow.offset) ++ "px"
2983− , String.fromFloat (Tuple.second shadow.offset) ++ "px"
2984− , String.fromFloat shadow.blur ++ "px"
2985− , 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"
29863158 , formatColorClass shadow.color
29873159 ]
29883160
@@ -3027,6 +3199,17 @@ paddingName top right bottom left =
30273199 ++ String.fromInt left
30283200
30293201
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+
30303213getStyleName : Style -> String
30313214getStyleName style =
30323215 case style of
@@ -3339,19 +3522,29 @@ convertAdjustment adjustment =
33393522 |> Maybe.withDefault adjustment.baseline
33403523
33413524 capitalVertical =
3342− (oldMiddle - newCapitalMiddle) * 2
3525+ 1 - ascender
3526+
3527+ capitalSize =
3528+ 1 / (ascender - newBaseline)
3529+
3530+ fullSize =
3531+ 1 / (ascender - descender)
33433532
33443533 fullVertical =
3345− (oldMiddle - newFullMiddle) * 2
3534+ 1 - ascender
3535+
3536+ -- (oldMiddle - newFullMiddle) * 2
33463537 in
33473538 { full =
3348− { vertical = fullVertical
3349− , height =
3350− (ascender - descender)
3351− - abs fullVertical
3352− }
3539+ adjust fullSize (ascender - descender) fullVertical
33533540 , capital =
3354− { vertical = capitalVertical
3355− , height = (ascender - newBaseline) - abs capitalVertical
3356− }
3541+ adjust capitalSize (ascender - newBaseline) capitalVertical
3542+ }
3543+
3544+
3545+adjust size height vertical =
3546+ { vertical = vertical
3547+ , height =
3548+ height / size
3549+ , size = size
33573550 }