Back to Grafana

CodeMirrorInlineInput

packages/grafana-ui/src/components/CodeMirror/InlineInput.mdx

13.2.02.3 KB
Original Source

import { ArgTypes, Meta } from '@storybook/addon-docs/blocks'; import { CodeMirrorInlineInput } from './InlineInput';

<Meta title="MDX|CodeMirrorInlineInput" component={CodeMirrorInlineInput} />

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.

Usage

tsx
<CodeMirrorInlineInput
  value={url}
  onChange={setUrl}
  placeholder="http://your-grafana.com/d/000000010/annotations"
  completionSources={[myVariableCompletionSource]}
/>

Suggesting variables

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.

tsx
const completionSources = useMemo(() => [createVariableCompletionSource(suggestions)], [suggestions]);

Inside a URL, where = also opens the popup and variables need query encoding:

tsx
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:

tsx
options: [
  ...variables.map((name) => ({ label: name, apply: applyVariableReference(`\${${name}}`), type: 'variable' })),
  ...fields.map((name) => ({ label: name, type: 'property' })),
];

Accessibility

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.

Props

<ArgTypes of={CodeMirrorInlineInput} />