Display
Package Info
A contract-driven package change card with version, dependency, loading, empty and error states.
Preview in your theme
Loading preview…
Installation
npx shadcn@latest add https://ui.zyeon.ai/r/package-info.jsonPrompt
Build a React + TypeScript + Tailwind "PackageInfo" component using zod,
lucide-react and the local cn() utility.
Contract
- Export packageChangeTypeSchema, packageDependencySchema, packageRecordSchema
and packageInfoSchema from package-info.contract.ts, plus their inferred
TypeScript types. The root schema is a discriminated union on status:
loading, empty, error { errorMessage }, or ready { package }.
- A ready package contains id, name, optional description, optional
currentVersion/newVersion, changeType = major | minor | patch | added |
removed, and dependencies [{ id, name, version }].
- Export a forwardRef<HTMLElement> PackageInfo. Its props combine the inferred
PackageInfoData union with native article attributes (except children);
className is merged with cn() and remaining native props reach the root.
Behavior
- Treat all four statuses as first-class synchronous branches. Loading renders
an aria-busy skeleton, empty renders a neutral selection hint, error uses
role="alert" and its contract message, and ready renders the package record.
- In ready state, label the article from the package name, map changeType to a
readable chip, show a version transition when either version exists, and
omit the dependency section when the array is empty.
- Keep the visual transition arrow decorative, but pair current and target
values with sr-only labels and announce the transition direction as
"updates to". A lone version must still be identified as current or target.
- Preserve source order for dependencies. Truncate only long package/dependency
names; allow version strings such as git URLs and commit hashes to break
across narrow cards instead of overflowing.
Rendering & styling
- Use semantic tokens only: bg-card, bg-muted, bg-primary/10,
bg-destructive/10, text-card-foreground, text-muted-foreground,
text-primary, text-destructive and border. Merge className with cn().
- Lucide glyphs are decorative and aria-hidden. Loading copy remains available
to screen readers through sr-only text; the skeleton pulse uses
motion-reduce:animate-none.
- Version semantics do not depend on the aria-hidden arrow: sr-only copy names
current and target values and supplies the transition phrase.
- Give the ready article an accessible label derived from the package name;
keep the contract id as business data rather than interpolating it into a DOM
id, where arbitrary API values may be unsafe or duplicate.
- Keep the component server-renderable: it needs no hooks, browser APIs or
client-only directive.
Customization levers
- Change card density at the three section wrappers without altering the
contract or state branches.
- Add a changeType by extending the zod enum and the label, icon and token maps
together; do not infer severity from a hardcoded color.
- Hide the version or dependency blocks by transforming the ready payload
before render, or replace those blocks with slots while keeping the
discriminated status union intact.
- Swap Package/Refresh icons, change the dependency row density, or map chip
treatments to a product's semantic status tokens.Concepts
- Discriminated render state — every branch has a valid, minimal payload, so impossible combinations such as an error without a message never reach the renderer.
- Semantic change severity —
changeTypedrives label, icon and token treatment together; color is reinforcement rather than the only meaning. - Version transition — current and target versions form a directional change, while either value can stand alone for added or removed packages.
- Dependency summary — the card preserves producer order and shows only direct dependencies, keeping the surface scannable instead of pretending to be a full dependency graph.
Scroll Area
A themed scroll container that keeps native scrolling untouched — the platform bar is hidden and a draggable thumb is drawn from scrollTop/scrollHeight, with optional edge fades and an end-reached callback.
Animated Beam
A resize-aware SVG connection that carries a token-colored highlight between referenced interface nodes.