Code
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/apogeeShow codeHide 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/apogeeShow codeHide 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 visiblefocus-visiblering 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 codeHide 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 / totalconst 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 24Show codeHide 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/apogeepnpm add @ava-ui/apogeeyarn add @ava-ui/apogeeShow codeHide 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 codeHide 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 passedShow codeHide code
<Code block>✓ 12 tests passed</Code>Block with copy, for install commands and config snippets:
pnpm add -D @ava-ui/apogeeShow codeHide 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 hasaria-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:hiddenand 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
copyfor 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
Codefor 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.