UbiqueLambda / elm-with-ui / UI

With-pattern UI toolkit for Elm. Oversimplified by now.

In this documentant, the world unit meaning varies according to your Encoder.

Type


type alias Graphics msg =
Backend.Graphics.Graphics msg

Type for describing atoms or groups.

map : (a -> msg) -> Graphics a -> Graphics msg

Usually used for nesting components.

dropdownView model =
    UI.map ForDropdownMsg (MyDropdown.view model.dropdown)

Color type


type alias Color =
Backend.Graphics.Color

Type for holding color primitives.

intRGBA : Basics.Int -> Color

Use 32-bit hexadecimal to describe the RGBA color.

red =
    intRGBA 0xFF0000FF

yellow =
    intRGBA 0xFFFF00FF

cyan =
    intRGBA 0x00FFFFFF

Helping types


type alias Rect =
{ top : Basics.Int
, right : Basics.Int
, bottom : Basics.Int
, left : Basics.Int 
}

Helper type for grouping top, right, bottom, and left distances (in units).


type alias Corners =
{ topLeft : Basics.Int
, topRight : Basics.Int
, bottomRight : Basics.Int
, bottomLeft : Basics.Int 
}

Helper type for grouping topLeft, topRight, bottomRight, and bottomLeft metrics (in units).

Atoms

empty : Graphics msg

Empty figure.

looseText : String -> Graphics msg

Text without a container. Don't have any special behavior, it just renders.

In HTML, this will insert text in the document without surrouding it in a tag.

NOTE: When you use any with-functions in a loose-text, it automatically wraps in a singleton. The result is then identical to a spanText.

spanText : String -> Graphics msg

Wraps text within a container. Behaves according to the parent grouping disposition.

In HTML, this will insert text in the document without surrouding it in a <div> tag.

Grouping

singleton : Graphics msg -> Graphics msg

Wraps a single element in a container.

nestedSquares =
    UI.empty
        |> UI.withWidth 25
        |> UI.withHeight 25
        |> UI.withBorder (UI.border1uBlack |> Just)
        |> UI.singleton
        |> UI.withBorder (UI.border1uBlack |> UI.borderWithColor red |> Just)
        |> UI.singleton
        |> UI.withBorder (UI.border1uBlack |> UI.borderWithColor orange |> Just)
        |> UI.singleton
        |> UI.withBorder (UI.border1uBlack |> UI.borderWithColor yellow |> Just)
        |> UI.singleton
        |> UI.withBorder (UI.border1uBlack |> UI.borderWithColor green |> Just)
        |> UI.singleton
        |> UI.withBorder (UI.border1uBlack |> UI.borderWithColor cyan |> Just)
        |> UI.singleton
        |> UI.withBorder (UI.border1uBlack |> UI.borderWithColor blue |> Just)

row : List ( String, Graphics msg ) -> Graphics msg

Group itens disposing them horizontally.

pageView model =
    [ ( "contents", contentsView model )
    , ( "tools", toolingView model )
    ]
        |> maybePrependSidebar model
        |> UI.row

column : List ( String, Graphics msg ) -> Graphics msg

Group itens disposing them vertically.

shopList model =
    [ ( "pineapple", pineappleBox )
    , ( "rice", riceBox )
    , ( "onions", onionsBox )
    ]
        |> maybePrependBeans model
        |> UI.column

stack : List ( String, Graphics msg ) -> Graphics msg

Group itens disposing them one above the other. Head goes on bottom, tails goes on top.

pageView model =
    [ ( "contents", pageContents ) ]
        |> maybeAppendHalfOpaqueBlackOverlay model
        |> maybeAppendDialogBox
        |> UI.stack

indexedRow : List (Graphics msg) -> Graphics msg

This is like row, but the virtual-dom struggles to know what to recreate and what to update. It should be fine when you group elements that don't disappear, don't decrease in number, don't increment, and don't swap their order.

TL;DR: Avoid this.

tabsMenu =
    UI.indexedRow
        [ codeTab
        , issuesTab
        , prTab
        , wikiTab
        , settingsTab
        ]

indexedColumn : List (Graphics msg) -> Graphics msg

This is like column, but the virtual-dom struggles to know what to recreate and what to update. It should be fine when you group elements that don't disappear, don't decrease in number, don't increment, and don't swap their order.

TL;DR: Avoid this.

pageView =
    UI.indexedColumn
        [ header
        , text
        , footer
        ]

indexedStack : List (Graphics msg) -> Graphics msg

This is like stack, but the virtual-dom struggles to know what to recreate and what to update. It should be fine when you group elements that don't disappear, don't decrease in number, don't increment, and don't swap their order.

TL;DR: Avoid this.

tabsMenu =
    UI.indexedStack
        [ pageContents
        , halfOpaqueBlackOverlay
        , dialogBox
        ]

Options

Change Width and Height

withWidth : Basics.Int -> Graphics msg -> Graphics msg

Forces the group's width to a quantity in units.

By default, if the children's length is bigger, the content is cliped. See withScrollingX to avoid it.

someSquare =
    UI.empty
        |> UI.withWidth 64
        |> UI.withHeight 64
        |> UI.withBackground (UI.backgroundColor blue |> Just)

withFitContentsX : Graphics msg -> Graphics msg

Instead of forcing the width, have enougth to show all the children contents.

For forcing a fixed one, see withWidth.

withHeight : Basics.Int -> Graphics msg -> Graphics msg

Forces the group's height to a quantity in units.

By default, if the children's length is bigger, the content is cliped. See withScrollingY to avoid it.

someSquare =
    UI.empty
        |> UI.withWidth 64
        |> UI.withHeight 64
        |> UI.withBackground (UI.backgroundColor blue |> Just)

withFitContentsY : Graphics msg -> Graphics msg

Instead of forcing the height, have enougth to show all the children contents.

For forcing a fixed one, see withHeight.

Change Spacing and Padding

withSpacing : Basics.Int -> Graphics msg -> Graphics msg

Empty space between the items of a group, in units.

spacedRow =
    UI.row [ item1, item2, item3 ]
        |> UI.withSpacing 8

withPadding : Basics.Int -> Graphics msg -> Graphics msg

Applies empty space, in units, repeatedly on top, bottom, left and right, surrounding the group.

square =
    UI.spanText "Hello World!"
        |> UI.withPadding 12
        |> UI.withBorder (UI.border1uBlack |> Just)

withPaddingXY : Basics.Int -> Basics.Int -> Graphics msg -> Graphics msg

Applies empty space, in units, to X (left and right) and Y (top and bottom).

square =
    UI.spanText "Hello World!"
        |> UI.withPaddingXY 12 16
        |> UI.withBorder (UI.border1uBlack |> Just)

withPaddingEach : Rect -> Graphics msg -> Graphics msg

Applies empty space, in units, surrounding the group.

square =
    UI.spanText "Hello World!"
        |> UI.withPaddingEach { top = 1, right = 3, bottom = 4, left = 2 }
        |> UI.withBorder (UI.border1uBlack |> Just)

Scrolling Behavior

withScrollingX : Maybe Scroll -> Graphics msg -> Graphics msg

When the contents of a group does not fit into the group's width, you might want to show a horizontal scroll bar.

See scrollInsetAlwaysVisible for the only value available right now. Nothing means the content will be horizontally clipped (default behavior).

horizontalScrollbars items =
    UI.row items
        |> UI.withPadding 16
        |> UI.withScrollingX (Just UI.scrollInsetAlwaysVisible)

withScrollingY : Maybe Scroll -> Graphics msg -> Graphics msg

When the contents of a group does not fit into the group's height, you might want to show a vertical scroll bar.

See scrollInsetAlwaysVisible for the only value available right now. Nothing means the content will be vertically clipped (default behavior).

verticalScrollbars items =
    UI.column items
        |> UI.withPadding 16
        |> UI.withScrollingY (Just UI.scrollInsetAlwaysVisible)


type alias Scroll =
Backend.Graphics.Scroll

Type for the possible options of scrolling.

scrollInsetAlwaysVisible : Scroll

The (default) HTML-like way of adding scrollbars to any group.

The scrollbar is inset, relative to the group's dimensions. And is always visible indiferent to the length of the group's contents.

See withScrollingX and withScrollingY for usage.

Background

withBackground : Maybe Background -> Graphics msg -> Graphics msg

Applies a background to an element.

square =
    UI.empty
        |> UI.withWidth 32
        |> UI.withHeight 32
        |> UI.withBackground (UI.backgroundColor black |> Just)


type alias Background =
Backend.Graphics.Background

Type for the possible backgrounds types.

backgroundColor : Color -> Background

Creates a background and fills it with a specific color.

green =
    UI.intRGBA 0x00FF00FF

greenSquare =
    UI.empty
        |> UI.withWidth 32
        |> UI.withHeight 32
        |> UI.withBackground (UI.backgroundColor green |> Just)

Borders

withBorder : Maybe Border -> Graphics msg -> Graphics msg

Applies borders to an element.

square =
    UI.empty
        |> UI.withWidth 32
        |> UI.withHeight 32
        |> UI.withBorder (UI.border1uBlack |> Just)


type alias Border =
Backend.Graphics.Border

Type for describing border displaying.

border1uBlack : Border

Creates a border with 1 unit on each side, solid and black.

emptySquare =
    UI.empty
        |> UI.withWidth 31
        |> UI.withHeight 31
        |> UI.withBorder (UI.border1uBlack |> Just)

borderWithColor : Color -> Border -> Border

Changes the color of all sides of the border.

pink =
    UI.intRGBA 0xFFC0CBFF

emptySquare =
    UI.empty
        |> UI.withWidth 31
        |> UI.withHeight 31
        |> UI.withBorder (UI.border1uBlack |> UI.borderWithColor pink |> Just)

borderWithWidth : Basics.Int -> Border -> Border

Specify one width value to all sides of the border in units.

emptySquare32x32 =
    UI.empty
        |> UI.withWidth 24
        |> UI.withHeight 24
        |> UI.withBorder (UI.border1uBlack |> UI.borderWithWidth 4 |> Just)

borderWithWidthXY : Basics.Int -> Basics.Int -> Border -> Border

Specify the width of X (pair left-right) and Y (pair top-bottom) borders in units.

emptySquare32x32 =
    UI.empty
        |> UI.withWidth 28
        |> UI.withHeight 24
        |> UI.withBorder
            (UI.border1uBlack
                |> UI.borderWithWidthXY 2 4
                |> Just
            )

borderWithWidthEach : Rect -> Border -> Border

Specify the width of each side's border.

emptySquare32x32 =
    UI.empty
        |> UI.withWidth 24
        |> UI.withHeight 24
        |> UI.withBorder
            (UI.border1uBlack
                |> UI.borderWithWidthEach
                    { top = 6
                    , right = 5
                    , bottom = 2
                    , left = 3
                    }
                |> Just
            )

borderWithRounding : Basics.Int -> Border -> Border

Rounds all the corners of said group, including border, content and background (in units).

emptyCircle =
    UI.empty
        |> UI.withWidth 31
        |> UI.withHeight 31
        |> UI.withBorder (UI.border1uBlack |> UI.borderWithRounding 16 |> Just)

borderWithRoundingEach : Corners -> Border -> Border

Rounds each of the corners of said group, including border, content and background (in units).

emptyRoudedSquare =
    UI.empty
        |> UI.withWidth 31
        |> UI.withHeight 31
        |> UI.withBorder
            (UI.border1uBlack
                |> UI.borderWithRoundingEach
                    { topLeft = 8
                    , topRight = 8
                    , bottomRight = 4
                    , bottomLeft = 4
                    }
                |> Just
            )

Shadows

withOuterShadow : Maybe Shadow -> Graphics msg -> Graphics msg

Applies outer-shadow to an element.

square =
    UI.empty
        |> UI.withWidth 32
        |> UI.withHeight 32
        |> UI.withBorder (UI.border1uBlack |> Just)
        |> UI.withOuterShadow
            (shadow1uBlack |> shadowWithColor green |> Just)


type alias Shadow =
Backend.Graphics.Shadow

Type for the describing shadow displaying.

shadow1uBlack : Shadow

The default shadow, black, 1 unit of length in X (slightly to the right) and Y (slightly to bottom), 1 unit of blur-radius and 1 unit of spread-radius.

shadowWithColor : Color -> Shadow -> Shadow

Change some shadow's color.

someShadow =
    UI.shadow1uBlack
        |> UI.shadowWithColor cyan

shadowWithLengthXY : Basics.Int -> Basics.Int -> Shadow -> Shadow

Changes the length in units of some shadow.

someShadow =
    UI.shadow1uBlack
        |> UI.shadowWithLengthXY 12 12

shadowWithBlurRadius : Basics.Int -> Shadow -> Shadow

Change some shadow's blur-radius in units.

someShadow =
    UI.shadow1uBlack
        |> UI.shadowWithBlurRadius 12

shadowWithSpreadRadius : Basics.Int -> Shadow -> Shadow

Change some shadow's spread-radius in units.

someShadow =
    UI.shadow1uBlack
        |> UI.shadowWithBlurRadius 12

Text Alignment

withTextAlign : TextAlignment -> Graphics msg -> Graphics msg

Where to align text inside a group.

spacedRow =
    UI.spanText "Foo Bar"
        |> UI.withWidth 640
        |> UI.withTextAlign UI.textCenter


type alias TextAlignment =
Backend.Graphics.TextAlignment

Type for the possible options of text alignemtn.

textLeft : TextAlignment

Aligns the text to the left.

NOTE: Remember that RTL locales exists.

textCenter : TextAlignment

Centers the text relative to its group.

textRight : TextAlignment

Aligns the text to the right.

NOTE: Remember that RTL locales exists.

Item Alignment

withAlignSelf : Alignment -> Graphics msg -> Graphics msg

Aligns an item relative to the cross-axis of its group.

alignColumnContentsExample =
    UI.column
        [ pinkSquare
            |> UI.withAlignSelf UI.start
            |> Tuple.pair "aligned-on-left"
        , greenSquare
            |> UI.withAlignSelf UI.center
            |> Tuple.pair "aligned-on-center"
        , blueSquare
            |> UI.withAlignSelf UI.end
            |> Tuple.pair "aligned-on-right"
        ]

alignRowContentsExample =
    UI.row
        [ pinkSquare
            |> UI.withAlignSelf UI.start
            |> Tuple.pair "aligned-on-top"
        , greenSquare
            |> UI.withAlignSelf UI.center
            |> Tuple.pair "aligned-on-center"
        , blueSquare
            |> UI.withAlignSelf UI.end
            |> Tuple.pair "aligned-on-bottom"
        ]

withJustifyItems : Alignment -> Graphics msg -> Graphics msg

How to align the items of a group. In a row and in a stack this affects how they're show horizontally. In a column this affects how they're show vertically.

alignRowContentsOnRightExample =
    UI.row
        [ pink32uSquare
        , green32uSquare
        , blue32uSquare
        ]
        |> UI.withWidth 640
        |> UI.withJustifyItems UI.end


type alias Alignment =
Backend.Graphics.Alignment

Type for the possible alignment positions.

start : Alignment

Aligns contents on start.

alignColumnContentsOnStartHorizontally =
    UI.indexedColumn
        [ pinkSquare
            |> UI.withAlignSelf UI.start
        , greenSquare
            |> UI.withAlignSelf UI.start
        ]

alignColumnContentsOnStartVertically =
    UI.column [ item1, item2, item3 ]
        |> UI.withJustifyItems UI.start

center : Alignment

Aligns contents on center.

alignColumnContentsOnCenterHorizontally =
    UI.indexedColumn
        [ pinkSquare
            |> UI.withAlignSelf UI.center
        , greenSquare
            |> UI.withAlignSelf UI.center
        ]

alignColumnContentsOnCenterVertically =
    UI.column [ item1, item2, item3 ]
        |> UI.withJustifyItems UI.center

end : Alignment

Aligns contents on end.

alignColumnContentsOnEndHorizontally =
    UI.indexedColumn
        [ pinkSquare
            |> UI.withAlignSelf UI.end
        , greenSquare
            |> UI.withAlignSelf UI.end
        ]

alignColumnContentsOnEndVertically =
    UI.column [ item1, item2, item3 ]
        |> UI.withJustifyItems UI.end

Font Adjustments

withFontColor : Color -> Graphics msg -> Graphics msg

Changes the text's color.

Default text's color is inherited, where's in the root element it's black.

coolTitle =
    UI.spanText "HELLO"
        |> UI.withFontColor pink

withFontSize : Basics.Int -> Graphics msg -> Graphics msg

Changes the text's size, in units.

Default text's color is inherited, where's in the root element it's 16 units.

coolTitle =
    UI.spanText "HELLO"
        |> UI.withFontSize 24

withFontWeight : Basics.Int -> Graphics msg -> Graphics msg

Changes the text's weight.

Default font's weight is inherited, where's in the root element it's 400.

coolTitle =
    UI.spanText "BOLD"
        |> UI.withFontWeight 700

withFontFamilies : List String -> FontFallback -> Graphics msg -> Graphics msg

Changes the text's font family. Tries all the font in the list, stopping in the first one available. The fallback is used when nothing in the list is available.

Default font family value is inherited, where's in the root element it's serif.

coolTitle =
    UI.spanText "HELLO"
        |> UI.withFontFamilies
            [ "Borg Sans Mono"
            , "Fira Code"
            , "JuliaMono"
            , "Fantasque Sans Mono"
            ]
            UI.monospace


type alias FontFallback =
Backend.Graphics.FontFallback

Type for the possible font fallbacks.

serif : FontFallback

An always-present serif font for fallback when the desired font-family is not found.

See withFontFamilies for usage.

sansSerif : FontFallback

An always-present sans-serif font for fallback when the desired font-family is not found.

See withFontFamilies for usage.

monospace : FontFallback

An always-present monospaced font for fallback when the desired font-family is not found.

See withFontFamilies for usage.

withInheritFontFamilies : Graphics msg -> Graphics msg

Instead of forcing the font's family, inherit it from the parent group.

For forcing a fixed one, or to learn about default behavior, see withFontFamilies.

withInheritFontColor : Graphics msg -> Graphics msg

Instead of forcing the font's color, inherit it from the parent group.

For forcing a fixed one, or to learn about default behavior, see withFontColor.

withInheritFontSize : Graphics msg -> Graphics msg

Instead of forcing the font's size, inherit it from the parent group.

For forcing a fixed one, or to learn about default behavior, see withFontSize.

withInheritFontWeight : Graphics msg -> Graphics msg

Instead of forcing the font's weight, inherit it from the parent group.

For forcing a fixed one, or to learn about default behavior, see withFontWeight.

Events

withOnClick : msg -> Graphics msg -> Graphics msg

Listen for click events and dispatches the choosen message.

Implicit effect: Changes the cursor to the platform's clickable-pointer, when available.

button =
    UI.withOnClick Msg.IncrementCounter incrementButton