Files
hemx/examples/html_examples/templates/gallery.heml
T
slhx agent cd7f64e5a3 feat(runtime): add tiny trigger timing conventions
Add boring runtime-level trigger timing primitives for delay, revealed, and interval while keeping them as attribute conventions rather than core effects or plugin surfaces. Promote lazy-load, infinite-scroll, progress-bar, value-select, and reset-user-input in examples/html_examples to runnable hemx patterns with exact htmx slugs and generated resources.

req: convention/001

req: convention/003

req: convention/005

req: htmx_equivalents/001

req: htmx_equivalents/002

req: examples/001
2026-06-23 07:51:43 +02:00

130 lines
5.3 KiB
Plaintext

<main data-hemx-root="gallery">
<header>
<p>Copy-pasteable hemx HTML patterns</p>
<h1>HTML UX pattern gallery</h1>
<p>Server-owned Rust state, boring .heml, generated resources, and tiny runtime behavior.</p>
</header>
<section id="click-to-edit" data-htmx-example="click-to-edit" aria-labelledby="click-to-edit-heading">
<h2 id="click-to-edit-heading">click-to-edit</h2>
<div data-hemx-slot="contact_card">
<template h-for="contact in &self.contacts" h-key="contact.id">
{+ contact +}
</template>
</div>
</section>
<section id="edit-row" data-htmx-example="edit-row" aria-labelledby="edit-row-heading">
<h2 id="edit-row-heading">edit-row</h2>
<p id="delete-row" data-htmx-example="delete-row">delete-row uses the same keyed row partial and a generated remove effect.</p>
<table>
<thead>
<tr><th>Task</th><th>Actions</th></tr>
</thead>
<tbody data-hemx-slot="editable_row">
<template h-for="row in &self.rows" h-key="row.id">
{+ row +}
</template>
</tbody>
</table>
</section>
<section id="inline-validation" data-htmx-example="inline-validation" aria-labelledby="validation-heading">
<h2 id="validation-heading">inline-validation</h2>
<form data-hemx-handle="validate_email" data-hemx-form="validate_email">
<label>Email <input name="email" +value="self.email" required="required"></label>
<button type="submit">Validate</button>
<p data-hemx-error-for="email"></p>
<p data-hemx-slot="email_status">{+ self.email_status +}</p>
</form>
</section>
<section id="lazy-load" data-htmx-example="lazy-load" aria-labelledby="lazy-heading">
<h2 id="lazy-heading">lazy-load</h2>
<form data-hemx-handle="lazy_load" data-hemx-form="lazy_load" data-hemx-revealed="true">
<input type="hidden" name="request" value="lazy">
<button type="submit">Load lazy content</button>
</form>
<div data-hemx-slot="lazy_panel">{+ self.lazy_panel +}</div>
</section>
<section id="click-to-load" data-htmx-example="click-to-load" aria-labelledby="load-heading">
<h2 id="load-heading">click-to-load</h2>
<ul data-hemx-slot="loaded_row">
<template h-for="row in &self.loaded_rows" h-key="row.id">
{+ row +}
</template>
</ul>
<form data-hemx-handle="load_more" data-hemx-form="load_more">
<input type="hidden" name="request" value="more">
<button type="submit">Load more</button>
</form>
<p data-hemx-slot="load_status">{+ self.load_status +}</p>
</section>
<section id="infinite-scroll" data-htmx-example="infinite-scroll" aria-labelledby="infinite-heading">
<h2 id="infinite-heading">infinite-scroll</h2>
<ul data-hemx-slot="infinite_row">
<template h-for="row in &self.infinite_rows" h-key="row.id">
{+ row +}
</template>
</ul>
<form data-hemx-handle="infinite_scroll" data-hemx-form="infinite_scroll" data-hemx-revealed="true">
<input type="hidden" name="request" value="more">
<button type="submit">Reveal more rows</button>
</form>
<p data-hemx-slot="infinite_status">{+ self.infinite_status +}</p>
</section>
<section id="progress-bar" data-htmx-example="progress-bar" aria-labelledby="progress-heading">
<h2 id="progress-heading">progress-bar</h2>
<form data-hemx-handle="tick_progress" data-hemx-form="tick_progress" data-hemx-interval="500ms">
<input type="hidden" name="request" value="tick">
<button type="submit">Tick progress</button>
</form>
<progress max="100" +value="self.progress">{+ self.progress_label +}</progress>
<p data-hemx-slot="progress_meter">{+ self.progress_label +}</p>
</section>
<section id="value-select" data-htmx-example="value-select" aria-labelledby="value-heading">
<h2 id="value-heading">value-select</h2>
<form data-hemx-handle="choose_category" data-hemx-form="choose_category">
<label>Category
<select name="category">
<option value="letters">Letters</option>
<option value="numbers">Numbers</option>
</select>
</label>
<button type="submit">Choose</button>
</form>
<select data-hemx-slot="value_option" name="value">
<template h-for="option in &self.value_options" h-key="option.id">
{+ option +}
</template>
</select>
</section>
<section id="reset-user-input" data-htmx-example="reset-user-input" aria-labelledby="reset-heading">
<h2 id="reset-heading">reset-user-input</h2>
<form data-hemx-handle="reset_message" data-hemx-form="reset_message">
<label>Message <input name="message"></label>
<button type="submit">Send and reset</button>
</form>
<p data-hemx-slot="reset_status">{+ self.reset_status +}</p>
</section>
<section id="active-search" data-htmx-example="active-search" aria-labelledby="search-heading">
<h2 id="search-heading">active-search</h2>
<form data-hemx-handle="search" data-hemx-form="search">
<label>Search <input name="query" +value="self.query"></label>
<button type="submit">Search</button>
</form>
<p data-hemx-slot="search_status">{+ self.search_status +}</p>
<ul data-hemx-slot="search_result">
<template h-for="result in &self.search_results" h-key="result.id">
{+ result +}
</template>
</ul>
</section>
</main>