High Mountains 🏔️

Package VersionHex 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:

Function Alpine Directive Description
data(js_object)x-data Initialize component data
init(js)x-init Run on initialization
show(js)x-show Toggle visibility
show_important(js)x-show.important Force visibility toggle
bind(attr, js)x-bind:attr Bind attribute to expression
on(event, modifiers, js)x-on:event Handle events
text(js)x-text Set text content
html(js)x-html Set innerHTML
model(modifiers, js)x-model Two-way data binding
modelable(js)x-modelable Make property modelable
for(key, value)x-for Loop through collections
key(js):key Unique key for iterations
x_if(js)x-if Conditional rendering
effect(js)x-effect Watch dependencies
ignore()x-ignore Prevent Alpine initialization
ref(id)x-ref Element reference
cloak()x-cloak Hide until Alpine loads
teleport(selector)x-teleport Move element in DOM
id(js)x-id ID scoping

Transition Functions

Function Description
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