@usefy/use-toggle
v0.2.5
Published
A React hook for boolean state management
Maintainers
Readme
Overview
@usefy/use-toggle is a powerful React hook for managing boolean state with helpful utilities. It provides toggle, setTrue, setFalse, and setValue functions, making it perfect for modals, dropdowns, accordions, and any UI component with on/off states.
Part of the @usefy ecosystem — a collection of production-ready React hooks designed for modern applications.
Why use-toggle?
- Zero Dependencies — Pure React implementation with no external dependencies
- TypeScript First — Full type safety with exported interfaces
- Stable References — All functions are memoized with
useCallbackfor optimal performance - SSR Compatible — Works seamlessly with Next.js, Remix, and other SSR frameworks
- Lightweight — Minimal bundle footprint (~300B minified + gzipped)
- Well Tested — Comprehensive test coverage with Vitest
Installation
# npm
npm install @usefy/use-toggle
# yarn
yarn add @usefy/use-toggle
# pnpm
pnpm add @usefy/use-togglePeer Dependencies
This package requires React 18 or 19:
{
"peerDependencies": {
"react": "^18.0.0 || ^19.0.0"
}
}Quick Start
import { useToggle } from "@usefy/use-toggle";
function Modal() {
const { value: isOpen, toggle, setTrue, setFalse } = useToggle(false);
return (
<>
<button onClick={setTrue}>Open Modal</button>
{isOpen && (
<div className="modal">
<h2>Modal Content</h2>
<button onClick={setFalse}>Close</button>
</div>
)}
</>
);
}API Reference
useToggle(initialValue?)
A hook that manages boolean state with toggle, setTrue, setFalse, and setValue functions.
Parameters
| Parameter | Type | Default | Description |
| -------------- | --------- | ------- | ------------------------- |
| initialValue | boolean | false | The initial boolean value |
Returns UseToggleReturn
| Property | Type | Description |
| ---------- | -------------------------- | ------------------------------------ |
| value | boolean | The current boolean state |
| toggle | () => void | Toggles the value (true ↔ false) |
| setTrue | () => void | Sets the value to true |
| setFalse | () => void | Sets the value to false |
| setValue | (value: boolean) => void | Sets the value to a specific boolean |
Examples
Modal/Dialog
import { useToggle } from "@usefy/use-toggle";
function ConfirmDialog() {
const { value: isOpen, setTrue: open, setFalse: close } = useToggle(false);
return (
<>
<button onClick={open}>Delete Item</button>
{isOpen && (
<div className="dialog-overlay">
<div className="dialog">
<h3>Confirm Deletion</h3>
<p>Are you sure you want to delete this item?</p>
<div className="dialog-actions">
<button onClick={close}>Cancel</button>
<button
onClick={() => {
deleteItem();
close();
}}
>
Delete
</button>
</div>
</div>
</div>
)}
</>
);
}Accordion
import { useToggle } from "@usefy/use-toggle";
function AccordionItem({ title, content }: AccordionItemProps) {
const { value: isExpanded, toggle } = useToggle(false);
return (
<div className="accordion-item">
<button
className="accordion-header"
onClick={toggle}
aria-expanded={isExpanded}
>
{title}
<span className={`icon ${isExpanded ? "rotate" : ""}`}>▼</span>
</button>
{isExpanded && <div className="accordion-content">{content}</div>}
</div>
);
}Dark Mode Toggle
import { useToggle } from "@usefy/use-toggle";
function ThemeToggle() {
const { value: isDark, toggle, setValue } = useToggle(false);
// Sync with system preference
useEffect(() => {
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
setValue(mediaQuery.matches);
}, [setValue]);
return (
<button
onClick={toggle}
aria-label={`Switch to ${isDark ? "light" : "dark"} mode`}
>
{isDark ? "🌙" : "☀️"}
</button>
);
}Dropdown Menu
import { useToggle } from "@usefy/use-toggle";
function Dropdown({ items }: DropdownProps) {
const { value: isOpen, toggle, setFalse: close } = useToggle(false);
return (
<div className="dropdown">
<button onClick={toggle} aria-haspopup="true" aria-expanded={isOpen}>
Menu
</button>
{isOpen && (
<ul className="dropdown-menu">
{items.map((item) => (
<li key={item.id}>
<button
onClick={() => {
item.onClick();
close();
}}
>
{item.label}
</button>
</li>
))}
</ul>
)}
</div>
);
}Controlled from Props
import { useToggle } from "@usefy/use-toggle";
function ControlledSwitch({ defaultChecked, onChange }: SwitchProps) {
const { value, toggle } = useToggle(defaultChecked);
const handleToggle = () => {
toggle();
onChange?.(!value);
};
return (
<button
role="switch"
aria-checked={value}
onClick={handleToggle}
className={`switch ${value ? "on" : "off"}`}
>
<span className="switch-thumb" />
</button>
);
}TypeScript
This hook is written in TypeScript and exports the UseToggleReturn interface.
import { useToggle, type UseToggleReturn } from "@usefy/use-toggle";
// Return type is fully typed
const { value, toggle, setTrue, setFalse, setValue }: UseToggleReturn =
useToggle(false);
// value: boolean
// toggle: () => void
// setTrue: () => void
// setFalse: () => void
// setValue: (value: boolean) => voidPerformance
All functions returned by the hook are memoized using useCallback, ensuring stable references across re-renders. This makes them safe to use as dependencies in other hooks or as props to child components.
const { toggle, setTrue, setFalse, setValue } = useToggle(false);
// These references remain stable across renders
useEffect(() => {
// Safe to use as dependencies
}, [toggle, setTrue, setFalse, setValue]);Testing
This package maintains comprehensive test coverage to ensure reliability and stability.
Test Coverage
📊 View Detailed Coverage Report (GitHub Pages)
Test Categories
- Default value initialization (false)
- Custom initial value (true/false)
- Return all required functions
- Toggle from false to true
- Toggle from true to false
- Multiple toggles
- Rapid successive toggles
- Set value from opposite state
- Maintain value when already set
- Multiple consecutive calls
- After toggle operations
- Stable toggle reference across renders
- Stable setTrue reference across renders
- Stable setFalse reference across renders
- Stable setValue reference across renders
- All references stable after multiple operations
License
MIT © mirunamu
This package is part of the usefy monorepo.
