Skip to content

QueryEditor

<caos-query-editor>

write and run queries, several open at once as tabs, with the editing engine swappable

May be placed on a page inside an app.

Name Attribute Description Type Default Required
tabs property only The open queries: { key, label, query }[]. Re-supplying the same list does NOT overwrite what somebody has typed since — a host that re-renders on every keystroke would otherwise erase the thing being typed. A tab dropped from the list has its text forgotten with it. json empty list Optional
active active, also a property Which tab is on screen, by key. An unknown key falls back to the first tab rather than showing an empty editor. Reading it back gives The key actually being shown, which is the fallback when the attribute names no open tab. text none declared Optional
language language, markup only What kind of text this is, passed to the engine as a hint. Changing it remounts the engine, carrying the current text across. Engines that do not know the language show plain text. text — anything it does not recognise reads as plain text, for any language the mounted engine does not recognise sql Optional
running running, markup only A run is in flight. The Run button reads “Running…” and is disabled, and Ctrl/Cmd+Enter raises nothing — so a person leaning on the shortcut cannot queue six copies of one query. boolean false Optional
status status, markup only A line under the editor — what the last run returned, or what went wrong with it. text none declared Optional
runLabel run-label, markup only What the run button is called, for a surface whose verb is not “Run”. text Run Optional
searchTerm search-term, markup only What the in-editor Search control looks for when it is pressed. text none declared Optional
Name When it fires What it carries
caos-query-run The run button is pressed, or Ctrl/Cmd+Enter is used in the editor. Never while running. { key, query } — which tab, and its text as it stands.
caos-query-change The person edits the query. { key, query }.
caos-query-tab A different tab is selected. { key }.
caos-query-prettify The Prettify control is pressed. { key, query, language }. Formatting is language knowledge this component does not have; the application formats and calls setQuery back.
caos-query-copy The Copy control is pressed. { text }. It asks rather than reaching for the clipboard, because a component cannot know whether this page is permitted to write to it and a silent rejection is worse than an event.
caos-query-search The Search control is pressed, or search() is called. { term, matches } — how many times it occurs, as the mounted engine counts them.

Not documented yet — this piece has not said.

Not documented yet — this piece has not said.

Name Description Arguments
setQuery() Put text into a tab from outside — what a host calls after prettifying, or after loading a saved query. Does nothing for a key that is not open. key: string, query: string
search() Find a term in the query and reveal it, returning how many times it occurs. Returns 0 when the mounted engine cannot search — the same answer as “not found”, which is why the toolbar control is disabled in that case rather than left to give a misleading zero. term: string
Name Type What it tells you
value string What is in the editor right now, for the tab on screen.
changed string[] The keys of tabs whose text differs from what was handed in. A comparison, not a flag somebody has to remember to set, so it cannot go stale.
engine string The name of the mounted editing engine — plain-text unless an application installed another. Readable so a surface can say which editor it is drawing.
Part Which piece of it When it is there
::part(editor) The outer column. Always
::part(tabs) The tab strip. Always
::part(tab) One open query’s tab. Always
::part(toolbar) The search / copy / prettify cluster on the editor’s right edge. Always
::part(tool) One of those three controls. Always
::part(run) The run button. Always
::part(status) The line under the editor. Always
::part(editor-surface) The editing surface itself. The built-in plain-text engine is mounted; another engine names its own parts, or none.

On a query surface, where somebody writes a query, runs it, and comes back to it — and where keeping the previous attempt matters as much as running the next one.

  • CodeEditor — the text is a stored artifact being edited rather than a question being asked — the code editor is built around fetching, dirty state and saving back, which a query has no notion of.
  • TextField — it is one short expression on a form, not a body of text somebody works in.

The tab strip is a real role="tablist" of buttons, with aria-selected and roving tabindex, so a keyboard reaches the tabs before the editor rather than having to pass through it. Unsaved work is marked with a dot AND an aria-label reading “unsaved changes”, because a bullet is not a word. The status line is a role="status" live region, so what a run returned is announced to somebody who was not watching the button. The editing surface carries its own accessible name, which every engine is required to apply — an unlabelled editing region is the most common way a surface like this becomes unusable without sight.

The ordinary working state: the tab being worked in, two kept from earlier, and a dot on the one whose text no longer matches what was handed in.

{
"id": "example",
"section": "Three queries open, one edited",
"columns": 1,
"items": [
{
"id": "query_editor_1",
"type": "component",
"key": "query_editor",
"inputs": {
"active": "accounts",
"status": "42 rows · ran in 310 ms",
"tabs": [
{
"key": "accounts",
"label": "Accounts",
"query": "select id, name, industry from account\nwhere industry = :industry"
},
{
"key": "contacts",
"label": "Contacts",
"query": "select id, email from contact limit 200"
},
{
"key": "scratch",
"label": "Scratch",
"query": ""
}
]
}
}
]
}
<caos-query-editor id="queryEditor1" active="accounts" status="42 rows · ran in 310 ms"></caos-query-editor>
// What an attribute cannot hold, set as a property — the same values the preview is drawn with.
const queryEditor1 = document.getElementById('queryEditor1');
queryEditor1.tabs = [
{
"key": "accounts",
"label": "Accounts",
"query": "select id, name, industry from account\nwhere industry = :industry"
},
{
"key": "contacts",
"label": "Contacts",
"query": "select id, email from contact limit 200"
},
{
"key": "scratch",
"label": "Scratch",
"query": ""
}
];

While running, the button says so and is disabled, and the keyboard shortcut raises nothing — leaning on Ctrl+Enter cannot queue six copies of one query.

{
"id": "example",
"section": "A run in flight",
"columns": 1,
"items": [
{
"id": "query_editor_1",
"type": "component",
"key": "query_editor",
"inputs": {
"running": true,
"status": "Running…",
"tabs": [
{
"key": "accounts",
"label": "Accounts",
"query": "select count() from account"
}
]
}
}
]
}
<caos-query-editor id="queryEditor1" running status="Running…"></caos-query-editor>
// What an attribute cannot hold, set as a property — the same values the preview is drawn with.
const queryEditor1 = document.getElementById('queryEditor1');
queryEditor1.tabs = [
{
"key": "accounts",
"label": "Accounts",
"query": "select count() from account"
}
];

With no tabs there is nothing to run, and the run button says so by being disabled rather than by raising an event with no query in it.

{
"id": "example",
"section": "Nothing open",
"columns": 1,
"items": [
{
"id": "query_editor_1",
"type": "component",
"key": "query_editor",
"inputs": {
"tabs": []
}
}
]
}
<caos-query-editor id="queryEditor1"></caos-query-editor>
// What an attribute cannot hold, set as a property — the same values the preview is drawn with.
const queryEditor1 = document.getElementById('queryEditor1');
queryEditor1.tabs = [];