npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@metadiv-studio/theme-context

v0.1.0

Published

A lightweight React context provider for managing light/dark theme switching with localStorage persistence and automatic Tailwind CSS dark mode integration.

Downloads

35

Readme

@metadiv-studio/theme-context

A lightweight React context provider for managing light/dark theme switching with localStorage persistence and automatic Tailwind CSS dark mode integration.

🚀 Installation

npm install @metadiv-studio/theme-context

📝 Description

This package provides a complete theme management solution for React applications. It includes:

  • ThemeProvider: A React context provider that manages theme state
  • useThemeContext: A custom hook to access and control theme state
  • Automatic persistence: Saves theme preference to localStorage
  • Tailwind CSS integration: Automatically applies/removes the dark class to document.documentElement
  • TypeScript support: Full type safety with TypeScript definitions

The package automatically handles theme persistence across browser sessions and provides a clean API for theme switching in your React components.

🛠️ Setup

1. Wrap your app with ThemeProvider

// pages/_app.tsx (Next.js) or App.tsx (Create React App)
import { ThemeProvider } from '@metadiv-studio/theme-context';

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

export default MyApp;

2. Configure Tailwind CSS for dark mode

Make sure your tailwind.config.js is configured for dark mode:

// tailwind.config.js
module.exports = {
  darkMode: 'class', // Enable class-based dark mode
  content: [
    // ... your content paths
    "./node_modules/@metadiv-studio/**/*.{js,ts,jsx,tsx}", // Include this package
  ],
  // ... rest of your config
}

📖 Usage

Basic Theme Toggle

import { useThemeContext } from '@metadiv-studio/theme-context';
import { Sun, Moon } from 'lucide-react';

function ThemeToggle() {
  const { theme, setTheme } = useThemeContext();

  const toggleTheme = () => {
    setTheme(theme === 'light' ? 'dark' : 'light');
  };

  return (
    <button 
      onClick={toggleTheme}
      className="p-2 rounded-full bg-gray-200 dark:bg-gray-800"
    >
      {theme === 'light' ? <Moon className="h-4 w-4" /> : <Sun className="h-4 w-4" />}
    </button>
  );
}

Theme-Aware Component

import { useThemeContext } from '@metadiv-studio/theme-context';

function ThemedCard({ children }) {
  const { theme } = useThemeContext();

  return (
    <div className={`
      p-6 rounded-lg border
      ${theme === 'light' 
        ? 'bg-white border-gray-200 text-gray-900' 
        : 'bg-gray-800 border-gray-700 text-white'
      }
    `}>
      {children}
    </div>
  );
}

Complete Example with Multiple Components

// App.tsx
import { ThemeProvider, useThemeContext } from '@metadiv-studio/theme-context';
import { Sun, Moon } from 'lucide-react';

function App() {
  return (
    <ThemeProvider>
      <div className="min-h-screen bg-white dark:bg-gray-900 transition-colors">
        <Header />
        <MainContent />
      </div>
    </ThemeProvider>
  );
}

function Header() {
  const { theme, setTheme } = useThemeContext();

  return (
    <header className="p-4 border-b border-gray-200 dark:border-gray-700">
      <div className="flex justify-between items-center">
        <h1 className="text-2xl font-bold text-gray-900 dark:text-white">
          My App
        </h1>
        
        <button
          onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}
          className="
            p-2 rounded-lg
            bg-gray-100 hover:bg-gray-200
            dark:bg-gray-800 dark:hover:bg-gray-700
            text-gray-900 dark:text-white
            transition-colors
          "
        >
          {theme === 'light' ? (
            <Moon className="h-5 w-5" />
          ) : (
            <Sun className="h-5 w-5" />
          )}
        </button>
      </div>
    </header>
  );
}

function MainContent() {
  return (
    <main className="p-8">
      <div className="max-w-4xl mx-auto">
        <div className="
          p-6 rounded-lg border
          bg-gray-50 border-gray-200
          dark:bg-gray-800 dark:border-gray-700
        ">
          <h2 className="text-xl font-semibold mb-4 text-gray-900 dark:text-white">
            Theme-Aware Content
          </h2>
          <p className="text-gray-700 dark:text-gray-300">
            This content automatically adapts to the current theme.
          </p>
        </div>
      </div>
    </main>
  );
}

export default App;

Theme Selection Menu

import { useThemeContext, ThemeMode } from '@metadiv-studio/theme-context';

function ThemeSelector() {
  const { theme, setTheme } = useThemeContext();

  const themes: { value: ThemeMode; label: string }[] = [
    { value: 'light', label: 'Light Mode' },
    { value: 'dark', label: 'Dark Mode' },
  ];

  return (
    <div className="space-y-2">
      <label className="block text-sm font-medium text-gray-700 dark:text-gray-300">
        Choose Theme
      </label>
      <select
        value={theme}
        onChange={(e) => setTheme(e.target.value as ThemeMode)}
        className="
          block w-full px-3 py-2 border border-gray-300 rounded-md
          bg-white dark:bg-gray-800
          text-gray-900 dark:text-white
          dark:border-gray-600
          focus:outline-none focus:ring-2 focus:ring-blue-500
        "
      >
        {themes.map(({ value, label }) => (
          <option key={value} value={value}>
            {label}
          </option>
        ))}
      </select>
    </div>
  );
}

🔧 API Reference

ThemeProvider

A React context provider that manages theme state and persistence.

Props:

  • children: React.ReactNode - The child components to wrap

Features:

  • Automatically loads saved theme from localStorage on mount
  • Applies/removes dark class to document.documentElement
  • Defaults to light theme if no saved preference exists

useThemeContext

A custom hook that provides access to the theme context.

Returns:

{
  theme: ThemeMode;           // Current theme: 'light' | 'dark'
  setTheme: (theme: ThemeMode) => void; // Function to change theme
}

Example:

const { theme, setTheme } = useThemeContext();

// Get current theme
console.log(theme); // 'light' or 'dark'

// Change theme
setTheme('dark');

ThemeMode

TypeScript type definition for theme values.

type ThemeMode = 'light' | 'dark';

🎨 Styling Best Practices

Using Tailwind CSS Dark Mode Classes

// Background colors
<div className="bg-white dark:bg-gray-900">

// Text colors  
<p className="text-gray-900 dark:text-white">

// Border colors
<div className="border border-gray-200 dark:border-gray-700">

// Hover states
<button className="hover:bg-gray-100 dark:hover:bg-gray-800">

// Transitions for smooth theme switching
<div className="bg-white dark:bg-gray-900 transition-colors duration-200">

Creating Theme-Aware Custom CSS

/* globals.css */
.themed-component {
  @apply bg-white text-gray-900;
  @apply dark:bg-gray-800 dark:text-white;
  @apply transition-colors duration-200;
}

📚 Dependencies

  • Peer Dependencies:

    • react: ^18
    • react-dom: ^18
  • Internal Dependencies:

    • @metadiv-studio/context: ^0.2.0 - Context creation utilities

🤝 Contributing

This package is part of the MetaDiv Studio UI component library. For contributions and issues, please refer to the main repository.

📄 License

UNLICENSED


Happy theming! 🎨