498

useValidatedState

Hook that manages a state value together with its validation result

statemediumtest coverage
import { useValidatedState } from '@siberiacancode/reactuse';
import { Mail } from 'lucide-react';

const EMAIL_PATTERN = /^[^\s@]+@[^\s@][^\s.@]*\.[^\s@]+$/;

const Demo = () => {
  const [email, setEmail] = useValidatedState('hello@reactuse.org', (value) =>
    EMAIL_PATTERN.test(value)
  );

  return (
    <section className='flex max-w-sm flex-col gap-3'>
      <label className='text-sm font-medium' htmlFor='email'>
        Email
      </label>

      <div className='relative'>
        <Mail className='text-muted-foreground pointer-events-none absolute top-1/2 left-3 size-4 -translate-y-1/2' />
        <input
          autoCapitalize='none'
          autoComplete='email'
          className='!pl-9'
          id='email'
          placeholder='you@example.com'
          spellCheck={false}
          type='email'
          value={email.value}
          onChange={(event) => setEmail(event.target.value)}
        />
      </div>

      <span className='text-destructive h-4 text-xs'>
        {!email.valid && 'Enter a valid email address'}
      </span>
    </section>
  );
};

export default Demo;

Installation

pnpm add @siberiacancode/reactuse

Usage

const [{ value, lastValidValue, valid }, setValue] = useValidatedState( '', (value) => value.length >= 3 );

Type Declarations

export interface UseValidatedStateValue<Value> {
  /** Last valid value */
  lastValidValue?: Value;
  /** True if the current value is valid, false otherwise */
  valid: boolean;
  /** Current value */
  value: Value;
}

export type UseValidatedStateReturn<Value> = [
  state: UseValidatedStateValue<Value>,
  setValue: (value: Value) => void
];

API

Parameters

NameTypeDefaultNote
initialValueValue-The initial state value
validate(value: Value) => boolean-Function that validates the state value
initialValidationStateboolean-Optional initial validity state

Returns

UseValidatedStateReturn<Value>

Contributors

ddebabinMMontana

Last updated on