Code.Movie

Blog / Conditional Theming with Dark Mode support in 0.0.29

The release of Code.Movie 0.0.29 adds conditional theming, which (among other things) unlocks dark mode support. Code.Movie is a JavaScript library that animates source code for the web - imagine a combination of git diffs, syntax highlighting, code annotations and CSS transitions.

1234
[,]"World""Hello"
➡️🚫
[]
["World"]
["Hello", "World"]
[
  "Hello",
  "World"
]
[
  "World",
  "Hello"
]

New in 0.0.29: conditional themes and dark mode support

Code.Movie generates CSS from theme objects, but has until now only been able to do so for one theme at a time:

import { animateHTML, monokaiLight } from "@codemovie/code-movie";
import json from "@codemovie/code-movie/languages/json";

const language = json();

let keyframes = [
  /* keyframes go here */
];

let html = animateHTML(keyframes, {
  tabSize: 2,
  language,
  theme: monokaiLight, // but what about dark mode?
});
➡️1234567891011121314
import { animateHTML, monokaiLight } from "@codemovie/code-movie";
import json from "@codemovie/code-movie/languages/json";

const language = json();

let keyframes = [
  /* keyframes go here */
];

let html = animateHTML(keyframes, {
  tabSize: 2,
  language,
  theme: monokaiLight, // but what about dark mode?
});

The newly added conditional themes feature enables Code.Movie to generate CSS from themes with an attached condition, such as a media query or a parent selector. To use this feature, pass an array of themes with conditions in place of a single theme object:

import { animateHTML, monokaiLight, monokaiDark } from "@codemovie/code-movie";
import json from "@codemovie/code-movie/languages/json";

const language = json();

let keyframes = [
  /* keyframes go here */
];

let html = animateHTML(keyframes, {
  tabSize: 2,
  language,
  theme: [
    // Light theme with condition for light mode
    { theme: monokaiLight, condition: "@media (prefers-color-scheme: light)" },
    // Dark theme with condition for dark mode
    { theme: monokaiDark, condition: "@media (prefers-color-scheme: dark)" },
  ],
});
➡️➡️12345678910111213141516171819
import { animateHTML, monokaiLight, monokaiDark } from "@codemovie/code-movie";
import json from "@codemovie/code-movie/languages/json";

const language = json();

let keyframes = [
  /* keyframes go here */
];

let html = animateHTML(keyframes, {
  tabSize: 2,
  language,
  theme: [
    // Light theme with condition for light mode
    { theme: monokaiLight, condition: "@media (prefers-color-scheme: light)" },
    // Dark theme with condition for dark mode
    { theme: monokaiDark, condition: "@media (prefers-color-scheme: dark)" },
  ],
});

The condition can be a selector or the "header" of any relevant block at-rule, such as @media and @supports. The CSS generator will then wrap the CSS it creates for each theme in a new CSS block and prefix it with the string in condition. The CSS for the above example will therefore look something like this:

@media (prefers-color-scheme: light) {
  /* CSS generated from monokaiLight */
}
@media (prefers-color-scheme: dark) {
  /* CSS generated from monokaiDark */
}
123456
@media (prefers-color-scheme: light) {
  /* CSS generated from monokaiLight */
}
@media (prefers-color-scheme: dark) {
  /* CSS generated from monokaiDark */
}

More information on conditional themes in available in the guide to dark/light mode.

Other changes in 0.0.29

  • Improvements to animation heuristics
  • Improved style isolation, featuring a built-in CSS reset
  • properly type the instanceof keyword in ECMAScript as well as async method definitions and setters in ECMAScript object literals.
  • fix the theme variable --ui-status-bar-enabled not working in Monokai Dark