Skip to content

Commit

Permalink
Animated columns
Browse files Browse the repository at this point in the history
  • Loading branch information
alexbeno committed Aug 8, 2024
1 parent 57462a9 commit b2f6d9d
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 21 deletions.
24 changes: 11 additions & 13 deletions app/test-nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

import { useState } from "react";

import { AnimatedColumn } from "@/shared/components/animated-columns/animated-column/animated-column";

export function TestNav() {
const [navSize, setNavSize] = useState(200);
function onNavSizeChange() {
Expand All @@ -16,16 +14,16 @@ export function TestNav() {
}
}
return (
<AnimatedColumn>
<div
className="h-screen bg-red-900"
style={{
width: navSize,
}}
onClick={onNavSizeChange}
>
NAV
</div>
</AnimatedColumn>
// <AnimatedColumn>
<div
className="h-screen bg-red-900"
style={{
width: navSize,
}}
onClick={onNavSizeChange}
>
NAV
</div>
// </AnimatedColumn>
);
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
"use client";

import { motion, spring } from "framer-motion";
import { motion } from "framer-motion";

import { TAnimatedColumn } from "./animated-column.types";
import { AnimatedColumnProps } from "./animated-column.types";

export function AnimatedColumn({ width, controlled, initialWidth, children, className, onClick }: AnimatedColumnProps) {
if (!controlled) {
return (
<motion.div onClick={onClick} layout="position" className={className}>
{children}
</motion.div>
);
}

export function AnimatedColumn({ children }: TAnimatedColumn.Props) {
return (
<motion.div layout className="origin-top" transition={spring}>
<motion.div onClick={onClick} className={className} style={{ width: initialWidth }} animate={{ width }}>
{children}
</motion.div>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
import { PropsWithChildren } from "react";

export namespace TAnimatedColumn {
export interface Props extends PropsWithChildren {}
interface BaseProps extends PropsWithChildren {
className?: string;
onClick?: () => void;
}
interface ControlledProps {
controlled: true;
width: number;
initialWidth: number;
}

interface UncontrolledProps {
controlled: false;
width?: never;
initialWidth?: never;
}

export type AnimatedColumnProps = BaseProps & (ControlledProps | UncontrolledProps);
34 changes: 32 additions & 2 deletions shared/components/animated-columns/animated-columns.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,43 @@
"use client";

import { motion, spring } from "framer-motion";
import { useState } from "react";

import { AnimatedColumn } from "@/shared/components/animated-columns/animated-column/animated-column";

import { TAnimatedColumns } from "./animated-columns.types";

export function AnimatedColumns({ children }: TAnimatedColumns.Props) {
const [navSize, setNavSize] = useState(200);
function onNavSizeChange() {
if (navSize === 200) {
setNavSize(400);
} else if (navSize === 400) {
setNavSize(100);
} else {
setNavSize(200);
}
}

return (
<motion.div layout layoutRoot className="flex h-full flex-row items-stretch justify-start" transition={spring}>
{children}
<motion.div
layout="position"
layoutRoot={true}
className="flex h-full flex-row items-stretch justify-start"
transition={spring}
>
<AnimatedColumn
controlled={true}
width={navSize}
initialWidth={200}
className="h-screen bg-green-900"
onClick={onNavSizeChange}
>
<div>NAV</div>
</AnimatedColumn>
<AnimatedColumn controlled={false} className="h-screen w-full bg-blue-900">
<div>content</div>
</AnimatedColumn>
</motion.div>
);
}

0 comments on commit b2f6d9d

Please sign in to comment.