All checks were successful
CI / build (push) Successful in 40s
- Remove test step from CI (WASM-only code can't run native tests) - Update manifesto links to use absolute Gitea URLs Co-Authored-By: Claude <noreply@anthropic.com>
102 lines
2.2 KiB
Markdown
102 lines
2.2 KiB
Markdown
# Iris
|
|
|
|
WASM reactive UI framework for Go.
|
|
|
|
## Organization Context
|
|
|
|
This repo is part of Flowmade. See:
|
|
- [Organization manifesto](https://git.flowmade.one/flowmade-one/architecture/src/branch/main/manifesto.md) - who we are, what we believe
|
|
- [Repository map](https://git.flowmade.one/flowmade-one/architecture/src/branch/main/repos.md) - how this fits in the bigger picture
|
|
- [Vision](./vision.md) - what this specific product does
|
|
|
|
## Setup
|
|
|
|
```bash
|
|
git clone git@git.flowmade.one:flowmade-one/iris.git
|
|
cd iris
|
|
```
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
iris/
|
|
├── reactive/ # Signal[T], Effect, Runtime - core reactivity
|
|
├── ui/ # Components: Button, Text, Input, View, Canvas, SVG
|
|
├── navigation/ # Router, guards, history management
|
|
├── auth/ # OIDC client for WASM applications
|
|
├── host/ # Static file server for WASM apps
|
|
└── internal/ # Internal element abstraction
|
|
```
|
|
|
|
## Development
|
|
|
|
```bash
|
|
# Build (WASM target)
|
|
GOOS=js GOARCH=wasm go build ./...
|
|
|
|
# Build host server (native)
|
|
go build ./host/...
|
|
|
|
# Test
|
|
go test ./...
|
|
|
|
# Lint
|
|
golangci-lint run
|
|
```
|
|
|
|
## Architecture
|
|
|
|
### Reactivity Model
|
|
|
|
Iris uses a signals-based reactivity model:
|
|
|
|
```go
|
|
// Create a signal
|
|
count := reactive.NewSignal(0)
|
|
|
|
// Read value
|
|
fmt.Println(count.Get())
|
|
|
|
// Update value - triggers dependent effects
|
|
count.Set(count.Get() + 1)
|
|
|
|
// Create derived state
|
|
doubled := reactive.Computed(func() int {
|
|
return count.Get() * 2
|
|
})
|
|
```
|
|
|
|
### Components
|
|
|
|
All UI components implement a common interface and render to DOM elements:
|
|
|
|
```go
|
|
// Create a button
|
|
btn := ui.Button("Click me", func() {
|
|
count.Set(count.Get() + 1)
|
|
})
|
|
|
|
// Create reactive text
|
|
text := ui.Text(func() string {
|
|
return fmt.Sprintf("Count: %d", count.Get())
|
|
})
|
|
```
|
|
|
|
### Routing
|
|
|
|
Client-side routing with guards:
|
|
|
|
```go
|
|
router := navigation.NewRouter()
|
|
router.Route("/", homeView)
|
|
router.Route("/users/:id", userView)
|
|
router.Guard("/admin/*", authGuard)
|
|
```
|
|
|
|
## Key Patterns
|
|
|
|
- **No virtual DOM** - Direct DOM manipulation via syscall/js
|
|
- **Signals propagate** - Changes flow through the dependency graph
|
|
- **Components are functions** - Return DOM elements, not component instances
|
|
- **WASM-only UI code** - Use build tags for browser-specific code
|