Display
Code inline
Inline code in running text outside prose, such as a command or an ID, with an optional copy button.
- Built on
<code>Clipboard APIrole=status- Client JavaScript
- Yes, for state
- Works without React
- React only (needs JavaScript)
- Source, gzipped
- 2.3 kB
- Dependencies
- React
Run pnpm add @equip/cli and log in with your org ID org_8f2KQ1
Try its options
Loading its options.
Code
import { CodeInline } from "@/components/equip/code-inline";
export default function Demo() {
return (
<p style={{ margin: 0, maxWidth: 208, fontSize: 13, lineHeight: 1.6, color: "var(--eq-ink-2)" }}>
Run <CodeInline>pnpm add @equip/cli</CodeInline> and log in with your org ID <CodeInline copy>org_8f2KQ1</CodeInline>
</p>
);
}Your versionchange its options in Look, This part
Examples
Copyable values
"Copied" is announced through a polite live region, and the button falls back to execCommand where the clipboard API is missing.
- Project ID
prj_4Xw9tLm2- Region
eu-west-1- Commit
9c41e07
Code
import { CodeInline } from "@/components/equip/code-inline";
export default function Example() {
return (
<dl style={{ display: "grid", gridTemplateColumns: "auto 1fr", gap: "8px 16px", margin: 0, fontSize: 14 }}>
<dt style={{ color: "var(--eq-ink-2)" }}>Project ID</dt>
<dd style={{ margin: 0, minWidth: 0 }}>
<CodeInline copy>prj_4Xw9tLm2</CodeInline>
</dd>
<dt style={{ color: "var(--eq-ink-2)" }}>Region</dt>
<dd style={{ margin: 0, minWidth: 0 }}>
<CodeInline copy>eu-west-1</CodeInline>
</dd>
<dt style={{ color: "var(--eq-ink-2)" }}>Commit</dt>
<dd style={{ margin: 0, minWidth: 0 }}>
<CodeInline copy="9c41e07b2d5fa8836e1f0c4b7d2a915e3f6b08cd" copyLabel="Copy full commit hash">9c41e07</CodeInline>
</dd>
</dl>
);
}Long tokens
Long paths and hashes break anywhere rather than pushing the column wider than the screen.
The export is saved to s3://acme-reports-eu/exports/2026/q3/revenue_by_region_final.csv and kept for 30 days.
Code
import { CodeInline } from "@/components/equip/code-inline";
export default function Example() {
return (
<p style={{ margin: 0, maxWidth: 260, fontSize: 14, lineHeight: 1.6 }}>
The export is saved to <CodeInline>s3://acme-reports-eu/exports/2026/q3/revenue_by_region_final.csv</CodeInline> and
kept for 30 days.
</p>
);
}In running text
The em-based padding and size follow whatever text the code sits in, from a hint to a heading.
Configure retry_limit
Set retry_limit to 0 to turn retries off. The default is 3.
Reads RETRY_LIMIT from the environment when it is set.
Code
import { CodeInline } from "@/components/equip/code-inline";
export default function Example() {
return (
<div style={{ display: "grid", gap: 12, maxWidth: 420 }}>
<h3 style={{ margin: 0, fontSize: 18 }}>
Configure <CodeInline>retry_limit</CodeInline>
</h3>
<p style={{ margin: 0, fontSize: 14, lineHeight: 1.6 }}>
Set <CodeInline>retry_limit</CodeInline> to <CodeInline>0</CodeInline> to turn retries off. The default is{" "}
<CodeInline>3</CodeInline>.
</p>
<p style={{ margin: 0, fontSize: 12, color: "var(--eq-ink-2)" }}>
Reads <CodeInline>RETRY_LIMIT</CodeInline> from the environment when it is set.
</p>
</div>
);
}Props
| Prop | Type | Default | What it does |
|---|---|---|---|
copy | boolean | string | false | Adds a copy button. true copies the text as shown; a string copies that instead, such as a full hash behind a short one. |
copyLabel | string | none | Names the copy button. Defaults to Copy and the text when it is a string. |
...rest | ComponentProps<"code"> | none | Every native code attribute and ref, applied to the code element even in copy mode. |
Anatomy
| root | .eq-code-inline | The code element, with the same metrics as code inside prose. |
|---|---|---|
| group | .eq-code-inline-group | Copy mode only. An inline span around the code, the button and the status. |
| copy | .eq-code-inline-copy | Copy mode only. 24px, pulled into the line so it does not push it apart. |
| status | .eq-code-inline-sr | Copy mode only. A visually hidden polite live region. |
Keyboard
| EnterSpace | Copies the value when the copy button has focus. |
|---|
Notes
- Exists because prose only styles code inside .eq-prose; use this for code in a label, a hint, a table cell or a settings row.
- Kbd is for keys a person presses and code-block is for whole blocks with lines; this is for a short token in a sentence.
- Long tokens break anywhere rather than overflowing, since hashes and paths have no spaces to wrap at.
- Copied or Copy failed is announced through a polite live region that stays mounted, and the button's tick draws in.
- Copy uses the async clipboard and falls back to a temporary textarea and execCommand; if both fail it says so.
- The file is a client component only for copying; without copy it renders a plain code element.
Source
Two files, and they are the whole part. Open either to read it, copy it straight from its bar, or add the part to your loadout and install it with everything else you picked.
components/equip/code-inline.tsx111 lines
"use client";
import { useEffect, useRef, useState } from "react";
import type { ComponentProps } from "react";
import "./code-inline.css";
export type CodeInlineProps = ComponentProps<"code"> & {
/** Adds a copy button. `true` copies the text as shown; a string copies that instead. */
copy?: boolean | string;
/** Names the copy button. Defaults to "Copy" and the text. */
copyLabel?: string;
};
const COPIED_MS = 1600;
type CopyState = "idle" | "copied" | "failed";
/** Last resort for browsers without the async clipboard: a throwaway textarea inside the part. */
function legacyCopy(text: string, host: HTMLElement) {
const active = document.activeElement;
const area = document.createElement("textarea");
area.value = text;
area.setAttribute("readonly", "");
area.setAttribute("aria-hidden", "true");
area.style.position = "fixed";
area.style.inset = "0 auto auto 0";
area.style.opacity = "0";
area.style.pointerEvents = "none";
host.appendChild(area);
area.select();
let ok = false;
try {
ok = document.execCommand("copy");
} catch {
ok = false;
}
host.removeChild(area);
if (active instanceof HTMLElement) active.focus();
return ok;
}
export function CodeInline({ copy = false, copyLabel, className, children, ...rest }: CodeInlineProps) {
const rootRef = useRef<HTMLSpanElement>(null);
const [copied, setCopied] = useState<CopyState>("idle");
useEffect(() => {
if (copied === "idle") return;
const t = window.setTimeout(() => setCopied("idle"), COPIED_MS);
return () => window.clearTimeout(t);
}, [copied]);
const code = (
<code {...rest} className={["eq-code-inline", className].filter(Boolean).join(" ")}>
{children}
</code>
);
if (copy === false) return code;
const shown = typeof children === "string" || typeof children === "number" ? String(children) : undefined;
const label = copyLabel ?? (shown != null ? `Copy ${shown}` : "Copy");
async function handleCopy() {
const text = typeof copy === "string" ? copy : (rootRef.current?.querySelector(".eq-code-inline")?.textContent ?? "");
let ok = false;
try {
if (navigator.clipboard?.writeText) {
await navigator.clipboard.writeText(text);
ok = true;
}
} catch {
ok = false;
}
if (!ok && rootRef.current) ok = legacyCopy(text, rootRef.current);
setCopied(ok ? "copied" : "failed");
}
return (
<span ref={rootRef} className="eq-code-inline-group">
{code}
{/* A word joiner, so the button never wraps onto a line of its own. */}
{""}
<button
type="button"
className="eq-code-inline-copy"
data-state={copied}
aria-label={label}
title={copied === "copied" ? "Copied" : copied === "failed" ? "Copy failed" : "Copy"}
onClick={handleCopy}
>
{copied === "copied" ? (
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
<path d="M3.5 8.5l3 3 6-7" pathLength={1} />
</svg>
) : copied === "failed" ? (
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" aria-hidden="true">
<path d="M8 4.5v4M8 11.25v.25" />
</svg>
) : (
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
<rect x="5.5" y="5.5" width="8" height="8" rx="1.5" />
<path d="M10.5 3.5v-.5A1.5 1.5 0 0 0 9 1.5H4A1.5 1.5 0 0 0 2.5 3v5A1.5 1.5 0 0 0 4 9.5h.5" />
</svg>
)}
</button>
<span className="eq-code-inline-sr" role="status">
{copied === "copied" ? "Copied" : copied === "failed" ? "Copy failed" : ""}
</span>
</span>
);
}components/equip/code-inline.css100 lines
@layer equip {
/* The same metrics as code inside .eq-prose, so the two read as one. */
.eq-code-inline {
padding: 0.1em 0.3em;
border-radius: var(--eq-radius-s);
background: var(--eq-tint);
color: inherit;
font-family: var(--eq-font-mono);
font-variation-settings: var(--eq-font-mono-settings);
font-size: 0.875em;
overflow-wrap: anywhere;
}
/* Inline, so a long token still breaks across lines with the button after its last piece. */
.eq-code-inline-group {
display: inline;
/* No break between the code and its button; the code itself still wraps. */
white-space: nowrap;
}
.eq-code-inline-group > .eq-code-inline {
white-space: normal;
}
.eq-code-inline-copy {
display: inline-grid;
place-items: center;
width: 24px;
height: 24px;
/* Pulled in above and below so the button never pushes the line apart. */
margin-block: -4px;
margin-inline: 2px 0;
padding: 0;
border: 0;
border-radius: var(--eq-radius-s);
background: transparent;
color: var(--eq-ink-3);
vertical-align: middle;
cursor: pointer;
transition:
background-color var(--eq-dur) var(--eq-ease),
color var(--eq-dur) var(--eq-ease),
scale var(--eq-dur) var(--eq-ease);
}
.eq-code-inline-copy > svg {
width: 14px;
height: 14px;
}
@media (hover: hover) {
.eq-code-inline-copy:hover {
background: var(--eq-tint);
color: var(--eq-ink);
}
}
.eq-code-inline-copy:active {
scale: var(--eq-press);
}
.eq-code-inline-copy:focus-visible {
outline: 2px solid var(--eq-focus);
outline-offset: 2px;
}
.eq-code-inline-copy[data-state="copied"] {
color: var(--eq-ok);
}
.eq-code-inline-copy[data-state="failed"] {
color: var(--eq-danger);
}
/* Copied: the tick draws itself in. */
.eq-code-inline-copy[data-state="copied"] path {
stroke-dasharray: 1;
stroke-dashoffset: 0;
transition: stroke-dashoffset var(--eq-dur-move) var(--eq-ease);
}
@starting-style {
.eq-code-inline-copy[data-state="copied"] path {
stroke-dashoffset: 1;
}
}
/* Read by screen readers, never seen. */
.eq-code-inline-sr {
position: absolute;
width: 1px;
height: 1px;
margin: -1px;
padding: 0;
overflow: hidden;
clip-path: inset(50%);
white-space: nowrap;
border: 0;
}
}