import Foundation /** An element showing a selection of images one by one using navigation buttons. */ struct ImageGallery: HtmlProducer { /// The unique id to distinguish different galleries in HTML and JavaScript let id: String /// The images to display let images: [ImageSet] /// A version of the id that is safe to use in HTML and JavaScript private var htmlSafeId: String { ImageGallery.htmlSafe(id) } init(id: String, images: [ImageSet]) { self.id = id self.images = images } func populate(_ result: inout String) { guard !images.isEmpty else { return } result += "
" let needsPagination = images.count > 1 for image in images { let sizeText = image.image.getImageDimensions().map { " style='aspect-ratio: \(Int($0.width)) / \(Int($0.height))'"} result += "
" result += image.content if needsPagination { result += "
" } result += "
" // Close swiper-slide } result += "
" // Close swiper-wrapper if needsPagination { result += "
" result += "
" result += "
" } result += "
" // Close swiper } private static func htmlSafe(_ id: String) -> String { id.replacingOccurrences(of: "-", with: "_") } static func swiperInit(id: String) -> String { let id = htmlSafe(id) return """ var swiper_\(id) = new Swiper("#\(id)", { loop: true, lazy: { loadPrevNext: false, }, slidesPerView: 1, spaceBetween: 30, centeredSlides: true, keyboard: { enabled: true }, pagination: { el: "#\(id) .swiper-pagination", clickable: true }, navigation: { nextEl: "#\(id) .swiper-button-next", prevEl: "#\(id) .swiper-button-prev" } }); """ } } /* extension ImageGallery: HTML { var content: some HTML { div(.id(id), .class("swiper")) { div(.class("swiper-wrapper")) { for image in images { div(.class("swiper-slide")) { // TODO: Use different images based on device img(.src(image.mainImageUrl), .lazyLoad) div(.class("swiper-lazy-preloader"), .class("swiper-lazy-preloader-white")) { } } } } div(.class("swiper-button-next")) { } div(.class("swiper-button-prev")) { } div(.class("swiper-pagination")) { } } } } */