npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@ohah/reset

v0.1.0

Published

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

Readme

@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

npm install @ohah/reset
yarn add @ohah/reset
pnpm add @ohah/reset

🚀 Basic Usage

Individual Reset

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

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

<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

resetById(id: string): void

Resets a component with the specified ID.

resetByGroup Function

resetByGroup(groupId: string): void

Resets all components that belong to the specified group.

🎯 Use Cases

React Hook Form Integration

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

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

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

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

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

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:

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:

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.

🤝 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 file for details.

🔗 Links


Made with ❤️ by ohah