<bmx-yaml-editor>
Configuration files edited in the page: YAML (1.2, or 1.1), TOML, INI, Java .properties and .env, as text (the library's code editor with colouring, folding and completion) or as a tree (edit values and keys in place, add, move, duplicate, comment out and delete), and compared with another version.
28 properties · 4 events · 18 methods · 10 parts
Example
Try it with your own configuration files in confidence: they are opened by your browser, on your device. Nothing is uploaded, no copy reaches us or anyone else, and nothing is kept once you close this tab.
Checking...
Show markup
<bmx-yaml-editor id="ex-ye" label="Deployment manifest" name="manifest" file-name="harbour-shop.yaml" compare-label="As deployed on Monday" description="Each document is checked against the schema for its kind as you edit. Try replicas: 0, or press Ctrl+Space on a new line under spec to see what can go there."></bmx-yaml-editor>
<p class="note" id="ex-ye-out" role="status" style="margin: 12px 0 0">Checking...</p>
<script type="module">
await customElements.whenDefined('bmx-yaml-editor');
const editor = document.getElementById('ex-ye');
const out = document.getElementById('ex-ye-out');
// Made-up schemas for a made-up shop's three kinds of document, chosen per document by its `kind`.
const metadata = {
type: 'object',
required: ['name'],
properties: {
name: { type: 'string', pattern: '^[a-z0-9-]+$', description: 'Lower-case letters, digits and dashes.' },
labels: { type: 'object', additionalProperties: { type: 'string' } },
},
};
const deployment = {
type: 'object',
required: ['apiVersion', 'kind', 'metadata', 'spec'],
properties: {
apiVersion: { const: 'apps/v1' },
kind: { const: 'Deployment' },
metadata,
spec: {
type: 'object',
required: ['replicas', 'template'],
properties: {
replicas: { type: 'integer', minimum: 1, maximum: 20, description: 'How many copies of the shop run at once.' },
strategy: { enum: ['RollingUpdate', 'Recreate'], description: 'How new versions replace old ones.' },
template: {
type: 'object',
properties: {
metadata: { type: 'object', properties: { labels: metadata.properties.labels } },
spec: {
type: 'object',
properties: {
containers: {
type: 'array',
minItems: 1,
items: {
type: 'object',
required: ['name', 'image'],
properties: {
name: { type: 'string' },
image: { type: 'string', pattern: ':[\\w.-]+$', description: 'An image with its version tag.' },
ports: { type: 'array', items: { type: 'object', properties: { containerPort: { type: 'integer', minimum: 1, maximum: 65535 } } } },
env: { type: 'array', items: { type: 'object', required: ['name'], properties: { name: { type: 'string' }, value: { type: 'string' } } } },
resources: { type: 'object', properties: { memory: { type: 'string' }, cpu: { type: 'string' } } },
},
},
},
},
},
},
},
},
},
},
};
const service = {
type: 'object',
required: ['kind', 'metadata', 'spec'],
properties: {
kind: { const: 'Service' },
metadata,
spec: {
type: 'object',
properties: {
type: { enum: ['ClusterIP', 'NodePort', 'LoadBalancer'] },
ports: { type: 'array', items: { type: 'object', required: ['port'], properties: { port: { type: 'integer', maximum: 65535 }, targetPort: { type: 'integer' } } } },
},
},
},
};
const settings = {
type: 'object',
properties: { kind: { const: 'ConfigMap' }, metadata, data: { type: 'object', additionalProperties: { type: 'string' } } },
};
const deployed = `# Harbour Shop - the web tier and its settings.
apiVersion: apps/v1
kind: Deployment
metadata:
name: harbour-shop
labels: &labels
app: harbour-shop
tier: web
spec:
replicas: 2
strategy: RollingUpdate
template:
metadata:
labels: *labels
spec:
containers:
- name: shop
image: registry.example.test/harbour-shop:4.1.0
ports:
- containerPort: 8080
env:
- name: CURRENCY
value: GBP
- name: CHECKOUT_TIMEOUT
value: "30" # seconds, as text
resources: &small
memory: 256Mi
cpu: 250m
---
apiVersion: v1
kind: Service
metadata:
name: harbour-shop
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 8080
---
apiVersion: v1
kind: ConfigMap
metadata:
name: harbour-shop-settings
data:
theme: harbour
# YAML 1.1 tools read the next value as false.
maintenance: off
`;
editor.schema = [
{ match: { kind: 'Deployment' }, schema: deployment, name: 'Deployment' },
{ match: { kind: 'Service' }, schema: service, name: 'Service' },
{ match: { kind: 'ConfigMap' }, schema: settings, name: 'Settings' },
];
// Now: one more copy running, and the next version of the image.
editor.value = deployed.replace('replicas: 2', 'replicas: 3').replace('harbour-shop:4.1.0', 'harbour-shop:4.2.0');
editor.compareWith = deployed;
const report = ({ ok, valid, problems }) => {
const errors = problems.filter(p => p.severity === 'error');
if (!ok) out.textContent = `Not valid YAML: ${errors[0]?.message ?? ''}`;
else if (!valid) out.textContent = `${errors.length} problem${errors.length === 1 ? '' : 's'} against the schemas: ${errors[0].message}`;
else out.textContent = `Valid against each document's schema${problems.length ? ` (${problems.length} note${problems.length === 1 ? '' : 's'})` : ''} - ready to deploy.`;
};
editor.addEventListener('bmxValidate', event => report(event.detail));
await editor.validate();
</script>
<bmx-yaml-editor label="Deployment" name="manifest"></bmx-yaml-editor>
<script>
editor.schema = [
{ match: { kind: 'Deployment' }, schema: deploymentSchema },
{ match: { kind: 'Service' }, schema: serviceSchema },
];
editor.value = manifestText;
</script>
Every mistake in the text is underlined where it is, in plain words, and
each document is checked against its JSON Schema - one schema for all, or
one chosen per document by the values it holds (kind: Deployment) or the
schema it names in a # yaml-language-server: $schema= comment. Completion
offers the keys a mapping can still have, required ones first, and the
values a key allows. Plain values that YAML 1.1 tools read differently
(no, on, 012) are pointed out.
Edits in the tree change only the characters they must, so comments,
quoting, anchors and blank lines stay as they were; Format lays a YAML file
out again with one indentation step and keeps every comment. Anchors,
aliases and merge keys are shown and followed. Every edit can be refused
(cancel bmxEdit) and undone. Convert, copy or save as YAML, JSON, TOML,
INI, .properties or .env.
Nothing leaves the page: schemas are what you give (schema, or
schema-src for the page's own copy) and files are opened from the
device. In a form, name receives the text; require-valid keeps the form
from submitting until every document is valid.
Tree keyboard: arrows move and open/close, Home/End, Page Up/Down, Enter edits a value (or opens a mapping), F2 renames, Delete deletes, Insert adds, Alt+Up/Down move, Ctrl+D duplicates, Ctrl+C copies the entry as YAML, Shift+F10 or the context-menu key opens actions.
Properties
| Property | Attribute | Type | Default | Description |
|---|---|---|---|---|
checking |
checking |
boolean |
true |
Check the text as it changes (its own rules always; the schema when there is one). |
compareLabel |
compare-label |
string |
— | What the original side of the comparison is called. |
compareWith |
compare-with |
string |
— | Another version of the text, for the Compare view. |
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. |
fileName |
file-name |
string |
— | The file's name: chooses the format when it is auto, and names saved files. |
format |
format |
BmxYamlEditorFormat |
'auto' |
How the text is read: yaml, toml, ini, properties, env, or auto (from file-name, else the text). |
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 |
— | Spaces per level for new and formatted YAML. Default: what the file uses. |
label |
label |
string |
— | The field's label: names the whole control. |
name |
name |
string |
— | The field's name in a form: it receives the text. |
readonly |
readonly |
boolean |
false |
Allow reading, searching and copying, but not changing. |
requireValid |
require-valid |
boolean |
false |
Keep the form from submitting until the text has no mistakes and every document is valid. |
schema |
schema |
BmxYamlSchemas | string |
— | The JSON Schema for every document, or rules that choose one per document: [{ match: { kind: 'Service' }, schema }, { uri: 'app.json', schema }, { schema }]. |
schemaMessages |
schema-messages |
Record<string, string> | string |
— | Schema messages in place of the English ones, by keyword (required, type, enum, ...), as an object or JSON. |
schemaSrc |
schema-src |
string |
— | An address of a JSON (or YAML) schema to fetch from the page's own server. |
sequenceIndent |
sequence-indent |
boolean |
— | Indent lists under their keys (key:\n - a). Default: what the file does. |
src |
src |
string |
— | An address to load the text from (the page's own server). |
strings |
strings |
Partial<BmxYamlEditorStrings> | string |
— | Words to show instead of the English ones, as an object or JSON. |
value |
value |
string |
'' |
The text. Two-way. |
view |
view |
BmxYamlEditorView |
'text' |
The view shown. Two-way. |
views |
views |
BmxYamlEditorView[] | string |
— | The views offered, as an array, JSON or a comma list. Default: text and tree, and compare when compare-with is set. |
yaml11Warnings |
yaml-1-1-warnings |
boolean |
true |
Point out plain values YAML 1.1 tools read differently (no, on, 012). |
yamlVersion |
yaml-version |
'1.1' | '1.2' |
'1.2' |
The YAML version a document is read with when it does not say: 1.2 or 1.1. |
Events
| Event | Detail | Description |
|---|---|---|
bmxChange |
BmxYamlChangeDetail |
Fired after the text changes. |
bmxEdit |
BmxYamlEditDetail |
Fired before an edit made with the tree or a command. Cancel it to refuse the edit. |
bmxSelect |
BmxYamlSelectDetail |
Fired when the selected entry changes (in the tree, or the one at the caret). |
bmxValidate |
BmxYamlValidateDetail |
Fired after each check of the text. |
Methods
| Method | Signature | Description |
|---|---|---|
collapseAll |
collapseAll() => Promise<void> |
|
convert |
convert(to: BmxYamlFileFormat | "json") => Promise<string> |
The data written in another format (or JSON), without changing anything. |
convertTo |
convertTo(to: BmxYamlFileFormat) => Promise<boolean> |
Replace the text with its data written in another format, and read it as that format. Can be undone. |
edit |
edit(edit: BmxYamlFileEdit, document?: number) => Promise<boolean> |
Make one change by path, as the tree does: { op: 'set', path: ['spec', 'replicas'], value: 3 }. Returns whether the text changed. |
expandAll |
expandAll(depth?: number) => Promise<void> |
|
formatText |
formatText() => Promise<boolean> |
Lay a YAML file out again, keeping its comments. Returns whether it changed (false when it has mistakes). |
getData |
getData() => Promise<BmxJsonValue[]> |
Each document's data (one item for TOML, INI, .properties and .env). |
getProblems |
getProblems() => Promise<BmxYamlProblem[]> |
The problems found by the last check. |
getSelection |
getSelection() => Promise<BmxYamlSelectDetail | null> |
The selected entry (in the tree, or at the caret). |
getValue |
getValue() => Promise<string> |
The text now (including typing not yet reported). |
goTo |
goTo(line: number, column?: number) => Promise<void> |
Put the caret at a line and column (from 1), in the text view. |
redo |
redo() => Promise<boolean> |
|
save |
save(fileName?: string) => Promise<void> |
Download the text as a file (default: the file name, else config.<format>). |
select |
select(path: readonly BmxYamlKey[] | string, document?: number) => Promise<boolean> |
Select the entry at a path (keys and indexes, a JSON Pointer, or spec.containers[0]) and show it. Returns whether it was found. |
setFocus |
setFocus() => Promise<void> |
|
setValue |
setValue(text: string, options?: { keepHistory?: boolean; }) => Promise<void> |
Replace the whole text. With keepHistory, it can be undone. |
undo |
undo() => Promise<boolean> |
|
validate |
validate() => Promise<BmxYamlProblem[]> |
Check now: the text's own rules and, with a schema, every document. Returns every problem. |
Slots
| Slot | Description |
|---|---|
description |
Rich help text, in place of the description property. |
label |
Rich label content, in place of the label property. |
CSS shadow parts
| Part | Description |
|---|---|
description |
The help text under the field. |
label |
The label element. |
menu |
The actions menu. |
name |
A key in a row. |
problems |
The problems panel. |
row |
A tree row; also row-selected, row-problem. |
status |
The bar under the views. |
toolbar |
The bar of views and commands. |
tree |
The tree. |
value |
A value in a row. |
CSS custom properties
| Property | Description |
|---|---|
--bmx-yaml-editor-background |
The views' background. |
--bmx-yaml-editor-date-color |
TOML dates and times. |
--bmx-yaml-editor-height |
The height of the views' scrolling area. |
--bmx-yaml-editor-indent |
How far each level of the tree is indented. |
--bmx-yaml-editor-key-color |
Keys in the tree. |
--bmx-yaml-editor-label-font-size |
The label's font size. |
--bmx-yaml-editor-literal-color |
true, false and null. |
--bmx-yaml-editor-number-color |
Number values. |
--bmx-yaml-editor-radius |
Corner radius of the frame. |
--bmx-yaml-editor-row-height |
The height of one tree row. |
--bmx-yaml-editor-selected-background |
The selected row. |
--bmx-yaml-editor-string-color |
Text values. |
--bmx-yaml-editor-support-font-size |
Font size of the description and error message. |