Create a component definition, which will be loaded in both the parent and child windows.
A tag-name for the component, used for:
- Logging
- Auto-generating an angular directive
tag: 'my-component-tag'
The full url that will be loaded when your component is rendered, or an object mapping different urls for different environments.
url: 'https://www.my-site.com/mycomponent'
url: {
local: 'http://localhost:8000/mycomponent',
dev: 'http://my-dev-site.com:8000/mycomponent',
live: 'https://my-live-site.com/mycomponent'
}
Note: If the map-syntax is used for url
, the rendered component can override the defaultEnv
at runtime like so:
MyComponent.render({
env: 'local'
}, '#container')
The dimensions for your component, in css-style units, with support for px
or %
.
dimensions: {
width: '300px',
height: '200px'
}
dimensions: {
width: '80%',
height: '90%'
}
A mapping of prop name to prop settings. Used to do run-time validation and prop normalization.
props: {
prefilledEmail: {
type: 'string',
required: false
},
onLogin: {
type: 'function',
required: true
}
}
-
type
string
The data-type expected for the prop
'string'
'number'
'boolean'
'object'
'function'
-
required
boolean
Whether or not the prop is mandatory
onLogin: { type: 'function', required: true }
-
def
(props) => value
A function returning the default value for the prop, if none is passed
email: { type: 'string', required: false, def: function() { return 'a@b.com'; } }
-
validate
(value, props) => void
A function to validate the passed value. Should throw an appopriate error if invalid.
email: { type: 'string', validate: function(value, props) { if (!value.match(/^.+@.+\..+$/)) { throw new Error(`Expected email to be valid format`); } } }
-
queryParam
boolean | string | (value) => string
Should a prop be passed in the url.
email: { type: 'string', queryParam: true // ?email=foo@bar.com }
If a string is set, this specifies the url param name which will be used.
email: { type: 'string', queryParam: 'user-email' // ?user-email=foo@bar.com }
If a function is set, this is called to determine the url param which should be used.
email: { type: 'string', queryParam: function(value) { if (value.indexOf('@foo.com') !== -1) { return 'foo-email'; // ?foo-email=person@foo.com } else { return 'generic-email'; // ?generic-email=person@whatever.com } } }
-
value
any
The value for the prop, if it should be statically defined at component creation time
userAgent: { type: 'string', value() { return window.navigator.userAgent; } }
-
decorate
(value, props) => value
A function used to decorate the prop at render-time. Called with the value of the prop, should return the new value.
onLogin: { type: 'function', decorate(original) { return function() { console.log('User logged in!'); return original.apply(this, arguments); }; } }
-
promisify
boolean
Should a function prop be turned into a promise-returning function
onLogin: { type: 'function', promisify: true }
-
noop
boolean
Should a function prop default to noop
onLogin: { type: 'function', noop: true }
-
once
boolean
Should a function prop be turned into a one-time function
onLogin: { type: 'function', once: true }
-
memoize
boolean
Should a function prop be turned into a memoizing function
getExpensiveData: { type: 'function', memoize: true }
-
serialization
string
If
'json'
, the prop will be JSON stringified before being inserted into the url, otherwise the prop will be converted to dot-notation.user: { type: 'object', serialization: 'json' // ?user={"name":"Zippy","age":34} }
user: { type: 'object', serialization: 'dotify' // ?user.name=Zippy&user.age=34 }
-
alias
string
An aliased name for the prop
onLogin: { type: 'function', alias: 'onUserLogin' }
A function which should return a DOM element, rendered on the parent page and containing the iframe element (or rendered behind the popup window).
zoid will pass opts.outlet
to this function, which is a pre-generated element your component will be rendered into. This must be inserted somewhere into the DOM element you return. For popup components, you don't need to use opts.outlet
Best used with jsx and the built-in jsxDom
jsx pragma. You can use babel to transpile the jsx down to regular javacript.
/* @jsx jsxDom */
var MyLoginZoidComponent = zoid.create({
tag: 'my-login',
url: 'https://www.mysite.com/login',
containerTemplate: function(opts) {
return (
<div id={ opts.id }>
<style>
{`
#${ opts.id } {
border: 5px solid red;
}
`}
</style>
{ opts.outlet }
</div>
);
}
});
As with React, you are also free to skip using JSX and just use jsxDom
directly:
var MyLoginZoidComponent = zoid.create({
tag: 'my-login',
url: 'https://www.mysite.com/login',
containerTemplate: function containerTemplate(opts) {
return jsxDom('div', { id: opts.id },
jsxDom('style', null, `
#${ opts.id } {
border: 5px solid red;
}
`),
opts.outlet
);
}
});
Since containerTemplate
only requires a DOM element, you're also free to manually create the element hierarchy using built-in browser methods like opts.document.createElement
, innerHTML
and so on.
Note: if using document.createElement
, you must use opts.document
, so the element is created using the target document of the new iframe or popup window, not the document of the parent page.
A function which should return a DOM element, rendered in place of the iframe element, or inside the popup window, as it loads.
Useful if you want to display a loading spinner or pre-render some content as the component loads.
Best used with jsx and the built-in jsxDom
jsx pragma. You can use babel to transpile the jsx down to regular javacript.
/* @jsx jsxDom */
var MyLoginZoidComponent = zoid.create({
tag: 'my-login',
url: 'https://www.mysite.com/login',
prerenderTemplate: function(opts) {
return (
<p>
Please wait while the component loads...
</p>
);
}
});
As with React, you are also free to skip using JSX and just use jsxDom
directly:
var MyLoginZoidComponent = zoid.create({
tag: 'my-login',
url: 'https://www.mysite.com/login',
prerenderTemplate: function containerTemplate(opts) {
return jsxDom('p', null, `
Please wait while the component loads...
`);
}
});
Since prerenderTemplate
only requires a DOM element, you're also free to manually create the element hierarchy using built-in browser methods like opts.document.createElement
, innerHTML
and so on.
Note: if using document.createElement
, you must use opts.document
, so the element is created using the target document of the new iframe or popup window, not the document of the parent page.
Data automatically passed to containerTemplate
and prerenderTemplate
, used to help render and customize the template.
id
: Unique id automatically generated by zoid on renderprops
: Props passed to the component inrender()
jsxDOM
: Helper for turning JSX into a DOM elementdocument
: The document into which the generated element will be inserted.container
: The element into which the generated element will be inserteddimensions
: The dimensions for the componenttag
: Tag name of the componentcontext
: Context type of the component (iframe
orpopup
)outlet
: DOM Element into which the iframe will be inserted on render. Only applies tocontainerTemplate
when rendering an iframeactions
: Set of functions which can be attached to events on the generated DOM elementclose
: Close the component. Useful if you want to render a close button outside the componentfocus
: Focus the component. Valid for popup components only. Useful if you want a clickable background overlay to re-focus the popup window.
on
: Listen for events from the componentresize
: The component window resized. Useful if you want to dynamically resize the container based on the size of the iframe.
CLASS
: Enum of class names which are internally used by zoidZOID
: Class given to the container for the componentOUTLET
: Class given to the outlet elementCOMPONENT_FRAME
: Class given to the component's iframePRERENDER_FRAME
: Class given to the component's prerender iframe, only ifprerenderTemplate
is specifiedVISIBLE
: Class given to the iframe when it becomes invisible, if pre-rendering usingprerenderTemplate
INVISIBLE
: Class given to the iframe while it is invisible, if pre-rendering usingprerenderTemplate
ANIMATION
: Enum of animation names that will be applied to the component as it renders and unrenders. Useful if you want to define custom css animations to display the component.SHOW_CONTAINER
: The component's container element, include it'scontainerTemplate
, if provided, is displayed during a render.HIDE_CONTAINER
: The component's container element, include it'scontainerTemplate
, if provided, is hidden during close.SHOW_COMPONENT
: The component element is displayed during renderHIDE_COMPONENT
: The component element is hidden during render
The default logging level required for this component. Options are:
'debug'
'info'
'warn'
'error'
defaultLogLevel: 'error'
Note that this value can be overriden by passing 'logLevel' as a prop when rendering the component.
When set to true
, makes the zoid parent iframe resize automatically when the child component size changes.
You can also decide whether you want autoresizing for width
or height
autoResize: true
autoResize: {
width: true,
height: false,
}
Note that by default it matches the html
element of your content. (body
if you are using IE9 or IE10).
You can override this setting by specifying a custom selector as an element
property.
autoResize: {
width: true,
height: true,
element: '.my-selector',
}
A string, array of strings or reqular expresions to be used to validate parent domain. If parent domain doesn't match any item, communication from child to parent will be prevented. The default value is '*' which match any domain.
allowedParentDomains: [
"http://localhost",
/^http:\/\/www\.mydomain\.com$/
]
Function which can be specified instead of url
if you need to dynamically generate the url with the user-provided props.
buildUrl(props) {
return `https://${ props.locale }.foo.com`;
}
Default env to use when specifying url
as a mapping of env to url.
url: {
local: 'http://localhost:8000/mycomponent',
dev: 'http://my-dev-site.com:8000/mycomponent',
live: 'https://my-live-site.com/mycomponent'
},
defaultEnv: 'live'
Note: See url
definition for note on overriding defaultEnv.
A string, or map of env to strings, for the domain which will be loaded in the iframe or popup.
Only required if the domain which will be rendered is different to the domain specified in the url
setting - for example, if the original url does a 302 redirect to a different domain or subdomain.
url: 'https://foo.com/login',
domain: 'https://subdomain.foo.com'
url: {
local: 'https://localhost.foo.com/login',
production: 'https://foo.com/login'
},
domain: {
local: 'https://subdomain.localhost.foo.com',
production: 'https://subdomain.foo.com'
}
Contexts to allow, between iframe
and popup
.
contexts: {
iframe: true,
popup: false
}
contexts: {
iframe: false,
popup: true
}
contexts: {
iframe: true,
popup: true
}
If both iframe
and popup
are set to true
in the contexts
setting, determines which should be picked by default.
defaultContext: 'popup'
Function which is passed all of the props at once and may validate them. Useful for validating inter-dependant props.
validate: function(component, props) {
if (props.name === 'Batman' && props.strength < 10) {
throw new Error(`Batman must have at least 10 strength`);
}
}
Whether to allow scrolling for iframe components. Defaults to false
.
The url for a post-robot bridge. Will be automatically loaded in a hidden iframe when a popup component is rendered, to allow communication between the parent window and the popup in IE/Edge.
This is only necessary if you are creating a popup component which needs to run in IE and/or Edge.
bridgeUrl: 'https://foo.com/bridge'
bridgeUrl: {
local: 'https://localhost.foo.com/bridge',
production: 'https://foo.com/bridge'
}
Required if the final domain of the bridge is different to that of the initial bridgeUrl
provided - for example, if the original url does a 302 redirect to a different domain or subdomain.
bridgeUrl: 'https://foo.com/bridge',
bridgeDomain: 'https://subdomain.foo.com'
bridgeUrl: {
local: 'https://localhost.foo.com/bridge',
production: 'https://foo.com/bridge'
},
bridgeDomain: {
local: 'https://subdomain.localhost.foo.com',
production: 'https://subdomain.foo.com'
}
Render the component to the given container element.
Object containing all of the props required by the given component
Element selector, or element, into which the component should be rendered.
Defaults to document.body
.
Equivalent to Component.render()
but allows rendering to a remote window. For example, a child component may render a new component to the parent page.
- The component must have been registered on the target window
- The component must be rendered from within the iframe of an existing component
- The component being rendered must have the same domain as the component initiating the render
The target window to which the component should be rendered. Ordinarily this will be window.parent
.
Shortcut to instantiate a component on a parent page, with props. Returns instance of ParentComponent
. Does not render the component. Render the instance using ParentComponent.render(container)
. Useful for obtaining the parent instance for inter-component operations.
Object containing all of the props required by the given component
Context type of the component (iframe
, popup
)
Element selector, or element, into which the component should be rendered.
Defaults to document.body
.
Register a component with your framework of choice, so it can be rendered natively in your app.
let MyReactZoidComponent = MyZoidComponent.driver('react', {
React: React,
ReactDOM: ReactDOM
});
render() {
return (
<MyReactZoidComponent foo="bar" />
);
}
MyZoidComponent.driver('angular', angular);`
<my-zoid foo="bar">
@ng.core.NgModule({
imports: [
ng.platformBrowser.BrowserModule,
MyZoidComponent.driver('angular2', ng.core)
]
});
<my-zoid [props]="{ foo: 'bar' }"></my-zoid>
import Component from '@glimmer/component';
export default MyZoidComponent.driver('glimmer', Component);
<my-zoid @foo={{bar}}></my-zoid>
Vue.component('app', {
components: {
'my-zoid': MyZoidComponent.driver('vue')
}
}
<my-zoid :foo="bar" />