IDs and Keys
GPUI-RSX generates stable IDs when GPUI APIs require an element identity.
Most layout and styling calls do not need an ID. The macro only injects one when a stateful GPUI method is used.
Auto IDs
Section titled “Auto IDs”For static RSX outside loops, the macro can generate IDs from the call site. This keeps common markup concise:
rsx! { <button onClick={handler}> {"Click"} </button>}Static stateful scroll classes also trigger auto IDs:
rsx! { <div class="overflow-y-scroll"> {"Scrollable content"} </div>}The generated ID is deterministic for the macro expansion site.
Common ID-triggering attributes include onClick, onHover, onDrag, onAuxClick, onA11yAction, active, activeClass, groupActive, tooltip, tooltipShowDelay, focusable, role, ariaLabel, overflowScroll, overflowXScroll, overflowYScroll, trackScroll, scrollbarWidth, and static overflow-scroll class variants.
Attributes such as hover, hoverClass, focus, focusClass, group, groupHover, onMouseDown, and captureKeyDown do not by themselves require a stateful ID in the current GPUI target.
Keys in Loops
Section titled “Keys in Loops”When rendering repeated stateful elements, provide key={...}:
rsx! { <div> {for task in &self.tasks { <button key={task.id} onClick={handler} class="flex items-center gap-2"> {task.title.clone()} </button> }} </div>}Loops that need stateful IDs produce a compile error if the key is missing. This prevents repeated rows from accidentally sharing the same generated ID.
key is a macro-only attribute. It never becomes a .key(...) method call.
Literal and Dynamic Keys
Section titled “Literal and Dynamic Keys”Literal keys can be expanded with concat!:
rsx! { <button key="toolbar" onClick={handler} />}Dynamic keys use formatting so each row or stateful instance gets a unique identity. The expression must implement Display:
rsx! { <button key={task.id} onClick={handler} />}If an element does not need an ID, key is ignored:
rsx! { <div key={task.id} class="flex items-center"> {task.title.as_str()} </div>}The example above stays a plain element because no stateful method is present.
Explicit IDs
Section titled “Explicit IDs”An explicit id always wins:
rsx! { <button id="save-button" key={task.id} onClick={handler}> {"Save"} </button>}Use explicit IDs when identity must remain stable across source-line movement or refactors.
When to Add a Key
Section titled “When to Add a Key”Add a key when:
- the element appears inside
{for ...}, - the class or attribute uses a GPUI stateful behavior,
- the identity must remain stable across reorder or update operations.
Keep simple, non-repeated elements keyless and let the macro generate IDs where needed.