This is the template project that's checked out and configured when you run the bando-up command from ljsthw-bandolier. This is where the code really lives.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
bandolier-template/client/components/Carousel.svelte

108 lines
2.0 KiB

<script>
import Icon from '$/client/components/Icon.svelte';
import { createEventDispatcher } from "svelte";
export let panels = [];
export let selected = {};
const dispatch = createEventDispatcher();
/* So dumb, but gotta do it. */
const current_index = () => {
for(let i = 0; i < panels.length; i++) {
if(panels[i].active) return i;
}
return 0;
}
const activate = (index) => {
panels = panels.map((x, i) => {
x.active = i == index;
if(x.active) selected = x;
return x;
});
dispatch("select", {index, selected});
}
const next = () => {
let i = current_index();
activate((i + 1) % panels.length);
}
const prev = () => {
let i = current_index();
activate((i - 1) < 0 ? panels.length -1 : i - 1);
}
</script>
<style>
carousel {
position: relative;
display: flex;
flex-direction: column;
flex: flex-grow;
}
carousel panel {
display: none;
}
carousel panel.active {
display: flex;
position: relative;
flex-direction: column;
}
carousel panel caption {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
text-align: center;
font-size: 2em;
background: var(--color-bg-secondary);
opacity: 0%;
}
carousel caption:hover {
opacity: 90%;
}
carousel next,
carousel prev {
position: absolute;
top: 0;
bottom: 0;
opacity: 60%;
display: flex;
flex-direction: column;
align-content: center;
justify-content: center;
}
carousel next {
right: 0;
}
carousel prev {
left: 0;
}
carousel next:hover,prev:hover {
opacity: 60%;
background-color: var(--color-bg);
}
</style>
<carousel>
{#each panels as panel}
<panel class:active={ panel.active }>
<svelte:component this={panel.component} {...panel.props} />
<caption>{ panel.caption }</caption>
</panel>
{/each}
<prev on:click={ prev }><Icon name="arrow-left" size="48" /></prev>
<next on:click={ next }><Icon name="arrow-right" size="48" /></next>
</carousel>