diff --git a/src/components/ToggleButton/ToggleButton.tsx b/src/components/ToggleButton/ToggleButton.tsx index bfdd3fca5c..8343bdbc1d 100644 --- a/src/components/ToggleButton/ToggleButton.tsx +++ b/src/components/ToggleButton/ToggleButton.tsx @@ -12,6 +12,7 @@ import { import color from 'color'; import { ToggleButtonGroupContext } from './ToggleButtonGroup'; +import type { ToggleButtonContextType } from './ToggleButtonGroup'; import { getToggleButtonColor } from './utils'; import { useInternalTheme } from '../../core/theming'; import { black, white } from '../../styles/themes/v2/colors'; @@ -20,7 +21,7 @@ import { forwardRef } from '../../utils/forwardRef'; import type { IconSource } from '../Icon'; import IconButton from '../IconButton/IconButton'; -export type Props = { +export type Props = { /** * Icon to display for the `ToggleButton`. */ @@ -48,11 +49,11 @@ export type Props = { /** * Function to execute on press. */ - onPress?: (value?: GestureResponderEvent | string) => void; + onPress?: (value?: GestureResponderEvent | Value) => void; /** * Value of button. */ - value?: string; + value?: Value; /** * Status of button. */ @@ -69,6 +70,12 @@ export type Props = { testID?: string; }; +// React.forwardRef doesn't preserve generic type parameters, causing type inference issues +// Define a generic function type to maintain proper TypeScript typing for +type ToggleButtonComponent = ( + props: Props & { ref?: React.Ref } +) => React.ReactElement; + /** * Toggle buttons can be used to group related options. To emphasize groups of related toggle buttons, * a group should share a common container. @@ -99,8 +106,9 @@ export type Props = { * * ``` */ -const ToggleButton = forwardRef( - ( + +const ToggleButton = forwardRef( + ( { icon, size, @@ -113,18 +121,16 @@ const ToggleButton = forwardRef( onPress, rippleColor, ...rest - }: Props, - ref + }: Props, + ref: React.ForwardedRef ) => { const theme = useInternalTheme(themeOverrides); const borderRadius = theme.roundness; return ( - {( - context: { value: string | null; onValueChange: Function } | null - ) => { - const checked: boolean | null = + {(context: ToggleButtonContextType | null) => { + const checked: boolean = (context && context.value === value) || status === 'checked'; const backgroundColor = getToggleButtonColor({ theme, checked }); @@ -139,13 +145,13 @@ const ToggleButton = forwardRef( { + onPress={(e?: GestureResponderEvent) => { if (onPress) { onPress(e); } if (context) { - context.onValueChange(!checked ? value : null); + context.onValueChange(!checked ? value ?? null : null); } }} size={size} @@ -171,7 +177,7 @@ const ToggleButton = forwardRef( ); } -); +) as ToggleButtonComponent; const styles = StyleSheet.create({ content: { diff --git a/src/components/ToggleButton/ToggleButtonGroup.tsx b/src/components/ToggleButton/ToggleButtonGroup.tsx index 4fc30d9f83..39d738cc0d 100644 --- a/src/components/ToggleButton/ToggleButtonGroup.tsx +++ b/src/components/ToggleButton/ToggleButtonGroup.tsx @@ -15,9 +15,9 @@ export type Props = { children: React.ReactNode; }; -type ToggleButtonContextType = { +export type ToggleButtonContextType = { value: Value | null; - onValueChange: (item: Value) => void; + onValueChange: (item: Value | null) => void; }; export const ToggleButtonGroupContext = diff --git a/src/components/ToggleButton/ToggleButtonRow.tsx b/src/components/ToggleButton/ToggleButtonRow.tsx index 380ae77203..df6e6cd3ff 100644 --- a/src/components/ToggleButton/ToggleButtonRow.tsx +++ b/src/components/ToggleButton/ToggleButtonRow.tsx @@ -4,15 +4,15 @@ import { StyleSheet, View, StyleProp, ViewStyle } from 'react-native'; import ToggleButton from './ToggleButton'; import ToggleButtonGroup from './ToggleButtonGroup'; -export type Props = { +export type Props = { /** * Function to execute on selection change. */ - onValueChange: (value: string) => void; + onValueChange: (value: Value) => void; /** * Value of the currently selected toggle button. */ - value: string; + value: Value; /** * React elements containing toggle buttons. */ @@ -43,7 +43,12 @@ export type Props = { * *``` */ -const ToggleButtonRow = ({ value, onValueChange, children, style }: Props) => { +const ToggleButtonRow = ({ + value, + onValueChange, + children, + style, +}: Props) => { const count = React.Children.count(children); return (