Skip to content
Components

Code input

Take a sign-in or pairing code one character at a time, without losing paste or autofill.

TS
import { … } from "@fungi.computer/caps/components/code-input";

Hero

TSX
import { useState } from "react";
import { CodeInput } from "@fungi.computer/caps/components/code-input";
export default function Hero() {
const [value, setValue] = useState("42");
return (
<CodeInput
aria-label="Pairing code"
length={6}
onValueChange={setValue}
value={value}
/>
);
}

Status

TSX
import { CodeInput } from "@fungi.computer/caps/components/code-input";
export default function Status() {
return (
<div className="flex flex-col gap-3">
<CodeInput
aria-label="Invalid code"
length={4}
onValueChange={() => {
/* This specimen has no host action. */
}}
status="invalid"
value="1234"
/>
<CodeInput
aria-label="Accepted code"
length={4}
onValueChange={() => {
/* This specimen has no host action. */
}}
status="accepted"
value="1234"
/>
</div>
);
}

Interactive

TSX
import { useState } from "react";
import {
CodeInput,
type CodeInputStatus,
} from "@fungi.computer/caps/components/code-input";
import { Button } from "@fungi.computer/caps/components/button";
export default function Interactive() {
const [value, setValue] = useState("");
const [status, setStatus] = useState<CodeInputStatus>("idle");
const verify = () => {
setStatus(value === "778899" ? "accepted" : "invalid");
};
return (
<div className="flex flex-col items-start gap-2">
<CodeInput
aria-label="Sign-in code"
length={6}
onValueChange={(next) => {
setValue(next);
setStatus("idle");
}}
status={status}
value={value}
/>
<Button onClick={verify} size="sm" variant="outline">
Verify
</Button>
</div>
);
}

Props

CodeInputProps

PropTypeDescription
length?numberHow many characters the code has.
valuestringThe current code.
onValueChange()(value) => voidReceives the code after a native edit or a normalized paste.
status?"idle" | "invalid" | "accepted"invalid shakes the slots in a cascade and marks them; accepted lifts them in a wave. Say what was wrong next to the field, as with any error.
  • length?number

    How many characters the code has.

  • valuestring

    The current code.

  • onValueChange()(value) => void

    Receives the code after a native edit or a normalized paste.

  • status?"idle" | "invalid" | "accepted"

    invalid shakes the slots in a cascade and marks them; accepted lifts them in a wave. Say what was wrong next to the field, as with any error.

Full types: API reference.