diff --git a/public/app/features/dashboard-scene/settings/variables/components/TextBoxVariableForm.test.tsx b/public/app/features/dashboard-scene/settings/variables/components/TextBoxVariableForm.test.tsx
new file mode 100644
index 00000000000..a1551b0028f
--- /dev/null
+++ b/public/app/features/dashboard-scene/settings/variables/components/TextBoxVariableForm.test.tsx
@@ -0,0 +1,34 @@
+import { render, screen } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
+import React from 'react';
+
+import { TextBoxVariableForm } from './TextBoxVariableForm';
+
+describe('TextBoxVariableForm', () => {
+ it('renders correctly', () => {
+ const onChange = jest.fn();
+ const onBlur = jest.fn();
+ const value = 'test value';
+
+ render();
+
+ expect(screen.getByText('Text options')).toBeInTheDocument();
+ expect(screen.getByRole('textbox', { name: 'Default value' })).toBeInTheDocument();
+ });
+
+ it('calls onChange when input value changes', async () => {
+ const onChange = jest.fn();
+ const onBlur = jest.fn();
+ const value = 'test value';
+
+ render();
+
+ const input = screen.getByRole('textbox', { name: 'Default value' });
+ expect(input).toHaveValue(value);
+
+ // change input value
+ const newValue = 'new value';
+ await userEvent.type(input, newValue);
+ expect(onChange).toHaveBeenCalledTimes(newValue.length);
+ });
+});
diff --git a/public/app/features/dashboard-scene/settings/variables/components/TextBoxVariableForm.tsx b/public/app/features/dashboard-scene/settings/variables/components/TextBoxVariableForm.tsx
new file mode 100644
index 00000000000..e91b7860dda
--- /dev/null
+++ b/public/app/features/dashboard-scene/settings/variables/components/TextBoxVariableForm.tsx
@@ -0,0 +1,28 @@
+import React, { FormEvent } from 'react';
+
+import { selectors } from '@grafana/e2e-selectors';
+import { VariableLegend } from 'app/features/dashboard-scene/settings/variables/components/VariableLegend';
+import { VariableTextField } from 'app/features/dashboard-scene/settings/variables/components/VariableTextField';
+
+interface TextBoxVariableFormProps {
+ value: string;
+ onChange: (event: FormEvent) => void;
+ onBlur: (event: FormEvent) => void;
+}
+
+export function TextBoxVariableForm({ onChange, onBlur, value }: TextBoxVariableFormProps) {
+ return (
+ <>
+ Text options
+
+ >
+ );
+}
diff --git a/public/app/features/dashboard-scene/settings/variables/editors/TextBoxVariableEditor.test.tsx b/public/app/features/dashboard-scene/settings/variables/editors/TextBoxVariableEditor.test.tsx
new file mode 100644
index 00000000000..063a1d033f3
--- /dev/null
+++ b/public/app/features/dashboard-scene/settings/variables/editors/TextBoxVariableEditor.test.tsx
@@ -0,0 +1,54 @@
+import { render, screen } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
+import React from 'react';
+
+import { TextBoxVariable } from '@grafana/scenes';
+
+import { TextBoxVariableEditor } from './TextBoxVariableEditor';
+
+describe('TextBoxVariableEditor', () => {
+ let textBoxVar: TextBoxVariable;
+ beforeEach(async () => {
+ const result = await buildTestScene();
+ textBoxVar = result.textBoxVar;
+ });
+
+ it('renders default value if any', () => {
+ const onChange = jest.fn();
+ render();
+
+ const input = screen.getByRole('textbox', { name: 'Default value' });
+ expect(input).toBeInTheDocument();
+ expect(input).toHaveValue('initial value test');
+ });
+
+ it('changes the value', async () => {
+ const onChange = jest.fn();
+ render();
+
+ const input = screen.getByRole('textbox', { name: 'Default value' });
+ expect(input).toBeInTheDocument();
+ expect(input).toHaveValue('initial value test');
+
+ // change input value
+ const newValue = 'new textbox value';
+ await userEvent.clear(input);
+ await userEvent.type(input, newValue);
+
+ expect(input).toHaveValue(newValue);
+
+ await userEvent.tab();
+ expect(textBoxVar.state.value).toBe(newValue);
+ });
+});
+
+async function buildTestScene() {
+ const textBoxVar = new TextBoxVariable({
+ name: 'textBoxVar',
+ label: 'textBoxVar',
+ type: 'textbox',
+ value: 'initial value test',
+ });
+
+ return { textBoxVar };
+}
diff --git a/public/app/features/dashboard-scene/settings/variables/editors/TextBoxVariableEditor.tsx b/public/app/features/dashboard-scene/settings/variables/editors/TextBoxVariableEditor.tsx
index 3eb6289eb3f..36da5e25491 100644
--- a/public/app/features/dashboard-scene/settings/variables/editors/TextBoxVariableEditor.tsx
+++ b/public/app/features/dashboard-scene/settings/variables/editors/TextBoxVariableEditor.tsx
@@ -1,12 +1,25 @@
-import React from 'react';
+import React, { useState } from 'react';
import { TextBoxVariable } from '@grafana/scenes';
+import { TextBoxVariableForm } from '../components/TextBoxVariableForm';
+
interface TextBoxVariableEditorProps {
variable: TextBoxVariable;
onChange: (variable: TextBoxVariable) => void;
}
-export function TextBoxVariableEditor(props: TextBoxVariableEditorProps) {
- return TextBoxVariableEditor
;
+export function TextBoxVariableEditor({ variable }: TextBoxVariableEditorProps) {
+ const { value } = variable.useState();
+ const [textValue, setTextValue] = useState(value);
+
+ const onTextValueChange = (event: React.FormEvent) => {
+ setTextValue(event.currentTarget.value);
+ };
+
+ const onBlur = () => {
+ variable.setState({ value: textValue });
+ };
+
+ return ;
}
diff --git a/public/app/features/variables/textbox/TextBoxVariableEditor.tsx b/public/app/features/variables/textbox/TextBoxVariableEditor.tsx
index 4ec385d370c..f3919521c62 100644
--- a/public/app/features/variables/textbox/TextBoxVariableEditor.tsx
+++ b/public/app/features/variables/textbox/TextBoxVariableEditor.tsx
@@ -1,9 +1,7 @@
import React, { FormEvent, ReactElement, useCallback } from 'react';
-import { selectors } from '@grafana/e2e-selectors';
+import { TextBoxVariableForm } from 'app/features/dashboard-scene/settings/variables/components/TextBoxVariableForm';
-import { VariableLegend } from '../../dashboard-scene/settings/variables/components/VariableLegend';
-import { VariableTextField } from '../../dashboard-scene/settings/variables/components/VariableTextField';
import { VariableEditorProps } from '../editor/types';
import { TextBoxVariableModel } from '../types';
@@ -22,18 +20,5 @@ export function TextBoxVariableEditor({ onPropChange, variable: { query } }: Pro
const onChange = useCallback((e: FormEvent) => updateVariable(e, false), [updateVariable]);
const onBlur = useCallback((e: FormEvent) => updateVariable(e, true), [updateVariable]);
- return (
- <>
- Text options
-
- >
- );
+ return ;
}