zoid
zoid copied to clipboard
How to pass props to remote pop up?
I have the following situation:
- I want to provide a zoid component that renders a simple button
- on click, this button should render another zoid component (react) that performs some complex functionality
- props should pass from the site that hosts the button component through to the final zoid component (react)
Much like this example: https://github.com/krakenjs/zoid/tree/master/demo/advanced/remote-popup
So, the user would use the component like this:
index.htm
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-material-design/4.0.2/bootstrap-material-design.css" />
<link rel="stylesheet" href="./index.css" />
<script src="../../dist/component.frame.js"></script>
</head>
<body>
<h3>Checkout Demo</h3>
<!-- Container for our zoid component to render into -->
<div id="container"></div>
<!-- Container to display the result of the login call -->
<div id="loginContainer"></div>
<script>
// Render the component and pass down props to the iframe
component.button({
env: 'demo',
prefilledEmail: '[email protected]',
loginContainer: '#loginContainer',
// When the iframe window calls `window.xprops.onLogin(email)` this callback will be called
onLogin: function(email) {
// Display the email address that was used to log in
console.log('LOGIN')
}
}).render('#container');
</script>
</body>
component.js
/* @flow */
/** @jsx node */
import { create } from 'zoid/src';
import * as zoid from "zoid/dist/zoid.frameworks.js";
import { node, dom } from 'jsx-pragmatic/src';
export let login = create({
tag: "chargecheckout",
url: "http://localhost:3000",
defaultContext: 'popup',
props: {
prefilledEmail: {
type: 'string'
}
},
});
export let button = zoid.create({
tag: 'login-component',
dimensions: {
width: '300px',
height: '150px'
},
url: ({ props }) => {
return {
demo: "./login.htm",
production: 'https://my-site.com/login',
test: 'mock://www.my-site.com/base/test/windows/login/index.htm',
}[props.env];
},
props: {
env: {
type: 'string',
default: () => 'production'
},
prefilledEmail: {
type: 'string'
},
onLogin: {
type: 'function'
}
},
defaultContext: __DEFAULT_CONTEXT__,
login.htm
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-material-design/4.0.2/bootstrap-material-design.css" />
<link rel="stylesheet" href="./login.css" />
<!-- Pull in zoid and the login component we defined -->
<script src="../../dist/component.frame.js"></script>
</head>
<body>
<!-- Set up a login form -->
<button id="openLoginButton" id="btn" type="button" class="btn btn-outline-primary btn-lg">Checkout</button>
<div id="result"></div>
<script>
document.querySelector('#openLoginButton').addEventListener('click', function() {
document.querySelector('#openLoaginButton').style.display = 'none';
component.button({
prefilledEmail: window.xprops.prefilledEmail, // <--- Not sure about this
}).renderTo(window.parent, window.xprops.loginContainer, 'popup');
});
</script>
</body>
And the login
component is a simple create-react-app
import React from "react";
import ReactDOM from "react-dom";
import logo from "./logo.svg";
import "./App.css";
class App extends React.Component {
render() {
console.log("props", window.xprops); // <--- This is undefined
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>I am the Demo Component</p>
</header>
</div>
);
}
}
export default App;
I can get the react app to render properly in the popup windown on button click, but the prop prefilledEmail
is undefined when I try to get it in the final zoid component.
Any ideas?
I found a solution, you need to include the component in your react app.
So the login
component includes the script in the public folder index.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script src="%PUBLIC_URL%/js/component.frame.js"></script> //<--HERE
</body>
</html>
Then the props propagate correctly from user to final zoid
component.
However, when I tried to include the component via npm install
and:
import React from "react";
import ReactDOM from "react-dom";
import logo from "./logo.svg";
// I publish the component to a local npm registry so I can do this
import component from "component"; // <--- HERE,
import "./App.css";
class App extends React.Component {
render() {
console.log("props", window.xprops);
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>I am the Demo Component</p>
</header>
</div>
);
}
}
export default App;
I get the following error:

Not sure about this one.
Fighting with this issue as well.
Any news about this issue? I'm fighting against this problem as well