Skip to content

Commit aef557d

Browse files
committed
render child elements of imported components
we need to do this for two reasons: 1. it is easier to implement bind() this way 2. modules from template relied on importing a version of idom-client-react from a CDN which, if breaking changes are ever introduced, would break until the latest version was released. taking this approach avoids that problem all together. this does sort of lock us into saying that all children of imported elements must be standard HTML elements or be imported from the same source, but I think that limitation is OK to impose given the benefits you get in return.
1 parent 4ea5b9a commit aef557d

File tree

18 files changed

+742
-609
lines changed

18 files changed

+742
-609
lines changed

docs/source/_static/custom.js

Lines changed: 400 additions & 307 deletions
Large diffs are not rendered by default.

docs/source/examples.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,14 @@ Move the slider and see the event information update 👇
7575
.. example:: material_ui_switch
7676

7777

78+
Pigeon Maps
79+
-----------
80+
81+
Click the map to create pinned location 📍:
82+
83+
.. example:: pigeon_maps
84+
85+
7886
.. Links
7987
.. =====
8088

docs/source/examples/super_simple_chart.js

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,8 @@ const html = htm.bind(h);
55

66
export function bind(node, config) {
77
return {
8-
render: (component, props, children) => {
9-
if (children) {
10-
console.error("Children not supported");
11-
}
12-
render(h(component, props), node);
13-
},
8+
create: (component, props, children) => h(component, props, ...children),
9+
render: (element) => render(element, node),
1410
unmount: () => render(null, node),
1511
}
1612
}

docs/source/javascript-components.rst

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,9 @@ adheres to the following interface:
7373
loadImportSource(source: string, sourceType: "NAME" | "URL") => Module;
7474
}
7575
76-
type SourceInfo = {
77-
source: string;
78-
sourceType: string;
79-
}
80-
81-
type bind = (node: HTMLElement, context: LayoutContext, source: SourceInfo) => ({
82-
render(component: any, props: Object, childModels: Array<any>): void;
76+
type bind = (node: HTMLElement, context: LayoutContext) => ({
77+
create(type: any, props: Object, children: Array<any>): any;
78+
render(element): void;
8379
unmount(): void;
8480
});
8581
@@ -90,20 +86,20 @@ adheres to the following interface:
9086
- ``context`` can send events back to the server and load "import sources"
9187
(like a custom component module).
9288

93-
- ``component`` is a named export of the current module.
89+
- ``type``is a named export of the current module, or a string (e.g. ``"div"``,
90+
``"button"``, etc.)
9491

9592
- ``props`` is an object containing attributes and callbacks for the given
9693
``component``.
9794

98-
- ``childModels`` is an array of unrendered VDOM elements. Passing them in this raw
99-
form allows for other frameworks besides react to render them as needed. If you
100-
are using react, you can just use the ``idom-client-react`` library to process
101-
them. See :ref:`Distributing Javascript via PyPI_` for an example usage.
95+
- ``children`` is an array of elements which were constructed by recursively calling
96+
``create``.
10297

10398
The interface returned by ``bind()`` can be thought of as being similar to that of
10499
React.
105100

106-
- ``render`` ➜ |React.createElement|_ and |ReactDOM.render|_
101+
- ``create`` ➜ |React.createElement|_
102+
- ``render`` ➜ |ReactDOM.render|_
107103
- ``unmount`` ➜ |ReactDOM.unmountComponentAtNode|_
108104

109105
.. |React.createElement| replace:: ``React.createElement``
@@ -123,7 +119,8 @@ It will be used in the following manner:
123119
const binding = bind(node, context);
124120
125121
// on every render
126-
binding.render(component, props, children);
122+
let element = binding.create(type, props, children)
123+
binding.render(element);
127124
128125
// once on unmount
129126
binding.unmount();
@@ -225,27 +222,16 @@ To start, let's take a look at the file structure we'll be building:
225222
226223
import * as React from "react";
227224
import * as ReactDOM from "react-dom";
228-
import { LayoutConfigContext, elementChildren } from "idom-client-react";
229225
230226
export function bind(node, config) {
231227
return {
232-
render: (component, props, childModels) =>
233-
ReactDOM.render(createElement(config, component, props, childModels), node),
228+
create: (component, props, children) =>
229+
React.createElement(component, props, ...children),
230+
render: (element) => ReactDOM.render(element, node),
234231
unmount: () => ReactDOM.unmountComponentAtNode(node),
235232
};
236233
}
237234
238-
function createElement(config, component, props, childModels) {
239-
// Render child models with idom-client-react
240-
return React.createElement(
241-
LayoutConfigContext.Provider,
242-
{ value: config },
243-
React.createElement(
244-
component, props, ...elementChildren(children)
245-
)
246-
)
247-
}
248-
249235
// exports for your components
250236
export YourFirstComponent(props) {...};
251237
export YourSecondComponent(props) {...};

noxfile.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,15 @@ def wrapper(session: Session) -> None:
2828
@nox.session(reuse_venv=True)
2929
@apply_standard_pip_upgrades
3030
def format(session: Session) -> None:
31+
# format Python
3132
install_requirements_file(session, "check-style")
3233
session.run("black", ".")
3334
session.run("isort", ".")
3435

36+
# format Javascript
37+
session.chdir(ROOT / "src" / "client")
38+
session.run("npm", "run", "format", external=True)
39+
3540

3641
@nox.session(reuse_venv=True)
3742
@apply_standard_pip_upgrades

src/client/packages/idom-client-react/src/component.js

Lines changed: 0 additions & 189 deletions
This file was deleted.

0 commit comments

Comments
 (0)