<.monaco_diff>: Monaco's diff editor, through Xenia's official adapter.
Setup
Install the library in your app:
npm install monaco-editor --prefix assetsPass it to the adapter, and register it, in assets/js/app.js:
import { createMonacoDiff } from "xenia/monaco-diff"
const monacoDiff = createMonacoDiff({
load: () => import("monaco-editor"),
})
hooks: { ...colocatedHooks, ...createHooks({ MonacoDiff: monacoDiff }) },Then import Xenia.Adapters.MonacoDiff in html_helpers, and render
<.monaco_diff id="..."> with the props below. Every event becomes an
on_<event> attribute; commands go through Xenia.push_to/4.
As a form field, field={@form[:x]} fills modified and submits the
component with the form.
The factory returns a plain adapter object: spread it to add or change props, commands and events, without copying the adapter.
The tag uses the adapter name "MonacoDiff". To register it under
another name, render <.xenia adapter="..."> or declare your own tag.
Reference
Xenia's official adapter for Monaco's diff editor: an original and a modified text side by side (or inline), with the modified side editable.
It follows the same conventions as monaco.js: the same value payload,
revision to force the server's text, form-field support with echo
handling, edits that bypass readOnly, and the editor mounted in a child
element so Monaco's data-* attributes survive LiveView patches.
Props:
original string, the left/old text. Always applied as given.
modified { value, version?, revision? } or a plain string; the
right/new text, as in monaco.js:
- with a `version` echoed from a change event, it is ignored
if the user has typed past it;
- without one it is authoritative;
- a changed `revision` forces it even over newer typing.
language Monaco language id, for both sides
theme theme name or theme definition (global, like monaco.js)
options diff editor options, e.g. %{renderSideBySide: false,
ignoreTrimWhitespace: false, readOnly: true,
originalEditable: false, wordWrap: "on"}Commands:
focus
next_diff, previous_diff jump between changes
reveal_line %{line, side?} side "modified" (default) or "original"Events:
change %{value, version} the user edited the modified side (300 ms)
diff %{changes, line_changes: [%{original_start, original_end,
modified_start, modified_end}]} the computed diff changed
error %{source, message, code}Form field: with field={@form[:code]}, the modified text is submitted with the form, exactly as in monaco.js.
The app owns Monaco's worker setup (MonacoEnvironment), as for monaco.js.
Summary
Functions
Attributes
id(:string) - Stable DOM id; defaults to field.id. Defaults tonil.field(Phoenix.HTML.FormField) - Phoenix form field for this component. Defaults tonil.original(:string) - Defaults to"".modified(:any)language(:string)theme(:any)options(:map)on_change(:string) - LiveView event triggered when the adapter emits :change. Defaults tonil.on_diff(:string) - LiveView event triggered when the adapter emits :diff. Defaults tonil.on_error(:string) - LiveView event triggered when the adapter emits :error. Defaults tonil.shortcuts(:map) - Key combination => LiveView event, while focus is inside (see Xenia.Shortcuts). Defaults to%{}.on_crash(:string) - LiveView event sent if the adapter throws (see Xenia.Component). Defaults tonil.- Global attributes are accepted.
Slots
loading- Shown until the island's first mount finishes.error- Shown if the adapter throws; data-xenia-retry starts it again.