npm.io
1.1.9 • Published 5d ago

@pecb-ui/components

Licence
MIT
Version
1.1.9
Deps
1
Size
15.8 MB
Vulns
0
Weekly
331

@pecb-ui/components

A professional Angular 17 UI components library built with TypeScript and SCSS. Features Storybook for component development and documentation, full accessibility compliance (WCAG 2.1 AA), and tree-shakeable, AOT-compatible builds.

npm version Angular License: MIT

Features

  • Angular 17.3+ - Built with the latest Angular features
  • APF Compliant - Angular Package Format for maximum compatibility
  • Tree-shakeable - Only import what you use
  • AOT Compatible - Optimized for Ahead-of-Time compilation
  • WCAG 2.1 AA - Full accessibility compliance
  • SCSS Design System - Professional variables, mixins, and utilities
  • Storybook - Interactive component documentation
  • Strict TypeScript - Full type safety

Installation

npm install @pecb-ui/components
From local package
npm install /path/to/dist/ui-components/pecb-ui-components-1.0.0.tgz

Peer Dependencies

This library requires the following peer dependencies:

{
  "@angular/common": "^17.3.0",
  "@angular/core": "^17.3.0",
  "@angular/animations": "^17.3.0"
}

Quick Start

1. Import the Module
// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { PecbComponentsModule } from '@pecb-ui/components';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    PecbComponentsModule  // Import the PECB UI components module
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }
2. Import Global Styles (Optional)

If you want to use the PECB design system variables in your application:

// styles.scss
@import '@pecb-ui/components/styles/main';

Or import specific abstracts:

// In your component SCSS
@import '@pecb-ui/components/styles/abstracts/variables';
@import '@pecb-ui/components/styles/abstracts/mixins';

.my-component {
  color: $primary-color;
  padding: $spacing-md;
  @include elevation(2);
}
3. Use Components
<!-- app.component.html -->
<pecb-button variant="primary" size="medium" (clicked)="handleClick()">
  Click Me
</pecb-button>

<pecb-card elevation="md">
  <pecb-card-header>
    <h3>Welcome</h3>
  </pecb-card-header>
  <pecb-card-body>
    <p>Your content goes here</p>
  </pecb-card-body>
</pecb-card>

Components

Button Component

A versatile button component with multiple variants, sizes, and accessibility features.

<!-- Basic button -->
<pecb-button variant="primary" (clicked)="onClick()">
  Submit
</pecb-button>

<!-- With loading state -->
<pecb-button variant="primary" [loading]="isLoading">
  Save
</pecb-button>

<!-- Disabled button -->
<pecb-button variant="danger" [disabled]="true">
  Delete
</pecb-button>

<!-- Full width button -->
<pecb-button variant="success" [fullWidth]="true">
  Continue
</pecb-button>

<!-- Icon button with accessibility label -->
<pecb-button variant="secondary" ariaLabel="Close dialog" iconLeft="">
</pecb-button>

<!-- Toggle button -->
<pecb-button variant="secondary" [ariaPressed]="isActive" (clicked)="toggle()">
  Toggle
</pecb-button>

<!-- Button that controls a dropdown -->
<pecb-button
  variant="primary"
  [ariaExpanded]="isOpen"
  ariaHasPopup="menu"
  ariaControls="dropdown-menu"
  (clicked)="toggleDropdown()">
  Menu
</pecb-button>

Properties:

Property Type Default Description
variant 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'text' 'primary' Visual style variant
size 'small' | 'medium' | 'large' 'medium' Button size
disabled boolean false Disable the button
loading boolean false Show loading spinner
fullWidth boolean false Make button full width
type 'button' | 'submit' | 'reset' 'button' HTML button type
iconLeft string - Icon before text
iconRight string - Icon after text
ariaLabel string - Accessible label
ariaExpanded boolean - ARIA expanded state
ariaPressed boolean - ARIA pressed state (toggle buttons)
ariaHasPopup boolean | 'menu' | 'listbox' | 'tree' | 'grid' | 'dialog' - Popup type
ariaControls string - ID of controlled element

Events:

Event Type Description
clicked EventEmitter<MouseEvent> Emitted on button click
Card Component

A container component for displaying content with optional header, body, and footer sections.

<!-- Basic card -->
<pecb-card elevation="md">
  <pecb-card-header>
    <h3>Card Title</h3>
  </pecb-card-header>
  <pecb-card-body>
    <p>Card content goes here</p>
  </pecb-card-body>
  <pecb-card-footer>
    <pecb-button variant="primary">Action</pecb-button>
  </pecb-card-footer>
</pecb-card>

<!-- Hoverable card -->
<pecb-card elevation="sm" [hoverable]="true">
  <pecb-card-body>
    <p>Hover over me!</p>
  </pecb-card-body>
</pecb-card>

<!-- Card as article (accessible) -->
<pecb-card role="article" ariaLabelledBy="article-title">
  <pecb-card-header>
    <h2 id="article-title">Article Headline</h2>
  </pecb-card-header>
  <pecb-card-body>
    <p>Article content...</p>
  </pecb-card-body>
</pecb-card>

<!-- Card as region -->
<pecb-card role="region" ariaLabel="Product Information">
  <pecb-card-body>
    <p>Product details...</p>
  </pecb-card-body>
</pecb-card>

Properties:

Property Type Default Description
elevation 'none' | 'sm' | 'md' | 'lg' | 'xl' 'md' Shadow depth
hoverable boolean false Enable hover effect
noPadding boolean false Remove default padding
role 'article' | 'region' | 'group' | 'listitem' | 'none' 'none' Semantic role
ariaLabel string - Accessible label
ariaLabelledBy string - ID of labelling element
ariaDescribedBy string - ID of describing element

Services

NotificationService

A stateless, injectable service for displaying toast notifications.

import { NotificationService } from '@pecb-ui/components';

@Component({...})
export class MyComponent {
  constructor(private notificationService: NotificationService) {}

  showSuccess(): void {
    this.notificationService.success('Operation completed successfully!');
  }

  showError(): void {
    this.notificationService.error('An error occurred', 'Error');
  }

  showWarning(): void {
    this.notificationService.warning('Please review your input', 'Warning');
  }

  showInfo(): void {
    this.notificationService.info('New updates available');
  }

  showCustom(): void {
    this.notificationService.show({
      message: 'Custom notification',
      type: 'info',
      duration: 10000,
      position: 'bottom-right',
      dismissible: true
    });
  }
}
ThemeService

A stateless, injectable service for managing application themes.

import { ThemeService } from '@pecb-ui/components';

@Component({...})
export class MyComponent {
  isDarkMode$ = this.themeService.theme$.pipe(
    map(config => config.resolvedTheme === 'dark')
  );

  constructor(private themeService: ThemeService) {}

  toggleTheme(): void {
    this.themeService.toggleTheme();
  }

  setDarkMode(): void {
    this.themeService.setTheme('dark');
  }

  useSystemPreference(): void {
    this.themeService.useSystemTheme();
  }

  setCustomColors(): void {
    this.themeService.setCustomVariables({
      primaryColor: '#007bff',
      backgroundColor: '#f8f9fa'
    });
  }
}
LoadingService

A stateless, injectable service for managing loading states.

import { LoadingService } from '@pecb-ui/components';

@Component({...})
export class MyComponent {
  isLoading$ = this.loadingService.isLoading$('data-fetch');

  constructor(private loadingService: LoadingService) {}

  async loadData(): Promise<void> {
    this.loadingService.start('data-fetch', 'Loading data...');
    try {
      const data = await this.fetchData();
      // Process data
    } finally {
      this.loadingService.stop('data-fetch');
    }
  }

  // Or use the helper method
  async loadDataAlt(): Promise<void> {
    const data = await this.loadingService.withLoading(
      'data-fetch',
      () => this.fetchData(),
      'Loading data...'
    );
  }
}

Utilities

The library exports utility functions for common operations:

import {
  // String utilities
  toKebabCase,
  toCamelCase,
  truncate,
  slugify,

  // DOM utilities
  generateUniqueId,
  getFocusableElements,
  trapFocus,
  copyToClipboard,

  // Accessibility utilities
  announceToScreenReader,
  getButtonAriaAttributes,
  prefersReducedMotion,

  // Error handling
  createError,
  wrapError,
  tryAsync
} from '@pecb-ui/components';

Types & Interfaces

import {
  // Common types
  Size,
  ComponentSize,
  ColorVariant,
  Position,

  // Component interfaces
  Disableable,
  Loadable,
  Focusable,
  SelectableItem,
  MenuItem,

  // Service interfaces
  NotificationConfig,
  ThemeConfig,
  LoadingState
} from '@pecb-ui/components';

SCSS Design System

Variables
// Colors
$primary-color: #1976d2;
$accent-color: #ff4081;
$success-color: #4caf50;
$warn-color: #f44336;
$info-color: #2196f3;

// Spacing (8px base unit)
$spacing-xs: 4px;
$spacing-sm: 8px;
$spacing-md: 16px;
$spacing-lg: 24px;
$spacing-xl: 32px;

// Typography
$font-family-base: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
$font-size-sm: 0.875rem;
$font-size-md: 1rem;
$font-size-lg: 1.125rem;

// Border radius
$border-radius-sm: 4px;
$border-radius-md: 8px;
$border-radius-lg: 12px;
Mixins
// Responsive breakpoints
@include respond-to('md') {
  // Styles for medium screens and up
}

// Flexbox utilities
@include flex-center;
@include flex-between;

// Elevation (shadows)
@include elevation(2);

// Focus visible
@include focus-visible {
  outline: 2px solid $primary-color;
}

// Transitions
@include transition(background-color, color);

Development

Prerequisites
  • Node.js 18+
  • npm 9+
  • Angular CLI 17.3+
Setup
# Clone the repository
git clone https://github.com/pecb-ui/components.git
cd components

# Install dependencies
npm install

# Build the library
npm run build

# Run Storybook
npm run storybook

# Run tests
npm test
Building
# Development build
npm run build

# Production build
npm run build:prod

# Create npm package
npm run publish:lib
Testing
# Run tests in watch mode
npm test

# Run tests once with coverage
npm run test:ci
Storybook
# Start Storybook dev server
npm run storybook

# Build Storybook for deployment
npm run build-storybook

Browser Support

  • Chrome (latest)
  • Firefox (latest)
  • Safari (latest)
  • Edge (latest)

Roadmap

Planned components:

  • Input/Form controls
  • Modal/Dialog
  • Dropdown/Select
  • Tabs
  • Accordion
  • Table
  • Pagination
  • Badge
  • Avatar
  • Tooltip
  • Alert/Toast
  • Progress indicators
  • Date picker

Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes using Conventional Commits
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

MIT License - see the LICENSE file for details.

Support

For issues and questions, please use the GitHub issue tracker.

Keywords