Skip to content

Instantly share code, notes, and snippets.

@zefhemel
Last active March 31, 2025 13:51
Show Gist options
  • Save zefhemel/36074f8af506fdc4dcaee7b140822f8e to your computer and use it in GitHub Desktop.
Save zefhemel/36074f8af506fdc4dcaee7b140822f8e to your computer and use it in GitHub Desktop.

Proof-of-concept library to easily build DOM-based Lua widgets with the magic of Lua meta tables.

Usage

-- any HTML tag can be used here
dom.span {
  -- tag attributes can be set like this:
  class = "my-class",
  id = "my-id",
  -- Plain text body elements can be added like this
  "Span content",
  -- And elements can be nested
  dom.strong { "I am strong" }
}

Examples

${dom.marquee{ "I'm in a ", dom.span { style="color:red;", "marquee" } }}

Implementation

dom =  setmetatable({}, {
  __index = function(self, tag)
    return function(spec)
      local node = js.window.document.createElement(tag)
      for key, val in pairs(spec) do
        if type(key) == "string" then
          -- This is an attribute
          node.setAttribute(key, val)
        elseif type(val) == "string" then
          -- Text body
          node.appendChild(js.window.document.createTextNode(val))
        elseif val._isWidget and val.html then
          -- Implicit assumption: .html is a DOM node
          node.appendChild(val.html)
        else
          js.log("Don't know what to do with", val)
          error("Invalid node, see JS console")
        end
      end
      return widget.html(node)
    end
  end
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment