From c5d96a0ded593cb9e270db6ca7eec031a17f5a98 Mon Sep 17 00:00:00 2001 From: Manu Arora Date: Wed, 9 Jul 2025 17:30:37 +0530 Subject: add: actual handlebars to resize container --- apps/web/src/components/landing/handlebars.tsx | 163 +++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 apps/web/src/components/landing/handlebars.tsx (limited to 'apps/web/src/components/landing/handlebars.tsx') diff --git a/apps/web/src/components/landing/handlebars.tsx b/apps/web/src/components/landing/handlebars.tsx new file mode 100644 index 00000000..832a923f --- /dev/null +++ b/apps/web/src/components/landing/handlebars.tsx @@ -0,0 +1,163 @@ +"use client"; +import React, { useState, useRef, useEffect } from "react"; +import { motion, useMotionValue, useTransform, PanInfo } from "motion/react"; + +interface HandlebarsProps { + children: React.ReactNode; + minWidth?: number; + maxWidth?: number; + onRangeChange?: (left: number, right: number) => void; +} + +export const Handlebars = ({ + children, + minWidth = 50, + maxWidth = 400, + onRangeChange, +}: HandlebarsProps) => { + const [leftHandle, setLeftHandle] = useState(0); + const [rightHandle, setRightHandle] = useState(maxWidth); + const [contentWidth, setContentWidth] = useState(maxWidth); + + const leftHandleX = useMotionValue(0); + const rightHandleX = useMotionValue(maxWidth); + + const visibleWidth = useTransform( + [leftHandleX, rightHandleX], + (values: number[]) => values[1] - values[0] + ); + + const contentLeft = useTransform(leftHandleX, (left: number) => -left); + + const containerRef = useRef(null); + const measureRef = useRef(null); + + useEffect(() => { + if (!measureRef.current) return; + + const measureContent = () => { + if (measureRef.current) { + const width = measureRef.current.scrollWidth; + const paddedWidth = width + 32; + setContentWidth(paddedWidth); + setRightHandle(paddedWidth); + rightHandleX.set(paddedWidth); + } + }; + + measureContent(); + const timer = setTimeout(measureContent, 50); + + return () => clearTimeout(timer); + }, [children, rightHandleX]); + + useEffect(() => { + leftHandleX.set(leftHandle); + }, [leftHandle, leftHandleX]); + + useEffect(() => { + rightHandleX.set(rightHandle); + }, [rightHandle, rightHandleX]); + + useEffect(() => { + onRangeChange?.(leftHandle, rightHandle); + }, [leftHandle, rightHandle, onRangeChange]); + + const handleLeftDrag = (event: any, info: PanInfo) => { + const newLeft = Math.max( + 0, + Math.min(leftHandle + info.offset.x, rightHandle - minWidth) + ); + setLeftHandle(newLeft); + }; + + const handleRightDrag = (event: any, info: PanInfo) => { + const newRight = Math.max( + leftHandle + minWidth, + Math.min(contentWidth, rightHandle + info.offset.x) + ); + setRightHandle(newRight); + }; + + return ( +
+
+ {children} +
+ +
+
+ +
+
+ + +
+
+
+ + + + {children} + + +
+
+ ); +}; -- cgit v1.3.1