# Inline Copy Text

Inline code that stays readable and copies its value when activated.

Page: https://sui.draco.dev/docs/components/inline-copy-text

### Example: inline-copy-text-demo

```tsx
import { InlineCopyText } from "@workspace/ui/components/inline-copy-text";
import type { ExampleProps } from "../types";
export default function Example({ locale }: ExampleProps) {
  const zh = locale === "zh-CN";
  return (
    <p className="text-sm">
      {zh ? "在终端运行 " : "Run "}
      <InlineCopyText
        labels={{
          copy: zh ? "复制命令" : "Copy command",
          copied: zh ? "已复制" : "Copied",
          failed: zh ? "无法复制，请手动复制" : "Copy failed. Copy manually.",
        }}
      >
        bun run dev
      </InlineCopyText>
      {zh
        ? " 启动开发服务"
        : " in your terminal to start the development server."}
    </p>
  );
}
```

## Installation

```bash
bunx --bun shadcn@latest add @sui/inline-copy-text
```

Install with the shadcn CLI or use the shared `@workspace/ui` package. Follow the [installation guide](/docs/installation) to configure the registry, load styles, and choose import aliases.

```tsx
import { InlineCopyText } from "@workspace/ui/components/inline-copy-text";
```

## Usage

```tsx
<p>Run <InlineCopyText>bun run dev</InlineCopyText> to start.</p>
```

This is a compact, borderless inline code button with keyboard support. It does not submit a surrounding form. Pressing it does not scale or move the text; copy, success, and failure icons share a fixed position so feedback does not change its width. The check mark appears after the asynchronous write succeeds; failure is announced and sent to `onCopyError`.

## Custom display content

Set `value` whenever `children` is a React element rather than a string. The displayed content and copied plain text can differ. `variant="muted"` blends the control into surrounding prose.

### Example: inline-copy-text-custom-value

```tsx
import { InlineCopyText } from "@workspace/ui/components/inline-copy-text";
import type { ExampleProps } from "../types";
export default function Example({ locale }: ExampleProps) {
  const zh = locale === "zh-CN";
  return (
    <div className="grid w-full max-w-xl gap-3 text-sm">
      <div className="group flex min-w-0 items-center justify-between gap-4 rounded-xl border border-border bg-card p-4 text-card-foreground">
        <span className="min-w-0 truncate">
          {zh ? "工作区路径" : "Workspace path"}
        </span>
        <InlineCopyText
          value="/workspace/projects/sui/packages/ui/src/components"
          variant="muted"
          className="max-w-[60%]"
          labels={{
            copy: zh ? "复制完整路径" : "Copy full path",
            copied: zh ? "完整路径已复制" : "Full path copied",
            failed: zh ? "无法复制，请手动复制" : "Copy failed. Copy manually.",
          }}
        >
          <span>packages/ui/…</span>
        </InlineCopyText>
      </div>
      <p className="text-muted-foreground text-sm">
        {zh
          ? "悬停整行或用键盘聚焦即可显示图标；value 指定完整复制值"
          : "Hover the row or focus the control to reveal its icon. The value prop supplies the full path."}
      </p>
    </div>
  );
}
```

## Resource row

Add an unnamed `group` to the enclosing row to reveal the copy icon when the row is hovered or receives focus within. The icon always reserves its space and changes only visibility; it remains visible on touch devices. A successful checkmark remains until the feedback timer resets.

```tsx
<div className="group flex items-center justify-between gap-4 rounded-xl border border-border bg-card p-4 text-card-foreground">
  <span className="min-w-0 truncate text-sm">Production database</span>
  <InlineCopyText labels={{ copy: "Copy database ID", copied: "Database ID copied" }}>
    database_72c31
  </InlineCopyText>
</div>;
```

## Size and disabled state

Use `size="sm"` for compact text, `truncate={false}` to show the complete visible content, or `disabled` to prevent copying.

### Example: inline-copy-text-disabled

```tsx
import { InlineCopyText } from "@workspace/ui/components/inline-copy-text";
import type { ExampleProps } from "../types";
export default function Example({ locale }: ExampleProps) {
  const zh = locale === "zh-CN";
  return (
    <div className="grid w-full max-w-xs gap-4">
      <InlineCopyText
        size="sm"
        labels={{ copy: zh ? "复制路径" : "Copy path" }}
      >
        packages/ui/src/components/inline-copy-text.tsx
      </InlineCopyText>
      <InlineCopyText disabled>
        {zh ? "暂不可复制" : "Copying unavailable"}
      </InlineCopyText>
    </div>
  );
}
```

## Feedback

```tsx
<InlineCopyText
  value="workspace_72c31"
  labels={{ copy: "Copy workspace ID", copied: "Copied", failed: "Copy failed" }}
  onCopy={(value) => console.log(value)}
  onCopyError={(error) => console.error(error)}
>
  Workspace ID
</InlineCopyText>
```

Clipboard access is requested only on activation. If Clipboard API access is unavailable, select and copy the text manually. Pending writes cannot overlap; stale writes cannot overwrite feedback for a changed value or an unmounted control.

## API

| Prop | Type | Default |
| --- | --- | --- |
| `children` | `ReactNode` | Required |
| `value` | `string` | String children |
| `variant` | `"default" \| "muted"` | `"default"` |
| `size` | `"sm" \| "default"` | `"default"` |
| `truncate` | `boolean` | `true` |
| `iconVisibility` | `"hover"` (default) or `"always"`; controls whether the idle copy icon stays visible. |
| `disabled` | `boolean` | `false` |
| `resetDelay` | `number`, milliseconds | `1500` |
| `onCopy` | `(value: string) => void` | — |
| `onCopyError` | `(error: Error) => void` | — |
| `labels` | `{ copy?, pending?, copied?, failed? }` | English labels |

Uses the Base UI Button primitive and supports `ref`, `render`, `onClick`, and `className`. Its inline styling does not inherit the regular Button press movement. Calling `event.preventDefault()` in `onClick` cancels copying. `data-copy-status` exposes `idle`, `pending`, `copied`, or `error`. See [Base UI Button](https://base-ui.com/react/components/button) for composition.

## Icon motion

The copy icon morphs into the success checkmark on the same SVG path, keeps a fixed size, and respects reduced motion. Pending and error states retain their feedback. Import the generic `MorphIcon` from `@workspace/ui/components/morph-icon`: it accepts an `IconNode` or path string, animates changes to `icon`, and defaults to `spring="snappy"` and `reducedMotion="user"`. Size, stroke width, and animation options can be overridden. The `CopyIcon` adapter at `@workspace/ui/components/copy-icon` accepts `status` or the `copied`, `pending`, and `error` flags.
