Code

Code in text and in blocks, and the changes between two versions of a file.

StableSince 1.0.0
On this page

Import

import { Code, CodeBlock } from '@envsemble/envui/code';
import {
  CodeDiff,
  countDiffLines,
} from '@envsemble/envui/diff';

Usage

Code and CodeBlock come from @envsemble/envui/code, and CodeDiff and countDiffLines from @envsemble/envui/diff. Code wraps a command, a value or a file name inside text.

<Text>
  Run <Code>npm run build</Code> before you deploy.
</Text>

Code blocks

CodeBlock takes the source as one string in children, shown, highlighted and copied as it is.

  • language picks the highlighting, such as tsx, json or sh; without one, or with one it doesn't know, the source stays plain text.
  • label names the block in its header and for assistive technology, such as a file name, and copyable adds the copy button.
  • Long lines scroll sideways; wrap wraps them instead, and copying keeps the original line breaks.
HighlightedSource.tsx
import { CodeBlock } from '@envsemble/envui/code';

const source = `// Saves the draft
<Button onClick={save}>
  Save changes
</Button>`;

export default function HighlightedSource() {
  return (
    <CodeBlock language="tsx" label="SaveButton.tsx" copyable>
      {source}
    </CodeBlock>
  );
}

Diffs

CodeDiff takes before and after, and a filename, which names the file in its header and chooses the language; language overrides it.

  • header={false} leaves out the header with its name and change counts.
  • expandUnchanged shows the unchanged lines between changes instead of folding them.
  • layout is auto, the default, side by side from 56 rem of width, or unified, one column at any width.
  • Long lines wrap, each continuation hanging four characters in, so it doesn't read as a new line without a number.
  • countDiffLines(before, after, filename) returns the additions and deletions for a DiffStat.
const { additions, deletions } = countDiffLines(saved, draft, 'settings.json');

<DiffStat additions={additions} deletions={deletions} />
<CodeDiff filename="settings.json" before={saved} after={draft} />

Highlighting

envUI picks the code theme from the app theme: Shiki's github-light-default in the light theme and github-dark-dimmed, a grey dark theme, in the dark one, and github-light-high-contrast and github-dark-high-contrast under high contrast, with every token at 4.5:1 contrast, or 7:1 under high contrast.

  • Inline code sits on a faint layer of the neutral muted fill, the whole fill at high contrast, and blocks and diffs on a translucent layer of the text color, so they stand a step apart from any surface.
  • A diff takes the same code theme and token colors as a block, and tints its added and removed lines with their change color over that layer, faintly enough that every token keeps its contrast. In dark the line tints are quieter in color than the line numbers' gutter, which carries the change, so they don't compete with the token colors.
  • Code has no theme or color props of its own.

Customize

Inline code is one part, env-code. A block is env-code-block: its header, env-code-block-header, holds the label and the copy button, and the source is its pre; the copy result is announced from env-code-block-copy-status.

Accessibility

You provide

  • A label on each block where a page has several.
  • Text around a diff that says what changed.

envUI provides

  • Native code and pre, read as text.
  • A focusable source named by label or its language.
  • A copy button named Copy code, then Code copied, with the result announced.
  • A busy diff while it loads, and an error with Try again if it fails.

Props

Code

Inline source in the code theme of the app theme, the nearest Theme boundary's; use CodeBlock for multiline source.

No props of its own.

Also accepts the native props of <code>, such as ref, className and aria-* attributes.

CodeBlock

Source display in the code theme of the app theme, with that code theme's own colors; copy always uses the original string. Its words come from EnvUIProvider's messages.codeBlock.

PropTypeDescription
childrenrequired
string
The source, as one string; it is shown, highlighted and copied as it is.
language
string
The language to highlight: js, jsx, ts, tsx, java, json, html, xml, css, sql, sh, bash, yaml, md or ini, or their full names. Other values, and none, leave the source plain text.
label
string
Names the block in its heading and for assistive technology, such as a file name.
copyableDefault false
boolean
Shows a copy button in the heading that copies the source; false by default.
wrapDefault false
boolean
Wraps long lines instead of scrolling them; false by default.

Also accepts the native props of <div>, such as ref, className and aria-* attributes.

CodeDiff

The changes between two versions of a file, rendered by Diffs (diffs.com) in the code theme of the app theme, as code blocks are; the whole file when nothing changed.

PropTypeDescription
beforerequired
string
The source before the change.
afterrequired
string
The source after the change.
filenamerequired
string
Names the file in the header and chooses its language, such as form.json.
language
string
Overrides the language the file name implies, such as json.
headerDefault true
boolean
Shows the file header with its name and change counts; true by default.
expandUnchangedDefault false
boolean
Shows the unchanged lines between changes instead of folding them; false by default.
layoutDefault 'auto'
'auto''unified'
auto (default) sets old and new side by side from 56 rem of width; unified keeps one column.

Also accepts the native props of <div>, such as ref, className and aria-* attributes.

countDiffLines

How many lines a change adds and removes, as a DiffStat shows them.

countDiffLines(before: string, after: string, filename?: string): { additions: number; deletions: number; }

Part names

Each part's class and state attributes are public and versioned, for an application's CSS to style.

Code

env-code
Inline code.

CodeBlock

env-code-block
The block of code.
env-code-block-copy-status
The announcement that the code was copied.
env-code-block-header
The row above the code: its label, such as a file name, and the copy button.
data-wrap
Present

CodeDiff

env-code-diff
The diff of two versions of code.
env-code-diff-failed
What the diff shows when it fails to load: the error, a sentence and Retry, announced as an alert.
env-code-diff-failed-icon
The error icon of a diff that failed to load, in the danger color.

Strings

EnvUIProvider's messages overrides each, and a component's own label prop wins over it.

messages.codeBlock.title
"Code" The heading of a block without a label or language.
messages.codeBlock.copy
"Copy code" The copy button's name.
messages.codeBlock.copied
"Code copied" The copy button's name once the code is copied.
messages.codeBlock.copiedStatus
"Copied." Announced once the code is copied.
messages.codeBlock.label
({ language }) => string Names the code region, such as TypeScript code.
messages.codeBlock.plainText
"Plain text" The language of code without one.
messages.codeBlock.selected
"Code selected. Use your keyboard or context menu to copy." Announced when the clipboard is unavailable and the code is selected instead.
messages.codeDiff.failed
"Changes could not be shown" The title when the changes could not be shown.
messages.codeDiff.failedDescription
"The code highlighter did not load." Says why, under the title.
messages.codeDiff.retry
"Try again" The retry button's label.
messages.codeDiff.loading
"Loading changes" Names the region while the changes load.

Changelog

1.0.0

Code, CodeBlock, CodeDiff and Markdown's code use Shiki's github-light-default and github-dark-dimmed code themes instead of the Pierre themes, and github-light-high-contrast and github-dark-high-contrast under high contrast; envUI no longer needs @pierre/theme. The DiffCount that countDiffLines feeds is DiffStat. Highlighted tokens reach 4.5:1 in both app themes, and 7:1 under high contrast, in code blocks and code diffs. CodeDiff takes CodeBlock's code theme, token colors and translucent layer, instead of a theme and an opaque grey of its own. CodeBlock's and CodeDiff's words come from EnvUIProvider's messages; the copy button copies through the selection fallback that CopyButton uses, and its status is env-code-block-copy-status. The row above a block's code, env-code-block-heading, is env-code-block-header.

1.0.0-prerelease.6

Inline code is quieter in running text: the monospace carries it, on half the neutral muted fill, and high contrast keeps the whole fill.

A CodeDiff line that wraps hangs its continuation four characters in.

In dark, CodeDiff's changed lines take a less saturated tint, and the line numbers' gutter keeps the full change color.