← Orion

registry:block

Diff Table

Proposed row-level changes sweeping through a table once.

Rendered example

Proposed workspace cleanup
RepositoryStatusOwner
onboarding-flowDrafts.kim
legacy-checkoutDrafta.reyes
search-indexActives.kim
checkout-v2Activea.reyes

Install

orion-themeuse-staged-sequencebadge
Open registry JSON

registry/blocks/diff-table.tsx

"use client"

import { useStagedSequence } from "@/registry/hooks/use-staged-sequence"
import { Badge } from "@/registry/ui/badge"

/**
 * DIFF TABLE
 * Proposed row-level changes sweep through a table once: removed rows
 * tint red and strike through, then an added row settles in green.
 */

type Row = {
  name: string
  status: string
  owner: string
  change: "removed" | "added" | null
}

const ROWS: Row[] = [
  { name: "onboarding-flow", status: "Draft", owner: "s.kim", change: "removed" },
  { name: "legacy-checkout", status: "Draft", owner: "a.reyes", change: "removed" },
  { name: "search-index", status: "Active", owner: "s.kim", change: null },
]

const ADDED_ROW: Row = { name: "checkout-v2", status: "Active", owner: "a.reyes", change: "added" }

const STATUS_DOT: Record<string, string> = {
  Draft: "bg-ink-3",
  Active: "bg-accent",
}

export function DiffTable() {
  const stage = useStagedSequence([800, 1000, 1000])
  const tinted = stage >= 2
  const added = stage >= 3

  return (
    <div className="w-full max-w-95">
      <div className="relative overflow-hidden rounded-card bg-surface shadow-card">
        <div className="primitive-card-bar flex items-center justify-between border-b border-line">
          <span className="text-[12.5px] font-medium text-ink">Proposed workspace cleanup</span>
        </div>

        <table className="w-full table-fixed border-collapse text-left">
          <colgroup>
            <col className="w-[40%]" />
            <col className="w-[26%]" />
            <col className="w-[34%]" />
          </colgroup>
          <thead>
            <tr className="border-b border-line">
              {["Repository", "Status", "Owner"].map((h) => (
                <th key={h} className="primitive-table-cell text-[12px] font-medium text-ink-3">
                  {h}
                </th>
              ))}
            </tr>
          </thead>
          <tbody>
            {ROWS.map((row) => {
              const out = row.change === "removed" && tinted
              return (
                <tr
                  key={row.name}
                  className="border-b border-line transition-colors duration-400 last:border-0 hover:bg-hover"
                  style={{ background: out ? "var(--red-tint)" : undefined }}
                >
                  <td
                    className="primitive-table-cell font-mono text-[12.5px] font-medium transition-colors duration-400"
                    style={{
                      color: out ? "var(--red)" : "var(--ink)",
                      textDecorationLine: out ? "line-through" : "none",
                      textDecorationColor: "color-mix(in srgb, var(--red) 50%, transparent)",
                    }}
                  >
                    {row.name}
                  </td>
                  <td className="primitive-table-cell">
                    <Badge
                      variant="chip"
                      dotColor={STATUS_DOT[row.status]}
                      className="transition-opacity duration-400"
                      style={{ opacity: out ? 0.55 : 1 }}
                    >
                      {row.status}
                    </Badge>
                  </td>
                  <td
                    className="primitive-table-cell text-[12.5px] whitespace-nowrap transition-colors duration-400"
                    style={{ color: out ? "var(--red)" : "var(--ink-2)" }}
                  >
                    {row.owner}
                  </td>
                </tr>
              )
            })}
            <tr>
              <td colSpan={3} className="p-0">
                <div
                  className="grid transition-[grid-template-rows,opacity] duration-400"
                  style={{
                    gridTemplateRows: added ? "1fr" : "0fr",
                    opacity: added ? 1 : 0,
                    transitionTimingFunction: "cubic-bezier(0.23, 1, 0.32, 1)",
                  }}
                >
                  <div className="overflow-hidden" style={{ background: "var(--green-tint)" }}>
                    <div className="grid grid-cols-[40%_26%_34%] items-center border-t border-line">
                      <span className="primitive-table-cell font-mono text-[12.5px] font-medium text-green">
                        {ADDED_ROW.name}
                      </span>
                      <span className="primitive-table-cell">
                        <Badge variant="chip" className="bg-surface" dotColor="var(--green)">
                          {ADDED_ROW.status}
                        </Badge>
                      </span>
                      <span className="primitive-table-cell text-[12.5px] text-green">{ADDED_ROW.owner}</span>
                    </div>
                  </div>
                </div>
              </td>
            </tr>
          </tbody>
        </table>
      </div>
    </div>
  )
}