UNPKG

flixburst-theme

Version:

A flexible and extensible package for theme management

306 lines (228 loc) 7.43 kB
# flixburst-theme A framework-agnostic theme management system that supports dark/light mode with system preference detection, cross-tab synchronization, and easy integration with any JavaScript framework. ## Features - 🌓 Dark/Light mode support - 🔄 System preference detection - 📱 Cross-tab synchronization - 🎨 Framework-agnostic - 📦 Small bundle size - 🔒 TypeScript support - 🧩 Easy to integrate ## Installation ```bash # Using npm npm install flixburst-theme # Using yarn yarn add flixburst-theme # Using pnpm pnpm add flixburst-theme ``` ## Framework Examples ### React ```tsx // ESM import { useEffect, useState } from 'react'; import { setupThemeManagement, Theme } from 'flixburst-theme'; // CJS // const { useEffect, useState } = require('react'); // const { setupThemeManagement, Theme } = require('flixburst-theme'); export function useTheme() { const [theme, setThemeState] = useState<Theme>('system'); useEffect(() => { const cleanup = setupThemeManagement({ setTheme: setThemeState, initializeTheme: () => { const savedTheme = localStorage.getItem('theme') as Theme; return savedTheme || 'system'; } }); return cleanup; }, []); return { theme, setTheme: setThemeState }; } // Usage in component function App() { const { theme, setTheme } = useTheme(); return ( <div> <button onClick={() => setTheme('dark')}>Dark</button> <button onClick={() => setTheme('light')}>Light</button> <button onClick={() => setTheme('system')}>System</button> </div> ); } ``` ### Vue 3 ```vue <script setup> // ESM import { ref, onMounted, onUnmounted } from 'vue'; import { setupThemeManagement, Theme } from 'flixburst-theme'; // CJS // const { ref, onMounted, onUnmounted } = require('vue'); // const { setupThemeManagement, Theme } = require('flixburst-theme'); const theme = ref<Theme>('system'); onMounted(() => { const cleanup = setupThemeManagement({ setTheme: (newTheme) => theme.value = newTheme, initializeTheme: () => { const savedTheme = localStorage.getItem('theme') as Theme; return savedTheme || 'system'; } }); onUnmounted(cleanup); }); </script> <template> <div> <button @click="theme = 'dark'">Dark</button> <button @click="theme = 'light'">Light</button> <button @click="theme = 'system'">System</button> </div> </template> ``` ### Angular ```typescript // ESM import { Component, OnInit, OnDestroy } from '@angular/core'; import { setupThemeManagement, Theme } from 'flixburst-theme'; // CJS // const { Component, OnInit, OnDestroy } = require('@angular/core'); // const { setupThemeManagement, Theme } = require('flixburst-theme'); @Component({ selector: 'app-theme-toggle', template: ` <button (click)="setTheme('dark')">Dark</button> <button (click)="setTheme('light')">Light</button> <button (click)="setTheme('system')">System</button> ` }) export class ThemeToggleComponent implements OnInit, OnDestroy { theme: Theme = 'system'; private cleanup: () => void; ngOnInit() { this.cleanup = setupThemeManagement({ setTheme: (theme) => this.theme = theme, initializeTheme: () => { const savedTheme = localStorage.getItem('theme') as Theme; return savedTheme || 'system'; } }); } ngOnDestroy() { this.cleanup(); } setTheme(theme: Theme) { this.theme = theme; } } ``` ### SolidJS ```tsx // ESM import { createSignal, onMount, onCleanup } from 'solid-js'; import { setupThemeManagement, Theme } from 'flixburst-theme'; // CJS // const { createSignal, onMount, onCleanup } = require('solid-js'); // const { setupThemeManagement, Theme } = require('flixburst-theme'); export function useTheme() { const [theme, setTheme] = createSignal<Theme>('system'); onMount(() => { const cleanup = setupThemeManagement({ setTheme, initializeTheme: () => { const savedTheme = localStorage.getItem('theme') as Theme; return savedTheme || 'system'; } }); onCleanup(cleanup); }); return { theme, setTheme }; } // Usage in component function App() { const { theme, setTheme } = useTheme(); return ( <div> <button onClick={() => setTheme('dark')}>Dark</button> <button onClick={() => setTheme('light')}>Light</button> <button onClick={() => setTheme('system')}>System</button> </div> ); } ``` ## Custom Event The package uses a custom event `theme-toggle` for theme changes. You can dispatch it manually: ```typescript // ESM import { Theme } from 'flixburst-theme'; // CJS // const { Theme } = require('flixburst-theme'); // Dispatch theme change event window.dispatchEvent(new CustomEvent('theme-toggle', { detail: 'dark' // or 'light' or 'system' })); ``` ## Types ```typescript // ESM import { Theme, SetupThemeManagementParams } from 'flixburst-theme'; // CJS // const { Theme, SetupThemeManagementParams } = require('flixburst-theme'); export type Theme = 'dark' | 'light' | 'system'; export interface SetupThemeManagementParams { setTheme: (theme: Theme) => void; initializeTheme: () => Theme; onThemeChange?: (theme: Theme) => void; onSystemThemeChange?: (isDark: boolean) => void; } // Core Functions export const setupThemeManagement: (params: SetupThemeManagementParams) => () => void; export const getSystemThemePreference: () => boolean; export const shouldUseDarkMode: (theme: Theme) => boolean; export const applyThemeToDOM: (isDark: boolean) => void; export const setTheme: (theme: Theme) => void; export const initializeTheme: () => Theme; export const subscribeToSystemTheme: (callback: (isDark: boolean) => void) => () => void; ``` ## API Reference ### `setupThemeManagement(params: SetupThemeManagementParams)` Sets up theme management with the provided configuration. **Parameters:** - `params`: Configuration object - `setTheme`: Function to update theme state - `initializeTheme`: Function to initialize theme - `onThemeChange`: Optional callback for theme changes - `onSystemThemeChange`: Optional callback for system theme changes **Returns:** - Cleanup function to remove event listeners ### `getSystemThemePreference()` Gets the current system theme preference. **Returns:** - `boolean`: `true` if system prefers dark mode ### `shouldUseDarkMode(theme: Theme)` Determines if dark mode should be active. **Parameters:** - `theme`: Current theme setting **Returns:** - `boolean`: `true` if dark mode should be active ### `applyThemeToDOM(isDark: boolean)` Applies theme to the DOM. **Parameters:** - `isDark`: Whether to apply dark mode ### `setTheme(theme: Theme)` Sets and applies theme. **Parameters:** - `theme`: Theme to set ### `initializeTheme()` Initializes theme from storage or system preference. **Returns:** - `Theme`: Initialized theme ### `subscribeToSystemTheme(callback: (isDark: boolean) => void)` Subscribes to system theme changes. **Parameters:** - `callback`: Function to call on system theme change **Returns:** - Cleanup function to remove event listener ## License MIT