From 5b892fe22f131a53e9526d41b30bcba2e1a23b23 Mon Sep 17 00:00:00 2001 From: Jeevan Jyoti Dash Date: Sun, 10 Oct 2021 12:21:06 +0530 Subject: [PATCH] star-rating init --- star-rating/app.js | 86 ++++++++++++++++++++++++++++++++++++++++++ star-rating/index.html | 14 +++++++ star-rating/style.css | 32 ++++++++++++++++ 3 files changed, 132 insertions(+) create mode 100644 star-rating/app.js create mode 100644 star-rating/index.html create mode 100644 star-rating/style.css diff --git a/star-rating/app.js b/star-rating/app.js new file mode 100644 index 0000000..af39f20 --- /dev/null +++ b/star-rating/app.js @@ -0,0 +1,86 @@ +const makeStarRating = function (noOfStars = 5) { + let rating = 0; + let starComponent; + + function changeRating(newRating) { + rating = newRating; + } + function getStarComponent() { + if (!starComponent) { + starComponent = document.createElement('ul'); + starComponent.className = 'stcomp'; + for (let i = 0; i < noOfStars; i++) { + const li = document.createElement('li'); + li.setAttribute('data-rating', i + 1); + li.className = 'star'; + if (i === 0) li.tabIndex = 0; + starComponent.append(li); + } + starComponent.addEventListener('mouseover', onMouseOver); + starComponent.addEventListener('mouseleave', onMouseLeave); + starComponent.addEventListener('click', onMouseClick); + } + return starComponent; + } + function renderChanges(rating) { + for (let index = 0; index < rating; index++) { + starComponent.children[index].classList.add('star-filled'); + } + for (let index = rating; index < noOfStars; index++) { + starComponent.children[index].classList.remove('star-filled'); + } + } + + function onMouseOver(e) { + let isStar = e.target.classList.contains('star'); + if (isStar) { + const { rating } = e.target.dataset; + renderChanges(rating); + } + } + + function onMouseLeave(e) { + renderChanges(rating); + } + + function onMouseClick(e) { + let star = e.target ?? e; + let isStar = star.classList.contains('star'); + if (isStar) { + activate(star); + let { rating } = star.dataset; + if (e.key !== 'Tab' && rating === getRating()) { + rating = 0; + resetTabIndex(); + starComponent.firstElementChild.tabIndex = 0; + } + changeRating(rating); + renderChanges(rating); + } + } + + function activate(element) { + resetTabIndex(); + element.tabIndex = 0; + element.focus(); + } + + function resetTabIndex() { + starComponent.childNodes.forEach((star) => { + star.tabIndex = -1; + }); + } + + function getRating() { + return rating; + } + + return { getStarComponent }; +}; + +const ratingModule1 = makeStarRating(5); + +const starComponent1 = ratingModule1.getStarComponent(); +const container = document.querySelector('main'); + +container.append(starComponent1); diff --git a/star-rating/index.html b/star-rating/index.html new file mode 100644 index 0000000..54c27ea --- /dev/null +++ b/star-rating/index.html @@ -0,0 +1,14 @@ + + + + + + + + Star Rating + + +
+ + + diff --git a/star-rating/style.css b/star-rating/style.css new file mode 100644 index 0000000..6743b0b --- /dev/null +++ b/star-rating/style.css @@ -0,0 +1,32 @@ +.star { + background: lightgrey; + clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%); + display: inline-block; + height: 50px; + width: 50px; + margin-left: 2px; + transition: transform 0.1s; +} + +.star:hover { + transform: scale(1.2); +} +.star:focus { + transform: scale(1.2); +} +.stcomp { + cursor: pointer; + display: flex; + list-style-type: none; +} + +main { + display: flex; + flex-direction: column; + height: 100vh; + justify-content: center; + align-items: center; +} +.star-filled { + background: orange; +}