Installation
npm install @teasim/[email protected] @teasim/[email protected] @teacss/[email protected]yarn add @teasim/[email protected] @teasim/[email protected] @teacss/[email protected]pnpm add @teasim/[email protected] @teasim/[email protected] @teacss/[email protected]bun add @teasim/[email protected] @teasim/[email protected] @teacss/[email protected]Complete Astra setup for TeaCSS 0.7.1,
including its CSS declarations, presets, source scan, and SSR settings.
The highlighting is Astro’s own — the family wraps astro/components/Code.astro
rather than taking a Shiki dependency, and hands the frame, the header and the
copy button to CodeBlock. What a notation means is computation, so the
transformer set lives in @teasim/astro: teasim() hands it to
markdown.shikiConfig for you, and you pass it to <Code> yourself because a
component is not part of that pipeline.
Preview
export function brew(leaves: string) {
return 'Brewing ' + leaves;
}---
import { Code } from "@teasim/astra";
import { codeTransformers } from "@teasim/astro/shiki";
---
<Code code={source} lang="ts" title="src/brew.ts" transformers={codeTransformers()} />Examples
Line highlight
A range in the metastring marks the lines the paragraph is about.
export function brew(leaves: string) {
return 'Brewing ' + leaves;
}Diff
// [!code ++] and // [!code --] tint the line and sign it in the gutter the
padding already reserves.
export function steep(minutes: number) {
return minutes * 60;
return minutes * 60_000;
}Focus
// [!code focus] marks the relevant line with a surface and inset edge.
Surrounding code stays readable, and the focused line keeps a visible boundary
in forced-color mode.
export function pour(cups: number) {
const ml = cups * 240;
return ml;
}Error and warning
Line 2 is marked as a warning; line 3 is marked as an error. The line numbers and this description keep the annotations identifiable without their colors.
export function divide(a: number, b: number) {
if (b === 0) return null;
return a / b;
}Line numbers
The gutter is a CSS counter on Shiki’s own per-line spans, so it stays in step with whatever else a transformer added or removed.
export function brew(leaves: string) {
return 'Brewing ' + leaves;
}Word highlight
export function brew(leaves: string) {
return 'Brewing ' + leaves;
}In markdown
teasim() gives the same set to markdown.shikiConfig, so an ordinary fence
reads the same notation with nothing passed in. This one is a plain
```ts block — the frame around it is CodeBlock, which this site maps onto
markdown’s pre so a fence and a <Code> read the same:
export function steep(minutes: number) {
return minutes * 60;
return minutes * 60_000;
}API reference
| Prop | Type | What it does |
|---|---|---|
code |
string |
the source to highlight — required |
lang |
string |
any language Shiki bundles; plaintext by default |
meta |
string |
the metastring, where a {2-4} range or a /term/ lives |
lineNumbers |
boolean |
turns on the counter gutter |
transformers |
ShikiTransformer[] |
what Shiki runs over the tree — codeTransformers() |
themes, defaultColor |
Shiki’s own | GitHub’s high-contrast pair with defaultColor: false by default |
title, language, bodyLabel, copyable, copyLabel |
forwarded to CodeBlock; bodyLabel names the scrollable code region |
codeRecipe exposes source and takes a numbered selection.
The default light and dark themes follow Astra’s resolved
data-css-appearance on <html>. Use one
AppearanceScript rather than maintaining
a separate .dark class. The frame owns horizontal code scrolling; keep long
lines inside it so they do not widen the document. A code-copy button copies
only the listing and remains separate from page-level Markdown routes.