continue re-design
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
"use client";
|
||||
|
||||
import { motion, MotionProps, TargetAndTransition } from "motion/react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
|
||||
import { cn } from "@/utils/cn";
|
||||
|
||||
type AnimatedHeight = {
|
||||
children: React.ReactNode;
|
||||
animate?: TargetAndTransition;
|
||||
initial?: TargetAndTransition;
|
||||
exit?: TargetAndTransition;
|
||||
className?: string;
|
||||
transition?: MotionProps["transition"];
|
||||
};
|
||||
|
||||
export default function AnimatedHeight({ children, ...attrs }: AnimatedHeight) {
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const [height, setHeight] = useState<number | "auto">("auto");
|
||||
|
||||
useEffect(() => {
|
||||
const child = containerRef.current?.children[0] as Element;
|
||||
|
||||
const updateHeight = () => {
|
||||
if (!child) return;
|
||||
|
||||
setHeight(child.clientHeight);
|
||||
};
|
||||
|
||||
updateHeight();
|
||||
|
||||
const resizeObserver = new ResizeObserver(updateHeight);
|
||||
|
||||
resizeObserver.observe(child);
|
||||
|
||||
return () => resizeObserver.disconnect();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
{...attrs}
|
||||
animate={{
|
||||
height,
|
||||
...attrs.animate,
|
||||
}}
|
||||
className={cn(attrs.className)}
|
||||
initial={{
|
||||
height,
|
||||
...attrs.initial,
|
||||
}}
|
||||
ref={containerRef}
|
||||
>
|
||||
<div className="h-max">{children}</div>
|
||||
</motion.div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
"use client";
|
||||
|
||||
import { motion, TargetAndTransition, Transition } from "motion/react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
|
||||
type AnimatedWidthProps = {
|
||||
children: React.ReactNode;
|
||||
animate?: TargetAndTransition;
|
||||
initial?: TargetAndTransition;
|
||||
transition?: Transition;
|
||||
};
|
||||
|
||||
export default function AnimatedWidth({
|
||||
children,
|
||||
...attrs
|
||||
}: AnimatedWidthProps) {
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const [width, setWidth] = useState<number | "auto">("auto");
|
||||
|
||||
useEffect(() => {
|
||||
const child = containerRef.current?.children[0] as Element;
|
||||
|
||||
const updateWidth = () => {
|
||||
if (!child) return;
|
||||
|
||||
setWidth(child.clientWidth);
|
||||
};
|
||||
|
||||
updateWidth();
|
||||
|
||||
const resizeObserver = new ResizeObserver(updateWidth);
|
||||
|
||||
resizeObserver.observe(child);
|
||||
|
||||
return () => resizeObserver.disconnect();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
{...attrs}
|
||||
animate={{
|
||||
width,
|
||||
...attrs.animate,
|
||||
}}
|
||||
className="overflow-hidden"
|
||||
initial={{
|
||||
width,
|
||||
...attrs.initial,
|
||||
}}
|
||||
ref={containerRef}
|
||||
>
|
||||
<div className="w-max whitespace-nowrap">{children}</div>
|
||||
</motion.div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import React from "react";
|
||||
|
||||
import CurvyRect from "./curvy-rect";
|
||||
|
||||
export function CurvyRectDivider() {
|
||||
return (
|
||||
<div className="relative mx-1 my-1">
|
||||
<div className="relative h-px bg-zinc-200 border-x border-zinc-200">
|
||||
<CurvyRect
|
||||
className="absolute -top-[0.5px] -left-[1px] w-[calc(100%+2px)]"
|
||||
top
|
||||
/>
|
||||
<CurvyRect
|
||||
className="absolute -bottom-[0.5px] -left-[1px] w-[calc(100%+2px)]"
|
||||
bottom
|
||||
/>
|
||||
<CurvyRect
|
||||
className="absolute -left-[0.5px] -top-[1px] h-[calc(100%+2px)]"
|
||||
left
|
||||
/>
|
||||
<CurvyRect
|
||||
className="absolute -right-[0.5px] -top-[1px] h-[calc(100%+2px)]"
|
||||
right
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
import { cn } from "@/utils/cn";
|
||||
|
||||
import Curve from "@/components/shared/icons/curve";
|
||||
|
||||
interface CurvyRectProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
allSides?: boolean;
|
||||
|
||||
x?: boolean;
|
||||
y?: boolean;
|
||||
|
||||
left?: boolean;
|
||||
right?: boolean;
|
||||
top?: boolean;
|
||||
bottom?: boolean;
|
||||
|
||||
topLeft?: boolean;
|
||||
topRight?: boolean;
|
||||
bottomLeft?: boolean;
|
||||
bottomRight?: boolean;
|
||||
}
|
||||
|
||||
export default function CurvyRect({
|
||||
className,
|
||||
allSides,
|
||||
x,
|
||||
y,
|
||||
left,
|
||||
right,
|
||||
top,
|
||||
bottom,
|
||||
topLeft,
|
||||
topRight,
|
||||
bottomLeft,
|
||||
bottomRight,
|
||||
...props
|
||||
}: CurvyRectProps) {
|
||||
const hasTopLeft = topLeft || top || left || x || allSides;
|
||||
const hasTopRight = topRight || top || right || x || allSides;
|
||||
const hasBottomLeft = bottomLeft || bottom || left || y || allSides;
|
||||
const hasBottomRight = bottomRight || bottom || right || y || allSides;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
className,
|
||||
"pointer-events-none contain-[layout,paint] curvy-rect",
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{hasTopLeft && <Curve className="-rotate-90 absolute top-0 left-0" />}
|
||||
{hasTopRight && <Curve className="absolute top-0 right-0" />}
|
||||
{hasBottomLeft && (
|
||||
<Curve className="rotate-180 absolute bottom-0 left-0" />
|
||||
)}
|
||||
{hasBottomRight && (
|
||||
<Curve className="rotate-90 absolute bottom-0 right-0" />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export const Connector = ({
|
||||
className,
|
||||
...props
|
||||
}: React.SVGProps<SVGSVGElement>) => {
|
||||
return (
|
||||
<svg
|
||||
fill="none"
|
||||
height="21"
|
||||
viewBox="0 0 22 21"
|
||||
width="22"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
{...props}
|
||||
className={cn(
|
||||
"pointer-events-none contain-[layout,paint] absolute",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<path
|
||||
d="M10.5 4C10.5 7.31371 7.81371 10 4.5 10H0.5V11H4.5C7.81371 11 10.5 13.6863 10.5 17V21H11.5V17C11.5 13.6863 14.1863 11 17.5 11H21.5V10H17.5C14.1863 10 11.5 7.31371 11.5 4V0H10.5V4Z"
|
||||
fill="#EDEDED"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export const ConnectorToRight = ({
|
||||
className,
|
||||
...props
|
||||
}: React.SVGProps<SVGSVGElement>) => {
|
||||
return (
|
||||
<svg
|
||||
fill="none"
|
||||
height="21"
|
||||
viewBox="0 0 11 21"
|
||||
width="11"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
{...props}
|
||||
className={cn(
|
||||
"pointer-events-none contain-[layout,paint] absolute",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<path
|
||||
d="M1 4C1 7.31371 3.68629 10 7 10H11V11H7C3.68629 11 1 13.6863 1 17V21H0V0H1V4Z"
|
||||
fill="#EDEDED"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export const ConnectorToLeft = ({
|
||||
className,
|
||||
...props
|
||||
}: React.SVGProps<SVGSVGElement>) => {
|
||||
return (
|
||||
<svg
|
||||
fill="none"
|
||||
height="21"
|
||||
viewBox="0 0 11 21"
|
||||
width="11"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
{...props}
|
||||
className={cn(
|
||||
"pointer-events-none contain-[layout,paint] absolute",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<path
|
||||
d="M11 21H10V17C10 13.6863 7.31371 11 4 11H0V10H4C7.31371 10 10 7.31371 10 4V0H11V21Z"
|
||||
fill="#EDEDED"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export const ConnectorToTop = ({
|
||||
className,
|
||||
...props
|
||||
}: React.SVGProps<SVGSVGElement>) => {
|
||||
return (
|
||||
<svg
|
||||
fill="none"
|
||||
height="11"
|
||||
viewBox="0 0 21 11"
|
||||
width="21"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
{...props}
|
||||
className={cn(
|
||||
"pointer-events-none contain-[layout,paint] absolute",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<path
|
||||
d="M11 4C11 7.31371 13.6863 10 17 10H21V11H0V10H4C7.31371 10 10 7.31371 10 4V0H11V4Z"
|
||||
fill="#EDEDED"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export const ConnectorToBottom = ({
|
||||
className,
|
||||
...props
|
||||
}: React.SVGProps<SVGSVGElement>) => {
|
||||
return (
|
||||
<svg
|
||||
fill="none"
|
||||
height="11"
|
||||
viewBox="0 0 21 11"
|
||||
width="21"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
{...props}
|
||||
className={cn(
|
||||
"pointer-events-none contain-[layout,paint] absolute",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<path
|
||||
d="M11 7C11 3.68629 13.6863 1 17 1H21V0H0V1H4C7.31371 1 10 3.68629 10 7V11H11V7Z"
|
||||
fill="#EDEDED"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user