Copyable Field
jarvis-ui/copyable-fieldFreeComponent
A selectable, horizontally scrollable field with a copy action.
Live preview
live · rendered by the registry
Rendered by jarvis-ui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://ui.jarv.is/r/copyable-field.jsonSource
1"use client";23import * as React from "react";45import { CopyButton } from "@/components/ui/copy-button";6import { Field, FieldLabel } from "@/components/ui/field";7import { InputGroup, InputGroupAddon } from "@/components/ui/input-group";8import { ScrollArea } from "@/components/ui/scroll-area";9import { cn } from "@/lib/utils";1011type CopyableFieldCopyEvent = Parameters<12 NonNullable<React.ComponentProps<typeof CopyButton>["onCopied"]>13>[1];1415type CopyableFieldProps = Omit<React.ComponentProps<typeof Field>, "children" | "onCopy"> & {16 label: React.ReactNode;17 value: string;18 copyValue?: string;19 showLabel?: boolean;20 copyLabel?: string;21 copiedLabel?: string;22 resetDelay?: number;23 children?: React.ReactNode;24 onCopy?: (value: string, event: CopyableFieldCopyEvent) => void;25 onCopyError?: (error: unknown, event: CopyableFieldCopyEvent) => void;26};2728function CopyableField({29 label,30 value,31 copyValue = value,32 showLabel = true,33 copyLabel = "Copy to clipboard",34 copiedLabel = "Copied",35 resetDelay = 2000,36 children,37 className,38 onCopy,39 onCopyError,40 ...props41}: CopyableFieldProps) {42 const contentRef = React.useRef<HTMLSpanElement>(null);4344 const handleSelect = React.useCallback(() => {45 if (!contentRef.current) {46 return;47 }4849 const selection = window.getSelection();5051 if (!selection) {52 return;53 }5455 const range = document.createRange();5657 range.selectNodeContents(contentRef.current);58 selection.removeAllRanges();59 selection.addRange(range);60 }, []);6162 return (63 <Field className={cn("min-w-0", className)} {...props}>64 <FieldLabel className={cn(showLabel ? "text-xs text-muted-foreground uppercase" : "sr-only")}>65 {label}66 </FieldLabel>67 <InputGroup className="h-10 min-w-0">68 <ScrollArea className="h-full min-w-0 flex-1 [&_[data-slot=scroll-area-scrollbar]]:hidden">69 <button70 type="button"71 aria-label={typeof label === "string" ? `Select ${label}` : "Select text"}72 onClick={handleSelect}73 className="h-full w-full min-w-0 cursor-text bg-transparent py-0 pr-2 pl-3 text-left font-mono text-[13px] outline-none"74 >75 <span ref={contentRef} className="inline-block whitespace-nowrap">76 {children ?? value}77 </span>78 </button>79 </ScrollArea>80 <InputGroupAddon align="inline-end">81 <CopyButton82 value={copyValue}83// … truncated
What it pulls in
Other registry items
Files it writes
More from jarvis-ui
All 10 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Browser Windowbrowser-window | jarvis-ui | Components | Free | no deps | |
| Cookie Consentcookie-consent | jarvis-ui | Components | Free | no deps | |
| Copy Buttoncopy-button | jarvis-ui | Components | Free | 1 dep | |
| Parallax Cardparallax-card | jarvis-ui | Components | Free | 1 dep | |
| Scroll Areascroll-area | jarvis-ui | Components | Free | 1 dep | |
| Stepperstepper | jarvis-ui | Components | Free | 1 dep | |
| Tipovertipover | jarvis-ui | Components | Free | 1 dep · 2 files | |
| Toasttoast | jarvis-ui | Components | Free | 2 deps |
