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 ( +
+
+
+
{title}
+
+
+ {description} +
+
+
+
+
+
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. +
+
+
+
+ {\`Feature +
+
+
+ ) +} + +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 ( +
+
+ +

Carousel

+
+ + + +
+ ) +} + +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 ( +
+
+
+
{title}
+
+
+ {description} +
+
+
+
+
+
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. +
+
+
+
+ {`Feature +
+
+
+ ) +} + +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