├── .gitignore ├── .babelrc ├── package.json ├── webpack.config.js ├── src ├── store.js ├── App.js ├── template.html └── components │ └── Counter.js └── Readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-env"] 3 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "counters", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "scripts": { 7 | "watch": "webpack-dev-server --mode=development", 8 | "build": "webpack --mode=production" 9 | }, 10 | "devDependencies": { 11 | "html-webpack-plugin": "^3.2.0", 12 | "webpack": "^4.28.4", 13 | "webpack-cli": "^3.2.1", 14 | "webpack-dev-server": "^3.1.14", 15 | "@babel/core": "^7.2.2", 16 | "@babel/preset-env": "^7.2.3", 17 | "babel-loader": "^8.0.5" 18 | }, 19 | "dependencies": { 20 | "@webcomponents/webcomponentsjs": "^2.2.4", 21 | "redux": "^4.0.1" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const htmlWebpackPlugin = require('html-webpack-plugin'); 3 | 4 | module.exports = { 5 | 6 | entry: './src/App.js', 7 | 8 | output: { 9 | filename: 'bundle.js', 10 | path: path.resolve(__dirname, 'build') 11 | }, 12 | 13 | module: { 14 | rules:[ 15 | { 16 | test: /\.js$/, 17 | exclude: /node_modules/, 18 | loader: 'babel-loader' 19 | } 20 | ] 21 | }, 22 | 23 | plugins: [ 24 | new htmlWebpackPlugin({ 25 | template: './src/template.html' 26 | }) 27 | ], 28 | 29 | devServer: { 30 | port: 9000, 31 | open: true 32 | } 33 | 34 | }; -------------------------------------------------------------------------------- /src/store.js: -------------------------------------------------------------------------------- 1 | import { createStore } from 'redux'; 2 | 3 | export const INCREASE_COUNTER = 'INCREASE_COUNTE'; 4 | 5 | const initState = [ 6 | {uid:1, counter: 0}, 7 | {uid:2, counter: 0}, 8 | {uid:3, counter: 0} 9 | ]; 10 | 11 | const reducer = (state = initState, action) => { 12 | switch(action.type) { 13 | case INCREASE_COUNTER: 14 | return state.map((counterItem)=>{ 15 | if(counterItem.uid === action.uid) { 16 | return { ...counterItem, counter: counterItem.counter + 1 }; 17 | } 18 | return counterItem; 19 | }); 20 | default: 21 | return state; 22 | } 23 | } 24 | 25 | export default createStore(reducer); -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # 🏗️ Native Web Component With Redux 2 | 3 | This is an experimental project, where I tried out native web components. I created a Counter component and embeded it three times to a simple HTML page. After that, I connected them to a common store with Redux and voila! 4 | The counters can increase themselfes in store individually with their own object. 5 | 6 | ## 🧱 Would you give it a try?! 7 | 8 | * First step: clone the repo 9 | * Second step: install the dependencies with **yarn install** command 10 | * Thirs step: **yarn watch** command (your development server will run on the **port 9000**) 11 | 12 | ## 🍻 If you need a bundled, build version: **yarn build** 13 | 14 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import '@webcomponents/webcomponentsjs'; 2 | import Counter from './components/Counter'; 3 | import store from './store'; 4 | 5 | class App { 6 | 7 | constructor() { 8 | this.initComponents(); 9 | store.subscribe(()=>{ 10 | const altogether = store.getState().reduce((acc, currentCounter)=>{ return currentCounter.counter + acc}, 0) 11 | this.changeAltogether(altogether); 12 | }); 13 | } 14 | 15 | changeAltogether(altogether) { 16 | document.getElementById('altogether').innerHTML = altogether; 17 | } 18 | 19 | initComponents() { 20 | window.customElements.define('my-counter', Counter); 21 | } 22 | 23 | } 24 | 25 | (function(){ 26 | new App(); 27 | })(); 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 |