@allsrvsonline/vue-component-library
v0.6.5
Published
A modern, type-safe Vue 3 component library built with TypeScript and Vite. This library provides reusable, well-tested components that follow best practices and strict coding standards.
Readme
Vue Component Library
A modern, type-safe Vue 3 component library built with TypeScript and Vite. This library provides reusable, well-tested components that follow best practices and strict coding standards.
Features
- ✅ TypeScript First - Full TypeScript support with strict type checking
- ✅ Vue 3 Composition API - Built with modern Vue patterns using
<script setup> - ✅ Tree-shakeable - Only import what you need
- ✅ Fully Tested - Comprehensive test coverage with Vitest
- ✅ ESLint & Prettier - Enforced code quality and formatting
- ✅ Type Definitions - Auto-generated
.d.tsfiles - ✅ Documented - JSDoc comments on all public APIs
Installation
npm install @allsrvsonline/vue-component-libraryUsage
Importing Components
import {
BaseButton,
BaseInput,
BaseSelect,
BaseCard,
CollapsibleCard,
BaseDeleteButton,
Header,
Title,
Logo,
Main,
Footer,
Copyright
} from '@allsrvsonline/vue-component-library'
import '@allsrvsonline/vue-component-library/style.css'Component Examples
BaseButton
<template>
<BaseButton variant="primary" size="medium" @click="handleClick"> Click Me </BaseButton>
</template>
<script setup lang="ts">
import { BaseButton } from '@allsrvsonline/vue-component-library'
const handleClick = () => {
console.log('Button clicked!')
}
</script>Props:
variant:'primary' | 'secondary' | 'success' | 'danger' | 'warning'(default:'primary')size:'small' | 'medium' | 'large'(default:'medium')disabled:boolean(default:false)loading:boolean(default:false)fullWidth:boolean(default:false)
BaseInput
<template>
<BaseInput
v-model="email"
type="email"
label="Email Address"
placeholder="Enter your email"
:error="emailError"
required
/>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { BaseInput } from '@allsrvsonline/vue-component-library'
const email = ref('')
const emailError = ref('')
</script>Props:
modelValue:string- The input value (v-model)type:'text' | 'email' | 'password' | 'number' | 'tel' | 'url'(default:'text')label:string- Input labelplaceholder:string- Placeholder texterror:string- Error message to displaydisabled:boolean(default:false)required:boolean(default:false)
BaseSelect
<template>
<BaseSelect
v-model="selectedFruit"
label="Favorite Fruit"
placeholder="Choose a fruit"
:options="['Apple', 'Banana', 'Orange']"
/>
<BaseSelect
v-model="selectedCountry"
label="Country"
:options="[
{ value: 'us', label: 'United States' },
{ value: 'ca', label: 'Canada' }
]"
:error="countryError"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { BaseSelect } from '@allsrvsonline/vue-component-library'
const selectedFruit = ref('')
const selectedCountry = ref('')
const countryError = ref('')
</script>Props:
modelValue:string | number- The select value (v-model)options:SelectOption[]- Array of options to displayplaceholder:string- Placeholder textdisabled:boolean(default:false)required:boolean(default:false)label:string- Select labelerror:string- Error message to displaylabelField:string(default:'label') - Field name for label when options are objectsvalueField:string(default:'value') - Field name for value when options are objects
BaseCard
<template>
<BaseCard title="User Profile" elevated>
<p>Card content goes here</p>
<template #footer>
<BaseButton variant="primary">Save</BaseButton>
</template>
</BaseCard>
</template>
<script setup lang="ts">
import { BaseCard, BaseButton } from '@allsrvsonline/vue-component-library'
</script>CollapsibleCard
<template>
<CollapsibleCard title="Click to expand" :initiallyCollapsed="false" elevated>
<p>This content can be toggled</p>
<template #footer>
<BaseButton variant="primary">Action</BaseButton>
</template>
</CollapsibleCard>
</template>
<script setup lang="ts">
import { CollapsibleCard, BaseButton } from '@allsrvsonline/vue-component-library'
</script>Props:
title:string- Card titleelevated:boolean(default:false) - Whether the card has elevated shadowpadding:boolean(default:true) - Whether the card has paddinginitiallyCollapsed:boolean(default:true) - Initial collapsed state
BaseDeleteButton
<template>
<BaseDeleteButton @click="handleDelete" />
<BaseDeleteButton size="small" @click="handleDelete" />
<BaseDeleteButton :disabled="true" @click="handleDelete" />
</template>
<script setup lang="ts">
import { BaseDeleteButton } from '@allsrvsonline/vue-component-library'
const handleDelete = () => {
// Handle delete action
}
</script>Props:
size:'small' | 'medium' | 'large'(default:'medium')disabled:boolean(default:false)loading:boolean(default:false)fullWidth:boolean(default:false)type:'button' | 'submit' | 'reset'(default:'button')ariaLabel:string- Accessibility label (default:'Delete')
Header
<template>
<Header>
<template #left>
<Logo />
<Title title="My App" subtitle="Welcome" />
</template>
<template #middle>
<nav>
<BaseButton variant="secondary" size="small">Home</BaseButton>
<BaseButton variant="secondary" size="small">About</BaseButton>
</nav>
</template>
<template #right>
<BaseButton>Settings</BaseButton>
</template>
</Header>
</template>
<script setup lang="ts">
import { Header, Logo, Title, BaseButton } from '@allsrvsonline/vue-component-library'
</script>Features:
- Fixed positioning at the top of the page
- Responsive design with theme support
- Three named slots: left, middle, and right for proper content alignment
- Automatic spacing and centering of middle content
- Automatic theming (light/dark mode)
Title
<template>
<Title title="My Application" subtitle="A modern Vue.js app" />
</template>
<script setup lang="ts">
import { Title } from '@allsrvsonline/vue-component-library'
</script>Props:
title:string(default:'TITLE PLACEHOLDER') - The main title textsubtitle:string(optional) - The subtitle text (only rendered when provided)
Logo
<template>
<Logo src="/path/to/logo.svg" alt="Company Logo" />
</template>
<script setup lang="ts">
import { Logo } from '@allsrvsonline/vue-component-library'
</script>Props:
src:string(default:'/logo.svg') - The image source pathalt:string(default:'Logo') - The alt text for accessibility
Main
<template>
<Main>
<h1>Welcome to my app</h1>
<p>This is the main content area.</p>
</Main>
</template>
<script setup lang="ts">
import { Main } from '@allsrvsonline/vue-component-library'
</script>Features:
- Fixed positioning between header and footer
- Scrollable content area with proper overflow handling
- Responsive design with automatic spacing
- Accepts any content via slots
Footer
<template>
<Footer>
<Copyright :startYear="2020" name="My Company" />
</Footer>
</template>
<script setup lang="ts">
import { Footer, Copyright } from '@allsrvsonline/vue-component-library'
</script>Features:
- Fixed positioning at the bottom of the page
- Responsive design with theme support
- Accepts any content via slots
- Automatic theming (light/dark mode)
Copyright
<template>
<Copyright :startYear="2020" name="My Company" />
</template>
<script setup lang="ts">
import { Copyright } from '@allsrvsonline/vue-component-library'
</script>Props:
startYear:number- The year the copyright startedname:string- The company or person name
Using Composables
import { useValidation, useClickOutside } from '@allsrvsonline/vue-component-library'
// Form validation
const { value, error, validate } = useValidation('', (val) =>
val.length > 0 ? null : 'Field is required'
)
// Click outside detection
const dropdownRef = ref<HTMLElement>()
useClickOutside(dropdownRef, () => {
// Close dropdown
})Using Utilities
import { cn, debounce, generateId } from '@allsrvsonline/vue-component-library'
// Combine class names
const classes = cn('btn', isActive && 'btn--active')
// Debounce function calls
const debouncedSearch = debounce(search, 300)
// Generate unique IDs
const id = generateId('input')Development
Prerequisites
- Node.js 18+
- npm or pnpm
Setup
# Install dependencies
npm install
# Run development server
npm run dev
# Run tests
npm run test
# Run tests with UI
npm run test:ui
# Build library
npm run build:lib
# Lint code
npm run lint
# Format code
npm run format
# Type check
npm run type-checkProject Structure
src/
├── components/ # Vue components
│ ├── base/ # Base components
│ │ └── header/
│ │ ├── Header.vue
│ │ ├── Header.spec.ts
│ │ ├── Title.vue
│ │ ├── Title.spec.ts
│ │ ├── Logo.vue
│ │ └── Logo.spec.ts
│ │ └── main/
│ │ ├── Main.vue
│ │ └── Main.spec.ts
│ │ └── footer/
│ │ ├── Footer.vue
│ │ ├── Footer.spec.ts
│ │ ├── Copyright.vue
│ │ └── Copyright.spec.ts
│ ├── BaseButton.vue
│ ├── BaseButton.spec.ts
│ ├── BaseInput.vue
│ ├── BaseInput.spec.ts
│ ├── BaseSelect.vue
│ ├── BaseSelect.spec.ts
│ ├── BaseCard.vue
│ ├── BaseCard.spec.ts
│ ├── CollapsibleCard.vue
│ ├── CollapsibleCard.spec.ts
│ ├── BaseDeleteButton.vue
│ └── BaseDeleteButton.spec.ts
├── composables/ # Composable functions
│ ├── useValidation.ts
│ └── useClickOutside.ts
├── utils/ # Utility functions
│ └── index.ts
├── types/ # TypeScript definitions
│ └── index.ts
└── index.ts # Main export fileDesign Patterns & Best Practices
This library follows strict coding standards:
Component Patterns
- Composition API with
<script setup>- All components use the modern Composition API - TypeScript Strict Mode - Full type safety with no
anytypes - Props Validation - All props are properly typed with interfaces
- Typed Events - Event emitters use TypeScript interfaces
- Single Responsibility - Each component has a clear, focused purpose
Code Quality
- ESLint - Enforces code quality rules
- Prettier - Consistent code formatting
- Vitest - Unit testing with good coverage
- JSDoc - Comprehensive documentation
Naming Conventions
- Components:
PascalCase(e.g.,BaseButton) - Composables:
camelCasestarting withuse(e.g.,useValidation) - Utilities:
camelCase(e.g.,generateId) - Types:
PascalCase(e.g.,ButtonVariant)
Contributing
When contributing components:
- Follow the existing patterns
- Add TypeScript types
- Write unit tests
- Document with JSDoc
- Run linting and formatting
License
MIT
