import { SensitiveInput } from "@cloudflare/kumo";
export function SensitiveInputDemo() {
return (
<div className="w-80">
<SensitiveInput
label="API Key"
defaultValue="sk_live_abc123xyz789"
onCopy={() => {}}
/>
</div>
);
} Installation
Barrel
import { SensitiveInput } from "@cloudflare/kumo";Granular
import { SensitiveInput } from "@cloudflare/kumo/components/sensitive-input"; Usage
import { SensitiveInput } from "@cloudflare/kumo";
export default function Example() {
return <SensitiveInput label="Secret" defaultValue="my-secret-key" />;
} Basic
By default, SensitiveInput renders only a reveal/mask toggle. The value is masked on blur and can be re-masked with Escape.
import { SensitiveInput } from "@cloudflare/kumo";
/** SensitiveInput with only the reveal toggle — no copy button. */
export function SensitiveInputBasicDemo() {
return (
<div className="w-80">
<SensitiveInput label="Password" defaultValue="super-secret-password" />
</div>
);
} With Copy Button
Pass onCopy to
enable a copy-to-clipboard button. An anchored toast confirms the action.
<SensitiveInput
label="API Key"
defaultValue="sk_live_abc123xyz789"
onCopy={() => {}}
/>import { SensitiveInput } from "@cloudflare/kumo";
/** SensitiveInput with copy enabled via onCopy. */
export function SensitiveInputWithCopyDemo() {
return (
<div className="w-80">
<SensitiveInput
label="API Key"
defaultValue="sk_live_abc123xyz789"
readOnly
onCopy={() => {}}
/>
</div>
);
} Sizes
SensitiveInput supports multiple sizes to fit different contexts.
xs
sm
base
lg
import { SensitiveInput } from "@cloudflare/kumo";
export function SensitiveInputSizesDemo() {
const sizes = ["xs", "sm", "base", "lg"] as const;
return (
<div className="flex flex-col gap-4">
{sizes.map((size) => (
<div key={size} className="flex items-center gap-2">
<span className="w-12 text-sm text-kumo-subtle">{size}</span>
<SensitiveInput
label={`${size} size`}
size={size}
defaultValue="secret-api-key-123"
/>
</div>
))}
</div>
);
} Controlled
Use controlled mode for full control over the input value.
Current value:
my-secret-valueimport { useState } from "react";
import { SensitiveInput, Button } from "@cloudflare/kumo";
export function SensitiveInputControlledDemo() {
const [value, setValue] = useState("my-secret-value");
return (
<div className="flex w-80 flex-col gap-4">
<SensitiveInput
label="Controlled Secret"
value={value}
onValueChange={setValue}
/>
<div className="text-sm text-kumo-subtle">
Current value: <code className="text-kumo-default">{value}</code>
</div>
<div className="flex gap-2">
<Button
onClick={() => setValue("new-secret-" + Date.now())}
variant="primary"
size="sm"
>
Change value
</Button>
<Button onClick={() => setValue("")} variant="secondary" size="sm">
Clear
</Button>
</div>
</div>
);
} States
Various input states including error, disabled, read-only, and with description.
This API key is not valid
Keep this value secure and don't share it
import { SensitiveInput } from "@cloudflare/kumo";
export function SensitiveInputStatesDemo() {
return (
<div className="flex w-80 flex-col gap-4">
<SensitiveInput
label="Error State"
variant="error"
defaultValue="invalid-key"
error="This API key is not valid"
/>
<SensitiveInput label="Disabled" defaultValue="cannot-edit" disabled />
<SensitiveInput
label="Read-only"
defaultValue="view-only-secret-key"
readOnly
/>
<SensitiveInput
label="With Description"
defaultValue="my-secret-value"
description="Keep this value secure and don't share it"
/>
</div>
);
} Internationalization
Pass a labels prop
to override the default English strings for tooltips, aria labels, and the
copy confirmation toast.
<SensitiveInput
label="Clé API"
defaultValue="sk_live_abc123xyz789"
onCopy={() => {}}
labels={{
copyAction: "Copier dans le presse-papiers",
copyTooltip: "Copier",
copiedToast: "Copié !",
reveal: "Afficher la valeur",
revealTooltip: "Afficher",
hide: "Masquer la valeur",
hideTooltip: "Masquer",
}}
/> API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
| alt | string | - | - |
| autoComplete | React.HTMLInputAutoCompleteAttribute | - | - |
| checked | boolean | - | - |
| disabled | boolean | - | - |
| height | number | string | - | - |
| list | string | - | - |
| name | string | - | - |
| placeholder | string | - | - |
| readOnly | boolean | - | - |
| required | boolean | - | - |
| width | number | string | - | - |
| className | string | - | - |
| id | string | - | - |
| lang | string | - | - |
| title | string | - | - |
| children | ReactNode | - | - |
| value | string | - | Controlled value |
| size | "xs" | "sm" | "base" | "lg" | "base" | Size of the input. |
| variant | "default" | "error" | "default" | Style variant of the input. |
| label | ReactNode | - | Label content for the input |
| labelTooltip | ReactNode | - | Tooltip content to display next to the label |
| description | ReactNode | - | Helper text displayed below the input |
| error | string | object | - | Error message or validation error object |
| labels | SensitiveInputLabels | - | Accessible labels for i18n. Pass translated strings to override English defaults. |