solid-styled-components
solid-styled-components copied to clipboard
ThemeProvider does not accept theme change over createContext
Issue Description
Expected Behavior
Change props theme in styled of the "solid-styled-components" via createSignal or createContext.
Actual Behavior
When receiving context or signal, styled of the ThemeProvider doesn't seem to notice the change in state.
Erros Presented
Solid did not show errors in console or browser
Steps to Reproduce
- Start a new solid project
npx degit solidjs/templates/ts my-app
- Add solid-styled-components to your project
yarn add solid-styled-components
- Create a light and a dark theme in src/styles/theme/index.ts.
export interface ITheme{
colors: {
background: {
index: string;
header: string;
}
fonts: {
title: string;
subTitle: string;
text: string;
},
book: {
index: string;
green: string;
red: string;
orange: string;
blue: string;
cyan: string;
},
border:{
header: string;
}
},
fonts: {
weight:{
light: number;
regular: number;
medium: number;
bold: number;
black: number;
},
family: {
title: string;
}
},
}
const darkTheme: ITheme = {
colors:{
background: {
index: "#12131A",
header: "#1E1E1E",
},
fonts: {
title: "#FFFFFF",
subTitle: "hsl(225, 20%, 60%)",
text: "hsl(225, 20%, 60%)",
},
book: {
index: "#2C2C2C",
green: '#2ED47A',
red: "#e83f58",
orange: "#ff872c",
blue: "#1182D9",
cyan: "#6FB6F6",
},
border:{
header: "#121212"
}
},
fonts: {
weight: {
light: 300,
regular: 400,
medium: 500,
bold: 700,
black: 900,
},
family: {
title: "Roboto",
}
},
};
const lightTheme: ITheme = {
colors:{
background: {
index: "#FFFFFF",
header: "#FFFFFF",
},
fonts: {
title: "#1E1E1E",
subTitle: "hsl(225, 20%, 60%)",
text: "rgba(0, 0, 0, 0.6)",
},
book: {
index: "hsl(225, 20%, 96%)",
green: '#2ED47A',
red: "#e83f58",
orange: "#ff872c",
blue: "#1182D9",
cyan: "#6FB6F6",
},
border:{
header: "hsl(225, 20%, 96%)"
}
},
fonts: {
weight: {
light: 300,
regular: 400,
medium: 500,
bold: 700,
black: 900,
},
family: {
title: "Roboto",
}
},
};
export const themes = {
light: lightTheme,
dark: darkTheme,
}
export type TThemeName = keyof typeof themes;
export type TThemeType = typeof themes.light | typeof themes.dark;
- Extend definitions using declaration merge in a src/@types/styled.d.ts.
import "solid-styled-components";
import { TThemeType } from "../styles/theme";
declare module "solid-styled-components" {
export interface DefaultTheme extends TThemeType {}
}
- Create a context of your app theme in src/contexts/theme/index.tsx
import {
createContext,
useContext,
ParentComponent,
createSignal,
} from "solid-js";
import { themes } from "../../styles/theme";
import { TThemeName, TThemeType } from "../../styles/theme";
export type ThemeContextState = {
theme: () => TThemeType;
};
export type ThemeContextValue = [
state: ThemeContextState,
actions: {
toggleTheme: (selectTheme: TThemeName) => void;
themeName: () => TThemeName;
}
];
const AppThemeContext = createContext<ThemeContextValue>([
{
theme: () => themes["dark"],
},
{
toggleTheme: () => undefined,
themeName: () => "dark",
},
]);
export const AppThemeProvider: ParentComponent = (props) => {
const [modeTheme, setModeTheme] = createSignal<TThemeName>("dark");
const toggleTheme = (mode: TThemeName) => {
setModeTheme(mode);
};
const themeName = () => {
return modeTheme();
};
const theme = () => {
return themes[modeTheme()];
};
return (
<AppThemeContext.Provider value={[{ theme }, { toggleTheme, themeName }]}>
{props.children}
</AppThemeContext.Provider>
);
};
export const useTheme = () => useContext(AppThemeContext);
- Create global Styles in src/styles/global/index.tsx.
import { createGlobalStyles } from "solid-styled-components";
export const GlobalStyles = () => {
const Styles = createGlobalStyles`
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html, body {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
`;
return <Styles />;
};
- Create a Container component using the styled from "solid-styled-components" in src/components/Container/index.tsx.
import type { Component, JSXElement } from "solid-js";
import { styled } from "solid-styled-components";
const Content = styled("div")`
width: 100vw;
height: 100vh;
background-color: ${({ theme }) => theme?.colors.background.index};
`;
interface IProps {
children: JSXElement;
}
export const Container: Component<IProps> = ({ children }) => {
return <Content>{children}</Content>;
};
- Add ThemeProvider of "solid style components", add GlobalStyles and its Container component, create a button using inline style in your App component..
import type { Component } from "solid-js";
import { ThemeProvider } from "solid-styled-components";
import { Container } from "./components/Container";
import { useTheme } from "./contexts/theme";
import { GlobalStyles } from "./styles/theme/global";
const App: Component = () => {
const [{ theme }, { toggleTheme, themeName }] = useTheme();
return (
<ThemeProvider theme={theme()}>
<Container>
<button
style={{
padding: "10px",
background: theme().colors.background.header,
color: "red",
}}
onClick={() =>
themeName() === "dark" ? toggleTheme("light") : toggleTheme("dark")
}
>
{themeName()} - {JSON.stringify(theme(), null, 2)}
</button>
</Container>
<GlobalStyles />
</ThemeProvider>
);
};
export default App;
- Import AppThemeProvider in index.tsx
import { render } from "solid-js/web";
import App from "./App";
import { AppThemeProvider } from "./contexts/theme";
render(
() => (
<AppThemeProvider>
<App />
</AppThemeProvider>
),
document.getElementById("root") as HTMLElement
);
Notice that the style button in lina gets the theme change, but the component Container created by styled from "solid-styled-components" doesn't seem to notice the change of ThemeProvider props.
My Environment
| Dependency | Version |
|---|---|
| Operating System | windows |
| Node.js version | 16.15.1 |
| Typescript version | 4.8.2 |
| Vite version | 3.0.9 |
| Vite Plugin Solid version | 2.3.0 |
| Solidjs version | 1.5.1 |
| Solidjs Styled Components version | 0.28.5 |
Are you willing to resolve this issue by submitting a Pull Request?
- ✖️ Yes, I have the time, and I know how to start.
- ✖️ Yes, I have the time, but I don't know how to start. I would need guidance.
- ✖️ No, I don’t have the time, but I can support (using donations) development.
- ✖️ No, I don’t have the time and I’m okay to wait for the community / maintainers to resolve this issue.
- ✅ I don't know how to solve this bug, I don’t have the time and I’m okay to wait for the community / maintainers to resolve this issue.