@haxtheweb/haxcms-nodejs
Version:
HAXcms single and multisite nodejs server, api, and administration
1 lines • 11 kB
JavaScript
const r=document.createElement("template");r.innerHTML='<style>*{box-sizing:border-box}:host{--fade-in-transition-duration:150ms;--fade-out-transition-duration:800ms;--fade-out-transition-delay:300ms;--fill-color-transition-duration:150ms;--viewport-overflow-x:auto;--viewport-overflow-y:auto;--viewport-scroll-snap-type:none;--viewport-scroll-behavior:auto;--viewport-overscroll-behavior:auto;--viewport-z-index:0;--scrollbar-width:16px;--scrollbar-padding:2px;--scrollbar-fill-color:transparent;--scrollbar-fill-color-hover:transparent;--scrollbar-border-width:0;--scrollbar-border-style:none;--scrollbar-border-color:#999;--scrollbar-border-radius:0;--scrollbar-box-shadow:none;--scrollbar-z-index-hover:30;--vertical-scrollbar-padding:var(--scrollbar-padding);--vertical-scrollbar-background:none;--vertical-scrollbar-background-size:auto;--vertical-scrollbar-z-index:20;--horizontal-scrollbar-padding:var(--scrollbar-padding);--horizontal-scrollbar-background:none;--horizontal-scrollbar-background-size:auto;--horizontal-scrollbar-z-index:10;--scrollbar-track-fill-color:transparent;--scrollbar-track-fill-color-hover:transparent;--scrollbar-track-border-width:0;--scrollbar-track-border-style:none;--scrollbar-track-border-color:#999;--scrollbar-track-border-radius:0;--scrollbar-track-box-shadow:none;--vertical-scrollbar-track-background:none;--vertical-scrollbar-track-background-size:auto;--horizontal-scrollbar-track-background:none;--horizontal-scrollbar-track-background-size:auto;--scrollbar-thumb-fill-color:#ccc;--scrollbar-thumb-fill-color-hover:#aaa;--scrollbar-thumb-border-width:0;--scrollbar-thumb-border-style:none;--scrollbar-thumb-border-color:#999;--scrollbar-thumb-border-radius:var(--scrollbar-width);--scrollbar-thumb-box-shadow:none;--vertical-scrollbar-thumb-background:none;--vertical-scrollbar-thumb-background-size:auto;--horizontal-scrollbar-thumb-background:none;--horizontal-scrollbar-thumb-background-size:auto;--content-padding:0;position:relative;overflow:hidden;display:grid;grid-template:1fr/1fr}.viewport{z-index:var(--viewport-z-index);display:grid;overflow-x:var(--viewport-overflow-x);overflow-y:var(--viewport-overflow-y);scrollbar-width:none;outline:0;scroll-behavior:var(--viewport-scroll-behavior);overscroll-behavior:var(--viewport-overscroll-behavior);scroll-snap-type:var(--viewport-scroll-snap-type)}.viewport::-webkit-scrollbar{width:0;height:0}.content{padding:var(--content-padding)}.content.restrict-width{width:var(--viewport-width)}.content.restrict-height{height:var(--viewport-height)}.scrollbar{user-select:none;touch-action:none;position:absolute;border-width:var(--scrollbar-border-width);border-style:var(--scrollbar-border-style);border-color:var(--scrollbar-border-color);border-radius:var(--scrollbar-border-radius);box-shadow:var(--scrollbar-box-shadow);opacity:0;transition:opacity var(--fade-out-transition-duration) ease-in-out var(--fade-out-transition-delay),background-color var(--fill-color-transition-duration) ease-out}.vertical-scrollbar{z-index:var(--vertical-scrollbar-z-index);width:var(--scrollbar-width);right:0;top:0;bottom:0;padding:var(--vertical-scrollbar-padding);background:var(--vertical-scrollbar-background);background-color:var(--scrollbar-fill-color);background-size:var(--vertical-scrollbar-background-size)}.vertical-scrollbar.left-position{left:0;right:auto}.horizontal-scrollbar{z-index:var(--horizontal-scrollbar-z-index);height:var(--scrollbar-width);left:0;right:0;bottom:0;padding:var(--horizontal-scrollbar-padding);background:var(--horizontal-scrollbar-background);background-color:var(--scrollbar-fill-color);background-size:var(--horizontal-scrollbar-background-size)}.horizontal-scrollbar.top-position{top:0;bottom:auto}.scrollbar:hover,.scrollbar.scrolling-with-thumb,.viewport:hover~.scrollbar,.viewport:not(:focus):focus-within~.scrollbar,.viewport.touch~.scrollbar{opacity:1;transition:opacity var(--fade-in-transition-duration) ease-in-out 0s,background-color var(--fill-color-transition-duration) ease-out}.viewport.scrollbar-visible~.scrollbar{opacity:1;transition:none}.scrollbar:hover,.scrollbar.scrolling-with-thumb{z-index:var(--scrollbar-z-index-hover);background-color:var(--scrollbar-fill-color-hover)}.scrollbar.hidden{display:none}.scrollbar .scrollbar-track{height:100%;width:100%;border-width:var(--scrollbar-track-border-width);border-style:var(--scrollbar-track-border-style);border-color:var(--scrollbar-track-border-color);border-radius:var(--scrollbar-track-border-radius);box-shadow:var(--scrollbar-track-box-shadow);transition:background-color var(--fill-color-transition-duration) ease-out}.vertical-scrollbar .scrollbar-track{background:var(--vertical-scrollbar-track-background);background-color:var(--scrollbar-track-fill-color);background-size:var(--vertical-scrollbar-track-background-size)}.horizontal-scrollbar .scrollbar-track{background:var(--horizontal-scrollbar-track-background);background-color:var(--scrollbar-track-fill-color);background-size:var(--horizontal-scrollbar-track-background-size)}.scrollbar-track:hover,.scrollbar.scrolling-with-thumb .scrollbar-track{background-color:var(--scrollbar-track-fill-color-hover)}.scrollbar .scrollbar-thumb{height:100%;width:100%;border-width:var(--scrollbar-thumb-border-width);border-style:var(--scrollbar-thumb-border-style);border-color:var(--scrollbar-thumb-border-color);border-radius:var(--scrollbar-thumb-border-radius);transform:translate3d(0,0,0);box-shadow:var(--scrollbar-thumb-box-shadow);transition:background-color var(--fill-color-transition-duration) ease-out}.vertical-scrollbar .scrollbar-thumb{background:var(--vertical-scrollbar-thumb-background);background-color:var(--scrollbar-thumb-fill-color);background-size:var(--vertical-scrollbar-thumb-background-size)}.horizontal-scrollbar .scrollbar-thumb{background:var(--horizontal-scrollbar-thumb-background);background-color:var(--scrollbar-thumb-fill-color);background-size:var(--horizontal-scrollbar-thumb-background-size)}.scrollbar .scrollbar-thumb:hover,.scrollbar.scrolling-with-thumb .scrollbar-thumb{background-color:var(--scrollbar-thumb-fill-color-hover)}</style><div class="viewport" tabindex="-1"><div class="content"><slot></slot></div></div><div class="scrollbar vertical-scrollbar hidden"><div class="scrollbar-track"><div class="scrollbar-thumb"></div></div></div><div class="scrollbar horizontal-scrollbar hidden"><div class="scrollbar-track"><div class="scrollbar-thumb"></div></div></div>';const o=Symbol("vertical"),l=Symbol("horizontal"),a=[{key:o,name:"vertical",size:"height",o:"offsetHeight",l:"scrollHeight",position:"top",t:"scrollTop",i:"overflow-y",h:"clientY",v:"pageY"},{key:l,name:"horizontal",size:"width",o:"offsetWidth",l:"scrollWidth",position:"left",t:"scrollLeft",i:"overflow-x",h:"clientX",v:"pageX"}];export class ScrollableComponentElement extends HTMLElement{constructor(){super(),this.u(),this.p(),this.g()}static get observedAttributes(){return["scrollbar-visibility","vertical-scrollbar-position","horizontal-scrollbar-position"]}connectedCallback(){this.k(),this.m(),this.S()}attributeChangedCallback(r,a,e){"scrollbar-visibility"===r?this.viewport.classList.toggle("scrollbar-visible","always"===e):"vertical-scrollbar-position"===r?this.elements[o].C.classList.toggle("left-position","left"===e):"horizontal-scrollbar-position"===r&&this.elements[l].C.classList.toggle("top-position","top"===e)}u(){this.viewport,this.content,this.elements={},this.cache={},this.T={},this.$=null;for(let r of a)this.elements[r.key]={C:null,W:null,T:null},this.cache[r.key]={A:!1,F:!1,M:0,O:0,P:1},this.T[r.key]={q:!0,L:1,R:{v:0,t:0}}}p(){this.attachShadow({mode:"open"}),this.shadowRoot.appendChild(r.content.cloneNode(!0)),this.viewport=this.shadowRoot.querySelector(".viewport"),this.content=this.viewport.querySelector(".content");for(let r of a){const o=this.elements[r.key];o.C=this.shadowRoot.querySelector(`.${r.name}-scrollbar`),o.W=o.C.querySelector(".scrollbar-track"),o.T=o.W.querySelector(".scrollbar-thumb")}}g(){const r=new ResizeObserver((()=>{this.H()}));r.observe(this.viewport),r.observe(this.content);for(let o of a){const l=this.elements[o.key];r.observe(l.W),l.W.addEventListener("pointerdown",(r=>{r.preventDefault(),r.stopPropagation(),this.D(o,r)}));const t=r=>{this.X(o,r)};l.T.addEventListener("pointerdown",(r=>{r.preventDefault(),r.stopPropagation(),l.T.addEventListener("pointermove",t,{passive:!0}),l.T.setPointerCapture(r.pointerId),this.Y(o,r)})),l.T.addEventListener("pointerup",(r=>{l.T.removeEventListener("pointermove",t,{passive:!0}),l.T.releasePointerCapture(r.pointerId),this.j(o)}),{passive:!0})}this.viewport.addEventListener("scroll",(()=>{this.B()}),{passive:!0}),this.viewport.addEventListener("touchstart",(()=>{this.G()}),{passive:!0}),this.viewport.addEventListener("touchend",(()=>{this.I()}),{passive:!0})}D(r,o){const l=this.elements[r.key],a=this.cache[r.key],e=l.W.getBoundingClientRect(),i=l.T.getBoundingClientRect(),s=o[r.h]-e[r.position]-i[r.size]/2,c=a.O/e[r.size],n=s/a.P*c;requestAnimationFrame((()=>{this.viewport.scrollTo({[r.position]:n,behavior:"smooth"}),this.viewport.focus({preventScroll:!0})}))}Y(r,o){const l=this.elements[r.key],a=this.T[r.key],e=l.W.getBoundingClientRect();a.q=!0,a.L=this.cache[r.key].O/e[r.size],a.R.v=o.touches?o.touches[0][r.v]:o[r.v],a.R.t=this.viewport[r.t],requestAnimationFrame((()=>{this.viewport.classList.add(`scrolling-with-${r.name}-thumb`),l.C.classList.add("scrolling-with-thumb"),this.viewport.focus({preventScroll:!0})}))}X(r,o){const l=this.T[r.key];if(l.q){const a=((o.touches?o.touches[0][r.v]:o[r.v])-l.R.v)/this.cache[r.key].P*l.L,e=l.R.t+a;this.viewport[r.t]=e}}j(r){const o=this.T[r.key];o.q&&(o.q=!1,this.viewport.classList.remove(`scrolling-with-${r.name}-thumb`),this.elements[r.key].C.classList.remove("scrolling-with-thumb"))}G(){this.viewport.classList.add("touch")}I(){this.viewport.classList.remove("touch")}B(){null===this.$&&(this.$=requestAnimationFrame((()=>{this.S(),this.$=null})))}H(){this.k(),null===this.$&&(this.$=requestAnimationFrame((()=>{this.m(),this.S(),this.$=null})))}k(){const r=getComputedStyle(this.viewport);for(let o of a){const l=this.cache[o.key];l.F="hidden"===r.getPropertyValue(o.i).trim(),l.M=Math.floor(10*this.viewport[o.o])/10,l.O=Math.floor(10*this.elements[o.key].W[o.o])/10,l.P=l.O/this.viewport[o.l],l.A=!l.F&&this.viewport[o.l]>Math.ceil(l.M)}}m(){for(let r of a){const o=this.elements[r.key],l=this.cache[r.key];if(this.shadowRoot.host.style.setProperty(`--viewport-${r.size}`,`${l.M}px`),this.content.classList.toggle(`restrict-${r.size}`,l.F),o.C.classList.toggle("hidden",!l.A),l.A){const a=l.M*l.P;o.T.style[r.size]=`${a}px`}}}S(){for(let r of a){const l=this.cache[r.key];if(l.A){const a=this.viewport[r.t]*l.P;this.elements[r.key].T.style.transform=r.key===o?`translate3D(0, ${a}px, 0)`:`translate3D(${a}px, 0, 0)`}}}}window.customElements.define("scrollable-component",ScrollableComponentElement);