From d26c167c767d58ff8d2ce92321f0dee08ad36ebd Mon Sep 17 00:00:00 2001 From: Aditya Toshniwal Date: Wed, 17 Jan 2024 18:38:00 +0530 Subject: [PATCH] Improve auto-focus of editable data grid when adding/editing rows --- .../static/js/SchemaView/DataGridView.jsx | 9 ++++++++- web/pgadmin/static/js/SchemaView/FormView.jsx | 6 +++++- web/pgadmin/static/js/utils.js | 20 +++++++++++++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/web/pgadmin/static/js/SchemaView/DataGridView.jsx b/web/pgadmin/static/js/SchemaView/DataGridView.jsx index 36feb0aee..acb0a4cdf 100644 --- a/web/pgadmin/static/js/SchemaView/DataGridView.jsx +++ b/web/pgadmin/static/js/SchemaView/DataGridView.jsx @@ -34,6 +34,7 @@ import { DepListenerContext } from './DepListener'; import { useIsMounted } from '../custom_hooks'; import { InputText } from '../components/FormComponents'; import { usePgAdmin } from '../BrowserComponent'; +import { requestAnimationAndFocus } from '../utils'; const useStyles = makeStyles((theme)=>({ grid: { @@ -221,6 +222,10 @@ function DataTableRow({index, row, totalRows, isResizing, isHovered, schema, sch } }); }); + + // Try autofocus on newly added row. + requestAnimationAndFocus(rowRef.current?.querySelector('input')); + return ()=>{ /* Cleanup the listeners when unmounting */ depListener?.removeDepListener(accessPath); @@ -656,7 +661,9 @@ export default function DataGridView({ {props.canEdit && row.isExpanded && + isDataGridForm={true} firstEleRef={(ele)=>{ + requestAnimationAndFocus(ele); + }}/> } ; })} diff --git a/web/pgadmin/static/js/SchemaView/FormView.jsx b/web/pgadmin/static/js/SchemaView/FormView.jsx index faf995d09..20a7ca762 100644 --- a/web/pgadmin/static/js/SchemaView/FormView.jsx +++ b/web/pgadmin/static/js/SchemaView/FormView.jsx @@ -324,7 +324,11 @@ export default function FormView({ let currentControl = { if(firstEleRef && firstEleID.current === field.id) { - firstEleRef.current = ele; + if(typeof firstEleRef == 'function') { + firstEleRef(ele); + } else { + firstEleRef.current = ele; + } } }} state={value} diff --git a/web/pgadmin/static/js/utils.js b/web/pgadmin/static/js/utils.js index 5a1481f7c..3d26ce7d4 100644 --- a/web/pgadmin/static/js/utils.js +++ b/web/pgadmin/static/js/utils.js @@ -574,3 +574,23 @@ export function gettextForTranslation(translations, ...replaceArgs) { return rawTranslation; } } + +// https://developer.mozilla.org/en-US/docs/Web/API/Window/cancelAnimationFrame +const requestAnimationFrame = + window.requestAnimationFrame || + window.mozRequestAnimationFrame || + window.webkitRequestAnimationFrame || + window.msRequestAnimationFrame; + +const cancelAnimationFrame = + window.cancelAnimationFrame || window.mozCancelAnimationFrame; + +/* Usefull in focussing an element after it appears on the screen */ +export function requestAnimationAndFocus(ele) { + if(!ele) return; + + const animateId = requestAnimationFrame(()=>{ + ele?.focus?.(); + cancelAnimationFrame(animateId); + }); +}