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 VirtualDom.node "style" [] [ VirtualDom.text Internal.Style.rules ]
1823 NoStaticStyleSheet ->
1827 VirtualDom.node "elm-ui-static-rules" [ VirtualDom.property "rules" (Encode.string Internal.Style.rules) ] []
1830addWhen ifThis x to =
1840This doesn't reduce equivalent attributes completely.
1843filter : List (Attribute aligned msg) -> List (Attribute aligned msg)
1847 (\x ( found, has ) ->
1858 StyleClass _ style ->
1862 if Set.member "width" has then
1866 ( x :: found, Set.insert "width" has )
1869 if Set.member "height" has then
1873 ( x :: found, Set.insert "height" has )
1875 Describe description ->
1876 if Set.member "described" has then
1880 ( x :: found, Set.insert "described" has )
1882 Nearby location elem ->
1886 if Set.member "align-x" has then
1890 ( x :: found, Set.insert "align-x" has )
1893 if Set.member "align-y" has then
1897 ( x :: found, Set.insert "align-y" has )
1899 TransformComponent _ _ ->
1900 if Set.member "transform" has then
1904 ( x :: found, Set.insert "transform" has )
1925get : List (Attribute aligned msg) -> (Attribute aligned msg -> Bool) -> List (Attribute aligned msg)
1941 = Spaced String Int Int
1945 = Padding String Int Int Int Int
1948extractSpacingAndPadding : List (Attribute aligned msg) -> ( Maybe Padding, Maybe Spacing )
1949extractSpacingAndPadding attrs =
1951 (\attr ( pad, spacing ) ->
1958 StyleClass _ (PaddingStyle name t r b l) ->
1959 Just (Padding name t r b l)
1969 StyleClass _ (SpacingStyle name x y) ->
1970 Just (Spaced name x y)
1976 ( Nothing, Nothing )
1980getSpacing : List (Attribute aligned msg) -> ( Int, Int ) -> ( Int, Int )
1981getSpacing attrs default =
1991 StyleClass _ (SpacingStyle _ x y) ->
1998 |> Maybe.withDefault default
2001getWidth : List (Attribute aligned msg) -> Maybe Length
2021getHeight : List (Attribute aligned msg) -> Maybe Length
2041textElementClasses : String
2047 ++ classes.widthContent
2049 ++ classes.heightContent
2052textElement : String -> VirtualDom.Node msg
2055 [ Html.Attributes.class
2061textElementFillClasses : String
2062textElementFillClasses =
2067 ++ classes.widthFill
2069 ++ classes.heightFill
2072textElementFill : String -> VirtualDom.Node msg
2073textElementFill str =
2075 [ Html.Attributes.class
2076 textElementFillClasses
2083 | Keyed (List ( String, x ))
2091 Styled { styles, html } ->
2092 html (mode styles) asEl
2102renderRoot : List Option -> List (Attribute aligned msg) -> Element msg -> VirtualDom.Node msg
2103renderRoot optionList attributes child =
2106 optionsToRecord optionList
2109 case options.mode of
2110 NoStaticStyleSheet ->
2114 StaticRootAndDynamic options
2116 element asEl div attributes (Unkeyed [ child ])
2117 |> toHtml embedStyle
2122 | NoStaticStyleSheet
2126type alias OptionRecord =
2127 { hover : HoverSetting
2128 , focus : FocusStyle
2140 = HoverOption HoverSetting
2141 | FocusStyleOption FocusStyle
2142 | RenderModeOption RenderMode
2145type alias FocusStyle =
2146 { borderColor : Maybe Color
2147 , shadow : Maybe Shadow
2148 , backgroundColor : Maybe Color
2154 , offset : ( Int, Int )
2160rootStyle : List (Attribute aligned msg)
2164 [ Typeface "Open Sans"
2165 , Typeface "Helvetica"
2166 , Typeface "Verdana"
2170 [ StyleClass Flag.bgColor (Colored ("bg-" ++ formatColorClass (Rgba 1 1 1 0)) "background-color" (Rgba 1 1 1 0))
2171 , StyleClass Flag.fontColor (Colored ("fc-" ++ formatColorClass (Rgba 0 0 0 1)) "color" (Rgba 0 0 0 1))
2172 , StyleClass Flag.fontSize (FontSize 20)
2173 , StyleClass Flag.fontFamily <|
2174 FontFamily (List.foldl renderFontClassName "font-" families)
2179renderFontClassName : Font -> String -> String
2180renderFontClassName font current =
2198 ImportFont name url ->
2204 FontWith { name } ->
2215renderFocusStyle focus =
2216 [ Style (Internal.Style.dot classes.focusedWithin ++ ":focus-within")
2217 (List.filterMap identity
2218 [ Maybe.map (\color -> Property "border-color" (formatColor color)) focus.borderColor
2219 , Maybe.map (\color -> Property "background-color" (formatColor color)) focus.backgroundColor
2222 Property "box-shadow"
2224 { color = shadow.color
2227 |> Tuple.mapFirst toFloat
2228 |> Tuple.mapSecond toFloat
2238 , Just <| Property "outline" "none"
2241 , Style (Internal.Style.dot classes.any ++ ":focus .focusable, " ++ Internal.Style.dot classes.any ++ ".focusable:focus")
2242 (List.filterMap identity
2243 [ Maybe.map (\color -> Property "border-color" (formatColor color)) focus.borderColor
2244 , Maybe.map (\color -> Property "background-color" (formatColor color)) focus.backgroundColor
2247 Property "box-shadow"
2249 { color = shadow.color
2252 |> Tuple.mapFirst toFloat
2253 |> Tuple.mapSecond toFloat
2255 , blur = toFloat shadow.blur
2256 , size = toFloat shadow.size
2261 , Just <| Property "outline" "none"
2267focusDefaultStyle : { backgroundColor : Maybe Color, borderColor : Maybe Color, shadow : Maybe Shadow }
2269 { backgroundColor = Nothing
2270 , borderColor = Nothing
2274 Rgba (155 / 255) (203 / 255) 1 1
2282optionsToRecord : List Option -> OptionRecord
2283optionsToRecord options =
2285 combine opt record =
2287 HoverOption hoverable ->
2288 case record.hover of
2290 { record | hover = Just hoverable }
2295 FocusStyleOption focusStyle ->
2296 case record.focus of
2298 { record | focus = Just focusStyle }
2303 RenderModeOption renderMode ->
2306 { record | mode = Just renderMode }
2313 case record.hover of
2320 case record.focus of
2344toStyleSheet : OptionRecord -> List Style -> VirtualDom.Node msg
2345toStyleSheet options styleSheet =
2346 case options.mode of
2348 VirtualDom.node "style" [] [ VirtualDom.text (toStyleSheetString options styleSheet) ]
2350 NoStaticStyleSheet ->
2351 VirtualDom.node "style" [] [ VirtualDom.text (toStyleSheetString options styleSheet) ]
2354 VirtualDom.node "elm-ui-rules"
2355 [ VirtualDom.property "rules"
2356 (encodeStyles options styleSheet)
2361renderTopLevelValues rules =
2366 Just ("@import url('" ++ url ++ "');")
2371 -- Just ("@import url('" ++ x ++ "');")
2378 List.map Tuple.first rules
2380 fontImports ( name, typefaces ) =
2383 String.join "\n" (List.filterMap withImport typefaces)
2387 fontAdjustments ( name, typefaces ) =
2388 case typefaceAdjustment typefaces of
2391 (List.map (renderNullAdjustmentRule name) allNames)
2395 (List.map (renderFontAdjustmentRule name adjustment) allNames)
2397 String.join "\n" (List.map fontImports rules)
2398 ++ String.join "\n" (List.map fontAdjustments rules)
2401renderNullAdjustmentRule fontToAdjust otherFontName =
2404 if fontToAdjust == otherFontName then
2408 otherFontName ++ " ." ++ fontToAdjust
2415 ++ classes.sizeByCapital
2420 ++ classes.sizeByCapital
2422 [ ( "line-height", "1" )
2428 ++ classes.sizeByCapital
2430 ++ Internal.Style.classes.text
2434 ++ classes.sizeByCapital
2436 ++ Internal.Style.classes.text
2438 [ ( "vertical-align", "0" )
2439 , ( "line-height", "1" )
2444fontRule name modifier ( parentAdj, textAdjustment ) =
2463 ++ Internal.Style.classes.text
2469 ++ Internal.Style.classes.text
2475renderFontAdjustmentRule fontToAdjust ( full, capital ) otherFontName =
2478 if fontToAdjust == otherFontName then
2482 otherFontName ++ " ." ++ fontToAdjust
2485 (fontRule name classes.sizeByCapital capital ++ fontRule name classes.fullSize full)
2488bracket selector rules =
2490 renderPair ( name, val ) =
2491 name ++ ": " ++ val ++ ";"
2493 selector ++ " {" ++ String.join "" (List.map renderPair rules) ++ "}"
2496fontAdjustmentRules converted =
2497 ( [ ( "display", "block" )
2499 , [ ( "display", "inline-block" )
2500 , ( "line-height", String.fromFloat converted.height )
2501 , ( "vertical-align", String.fromFloat converted.vertical ++ "em" )
2502 , ( "font-size", String.fromFloat converted.size ++ "em" )
2507typefaceAdjustment typefaces =
2514 case with.adjustment of
2520 ( fontAdjustmentRules
2521 (.full (convertAdjustment adjustment))
2522 , fontAdjustmentRules
2523 (.capital (convertAdjustment adjustment))
2548 "\"" ++ name ++ "\""
2550 ImportFont name url ->
2551 "\"" ++ name ++ "\""
2553 FontWith { name } ->
2554 "\"" ++ name ++ "\""
2559 FontFamily name typefaces ->
2560 Just ( name, typefaces )
2566renderProps force (Property key val) existing =
2568 existing ++ "\n " ++ key ++ ": " ++ val ++ " !important;"
2571 existing ++ "\n " ++ key ++ ": " ++ val ++ ";"
2574encodeStyles options stylesheet =
2580 renderStyleRule options style Nothing
2582 ( getStyleName style, Encode.list Encode.string styled )
2587toStyleSheetString : OptionRecord -> List Style -> String
2588toStyleSheetString options stylesheet =
2590 combine style rendered =
2591 { rules = rendered.rules ++ renderStyleRule options style Nothing
2593 case topLevelValue style of
2598 topLevel :: rendered.topLevel
2601 case List.foldl combine { topLevel = [], rules = [] } stylesheet of
2602 { topLevel, rules } ->
2603 renderTopLevelValues topLevel ++ String.concat rules
2606renderStyle : OptionRecord -> Maybe PseudoClass -> String -> List Property -> List String
2607renderStyle options maybePseudo selector props =
2610 [ selector ++ "{" ++ List.foldl (renderProps False) "" props ++ "\n}" ]
2615 case options.hover of
2620 [ selector ++ "-hv {" ++ List.foldl (renderProps True) "" props ++ "\n}" ]
2623 [ selector ++ "-hv:hover {" ++ List.foldl (renderProps False) "" props ++ "\n}" ]
2628 List.foldl (renderProps False) "" props
2638 ++ "-fs:not(.focus) {"
2648 , ".focusable-parent:focus ~ "
2659 [ selector ++ "-act:active {" ++ List.foldl (renderProps False) "" props ++ "\n}" ]
2662renderStyleRule : OptionRecord -> Style -> Maybe PseudoClass -> List String
2663renderStyleRule options rule maybePseudo =
2665 Style selector props ->
2666 renderStyle options maybePseudo selector props
2668 Shadows name prop ->
2672 [ Property "box-shadow" prop
2675 Transparency name transparency ->
2685 [ Property "opacity" (String.fromFloat opacity)
2691 (".font-size-" ++ String.fromInt i)
2692 [ Property "font-size" (String.fromInt i ++ "px")
2695 FontFamily name typefaces ->
2699 |> List.filterMap renderVariants
2703 [ Property "font-family"
2705 |> List.map fontName
2708 , Property "font-feature-settings" features
2709 , Property "font-variant"
2710 (if List.any hasSmallCaps typefaces then
2723 Single class prop val ->
2730 Colored class prop color ->
2734 [ Property prop (formatColor color)
2737 SpacingStyle cls x y ->
2743 String.fromFloat (toFloat x / 2) ++ "px"
2746 String.fromFloat (toFloat y / 2) ++ "px"
2749 String.fromInt x ++ "px"
2752 String.fromInt y ++ "px"
2755 "." ++ Internal.Style.classes.row
2758 "." ++ Internal.Style.classes.wrapped ++ row
2761 "." ++ Internal.Style.classes.column
2764 "." ++ Internal.Style.classes.page
2767 "." ++ Internal.Style.classes.paragraph
2770 "." ++ Internal.Style.classes.alignLeft
2773 "." ++ Internal.Style.classes.alignRight
2776 "." ++ Internal.Style.classes.any
2779 "." ++ Internal.Style.classes.single
2782 [ renderStyle options maybePseudo (class ++ row ++ " > " ++ any ++ " + " ++ any) [ Property "margin-left" xPx ]
2784 -- margins don't apply to last element of normal, unwrapped rows
2785 -- , renderStyle options maybePseudo (class ++ row ++ " > " ++ any ++ ":first-child") [ Property "margin" "0" ]
2786 -- For wrapped rows, margins always apply because we handle "canceling out" the other margins manually in the element.
2787 , renderStyle options
2789 (class ++ wrappedRow ++ " > " ++ any)
2790 [ Property "margin" (halfY ++ " " ++ halfX)
2793 -- , renderStyle options maybePseudo
2794 -- (class ++ wrappedRow ++ " > " ++ any ++ ":last-child")
2795 -- [ Property "margin-right" "0"
2798 , renderStyle options maybePseudo (class ++ column ++ " > " ++ any ++ " + " ++ any) [ Property "margin-top" yPx ]
2799 , renderStyle options maybePseudo (class ++ page ++ " > " ++ any ++ " + " ++ any) [ Property "margin-top" yPx ]
2800 , renderStyle options maybePseudo (class ++ page ++ " > " ++ left) [ Property "margin-right" xPx ]
2801 , renderStyle options maybePseudo (class ++ page ++ " > " ++ right) [ Property "margin-left" xPx ]
2802 , renderStyle options
2804 (class ++ paragraph)
2805 [ Property "line-height" ("calc(1em + " ++ String.fromInt y ++ "px)")
2807 , renderStyle options
2809 ("textarea" ++ any ++ class)
2810 [ Property "line-height" ("calc(1em + " ++ String.fromInt y ++ "px)")
2811 , Property "height" ("calc(100% + " ++ String.fromInt y ++ "px)")
2814 -- , renderStyle options
2816 -- (class ++ paragraph ++ " > " ++ any)
2817 -- [ Property "margin-right" xPx
2818 -- , Property "margin-bottom" yPx
2820 , renderStyle options
2822 (class ++ paragraph ++ " > " ++ left)
2823 [ Property "margin-right" xPx
2825 , renderStyle options
2827 (class ++ paragraph ++ " > " ++ right)
2828 [ Property "margin-left" xPx
2830 , renderStyle options
2832 (class ++ paragraph ++ "::after")
2833 [ Property "content" "''"
2834 , Property "display" "block"
2835 , Property "height" "0"
2836 , Property "width" "0"
2837 , Property "margin-top" (String.fromInt (-1 * (y // 2)) ++ "px")
2839 , renderStyle options
2841 (class ++ paragraph ++ "::before")
2842 [ Property "content" "''"
2843 , Property "display" "block"
2844 , Property "height" "0"
2845 , Property "width" "0"
2846 , Property "margin-bottom" (String.fromInt (-1 * (y // 2)) ++ "px")
2850 PaddingStyle cls top right bottom left ->
2859 [ Property "padding"
2862 ++ String.fromInt right
2864 ++ String.fromInt bottom
2866 ++ String.fromInt left
2871 BorderWidth cls top right bottom left ->
2880 [ Property "border-width"
2883 ++ String.fromInt right
2885 ++ String.fromInt bottom
2887 ++ String.fromInt left
2892 GridTemplateStyle template ->
2896 ++ String.join "-" (List.map lengthClassName template.rows)
2898 ++ String.join "-" (List.map lengthClassName template.columns)
2900 ++ lengthClassName (Tuple.first template.spacing)
2902 ++ lengthClassName (Tuple.second template.spacing)
2905 toGridLength (Tuple.second template.spacing)
2908 toGridLength (Tuple.first template.spacing)
2911 toGridLengthHelper Nothing Nothing x
2913 toGridLengthHelper minimum maximum x =
2916 String.fromInt px ++ "px"
2919 case ( minimum, maximum ) of
2920 ( Nothing, Nothing ) ->
2923 ( Just minSize, Nothing ) ->
2924 "minmax(" ++ String.fromInt minSize ++ "px, " ++ "max-content)"
2926 ( Nothing, Just maxSize ) ->
2927 "minmax(max-content, " ++ String.fromInt maxSize ++ "px)"
2929 ( Just minSize, Just maxSize ) ->
2930 "minmax(" ++ String.fromInt minSize ++ "px, " ++ String.fromInt maxSize ++ "px)"
2933 case ( minimum, maximum ) of
2934 ( Nothing, Nothing ) ->
2935 String.fromInt i ++ "fr"
2937 ( Just minSize, Nothing ) ->
2938 "minmax(" ++ String.fromInt minSize ++ "px, " ++ String.fromInt i ++ "fr" ++ "fr)"
2940 ( Nothing, Just maxSize ) ->
2941 "minmax(max-content, " ++ String.fromInt maxSize ++ "px)"
2943 ( Just minSize, Just maxSize ) ->
2944 "minmax(" ++ String.fromInt minSize ++ "px, " ++ String.fromInt maxSize ++ "px)"
2947 toGridLengthHelper (Just m) maximum len
2950 toGridLengthHelper minimum (Just m) len
2954 |> List.map toGridLength
2955 |> String.join ySpacing
2956 |> (\x -> "-ms-grid-columns: " ++ x ++ ";")
2960 |> List.map toGridLength
2961 |> String.join ySpacing
2962 |> (\x -> "-ms-grid-rows: " ++ x ++ ";")
2965 class ++ "{" ++ msColumns ++ msRows ++ "}"
2969 |> List.map toGridLength
2971 |> (\x -> "grid-template-columns: " ++ x ++ ";")
2975 |> List.map toGridLength
2977 |> (\x -> "grid-template-rows: " ++ x ++ ";")
2980 "grid-column-gap:" ++ toGridLength (Tuple.first template.spacing) ++ ";"
2983 "grid-row-gap:" ++ toGridLength (Tuple.second template.spacing) ++ ";"
2986 class ++ "{" ++ columns ++ rows ++ gapX ++ gapY ++ "}"
2989 "@supports (display:grid) {" ++ modernGrid ++ "}"
2995 GridPosition position ->
2999 ++ String.fromInt position.row
3001 ++ String.fromInt position.col
3003 ++ String.fromInt position.width
3005 ++ String.fromInt position.height
3010 ++ String.fromInt position.row
3012 , "-ms-grid-row-span: "
3013 ++ String.fromInt position.height
3015 , "-ms-grid-column: "
3016 ++ String.fromInt position.col
3018 , "-ms-grid-column-span: "
3019 ++ String.fromInt position.width
3024 class ++ "{" ++ msPosition ++ "}"
3029 ++ String.fromInt position.row
3031 ++ String.fromInt (position.row + position.height)
3034 ++ String.fromInt position.col
3036 ++ String.fromInt (position.col + position.width)
3041 class ++ "{" ++ modernPosition ++ "}"
3044 "@supports (display:grid) {" ++ modernGrid ++ "}"
3050 PseudoSelector class styles ->
3052 renderPseudoRule style =
3053 renderStyleRule options style (Just class)
3055 List.concatMap renderPseudoRule styles
3057 Transform transform ->
3060 transformValue transform
3063 transformClass transform
3065 case ( class, val ) of
3066 ( Just cls, Just v ) ->
3070 [ Property "transform"
3078lengthClassName : Length -> String
3082 String.fromInt px ++ "px"
3088 String.fromInt i ++ "fr"
3091 "min" ++ String.fromInt min ++ lengthClassName len
3094 "max" ++ String.fromInt max ++ lengthClassName len
3097formatDropShadow shadow =
3099 [ String.fromFloat (Tuple.first shadow.offset) ++ "px"
3100 , String.fromFloat (Tuple.second shadow.offset) ++ "px"
3101 , String.fromFloat shadow.blur ++ "px"
3102 , formatColor shadow.color
3106formatTextShadow shadow =
3108 [ String.fromFloat (Tuple.first shadow.offset) ++ "px"
3109 , String.fromFloat (Tuple.second shadow.offset) ++ "px"
3110 , String.fromFloat shadow.blur ++ "px"
3111 , formatColor shadow.color
3115textShadowClass shadow =
3118 , floatClass (Tuple.first shadow.offset) ++ "px"
3119 , floatClass (Tuple.second shadow.offset) ++ "px"
3120 , floatClass shadow.blur ++ "px"
3121 , formatColorClass shadow.color
3125formatBoxShadow shadow =
3127 List.filterMap identity
3128 [ if shadow.inset then
3133 , Just <| String.fromFloat (Tuple.first shadow.offset) ++ "px"
3134 , Just <| String.fromFloat (Tuple.second shadow.offset) ++ "px"
3135 , Just <| String.fromFloat shadow.blur ++ "px"
3136 , Just <| String.fromFloat shadow.size ++ "px"
3137 , Just <| formatColor shadow.color
3141boxShadowClass shadow =
3143 [ if shadow.inset then
3148 , floatClass (Tuple.first shadow.offset) ++ "px"
3149 , floatClass (Tuple.second shadow.offset) ++ "px"
3150 , floatClass shadow.blur ++ "px"
3151 , floatClass shadow.size ++ "px"
3152 , formatColorClass shadow.color
3156floatClass : Float -> String
3158 String.fromInt (round (x * 255))
3161formatColor : Color -> String
3162formatColor (Rgba red green blue alpha) =
3164 ++ String.fromInt (round (red * 255))
3165 ++ ("," ++ String.fromInt (round (green * 255)))
3166 ++ ("," ++ String.fromInt (round (blue * 255)))
3167 ++ ("," ++ String.fromFloat alpha ++ ")")
3170formatColorClass : Color -> String
3171formatColorClass (Rgba red green blue alpha) =
3182 "spacing-" ++ String.fromInt x ++ "-" ++ String.fromInt y
3185paddingName top right bottom left =
3187 ++ String.fromInt top
3189 ++ String.fromInt right
3191 ++ String.fromInt bottom
3193 ++ String.fromInt left
3196getStyleName : Style -> String
3202 Transparency name o ->
3208 FontFamily name _ ->
3212 "font-size-" ++ String.fromInt i
3217 Colored class _ _ ->
3220 SpacingStyle cls x y ->
3223 PaddingStyle cls top right bottom left ->
3226 BorderWidth cls top right bottom left ->
3229 GridTemplateStyle template ->
3231 ++ String.join "-" (List.map lengthClassName template.rows)
3233 ++ String.join "-" (List.map lengthClassName template.columns)
3235 ++ lengthClassName (Tuple.first template.spacing)
3237 ++ lengthClassName (Tuple.second template.spacing)
3241 ++ String.fromInt pos.row
3243 ++ String.fromInt pos.col
3245 ++ String.fromInt pos.width
3247 ++ String.fromInt pos.height
3249 PseudoSelector selector subStyle ->
3264 case getStyleName sty of
3269 styleName ++ "-" ++ name
3275 Maybe.withDefault "" (transformClass x)
3282asGrid : LayoutContext
3287asRow : LayoutContext
3292asColumn : LayoutContext
3302asParagraph : LayoutContext
3307asTextColumn : LayoutContext
3316map : (msg -> msg1) -> Element msg -> Element msg1
3321 { styles = styled.styles
3322 , html = \add context -> VirtualDom.map fn <| styled.html add context
3326 Unstyled (VirtualDom.map fn << html)
3335mapAttr : (msg -> msg1) -> Attribute aligned msg -> Attribute aligned msg1
3341 Describe description ->
3342 Describe description
3359 StyleClass flag style ->
3360 StyleClass flag style
3362 Nearby location elem ->
3363 Nearby location (map fn elem)
3366 Attr (VirtualDom.mapAttribute fn htmlAttr)
3368 TransformComponent fl trans ->
3369 TransformComponent fl trans
3372mapAttrFromStyle : (msg -> msg1) -> Attribute Never msg -> Attribute () msg1
3373mapAttrFromStyle fn attr =
3378 Describe description ->
3379 Describe description
3393 -- invalidation key "border-color" as opposed to "border-color-10-10-10" that will be the key for the class
3397 StyleClass flag style ->
3398 StyleClass flag style
3400 Nearby location elem ->
3401 Nearby location (map fn elem)
3404 Attr (VirtualDom.mapAttribute fn htmlAttr)
3406 TransformComponent fl trans ->
3407 TransformComponent fl trans
3410unwrapDecorations : List (Attribute Never Never) -> List Style
3411unwrapDecorations attrs =
3412 case List.foldl unwrapDecsHelper ( [], Untransformed ) attrs of
3413 ( styles, transform ) ->
3414 Transform transform :: styles
3417unwrapDecsHelper attr ( styles, trans ) =
3418 case removeNever attr of
3419 StyleClass _ style ->
3420 ( style :: styles, trans )
3422 TransformComponent flag component ->
3423 ( styles, composeTransformation trans component )
3429removeNever : Attribute Never Never -> Attribute () msg
3431 mapAttrFromStyle Basics.never style
3434tag : String -> Style -> Style
3437 Single class prop val ->
3438 Single (label ++ "-" ++ class) prop val
3440 Colored class prop val ->
3441 Colored (label ++ "-" ++ class) prop val
3443 Style class props ->
3444 Style (label ++ "-" ++ class) props
3446 Transparency class o ->
3447 Transparency (label ++ "-" ++ class) o
3453onlyStyles : Attribute aligned msg -> Maybe Style
3456 StyleClass _ style ->
3464{- Font Adjustments -}
3467convertAdjustment adjustment =
3483 ((ascender - newBaseline) / 2) + newBaseline
3486 ((ascender - descender) / 2) + descender
3489 [ adjustment.capital
3490 , adjustment.baseline
3491 , adjustment.descender
3492 , adjustment.lowercase
3496 Maybe.withDefault adjustment.capital (List.maximum lines)
3499 Maybe.withDefault adjustment.descender (List.minimum lines)
3503 |> List.filter (\x -> x /= descender)
3505 |> Maybe.withDefault adjustment.baseline
3511 1 / (ascender - newBaseline)
3514 1 / (ascender - descender)
3519 -- (oldMiddle - newFullMiddle) * 2
3522 adjust fullSize (ascender - descender) fullVertical
3524 adjust capitalSize (ascender - newBaseline) capitalVertical
3528adjust size height vertical =
3529 { 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