5 changed files with 157 additions and 0 deletions
@ -0,0 +1,6 @@ |
|||
module.exports = { |
|||
stories: [ |
|||
'../stories/**/*.stories.js', |
|||
'../src/components/**/*.js', |
|||
], |
|||
} |
@ -0,0 +1,2 @@ |
|||
npm install |
|||
yarn storybook |
@ -0,0 +1,20 @@ |
|||
{ |
|||
"name": "WebComponent", |
|||
"version": "1.0.0", |
|||
"description": "", |
|||
"main": "index.js", |
|||
"scripts": { |
|||
"test": "echo \"Error: no test specified\" && exit 1", |
|||
"storybook": "start-storybook -p 6006", |
|||
"build-storybook": "build-storybook -c .storybook -o .out", |
|||
"start-storybook": "start-storybook -s ./public -p 9001" |
|||
}, |
|||
"keywords": [], |
|||
"author": "", |
|||
"license": "ISC", |
|||
"devDependencies": { |
|||
"@babel/core": "^7.8.6", |
|||
"@storybook/html": "^5.3.14", |
|||
"babel-loader": "^8.0.6" |
|||
} |
|||
} |
@ -0,0 +1,96 @@ |
|||
|
|||
const styleRules = ` .rating {font-size: 50px; color: orange; cursor: pointer }` |
|||
|
|||
class MyRating extends HTMLElement { |
|||
|
|||
constructor() { |
|||
super() |
|||
this._maxValue = 5 |
|||
this._value = 4 |
|||
this.attachShadow({mode: "open"}) |
|||
} |
|||
|
|||
connectedCallback() { |
|||
this.createComponent() |
|||
} |
|||
|
|||
get maxValue() { |
|||
return this._maxValue |
|||
} |
|||
|
|||
set maxValue(val) { |
|||
this._maxValue = val |
|||
this.setAttribute("max-value", val) |
|||
} |
|||
|
|||
get value() { |
|||
return this._value |
|||
} |
|||
|
|||
set value(val) { |
|||
this._value = val |
|||
this.setAttribute("value", val) |
|||
} |
|||
|
|||
static get observedAttributes() { |
|||
return ["max-value", "value"] |
|||
} |
|||
|
|||
attributeChangedCallback(name, oldValue, newValue) { |
|||
if (oldValue !== newValue) { |
|||
switch (name) { |
|||
case "max-value": |
|||
this._maxValue = newValue |
|||
break |
|||
case "value": |
|||
this._value = newValue |
|||
break |
|||
default: |
|||
} |
|||
this.replaceStarList() |
|||
} |
|||
} |
|||
|
|||
replaceStarList() { |
|||
let starNode = this.shadowRoot.children[1]; |
|||
if (starNode) { |
|||
let starList = this.createStarList(); |
|||
starNode.remove(); |
|||
this.shadowRoot.appendChild(starList); |
|||
} |
|||
} |
|||
|
|||
createComponent() { |
|||
this.createStyle() |
|||
let starList = this.createStarList() |
|||
this.shadowRoot.appendChild(starList) |
|||
} |
|||
|
|||
createStyle() { |
|||
let style = document.createElement("style") |
|||
style.appendChild(document.createTextNode(styleRules)) |
|||
this.shadowRoot.appendChild(style) |
|||
} |
|||
|
|||
createStarList() { |
|||
let div = document.createElement("div") |
|||
for (let i = 1; i <= this.maxValue; i++) { |
|||
let star = i <= this.value ? this.createStar("★", i) : this.createStar("☆", i) |
|||
div.appendChild(star) |
|||
} |
|||
return div |
|||
} |
|||
|
|||
createStar(starCode, i) { |
|||
let span = document.createElement("span") |
|||
span.setAttribute("class", "rating") |
|||
span.innerHTML = starCode |
|||
span.addEventListener("click", () => { |
|||
this.value = i |
|||
}, false) |
|||
return span |
|||
} |
|||
} |
|||
|
|||
customElements.define("my-rating", MyRating) |
|||
|
@ -0,0 +1,33 @@ |
|||
|
|||
export default { |
|||
title: 'Demo', |
|||
} |
|||
|
|||
export const Heading = () => '<h1>Hello World</h1>' |
|||
|
|||
export const Button = () => { |
|||
const btn = document.createElement('button') |
|||
btn.type = 'button' |
|||
btn.innerText = 'Button' |
|||
btn.addEventListener('click', (e) => { |
|||
console.log('clicked') |
|||
}) |
|||
return btn |
|||
} |
|||
|
|||
export const withText = () => '<button class="btn">Hello World</button>' |
|||
|
|||
export const withEmoji = () => { |
|||
const button = document.createElement('button') |
|||
button.innerText = '😀 😎 👍 💯' |
|||
return button |
|||
} |
|||
|
|||
export const Rating = () => { |
|||
const rat = document.createElement('my-rating') |
|||
rat.type = 'my-rating' |
|||
rat.id = 'myRatingComponent' |
|||
rat.value = 4 |
|||
rat.maxValue = 5 |
|||
return rat |
|||
} |
Loading…
Reference in new issue