Skip to content本文へ移動

@celesta/code

Syntax-highlighted code, with themes and line highlights.

@celesta/code draws syntax-highlighted source code in a composition. It tokenizes with twinkleplop and draws each line as one of Celesta’s own Text layers with color runs, and line highlights as Rects, so code scales, fades, blurs, and exports like any other layer. It is optional: @celesta/react does not depend on it.

Your first code block

import { Assets, Composition, Font, Rect } from '@celesta/react';
import { Code, codeThemes } from '@celesta/code';

const source = `const message: string = 'Hello, Celesta.';
console.log(message);`;

const style = { fontFamily: 'IBM Plex Mono', fontSize: 40, lineHeight: 60 };

export default function Root() {
  return (
    <Composition width={1280} height={480} fps={30} durationInFrames={90}>
      <Assets>
        <Font src="./fonts/IBMPlexMono-Regular.ttf" />
      </Assets>
      <Rect width={1280} height={480} fill="#161418" />
      <Code x={64} y={64} language="ts" style={style} theme={codeThemes.dark}>
        {source}
      </Code>
    </Composition>
  );
}

Code takes the source as its only child, as a string. Keep indentation and trailing newlines inside the string: they are part of the picture.

Fonts

Use a monospaced font. Code defaults to JetBrains Mono at 24 px with a line height of 1.5 × the font size. Load the font file with <Font src="…" />, as above, or install it on the machine that renders. If the font is missing, Celesta falls back as it does for any text.

Props

Code props

API Use it for
children The source, as a string.
language tsx, ts, json, bash, or text (the default, which applies no coloring).
style A Celesta TextStyle: fontFamily, fontSize, lineHeight, and so on. Text is left aligned and never wraps, and the theme supplies each run’s fill color. Other align values throw.
theme Token colors, a foreground fallback, and the line highlight color. codeThemes.dark by default.
tabSize Width of a tab stop, counted in characters. Defaults to 2.
highlightLines One-based line numbers to mark with a highlight band.
highlightWidth Band width in pixels. Defaults to the width of the source; set it to reach the edge of a surrounding panel.
visibleCharacters How much of the source to show, for typing effects. See code: typing, carets & tokens.
x, y, scale, rotation, anchorX/anchorY, opacity, blendMode, blur, shadow, glow The usual layer props apply to the whole block.

Line highlights

highlightLines draws a band behind the lines you name, full width and full line height, even while the code is still being typed:

<Code x={64} y={64} language="ts" style={style} highlightLines={[2]} highlightWidth={1152}>
  {source}
</Code>

Animate the highlight by changing the list as the frame advances; each band is cheap, so highlighting a line per beat or per cue is fine.

Themes

codeThemes.dark and codeThemes.light are ready to use. A theme does not draw a panel background: place a Rect behind the code, sized to your design. To customize, spread a built-in theme and override what you need:

const theme = {
  ...codeThemes.dark,
  highlightLine: '#a68bbf30',
  tokens: { ...codeThemes.dark.tokens, keyword: '#e0b7ff' },
};

Token names are twinkleplop’s, such as keyword, string, comment, number, function, type, tag_name, attr_name, punctuation, and operator. In JSON, object keys are property; string values keep string and string_escape. A name your theme does not list uses foreground.

Continue with typing effects, carets, and tokens.

Try it without installing.

The playground runs Celesta in your browser, export included.

Open the playground