https://github.com/phucbm/data-toggle
Toggle class in elements via [data-toggle="class-name"]
https://github.com/phucbm/data-toggle
Last synced: 4 months ago
JSON representation
Toggle class in elements via [data-toggle="class-name"]
- Host: GitHub
- URL: https://github.com/phucbm/data-toggle
- Owner: phucbm
- License: mit
- Created: 2025-07-01T10:13:22.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2026-04-05T15:13:10.000Z (4 months ago)
- Last Synced: 2026-04-05T15:25:11.725Z (4 months ago)
- Language: TypeScript
- Size: 221 KB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE
- Codeowners: .github/CODEOWNERS
Awesome Lists containing this project
README
# @phucbm/data-toggle
A lightweight, flexible TypeScript utility for toggling CSS classes via data attributes. Perfect for building interactive UI components without framework dependencies.
[](https://www.npmjs.com/package/@phucbm/data-toggle)
[](https://www.npmjs.com/package/@phucbm/data-toggle)
[](https://www.npmjs.com/package/@phucbm/data-toggle)
[](https://github.com/phucbm/data-toggle/)
[](https://github.com/phucbm/data-toggle/blob/main/LICENSE)
## Features
✨ **Zero dependencies** - fully self-contained
🎯 **Framework agnostic** - works with any JavaScript framework or vanilla JS
🔧 **Flexible targeting** - toggle classes on any element via selectors
📱 **Smart defaults** - auto-prevents default for links and buttons
🎪 **Event-driven** - dispatches custom events for easy integration
⚡ **Debounced clicks** - built-in debouncing support
🔄 **Multiple instances** - create separate instances with different configurations
🛡️ **TypeScript** - fully typed for better DX
## Installation
```bash
npm i @phucbm/data-toggle
```
```bash
pnpm add @phucbm/data-toggle
```
## Quick Start
### HTML
```html
Toggle Dark Mode
Toggle Dark Mode + Sidebar
Toggle Sidebar
Menu
Modal
```
### JavaScript
```typescript
import { createDataToggle } from '@phucbm/data-toggle';
// Initialize once - tracks all [data-toggle] elements
const toggle = createDataToggle();
// That's it! All buttons with data-toggle now work
```
## Advanced Usage
### Custom Configuration
```typescript
const toggle = createDataToggle({
// Use custom data attributes
toggleAttribute: 'data-my-toggle',
elementAttribute: 'data-my-target',
// Change default target (instead of )
defaultTarget: document.body,
// Control click behavior
preventDefault: true, // or false, or 'auto' (default)
// Add debouncing
debounceDelay: 100,
// Enable debug logging
debug: true
});
```
### Programmatic Control
```typescript
// Toggle classes programmatically
toggle.toggle('dark-mode'); // Toggle on default target
toggle.toggle('sidebar-open', '.sidebar'); // Toggle on specific element
toggle.toggle('dark-mode,nav-hidden'); // Toggle multiple classes at once
// Check if classes are active
if (toggle.isActive('dark-mode')) {
console.log('Dark mode is ON');
}
// Check specific elements
if (toggle.isActive('sidebar-open', '.sidebar')) {
console.log('Sidebar is open');
}
// isActive returns true only if ALL specified classes are active
if (toggle.isActive('dark-mode,nav-hidden')) {
console.log('Both classes are active');
}
// Refresh after DOM changes
document.body.innerHTML += 'New';
toggle.refresh(); // Now the new button works
// Clean up
toggle.destroy(); // Removes all event listeners
```
### Event Listening
```typescript
// Listen for toggle events
document.addEventListener('datatoggle', (event) => {
const { classNames, target, trigger, active } = event.detail;
console.log(`Classes "${classNames.join(', ')}" were ${active ? 'added' : 'removed'}`);
console.log('Target element:', target);
console.log('Trigger element:', trigger);
// Example: Save theme preference
if (classNames.includes('dark-mode')) {
localStorage.setItem('theme', active ? 'dark' : 'light');
}
});
```
## Examples
### Dark Mode Toggle
```html
🌙 Toggle Dark Mode
```
```css
.dark-mode {
background: #1a1a1a;
color: #ffffff;
}
```
### Mobile Menu
```html
☰ Menu
```
```css
.mobile-menu {
transform: translateX(-100%);
transition: transform 0.3s ease;
}
.mobile-menu.menu-open {
transform: translateX(0);
}
```
### Modal Dialog
```html
Open Modal
```
### Sidebar with Body Scroll Lock
```typescript
const toggle = createDataToggle();
document.addEventListener('datatoggle', (e) => {
if (e.detail.classNames.includes('sidebar-open')) {
// Lock body scroll when sidebar opens
document.body.style.overflow = e.detail.active ? 'hidden' : '';
}
});
```
## API Reference
### `createDataToggle(config?: DataToggleConfig): DataToggleInstance`
Creates a new data toggle instance.
**Configuration Options:**
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `selector` | `string` | `'[data-toggle]'` | CSS selector for toggle elements |
| `toggleAttribute` | `string` | `'data-toggle'` | Attribute containing the class name(s), comma-separated |
| `elementAttribute` | `string` | `'data-toggle-element'` | Attribute containing target selector |
| `defaultTarget` | `Element` | `document.documentElement` | Default element to toggle classes on |
| `defaultElementSelector` | `string` | `''` | Fallback selector for targets |
| `preventDefault` | `boolean \| 'auto'` | `'auto'` | Prevent default click behavior |
| `debug` | `boolean` | `false` | Enable debug logging |
| `debounceDelay` | `number` | `0` | Debounce delay in milliseconds |
**Instance Methods:**
| Method | Description |
|--------|-------------|
| `destroy()` | Remove all event listeners for this instance |
| `toggle(className, elementSelector?)` | Programmatically toggle a class |
| `isActive(className, elementSelector?)` | Check if a class is currently active |
| `refresh()` | Re-scan DOM for new toggle elements |
### Custom Events
The library dispatches `datatoggle` events with the following detail:
```typescript
{
classNames: string[]; // Array of toggled class names
target: Element; // Element that received the class
trigger: Element; // Button/element that was clicked (null for programmatic)
active: boolean; // Whether classes were added (true) or removed (false)
}
```
## Browser Support
Works in all modern browsers that support:
- ES6+ features
- `classList` API
- `CustomEvent`
- `WeakMap`
## Use Cases
- 🌙 **Dark/light mode toggles**
- 📱 **Mobile navigation menus**
- 🗂️ **Sidebar panels**
- 🪟 **Modal dialogs**
- 📖 **Accordion/collapsible content**
- 🎛️ **Settings panels**
- 🔍 **Search overlays**
- 🎨 **Theme switchers**
## Development
```bash
# Install dependencies
pnpm install
# Run tests
pnpm test
# Build the package
pnpm run build
# Run tests in watch mode
pnpm run test:watch
```
## License
MIT © [phucbm](https://github.com/phucbm)