javascriptreactjsnext.jsbaseweb

can't change background colour in base web


i am using next js in my project and when i create a button to change colour they only change the base web components colour not background colour.

_app.tsx

import '../styles/globals.css';
import type { AppProps } from 'next/app';
import { Provider as StyletronProvider } from 'styletron-react';
import { LightTheme, BaseProvider, ThemeProvider, DarkTheme } from 'baseui';
import { styletron } from '../helpers/styletron';
import { useState } from 'react';

const THEME = {
    light: 'light',
    dark: 'dark',
};

function MyApp({ Component, pageProps }: AppProps) {
    const [theme, setTheme] = useState(THEME.light);
    return (
        <StyletronProvider value={styletron}>
            <BaseProvider
                theme={theme === THEME.light ? LightTheme : DarkTheme}
            >
                <Component
                    {...pageProps}
                    THEMES={THEME}
                    theme={theme}
                    settheme={setTheme}
                />
            </BaseProvider>
        </StyletronProvider>
    );
}

export default MyApp;

index.tsx

import type { NextPage } from 'next';
import Navbar from '../components/Navbar';

interface props {
    THEMES: {
        light: string;
        dark: string;
    };
    settheme: any;
    theme: any;
}

const Home: NextPage<props> = ({ THEMES, settheme, theme }) => {
    return (
        <>
            <Navbar />
            <button
                onClick={() =>
                    settheme(theme === THEMES.dark ? THEMES.light : THEMES.dark)
                }
            >
                change
            </button>
        </>
    );
};

export default Home;

and when i click on button it not change the background colour to black

poc

like you see above it not change the background


Solution

  • don't known it's the best way of doing it but it's work

    what i do is add a class in html tag called theme which indicate the current theme which user select and store that theme name in localstorage and using css to add background colour according to html class name

    if anyone has better solution pls don't hesitate to share.

    _app.tsx

    import '../styles/globals.css';
    import type { AppProps } from 'next/app';
    import { Provider as StyletronProvider } from 'styletron-react';
    import { LightTheme, BaseProvider, DarkTheme } from 'baseui';
    import { styletron } from '../helpers/styletron';
    import { useEffect, useState } from 'react';
    
    const THEME = {
        light: 'light',
        dark: 'dark',
    };
    
    function MyApp({ Component, pageProps }: AppProps) {
        const [theme, setTheme] = useState<string>('');
        useEffect(() => {
            if (typeof window !== 'undefined') {
                !localStorage.getItem('theme')
                    ? localStorage.setItem('theme', 'dark')
                    : '';
                let user_themes = localStorage.getItem('theme');
                document
                    .getElementById('theme')
                    ?.classList?.add(user_themes || theme);
                setTheme(user_themes || theme);
            }
        }, []);
        useEffect(() => {
            if (theme) {
                document
                    .getElementById('theme')
                    ?.classList?.remove(
                        theme === THEME.dark ? THEME.light : THEME.dark
                    );
                document.getElementById('theme')?.classList?.add(theme);
                localStorage.setItem('theme', theme);
            }
        }, [theme]);
        return (
            <StyletronProvider value={styletron}>
                <BaseProvider
                    theme={theme === THEME.light ? LightTheme : DarkTheme}
                >
                    <Component
                        {...pageProps}
                        THEMES={THEME}
                        theme={theme}
                        settheme={setTheme}
                    />
                </BaseProvider>
            </StyletronProvider>
        );
    }
    
    export default MyApp;
    

    _document.tsx

    import Document, { Html, Head, Main, NextScript } from 'next/document';
    
    export default class CustomDocument extends Document {
        render() {
            return (
                <Html id='theme'>
                    <Head />
                    <body>
                        <Main />
                        <NextScript />
                    </body>
                </Html>
            );
        }
    }
    

    index.tsx

    import type { NextPage } from 'next';
    import Navbar from '../components/Navbar';
    
    interface props {
        THEMES: {
            light: string;
            dark: string;
        };
        settheme: any;
        theme: any;
    }
    
    const Home: NextPage<props> = ({ THEMES, settheme, theme }) => {
        return (
            <>
                <Navbar />
                <button
                    onClick={() =>
                        settheme(theme === THEMES.dark ? THEMES.light : THEMES.dark)
                    }
                >
                    change
                </button>
            </>
        );
    };
    
    export default Home;
    

    globals.css

    body {
        padding: 0;
        margin: 0;
    }
    
    html.dark {
        background: rgba(12, 12, 12);
    }
    
    html.light {
        background: rgb(252, 252, 252);
    }