Reputation: 79
I am new to React and Typescript, I am trying to add dark-mode to my project, I created globalStyle component, Themes component and using Themeprovider.
I am facing an issue on my globalStyle component when it says: property 'body' does not exist type 'DefaultTheme'
My globalStyles.tsx code is as follow:
import { createGlobalStyle} from "styled-components"
export const GlobalStyles = createGlobalStyle`
body {
background: ${({ theme }) => theme.body};
color: ${({ theme }) => theme.text};
font-family: Tahoma, Helvetica, Arial, Roboto, sans-serif;
transition: all 0.50s linear;
}`
my Themes.tsx:
export const lightTheme = {
body: '#FFF',
text: '#363537',
background: '#363537',
}
export const darkTheme = {
body: '#363537',
text: '#FAFAFA',
background: '#999',
}
and my Themeprovider code on App.tsx:
<ThemeProvider theme={this.state.theme === 'light' ? lightTheme : darkTheme}>
<>
<GlobalStyles/>
<ul className='tickets'>
{filteredTickets.map((ticket) => (
<li key={ticket.id} className={ticket.toggle ? 'expand' : 'ticket'}>
<h5 className='title'>{ticket.title}</h5>
<button onClick={() => this.onHide(ticket.id)}>Hide</button>
<p className={ticket.toggle ? 'show-more' : 'content'}>{ticket.content}</p>
<button onClick={()=> this.onToggle(ticket.id)}>{ticket.toggle ? 'Show less' : 'Show more'}</button>
<footer>
<div className='meta-data'>By {ticket.userEmail} | { new Date(ticket.creationTime).toLocaleString()}</div>
</footer>
</li>))}
</ul>
</>
</ThemeProvider>
What am I doing wrong and why theme.body and theme.text is not recognized on globalStyles.tsx?
Thanks !
Upvotes: 8
Views: 14386
Reputation: 151
Based on the styled-components
docs (https://styled-components.com/docs/api#typescript) I created an interface for the body type:
export interface DefaultTheme {
body: string;
}
export const GlobalStyle = createGlobalStyle<{ theme: DefaultTheme }>`
body{
background-color: ${({ theme }) => theme.body};
color: var(--font-color);
}
`;
This works pretty well for me.
Upvotes: 2
Reputation: 323
So the answer above fails, as useTheme does not know what type you passed to createGlobalStyles.
But this is a typescript workaround that doesn't require you to use ts-ginore:
createGlobalStyle<{theme: ThemeType}>
const theme = useTheme() as ThemeType;
Upvotes: 1
Reputation: 52535
I'm basing this answer on the following link: https://spectrum.chat/styled-components/general/i-cant-use-my-theme-in-createglobalstyle-function-styled-components-v4-react-v16-6-3~0978b404-ab71-45c9-8f75-0862abde4eb5
createGlobalStyle
can accept a shape for the theme:
createGlobalStyle<{theme: ThemeType}>
From the styled-components
docs, there's this (https://styled-components.com/docs/api#typescript):
declare module 'styled-components' {
export interface DefaultTheme {
borderRadius: string;
colors: {
main: string;
secondary: string;
};
}
}
So, I suggest you set up an interface for your theme, as above, and then pass it into createGlobalStyle
in place of ThemeType
Upvotes: 19