npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@todovue/tv-card

v1.1.3

Published

TvCard is a customizable and flexible card component for Vue 3 applications, ideal for showcasing content with a title, image, description, and action buttons. It supports additional elements like secondary buttons and labels for enhanced interactivity an

Readme

TODOvue Card (TvCard)

A flexible and customizable Vue 3 card component for showcasing content with title, image, description, and action buttons. Perfect for Single Page Apps and Server-Side Rendered (SSR) environments like Nuxt 4.

npm npm downloads npm total downloads License Release Date Bundle Size Node Version Last Commit Stars

Demo: https://ui.todovue.blog/card


Table of Contents


Features

  • Clean and modern card layout with image, title, and description
  • Primary and secondary action buttons
  • Label/tag support with customizable limit
  • Fully customizable color scheme (background, text, button styles)
  • Click events for buttons and labels
  • Works seamlessly in SPA and SSR (Nuxt 3) contexts
  • Built on top of @todovue/tv-button and @todovue/tv-label
  • Tree-shake friendly (Vue marked external in library build)
  • TypeScript support

Installation

Using npm:

npm install @todovue/tv-card

Using yarn:

yarn add @todovue/tv-card

Using pnpm:

pnpm add @todovue/tv-card

Style usage

Vue 3 SPA (Vite)

// main.ts
import { createApp } from 'vue'
import App from './App.vue'

import '@todovue/tv-card/style.css'
import '@todovue/tv-button/style.css'
import '@todovue/tv-style/style.css'
import { TvCard } from '@todovue/tv-card'

const app = createApp(App)
app.component('TvCard', TvCard)
app.mount('#app')

Nuxt 3/4

// nuxt.config.ts
export default defineNuxtConfig({
  modules: [
    '@todovue/tv-card/nuxt'
  ]
})

Quick Start (SPA)

Global registration (main.js / main.ts):

import { createApp } from 'vue'
import App from './App.vue'
import { TvCard } from '@todovue/tv-card'

createApp(App)
  .use(TvCard) // enables <TvCard /> globally
  .mount('#app')

Local import inside a component:

<script setup>
import { TvCard } from '@todovue/tv-card'
import { ref } from 'vue'

const configCard = ref({
  title: 'Create Vue.js',
  description: 'Vue.js (commonly known as Vue; pronounced /vju/...',
  alt: 'Card Image',
  image: 'https://todovue.com/vue.webp',
  primaryButtonText: 'View more',
})

function handleButton() {
  console.log('Button clicked')
}
</script>

<template>
  <TvCard :configCard="configCard" @click-button="handleButton" />
</template>

Nuxt 3 / SSR Usage

Create a plugin file: plugins/tv-card.client.ts (client-only is fine, or without suffix for SSR as it is safe):

import { defineNuxtPlugin } from '#app'
import { TvCard } from '@todovue/tv-card'

export default defineNuxtPlugin(nuxtApp => {
  nuxtApp.vueApp.use(TvCard)
})

Use anywhere:

<template>
  <TvCard :configCard="myConfig" @click-button="handleAction" />
</template>

Optional direct import (no plugin):

<script setup>
import { TvCard } from '@todovue/tv-card'
</script>

Component Registration Options

| Approach | When to use | |-------------------------------------------------------------------|------------------------------------------------| | Global via app.use(TvCard) | Many usages across app / design system install | | Local named import { TvCard } | Isolated / code-split contexts | | Direct default import import { TvCard } from '@todovue/tv-card' | Single usage or manual registration | | Plugin import { TvCardPlugin } | Explicit plugin installation |


Props

| Prop Name | Type | Required | Default | Description | |--------------|---------|----------|---------|-------------------------------------------------| | configCard | object | Yes | - | Configuration object for the card (see below). | | isHorizontal | boolean | No | false | If true, renders the card in horizontal layout. |

The component accepts a single prop configCard which is an object with the following structure:

| Property | Type | Required | Default | Description | |----------------------------------|----------|----------|---------|--------------------------------------------------| | title | string | Yes | - | Card title text. | | description | string | Yes | - | Card description/content text. | | image | string | Yes | - | URL of the card image. | | alt | string | No | '' | Alt text for the image (accessibility). | | primaryButtonText | string | Yes | - | Text for the primary action button. | | secondaryButtonText | string | No | - | Text for the secondary action button (optional). | | labels | array | No | - | Array of label objects {id, name, color}. | | limitLabels | number | No | 3 | Maximum number of labels to display. | | backgroundColor | string | No | - | Custom background color for the card. | | color | string | No | - | Custom text color for the card. | | backgroundButtonColor | string | No | - | Custom background color for primary button. | | colorButton | string | No | - | Custom text color for primary button. | | backgroundButtonSecondaryColor | string | No | - | Custom background color for secondary button. | | colorButtonSecondary | string | No | - | Custom text color for secondary button. |

Label Object Structure

{
  id: 1,              // Unique identifier
  name: 'JavaScript', // Label text
  color: '#F7DF1E'    // Label color (hex, rgb, etc.)
}

Events

| Event name (kebab) | Payload | Description | |--------------------------|--------------|-------------------------------------------------| | click-button | - | Emitted when primary button is clicked. | | click-secondary-button | - | Emitted when secondary button is clicked. | | click-label | label object | Emitted when a label is clicked, returns label. |

Usage:

<TvCard 
  :configCard="config"
  @click-button="onPrimaryAction" 
  @click-secondary-button="onSecondaryAction"
  @click-label="onLabelClick"
/>

Customization (Styles / Theming)

The card supports extensive customization through the configCard object:

Basic Card with Custom Colors

<script setup>
import { ref } from 'vue'
import { TvCard } from '@todovue/tv-card'

const configCard = ref({
  title: 'Custom Styled Card',
  description: 'This card has custom colors applied',
  image: 'https://example.com/image.jpg',
  primaryButtonText: 'Action',
  backgroundColor: '#46627f',
  color: '#ffffff',
  backgroundButtonColor: '#062131',
  colorButton: '#ffffff'
})
</script>

<template>
  <TvCard :configCard="configCard" />
</template>

Card with Labels

<script setup>
import { ref } from 'vue'
import { TvCard } from '@todovue/tv-card'

const configCard = ref({
  title: 'Vue.js Tutorial',
  description: 'Learn Vue.js with these comprehensive guides',
  image: 'https://todovue.com/vue.webp',
  primaryButtonText: 'Start Learning',
  labels: [
    { id: 1, name: 'JavaScript', color: '#F7DF1E' },
    { id: 2, name: 'HTML', color: '#E34F26' },
    { id: 3, name: 'CSS', color: '#1572B6' }
  ],
  limitLabels: 2 // Only show 2 labels
})
</script>

<template>
  <TvCard :configCard="configCard" @click-label="handleLabelClick" />
</template>

Card with Two Buttons

<script setup>
import { ref } from 'vue'
import { TvCard } from '@todovue/tv-card'

const configCard = ref({
  title: 'Advanced Vue Tutorial',
  description: 'Deep dive into Vue.js advanced concepts',
  image: 'https://todovue.com/vuejs.webp',
  primaryButtonText: 'Read Article',
  secondaryButtonText: 'View Source',
  backgroundButtonColor: '#062131',
  colorButton: '#ffffff',
  backgroundButtonSecondaryColor: '#0eb096',
  colorButtonSecondary: '#000000'
})

function handlePrimary() {
  console.log('Primary action')
}

function handleSecondary() {
  console.log('Secondary action')
}
</script>

<template>
  <TvCard 
    :configCard="configCard"
    @click-button="handlePrimary"
    @click-secondary-button="handleSecondary"
  />
</template>

Examples

Check out the demo files in src/utils/demos/ for more examples:

  • default.vue - Basic card usage
  • withCustomColors.vue - Full customization example
  • withLabels.vue - Card with labels
  • withMultipleLabels.vue - Card with label limit
  • withTwoButtons.vue - Card with primary and secondary buttons

Accessibility

  • Always provide alt text for images for screen readers.
  • Button text should be descriptive of the action.
  • Label clicks are keyboard accessible through the underlying TvLabel component.
  • Color contrast should be considered when using custom colors.

SSR Notes

  • No direct DOM (window / document) access in source → safe for SSR.
  • Styles are automatically applied when you import the library.
  • The component works seamlessly with Nuxt 3's server-side rendering.
  • Dependencies (@todovue/tv-button and @todovue/tv-label) are SSR-compatible.
  • Ensure you import @todovue/tv-card/style.css in an SSR-compatible entry if needed.

Development

git clone https://github.com/TODOvue/tv-card.git
cd tv-card
npm install
npm run dev     # run demo playground
npm run build   # build library

Local demo served from Vite using index.html + src/demo examples.


Contributing

PRs and issues welcome. See CONTRIBUTING.md and CODE_OF_CONDUCT.md.


License

MIT © TODOvue


Attributions

Crafted for the TODOvue component ecosystem