Coder Social home page Coder Social logo

alfiejones / next-use-theme Goto Github PK

View Code? Open in Web Editor NEW
5.0 1.0 0.0 2.2 MB

A NextJS wrapper component which provides a useTheme hook as well as dealing with theme changes and the dreaded flash of incorrect theme

Home Page: https://next-theme.firstbyte.app/

License: MIT License

TypeScript 80.78% CSS 19.22%

next-use-theme's Introduction

NPM version

Extremely lightweight, Highly customizable

A NextJS wrapper component which provides a useTheme hook as well as dealing with theme changes and the dreaded flash of incorrect theme

Table of Contents
  1. Getting Started
  2. API
  3. Typescript
  4. About The Project
  5. Contributing
  6. License

Getting Started

Prerequisites

Install the package as a dependency

npm install next-use-theme

or with yarn

yarn add next-use-theme

Usage

We need to wrap the component tree with our component and so it's recommend we do this in the _app file. If you haven't already got one, create a custom _app and wrap the Component with our ThemeProvider.

Since both the ThemeProvider and ThemeScript require the same props to function properly, it's recommended to store these in a global variable.

This example uses a config stored in _app but it can also be placed into its own file.

// Example pages/_app.js
import { ThemeProvider } from "next-use-theme";

export const config = {
  themes: ["dark", "light", "tech"]
}

function MyApp({ Component, pageProps }) {
  return (
    <ThemeProvider {...config}>
      <Component {...pageProps} />
    </ThemeProvider>
  );
}

export default MyApp;

To avoid the FOIT (Flash of Incorrect Theme) we need to inject a script into the Head to run before React/Nextjs. We do this with a custom _document

// Example pages/_document.js
import { Html, Head, Main, NextScript } from 'next/document'
import { ThemeScript } from 'next-use-theme'
import { config } from './_app';

export default function Document() {
  return (
    <Html>
      <Head >
          <ThemeScript {...config} />
      </Head>
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  )
}

Then we you can use our hook useTheme() to access and change the current theme

// Example hook usage
import { useTheme } from "next-use-theme";

function ThemeButtons() {
  const { setTheme, toggle, theme } = useTheme();
  return (
    <>
      <h1>Current theme: {theme}</h1>
      <button type="button" onClick={toggle}>
        Toggle theme
      </button>
      <button type="button" onClick={() => setTheme("light")}>
        Light theme
      </button>
      <button type="button" onClick={() => setTheme("dark")}>
        Dark theme
      </button>
    </>
  );
}

API

ThemeConfig

Themes are the props for both the ThemeProvider and ThemeScript.

These are all optional

themes: string[]
List of all available theme names, defaults to the two props [lightTheme, darkTheme], eg ["lightTheme", "darkTheme"]
Default: [lightTheme, darkTheme, "system"]
defaultTheme: string
Default theme, this must also exist in themes
Default: "system"
lightTheme: string
Light theme name
Default: "light"
darkTheme: string
Dark theme name
Default: "dark"
toggleThemes: string[]
Themes for the toggle to loop through
Default: [lightTheme, darkTheme]
attribute: `data-${string}` | "class"
The HTML attribute to be set
Default: "class"
mediaQuery: boolean
Use media query to toggle the theme between light and dark. If true and no storage handlers find a theme, next-theme falls back onto the media query
Default: true
colorScheme: boolean
Should we set the meta tag colorScheme, if default theme is dark we set it to dark light otherwise light dark
Default: true
onChange: (theme: string, resolvedTheme: string) => void
Handle the theme change yourself. Setting this disables next-theme from setting the attribute
Default: undefined
storageHandlers: Handler[]
The array of storage handlers. Used to customize where we get and store our theme information
Default: [localStorage()]
respectHandlerOrder: boolean
If true, when a handler changes we only use the value of the first handler to yield a valid theme. If false, we accept the new value if valid
Default: false

UseTheme

Returns for the useTheme Hook

theme: string
The current theme set
setTheme: (theme: string) => void
Change the current theme, only themes listed to the provider are accepted
toggle: () => void;
Toggle the theme, this goes through the toggle themes listed to the provider
resolvedTheme: string
Same as theme unless system theme is set, then shows 'system' while theme holds dark/light (set by provider)

TypeScript

This project is written in TypeScript and therefore fully supports it.

About The Project

I built this project to make theme handling much easier and hassle free. It's amazing how hard it is to handle theme changes so I hope this project makes your life easier

Features:

  • No horrible flash of incorrect theme (FOIT)
  • Easy to use hook and wrapper
  • Highly customizable
  • Lightweight

Animated toggle

I also maintain a library of animated toggles

Contributing

Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are greatly appreciated.

License

Distributed under the MIT License. See LICENSE for more information.

next-use-theme's People

Contributors

alfiejones avatar

Stargazers

Koki Inoue avatar  avatar Liam Ward avatar Matt Gaynor avatar James Barber avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.