~ knotless Search/
↑↓ move↵ open⇧↵ all results

chadtmiller.com/pds.js

An atproto PDS in JavaScript, for Cloudflare Workers and Node

0
0
main
59 lines · 2.0 KB Raw History
import { FileIcon, FolderIcon, LinkIcon, PackageIcon } from 'lucide-react';
import { Link } from '#/components/atoms/link.jsx';
import { bytes } from '#/lib/format.js';
import { cn } from '#/lib/utils.js';

const ICONS = {
  dir: FolderIcon,
  file: FileIcon,
  symlink: LinkIcon,
  submodule: PackageIcon,
};

/**
 * A directory's entries with their sizes, for the reading pane of a directory
 * that says nothing about itself. The pane beside it navigates; this says how
 * big each of those entries is, which the narrow pane has no room for.
 */
export function DirTable({ repo, refName, path, entries }) {
  return (
    <ul>
      {entries.map((entry) => {
        const child = path ? `${path}/${entry.name}` : entry.name;
        const kind = entry.type === 'dir' ? 'tree' : 'blob';
        const href = `/${encodeURIComponent(repo)}/${kind}/${encodeURI(refName)}/${encodeURI(child)}`;
        const Icon = ICONS[entry.type] ?? FileIcon;
        const row = (
          <>
            <Icon
              className={cn(
                'size-4 shrink-0',
                entry.type === 'dir' ? 'text-key' : 'text-faint',
              )}
            />
            <span className="min-w-0 flex-1 truncate">{entry.name}</span>
            <span className="shrink-0 font-mono text-[12px] text-faint tabular-nums">
              {entry.type === 'submodule' ? 'submodule' : bytes(entry.size)}
            </span>
          </>
        );
        return (
          <li key={entry.name} className="border-border border-b">
            {entry.type === 'submodule' ? (
              <span className="flex items-center gap-3 px-4 py-2.5 text-[13.5px] text-faint">
                {row}
              </span>
            ) : (
              <Link
                href={href}
                className="flex items-center gap-3 px-4 py-2.5 text-[13.5px] text-foreground no-underline transition-colors hover:bg-accent hover:no-underline"
              >
                {row}
              </Link>
            )}
          </li>
        );
      })}
    </ul>
  );
}