@@ -0,0 +1,3564 @@
1+module Internal.Model exposing
30+ , TransformComponent(..)
47+ , composeTransformation
55+ , extractSpacingAndPadding
65+ , gatherAttrRecursive
87+ , reduceStylesRecursive
89+ , renderFontClassName
111+import Html.Attributes
113+import Internal.Flag as Flag exposing (Flag)
114+import Internal.Style exposing (classes, dot)
115+import Json.Encode as Encode
116+import Set exposing (Set)
121+ = Unstyled (LayoutContext -> VirtualDom.Node msg)
123+ { styles : List Style
124+ , html : EmbedStyle -> LayoutContext -> VirtualDom.Node msg
132+ | StaticRootAndDynamic OptionRecord (List Style)
133+ | OnlyDynamic OptionRecord (List Style)
136+noStyleSheet : EmbedStyle
152+ | Aligned (Maybe HAlign) (Maybe VAlign)
168+ = Style String (List Property)
170+ | FontFamily String (List Font)
172+ -- classname, prop, value
173+ | Single String String String
174+ | Colored String String Color
175+ | SpacingStyle String Int Int
176+ | BorderWidth String Int Int Int Int
177+ | PaddingStyle String Float Float Float Float
179+ { spacing : ( Length, Length )
180+ , columns : List Length
181+ , rows : List Length
189+ | Transform Transformation
190+ | PseudoSelector PseudoClass (List Style)
191+ | Transparency String Float
192+ | Shadows String String
198+ -- translate, scale, rotate
199+ | FullTransform XYZ XYZ XYZ Angle
209+type alias Adjustment =
222+ | ImportFont String String
225+ , adjustment : Maybe Adjustment
226+ , variants : List Variant
231+ = VariantActive String
233+ | VariantIndexed String Int
238+ VariantActive name ->
239+ "\"" ++ name ++ "\""
242+ "\"" ++ name ++ "\" 0"
244+ VariantIndexed name index ->
245+ "\"" ++ name ++ "\" " ++ String.fromInt index
250+ VariantActive name ->
256+ VariantIndexed name index ->
257+ name ++ "-" ++ String.fromInt index
260+renderVariants typeface =
263+ Just (String.join ", " (List.map renderVariant font.variants))
271+ VariantActive name ->
277+ VariantIndexed name index ->
278+ name == "smcp" && index == 1
281+hasSmallCaps typeface =
284+ List.any isSmallCaps font.variants
291+ = Property String String
295+ ( Float, Float, Float )
302+type Attribute aligned msg
304+ | Attr (VirtualDom.Attribute msg)
305+ | Describe Description
306+ -- invalidation key and literal class
308+ -- invalidation key "border-color" as opposed to "border-color-10-10-10" that will be the key for the class
309+ | StyleClass Flag Style
314+ | Nearby Location (Element msg)
315+ | TransformComponent Flag TransformComponent
318+type TransformComponent
366+ = Rgba Float Float Float Float
372+ | Embedded String String
375+type NearbyChildren msg
377+ | ChildrenBehind (List (Html.Html msg))
378+ | ChildrenInFront (List (Html.Html msg))
379+ | ChildrenBehindAndInFront (List (Html.Html msg)) (List (Html.Html msg))
386+type alias Gathered msg =
388+ , attributes : List (VirtualDom.Attribute msg)
389+ , styles : List Style
390+ , children : NearbyChildren msg
395+htmlClass : String -> Attribute aligned msg
397+ Attr <| Html.Attributes.class cls
401+unstyled : VirtualDom.Node msg -> Element msg
406+finalizeNode has node attributes children embedMode parentContext =
408+ createNode nodeName attrs =
411+ VirtualDom.keyedNode nodeName
417+ OnlyDynamic opts styles ->
418+ embedKeyed False opts styles keyed
420+ StaticRootAndDynamic opts styles ->
421+ embedKeyed True opts styles keyed
433+ VirtualDom.node nodeName
440+ OnlyDynamic opts styles ->
441+ embedWith False opts styles unkeyed
443+ StaticRootAndDynamic opts styles ->
444+ embedWith True opts styles unkeyed
450+ createNode "div" attributes
452+ NodeName nodeName ->
453+ createNode nodeName attributes
455+ Embedded nodeName internal ->
456+ VirtualDom.node nodeName
458+ [ createNode internal
459+ [ Html.Attributes.class
460+ (classes.any ++ " " ++ classes.single)
464+ case parentContext of
466+ if Flag.present Flag.widthFill has && not (Flag.present Flag.widthBetween has) then
469+ else if Flag.present Flag.alignRight has then
471+ [ Html.Attributes.class
476+ , classes.contentCenterY
477+ , classes.alignContainerRight
483+ else if Flag.present Flag.centerX has then
485+ [ Html.Attributes.class
490+ , classes.contentCenterY
491+ , classes.alignContainerCenterX
501+ if Flag.present Flag.heightFill has && not (Flag.present Flag.heightBetween has) then
504+ else if Flag.present Flag.centerY has then
506+ [ Html.Attributes.class
511+ , classes.alignContainerCenterY
517+ else if Flag.present Flag.alignBottom has then
519+ [ Html.Attributes.class
524+ , classes.alignContainerBottom
537+embedWith static opts styles children =
541+ |> List.foldl reduceStyles ( Set.empty, renderFocusStyle opts.focus )
543+ -- |> reduceStylesRecursive Set.empty [ ]) --renderFocusStyle opts.focus ]
545+ |> toStyleSheet opts
549+ :: dynamicStyleSheet
557+embedKeyed static opts styles children =
561+ |> List.foldl reduceStyles ( Set.empty, renderFocusStyle opts.focus )
563+ -- |> reduceStylesRecursive Set.empty [ ]) --renderFocusStyle opts.focus ]
565+ |> toStyleSheet opts
568+ ( "static-stylesheet", staticRoot opts )
569+ :: ( "dynamic-stylesheet"
575+ ( "dynamic-stylesheet"
581+reduceStylesRecursive : Set String -> List Style -> List Style -> List Style
582+reduceStylesRecursive cache found styles =
587+ head :: remaining ->
592+ if Set.member styleName cache then
593+ reduceStylesRecursive cache found remaining
596+ reduceStylesRecursive (Set.insert styleName cache) (head :: found) remaining
599+reduceStyles : Style -> ( Set String, List Style ) -> ( Set String, List Style )
600+reduceStyles style (( cache, existing ) as nevermind) =
605+ if Set.member styleName cache then
609+ ( Set.insert styleName cache
614+sortedReduce styles =
616+ -- |> List.map (\x -> ( getStyleName x, x ))
617+ |> List.sortBy getStyleName
618+ |> reduceRecursiveCalcName []
621+reduceRecursiveCalcName : List Style -> List Style -> List Style
622+reduceRecursiveCalcName found styles =
630+ headOfList :: other :: remaining ->
631+ if headOfList /= other then
632+ reduceRecursiveCalcName (headOfList :: found) (other :: remaining)
635+ reduceRecursiveCalcName found (other :: remaining)
638+reduceRecursive : List Style -> List ( String, Style ) -> List Style
639+reduceRecursive found styles =
644+ ( _, headOfList ) :: [] ->
647+ ( headOfListName, headOfList ) :: ( otherName, other ) :: remaining ->
648+ if headOfListName /= otherName then
649+ reduceRecursive (headOfList :: found) (( otherName, other ) :: remaining)
652+ reduceRecursive found (( otherName, other ) :: remaining)
655+addNodeName : String -> NodeName -> NodeName
656+addNodeName newNode old =
662+ Embedded name newNode
668+alignXName : HAlign -> String
672+ classes.alignedHorizontally ++ " " ++ classes.alignLeft
675+ classes.alignedHorizontally ++ " " ++ classes.alignRight
678+ classes.alignedHorizontally ++ " " ++ classes.alignCenterX
681+alignYName : VAlign -> String
685+ classes.alignedVertically ++ " " ++ classes.alignTop
688+ classes.alignedVertically ++ " " ++ classes.alignBottom
691+ classes.alignedVertically ++ " " ++ classes.alignCenterY
694+transformClass transform =
699+ Moved ( x, y, z ) ->
708+ FullTransform ( tx, ty, tz ) ( sx, sy, sz ) ( ox, oy, oz ) angle ->
732+transformValue transform =
737+ Moved ( x, y, z ) ->
740+ ++ String.fromFloat x
742+ ++ String.fromFloat y
744+ ++ String.fromFloat z
747+ FullTransform ( tx, ty, tz ) ( sx, sy, sz ) ( ox, oy, oz ) angle ->
751+ ++ String.fromFloat tx
753+ ++ String.fromFloat ty
755+ ++ String.fromFloat tz
760+ ++ String.fromFloat sx
762+ ++ String.fromFloat sy
764+ ++ String.fromFloat sz
769+ ++ String.fromFloat ox
771+ ++ String.fromFloat oy
773+ ++ String.fromFloat oz
775+ ++ String.fromFloat angle
778+ Just <| translate ++ " " ++ scale ++ " " ++ rotate
781+composeTransformation transform component =
798+ FullTransform ( 0, 0, 0 ) ( 1, 1, 1 ) xyz angle
801+ FullTransform ( 0, 0, 0 ) xyz ( 0, 0, 1 ) 0
803+ Moved (( x, y, z ) as moved) ->
806+ Moved ( newX, y, z )
809+ Moved ( x, newY, z )
812+ Moved ( x, y, newZ )
818+ FullTransform moved ( 1, 1, 1 ) xyz angle
821+ FullTransform moved scale ( 0, 0, 1 ) 0
823+ FullTransform (( x, y, z ) as moved) scaled origin angle ->
826+ FullTransform ( newX, y, z ) scaled origin angle
829+ FullTransform ( x, newY, z ) scaled origin angle
832+ FullTransform ( x, y, newZ ) scaled origin angle
835+ FullTransform newMove scaled origin angle
837+ Rotate newOrigin newAngle ->
838+ FullTransform moved scaled newOrigin newAngle
841+ FullTransform moved newScale origin angle
844+skippable flag style =
845+ if flag == Flag.borderWidth then
881+ PaddingStyle name t r b l ->
882+ t == b && t == r && t == l && t >= 0 && t <= 24
884+ -- SpacingStyle _ _ _ ->
886+ -- FontFamily _ _ ->
892+gatherAttrRecursive :
898+ -> List (VirtualDom.Attribute msg)
899+ -> NearbyChildren msg
900+ -> List (Attribute aligned msg)
902+gatherAttrRecursive classes node has transform styles attrs children elementAttrs =
903+ case elementAttrs of
905+ case transformClass transform of
907+ { attributes = Html.Attributes.class classes :: attrs
910+ , children = children
915+ { attributes = Html.Attributes.class (classes ++ " " ++ class) :: attrs
916+ , styles = Transform transform :: styles
918+ , children = children
922+ attribute :: remaining ->
925+ gatherAttrRecursive classes node has transform styles attrs children remaining
927+ Class flag exactClassName ->
928+ if Flag.present flag has then
929+ gatherAttrRecursive classes node has transform styles attrs children remaining
932+ gatherAttrRecursive (exactClassName ++ " " ++ classes) node (Flag.add flag has) transform styles attrs children remaining
934+ Attr actualAttribute ->
935+ gatherAttrRecursive classes node has transform styles (actualAttribute :: attrs) children remaining
937+ StyleClass flag style ->
938+ if Flag.present flag has then
939+ gatherAttrRecursive classes node has transform styles attrs children remaining
941+ else if skippable flag style then
942+ gatherAttrRecursive (getStyleName style ++ " " ++ classes)
952+ gatherAttrRecursive (getStyleName style ++ " " ++ classes)
961+ TransformComponent flag component ->
962+ gatherAttrRecursive classes
965+ (composeTransformation transform component)
972+ if Flag.present Flag.width has then
973+ gatherAttrRecursive classes node has transform styles attrs children remaining
978+ gatherAttrRecursive ((Internal.Style.classes.widthExact ++ " width-px-" ++ String.fromInt px) ++ " " ++ classes)
980+ (Flag.add Flag.width has)
982+ (Single ("width-px-" ++ String.fromInt px) "width" (String.fromInt px ++ "px") :: styles)
988+ gatherAttrRecursive (classes ++ " " ++ Internal.Style.classes.widthContent)
990+ (Flag.add Flag.widthContent (Flag.add Flag.width has))
998+ if portion == 1 then
999+ gatherAttrRecursive (classes ++ " " ++ Internal.Style.classes.widthFill)
1001+ (Flag.add Flag.widthFill (Flag.add Flag.width has))
1009+ gatherAttrRecursive (classes ++ " " ++ Internal.Style.classes.widthFillPortion ++ " width-fill-" ++ String.fromInt portion)
1011+ (Flag.add Flag.widthFill (Flag.add Flag.width has))
1014+ (Internal.Style.classes.any
1016+ ++ Internal.Style.classes.row
1018+ ++ (Internal.Style.dot <| "width-fill-" ++ String.fromInt portion)
1021+ (String.fromInt (portion * 100000))
1030+ ( addToFlags, newClass, newStyles ) =
1033+ gatherAttrRecursive (classes ++ " " ++ newClass)
1035+ (Flag.merge addToFlags (Flag.add Flag.width has))
1037+ (newStyles ++ styles)
1043+ if Flag.present Flag.height has then
1044+ gatherAttrRecursive classes node has transform styles attrs children remaining
1051+ String.fromInt px ++ "px"
1054+ "height-px-" ++ val
1056+ gatherAttrRecursive (Internal.Style.classes.heightExact ++ " " ++ name ++ " " ++ classes)
1058+ (Flag.add Flag.height has)
1060+ (Single name "height " val :: styles)
1066+ gatherAttrRecursive (Internal.Style.classes.heightContent ++ " " ++ classes)
1068+ (Flag.add Flag.heightContent (Flag.add Flag.height has))
1076+ if portion == 1 then
1077+ gatherAttrRecursive (Internal.Style.classes.heightFill ++ " " ++ classes)
1079+ (Flag.add Flag.heightFill (Flag.add Flag.height has))
1087+ gatherAttrRecursive (classes ++ " " ++ (Internal.Style.classes.heightFillPortion ++ " height-fill-" ++ String.fromInt portion))
1089+ (Flag.add Flag.heightFill (Flag.add Flag.height has))
1092+ (Internal.Style.classes.any
1094+ ++ Internal.Style.classes.column
1096+ ++ (Internal.Style.dot <| "height-fill-" ++ String.fromInt portion)
1099+ (String.fromInt (portion * 100000))
1108+ ( addToFlags, newClass, newStyles ) =
1109+ renderHeight height
1111+ gatherAttrRecursive (classes ++ " " ++ newClass)
1113+ (Flag.merge addToFlags (Flag.add Flag.height has))
1115+ (newStyles ++ styles)
1120+ Describe description ->
1121+ case description of
1123+ gatherAttrRecursive classes (addNodeName "main" node) has transform styles attrs children remaining
1126+ gatherAttrRecursive classes (addNodeName "nav" node) has transform styles attrs children remaining
1129+ gatherAttrRecursive classes (addNodeName "footer" node) has transform styles attrs children remaining
1132+ gatherAttrRecursive classes (addNodeName "aside" node) has transform styles attrs children remaining
1136+ gatherAttrRecursive classes (addNodeName "h1" node) has transform styles attrs children remaining
1139+ gatherAttrRecursive classes (addNodeName ("h" ++ String.fromInt i) node) has transform styles attrs children remaining
1142+ gatherAttrRecursive classes (addNodeName "h6" node) has transform styles attrs children remaining
1145+ -- previously we rendered a <p> tag, though apparently this invalidates the html if it has <div>s inside.
1146+ -- Since we can't guaranteee that there are no divs, we need another strategy.
1147+ -- While it's not documented in many places, there apparently is a paragraph aria role
1148+ -- https://github.com/w3c/aria/blob/11f85f41a5b621fdbe85fc9bcdcd270e653a48ba/common/script/roleInfo.js
1149+ -- Though we'll need to wait till it gets released in an official wai-aria spec to use it.
1150+ -- If it's used at the moment, then Lighthouse complains (likely rightfully) that role paragraph is not recognized.
1151+ gatherAttrRecursive
1162+ gatherAttrRecursive classes node has transform styles (VirtualDom.attribute "role" "button" :: attrs) children remaining
1165+ gatherAttrRecursive classes node has transform styles (VirtualDom.attribute "aria-label" label :: attrs) children remaining
1168+ gatherAttrRecursive classes node has transform styles (VirtualDom.attribute "aria-live" "polite" :: attrs) children remaining
1171+ gatherAttrRecursive classes node has transform styles (VirtualDom.attribute "aria-live" "assertive" :: attrs) children remaining
1173+ Nearby location elem ->
1187+ styles ++ styled.styles
1189+ gatherAttrRecursive
1196+ (addNearbyElement location elem children)
1200+ if Flag.present Flag.xAlign has then
1201+ gatherAttrRecursive classes node has transform styles attrs children remaining
1204+ gatherAttrRecursive (alignXName x ++ " " ++ classes)
1207+ |> Flag.add Flag.xAlign
1211+ Flag.add Flag.centerX flags
1214+ Flag.add Flag.alignRight flags
1227+ if Flag.present Flag.yAlign has then
1228+ gatherAttrRecursive classes node has transform styles attrs children remaining
1231+ gatherAttrRecursive (alignYName y ++ " " ++ classes)
1233+ (Flag.add Flag.yAlign has
1237+ Flag.add Flag.centerY flags
1240+ Flag.add Flag.alignBottom flags
1253+addNearbyElement location elem existing =
1256+ nearbyElement location elem
1259+ NoNearbyChildren ->
1262+ ChildrenBehind [ nearby ]
1265+ ChildrenInFront [ nearby ]
1267+ ChildrenBehind existingBehind ->
1270+ ChildrenBehind (nearby :: existingBehind)
1273+ ChildrenBehindAndInFront existingBehind [ nearby ]
1275+ ChildrenInFront existingInFront ->
1278+ ChildrenBehindAndInFront [ nearby ] existingInFront
1281+ ChildrenInFront (nearby :: existingInFront)
1283+ ChildrenBehindAndInFront existingBehind existingInFront ->
1286+ ChildrenBehindAndInFront (nearby :: existingBehind) existingInFront
1289+ ChildrenBehindAndInFront existingBehind (nearby :: existingInFront)
1292+nearbyElement location elem =
1294+ [ Html.Attributes.class <|
1298+ [ Internal.Style.classes.nearby
1299+ , Internal.Style.classes.single
1300+ , Internal.Style.classes.above
1305+ [ Internal.Style.classes.nearby
1306+ , Internal.Style.classes.single
1307+ , Internal.Style.classes.below
1312+ [ Internal.Style.classes.nearby
1313+ , Internal.Style.classes.single
1314+ , Internal.Style.classes.onRight
1319+ [ Internal.Style.classes.nearby
1320+ , Internal.Style.classes.single
1321+ , Internal.Style.classes.onLeft
1326+ [ Internal.Style.classes.nearby
1327+ , Internal.Style.classes.single
1328+ , Internal.Style.classes.inFront
1333+ [ Internal.Style.classes.nearby
1334+ , Internal.Style.classes.single
1335+ , Internal.Style.classes.behind
1349+ styled.html NoStyleSheet asEl
1357+ , Internal.Style.classes.widthExact ++ " width-px-" ++ String.fromInt px
1358+ , [ Single ("width-px-" ++ String.fromInt px) "width" (String.fromInt px ++ "px") ]
1362+ ( Flag.add Flag.widthContent Flag.none
1363+ , Internal.Style.classes.widthContent
1368+ if portion == 1 then
1369+ ( Flag.add Flag.widthFill Flag.none
1370+ , Internal.Style.classes.widthFill
1375+ ( Flag.add Flag.widthFill Flag.none
1376+ , Internal.Style.classes.widthFillPortion ++ " width-fill-" ++ String.fromInt portion
1378+ (Internal.Style.classes.any
1380+ ++ Internal.Style.classes.row
1382+ ++ (Internal.Style.dot <| "width-fill-" ++ String.fromInt portion)
1385+ (String.fromInt (portion * 100000))
1393+ ++ String.fromInt minSize
1399+ (String.fromInt minSize ++ "px")
1401+ ( newFlag, newAttrs, newStyle ) =
1404+ ( Flag.add Flag.widthBetween newFlag
1405+ , cls ++ " " ++ newAttrs
1406+ , style :: newStyle
1412+ "max-width-" ++ String.fromInt maxSize
1417+ (String.fromInt maxSize ++ "px")
1419+ ( newFlag, newAttrs, newStyle ) =
1422+ ( Flag.add Flag.widthBetween newFlag
1423+ , cls ++ " " ++ newAttrs
1424+ , style :: newStyle
1436+ "height-px-" ++ val
1439+ , Internal.Style.classes.heightExact ++ " " ++ name
1440+ , [ Single name "height" (val ++ "px") ]
1444+ ( Flag.add Flag.heightContent Flag.none
1445+ , Internal.Style.classes.heightContent
1450+ if portion == 1 then
1451+ ( Flag.add Flag.heightFill Flag.none
1452+ , Internal.Style.classes.heightFill
1457+ ( Flag.add Flag.heightFill Flag.none
1458+ , Internal.Style.classes.heightFillPortion ++ " height-fill-" ++ String.fromInt portion
1460+ (Internal.Style.classes.any
1462+ ++ Internal.Style.classes.column
1464+ ++ (Internal.Style.dot <| "height-fill-" ++ String.fromInt portion)
1467+ (String.fromInt (portion * 100000))
1475+ ++ String.fromInt minSize
1481+ -- This needs to be !important because we're using `min-height: min-content`
1482+ -- to correct for safari's incorrect implementation of flexbox.
1483+ (String.fromInt minSize ++ "px !important")
1485+ ( newFlag, newAttrs, newStyle ) =
1488+ ( Flag.add Flag.heightBetween newFlag
1489+ , cls ++ " " ++ newAttrs
1490+ , style :: newStyle
1496+ "max-height-" ++ String.fromInt maxSize
1501+ (String.fromInt maxSize ++ "px")
1503+ ( newFlag, newAttrs, newStyle ) =
1506+ ( Flag.add Flag.heightBetween newFlag
1507+ , cls ++ " " ++ newAttrs
1508+ , style :: newStyle
1513+ classes.any ++ " " ++ classes.row
1517+ classes.any ++ " " ++ classes.column
1521+ classes.any ++ " " ++ classes.single
1525+ classes.any ++ " " ++ classes.grid
1529+ classes.any ++ " " ++ classes.paragraph
1533+ classes.any ++ " " ++ classes.page
1536+contextClasses context =
1557+element : LayoutContext -> NodeName -> List (Attribute aligned msg) -> Children (Element msg) -> Element msg
1558+element context node attributes children =
1561+ |> gatherAttrRecursive (contextClasses context) node Flag.none untransformed [] [] NoNearbyChildren
1562+ |> createElement context children
1569+createElement : LayoutContext -> Children (Element msg) -> Gathered msg -> Element msg
1570+createElement context children rendered =
1572+ gather child ( htmls, existingStyles ) =
1575+ if context == asParagraph then
1576+ ( html context :: htmls
1581+ ( html context :: htmls
1586+ if context == asParagraph then
1587+ ( styled.html NoStyleSheet context :: htmls
1588+ , if List.isEmpty existingStyles then
1592+ styled.styles ++ existingStyles
1596+ ( styled.html NoStyleSheet context :: htmls
1597+ , if List.isEmpty existingStyles then
1601+ styled.styles ++ existingStyles
1605+ -- TEXT OPTIMIZATION
1606+ -- You can have raw text if the element is an el, and has `width-content` and `height-content`
1607+ -- Same if it's a column or row with one child and width-content, height-content
1608+ -- interferes with css grid
1609+ -- Maybe we could unpack text elements in a paragraph as well,
1610+ -- however, embedded elements that are larger than the line height will overlap with exisitng text.
1611+ -- I don't think that's what we want.
1618+ -- ( VirtualDom.text
1619+ -- (if context == asParagraph then
1625+ -- , existingStyles
1628+ ( (if context == asEl then
1629+ textElementFill str
1639+ ( htmls, existingStyles )
1641+ gatherKeyed ( key, child ) ( htmls, existingStyles ) =
1644+ if context == asParagraph then
1645+ ( ( key, html context ) :: htmls
1650+ ( ( key, html context ) :: htmls
1655+ if context == asParagraph then
1656+ ( ( key, styled.html NoStyleSheet context )
1658+ , if List.isEmpty existingStyles then
1662+ styled.styles ++ existingStyles
1666+ ( ( key, styled.html NoStyleSheet context ) :: htmls
1667+ , if List.isEmpty existingStyles then
1671+ styled.styles ++ existingStyles
1675+ -- TEXT OPTIMIZATION
1676+ -- You can have raw text if the element is an el, and has `width-content` and `height-content`
1677+ -- Same if it's a column or row with one child and width-content, height-content
1685+ -- , VirtualDom.text
1689+ -- , existingStyles
1693+ , if context == asEl then
1694+ textElementFill str
1704+ ( htmls, existingStyles )
1707+ Keyed keyedChildren ->
1708+ case List.foldr gatherKeyed ( [], [] ) keyedChildren of
1709+ ( keyed, styles ) ->
1712+ if List.isEmpty styles then
1716+ rendered.styles ++ styles
1721+ (finalizeNode rendered.has
1723+ rendered.attributes
1725+ (addKeyedChildren "nearby-element-pls" keyed rendered.children)
1732+ { styles = allStyles
1737+ rendered.attributes
1739+ (addKeyedChildren "nearby-element-pls" keyed rendered.children)
1743+ Unkeyed unkeyedChildren ->
1744+ case List.foldr gather ( [], [] ) unkeyedChildren of
1745+ ( unkeyed, styles ) ->
1748+ if List.isEmpty styles then
1752+ rendered.styles ++ styles
1760+ rendered.attributes
1761+ (Unkeyed (addChildren unkeyed rendered.children))
1767+ { styles = allStyles
1772+ rendered.attributes
1773+ (Unkeyed (addChildren unkeyed rendered.children))
1777+addChildren existing nearbyChildren =
1778+ case nearbyChildren of
1779+ NoNearbyChildren ->
1782+ ChildrenBehind behind ->
1785+ ChildrenInFront inFront ->
1786+ existing ++ inFront
1788+ ChildrenBehindAndInFront behind inFront ->
1789+ behind ++ existing ++ inFront
1792+addKeyedChildren key existing nearbyChildren =
1793+ case nearbyChildren of
1794+ NoNearbyChildren ->
1797+ ChildrenBehind behind ->
1798+ List.map (\x -> ( key, x )) behind ++ existing
1800+ ChildrenInFront inFront ->
1801+ existing ++ List.map (\x -> ( key, x )) inFront
1803+ ChildrenBehindAndInFront behind inFront ->
1804+ List.map (\x -> ( key, x )) behind
1806+ ++ List.map (\x -> ( key, x )) inFront
1814+ { hover = AllowHover
1815+ , focus = focusDefaultStyle
1820+staticRoot : OptionRecord -> VirtualDom.Node msg
1824+ -- wrap the style node in a div to prevent `Dark Reader` from blowin up the dom.
1825+ VirtualDom.node "div"
1827+ [ VirtualDom.node "style" [] [ VirtualDom.text Internal.Style.rules ] ]
1829+ NoStaticStyleSheet ->
1833+ VirtualDom.node "elm-ui-static-rules" [ VirtualDom.property "rules" (Encode.string Internal.Style.rules) ] []
1836+addWhen ifThis x to =
1846+This doesn't reduce equivalent attributes completely.
1849+filter : List (Attribute aligned msg) -> List (Attribute aligned msg)
1853+ (\x ( found, has ) ->
1859+ ( x :: found, has )
1862+ ( x :: found, has )
1864+ StyleClass _ style ->
1865+ ( x :: found, has )
1868+ if Set.member "width" has then
1872+ ( x :: found, Set.insert "width" has )
1875+ if Set.member "height" has then
1879+ ( x :: found, Set.insert "height" has )
1881+ Describe description ->
1882+ if Set.member "described" has then
1886+ ( x :: found, Set.insert "described" has )
1888+ Nearby location elem ->
1889+ ( x :: found, has )
1892+ if Set.member "align-x" has then
1896+ ( x :: found, Set.insert "align-x" has )
1899+ if Set.member "align-y" has then
1903+ ( x :: found, Set.insert "align-y" has )
1905+ TransformComponent _ _ ->
1906+ if Set.member "transform" has then
1910+ ( x :: found, Set.insert "transform" has )
1931+get : List (Attribute aligned msg) -> (Attribute aligned msg -> Bool) -> List (Attribute aligned msg)
1947+ = Spaced String Int Int
1951+ = Padding String Float Float Float Float
1954+extractSpacingAndPadding : List (Attribute aligned msg) -> ( Maybe Padding, Maybe Spacing )
1955+extractSpacingAndPadding attrs =
1957+ (\attr ( pad, spacing ) ->
1964+ StyleClass _ (PaddingStyle name t r b l) ->
1965+ Just (Padding name t r b l)
1975+ StyleClass _ (SpacingStyle name x y) ->
1976+ Just (Spaced name x y)
1982+ ( Nothing, Nothing )
1986+getSpacing : List (Attribute aligned msg) -> ( Int, Int ) -> ( Int, Int )
1987+getSpacing attrs default =
1997+ StyleClass _ (SpacingStyle _ x y) ->
2004+ |> Maybe.withDefault default
2007+getWidth : List (Attribute aligned msg) -> Maybe Length
2027+getHeight : List (Attribute aligned msg) -> Maybe Length
2047+textElementClasses : String
2048+textElementClasses =
2053+ ++ classes.widthContent
2055+ ++ classes.heightContent
2058+textElement : String -> VirtualDom.Node msg
2061+ [ Html.Attributes.class
2067+textElementFillClasses : String
2068+textElementFillClasses =
2073+ ++ classes.widthFill
2075+ ++ classes.heightFill
2078+textElementFill : String -> VirtualDom.Node msg
2079+textElementFill str =
2081+ [ Html.Attributes.class
2082+ textElementFillClasses
2089+ | Keyed (List ( String, x ))
2097+ Styled { styles, html } ->
2098+ html (mode styles) asEl
2108+renderRoot : List Option -> List (Attribute aligned msg) -> Element msg -> VirtualDom.Node msg
2109+renderRoot optionList attributes child =
2112+ optionsToRecord optionList
2115+ case options.mode of
2116+ NoStaticStyleSheet ->
2117+ OnlyDynamic options
2120+ StaticRootAndDynamic options
2122+ element asEl div attributes (Unkeyed [ child ])
2123+ |> toHtml embedStyle
2128+ | NoStaticStyleSheet
2132+type alias OptionRecord =
2133+ { hover : HoverSetting
2134+ , focus : FocusStyle
2135+ , mode : RenderMode
2146+ = HoverOption HoverSetting
2147+ | FocusStyleOption FocusStyle
2148+ | RenderModeOption RenderMode
2151+type alias FocusStyle =
2152+ { borderColor : Maybe Color
2153+ , shadow : Maybe Shadow
2154+ , backgroundColor : Maybe Color
2160+ , offset : ( Int, Int )
2166+rootStyle : List (Attribute aligned msg)
2170+ [ Typeface "Open Sans"
2171+ , Typeface "Helvetica"
2172+ , Typeface "Verdana"
2176+ [ StyleClass Flag.bgColor (Colored ("bg-" ++ formatColorClass (Rgba 1 1 1 0)) "background-color" (Rgba 1 1 1 0))
2177+ , StyleClass Flag.fontColor (Colored ("fc-" ++ formatColorClass (Rgba 0 0 0 1)) "color" (Rgba 0 0 0 1))
2178+ , StyleClass Flag.fontSize (FontSize 20)
2179+ , StyleClass Flag.fontFamily <|
2180+ FontFamily (List.foldl renderFontClassName "font-" families)
2185+renderFontClassName : Font -> String -> String
2186+renderFontClassName font current =
2204+ ImportFont name url ->
2210+ FontWith { name } ->
2221+renderFocusStyle focus =
2222+ [ Style (Internal.Style.dot classes.focusedWithin ++ ":focus-within")
2223+ (List.filterMap identity
2224+ [ Maybe.map (\color -> Property "border-color" (formatColor color)) focus.borderColor
2225+ , Maybe.map (\color -> Property "background-color" (formatColor color)) focus.backgroundColor
2228+ Property "box-shadow"
2230+ { color = shadow.color
2233+ |> Tuple.mapFirst toFloat
2234+ |> Tuple.mapSecond toFloat
2237+ toFloat shadow.blur
2239+ toFloat shadow.size
2244+ , Just <| Property "outline" "none"
2248+ ((Internal.Style.dot classes.any ++ ":focus .focusable, ")
2249+ ++ (Internal.Style.dot classes.any ++ ".focusable:focus, ")
2250+ ++ (".ui-slide-bar:focus + " ++ Internal.Style.dot classes.any ++ " .focusable-thumb")
2252+ (List.filterMap identity
2253+ [ Maybe.map (\color -> Property "border-color" (formatColor color)) focus.borderColor
2254+ , Maybe.map (\color -> Property "background-color" (formatColor color)) focus.backgroundColor
2257+ Property "box-shadow"
2259+ { color = shadow.color
2262+ |> Tuple.mapFirst toFloat
2263+ |> Tuple.mapSecond toFloat
2265+ , blur = toFloat shadow.blur
2266+ , size = toFloat shadow.size
2271+ , Just <| Property "outline" "none"
2277+focusDefaultStyle : { backgroundColor : Maybe Color, borderColor : Maybe Color, shadow : Maybe Shadow }
2279+ { backgroundColor = Nothing
2280+ , borderColor = Nothing
2284+ Rgba (155 / 255) (203 / 255) 1 1
2285+ , offset = ( 0, 0 )
2292+optionsToRecord : List Option -> OptionRecord
2293+optionsToRecord options =
2295+ combine opt record =
2297+ HoverOption hoverable ->
2298+ case record.hover of
2300+ { record | hover = Just hoverable }
2305+ FocusStyleOption focusStyle ->
2306+ case record.focus of
2308+ { record | focus = Just focusStyle }
2313+ RenderModeOption renderMode ->
2314+ case record.mode of
2316+ { record | mode = Just renderMode }
2321+ andFinally record =
2323+ case record.hover of
2330+ case record.focus of
2337+ case record.mode of
2354+toStyleSheet : OptionRecord -> List Style -> VirtualDom.Node msg
2355+toStyleSheet options styleSheet =
2356+ case options.mode of
2358+ -- wrap the style node in a div to prevent `Dark Reader` from blowin up the dom.
2359+ VirtualDom.node "div"
2361+ [ VirtualDom.node "style"
2363+ [ VirtualDom.text (toStyleSheetString options styleSheet) ]
2366+ NoStaticStyleSheet ->
2367+ -- wrap the style node in a div to prevent `Dark Reader` from blowin up the dom.
2368+ VirtualDom.node "div"
2370+ [ VirtualDom.node "style"
2372+ [ VirtualDom.text (toStyleSheetString options styleSheet) ]
2376+ VirtualDom.node "elm-ui-rules"
2377+ [ VirtualDom.property "rules"
2378+ (encodeStyles options styleSheet)
2383+renderTopLevelValues rules =
2387+ ImportFont _ url ->
2388+ Just ("@import url('" ++ url ++ "');")
2390+ -- FontWith with ->
2391+ -- case with.url of
2393+ -- Just ("@import url('" ++ x ++ "');")
2400+ List.map Tuple.first rules
2402+ fontImports ( name, typefaces ) =
2405+ String.join "\n" (List.filterMap withImport typefaces)
2409+ fontAdjustments ( name, typefaces ) =
2410+ case typefaceAdjustment typefaces of
2413+ (List.map (renderNullAdjustmentRule name) allNames)
2417+ (List.map (renderFontAdjustmentRule name adjustment) allNames)
2419+ String.join "\n" (List.map fontImports rules)
2420+ ++ String.join "\n" (List.map fontAdjustments rules)
2423+renderNullAdjustmentRule fontToAdjust otherFontName =
2426+ if fontToAdjust == otherFontName then
2430+ otherFontName ++ " ." ++ fontToAdjust
2437+ ++ classes.sizeByCapital
2442+ ++ classes.sizeByCapital
2444+ [ ( "line-height", "1" )
2450+ ++ classes.sizeByCapital
2452+ ++ Internal.Style.classes.text
2456+ ++ classes.sizeByCapital
2458+ ++ Internal.Style.classes.text
2460+ [ ( "vertical-align", "0" )
2461+ , ( "line-height", "1" )
2466+fontRule name modifier ( parentAdj, textAdjustment ) =
2485+ ++ Internal.Style.classes.text
2491+ ++ Internal.Style.classes.text
2497+renderFontAdjustmentRule fontToAdjust ( full, capital ) otherFontName =
2500+ if fontToAdjust == otherFontName then
2504+ otherFontName ++ " ." ++ fontToAdjust
2507+ (fontRule name classes.sizeByCapital capital ++ fontRule name classes.fullSize full)
2510+bracket selector rules =
2512+ renderPair ( name, val ) =
2513+ name ++ ": " ++ val ++ ";"
2515+ selector ++ " {" ++ String.join "" (List.map renderPair rules) ++ "}"
2518+fontAdjustmentRules converted =
2519+ ( [ ( "display", "block" )
2521+ , [ ( "display", "inline-block" )
2522+ , ( "line-height", String.fromFloat converted.height )
2523+ , ( "vertical-align", String.fromFloat converted.vertical ++ "em" )
2524+ , ( "font-size", String.fromFloat converted.size ++ "em" )
2529+typefaceAdjustment typefaces =
2536+ case with.adjustment of
2542+ ( fontAdjustmentRules
2543+ (.full (convertAdjustment adjustment))
2544+ , fontAdjustmentRules
2545+ (.capital (convertAdjustment adjustment))
2570+ "\"" ++ name ++ "\""
2572+ ImportFont name url ->
2573+ "\"" ++ name ++ "\""
2575+ FontWith { name } ->
2576+ "\"" ++ name ++ "\""
2579+topLevelValue rule =
2581+ FontFamily name typefaces ->
2582+ Just ( name, typefaces )
2588+renderProps force (Property key val) existing =
2590+ existing ++ "\n " ++ key ++ ": " ++ val ++ " !important;"
2593+ existing ++ "\n " ++ key ++ ": " ++ val ++ ";"
2596+encodeStyles options stylesheet =
2602+ renderStyleRule options style Nothing
2604+ ( getStyleName style, Encode.list Encode.string styled )
2609+toStyleSheetString : OptionRecord -> List Style -> String
2610+toStyleSheetString options stylesheet =
2612+ combine style rendered =
2613+ { rules = rendered.rules ++ renderStyleRule options style Nothing
2615+ case topLevelValue style of
2620+ topLevel :: rendered.topLevel
2623+ case List.foldl combine { topLevel = [], rules = [] } stylesheet of
2624+ { topLevel, rules } ->
2627+ if String.contains ":hover" s then
2630+ else if String.contains ":focus" s then
2633+ else if String.contains ":active" s then
2639+ renderTopLevelValues topLevel ++ String.concat (List.sortBy ruleWeight rules)
2642+renderStyle : OptionRecord -> Maybe PseudoClass -> String -> List Property -> List String
2643+renderStyle options maybePseudo selector props =
2644+ case maybePseudo of
2646+ [ selector ++ "{" ++ List.foldl (renderProps False) "" props ++ "\n}" ]
2651+ case options.hover of
2656+ [ selector ++ "-hv {" ++ List.foldl (renderProps True) "" props ++ "\n}" ]
2659+ [ selector ++ "-hv:hover {" ++ List.foldl (renderProps False) "" props ++ "\n}" ]
2664+ List.foldl (renderProps False) "" props
2666+ [ selector ++ "-fs:focus {" ++ renderedProps ++ "\n}"
2667+ , ("." ++ classes.any ++ ":focus " ++ selector ++ "-fs {")
2670+ , (selector ++ "-fs:focus-within {")
2673+ , (".ui-slide-bar:focus + " ++ Internal.Style.dot classes.any ++ " .focusable-thumb" ++ selector ++ "-fs {")
2679+ [ selector ++ "-act:active {" ++ List.foldl (renderProps False) "" props ++ "\n}" ]
2682+renderStyleRule : OptionRecord -> Style -> Maybe PseudoClass -> List String
2683+renderStyleRule options rule maybePseudo =
2685+ Style selector props ->
2686+ renderStyle options maybePseudo selector props
2688+ Shadows name prop ->
2689+ renderStyle options
2692+ [ Property "box-shadow" prop
2695+ Transparency name transparency ->
2702+ renderStyle options
2705+ [ Property "opacity" (String.fromFloat opacity)
2709+ renderStyle options
2711+ (".font-size-" ++ String.fromInt i)
2712+ [ Property "font-size" (String.fromInt i ++ "px")
2715+ FontFamily name typefaces ->
2719+ |> List.filterMap renderVariants
2720+ |> String.join ", "
2723+ [ Property "font-family"
2725+ |> List.map fontName
2726+ |> String.join ", "
2728+ , Property "font-feature-settings" features
2729+ , Property "font-variant"
2730+ (if List.any hasSmallCaps typefaces then
2738+ renderStyle options
2743+ Single class prop val ->
2744+ renderStyle options
2747+ [ Property prop val
2750+ Colored class prop color ->
2751+ renderStyle options
2754+ [ Property prop (formatColor color)
2757+ SpacingStyle cls x y ->
2763+ String.fromFloat (toFloat x / 2) ++ "px"
2766+ String.fromFloat (toFloat y / 2) ++ "px"
2769+ String.fromInt x ++ "px"
2772+ String.fromInt y ++ "px"
2775+ "." ++ Internal.Style.classes.row
2778+ "." ++ Internal.Style.classes.wrapped ++ row
2781+ "." ++ Internal.Style.classes.column
2784+ "." ++ Internal.Style.classes.page
2787+ "." ++ Internal.Style.classes.paragraph
2790+ "." ++ Internal.Style.classes.alignLeft
2793+ "." ++ Internal.Style.classes.alignRight
2796+ "." ++ Internal.Style.classes.any
2799+ "." ++ Internal.Style.classes.single
2802+ [ renderStyle options maybePseudo (class ++ row ++ " > " ++ any ++ " + " ++ any) [ Property "margin-left" xPx ]
2804+ -- margins don't apply to last element of normal, unwrapped rows
2805+ -- , renderStyle options maybePseudo (class ++ row ++ " > " ++ any ++ ":first-child") [ Property "margin" "0" ]
2806+ -- For wrapped rows, margins always apply because we handle "canceling out" the other margins manually in the element.
2807+ , renderStyle options
2809+ (class ++ wrappedRow ++ " > " ++ any)
2810+ [ Property "margin" (halfY ++ " " ++ halfX)
2813+ -- , renderStyle options maybePseudo
2814+ -- (class ++ wrappedRow ++ " > " ++ any ++ ":last-child")
2815+ -- [ Property "margin-right" "0"
2818+ , renderStyle options maybePseudo (class ++ column ++ " > " ++ any ++ " + " ++ any) [ Property "margin-top" yPx ]
2819+ , renderStyle options maybePseudo (class ++ page ++ " > " ++ any ++ " + " ++ any) [ Property "margin-top" yPx ]
2820+ , renderStyle options maybePseudo (class ++ page ++ " > " ++ left) [ Property "margin-right" xPx ]
2821+ , renderStyle options maybePseudo (class ++ page ++ " > " ++ right) [ Property "margin-left" xPx ]
2822+ , renderStyle options
2824+ (class ++ paragraph)
2825+ [ Property "line-height" ("calc(1em + " ++ String.fromInt y ++ "px)")
2827+ , renderStyle options
2829+ ("textarea" ++ any ++ class)
2830+ [ Property "line-height" ("calc(1em + " ++ String.fromInt y ++ "px)")
2831+ , Property "height" ("calc(100% + " ++ String.fromInt y ++ "px)")
2834+ -- , renderStyle options
2836+ -- (class ++ paragraph ++ " > " ++ any)
2837+ -- [ Property "margin-right" xPx
2838+ -- , Property "margin-bottom" yPx
2840+ , renderStyle options
2842+ (class ++ paragraph ++ " > " ++ left)
2843+ [ Property "margin-right" xPx
2845+ , renderStyle options
2847+ (class ++ paragraph ++ " > " ++ right)
2848+ [ Property "margin-left" xPx
2850+ , renderStyle options
2852+ (class ++ paragraph ++ "::after")
2853+ [ Property "content" "''"
2854+ , Property "display" "block"
2855+ , Property "height" "0"
2856+ , Property "width" "0"
2857+ , Property "margin-top" (String.fromInt (-1 * (y // 2)) ++ "px")
2859+ , renderStyle options
2861+ (class ++ paragraph ++ "::before")
2862+ [ Property "content" "''"
2863+ , Property "display" "block"
2864+ , Property "height" "0"
2865+ , Property "width" "0"
2866+ , Property "margin-bottom" (String.fromInt (-1 * (y // 2)) ++ "px")
2870+ PaddingStyle cls top right bottom left ->
2876+ renderStyle options
2879+ [ Property "padding"
2880+ (String.fromFloat top
2882+ ++ String.fromFloat right
2884+ ++ String.fromFloat bottom
2886+ ++ String.fromFloat left
2891+ BorderWidth cls top right bottom left ->
2897+ renderStyle options
2900+ [ Property "border-width"
2901+ (String.fromInt top
2903+ ++ String.fromInt right
2905+ ++ String.fromInt bottom
2907+ ++ String.fromInt left
2912+ GridTemplateStyle template ->
2916+ ++ String.join "-" (List.map lengthClassName template.rows)
2918+ ++ String.join "-" (List.map lengthClassName template.columns)
2920+ ++ lengthClassName (Tuple.first template.spacing)
2922+ ++ lengthClassName (Tuple.second template.spacing)
2925+ toGridLength (Tuple.second template.spacing)
2928+ toGridLength (Tuple.first template.spacing)
2931+ toGridLengthHelper Nothing Nothing x
2933+ toGridLengthHelper minimum maximum x =
2936+ String.fromInt px ++ "px"
2939+ case ( minimum, maximum ) of
2940+ ( Nothing, Nothing ) ->
2943+ ( Just minSize, Nothing ) ->
2944+ "minmax(" ++ String.fromInt minSize ++ "px, " ++ "max-content)"
2946+ ( Nothing, Just maxSize ) ->
2947+ "minmax(max-content, " ++ String.fromInt maxSize ++ "px)"
2949+ ( Just minSize, Just maxSize ) ->
2950+ "minmax(" ++ String.fromInt minSize ++ "px, " ++ String.fromInt maxSize ++ "px)"
2953+ case ( minimum, maximum ) of
2954+ ( Nothing, Nothing ) ->
2955+ String.fromInt i ++ "fr"
2957+ ( Just minSize, Nothing ) ->
2958+ "minmax(" ++ String.fromInt minSize ++ "px, " ++ String.fromInt i ++ "fr" ++ "fr)"
2960+ ( Nothing, Just maxSize ) ->
2961+ "minmax(max-content, " ++ String.fromInt maxSize ++ "px)"
2963+ ( Just minSize, Just maxSize ) ->
2964+ "minmax(" ++ String.fromInt minSize ++ "px, " ++ String.fromInt maxSize ++ "px)"
2967+ toGridLengthHelper (Just m) maximum len
2970+ toGridLengthHelper minimum (Just m) len
2974+ |> List.map toGridLength
2975+ |> String.join ySpacing
2976+ |> (\x -> "-ms-grid-columns: " ++ x ++ ";")
2980+ |> List.map toGridLength
2981+ |> String.join ySpacing
2982+ |> (\x -> "-ms-grid-rows: " ++ x ++ ";")
2985+ class ++ "{" ++ msColumns ++ msRows ++ "}"
2989+ |> List.map toGridLength
2991+ |> (\x -> "grid-template-columns: " ++ x ++ ";")
2995+ |> List.map toGridLength
2997+ |> (\x -> "grid-template-rows: " ++ x ++ ";")
3000+ "grid-column-gap:" ++ toGridLength (Tuple.first template.spacing) ++ ";"
3003+ "grid-row-gap:" ++ toGridLength (Tuple.second template.spacing) ++ ";"
3006+ class ++ "{" ++ columns ++ rows ++ gapX ++ gapY ++ "}"
3009+ "@supports (display:grid) {" ++ modernGrid ++ "}"
3015+ GridPosition position ->
3019+ ++ String.fromInt position.row
3021+ ++ String.fromInt position.col
3023+ ++ String.fromInt position.width
3025+ ++ String.fromInt position.height
3030+ ++ String.fromInt position.row
3032+ , "-ms-grid-row-span: "
3033+ ++ String.fromInt position.height
3035+ , "-ms-grid-column: "
3036+ ++ String.fromInt position.col
3038+ , "-ms-grid-column-span: "
3039+ ++ String.fromInt position.width
3044+ class ++ "{" ++ msPosition ++ "}"
3049+ ++ String.fromInt position.row
3051+ ++ String.fromInt (position.row + position.height)
3054+ ++ String.fromInt position.col
3056+ ++ String.fromInt (position.col + position.width)
3061+ class ++ "{" ++ modernPosition ++ "}"
3064+ "@supports (display:grid) {" ++ modernGrid ++ "}"
3070+ PseudoSelector class styles ->
3072+ renderPseudoRule style =
3073+ renderStyleRule options style (Just class)
3075+ List.concatMap renderPseudoRule styles
3077+ Transform transform ->
3080+ transformValue transform
3083+ transformClass transform
3085+ case ( class, val ) of
3086+ ( Just cls, Just v ) ->
3087+ renderStyle options
3090+ [ Property "transform"
3098+lengthClassName : Length -> String
3102+ String.fromInt px ++ "px"
3108+ String.fromInt i ++ "fr"
3111+ "min" ++ String.fromInt min ++ lengthClassName len
3114+ "max" ++ String.fromInt max ++ lengthClassName len
3117+formatDropShadow shadow =
3119+ [ String.fromFloat (Tuple.first shadow.offset) ++ "px"
3120+ , String.fromFloat (Tuple.second shadow.offset) ++ "px"
3121+ , String.fromFloat shadow.blur ++ "px"
3122+ , formatColor shadow.color
3126+formatTextShadow shadow =
3128+ [ String.fromFloat (Tuple.first shadow.offset) ++ "px"
3129+ , String.fromFloat (Tuple.second shadow.offset) ++ "px"
3130+ , String.fromFloat shadow.blur ++ "px"
3131+ , formatColor shadow.color
3135+textShadowClass shadow =
3138+ , floatClass (Tuple.first shadow.offset) ++ "px"
3139+ , floatClass (Tuple.second shadow.offset) ++ "px"
3140+ , floatClass shadow.blur ++ "px"
3141+ , formatColorClass shadow.color
3145+formatBoxShadow shadow =
3147+ List.filterMap identity
3148+ [ if shadow.inset then
3153+ , Just <| String.fromFloat (Tuple.first shadow.offset) ++ "px"
3154+ , Just <| String.fromFloat (Tuple.second shadow.offset) ++ "px"
3155+ , Just <| String.fromFloat shadow.blur ++ "px"
3156+ , Just <| String.fromFloat shadow.size ++ "px"
3157+ , Just <| formatColor shadow.color
3161+boxShadowClass shadow =
3163+ [ if shadow.inset then
3168+ , floatClass (Tuple.first shadow.offset) ++ "px"
3169+ , floatClass (Tuple.second shadow.offset) ++ "px"
3170+ , floatClass shadow.blur ++ "px"
3171+ , floatClass shadow.size ++ "px"
3172+ , formatColorClass shadow.color
3176+floatClass : Float -> String
3178+ String.fromInt (round (x * 255))
3181+formatColor : Color -> String
3182+formatColor (Rgba red green blue alpha) =
3184+ ++ String.fromInt (round (red * 255))
3185+ ++ ("," ++ String.fromInt (round (green * 255)))
3186+ ++ ("," ++ String.fromInt (round (blue * 255)))
3187+ ++ ("," ++ String.fromFloat alpha ++ ")")
3190+formatColorClass : Color -> String
3191+formatColorClass (Rgba red green blue alpha) =
3194+ ++ floatClass green
3198+ ++ floatClass alpha
3202+ "spacing-" ++ String.fromInt x ++ "-" ++ String.fromInt y
3205+paddingName top right bottom left =
3207+ ++ String.fromInt top
3209+ ++ String.fromInt right
3211+ ++ String.fromInt bottom
3213+ ++ String.fromInt left
3216+paddingNameFloat top right bottom left =
3220+ ++ floatClass right
3222+ ++ floatClass bottom
3227+getStyleName : Style -> String
3228+getStyleName style =
3233+ Transparency name o ->
3239+ FontFamily name _ ->
3243+ "font-size-" ++ String.fromInt i
3245+ Single class _ _ ->
3248+ Colored class _ _ ->
3251+ SpacingStyle cls x y ->
3254+ PaddingStyle cls top right bottom left ->
3257+ BorderWidth cls top right bottom left ->
3260+ GridTemplateStyle template ->
3262+ ++ String.join "-" (List.map lengthClassName template.rows)
3264+ ++ String.join "-" (List.map lengthClassName template.columns)
3266+ ++ lengthClassName (Tuple.first template.spacing)
3268+ ++ lengthClassName (Tuple.second template.spacing)
3270+ GridPosition pos ->
3272+ ++ String.fromInt pos.row
3274+ ++ String.fromInt pos.col
3276+ ++ String.fromInt pos.width
3278+ ++ String.fromInt pos.height
3280+ PseudoSelector selector subStyle ->
3295+ case getStyleName sty of
3300+ styleName ++ "-" ++ name
3306+ Maybe.withDefault "" (transformClass x)
3313+asGrid : LayoutContext
3318+asRow : LayoutContext
3323+asColumn : LayoutContext
3328+asEl : LayoutContext
3333+asParagraph : LayoutContext
3338+asTextColumn : LayoutContext
3347+map : (msg -> msg1) -> Element msg -> Element msg1
3352+ { styles = styled.styles
3353+ , html = \add context -> VirtualDom.map fn <| styled.html add context
3357+ Unstyled (VirtualDom.map fn << html)
3366+mapAttr : (msg -> msg1) -> Attribute aligned msg -> Attribute aligned msg1
3372+ Describe description ->
3373+ Describe description
3390+ StyleClass flag style ->
3391+ StyleClass flag style
3393+ Nearby location elem ->
3394+ Nearby location (map fn elem)
3397+ Attr (VirtualDom.mapAttribute fn htmlAttr)
3399+ TransformComponent fl trans ->
3400+ TransformComponent fl trans
3403+mapAttrFromStyle : (msg -> msg1) -> Attribute Never msg -> Attribute () msg1
3404+mapAttrFromStyle fn attr =
3409+ Describe description ->
3410+ Describe description
3424+ -- invalidation key "border-color" as opposed to "border-color-10-10-10" that will be the key for the class
3428+ StyleClass flag style ->
3429+ StyleClass flag style
3431+ Nearby location elem ->
3432+ Nearby location (map fn elem)
3435+ Attr (VirtualDom.mapAttribute fn htmlAttr)
3437+ TransformComponent fl trans ->
3438+ TransformComponent fl trans
3441+unwrapDecorations : List (Attribute Never Never) -> List Style
3442+unwrapDecorations attrs =
3443+ case List.foldl unwrapDecsHelper ( [], Untransformed ) attrs of
3444+ ( styles, transform ) ->
3445+ Transform transform :: styles
3448+unwrapDecsHelper attr ( styles, trans ) =
3449+ case removeNever attr of
3450+ StyleClass _ style ->
3451+ ( style :: styles, trans )
3453+ TransformComponent flag component ->
3454+ ( styles, composeTransformation trans component )
3460+removeNever : Attribute Never Never -> Attribute () msg
3462+ mapAttrFromStyle Basics.never style
3465+tag : String -> Style -> Style
3468+ Single class prop val ->
3469+ Single (label ++ "-" ++ class) prop val
3471+ Colored class prop val ->
3472+ Colored (label ++ "-" ++ class) prop val
3474+ Style class props ->
3475+ Style (label ++ "-" ++ class) props
3477+ Transparency class o ->
3478+ Transparency (label ++ "-" ++ class) o
3484+onlyStyles : Attribute aligned msg -> Maybe Style
3487+ StyleClass _ style ->
3495+{- Font Adjustments -}
3498+convertAdjustment adjustment =
3514+ ((ascender - newBaseline) / 2) + newBaseline
3517+ ((ascender - descender) / 2) + descender
3520+ [ adjustment.capital
3521+ , adjustment.baseline
3522+ , adjustment.descender
3523+ , adjustment.lowercase
3527+ Maybe.withDefault adjustment.capital (List.maximum lines)
3530+ Maybe.withDefault adjustment.descender (List.minimum lines)
3534+ |> List.filter (\x -> x /= descender)
3536+ |> Maybe.withDefault adjustment.baseline
3542+ 1 / (ascender - newBaseline)
3545+ 1 / (ascender - descender)
3550+ -- (oldMiddle - newFullMiddle) * 2
3553+ adjust fullSize (ascender - descender) fullVertical
3555+ adjust capitalSize (ascender - newBaseline) capitalVertical
3559+adjust size height vertical =
3560+ { vertical = vertical