1module Internal.Model exposing
30 , TransformComponent(..)
47 , composeTransformation
55 , extractSpacingAndPadding
86 , reduceStylesRecursive
110import Html.Attributes
112import Internal.Flag as Flag exposing (Flag)
113import Internal.Style exposing (classes, dot)
114import Json.Encode as Encode
115import Set exposing (Set)
120 = Unstyled (LayoutContext -> VirtualDom.Node msg)
122 { styles : List Style
123 , html : EmbedStyle -> LayoutContext -> VirtualDom.Node msg
131 | StaticRootAndDynamic OptionRecord (List Style)
132 | OnlyDynamic OptionRecord (List Style)
135noStyleSheet : EmbedStyle
151 | Aligned (Maybe HAlign) (Maybe VAlign)
167 = Style String (List Property)
169 | FontFamily String (List Font)
171 -- classname, prop, value
172 | Single String String String
173 | Colored String String Color
174 | SpacingStyle String Int Int
175 | BorderWidth String Int Int Int Int
176 | PaddingStyle String Int Int Int Int
178 { spacing : ( Length, Length )
179 , columns : List Length
188 | Transform Transformation
189 | PseudoSelector PseudoClass (List Style)
190 | Transparency String Float
191 | Shadows String String
197 -- translate, scale, rotate
198 | FullTransform XYZ XYZ XYZ Angle
208type alias Adjustment =
221 | ImportFont String String
224 , adjustment : Maybe Adjustment
225 , variants : List Variant
230 = VariantActive String
232 | VariantIndexed String Int
237 VariantActive name ->
241 "\"" ++ name ++ "\" 0"
243 VariantIndexed name index ->
244 "\"" ++ name ++ "\" " ++ String.fromInt index
249 VariantActive name ->
255 VariantIndexed name index ->
256 name ++ "-" ++ String.fromInt index
259renderVariants typeface =
262 Just (String.join ", " (List.map renderVariant font.variants))
270 VariantActive name ->
276 VariantIndexed name index ->
277 name == "smcp" && index == 1
280hasSmallCaps typeface =
283 List.any isSmallCaps font.variants
290 = Property String String
294 ( Float, Float, Float )
301type Attribute aligned msg
303 | Attr (VirtualDom.Attribute msg)
304 | Describe Description
305 -- invalidation key and literal class
307 -- invalidation key "border-color" as opposed to "border-color-10-10-10" that will be the key for the class
308 | StyleClass Flag Style
313 | Nearby Location (Element msg)
314 | TransformComponent Flag TransformComponent
317type TransformComponent
365 = Rgba Float Float Float Float
371 | Embedded String String
374type NearbyChildren msg
376 | ChildrenBehind (List (Html.Html msg))
377 | ChildrenInFront (List (Html.Html msg))
378 | ChildrenBehindAndInFront (List (Html.Html msg)) (List (Html.Html msg))
385type alias Gathered msg =
387 , attributes : List (VirtualDom.Attribute msg)
388 , styles : List Style
389 , children : NearbyChildren msg
394htmlClass : String -> Attribute aligned msg
396 Attr <| Html.Attributes.class cls
400unstyled : VirtualDom.Node msg -> Element msg
405finalizeNode has node attributes children embedMode parentContext =
407 createNode nodeName attrs =
410 VirtualDom.keyedNode nodeName
416 OnlyDynamic opts styles ->
417 embedKeyed False opts styles keyed
419 StaticRootAndDynamic opts styles ->
420 embedKeyed True opts styles keyed
432 VirtualDom.node nodeName
439 OnlyDynamic opts styles ->
440 embedWith False opts styles unkeyed
442 StaticRootAndDynamic opts styles ->
443 embedWith True opts styles unkeyed
449 createNode "div" attributes
452 createNode nodeName attributes
454 Embedded nodeName internal ->
455 VirtualDom.node nodeName
457 [ createNode internal
458 [ Html.Attributes.class
459 (classes.any ++ " " ++ classes.single)
463 case parentContext of
465 if Flag.present Flag.widthFill has && not (Flag.present Flag.widthBetween has) then
468 else if Flag.present Flag.alignRight has then
470 [ Html.Attributes.class
475 , classes.contentCenterY
476 , classes.alignContainerRight
482 else if Flag.present Flag.centerX has then
484 [ Html.Attributes.class
489 , classes.contentCenterY
490 , classes.alignContainerCenterX
500 if Flag.present Flag.heightFill has && not (Flag.present Flag.heightBetween has) then
503 else if Flag.present Flag.centerY has then
505 [ Html.Attributes.class
510 , classes.alignContainerCenterY
516 else if Flag.present Flag.alignBottom has then
518 [ Html.Attributes.class
523 , classes.alignContainerBottom
536embedWith static opts styles children =
540 |> List.foldl reduceStyles ( Set.empty, renderFocusStyle opts.focus )
542 -- |> reduceStylesRecursive Set.empty [ ]) --renderFocusStyle opts.focus ]
556embedKeyed static opts styles children =
560 |> List.foldl reduceStyles ( Set.empty, renderFocusStyle opts.focus )
562 -- |> reduceStylesRecursive Set.empty [ ]) --renderFocusStyle opts.focus ]
567 ( "static-stylesheet", staticRoot opts )
568 :: ( "dynamic-stylesheet"
574 ( "dynamic-stylesheet"
580reduceStylesRecursive : Set String -> List Style -> List Style -> List Style
581reduceStylesRecursive cache found styles =
591 if Set.member styleName cache then
592 reduceStylesRecursive cache found remaining
595 reduceStylesRecursive (Set.insert styleName cache) (head :: found) remaining
598reduceStyles : Style -> ( Set String, List Style ) -> ( Set String, List Style )
599reduceStyles style (( cache, existing ) as nevermind) =
604 if Set.member styleName cache then
608 ( Set.insert styleName cache
615 -- |> List.map (\x -> ( getStyleName x, x ))
616 |> List.sortBy getStyleName
617 |> reduceRecursiveCalcName []
620reduceRecursiveCalcName : List Style -> List Style -> List Style
621reduceRecursiveCalcName found styles =
629 headOfList :: other :: remaining ->
630 if headOfList /= other then
631 reduceRecursiveCalcName (headOfList :: found) (other :: remaining)
634 reduceRecursiveCalcName found (other :: remaining)
637reduceRecursive : List Style -> List ( String, Style ) -> List Style
638reduceRecursive found styles =
643 ( _, headOfList ) :: [] ->
646 ( headOfListName, headOfList ) :: ( otherName, other ) :: remaining ->
647 if headOfListName /= otherName then
648 reduceRecursive (headOfList :: found) (( otherName, other ) :: remaining)
651 reduceRecursive found (( otherName, other ) :: remaining)
654addNodeName : String -> NodeName -> NodeName
655addNodeName newNode old =
661 Embedded name newNode
667alignXName : HAlign -> String
671 classes.alignedHorizontally ++ " " ++ classes.alignLeft
674 classes.alignedHorizontally ++ " " ++ classes.alignRight
677 classes.alignedHorizontally ++ " " ++ classes.alignCenterX
680alignYName : VAlign -> String
684 classes.alignedVertically ++ " " ++ classes.alignTop
687 classes.alignedVertically ++ " " ++ classes.alignBottom
690 classes.alignedVertically ++ " " ++ classes.alignCenterY
693transformClass transform =
707 FullTransform ( tx, ty, tz ) ( sx, sy, sz ) ( ox, oy, oz ) angle ->
731transformValue transform =
739 ++ String.fromFloat x
741 ++ String.fromFloat y
743 ++ String.fromFloat z
746 FullTransform ( tx, ty, tz ) ( sx, sy, sz ) ( ox, oy, oz ) angle ->
750 ++ String.fromFloat tx
752 ++ String.fromFloat ty
754 ++ String.fromFloat tz
759 ++ String.fromFloat sx
761 ++ String.fromFloat sy
763 ++ String.fromFloat sz
768 ++ String.fromFloat ox
770 ++ String.fromFloat oy
772 ++ String.fromFloat oz
774 ++ String.fromFloat angle
777 Just <| translate ++ " " ++ scale ++ " " ++ rotate
780composeTransformation transform component =
797 FullTransform ( 0, 0, 0 ) ( 1, 1, 1 ) xyz angle
800 FullTransform ( 0, 0, 0 ) xyz ( 0, 0, 1 ) 0
802 Moved (( x, y, z ) as moved) ->
817 FullTransform moved ( 1, 1, 1 ) xyz angle
820 FullTransform moved scale ( 0, 0, 1 ) 0
822 FullTransform (( x, y, z ) as moved) scaled origin angle ->
825 FullTransform ( newX, y, z ) scaled origin angle
828 FullTransform ( x, newY, z ) scaled origin angle
831 FullTransform ( x, y, newZ ) scaled origin angle
834 FullTransform newMove scaled origin angle
836 Rotate newOrigin newAngle ->
837 FullTransform moved scaled newOrigin newAngle
840 FullTransform moved newScale origin angle
843skippable flag style =
844 if flag == Flag.borderWidth then
880 PaddingStyle name t r b l ->
881 t == b && t == r && t == l && t >= 0 && t <= 24
883 -- SpacingStyle _ _ _ ->
897 -> List (VirtualDom.Attribute msg)
898 -> NearbyChildren msg
899 -> List (Attribute aligned msg)
901gatherAttrRecursive classes node has transform styles attrs children elementAttrs =
904 case transformClass transform of
906 { attributes = Html.Attributes.class classes :: attrs
909 , children = children
914 { attributes = Html.Attributes.class (classes ++ " " ++ class) :: attrs
915 , styles = Transform transform :: styles
917 , children = children
921 attribute :: remaining ->
924 gatherAttrRecursive classes node has transform styles attrs children remaining
926 Class flag exactClassName ->
927 if Flag.present flag has then
928 gatherAttrRecursive classes node has transform styles attrs children remaining
931 gatherAttrRecursive (exactClassName ++ " " ++ classes) node (Flag.add flag has) transform styles attrs children remaining
933 Attr actualAttribute ->
934 gatherAttrRecursive classes node has transform styles (actualAttribute :: attrs) children remaining
936 StyleClass flag style ->
937 if Flag.present flag has then
938 gatherAttrRecursive classes node has transform styles attrs children remaining
940 else if skippable flag style then
941 gatherAttrRecursive (getStyleName style ++ " " ++ classes)
951 gatherAttrRecursive (getStyleName style ++ " " ++ classes)
960 TransformComponent flag component ->
961 gatherAttrRecursive classes
964 (composeTransformation transform component)
971 if Flag.present Flag.width has then
972 gatherAttrRecursive classes node has transform styles attrs children remaining
977 gatherAttrRecursive ((Internal.Style.classes.widthExact ++ " width-px-" ++ String.fromInt px) ++ " " ++ classes)
979 (Flag.add Flag.width has)
981 (Single ("width-px-" ++ String.fromInt px) "width" (String.fromInt px ++ "px") :: styles)
987 gatherAttrRecursive (classes ++ " " ++ Internal.Style.classes.widthContent)
989 (Flag.add Flag.widthContent (Flag.add Flag.width has))
998 gatherAttrRecursive (classes ++ " " ++ Internal.Style.classes.widthFill)
1000 (Flag.add Flag.widthFill (Flag.add Flag.width has))
1008 gatherAttrRecursive (classes ++ " " ++ Internal.Style.classes.widthFillPortion ++ " width-fill-" ++ String.fromInt portion)
1010 (Flag.add Flag.widthFill (Flag.add Flag.width has))
1013 (Internal.Style.classes.any
1015 ++ Internal.Style.classes.row
1017 ++ (Internal.Style.dot <| "width-fill-" ++ String.fromInt portion)
1020 (String.fromInt (portion * 100000))
1029 ( addToFlags, newClass, newStyles ) =
1032 gatherAttrRecursive (classes ++ " " ++ newClass)
1034 (Flag.merge addToFlags (Flag.add Flag.width has))
1036 (newStyles ++ styles)
1042 if Flag.present Flag.height has then
1043 gatherAttrRecursive classes node has transform styles attrs children remaining
1050 String.fromInt px ++ "px"
1055 gatherAttrRecursive (Internal.Style.classes.heightExact ++ " " ++ name ++ " " ++ classes)
1057 (Flag.add Flag.height has)
1059 (Single name "height " val :: styles)
1065 gatherAttrRecursive (Internal.Style.classes.heightContent ++ " " ++ classes)
1067 (Flag.add Flag.heightContent (Flag.add Flag.height has))
1075 if portion == 1 then
1076 gatherAttrRecursive (Internal.Style.classes.heightFill ++ " " ++ classes)
1078 (Flag.add Flag.heightFill (Flag.add Flag.height has))
1086 gatherAttrRecursive (classes ++ " " ++ (Internal.Style.classes.heightFillPortion ++ " height-fill-" ++ String.fromInt portion))
1088 (Flag.add Flag.heightFill (Flag.add Flag.height has))
1091 (Internal.Style.classes.any
1093 ++ Internal.Style.classes.column
1095 ++ (Internal.Style.dot <| "height-fill-" ++ String.fromInt portion)
1098 (String.fromInt (portion * 100000))
1107 ( addToFlags, newClass, newStyles ) =
1110 gatherAttrRecursive (classes ++ " " ++ newClass)
1112 (Flag.merge addToFlags (Flag.add Flag.height has))
1114 (newStyles ++ styles)
1119 Describe description ->
1122 gatherAttrRecursive classes (addNodeName "main" node) has transform styles attrs children remaining
1125 gatherAttrRecursive classes (addNodeName "nav" node) has transform styles attrs children remaining
1128 gatherAttrRecursive classes (addNodeName "footer" node) has transform styles attrs children remaining
1131 gatherAttrRecursive classes (addNodeName "aside" node) has transform styles attrs children remaining
1135 gatherAttrRecursive classes (addNodeName "h1" node) has transform styles attrs children remaining
1138 gatherAttrRecursive classes (addNodeName ("h" ++ String.fromInt i) node) has transform styles attrs children remaining
1141 gatherAttrRecursive classes (addNodeName "h6" node) has transform styles attrs children remaining
1144 -- previously we rendered a <p> tag, though apparently this invalidates the html if it has <div>s inside.
1145 -- Since we can't guaranteee that there are no divs, we need another strategy.
1146 -- While it's not documented in many places, there apparently is a paragraph aria role
1147 -- https://github.com/w3c/aria/blob/11f85f41a5b621fdbe85fc9bcdcd270e653a48ba/common/script/roleInfo.js
1148 -- Though we'll need to wait till it gets released in an official wai-aria spec to use it.
1149 -- If it's used at the moment, then Lighthouse complains (likely rightfully) that role paragraph is not recognized.
1161 gatherAttrRecursive classes node has transform styles (VirtualDom.attribute "role" "button" :: attrs) children remaining
1164 gatherAttrRecursive classes node has transform styles (VirtualDom.attribute "aria-label" label :: attrs) children remaining
1167 gatherAttrRecursive classes node has transform styles (VirtualDom.attribute "aria-live" "polite" :: attrs) children remaining
1170 gatherAttrRecursive classes node has transform styles (VirtualDom.attribute "aria-live" "assertive" :: attrs) children remaining
1172 Nearby location elem ->
1186 styles ++ styled.styles
1195 (addNearbyElement location elem children)
1199 if Flag.present Flag.xAlign has then
1200 gatherAttrRecursive classes node has transform styles attrs children remaining
1203 gatherAttrRecursive (alignXName x ++ " " ++ classes)
1206 |> Flag.add Flag.xAlign
1210 Flag.add Flag.centerX flags
1213 Flag.add Flag.alignRight flags
1226 if Flag.present Flag.yAlign has then
1227 gatherAttrRecursive classes node has transform styles attrs children remaining
1230 gatherAttrRecursive (alignYName y ++ " " ++ classes)
1232 (Flag.add Flag.yAlign has
1236 Flag.add Flag.centerY flags
1239 Flag.add Flag.alignBottom flags
1252addNearbyElement location elem existing =
1255 nearbyElement location elem
1261 ChildrenBehind [ nearby ]
1264 ChildrenInFront [ nearby ]
1266 ChildrenBehind existingBehind ->
1269 ChildrenBehind (nearby :: existingBehind)
1272 ChildrenBehindAndInFront existingBehind [ nearby ]
1274 ChildrenInFront existingInFront ->
1277 ChildrenBehindAndInFront [ nearby ] existingInFront
1280 ChildrenInFront (nearby :: existingInFront)
1282 ChildrenBehindAndInFront existingBehind existingInFront ->
1285 ChildrenBehindAndInFront (nearby :: existingBehind) existingInFront
1288 ChildrenBehindAndInFront existingBehind (nearby :: existingInFront)
1291nearbyElement location elem =
1293 [ Html.Attributes.class <|
1297 [ Internal.Style.classes.nearby
1298 , Internal.Style.classes.single
1299 , Internal.Style.classes.above
1304 [ Internal.Style.classes.nearby
1305 , Internal.Style.classes.single
1306 , Internal.Style.classes.below
1311 [ Internal.Style.classes.nearby
1312 , Internal.Style.classes.single
1313 , Internal.Style.classes.onRight
1318 [ Internal.Style.classes.nearby
1319 , Internal.Style.classes.single
1320 , Internal.Style.classes.onLeft
1325 [ Internal.Style.classes.nearby
1326 , Internal.Style.classes.single
1327 , Internal.Style.classes.inFront
1332 [ Internal.Style.classes.nearby
1333 , Internal.Style.classes.single
1334 , Internal.Style.classes.behind
1348 styled.html NoStyleSheet asEl
1356 , Internal.Style.classes.widthExact ++ " width-px-" ++ String.fromInt px
1357 , [ Single ("width-px-" ++ String.fromInt px) "width" (String.fromInt px ++ "px") ]
1361 ( Flag.add Flag.widthContent Flag.none
1362 , Internal.Style.classes.widthContent
1367 if portion == 1 then
1368 ( Flag.add Flag.widthFill Flag.none
1369 , Internal.Style.classes.widthFill
1374 ( Flag.add Flag.widthFill Flag.none
1375 , Internal.Style.classes.widthFillPortion ++ " width-fill-" ++ String.fromInt portion
1377 (Internal.Style.classes.any
1379 ++ Internal.Style.classes.row
1381 ++ (Internal.Style.dot <| "width-fill-" ++ String.fromInt portion)
1384 (String.fromInt (portion * 100000))
1392 ++ String.fromInt minSize
1398 (String.fromInt minSize ++ "px")
1400 ( newFlag, newAttrs, newStyle ) =
1403 ( Flag.add Flag.widthBetween newFlag
1404 , cls ++ " " ++ newAttrs
1411 "max-width-" ++ String.fromInt maxSize
1416 (String.fromInt maxSize ++ "px")
1418 ( newFlag, newAttrs, newStyle ) =
1421 ( Flag.add Flag.widthBetween newFlag
1422 , cls ++ " " ++ newAttrs
1438 , Internal.Style.classes.heightExact ++ " " ++ name
1439 , [ Single name "height" (val ++ "px") ]
1443 ( Flag.add Flag.heightContent Flag.none
1444 , Internal.Style.classes.heightContent
1449 if portion == 1 then
1450 ( Flag.add Flag.heightFill Flag.none
1451 , Internal.Style.classes.heightFill
1456 ( Flag.add Flag.heightFill Flag.none
1457 , Internal.Style.classes.heightFillPortion ++ " height-fill-" ++ String.fromInt portion
1459 (Internal.Style.classes.any
1461 ++ Internal.Style.classes.column
1463 ++ (Internal.Style.dot <| "height-fill-" ++ String.fromInt portion)
1466 (String.fromInt (portion * 100000))
1474 ++ String.fromInt minSize
1480 (String.fromInt minSize ++ "px")
1482 ( newFlag, newAttrs, newStyle ) =
1485 ( Flag.add Flag.heightBetween newFlag
1486 , cls ++ " " ++ newAttrs
1493 "max-height-" ++ String.fromInt maxSize
1498 (String.fromInt maxSize ++ "px")
1500 ( newFlag, newAttrs, newStyle ) =
1503 ( Flag.add Flag.heightBetween newFlag
1504 , cls ++ " " ++ newAttrs
1510 classes.any ++ " " ++ classes.row
1514 classes.any ++ " " ++ classes.column
1518 classes.any ++ " " ++ classes.single
1522 classes.any ++ " " ++ classes.grid
1526 classes.any ++ " " ++ classes.paragraph
1530 classes.any ++ " " ++ classes.page
1533contextClasses context =
1554element : LayoutContext -> NodeName -> List (Attribute aligned msg) -> Children (Element msg) -> Element msg
1555element context node attributes children =
1558 |> gatherAttrRecursive (contextClasses context) node Flag.none untransformed [] [] NoNearbyChildren
1559 |> createElement context children
1566createElement : LayoutContext -> Children (Element msg) -> Gathered msg -> Element msg
1567createElement context children rendered =
1569 gather child ( htmls, existingStyles ) =
1572 if context == asParagraph then
1573 ( html context :: htmls
1578 ( html context :: htmls
1583 if context == asParagraph then
1584 ( styled.html NoStyleSheet context :: htmls
1585 , if List.isEmpty existingStyles then
1589 styled.styles ++ existingStyles
1593 ( styled.html NoStyleSheet context :: htmls
1594 , if List.isEmpty existingStyles then
1598 styled.styles ++ existingStyles
1602 -- TEXT OPTIMIZATION
1603 -- You can have raw text if the element is an el, and has `width-content` and `height-content`
1604 -- Same if it's a column or row with one child and width-content, height-content
1605 -- interferes with css grid
1606 -- Maybe we could unpack text elements in a paragraph as well,
1607 -- however, embedded elements that are larger than the line height will overlap with exisitng text.
1608 -- I don't think that's what we want.
1615 -- ( VirtualDom.text
1616 -- (if context == asParagraph then
1625 ( (if context == asEl then
1636 ( htmls, existingStyles )
1638 gatherKeyed ( key, child ) ( htmls, existingStyles ) =
1641 if context == asParagraph then
1642 ( ( key, html context ) :: htmls
1647 ( ( key, html context ) :: htmls
1652 if context == asParagraph then
1653 ( ( key, styled.html NoStyleSheet context )
1655 , if List.isEmpty existingStyles then
1659 styled.styles ++ existingStyles
1663 ( ( key, styled.html NoStyleSheet context ) :: htmls
1664 , if List.isEmpty existingStyles then
1668 styled.styles ++ existingStyles
1672 -- TEXT OPTIMIZATION
1673 -- You can have raw text if the element is an el, and has `width-content` and `height-content`
1674 -- Same if it's a column or row with one child and width-content, height-content
1682 -- , VirtualDom.text
1690 , if context == asEl then
1701 ( htmls, existingStyles )
1704 Keyed keyedChildren ->
1705 case List.foldr gatherKeyed ( [], [] ) keyedChildren of
1706 ( keyed, styles ) ->
1709 if List.isEmpty styles then
1713 rendered.styles ++ styles
1718 (finalizeNode rendered.has
1722 (addKeyedChildren "nearby-element-pls" keyed rendered.children)
1729 { styles = allStyles
1736 (addKeyedChildren "nearby-element-pls" keyed rendered.children)
1740 Unkeyed unkeyedChildren ->
1741 case List.foldr gather ( [], [] ) unkeyedChildren of
1742 ( unkeyed, styles ) ->
1745 if List.isEmpty styles then
1749 rendered.styles ++ styles
1758 (Unkeyed (addChildren unkeyed rendered.children))
1764 { styles = allStyles
1770 (Unkeyed (addChildren unkeyed rendered.children))
1774addChildren existing nearbyChildren =
1775 case nearbyChildren of
1779 ChildrenBehind behind ->
1782 ChildrenInFront inFront ->
1785 ChildrenBehindAndInFront behind inFront ->
1786 behind ++ existing ++ inFront
1789addKeyedChildren key existing nearbyChildren =
1790 case nearbyChildren of
1794 ChildrenBehind behind ->
1795 List.map (\x -> ( key, x )) behind ++ existing
1797 ChildrenInFront inFront ->
1798 existing ++ List.map (\x -> ( key, x )) inFront
1800 ChildrenBehindAndInFront behind inFront ->
1801 List.map (\x -> ( key, x )) behind
1803 ++ List.map (\x -> ( key, x )) inFront
1811 { hover = AllowHover
1812 , focus = focusDefaultStyle
1817staticRoot : OptionRecord -> VirtualDom.Node msg
1821 -- wrap the style node in a div to prevent `Dark Reader` from blowin up the dom.
1822 VirtualDom.node "div"
1824 [ VirtualDom.node "style" [] [ VirtualDom.text Internal.Style.rules ] ]
1826 NoStaticStyleSheet ->
1830 VirtualDom.node "elm-ui-static-rules" [ VirtualDom.property "rules" (Encode.string Internal.Style.rules) ] []
1833addWhen ifThis x to =
1843This doesn't reduce equivalent attributes completely.
1846filter : List (Attribute aligned msg) -> List (Attribute aligned msg)
1850 (\x ( found, has ) ->
1861 StyleClass _ style ->
1865 if Set.member "width" has then
1869 ( x :: found, Set.insert "width" has )
1872 if Set.member "height" has then
1876 ( x :: found, Set.insert "height" has )
1878 Describe description ->
1879 if Set.member "described" has then
1883 ( x :: found, Set.insert "described" has )
1885 Nearby location elem ->
1889 if Set.member "align-x" has then
1893 ( x :: found, Set.insert "align-x" has )
1896 if Set.member "align-y" has then
1900 ( x :: found, Set.insert "align-y" has )
1902 TransformComponent _ _ ->
1903 if Set.member "transform" has then
1907 ( x :: found, Set.insert "transform" has )
1928get : List (Attribute aligned msg) -> (Attribute aligned msg -> Bool) -> List (Attribute aligned msg)
1944 = Spaced String Int Int
1948 = Padding String Int Int Int Int
1951extractSpacingAndPadding : List (Attribute aligned msg) -> ( Maybe Padding, Maybe Spacing )
1952extractSpacingAndPadding attrs =
1954 (\attr ( pad, spacing ) ->
1961 StyleClass _ (PaddingStyle name t r b l) ->
1962 Just (Padding name t r b l)
1972 StyleClass _ (SpacingStyle name x y) ->
1973 Just (Spaced name x y)
1979 ( Nothing, Nothing )
1983getSpacing : List (Attribute aligned msg) -> ( Int, Int ) -> ( Int, Int )
1984getSpacing attrs default =
1994 StyleClass _ (SpacingStyle _ x y) ->
2001 |> Maybe.withDefault default
2004getWidth : List (Attribute aligned msg) -> Maybe Length
2024getHeight : List (Attribute aligned msg) -> Maybe Length
2044textElementClasses : String
2050 ++ classes.widthContent
2052 ++ classes.heightContent
2055textElement : String -> VirtualDom.Node msg
2058 [ Html.Attributes.class
2064textElementFillClasses : String
2065textElementFillClasses =
2070 ++ classes.widthFill
2072 ++ classes.heightFill
2075textElementFill : String -> VirtualDom.Node msg
2076textElementFill str =
2078 [ Html.Attributes.class
2079 textElementFillClasses
2086 | Keyed (List ( String, x ))
2094 Styled { styles, html } ->
2095 html (mode styles) asEl
2105renderRoot : List Option -> List (Attribute aligned msg) -> Element msg -> VirtualDom.Node msg
2106renderRoot optionList attributes child =
2109 optionsToRecord optionList
2112 case options.mode of
2113 NoStaticStyleSheet ->
2117 StaticRootAndDynamic options
2119 element asEl div attributes (Unkeyed [ child ])
2120 |> toHtml embedStyle
2125 | NoStaticStyleSheet
2129type alias OptionRecord =
2130 { hover : HoverSetting
2131 , focus : FocusStyle
2143 = HoverOption HoverSetting
2144 | FocusStyleOption FocusStyle
2145 | RenderModeOption RenderMode
2148type alias FocusStyle =
2149 { borderColor : Maybe Color
2150 , shadow : Maybe Shadow
2151 , backgroundColor : Maybe Color
2157 , offset : ( Int, Int )
2163rootStyle : List (Attribute aligned msg)
2167 [ Typeface "Open Sans"
2168 , Typeface "Helvetica"
2169 , Typeface "Verdana"
2173 [ StyleClass Flag.bgColor (Colored ("bg-" ++ formatColorClass (Rgba 1 1 1 0)) "background-color" (Rgba 1 1 1 0))
2174 , StyleClass Flag.fontColor (Colored ("fc-" ++ formatColorClass (Rgba 0 0 0 1)) "color" (Rgba 0 0 0 1))
2175 , StyleClass Flag.fontSize (FontSize 20)
2176 , StyleClass Flag.fontFamily <|
2177 FontFamily (List.foldl renderFontClassName "font-" families)
2182renderFontClassName : Font -> String -> String
2183renderFontClassName font current =
2201 ImportFont name url ->
2207 FontWith { name } ->
2218renderFocusStyle focus =
2219 [ Style (Internal.Style.dot classes.focusedWithin ++ ":focus-within")
2220 (List.filterMap identity
2221 [ Maybe.map (\color -> Property "border-color" (formatColor color)) focus.borderColor
2222 , Maybe.map (\color -> Property "background-color" (formatColor color)) focus.backgroundColor
2225 Property "box-shadow"
2227 { color = shadow.color
2230 |> Tuple.mapFirst toFloat
2231 |> Tuple.mapSecond toFloat
2241 , Just <| Property "outline" "none"
2244 , Style (Internal.Style.dot classes.any ++ ":focus .focusable, " ++ Internal.Style.dot classes.any ++ ".focusable:focus")
2245 (List.filterMap identity
2246 [ Maybe.map (\color -> Property "border-color" (formatColor color)) focus.borderColor
2247 , Maybe.map (\color -> Property "background-color" (formatColor color)) focus.backgroundColor
2250 Property "box-shadow"
2252 { color = shadow.color
2255 |> Tuple.mapFirst toFloat
2256 |> Tuple.mapSecond toFloat
2258 , blur = toFloat shadow.blur
2259 , size = toFloat shadow.size
2264 , Just <| Property "outline" "none"
2270focusDefaultStyle : { backgroundColor : Maybe Color, borderColor : Maybe Color, shadow : Maybe Shadow }
2272 { backgroundColor = Nothing
2273 , borderColor = Nothing
2277 Rgba (155 / 255) (203 / 255) 1 1
2285optionsToRecord : List Option -> OptionRecord
2286optionsToRecord options =
2288 combine opt record =
2290 HoverOption hoverable ->
2291 case record.hover of
2293 { record | hover = Just hoverable }
2298 FocusStyleOption focusStyle ->
2299 case record.focus of
2301 { record | focus = Just focusStyle }
2306 RenderModeOption renderMode ->
2309 { record | mode = Just renderMode }
2316 case record.hover of
2323 case record.focus of
2347toStyleSheet : OptionRecord -> List Style -> VirtualDom.Node msg
2348toStyleSheet options styleSheet =
2349 case options.mode of
2351 -- wrap the style node in a div to prevent `Dark Reader` from blowin up the dom.
2352 VirtualDom.node "div"
2354 [ VirtualDom.node "style"
2356 [ VirtualDom.text (toStyleSheetString options styleSheet) ]
2359 NoStaticStyleSheet ->
2360 -- wrap the style node in a div to prevent `Dark Reader` from blowin up the dom.
2361 VirtualDom.node "div"
2363 [ VirtualDom.node "style"
2365 [ VirtualDom.text (toStyleSheetString options styleSheet) ]
2369 VirtualDom.node "elm-ui-rules"
2370 [ VirtualDom.property "rules"
2371 (encodeStyles options styleSheet)
2376renderTopLevelValues rules =
2381 Just ("@import url('" ++ url ++ "');")
2386 -- Just ("@import url('" ++ x ++ "');")
2393 List.map Tuple.first rules
2395 fontImports ( name, typefaces ) =
2398 String.join "\n" (List.filterMap withImport typefaces)
2402 fontAdjustments ( name, typefaces ) =
2403 case typefaceAdjustment typefaces of
2406 (List.map (renderNullAdjustmentRule name) allNames)
2410 (List.map (renderFontAdjustmentRule name adjustment) allNames)
2412 String.join "\n" (List.map fontImports rules)
2413 ++ String.join "\n" (List.map fontAdjustments rules)
2416renderNullAdjustmentRule fontToAdjust otherFontName =
2419 if fontToAdjust == otherFontName then
2423 otherFontName ++ " ." ++ fontToAdjust
2430 ++ classes.sizeByCapital
2435 ++ classes.sizeByCapital
2437 [ ( "line-height", "1" )
2443 ++ classes.sizeByCapital
2445 ++ Internal.Style.classes.text
2449 ++ classes.sizeByCapital
2451 ++ Internal.Style.classes.text
2453 [ ( "vertical-align", "0" )
2454 , ( "line-height", "1" )
2459fontRule name modifier ( parentAdj, textAdjustment ) =
2478 ++ Internal.Style.classes.text
2484 ++ Internal.Style.classes.text
2490renderFontAdjustmentRule fontToAdjust ( full, capital ) otherFontName =
2493 if fontToAdjust == otherFontName then
2497 otherFontName ++ " ." ++ fontToAdjust
2500 (fontRule name classes.sizeByCapital capital ++ fontRule name classes.fullSize full)
2503bracket selector rules =
2505 renderPair ( name, val ) =
2506 name ++ ": " ++ val ++ ";"
2508 selector ++ " {" ++ String.join "" (List.map renderPair rules) ++ "}"
2511fontAdjustmentRules converted =
2512 ( [ ( "display", "block" )
2514 , [ ( "display", "inline-block" )
2515 , ( "line-height", String.fromFloat converted.height )
2516 , ( "vertical-align", String.fromFloat converted.vertical ++ "em" )
2517 , ( "font-size", String.fromFloat converted.size ++ "em" )
2522typefaceAdjustment typefaces =
2529 case with.adjustment of
2535 ( fontAdjustmentRules
2536 (.full (convertAdjustment adjustment))
2537 , fontAdjustmentRules
2538 (.capital (convertAdjustment adjustment))
2563 "\"" ++ name ++ "\""
2565 ImportFont name url ->
2566 "\"" ++ name ++ "\""
2568 FontWith { name } ->
2569 "\"" ++ name ++ "\""
2574 FontFamily name typefaces ->
2575 Just ( name, typefaces )
2581renderProps force (Property key val) existing =
2583 existing ++ "\n " ++ key ++ ": " ++ val ++ " !important;"
2586 existing ++ "\n " ++ key ++ ": " ++ val ++ ";"
2589encodeStyles options stylesheet =
2595 renderStyleRule options style Nothing
2597 ( getStyleName style, Encode.list Encode.string styled )
2602toStyleSheetString : OptionRecord -> List Style -> String
2603toStyleSheetString options stylesheet =
2605 combine style rendered =
2606 { rules = rendered.rules ++ renderStyleRule options style Nothing
2608 case topLevelValue style of
2613 topLevel :: rendered.topLevel
2616 case List.foldl combine { topLevel = [], rules = [] } stylesheet of
2617 { topLevel, rules } ->
2618 renderTopLevelValues topLevel ++ String.concat rules
2621renderStyle : OptionRecord -> Maybe PseudoClass -> String -> List Property -> List String
2622renderStyle options maybePseudo selector props =
2625 [ selector ++ "{" ++ List.foldl (renderProps False) "" props ++ "\n}" ]
2630 case options.hover of
2635 [ selector ++ "-hv {" ++ List.foldl (renderProps True) "" props ++ "\n}" ]
2638 [ selector ++ "-hv:hover {" ++ List.foldl (renderProps False) "" props ++ "\n}" ]
2643 List.foldl (renderProps False) "" props
2653 ++ "-fs:not(.focus) {"
2664 ++ "-fs:focus-within {"
2667 , ".focusable-parent:focus ~ "
2678 [ selector ++ "-act:active {" ++ List.foldl (renderProps False) "" props ++ "\n}" ]
2681renderStyleRule : OptionRecord -> Style -> Maybe PseudoClass -> List String
2682renderStyleRule options rule maybePseudo =
2684 Style selector props ->
2685 renderStyle options maybePseudo selector props
2687 Shadows name prop ->
2691 [ Property "box-shadow" prop
2694 Transparency name transparency ->
2704 [ Property "opacity" (String.fromFloat opacity)
2710 (".font-size-" ++ String.fromInt i)
2711 [ Property "font-size" (String.fromInt i ++ "px")
2714 FontFamily name typefaces ->
2718 |> List.filterMap renderVariants
2722 [ Property "font-family"
2724 |> List.map fontName
2727 , Property "font-feature-settings" features
2728 , Property "font-variant"
2729 (if List.any hasSmallCaps typefaces then
2742 Single class prop val ->
2749 Colored class prop color ->
2753 [ Property prop (formatColor color)
2756 SpacingStyle cls x y ->
2762 String.fromFloat (toFloat x / 2) ++ "px"
2765 String.fromFloat (toFloat y / 2) ++ "px"
2768 String.fromInt x ++ "px"
2771 String.fromInt y ++ "px"
2774 "." ++ Internal.Style.classes.row
2777 "." ++ Internal.Style.classes.wrapped ++ row
2780 "." ++ Internal.Style.classes.column
2783 "." ++ Internal.Style.classes.page
2786 "." ++ Internal.Style.classes.paragraph
2789 "." ++ Internal.Style.classes.alignLeft
2792 "." ++ Internal.Style.classes.alignRight
2795 "." ++ Internal.Style.classes.any
2798 "." ++ Internal.Style.classes.single
2801 [ renderStyle options maybePseudo (class ++ row ++ " > " ++ any ++ " + " ++ any) [ Property "margin-left" xPx ]
2803 -- margins don't apply to last element of normal, unwrapped rows
2804 -- , renderStyle options maybePseudo (class ++ row ++ " > " ++ any ++ ":first-child") [ Property "margin" "0" ]
2805 -- For wrapped rows, margins always apply because we handle "canceling out" the other margins manually in the element.
2806 , renderStyle options
2808 (class ++ wrappedRow ++ " > " ++ any)
2809 [ Property "margin" (halfY ++ " " ++ halfX)
2812 -- , renderStyle options maybePseudo
2813 -- (class ++ wrappedRow ++ " > " ++ any ++ ":last-child")
2814 -- [ Property "margin-right" "0"
2817 , renderStyle options maybePseudo (class ++ column ++ " > " ++ any ++ " + " ++ any) [ Property "margin-top" yPx ]
2818 , renderStyle options maybePseudo (class ++ page ++ " > " ++ any ++ " + " ++ any) [ Property "margin-top" yPx ]
2819 , renderStyle options maybePseudo (class ++ page ++ " > " ++ left) [ Property "margin-right" xPx ]
2820 , renderStyle options maybePseudo (class ++ page ++ " > " ++ right) [ Property "margin-left" xPx ]
2821 , renderStyle options
2823 (class ++ paragraph)
2824 [ Property "line-height" ("calc(1em + " ++ String.fromInt y ++ "px)")
2826 , renderStyle options
2828 ("textarea" ++ any ++ class)
2829 [ Property "line-height" ("calc(1em + " ++ String.fromInt y ++ "px)")
2830 , Property "height" ("calc(100% + " ++ String.fromInt y ++ "px)")
2833 -- , renderStyle options
2835 -- (class ++ paragraph ++ " > " ++ any)
2836 -- [ Property "margin-right" xPx
2837 -- , Property "margin-bottom" yPx
2839 , renderStyle options
2841 (class ++ paragraph ++ " > " ++ left)
2842 [ Property "margin-right" xPx
2844 , renderStyle options
2846 (class ++ paragraph ++ " > " ++ right)
2847 [ Property "margin-left" xPx
2849 , renderStyle options
2851 (class ++ paragraph ++ "::after")
2852 [ Property "content" "''"
2853 , Property "display" "block"
2854 , Property "height" "0"
2855 , Property "width" "0"
2856 , Property "margin-top" (String.fromInt (-1 * (y // 2)) ++ "px")
2858 , renderStyle options
2860 (class ++ paragraph ++ "::before")
2861 [ Property "content" "''"
2862 , Property "display" "block"
2863 , Property "height" "0"
2864 , Property "width" "0"
2865 , Property "margin-bottom" (String.fromInt (-1 * (y // 2)) ++ "px")
2869 PaddingStyle cls top right bottom left ->
2878 [ Property "padding"
2881 ++ String.fromInt right
2883 ++ String.fromInt bottom
2885 ++ String.fromInt left
2890 BorderWidth cls top right bottom left ->
2899 [ Property "border-width"
2902 ++ String.fromInt right
2904 ++ String.fromInt bottom
2906 ++ String.fromInt left
2911 GridTemplateStyle template ->
2915 ++ String.join "-" (List.map lengthClassName template.rows)
2917 ++ String.join "-" (List.map lengthClassName template.columns)
2919 ++ lengthClassName (Tuple.first template.spacing)
2921 ++ lengthClassName (Tuple.second template.spacing)
2924 toGridLength (Tuple.second template.spacing)
2927 toGridLength (Tuple.first template.spacing)
2930 toGridLengthHelper Nothing Nothing x
2932 toGridLengthHelper minimum maximum x =
2935 String.fromInt px ++ "px"
2938 case ( minimum, maximum ) of
2939 ( Nothing, Nothing ) ->
2942 ( Just minSize, Nothing ) ->
2943 "minmax(" ++ String.fromInt minSize ++ "px, " ++ "max-content)"
2945 ( Nothing, Just maxSize ) ->
2946 "minmax(max-content, " ++ String.fromInt maxSize ++ "px)"
2948 ( Just minSize, Just maxSize ) ->
2949 "minmax(" ++ String.fromInt minSize ++ "px, " ++ String.fromInt maxSize ++ "px)"
2952 case ( minimum, maximum ) of
2953 ( Nothing, Nothing ) ->
2954 String.fromInt i ++ "fr"
2956 ( Just minSize, Nothing ) ->
2957 "minmax(" ++ String.fromInt minSize ++ "px, " ++ String.fromInt i ++ "fr" ++ "fr)"
2959 ( Nothing, Just maxSize ) ->
2960 "minmax(max-content, " ++ String.fromInt maxSize ++ "px)"
2962 ( Just minSize, Just maxSize ) ->
2963 "minmax(" ++ String.fromInt minSize ++ "px, " ++ String.fromInt maxSize ++ "px)"
2966 toGridLengthHelper (Just m) maximum len
2969 toGridLengthHelper minimum (Just m) len
2973 |> List.map toGridLength
2974 |> String.join ySpacing
2975 |> (\x -> "-ms-grid-columns: " ++ x ++ ";")
2979 |> List.map toGridLength
2980 |> String.join ySpacing
2981 |> (\x -> "-ms-grid-rows: " ++ x ++ ";")
2984 class ++ "{" ++ msColumns ++ msRows ++ "}"
2988 |> List.map toGridLength
2990 |> (\x -> "grid-template-columns: " ++ x ++ ";")
2994 |> List.map toGridLength
2996 |> (\x -> "grid-template-rows: " ++ x ++ ";")
2999 "grid-column-gap:" ++ toGridLength (Tuple.first template.spacing) ++ ";"
3002 "grid-row-gap:" ++ toGridLength (Tuple.second template.spacing) ++ ";"
3005 class ++ "{" ++ columns ++ rows ++ gapX ++ gapY ++ "}"
3008 "@supports (display:grid) {" ++ modernGrid ++ "}"
3014 GridPosition position ->
3018 ++ String.fromInt position.row
3020 ++ String.fromInt position.col
3022 ++ String.fromInt position.width
3024 ++ String.fromInt position.height
3029 ++ String.fromInt position.row
3031 , "-ms-grid-row-span: "
3032 ++ String.fromInt position.height
3034 , "-ms-grid-column: "
3035 ++ String.fromInt position.col
3037 , "-ms-grid-column-span: "
3038 ++ String.fromInt position.width
3043 class ++ "{" ++ msPosition ++ "}"
3048 ++ String.fromInt position.row
3050 ++ String.fromInt (position.row + position.height)
3053 ++ String.fromInt position.col
3055 ++ String.fromInt (position.col + position.width)
3060 class ++ "{" ++ modernPosition ++ "}"
3063 "@supports (display:grid) {" ++ modernGrid ++ "}"
3069 PseudoSelector class styles ->
3071 renderPseudoRule style =
3072 renderStyleRule options style (Just class)
3074 List.concatMap renderPseudoRule styles
3076 Transform transform ->
3079 transformValue transform
3082 transformClass transform
3084 case ( class, val ) of
3085 ( Just cls, Just v ) ->
3089 [ Property "transform"
3097lengthClassName : Length -> String
3101 String.fromInt px ++ "px"
3107 String.fromInt i ++ "fr"
3110 "min" ++ String.fromInt min ++ lengthClassName len
3113 "max" ++ String.fromInt max ++ lengthClassName len
3116formatDropShadow shadow =
3118 [ String.fromFloat (Tuple.first shadow.offset) ++ "px"
3119 , String.fromFloat (Tuple.second shadow.offset) ++ "px"
3120 , String.fromFloat shadow.blur ++ "px"
3121 , formatColor shadow.color
3125formatTextShadow shadow =
3127 [ String.fromFloat (Tuple.first shadow.offset) ++ "px"
3128 , String.fromFloat (Tuple.second shadow.offset) ++ "px"
3129 , String.fromFloat shadow.blur ++ "px"
3130 , formatColor shadow.color
3134textShadowClass shadow =
3137 , floatClass (Tuple.first shadow.offset) ++ "px"
3138 , floatClass (Tuple.second shadow.offset) ++ "px"
3139 , floatClass shadow.blur ++ "px"
3140 , formatColorClass shadow.color
3144formatBoxShadow shadow =
3146 List.filterMap identity
3147 [ if shadow.inset then
3152 , Just <| String.fromFloat (Tuple.first shadow.offset) ++ "px"
3153 , Just <| String.fromFloat (Tuple.second shadow.offset) ++ "px"
3154 , Just <| String.fromFloat shadow.blur ++ "px"
3155 , Just <| String.fromFloat shadow.size ++ "px"
3156 , Just <| formatColor shadow.color
3160boxShadowClass shadow =
3162 [ if shadow.inset then
3167 , floatClass (Tuple.first shadow.offset) ++ "px"
3168 , floatClass (Tuple.second shadow.offset) ++ "px"
3169 , floatClass shadow.blur ++ "px"
3170 , floatClass shadow.size ++ "px"
3171 , formatColorClass shadow.color
3175floatClass : Float -> String
3177 String.fromInt (round (x * 255))
3180formatColor : Color -> String
3181formatColor (Rgba red green blue alpha) =
3183 ++ String.fromInt (round (red * 255))
3184 ++ ("," ++ String.fromInt (round (green * 255)))
3185 ++ ("," ++ String.fromInt (round (blue * 255)))
3186 ++ ("," ++ String.fromFloat alpha ++ ")")
3189formatColorClass : Color -> String
3190formatColorClass (Rgba red green blue alpha) =
3201 "spacing-" ++ String.fromInt x ++ "-" ++ String.fromInt y
3204paddingName top right bottom left =
3206 ++ String.fromInt top
3208 ++ String.fromInt right
3210 ++ String.fromInt bottom
3212 ++ String.fromInt left
3215getStyleName : Style -> String
3221 Transparency name o ->
3227 FontFamily name _ ->
3231 "font-size-" ++ String.fromInt i
3236 Colored class _ _ ->
3239 SpacingStyle cls x y ->
3242 PaddingStyle cls top right bottom left ->
3245 BorderWidth cls top right bottom left ->
3248 GridTemplateStyle template ->
3250 ++ String.join "-" (List.map lengthClassName template.rows)
3252 ++ String.join "-" (List.map lengthClassName template.columns)
3254 ++ lengthClassName (Tuple.first template.spacing)
3256 ++ lengthClassName (Tuple.second template.spacing)
3260 ++ String.fromInt pos.row
3262 ++ String.fromInt pos.col
3264 ++ String.fromInt pos.width
3266 ++ String.fromInt pos.height
3268 PseudoSelector selector subStyle ->
3283 case getStyleName sty of
3288 styleName ++ "-" ++ name
3294 Maybe.withDefault "" (transformClass x)
3301asGrid : LayoutContext
3306asRow : LayoutContext
3311asColumn : LayoutContext
3321asParagraph : LayoutContext
3326asTextColumn : LayoutContext
3335map : (msg -> msg1) -> Element msg -> Element msg1
3340 { styles = styled.styles
3341 , html = \add context -> VirtualDom.map fn <| styled.html add context
3345 Unstyled (VirtualDom.map fn << html)
3354mapAttr : (msg -> msg1) -> Attribute aligned msg -> Attribute aligned msg1
3360 Describe description ->
3361 Describe description
3378 StyleClass flag style ->
3379 StyleClass flag style
3381 Nearby location elem ->
3382 Nearby location (map fn elem)
3385 Attr (VirtualDom.mapAttribute fn htmlAttr)
3387 TransformComponent fl trans ->
3388 TransformComponent fl trans
3391mapAttrFromStyle : (msg -> msg1) -> Attribute Never msg -> Attribute () msg1
3392mapAttrFromStyle fn attr =
3397 Describe description ->
3398 Describe description
3412 -- invalidation key "border-color" as opposed to "border-color-10-10-10" that will be the key for the class
3416 StyleClass flag style ->
3417 StyleClass flag style
3419 Nearby location elem ->
3420 Nearby location (map fn elem)
3423 Attr (VirtualDom.mapAttribute fn htmlAttr)
3425 TransformComponent fl trans ->
3426 TransformComponent fl trans
3429unwrapDecorations : List (Attribute Never Never) -> List Style
3430unwrapDecorations attrs =
3431 case List.foldl unwrapDecsHelper ( [], Untransformed ) attrs of
3432 ( styles, transform ) ->
3433 Transform transform :: styles
3436unwrapDecsHelper attr ( styles, trans ) =
3437 case removeNever attr of
3438 StyleClass _ style ->
3439 ( style :: styles, trans )
3441 TransformComponent flag component ->
3442 ( styles, composeTransformation trans component )
3448removeNever : Attribute Never Never -> Attribute () msg
3450 mapAttrFromStyle Basics.never style
3453tag : String -> Style -> Style
3456 Single class prop val ->
3457 Single (label ++ "-" ++ class) prop val
3459 Colored class prop val ->
3460 Colored (label ++ "-" ++ class) prop val
3462 Style class props ->
3463 Style (label ++ "-" ++ class) props
3465 Transparency class o ->
3466 Transparency (label ++ "-" ++ class) o
3472onlyStyles : Attribute aligned msg -> Maybe Style
3475 StyleClass _ style ->
3483{- Font Adjustments -}
3486convertAdjustment adjustment =
3502 ((ascender - newBaseline) / 2) + newBaseline
3505 ((ascender - descender) / 2) + descender
3508 [ adjustment.capital
3509 , adjustment.baseline
3510 , adjustment.descender
3511 , adjustment.lowercase
3515 Maybe.withDefault adjustment.capital (List.maximum lines)
3518 Maybe.withDefault adjustment.descender (List.minimum lines)
3522 |> List.filter (\x -> x /= descender)
3524 |> Maybe.withDefault adjustment.baseline
3530 1 / (ascender - newBaseline)
3533 1 / (ascender - descender)
3538 -- (oldMiddle - newFullMiddle) * 2
3541 adjust fullSize (ascender - descender) fullVertical
3543 adjust capitalSize (ascender - newBaseline) capitalVertical
3547adjust size height vertical =
3548 { vertical = vertical
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list