Skip to main content

Themes

CodePad ships with 3 themes: githubLight (the default), githubDark and oneDark. Each one is a plain object passed as theme.

import { useColorScheme } from 'react-native';
import { CodeEditor, githubDark, githubLight } from 'react-native-codepad';

export function Editor() {
const scheme = useColorScheme();
return <CodeEditor style={{ flex: 1 }} theme={scheme === 'dark' ? githubDark : githubLight} />;
}

The shape​

interface Theme {
background: string;
foreground: string;
gutterBackground: string;
gutterForeground: string;
gutterActiveForeground: string;
activeLine: string;
selection: string;
cursor: string;
matchingBracket: string;
searchMatch: string;
searchMatchActive: string;
tokens: Record<string, TokenStyle>;
}

type TokenStyle = string | { color: string; bold?: boolean; italic?: boolean };

Colors are #rrggbb or #rrggbbaa. selection, matchingBracket, searchMatch and searchMatchActive are drawn under the text, so give them some alpha. The theme tokens reference lists every value of the three themes.

Token lookup​

tokens is keyed by tree-sitter capture names such as keyword, keyword.return, punctuation.bracket or markup.heading.1. The lookup walks the dotted prefixes from the longest one down and ends at foreground, so a theme only needs the root names and can add a leaf wherever it wants a distinction.

The built-in themes cover every capture the fifteen packages produce. A theme from the nvim-treesitter ecosystem ports by renaming its keys: @keyword.return becomes keyword.return.

A custom theme​

Spread a built-in theme and override what you want:

import { githubDark, type Theme } from 'react-native-codepad';

export const midnight: Theme = {
...githubDark,
background: '#000000',
gutterBackground: '#000000',
tokens: {
...githubDark.tokens,
keyword: { color: '#ff9bce', bold: true },
'string.regexp': '#ffd27f',
comment: { color: '#6b7280', italic: true },
},
};

Hoist the object out of the render. The prop is compared by identity, so a literal written in JSX crosses to native on every render.

A theme built from scratch needs the root names: comment, keyword, string, number, function, variable, type, operator, punctuation, tag, attribute, constant, boolean, property, module, label, constructor, character and the markup.* keys. A missing root paints in foreground.

Bold and italic need a font that has those faces. The defaults, monospace on Android and Menlo on iOS, do.