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

@xcelsior/ui-fields

v1.0.5

Published

A React component library that provides form field components integrated with react-hook-form, built on top of the @xcelsior/design-system package.

Readme

@xcelsior/ui-fields

A React component library that provides form field components integrated with react-hook-form, built on top of the @xcelsior/design-system package.

Installation

npm install @xcelsior/ui-fields

Peer Dependencies

This package requires the following peer dependencies:

  • react >= 19
  • react-dom >= 19
  • @xcelsior/design-system (workspace package)

Components

TextInputField

A text input field component integrated with react-hook-form.

import { TextInputField } from '@xcelsior/ui-fields';
import { useForm } from 'react-hook-form';

const MyForm = () => {
    const { control } = useForm();

    return (
        <TextInputField
            control={control}
            name="email"
            label="Email"
            type="email"
            required
            rules={{
                required: 'Email is required',
                pattern: {
                    value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i,
                    message: 'Invalid email address'
                }
            }}
        />
    );
};

SelectField

A select field component integrated with react-hook-form.

import { SelectField } from '@xcelsior/ui-fields';
import { useForm } from 'react-hook-form';

const MyForm = () => {
    const { control } = useForm();

    return (
        <SelectField
            control={control}
            name="country"
            label="Country"
            required
            options={[
                { value: 'AU', label: 'Australia' },
                { value: 'VN', label: 'Vietnam' }
            ]}
            rules={{
                required: 'Country is required'
            }}
        />
    );
};

CheckboxField

A checkbox field component integrated with react-hook-form.

import { CheckboxField } from '@xcelsior/ui-fields';
import { useForm } from 'react-hook-form';

const MyForm = () => {
    const { control } = useForm();

    return (
        <CheckboxField
            control={control}
            name="acceptTerms"
            label="Accept Terms and Conditions"
            required
            rules={{
                required: 'You must accept the terms and conditions'
            }}
        />
    );
};

DatePickerField

A date picker field component integrated with react-hook-form.

import { DatePickerField } from '@xcelsior/ui-fields';
import { useForm } from 'react-hook-form';

const MyForm = () => {
    const { control } = useForm();

    return (
        <DatePickerField
            control={control}
            name="birthDate"
            label="Birth Date"
            placeholder="Select your birth date"
            required
            dateFormat="dd-MM-yyyy"
            rules={{
                required: 'Birth date is required'
            }}
        />
    );
};

TimePickerField

A time picker field component integrated with react-hook-form.

import { TimePickerField } from '@xcelsior/ui-fields';
import { useForm } from 'react-hook-form';

const MyForm = () => {
    const { control } = useForm();

    return (
        <TimePickerField
            control={control}
            name="startTime"
            label="Start Time"
            placeholder="Select start time"
            required
            format12Hour={true}
            rules={{
                required: 'Start time is required'
            }}
        />
    );
};

DateTimePickerField

A combined date and time picker field component integrated with react-hook-form.

import { DateTimePickerField } from '@xcelsior/ui-fields';
import { useForm } from 'react-hook-form';

const MyForm = () => {
    const { control } = useForm();

    return (
        <DateTimePickerField
            control={control}
            name="eventDateTime"
            label="Event Date & Time"
            datePlaceholder="Select date"
            timePlaceholder="Select time"
            required
            outputFormat="iso"
            dateFormat="dd-MM-yyyy"
            format12Hour={true}
            rules={{
                required: 'Event date and time is required'
            }}
        />
    );
};

AddressFormField

A comprehensive address form field component with country-specific formatting (Australia and Vietnam).

import { AddressFormField } from '@xcelsior/ui-fields';
import { useForm } from 'react-hook-form';

const MyForm = () => {
    const { control } = useForm();

    return (
        <AddressFormField
            control={control}
            name="address"
            country="AU"
            required
            t={(key) => translations[key] || key}
            showAutoComplete={false}
            initialAddressesList={[
                { id: '1', addressLine: '123 Main St, Sydney, NSW 2000' },
                { id: '2', addressLine: '456 Queen St, Melbourne, VIC 3000' }
            ]}
            onSelectExistingAddress={(id) => {
                // Handle existing address selection
                console.log('Selected address:', id);
            }}
        />
    );
};

AddressFormField Props

| Prop | Type | Description | |------|------|-------------| | name | string | The name prefix for the address fields | | control | Control | The react-hook-form control object | | country | 'AU' \| 'VN' | The country for address formatting | | required | boolean | Whether the fields are required (default: true) | | t | (key: string) => string | Translation function | | showAutoComplete | boolean | Whether to show the auto-complete address field | | initialAddressesList | Array<{id: string, addressLine: string}> | List of existing addresses | | onSelectExistingAddress | (id: string) => void | Callback when an existing address is selected | | containerClassName | string | Custom className for the container | | labelClassName | string | Custom className for labels |

Address Data Structure

The AddressFormField creates the following nested structure in your form:

interface AddressData {
    areaLevel1?: string;      // State/Province
    areaLevel2?: string;      // Suburb/District
    areaLevel3?: string;      // Ward (VN only)
    streetAddress?: string;   // Street address
    postcode?: string;        // Postcode (AU only)
    addressLine?: string;     // Auto-generated full address
    autoAddress?: string;     // Auto-complete input (optional)
    existAddress?: string;    // Selected existing address ID (optional)
}

Features

  • Full react-hook-form integration: All components use useController for proper integration
  • TypeScript support: Fully typed with generics for form data
  • Country-specific formatting: Address fields adapt to AU/VN formats
  • Auto-generated address line: Automatically builds full address from components
  • Validation support: Built-in error handling and validation rules
  • Consistent styling: Based on @xcelsior/design-system components
  • Accessibility: Proper ARIA attributes and keyboard navigation

Complete Form Example

Here's a comprehensive example showing how to use all the field components together:

import { 
    TextInputField, 
    TextAreaField, 
    SelectField, 
    CheckboxField,
    DatePickerField,
    TimePickerField,
    DateTimePickerField
} from '@xcelsior/ui-fields';
import { useForm } from 'react-hook-form';

interface FormData {
    name: string;
    email: string;
    country: string;
    description: string;
    acceptTerms: boolean;
    birthDate: string;
    meetingTime: string;
    eventDateTime: string;
}

const ComprehensiveForm = () => {
    const { control, handleSubmit } = useForm<FormData>();

    const onSubmit = (data: FormData) => {
        console.log('Form submitted:', data);
    };

    return (
        <form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
            <TextInputField
                control={control}
                name="name"
                label="Full Name"
                placeholder="Enter your full name"
                required
                rules={{ required: 'Name is required' }}
            />
            
            <TextInputField
                control={control}
                name="email"
                label="Email Address"
                type="email"
                placeholder="Enter your email"
                required
                rules={{
                    required: 'Email is required',
                    pattern: {
                        value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i,
                        message: 'Invalid email address'
                    }
                }}
            />
            
            <SelectField
                control={control}
                name="country"
                label="Country"
                required
                options={[
                    { value: 'AU', label: 'Australia' },
                    { value: 'VN', label: 'Vietnam' }
                ]}
                rules={{ required: 'Country is required' }}
            />
            
            <DatePickerField
                control={control}
                name="birthDate"
                label="Birth Date"
                placeholder="Select your birth date"
                required
                dateFormat="dd-MM-yyyy"
                rules={{ required: 'Birth date is required' }}
            />
            
            <TimePickerField
                control={control}
                name="meetingTime"
                label="Preferred Meeting Time"
                placeholder="Select time"
                format12Hour={true}
                rules={{ required: 'Meeting time is required' }}
            />
            
            <DateTimePickerField
                control={control}
                name="eventDateTime"
                label="Event Date & Time"
                datePlaceholder="Select date"
                timePlaceholder="Select time"
                required
                outputFormat="iso"
                dateFormat="dd-MM-yyyy"
                format12Hour={true}
                rules={{ required: 'Event date and time is required' }}
            />
            
            <TextAreaField
                control={control}
                name="description"
                label="Additional Notes"
                placeholder="Any additional information..."
                rows={3}
            />
            
            <CheckboxField
                control={control}
                name="acceptTerms"
                label="I accept the terms and conditions"
                required
                rules={{ required: 'You must accept the terms and conditions' }}
            />
            
            <button type="submit" className="px-4 py-2 bg-blue-600 text-white rounded">
                Submit Form
            </button>
        </form>
    );
};

Best Practices

  1. Use consistent naming: Follow the memory preference to use 'product' instead of 'unified' in component names
  2. Provide validation rules: Always include appropriate validation for required fields
  3. Use TypeScript: Leverage the TypeScript support for better developer experience
  4. Handle translations: Provide translation functions for international applications
  5. Consider accessibility: Test with screen readers and keyboard navigation
  6. Date/Time formats: Choose appropriate date formats and time formats for your use case
  7. Timezone handling: Use ISO format for DateTimePickerField when dealing with server data

Development

# Build the package
npm run build

# Build in watch mode
npm run dev

# Type check
npm run type-check

# Lint
npm run lint

License

Private package - not for public distribution.