State-Based Styling
Apply styles that react to a widget's state, such as hover or disabled, using prefixed utility classes. Wind's classNameParser function resolves these prefixes against the list of currently active states you pass in, so state-aware styling stays declarative.
import 'package:flutter/material.dart';
import 'package:fluttersdk_wind/fluttersdk_wind.dart';
// Inside a widget that tracks its own active states:
final List states = [];
if (isHovered) states.add('hover');
if (isDisabled) states.add('disabled');
final String parsed = classNameParser(
'bg-primary-500 p-4 rounded-lg hover:bg-white disabled:bg-gray-500',
states: states,
);
WFlexContainer(
className: parsed,
children: [
WText('Submit', className: 'text-white'),
],
);
Basic Usage
Prefix a utility with a state name and pass the active states to classNameParser. When a state is active, its prefix is stripped and the underlying utility applies; when it is not active, the prefixed token is removed:
final String parsed = classNameParser(
'bg-primary-500 hover:bg-white disabled:bg-gray-500',
states: ['hover'],
);
// hover active -> bg-white wins; disabled token dropped.
State names are not a fixed set. Any token you list in states matches the corresponding prefix, so hover, disabled, pressed, selected, or your own custom name all work the same way.
How It Works
classNameParser(className, {states}) walks the className and, for each active state, strips the matching state: prefix so the utility behind it is applied. Prefixed tokens whose state is not active are dropped before the parsers run.
This is why state-based styling needs a stateful host widget: your widget decides which states are active (a hover from an InkWell, a disabled flag, a selection), assembles them into a list, and feeds that list to classNameParser. Wind does not track widget state for you; it resolves the class names against the states you report.
Building a Stateful Widget
Here is a reusable button that tracks hover and disabled states and styles itself through classNameParser:
import 'package:flutter/material.dart';
import 'package:fluttersdk_wind/fluttersdk_wind.dart';
class AppButton extends StatefulWidget {
final String? className;
final String? textClassName;
final String? text;
final bool disabled;
const AppButton({
super.key,
this.className,
this.textClassName,
this.text,
this.disabled = false,
});
@override
State createState() => _AppButtonState();
}
class _AppButtonState extends State {
bool isHovered = false;
@override
Widget build(BuildContext context) {
final List states = [];
if (widget.disabled) states.add('disabled');
if (isHovered) states.add('hover');
final String parsedClassName = classNameParser(widget.className, states: states);
final String parsedTextClassName = classNameParser(widget.textClassName, states: states);
return InkWell(
onHover: (hovered) {
if (!widget.disabled) {
setState(() => isHovered = hovered);
}
},
onTap: widget.disabled ? null : () {},
child: WFlexContainer(
className: parsedClassName,
children: [
WText(widget.text ?? 'Button', className: parsedTextClassName),
],
),
);
}
}
Used like this, the prefixed utilities resolve as the button's state changes:
AppButton(
className: 'bg-primary-500 p-4 rounded-lg hover:bg-white',
textClassName: 'text-white hover:text-primary-600',
text: 'Submit',
);
Best Practices
- Drive states from your widget's own logic (hover callbacks, flags) and pass them into
classNameParser; Wind does not manage state for you. - Parse every class string that should react to state, including separate text class names, with the same
stateslist. - Keep base styles unprefixed and add only the state-specific overrides behind a prefix.
- Reuse one stateful wrapper (like
AppButton) across your app instead of wiring state tracking into every call site.
Related Documentation
- Dark Mode — the
dark:prefix, resolved separately from interaction states. - Responsive Design — breakpoint prefixes that compose with utilities.
- Background Color — the
bg-*utilities commonly toggled per state. - Text Color — the
text-*utilities for state-driven text styling.