Skip to content

Code Editor JSON Settings

A settings file edited in place: the footer reports the parse error as you type, and saving stays blocked until the JSON is valid again.

settings.json

Code

The following example assumes that you have imported the component and set up the theme.

JSON Settings
<!-- Light theme -->
<link class="hljs-light" href="highlight.js/styles/atom-one-light.min.css" rel="stylesheet" />
<!-- Dark theme -->
<link class="hljs-dark" href="highlight.js/styles/atom-one-dark.min.css" rel="stylesheet" />
<div class="settings">
9 collapsed lines
<sv-code-editor class="settings-editor" expand linenumbers>
<span class="settings-name" slot="header">settings.json</span>
<span class="settings-status" slot="footer"></span>
</sv-code-editor>
<div class="settings-actions">
<button type="button" class="settings-save">Save</button>
<span class="settings-saved"></span>
</div>
</div>
<script type="application/x-typescript" module>
52 collapsed lines
import hljs from "highlight.js/lib/core";
import json from "highlight.js/lib/languages/json";
hljs.registerLanguage("json", json);
const editor = document.querySelector<CodeEditor>(".settings-editor")!;
const status = document.querySelector<HTMLSpanElement>(".settings-status")!;
const save = document.querySelector<HTMLButtonElement>(".settings-save")!;
const saved = document.querySelector<HTMLSpanElement>(".settings-saved")!;
editor.highlighter = code => hljs.highlight(code, { language: "json" }).value;
editor.value = `{
"port": 3000,
"open": true,
"outDir": "dist",
"ignore": ["node_modules", ".git"]
}`;
const validate = () => {
saved.textContent = "";
try {
const parsed = JSON.parse(editor.value);
const keys = Object.keys(parsed).length;
status.textContent = `Valid, ${keys} keys`;
status.classList.remove("is-invalid");
save.disabled = false;
} catch (error) {
status.textContent = (error as Error).message;
status.classList.add("is-invalid");
save.disabled = true;
}
};
save.addEventListener("click", () => {
saved.textContent = "Settings saved";
});
editor.addEventListener("valuechange", validate);
validate();
// The docs site color scheme, a page of your own would pick one theme
const stored = document.documentElement.style.colorScheme;
const preferred = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
editor.codeStylesheet = `.hljs-${stored === "dark" || stored === "light" ? stored : preferred}`;
document.addEventListener("color-scheme-changed", event => {
const theme = (event as CustomEvent<"light" | "dark">).detail;
editor.codeStylesheet = `.hljs-${theme}`;
});
</script>
<style>
58 collapsed lines
.settings {
display: grid;
gap: 0.75em;
max-inline-size: 34rem;
padding: clamp(1rem, 4vw, 2rem);
margin-inline: auto;
.settings-name,
.settings-status {
display: block;
padding: 0.35em 0.8em;
font-size: 0.8em;
color: var(--sv-gray-2);
background-color: var(--sv-gray-5);
}
.settings-name {
border-start-start-radius: var(--sv-bdr-rad-md);
border-start-end-radius: var(--sv-bdr-rad-md);
}
.settings-status {
border-end-start-radius: var(--sv-bdr-rad-md);
border-end-end-radius: var(--sv-bdr-rad-md);
&.is-invalid {
color: var(--sv-error);
}
}
.settings-actions {
display: flex;
gap: 0.75em;
align-items: center;
}
.settings-save {
padding: 0.4em 1.2em;
font: inherit;
font-size: 0.9em;
color: var(--sv-accent-content);
cursor: pointer;
background-color: var(--sv-accent);
border: none;
border-radius: var(--sv-bdr-rad-md);
&:disabled {
color: var(--sv-gray-3);
cursor: not-allowed;
background-color: var(--sv-gray-5);
}
}
.settings-saved {
font-size: 0.8em;
color: var(--sv-gray-3);
}
}
</style>