Skip to content

@vibe-labs/design-vue-cards

Vue 3 card components for the Vibe Design System. Compositional sub-components for headers, bodies, footers, and media.

Installation

ts
import { VibeCard, VibeCardHeader, VibeCardBody, VibeCardFooter, VibeCardMedia } from "@vibe-labs/design-vue-cards";

Requires the CSS layer from @vibe-labs/design-components-cards.

Components

VibeCard

Polymorphic card container with variant styling, interactive mode, and layout modifiers.

Usage

vue
<!-- Basic card -->
<VibeCard>
  <VibeCardHeader>Title</VibeCardHeader>
  <VibeCardBody>Content goes here.</VibeCardBody>
  <VibeCardFooter>Footer actions</VibeCardFooter>
</VibeCard>

<!-- Variants -->
<VibeCard variant="elevated">Elevated with shadow</VibeCard>
<VibeCard variant="outlined">Outlined border</VibeCard>
<VibeCard variant="ghost">Transparent</VibeCard>
<VibeCard variant="gradient">Gradient background</VibeCard>
<VibeCard variant="gradient-subtle">Subtle gradient</VibeCard>
<VibeCard variant="gradient-elevated">Gradient + shadow</VibeCard>

<!-- Sizes (controls section padding) -->
<VibeCard size="sm">Compact</VibeCard>
<VibeCard size="lg">Spacious</VibeCard>

<!-- Interactive card -->
<VibeCard interactive @click="handleClick">
  <VibeCardBody>Clickable card</VibeCardBody>
</VibeCard>

<!-- Link card (auto-detects href → as="a", interactive=true) -->
<VibeCard href="/details/123">
  <VibeCardBody>Click to navigate</VibeCardBody>
</VibeCard>

<!-- Semantic element -->
<VibeCard as="article">
  <VibeCardBody>An article card</VibeCardBody>
</VibeCard>

<!-- Horizontal layout with media -->
<VibeCard horizontal>
  <VibeCardMedia>
    <img src="/cover.jpg" alt="Album cover" />
  </VibeCardMedia>
  <VibeCardBody>Side-by-side content</VibeCardBody>
</VibeCard>

<!-- Modifiers -->
<VibeCard seamless>No internal borders</VibeCard>
<VibeCard flush>No section padding</VibeCard>

Props

PropTypeDefaultDescription
variantCardVariant"default"default · elevated · outlined · ghost · gradient · gradient-subtle · gradient-elevated
sizeCardSize"md"sm · md · lg
interactivebooleanfalseHover/focus states, pointer cursor
horizontalbooleanfalseRow layout with media capped at 40%
seamlessbooleanfalseRemove internal section borders
flushbooleanfalseRemove all section padding
asstring | Component"div"Root element (auto: "a" when href set)
hrefstringLink URL (auto-enables interactive + <a> tag)

Accessibility

  • Interactive non-link cards get role="button" and tabindex="0"
  • Link cards use native <a> semantics
  • Keyboard activation (Enter/Space) for interactive non-link cards

VibeCardHeader

Flex row section with bottom border. Typically used for title and actions.

vue
<VibeCardHeader>
  <h3>Card Title</h3>
  <VibeButton variant="ghost" icon><MoreIcon /></VibeButton>
</VibeCardHeader>

VibeCardBody

Flex-grow scrollable content area.

vue
<VibeCardBody>
  <p>Main card content goes here.</p>
</VibeCardBody>

VibeCardFooter

Flex row section with top border and subtle background.

vue
<VibeCardFooter>
  <VibeButton variant="ghost">Cancel</VibeButton>
  <VibeButton>Save</VibeButton>
</VibeCardFooter>

VibeCardMedia

Overflow-hidden container for images and video. Child <img> and <video> auto-fill.

vue
<VibeCardMedia>
  <img src="/album-art.jpg" alt="Album artwork" />
</VibeCardMedia>

Props

PropTypeDefaultDescription
position"top" | "bottom"Position hint within the card

Dependencies

PackagePurpose
@vibe-labs/design-components-cardsCSS tokens + generated styles

Build

bash
npm run build

Built with Vite + vite-plugin-dts. Outputs ES module with TypeScript declarations.