Skip to content

Latest commit

 

History

6 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 

Repository files navigation

Altair UI

A native UI system for the Altair framework

Built on Crystal · ECR · Tailwind CSS

Components & Contracts — not scattered HTML, CSS, and JavaScript.


What is Altair UI?

Altair UI is not just a component library built on top of Tailwind.

It is a native UI layer inside the Altair framework, connecting:

  • Crystal — real, type-safe APIs (not HTML snippets)
  • ECR — natural composition inside templates
  • Semantic HTML — semantic-first markup
  • Tailwind CSS — a design engine, not the component interface
  • Server & browser behavior — unified under a single contract

The core idea: developers work with Components and Contracts, instead of manually wiring HTML, CSS, JavaScript, forms, validation, and server actions separately.

flowchart TD
    A["Altair UI"] --> B["Component API"]
    A --> C["Server Behavior"]
    A --> D["Browser Behavior"]
    B --> E["Tailwind CSS"]
    C --> E
    D --> E
    E --> F["Altair / External JS"]
    F --> G["Browser"]

    classDef ui fill:#4b5563,stroke:#374151,color:#ffffff;
    class A,B,C,D,E,F,G ui
Loading

The Target Experience

Instead of hand-writing this:

HTML + CSS + JavaScript + validation + CSRF + routes + API requests + error rendering

You write this:

<%= ui.form @product do |form| %>
  <%= form.input :name %>
  <%= form.input :price %>
  <%= form.select :category_id, categories %>

  <%= form.submit "Create Product" %>
<% end %>

Everything else — binding, styling, security — is the system's responsibility.


Architectural Principles

# Principle
1 Crystal-native first — components are real Crystal APIs with type safety, variants, and composition
2 A component is not just HTML — presentation + browser behavior + server behavior
3 JavaScript is opt-in, not mandatory — progressive enhancement over requirement
4 Tailwind powers the design; it does not define the APIAltair UI ≠ Tailwind wrapper
5 Adapters, not dependencies — HTMX, Alpine.js, and Preact are optional integrations

HTML-first · CSS-first · Server-first · JavaScript-last


JavaScript Classification

An official architectural rule: every component declares its JavaScript dependency.

Class Description Runtime Examples
Zero-JS Works entirely without JavaScript none Button · Card · Input · Form · Badge · Alert · Pagination
Progressive-JS HTML first, optional enhancement optional Modal · Dropdown · Tabs · Toast · Combobox
Rich-JS Requires client-side interactivity by nature required DataGrid · Rich Text Editor · Charts · Drag & Drop

The golden rule: JS enhancement — not JS requirement.


Integration Layer

Altair UI is not bound to a single JavaScript framework. The Component Contract stays neutral:

flowchart TD
    CC["Component Contract"] --> N["Native"]
    CC --> AR["Altair Runtime"]
    CC --> AD["Adapters"]
    AD --> H["HTMX<br/><i>hx-*</i>"]
    AD --> AL["Alpine.js<br/><i>x-data</i>"]
    AD --> P["Preact<br/><i>Islands</i>"]

    classDef ui fill:#4b5563,stroke:#374151,color:#ffffff;
    class CC,N,AR,AD,H,AL,P ui
Loading

Altair UI owns the component contract; external JavaScript libraries own specialized client behavior.

Example — Optional HTMX adapter

<%= ui.button(
  "Delete",
  variant: :danger,
  hx: {
    delete: "/products/42",
    target: "#product-42",
    swap: "outerHTML"
  }
) %>

Remove HTMX? The component API remains fully valid.

Example — Islands (Preact)

<%= ui.island "#product-editor", framework: :preact %>

Server-render the application; hydrate only the parts that need it.


Server-aware Components

Altair UI's key differentiator: components understand your server-side model.

flowchart LR
    M["Model"] --> F["Fields"] --> T["Types"] --> V["Validation"] --> E["Errors"] --> C["CSRF"] --> R["Route"] --> S["Response"]
Loading

Once primitives stabilize, this unlocks higher-level APIs:

<%= ui.auto_form @product %>          <%# Fully generated form %>
<%= ui.table Product.all %>           <%# Fully generated table %>

With full override support when you need control:

<%= ui.auto_form @product do |form| %>
  <%= form.field :name %>
  <%= form.field :price, prefix: "$" %>
  <%= form.submit "Create" %>
<% end %>

Component Hierarchy

flowchart TB
    F["Foundation<br/><i>Colors · Typography · Spacing · Icons · Focus States</i>"] --> P["Primitives<br/><i>Button · Input · Label · Badge · Avatar</i>"]
    P --> C["Composite<br/><i>Form · Card · Dialog · Dropdown · Tabs · Toast</i>"]
    C --> A["Application<br/><i>Data Table · Data Grid · Pagination · Command Interface</i>"]

    classDef ui fill:#4b5563,stroke:#374151,color:#ffffff;
    class F,P,C,A ui
Loading

Every component ships with discoverable metadata so developers know its cost before using it:

Modal
JavaScript Progressive-JS
Runtime optional
Bundle small
Tailwind yes
Server-aware no
Adapters HTMX, Alpine

CLI

The CLI is part of the product:

altair ui add button                   # Add a component
altair ui add modal --engine alpine    # Add one with an adapter
altair ui info modal                   # Inspect capabilities & metadata
altair ui adapters list                # List available adapters
altair ui doctor                       # Validate project health

The CLI generates source into your project — you own the code:

lib/
└── altair_ui/
    ├── components/
    ├── themes/
    └── adapters/

Roadmap

Governing rule: no external integration ships before the core contract is proven.

Phase Scope
0 Foundation & Rules — vision · contracts · taxonomy · JS charter
1 Design Foundation — tokens · Tailwind · accessibility
2 Crystal-native Core — base API · rendering · first components
3 Server-aware UI — form engine · actions · auto UI
4 Native Browser Runtime — progressive components · lifecycle
5 CLI & Registry — add/info/doctor · source ownership
6 Integrations — HTMX · Alpine · Preact islands · public adapter API
7 Advanced Components — data grid · command menu · charts
8 DX & Maturity — docs · explorer · testing · performance

What Altair UI Will Never Be

  • A Tailwind wrapper — static class strings are not the value proposition
  • A new JavaScript framework — no heavyweight runtime, no reinvented state management
  • Bound to HTMX, Alpine, or Preact — all are optional adapters
  • An SPA framework — Altair is server-rendered first

The Core Question

Altair UI doesn't answer "which JavaScript framework should I use?"

It answers:

What should the developer's UI contract be — and how can it be delivered at the lowest possible cost?

Crystal-native + HTML-first + Tailwind-powered +
Server-aware + JavaScript-optional + Adapter-friendly + Islands-capable


Altair UI — a native part of the Altair experience, not just another design library.

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors