@@ -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
@@ -68,6 +70,7 @@ module Internal.Model exposing
6870 , getWidth
6971 , gridClass
7072 , htmlClass
73+ , isContent
7174 , lengthClassName
7275 , map
7376 , mapAttr
@@ -76,41 +79,30 @@ module Internal.Model exposing
7679 , onlyStyles
7780 , optionsToRecord
7881 , paddingName
82+ , paddingNameFloat
7983 , pageClass
8084 , paragraphClass
8185 , reduceRecursive
82− , reduceRecursiveCalcName
8386 , reduceStyles
8487 , reduceStylesRecursive
8588 , removeNever
86− , renderFocusStyle
87− , renderFont
8889 , renderFontClassName
8990 , renderHeight
9091 , renderRoot
92+ , renderVariant
9193 , renderWidth
9294 , rootStyle
9395 , rowClass
9496 , singleClass
95− , skippable
96− , sortedReduce
9797 , spacingName
98− , staticRoot
9998 , tag
100− , textElement
101− , textElementFill
102− , textShadowName
99+ , textShadowClass
103100 , toHtml
104101 , toStyleSheet
105− , toStyleSheetString
106102 , transformClass
107− , transformValue
108− , unit
109103 , unstyled
110− , untransformed
111104 , unwrapDecorations
112− , unwrapDecsHelper
113− , isContent
105+ , variantName
114106 )
115107
116108{-| -}
@@ -120,7 +112,7 @@ import Html.Attributes
120112import Html.Keyed
121113import Internal.Flag as Flag exposing (Flag)
122114import Internal.Style exposing (classes, dot)
123−import Json.Encode as Json
115+import Json.Encode as Encode
124116import Set exposing (Set)
125117import VirtualDom
126118
@@ -182,7 +174,7 @@ type Style
182174 | Colored String String Color
183175 | SpacingStyle String Int Int
184176 | BorderWidth String Int Int Int Int
185− | PaddingStyle String Int Int Int Int
177+ | PaddingStyle String Float Float Float Float
186178 | GridTemplateStyle
187179 { spacing : ( Length, Length )
188180 , columns : List Length
@@ -213,12 +205,86 @@ type PseudoClass
213205 | Active
214206
215207
208+{-| -}
209+type alias Adjustment =
210+ { capital : Float
211+ , lowercase : Float
212+ , baseline : Float
213+ , descender : Float
214+ }
215+
216+
216217type Font
217218 = Serif
218219 | SansSerif
219220 | Monospace
220221 | Typeface String
221222 | ImportFont String String
223+ | FontWith
224+ { name : String
225+ , adjustment : Maybe Adjustment
226+ , variants : List Variant
227+ }
228+
229+
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
222288
223289
224290type Property
@@ -306,6 +372,13 @@ type NodeName
306372 | Embedded String String
307373
308374
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+
309382div =
310383 Generic
311384
@@ -314,7 +387,7 @@ type alias Gathered msg =
314387 { node : NodeName
315388 , attributes : List (VirtualDom.Attribute msg)
316389 , styles : List Style
317− , children : List (VirtualDom.Node msg)
390+ , children : NearbyChildren msg
318391 , has : Flag.Field
319392 }
320393
@@ -330,7 +403,6 @@ unstyled =
330403 Unstyled << always
331404
332405
333−
334406finalizeNode has node attributes children embedMode parentContext =
335407 let
336408 createNode nodeName attrs =
@@ -383,7 +455,10 @@ finalizeNode has node attributes children embedMode parentContext =
383455 Embedded nodeName internal ->
384456 VirtualDom.node nodeName
385457 attributes
386− [ createNode internal [ Html.Attributes.class (classes.any ++ " " ++ classes.single) ]
458+ [ createNode internal
459+ [ Html.Attributes.class
460+ (classes.any ++ " " ++ classes.single)
461+ ]
387462 ]
388463 in
389464 case parentContext of
@@ -460,49 +535,45 @@ finalizeNode has node attributes children embedMode parentContext =
460535
461536
462537embedWith 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
463547 if static then
464− staticRoot
465− :: (styles
466− |> List.foldl reduceStyles ( Set.empty, [ renderFocusStyle opts.focus ] )
467− |> Tuple.second
468− -- |> reduceStylesRecursive Set.empty [ ]) --renderFocusStyle opts.focus ]
469− -- |> sortedReduce
470− |> toStyleSheet opts
471− )
548+ staticRoot opts
549+ :: dynamicStyleSheet
472550 :: children
473551
474552 else
475− (styles
476− |> List.foldl reduceStyles ( Set.empty, [ renderFocusStyle opts.focus ] )
477− |> Tuple.second
478− -- |> reduceStylesRecursive Set.empty [ ]) --renderFocusStyle opts.focus ]
479− -- |> sortedReduce
480− |> toStyleSheet opts
481− )
553+ dynamicStyleSheet
482554 :: children
483555
484556
485557embedKeyed 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
486567 if static then
487− ( "static-stylesheet", staticRoot )
568+ ( "static-stylesheet", staticRoot opts )
488569 :: ( "dynamic-stylesheet"
489− , styles
490− |> List.foldl reduceStyles ( Set.empty, [ renderFocusStyle opts.focus ] )
491− |> Tuple.second
492− -- |> reduceStylesRecursive Set.empty [ ]) --renderFocusStyle opts.focus ]
493− -- |> sortedReduce
494− |> toStyleSheet opts
570+ , dynamicStyleSheet
495571 )
496572 :: children
497573
498574 else
499575 ( "dynamic-stylesheet"
500− , styles
501− |> List.foldl reduceStyles ( Set.empty, [ renderFocusStyle opts.focus ] )
502− |> Tuple.second
503− -- |> reduceStylesRecursive Set.empty [ ]) --renderFocusStyle opts.focus ]
504− -- |> sortedReduce
505− |> toStyleSheet opts
576+ , dynamicStyleSheet
506577 )
507578 :: children
508579
@@ -818,7 +889,16 @@ skippable flag style =
818889 False
819890
820891
821−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
822902gatherAttrRecursive classes node has transform styles attrs children elementAttrs =
823903 case elementAttrs of
824904 [] ->
@@ -952,7 +1032,7 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
9521032 in
9531033 gatherAttrRecursive (classes ++ " " ++ newClass)
9541034 node
955− (Flag.merge addToFlags has)
1035+ (Flag.merge addToFlags (Flag.add Flag.width has))
9561036 transform
9571037 (newStyles ++ styles)
9581038 attrs
@@ -973,7 +1053,7 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
9731053 name =
9741054 "height-px-" ++ val
9751055 in
976− gatherAttrRecursive (name ++ " " ++ classes)
1056+ gatherAttrRecursive (Internal.Style.classes.heightExact ++ " " ++ name ++ " " ++ classes)
9771057 node
9781058 (Flag.add Flag.height has)
9791059 transform
@@ -1030,7 +1110,7 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
10301110 in
10311111 gatherAttrRecursive (classes ++ " " ++ newClass)
10321112 node
1033− (Flag.merge addToFlags has)
1113+ (Flag.merge addToFlags (Flag.add Flag.height has))
10341114 transform
10351115 (newStyles ++ styles)
10361116 attrs
@@ -1062,20 +1142,15 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
10621142 gatherAttrRecursive classes (addNodeName "h6" node) has transform styles attrs children remaining
10631143
10641144 Paragraph ->
1065− let
1066− newNode =
1067− case node of
1068− Generic ->
1069− NodeName "p"
1070−
1071− NodeName name ->
1072− NodeName name
1073−
1074− Embedded x y ->
1075− Embedded x y
1076− in
1077− gatherAttrRecursive classes
1078− 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
10791154 has
10801155 transform
10811156 styles
@@ -1110,75 +1185,16 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
11101185
11111186 Styled styled ->
11121187 styles ++ styled.styles
1113−
1114− nearbyElement =
1115− Html.div
1116− [ Html.Attributes.class <|
1117− case location of
1118− Above ->
1119− String.join " "
1120− [ Internal.Style.classes.nearby
1121− , Internal.Style.classes.single
1122− , Internal.Style.classes.above
1123− ]
1124−
1125− Below ->
1126− String.join " "
1127− [ Internal.Style.classes.nearby
1128− , Internal.Style.classes.single
1129− , Internal.Style.classes.below
1130− ]
1131−
1132− OnRight ->
1133− String.join " "
1134− [ Internal.Style.classes.nearby
1135− , Internal.Style.classes.single
1136− , Internal.Style.classes.onRight
1137− ]
1138−
1139− OnLeft ->
1140− String.join " "
1141− [ Internal.Style.classes.nearby
1142− , Internal.Style.classes.single
1143− , Internal.Style.classes.onLeft
1144− ]
1145−
1146− InFront ->
1147− String.join " "
1148− [ Internal.Style.classes.nearby
1149− , Internal.Style.classes.single
1150− , Internal.Style.classes.inFront
1151− ]
1152−
1153− Behind ->
1154− String.join " "
1155− [ Internal.Style.classes.nearby
1156− , Internal.Style.classes.single
1157− , Internal.Style.classes.behind
1158− ]
1159− ]
1160− [ case elem of
1161− Empty ->
1162− VirtualDom.text ""
1163−
1164− Text str ->
1165− textElement str
1166−
1167− Unstyled html ->
1168− html asEl
1169−
1170− Styled styled ->
1171− styled.html NoStyleSheet asEl
1172− ]
1173−
1174− newClasses =
1175− if location == Behind then
1176− Internal.Style.classes.hasBehind ++ " " ++ classes
1177−
1178− else
1179− classes
11801188 in
1181− 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
11821198
11831199 AlignX x ->
11841200 if Flag.present Flag.xAlign has then
@@ -1234,6 +1250,106 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
12341250 remaining
12351251
12361252
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+
12371353renderWidth w =
12381354 case w of
12391355 Px px ->
@@ -1320,7 +1436,7 @@ renderHeight h =
13201436 "height-px-" ++ val
13211437 in
13221438 ( Flag.none
1323− , name
1439+ , Internal.Style.classes.heightExact ++ " " ++ name
13241440 , [ Single name "height" (val ++ "px") ]
13251441 )
13261442
@@ -1343,7 +1459,7 @@ renderHeight h =
13431459 , [ Single
13441460 (Internal.Style.classes.any
13451461 ++ "."
1346− ++ Internal.Style.classes.row
1462+ ++ Internal.Style.classes.column
13471463 ++ " > "
13481464 ++ (Internal.Style.dot <| "height-fill-" ++ String.fromInt portion)
13491465 )
@@ -1362,7 +1478,9 @@ renderHeight h =
13621478 Single
13631479 cls
13641480 "min-height"
1365− (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")
13661484
13671485 ( newFlag, newAttrs, newStyle ) =
13681486 renderHeight len
@@ -1440,7 +1558,7 @@ element : LayoutContext -> NodeName -> List (Attribute aligned msg) -> Children
14401558element context node attributes children =
14411559 attributes
14421560 |> List.reverse
1443− |> gatherAttrRecursive (contextClasses context) node Flag.none untransformed [] [] []
1561+ |> gatherAttrRecursive (contextClasses context) node Flag.none untransformed [] [] NoNearbyChildren
14441562 |> createElement context children
14451563
14461564
@@ -1448,13 +1566,6 @@ untransformed =
14481566 Untransformed
14491567
14501568
1451−
1452−-- space =
1453−-- VirtualDom.text " "
1454−-- keyedSpace =
1455−-- ( " ", space )
1456−
1457−
14581569createElement : LayoutContext -> Children (Element msg) -> Gathered msg -> Element msg
14591570createElement context children rendered =
14601571 let
@@ -1496,36 +1607,33 @@ createElement context children rendered =
14961607 -- Same if it's a column or row with one child and width-content, height-content
14971608 -- interferes with css grid
14981609 -- Maybe we could unpack text elements in a paragraph as well,
1499− -- however embedded style elements that are larger than the line height will overlap with exisitng text.
1610+ -- however, embedded elements that are larger than the line height will overlap with exisitng text.
15001611 -- I don't think that's what we want.
1501− if
1502− context
1503− == asEl
1504− || context
1505− == asParagraph
1506− then
1507− ( VirtualDom.text
1508− (if context == asParagraph then
1509− str ++ " "
1510−
1511− else
1512− str
1513− )
1514− :: htmls
1515− , existingStyles
1516− )
1517−
1518− else
1519− ( textElement
1520− (if context == asParagraph then
1521− str ++ " "
1522−
1523− else
1524− str
1525− )
1526− :: htmls
1527− , existingStyles
1528− )
1612+ -- if
1613+ -- context
1614+ -- == asEl
1615+ -- || context
1616+ -- == asParagraph
1617+ -- then
1618+ -- ( VirtualDom.text
1619+ -- (if context == asParagraph then
1620+ -- str
1621+ -- else
1622+ -- str
1623+ -- )
1624+ -- :: htmls
1625+ -- , existingStyles
1626+ -- )
1627+ -- else
1628+ ( (if context == asEl then
1629+ textElementFill str
1630+
1631+ else
1632+ textElement str
1633+ )
1634+ :: htmls
1635+ , existingStyles
1636+ )
15291637
15301638 Empty ->
15311639 ( htmls, existingStyles )
@@ -1567,38 +1675,30 @@ createElement context children rendered =
15671675 -- TEXT OPTIMIZATION
15681676 -- You can have raw text if the element is an el, and has `width-content` and `height-content`
15691677 -- Same if it's a column or row with one child and width-content, height-content
1570− if
1571− context
1572− == asEl
1573− || context
1574− == asParagraph
1575− then
1576− ( ( key
1577− , VirtualDom.text
1578− (if context == asParagraph then
1579− str ++ " "
1580−
1581− else
1582− str
1583− )
1584− )
1585− :: htmls
1586− , existingStyles
1587− )
1678+ -- if
1679+ -- context
1680+ -- == asEl
1681+ -- || context
1682+ -- == asParagraph
1683+ -- then
1684+ -- ( ( key
1685+ -- , VirtualDom.text
1686+ -- str
1687+ -- )
1688+ -- :: htmls
1689+ -- , existingStyles
1690+ -- )
1691+ -- else
1692+ ( ( key
1693+ , if context == asEl then
1694+ textElementFill str
15881695
1589− else
1590− ( ( key
1591− , textElement
1592− (if context == asParagraph then
1593− str ++ " "
1594−
1595− else
1596− str
1597− )
1598− )
1599− :: htmls
1600− , existingStyles
1601− )
1696+ else
1697+ textElement str
1698+ )
1699+ :: htmls
1700+ , existingStyles
1701+ )
16021702
16031703 Empty ->
16041704 ( htmls, existingStyles )
@@ -1621,7 +1721,9 @@ createElement context children rendered =
16211721 (finalizeNode rendered.has
16221722 rendered.node
16231723 rendered.attributes
1624− (Keyed <| List.map (\x -> ( "nearby-elements-pls", x )) rendered.children ++ keyed)
1724+ (Keyed
1725+ (addKeyedChildren "nearby-element-pls" keyed rendered.children)
1726+ )
16251727 NoStyleSheet
16261728 )
16271729
@@ -1629,7 +1731,13 @@ createElement context children rendered =
16291731 Styled
16301732 { styles = allStyles
16311733 , html =
1632− finalizeNode rendered.has rendered.node rendered.attributes (Keyed (List.map (\x -> ( "nearby-elements-pls", x )) rendered.children ++ keyed))
1734+ finalizeNode
1735+ rendered.has
1736+ rendered.node
1737+ rendered.attributes
1738+ (Keyed
1739+ (addKeyedChildren "nearby-element-pls" keyed rendered.children)
1740+ )
16331741 }
16341742
16351743 Unkeyed unkeyedChildren ->
@@ -1646,20 +1754,58 @@ createElement context children rendered =
16461754 case newStyles of
16471755 [] ->
16481756 Unstyled
1649− (finalizeNode rendered.has
1757+ (finalizeNode
1758+ rendered.has
16501759 rendered.node
16511760 rendered.attributes
1652− (Unkeyed <| rendered.children ++ unkeyed)
1761+ (Unkeyed (addChildren unkeyed rendered.children))
16531762 NoStyleSheet
16541763 )
16551764
16561765 allStyles ->
16571766 Styled
16581767 { styles = allStyles
1659− , html = finalizeNode rendered.has rendered.node rendered.attributes (Unkeyed (rendered.children ++ unkeyed))
1768+ , html =
1769+ finalizeNode
1770+ rendered.has
1771+ rendered.node
1772+ rendered.attributes
1773+ (Unkeyed (addChildren unkeyed rendered.children))
16601774 }
16611775
16621776
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+
16631809unit =
16641810 0
16651811
@@ -1671,8 +1817,20 @@ defaultOptions =
16711817 }
16721818
16731819
1674−staticRoot =
1675− 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) ] []
16761834
16771835
16781836addWhen ifThis x to =
@@ -1790,7 +1948,7 @@ type Spacing
17901948
17911949
17921950type Padding
1793− = Padding String Int Int Int Int
1951+ = Padding String Float Float Float Float
17941952
17951953
17961954extractSpacingAndPadding : List (Attribute aligned msg) -> ( Maybe Padding, Maybe Spacing )
@@ -1886,35 +2044,44 @@ getHeight attrs =
18862044 Nothing
18872045
18882046
2047+textElementClasses : String
2048+textElementClasses =
2049+ classes.any
2050+ ++ " "
2051+ ++ classes.text
2052+ ++ " "
2053+ ++ classes.widthContent
2054+ ++ " "
2055+ ++ classes.heightContent
2056+
2057+
18892058textElement : String -> VirtualDom.Node msg
18902059textElement str =
18912060 Html.div
18922061 [ Html.Attributes.class
1893− (String.join " "
1894− [ classes.any
1895− , classes.text
1896− , classes.widthContent
1897− , classes.heightContent
1898− ]
1899− )
2062+ textElementClasses
19002063 ]
19012064 [ Html.text str ]
19022065
19032066
2067+textElementFillClasses : String
2068+textElementFillClasses =
2069+ classes.any
2070+ ++ " "
2071+ ++ classes.text
2072+ ++ " "
2073+ ++ classes.widthFill
2074+ ++ " "
2075+ ++ classes.heightFill
2076+
2077+
19042078textElementFill : String -> VirtualDom.Node msg
19052079textElementFill str =
1906− VirtualDom.node "div"
1907− [ VirtualDom.property "className"
1908− (Json.string <|
1909− String.join " "
1910− [ classes.any
1911− , classes.text
1912− , classes.widthFill
1913− , classes.heightFill
1914− ]
1915− )
2080+ Html.div
2081+ [ Html.Attributes.class
2082+ textElementFillClasses
19162083 ]
1917− [ VirtualDom.text str ]
2084+ [ Html.text str ]
19182085
19192086
19202087type Children x
@@ -1922,10 +2089,6 @@ type Children x
19222089 | Keyed (List ( String, x ))
19232090
19242091
1925−
1926−-- toHtml : OptionRecord -> Element msg -> VirtualDom.Node msg
1927−
1928−
19292092toHtml mode el =
19302093 case el of
19312094 Unstyled html ->
@@ -1961,8 +2124,7 @@ renderRoot optionList attributes child =
19612124
19622125
19632126type RenderMode
1964− = Viewport
1965− | Layout
2127+ = Layout
19662128 | NoStaticStyleSheet
19672129 | WithVirtualCss
19682130
@@ -2011,8 +2173,8 @@ rootStyle =
20112173 , SansSerif
20122174 ]
20132175 in
2014− [ StyleClass Flag.bgColor (Colored ("bg-color-" ++ formatColorClass (Rgba 1 1 1 0)) "background-color" (Rgba 1 1 1 0))
2015− , 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))
20162178 , StyleClass Flag.fontSize (FontSize 20)
20172179 , StyleClass Flag.fontFamily <|
20182180 FontFamily (List.foldl renderFontClassName "font-" families)
@@ -2044,14 +2206,49 @@ renderFontClassName font current =
20442206 |> String.toLower
20452207 |> String.words
20462208 |> String.join "-"
2209+
2210+ FontWith { name } ->
2211+ name
2212+ |> String.toLower
2213+ |> String.words
2214+ |> String.join "-"
20472215 )
20482216
20492217
20502218renderFocusStyle :
20512219 FocusStyle
2052− -> Style
2220+ -> List Style
20532221renderFocusStyle focus =
2054− 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+ )
20552252 (List.filterMap identity
20562253 [ Maybe.map (\color -> Property "border-color" (formatColor color)) focus.borderColor
20572254 , Maybe.map (\color -> Property "background-color" (formatColor color)) focus.backgroundColor
@@ -2074,6 +2271,7 @@ renderFocusStyle focus =
20742271 , Just <| Property "outline" "none"
20752272 ]
20762273 )
2274+ ]
20772275
20782276
20792277focusDefaultStyle : { backgroundColor : Maybe Color, borderColor : Maybe Color, shadow : Maybe Shadow }
@@ -2085,7 +2283,7 @@ focusDefaultStyle =
20852283 { color =
20862284 Rgba (155 / 255) (203 / 255) 1 1
20872285 , offset = ( 0, 0 )
2088− , blur = 3
2286+ , blur = 0
20892287 , size = 3
20902288 }
20912289 }
@@ -2153,519 +2351,734 @@ optionsToRecord options =
21532351 options
21542352
21552353
2156−renderFont : List Font -> String
2157−renderFont families =
2354+toStyleSheet : OptionRecord -> List Style -> VirtualDom.Node msg
2355+toStyleSheet 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+ []
2381+
2382+
2383+renderTopLevelValues rules =
21582384 let
2159− fontName font =
2385+ withImport font =
21602386 case font of
2161− Serif ->
2162− "serif"
2387+ ImportFont _ url ->
2388+ Just ("@import url('" ++ url ++ "');")
2389+
2390+ -- FontWith with ->
2391+ -- case with.url of
2392+ -- Just x ->
2393+ -- Just ("@import url('" ++ x ++ "');")
2394+ -- Nothing ->
2395+ -- Nothing
2396+ _ ->
2397+ Nothing
21632398
2164− SansSerif ->
2165− "sans-serif"
2399+ allNames =
2400+ List.map Tuple.first rules
21662401
2167− Monospace ->
2168− "monospace"
2402+ fontImports ( name, typefaces ) =
2403+ let
2404+ imports =
2405+ String.join "\n" (List.filterMap withImport typefaces)
2406+ in
2407+ imports
21692408
2170− Typeface name ->
2171− "\"" ++ name ++ "\""
2409+ fontAdjustments ( name, typefaces ) =
2410+ case typefaceAdjustment typefaces of
2411+ Nothing ->
2412+ String.join ""
2413+ (List.map (renderNullAdjustmentRule name) allNames)
21722414
2173− ImportFont name url ->
2174− "\"" ++ name ++ "\""
2415+ Just adjustment ->
2416+ String.join ""
2417+ (List.map (renderFontAdjustmentRule name adjustment) allNames)
21752418 in
2176− families
2177− |> List.map fontName
2178− |> String.join ", "
2419+ String.join "\n" (List.map fontImports rules)
2420+ ++ String.join "\n" (List.map fontAdjustments rules)
21792421
21802422
2181−toStyleSheet : OptionRecord -> List Style -> VirtualDom.Node msg
2182−toStyleSheet options styleSheet =
2183− VirtualDom.node "style" [] [ VirtualDom.text (toStyleSheetString options styleSheet) ]
2423+renderNullAdjustmentRule fontToAdjust otherFontName =
2424+ let
2425+ name =
2426+ if fontToAdjust == otherFontName then
2427+ fontToAdjust
21842428
2429+ else
2430+ otherFontName ++ " ." ++ fontToAdjust
2431+ in
2432+ String.join " "
2433+ [ bracket
2434+ ("."
2435+ ++ name
2436+ ++ "."
2437+ ++ classes.sizeByCapital
2438+ ++ ", "
2439+ ++ "."
2440+ ++ name
2441+ ++ " ."
2442+ ++ classes.sizeByCapital
2443+ )
2444+ [ ( "line-height", "1" )
2445+ ]
2446+ , bracket
2447+ ("."
2448+ ++ name
2449+ ++ "."
2450+ ++ classes.sizeByCapital
2451+ ++ "> ."
2452+ ++ Internal.Style.classes.text
2453+ ++ ", ."
2454+ ++ name
2455+ ++ " ."
2456+ ++ classes.sizeByCapital
2457+ ++ " > ."
2458+ ++ Internal.Style.classes.text
2459+ )
2460+ [ ( "vertical-align", "0" )
2461+ , ( "line-height", "1" )
2462+ ]
2463+ ]
21852464
2186−toStyleSheetString : OptionRecord -> List Style -> String
2187−toStyleSheetString options stylesheet =
2188− let
2189− renderTopLevels rule =
2190− case rule of
2191− FontFamily name typefaces ->
2192− let
2193− getImports font =
2194− case font of
2195− ImportFont _ url ->
2196− Just ("@import url('" ++ url ++ "');")
21972465
2198− _ ->
2199− Nothing
2200− in
2201− typefaces
2202− |> List.filterMap getImports
2203− |> String.join "\n"
2204− |> Just
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+ ]
22052495
2206− _ ->
2207− Nothing
22082496
2209− renderProps force (Property key val) existing =
2210− if force then
2211− existing ++ "\n " ++ key ++ ": " ++ val ++ " !important;"
2497+renderFontAdjustmentRule fontToAdjust ( full, capital ) otherFontName =
2498+ let
2499+ name =
2500+ if fontToAdjust == otherFontName then
2501+ fontToAdjust
22122502
22132503 else
2214− existing ++ "\n " ++ key ++ ": " ++ val ++ ";"
2504+ otherFontName ++ " ." ++ fontToAdjust
2505+ in
2506+ String.join " "
2507+ (fontRule name classes.sizeByCapital capital ++ fontRule name classes.fullSize full)
2508+
22152509
2216− renderStyle maybePseudo selector props =
2217− case maybePseudo of
2510+bracket selector rules =
2511+ let
2512+ renderPair ( name, val ) =
2513+ name ++ ": " ++ val ++ ";"
2514+ in
2515+ selector ++ " {" ++ String.join "" (List.map renderPair rules) ++ "}"
2516+
2517+
2518+fontAdjustmentRules converted =
2519+ ( [ ( "display", "block" )
2520+ ]
2521+ , [ ( "display", "inline-block" )
2522+ , ( "line-height", String.fromFloat converted.height )
2523+ , ( "vertical-align", String.fromFloat converted.vertical ++ "em" )
2524+ , ( "font-size", String.fromFloat converted.size ++ "em" )
2525+ ]
2526+ )
2527+
2528+
2529+typefaceAdjustment typefaces =
2530+ List.foldl
2531+ (\face found ->
2532+ case found of
22182533 Nothing ->
2219− selector ++ "{" ++ List.foldl (renderProps False) "" props ++ "\n}"
2534+ case face of
2535+ FontWith with ->
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+ )
22202547
2221− Just pseudo ->
2222− case pseudo of
2223− Hover ->
2224− case options.hover of
2225− NoHover ->
2226− ""
2548+ _ ->
2549+ found
22272550
2228− ForceHover ->
2229− selector ++ "-hv {" ++ List.foldl (renderProps True) "" props ++ "\n}"
2551+ Just _ ->
2552+ found
2553+ )
2554+ Nothing
2555+ typefaces
22302556
2231− AllowHover ->
2232− selector ++ "-hv:hover {" ++ List.foldl (renderProps False) "" props ++ "\n}"
22332557
2234− Focus ->
2235− let
2236− renderedProps =
2237− List.foldl (renderProps False) "" props
2238− in
2239− String.join "\n"
2240− [ selector
2241− ++ "-fs:focus {"
2242− ++ renderedProps
2243− ++ "\n}"
2244− , "."
2245− ++ classes.any
2246− ++ ":focus ~ "
2247− ++ selector
2248− ++ "-fs:not(.focus) {"
2249− ++ renderedProps
2250− ++ "\n}"
2251− , "."
2252− ++ classes.any
2253− ++ ":focus "
2254− ++ selector
2255− ++ "-fs {"
2256− ++ renderedProps
2257− ++ "\n}"
2258− , ".focusable-parent:focus ~ "
2259− ++ "."
2260− ++ classes.any
2261− ++ " "
2262− ++ selector
2263− ++ "-fs {"
2264− ++ renderedProps
2265− ++ "\n}"
2266− ]
2558+fontName font =
2559+ case font of
2560+ Serif ->
2561+ "serif"
22672562
2268− Active ->
2269− selector ++ "-act:active {" ++ List.foldl (renderProps False) "" props ++ "\n}"
2563+ SansSerif ->
2564+ "sans-serif"
22702565
2271− renderStyleRule rule maybePseudo =
2272− case rule of
2273− Style selector props ->
2274− renderStyle maybePseudo selector props
2566+ Monospace ->
2567+ "monospace"
22752568
2276− Shadows name prop ->
2277− renderStyle
2278− maybePseudo
2279− ("." ++ name)
2280− [ Property "box-shadow" prop
2281− ]
2569+ Typeface name ->
2570+ "\"" ++ name ++ "\""
2571+
2572+ ImportFont name url ->
2573+ "\"" ++ name ++ "\""
2574+
2575+ FontWith { name } ->
2576+ "\"" ++ name ++ "\""
2577+
2578+
2579+topLevelValue rule =
2580+ case rule of
2581+ FontFamily name typefaces ->
2582+ Just ( name, typefaces )
2583+
2584+ _ ->
2585+ Nothing
2586+
2587+
2588+renderProps force (Property key val) existing =
2589+ if force then
2590+ existing ++ "\n " ++ key ++ ": " ++ val ++ " !important;"
2591+
2592+ else
2593+ existing ++ "\n " ++ key ++ ": " ++ val ++ ";"
2594+
2595+
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+
2609+toStyleSheetString : OptionRecord -> List Style -> String
2610+toStyleSheetString options stylesheet =
2611+ let
2612+ combine style rendered =
2613+ { rules = rendered.rules ++ renderStyleRule options style Nothing
2614+ , topLevel =
2615+ case topLevelValue style of
2616+ Nothing ->
2617+ rendered.topLevel
2618+
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
22822626
2283− Transparency name transparency ->
2627+
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}" ]
2633+
2634+ Just pseudo ->
2635+ case pseudo of
2636+ Hover ->
2637+ case options.hover of
2638+ NoHover ->
2639+ []
2640+
2641+ ForceHover ->
2642+ [ selector ++ "-hv {" ++ List.foldl (renderProps True) "" props ++ "\n}" ]
2643+
2644+ AllowHover ->
2645+ [ selector ++ "-hv:hover {" ++ List.foldl (renderProps False) "" props ++ "\n}" ]
2646+
2647+ Focus ->
22842648 let
2285− opacity =
2286− (1 - transparency)
2287− |> min 1
2288− |> max 0
2649+ renderedProps =
2650+ List.foldl (renderProps False) "" props
22892651 in
2290− renderStyle
2291− maybePseudo
2292− ("." ++ name)
2293− [ Property "opacity" (String.fromFloat opacity)
2294− ]
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+ ]
22952663
2296− FontSize i ->
2297− renderStyle
2298− maybePseudo
2299− (".font-size-" ++ String.fromInt i)
2300− [ Property "font-size" (String.fromInt i ++ "px")
2301− ]
2664+ Active ->
2665+ [ selector ++ "-act:active {" ++ List.foldl (renderProps False) "" props ++ "\n}" ]
23022666
2303− FontFamily name typefaces ->
2304− renderStyle
2305− maybePseudo
2306− ("." ++ name)
2307− [ Property "font-family" (renderFont typefaces)
2308− ]
23092667
2310− Single class prop val ->
2311− renderStyle
2312− maybePseudo
2313− ("." ++ class)
2314− [ Property prop val
2315− ]
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
23162673
2317− Colored class prop color ->
2318− renderStyle
2319− maybePseudo
2320− ("." ++ class)
2321− [ Property prop (formatColor color)
2322− ]
2674+ Shadows name prop ->
2675+ renderStyle options
2676+ maybePseudo
2677+ ("." ++ name)
2678+ [ Property "box-shadow" prop
2679+ ]
23232680
2324− SpacingStyle cls x y ->
2325− let
2326− class =
2327− "." ++ cls
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+ ]
23282693
2329− xPx =
2330− String.fromInt x ++ "px"
2694+ FontSize i ->
2695+ renderStyle options
2696+ maybePseudo
2697+ (".font-size-" ++ String.fromInt i)
2698+ [ Property "font-size" (String.fromInt i ++ "px")
2699+ ]
23312700
2332− yPx =
2333− String.fromInt y ++ "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"
23342718
2335− row =
2336− "." ++ Internal.Style.classes.row
2719+ else
2720+ "normal"
2721+ )
2722+ ]
2723+ in
2724+ renderStyle options
2725+ maybePseudo
2726+ ("." ++ name)
2727+ families
23372728
2338− wrappedRow =
2339− "." ++ Internal.Style.classes.wrapped ++ row
2729+ Single class prop val ->
2730+ renderStyle options
2731+ maybePseudo
2732+ ("." ++ class)
2733+ [ Property prop val
2734+ ]
23402735
2341− column =
2342− "." ++ Internal.Style.classes.column
2736+ Colored class prop color ->
2737+ renderStyle options
2738+ maybePseudo
2739+ ("." ++ class)
2740+ [ Property prop (formatColor color)
2741+ ]
23432742
2344− page =
2345− "." ++ Internal.Style.classes.page
2743+ SpacingStyle cls x y ->
2744+ let
2745+ class =
2746+ "." ++ cls
23462747
2347− paragraph =
2348− "." ++ Internal.Style.classes.paragraph
2748+ halfX =
2749+ String.fromFloat (toFloat x / 2) ++ "px"
23492750
2350− left =
2351− "." ++ Internal.Style.classes.alignLeft
2751+ halfY =
2752+ String.fromFloat (toFloat y / 2) ++ "px"
23522753
2353− right =
2354− "." ++ Internal.Style.classes.alignRight
2754+ xPx =
2755+ String.fromInt x ++ "px"
23552756
2356− any =
2357− "." ++ Internal.Style.classes.any
2757+ yPx =
2758+ String.fromInt y ++ "px"
23582759
2359− single =
2360− "." ++ Internal.Style.classes.single
2361− in
2362− String.concat
2363− [ renderStyle maybePseudo (class ++ row ++ " > " ++ any) [ Property "margin-right" xPx ]
2760+ row =
2761+ "." ++ Internal.Style.classes.row
23642762
2365− -- margins don't apply to last element of normal, unwrapped rows
2366− , renderStyle maybePseudo (class ++ row ++ " > " ++ any ++ ":last-child") [ Property "margin" "0" ]
2763+ wrappedRow =
2764+ "." ++ Internal.Style.classes.wrapped ++ row
23672765
2368− -- For wrapped rows, margins always apply because we handle "canceling out" the other margins manually in the element.
2369− , renderStyle maybePseudo
2370− (class ++ wrappedRow ++ " > " ++ any)
2371− [ Property "margin" ("0 " ++ xPx ++ " " ++ yPx ++ " 0")
2372− ]
2373− , renderStyle maybePseudo
2374− (class ++ wrappedRow ++ " > " ++ any ++ ":last-child")
2375− [ Property "margin-right" "0"
2376− ]
2766+ column =
2767+ "." ++ Internal.Style.classes.column
23772768
2378− -- columns
2379− , renderStyle maybePseudo (class ++ column ++ " > " ++ any ++ " + " ++ any) [ Property "margin-top" yPx ]
2380− , renderStyle maybePseudo (class ++ page ++ " > " ++ any ++ " + " ++ any) [ Property "margin-top" yPx ]
2381− , renderStyle maybePseudo (class ++ page ++ " > " ++ left) [ Property "margin-right" xPx ]
2382− , renderStyle maybePseudo (class ++ page ++ " > " ++ right) [ Property "margin-left" xPx ]
2383− , renderStyle
2384− maybePseudo
2385− (class ++ paragraph)
2386− [ Property "line-height" ("calc(1em + " ++ String.fromInt y ++ "px)")
2387− ]
2388− , renderStyle
2389− maybePseudo
2390− ("textarea" ++ class)
2391− [ Property "line-height" ("calc(1em + " ++ String.fromInt y ++ "px)")
2392− ]
2769+ page =
2770+ "." ++ Internal.Style.classes.page
23932771
2394− -- , renderStyle
2395− -- maybePseudo
2396− -- (class ++ paragraph ++ " > " ++ any)
2397− -- [ Property "margin-right" xPx
2398− -- , Property "margin-bottom" yPx
2399− -- ]
2400− , renderStyle
2401− maybePseudo
2402− (class ++ paragraph ++ " > " ++ left)
2403− [ Property "margin-right" xPx
2404− ]
2405− , renderStyle
2406− maybePseudo
2407− (class ++ paragraph ++ " > " ++ right)
2408− [ Property "margin-left" xPx
2409− ]
2410− , renderStyle
2411− maybePseudo
2412− (class ++ paragraph ++ "::after")
2413− [ Property "content" "''"
2414− , Property "display" "block"
2415− , Property "height" "0"
2416− , Property "width" "0"
2417− , Property "margin-top" (String.fromInt (-1 * (y // 2)) ++ "px")
2418− ]
2419− , renderStyle
2420− maybePseudo
2421− (class ++ paragraph ++ "::before")
2422− [ Property "content" "''"
2423− , Property "display" "block"
2424− , Property "height" "0"
2425− , Property "width" "0"
2426− , Property "margin-bottom" (String.fromInt (-1 * (y // 2)) ++ "px")
2427− ]
2428− ]
2772+ paragraph =
2773+ "." ++ Internal.Style.classes.paragraph
24292774
2430− PaddingStyle cls top right bottom left ->
2431− let
2432− class =
2433− "."
2434− ++ cls
2435− in
2436− renderStyle
2437− maybePseudo
2438− class
2439− [ Property "padding"
2440− (String.fromInt top
2441− ++ "px "
2442− ++ String.fromInt right
2443− ++ "px "
2444− ++ String.fromInt bottom
2445− ++ "px "
2446− ++ String.fromInt left
2447− ++ "px"
2448− )
2449− ]
2775+ left =
2776+ "." ++ Internal.Style.classes.alignLeft
24502777
2451− BorderWidth cls top right bottom left ->
2452− let
2453− class =
2454− "."
2455− ++ cls
2456− in
2457− renderStyle
2458− maybePseudo
2459− class
2460− [ Property "border-width"
2461− (String.fromInt top
2462− ++ "px "
2463− ++ String.fromInt right
2464− ++ "px "
2465− ++ String.fromInt bottom
2466− ++ "px "
2467− ++ String.fromInt left
2468− ++ "px"
2469− )
2470− ]
2778+ right =
2779+ "." ++ Internal.Style.classes.alignRight
24712780
2472− GridTemplateStyle template ->
2473− let
2474− class =
2475− ".grid-rows-"
2476− ++ String.join "-" (List.map lengthClassName template.rows)
2477− ++ "-cols-"
2478− ++ String.join "-" (List.map lengthClassName template.columns)
2479− ++ "-space-x-"
2480− ++ lengthClassName (Tuple.first template.spacing)
2481− ++ "-space-y-"
2482− ++ lengthClassName (Tuple.second template.spacing)
2483−
2484− ySpacing =
2485− toGridLength (Tuple.second template.spacing)
2486−
2487− xSpacing =
2488− toGridLength (Tuple.first template.spacing)
2489−
2490− toGridLength x =
2491− toGridLengthHelper Nothing Nothing x
2492−
2493− toGridLengthHelper minimum maximum x =
2494− case x of
2495− Px px ->
2496− String.fromInt px ++ "px"
2497−
2498− Content ->
2499− case ( minimum, maximum ) of
2500− ( Nothing, Nothing ) ->
2501− "max-content"
2502−
2503− ( Just minSize, Nothing ) ->
2504− "minmax(" ++ String.fromInt minSize ++ "px, " ++ "max-content)"
2505−
2506− ( Nothing, Just maxSize ) ->
2507− "minmax(max-content, " ++ String.fromInt maxSize ++ "px)"
2508−
2509− ( Just minSize, Just maxSize ) ->
2510− "minmax(" ++ String.fromInt minSize ++ "px, " ++ String.fromInt maxSize ++ "px)"
2511−
2512− Fill i ->
2513− case ( minimum, maximum ) of
2514− ( Nothing, Nothing ) ->
2515− String.fromInt i ++ "fr"
2516−
2517− ( Just minSize, Nothing ) ->
2518− "minmax(" ++ String.fromInt minSize ++ "px, " ++ String.fromInt i ++ "fr" ++ "fr)"
2519−
2520− ( Nothing, Just maxSize ) ->
2521− "minmax(max-content, " ++ String.fromInt maxSize ++ "px)"
2522−
2523− ( Just minSize, Just maxSize ) ->
2524− "minmax(" ++ String.fromInt minSize ++ "px, " ++ String.fromInt maxSize ++ "px)"
2525−
2526− Min m len ->
2527− toGridLengthHelper (Just m) maximum len
2528−
2529− Max m len ->
2530− toGridLengthHelper minimum (Just m) len
2531−
2532− msColumns =
2533− template.columns
2534− |> List.map toGridLength
2535− |> String.join ySpacing
2536− |> (\x -> "-ms-grid-columns: " ++ x ++ ";")
2537−
2538− msRows =
2539− template.columns
2540− |> List.map toGridLength
2541− |> String.join ySpacing
2542− |> (\x -> "-ms-grid-rows: " ++ x ++ ";")
2543−
2544− base =
2545− class ++ "{" ++ msColumns ++ msRows ++ "}"
2546−
2547− columns =
2548− template.columns
2549− |> List.map toGridLength
2550− |> String.join " "
2551− |> (\x -> "grid-template-columns: " ++ x ++ ";")
2552−
2553− rows =
2554− template.rows
2555− |> List.map toGridLength
2556− |> String.join " "
2557− |> (\x -> "grid-template-rows: " ++ x ++ ";")
2558−
2559− gapX =
2560− "grid-column-gap:" ++ toGridLength (Tuple.first template.spacing) ++ ";"
2561−
2562− gapY =
2563− "grid-row-gap:" ++ toGridLength (Tuple.second template.spacing) ++ ";"
2564−
2565− modernGrid =
2566− class ++ "{" ++ columns ++ rows ++ gapX ++ gapY ++ "}"
2567−
2568− supports =
2569− "@supports (display:grid) {" ++ modernGrid ++ "}"
2570− in
2571− base ++ supports
2781+ any =
2782+ "." ++ Internal.Style.classes.any
25722783
2573− GridPosition position ->
2574− let
2575− class =
2576− ".grid-pos-"
2577− ++ String.fromInt position.row
2578− ++ "-"
2579− ++ String.fromInt position.col
2580− ++ "-"
2581− ++ String.fromInt position.width
2582− ++ "-"
2583− ++ String.fromInt position.height
2584−
2585− msPosition =
2586− String.join " "
2587− [ "-ms-grid-row: "
2588− ++ String.fromInt position.row
2589− ++ ";"
2590− , "-ms-grid-row-span: "
2591− ++ String.fromInt position.height
2592− ++ ";"
2593− , "-ms-grid-column: "
2594− ++ String.fromInt position.col
2595− ++ ";"
2596− , "-ms-grid-column-span: "
2597− ++ String.fromInt position.width
2598− ++ ";"
2599− ]
2600−
2601− base =
2602− class ++ "{" ++ msPosition ++ "}"
2603−
2604− modernPosition =
2605− String.join " "
2606− [ "grid-row: "
2607− ++ String.fromInt position.row
2608− ++ " / "
2609− ++ String.fromInt (position.row + position.height)
2610− ++ ";"
2611− , "grid-column: "
2612− ++ String.fromInt position.col
2613− ++ " / "
2614− ++ String.fromInt (position.col + position.width)
2615− ++ ";"
2616− ]
2617−
2618− modernGrid =
2619− class ++ "{" ++ modernPosition ++ "}"
2620−
2621− supports =
2622− "@supports (display:grid) {" ++ modernGrid ++ "}"
2623− in
2624− 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+ ]
26252798
2626− PseudoSelector class styles ->
2627− let
2628− renderPseudoRule style =
2629− renderStyleRule style (Just class)
2630− in
2631− List.map renderPseudoRule styles
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+ ]
2819+
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
26322976 |> String.join " "
2977+ |> (\x -> "grid-template-columns: " ++ x ++ ";")
26332978
2634− Transform transform ->
2635− let
2636− val =
2637− transformValue transform
2979+ rows =
2980+ template.rows
2981+ |> List.map toGridLength
2982+ |> String.join " "
2983+ |> (\x -> "grid-template-rows: " ++ x ++ ";")
26382984
2639− class =
2640− transformClass transform
2641− in
2642− case ( class, val ) of
2643− ( Just cls, Just v ) ->
2644− renderStyle
2645− maybePseudo
2646− ("." ++ cls)
2647− [ Property "transform"
2648− v
2649− ]
2985+ gapX =
2986+ "grid-column-gap:" ++ toGridLength (Tuple.first template.spacing) ++ ";"
26502987
2651− _ ->
2652− ""
2988+ gapY =
2989+ "grid-row-gap:" ++ toGridLength (Tuple.second template.spacing) ++ ";"
26532990
2654− combine style rendered =
2655− { rendered
2656− | rules = rendered.rules ++ renderStyleRule style Nothing
2657− , topLevel =
2658− case renderTopLevels style of
2659− Nothing ->
2660− rendered.topLevel
2991+ modernGrid =
2992+ class ++ "{" ++ columns ++ rows ++ gapX ++ gapY ++ "}"
26612993
2662− Just topLevel ->
2663− rendered.topLevel ++ topLevel
2664− }
2665− in
2666− case List.foldl combine { rules = "", topLevel = "" } stylesheet of
2667− { topLevel, rules } ->
2668− 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+ []
26693082
26703083
26713084lengthClassName : Length -> String
@@ -2705,12 +3118,12 @@ formatTextShadow shadow =
27053118 ]
27063119
27073120
2708−textShadowName shadow =
3121+textShadowClass shadow =
27093122 String.concat
27103123 [ "txt"
2711− , String.fromFloat (Tuple.first shadow.offset) ++ "px"
2712− , String.fromFloat (Tuple.second shadow.offset) ++ "px"
2713− , String.fromFloat shadow.blur ++ "px"
3124+ , floatClass (Tuple.first shadow.offset) ++ "px"
3125+ , floatClass (Tuple.second shadow.offset) ++ "px"
3126+ , floatClass shadow.blur ++ "px"
27143127 , formatColorClass shadow.color
27153128 ]
27163129
@@ -2731,17 +3144,17 @@ formatBoxShadow shadow =
27313144 ]
27323145
27333146
2734−boxShadowName shadow =
3147+boxShadowClass shadow =
27353148 String.concat <|
27363149 [ if shadow.inset then
27373150 "box-inset"
27383151
27393152 else
27403153 "box-"
2741− , String.fromFloat (Tuple.first shadow.offset) ++ "px"
2742− , String.fromFloat (Tuple.second shadow.offset) ++ "px"
2743− , String.fromFloat shadow.blur ++ "px"
2744− , 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"
27453158 , formatColorClass shadow.color
27463159 ]
27473160
@@ -2786,6 +3199,17 @@ paddingName top right bottom left =
27863199 ++ String.fromInt left
27873200
27883201
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+
27893213getStyleName : Style -> String
27903214getStyleName style =
27913215 case style of
@@ -3051,3 +3475,76 @@ onlyStyles attr =
30513475
30523476 _ ->
30533477 Nothing
3478+
3479+
3480+
3481+{- Font Adjustments -}
3482+
3483+
3484+convertAdjustment adjustment =
3485+ let
3486+ lineHeight =
3487+ 1.5
3488+
3489+ base =
3490+ lineHeight
3491+
3492+ normalDescender =
3493+ (lineHeight - 1)
3494+ / 2
3495+
3496+ oldMiddle =
3497+ lineHeight / 2
3498+
3499+ newCapitalMiddle =
3500+ ((ascender - newBaseline) / 2) + newBaseline
3501+
3502+ newFullMiddle =
3503+ ((ascender - descender) / 2) + descender
3504+
3505+ lines =
3506+ [ adjustment.capital
3507+ , adjustment.baseline
3508+ , adjustment.descender
3509+ , adjustment.lowercase
3510+ ]
3511+
3512+ ascender =
3513+ Maybe.withDefault adjustment.capital (List.maximum lines)
3514+
3515+ descender =
3516+ Maybe.withDefault adjustment.descender (List.minimum lines)
3517+
3518+ newBaseline =
3519+ lines
3520+ |> List.filter (\x -> x /= descender)
3521+ |> List.minimum
3522+ |> Maybe.withDefault adjustment.baseline
3523+
3524+ capitalVertical =
3525+ 1 - ascender
3526+
3527+ capitalSize =
3528+ 1 / (ascender - newBaseline)
3529+
3530+ fullSize =
3531+ 1 / (ascender - descender)
3532+
3533+ fullVertical =
3534+ 1 - ascender
3535+
3536+ -- (oldMiddle - newFullMiddle) * 2
3537+ in
3538+ { full =
3539+ adjust fullSize (ascender - descender) fullVertical
3540+ , capital =
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
3550+ }