AuthCode 10.17.4

ARIA
RTL

A one-time password (OTP) is an automatically generated numeric or alphanumeric string of characters that authenticates a user for a single transaction or login session.

Authcode component is designed for entering OTP codes;it is usually positioned through your UI in places like:

  • Login
  • OTP check

Default

"use client";

import { useCallback, useState } from "react";
import { AuthCode } from "@heathmont/moon-core-tw";

export const Default = () => {
  const [result, setResult] = useState("");
  const handleOnChange = useCallback((res: string) => {
    setResult(res);
  }, []);
  return <AuthCode onChange={handleOnChange} />;
};

export default Default;

    Using React Hook Form with Manual Submit

    The AuthCode component can be utilized in conjunction with Controller component from React Hook Form library.

    In this instance, the user is required to click the button to submit the code.

    "use client";
    
    import { AuthCode, Button, Form } from "@heathmont/moon-core-tw";
    import { Controller, useForm, SubmitHandler } from "react-hook-form";
    import { zodResolver } from "@hookform/resolvers/zod";
    import { z } from "zod";
    
    const schema = z.object({
      authCode: z
        .string()
        .length(6, { message: "Must be exactly 6 characters long" }),
    });
    
    type ValidationSchema = z.infer<typeof schema>;
    
    export const WithManualSubmit = () => {
      const {
        control,
        handleSubmit,
        formState: { isValid, isDirty },
      } = useForm({
        defaultValues: {
          authCode: "",
        },
        resolver: zodResolver(schema),
      });
      const onSubmit: SubmitHandler<ValidationSchema> = (data: ValidationSchema) =>
        alert(data.authCode);
      return (
        <Form onSubmit={handleSubmit(onSubmit)} className="flex flex-col gap-2">
          <Controller
            name="authCode"
            control={control}
            render={({ field }) => <AuthCode {...field} />}
          />
          <Button as="button" type="submit" disabled={!isDirty || !isValid}>
            Send code
          </Button>
        </Form>
      );
    };
    
    export default WithManualSubmit;
    

      Using React Hook Form with Automatic Submit

      In this scenario, there's no need for the user to manually trigger the submit;the submit occurs once the code have length 6 characters in this specific example.

      "use client";
      
      import { AuthCode, Form } from "@heathmont/moon-core-tw";
      import { Controller, useForm, SubmitHandler } from "react-hook-form";
      import { zodResolver } from "@hookform/resolvers/zod";
      import { z } from "zod";
      
      const schema = z.object({
        authCode: z
          .string()
          .length(6, { message: "Must be exactly 6 characters long" }),
      });
      
      type ValidationSchema = z.infer<typeof schema>;
      
      export const WithAutoSubmit = () => {
        const { control, handleSubmit } = useForm({
          defaultValues: {
            authCode: "",
          },
          resolver: zodResolver(schema),
        });
        const onSubmit: SubmitHandler<ValidationSchema> = ({ authCode }) => {
          if (authCode.length === 6) {
            alert(`Code sent: "${authCode}"`);
          }
        };
        return (
          <Form onSubmit={handleSubmit(onSubmit)}>
            <Controller
              name="authCode"
              control={control}
              render={({ field }) => (
                <AuthCode
                  {...field}
                  onChange={(value: string) => {
                    field.onChange(value);
                    onSubmit({ authCode: value });
                  }}
                />
              )}
            />
          </Form>
        );
      };
      
      export default WithAutoSubmit;
      

        Allow only specific characters

        The default setting allows you to input any characters in the field. However, you have the option to restrict it to only letters (alpha) or only numeric input (numeric) using the dedicated prop allowedCharacters.


        In this example the component is restrict to numeric only characters.

        "use client";
        
        import { useCallback, useState } from "react";
        import { AuthCode } from "@heathmont/moon-core-tw";
        
        export const AllowedCharacters = () => {
          const [result, setResult] = useState("");
          const handleOnChange = useCallback((res: string) => {
            setResult(res);
          }, []);
          return <AuthCode allowedCharacters="numeric" onChange={handleOnChange} />;
        };
        
        export default AllowedCharacters;
        

          Custom length

          AuthCode component offers flexibility by adapting on the length of the input. Using the length prop. It allow you to meet with your OTP needs to specific length criteria.


          In this example the length of the OTP is limited to 4.

          "use client";
          
          import { AuthCode, Form } from "@heathmont/moon-core-tw";
          import { Controller, useForm } from "react-hook-form";
          
          export const CustomLength = () => {
            const { control, handleSubmit } = useForm({
              defaultValues: {
                authCode: "",
              },
            });
            const codeLength = 4;
            const onSubmit = ({ authCode }: { authCode: string }) => {
              if (authCode.length === codeLength) alert(`Code sent: "${authCode}"`);
            };
            return (
              <Form
                onSubmit={handleSubmit(onSubmit)}
                className="flex flex-col justify-between items-end gap-y-2"
              >
                <Controller
                  name="authCode"
                  control={control}
                  render={({ field }) => (
                    <AuthCode
                      {...field}
                      length={codeLength}
                      onChange={(value: string) => {
                        field.onChange(value);
                        onSubmit({ authCode: value });
                      }}
                      disabled={field.value.length === codeLength}
                    />
                  )}
                />
              </Form>
            );
          };
          
          export default CustomLength;
          

            Handling Errors

            The isValid prop provides you the option to show a visual error to the user the input a not valid OTP. It can be used also for show not valid OTP after the validation process.


            This example uses the component <Hint error /> to show an additional message, that requires OTP to be at least 3 characters long

            "use client";
            
            import { useEffect } from "react";
            import { AuthCode, Form, Hint } from "@heathmont/moon-core-tw";
            import { Controller, useForm, SubmitHandler } from "react-hook-form";
            import { zodResolver } from "@hookform/resolvers/zod";
            import { z } from "zod";
            import { GenericInfo } from "@heathmont/moon-icons-tw";
            
            const schema = z.object({
              authCode: z.string().min(3, { message: "Must be 3 or more characters long" }),
            });
            
            type ValidationSchema = z.infer<typeof schema>;
            
            export const ErrorState = () => {
              const {
                control,
                handleSubmit,
                formState: { isValid, errors },
                trigger,
              } = useForm({
                defaultValues: {
                  authCode: "",
                },
                resolver: zodResolver(schema),
              });
              const onSubmit: SubmitHandler<ValidationSchema> = (data: ValidationSchema) =>
                console.log("onSubmit: ", data);
              // Trigger validation for this example
              useEffect(() => {
                trigger("authCode");
              }, [trigger]);
              return (
                <Form
                  onSubmit={handleSubmit(onSubmit)}
                  className="flex items-center flex-col"
                >
                  <Controller
                    name="authCode"
                    control={control}
                    render={({ field }) => (
                      <>
                        <AuthCode {...field} isValid={isValid} />
                        {!isValid && (
                          <Hint error>
                            <GenericInfo />
                            {errors.authCode?.message}
                          </Hint>
                        )}
                      </>
                    )}
                  />
                </Form>
              );
            };
            
            export default ErrorState;
            

              Display a hint message

              The previous example uses the component <Hint /> to display an error, but this component can be utilized in conjunction with AuthCode to show additional hints to the user.

              "use client";
              
              import { useState } from "react";
              import { AuthCode, Hint } from "@heathmont/moon-core-tw";
              
              export const HintMessage = () => {
                const [result, setResult] = useState("");
                const handleOnChange = (res: string) => {
                  setResult(res);
                };
                return (
                  <div className="flex items-center flex-col">
                    <AuthCode onChange={handleOnChange} />
                    <Hint>Hint message</Hint>
                  </div>
                );
              };
              
              export default HintMessage;
              

                Display a placeholder

                You can utilize the prop placeholder to display a OTP code as a placeholder in your input. The placeholder can be of any length.

                "use client";
                
                import { useState } from "react";
                import { AuthCode } from "@heathmont/moon-core-tw";
                
                export const Placeholder = () => {
                  const [result, setResult] = useState("");
                  const handleOnChange = (res: string) => {
                    setResult(res);
                  };
                  return <AuthCode onChange={handleOnChange} placeholder="123456" />;
                };
                
                export default Placeholder;
                

                  Hide your input

                  You can make use of the prop isPassword to hide the user input. This prop prevents the characters from being visible on the display.

                  "use client";
                  
                  import { useState } from "react";
                  import { AuthCode } from "@heathmont/moon-core-tw";
                  
                  export const Password = () => {
                    const [result, setResult] = useState("");
                    const handleOnChange = (res: string) => {
                      setResult(res);
                    };
                    return <AuthCode onChange={handleOnChange} isPassword />;
                  };
                  
                  export default Password;
                  

                    Different spacing between inputs

                    "use client";
                    
                    import { useState } from "react";
                    import { AuthCode } from "@heathmont/moon-core-tw";
                    
                    export const DifferentGaps = () => {
                      const [result1, setResult1] = useState("");
                      const handleOnChange1 = () => {
                        setResult1(result1);
                      };
                      const [result12, setResult2] = useState("");
                      const handleOnChange2 = () => {
                        setResult2(result12);
                      };
                      return (
                        <div className="flex flex-col items-center gap-4">
                          <AuthCode onChange={handleOnChange1} />
                          <AuthCode onChange={handleOnChange2} className="gap-4" />
                        </div>
                      );
                    };
                    
                    export default DifferentGaps;
                    

                      AuthCode

                      These are props specific to the AuthCode component:

                      Name
                      Type
                      Default
                      onChange*
                      (value: string) => {}-
                      length
                      number6
                      allowedCharacters
                      "alphanumeric" | "numeric" | "alpha"alphanumeric
                      autoFocus
                      booleanfalse
                      isPassword
                      booleanfalse
                      disabled
                      booleanfalse
                      placeholder
                      string-
                      isValid
                      booleantrue
                      className
                      string-
                      ariaLabel
                      string"Character `${i + 1}`"

                      Properties indicated with * are required.