about
Hideable PhotoSizer
04/24/2024
Hide-able PhotoSizer Element
Implements W3C/Google webcomponent
This is how this page uses the Hideable PhotoSizer Element:
<hidephotosizer-block src="Pictures/ThreadPool.JPG" width="200" class="photoSizerBlock left"> <span style="font-family:'Comic Sans MS';">Figure 1. ThreadPool</span> </photosizer-block>And this is how this pages styles the PhotoSizer Element:
#github hidephotosizer-block { --border:1px solid black; --box-shadow: 3px 3px 5px #999; --wrapperPadding: 5px 10px 10px 10px; --margin: 20px; --captionPadding: 0px 0px 5px 0px; } /* uncomment .photoBlock to use this class */ /*#github .photoSizerBlock { --background-color: #efe; --font-family:Comic Sans MS; --font-weight: Bold; --border: 3px solid darkgreen; --captionPadding: 0px 0px 5px 0px; --wrapperPadding: 5px; --margin: 30px; }*/View page source for all the details.
<script> /* custom webcomponent - PhotoSizerBlock*/ class PhotoSizerBlock extends HTMLElement { constructor(...args) { const self = super(...args); const shadowRoot = this.attachShadow({ mode: 'open' }); shadowRoot.innerHTML = ` <style> #cont { display:flex; padding: var(--padding); } #wrapper { width:min-content; padding: var(--wrapperPadding); //10px; margin: var(--margin); //20px; background-color: var(--background-color); color: var(--color); box-shadow: var(--box-shadow); font-family: var(--font-family); font-size: var(--font-size); font-weight: var(--font-weight); border: var(--border); cursor: pointer; user-select:none; -webkit-user-select:none; -moz-user-select:none; -ms-user-select:none; } #closer { text-align:center; font-family:'Comic Sans MS', Sans-serif; } #caption { text-align:center; padding-bottom:10px; padding: var(--captionPadding); //0px 0px 10px 0px; background-color:white; } img { user-select:none; -webkit-user-select:none; -moz-user-select:none; -ms-user-select:none; } </style> <div id="cont"> <slot></slot> <div id="wrapper"> <div id="caption"></div> <img /> <div id="closer">click to close</div> </div> </div> `; this.bigger = this.bigger.bind(this); this.smaller = this.smaller.bind(this); this.toggle = this.toggle.bind(this); return self; } connectedCallback() { this.url = this.getAttribute('src'); this.imgElem = this.shadowRoot.querySelector('img'); this.imgElem.setAttribute('src', this.url); this.width = this.getAttribute('width'); if (isDefined(this.width)) this.imgElem.setAttribute('width', this.width); this.height = this.getAttribute('height'); if (isDefined(this.height)) this.imgElem.setAttribute(this.height); this.caption = this.shadowRoot.querySelector('#caption'); if (isDefined(this.caption)) { this.captionText = this.innerHTML; this.innerHTML = ""; this.caption.innerHTML = this.captionText; } this.imgElem.addEventListener('click', this.bigger); this.caption.addEventListener('click', this.smaller); this.closer = this.shadowRoot.querySelector('#closer'); this.closer.addEventListener('click', this.toggle); } bigger() { this.imgElem.width = Number(this.imgElem.width) * 1.25; } smaller() { this.imgElem.width = Number(this.imgElem.width) / 1.25; } toggle() { let wrpr = this.shadowRoot.getElementById("wrapper"); if (isDefined(wrpr)) { if (wrpr.style.display === "none") { wrpr.style.display = "block"; this.closer.style.right = "8px"; } else { wrpr.style.display = "none"; this.closer.style.right = "7px"; } } } } /* register with DOM - don't need to use script block to execute */ /*--------------------------------------------------------------------------- * This listener is added because of a component lifecycle issue with chrome * See first reference, below. */ document.addEventListener('DOMContentLoaded', function () { window.customElements.define('photosizer-block', PhotoSizerBlock); }); /* * The listener, above, will be removed and replaced with this when chrome * component lifecycle is fixed. * * window.customElements.define('photosizer-block', PhotoSizerBlock); */ </script>
References:
- Issue with Chrome loading innerHTML
- polyfills CDN
- customelements - google.com
- shadowdom - google.com
- webcomponents - htm5rocks.com
- attributes & properties - alligator.io
- styling webcomponent - css-tricks.com
- encapsulating style and structure - css-tricks.com
- creating custom component from scratch - css-tricks.com
- Using custom elements - mozilla.org
- introduction to webcomponents - webcomponents.org
- build web components - dev.to
- tutorial - robinwieruch.de
- introduction - grapecity.com