UNPKG

react-tailwind-form-validator

Version:

A lightweight and customizable React form validation library built with Tailwind CSS for modern, responsive, and accessible forms.

62 lines (61 loc) 2.71 kB
import clsx from 'clsx'; import React, { useState } from 'react'; import { FormProvider } from '../context/FormContext'; import { useFormData } from '../hooks/useFormData'; const Select = ({ options, placeholder = 'Select an option', required = false, label, className, fieldKey, styleVariant = 'default', onChange, onValidityChange, }) => { const { updateFormData, setInputValidity } = useFormData(); const [selectedValue, setSelectedValue] = useState(''); const [isValid, setIsValid] = useState(true); const [error, setError] = useState(''); const [shake, setShake] = useState(false); const handleSelectChange = (e) => { const value = e.target.value; setSelectedValue(value); let valid = true; let errorMessage = ''; if (required && value === '') { errorMessage = 'This field cannot be empty.'; valid = false; } setIsValid(valid); setError(errorMessage); updateFormData(fieldKey, value); setInputValidity(fieldKey, valid); if (onValidityChange) { onValidityChange(valid); } if (onChange) { onChange(value); } if (!valid) { setShake(true); setTimeout(() => setShake(false), 500); } }; const selectClass = clsx('inline-flex h-12 font-semibold animate-shimmer items-center justify-between rounded-md border border-slate-800 bg-[linear-gradient(110deg,#000103,45%,#1e2631,55%,#000103)] bg-[length:200%_100%] px-6 font-medium text-slate-400 transition-all duration-300 ease-in-out focus:outline-none focus:ring-2 focus:ring-slate-400 focus:ring-offset-2 focus:ring-offset-slate-50', { 'border-transparent hover:px-3 focus:px-3': true, 'focus:ring-[#000103]': true, 'border-gray-500 border-2': styleVariant === 'outline' && isValid, 'border-red-500 border-2': !isValid, 'animate-shake': shake, }, className); return (<FormProvider> {label && (<label className="text-sm font-semibold text-slate-300" htmlFor={label.toLowerCase()}> {label} </label>)} <select id={label?.toLowerCase()} className={selectClass} value={selectedValue} onChange={handleSelectChange}> <option value="" disabled> {placeholder} </option> {options.map((option) => (<option key={option.value} value={option.value}> {option.label} </option>))} </select> {error && (<span className={clsx('text-red-500 text-sm font-semibold', { 'animate-shake': shake, })}> {error} </span>)} </FormProvider>); }; export default Select;