itc-sidebar
v1.0.2
Published
Reusable Quasar sidebar shell (QDrawer + scroll area + slots), inspired by boilerplate drawer layout.
Downloads
421
Maintainers
Readme
ItcSidebar (itc-sidebar)
Table of Contents
- Description
- Features
- Package structure
- Requirements
- Installation
- Quick start
- Props
- Events
- Slots
- Header selects
- Menu items
- Mini hover behavior
- Exports and types
- Development
Description
A Vue 3 + Quasar sidebar built on QLayout, QDrawer, and QScrollArea. It includes a boilerplate-style top section (banner, profile, company/project selects) and an optional scrollable menu or custom body content.
The implementation lives in a single component file — src/components/ItcSidebar.vue — plus small types.ts and plugin.ts helpers.
Features
- Full layout shell (
QLayout+ drawer + page area) - Boilerplate-style header: banner image, profile block,
QSelectdropdowns - Built-in menu list via the
itemsprop, or custom content in the default slot v-model,v-model:mini, andv-model:header-values- Mini mode with optional expand on hover
- Slots:
profile,header-actions, default body,page - TypeScript types for menu items, header selects, and header values
- Global registration via
itcSidebarplugin ItcSidebarLayoutexport kept as a deprecated alias ofItcSidebar
Package structure
| Path | Role |
|------|------|
| src/components/ItcSidebar.vue | Main (and only) UI component |
| src/types.ts | Shared TypeScript types |
| src/plugin.ts | app.use(itcSidebar) |
| src/index.ts | Package entry |
| src/example/ | Local demo helpers (not published in npm files) |
Published builds output to dist/ (built on npm publish via prepublishOnly; dist/ is gitignored).
Requirements
- Vue 3.x
- Quasar 2.x
- Node.js 20.19+ or 22.12+ (for local development)
Installation
npm install itc-sidebarEnsure Quasar is set up in your app (peer dependency).
Quick start
ItcSidebar renders its own QLayout. You usually do not wrap it in another QLayout — use it as the page root (see package demo).
<script setup lang="ts">
import { ref } from 'vue'
import { ItcSidebar } from 'itc-sidebar'
import type { ItcSidebarHeaderSelect, ItcSidebarMenuItem } from 'itc-sidebar'
const drawerOpen = ref(true)
const mini = ref(false)
const headerValues = ref({
company: 'itc',
project: 'sidebar'
})
const headerSelects: ItcSidebarHeaderSelect[] = [
{
key: 'company',
label: 'Company',
options: [
{ label: 'ITC', value: 'itc' },
{ label: 'Super Cards', value: 'super-cards' }
]
},
{
key: 'project',
label: 'Project',
options: [
{ label: 'Sidebar package', value: 'sidebar' },
{ label: 'Navigation menu', value: 'menu' }
]
}
]
const items: ItcSidebarMenuItem[] = [
{ label: 'Overview', caption: 'Dashboard summary', icon: 'o_dashboard' },
{ label: 'Projects', caption: 'Active work', icon: 'o_folder_open' }
]
</script>
<template>
<ItcSidebar
v-model="drawerOpen"
v-model:mini="mini"
v-model:header-values="headerValues"
:width="280"
bordered
show-if-above
expand-mini-on-hover
:header-min-height="190"
banner-src="https://picsum.photos/id/1015/900/280"
profile-name="ITC Product Team"
profile-subtitle="[email protected]"
profile-image="https://cdn.quasar.dev/img/boy-avatar.png"
profile-status-color="positive"
profile-status-icon="check"
show-close-button
show-mobile-close-button
show-project-select
:header-selects="headerSelects"
:items="items"
@item-click="(item, index) => console.log(item, index)"
/>
</template>Global registration (plugin)
// main.ts
import { createApp } from 'vue'
import App from './App.vue'
import { itcSidebar } from 'itc-sidebar'
const app = createApp(App)
app.use(itcSidebar) // registers <ItcSidebar> globally
app.mount('#app')Custom sidebar body (no items prop)
When items is empty, use the default slot for custom content (for example itc-navigation-menu):
<script setup lang="ts">
import { ref } from 'vue'
import { ItcNavigationMenu } from 'itc-navigation-menu'
import { ItcSidebar } from 'itc-sidebar'
import { navLinks } from './navigation-links'
const drawerOpen = ref(true)
const mini = ref(false)
</script>
<template>
<ItcSidebar
v-model="drawerOpen"
v-model:mini="mini"
:width="280"
bordered
show-if-above
profile-name="ITC Product Team"
>
<ItcNavigationMenu :nav-links="navLinks" :mini="mini" />
</ItcSidebar>
</template>Page content slot
Use the page slot to replace the default empty main area:
<ItcSidebar v-model="drawerOpen" v-model:mini="mini">
<template #page>
<div class="q-pa-md">Main app content here</div>
</template>
</ItcSidebar>Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| modelValue | boolean | true | Drawer open state. |
| mini | boolean | false | Mini drawer mode. |
| headerValues | Record<string, string \| number> | {} | Values for headerSelects keys (v-model:header-values). |
| layoutClass | string | 'bg-grey-1' | Class on root QLayout. |
| pageClass | string | 'bg-grey-1' | Class on QPageContainer. |
| showPageOpenButton | boolean | true | Floating button to reopen drawer when closed or mini. |
| width | number | 250 | Drawer width (px). |
| breakpoint | number | 800 | Quasar drawer breakpoint. |
| side | 'left' \| 'right' | 'left' | Drawer side. |
| showIfAbove | boolean | true | Quasar show-if-above. |
| expandMiniOnHover | boolean | false | Expand mini drawer while hovered. |
| scrollAreaClass | string | '' | Extra class on QScrollArea. |
| bordered | boolean | false | Drawer border. |
| bannerSrc | string | '' | Banner background image URL. |
| bannerAlt | string | '' | Alt text (reserved for future use). |
| headerMinHeight | number | 160 | Top section height when expanded. |
| miniHeaderMinHeight | number | 60 | Top section height in collapsed mini mode. |
| profileName | string | '' | Profile title. |
| profileSubtitle | string | '' | Profile subtitle (email, role, etc.). |
| profileImage | string | '' | Avatar image URL. |
| profileImageAlt | string | '' | Avatar alt text. |
| profileFallbackIcon | string | 'o_person' | Icon when no image. |
| profileStatusColor | string | '' | Avatar badge color. |
| profileStatusIcon | string | '' | Icon inside avatar badge. |
| showCloseButton | boolean | false | Top-right chevron: mini on desktop, close drawer on mobile. |
| showMobileCloseButton | boolean | false | Same button, mobile only (when combined with desktop rules). |
| showCompanySelect | boolean | true | Show select where headerSelects key is company. |
| showProjectSelect | boolean | false | Show select where headerSelects key is project. |
| headerSelects | ItcSidebarHeaderSelect[] | [] | Header dropdown definitions. |
| items | ItcSidebarMenuItem[] | [] | Built-in menu rows; when set, default slot is not used. |
Events
| Event | Payload | Description |
|-------|---------|-------------|
| update:modelValue | boolean | Drawer open state changed. |
| update:mini | boolean | Mini state changed. |
| update:headerValues | ItcSidebarHeaderValues | Header select values changed. |
| item-click | item, index | User clicked a row from the items prop. |
Slots
| Slot | Description |
|------|-------------|
| profile | Replace default avatar block. Props: mini, isMiniCollapsed. |
| header-actions | Extra buttons beside the close chevron. Props: mini, isMiniCollapsed. |
| default | Scrollable sidebar body when items is empty. |
| page | Main page area (replaces default empty QPageContainer content). |
Header selects
Each entry in headerSelects:
{
key: 'company', // stored in headerValues[key]
label: 'Company', // QSelect label
options: [{ label, value }],
show?: boolean // false hides this field
}Visibility rules:
show: falseon a field hides it.showCompanySelect/showProjectSelectcontrol fields with keyscompanyandproject.
<ItcSidebar
v-model:header-values="headerValues"
show-project-select
:header-selects="headerSelects"
/>Menu items
When items is provided, the component renders a QList automatically:
{
label: 'Overview',
caption?: 'Optional subtitle',
icon?: 'o_dashboard'
}Listen for clicks:
<ItcSidebar :items="items" @item-click="onNav" />Mini hover behavior
With expand-mini-on-hover, hovering the drawer while mini is true temporarily sets mini to false; leaving restores mini mode.
The built-in header adapts in mini mode on desktop:
- Compact padding and centered avatar
- Profile text and header selects hidden
header-actionsslot area hidden when collapsed
Exports and types
import { ItcSidebar, ItcSidebarLayout, itcSidebar } from 'itc-sidebar'
import type {
ItcSidebarSide,
ItcSidebarMenuItem,
ItcSidebarHeaderSelect,
ItcSidebarHeaderValues,
ItcSidebarSelectOption
} from 'itc-sidebar'ItcSidebarLayout is deprecated; use ItcSidebar.
Local development alias
In this repo, vite.config.ts maps src/ for internal imports. Consumers import from 'itc-sidebar' only.
Development
For package maintainers.
git clone <repo-url>
cd sidebar # or your clone folder name
npm install
npm run buildWatch mode:
npm run devTry the in-repo demo
The itc-navigation-menu-demo app can link this package locally:
"itc-sidebar": "file:../../main/sidebar"Run that app’s dev server and open the /itc-sidebar route.
Publish notes
dist/is not committed;prepublishOnlyrunsnpm run build.- npm
"files"includes onlydist.
