Skip to content

Repository files navigation

English | Korean | Japanese

glendix

glendix is the JavaScript-target build and rendering bridge for Mendix Pluggable Widgets written in Gleam.

Its package boundary is explicit:

  • glendix owns Pluggable Widgets Tools orchestration, widget definition editing, external npm React bindings, and the Lustre-to-React bridge;
  • mendraw owns Mendix client values and bindings generated from installed .mpk assets;
  • mxpak owns Marketplace search, package download, cache, lockfiles, and workspace deduplication;
  • glendam owns generic browser automation.

Glendix does not implement Marketplace access or browser automation.

Install

[dependencies]
glendix = ">= 5.0.0 and < 6.0.0"

Add mendraw only when the project uses Mendix client values or installed MPK components, and add/use mxpak only when package acquisition is required.

A widget project's package.json normally includes the Mendix Pluggable Widgets Tools and their React peer dependencies.

Basic widget

importmendraw/mendiximportredrawimportredraw/dom/attributeimportredraw/dom/htmlpubfnwidget(props:mendix.JsProps)->redraw.Element{lettitle=mendix.get_string_prop(props,"title")html.section([attribute.class("widget")],[html.text(title)])}

This example composes Glendix with Mendraw in the application. Glendix itself remains independently usable for external React bindings and Lustre rendering.

Lustre bridge

importglendix/lustreasglendix_lustreimportgleam/intimportlustre/effectimportlustre/elementimportlustre/element/htmlimportlustre/eventimportredrawtypeModel{Model(count:Int)}typeMessage{Increment}fnupdate(model:Model,message:Message)->#(Model,effect.Effect(Message)){casemessage{Increment->#(Model(model.count+1),effect.none())}}fnview(model:Model)->element.Element(Message){html.button([event.on_click(Increment)],[html.text("Count: "<>int.to_string(model.count)),])}pubfncomponent()->redraw.Element{glendix_lustre.use_tea(#(Model(0),effect.none()),update,view)}

External npm React components

Configure exports in gleam.toml:

[tools.glendix.bindings]
recharts = ["PieChart", "Pie"]

Install the npm package, then run gleam run -m glendix/install. Glendix owns both component lookup and element construction; Mendraw is not required:

importgleam/resultimportglendix/bindingimportredrawimportredraw/dom/attributepubfnpie_chart(attributesattributes:List(attribute.Attribute),childrenchildren:List(redraw.Element),)->Result(redraw.Element,binding.BindingError){usemodule<-result.try(binding.module("recharts"))usecomponent<-result.try(binding.resolve(module,"PieChart"))Ok(binding.element(component,attributes,children))}

binding.element_ creates an element with children only, and binding.void_element creates one without children.

Installed Marketplace widgets

Package acquisition is a separate step owned by mxpak:

[tools.mxpak]
mode = "extract"
[tools.mxpak.widgets.Charts]
version = "3.0.0"
mxp install
gleam run -m mendraw/install
gleam run -m glendix/install
gleam run -m glendix/build
  • mxp install writes package assets to build/widgets/.
  • mendraw/install generates typed MPK bindings.
  • glendix/install installs JavaScript dependencies and generates Glendix npm bindings.
  • glendix/build creates the production .mpk.

Projects that do not use Marketplace widgets omit the first two steps.

Commands

CommandResponsibility
gleam run -m glendix/installInstall JS dependencies and generate Glendix npm bindings
gleam run -m glendix/defineEdit widget property definitions
gleam run -m glendix/devRun the development build/server
gleam run -m glendix/buildBuild a production .mpk
gleam run -m glendix/startConnect to the configured Mendix test project
gleam run -m glendix/lintRun lint checks
gleam run -m glendix/lint_fixApply lint fixes
gleam run -m glendix/releaseRun the release build

Development

gleam deps download
gleam format --check
gleam check
gleam build --warnings-as-errors
gleam docs build
gleam test --runtime bun

License

MIT License

Releases

Packages

Contributors

Languages