Translate

sábado, 1 de noviembre de 2025

Diseñando interfaces declarativas con Elm UI


Elm es conocido por su modelo funcional puro y su arquitectura confiable (el Elm Architecture).

Sin embargo, muchos desarrolladores se frustran al escribir HTML y CSS en el código de Elm tradicional.

Ahí entra Elm UI, una librería creada por Matthew Griffith que propone algo radical:

“Construir interfaces sin HTML ni CSS.”

mdgriffith/elm-ui reemplaza los módulos Html y Html.Attributes por un conjunto de tipos y funciones que representan elementos visuales y propiedades de diseño.

En vez de mezclar markup y estilo, describís la interfaz de forma estructurada y tipada.


Por ejemplo:


import Element exposing (..)

import Element.Font as Font


main =

    layout [] <|

        column [ spacing 20, centerX, centerY ]

            [ el [ Font.bold ] (text "Hola Elm UI!")

            , el [] (text "Una forma diferente de pensar las interfaces.")

            ]


Este código produce una interfaz centrada con dos textos.

Sin CSS, sin HTML — todo se define a través de funciones puras.


Elm UI se basa en unos pocos conceptos muy consistentes:

Element: Unidad visual principal, equivalente a un “nodo” del DOM

layout: Punto de entrada para renderizar la interfaz 

row, column: Contenedores para alinear elementos horizontal o verticalmente 

el: Envuelve un elemento simple (por ejemplo, texto o imagen) 

text: Muestra texto

Attribute msg: Propiedad de estilo o comportamiento (como `spacing`, `padding`, `centerX`, `Font.size`, etc.)


Veamos un ejemplo más completo: una pequeña tarjeta de usuario.


import Element exposing (..)

import Element.Background as Background

import Element.Border as Border

import Element.Font as Font


viewUser : Element msg

viewUser =

    el

        [ Background.color (rgb255 240 240 255)

        , Border.rounded 12

        , padding 16

        , width (px 250)

        , centerX

        ]

    <|

        column [ spacing 8 ]

            [ el [ Font.bold, Font.size 20 ] (text "Emanuel Goette")

            , el [ Font.color (rgb255 100 100 100) ] (text "Desarrollador de software")

            , el [] (text "🌎 Argentina")

            ]


Y en el main:


main =

    layout [] viewUser


El resultado: una tarjeta limpia, centrada, con esquinas redondeadas y colores suaves.

Todo expresado como funciones y tipos, sin estilos externos.


Elm UI funciona perfectamente dentro del patrón clásico Model, Update, View.

Ejemplo simple:


import Browser

import Element exposing (..)

import Element.Font as Font


type alias Model =

    { counter : Int }


init : Model

init =

    { counter = 0 }


type Msg

    = Increment

    | Decrement


update msg model =

    case msg of

        Increment ->

            { model | counter = model.counter + 1 }


        Decrement ->

            { model | counter = model.counter - 1 }


view model =

    layout []

        (column [ spacing 16, centerX, centerY ]

            [ el [ Font.size 24 ] (text ("Contador: " ++ String.fromInt model.counter))

            , row [ spacing 10 ]

                [ button "-" Decrement

                , button "+" Increment

                ]

            ]

        )


button label msg =

    el

        [ Background.color (rgb255 100 149 237)

        , Font.color (rgb255 255 255 255)

        , Border.rounded 6

        , paddingXY 16 8

        , mouseDown [ onClick msg ]

        ]

        (text label)


main =

    Browser.sandbox { init = init, update = update, view = view }


Un pequeño contador con estilo nativo y sin HTML.


Elm UI lleva la programación declarativa al diseño visual.

En lugar de pensar en “cómo” maquetar una interfaz, pensás en qué representa cada parte de ella.

“Elm UI te obliga a pensar en tu interfaz como un modelo de datos, no como una plantilla.”

Ideal para quienes buscan precisión, seguridad y coherencia en sus diseños.


Dejo link: 

https://package.elm-lang.org/packages/mdgriffith/elm-ui/latest/

https://ellie-app.com