Skip to content

Commit 56f9eb9

Browse files
chore(buttons): improved typization
1 parent d082644 commit 56f9eb9

File tree

18 files changed

+81
-50
lines changed

18 files changed

+81
-50
lines changed

src/buttons/common-buttons/common-button/CommonButton.component.tsx

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,26 @@ import {styles} from './common-button.styles';
55
import {type IconProps} from '../../../icons/icon-props';
66
import {useTypography} from '../../../typography/useTypography.component';
77

8-
export interface CommonButtonProps extends TouchableOpacityProps {
8+
export interface CommonButtonProps<T extends IconProps> extends TouchableOpacityProps {
99
title: string;
1010

1111
titleStyle?: StyleProp<TextStyle>;
12-
StartIcon?: React.FC<IconProps>;
13-
EndIcon?: React.FC<IconProps>;
14-
iconProps?: IconProps;
12+
StartIcon?: React.FC<T>;
13+
EndIcon?: React.FC<T>;
14+
iconProps?: T;
1515
}
1616

1717
const DEFAULT_ICON_SIZE = 18;
1818

19-
export const CommonButton: React.FC<CommonButtonProps> = ({title, StartIcon, EndIcon, titleStyle, iconProps, style, ...props}) => {
19+
export const CommonButton = <T extends IconProps>({
20+
title,
21+
StartIcon,
22+
EndIcon,
23+
titleStyle,
24+
iconProps = {} as T,
25+
style,
26+
...props
27+
}: CommonButtonProps<T>) => {
2028
const {labelLarge} = useTypography();
2129

2230
const containerPaddingStart = StartIcon || EndIcon ? 16 : 24;

src/buttons/common-buttons/elevated-button/ElevatedButton.component.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ import {StyleSheet} from 'react-native';
33

44
import {styles} from './elevated-button.styles';
55
import {useTheme} from '../../../theme/useTheme.hook';
6+
import {type IconProps} from '../../../icons/icon-props';
67
import {convertToRGBA} from '../../../utils/convert-to-rgba';
78
import {CommonButton, type CommonButtonProps} from '../common-button/CommonButton.component';
89

9-
export const ElevatedButton: React.FC<CommonButtonProps> = ({titleStyle, style, ...props}) => {
10+
export const ElevatedButton = <T extends IconProps>({titleStyle, style, iconProps = {} as T, ...props}: CommonButtonProps<T>) => {
1011
const {primary, surface, shadow, surfaceContainer} = useTheme();
1112

1213
const colorStyles = useMemo(
@@ -26,7 +27,7 @@ export const ElevatedButton: React.FC<CommonButtonProps> = ({titleStyle, style,
2627
<CommonButton
2728
style={[colorStyles.container, styles.container, style]}
2829
titleStyle={[colorStyles.title, titleStyle]}
29-
iconProps={{color: colorStyles.title.color}}
30+
iconProps={{color: colorStyles.title.color, ...iconProps}}
3031
{...props}
3132
/>
3233
);

src/buttons/common-buttons/filled-button/FilledButton.component.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@ import React, {useMemo} from 'react';
22
import {StyleSheet} from 'react-native';
33

44
import {useTheme} from '../../../theme/useTheme.hook';
5+
import {type IconProps} from '../../../icons/icon-props';
56
import {convertToRGBA} from '../../../utils/convert-to-rgba';
67
import {CommonButton, type CommonButtonProps} from '../common-button/CommonButton.component';
78

8-
export const FilledButton: React.FC<CommonButtonProps> = ({style, titleStyle, ...props}) => {
9+
export const FilledButton = <T extends IconProps>({style, titleStyle, iconProps = {} as T, ...props}: CommonButtonProps<T>) => {
910
const {primary, surface} = useTheme();
1011

1112
const colorStyles = useMemo(
@@ -25,7 +26,7 @@ export const FilledButton: React.FC<CommonButtonProps> = ({style, titleStyle, ..
2526
<CommonButton
2627
style={[colorStyles.container, style]}
2728
titleStyle={[colorStyles.title, titleStyle]}
28-
iconProps={{color: colorStyles.title.color}}
29+
iconProps={{color: colorStyles.title.color, ...iconProps}}
2930
{...props}
3031
/>
3132
);

src/buttons/common-buttons/outlined-button/OutlinedButton.component.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ import {StyleSheet} from 'react-native';
33

44
import {styles} from './outlined-button.styles';
55
import {useTheme} from '../../../theme/useTheme.hook';
6+
import {type IconProps} from '../../../icons/icon-props';
67
import {convertToRGBA} from '../../../utils/convert-to-rgba';
78
import {CommonButton, type CommonButtonProps} from '../common-button/CommonButton.component';
89

9-
export const OutlinedButton: React.FC<CommonButtonProps> = ({titleStyle, style, ...props}) => {
10+
export const OutlinedButton = <T extends IconProps>({titleStyle, style, iconProps = {} as T, ...props}: CommonButtonProps<T>) => {
1011
const {primary, outline, surface} = useTheme();
1112

1213
const colorStyles = useMemo(
@@ -21,9 +22,9 @@ export const OutlinedButton: React.FC<CommonButtonProps> = ({titleStyle, style,
2122

2223
return (
2324
<CommonButton
24-
iconProps={{color: colorStyles.title.color}}
2525
titleStyle={[colorStyles.title, titleStyle]}
2626
style={[styles.container, colorStyles.container, style]}
27+
iconProps={{color: colorStyles.title.color, ...iconProps}}
2728
{...props}
2829
/>
2930
);

src/buttons/common-buttons/text-button/TextButton.component.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@ import React, {useMemo} from 'react';
22
import {StyleSheet} from 'react-native';
33

44
import {useTheme} from '../../../theme/useTheme.hook';
5+
import {type IconProps} from '../../../icons/icon-props';
56
import {convertToRGBA} from '../../../utils/convert-to-rgba';
67
import {CommonButton, type CommonButtonProps} from '../common-button/CommonButton.component';
78

8-
export const TextButton: React.FC<CommonButtonProps> = ({titleStyle, ...props}) => {
9+
export const TextButton = <T extends IconProps>({titleStyle, iconProps = {} as T, ...props}: CommonButtonProps<T>) => {
910
const {primary, surface} = useTheme();
1011

1112
const colorStyles = useMemo(
@@ -16,5 +17,5 @@ export const TextButton: React.FC<CommonButtonProps> = ({titleStyle, ...props})
1617
[props.disabled]
1718
);
1819

19-
return <CommonButton titleStyle={[colorStyles.title, titleStyle]} iconProps={{color: colorStyles.title.color}} {...props} />;
20+
return <CommonButton titleStyle={[colorStyles.title, titleStyle]} iconProps={{color: colorStyles.title.color, ...iconProps}} {...props} />;
2021
};

src/buttons/common-buttons/tonal-button/TonalButton.component.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ import {StyleSheet} from 'react-native';
44
import {useTheme} from '../../../theme/useTheme.hook';
55
import {convertToRGBA} from '../../../utils/convert-to-rgba';
66
import {CommonButton, type CommonButtonProps} from '../common-button/CommonButton.component';
7+
import {type IconProps} from '../../../icons/icon-props';
78

8-
export const TonalButton: React.FC<CommonButtonProps> = ({titleStyle, style, ...props}) => {
9+
export const TonalButton = <T extends IconProps>({titleStyle, style, iconProps = {} as T, ...props}: CommonButtonProps<T>) => {
910
const {secondaryContainer, surface} = useTheme();
1011

1112
const colorStyles = useMemo(
@@ -25,7 +26,7 @@ export const TonalButton: React.FC<CommonButtonProps> = ({titleStyle, style, ...
2526
<CommonButton
2627
style={[colorStyles.container, style]}
2728
titleStyle={[colorStyles.title, titleStyle]}
28-
iconProps={{color: colorStyles.title.color}}
29+
iconProps={{color: colorStyles.title.color, ...iconProps}}
2930
{...props}
3031
/>
3132
);

src/buttons/floating-action-button/FloatingActionButton.component.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, {useMemo} from 'react';
1+
import React, {useMemo, type ReactElement} from 'react';
22
import Animated, {FadeInRight, LinearTransition, FadeOutRight} from 'react-native-reanimated';
33
import {TouchableOpacity, type StyleProp, type TextStyle, type TouchableOpacityProps} from 'react-native';
44

@@ -20,27 +20,27 @@ export enum FloatingActionButtonType {
2020
TERTIARY = 'TERTIARY',
2121
}
2222

23-
export interface FloatingActionButtonProps extends TouchableOpacityProps {
23+
export interface FloatingActionButtonProps<T extends IconProps> extends TouchableOpacityProps {
2424
type?: FloatingActionButtonType;
2525
label?: string;
2626
extended?: boolean;
27-
Icon?: React.FC<IconProps>;
28-
iconProps?: IconProps;
27+
Icon?: React.FC<T>;
28+
iconProps?: T;
2929
size?: FloatingActionButtonSize;
3030
labelStyle?: StyleProp<TextStyle>;
3131
}
3232

33-
export const FloatingActionButton: React.FC<FloatingActionButtonProps> = ({
33+
export const FloatingActionButton = <T extends IconProps>({
3434
label,
35-
iconProps,
35+
iconProps = {} as T,
3636
labelStyle,
3737
Icon = EditIcon,
3838
extended = true,
3939
size = FloatingActionButtonSize.SMALL,
4040
type = FloatingActionButtonType.PRIMARY,
4141
style,
4242
...props
43-
}) => {
43+
}: FloatingActionButtonProps<T>): ReactElement => {
4444
const {labelLarge} = useTypography();
4545
const {shadow, primaryContainer, surfaceContainer, secondaryContainer, tertiaryContainer, primary} = useTheme();
4646

src/buttons/icon-buttons/base-icon-button/BaseIconButton.component.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@ import {TouchableOpacity, type TouchableOpacityProps} from 'react-native';
44
import {type IconProps} from '../../../types/icon-props.type';
55
import {getIconButtonFrameStyles, styles} from './base-icon-button.styles';
66

7-
export interface BaseIconButtonProps extends TouchableOpacityProps {
8-
Icon: React.FC<IconProps>;
7+
export interface BaseIconButtonProps<T extends IconProps> extends TouchableOpacityProps {
8+
Icon: React.FC<T>;
9+
iconProps: T;
910

1011
size?: number;
11-
iconProps?: IconProps;
1212
}
1313

1414
const DEFAULT_SIZE = 40;
1515
const ICON_SIZE_COEFF = 0.6;
1616

17-
export const BaseIconButton: React.FC<BaseIconButtonProps> = ({Icon, size = DEFAULT_SIZE, iconProps, style, ...props}) => (
17+
export const BaseIconButton = <T extends IconProps>({Icon, size = DEFAULT_SIZE, iconProps, style, ...props}: BaseIconButtonProps<T>) => (
1818
<TouchableOpacity style={[styles.container, getIconButtonFrameStyles(size), style]} hitSlop={8} {...props}>
1919
<Icon size={size * ICON_SIZE_COEFF} {...iconProps} />
2020
</TouchableOpacity>

src/buttons/icon-buttons/filled-icon-button/FilledIconButton.component.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import React, {useMemo} from 'react';
22

33
import {useTheme} from '../../../theme/useTheme.hook';
4+
import {type IconProps} from '../../../icons/icon-props';
45
import {type IconButtonProps} from '../icon-button.types';
56
import {convertToRGBA} from '../../../utils/convert-to-rgba';
67
import {BaseIconButton} from '../base-icon-button/BaseIconButton.component';
78

8-
export const FilledIconButton: React.FC<IconButtonProps> = ({selected, Icon, selectedIcon, style, ...props}) => {
9+
export const FilledIconButton = <T extends IconProps>({selected, Icon, selectedIcon, iconProps = {} as T, style, ...props}: IconButtonProps<T>) => {
910
const {primary, surface, surfaceContainer} = useTheme();
1011

1112
const [disabledIconColor, disabledContainerColor] = useMemo(
@@ -21,6 +22,11 @@ export const FilledIconButton: React.FC<IconButtonProps> = ({selected, Icon, sel
2122
: [activeContainerColor, activeIconColor];
2223

2324
return (
24-
<BaseIconButton style={[{backgroundColor: appliedContainerColor}, style]} Icon={IconComponent} iconProps={{color: appliedIconColor}} {...props} />
25+
<BaseIconButton
26+
Icon={IconComponent}
27+
iconProps={{color: appliedIconColor, ...iconProps}}
28+
style={[{backgroundColor: appliedContainerColor}, style]}
29+
{...props}
30+
/>
2531
);
2632
};
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import type {IconProps} from '../../icons/icon-props';
2-
import type {BaseIconButtonProps} from './base-icon-button/BaseIconButton.component';
1+
import {type IconProps} from '../../icons/icon-props';
2+
import {type BaseIconButtonProps} from './base-icon-button/BaseIconButton.component';
33

4-
export interface IconButtonProps extends BaseIconButtonProps {
4+
export interface IconButtonProps<T extends IconProps> extends BaseIconButtonProps<T> {
55
selected?: boolean;
6-
selectedIcon?: React.FC<IconProps>;
6+
selectedIcon?: React.FC<T>;
77
}

0 commit comments

Comments
 (0)