UI Primitives (components/ui/*)
Vendored shadcn/ui pattern (Radix + class-variance-authority + cn() from lib/utils.ts:4 = twMerge(clsx)). Not a barrel npm component library — edit in place or regenerate from shadcn. All primitives verified under webui/src/components/ui/*.tsx (17 files enumerated glob:*).
Inventory
| File | Underlying | Exports | Key props / notes |
|---|---|---|---|
button.tsx:6 | Radix Slot + cva | Button, buttonVariants | `variant default |
badge.tsx:5 | cva div | Badge, badgeVariants | `variant default |
card.tsx:4 | div | Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter | Card hover:shadow-md hover:-translate-y-0.5 (card.tsx:8), default padding p-4, header space-y-1.5 |
dialog.tsx | Radix Dialog | Dialog, DialogTrigger, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter | used for Help/Permission/Skill add/delete, Home notice. DialogContent sm:max-w-* |
input.tsx | native input | Input | h-9 border-input bg-background |
label.tsx | Radix Label | Label | text-sm font-medium |
textarea.tsx | native textarea | Textarea | min-h-[80px] for ManualToolPanel JSON |
tabs.tsx | Radix Tabs | Tabs, TabsList, TabsTrigger, TabsContent | RunPage TabsTrigger h-6 px-2 text-xs, Artifacts/Run tabs |
select.tsx | Radix Select | Select, SelectTrigger, SelectValue, SelectContent, SelectItem | RunList sort, Skills page sort |
checkbox.tsx | Radix Checkbox | Checkbox | ToggleRow, GraphFilters, RunWizard skip-confirm |
switch.tsx | Radix Switch | Switch | Skills Configuration master + feature switches |
popover.tsx | Radix Popover | Popover, PopoverTrigger, PopoverContent | SkillRowActions, skill tag filter |
tooltip.tsx | Radix Tooltip | TooltipProvider, Tooltip, TooltipTrigger, TooltipContent | Stats page metric help, icon hints (delayDuration 120) |
toast.tsx | Radix Toast | Toast, ToastProvider, ToastViewport + hooks/use-toast.ts store | Toaster (components/Toaster.tsx) viewport for useToast |
scroll-area.tsx | Radix ScrollArea | ScrollArea, ScrollBar | RunPage tab list (type scroll), Artifacts tabs |
separator.tsx | Radix Separator | Separator | vertical/horizontal dividers |
skeleton.tsx | div | Skeleton | skeleton shimmer bg index.css:150 + h-4 w-* placeholders (components/Loading.tsx re-exports shaped rows) |
Also present via glob: components.json (shadcn config), tailwind.config.ts Radix-animate wiring.
Custom wrappers (non-ui)
These are app components, not primitives, but are shared "mini-primitives":
| Component | File | Purpose |
|---|---|---|
StatusBadge | components/StatusBadge.tsx | RunState → colored Badge (draft/awaiting/queued/running/... variants) |
CopyButton | components/CopyButton.tsx | clipboard copy value + icon/label, `size sm |
Loading | components/Loading.tsx | Spinner, SkeletonRows(count), SkeletonCards(count), Skeleton, ErrorState(message,onRetry), EmptyState(message) |
Toaster | components/Toaster.tsx | Radix Toast viewport + useToast consumer |
ErrorBoundary | components/ErrorBoundary.tsx | class component wrapping App (main.tsx:10) |
Patterns
buttonVariants/badgeVariantsarecvasocn(buttonVariants({variant,size,className}))merges correctly with overrides (Badgein risk filters passesactiveCls).Cardhover translate is subtle (-translate-y-0.5) but visible onGoalCard,Skillrows,ModuleRow. Disable via extraclassNamewhenblocked(GoalsPage).- Dialogs: every destructive action confirms via
Dialog(RunList delete, Skills delete, Cancel run). Props mirror Radix —open/onOpenChange,DialogHeader/Title/Description/Footer. - Inputs: filter fields use
h-8 text-xs(RunList, Artifacts), skills searchh-9 pl-8, dialog inputsh-9 font-mono. TabsListin RunPage ish-7 bg-transparent p-0.5withTabsTrigger h-6 text-xs, plus a separator|.- Accessibility: all icons have
aria-hidden, interactive elements exposearia-label,aria-pressed, tables havesr-only caption.
Styling hooks
Colors via CSS vars (card.tsx:8 border bg-card text-card-foreground etc.) from index.css. Utilities cn resolves conflicts (e.g. border-primary vs border-border precedence). See docs/webui/build.md for Tailwind config.
source: repo docs (build sync)Edit this page on GitHub →