portal-design-system
v0.0.979
Published
A type-safe Vue 3 UI library with Tailwind CSS and isolated styles
Maintainers
Readme
Portal Design System
A type-safe, production-ready Vue 3 UI component library built with Tailwind CSS, TypeScript, and isolated styles for easy integration into projects. Features a comprehensive collection of reusable components, composables, directives, and utilities.
Table of Contents
- Features
- Quick Overview
- Installation
- Quick Start
- Components
- Inputs
- Overlays
- Directives
- Composables
- Styling & CSS
- Development
- Contributing
- License
Features
- Vue 3 + TypeScript - Full type safety with modern Vue 3 Composition API
- Tailwind CSS - Utility-first styling with prefixed classes for isolation
- ESM/CJS Distribution - Works with all module systems
- Component Flexibility - Regular Vue components + Web Components support
- Icon Support - Integrated Iconsax icons with customizable styling
- Accessible - Built with accessibility in mind
- Production Ready - Thoroughly tested components with real-world use cases
Quick Overview
- Framework: Vue 3 (Composition API)
- Styling: Tailwind CSS 4+ (prefixed utilities for isolation)
- Language: TypeScript 5+
- Build Tool: Vite 6
- Distribution: ESM / CJS + CSS + Type Definitions
- Package Version: 0.0.972
Installation
Install the package from npm (or use your preferred package manager):
npm install portal-design-system
# or
yarn add portal-design-system
# or
pnpm add portal-design-system
# or
bun add portal-design-systemRequired Peer Dependencies
If you use the DataGrid component, you must also install DevExtreme and its Vue bindings:
npm install devextreme devextreme-vue devextreme-aspnet-data-nojqueryThen import it separately:
<script setup lang="ts">
import { DataGrid } from 'portal-design-system/datagrid'
import { Button } from 'portal-design-system'
</script>
<template>
<DataGrid
:data-source="yourData"
:columns="columns"
/>
</template>Note: DataGrid is exported as a separate entry point to avoid bundling DevExtreme in projects that don't use it. This keeps the main library lightweight.
Quick Start
1. Import Styles (one-time in your app entry)
// main.ts
import 'portal-design-system/styles'2. Use Components in Your Vue App
<script setup lang="ts">
import { Button, Input, Select } from 'portal-design-system'
</script>
<template>
<div>
<Button variant="primary" text="Click Me" />
<Input placeholder="Enter text..." />
<Select :options="options" />
</div>
</template>3. Optional: Web Components (Shadow DOM)
For full style encapsulation with Web Components:
<script type="module">
import { defineCustomElements } from 'portal-design-system'
defineCustomElements()
</script>
<pds-button variant="primary">Shadow Button</pds-button>Components
Core Components
Button
- Versatile button component with multiple variants, sizes, and states
- Props:
variant(primary, secondary, etc.),size,radius,loading,disabled,text,icon - Supports icons, loading states, and router links
- Customizable appearance with
classListandiconConfig
Badge
- Lightweight label component for tagging and highlighting
- Props:
color,text,icon,iconPosition,size - Supports custom icons (Iconsax) with color customization
- Flexible sizing and styling
Text
- Typography component for consistent text styling
- Supports various text sizes and font weights
- Built for semantic HTML and accessibility
Iconsax
- Icon component wrapper for Iconsax icon library
- Props:
name,color,size,type(linear, outline, bold, bulk, broken, two-tone) - Seamless integration with other components
IconsaxFont
- Alternative Iconsax implementation using font-based icons
Tabs
- Tab navigation component with animated indicator
- Features: Smooth sliding indicator, responsive spacing, customizable colors
- Generic TypeScript support for flexible tab data structures
- Props:
tabs,indicatorColor,spacing - v-model support for active tab state
Dropdown
- Dropdown/menu component for filtering and selection
- Customizable trigger and menu items
- Position-aware placement
Pagination
- Navigation component for paginated content
- Props:
currentPage,totalPages,pageSize - Event handlers for page changes
DurationTimeline
- Timeline visualization component
- Ideal for showing time-based events or durations
- Customizable styling and event markers
DataGrid
- Enterprise-grade data table component (requires DevExtreme)
- Full support for sorting, filtering, paging
- Exported separately to keep main bundle lightweight
Inputs
Located in src/components/inputs/, these form control components provide flexible input handling:
Input
- Basic text input field
- Props:
placeholder,disabled,readonly,type,value - Validation support with Error component
- Full accessibility features
Select
- Dropdown select component
- Props:
options,modelValue,placeholder,disabled,multiple - Type-safe with
SelectOptionTypeinterface - Supports custom slots for option rendering
DateInput
- Date picker component
- Built-in calendar UI
- Customizable date format
- Min/max date validation support
CountryCode
- Specialized select for country code selection
- Pre-populated with country data
- Flag emoji display support
- Props:
modelValuefor selected country code
RadioGroup
- Radio button group component
- Props:
options,modelValue - Grouped radio options for single selection
- Supports custom styling
Label
- Form label component
- Associated with form inputs via
forattribute - Proper accessibility support
Error
- Error message display component
- Integrates with form validation
- Styling for error states
Overlays
Located in src/components/overlays/, these modal and panel components:
Dialog
- Modal dialog component for important user interactions
- Features: Backdrop overlay, close on escape, customizable content
- Props:
title,visible,closable,backdropClosable - Slot-based content structure
Drawer
- Side panel component sliding from edge
- Props:
title,visible,position(left, right, top, bottom) - Similar slot structure to Dialog
- Smooth animations and transitions
Heading
- Dialog/Drawer title component
- Semantic heading element with consistent styling
Directives
v-tooltip
- Tooltip directive for displaying contextual help text
- Usage:
<button v-tooltip="'Help text'">Hover me</button> <!-- or --> <button v-tooltip="{ content: 'Help text', placement: 'top' }">Hover me</button> - Modifiers:
.top,.bottom,.left,.right,.auto - Sub-modifiers:
.start,.end(for positioning variants) - Props:
delay,offset,class,placement - Default z-index: 100000 (high stacking context)
- Features: Smooth transitions, arrow indicator, customizable styling
tooltip.ts
- Core tooltip class implementation
- Uses PopperJS for intelligent positioning
- Handles show/hide logic with delay support
Composables
Located in src/components/composables/, reusable Vue 3 Composition API utilities:
useOutsideClick
- Detects clicks outside of a DOM element
- Usage:
const elementRef = ref<HTMLElement>() useOutsideClick(elementRef, () => { // Handle outside click }) - Useful for closing dropdowns, modals, and menus
useOverlay
- Manages overlay/modal state and behavior
- Handles backdrop interaction logic
useWindowScroll
- Detects and reacts to window scroll events
- Props:
element,callback,options - Useful for lazy loading and infinite scroll patterns
Styling & CSS
The library includes comprehensive CSS organization:
styles.css
- Main stylesheet
- Contains base styles, resets, and Tailwind imports
- One-time import in app entry point
tooltip.css
- Tooltip-specific styles
- Classes:
.h-tooltip,.vue-tooltip-hidden,.vue-tooltip-visible - Includes arrow styling and placement modifiers
- Z-index: 100000
transition.css
- Vue transition classes
- Smooth animations for component entry/exit
vue-datepicker.css
- Datepicker calendar styling
- Integration with DateInput component
dev-express.css
- DevExtreme DataGrid styling customizations
- Required when using DataGrid component
Types
Located in src/types/, comprehensive TypeScript definitions:
button-types.ts- Button variant and size enumstext-types.ts- Typography type definitionsiconsax-types.ts- Icon name typesdev-express-types.ts- DataGrid type definitionsindex.ts- Core interface definitions (e.g.,SelectOptionType)components.d.ts- Vue component auto-registration typesvue.d.ts- Vue augmentation types
Development
Common development tasks (scripts available in package.json):
# Start dev server with Vite
npm run dev
# or with Bun
bun run dev
# Build library for production
npm run build
# Type check entire codebase
npm run type-check
# Preview production build locally
npm run previewProject Structure
src/
├── components/ # Vue components
│ ├── inputs/ # Form input components
│ ├── overlays/ # Modal/panel components
│ ├── composables/ # Vue 3 Composition API utilities
│ ├── examples/ # Component usage examples
│ └── *.vue # Core components
├── directives/ # Vue directives (tooltip)
├── types/ # TypeScript type definitions
├── css/ # Stylesheets
│ ├── styles.css
│ ├── tooltip.css
│ ├── transition.css
│ └── vue-datepicker.css
├── utils/ # Utility functions (currently empty)
├── index.ts # Main entry point
└── example.ts # Example usageBuild Output
The library builds to dist/ with:
dist/index.js- ES Moduledist/index.cjs- CommonJSdist/index.d.ts- Type Definitionsdist/styles.css- Compiled Styles
Configuration Files
vite.config.ts- Vite build configurationtailwind.config.js- Tailwind CSS configurationtsconfig.json- TypeScript configurationpackage.json- Dependencies and scripts
Contributing
Contributions are welcome! Typical workflow:
- Fork the repository and create a feature branch
- Install dependencies and run the dev server:
npm install npm run dev - Make your changes to components, directives, or utilities
- Add examples or update component documentation
- Run type checker to ensure no TypeScript errors:
npm run type-check - Test your changes in the dev environment
- Open a Pull Request with a clear description of changes
Before Submitting a PR
Please ensure:
- All TypeScript errors are resolved
- Components follow existing patterns and conventions
- Props are properly typed with interfaces
- Documentation comments are added for complex logic
- CSS follows Tailwind utility-first approach with logical properties (RTL-safe)
License
MIT
For questions, feature requests, or bug reports, please open an issue on the repository.
