portal-design-system

A type-safe Vue 3 UI library with Tailwind CSS and isolated styles
13,308
Install
npm install portal-design-system
Latest Version:0.0.989
Vue:3
License:MIT
Last Updated:Feb 3, 2026
Links: npm
Maintainer: voidbase

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

  • 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-system

Required 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-nojquery

Then 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 classList and iconConfig
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 SelectOptionType interface
  • 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: modelValue for 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 for attribute
  • 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 enums
  • text-types.ts - Typography type definitions
  • iconsax-types.ts - Icon name types
  • dev-express-types.ts - DataGrid type definitions
  • index.ts - Core interface definitions (e.g., SelectOptionType)
  • components.d.ts - Vue component auto-registration types
  • vue.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 preview

Project 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 usage

Build Output

The library builds to dist/ with:

  • dist/index.js - ES Module
  • dist/index.cjs - CommonJS
  • dist/index.d.ts - Type Definitions
  • dist/styles.css - Compiled Styles

Configuration Files

  • vite.config.ts - Vite build configuration
  • tailwind.config.js - Tailwind CSS configuration
  • tsconfig.json - TypeScript configuration
  • package.json - Dependencies and scripts

Contributing

Contributions are welcome! Typical workflow:

  1. Fork the repository and create a feature branch
  2. Install dependencies and run the dev server:
    npm install
    npm run dev
    
  3. Make your changes to components, directives, or utilities
  4. Add examples or update component documentation
  5. Run type checker to ensure no TypeScript errors:
    npm run type-check
    
  6. Test your changes in the dev environment
  7. 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.

Related Packages

@bobbykim/manguito-theme

main theme file for manguito components library. Other MCL components will need...

3,458 3
@cssninja/nuxt-ui

🖌️ A beautiful, customizable, and simple to use component library with Tailwind...

2,985
@bridge-ui/vue

Vue components and composables for Bridge UI.

7,241 6

Version History

Version Released Vue License
0.0.989 ^3.4.13 MIT
0.0.988 ^3.4.13 MIT
0.0.987 ^3.4.13 MIT
0.0.986 ^3.4.13 MIT
0.0.985 ^3.4.13 MIT