diff --git a/example/lib/src/storybook/stories/primitives/radio.dart b/example/lib/src/storybook/stories/primitives/radio.dart index bf44f54b..4fdf6051 100644 --- a/example/lib/src/storybook/stories/primitives/radio.dart +++ b/example/lib/src/storybook/stories/primitives/radio.dart @@ -26,7 +26,7 @@ class _RadioStoryState extends State { Widget build(BuildContext context) { final activeColorKnob = context.knobs.nullable.options( label: "activeColor", - description: "MoonColors variants for selected MoonRadio.", + description: "MoonColors variants for selected MoonRadio background.", enabled: false, initial: 0, // piccolo @@ -37,7 +37,7 @@ class _RadioStoryState extends State { final inactiveColorKnob = context.knobs.nullable.options( label: "inactiveColor", - description: "MoonColors variants for unselected MoonRadio.", + description: "MoonColors variants for unselected MoonRadio background.", enabled: false, initial: 0, // piccolo @@ -46,6 +46,40 @@ class _RadioStoryState extends State { final inactiveColor = colorTable(context)[inactiveColorKnob ?? 40]; + final activeBorderColorKnob = context.knobs.nullable.options( + label: "activeBorderColor", + description: "MoonColors variants for selected MoonRadio border.", + enabled: false, + initial: 0, + // piccolo + options: colorOptions, + ); + + final activeBorderColor = colorTable(context)[activeBorderColorKnob ?? 40]; + + final inactiveBorderColorKnob = context.knobs.nullable.options( + label: "inactiveBorderColor", + description: "MoonColors variants for unselected MoonRadio border.", + enabled: false, + initial: 0, + // piccolo + options: colorOptions, + ); + + final inactiveBorderColor = + colorTable(context)[inactiveBorderColorKnob ?? 40]; + + final indicatorColorKnob = context.knobs.nullable.options( + label: "indicatorColor", + description: "MoonColors variants for selected MoonRadio indicator.", + enabled: false, + initial: 0, + // piccolo + options: colorOptions, + ); + + final indicatorColor = colorTable(context)[indicatorColorKnob ?? 40]; + final isToggleableKnob = context.knobs.boolean( label: "toggleable", description: "Whether selected MoonRadio can be unselected.", @@ -72,6 +106,9 @@ class _RadioStoryState extends State { groupValue: valueCustom, activeColor: activeColor, inactiveColor: inactiveColor, + activeBorderColor: activeBorderColor, + inactiveBorderColor: inactiveBorderColor, + indicatorColor: indicatorColor, toggleable: isToggleableKnob, onChanged: isDisabledKnob ? null diff --git a/lib/src/widgets/radio/radio.dart b/lib/src/widgets/radio/radio.dart index 02cc0de2..e858d5f3 100644 --- a/lib/src/widgets/radio/radio.dart +++ b/lib/src/widgets/radio/radio.dart @@ -31,12 +31,21 @@ class MoonRadio extends StatefulWidget { /// unselected. final bool toggleable; - /// The color of the active (selected) radio button. + /// The background color of the active (selected) radio button. final Color? activeColor; /// The background color of the inactive (unselected) radio button. final Color? inactiveColor; + /// The border color of the active (selected) radio button. + final Color? activeBorderColor; + + /// The border color of the inactive (unselected) radio button. + final Color? inactiveBorderColor; + + /// The indicator color of the active (selected) radio button. + final Color? indicatorColor; + /// The size of the radio button tap target. /// /// Defaults to 40. @@ -80,6 +89,9 @@ class MoonRadio extends StatefulWidget { this.toggleable = false, this.activeColor, this.inactiveColor, + this.activeBorderColor, + this.inactiveBorderColor, + this.indicatorColor, this.tapAreaSizeValue = 40, this.focusNode, this.semanticLabel, @@ -111,8 +123,8 @@ class _RadioState extends State> { @override Widget build(BuildContext context) { - const double sizeValue = 16; - const double dotSizeValue = (sizeValue - 1) / 2; + const double sizeValue = 20; + const double dotSizeValue = 8; final MoonFocusEffect focusEffect = MoonEffectsTheme(tokens: MoonTokens.light).controlFocusEffect; @@ -121,7 +133,23 @@ class _RadioState extends State> { widget.activeColor ?? MoonColors.light.piccolo; final Color effectiveInactiveColor = - widget.inactiveColor ?? MoonColors.light.trunks; + widget.inactiveColor ?? const Color.fromRGBO(252, 252, 253, 1); + + final Color effectiveActiveBorderColor = + widget.activeBorderColor ?? effectiveActiveColor; + + final Color effectiveInactiveBorderColor = + widget.inactiveBorderColor ?? const Color.fromRGBO(205, 206, 214, 1); + + final Color effectiveIndicatorColor = + widget.indicatorColor ?? const Color.fromRGBO(252, 252, 253, 1); + + const Color hoverColor = Color.fromRGBO(28, 32, 36, 0.08); + + final effectiveHoverColor = Color.alphaBlend( + hoverColor, + _selected ? effectiveActiveColor : effectiveInactiveColor, + ); final Color effectiveFocusEffectColor = focusEffect.effectColor; @@ -138,7 +166,7 @@ class _RadioState extends State> { $box.chain ..width(_selected ? dotSizeValue : 0) ..height(_selected ? dotSizeValue : 0) - ..color(effectiveActiveColor) + ..color(_selected ? effectiveIndicatorColor : effectiveInactiveColor) ..shape.circle(), ).animate(duration: effectiveFocusEffectDuration); @@ -146,10 +174,18 @@ class _RadioState extends State> { $box.chain ..height(sizeValue) ..width(sizeValue) - ..border - .color(_selected ? effectiveActiveColor : effectiveInactiveColor) + ..color(_selected ? effectiveActiveColor : effectiveInactiveColor) + ..border( + width: 2, + color: _selected + ? effectiveActiveBorderColor + : effectiveInactiveBorderColor, + ) ..alignment.center() ..shape.circle(), + $on.hover( + $box.color(effectiveHoverColor), + ), ).animate(duration: effectiveFocusEffectDuration); final Style effectsStyle = Style(