npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@afkarbase/ui

v0.3.0

Published

Modern Angular Material Design 3 UI component library with comprehensive theming and accessibility features

Downloads

187

Readme

@afkarbase/ui

Angular UI component library — Material Design 3 inspired, zero Angular Material dependency.

v0.2.0 · Angular 19/20/21 · MIT License


Installation

npm install @afkarbase/ui

Required peer dependencies:

npm install @angular/core @angular/common

Optional peer dependencies (install if you use the corresponding features):

npm install @angular/forms       # form components (inputs, select, checkbox…)
npm install @angular/animations  # animated transitions
npm install @angular/router      # breadcrumbs, navigation

Quick Start

1. Import the library styles in your angular.json or global stylesheet:

// styles.scss
@use '@afkarbase/ui/styles';         // base styles + component styles
@use '@afkarbase/ui/themes/light';   // light theme tokens

For dark theme, add the dark stylesheet or let ThemeService toggle it at runtime:

@use '@afkarbase/ui/themes/dark';

2. Import the component you need (all components are standalone):

import { UiButton } from '@afkarbase/ui';

@Component({
  imports: [UiButton],
  // ...
})

3. Use it in your template:

<button ui-button="filled">Get started</button>
<button ui-button="outlined" [loading]="saving">Save</button>
<a ui-button="text" href="/docs">Documentation</a>

Features

| Feature | Description | |---|---| | Zero Material dependency | No @angular/material or @angular/cdk — no version conflicts | | Standalone components | Each component is fully standalone; import only what you use | | CSS token theming | Every visual property is a --ui-* CSS custom property | | Light / Dark / High-contrast | Built-in theme stylesheets, runtime switching via ThemeService | | RTL & LTR | Full bidirectional layout support via UiDirectionality | | Density variants | Compact, default, and comfortable density via CSS token overrides | | Accessibility | ARIA roles, keyboard navigation, focus rings, reduced-motion support | | Signal-based services | ThemeService and UiDirectionality expose Angular signals | | Angular 19 / 20 / 21 | Tested across supported versions | | Testing harnesses | UiButtonHarness, UiCheckboxHarness, UiInputHarness, and more |


Component Inventory

Actions

| Component | Selector | Description | |---|---|---| | Button | button[ui-button], a[ui-button] | Five variants: filled, outlined, text, elevated, tonal | | IconButton | button[ui-icon-button], a[ui-icon-button] | Icon-only button with standard/filled/outlined/tonal variants | | FAB | ui-fab | Floating action button | | ButtonToggle | ui-button-toggle / ui-button-toggle-group | Toggle button group | | SegmentedButton | ui-segmented-button / ui-segmented-button-group | Segmented control |

Display

| Component | Selector | Description | |---|---|---| | Card | ui-card | Surface container with header, content, actions, media slots | | Avatar | ui-avatar / ui-avatar-group | User avatars with image, initials, and icon support | | Icon | ui-icon | Inline SVG / ligature icon | | Badge | ui-badge | Numeric or dot indicator | | Chip | ui-chip / ui-chip-set / ui-chip-listbox | Input, filter, and suggestion chips | | Divider | ui-divider | Horizontal or vertical separator | | ProgressBar | ui-progress-bar | Determinate and indeterminate progress | | Timeline | ui-timeline / ui-timeline-item | Vertical timeline with custom icons | | ExpansionPanel | ui-expansion-panel / ui-accordion | Collapsible content panels | | Toolbar | ui-toolbar | App bar / page toolbar |

Form

| Component | Selector | Description | |---|---|---| | FormField | ui-form-field | Wrapper providing label, hint, error, and prefix/suffix slots | | TextInput | ui-text-input | Single-line text field | | Textarea | ui-textarea | Multi-line text field with auto-resize | | PasswordInput | ui-password-input | Password field with show/hide toggle | | NumberInput | ui-number-input | Numeric input with stepper | | SearchInput | ui-search-input | Search field with clear button | | PhoneInput | ui-phone-input | Phone number input with country code | | Select | ui-select | Single and multi-select dropdown | | Autocomplete | ui-autocomplete | Combobox with filtered suggestions | | Checkbox | ui-checkbox | Material checkbox with indeterminate state | | Radio | ui-radio-button / ui-radio-group | Radio button group | | ToggleSwitch | ui-toggle-switch | On/off toggle (slide toggle) | | Slider | ui-slider | Single and range value slider | | WYSIWYG | ui-wysiwyg | Rich text editor |

Feedback & Overlays

| Component | Selector / Service | Description | |---|---|---| | Alert | ui-alert | Inline alert with severity variants | | Tooltip | [uiTooltip] | Lightweight hover/focus tooltip | | Dialog | UiDialog service | Modal dialog with custom content | | Snackbar | UiSnackBar service | Brief dismissible notification | | Toast | UiToastService service | Stacked toast notifications | | BottomSheet | service | Bottom sheet overlay | | ProgressSpinner | ui-progress-spinner | Circular determinate/indeterminate spinner | | Skeleton | ui-skeleton | Content placeholder | | EmptyState | ui-empty-state | Zero-result / no-data illustration |

Navigation

| Component | Selector | Description | |---|---|---| | Drawer | ui-drawer-container / ui-drawer | Side navigation drawer (modal and persistent) | | NavRail | ui-nav-rail / ui-nav-rail-item | Vertical navigation rail | | Menu | ui-menu / [uiMenuTriggerFor] | Contextual dropdown menu | | Breadcrumbs | ui-breadcrumbs | Page hierarchy breadcrumb trail | | Stepper | ui-stepper | Linear/non-linear wizard stepper | | Paginator | ui-paginator | Page navigation with size control | | Tree | ui-tree / ui-tree-node | Hierarchical tree view |

List

| Component | Selector | Description | |---|---|---| | List | ui-list / ui-list-item | Structured list with leading/trailing slots | | SelectionList | ui-selection-list / ui-selection-list-option | Checkable list items |

Utilities & Extras

| Component | Selector | Description | |---|---|---| | DatePicker | ui-date | Calendar date picker | | TimePicker | ui-time | Clock time picker | | ColorPicker | ui-color-picker | Color selection widget | | FileUpload | ui-file-upload | Drag-and-drop file input | | CommandPalette | ui-command-palette | Searchable command menu (Cmd+K style) | | CodeBlock | ui-code | Syntax-highlighted code block | | Popover | ui-popover / [uiPopoverTriggerFor] | Anchored floating content panel | | ErrorBoundary | ui-error-boundary | Catches and displays Angular render errors | | Chips | ui-chip-input / ui-chip-option-listbox | Tag input and multi-select chip list |

Directives

| Directive | Selector | Description | |---|---|---| | Ripple | [uiRipple] | Material ink ripple effect | | TrapFocus | [uiTrapFocus] | Keyboard focus trap for overlays | | Autofocus | [uiAutofocus] | Focus element on render | | ClickOutside | [uiClickOutside] | Emit event on outside click | | LongPress | [uiLongPress] | Detect long-press gestures | | Drag & Drop | [uiDrag] / [uiDropList] / [uiDragHandle] | Drag-and-drop primitives |


Theming

The library uses a three-layer CSS custom property system:

core tokens (--ui-palette-*, --ui-spacing-*, …)
    ↓
semantic tokens (--ui-sys-color-primary, --ui-sys-color-surface, …)
    ↓
component tokens (--ui-button-container-color, …)

Built-in themes

@use '@afkarbase/ui/styles';            // required: base + component styles
@use '@afkarbase/ui/themes/light';      // light color scheme
@use '@afkarbase/ui/themes/dark';       // dark color scheme
@use '@afkarbase/ui/themes/high-contrast'; // high contrast

Overriding tokens

Override at any level using CSS custom properties:

:root {
  /* Semantic tokens */
  --ui-sys-color-primary: #1a73e8;
  --ui-sys-color-secondary: #5f6368;

  /* Component-level override */
  --ui-button-container-color: #1a73e8;
  --ui-button-label-text-color: #ffffff;

  /* Density */
  --ui-density: -1;   /* -2 compact | 0 default | 2 comfortable */
}

ThemeService

Inject ThemeService to control the active theme at runtime:

import { ThemeService } from '@afkarbase/ui';

@Component({ /* … */ })
export class AppComponent {
  private theme = inject(ThemeService);

  // Switch mode
  setDark()   { this.theme.setTheme('dark'); }
  setLight()  { this.theme.setTheme('light'); }
  setSystem() { this.theme.setTheme('system'); }
  toggle()    { this.theme.toggleTheme(); }

  // Dynamic source color (generates full M3 palette from one seed color)
  setBrand(color: string) { this.theme.setSourceColor(color); }

  // Accessibility
  enableHighContrast() { this.theme.setHighContrast(true); }
  enableReducedMotion() { this.theme.setReducedMotion(true); }

  // Signals (use in templates with Angular's signal reactivity)
  isDark      = this.theme.isDark;         // Signal<boolean>
  currentMode = this.theme.currentTheme;   // Signal<'light' | 'dark' | 'system'>
}
<button (click)="toggle()">
  {{ isDark() ? 'Switch to Light' : 'Switch to Dark' }}
</button>

RTL Support

All components flip their layout automatically based on the document dir attribute. Use UiDirectionality to read or set direction at runtime:

import { UiDirectionality } from '@afkarbase/ui';

@Component({ /* … */ })
export class AppComponent {
  private dir = inject(UiDirectionality);

  isRtl  = this.dir.isRtl;    // Signal<boolean>
  dirVal = this.dir.direction; // Signal<'ltr' | 'rtl'>

  setRtl() { this.dir.setDirection('rtl'); }
  setLtr() { this.dir.setDirection('ltr'); }
}

To set the initial direction, add dir="rtl" to your <html> element:

<html lang="ar" dir="rtl">

UiDirectionality observes <html dir="…"> via MutationObserver and updates its signals when the attribute changes at runtime.


Accessibility

  • All interactive components are keyboard operable and follow ARIA authoring practices.
  • Focus rings are visible by default and styled via --ui-focus-ring-color / --ui-focus-ring-width.
  • Reduced motion: set via ThemeService.setReducedMotion(true) or the OS preference is respected automatically.
  • Form components implement ControlValueAccessor with correct aria-label, aria-describedby, and aria-invalid wiring.
  • LiveAnnouncer service is available for dynamic screen-reader announcements.

Contributing

See CONTRIBUTING.md for development setup, coding standards, and the PR workflow.

Issues and feature requests: github.com/afkarbase/ui/issues


License

MIT © Afkarbase