@mosaicoo/form-angular
v0.9.3
Published
Angular renderer for Mosaicoo Form: accessible, token-themable dynamic forms with wizard mode and host-provided dynamic options
Maintainers
Readme
@mosaicoo/form-angular
Angular renderer for Mosaicoo Form: renders dynamic forms at runtime from a schema (or any definition an importer understands), with validation, conditional visibility, repeatable rows, tabs and wizard mode — accessible by default and themable by CSS tokens.
import { FormRendererComponent } from '@mosaicoo/form-angular';
@Component({
imports: [FormRendererComponent],
template: `
<mform-renderer
[source]="definition"
[optionsProviders]="providers"
[messages]="ptBr"
(submitted)="onSubmitted($event)"
/>
`,
})
export class MyPage {}Highlights
- Standalone, signals, zoneless-ready — Angular 21+, OnPush throughout.
- Accessible by default — linked labels,
aria-required/invalid/ describedby,role=alerterrors, focus moves to the first invalid field on submit. - Wizard mode — schemas with
display: 'wizard'render top-level containers as steps; Next is blocked by per-step validation and submit jumps to the step owning the first error. - Dynamic options without scripts —
[optionsProviders]maps named providers to host functions (authenticated APIs, caching, tenant catalogs);refreshOnre-resolves when observed data changes. - Own look, host's brand — every style reads a
--mform-*CSS custom property with a built-in fallback. Define the tokens on any ancestor and the form adopts your design system; override[labels]and[messages]to localize.
Designer
Visual authoring ships as a separate entry point — apps that only render never load it:
import { FormDesignerComponent } from '@mosaicoo/form-angular/designer';<mform-designer [source]="definition" (schemaChanged)="save($event)" />Palette, canvas with selection, structure tree, property inspector,
undo/redo (Ctrl+Z/Y), duplicate/delete/move, live schema diagnostics,
import/export and a Preview mode with test data. The host owns persistence:
schemaChanged hands you the versioned schema document.
Custom types in the palette — register the component in the runtime and
contribute a palette entry; the Inspector edits its settings through the
props JSON editor, so a board, a map or a chart becomes a first-class field:
<mform-designer [extraCatalog]="[{
label: 'My components',
entries: [{ type: 'board', label: 'Board', icon: '▤', create: (schema) => ({
kind: 'input', key: generateKey(schema, 'board'), type: 'board',
dataType: 'object', props: { columns: ['To do', 'Doing', 'Done'] },
}) }],
}]" />Workspace — panels (Fields, Structure, Properties) dock left or right or hide, with presets and per-user persistence, like a professional IDE.
Drag and drop — drag palette entries onto the canvas, INTO containers and into individual columns; reorder nodes by dragging. Drop zones highlight the landing position and the columns map stays consistent automatically.
Localizable — every designer string comes from [labels] (partial
overrides fall back to English); translate the palette by passing your own
[catalog] (start from DEFAULT_CATALOG).
Resizable docks — drag the splitter between a panel rail and the canvas; widths persist with the layout.
Keyboard — Ctrl+Z/Y undo/redo, Ctrl+D duplicate, Del delete, Alt+↑/↓ move, Alt+→ nest into the container above, Alt+← move out of it, Esc clears the selection.
Responsive preview — preview at desktop, tablet or mobile width. Layout reacts to the FORM's own width (CSS container queries), so a form inside a narrow drawer stacks its columns even on a wide screen.
Reusable blocks — save any subtree as a named block and drop it into other
forms (keys are regenerated). Blocks persist locally by default; bind
[blocks] / (blocksChanged) to store them wherever your platform keeps
shared assets.
The canvas renders leaves with the RUNTIME components and the runtime theme, so what you design is exactly what your users get.
Material Design 3 adapter
Optional entry point (requires @angular/material, an optional peer):
import { provideMaterialForms } from '@mosaicoo/form-angular/material';
bootstrapApplication(App, { providers: [provideMaterialForms()] });Swaps text/number/select/checkbox/radio (and friends) for Material
components styled by YOUR M3 theme; unmapped types keep the accessible
built-in renderers. Individual types can still be overridden by later
provideMosaicooForm({components}) calls.
Extending
// Register custom field components and your HTTP transport once:
bootstrapApplication(App, {
providers: [
provideMosaicooForm({
components: { signature: SignatureFieldComponent }, // new or overridden types
remoteFetcher: (url) => api.get(url), // auth/caching stay yours
}),
],
});A registered component receives field, engine, path and tick as signal
inputs and talks to the form exclusively through the engine
(engine.getValue/setValue/markTouched) — validation, conditional visibility
and events keep working with no extra wiring.
Theming example
:root {
--mform-primary: #0f766e;
--mform-radius: 2px;
--mform-font: Georgia, serif;
}