d0dc9729fd
Add the public 'Where are my components?' answer: hemx maps framework component jobs to hemplate partials, generated helpers, app-owned state, IntoEffect composition, and explicit leaf islands. The pre-commit guard now only blocks commits that change REQUIREMENTS.md without an AGENTS.md review, so unrelated follow-up commits are not trapped by old history. req: canonical_authoring/002 req: canonical_authoring/003
42 lines
2.0 KiB
Markdown
42 lines
2.0 KiB
Markdown
# Where are my components?
|
|
|
|
In hemx, the reusable UI unit is a **checked hemplate partial plus generated Rust
|
|
helpers**, not a client component instance. You still get reuse and composition;
|
|
the ownership moves to places Rust apps can inspect and test. req: canonical_authoring/002 req: canonical_authoring/003
|
|
|
|
| Framework component job | hemx home |
|
|
| --- | --- |
|
|
| Markup and local UI shape | A `.heml` partial rendered from a Rust view struct. |
|
|
| Props | The view struct fields passed into the partial/helper. |
|
|
| Stable child identity | `h-key` on repeated partials, exposed through generated keyed helpers. |
|
|
| Events | Real forms, links, handles, and explicit generated events. |
|
|
| State | App-owned Rust state, commands/events/projections, or integration-owned stores. |
|
|
| Updating the UI | Generated commands such as `ui::todo_row.replace(row)`. |
|
|
| Composition | `impl IntoEffect`: tuples for fixed mixed batches, arrays for fixed repeated batches, and `Vec<T: IntoEffect>` for dynamic repeated batches. |
|
|
| Client-only widgets | Explicit islands or Web Components at leaf boundaries. |
|
|
|
|
A reusable row should be one partial used in both places: initial render and later
|
|
updates. The handler builds domain state, converts it to a view value, and returns
|
|
generated commands:
|
|
|
|
```rust
|
|
(
|
|
rows
|
|
.into_iter()
|
|
.map(|row| ui::todo_row.replace(row))
|
|
.collect::<Vec<_>>(),
|
|
ui::summary.set(summary),
|
|
ui::notice.set("Saved"),
|
|
)
|
|
```
|
|
|
|
That is the component story: the row partial is reusable; the generated helper
|
|
knows the target and swap kind; `IntoEffect` composes the update without a client
|
|
component runtime, selector lookup, raw ids, raw opcodes, or manual registry
|
|
plumbing. req: public_api/005
|
|
|
|
Use an island only when the browser must own high-frequency local behavior, such
|
|
as a chart, map, editor, or media widget. The island is an explicit leaf; it can
|
|
emit facts back through generated handles/events, but the app still changes
|
|
server-owned UI through normal hemx effects. req: interop/003
|