I want to build a component that allows me to have different button sizes with react-native-elements
. To achieve this I build a custom component which have a property size
and with this I access dynamically to a specific size of the button with its respective styles inside theme
object. Everything works as expected, but I have the following error in typescript: TS2532: Object is possibly 'undefined'.
every time I try to access to the sizes
object inside theme
with the bracket notation.
Custom button component
import React, { useContext } from 'react';
import { Button, FullTheme, ThemeContext } from 'react-native-elements';
export type Props = Button['props'];
export type Theme = Partial<FullTheme>;
const styles = {
button: (theme: Partial<FullTheme>, size: string) => ({
padding: theme?.Button?.sizes[size]?.padding, // problem here
}),
title: (theme: Partial<FullTheme>, size: string) => ({
fontSize: theme?.Button?.sizes[size]?.fontSize, // problem here
lineHeight: theme?.Button?.sizes[size]?.lineHeight, // problem here
fontFamily: theme?.Button?.font?.fontFamily,
}),
};
function ButtonElement(props: Props): JSX.Element {
const {
size = 'medium',
children,
...rest
} = props;
const { theme } = useContext(ThemeContext);
return (
<Button
titleStyle={styles.title(theme, size)}
buttonStyle={styles.button(theme, size)}
{...rest}
>
{children}
</Button>
);
}
theme.ts
export const theme = {
Button: {
font: {
fontFamily: 'inter-display-bold',
},
sizes: {
small: {
fontSize: 14,
padding: 10,
lineHeight: 20,
},
medium: {
fontSize: 18,
padding: 14,
lineHeight: 24,
},
large: {
fontSize: 20,
padding: 18,
lineHeight: 24,
},
},
},
}
// react-native-elements.d.ts -> Extending the default theme to manage button sizes
import 'react-native-elements';
import { StyleProp, TextStyle } from 'react-native';
export type Sizes = {[index: string]: TextStyle};
export type Size = 'small' | 'medium' | 'large';
declare module 'react-native-elements' {
export interface ButtonProps {
font?: TextStyle;
sizes?: Sizes;
size?: Size;
}
export interface FullTheme {
Button: Partial<ButtonProps>;
}
}
pass theme
object to the components tree
// pass theme to the component tree
import { theme } from '@common/styles/theme';
export default function App(): JSX.Element | null {
return (
<ThemeProvider theme={theme}>
<SafeAreaProvider>
<Navigation />
<StatusBar />
</SafeAreaProvider>
</ThemeProvider>
);
}