FN-6160: fix mobile quick-entry touch handling
Let mobile Quick Entry actions rely on native tap-to-click behavior again. - remove the manual quick-entry action button click dispatch on touchend - switch mobile quick-entry action buttons to touch-action: manipulation - update QuickEntryBox mobile touch tests and add a patch changeset for @runfusion/fusion Files changed: .changeset/tiny-mobile-clicks.md | 5 +++++ packages/dashboard/app/components/QuickEntryBox.css | 4 ++-- packages/dashboard/app/components/QuickEntryBox.tsx | 9 --------- packages/dashboard/app/components/__tests__/QuickEntryBox.test.tsx | 14 +++++++++++++- 4 files changed, 20 insertions(+), 12 deletions(-) Fusion-Task-Id: FN-6160 Fusion-Task-Lineage: a8c13f7e-fb86-4087-a516-a6e16dac2092
This commit is contained in:
5
.changeset/tiny-mobile-clicks.md
Normal file
5
.changeset/tiny-mobile-clicks.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"@runfusion/fusion": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Fix mobile Quick Entry action buttons so taps rely on native browser click synthesis instead of a manual touchend click.
|
||||||
@@ -428,11 +428,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* === Quick Entry Mobile Touch + Overflow Fixes (FN-1140, FN-6153) === */
|
/* === Quick Entry Mobile Touch + Overflow Fixes (FN-1140, FN-6153, FN-6160) === */
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.quick-entry-actions,
|
.quick-entry-actions,
|
||||||
.quick-entry-actions * {
|
.quick-entry-actions * {
|
||||||
touch-action: none;
|
touch-action: manipulation;
|
||||||
}
|
}
|
||||||
|
|
||||||
.quick-entry-actions .btn {
|
.quick-entry-actions .btn {
|
||||||
|
|||||||
@@ -1492,16 +1492,7 @@ export function QuickEntryBox({ onCreate, addToast, tasks = [], availableModels,
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onTouchEnd={() => {
|
onTouchEnd={() => {
|
||||||
const button = touchButtonRef.current;
|
|
||||||
touchButtonRef.current = null;
|
touchButtonRef.current = null;
|
||||||
if (button && !button.disabled) {
|
|
||||||
button.click();
|
|
||||||
window.setTimeout(() => {
|
|
||||||
window.setTimeout(() => {
|
|
||||||
textareaRef.current?.focus({ preventScroll: true });
|
|
||||||
}, 0);
|
|
||||||
}, 0);
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
onTouchCancel={() => {
|
onTouchCancel={() => {
|
||||||
touchButtonRef.current = null;
|
touchButtonRef.current = null;
|
||||||
|
|||||||
@@ -505,6 +505,7 @@ describe("QuickEntryBox", () => {
|
|||||||
expect(preventDefaultSpy).toHaveBeenCalled();
|
expect(preventDefaultSpy).toHaveBeenCalled();
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
fireEvent(button, new Event("touchend", { bubbles: true, cancelable: true }));
|
fireEvent(button, new Event("touchend", { bubbles: true, cancelable: true }));
|
||||||
|
fireEvent.click(button);
|
||||||
vi.runOnlyPendingTimers();
|
vi.runOnlyPendingTimers();
|
||||||
vi.runOnlyPendingTimers();
|
vi.runOnlyPendingTimers();
|
||||||
});
|
});
|
||||||
@@ -530,6 +531,7 @@ describe("QuickEntryBox", () => {
|
|||||||
expect(preventDefaultSpy).toHaveBeenCalled();
|
expect(preventDefaultSpy).toHaveBeenCalled();
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
fireEvent(svg!, new Event("touchend", { bubbles: true, cancelable: true }));
|
fireEvent(svg!, new Event("touchend", { bubbles: true, cancelable: true }));
|
||||||
|
fireEvent.click(priorityButton);
|
||||||
vi.runOnlyPendingTimers();
|
vi.runOnlyPendingTimers();
|
||||||
vi.runOnlyPendingTimers();
|
vi.runOnlyPendingTimers();
|
||||||
});
|
});
|
||||||
@@ -569,6 +571,7 @@ describe("QuickEntryBox", () => {
|
|||||||
expect(preventDefaultSpy).toHaveBeenCalled();
|
expect(preventDefaultSpy).toHaveBeenCalled();
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
fireEvent(svg!, new Event("touchend", { bubbles: true, cancelable: true }));
|
fireEvent(svg!, new Event("touchend", { bubbles: true, cancelable: true }));
|
||||||
|
fireEvent.click(githubToggle);
|
||||||
vi.runOnlyPendingTimers();
|
vi.runOnlyPendingTimers();
|
||||||
vi.runOnlyPendingTimers();
|
vi.runOnlyPendingTimers();
|
||||||
});
|
});
|
||||||
@@ -653,10 +656,19 @@ describe("QuickEntryBox", () => {
|
|||||||
expect(document.activeElement).toBe(textarea);
|
expect(document.activeElement).toBe(textarea);
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
fireEvent(button, new Event("touchend", { bubbles: true, cancelable: true }));
|
fireEvent(button, new Event("touchend", { bubbles: true, cancelable: true }));
|
||||||
|
fireEvent.click(button);
|
||||||
vi.runOnlyPendingTimers();
|
vi.runOnlyPendingTimers();
|
||||||
vi.runOnlyPendingTimers();
|
vi.runOnlyPendingTimers();
|
||||||
});
|
});
|
||||||
expect(document.activeElement).toBe(textarea);
|
expect(document.activeElement).toBe(textarea);
|
||||||
|
|
||||||
|
const outsideElement = document.createElement("div");
|
||||||
|
document.body.appendChild(outsideElement);
|
||||||
|
try {
|
||||||
|
fireEvent.mouseDown(outsideElement);
|
||||||
|
} finally {
|
||||||
|
document.body.removeChild(outsideElement);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it("does not fire disabled button actions via touch", async () => {
|
it("does not fire disabled button actions via touch", async () => {
|
||||||
@@ -3218,7 +3230,7 @@ describe("QuickEntryBox", () => {
|
|||||||
const touchRule = quickEntryMobileActionsTouchRule();
|
const touchRule = quickEntryMobileActionsTouchRule();
|
||||||
|
|
||||||
expect(touchRule).toMatch(/\.quick-entry-actions,\s*\.quick-entry-actions \*/);
|
expect(touchRule).toMatch(/\.quick-entry-actions,\s*\.quick-entry-actions \*/);
|
||||||
expect(touchRule).toMatch(/touch-action:\s*none;/);
|
expect(touchRule).toMatch(/touch-action:\s*manipulation;/);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("keeps inline deps/models controls in touch-target button classes on mobile", () => {
|
it("keeps inline deps/models controls in touch-target button classes on mobile", () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user