Last active
August 22, 2025 02:28
-
-
Save pedrouzcategui/c56efc1575f40f4a75a1d99d4e653328 to your computer and use it in GitHub Desktop.
Componente Vanilla de Cédula Venezolana (React/Typescript)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import React, { useState, ChangeEvent, useEffect } from 'react'; | |
| type CedulaInputProps = { | |
| id?: string; | |
| name: string; | |
| label: string; | |
| value?: string; | |
| onChange?: (value: string) => void; | |
| errorMessage?: string; | |
| disabled?: boolean; | |
| className?: string; | |
| inputClassName?: string; | |
| maxLength?: number; | |
| internationalNumberFormatter?: 'es-VE' | 'de-DE'; | |
| }; | |
| export default function CedulaInput({ | |
| id, | |
| name, | |
| label, | |
| value = '', | |
| onChange, | |
| errorMessage, | |
| disabled = false, | |
| className = '', | |
| inputClassName = '', | |
| maxLength = 8, | |
| internationalNumberFormatter = 'de-DE', | |
| }: CedulaInputProps) { | |
| const [cedulaValue, setCedulaValue] = useState(value); | |
| useEffect(() => { | |
| const numericValue = String(value).replace(/[^0-9]/g, ''); | |
| setCedulaValue(numericValue); | |
| }, [value]); | |
| const formatCedula = (val: string) => { | |
| if (!val) return ''; | |
| const numericValue = String(val).replace(/[^0-9]/g, ''); | |
| return new Intl.NumberFormat(internationalNumberFormatter).format( | |
| Number(numericValue) | |
| ); | |
| }; | |
| const handleChange = (e: ChangeEvent<HTMLInputElement>) => { | |
| const numericValue = e.target.value.replace(/[^0-9]/g, ''); | |
| if (numericValue.length <= maxLength) { | |
| setCedulaValue(numericValue); | |
| // Esto es conocido como 'optional chaining operator', es lo mismo que decir if(onChange) { onChange(numericValue) } | |
| onChange?.(numericValue); | |
| } | |
| }; | |
| const formattedMaxLength = maxLength + Math.floor((maxLength - 1) / 3); | |
| return ( | |
| <div className={className}> | |
| <label htmlFor={id || name} className="block font-medium text-sm text-gray-700"> | |
| {label} | |
| </label> | |
| <input | |
| id={id || name} | |
| name={name} | |
| value={formatCedula(cedulaValue)} | |
| onChange={handleChange} | |
| disabled={disabled} | |
| inputMode="numeric" | |
| className={`${inputClassName}`} // Puedes agregar estilos por default si lo deseas | |
| maxLength={formattedMaxLength} | |
| autoComplete="off" | |
| /> | |
| {errorMessage && ( | |
| // También puedes modificar los estilos de error si lo deseas. | |
| <p className="mt-2 text-sm text-red-600">{errorMessage}</p> | |
| )} | |
| </div> | |
| ); | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Cambié unas cosas para poder pasasr tus propias funciones de onChange.