You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

331 lines
10 KiB

7 years ago
<p align="left" style="margin-left: -24px">
<img alt="PillarJS" title="PillarJS" src="http://stuffs.fivepointseven.com/i/pillar.svg" width="250">
</p>
PillarJS is a "batteries included" JavaScript library for writing smart reusable [Web Components](https://www.webcomponents.org/introduction) in a modern way.
Inspired by React components PillarJS provides familiar state management mechanisms and Virtual DOM, while also providing all of the sweetness of Web Components like Shadow DOM, "by-definition" server side rendering and ability to render from template tags and strings.
# Shortcuts
1. [Getting started](#getting-started)
1. [Using stateless components](#stateless-components)
1. [Options](#options)
1. [Using JSX](#jsx)
1. [Browser support](#browser-support)
1. [FAQ](#faq)
<a name="getting-started"></a>
# Getting Started
Getting started is simple:
**Step 1.** Import PillarJS:
```javascript
import Pillar from 'pillarjs';
```
**Step 2.** Create your component:
```jsx
class SuperHeader extends Pillar {
render(props) {
return (
<div>
<h1>{props.text}</h1>
<h3>It's Superpowered!</h3>
</div>
);
}
}
```
Looks familiar? Pillar components are written in the exact same way as React components.
_**Note:** Because Pillar uses [Preact](https://github.com/developit/preact) for rendering JSX, `props` and `state` are passed as arguments to the `render()` method for convenient destructuring. You can still use `this.props` and `this.state` if you want to, but it's not required._
**Step 3.** Register your custom tag:
```javascript
Pillar.register(SuperHeader, 'super-header');
```
Second argument is an optional tag name. If not set, component name converted to dash-case will be used.
**Step 4.** Use it!
```html
<div id="main">
<super-header text="This is not a simple header!"></super-header>
</div>
```
And you're good to go! Custom tag's attributes will be passed to `this.props` in your component and resulting HTML on the page will be:
```html
<div>
<h1>This is not a simple header!</h1>
<h3>It's Superpowered!</h3>
</div>
```
<a name="stateless-components"></a>
### Can I use stateless components?
Yes, you can! The above class example can be trimmed down to this:
```jsx
const SuperHeader = ({ text }) => (
<div>
<h1>{text}</h1>
<h3>It's Superpowered!</h3>
</div>
);
```
<a name="getting-started"></a>
### Options
A third argument passed to `Pillar.register` is an options object:
```javascript
{
useShadow: 'open' || 'closed',
allowScripts: true // Template render only
}
```
**`useShadow`** option enables Shadow DOM. Pass **open** for open mode and **closed** for closed. See the difference [here](https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot/mode).
**`allowScripts`** By default, all `<script>` tags will be removed from the content of the template tag before rendering. This option re-enables them and permits executing **_any JavaScript code within template tag_**. Be careful with this option.
<a name="jsx"></a>
### Notes on JSX
There are 3 ways to enable JSX with Pillar:
1. Using a Babel preset (easiest)
```json
// .babelrc
{
"presets": ["pillar"]
}
```
2. By adding:
```javascript
/** @jsx Pillar.h */
```
on top of the file containing JSX. This will tell Babel to turn all JSX calls into `Pillar.h` calls. This is useful if for instance you already have React in your project and don't wan't to overwrite all of JSX behavior.
3. In `.babelrc`:
```json
{
"presets": [...],
"plugins": [
"transform-react-jsx",
{
"pragma": "h" // default pragma is React.createElement
}
]
}
```
<a name="browser-support"></a>
### What browsers are supported?
Pillar is written with the web platform in mind. According to [WebComponents.org](https://www.webcomponents.org/), the current support for platform features is as follows:
<table>
<thead>
<tr>
<th style="text-align: left;"><strong>Browser Support</strong></th>
<th><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/a5/Google_Chrome_icon_%28September_2014%29.svg/64px-Google_Chrome_icon_%28September_2014%29.svg.png" style="height: 24px"></th>
<th><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/49/Opera_2015_icon.svg/48px-Opera_2015_icon.svg.png" style="height: 24px"></th>
<th><img src="https://upload.wikimedia.org/wikipedia/en/6/61/Apple_Safari.png" style="height: 24px"></th>
<th><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/6/67/Firefox_Logo%2C_2017.svg/64px-Firefox_Logo%2C_2017.svg.png" style="height: 24px"></th>
<th><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/d/d6/Microsoft_Edge_logo.svg/48px-Microsoft_Edge_logo.svg.png" style="height: 24px"></th>
</tr>
</thead>
<tbody>
<tr>
<td>Template Tags</td>
<td>❇️ Stable</td>
<td>❇️ Stable</td>
<td>❇️ Stable</td>
<td>❇️ Stable</td>
<td>❇️ Stable</td>
</tr>
<tr>
<td>Custom Elements</td>
<td>❇️ Stable</td>
<td>❇️ Stable</td>
<td>❇️ Stable</td>
<td>
🛠 Developing
</td>
<td>
🤔 Considering
</td>
</tr>
<tr>
<td>Shadow DOM</td>
<td>❇️ Stable</td>
<td>❇️ Stable</td>
<td>❇️ Stable</td>
<td>
🛠 Developing
</td>
<td>
🤔 Considering
</td>
</tr>
<tr>
<td>Module Scripts</td>
<td>❇️ Stable</td>
<td>❇️ Stable</td>
<td>❇️ >10.1</td>
<td>🏁 Flag in 54</td>
<td>🏁 Flag in 15</td>
</tr>
<tr>
<td>HTML Imports</td>
<td>❇️ Stable</td>
<td>❇️ Stable</td>
<td>⏱ On Hold</td>
<td>⏱ On Hold</td>
<td>🤔 Considering</td>
</tr>
</tbody>
</table>
<br />
And this is what the support looks like with
[the polyfill](https://github.com/webcomponents/webcomponentsjs):
<table>
<thead>
<tr>
<th style="text-align: left;"><strong>Polyfill Support</strong></th>
<th><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/a5/Google_Chrome_icon_%28September_2014%29.svg/64px-Google_Chrome_icon_%28September_2014%29.svg.png" style="height: 24px"></th>
<th><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/49/Opera_2015_icon.svg/48px-Opera_2015_icon.svg.png" style="height: 24px"></th>
<th><img src="https://upload.wikimedia.org/wikipedia/en/6/61/Apple_Safari.png" style="height: 24px"></th>
<th><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/6/67/Firefox_Logo%2C_2017.svg/64px-Firefox_Logo%2C_2017.svg.png" style="height: 24px"></th>
<th><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/d/d6/Microsoft_Edge_logo.svg/48px-Microsoft_Edge_logo.svg.png" style="height: 24px"></th>
</tr>
</thead>
<tbody>
<tr>
<td>Template Tags</td>
<td>❇️ Stable</td>
<td>❇️ Stable</td>
<td>❇️ Stable</td>
<td>❇️ Stable</td>
<td>❇️ Stable</td>
</tr>
<tr>
<td>Custom Elements</td>
<td>❇️ Stable</td>
<td>❇️ Stable</td>
<td>❇️ Stable</td>
<td>
☘️ Polyfill
</td>
<td>
☘️ Polyfill
</td>
</tr>
<tr>
<td>Shadow DOM</td>
<td>❇️ Stable</td>
<td>❇️ Stable</td>
<td>❇️ Stable</td>
<td>
☘️ Polyfill
</td>
<td>
☘️ Polyfill
</td>
</tr>
<tr>
<td>Module Scripts</td>
<td>❇️ Stable</td>
<td>❇️ Stable</td>
<td>❇️ >10.1</td>
<td>☘️ Polyfill</td>
<td>☘️ Polyfill</td>
</tr>
<tr>
<td>HTML Imports</td>
<td>❇️ Stable</td>
<td>❇️ Stable</td>
<td>☘️ Polyfill</td>
<td>☘️ Polyfill</td>
<td>☘️ Polyfill</td>
</tr>
</tbody>
</table>
<br />
**_Note:_** _Pillar does not include any polyfills. You are responsible for pollyfilling for your target browsers._
<a name="faq"></a>
### FAQ
#### Q: I am morally opposed to JSX! How can I use this?
Pillar also supports [rendering from string]() and [template tags](). We'll get to explaining those in a bit.
However using JSX provides a whole lot of awesome features that you'll be missing out on otherwise.
#### Q: I'm morally opposed to Webpack and bundling! How can I use this?
Pillar doesn't impose any build systems on you. All you need to get started is drop a script tag on the page.
The downside of not using a build system is unavailability of JSX via Babel. But you can still use [string render]() and [template tags]() and get all benefits of Virtual DOM.
#### Q: I am morally opposed to HTML Imports!
We are too. Safari and Firefox [aren't going to](https://platform-status.mozilla.org/#html-imports) implement them, and they are just generally weird. Pillar doesn't rely on them and we suggest not to use them.
#### Q: Do I need React to use this?
Nope. Pillar is inspired by React components approach and uses [Preact](https://github.com/developit/preact/) under the hood for features like Virtual DOM and [`linkState`](https://github.com/developit/preact/wiki/Linked-State#linked-state-to-the-rescue) but it's not React nor does it require it.
#### Q: Can I have content inside of my custom elements?
Yes! By default all elements inside your custom tag will be passed to `this.props.children`. There's a [flag]() to disable that behavior.
#### Q: I am morally supportive of imperative DOM manipulations. Will this still work?
Pillar is your friend! If outside forces like jQuery decide to change your element's attributes, changes will be passed down to `this.props` and `componentWillReceiveProps` will be called as you would expect.
#### Q: Can I use React library XYZ to do ZYX?
No idea. Pillar doesn't use React, it only uses JSX via [Preact](https://github.com/developit/preact/), so if library XYZ just does some JSX stuff and doesn't heavily depend on React core, it might work, but no promises.
#### Q: How do I port my single page app to Pillar?
Whoa whoa, hold your horses. Pillar serves different purpose than React or Angular or Vue or what have you. You're not supposed to be building an SPA with this.
Pillar is not a framework, it's a [Web Components](https://www.webcomponents.org/introduction) library.
> Web components are a set of web platform APIs that allow you to create new custom, reusable encapsulated HTML tags to use in web pages and web apps.
What Pillar does is allows you to create componens that are smarter than just a collection of tags and styles and allow you to do things like interactivity, networking, etc.
If you want to build a dynamic single page app, this library is probably not the tool you're looking for.
**_Next: [Lifecycle Methods →](./1_LIFECYCLE_METHODS.html)_**