lustre_transition

Package Version Hex Docs

Installation

  1. Add lustre to your project

Lustre is published on Hex! You can add it to your Gleam projects from the command line:

gleam add lustre
  1. Add lustre_transitions to your project
gleam add lustre_transitions
  1. Add lustre_dev_tools to your project

Lustre’s dev tools are published on Hex! You can add them as a dev dependency to your Gleam projects from the command line:

Note: currently one of lustre_dev_tools’ dependencies is not compatible with the most recent version of gleam_json, making it impossible to install. To fix this, add gleam_json = "1.0.1" as a dependency in your gleam.toml file.

gleam add lustre_dev_tools --dev
  1. Add tailwind support

Download a platform-appropriate version of the Tailwind binary.

gleam run -m lustre/dev add tailwind
  1. Serve your project

Start a development server for your Lustre project. This command will compile your application and serve it on a local server.

gleam run -m lustre/dev start

Example

import gleam/dynamic
import gleam/option.{Some}
import gleam/result
import lustre
import lustre/attribute
import lustre/effect.{type Effect}
import lustre/element.{type Element}
import lustre/element/html
import lustre/event
import transition.{type State}

pub fn main() {
  let app = lustre.application(init, update, view)
  let assert Ok(_) = lustre.start(app, "#app", Nil)
}

type Model {
  Model(panel_state: transition.State)
}

pub opaque type Msg {
  UserClickedButton
  TransitionStarted
  TransitionEnded(String)
}

fn init(_flags) -> #(Model, Effect(Msg)) {
  #(Model(transition.Init), effect.none())
}

fn update(model: Model, msg: Msg) -> #(Model, Effect(Msg)) {
  case msg {
    UserClickedButton -> #(
      Model(panel_state: transition.toggle(Some(model.panel_state))),
      transition.start(TransitionStarted),
    )
    TransitionStarted -> #(
      Model(panel_state: transition.next(Some(model.panel_state))),
      effect.none(),
    )
    TransitionEnded(_) -> #(
      Model(panel_state: transition.end(Some(model.panel_state))),
      effect.none(),
    )
  }
}

fn view(model: Model) -> Element(Msg) {
  html.div([attribute.class("p-4")], [
    html.button(
      [
        event.on_click(UserClickedButton),
        attribute.class(
          "rounded-md bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focusivisible:outline-2 focus-visible:outline-indigo-600",
        ),
      ],
      [element.text("Click Me!")],
    ),
    panel(model.panel_state),
  ])
}

fn panel(state: State) {
  // "hidden" - we need to add this here so that tailwind doesn't strip out this class
  let classes =
    transition.Classes(
      enter: #(
        "transition ease-out duration-300",
        "opacity-0 scale-90",
        "opacity-100 scale-100",
      ),
      leave: #(
        "transition ease-in duration-300",
        "opacity-100 scale-100",
        "opacity-0 scale-90",
      ),
    )
    |> transition.apply(state)
  html.div(
    [
      attribute.class(classes),
      attribute.id("hello"),
      event.on("transitionend", handle_transition_end),
    ],
    [element.text("Hello World!")],
  )
}

fn handle_transition_end(event) -> Result(Msg, List(dynamic.DecodeError)) {
  use target <- result.try(dynamic.field("target", dynamic.dynamic)(event))
  use id <- result.try(dynamic.field("id", dynamic.string)(target))
  Ok(TransitionEnded(id))
}

Further documentation can be found at https://hexdocs.pm/lustre_transition.

Search Document