Component directives

A directive in the context of web development and frameworks like Vue.js, Angular, or similar, is a special token in the markup that tells the library or framework to do something to an element in the page. Directives are extended HTML attributes prefixed with a special character or keyword, often a symbol like v- in Vue.js or ng- in Angular. They apply reactive behavior to the DOM or can even transform the DOM element and its children.

Vue.js directives are parameters of the type v-, like v-if or v-on. In stipple, these are implemented through the macros @click, @on, @iif, @els, @elsiif, @recur, @text, @bind, @data and @showif. Each macro provides a way to manipulate a component in UI code by generating the equivalent HTML as:

julia> span(@showif(true))
"<span v-show=\"true\"></span>"

julia> span(@click(:mybutton))
"<span v-on:click=\"mybutton = true\"></span>"

julia> span(@click("process = !process"))
"<span v-on:click=\"process = !process\"></span>"

Note that, if a directive takes a string argument, its content must be valid Javascript code.

Loop component generation with @recur

The @recur macro is used to generate UI components in a loop over a list. This macro adds a for loop that iterates over the specified list. In each iteration, the nested components are evaluated with the current value of the loop variable.

module App
using GenieFramework
@genietools

@app begin
    @out messages = ["msg1", "msg2", "msg3"]
end

function ui()
    row([card(style="margin: 10px;", @recur("msg in messages"), [
        p("{{msg}}")
    ]),])
end
@page("/", ui)
end

In this example, the @recur macro is used to iterate over the messages list. For each message in the list, a paragraph (p) component is created with the content of the message. This results in a row of cards, each containing a paragraph with one of the messages.

The @recur macro is particularly useful when you need to generate a large number of similar components based on a list of data. It allows you to avoid repetitive code and makes your app more maintainable and scalable.

Conditional rendering with @showif

The @showif macro is used to conditionally render elements in the UI based on the state of a reactive variable. You can use it with a button to toggle showing an element in the UI:

@app begin
    @in show_element = false
end

function ui()
    [ 
        btn("Toggle Element", @click("show_element =! show_element")),
        div("This is a hidden element", @showif("show_element"))
    ]
end

In this example, clicking the "Toggle Element" button will toggle the state of the show_element reactive variable, which in turn toggles the visibility of the div element. When show_element is true, the div will be visible; when show_element is false, the div will be hidden.