react-seasonal-themes
v1.1.0
Published
Fully dynamic seasonal design system mapping to unique UI themes.
Readme
✨ Features
- 🌍 Auto-Season Detection: Calculates the current season from the date (hemisphere/region default to
northern/temperate, and can be changed viauseSeason()). - 🎨 CSS Variable Powered: A robust design system built on CSS variables (
--season-primary,--season-gradient, etc.) making overrides a breeze. - 🧩 Premium UI Components: Ships with a suite of beautifully designed, dark-mode ready components (
SeasonCard,SeasonButton,SeasonHeading, etc.). - ⚛️ React First: Built from the ground up for React 18+ with zero boilerplate.
- 🛡️ 100% TypeScript: First-class types for excellent developer experience and autocomplete.
- 🕹️ Manual Overrides: Let users choose their favorite season with our built-in global store (powered by Zustand).
📦 Installation
Install via your favorite package manager:
npm install react-seasonal-themes
# or
yarn add react-seasonal-themes
# or
pnpm add react-seasonal-themes🚀 Quick Start
Wrap your application in the SeasonProvider and import the global CSS styles at the root of your application (e.g., in main.tsx or App.tsx):
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
// 1. Import the provider and the CSS
import { SeasonProvider } from 'react-seasonal-themes';
import 'react-seasonal-themes/style.css';
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
<React.StrictMode>
{/* 2. Wrap your app! */}
<SeasonProvider>
<App />
</SeasonProvider>
</React.StrictMode>
);Using Components
Once the provider is wrapped, you can drop any of our premium components anywhere in your app:
import { SeasonCard, SeasonHeading, SeasonButton, SeasonBadge, SeasonInput, SeasonText } from 'react-seasonal-themes';
function MyDashboard() {
return (
<div style={{ padding: '2rem' }}>
<SeasonCard>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
<SeasonHeading level={2} gradient>
Welcome to the current season!
</SeasonHeading>
<SeasonBadge variant="glass" animate="pulse">Active</SeasonBadge>
</div>
<SeasonText variant="muted">
This card automatically updates its styling based on the time of year.
</SeasonText>
<div style={{ marginTop: '1.5rem', display: 'flex', gap: '1rem', alignItems: 'center' }}>
<SeasonInput placeholder="Search themes..." glass />
<SeasonButton variant="primary" animate="float">
Explore Themes
</SeasonButton>
</div>
</SeasonCard>
</div>
);
}🪝 Hooks (Manual Control)
Want to let users change the season manually? Use the useSeason hook!
import { useSeason } from 'react-seasonal-themes';
function SeasonSwitcher() {
const { season, isOverridden, setSeason, resetSeason, setHemisphere, setRegion } = useSeason();
return (
<div>
<p>Current Theme: {season}</p>
<p>Overridden: {String(isOverridden)}</p>
<button onClick={() => setSeason('winter')}>Force Winter</button>
<button onClick={() => setSeason('summer')}>Force Summer</button>
<button onClick={resetSeason}>Auto-Detect</button>
<div style={{ marginTop: 12 }}>
<button onClick={() => setHemisphere('southern')}>Southern Hemisphere</button>
<button onClick={() => setRegion('tropical')}>Tropical Region</button>
</div>
</div>
);
}🎨 Theming & CSS Variables
The magic happens via native CSS variables defined in style.css. The active theme is selected by data-season on document.documentElement.
.my-custom-box {
background: var(--season-bg);
border: 1px solid var(--season-primary-light);
border-radius: var(--season-border-radius);
color: var(--season-text);
box-shadow: var(--season-shadow);
transition: all 0.3s ease;
}
.my-text {
background: var(--season-gradient);
-webkit-background-clip: text;
color: transparent;
}Available Components
SeasonProviderSeasonButtonSeasonCardSeasonInputSeasonBadgeSeasonTextSeasonHeadingSeasonBackgroundSeasonDividerSeasonAccentBar
🤝 Contributing
Contributions, issues, and feature requests are welcome! Feel free to check the issues page.
📄 License
This project is MIT licensed.
