# @gmana/react-hooks

[![npm version](https://badge.fury.io/js/@gmana%2Freact-hooks.svg)](https://badge.fury.io/js/@gmana%2Freact-hooks)
[![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/)
[![MIT License](https://img.shields.io/badge/license-MIT-green.svg)](https://opensource.org/licenses/MIT)

A comprehensive collection of production-ready React hooks for modern applications. Built with TypeScript and fully tested.

## ✨ Features

- 🚀 **47 Production-Ready Hooks** - Covering state management, UI interactions, network requests, and more
- 📦 **TypeScript Support** - Full type safety with comprehensive TypeScript definitions
- 🧪 **Thoroughly Tested** - Complete test coverage with Vitest
- 📱 **Mobile-First** - Responsive design helpers and mobile-optimized hooks
- 🎯 **Tree-Shakable** - Import only what you need
- 🔄 **Server-Side Rendering** - SSR compatible with Next.js and other frameworks
- 📖 **Well Documented** - Comprehensive examples and API documentation

## 📦 Installation

```bash
# npm
npm install @gmana/react-hooks

# yarn
yarn add @gmana/react-hooks

# pnpm
pnpm add @gmana/react-hooks

# bun
bun add @gmana/react-hooks
```

## 🚀 Quick Start

```tsx
import React from "react"
import { useBoolean, useCounter, useFetch } from "@gmana/react-hooks"

function App() {
  const { value: isVisible, toggle } = useBoolean(false)
  const { count, increment, decrement } = useCounter(0)
  const { data, error } = useFetch<{ title: string }>("https://api.example.com/data")

  if (error) return <div>Error loading data</div>
  if (!data) return <div>Loading...</div>

  return (
    <div>
      <h1>{data.title}</h1>
      <p>Count: {count}</p>
      <button onClick={increment}>+</button>
      <button onClick={decrement}>-</button>

      <button onClick={toggle}>{isVisible ? "Hide" : "Show"} Content</button>
      {isVisible && <div>Toggle content</div>}
    </div>
  )
}
```

## 📚 Available Hooks

### 🔄 State Management

- **`useBoolean`** - Manage boolean state with helper functions
- **`useCounter`** - Counter with increment, decrement, and reset
- **`useToggle`** - Toggle between values with customizable states
- **`useToggleState`** - Advanced toggle state management
- **`useArray`** - Array manipulation with push, filter, remove operations
- **`useMap`** - Map data structure with CRUD operations
- **`useStep`** - Multi-step form/wizard state management

### 🎨 UI & Layout

- **`useElementSize`** - Track element dimensions
- **`useWindowSize`** - Monitor window dimensions
- **`useDimensions`** - Get container dimensions
- **`useHover`** - Detect hover state on elements
- **`useInView`** - Check if element is in viewport
- **`useIntersectionObserver`** - Advanced intersection observer
- **`useOnClickOutside`** - Detect clicks outside element
- **`useLockedBody`** - Lock/unlock body scroll
- **`useSidebar`** - Sidebar state management

### 🌐 Network & Data

- **`useFetch`** - HTTP requests with caching and error handling
- **`useNetworkInformation`** - Network connection details
- **`useOfflineDetector`** - Online/offline status detection

### 💾 Storage & Persistence

- **`useLocalStorage`** - Local storage with synchronization
- **`useReadLocalStorage`** - Read-only local storage access
- **`useCookies`** - Cookie management utilities

### 📱 Device & Browser APIs

- **`useMediaQuery`** - CSS media query matching
- **`useMobile`** - Mobile device detection
- **`useScreen`** - Screen information access
- **`useClipboard`** - Clipboard operations
- **`useCopyToClipboard`** - Copy text to clipboard
- **`useEstimateStorage`** - Storage quota estimation
- **`useScript`** - Dynamic script loading

### ⏱️ Timing & Effects

- **`useDebounce`** - Debounce values and callbacks
- **`useDebounceA`** - Alternative debounce implementation
- **`useDebounceB`** - Callback-based debouncing
- **`useTimeout`** - Declarative setTimeout
- **`useTimeoutA`** - Alternative timeout hook
- **`useInterval`** - Declarative setInterval
- **`useCountdown`** - Countdown timer with controls

### 🔧 Utilities

- **`useIsClient`** - Client-side rendering detection
- **`useIsFirstRender`** - First render detection
- **`useIsMounted`** - Component mount status
- **`useSSR`** - Server-side rendering utilities
- **`useEffectOnce`** - Run effect only once
- **`useUpdateEffect`** - Skip effect on first render
- **`useIsomorphicLayoutEffect`** - SSR-safe layout effect
- **`useEventListener`** - Event listener management
- **`useImageOnLoad`** - Image loading state management
- **`useUnloadWarning`** - Page unload warning

### 🎨 Theme & Appearance

- **`useDarkMode`** - Simple dark mode toggle
- **`useTernaryDarkMode`** - Advanced theme management (light/dark/system)

## 💡 Usage Examples

### State Management

```tsx
import { useBoolean, useCounter, useArray } from "@gmana/react-hooks"

function StateExample() {
  // Boolean state with helpers
  const { value: isOpen, setTrue: open, setFalse: close, toggle } = useBoolean(false)

  // Counter with operations
  const { count, increment, decrement, reset } = useCounter(0)

  // Array management
  const { array, push, remove, filter, clear } = useArray([1, 2, 3])

  return (
    <div>
      <button onClick={toggle}>{isOpen ? "Close" : "Open"}</button>
      <button onClick={increment}>Count: {count}</button>
      <div>Array: {array.join(", ")}</div>
      <button onClick={() => push(Math.random())}>Add Random</button>
    </div>
  )
}
```

### UI Interactions

```tsx
import { useHover, useOnClickOutside, useElementSize } from "@gmana/react-hooks"

function UIExample() {
  const [setRef, { width, height }] = useElementSize()
  const hoverRef = useRef(null)
  const isHovered = useHover(hoverRef)

  const dropdownRef = useRef(null)
  const [isDropdownOpen, setIsDropdownOpen] = useState(false)

  useOnClickOutside(dropdownRef, () => setIsDropdownOpen(false))

  return (
    <div ref={setRef}>
      <p>
        Element size: {width}x{height}
      </p>

      <div ref={hoverRef} style={{ background: isHovered ? "blue" : "gray" }}>
        Hover me!
      </div>

      <div ref={dropdownRef}>
        <button onClick={() => setIsDropdownOpen(!isDropdownOpen)}>Toggle Dropdown</button>
        {isDropdownOpen && <div>Dropdown content</div>}
      </div>
    </div>
  )
}
```

### Data Fetching

```tsx
import { useFetch, useDebounce } from "@gmana/react-hooks"

function DataExample() {
  const [query, setQuery] = useState("")
  const debouncedQuery = useDebounce(query, 500)

  const { data, error } = useFetch(debouncedQuery ? `https://api.example.com/search?q=${debouncedQuery}` : null)

  return (
    <div>
      <input value={query} onChange={(e) => setQuery(e.target.value)} placeholder="Search..." />
      {error && <p>Error: {error.message}</p>}
      {data && <pre>{JSON.stringify(data, null, 2)}</pre>}
    </div>
  )
}
```

### Theme Management

```tsx
import { useDarkMode, useTernaryDarkMode } from "@gmana/react-hooks"

function ThemeExample() {
  // Simple dark mode
  const { isDarkMode, toggle, enable, disable } = useDarkMode()

  // Advanced theme with system preference
  const { isDarkMode: isAdvancedDark, ternaryDarkMode, setTernaryDarkMode } = useTernaryDarkMode()

  return (
    <div className={isDarkMode ? "dark" : "light"}>
      <button onClick={toggle}>{isDarkMode ? "Light" : "Dark"} Mode</button>

      <select value={ternaryDarkMode} onChange={(e) => setTernaryDarkMode(e.target.value)}>
        <option value="light">Light</option>
        <option value="dark">Dark</option>
        <option value="system">System</option>
      </select>
    </div>
  )
}
```

## 🛠️ Development

### Prerequisites

- Node.js ≥ 18
- Bun ≥ 1.0.0 (recommended) or npm/yarn

### Setup

```bash
# Clone the repository
git clone https://github.com/sun-sreng/npm-gmana-react-hooks.git
cd npm-gmana-react-hooks

# Install dependencies
bun install

# Start development mode
bun run dev
```

### Scripts

- **`bun run dev`** - Start development mode with watch
- **`bun run build`** - Build the library
- **`bun run test`** - Run tests
- **`bun run test:watch`** - Run tests in watch mode
- **`bun run lint`** - Lint code
- **`bun run format`** - Format code with Prettier
- **`bun run check`** - Run linting and format checks

### Testing

We use Vitest for testing with React Testing Library:

```bash
# Run all tests
bun run test

# Run tests in watch mode
bun run test:watch

# Run specific test file
bun run test src/lib/use-boolean.test.ts
```

### Building

The library is built using Rolldown for optimal performance:

```bash
bun run build
```

This generates:

- `dist/index.js` - ES module bundle
- `dist/index.d.ts` - TypeScript declarations

## 📋 Requirements

### Peer Dependencies

- React ≥ 16.8.0 (hooks support)
- TypeScript ≥ 5.0.0 (for TypeScript projects)

### Browser Support

- Modern browsers with ES2022 support
- React Native (most hooks)

## 🤝 Contributing

We welcome contributions! Please see our [Contributing Guidelines](CONTRIBUTING.md) for details.

### Quick Contribution Guide

1. Fork the repository
2. Create a feature branch: `git checkout -b feature/new-hook`
3. Add your hook with tests and documentation
4. Run tests: `bun run test`
5. Submit a pull request

### Adding a New Hook

1. Create your hook in `src/lib/use-your-hook.ts`
2. Add comprehensive tests in `src/lib/use-your-hook.test.ts`
3. Export the hook in `src/index.ts`
4. Update this README with documentation

## 📄 License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

## 🙏 Acknowledgments

- React team for the amazing hooks API
- All contributors who helped build this library
- The open-source community for inspiration and feedback

## 📞 Support

- 🐛 [Report Issues](https://github.com/sun-sreng/npm-gmana-react-hooks/issues)
- 💡 [Request Features](https://github.com/sun-sreng/npm-gmana-react-hooks/issues)
- 💖 [Sponsor](https://github.com/sponsors/sun-sreng)

---

Made with ❤️ by [Sun Sreng](https://github.com/sun-sreng)
