Skip to content

Formula Field

A spreadsheet-style formula field in a "new column" form, highlighted, yet indistinguishable from the native inputs around it. one-line makes the editor behave like an input, and block-size: 1lh on the textarea holds it to one line.

Both share the same font, padding, and focus look, and the active line highlight is turned off. The highlighter is a small regular expression, and its colors come from a <style> that uses light-dark(), so one stylesheet covers both color schemes.

Formula
ROUND({Price} * (1 - {Discount}), 2)

Code

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

Formula Field
<!-- Token colors for both color schemes -->
<style class="formula-tokens">
11 collapsed lines
.token-function {
color: light-dark(#4078f2, #61afef);
}
.token-column {
color: light-dark(#a626a4, #c678dd);
}
.token-number {
color: light-dark(#986801, #d19a66);
}
</style>
<form class="column-form">
10 collapsed lines
<label class="field-label" for="column-name">Column name</label>
<input id="column-name" type="text" class="field-input" value="Sale price" />
<span class="field-label">Formula</span>
<sv-code-editor class="formula-editor" code-stylesheet=".formula-tokens" one-line>
<pre>ROUND({Price} * (1 - {Discount}), 2)</pre>
</sv-code-editor>
<label class="field-label" for="column-unit">Unit</label>
<input id="column-unit" type="text" class="field-input" value="USD" />
</form>
<script type="application/x-typescript" module>
11 collapsed lines
const editor = document.querySelector<CodeEditor>(".formula-editor")!;
const tokenPattern = /([A-Z]+(?=\())|(\{[^}]*\})|(\d*\.?\d+)/g;
const escapeHtml = (code: string) => code.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
editor.highlighter = code =>
escapeHtml(code).replace(tokenPattern, (token, functionName, columnName) => {
const tokenType = functionName ? "function" : columnName ? "column" : "number";
return `<span class="token-${tokenType}">${token}</span>`;
});
</script>
<style>
47 collapsed lines
.column-form {
--field-font-sz: 0.95rem;
--field-pad: 0.5rem;
display: grid;
grid-template-columns: auto minmax(0, 1fr);
gap: 0.75em 1.5em;
align-items: center;
max-inline-size: 32rem;
margin-inline: auto;
.field-label {
font-size: 0.9rem;
color: var(--sv-gray-2);
}
.formula-editor {
--sv-code-editor-font-sz: var(--field-font-sz);
--sv-code-editor-pad: var(--field-pad);
--sv-code-editor-active-ln-bg: transparent;
--sv-code-editor-active-ln-bdr-clr: transparent;
color: var(--sv-gray-1);
&::part(textarea) {
block-size: 1lh;
caret-color: var(--sv-gray-1);
}
}
.field-input {
padding: var(--field-pad);
font-family: monospace;
font-size: var(--field-font-sz);
line-height: 1.5;
color: var(--sv-gray-1);
outline: none;
background-color: var(--sv-gray-6);
border: var(--sv-bdr-sz-sm) solid var(--sv-gray-5);
border-radius: var(--sv-bdr-rad-md);
}
.field-input:focus,
.formula-editor:focus-within::part(wrapper) {
border-color: var(--sv-accent);
}
}
</style>