High Mountains 🏔️

Package Version Hex Docs

A Gleam library for working with Alpine.js through Lustre attributes

High Mountains provides a type-safe, idiomatic Gleam wrapper for Alpine.js directives, allowing you to build interactive web applications using Alpine.js features within the Lustre ecosystem.

Features

Installation

Add High Mountains to your Gleam project:

gleam add high_mountains

Quick Start

import lustre/element/html
import high_mountains as alpine

pub fn counter_component() {
  html.div([
    alpine.data("{count: 0}"),
    alpine.cloak()
  ], [
    html.button([
      alpine.on("click", [], "count++")
    ], [html.text("Increment")]),
    html.span([
      alpine.text("count")
    ], [])
  ])
}

Core Directives

Data Binding

Control Flow

Events

Effects and Lifecycle

Modifiers

Event Modifiers

import high_mountains/event_modifier.{Prevent, Stop, Debounce}
import gleam/option

html.form([
  alpine.on("submit", [Prevent], "submitForm()")
], [...])

html.input([
  alpine.on("input", [Debounce(option.Some(300))], "search()")
], [])

Available event modifiers:

Model Modifiers

import high_mountains/model_modifier.{Lazy, Number}

html.input([
  alpine.model([Lazy, Number], "price")
], [])

Available model modifiers:

Transition Modifiers

import high_mountains/transition_modifier.{Duration, Scale, Opacity}
import gleam/option

html.div([
  alpine.transition_helper([Duration(300), Scale(option.Some(95), []), Opacity])
], [...])

Available transition modifiers:

Advanced Features

References

html.input([alpine.ref("email")], [])
// Access with $refs.email in Alpine expressions

Teleporting

html.template([
  alpine.teleport("body")
], [
  // Modal content will be moved to body
])

ID Scoping

html.div([
  alpine.id("['tab-content', 'tab-trigger']")
], [
  // Use $id('tab-content') for unique IDs
])

Preventing Initialization

html.div([alpine.ignore()], [
  // Alpine won't initialize this section
])

Preventing Flash

html.div([alpine.cloak()], [
  // Hidden until Alpine loads
])

CSS required for x-cloak:

[x-cloak] { display: none !important; }

Examples

Toggle Component

import lustre/element/html
import high_mountains as alpine

pub fn toggle() {
  html.div([
    alpine.data("{open: false}")
  ], [
    html.button([
      alpine.on("click", [], "open = !open")
    ], [html.text("Toggle")]),
    
    html.div([
      alpine.show("open"),
      alpine.transition_helper([])
    ], [
      html.text("Content that toggles")
    ])
  ])
}

Form with Validation

import lustre/element/html
import high_mountains as alpine
import high_mountains/event_modifier

pub fn form() {
  html.form([
    alpine.data("{email: '', valid: false}"),
    alpine.on("submit", [event_modifier.Prevent], "submit()")
  ], [
    html.input([
      alpine.model([], "email"),
      alpine.on("input", [], "valid = email.includes('@')")
    ], []),
    
    html.button([
      alpine.bind("disabled", "!valid")
    ], [html.text("Submit")])
  ])
}

Dynamic List

import lustre/element/html
import high_mountains as alpine

pub fn todo_list() {
  html.div([
    alpine.data("{todos: [], newTodo: ''}")
  ], [
    html.input([
      alpine.model([], "newTodo"),
      alpine.on("keyup.enter", [], "todos.push(newTodo); newTodo = ''")
    ], []),
    
    html.template([
      alpine.for("todo", "todos")
    ], [
      html.div([
        alpine.key("todo")
      ], [
        html.span([alpine.text("todo")], [])
      ])
    ])
  ])
}

API Reference

Core Functions

All functions return Lustre attributes that can be used with HTML elements:

FunctionAlpine DirectiveDescription
data(js_object)x-dataInitialize component data
init(js)x-initRun on initialization
show(js)x-showToggle visibility
show_important(js)x-show.importantForce visibility toggle
bind(attr, js)x-bind:attrBind attribute to expression
on(event, modifiers, js)x-on:eventHandle events
text(js)x-textSet text content
html(js)x-htmlSet innerHTML
model(modifiers, js)x-modelTwo-way data binding
modelable(js)x-modelableMake property modelable
for(key, value)x-forLoop through collections
key(js):keyUnique key for iterations
x_if(js)x-ifConditional rendering
effect(js)x-effectWatch dependencies
ignore()x-ignorePrevent Alpine initialization
ref(id)x-refElement reference
cloak()x-cloakHide until Alpine loads
teleport(selector)x-teleportMove element in DOM
id(js)x-idID scoping

Transition Functions

FunctionDescription
transition_helper(modifiers)Basic transition with modifiers
transition_helper_enter(modifiers)Enter transition with modifiers
transition_helper_leave(modifiers)Leave transition with modifiers
transition_enter(classes)Enter phase classes
transition_enter_start(classes)Enter start classes
transition_end(classes)Enter end classes
transition_leave(classes)Leave phase classes
transition_leave_start(classes)Leave start classes
transition_leave_end(classes)Leave end classes

Testing

gleam test

Development

gleam build
gleam format
gleam docs build

Contributing

  1. Fork the repository on GitHub
  2. Create a feature branch
  3. Make your changes
  4. Add tests if applicable
  5. Ensure code passes gleam format and gleam test
  6. Submit a pull request

License

MIT License - see LICENSE file for details.

Resources


Made with ❤️ for the Gleam and Alpine.js communities

Search Document