Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lightbox Component #44

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions src/lightbox/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<!doctype html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Web Component: Lightbox Gallery</title>

<link rel="stylesheet" href="../../dist/lightbox/style.css" media="all">
<script type="module" src="../../dist/lightbox/index.js"></script>

<style>
</style>
</head>

<body>
<main>
<tp-lightbox-trigger>
<button type="button">Default gallery</button>
<template>
<div style="height:400px;width:400px;background-color:#d864d8;">
</div>
</template>
</tp-lightbox-trigger>
<tp-lightbox-trigger>
<button type="button">Default gallery 2</button>
<template>
<div style="height:400px;width:400px;background-color:#ff0000;">
</div>
</template>
</tp-lightbox-trigger>
<tp-lightbox-trigger gallery-id="my_gallery">
<button type="button">My gallery</button>
<template>
<div style="height:400px;width:400px;background-color:pink;">
</div>
</template>
</tp-lightbox-trigger>
<tp-lightbox-trigger gallery-id="my_gallery">
<button type="button">My gallery 2</button>
<template>
<div style="height:400px;width:400px;background-color:green;">
</div>
</template>
</tp-lightbox-trigger>
</main>
</body>

</html>
32 changes: 32 additions & 0 deletions src/lightbox/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* Styles.
*/
import './style.scss';

/**
* Components
*/
import { TPLightboxElement } from './tp-lightbox';
import { TPLightboxTriggerElement } from './tp-lightbox-trigger';
import { TPLightboxGalleryElement } from './tp-lightbox-gallery';
import { TPLightboxSliderTrackElement } from './tp-lightbox-slider-track';
import { TPLightboxSliderElement } from './tp-lightbox-slider';
import { TPLightboxSlideElement } from './tp-lightbox-slide';
import { TPLightboxNavElement } from './tp-lightbox-nav';
import { TPLightboxNavButtonElement } from './tp-lightbox-nav-button';
import { TPLightboxCounterElement } from './tp-lightbox-counter';
import { TPLightboxCloseElement } from './tp-lightbox-close';

/**
* Register Components
*/
customElements.define( 'tp-lightbox', TPLightboxElement );
customElements.define( 'tp-lightbox-trigger', TPLightboxTriggerElement );
customElements.define( 'tp-lightbox-gallery', TPLightboxGalleryElement );
customElements.define( 'tp-lightbox-slider-track', TPLightboxSliderTrackElement );
customElements.define( 'tp-lightbox-slider', TPLightboxSliderElement );
customElements.define( 'tp-lightbox-slide', TPLightboxSlideElement );
customElements.define( 'tp-lightbox-nav', TPLightboxNavElement );
customElements.define( 'tp-lightbox-nav-button', TPLightboxNavButtonElement );
customElements.define( 'tp-lightbox-counter', TPLightboxCounterElement );
customElements.define( 'tp-lightbox-close', TPLightboxCloseElement );
34 changes: 34 additions & 0 deletions src/lightbox/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
tp-lightbox {

@keyframes fade-in {
to {
opacity: 1;
}
}

&-gallery {
display: none;

&[open] {
display: block;
position: fixed;
inset: 0;
background-color: rgba(0, 0, 0, 0.9);
}
}

&-close {
display: block;
position: absolute;
inset: 5px 10px auto auto;
height: fit-content;
width: fit-content;

&::before {
content: "\00d7";
color: #fff;
font-size: 2.5rem;
font-weight: 400;
}
}
}
20 changes: 20 additions & 0 deletions src/lightbox/tp-lightbox-close.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { TPLightboxGalleryElement } from './tp-lightbox-gallery';

/**
* TP Lightbox Close
*/
export class TPLightboxCloseElement extends HTMLElement {
/**
* Connected Callback
*/
connectedCallback() {
this.addEventListener( 'click', this.handleClick.bind( this ) );
}

/**
* Handle Click
*/
handleClick() {
this.closest<TPLightboxGalleryElement>( 'tp-lightbox-gallery' )?.close();
}
}
6 changes: 6 additions & 0 deletions src/lightbox/tp-lightbox-counter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* TP Lightbox Counter
*/
export class TPLightboxCounterElement extends HTMLElement {

}
90 changes: 90 additions & 0 deletions src/lightbox/tp-lightbox-gallery.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/**
* TP Lightbox Gallery
*/
export class TPLightboxGalleryElement extends HTMLElement {
/**
* Properties
*/
private galleryID: string | null;
private numSlides: number;
private currentSlide: number;

/**
* Constructor
*/
constructor() {
super();

this.galleryID = this.getAttribute( 'gallery-id' );
this.numSlides = 0;
this.currentSlide = 0;
}

/**
* Connected callback
*/
connectedCallback() {
const innerElements = [
document.createElement( 'tp-lightbox-counter' ),
document.createElement( 'tp-lightbox-close' ),
document.createElement( 'tp-lightbox-slider' ),
];

if ( null !== this.galleryID ) {
const prevBtn = document.createElement( 'tp-lightbox-nav-button' );
const nextBtn = document.createElement( 'tp-lightbox-nav-button' );
prevBtn.setAttribute( 'direction', 'prev' );
nextBtn.setAttribute( 'direction', 'next' );

innerElements.push( prevBtn, nextBtn );
}

innerElements.forEach( ( innerElement ) => this.appendChild( innerElement ) );

this.addEventListener( 'click', this.handleClick.bind( this ) );
}

/**
* Adds slide
*
* @param { HTMLElement | undefined } slideContent
*/
addSlide( slideContent: HTMLElement | undefined ): number | undefined {
if ( ! slideContent ) {
return undefined;
}

const slideElement = document.createElement( 'tp-lightbox-slide' );
slideElement.appendChild( slideContent );

this.querySelector( 'tp-lightbox-slider' )?.appendChild( slideElement );

this.numSlides++;

return this.numSlides;
}

// Open the lightbox gallery.
open( slideIndex: number | undefined ) {
if ( ! slideIndex ) {
return;
}

this.currentSlide = slideIndex;
this.setAttribute( 'current-slide', this.currentSlide.toString() );
this.setAttribute( 'open', '' );
this.dispatchEvent( new CustomEvent( 'open', { bubbles: false } ) );
}

// Close the lightbox gallery.
close() {
this.removeAttribute( 'open' );
this.dispatchEvent( new CustomEvent( 'close', { bubbles: false } ) );
}

handleClick( e: Event ) {
if ( e.target === this ) {
this.close();
}
}
}
6 changes: 6 additions & 0 deletions src/lightbox/tp-lightbox-nav-button.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* TP Lightbox Nav Button
*/
export class TPLightboxNavButtonElement extends HTMLElement {

}
6 changes: 6 additions & 0 deletions src/lightbox/tp-lightbox-nav.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* TP Lightbox Nav
*/
export class TPLightboxNavElement extends HTMLElement {

}
6 changes: 6 additions & 0 deletions src/lightbox/tp-lightbox-slide.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* TP Lightbox Slide
*/
export class TPLightboxSlideElement extends HTMLElement {

}
6 changes: 6 additions & 0 deletions src/lightbox/tp-lightbox-slider-track.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* TP Lightbox Slider Track
*/
export class TPLightboxSliderTrackElement extends HTMLElement {

}
38 changes: 38 additions & 0 deletions src/lightbox/tp-lightbox-slider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { TPLightboxGalleryElement } from './tp-lightbox-gallery';
import { TPLightboxTriggerElement } from './tp-lightbox-trigger';

/**
* TP Lightbox Slider
*/
export class TPLightboxSliderElement extends HTMLElement {
/**
* Connected callback
*/
connectedCallback() {
const gallery = this.closest( 'tp-lightbox-gallery' ) as TPLightboxGalleryElement;

if ( ! gallery ) {
return;
}

const galleryID = gallery.getAttribute( 'gallery-id' );

let triggerQuery = 'tp-lightbox-trigger';

if ( ! galleryID ) {
triggerQuery += ':not([gallery-id])';
} else {
triggerQuery += `[gallery-id="${ galleryID }"]`;
}

const triggers = Array.from( document.querySelectorAll<TPLightboxTriggerElement>( triggerQuery ) );

triggers.forEach( ( trigger ) => {
const slideIndex = gallery.addSlide( trigger.lightboxContentTemplate?.content.cloneNode( true ) as HTMLElement );

if ( slideIndex ) {
trigger.setAttribute( 'slide-index', slideIndex.toString() );
}
} );
}
}
Loading
Loading