WAnchor
The foundational state wrapper that detects user gestures (Hover, Focus, Press) and propagates that state down to all descendant widgets via WindAnchorStateProvider.
- Basic Usage
- Constructor
- Props
- Layout Modes
- Event Handling
- State Variants
- Styling Examples
- All Supported Classes
- Customizing Theme
- Related Documentation
WAnchor(
onTap: () => print('Pressed'),
child: WDiv(
// Reacts to hover state provided by WAnchor
className: 'p-4 bg-white hover:bg-gray-100 transition-colors',
child: WText('Hover Me'),
),
)
Basic Usage
The WAnchor widget acts as the "brain" for interaction state management in Wind. It handles gesture detection and focus management, making it possible for child widgets to use prefixes like hover:, focus:, and disabled:.
Unlike most Wind widgets, WAnchor does not take a className itself. Instead, it provides the context needed for its children to respond to interactive states.
WAnchor(
onTap: () => print('Tapped!'),
child: WDiv(
className: 'p-4 bg-blue-500 hover:bg-blue-600 rounded-lg',
child: WText('Interactive Box', className: 'text-white'),
),
)
Constructor
const WAnchor({
Key? key,
required Widget child,
VoidCallback? onTap,
VoidCallback? onLongPress,
VoidCallback? onDoubleTap,
bool isDisabled = false,
Set? states,
MouseCursor? mouseCursor,
String? semanticLabel,
})
Props
| Prop | Type | Default | Description |
|---|---|---|---|
child |
Widget |
Required | The widget that will receive the hover, focus, and gesture states. |
onTap |
VoidCallback? |
null |
Triggered when the widget is tapped. |
onLongPress |
VoidCallback? |
null |
Triggered when the widget is long-pressed. |
onDoubleTap |
VoidCallback? |
null |
Triggered when the widget is double-tapped. |
isDisabled |
bool |
false |
When true, gestures are ignored and the disabled: prefix is activated. |
states |
Set |
null |
Custom states for dynamic styling (e.g., {'active'}). |
mouseCursor |
MouseCursor? |
null |
Custom cursor. Defaults to click when interactive. |
semanticLabel |
String? |
null |
Accessible name for icon-only controls. When set, excludes the child subtree from semantics so the label overrides any child text; prefer it for icon-only controls rather than controls that already expose readable text. |
Layout Modes
WAnchor is a logic wrapper and does not provide layout properties of its own. To control the layout of the interactive area, use a WDiv or another layout widget as the immediate child.
Flex Layout Wrapper
WAnchor(
onTap: () {},
child: WDiv(
className: 'flex items-center gap-2 p-3 bg-gray-50 hover:bg-gray-100 rounded',
children: [
WIcon(Icons.add, className: 'text-blue-500'),
WText('Add Item'),
],
),
)
Event Handling
WAnchor supports standard touch and mouse gestures. These events are only triggered if isDisabled is false.
WAnchor(
onTap: () => print('Single Tap'),
onDoubleTap: () => print('Double Tap'),
onLongPress: () => print('Long Press'),
child: WDiv(
className: 'p-10 bg-zinc-200 text-center',
child: WText('Gesture Interaction Area')
),
)
State Variants
WAnchor enables several state prefixes for all Wind widgets in its subtree. This allows you to define complex interactive styles easily.
WAnchor(
isDisabled: false,
child: WDiv(
className: '''
bg-blue-500
hover:bg-blue-600
focus:ring-2 focus:ring-blue-300
disabled:bg-gray-400 disabled:opacity-50
''',
child: WText('Interactive States', className: 'text-white'),
),
)
Styling Examples
Card Lift Effect
WAnchor(
onTap: () {},
child: WDiv(
className: 'p-6 bg-white shadow hover:shadow-lg hover:-translate-y-1 rounded-xl duration-300',
child: WText('Hover to see the lift effect'),
),
)
Navigation Link
WAnchor(
onTap: () {},
child: WDiv(
className: 'px-4 py-2 text-gray-600 hover:text-blue-600 hover:bg-blue-50 rounded',
child: WText('Dashboard'),
),
)
All Supported Classes
While WAnchor does not take a className, it facilitates the use of these state prefixes for visual widgets (like WDiv or WText) within its subtree:
| Category | Prefixes / Features |
|---|---|
| Interaction | hover:, focus:, disabled: |
| Custom States | Any value passed to the states prop (e.g., active:, error:) |
| Gestures | Enables onTap, onLongPress, onDoubleTap |
Customizing Theme
WAnchor behavior is primarily state-driven. You can customize the global interaction defaults via WindThemeData.
WindTheme(
data: WindThemeData(
// Theme scales influence the styles applied during states
baseSpacingUnit: 4.0,
),
child: MyApp(),
)
Accessibility
A WAnchor that carries a gesture (onTap, onLongPress or onDoubleTap) publishes one Semantics(button: true) node, and MergeSemantics folds the child's text into it so the control gets its name from what it renders. Pass semanticLabel when the child has no readable text, such as an icon-only anchor; that label replaces the child subtree rather than concatenating with it.
A WAnchor with no gesture and no semanticLabel publishes nothing of its own. It is the state propagator in that mode, which is how WDiv uses it to serve hover:, focus: and active: classes (the auto-wrap never passes a label), and a decorative surface must not announce itself as a button with no action behind it.
semanticLabel is the exception, and deliberately so: setting it always publishes the named button node, gestures or not. It is how a DISABLED control still tells assistive technology that a control is there and currently unavailable, which is information the user needs. That makes the label a statement of intent rather than a formatting choice: set it on a control, never on decoration.
// One button node named "Save".
WAnchor(onTap: save, child: const WText('Save'))
// One button node named "Save", announced disabled, with no tap action.
const WAnchor(isDisabled: true, semanticLabel: 'Save', child: WText('Save'))
// No node at all: hover styling only.
const WAnchor(child: WDiv(className: 'hover:bg-slate-100', child: WText('Card')))
Related Documentation
- WButton - High-level button widget built on WAnchor.
- WDiv - The primary layout widget used with WAnchor.
- State Management - Deep dive into state prefixes.