TODOvue Demo Catalog (TvDemo)

February 12, 2026 · View on GitHub

TODOvue logo

TODOvue Demo Catalog (TvDemo)

A flexible, framework-agnostic Vue 3 component catalog for demos, documentation, and playgrounds. Compatible with both SPA and SSR (Nuxt 3), with automatic style injection and no DOM assumptions.

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

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

Table of Contents

Features

  • Visual catalog for Vue 3 components with live variants.
  • SPA and SSR (Nuxt 3) compatible.
  • Automatic import of global and highlight.js styles (no manual CSS import needed).
  • Interactive code highlighting and Markdown documentation support.
  • Modular structure, easy to extend.
  • Tree-shake friendly and ready for modern bundlers.

Installation

Using npm:

npm install @todovue/tv-demo

Using yarn:

yarn add @todovue/tv-demo

Using pnpm:

pnpm add @todovue/tv-demo

Usage of Styles

Vue/Vite (SPA)

Import the CSS generated by the library in your main entry file:

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

import '@todovue/tv-demo/style.css'
import { TvDemo } from '@todovue/tv-demo'

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

Nuxt 3/4

Add the library's CSS to your Nuxt configuration:

// nuxt.config.ts
export default defineNuxtConfig({
  css: ['@todovue/tv-demo/style.css'],
})

Quick Start (SPA)

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

import { createApp } from 'vue'
import App from './App.vue'
import TvDemo from '@todovue/tv-demo'

createApp(App)
  .component('TvDemo', TvDemo)
  .mount('#app')

Local import inside a component:

<script setup>
import { TvDemo } from '@todovue/tv-demo'
</script>

<template>
  <TvDemo />
</template>

Nuxt 4 / SSR Usage

Create a plugin file: plugins/tv-demo.client.ts (or without suffix for SSR, it's safe):

import { defineNuxtPlugin } from '#app'
import TvDemo from '@todovue/tv-demo'

export default defineNuxtPlugin(nuxtApp => {
  nuxtApp.vueApp.component('TvDemo', TvDemo)
})

Use anywhere:

<TvDemo />

Direct import (no plugin):

<script setup>
import { TvDemo } from '@todovue/tv-demo'
</script>

Component Registration Options

ApproachWhen to use
Global via app.component('TvDemo', TvDemo)Frequent use across the app
Local named import { TvDemo }Isolated/code-split contexts
Direct default import import TvDemo from ...Single use or manual registration

Props

NameTypeDefaultDescriptionRequired
componentObjectComponent to displaytrue
variantsArrayVariations of the componenttrue
hideBackgroundBooleanfalseHide the background of the component demofalse
demoStyleObjectStyle of the componentfalse
componentNameStringnullName of the component to display in the demofalse
npmInstallStringnullCommand to install the component (without npm install)false
sourceLinkStringnullLink to the source code of the componentfalse
urlCloneStringnullLink to clone the repository of the component (without git clone)false
isDevComponentBooleanfalseIndicates that the component is in development (to include -D)false
versionString1.0.0Version of the componentfalse
readmePathString./README.mdPath to the README file of the componentfalse
showDocumentationBooleantrueShow or hide the documentation tabfalse
showChangelogBooleantrueShow or hide the changelog tabfalse
manualEmitsArray[]List of event names to listen relative to the componentfalse

Events

Event nameDescription
select-demoEmitted when a demo/variant is selected

Usage:

<TvDemo @select-demo="onSelectDemo" />

Manual Emits (for async components):

<TvDemo
  :component="AsyncComponent"
  :manual-emits="['click', 'submit']"
  :variants="demos"
/>

Customization (Styles)

  • All global and highlight.js styles are injected automatically.
  • You can override styles by passing the demoStyle prop:
const demoStyle = ref({
  dark: {
    backgroundBody: "#000000",
    backgroundContent: "#1f1f1f",
    color: "#ffffff",
  },
  light: {
    backgroundBody: "#ffffff",
    backgroundContent: "#f5f5f5",
    color: "#000000",
  },
});

Use in your component:

<TvDemo :component="component" :variants="demos" :demoStyle="demoStyle" />

You can provide colors for both dark and light themes, or just one. Defaults are used if not provided.

SSR Notes

  • No direct DOM (window / document) access in the source code—safe for SSR.
  • Styles are injected automatically when you import the library.
  • Code highlighting works in both Vite and Nuxt.
  • Markdown documentation is supported by placing your README.md in the public/ folder and referencing it via the readmePath prop.

Development

git clone https://github.com/TODOvue/tv-demo.git
cd tv-demo
yarn install
yarn dev     # run local demo
yarn build   # build library

The local demo is served with Vite using index.html and examples in src/demo.

Contributing

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

License

MIT © TODOvue

Attributions

Crafted for the TODOvue component ecosystem