Skip to content

Commit

Permalink
replace react-verification-input with input-otp (#90)
Browse files Browse the repository at this point in the history
* replace react-verification-input with input-otp

* input otp styling cleanup

* connect footer styling cleanup

* add changeset
  • Loading branch information
alecananian authored Aug 20, 2024
1 parent 1550336 commit 2b4137c
Show file tree
Hide file tree
Showing 8 changed files with 562 additions and 497 deletions.
5 changes: 5 additions & 0 deletions .changeset/hip-crews-argue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@treasure-dev/tdk-react": patch
---

Replaced react-input-verification with input-otp
936 changes: 458 additions & 478 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@
"clsx": "^2.1.1",
"i18next": "^23.12.3",
"i18next-browser-languagedetector": "^8.0.0",
"input-otp": "^1.2.4",
"react": "^18.2.0",
"react-i18next": "^15.0.1",
"react-verification-input": "^4.1.2",
"tailwind-merge": "^2.5.2",
"thirdweb": "^5.46.1",
"viem": "^2.7.6",
Expand Down
2 changes: 1 addition & 1 deletion packages/react/src/components/connect/ConnectFooter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export const ConnectFooter = () => {
href="https://thirdweb.com/connect?utm_source=cw_text"
target="_blank"
rel="noopener noreferrer"
className="tdk-inline-flex tdk-items-center tdk-gap-1 tdk-text-silver tdk-font-semibold hover:tdk-text-white tdk-transition-colors tdk-text-xs tdk-no-underline"
className="tdk-inline-flex tdk-items-center tdk-gap-1 tdk-text-silver tdk-font-semibold hover:tdk-text-white tdk-transition-colors tdk-text-xs tdk-no-underline hover:tdk-no-underline"
>
<Trans
i18nKey="connect.footer"
Expand Down
39 changes: 24 additions & 15 deletions packages/react/src/components/connect/ConnectVerifyCodeView.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { REGEXP_ONLY_DIGITS } from "input-otp";
import { useRef, useState } from "react";
import { Trans, useTranslation } from "react-i18next";
import VerificationInput from "react-verification-input";

import { Button } from "../ui/Button";
import { InputOTP, InputOTPGroup, InputOTPSlot } from "../ui/InputOTP";
import { ConnectFooter } from "./ConnectFooter";

type Props = {
Expand All @@ -12,6 +14,8 @@ type Props = {
onResend: () => void;
};

const OTP_CODE_LENGTH = 6;

export const ConnectVerifyCodeView = ({
recipient,
isLoading = false,
Expand Down Expand Up @@ -74,21 +78,26 @@ export const ConnectVerifyCodeView = ({
<h3 className="tdk-text-sm tdk-font-normal tdk-text-silver-200 tdk-mt-0 tdk-mb-2">
{t("connect.verify.inputLabel")}
</h3>
<VerificationInput
length={6}
placeholder=""
autoFocus
onChange={setCode}
onComplete={onConfirm}
classNames={{
container: "tdk-max-w-full",
character:
"tdk-rounded tdk-text-lg tdk-font-semibold tdk-flex tdk-items-center tdk-justify-center tdk-bg-[#0C1420] tdk-border tdk-border-night-500 tdk-text-cream",
characterInactive: "tdk-bg-[#0C1420]",
characterSelected:
"tdk-border-silver-300 tdk-outline-silver-300 tdk-text-cream",
<InputOTP
maxLength={OTP_CODE_LENGTH}
pattern={REGEXP_ONLY_DIGITS}
value={code}
onChange={(nextCode) => {
setCode(nextCode);
if (nextCode.length === OTP_CODE_LENGTH) {
onConfirm(nextCode);
}
}}
/>
autoComplete="off"
disabled={isLoading}
>
<InputOTPGroup>
{Array.from({ length: OTP_CODE_LENGTH }).map((_, i) => (
// biome-ignore lint/suspicious/noArrayIndexKey: index is the only key
<InputOTPSlot key={i} index={i} />
))}
</InputOTPGroup>
</InputOTP>
</div>
<div className="tdk-space-y-3">
<Button
Expand Down
2 changes: 1 addition & 1 deletion packages/react/src/components/ui/Dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const DialogContent = React.forwardRef<
<DialogPrimitive.Content
ref={ref}
className={cn(
"tdk-fixed tdk-max-h-screen tdk-p-4 sm:tdk-px-6 tdk-overflow-y-auto tdk-left-1/2 tdk-top-1/2 tdk-z-50 tdk-w-full -tdk-translate-x-1/2 -tdk-translate-y-1/2 tdk-duration-200 data-[state=open]:tdk-animate-in data-[state=closed]:tdk-animate-out data-[state=closed]:tdk-fade-out-0 data-[state=open]:tdk-fade-in-0 data-[state=closed]:tdk-zoom-out-95 data-[state=open]:tdk-zoom-in-95 data-[state=closed]:tdk-slide-out-to-left-1/2 data-[state=closed]:tdk-slide-out-to-top-[48%] data-[state=open]:tdk-slide-in-from-left-1/2 data-[state=open]:tdk-slide-in-from-top-[48%] tdk-outline-none focus:tdk-outline-none focus:tdk-ring-0",
"tdk-fixed tdk-max-h-screen tdk-p-4 sm:tdk-px-6 tdk-overflow-y-auto tdk-left-1/2 tdk-top-1/2 tdk-z-50 tdk-w-full -tdk-translate-x-1/2 -tdk-translate-y-1/2 tdk-border tdk-border-night-600 tdk-shadow-none tdk-drop-shadow-xl data-[state=open]:tdk-animate-in data-[state=closed]:tdk-animate-out data-[state=closed]:tdk-fade-out-0 data-[state=open]:tdk-fade-in-0 data-[state=closed]:tdk-zoom-out-95 data-[state=open]:tdk-zoom-in-95 data-[state=closed]:tdk-slide-out-to-left-1/2 data-[state=closed]:tdk-slide-out-to-top-[48%] data-[state=open]:tdk-slide-in-from-left-1/2 data-[state=open]:tdk-slide-in-from-top-[48%] tdk-outline-none focus:tdk-outline-none focus:tdk-ring-0",
className,
)}
{...props}
Expand Down
61 changes: 61 additions & 0 deletions packages/react/src/components/ui/InputOTP.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { OTPInput, OTPInputContext } from "input-otp";
import * as React from "react";
import { cn } from "../../utils/classnames";

const InputOTP = React.forwardRef<
React.ElementRef<typeof OTPInput>,
React.ComponentPropsWithoutRef<typeof OTPInput>
>(({ className, containerClassName, ...props }, ref) => (
<OTPInput
ref={ref}
containerClassName={cn(
"tdk-flex tdk-items-center tdk-gap-2 has-[:disabled]:tdk-opacity-50",
containerClassName,
)}
className={cn("disabled:tdk-cursor-not-allowed", className)}
{...props}
/>
));
InputOTP.displayName = "InputOTP";

const InputOTPGroup = React.forwardRef<
React.ElementRef<"div">,
React.ComponentPropsWithoutRef<"div">
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("tdk-flex tdk-items-center tdk-gap-3", className)}
{...props}
/>
));
InputOTPGroup.displayName = "InputOTPGroup";

const InputOTPSlot = React.forwardRef<
React.ElementRef<"div">,
React.ComponentPropsWithoutRef<"div"> & { index: number }
>(({ index, className, ...props }, ref) => {
const inputOTPContext = React.useContext(OTPInputContext);
const { char, hasFakeCaret, isActive } = inputOTPContext.slots[index];

return (
<div
ref={ref}
className={cn(
"tdk-relative tdk-flex tdk-h-14 tdk-w-14 tdk-items-center tdk-justify-center tdk-text-lg tdk-font-semibold tdk-bg-[#0C1420] tdk-border tdk-border-solid tdk-border-night-500 tdk-text-cream tdk-transition-all tdk-rounded-md",
isActive && "tdk-z-10 tdk-ring-2 tdk-ring-night-300",
className,
)}
{...props}
>
{char}
{hasFakeCaret && (
<div className="tdk-pointer-events-none tdk-absolute tdk-inset-0 tdk-flex tdk-items-center tdk-justify-center">
<div className="tdk-h-4 tdk-w-px tdk-animate-caret-blink tdk-bg-foreground tdk-duration-1000" />
</div>
)}
</div>
);
});
InputOTPSlot.displayName = "InputOTPSlot";

export { InputOTP, InputOTPGroup, InputOTPSlot };
12 changes: 11 additions & 1 deletion packages/react/tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,17 @@ module.exports = {
content: ["./src/**/*.{js,ts,jsx,tsx}"],
presets: [require("@treasure-dev/tailwind-config")],
theme: {
extend: {},
extend: {
keyframes: {
"caret-blink": {
"0%,70%,100%": { opacity: "1" },
"20%,50%": { opacity: "0" },
},
},
animation: {
"caret-blink": "caret-blink 1.25s ease-out infinite",
},
},
},
plugins: [require("tailwindcss-animate")],
corePlugins: {
Expand Down

0 comments on commit 2b4137c

Please sign in to comment.