hariroshan / elm-native / Native

This library should be used with elm-native JS library

We will use CustomElements feature to create mobile UI elements with nativescript objects and control the nativescript object from elm.

Here's a simple representation of how UI elements are created

Elm -> Nativescript -> Mobile

When we listen for / receive an event,

Mobile -> Nativescript -> Elm

Consider this flow while building an application. This will help you to overcome performance issues if you encounter them.

Types


type ListViewModel a

Used to abstract complexity of syncing items and encoded value


type alias Native msg =
Html msg

Just an alias for Html. This allows the usage of Html.Lazy packages when needed.

Functions

actionBar : List (Html.Attribute msg) -> List (Html msg) -> Html msg

Refer

The ActionBar is NativeScript’s abstraction over the Android ActionBar and iOS NavigationBar. It represents a toolbar at the top of the activity window, and can have a title, application-level navigation, as well as other custom interactive items.

actionBar [ title "Elm Native Flix" ] []

actionBar []
    [ label [ text "Browse", fontSize "18" ] []
    ]

actionBar [ title "Action Title" ]
    [ navigationButton [ text "Back" ] []
    ]

-- Advanced usage
actionBar
    []
    [ navigationButton [ visibility "collapsed" ] []
    , label [ text "Edit Car Details", fontSize "18" ] []
    , actionItem
        [ text "Cancel"
        , iosPosition "left"
        , onTap GoBack
        ]
        []
    , actionItem
        [ text "Done"
        , iosPosition "right"
        , onTap DoneEditing
        ]
        []
    ]

actionItem : List (Html.Attribute msg) -> List (Html msg) -> Html msg

Action Item should be a child of actionBar. Refer actionBar for example

activityIndicator : List (Html.Attribute msg) -> List (Html msg) -> Html msg

Refer

ActivityIndicator is a UI component that shows a progress indicator signaling to the user of an operation running in the background.

activityIndicator
    [ busy isBusy
    , onBusyChange SomeMessage
    , onLoaded IndicatorLoaded
    , color "#610fc8"
    ]
    []

button : List (Html.Attribute msg) -> List (Html msg) -> Html msg

Refer

Button is a UI component that displays a button which reacts to a user gesture. For more information about the available gestures, see Gestures in the documentation.

button [ text "Tap me!", onTap ButtonTappedMsg ] []

datePicker : List (Html.Attribute msg) -> List (Html msg) -> Html msg

Refer

DatePicker is a UI component that lets users select a date from a pre-configured range.

datePicker
    [ year "1980"
    , month "4"
    , day "20"
    , minDate "1980-02-01"
    ]
    []

formattedString : List (Html.Attribute msg) -> List (Html msg) -> Html msg

Refer

If you need to style parts of the text, you can use a combination of a FormattedString and Span elements.

formattedString []
    [ span [ text "Hello", fontStyle "bold" ] []
    , span [ text "World", fontStyle "italic" ]
    ]

getEncodedItems : ListViewModel a -> Json.Encode.Value

Gets encoded items from the model

getListItems : ListViewModel a -> List a

Gets items from the model

htmlView : List (Html.Attribute msg) -> List (Html msg) -> Html msg

Refer

HtmlView is a UI component that lets you show static HTML content. See also WebView

htmlView [ html "<div><h1>HtmlView</h1></div>" ] []

htmlView
    [ html """
      <!DOCTYPE html>
      <html>
          <head>
          </head>
          <body>
              <span style="color: green">Hello World</span>
          </body>
      </html>
      """
    ]
    []

image : List (Html.Attribute msg) -> List (Html msg) -> Html msg

Refer

Image is a UI component that shows an image from an ImageSource or from a URL. When working with images following the best practices is a must.

image [ src "res://icon" stretch "aspectFill" ] []

image [ src imageUrl, stretch "aspectFill", height "200" ] []

label : List (Html.Attribute msg) -> List (Html msg) -> Html msg

Refer

label is a UI component that displays read-only text. This

label
    [ text "Elm"
    , textAlignment "center"
    , color "#610fc8"
    , fontSize "40"
    ]
    []

listPicker : List (Html.Attribute msg) -> List (Html msg) -> Html msg

Refer

ListPicker is a UI component that lets the user select a value from a pre-configured list. We have to encode as List String values and pass the encoded value into items

listPicker
    [ E.list E.string
        [ "2022", "2021", "2020" ]
        |> items
    , selectedIndex "1"
    ]
    []

listViewWithMultipleTemplate : String -> List (Html.Attribute msg) -> List (Html msg) -> Html msg

To build a ListView with multiple templates and choose one based on the item, We need to build templateSelectorExpression. templateSelectorExpression has access to $value and $index variables. In addition to that, we should set a key attribute for all the children which will act as template id when picking the right template.

import Attributes as N
...

listViewWithMultipleTemplate
    -- Use single quotes (') to create a JS string.
    (dangerousEvalExpression " ($value % 2 == 0) || ($index % 3 == 0) ? 'even' : 'odd' " )
    [ items model.items -- here items is ListViewModel Int
    ]
    -- Since $value is Int, we can use .toString() method on number to convert a number to string
    [ Layout.stackLayout [ key "odd", color "red" ]
        [ label [ text (bindingExpression " $value.toString() " ) ] []
        ]
    , Layout.stackLayout [ key "even", color "green" ]
        [ label [ text (bindingExpression " $value.toString() " ) ] []
        ]
    ]

listViewWithSingleTemplate : List (Html.Attribute msg) -> Html msg -> Html msg

Refer

ListView is a UI component that shows items in a vertically scrolling list. Using a ListView requires some special attention due to the complexity of the native implementations, with custom item templates, bindings and so on.

listViewWithSingleTemplate
    [ height "100%"
    , separatorColor "transparent"
    , items listViewModel
    , Event.onItemTap ToDetails
    ]
<|
    Layout.gridLayout
        [ height "280"
        , borderRadius "10"
        , class "bg-secondary"
        , rows "*, auto, auto"
        , columns "*"
        , margin "5, 10"
        , padding "0"
        ]
        [ image
            [ row "0"
            , margin "0"
            , stretch "aspectFill"
            , bindAttributeWithExpression "src" " $value.image "
            ]
            []
        , label
            [ row "1"
            , margin "10, 10, 0, 10"
            , fontWeight "700"
            , class "text-primary"
            , fontSize "18"
            , bindAttributeWithExpression "title" " $value.title "
            ]
            []
        , label
            [ row "2"
            , margin "0, 10, 10, 10"
            , class "text-secondary"
            , fontSize "14"
            , textWrap "true"
            , bindAttributeWithExpression "text" " $value.description "
            ]
            []
        ]

makeListViewModel : (a -> Json.Encode.Value) -> List a -> ListViewModel a

Builds list view model when given encoder function for the value

mapListViewModel : (item2 -> Json.Encode.Value) -> (item1 -> item2) -> ListViewModel item1 -> ListViewModel item2

Maps the value. Similar to List.map

navigationButton : List (Html.Attribute msg) -> List (Html msg) -> Html msg

Left navigation button in action bar.

placeholderView : List (Html.Attribute msg) -> List (Html msg) -> Html msg

Refer

Placeholder allows you to add any native widget to your application. To do that, you need to put a Placeholder somewhere in the UI hierarchy and then create and configure the native widget that you want to appear there. Finally, pass your native widget to the event arguments of the creatingView event. Use ports to have access to the rendering element and its native object.

placeholderView
    [ id "placeholder"
    , on "creatingView" (Decode.succeed CreatingPlaceholder)
    ]
    []

progress : List (Html.Attribute msg) -> List (Html msg) -> Html msg

Refer

Progress is a UI component that shows a bar to indicate the progress of a task.

progress
    [ value "50"
    , maxValue "100"
    , backgroundColor "red"
    , color "green"
    , scaleY "2"
    ]
    []

scrollView : List (Html.Attribute msg) -> Html msg -> Html msg

Refer

ScrollView is a UI component that shows a scrollable content area. Content can be scrolled vertically or horizontally.

It's important to note that ScrollView extends ContentView, so it can only have a single child element.

scrollView [ orientation "horizontal" ] <|
    stackLayout []
        [ label [ text "this" ] []
        , label [ text "text" ] []
        , label [ text "scrolls" ] []
        , label [ text "horizontally" ] []
        , label [ text "if necessary" ] []
        ]

searchBar : List (Html.Attribute msg) -> List (Html msg) -> Html msg

Refer

SearchBar is a UI component that provides a user interface for entering search queries and submitting requests to the search provider.

searchBar
    [ hint "Search hint"
    , text "searchPhrase"
    , on "submit" (Decode.succeed Submitted)
    , on "clear" (Decode.succeed Cleared)
    ]
    []

segmentedBar : List (Html.Attribute msg) -> List (Html msg) -> Html msg

Refer

SegmentedBar is a UI bar component that displays a set of buttons for discrete selection. Can show text or images.

segmentedBar []
    [ segmentedBarItem [ title "First" ] []
    , segmentedBarItem [ title "Second" ] []
    , segmentedBarItem [ title "Third" ] []
    ]

As opposed to TabView:

segmentedBarItem : List (Html.Attribute msg) -> List (Html msg) -> Html msg

Child for segmentedBar.

slider : List (Html.Attribute msg) -> List (Html msg) -> Html msg

Refer

Slider is a UI component that provides a slider control for picking values within a specified numeric range. It returns Float value. Don't try to truncate Float and set Int value for slider value. This will result in weird/janky UI experience. If you want Int, then have 2 fields for slider like sliderFloatValue and sliderIntValue in Model

slider
    [ row "1"
    , colSpan "2"
    , minValue "0"
    , maxValue "5"
    , value (someValue |> String.fromFloat)
    , onValueChange Changed
    ]
    []

span : List (Html.Attribute msg) -> List (Html msg) -> Html msg

Similar to Html span, we can use it in combination with formattedString

span [ text "Hello", fontStyle "bold", style "color: red" ] []

switch : List (Html.Attribute msg) -> List (Html msg) -> Html msg

Refer

Switch is a UI component that lets users toggle between two states.

The default state is false or OFF.

switch [ checked True ] []

tabViewItem : List (Html.Attribute msg) -> List (Html msg) -> Html msg

Should be the child of tabView

tabView []
    [ tabViewItem [ title "Profile" ]
        [ label [ text "Hello" ] []
        ]
    ]

textField : List (Html.Attribute msg) -> List (Html msg) -> Html msg

Refer

TextField is an input component that creates an editable single-line box.

TextField extends TextBase and EditableTextBase which provide additional properties and events.

textField
    [ hint "Enter Text"
    , color "orangered"
    , backgroundColor "lightyellow"
    ]
    []

textView : List (Html.Attribute msg) -> List (Html msg) -> Html msg

Refer

TextView is a UI component that shows an editable or a read-only multi-line text container. You can use it to let users type large text in your app or to show longer, multi-line text on the screen.

TextView extends TextBase and EditableTextBase which provide additional properties and events.

textView
    [ hint "Enter Date"
    , text "Hello World"
    , secure "false"
    , keyboardType "datetime"
    , returnKeyType "done"
    , autocorrect "false"
    , maxLength "10"
    ]
    []

timePicker : List (Html.Attribute msg) -> List (Html msg) -> Html msg

Refer

TimePicker is a UI component that lets users select time.

timePicker
    [ hour "10"
    , minute "25"
    , row "2"
    , col "0"
    , colSpan "2"
    , class "m-15"
    , verticalAlignment "center"
    , on "timeChange" (Decode.succeed TimeChanged)
    ]
    []

webView : List (Html.Attribute msg) -> List (Html msg) -> Html msg

Refer

WebView is a UI component that lets you show web content in your app. You can pull and show content from a URL or a local HTML file, or you can render static HTML content.

webView [ src "<div><h1>Some static HTML</h1></div>" ] []

webView [ src "http://nativescript.org/" ] []

webView [ src "~/html/index.html" ] []