Skip to content
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

Allow mapping child nodes to functional components #2547

Closed
George-Payne opened this issue Jul 3, 2020 · 0 comments · Fixed by #2548
Closed

Allow mapping child nodes to functional components #2547

George-Payne opened this issue Jul 3, 2020 · 0 comments · Fixed by #2548
Labels

Comments

@George-Payne
Copy link
Contributor

George-Payne commented Jul 3, 2020

Stencil version:

I'm submitting a:
[x] bug report

Introduction:

Based on the ChildNode type in the documentation:

export interface ChildNode {
  vtag?: string | number | Function; 
  // ...
}

It should be possble to return a ChildNode with a Function for its vtag. However, this does not currently work.

Set up:

const ConvertToMyFunctionalComponent: FunctionalComponent = (_, children, utils) => (
    utils.map(children, child => ({
        ...child,
        vtag: MyFunctionalComponent
    }))
<ConvertToMyFunctionalComponent>
    <div class={'something'}>{'hello'}</div>
</ConvertToMyFunctionalComponent>

Current behavior:

Stencil attempts to use the functional component as an element:

index-fd3d22f9.js:2677 
DOMException: Failed to execute 'createElementNS' on 'Document': 
The qualified name provided ('(props) => (h("div", Object.assign({}, props), 'hello!'))') contains the invalid name-start character '('.

Expected behavior:

Stencil should resolve the functional component, as if the following was written:

<MyFunctionalComponent class={'something'}>{'hello'}</MyFunctionalComponent>

Other information:
Thread on slack

Hacky workaround:

// stencil's convertToPublic is not exported, so we have to access it via foreach
const convertToPublic = (utils: FunctionalUtilities) => (node: VNode) => {
    let publicNode!: ChildNode;
    utils.forEach([node], (p) => {
        publicNode = p;
    });
    return publicNode;
};
const ConvertToMyFunctionalComponent: FunctionalComponent = (_, children, utils) => {
    const toChildNode = convertToPublic(utils);
    return utils.map(children, child => toChildNode(
        <MyFunctionalComponent key={child.vkey} {...child.vattrs}>
            {child.vchildren}
        </MyFunctionalComponent>
    ))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant