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
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)_**
|