packages/grafana-ui/src/components/CodeMirror/InlineInput.mdx
import { ArgTypes, Meta } from '@storybook/addon-docs/blocks'; import { CodeMirrorInlineInput } from './InlineInput';
<Meta title="MDX|CodeMirrorInlineInput" component={CodeMirrorInlineInput} />A single-line text input built on CodeMirrorEditor, styled to read as a
standard Grafana text field. It keeps the editor to one line (newlines are
filtered on keypress and stripped from pasted text), supports a placeholder, and
accepts completion sources for suggestions. Layer syntax highlighting or token
theming through the extensions prop.
It replaces the legacy Slate-based DataLinkInput and is the basis for inputs
that edit ${...} variable expressions.
<CodeMirrorInlineInput
value={url}
onChange={setUrl}
placeholder="http://your-grafana.com/d/000000010/annotations"
completionSources={[myVariableCompletionSource]}
/>
Build the source with createVariableCompletionSource rather than by hand. It
owns the $ trigger, the filtering and — importantly — the range an option
replaces, so accepting a suggestion next to a closing brace cannot leave a stray
} behind.
const completionSources = useMemo(() => [createVariableCompletionSource(suggestions)], [suggestions]);
Inside a URL, where = also opens the popup and variables need query encoding:
createVariableCompletionSource(suggestions, {
separators: ['='],
getInsertText: (suggestion) => `\${${suggestion.value}:queryparam}`,
});
If a source has to offer variables alongside other kinds of completion, the
factory does not fit — a range on the result would apply to every option. Build
the options yourself and reach for applyVariableReference on the variable ones:
options: [
...variables.map((name) => ({ label: name, apply: applyVariableReference(`\${${name}}`), type: 'variable' })),
...fields.map((name) => ({ label: name, type: 'property' })),
];
The editable element is a contenteditable, so it cannot be associated with a
label via htmlFor. Pass aria-labelledby (the id of a visible label) or
aria-label. The optional id is applied to the wrapping element, so selectors
like #your-id [contenteditable="true"] resolve to the editable.