npm package: @ohah/reset
Description: A React component reset library with full TypeScript support. Reset individual components by ID or multiple components by group.
Author: ohah
Latest version: 0.1.0

# @ohah/reset

A React component reset library with full TypeScript support. Reset individual components by ID or multiple components by group.

## ✨ Features

- 🎯 **Individual Reset**: Reset specific components by ID
- 👥 **Group Reset**: Reset multiple components simultaneously by group
- 🔧 **TypeScript Support**: Full type safety and autocomplete
- ⚡ **Lightweight**: Minimal dependencies for fast performance
- 🌐 **Universal**: Works with any React component
- 📱 **React Native Support**: Works on mobile platforms

## 📦 Installation

```bash
npm install @ohah/reset
```

```bash
yarn add @ohah/reset
```

```bash
pnpm add @ohah/reset
```

## 🚀 Basic Usage

### Individual Reset

```tsx
import React, { useState } from 'react';
import { Reset, resetById } from '@ohah/reset';

function Counter({ reset }: { reset: () => void }) {
  const [count, setCount] = useState(0);
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(c => c + 1)}>+1</button>
      <button onClick={reset}>Reset</button>
    </div>
  );
}

function App() {
  return (
    <div>
      <Reset id="counter1">
        {(reset, key) => <Counter key={key} reset={reset} />}
      </Reset>
      
      <button onClick={() => resetById("counter1")}>
        Reset from outside
      </button>
    </div>
  );
}
```

### Group Reset

```tsx
import React, { useState } from 'react';
import { Reset, resetByGroup } from '@ohah/reset';

function App() {
  return (
    <div>
      {/* Form group */}
      <Reset id="form-field1" groups={["form", "all"]}>
        {(reset, key) => <MyComponent key={key} reset={reset} />}
      </Reset>
      
      <Reset id="form-field2" groups={["form", "all"]}>
        {(reset, key) => <MyComponent key={key} reset={reset} />}
      </Reset>
      
      {/* Sidebar group */}
      <Reset id="sidebar-widget" groups={["sidebar", "all"]}>
        {(reset, key) => <MyComponent key={key} reset={reset} />}
      </Reset>
      
      {/* Group reset buttons */}
      <button onClick={() => resetByGroup("form")}>
        Reset Form Group
      </button>
      <button onClick={() => resetByGroup("sidebar")}>
        Reset Sidebar Group
      </button>
      <button onClick={() => resetByGroup("all")}>
        Reset All
      </button>
    </div>
  );
}
```

## 📚 API Documentation

### Reset Component

```tsx
<Reset id="unique-id" groups={["group1", "group2"]}>
  {(reset, key) => <YourComponent key={key} reset={reset} />}
</Reset>
```

#### Props

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `id` | `string` | ✅ | Unique identifier for the component |
| `groups` | `string[]` | ❌ | Groups the component belongs to |
| `children` | `(reset: () => void, key: number) => ReactNode` | ✅ | Render function |

### resetById Function

```tsx
resetById(id: string): void
```

Resets a component with the specified ID.

### resetByGroup Function

```tsx
resetByGroup(groupId: string): void
```

Resets all components that belong to the specified group.

## 🎯 Use Cases

### React Hook Form Integration

```tsx
import { useForm } from 'react-hook-form';
import { Reset, resetByGroup } from '@ohah/reset';

function UserForm() {
  const { register, reset: formReset, watch } = useForm();
  
  return (
    <form>
      <Reset id="user-form" groups={["user-forms"]}>
        {(reset, key) => (
          <div key={key}>
            <input 
              {...register("name")} 
              placeholder="Name" 
            />
            <input 
              {...register("email")} 
              placeholder="Email" 
            />
            <input 
              {...register("phone")} 
              placeholder="Phone" 
            />
            
            {/* Reset both form state and component state */}
            <button 
              type="button"
              onClick={() => {
                formReset(); // Reset form data
                reset();     // Reset component state
              }}
            >
              Clear Form
            </button>
          </div>
        )}
      </Reset>
      
      {/* Reset all user forms */}
      <button onClick={() => resetByGroup("user-forms")}>
        Reset All User Forms
      </button>
    </form>
  );
}
```

### React Table Integration

```tsx
import { useTable, useSortBy, useFilters } from '@tanstack/react-table';
import { Reset, resetByGroup } from '@ohah/reset';

function DataTable({ data, columns }) {
  const [sorting, setSorting] = useState([]);
  const [filtering, setFiltering] = useState('');
  
  const table = useTable({
    data,
    columns,
    state: { sorting, globalFilter: filtering },
    onSortingChange: setSorting,
    onGlobalFilterChange: setFiltering,
  });

  return (
    <div>
      <Reset id="data-table" groups={["tables", "dashboard"]}>
        {(reset, key) => (
          <div key={key}>
            {/* Table filters */}
            <input
              value={filtering}
              onChange={(e) => setFiltering(e.target.value)}
              placeholder="Search..."
            />
            
            {/* Table */}
            <table>
              <thead>
                {table.getHeaderGroups().map(headerGroup => (
                  <tr key={headerGroup.id}>
                    {headerGroup.headers.map(header => (
                      <th 
                        key={header.id}
                        onClick={header.column.getToggleSortingHandler()}
                      >
                        {header.renderHeader()}
                        {header.column.getIsSorted() === 'asc' ? ' ↑' : 
                         header.column.getIsSorted() === 'desc' ? ' ↓' : ''}
                      </th>
                    ))}
                  </tr>
                ))}
              </thead>
              <tbody>
                {table.getRowModel().rows.map(row => (
                  <tr key={row.id}>
                    {row.getVisibleCells().map(cell => (
                      <td key={cell.id}>
                        {cell.renderCell()}
                      </td>
                    ))}
                  </tr>
                ))}
              </tbody>
            </table>
            
            {/* Reset table state */}
            <button 
              onClick={() => {
                setSorting([]);
                setFiltering('');
                reset();
              }}
            >
              Reset Table
            </button>
          </div>
        )}
      </Reset>
      
      {/* Reset all tables */}
      <button onClick={() => resetByGroup("tables")}>
        Reset All Tables
      </button>
    </div>
  );
}
```

### Advanced Form with Validation Reset

```tsx
import { useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
import * as yup from 'yup';
import { Reset, resetByGroup } from '@ohah/reset';

const schema = yup.object({
  name: yup.string().required(),
  email: yup.string().email().required(),
  age: yup.number().min(18).required(),
});

function AdvancedForm() {
  const { register, handleSubmit, reset: formReset, formState: { errors } } = useForm({
    resolver: yupResolver(schema)
  });
  
  const [submittedData, setSubmittedData] = useState(null);
  
  const onSubmit = (data) => {
    setSubmittedData(data);
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <Reset id="advanced-form" groups={["forms", "validation"]}>
        {(reset, key) => (
          <div key={key}>
            <div>
              <input {...register("name")} placeholder="Name" />
              {errors.name && <span>{errors.name.message}</span>}
            </div>
            
            <div>
              <input {...register("email")} placeholder="Email" />
              {errors.email && <span>{errors.email.message}</span>}
            </div>
            
            <div>
              <input {...register("age")} type="number" placeholder="Age" />
              {errors.age && <span>{errors.age.message}</span>}
            </div>
            
            {submittedData && (
              <div style={{ background: '#e8f5e8', padding: '10px', margin: '10px 0' }}>
                <h4>Submitted Data:</h4>
                <pre>{JSON.stringify(submittedData, null, 2)}</pre>
              </div>
            )}
            
            <div>
              <button type="submit">Submit</button>
              <button 
                type="button"
                onClick={() => {
                  formReset();
                  setSubmittedData(null);
                  reset();
                }}
              >
                Clear All
              </button>
            </div>
          </div>
        )}
      </Reset>
      
      <button onClick={() => resetByGroup("forms")}>
        Reset All Forms
      </button>
    </form>
  );
}
```

### Table with Pagination and Filters Reset

```tsx
import { useTable, usePagination, useSortBy, useGlobalFilter } from '@tanstack/react-table';
import { Reset, resetByGroup } from '@ohah/reset';

function PaginatedTable({ data, columns }) {
  const [globalFilter, setGlobalFilter] = useState('');
  const [pageSize, setPageSize] = useState(10);
  
  const table = useTable({
    data,
    columns,
    state: { globalFilter, pageSize },
    onGlobalFilterChange: setGlobalFilter,
    onPageSizeChange: setPageSize,
  }, useSortBy, usePagination);

  return (
    <div>
      <Reset id="paginated-table" groups={["tables", "data"]}>
        {(reset, key) => (
          <div key={key}>
            {/* Global filter */}
            <input
              value={globalFilter}
              onChange={(e) => setGlobalFilter(e.target.value)}
              placeholder="Search all columns..."
            />
            
            {/* Page size selector */}
            <select 
              value={pageSize} 
              onChange={(e) => setPageSize(Number(e.target.value))}
            >
              {[10, 20, 30, 40, 50].map(pageSize => (
                <option key={pageSize} value={pageSize}>
                  Show {pageSize}
                </option>
              ))}
            </select>
            
            {/* Table */}
            <table>
              <thead>
                {table.getHeaderGroups().map(headerGroup => (
                  <tr key={headerGroup.id}>
                    {headerGroup.headers.map(header => (
                      <th key={header.id}>
                        <div onClick={header.column.getToggleSortingHandler()}>
                          {header.renderHeader()}
                          {header.column.getIsSorted() === 'asc' ? ' ↑' : 
                           header.column.getIsSorted() === 'desc' ? ' ↓' : ''}
                        </div>
                      </th>
                    ))}
                  </tr>
                ))}
              </thead>
              <tbody>
                {table.getRowModel().rows.map(row => (
                  <tr key={row.id}>
                    {row.getVisibleCells().map(cell => (
                      <td key={cell.id}>
                        {cell.renderCell()}
                      </td>
                    ))}
                  </tr>
                ))}
              </tbody>
            </table>
            
            {/* Pagination */}
            <div>
              <button 
                onClick={() => table.setPageIndex(0)}
                disabled={!table.getCanPreviousPage()}
              >
                {'<<'}
              </button>
              <button 
                onClick={() => table.previousPage()}
                disabled={!table.getCanPreviousPage()}
              >
                {'<'}
              </button>
              <button 
                onClick={() => table.nextPage()}
                disabled={!table.getCanNextPage()}
              >
                {'>'}
              </button>
              <button 
                onClick={() => table.setPageIndex(table.getPageCount() - 1)}
                disabled={!table.getCanNextPage()}
              >
                {'>>'}
              </button>
              
              <span>
                Page {table.getState().pagination.pageIndex + 1} of{' '}
                {table.getPageCount()}
              </span>
            </div>
            
            {/* Reset table state */}
            <button 
              onClick={() => {
                setGlobalFilter('');
                setPageSize(10);
                table.setPageIndex(0);
                reset();
              }}
            >
              Reset Table
            </button>
          </div>
        )}
      </Reset>
      
      <button onClick={() => resetByGroup("tables")}>
        Reset All Tables
      </button>
    </div>
  );
}
```

### Form Reset

```tsx
function ContactForm() {
  return (
    <form>
      <Reset id="name-field" groups={["contact-form"]}>
        {(reset, key) => <NameInput key={key} reset={reset} />}
      </Reset>
      
      <Reset id="email-field" groups={["contact-form"]}>
        {(reset, key) => <EmailInput key={key} reset={reset} />}
      </Reset>
      
      <Reset id="message-field" groups={["contact-form"]}>
        {(reset, key) => <MessageInput key={key} reset={reset} />}
      </Reset>
      
      <button onClick={() => resetByGroup("contact-form")}>
        Clear Form
      </button>
    </form>
  );
}
```

### Dashboard Widget Reset

```tsx
function Dashboard() {
  return (
    <div>
      <Reset id="chart-widget" groups={["dashboard", "all"]}>
        {(reset, key) => <ChartWidget key={key} reset={reset} />}
      </Reset>
      
      <Reset id="stats-widget" groups={["dashboard", "all"]}>
        {(reset, key) => <StatsWidget key={key} reset={reset} />}
      </Reset>
      
      <Reset id="table-widget" groups={["dashboard", "all"]}>
        {(reset, key) => <TableWidget key={key} reset={reset} />}
      </Reset>
      
      <button onClick={() => resetByGroup("dashboard")}>
        Refresh Dashboard
      </button>
    </div>
  );
}
```

## 🔧 TypeScript Support

This library provides full TypeScript support:

```tsx
import { Reset, resetById, resetByGroup } from '@ohah/reset';

// Autocomplete support
resetById("counter1"); // ✅ Autocomplete
resetByGroup("form");  // ✅ Autocomplete

// Type safety
<Reset id="counter1" groups={["form"]}>
  {(reset, key) => <MyComponent key={key} reset={reset} />}
</Reset>
```

## 🌐 React Native Support

Works seamlessly with React Native:

```tsx
import { Reset, resetById } from '@ohah/reset';

function NativeApp() {
  return (
    <View>
      <Reset id="native-counter">
        {(reset, key) => <NativeCounter key={key} reset={reset} />}
      </Reset>
      
      <TouchableOpacity onPress={() => resetById("native-counter")}>
        <Text>Reset</Text>
      </TouchableOpacity>
    </View>
  );
}
```

## 📖 Examples

Check out more examples in our [Storybook](https://github.com/ohah/reset).

## 🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

1. Fork the Project
2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`)
3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`)
4. Push to the Branch (`git push origin feature/AmazingFeature`)
5. Open a Pull Request

## 📄 License

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

## 🔗 Links

- [GitHub Repository](https://github.com/ohah/reset)
- [npm Package](https://www.npmjs.com/package/@ohah/reset)
- [Issues](https://github.com/ohah/reset/issues)

---

Made with ❤️ by [ohah](https://github.com/ohah)