- {/*
*/}
+
{name}
@@ -26,7 +26,7 @@ const Slide = ({ name }: { name: string }) => (
- {/*
*/}
+
Mentimeter
@@ -58,7 +58,31 @@ export default {
component: Slider,
args: {
children: slides,
- interval: 15000,
+ options: {
+ interval: 10000,
+ intervalIndicator: true,
+ controlPosition: "floating",
+ },
+ },
+};
+
+export const InlineControlPosition = {
+ args: {
+ options: {
+ interval: 10000,
+ intervalIndicator: true,
+ controlPosition: "inline",
+ },
+ },
+};
+
+export const WithoutIntervalIndicator = {
+ args: {
+ options: {
+ interval: 10000,
+ intervalIndicator: false,
+ controlPosition: "floating",
+ },
},
};
diff --git a/src/core/Slider/component.css b/src/core/Slider/component.css
index 79bed4c69..a2201db36 100644
--- a/src/core/Slider/component.css
+++ b/src/core/Slider/component.css
@@ -1,3 +1,10 @@
+.ui-slider-marker {
+ font-size: 0.5rem;
+ top: -1px;
+
+ @apply leading-none px-4 relative;
+}
+
@keyframes fillAnimation {
0% {
width: 0%;
@@ -6,3 +13,26 @@
width: 100%;
}
}
+
+.ui-icon-cta {
+ @apply w-48 h-48 cursor-pointer overflow-hidden;
+ @apply rounded border-2 border-mid-grey hover:border-active-orange;
+ transition: all 0.4s;
+}
+
+@screen md {
+ .ui-icon-cta-left:hover .ui-icon-cta-holder {
+ transform: translateX(-100%);
+ }
+ .ui-icon-cta-right .ui-icon-cta-holder {
+ transform: translateX(-100%);
+ }
+ .ui-icon-cta-right:hover .ui-icon-cta-holder {
+ transform: translateX(0%);
+ }
+}
+
+.ui-icon-cta-holder {
+ @apply w-full h-full;
+ transition: all 0.4s;
+}
diff --git a/src/core/Slider/component.js b/src/core/Slider/component.js
index e69de29bb..473eb5f28 100644
--- a/src/core/Slider/component.js
+++ b/src/core/Slider/component.js
@@ -0,0 +1,107 @@
+import "./component.css";
+
+import throttle from "lodash.throttle";
+
+import { queryId, queryIdAll } from "../dom-query";
+
+const mdBreakpoint = () => window.matchMedia("(min-width: 48rem)").matches;
+const DRAG_BUFFER = 20;
+
+const init = (slidesContainer) => {
+ const transformContainer = queryId("slider-strip", slidesContainer);
+ const slides = Array.from(queryIdAll("slider-slide", slidesContainer));
+ const slideLeftChevron = queryId("slider-previous", slidesContainer);
+ const slideRightChevron = queryId("slider-next", slidesContainer);
+ const slideMarkers = Array.from(queryIdAll("slider-marker", slidesContainer));
+ const sliderControls = queryId("slider-controls", slidesContainer);
+
+ sliderControls.classList.replace("hidden", "flex");
+ const slidesLength = slides.length;
+
+ const slidesWidth = slidesContainer.getBoundingClientRect().width;
+ const { width: slideWidth, left: slideLeftDistance } =
+ slides[0].getBoundingClientRect();
+ const { left: slideLeftDistanceSecond } = slides[1].getBoundingClientRect();
+ const slideGap = slideLeftDistanceSecond - slideLeftDistance - slideWidth;
+ const adjustment = (slidesWidth - slideWidth) / 2;
+
+ let currentIndex = 0;
+ let touchStartX = 0;
+
+ const calculateTransform = (index) =>
+ index * -slideWidth + adjustment + index * -slideGap;
+
+ const updateSlide = (index) =>
+ (transformContainer.style.transform = `translateX(${calculateTransform(
+ index
+ )}px)`);
+
+ const updateMarkers = (index) => {
+ slideMarkers.forEach((marker) =>
+ marker.classList.remove("text-active-orange")
+ );
+ slideMarkers[index].classList.remove("text-cool-black");
+ slideMarkers[index].classList.add("text-active-orange");
+ };
+
+ const slideLeft = () => {
+ currentIndex = currentIndex - 1 <= 0 ? 0 : currentIndex - 1;
+ updateSlide(currentIndex);
+ updateMarkers(currentIndex);
+ };
+
+ const slideRight = () => {
+ currentIndex =
+ currentIndex + 1 >= slidesLength ? currentIndex : currentIndex + 1;
+ updateSlide(currentIndex);
+ updateMarkers(currentIndex);
+ };
+
+ updateSlide(0);
+ updateMarkers(0);
+
+ slideLeftChevron.addEventListener("click", slideLeft);
+
+ transformContainer.addEventListener("touchstart", (e) => {
+ touchStartX = e.touches[0]?.clientX;
+ });
+
+ transformContainer.addEventListener("touchend", (e) => {
+ const distance = e.changedTouches[0]?.clientX - touchStartX;
+
+ // Prevent sliding on clicks
+ if (Math.abs(distance) < DRAG_BUFFER) return;
+
+ const direction = distance > 0 ? slideLeft : slideRight;
+ direction();
+ });
+
+ slideRightChevron.addEventListener("click", slideRight);
+
+ return () => {
+ transformContainer.style.transform = null;
+ sliderControls.classList.replace("flex", "hidden");
+ };
+};
+
+const Slider = ({ container, mqEnableThreshold }) => {
+ if (!container) return;
+
+ const breakpointCheck = mqEnableThreshold || (() => !mdBreakpoint());
+
+ let unmount = () => {};
+ if (breakpointCheck()) unmount = init(container);
+
+ window.addEventListener(
+ "resize",
+ throttle(() => {
+ if (breakpointCheck()) {
+ unmount = init(container);
+ } else {
+ unmount();
+ }
+ }, 100)
+ );
+};
+
+export default Slider;