UNPKG

13.2 kBMarkdownView Raw
1![bulmil](https://user-images.githubusercontent.com/2362138/65766959-c721a080-e16f-11e9-9fb9-45a5a2ad0391.jpg)
2
3<!-- Badges -->
4
5<p align="center">
6 <a href="#">
7 <img src="https://img.shields.io/badge/-Built%20With%20Stencil-16161d.svg?logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDE5LjIuMSwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCA1MTIgNTEyIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA1MTIgNTEyOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI%2BCjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI%2BCgkuc3Qwe2ZpbGw6I0ZGRkZGRjt9Cjwvc3R5bGU%2BCjxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik00MjQuNywzNzMuOWMwLDM3LjYtNTUuMSw2OC42LTkyLjcsNjguNkgxODAuNGMtMzcuOSwwLTkyLjctMzAuNy05Mi43LTY4LjZ2LTMuNmgzMzYuOVYzNzMuOXoiLz4KPHBhdGggY2xhc3M9InN0MCIgZD0iTTQyNC43LDI5Mi4xSDE4MC40Yy0zNy42LDAtOTIuNy0zMS05Mi43LTY4LjZ2LTMuNkgzMzJjMzcuNiwwLDkyLjcsMzEsOTIuNyw2OC42VjI5Mi4xeiIvPgo8cGF0aCBjbGFzcz0ic3QwIiBkPSJNNDI0LjcsMTQxLjdIODcuN3YtMy42YzAtMzcuNiw1NC44LTY4LjYsOTIuNy02OC42SDMzMmMzNy45LDAsOTIuNywzMC43LDkyLjcsNjguNlYxNDEuN3oiLz4KPC9zdmc%2BCg%3D%3D&colorA=16161d&style=flat-square" alt="Built with Stencil" />
8 </a>
9
10 <a href="https://bulmil.netlify.com/" target="_blank">
11 <img src="https://cdn.jsdelivr.net/gh/storybookjs/brand@master/badge/badge-storybook.svg">
12 </a>
13
14 <a href="https://stenciljs.com/docs/style-guide">
15 <img src="https://img.shields.io/badge/code_style-stencil/stylelint/prettier-5851ff.svg?style=flat-square" alt="Code Style" />
16 </a>
17
18 <a href="https://npmjs.com/package/bulmil">
19 <img src="https://img.shields.io/npm/v/bulmil/latest.svg?style=flat-square" alt="npm version" />
20 </a>
21
22 <a href="https://opensource.org/licenses/MIT">
23 <img src="https://img.shields.io/badge/License-MIT-black.svg?style=flat-square" alt="License MIT" />
24 </a>
25
26 <br />
27
28 <a href="https://david-dm.org/gomah/bulmil">
29 <img src="https://david-dm.org/gomah/bulmil/status.svg?style=flat-square" alt="dependencies" />
30 </a>
31
32 <a href="https://circleci.com/gh/Gomah/bulmil">
33 <img src="https://circleci.com/gh/Gomah/bulmil.svg?style=shield" alt="Circle CI" />
34 </a>
35
36 <a href="https://npmjs.com/package/bulmil">
37 <img src="https://img.shields.io/npm/dt/bulmil.svg?style=flat-square" alt="npm downloads" />
38 </a>
39
40 <a href="https://packagephobia.now.sh/result?p=bulmil">
41 <img src="https://flat.badgen.net/packagephobia/install/bulmil" alt="Package Phobia" />
42 </a>
43
44 <a href="https://bundlephobia.com/result?p=bulmil">
45 <img src="https://flat.badgen.net/bundlephobia/minzip/bulmil" alt="Bundle Phobia" />
46 </a>
47
48</p>
49
50Bulmil is an agnostic UI library based on Web Components, made with [Bulma.io](https://bulma.io/) & [Stencil.js](https://stenciljs.com/).
51
52Bulmil was created as a proof of concept to introduce an easy way to consume common reusable web components for use with various modern application frameworks (Angular, Vue, React, Ember) or simply with pure Javascript.
53
54:warning: Currently in Alpha, beta will be available once [this issue](https://github.com/Gomah/bulmil/issues/26) is resolved.
55
56## Why Stencil?
57
58Stencil is a compiler for building fast web apps using Web Components.
59
60Stencil combines the best concepts of the most popular frontend frameworks into a compile-time rather than run-time tool. Stencil takes TypeScript, JSX, a tiny virtual DOM layer, efficient one-way data binding, an asynchronous rendering pipeline (similar to React Fiber), and lazy-loading out of the box, and generates 100% standards-based Web Components that run in any browser supporting the Custom Elements v1 spec.
61
62Stencil components are just Web Components, so they work in any major framework or with no framework at all.
63
64## Getting Started
65
66```bash
67# Using npm
68npm i bulmil
69
70# Using yarn
71yarn add bulmil
72```
73
74---
75
76## Framework Integration
77
78Stencil's primary goal is to remove the need for components to be written using a specific framework's API. It accomplishes this by using standardized web platform APIs that work across all modern browsers. Using the low-level component model that is provided by the browser (which all frameworks are built on) allows Stencil components to work inside of a framework or without one.
79
80Stencil's integration with different frameworks is currently a work in progress. As Stencil matures, the goal is to make it easy to write standard web components which will compile to various output targets. This allows developers to stay aligned with the latest web standards while using a common API. The generated components will also be more future-proof as frameworks continue to change.
81
82The following list contains the framework integrations that have been started. All of them are not yet completed.
83
84### Components without a Framework
85
86Integrating a component built with Stencil to a project without a JavaScript framework is straight forward. If you're using a simple HTML page, you can add your component via a script tag. For example, if we published a component to npm, we could load the component through unpkg like this:
87
88```html
89<!DOCTYPE html>
90<html lang="en">
91 <head>
92 <script src="https://unpkg.com/bulmil/latest/dist/bulmil.js"></script>
93 </head>
94 <body>
95 <bm-button>Button</bm-button>
96 </body>
97</html>
98```
99
100Alternatively, if you wanted to take advantage of ES Modules, you could include the components using an import statement. Note that in this scenario `applyPolyfills` is needed if you are targeting Edge or IE11.
101
102```html
103<!DOCTYPE html>
104<html lang="en">
105 <head>
106 <script type="module">
107 import {
108 applyPolyfills,
109 defineCustomElements,
110 } from 'https://unpkg.com/bulmil/latest/dist/esm/es2017/bulmil.define.js';
111 applyPolyfills().then(() => {
112 defineCustomElements(window);
113 });
114 </script>
115 </head>
116 <body>
117 <bm-button>Button</bm-button>
118 </body>
119</html>
120```
121
122---
123
124### React
125
126With an application built using the `create-react-app` script the easiest way to include the component library is to call `defineCustomElements(window)` from the `index.js` file.
127Note that in this scenario `applyPolyfills` is needed if you are targeting Edge or IE11.
128
129```tsx
130import React from 'react';
131import ReactDOM from 'react-dom';
132import './index.css';
133import App from './App';
134import registerServiceWorker from './registerServiceWorker';
135
136import { applyPolyfills, defineCustomElements } from '@bulmil/core/dist/loader';
137
138ReactDOM.render(<App />, document.getElementById('root'));
139registerServiceWorker();
140
141applyPolyfills().then(() => {
142 defineCustomElements(window);
143});
144```
145
146Following the steps above will enable your web components to be used in React, however there are some additional complexities that must also be considered. https://custom-elements-everywhere.com/ describes them well.
147
148---
149
150### Vue
151
152In order to use the custom element library within the Vue app, the application must be modified to define the custom elements and to inform the Vue compiler which elements to ignore during compilation. This can all be done within the `main.js` file.
153
154Assuming you’ve run `npm install --save bulmil` beforehand, and that `bulmil` is the name of our made up Web Components that we have published to npm, you import the components into the 'main.js' file by
155
156- importing the node module
157- telling Vue to ignore the custom element tags (see `https://vuejs.org/v2/api/#ignoredElements`)
158- binding the Stenciljs component code to the window object
159
160```tsx
161import Vue from 'vue';
162import App from './App.vue';
163
164import { applyPolyfills, defineCustomElements } from '@bulmil/core/dist/loader';
165
166Vue.config.productionTip = false;
167
168// Tell Vue to ignore all components defined in the bulmil package.
169//T he regex assumes all components names are prefixed with 'bm-'
170Vue.config.ignoredElements = [/bm-\w*/];
171
172// Bind the custom elements to the window object
173applyPolyfills().then(() => {
174 defineCustomElements(window);
175});
176
177new Vue({
178 render: (h) => h(App),
179}).$mount('#app');
180```
181
182#### Using Nuxt
183
184Create a plugin, (e.g bulmil.ts):
185
186```ts
187import Vue from 'vue';
188
189import { applyPolyfills, defineCustomElements } from '@bulmil/core/dist/loader';
190
191Vue.config.productionTip = false;
192Vue.config.ignoredElements = [/bm-\w*/];
193
194// Bind the custom elements to the window object
195applyPolyfills().then(() => {
196 defineCustomElements(window);
197});
198```
199
200```ts
201// nuxt.config.ts
202{
203 plugins: [
204 { src: '~/plugins/bulmil.ts', mode: 'client' },
205 ],
206}
207```
208
209The components should then be available in any of the Vue components
210
211```tsx
212render() {
213 return (
214 <div>
215 <bm-button>Button</bm-button>
216 </div>
217 )
218}
219```
220
221Vue provides several different ways to install and use the framework in an application. The above technique for integrating a Stencil custom element library has been tested on a Vue application that was created using the `vue-cli` with ES2015 and WebPack as primary options. A similar technique should work if the application was generated using other options.
222
223### Angular
224
225Using a Stencil built web component collection within an Angular CLI project is a two-step process. We need to:
226
2271. Include the `CUSTOM_ELEMENTS_SCHEMA` in the modules that use the components.
2282. Call `defineCustomElements(window)` from `main.ts` (or some other appropriate place).
229
230#### Including the Custom Elements Schema
231
232Including the `CUSTOM_ELEMENTS_SCHEMA` in the module allows the use of the web components in the HTML markup without the compiler producing errors this code should be added into the `AppModule` and in every other modules that use your custom elements.
233Here is an example of adding it to `AppModule`:
234
235```tsx
236import { BrowserModule } from '@angular/platform-browser';
237import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
238import { FormsModule } from '@angular/forms';
239
240import { AppComponent } from './app.component';
241
242@NgModule({
243 declarations: [AppComponent],
244 imports: [BrowserModule, FormsModule],
245 bootstrap: [AppComponent],
246 schemas: [CUSTOM_ELEMENTS_SCHEMA],
247})
248export class AppModule {}
249```
250
251The `CUSTOM_ELEMENTS_SCHEMA` needs to be included in any module that uses custom elements.
252
253#### Calling defineCustomElements
254
255A component collection built with Stencil includes a main function that is used to load the components in the collection. That function is called `defineCustomElements()` and it needs to be called once during the bootstrapping of your application. One convenient place to do this is in `main.ts` as such:
256
257```tsx
258import { enableProdMode } from '@angular/core';
259import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
260
261import { AppModule } from './app/app.module';
262import { environment } from './environments/environment';
263
264// Note: loader import location set using "esmLoaderPath" within the output target confg
265import { defineCustomElements } from '@bulmil/core/dist/loader';
266
267if (environment.production) {
268 enableProdMode();
269}
270
271platformBrowserDynamic()
272 .bootstrapModule(AppModule)
273 .catch((err) => console.log(err));
274defineCustomElements(window);
275```
276
277#### Edge and IE11 polyfills
278
279If you want your custom elements to be able to work on older browser, you should add the `applyPolyfills()` that surrond the `defineCustomElements()` function.
280
281```tsx
282import { applyPolyfills, defineCustomElements } from '@bulmil/core/dist/loader';
283...
284applyPolyfills().then(() => {
285 defineCustomElements(window)
286})
287
288```
289
290#### Accessing components using ViewChild and ViewChildren
291
292Once included, components could be referenced in your code using `ViewChild` and `ViewChildren` as in the following example:
293
294```tsx
295import { Component, ElementRef, ViewChild } from '@angular/core';
296
297import '@bulmil/core/dist';
298
299@Component({
300 selector: 'app-home',
301 template: ` <bm-button #button></bm-button> `,
302 styleUrls: ['./home.component.scss'],
303})
304export class HomeComponent {
305 @ViewChild('button') buttonComponent: ElementRef<HTMLBulmilComponentElement>;
306
307 async onAction() {
308 await this.buttonComponent.nativeElement.componentMethod();
309 }
310}
311```
312
313---
314
315### Ember
316
317Working with Stencil components in Ember is really easy thanks to the `ember-cli-stencil` addon. It handles:
318
319- Importing the required files into your `vendor.js`
320- Copying the component definitions into your `assets` directory
321- Optionally generating a wrapper component for improved compatibility with older Ember versions
322
323Start off by installing the Ember addon
324
325```bash
326ember install ember-cli-stencil
327```
328
329Now, when you build your application, Stencil collections in your dependencies will automatically be discovered and pulled into your application. You can just start using the custom elements in your `hbs` files with no further work needed. For more information, check out the [`ember-cli-stencil` documentation](https://github.com/alexlafroscia/ember-cli-stencil).
330
331---
332
333## Development
334
3351. Clone this repository
3362. Install dependencies using `yarn install` or `npm install`
3373. Start development server using `yarn storybook` or `npm run storybook`
338
339## 📑 License
340
341[MIT License](./LICENSE)