v2.6.0

<bmx-json-editor>

One JSON document, three ways to work on it, and a fourth to see what changed: a tree (expand, edit values in place, rename keys, add, duplicate, move and delete, change a value's type), the text (the library's code editor with JSON highlighting, folding, search and underlined mistakes), a table of any array of objects (sortable, editable cells), and the changes against another version of the document.

21 properties · 3 events · 12 methods · 12 parts

Example

No changes yet.

Show markup
<bmx-json-editor id="ex-je" label="Service settings" name="settings" array-key="name" description="Checked against the service's JSON Schema as you edit. Try a negative timeout, or switch to Table on the regions."></bmx-json-editor>
<p class="note" id="ex-je-out" role="status" style="margin: 12px 0 0">No changes yet.</p>

<script type="module">
  await customElements.whenDefined('bmx-json-editor');
  const editor = document.getElementById('ex-je');
  const out = document.getElementById('ex-je-out');
  const published = {
    service: 'billing-api',
    version: '4.2.0',
    timeoutSeconds: 30,
    retries: { attempts: 3, backoff: 'exponential' },
    regions: [
      { name: 'eu-west', replicas: 3, primary: true },
      { name: 'us-east', replicas: 2, primary: false },
    ],
  };
  editor.schema = {
    type: 'object',
    required: ['service', 'version', 'timeoutSeconds', 'regions'],
    additionalProperties: false,
    properties: {
      service: { type: 'string', pattern: '^[a-z][a-z0-9-]*$', description: 'Lower case, letters, digits and hyphens.' },
      version: { type: 'string', pattern: '^\\d+\\.\\d+\\.\\d+$', description: 'Semantic version.' },
      timeoutSeconds: { type: 'integer', minimum: 1, maximum: 300, default: 30 },
      retries: {
        type: 'object',
        properties: { attempts: { type: 'integer', minimum: 0, maximum: 10 }, backoff: { enum: ['none', 'linear', 'exponential'] } },
      },
      regions: {
        type: 'array',
        minItems: 1,
        items: {
          type: 'object',
          required: ['name', 'replicas'],
          properties: { name: { enum: ['eu-west', 'eu-central', 'us-east', 'us-west', 'ap-south'] }, replicas: { type: 'integer', minimum: 1, default: 2 }, primary: { type: 'boolean', default: false } },
        },
      },
    },
  };
  editor.value = structuredClone(published);
  editor.compareWith = published;
  editor.addEventListener('bmxChange', event => {
    const { problems } = event.detail;
    out.textContent = problems.length ? `${problems.length} problem(s): ${problems[0].message}` : 'Valid - ready to publish.';
  });
</script>
<bmx-json-editor label="Settings" name="settings"
  value='{"name":"Acme","retries":3,"regions":["eu-west","us-east"]}'></bmx-json-editor>

Give it a JSON Schema (schema, 2020-12 or draft-07) and the document is checked as it is edited: broken rules are marked on their rows and lines and listed in a problems panel that takes you to each; the schema's titles and descriptions show beside keys, enum values become choices, and new members start from the schema's defaults. Nothing is fetched - $ref within the schema is followed, other documents are not.

Search finds keys and values (case and accents ignored) and narrows the tree to them; "Go to path" takes orders[3].total or /orders/3/total. The tree draws only the rows in view, so a document of hundreds of thousands of values opens and scrolls quickly. Every edit can be refused by cancelling bmxEdit, and undone (Ctrl+Z) and redone (Ctrl+Y).

value takes a JavaScript value, or JSON text (as an attribute must); the element writes back the same kind it was given. In a form, name receives the document as text.

Tree keyboard: arrows move and open/close, Home/End, Page Up/Down, Enter edits the value (or opens a container), F2 renames, Space flips true/false, Delete deletes, Insert adds after, Alt+Up/Down move, Ctrl+D duplicates, Ctrl+C copies the value, Shift+F10 or the context-menu key opens actions.

Properties

PropertyAttributeTypeDefaultDescription
arrayKey array-key string — A property that identifies array items (such as id), so changes match items by it rather than by place.
compareWith property only unknown — Another version of the document (value or JSON text) for the Changes view and the marks in the tree.
description description string — Help text below the editor.
disabled disabled boolean false Disable the editor.
errorText error-text string — An error supplied by the page.
expandDepth expand-depth number 2 How many levels of the tree start open.
hideLabel hide-label boolean false Hide the label visually while keeping it as the accessible name.
hideStatus hide-status boolean false Hide the status bar.
hideToolbar hide-toolbar boolean false Hide the toolbar.
indent indent number 2 Spaces per level in the text (0 writes one line).
label label string — The field's label: names the whole control.
name name string — The field's name in a form: it receives the document as text.
readonly readonly boolean false Allow reading, searching and copying, but not changing.
schema schema BmxJsonSchema | string — A JSON Schema (object or JSON text) the document is checked against.
schemaMessages schema-messages Record<string, string> | string — Schema messages in place of the English ones, by keyword (required, type, ...), as an object or JSON.
search search string '' What the search box holds. Two-way.
sortKeys sort-keys boolean false Sort object keys when writing the text.
strings strings Partial<BmxJsonEditorStrings> | string — Words to show instead of the English ones, as an object or JSON.
value property only unknown {} The document: any JavaScript value that is JSON, or JSON text. Two-way: written back in the kind it was given.
view view BmxJsonEditorView 'tree' The view shown. Two-way.
views views BmxJsonEditorView[] | string — The views offered, as an array, JSON or a comma list. Default: tree, text, table, and changes when compare-with is set.

Events

EventDetailDescription
bmxChange BmxJsonChangeDetail Fired after the document changes.
bmxEdit BmxJsonEditDetail Fired before an edit. Cancel it to refuse the edit.
bmxSelect BmxJsonSelectDetail Fired when the selected row changes.

Methods

MethodSignatureDescription
collapseAll collapseAll() => Promise<void> Closes every container but the root.
expandAll expandAll(depth?: number) => Promise<void> Opens every container (up to 5,000), or down to depth levels.
getChanges getChanges() => Promise<BmxJsonChange[]> The changes from compare-with to the current document.
getSelection getSelection() => Promise<BmxJsonSelectDetail> The selected place and its value.
getText getText(indent?: number) => Promise<string> The document as text; indent defaults to the element's.
getValue getValue() => Promise<BmxJsonValue> The document as a value (the last one that could be read, if the text has a mistake).
redo redo() => Promise<boolean> Redoes the last undone edit.
select select(path: BmxJsonPath | string) => Promise<boolean> Selects a place - a path array, a JSON Pointer or orders[3].total - opening its ancestors and scrolling to it. Returns false when there is nothing there.
setFocus setFocus() => Promise<void> Moves focus into the current view.
setValue setValue(value: unknown, options?: { keepHistory?: boolean; }) => Promise<void> Replaces the document. keepHistory lets the reader undo back to the previous one.
undo undo() => Promise<boolean> Undoes the last edit.
validate validate() => Promise<BmxJsonSchemaProblem[]> Schema problems in the current document.

Slots

SlotDescription
description Rich help text, in place of the description property.
label Rich label content, in place of the label property.

CSS shadow parts

PartDescription
changes The list of changes.
description The help text under the field.
key A key in a row.
label The label element.
menu The actions menu.
problems The problems panel.
row A tree row; also row-selected, row-problem, row-added, row-changed.
status The bar under the views.
table The table view.
toolbar The bar of views, search and commands.
tree The tree.
value A value in a row.

CSS custom properties

PropertyDescription
--bmx-json-editor-background The views' background.
--bmx-json-editor-height The height of the views' scrolling area.
--bmx-json-editor-indent How far each level of the tree is indented.
--bmx-json-editor-key-color Keys in the tree.
--bmx-json-editor-label-font-size The label's font size.
--bmx-json-editor-literal-color true, false and null.
--bmx-json-editor-number-color Number values.
--bmx-json-editor-radius Corner radius of the frame.
--bmx-json-editor-row-height The height of one tree or table row.
--bmx-json-editor-selected-background The selected row.
--bmx-json-editor-string-color String values.
--bmx-json-editor-support-font-size Font size of the description and error message.