📚ReDocs
ReDocs

Partials

RefaceComposer's Partials Plugin provides interactive components with HTMX integration.

Basic Usage

Simple Partial

1import { partial } from "@reface/plugins/partials";
2
3const Counter = partial(async () => {
4 ​const count = 0;
5 ​return (
6 ​ ​<div>
7 ​ ​ ​<span>{count}</span>
8 ​ ​ ​<button {...Counter.trigger()}>Increment</button>
9 ​ ​</div>
10 ​);
11}, "counter");
12
13// Usage
14<Counter />;

HTMX Integration

1// Default click trigger
2const Button = partial(async () => {
3 ​return <button {...Button.trigger()}>Click me</button>;
4}, "button");
5
6// Custom trigger with delay
7const SearchBox = partial(async () => {
8 ​return (
9 ​ ​<div>
10 ​ ​ ​<input type="text" />
11 ​ ​ ​<button {...SearchBox.trigger("keyup delay:500ms from:input")}>
12 ​ ​ ​ ​Search
13 ​ ​ ​</button>
14 ​ ​</div>
15 ​);
16}, "search");
17
18// Form submission
19const Form = partial(async () => {
20 ​return (
21 ​ ​<form {...Form.trigger("submit")}>
22 ​ ​ ​<input type="text" name="title" />
23 ​ ​ ​<button type="submit">Save</button>
24 ​ ​</form>
25 ​);
26}, "form");

State Management

Local State

1const TodoList = partial(async () => {
2 ​const todos = await fetch("/api/todos").then((r) => r.json());
3
4 ​return (
5 ​ ​<div>
6 ​ ​ ​<ul>
7 ​ ​ ​ ​{todos.map((todo) => (
8 ​ ​ ​ ​ ​<li>
9 ​ ​ ​ ​ ​ ​{todo.title}
10 ​ ​ ​ ​ ​ ​<button {...TodoList.trigger()}>Delete</button>
11 ​ ​ ​ ​ ​</li>
12 ​ ​ ​ ​))}
13 ​ ​ ​</ul>
14 ​ ​</div>
15 ​);
16}, "todo-list");

Shared State

1const CartCounter = partial(async () => {
2 ​const count = await getCartCount();
3 ​return <span>{count} items</span>;
4}, "cart-counter");
5
6const AddToCart = partial(async () => {
7 ​return (
8 ​ ​<button {...AddToCart.trigger()} data-rerender="cart-counter">
9 ​ ​ ​Add to Cart
10 ​ ​</button>
11 ​);
12}, "add-to-cart");

Implementation Details

Partial Registration

1// Partials are automatically registered during render
2const composer = new RefaceComposer();
3composer.use(new PartialsPlugin());
4
5// Each partial gets a unique identifier
6<div>
7 ​<Counter /> <!-- data-partial="counter" -->
8 ​<SearchBox /> <!-- data-partial="search" -->
9</div>

HTMX Attributes

1// Trigger generates HTMX attributes
2const trigger = Counter.trigger("click");
3// Results in:
4// hx-get="/reface-partial/counter"
5// hx-target="[data-partial='counter']"
6// hx-trigger="click"
7
8// Custom configuration
9const trigger = SearchBox.trigger({
10 ​event: "keyup",
11 ​modifiers: {
12 ​ ​delay: 500,
13 ​ ​from: "input",
14 ​},
15});

Server Integration

1// Partial handler is called on HTMX request
2const handler = composer.getPlugin(PartialsPlugin)?.getHandler("counter");
3const result = await handler();
4// Result is used to update the partial

Best Practices

  1. Component Design

    • Keep partials focused

    • Clear state management

    • Proper error handling

    • Loading states

  2. Performance

    • Minimal updates

    • Efficient triggers

    • Optimized responses

    • Cache when possible

  3. User Experience

    • Loading indicators

    • Error feedback

    • Progressive enhancement

    • Fallback behavior

  4. Security

    • Input validation

    • CSRF protection

    • Rate limiting

    • Error handling