Last active
April 8, 2021 17:27
-
-
Save sarvabowmen/26479212232f07bada32a3007c15cb7b to your computer and use it in GitHub Desktop.
Convert Rating react component as web component
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <div style="display:flex"> | |
| <div style="padding:150px 500px"> | |
| <h1>Rating element with webcomponents</h1> | |
| <rating-element maxValue=5 value=0 onratingupdatedevt="onratingupdatedevt"></rating-element> | |
| <div id="result"></div> | |
| <button id="btnReset">Reset</button> | |
| </div> | |
| <script> | |
| const btn = document.getElementById('btnReset'); | |
| const reactEl = document.getElementsByTagName('rating-element')[0]; | |
| btn.onclick = function (event) { | |
| reactEl.setAttribute("value", 0); | |
| var reactResultEl = document.getElementById('result'); | |
| reactResultEl.innerHTML = "You have rated " + event.detail; | |
| }; | |
| reactEl.addEventListener("onratingupdatedevt", function (event) { | |
| var reactResultEl = document.getElementById('result'); | |
| reactResultEl.innerHTML = "You have rated " + event.detail; | |
| }); | |
| </script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import './index.css'; | |
| import * as serviceWorker from './serviceWorker'; | |
| import './ReactElement'; | |
| // If you want your app to work offline and load faster, you can change | |
| // unregister() to register() below. Note this comes with some pitfalls. | |
| // Learn more about service workers: https://bit.ly/CRA-PWA | |
| serviceWorker.unregister(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import * as React from 'react'; | |
| import PropTypes from 'prop-types'; | |
| class RatingComponent extends React.Component { | |
| static propTypes = { | |
| maxValue: PropTypes.number, | |
| value: PropTypes.number, | |
| onRatingUpdatedEvt: PropTypes.func | |
| } | |
| static defaultProps = { | |
| maxValue: 5 | |
| } | |
| constructor(props){ | |
| super(props); | |
| this.starList = []; | |
| this.value = 0; | |
| this.maxValue = props.maxValue; | |
| this.state = { starList : [] }; | |
| } | |
| componentDidMount(){ | |
| this.createStars(this.value); | |
| } | |
| setValue(newVal) { | |
| this.value = newVal; | |
| this.createStars(this.value); | |
| this.props.onratingupdatedevt({ detail: this.value }); | |
| } | |
| createStars(starsSelected) { | |
| let starList = []; | |
| for(let i=0; i<=this.maxValue; i++) { | |
| if(i<=starsSelected){ | |
| starList.push(<span key={i} className="rating" onMouseOver={()=> this.createStars(i)} onMouseOut={()=> { this.createStars(this.value) }} onClick={ ()=> this.setValue(i) } >★</span>); | |
| } else { | |
| starList.push(<span key={i} className="rating" onMouseOver={()=> this.createStars(i)} onMouseOut={()=> { this.createStars(this.value) }} onClick={ ()=> this.setValue(i) }>☆</span>); | |
| } | |
| } | |
| this.starList = starList; | |
| this.setState({ starList: starList }); | |
| } | |
| render(){ | |
| return ( | |
| <div> | |
| {this.state.starList} | |
| </div> | |
| ) | |
| } | |
| } | |
| RatingComponent.propTypes = { | |
| maxValue: PropTypes.number, | |
| value: PropTypes.number, | |
| onratingupdatedevt: PropTypes.func | |
| }; | |
| export default RatingComponent; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import * as React from 'react'; | |
| import { render, unmountComponentAtNode } from 'react-dom'; | |
| import RatingComponent from './RatingComponent.js'; | |
| class ReactElement extends HTMLElement { | |
| constructor() { | |
| super(); | |
| this.observer = new MutationObserver(() => this.update()); | |
| this.observer.observe(this, { attributes: true }); | |
| } | |
| connectedCallback() { | |
| this._innerHTML = this.innerHTML; | |
| this.mount(); | |
| } | |
| disconnectedCallback() { | |
| this.unmount(); | |
| this.observer.disconnect(); | |
| } | |
| update() { | |
| this.unmount(); | |
| this.mount(); | |
| } | |
| mount() { | |
| const props = { | |
| ...this.getProps(this.attributes), | |
| ...this.getEvents(), | |
| children: this.parseHtmlToReact(this.innerHTML) | |
| }; | |
| render(<RatingComponent {...props} />, this); | |
| } | |
| unmount() { | |
| unmountComponentAtNode(this); | |
| } | |
| parseHtmlToReact(html) { | |
| return html; | |
| } | |
| getProps(attributes) { | |
| return [ ...attributes ] | |
| .filter(attr => attr.name !== 'style') | |
| .map(attr => this.convert(attr.name, attr.value)) | |
| .reduce((props, prop) => | |
| ({ ...props, [prop.name]: prop.value }), {}); | |
| } | |
| getEvents() { | |
| return Object.values(this.attributes) | |
| .filter(key => /on([a-z].*)/.exec(key.name)) | |
| .reduce((events, ev) => ({ | |
| ...events, | |
| [ev.name]: args => | |
| this.dispatchEvent(new CustomEvent(ev.name, { ...args })) | |
| }), {}); | |
| } | |
| convert(attrName, attrValue) { | |
| let value = attrValue; | |
| if (attrValue === 'true' || attrValue === 'false') | |
| value = attrValue === 'true'; | |
| else if (!isNaN(attrValue) && attrValue !== '') | |
| value = +attrValue; | |
| else if (/^{.*}/.exec(attrValue)) | |
| value = JSON.parse(attrValue); | |
| return { | |
| name: attrName, | |
| value: value | |
| }; | |
| } | |
| } | |
| customElements.define('rating-element', ReactElement); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment