@dkvz/img-lightbox 0.2.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -9,6 +9,8 @@ I quickly made this in regard to a blog article I was writing, it could be impro
9
9
 
10
10
  Uncompressed minified size: 8.5Kb including the loading spinner image.
11
11
 
12
+ **Note**: we no longer minify the build - It seems to be standard practice for libraries nowadays.
13
+
12
14
  ## Using the component from npm
13
15
  To use it in a project with a module bundler, install the dependency first:
14
16
  ```
@@ -44,6 +46,22 @@ img-lightbox:active, img-lightbox:focus {
44
46
  }
45
47
  ```
46
48
 
49
+ You also may have strange spacing issues if the a and img elements have their default "inline" display mode. Which could be changed like so:
50
+ ```css
51
+ img-lightbox a, img-lightbox img {
52
+ display: block;
53
+ }
54
+ ```
55
+
56
+ This is also where you should set any max-width or max-height. Or you could set it on img-lightbox itself but then you need to set width and height to 100% as in:
57
+ ```css
58
+ img-lightbox a, img-lightbox img {
59
+ display: block;
60
+ width: 100%;
61
+ height: 100%;
62
+ }
63
+ ```
64
+
47
65
  ## Building the component
48
66
 
49
67
  ### Build requirements
@@ -62,11 +80,6 @@ Build using either:
62
80
  ```
63
81
  npm run build
64
82
  ```
65
- For the shadow DOM (default) version and:
66
- ```
67
- npm run build-no-shadow
68
- ```
69
- For the version that does not use the shadow DOM API at all.
70
83
 
71
84
  You'll find the build script in the `dist` folder.
72
85
 
@@ -77,8 +90,20 @@ To manually use it in some page, you could do something like this:
77
90
  customElements.define('img-lightbox', ImgLightbox.default);
78
91
  </script>
79
92
  ```
93
+ **Update 2025**: There is a .mjs file built as well and it might be a good idea to use that one (with `type="module" in the script tag`).
94
+
80
95
  The loading icon SVG file is normally not necessary but since I change my mind all the time about it you might want to copy it along anyway.
81
96
 
97
+ ## Build without shadow DOM
98
+ In the past I had a way to build the component without using the shadow DOM at all, which has a few consequences but I think the main idea was to support some old browsers.
99
+
100
+ Anyway, after upgrading Parcel to v2 I didn't take time to fix the build command for the no-shadow DOM version.
101
+
102
+ It used to be:
103
+ ```
104
+ npm run build-no-shadow
105
+ ```
106
+
82
107
  The no-shadow DOM version also requires extra styles to work. See `src/no-shadow/index.pug`.
83
108
 
84
109
  ## Remarks
@@ -122,12 +147,27 @@ if (event.altKey)
122
147
  ## Resources and copyright notices
123
148
  - The hourglass icon has been modified from the GPL-licensed file here: https://fr.wikipedia.org/wiki/Fichier:Circle-icons-hourglass.svg
124
149
 
150
+ ## Upgrade to parcel 2
151
+ The doc: https://parceljs.org/migration/parcel-1/
152
+
153
+ I removed all of these deps:
154
+ ```
155
+ "parcel-bundler": "^1.12.4",
156
+ "parcel-plugin-clean-dist": "0.0.6",
157
+ "parcel-plugin-url-loader": "^1.3.1",
158
+ ```
159
+
160
+ Then added the latest parcel through npm install.
161
+
162
+ I need to add a manual wipe of the dist folder before the build commands, doing a quick rimraf for now.
163
+
164
+ I also had to change how the loading SVG gets inlined. It's now imported as a string.
165
+
125
166
  ## TODO
126
167
  - [ ] Test on all browsers
127
168
  - [ ] Write tests - Probably going to need jsdom
128
169
  - [x] Don't forget to register the keyboard events
129
170
  - [x] Use template tags, they say it's better (here)[https://github.com/GoogleChromeLabs/howto-components/blob/master/elements/howto-checkbox/howto-checkbox.js]
130
- - [ ] Document how to check for web component browser support
131
171
  - [x] Disable overflow on the fullscreen overlay
132
172
  - [x] Make a shadow DOM version
133
173
  - [x] To maximize accessibility we need some kind of focus outline
@@ -1,6 +1,198 @@
1
- parcelRequire=function(e,r,t,n){var i,o="function"==typeof parcelRequire&&parcelRequire,u="function"==typeof require&&require;function f(t,n){if(!r[t]){if(!e[t]){var i="function"==typeof parcelRequire&&parcelRequire;if(!n&&i)return i(t,!0);if(o)return o(t,!0);if(u&&"string"==typeof t)return u(t);var c=new Error("Cannot find module '"+t+"'");throw c.code="MODULE_NOT_FOUND",c}p.resolve=function(r){return e[t][1][r]||r},p.cache={};var l=r[t]=new f.Module(t);e[t][0].call(l.exports,p,l,l.exports,this)}return r[t].exports;function p(e){return f(p.resolve(e))}}f.isParcelRequire=!0,f.Module=function(e){this.id=e,this.bundle=f,this.exports={}},f.modules=e,f.cache=r,f.parent=o,f.register=function(r,t){e[r]=[function(e,r){r.exports=t},{}]};for(var c=0;c<t.length;c++)try{f(t[c])}catch(e){i||(i=e)}if(t.length){var l=f(t[t.length-1]);"object"==typeof exports&&"undefined"!=typeof module?module.exports=l:"function"==typeof define&&define.amd?define(function(){return l}):n&&(this[n]=l)}if(parcelRequire=f,i)throw i;return f}({"q71P":[function(require,module,exports) {
2
- module.exports="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCA2NCA2NCIgdmVyc2lvbj0iMS4xIiB2aWV3Qm94PSIwIDAgNjQgNjQiIHhtbDpzcGFjZT0icHJlc2VydmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6Y2M9Imh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL25zIyIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPjxtZXRhZGF0YT48cmRmOlJERj48Y2M6V29yayByZGY6YWJvdXQ9IiI+PGRjOmZvcm1hdD5pbWFnZS9zdmcreG1sPC9kYzpmb3JtYXQ+PGRjOnR5cGUgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIvPjxkYzp0aXRsZS8+PC9jYzpXb3JrPjwvcmRmOlJERj48L21ldGFkYXRhPgo8Zz4KCQk8Y2lyY2xlIGNsYXNzPSJzdDAiIGN4PSIzMiIgY3k9IjMyIiByPSIzMiIvPgoJPC9nPjxnIGNsYXNzPSJzdDEiIG9wYWNpdHk9Ii4yIj4KCQk8cGF0aCBjbGFzcz0ic3QyIiBkPSJtNDYgNTBoLTJ2LTRjMC00LjUtMy03LjQtMy03LjRzLTMtMi44LTMuOS0zLjcgMC0xLjggMC0xLjggMS4zLTEuMyA0LjItNGMyLjgtMi43IDIuNy02LjcgMi43LTYuN3YtNS4xbC0xMi0xLTEyIDF2NS4xcy0wLjEgMy45IDIuNyA2LjdjMi44IDIuNyA0LjIgNCA0LjIgNHMwLjkgMC45IDAgMS44LTMuOSAzLjctMy45IDMuNy0zIDIuOC0zIDcuNHY0aC0yYy0xLjEgMC0yIDAuOS0yIDJzMC45IDIgMiAyaDI4YzEuMSAwIDItMC45IDItMnMtMC45LTItMi0yeiIgZmlsbD0iIzIzMWYyMCIvPgoJPC9nPgoJCTxwYXRoIGNsYXNzPSJzdDMiIGQ9Im00MSAzNi42cy0zLTIuOC0zLjktMy43IDAtMS44IDAtMS44IDEuMy0xLjMgNC4yLTRjMi44LTIuNyAyLjctNi43IDIuNy02Ljd2LTUuMWwtMTItMS0xMiAxdjUuMXMtMC4xIDMuOSAyLjcgNi43YzIuOCAyLjcgNC4yIDQgNC4yIDRzMC45IDAuOSAwIDEuOC0zLjkgMy43LTMuOSAzLjctMyAyLjgtMyA3LjR2NS4xaDI0di01LjFjMC00LjUtMy03LjQtMy03LjR6IiBmaWxsPSIjZmZmIi8+CgkKCQk8cGF0aCBjbGFzcz0ic3Q0IiBkPSJtMzEgNDN2LTExYzAtMi4xLTEtMy40LTEuMy0zLjdsLTQuMi00Yy0xLjUtMS40LTEuNS0zLjctMS41LTMuN2gxNnMwIDIuMy0xLjUgMy43bC00LjIgNGMtMC40IDAuMy0xLjMgMS42LTEuMyAzLjd2MTF6Ii8+Cgk8ZyBjbGFzcz0ic3Q1IiBvcGFjaXR5PSIuMyI+CgkJPHBhdGggY2xhc3M9InN0MiIgZD0ibTQ4IDE2YzAgMS4xLTAuOSAyLTIgMmgtMjhjLTEuMSAwLTItMC45LTItMnMwLjktMiAyLTJoMjhjMS4xIDAgMiAwLjkgMiAyeiIgZmlsbD0iIzIzMWYyMCIvPgoJPC9nPjxnIGZpbGw9IiNmZmYiPgoJCTxwYXRoIGNsYXNzPSJzdDYiIGQ9Im00OCAxNGMwIDEuMS0wLjkgMi0yIDJoLTI4Yy0xLjEgMC0yLTAuOS0yLTJzMC45LTIgMi0yaDI4YzEuMSAwIDIgMC45IDIgMnoiIGZpbGw9IiNmZmYiLz4KCTwvZz48ZyBmaWxsPSIjZmZmIj4KCQk8cGF0aCBjbGFzcz0ic3Q2IiBkPSJtNDggNTBjMCAxLjEtMC45IDItMiAyaC0yOGMtMS4xIDAtMi0wLjktMi0yczAuOS0yIDItMmgyOGMxLjEgMCAyIDAuOSAyIDJ6IiBmaWxsPSIjZmZmIi8+Cgk8L2c+PGc+CgkJPHBvbHlnb24gY2xhc3M9InN0NCIgcG9pbnRzPSIyMyA0OCAyMyA0OCAzMiA0MCA0MSA0OCIvPgoJPC9nPgoKPC9zdmc+Cg==";
3
- },{}],"wPYj":[function(require,module,exports) {
4
- "use strict";function t(e){return(t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(e)}function e(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function n(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}function o(t,e,o){return e&&n(t.prototype,e),o&&n(t,o),t}function r(e,n){return!n||"object"!==t(n)&&"function"!=typeof n?i(e):n}function i(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}function a(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),e&&f(t,e)}function l(t){var e="function"==typeof Map?new Map:void 0;return(l=function(t){if(null===t||!c(t))return t;if("function"!=typeof t)throw new TypeError("Super expression must either be null or a function");if(void 0!==e){if(e.has(t))return e.get(t);e.set(t,n)}function n(){return u(t,arguments,h(this).constructor)}return n.prototype=Object.create(t.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),f(n,t)})(t)}function s(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch(t){return!1}}function u(t,e,n){return(u=s()?Reflect.construct:function(t,e,n){var o=[null];o.push.apply(o,e);var r=new(Function.bind.apply(t,o));return n&&f(r,n.prototype),r}).apply(null,arguments)}function c(t){return-1!==Function.toString.call(t).indexOf("[native code]")}function f(t,e){return(f=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t})(t,e)}function h(t){return(h=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)})(t)}Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=void 0;var d=require("../../assets/hourglass.svg"),y=function(t){function n(){var t;return e(this,n),(t=r(this,h(n).call(this))).loading=!1,t.attachShadow({mode:"open"}),t}return a(n,l(HTMLElement)),o(n,[{key:"connectedCallback",value:function(){this.shadowRoot.appendChild(this.template.content.cloneNode(!0)),this.overlay=this.shadowRoot.querySelector("#overlay"),this.loadingOverlay=this.shadowRoot.querySelector("#loader"),this.tabIndex=0;var t=this.querySelector("a"),e=this.querySelector("img");t?(this.fullImage=t.getAttribute("href"),t.tabIndex=-1):e&&(this.fullImage=e.getAttribute("src")),this.fullImage&&this._addListeners()}},{key:"_addListeners",value:function(){var t=this;this.addEventListener("click",this.showLightbox.bind(this),!0),this.addEventListener("keydown",function(e){if(!e.altKey)switch(e.keyCode){case 13:case 32:t.showLightbox(e);default:return}},!0)}},{key:"showLightbox",value:function(t){var e=this;t.preventDefault(),this.loading||(this.loading=!0,this._showOverlay(this.loadingOverlay),this.img?this.showImage():(this.img=document.createElement("img"),this.img.addEventListener("load",function(){return e.showImage()}),this.img.src=this.fullImage,this.img.tabIndex=1,["click","keydown"].forEach(function(t){return e.overlay.addEventListener(t,function(t){return e._hideOverlay(t.currentTarget)})}),this.overlay.appendChild(this.img)))}},{key:"showImage",value:function(){this.img.style.transform="scale(0.1)",this._hideOverlay(this.loadingOverlay),this._showOverlay(this.overlay),this.overlay.focus(),this.img.style.transform="scale(1)",this.loading=!1}},{key:"_showOverlay",value:function(t){t.style.display="flex"}},{key:"_hideOverlay",value:function(t){t.style.display=""}}]),n}(),p=document.createElement("template");p.innerHTML='\n<style>\n :host {\n display: inline-block;\n cursor: pointer;\n position: relative;\n }\n\n :host([hidden]) {\n display: none;\n }\n\n :host(:focus), :host(:active) {\n outline: 2px solid #77b;\n }\n\n #loader {\n position: absolute;\n z-index: 1;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background-color: rgba(0,0,0,.2);\n display: none;\n align-items: center;\n justify-content: center;\n }\n\n #overlay {\n position: fixed;\n top: 0;\n left: 0;\n bottom: 0;\n right: 0;\n overflow: hidden;\n z-index: 999;\n background-color: rgba(0,0,0,.5);\n display: none;\n align-items: center;\n justify-content: center;\n }\n\n #loader img {\n width: 50%;\n opacity: 0.6;\n animation: lightbox-loader 2s infinite;\n }\n\n #overlay img {\n max-width: 100%;\n max-height: 100%;\n transition: transform 0.8s;\n }\n\n @keyframes lightbox-loader {\n 0% {transform: rotate(0deg);}\n 100% {transform: rotate(360deg);}\n }\n</style>\n<slot></slot>\n<div id="overlay" tabindex="0"></div>\n<div id="loader">\n <img src="'.concat(d,'">\n</div>\n'),y.prototype.template=p;var g=y;exports.default=g;
5
- },{"../../assets/hourglass.svg":"q71P"}]},{},["wPYj"], "ImgLightbox")
6
- //# sourceMappingURL=img-lightbox.js.map
1
+
2
+ function $parcel$interopDefault(a) {
3
+ return a && a.__esModule ? a.default : a;
4
+ }
5
+
6
+ function $parcel$defineInteropFlag(a) {
7
+ Object.defineProperty(a, '__esModule', {value: true, configurable: true});
8
+ }
9
+
10
+ function $parcel$export(e, n, v, s) {
11
+ Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
12
+ }
13
+
14
+ $parcel$defineInteropFlag(module.exports);
15
+
16
+ $parcel$export(module.exports, "default", () => $a6ba83244539002c$export$2e2bcd8739ae039);
17
+ // const loaderSvgUrl = require('../../assets/hourglass.svg');
18
+ var $735957c3b581425f$exports = {};
19
+ $735957c3b581425f$exports = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:cc=\"http://creativecommons.org/ns#\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" enable-background=\"new 0 0 64 64\" version=\"1.1\" viewBox=\"0 0 64 64\" xml:space=\"preserve\"><metadata><rdf:RDF><cc:Work rdf:about=\"\"><dc:format>image/svg+xml</dc:format><dc:type rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\"/><dc:title/></cc:Work></rdf:RDF></metadata>\n<g>\n\t\t<circle class=\"st0\" cx=\"32\" cy=\"32\" r=\"32\"/>\n\t</g><g class=\"st1\" opacity=\".2\">\n\t\t<path class=\"st2\" d=\"m46 50h-2v-4c0-4.5-3-7.4-3-7.4s-3-2.8-3.9-3.7 0-1.8 0-1.8 1.3-1.3 4.2-4c2.8-2.7 2.7-6.7 2.7-6.7v-5.1l-12-1-12 1v5.1s-0.1 3.9 2.7 6.7c2.8 2.7 4.2 4 4.2 4s0.9 0.9 0 1.8-3.9 3.7-3.9 3.7-3 2.8-3 7.4v4h-2c-1.1 0-2 0.9-2 2s0.9 2 2 2h28c1.1 0 2-0.9 2-2s-0.9-2-2-2z\" fill=\"#231f20\"/>\n\t</g>\n\t\t<path class=\"st3\" d=\"m41 36.6s-3-2.8-3.9-3.7 0-1.8 0-1.8 1.3-1.3 4.2-4c2.8-2.7 2.7-6.7 2.7-6.7v-5.1l-12-1-12 1v5.1s-0.1 3.9 2.7 6.7c2.8 2.7 4.2 4 4.2 4s0.9 0.9 0 1.8-3.9 3.7-3.9 3.7-3 2.8-3 7.4v5.1h24v-5.1c0-4.5-3-7.4-3-7.4z\" fill=\"#fff\"/>\n\t\n\t\t<path class=\"st4\" d=\"m31 43v-11c0-2.1-1-3.4-1.3-3.7l-4.2-4c-1.5-1.4-1.5-3.7-1.5-3.7h16s0 2.3-1.5 3.7l-4.2 4c-0.4 0.3-1.3 1.6-1.3 3.7v11z\"/>\n\t<g class=\"st5\" opacity=\".3\">\n\t\t<path class=\"st2\" d=\"m48 16c0 1.1-0.9 2-2 2h-28c-1.1 0-2-0.9-2-2s0.9-2 2-2h28c1.1 0 2 0.9 2 2z\" fill=\"#231f20\"/>\n\t</g><g fill=\"#fff\">\n\t\t<path class=\"st6\" d=\"m48 14c0 1.1-0.9 2-2 2h-28c-1.1 0-2-0.9-2-2s0.9-2 2-2h28c1.1 0 2 0.9 2 2z\" fill=\"#fff\"/>\n\t</g><g fill=\"#fff\">\n\t\t<path class=\"st6\" d=\"m48 50c0 1.1-0.9 2-2 2h-28c-1.1 0-2-0.9-2-2s0.9-2 2-2h28c1.1 0 2 0.9 2 2z\" fill=\"#fff\"/>\n\t</g><g>\n\t\t<polygon class=\"st4\" points=\"23 48 23 48 32 40 41 48\"/>\n\t</g>\n\n</svg>";
20
+
21
+
22
+ class $a6ba83244539002c$var$ImgLightbox extends HTMLElement {
23
+ constructor(){
24
+ super();
25
+ this.loading = false;
26
+ this.attachShadow({
27
+ mode: 'open'
28
+ });
29
+ }
30
+ connectedCallback() {
31
+ // Template is added to prototype below the
32
+ // class definition.
33
+ // It's from a template tag because it's
34
+ // supposed to be faster this way.
35
+ this.shadowRoot.appendChild(this.template.content.cloneNode(true));
36
+ // Get some element references from shadow DOM:
37
+ this.overlay = this.shadowRoot.querySelector('#overlay');
38
+ this.loadingOverlay = this.shadowRoot.querySelector('#loader');
39
+ // Add the loading SVG to that element:
40
+ this.loadingOverlay.innerHTML = (0, (/*@__PURE__*/$parcel$interopDefault($735957c3b581425f$exports)));
41
+ // Component needs a tabIndex to be focusable.
42
+ this.tabIndex = 0;
43
+ // The slotted elements are actually not in
44
+ // the shadow DOM so we can get them like so:
45
+ const link = this.querySelector('a');
46
+ const img = this.querySelector('img');
47
+ if (link) {
48
+ // Store the URL as the full image URL:
49
+ this.fullImage = link.getAttribute('href');
50
+ // Register a click event that has to
51
+ // prevent default:
52
+ //this._addListeners(link);
53
+ // Prevent ability to focus the link:
54
+ link.tabIndex = -1;
55
+ } else if (img) this.fullImage = img.getAttribute('src');
56
+ this.fullImage && this._addListeners();
57
+ }
58
+ _addListeners() {
59
+ this.addEventListener('click', this.showLightbox.bind(this), true);
60
+ this.addEventListener('keydown', (e)=>{
61
+ // It's common to ignore anything with alt
62
+ // modifiers. I've copied this from Google
63
+ // people.
64
+ if (e.altKey) return;
65
+ // Catch enter and space:
66
+ switch(e.keyCode){
67
+ case 13:
68
+ case 32:
69
+ this.showLightbox(e);
70
+ default:
71
+ return;
72
+ }
73
+ }, true);
74
+ }
75
+ showLightbox(e) {
76
+ // This is required so that the link element does not get
77
+ // followed:
78
+ e.preventDefault();
79
+ // Implement some kind of lock:
80
+ if (!this.loading) {
81
+ this.loading = true;
82
+ // Preload the full image.
83
+ // Show the spinner overlay:
84
+ this._showOverlay(this.loadingOverlay);
85
+ if (!this.img) {
86
+ this.img = document.createElement('img');
87
+ this.img.addEventListener('load', ()=>this.showImage());
88
+ this.img.src = this.fullImage;
89
+ this.img.tabIndex = 1;
90
+ // Prepare the events to close the overlay.
91
+ // I'm doing this here to light up what's
92
+ // happening in connectedCallback.
93
+ // I'm not doing a check for which key was
94
+ // called on purpose, but maybe I should do
95
+ // that alt key check?
96
+ [
97
+ 'click',
98
+ 'keydown'
99
+ ].forEach((type)=>this.overlay.addEventListener(type, (e)=>this._hideOverlay(e.currentTarget)));
100
+ this.overlay.appendChild(this.img);
101
+ } else this.showImage();
102
+ }
103
+ }
104
+ showImage() {
105
+ this.img.style.transform = 'scale(0.1)';
106
+ // Hide the loading overlay:
107
+ this._hideOverlay(this.loadingOverlay);
108
+ this._showOverlay(this.overlay);
109
+ // Focus the overlay (requires it to have a tabIndex):
110
+ this.overlay.focus();
111
+ // Start the CSS transition:
112
+ this.img.style.transform = 'scale(1)';
113
+ // Don't forget to unlock the click event:
114
+ this.loading = false;
115
+ }
116
+ _showOverlay(overlay) {
117
+ overlay.style.display = 'flex';
118
+ }
119
+ _hideOverlay(overlay) {
120
+ overlay.style.display = '';
121
+ }
122
+ }
123
+ // I'm using a true template tag because the Chrome
124
+ // team says it's faster. The template tag has
125
+ // better browser support than web components anyway.
126
+ // The strange comment here is needed for syntax
127
+ // highlighting with a VS Code extension I'm using.
128
+ const $a6ba83244539002c$var$tpl = document.createElement('template');
129
+ $a6ba83244539002c$var$tpl.innerHTML = /*template*/ `
130
+ <style>
131
+ :host {
132
+ display: inline-block;
133
+ cursor: pointer;
134
+ position: relative;
135
+ }
136
+
137
+ :host([hidden]) {
138
+ display: none;
139
+ }
140
+
141
+ :host(:focus), :host(:active) {
142
+ outline: 2px solid #77b;
143
+ }
144
+
145
+ #loader {
146
+ position: absolute;
147
+ z-index: 1;
148
+ top: 0;
149
+ left: 0;
150
+ width: 100%;
151
+ height: 100%;
152
+ background-color: rgba(0,0,0,.2);
153
+ display: none;
154
+ align-items: center;
155
+ justify-content: center;
156
+ }
157
+
158
+ #overlay {
159
+ position: fixed;
160
+ top: 0;
161
+ left: 0;
162
+ bottom: 0;
163
+ right: 0;
164
+ overflow: hidden;
165
+ z-index: 999;
166
+ background-color: rgba(0,0,0,.5);
167
+ display: none;
168
+ align-items: center;
169
+ justify-content: center;
170
+ }
171
+
172
+ #loader img {
173
+ width: 50%;
174
+ opacity: 0.6;
175
+ animation: lightbox-loader 2s infinite;
176
+ }
177
+
178
+ #overlay img {
179
+ max-width: 100%;
180
+ max-height: 100%;
181
+ transition: transform 0.8s;
182
+ }
183
+
184
+ @keyframes lightbox-loader {
185
+ 0% {transform: rotate(0deg);}
186
+ 100% {transform: rotate(360deg);}
187
+ }
188
+ </style>
189
+ <slot></slot>
190
+ <div id="overlay" tabindex="0"></div>
191
+ <div id="loader">
192
+ </div>
193
+ `;
194
+ $a6ba83244539002c$var$ImgLightbox.prototype.template = $a6ba83244539002c$var$tpl;
195
+ var $a6ba83244539002c$export$2e2bcd8739ae039 = $a6ba83244539002c$var$ImgLightbox;
196
+
197
+
198
+ //# sourceMappingURL=img-lightbox.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["img-lightbox.js"],"names":["ImgLightbox","loaderSvgUrl","require","loading","attachShadow","mode","HTMLElement","shadowRoot","appendChild","template","content","cloneNode","overlay","querySelector","loadingOverlay","tabIndex","link","img","fullImage","getAttribute","_addListeners","addEventListener","showLightbox","bind","e","altKey","keyCode","preventDefault","_showOverlay","showImage","document","createElement","src","forEach","type","_hideOverlay","currentTarget","style","transform","focus","display","tpl","innerHTML","prototype"],"mappings":"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","file":"img-lightbox.js","sourceRoot":"../src/shadow","sourcesContent":["const loaderSvgUrl = require('../../assets/hourglass.svg');\n\nclass ImgLightbox extends HTMLElement {\n\n constructor() {\n super();\n this.loading = false;\n this.attachShadow({mode: 'open'});\n }\n\n connectedCallback() {\n // Template is added to prototype below the \n // class definition.\n // It's from a template tag because it's \n // supposed to be faster this way.\n this.shadowRoot.appendChild(\n this.template.content.cloneNode(true)\n );\n // Get some element references from shadow DOM:\n this.overlay = this.shadowRoot.querySelector('#overlay');\n this.loadingOverlay = this.shadowRoot.querySelector('#loader');\n // Component needs a tabIndex to be focusable.\n this.tabIndex = 0;\n // The slotted elements are actually not in \n // the shadow DOM so we can get them like so:\n const link = this.querySelector('a');\n const img = this.querySelector('img');\n if (link) {\n // Store the URL as the full image URL:\n this.fullImage = link.getAttribute('href');\n // Register a click event that has to \n // prevent default:\n //this._addListeners(link);\n // Prevent ability to focus the link:\n link.tabIndex = -1;\n } else if (img) {\n this.fullImage = img.getAttribute('src');\n // Nothing wrong with giving the same tabIndex\n // to things, they're ordered by position.\n // I think.\n //img.tabIndex = 0;\n //this._addListeners(img);\n }\n this.fullImage && this._addListeners();\n }\n\n _addListeners() {\n this.addEventListener('click', this.showLightbox.bind(this), true);\n this.addEventListener('keydown', (e) => {\n // It's common to ignore anything with alt\n // modifiers. I've copied this from Google\n // people.\n if (e.altKey) return;\n // Catch enter and space:\n switch (e.keyCode) {\n case 13:\n case 32:\n this.showLightbox(e);\n default:\n return;\n }\n }, true);\n }\n\n showLightbox(e) {\n // This is required so that the link element does not get \n // followed:\n e.preventDefault();\n\n // Implement some kind of lock:\n if (!this.loading) {\n this.loading = true;\n // Preload the full image.\n // Show the spinner overlay:\n this._showOverlay(this.loadingOverlay);\n if (!this.img) {\n this.img = document.createElement('img');\n this.img.addEventListener('load', () => this.showImage());\n this.img.src = this.fullImage;\n this.img.tabIndex = 1;\n // Prepare the events to close the overlay.\n // I'm doing this here to light up what's\n // happening in connectedCallback.\n // I'm not doing a check for which key was\n // called on purpose, but maybe I should do\n // that alt key check?\n ['click', 'keydown'].forEach(\n (type) => \n this.overlay.addEventListener(\n type, \n (e) => this._hideOverlay(e.currentTarget)\n )\n );\n this.overlay.appendChild(this.img);\n } else {\n this.showImage();\n }\n }\n }\n\n showImage() {\n this.img.style.transform = 'scale(0.1)';\n // Hide the loading overlay:\n this._hideOverlay(this.loadingOverlay);\n this._showOverlay(this.overlay);\n // Focus the overlay (requires it to have a tabIndex):\n this.overlay.focus();\n // Start the CSS transition:\n this.img.style.transform = 'scale(1)';\n // Don't forget to unlock the click event:\n this.loading = false;\n }\n\n _showOverlay(overlay) {\n overlay.style.display = 'flex';\n }\n\n _hideOverlay(overlay) {\n overlay.style.display = '';\n }\n\n}\n\n// I'm using a true template tag because the Chrome\n// team says it's faster. The template tag has \n// better browser support than web components anyway.\n// The strange comment here is needed for syntax\n// highlighting with a VS Code extension I'm using.\nconst tpl = document.createElement('template');\ntpl.innerHTML = /*template*/`\n<style>\n :host {\n display: inline-block;\n cursor: pointer;\n position: relative;\n }\n\n :host([hidden]) {\n display: none;\n }\n\n :host(:focus), :host(:active) {\n outline: 2px solid #77b;\n }\n\n #loader {\n position: absolute;\n z-index: 1;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background-color: rgba(0,0,0,.2);\n display: none;\n align-items: center;\n justify-content: center;\n }\n\n #overlay {\n position: fixed;\n top: 0;\n left: 0;\n bottom: 0;\n right: 0;\n overflow: hidden;\n z-index: 999;\n background-color: rgba(0,0,0,.5);\n display: none;\n align-items: center;\n justify-content: center;\n }\n\n #loader img {\n width: 50%;\n opacity: 0.6;\n animation: lightbox-loader 2s infinite;\n }\n\n #overlay img {\n max-width: 100%;\n max-height: 100%;\n transition: transform 0.8s;\n }\n\n @keyframes lightbox-loader {\n 0% {transform: rotate(0deg);}\n 100% {transform: rotate(360deg);}\n }\n</style>\n<slot></slot>\n<div id=\"overlay\" tabindex=\"0\"></div>\n<div id=\"loader\">\n <img src=\"${loaderSvgUrl}\">\n</div>\n`;\nImgLightbox.prototype.template = tpl;\n\nexport default ImgLightbox;"]}
1
+ {"mappings":"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","sources":["src/shadow/img-lightbox.js","node_modules/@parcel/runtime-js/lib/bundles/runtime-4f432e39aae9d60a.js"],"sourcesContent":["// const loaderSvgUrl = require('../../assets/hourglass.svg');\nimport loaderSvg from 'bundle-text:../../assets/hourglass.svg';\n\nclass ImgLightbox extends HTMLElement {\n\n constructor() {\n super();\n this.loading = false;\n this.attachShadow({ mode: 'open' });\n }\n\n connectedCallback() {\n // Template is added to prototype below the \n // class definition.\n // It's from a template tag because it's \n // supposed to be faster this way.\n this.shadowRoot.appendChild(\n this.template.content.cloneNode(true)\n );\n // Get some element references from shadow DOM:\n this.overlay = this.shadowRoot.querySelector('#overlay');\n this.loadingOverlay = this.shadowRoot.querySelector('#loader');\n // Add the loading SVG to that element:\n this.loadingOverlay.innerHTML = loaderSvg;\n // Component needs a tabIndex to be focusable.\n this.tabIndex = 0;\n // The slotted elements are actually not in \n // the shadow DOM so we can get them like so:\n const link = this.querySelector('a');\n const img = this.querySelector('img');\n if (link) {\n // Store the URL as the full image URL:\n this.fullImage = link.getAttribute('href');\n // Register a click event that has to \n // prevent default:\n //this._addListeners(link);\n // Prevent ability to focus the link:\n link.tabIndex = -1;\n } else if (img) {\n this.fullImage = img.getAttribute('src');\n // Nothing wrong with giving the same tabIndex\n // to things, they're ordered by position.\n // I think.\n //img.tabIndex = 0;\n //this._addListeners(img);\n }\n this.fullImage && this._addListeners();\n }\n\n _addListeners() {\n this.addEventListener('click', this.showLightbox.bind(this), true);\n this.addEventListener('keydown', (e) => {\n // It's common to ignore anything with alt\n // modifiers. I've copied this from Google\n // people.\n if (e.altKey) return;\n // Catch enter and space:\n switch (e.keyCode) {\n case 13:\n case 32:\n this.showLightbox(e);\n default:\n return;\n }\n }, true);\n }\n\n showLightbox(e) {\n // This is required so that the link element does not get \n // followed:\n e.preventDefault();\n\n // Implement some kind of lock:\n if (!this.loading) {\n this.loading = true;\n // Preload the full image.\n // Show the spinner overlay:\n this._showOverlay(this.loadingOverlay);\n if (!this.img) {\n this.img = document.createElement('img');\n this.img.addEventListener('load', () => this.showImage());\n this.img.src = this.fullImage;\n this.img.tabIndex = 1;\n // Prepare the events to close the overlay.\n // I'm doing this here to light up what's\n // happening in connectedCallback.\n // I'm not doing a check for which key was\n // called on purpose, but maybe I should do\n // that alt key check?\n ['click', 'keydown'].forEach(\n (type) =>\n this.overlay.addEventListener(\n type,\n (e) => this._hideOverlay(e.currentTarget)\n )\n );\n this.overlay.appendChild(this.img);\n } else {\n this.showImage();\n }\n }\n }\n\n showImage() {\n this.img.style.transform = 'scale(0.1)';\n // Hide the loading overlay:\n this._hideOverlay(this.loadingOverlay);\n this._showOverlay(this.overlay);\n // Focus the overlay (requires it to have a tabIndex):\n this.overlay.focus();\n // Start the CSS transition:\n this.img.style.transform = 'scale(1)';\n // Don't forget to unlock the click event:\n this.loading = false;\n }\n\n _showOverlay(overlay) {\n overlay.style.display = 'flex';\n }\n\n _hideOverlay(overlay) {\n overlay.style.display = '';\n }\n\n}\n\n// I'm using a true template tag because the Chrome\n// team says it's faster. The template tag has \n// better browser support than web components anyway.\n// The strange comment here is needed for syntax\n// highlighting with a VS Code extension I'm using.\nconst tpl = document.createElement('template');\ntpl.innerHTML = /*template*/`\n<style>\n :host {\n display: inline-block;\n cursor: pointer;\n position: relative;\n }\n\n :host([hidden]) {\n display: none;\n }\n\n :host(:focus), :host(:active) {\n outline: 2px solid #77b;\n }\n\n #loader {\n position: absolute;\n z-index: 1;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background-color: rgba(0,0,0,.2);\n display: none;\n align-items: center;\n justify-content: center;\n }\n\n #overlay {\n position: fixed;\n top: 0;\n left: 0;\n bottom: 0;\n right: 0;\n overflow: hidden;\n z-index: 999;\n background-color: rgba(0,0,0,.5);\n display: none;\n align-items: center;\n justify-content: center;\n }\n\n #loader img {\n width: 50%;\n opacity: 0.6;\n animation: lightbox-loader 2s infinite;\n }\n\n #overlay img {\n max-width: 100%;\n max-height: 100%;\n transition: transform 0.8s;\n }\n\n @keyframes lightbox-loader {\n 0% {transform: rotate(0deg);}\n 100% {transform: rotate(360deg);}\n }\n</style>\n<slot></slot>\n<div id=\"overlay\" tabindex=\"0\"></div>\n<div id=\"loader\">\n</div>\n`;\nImgLightbox.prototype.template = tpl;\n\nexport default ImgLightbox;\n","module.exports = \"1f3d06fcd1df419a\";"],"names":[],"version":3,"file":"img-lightbox.js.map"}
@@ -0,0 +1,187 @@
1
+
2
+ function $parcel$interopDefault(a) {
3
+ return a && a.__esModule ? a.default : a;
4
+ }
5
+ // const loaderSvgUrl = require('../../assets/hourglass.svg');
6
+ var $6ba1613a1599b26d$exports = {};
7
+ $6ba1613a1599b26d$exports = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:cc=\"http://creativecommons.org/ns#\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" enable-background=\"new 0 0 64 64\" version=\"1.1\" viewBox=\"0 0 64 64\" xml:space=\"preserve\"><metadata><rdf:RDF><cc:Work rdf:about=\"\"><dc:format>image/svg+xml</dc:format><dc:type rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\"/><dc:title/></cc:Work></rdf:RDF></metadata>\n<g>\n\t\t<circle class=\"st0\" cx=\"32\" cy=\"32\" r=\"32\"/>\n\t</g><g class=\"st1\" opacity=\".2\">\n\t\t<path class=\"st2\" d=\"m46 50h-2v-4c0-4.5-3-7.4-3-7.4s-3-2.8-3.9-3.7 0-1.8 0-1.8 1.3-1.3 4.2-4c2.8-2.7 2.7-6.7 2.7-6.7v-5.1l-12-1-12 1v5.1s-0.1 3.9 2.7 6.7c2.8 2.7 4.2 4 4.2 4s0.9 0.9 0 1.8-3.9 3.7-3.9 3.7-3 2.8-3 7.4v4h-2c-1.1 0-2 0.9-2 2s0.9 2 2 2h28c1.1 0 2-0.9 2-2s-0.9-2-2-2z\" fill=\"#231f20\"/>\n\t</g>\n\t\t<path class=\"st3\" d=\"m41 36.6s-3-2.8-3.9-3.7 0-1.8 0-1.8 1.3-1.3 4.2-4c2.8-2.7 2.7-6.7 2.7-6.7v-5.1l-12-1-12 1v5.1s-0.1 3.9 2.7 6.7c2.8 2.7 4.2 4 4.2 4s0.9 0.9 0 1.8-3.9 3.7-3.9 3.7-3 2.8-3 7.4v5.1h24v-5.1c0-4.5-3-7.4-3-7.4z\" fill=\"#fff\"/>\n\t\n\t\t<path class=\"st4\" d=\"m31 43v-11c0-2.1-1-3.4-1.3-3.7l-4.2-4c-1.5-1.4-1.5-3.7-1.5-3.7h16s0 2.3-1.5 3.7l-4.2 4c-0.4 0.3-1.3 1.6-1.3 3.7v11z\"/>\n\t<g class=\"st5\" opacity=\".3\">\n\t\t<path class=\"st2\" d=\"m48 16c0 1.1-0.9 2-2 2h-28c-1.1 0-2-0.9-2-2s0.9-2 2-2h28c1.1 0 2 0.9 2 2z\" fill=\"#231f20\"/>\n\t</g><g fill=\"#fff\">\n\t\t<path class=\"st6\" d=\"m48 14c0 1.1-0.9 2-2 2h-28c-1.1 0-2-0.9-2-2s0.9-2 2-2h28c1.1 0 2 0.9 2 2z\" fill=\"#fff\"/>\n\t</g><g fill=\"#fff\">\n\t\t<path class=\"st6\" d=\"m48 50c0 1.1-0.9 2-2 2h-28c-1.1 0-2-0.9-2-2s0.9-2 2-2h28c1.1 0 2 0.9 2 2z\" fill=\"#fff\"/>\n\t</g><g>\n\t\t<polygon class=\"st4\" points=\"23 48 23 48 32 40 41 48\"/>\n\t</g>\n\n</svg>";
8
+
9
+
10
+ class $ef17987508a11d23$var$ImgLightbox extends HTMLElement {
11
+ constructor(){
12
+ super();
13
+ this.loading = false;
14
+ this.attachShadow({
15
+ mode: 'open'
16
+ });
17
+ }
18
+ connectedCallback() {
19
+ // Template is added to prototype below the
20
+ // class definition.
21
+ // It's from a template tag because it's
22
+ // supposed to be faster this way.
23
+ this.shadowRoot.appendChild(this.template.content.cloneNode(true));
24
+ // Get some element references from shadow DOM:
25
+ this.overlay = this.shadowRoot.querySelector('#overlay');
26
+ this.loadingOverlay = this.shadowRoot.querySelector('#loader');
27
+ // Add the loading SVG to that element:
28
+ this.loadingOverlay.innerHTML = (0, (/*@__PURE__*/$parcel$interopDefault($6ba1613a1599b26d$exports)));
29
+ // Component needs a tabIndex to be focusable.
30
+ this.tabIndex = 0;
31
+ // The slotted elements are actually not in
32
+ // the shadow DOM so we can get them like so:
33
+ const link = this.querySelector('a');
34
+ const img = this.querySelector('img');
35
+ if (link) {
36
+ // Store the URL as the full image URL:
37
+ this.fullImage = link.getAttribute('href');
38
+ // Register a click event that has to
39
+ // prevent default:
40
+ //this._addListeners(link);
41
+ // Prevent ability to focus the link:
42
+ link.tabIndex = -1;
43
+ } else if (img) this.fullImage = img.getAttribute('src');
44
+ this.fullImage && this._addListeners();
45
+ }
46
+ _addListeners() {
47
+ this.addEventListener('click', this.showLightbox.bind(this), true);
48
+ this.addEventListener('keydown', (e)=>{
49
+ // It's common to ignore anything with alt
50
+ // modifiers. I've copied this from Google
51
+ // people.
52
+ if (e.altKey) return;
53
+ // Catch enter and space:
54
+ switch(e.keyCode){
55
+ case 13:
56
+ case 32:
57
+ this.showLightbox(e);
58
+ default:
59
+ return;
60
+ }
61
+ }, true);
62
+ }
63
+ showLightbox(e) {
64
+ // This is required so that the link element does not get
65
+ // followed:
66
+ e.preventDefault();
67
+ // Implement some kind of lock:
68
+ if (!this.loading) {
69
+ this.loading = true;
70
+ // Preload the full image.
71
+ // Show the spinner overlay:
72
+ this._showOverlay(this.loadingOverlay);
73
+ if (!this.img) {
74
+ this.img = document.createElement('img');
75
+ this.img.addEventListener('load', ()=>this.showImage());
76
+ this.img.src = this.fullImage;
77
+ this.img.tabIndex = 1;
78
+ // Prepare the events to close the overlay.
79
+ // I'm doing this here to light up what's
80
+ // happening in connectedCallback.
81
+ // I'm not doing a check for which key was
82
+ // called on purpose, but maybe I should do
83
+ // that alt key check?
84
+ [
85
+ 'click',
86
+ 'keydown'
87
+ ].forEach((type)=>this.overlay.addEventListener(type, (e)=>this._hideOverlay(e.currentTarget)));
88
+ this.overlay.appendChild(this.img);
89
+ } else this.showImage();
90
+ }
91
+ }
92
+ showImage() {
93
+ this.img.style.transform = 'scale(0.1)';
94
+ // Hide the loading overlay:
95
+ this._hideOverlay(this.loadingOverlay);
96
+ this._showOverlay(this.overlay);
97
+ // Focus the overlay (requires it to have a tabIndex):
98
+ this.overlay.focus();
99
+ // Start the CSS transition:
100
+ this.img.style.transform = 'scale(1)';
101
+ // Don't forget to unlock the click event:
102
+ this.loading = false;
103
+ }
104
+ _showOverlay(overlay) {
105
+ overlay.style.display = 'flex';
106
+ }
107
+ _hideOverlay(overlay) {
108
+ overlay.style.display = '';
109
+ }
110
+ }
111
+ // I'm using a true template tag because the Chrome
112
+ // team says it's faster. The template tag has
113
+ // better browser support than web components anyway.
114
+ // The strange comment here is needed for syntax
115
+ // highlighting with a VS Code extension I'm using.
116
+ const $ef17987508a11d23$var$tpl = document.createElement('template');
117
+ $ef17987508a11d23$var$tpl.innerHTML = /*template*/ `
118
+ <style>
119
+ :host {
120
+ display: inline-block;
121
+ cursor: pointer;
122
+ position: relative;
123
+ }
124
+
125
+ :host([hidden]) {
126
+ display: none;
127
+ }
128
+
129
+ :host(:focus), :host(:active) {
130
+ outline: 2px solid #77b;
131
+ }
132
+
133
+ #loader {
134
+ position: absolute;
135
+ z-index: 1;
136
+ top: 0;
137
+ left: 0;
138
+ width: 100%;
139
+ height: 100%;
140
+ background-color: rgba(0,0,0,.2);
141
+ display: none;
142
+ align-items: center;
143
+ justify-content: center;
144
+ }
145
+
146
+ #overlay {
147
+ position: fixed;
148
+ top: 0;
149
+ left: 0;
150
+ bottom: 0;
151
+ right: 0;
152
+ overflow: hidden;
153
+ z-index: 999;
154
+ background-color: rgba(0,0,0,.5);
155
+ display: none;
156
+ align-items: center;
157
+ justify-content: center;
158
+ }
159
+
160
+ #loader img {
161
+ width: 50%;
162
+ opacity: 0.6;
163
+ animation: lightbox-loader 2s infinite;
164
+ }
165
+
166
+ #overlay img {
167
+ max-width: 100%;
168
+ max-height: 100%;
169
+ transition: transform 0.8s;
170
+ }
171
+
172
+ @keyframes lightbox-loader {
173
+ 0% {transform: rotate(0deg);}
174
+ 100% {transform: rotate(360deg);}
175
+ }
176
+ </style>
177
+ <slot></slot>
178
+ <div id="overlay" tabindex="0"></div>
179
+ <div id="loader">
180
+ </div>
181
+ `;
182
+ $ef17987508a11d23$var$ImgLightbox.prototype.template = $ef17987508a11d23$var$tpl;
183
+ var $ef17987508a11d23$export$2e2bcd8739ae039 = $ef17987508a11d23$var$ImgLightbox;
184
+
185
+
186
+ export {$ef17987508a11d23$export$2e2bcd8739ae039 as default};
187
+ //# sourceMappingURL=img-lightbox.mjs.map
@@ -0,0 +1 @@
1
+ {"mappings":";;;;AAAA,8DAA8D;;ACA9D,4BAAiB;;;ADGjB,MAAM,0CAAoB;IAExB,aAAc;QACZ,KAAK;QACL,IAAI,CAAC,OAAO,GAAG;QACf,IAAI,CAAC,YAAY,CAAC;YAAE,MAAM;QAAO;IACnC;IAEA,oBAAoB;QAClB,4CAA4C;QAC5C,oBAAoB;QACpB,yCAAyC;QACzC,kCAAkC;QAClC,IAAI,CAAC,UAAU,CAAC,WAAW,CACzB,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC;QAElC,+CAA+C;QAC/C,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC;QAC7C,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC;QACpD,uCAAuC;QACvC,IAAI,CAAC,cAAc,CAAC,SAAS,GAAG,CAAA,GAAA,gEAAQ;QACxC,8CAA8C;QAC9C,IAAI,CAAC,QAAQ,GAAG;QAChB,4CAA4C;QAC5C,6CAA6C;QAC7C,MAAM,OAAO,IAAI,CAAC,aAAa,CAAC;QAChC,MAAM,MAAM,IAAI,CAAC,aAAa,CAAC;QAC/B,IAAI,MAAM;YACR,uCAAuC;YACvC,IAAI,CAAC,SAAS,GAAG,KAAK,YAAY,CAAC;YACnC,sCAAsC;YACtC,mBAAmB;YACnB,2BAA2B;YAC3B,qCAAqC;YACrC,KAAK,QAAQ,GAAG;QAClB,OAAO,IAAI,KACT,IAAI,CAAC,SAAS,GAAG,IAAI,YAAY,CAAC;QAOpC,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,aAAa;IACtC;IAEA,gBAAgB;QACd,IAAI,CAAC,gBAAgB,CAAC,SAAS,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,GAAG;QAC7D,IAAI,CAAC,gBAAgB,CAAC,WAAW,CAAC;YAChC,0CAA0C;YAC1C,0CAA0C;YAC1C,UAAU;YACV,IAAI,EAAE,MAAM,EAAE;YACd,yBAAyB;YACzB,OAAQ,EAAE,OAAO;gBACf,KAAK;gBACL,KAAK;oBACH,IAAI,CAAC,YAAY,CAAC;gBACpB;oBACE;YACJ;QACF,GAAG;IACL;IAEA,aAAa,CAAC,EAAE;QACd,0DAA0D;QAC1D,YAAY;QACZ,EAAE,cAAc;QAEhB,+BAA+B;QAC/B,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YACjB,IAAI,CAAC,OAAO,GAAG;YACf,0BAA0B;YAC1B,4BAA4B;YAC5B,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,cAAc;YACrC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE;gBACb,IAAI,CAAC,GAAG,GAAG,SAAS,aAAa,CAAC;gBAClC,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,QAAQ,IAAM,IAAI,CAAC,SAAS;gBACtD,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,SAAS;gBAC7B,IAAI,CAAC,GAAG,CAAC,QAAQ,GAAG;gBACpB,2CAA2C;gBAC3C,yCAAyC;gBACzC,kCAAkC;gBAClC,0CAA0C;gBAC1C,2CAA2C;gBAC3C,sBAAsB;gBACtB;oBAAC;oBAAS;iBAAU,CAAC,OAAO,CAC1B,CAAC,OACC,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAC3B,MACA,CAAC,IAAM,IAAI,CAAC,YAAY,CAAC,EAAE,aAAa;gBAG9C,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG;YACnC,OACE,IAAI,CAAC,SAAS;QAElB;IACF;IAEA,YAAY;QACV,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,GAAG;QAC3B,4BAA4B;QAC5B,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,cAAc;QACrC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO;QAC9B,sDAAsD;QACtD,IAAI,CAAC,OAAO,CAAC,KAAK;QAClB,4BAA4B;QAC5B,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,GAAG;QAC3B,0CAA0C;QAC1C,IAAI,CAAC,OAAO,GAAG;IACjB;IAEA,aAAa,OAAO,EAAE;QACpB,QAAQ,KAAK,CAAC,OAAO,GAAG;IAC1B;IAEA,aAAa,OAAO,EAAE;QACpB,QAAQ,KAAK,CAAC,OAAO,GAAG;IAC1B;AAEF;AAEA,mDAAmD;AACnD,+CAA+C;AAC/C,qDAAqD;AACrD,gDAAgD;AAChD,mDAAmD;AACnD,MAAM,4BAAM,SAAS,aAAa,CAAC;AACnC,0BAAI,SAAS,GAAG,UAAU,GAAE,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgE7B,CAAC;AACD,kCAAY,SAAS,CAAC,QAAQ,GAAG;IAEjC,2CAAe","sources":["src/shadow/img-lightbox.js","node_modules/@parcel/runtime-js/lib/bundles/runtime-7833d3a46095a7f4.js"],"sourcesContent":["// const loaderSvgUrl = require('../../assets/hourglass.svg');\nimport loaderSvg from 'bundle-text:../../assets/hourglass.svg';\n\nclass ImgLightbox extends HTMLElement {\n\n constructor() {\n super();\n this.loading = false;\n this.attachShadow({ mode: 'open' });\n }\n\n connectedCallback() {\n // Template is added to prototype below the \n // class definition.\n // It's from a template tag because it's \n // supposed to be faster this way.\n this.shadowRoot.appendChild(\n this.template.content.cloneNode(true)\n );\n // Get some element references from shadow DOM:\n this.overlay = this.shadowRoot.querySelector('#overlay');\n this.loadingOverlay = this.shadowRoot.querySelector('#loader');\n // Add the loading SVG to that element:\n this.loadingOverlay.innerHTML = loaderSvg;\n // Component needs a tabIndex to be focusable.\n this.tabIndex = 0;\n // The slotted elements are actually not in \n // the shadow DOM so we can get them like so:\n const link = this.querySelector('a');\n const img = this.querySelector('img');\n if (link) {\n // Store the URL as the full image URL:\n this.fullImage = link.getAttribute('href');\n // Register a click event that has to \n // prevent default:\n //this._addListeners(link);\n // Prevent ability to focus the link:\n link.tabIndex = -1;\n } else if (img) {\n this.fullImage = img.getAttribute('src');\n // Nothing wrong with giving the same tabIndex\n // to things, they're ordered by position.\n // I think.\n //img.tabIndex = 0;\n //this._addListeners(img);\n }\n this.fullImage && this._addListeners();\n }\n\n _addListeners() {\n this.addEventListener('click', this.showLightbox.bind(this), true);\n this.addEventListener('keydown', (e) => {\n // It's common to ignore anything with alt\n // modifiers. I've copied this from Google\n // people.\n if (e.altKey) return;\n // Catch enter and space:\n switch (e.keyCode) {\n case 13:\n case 32:\n this.showLightbox(e);\n default:\n return;\n }\n }, true);\n }\n\n showLightbox(e) {\n // This is required so that the link element does not get \n // followed:\n e.preventDefault();\n\n // Implement some kind of lock:\n if (!this.loading) {\n this.loading = true;\n // Preload the full image.\n // Show the spinner overlay:\n this._showOverlay(this.loadingOverlay);\n if (!this.img) {\n this.img = document.createElement('img');\n this.img.addEventListener('load', () => this.showImage());\n this.img.src = this.fullImage;\n this.img.tabIndex = 1;\n // Prepare the events to close the overlay.\n // I'm doing this here to light up what's\n // happening in connectedCallback.\n // I'm not doing a check for which key was\n // called on purpose, but maybe I should do\n // that alt key check?\n ['click', 'keydown'].forEach(\n (type) =>\n this.overlay.addEventListener(\n type,\n (e) => this._hideOverlay(e.currentTarget)\n )\n );\n this.overlay.appendChild(this.img);\n } else {\n this.showImage();\n }\n }\n }\n\n showImage() {\n this.img.style.transform = 'scale(0.1)';\n // Hide the loading overlay:\n this._hideOverlay(this.loadingOverlay);\n this._showOverlay(this.overlay);\n // Focus the overlay (requires it to have a tabIndex):\n this.overlay.focus();\n // Start the CSS transition:\n this.img.style.transform = 'scale(1)';\n // Don't forget to unlock the click event:\n this.loading = false;\n }\n\n _showOverlay(overlay) {\n overlay.style.display = 'flex';\n }\n\n _hideOverlay(overlay) {\n overlay.style.display = '';\n }\n\n}\n\n// I'm using a true template tag because the Chrome\n// team says it's faster. The template tag has \n// better browser support than web components anyway.\n// The strange comment here is needed for syntax\n// highlighting with a VS Code extension I'm using.\nconst tpl = document.createElement('template');\ntpl.innerHTML = /*template*/`\n<style>\n :host {\n display: inline-block;\n cursor: pointer;\n position: relative;\n }\n\n :host([hidden]) {\n display: none;\n }\n\n :host(:focus), :host(:active) {\n outline: 2px solid #77b;\n }\n\n #loader {\n position: absolute;\n z-index: 1;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background-color: rgba(0,0,0,.2);\n display: none;\n align-items: center;\n justify-content: center;\n }\n\n #overlay {\n position: fixed;\n top: 0;\n left: 0;\n bottom: 0;\n right: 0;\n overflow: hidden;\n z-index: 999;\n background-color: rgba(0,0,0,.5);\n display: none;\n align-items: center;\n justify-content: center;\n }\n\n #loader img {\n width: 50%;\n opacity: 0.6;\n animation: lightbox-loader 2s infinite;\n }\n\n #overlay img {\n max-width: 100%;\n max-height: 100%;\n transition: transform 0.8s;\n }\n\n @keyframes lightbox-loader {\n 0% {transform: rotate(0deg);}\n 100% {transform: rotate(360deg);}\n }\n</style>\n<slot></slot>\n<div id=\"overlay\" tabindex=\"0\"></div>\n<div id=\"loader\">\n</div>\n`;\nImgLightbox.prototype.template = tpl;\n\nexport default ImgLightbox;\n","module.exports = \"0470ae78683fa4f4\";"],"names":[],"version":3,"file":"img-lightbox.mjs.map"}
package/package.json CHANGED
@@ -1,13 +1,15 @@
1
1
  {
2
2
  "name": "@dkvz/img-lightbox",
3
- "version": "0.2.0",
3
+ "version": "1.0.0",
4
4
  "description": "Web component to add a lightbox effect to img elements",
5
5
  "main": "dist/img-lightbox.js",
6
+ "module": "dist/img-lightbox.mjs",
7
+ "source": "src/shadow/img-lightbox.js",
6
8
  "scripts": {
7
9
  "start": "parcel src/shadow/index.pug",
8
- "build": "parcel build src/shadow/img-lightbox.js --public-url ./ --global ImgLightbox",
10
+ "build": "rimraf dist && parcel build",
9
11
  "start-no-shadow": "parcel src/no-shadow/index.pug",
10
- "build-no-shadow": "parcel build src/no-shadow/img-lightbox.js --public-url ./ --global ImgLightbox"
12
+ "build-no-shadow": "parcel build src/no-shadow/img-lightbox.js --public-url ./"
11
13
  },
12
14
  "repository": {
13
15
  "type": "git",
@@ -16,9 +18,10 @@
16
18
  "author": "dkvz",
17
19
  "license": "MIT",
18
20
  "devDependencies": {
19
- "parcel-bundler": "^1.12.4",
20
- "parcel-plugin-clean-dist": "0.0.6",
21
- "parcel-plugin-url-loader": "^1.3.1",
22
- "pug": "^2.0.4"
21
+ "@parcel/transformer-inline-string": "^2.15.4",
22
+ "@parcel/transformer-pug": "^2.15.4",
23
+ "parcel": "^2.15.4",
24
+ "pug": "^2.0.4",
25
+ "rimraf": "^6.0.1"
23
26
  }
24
27
  }
@@ -1,11 +1,12 @@
1
- const loaderSvgUrl = require('../../assets/hourglass.svg');
1
+ // const loaderSvgUrl = require('../../assets/hourglass.svg');
2
+ import loaderSvg from 'bundle-text:../../assets/hourglass.svg';
2
3
 
3
4
  class ImgLightbox extends HTMLElement {
4
5
 
5
6
  constructor() {
6
7
  super();
7
8
  this.loading = false;
8
- this.attachShadow({mode: 'open'});
9
+ this.attachShadow({ mode: 'open' });
9
10
  }
10
11
 
11
12
  connectedCallback() {
@@ -19,6 +20,8 @@ class ImgLightbox extends HTMLElement {
19
20
  // Get some element references from shadow DOM:
20
21
  this.overlay = this.shadowRoot.querySelector('#overlay');
21
22
  this.loadingOverlay = this.shadowRoot.querySelector('#loader');
23
+ // Add the loading SVG to that element:
24
+ this.loadingOverlay.innerHTML = loaderSvg;
22
25
  // Component needs a tabIndex to be focusable.
23
26
  this.tabIndex = 0;
24
27
  // The slotted elements are actually not in
@@ -85,9 +88,9 @@ class ImgLightbox extends HTMLElement {
85
88
  // called on purpose, but maybe I should do
86
89
  // that alt key check?
87
90
  ['click', 'keydown'].forEach(
88
- (type) =>
91
+ (type) =>
89
92
  this.overlay.addEventListener(
90
- type,
93
+ type,
91
94
  (e) => this._hideOverlay(e.currentTarget)
92
95
  )
93
96
  );
@@ -190,9 +193,8 @@ tpl.innerHTML = /*template*/`
190
193
  <slot></slot>
191
194
  <div id="overlay" tabindex="0"></div>
192
195
  <div id="loader">
193
- <img src="${loaderSvgUrl}">
194
196
  </div>
195
197
  `;
196
198
  ImgLightbox.prototype.template = tpl;
197
199
 
198
- export default ImgLightbox;
200
+ export default ImgLightbox;
@@ -18,6 +18,13 @@ html
18
18
  display: inline-block;
19
19
  border: 1px solid #333;
20
20
  box-shadow: 0px 0px 4px rgba(0,0,0,0.6);
21
+ background-color: #333;
22
+ }
23
+
24
+ /* Both slotted elements should be display: block */
25
+ img-lightbox a, img-lightbox img {
26
+ display: block;
27
+ max-width: 200px;
21
28
  }
22
29
 
23
30
  img-lightbox:active, img-lightbox:focus {
@@ -2,9 +2,9 @@
2
2
  <p>The image should still show and link to the full version with JS disabled.</p>
3
3
 
4
4
  <img-lightbox>
5
- <a href="../../assets/example.png" target="_blank" rel="noopener noreferrer">
6
- <img src="../../assets/example_preview.png"
7
- alt="Rabbit with a trumpet mute on its head">
5
+ <a href="../../assets/example.jpg" target="_blank" rel="noopener noreferrer">
6
+ <img src="../../assets/example_preview.jpg"
7
+ alt="Some cute cat">
8
8
  </a>
9
9
  </img-lightbox>
10
10
 
@@ -14,4 +14,4 @@
14
14
 
15
15
  </div>
16
16
 
17
- <script src="./example.js"></script>
17
+ <script type="module" src="./example.js"></script>