Vendor elm-ui.

This commit is contained in:
Dillon Kearns 2020-05-19 06:33:33 -07:00
parent 84fd44b922
commit 29deee3dc5
14 changed files with 11425 additions and 2 deletions

View File

@ -3,6 +3,7 @@
"source-directories": [
"src",
"../../src",
"vendor/elm-ui",
"gen"
],
"elm-version": "0.19.1",
@ -24,6 +25,7 @@
"elm/svg": "1.0.1",
"elm/time": "1.0.0",
"elm/url": "1.0.0",
"elm/virtual-dom": "1.0.2",
"elm-community/dict-extra": "2.4.0",
"elm-community/list-extra": "8.2.3",
"elm-community/result-extra": "2.3.0",
@ -31,7 +33,6 @@
"elm-explorations/markdown": "1.0.0",
"justinmimbs/date": "3.2.0",
"lukewestby/elm-string-interpolate": "1.0.4",
"mdgriffith/elm-ui": "1.1.5",
"miniBill/elm-codec": "1.2.0",
"noahzgordon/elm-color-extra": "1.0.2",
"pablohirafuji/elm-syntax-highlight": "3.2.0",
@ -44,7 +45,6 @@
"elm/file": "1.0.5",
"elm/random": "1.0.0",
"elm/regex": "1.0.0",
"elm/virtual-dom": "1.0.2",
"fredcy/elm-parseint": "2.0.1",
"justinmimbs/time-extra": "1.1.0",
"lazamar/dict-parser": "1.0.2",

1691
examples/docs/vendor/elm-ui/Element.elm vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,226 @@
module Element.Background exposing
( color, gradient
, image, uncropped, tiled, tiledX, tiledY
)
{-|
@docs color, gradient
# Images
@docs image, uncropped, tiled, tiledX, tiledY
**Note** if you want more control over a background image than is provided here, you should try just using a normal `Element.image` with something like `Element.behindContent`.
-}
import Element exposing (Attr, Attribute, Color)
import Internal.Flag as Flag
import Internal.Model as Internal
import VirtualDom
{-| -}
color : Color -> Attr decorative msg
color clr =
Internal.StyleClass Flag.bgColor (Internal.Colored ("bg-" ++ Internal.formatColorClass clr) "background-color" clr)
{-| Resize the image to fit the containing element while maintaining proportions and cropping the overflow.
-}
image : String -> Attribute msg
image src =
Internal.Attr (VirtualDom.style "background" ("url(\"" ++ src ++ "\") center / cover no-repeat"))
{-| A centered background image that keeps its natural proportions, but scales to fit the space.
-}
uncropped : String -> Attribute msg
uncropped src =
Internal.Attr (VirtualDom.style "background" ("url(\"" ++ src ++ "\") center / contain no-repeat"))
{-| Tile an image in the x and y axes.
-}
tiled : String -> Attribute msg
tiled src =
Internal.Attr (VirtualDom.style "background" ("url(\"" ++ src ++ "\") repeat"))
{-| Tile an image in the x axis.
-}
tiledX : String -> Attribute msg
tiledX src =
Internal.Attr (VirtualDom.style "background" ("url(\"" ++ src ++ "\") repeat-x"))
{-| Tile an image in the y axis.
-}
tiledY : String -> Attribute msg
tiledY src =
Internal.Attr (VirtualDom.style "background" ("url(\"" ++ src ++ "\") repeat-y"))
type Direction
= ToUp
| ToDown
| ToRight
| ToTopRight
| ToBottomRight
| ToLeft
| ToTopLeft
| ToBottomLeft
| ToAngle Float
type Step
= ColorStep Color
| PercentStep Float Color
| PxStep Int Color
{-| -}
step : Color -> Step
step =
ColorStep
{-| -}
percent : Float -> Color -> Step
percent =
PercentStep
{-| -}
px : Int -> Color -> Step
px =
PxStep
{-| A linear gradient.
First you need to specify what direction the gradient is going by providing an angle in radians. `0` is up and `pi` is down.
The colors will be evenly spaced.
-}
gradient :
{ angle : Float
, steps : List Color
}
-> Attr decorative msg
gradient { angle, steps } =
case steps of
[] ->
Internal.NoAttribute
clr :: [] ->
Internal.StyleClass Flag.bgColor
(Internal.Colored ("bg-" ++ Internal.formatColorClass clr) "background-color" clr)
_ ->
Internal.StyleClass Flag.bgGradient <|
Internal.Single ("bg-grad-" ++ (String.join "-" <| Internal.floatClass angle :: List.map Internal.formatColorClass steps))
"background-image"
("linear-gradient(" ++ (String.join ", " <| (String.fromFloat angle ++ "rad") :: List.map Internal.formatColor steps) ++ ")")
-- {-| -}
-- gradientWith : { direction : Direction, steps : List Step } -> Attribute msg
-- gradientWith { direction, steps } =
-- StyleClass <|
-- Single ("bg-gradient-" ++ (String.join "-" <| renderDirectionClass direction :: List.map renderStepClass steps))
-- "background"
-- ("linear-gradient(" ++ (String.join ", " <| renderDirection direction :: List.map renderStep steps) ++ ")")
-- {-| -}
-- renderStep : Step -> String
-- renderStep step =
-- case step of
-- ColorStep color ->
-- formatColor color
-- PercentStep percent color ->
-- formatColor color ++ " " ++ toString percent ++ "%"
-- PxStep px color ->
-- formatColor color ++ " " ++ toString px ++ "px"
-- {-| -}
-- renderStepClass : Step -> String
-- renderStepClass step =
-- case step of
-- ColorStep color ->
-- formatColorClass color
-- PercentStep percent color ->
-- formatColorClass color ++ "-" ++ floatClass percent ++ "p"
-- PxStep px color ->
-- formatColorClass color ++ "-" ++ toString px ++ "px"
-- toUp : Direction
-- toUp =
-- ToUp
-- toDown : Direction
-- toDown =
-- ToDown
-- toRight : Direction
-- toRight =
-- ToRight
-- toTopRight : Direction
-- toTopRight =
-- ToTopRight
-- toBottomRight : Direction
-- toBottomRight =
-- ToBottomRight
-- toLeft : Direction
-- toLeft =
-- ToLeft
-- toTopLeft : Direction
-- toTopLeft =
-- ToTopLeft
-- toBottomLeft : Direction
-- toBottomLeft =
-- ToBottomLeft
-- angle : Float -> Direction
-- angle rad =
-- ToAngle rad
-- renderDirection : Direction -> String
-- renderDirection dir =
-- case dir of
-- ToUp ->
-- "to top"
-- ToDown ->
-- "to bottom"
-- ToRight ->
-- "to right"
-- ToTopRight ->
-- "to top right"
-- ToBottomRight ->
-- "to bottom right"
-- ToLeft ->
-- "to left"
-- ToTopLeft ->
-- "to top left"
-- ToBottomLeft ->
-- "to bottom left"
-- ToAngle angle ->
-- toString angle ++ "rad"
-- renderDirectionClass : Direction -> String
-- renderDirectionClass dir =
-- case dir of
-- ToUp ->
-- "to-top"
-- ToDown ->
-- "to-bottom"
-- ToRight ->
-- "to-right"
-- ToTopRight ->
-- "to-top-right"
-- ToBottomRight ->
-- "to-bottom-right"
-- ToLeft ->
-- "to-left"
-- ToTopLeft ->
-- "to-top-left"
-- ToBottomLeft ->
-- "to-bottom-left"
-- ToAngle angle ->
-- floatClass angle ++ "rad"

View File

@ -0,0 +1,281 @@
module Element.Border exposing
( color
, width, widthXY, widthEach
, solid, dashed, dotted
, rounded, roundEach
, glow, innerGlow, shadow, innerShadow
)
{-|
@docs color
## Border Widths
@docs width, widthXY, widthEach
## Border Styles
@docs solid, dashed, dotted
## Rounded Corners
@docs rounded, roundEach
## Shadows
@docs glow, innerGlow, shadow, innerShadow
-}
import Element exposing (Attr, Attribute, Color)
import Internal.Flag as Flag
import Internal.Model as Internal
import Internal.Style as Style exposing (classes)
{-| -}
color : Color -> Attr decorative msg
color clr =
Internal.StyleClass
Flag.borderColor
(Internal.Colored
("bc-" ++ Internal.formatColorClass clr)
"border-color"
clr
)
{-| -}
width : Int -> Attribute msg
width v =
Internal.StyleClass
Flag.borderWidth
(Internal.BorderWidth
("b-" ++ String.fromInt v)
v
v
v
v
)
{-| Set horizontal and vertical borders.
-}
widthXY : Int -> Int -> Attribute msg
widthXY x y =
Internal.StyleClass
Flag.borderWidth
(Internal.BorderWidth
("b-"
++ String.fromInt x
++ "-"
++ String.fromInt y
)
y
x
y
x
)
{-| -}
widthEach :
{ bottom : Int
, left : Int
, right : Int
, top : Int
}
-> Attribute msg
widthEach { bottom, top, left, right } =
if top == bottom && left == right then
if top == right then
width top
else
widthXY left top
else
Internal.StyleClass Flag.borderWidth
(Internal.BorderWidth
("b-"
++ String.fromInt top
++ "-"
++ String.fromInt right
++ "-"
++ String.fromInt bottom
++ "-"
++ String.fromInt left
)
top
right
bottom
left
)
-- {-| No Borders
-- -}
-- none : Attribute msg
-- none =
-- Class "border" "border-none"
{-| -}
solid : Attribute msg
solid =
Internal.Class Flag.borderStyle classes.borderSolid
{-| -}
dashed : Attribute msg
dashed =
Internal.Class Flag.borderStyle classes.borderDashed
{-| -}
dotted : Attribute msg
dotted =
Internal.Class Flag.borderStyle classes.borderDotted
{-| Round all corners.
-}
rounded : Int -> Attribute msg
rounded radius =
Internal.StyleClass
Flag.borderRound
(Internal.Single
("br-" ++ String.fromInt radius)
"border-radius"
(String.fromInt radius ++ "px")
)
{-| -}
roundEach :
{ topLeft : Int
, topRight : Int
, bottomLeft : Int
, bottomRight : Int
}
-> Attribute msg
roundEach { topLeft, topRight, bottomLeft, bottomRight } =
Internal.StyleClass Flag.borderRound
(Internal.Single
("br-"
++ String.fromInt topLeft
++ "-"
++ String.fromInt topRight
++ String.fromInt bottomLeft
++ "-"
++ String.fromInt bottomRight
)
"border-radius"
(String.fromInt topLeft
++ "px "
++ String.fromInt topRight
++ "px "
++ String.fromInt bottomRight
++ "px "
++ String.fromInt bottomLeft
++ "px"
)
)
{-| A simple glow by specifying the color and size.
-}
glow : Color -> Float -> Attr decorative msg
glow clr size =
shadow
{ offset = ( 0, 0 )
, size = size
, blur = size * 2
, color = clr
}
{-| -}
innerGlow : Color -> Float -> Attr decorative msg
innerGlow clr size =
innerShadow
{ offset = ( 0, 0 )
, size = size
, blur = size * 2
, color = clr
}
{-| -}
shadow :
{ offset : ( Float, Float )
, size : Float
, blur : Float
, color : Color
}
-> Attr decorative msg
shadow almostShade =
let
shade =
{ inset = False
, offset = almostShade.offset
, size = almostShade.size
, blur = almostShade.blur
, color = almostShade.color
}
in
Internal.StyleClass Flag.shadows <|
Internal.Single
(Internal.boxShadowClass shade)
"box-shadow"
(Internal.formatBoxShadow shade)
{-| -}
innerShadow :
{ offset : ( Float, Float )
, size : Float
, blur : Float
, color : Color
}
-> Attr decorative msg
innerShadow almostShade =
let
shade =
{ inset = True
, offset = almostShade.offset
, size = almostShade.size
, blur = almostShade.blur
, color = almostShade.color
}
in
Internal.StyleClass Flag.shadows <|
Internal.Single
(Internal.boxShadowClass shade)
"box-shadow"
(Internal.formatBoxShadow shade)
-- {-| -}
-- shadow :
-- { offset : ( Float, Float )
-- , blur : Float
-- , size : Float
-- , color : Color
-- }
-- -> Attr decorative msg
-- shadow shade =
-- Internal.BoxShadow
-- { inset = False
-- , offset = shade.offset
-- , size = shade.size
-- , blur = shade.blur
-- , color = shade.color
-- }

View File

@ -0,0 +1,265 @@
module Element.Events exposing
( onClick, onDoubleClick, onMouseDown, onMouseUp, onMouseEnter, onMouseLeave, onMouseMove
, onFocus, onLoseFocus
-- , onClickCoords
-- , onClickPageCoords
-- , onClickScreenCoords
-- , onMouseCoords
-- , onMousePageCoords
-- , onMouseScreenCoords
)
{-|
## Mouse Events
@docs onClick, onDoubleClick, onMouseDown, onMouseUp, onMouseEnter, onMouseLeave, onMouseMove
## Focus Events
@docs onFocus, onLoseFocus
-}
import Element exposing (Attribute)
import Html.Events
import Internal.Model as Internal
import Json.Decode as Json
import VirtualDom
-- MOUSE EVENTS
{-| -}
onMouseDown : msg -> Attribute msg
onMouseDown =
Internal.Attr << Html.Events.onMouseDown
{-| -}
onMouseUp : msg -> Attribute msg
onMouseUp =
Internal.Attr << Html.Events.onMouseUp
{-| -}
onClick : msg -> Attribute msg
onClick =
Internal.Attr << Html.Events.onClick
{-| -}
onDoubleClick : msg -> Attribute msg
onDoubleClick =
Internal.Attr << Html.Events.onDoubleClick
{-| -}
onMouseEnter : msg -> Attribute msg
onMouseEnter =
Internal.Attr << Html.Events.onMouseEnter
{-| -}
onMouseLeave : msg -> Attribute msg
onMouseLeave =
Internal.Attr << Html.Events.onMouseLeave
{-| -}
onMouseMove : msg -> Attribute msg
onMouseMove msg =
on "mousemove" (Json.succeed msg)
-- onClickWith
-- { button = primary
-- , send = localCoords Button
-- }
-- type alias Click =
-- { button : Button
-- , send : Track
-- }
-- type Button = Primary | Secondary
-- type Track
-- = ElementCoords
-- | PageCoords
-- | ScreenCoords
-- |
{-| -}
onClickCoords : (Coords -> msg) -> Attribute msg
onClickCoords msg =
on "click" (Json.map msg localCoords)
{-| -}
onClickScreenCoords : (Coords -> msg) -> Attribute msg
onClickScreenCoords msg =
on "click" (Json.map msg screenCoords)
{-| -}
onClickPageCoords : (Coords -> msg) -> Attribute msg
onClickPageCoords msg =
on "click" (Json.map msg pageCoords)
{-| -}
onMouseCoords : (Coords -> msg) -> Attribute msg
onMouseCoords msg =
on "mousemove" (Json.map msg localCoords)
{-| -}
onMouseScreenCoords : (Coords -> msg) -> Attribute msg
onMouseScreenCoords msg =
on "mousemove" (Json.map msg screenCoords)
{-| -}
onMousePageCoords : (Coords -> msg) -> Attribute msg
onMousePageCoords msg =
on "mousemove" (Json.map msg pageCoords)
type alias Coords =
{ x : Int
, y : Int
}
screenCoords : Json.Decoder Coords
screenCoords =
Json.map2 Coords
(Json.field "screenX" Json.int)
(Json.field "screenY" Json.int)
{-| -}
localCoords : Json.Decoder Coords
localCoords =
Json.map2 Coords
(Json.field "offsetX" Json.int)
(Json.field "offsetY" Json.int)
pageCoords : Json.Decoder Coords
pageCoords =
Json.map2 Coords
(Json.field "pageX" Json.int)
(Json.field "pageY" Json.int)
-- FOCUS EVENTS
{-| -}
onLoseFocus : msg -> Attribute msg
onLoseFocus =
Internal.Attr << Html.Events.onBlur
{-| -}
onFocus : msg -> Attribute msg
onFocus =
Internal.Attr << Html.Events.onFocus
-- CUSTOM EVENTS
{-| Create a custom event listener. Normally this will not be necessary, but
you have the power! Here is how `onClick` is defined for example:
import Json.Decode as Json
onClick : msg -> Attribute msg
onClick message =
on "click" (Json.succeed message)
The first argument is the event name in the same format as with JavaScript's
[`addEventListener`][aEL] function.
The second argument is a JSON decoder. Read more about these [here][decoder].
When an event occurs, the decoder tries to turn the event object into an Elm
value. If successful, the value is routed to your `update` function. In the
case of `onClick` we always just succeed with the given `message`.
If this is confusing, work through the [Elm Architecture Tutorial][tutorial].
It really does help!
[aEL]: <https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener>
[decoder]: <http://package.elm-lang.org/packages/elm-lang/core/latest/Json-Decode>
[tutorial]: <https://github.com/evancz/elm-architecture-tutorial/>
-}
on : String -> Json.Decoder msg -> Attribute msg
on event decode =
Internal.Attr <| Html.Events.on event decode
-- {-| Same as `on` but you can set a few options.
-- -}
-- onWithOptions : String -> Html.Events.Options -> Json.Decoder msg -> Attribute msg
-- onWithOptions event options decode =
-- Internal.Attr <| Html.Events.onWithOptions event options decode
-- COMMON DECODERS
{-| A `Json.Decoder` for grabbing `event.target.value`. We use this to define
`onInput` as follows:
import Json.Decode as Json
onInput : (String -> msg) -> Attribute msg
onInput tagger =
on "input" (Json.map tagger targetValue)
You probably will never need this, but hopefully it gives some insights into
how to make custom event handlers.
-}
targetValue : Json.Decoder String
targetValue =
Json.at [ "target", "value" ] Json.string
{-| A `Json.Decoder` for grabbing `event.target.checked`. We use this to define
`onCheck` as follows:
import Json.Decode as Json
onCheck : (Bool -> msg) -> Attribute msg
onCheck tagger =
on "input" (Json.map tagger targetChecked)
-}
targetChecked : Json.Decoder Bool
targetChecked =
Json.at [ "target", "checked" ] Json.bool
{-| A `Json.Decoder` for grabbing `event.keyCode`. This helps you define
keyboard listeners like this:
import Json.Decode as Json
onKeyUp : (Int -> msg) -> Attribute msg
onKeyUp tagger =
on "keyup" (Json.map tagger keyCode)
**Note:** It looks like the spec is moving away from `event.keyCode` and
towards `event.key`. Once this is supported in more browsers, we may add
helpers here for `onKeyUp`, `onKeyDown`, `onKeyPress`, etc.
-}
keyCode : Json.Decoder Int
keyCode =
Json.field "keyCode" Json.int

View File

@ -0,0 +1,525 @@
module Element.Font exposing
( color, size
, family, Font, typeface, serif, sansSerif, monospace
, external
, alignLeft, alignRight, center, justify, letterSpacing, wordSpacing
, underline, strike, italic, unitalicized
, heavy, extraBold, bold, semiBold, medium, regular, light, extraLight, hairline
, Variant, variant, variantList, smallCaps, slashedZero, ligatures, ordinal, tabularNumbers, stackedFractions, diagonalFractions, swash, feature, indexed
, glow, shadow
)
{-|
import Element
import Element.Font as Font
view =
Element.el
[ Font.color (Element.rgb 0 0 1)
, Font.size 18
, Font.family
[ Font.typeface "Open Sans"
, Font.sansSerif
]
]
(Element.text "Woohoo, I'm stylish text")
**Note:** `Font.color`, `Font.size`, and `Font.family` are inherited, meaning you can set them at the top of your view and all subsequent nodes will have that value.
**Other Note:** If you're looking for something like `line-height`, it's handled by `Element.spacing` on a `paragraph`.
@docs color, size
## Typefaces
@docs family, Font, typeface, serif, sansSerif, monospace
@docs external
## Alignment and Spacing
@docs alignLeft, alignRight, center, justify, letterSpacing, wordSpacing
## Font Styles
@docs underline, strike, italic, unitalicized
## Font Weight
@docs heavy, extraBold, bold, semiBold, medium, regular, light, extraLight, hairline
## Variants
@docs Variant, variant, variantList, smallCaps, slashedZero, ligatures, ordinal, tabularNumbers, stackedFractions, diagonalFractions, swash, feature, indexed
## Shadows
@docs glow, shadow
-}
import Element exposing (Attr, Attribute, Color)
import Internal.Flag as Flag
import Internal.Model as Internal
import Internal.Style exposing (classes)
{-| -}
type alias Font =
Internal.Font
{-| -}
color : Color -> Attr decorative msg
color fontColor =
Internal.StyleClass
Flag.fontColor
(Internal.Colored
("fc-" ++ Internal.formatColorClass fontColor)
"color"
fontColor
)
{-|
import Element
import Element.Font as Font
myElement =
Element.el
[ Font.family
[ Font.typeface "Helvetica"
, Font.sansSerif
]
]
(text "")
-}
family : List Font -> Attribute msg
family families =
Internal.StyleClass
Flag.fontFamily
(Internal.FontFamily
(List.foldl Internal.renderFontClassName "ff-" families)
families
)
{-| -}
serif : Font
serif =
Internal.Serif
{-| -}
sansSerif : Font
sansSerif =
Internal.SansSerif
{-| -}
monospace : Font
monospace =
Internal.Monospace
{-| -}
typeface : String -> Font
typeface =
Internal.Typeface
{-| -}
type alias Adjustment =
{ capital : Float
, lowercase : Float
, baseline : Float
, descender : Float
}
{-| -}
with :
{ name : String
, adjustment : Maybe Adjustment
, variants : List Variant
}
-> Font
with =
Internal.FontWith
{-| -}
sizeByCapital : Attribute msg
sizeByCapital =
Internal.htmlClass classes.sizeByCapital
{-| -}
full : Attribute msg
full =
Internal.htmlClass classes.fullSize
{-| **Note** it's likely that `Font.external` will cause a flash on your page on loading.
To bypass this, import your fonts using a separate stylesheet and just use `Font.typeface`.
It's likely that `Font.external` will be removed or redesigned in the future to avoid the flashing.
`Font.external` can be used to import font files. Let's say you found a neat font on <http://fonts.google.com>:
import Element
import Element.Font as Font
view =
Element.el
[ Font.family
[ Font.external
{ name = "Roboto"
, url = "https://fonts.googleapis.com/css?family=Roboto"
}
, Font.sansSerif
]
]
(Element.text "Woohoo, I'm stylish text")
-}
external : { url : String, name : String } -> Font
external { url, name } =
Internal.ImportFont name url
{-| Font sizes are always given as `px`.
-}
size : Int -> Attr decorative msg
size i =
Internal.StyleClass Flag.fontSize (Internal.FontSize i)
{-| In `px`.
-}
letterSpacing : Float -> Attribute msg
letterSpacing offset =
Internal.StyleClass Flag.letterSpacing <|
Internal.Single
("ls-" ++ Internal.floatClass offset)
"letter-spacing"
(String.fromFloat offset ++ "px")
{-| In `px`.
-}
wordSpacing : Float -> Attribute msg
wordSpacing offset =
Internal.StyleClass Flag.wordSpacing <|
Internal.Single ("ws-" ++ Internal.floatClass offset) "word-spacing" (String.fromFloat offset ++ "px")
{-| Align the font to the left.
-}
alignLeft : Attribute msg
alignLeft =
Internal.Class Flag.fontAlignment classes.textLeft
{-| Align the font to the right.
-}
alignRight : Attribute msg
alignRight =
Internal.Class Flag.fontAlignment classes.textRight
{-| Center align the font.
-}
center : Attribute msg
center =
Internal.Class Flag.fontAlignment classes.textCenter
{-| -}
justify : Attribute msg
justify =
Internal.Class Flag.fontAlignment classes.textJustify
-- {-| -}
-- justifyAll : Attribute msg
-- justifyAll =
-- Internal.class classesTextJustifyAll
{-| -}
underline : Attribute msg
underline =
Internal.htmlClass classes.underline
{-| -}
strike : Attribute msg
strike =
Internal.htmlClass classes.strike
{-| -}
italic : Attribute msg
italic =
Internal.htmlClass classes.italic
{-| -}
bold : Attribute msg
bold =
Internal.Class Flag.fontWeight classes.bold
{-| -}
light : Attribute msg
light =
Internal.Class Flag.fontWeight classes.textLight
{-| -}
hairline : Attribute msg
hairline =
Internal.Class Flag.fontWeight classes.textThin
{-| -}
extraLight : Attribute msg
extraLight =
Internal.Class Flag.fontWeight classes.textExtraLight
{-| -}
regular : Attribute msg
regular =
Internal.Class Flag.fontWeight classes.textNormalWeight
{-| -}
semiBold : Attribute msg
semiBold =
Internal.Class Flag.fontWeight classes.textSemiBold
{-| -}
medium : Attribute msg
medium =
Internal.Class Flag.fontWeight classes.textMedium
{-| -}
extraBold : Attribute msg
extraBold =
Internal.Class Flag.fontWeight classes.textExtraBold
{-| -}
heavy : Attribute msg
heavy =
Internal.Class Flag.fontWeight classes.textHeavy
{-| This will reset bold and italic.
-}
unitalicized : Attribute msg
unitalicized =
Internal.htmlClass classes.textUnitalicized
{-| -}
shadow :
{ offset : ( Float, Float )
, blur : Float
, color : Color
}
-> Attr decorative msg
shadow shade =
Internal.StyleClass Flag.txtShadows <|
Internal.Single (Internal.textShadowClass shade) "text-shadow" (Internal.formatTextShadow shade)
{-| A glow is just a simplified shadow.
-}
glow : Color -> Float -> Attr decorative msg
glow clr i =
let
shade =
{ offset = ( 0, 0 )
, blur = i * 2
, color = clr
}
in
Internal.StyleClass Flag.txtShadows <|
Internal.Single (Internal.textShadowClass shade) "text-shadow" (Internal.formatTextShadow shade)
{- Variants -}
{-| -}
type alias Variant =
Internal.Variant
{-| You can use this to set a single variant on an element itself such as:
el
[ Font.variant Font.smallCaps
]
(text "rendered with smallCaps")
**Note** These will **not** stack. If you want multiple variants, you should use `Font.variantList`.
-}
variant : Variant -> Attribute msg
variant var =
case var of
Internal.VariantActive name ->
Internal.Class Flag.fontVariant ("v-" ++ name)
Internal.VariantOff name ->
Internal.Class Flag.fontVariant ("v-" ++ name ++ "-off")
Internal.VariantIndexed name index ->
Internal.StyleClass Flag.fontVariant <|
Internal.Single ("v-" ++ name ++ "-" ++ String.fromInt index)
"font-feature-settings"
("\"" ++ name ++ "\" " ++ String.fromInt index)
isSmallCaps x =
case x of
Internal.VariantActive feat ->
feat == "smcp"
_ ->
False
{-| -}
variantList : List Variant -> Attribute msg
variantList vars =
let
features =
vars
|> List.map Internal.renderVariant
hasSmallCaps =
List.any isSmallCaps vars
name =
if hasSmallCaps then
vars
|> List.map Internal.variantName
|> String.join "-"
|> (\x -> x ++ "-sc")
else
vars
|> List.map Internal.variantName
|> String.join "-"
featureString =
String.join ", " features
in
Internal.StyleClass Flag.fontVariant <|
Internal.Style ("v-" ++ name)
[ Internal.Property "font-feature-settings" featureString
, Internal.Property "font-variant"
(if hasSmallCaps then
"small-caps"
else
"normal"
)
]
{-| [Small caps](https://en.wikipedia.org/wiki/Small_caps) are rendered using uppercase glyphs, but at the size of lowercase glyphs.
-}
smallCaps : Variant
smallCaps =
Internal.VariantActive "smcp"
{-| Add a slash when rendering `0`
-}
slashedZero : Variant
slashedZero =
Internal.VariantActive "zero"
{-| -}
ligatures : Variant
ligatures =
Internal.VariantActive "liga"
{-| Oridinal markers like `1st` and `2nd` will receive special glyphs.
-}
ordinal : Variant
ordinal =
Internal.VariantActive "ordn"
{-| Number figures will each take up the same space, allowing them to be easily aligned, such as in tables.
-}
tabularNumbers : Variant
tabularNumbers =
Internal.VariantActive "tnum"
{-| Render fractions with the numerator stacked on top of the denominator.
-}
stackedFractions : Variant
stackedFractions =
Internal.VariantActive "afrc"
{-| Render fractions
-}
diagonalFractions : Variant
diagonalFractions =
Internal.VariantActive "frac"
{-| -}
swash : Int -> Variant
swash =
Internal.VariantIndexed "swsh"
{-| Set a feature by name and whether it should be on or off.
Feature names are four-letter names as defined in the [OpenType specification](https://docs.microsoft.com/en-us/typography/opentype/spec/featurelist).
-}
feature : String -> Bool -> Variant
feature name on =
if on then
Internal.VariantIndexed name 1
else
Internal.VariantIndexed name 0
{-| A font variant might have multiple versions within the font.
In these cases we need to specify the index of the version we want.
-}
indexed : String -> Int -> Variant
indexed name on =
Internal.VariantIndexed name on

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,70 @@
module Element.Keyed exposing (el, column, row)
{-| Notes from the `Html.Keyed` on how keyed works:
---
A keyed node helps optimize cases where children are getting added, moved, removed, etc. Common examples include:
- The user can delete items from a list.
- The user can create new items in a list.
- You can sort a list based on name or date or whatever.
When you use a keyed node, every child is paired with a string identifier. This makes it possible for the underlying diffing algorithm to reuse nodes more efficiently.
This means if a key is changed between renders, then the diffing step will be skipped and the node will be forced to rerender.
---
@docs el, column, row
-}
import Element exposing (Attribute, Element, fill, height, shrink, width)
import Internal.Model as Internal
import Internal.Style exposing (classes)
{-| -}
el : List (Attribute msg) -> ( String, Element msg ) -> Element msg
el attrs child =
Internal.element
Internal.asEl
Internal.div
(width shrink
:: height shrink
:: attrs
)
(Internal.Keyed [ child ])
{-| -}
row : List (Attribute msg) -> List ( String, Element msg ) -> Element msg
row attrs children =
Internal.element
Internal.asRow
Internal.div
(Internal.htmlClass (classes.contentLeft ++ " " ++ classes.contentCenterY)
:: width shrink
:: height shrink
:: attrs
)
(Internal.Keyed children)
{-| -}
column : List (Attribute msg) -> List ( String, Element msg ) -> Element msg
column attrs children =
Internal.element
Internal.asColumn
Internal.div
(Internal.htmlClass
(classes.contentTop
++ " "
++ classes.contentLeft
)
:: height shrink
:: width shrink
:: attrs
)
(Internal.Keyed children)

View File

@ -0,0 +1,117 @@
module Element.Lazy exposing (lazy, lazy2, lazy3, lazy4, lazy5)
{-| Same as `Html.lazy`. In case you're unfamiliar, here's a note from the `Html` library!
---
Since all Elm functions are pure we have a guarantee that the same input
will always result in the same output. This module gives us tools to be lazy
about building `Html` that utilize this fact.
Rather than immediately applying functions to their arguments, the `lazy`
functions just bundle the function and arguments up for later. When diffing
the old and new virtual DOM, it checks to see if all the arguments are equal
by reference. If so, it skips calling the function!
This is a really cheap test and often makes things a lot faster, but definitely
benchmark to be sure!
---
@docs lazy, lazy2, lazy3, lazy4, lazy5
-}
import Internal.Model exposing (..)
import VirtualDom
{-| -}
lazy : (a -> Element msg) -> a -> Element msg
lazy fn a =
Unstyled <| VirtualDom.lazy3 apply1 fn a
{-| -}
lazy2 : (a -> b -> Element msg) -> a -> b -> Element msg
lazy2 fn a b =
Unstyled <| VirtualDom.lazy4 apply2 fn a b
{-| -}
lazy3 : (a -> b -> c -> Element msg) -> a -> b -> c -> Element msg
lazy3 fn a b c =
Unstyled <| VirtualDom.lazy5 apply3 fn a b c
{-| -}
lazy4 : (a -> b -> c -> d -> Element msg) -> a -> b -> c -> d -> Element msg
lazy4 fn a b c d =
Unstyled <| VirtualDom.lazy6 apply4 fn a b c d
{-| -}
lazy5 : (a -> b -> c -> d -> e -> Element msg) -> a -> b -> c -> d -> e -> Element msg
lazy5 fn a b c d e =
Unstyled <| VirtualDom.lazy7 apply5 fn a b c d e
apply1 fn a =
embed (fn a)
apply2 fn a b =
embed (fn a b)
apply3 fn a b c =
embed (fn a b c)
apply4 fn a b c d =
embed (fn a b c d)
apply5 fn a b c d e =
embed (fn a b c d e)
{-| -}
embed : Element msg -> LayoutContext -> VirtualDom.Node msg
embed x =
case x of
Unstyled html ->
html
Styled styled ->
styled.html
(Internal.Model.OnlyDynamic
{ hover = AllowHover
, focus =
{ borderColor = Nothing
, shadow = Nothing
, backgroundColor = Nothing
}
, mode = Layout
}
styled.styles
)
-- -- (Just
-- -- (toStyleSheetString
-- { hover = AllowHover
-- , focus =
-- { borderColor = Nothing
-- , shadow = Nothing
-- , backgroundColor = Nothing
-- }
-- , mode = Layout
-- }
-- -- styled.styles
-- -- )
-- -- )
Text text ->
always (VirtualDom.text text)
Empty ->
always (VirtualDom.text "")

View File

@ -0,0 +1,107 @@
module Element.Region exposing
( mainContent, navigation, heading, aside, footer
, description
, announce, announceUrgently
)
{-| This module is meant to make accessibility easy!
These are sign posts that accessibility software like screen readers can use to navigate your app.
All you have to do is add them to elements in your app where you see fit.
Here's an example of annotating your navigation region:
import Element.Region as Region
myNavigation =
Element.row [ Region.navigation ]
[-- ..your navigation links
]
@docs mainContent, navigation, heading, aside, footer
@docs description
@docs announce, announceUrgently
-}
import Element exposing (Attribute)
import Internal.Model as Internal exposing (Description(..))
{-| -}
mainContent : Attribute msg
mainContent =
Internal.Describe Main
{-| -}
aside : Attribute msg
aside =
Internal.Describe Complementary
{-| -}
navigation : Attribute msg
navigation =
Internal.Describe Navigation
-- form : Attribute msg
-- form =
-- Internal.Describe Form
-- search : Attribute msg
-- search =
-- Internal.Describe Search
{-| -}
footer : Attribute msg
footer =
Internal.Describe ContentInfo
{-| This will mark an element as `h1`, `h2`, etc where possible.
Though it's also smart enough to not conflict with existing nodes.
So, this code
link [ Region.heading 1 ]
{ url = "http://fruits.com"
, label = text "Best site ever"
}
will generate
<a href="http://fruits.com">
<h1>Best site ever</h1>
</a>
-}
heading : Int -> Attribute msg
heading =
Internal.Describe << Heading
{-| Screen readers will announce changes to this element and potentially interrupt any other announcement.
-}
announceUrgently : Attribute msg
announceUrgently =
Internal.Describe LiveAssertive
{-| Screen readers will announce when changes to this element are made.
-}
announce : Attribute msg
announce =
Internal.Describe LivePolite
{-| -}
description : String -> Attribute msg
description =
Internal.Describe << Internal.Label

View File

@ -0,0 +1,325 @@
module Internal.Flag exposing
( Field(..)
, Flag(..)
, active
, add
, alignBottom
, alignRight
, behind
, bgColor
, bgGradient
, bgImage
, borderColor
, borderRound
, borderStyle
, borderWidth
, centerX
, centerY
, cursor
, flag
, focus
, fontAlignment
, fontColor
, fontFamily
, fontSize
, fontVariant
, fontWeight
, gridPosition
, gridTemplate
, height
, heightBetween
, heightContent
, heightFill
, heightTextAreaContent
, hover
, letterSpacing
, merge
, moveX
, moveY
, none
, overflow
, padding
, present
, rotate
, scale
, shadows
, spacing
, transparency
, txtShadows
, value
, width
, widthBetween
, widthContent
, widthFill
, wordSpacing
, xAlign
, yAlign
)
{-| -}
import Bitwise
type Field
= Field Int Int
type Flag
= Flag Int
| Second Int
none : Field
none =
Field 0 0
value myFlag =
case myFlag of
Flag first ->
round (logBase 2 (toFloat first))
Second second ->
round (logBase 2 (toFloat second)) + 32
{-| If the query is in the truth, return True
-}
present : Flag -> Field -> Bool
present myFlag (Field fieldOne fieldTwo) =
case myFlag of
Flag first ->
Bitwise.and first fieldOne == first
Second second ->
Bitwise.and second fieldTwo == second
{-| Add a flag to a field.
-}
add : Flag -> Field -> Field
add myFlag (Field one two) =
case myFlag of
Flag first ->
Field (Bitwise.or first one) two
Second second ->
Field one (Bitwise.or second two)
{-| Generally you want to use `add`, which keeps a distinction between Fields and Flags.
Merging will combine two fields
-}
merge : Field -> Field -> Field
merge (Field one two) (Field three four) =
Field (Bitwise.or one three) (Bitwise.or two four)
flag : Int -> Flag
flag i =
if i > 31 then
Second
(Bitwise.shiftLeftBy (i - 32) 1)
else
Flag
(Bitwise.shiftLeftBy i 1)
{- Used for Style invalidation -}
transparency =
flag 0
padding =
flag 2
spacing =
flag 3
fontSize =
flag 4
fontFamily =
flag 5
width =
flag 6
height =
flag 7
bgColor =
flag 8
bgImage =
flag 9
bgGradient =
flag 10
borderStyle =
flag 11
fontAlignment =
flag 12
fontWeight =
flag 13
fontColor =
flag 14
wordSpacing =
flag 15
letterSpacing =
flag 16
borderRound =
flag 17
txtShadows =
flag 18
shadows =
flag 19
overflow =
flag 20
cursor =
flag 21
scale =
flag 23
rotate =
flag 24
moveX =
flag 25
moveY =
flag 26
borderWidth =
flag 27
borderColor =
flag 28
yAlign =
flag 29
xAlign =
flag 30
focus =
flag 31
active =
flag 32
hover =
flag 33
gridTemplate =
flag 34
gridPosition =
flag 35
{- Notes -}
heightContent =
flag 36
heightFill =
flag 37
widthContent =
flag 38
widthFill =
flag 39
alignRight =
flag 40
alignBottom =
flag 41
centerX =
flag 42
centerY =
flag 43
widthBetween =
flag 44
heightBetween =
flag 45
behind =
flag 46
heightTextAreaContent =
flag 47
fontVariant =
flag 48

View File

@ -0,0 +1,270 @@
module Internal.Grid exposing (Around, Layout(..), PositionedElement, RelativePosition(..), build, createGrid, getWidth, relative)
{-| Relative positioning within a grid.
A relatively positioned grid, means a 3x3 grid with the primary element in the center.
-}
import Element
import Internal.Flag as Flag
import Internal.Model as Internal
type RelativePosition
= OnRight
| OnLeft
| Above
| Below
| InFront
type Layout
= GridElement
| Row
| Column
type alias Around alignment msg =
{ right : Maybe (PositionedElement alignment msg)
, left : Maybe (PositionedElement alignment msg)
, primary : ( Maybe String, List (Internal.Attribute alignment msg), List (Internal.Element msg) )
-- , primaryWidth : Internal.Length
, defaultWidth : Internal.Length
, below : Maybe (PositionedElement alignment msg)
, above : Maybe (PositionedElement alignment msg)
, inFront : Maybe (PositionedElement alignment msg)
}
type alias PositionedElement alignment msg =
{ layout : Layout
, child : List (Internal.Element msg)
, attrs : List (Internal.Attribute alignment msg)
, width : Int
, height : Int
}
relative : Maybe String -> List (Internal.Attribute alignment msg) -> Around alignment msg -> Internal.Element msg
relative node attributes around =
let
( sX, sY ) =
Internal.getSpacing attributes ( 7, 7 )
make positioned =
Internal.element Internal.noStyleSheet
Internal.asEl
Nothing
positioned.attrs
(Internal.Unkeyed positioned.child)
( template, children ) =
createGrid ( sX, sY ) around
in
Internal.element Internal.noStyleSheet
Internal.asGrid
node
(template ++ attributes)
(Internal.Unkeyed
children
)
createGrid : ( Int, Int ) -> Around alignment msg -> ( List (Internal.Attribute alignment msg1), List (Element.Element msg) )
createGrid ( spacingX, spacingY ) nearby =
let
rowCount =
List.sum
[ 1
, if Nothing == nearby.above then
0
else
1
, if Nothing == nearby.below then
0
else
1
]
colCount =
List.sum
[ 1
, if Nothing == nearby.left then
0
else
1
, if Nothing == nearby.right then
0
else
1
]
rows =
if nearby.above == Nothing then
{ above = 0
, primary = 1
, below = 2
}
else
{ above = 1
, primary = 2
, below = 3
}
columns =
if Nothing == nearby.left then
{ left = 0
, primary = 1
, right = 2
}
else
{ left = 1
, primary = 2
, right = 3
}
rowCoord pos =
case pos of
Above ->
rows.above
Below ->
rows.below
OnRight ->
rows.primary
OnLeft ->
rows.primary
InFront ->
rows.primary
colCoord pos =
case pos of
Above ->
columns.primary
Below ->
columns.primary
OnRight ->
columns.right
OnLeft ->
columns.left
InFront ->
columns.primary
place pos el =
build (rowCoord pos) (colCoord pos) spacingX spacingY el
in
( [ Internal.StyleClass Flag.gridTemplate
(Internal.GridTemplateStyle
{ spacing = ( Internal.Px spacingX, Internal.Px spacingY )
, columns =
List.filterMap identity
[ nearby.left
|> Maybe.map (\el -> Maybe.withDefault nearby.defaultWidth (getWidth el.attrs))
, nearby.primary
|> (\( node, attrs, el ) -> getWidth attrs)
|> Maybe.withDefault nearby.defaultWidth
|> Just
, nearby.right
|> Maybe.map (\el -> Maybe.withDefault nearby.defaultWidth (getWidth el.attrs))
]
, rows = List.map (always Internal.Content) (List.range 1 rowCount)
}
)
]
, List.filterMap identity
[ Just <|
case nearby.primary of
( primaryNode, primaryAttrs, primaryChildren ) ->
Internal.element Internal.noStyleSheet
Internal.asEl
primaryNode
(Internal.StyleClass Flag.gridPosition
(Internal.GridPosition
{ row = rows.primary
, col = columns.primary
, width = 1
, height = 1
}
)
:: primaryAttrs
)
(Internal.Unkeyed primaryChildren)
, Maybe.map (place OnLeft) nearby.left
, Maybe.map (place OnRight) nearby.right
, Maybe.map (place Above) nearby.above
, Maybe.map (place Below) nearby.below
, Maybe.map (place InFront) nearby.inFront
]
)
build : Int -> Int -> Int -> Int -> { a | attrs : List (Internal.Attribute alignment msg), height : Int, layout : Layout, width : Int, child : List (Internal.Element msg) } -> Internal.Element msg
build rowCoord colCoord spacingX spacingY positioned =
let
attributes =
Internal.StyleClass Flag.gridPosition
(Internal.GridPosition
{ row = rowCoord
, col = colCoord
, width = positioned.width
, height = positioned.height
}
)
:: Internal.StyleClass Flag.spacing (Internal.SpacingStyle spacingX spacingY)
:: positioned.attrs
in
case positioned.layout of
GridElement ->
Internal.element Internal.noStyleSheet
Internal.asEl
Nothing
attributes
(Internal.Unkeyed <| positioned.child)
Row ->
Internal.element Internal.noStyleSheet
Internal.asRow
Nothing
attributes
(Internal.Unkeyed positioned.child)
Column ->
Internal.element Internal.noStyleSheet
Internal.asColumn
Nothing
attributes
(Internal.Unkeyed positioned.child)
getWidth : List (Internal.Attribute align msg) -> Maybe Internal.Length
getWidth attrs =
let
widthPlease attr found =
case found of
Just x ->
Just x
Nothing ->
case attr of
Internal.Width w ->
Just w
_ ->
Nothing
in
List.foldr widthPlease Nothing attrs

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff