Style Guide

August 3, 2026 · View on GitHub

Design principles, Angular Material theming, component guidelines, and accessibility standards for the @acontplus/ng-components library.


Design Principles

  1. Consistency — components look and behave the same across all applications
  2. Simplicity — intuitive API, minimal required configuration
  3. Flexibility — fully customizable without forking
  4. Accessibility — WCAG AA minimum on all components
  5. Performance — OnPush change detection, Angular Signals for reactive state

Color System

Built on Angular Material's theming. All components adapt automatically to light/dark mode via the ThemeSwitcher service.

PaletteSCSS variableUse
Primarymat.$indigo-paletteMain actions, key UI elements
Accentmat.$pink-palette A200/A100/A400Secondary actions, highlights
Warnmat.$red-paletteErrors, destructive actions

Dark mode detection

Components and ThemeSwitcher detect dark mode via the .dark-theme CSS class on <html>. Toggle it with:

import { ThemeSwitcher } from '@acontplus/ng-components';

themeSwitcher.toggle(); // toggles and persists to localStorage
themeSwitcher.isDarkMode(); // Signal<boolean>

Typography

Follows Angular Material typography system using the Roboto font family.

LevelUse case
DisplayPage titles, hero text
HeadlineSection headings (<h1>, <h2>)
TitleCard titles, dialog titles
SubheadingSecondary headings (<h3>)
BodyMain content
CaptionLabels, hints, metadata
ButtonButton text

Spacing Scale

Base unit: 8px (0.5rem)

Namepxrem
xs4px0.25rem
sm8px0.5rem
md16px1rem
lg24px1.5rem
xl32px2rem
2xl48px3rem
3xl64px4rem

Minimum touch target: 48px


Component Guidelines

Cards — <acp-dynamic-card>

<acp-dynamic-card
  [cardTitle]="'Product Details'"
  [cardSubtitle]="'Premium Package'"
  [isHeaderVisible]="true"
  [areActionsVisible]="true"
  [primaryButtonText]="'Buy Now'"
  (primaryButtonClicked)="onPurchase()"
>
  Card content here
</acp-dynamic-card>
  • Use cards for discrete pieces of content — one topic per card
  • Maintain 16px padding inside card content
  • Limit to 2-3 actions per card maximum

Buttons — <acp-button>

<!-- Standard button -->
<acp-button variant="primary" text="Save" icon="save" (handleClick)="onSave()" />

<!-- Report/export button — auto icon, color, tooltip from format -->
<acp-button [reportFormat]="REPORT_FORMAT.PDF" text="Export" (handleClick)="export()" />
variantUse
primaryMain action on a page or section
secondaryAlternative action
successConfirmation, save, approve
dangerDelete, reject, destructive
warningCaution actions
infoNeutral informational actions

Button placement: Primary actions on the right in dialogs and forms. Consistent order: Cancel → Confirm.

Dialogs

import { AdvancedDialogService } from '@acontplus/ng-components';

dialogService.openInWrapper({
  component: YourDialogContentComponent,
  title: 'Dialog Title',
  icon: 'info',
  data: {/* ... */},
});
  • Keep dialogs focused on one task
  • Use 24px padding inside dialog content
  • Always provide a clear cancel/close action

DataGrid — <acp-data-grid>

columns: DataGridColumn[] = [
  { field: 'id',     header: 'ID',     type: 'number', sortable: true },
  { field: 'name',   header: 'Name',   sortable: true },
  { field: 'status', header: 'Status', cellTemplate: statusTemplate },
];
<acp-data-grid
  [data]="items"
  [columns]="columns"
  [rowSelectable]="true"
  [showPaginator]="true"
  [pageOnFront]="false"
  [length]="totalCount"
  (page)="onPageChange($event)"
  (rowSelectedChange)="onSelect($event)"
/>
  • Use for tabular data with pagination and sorting
  • Enable pageOnFront="false" for server-side pagination
  • Use cellTemplate for custom cell rendering
  • Column pinning available via pinned: 'left' | 'right'

Theme Toggle — <acp-theme-toggle>

<acp-theme-toggle lightModeLabel="Switch to light mode" darkModeLabel="Switch to dark mode" />
  • Place in app header or navigation bar
  • Always include accessible lightModeLabel and darkModeLabel for screen readers

Component Selector Convention

All library components use the acp- prefix:

@Component({ selector: 'acp-dynamic-card', ... })
@Component({ selector: 'acp-data-grid', ... })
@Component({ selector: 'acp-theme-toggle', ... })

Demo app components use app- prefix.


Accessibility Guidelines

  • Color contrast: WCAG AA minimum (4.5:1 for text, 3:1 for UI components)
  • Keyboard navigation: All interactive elements reachable via Tab, operated via Enter/Space
  • Screen readers: ARIA labels on icon-only buttons, `role$ \text{attributes} \text{on} \text{custom} \text{widgets}
  • \text{Touch} \text{targets}: \text{Minimum} 48 \times 48\text{px} \text{for} \text{all} \text{interactive} \text{elements}
  • \text{Motion}: \text{Respect} $prefers-reduced-motion` — disable animations for users who prefer it
// Animation example following the guidelines
animations: [
  trigger('fadeIn', [
    transition(':enter', [style({ opacity: 0 }), animate('300ms ease-in', style({ opacity: 1 }))]),
  ]),
];

Responsive Design

  • Mobile-first: design for smallest viewport, enhance for larger
  • Breakpoints: follow Angular Material breakpoints (xs, sm, md, lg, xl)
  • Test components at 320px, 768px, 1024px, 1440px minimum

SCSS Imports

// Import all ng-components styles
@use '@acontplus/ng-components/styles';

// For Tabulator Material theme
@import 'tabulator-tables/dist/css/tabulator_materialize.min.css';

// For notifications
@import 'ngx-toastr/toastr';
@import 'sweetalert2/themes/material-ui.css';