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

@gridcore/react-smart-input

v0.1.1

Published

A smart input fields component library for React

Downloads

120

Readme

React Smart Input

A comprehensive, type-safe form input component library for React with built-in Formik integration.

Features

  • 🎨 Beautiful, modern UI with Tailwind CSS
  • 📝 Multiple input types (text, email, password, number, tel, select, textarea, date, month, checkbox)
  • ✅ Built-in Formik integration with auto-scroll to errors
  • 🎯 Type-safe with TypeScript
  • 🎨 Customizable primary colors
  • 🔍 Smart select with search and keyboard navigation
  • 📅 Advanced date picker with month/year selection
  • 🏷️ Multi-select with tags and checkboxes
  • 🎯 Select All functionality for multi-select
  • 📦 Standalone Chip component for tags
  • 👁️ Password visibility toggle
  • 🎭 Icons and suffix support
  • 📏 Min/Max length validation
  • 🏷️ Built-in label support for all fields
  • 📋 JSON-based form rendering
  • 🔄 Auto-positioning dropdowns (flip when no space)
  • ⌨️ FormWrapper with keyboard shortcuts (Ctrl+J, Ctrl+S, Ctrl+P, Ctrl+R)
  • 🎯 Jump to field functionality
  • 🖱️ Right-click context menu
  • ♿ Accessible and keyboard-friendly

Installation

npm install @gridcore/react-smart-input lucide-react

For Formik integration:

npm install formik yup

Import Options

Individual Components

import { InputField } from '@gridcore/react-smart-input';
import { SelectField } from '@gridcore/react-smart-input';
import { CheckboxField } from '@gridcore/react-smart-input';
import { TextAreaField } from '@gridcore/react-smart-input';
import { DatePicker } from '@gridcore/react-smart-input';
import { MonthPicker } from '@gridcore/react-smart-input';

Universal Field Component

import { Field } from '@gridcore/react-smart-input';

Formik Integration

import { FormikField } from '@gridcore/react-smart-input';
import { Formik, Form } from 'formik';
import * as Yup from 'yup';

All at Once

import {
  InputField,
  SelectField,
  CheckboxField,
  TextAreaField,
  DatePicker,
  MonthPicker,
  Field,
  FormikField,
  JsonForm,
  FormWrapper
} from '@gridcore/react-smart-input';

Usage Examples

1. Text Input

import { InputField } from '@gridcore/react-smart-input';

function MyForm() {
  const [name, setName] = useState('');
  
  return (
    <InputField
      type="text"
      value={name}
      onChange={setName}
      placeholder="Enter your name"
    />
  );
}

2. Email Input

<InputField
  type="email"
  value={email}
  onChange={setEmail}
  placeholder="Enter your email"
/>

3. Password Input (with toggle)

<InputField
  type="password"
  value={password}
  onChange={setPassword}
  placeholder="Enter password"
/>

4. Number Input

<InputField
  type="number"
  value={age}
  onChange={setAge}
  placeholder="Enter age"
/>

5. Phone Input

<InputField
  type="tel"
  value={phone}
  onChange={setPhone}
  placeholder="Enter phone number"
/>

6. Select Dropdown

import { SelectField } from '@gridcore/react-smart-input';

<SelectField
  value={country}
  onChange={setCountry}
  options={[
    { value: 'us', label: 'United States' },
    { value: 'uk', label: 'United Kingdom' },
    { value: 'ca', label: 'Canada' }
  ]}
  placeholder="Select country"
/>

7. Multi-Select with Tags

<SelectField
  value={skills}
  onChange={setSkills}
  options={[
    { value: 'react', label: 'React' },
    { value: 'typescript', label: 'TypeScript' },
    { value: 'nodejs', label: 'Node.js' }
  ]}
  placeholder="Select skills"
  multiple
  showTags
  showCheckboxes
  showSelectAll
/>

8. Chip Component

import { Chip } from '@gridcore/react-smart-input';

<Chip label="React" onRemove={() => {}} primaryColor="purple-600" />
<Chip label="TypeScript" />

9. Textarea

import { TextAreaField } from '@gridcore/react-smart-input';

<TextAreaField
  value={description}
  onChange={setDescription}
  placeholder="Enter description"
  rows={4}
/>

9. Date Picker

import { DatePicker } from '@gridcore/react-smart-input';

<DatePicker
  value={birthDate}
  onChange={setBirthDate}
  placeholder="Select date"
  maxDate="2010-12-31"
  minDate="1950-01-01"
/>

10. Month Picker

import { MonthPicker } from '@gridcore/react-smart-input';

<MonthPicker
  value={startMonth}
  onChange={setStartMonth}
  placeholder="Select month"
/>

11. Checkbox

import { CheckboxField } from '@gridcore/react-smart-input';

<CheckboxField
  value={agreed}
  onChange={setAgreed}
/>

12. Using Field Component (Type-based)

import { Field } from '@gridcore/react-smart-input';

// Text input
<Field type="text" value={name} onChange={setName} placeholder="Name" />

// Select
<Field 
  type="select" 
  value={country} 
  onChange={setCountry}
  options={[{ value: 'us', label: 'USA' }]}
  placeholder="Select country"
/>

// Date
<Field type="date" value={date} onChange={setDate} placeholder="Select date" />

// Textarea
<Field type="textarea" value={bio} onChange={setBio} rows={3} />

// Checkbox
<Field type="checkbox" value={agreed} onChange={setAgreed} />

13. With Icons and Suffix

import { Mail, Lock } from 'lucide-react';

<InputField
  type="email"
  value={email}
  onChange={setEmail}
  leftIcon={<Mail className="w-4 h-4" />}
  placeholder="Email"
/>

<InputField
  type="password"
  value={password}
  onChange={setPassword}
  leftIcon={<Lock className="w-4 h-4" />}
  placeholder="Password"
/>

<InputField
  type="number"
  value={price}
  onChange={setPrice}
  suffix="USD"
  placeholder="Price"
/>

14. Min/Max Length Validation

<InputField
  type="text"
  value={username}
  onChange={setUsername}
  minLength={3}
  maxLength={20}
  placeholder="Username (3-20 chars)"
/>

<TextAreaField
  value={bio}
  onChange={setBio}
  minLength={10}
  maxLength={500}
  placeholder="Bio (10-500 chars)"
  rows={4}
/>

15. JSON Form (Auto-render from Schema)

import { JsonForm } from '@gridcore/react-smart-input';
import { Formik, Form } from 'formik';
import * as Yup from 'yup';

const schema = [
  { name: 'name', type: 'text', label: 'Name', placeholder: 'Enter name', minLength: 3, maxLength: 50 },
  { name: 'email', type: 'email', label: 'Email', placeholder: 'Enter email' },
  { name: 'country', type: 'select', label: 'Country', options: [
    { value: 'us', label: 'United States' },
    { value: 'uk', label: 'United Kingdom' }
  ]},
  { name: 'bio', type: 'textarea', label: 'Bio', rows: 3, maxLength: 200 },
  { name: 'birthDate', type: 'date', label: 'Birth Date' },
  { name: 'agree', type: 'checkbox', checkboxText: 'I agree to terms' }
];

function MyForm() {
  return (
    <Formik
      initialValues={{ name: '', email: '', country: '', bio: '', birthDate: '', agree: false }}
      validationSchema={Yup.object({
        name: Yup.string().required('Required'),
        email: Yup.string().email('Invalid').required('Required'),
        country: Yup.string().required('Required'),
        birthDate: Yup.string().required('Required'),
        agree: Yup.boolean().oneOf([true], 'Must agree')
      })}
      onSubmit={(values) => console.log(values)}
    >
      <Form>
        <JsonForm schema={schema} />
        <button type="submit">Submit</button>
      </Form>
    </Formik>
  );
}

15b. JSON Form with Grid Layout

// 2-column grid layout
const schema = [
  { name: 'firstName', type: 'text', label: 'First Name' },
  { name: 'lastName', type: 'text', label: 'Last Name' },
  { name: 'email', type: 'email', label: 'Email', colSpan: 2 }, // spans 2 columns
  { name: 'phone', type: 'tel', label: 'Phone' },
  { name: 'city', type: 'text', label: 'City' },
  { name: 'bio', type: 'textarea', label: 'Bio', rows: 3, colSpan: 2 } // spans 2 columns
];

<JsonForm schema={schema} columns={2} />

// 3-column grid layout
const schema3Col = [
  { name: 'field1', type: 'text', label: 'Field 1' },
  { name: 'field2', type: 'text', label: 'Field 2' },
  { name: 'field3', type: 'text', label: 'Field 3' },
  { name: 'fullWidth', type: 'textarea', label: 'Full Width', colSpan: 3 }
];

<JsonForm schema={schema3Col} columns={3} />

16. Address Form (Common Fields)

import { JsonForm } from '@gridcore/react-smart-input';
import { Formik, Form } from 'formik';
import * as Yup from 'yup';

const addressSchema = [
  { name: 'fullName', type: 'text', label: 'Full Name', placeholder: 'John Doe' },
  { name: 'email', type: 'email', label: 'Email', placeholder: '[email protected]' },
  { name: 'phone', type: 'tel', label: 'Phone Number', placeholder: '+1 (555) 000-0000' },
  { name: 'address1', type: 'text', label: 'Address Line 1', placeholder: '123 Main Street' },
  { name: 'address2', type: 'text', label: 'Address Line 2', placeholder: 'Apt 4B (Optional)' },
  { name: 'city', type: 'text', label: 'City', placeholder: 'New York' },
  { name: 'state', type: 'select', label: 'State/Province', placeholder: 'Select state', options: [
    { value: 'ny', label: 'New York' },
    { value: 'ca', label: 'California' },
    { value: 'tx', label: 'Texas' },
    { value: 'fl', label: 'Florida' }
  ]},
  { name: 'zipCode', type: 'text', label: 'ZIP/Postal Code', placeholder: '10001', maxLength: 10 },
  { name: 'country', type: 'select', label: 'Country', placeholder: 'Select country', options: [
    { value: 'us', label: 'United States' },
    { value: 'ca', label: 'Canada' },
    { value: 'uk', label: 'United Kingdom' },
    { value: 'au', label: 'Australia' },
    { value: 'de', label: 'Germany' },
    { value: 'fr', label: 'France' },
    { value: 'in', label: 'India' },
    { value: 'jp', label: 'Japan' }
  ]}
];

function AddressForm() {
  return (
    <Formik
      initialValues={{
        fullName: '', email: '', phone: '', address1: '', address2: '',
        city: '', state: '', zipCode: '', country: ''
      }}
      validationSchema={Yup.object({
        fullName: Yup.string().required('Name is required'),
        email: Yup.string().email('Invalid email').required('Email is required'),
        phone: Yup.string().required('Phone is required'),
        address1: Yup.string().required('Address is required'),
        city: Yup.string().required('City is required'),
        state: Yup.string().required('State is required'),
        zipCode: Yup.string().required('ZIP code is required'),
        country: Yup.string().required('Country is required')
      })}
      onSubmit={(values) => console.log(values)}
    >
      <Form>
        <JsonForm schema={addressSchema} />
        <button type="submit">Submit</button>
      </Form>
    </Formik>
  );
}

18. FormWrapper - Jump to Field & Keyboard Shortcuts

import { FormWrapper, InputField, SelectField, TextAreaField } from '@gridcore/react-smart-input';
import { Formik, Form } from 'formik';

// With JsonForm (automatic)
function MyForm() {
  return (
    <Formik
      initialValues={{ employee_name: '', department: '', description: '' }}
      onSubmit={handleSubmit}
    >
      {({ values, submitForm, resetForm }) => (
        <Form>
          <JsonForm
            schema={[
              { name: 'employee_name', type: 'text', label: 'Employee Name' },
              { name: 'department', type: 'select', label: 'Department', options: deptOptions },
              { name: 'description', type: 'textarea', label: 'Description' }
            ]}
            columns={2}
            enableFormWrapper={true}
            formValues={values}
            onSave={submitForm}
            onReset={resetForm}
            onPrint={() => window.print()}
            primaryColor="purple-600"
          />
        </Form>
      )}
    </Formik>
  );
}

// Manual wrapper for custom forms
function CustomForm() {
  const [formData, setFormData] = useState({
    employee_name: '',
    department: '',
    description: ''
  });

  return (
    <FormWrapper
      formFields={formData}
      excludeFields={['id', 'created_at']}
      onSave={handleSave}
      onPrint={() => window.print()}
      onReset={handleReset}
      primaryColor="purple-600"
    >
      <InputField 
        name="employee_name"
        label="Employee Name"
        value={formData.employee_name}
        onChange={(val) => setFormData({...formData, employee_name: val})}
      />
      
      <SelectField 
        name="department"
        label="Department"
        value={formData.department}
        onChange={(val) => setFormData({...formData, department: val})}
        options={deptOptions}
      />
      
      <TextAreaField 
        name="description"
        label="Description"
        value={formData.description}
        onChange={(val) => setFormData({...formData, description: val})}
      />
    </FormWrapper>
  );
}

Keyboard Shortcuts:

  • Ctrl+J (Cmd+J on Mac): Jump to field
  • Ctrl+S (Cmd+S on Mac): Save form
  • Ctrl+P (Cmd+P on Mac): Print form
  • Ctrl+R (Cmd+R on Mac): Reset form
  • Right-click: Context menu

Requirements:

  • Fields must have name prop for jump-to-field to work
  • Pass formValues to JsonForm or formFields to FormWrapper

17. Formik Integration

import { FormikField } from '@gridcore/react-smart-input';
import { Formik, Form } from 'formik';
import * as Yup from 'yup';

const validationSchema = Yup.object({
  fullName: Yup.string().required('Name is required'),
  email: Yup.string().email('Invalid email').required('Required'),
  password: Yup.string().min(6, 'Too short').required('Required'),
  country: Yup.string().required('Required'),
  skills: Yup.array().min(1, 'Select at least one'),
  birthDate: Yup.string().required('Required'),
  phone: Yup.string().matches(/^[0-9+\-\s()]*$/, 'Invalid phone'),
  age: Yup.number().positive().integer(),
  bio: Yup.string().max(200, 'Too long'),
  terms: Yup.boolean().oneOf([true], 'Must accept')
});

function MyForm() {
  return (
    <Formik
      initialValues={{
        fullName: '',
        email: '',
        password: '',
        country: '',
        skills: [],
        birthDate: '',
        phone: '',
        age: '',
        bio: '',
        terms: false
      }}
      validationSchema={validationSchema}
      onSubmit={(values) => {
        console.log(values);
      }}
    >
      <Form>
        <FormikField
          type="text"
          name="fullName"
          label="Full Name"
          placeholder="Enter your name"
        />

        <FormikField
          type="email"
          name="email"
          label="Email"
          placeholder="Enter email"
        />

        <FormikField
          type="password"
          name="password"
          label="Password"
          placeholder="Enter password"
        />

        <FormikField
          type="select"
          name="country"
          label="Country"
          placeholder="Select country"
          options={[
            { value: 'us', label: 'United States' },
            { value: 'uk', label: 'United Kingdom' }
          ]}
        />

        <FormikField
          type="select"
          name="skills"
          label="Skills"
          placeholder="Select skills"
          multiple
          showTags
          options={[
            { value: 'react', label: 'React' },
            { value: 'typescript', label: 'TypeScript' }
          ]}
        />

        <FormikField
          type="date"
          name="birthDate"
          label="Birth Date"
          placeholder="Select date"
        />

        <FormikField
          type="tel"
          name="phone"
          label="Phone"
          placeholder="Enter phone"
        />

        <FormikField
          type="number"
          name="age"
          label="Age"
          placeholder="Enter age"
        />

        <FormikField
          type="textarea"
          name="bio"
          label="Bio"
          placeholder="Tell us about yourself"
          rows={4}
        />

        <FormikField
          type="checkbox"
          name="terms"
          label="I accept terms and conditions"
        />

        <button type="submit">Submit</button>
      </Form>
    </Formik>
  );
}

Props

Common Props (All Components)

| Prop | Type | Default | Description | |------|------|---------|-------------| | value | string \| boolean \| string[] | - | Field value | | onChange | function | - | Change handler | | className | string | '' | Additional CSS classes | | label | string | - | Field label (renders above field) | | primaryColor | string | 'purple-600' | Primary color for focus states | | disabled | boolean | false | Disable field |

InputField Props

| Prop | Type | Description | |------|------|-------------| | type | 'text' \| 'email' \| 'password' \| 'number' \| 'tel' \| 'file' | Input type | | placeholder | string | Placeholder text | | leftIcon | ReactNode | Icon on left side | | rightIcon | ReactNode | Icon on right side | | suffix | string | Suffix text | | minLength | number | Minimum character length | | maxLength | number | Maximum character length | | label | string | Field label |

SelectField Props

| Prop | Type | Description | |------|------|-------------| | options | { value: string; label: string }[] | Options array | | multiple | boolean | Enable multi-select | | showTags | boolean | Show selected as tags (for multi-select) | | showCheckboxes | boolean | Show checkboxes (default: true when multiple=true) | | showSelectAll | boolean | Show "Select All" button (default: true when multiple=true) | | position | 'top' \| 'bottom' | Dropdown position (auto-adjusts if no space) | | hideSelectOption | boolean | Hide "Select option" placeholder | | label | string | Field label |

Chip Props

| Prop | Type | Description | |------|------|-------------| | label | string | Chip text content | | onRemove | () => void | Callback when X button clicked | | className | string | Additional CSS classes | | primaryColor | string | Primary color (default: 'purple-600') |

DatePicker Props

| Prop | Type | Description | |------|------|-------------| | minDate | string | Minimum date (YYYY-MM-DD) | | maxDate | string | Maximum date (YYYY-MM-DD) | | position | 'top' \| 'bottom' \| 'left' \| 'right' | Calendar position (auto-adjusts if no space) |

TextAreaField Props

| Prop | Type | Description | |------|------|-------------| | rows | number | Number of rows | | minLength | number | Minimum character length | | maxLength | number | Maximum character length | | label | string | Field label |

FormikField Props

| Prop | Type | Description | |------|------|-------------| | name | string | Formik field name (required) | | label | string | Field label (for non-checkbox fields) | | checkboxText | string | Label text for checkbox fields | | showError | boolean | Show validation error message |

JsonForm Props

| Prop | Type | Description | |------|------|-------------| | schema | JsonFieldConfig[] | Array of field configurations | | className | string | Container CSS classes | | columns | number | Number of columns (1-4, default: 1) | | enableFormWrapper | boolean | Enable FormWrapper (default: false) | | formValues | Record<string, any> | Form values for jump-to-field | | onSave | () => void | Save handler (Ctrl+S) | | onPrint | () => void | Print handler (Ctrl+P) | | onReset | () => void | Reset handler (Ctrl+R) | | primaryColor | string | Primary color (default: 'purple-600') | | excludeFields | string[] | Fields to exclude from jump list |

Note: Fields in JsonForm have automatic spacing. Use columns prop for grid layout.

JsonFieldConfig

| Prop | Type | Description | |------|------|-------------| | name | string | Field name (required) | | type | string | Field type (required) | | label | string | Field label | | checkboxText | string | Label for checkbox (use instead of label) | | colSpan | number | Column span in grid layout (1-4) | | placeholder | string | Placeholder text | | options | array | Options for select fields | | multiple | boolean | Enable multi-select | | showTags | boolean | Show tags for multi-select | | showCheckboxes | boolean | Show checkboxes in multi-select | | showSelectAll | boolean | Show "Select All" in multi-select | | minLength | number | Min character length | | maxLength | number | Max character length | | rows | number | Rows for textarea | | showError | boolean | Show validation errors | | ...any other field props | - | All field-specific props supported |

FormWrapper Props

| Prop | Type | Description | |------|------|-------------| | children | ReactNode | Form content (required) | | formFields | Record<string, any> | Form data object for field list | | excludeFields | string[] | Fields to exclude from jump list | | onSave | () => void | Save handler (Ctrl+S) | | onPrint | () => void | Print handler (Ctrl+P) | | onReset | () => void | Reset handler (Ctrl+R) | | primaryColor | string | Highlight color (default: 'purple-600') |

Features

Built-in Label Support

All field components (InputField, SelectField, TextAreaField, DatePicker, MonthPicker, CheckboxField) support a label prop that renders a label above the field. No need for manual label wrappers.

Multi-Select Enhancements

  • Checkboxes display by default when multiple=true
  • "Select All" button automatically shown for multi-select
  • Chip/tag display for selected items
  • Clear all button on hover

JSON Form Rendering

Render entire forms from JSON schema with automatic field spacing and full validation support. Supports grid layouts with customizable columns and column spans.

Chip Component

Standalone component for displaying removable tags with customizable colors.

Min/Max Length Validation

InputField and TextAreaField support minLength and maxLength props for character validation.

Auto-positioning Dropdowns

DatePicker, MonthPicker, and SelectField automatically adjust their position (top/bottom) when there's insufficient space in the viewport.

Auto-scroll to Error (Formik)

When form validation fails, automatically scrolls to the first field with an error.

Keyboard Navigation (Select)

  • Arrow Up/Down: Navigate options
  • Enter: Select highlighted option
  • Escape: Close dropdown

Date Input Validation

Automatically validates and formats date input (DD-MM-YYYY).

Password Toggle

Click eye icon to show/hide password.

FormWrapper Features

  • Keyboard Shortcuts: Ctrl+J (jump to field), Ctrl+S (save), Ctrl+P (print), Ctrl+R (reset)
  • Jump to Field: Press Ctrl+J to open a searchable modal, select a field, and automatically scroll and focus
  • Context Menu: Right-click anywhere in the form to access all actions
  • Field Highlighting: Jumped fields are highlighted with a colored border for 2 seconds
  • Requirements: Fields must have name prop for jump-to-field functionality

See FORM_WRAPPER.md for detailed documentation.

Customization

Custom Colors

<InputField
  type="text"
  value={name}
  onChange={setName}
  primaryColor="blue-600"
/>

Custom Styling

<InputField
  type="text"
  value={name}
  onChange={setName}
  className="custom-class"
/>

License

MIT

Author

GridCore