WidgetStateMap<T> typedef

WidgetStateMap<T> = Map<WidgetStatesConstraint, T>

A Map used to resolve to a single value of type T based on the current set of Widget states.

Example:

// This WidgetStateMap<Color?> resolves to null if no keys match.
WidgetStateProperty<Color?>.fromMap(<WidgetStatesConstraint, Color?>{
  WidgetState.error: Colors.red,
  WidgetState.hovered & WidgetState.focused: Colors.blueAccent,
  WidgetState.focused: Colors.blue,
  ~WidgetState.disabled: Colors.black,
});

// The same can be accomplished with a WidgetPropertyResolver,
// but it's more verbose:
WidgetStateProperty.resolveWith<Color?>((Set<WidgetState> states) {
  if (states.contains(WidgetState.error)) {
    return Colors.red;
  } else if (states.contains(WidgetState.hovered) && states.contains(WidgetState.focused)) {
    return Colors.blueAccent;
  } else if (states.contains(WidgetState.focused)) {
    return Colors.blue;
  } else if (!states.contains(WidgetState.disabled)) {
    return Colors.black;
  }
  return null;
});

A widget state combination can be stored in a variable, and WidgetState.any can be used for non-nullable types to ensure that there's a match:

final WidgetStatesConstraint selectedError = WidgetState.selected & WidgetState.error;

final WidgetStateProperty<Color> color = WidgetStateProperty<Color>.fromMap(
  <WidgetStatesConstraint, Color>{
    selectedError & WidgetState.hovered: Colors.redAccent,
    selectedError: Colors.red,
    WidgetState.any: Colors.black,
  },
);

// The (more verbose) WidgetPropertyResolver implementation:
final WidgetStateProperty<Color> colorResolveWith = WidgetStateProperty.resolveWith<Color>(
  (Set<WidgetState> states) {
    if (states.containsAll(<WidgetState>{WidgetState.selected, WidgetState.error})) {
      if (states.contains(WidgetState.hovered)) {
        return Colors.redAccent;
      }
      return Colors.red;
    }
    return Colors.black;
  },
);

Implementation

typedef WidgetStateMap<T> = Map<WidgetStatesConstraint, T>;