"Next" and "Previous" Buttons in Pluto

Another toy example, using JavaScript:

function Carousel(elementsList)
    carouselHTML = map(elementsList) do element
        @htl("""<div class="carousel-slide">
            $(element)
        </div>""")
    end
    @htl("""
<div>
    <style>
    .carousel-box{
        width: 100%;
        overflow: hidden;
    }
    .carousel-container{
        top: 0;
        left: 0;
        display: flex;
        width: 100%;
        flex-flow: row nowrap;
        transform: translate(0px, 0px);
        transition: transform 700ms;
    }
    .carousel-controls{
        display: flex;
        justify-content: center;
        align-items: center;
    }
    .carousel-controls button{
        margin: 8px;
        width: 7em;
    }
    .carousel-slide {
        min-width: 100%;
    }
    </style>
    <script>
        const div = currentScript.parentElement
        const buttons = div.querySelectorAll("button")
        let count = 0
        const onclick = (e) => {
            const max = $(length(elementsList))
            count = (count + parseInt(e.target.dataset.value)) % max;
            count = count < 0 ? max - 1 : count;
            div.querySelector(".carousel-container").style = `transform: translate(\${-count*100}%, 0px)`;
            div.value = count
            div.dispatchEvent(new CustomEvent("input"))
            e.preventDefault()
        }
        buttons.forEach(button => button.addEventListener("click", onclick))
        div.value = count
    </script>
    <div class="carousel-box">
        <div class="carousel-container">
            $(carouselHTML)
        </div>
    </div>
    <div class="carousel-controls">
        <button data-value="-1">Previous</button>
        <button data-value="1">Next</button>
    </div>
</div>
    """)

end

Then you can pass an array of pluto-showables and bind the index of the visible one!

@bind index Carousel([plot(sqrt.(1:1000)), plot(sqrt.(1:1000)), @htl("<div>test</div>"), md"> wow"])

Coming soon to a package near you (PlutoUI)!

4 Likes