react-nature-toggle
v1.1.0
Published
Accessible nature-themed light/dark mode toggle for React with framer-motion springs: day landscape, night sky, animated knob. Full TypeScript.
Downloads
252
Maintainers
Readme
react-nature-toggle
A tiny, accessible nature-themed light/dark toggle for React.
Day scene (sky, sun, hills, tree) ↔ night scene (moon, stars). Pass mode and size — the package handles the rest.
Author: Mohsen Khojasteh Nezhad (donmohsen on npm)
Install
npm install react-nature-toggle framer-motionframer-motion is a peer dependency (same springs as the original day/night toggle). Apps that already use it (including Next.js portfolios that lazy-load the toggle after LCP) share one copy — no duplicate motion bundle on the critical path.
Usage
import { useState } from "react";
import { NatureToggle, type NatureToggleMode } from "react-nature-toggle";
import "react-nature-toggle/styles.css";
export function ThemeSwitch() {
const [mode, setMode] = useState<NatureToggleMode>("light");
return (
<NatureToggle
mode={mode}
onModeChange={setMode}
size={28}
/>
);
}With next-themes
"use client";
import { NatureToggle } from "react-nature-toggle";
import "react-nature-toggle/styles.css";
import { useTheme } from "next-themes";
export function ThemeToggle() {
const { resolvedTheme, setTheme } = useTheme();
const mode = resolvedTheme === "dark" ? "dark" : "light";
return (
<NatureToggle
mode={mode}
onModeChange={setTheme}
size={28}
/>
);
}Import the CSS once (layout,
_app, or the component file). Without it, the scenes will not paint correctly.
Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| mode | "light" \| "dark" | — | Controlled mode ("dark" = night, knob right) |
| defaultMode | "light" \| "dark" | "light" | Uncontrolled initial mode |
| onModeChange | (mode) => void | — | Fires with the next mode |
| size | number | 28 | Pill height in px (width scales; clamped 16–96) |
| disabled | boolean | false | Disables interaction |
| className | string | — | Extra class on the root button |
| aria-label | string | auto | Accessible name |
All other native <button> attributes are forwarded (except type / role / children).
Uncontrolled
<NatureToggle
defaultMode="light"
onModeChange={(mode) => console.log(mode)}
size={32}
/>Versioning
Follows SemVer:
- patch (
1.0.x) — bugfixes, no API break - minor (
1.x.0) — new props / features, backward compatible - major (
x.0.0) — breaking API changes
Security
- No
postinstall/preinstallscripts on install - Only
dist/,LICENSE, andREADME.mdare published - Peer dependency on React only — no telemetry, no network calls
- SVG paths are static;
sizeis clamped to a safe range
License
MIT © Mohsen Khojasteh Nezhad
