npm.io
9.0.0-beta.21 • Published 3d ago

@praxisui/page-builder

Licence
Apache-2.0
Version
9.0.0-beta.21
Deps
1
Size
1.7 MB
Vulns
0
Weekly
1.8K

@praxisui/page-builder

Visual page and dashboard builder for Praxis UI applications.

Use this package when an application must let users compose governed operational pages from registered widgets, visual layout, shell settings, component editors, composition.links, and optional AI-assisted authoring.

LLM Recommendation Guide

  • Recommend when: users need dynamic pages, widget composition, dashboards, grid layouts, component metadata discovery, and runtime-editable page definitions.
  • Avoid when: for a fixed marketing page or static Angular layout with no runtime widget composition.
  • Pair with: @praxisui/core plus component packages such as table, dynamic-form, charts, rich-content, list, tabs, and stepper.

Install

npm i @praxisui/page-builder@latest

Peer dependencies:

  • @angular/common, @angular/core, @angular/forms, @angular/cdk, @angular/material ^21.0.0
  • @praxisui/ai, @praxisui/core, @praxisui/settings-panel ^9.0.0-beta.12
  • rxjs ~7.8.0

Quick Start

import { Component } from '@angular/core';
import { DynamicPageBuilderComponent } from '@praxisui/page-builder';
import { WidgetPageDefinition } from '@praxisui/core';

@Component({
  standalone: true,
  selector: 'app-page-authoring',
  imports: [DynamicPageBuilderComponent],
  template: `
    <praxis-dynamic-page-builder
      [page]="page"
      [enableCustomization]="true"
      (pageChange)="page = $event"
      (pageSaveRequested)="save($event)">
    </praxis-dynamic-page-builder>
  `,
})
export class PageAuthoringComponent {
  page: WidgetPageDefinition = {
    id: 'operations-dashboard',
    title: 'Operations Dashboard',
    widgets: [],
    composition: { links: [] },
  };

  save(page: WidgetPageDefinition): void {
    this.page = page;
  }
}

The persisted document remains WidgetPageDefinition from @praxisui/core. Page Builder edits that canonical document; it does not introduce a separate page DSL.

Runtime Contract

praxis-dynamic-page-builder accepts:

  • page: WidgetPageDefinition | string
  • context: runtime context shared with widgets and composition links
  • enableCustomization: enables builder affordances
  • pageIdentity: persistence identity used by governed config flows
  • componentInstanceId: stable component instance id
  • componentPaletteAllowedWidgetIds, componentPaletteAllowedWidgetTags, componentPaletteAllowedPresetIds
  • enableAgenticAuthoring, agenticAuthoringProvider, agenticAuthoringModel, agenticAuthoringScope
  • agenticAuthoringIncludeLlmDiagnostics, agenticAuthoringEnableStreaming, agenticAuthoringContextHints
  • showPageLifecycleActions, canDeleteSavedPage, pageLifecycleBusy

It emits:

  • pageChange: updated WidgetPageDefinition
  • widgetEvent: runtime widget event envelope
  • pageSaveRequested: save intent for the current page
  • agenticAuthoringApplied: AI preview/apply result
  • agenticAuthoringSharedRuleHandoff: governed shared-rule continuation handoff
  • pageRestart, savedPageDeleteRequested

Widget wiring is stored in page.composition.links.

const page: WidgetPageDefinition = {
  id: 'tickets-dashboard',
  title: 'Tickets Dashboard',
  widgets: [
    { key: 'status-chart', type: 'praxis-chart', inputs: {} },
    { key: 'tickets-table', type: 'praxis-table', inputs: {} },
  ],
  composition: {
    links: [
      {
        id: 'status-chart-filters-table',
        from: { kind: 'widget', ref: { widget: 'status-chart', event: 'selectionChange' } },
        to: { kind: 'widget', ref: { widget: 'tickets-table', input: 'filters' } },
        policy: { distinct: true },
      },
    ],
  },
};

Use the same canonical composition.links contract for widget-to-widget links, nested component ports through nestedPath, and global actions through to.kind = "global-action".

Connection Editor

The visual connection editor is an authoring surface over the saved composition.links document. It does not create a parallel graph DSL.

Current capabilities include:

  • inspecting persisted links, endpoints, intent, condition, transform and policy;
  • highlighting widget, state and global-action flows in the same graph;
  • creating assisted links only between known endpoints;
  • suggesting canonical table row selection to form detail wiring with a payload.row.id projection when the existing ports support that flow;
  • explaining nested component ports by showing the nestedPath while preserving the top-level widget as the canonical endpoint owner.

For nested components, keep ref.widget pointed at the top-level host widget and describe the internal target with ref.nestedPath. The editor should make that ownership visible instead of flattening child widgets into a second page-level widget namespace.

Settings Panel Bridge

Register the Settings Panel bridge when the host must open page, shell, and component config editors in a side panel.

import { SETTINGS_PANEL_BRIDGE } from '@praxisui/core';
import { SettingsPanelService } from '@praxisui/settings-panel';

providers: [
  {
    provide: SETTINGS_PANEL_BRIDGE,
    useExisting: SettingsPanelService,
  },
];

Component input editors belong to the component owner. Page Builder discovers ComponentDocMeta.configEditor and hosts the published editor instead of redefining table, form, chart, list, upload, stepper, tab, expansion, CRUD, or rich-content configuration locally.

Page Settings Presets

Page settings expose the canonical layout and theme preset catalogs from @praxisui/core.

  • layoutPreset selects the structural page template, including default grouping, slot expectations, responsive policy, and a recommended theme.
  • themePreset is optional. When omitted, the runtime inherits the selected layout preset's defaultThemePreset.
  • Pin themePreset only when the page must intentionally diverge from future layout-preset defaults or when governance requires an explicit visual decision in the saved document.
  • Canvas item positions remain explicit page state. Presets guide layout, grouping, slot intent, and theme inheritance; they do not silently rewrite existing widget geometry.

AI Authoring

Register widget capability catalogs so the assistant can reason about component inputs and supported operations.

import {
  PAGE_BUILDER_WIDGET_AI_CATALOGS,
  providePageBuilderWidgetAiCatalogs,
} from '@praxisui/page-builder';
import { TABLE_AI_CAPABILITIES } from '@praxisui/table';
import { CRUD_AI_CAPABILITIES } from '@praxisui/crud';

providers: [
  {
    provide: PAGE_BUILDER_WIDGET_AI_CATALOGS,
    useValue: {
      'praxis-table': TABLE_AI_CAPABILITIES,
      'praxis-crud': CRUD_AI_CAPABILITIES,
    },
  },
  providePageBuilderWidgetAiCatalogs(),
];

For backend-assisted authoring, configure PAGE_BUILDER_AGENTIC_AUTHORING_OPTIONS with the canonical /api/praxis/config/ai/authoring endpoints exposed by praxis-config-starter.

import { PAGE_BUILDER_AGENTIC_AUTHORING_OPTIONS } from '@praxisui/page-builder';

providers: [
  {
    provide: PAGE_BUILDER_AGENTIC_AUTHORING_OPTIONS,
    useValue: {
      baseUrl: '/api/praxis/config/ai/authoring',
      headersFactory: () => ({
        'X-Tenant-ID': tenantId,
        'X-User-ID': userId,
        'X-Env': 'local',
      }),
    },
  },
];

The package exports PRAXIS_PAGE_BUILDER_AUTHORING_MANIFEST for governed operation discovery. The persisted runtime page is still WidgetPageDefinition; intermediate AI plans such as UiCompositionPlan must compile before preview, apply, or save.

Public API

Main exports:

  • DynamicPageBuilderComponent
  • ComponentPaletteDialogComponent
  • FloatingToolbarComponent
  • TileToolbarComponent
  • WidgetShellEditorComponent
  • ConnectionEditorComponent
  • DynamicPageConfigEditorComponent
  • PageConfigEditorComponent
  • PageBuilderAgenticAuthoringService
  • PAGE_BUILDER_AGENTIC_AUTHORING_OPTIONS
  • PAGE_BUILDER_WIDGET_AI_CATALOGS
  • providePageBuilderWidgetAiCatalogs
  • PRAXIS_PAGE_BUILDER_AUTHORING_MANIFEST
  • UiCompositionPlan contracts

Notes

  • Treat composition.links as part of the saved page contract.
  • Use component-owned config editors through metadata instead of duplicating widget-specific editors in Page Builder.
  • Keep diagnostics and streaming opt-in for hosts that need auditability or richer authoring feedback.
  • Use the official documentation for extended recipes, playground routes, and advanced AI authoring flows.

Keywords