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 {
tree: TreeNode;
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(
tree.type !== "directory" || level === 0 ? true : false,
);
@@ -32,11 +37,9 @@ export const FileTree: React.FC<FileTreeProps> = ({ tree, level = 0 }) => {
onClick={toggleExpand}
style={{
paddingLeft: level * 20,
display: "flex",
alignItems: "center",
cursor: tree.type === "directory" ? "pointer" : "default",
userSelect: "none",
animationDelay: `${delay}ms`,
}}
className="flex items-center cursor-pointer select-none animate-fade-in opacity-0"
>
{tree.type === "directory" ? (
expanded ? (
@@ -52,8 +55,14 @@ export const FileTree: React.FC<FileTreeProps> = ({ tree, level = 0 }) => {
{/* Children */}
{expanded &&
tree.children?.map((child) => (
<FileTree key={child.uri} tree={child} level={level + 1} />
tree.children?.map((child, index) => (
<FileTree
key={child.uri}
tree={child}
level={level + 1}
// stagger each child by 100ms
delay={delay + (index + 1) * 100}
/>
))}
</div>
);
+5 -1
View File
@@ -30,7 +30,11 @@ export default function RunChat({
{/* Messages */}
<div className="flex-1 overflow-y-auto space-y-2">
{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="text-muted-foreground">{msg.message}</span>
<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 }} />
</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} />}
</div>
<div className="flex-1">
<ProblemCard name="Idk" difficulty="hard" tags={[]} attempts={0} />
<ProblemCard
name="Idk"
difficulty="hard"
tags={[]}
attempts={0}
index={4}
/>
</div>
</div>