# Lustre Prefab 🎨
[](https://hex.pm/packages/lustre_prefab)
[](https://hexdocs.pm/lustre_prefab/)
A UI component library for [Lustre](https://github.com/lustre-labs/lustre) built on [lustre_stylish](https://hex.pm/packages/lustre_stylish). Inspired by [prefab-ui](https://github.com/mc706/prefab-ui) (Elm) and the [Clarity Design System](https://clarity.design/).
## Installation
```sh
gleam add lustre_prefab
```
## Quick Start
```gleam
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
- **`button`** - Buttons with multiple styles (Primary, Secondary, Success, Danger, Warning, Info), sizes (Normal, Small, Large, Block), and variants (Solid, Outline, Flat)
- **`card`** - Container with white background, rounded borders, and shadow
- **`theme`** - Comprehensive color palette with semantic colors
- **`text`** - Predefined text styles (h1-h6, body, label, helpText, sectionHeader)
- **`alert`** - Alert/notification messages with types and dismiss functionality
- **`link`** - Hyperlinks styled as buttons with all button variants
- **`checkbox`** - Checkbox inputs with labels
- **`input`** - Text inputs with multiple types (Text, Email, Password, Multiline, etc.) and layouts
- **`radio`** - Radio button groups with multiple layout options (Vertical, Horizontal, Compact, etc.)
- **`loader`** - Simple loading indicator
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
```gleam
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
```gleam
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
```gleam
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
```gleam
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
```gleam
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
```gleam
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
```gleam
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
```sh
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](https://github.com/mc706/prefab-ui), maintaining API compatibility where possible while adapting to Gleam's idioms and lustre_stylish's architecture.
## License
MIT License
## Acknowledgments
- **prefab-ui** - The original Elm implementation
- **Clarity Design System** - Design inspiration
- **lustre_stylish** - The foundation layout library
- **Lustre** - The excellent Gleam web framework