7
votes

I've been struggling with this for a while and finally I managed to track down the root of the problem, yet I don't know how to solve it!

Consider rendering Polymer's elements in a React render method:

ReactDOM.render(
    <paper-button>Ok</paper-button>,
    document.getElementById('root')
);

Previous code works fine since <paper-button> has got no child elements. But the following example does not work:

ReactDOM.render(
    <paper-dialog>
        <h2>Header</h2>
        <paper-dialog-scrollable>
            Lorem ipsum...
        </paper-dialog-scrollable>
        <div class="buttons">
            <paper-button dialog-dismiss>Cancel</paper-button>
            <paper-button dialog-confirm>Accept</paper-button>
        </div>
    </paper-dialog>,
    document.getElementById('root')
);

Because <paper-dialog> has several child elements. In the Polymer's library there's a <content> tag which represent the child elements given in the named custom tag and how they should be embedded in the final realization of the custom tag (it acts like a portal). It seems like when React is used to add a Polymer element into the document, the child elements are not passed through the portal!

When the mentioned paper-dialog Polymer element goes through React, this is what comes out:

<paper-dialog data-reactroot="">
    <h2>Header</h2>
    <paper-dialog-scrollable
        class="x-scope paper-dialog-scrollable-0 no-padding scrolled-to-bottom">
        Lorem ipsum...
    </paper-dialog-scrollable>
    <div>
        <paper-button
            role="button" tabindex="0"
            animated="" aria-disabled="false"
            elevation="0" dialog-dismiss="true"
            class="x-scope paper-button-0">
            Cancel
        </paper-button>
        <paper-button
            role="button" tabindex="0"
            animated="" aria-disabled="false"
            elevation="0" dialog-confirm="true"
            class="x-scope paper-button-0">
            Accept
        </paper-button>
    </div>
</paper-dialog>

It's in the case that if I do it as google has instructed (putting the tags inside the HTML to begin with), here's what dom tree will look like:

<paper-dialog>
    <h2>Header</h2>
    <paper-dialog-scrollable
        class="x-scope paper-dialog-scrollable-0 no-padding can-scroll">
        <div id="scrollable"
            class="scrollable style-scope paper-dialog-scrollable fit">
            Lorem ipsum...
        </div>
    </paper-dialog-scrollable>
    <div class="buttons">
        <paper-button
            role="button" tabindex="0"
            animated="" aria-disabled="false"
            elevation="0" dialog-dismiss=""
            class="x-scope paper-button-0">
            Cancel
        </paper-button>
        <paper-button
            role="button" tabindex="0"
            animated="" aria-disabled="false"
            elevation="0" dialog-confirm=""
            class="x-scope paper-button-0">
            Accept
        </paper-button>
    </div>
</paper-dialog>

The parts that are in bold are disagreement parts.

Does anyone know how to actually match Polymer with React?

1

1 Answers

2
votes

Have you tried wrapping the <paper-dialog> into another react component and then feeding it to the ReactDOM like this

var PaperDialog = React.createClass({
    render: function () {
        return (
            <paper-dialog>
                <h2>Header</h2>
                <paper-dialog-scrollable>
                    Lorem ipsum...
                </paper-dialog-scrollable>
                <div class="buttons">
                    <paper-button dialog-dismiss>Cancel</paper-button>
                    <paper-button dialog-confirm>Accept</paper-button>
                </div>
            </paper-dialog>);
    }
});

ReactDOM.render(<PaperDialog />, document.getElementById('root'));