1- import React , { useEffect } from 'react' ;
1+ import React , { useEffect , useMemo } from 'react' ;
22import { Pressable , type PressableProps , type StyleProp , type ViewStyle , type TextStyle , type ColorValue } from 'react-native' ;
33import Animated , {
44 FadeIn ,
@@ -14,12 +14,14 @@ import Animated, {
1414import { styles } from './button-segment.styles' ;
1515import { useTheme } from '../../../theme/useTheme.hook' ;
1616import { type IconProps } from '../../../icons/icon-props' ;
17+ import { convertToRGBA } from '../../../utils/convert-to-rgba' ;
1718import { useTypography } from '../../../typography/useTypography.component' ;
1819import { AnimatedSelectedIcon } from './animated-selected-icon/AnimatedSelectedIcon.component' ;
1920
2021interface ButtonSegmentProps < T > extends Omit < PressableProps , 'onPress' > {
2122 value : T ;
2223 selected : boolean ;
24+ disabled : boolean ;
2325 multiSelectionEnabled : boolean ;
2426
2527 label ?: string ;
@@ -40,6 +42,7 @@ export const ButtonSegment = React.memo(
4042 < T extends any > ( {
4143 value,
4244 selected,
45+ disabled,
4346 Icon,
4447 label,
4548 multiSelectionEnabled,
@@ -56,16 +59,20 @@ export const ButtonSegment = React.memo(
5659 const { surface, secondaryContainer} = useTheme ( ) ;
5760
5861 const fill = useSharedValue ( Number ( selected ) ) ;
62+ const labelDisabledColor = useMemo ( ( ) => convertToRGBA ( surface . text as string , 0.38 ) , [ ] ) ;
63+
64+ const defaultIconColor = selected ? secondaryContainer . text : iconColor ?? surface . text ;
65+ const appliedIconColor = disabled ? labelDisabledColor : defaultIconColor ;
5966
6067 useEffect ( ( ) => {
6168 fill . value = withTiming ( Number ( selected ) ) ;
6269 } , [ selected ] ) ;
6370
6471 const animatedLabelStyle = useAnimatedStyle (
6572 ( ) => ( {
66- color : interpolateColor ( fill . value , [ 0 , 1 ] , [ surface . text as string , secondaryContainer . text as string ] ) ,
73+ color : disabled ? labelDisabledColor : interpolateColor ( fill . value , [ 0 , 1 ] , [ surface . text as string , secondaryContainer . text as string ] ) ,
6774 } ) ,
68- [ ]
75+ [ disabled ]
6976 ) ;
7077
7178 const circleAnimatedStyle = useAnimatedStyle ( ( ) => {
@@ -91,25 +98,22 @@ export const ButtonSegment = React.memo(
9198 } ) ;
9299 } ;
93100
94- const renderIconConditionally = ( ) => {
95- const defaultIconColor = selected ? secondaryContainer . text : surface . text ;
96-
97- return Icon ? (
101+ const renderIconConditionally = ( ) =>
102+ Icon ? (
98103 < Animated . View layout = { LinearTransition } entering = { FadeIn } exiting = { FadeOut } >
99- < Icon size = { iconSize } color = { iconColor ?? defaultIconColor } />
104+ < Icon size = { iconSize } color = { appliedIconColor } />
100105 </ Animated . View >
101106 ) : null ;
102- } ;
103107
104108 return (
105- < Pressable style = { [ styles . container , style ] } { ...props } onPress = { handleSegmentPress } >
109+ < Pressable style = { [ styles . container , style ] } disabled = { disabled } { ...props } onPress = { handleSegmentPress } >
106110 < Animated . View style = { [ styles . ripple , { backgroundColor : rippleColor ?? secondaryContainer . background } , circleAnimatedStyle ] } />
107111 { withCheckmark && selected ? (
108112 < Animated . View layout = { LinearTransition } entering = { FadeIn } >
109- < AnimatedSelectedIcon width = { iconSize } height = { iconSize } strokeWidth = { 2 } stroke = { secondaryContainer . text } />
113+ < AnimatedSelectedIcon width = { iconSize } height = { iconSize } strokeWidth = { 2 } stroke = { appliedIconColor } />
110114 </ Animated . View >
111115 ) : null }
112- { Icon && withCheckmark && selected ? null : renderIconConditionally ( ) }
116+ { Icon && withCheckmark && label && selected ? null : renderIconConditionally ( ) }
113117 { label ? (
114118 < Animated . Text layout = { LinearTransition } style = { [ labelLarge , animatedLabelStyle , labelStyle ] } >
115119 { label }
0 commit comments