Awesome
<div align="center"> <img src="https://github.com/zouhir/preact-habitat/blob/master/docs/artworkv3.gif?raw=true" height=300px> </div>Preact Habitat
A 900 Bytes module for that will make plugging in Preact components and widgets in any CMS or website as fun as lego!
Demos
Login Widget Source Code 💻
Login Widget Integration pen Codepen Demo 🖋
Installation
npm install --save preact-habitat
Core Features
- 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.
Basic Usage Example
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! 🎉
API Docs
habitat(...)
accepts a single Preact component as its only argument
example:
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(options)
render function accepts an options Object which supports the following properties:
option.selector
String:
.myclass
,#myid
,[data-selector="my-data-attr"]
DOM Element selector used to retrieve the DOM elements you want to mount the widget in
option.defaultProps
Object: {} || undefined (default)
Default props to be rendered throughout widgets, you can replace each value declaring props.
option.inline
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>
option.clean
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>
option.clientSpecified
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>
Passing Props
There are 2 ways to pass props, either via data-attributes or application/json script tag
via props script
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>
via data-attribute
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>
License
MIT - Copyright (c) Zouhir Chahoud
Credits
Artwork By: Oleg Turbaba, Dribble