Skip to content

Commit

Permalink
chore: rename old slider
Browse files Browse the repository at this point in the history
  • Loading branch information
aleksandar-r committed Apr 1, 2024
1 parent 7d35cb3 commit 61cbcf8
Show file tree
Hide file tree
Showing 4 changed files with 270 additions and 0 deletions.
45 changes: 45 additions & 0 deletions src/core/SliderOld/Slider.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React, { ReactNode } from "react";
import Slider from "./component.tsx";

export default {
title: "Components/Slider-Old",
component: Slider,
parameters: {
layout: "fullscreen",
},
tags: ["autodocs"],
};

const Slide = ({ children }: { children: ReactNode }) => (
<div className="h-full p-24 bg-white rounded">
<p className="ui-text-p2 text-center">{children}</p>
</div>
);

const slides = [
<Slide key="1">
Powers live chat, updates, analytics, and composition for millions of users.
</Slide>,
<Slide key="2">
Powers virtual venues for millions of event attendees around the world.
</Slide>,
<Slide key="3">
Provides 5 million daily users with live financial commentary and stock
tickers.
</Slide>,
<Slide key="4">Monitors live car performance data across the USA.</Slide>,
];

export const SliderOnAllBreakpoints = {
args: {
slides,
},
};

export const SliderOnSmallBreakpointOnly = {
args: {
slides,
classes: `sm:grid-cols-${slides.length / 2} md:grid-cols-${slides.length}`,
mqEnableThreshold: () => !window.matchMedia("(min-width: 48rem)").matches,
},
};
6 changes: 6 additions & 0 deletions src/core/SliderOld/component.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.ui-slider-marker {
font-size: 0.5rem;
top: -1px;

@apply leading-none px-4 relative;
}
107 changes: 107 additions & 0 deletions src/core/SliderOld/component.js
Original file line number Diff line number Diff line change
@@ -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;
112 changes: 112 additions & 0 deletions src/core/SliderOld/component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import React, { CSSProperties, ReactNode, useEffect, useRef } from "react";

import Icon from "../Icon/component.tsx";
import SliderScripts from "./component.js";
import "./component.css";

type SliderProps = {
slides?: ReactNode[];
classes?: string;
slideClasses?: string;
slideMinWidth?: string;
slideMaxWidth?: string;
mqEnableThreshold?: () => boolean;

container?: HTMLDivElement | null;
};

const Slider = ({
slides = [],
classes = "",
slideClasses = "",
slideMinWidth = "16.875rem",
slideMaxWidth = "1fr",
mqEnableThreshold = () => true,
...props
}: SliderProps) => {
const containerRef = useRef<HTMLDivElement>(null);

useEffect(() => {
SliderScripts({
container: containerRef.current,
mqEnableThreshold,
});
}, []);

if (slides.length === 0) return;

return (
<div
className="w-full overflow-x-hidden"
data-id="slider"
style={
{
"--dynamic-grid-columns-count": slides.length,
"--dynamic-grid-column-min-width": slideMinWidth,
"--dynamic-grid-column-max-width": slideMaxWidth,
} as CSSProperties
}
ref={containerRef}
>
<ol
className={`grid ui-grid-gap grid-cols-dynamic transform transition-transform ${classes}`}
data-id="slider-strip"
{...props}
>
{slides.map((slide, i) => (
<li key={i} className={slideClasses} data-id="slider-slide">
{slide}
</li>
))}
</ol>

<div
className="justify-center items-center my-24 hidden"
data-id="slider-controls"
>
<button
type="button"
className="p-0 w-24 h-24 flex items-center focus:outline-gui-focus"
data-id="slider-previous"
>
<Icon
name="icon-gui-disclosure-arrow"
size="1.5rem"
color="text-cool-black"
additionalCSS="transform rotate-180"
data-id="meganav-control-mobile-dropdown-menu"
/>
</button>

<ul className="flex justify-center items-center mx-32 relative h-24">
{slides.map((_, i) => (
<li key={i}>
<span
className="ui-slider-marker text-cool-black"
data-id="slider-marker"
>
&#x2b24;
</span>{" "}
{/* ⬤ */}
</li>
))}
</ul>

<button
type="button"
className="p-0 w-24 h-24 flex items-center focus:outline-gui-focus"
data-id="slider-next"
>
<Icon
name="icon-gui-disclosure-arrow"
size="1.5rem"
color="text-cool-black"
data-id="meganav-control-mobile-dropdown-menu"
/>
</button>
</div>
</div>
);
};

export default Slider;

0 comments on commit 61cbcf8

Please sign in to comment.