Skip to content
npm

Extensions overview ​

All customisation funnels through a single config type, INgxViewBuilderExtensionsConfig, registered either at bootstrap or at runtime.

Registering ​

At bootstrap (recommended):

ts
import { provideNgxViewBuilderExtensions } from '@ngxviewbuilder/runtime';

providers: [
  provideNgxViewBuilderExtensions({
    elements: [...],
    expressionFunctions: [...],
    svgIcons: {...},
  }),
]

The provider also accepts a factory (sync or async), which helps when the config comes from an API:

ts
provideNgxViewBuilderExtensions(async () => {
  const cfg = await fetch('/api/builder-config').then((r) => r.json());
  return { runtimeVariableContext: cfg.context, svgIcons: cfg.icons };
}),

At runtime:

ts
api.registerExtensions(config);
await api.registerExtensionsAsync(config);   // resolves icon directories etc.

Multiple provideNgxViewBuilderExtensions(...) calls compose; plugins use the same mechanism.

What the config can contain ​

KeyRegistersDetails
elementscustom element typesCustom elements
elementGroupsnew sidebar groupsid, label, icon, order
expressionFunctionsJEXL functionsCustom functions
globalPropertiesproperties added to every elementCustom properties
elementPropertiesper-type property overrides/additionsCustom properties
svgIcons / svgIconDirectory / svgIconDirectoriesicons by name / from asset foldersIcons
builderTabsextra builder tabsBuilding a plugin
featurePacksbundles of tabs + capabilitiesBuilding a plugin
runtimeVariables / runtimeVariableContextvariables for expressionsRuntime variables
uiDictionariesbuilder UI translationsUI translations
triggers / rules / process / fragmentsautomation definitionsconsumed by the automation plugins

Example: a project preset ​

ts
provideNgxViewBuilderExtensions({
  elementGroups: [{ code: 'acme', label: 'ACME widgets', icon: 'acmeLogo', order: 10 }],
  elements: [acmeCardElement, acmeRatingElement],
  expressionFunctions: [
    { name: 'vatAmount', args: ['net'], description: 'Adds 21% VAT',
      example: 'vatAmount({netPrice})',
      handler: (net: unknown) => Number(net || 0) * 1.21 },
  ],
  globalProperties: {
    trackingId: { label: 'Tracking ID', type: 'text', category: 'general' },
  },
  svgIcons: { acmeLogo: '<svg ...>...</svg>' },
  runtimeVariableContext: { brand: 'acme' },
});

Everything a creator then sees (the ACME group, the elements, the vatAmount() function, the extra property) comes from this one object.