import 'dart:math' as math; import 'package:apidash/consts.dart'; import 'package:apidash_design_system/apidash_design_system.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; class TextFieldEditor extends StatefulWidget { const TextFieldEditor({ super.key, required this.fieldKey, this.onChanged, this.initialValue, this.readOnly = false, this.hintText, }); final String fieldKey; final Function(String)? onChanged; final String? initialValue; final bool readOnly; final String? hintText; @override State createState() => _TextFieldEditorState(); } class _TextFieldEditorState extends State { final TextEditingController controller = TextEditingController(); late final FocusNode editorFocusNode; void insertTab() { String sp = " "; int offset = math.min( controller.selection.baseOffset, controller.selection.extentOffset); String text = controller.text.substring(0, offset) + sp + controller.text.substring(offset); controller.value = TextEditingValue( text: text, selection: controller.selection.copyWith( baseOffset: controller.selection.baseOffset + sp.length, extentOffset: controller.selection.extentOffset + sp.length, ), ); widget.onChanged?.call(text); } @override void initState() { super.initState(); editorFocusNode = FocusNode(debugLabel: "Editor Focus Node"); } @override void dispose() { editorFocusNode.dispose(); super.dispose(); } @override Widget build(BuildContext context) { if (widget.initialValue != null) { controller.text = widget.initialValue!; } return CallbackShortcuts( bindings: { const SingleActivator(LogicalKeyboardKey.tab): () { insertTab(); }, }, child: TextFormField( key: Key(widget.fieldKey), controller: controller, focusNode: editorFocusNode, keyboardType: TextInputType.multiline, expands: true, maxLines: null, readOnly: widget.readOnly, style: kCodeStyle.copyWith( fontSize: Theme.of(context).textTheme.bodyMedium?.fontSize, ), textAlignVertical: TextAlignVertical.top, onChanged: widget.onChanged, onTapOutside: (PointerDownEvent event) { editorFocusNode.unfocus(); }, decoration: InputDecoration( hintText: widget.hintText ?? kHintContent, hintStyle: TextStyle( color: Theme.of(context).colorScheme.outlineVariant, ), focusedBorder: OutlineInputBorder( borderRadius: kBorderRadius8, borderSide: BorderSide( color: Theme.of(context).colorScheme.outlineVariant, ), ), enabledBorder: OutlineInputBorder( borderRadius: kBorderRadius8, borderSide: BorderSide( color: Theme.of(context).colorScheme.surfaceContainerHighest, ), ), filled: true, hoverColor: kColorTransparent, fillColor: Theme.of(context).colorScheme.surfaceContainerLow, ), ), ); } }