itc-quasar-tabs
v1.0.0
Published
Dynamic Quasar QTabs / QTab (+ optional QTabPanels) for Vue 3
Readme
Vue + Quasar Plugin Template
A modern starter template for building Vue 3 + Quasar plugins/libraries with TypeScript, Vite, and path aliases support.
Features
- ✅ Vue 3 with Composition API
- ✅ Quasar Framework support
- ✅ TypeScript for type safety
- ✅ Vite for fast builds
- ✅ Path Aliases - Import without relative paths (e.g.,
src/components/...) - ✅ Dual Format Build - ES Modules and CommonJS
- ✅ Preserved Directory Structure - Maintains
src/structure in output - ✅ SCSS/SASS support for styling
Getting Started
Prerequisites
- Node.js 20.19+ or 22.12+
- pnpm (recommended) or npm/yarn
Installation
Clone or use this template:
git clone <your-repo-url> cd <your-project-name>Install dependencies:
pnpm install # or npm installUpdate package.json:
- Change
nameto your package name - Update
version,description,author,license, andkeywords - Adjust
dependenciesanddevDependenciesas needed
- Change
Update src/index.ts:
- Export your main components/utilities
- Example:
export { default as ItcQuasarTabs } from './components/ItcQuasarTabs.vue' export { itcQuasarTabs } from './plugin' export type { ItcQuasarTabsVariant, ItcTabDefinition } from './types'
Usage
Path Aliases
This template supports importing files using the src/ prefix without relative paths:
// ✅ Good - Using path alias
import { ItcTabDefinition } from 'src/types'
import ItcQuasarTabs from 'src/components/ItcQuasarTabs.vue'
// ❌ Avoid - Relative paths (still works, but not recommended)
import { ItcTabDefinition } from '../types'
import ItcQuasarTabs from './components/ItcQuasarTabs.vue'Example: itc-quasar-tabs (basic)
<script setup lang="ts">
import { ref } from 'vue'
import { ItcQuasarTabs } from 'itc-quasar-tabs'
const tab = ref('mails')
const tabs = [
{ name: 'mails', label: 'Mails' },
{ name: 'alarms', label: 'Alarms' },
{ name: 'movies', label: 'Movies' }
]
</script>
<template>
<ItcQuasarTabs
v-model="tab"
:tabs="tabs"
variant="card"
use-panels
:panels-on-top="false"
:tabs-dark-aware-bg="true"
dense
align="justify"
>
<template #panel="{ tab: t }">
<div>{{ t.label }} panel content</div>
</template>
</ItcQuasarTabs>
</template>Quick Demo File
If you want a ready example page, copy:
src/examples/ItcQuasarTabsDemo.vue
Project Structure
src/
components/ # Vue components
examples/ # Demo SFCs for quick testing
types.ts # Component types
index.ts # Main export file
plugin.ts # Global install plugin
vue-shim.d.ts # Vue type declarations
dist/ # Build output (generated)
package.json
tsconfig.json
vite.config.tsBuilding
Build for Production
pnpm run build
# or
npm run buildThis will:
- Compile TypeScript to JavaScript
- Bundle Vue components
- Generate both ES Modules (
.js) and CommonJS (.cjs) formats - Output to
dist/directory with preservedsrc/structure
Testing Locally
Option 1: Using pnpm link (Recommended)
In your plugin directory:
pnpm link --globalIn your test project:
pnpm link --global itc-quasar-tabsUse in your project:
<script setup> import { ItcQuasarTabs } from "itc-quasar-tabs" </script>
Option 2: Using File Path
In your test project's
package.json:{ "dependencies": { "itc-quasar-tabs": "file:../path/to/itc-quasar-tabs" } }Install:
pnpm install # or npm install
Development Workflow
For active development with auto-rebuild:
pnpm run devChanges will rebuild automatically. Restart your test project's dev server to pick up changes.
Publishing to npm
Before Publishing
Update
package.json:- Set correct
name(must be unique on npm) - Update
version(follow https://semver.org/) - Add
description,keywords,author,license - Verify
filesarray includes only what should be published (typicallydist)
- Set correct
Build the package:
pnpm run buildTest the build locally
Publishing Steps
Login to npm:
npm loginPublish:
npm publish
Configuration
External Dependencies
By default, vue and quasar are marked as external (not bundled). This is handled in vite.config.ts.
Build Formats
The template builds both ES Modules and CommonJS formats.
Troubleshooting
TypeScript Errors
- "Cannot find module 'src/...'": Restart TypeScript server
- "Path aliases not working": Check both
tsconfig.jsonandvite.config.ts
Build Errors
- "Rollup failed to resolve import": Ensure the package imports are externalized in
vite.config.ts
License
MIT
itc-quasar-tabs
Generic tabs component for Vue 3 + Quasar, built as a reusable library.
It wraps Quasar’s QTabs, QTab, QTabPanels, QTabPanel and QSplitter with:
- Dynamic tabs from a simple array definition
- Multiple layout variants (card, splitter, default)
- Optional tab panels and vertical layouts
- A few opinionated props (
panelsOnTop,tabsDarkAwareBg) that mirror common patterns from the Quasar docs
Features
- ✅ Vue 3 + Composition API
- ✅ Quasar 2 components under the hood (
QTabs,QTab,QTabPanels,QTabPanel,QSplitter) - ✅ Dynamic tabs from a
tabsarray (name,label,icon, etc.) - ✅ Layout variants:
default– tabs then panelscard–QCardwrapper, tabs + panelscard-reverse– alias forcardwithpanelsOnTop=truesplitter– vertical rail + panels viaQSplitter
- ✅ Panels positioning with
panelsOnTop - ✅ Dark-aware tab bar with
tabsDarkAwareBg - ✅ TypeScript support (
ItcTabDefinition,ItcQuasarTabsVariant) - ✅ Built with Vite (ESM + CJS outputs, preserved
src/structure)
Installation
From npm (when published)
npm install itc-quasar-tabs
# or
pnpm add itc-quasar-tabsLocal file install (like in boilerplate-quasar-v2)
In your app’s package.json:
{
"dependencies": {
"itc-quasar-tabs": "file:../../project/itc-quasar-tabs"
}
}Then:
npm installBasic Usage
1. Import and use as a local component
<script setup lang="ts">
import { ref } from 'vue'
import { ItcQuasarTabs } from 'itc-quasar-tabs'
const tab = ref('mails')
const tabs = [
{ name: 'mails', label: 'Mails' },
{ name: 'alarms', label: 'Alarms' },
{ name: 'movies', label: 'Movies' }
]
</script>
<template>
<ItcQuasarTabs
v-model="tab"
:tabs="tabs"
variant="card"
use-panels
:panels-on-top="false"
:tabs-dark-aware-bg="true"
dense
align="justify"
>
<template #panel="{ tab: t }">
<div>{{ t.label }} panel content</div>
</template>
</ItcQuasarTabs>
</template>2. Register globally via plugin
// main.ts
import { createApp } from 'vue'
import App from './App.vue'
import { itcQuasarTabs } from 'itc-quasar-tabs'
const app = createApp(App)
app.use(itcQuasarTabs) // registers <ItcQuasarTabs> globally
app.mount('#app')Layout Variants
variant="card"
Tabs + optional panels, wrapped in QCard.
panelsOnTop=false→ tabs top, panels bottompanelsOnTop=true→ panels top, tabs bottom
<ItcQuasarTabs
v-model="tab"
:tabs="tabs"
variant="card"
use-panels
:panels-on-top="true"
dense
align="justify"
tabs-class="text-grey"
:tabs-dark-aware-bg="true"
>
<template #panel="{ tab: t }">
<div class="text-h6">{{ t.label }}</div>
<div>Panels are on top because panels-on-top is true.</div>
</template>
</ItcQuasarTabs>variant="splitter"
Vertical rail + panels using QSplitter:
<script setup lang="ts">
import { ref } from 'vue'
import { ItcQuasarTabs } from 'itc-quasar-tabs'
const splitterTab = ref('mails')
const splitterModel = ref(20)
const tabs = [
{ name: 'mails', label: 'Mails' },
{ name: 'alarms', label: 'Alarms' },
{ name: 'movies', label: 'Movies' }
]
</script>
<template>
<ItcQuasarTabs
v-model="splitterTab"
:splitter-model="splitterModel"
@update:splitter-model="(v) => { splitterModel = v }"
:tabs="tabs"
variant="splitter"
use-panels
panels-vertical
panels-swipeable
transition-prev="jump-up"
transition-next="jump-up"
tabs-class="text-teal"
splitter-style="height: 250px"
>
<template #panel="{ tab: t }">
<div class="text-h6">{{ t.label }}</div>
<p>Content for {{ t.name }}.</p>
</template>
</ItcQuasarTabs>
</template>Props Overview (main ones)
Core
modelValue(string | number | null) – active tab name (used withv-model)tabs(ItcTabDefinition[]) – tab definitions arrayvariant('default' | 'card' | 'card-reverse' | 'splitter')usePanels(boolean) – whether to renderQTabPanels
Layout / behavior
vertical– vertical tabs (QTabs vertical) for non-splitter variantspanelsVertical– verticalQTabPanelspanelsOnTop– forcard;true→ panels top, tabs bottomtabsDarkAwareBg– whentrueaddsbg-grey-9(dark) /bg-grey-3(light) based on$q.dark.isActivealign–'left' | 'center' | 'right' | 'justify'dense,shrink,stretch,inlineLabel,outsideArrows,mobileArrows,narrowIndicator
Splitter
splitterModel(number) – splitter percentagesplitterStyle– style object/string forQSplittersplitterTabsVertical(boolean) – vertical rail (defaulttrue)
Styling hooks
wrapperClass,wrapperStyletabsClass,tabsStylepanelsClass,panelsStylepanelClass,panelStyle
See src/components/ItcQuasarTabs.vue for the full prop list.
Example File
A small playground is shipped in the package:
src/examples/ItcQuasarTabsDemo.vue
You can copy this file into your app to get a working demo page quickly.
Project Structure
itc-quasar-tabs/
├─ src/
│ ├─ components/
│ │ └─ ItcQuasarTabs.vue # main component
│ ├─ examples/
│ │ └─ ItcQuasarTabsDemo.vue # demo you can copy into your app
│ ├─ types.ts # ItcTabDefinition, ItcQuasarTabsVariant
│ ├─ index.ts # library entry (exports)
│ ├─ plugin.ts # global install plugin
│ └─ vue-shim.d.ts # Vue type declarations
├─ dist/ # build output (generated)
├─ package.json
├─ tsconfig.json
└─ vite.config.tsBuilding the Library
npm run buildThis runs:
vite build→ JS bundle (ESM + CJS, preserved modules)vue-tsc -p tsconfig.build.json→ type declarations intodist/src
The built entries are:
dist/src/index.js/index.cjs- plus all preserved module files for components and types.
Local Development & Testing
Option 1: Using pnpm link (Recommended)
In your plugin directory:
pnpm link --globalIn your test project:
pnpm link --global itc-quasar-tabsUse in your project:
<script setup> import { ItcQuasarTabs } from 'itc-quasar-tabs' </script>
Option 2: Using File Path
In your test project's
package.json:{ "dependencies": { "itc-quasar-tabs": "file:../path/to/itc-quasar-tabs" } }Install:
pnpm install # or npm installUse in your project:
<script setup> import { ItcQuasarTabs } from 'itc-quasar-tabs' </script>
Unlinking After Local Development
When you're done with local development and want to switch back:
For Option 1 (pnpm/npm link)
Unlink:
pnpm unlink --global itc-quasar-tabs # or npm unlink itc-quasar-tabs
For Option 2 (File Path)
- Remove the file dependency from
package.json - Run install again
Troubleshooting
TypeScript Errors
- "Cannot find module 'src/...'" : Restart TypeScript server
- "Cannot find module 'path'" : Ensure
@types/nodeis installed - Path aliases not working: Check both
tsconfig.jsonandvite.config.tshave matching aliases
Build Errors
- "Rollup failed to resolve import": Add the package to
externalinvite.config.ts - "Preprocessor dependency not found": Install required preprocessors (for example
sass-embeddedfor SCSS)
Import Errors in Test Project
- Ensure the package is built (
pnpm run build) - Check package.json exports are correct
- Verify the import path matches your exports
Notes
vueandquasarare peer dependencies and are treated as externals invite.config.ts.- The component assumes you already have Quasar configured in your app (including any icons/extras you use).
License
MIT (or update to your preferred license in package.json).
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Build and test locally
- Submit a pull request
Happy coding!
