Extending Theme
TypeScript definitions for your theme can be extended by using TypeScript's declaration merging feature. First you need to create a declaration file called themed.d.ts
and then declare the module @rneui/themed
and 're-export' the types that you want to extend. i.e. below we add a custom p1Style
to the Text
theme object and we add a bunch of colors to the colors
object.
Adding custom colors
TypeScript will only autocomplete RNE's default colors when accessing the theme. To add your custom colors to the Colors
type, you can use TypeScript module declaration:
// themed.d.ts
import '@rneui/themed';
declare module '@rneui/themed' {
export interface Colors {
tertiary: string;
accent: string;
surface: string;
}
}
Then when you create your ThemeProvider
instance,
// App.tsx
const theme = createTheme({
lightColors: {
tertiary: '#124789',
accent: '#f98652',
surface: '#0990763',
},
darkColors: {
tertiary: '#124789',
accent: '#908652',
surface: '#0990763',
},
components:{
Button:(props,theme)=>({
containerStyle:{
backgroundColor:theme.colors.tertiary
}
})
}
mode: 'light', // or 'dark'
});
// Wrap with ThemeProvider
const App = () => {
return (
<ThemeProvider theme={theme}>
<Component />
</ThemeProvider>
);
};
Usage
// Component.tsx
export const Component = () => {
const { theme } = useTheme();
return <Text style={{ color: theme.colors.accent }} />;
};
Adding custom 'other' properties
Similar to how you can extend/set custom colors, you can add your own properties to the theme
type using TypeScript module declaration:
// themed.d.ts
import '@rneui/themed';
declare module '@rneui/themed' {
export interface Theme {
myCustomProperty: string;
myCustomFunction: () => void;
}
}
Usage
// App.tsx
const App = () => {
const { theme } = useTheme();
return <Text>{theme.myCustomProperty}</Text>;
};
Extending RNE default components
If you need to extend some props of RNE's default components, you can use TypeScript module declaration, Also remember to extend ComponentTheme
too.
// themed.d.ts
import '@rneui/themed';
declare module '@rneui/themed' {
export interface TextProps {
bold: boolean;
}
export interface ComponentTheme {
Text: Partial<TextProps>;
}
}
For eg. You can use the following code to extend the Text
component:
const myTheme = createTheme({
Text: (props) => ({
style: {
fontWeight: props.bold ? 'bold' : 'normal',
},
}),
});
and use it like this
const App = () => {
const { theme } = useTheme();
return (
<View>
<Text>Normal Text</Text>
<Text bold>Bold Text</Text>
</View>
);
};
Using the theme in your own components
You may want to make use of the theming utilities in your own components. For this you can use the withTheme(Component,ComponentThemeKey)
HOC exported from this library. It adds three props to the component it wraps - theme, updateTheme and replaceTheme.
import { withTheme } from '@rneui/themed';
type CustomComponentProps = {
title: string;
titleStyle: StyleProps<TextStyle>;
};
const CustomComponent = (props: CustomComponentProps) => {
// Access theme from props
const { theme, updateTheme, replaceTheme } = props;
// ...
};
export default withTheme<CustomComponentProps>(CustomComponent, 'ComponentKey');
declare module '@rneui/themed' {
export interface ComponentTheme {
ComponentKey: Partial<CustomComponentProps>;
}
}
import { ThemeProvider, createTheme } from '@rneui/themed';
const myTheme = createTheme({
components: {
ComponentKey: {
titleStyle: {
color: 'red',
},
},
},
});
const App = () => {
return (
<ThemeProvider theme={myTheme}>
<CustomComponent title="My Component" />
</ThemeProvider>
);
};
Theme Key for custom component must be unique