(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.
- 🌐 Live demo & docs: https://ryoucerious.github.io/cerious-widgets/
- 📦 npm: https://www.npmjs.com/package/ngx-cerious-widgets
- ~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 underprovideExperimentalZonelessChangeDetection(). - 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.
npm install ngx-cerious-widgetsNo 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.scssto yourangular.jsonstylesarray, it's identical to the injected sheet.
<!-- 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.
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 */
}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 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 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>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.
Ideas, plugins and PRs are welcome. Head to the issues page to suggest features or report bugs.
MIT, free for personal and commercial projects.
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.
