From 11b6c77c9de8bee2bba0d2df6f2fdf83a2737f7b Mon Sep 17 00:00:00 2001 From: Archmonger <16909269+Archmonger@users.noreply.github.com> Date: Mon, 14 Oct 2024 02:05:10 -0700 Subject: [PATCH 1/6] fix ctrl click on links --- src/reactpy_router/components.py | 4 +++- src/reactpy_router/static/link.js | 8 ++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/reactpy_router/components.py b/src/reactpy_router/components.py index 3008065..9d39298 100644 --- a/src/reactpy_router/components.py +++ b/src/reactpy_router/components.py @@ -63,8 +63,10 @@ def _link(attributes: dict[str, Any], *children: Any) -> VdomDict: # https://github.com/reactive-python/reactpy/pull/1224 current_path = use_connection().location.pathname - @event(prevent_default=True) def on_click(_event: dict[str, Any]) -> None: + if _event.get("ctrlKey", False): + return + pathname, search = to.split("?", 1) if "?" in to else (to, "") if search: search = f"?{search}" diff --git a/src/reactpy_router/static/link.js b/src/reactpy_router/static/link.js index 0ce08b9..b574201 100644 --- a/src/reactpy_router/static/link.js +++ b/src/reactpy_router/static/link.js @@ -1,8 +1,12 @@ document.querySelector(".UUID").addEventListener( "click", (event) => { - let to = event.target.getAttribute("href"); - window.history.pushState({}, to, new URL(to, window.location)); + // Prevent default if ctrl isn't pressed + if (!event.ctrlKey) { + event.preventDefault(); + let to = event.target.getAttribute("href"); + window.history.pushState({}, to, new URL(to, window.location)); + } }, { once: true }, ); From 88aea45cb393c783577d60852f57ded45d23234a Mon Sep 17 00:00:00 2001 From: Archmonger <16909269+Archmonger@users.noreply.github.com> Date: Mon, 14 Oct 2024 02:17:53 -0700 Subject: [PATCH 2/6] Fix style lint --- src/reactpy_router/components.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/reactpy_router/components.py b/src/reactpy_router/components.py index 9d39298..6c023d4 100644 --- a/src/reactpy_router/components.py +++ b/src/reactpy_router/components.py @@ -5,7 +5,7 @@ from urllib.parse import urljoin from uuid import uuid4 -from reactpy import component, event, html, use_connection +from reactpy import component, html, use_connection from reactpy.backend.types import Location from reactpy.core.component import Component from reactpy.core.types import VdomDict From b76990eb8e025474820fab7aa5e9d1bc966eac6f Mon Sep 17 00:00:00 2001 From: Archmonger <16909269+Archmonger@users.noreply.github.com> Date: Mon, 14 Oct 2024 02:19:11 -0700 Subject: [PATCH 3/6] Attempt at creating a test for new page --- tests/{test_core.py => test_router.py} | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) rename tests/{test_core.py => test_router.py} (93%) diff --git a/tests/test_core.py b/tests/test_router.py similarity index 93% rename from tests/test_core.py rename to tests/test_router.py index 390236d..aa77e59 100644 --- a/tests/test_core.py +++ b/tests/test_router.py @@ -277,3 +277,20 @@ def sample(): _link = await display.page.wait_for_selector("#root") assert "/a" in await _link.get_attribute("href") + + +async def test_ctrl_click(display: DisplayFixture, browser): + @component + def sample(): + return browser_router( + route("/", link({"to": "/a", "id": "root"}, "Root")), + route("/a", link({"to": "/a", "id": "a"}, "a")), + ) + + await display.show(sample) + + _link = await display.page.wait_for_selector("#root") + await _link.click(delay=CLICK_DELAY, modifiers=["Control"]) + browser_context = browser.contexts[0] + new_page = await browser_context.wait_for_event("page") + await new_page.wait_for_selector("#a") From be75c085902677a8a86605dfca37f560456f3066 Mon Sep 17 00:00:00 2001 From: Archmonger <16909269+Archmonger@users.noreply.github.com> Date: Mon, 14 Oct 2024 02:27:00 -0700 Subject: [PATCH 4/6] add changelog --- CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7380865..f652ffa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,7 +36,6 @@ Using the following categories, list your changes in this order: ### Changed -- Bump GitHub workflows - Rename `use_query` to `use_search_params`. - Rename `simple.router` to `browser_router`. - Rename `SimpleResolver` to `StarletteResolver`. @@ -58,7 +57,7 @@ Using the following categories, list your changes in this order: - Fix bug where "Match Any" pattern wouldn't work when used in complex or nested paths. - Fix bug where `link` elements could not have `@component` type children. - Fix bug where the ReactPy would not detect the current URL after a reconnection. -- Fixed flakey tests on GitHub CI by adding click delays. +- Fix bug where `ctrl` + `click` on a `link` element would not open in a new tab. ## [0.1.1] - 2023-12-13 From a6354f4c058cc04170b7b85e4908c9ec17f02f64 Mon Sep 17 00:00:00 2001 From: Archmonger <16909269+Archmonger@users.noreply.github.com> Date: Mon, 14 Oct 2024 02:27:11 -0700 Subject: [PATCH 5/6] add type hints to new test --- tests/test_router.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_router.py b/tests/test_router.py index aa77e59..2080311 100644 --- a/tests/test_router.py +++ b/tests/test_router.py @@ -1,6 +1,7 @@ import os from typing import Any +from playwright.async_api._generated import Browser from reactpy import Ref, component, html, use_location from reactpy.testing import DisplayFixture @@ -279,7 +280,7 @@ def sample(): assert "/a" in await _link.get_attribute("href") -async def test_ctrl_click(display: DisplayFixture, browser): +async def test_ctrl_click(display: DisplayFixture, browser: Browser): @component def sample(): return browser_router( From 802de52f4eb2e87eb7997dd86a6d17f5ffcaed63 Mon Sep 17 00:00:00 2001 From: Archmonger <16909269+Archmonger@users.noreply.github.com> Date: Mon, 14 Oct 2024 02:32:27 -0700 Subject: [PATCH 6/6] more test type hints --- tests/test_router.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_router.py b/tests/test_router.py index 2080311..d6e0deb 100644 --- a/tests/test_router.py +++ b/tests/test_router.py @@ -1,7 +1,7 @@ import os from typing import Any -from playwright.async_api._generated import Browser +from playwright.async_api._generated import Browser, Page from reactpy import Ref, component, html, use_location from reactpy.testing import DisplayFixture @@ -293,5 +293,5 @@ def sample(): _link = await display.page.wait_for_selector("#root") await _link.click(delay=CLICK_DELAY, modifiers=["Control"]) browser_context = browser.contexts[0] - new_page = await browser_context.wait_for_event("page") + new_page: Page = await browser_context.wait_for_event("page") await new_page.wait_for_selector("#a")