Skip to content

Commit

Permalink
✨ 272 slider component (#357)
Browse files Browse the repository at this point in the history
* 272: add slider component

* 272: add slider component

* 272: format code

* 272: add emit and accessibility

* 272: format code

* 272: delete console log

* 272: disable vertical scroll

* 272: format code

* 272: change package-lock.json

* 💚 use fork of vue-splide to fix ts-errors

* replaced buttons with muc-buttons

* using templateRef to access ref

* using templateRef to access ref

* 272: pr feedback

* 272: format code

* 272: adjust package-lock.json

* 272: format code

* 272: rename SliderOptions.ts in MucSliderOptions.ts

---------

Co-authored-by: fabian.wilms <[email protected]>
Co-authored-by: langehm <[email protected]>
Co-authored-by: langehm <[email protected]>
  • Loading branch information
4 people authored Jan 8, 2025
1 parent 5333c35 commit d2b12b3
Show file tree
Hide file tree
Showing 8 changed files with 244 additions and 0 deletions.
16 changes: 16 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,5 +76,8 @@
"vite-plugin-dts": "4.4.0",
"vitest": "2.1.8",
"vue-tsc": "2.2.0"
},
"dependencies": {
"@splidejs/vue-splide": "github:joris-gallot/vue-splide"
}
}
39 changes: 39 additions & 0 deletions src/components/Slider/MucSlider.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import MucCard from "../Card/MucCard.vue";
import MucSlider from "./MucSlider.vue";
import MucSliderItem from "./MucSliderItem.vue";

export default {
components: { MucSliderItem, MucSlider },
component: MucSlider,
title: "MucSlider",
tags: ["autodocs"],
parameters: {
docs: {
description: {
component: `A wrapping layout to show elements in a carousel and slide them, for example [MucCards](/docs/muccard--docs).
🔗 Patternlab-Docs (https://patternlab.muenchen.space/?p=components-slider-quote)
`,
},
},
},
};

export const Template = () => ({
components: { MucCard, MucSlider, MucSliderItem },
template: `
<MucSlider>
<MucSliderItem v-for="index in 5" :key="index">
<MucCard
title="Lorem Ipsum"
tagline="Dolor"
>
<template #content>
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et
dolore magna aliquyam erat, sed diam voluptua.
</template>
</MucCard>
</MucSliderItem>
</MucSlider>
`,
});
130 changes: 130 additions & 0 deletions src/components/Slider/MucSlider.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
<template>
<div
class="m-component m-component-slider-comment"
style="overflow: hidden"
>
<div class="container">
<div class="m-component__grid">
<div class="m-component__column">
<section
class="m-slider m-slider--visible-preview"
aria-label="Slider mit Elementen"
data-m-slider-splide="m-slider-comment"
>
<button
v-if="showBackArrow"
aria-label="Vorheriges Element"
class="previous-button is-control"
@click="prevSlide"
>
<svg class="icon">
<use xlink:href="#icon-arrow-left"></use>
</svg>
</button>
<Splide
:options="mucSliderOptions"
aria-label="Dies ist ein Karussell mit rotierenden Elementen. Verwenden Sie
die Pfeiltaste links und rechts oder die Buttons um zu navigieren."
ref="splide"
>
<slot />
</Splide>
<button
v-if="showNextArrow"
aria-label="Nächstes Element"
class="next-button is-control"
@click="nextSlide"
>
<svg class="icon">
<use xlink:href="#icon-arrow-right"></use>
</svg>
</button>
</section>
</div>
</div>
</div>
</div>
</template>

<script setup lang="ts">
import { Splide } from "@splidejs/vue-splide";
import { computed, onMounted, ref, useTemplateRef } from "vue";
import { mucSliderOptions } from "./MucSliderOptions";
defineSlots<{
/**
* MucSliderItems can be put into this slot.
*/
default(): any;
}>();
const emit = defineEmits<{
/**
* Triggered when an item is clicked.
* @param id of the clicked item
*/
changeSlide: [index: number];
}>();
const splide = useTemplateRef("splide");
/**
* Index of the current silde
*/
const currentSlide = ref<number>(0);
/**
* Length of the splide
*/
const splideLength = ref<number>(0);
/**
* Set next slide
*/
const nextSlide = () => {
if (splide.value) {
splide.value.go(">");
}
};
/**
* Set previous slide
*/
const prevSlide = () => {
if (splide.value) {
splide.value.go("<");
}
};
/**
* Computed property set back button
*/
const showBackArrow = computed(() => currentSlide.value > 0);
/**
* Computed property set next button
*/
const showNextArrow = computed(
() => currentSlide.value < splideLength.value - 1
);
onMounted(() => {
if (splide.value && splide.value.splide) {
splideLength.value = splide.value.length;
splide.value.splide.on("move", () => {
if (splide.value) {
currentSlide.value = splide.value.splide!.index;
emit("changeSlide", splide.value.splide!.index);
}
});
}
});
</script>

<style scoped>
.m-component-slider-comment {
padding-right: 1.8rem;
padding-left: 1.8rem;
}
</style>
16 changes: 16 additions & 0 deletions src/components/Slider/MucSliderItem.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<template>
<SplideSlide>
<slot />
</SplideSlide>
</template>

<script setup lang="ts">
import { SplideSlide } from "@splidejs/vue-splide";
defineSlots<{
/**
* Elements can be put into this slot.
*/
default(): any;
}>();
</script>
33 changes: 33 additions & 0 deletions src/components/Slider/MucSliderOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import type { Options } from "@splidejs/splide";

export const mucSliderOptions: Options = {
autoplay: false,
keyboard: true,
slideFocus: true,
lazyLoad: false,
arrows: false,
perMove: 1,
gap: "0",
type: "slide",
perPage: 1,
pagination: false,
speed: 350,
drag: true,
swipe: true,
swipeThreshold: 50,
mediaQuery: "min",
breakpoints: {
1: {
perPage: 1,
gap: "1.5rem",
},
768: {
perPage: 1,
gap: "1.5rem",
},
1200: {
perPage: 1,
gap: "2rem",
},
},
};
4 changes: 4 additions & 0 deletions src/components/Slider/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import MucSlider from "./MucSlider.vue";
import MucSliderItem from "./MucSliderItem.vue";

export { MucSlider, MucSliderItem };
3 changes: 3 additions & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { MucIcon } from "./Icon";
import { MucIntro } from "./Intro";
import { MucLink } from "./Link";
import { MucPercentageSpinner } from "./PercentageSpinner";
import { MucSlider, MucSliderItem } from "./Slider";
import { MucStepper } from "./Stepper";

export {
Expand Down Expand Up @@ -48,4 +49,6 @@ export {
MucPercentageSpinner,
MucStepper,
MucCalendar,
MucSlider,
MucSliderItem,
};

0 comments on commit d2b12b3

Please sign in to comment.