Editor Component
The FlyQL editor is a Vue 3 component published as the flyql-vue npm package. It provides a schema-driven query input with autocomplete, syntax highlighting, and keyboard navigation.
Quick Setup
Section titled “Quick Setup”<script setup>import { ref } from 'vue'import { FlyqlEditor, ColumnSchema } from 'flyql-vue'
const query = ref('')const columns = ColumnSchema.fromPlainObject({ status: { type: 'number', suggest: true }, level: { type: 'enum', suggest: true, autocomplete: true, values: ['debug', 'info', 'error'] }, service: { type: 'string', suggest: true, autocomplete: true }, host: { type: 'string', suggest: true },})
function onSubmit() { console.log('Query submitted:', query.value)}
function onParseError(error) { console.log('Parse error:', error)}</script>
<template> <FlyqlEditor v-model="query" :columns="columns" placeholder="Type a FlyQL query..." @submit="onSubmit" @parse-error="onParseError" /></template>This renders a text input with autocomplete suggestions for columns, type-aware operators, and boolean operators — all driven by the columns schema.
Installation
Section titled “Installation”npm install flyql-vueflyql-vue automatically pulls in the flyql core package as a regular dependency, so you do not need to install it separately. The editor requires Vue 3 as a peer dependency:
npm install vueImport from flyql-vue:
import { FlyqlEditor, FlyqlColumns } from 'flyql-vue'The components do not import the stylesheet automatically — import flyql.css once in your application entrypoint:
import 'flyql-vue/flyql.css'This provides theme variables, suggestion panel styles, and token highlighting.
| Prop | Type | Default | Description |
|---|---|---|---|
modelValue | String | '' | Query text (v-model) |
columns | Object | {} | Column schema |
onAutocomplete | Function | null | Async value callback |
onKeyDiscovery | Function | null | Remote key discovery callback |
placeholder | String | '' | Placeholder text |
autofocus | Boolean | false | Auto-focus on mount |
debug | Boolean | false | Debug logging |
debounceMs | Number | 300 | Debounce delay (ms) for async autocomplete calls. Set to 0 to disable |
dark | Boolean | false | Enable dark theme (see theming) |
label | String | '' | Text shown inside the field, to the left of the query |
icon | String | Object | Function | Boolean | null | Icon shown before the label: a string renders as text, a component renders as-is, false removes it |
multiline | Boolean | true | Allow multi-line input. When false, newlines are collapsed to spaces and the field stays one line |
hasClear | Boolean | false | Show a clear button at the trailing edge; it appears only when the field has a value |
clearButtonLabel | String | 'Clear' | Accessible name of the clear button |
panelContainer | String | Object | 'body' | Where to portal the suggestion panel: a selector or an element. Defaults to body |
Callback signatures:
onAutocomplete(key, value)— returnsPromise<{ items: string[], incomplete?: boolean }>onKeyDiscovery(columnName, segments)— returnsPromise<Array<{ name, type?, hasChildren? }>>
When incomplete is true in the response, the editor knows the returned list is partial and will re-fetch on the next keystroke. Async calls are debounced (default 150ms) and in-flight requests are automatically cancelled when a new one starts.
Label and Icon
Section titled “Label and Icon”label and icon share the slot on the left of the field, ahead of the query text. Clicking either focuses the input, and an overlong label is truncated with an ellipsis at half the field width instead of squeezing the input. A text label also becomes the input’s accessible name, replacing the component’s default aria-label.
<template> <FlyqlEditor v-model="query" :columns="columns" label="Filter" /> <FlyqlEditor v-model="query" :columns="columns" icon="🔎" /> <FlyqlEditor v-model="query" :columns="columns" :icon="MyIcon" /> <FlyqlEditor v-model="query" :columns="columns" :icon="false" label="Filter" /></template>The icon and label slots take precedence over the props when you need richer content:
<template> <FlyqlEditor v-model="query" :columns="columns"> <template #icon><MyIcon /></template> <template #label><strong>Filter</strong></template> </FlyqlEditor></template>Events
Section titled “Events”| Event | Payload | Description |
|---|---|---|
update:modelValue | string | Query text changed (v-model) |
submit | — | User pressed Ctrl/Cmd+Enter |
parse-error | string | Parse error message when query is invalid |
focus | — | Editor gained focus |
blur | — | Editor lost focus |
Exposed Methods
Section titled “Exposed Methods”Access via template ref:
<script setup>import { ref } from 'vue'import { FlyqlEditor } from 'flyql-vue'
const editorRef = ref(null)
function checkStatus() { const status = editorRef.value.getQueryStatus() console.log(status.valid, status.message)}</script>
<template> <FlyqlEditor ref="editorRef" v-model="query" :columns="columns" /> <button @click="checkStatus">Check</button></template>| Method | Returns | Description |
|---|---|---|
focus() | — | Focus the editor input |
blur() | — | Blur the editor input |
getQueryStatus() | { valid: boolean, message: string } | Validate the current query |
Async Value Autocomplete
Section titled “Async Value Autocomplete”Provide an onAutocomplete callback to fetch value suggestions from your API:
<script setup>import { ref } from 'vue'import { FlyqlEditor, ColumnSchema } from 'flyql-vue'
const query = ref('')const columns = ColumnSchema.fromPlainObject({ service: { type: 'string', suggest: true, autocomplete: true }, level: { type: 'enum', suggest: true, autocomplete: true, values: ['info', 'error'] },})
async function onAutocomplete(key, value) { const resp = await fetch(`/api/autocomplete?key=${encodeURIComponent(key)}`) const data = await resp.json() return { items: data.values }}</script>
<template> <FlyqlEditor v-model="query" :columns="columns" :on-autocomplete="onAutocomplete" /></template>The callback receives the column key and current value prefix. Return { items: string[], incomplete?: boolean }. A loading indicator appears automatically after 200ms.
Stateful autocomplete flow
Section titled “Stateful autocomplete flow”The editor uses a stateful autocomplete flow that minimizes server calls:
- Initial load — When entering value context (e.g.,
service=), the editor fetches immediately with no debounce. A full spinner is shown until results arrive. - Complete list (
incomplete: false) — The editor stores the returned items and switches to client-side filtering. Subsequent keystrokes filter instantly without server calls, until the user changes to a different column. - Incomplete list (
incomplete: true) — The editor keeps showing current suggestions while a debounced re-fetch runs in the background. An inline spinner appears in the header. When new results arrive, they replace the current suggestions.
If the server returns 0 items, the editor displays “No matching values”. For client-side filtering of a complete list, an empty result simply shows no suggestions (the user can backspace to see more).
Columns with autocomplete: true and static values use those values directly without calling the callback. Columns with autocomplete: true but no values trigger the callback.
Keyboard Shortcuts
Section titled “Keyboard Shortcuts”| Key | Action |
|---|---|
| Arrow Up/Down | Navigate suggestions |
| Enter / Tab | Accept selected suggestion |
| Escape | Dismiss suggestions |
| Ctrl/Cmd+Enter | Submit query (emits submit event) |
| Shift+Enter | Insert a newline (unless multiline is false) |