type
Code block
A block of code with a header for its name and a copy button, that scrolls sideways when wide.
Rich widgetNeeds a script for its behavior.
Usage
A <figure> with a <figcaption> header: the title names the code, the actions hold a copy button. data-ca-copy points at the <pre>.
@import "tailwindcss";
@import "@calaca/ui/core.css";
@import "@calaca/ui/skins/base.css";
<figure class="ca-code-block w-full max-w-lg">
<figcaption class="ca-code-block__header">
<span class="ca-code-block__title">global.css</span>
<span class="ca-code-block__actions">
<button class="ca-button ca-button--ghost ca-button--sm" type="button" data-ca-copy="stylesheet-code">Copy code</button>
</span>
</figcaption>
<pre class="ca-code-block__code" id="stylesheet-code" tabindex="0"><code>@import "tailwindcss";
@import "@calaca/ui/core.css";
@import "@calaca/ui/skins/base.css";</code></pre>
<p class="ca-code-block__status" role="status"></p>
</figure>Examples
Without a header
Leave the header out for short snippets; give the <pre> an aria-label instead.
bun add @calaca/ui tailwindcss
<figure class="ca-code-block w-full max-w-lg">
<pre class="ca-code-block__code" tabindex="0" aria-label="Install command"><code>bun add @calaca/ui tailwindcss</code></pre>
</figure>Guidance and accessibility
When to use
- Use a code block for snippets people copy, such as configuration or markup.
- Name the code in the header, with the file name when people paste it into a file.
- Add syntax colors with your highlighter of choice; the block sets the frame, font and scrolling.
Accessibility
- Lines do not wrap, so code keeps its shape. Give the
<pre>tabindex="0", so keyboard users can reach and scroll it. - The copy button names its action in words.
ca-copy.jscopies the text of the element indata-ca-copyand announces the result in the status part. A text-only button also reads “Copied” for two seconds, so sighted people see the result where they clicked;data-ca-copied-labelchanges the word. - The
<figcaption>names the figure for screen readers.
Classes
Generated from the component contract. Parts use __, modifiers use --.
| Class | Kind | Use it for |
|---|---|---|
ca-code-block | Component | The <figure> around the header and the code. |
ca-code-block__header | Part | The <figcaption> with the title and the actions. |
ca-code-block__title | Part | What the code is, such as the language or the file name. |
ca-code-block__actions | Part | Buttons such as Copy code. |
ca-code-block__code | Part | The <pre>: keeps its lines and scrolls sideways. |
ca-code-block__status | Part | Visually hidden live region that announces a copy. |
Skins
The same markup, dressed by each skin. Structure and behavior stay the same; only the look changes.
Base skin
Neutral grayscale starting point; product skins extend it and change what differs.
@import "tailwindcss";
@import "@calaca/ui/core.css";
@import "@calaca/ui/skins/base.css";
Calaca skin
The Calaca UI brand: hueso paper and tinta ink, cempasúchil marigold, rosa and jade.
@import "tailwindcss";
@import "@calaca/ui/core.css";
@import "@calaca/ui/skins/base.css";
Proof skin
Pilot skin pushed far from base: square, heavy, offset shadows, larger targets.
@import "tailwindcss";
@import "@calaca/ui/core.css";
@import "@calaca/ui/skins/base.css";
Crossview skin
The CrossView proofing table: cool ground, bond-paper sheets, rule-grey hairlines, one red mark.
@import "tailwindcss";
@import "@calaca/ui/core.css";
@import "@calaca/ui/skins/base.css";
Framework notes
Link the prebuilt stylesheet of your skin next to your brand theme. No build step.
<link rel="stylesheet" href="theme.css" />
<link rel="stylesheet" href="ca-base.css" />In Astro, Vite and other Tailwind projects, import Calaca after Tailwind and your theme in your main stylesheet.
@import "tailwindcss";
@import "./theme.css";
@import "@calaca/ui/core.css";
@import "@calaca/ui/skins/base.css";Same stylesheet as above; write the classes in className.
<button className="ca-button ca-button--primary ca-button--md" type="button">Save changes</button>Load the copy script once per page; every button with data-ca-copy then copies the text of the element it names. In Astro or Next.js, import @calaca/ui/behavior/copy once in the layout.
<script type="module" src="ca-copy.js"></script>