How to use styled-components theme in Gatsby 2.0 - reactjs

so as the title says I'm curious what is the best practise of adding a styled-components theme to Gatsby website? I've been searching through the internet without finding a definite answer but from what I've gathered I probably should do it by creating a layout in src/layouts/index.tsx that wraps all the pages with the ThemeProvider:
import * as React from 'react'
import { ThemeProvider } from 'styled-components'
import { defaultTheme } from '../theme/defaultTheme'
export const DefaultLayout = ({ children }) => (
<ThemeProvider theme={defaultTheme}>
{ children }
</ThemeProvider>
)
And then I'm able to use theme freely in my styled components? Which doesn't work and I'm getting a bit frustrated with this.

Ok well the solution was simple. Since I was following the old examples done with v1 I guess I should have known that the layouts are not automatically added in v2. Sigh so that layout works but I just have to add it manually:
import { DefaultLayout } from '../layouts/DefaultLayout'
...
<DefaultLayout>
<div>
<h1>Front page</h1>
<Button>I am a button</Button>
</div>
</DefaultLayout>
Hmmph frustrating bug but maybe that was on me.

Related

Why is my custom theme only partially applying (antd)?

I am using Ant Design in a React project of mine, and I am attempting to make use of their custom theming available in version 5 (5.1.2 installed) according to documentation here. However, the custom theme appears to only apply to certain components while skipping others altogether. In the below example, the darker background color is applied to the Content and Footer components while the Header and Sider components are left with the default color, and the Header and Footer components have updated foreground colors, but the Sider and Content components do not. What am I missing to make this theme apply in full to each of these components?
Example:
src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import { ConfigProvider } from 'antd';
import theme from './theme';
import reducers from './reducers';
import App from './components/App';
const store = createStore(reducers)
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Provider store={store}>
<ConfigProvider theme={theme}>
<React.StrictMode>
<App />
</React.StrictMode>
</ConfigProvider>
</Provider>
);
src/theme.js
import { theme } from 'antd';
const custom_theme = {
algorithm: theme.darkAlgorithm,
token: {
colorPrimary: '#e02820',
borderRadius: 5,
wireframe: false
},
}
export default custom_theme;
src/components/App.js
import React from 'react';
import { Layout } from 'antd';
const { Header, Footer, Sider, Content } = Layout;
class App extends React.Component {
render() {
return (
<Layout>
<Header>header</Header>
<Layout>
<Sider>sider</Sider>
<Content>content</Content>
</Layout>
<Footer>footer</Footer>
</Layout>
);
}
}
export default App;
Result:
I have been playing around with AntD custom theme as well and have found that not every attribute can be updated. The main changes allowed are colorPrimary and according to the documentation based on this color their algorithm chooses the rest of the color pallet that matches.
From documentation - "Brand color is one of the most direct visual elements to reflect the characteristics and communication of the product. After you have selected the brand color, we will automatically generate a complete color palette and assign it effective design semantics."
That being said you can try to be even more specific. By that I mean you can specify the style for each separate component.
<ConfigProvider
theme={{
components: {
Header: {
colorPrimary: '#00b96b',
},
Footer: {
colorPrimary: '#fff',
},
},
}}
>
Just change and add your desired styles to each component. If it still does not change, then that is the color AntD will let you have based for each component based on your choice of primary color.
Another option would be to use styled-components library to further provide the styles to AntD components that are not possible using Ants Config API.
If this provides the valid solution would you please click the green arrow on my response to inform others of the solution.

Mui theme not applying if within a wrapper component

With React (typescript) and MUI (5.4.2), I'm trying to put everything regarding styles within a single file, wrapping everything in my App.tsx.
Issue: The custom MUI theme does not apply to the rest of my app (fallback to default MUI theme)
The whole thing worked fine when the ThemeProvider component was placed directly within the App.tsx file, but broke as soon as I placed it elsewhere. I need to keep a separated component, for I'll add Elastic UI on top of MUI later on.
My App.tsx file:
function App() {
<UiProvider>
// ...whole app
</UiProvider>
}
The UiProvider component is a simple wrapper component as it follows:
import {ThemeProvider} from "#mui/styles";
import {CustomTheme} from "../../themes/CustomTheme";
import {createTheme, Theme} from "#mui/material/styles";
const UiProvider = (props: any) => {
return (
<ThemeProvider theme={CustomTheme}>
{props.children}
</ThemeProvider>
)
}
export default UiProvider
Because #mui/styles is the legacy styling solution for MUI, if this is for v5, perhaps the import for ThemeProvider should be:
import { ThemeProvider } from '#mui/material/styles';

How to access MUI 5 theme variables in deep functional component?

The MUI 5 docs on Theming have a section on "Accessing the theme in a component". However, it's really just one sentence that links to the legacy style docs.
Here's the example they give in those legacy docs:
import { useTheme } from '#mui/styles';
function DeepChild() {
const theme = useTheme();
return <span>{`spacing ${theme.spacing}`}</span>;
}
Which is pretty much exactly what I want to do — I want to be able to access the theme color palette down in some deep functional component. However, my component complains
Module not found: Error: Can't resolve '#mui/styles' in...
Digging a little further, it seems they're rather strongly trying to discourage people from using this legacy Styles technique, and the MUI 5 way to do this is with "system design tokens", which I guess should Just Work. But, they're not.
I have my whole app wrapped in ThemeProvider:
import React from 'react';
import { CssBaseline } from '#mui/material';
import { ThemeProvider } from '#mui/material/styles';
import theme from './theme';
import Foo from './foo';
const App = () => {
return (
<Fragment>
<ThemeProvider theme={theme}>
<CssBaseline enableColorScheme />
<Foo />
</ThemeProvider>
</Fragment>
);
};
export default App;
And then in foo.js:
import React from 'react';
import { Box } from '#mui/material';
export const Foo = () => {
return (
<Box
sx={{
background: 'repeating-linear-gradient(-45deg, '
+ ' theme.palette.error.light, theme.palette.error.light 25px,'
+ ' theme.palette.error.dark 25px, theme.palette.error.dark 50px'
+ ')',
}}
>
<span>Test</span>
</Box>
);
};
I initially started with just error.light and error.dark. When that didn't work, I expanded it all to palette.error.light, etc..., and then ultimately to theme.palette.error.light, etc....
It seems no matter what I try, it's not accessing those theme variables, and is instead just passing through the text.
So, back to the question: how am I supposed to access MUI 5 theme variables in nested functional components?
Replace
import { useTheme } from '#mui/styles';
with
import { useTheme } from '#mui/material/styles';
#mui/styles is used for legacy, you can add it using yarn add or npm install, but first give a shot to what I mentioned above.

Use antd for React together with Storybook v5

Now, I am stuck for several hours trying to make Storybook work with antd in my new React application (created with create-react-app), without success.
Whatever I do, Storybook does not take the styling of antd.
For example, I created a menu item with antd:
menuNav.tsx:
import React from "react";
import {Menu} from 'antd';
import "antd/dist/antd.less";
const MenuNav = () => {
return (
<Menu mode="horizontal">
<Menu.Item key="menu1">
This is my menu title
</Menu.Item>
</Menu>
)
}
export default MenuNav;
But the result looks like this, no styling at all, but a list:
And as you can see here, it understands that the menu is created by the UI library, but there is no antd styling applied:
This is the story file of MenuNav, 3-Menu.stories.js:
import React from "react";
import MenuNav from '../components/MenuNav';
export default {
title: "MenuNav",
component: MenuNav,
};
export const Text = () => <MenuNav></MenuNav>
I already tried to add a config.js inside ./storybook as suggested here, with no success. Furthermore, I tried adding a webpack.config.js in the same directory as recommended here, same result.
What am I doing wrong?
try adding #import '~antd/dist/antd.css'; to your applications main file, let say index.css which for example is placed in src folder and then add import '../src/index.css'; to .storybook/preview.js
`

How to change theme dinamically in react application

I'm trying to change the theme of my react application from light to dark (and viceversa) using a button or a switch button (I will decide it later). The fact is: I'm importing the themes' .css directly from bootswatch (I'm currently using "Minty" as the light theme and I want to use "Darkly" as the dark theme (https://bootswatch.com/)). For now I only found that there is the ThemeProvider component but it needs the theme as a .js file in which you must export what you want (and I can't do it since I only have the .css). I also found a ThemeSwitcher on github (https://github.com/raythree/react-bootstrap-theme-switcher) but it seems it's using bootstrap v3 and I actually need v4. There is also a thread on Reddit that suggests to import them in the public folder and change them (https://www.reddit.com/r/reactjs/comments/9lzm8g/react_switching_themes_css/) but I don't think it's a good practice. Can anybody help me?
edit: I tried the reddit solution: now it's changing the theme but for an instant I can definitely see some pure html things that I don't like at all.
This is my code
import React, { useState } from "react";
import ReactDOM from "react-dom";
import Tabs from "./Tabs";
import "react-toastify/dist/ReactToastify.min.css";
import { Helmet } from "react-helmet"
export const Application = () =>{
const [theme, setTheme] = useState(true)
const changeThemeHandler = (event) => {
event.preventDefault();
setTheme(!theme)
}
return(
<>
<button onClick={(event) => changeThemeHandler(event)}>Change Theme</button>
<Helmet>
<link rel="stylesheet" href={`${process.env.PUBLIC_URL}/${theme ? 'lightbootstrap.min.css' : 'darkbootstrap.min.css'}`} />
</Helmet>
<Tabs />
</>
)
}
ReactDOM.render(<Application />, document.getElementById("root"));
How can I adjust it in order to have a smooth transition from light to dark theme and viceversa?

Resources