git.iko.soy/typeable/elm-ui
on master help sign in
behindContent is rendered first, other nearbys, after.
775abeeMatthew Griffith
NOTES.mddeleted−10
@@ -1,10 +0,0 @@
1−# Rendering Order
2−
3−Nearby elements such as `below`, `above`, `behindContent`, and `inFront` are rendered after the other children of the `Element.
4−
5−This is so:
6−
7−- `inFront` doesn't need a special `z-index` to work. This can increase performance because too many `z-index` overrides means shipping more layers to the gpu.
8−- Nearby elements higher up in the DOM hierarchy will be on top of elements lower in the hierarchy. `inFront` on a higher element should be on top of `inFront` elements on a lower element.
9−- Allows nearby elements to be affected by `focused` for `Input`, because they can be reached by a sibling selector. `.focuesed:focus ~ .focusable-style {}`
10−
implementation/NEARBY.mdnew file+24
@@ -0,0 +1,24 @@
1+# Rendering Order
2+
3+Nearby elements such as `below`, `above`, and `inFront` are rendered after the other children of the `Element. `behindContent` is rendered before.
4+
5+This is so:
6+
7+- `inFront` doesn't need a special `z-index` to work. This can increase performance because too many `z-index` overrides means shipping more layers to the gpu.
8+- Nearby elements higher up in the DOM hierarchy will be on top of elements lower in the hierarchy. `inFront` on a higher element should be on top of `inFront` elements on a lower element.
9+- Allows nearby elements to be affected by `focused` for `Input`, because they can be reached by a sibling selector. `.focuesed:focus ~ .focusable-style {}`
10+
11+
12+
13+# Desired Behavior of Nearby Elements
14+
15+
16+
17+- `inFront` on an element will be in front of all children.
18+ - if there's an `inFront` attached to a child, it will be beneath the parent's `inFront`
19+- `behindContent`, likewise, will always be between the background and the element's children.
20+- `onLeft`, `onRight`, `above`, and `below` will be in front of any element they overlap with.
21+ - if an element has an `inFront` and it's neighbor has an `onLeft`, then the `onLeft` element will be on top of the `inFront`.
22+- if `onLeft`, `onRight`, `above`, and `below` on separate elements overlap, source order wins:
23+ - in a row, the one attached to the element farthest to the right wins.
24+ - in a column, the one attached to the element farthest down wins.
src/Internal/Model.elm+165−87
@@ -361,6 +361,13 @@ type NodeName
361 | Embedded String String
361 | Embedded String String
362
362
363
363
364+type NearbyChildren msg
365+ = NoNearbyChildren
366+ | ChildrenBehind (List (Html.Html msg))
367+ | ChildrenInFront (List (Html.Html msg))
368+ | ChildrenBehindAndInFront (List (Html.Html msg)) (List (Html.Html msg))
369+
370+
364div =
371div =
365 Generic
372 Generic
366
373
@@ -369,7 +376,7 @@ type alias Gathered msg =
369 { node : NodeName
376 { node : NodeName
370 , attributes : List (VirtualDom.Attribute msg)
377 , attributes : List (VirtualDom.Attribute msg)
371 , styles : List Style
378 , styles : List Style
372− , children : List (VirtualDom.Node msg)
379+ , children : NearbyChildren msg
373 , has : Flag.Field
380 , has : Flag.Field
374 }
381 }
375
382
@@ -872,7 +879,16 @@ skippable flag style =
872 False
879 False
873
880
874
881
875−gatherAttrRecursive : String -> NodeName -> Flag.Field -> Transformation -> List Style -> List (VirtualDom.Attribute msg) -> List (VirtualDom.Node msg) -> List (Attribute aligned msg) -> Gathered msg
882+gatherAttrRecursive :
883+ String
884+ -> NodeName
885+ -> Flag.Field
886+ -> Transformation
887+ -> List Style
888+ -> List (VirtualDom.Attribute msg)
889+ -> NearbyChildren msg
890+ -> List (Attribute aligned msg)
891+ -> Gathered msg
876gatherAttrRecursive classes node has transform styles attrs children elementAttrs =
892gatherAttrRecursive classes node has transform styles attrs children elementAttrs =
877 case elementAttrs of
893 case elementAttrs of
878 [] ->
894 [] ->
@@ -1164,75 +1180,16 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
1164
1180
1165 Styled styled ->
1181 Styled styled ->
1166 styles ++ styled.styles
1182 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
1234 in
1183 in
1235− gatherAttrRecursive newClasses node has transform newStyles attrs (nearbyElement :: children) remaining
1184+ gatherAttrRecursive
1185+ classes
1186+ node
1187+ has
1188+ transform
1189+ newStyles
1190+ attrs
1191+ (addNearbyElement location elem children)
1192+ remaining
1236
1193
1237 AlignX x ->
1194 AlignX x ->
1238 if Flag.present Flag.xAlign has then
1195 if Flag.present Flag.xAlign has then
@@ -1288,6 +1245,106 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
1288 remaining
1245 remaining
1289
1246
1290
1247
1248+addNearbyElement location elem existing =
1249+ let
1250+ nearby =
1251+ nearbyElement location elem
1252+ in
1253+ case existing of
1254+ NoNearbyChildren ->
1255+ case location of
1256+ Behind ->
1257+ ChildrenBehind [ nearby ]
1258+
1259+ _ ->
1260+ ChildrenInFront [ nearby ]
1261+
1262+ ChildrenBehind existingBehind ->
1263+ case location of
1264+ Behind ->
1265+ ChildrenBehind (nearby :: existingBehind)
1266+
1267+ _ ->
1268+ ChildrenBehindAndInFront existingBehind [ nearby ]
1269+
1270+ ChildrenInFront existingInFront ->
1271+ case location of
1272+ Behind ->
1273+ ChildrenBehindAndInFront [ nearby ] existingInFront
1274+
1275+ _ ->
1276+ ChildrenInFront (nearby :: existingInFront)
1277+
1278+ ChildrenBehindAndInFront existingBehind existingInFront ->
1279+ case location of
1280+ Behind ->
1281+ ChildrenBehindAndInFront (nearby :: existingBehind) existingInFront
1282+
1283+ _ ->
1284+ ChildrenBehindAndInFront existingBehind (nearby :: existingInFront)
1285+
1286+
1287+nearbyElement location elem =
1288+ Html.div
1289+ [ Html.Attributes.class <|
1290+ case location of
1291+ Above ->
1292+ String.join " "
1293+ [ Internal.Style.classes.nearby
1294+ , Internal.Style.classes.single
1295+ , Internal.Style.classes.above
1296+ ]
1297+
1298+ Below ->
1299+ String.join " "
1300+ [ Internal.Style.classes.nearby
1301+ , Internal.Style.classes.single
1302+ , Internal.Style.classes.below
1303+ ]
1304+
1305+ OnRight ->
1306+ String.join " "
1307+ [ Internal.Style.classes.nearby
1308+ , Internal.Style.classes.single
1309+ , Internal.Style.classes.onRight
1310+ ]
1311+
1312+ OnLeft ->
1313+ String.join " "
1314+ [ Internal.Style.classes.nearby
1315+ , Internal.Style.classes.single
1316+ , Internal.Style.classes.onLeft
1317+ ]
1318+
1319+ InFront ->
1320+ String.join " "
1321+ [ Internal.Style.classes.nearby
1322+ , Internal.Style.classes.single
1323+ , Internal.Style.classes.inFront
1324+ ]
1325+
1326+ Behind ->
1327+ String.join " "
1328+ [ Internal.Style.classes.nearby
1329+ , Internal.Style.classes.single
1330+ , Internal.Style.classes.behind
1331+ ]
1332+ ]
1333+ [ case elem of
1334+ Empty ->
1335+ VirtualDom.text ""
1336+
1337+ Text str ->
1338+ textElement str
1339+
1340+ Unstyled html ->
1341+ html asEl
1342+
1343+ Styled styled ->
1344+ styled.html NoStyleSheet asEl
1345+ ]
1346+
1347+
1291renderWidth w =
1348renderWidth w =
1292 case w of
1349 case w of
1293 Px px ->
1350 Px px ->
@@ -1494,7 +1551,7 @@ element : LayoutContext -> NodeName -> List (Attribute aligned msg) -> Children
1494element context node attributes children =
1551element context node attributes children =
1495 attributes
1552 attributes
1496 |> List.reverse
1553 |> List.reverse
1497− |> gatherAttrRecursive (contextClasses context) node Flag.none untransformed [] [] []
1554+ |> gatherAttrRecursive (contextClasses context) node Flag.none untransformed [] [] NoNearbyChildren
1498 |> createElement context children
1555 |> createElement context children
1499
1556
1500
1557
@@ -1657,13 +1714,8 @@ createElement context children rendered =
1657 (finalizeNode rendered.has
1714 (finalizeNode rendered.has
1658 rendered.node
1715 rendered.node
1659 rendered.attributes
1716 rendered.attributes
1660− (Keyed <|
1717+ (Keyed
1661− keyed
1662− ++ List.map
1663− (\x ->
1664− ( "nearby-elements-pls", x )
1665− )
1666− rendered.children
1718+ (addKeyedChildren "nearby-element-pls" keyed rendered.children)
1667 )
1719 )
1668 NoStyleSheet
1720 NoStyleSheet
1669 )
1721 )
@@ -1677,13 +1729,7 @@ createElement context children rendered =
1677 rendered.node
1729 rendered.node
1678 rendered.attributes
1730 rendered.attributes
1679 (Keyed
1731 (Keyed
1680− (keyed
1681− ++ List.map
1682− (\x ->
1683− ( "nearby-elements-pls", x )
1684− )
1685− rendered.children
1732+ (addKeyedChildren "nearby-element-pls" keyed rendered.children)
1686− )
1687 )
1733 )
1688 }
1734 }
1689
1735
@@ -1705,7 +1751,7 @@ createElement context children rendered =
1705 rendered.has
1751 rendered.has
1706 rendered.node
1752 rendered.node
1707 rendered.attributes
1753 rendered.attributes
1708− (Unkeyed <| unkeyed ++ rendered.children)
1754+ (Unkeyed (addChildren unkeyed rendered.children))
1709 NoStyleSheet
1755 NoStyleSheet
1710 )
1756 )
1711
1757
@@ -1717,10 +1763,42 @@ createElement context children rendered =
1717 rendered.has
1763 rendered.has
1718 rendered.node
1764 rendered.node
1719 rendered.attributes
1765 rendered.attributes
1720− (Unkeyed (unkeyed ++ rendered.children))
1766+ (Unkeyed (addChildren unkeyed rendered.children))
1721 }
1767 }
1722
1768
1723
1769
1770+addChildren existing nearbyChildren =
1771+ case nearbyChildren of
1772+ NoNearbyChildren ->
1773+ existing
1774+
1775+ ChildrenBehind behind ->
1776+ behind ++ existing
1777+
1778+ ChildrenInFront inFront ->
1779+ existing ++ inFront
1780+
1781+ ChildrenBehindAndInFront behind inFront ->
1782+ behind ++ existing ++ inFront
1783+
1784+
1785+addKeyedChildren key existing nearbyChildren =
1786+ case nearbyChildren of
1787+ NoNearbyChildren ->
1788+ existing
1789+
1790+ ChildrenBehind behind ->
1791+ List.map (\x -> ( key, x )) behind ++ existing
1792+
1793+ ChildrenInFront inFront ->
1794+ existing ++ List.map (\x -> ( key, x )) inFront
1795+
1796+ ChildrenBehindAndInFront behind inFront ->
1797+ List.map (\x -> ( key, x )) behind
1798+ ++ existing
1799+ ++ List.map (\x -> ( key, x )) inFront
1800+
1801+
1724unit =
1802unit =
1725 0
1803 0
1726
1804