C&C Docs
Log in

cnc-code

Two widgets in one element. With readonly it is a syntax-highlighted snippet, rendered entirely on the server with a copy button and no JavaScript at all. Without it, the snippet is a first paint that upgrades into a full Ace editor once the library arrives — and stays a readable snippet if it never does.

Quick start

For showing code, which is the common case: bind $code, name the language, and add readonly.

function greet(name) {
  return `Hello, ${name}!`
}

const names = ['Ada', 'Grace', 'Alan']
console.log(names.map(greet).join('\n'))
<cnc-code language="javascript" readonly $code="jsSample"></cnc-code>

Snippet or editor

The readonly attribute is the fork in the road, and it decides more than whether the text can be typed into.

readonly editable
JavaScript None. Nothing is fetched, nothing hydrates. Ace, from a CDN, on mount.
Highlighting The built-in server highlighter — HTML, JavaScript and TypeScript. Ace's, which covers a hundred-odd languages.
Copy button Yes. No.
Long class lists Collapsed to …, click to expand. Shown in full.
Offline Unaffected. Falls back to the same read-only snippet rather than showing a blank box.

So readonly is not "an editor that refuses input" — that is disabled. Use readonly for documentation and log output, where paying for an editor makes no sense.

Things to know

  • There is no transparent property. The previous version of this page passed transparent="true"; nothing reads it. The snippet's background comes from the stylesheet.
  • code is two-way, and the editor is the one writing. Bind it with $code and the editor opens on that value and writes every keystroke back to it — no change listener needed. A page-side change still reaches the editor, unless the reader has it focused: whoever is typing keeps the buffer.
  • The change event and name are still there. change carries { value } for a handler that wants to do more than store the text, and name renders a hidden input that follows the typing. Reach for them when a binding is not what you want, not because a binding does not work.
  • The copy button only exists in readonly mode. An editable editor has no copy affordance of its own — the user selects and copies, as in any text field.
  • An editor needs the network once. Ace is fetched from cdnjs.cloudflare.com. Where it cannot be reached the widget keeps the server-rendered snippet, so the code is still readable — but not editable, and nothing says so.
  • language is passed to Ace verbatim. It becomes ace/mode/<language>, so it has to be a mode Ace knows — javascript, not js. The server highlighter is more forgiving and accepts the short forms, which means a wrong value can highlight correctly before hydration and stop afterwards.
  • The editor's theme follows the page, the snippet's colours do not. Ace re-themes live when the colour mode flips. The read-only highlighter emits fixed dark: utility classes instead, which do the same job through CSS.

Usage guidance

Reach for readonly whenever the code is only to be read — documentation, a configuration preview, a log. It costs nothing to ship and is complete before any script runs. Save the editor for the places a user genuinely types code, and give it a name or a $code binding so the text goes somewhere. For prose with the occasional inline snippet, cnc-markdown renders fenced code blocks itself; for a read-only value in a table cell, cnc-display type="code" is smaller again.

← Back to Widgets