-
-
Notifications
You must be signed in to change notification settings - Fork 8
Rewrite ReactPy-Router #30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 1 commit
Commits
Show all changes
62 commits
Select commit
Hold shift + click to select a range
69598ef
Bump workflows
Archmonger c86f37b
use_query -> use_search_params
Archmonger ec1b633
use_params docstring
Archmonger 332ca75
better error for route state
Archmonger 189b484
simple.router -> browser_router
Archmonger 6557000
Allow multi-component routes
Archmonger 9e72ca0
Fix potential key identity bug of router component children
Archmonger 7a242e1
Add slug conversion type
Archmonger e92842f
SimpleResolver -> Resolver, CONVERSION_TYPES -> CONVERTERS, file refa…
Archmonger f46d9d1
allow customizable match_any_identifier
Archmonger b8efe54
attempt to fix workflows
Archmonger bee18a5
server-side link component
Archmonger de53beb
fix a handful of test errors
Archmonger f77f052
change js output directory
Archmonger 518d226
fix py3.9 type hints
Archmonger e96a512
Change star pattern to `{NAME:any}`
Archmonger 03b8f2c
Fix router in local environment
Archmonger 37760bb
Fix link component
Archmonger ee616d0
Fix route parameters
Archmonger 169e2dc
remove black from workflow
Archmonger 5ffc34f
Format with ruff + prettier
Archmonger 8b057b2
Fix github actions
Archmonger db9e074
Fix use_search_params
Archmonger 7947e91
Clean up use-params example
Archmonger d9a943a
Remove select from top level router
Archmonger 94e9de5
docs tweaks
Archmonger afb97c8
js tweaks
Archmonger 78c7c49
Refactor some more docs
Archmonger 1b8031b
Better mkdocstrings
Archmonger f52aaa3
Remove core.py
Archmonger bad417f
cleaner example for use params
Archmonger 155079b
ignore link click type
Archmonger c7d19f6
Move event loop policy to dedicated fixture
Archmonger d7184b1
Fix resolver tests
Archmonger 6857f7a
fix type errors
Archmonger fa0f307
use link class instead of ID
Archmonger 1723f8d
prefix uuid with a string
Archmonger b67101a
add test for link search params
Archmonger c38ac3b
Remove coverage from some unneeded places
Archmonger f57b63b
Fix browser history
Archmonger 88d1f46
use server side prevent default
Archmonger a78a5b1
Server side handling of relative URLs
Archmonger 97a715c
Add test for class name
Archmonger 4633ab2
fix last coverage hit
Archmonger 70a7ea0
self review
Archmonger 98ac776
Add click delay (attempt to fix flakey tests)
Archmonger 9fc92ce
Add changelog
Archmonger 0e87d27
Increase delay
Archmonger 0469615
Remove unneeded homepage stuff
Archmonger 1d33c65
Use ReactJS event naming conventions
Archmonger 25e440f
Self review: Use JS component as background listener for link clicks
Archmonger 8e9b6a8
use attributes dict for all link parameters
Archmonger 05e7012
Allow reconnections to re-obtain the current URL
Archmonger afa8c83
Add new changelog item
Archmonger 972c275
Revert to dumb script for links
Archmonger ff65483
no cov on exception
Archmonger 7e10dd4
fix test
Archmonger 78b5a95
Fix spelling
Archmonger 2d88133
Update src/reactpy_router/resolvers.py
Archmonger b1192c5
use unpacking instead of list
Archmonger 9d18fc9
safer query string parsing
Archmonger df4c088
Remove unused import
Archmonger File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Remove core.py
- Loading branch information
commit f52aaa3fe1f07570aedbdeee952ed8707377a7db
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
from __future__ import annotations | ||
|
||
from pathlib import Path | ||
from typing import Any | ||
from uuid import uuid4 | ||
|
||
from reactpy import component, html | ||
from reactpy.backend.types import Location | ||
from reactpy.core.types import VdomChild, VdomDict | ||
from reactpy.web.module import export, module_from_file | ||
|
||
from reactpy_router.hooks import _use_route_state | ||
from reactpy_router.types import Route | ||
|
||
History = export( | ||
module_from_file("reactpy-router", file=Path(__file__).parent / "static" / "bundle.js"), | ||
("History"), | ||
) | ||
link_js_content = (Path(__file__).parent / "static" / "link.js").read_text(encoding="utf-8") | ||
|
||
|
||
@component | ||
def link(*children: VdomChild, to: str, **attributes: Any) -> VdomDict: | ||
"""A component that renders a link to the given path.""" | ||
# FIXME: This currently works in a "dumb" way by trusting that ReactPy's script tag \ | ||
# properly sets the location. When a client-server communication layer is added to a \ | ||
# future ReactPy release, this component will need to be rewritten to use that instead. \ | ||
set_location = _use_route_state().set_location | ||
uuid = uuid4().hex | ||
|
||
def on_click(_event: dict[str, Any]) -> None: | ||
pathname, search = to.split("?", 1) if "?" in to else (to, "") | ||
if search: | ||
search = f"?{search}" | ||
set_location(Location(pathname, search)) | ||
|
||
attrs = { | ||
**attributes, | ||
"href": to, | ||
"onClick": on_click, | ||
"id": uuid, | ||
} | ||
return html._(html.a(attrs, *children), html.script(link_js_content.replace("UUID", uuid))) | ||
|
||
|
||
def route(path: str, element: Any | None, *routes: Route) -> Route: | ||
"""Create a route with the given path, element, and child routes.""" | ||
return Route(path, element, routes) |
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
from __future__ import annotations | ||
|
||
from dataclasses import dataclass | ||
from typing import Any, Callable | ||
from urllib.parse import parse_qs | ||
|
||
from reactpy import ( | ||
create_context, | ||
use_context, | ||
use_location, | ||
) | ||
from reactpy.backend.types import Location | ||
from reactpy.types import Context | ||
|
||
|
||
@dataclass | ||
class _RouteState: | ||
set_location: Callable[[Location], None] | ||
params: dict[str, Any] | ||
|
||
|
||
def _use_route_state() -> _RouteState: | ||
route_state = use_context(_route_state_context) | ||
if route_state is None: | ||
raise RuntimeError( | ||
"ReactPy-Router was unable to find a route context. Are you " | ||
"sure this hook/component is being called within a router?" | ||
) | ||
|
||
return route_state | ||
|
||
|
||
_route_state_context: Context[_RouteState | None] = create_context(None) | ||
|
||
|
||
def use_params() -> dict[str, Any]: | ||
"""The `use_params` hook returns an object of key/value pairs of the dynamic parameters \ | ||
from the current URL that were matched by the `Route`. Child routes inherit all parameters \ | ||
from their parent routes. | ||
|
||
For example, if you have a `URL_PARAM` defined in the route `/example/<URL_PARAM>/`, | ||
this hook will return the URL_PARAM value that was matched.""" | ||
|
||
# TODO: Check if this returns all parent params | ||
return _use_route_state().params | ||
|
||
|
||
def use_search_params( | ||
keep_blank_values: bool = False, | ||
strict_parsing: bool = False, | ||
errors: str = "replace", | ||
max_num_fields: int | None = None, | ||
separator: str = "&", | ||
) -> dict[str, list[str]]: | ||
""" | ||
The `use_search_params` hook is used to read and modify the query string in the URL \ | ||
for the current location. Like React's own `use_state` hook, `use_search_params` returns \ | ||
an array of two values: the current location's search parameters and a function that may \ | ||
be used to update them. | ||
|
||
See `urllib.parse.parse_qs` for info on this hook's parameters.""" | ||
|
||
# FIXME: This needs to return a tuple of the search params and a function to update them | ||
return parse_qs( | ||
use_location().search[1:], | ||
keep_blank_values=keep_blank_values, | ||
strict_parsing=strict_parsing, | ||
errors=errors, | ||
max_num_fields=max_num_fields, | ||
separator=separator, | ||
) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.