standard-ui/components/dist/carousel.min.js
2021-07-19 00:56:26 +05:30

1 line
9.8 KiB
JavaScript

const smCarousel=document.createElement("template");smCarousel.innerHTML='\n<style>\n*{\n padding: 0;\n margin: 0;\n -webkit-box-sizing: border-box;\n box-sizing: border-box;\n} \n:host{\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n --accent-color: #4d2588;\n --text-color: 17, 17, 17;\n --background-color: 255, 255, 255;\n --arrow-left: 1rem;\n --arrow-right: 1rem;\n --arrow-top: auto;\n --arrow-bottom: auto;\n --nav-icon-fill: rgba(var(--background-color), 1);\n --nav-background-color: rgba(var(--text-color), 1);\n --nav-box-shadow: 0 0.2rem 0.2rem #00000020, 0 0.5rem 1rem #00000040;\n --indicator-top: auto;\n --indicator-bottom: -1.5rem;\n --indicator-height: 0.2rem;\n --indicator-width: 0.4rem;\n --indicator-border-radius: 0.4rem;\n --indicators-gap: 0.5rem;\n --active-indicator-color: var(--accent-color);\n}\n.carousel__button{\n position: absolute;\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n cursor: pointer;\n min-width: 0;\n top: var(--arrow-top);\n bottom: var(--arrow-bottom);\n border: none;\n background: var(--nav-background-color);\n -webkit-box-shadow: var(--nav-box-shadow);\n box-shadow: var(--nav-box-shadow); \n -webkit-tap-highlight-color: transparent;\n transition: transform 0.3s, opacity 0.3s;\n z-index: 1;\n border-radius: 3rem;\n padding: 0.5rem;\n}\nbutton:focus{\n outline: none;\n}\nbutton:focus-visible{\n outline: rgba(var(--text-color), 1) 0.1rem solid;\n}\n.carousel__button:active{\n transform: scale(0.9);\n}\n.carousel__button--left{\n left: var(--arrow-left);\n}\n.carousel__button--right{\n right: var(--arrow-right);\n}\n.icon {\n height: 1.5rem;\n width: 1.5rem;\n fill: var(--nav-icon-fill);\n}\n.hide{\n display: none !important;\n}\n:host([indicator]) .carousel-container{\n margin-bottom: 2rem;\n}\n.carousel-container{\n position: relative;\n display: grid;\n width: 100%;\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n}\n.carousel{\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n max-width: 100%;\n width: 100%;\n overflow: auto hidden;\n -ms-scroll-snap-type: x mandatory;\n scroll-snap-type: x mandatory;\n}\n.indicators{\n display: -ms-grid;\n display: grid;\n grid-auto-flow: column;\n -webkit-box-pack: center;\n -ms-flex-pack: center;\n justify-content: center;\n position: absolute;\n padding: 0.5rem 0;\n top: var(--indicator-top);\n bottom: var(--indicator-bottom);\n gap: var(--indicators-gap);\n width: 100%;\n}\n.indicator{\n position: relative;\n height: var(--indicator-height);\n width: var(--indicator-width);\n background: rgba(var(--text-color), 0.3);\n border-radius: var(--indicator-border-radius);\n -webkit-transition: 0.2s;\n -o-transition: 0.2s;\n transition: 0.2s;\n cursor: pointer;\n}\n.indicator.active{\n -webkit-transform: scale(1.5);\n -ms-transform: scale(1.5);\n transform: scale(1.5);\n background: var(--active-indicator-color);\n}\nslot::slotted(*){\n scroll-snap-align: center;\n}\n:host([align-items="start"]) slot::slotted(*){\n scroll-snap-align: start;\n}\n:host([align-items="center"]) slot::slotted(*){\n scroll-snap-align: center;\n}\n:host([align-items="end"]) slot::slotted(*){\n scroll-snap-align: end;\n}\n@media (hover: hover){\n .carousel{\n overflow: hidden;\n }\n .carousel__button{\n opacity: 0.8;\n }\n :host(:hover) .carousel__button{\n opacity: 1;\n }\n .left,.right{\n display: none;\n }\n .indicators{\n transition: gap 0.3s;\n }\n .indicators:hover{\n gap: calc(var(--indicators-gap) * 2);\n }\n .indicators:hover .indicator{\n transform: scale(2);\n }\n}\n@media (hover: none){\n ::-webkit-scrollbar-track {\n -webkit-box-shadow: none !important;\n background-color: transparent !important;\n }\n ::-webkit-scrollbar {\n height: 0;\n background-color: transparent;\n }\n .carousel{\n overflow: auto none;\n }\n .carousel__button{\n display: none;\n }\n .left,.right{\n display: block;\n }\n}\n</style>\n<div class="carousel-container">\n <button class="carousel__button carousel__button--left hide">\n <svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M10.828 12l4.95 4.95-1.414 1.414L8 12l6.364-6.364 1.414 1.414z"/></svg>\n </button>\n <div part="carousel" class="carousel">\n <slot></slot>\n </div>\n <button class="carousel__button carousel__button--right hide">\n <svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M13.172 12l-4.95-4.95 1.414-1.414L16 12l-6.364 6.364-1.414-1.414z"/></svg>\n </button>\n <div class="indicators"></div>\n</div>\n',customElements.define("sm-carousel",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(smCarousel.content.cloneNode(!0)),this.isAutoPlaying=!1,this.autoPlayInterval=5e3,this.autoPlayTimeout,this.initialTimeout,this.activeSlideNum=0,this.carouselItems,this.indicators,this.showIndicator=!1,this.carousel=this.shadowRoot.querySelector(".carousel"),this.carouselContainer=this.shadowRoot.querySelector(".carousel-container"),this.carouselSlot=this.shadowRoot.querySelector("slot"),this.navButtonRight=this.shadowRoot.querySelector(".carousel__button--right"),this.navButtonLeft=this.shadowRoot.querySelector(".carousel__button--left"),this.indicatorsContainer=this.shadowRoot.querySelector(".indicators"),this.scrollLeft=this.scrollLeft.bind(this),this.scrollRight=this.scrollRight.bind(this),this.handleIndicatorClick=this.handleIndicatorClick.bind(this),this.showSlide=this.showSlide.bind(this),this.nextSlide=this.nextSlide.bind(this),this.autoPlay=this.autoPlay.bind(this),this.startAutoPlay=this.startAutoPlay.bind(this),this.stopAutoPlay=this.stopAutoPlay.bind(this)}static get observedAttributes(){return["indicator","autoplay","interval"]}scrollLeft(){this.carousel.scrollBy({left:-this.scrollDistance,behavior:"smooth"})}scrollRight(){this.carousel.scrollBy({left:this.scrollDistance,behavior:"smooth"})}showSlide(t){this.carousel.scrollTo({left:this.carouselItems[t].getBoundingClientRect().left-this.carousel.getBoundingClientRect().left+this.carousel.scrollLeft,behavior:"smooth"})}nextSlide(){if(!this.carouselItems)return;let t=this.activeSlideNum+1<this.carouselItems.length?this.activeSlideNum+1:0;this.showSlide(t)}autoPlay(){this.nextSlide(),this.isAutoPlaying&&(this.autoPlayTimeout=setTimeout(()=>{this.autoPlay()},this.autoPlayInterval))}startAutoPlay(){this.setAttribute("autoplay","")}stopAutoPlay(){this.removeAttribute("autoplay")}createIndicator(t){let n=document.createElement("div");return n.classList.add("indicator"),n.dataset.rank=t,n}handleIndicatorClick(t){if(t.target.closest(".indicator")){const n=parseInt(t.target.closest(".indicator").dataset.rank);this.activeSlideNum!==n&&this.showSlide(n)}}handleKeyDown(t){"ArrowLeft"===t.code?this.scrollRight():"ArrowRight"===t.code&&this.scrollRight()}connectedCallback(){let t=document.createDocumentFragment();this.carouselSlot.addEventListener("slotchange",n=>{this.carouselItems=this.carouselSlot.assignedElements(),this.carouselItems.forEach(t=>i.observe(t)),this.carouselItems.length>0?(o.observe(this.carouselItems[0]),e.observe(this.carouselItems[this.carouselItems.length-1])):(navButtonLeft.classList.add("hide"),navButtonRight.classList.add("hide"),o.disconnect(),e.disconnect()),this.showIndicator&&(this.indicatorsContainer.innerHTML="",this.carouselItems.forEach((n,i)=>{t.append(this.createIndicator(i)),n.dataset.rank=i}),this.indicatorsContainer.append(t),this.indicators=this.indicatorsContainer.children)});const n={threshold:.9,root:this},i=new IntersectionObserver(t=>{t.forEach(t=>{if(this.showIndicator){const n=parseInt(t.target.dataset.rank);t.isIntersecting?(this.indicators[n].classList.add("active"),this.activeSlideNum=n):this.indicators[n].classList.remove("active")}})},n),o=new IntersectionObserver(t=>{t.forEach(t=>{t.isIntersecting?this.navButtonLeft.classList.add("hide"):this.navButtonLeft.classList.remove("hide")})},n),e=new IntersectionObserver(t=>{t.forEach(t=>{t.isIntersecting?this.navButtonRight.classList.add("hide"):this.navButtonRight.classList.remove("hide")})},n),s=new ResizeObserver(t=>{t.forEach(t=>{if(t.contentBoxSize){const n=Array.isArray(t.contentBoxSize)?t.contentBoxSize[0]:t.contentBoxSize;this.scrollDistance=.6*n.inlineSize}else this.scrollDistance=.6*t.contentRect.width})});s.observe(this),this.addEventListener("keydown",this.handleKeyDown),this.navButtonRight.addEventListener("click",this.scrollRight),this.navButtonLeft.addEventListener("click",this.scrollLeft),this.indicatorsContainer.addEventListener("click",this.handleIndicatorClick)}attributeChangedCallback(t,n,i){n!==i&&("indicator"===t&&(this.showIndicator=this.hasAttribute("indicator")),"autoplay"===t&&(this.hasAttribute("autoplay")?this.initialTimeout=setTimeout(()=>{this.isAutoPlaying=!0,this.autoPlay()},this.autoPlayInterval):(this.isAutoPlaying=!1,clearTimeout(this.autoPlayTimeout),clearTimeout(this.initialTimeout))),"interval"===t&&(this.hasAttribute("interval")&&""!==this.getAttribute("interval").trim()?this.autoPlayInterval=Math.abs(parseInt(this.getAttribute("interval").trim())):this.autoPlayInterval=5e3))}disconnectedCallback(){this.navButtonRight.removeEventListener("click",this.scrollRight),this.navButtonLeft.removeEventListener("click",this.scrollLeft),this.indicatorsContainer.removeEventListener("click",this.handleIndicatorClick)}});