Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 43 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# Ash UI

A resource-driven UI framework for Elixir built on the Ash Framework, enabling dynamic UI generation from database resources through Phoenix LiveView and static web rendering.
A resource-driven UI framework for Elixir built on the Ash Framework, enabling dynamic UI generation from database resources through the unified UI rendering ecosystem.

## Overview

Ash UI provides a declarative approach to building user interfaces by defining UI components as Ash resources. This enables:

- **Database-Driven UI** - Define screens and elements as resources
- **Reactive Data Binding** - Connect UI directly to Ash resources
- **Dual Rendering** - Output to LiveView (interactive) or static HTML
- **Multi-Platform Rendering** - Output to LiveView, static HTML, or desktop via unified renderer packages
- **Type Safety** - Leverage Ash's type system for UI components
- **Authorization-First** - Built-in policy-based access control

Expand All @@ -24,22 +24,38 @@ flowchart LR

subgraph AshUI["Ash UI Framework"]
Compiler["Compiler"]
IUR["IUR"]
Renderer["Renderer"]
IUR["Ash IUR"]
Adapter["IUR Adapter"]
end

subgraph Unified["Unified Ecosystem"]
Canonical["Canonical IUR"]
end

subgraph Renderers["Renderer Packages"]
Live["live_ui"]
Web["web_ui"]
Desktop["desktop_ui"]
end

subgraph Output["User Interface"]
Live["LiveView"]
LV["LiveView"]
HTML["Static HTML"]
Native["Desktop UI"]
end

Element --> Compiler
Screen --> Compiler
Binding --> Compiler
Compiler --> IUR
IUR --> Renderer
Renderer --> Live
Renderer --> HTML
IUR --> Adapter
Adapter --> Canonical
Canonical --> Live
Canonical --> Web
Canonical --> Desktop
Live --> LV
Web --> HTML
Desktop --> Native
```

## Quick Start
Expand All @@ -52,6 +68,8 @@ Add to your `mix.exs`:
def deps do
[
{:ash_ui, "~> 0.1"},
{:unified_iur, "~> 0.1"}, # Canonical IUR format
{:live_ui, "~> 0.1"}, # LiveView renderer (or web_ui, desktop_ui)
{:ash, "~> 3.0"},
{:phoenix_live_view, "~> 1.0"}
]
Expand Down Expand Up @@ -82,14 +100,15 @@ end
```elixir
defmodule MyAppWeb.DashboardLive do
use MyAppWeb, :live_view
use AshUI.LiveView

def mount(params, _session, socket) do
{:ok, mount_ui_screen(socket, :dashboard, params)}
end
end
```

The `mount_ui_screen/3` helper handles compilation, IUR conversion, and rendering.

## Documentation

### User Guides
Expand Down Expand Up @@ -127,9 +146,9 @@ This project is in early development. The governance system and core architectur
|---|---|
| Governance System | ✅ Implemented |
| Resource Definitions | 🚧 In Progress |
| Compilation Pipeline | 🚧 Planned |
| LiveView Rendering | 🚧 Planned |
| Static Rendering | 🚧 Planned |
| Compilation Pipeline | 🚧 In Progress |
| IUR Adapter | 🚧 Planned |
| Renderer Integration | 🚧 Planned (via unified packages) |

## Governance

Expand All @@ -148,11 +167,16 @@ See [RFC-0001](rfcs/RFC-0001-ash-ui-governance-system.md) for details on the gov
| Control Plane | Scope | Module |
|---|---|---|
| Framework | Resource definitions, type system | `AshUI.Framework` |
| Compilation | Resource → IUR pipeline | `AshUI.Compilation` |
| Rendering | Output generation | `AshUI.Rendering` |
| Compilation | Resource → canonical IUR pipeline | `AshUI.Compilation` |
| Rendering | IUR adaptation, renderer delegation | `AshUI.Rendering` |
| Runtime | Session lifecycle | `AshUI.Runtime` |
| Extension | Widgets, plugins | `AshUI.Extension` |

**External Renderer Packages** (unified ecosystem):
- `live_ui` - Phoenix LiveView rendering
- `web_ui` - Static HTML + Elm rendering
- `desktop_ui` - Native desktop rendering

See [Control Plane Ownership](specs/contracts/control_plane_ownership_matrix.md) for details.

## Contributing
Expand All @@ -171,6 +195,11 @@ We welcome contributions! Please:
## Related Projects

- [Ash Framework](https://ash-hq.org/) - The declarative foundation
- [Unified UI Ecosystem](https://github.com/your-org/unified) - Renderer packages:
- [unified_iur](https://github.com/your-org/unified/tree/main/packages/unified_iur) - Canonical IUR format
- [live_ui](https://github.com/your-org/unified/tree/main/packages/live_ui) - LiveView renderer
- [web_ui](https://github.com/your-org/unified/tree/main/packages/web_ui) - Static HTML renderer
- [desktop_ui](https://github.com/your-org/unified/tree/main/packages/desktop_ui) - Desktop renderer
- [Phoenix](https://www.phoenixframework.org/) - The web framework
- [Phoenix LiveView](https://hexdocs.pm/phoenix_live_view) - Real-time UI

Expand Down
96 changes: 73 additions & 23 deletions guides/developer/DG-0001-architecture-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,15 @@ flowchart TB
end

subgraph Rendering["Rendering Control Plane"]
LiveRenderer["LiveView Renderer"]
WebRenderer["Static Renderer"]
Adapter["IUR Adapter"]
Registry["Renderer Registry"]
end

subgraph Unified["Unified Ecosystem"]
Canonical["Canonical IUR"]
LiveRenderer["LiveUI.Renderer"]
WebRenderer["WebUI.Renderer"]
DesktopRenderer["DesktopUI.Renderer"]
end

LiveView --> Session
Expand All @@ -76,9 +83,15 @@ flowchart TB
Compiler --> IUR
IUR --> Validator
Validator --> Normalizer
Normalizer --> Adapter
Adapter --> Canonical

Canonical --> LiveRenderer
Canonical --> WebRenderer
Canonical --> DesktopRenderer

Normalizer --> LiveRenderer
Normalizer --> WebRenderer
LiveRenderer --> LiveView
WebRenderer --> Static

Validator --> Element
Validator --> Screen
Expand All @@ -95,12 +108,14 @@ flowchart TB
classDef rendering fill:#f3e5f5,stroke:#4a148c,stroke-width:2px
classDef runtime fill:#e8f5e9,stroke:#1b5e20,stroke-width:2px
classDef data fill:#eceff1,stroke:#37474f,stroke-width:2px
classDef unified fill:#e0f2f1,stroke:#00695c,stroke-width:2px

class Element,Screen,Binding framework
class Compiler,IUR,Validator,Normalizer compilation
class LiveRenderer,WebRenderer rendering
class Adapter,Registry rendering
class Session,Event,Lifecycle runtime
class Resources,DB data
class Canonical,LiveRenderer,WebRenderer,DesktopRenderer unified
```

## Control Planes
Expand Down Expand Up @@ -141,13 +156,16 @@ Ash UI is organized into five control planes, each with distinct authority and r

**Module**: `AshUI.Rendering`

**Authority**: Output generation for target platforms
**Authority**: IUR adaptation and renderer delegation

**Components**:
- `AshUI.Renderer.LiveView` - LiveView rendering
- `AshUI.Renderer.Static` - Static HTML rendering
- `AshUI.Renderer.Registry` - Renderer registry
- `AshUI.Renderer.Presenter` - Presentation logic
- `AshUI.Rendering.IURAdapter` - Converts Ash IUR to canonical unified_iur format
- `AshUI.Rendering.Registry` - Manages available renderer packages

**External Renderer Packages** (unified ecosystem):
- `live_ui` - LiveView rendering (https://github.com/your-org/unified/tree/main/packages/live_ui)
- `web_ui` - Static HTML rendering (https://github.com/your-org/unified/tree/main/packages/web_ui)
- `desktop_ui` - Desktop rendering (https://github.com/your-org/unified/tree/main/packages/desktop_ui)

**Key Contract**: [rendering_contract.md](../../specs/contracts/rendering_contract.md)

Expand Down Expand Up @@ -202,7 +220,7 @@ flowchart LR

## Intermediate UI Representation (IUR)

### IUR Schema
### Ash UI IUR Schema (Internal)

```elixir
%AshUI.Compilation.IUR{
Expand All @@ -217,12 +235,25 @@ flowchart LR
}
```

### Canonical IUR Schema (unified_iur package)

```elixir
%UnifiedIUR.Screen{
id: UUID.t(),
elements: [%UnifiedIUR.Element{}],
layout: UnifiedIUR.Layout.t(),
signals: [%UnifiedIUR.Signal{}],
metadata: map()
}
```

### IUR Properties

- **Serializable** - Can be encoded to JSON/binary
- **Immutable** - IUR instances are never modified
- **Self-contained** - All information needed for rendering
- **Versioned** - Schema version for compatibility
- **Convertible** - Ash UI IUR converts to canonical unified_iur format

## Module Namespace

Expand All @@ -243,10 +274,8 @@ AshUI # Application root
│ ├── Normalizer
│ └── Cache
├── Rendering # Rendering Control Plane
│ ├── LiveView
│ ├── Static
│ ├── Registry
│ └── Presenter
│ ├── IURAdapter # Ash IUR → Canonical IUR
│ └── Registry # Renderer package management
├── Runtime # Runtime Control Plane
│ ├── Session
│ ├── Event
Expand All @@ -257,6 +286,12 @@ AshUI # Application root
└── Loader
```

**External Packages** (unified ecosystem):
- `unified_iur` - Canonical IUR schema and types
- `live_ui` - LiveView renderer
- `web_ui` - Static HTML renderer
- `desktop_ui` - Desktop renderer

## Extension Points

### Custom Element Types
Expand All @@ -278,21 +313,36 @@ AshUI.Extension.Widget.register(:my_custom, MyApp.CustomElement)

### Custom Renderers

Implement the renderer behaviour:
Custom renderers are implemented via the unified ecosystem packages. To create a custom renderer:

1. **For Ash UI integration**: Ensure your renderer accepts canonical unified_iur format
2. **Implement renderer contract**: Follow the unified ecosystem renderer spec
3. **Register with Ash UI**: Add to renderer registry

```elixir
defmodule MyApp.CustomRenderer do
@behaviour AshUI.Renderer
# Example: Using live_ui renderer
defmodule MyAppWeb.MyLive do
use Phoenix.LiveView

def render(iur, opts) do
# Custom rendering logic
end
def mount(_params, _session, socket) do
# Compile Ash UI screen
{:ok, iur} = AshUI.Compilation.compile(:my_screen, %{})

def can_render?(iur), do: true
def format, do: :custom
# Convert to canonical IUR
{:ok, canonical_iur} = AshUI.Rendering.IURAdapter.to_canonical(iur)

# Render via live_ui
{:ok, heex} = LiveUI.Renderer.render(canonical_iur, [])

{:ok, assign(socket, :content, heex)}
end
end
```

For creating custom renderer packages, see:
- [Unified Ecosystem Architecture](https://github.com/your-org/unified/blob/main/.spec/specs/architecture.spec.md)
- [Platform Runtimes Spec](https://github.com/your-org/unified/blob/main/.spec/specs/platform_runtimes.spec.md)

## Data Flow

### LiveView Request Flow
Expand Down
Loading
Loading