Skip to content

Commit

Permalink
modules with mount func should not have children
Browse files Browse the repository at this point in the history
  • Loading branch information
rmorshea committed May 14, 2021
1 parent e7c11d0 commit 94d006c
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 23 deletions.
37 changes: 21 additions & 16 deletions src/idom/client/app/packages/idom-client-react/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ function ImportedElement({ model }) {
model.importSource.source
);
eval(`import("${importSource}")`).then((module) => {
mountImportSource(module, mountPoint.current, model, config);
mountImportSource(mountPoint.current, module, model, config);
});
});
return html`<div ref=${mountPoint} />`;
Expand Down Expand Up @@ -137,21 +137,26 @@ function eventHandler(sendEvent, eventSpec) {
};
}

function mountImportSource(module, mountPoint, model, config) {
const mountFunction = model.importSource.hasMount
? module.mount
: (element, component, props, children) =>
reactDOM.render(
react.createElement(component, props, ...children),
element
);

const component = module[model.tagName];
const children = elementChildren(model);
const attributes = elementAttributes(model, config.sendEvent);
const props = { key: model.key, ...attributes };

mountFunction(mountPoint, component, props, children);
function mountImportSource(element, module, model, config) {
if (model.importSource.hasMount) {
if (model.children) {
console.error("Mount function does not support children");
}
module.mount(
element,
module[model.tagName],
elementAttributes(model, config.sendEvent)
);
} else {
reactDOM.render(
react.createElement(
module[model.tagName],
elementAttributes(model, config.sendEvent),
...elementChildren(model)
),
element
);
}
}

function useInplaceJsonPatch(doc) {
Expand Down
17 changes: 14 additions & 3 deletions src/idom/client/module.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ def __init__(
def declare(
self,
name: str,
has_children: bool = True,
has_children: Optional[bool] = None,
fallback: Optional[str] = None,
) -> Import:
"""Return an :class:`Import` for the given :class:`Module` and ``name``
Expand All @@ -147,10 +147,11 @@ def declare(
raise ValueError(
f"{self} does not export {name!r}, available options are {list(self.exports)}"
)

return Import(
self.url,
name,
has_children,
has_children=has_children,
has_mount=self.has_mount,
fallback=fallback or self.fallback,
)
Expand Down Expand Up @@ -183,7 +184,7 @@ def __init__(
self,
module: str,
name: str,
has_children: bool = True,
has_children: Optional[bool] = None,
has_mount: bool = False,
fallback: Optional[str] = None,
) -> None:
Expand All @@ -192,6 +193,16 @@ def __init__(
f"{IDOM_CLIENT_MODULES_MUST_HAVE_MOUNT} is set and {module} has no mount"
)

if has_mount:
if has_children is True:
raise ValueError(
f"Components of {module!r} do not support "
"children because has_mount=True"
)
has_children = False
else:
has_children = bool(has_children)

self._name = name
self._constructor = make_vdom_constructor(name, has_children)
self._import_source = ImportSourceDict(
Expand Down
6 changes: 3 additions & 3 deletions tests/test_client/js/vanilla-js-component.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export function mount(element, component, props, children) {
component(element, props, children);
export function mount(element, component, props) {
component(element, props);
}

export function SetInnerHtml(element, props, children) {
export function SetInnerHtml(element, props) {
element.innerHTML = props.innerHTML;
}
17 changes: 16 additions & 1 deletion tests/test_client/test_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,21 @@ def test_idom_client_modules_must_have_mount():
IDOM_CLIENT_MODULES_MUST_HAVE_MOUNT.current = True
try:
with pytest.raises(RuntimeError, match="has no mount"):
idom.Module("https://some.url", has_mount=False).SomeComponent
idom.Import(
"https://some.url",
"SomeComponent",
has_mount=False,
)
finally:
IDOM_CLIENT_MODULES_MUST_HAVE_MOUNT.current = old_opt


def test_no_children_if_import_has_mount():
with pytest.raises(ValueError, match="do not support children"):
idom.Import(
"https://some.url",
"SomeComponent",
has_children=True,
has_mount=True,
fallback=None,
)

0 comments on commit 94d006c

Please sign in to comment.