@arrowster/shared-ui

Shared Vue 3 component library for Arrowster projects. Built with Vite in library mode; works in plain Vue 3 apps and Nuxt 3 (Nuxt is Vue 3 under the hood).
817
Install
npm install @arrowster/shared-ui
Latest Version:0.2.3
Vue:3
Last Updated:Oct 15, 2026
Links: npm
Maintainer: mohid.khan

@arrowster/shared-ui

Shared Vue 3 component library for Arrowster projects. Built with Vite in library mode; works in plain Vue 3 apps and Nuxt 3 (Nuxt is Vue 3 under the hood).

Requirements

  • Node >=24.15.0 (see .nvmrc — run nvm use)
  • npm (this repo uses npm; package-lock.json is the committed lockfile)

Install (in a consuming app)

npm install @arrowster/shared-ui

vue (^3.5) is a peer dependency — your app already provides it.

Vue 3

// main.ts
import '@arrowster/shared-ui/style.css'
<script setup lang="ts">
import { BaseButton } from '@arrowster/shared-ui'
</script>

<template>
  <BaseButton variant="primary">Hi</BaseButton>
</template>

Nuxt 3

// nuxt.config.ts
export default defineNuxtConfig({
  css: ['@arrowster/shared-ui/style.css'],
})
<script setup lang="ts">
import { BaseButton } from '@arrowster/shared-ui'
</script>

Dashboard layout

BaseDashboardLayout owns the sidebar and topbar. Pass the menu as an items array and bind the active item with v-model. Anything you leave out shows a labelled placeholder.

<script setup lang="ts">
import { ref } from 'vue'
import { BaseDashboardLayout, type NavItem } from '@arrowster/shared-ui'
import { HomeIcon, UsersIcon } from './icons' // any Vue components

const active = ref('dashboard')
const items: NavItem[] = [
  { value: 'dashboard', label: 'Dashboard', icon: HomeIcon },
  { value: 'students', label: 'Active Students', icon: UsersIcon, badge: 128 },
  { value: 'archive', label: 'Archived', disabled: true },
]
</script>

<template>
  <BaseDashboardLayout v-model="active" brand="Arrowster" :items="items">
    <template #topbar>…</template>
    <!-- page content -->
  </BaseDashboardLayout>
</template>
NavItem field Type Notes
value string | number Identifies the item; this is what v-model holds.
label string Text shown next to the icon.
icon Vue component Optional. Without one, the collapsed rail shows the label's first letter.
badge string | number Optional count pill (expanded sidebar only).
disabled boolean Optional. Dimmed and not selectable.
Layout prop / slot Purpose
brand prop, #brand slot Sidebar header text, or a custom logo.
#logo slot Mark shown when the sidebar is collapsed.
items prop, #nav slot Menu items; the slot replaces items for fully custom content.
#sidebar-footer slot Profile or actions at the bottom of the sidebar.
#topbar slot Content inside the topbar.
default slot Page content.
hide-sidebar, hide-topbar Remove those regions (for example on a login page).
hide-sidebar-footer No footer in the sidebar. Without it, an empty footer shows a placeholder.

Local development

nvm use          # match Node version
npm install      # install deps
npm run dev      # Vite playground (index.html + src/App.vue)

Other scripts:

Command What it does
npm run dev Playground dev server with HMR
npm run build Typecheck + lint + test, then build to dist/
npm run typecheck vue-tsc type check
npm run lint ESLint
npm run format Prettier write
npm run test Vitest run
npm run test:watch Vitest watch

Project structure

src/
  index.ts               # published entry (re-exports components + imports CSS)
  style.css              # Tailwind entry, compiled to dist/style.css
  components/
    index.ts             # component barrel (public exports)
    ui/                  # UI primitives
      BaseButton.vue
      BaseButton.spec.ts # colocated tests — every component ships one
  App.vue                # playground only (not published)
  main.ts                # playground only (not published)

Adding a component

  1. Create src/components/ui/YourComponent.vue.
  2. Add a colocated src/components/ui/YourComponent.spec.ts.
  3. Export it from src/components/index.ts.
  4. Drop it into src/App.vue and npm run dev to view it.
  5. npm run build — it's in the package automatically.

Publishing

npm version patch   # or minor / major
npm publish

prepublishOnly runs the full build (typecheck + lint + test + bundle) first, so dist/ is always fresh and verified. Only dist/ + README.md are published (see files in package.json).

Version History

Version Released Vue License
0.2.3 ^3.5.0
0.2.2 ^3.5.0
0.2.1 ^3.5.0
0.2.0 ^3.5.0
0.1.4 ^3.5.0