Coming from ngx-formly? The migration guide maps
defaultProps,extends, and the formlyextensionsAPI to their ng-forge equivalents.
Configure global defaults for all forms at provider level, or per-form via defaultProps.
The Cascade
ng-forge applies props in priority order — more specific always wins:
withXxxFields({...})All formsdefaultPropsOne formpropsOne fieldCustom Adapter Config
Custom adapters define their own config interface. The cascade pattern works the same way — implement a config merger in your adapter to support library-level and form-level defaults. See Building an Adapter for a full guide.
Library-level (provider)
// Define your own config interface:
export interface MyAdapterConfig {
variant?: 'primary' | 'secondary';
size?: 'sm' | 'lg';
}
// Pass it to withCustomFields():
provideDynamicForm(
...withCustomFields({ variant: 'primary', size: 'sm' })
)Form-level (defaultProps)
Use (your form config type) from (your adapter package) for type-safe defaultProps with autocomplete.
// Define a typed FormConfig alias using your config:
import { FormConfig } from '@ng-forge/dynamic-forms';
import { MyAdapterConfig } from './my-adapter';
type MyFormConfig = FormConfig<any, any, MyAdapterConfig>;
const config = {
defaultProps: {
variant: 'secondary',
},
fields: [
{ type: 'my-input', key: 'name', label: 'Name' },
],
} as const satisfies MyFormConfig;Field-level Props
Each field type also accepts its own adapter-specific props. See Field Types for the full per-field reference.
Nullable values
Value fields accept an optional nullable?: boolean flag. When true:
valueacceptsnullin addition to the field's normal type (e.g.string | null).- An omitted
valueresolves tonullinstead of the type-specific empty default ('',NaN,[], …). nullablestays orthogonal torequired— they describe different layers.nullabledeclares that the model acceptsnull(data shape).requiredis a validation constraint. Angular'sValidators.requiredtreatsnullas invalid, so a field that is bothnullableandrequiredwill fail required-validation when the value isnull. The flags are independent OpenAPI concepts; combine them if that matches your schema, but understand the runtime interaction.
{
key: 'middleName',
type: 'input',
label: 'Middle Name',
nullable: true,
value: null, // allowed; also the resolved default when omitted
}Read-side caveat. A user clearing a text input reads back as "", not null — this is a DOM/Web IDL contract, identical to classic Reactive Forms. nullable is a contract for accepted values, not a guarantee of emitted ones. If your backend distinguishes null from empty string, handle the coercion at submission.
Next Steps
- Examples — Browse complete form examples
- Field Types — Per-field adapter props reference
- Building an Adapter — Build your own adapter