Cerious Widgets

July 14, 2026 Β· View on GitHub

Cerious Widgets

Cerious Widgets

(Pronounced: Serious)

A seriously complete, enterprise-grade Angular component library, ~85 standalone, signal-based, zoneless-safe components unified by a token-based theming engine (10 built-in themes plus your own brand colors), accessible to WCAG 2.1 AA, and extensible end-to-end with a universal plugin architecture.

No heavy dependencies. MIT licensed. Built for real-world, data-intensive apps.


✨ Highlights

  • ~85 components across Data, Form, Display, Navigation, Overlay & Utilities, from inputs, selects and a virtualized data grid to menus, dialogs, charts and a calendar.
  • Themeable to the core, 10 built-in presets (light, frost, dark, midnight, sandstone, emerald, grape, contrast, flat, soft) that vary color and shape/elevation, plus a runtime engine to set your own primary/secondary, radius and typography. All driven by --cw-* tokens; switch live.
  • Accessible by default, keyboard navigation, ARIA and focus management throughout; the whole library passes axe-core WCAG 2.1 AA with 0 violations across every component page in every theme.
  • Zoneless & signal-based, every component is standalone, OnPush and built on Angular signals, safe under provideExperimentalZonelessChangeDetection().
  • Universal plugin system, every component is a plugin host. Extend, observe or completely replace behaviour without forking. See Plugins.
  • A world-class data grid, virtual scrolling, server-side mode, multi-sort, grouping, pinning, drag-and-drop columns, column menu, Excel export, save/restore views.

πŸ“¦ Installation

npm install ngx-cerious-widgets

No stylesheet import needed. The library injects its structural styles and --cw-* tokens automatically at bootstrap, add provideCeriousTheme() once (standalone apps) or use CeriousWidgetsModule.forRoot(...) (module apps):

// app.config.ts (standalone)
import { provideCeriousTheme } from 'ngx-cerious-widgets';

export const appConfig: ApplicationConfig = {
  providers: [
    provideCeriousTheme(),                       // default theme
    // provideCeriousTheme({ preset: 'dark', primary: '#6c63ff' })
  ]
};

The components are standalone, import just what you use:

import { SelectComponent, DialogComponent } from 'ngx-cerious-widgets';

@Component({
  standalone: true,
  imports: [SelectComponent, DialogComponent],
  // ...
})
export class MyComponent {}

Prefer a module? CeriousWidgetsModule.forRoot({ /* config */ }) still works, delivers the styles, and is where you register plugins (see below).

Prefer a plain global stylesheet instead? You can still add node_modules/ngx-cerious-widgets/styles/grid-styles-generated.scss to your angular.json styles array, it's identical to the injected sheet.


πŸš€ Quick start

<!-- A themed select -->
<cw-select [options]="cities" [(ngModel)]="city" optionLabel="name" optionValue="code" placeholder="Pick a city" />

<!-- The data grid -->
<cw-grid [data]="rows" [gridOptions]="gridOptions" (rowClick)="onRowClick($event)" />

Browse every component, with live examples, an API table and theming notes for each, in the documentation site.


🎨 Theming

All visuals are driven by --cw-* design tokens, so theming is a matter of setting CSS variables, no recompiling. Ship the built-in presets or define your own.

<!-- Switch the whole app at runtime -->
<html data-cw-theme="frost">  <!-- 'light' | 'frost' | 'dark' -->
:root {
  --cw-primary: #2563eb;
  --cw-surface: #ffffff;
  --cw-radius: 8px;
  /* …override any token */
}

Custom themes & brand colors

Beyond the static themes, a runtime theming engine lets you set your own brand colors and choose from extra curated presets, light, frost, dark, midnight, sandstone, emerald, grape, contrast. Pass a preset and/or your own primary/secondary; the engine derives the whole brand palette (hover/active states, AA-safe filled surfaces, focus ring, chips) while keeping the preset's tuned neutrals.

// app.config.ts, apply at bootstrap
import { provideCeriousTheme } from 'ngx-cerious-widgets';

export const appConfig = {
  providers: [
    provideCeriousTheme({ preset: 'dark', primary: '#e11d48', radius: '10px' })
  ]
};
// …or change it live
import { CwThemeService } from 'ngx-cerious-widgets';

const theme = inject(CwThemeService);
theme.apply({ preset: 'emerald' });      // switch preset
theme.apply({ primary: '#0ea5e9' });     // re-brand on the current theme
theme.registerPreset({ name: 'ocean', label: 'Ocean', base: 'dark', dark: true,
                       seeds: { primary: '#06b6d4' } });

Themes can also be scoped to a region (apply({ scope: el })). Full guide: /components/theming.


🧩 Plugins

Plugins let you change or extend a component's functionality without touching library source. Every component is a plugin host: your plugin receives the component's typed public API on init and can read state, drive it, decorate the DOM, or replace behaviour outright.

import { SelectApi, SelectPlugin } from 'ngx-cerious-widgets';

export class DblClickOpenPlugin implements SelectPlugin {
  onInit(api: SelectApi) {
    api.getHost().addEventListener('dblclick', () => api.open());
  }
  onDestroy() { /* clean up */ }
}

Register plugins declaratively per component (the key is the component's selector without cw-, camel-cased):

CeriousWidgetsModule.forRoot({
  select:   { plugins: [DblClickOpenPlugin] },
  checkbox: { plugins: [AuditPlugin] },
  grid:     { plugins: [MultiSortPlugin, ColumnMenuPlugin] },
})

API tiers: every host exposes at least getHost() (CwWidgetApi); value controls add getValue/setValue/isDisabled (CwFormControlApi); selection containers and the grid expose richer bespoke contracts (SelectApi, TabsApi, TreeApi, GridApi, …). Building your own component? Make it extensible in one line with providePluginHost(namespace, api).

Full guide: /components/plugins.


β–¦ The data grid

The grid is a full-blown, enterprise data grid, not just a table:

  • Performance, virtual scrolling (render 1M+ rows), pagination, server-side mode (paging / filtering / virtual scroll).
  • Layout, column resizing & pinning, drag-and-drop reordering, grouped headers, group-by with a drag-to-group UI, nested rows (any Angular template).
  • Data, multi-column sorting (Ctrl/Meta-click), text/number/select/date filtering.
  • Customization, cell/header/row templates; directive-based plugin templates.
  • Extensibility, pluggable architecture, save & restore views, one-line Excel export.
<cw-grid
  [data]="data"
  [gridOptions]="gridOptions"
  [pluginOptions]="{ MultiSort: { enableMultiSort: true }, ColumnMenu: { enableColumnMenu: true } }"
  (rowClick)="onRowClick($event)">
</cw-grid>

β™Ώ Accessibility

Keyboard support, ARIA roles/attributes and focus management are built into every component. The library is verified with an axe-core harness across all component pages in every theme, 0 WCAG 2.1 AA violations. Color tokens meet AA contrast, including the filled/severity surfaces.


🀝 Contributing

Ideas, plugins and PRs are welcome. Head to the issues page to suggest features or report bugs.


πŸ“ License

MIT, free for personal and commercial projects.


🧠 Built with purpose

Cerious Widgets was built by a developer who's spent nearly two decades in enterprise front-end development. If you've ever been frustrated by restrictive licensing or boxed in by rigid components, this is for you.

https://ryoucerious.github.io/cerious-widgets/