Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
8077f5f
chore(release): update release workflow for pull-requests and change …
CristhianDaza Jan 23, 2026
2b5d7cb
chore(release): update release workflow to use GitHub App token and s…
CristhianDaza Jan 24, 2026
904ba24
feat(TvUi): implement routing and demo component loading for TodoVue UI
CristhianDaza Jan 27, 2026
3df9e75
feat(TvUi): add routing and styles for tv-label component
CristhianDaza Jan 27, 2026
f00ccd2
feat(TvUi): add TvButton component with demo and asset copying script
CristhianDaza Jan 27, 2026
60b1937
chore(deps): update @todovue/tv-demo to version 1.4.11
CristhianDaza Jan 27, 2026
4fc440b
feat(TvUi): add TvRelativeTime component with routing and demo docume…
CristhianDaza Jan 27, 2026
43be4d3
feat(TvUi): enhance Home.vue with dynamic demo links and add TvThemeB…
CristhianDaza Jan 27, 2026
4513337
feat(TvUi): add @todovue/tv-alert dependency and update styles for in…
CristhianDaza Jan 27, 2026
5859ccc
feat(TvUi): add @todovue/tv-hero component with styles and documentation
CristhianDaza Jan 27, 2026
282a58b
feat(TvUi): add @todovue/tv-modal component with styles, documentatio…
CristhianDaza Jan 27, 2026
4fa8969
feat(TvUi): add @todovue/tv-breadcrumbs component with styles, docume…
CristhianDaza Jan 27, 2026
63b2b00
feat(TvUi): add @todovue/tv-search component with styles, documentati…
CristhianDaza Jan 27, 2026
1fcebdd
feat(TvUi): add @todovue/tv-menu component with styles, documentation…
CristhianDaza Jan 27, 2026
87ce19f
feat(TvUi): add @todovue/tv-sidebar component with styles, documentat…
CristhianDaza Jan 27, 2026
cebe3c4
feat(TvUi): add @todovue/tv-pagination component with styles, documen…
CristhianDaza Jan 27, 2026
6d8f51a
feat(TvUi): add @todovue/tv-card component with styles, documentation…
CristhianDaza Jan 27, 2026
aedb35e
feat(TvUi): add @todovue/tv-settings component with styles, documenta…
CristhianDaza Jan 27, 2026
1e50fb1
feat(TvUi): add @todovue/tv-toc component with styles, documentation,…
CristhianDaza Jan 27, 2026
0dd2b4b
feat(TvUi): add @todovue/tv-scroll-top component with styles, documen…
CristhianDaza Jan 27, 2026
9cf5e76
feat(TvUi): add @todovue/tv-progress-bar component with styles, docum…
CristhianDaza Jan 28, 2026
6a6aa8d
feat(TvUi): add @todovue/tv-footer component with styles, documentati…
CristhianDaza Jan 28, 2026
40c6860
feat(TvUi): add @todovue/tv-article component with styles, documentat…
CristhianDaza Jan 28, 2026
a2f3d50
chore(TvUi): update package dependencies and remove console log from …
CristhianDaza Jan 28, 2026
0ac305e
feat(TvUi): add multiple component styles to Nuxt configuration
CristhianDaza Jan 28, 2026
9d6273a
feat(TvUi): add TvScrollTop component and enhance Home layout with co…
CristhianDaza Jan 28, 2026
4e213e7
feat(TvUi): integrate TvFooter component and update Home layout with …
CristhianDaza Jan 28, 2026
4038bf0
feat(release): add demo website build and deployment steps to release…
CristhianDaza Jan 28, 2026
d1b22cc
feat(TvUi): refactor component registration and import styles for new…
CristhianDaza Jan 28, 2026
6d6dbdd
feat(vite): update external dependencies to include scoped packages
CristhianDaza Jan 28, 2026
7bf496a
feat(build): simplify build script by removing asset copy step
CristhianDaza Jan 28, 2026
5696784
feat(docs): update README to clarify package purpose and installation…
CristhianDaza Jan 28, 2026
6c799b9
feat(changelog): add initial release notes for @todovue/tv-ui
CristhianDaza Jan 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 45 additions & 22 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Publish to npm and GitHub Packages
name: Publish to npm and Deploy

on:
pull_request:
Expand All @@ -16,23 +16,35 @@ jobs:
actions: write
id-token: write
packages: write
pull-requests: write

steps:
- name: Generate token from GitHub App
id: generate_token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}

- name: Checkout repository
uses: actions/checkout@v4
with:
token: ${{ steps.generate_token.outputs.token }}
fetch-depth: 0
persist-credentials: true

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
registry-url: https://registry.npmjs.org/
cache: 'npm'

- name: Install dependencies
run: npm install
run: npm ci

- name: Determine version bump
id: version
id: version_type
run: |
if [[ "${{ github.event.pull_request.title }}" == *"major"* ]]; then
echo "BUMP_TYPE=major" >> $GITHUB_ENV
Expand All @@ -42,16 +54,24 @@ jobs:
echo "BUMP_TYPE=patch" >> $GITHUB_ENV
fi

- name: Bump version and push tag
- name: Configure Git
run: |
git config user.name "TODOvue-release-bot[bot]"
git config user.email "TODOvue-release-bot[bot]@users.noreply.github.com"
git config url."https://x-access-token:${{ steps.generate_token.outputs.token }}@github.com/".insteadOf "https://github.com/"

- name: Bump version and push
id: bump
run: |
git config --global user.name "github-actions"
git config --global user.email "actions@github.com"
npm version $BUMP_TYPE --no-git-tag-version
git commit -am "chore(release): 🔥 v$(node -p "require('./package.json').version")"
git tag v$(node -p "require('./package.json').version")
git push origin main --tags
npm version $BUMP_TYPE -m "chore(release): 🔥 v%s [skip ci]"
NEW_VERSION=$(node -p "require('./package.json').version")
echo "NEW_VERSION=$NEW_VERSION" >> $GITHUB_OUTPUT
git push origin main --follow-tags
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GIT_AUTHOR_NAME: "TODOvue-release-bot[bot]"
GIT_AUTHOR_EMAIL: "TODOvue-release-bot[bot]@users.noreply.github.com"
GIT_COMMITTER_NAME: "TODOvue-release-bot[bot]"
GIT_COMMITTER_EMAIL: "TODOvue-release-bot[bot]@users.noreply.github.com"

- name: Build package
run: npm run build
Expand All @@ -61,22 +81,25 @@ jobs:
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Setup Node.js for GitHub Packages
uses: actions/setup-node@v4
- name: Create GitHub Release
uses: actions/github-script@v7
with:
node-version: 20
registry-url: https://npm.pkg.github.com
scope: '@todovue'

- name: Publish to GitHub Packages
run: npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
github-token: ${{ steps.generate_token.outputs.token }}
script: |
await github.rest.repos.createRelease({
owner: context.repo.owner,
repo: context.repo.repo,
tag_name: `v${{ steps.bump.outputs.NEW_VERSION }}`,
name: `v${{ steps.bump.outputs.NEW_VERSION }}`,
body: 'For stable releases, please refer to [CHANGELOG.md](https://github.com/TODOvue/tv-demo/blob/main/CHANGELOG.md) for details.',
draft: false,
prerelease: false
});

- name: Build Demo Website
run: npm run build:demo

- name: Deploy Demo to FTP
- name: Deploy TODOvue UI
uses: SamKirkland/FTP-Deploy-Action@v4.3.4
with:
server: ${{ secrets.FTP_SERVER }}
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,8 @@ All notable changes to `@todovue/tv-ui` will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.1.0] - 2026-01-27

### Added
- Initial release of `@todovue/tv-ui`.
205 changes: 203 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,207 @@
<p align="center"><img width="150" src="https://res.cloudinary.com/dcdfhi8qz/image/upload/v1763663056/uqqtkgp1lg3xdplutpga.png" alt="TODOvue logo">
</p>

# TODOvue TvUi
###### TvUi - A TODOvue based UI library.
# TODOvue UI (TvUi)
An **umbrella** package for Vue 3 that installs and re-exports the official `@todovue/*` components.

> Important: **this is NOT a monorepo**. `@todovue/tv-ui` is a library that declares dependencies on each `@todovue/tv-*` component (by the version published on npm), and re-exports them for unified consumption.

[![npm](https://img.shields.io/npm/v/@todovue/tv-ui.svg)](https://www.npmjs.com/package/@todovue/tv-ui)
[![npm downloads](https://img.shields.io/npm/dm/@todovue/tv-ui.svg)](https://www.npmjs.com/package/@todovue/tv-ui)
[![npm total downloads](https://img.shields.io/npm/dt/@todovue/tv-ui.svg)](https://www.npmjs.com/package/@todovue/tv-ui)
![License](https://img.shields.io/github/license/TODOvue/tv-ui)
![Release Date](https://img.shields.io/github/release-date/TODOvue/tv-ui)
![Bundle Size](https://img.shields.io/bundlephobia/minzip/@todovue/tv-ui)
![Node Version](https://img.shields.io/node/v/@todovue/tv-ui)
![Last Commit](https://img.shields.io/github/last-commit/TODOvue/tv-ui)
![Stars](https://img.shields.io/github/stars/TODOvue/tv-ui?style=social)

> Demo / docs: https://ui.todovue.blog

## Table of contents
- [Features](#features)
- [Installation](#installation)
- [Quick Start (SPA)](#quick-start-spa)
- [Using styles](#using-styles)
- [Nuxt (SSR) / Nuxt Module](#nuxt-ssr--nuxt-module)
- [Exported components](#exported-components)
- [Registration options](#registration-options)
- [SSR notes](#ssr-notes)
- [Development](#development)
- [Contributing](#contributing)
- [License](#license)

## Features
- **One-time install** to get TODOvue components available.
- **Vue plugin**: `app.use(TvUi)` registers components globally.
- **Re-exports**: you can import specific components from `@todovue/tv-ui`.
- Compatible with **SPA** (Vite/Vue CLI) and **SSR** (Nuxt) as long as your app imports the styles.
- **Does not bundle Vue nor the `@todovue/*` packages** into the build: they remain external dependencies (great for ecosystems and tree-shaking).

## Installation
With npm:
```bash
npm install @todovue/tv-ui
```
With yarn:
```bash
yarn add @todovue/tv-ui
```
With pnpm:
```bash
pnpm add @todovue/tv-ui
```

> Node requirement for this repo: `>= 20.19.0`.

## Quick Start (SPA)
Global registration (main.js / main.ts):
```js
import { createApp } from 'vue'
import App from './App.vue'

// Styles (see “Using styles” section)
import '@todovue/tv-ui/style.css'

import TvUi from '@todovue/tv-ui'

createApp(App)
.use(TvUi) // enables <TvButton />, <TvCard />, etc. globally
.mount('#app')
```

Usage in a component:
```vue
<template>
<TvButton variant="success" icon="check">Save</TvButton>
</template>
```

Local import (named export) if you prefer granular control:
```vue
<script setup>
import '@todovue/tv-ui/style.css'
import { TvButton, TvCard } from '@todovue/tv-ui'
</script>

<template>
<TvCard>
<TvButton>Action</TvButton>
</TvCard>
</template>
```

## Using styles
`@todovue/tv-ui` exposes a styles entry:

- Recommended import:
```js
import '@todovue/tv-ui/style.css'
```

This points to `./dist/tv-ui.css` (via `exports["./style.css"]`).

### What about per-component styles?
You can also import styles from each package:
```js
import '@todovue/tv-button/style.css'
import '@todovue/tv-card/style.css'
```

This is useful if you:
- only use 1–2 components,
- want to control exactly what CSS gets into your bundle,
- or are migrating gradually.

## Nuxt (SSR) / Nuxt Module
This package publishes a Nuxt module at `@todovue/tv-ui/nuxt` that **injects the CSS** of `@todovue/*` packages into `nuxt.options.css`.

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

### Plugin registration (optional)
You can register all components globally:
```ts
// plugins/tv-ui.ts
import { defineNuxtPlugin } from '#app'
import TvUi from '@todovue/tv-ui'

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

Or import them locally:
```vue
<script setup>
import { TvButton } from '@todovue/tv-ui'
</script>

<template>
<TvButton>Hello</TvButton>
</template>
```

## Exported components
Currently `@todovue/tv-ui` re-exports:

- `TvAlert`
- `TvArticle`
- `TvBreadcrumbs`
- `TvButton`
- `TvCard`
- `TvDemo`
- `TvFooter`
- `TvHero`
- `TvLabel`
- `TvMenu`
- `TvModal`
- `TvPagination`
- `TvProgressBar`
- `TvRelativeTime`
- `TvScrollTop`
- `TvSearch`
- `TvSettings`
- `TvSidebar`
- `TvThemeButton`
- `TvToc`

## Registration options
| Approach | Example | When to use |
|---------------------|---------------------------------------------|------------------------------------------------------|
| Global via plugin | `app.use(TvUi)` | You use many components across the whole app |
| Local import | `import { TvButton } from '@todovue/tv-ui'` | Isolated views, code-splitting, fine-grained control |
| Individual packages | `import TvButton from '@todovue/tv-button'` | If you want to install/update components separately |

## SSR notes
- This package does not assume a DOM during plugin installation.
- Still, SSR compatibility depends on each `@todovue/*` component not accessing `window/document` at render time.
- In Nuxt, the `@todovue/tv-ui/nuxt` module takes care of registering global CSS for you.

## Development
Available scripts:
- `dev`: copies `README.md`/`CHANGELOG.md` from `node_modules/@todovue/*` into `public/demos/*` and starts Vite.
- `build`: library build (ESM + CJS) + types.
- `build:demo`: builds the demo (target `demo`) and copies `README.md`/`CHANGELOG.md` to `public/`.

Commands:
```bash
npm run dev
npm run build
npm run build:demo
```

## Contributing
PRs and issues are welcome. See:
- `CONTRIBUTING.md`
- `CODE_OF_CONDUCT.md`

## License
MIT © TODOvue
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>TvUi</title>
</head>
<body>
<body class="dark-mode">
<div id="tv-ui"></div>
<script type="module" src="/src/main.js"></script>
</body>
Expand Down
51 changes: 47 additions & 4 deletions nuxt.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,52 @@ export default defineNuxtModule({
configKey: 'tvUi'
},
setup(_options, nuxt) {
const cssPath = '@todovue/tv-ui/style.css';
if (!nuxt.options.css.includes(cssPath)) {
nuxt.options.css.push(cssPath);
}
const alertCss = '@todovue/tv-alert/style.css';
const articleCss = '@todovue/tv-article/style.css';
const breadcrumbsCss = '@todovue/tv-breadcrumbs/style.css';
const cardCss = '@todovue/tv-card/style.css';
const footerCss = '@todovue/tv-footer/style.css';
const labelCss = '@todovue/tv-label/style.css';
const modalCss = '@todovue/tv-modal/style.css';
const buttonCss = '@todovue/tv-button/style.css';
const demoCss = '@todovue/tv-demo/style.css';
const heroCss = '@todovue/tv-hero/style.css';
const menuCss = '@todovue/tv-menu/style.css';
const paginationCss = '@todovue/tv-pagination/style.css';
const progressBarCss = '@todovue/tv-progress-bar/style.css';
const scrollTopCss = '@todovue/tv-scroll-top/style.css';
const searchCss = '@todovue/tv-search/style.css';
const settingsCss = '@todovue/tv-settings/style.css';
const sidebarCss = '@todovue/tv-sidebar/style.css';
const themeButtonCss = '@todovue/tv-theme-button/style.css';
const tocCss = '@todovue/tv-toc/style.css';

const pushUnique = (path) => {
if (!nuxt.options.css.includes(path)) {
nuxt.options.css.push(path);
}
};

[
alertCss,
articleCss,
breadcrumbsCss,
cardCss,
footerCss,
labelCss,
modalCss,
buttonCss,
demoCss,
heroCss,
menuCss,
paginationCss,
progressBarCss,
scrollTopCss,
searchCss,
settingsCss,
sidebarCss,
themeButtonCss,
tocCss
].forEach(pushUnique);
}
})
Loading