@rat.md/bs-lightbox
A simple and ease-to-use Lightbox system build on top of Bootstrap's native Carousel and Modal JavaScript components. bs-lightbox is compatible with Bootstrap v4 and Bootstrap v5.
Getting Started
Our bs-lightbox package depends on the Bootstrap CSS and JS framework, especially the Carousel and Modal components. Since this package does not provide a bundled version you've to ensure yourself that the Bootstrap framework is added to your HTML document and loaded BEFORE the bs-lightbox JavaScript.
bs-lightbox does also not provide any stylings or stylesheets but uses and depends on the Bootstrap native CSS components and utility classes. You don't have to worry, when you're using the already bundled distribution files - provided on getbootstrap.com. Only if you're using the Bootstrap source files, you've to make sure, that the default utility classes as well as the Carousel and Modal components are loaded and included in your bundled stylesheet.
Requirements
bs-lightbox has been especially designed for Bootstrap v5 and provides a working backward compatibility to Bootstrap v4. Older versions of Bootstrap may work with this plugin, but aren't supported nor tested.
Installation
You can download and embed the latest bs-lightbox version on the official GitHub Repository. Otherwise you can also use node.js and NPM, to include this package in your bundle / stack.
npm i @rat.md/bs-lightbox
            Basic Usage
You can use bs-lightbox similar to many other different JavaScript packages. The following example code shows how to load and invoke the UMD bundle in the most basic way.
<html>
<head>
    <link href="/bs-lightbox/assets/css/bootstrap.min.css" />
</head>
<body>
    <script src="/bs-lightbox/assets/js/bootstrap.bundle.min.js"></script>
    <script src="/bs-lightbox/assets/js/rat.lightbox.min.js"></script>
    <script>
        document.addEventListener('DOMContentLoaded', () => {
            rat.Lightbox.invoke();
        });
    </script>
</body>
</html>
            
                The rat.Lightbox.invoke() method will fetch all supported elements, which has either 
                the data-bs-toggle="lightbox", data-toggle="lightbox" or data-rat-lightbox
                attribute on it. However, you can also pass your own selector string to the .invoke method, or pass 
                your options as second parameter (Read more about the Configurations here).
            
document.addEventListener('DOMContentLoaded', () => {
// Invoke using a custom selector
rat.Lightbox.invoke('[data-custom-lightbox]');
// Invoke using custom configuration and the default selector
rat.Lightbox.invoke(null, {
    carousel: {
        ride: true
    },
    modal: {
        size: 'fullscreen'
    }
});
});
            
                bs-lightbox will create a new Lightbox instance for each image, unless the items 
                are grouped using the data-bs-gallery or data-gallery attribute, 
                as described here. You can also add new images using the 
                getOrCreateInstance or the Lightbox constructor method itself. However, we 
                recommend using getOrCreateInstance to keep the gallery grouping alive and prevent 
                throwing errors on images, which are already included in a Lightbox or Lightbox Set. 
            
document.addEventListener('DOMContentLoaded', () => {
let element = document.querySelector('img.some-special-image');
// Creates a new Lightbox, or throws an Error when the image 
// is already included in another Lightbox.
let lightbox = new rat.Lightbox(element, /* Custom Configuration */);
// Create a new Lightbox or returns an existing Lightbox 
// Appends the image on grouped lightbox instances
let lightbox = rat.Lightbox.getOrCreateInstance(element);
});
            
            Usage & Examples
                bs-lightbox uses the data-bs-toggle="lightbox" (alternatively also data-toggle="lightbox"
                or data-rat-lightbox) attribute to find the nearest <picture /> or 
                <img /> element (which must either the linked one or one of it's children). Thus, the most 
                basic way to add a lightbox to your image is by following the syntax below. However, bs-lightbox
                does also support sightly different variations, as described in the chapter below.
            
<picture /> or <img />
                Element has been found, bs-lightbox will deep-clone the whole node and remove the class names on the 
                main element ... and only on the main element. So, if you've a picture > img construct, you should style your 
                <picture /> element and set the height / width of the child <img /> node to 100%.
            
                    
                        Even if the pictures above aren't linked, you're still able to click on them to open the Lightbox.
<div class="mb-3 d-flex justify-content-center">
<img src="/bs-lightbox/assets/imgs/demo-4.jpg" data-toggle="lightbox" class="w-25 d-block" />
</div>
<div class="mb-3 d-flex justify-content-center">
<picture data-toggle="lightbox" class="w-25 d-block">
    <img src="/bs-lightbox/assets/imgs/demo-5.jpg" class="w-100" />
</picture>
</div>
<p class="text-muted mt-5">
...
</p>
            Supported Variations
bs-lightbox also supports different formatting variations, which allows to change the image shown on the modal-carousel and also to add an optional title or caption.
Simple Link
                Using a link as parent element allows to change the URL on an <img /> element, 
                for example to provide a higher resolution version of the same (or a different) image. This does NOT 
                work when using a <picture /> element - in this case you should rely on the HTML native 
                <source> 
                element.
            
                    
                    
                    
                        
                        Both links above point to the opposite picture, however just the first one works due to the <img /> element.
<a href="/bs-lightbox/assets/imgs/demo-5.jpg" class="mb-3 d-flex justify-content-center" data-toggle="lightbox">
<img src="/bs-lightbox/assets/imgs/demo-4.jpg" class="w-25 d-block" />
</a>
<a href="/bs-lightbox/assets/imgs/demo-4.jpg" class="mb-3 d-flex justify-content-center" data-toggle="lightbox">
<picture class="w-25 d-block">
    <img src="/bs-lightbox/assets/imgs/demo-5.jpg" class="w-100" />
</picture>
</a>
<p class="text-muted mt-5">
...
</p>
            Title & Caption
                Since bs-lightbox using the official Bootstrap Carousel component, you can also add an own title 
                and caption to the respective image. Just add the data-bs-title / data-bs-caption attributes 
                or their alternative version data-title / data-caption on the desired picture.
            
<a href="/bs-lightbox/assets/imgs/demo-5.jpg" class="mb-3 d-flex justify-content-center" 
data-toggle="lightbox" data-title="Title" data-caption="Caption">
<img src="/bs-lightbox/assets/imgs/demo-4.jpg" class="w-25 d-block" />
</a>
<a href="/bs-lightbox/assets/imgs/demo-4.jpg" class="mb-3 d-flex justify-content-center" data-toggle="lightbox">
<picture class="w-25 d-block" data-title="Title" data-caption="Caption">
    <img src="/bs-lightbox/assets/imgs/demo-5.jpg" class="w-100" />
</picture>
</a>
<p class="text-muted mt-5">
...
</p>
            Figure & Figcaption
                Alternatively to the data-attributes above, you can also use the <figure> and 
                <figcaption> elements, which allows to show the caption outside the Lightbox as well.
            
                        
                        <figure class="figure" data-toggle="lightbox" data-title="Title">
<img src="/bs-lightbox/assets/imgs/demo-4.jpg" class="w-25 d-block figure-img" />
<figcaption>Caption</figcaption>
</figure>
<figure class="figure" data-toggle="lightbox" data-title="Title">
<picture class="w-25 d-block figure-img">
    <img src="/bs-lightbox/assets/imgs/demo-5.jpg" class="w-100" />
</picture>
<figcaption>Caption</figcaption>
</figure>
            Lightbox Gallery
                A Lightbox / Carousel without the possibility to collect and slide through a bunch of pictures 
                is absolutely useless. Thus, bs-lightbox provides the s-gallery 
                (or alternatively data-gallery) attribute, which allows to group different pictures 
                all over the whole document and shows them all together. 
            
<div class="row">
<div class="col-4 p-2">
    <a href="/bs-lightbox/assets/imgs/demo-1.png" data-toggle="lightbox" data-gallery="example" class="d-block">
        <img src="/bs-lightbox/assets/imgs/demo-1.png" class="w-100 rounded-2" />
    </a>
</div>
<div class="col-4 p-2">
    <a href="/bs-lightbox/assets/imgs/demo-2.png" data-toggle="lightbox" data-gallery="example" class="d-block">
        <img src="/bs-lightbox/assets/imgs/demo-2.png" class="w-100 rounded-2" />
    </a>
</div>
<div class="col-4 p-2">
    <a href="/bs-lightbox/assets/imgs/demo-3.png" data-toggle="lightbox" data-gallery="example" class="d-block">
        <img src="/bs-lightbox/assets/imgs/demo-3.png" class="w-100 rounded-2" />
    </a>
</div>
</div>
            Configuration
                bs-lightbox gives you the full control over the used Carousel and Modal instances,
                just pass the desired options as second parameter on the Lightbox constructor, the  
                recommended getOrCreateInstance or the general invoke method.
            
rat.Lightbox.invoke(
null,       // Use default selector string
{
    lightbox: {
        loader: false,
        replacePictures: false
    },
    carousel: {
        id: null,
        controls: true,
        indicators: false,
        interval: 5000,
        keyboard: false,
        pause: 'hover',
        ride: false,
        touch: true,
        wrap: true
    },
    modal: {
        id: null,
        backdrop: true,
        focus: true,
        keyboard: true,
        size: 'xl'
    }
}
);
            Lightbox Options
The following options are available since version 1.1.0 and are aimed to configure the Lightbox environment itself.
| Option | Type | Default | Description | 
|---|---|---|---|
| loader | boolean | 
                        false | 
                        Shows an spinner and preloads the images inside the Lightbox Carousel in the background. | 
| replacePictures | boolean | 
                        false | 
                        
                            The default option will only replace the image source on <img /> elements, 
                            when the lightbox is introduced on an <a> tag. Enabling this option will a
                            also replace <picture> elements with an <img /> tag.
                         | 
                    
Carousel Options
You may recognize a few of the available Carousel options from the official Bootstrap documentation.
| Option | Type | Default | Description | 
|---|---|---|---|
| id | string | 
                        "lightboxCarousel" | 
                        Set a custom id value for the carousel element. | 
| controls | boolean | 
                        true | 
                        Whether the carousel control action buttons, for sliding to the next or previous item, should be shown or not. When only one slide is available, the control buttons will be hidden regardless of this value. | 
| indicators | boolean | 
                        false | 
                        Whether the carousel indicator buttons should be shown or not. When only one slide is available, the indicator buttons will be hidden regardless of this value. | 
| interval | number | 
                        5000 | 
                        The amount of time in milliseconds to delay between automatically cycling an item. | 
| keyboard | boolean | 
                        true | 
                        Whether the carousel should react to keyboard events or not (left / right button). | 
| pause | boolean"hover" | 
                        "hover" | 
                        Whether the carousel should pause on mouse and touch-events or not. | 
| ride | boolean"carousel" | 
                        false | 
                        
                            Whether the carousel should autoplay or not. "carousel" starts the 
                            autoplay of the carousel automatically, using true will autoplay 
                            after the user manually cycles the first item, false disables the 
                            autoplay completely.
                         | 
                    
| touch | boolean | 
                        true | 
                        Whether the carousel should support left/right swipe interactions on touchscreen devices. | 
| wrap | boolean | 
                        true | 
                        Whether the carousel should cycle continuously or have hard stops | 
Modal Options
You may recognize a few of the available Modal options from the official Bootstrap documentation.
| Option | Type | Default | Description | 
|---|---|---|---|
| id | string | 
                        "lightboxModal" | 
                        Set a custom id value for the lightbox modal. | 
| backdrop | boolean"static" | 
                        true | 
                        
                            Includes a modal-backdrop element. Alternatively, specify static for a backdrop 
                            which doesn't close the modal when clicked.
                         | 
                    
| focus | boolean | 
                        true | 
                        Puts the focus on the modal when initialized. | 
| keyboard | boolean | 
                        true | 
                        Closes the modal when escape key is pressed. | 
| size | string | 
                        "xl" | 
                        
                            Sets the size of the modal, supports the following sizes: 
                            "sm", "md", "lg", "xl" and  "fullscreen"
                         | 
                    
Methods
The current version of bs-lightbox provides the following Methods.
Lightbox.invoke()
Signaturerat.Lightbox.invoke(selector: null|string = null, config: object = {}): Lightbox[]
            
                Invokes the Lightbox instances on all capable elements within the current DOM. This method supports 
                2 optional parameters: selector allows to change the default selector string used to 
                find valid Lightbox candidates, config allows to override the default set of options to 
                configure each single Lightbox instance.
            
Lightbox.hasInstance()
Signaturerat.Lightbox.hasInstance(data: HTMLElement|string): boolean
            Checks if the passed HTMLElement or gallery string identifier has already been invoked within a Lightbox instance. Attention: This method does NOT verify if the passed HTMLElement is or could be a valid Lightbox candidate, it just checks if an instance has been assigned with it.
Lightbox.getInstance()
Signaturerat.Lightbox.getInstance(data: HTMLElement|string): Lightbox|null
            
                Receive an already invoked Lightbox instance using the respective HTMLElement or a gallery string 
                identifier. This method returns null if the passed argument is not assigned with a 
                Lightbox instance. Attention: This method does NOT verify if the passed HTMLElement is or 
                could be a valid Lightbox candidate, it just checks if an instance has been assigned with it.
            
Lightbox.getOrCreateInstance()
Signaturerat.Lightbox.getOrCreateInstance(element: HTMLElement, config: object: = {}): Lightbox
            
                Receive or create a new Lightbox instance, based on the desired HTMLElement. The second parameter 
                config is only used when this method invokes a new Lightbox instance, the options of 
                existing Lightbox instances stay the same. When the element has a gallery string identifier - which 
                has already been invoked - the element will be appended to this instance.
            
Lightbox.constructor()
Signaturerat.Lightbox.constructor(element: HTMLElement, config: object: = {}): Lightbox
            
                Create a new Lightbox instance. This method will throw an Error, when the passed element 
                is already be part of an Lightbox instance. We recommend using getOrCreateInstance to 
                prevent this.
            
<lightbox>.dispose()
            Signature
            rat.Lightbox.dispose(): Lightbox
            
                Destroys the Carousel and Modal bootstrap instances - by calling their own dispose
                method, and will clear the core Lightbox element. The Lightbox instance itself stays available, 
                with all configurations and native event listeners. This method is used internally, when an open 
                Lightbox closes.
            
<lightbox>.append()
            Signature
            rat.Lightbox.append(source: HTMLElement): Lightbox
            
                Appends a new image to the same Lightbox instance. This method checks if the passed HTMLElement 
                is a valid Lightbox candidate, if not it throws an error. Using append allows to 
                create Lightbox galleries, and is used internally by the getOrCreateInstance method.
            
<lightbox>.toggle()
            Signature
            rat.Lightbox.toggle(): Lightbox
            
                Calls the .show() or .hide() method, depending if the Lightbox is 
                currently shown or not.
            
<lightbox>.show()
            Signature
            rat.Lightbox.show(): Lightbox
            Creates the Lightbox modal HTML structure, applies the Modal and Carousel instances, binds all native as well as custom events, adds this whole construct to the DOM and starts the modal itself. This method does nothing, when the Lightbox Modal is already available.
<lightbox>.hide()
            Signature
            rat.Lightbox.hide(): Lightbox
            Simple hides the Lightbox modal, when available, otherwise does nothing.
<lightbox>.cycle()
            Signature
            rat.Lightbox.cycle(): Lightbox
            
                Calls the .cycle() method on the Carousel instance, when available.
            
<lightbox>.next()
            Signature
            rat.Lightbox.next(): Lightbox
            
                Calls the .next() method on the Carousel instance, when available.
            
<lightbox>.prev()
            Signature
            rat.Lightbox.prev(): Lightbox
            
                Calls the .prev() method on the Carousel instance, when available.
            
<lightbox>.to()
            Signature
            rat.Lightbox.to(direction: number|string): Lightbox
            
                Allows to slide to a specific position within the Carousel instance. direction 
                can either be an exact slide number (starting from 0) or one of the following strings: 
                "next", "prev" or "previous".
            
<lightbox>.on()
            Signature
            rat.Lightbox.on(event: string, caller: Function): Lightbox
            
                Attach an event listener to the modal or carousel. Currently supported events are: 
                "slid.bs.carousel", "slide.bs.carousel", "hide.bs.modal", "hidden.bs.modal", "show.bs.modal" and
                "shown.bs.modal". The event listener is stored internally and attached every time, when then 
                Lightbox' .show() method is called.
            
<lightbox>.off()
            Signature
            rat.Lightbox.off(event: string, caller: Function): Lightbox
            
                Removes an event listener (as attached by the own .on() method) and detach it from 
                the Carousel or Modal instance when the Lightbox is currently shown.
            
Events
                The current version of bs-lightbox does not provide own events, however using the 
                .on() method allows you to attach all available, Bootstrap-native Carousel and Modal 
                events as described below.
            
| Event | Description | 
|---|---|
slid.bs.carousel | 
                        Fired when the carousel has completed its slide transition. | 
slide.bs.carousel | 
                        Fires immediately when the Carousel slide instance method is invoked. | 
                    
hide.bs.modal | 
                        This event is fired immediately when the hide instance method has been called. | 
                    
hidden.bs.modal | 
                        This event is fired when the modal has finished being hidden from the user (will wait for CSS transitions to complete). | 
hidePrevented.bs.modal | 
                        This event is fired when the modal is shown, its backdrop is static and a click outside of the modal is performed. The event is also fired when the escape key is pressed and the keyboard option is set to false. | 
                    
show.bs.modal | 
                        This event fires immediately when the show instance method is called. If caused by a click, the clicked element is available as the relatedTarget property of the event. | 
                    
shown.bs.modal | 
                        This event is fired when the modal has been made visible to the user (will wait for CSS transitions to complete). If caused by a click, the clicked element is available as the relatedTarget property of the event. |