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

@dynamic-widget/angular

v1.2.0

Published

Angular wrapper for Dynamic Widget.

Readme

@dynamic-widget/angular

Angular standalone component and injectable feature service for schema-driven forms and dashboards, built on @dynamic-widget/core. Editable tabs, validation, enterprise charts, rules engine, designer events, and visual schema designer (dw-schema-designer).

Current release: 1.2.0 — Depends on @dynamic-widget/core ^1.2.0. See monorepo CHANGELOG.

Live demo & docs: https://dynamic-widget-app.vercel.app/ — try the interactive demo, /designer, or read the Angular API guide.

What's new in 1.2.0

  • SchemaDesignerComponent (dw-schema-designer) — templates, undo/redo, import modal (merge/replace + diff), field-type modal, validation jump-to-field.
  • enterpriseLicenseKey, locale, dataProvider on schema designer for live preview.
  • Controlled [schema] + (schemaChange) preserves undo history (echo updates are not reapplied as external resets).

Ships as ESM TypeScript declarations. Works with Angular 18+ and 19 (@angular/core, @angular/common, @angular/forms). Import @dynamic-widget/themes CSS in angular.json or global styles.

Keywords: dynamic-widget angular standalone schema-driven forms dashboard i18n data-binding editable-tabs

Install

npm install @dynamic-widget/angular @dynamic-widget/themes
# Adds @dynamic-widget/core automatically.
# Peer deps: @angular/core ^18 || ^19, @angular/common ^18 || ^19, @angular/forms ^18 || ^19.
# Optional enterprise:
npm install @dynamic-widget/enterprise

Usage — component

// app.component.ts
import { Component } from "@angular/core";
import { DynamicWidgetComponent } from "@dynamic-widget/angular";
import type { WidgetSchema } from "@dynamic-widget/core";

@Component({
  selector: "app-root",
  standalone: true,
  imports: [DynamicWidgetComponent],
  template: `
    <dynamic-widget
      [schema]="schema"
      [values]="values"
      (valuesChange)="values = $event"
      (widgetEvent)="onWidgetEvent($event)"
      enterpriseLicenseKey=""
    />
  `,
})
export class AppComponent {
  values: Record<string, unknown> = {};
  schema: WidgetSchema = {
    widgets: [{ id: "email", type: "input", field: "email", label: "Email" }],
  };

  onWidgetEvent(event: unknown) {
    console.log(event);
  }
}

Add styles once in angular.json:

"styles": ["node_modules/@dynamic-widget/themes/dynamic-widget.css"]

Usage — i18n (language dropdown)

Bind a host <select> to locale; use labelKey and schema.locales on the schema:

<select [(ngModel)]="locale" aria-label="Language">
  <option value="en">English</option>
  <option value="fr">Français</option>
  <option value="ar">العربية</option>
</select>

<dynamic-widget [schema]="schema" [locale]="locale" [values]="values" (valuesChange)="values = $event" />

Guide: Internationalization · Demo: Locale / i18n scenario.

Usage — async binding

import { createFetchDataProvider } from "@dynamic-widget/core";

readonly dataProvider = createFetchDataProvider();
<dynamic-widget [schema]="schema" [dataProvider]="dataProvider" [values]="values" (valuesChange)="values = $event" />

Declare optionsFrom on select nodes; dependent lists use dependsOn and {field} URL tokens. Demo: Async binding on /demo.

Community widgets markdown and fileUpload need no extra inputs. Virtual tables use props.virtualize with an enterprise licence.

Usage — visual schema designer (dw-schema-designer)

Import themes (includes schema designer CSS when you use the main stylesheet):

@import "@dynamic-widget/themes/dynamic-widget.css";
import { Component, signal } from "@angular/core";
import { SchemaDesignerComponent } from "@dynamic-widget/angular";
import { createEmptySchema, createFetchDataProvider, type WidgetSchema, type WidgetValues } from "@dynamic-widget/core";

@Component({
  standalone: true,
  imports: [SchemaDesignerComponent],
  template: `
    <dw-schema-designer
      [schema]="schema()"
      (schemaChange)="schema.set($event)"
      [values]="values()"
      (valuesChange)="values.set($event)"
      [enterpriseLicenseKey]="licenseKey"
      [locale]="locale"
      [dataProvider]="dataProvider"
      previewTitle="Form preview"
    />
  `
})
export class FormBuilderPage {
  readonly schema = signal<WidgetSchema>(createEmptySchema("My form"));
  readonly values = signal<WidgetValues>({});
  readonly licenseKey = "";
  readonly locale = "en";
  readonly dataProvider = createFetchDataProvider();
}

| Input | Description | | --- | --- | | schema | Form schema (emit updates with schemaChange). | | values | Preview values (valuesChange). | | palette | Optional custom SchemaDesignerPaletteGroup[] (default: form fields + dashboard: metric, table, chart). | | readonly | Disable add/edit/remove/reorder. | | showJsonPanel | Show collapsible schema JSON (default true). | | embedded | Compact chrome for embeds (hides default title row). | | dark | Applies dark theme to designer shell and live preview. | | previewTitle | Preview panel heading (default "Form preview"). | | locale | Passed to inner <dynamic-widget> preview. | | dataProvider | Async optionsFrom in preview. | | enterpriseLicenseKey | Enables chart/plugin preview when licence modules allow. |

Toolbar includes templates, undo/redo, and import JSON (merge or replace with summary). Guide: Schema designer.

Live demo: /designer. For multi-tab dashboards with seven chart types and live chart editing in tab chrome, use editable tabs in the demo workbench (separate from the form schema designer; uses canDesigner).

Usage — service

Enterprise charting and AI helpers without mounting the full widget:

import { inject } from "@angular/core";
import { DynamicWidgetFeatureService } from "@dynamic-widget/angular";
import { syncEnterpriseLicenseFromKey } from "@dynamic-widget/angular";

// In a component or APP_INITIALIZER:
syncEnterpriseLicenseFromKey("YOUR-LICENSE-KEY");

const features = inject(DynamicWidgetFeatureService);
const insight = features.ai({ widgetType: "chart", context: "demo" });
const spec = features.charting.createChartSpec({ type: "bar", data: [] });

Re-exports all public symbols from @dynamic-widget/core (including createSchemaDesignerController for headless UIs).

Angular vs React naming

| Angular | React | | --- | --- | | SchemaDesignerComponent selector dw-schema-designer | SchemaDesigner | | (schemaChange) | onSchemaChange |

API

DynamicWidgetComponent inputs

| Input | Type | Description | | --- | --- | --- | | schema | WidgetSchema | Required. Root widget tree. | | locale | string | Active locale tag; resolves labelKey from schema.locales. | | dataProvider | DataProvider | Fetches JSON for optionsFrom (internal bindingCache per component). | | values | WidgetValues | Bound field values. | | dark | boolean | Dark theme. | | enterpriseLicenseKey | string | Activates @dynamic-widget/enterprise when valid. | | rules | WidgetRule[] | Rules engine definitions. | | aiInsightProvider | AiInsightProvider | Custom AI insight provider. | | tabsContentOnly | boolean | Preview mode: widgets only, no insert bar. |

DynamicWidgetComponent outputs

| Output | Type | Description | | --- | --- | --- | | valuesChange | WidgetValues | Emitted when form values change. | | widgetEvent | WidgetEventPayload | Tab designer and widget actions. | | enterpriseStatusChange | EnterpriseWidgetStatus | License and feature flags snapshot. |

DynamicWidgetFeatureService

| Member | Description | | --- | --- | | ai | createAiWidgetInsight from core | | charting | { createChartSpec, renderChartToSvg } |

License helpers

syncEnterpriseLicenseFromKey(key), isEnterpriseUnlocked() — thin wrappers over @dynamic-widget/enterprise.

Browser support

Requires a modern browser (see @dynamic-widget/core). The component renders client-side DOM via the shared renderer; use tabsContentOnly for read-only preview surfaces.

Angular SSR: only mount <dynamic-widget> in the browser (e.g. afterNextRender or *ngIf="isBrowser") because rendering uses document and HTMLElement.

Related packages

License

MIT