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

tsgrid-ui

v3.3.2

Published

TypeScript-native UI components: data grid, forms, fields, layout, sidebar, tabs, toolbar, popup, tooltip. ESM + CJS dual bundle, .d.ts rollup, zero runtime dependencies.

Readme

TsGrid UI

TypeScript-native UI component library: data grid, forms, fields, layout, sidebar, tabs, toolbar, popup, tooltip. Strict-mode TypeScript port of the venerable w2ui v2.0 codebase, with modern tooling, zero runtime dependencies, and full .d.ts declarations.

This is a hard fork of w2ui by Vit Malina. See Acknowledgments below.

npm version license

v3.0 is a MAJOR release. The flat tsgrid-ui barrel (import { TsGrid } from 'tsgrid-ui'), the IIFE bundle (dist/tsgrid-ui.js), and the .tsg-icon-{name} CSS background-image rules are removed. Migrate to per-widget subpath imports and tsgrid-ui/icons functions. See MIGRATION_v3.md for the full guide.

Install

pnpm add tsgrid-ui
# or: npm install tsgrid-ui
# or: yarn add tsgrid-ui

Quick start

import { TsGrid } from 'tsgrid-ui/grid'
import 'tsgrid-ui/css'

const grid = new TsGrid({
    name: 'mygrid',
    columns: [
        { field: 'name',  text: 'Name',  size: '50%' },
        { field: 'email', text: 'Email', size: '50%' }
    ],
    records: [
        { recid: 1, name: 'Ada Lovelace',     email: '[email protected]' },
        { recid: 2, name: 'Alan Turing',      email: '[email protected]' },
        { recid: 3, name: 'Grace Hopper',     email: '[email protected]' }
    ]
})
grid.render('#mygrid')
<div id="mygrid" style="width: 600px; height: 300px;"></div>

Icons

v3.0 ships 18 named icon functions via tsgrid-ui/icons:

import { checkIcon, crossIcon, searchIcon } from 'tsgrid-ui/icons'

// Basic use (decorative — aria-hidden="true" emitted automatically)
const html = `<span class="tsg-icon">${searchIcon()}</span>`

// Interactive use — pass label for accessibility
const closeBtn = `<button>${crossIcon({ label: 'Close dialog' })}</button>`

// Custom size
const bigCheck = checkIcon({ size: 24, label: 'Confirmed' })

All icons use fill="currentColor" — set color: on the parent to theme them. See MIGRATION_v3.md#v300--icon-api for the full 18-icon table.

CommonJS Usage

Starting in v2.13.0, all 12 JS subpath exports support require() in Node.js CJS modules.

// CJS subpath import — Node.js only
const { TsGrid }    = require('tsgrid-ui/grid')
const { TsForm }    = require('tsgrid-ui/form')
const { TsField }   = require('tsgrid-ui/field')
const { TsLocale }  = require('tsgrid-ui/locale')
const { TsUtils }   = require('tsgrid-ui/utils')
// ... all 12 subpaths available

ESM equivalent (preferred — use ESM whenever your environment supports it):

import { TsGrid }   from 'tsgrid-ui/grid'
import { TsForm }   from 'tsgrid-ui/form'
import { TsField }  from 'tsgrid-ui/field'
import { TsLocale } from 'tsgrid-ui/locale'
import { TsUtils }  from 'tsgrid-ui/utils'

CJS subpath imports are Node.js only. Browser consumers should use <script type="module"> with subpath ESM imports — the IIFE monolith (dist/tsgrid-ui.min.js) is removed in v3.0. See MIGRATION_v3.md#v300--iife-globals for the browser migration guide. For multi-subpath CJS consumers, note that each subpath file inlines all its dependencies because splitting: false is required for CJS output.

Pure-Node consumers must provide a DOM environment (jsdom / happy-dom or equivalent stubs) before the require() call resolves — tsgrid-ui references document, window, Node, Event, MutationObserver, navigator, localStorage, and self at module-load time because it targets browsers as its primary runtime. Calling require('tsgrid-ui/grid') in a bare Node process without these polyfills throws at load. See CHANGELOG v2.13.0 Known Limitations for the full list and test/consumer-smoke-cjs.js for a working stub example.

Per-component CSS

Starting in v2.12.0, individual per-widget CSS subpaths are available. There are two import patterns:

Monolith (recommended for most consumers)

import 'tsgrid-ui/css'  // ~700 KB — all widgets + fonts in one import

Use this when you render multiple widgets on the same page and want simplicity. One import, all styles.

Per-widget (granular cache control)

import 'tsgrid-ui/grid.css'     // 56 KB — grid styles only
import 'tsgrid-ui/form.css'     // 32 KB — form styles only
import 'tsgrid-ui/tooltip.css'  // 47 KB
import 'tsgrid-ui/popup.css'    // 15 KB
import 'tsgrid-ui/sidebar.css'  // 15 KB
import 'tsgrid-ui/tabs.css'     // 27 KB
import 'tsgrid-ui/toolbar.css'  // 30 KB
import 'tsgrid-ui/layout.css'   // 26 KB
import 'tsgrid-ui/field.css'    // 31 KB

Use this when you import only a subset of widgets and want CSS cache granularity — each widget's styles are cached independently, so a change to the grid style does not invalidate the form cache.

Note: per-widget CSS files do NOT include the OpenSans text font embedded in the monolith. If you use ONLY per-widget CSS imports, text rendering may differ from the monolith. To fix: also import tsgrid-ui/css, or provide OpenSans via a CDN or your own font pipeline.

Icon rendering (v3.0+) is handled via inline SVG strings from tsgrid-ui/icons — not CSS background-image rules — so per-widget CSS files have no icon font dependency.

Components

| Class | Purpose | |-------------|------------------------------------------------| | TsGrid | Data grid with sort / search / select / edit | | TsForm | Form with field validation + submit lifecycle | | TsField | Standalone field types (text/list/date/color/file) | | TsLayout | 6-panel resizable layout | | TsSidebar | Tree / sidebar with expandable nodes | | TsTabs | Tab strip | | TsToolbar | Toolbar with multiple item types | | TsTooltip | Hover tooltips and overlays | | TsPopup | Modal popup, alert, confirm, prompt |

Helpers exported: TsAlert, TsConfirm, TsPrompt, TsColor, TsDate, TsMenu, TsDialog, TsUtils, TsLocale, TsBase, TsEvent, TsUi (instance registry), query (DOM helper), plus branded primitive types RecId, LayoutPanelId, FieldName.

TypeScript support

Full type declarations ship in dist/w2ui.d.ts (will be renamed to dist/tsgrid-ui.d.ts once the build artifacts are rebuilt — see CHANGELOG). Strict mode is active in source: strict, noUncheckedIndexedAccess, exactOptionalPropertyTypes, noImplicitOverride, noPropertyAccessFromIndexSignature.

import { TsGrid, type TsGridColumn, type TsGridCellSelection } from 'tsgrid-ui'

const cols: TsGridColumn[] = [
    { field: 'name', text: 'Name', sortable: true }
]

Building

pnpm install
pnpm build       # CSS (gulp) + JS (tsup) + .d.ts rollup
pnpm verify      # lint + typecheck + consumer-smoke + unit tests + Playwright smoke

| Script | Purpose | |----------------------|-----------------------------------------------------| | pnpm test | ESLint + tsc --noEmit | | pnpm test:unit | Vitest unit suite (w2utils helpers, w2base events, types brands) | | pnpm consumer-smoke| Typecheck the public API surface as a consumer would | | pnpm smoke | Playwright DOM smoke harness (38 tests) | | pnpm verify | All of the above, end-to-end | | pnpm dev | tsup watch mode for JS bundle | | pnpm start | Local dev server (Python http.server) on :3500 |

Maintainers: see RELEASING.md for the manual release workflow.

Migration from w2ui

If you're coming from w2ui v2.0 or v2.1, see MIGRATION-FROM-W2UI.md for the complete renaming map (JS globals, CSS classes, file paths, jQuery shim removal).

Acknowledgments

TsGrid UI is a hard fork of w2ui by Vit Malina (@vitmalina). The original w2ui (MIT-licensed, started in 2014) was the foundation for this project — every widget pattern, every interaction model, and most of the architectural decisions originate there. This fork's contribution is:

  • A full TypeScript-native port (the original was JS with optional types).
  • Modern tsup / esbuild build pipeline replacing the original Gulp-based regex concat.
  • Zero runtime dependencies — the jQuery shim (w2compat) was removed.
  • Vitest unit test layer alongside the original Playwright smoke harness.
  • Renamed identity at every layer (package, globals, classes, types, CSS classes) to operate as an independent library while preserving the original's MIT copyright per license terms.

If you need the original library, please use vitmalina/w2ui.

License

MIT — preserves the original w2ui copyright (2014, Vit Malina) and adds the fork copyright (2026, DaverSoGT). You are free to use, modify, and redistribute under MIT terms.