Skip to main content
Primary use: when you build your own widgets and want the same consistent disabled effect and scale-down on press as widgets like NeoButton, wrap them with NeoInteractable.

Examples

Provide exactly one of child or builder.

Properties

Required

Provide either child or builder (exactly one).

Content

Widget?
Static child when interaction-driven rebuilds are not needed. Mutually exclusive with builder.
NeoInteractableBuilder?
Builds content from the current interaction snapshot (isEnabled, isHovered, isPressed, isActive). Mutually exclusive with child.

Layout

HitTestBehavior
default:"HitTestBehavior.deferToChild"
Hit-test behavior passed to the underlying gesture detector when press handlers are present.

Styling

bool
default:"true"
Whether the content scales slightly while pressed.
double
default:"0.97"
Scale factor applied while pressed when enableScale is true.
MouseCursor?
Mouse cursor override. When null, uses click when enabled and forbidden when disabled.

State

VoidCallback?
Called on tap when enabled.
bool
default:"true"
When false, dims via Neo’s disabled opacity, clears hover/press, and ignores input.
bool?
When null, uses NeoConfig.enableInteractionHaptics. When enabled, plays light haptic on press down, and a second light haptic on release only if the press lasted at least minPressDuration (or theme durations.short).
VoidCallback?
Called when a press begins.
VoidCallback?
Called when a press ends or is cancelled.
VoidCallback?
Called when the pointer enters the interactable region.
VoidCallback?
Called when the pointer leaves the interactable region.
GestureDragStartCallback?
Optional horizontal drag start handler.
GestureDragUpdateCallback?
Optional horizontal drag update handler.
Duration?
Overrides theme durations.short for the minimum time pressed stays true on quick taps.

Builder state

When you need custom hover/press visuals, use builder. The snapshot includes:
  • isEnabled / isHovered / isPressed
  • isActive — true when enabled and either hovered or pressed (same feedback on touch and desktop)

Best Practices

  • Use child for disabled opacity and press scale only.
  • Use builder and state.isActive when the child also changes color on hover or press.
  • Keep layout in the child. Leave the gestures to NeoInteractable.

Behavior

  • NeoButton and other Neo controls use this wrapper.
  • The press scale uses theme.durations.short.
Last modified on September 30, 2026