Skip to Content
🎉 Rut.ts 3.4.0 is released! Check out Safe Mode and improved API.

React Example

Complete React examples with rut.ts.

Simple RUT Input Component

import { useState } from 'react' import { format, validate } from 'rut.ts' export function RutInput() { const [rut, setRut] = useState('') const [isValid, setIsValid] = useState(false) const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => { const formatted = format(e.target.value, { incremental: true }) setRut(formatted) setIsValid(validate(formatted)) } return ( <div> <input type="text" value={rut} onChange={handleChange} placeholder="12.345.678-5" className={isValid ? 'valid' : 'invalid'} /> {!isValid && rut && ( <span className="error">Invalid RUT</span> )} </div> ) }

Controlled Component with Validation

import { useState, useEffect } from 'react' import { format, validate, clean } from 'rut.ts' interface RutInputProps { value?: string onChange?: (cleanedRut: string) => void onValidChange?: (isValid: boolean) => void strictMode?: boolean } export function RutInput({ value = '', onChange, onValidChange, strictMode = false }: RutInputProps) { const [displayValue, setDisplayValue] = useState('') const [error, setError] = useState<string | null>(null) useEffect(() => { if (value) { const formatted = format(value, { incremental: true, throwOnError: false }) if (formatted) setDisplayValue(formatted) } }, [value]) const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => { const input = e.target.value // Format incrementally const formatted = format(input, { incremental: true }) setDisplayValue(formatted) // Validate const isValid = validate(formatted, { strict: strictMode }) if (isValid) { setError(null) const cleaned = clean(formatted) onChange?.(cleaned) onValidChange?.(true) } else { setError('RUT inválido') onValidChange?.(false) } } return ( <div className="rut-input"> <input type="text" value={displayValue} onChange={handleChange} placeholder="12.345.678-5" className={error ? 'error' : ''} /> {error && <span className="error-message">{error}</span>} </div> ) }

Form with Multiple Fields

import { useState } from 'react' import { validate, clean, format } from 'rut.ts' interface UserForm { name: string rut: string email: string } export function UserRegistration() { const [form, setForm] = useState<UserForm>({ name: '', rut: '', email: '' }) const [errors, setErrors] = useState<Partial<UserForm>>({}) const handleRutChange = (e: React.ChangeEvent<HTMLInputElement>) => { const formatted = format(e.target.value, { incremental: true }) setForm(prev => ({ ...prev, rut: formatted })) // Clear error if valid if (validate(formatted)) { setErrors(prev => ({ ...prev, rut: undefined })) } } const handleSubmit = async (e: React.FormEvent) => { e.preventDefault() // Validate RUT if (!validate(form.rut)) { setErrors(prev => ({ ...prev, rut: 'RUT inválido' })) return } // Clean RUT for API const cleanedRut = clean(form.rut) // Submit await fetch('/api/users', { method: 'POST', body: JSON.stringify({ ...form, rut: cleanedRut }) }) } return ( <form onSubmit={handleSubmit}> <div> <label>Name:</label> <input value={form.name} onChange={(e) => setForm(prev => ({ ...prev, name: e.target.value }))} /> </div> <div> <label>RUT:</label> <input value={form.rut} onChange={handleRutChange} placeholder="12.345.678-5" /> {errors.rut && <span className="error">{errors.rut}</span>} </div> <div> <label>Email:</label> <input type="email" value={form.email} onChange={(e) => setForm(prev => ({ ...prev, email: e.target.value }))} /> </div> <button type="submit">Register</button> </form> ) }

Display Formatted RUT

import { format } from 'rut.ts' interface RutDisplayProps { rut: string withDots?: boolean } export function RutDisplay({ rut, withDots = true }: RutDisplayProps) { const formatted = format(rut, { dots: withDots, throwOnError: false }) if (!formatted) { return <span className="error">Invalid RUT</span> } return <span className="rut">{formatted}</span> } // Usage <RutDisplay rut="123456785" /> // '12.345.678-5' <RutDisplay rut="123456785" withDots={false} /> // '12345678-5'

Searchable RUT Table

import { useState, useMemo } from 'react' import { clean, format, isRutLike } from 'rut.ts' interface User { id: number name: string rut: string } export function UserTable({ users }: { users: User[] }) { const [search, setSearch] = useState('') const filteredUsers = useMemo(() => { if (!search) return users // Clean search term for comparison const searchCleaned = clean(search, { throwOnError: false }) if (!searchCleaned) return users return users.filter(user => { const userCleaned = clean(user.rut, { throwOnError: false }) return userCleaned?.includes(searchCleaned) }) }, [users, search]) return ( <div> <input type="text" value={search} onChange={(e) => setSearch(e.target.value)} placeholder="Search by RUT" /> <table> <thead> <tr> <th>Name</th> <th>RUT</th> </tr> </thead> <tbody> {filteredUsers.map(user => ( <tr key={user.id}> <td>{user.name}</td> <td>{format(user.rut)}</td> </tr> ))} </tbody> </table> </div> ) }
Last updated on