Browse all components
Context Files UI
The files currently in the model's context — sizes, how many tokens each one costs, and removal without leaving the chat.
Preview
- auth/token.ts≈ 1.2k tokens
- auth/refresh.ts≈ 840 tokens
- design-tokens.json48 KB
Presets
Props
Also takes onRemove.
Agent promptClaude Code · Cursor · any agent
Add the Context Files UI component from the Scrim UI registry to this project and use it in the configuration described below.
Context Files UI — The files currently in the model's context — sizes, how many tokens each one costs, and removal without leaving the chat.
## 1. Install
```bash
npx shadcn@latest add @scrimui/context-files
```
This writes a single file to `components/ui/context-files.tsx`. It is plain React + Tailwind with no runtime dependencies — no Radix, no CVA, nothing to add to package.json. If this project does not use the shadcn CLI, copy the source from https://scrimui.dev/components/context-files to the same path by hand; nothing in the file depends on shadcn.
## 2. Use it
```tsx
import { ContextFiles } from "@/components/ui/context-files";
const FILES = [
{ name: "auth/token.ts", detail: "≈ 1.2k tokens" },
{ name: "auth/refresh.ts", detail: "≈ 840 tokens" },
{ name: "design-tokens.json", detail: "48 KB" },
];
<ContextFiles
title="In context"
used={18000}
limit={128000}
files={FILES}
usage={{ used: 18000, limit: 128000 }}
onRemove={() => {}}
/>
```
## 3. The configuration that matters
This is the component's "Default" state — Files in context with per-file size and a remove affordance.
Every prop is at its default value. Keep the call site minimal — do not write out default values.
## 4. Wire the handlers
`onRemove` is a stub in the snippet above (`() => {}`). Connect it to this project's own state and data layer instead of shipping the empty function.
Reference: https://scrimui.dev/components/context-filesFollows the props below — change a control and the prompt changes with it, so an agent reproduces that configuration instead of the defaults.
Install
npx shadcn@latest add @scrimui/context-filesComponent source
React + Tailwind component using shadcn/ui (button). The install command adds these dependencies automatically.
When copying source manually, install the required primitives first:
npx shadcn@latest add button"use client";
import { Button } from "@/components/ui/button";
import * as React from "react";
/* ------------------------------------------------------------------ */
/* Types */
/* ------------------------------------------------------------------ */
export type ContextFile = {
name: string;
/** Human size or token detail, e.g. "48 KB" or "≈ 1.2k tokens". */
detail?: string;
};
export type ContextFilesProps = {
files: ContextFile[];
/** Token usage against the context window — renders a progress bar when provided. */
usage?: { used: number; limit: number };
onRemove?: (name: string) => void;
title?: string;
className?: string;
};
/* ------------------------------------------------------------------ */
/* Helpers */
/* ------------------------------------------------------------------ */
function FileIcon() {
return (
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" width="15" height="15">
<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" />
<path d="M14 2v4a2 2 0 0 0 2 2h4" />
</svg>
);
}
function XIcon() {
return (
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" width="12" height="12">
<path d="M18 6 6 18" />
<path d="m6 6 12 12" />
</svg>
);
}
/* ------------------------------------------------------------------ */
/* ContextFiles */
/* ------------------------------------------------------------------ */
export function ContextFiles({
files,
usage,
onRemove,
title = "Files in context",
className = "",
}: ContextFilesProps) {
const used = usage ? Math.min(usage.used / usage.limit, 1) : 0;
const pct = usage ? Math.round(used * 100) : 0;
return (
<div className={`overflow-hidden rounded-xl border border-border ${className}`}>
<div className="flex items-center justify-between bg-muted px-3 py-2">
<span className="text-sm font-medium text-foreground">{title}</span>
<span className="text-xs text-muted-foreground">
{files.length} {files.length === 1 ? "file" : "files"}
{usage && ` · ${pct}% of context`}
</span>
</div>
{files.length === 0 ? (
<div className="px-3 py-4 text-center text-xs text-muted-foreground">
No files in context yet — attach files and they’ll appear here.
</div>
) : (
<ul className="divide-y divide-border">
{files.map((file) => (
<li key={file.name} className="flex items-center gap-2.5 px-3 py-2">
<span className="shrink-0 text-muted-foreground">
<FileIcon />
</span>
<span className="min-w-0 flex-1 truncate text-sm text-foreground">
{file.name}
</span>
{file.detail && (
<span className="shrink-0 text-xs text-muted-foreground">
{file.detail}
</span>
)}
{onRemove && (
<Button variant="ghost" size="icon-sm"
type="button"
onClick={() => onRemove(file.name)}
aria-label={`Remove ${file.name}`}
className="min-h-6 min-w-6 shrink-0 rounded p-1 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground"
>
<XIcon />
</Button>
)}
</li>
))}
</ul>
)}
{usage && (
<div className="px-3 pb-2.5">
<div className="h-1 overflow-hidden rounded-full bg-muted">
<div
className={`h-full rounded-full ${pct > 85 ? "bg-red-500" : pct > 60 ? "bg-amber-500" : "bg-emerald-500"}`}
style={{ width: `${pct}%` }}
/>
</div>
</div>
)}
</div>
);
}
When to use it
- Make context visible: users behave differently when they can see exactly which files the model is reading.
- Show token pressure with a colored bar — red only past ~85% so it means something.
- Let users remove files inline; an un-editable context list feels like the model is hiding its inputs.
- Truncate long names with an ellipsis and put the size on its own, non-wrapping column.
What breaks in production
- Hiding which files were used after the fact — the user can't audit or correct a hallucination they can't trace.
- Listing internal files the user never chose; context should reflect what the user supplied or approved.
- Showing a token bar in a color that doesn't communicate urgency (a green bar at 95% is a lie).
Related Components
A drag-and-drop upload zone — per-file progress bars, type icons, and error states for files too big or of the wrong type.
The @-mention menu for adding context to a prompt — files, web pages and knowledge bases with search, recent items, access states and token cost.
How much of the context window is gone and to what — system prompt, files, history — plus what gets dropped first when the next message does not fit.
The message input at the heart of an AI chat app — file attachments, model picker, tool toggles, voice, and a send button that turns into stop.