- Dependencies:
- ∟Direct: 2
- ∟Peer: 10
- Source code ↗
- Check on NPM ↗
Overview
Section titled “Overview”A multipurpose form input field to capture user data.
import { useForm } from "react-hook-form";import { zodResolver } from "@hookform/resolvers/zod";import { z } from "zod";import { Form } from '@inpulse-ui/form';import { Input } from '@inpulse-ui/input';
const schema = z.object({ field: z.string().optional(),});
export function Demo() { const methods = useForm({ resolver: zodResolver(schema) }); return ( <Form {...methods}> <Input name="field" label="Input" variant="rift" /> </Form> );}This is an original component from Inpulse.
Input was designed from the ground up to be a versatile, all-in-one form field. Within a single component, you get:
- A standard input field for text, number, email and more.
- A password field with a built-in visibility toggle.
- A text field with value masking for a smoother user experience.
- A smart multi-line field.
All of this comes in 5 variations to fit a wide range of use cases.
Our goal with Input is to provide the definitive text input — combining the features developers expect with an intuitive API. Under the hood, it leverages two excellent libraries to power its functionality: imask and react-textarea-autosize.
Installation
Section titled “Installation”pnpm add @inpulse-ui/inputbun add @inpulse-ui/inputyarn add @inpulse-ui/inputnpm install @inpulse-ui/inputAPI Reference
Section titled “API Reference”A native input or textarea element will be rendered based on the configuration.
| Prop | Type | Default Value | Required |
disabled | boolean | false | No |
label | string | Input | No |
locale |
| No | |
mask | string | - | No |
name | string | - | Yes |
onChange | function | - | No |
placeholder | string | - | No |
preset |
| No | |
required | boolean | false | No |
rows | number | - | No |
size |
| No | |
type |
| No | |
variant |
| No |
| Attribute | Value | ||
[data-variant] | |||
Instantiate the component within a form context and set an appropriate name attribute, otherwise it won’t be rendered. The name attribute must be unique within the form for proper functionality.
import { Input } from '@inpulse-ui/input';<Form {...useFormProps}> <Input name="field" label="Input" /></Form>Examples
Section titled “Examples”Default
Section titled “Default”The default variant offers a clean, modern look suitable for most applications. The label is integrated into the input field and dynamically floats based on user interaction, delivering a seamless and intuitive experience.
import { useForm } from "react-hook-form";import { zodResolver } from "@hookform/resolvers/zod";import { z } from "zod";import { Form } from '@inpulse-ui/form';import { Input } from '@inpulse-ui/input';
const schema = z.object({ field: z.string().optional(),});
export function Demo() { const methods = useForm({ resolver: zodResolver(schema) }); return ( <Form {...methods}> <Input name="field" label="Input" variant="default" /> </Form> );}Similar to the standard variant but the label animation breaks the edges of the input, creating additional space for its elements.
import { useForm } from "react-hook-form";import { zodResolver } from "@hookform/resolvers/zod";import { z } from "zod";import { Form } from '@inpulse-ui/form';import { Input } from '@inpulse-ui/input';
const schema = z.object({ field: z.string().optional(),});
export function Demo() { const methods = useForm({ resolver: zodResolver(schema) }); return ( <Form {...methods}> <Input name="field" label="Input" variant="rift" /> </Form> );}The line variant provides a minimalist approach with an underlined style.
import { useForm } from "react-hook-form";import { zodResolver } from "@hookform/resolvers/zod";import { z } from "zod";import { Form } from '@inpulse-ui/form';import { Input } from '@inpulse-ui/input';
const schema = z.object({ field: z.string().optional(),});
export function Demo() { const methods = useForm({ resolver: zodResolver(schema) }); return ( <Form {...methods}> <Input name="field" label="Input" variant="line" /> </Form> );}The ghost variant offers an unopinionated design, allowing it to be easily integrated into any layout.
import { useForm } from "react-hook-form";import { zodResolver } from "@hookform/resolvers/zod";import { z } from "zod";import { Form } from '@inpulse-ui/form';import { Input } from '@inpulse-ui/input';
const schema = z.object({ field: z.string().optional(),});
export function Demo() { const methods = useForm({ resolver: zodResolver(schema) }); return ( <Form {...methods}> <Input name="field" label="Input" variant="ghost" /> </Form> );}The raw variant delivers a neutral approach, closely resembling the native text input experience.
import { useForm } from "react-hook-form";import { zodResolver } from "@hookform/resolvers/zod";import { z } from "zod";import { Form } from '@inpulse-ui/form';import { Input } from '@inpulse-ui/input';
const schema = z.object({ field: z.string().optional(),});
export function Demo() { const methods = useForm({ resolver: zodResolver(schema) }); return ( <Form {...methods}> <Input name="field" label="Input" variant="raw" /> </Form> );}Masks and Presets
Section titled “Masks and Presets”Control text input in Input through a mask. It is possible to define the mask completely freely using the mask property or choose one of the pre-defined masks using the preset property.
import { useForm } from "react-hook-form";import { zodResolver } from "@hookform/resolvers/zod";import { z } from "zod";import { Form } from '@inpulse-ui/form';import { Input } from '@inpulse-ui/input';
const schema = z.object({ field: z.string().optional(),});
export function Demo() { const methods = useForm({ resolver: zodResolver(schema) }); return ( <Form {...methods}> <Input name="field" label="Input" mask="000-X-000" /> </Form> );}The preset property always overrides the mask property - if there is a predefined mask for the chosen value. The available options are:
| Preset | 🇺🇸 | 🇧🇷 | Description |
phone | ✓ | ✓ | Phone number |
zipcode | ✓ | ✓ | Postal code |
ssn | ✓ | - | Social Security Number |
cpf | - | ✓ | Cadastro de Pessoa Física |
cnpj | - | ✓ | Cadastro Nacional de Pessoas Jurídicas |
It is also worth mentioning that the use of the preset property depends on the locale property. For example, the mask of the zipcode preset is different for pt_BR (00000-000) and en_US (00000). This is especially useful for projects that support multiple languages. If locale is not set, the language en_US will be set by default.
import { useForm } from "react-hook-form";import { zodResolver } from "@hookform/resolvers/zod";import { z } from "zod";import { Form } from '@inpulse-ui/form';import { Input } from '@inpulse-ui/input';
const schema = z.object({ field: z.string().optional(),});
export function Demo() { const methods = useForm({ resolver: zodResolver(schema) }); return ( <Form {...methods}> <Input name="field" label="Input" preset="zipcode" /> </Form> );}Password
Section titled “Password”Password fields can be created via the type property. If password is chosen, a secret visibility toggle button will be displayed in the field. When you click this button, the text visibility will be switched between visible and hidden.
import { useForm } from "react-hook-form";import { zodResolver } from "@hookform/resolvers/zod";import { z } from "zod";import { Form } from '@inpulse-ui/form';import { Input } from '@inpulse-ui/input';
const schema = z.object({ password: z.string().optional(),});
export function Demo() { const methods = useForm({ resolver: zodResolver(schema) }); return ( <Form {...methods}> <Input name="password" label="Password" type="password" /> </Form> );}Multiple lines
Section titled “Multiple lines”It is possible to convert the text field into a multi-line field through the rows property. The value of this property defines the maximum number of lines visible in the field, until the content starts to generate a vertical scroll. By default, the minimum number of visible lines will always be 2.
import { useForm } from "react-hook-form";import { zodResolver } from "@hookform/resolvers/zod";import { z } from "zod";import { Form } from '@inpulse-ui/form';import { Input } from '@inpulse-ui/input';
const schema = z.object({ message: z.string().optional(),});
export function Demo() { const methods = useForm({ resolver: zodResolver(schema) }); return ( <Form {...methods}> <Input name="message" label="Message" variant="rift" rows={4} /> </Form> );}Disabled
Section titled “Disabled”The disabled prop prevents user interaction, making it clear that the input is not available for editing. It maintains the same visual style as the default variant but applies a muted color scheme to indicate its inactive state.
import { useForm } from "react-hook-form";import { zodResolver } from "@hookform/resolvers/zod";import { z } from "zod";import { Form } from '@inpulse-ui/form';import { Input } from '@inpulse-ui/input';
const schema = z.object({ field: z.string().optional(),});
export function Demo() { const methods = useForm({ resolver: zodResolver(schema) }); return ( <Form {...methods}> <Input name="field" label="Input" disabled /> </Form> );}It is possible to define the size of the text field using the size property. The available options are sm, md and lg.
import { useForm } from "react-hook-form";import { zodResolver } from "@hookform/resolvers/zod";import { z } from "zod";import { Form } from '@inpulse-ui/form';import { Input } from '@inpulse-ui/input';
const schema = z.object({ small: z.string().optional(), medium: z.string().optional(), large: z.string().optional(),});
export function Demo() { const methods = useForm({ resolver: zodResolver(schema) }); return ( <Form {...methods}> <div className="flex flex-col items-center space-y-4"> <Input name="small" label="Small" size="sm" /> <Input name="medium" label="Medium" size="md" /> <Input name="large" label="Large" size="lg" /> </div> </Form> );}External Label
Section titled “External Label”You can use an external label for the input field by placing a Label component before it and applying the raw variant to the Input.
import { useForm } from "react-hook-form";import { zodResolver } from "@hookform/resolvers/zod";import { z } from "zod";import { Form } from '@inpulse-ui/form';import { Label } from '@inpulse-ui/label';import { Input } from '@inpulse-ui/input';
const schema = z.object({ field: z.string().optional(),});
export function Demo() { const methods = useForm({ resolver: zodResolver(schema) }); return ( <Form {...methods}> <div className="flex flex-col items-center"> <Label for="field" size="xs" className="mb-1 w-full text-left font-bold">Input</Label> <Input name="field" id="field" variant="raw" /> </div> </Form> );}Built with by Jo Santana in Brazil.
© 2026 Inpulse. All rights reserved.