Skip to content
animorio
IT
All components

The file tree

Trees, Transitions, PhysicsGSAPMediumCompressed weight: Demo 6.5 KBGSAP 28 KBFreeDownload the zip

A project’s files in a tree: a folder opens tilting its lid and turning its chevron, its files come down one after another while the line they hang from draws itself; a single highlight slides on a spring to the item chosen, stretching a little, a new file writes its own name letter by letter and a deleted one folds away.

The code

A folder that runs on its own: index.html, style.css, script.js and the libraries from a CDN. The React and Vue tabs hold the same demo as a ready component, which switches its animations off when it leaves the page.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>The file tree</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/encode-sans@5.3.0/standard.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- the file tree: folders open with their lid lifting and their files coming down one after another, a single
         highlight slides to the item chosen, and a new file writes its own name -->
    <section class="files" aria-labelledby="files-title" data-files data-autoclic>
      <header class="files__head">
        <h2 class="files__title" id="files-title">Explorer</h2>
        <button class="files__new" type="button" data-new>
          <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 6v12M6 12h12"/></svg>
          New file
        </button>
      </header>
      <div class="tree" data-tree>
        <span class="tree__mark" aria-hidden="true" data-mark></span>
        <ul class="tree__root" role="tree" aria-labelledby="files-title" data-root></ul>
      </div>
      <p class="sr" aria-live="polite" data-live></p>
    </section>
  </main>

  <script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.min.js"></script>
  <script src="script.js"></script>
</body>
</html>

Playground

Change values, colours and text with the controls and watch the animation respond live. Or write in the code yourself. Then download the folder with your changes.

34 values to change

Or ask Claude Code for it

With the Animorio connector, Claude Code takes it from here, guide included, and fits it into your project. Paste this request:

Take “The file tree” from Animorio and fit it into my site

What it does

On a white background a light panel: Explorer with the New file button and under it a website’s tree (website, src with components and pages, public with images, package.json, README.md), with yellow folders and files tagged in the colour of their kind. At the start website, src and pages are open, and index.astro is chosen. Clicking a folder its chevron turns with a bounce, its lid tilts back as in an open folder, the space opens and the files come in from the left one after another, while the line hanging them from the folder draws itself from the top; clicking it again closes it. Clicking an item the light blue highlight slides over to it on a spring, stretching a little as it runs, and follows it while the folders above open and close. New file makes notes.md (notes-2.md if it is already there) in the folder chosen or in the chosen file’s folder: the row opens and the name writes itself behind a caret that blinks and goes. Delete or Backspace delete the file chosen, which folds away sliding sideways; folders are not deleted.

How it works

Opening a folder

The group of children starts at zero height and goes to the height read from scrollHeight in OPEN seconds with power3.out; at the end the written height is taken away (clearProps), so a file added later is not left out. Meanwhile the children come in from the left CASCADE seconds apart and the --hang variable takes the vertical scale of the line they hang from from 0 to 1. Closing, the height goes back to zero and the group is hidden.

Chevron and lid

The chevron turns 90 degrees with back.out; the folder’s lid, a separate piece of the same SVG, leans (skewX) and shortens (scaleY) round its bottom edge, like an open folder.

One highlight

Under the items there is a single rectangle, moved by a spring (GLIDE) worked out on GSAP’s ticker in steps of 4 milliseconds towards the position of the item chosen, read again every frame: so it follows it even while the folders above change height. The faster it goes the more it stretches vertically, up to about a third; the ticker stops once it has arrived and no folder is moving.

The new file and the deleted one

The new file goes into the folder chosen, which opens; its row grows from zero to 32 pixels and a tween on a number writes the name letter by letter (TYPE seconds a letter) in front of a caret, which blinks and is taken away. The deleted file goes to zero height sliding sideways and, if it was chosen, the highlight moves to the next item (or the one before).

Keys and the preview

The tree follows the ARIA tree pattern: a single stop in the Tab order, the item chosen named by aria-activedescendant, up and down arrows, Home and End, right opening or going in, left closing or going up, Enter and space opening and closing, Delete deleting; with the keys the focus ring sits on the highlight and travels with it. A click from a script (the library’s preview) is a pretend hand that chooses files, opens and closes folders, makes a file and later deletes it, and goes back to the start.

Values to change

NameFileDefaultWhat it changes
OPENscript.js0.38The seconds a folder takes to open (a little less to close).
CASCADEscript.js0.04The seconds between one file coming in and the next.
GLIDEscript.js[420, 0.78]The highlight’s spring: how stiff it is and how much it is held back.
TYPEscript.js0.06The seconds a new file’s name takes for each letter.
TREEscript.js['website', [['src', […]], …]]The files: a name and, for a folder, what is inside it.

Try them in the Playground

When to use it

For an editor in the browser, an app’s file manager, a project’s documentation, a nested index, a menu with several levels, a shop’s categories.

On phones

The items are tapped with a finger; the panel is at most 360 pixels wide and hangs from the top, so it never jumps as it grows and shrinks; taps do not wait for a double tap (touch-action manipulation).

With reduced motion

Folders open and close at once, the highlight goes to the item without a spring and without stretching, the new file appears with its name already written and the deleted one disappears at once; no entrance.

Pitfalls

  • At the top of a classic script a constant called top throws an error, because window.top already exists and cannot be declared again: the tree’s root is called tree0.
  • Animating the height to a number read from scrollHeight leaves that number written on the group: it must be taken away at the end (clearProps), or a file added later would be left out.
  • A highlight sent to the position read at the click lands in the wrong place if meanwhile a folder above opens: the item’s position has to be read again every frame while something moves.
  • A panel centred on the page moves by half its growth when it grows, and its heading jumps: it has to hang from the top.
  • With aria-activedescendant the focus stays on the tree and the items do not get it one by one: the focus ring has to be drawn by hand, here on the highlight.

Libraries

GSAP 3.15.0, Encode Sans (font variabile) 5.3.0.

Compressed with gzip, the three demo files weigh 6.5 KB; the libraries: GSAP 28 KB.

Testing

Tested on 3 October 2026

  • Desktop: Done
  • Phone: Done
  • Reduced motion: Done
  • Safari on iPhone: Done

License

Use it in your own projects and in your clients’ projects. Do not resell it or redistribute it as is. GSAP stays under its own Standard license. Full license.

All components