mirror of
https://github.com/actualbudget/actual.git
synced 2026-10-11 22:49:59 +00:00
[AI] fix: let Firefox place the caret when renaming a category (#8950)
* fix: let Firefox place the caret when renaming a category or account react-dnd's HTML5 backend sets draggable="true" on the connected node and only consults canDrag on dragstart, so the attribute stays on while a row is being edited. Firefox refuses to place the caret in an input under a draggable ancestor, which made click-to-position impossible in the category and account rename fields. useDraggable now mirrors canDrag onto the attribute, which covers every caller at once. Closes #5620 * chore: name the release note after the PR * chore: scope release note to category rename
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
import React from 'react';
|
||||
import { DndProvider } from 'react-dnd';
|
||||
import { HTML5Backend } from 'react-dnd-html5-backend';
|
||||
|
||||
import { render, screen } from '@testing-library/react';
|
||||
|
||||
import { useDragRef } from '#hooks/useDragRef';
|
||||
|
||||
import { useDraggable } from './sort';
|
||||
|
||||
function Row({ canDrag }: { canDrag: boolean }) {
|
||||
const { dragRef } = useDraggable({
|
||||
type: 'row',
|
||||
item: { id: 'row-1' },
|
||||
canDrag,
|
||||
onDragChange: vi.fn(),
|
||||
});
|
||||
const handleDragRef = useDragRef(dragRef);
|
||||
|
||||
return <div data-testid="row" ref={handleDragRef} />;
|
||||
}
|
||||
|
||||
function renderRow(canDrag: boolean) {
|
||||
return render(
|
||||
<DndProvider backend={HTML5Backend}>
|
||||
<Row canDrag={canDrag} />
|
||||
</DndProvider>,
|
||||
);
|
||||
}
|
||||
|
||||
describe('useDraggable', () => {
|
||||
// #5620: react-dnd only consults canDrag on dragstart and leaves
|
||||
// draggable="true" on the node, which stops Firefox from placing the caret
|
||||
// in an input rendered inside it (e.g. the category rename field).
|
||||
it('mirrors canDrag onto the draggable attribute', () => {
|
||||
const { rerender } = renderRow(true);
|
||||
expect(screen.getByTestId('row')).toHaveAttribute('draggable', 'true');
|
||||
|
||||
rerender(
|
||||
<DndProvider backend={HTML5Backend}>
|
||||
<Row canDrag={false} />
|
||||
</DndProvider>,
|
||||
);
|
||||
expect(screen.getByTestId('row')).toHaveAttribute('draggable', 'false');
|
||||
|
||||
rerender(
|
||||
<DndProvider backend={HTML5Backend}>
|
||||
<Row canDrag />
|
||||
</DndProvider>,
|
||||
);
|
||||
expect(screen.getByTestId('row')).toHaveAttribute('draggable', 'true');
|
||||
});
|
||||
|
||||
it('is not draggable when mounted while editing', () => {
|
||||
renderRow(false);
|
||||
expect(screen.getByTestId('row')).toHaveAttribute('draggable', 'false');
|
||||
});
|
||||
});
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, {
|
||||
createContext,
|
||||
useCallback,
|
||||
useContext,
|
||||
useEffect,
|
||||
useLayoutEffect,
|
||||
@@ -42,8 +43,9 @@ export function useDraggable<T>({
|
||||
onDragChange,
|
||||
}: UseDraggableArgs<T>) {
|
||||
const _onDragChange = useRef(onDragChange);
|
||||
const node = useRef<HTMLElement | null>(null);
|
||||
|
||||
const [, dragRef] = useDrag({
|
||||
const [, connectDragSource] = useDrag({
|
||||
type,
|
||||
item: () => {
|
||||
void _onDragChange.current({ state: 'start-preview', type, item });
|
||||
@@ -69,6 +71,21 @@ export function useDraggable<T>({
|
||||
_onDragChange.current = onDragChange;
|
||||
}, [onDragChange]);
|
||||
|
||||
const dragRef = useCallback(
|
||||
(el: HTMLElement | null) => {
|
||||
node.current = el;
|
||||
connectDragSource(el);
|
||||
},
|
||||
[connectDragSource],
|
||||
);
|
||||
|
||||
// react-dnd sets draggable="true" when it connects and only consults
|
||||
// canDrag on dragstart. Firefox refuses to place the caret in an input under
|
||||
// a draggable ancestor, so mirror canDrag onto the attribute (#5620).
|
||||
useLayoutEffect(() => {
|
||||
node.current?.setAttribute('draggable', String(canDrag));
|
||||
}, [canDrag, dragRef]);
|
||||
|
||||
return { dragRef };
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
category: Bugfix
|
||||
authors: [costajohnt]
|
||||
---
|
||||
|
||||
Allow clicking to place the cursor when renaming a category in Firefox
|
||||
Reference in New Issue
Block a user