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

react-kt-forms

v1.0.6

Published

React KT Forms is a compact collection of React form components, validation helpers, theme utilities and a small API provider designed to be dropped into web (and web-like) React apps. It focuses on simple, composable inputs that work with a form context,

Readme

react-kt-forms

React KT Forms is a compact collection of React form components, validation helpers, theme utilities and a small API provider designed to be dropped into web (and web-like) React apps. It focuses on simple, composable inputs that work with a form context, theme-aware components, and a tiny API wrapper using axios.

This README explains how to install and use the package, shows concrete examples that match the code in this repository (see src/extampl.tsx and src/index.ts), and documents the main hooks and components you will use.

Install

Using npm:

npm install react-kt-forms

Or with yarn / pnpm:

yarn add react-kt-forms
# or
pnpm add react-kt-forms

Import the stylesheet

The package ships a small stylesheet required for base styles and some input behaviors. Import it once in your application's entry point (for example src/index.tsx or src/main.tsx):

import "react-kt-forms/styles.css";

What this package exports

The main entry (src/index.ts) exposes the public surface you'll use:

  • Form — container for form inputs and provides form-specific behavior; also used as a namespace for some inputs (e.g. Form.TonalTextInput).
  • FormProvider — wraps part of your app and provides an API instance and theme context.
  • useApi — hook to access the axios instance from FormProvider.
  • rules — validation helpers (e.g. rules.required, rules.number).
  • TonalTextInput — a commonly used text input that integrates with the form context.
  • useColorScheme, useCurrentThemeColors — theme hooks and helpers.
  • Button, ThemedText, ThemedView — small UI helpers that integrate with theme.

Additionally, the src/components/Form/Inputs folder contains other form inputs such as Autocomplete, Checkbox, Combobox, DatePicker, TonalTextInput, and WebOnlyFileInput.

Quick-start (recommended)

Below is a practical example demonstrating the correct way to use Form, Form.TonalTextInput, the validation rules, and FormProvider.

This example is adapted from src/extampl.tsx in this repo.

import React, { useState } from "react";
import "react-kt-forms/styles.css";
import { Form, rules, FormProvider } from "react-kt-forms";

function Main() {
  const [name, setName] = useState<string | null>(null);

  return (
    <Form>
      <div
        style={{ background: "red", width: 40, height: 40 }}
        className="hoverable"
      />

      <Form.TonalTextInput
        title="test"
        value={name}
        onChangeText={(t) => setName(t)}
        rules={[rules.required("test"), rules.number("test", 100, 0)]}
      />
    </Form>
  );
}

export default function App() {
  return (
    <div className="app">
      <FormProvider>
        <Main />
      </FormProvider>
    </div>
  );
}

Key points:

  • Use Form as the immediate parent for inputs that implicitly use the form context.
  • Some inputs are also available via Form.<InputName> (for convenience) — e.g. Form.TonalTextInput.
  • Validation rules are passed as an array to inputs that accept rules.
  • Wrap your app (or the subtree that needs API access / theme management) with FormProvider so useApi and theme hooks work.

API integration — FormProvider and useApi

FormProvider creates and exposes an axios instance on the form context. Use useApi() to access that instance.

Important details (matching src/hooks/api.tsx):

  • FormProvider creates the axios instance using axios.create({ baseURL: props.baseUrl || baseUrlFromEnv(), timeout: 120e3 }).
  • baseUrlFromEnv() attempts to read process.env.EXPO_PUBLIC_BASE_URL and can be overridden by passing baseUrl to FormProvider.
  • props.headers (if given) are merged into api.defaults.headers via an effect — this ensures headers are applied after the axios instance is created.

Example of using useApi:

import { useApi } from "react-kt-forms";

function Example() {
  const api = useApi();

  async function loadData() {
    const res = await api.get("/some-endpoint");
    console.log(res.data);
  }

  return <button onClick={loadData}>Load</button>;
}

Notes:

  • If you pass baseUrl prop to FormProvider, that value will be used as the axios baseURL and will also be reapplied in a useEffect so changes propagate to api.defaults.baseURL.
  • The axios instance has a 120 second timeout by default.

Theme and color scheme

Theme and color-scheme functions live under src/hooks/useColorScheme.tsx and src/hooks/formContext.tsx.

Main exports and helpers:

  • ColorSchemeProvider — listens to the prefers-color-scheme media query and exposes colorScheme, setPreferredColorScheme, clearPreferredColorScheme, and systemColorScheme via context.
  • useColorScheme() — hook that reads the theme context. It throws if used outside a provider (so wrap components in FormProvider which includes ColorSchemeProvider).
  • useCurrentThemeColors() — returns the current color palette merged with any passed theme overrides (via formContext/FormProvider's theme prop).
  • setDomTheme(colorScheme) — helper that toggles .light/.dark classes on document.documentElement and updates the meta[name=theme-color] tag with the theme color.

Example: toggling theme preference

import { useColorScheme } from "react-kt-forms";

function ThemeToggle() {
  const { colorScheme, setPreferredColorScheme, clearPreferredColorScheme } = useColorScheme();

  return (
    <div>
      <div>Current: {colorScheme}</div>
      <button onClick={() => setPreferredColorScheme("dark")}>Dark</button>
      <button onClick={() => setPreferredColorScheme("light")}>Light</button>
      <button onClick={() => clearPreferredColorScheme()}>Follow system</button>
    </div>
  );
}

The provider also saves user preference in localStorage under the color-scheme key and applies it to the DOM immediately on load (so the app matches user choice on refresh).

Form provider — API headers (auth) & theme overrides

The package's provider (exported as FormProvider in the public API — implemented as ApiProvider in the source) accepts two optional props you can use to configure the underlying axios instance and to override the theme used by components.

  • headers — an object merged into the axios defaults. Useful for adding Authorization tokens and custom headers used by your backend.
  • theme — an object matching a subset of the internal theme keys (you can override as many or as few colors as you need). Components will use values from the provided theme when present.

Simple example — static headers and theme:

import React from 'react';
import { FormProvider } from 'react-native-kt-forms';
import App from './App';

const customTheme = {
    // override some colors in light theme 
    light: {
        primary: '#0066FF',
        surface: '#FFFFFF',
        onPrimary: '#FFFFFF',
        onSurface: '#111111',
    }
};

export default function Root() {
    const user = useUser(); // or some state where you store your user session authentication stuff and tokens
    return (
        <FormProvider
            headers={{ Authorization: `Bearer ${user?.token}`, 'X-App-Version': '1.2.3' }}
            theme={customTheme}
        >
            <App />
        </FormProvider>
    );
}

Accessing the axios instance and the active theme in a component:

import React from 'react';
import { useApi, useCurrentThemeColors } from 'react-native-kt-forms';

function Example() {
    const api = useApi();
    const theme = useCurrentThemeColors(); // based on the curren theme (check the theme section) it will return the `light` colors or the `dark` colors with your passed overrides

    async function send() {
        const res = await api.post('/endpoint', { hello: 'world' });
        return res.data;
    }

    return (
        // render UI using theme.primary, theme.surface, etc.
        null
    );
}

Notes

  • headers are merged via api.defaults.headers = {...api.defaults.headers, ...(props.headers || {})} so you can pass any axios header value.
  • the updated theme weather dark or light or both may include the small set of keys used by components (for example primary, surface, onPrimary, onSurface) — the Theme type in the source lists all supported keys; most are optional and you can override only the ones you need.

Utility hooks: useIsMobile

useIsMobile (in src/hooks/useIsMobile.tsx) is a tiny hook that returns whether the viewport width is below the isMobileThreshold constant. It uses window.innerWidth and listens to resize events.

Important notes:

  • useIsMobile reads window.innerWidth on first render — in server-side rendering environments you must ensure this is only used on the client or guard its usage.
  • The hook updates on resize and returns a boolean true when width < isMobileThreshold.

Example:

import { useIsMobile } from "react-kt-forms";

function Responsive() {
  const isMobile = useIsMobile();
  return <div>{isMobile ? "mobile" : "desktop"}</div>;
}

Inputs overview

Inputs live under src/components/Form/Inputs. The folder contains:

  • Autocomplete — index at Inputs/Autocomplete/index.tsx.
  • Checkbox — index at Inputs/Checkbox/index.tsx.
  • Combobox — index at Inputs/Combobox/index.tsx.
  • DatePicker — index at Inputs/DatePicker/index.tsx.
  • TonalTextInput — index at Inputs/TonalTextInput/index.tsx (also exposed as Form.TonalTextInput).
  • WebOnlyFileInputInputs/WebOnlyFileInput/index.web.tsx with style.css.

Each input integrates with the form context and accepts rules for validation when applicable. Check the individual components for prop details; their TypeScript signatures are the source of truth.

Example: Form with API call and theming

import { useState } from "react";
import "react-kt-forms-2/styles.css";
import { Form, rules, FormProvider, useApi } from ".";

const Main = () => {
    const [name, setName] = useState(null as null | string);
    const [loading, setLoading] = useState(false);
    const [valid, setValid] = useState(false);
    const api = useApi();

    const submit = async () => {
        if (loading) {
            return;
        }
        setLoading(true);
        try {
            // submit the data
            await api.post("/add/user", {
                name,
            });
            // do some stuff
        } catch (error) {
            console.error(error);
            // catch the error
        } finally {
            setLoading(false);
        }
    };

    return (
        <>
            <Form
                disabled={loading}
                onValidationStateChange={(v) => {
                    setValid(v);
                }}
            >
                <Form.TonalTextInput
                    onChangeText={(t) => {
                        setName(t);
                    }}
                    value={name}
                    title="test"
                    rules={[rules.required("test"), rules.number("test", 100, 0)]}
                ></Form.TonalTextInput>
            </Form>
            <button
                disabled={loading || !valid}
                onClick={(e) => {
                    e.preventDefault();
                    submit();
                }}
            >
                {loading ? "submitting..." : "submit"}
            </button>
        </>
    );
};

export function App() {
    return (
        <div className="app">
            <FormProvider>
                <Main></Main>
            </FormProvider>
        </div>
    );
}

export default App;

Form inputs reference

Below are usage examples for each input component provided under src/components/Form/Inputs. These snippets follow the components' real props as implemented in the source.

TonalTextInput

<Form.TonalTextInput
    id="name"
    title="name"
    label="Full name"
    value={name}
    onChangeText={(text) => setName(text)}
    rules={[rules.required('Name')]}
    variant="outlined"
    placeholder="Your full name"
/>

Autocomplete (data-backed)

<Autocomplete
    type="data"
    title="Choose city"
    label="City"
    data={[ 'Cairo', 'London', 'New York' ]}
    text={(item) => String(item)}
    selectedItem={selectedCity}
    onChose={(item) => setSelectedCity(item)}
    onClear={(mounted_clear) => { if (!mounted_clear) setSelectedCity(null); }}
    rules={[rules.required('City')]}
/>

Autocomplete (remote API)

<Autocomplete
    type="unknownApi"
    title="Choose user"
    label="User"
    url="/api/users/search"
    body={{ q: 'search term' }}
    apiSelector={(data) => data.users}
    text={(user) => `${user.firstName} ${user.lastName}`}
    selectedItem={selectedUser}
    onChose={(u) => setSelectedUser(u)}
    onClear={() => setSelectedUser(null)}
/>

Combobox

<Combobox
    title="Select option"
    label="Option"
    value={value}
    onTextChange={(v) => setValue(v)}
    data={[ 'Option A', 'Option B' ]}
    type="dada"
    textExtractor={(item) => String(item)}
    placeholder="Start typing"
    rules={[rules.required('Option')]}
/>

DatePicker

<DatePicker
    title="Birthdate"
    label="Birthdate"
    shown={showDatePicker}
    onShow={() => setShowDatePicker(true)}
    onConfirm={(d) => { setBirthdate(d); setShowDatePicker(false); }}
    onCancel={() => setShowDatePicker(false)}
    value={birthdate}
    mode="date"
    rules={[rules.required('Birthdate')]}
/>

DateTimePicker

<DateTimePicker
    title="Appointment"
    shown={showDateTime}
    onShow={() => setShowDateTime(true)}
    onConfirm={(d) => { setAppointment(d); setShowDateTime(false); }}
    onCancel={() => setShowDateTime(false)}
    value={appointment}
    mode="datetime"
    rules={[rules.required('Appointment')]}
/>

OptionsButtons

<OptionsButtons
    label="Choose one"
    options={[{ text: 'Yes', value: 'yes' }, { text: 'No', value: 'no' }]}
    value={opt}
    onValueChange={(v) => setOpt(v)}
    rules={[rules.required('Choice')]}
/>

Development notes

  • FormProvider composes formContext and ColorSchemeProvider. If you need to pass a theme override, pass a theme prop into FormProvider and useCurrentThemeColors() will merge it with the default color palette.
  • The axios instance is created once with useMemo and updated via useEffect when props.headers or props.baseUrl change.
  • Some utilities depend on browser globals (window, localStorage, document). Avoid calling them during SSR.

Where to look in the repo

  • src/index.ts — exports and public API surface.
  • src/extampl.tsx — concrete example usage.
  • src/hooks/api.tsxFormProvider and useApi implementation.
  • src/hooks/useColorScheme.tsx — theme provider and helpers.
  • src/hooks/useIsMobile.tsx — viewport helper.
  • src/components/Form and src/components/Form/Inputs — core form implementation and inputs.

Contributing

Contributions are welcome. If you open a PR, include clear motivation and small, focused changes. Update README and add tests for new behavior when appropriate.

License

MIT