Better resolution headshot, fullscreen modal for carousel, no fixed height and width on logo title for better resolution, spacing between dropdown entries in navbar

This commit is contained in:
2025-11-11 17:19:23 -08:00
parent c9f921ba5b
commit 7774e31c36
8 changed files with 70 additions and 30 deletions

View File

@@ -1,10 +1,21 @@
import {Carousel, type CarouselItem, type CarouselOptions, type IndicatorItem} from 'flowbite';
import {
Carousel,
type CarouselItem,
type CarouselInterface,
type CarouselOptions,
type IndicatorItem,
Modal,
type ModalInterface,
} from 'flowbite';
class CustomCarousel extends HTMLElement {
_slide: boolean;
_items: CarouselItem[];
_options: CarouselOptions;
_carousel: Carousel;
_carousel: CarouselInterface;
_modalEl: HTMLElement;
_modal: ModalInterface;
constructor() {
super();
@@ -16,6 +27,9 @@ class CustomCarousel extends HTMLElement {
if (this._slide && this._items.length > 0) this._carousel.cycle();
this._modalEl = this.querySelector('[data-custom-carousel-modal]') as HTMLElement || undefined;
this._modal = new Modal(this._modalEl);
window.addEventListener("load", this._attachHandlers);
}
@@ -24,8 +38,11 @@ class CustomCarousel extends HTMLElement {
let customItems = this.querySelectorAll('[data-custom-carousel-item]') || [];
return Array.from(customItems).map(
(item, index): CarouselItem => {
return {el: item as HTMLElement, position: index}
(item): CarouselItem => {
return {
el: item as HTMLElement,
position: Number(item.getAttribute("data-custom-carousel-item"))
}
}
)
}
@@ -52,29 +69,32 @@ class CustomCarousel extends HTMLElement {
}
}
_attachHandlers = (): void => {
// Controls
const carouselNextEl = this.querySelector(
// Carousel controls
this.querySelector(
'[data-custom-carousel-next]'
);
const carouselPrevEl = this.querySelector(
)?.addEventListener('click', () => this._carousel.next());
this.querySelector(
'[data-custom-carousel-prev]'
);
)?.addEventListener('click', () => this._carousel.prev());
if (carouselNextEl) {
carouselNextEl.addEventListener('click', () => {
this._carousel.next();
});
}
// Close fullscreen modal
this._modalEl.querySelector('[data-custom-carousel-modal-hide]')?.addEventListener('click', () => this._modal.hide())
if (carouselPrevEl) {
carouselPrevEl.addEventListener('click', () => {
this._carousel.prev();
});
}
// Click to open fullscreen modal
this._items.forEach((item) => {
item.el.addEventListener('click', () => {
const imgCloned = item.el.querySelector('img')?.cloneNode() as Node;
const imageDiv = this._modalEl.querySelector('[data-custom-carousel-modal-image]') as HTMLElement || undefined;
imageDiv.innerHTML = '';
imageDiv?.appendChild(imgCloned);
this._modal.show();
})
})
}
}
customElements.define('custom-carousel', CustomCarousel)