# OTPInput

A customizable component for entering One-Time Passwords with visual feedback and detailed styling options.

### **Import**
```tsx
import { OTPInput } from '@app-studio/web';
```

### **Default**
```tsx
import React, { useState } from 'react';
import { Button } from '../../Button/Button';
import { Vertical } from 'app-studio';
import { Text } from 'app-studio';
import { OTPInput } from '../OTPInput';

export const DefaultOTPInput = () => {
  const [otp, setOtp] = useState('');

  const handleSubmit = (event: React.FormEvent) => {
    event.preventDefault();
    alert(`Entered OTP: ${otp}`);
  };

  return (
    <form onSubmit={handleSubmit}>
      <Vertical gap={20}>
        <Text>Enter verification code:</Text>
        <OTPInput name="otp" value={otp} onChange={setOtp} isAutoFocus />
        <Button type="submit" isAuto>
          Verify
        </Button>
      </Vertical>
    </form>
  );
};

export const CustomizedOTPInput = () => {
  const [otp, setOtp] = useState('');

  return (
    <Vertical gap={20}>
      <Text>Custom OTP Input:</Text>
      <OTPInput
        name="customOtp"
        value={otp}
        onChange={setOtp}
        length={4}
        shape="pill"
        variant="outline"
        size="lg"
        gap={12}
        shadow={{ boxShadow: 'rgba(0, 0, 0, 0.1) 0px 4px 6px' }}
        views={{
          container: {
            borderColor: 'theme-primary',
            backgroundColor: 'color-gray-50',
          },
          input: {
            color: 'theme-primary',
            fontWeight: 'bold',
          },
        }}
      />
    </Vertical>
  );
};

export const OTPInputWithLabel = () => {
  const [otp, setOtp] = useState('');

  return (
    <Vertical gap={20}>
      <OTPInput
        name="labeledOtp"
        label="Verification Code"
        helperText="Enter the 6-digit code sent to your phone"
        value={otp}
        onChange={setOtp}
      />
    </Vertical>
  );
};
```

### **onComplete**
Callback function invoked when all OTP digits have been entered.

- **Type:** `(value: string) => void`
- **Default:** `undefined`
- **Possible Values:** ``

```tsx
import React, { useState } from 'react';
import { Vertical } from 'app-studio';
import { Text } from 'app-studio';
import { OTPInput } from '../OTPInput';

export const OnCompleteDemo = () => {
  const [otp, setOtp] = useState('');
  const [message, setMessage] = useState('');

  const handleComplete = (value: string) => {
    setMessage(`OTP completed: ${value}`);
  };

  return (
    <Vertical gap={20}>
      <Text>Enter OTP (auto-submits when complete):</Text>
      <OTPInput
        name="completeOtp"
        value={otp}
        onChange={setOtp}
        onComplete={handleComplete}
        isAutoFocus
      />
      {message && (
        <Text color="theme-success" fontWeight="medium">
          {message}
        </Text>
      )}
    </Vertical>
  );
};
```

### **stepValues**
An array of numbers used for specific stepping behavior, if applicable.

- **Type:** `number[]`
- **Default:** `undefined`
- **Possible Values:** ``

```tsx
import React, { useState } from 'react';
import { Vertical } from 'app-studio';
import { Horizontal } from 'app-studio';
import { Text } from 'app-studio';
import { OTPInput } from '../OTPInput';

export const StepValuesOTPInput = () => {
  const [otp, setOtp] = useState('');

  // Define specific values that the OTP can take
  const stepValues = [1234, 2468, 3579, 5678, 9876];

  return (
    <Vertical gap={20}>
      <Text>Step-based OTP Input:</Text>
      <OTPInput
        name="stepOtp"
        value={otp}
        onChange={setOtp}
        length={4}
        stepValues={stepValues}
        shape="rounded"
        variant="outline"
        size="lg"
        gap={12}
        views={{
          container: {
            borderColor: 'theme-primary',
            backgroundColor: 'color-gray-50',
          },
          input: {
            color: 'theme-primary',
            fontWeight: 'bold',
          },
        }}
      />

      <Horizontal justifyContent="space-between" width="100%">
        {stepValues.map((step) => (
          <Text key={step} fontSize={14} color="color-blueGray-500">
            {step}
          </Text>
        ))}
      </Horizontal>

      <Text fontSize={14} color="color-gray-600">
        This OTP input will snap to the closest value from:{' '}
        {stepValues.join(', ')}
      </Text>
    </Vertical>
  );
};

export const FormikStepValuesOTPInput = () => {
  // This would be implemented in the Formik examples file
  return null;
};
```

### **Default**

```tsx
import React, { useState } from 'react';
import { Button } from '../../Button/Button';
import { Vertical } from 'app-studio';
import { Text } from 'app-studio';
import { OTPInput } from '../OTPInput';

export const DefaultOTPInput = () => {
  const [otp, setOtp] = useState('');

  const handleSubmit = (event: React.FormEvent) => {
    event.preventDefault();
    alert(`Entered OTP: ${otp}`);
  };

  return (
    <form onSubmit={handleSubmit}>
      <Vertical gap={20}>
        <Text>Enter verification code:</Text>
        <OTPInput name="otp" value={otp} onChange={setOtp} isAutoFocus />
        <Button type="submit" isAuto>
          Verify
        </Button>
      </Vertical>
    </form>
  );
};

export const CustomizedOTPInput = () => {
  const [otp, setOtp] = useState('');

  return (
    <Vertical gap={20}>
      <Text>Custom OTP Input:</Text>
      <OTPInput
        name="customOtp"
        value={otp}
        onChange={setOtp}
        length={4}
        shape="pill"
        variant="outline"
        size="lg"
        gap={12}
        shadow={{ boxShadow: 'rgba(0, 0, 0, 0.1) 0px 4px 6px' }}
        views={{
          container: {
            borderColor: 'theme-primary',
            backgroundColor: 'color-gray-50',
          },
          input: {
            color: 'theme-primary',
            fontWeight: 'bold',
          },
        }}
      />
    </Vertical>
  );
};

export const OTPInputWithLabel = () => {
  const [otp, setOtp] = useState('');

  return (
    <Vertical gap={20}>
      <OTPInput
        name="labeledOtp"
        label="Verification Code"
        helperText="Enter the 6-digit code sent to your phone"
        value={otp}
        onChange={setOtp}
      />
    </Vertical>
  );
};
```

### **OnComplete**

```tsx
import React, { useState } from 'react';
import { Vertical } from 'app-studio';
import { Text } from 'app-studio';
import { OTPInput } from '../OTPInput';

export const OnCompleteDemo = () => {
  const [otp, setOtp] = useState('');
  const [message, setMessage] = useState('');

  const handleComplete = (value: string) => {
    setMessage(`OTP completed: ${value}`);
  };

  return (
    <Vertical gap={20}>
      <Text>Enter OTP (auto-submits when complete):</Text>
      <OTPInput
        name="completeOtp"
        value={otp}
        onChange={setOtp}
        onComplete={handleComplete}
        isAutoFocus
      />
      {message && (
        <Text color="theme-success" fontWeight="medium">
          {message}
        </Text>
      )}
    </Vertical>
  );
};
```

### **PasswordOTP**

```tsx
import React, { useState } from 'react';
import { Button } from '../../Button/Button';
import { Horizontal } from 'app-studio';
import { Vertical } from 'app-studio';
import { Text } from 'app-studio';
import { OTPInput } from '../OTPInput';

export const PasswordOTPInput = () => {
  const [otp, setOtp] = useState('');
  const [isComplete, setIsComplete] = useState(false);

  const handleComplete = (value: string) => {
    setIsComplete(true);
    console.log('OTP completed:', value);
  };

  const resetOTP = () => {
    setOtp('');
    setIsComplete(false);
  };

  return (
    <Vertical gap={20}>
      <Text>Secure PIN Entry (Password Type):</Text>
      <OTPInput
        id="passwordOtpPin"
        name="securePin"
        value={otp}
        onChange={setOtp}
        length={4}
        type="password"
        onComplete={handleComplete}
        isAutoFocus
      />
      {isComplete && <Text color="theme-success">PIN entry complete!</Text>}
      <Horizontal gap={10}>
        <Button onClick={resetOTP} isAuto variant="outline">
          Reset
        </Button>
      </Horizontal>
    </Vertical>
  );
};

export const OnCompleteODemo = () => {
  const [otp, setOtp] = useState('');
  const [completedValue, setCompletedValue] = useState('');

  const handleComplete = (value: string) => {
    setCompletedValue(value);
  };

  return (
    <Vertical gap={20}>
      <Text>OTP with Completion Callback:</Text>
      <OTPInput
        name="completionOtp"
        value={otp}
        onChange={setOtp}
        onComplete={handleComplete}
        length={6}
      />
      {completedValue && <Text>Completed OTP: {completedValue}</Text>}
    </Vertical>
  );
};
```

### **StepValues**

```tsx
import React, { useState } from 'react';
import { Vertical } from 'app-studio';
import { Horizontal } from 'app-studio';
import { Text } from 'app-studio';
import { OTPInput } from '../OTPInput';

export const StepValuesOTPInput = () => {
  const [otp, setOtp] = useState('');

  // Define specific values that the OTP can take
  const stepValues = [1234, 2468, 3579, 5678, 9876];

  return (
    <Vertical gap={20}>
      <Text>Step-based OTP Input:</Text>
      <OTPInput
        name="stepOtp"
        value={otp}
        onChange={setOtp}
        length={4}
        stepValues={stepValues}
        shape="rounded"
        variant="outline"
        size="lg"
        gap={12}
        views={{
          container: {
            borderColor: 'theme-primary',
            backgroundColor: 'color-gray-50',
          },
          input: {
            color: 'theme-primary',
            fontWeight: 'bold',
          },
        }}
      />

      <Horizontal justifyContent="space-between" width="100%">
        {stepValues.map((step) => (
          <Text key={step} fontSize={14} color="color-blueGray-500">
            {step}
          </Text>
        ))}
      </Horizontal>

      <Text fontSize={14} color="color-gray-600">
        This OTP input will snap to the closest value from:{' '}
        {stepValues.join(', ')}
      </Text>
    </Vertical>
  );
};

export const FormikStepValuesOTPInput = () => {
  // This would be implemented in the Formik examples file
  return null;
};
```

### **Index**

```tsx
export * from './Default';
export * from './PasswordOTP';
export * from './StepValues';
export * from './OnComplete';
```

