f-ui
Components

Copyable

Truncated mono text with a copy affordance for IDs and free-form surfaces, with an optional host Link.

Copyable shows a truncated, mono value and copies the full string via Copy Affordance. Use it on detail panels, headers, and free-form layouts — not as a substitute for schema-driven table cells.

When To Use

  • Show a UUID, task id, or similar opaque string where the full value must be copyable but the display should stay short.
  • Prefer CopyableCell inside clickable table rows so the copy control does not fire row navigation.
  • Set href when the truncated text should navigate through the host LinkProvider / useResolvedLink.
  • Use schema copyable: true on Field Types for list/detail cells — use Copyable when you are composing outside that schema surface.
  • Do not introduce a second clipboard stack; Copyable always composes Copy Affordance, which shares useClipboardCopy with message / code shells — see the Copy Affordance shell matrix.

Features

AreaBehavior
TruncationDefault middle truncate (UUID_COPYABLE_TRUNCATE: prefix 8 / suffix 4); override or pass false
ClipboardCopies the full value through Copy Affordance → useClipboardCopy (Copy / Copied labels)
LinkOptional href resolves via useResolvedLink / LinkProvider
Row safetyCopyableCell stops click propagation for table row handlers

Installing

pnpm dlx shadcn@latest add https://ui.isaacfei.com/r/copyable.json
npx shadcn@latest add https://ui.isaacfei.com/r/copyable.json
yarn dlx shadcn@latest add https://ui.isaacfei.com/r/copyable.json
bun x shadcn@latest add https://ui.isaacfei.com/r/copyable.json

With a namespace: npx shadcn@latest add @f-ui/copyable.

registryDependencies: https://ui.isaacfei.com/r/copy-affordance.json, https://ui.isaacfei.com/r/link.json. Runtime npm: lucide-react (via Copy Affordance).

Usage

import { Copyable, CopyableCell } from "@/components/f-ui/copyable/copyable";

<Copyable value="12345678-aaaa-bbbb-cccc-ddddeeeeffff" />
<CopyableCell value={taskId} href={`/tasks/${taskId}`} />

Examples

Plain Id

Middle-truncated mono text with an always-visible copy button. Hover the value for the full string in the native tooltip.

12345678…ffff
"use client";

import { Copyable } from "@/components/f-ui/copyable/copyable";

const SAMPLE_UUID = "12345678-aaaa-bbbb-cccc-ddddeeeeffff";

export function CopyableDemo() {
  return <Copyable value={SAMPLE_UUID} visibility="always" />;
}

Linked Id

Same truncation and copy behavior, with the text wired as a host link (href="#" in the demo).

"use client";

import { Copyable } from "@/components/f-ui/copyable/copyable";

const SAMPLE_UUID = "12345678-aaaa-bbbb-cccc-ddddeeeeffff";

export function CopyableLinkDemo() {
  return <Copyable value={SAMPLE_UUID} href="#" visibility="always" />;
}

Composition

Copyable
└── CopyAffordance
    ├── code | ResolvedLink (truncated display, title = full value)
    └── copy button

CopyableCell wraps Copyable in a div that calls stopPropagation on click.

API Reference

Props

PropTypeDefaultDescription
valuestringFull string to display (truncated) and copy.
truncateTruncatedTextOptions | falseUUID_COPYABLE_TRUNCATETruncation options, or false for the full string.
hrefstringWhen set, display renders through the resolved Link instead of <code>.
visibility"hover" | "always""hover"Copy button visibility (passed to Copy Affordance).
showCopybooleantrueWhen false, hides the copy button.
classNamestringMerged onto the Copy Affordance root.

CopyableCell

Same props as Copyable. Stops click propagation so nested use inside row-click tables does not trigger the row handler.

Constants

ExportDescription
UUID_COPYABLE_TRUNCATE{ mode: "middle", prefix: 8, suffix: 4 } — default truncate for UUID-shaped ids.

On this page