@@ -16,6 +16,7 @@ module Internal.Model exposing
1616 , LayoutContext(..)
1717 , Length(..)
1818 , Location(..)
19+ , NearbyChildren(..)
1920 , NodeName(..)
2021 , Option(..)
2122 , OptionRecord
@@ -41,7 +42,7 @@ module Internal.Model exposing
4142 , asParagraph
4243 , asRow
4344 , asTextColumn
44− , boxShadowName
45+ , boxShadowClass
4546 , columnClass
4647 , composeTransformation
4748 , contextClasses
@@ -78,31 +79,30 @@ module Internal.Model exposing
7879 , onlyStyles
7980 , optionsToRecord
8081 , paddingName
82+ , paddingNameFloat
8183 , pageClass
8284 , paragraphClass
8385 , reduceRecursive
8486 , reduceStyles
8587 , reduceStylesRecursive
8688 , removeNever
87− , renderFocusStyle
88− -- , renderFont
89−
9089 , renderFontClassName
9190 , renderHeight
9291 , renderRoot
92+ , renderVariant
9393 , renderWidth
9494 , rootStyle
9595 , rowClass
9696 , singleClass
9797 , spacingName
98− , staticRoot
9998 , tag
100− , textShadowName
99+ , textShadowClass
101100 , toHtml
102101 , toStyleSheet
103102 , transformClass
104103 , unstyled
105104 , unwrapDecorations
105+ , variantName
106106 )
107107
108108{-| -}
@@ -112,7 +112,7 @@ import Html.Attributes
112112import Html.Keyed
113113import Internal.Flag as Flag exposing (Flag)
114114import Internal.Style exposing (classes, dot)
115−import Json.Encode as Json
115+import Json.Encode as Encode
116116import Set exposing (Set)
117117import VirtualDom
118118
@@ -174,7 +174,7 @@ type Style
174174 | Colored String String Color
175175 | SpacingStyle String Int Int
176176 | BorderWidth String Int Int Int Int
177− | PaddingStyle String Int Int Int Int
177+ | PaddingStyle String Float Float Float Float
178178 | GridTemplateStyle
179179 { spacing : ( Length, Length )
180180 , columns : List Length
@@ -222,8 +222,7 @@ type Font
222222 | ImportFont String String
223223 | FontWith
224224 { name : String
225− , url : Maybe String
226− , adjustment : Adjustment
225+ , adjustment : Maybe Adjustment
227226 , variants : List Variant
228227 }
229228
@@ -246,6 +245,18 @@ renderVariant var =
246245 "\"" ++ name ++ "\" " ++ String.fromInt index
247246
248247
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+
249260renderVariants typeface =
250261 case typeface of
251262 FontWith font ->
@@ -361,6 +372,13 @@ type NodeName
361372 | Embedded String String
362373
363374
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+
364382div =
365383 Generic
366384
@@ -369,7 +387,7 @@ type alias Gathered msg =
369387 { node : NodeName
370388 , attributes : List (VirtualDom.Attribute msg)
371389 , styles : List Style
372− , children : List (VirtualDom.Node msg)
390+ , children : NearbyChildren msg
373391 , has : Flag.Field
374392 }
375393
@@ -437,7 +455,10 @@ finalizeNode has node attributes children embedMode parentContext =
437455 Embedded nodeName internal ->
438456 VirtualDom.node nodeName
439457 attributes
440− [ createNode internal [ Html.Attributes.class (classes.any ++ " " ++ classes.single) ]
458+ [ createNode internal
459+ [ Html.Attributes.class
460+ (classes.any ++ " " ++ classes.single)
461+ ]
441462 ]
442463 in
443464 case parentContext of
@@ -514,49 +535,45 @@ finalizeNode has node attributes children embedMode parentContext =
514535
515536
516537embedWith 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
517547 if static then
518− staticRoot
519− :: (styles
520− |> List.foldl reduceStyles ( Set.empty, [ renderFocusStyle opts.focus ] )
521− |> Tuple.second
522− -- |> reduceStylesRecursive Set.empty [ ]) --renderFocusStyle opts.focus ]
523− -- |> sortedReduce
524− |> toStyleSheet opts
525− )
548+ staticRoot opts
549+ :: dynamicStyleSheet
526550 :: children
527551
528552 else
529− (styles
530− |> List.foldl reduceStyles ( Set.empty, [ renderFocusStyle opts.focus ] )
531− |> Tuple.second
532− -- |> reduceStylesRecursive Set.empty [ ]) --renderFocusStyle opts.focus ]
533− -- |> sortedReduce
534− |> toStyleSheet opts
535− )
553+ dynamicStyleSheet
536554 :: children
537555
538556
539557embedKeyed 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
540567 if static then
541− ( "static-stylesheet", staticRoot )
568+ ( "static-stylesheet", staticRoot opts )
542569 :: ( "dynamic-stylesheet"
543− , styles
544− |> List.foldl reduceStyles ( Set.empty, [ renderFocusStyle opts.focus ] )
545− |> Tuple.second
546− -- |> reduceStylesRecursive Set.empty [ ]) --renderFocusStyle opts.focus ]
547− -- |> sortedReduce
548− |> toStyleSheet opts
570+ , dynamicStyleSheet
549571 )
550572 :: children
551573
552574 else
553575 ( "dynamic-stylesheet"
554− , styles
555− |> List.foldl reduceStyles ( Set.empty, [ renderFocusStyle opts.focus ] )
556− |> Tuple.second
557− -- |> reduceStylesRecursive Set.empty [ ]) --renderFocusStyle opts.focus ]
558− -- |> sortedReduce
559− |> toStyleSheet opts
576+ , dynamicStyleSheet
560577 )
561578 :: children
562579
@@ -872,7 +889,16 @@ skippable flag style =
872889 False
873890
874891
875−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
876902gatherAttrRecursive classes node has transform styles attrs children elementAttrs =
877903 case elementAttrs of
878904 [] ->
@@ -1006,7 +1032,7 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
10061032 in
10071033 gatherAttrRecursive (classes ++ " " ++ newClass)
10081034 node
1009− (Flag.merge addToFlags has)
1035+ (Flag.merge addToFlags (Flag.add Flag.width has))
10101036 transform
10111037 (newStyles ++ styles)
10121038 attrs
@@ -1027,7 +1053,7 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
10271053 name =
10281054 "height-px-" ++ val
10291055 in
1030− gatherAttrRecursive (name ++ " " ++ classes)
1056+ gatherAttrRecursive (Internal.Style.classes.heightExact ++ " " ++ name ++ " " ++ classes)
10311057 node
10321058 (Flag.add Flag.height has)
10331059 transform
@@ -1084,7 +1110,7 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
10841110 in
10851111 gatherAttrRecursive (classes ++ " " ++ newClass)
10861112 node
1087− (Flag.merge addToFlags has)
1113+ (Flag.merge addToFlags (Flag.add Flag.height has))
10881114 transform
10891115 (newStyles ++ styles)
10901116 attrs
@@ -1116,20 +1142,15 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
11161142 gatherAttrRecursive classes (addNodeName "h6" node) has transform styles attrs children remaining
11171143
11181144 Paragraph ->
1119− let
1120− newNode =
1121− case node of
1122− Generic ->
1123− NodeName "p"
1124−
1125− NodeName name ->
1126− NodeName name
1127−
1128− Embedded x y ->
1129− Embedded x y
1130− in
1131− gatherAttrRecursive classes
1132− 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
11331154 has
11341155 transform
11351156 styles
@@ -1164,75 +1185,16 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
11641185
11651186 Styled styled ->
11661187 styles ++ styled.styles
1167−
1168− nearbyElement =
1169− Html.div
1170− [ Html.Attributes.class <|
1171− case location of
1172− Above ->
1173− String.join " "
1174− [ Internal.Style.classes.nearby
1175− , Internal.Style.classes.single
1176− , Internal.Style.classes.above
1177− ]
1178−
1179− Below ->
1180− String.join " "
1181− [ Internal.Style.classes.nearby
1182− , Internal.Style.classes.single
1183− , Internal.Style.classes.below
1184− ]
1185−
1186− OnRight ->
1187− String.join " "
1188− [ Internal.Style.classes.nearby
1189− , Internal.Style.classes.single
1190− , Internal.Style.classes.onRight
1191− ]
1192−
1193− OnLeft ->
1194− String.join " "
1195− [ Internal.Style.classes.nearby
1196− , Internal.Style.classes.single
1197− , Internal.Style.classes.onLeft
1198− ]
1199−
1200− InFront ->
1201− String.join " "
1202− [ Internal.Style.classes.nearby
1203− , Internal.Style.classes.single
1204− , Internal.Style.classes.inFront
1205− ]
1206−
1207− Behind ->
1208− String.join " "
1209− [ Internal.Style.classes.nearby
1210− , Internal.Style.classes.single
1211− , Internal.Style.classes.behind
1212− ]
1213− ]
1214− [ case elem of
1215− Empty ->
1216− VirtualDom.text ""
1217−
1218− Text str ->
1219− textElement str
1220−
1221− Unstyled html ->
1222− html asEl
1223−
1224− Styled styled ->
1225− styled.html NoStyleSheet asEl
1226− ]
1227−
1228− newClasses =
1229− if location == Behind then
1230− Internal.Style.classes.hasBehind ++ " " ++ classes
1231−
1232− else
1233− classes
12341188 in
1235− 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
12361198
12371199 AlignX x ->
12381200 if Flag.present Flag.xAlign has then
@@ -1288,6 +1250,106 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
12881250 remaining
12891251
12901252
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+
12911353renderWidth w =
12921354 case w of
12931355 Px px ->
@@ -1374,7 +1436,7 @@ renderHeight h =
13741436 "height-px-" ++ val
13751437 in
13761438 ( Flag.none
1377− , name
1439+ , Internal.Style.classes.heightExact ++ " " ++ name
13781440 , [ Single name "height" (val ++ "px") ]
13791441 )
13801442
@@ -1397,7 +1459,7 @@ renderHeight h =
13971459 , [ Single
13981460 (Internal.Style.classes.any
13991461 ++ "."
1400− ++ Internal.Style.classes.row
1462+ ++ Internal.Style.classes.column
14011463 ++ " > "
14021464 ++ (Internal.Style.dot <| "height-fill-" ++ String.fromInt portion)
14031465 )
@@ -1416,7 +1478,9 @@ renderHeight h =
14161478 Single
14171479 cls
14181480 "min-height"
1419− (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")
14201484
14211485 ( newFlag, newAttrs, newStyle ) =
14221486 renderHeight len
@@ -1494,7 +1558,7 @@ element : LayoutContext -> NodeName -> List (Attribute aligned msg) -> Children
14941558element context node attributes children =
14951559 attributes
14961560 |> List.reverse
1497− |> gatherAttrRecursive (contextClasses context) node Flag.none untransformed [] [] []
1561+ |> gatherAttrRecursive (contextClasses context) node Flag.none untransformed [] [] NoNearbyChildren
14981562 |> createElement context children
14991563
15001564
@@ -1657,13 +1721,8 @@ createElement context children rendered =
16571721 (finalizeNode rendered.has
16581722 rendered.node
16591723 rendered.attributes
1660− (Keyed <|
1661− keyed
1662− ++ List.map
1663− (\x ->
1664− ( "nearby-elements-pls", x )
1665− )
1666− rendered.children
1724+ (Keyed
1725+ (addKeyedChildren "nearby-element-pls" keyed rendered.children)
16671726 )
16681727 NoStyleSheet
16691728 )
@@ -1677,13 +1736,7 @@ createElement context children rendered =
16771736 rendered.node
16781737 rendered.attributes
16791738 (Keyed
1680− (keyed
1681− ++ List.map
1682− (\x ->
1683− ( "nearby-elements-pls", x )
1684− )
1685− rendered.children
1686− )
1739+ (addKeyedChildren "nearby-element-pls" keyed rendered.children)
16871740 )
16881741 }
16891742
@@ -1705,7 +1758,7 @@ createElement context children rendered =
17051758 rendered.has
17061759 rendered.node
17071760 rendered.attributes
1708− (Unkeyed <| unkeyed ++ rendered.children)
1761+ (Unkeyed (addChildren unkeyed rendered.children))
17091762 NoStyleSheet
17101763 )
17111764
@@ -1717,10 +1770,42 @@ createElement context children rendered =
17171770 rendered.has
17181771 rendered.node
17191772 rendered.attributes
1720− (Unkeyed (unkeyed ++ rendered.children))
1773+ (Unkeyed (addChildren unkeyed rendered.children))
17211774 }
17221775
17231776
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+
17241809unit =
17251810 0
17261811
@@ -1732,8 +1817,20 @@ defaultOptions =
17321817 }
17331818
17341819
1735−staticRoot =
1736− 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) ] []
17371834
17381835
17391836addWhen ifThis x to =
@@ -1851,7 +1948,7 @@ type Spacing
18511948
18521949
18531950type Padding
1854− = Padding String Int Int Int Int
1951+ = Padding String Float Float Float Float
18551952
18561953
18571954extractSpacingAndPadding : List (Attribute aligned msg) -> ( Maybe Padding, Maybe Spacing )
@@ -1947,34 +2044,44 @@ getHeight attrs =
19472044 Nothing
19482045
19492046
2047+textElementClasses : String
2048+textElementClasses =
2049+ classes.any
2050+ ++ " "
2051+ ++ classes.text
2052+ ++ " "
2053+ ++ classes.widthContent
2054+ ++ " "
2055+ ++ classes.heightContent
2056+
2057+
19502058textElement : String -> VirtualDom.Node msg
19512059textElement str =
19522060 Html.div
19532061 [ Html.Attributes.class
1954− (String.join " "
1955− [ classes.any
1956− , classes.text
1957− , classes.widthContent
1958− , classes.heightContent
1959− ]
1960− )
2062+ textElementClasses
19612063 ]
19622064 [ Html.text str ]
19632065
19642066
2067+textElementFillClasses : String
2068+textElementFillClasses =
2069+ classes.any
2070+ ++ " "
2071+ ++ classes.text
2072+ ++ " "
2073+ ++ classes.widthFill
2074+ ++ " "
2075+ ++ classes.heightFill
2076+
2077+
19652078textElementFill : String -> VirtualDom.Node msg
19662079textElementFill str =
1967− VirtualDom.node "div"
2080+ Html.div
19682081 [ Html.Attributes.class
1969− (String.join " "
1970− [ classes.any
1971− , classes.text
1972− , classes.widthFill
1973− , classes.heightFill
1974− ]
1975− )
2082+ textElementFillClasses
19762083 ]
1977− [ VirtualDom.text str ]
2084+ [ Html.text str ]
19782085
19792086
19802087type Children x
@@ -1982,10 +2089,6 @@ type Children x
19822089 | Keyed (List ( String, x ))
19832090
19842091
1985−
1986−-- toHtml : OptionRecord -> Element msg -> VirtualDom.Node msg
1987−
1988−
19892092toHtml mode el =
19902093 case el of
19912094 Unstyled html ->
@@ -2021,8 +2124,7 @@ renderRoot optionList attributes child =
20212124
20222125
20232126type RenderMode
2024− = Viewport
2025− | Layout
2127+ = Layout
20262128 | NoStaticStyleSheet
20272129 | WithVirtualCss
20282130
@@ -2071,8 +2173,8 @@ rootStyle =
20712173 , SansSerif
20722174 ]
20732175 in
2074− [ StyleClass Flag.bgColor (Colored ("bg-color-" ++ formatColorClass (Rgba 1 1 1 0)) "background-color" (Rgba 1 1 1 0))
2075− , 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))
20762178 , StyleClass Flag.fontSize (FontSize 20)
20772179 , StyleClass Flag.fontFamily <|
20782180 FontFamily (List.foldl renderFontClassName "font-" families)
@@ -2115,9 +2217,38 @@ renderFontClassName font current =
21152217
21162218renderFocusStyle :
21172219 FocusStyle
2118− -> Style
2220+ -> List Style
21192221renderFocusStyle focus =
2120− 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+ )
21212252 (List.filterMap identity
21222253 [ Maybe.map (\color -> Property "border-color" (formatColor color)) focus.borderColor
21232254 , Maybe.map (\color -> Property "background-color" (formatColor color)) focus.backgroundColor
@@ -2140,6 +2271,7 @@ renderFocusStyle focus =
21402271 , Just <| Property "outline" "none"
21412272 ]
21422273 )
2274+ ]
21432275
21442276
21452277focusDefaultStyle : { backgroundColor : Maybe Color, borderColor : Maybe Color, shadow : Maybe Shadow }
@@ -2151,7 +2283,7 @@ focusDefaultStyle =
21512283 { color =
21522284 Rgba (155 / 255) (203 / 255) 1 1
21532285 , offset = ( 0, 0 )
2154− , blur = 3
2286+ , blur = 0
21552287 , size = 3
21562288 }
21572289 }
@@ -2221,7 +2353,31 @@ optionsToRecord options =
22212353
22222354toStyleSheet : OptionRecord -> List Style -> VirtualDom.Node msg
22232355toStyleSheet options styleSheet =
2224− VirtualDom.node "style" [] [ VirtualDom.text (toStyleSheetString options styleSheet) ]
2356+ case options.mode of
2357+ Layout ->
2358+ -- wrap the style node in a div to prevent `Dark Reader` from blowin up the dom.
2359+ VirtualDom.node "div"
2360+ []
2361+ [ VirtualDom.node "style"
2362+ []
2363+ [ VirtualDom.text (toStyleSheetString options styleSheet) ]
2364+ ]
2365+
2366+ NoStaticStyleSheet ->
2367+ -- wrap the style node in a div to prevent `Dark Reader` from blowin up the dom.
2368+ VirtualDom.node "div"
2369+ []
2370+ [ VirtualDom.node "style"
2371+ []
2372+ [ VirtualDom.text (toStyleSheetString options styleSheet) ]
2373+ ]
2374+
2375+ WithVirtualCss ->
2376+ VirtualDom.node "elm-ui-rules"
2377+ [ VirtualDom.property "rules"
2378+ (encodeStyles options styleSheet)
2379+ ]
2380+ []
22252381
22262382
22272383renderTopLevelValues rules =
@@ -2231,14 +2387,12 @@ renderTopLevelValues rules =
22312387 ImportFont _ url ->
22322388 Just ("@import url('" ++ url ++ "');")
22332389
2234− FontWith with ->
2235− case with.url of
2236− Just x ->
2237− Just ("@import url('" ++ x ++ "');")
2238−
2239− Nothing ->
2240− Nothing
2241−
2390+ -- FontWith with ->
2391+ -- case with.url of
2392+ -- Just x ->
2393+ -- Just ("@import url('" ++ x ++ "');")
2394+ -- Nothing ->
2395+ -- Nothing
22422396 _ ->
22432397 Nothing
22442398
@@ -2379,12 +2533,17 @@ typefaceAdjustment typefaces =
23792533 Nothing ->
23802534 case face of
23812535 FontWith with ->
2382− Just
2383− ( fontAdjustmentRules
2384− (.full (convertAdjustment with.adjustment))
2385− , fontAdjustmentRules
2386− (.capital (convertAdjustment with.adjustment))
2387− )
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+ )
23882547
23892548 _ ->
23902549 found
@@ -2434,489 +2593,492 @@ renderProps force (Property key val) existing =
24342593 existing ++ "\n " ++ key ++ ": " ++ val ++ ";"
24352594
24362595
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+
24372609toStyleSheetString : OptionRecord -> List Style -> String
24382610toStyleSheetString options stylesheet =
24392611 let
2440− renderStyle maybePseudo selector props =
2441− case maybePseudo of
2442− Nothing ->
2443− selector ++ "{" ++ List.foldl (renderProps False) "" props ++ "\n}"
2444−
2445− Just pseudo ->
2446− case pseudo of
2447− Hover ->
2448− case options.hover of
2449− NoHover ->
2450− ""
2612+ combine style rendered =
2613+ { rules = rendered.rules ++ renderStyleRule options style Nothing
2614+ , topLevel =
2615+ case topLevelValue style of
2616+ Nothing ->
2617+ rendered.topLevel
24512618
2452− ForceHover ->
2453− 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
24542626
2455− AllowHover ->
2456− selector ++ "-hv:hover {" ++ List.foldl (renderProps False) "" props ++ "\n}"
24572627
2458− Focus ->
2459− let
2460− renderedProps =
2461− List.foldl (renderProps False) "" props
2462− in
2463− String.join "\n"
2464− [ selector
2465− ++ "-fs:focus {"
2466− ++ renderedProps
2467− ++ "\n}"
2468− , "."
2469− ++ classes.any
2470− ++ ":focus ~ "
2471− ++ selector
2472− ++ "-fs:not(.focus) {"
2473− ++ renderedProps
2474− ++ "\n}"
2475− , "."
2476− ++ classes.any
2477− ++ ":focus "
2478− ++ selector
2479− ++ "-fs {"
2480− ++ renderedProps
2481− ++ "\n}"
2482− , ".focusable-parent:focus ~ "
2483− ++ "."
2484− ++ classes.any
2485− ++ " "
2486− ++ selector
2487− ++ "-fs {"
2488− ++ renderedProps
2489− ++ "\n}"
2490− ]
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}" ]
24912633
2492− Active ->
2493− 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+ []
24942640
2495− renderStyleRule rule maybePseudo =
2496− case rule of
2497− Style selector props ->
2498− renderStyle maybePseudo selector props
2641+ ForceHover ->
2642+ [ selector ++ "-hv {" ++ List.foldl (renderProps True) "" props ++ "\n}" ]
24992643
2500− Shadows name prop ->
2501− renderStyle
2502− maybePseudo
2503− ("." ++ name)
2504− [ Property "box-shadow" prop
2505− ]
2644+ AllowHover ->
2645+ [ selector ++ "-hv:hover {" ++ List.foldl (renderProps False) "" props ++ "\n}" ]
25062646
2507− Transparency name transparency ->
2647+ Focus ->
25082648 let
2509− opacity =
2510− (1 - transparency)
2511− |> min 1
2512− |> max 0
2649+ renderedProps =
2650+ List.foldl (renderProps False) "" props
25132651 in
2514− renderStyle
2515− maybePseudo
2516− ("." ++ name)
2517− [ Property "opacity" (String.fromFloat opacity)
2518− ]
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+ ]
25192663
2520− FontSize i ->
2521− renderStyle
2522− maybePseudo
2523− (".font-size-" ++ String.fromInt i)
2524− [ Property "font-size" (String.fromInt i ++ "px")
2525− ]
2664+ Active ->
2665+ [ selector ++ "-act:active {" ++ List.foldl (renderProps False) "" props ++ "\n}" ]
25262666
2527− FontFamily name typefaces ->
2528− let
2529− features =
2530− typefaces
2531− |> List.filterMap renderVariants
2532− |> String.join ", "
2533−
2534− families =
2535− [ Property "font-family"
2536− (typefaces
2537− |> List.map fontName
2538− |> String.join ", "
2539− )
2540− , Property "font-feature-settings" features
2541− , Property "font-variant"
2542− (if List.any hasSmallCaps typefaces then
2543− "small-caps"
25442667
2545− else
2546− "normal"
2547− )
2548− ]
2549− in
2550− String.join " "
2551− [ renderStyle
2552− maybePseudo
2553− ("." ++ name)
2554− families
2555− ]
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+ ]
25562680
2557− Single class prop val ->
2558− renderStyle
2559− maybePseudo
2560− ("." ++ class)
2561− [ Property prop val
2562− ]
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+ ]
25632693
2564− Colored class prop color ->
2565− renderStyle
2566− maybePseudo
2567− ("." ++ class)
2568− [ Property prop (formatColor color)
2569− ]
2694+ FontSize i ->
2695+ renderStyle options
2696+ maybePseudo
2697+ (".font-size-" ++ String.fromInt i)
2698+ [ Property "font-size" (String.fromInt i ++ "px")
2699+ ]
25702700
2571− SpacingStyle cls x y ->
2572− let
2573− class =
2574− "." ++ cls
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"
25752718
2576− halfX =
2577− String.fromFloat (toFloat x / 2) ++ "px"
2719+ else
2720+ "normal"
2721+ )
2722+ ]
2723+ in
2724+ renderStyle options
2725+ maybePseudo
2726+ ("." ++ name)
2727+ families
25782728
2579− halfY =
2580− String.fromFloat (toFloat y / 2) ++ "px"
2729+ Single class prop val ->
2730+ renderStyle options
2731+ maybePseudo
2732+ ("." ++ class)
2733+ [ Property prop val
2734+ ]
25812735
2582− xPx =
2583− String.fromInt x ++ "px"
2736+ Colored class prop color ->
2737+ renderStyle options
2738+ maybePseudo
2739+ ("." ++ class)
2740+ [ Property prop (formatColor color)
2741+ ]
25842742
2585− yPx =
2586− String.fromInt y ++ "px"
2743+ SpacingStyle cls x y ->
2744+ let
2745+ class =
2746+ "." ++ cls
25872747
2588− row =
2589− "." ++ Internal.Style.classes.row
2748+ halfX =
2749+ String.fromFloat (toFloat x / 2) ++ "px"
25902750
2591− wrappedRow =
2592− "." ++ Internal.Style.classes.wrapped ++ row
2751+ halfY =
2752+ String.fromFloat (toFloat y / 2) ++ "px"
25932753
2594− column =
2595− "." ++ Internal.Style.classes.column
2754+ xPx =
2755+ String.fromInt x ++ "px"
25962756
2597− page =
2598− "." ++ Internal.Style.classes.page
2757+ yPx =
2758+ String.fromInt y ++ "px"
25992759
2600− paragraph =
2601− "." ++ Internal.Style.classes.paragraph
2760+ row =
2761+ "." ++ Internal.Style.classes.row
26022762
2603− left =
2604− "." ++ Internal.Style.classes.alignLeft
2763+ wrappedRow =
2764+ "." ++ Internal.Style.classes.wrapped ++ row
26052765
2606− right =
2607− "." ++ Internal.Style.classes.alignRight
2766+ column =
2767+ "." ++ Internal.Style.classes.column
26082768
2609− any =
2610− "." ++ Internal.Style.classes.any
2769+ page =
2770+ "." ++ Internal.Style.classes.page
26112771
2612− single =
2613− "." ++ Internal.Style.classes.single
2614− in
2615− String.concat
2616− [ renderStyle maybePseudo (class ++ row ++ " > " ++ any ++ " + " ++ any) [ Property "margin-left" xPx ]
2617−
2618− -- margins don't apply to last element of normal, unwrapped rows
2619− -- , renderStyle maybePseudo (class ++ row ++ " > " ++ any ++ ":first-child") [ Property "margin" "0" ]
2620− -- For wrapped rows, margins always apply because we handle "canceling out" the other margins manually in the element.
2621− , renderStyle maybePseudo
2622− (class ++ wrappedRow ++ " > " ++ any)
2623− [ Property "margin" (halfY ++ " " ++ halfX)
2624− ]
2772+ paragraph =
2773+ "." ++ Internal.Style.classes.paragraph
26252774
2626− -- , renderStyle maybePseudo
2627− -- (class ++ wrappedRow ++ " > " ++ any ++ ":last-child")
2628− -- [ Property "margin-right" "0"
2629− -- ]
2630− -- columns
2631− , renderStyle maybePseudo (class ++ column ++ " > " ++ any ++ " + " ++ any) [ Property "margin-top" yPx ]
2632− , renderStyle maybePseudo (class ++ page ++ " > " ++ any ++ " + " ++ any) [ Property "margin-top" yPx ]
2633− , renderStyle maybePseudo (class ++ page ++ " > " ++ left) [ Property "margin-right" xPx ]
2634− , renderStyle maybePseudo (class ++ page ++ " > " ++ right) [ Property "margin-left" xPx ]
2635− , renderStyle
2636− maybePseudo
2637− (class ++ paragraph)
2638− [ Property "line-height" ("calc(1em + " ++ String.fromInt y ++ "px)")
2639− ]
2640− , renderStyle
2641− maybePseudo
2642− ("textarea" ++ class)
2643− [ Property "line-height" ("calc(1em + " ++ String.fromInt y ++ "px)")
2644− ]
2775+ left =
2776+ "." ++ Internal.Style.classes.alignLeft
26452777
2646− -- , renderStyle
2647− -- maybePseudo
2648− -- (class ++ paragraph ++ " > " ++ any)
2649− -- [ Property "margin-right" xPx
2650− -- , Property "margin-bottom" yPx
2651− -- ]
2652− , renderStyle
2653− maybePseudo
2654− (class ++ paragraph ++ " > " ++ left)
2655− [ Property "margin-right" xPx
2656− ]
2657− , renderStyle
2658− maybePseudo
2659− (class ++ paragraph ++ " > " ++ right)
2660− [ Property "margin-left" xPx
2661− ]
2662− , renderStyle
2663− maybePseudo
2664− (class ++ paragraph ++ "::after")
2665− [ Property "content" "''"
2666− , Property "display" "block"
2667− , Property "height" "0"
2668− , Property "width" "0"
2669− , Property "margin-top" (String.fromInt (-1 * (y // 2)) ++ "px")
2670− ]
2671− , renderStyle
2672− maybePseudo
2673− (class ++ paragraph ++ "::before")
2674− [ Property "content" "''"
2675− , Property "display" "block"
2676− , Property "height" "0"
2677− , Property "width" "0"
2678− , Property "margin-bottom" (String.fromInt (-1 * (y // 2)) ++ "px")
2679− ]
2680− ]
2778+ right =
2779+ "." ++ Internal.Style.classes.alignRight
26812780
2682− PaddingStyle cls top right bottom left ->
2683− let
2684− class =
2685− "."
2686− ++ cls
2687− in
2688− renderStyle
2689− maybePseudo
2690− class
2691− [ Property "padding"
2692− (String.fromInt top
2693− ++ "px "
2694− ++ String.fromInt right
2695− ++ "px "
2696− ++ String.fromInt bottom
2697− ++ "px "
2698− ++ String.fromInt left
2699− ++ "px"
2700− )
2701− ]
2781+ any =
2782+ "." ++ Internal.Style.classes.any
27022783
2703− BorderWidth cls top right bottom left ->
2704− let
2705− class =
2706− "."
2707− ++ cls
2708− in
2709− renderStyle
2710− maybePseudo
2711− class
2712− [ Property "border-width"
2713− (String.fromInt top
2714− ++ "px "
2715− ++ String.fromInt right
2716− ++ "px "
2717− ++ String.fromInt bottom
2718− ++ "px "
2719− ++ String.fromInt left
2720− ++ "px"
2721− )
2722− ]
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+ ]
27232798
2724− GridTemplateStyle template ->
2725− let
2726− class =
2727− ".grid-rows-"
2728− ++ String.join "-" (List.map lengthClassName template.rows)
2729− ++ "-cols-"
2730− ++ String.join "-" (List.map lengthClassName template.columns)
2731− ++ "-space-x-"
2732− ++ lengthClassName (Tuple.first template.spacing)
2733− ++ "-space-y-"
2734− ++ lengthClassName (Tuple.second template.spacing)
2735−
2736− ySpacing =
2737− toGridLength (Tuple.second template.spacing)
2738−
2739− xSpacing =
2740− toGridLength (Tuple.first template.spacing)
2741−
2742− toGridLength x =
2743− toGridLengthHelper Nothing Nothing x
2744−
2745− toGridLengthHelper minimum maximum x =
2746− case x of
2747− Px px ->
2748− String.fromInt px ++ "px"
2749−
2750− Content ->
2751− case ( minimum, maximum ) of
2752− ( Nothing, Nothing ) ->
2753− "max-content"
2754−
2755− ( Just minSize, Nothing ) ->
2756− "minmax(" ++ String.fromInt minSize ++ "px, " ++ "max-content)"
2757−
2758− ( Nothing, Just maxSize ) ->
2759− "minmax(max-content, " ++ String.fromInt maxSize ++ "px)"
2760−
2761− ( Just minSize, Just maxSize ) ->
2762− "minmax(" ++ String.fromInt minSize ++ "px, " ++ String.fromInt maxSize ++ "px)"
2763−
2764− Fill i ->
2765− case ( minimum, maximum ) of
2766− ( Nothing, Nothing ) ->
2767− String.fromInt i ++ "fr"
2768−
2769− ( Just minSize, Nothing ) ->
2770− "minmax(" ++ String.fromInt minSize ++ "px, " ++ String.fromInt i ++ "fr" ++ "fr)"
2771−
2772− ( Nothing, Just maxSize ) ->
2773− "minmax(max-content, " ++ String.fromInt maxSize ++ "px)"
2774−
2775− ( Just minSize, Just maxSize ) ->
2776− "minmax(" ++ String.fromInt minSize ++ "px, " ++ String.fromInt maxSize ++ "px)"
2777−
2778− Min m len ->
2779− toGridLengthHelper (Just m) maximum len
2780−
2781− Max m len ->
2782− toGridLengthHelper minimum (Just m) len
2783−
2784− msColumns =
2785− template.columns
2786− |> List.map toGridLength
2787− |> String.join ySpacing
2788− |> (\x -> "-ms-grid-columns: " ++ x ++ ";")
2789−
2790− msRows =
2791− template.columns
2792− |> List.map toGridLength
2793− |> String.join ySpacing
2794− |> (\x -> "-ms-grid-rows: " ++ x ++ ";")
2795−
2796− base =
2797− class ++ "{" ++ msColumns ++ msRows ++ "}"
2798−
2799− columns =
2800− template.columns
2801− |> List.map toGridLength
2802− |> String.join " "
2803− |> (\x -> "grid-template-columns: " ++ x ++ ";")
2804−
2805− rows =
2806− template.rows
2807− |> List.map toGridLength
2808− |> String.join " "
2809− |> (\x -> "grid-template-rows: " ++ x ++ ";")
2810−
2811− gapX =
2812− "grid-column-gap:" ++ toGridLength (Tuple.first template.spacing) ++ ";"
2813−
2814− gapY =
2815− "grid-row-gap:" ++ toGridLength (Tuple.second template.spacing) ++ ";"
2816−
2817− modernGrid =
2818− class ++ "{" ++ columns ++ rows ++ gapX ++ gapY ++ "}"
2819−
2820− supports =
2821− "@supports (display:grid) {" ++ modernGrid ++ "}"
2822− in
2823− 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+ ]
28242819
2825− GridPosition position ->
2826− let
2827− class =
2828− ".grid-pos-"
2829− ++ String.fromInt position.row
2830− ++ "-"
2831− ++ String.fromInt position.col
2832− ++ "-"
2833− ++ String.fromInt position.width
2834− ++ "-"
2835− ++ String.fromInt position.height
2836−
2837− msPosition =
2838− String.join " "
2839− [ "-ms-grid-row: "
2840− ++ String.fromInt position.row
2841− ++ ";"
2842− , "-ms-grid-row-span: "
2843− ++ String.fromInt position.height
2844− ++ ";"
2845− , "-ms-grid-column: "
2846− ++ String.fromInt position.col
2847− ++ ";"
2848− , "-ms-grid-column-span: "
2849− ++ String.fromInt position.width
2850− ++ ";"
2851− ]
2852−
2853− base =
2854− class ++ "{" ++ msPosition ++ "}"
2855−
2856− modernPosition =
2857− String.join " "
2858− [ "grid-row: "
2859− ++ String.fromInt position.row
2860− ++ " / "
2861− ++ String.fromInt (position.row + position.height)
2862− ++ ";"
2863− , "grid-column: "
2864− ++ String.fromInt position.col
2865− ++ " / "
2866− ++ String.fromInt (position.col + position.width)
2867− ++ ";"
2868− ]
2869−
2870− modernGrid =
2871− class ++ "{" ++ modernPosition ++ "}"
2872−
2873− supports =
2874− "@supports (display:grid) {" ++ modernGrid ++ "}"
2875− in
2876− base ++ supports
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+ ]
28772855
2878− PseudoSelector class styles ->
2879− let
2880− renderPseudoRule style =
2881− renderStyleRule style (Just class)
2882− in
2883− List.map renderPseudoRule styles
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
28842976 |> String.join " "
2977+ |> (\x -> "grid-template-columns: " ++ x ++ ";")
28852978
2886− Transform transform ->
2887− let
2888− val =
2889− transformValue transform
2979+ rows =
2980+ template.rows
2981+ |> List.map toGridLength
2982+ |> String.join " "
2983+ |> (\x -> "grid-template-rows: " ++ x ++ ";")
28902984
2891− class =
2892− transformClass transform
2893− in
2894− case ( class, val ) of
2895− ( Just cls, Just v ) ->
2896− renderStyle
2897− maybePseudo
2898− ("." ++ cls)
2899− [ Property "transform"
2900− v
2901− ]
2985+ gapX =
2986+ "grid-column-gap:" ++ toGridLength (Tuple.first template.spacing) ++ ";"
29022987
2903− _ ->
2904− ""
2988+ gapY =
2989+ "grid-row-gap:" ++ toGridLength (Tuple.second template.spacing) ++ ";"
29052990
2906− combine style rendered =
2907− { rules = rendered.rules ++ renderStyleRule style Nothing
2908− , topLevel =
2909− case topLevelValue style of
2910− Nothing ->
2911− rendered.topLevel
2991+ modernGrid =
2992+ class ++ "{" ++ columns ++ rows ++ gapX ++ gapY ++ "}"
29122993
2913− Just topLevel ->
2914− topLevel :: rendered.topLevel
2915− }
2916− in
2917− case List.foldl combine { topLevel = [], rules = "" } stylesheet of
2918− { topLevel, rules } ->
2919− 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+ []
29203082
29213083
29223084lengthClassName : Length -> String
@@ -2956,12 +3118,12 @@ formatTextShadow shadow =
29563118 ]
29573119
29583120
2959−textShadowName shadow =
3121+textShadowClass shadow =
29603122 String.concat
29613123 [ "txt"
2962− , String.fromFloat (Tuple.first shadow.offset) ++ "px"
2963− , String.fromFloat (Tuple.second shadow.offset) ++ "px"
2964− , String.fromFloat shadow.blur ++ "px"
3124+ , floatClass (Tuple.first shadow.offset) ++ "px"
3125+ , floatClass (Tuple.second shadow.offset) ++ "px"
3126+ , floatClass shadow.blur ++ "px"
29653127 , formatColorClass shadow.color
29663128 ]
29673129
@@ -2982,17 +3144,17 @@ formatBoxShadow shadow =
29823144 ]
29833145
29843146
2985−boxShadowName shadow =
3147+boxShadowClass shadow =
29863148 String.concat <|
29873149 [ if shadow.inset then
29883150 "box-inset"
29893151
29903152 else
29913153 "box-"
2992− , String.fromFloat (Tuple.first shadow.offset) ++ "px"
2993− , String.fromFloat (Tuple.second shadow.offset) ++ "px"
2994− , String.fromFloat shadow.blur ++ "px"
2995− , 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"
29963158 , formatColorClass shadow.color
29973159 ]
29983160
@@ -3037,6 +3199,17 @@ paddingName top right bottom left =
30373199 ++ String.fromInt left
30383200
30393201
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+
30403213getStyleName : Style -> String
30413214getStyleName style =
30423215 case style of