Engram

Socket grid

component

The socket layout: perk sockets as side-by-side columns of circles, then mod sockets as a row of squares — the Destiny weapon perk/mod grid.

Install

npx shadcn@latest add @engram/socket-grid

Registry item: /r/socket-grid.json — the machine-readable definition agents install from.

Example

Bungie API

source the props

Fetch 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

PropTypeDefaultDescription
classNamestring
annotationsRecord<number, PlugAnnotation>Typed curated-roll annotations keyed by plug hash (rendered as default badges).
renderBadge(plug: PlugData) => ReactNodeFully override the badge for a plug (takes precedence over `annotations`).
onPlugClick(plug: PlugData) => voidCalled when a plug is clicked.
plugPopup(plug: PlugData) => ReactNodeA plug's inspect popup (e.g. a ), revealed on hover beside the parent inspect panel. Return `null` for plugs with no inspect.
sockets*SocketProps[]

Composition

pulled in on install

Dependencies

npm
@engram/core

Own 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.