resolve method
RSwitchResolvedTokens
resolve({
- required BuildContext context,
- required RSwitchSpec spec,
- required Set<
WidgetState> states, - BoxConstraints? constraints,
- RenderOverrides? overrides,
Implementation
@override
RSwitchResolvedTokens resolve({
required BuildContext context,
required RSwitchSpec spec,
required Set<WidgetState> states,
BoxConstraints? constraints,
RenderOverrides? overrides,
}) {
final motionTheme =
HeadlessThemeProvider.of(context)?.capability<HeadlessMotionTheme>() ??
HeadlessMotionTheme.cupertino;
final q = HeadlessWidgetStateQuery(states);
final contractOverrides = overrides?.get<RSwitchOverrides>();
// Use provided brightness or fallback to platform brightness
final effectiveBrightness =
brightness ?? MediaQuery.platformBrightnessOf(context);
final isDark = effectiveBrightness == Brightness.dark;
// Cupertino Switch baseline values (iOS style).
// Cupertino switches have a fixed thumb size (no dynamic sizing like Material 3)
const defaultTrackSize = Size(51, 31);
// Flutter: _kThumbRadius = 14.0 -> diameter 28.0
const defaultThumbSize = Size(28, 28);
const defaultTrackBorderRadius = BorderRadius.all(Radius.circular(16));
const defaultThumbPadding = 2.0;
final isSelected = spec.value || q.isSelected;
Color activeTrackColor;
Color inactiveTrackColor;
Color activeThumbColor;
Color inactiveThumbColor;
Color trackOutlineColor;
if (q.isDisabled) {
activeTrackColor = CupertinoColors.systemGreen.withValues(alpha: 0.5);
inactiveTrackColor = isDark
? CupertinoColors.systemGrey.withValues(alpha: 0.5)
: CupertinoColors.systemGrey4.withValues(alpha: 0.5);
activeThumbColor = CupertinoColors.white.withValues(alpha: 0.8);
inactiveThumbColor = CupertinoColors.white.withValues(alpha: 0.8);
trackOutlineColor = isDark
? CupertinoColors.systemGrey.withValues(alpha: 0.5)
: CupertinoColors.systemGrey4.withValues(alpha: 0.5);
} else {
activeTrackColor = CupertinoColors.systemGreen;
inactiveTrackColor =
isDark ? CupertinoColors.systemGrey : CupertinoColors.systemGrey4;
activeThumbColor = CupertinoColors.white;
inactiveThumbColor = CupertinoColors.white;
trackOutlineColor =
isDark ? CupertinoColors.systemGrey : CupertinoColors.systemGrey4;
}
final pressOverlayColor = isSelected
? CupertinoColors.systemGreen.withValues(alpha: 0.12)
: CupertinoColors.systemGrey.withValues(alpha: 0.12);
// Cupertino doesn't use state layer, but we provide transparent fallback
final stateLayerColor =
WidgetStateProperty.all<Color?>(const Color(0x00000000));
final minTapTargetSize = _resolveMinTapTargetSize(
constraints: constraints,
override: contractOverrides?.minTapTargetSize,
);
return RSwitchResolvedTokens(
trackSize: contractOverrides?.trackSize ?? defaultTrackSize,
trackBorderRadius:
contractOverrides?.trackBorderRadius ?? defaultTrackBorderRadius,
trackOutlineColor:
contractOverrides?.trackOutlineColor ?? trackOutlineColor,
trackOutlineWidth: contractOverrides?.trackOutlineWidth ?? 0.0,
activeTrackColor: contractOverrides?.activeTrackColor ?? activeTrackColor,
inactiveTrackColor:
contractOverrides?.inactiveTrackColor ?? inactiveTrackColor,
// Cupertino: thumb size is fixed (no unselected/selected/pressed differentiation)
thumbSizeUnselected:
contractOverrides?.thumbSizeUnselected ?? defaultThumbSize,
thumbSizeSelected:
contractOverrides?.thumbSizeSelected ?? defaultThumbSize,
thumbSizePressed: contractOverrides?.thumbSizePressed ?? defaultThumbSize,
thumbSizeTransition:
contractOverrides?.thumbSizeTransition ?? defaultThumbSize,
activeThumbColor: contractOverrides?.activeThumbColor ?? activeThumbColor,
inactiveThumbColor:
contractOverrides?.inactiveThumbColor ?? inactiveThumbColor,
thumbPadding: contractOverrides?.thumbPadding ?? defaultThumbPadding,
// Flutter: _kDisabledOpacity = 0.5
disabledOpacity: contractOverrides?.disabledOpacity ?? 0.5,
pressOverlayColor:
contractOverrides?.pressOverlayColor ?? pressOverlayColor,
// Native CupertinoSwitch does not dim the whole control on press.
pressOpacity: contractOverrides?.pressOpacity ?? 1.0,
// Flutter: _kSwitchSize = 59×39 (track 51×31 centered inside).
minTapTargetSize: minTapTargetSize,
// Cupertino doesn't use state layer
stateLayerRadius: contractOverrides?.stateLayerRadius ?? 0.0,
stateLayerColor: contractOverrides?.stateLayerColor ?? stateLayerColor,
thumbIcon: contractOverrides?.thumbIcon,
motion: contractOverrides?.motion ??
RSwitchMotionTokens(
stateChangeDuration: motionTheme.button.stateChangeDuration,
thumbSlideDuration: const Duration(milliseconds: 200),
),
);
}