├── polymer3
├── .gitignore
├── src
│ ├── index.js
│ ├── my-todo-styles.js
│ ├── todo-input-styles.js
│ ├── todo-item.js
│ ├── todo-input.js
│ └── my-todo.js
├── polymer.json
├── rollup.config.js
├── README.md
├── index.html
└── package.json
├── atomico
├── .gitignore
├── public
│ ├── logo.png
│ ├── preview.png
│ └── index.html
├── README.md
├── src
│ ├── style.css
│ ├── todo-input
│ │ ├── style.css
│ │ └── index.js
│ └── todo-item
│ │ ├── index.js
│ │ └── style.css
├── package.json
└── rollup.config.js
├── dist
└── .gitignore
├── stencil-0.16
├── src
│ ├── global
│ │ ├── app.ts
│ │ └── app.css
│ ├── assets
│ │ └── icon
│ │ │ ├── icon.png
│ │ │ └── favicon.ico
│ ├── manifest.json
│ ├── components
│ │ ├── my-todo
│ │ │ ├── my-todo.css
│ │ │ └── my-todo.tsx
│ │ ├── todo-input
│ │ │ ├── todo-input.css
│ │ │ └── todo-input.tsx
│ │ └── todo-item
│ │ │ ├── todo-item.tsx
│ │ │ └── todo-item.css
│ ├── index.html
│ └── components.d.ts
├── .editorconfig
├── .gitignore
├── stencil.config.ts
├── tsconfig.json
├── package.json
├── LICENSE
└── readme.md
├── slim-js
├── src
│ ├── index.js
│ ├── todo-app.css
│ ├── directives
│ │ └── bind-boolean.js
│ ├── components
│ │ ├── todo-input.css
│ │ ├── todo-input.js
│ │ ├── todo-item.js
│ │ └── todo-item.css
│ └── todo-app.js
├── jsconfig.json
├── .babelrc
├── webpack.config.js
├── index.html
└── package.json
├── polymer2
├── .gitignore
├── manifest.json
├── polymer.json
├── package.json
├── bower.json
├── README.md
├── index.html
├── test
│ └── my-todo
│ │ └── my-todo_test.html
└── src
│ └── todo-input
│ └── todo-input.html
├── non-web-components-refs
├── angular
│ ├── src
│ │ ├── assets
│ │ │ └── .gitkeep
│ │ ├── environments
│ │ │ ├── environment.prod.ts
│ │ │ └── environment.ts
│ │ ├── styles.css
│ │ ├── favicon.ico
│ │ ├── tsconfig.app.json
│ │ ├── tsconfig.spec.json
│ │ ├── tslint.json
│ │ ├── main.ts
│ │ ├── browserslist
│ │ ├── app
│ │ │ ├── app.module.ts
│ │ │ ├── todo-input
│ │ │ │ └── todo-input.component.ts
│ │ │ └── app.component.ts
│ │ ├── test.ts
│ │ ├── karma.conf.js
│ │ └── index.html
│ ├── .editorconfig
│ ├── tsconfig.json
│ ├── .gitignore
│ ├── README.md
│ └── package.json
├── vue
│ ├── vue.config.js
│ ├── babel.config.js
│ ├── public
│ │ ├── favicon.ico
│ │ └── index.html
│ ├── src
│ │ ├── assets
│ │ │ └── logo.png
│ │ ├── main.js
│ │ ├── App.vue
│ │ └── components
│ │ │ ├── todo-input.vue
│ │ │ └── my-todo.vue
│ ├── .gitignore
│ ├── README.md
│ └── package.json
└── react
│ ├── public
│ ├── favicon.ico
│ ├── manifest.json
│ └── index.html
│ ├── src
│ ├── index.js
│ ├── index.css
│ └── components
│ │ ├── my-todo
│ │ ├── my-todo.css
│ │ └── my-todo.js
│ │ ├── todo-input
│ │ ├── todo-input.css
│ │ └── todo-input.js
│ │ └── todo-item
│ │ ├── todo-item.js
│ │ └── todo-item.css
│ ├── .gitignore
│ └── package.json
├── skatejs-lit-html
├── .gitignore
├── .babelrc
├── webpack.config.js
├── src
│ ├── index.js
│ ├── input.js
│ ├── util.js
│ └── app.js
├── package.json
└── index.html
├── skatejs-preact
├── .gitignore
├── .babelrc
├── webpack.config.js
├── src
│ ├── index.js
│ ├── util.js
│ ├── input.js
│ └── app.js
├── package.json
└── index.html
├── svelte
├── src
│ ├── main.js
│ └── components
│ │ ├── TodoInput.html
│ │ └── MyTodo.html
├── .gitignore
├── package.json
├── public
│ └── index.html
├── rollup.config.js
└── README.md
├── solid
├── .gitignore
├── src
│ ├── MyTodo.css
│ ├── TodoInput.css
│ ├── TodoItem.jsx
│ ├── TodoInput.jsx
│ ├── MyTodo.jsx
│ └── TodoItem.css
├── rollup.config.js
├── public
│ └── index.html
└── package.json
├── .firebaserc
├── vue
├── vue.config.js
├── public
│ ├── favicon.ico
│ └── index.html
├── src
│ ├── assets
│ │ └── logo.png
│ ├── main.js
│ └── components
│ │ ├── todo-input.vue
│ │ └── my-todo.vue
├── .gitignore
├── package.json
└── index.html
├── stencil-0.11
├── src
│ ├── assets
│ │ └── icon
│ │ │ ├── icon.png
│ │ │ └── favicon.ico
│ ├── manifest.json
│ ├── components
│ │ ├── my-todo
│ │ │ ├── my-todo.css
│ │ │ └── my-todo.tsx
│ │ ├── todo-input
│ │ │ ├── todo-input.css
│ │ │ └── todo-input.tsx
│ │ └── todo-item
│ │ │ ├── todo-item.tsx
│ │ │ └── todo-item.css
│ ├── global
│ │ └── app.css
│ └── index.html
├── stencil.config.ts
├── .editorconfig
├── .gitignore
├── tsconfig.json
├── LICENSE
├── .github
│ └── ISSUE_TEMPLATE.md
├── package.json
└── readme.md
├── native-shadow-dom
├── webpack.config.js
├── src
│ ├── index.js
│ └── todo-input.js
├── package.json
└── index.html
├── functional-element
├── public
│ ├── functional-element.d.ts
│ └── index.html
├── tsconfig.json
├── rollup.config.js
├── package.json
├── src
│ ├── todo-input.js
│ └── my-todo.js
└── index.html
├── lit-element-0.6
├── src
│ ├── index.js
│ └── todo-input.js
├── package.json
└── index.html
├── lit-element-2.1
├── src
│ ├── index.js
│ ├── todo-input.js
│ └── my-todo.js
├── package.json
└── index.html
├── tests
├── commands
│ ├── addItem.js
│ ├── checkItem.js
│ ├── uncheckItem.js
│ └── removeItem.js
└── suite
│ └── wc.js
├── firebase.json
├── angular-elements
├── src
│ ├── main.ts
│ ├── todo.module.ts
│ ├── index.html
│ ├── todo-input.ts
│ └── my-todo.ts
├── tsconfig.json
├── README.md
├── .gitignore
├── package.json
├── webpack.config.js
└── LICENSE
├── benchmark
├── package.json
└── filesize.js
├── templates
├── group.ejs
└── row.ejs
├── generateIndex.js
├── LICENSE
├── .gitignore
├── native
└── js
│ ├── todo-input.js
│ ├── my-todo.js
│ └── todo-item.js
├── README.md
└── nightwatch.json
/polymer3/.gitignore:
--------------------------------------------------------------------------------
1 | build/
--------------------------------------------------------------------------------
/atomico/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/dist/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
--------------------------------------------------------------------------------
/stencil-0.16/src/global/app.ts:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/slim-js/src/index.js:
--------------------------------------------------------------------------------
1 | import './todo-app';
--------------------------------------------------------------------------------
/polymer2/.gitignore:
--------------------------------------------------------------------------------
1 | build/
2 | bower_components/
--------------------------------------------------------------------------------
/non-web-components-refs/angular/src/assets/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/skatejs-lit-html/.gitignore:
--------------------------------------------------------------------------------
1 | dist
2 | node_modules
3 |
--------------------------------------------------------------------------------
/skatejs-preact/.gitignore:
--------------------------------------------------------------------------------
1 | dist
2 | node_modules
3 |
--------------------------------------------------------------------------------
/svelte/src/main.js:
--------------------------------------------------------------------------------
1 | import './components/MyTodo.html';
2 |
--------------------------------------------------------------------------------
/solid/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | public/bundle.*
--------------------------------------------------------------------------------
/skatejs-lit-html/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["stage-0"]
3 | }
4 |
--------------------------------------------------------------------------------
/skatejs-preact/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["react", "stage-0"]
3 | }
4 |
--------------------------------------------------------------------------------
/.firebaserc:
--------------------------------------------------------------------------------
1 | {
2 | "projects": {
3 | "default": "wc-todo"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/vue/vue.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | lintOnSave: true,
3 | baseUrl: '/vue/'
4 | }
--------------------------------------------------------------------------------
/slim-js/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "experimentalDecorators": true
4 | }
5 | }
--------------------------------------------------------------------------------
/svelte/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | public/bundle.*
4 | package-lock.json
5 | yarn.lock
--------------------------------------------------------------------------------
/polymer3/src/index.js:
--------------------------------------------------------------------------------
1 | import './todo-input.js';
2 | import './todo-item.js';
3 | import './my-todo.js';
4 |
--------------------------------------------------------------------------------
/vue/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shprink/web-components-todo/HEAD/vue/public/favicon.ico
--------------------------------------------------------------------------------
/atomico/public/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shprink/web-components-todo/HEAD/atomico/public/logo.png
--------------------------------------------------------------------------------
/non-web-components-refs/vue/vue.config.js:
--------------------------------------------------------------------------------
1 | // vue.config.js
2 | module.exports = {
3 | baseUrl: '/vue/',
4 | }
--------------------------------------------------------------------------------
/polymer3/polymer.json:
--------------------------------------------------------------------------------
1 | {
2 | "builds": [
3 | {
4 | "preset": "es6-bundled"
5 | }
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/vue/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shprink/web-components-todo/HEAD/vue/src/assets/logo.png
--------------------------------------------------------------------------------
/atomico/public/preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shprink/web-components-todo/HEAD/atomico/public/preview.png
--------------------------------------------------------------------------------
/non-web-components-refs/vue/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/non-web-components-refs/angular/src/environments/environment.prod.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: true
3 | };
4 |
--------------------------------------------------------------------------------
/non-web-components-refs/angular/src/styles.css:
--------------------------------------------------------------------------------
1 | /* You can add global styles to this file, and also import other style files */
2 |
--------------------------------------------------------------------------------
/polymer2/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "todo",
3 | "short_name": "todo",
4 | "start_url": "/",
5 | "display": "standalone"
6 | }
7 |
--------------------------------------------------------------------------------
/stencil-0.11/src/assets/icon/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shprink/web-components-todo/HEAD/stencil-0.11/src/assets/icon/icon.png
--------------------------------------------------------------------------------
/stencil-0.16/src/assets/icon/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shprink/web-components-todo/HEAD/stencil-0.16/src/assets/icon/icon.png
--------------------------------------------------------------------------------
/stencil-0.11/src/assets/icon/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shprink/web-components-todo/HEAD/stencil-0.11/src/assets/icon/favicon.ico
--------------------------------------------------------------------------------
/stencil-0.16/src/assets/icon/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shprink/web-components-todo/HEAD/stencil-0.16/src/assets/icon/favicon.ico
--------------------------------------------------------------------------------
/non-web-components-refs/angular/src/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shprink/web-components-todo/HEAD/non-web-components-refs/angular/src/favicon.ico
--------------------------------------------------------------------------------
/non-web-components-refs/vue/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shprink/web-components-todo/HEAD/non-web-components-refs/vue/public/favicon.ico
--------------------------------------------------------------------------------
/non-web-components-refs/vue/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shprink/web-components-todo/HEAD/non-web-components-refs/vue/src/assets/logo.png
--------------------------------------------------------------------------------
/non-web-components-refs/react/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shprink/web-components-todo/HEAD/non-web-components-refs/react/public/favicon.ico
--------------------------------------------------------------------------------
/native-shadow-dom/webpack.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | module: {
3 | rules: [
4 | {
5 | use: "babel-loader"
6 | }
7 | ]
8 | }
9 | };
10 |
--------------------------------------------------------------------------------
/skatejs-lit-html/webpack.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | module: {
3 | rules: [
4 | {
5 | use: "babel-loader"
6 | }
7 | ]
8 | }
9 | };
10 |
--------------------------------------------------------------------------------
/skatejs-preact/webpack.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | module: {
3 | rules: [
4 | {
5 | use: "babel-loader"
6 | }
7 | ]
8 | }
9 | };
10 |
--------------------------------------------------------------------------------
/polymer2/polymer.json:
--------------------------------------------------------------------------------
1 | {
2 | "lint": {
3 | "rules": [
4 | "polymer-2"
5 | ]
6 | },
7 | "builds": [
8 | {
9 | "preset": "es6-bundled"
10 | }
11 | ]
12 | }
--------------------------------------------------------------------------------
/non-web-components-refs/vue/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './components/my-todo'
3 |
4 | Vue.config.productionTip = false
5 |
6 | new Vue({
7 | render: h => h(App)
8 | }).$mount('#app')
9 |
--------------------------------------------------------------------------------
/polymer3/rollup.config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | input: 'src/index.js',
3 | output: {
4 | file: 'build/es6-bundled/src_tmp/index.js',
5 | format: 'es',
6 | sourcemap: false
7 | }
8 | };
9 |
--------------------------------------------------------------------------------
/functional-element/public/functional-element.d.ts:
--------------------------------------------------------------------------------
1 | import { UserFunction } from './index.d';
2 | export { html } from 'lit-html';
3 | export declare function customElement(tagName: string, userFunction: UserFunction): void;
4 |
--------------------------------------------------------------------------------
/skatejs-preact/src/index.js:
--------------------------------------------------------------------------------
1 | import App from "./app";
2 | import Input from "./input";
3 | import Item from "./item";
4 |
5 | customElements.define("todo-app", App);
6 | customElements.define("todo-input", Input);
7 | customElements.define("todo-item", Item);
8 |
--------------------------------------------------------------------------------
/skatejs-lit-html/src/index.js:
--------------------------------------------------------------------------------
1 | import App from "./app";
2 | import Input from "./input";
3 | import Item from "./item";
4 |
5 | customElements.define("todo-app", App);
6 | customElements.define("todo-input", Input);
7 | customElements.define("todo-item", Item);
8 |
--------------------------------------------------------------------------------
/non-web-components-refs/angular/src/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../out-tsc/app",
5 | "types": []
6 | },
7 | "exclude": [
8 | "test.ts",
9 | "**/*.spec.ts"
10 | ]
11 | }
12 |
--------------------------------------------------------------------------------
/slim-js/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [[
3 | "@babel/preset-env",
4 | {
5 | "targets": {
6 | "esmodules": true
7 | },
8 | "useBuiltIns": "usage"
9 | }
10 | ]],
11 | "plugins": [
12 | ["@babel/plugin-proposal-decorators", { "legacy": true }]
13 | ]
14 | }
--------------------------------------------------------------------------------
/polymer2/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "polymer",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "directories": {
7 | "test": "test"
8 | },
9 | "scripts": {
10 | "build": "polymer build"
11 | },
12 | "author": "",
13 | "license": "MIT"
14 | }
15 |
--------------------------------------------------------------------------------
/lit-element-0.6/src/index.js:
--------------------------------------------------------------------------------
1 | import MyTodo from "./my-todo";
2 | import TodoInput from "./todo-input";
3 | import TodoItem from "./todo-item";
4 |
5 | window.customElements.define('my-todo', MyTodo);
6 | window.customElements.define('todo-input', TodoInput);
7 | window.customElements.define('todo-item', TodoItem);
--------------------------------------------------------------------------------
/lit-element-2.1/src/index.js:
--------------------------------------------------------------------------------
1 | import MyTodo from "./my-todo";
2 | import TodoInput from "./todo-input";
3 | import TodoItem from "./todo-item";
4 |
5 | window.customElements.define('my-todo', MyTodo);
6 | window.customElements.define('todo-input', TodoInput);
7 | window.customElements.define('todo-item', TodoItem);
--------------------------------------------------------------------------------
/native-shadow-dom/src/index.js:
--------------------------------------------------------------------------------
1 | import MyTodo from "./my-todo";
2 | import TodoInput from "./todo-input";
3 | import TodoItem from "./todo-item";
4 |
5 | window.customElements.define('my-todo', MyTodo);
6 | window.customElements.define('todo-input', TodoInput);
7 | window.customElements.define('todo-item', TodoItem);
--------------------------------------------------------------------------------
/tests/commands/addItem.js:
--------------------------------------------------------------------------------
1 | exports.command = function (text, wait) {
2 | return this.setValue('#new-todo', text)
3 | .sendKeys('#new-todo', this.Keys.ENTER)
4 | .waitForElementVisible(`todo-item[text="${text}"]`, wait)
5 | .assert.cssClassNotPresent(`todo-item[text="${text}"]`, 'completed');
6 | };
7 |
--------------------------------------------------------------------------------
/vue/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 | /distWC
5 |
6 | # local env files
7 | .env.local
8 | .env.*.local
9 |
10 | # Log files
11 | npm-debug.log*
12 | yarn-debug.log*
13 | yarn-error.log*
14 |
15 | # Editor directories and files
16 | .idea
17 | .vscode
18 | *.suo
19 | *.ntvs*
20 | *.njsproj
21 | *.sln
22 |
--------------------------------------------------------------------------------
/stencil-0.11/stencil.config.ts:
--------------------------------------------------------------------------------
1 | import { Config } from '@stencil/core';
2 |
3 | // https://stenciljs.com/docs/config
4 |
5 | export const config: Config = {
6 | globalStyle: 'src/global/app.css',
7 | outputTargets: [
8 | {
9 | type: 'www',
10 | baseUrl: process.env.DEMO_BASE_URL
11 | }
12 | ]
13 | };
14 |
--------------------------------------------------------------------------------
/tests/commands/checkItem.js:
--------------------------------------------------------------------------------
1 | exports.command = function (text, wait) {
2 | return this
3 | .assert.cssClassNotPresent(`todo-item[text="${text}"] > li`, 'completed')
4 | .click(`todo-item[text="${text}"] input[type="checkbox"]`)
5 | .assert.cssClassPresent(`todo-item[text="${text}"] > li`, 'completed')
6 | };
7 |
--------------------------------------------------------------------------------
/tests/commands/uncheckItem.js:
--------------------------------------------------------------------------------
1 | exports.command = function (text, wait) {
2 | return this
3 | .assert.cssClassPresent(`todo-item[text="${text}"] > li`, 'completed')
4 | .click(`todo-item[text="${text}"] input[type="checkbox"]`)
5 | .assert.cssClassNotPresent(`todo-item[text="${text}"] > li`, 'completed')
6 | };
7 |
--------------------------------------------------------------------------------
/stencil-0.11/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 |
3 | root = true
4 |
5 | [*]
6 | charset = utf-8
7 | indent_style = space
8 | indent_size = 2
9 | end_of_line = lf
10 | insert_final_newline = true
11 | trim_trailing_whitespace = true
12 |
13 | [*.md]
14 | insert_final_newline = false
15 | trim_trailing_whitespace = false
16 |
--------------------------------------------------------------------------------
/stencil-0.16/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 |
3 | root = true
4 |
5 | [*]
6 | charset = utf-8
7 | indent_style = space
8 | indent_size = 2
9 | end_of_line = lf
10 | insert_final_newline = true
11 | trim_trailing_whitespace = true
12 |
13 | [*.md]
14 | insert_final_newline = false
15 | trim_trailing_whitespace = false
16 |
--------------------------------------------------------------------------------
/functional-element/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "declaration": true,
4 | "declarationDir": "./dist",
5 | "module": "es6",
6 | "noImplicitAny": true,
7 | "outDir": "./dist",
8 | "target": "es6"
9 | },
10 | "include": [
11 | "src/**/*"
12 | ],
13 | "exclude": ["node_modules"]
14 | }
15 |
--------------------------------------------------------------------------------
/non-web-components-refs/angular/.editorconfig:
--------------------------------------------------------------------------------
1 | # Editor configuration, see http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | indent_style = space
7 | indent_size = 2
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 | [*.md]
12 | max_line_length = off
13 | trim_trailing_whitespace = false
14 |
--------------------------------------------------------------------------------
/non-web-components-refs/vue/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 | # local env files
6 | .env.local
7 | .env.*.local
8 |
9 | # Log files
10 | npm-debug.log*
11 | yarn-debug.log*
12 | yarn-error.log*
13 |
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 | *.suo
18 | *.ntvs*
19 | *.njsproj
20 | *.sln
21 | *.sw*
22 |
--------------------------------------------------------------------------------
/stencil-0.11/src/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Stencil Starter",
3 | "short_name": "Stencil",
4 | "start_url": "/",
5 | "display": "standalone",
6 | "icons": [{
7 | "src": "assets/icon/icon.png",
8 | "sizes": "512x512",
9 | "type": "image/png"
10 | }],
11 | "background_color": "#16161d",
12 | "theme_color": "#16161d"
13 | }
--------------------------------------------------------------------------------
/stencil-0.16/src/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Stencil Starter",
3 | "short_name": "Stencil",
4 | "start_url": "/",
5 | "display": "standalone",
6 | "icons": [{
7 | "src": "assets/icon/icon.png",
8 | "sizes": "512x512",
9 | "type": "image/png"
10 | }],
11 | "background_color": "#16161d",
12 | "theme_color": "#16161d"
13 | }
--------------------------------------------------------------------------------
/non-web-components-refs/react/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 |
4 | import './index.css';
5 | import MyTodo from './components/my-todo/my-todo';
6 | import registerServiceWorker from './registerServiceWorker';
7 |
8 | ReactDOM.render(, document.getElementById('root'));
9 | registerServiceWorker();
10 |
--------------------------------------------------------------------------------
/non-web-components-refs/vue/README.md:
--------------------------------------------------------------------------------
1 | # vue
2 |
3 | ## Project setup
4 | ```
5 | yarn install
6 | ```
7 |
8 | ### Compiles and hot-reloads for development
9 | ```
10 | yarn run serve
11 | ```
12 |
13 | ### Compiles and minifies for production
14 | ```
15 | yarn run build
16 | ```
17 |
18 | ### Lints and fixes files
19 | ```
20 | yarn run lint
21 | ```
22 |
--------------------------------------------------------------------------------
/firebase.json:
--------------------------------------------------------------------------------
1 | {
2 | "hosting": {
3 | "public": "dist",
4 | "ignore": [
5 | "firebase.json",
6 | "**/.*",
7 | "**/node_modules/**"
8 | ],
9 | "rewrites": [
10 | {
11 | "source": "**",
12 | "destination": "/index.html"
13 | }
14 | ]
15 | }
16 | }
--------------------------------------------------------------------------------
/tests/commands/removeItem.js:
--------------------------------------------------------------------------------
1 | exports.command = function (text, wait) {
2 | return this
3 | .assert.elementPresent(`todo-item[text="${text}"] button`)
4 | .click(`todo-item[text="${text}"] button`, () => console.log('eee'))
5 | .waitForElementNotPresent(`todo-item[text="${text}"]`, wait)
6 | .assert.elementNotPresent(`todo-item[text="${text}"]`)
7 | };
8 |
--------------------------------------------------------------------------------
/non-web-components-refs/angular/src/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../out-tsc/spec",
5 | "types": [
6 | "jasmine",
7 | "node"
8 | ]
9 | },
10 | "files": [
11 | "test.ts",
12 | "polyfills.ts"
13 | ],
14 | "include": [
15 | "**/*.spec.ts",
16 | "**/*.d.ts"
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/stencil-0.11/.gitignore:
--------------------------------------------------------------------------------
1 | dist/
2 | !www/favicon.ico
3 | www/
4 |
5 | *~
6 | *.sw[mnpcod]
7 | *.log
8 | *.lock
9 | *.tmp
10 | *.tmp.*
11 | log.txt
12 | *.sublime-project
13 | *.sublime-workspace
14 |
15 | .stencil/
16 | .idea/
17 | .vscode/
18 | .sass-cache/
19 | .versions/
20 | node_modules/
21 | $RECYCLE.BIN/
22 |
23 | .DS_Store
24 | Thumbs.db
25 | UserInterfaceState.xcuserstate
26 | .env
27 |
--------------------------------------------------------------------------------
/stencil-0.16/.gitignore:
--------------------------------------------------------------------------------
1 | dist/
2 | !www/favicon.ico
3 | www/
4 |
5 | *~
6 | *.sw[mnpcod]
7 | *.log
8 | *.lock
9 | *.tmp
10 | *.tmp.*
11 | log.txt
12 | *.sublime-project
13 | *.sublime-workspace
14 |
15 | .stencil/
16 | .idea/
17 | .vscode/
18 | .sass-cache/
19 | .versions/
20 | node_modules/
21 | $RECYCLE.BIN/
22 |
23 | .DS_Store
24 | Thumbs.db
25 | UserInterfaceState.xcuserstate
26 | .env
27 |
--------------------------------------------------------------------------------
/non-web-components-refs/react/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 |
6 | # testing
7 | /coverage
8 |
9 | # production
10 | /build
11 |
12 | # misc
13 | .DS_Store
14 | .env.local
15 | .env.development.local
16 | .env.test.local
17 | .env.production.local
18 |
19 | npm-debug.log*
20 | yarn-debug.log*
21 | yarn-error.log*
22 |
--------------------------------------------------------------------------------
/non-web-components-refs/react/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | }
10 | ],
11 | "start_url": "./index.html",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/non-web-components-refs/react/src/index.css:
--------------------------------------------------------------------------------
1 | html, body {
2 | margin: 0;
3 | padding: 0;
4 | }
5 |
6 | #back {
7 | margin: 50px 0;
8 | display: block;
9 | }
10 |
11 | body {
12 | font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
13 | line-height: 1.4em;
14 | background: #f5f5f5;
15 | color: #4d4d4d;
16 | min-width: 230px;
17 | max-width: 550px;
18 | margin: 0 auto;
19 | font-weight: 300;
20 | }
--------------------------------------------------------------------------------
/non-web-components-refs/angular/src/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tslint.json",
3 | "rules": {
4 | "directive-selector": [
5 | true,
6 | "attribute",
7 | "app",
8 | "camelCase"
9 | ],
10 | "component-selector": [
11 | true,
12 | "element",
13 | "app",
14 | "kebab-case"
15 | ]
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/angular-elements/src/main.ts:
--------------------------------------------------------------------------------
1 | import 'zone.js/dist/zone';
2 |
3 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
4 |
5 | import { registerAsCustomElements } from '@angular/elements';
6 |
7 | import { TodoModule } from './todo.module';
8 | import { MyTodo } from './my-todo';
9 |
10 | registerAsCustomElements([
11 | MyTodo,
12 | ], () =>
13 | platformBrowserDynamic().bootstrapModule(TodoModule)
14 | );
15 |
--------------------------------------------------------------------------------
/polymer2/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "todo",
3 | "main": "index.html",
4 | "dependencies": {
5 | "polymer": "Polymer/polymer#^2.0.0",
6 | "iron-input": "PolymerElements/iron-input#^2.0.1",
7 | "iron-form": "PolymerElements/iron-form#^2.1.3"
8 | },
9 | "devDependencies": {
10 | "web-component-tester": "Polymer/web-component-tester#^6.0.0",
11 | "webcomponentsjs": "webcomponents/webcomponentsjs#^1.0.0"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/angular-elements/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "compilerOptions": {
4 | "outDir": "./dist/out-tsc",
5 | "sourceMap": true,
6 | "declaration": false,
7 | "module": "es2015",
8 | "moduleResolution": "node",
9 | "emitDecoratorMetadata": true,
10 | "experimentalDecorators": true,
11 | "target": "es2015",
12 | "typeRoots": ["node_modules/@types"],
13 | "lib": ["es2017", "dom"]
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/non-web-components-refs/angular/src/main.ts:
--------------------------------------------------------------------------------
1 | import { enableProdMode } from '@angular/core';
2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
3 |
4 | import { AppModule } from './app/app.module';
5 | import { environment } from './environments/environment';
6 |
7 | if (environment.production) {
8 | enableProdMode();
9 | }
10 |
11 | platformBrowserDynamic().bootstrapModule(AppModule)
12 | .catch(err => console.error(err));
13 |
14 |
--------------------------------------------------------------------------------
/non-web-components-refs/angular/src/browserslist:
--------------------------------------------------------------------------------
1 | # This file is currently used by autoprefixer to adjust CSS to support the below specified browsers
2 | # For additional information regarding the format and rule options, please see:
3 | # https://github.com/browserslist/browserslist#queries
4 | #
5 | # For IE 9-11 support, please remove 'not' from the last line of the file and adjust as needed
6 |
7 | > 0.5%
8 | last 2 versions
9 | Firefox ESR
10 | not dead
11 | not IE 9-11
--------------------------------------------------------------------------------
/non-web-components-refs/react/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "reactv",
3 | "version": "0.1.0",
4 | "private": true,
5 | "homepage": "https://wc-todo.firebaseapp.com/react/",
6 | "dependencies": {
7 | "react": "^16.5.1",
8 | "react-dom": "^16.5.1",
9 | "react-scripts": "1.1.5"
10 | },
11 | "scripts": {
12 | "start": "react-scripts start",
13 | "build": "react-scripts build",
14 | "test": "react-scripts test --env=jsdom",
15 | "eject": "react-scripts eject"
16 | }
17 | }
--------------------------------------------------------------------------------
/stencil-0.16/stencil.config.ts:
--------------------------------------------------------------------------------
1 | import { Config } from '@stencil/core';
2 |
3 | // https://stenciljs.com/docs/config
4 |
5 | export const config: Config = {
6 | globalStyle: 'src/global/app.css',
7 | globalScript: 'src/global/app.ts',
8 | prerenderIndex: null,
9 | outputTargets: [
10 | {
11 | type: 'www',
12 | baseUrl: process.env.DEMO_BASE_URL,
13 | // uncomment the following line to disable service workers in production
14 | serviceWorker: null
15 | }
16 | ]
17 | };
--------------------------------------------------------------------------------
/native-shadow-dom/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "native-shadow-dom",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "build": "webpack --mode production",
8 | "start": "webpack --mode development --watch"
9 | },
10 | "author": "",
11 | "license": "MIT",
12 | "devDependencies": {
13 | "babel-loader": "^7.1.2",
14 | "babel-preset-stage-0": "^6.24.1",
15 | "webpack": "^4.0.0-beta.2",
16 | "webpack-cli": "^2.0.6"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/solid/src/MyTodo.css:
--------------------------------------------------------------------------------
1 | :host {
2 | display: block;
3 | }
4 |
5 | h1 {
6 | font-size: 60px;
7 | font-weight: 100;
8 | text-align: center;
9 | color: rgba(175, 47, 47, 0.15);
10 | }
11 |
12 | section {
13 | background: #fff;
14 | margin: 30px 0 40px 0;
15 | position: relative;
16 | box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
17 | }
18 |
19 | #list-container {
20 | margin: 0;
21 | padding: 0;
22 | list-style: none;
23 | border-top: 1px solid #e6e6e6;
24 | }
--------------------------------------------------------------------------------
/slim-js/src/todo-app.css:
--------------------------------------------------------------------------------
1 | :host {
2 | display: block;
3 | }
4 |
5 | h1 {
6 | font-size: 100px;
7 | font-weight: 100;
8 | text-align: center;
9 | color: rgba(175, 47, 47, 0.15);
10 | }
11 |
12 | section {
13 | background: #fff;
14 | margin: 30px 0 40px 0;
15 | position: relative;
16 | box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
17 | }
18 |
19 | #list-container {
20 | margin: 0;
21 | padding: 0;
22 | list-style: none;
23 | border-top: 1px solid #e6e6e6;
24 | }
--------------------------------------------------------------------------------
/vue/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import wrap from '@vue/web-component-wrapper';
3 |
4 | Vue.config.productionTip = false
5 |
6 | import MyTodo from './components/my-todo.vue';
7 | import TodoInput from './components/todo-input.vue';
8 | import TodoItem from './components/todo-item.vue';
9 |
10 | window.customElements.define('vue-my-todo', wrap(Vue, MyTodo));
11 | window.customElements.define('vue-todo-input', wrap(Vue, TodoInput));
12 | window.customElements.define('vue-todo-item', wrap(Vue, TodoItem));
--------------------------------------------------------------------------------
/slim-js/src/directives/bind-boolean.js:
--------------------------------------------------------------------------------
1 | import { Slim } from "slim-js"
2 |
3 | const test = attr => /^(bind.boolean):(\S+)/.exec(attr.nodeName)
4 | const execute = (source, target, attribute, match) => {
5 | const tAttr = match[2]
6 | const path = attribute.value
7 | Slim.bind(source, target, path, () => {
8 | if (Slim.lookup(source, path)) {
9 | target.setAttribute(tAttr, '')
10 | } else {
11 | target.removeAttribute(tAttr)
12 | }
13 | })
14 | }
15 |
16 | Slim.customDirective(test, execute)
--------------------------------------------------------------------------------
/atomico/README.md:
--------------------------------------------------------------------------------
1 | # atomico-todo
2 |
3 | This is a small example of a component generated with [**Atomico**](https://github.com/uppercod/atomico) and packaged thanks to [**Rollup**](https://rollupjs.org/guide/en)
4 |
5 | As learning of the use of Atomico i invite you to see explore the directory **/src**.
6 |
7 | |File|Min|Gzip|
8 | |----|---|----|
9 | |Atomico| 3.76kB| 1.63kB|
10 | |atom-todo| 4.15kB| 1.43kB|
11 | |Total| 7,91kB| 3.06kB|
12 |
13 | [](https://uppercod.github.io/atomico-todo)
14 |
15 |
16 |
--------------------------------------------------------------------------------
/lit-element-2.1/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "lit-element",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "build": "webpack --mode production",
9 | "start": "webpack --mode development --watch"
10 | },
11 | "author": "",
12 | "license": "MIT",
13 | "dependencies": {
14 | "lit-element": "2.1.0"
15 | },
16 | "devDependencies": {
17 | "webpack": "^4.17.2",
18 | "webpack-cli": "^3.1.0"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/non-web-components-refs/angular/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "compilerOptions": {
4 | "baseUrl": "./",
5 | "outDir": "./dist/out-tsc",
6 | "sourceMap": true,
7 | "declaration": false,
8 | "module": "es2015",
9 | "moduleResolution": "node",
10 | "emitDecoratorMetadata": true,
11 | "experimentalDecorators": true,
12 | "target": "es5",
13 | "typeRoots": [
14 | "node_modules/@types"
15 | ],
16 | "lib": [
17 | "es2017",
18 | "dom"
19 | ]
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/stencil-0.11/src/components/my-todo/my-todo.css:
--------------------------------------------------------------------------------
1 | :host {
2 | display: block;
3 | }
4 |
5 | h1 {
6 | font-size: 100px;
7 | font-weight: 100;
8 | text-align: center;
9 | color: rgba(175, 47, 47, 0.15);
10 | }
11 |
12 | section {
13 | background: #fff;
14 | margin: 30px 0 40px 0;
15 | position: relative;
16 | box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
17 | }
18 |
19 | #list-container {
20 | margin: 0;
21 | padding: 0;
22 | list-style: none;
23 | border-top: 1px solid #e6e6e6;
24 | }
25 |
--------------------------------------------------------------------------------
/stencil-0.16/src/components/my-todo/my-todo.css:
--------------------------------------------------------------------------------
1 | :host {
2 | display: block;
3 | }
4 |
5 | h1 {
6 | font-size: 100px;
7 | font-weight: 100;
8 | text-align: center;
9 | color: rgba(175, 47, 47, 0.15);
10 | }
11 |
12 | section {
13 | background: #fff;
14 | margin: 30px 0 40px 0;
15 | position: relative;
16 | box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
17 | }
18 |
19 | #list-container {
20 | margin: 0;
21 | padding: 0;
22 | list-style: none;
23 | border-top: 1px solid #e6e6e6;
24 | }
25 |
--------------------------------------------------------------------------------
/non-web-components-refs/react/src/components/my-todo/my-todo.css:
--------------------------------------------------------------------------------
1 | .MyTodo h1 {
2 | font-size: 70px;
3 | line-height: 70px;
4 | font-weight: 100;
5 | text-align: center;
6 | color: rgba(175, 47, 47, 0.15);
7 | }
8 |
9 | .MyTodo section {
10 | background: #fff;
11 | margin: 30px 0 40px 0;
12 | position: relative;
13 | box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
14 | }
15 |
16 | .MyTodo #list-container {
17 | margin: 0;
18 | padding: 0;
19 | list-style: none;
20 | border-top: 1px solid #e6e6e6;
21 | }
--------------------------------------------------------------------------------
/atomico/src/style.css:
--------------------------------------------------------------------------------
1 | :host {
2 | display: block;
3 | }
4 |
5 | h1 {
6 | font-size: 70px;
7 | line-height: 70px;
8 | font-weight: 100;
9 | text-align: center;
10 | color: rgba(175, 47, 47, 0.15);
11 | }
12 |
13 | section {
14 | background: #fff;
15 | margin: 30px 0 40px 0;
16 | position: relative;
17 | box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
18 | }
19 |
20 | #list-container {
21 | margin: 0;
22 | padding: 0;
23 | list-style: none;
24 | border-top: 1px solid #e6e6e6;
25 | }
--------------------------------------------------------------------------------
/lit-element-0.6/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "lit-element",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "build": "webpack --mode production",
9 | "start": "webpack --mode development --watch"
10 | },
11 | "author": "",
12 | "license": "MIT",
13 | "dependencies": {
14 | "@polymer/lit-element": "^0.6.0-dev.6"
15 | },
16 | "devDependencies": {
17 | "webpack": "^4.17.2",
18 | "webpack-cli": "^3.1.0"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/benchmark/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "benchmark",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "build:filesize": "node ./filesize.js",
8 | "build:lighthouse": "node ./lighthouse.js http://localhost:3000"
9 | },
10 | "author": "",
11 | "license": "MIT",
12 | "dependencies": {
13 | "ascii-horizontal-barchart": "^1.3.3",
14 | "chrome-launcher": "^0.10.5",
15 | "lighthouse": "^4.2.0"
16 | },
17 | "devDependencies": {
18 | "ejs": "^2.6.1",
19 | "express": "^4.16.4"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/angular-elements/README.md:
--------------------------------------------------------------------------------
1 | # Angular Elements demo
2 |
3 | This project is a first try of using the experimental `@angular/elements`.
4 |
5 | It uses Ahead of Time Compilation provided by `@ngtools/webpack`.
6 |
7 | The bundle will run only in browsers supporting WebComponents.
8 |
9 | ## Install
10 |
11 | ```
12 | npm install
13 | ```
14 |
15 | ## Build
16 |
17 | Run `npm run build` to build the project. The build artifacts will be stored in the `dist/` directory.
18 |
19 | ## Run
20 |
21 | Run `npm run serve` to serve the index.html page with the builded element.
22 |
--------------------------------------------------------------------------------
/skatejs-lit-html/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "scripts": {
4 | "build": "webpack --mode production",
5 | "start": "webpack --mode development --watch"
6 | },
7 | "dependencies": {
8 | "@skatejs/renderer-lit-html": "^0.2.0",
9 | "lit-html": "^0.9.0",
10 | "skatejs": "^5.1.1"
11 | },
12 | "devDependencies": {
13 | "babel-loader": "^7.1.2",
14 | "babel-preset-stage-0": "^6.24.1",
15 | "prettier": "^1.10.2",
16 | "prettier-eslint": "^8.8.1",
17 | "webpack": "^4.0.0-beta.2",
18 | "webpack-cli": "^2.0.6"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/angular-elements/src/todo.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { FormsModule, ReactiveFormsModule } from '@angular/forms';
3 |
4 | import { BrowserModule } from '@angular/platform-browser';
5 | import { MyTodo } from './my-todo';
6 | import { TodoInput } from './todo-input';
7 | import { TodoItem } from './todo-item';
8 |
9 | @NgModule({
10 | imports: [BrowserModule, FormsModule, ReactiveFormsModule],
11 | declarations: [MyTodo, TodoInput, TodoItem],
12 | entryComponents: [MyTodo],
13 | })
14 | export class TodoModule {
15 | ngDoBootstrap() { }
16 | }
17 |
--------------------------------------------------------------------------------
/stencil-0.11/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "allowSyntheticDefaultImports": true,
4 | "allowUnreachableCode": false,
5 | "declaration": false,
6 | "experimentalDecorators": true,
7 | "lib": [
8 | "dom",
9 | "es2015"
10 | ],
11 | "moduleResolution": "node",
12 | "module": "es2015",
13 | "target": "es2015",
14 | "noUnusedLocals": true,
15 | "noUnusedParameters": true,
16 | "jsx": "react",
17 | "jsxFactory": "h"
18 | },
19 | "include": [
20 | "src"
21 | ],
22 | "exclude": [
23 | "node_modules"
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------
/stencil-0.16/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "allowSyntheticDefaultImports": true,
4 | "allowUnreachableCode": false,
5 | "declaration": false,
6 | "experimentalDecorators": true,
7 | "lib": [
8 | "dom",
9 | "es2015"
10 | ],
11 | "moduleResolution": "node",
12 | "module": "esnext",
13 | "target": "es2017",
14 | "noUnusedLocals": true,
15 | "noUnusedParameters": true,
16 | "jsx": "react",
17 | "jsxFactory": "h"
18 | },
19 | "include": [
20 | "src"
21 | ],
22 | "exclude": [
23 | "node_modules"
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------
/svelte/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "svelte-app",
3 | "version": "1.0.0",
4 | "devDependencies": {
5 | "rollup": "^0.65.2",
6 | "rollup-plugin-buble": "^0.19.2",
7 | "rollup-plugin-commonjs": "^9.1.6",
8 | "rollup-plugin-node-resolve": "^3.3.0",
9 | "rollup-plugin-svelte": "^4.0.0",
10 | "rollup-plugin-terser": "^2.0.2",
11 | "serve": "^10.0.1",
12 | "svelte": "^2.13.4"
13 | },
14 | "scripts": {
15 | "prebuild": "npm prune && npm install",
16 | "build": "rollup -c",
17 | "dev": "serve public & rollup -c -w",
18 | "start": "serve public"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/skatejs-preact/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "scripts": {
4 | "build": "webpack --mode production",
5 | "start": "webpack --mode development --watch"
6 | },
7 | "dependencies": {
8 | "@skatejs/renderer-preact": "^0.2.5",
9 | "preact": "^8.2.7",
10 | "skatejs": "^5.1.1"
11 | },
12 | "devDependencies": {
13 | "babel-loader": "^7.1.2",
14 | "babel-preset-react": "^6.24.1",
15 | "babel-preset-stage-0": "^6.24.1",
16 | "prettier": "^1.10.2",
17 | "prettier-eslint": "^8.8.1",
18 | "webpack": "^4.0.0-beta.2",
19 | "webpack-cli": "^2.0.6"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/non-web-components-refs/vue/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |

4 |
5 |
6 |
7 |
8 |
18 |
19 |
29 |
--------------------------------------------------------------------------------
/functional-element/rollup.config.js:
--------------------------------------------------------------------------------
1 | import commonjs from 'rollup-plugin-commonjs';
2 | import resolve from "rollup-plugin-node-resolve";
3 | import { terser } from 'rollup-plugin-terser';
4 | import typescript from 'rollup-plugin-typescript2'
5 |
6 | const production = !process.env.ROLLUP_WATCH;
7 |
8 | export default {
9 | input: 'src/my-todo.js',
10 | output: {
11 | sourcemap: true,
12 | format: 'iife',
13 | file: 'public/bundle.js',
14 | name: 'app'
15 | },
16 | plugins: [
17 | resolve(),
18 | typescript({
19 | typescript: require('typescript'),
20 | }),
21 | commonjs(),
22 | terser()
23 | ]
24 | };
--------------------------------------------------------------------------------
/templates/group.ejs:
--------------------------------------------------------------------------------
1 | <%- include('row', {project: row}); %>
2 | <% row.group.forEach(function(project){ %>
3 |
4 | |
5 | |-- <%= project.name %>
6 | |
7 |
8 |
9 |
12 | <%= project.size.toFixed(1) %>
13 |
14 | |
15 |
16 | <% }); %>
--------------------------------------------------------------------------------
/solid/src/TodoInput.css:
--------------------------------------------------------------------------------
1 | :host {
2 | display: block;
3 | }
4 |
5 | form {
6 | position: relative;
7 | font-size: 24px;
8 | border-bottom: 1px solid #ededed;
9 | }
10 |
11 | input {
12 | padding: 16px 16px 16px 60px;
13 | border: none;
14 | background: rgba(0, 0, 0, 0.003);
15 | position: relative;
16 | margin: 0;
17 | width: 100%;
18 | font-size: 24px;
19 | font-family: inherit;
20 | font-weight: inherit;
21 | line-height: 1.4em;
22 | border: 0;
23 | outline: none;
24 | color: inherit;
25 | padding: 6px;
26 | border: 1px solid #CCC;
27 | box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
28 | box-sizing: border-box;
29 | }
--------------------------------------------------------------------------------
/non-web-components-refs/react/src/components/todo-input/todo-input.css:
--------------------------------------------------------------------------------
1 | form {
2 | position: relative;
3 | font-size: 24px;
4 | border-bottom: 1px solid #ededed;
5 | }
6 |
7 | input {
8 | padding: 16px 16px 16px 60px;
9 | border: none;
10 | background: rgba(0, 0, 0, 0.003);
11 | position: relative;
12 | margin: 0;
13 | width: 100%;
14 | font-size: 24px;
15 | font-family: inherit;
16 | font-weight: inherit;
17 | line-height: 1.4em;
18 | border: 0;
19 | outline: none;
20 | color: inherit;
21 | padding: 6px;
22 | border: 1px solid #CCC;
23 | box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
24 | box-sizing: border-box;
25 | }
26 |
--------------------------------------------------------------------------------
/slim-js/webpack.config.js:
--------------------------------------------------------------------------------
1 | const HtmlWebpackPlugin = require('html-webpack-plugin')
2 |
3 | const mode = process.env.NODE_ENV || 'development'
4 |
5 | module.exports = {
6 | entry: './src/index.js',
7 | target: 'web',
8 | mode,
9 | module: {
10 | rules: [
11 | {
12 | test: /\.js$/,
13 | loader: 'babel-loader'
14 | },
15 | {
16 | test: /\.css$/,
17 | loader: 'raw-loader'
18 | }
19 | ]
20 | },
21 | devtool: 'sourcemap',
22 | devServer: {
23 | port: 1337,
24 | compress: true
25 | },
26 | plugins: [
27 | new HtmlWebpackPlugin({
28 | template: './index.html'
29 | })
30 | ]
31 | }
--------------------------------------------------------------------------------
/solid/src/TodoItem.jsx:
--------------------------------------------------------------------------------
1 | import { Component } from 'solid-components'
2 | import { r } from 'solid-js/dom'
3 |
4 | import style from './TodoItem.css'
5 |
6 | const TodoItem = (props, element) =>
7 | <>
8 |
9 |
10 | element.trigger('check', { detail: !props.checked })}
13 | />
14 |
17 |
18 |
19 | >
20 |
21 | Component('todo-item', { checked: false }, TodoItem);
22 |
--------------------------------------------------------------------------------
/stencil-0.11/src/components/todo-input/todo-input.css:
--------------------------------------------------------------------------------
1 | :host {
2 | display: block;
3 | }
4 |
5 | form {
6 | position: relative;
7 | font-size: 24px;
8 | border-bottom: 1px solid #ededed;
9 | }
10 |
11 | input {
12 | padding: 16px 16px 16px 60px;
13 | border: none;
14 | background: rgba(0, 0, 0, 0.003);
15 | position: relative;
16 | margin: 0;
17 | width: 100%;
18 | font-size: 24px;
19 | font-family: inherit;
20 | font-weight: inherit;
21 | line-height: 1.4em;
22 | border: 0;
23 | outline: none;
24 | color: inherit;
25 | padding: 6px;
26 | border: 1px solid #CCC;
27 | box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
28 | box-sizing: border-box;
29 | }
30 |
--------------------------------------------------------------------------------
/stencil-0.16/src/components/todo-input/todo-input.css:
--------------------------------------------------------------------------------
1 | :host {
2 | display: block;
3 | }
4 |
5 | form {
6 | position: relative;
7 | font-size: 24px;
8 | border-bottom: 1px solid #ededed;
9 | }
10 |
11 | input {
12 | padding: 16px 16px 16px 60px;
13 | border: none;
14 | background: rgba(0, 0, 0, 0.003);
15 | position: relative;
16 | margin: 0;
17 | width: 100%;
18 | font-size: 24px;
19 | font-family: inherit;
20 | font-weight: inherit;
21 | line-height: 1.4em;
22 | border: 0;
23 | outline: none;
24 | color: inherit;
25 | padding: 6px;
26 | border: 1px solid #CCC;
27 | box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
28 | box-sizing: border-box;
29 | }
30 |
--------------------------------------------------------------------------------
/slim-js/src/components/todo-input.css:
--------------------------------------------------------------------------------
1 | :host {
2 | display: block;
3 | }
4 |
5 | form {
6 | position: relative;
7 | font-size: 24px;
8 | border-bottom: 1px solid #ededed;
9 | }
10 |
11 | input {
12 | padding: 16px 16px 16px 60px;
13 | border: none;
14 | background: rgba(0, 0, 0, 0.003);
15 | position: relative;
16 | margin: 0;
17 | margin-bottom: 2px;
18 | width: 100%;
19 | font-size: 24px;
20 | font-family: inherit;
21 | font-weight: inherit;
22 | line-height: 1.4em;
23 | border: 0;
24 | outline: none;
25 | color: inherit;
26 | padding: 6px;
27 | border: 1px solid #CCC;
28 | box-shadow: 0 0px 1px 0px rgba(0, 0, 0, 0.5);
29 | box-sizing: border-box;
30 | }
31 |
--------------------------------------------------------------------------------
/stencil-0.16/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "stencil",
3 | "private": true,
4 | "version": "0.0.1",
5 | "description": "Stencil App Starter",
6 | "scripts": {
7 | "build": "DEMO_BASE_URL=/stencil-0.16 stencil build",
8 | "build:prerendered": "DEMO_BASE_URL=/stencil-prerendered stencil build --prerender",
9 | "start": "stencil build --dev --watch --serve",
10 | "test": "stencil test --spec --e2e",
11 | "test.watch": "stencil test --spec --e2e --watchAll"
12 | },
13 | "dependencies": {
14 | "@stencil/core": "~0.16.2",
15 | "@stencil/router": "~0.3.1"
16 | },
17 | "license": "MIT",
18 | "devDependencies": {
19 | "workbox-build": "3.4.1"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/atomico/src/todo-input/style.css:
--------------------------------------------------------------------------------
1 | :host {
2 | display: block;
3 | }
4 |
5 | form {
6 | position: relative;
7 | font-size: 24px;
8 | border-bottom: 1px solid #ededed;
9 | }
10 |
11 | input {
12 | padding: 16px 16px 16px 60px;
13 | border: none;
14 | background: rgba(0, 0, 0, 0.003);
15 | position: relative;
16 | margin: 0;
17 | width: 100%;
18 | font-size: 24px;
19 | font-family: inherit;
20 | font-weight: inherit;
21 | line-height: 1.4em;
22 | border: 0;
23 | outline: none;
24 | color: inherit;
25 | padding: 6px;
26 | border: 1px solid #CCC;
27 | box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
28 | box-sizing: border-box;
29 | }
--------------------------------------------------------------------------------
/non-web-components-refs/angular/src/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { BrowserModule } from '@angular/platform-browser';
2 | import { NgModule } from '@angular/core';
3 | import { FormsModule } from '@angular/forms';
4 |
5 | import { AppComponent } from './app.component';
6 | import { TodoInputComponent } from './todo-input/todo-input.component';
7 | import { TodoItemComponent } from './todo-item/todo-item.component';
8 |
9 | @NgModule({
10 | declarations: [
11 | AppComponent,
12 | TodoInputComponent,
13 | TodoItemComponent
14 | ],
15 | imports: [
16 | BrowserModule,
17 | FormsModule,
18 | ],
19 | providers: [],
20 | bootstrap: [AppComponent]
21 | })
22 | export class AppModule { }
23 |
--------------------------------------------------------------------------------
/slim-js/src/components/todo-input.js:
--------------------------------------------------------------------------------
1 | import { tag, template, useShadow } from "slim-js/Decorators";
2 | import { Slim } from "slim-js";
3 |
4 | @tag('todo-input')
5 | @template(/*html*/`
6 |
7 |
10 | `)
11 | @useShadow(true)
12 | export default class extends Slim {
13 | onSubmit (e) {
14 | const { input } = this
15 | input.value = input.value.trim()
16 | const { value: text } = input
17 | e.preventDefault()
18 | if (text) {
19 | this.callAttribute('on-new-item', text)
20 | input.value = null
21 | }
22 | }
23 | }
--------------------------------------------------------------------------------
/angular-elements/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # compiled output
4 | /tmp
5 | /out-tsc
6 |
7 | # dependencies
8 | /node_modules
9 |
10 | # IDEs and editors
11 | /.idea
12 | .project
13 | .classpath
14 | .c9/
15 | *.launch
16 | .settings/
17 | *.sublime-workspace
18 |
19 | # IDE - VSCode
20 | .vscode/*
21 | !.vscode/settings.json
22 | !.vscode/tasks.json
23 | !.vscode/launch.json
24 | !.vscode/extensions.json
25 |
26 | # misc
27 | /.sass-cache
28 | /connect.lock
29 | /coverage
30 | /libpeerconnection.log
31 | npm-debug.log
32 | testem.log
33 | /typings
34 |
35 | # e2e
36 | /e2e/*.js
37 | /e2e/*.map
38 |
39 | # System Files
40 | .DS_Store
41 | Thumbs.db
42 |
--------------------------------------------------------------------------------
/non-web-components-refs/angular/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # compiled output
4 | /dist
5 | /tmp
6 | /out-tsc
7 |
8 | # dependencies
9 | /node_modules
10 |
11 | # IDEs and editors
12 | /.idea
13 | .project
14 | .classpath
15 | .c9/
16 | *.launch
17 | .settings/
18 | *.sublime-workspace
19 |
20 | # IDE - VSCode
21 | .vscode/*
22 | !.vscode/settings.json
23 | !.vscode/tasks.json
24 | !.vscode/launch.json
25 | !.vscode/extensions.json
26 |
27 | # misc
28 | /.sass-cache
29 | /connect.lock
30 | /coverage
31 | /libpeerconnection.log
32 | npm-debug.log
33 | yarn-error.log
34 | testem.log
35 | /typings
36 |
37 | # System Files
38 | .DS_Store
39 | Thumbs.db
40 |
--------------------------------------------------------------------------------
/solid/rollup.config.js:
--------------------------------------------------------------------------------
1 | import babel from 'rollup-plugin-babel';
2 | import resolve from 'rollup-plugin-node-resolve';
3 | import commonjs from 'rollup-plugin-commonjs';
4 | import postcss from 'rollup-plugin-postcss'
5 | import { terser } from 'rollup-plugin-terser';
6 |
7 | const production = !process.env.ROLLUP_WATCH;
8 |
9 | export default {
10 | input: 'src/MyTodo.jsx',
11 | output: {
12 | // sourcemap: true,
13 | format: 'iife',
14 | file: 'public/bundle.js',
15 | name: 'app'
16 | },
17 | plugins: [
18 | babel({
19 | exclude: 'node_modules/**',
20 | plugins: ["jsx-dom-expressions"]
21 | }),
22 | resolve({ extensions: ['.js', '.jsx'] }),
23 | postcss({ inject: false }),
24 | production && terser()
25 | ]
26 | };
--------------------------------------------------------------------------------
/stencil-0.11/src/global/app.css:
--------------------------------------------------------------------------------
1 | /*
2 | Global App CSS
3 | ----------------------
4 | Use this file for styles that should be applied to all components.
5 | For example, "font-family" within the "body" selector is a CSS property
6 | most apps will want applied to all components.
7 |
8 | Any global CSS variables should also be applied here.
9 | */
10 |
11 | html, body {
12 | margin: 0;
13 | padding: 0;
14 | }
15 |
16 | #back {
17 | margin: 50px 0;
18 | display: block;
19 | }
20 |
21 | body {
22 | font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
23 | line-height: 1.4em;
24 | background: #f5f5f5;
25 | color: #4d4d4d;
26 | min-width: 230px;
27 | max-width: 550px;
28 | margin: 0 auto;
29 | font-weight: 300;
30 | }
--------------------------------------------------------------------------------
/stencil-0.16/src/global/app.css:
--------------------------------------------------------------------------------
1 | /*
2 | Global App CSS
3 | ----------------------
4 | Use this file for styles that should be applied to all components.
5 | For example, "font-family" within the "body" selector is a CSS property
6 | most apps will want applied to all components.
7 |
8 | Any global CSS variables should also be applied here.
9 | */
10 |
11 | html, body {
12 | margin: 0;
13 | padding: 0;
14 | }
15 |
16 | #back {
17 | margin: 50px 0;
18 | display: block;
19 | }
20 |
21 | body {
22 | font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
23 | line-height: 1.4em;
24 | background: #f5f5f5;
25 | color: #4d4d4d;
26 | min-width: 230px;
27 | max-width: 550px;
28 | margin: 0 auto;
29 | font-weight: 300;
30 | }
--------------------------------------------------------------------------------
/non-web-components-refs/angular/src/test.ts:
--------------------------------------------------------------------------------
1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files
2 |
3 | import 'zone.js/dist/zone-testing';
4 | import { getTestBed } from '@angular/core/testing';
5 | import {
6 | BrowserDynamicTestingModule,
7 | platformBrowserDynamicTesting
8 | } from '@angular/platform-browser-dynamic/testing';
9 |
10 | declare const require: any;
11 |
12 | // First, initialize the Angular testing environment.
13 | getTestBed().initTestEnvironment(
14 | BrowserDynamicTestingModule,
15 | platformBrowserDynamicTesting()
16 | );
17 | // Then we find all the tests.
18 | const context = require.context('./', true, /\.spec\.ts$/);
19 | // And load the modules.
20 | context.keys().map(context);
21 |
--------------------------------------------------------------------------------
/non-web-components-refs/angular/src/environments/environment.ts:
--------------------------------------------------------------------------------
1 | // This file can be replaced during build by using the `fileReplacements` array.
2 | // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`.
3 | // The list of file replacements can be found in `angular.json`.
4 |
5 | export const environment = {
6 | production: false
7 | };
8 |
9 | /*
10 | * For easier debugging in development mode, you can import the following file
11 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
12 | *
13 | * This import should be commented out in production mode because it will have a negative impact
14 | * on performance if an error is thrown.
15 | */
16 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI.
17 |
--------------------------------------------------------------------------------
/solid/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Solid Todo
9 |
32 |
33 |
34 |
35 |
36 |
37 | ⬅ Back to other implementations
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/svelte/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Svelte app
9 |
32 |
33 |
34 |
35 |
36 |
37 | ⬅ Back to other implementations
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/solid/src/TodoInput.jsx:
--------------------------------------------------------------------------------
1 | import { Component } from 'solid-components';
2 | import { useState } from 'solid-js';
3 | import { r } from 'solid-js/dom';
4 |
5 | import style from './TodoInput.css';
6 |
7 | const TodoInput = (props, element) => {
8 | const [state, setState] = useState({ value: '' }),
9 | handleSubmit = e => {
10 | e.preventDefault();
11 | if (!state.value) return;
12 | element.trigger('submit', { detail: state.value });
13 | setState({ value: '' });
14 | };
15 | return <>
16 |
17 |
25 | >
26 | }
27 |
28 | Component('todo-input', TodoInput);
--------------------------------------------------------------------------------
/templates/row.ejs:
--------------------------------------------------------------------------------
1 | class="table-light" <% } %>>
2 | |
3 | <%= project.name %>
4 | <% if (project.new) { %>
5 | NEW!
6 | <% } %>
7 | |
8 | Demo |
9 |
10 | <% if (project.docs) { %>
11 | Docs
12 | <% } %>
13 | |
14 |
15 |
16 | <%= project.size.toFixed(1) %>
18 |
19 | |
20 |
--------------------------------------------------------------------------------
/slim-js/src/components/todo-item.js:
--------------------------------------------------------------------------------
1 | import { tag, template, useShadow } from "slim-js/Decorators";
2 | import { Slim } from "slim-js";
3 |
4 | @tag('todo-item')
5 | @template(/*html*/`
6 |
9 |
10 |
13 |
14 |
15 |
16 | `)
17 | @useShadow(true)
18 | export default class TodoItem extends Slim {
19 |
20 | onChecked () {
21 | this.checked = this.data.checked = this.checkbox.checked
22 | this.commit()
23 | }
24 |
25 | getClass (checked) {
26 | return checked ? 'completed' : ''
27 | }
28 |
29 | onRemove (e) {
30 | this.callAttribute('on-remove', this.data)
31 | }
32 |
33 | }
--------------------------------------------------------------------------------
/slim-js/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Todo Demo with slim-js
7 |
30 |
31 |
32 | ⬅ Back to other implementations
33 |
34 |
35 |
--------------------------------------------------------------------------------
/slim-js/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "slim-todo",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "dev": "webpack-dev-server --watch --progress --colors --config webpack.config.js",
9 | "build": "NODE_ENV=production webpack"
10 | },
11 | "author": "Avichay Eyal ",
12 | "license": "MIT",
13 | "dependencies": {
14 | "slim-js": "^3.3.4"
15 | },
16 | "devDependencies": {
17 | "@babel/cli": "^7.0.0",
18 | "@babel/core": "^7.0.1",
19 | "@babel/plugin-proposal-decorators": "^7.0.0",
20 | "@babel/preset-env": "^7.0.0",
21 | "babel-loader": "^8.0.2",
22 | "html-webpack-plugin": "^3.2.0",
23 | "raw-loader": "^0.5.1",
24 | "webpack": "^4.18.0",
25 | "webpack-cli": "^3.1.0",
26 | "webpack-dev-server": "^3.1.8"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/stencil-0.11/src/components/todo-item/todo-item.tsx:
--------------------------------------------------------------------------------
1 |
2 | import { Component, Prop, Event, EventEmitter } from '@stencil/core';
3 |
4 | @Component({
5 | tag: 'todo-item',
6 | styleUrl: 'todo-item.css',
7 | // shadow: true,
8 | })
9 | export class TodoItem {
10 | @Prop() checked: boolean;
11 | @Prop() text: string;
12 | @Prop() index: number;
13 | @Event() onTodoItemChecked: EventEmitter;
14 | @Event() onTodoItemRemove: EventEmitter;
15 |
16 | handleOnRemove = () => this.onTodoItemRemove.emit(this.index);
17 | handleOnChecked = () => this.onTodoItemChecked.emit(this.index);
18 |
19 | render() {
20 | return (
21 |
22 |
23 |
24 |
25 |
26 | );
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/stencil-0.16/src/components/todo-item/todo-item.tsx:
--------------------------------------------------------------------------------
1 |
2 | import { Component, Prop, Event, EventEmitter } from '@stencil/core';
3 |
4 | @Component({
5 | tag: 'todo-item',
6 | styleUrl: 'todo-item.css',
7 | // shadow: true,
8 | })
9 | export class TodoItem {
10 | @Prop() checked: boolean;
11 | @Prop() text: string;
12 | @Prop() index: number;
13 | @Event() onTodoItemChecked: EventEmitter;
14 | @Event() onTodoItemRemove: EventEmitter;
15 |
16 | handleOnRemove = () => this.onTodoItemRemove.emit(this.index);
17 | handleOnChecked = () => this.onTodoItemChecked.emit(this.index);
18 |
19 | render() {
20 | return (
21 |
22 |
23 |
24 |
25 |
26 | );
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/skatejs-lit-html/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SkateJS & LitHTML
6 |
7 |
30 |
31 |
32 |
33 | ⬅ Back to other implementations
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/skatejs-preact/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SkateJS & Preact
6 |
7 |
30 |
31 |
32 |
33 | ⬅ Back to other implementations
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/stencil-0.11/src/components/todo-input/todo-input.tsx:
--------------------------------------------------------------------------------
1 | import { Component, State, Event, EventEmitter } from '@stencil/core';
2 |
3 | @Component({
4 | tag: 'todo-input',
5 | styleUrl: 'todo-input.css',
6 | // shadow: true,
7 | })
8 | export class TodoInput {
9 | @Event() onTodoInputSubmit: EventEmitter;
10 | @State() value: string;
11 |
12 | handleOnSubmit = (e) => {
13 | e.preventDefault();
14 | if (!this.value) return;
15 | this.onTodoInputSubmit.emit(this.value);
16 | this.value = '';
17 | }
18 |
19 | handleInputChange = (event) => this.value = event.target.value;
20 |
21 | render() {
22 | return (
23 |
31 | );
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/stencil-0.16/src/components/todo-input/todo-input.tsx:
--------------------------------------------------------------------------------
1 | import { Component, State, Event, EventEmitter } from '@stencil/core';
2 |
3 | @Component({
4 | tag: 'todo-input',
5 | styleUrl: 'todo-input.css',
6 | // shadow: true,
7 | })
8 | export class TodoInput {
9 | @Event() onTodoInputSubmit: EventEmitter;
10 | @State() value: string;
11 |
12 | handleOnSubmit = (e) => {
13 | e.preventDefault();
14 | if (!this.value) return;
15 | this.onTodoInputSubmit.emit(this.value);
16 | this.value = '';
17 | }
18 |
19 | handleInputChange = (event) => this.value = event.target.value;
20 |
21 | render() {
22 | return (
23 |
31 | );
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/native-shadow-dom/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Native Web Component Todo
6 |
7 |
30 |
31 |
32 |
33 | ⬅ Back to other implementations
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/polymer2/README.md:
--------------------------------------------------------------------------------
1 | # \
2 |
3 |
4 |
5 | ## Install the Polymer-CLI
6 |
7 | First, make sure you have the [Polymer CLI](https://www.npmjs.com/package/polymer-cli) installed. Then run `polymer serve` to serve your application locally.
8 |
9 | ## Viewing Your Application
10 |
11 | ```
12 | $ polymer serve
13 | ```
14 |
15 | ## Building Your Application
16 |
17 | ```
18 | $ polymer build
19 | ```
20 |
21 | This will create builds of your application in the `build/` directory, optimized to be served in production. You can then serve the built versions by giving `polymer serve` a folder to serve from:
22 |
23 | ```
24 | $ polymer serve build/default
25 | ```
26 |
27 | ## Running Tests
28 |
29 | ```
30 | $ polymer test
31 | ```
32 |
33 | Your application is already set up to be tested via [web-component-tester](https://github.com/Polymer/web-component-tester). Run `polymer test` to run your application's test suite locally.
34 |
--------------------------------------------------------------------------------
/polymer3/README.md:
--------------------------------------------------------------------------------
1 | # \
2 |
3 |
4 |
5 | ## Install the Polymer-CLI
6 |
7 | First, make sure you have the [Polymer CLI](https://www.npmjs.com/package/polymer-cli) installed. Then run `polymer serve` to serve your application locally.
8 |
9 | ## Viewing Your Application
10 |
11 | ```
12 | $ polymer serve
13 | ```
14 |
15 | ## Building Your Application
16 |
17 | ```
18 | $ polymer build
19 | ```
20 |
21 | This will create builds of your application in the `build/` directory, optimized to be served in production. You can then serve the built versions by giving `polymer serve` a folder to serve from:
22 |
23 | ```
24 | $ polymer serve build/default
25 | ```
26 |
27 | ## Running Tests
28 |
29 | ```
30 | $ polymer test
31 | ```
32 |
33 | Your application is already set up to be tested via [web-component-tester](https://github.com/Polymer/web-component-tester). Run `polymer test` to run your application's test suite locally.
34 |
--------------------------------------------------------------------------------
/functional-element/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "functional-element-todo",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "my-todo.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "build": "rollup -c",
9 | "dev": "serve public & rollup -c -w",
10 | "start": "serve public"
11 | },
12 | "author": "Jordan Last ",
13 | "license": "MIT",
14 | "devDependencies": {
15 | "jsverify-es-module": "0.0.2",
16 | "rollup": "^0.65.2",
17 | "rollup-plugin-buble": "^0.19.2",
18 | "rollup-plugin-commonjs": "^9.1.6",
19 | "rollup-plugin-node-resolve": "^3.3.0",
20 | "rollup-plugin-svelte": "^4.0.0",
21 | "rollup-plugin-terser": "^2.0.2",
22 | "rollup-plugin-typescript2": "^0.20.1",
23 | "serve": "^10.1.2",
24 | "typescript": "^3.3.4000"
25 | },
26 | "dependencies": {
27 | "functional-element": "0.0.9"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/solid/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "solid-todo",
3 | "version": "0.0.1",
4 | "source": "src/index.js",
5 | "author": "Ryan Carniato",
6 | "license": "MIT",
7 | "repository": {
8 | "type": "git",
9 | "url": "https://github.com/ryansolid/solid"
10 | },
11 | "scripts": {
12 | "prebuild": "npm prune && npm install",
13 | "build": "rollup -c",
14 | "dev": "serve public & rollup -c -w",
15 | "start": "serve public"
16 | },
17 | "dependencies": {
18 | "babel-plugin-jsx-dom-expressions": "0.3.6",
19 | "solid-components": "0.0.6",
20 | "solid-js": "0.3.4"
21 | },
22 | "devDependencies": {
23 | "@babel/core": "7.2.2",
24 | "rollup": "^1.0.0",
25 | "rollup-plugin-babel": "4.2.0",
26 | "rollup-plugin-commonjs": "^9.2.0",
27 | "rollup-plugin-node-resolve": "^4.0.0",
28 | "rollup-plugin-postcss": "^1.6.3",
29 | "rollup-plugin-terser": "4.0.1",
30 | "serve": "^10.0.1"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/atomico/src/todo-input/index.js:
--------------------------------------------------------------------------------
1 | import { h, Element } from "atomico";
2 | import style from "./style.css";
3 |
4 | export default class extends Element {
5 | constructor() {
6 | super();
7 | this.attachShadow({ mode: "open" });
8 | }
9 | static get props() {
10 | return ["placeholder"];
11 | }
12 | render() {
13 | return (
14 |
30 | );
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/polymer3/src/my-todo-styles.js:
--------------------------------------------------------------------------------
1 | import {
2 | Element as PolymerElement
3 | }
4 | from '../node_modules/@polymer/polymer/polymer-element.js';
5 |
6 | const myTodoStyleElement = document.createElement('dom-module');
7 | myTodoStyleElement.innerHTML =
8 | `
9 |
35 | `
36 | myTodoStyleElement.register('my-todo-style-element');
--------------------------------------------------------------------------------
/atomico/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Atomico todo
8 |
31 |
32 |
33 | ⬅ Back to other implementations
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/stencil-0.16/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Stencil Starter App
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | ⬅ Back to other implementations
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/non-web-components-refs/react/src/components/todo-item/todo-item.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import PropTypes from 'prop-types';
3 | import './todo-item.css';
4 |
5 | class MyTodo extends Component {
6 | static propTypes = {
7 | checked: PropTypes.bool.isRequired,
8 | text: PropTypes.string.isRequired,
9 | index: PropTypes.number.isRequired,
10 | onTodoItemRemove: PropTypes.func.isRequired,
11 | onTodoItemChecked: PropTypes.func.isRequired,
12 | };
13 |
14 | handleOnRemove = () => this.props.onTodoItemRemove(this.props.index);
15 | handleOnChecked = () => this.props.onTodoItemChecked(this.props.index);
16 |
17 | render() {
18 | const { checked, text } = this.props;
19 | return (
20 |
21 |
22 |
23 |
24 |
25 | );
26 | }
27 | }
28 |
29 | export default MyTodo;
30 |
31 |
--------------------------------------------------------------------------------
/stencil-0.11/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Stencil Starter App
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | ⬅ Back to other implementations
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/non-web-components-refs/vue/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "start": "npm run serve",
7 | "serve": "vue-cli-service serve",
8 | "build": "vue-cli-service build",
9 | "lint": "vue-cli-service lint"
10 | },
11 | "dependencies": {
12 | "vue": "^2.5.17"
13 | },
14 | "devDependencies": {
15 | "@vue/cli-plugin-babel": "^3.0.3",
16 | "@vue/cli-plugin-eslint": "^3.0.3",
17 | "@vue/cli-service": "^3.0.3",
18 | "vue-template-compiler": "^2.5.17"
19 | },
20 | "eslintConfig": {
21 | "root": true,
22 | "env": {
23 | "node": true
24 | },
25 | "extends": [
26 | "plugin:vue/essential",
27 | "eslint:recommended"
28 | ],
29 | "rules": {},
30 | "parserOptions": {
31 | "parser": "babel-eslint"
32 | }
33 | },
34 | "postcss": {
35 | "plugins": {
36 | "autoprefixer": {}
37 | }
38 | },
39 | "browserslist": [
40 | "> 1%",
41 | "last 2 versions",
42 | "not ie <= 8"
43 | ]
44 | }
45 |
--------------------------------------------------------------------------------
/non-web-components-refs/react/src/components/todo-input/todo-input.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import PropTypes from 'prop-types';
3 | import './todo-input.css';
4 |
5 | class MyTodo extends Component {
6 | state = { value: '' };
7 |
8 | static propTypes = {
9 | onTodoInputSubmit: PropTypes.func.isRequired,
10 | };
11 |
12 | handleOnSubmit = (e) => {
13 | e.preventDefault();
14 | if (!this.state.value) return;
15 | this.props.onTodoInputSubmit(this.state.value);
16 | this.setState({ value: '' });
17 | }
18 |
19 | handleInputChange = (event) => this.setState({ value: event.target.value });
20 |
21 | render() {
22 | const { checked, text } = this.props;
23 | return (
24 |
32 | );
33 | }
34 | }
35 |
36 | export default MyTodo;
37 |
38 |
39 |
--------------------------------------------------------------------------------
/atomico/src/todo-item/index.js:
--------------------------------------------------------------------------------
1 | import { h, Element } from "atomico";
2 | import style from "./style.css";
3 | export default class extends Element {
4 | constructor() {
5 | super();
6 | this.attachShadow({ mode: "open" });
7 | }
8 | static get props() {
9 | return ["text", "checked"];
10 | }
11 | render() {
12 | return (
13 |
14 |
15 | {
18 | this.dispatch("toggle");
19 | }}
20 | checked={this.props.checked}
21 | />
22 |
23 |
30 |
31 | );
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/vue/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-web-component-wrapper",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "start": "vue-cli-service serve --open",
7 | "build": "npm run build:wc && cp index.html dist/ && rm dist/demo.html",
8 | "build:wc": "vue-cli-service build --target wc --name vue 'src/components/*.vue'",
9 | "lint": "vue-cli-service lint"
10 | },
11 | "dependencies": {
12 | "vue": "^2.5.13"
13 | },
14 | "devDependencies": {
15 | "@vue/cli-plugin-babel": "^3.0.0-alpha.11",
16 | "@vue/cli-plugin-eslint": "^3.0.0-alpha.11",
17 | "@vue/cli-service": "^3.0.0-alpha.11",
18 | "vue-template-compiler": "^2.5.13"
19 | },
20 | "babel": {
21 | "presets": [
22 | "@vue/app"
23 | ]
24 | },
25 | "eslintConfig": {
26 | "root": true,
27 | "extends": [
28 | "plugin:vue/essential",
29 | "eslint:recommended"
30 | ]
31 | },
32 | "postcss": {
33 | "plugins": {
34 | "autoprefixer": {}
35 | }
36 | },
37 | "browserslist": [
38 | "> 1%",
39 | "last 2 versions",
40 | "not ie <= 8"
41 | ]
42 | }
--------------------------------------------------------------------------------
/angular-elements/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-elements-demo",
3 | "version": "0.0.0",
4 | "license": "MIT",
5 | "scripts": {
6 | "build": "webpack",
7 | "start": "npm run build && http-server ./dist"
8 | },
9 | "private": true,
10 | "dependencies": {
11 | "@angular/common": "^5.2.2",
12 | "@angular/compiler": "^5.2.2",
13 | "@angular/core": "^5.2.2",
14 | "@angular/elements": "github:angular/elements-builds#labs/elements",
15 | "@angular/forms": "^5.2.2",
16 | "@angular/platform-browser": "^5.2.2",
17 | "@angular/platform-browser-dynamic": "^5.2.2",
18 | "core-js": "^2.5.3",
19 | "mutation-observer": "^1.0.3",
20 | "rxjs": "^5.5.6",
21 | "zone.js": "^0.8.20"
22 | },
23 | "devDependencies": {
24 | "@angular/cli": "^1.6.6",
25 | "@angular/compiler-cli": "^5.2.2",
26 | "@ngtools/webpack": "^1.9.6",
27 | "compression-webpack-plugin": "^1.1.3",
28 | "custom-elements": "^1.0.2",
29 | "html-webpack-plugin": "^2.30.1",
30 | "http-server": "^0.11.1",
31 | "typescript": "~2.6.2",
32 | "webpack": "^3.10.0"
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/non-web-components-refs/vue/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Todos Vue
10 |
33 |
34 |
35 |
36 |
39 | ⬅ Back to other implementations
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/vue/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | vue-web-component-wrapper
10 |
11 |
12 |
13 |
14 |
15 | ⬅ Back to other implementations
16 |
17 |
18 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/generateIndex.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const ejs = require('ejs');
3 | const benchmark = require('./benchmark/filesize.js');
4 | const { legacy, latest } = require('./benchmark/meta');
5 |
6 | const latestWithBytes = benchmark.filesizeGzipped(latest);
7 | const metasWithKb = latestWithBytes.map((project) => ({
8 | ...project,
9 | size: project.size / 1000,
10 | group: project.group ? benchmark.filesizeGzipped(legacy[project.group]).map((project) => ({
11 | ...project,
12 | size: project.size / 1000,
13 | })) : null,
14 | }));
15 |
16 | console.log('metasWithKb', metasWithKb)
17 | const maxSize = Math.max(...metasWithKb.map(project => project.size));
18 | const WCprojects = metasWithKb.filter(project => project.wc);
19 | const NonWCprojects = metasWithKb.filter(project => !project.wc);
20 |
21 | ejs.renderFile('./templates/index.ejs', {
22 | WCprojects,
23 | NonWCprojects,
24 | maxSize,
25 | }, {}, function (err, str) {
26 | fs.writeFile('dist/index.html', str, (err) => {
27 | if (err) throw err;
28 | console.log('The file has been saved!');
29 | });
30 | });
--------------------------------------------------------------------------------
/non-web-components-refs/angular/src/karma.conf.js:
--------------------------------------------------------------------------------
1 | // Karma configuration file, see link for more information
2 | // https://karma-runner.github.io/1.0/config/configuration-file.html
3 |
4 | module.exports = function (config) {
5 | config.set({
6 | basePath: '',
7 | frameworks: ['jasmine', '@angular-devkit/build-angular'],
8 | plugins: [
9 | require('karma-jasmine'),
10 | require('karma-chrome-launcher'),
11 | require('karma-jasmine-html-reporter'),
12 | require('karma-coverage-istanbul-reporter'),
13 | require('@angular-devkit/build-angular/plugins/karma')
14 | ],
15 | client: {
16 | clearContext: false // leave Jasmine Spec Runner output visible in browser
17 | },
18 | coverageIstanbulReporter: {
19 | dir: require('path').join(__dirname, '../coverage'),
20 | reports: ['html', 'lcovonly'],
21 | fixWebpackSourcePaths: true
22 | },
23 | reporters: ['progress', 'kjhtml'],
24 | port: 9876,
25 | colors: true,
26 | logLevel: config.LOG_INFO,
27 | autoWatch: true,
28 | browsers: ['Chrome'],
29 | singleRun: false
30 | });
31 | };
--------------------------------------------------------------------------------
/angular-elements/webpack.config.js:
--------------------------------------------------------------------------------
1 | /* global module */
2 | const AotPlugin = require('@ngtools/webpack').AngularCompilerPlugin;
3 | const CompressionPlugin = require("compression-webpack-plugin");
4 | const HtmlWebpackPlugin = require('html-webpack-plugin');
5 | const path = require('path');
6 |
7 | module.exports = {
8 | entry: './src/main.ts',
9 | resolve: {
10 | mainFields: ['es2015', 'browser', 'module', 'main']
11 | },
12 | module: {
13 | rules: [{ test: /\.ts$/, loaders: ['@ngtools/webpack'] }]
14 | },
15 | plugins: [
16 | new AotPlugin({
17 | tsConfigPath: './tsconfig.json',
18 | entryModule: path.resolve(__dirname, './src/todo.module#TodoModule')
19 | }),
20 | new HtmlWebpackPlugin({
21 | inject: true,
22 | template: 'src/index.html'
23 | }),
24 | // new CompressionPlugin({
25 | // asset: "[path].gz[query]",
26 | // algorithm: "gzip",
27 | // test: /\.js$|\.css$/,
28 | // threshold: 10240,
29 | // minRatio: 0.8
30 | // })
31 | ],
32 | output: {
33 | path: __dirname + '/dist',
34 | filename: 'main.bundle.js'
35 | }
36 | };
37 |
--------------------------------------------------------------------------------
/tests/suite/wc.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const url = `file:///${path.join(__dirname, '../..')}/native/index.html`;
3 |
4 | const pause = 200;
5 | const wait = 5000;
6 |
7 | module.exports = {
8 | '@tags': ['wc'],
9 | 'Todo sequence': browser =>
10 | browser.url(url)
11 | .waitForElementVisible('#new-todo', wait)
12 | .waitForElementVisible('todo-item[text="my initial todo"]', wait)
13 | .addItem('first added todo', wait)
14 | .pause(pause)
15 | .addItem('second added todo', wait)
16 | .pause(pause)
17 | .checkItem('first added todo', wait)
18 | .pause(pause)
19 | .uncheckItem('first added todo', wait)
20 | .pause(pause)
21 | .removeItem('first added todo', wait)
22 | .pause(pause)
23 | .removeItem('second added todo', wait)
24 | .pause(pause)
25 | .removeItem('Learn about Web Components', wait)
26 | .pause(pause)
27 | .removeItem('my initial todo', wait)
28 | .pause(pause)
29 | .end(),
30 | };
31 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Julien Renaux
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/atomico/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "atom-todo",
3 | "version": "0.0.1",
4 | "description": "This is a small skeleton to create distributable components based on Atomico",
5 | "iife": "public/atom-todo.iife.js",
6 | "source": "src/index.js",
7 | "author": "Matias Trujillo Olivares",
8 | "license": "ISC",
9 | "repository": {
10 | "type": "git",
11 | "url": "https://github.com/UpperCod/atomico-starter-component.git"
12 | },
13 | "scripts": {
14 | "prebuild": "npm prune && npm install",
15 | "watch": "rollup -c -w",
16 | "build": "rollup -c"
17 | },
18 | "dependencies": {
19 | "atomico": "^0.0.9"
20 | },
21 | "globals": {
22 | "atomico": "atomico"
23 | },
24 | "devDependencies": {
25 | "cssnano": "^4.1.0",
26 | "rollup": "^0.65.2",
27 | "rollup-plugin-buble": "^0.19.2",
28 | "rollup-plugin-commonjs": "^9.1.6",
29 | "rollup-plugin-copy": "^0.2.3",
30 | "rollup-plugin-filesize": "^4.0.1",
31 | "rollup-plugin-node-resolve": "^3.4.0",
32 | "rollup-plugin-postcss": "^1.6.2",
33 | "rollup-plugin-terser": "1.0.1",
34 | "rollup-prepare": "^0.0.0"
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/stencil-0.16/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/stencil-0.11/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Ionic
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/svelte/rollup.config.js:
--------------------------------------------------------------------------------
1 | import svelte from 'rollup-plugin-svelte';
2 | import resolve from 'rollup-plugin-node-resolve';
3 | import commonjs from 'rollup-plugin-commonjs';
4 | import { terser } from 'rollup-plugin-terser';
5 |
6 | const production = !process.env.ROLLUP_WATCH;
7 |
8 | export default {
9 | input: 'src/main.js',
10 | output: {
11 | sourcemap: true,
12 | format: 'iife',
13 | file: 'public/bundle.js',
14 | name: 'app'
15 | },
16 | plugins: [
17 | svelte({
18 | // enable run-time checks when not in production
19 | dev: !production,
20 |
21 | customElement: true,
22 |
23 | // this results in smaller CSS files
24 | cascade: false
25 | }),
26 |
27 | // If you have external dependencies installed from
28 | // npm, you'll most likely need these plugins. In
29 | // some cases you'll need additional configuration —
30 | // consult the documentation for details:
31 | // https://github.com/rollup/rollup-plugin-commonjs
32 | resolve(),
33 | commonjs(),
34 |
35 | // If we're building for production (npm run build
36 | // instead of npm run dev), minify bundle
37 | production && terser()
38 | ]
39 | };
--------------------------------------------------------------------------------
/angular-elements/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Angular Elements Todo
7 |
8 |
9 |
10 |
11 |
12 | ⬅ Back to other implementations
13 |
14 |
15 |
16 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/non-web-components-refs/angular/README.md:
--------------------------------------------------------------------------------
1 | # Angular
2 |
3 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 6.2.2.
4 |
5 | ## Development server
6 |
7 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
8 |
9 | ## Code scaffolding
10 |
11 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
12 |
13 | ## Build
14 |
15 | Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build.
16 |
17 | ## Running unit tests
18 |
19 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
20 |
21 | ## Running end-to-end tests
22 |
23 | Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
24 |
25 | ## Further help
26 |
27 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
28 |
--------------------------------------------------------------------------------
/angular-elements/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Vincent Ogloblinsky
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/polymer2/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | todo
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | ⬅ Back to other implementations
22 |
23 |
24 |
47 |
48 |
--------------------------------------------------------------------------------
/polymer3/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | polymer-3
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | ⬅ Back to other implementations
21 |
22 |
23 |
46 |
47 |
--------------------------------------------------------------------------------
/vue/src/components/todo-input.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
20 |
--------------------------------------------------------------------------------
/slim-js/src/todo-app.js:
--------------------------------------------------------------------------------
1 | import { Slim } from 'slim-js'
2 | import { tag, template, useShadow } from 'slim-js/Decorators';
3 | import './directives/bind-boolean.js'
4 | import TodoItem from './components/todo-item';
5 | import todoInput from './components/todo-input.js';
6 |
7 | @tag('todo-app')
8 | @template(/*html*/`
9 |
10 |
11 |
Todos slim-js
12 |
20 |
21 | `)
22 | @useShadow(true)
23 | export default class TodoApp extends Slim {
24 |
25 | constructor () {
26 | super()
27 | this.list = [
28 | { text: 'my initial todo', checked: false },
29 | { text: 'Learn about Web Components', checked: true }
30 | ]
31 | }
32 |
33 | onNewItem (text) {
34 | this.list = [...this.list, {
35 | text,
36 | checked: false
37 | }]
38 | }
39 |
40 | onRemoveItem (item) {
41 | this.list = this.list.filter(existingItem => existingItem !== item)
42 | }
43 |
44 | }
--------------------------------------------------------------------------------
/non-web-components-refs/vue/src/components/todo-input.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
20 |
--------------------------------------------------------------------------------
/vue/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | vue-web-component-wrapper
10 |
11 |
12 |
13 |
14 |
15 | ⬅ Back to other implementations
16 |
17 |
18 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/stencil-0.11/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | **Resources:**
2 | Before submitting an issue, please consult our [docs](https://stenciljs.com/).
3 |
4 | **Stencil version:** (run `npm list @stencil/core` from a terminal/cmd prompt and paste output below):
5 |
6 | ```
7 | insert the output from npm list @stencil/core here
8 | ```
9 |
10 | **I'm submitting a ...** (check one with "x")
11 | [ ] bug report
12 | [ ] feature request
13 | [ ] support request => Please do not submit support requests here, use one of these channels: https://forum.ionicframework.com/ or https://stencil-worldwide.slack.com
14 |
15 | **Current behavior:**
16 |
17 |
18 | **Expected behavior:**
19 |
20 |
21 | **Steps to reproduce:**
22 |
24 |
25 | **Related code:**
26 |
27 | ```
28 | insert any relevant code here
29 | ```
30 |
31 | **Other information:**
32 |
33 |
--------------------------------------------------------------------------------
/polymer3/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "polymer3",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "license": "MIT",
6 | "flat": true,
7 | "scripts": {
8 | "build": "npm run build-polymer && npm run build-es6 && npm run minify-es6",
9 | "build-polymer": "polymer build",
10 | "postbuild-polymer": "rm -rf build/es6-bundled/node_modules && rm -rf build/es6-bundled/src/*",
11 | "build-es6": "rollup -c rollup.config.js",
12 | "minify-es6": "mkdir -p build/es6-bundled/src/ && uglifyjs build/es6-bundled/src_tmp/index.js -o build/es6-bundled/src/index.js -c -m",
13 | "postminify-es6": "rm -rf build/es6-bundled/src_tmp"
14 | },
15 | "dependencies": {
16 | "@polymer/iron-form": "^3.0.0-pre.8",
17 | "@polymer/iron-input": "^3.0.0-pre.8",
18 | "@polymer/polymer": "^3.0.0-pre.9",
19 | "@webcomponents/webcomponentsjs": "^1.1.0"
20 | },
21 | "resolutions": {
22 | "@webcomponents/webcomponentsjs": "1.1.0",
23 | "@polymer/polymer": "3.0.0-pre.9"
24 | },
25 | "devDependencies": {
26 | "rollup": "^0.56.2",
27 | "rollup-plugin-node-resolve": "^3.0.3",
28 | "uglify-es": "^3.3.9"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | .rpt2_cache
8 |
9 | # Runtime data
10 | pids
11 | *.pid
12 | *.seed
13 | *.pid.lock
14 |
15 | # Directory for instrumented libs generated by jscoverage/JSCover
16 | lib-cov
17 |
18 | # Coverage directory used by tools like istanbul
19 | coverage
20 |
21 | # nyc test coverage
22 | .nyc_output
23 |
24 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
25 | .grunt
26 |
27 | # Bower dependency directory (https://bower.io/)
28 | bower_components
29 |
30 | # node-waf configuration
31 | .lock-wscript
32 |
33 | # Compiled binary addons (http://nodejs.org/api/addons.html)
34 | build/Release
35 |
36 | # Dependency directories
37 | node_modules/
38 | jspm_packages/
39 |
40 | # Typescript v1 declaration files
41 | typings/
42 |
43 | # Optional npm cache directory
44 | .npm
45 |
46 | # Optional eslint cache
47 | .eslintcache
48 |
49 | # Optional REPL history
50 | .node_repl_history
51 |
52 | # Output of 'npm pack'
53 | *.tgz
54 |
55 | # Yarn Integrity file
56 | .yarn-integrity
57 |
58 | # dotenv environment variables file
59 | .env
60 |
61 | .e2e-results
62 |
63 | # functional-element dist
64 | /functional-element/dist
--------------------------------------------------------------------------------
/native/js/todo-input.js:
--------------------------------------------------------------------------------
1 | const templateTodoInput = document.createElement('template');
2 | templateTodoInput.innerHTML = `
3 |
6 | `;
7 |
8 | class TodoInput extends HTMLElement {
9 | constructor() {
10 | super();
11 | // Do not use shadow DOM to avoid problems when testing with selenium
12 | // this._root = this.attachShadow({ 'mode': 'open' });
13 | }
14 |
15 | connectedCallback() {
16 | console.log('TodoInput ADDED TO THE DOM');
17 | this.appendChild(templateTodoInput.content.cloneNode(true));
18 | this.$form = this.querySelector('form');
19 | this.$input = this.querySelector('input');
20 | this.$form.addEventListener("submit", (e) => {
21 | e.preventDefault();
22 | if (!this.$input.value) return;
23 | this.dispatchEvent(new CustomEvent('onSubmit', { detail: this.$input.value }));
24 | this.$input.value = '';
25 | });
26 | }
27 |
28 | disconnectedCallback() {
29 | console.log('TodoInput REMOVED TO THE DOM');
30 | }
31 | }
32 |
33 | window.customElements.define('todo-input', TodoInput);
34 |
--------------------------------------------------------------------------------
/polymer3/src/todo-input-styles.js:
--------------------------------------------------------------------------------
1 | import {
2 | Element as PolymerElement
3 | }
4 | from '../node_modules/@polymer/polymer/polymer-element.js';
5 |
6 | const todoInputStyleElement = document.createElement('dom-module');
7 | todoInputStyleElement.innerHTML =
8 | `
9 |
44 | `
45 | todoInputStyleElement.register('todo-input-style-element');
--------------------------------------------------------------------------------
/solid/src/MyTodo.jsx:
--------------------------------------------------------------------------------
1 | import { Component } from 'solid-components';
2 | import { useState } from 'solid-js';
3 | import { r } from 'solid-js/dom';
4 |
5 | import style from './MyTodo.css';
6 | import './TodoInput';
7 | import './TodoItem';
8 |
9 | let uid = 1;
10 | const MyTodo = () => {
11 | const [state, setState] = useState({ list: [
12 | { id: uid++, text: "my initial todo", checked: false },
13 | { id: uid++, text: "Learn about Web Components", checked: true }
14 | ] });
15 | return <>
16 |
17 | Solid Todo
18 |
19 |
20 | setState('list', l => [...l, { id: uid++, text, checked: false }])
21 | }/>
22 | setState('list', state.list.findIndex(t => t.id === id), { checked })}
24 | onRemove={(e, id) => setState('list', l => l.filter(t => t.id !== id))}
25 | >
26 | <$ each={ state.list }>{ item =>
27 |
32 | }$>
33 |
34 |
35 | >
36 | }
37 |
38 | Component('my-todo', MyTodo);
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # web-components-todo
2 |
3 | Comparison on how to update DOM, pass attributes/properties and dispatch/listen to events with Web Components
4 |
5 | 
6 |
7 | ## Demos
8 |
9 | * [Native Web Component](https://wc-todo.firebaseapp.com/native)
10 | * [Lit-Element](https://wc-todo.firebaseapp.com/lit-element-2.1/)
11 | * [Stencil](https://wc-todo.firebaseapp.com/stencil-0.16/)
12 | * [Slim.js](https://wc-todo.firebaseapp.com/slimjs)
13 | * [SkateJS + Lit-Html](https://wc-todo.firebaseapp.com/skatejs-lit-html)
14 | * [SkateJS + Preact](https://wc-todo.firebaseapp.com/skatejs-preact)
15 | * [Svelte](https://wc-todo.firebaseapp.com/svelte/)
16 | * [Solid](https://wc-todo.firebaseapp.com/solid/)
17 | * [Functional-element](https://wc-todo.firebaseapp.com/functional-element/)
18 | * [Angular Elements](https://wc-todo.firebaseapp.com/angular-elements)
19 | * [Vue Web Component Wrapper](https://wc-todo.firebaseapp.com/vue)
20 | * [Polymer 2](https://wc-todo.firebaseapp.com/polymer2)
21 | * [Polymer 3](https://wc-todo.firebaseapp.com/polymer3)
22 |
23 | ## syntax differences
24 |
25 | 
26 |
--------------------------------------------------------------------------------
/stencil-0.11/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@stencil/starter",
3 | "private": true,
4 | "version": "0.0.1",
5 | "description": "Stencil App Starter",
6 | "scripts": {
7 | "build": "DEMO_BASE_URL=/stencil-0.11 stencil build",
8 | "build:prerendered": "DEMO_BASE_URL=/stencil-prerendered stencil build --prerender",
9 | "start": "stencil build --dev --watch --serve",
10 | "test": "jest",
11 | "test.watch": "jest --watch"
12 | },
13 | "dependencies": {
14 | "@stencil/core": "^0.11.0",
15 | "@stencil/router": "^0.2.5"
16 | },
17 | "devDependencies": {
18 | "@types/jest": "^23.3.1",
19 | "jest": "^23.4.2"
20 | },
21 | "repository": {
22 | "type": "git",
23 | "url": "git+https://github.com/ionic-team/stencil-app-starter.git"
24 | },
25 | "author": "Ionic Team",
26 | "license": "MIT",
27 | "bugs": {
28 | "url": "https://github.com/ionic-team/stencil"
29 | },
30 | "homepage": "https://github.com/ionic-team/stencil",
31 | "jest": {
32 | "transform": {
33 | "^.+\\.(ts|tsx)$": "/node_modules/@stencil/core/testing/jest.preprocessor.js"
34 | },
35 | "testRegex": "(/__tests__/.*|\\.(test|spec))\\.(tsx?|jsx?)$",
36 | "moduleFileExtensions": [
37 | "ts",
38 | "tsx",
39 | "js",
40 | "json",
41 | "jsx"
42 | ]
43 | }
44 | }
--------------------------------------------------------------------------------
/polymer3/src/todo-item.js:
--------------------------------------------------------------------------------
1 | import {
2 | Element as PolymerElement
3 | }
4 | from '../node_modules/@polymer/polymer/polymer-element.js';
5 |
6 | import './todo-item-styles.js';
7 |
8 | export class TodoItem extends PolymerElement {
9 | static get is() {
10 | return 'todo-item';
11 | }
12 | static get template() {
13 | return `
14 |
15 |
16 |
17 |
18 |
19 |
20 | `
21 | }
22 | static get properties() {
23 | return {
24 | checked: { type: Boolean },
25 | index: { type: Number },
26 | text: { type: String }
27 | }
28 | }
29 | handleOnRemove(e) {
30 | this.dispatchEvent(new CustomEvent('remove', { detail: this.index }));
31 | }
32 | handleOnToggle(e){
33 | this.dispatchEvent(new CustomEvent('toggle', { detail: this.index }));
34 | }
35 | isCompleted(completed) {
36 | return completed ? 'completed' : '';
37 | }
38 | }
39 |
40 | customElements.define(TodoItem.is, TodoItem);
41 |
--------------------------------------------------------------------------------
/svelte/src/components/TodoInput.html:
--------------------------------------------------------------------------------
1 |
4 |
5 |
36 |
37 |
--------------------------------------------------------------------------------
/non-web-components-refs/angular/src/app/todo-input/todo-input.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit, Input, Output, EventEmitter, ChangeDetectionStrategy } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-todo-input',
5 | styles: [`
6 | form {
7 | position: relative;
8 | font-size: 24px;
9 | border-bottom: 1px solid #ededed;
10 | }
11 |
12 | input[type=text] {
13 | padding: 16px 16px 16px 60px;
14 | border: none;
15 | background: rgba(0, 0, 0, 0.003);
16 | position: relative;
17 | margin: 0;
18 | width: 100%;
19 | font-size: 24px;
20 | font-family: inherit;
21 | font-weight: inherit;
22 | line-height: 1.4em;
23 | border: 0;
24 | outline: none;
25 | color: inherit;
26 | padding: 6px;
27 | border: 1px solid #CCC;
28 | box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
29 | box-sizing: border-box;
30 | }
31 | `],
32 | template: `
33 |
36 | `,
37 | changeDetection: ChangeDetectionStrategy.OnPush,
38 | })
39 | export class TodoInputComponent {
40 | text: string;
41 | @Output() newTodo: EventEmitter = new EventEmitter();
42 |
43 | onSubmit(e) {
44 | this.newTodo.emit(this.text);
45 | this.text = '';
46 | }
47 |
48 | }
49 |
50 |
--------------------------------------------------------------------------------
/polymer3/src/todo-input.js:
--------------------------------------------------------------------------------
1 | import {
2 | Element as PolymerElement
3 | }
4 | from '../node_modules/@polymer/polymer/polymer-element.js';
5 |
6 | import '../node_modules/@polymer/iron-form/iron-form.js';
7 | import '../node_modules/@polymer/iron-input/iron-input.js';
8 |
9 | import './todo-input-styles.js';
10 |
11 | export class TodoInput extends PolymerElement {
12 |
13 | static get is() {
14 | return 'todo-input';
15 | }
16 |
17 | static get template() {
18 | return `
19 |
20 |
21 |
26 |
27 | `
28 | }
29 |
30 | static get properties() {
31 | return {
32 | text: {
33 | type: String,
34 | value: ''
35 | }
36 | }
37 | }
38 |
39 | ready() {
40 | super.ready();
41 | this.$form = this.shadowRoot.querySelector('iron-form');
42 | this.$form.addEventListener('iron-form-submit', (e) => {
43 | if (!this.text) return;
44 | this.dispatchEvent(new CustomEvent('onSubmit', { detail: this.text }));
45 | this.text = '';
46 | });
47 | }
48 | }
49 |
50 | customElements.define(TodoInput.is, TodoInput);
--------------------------------------------------------------------------------
/nightwatch.json:
--------------------------------------------------------------------------------
1 | {
2 | "src_folders": [
3 | "tests/suite"
4 | ],
5 | "output_folder": ".e2e-results",
6 | "custom_commands_path": "./tests/commands",
7 | "custom_assertions_path": "",
8 | "page_objects_path": "",
9 | "globals_path": "",
10 | "live_output": true,
11 | "selenium": {
12 | "start_process": true,
13 | "server_path": "./node_modules/selenium-server-standalone-jar/jar/selenium-server-standalone-3.8.1.jar",
14 | "log_path": "",
15 | "port": 4444,
16 | "cli_args": {
17 | "webdriver.chrome.driver": "",
18 | "webdriver.gecko.driver": "",
19 | "webdriver.edge.driver": ""
20 | }
21 | },
22 | "test_settings": {
23 | "default": {
24 | "selenium_port": 4444,
25 | "selenium_host": "localhost",
26 | "silent": true,
27 | "screenshots": {
28 | "enabled": false,
29 | "path": ""
30 | },
31 | "desiredCapabilities": {
32 | "browserName": "chrome",
33 | "javascriptEnabled": true,
34 | "acceptSslCerts": true,
35 | "marionette": true,
36 | "chromeOptions": {
37 | "args": [
38 | "disable-web-security",
39 | "ignore-certificate-errors",
40 | "no-sandbox"
41 | ]
42 | }
43 | }
44 | }
45 | }
46 | }
--------------------------------------------------------------------------------
/lit-element-0.6/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Native Web Component Todo
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
40 |
41 |
42 |
43 |
44 | ⬅ Back to other implementations
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/lit-element-2.1/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Native Web Component Todo
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
40 |
41 |
42 |
43 |
44 | ⬅ Back to other implementations
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/non-web-components-refs/angular/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Angular Todo list
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
40 |
41 |
42 |
43 |
44 | ⬅ Back to other implementations
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/non-web-components-refs/angular/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular",
3 | "version": "0.0.0",
4 | "scripts": {
5 | "ng": "ng",
6 | "start": "ng serve",
7 | "build": "ng build --prod --configuration=production",
8 | "test": "ng test",
9 | "lint": "ng lint",
10 | "e2e": "ng e2e"
11 | },
12 | "private": true,
13 | "dependencies": {
14 | "@angular/animations": "^6.1.0",
15 | "@angular/common": "^6.1.0",
16 | "@angular/compiler": "^6.1.0",
17 | "@angular/core": "^6.1.0",
18 | "@angular/forms": "^6.1.0",
19 | "@angular/http": "^6.1.0",
20 | "@angular/platform-browser": "^6.1.0",
21 | "@angular/platform-browser-dynamic": "^6.1.0",
22 | "@angular/router": "^6.1.0",
23 | "core-js": "^2.5.4",
24 | "rxjs": "~6.2.0",
25 | "zone.js": "~0.8.26"
26 | },
27 | "devDependencies": {
28 | "@angular-devkit/build-angular": "~0.8.0",
29 | "@angular/cli": "~6.2.2",
30 | "@angular/compiler-cli": "^6.1.0",
31 | "@angular/language-service": "^6.1.0",
32 | "@types/jasmine": "~2.8.8",
33 | "@types/jasminewd2": "~2.0.3",
34 | "@types/node": "~8.9.4",
35 | "codelyzer": "~4.3.0",
36 | "jasmine-core": "~2.99.1",
37 | "jasmine-spec-reporter": "~4.2.1",
38 | "karma": "~3.0.0",
39 | "karma-chrome-launcher": "~2.2.0",
40 | "karma-coverage-istanbul-reporter": "~2.0.1",
41 | "karma-jasmine": "~1.1.2",
42 | "karma-jasmine-html-reporter": "^0.2.2",
43 | "protractor": "~5.4.0",
44 | "ts-node": "~7.0.0",
45 | "tslint": "~5.11.0",
46 | "typescript": "~2.9.2"
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/svelte/README.md:
--------------------------------------------------------------------------------
1 | # svelte app
2 |
3 | This is a project template for [Svelte](https://svelte.technology) apps. It lives at https://github.com/sveltejs/template-custom-element.
4 |
5 | To create a new project based on this template using [degit](https://github.com/Rich-Harris/degit):
6 |
7 | ```bash
8 | npm install -g degit # you only need to do this once
9 |
10 | degit sveltejs/template-custom-element svelte-app
11 | cd svelte-app
12 | ```
13 |
14 | *Note that you will need to have [Node.js](https://nodejs.org) installed.*
15 |
16 |
17 | ## Get started
18 |
19 | Install the dependencies...
20 |
21 | ```bash
22 | cd svelte-app
23 | npm install
24 | ```
25 |
26 | ...then start [Rollup](https://rollupjs.org):
27 |
28 | ```bash
29 | npm run dev
30 | ```
31 |
32 | Navigate to [localhost:5000](http://localhost:5000). You should see your app running. Edit a component file in `src`, save it, and reload the page to see your changes.
33 |
34 |
35 | ## Deploying to the web
36 |
37 | ### With [now](https://zeit.co/now)
38 |
39 | Install `now` if you haven't already:
40 |
41 | ```bash
42 | npm install -g now
43 | ```
44 |
45 | Then, from within your project folder:
46 |
47 | ```bash
48 | now
49 | ```
50 |
51 | As an alternative, use the [Now desktop client](https://zeit.co/download) and simply drag the unzipped project folder to the taskbar icon.
52 |
53 | ### With [surge](https://surge.sh/)
54 |
55 | Install `surge` if you haven't already:
56 |
57 | ```bash
58 | npm install -g surge
59 | ```
60 |
61 | Then, from within your project folder:
62 |
63 | ```bash
64 | npm run build
65 | surge public
66 | ```
67 |
--------------------------------------------------------------------------------
/functional-element/src/todo-input.js:
--------------------------------------------------------------------------------
1 | import { customElement, html } from 'functional-element';
2 |
3 | customElement('todo-input', ({ element }) => {
4 | return html`
5 |
32 |
33 |
36 | `;
37 | });
38 |
39 | function onSubmit(e, element) {
40 | const $input = element.querySelector('input');
41 | e.stopPropagation();
42 | e.preventDefault();
43 | if (!$input.value) return;
44 | element.dispatchEvent(new CustomEvent('submit', { detail: $input.value }));
45 | $input.value = '';
46 | }
--------------------------------------------------------------------------------
/stencil-0.16/readme.md:
--------------------------------------------------------------------------------
1 | # Stencil App Starter
2 |
3 | Stencil is a compiler for building fast web apps using Web Components.
4 |
5 | Stencil 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.
6 |
7 | Stencil components are just Web Components, so they work in any major framework or with no framework at all. In many cases, Stencil can be used as a drop in replacement for traditional frontend frameworks given the capabilities now available in the browser, though using it as such is certainly not required.
8 |
9 | Stencil also enables a number of key capabilities on top of Web Components, in particular Server Side Rendering (SSR) without the need to run a headless browser, pre-rendering, and objects-as-properties (instead of just strings).
10 |
11 | ## Getting Started
12 |
13 | To start a new project using Stencil, clone this repo to a new directory:
14 |
15 | ```bash
16 | npm init stencil app
17 | ```
18 |
19 | and run:
20 |
21 | ```bash
22 | npm start
23 | ```
24 |
25 | To build the app for production, run:
26 |
27 | ```bash
28 | npm run build
29 | ```
30 |
31 | To run the unit tests once, run:
32 |
33 | ```
34 | npm test
35 | ```
36 |
37 | To run the unit tests and watch for file changes during development, run:
38 |
39 | ```
40 | npm run test.watch
41 | ```
42 |
--------------------------------------------------------------------------------
/stencil-0.11/src/components/my-todo/my-todo.tsx:
--------------------------------------------------------------------------------
1 | import { Component, State, Listen } from '@stencil/core';
2 |
3 | interface TodoItem {
4 | text: string;
5 | checked: boolean;
6 | }
7 |
8 | @Component({
9 | tag: 'my-todo',
10 | styleUrl: 'my-todo.css',
11 | // shadow: true,
12 | })
13 | export class MyTodo {
14 | @State() list: TodoItem[] = [
15 | { text: 'my initial todo', checked: false },
16 | { text: 'Learn about Web Components', checked: true }
17 | ];
18 |
19 | @Listen('onTodoInputSubmit')
20 | todoInputSubmiHandler(e: CustomEvent) {
21 | this.list = [...this.list, { text: e.detail, checked: false, }];
22 | }
23 |
24 | @Listen('onTodoItemChecked')
25 | todoItemCheckedHandler(e: CustomEvent) {
26 | const list = [...this.list];
27 | const item = list[e.detail];
28 | list[e.detail] = Object.assign({}, item, { checked: !item.checked });
29 | this.list = list;
30 | }
31 |
32 | @Listen('onTodoItemRemove')
33 | todoItemRemoveHandler(e: CustomEvent) {
34 | this.list = [...this.list.slice(0, e.detail), ...this.list.slice(e.detail + 1)];
35 | }
36 |
37 | render() {
38 | return (
39 |
40 |
Todos Stencil
41 |
42 |
43 |
44 | {this.list.map((item, index) => (
45 |
50 | ))}
51 |
52 |
53 |
54 | );
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/stencil-0.16/src/components/my-todo/my-todo.tsx:
--------------------------------------------------------------------------------
1 | import { Component, State, Listen } from '@stencil/core';
2 |
3 | interface TodoItem {
4 | text: string;
5 | checked: boolean;
6 | }
7 |
8 | @Component({
9 | tag: 'my-todo',
10 | styleUrl: 'my-todo.css',
11 | // shadow: true,
12 | })
13 | export class MyTodo {
14 | @State() list: TodoItem[] = [
15 | { text: 'my initial todo', checked: false },
16 | { text: 'Learn about Web Components', checked: true }
17 | ];
18 |
19 | @Listen('onTodoInputSubmit')
20 | todoInputSubmiHandler(e: CustomEvent) {
21 | this.list = [...this.list, { text: e.detail, checked: false, }];
22 | }
23 |
24 | @Listen('onTodoItemChecked')
25 | todoItemCheckedHandler(e: CustomEvent) {
26 | const list = [...this.list];
27 | const item = list[e.detail];
28 | list[e.detail] = Object.assign({}, item, { checked: !item.checked });
29 | this.list = list;
30 | }
31 |
32 | @Listen('onTodoItemRemove')
33 | todoItemRemoveHandler(e: CustomEvent) {
34 | this.list = [...this.list.slice(0, e.detail), ...this.list.slice(e.detail + 1)];
35 | }
36 |
37 | render() {
38 | return (
39 |
40 |
Todos Stencil
41 |
42 |
43 |
44 | {this.list.map((item, index) => (
45 |
50 | ))}
51 |
52 |
53 |
54 | );
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/polymer3/src/my-todo.js:
--------------------------------------------------------------------------------
1 | import {
2 | Element as PolymerElement
3 | }
4 | from '../node_modules/@polymer/polymer/polymer-element.js';
5 |
6 | import './my-todo-styles.js';
7 |
8 | export class MyTodo extends PolymerElement {
9 |
10 | static get is() { return 'my-todo'; }
11 |
12 | static get template() {
13 | return `
14 |
15 | Todos Polymer 3
16 |
24 | `
25 | }
26 |
27 | static get properties() {
28 | return {
29 | list: {
30 | type: Array,
31 | value: () => [
32 | { text: 'my initial todo', checked: false },
33 | { text: 'Learn about Web Components', checked: true }
34 | ]
35 | }
36 | }
37 | }
38 |
39 | ready() {
40 | super.ready();
41 | this.$input = this.shadowRoot.querySelector('todo-input');
42 | this.$input.addEventListener('onSubmit', this.addItem.bind(this));
43 | }
44 |
45 | addItem(e) {
46 | this.push('list', { text: e.detail, checked: false });
47 | }
48 |
49 | removeItem(e) {
50 | this.splice('list', e.detail, 1);
51 | }
52 |
53 | toggleItem(e) {
54 | this.set('list.'+e.detail, { ...this.list[e.detail], checked: !this.list[e.detail].checked });
55 | }
56 | }
57 |
58 | customElements.define(MyTodo.is, MyTodo);
59 |
--------------------------------------------------------------------------------
/functional-element/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Functional Element
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
40 |
41 |
42 |
43 | ⬅ Back to other implementations
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/functional-element/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Functional Element
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
40 |
41 |
42 |
43 | ⬅ Back to other implementations
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/stencil-0.11/readme.md:
--------------------------------------------------------------------------------
1 | # Stencil App Starter
2 |
3 | Stencil is a compiler for building fast web apps using Web Components.
4 |
5 | Stencil 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.
6 |
7 | Stencil components are just Web Components, so they work in any major framework or with no framework at all. In many cases, Stencil can be used as a drop in replacement for traditional frontend frameworks given the capabilities now available in the browser, though using it as such is certainly not required.
8 |
9 | Stencil also enables a number of key capabilities on top of Web Components, in particular Server Side Rendering (SSR) without the need to run a headless browser, pre-rendering, and objects-as-properties (instead of just strings).
10 |
11 | ## Getting Started
12 |
13 | To start a new project using Stencil, clone this repo to a new directory:
14 |
15 | ```bash
16 | git clone https://github.com/ionic-team/stencil-starter.git my-app
17 | cd my-app
18 | git remote rm origin
19 | ```
20 |
21 | and run:
22 |
23 | ```bash
24 | npm install
25 | npm start
26 | ```
27 |
28 | To build the app for production, run:
29 |
30 | ```bash
31 | npm run build
32 | ```
33 |
34 | To run the unit tests once, run:
35 |
36 | ```
37 | npm test
38 | ```
39 |
40 | To run the unit tests and watch for file changes during development, run:
41 |
42 | ```
43 | npm run test.watch
44 | ```
45 |
--------------------------------------------------------------------------------
/lit-element-2.1/src/todo-input.js:
--------------------------------------------------------------------------------
1 | import { LitElement, html } from 'lit-element';
2 |
3 | export default class TodoInput extends LitElement {
4 | constructor() {
5 | super();
6 | this.onSubmit = this.onSubmit.bind(this);
7 | }
8 |
9 | onSubmit(e) {
10 | const $input = this.shadowRoot.querySelector('input');
11 | e.preventDefault();
12 | if (!$input.value) return;
13 | this.dispatchEvent(new CustomEvent('submit', { detail: $input.value }));
14 | $input.value = '';
15 | }
16 |
17 | render(props) {
18 | return html`
19 |
46 |
49 | `;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/lit-element-0.6/src/todo-input.js:
--------------------------------------------------------------------------------
1 | import { LitElement, html } from '@polymer/lit-element';
2 |
3 | export default class TodoInput extends LitElement {
4 | constructor() {
5 | super();
6 | this.onSubmit = this.onSubmit.bind(this);
7 | }
8 |
9 | onSubmit(e) {
10 | const $input = this.shadowRoot.querySelector('input');
11 | e.preventDefault();
12 | if (!$input.value) return;
13 | this.dispatchEvent(new CustomEvent('submit', { detail: $input.value }));
14 | $input.value = '';
15 | }
16 |
17 | render(props) {
18 | return html`
19 |
46 |
49 | `;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/vue/src/components/my-todo.vue:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 |
40 |
41 |
66 |
--------------------------------------------------------------------------------
/svelte/src/components/MyTodo.html:
--------------------------------------------------------------------------------
1 | Todos Svelte
2 |
3 |
4 |
5 | {#each list as item, index (item.id)}
6 |
11 | {/each}
12 |
13 |
14 |
15 |
41 |
42 |
--------------------------------------------------------------------------------
/skatejs-lit-html/src/input.js:
--------------------------------------------------------------------------------
1 | import { props } from "skatejs/dist/esnext";
2 | import { html } from "lit-html/lib/lit-extended";
3 | import { Component } from "./util";
4 |
5 | export default class extends Component {
6 | static events = ["submit"];
7 | state = {
8 | value: ""
9 | };
10 |
11 | handleInput = e => {
12 | this.state = { value: e.target.value };
13 | };
14 | handleSubmit = e => {
15 | e.preventDefault();
16 | if (!this.state.value) return;
17 | this.onSubmit({ value: this.state.value });
18 | this.state = { value: "" };
19 | };
20 |
21 | render({ handleInput, handleSubmit }) {
22 | return html`
23 |
54 |
62 | `;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/non-web-components-refs/react/src/components/my-todo/my-todo.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 |
3 | import './my-todo.css';
4 | import TodoInput from '../todo-input/todo-input';
5 | import TodoItem from '../todo-item/todo-item';
6 |
7 | class MyTodo extends Component {
8 | state = {
9 | list: [
10 | { text: 'my initial todo', checked: false },
11 | { text: 'Learn about Web Components', checked: true }
12 | ],
13 | }
14 |
15 | handleOnTodoInputSubmit = (text) => {
16 | this.setState({ list: [...this.state.list, { text, checked: false, }] });
17 | }
18 |
19 | handleOnTodoItemChecked = (index) => {
20 | const { list } = this.state;
21 | const newList = [...list];
22 | const item = newList[index];
23 | newList[index] = Object.assign({}, item, { checked: !item.checked });
24 | this.setState({ list: newList });
25 | }
26 |
27 | handleOnTodoItemRemove = (index) => {
28 | const { list } = this.state;
29 | this.setState({ list: [...list.slice(0, index), ...list.slice(index + 1)] });
30 | }
31 |
32 | render() {
33 | return (
34 |
35 |
Todos React
36 |
37 |
38 |
39 | {this.state.list.map((item, index) => (
40 |
48 | ))}
49 |
50 |
51 |
52 | );
53 | }
54 | }
55 |
56 | export default MyTodo;
57 |
--------------------------------------------------------------------------------
/skatejs-preact/src/util.js:
--------------------------------------------------------------------------------
1 | import { emit, withComponent } from "skatejs/dist/esnext";
2 | import withRenderer from "@skatejs/renderer-preact/dist/esnext";
3 |
4 | // Mixin for auto-defining functions that emit events.
5 | const withEvents = (Base = HTMLElement) =>
6 | class extends Base {
7 | // Since observedAttributes are called only once, we can use that as a hook
8 | // to do any one-time setup we need upon definition.
9 | static get observedAttributes() {
10 | (this.events || []).forEach(e => {
11 | const name = `on${e[0].toUpperCase() + e.substring(1)}`;
12 |
13 | // Allows the following for the consumer:
14 | //
15 | // - elem.onEvent = fn
16 | // - elem.addEventListener('event', fn)
17 | //
18 | // Allows the following for the author:
19 | //
20 | // - this.onEvent(detail)
21 | Object.defineProperty(this.prototype, name, {
22 | get() {
23 | if (!this.__events[e]) {
24 | this[name] = () => {};
25 | }
26 | return this.__events[e];
27 | },
28 | set(fn) {
29 | this.__events[e] = detail => {
30 | fn(detail);
31 | emit(this, e, { detail });
32 | };
33 | if (this.triggerUpdate) {
34 | this.triggerUpdate();
35 | }
36 | }
37 | });
38 | });
39 | return super.observedAttributes;
40 | }
41 | __events = {};
42 | };
43 |
44 | // We must mixin in this order because withComponent() doesn't yet call super
45 | // on observedAttributes. This means that observedAttributes from the
46 | // withEvents() mixin wouldn't get called. This will be fixed in the next
47 | // version of Skate.
48 | export const Component = withEvents(withComponent(withRenderer()));
49 |
--------------------------------------------------------------------------------
/skatejs-lit-html/src/util.js:
--------------------------------------------------------------------------------
1 | import { emit, withComponent } from "skatejs/dist/esnext";
2 | import withRenderer from "@skatejs/renderer-lit-html/dist/esnext";
3 |
4 | // Mixin for auto-defining functions that emit events.
5 | const withEvents = (Base = HTMLElement) =>
6 | class extends Base {
7 | // Since observedAttributes are called only once, we can use that as a hook
8 | // to do any one-time setup we need upon definition.
9 | static get observedAttributes() {
10 | (this.events || []).forEach(e => {
11 | const name = `on${e[0].toUpperCase() + e.substring(1)}`;
12 |
13 | // Allows the following for the consumer:
14 | //
15 | // - elem.onEvent = fn
16 | // - elem.addEventListener('event', fn)
17 | //
18 | // Allows the following for the author:
19 | //
20 | // - this.onEvent(detail)
21 | Object.defineProperty(this.prototype, name, {
22 | get() {
23 | if (!this.__events[e]) {
24 | this[name] = () => {};
25 | }
26 | return this.__events[e];
27 | },
28 | set(fn) {
29 | this.__events[e] = detail => {
30 | fn(detail);
31 | emit(this, e, { detail });
32 | };
33 | if (this.triggerUpdate) {
34 | this.triggerUpdate();
35 | }
36 | }
37 | });
38 | });
39 | return super.observedAttributes;
40 | }
41 | __events = {};
42 | };
43 |
44 | // We must mixin in this order because withComponent() doesn't yet call super
45 | // on observedAttributes. This means that observedAttributes from the
46 | // withEvents() mixin wouldn't get called. This will be fixed in the next
47 | // version of Skate.
48 | export const Component = withEvents(withComponent(withRenderer()));
49 |
--------------------------------------------------------------------------------
/non-web-components-refs/react/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
11 |
12 |
13 |
22 | React App
23 |
24 |
25 |
28 | ⬅ Back to other implementations
29 |
30 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/non-web-components-refs/vue/src/components/my-todo.vue:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 |
45 |
46 |
72 |
--------------------------------------------------------------------------------
/polymer2/test/my-todo/my-todo_test.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | my-todo test
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/non-web-components-refs/angular/src/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, ChangeDetectionStrategy } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-root',
5 | changeDetection: ChangeDetectionStrategy.OnPush,
6 | template: `
7 | Todos Angular
8 |
19 | `,
20 | styles: [`
21 | h1 {
22 | font-size: 70px;
23 | line-height: 70px;
24 | font-weight: 100;
25 | text-align: center;
26 | color: rgba(175, 47, 47, 0.15);
27 | }
28 |
29 | section {
30 | background: #fff;
31 | margin: 30px 0 40px 0;
32 | position: relative;
33 | box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
34 | }
35 |
36 | #list-container {
37 | margin: 0;
38 | padding: 0;
39 | list-style: none;
40 | border-top: 1px solid #e6e6e6;
41 | }
42 | ` ]
43 | })
44 | export class AppComponent {
45 | list = [
46 | { text: 'my initial todo', checked: false },
47 | { text: 'Learn about Web Components', checked: true },
48 | ]
49 |
50 | addItem(text) {
51 | this.list = [...this.list, { text, checked: false, }];
52 | }
53 |
54 | removeItem(index) {
55 | this.list = [...this.list.slice(0, index), ...this.list.slice(index + 1)];
56 | }
57 |
58 | toggleItem(index) {
59 | const list = [...this.list];
60 | const item = list[index];
61 | list[index] = Object.assign({}, item, { checked: !item.checked });
62 | this.list = list;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/atomico/rollup.config.js:
--------------------------------------------------------------------------------
1 | import buble from "rollup-plugin-buble";
2 | import resolve from "rollup-plugin-node-resolve";
3 | import { terser } from "rollup-plugin-terser";
4 | import commonjs from "rollup-plugin-commonjs";
5 | import filesize from "rollup-plugin-filesize";
6 | import pkg from "./package.json";
7 | import colors from "colors";
8 | import prepare from "rollup-prepare";
9 | import postcss from "rollup-plugin-postcss";
10 | import copy from 'rollup-plugin-copy';
11 | import cssnano from "cssnano";
12 |
13 | export default {
14 | ...prepare({
15 | pkg
16 | }),
17 | plugins: plugins(false)
18 | };
19 |
20 | /**
21 | * Returns the generic plugins to be used for packaging
22 | * @param {boolean} classes - lets you disable the transformation of classes
23 | * @return {Array}
24 | */
25 | function plugins(classes = true) {
26 | return [
27 | commonjs({
28 | include: "node_modules/**"
29 | }),
30 | resolve(),
31 | postcss({
32 | plugins: [cssnano]
33 | }),
34 | buble({
35 | jsx: "h",
36 | transforms: {
37 | classes
38 | },
39 | objectAssign: "Object.assign"
40 | }),
41 | terser(),
42 | copy({
43 | "node_modules/atomico/dist/atomico.umd.js": "public/atomico.umd.js",
44 | verbose: true
45 | }),
46 | filesize({
47 | /**
48 | * allows to generate the printing of the output size of each file
49 | */
50 | render(options, size, gzip, brotliSize, minifiedSize, bundle) {
51 | let title = colors.cyan.bold,
52 | value = colors.yellow;
53 | return `${title(bundle.file)} Min: ${value(
54 | size
55 | )} Gzip: ${value(gzip)}`;
56 | }
57 | })
58 | ];
59 | }
60 |
--------------------------------------------------------------------------------
/skatejs-preact/src/input.js:
--------------------------------------------------------------------------------
1 | // @jsx h
2 |
3 | import { props } from "skatejs/dist/esnext";
4 | import { h } from "preact";
5 | import { Component } from "./util";
6 |
7 | export default class extends Component {
8 | static events = ["submit"];
9 | state = {
10 | value: ""
11 | };
12 |
13 | handleInput = e => {
14 | this.state = { value: e.target.value };
15 | };
16 | handleSubmit = e => {
17 | e.preventDefault();
18 | if (!this.state.value) return;
19 | this.onSubmit({ value: this.state.value });
20 | this.state = { value: "" };
21 | };
22 |
23 | render({ handleInput, handleSubmit }) {
24 | return (
25 |
26 |
57 |
65 |
66 | );
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/benchmark/filesize.js:
--------------------------------------------------------------------------------
1 | const fs = require("fs");
2 | const zlib = require('zlib');
3 | const chart = require('ascii-horizontal-barchart')
4 |
5 | const filesize = () => projects.reduce((previous, project) => {
6 | previous[project.name] = project.paths.reduce((previous, current) => {
7 | const exists = fs.existsSync(`dist/${current}`);
8 | if (!exists) return undefined;
9 | return previous + fs.statSync(`/dist/${current}`).size
10 | }, 0);
11 | return previous;
12 | }, {})
13 |
14 |
15 | // console.log(stats)
16 | // console.log(chart(filesize(), true, 30))
17 |
18 |
19 | // Gzipped
20 | // const filesizeGzipped = (list) => list.reduce((previous, project) => {
21 | // previous[project.name] = project.paths.reduce((previous, current) => {
22 | // const exists = fs.existsSync(`dist/${current}`);
23 | // if (!exists) return undefined;
24 | // const fileContents = fs.readFileSync(`dist/${current}`)
25 | // const zippedContent = zlib.gzipSync(fileContents.toString());
26 | // fs.writeFileSync(`dist/${current}.gzip`, zippedContent)
27 | // return previous + fs.statSync(`dist/${current}.gzip`).size
28 | // }, 0);
29 | // return previous;
30 | // }, {});
31 |
32 | const filesizeGzipped = (list) => list.map(project => ({
33 | ...project,
34 | size: project.paths.reduce((previous, current) => {
35 | const exists = fs.existsSync(`dist/${current}`);
36 | if (!exists) return undefined;
37 | const fileContents = fs.readFileSync(`dist/${current}`)
38 | const zippedContent = zlib.gzipSync(fileContents.toString());
39 | fs.writeFileSync(`dist/${current}.gzip`, zippedContent)
40 | return previous + fs.statSync(`dist/${current}.gzip`).size
41 | }, 0),
42 | })).sort((a, b) => a.size - b.size);
43 |
44 |
45 | // console.log(filesizeGzipped())
46 | // console.log(chart(filesizeGzipped(), true, 30))
47 |
48 | module.exports = {
49 | filesize,
50 | filesizeGzipped
51 | }
--------------------------------------------------------------------------------
/native-shadow-dom/src/todo-input.js:
--------------------------------------------------------------------------------
1 | const templateTodoInput = document.createElement('template');
2 | templateTodoInput.innerHTML = `
3 |
30 |
33 | `;
34 |
35 | export default class TodoInput extends HTMLElement {
36 | constructor() {
37 | super();
38 | this._root = this.attachShadow({ 'mode': 'open' });
39 | }
40 |
41 | connectedCallback() {
42 | console.log('TodoInput ADDED TO THE DOM');
43 | this._root.appendChild(templateTodoInput.content.cloneNode(true));
44 | this.$form = this._root.querySelector('form');
45 | this.$input = this._root.querySelector('input');
46 | this.$form.addEventListener("submit", (e) => {
47 | e.preventDefault();
48 | if (!this.$input.value) return;
49 | this.dispatchEvent(new CustomEvent('onSubmit', { detail: this.$input.value }));
50 | this.$input.value = '';
51 | });
52 | }
53 |
54 | disconnectedCallback() {
55 | console.log('TodoInput REMOVED TO THE DOM');
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/angular-elements/src/todo-input.ts:
--------------------------------------------------------------------------------
1 | import {
2 | Component,
3 | EventEmitter,
4 | Input,
5 | Output,
6 | ViewEncapsulation
7 | } from '@angular/core';
8 | import { FormBuilder, FormGroup, Validators } from '@angular/forms';
9 |
10 | @Component({
11 | selector: 'todo-input',
12 | template: `
13 |
20 | `,
21 | styles: [`
22 | :host {
23 | display: block;
24 | }
25 | form {
26 | position: relative;
27 | font-size: 24px;
28 | border-bottom: 1px solid #ededed;
29 | }
30 | input {
31 | padding: 16px 16px 16px 60px;
32 | border: none;
33 | background: rgba(0, 0, 0, 0.003);
34 | position: relative;
35 | margin: 0;
36 | width: 100%;
37 | font-size: 24px;
38 | font-family: inherit;
39 | font-weight: inherit;
40 | line-height: 1.4em;
41 | border: 0;
42 | outline: none;
43 | color: inherit;
44 | padding: 6px;
45 | border: 1px solid #CCC;
46 | box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
47 | box-sizing: border-box;
48 | }
49 | `],
50 | encapsulation: ViewEncapsulation.Native
51 | })
52 | export class TodoInput {
53 | @Output() onTodoInputSubmit = new EventEmitter();
54 | inputForm: FormGroup;
55 |
56 | constructor(
57 | private formBuilder: FormBuilder,
58 | ) {
59 | this.inputForm = this.formBuilder.group({
60 | 'text': ['', Validators.required],
61 | });
62 | }
63 |
64 | handleOnSubmit(e) {
65 | if (!this.inputForm.value.text) return;
66 | this.onTodoInputSubmit.emit(this.inputForm.value.text);
67 | this.inputForm.reset();
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/skatejs-lit-html/src/app.js:
--------------------------------------------------------------------------------
1 | import { props } from "skatejs/dist/esnext";
2 | import { html } from "lit-html/lib/lit-extended";
3 | import { Component } from "./util";
4 |
5 | export default class extends Component {
6 | state = {
7 | list: [
8 | { text: "my initial todo", checked: false },
9 | { text: "Learn about Web Components", checked: true }
10 | ]
11 | };
12 |
13 | handleCheck = e => {
14 | this.state.list[e.detail.index].checked = e.detail.value;
15 | this.state = this.state;
16 | };
17 | handleRemove = e => {
18 | this.state = {
19 | list: this.state.list.filter((item, index) => index !== e.detail.index)
20 | };
21 | };
22 | handleSubmit = e => {
23 | this.state = {
24 | list: [...this.state.list, { text: e.detail.value, checked: false }]
25 | };
26 | };
27 |
28 | render({ handleCheck, handleRemove, handleSubmit }) {
29 | return html`
30 |
56 | SkateJS & lit-html
57 |
58 |
59 |
60 | ${this.state.list.map(
61 | ({ checked, text }, index) => html`
62 | ${text}
68 | `
69 | )}
70 |
71 |
72 | `;
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/angular-elements/src/my-todo.ts:
--------------------------------------------------------------------------------
1 | import {
2 | Component,
3 | ViewEncapsulation,
4 | } from '@angular/core';
5 |
6 | interface TodoItem {
7 | text: string;
8 | checked: boolean;
9 | }
10 |
11 | @Component({
12 | selector: 'my-todo',
13 | template: `
14 | Todos Angular Elements
15 |
26 | `,
27 | styles: [`
28 | h1 {
29 | font-size: 55px;
30 | font-weight: 100;
31 | text-align: center;
32 | color: rgba(175, 47, 47, 0.15);
33 | }
34 |
35 | section {
36 | background: #fff;
37 | margin: 30px 0 40px 0;
38 | position: relative;
39 | box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
40 | }
41 |
42 | #list-container {
43 | margin: 0;
44 | padding: 0;
45 | list-style: none;
46 | border-top: 1px solid #e6e6e6;
47 | }
48 | `],
49 | encapsulation: ViewEncapsulation.Native
50 | })
51 | export class MyTodo {
52 | list: TodoItem[] = [
53 | { text: 'my initial todo', checked: false },
54 | { text: 'Learn about Web Components', checked: true }
55 | ];
56 |
57 | todoInputSubmiHandler(e) {
58 | this.list = [...this.list, { text: e, checked: false, }];
59 | }
60 |
61 | todoItemCheckedHandler(e, i) {
62 | const list = [...this.list];
63 | const item = list[i];
64 | list[i] = Object.assign({}, item, { checked: !item.checked });
65 | this.list = list;
66 | }
67 |
68 | todoItemRemoveHandler(e, i) {
69 | this.list = [...this.list.slice(0, i), ...this.list.slice(i + 1)];
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/native/js/my-todo.js:
--------------------------------------------------------------------------------
1 | const templateTodo = document.createElement('template');
2 | templateTodo.innerHTML = `
3 |
7 | `;
8 |
9 | class MyTodo extends HTMLElement {
10 | constructor() {
11 | super();
12 | // Do not use shadow DOM to avoid problems when testing with selenium
13 | // this._root = this.attachShadow({ 'mode': 'open' });
14 | // initial state
15 | this._list = [
16 | { text: 'my initial todo', checked: false },
17 | { text: 'Learn about Web Components', checked: true }
18 | ];
19 | }
20 |
21 | connectedCallback() {
22 | this.appendChild(templateTodo.content.cloneNode(true));
23 | this.$input = this.querySelector('todo-input');
24 | this.$listContainer = this.querySelector('#list-container');
25 | this.$input.addEventListener('onSubmit', this.addItem.bind(this));
26 | this._render();
27 | }
28 |
29 | addItem(e) {
30 | this._list.push({ text: e.detail, checked: false, });
31 | this._render();
32 | }
33 |
34 | removeItem(e) {
35 | this._list.splice(e.detail, 1);
36 | this._render();
37 | }
38 |
39 | toggleItem(e) {
40 | const item = this._list[e.detail];
41 | this._list[e.detail] = Object.assign({}, item, {
42 | checked: !item.checked
43 | });
44 | this._render();
45 | }
46 |
47 | disconnectedCallback() { }
48 |
49 | _render() {
50 | if (!this.$listContainer) return;
51 | // empty the list
52 | this.$listContainer.innerHTML = '';
53 | this._list.forEach((item, index) => {
54 | let $item = document.createElement('todo-item');
55 | $item.setAttribute('text', item.text);
56 | $item.checked = item.checked;
57 | $item.index = index;
58 | $item.addEventListener('onRemove', this.removeItem.bind(this));
59 | $item.addEventListener('onToggle', this.toggleItem.bind(this));
60 | this.$listContainer.appendChild($item);
61 | });
62 | }
63 | }
64 |
65 | window.customElements.define('my-todo', MyTodo);
66 |
--------------------------------------------------------------------------------
/skatejs-preact/src/app.js:
--------------------------------------------------------------------------------
1 | // @jsx h
2 |
3 | import { props } from "skatejs/dist/esnext";
4 | import { h } from "preact";
5 | import { Component } from "./util";
6 |
7 | export default class extends Component {
8 | state = {
9 | list: [
10 | { text: "my initial todo", checked: false },
11 | { text: "Learn about Web Components", checked: true }
12 | ]
13 | };
14 |
15 | handleCheck = e => {
16 | this.state.list[e.detail.index].checked = e.detail.value;
17 | this.state = this.state;
18 | };
19 | handleRemove = e => {
20 | this.state = {
21 | list: this.state.list.filter((item, index) => index !== e.detail.index)
22 | };
23 | };
24 | handleSubmit = e => {
25 | this.state = {
26 | list: [...this.state.list, { text: e.detail.value, checked: false }]
27 | };
28 | };
29 |
30 | render({ handleCheck, handleRemove, handleSubmit }) {
31 | return (
32 |
33 |
59 |
SkateJS & Preact
60 |
61 |
62 |
63 | {this.state.list.map(({ checked, text }, index) => (
64 |
70 | {text}
71 |
72 | ))}
73 |
74 |
75 |
76 | );
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/polymer2/src/todo-input/todo-input.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
42 |
43 |
48 |
49 |
50 |
51 |
79 |
--------------------------------------------------------------------------------
/solid/src/TodoItem.css:
--------------------------------------------------------------------------------
1 | :host {
2 | display: block;
3 | }
4 |
5 | li {
6 | font-size: 24px;
7 | display: block;
8 | position: relative;
9 | border-bottom: 1px solid #ededed;
10 | }
11 |
12 | li input {
13 | text-align: center;
14 | width: 40px;
15 | /* auto, since non-WebKit browsers doesn't support input styling */
16 | height: auto;
17 | position: absolute;
18 | top: 9px;
19 | bottom: 0;
20 | margin: auto 0;
21 | border: none;
22 | /* Mobile Safari */
23 | -webkit-appearance: none;
24 | appearance: none;
25 | }
26 |
27 | li input:after {
28 | content: url('data:image/svg+xml;utf8,');
29 | }
30 |
31 | li input:checked:after {
32 | content: url('data:image/svg+xml;utf8,');
33 | }
34 |
35 | li label {
36 | white-space: pre;
37 | word-break: break-word;
38 | padding: 15px 60px 15px 15px;
39 | margin-left: 45px;
40 | display: block;
41 | line-height: 1.2;
42 | transition: color 0.4s;
43 | }
44 |
45 | li.completed label {
46 | color: #d9d9d9;
47 | text-decoration: line-through;
48 | }
49 |
50 | li button,
51 | li input[type="checkbox"] {
52 | outline: none;
53 | }
54 |
55 | li button {
56 | margin: 0;
57 | padding: 0;
58 | border: 0;
59 | background: none;
60 | font-size: 100%;
61 | vertical-align: baseline;
62 | font-family: inherit;
63 | font-weight: inherit;
64 | color: inherit;
65 | -webkit-appearance: none;
66 | appearance: none;
67 | -webkit-font-smoothing: antialiased;
68 | -moz-font-smoothing: antialiased;
69 | font-smoothing: antialiased;
70 | }
71 |
72 | li button {
73 | position: absolute;
74 | top: 0;
75 | right: 10px;
76 | bottom: 0;
77 | width: 40px;
78 | height: 40px;
79 | margin: auto 0;
80 | font-size: 30px;
81 | color: #cc9a9a;
82 | margin-bottom: 11px;
83 | transition: color 0.2s ease-out;
84 | }
85 |
86 | li button:hover {
87 | color: #af5b5e;
88 | }
--------------------------------------------------------------------------------
/non-web-components-refs/react/src/components/todo-item/todo-item.css:
--------------------------------------------------------------------------------
1 | li {
2 | font-size: 24px;
3 | display: block;
4 | position: relative;
5 | border-bottom: 1px solid #ededed;
6 | }
7 |
8 | li input {
9 | text-align: center;
10 | width: 40px;
11 | /* auto, since non-WebKit browsers doesn't support input styling */
12 | height: auto;
13 | position: absolute;
14 | top: 9px;
15 | bottom: 0;
16 | margin: auto 0;
17 | border: none;
18 | /* Mobile Safari */
19 | -webkit-appearance: none;
20 | appearance: none;
21 | padding: 0;
22 | box-shadow: none;
23 | }
24 |
25 | li input:after {
26 | content: url('data:image/svg+xml;utf8,');
27 | }
28 |
29 | li input:checked:after {
30 | content: url('data:image/svg+xml;utf8,');
31 | }
32 |
33 | li label {
34 | white-space: pre;
35 | word-break: break-word;
36 | padding: 15px 60px 15px 15px;
37 | margin-left: 45px;
38 | display: block;
39 | line-height: 1.2;
40 | transition: color 0.4s;
41 | }
42 |
43 | li.completed label {
44 | color: #d9d9d9;
45 | text-decoration: line-through;
46 | }
47 |
48 | li button, li input[type="checkbox"] {
49 | outline: none;
50 | }
51 |
52 | li button {
53 | margin: 0;
54 | padding: 0;
55 | border: 0;
56 | background: none;
57 | font-size: 100%;
58 | vertical-align: baseline;
59 | font-family: inherit;
60 | font-weight: inherit;
61 | color: inherit;
62 | -webkit-appearance: none;
63 | appearance: none;
64 | -webkit-font-smoothing: antialiased;
65 | -moz-font-smoothing: antialiased;
66 | font-smoothing: antialiased;
67 | }
68 |
69 | li button {
70 | position: absolute;
71 | top: 0;
72 | right: 10px;
73 | bottom: 0;
74 | width: 40px;
75 | height: 40px;
76 | margin: auto 0;
77 | font-size: 30px;
78 | color: #cc9a9a;
79 | margin-bottom: 11px;
80 | transition: color 0.2s ease-out;
81 | }
82 |
83 | li button:hover {
84 | color: #af5b5e;
85 | }
--------------------------------------------------------------------------------
/native/js/todo-item.js:
--------------------------------------------------------------------------------
1 | const templateTodoItem = document.createElement('template');
2 | templateTodoItem.innerHTML = `
3 |
4 |
5 |
6 |
7 |
8 | `;
9 |
10 | class TodoItem extends HTMLElement {
11 | constructor() {
12 | super();
13 | // Do not use shadow DOM to avoid problems when testing with selenium
14 | // this._root = this.attachShadow({ 'mode': 'open' });
15 | this._checked = false;
16 | this._text = '';
17 | }
18 |
19 | connectedCallback() {
20 | this.appendChild(templateTodoItem.content.cloneNode(true));
21 | this.$item = this.querySelector('.item');
22 | this.$removeButton = this.querySelector('.destroy');
23 | this.$text = this.querySelector('label');
24 | this.$checkbox = this.querySelector('input');
25 | this.$removeButton.addEventListener('click', (e) => {
26 | e.preventDefault();
27 | this.dispatchEvent(new CustomEvent('onRemove', { detail: this.index }));
28 | });
29 | this.$checkbox.addEventListener('click', (e) => {
30 | e.preventDefault();
31 | this.dispatchEvent(new CustomEvent('onToggle', { detail: this.index }));
32 | });
33 | this._render();
34 | }
35 |
36 | disconnectedCallback() { }
37 |
38 | static get observedAttributes() {
39 | return ['text'];
40 | }
41 | attributeChangedCallback(name, oldValue, newValue) {
42 | this._text = newValue;
43 | }
44 |
45 | set index(value) {
46 | this._index = value;
47 | }
48 |
49 | get index() {
50 | return this._index;
51 | }
52 |
53 | set checked(value) {
54 | this._checked = Boolean(value);
55 | }
56 |
57 | get checked() {
58 | return this.hasAttribute('checked');
59 | }
60 |
61 | _render() {
62 | if (!this.$item) return;
63 | this.$text.textContent = this._text;
64 | if (this._checked) {
65 | this.$item.classList.add('completed');
66 | this.$checkbox.setAttribute('checked', '');
67 | } else {
68 | this.$item.classList.remove('completed');
69 | this.$checkbox.removeAttribute('checked');
70 | }
71 |
72 | }
73 | }
74 |
75 | window.customElements.define('todo-item', TodoItem);
76 |
--------------------------------------------------------------------------------
/slim-js/src/components/todo-item.css:
--------------------------------------------------------------------------------
1 | :host {
2 | display: block;
3 | }
4 |
5 | li {
6 | font-size: 24px;
7 | display: block;
8 | position: relative;
9 | border-bottom: 1px solid #ededed;
10 | }
11 |
12 | li input {
13 | text-align: center;
14 | width: 40px;
15 | /* auto, since non-WebKit browsers doesn't support input styling */
16 | height: auto;
17 | position: absolute;
18 | top: 9px;
19 | bottom: 0;
20 | margin: auto 0;
21 | border: none;
22 | /* Mobile Safari */
23 | -webkit-appearance: none;
24 | appearance: none;
25 | padding: 0;
26 | box-shadow: none;
27 | }
28 |
29 | li input:after {
30 | content: url('data:image/svg+xml;utf8,');
31 | }
32 |
33 | li input:checked:after {
34 | content: url('data:image/svg+xml;utf8,');
35 | }
36 |
37 | li label {
38 | white-space: pre;
39 | word-break: break-word;
40 | padding: 15px 60px 15px 15px;
41 | margin-left: 45px;
42 | display: block;
43 | line-height: 1.2;
44 | transition: color 0.4s;
45 | }
46 |
47 | li.completed label {
48 | color: #d9d9d9;
49 | text-decoration: line-through;
50 | }
51 |
52 | li button,
53 | li input[type="checkbox"] {
54 | outline: none;
55 | }
56 |
57 | li button {
58 | margin: 0;
59 | padding: 0;
60 | border: 0;
61 | background: none;
62 | font-size: 100%;
63 | vertical-align: baseline;
64 | font-family: inherit;
65 | font-weight: inherit;
66 | color: inherit;
67 | -webkit-appearance: none;
68 | appearance: none;
69 | -webkit-font-smoothing: antialiased;
70 | -moz-font-smoothing: antialiased;
71 | font-smoothing: antialiased;
72 | }
73 |
74 | li button {
75 | position: absolute;
76 | top: 0;
77 | right: 10px;
78 | bottom: 0;
79 | width: 40px;
80 | height: 40px;
81 | margin: auto 0;
82 | font-size: 30px;
83 | color: #cc9a9a;
84 | margin-bottom: 11px;
85 | transition: color 0.2s ease-out;
86 | }
87 |
88 | li button:hover {
89 | color: #af5b5e;
90 | }
--------------------------------------------------------------------------------
/stencil-0.11/src/components/todo-item/todo-item.css:
--------------------------------------------------------------------------------
1 | :host {
2 | display: block;
3 | }
4 |
5 | li {
6 | font-size: 24px;
7 | display: block;
8 | position: relative;
9 | border-bottom: 1px solid #ededed;
10 | }
11 |
12 | li input {
13 | text-align: center;
14 | width: 40px;
15 | /* auto, since non-WebKit browsers doesn't support input styling */
16 | height: auto;
17 | position: absolute;
18 | top: 9px;
19 | bottom: 0;
20 | margin: auto 0;
21 | border: none;
22 | /* Mobile Safari */
23 | -webkit-appearance: none;
24 | appearance: none;
25 | padding: 0;
26 | box-shadow: none;
27 | }
28 |
29 | li input:after {
30 | content: url('data:image/svg+xml;utf8,');
31 | }
32 |
33 | li input:checked:after {
34 | content: url('data:image/svg+xml;utf8,');
35 | }
36 |
37 | li label {
38 | white-space: pre;
39 | word-break: break-word;
40 | padding: 15px 60px 15px 15px;
41 | margin-left: 45px;
42 | display: block;
43 | line-height: 1.2;
44 | transition: color 0.4s;
45 | }
46 |
47 | li.completed label {
48 | color: #d9d9d9;
49 | text-decoration: line-through;
50 | }
51 |
52 | li button,
53 | li input[type="checkbox"] {
54 | outline: none;
55 | }
56 |
57 | li button {
58 | margin: 0;
59 | padding: 0;
60 | border: 0;
61 | background: none;
62 | font-size: 100%;
63 | vertical-align: baseline;
64 | font-family: inherit;
65 | font-weight: inherit;
66 | color: inherit;
67 | -webkit-appearance: none;
68 | appearance: none;
69 | -webkit-font-smoothing: antialiased;
70 | -moz-font-smoothing: antialiased;
71 | font-smoothing: antialiased;
72 | }
73 |
74 | li button {
75 | position: absolute;
76 | top: 0;
77 | right: 10px;
78 | bottom: 0;
79 | width: 40px;
80 | height: 40px;
81 | margin: auto 0;
82 | font-size: 30px;
83 | color: #cc9a9a;
84 | margin-bottom: 11px;
85 | transition: color 0.2s ease-out;
86 | }
87 |
88 | li button:hover {
89 | color: #af5b5e;
90 | }
91 |
--------------------------------------------------------------------------------
/stencil-0.16/src/components/todo-item/todo-item.css:
--------------------------------------------------------------------------------
1 | :host {
2 | display: block;
3 | }
4 |
5 | li {
6 | font-size: 24px;
7 | display: block;
8 | position: relative;
9 | border-bottom: 1px solid #ededed;
10 | }
11 |
12 | li input {
13 | text-align: center;
14 | width: 40px;
15 | /* auto, since non-WebKit browsers doesn't support input styling */
16 | height: auto;
17 | position: absolute;
18 | top: 9px;
19 | bottom: 0;
20 | margin: auto 0;
21 | border: none;
22 | /* Mobile Safari */
23 | -webkit-appearance: none;
24 | appearance: none;
25 | padding: 0;
26 | box-shadow: none;
27 | }
28 |
29 | li input:after {
30 | content: url('data:image/svg+xml;utf8,');
31 | }
32 |
33 | li input:checked:after {
34 | content: url('data:image/svg+xml;utf8,');
35 | }
36 |
37 | li label {
38 | white-space: pre;
39 | word-break: break-word;
40 | padding: 15px 60px 15px 15px;
41 | margin-left: 45px;
42 | display: block;
43 | line-height: 1.2;
44 | transition: color 0.4s;
45 | }
46 |
47 | li.completed label {
48 | color: #d9d9d9;
49 | text-decoration: line-through;
50 | }
51 |
52 | li button,
53 | li input[type="checkbox"] {
54 | outline: none;
55 | }
56 |
57 | li button {
58 | margin: 0;
59 | padding: 0;
60 | border: 0;
61 | background: none;
62 | font-size: 100%;
63 | vertical-align: baseline;
64 | font-family: inherit;
65 | font-weight: inherit;
66 | color: inherit;
67 | -webkit-appearance: none;
68 | appearance: none;
69 | -webkit-font-smoothing: antialiased;
70 | -moz-font-smoothing: antialiased;
71 | font-smoothing: antialiased;
72 | }
73 |
74 | li button {
75 | position: absolute;
76 | top: 0;
77 | right: 10px;
78 | bottom: 0;
79 | width: 40px;
80 | height: 40px;
81 | margin: auto 0;
82 | font-size: 30px;
83 | color: #cc9a9a;
84 | margin-bottom: 11px;
85 | transition: color 0.2s ease-out;
86 | }
87 |
88 | li button:hover {
89 | color: #af5b5e;
90 | }
91 |
--------------------------------------------------------------------------------
/functional-element/src/my-todo.js:
--------------------------------------------------------------------------------
1 | import { customElement, html } from 'functional-element';
2 | import './todo-input.js';
3 | import './todo-item.js';
4 |
5 | customElement('my-todo', ({ constructing, props, update }) => {
6 | if (constructing) {
7 | return {
8 | list: [
9 | { text: 'my initial todo', checked: false },
10 | { text: 'Learn about Web Components', checked: true },
11 | ]
12 | };
13 | }
14 |
15 | return html`
16 |
39 |
40 | Todos Functional Element
41 |
42 |
43 | update(addItem(props.list, e.detail))}>
44 | ${props.list.map((item, index) => html`
45 | update(removeItem(props.list, e.detail))}
50 | @toggle=${(e) => update(toggleItem(props.list, e.detail))}
51 | >`)}
52 |
53 |
54 | `;
55 | });
56 |
57 | function addItem(list, text) {
58 | return {
59 | list: [...list, { text, checked: false, }]
60 | };
61 | }
62 |
63 | function removeItem(list, index) {
64 | return {
65 | list: [...list.slice(0, index), ...list.slice(index + 1)]
66 | };
67 | }
68 |
69 | function toggleItem(list, index) {
70 | const originalList = [...list];
71 | const item = originalList[index];
72 | originalList[index] = Object.assign({}, item, { checked: !item.checked });
73 |
74 | return {
75 | list: originalList
76 | };
77 | }
--------------------------------------------------------------------------------
/atomico/src/todo-item/style.css:
--------------------------------------------------------------------------------
1 | :host {
2 | display: block;
3 | }
4 |
5 | li {
6 | font-size: 24px;
7 | display: block;
8 | position: relative;
9 | border-bottom: 1px solid #ededed;
10 | }
11 |
12 | li input {
13 | text-align: center;
14 | width: 40px;
15 | /* auto, since non-WebKit browsers doesn't support input styling */
16 | height: auto;
17 | position: absolute;
18 | top: 9px;
19 | bottom: 0;
20 | margin: auto 0;
21 | border: none;
22 | /* Mobile Safari */
23 | -webkit-appearance: none;
24 | appearance: none;
25 | padding: 0;
26 | box-shadow: none;
27 | }
28 |
29 | li input:after {
30 | content: url('data:image/svg+xml;utf8,');
31 | }
32 |
33 | li input:checked:after {
34 | content: url('data:image/svg+xml;utf8,');
35 | }
36 |
37 | li label {
38 | white-space: pre;
39 | word-break: break-word;
40 | padding: 15px 60px 15px 15px;
41 | margin-left: 45px;
42 | display: block;
43 | line-height: 1.2;
44 | transition: color 0.4s;
45 | }
46 |
47 | li.completed label {
48 | color: #d9d9d9;
49 | text-decoration: line-through;
50 | }
51 |
52 | li button, li input[type="checkbox"] {
53 | outline: none;
54 | }
55 |
56 | li button {
57 | margin: 0;
58 | padding: 0;
59 | border: 0;
60 | background: none;
61 | font-size: 100%;
62 | vertical-align: baseline;
63 | font-family: inherit;
64 | font-weight: inherit;
65 | color: inherit;
66 | -webkit-appearance: none;
67 | appearance: none;
68 | -webkit-font-smoothing: antialiased;
69 | -moz-font-smoothing: antialiased;
70 | font-smoothing: antialiased;
71 | }
72 |
73 | li button {
74 | position: absolute;
75 | top: 0;
76 | right: 10px;
77 | bottom: 0;
78 | width: 40px;
79 | height: 40px;
80 | margin: auto 0;
81 | font-size: 30px;
82 | color: #cc9a9a;
83 | margin-bottom: 11px;
84 | transition: color 0.2s ease-out;
85 | }
86 |
87 | li button:hover {
88 | color: #af5b5e;
89 | }
--------------------------------------------------------------------------------
/stencil-0.16/src/components.d.ts:
--------------------------------------------------------------------------------
1 | /* tslint:disable */
2 | /**
3 | * This is an autogenerated file created by the Stencil compiler.
4 | * It contains typing information for all components that exist in this project.
5 | */
6 |
7 |
8 | import '@stencil/core';
9 |
10 |
11 |
12 |
13 | export namespace Components {
14 |
15 | interface MyTodo {}
16 | interface MyTodoAttributes extends StencilHTMLAttributes {}
17 |
18 | interface TodoInput {}
19 | interface TodoInputAttributes extends StencilHTMLAttributes {
20 | 'onOnTodoInputSubmit'?: (event: CustomEvent) => void;
21 | }
22 |
23 | interface TodoItem {
24 | 'checked': boolean;
25 | 'index': number;
26 | 'text': string;
27 | }
28 | interface TodoItemAttributes extends StencilHTMLAttributes {
29 | 'checked'?: boolean;
30 | 'index'?: number;
31 | 'onOnTodoItemChecked'?: (event: CustomEvent) => void;
32 | 'onOnTodoItemRemove'?: (event: CustomEvent) => void;
33 | 'text'?: string;
34 | }
35 | }
36 |
37 | declare global {
38 | interface StencilElementInterfaces {
39 | 'MyTodo': Components.MyTodo;
40 | 'TodoInput': Components.TodoInput;
41 | 'TodoItem': Components.TodoItem;
42 | }
43 |
44 | interface StencilIntrinsicElements {
45 | 'my-todo': Components.MyTodoAttributes;
46 | 'todo-input': Components.TodoInputAttributes;
47 | 'todo-item': Components.TodoItemAttributes;
48 | }
49 |
50 |
51 | interface HTMLMyTodoElement extends Components.MyTodo, HTMLStencilElement {}
52 | var HTMLMyTodoElement: {
53 | prototype: HTMLMyTodoElement;
54 | new (): HTMLMyTodoElement;
55 | };
56 |
57 | interface HTMLTodoInputElement extends Components.TodoInput, HTMLStencilElement {}
58 | var HTMLTodoInputElement: {
59 | prototype: HTMLTodoInputElement;
60 | new (): HTMLTodoInputElement;
61 | };
62 |
63 | interface HTMLTodoItemElement extends Components.TodoItem, HTMLStencilElement {}
64 | var HTMLTodoItemElement: {
65 | prototype: HTMLTodoItemElement;
66 | new (): HTMLTodoItemElement;
67 | };
68 |
69 | interface HTMLElementTagNameMap {
70 | 'my-todo': HTMLMyTodoElement
71 | 'todo-input': HTMLTodoInputElement
72 | 'todo-item': HTMLTodoItemElement
73 | }
74 |
75 | interface ElementTagNameMap {
76 | 'my-todo': HTMLMyTodoElement;
77 | 'todo-input': HTMLTodoInputElement;
78 | 'todo-item': HTMLTodoItemElement;
79 | }
80 |
81 |
82 | export namespace JSX {
83 | export interface Element {}
84 | export interface IntrinsicElements extends StencilIntrinsicElements {
85 | [tagName: string]: any;
86 | }
87 | }
88 | export interface HTMLAttributes extends StencilHTMLAttributes {}
89 |
90 | }
91 |
--------------------------------------------------------------------------------
/lit-element-2.1/src/my-todo.js:
--------------------------------------------------------------------------------
1 | import { LitElement, html } from 'lit-element';
2 |
3 | export default class MyTodo extends LitElement {
4 | constructor() {
5 | super();
6 | this.list = [
7 | { text: 'my initial todo', checked: false },
8 | { text: 'Learn about Web Components', checked: true },
9 | ];
10 | this.addItem = this.addItem.bind(this);
11 | this.removeItem = this.removeItem.bind(this);
12 | this.toggleItem = this.toggleItem.bind(this);
13 | }
14 |
15 | addItem(e, text) {
16 | this.list = [...this.list, { text, checked: false, }];
17 | this.requestUpdate('list');
18 | }
19 |
20 | removeItem(e, index) {
21 | this.list = [...this.list.slice(0, index), ...this.list.slice(index + 1)];
22 | this.requestUpdate('list');
23 | }
24 |
25 | toggleItem(e, index) {
26 | const list = [...this.list];
27 | const item = list[index];
28 | list[index] = Object.assign({}, item, { checked: !item.checked });
29 | this.list = list;
30 | this.requestUpdate('list');
31 | }
32 |
33 | render() {
34 | return html`
35 |
58 | Todos Lit Element
59 |
60 | this.addItem(e, e.detail)}">
61 | ${this.list.map((item, index) => html`
62 | this.removeItem(e, e.detail)}"
67 | @toggle="${(e) => this.toggleItem(e, e.detail)}"
68 | >`)}
69 |
70 | `;
71 | }
72 | }
73 |
--------------------------------------------------------------------------------