+
Skip to content

colafly/react-nlform

Repository files navigation

React NLForm

A React component library for creating natural language forms with interactive dropdowns and inputs.

React NLForm Demo

npm version License: MIT

Installation

npm install react-nlform
# or
yarn add react-nlform

Quick Start

import React, { useState } from 'react';
import { NLForm, NLSelect, NLInput } from 'react-nlform';

function App() {
  const [formData, setFormData] = useState({
    foodType: '1',
    city: ''
  });

  const foodOptions = [
    { value: '1', label: 'any food' },
    { value: '2', label: 'Italian' },
    { value: '3', label: 'Japanese' }
  ];

  const handleSubmit = (e) => {
    e.preventDefault();
    console.log('Form data:', formData);
  };

  return (
    <NLForm onSubmit={handleSubmit}>
      I feel to eat{' '}
      <NLSelect 
        options={foodOptions}
        value={formData.foodType}
        onChange={(value) => setFormData(prev => ({ ...prev, foodType: value }))}
      />
      <br />
      in{' '}
      <NLInput
        type="text"
        placeholder="any city"
        value={formData.city}
        onChange={(value) => setFormData(prev => ({ ...prev, city: value }))}
        subline="For example: <em>Los Angeles</em> or <em>New York</em>"
      />
      <div className="nl-submit-wrap">
        <button className="nl-submit" type="submit">
          Find a restaurant
        </button>
      </div>
    </NLForm>
  );
}

Components API

NLForm

The main container component for natural language forms.

Props:

  • onSubmit?: (event: FormEvent) => void - Form submission handler
  • className?: string - Custom CSS class (default: 'nl-form')
  • children: ReactNode - Form content

Example:

<NLForm onSubmit={handleSubmit} className="my-form">
  {/* Your form content */}
</NLForm>

NLSelect

Interactive dropdown component for selecting from predefined options.

Props:

  • options: Option[] - Array of {value: string, label: string} objects
  • value?: string - Currently selected value
  • onChange: (value: string, label: string) => void - Selection change handler
  • className?: string - Custom CSS class

Example:

const options = [
  { value: '1', label: 'Option 1' },
  { value: '2', label: 'Option 2' }
];

<NLSelect
  options={options}
  value={selectedValue}
  onChange={(value, label) => {
    console.log('Selected:', { value, label });
    setSelectedValue(value);
  }}
/>

NLInput

Interactive text input component with expandable interface.

Props:

  • type?: string - Input type (default: 'text')
  • value?: string - Current input value
  • placeholder?: string - Placeholder text
  • subline?: string - Helper text below input (supports HTML)
  • onChange: (value: string) => void - Value change handler
  • className?: string - Custom CSS class

Example:

<NLInput
  type="text"
  placeholder="Enter your location"
  value={location}
  onChange={setLocation}
  subline="For example: <em>San Francisco</em> or <em>New York</em>"
/>

Theme Customization

React NLForm includes a powerful theme system for complete styling control.

NLThemeProvider

Wrap your components with NLThemeProvider to apply custom themes:

import { NLForm, NLSelect, NLInput, NLThemeProvider } from 'react-nlform';

const customTheme = {
  form: {
    fontSize: '2.5em',
    fontFamily: 'Georgia, serif',
  },
  fieldToggle: {
    color: '#0066cc',
    borderBottom: '2px solid #0066cc',
  },
  optionsList: {
    background: '#2c3e50',
    borderRadius: '8px',
    boxShadow: '0 4px 12px rgba(0,0,0,0.2)',
  },
  optionItem: {
    color: '#ecf0f1',
    padding: '0.75rem 1.5rem',
  },
  submitButton: {
    background: '#27ae60',
    borderRadius: '6px',
  },
};

function App() {
  return (
    <NLThemeProvider theme={customTheme}>
      <NLForm>
        {/* Your form components */}
      </NLForm>
    </NLThemeProvider>
  );
}

Theme Configuration

The theme object supports the following properties:

interface NLTheme {
  form: {
    fontSize?: string;
    lineHeight?: string | number;
    fontFamily?: string;
    fontWeight?: string | number;
    width?: string;
    margin?: string;
  };
  fieldToggle: {
    color?: string;
    cursor?: string;
    borderBottom?: string;
    textDecoration?: string;
    padding?: string;
    background?: string;
  };
  optionsList: {
    background?: string;
    border?: string;
    borderRadius?: string;
    boxShadow?: string;
    fontSize?: string;
    minWidth?: string;
    zIndex?: number;
  };
  optionItem: {
    color?: string;
    padding?: string;
    cursor?: string;
    backgroundColor?: string;
    hoverBackgroundColor?: string;
    checkedColor?: string;
  };
  input: {
    width?: string;
    padding?: string;
    border?: string;
    borderRadius?: string;
    fontSize?: string;
    color?: string;
    backgroundColor?: string;
  };
  submitButton: {
    background?: string;
    color?: string;
    padding?: string;
    fontSize?: string;
    fontWeight?: string | number;
    borderRadius?: string;
  };
  // ... and more
}

Using Default Theme

Import and extend the default theme:

import { defaultTheme, NLThemeProvider } from 'react-nlform';

const myTheme = {
  ...defaultTheme,
  fieldToggle: {
    ...defaultTheme.fieldToggle,
    color: '#e74c3c',
  },
};

Advanced Usage

Complete Restaurant Finder Example

import React, { useState } from 'react';
import { NLForm, NLSelect, NLInput, NLThemeProvider } from 'react-nlform';

function RestaurantFinder() {
  const [formData, setFormData] = useState({
    foodType: '1',
    restaurantType: '1',
    time: '1',
    city: ''
  });

  const foodOptions = [
    { value: '1', label: 'any food' },
    { value: '2', label: 'Indian' },
    { value: '3', label: 'French' },
    { value: '4', label: 'Japanese' },
    { value: '5', label: 'Italian' }
  ];

  const restaurantOptions = [
    { value: '1', label: 'standard' },
    { value: '2', label: 'fancy' },
    { value: '3', label: 'casual' },
    { value: '4', label: 'romantic' }
  ];

  const timeOptions = [
    { value: '1', label: 'anytime' },
    { value: '2', label: '7 p.m.' },
    { value: '3', label: '8 p.m.' },
    { value: '4', label: '9 p.m.' }
  ];

  const customTheme = {
    form: {
      fontSize: '3em',
      fontFamily: 'Arial, sans-serif',
    },
    fieldToggle: {
      color: '#3498db',
      borderBottom: '2px solid #3498db',
    },
    optionsList: {
      background: '#34495e',
      borderRadius: '8px',
    },
    optionItem: {
      color: '#ecf0f1',
      checkedColor: '#f39c12',
    },
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    console.log('Restaurant preferences:', formData);
    // Handle form submission
  };

  return (
    <NLThemeProvider theme={customTheme}>
      <NLForm onSubmit={handleSubmit}>
        I feel to eat{' '}
        <NLSelect 
          options={foodOptions}
          value={formData.foodType}
          onChange={(value) => setFormData(prev => ({ ...prev, foodType: value }))}
        />
        <br />
        in a{' '}
        <NLSelect 
          options={restaurantOptions}
          value={formData.restaurantType}
          onChange={(value) => setFormData(prev => ({ ...prev, restaurantType: value }))}
        />
        {' '}restaurant
        <br />
        at{' '}
        <NLSelect 
          options={timeOptions}
          value={formData.time}
          onChange={(value) => setFormData(prev => ({ ...prev, time: value }))}
        />
        {' '}in{' '}
        <NLInput
          type="text"
          value={formData.city}
          placeholder="any city"
          subline="For example: <em>Los Angeles</em> or <em>New York</em>"
          onChange={(value) => setFormData(prev => ({ ...prev, city: value }))}
        />
        <div className="nl-submit-wrap">
          <button className="nl-submit" type="submit">
            Find a restaurant
          </button>
        </div>
      </NLForm>
    </NLThemeProvider>
  );
}

Features

  • 🎯 Natural Language Interface - Create forms that read like sentences
  • 🎨 Fully Customizable Themes - Complete control over styling with theme provider
  • 📱 Mobile Friendly - Touch-optimized interactions
  • Accessible - Keyboard navigation and screen reader support
  • 🔧 TypeScript Support - Full type definitions included
  • 🪶 Lightweight - Minimal bundle size impact
  • Easy Integration - Works with any React setup

Browser Support

  • Chrome (latest)
  • Firefox (latest)
  • Safari (latest)
  • Edge (latest)

TypeScript

All components and themes are fully typed. Import types as needed:

import { NLTheme, NLFormProps, NLSelectProps, NLInputProps, Option } from 'react-nlform';

License

MIT © Hypercard Limited Liability Co.

Credits

Inspired by the original NLForm by Codrops, reimagined for React with modern theming capabilities.

点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载