OptionalanchorSet when kind matches 'handle:*'. Identifies which corner stays
fixed during a resize so consumers (resizeAction) don't re-parse kind.
Other affordance kinds (rotate-handle, anchor:N, controlIn:N, controlOut:N)
leave this undefined.
OptionalcursorCSS cursor to show while the pointer hovers this affordance (no
gesture in flight). Consumed by the hover-cursor pump in
useGestureDispatcher; unset = the pump falls through to
action-cursor prediction, then to the active tool's cursor.
OptionalfixedWorld-space fixed/pivot point. For resize: opposite corner. For rotate: pivot.
Discriminator string, e.g. 'handle:bottom-right'.
OptionalpayloadFree-form payload from whatever produced the hit, carried through to the matching action untouched.
Kit affordances describe themselves fully in the fields above and leave
this unset. It exists for affordances the kit doesn't know the shape of —
a registered layer's own chrome, where the hit-test already resolved
which of its pieces was hit and the action would otherwise have to
redo that work. @weasel-js/hud passes the hit widget here.
OptionaltargetWhich nodes this affordance belongs to.
Information about which UI affordance was hit at pointerdown.
Populated by the dispatcher when the
affordanceAtthunk is provided touseGestureDispatcher. Tools / action invokers that only fire on a specific affordance (e.g. a resize handle) use this field as a guard — if the affordance is absent or is the wrong kind, they return{}and let other bindings handle the drag.kindis a discriminator string:'handle:top-left'/'handle:top-right'/'handle:bottom-left'/'handle:bottom-right'— corner resize handles.'rotate-handle'— the rotation affordance.'anchor:N'— a path anchor at index N.fixedPointis the world-space point that should remain stationary during the gesture. For resize handles this is the opposite (diagonally fixed) corner; for rotate it is the pivot.targetIdsare the node ids this affordance belongs to.