A 900 Bytes module for that will make plugging in Preact components and widgets in any CMS or website as fun as lego!
Login Widget Source Code π»
Login Widget Integration pen Codepen Demo π
npm install --save preact-habitat
- 2 ways to passing props from DOM.
- Multiple rendering options.
- Light weight ( < 1KB ).
- Compatible with React widgets through preact-compat.
- In use in high traffic web applications.
import habitat from 'preact-habitat';
import WidgetAwesome from './components/WidgetAwesome';
const { render } = habitat(WidgetAwesome);
/**
** other selecors options:
**
** ".classname" for querying DOM element by its class name
**
** "#div-id" for querying DOM element by its ID value
**
** "[data-attribute-example='widget-here']" for querying DOM element by its data attribute name & val
**
**/
render({
selector: '.some-class', // Searches and mounts in <div class="some-class"></div>
defaultProps: undefined, // Default props for all widgets
inline: false,
clean: false,
clientSpecified: false
});
in webpack.config.js
or any other build tool bundle output format should be UMD
:
output: {
libraryTarget: 'umd'
}
in the DOM you'd like to mount your widget in:
<div class="some-class"> <!-- as specified in render, habitat will mount the component in this-->
<script type="application/json">
{
"title": "Widget Title passed as prop",
"theme": "red",
"anotherProp": "Thanks for trying this widget out!"
}
</script>
</div>
Now, build your production ready preact widget and you're all set, TADA! π
accepts a single Preact component as its only argument
import { h } form 'preact';
import habitat from 'preact-habitat';
const Widget = () => <h1>Hello, World!</h1>;
const { render } = habitat(Widget); // NOTE: pass Widget and not <Widget />
render({
...
});
render function accepts an options Object which supports the following properties:
String:
.myclass
,#myid
,[data-selector="my-data-attr"]
DOM Element selector used to retrieve the DOM elements you want to mount the widget in
Object: {} || undefined (default)
Default props to be rendered throughout widgets, you can replace each value declaring props.
Boolean: true || false (default)
Set to true if you want to use the parent DOM node as a host for your widget without specifing any selectors.
example:
<div class="beautiful-container">
<!-- inline set to true will make this widget render in it's parent
wrapper class="beautiful-container" without using selector option-->
<script async src="cdn.preactwidget..."></script>
</div>
Boolean: true || false (default)
clean will remove all the innerHTML from the HTMl element the widget will mount in.
example:
if we set the widget to be mounted inside the selector ".beautiful-container" with {clean: true} it will remove the Loading div as soon as it renders.
<div class="beautiful-container">
<div class="loader">LOADING...</div>
</div>
<script async src="cdn.preactwidget..."></script>
Boolean: true || false (default)
This option allows who ever using the script to specifit the selector which they'd like to mount the widget in
<div class="beautiful-container">
<div class="loader">LOADING...</div>
</div>
<script async src="cdn.preactwidget..." data-mount-in=".beautiful-container"></script>
There are 2 ways to pass props, either via data-attributes or application/json script tag
Simply add a <script>
tag with type="application/json"
or type="text/props"
and ensure the content is valid JSON. multiple script tags will be merged together and passed down.
<div class="beautiful-container" data-prop-name="preact habitat" data-prop-version="v3.0.0" data-prop-theme-color="green">
<script type="application/json">
{
"name": "preact habitat",
"version":"v3.0.0",
"themeColor": "green"
}
</script>
</div>
the data attribute has to always start with data-prop-
examples:
data-prop-name
will be available in your component as name
data-prop-version
will be available in your component as version
data-prop-theme-color
will be available in your component as themeColor
NOTE the lowerCamelCase when there's a -
<div class="beautiful-container" data-prop-name="preact habitat" data-prop-version="v3.0.0" data-prop-theme-color="green">
</div>
MIT - Copyright (c) Zouhir Chahoud
Artwork By: Oleg Turbaba, Dribble