npm package: @gridcore/react-smart-input
Description: A smart input fields component library for React
Latest version: 0.1.1

# 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

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

For Formik integration:
```bash
npm install formik yup
```

## Import Options

### Individual Components

```tsx
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

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

### Formik Integration

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

### All at Once

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

## Usage Examples

### 1. Text Input

```tsx
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

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

### 3. Password Input (with toggle)

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

### 4. Number Input

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

### 5. Phone Input

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

### 6. Select Dropdown

```tsx
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

```tsx
<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

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

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

### 9. Textarea

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

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

### 9. Date Picker

```tsx
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

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

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

### 11. Checkbox

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

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

### 12. Using Field Component (Type-based)

```tsx
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

```tsx
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

```tsx
<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)

```tsx
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

```tsx
// 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)

```tsx
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: 'john@example.com' },
  { 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

```tsx
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

```tsx
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](./FORM_WRAPPER.md) for detailed documentation.

## Customization

### Custom Colors

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

### Custom Styling

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

## License

MIT

## Author

GridCore