In my development project using styled components with React and typescript, I have set up a theme.ts file to define the variables that are used in my ThemeProvider to expose them across the application. Additionally, I have created a styled.d.ts file where I declare DefaultTheme as an interface for theme.ts.
Recently, I created a media.ts file where I implemented reusable media queries based on an article I found at: https://medium.com/@samuelresua/easy-media-queries-in-styled-components-690b78f50053. Now, I want to include this media functionality in my theme so that it can be utilized throughout:
media.ts
import { css } from 'styled-components'
interface MediaQueryProps {
[key: string]: any;
}
const breakpoints: MediaQueryProps = {
xs: 480,
sm: 768,
md: 992,
lg: 1200
}
export default Object.keys(breakpoints).reduce((acc, label) => {
acc[label] = (literals: TemplateStringsArray, ...placeholders: any[]) => css`
@media (max-width: ${breakpoints[label]}px) {
${css(literals, ...placeholders)};
}
`.join("");
return acc
}, {} as Record<keyof typeof breakpoints, (l: TemplateStringsArray, ...p: any[])=> string>)
theme.ts
import { DefaultTheme } from 'styled-components'
import media from './media';
const theme: DefaultTheme = {
primary: "#262646",
secondary: "#F9FAFE",
success: "#00897B",
danger: "#B00020",
text: "#263646",
background: "#E8EAF6",
white: "#ffffff",
fonts: ["sans-serif", "Roboto"],
...media,
fontSizes: {
small: "1em",
medium: "1.2em",
},
}
export default theme;
styled.d.ts
// import original module declarations
import 'styled-components'
// and extend them!
declare module 'styled-components' {
export interface DefaultTheme {
primary: string,
secondary: string,
success: string,
danger: string,
text: string,
background: string,
white: string,
fonts: Array<string>,
fontSizes: {
small: string,
medium: string,
},
}
}
When attempting to use the mediaqueries in my App.ts without including ...media in DefaultTheme, I encounter an error stating 'Property 'media' does not exist on type 'DefaultTheme'.ts(2339)':
const TableRow = styled.tr`
&:nth-of-type(odd){
background: ${props => props.theme.secondary}
}
${({theme}) => theme.media.sm`
background: ${theme.secondary}
`}
`
However, if I try defining it as follows, another error arises:
declare module 'styled-components' {
export interface DefaultTheme {
media: Array<string>
}
}
This results in an error in theme.ts stating 'Property 'media' is missing in type '{ primary: string; secondary: string; success: string; danger: string; text: string; background: string; white: string; fonts: string[]; fontSizes: { small: string; medium: string; }; }' but required in type 'DefaultTheme'.ts(2741)'
I am struggling to determine the correct way to define it in order for everything to function properly. When hovering over media in my code editor, I receive the following information from Typescript:
(alias) const media: Record string>
If you have any insights or guidance, please help...