kempo-ui 0.4.24 → 0.4.25
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.
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import e from"./ShadowComponent.js";import{html as t,css as n,render as o}from"../lit-all.min.js";import{boolExists as
|
|
1
|
+
import e from"./ShadowComponent.js";import{html as t,css as n,render as o}from"../lit-all.min.js";import{boolExists as l}from"../utils/propConverters.js";import"./Icon.js";export default class i extends e{static properties={src:{type:String,reflect:!0},alt:{type:String,reflect:!0},fullscreen:{type:Boolean,reflect:!0,converter:l},keyboardControls:{type:Boolean,reflect:!0,attribute:"keyboard-controls",converter:l},global:{type:Boolean,reflect:!0,converter:l}};constructor(){super(),this.src="",this.alt="",this.fullscreen=!1,this.keyboardControls=!0,this.global=!1}handleImageClick=()=>{this.open()};handleImageKeydown=e=>{"Enter"!==e.key||this.fullscreen||this.open()};handleCloseClick=()=>{this.close()};handleOverlayClick=e=>{e.target===e.currentTarget&&this.close()};handlePrevClick=e=>{e.stopPropagation();const t=this.getPrevSibling();t&&(this.close(),t.open())};handleNextClick=e=>{e.stopPropagation();const t=this.getNextSibling();t&&(this.close(),t.open())};handleKeydown=e=>{if("Escape"===e.key)this.close();else if("ArrowLeft"===e.key){const e=this.getPrevSibling();e&&(this.close(),e.open())}else if("ArrowRight"===e.key){const e=this.getNextSibling();e&&(this.close(),e.open())}};connectedCallback(){super.connectedCallback()}disconnectedCallback(){super.disconnectedCallback(),this.keyboardControls&&document.removeEventListener("keydown",this.handleKeydown)}updated(e){if(super.updated(e),e.has("fullscreen")){this.dispatchEvent(new CustomEvent("fullscreenchange",{detail:{fullscreen:this.fullscreen}})),this.dispatchEvent(new CustomEvent(this.fullscreen?"fullscreen":"fullscreenclose")),this.updateNavigationState(),document.body.classList.toggle("no-scroll",this.fullscreen);const e=this.closest("[data-overlay-root]");e&&e.classList.toggle("no-scroll",this.fullscreen),this.keyboardControls&&(this.fullscreen?document.addEventListener("keydown",this.handleKeydown):document.removeEventListener("keydown",this.handleKeydown))}(e.has("src")||e.has("alt"))&&this.handleFullscreenCaption()}firstUpdated(){this.handleFullscreenCaption()}open(){this.fullscreen=!0}close(){this.fullscreen=!1}toggle(){this.fullscreen=!this.fullscreen}static open(e,t=0,n={}){const{keyboardControls:l=!0,onClose:i}=n,s=document.createElement("div");s.style.position="fixed",s.style.top="0",s.style.left="0",s.style.width="0",s.style.height="0",s.style.overflow="hidden",s.style.zIndex="80";const r=e.map(e=>{const t=document.createElement("k-photo-viewer");return t.src=e.src,t.alt=e.alt||"",t.keyboardControls=l,void 0!==e.caption&&("string"==typeof e.caption?t.innerHTML=e.caption:o(e.caption,t)),s.appendChild(t),t});(document.querySelector("[data-overlay-root]")||document.body).appendChild(s);const a=()=>{r.some(e=>e.fullscreen)||(r.forEach(e=>e.removeEventListener("fullscreenclose",a)),s.remove(),i?.())};r.forEach(e=>e.addEventListener("fullscreenclose",a));const c=Math.min(Math.max(t,0),r.length-1);return r[c].open(),r[c]}getPrevSibling(){if(this.global){const e=Array.from(document.getElementsByTagName("k-photo-viewer")),t=e.indexOf(this);return-1===t?null:e[0===t?e.length-1:t-1]}{let e=this.previousElementSibling;for(;e&&"K-PHOTO-VIEWER"!==e.tagName;)e=e.previousElementSibling;if(!e&&this.hasPhotoSiblings())for(e=this.parentElement.lastElementChild;e&&"K-PHOTO-VIEWER"!==e.tagName;)e=e.previousElementSibling;return e}}getNextSibling(){if(this.global){const e=Array.from(document.getElementsByTagName("k-photo-viewer")),t=e.indexOf(this);return-1===t?null:e[t===e.length-1?0:t+1]}{let e=this.nextElementSibling;for(;e&&"K-PHOTO-VIEWER"!==e.tagName;)e=e.nextElementSibling;if(!e&&this.hasPhotoSiblings())for(e=this.parentElement.firstElementChild;e&&"K-PHOTO-VIEWER"!==e.tagName;)e=e.nextElementSibling;return e}}hasPhotoSiblings(){return this.global?document.getElementsByTagName("k-photo-viewer").length>1:Array.from(this.parentElement.children).filter(e=>e!==this&&"K-PHOTO-VIEWER"===e.tagName).length>0}updateNavigationState(){const e=this.fullscreen&&this.hasPhotoSiblings();this.shadowRoot.querySelectorAll(".nav-btn").forEach(t=>{t.style.display=e?"":"none"})}async handleFullscreenCaption(){await this.updateComplete;const e=this.shadowRoot.querySelector('slot[name="fullscreen-caption"]');if(e&&!e.assignedNodes().length){const e=this.shadowRoot.querySelector("slot:not([name])");(e?e.assignedNodes():[]).forEach(e=>{if(e.nodeType===Node.ELEMENT_NODE){const t=e.cloneNode(!0);t.slot="fullscreen-caption",this.appendChild(t)}})}}static styles=n`
|
|
2
2
|
:host {
|
|
3
3
|
display: block;
|
|
4
4
|
}
|
|
@@ -132,4 +132,4 @@ import e from"./ShadowComponent.js";import{html as t,css as n,render as o}from".
|
|
|
132
132
|
</div>
|
|
133
133
|
</div>
|
|
134
134
|
</div>
|
|
135
|
-
`}}customElements.define("k-photo-viewer",
|
|
135
|
+
`}}customElements.define("k-photo-viewer",i);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import e from"./ShadowComponent.js";import{html as t,css as n,render as o}from"../lit-all.min.js";import{boolExists as
|
|
1
|
+
import e from"./ShadowComponent.js";import{html as t,css as n,render as o}from"../lit-all.min.js";import{boolExists as l}from"../utils/propConverters.js";import"./Icon.js";export default class i extends e{static properties={src:{type:String,reflect:!0},alt:{type:String,reflect:!0},fullscreen:{type:Boolean,reflect:!0,converter:l},keyboardControls:{type:Boolean,reflect:!0,attribute:"keyboard-controls",converter:l},global:{type:Boolean,reflect:!0,converter:l}};constructor(){super(),this.src="",this.alt="",this.fullscreen=!1,this.keyboardControls=!0,this.global=!1}handleImageClick=()=>{this.open()};handleImageKeydown=e=>{"Enter"!==e.key||this.fullscreen||this.open()};handleCloseClick=()=>{this.close()};handleOverlayClick=e=>{e.target===e.currentTarget&&this.close()};handlePrevClick=e=>{e.stopPropagation();const t=this.getPrevSibling();t&&(this.close(),t.open())};handleNextClick=e=>{e.stopPropagation();const t=this.getNextSibling();t&&(this.close(),t.open())};handleKeydown=e=>{if("Escape"===e.key)this.close();else if("ArrowLeft"===e.key){const e=this.getPrevSibling();e&&(this.close(),e.open())}else if("ArrowRight"===e.key){const e=this.getNextSibling();e&&(this.close(),e.open())}};connectedCallback(){super.connectedCallback()}disconnectedCallback(){super.disconnectedCallback(),this.keyboardControls&&document.removeEventListener("keydown",this.handleKeydown)}updated(e){if(super.updated(e),e.has("fullscreen")){this.dispatchEvent(new CustomEvent("fullscreenchange",{detail:{fullscreen:this.fullscreen}})),this.dispatchEvent(new CustomEvent(this.fullscreen?"fullscreen":"fullscreenclose")),this.updateNavigationState(),document.body.classList.toggle("no-scroll",this.fullscreen);const e=this.closest("[data-overlay-root]");e&&e.classList.toggle("no-scroll",this.fullscreen),this.keyboardControls&&(this.fullscreen?document.addEventListener("keydown",this.handleKeydown):document.removeEventListener("keydown",this.handleKeydown))}(e.has("src")||e.has("alt"))&&this.handleFullscreenCaption()}firstUpdated(){this.handleFullscreenCaption()}open(){this.fullscreen=!0}close(){this.fullscreen=!1}toggle(){this.fullscreen=!this.fullscreen}static open(e,t=0,n={}){const{keyboardControls:l=!0,onClose:i}=n,s=document.createElement("div");s.style.position="fixed",s.style.top="0",s.style.left="0",s.style.width="0",s.style.height="0",s.style.overflow="hidden",s.style.zIndex="80";const r=e.map(e=>{const t=document.createElement("k-photo-viewer");return t.src=e.src,t.alt=e.alt||"",t.keyboardControls=l,void 0!==e.caption&&("string"==typeof e.caption?t.innerHTML=e.caption:o(e.caption,t)),s.appendChild(t),t});(document.querySelector("[data-overlay-root]")||document.body).appendChild(s);const a=()=>{r.some(e=>e.fullscreen)||(r.forEach(e=>e.removeEventListener("fullscreenclose",a)),s.remove(),i?.())};r.forEach(e=>e.addEventListener("fullscreenclose",a));const c=Math.min(Math.max(t,0),r.length-1);return r[c].open(),r[c]}getPrevSibling(){if(this.global){const e=Array.from(document.getElementsByTagName("k-photo-viewer")),t=e.indexOf(this);return-1===t?null:e[0===t?e.length-1:t-1]}{let e=this.previousElementSibling;for(;e&&"K-PHOTO-VIEWER"!==e.tagName;)e=e.previousElementSibling;if(!e&&this.hasPhotoSiblings())for(e=this.parentElement.lastElementChild;e&&"K-PHOTO-VIEWER"!==e.tagName;)e=e.previousElementSibling;return e}}getNextSibling(){if(this.global){const e=Array.from(document.getElementsByTagName("k-photo-viewer")),t=e.indexOf(this);return-1===t?null:e[t===e.length-1?0:t+1]}{let e=this.nextElementSibling;for(;e&&"K-PHOTO-VIEWER"!==e.tagName;)e=e.nextElementSibling;if(!e&&this.hasPhotoSiblings())for(e=this.parentElement.firstElementChild;e&&"K-PHOTO-VIEWER"!==e.tagName;)e=e.nextElementSibling;return e}}hasPhotoSiblings(){return this.global?document.getElementsByTagName("k-photo-viewer").length>1:Array.from(this.parentElement.children).filter(e=>e!==this&&"K-PHOTO-VIEWER"===e.tagName).length>0}updateNavigationState(){const e=this.fullscreen&&this.hasPhotoSiblings();this.shadowRoot.querySelectorAll(".nav-btn").forEach(t=>{t.style.display=e?"":"none"})}async handleFullscreenCaption(){await this.updateComplete;const e=this.shadowRoot.querySelector('slot[name="fullscreen-caption"]');if(e&&!e.assignedNodes().length){const e=this.shadowRoot.querySelector("slot:not([name])");(e?e.assignedNodes():[]).forEach(e=>{if(e.nodeType===Node.ELEMENT_NODE){const t=e.cloneNode(!0);t.slot="fullscreen-caption",this.appendChild(t)}})}}static styles=n`
|
|
2
2
|
:host {
|
|
3
3
|
display: block;
|
|
4
4
|
}
|
|
@@ -132,4 +132,4 @@ import e from"./ShadowComponent.js";import{html as t,css as n,render as o}from".
|
|
|
132
132
|
</div>
|
|
133
133
|
</div>
|
|
134
134
|
</div>
|
|
135
|
-
`}}customElements.define("k-photo-viewer",
|
|
135
|
+
`}}customElements.define("k-photo-viewer",i);
|
package/package.json
CHANGED
|
@@ -104,7 +104,11 @@ export default class PhotoViewer extends ShadowComponent {
|
|
|
104
104
|
}));
|
|
105
105
|
this.dispatchEvent(new CustomEvent(this.fullscreen ? 'fullscreen' : 'fullscreenclose'));
|
|
106
106
|
this.updateNavigationState();
|
|
107
|
-
|
|
107
|
+
|
|
108
|
+
document.body.classList.toggle('no-scroll', this.fullscreen);
|
|
109
|
+
const overlayRoot = this.closest('[data-overlay-root]');
|
|
110
|
+
if(overlayRoot) overlayRoot.classList.toggle('no-scroll', this.fullscreen);
|
|
111
|
+
|
|
108
112
|
if(this.keyboardControls) {
|
|
109
113
|
if(this.fullscreen) {
|
|
110
114
|
document.addEventListener('keydown', this.handleKeydown);
|
|
@@ -872,5 +872,69 @@ export default {
|
|
|
872
872
|
}
|
|
873
873
|
|
|
874
874
|
pass('Container mounts into the [data-overlay-root] element');
|
|
875
|
+
},
|
|
876
|
+
|
|
877
|
+
/*
|
|
878
|
+
Scroll Lock Tests
|
|
879
|
+
*/
|
|
880
|
+
'should add no-scroll to body when opened': async ({pass, fail}) => {
|
|
881
|
+
const { container, viewer } = await createPhotoViewer();
|
|
882
|
+
|
|
883
|
+
viewer.open();
|
|
884
|
+
await viewer.updateComplete;
|
|
885
|
+
|
|
886
|
+
const hasClass = document.body.classList.contains('no-scroll');
|
|
887
|
+
viewer.close();
|
|
888
|
+
await viewer.updateComplete;
|
|
889
|
+
|
|
890
|
+
cleanup(container);
|
|
891
|
+
if(!hasClass){
|
|
892
|
+
fail('document.body should have no-scroll class when fullscreen');
|
|
893
|
+
return;
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
pass('document.body gets no-scroll class when opened');
|
|
897
|
+
},
|
|
898
|
+
|
|
899
|
+
'should remove no-scroll from body when closed': async ({pass, fail}) => {
|
|
900
|
+
const { container, viewer } = await createPhotoViewer({ fullscreen: true });
|
|
901
|
+
|
|
902
|
+
viewer.close();
|
|
903
|
+
await viewer.updateComplete;
|
|
904
|
+
|
|
905
|
+
const hasClass = document.body.classList.contains('no-scroll');
|
|
906
|
+
cleanup(container);
|
|
907
|
+
|
|
908
|
+
if(hasClass){
|
|
909
|
+
fail('document.body should not have no-scroll class when closed');
|
|
910
|
+
return;
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
pass('document.body loses no-scroll class when closed');
|
|
914
|
+
},
|
|
915
|
+
|
|
916
|
+
'should add no-scroll to the nearest [data-overlay-root] when opened': async ({pass, fail}) => {
|
|
917
|
+
const root = document.createElement('div');
|
|
918
|
+
root.setAttribute('data-overlay-root', '');
|
|
919
|
+
document.body.appendChild(root);
|
|
920
|
+
|
|
921
|
+
const viewer = document.createElement('k-photo-viewer');
|
|
922
|
+
root.appendChild(viewer);
|
|
923
|
+
await viewer.updateComplete;
|
|
924
|
+
|
|
925
|
+
viewer.open();
|
|
926
|
+
await viewer.updateComplete;
|
|
927
|
+
|
|
928
|
+
const hasClass = root.classList.contains('no-scroll');
|
|
929
|
+
viewer.close();
|
|
930
|
+
await viewer.updateComplete;
|
|
931
|
+
root.remove();
|
|
932
|
+
|
|
933
|
+
if(!hasClass){
|
|
934
|
+
fail('[data-overlay-root] should have no-scroll class when a descendant viewer is fullscreen');
|
|
935
|
+
return;
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
pass('[data-overlay-root] gets no-scroll class when opened');
|
|
875
939
|
}
|
|
876
940
|
};
|