add comprehensive documentation for external users

Includes getting started guide, hiccup views reference,
full API documentation, and annotated example walkthroughs
with ASCII output examples.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-21 11:37:16 -05:00
parent 9fe0ac2c6e
commit dab0a27e4d
5 changed files with 2712 additions and 97 deletions
+542
View File
@@ -0,0 +1,542 @@
# Hiccup Views
Clojure TUI uses Hiccup-style syntax for declarative UI definitions. Views are pure functions that return nested data structures representing the UI.
## Basic Syntax
Views use vectors with keywords as element tags:
```clojure
[:element-type {attributes} children...]
```
Examples:
```clojure
[:text "Hello"] ;; Simple text
[:text {:fg :red} "Error"] ;; Text with attributes
[:col [:text "Line 1"] [:text "Line 2"]] ;; Nested elements
```
## Elements
### `:text` - Styled Text
The basic building block for displaying text.
```clojure
;; Simple text
[:text "Hello, World!"]
;; Styled text
[:text {:fg :cyan :bold true} "Important"]
;; Multiple style attributes
[:text {:fg :white :bg :red :bold true :underline true} "Alert!"]
```
**Output:**
```
Hello, World!
Important
Alert!
```
**Attributes:**
| Attribute | Type | Description |
|-----------|------|-------------|
| `:fg` | keyword/int | Foreground color |
| `:bg` | keyword/int | Background color |
| `:bold` | boolean | Bold text |
| `:dim` | boolean | Dimmed text |
| `:italic` | boolean | Italic text |
| `:underline` | boolean | Underlined text |
| `:inverse` | boolean | Swap fg/bg colors |
| `:strike` | boolean | Strikethrough text |
### `:row` - Horizontal Layout
Arranges children horizontally (left to right).
```clojure
;; Basic row
[:row "Left" "Middle" "Right"]
;; Row with gap
[:row {:gap 2} "A" "B" "C"]
;; Nested elements in row
[:row
[:text {:fg :green} "Status:"]
[:text {:bold true} "OK"]]
```
**Output:**
```
LeftMiddleRight
A B C
Status:OK
```
**Attributes:**
| Attribute | Type | Description |
|-----------|------|-------------|
| `:gap` | integer | Spaces between children (default: 0) |
### `:col` - Vertical Layout
Arranges children vertically (top to bottom).
```clojure
;; Basic column
[:col "Line 1" "Line 2" "Line 3"]
;; Column with gap
[:col {:gap 1}
[:text "Section 1"]
[:text "Section 2"]]
;; Nested layouts
[:col
[:text {:bold true} "Header"]
[:row "Col A" "Col B" "Col C"]
[:text {:fg :gray} "Footer"]]
```
**Output:**
```
Line 1
Line 2
Line 3
Section 1
Section 2
Header
Col ACol BCol C
Footer
```
**Attributes:**
| Attribute | Type | Description |
|-----------|------|-------------|
| `:gap` | integer | Blank lines between children (default: 0) |
### `:box` - Bordered Container
Wraps content in a bordered box.
```clojure
;; Simple box
[:box "Content"]
;; Box with title
[:box {:title "Settings"} "Options go here"]
;; Box with padding
[:box {:padding 1} "Padded content"]
;; Box with custom border style
[:box {:border :double} "Important!"]
```
**Output:**
```
╭─────────╮
│Content │
╰─────────╯
╭─Settings─╮
│Options go here│
╰──────────╯
╭──────────────────╮
│ │
│ Padded content │
│ │
╰──────────────────╯
╔═══════════╗
║Important! ║
╚═══════════╝
```
**Attributes:**
| Attribute | Type | Description |
|-----------|------|-------------|
| `:border` | keyword | Border style (see below) |
| `:title` | string | Title in top border |
| `:padding` | int/vec | Inner padding (see below) |
| `:width` | integer | Fixed width |
**Border Styles:**
| Style | Characters | Example |
|-------|------------|---------|
| `:rounded` | `╭╮╰╯─│` | `╭───╮` (default) |
| `:single` | `┌┐└┘─│` | `┌───┐` |
| `:double` | `╔╗╚╝═║` | `╔═══╗` |
| `:heavy` | `┏┓┗┛━┃` | `┏━━━┓` |
| `:ascii` | `++--\|` | `+---+` |
**Padding:**
```clojure
;; All sides
[:box {:padding 2} "Content"]
;; Vertical and horizontal [v h]
[:box {:padding [1 2]} "Content"]
;; Individual [top right bottom left]
[:box {:padding [1 2 1 2]} "Content"]
```
### `:space` - Empty Space
Creates empty space for layout purposes.
```clojure
;; Default 1x1 space
[:space]
;; Horizontal space
[:row "Left" [:space {:width 10}] "Right"]
;; Vertical space
[:col "Top" [:space {:height 3}] "Bottom"]
```
**Output:**
```
Left Right
Top
Bottom
```
**Attributes:**
| Attribute | Type | Description |
|-----------|------|-------------|
| `:width` | integer | Width in characters (default: 1) |
| `:height` | integer | Height in lines (default: 1) |
## Colors
### Named Colors
Basic 16-color palette supported by all terminals:
| Color | Keyword | Bright Version |
|-------|---------|----------------|
| Black | `:black` | `:bright-black` |
| Red | `:red` | `:bright-red` |
| Green | `:green` | `:bright-green` |
| Yellow | `:yellow` | `:bright-yellow` |
| Blue | `:blue` | `:bright-blue` |
| Magenta | `:magenta` | `:bright-magenta` |
| Cyan | `:cyan` | `:bright-cyan` |
| White | `:white` | `:bright-white` |
| Default | `:default` | - |
Aliases: `:gray` and `:grey` map to `:bright-black`
```clojure
[:text {:fg :red} "Error"]
[:text {:fg :bright-green} "Success"]
[:text {:bg :blue :fg :white} "Highlighted"]
```
### 256 Colors
Use integers 0-255 for extended color support:
```clojure
[:text {:fg 208} "Orange (256-color)"]
[:text {:bg 236} "Dark gray background"]
```
**Color ranges:**
- 0-7: Standard colors
- 8-15: Bright colors
- 16-231: 6x6x6 color cube
- 232-255: Grayscale (dark to light)
### True Color (24-bit)
For true color, use the `tui.ansi` namespace directly:
```clojure
(require '[tui.ansi :as ansi])
[:text (ansi/fg-rgb 255 128 0 "Orange text")]
[:text (ansi/bg-rgb 30 30 30 "Dark background")]
```
## Text Styles
Combine multiple styles:
```clojure
[:text {:bold true :underline true} "Bold and underlined"]
[:text {:fg :red :bold true :inverse true} "Inverted error"]
[:text {:dim true :italic true} "Subtle italic"]
```
**Available styles:**
| Style | Attribute | Description |
|-------|-----------|-------------|
| Bold | `:bold true` | Heavier font weight |
| Dim | `:dim true` | Lighter/faded text |
| Italic | `:italic true` | Slanted text |
| Underline | `:underline true` | Line under text |
| Inverse | `:inverse true` | Swap foreground/background |
| Strikethrough | `:strike true` | Line through text |
## Layout Examples
### Two-Column Layout
```clojure
[:row {:gap 4}
[:col
[:text {:bold true} "Left Column"]
[:text "Item 1"]
[:text "Item 2"]]
[:col
[:text {:bold true} "Right Column"]
[:text "Item A"]
[:text "Item B"]]]
```
**Output:**
```
Left Column Right Column
Item 1 Item A
Item 2 Item B
```
### Nested Boxes
```clojure
[:box {:title "Outer" :padding 1}
[:row {:gap 2}
[:box {:border :single :title "Box A"}
[:text "Content A"]]
[:box {:border :single :title "Box B"}
[:text "Content B"]]]]
```
**Output:**
```
╭─Outer────────────────────────────╮
│ │
│ ┌─Box A─────┐ ┌─Box B─────┐ │
│ │Content A │ │Content B │ │
│ └───────────┘ └───────────┘ │
│ │
╰──────────────────────────────────╯
```
### Status Bar
```clojure
[:col
[:box {:border :rounded :padding [0 1]}
[:text {:bold true} "My Application"]]
[:space {:height 1}]
[:text "Main content here..."]
[:space {:height 1}]
[:row {:gap 2}
[:text {:fg :gray} "Status: Ready"]
[:text {:fg :gray} "|"]
[:text {:fg :gray} "Press q to quit"]]]
```
**Output:**
```
╭──────────────────╮
│ My Application │
╰──────────────────╯
Main content here...
Status: Ready | Press q to quit
```
### Menu with Selection
```clojure
(defn menu-item [label selected?]
[:row
[:text (if selected? "> " " ")]
[:text {:fg (if selected? :cyan :white)
:bold selected?}
label]])
(defn view [{:keys [items cursor]}]
[:col
[:text {:bold true} "Select an option:"]
[:space {:height 1}]
[:col {:gap 0}
(for [[idx item] (map-indexed vector items)]
(menu-item item (= idx cursor)))]])
```
**Output (cursor on second item):**
```
Select an option:
First Option
> Second Option
Third Option
```
### Progress Indicator
```clojure
(defn progress-bar [percent width]
(let [filled (int (* width (/ percent 100)))
empty (- width filled)]
[:row
[:text "["]
[:text {:fg :green} (apply str (repeat filled "="))]
[:text {:fg :gray} (apply str (repeat empty "-"))]
[:text "]"]
[:text " "]
[:text (str percent "%")]]))
(defn view [{:keys [progress]}]
[:col
[:text "Downloading..."]
(progress-bar progress 20)])
```
**Output (at 65%):**
```
Downloading...
[=============-------] 65%
```
## Helper Functions
The `tui.render` namespace provides helper functions:
```clojure
(require '[tui.render :refer [text row col box]])
;; These are equivalent:
[:text {:fg :red} "Error"]
(text {:fg :red} "Error")
[:row {:gap 2} "A" "B"]
(row {:gap 2} "A" "B")
[:col [:text "Line 1"] [:text "Line 2"]]
(col (text "Line 1") (text "Line 2"))
[:box {:title "Info"} "Content"]
(box {:title "Info"} "Content")
```
## Conditional Rendering
Use standard Clojure conditionals:
```clojure
(defn view [{:keys [loading? error data]}]
[:col
[:text {:bold true} "Status"]
(cond
loading?
[:text {:fg :yellow} "Loading..."]
error
[:text {:fg :red} (str "Error: " error)]
:else
[:text {:fg :green} (str "Data: " data)])])
```
## Dynamic Views with `for`
Generate repeated elements:
```clojure
(defn view [{:keys [items selected]}]
[:col
(for [[idx item] (map-indexed vector items)]
[:row
[:text (if (= idx selected) "> " " ")]
[:text {:fg (if (= idx selected) :cyan :white)} item]])])
```
## String Shortcuts
Plain strings are automatically wrapped in `:text`:
```clojure
;; These are equivalent:
[:col "Line 1" "Line 2"]
[:col [:text "Line 1"] [:text "Line 2"]]
;; In rows too:
[:row "A" "B" "C"]
[:row [:text "A"] [:text "B"] [:text "C"]]
```
## Common Patterns
### Styled Labels
```clojure
(defn label [text]
[:text {:fg :gray} (str text ": ")])
(defn value [text]
[:text {:fg :white :bold true} text])
[:row (label "Name") (value "John")]
```
### Conditional Styling
```clojure
(defn status-text [status]
[:text {:fg (case status
:ok :green
:warning :yellow
:error :red
:white)
:bold (= status :error)}
(name status)])
```
### Reusable Components
```clojure
(defn card [{:keys [title]} & children]
[:box {:border :rounded :title title :padding [0 1]}
(into [:col] children)])
;; Usage
(card {:title "User Info"}
[:row (label "Name") (value "Alice")]
[:row (label "Email") (value "alice@example.com")])
```
## Next Steps
- [API Reference](api-reference.md) - Complete API documentation
- [Examples](examples.md) - Full example applications