Lustre Prefab 🎨

Package Version Hex Docs

A UI component library for Lustre built on lustre_stylish. Inspired by prefab-ui (Elm) and the Clarity Design System.

Installation

gleam add lustre_prefab

Quick Start

import lustre/stylish as el
import lustre/prefab/button
import lustre/prefab/card
import lustre/prefab/theme
import gleam/option.{Some}

pub fn view(model: Model) {
  card.view(
    [el.padding(20)],
    el.column([el.spacing(15)], [
      el.el([
        font.size(24),
        font.color(theme.primary()),
      ], el.text("Welcome!")),
      
      button.new("Get Started", Some(StartClicked))
        |> button.with_style(button.Primary)
        |> button.with_size(button.Large)
        |> button.view([]),
    ])
  )
}

Components

✅ Available Now

All core components from prefab-ui have been successfully ported! 🎉

Features

Type-Safe - Leverages Gleam’s type system for compile-time safety
🎨 Themeable - Consistent color palette across all components
📦 Composable - Built with lustre_stylish’s declarative API
🚀 Zero CSS - All styles generated automatically
📖 Well Documented - Every component includes examples

Button Example

import lustre/prefab/button
import gleam/option.{Some}

// Basic button
button.new("Click me", Some(ButtonClicked))
  |> button.view([])

// Styled button with options
button.new("Submit", Some(FormSubmitted))
  |> button.with_style(button.Primary)
  |> button.with_size(button.Large)
  |> button.with_variant(button.Solid)
  |> button.view([])

// Outline button
button.new("Cancel", Some(Cancelled))
  |> button.with_style(button.Secondary)
  |> button.with_variant(button.Outline)
  |> button.view([])

// Disabled button
button.new("Loading...", option.None)
  |> button.with_disabled()
  |> button.view([])

Card Example

import lustre/prefab/card
import lustre/stylish as el

card.view(
  [el.padding(30), el.width(el.px(400))],
  el.column([el.spacing(10)], [
    el.text("Card Title"),
    el.text("Card content goes here"),
  ])
)

Theme Example

import lustre/prefab/theme
import lustre/stylish/background
import lustre/stylish/font

el.el([
  background.color(theme.primary()),
  font.color(theme.white()),
], el.text("Themed element"))

// Semantic colors
background.color(theme.success())
background.color(theme.danger())
background.color(theme.warning())
background.color(theme.info())

// With alpha transparency
background.color(theme.primary_alpha(0.5))

Text Example

import lustre/prefab/text

// Headers
text.h1([], "Main Title")
text.h2([], "Subtitle")

// Body text
text.body([], "This is body text")
text.label([], "Form Label")
text.help_text([], "Helper text goes here")

Alert Example

import lustre/prefab/alert

// Success alert with dismiss
alert.new("Operation completed successfully!")
  |> alert.with_type(alert.Success)
  |> alert.with_dismiss(DismissAlert)
  |> alert.view([])

// Warning alert (compact)
alert.new("Please review your input")
  |> alert.with_type(alert.Warning)
  |> alert.with_size(alert.Compact)
  |> alert.view([])

Input Example

import lustre/prefab/input

// Text input
input.new(
  on_change: UpdateName,
  value: model.name,
  label: "Name",
)
|> input.with_placeholder("Enter your name")
|> input.view([])

// Email input with help text
input.new(
  on_change: UpdateEmail,
  value: model.email,
  label: "Email",
)
|> input.with_input_type(input.Email)
|> input.with_help_text("We'll never share your email")
|> input.view([])

Radio Example

import lustre/prefab/radio

radio.new(
  label: "Choose size",
  on_change: UpdateSize,
  selected: Some(model.size),
)
|> radio.with_options([Small, Medium, Large])
|> radio.with_serializer(size_to_string)
|> radio.with_layout(radio.Horizontal)
|> radio.view([])

// Semantic colors background.color(theme.success()) background.color(theme.danger()) background.color(theme.warning()) background.color(theme.info())

// With alpha transparency background.color(theme.primary_alpha(0.5))


## Philosophy

Lustre Prefab follows the same philosophy as lustre_stylish and prefab-ui:

1. **Pre-fabricated but flexible** - Sensible defaults with customization options
2. **Type-safe** - Impossible states are impossible
3. **Composable** - Build complex UIs from simple pieces
4. **Consistent** - Unified theming across all components

## Documentation

Full API documentation available at <https://hexdocs.pm/lustre_prefab>

Or build locally:
```sh
gleam docs build

Development

gleam build  # Build the project
gleam test   # Run the tests
gleam docs build  # Generate documentation

Relationship to prefab-ui

This library is a Gleam/Lustre port of prefab-ui, maintaining API compatibility where possible while adapting to Gleam’s idioms and lustre_stylish’s architecture.

License

MIT License

Acknowledgments

Search Document