Skip to main content
Version: 4.0.0-rc.8

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>
);
};
info

Theme Key for custom component must be unique