Skip to content

ability to specify version in template + no more exports_default #765

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 4 commits into from
Jun 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions docs/source/about/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ Unreleased
- ``ServerFixture -> BackendFixture``
- ``DisplayFixture.server -> DisplayFixture.backend``

- :pull:`765` - ``exports_default`` parameter is not longer required for
``module_from_template`` when exporting ``default``.

**Added**

- :pull:`765` - ability to specify versions with module templates (e.g.
``module_from_template("react@^17.0.0", ...)``).


v0.38.1
-------
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import idom
from idom import component, run, web


mui = idom.web.module_from_template("react", "@material-ui/core@^5.0", fallback="⌛")
Button = idom.web.export(mui, "Button")

idom.run(
idom.component(
lambda: Button({"color": "primary", "variant": "contained"}, "Hello World!")
)
mui = web.module_from_template(
"react@^17.0.0",
"@material-ui/[email protected]",
fallback="⌛",
)
Button = web.export(mui, "Button")


@component
def HelloWorld():
return Button({"color": "primary", "variant": "contained"}, "Hello World!")


run(HelloWorld)
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
import idom


mui = idom.web.module_from_template("react", "@material-ui/core@^5.0", fallback="⌛")
mui = idom.web.module_from_template(
"react@^17.0.0",
"@material-ui/[email protected]",
fallback="⌛",
)
Button = idom.web.export(mui, "Button")


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,9 @@ function makePath(props, domain, data, options) {
const getSvgX = (x) => ((x - xMin) / (xMax - xMin)) * width;
const getSvgY = (y) => height - ((y - yMin) / (yMax - yMin)) * height;

let pathD = "M " + getSvgX(data[0].x) + " " + getSvgY(data[0].y) + " ";
pathD += data.map((point, i) => {
return "L " + getSvgX(point.x) + " " + getSvgY(point.y) + " ";
});
let pathD =
`M ${getSvgX(data[0].x)} ${getSvgY(data[0].y)} ` +
data.map(({ x, y }, i) => `L ${getSvgX(x)} ${getSvgY(y)}`).join(" ");

return html`<path
d="${pathD}"
Expand Down
2 changes: 0 additions & 2 deletions docs/source/reference/_examples/network_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@


react_cytoscapejs = idom.web.module_from_template(
# we need to use this template because react-cytoscapejs uses a default export
"react",
"react-cytoscapejs",
exports_default=True,
fallback="⌛",
)
Cytoscape = idom.web.export(react_cytoscapejs, "default")
Expand Down
16 changes: 6 additions & 10 deletions src/idom/web/module.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ def module_from_template(
package: str,
cdn: str = "https://esm.sh",
fallback: Optional[Any] = None,
exports_default: bool = False,
resolve_exports: bool = IDOM_DEBUG_MODE.current,
resolve_exports_depth: int = 5,
unmount_before_update: bool = False,
Expand All @@ -93,7 +92,7 @@ def module_from_template(

This approach is not recommended for use in a production setting because the
framework templates may use unpinned dependencies that could change without
warning.cIt's best to author a module adhering to the
warning. It's best to author a module adhering to the
:ref:`Custom Javascript Component` interface instead.

**Templates**
Expand All @@ -110,8 +109,6 @@ def module_from_template(
Where the package should be loaded from. The CDN must distribute ESM modules
fallback:
What to temporarilly display while the module is being loaded.
exports_default:
Whether the module has a default export.
resolve_imports:
Whether to try and find all the named exports of this module.
resolve_exports_depth:
Expand All @@ -122,6 +119,9 @@ def module_from_template(
Using this option has negative performance consequences since all DOM
elements must be changed on each render. See :issue:`461` for more info.
"""
template_name, _, template_version = template.partition("@")
template_version = "@" + template_version if template_version else ""

# We do this since the package may be any valid URL path. Thus we may need to strip
# object parameters or query information so we save the resulting template under the
# correct file name.
Expand All @@ -130,17 +130,13 @@ def module_from_template(
# downstream code assumes no trailing slash
cdn = cdn.rstrip("/")

template_file_name = (
template
+ (".default" if exports_default else "")
+ module_name_suffix(package_name)
)
template_file_name = template_name + module_name_suffix(package_name)

template_file = Path(__file__).parent / "templates" / template_file_name
if not template_file.exists():
raise ValueError(f"No template for {template_file_name!r} exists")

variables = {"PACKAGE": package, "CDN": cdn}
variables = {"PACKAGE": package, "CDN": cdn, "VERSION": template_version}
content = Template(template_file.read_text()).substitute(variables)

return module_from_string(
Expand Down
48 changes: 0 additions & 48 deletions src/idom/web/templates/react.default.js

This file was deleted.

17 changes: 15 additions & 2 deletions src/idom/web/templates/react.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
export * from "$CDN/$PACKAGE";

import * as React from "$CDN/react";
import * as ReactDOM from "$CDN/react-dom";
import * as React from "$CDN/react$VERSION";
import * as ReactDOM from "$CDN/react-dom$VERSION";

export default ({ children, ...props }) => {
const [{ component }, setComponent] = React.useState({});
React.useEffect(() => {
import("$CDN/$PACKAGE").then((module) => {
// dynamically load the default export since we don't know if it's exported.
setComponent({ component: module.default });
});
});
return component
? React.createElement(component, props, ...(children || []))
: null;
};

export function bind(node, config) {
return {
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
4 changes: 3 additions & 1 deletion tests/test_web/test_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,9 @@ def test_module_from_template_where_template_does_not_exist():


async def test_module_from_template(display: DisplayFixture):
victory = idom.web.module_from_template("react", "[email protected]")
victory = idom.web.module_from_template("[email protected]", "[email protected]")

assert "[email protected]" in victory.file.read_text()
VictoryBar = idom.web.export(victory, "VictoryBar")
await display.show(VictoryBar)

Expand Down