Item popup
componentThe item inspect flyout — a dark glass panel modeled on the in-game tooltip: a rarity header band, a damage-type + power/ammo readout, flavor, an optional kill tracker, the stat block, the intrinsic frame row, a perk band (`children`, e.g. a `SocketGrid`), and an action `footer` (e.g. Apply).
Install
npx shadcn@latest add @engram/item-popupRegistry item: /r/item-popup.json — the machine-readable definition agents install from.
Example
Festival Flight
Grenade Launcher
LegendaryLight up the sky anew.
Bungie API
source the propsFetch the data with @engram/api (a typed bungie-api-ts client) and map it to this component's props with @engram/core. This is the exact code the docs' live examples run.
/** Resolve a Bungie name → membership, then fetch that profile. Returns a
* bungie-api-ts DestinyProfileResponse. */
export async function fetchProfile(
client: BungieClient,
bungieName: string,
components: DestinyComponentType[] = PROFILE_COMPONENTS,
): Promise<DestinyProfileResponse> {
const memberships = await client.searchByBungieName(bungieName);
const membership = memberships.find((m) => m.membershipId) ?? memberships[0];
if (!membership) throw new Error(`No Destiny profile for "${bungieName}"`);
return client.getProfile(
membership.membershipType,
membership.membershipId,
components,
);
}
export function resolveEquipped(
profile: DestinyProfileResponse,
characterId: string,
getDef: GetDefinition,
): ResolvedItem[] {
const equip = profile.characterEquipment?.data?.[characterId]?.items ?? [];
const instances = profile.itemComponents?.instances?.data ?? {};
const stats = profile.itemComponents?.stats?.data ?? {};
const sockets = profile.itemComponents?.sockets?.data ?? {};
const reusable = profile.itemComponents?.reusablePlugs?.data ?? {};
return equip
.map((it) => {
const id = it.itemInstanceId;
return resolveItem(
it,
{
instance: id ? instances[id] : undefined,
stats: id ? stats[id]?.stats : undefined,
sockets: id ? sockets[id]?.sockets : undefined,
reusablePlugs: id ? reusable[id]?.plugs : undefined,
},
getDef,
);
})
.filter((r): r is ResolvedItem => r !== null);
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
header* | HeaderData | — | — |
seasonIcon | ImageRef | — | Season watermark shown in the header's tier strip (matches the tile). |
archetype | { name: string; icon?: ImageRef } | — | New-armor archetype (Brawler/Paragon/…) shown beside the power readout. |
stats | StatProps[] | — | — |
frame | WeaponFrameRef | — | Intrinsic frame row (weapons). |
tracker | ItemTracker | — | Kill / usage tracker row. |
annotations | ItemAnnotations | — | Typed curated-roll annotations — verdict + tags. |
children | ReactNode | — | Perk / socket content (e.g. a `SocketGrid`). |
footer | ReactNode | — | Action buttons (e.g. Apply / Compare). |
className | string | — | — |
Composition
pulled in on install- item-popupcomponent
- bungie-imageatom
- chipatom
- item-hover-cardcomponent
- item-popup-headercomponent
- tier-watermarkcomponent
- item-statscomponent
- segmented-baratom
- panelatom
- roll-verdictcomponent
Dependencies
npmOwn the code: shadcn add copies this component's source into your repo to read and edit directly. Extend without forking — edit the source, use asChild to swap the element, or pass the typed annotations prop for curated data.