Animated run layout

This commit is contained in:
2026-02-07 01:47:20 +01:00
parent 77ebe246ca
commit 06508e0631
3 changed files with 29 additions and 10 deletions
+16 -7
View File
@@ -12,9 +12,14 @@ type TreeNode = {
interface FileTreeProps { interface FileTreeProps {
tree: TreeNode; tree: TreeNode;
level?: number; // for indentation level?: number; // for indentation
delay?: number; // stagger delay in ms
} }
export const FileTree: React.FC<FileTreeProps> = ({ tree, level = 0 }) => { export const FileTree: React.FC<FileTreeProps> = ({
tree,
level = 0,
delay = 0,
}) => {
const [expanded, setExpanded] = useState( const [expanded, setExpanded] = useState(
tree.type !== "directory" || level === 0 ? true : false, tree.type !== "directory" || level === 0 ? true : false,
); );
@@ -32,11 +37,9 @@ export const FileTree: React.FC<FileTreeProps> = ({ tree, level = 0 }) => {
onClick={toggleExpand} onClick={toggleExpand}
style={{ style={{
paddingLeft: level * 20, paddingLeft: level * 20,
display: "flex", animationDelay: `${delay}ms`,
alignItems: "center",
cursor: tree.type === "directory" ? "pointer" : "default",
userSelect: "none",
}} }}
className="flex items-center cursor-pointer select-none animate-fade-in opacity-0"
> >
{tree.type === "directory" ? ( {tree.type === "directory" ? (
expanded ? ( expanded ? (
@@ -52,8 +55,14 @@ export const FileTree: React.FC<FileTreeProps> = ({ tree, level = 0 }) => {
{/* Children */} {/* Children */}
{expanded && {expanded &&
tree.children?.map((child) => ( tree.children?.map((child, index) => (
<FileTree key={child.uri} tree={child} level={level + 1} /> <FileTree
key={child.uri}
tree={child}
level={level + 1}
// stagger each child by 100ms
delay={delay + (index + 1) * 100}
/>
))} ))}
</div> </div>
); );
+5 -1
View File
@@ -30,7 +30,11 @@ export default function RunChat({
{/* Messages */} {/* Messages */}
<div className="flex-1 overflow-y-auto space-y-2"> <div className="flex-1 overflow-y-auto space-y-2">
{chatMessages.map((msg, i) => ( {chatMessages.map((msg, i) => (
<div key={i} className="rounded-lg bg-secondary/50 p-2 text-sm"> <div
key={i}
className="rounded-lg bg-secondary/50 p-2 text-sm opacity-0 animate-fade-in"
style={{ animationDelay: `${i * 100}ms` }} // stagger by 100ms
>
<span className="font-semibold text-foreground">{msg.user}</span>:{" "} <span className="font-semibold text-foreground">{msg.user}</span>:{" "}
<span className="text-muted-foreground">{msg.message}</span> <span className="text-muted-foreground">{msg.message}</span>
<span className="ml-2 text-xs text-muted-foreground"> <span className="ml-2 text-xs text-muted-foreground">
+8 -2
View File
@@ -28,12 +28,18 @@ export default function Run() {
<ProfileCard user={{ username: "selimaj", rank: 1 }} /> <ProfileCard user={{ username: "selimaj", rank: 1 }} />
</div> </div>
<div className="flex-1 animate-fade-in opacity-0 duration-1000"> <div className="flex-1 animate-fade-in opacity-0 duration-1000 stagger-2">
{runInfo && <RunTimer runInfo={runInfo} />} {runInfo && <RunTimer runInfo={runInfo} />}
</div> </div>
<div className="flex-1"> <div className="flex-1">
<ProblemCard name="Idk" difficulty="hard" tags={[]} attempts={0} /> <ProblemCard
name="Idk"
difficulty="hard"
tags={[]}
attempts={0}
index={4}
/>
</div> </div>
</div> </div>