Query Input
A key:value query field whose filters are chips you can switch off or remove, with syntax highlighting and field and value suggestions, as in Datadog, GitHub and Sentry.
c2-query-input is the search bar of a log explorer or an issue tracker: key:value terms such as service:web -status:>=500 "timed out". Each term that stands on its own is a c2-chip in front of the text. Click a chip (or press Enter or Space on it) to switch it off: it stays in the field, struck through and dashed, but drops out of the query until you switch it back on. Its cross (or Backspace / Delete on the chip) removes it. Backspace at the start of the text puts the last chip back into the text for editing, and ArrowLeft there walks the chips.
A term becomes a chip when you pick its value from the suggestions, when Enter runs the query, when focus leaves the field, and when value is set. Terms joined by AND or OR, after NOT, or inside parentheses stay text, since they cannot be switched off alone. The text is coloured as it is typed: keys, values, comparators (>, >=, <, <=), the boolean operators, negations (- or ! before a term), parentheses and quoted phrases each get their own colour.
fields lists what the query can filter on, as JSON ([{"key":"service","values":["web","api"]}]) or as an array property. The field then suggests keys while a word is typed and, right after key:, that key’s values; move the caret into another term’s value and the list switches to that key’s values, which may be plain strings or { value, label, description } objects. The arrow keys move through the suggestions, Enter or Tab inserts one, and a value containing spaces is quoted for you. With fields set, a key that is not one of them is underlined, as is an unterminated quote, and the host matches :state(invalid). For values fetched on demand, listen for suggest: it reports the kind, key and prefix the caret is completing whenever they change, so you can update that field’s values.
A field whose key is "" is the key-less field, for values that need no key (saved searches, tags): typing : at the start of a word offers its values, the term is written :value (-:value negated), and its chip shows the value alone, without key or colon. It is not listed among the keys, and terms reports it with key: ''.
Enter with no suggestion active fires search with the query and its parsed terms (key, value, negated, comparator, quoted); switching or removing a chip fires it too, with trigger set to toggle or remove. value, the form value and search hold the active chips, then the text; filters (on the element and in the event) lists every chip with its active flag. Escape closes the suggestions, then clears the field. search does not bubble, so listen on the element. input and change fire on every change, and the element is form-associated through name. The tokenizer, parser and chip splitter behind it, tokenizeQuery, parseQuery and splitQueryFilters, are exported for use on the server.
The chips take the --c2-query-input__filter--* variables (__filter--background, __filter__negated--background, __filter__inactive--border, …). A term still being typed sits on a lighter chip drawn under the transparent input (--c2-query-input__term--*), so typing and the caret stay native; that chip is padded with a ring and spaced with --c2-query-input--word-spacing, which the input shares, because anything that changed the width of a character would move the caret off its letter. Give the host a width and the field fills it; the chips wrap onto more lines when they need to.
Import
import '@c2n/components/query-input'