The sample project's package.json includes classnames (^2.5.1) as a dependency, but it is not used in glendix itself. The classnames API is trivially replaceable with a Gleam utility function.
classNames('foo', 'bar'); // "foo bar"
classNames('foo', { bar: true }); // "foo bar"
classNames({ foo: true }, { bar: false }); // "foo"
classNames('foo', { bar: true, baz: false }, 'qux'); // "foo bar qux"Only the conditional class joining pattern ({ className: bool }) is practically used in widget development. Static class names are just string concatenation.
Add a cx utility to glendix/mendix (or a shared util module):
import gleam/list
import gleam/string
/// Conditionally join CSS class names.
///
/// ```gleam
/// cx([#("btn", True), #("btn-primary", is_primary), #("disabled", !enabled)])
/// // => "btn btn-primary"
/// ```
pub fn cx(classes: List(#(String, Bool))) -> String {
classes
|> list.filter_map(fn(pair) {
case pair.1 {
True -> Ok(pair.0)
False -> Error(Nil)
}
})
|> string.join(" ")
}Usage with redraw/dom/attribute:
import redraw/dom/attribute
import glendix/mendix // or wherever cx lives
html.div(
[attribute.class(mendix.cx([
#("widget-container", True),
#("active", is_active),
#("error", has_error),
]))],
[..children],
)- Add
cxfunction to glendix (e.g.,src/glendix/mendix.gleamor a newsrc/glendix/util.gleam) - Update
glendix_guide.mdwith thecxpattern - Remove
classnamesfrom sample projectpackage.json - Update any documentation referencing
classnames
- No FFI or
.mjsfile needed — pure Gleam - Zero runtime dependency added
- API is intentionally simpler than classnames (no nested objects, no arrays) — the tuple-based
#(String, Bool)pattern covers all real-world Mendix widget use cases - For static class names, plain string concatenation or
string.joinis sufficient