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

@masterteam/data-grid

v0.0.1

Published

Independent Angular data grid. Full reference parity is under development.

Readme

@masterteam/data-grid

Independent Angular 21 data-grid package, currently an incomplete implementation checkpoint. Full parity with the locked AG Grid 36.2.0 Community and Enterprise reference remains required; this package is not ready for that acceptance claim.

import { MtDataGridComponent, type MtColumnDef } from '@masterteam/data-grid';
// Add MtDataGridComponent to a standalone component's imports.
readonly rows = [{ id: 'a', name: 'Record', amount: 0 }];
readonly columns: MtColumnDef<(typeof this.rows)[number]>[] = [
  { field: 'name', width: 240 }, { field: 'amount', width: 180 },
];
readonly identify = (row: (typeof this.rows)[number]) => row.id;
<mt-data-grid [rowData]="rows" [columnDefs]="columns" [getRowId]="identify" [height]="400" ariaLabel="Records" />

Implemented foundations: fixed row/column virtual geometry, stable IDs, value getters/formatters, local stable multi-sort (Shift-click), keyboard arrows/Home/End/Page Up/Down, RTL positions, loading/empty text and a small owned API. Callers retain ownership of their input arrays/records. Without getRowId, IDs are source indices; provide IDs for identity across replacements. Values render as text. Duplicate identities and invalid sizes/sort models are errors.

Set direction="rtl" for right-to-left layout; label and overlay messages are caller-configurable. CSS variables currently expose mt-grid foreground/background/header/border/row-border/radius/font/cell-padding/hover/focus customization. These are an owned initial subset, not all upstream themes/parts.

Columns resize by dragging the header edge or pressing Alt+Left/Right from a focused header (2px per press, RTL aware). Shift-drag transfers width to the next displayed column within both columns' bounds. resizable:false disables that column's handle/keys; it can still receive width transferred by its neighbor. Width state belongs to each grid, including hidden columns. initialWidth applies on introduction of an ID; a later explicit width replaces its state, while omission preserves it. Removing and re-adding the ID creates fresh state. The default minimum is36px; minWidth/maxWidth bound widths.

The gridReady event exposes api.getColumnWidths() and api.setColumnWidths([{ colId: 'name', width: 280 }], finished = true). API requests outside the column's bounds are ignored, including0/negative requests; they still emit the requested completion notification with current widths. A same-width finished=true call can close a prior unfinished update. Nonfinite sizes and unknown/duplicate IDs fail atomically. columnResized emits { columns: [{ colId, width }], finished, source: 'api' | 'uiColumnResized' }. Input-definition replacement events, pointer no-change/Shift-final event details, exact upstream event timing/payloads, held-key acceleration, flex/auto/group sizing and full column state remain open; these owned names/signatures do not imply upstream API compatibility.

Build/test/API checks use the package scripts. Research, gaps, API differences and evidence are documented in .github/instructions/data-grid/README.md. Canonical integration is the existing showcase /data-grid route. Existing mt-table remains in place.

Portal integration contracts

Categorical analysis: give a column chartCategory: { values: ({ value, data }) => [{ id, label, color }], multiValue? } and charts group records by that identity, label the axis/legend with label, colour items with the authored colour (or a stable palette slot), and offer Count of records, Non-empty and Distinct measures beside numeric series. A Title + Status range therefore charts <chartRecordsLabel> by Status with integer counts and no numeric column; numeric series sum per identity category by default. chartRecordsLabel names the records ("Tasks"). Multi-value categories count a record once per member and disable share charts; missing values group under the localized Unassigned.

Nested viewports isolate their sticky headers so details cannot paint above a parent grid header. For a visible closed native end rail, use {toolPanels: ['columns', 'filters'], position: 'right'} in LTR (left in RTL), omitting defaultToolPanel. hiddenByDefault hides the rail itself.

For application-wide Columns panel defaults, provide {provide: MT_GRID_COLUMNS_TOOL_PANEL_DEFAULTS, useValue: {suppressRowGroups: true}}. This hides the duplicate Row Groups zone while retaining the top grouping strip, column menus and grouping API. Only built-in Columns panels inherit these defaults; explicit toolPanelParams override them. Other applications keep the full panel by default. /data-table demonstrates this provider without changing /data-grid/demo.

[autoSizeStrategy]="{ type: 'fitGridWidth' }" fits displayed columns on mount, viewport resizing and visibility/group changes, respecting minWidth, maxWidth and suppressSizeToFit. Manual column widths survive sorting/filtering. Applying or resetting column state refits saved widths to the current viewport in this mode, retaining their proportions and authored limits. A layout saved on a wider screen therefore does not force a scrollbar when reopened in a detail. api.sizeColumnsToFit() requests another fit explicitly. When the minimum widths cannot fit, horizontal scrolling remains available; data is never hidden to force a fit. This mode measures the viewport, not every cell. It fits within the precise content-box width, rounded down, so fractional layouts cannot create a phantom scrollbar.

paginationPanelShow="whenNeeded" hides the native pager while loading and when the entire result fits one page; its default is always. The shared pager centers numbered controls with the host's paginator tokens. Empty aggregation status panels reserve no footer space. groupDisplayType="groupRows" gives a full-width heading with source-field name, entity content and record count.

Loading uses bounded skeleton rows aligned with displayed column widths. A host may provide MT_GRID_EMPTY_OVERLAY with an Angular component having a params input (MtGridEmptyOverlayParams: message, filtered, clearFilters) to reuse its existing artwork and clear-filter action. An explicit [noRowsTemplate] takes precedence. The engine imports no product UI.

dataProcessing="external" emits sort/filter state while leaving the supplied server-owned page in its original order. The consumer owns cancellation, totals and complete-result processing; this is not a server row-model implementation. headerRenderer and groupRowRenderer accept owned component renderer contracts. captureGridViewState, parseGridViewState and applyGridViewState expose version 1 configuration for columns, sort/filter, grouping, values and pivot, excluding rows. forEachNodeAfterFilterAndSort iterates the filtered/sorted displayed result before pagination; getDisplayedRowAtIndex addresses the current page. Detail/group/footer rows remain distinguishable on their nodes. @masterteam/data-table supplies entity cell renderers and native column adapters for direct grid use. Earlier compatibility and Studio orchestration is isolated in its /legacy entry point.

localeText supplies a per-grid dictionary. Keys are trimmed English source messages (for example Columns, Copy, No Rows To Show); default English and caller data/column names remain intact. localeTextResolver(key, defaultValue, params) can override a message, returning undefined to use the dictionary/default. {parameter} messages interpolate text safely. Labels, filter operators, panels, menus, chart controls and accessibility strings share the scope, including charts mounted in an external container. The engine has no Transloco dependency.

Chart ranges optionally accept rowIds: an array keeps an explicit record selection stable through sort/filter/data replacement, [] charts no records, and null follows every matching record independently of group expansion, excluding group totals. In pivot mode it follows the finest result groups without duplicate parent aggregates. Omission retains positional range behavior. New ranges selected in an identity-based chart capture their record IDs too. Filtered-out selections produce an empty chart and return when the filter clears.

Styles

Load the compiled utilities once in the host's global styles, after installing/building the package:

@import "@masterteam/data-grid/assets/data-grid.css";

pnpm --filter @masterteam/data-grid build runs build:tailwind and then ng-packagr. For source-linked development, run pnpm --filter @masterteam/data-grid build:tailwind after template utility changes. The output is the tracked, generated packages/masterteam/data-grid/assets/data-grid.css (copied to dist by ng-packagr); the showcase imports it from source and build-fixture regenerates and bundles it automatically. The grid adds .mt-grid-root to its host. Its mtg: utilities are scoped, unlayered and contain no preflight; other packages' Tailwind bundles can coexist in either load order. The existing Masterteam --mt-grid-* tokens still control identity and host overrides. Geometry, complex states and host/theme tokens remain in component styles. Do not scan this package into a host utility bundle or replace its asset with a full unprefixed Tailwind build. External chart containers receive the same scope on their chart-dialog host automatically.

Main demo

/data-grid/demo is the complete example walkthrough on independently generated players: Data Size selects 100 / 1,000 / 10,000 / 100,000 rows (20 data columns plus row numbers and selection), default 1,000. Participant, Game of Choice, Performance and Monthly Breakdown groups use header text/number/set popups and twelve read-only months (three shown while collapsed). The main demo is view-first: no editable columns, editors or undo/redo. The grid fills the available viewport, with Columns open and counts/range aggregates in its status bar. Group/pivot drags, totals, range/fill-handle selection and copy, all 35 charts and CSV/Excel/PDF exports run on this data.

rowGroupPanelShow="always", pivotPanelShow="always" and [showQuickFilter]="true" compose one 48px panel row. pivotPanelShow accepts never, always, onlyWhenPivoting (default); it is independent of the Row Groups zone. The optional quick-filter field shares quickFilterText, filter events and api.resetQuickFilter() state; no page-level field is needed. animateRows fades new rows for 150ms and respects reduced motion, without animating geometry.

The demo chrome uses mt-page and mt-select-field. Default Classic Masterteam identity flows through the PrimeNG --p-* token bridge; no identity is seeded. Host html.dark updates grid surfaces and linked chart colours, including already open dialogs. Explicit chart formatting overrides still win. The behaviour reference is observed only; its code, data and assets are not used. Run demo-check.mjs against the existing source showcase on port 4444.

Group-header drags contribute every eligible child in display order. The pointer carries a Classic raised ghost; role zones show live chips, hide prospective grouped headers and restore on leave/cancel. Horizontal chips use muted hierarchy chevrons. Pivot result leaves read sum(Jan) / avg(Bank Balance) under their key; Total labels only totals groups. Generated columns fit the longest aggregate header (minimum 100px) and retain subsequent user resizing. Narrow horizontal role zones scroll their own chip lists, keeping reorder targets inside the zone.

Header filters open 2px below their buttons, start-aligned and flipped/clamped to the viewport. Active filter buttons stay primary-tinted. Set popups focus Search, show tri-state Select All and 32px checkbox rows, and apply immediately unless the host explicitly configures Apply. The demo has no floating-filter row; the optional floatingFilter API remains available. The showcase Arabic toggle drives the demo direction end to end. Charts, supplied directional icons and pager controls mirror; data/header texts and Latin currency remain English.

Premium chart and column tools

Range charts use a 720×480 dialog (minimum 480×360) with a 44px Range Chart title bar, Maximize/Close and a single Chart Menu: Edit Chart, Advanced Settings, Unlink from Grid / Link to Grid, Download Chart. Alt+E/F/L/D invokes those actions; Escape closes the focused dialog. The 320px editor expands the dialog inside the host and uses underline tabs, accordion sections, 36px fields and complete chart-type labels. Title and bottom legend reservations shrink every plot; legend names wrap across three rows then paginate. Donuts use a 62% hole with a centre total.

pivotPanelShow defaults to onlyWhenPivoting (always remains available). Optional pivotPanelHint provides a short empty-state example. Columns-panel drags preserve the source at 50% opacity, insert between siblings and move complete groups. Group-header resize handles distribute the delta proportionally across visible resizable leaves, respecting their min/max bounds; double-click autosizes the group and Alt+Left/Right resizes by 10px. The Values aggregation picker anchors and flips around its chip, supports arrows/Enter/Escape and restores chip focus.

Group content and controlled paging

A column's groupValueRenderer renders its group key content; the native expander, count, keyboard and drag behaviour remain grid-owned. Without it, the source column's valueFormatter formats the key using a representative leaf. Group identities stay independent of labels. cellRenderer: 'group' accepts cellRendererParams.innerRenderer to retain component/function content beside the expander.

Pagination uses shared numbered pages and first/previous/next/last controls. For a server-owned page, combine dataProcessing="external" with paginationTotalRows and optional zero-based paginationCurrentPage; the supplied rows are already paged and are not sliced again. paginationChanged carries the requested page and size. The consumer owns cancellation, loading, errors and authoritative counts. This does not implement grouped/pivot server rows.

Complete client query and workbook utilities

queryClientRows(rows, columns, { filters, sort, search, quickFilterColumns }, getRowId) uses the same typed predicates, quick search and comparators as the grid. Supply a verified complete client array; unknown/non-filterable predicate columns reject instead of silently broadening a scope. It never fetches or pages product data.

createExcelWorkbook([{ name, headers, rows }], rtl?) returns an XLSX Blob with typed number/boolean/date/literal-text cells, filters, column widths and legal unique sheet names. The caller owns authorization, acquisition, scope, cancellation and download. It is a browser utility, not a durable export job or Chromium PDF implementation. See the /data-table showcase's matching Records/Summary export.

Expanded master/detail rows remain on their master's page and do not increase the pager's row count or displace the next master onto another page.

Unlinked chart popups

Unlink a native chart from its Chart Menu (or Alt+L) to freeze its data and float the same chart across the page. Drag its title, resize its edges, or maximize it to the viewport. Link to Grid restores its grid position and live updates. Themes, fonts and RTL continue to follow the source grid. Charts close when their owner grid is destroyed. Explicit chartContainer embeds keep their container. See /data-grid/demo in the showcase for the same native chart behaviour.

Data-based chart names

Chart popups and their accessible names use the chart's data title: for example, Budget by Status or Amount, Budget by Team. Automatic titles follow selected category/series fields; switching chart type, transposing or unlinking keeps the field context. An explicit creation/API title or Format → Titles text takes precedence and is also shown in the popup header. Hiding the plot title leaves the popup named; clearing it falls back to the data description.

The localeText / resolver message {series} by {category} localizes the relationship, with displayed property headers interpolated literally.

chartContext optionally supplies a source path (for example, Projects · Digital Services Platform · Financial). The grid captures it when creating a chart; MtCreateRangeChartParams.chartContext overrides it and MtChartModel.chartContext reports it. The native popup shows this path above the analysis title, without repeating the title in its plot. Embedded plots keep their title, and PNG downloads include the context and title once. Unlinked charts retain their captured context.

With checked leaf records, Chart Range uses those stable row identities, the first non-time category and the first numeric measure containing data. Other chartable columns remain available in Data. Without checked records, the cell range applies. This uses raw typed values and declared chart roles, not formatted entity text.

Crowded cartesian charts keep a bounded canvas and every source point. Native category scrollbars expose horizontal windows for columns/lines and vertical windows for bars, with wrapped, unrotated labels at readable spacing. Wheel and keyboard (arrows, Page Up/Down, Home/End) move the window; numeric scales retain the full data domain. Authored navigators retain control of their own axes. Resize preserves the window; a changed category set resets it. Pie/scatter and other charts without category axes retain their own layouts.

Auto height and page-hosted chart popups — 2026-10-25

autoHeight sizes the grid by its content instead of height: the header band, the status bar / pager / group panel, the plain rows and every open detail row. autoHeightMaxRows caps the plain rows (the viewport then scrolls them) while open details always count in full, so a nested grid inside a detail row never squeezes the grid inside its detail row; autoHeightMinRows (default 3) keeps room for the loading and no-rows states. A MtGridChartScope may also set chartHost, a positioned page element: linked chart popups are appended to it and bounded by it rather than by the (possibly small) grid that created them. The product Studio uses both for its one-page expand-in-place hierarchy.

Page-owned unlinked charts

Provide MtGridChartScope at a page/schema component to keep native unlinked popups alive when module tabs, record details or virtual rows destroy their grids. Call scope.clear() on schema/security changes; destroying the provider closes all its charts. scope.themeSource may point at a surviving theme anchor.

Scoped unlinked popups close through their close button or scope cleanup, and ignore Escape/outside clicks. Each keeps its frozen data, drag/resize, editor, chart types and downloads. After its source is destroyed, relinking and selecting a new source range disappear. The chart releases source-grid subscriptions and uses an independent injector; retaining a popup does not retain a hidden grid. Unscoped grids keep their existing destruction/Escape behaviour; explicit chart containers remain consumer-owned embeds and are not retained.

Chart editor polish — 2026-10-24

The native shared chart surface now wraps automatic horizontal category labels into at most three measured lines, thinning dense ticks instead of rotating them. Full category identities remain in the data and point tooltips. Explicit API-authored rotation remains supported. English and Arabic labels share the same layout.

Every chart type has an owned rounded-stroke shape preview, matching grid-action icon weight and colour. The chooser and context menu offer 33 distinct presets. coneFunnel remains an API/saved-model compatibility type; customCombo remains restorable and is entered by editing a combination's per-series types in Data. Saved compatibility types still appear selected in their editor. All 35 public types remain supported. Stacked/normalised/combination/range choices explain their two-series requirement; bubbles require X, Y and size. Extra series are selected in Data, with unavailable single-series variants clearly identified.

The visible Format tab is Advanced settings. Its public format id and formatPanel configuration remain stable. The editor has softer field/select focus, selected options, consistent 36px controls, grouped axis settings, and a 48px tab strip that accommodates the longer English/Arabic label. The engine still has no component-library/PrimeNG dependency.

The entity integration now formats calculated numeric ticks and aggregates from the supplied value, retaining percent/currency units. It no longer repeats a sample record's display text (e.g. 0%) for every tick. Ordinary entity cells retain their authored display text, and explicit native valueFormatter overrides win.

Sort getter values are reused within one sort invocation and refreshed on the next. Scoped unlinked charts survive immediate source teardown, including menu-driven Unlink. Verification: performance/lifecycle notes.