Code

The Code node renders syntax-highlighted code using Lezer. Grammars are loaded lazily per language, and built-in themes are provided. It offers animation methods for highlighting, replacing, inserting, and removing code.

Supported languages: typescript, tsx, javascript, jsx, python, json, html, css, rust, go, java, cpp, php, markdown, xml, and yaml.

0.0s / 3.2s

Install the package:

npm install @motion-script/code

Basic usage

import { createScene, createRef } from '@motion-script/core';
import { Code, lines, word } from '@motion-script/code';

export default createScene(function* (stage) {
  const ref = createRef<Code>();

  stage.add(
    <Code
      ref={ref}
      code={`function greet(name: string) {
  return \`Hello, \${name}!\`;
}`}
      fontSize={28}
      showLineNumbers={true}
    />
  );

  yield* ref().highlight(lines(2), 0.5);
});

Props

PropTypeDescription
codestringSource code to display
fontSizenumberFont size in pixels
showLineNumbersbooleanShow line number gutter

The highlighted language and color theme are configured via the @motion-script/code package settings. Themes are Lezer-based highlight styles (e.g. github-dark, github-light, vscode-dark, vscode-light) rather than Shiki themes.

Animation methods

All methods return a FrameGenerator and must be yield*-ed.

highlight(range, duration, easing?)

Visually highlight a range of code:

yield* ref().highlight(lines(2), 0.5);
yield* ref().highlight(word(3, 10, 9), 0.4);  // line 3, col 10, length 9

resetHighlight(duration, easing?)

Remove all highlights:

yield* ref().resetHighlight(0.3);

replace(range, text, duration, easing?)

Replace a range of code with new text:

yield* ref().replace(word(1, 22, 6), 'string', 0.3);

remove(range, duration, easing?)

Remove a range of code with an animated transition:

yield* ref().remove(lines(2), 0.4);

Range helpers

Import range helpers from @motion-script/code:

import { lines, word } from '@motion-script/code';

// Select line 2 (1-indexed)
lines(2)

// Select lines 2 through 5
lines(2, 5)

// Select a word: line 3, starting at column 10, length 9
word(3, 10, 9)

Full example

import { createScene, createRef, wait, parallel, easeOut } from '@motion-script/core';
import { Code, lines, word } from '@motion-script/code';

export default createScene(function* (stage) {
  const ref = createRef<Code>();

  stage.add(
    <Code
      ref={ref}
      code={`function getUser(id: number) {
  const user = db.find(id);
  return user.name;
}`}
      fontSize={32}
      showLineNumbers={true}
    />
  );

  yield* wait(0.5);

  // Highlight line 2
  yield* ref().highlight(lines(2), 0.5);
  yield* wait(0.6);

  // Highlight a specific word
  yield* ref().highlight(word(3, 10, 9), 0.4);
  yield* wait(0.6);

  // Clear highlight
  yield* ref().resetHighlight(0.4);
  yield* wait(0.3);

  // Replace a token
  yield* ref().replace(word(1, 22, 6), 'string', 0.3, easeOut('quad'));
  yield* wait(0.5);

  // Remove a line
  yield* ref().remove(lines(2), 0.4);
  yield* wait(1);
});