Indication
Indication is temporary client-side DOM feedback while a hook request is in flight. Doors applies it as the request starts and restores the previous DOM when the request ends.
<button (doors.AClick{
Indicator: doors.IndicateClass("active"),
On: func(ctx context.Context, r doors.RequestEvent[doors.PointerEvent]) bool {
<-time.After(500 * time.Millisecond)
return false
},
})>
Save
</button>
Kinds
The Indicate* family covers four indicator kinds:
| Helper | Effect |
|---|---|
IndicateContent(html) |
Replace element content with html |
IndicateAttr(name, value) |
Set attribute name=value |
IndicateClass(class) |
Add CSS class(es) |
IndicateClassRemove(class) |
Remove CSS class(es) |
IndicateContentwrites toinnerHTML— pass only trusted HTML.
Targets
By default the helper acts on the event source. A suffix redirects it:
| Suffix | Target |
|---|---|
| (none) | Event source element |
Query |
First match of a CSS query |
QueryAll |
All matches |
QueryParent |
Closest matching ancestor |
doors.IndicateAttrQuery("#loader", "aria-busy", "true")
doors.IndicateClassQueryAll(".row", "pending")
The four selectors are also available directly: doors.SelectorTarget(), doors.SelectorQuery(q), doors.SelectorQueryAll(q), doors.SelectorQueryParent(q) — used with the struct form below.
Combining
Indicator is a single doors.Indicators value. Each helper returns one, so a single helper passes directly. Combine with .And(...) or doors.JoinIndicators(...):
Indicator: doors.IndicateClass("loading").
And(doors.IndicateAttrQuery("#search-loader", "aria-busy", "true"))
Struct Form
For shared selectors or several changes on the same element, use the structs directly. They are also doors.Indicators:
sel := doors.SelectorQuery("#card")
Indicator: doors.JoinIndicators(
doors.IndicatorAttr{Selector: sel, Name: "data-state", Value: "saving"},
doors.IndicatorClass{Selector: sel, Class: "pending"},
doors.IndicatorContent{Selector: sel, Content: "Saving..."},
)
Behavior
- Indication starts when the request actually begins on the client. Scopes can delay or cancel the request — indication follows that decision.
- When the request ends, Doors restores what the indicator changed: temporary attributes removed, added classes removed, removed classes restored, content put back.
- Overlapping indications on the same element queue. When one ends, the next takes over. Fields the next indication doesn't touch fall back to the original value, not the previous indication's value.
Example
<>
<span id="search-loader"></span>
<input
type="search"
placeholder="Country"
(doors.AInput{
Indicator: doors.IndicateAttrQuery("#search-loader", "aria-busy", "true"),
Scope: &doors.ScopeDebounce{
Duration: 300 * time.Millisecond,
Limit: 600 * time.Millisecond,
},
On: func(ctx context.Context, r doors.RequestEvent[doors.InputEvent]) bool {
<-time.After(500 * time.Millisecond)
return false
},
})/>
</>
Rules
- Use indication for temporary feedback, not as your main UI state.
- Default to
Indicate*helpers; reach for the struct form when you need shared selectors or several changes on the same element. - Pair with Scopes when request timing matters.
- For programmatic, fixed-duration indication outside the event lifecycle, see
ActionIndicatein Actions.