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

ngx-manifold-material

v0.1.0

Published

Angular Material widgets for Manifold: a ready-made registry so a layout document can compose Material components without writing a wrapper first.

Readme

ngx-manifold-material

Angular Material as Manifold widgets: a registry a layout document can use straight away.

Manifold renders pages from JSON documents, and a document may only name widgets that are in the registry. This package is that registry, filled in — the whole Material component set, so a page is something you compose in JSON rather than something you write wrappers for first.

npm install ngx-manifold ngx-manifold-material @angular/material @angular/cdk
import { provideManifold } from 'ngx-manifold';
import { materialWidgets } from 'ngx-manifold-material';

provideManifold({ widgets: materialWidgets });

A registry is a default, not a law. Spread it, drop what you do not want, add your own:

provideManifold({ widgets: { ...materialWidgets, badge: myBadge } });

What is in it

Thirty-two widgets, covering every component in the Material set.

| Group | Widgets | | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Data | matTable (sorting and paging built in), matList, matTree, matChips | | Layout | matCard, matToolbar, matTabs, matExpansion, matGridList, matSidenav, matStepper | | Actions | matButton, matIconButton, matMenu, matDialog, matBottomSheet, matRipple | | Forms | matForm, matInput, matSelect, matAutocomplete, matCheckbox, matRadio, matSlideToggle, matSlider, matDatepicker, matTimepicker, matButtonToggle | | Small things | matIcon, matDivider, matProgressBar, matProgressSpinner |

Five Material features are not widgets, because they are not components you compose:

  • Paginator and sort header are inputs on matTable (pageSize, sortable).
  • Tooltip and badge are directives, so they are inputs on the widgets that carry them (tooltip, badge on buttons and icons).
  • Snackbar is the result of something happening, so it ships as an action rather than a node — see below.
  • Form field is the frame around a control, so every control brings its own: label, hint and appearance are inputs on each.
  • Core is theming and ripples: mat.theme() in your stylesheet, and matRipple as a widget.

Every widget is a separate entry point (ngx-manifold-material/table and so on) and the registry loads it with a dynamic import, so a widget no document names is never sent to the browser.

Forms

A binding is a path reader$.user.email fills a field and nothing more. What the reader types lives in a form state that matForm owns and provides, and leaves only when an action is handed the whole collection:

{
  "type": "matForm",
  "inputs": { "submitLabel": "Save" },
  "outputs": { "submitted": "saveVisit" },
  "children": [
    { "type": "matInput", "inputs": { "name": "contact", "label": "Contact", "required": true } },
    { "type": "matCheckbox", "inputs": { "name": "followUp", "label": "Needs a follow-up" } }
  ]
}

The document says which fields exist and which action receives them; what happens to the values is application code, like every other action. Submission is blocked while a required field is empty, and the form says which ones. A control removed by a when condition releases its field, so a page never becomes unsubmittable over something nobody can see.

Dates cross as YYYY-MM-DD and times as HH:mm, because a document is JSON and JSON has no Date. The pickers read in the tenant's locale, so the same field shows 12/03/2026 for one company and 12.3.2026 for another.

Actions

import { materialActions } from 'ngx-manifold-material/actions';

const actions = { ...materialActions(), openPage: /* yours */ };

notify opens a snackbar. Payload is a string, or { message, action?, duration? }.

Theming

The widgets carry no colours of their own. They read Material's --mat-sys-* tokens, which is what Manifold's TenantTheming writes — so a company's palette reaches the Material components through the same mechanism that themes everything else, and switching tenant recolours them with it.

Licence

MIT.