Tally UI
UI

HoverCard

A floating card that appears when hovering over a trigger, useful for previewing linked content.

Import

import { HoverCard, HoverCardTrigger, HoverCardContent } from '@tallyui/components';

Usage

<HoverCard>
  <HoverCardTrigger asChild>
    <Button variant="link"><Text>@tallyui</Text></Button>
  </HoverCardTrigger>
  <HoverCardContent>
    <VStack className="gap-2">
      <Text className="text-sm font-semibold">TallyUI</Text>
      <Text className="text-sm text-muted-foreground">
        A cross-platform component library for React Native and web.
      </Text>
    </VStack>
  </HoverCardContent>
</HoverCard>

HoverCard is a styled wrapper around the HoverCard primitive. On web it opens on hover; on native it responds to taps. Content text is styled through TextClassContext so descendant Text components pick up text-popover-foreground automatically. For full accessibility and behavior details, see the primitive docs.

Components

HoverCardContent

The floating card that appears near the trigger. Renders through a portal automatically.

Default classes: z-50 w-64 rounded-md border border-border bg-popover p-4 text-popover-foreground shadow-md outline-none

PropTypeDefaultDescription
align'start' | 'center' | 'end''center'Horizontal alignment relative to the trigger
sideOffsetnumber4Distance in pixels between the trigger and the card
side'top' | 'bottom' | 'left' | 'right''bottom'Which side of the trigger to position the card
classNamestring--Additional NativeWind classes merged via cn()

Plus all props from the HoverCard primitive's Content component.

Props

PropTypeDefaultDescription
openboolean--Controlled open state
defaultOpenboolean--Uncontrolled initial open state
onOpenChange(open: boolean) => void--Called when the open state changes
openDelaynumber--Delay in ms before the card appears on hover
closeDelaynumber--Delay in ms before the card hides after hover ends

HoverCardTrigger accepts asChild to merge props onto a custom child element.

Examples

User profile card

<HoverCard>
  <HoverCardTrigger asChild>
    <Button variant="link"><Text>@johndoe</Text></Button>
  </HoverCardTrigger>
  <HoverCardContent>
    <VStack className="gap-3">
      <HStack className="items-center gap-3">
        <Avatar src="https://example.com/photo.jpg" alt="John Doe" size="lg" />
        <VStack className="gap-0.5">
          <Text className="text-sm font-semibold">John Doe</Text>
          <Text className="text-xs text-muted-foreground">@johndoe</Text>
        </VStack>
      </HStack>
      <Text className="text-sm text-muted-foreground">
        Software engineer working on design systems and component libraries.
      </Text>
      <Text className="text-xs text-muted-foreground">Joined December 2021</Text>
    </VStack>
  </HoverCardContent>
</HoverCard>

Custom width and alignment

<HoverCard>
  <HoverCardTrigger asChild>
    <Button variant="link"><Text>Project Details</Text></Button>
  </HoverCardTrigger>
  <HoverCardContent className="w-80" align="start">
    <VStack className="gap-2">
      <Text className="text-sm font-semibold">TallyUI Primitives</Text>
      <Text className="text-sm text-muted-foreground">
        A headless, cross-platform component library for React Native and web.
        Built with accessibility and composition in mind.
      </Text>
    </VStack>
  </HoverCardContent>
</HoverCard>

Controlled hover card

const [open, setOpen] = useState(false);

<HoverCard open={open} onOpenChange={setOpen}>
  <HoverCardTrigger asChild>
    <Button variant="link"><Text>Hover or tap</Text></Button>
  </HoverCardTrigger>
  <HoverCardContent>
    <Text className="text-sm">
      Controlled: {open ? 'visible' : 'hidden'}
    </Text>
  </HoverCardContent>
</HoverCard>

On this page