Inline code or a code block with build-time highlighting, line numbers, a copy button and a collapsible long view.

Last updated

Uses JavaScript

Copies the block’s text to the clipboard on click, then swaps the icon to a checkmark and shows a “Copied” label for 3 seconds. With maxHeight, a Show more button expands and collapses the block.

Without JS: The copy button and the Show more toggle (`no-js:hidden`) don't render. The code stays visible and selectable, and a collapsed block scrolls instead.

npm install @ava-ui/apogee
Show code
<Code copy>npm install @ava-ui/apogee</Code>

Add

npx @ava-ui/apogee add code

No Apogee dependencies. Uses @lucide/astro internally (Copy, Check) for the copy button — no icon import needed in your usage.

Usage

---
import Code from '@/components/apogee/Code/Code.astro'
---
Run <Code>npm i</Code> to install.

<Code block>const x = 1</Code>
<Code copy>const x = 1</Code>

API

@composable — exposed to Content Editors in AVA. Any other native <code> / <pre> / <div> attribute (e.g. aria-label) passes through to the root element.

Prop Type Default Description
block boolean false Renders a block <pre> panel instead of inline <code>.
copy boolean false Adds a copy-to-clipboard button. Implies block.
lang string — Syntax-highlights at build time (both themes). Implies block. Requires code; without it the slot renders plain.
code string — Source to highlight when lang is set.
lineNumbers boolean false Numbers each line (CSS counters; copying skips them). Needs lang and code.
maxHeight string — Collapses a long block to this height with a “Show more” toggle (JS); without JS the block scrolls.
class string — Extra classes, merged last.

Variants

The three render modes — inline, block, and block with copy:

npm i
{ "name": "apogee" }
npm install @ava-ui/apogee
Show code
<Code>npm i</Code>
<Code block>{'{ "name": "apogee" }'}</Code>
<Code copy>npm install @ava-ui/apogee</Code>

States

  • Default — copy button shows a copy icon, muted-foreground colour.
  • Hover / focus — button background shifts to --background-neutral-faded; a visible focus-visible ring on keyboard focus.
  • Copied — icon swaps to a checkmark, button turns --foreground-positive, and a “Copied” label fades in for 3 seconds (role="status").
git commit -m “fix: copy button”
Show code
<Code copy>git commit -m "fix: copy button"</Code>

Examples

Highlighted (build time, follows the theme):

Line numbers, and a long block collapsed to 10rem:

const total = items.length
const done = items.filter((i) => i.done).length
export const progress = done / total
const step1 = await run(1) // step 1
const step2 = await run(2) // step 2
const step3 = await run(3) // step 3
const step4 = await run(4) // step 4
const step5 = await run(5) // step 5
const step6 = await run(6) // step 6
const step7 = await run(7) // step 7
const step8 = await run(8) // step 8
const step9 = await run(9) // step 9
const step10 = await run(10) // step 10
const step11 = await run(11) // step 11
const step12 = await run(12) // step 12
const step13 = await run(13) // step 13
const step14 = await run(14) // step 14
const step15 = await run(15) // step 15
const step16 = await run(16) // step 16
const step17 = await run(17) // step 17
const step18 = await run(18) // step 18
const step19 = await run(19) // step 19
const step20 = await run(20) // step 20
const step21 = await run(21) // step 21
const step22 = await run(22) // step 22
const step23 = await run(23) // step 23
const step24 = await run(24) // step 24
Show code
<Code lang="ts" code={src} lineNumbers copy />
<Code lang="ts" code={longSrc} lineNumbers maxHeight="10rem" />

Tabbed install commands: Tabs with a copyable block per panel.

npm i @ava-ui/apogee
pnpm add @ava-ui/apogee
yarn add @ava-ui/apogee
Show code
<Tabs variant="pills" tabs={['npm', 'pnpm', 'yarn']}>
<Code slot="panel-0" copy>npm i @ava-ui/apogee</Code>
…
</Tabs>
export const greet = (name: string) => 'Hello, ' + name
.card { border-radius: var(--radius-lg); }
<button class="bg-primary text-on-primary">Save</button>
Show code
<Code lang="ts" copy code={tsSnippet} />
<Code lang="css" code={cssSnippet} />
<Code lang="html" code={htmlSnippet} />

Inline, in prose:

Run <Code>npm i</Code> before starting the dev server.

Block, no copy button (e.g. read-only output):

✓ 12 tests passed
Show code
<Code block>✓ 12 tests passed</Code>

Block with copy, for install commands and config snippets:

pnpm add -D @ava-ui/apogee
Show code
<Code copy>pnpm add -D @ava-ui/apogee</Code>

Accessibility

  • The copy button is a real <button> — focusable and operable with Enter/Space, and has aria-label="Copy code".
  • The “Copied” confirmation is a role="status" label so it’s announced to screen readers without stealing focus.
  • No JS: the copy button carries no-js:hidden and never renders — the code text itself is always selectable, so copying by hand still works.
  • The copied-state transition respects prefers-reduced-motion.

Tokens

Token Used for
--border-neutral Inline <code> and block <pre> border
--background-neutral-faded Inline code background
--background-page-faded Block background
--background-neutral-faded-highlighted Copy and Show more button hover
--background-page Copy button background
--foreground-neutral Code text; copy button hover/copied text
--foreground-neutral-faded Copy button default icon/text colour
--foreground-positive Copy button “copied” colour
--outline-color-focus Focus ring
--duration-fast / --ease-standard “Copied” label fade transition

Do / Don’t

  • Do use copy for anything a reader will paste elsewhere — install commands, config, CLI output.
  • Do use inline <Code> for short identifiers, flags, and filenames in prose.
  • Don’t use Code for large syntax-highlighted files — pair Astro’s built-in Shiki / Expressive Code in Markdown for that; this is the bare styled element.
  • Don’t pad the content with extra leading/trailing whitespace — it gets copied along with the code.

Content

  • Keep inline code to short tokens (a command, a flag, a filename); move anything longer into a block.
  • Block content is literal source — no explanatory prose inside the block.