From 79398b5c836ef9c831426572fd0f68c6f9966a81 Mon Sep 17 00:00:00 2001
From: Ben Orloff <99829882+benorloff@users.noreply.github.com>
Date: Tue, 23 Apr 2024 00:12:49 -0700
Subject: [PATCH] resolves preview container (#3)
---
app/gluons/carousel/_demo/carousel-code.tsx | 151 ++++++++++++++++++
.../carousel/_demo/carousel-preview.tsx | 7 +
app/gluons/carousel/page.tsx | 40 +++++
components/demo-preview.tsx | 2 +-
components/gluons/carousel.tsx | 150 +++++++++++++++++
5 files changed, 349 insertions(+), 1 deletion(-)
create mode 100644 app/gluons/carousel/_demo/carousel-code.tsx
create mode 100644 app/gluons/carousel/_demo/carousel-preview.tsx
create mode 100644 app/gluons/carousel/page.tsx
create mode 100644 components/gluons/carousel.tsx
diff --git a/app/gluons/carousel/_demo/carousel-code.tsx b/app/gluons/carousel/_demo/carousel-code.tsx
new file mode 100644
index 0000000..b5aa68a
--- /dev/null
+++ b/app/gluons/carousel/_demo/carousel-code.tsx
@@ -0,0 +1,151 @@
+export const CarouselCode = `
+"use client"
+
+import React, { useEffect, useState } from "react"
+import { useDebounceValue } from "usehooks-ts"
+import { cn } from "@/lib/utils"
+
+import Image from "next/image";
+
+const CarouselSlide = ({
+ number,
+ title,
+ description
+}: {
+ number: number;
+ title: string;
+ description: string;
+}) => {
+
+ return (
+
+
+
+
+
+
Lorem ipsum.
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
+ Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
+
+
+
+
Lorem ipsum.
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
+ Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
+
+
+
+
+
+
+
+
+ )
+}
+
+export const Carousel = () => {
+
+ const [activeFeature, setActiveFeature] = useDebounceValue(1, 50)
+ const [scrollProgress, setScrollProgress] = useState(0)
+
+ let featureTrack: HTMLElement | null = null;
+ let featureTrackScrollWidth: number = 0;
+ let featureEl: HTMLElement | null = null;
+ let featureElClientWidth: number = 0;
+
+ if (typeof document !== 'undefined') {
+ featureTrack = document.getElementById("FeatureCarouselTrack");
+ featureTrackScrollWidth = featureTrack?.scrollWidth as number;
+ featureEl = document.getElementById("Feature");
+ featureElClientWidth = featureEl?.clientWidth as number;
+ }
+
+ const onTrackScroll = (e: React.UIEvent) => {
+ let progress = Number(( e.currentTarget.scrollLeft / e.currentTarget.scrollWidth ).toPrecision(2)) * 100;
+ setScrollProgress(progress);
+ }
+
+ useEffect(() => {
+ switch (true) {
+ case scrollProgress < 33:
+ setActiveFeature(1);
+ break;
+ case scrollProgress >= 33 && scrollProgress < 66:
+ setActiveFeature(2);
+ break;
+ case scrollProgress >= 66 && scrollProgress < 100:
+ setActiveFeature(3);
+ break;
+ default:
+ setActiveFeature(1);
+ break;
+ }
+ }, [scrollProgress])
+
+ const handleClick = (e: React.MouseEvent) => {
+ console.log(e, '<== e clicked')
+ let id = parseInt(e.currentTarget.dataset.id as string);
+ let n: number = 0;
+ n = ( id - 1 ) * featureElClientWidth;
+
+ featureTrack?.scrollTo( { left: n , top: 0, behavior: 'smooth' } )
+ }
+
+ return (
+
+
+ {Array.from({ length: 3 }).map((_, i) => (
+
+ ))}
+
+
+
+ {Array.from({ length: 3 }).map((_, i) => (
+
handleClick(e)}
+ >
+ Feature {i + 1}
+
+ ))}
+
+
+ )
+}`.trim();
\ No newline at end of file
diff --git a/app/gluons/carousel/_demo/carousel-preview.tsx b/app/gluons/carousel/_demo/carousel-preview.tsx
new file mode 100644
index 0000000..8ce9e2c
--- /dev/null
+++ b/app/gluons/carousel/_demo/carousel-preview.tsx
@@ -0,0 +1,7 @@
+import { Carousel } from "@/components/gluons/carousel"
+
+export const CarouselPreview = () => {
+ return (
+
+ )
+};
\ No newline at end of file
diff --git a/app/gluons/carousel/page.tsx b/app/gluons/carousel/page.tsx
new file mode 100644
index 0000000..6363220
--- /dev/null
+++ b/app/gluons/carousel/page.tsx
@@ -0,0 +1,40 @@
+import { Breadcrumbs } from "@/components/breadcrumbs";
+import { Demo } from "@/components/demo";
+import { ContentAccordion } from "@/components/gluons/content-accordion";
+import {
+ Breadcrumb,
+ BreadcrumbItem,
+ BreadcrumbLink,
+ BreadcrumbList,
+ BreadcrumbSeparator
+} from "@/components/ui/breadcrumb";
+import {
+ Tabs,
+ TabsContent,
+ TabsList,
+ TabsTrigger
+} from "@/components/ui/tabs";
+import { CarouselPreview } from "./_demo/carousel-preview";
+import { CarouselCode } from "./_demo/carousel-code";
+
+const CarouselPage = () => {
+ return (
+
+
+
+
+
+
+ )
+}
+
+export default CarouselPage;
\ No newline at end of file
diff --git a/components/demo-preview.tsx b/components/demo-preview.tsx
index e94e9a2..21047c7 100644
--- a/components/demo-preview.tsx
+++ b/components/demo-preview.tsx
@@ -57,7 +57,7 @@ export const DemoPreview = ({
diff --git a/components/gluons/carousel.tsx b/components/gluons/carousel.tsx
new file mode 100644
index 0000000..c1f9c6c
--- /dev/null
+++ b/components/gluons/carousel.tsx
@@ -0,0 +1,150 @@
+"use client"
+
+import React, { useEffect, useState } from "react"
+import { useDebounceValue } from "usehooks-ts"
+import { cn } from "@/lib/utils"
+
+import Image from "next/image";
+
+const CarouselSlide = ({
+ number,
+ title,
+ description
+}: {
+ number: number;
+ title: string;
+ description: string;
+}) => {
+
+ return (
+
+
+
+
+
+
Lorem ipsum.
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
+ Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
+
+
+
+
Lorem ipsum.
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
+ Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
+
+
+
+
+
+
+
+
+ )
+}
+
+export const Carousel = () => {
+
+ const [activeFeature, setActiveFeature] = useDebounceValue(1, 50)
+ const [scrollProgress, setScrollProgress] = useState(0)
+
+ let featureTrack: HTMLElement | null = null;
+ let featureTrackScrollWidth: number = 0;
+ let featureEl: HTMLElement | null = null;
+ let featureElClientWidth: number = 0;
+
+ if (typeof document !== 'undefined') {
+ featureTrack = document.getElementById("FeatureCarouselTrack");
+ featureTrackScrollWidth = featureTrack?.scrollWidth as number;
+ featureEl = document.getElementById("Feature");
+ featureElClientWidth = featureEl?.clientWidth as number;
+ }
+
+ const onTrackScroll = (e: React.UIEvent) => {
+ let progress = Number(( e.currentTarget.scrollLeft / e.currentTarget.scrollWidth ).toPrecision(2)) * 100;
+ setScrollProgress(progress);
+ }
+
+ useEffect(() => {
+ switch (true) {
+ case scrollProgress < 33:
+ setActiveFeature(1);
+ break;
+ case scrollProgress >= 33 && scrollProgress < 66:
+ setActiveFeature(2);
+ break;
+ case scrollProgress >= 66 && scrollProgress < 100:
+ setActiveFeature(3);
+ break;
+ default:
+ setActiveFeature(1);
+ break;
+ }
+ }, [scrollProgress])
+
+ const handleClick = (e: React.MouseEvent) => {
+ console.log(e, '<== e clicked')
+ let id = parseInt(e.currentTarget.dataset.id as string);
+ let n: number = 0;
+ n = ( id - 1 ) * featureElClientWidth;
+
+ featureTrack?.scrollTo( { left: n , top: 0, behavior: 'smooth' } )
+ }
+
+ return (
+
+
+ {Array.from({ length: 3 }).map((_, i) => (
+
+ ))}
+
+
+
+ {Array.from({ length: 3 }).map((_, i) => (
+
handleClick(e)}
+ >
+ Feature {i + 1}
+
+ ))}
+
+
+ )
+}
\ No newline at end of file