API Key Field
zyeon/api-key-fieldFreeComponent
A settings-page secret field with fixed-length masking, reveal/hide with optional auto re-mask, copy-to-clipboard with a visible failure fallback, and a two-step confirm before regenerating.
Install it
npx shadcn@latest add https://ui.zyeon.ai/r/api-key-field.jsonSource
1"use client"23import * as React from "react"4import { Check, Copy, Eye, EyeOff, RefreshCw, TriangleAlert } from "lucide-react"5import { cn } from "@/lib/utils"67/** The masked middle is always this many dots — fixed length, so the real key length never leaks. */8const MASK_DOT_COUNT = 129/** How long the "Copied" / "Copy failed" line stays visible before resetting to idle. */10const COPY_STATUS_DELAY = 20001112export interface ApiKeyFieldProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "onCopy" | "children"> {13 /** The real secret. Rendered verbatim once revealed — this component never reformats it. */14 value: string15 label?: string16 /** Start already revealed instead of masked. */17 defaultRevealed?: boolean18 /** ms after a reveal before it auto-masks again. 0 (default) = never auto-hide. */19 revealTimeout?: number20 /** Prefix characters kept visible in the mask. */21 keepPrefix?: number22 /** Suffix characters kept visible in the mask. */23 keepSuffix?: number24 /** Fires once after a successful clipboard write. */25 onCopy?: () => void26 /** Called only after the two-step confirm; return a Promise to drive the built-in pending state. */27 onRegenerate?: () => void | Promise<void>28 /** External pending flag, OR'd with the promise-driven internal one — set it if the caller tracks its own request lifecycle instead of relying on onRegenerate's return value. */29 regenerating?: boolean30 helper?: React.ReactNode31 /** Already-formatted "created" string — this component never formats dates itself. */32 createdAtLabel?: string33 disabled?: boolean34}3536/** `sk_live_••••••••••••3f9a` — fixed-length dots in the middle, real prefix/suffix at the ends. */37function maskValue(value: string, keepPrefix: number, keepSuffix: number) {38 const dots = "•".repeat(MASK_DOT_COUNT)39 const prefixLen = Math.max(0, keepPrefix)40 const suffixLen = Math.max(0, keepSuffix)41 if (value.length <= prefixLen + suffixLen) return dots42 const prefix = value.slice(0, prefixLen)43 const suffix = suffixLen > 0 ? value.slice(value.length - suffixLen) : ""44 return `${prefix}${dots}${suffix}`45}4647export const ApiKeyField = React.forwardRef<HTMLDivElement, ApiKeyFieldProps>(48 (49 {50 value,51 label,52 defaultRevealed = false,53 revealTimeout = 0,54 keepPrefix = 7,55 keepSuffix = 4,56 onCopy,57 onRegenerate,58 regenerating = false,59 helper,60 createdAtLabel,61 disabled = false,62 className,63// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from zyeon
All 893 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| A/B Test Resultab-test-result | zyeon | Components | Paid | 2 deps · 2 files | |
| Accordionaccordion | zyeon | Components | Free | 1 dep | |
| Activity Feedactivity-feed | zyeon | Components | Free | 2 deps · 2 files | |
| Activity Heatmapactivity-heatmap | zyeon | Components | Paid | 1 dep · 2 files | |
| Address Formaddress-form | zyeon | Components | Paid | 1 dep | |
| Agent Graphagent-graph | zyeon | Components | Free | 2 deps · 2 files | |
| Agent Handoffagent-handoff | zyeon | Components | Free | 1 dep | |
| Agent Inboxagent-inbox | zyeon | Components | Free | 2 deps · 2 files |
