From c5d96a0ded593cb9e270db6ca7eec031a17f5a98 Mon Sep 17 00:00:00 2001 From: Manu Arora Date: Wed, 9 Jul 2025 17:30:37 +0530 Subject: [PATCH 1/2] add: actual handlebars to resize container --- .../web/src/components/landing/handlebars.tsx | 163 ++++++++++++++++++ apps/web/src/components/landing/hero.tsx | 10 +- 2 files changed, 165 insertions(+), 8 deletions(-) create mode 100644 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 0000000..832a923 --- /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} + + +
+
+ ); +}; diff --git a/apps/web/src/components/landing/hero.tsx b/apps/web/src/components/landing/hero.tsx index d45f33e..a71bee9 100644 --- a/apps/web/src/components/landing/hero.tsx +++ b/apps/web/src/components/landing/hero.tsx @@ -8,6 +8,7 @@ import { useState } from "react"; import { useToast } from "@/hooks/use-toast"; import Image from "next/image"; +import { Handlebars } from "./handlebars"; interface HeroProps { signupCount: number; @@ -91,14 +92,7 @@ export function Hero({ signupCount }: HeroProps) { className="inline-block font-bold tracking-tighter text-4xl md:text-[4rem]" >

The Open Source

-
-
- frame - - Video Editor - -
-
+ Video Editor Date: Sat, 12 Jul 2025 16:50:34 +0200 Subject: [PATCH 2/2] cleanup --- apps/web/src/components/landing/handlebars.tsx | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/apps/web/src/components/landing/handlebars.tsx b/apps/web/src/components/landing/handlebars.tsx index 832a923..36705e9 100644 --- a/apps/web/src/components/landing/handlebars.tsx +++ b/apps/web/src/components/landing/handlebars.tsx @@ -1,4 +1,5 @@ "use client"; + import React, { useState, useRef, useEffect } from "react"; import { motion, useMotionValue, useTransform, PanInfo } from "motion/react"; @@ -9,12 +10,12 @@ interface HandlebarsProps { onRangeChange?: (left: number, right: number) => void; } -export const Handlebars = ({ +export function Handlebars({ children, minWidth = 50, maxWidth = 400, onRangeChange, -}: HandlebarsProps) => { +}: HandlebarsProps) { const [leftHandle, setLeftHandle] = useState(0); const [rightHandle, setRightHandle] = useState(maxWidth); const [contentWidth, setContentWidth] = useState(maxWidth); @@ -93,9 +94,9 @@ export const Handlebars = ({ className="relative -rotate-[2.76deg] max-w-[250px] md:max-w-[454px] mt-2" style={{ width: contentWidth }} > -
+
-
+
-
+