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

@one-grid-core/angular

v1.0.0

Published

OneGrid — a feature-rich Angular data grid component with tree data, master/detail, editing, selection, pagination, and virtual scrolling.

Readme

OneGrid

A feature-rich Angular data grid component with tree data, master/detail rows, inline editing, row/cell selection, pagination, and virtual scrolling.

Installation

npm install @one-grid-core/angular

Peer dependencies (installed alongside your app):

npm install @angular/cdk lucide-angular

Requires Angular 17 or newer.

Usage

Everything in the library is standalone, so import the component directly:

import { OneGridComponent } from '@one-grid-core/angular';

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

OneGridModule still works and exports the same components, for apps that are not standalone yet:

import { OneGridModule } from '@one-grid-core/angular';

@NgModule({
  imports: [OneGridModule],
})
export class AppModule {}

Both paths render identically — the icons the grid draws travel with the components, so nothing extra needs registering either way.

Use the component:

<one-grid
  [rowData]="rows"
  [columnDefs]="columnDefs"
  [defaultColumnDef]="defaultColumnDef"
  (onGridReady)="onGridReady($event)"
/>
import { OneColumnDef, OneGridReadyEvent } from '@one-grid-core/angular';

export class AppComponent {
  rows = [{ make: 'Toyota', model: 'Celica', price: 35000 }];

  columnDefs: OneColumnDef<any>[] = [
    { field: 'make' },
    { field: 'model' },
    { field: 'price' },
  ];

  defaultColumnDef: OneColumnDef<any> = { resizable: true, sortable: true };

  onGridReady(event: OneGridReadyEvent) {
    // event.api gives programmatic access to the grid
  }
}

Styles

Import the theme in your global styles.scss:

@use "@one-grid-core/angular/scss/one-grid";

The theme is self-contained: it renders with neutral defaults on its own, and automatically picks up your Bootstrap design tokens (--bs-* CSS variables) when Bootstrap is present.

Theming

Every visual value is exposed through a layered token system, so you can customize at the level that fits:

1. Runtime CSS custom properties (recommended)

Set --one-grid-* variables anywhere — they inherit like normal CSS variables. No recompile needed, and they can change at runtime (theme switcher, dark mode).

/* Globally */
:root {
  --one-grid-primary: #6d28d9;
  --one-grid-cell-height: 34px;
}

/* Dark mode */
.theme-dark {
  --one-grid-body-bg: #1e1e1e;
  --one-grid-header-bg: #262626;
  --one-grid-row-odd-bg: #1e1e1e;
  --one-grid-row-even-bg: #242424;
  --one-grid-text-color: #e5e5e5;
  --one-grid-border-color: #3a3a3a;
  --one-grid-input-bg: #2a2a2a;
  --one-grid-pagination-bg: #1e1e1e;
  --one-grid-pagination-btn-color: #e5e5e5;
}

/* A single compact grid instance */
one-grid.compact {
  --one-grid-cell-height: 24px;
  --one-grid-header-cell-height: 28px;
  --one-grid-font-size: 11px;
}

2. Compile-time Sass configuration

Every Sass variable is declared !default, so you can configure the module:

@use "@one-grid-core/angular/scss/one-grid" with (
  $cell-height: 36px,
  $og-primary: #6d28d9,
  $prefix: "bs-"   // prefix of your design system's CSS variables
);

Legacy @import with pre-defined variables also still works.

Available tokens

| Token (--one-grid-*) | Default | Purpose | | --- | --- | --- | | header-bg | var(--bs-tertiary-bg, #f8f9fa) | Header background | | body-bg | var(--bs-card-bg, #fff) | Body background | | row-odd-bg / row-even-bg | card / body bg | Zebra striping | | border-color | var(--bs-border-color, #dee2e6) | All borders and separators | | text-color | var(--bs-body-color, #212529) | Cell and header text | | font-size | 12px | Grid font size | | hover-bg | primary at 8% | Row hover | | selected-bg | primary at 8% | Selected row | | cell-selected-bg | primary at 16% | Selected cell | | cell-selected-flash-bg | primary at 60% | Copy-feedback flash | | header-cell-height | 34px | Header row height | | cell-height | 30px | Data row height (density) | | cell-padding | 0 10px | Cell padding | | cell-item-space | 8px | Spacing between in-cell items | | cell-line-height | 1.2 | Text line height | | row-drag-handle-color | var(--bs-secondary-color, #6c757d) | Row drag handle at rest | | row-drag-indicator-size | 2px | Thickness of the drop indicator line | | detail-padding | 8px | Inset around a master/detail row's nested grid. It is height the virtual scroller cannot account for; set it to 0 for a flush detail area. | | action-btn-size | 20px | Row action buttons, checkboxes, icons | | action-btn-radius | 4px | Small control corner radius | | border-radius | 0 | Outer grid corner radius | | input-bg | var(--bs-input-bg, #fff) | Inline cell editor background | | pagination-bg / pagination-btn-color / pagination-height | card bg / body color / 40px | Pagination bar | | primary / success / warning / danger / info | Bootstrap accents | Accent colors | | on-accent | #fff | Text/icons on accent fills | | primary-ink | var(--tl-accent-ink, #fff) | Ink on the primary fill | | primary-subtle-bg / success-subtle-bg / danger-subtle-bg / info-subtle-bg | accents at 8–15% | Subtle state fills | | drop-valid-bg / drop-invalid-bg | success/danger at 10% | Drag-and-drop targets | | menu-shadow | var(--bs-box-shadow-lg, …) | Cell option menu elevation |

UX guidance when customizing: keep cell-height ≥ 24px so click targets stay usable, keep text/background pairs at a WCAG contrast of at least 4.5:1, and derive hover/selected states from your primary color at low opacity so they remain distinguishable in both light and dark themes.

Column callbacks

Every callback on a column definition comes in one of two scopes, and the params say which.

Cell-scoped — resolved per row, and all handed the same object: value, data, node, rowIndex, field, columnDef, api, context, plus whatever the column declared in cellRendererParams (the grid's own fields win a name collision).

editable · updatable · disable · hideActionButton · rowDrag · cellClass · cellStyle · cellRenderer · valueFormatter

Header-scoped — resolved once per column, when the columns are registered. A header is one cell for the whole column, so there is no row: columnDef, field, context.

sortable · resizable · dragable · suppressHeaderMenuButton · headerClass · headerStyle

valueGetter is its own shape (OneValueGetterParams): data, rowIndex, node, context.

Features

  • Column definitions with value getters, value formatters, cell renderers and validation
  • Column visibility (hide / api.setColumnVisible) and a JSON-safe layout round-trip (api.getColumnStateSnapshot / api.applyColumnState)
  • Sorting, including multi-column through the sort model
  • Quick filter and a programmatic column filter model with thirteen operators, including negations, inclusive inRange and blank / notBlank
  • Tree data with expand/collapse and auto group columns
  • Row transactions (api.applyTransaction({ add, addToParentId, update, remove })) — append, patch or drop rows by id without rebinding the dataset; selection and expansion survive, tree-aware
  • Row grouping (columnDef.rowGroup, nesting in column order) with aggregation (columnDef.aggFunc: sum/min/max/avg/count/first/last or a custom function over the leaves), regroupable at runtime through api.setRowGrouping(fields) — any columns, any nesting order, [] to ungroup, without the grid being re-created
  • Master/detail nested grids
  • Inline cell editing with input validation, including a select editor whose options commit typed values
  • Full-row editing (editType="fullRow"): every editable cell of the row opens together, Enter or leaving the row commits, Escape abandons
  • Undo/redo of committed cell edits ([undoRedoCellEditing], api.undoCellEditing / redoCellEditing, Ctrl+Z / Ctrl+Y in the grid); a paste or a clear is one step however many cells it touched
  • Cell ranges, by dragging or from the keyboard: Shift with the arrow, Home, End and page keys stretches a range, a plain arrow or Escape collapses it, Ctrl/Cmd+A takes every cell. Drawn as one outline around the range. It survives a click elsewhere on the page, so a host toolbar button can act on it
  • Clipboard in the spreadsheet format (tab-separated, quoted where a value holds a tab or line break): Ctrl+C copies the range or the focused cell, Ctrl+V pastes from Excel, Sheets or the grid — one value fills a selected range — and Delete / Backspace clears the range. Pasted values go through the editor's conversion; read-only cells and values that do not fit the column are skipped and the count announced. Each changed cell raises cellValueChanged with source: 'paste' or 'delete'
  • Row and cell selection, header checkbox select-all. From the keyboard, Space toggles the focused row and Shift+Space selects from where the row selection started (Shift+Arrow used to extend the rows; it now stretches the cell range)
  • Pinned columns (left/right) and pinned rows (top/bottom)
  • Row drag & drop, operable by pointer or keyboard
  • Row action buttons and per-cell option menus
  • Virtual scrolling (Angular CDK)
  • Flex column sizing (columnDef.flex) against the grid's own viewport; hand-resizing a column takes it out of the flex pool
  • A default column menu behind the header ⋮ button ([headerMenu]) — sort, pin, hide — with (headerMenuClick) still emitted for hosts that bring their own
  • A filter row ([filterRow]) with an input under every column whose filterable resolves true, feeding the filter model debounced
  • Client-side pagination ([clientSidePagination] + [pageSize]): the grid slices the filtered rows and drives its own bar; the default mode still leaves paging to the host
  • CSV export (api.getDataAsCsv / api.exportDataAsCsv), through the same value getter/formatter pipeline the cells render with
  • Host outputs for sort changes (sortChanged), committed cell edits (cellValueChanged), focus and range changes (cellFocused / cellRangeChanged), and completed column drags and resizes (columnMoved / columnResized) — also available from code through api.addEventListener(type, listener), which returns its unsubscribe
  • A cell API for everything the keyboard and pointer can do: getFocusedCell / setFocusedCell, ensureRowVisible / ensureColumnVisible (minimal scroll, clear of pinned columns), getCellRange / setCellRange / clearCellRange / getCellRangeValues, startEditingCell / stopEditing(cancel?) / getEditingCells, and getCellValue(rowId, field, { formatted }) / setCellValue — the last refreshes the cell and raises cellValueChanged with source: 'api'

Not implemented

Declared in the public types but inert, and documented as such rather than quietly omitted:

  • columnDef.valueSetter — never invoked, and its signature could not work; api.setCellValue(rowId, field, value) is the write path

Deliberately out of scope, so nobody goes looking:

  • Pivoting — row grouping aggregates down a tree; turning values into columns is a different engine.
  • A server-side / infinite row model — the host-driven pagination contract plus the sort and filter models is this grid's server story: page, sort and filter server-side and hand the grid each page. A block cache would duplicate that with more machinery.
  • Cell/row spanning — incompatible with fixed-height virtual scrolling as built.

License

MIT