Skip to content

API: Forms and infolists

Public TypeScript declarations verified against the package export entries.

This reference is generated before development, checking and building from declarations reachable through the package’s published entry points, following re-exports. Internal source-module exports are omitted. Types shown together share their source module; follow the source link for imports and implementation. Use the guides for examples and runtime behavior.

src/definition/schema.ts

Source

export type SchemaKind = 'extensionField' | 'extensionEntry' | 'text' | 'email' | 'password' | 'slider' | 'number' | 'textarea' | 'hidden' | 'select' | 'multiSelect' | 'checkbox' | 'checkboxList' | 'radio' | 'toggle' | 'toggleButtons' | 'date' | 'dateTime' | 'time' | 'color' | 'tags' | 'keyValue' | 'markdownEditor' | 'codeEditor' | 'richEditor' | 'fileUpload' | 'builder' | 'repeater' | 'grid' | 'section' | 'fieldset' | 'tabs' | 'tab' | 'group' | 'split' | 'placeholder' | 'html' | 'divider' | 'view' | 'fragment' | 'textEntry' | 'iconEntry' | 'imageEntry' | 'colorEntry' | 'keyValueEntry' | 'repeatableEntry' | 'codeEntry' | 'wizard' | 'step' | 'badgeEntry';

export type ValidationRules = {
    required?: boolean;
    nullable?: boolean;
    minLength?: number;
    maxLength?: number;
    min?: number;
    max?: number;
    step?: number;
    email?: boolean;
    url?: boolean;
    regex?: RegExp | string;
    alpha?: boolean;
    alphaNumeric?: boolean;
    in?: readonly unknown[];
    same?: string;
    different?: string;
    confirmed?: boolean;
    unique?: {
        table?: string;
        column?: string;
        ignoreRecord?: boolean;
    };
    exists?: {
        table: string;
        column: string;
    };
    custom?: readonly unknown[];
};

export type FieldCommon = {
    label?: string | null | FieldClosure<string | null>;
    helperText?: string | null;
    hint?: string | null;
    hintIcon?: string;
    hintTooltip?: string;
    hintColor?: string;
    hintAction?: ActionDefinition;
    placeholder?: string | null;
    default?: unknown | (() => unknown);
    disabled?: boolean | FieldClosure<boolean>;
    readOnly?: boolean;
    visible?: FieldClosure<boolean>;
    hidden?: FieldClosure<boolean>;
    columnSpan?: number | 'full';
    extraAttributes?: Record<string, string>;
    live?: {
        onBlur?: boolean;
        debounce?: number;
        server?: boolean;
    } | true;
    afterStateUpdated?: (args: {
        state: unknown;
        old: unknown;
        get(path: string): any;
        set(path: string, value: unknown): void;
        record?: Record<string, unknown> | null;
        ctx?: HttpContext;
    }) => unknown;
    dehydrated?: boolean;
    dehydratedWhenHidden?: boolean;
    format?: ((record: Record<string, unknown>) => unknown) | 'hex' | 'rgb' | 'hsl';
    dehydrate?: (state: unknown) => unknown;
    rules?: ValidationRules;
};

export type FieldDefinition<K extends SchemaKind, P extends object = object> = FieldCommon & P & {
    kind: K;
    name: string;
};

export type FieldDefinitionUnion = ExtensionFieldDefinition | TextFieldDefinition | NumberFieldDefinition | SliderFieldDefinition | TextareaFieldDefinition | SelectFieldDefinition | CheckboxFieldDefinition | CheckboxListFieldDefinition | RadioFieldDefinition | ToggleFieldDefinition | ToggleButtonsFieldDefinition | DateFieldDefinition | ColorFieldDefinition | TagsFieldDefinition | KeyValueFieldDefinition | MarkdownEditorFieldDefinition | CodeEditorFieldDefinition | RichEditorFieldDefinition | FileUploadFieldDefinition | RepeaterFieldDefinition | BuilderFieldDefinition | HiddenFieldDefinition;

export type LayoutDefinition = WizardDefinition | WizardStepDefinition | {
    kind: 'grid';
    children: SchemaNodeDefinition[];
    columns?: number | Record<string, number>;
    gap?: number;
    visible?: FieldClosure<boolean>;
    hidden?: FieldClosure<boolean>;
    columnSpan?: number | 'full';
    extraAttributes?: Record<string, string>;
} | {
    kind: 'section';
    children: SchemaNodeDefinition[];
    heading?: string;
    description?: string;
    icon?: string;
    collapsible?: boolean;
    collapsed?: boolean;
    aside?: boolean;
    compact?: boolean;
    columns?: number | Record<string, number>;
    visible?: FieldClosure<boolean>;
    hidden?: FieldClosure<boolean>;
    columnSpan?: number | 'full';
    extraAttributes?: Record<string, string>;
} | {
    kind: 'fieldset';
    children: SchemaNodeDefinition[];
    label?: string;
    columns?: number | Record<string, number>;
    visible?: FieldClosure<boolean>;
    hidden?: FieldClosure<boolean>;
    columnSpan?: number | 'full';
    extraAttributes?: Record<string, string>;
} | {
    kind: 'tabs';
    children: SchemaNodeDefinition[];
    visible?: FieldClosure<boolean>;
    hidden?: FieldClosure<boolean>;
    columnSpan?: number | 'full';
    extraAttributes?: Record<string, string>;
} | {
    kind: 'tab';
    name: string;
    children: SchemaNodeDefinition[];
    visible?: FieldClosure<boolean>;
    hidden?: FieldClosure<boolean>;
    columnSpan?: number | 'full';
    extraAttributes?: Record<string, string>;
} | {
    kind: 'group';
    name?: string;
    children: SchemaNodeDefinition[];
    visible?: FieldClosure<boolean>;
    hidden?: FieldClosure<boolean>;
    columnSpan?: number | 'full';
    extraAttributes?: Record<string, string>;
} | {
    kind: 'fragment';
    children: SchemaNodeDefinition[];
    visible?: FieldClosure<boolean>;
    hidden?: FieldClosure<boolean>;
    columnSpan?: number | 'full';
    extraAttributes?: Record<string, string>;
} | {
    kind: 'split';
    children: SchemaNodeDefinition[];
    columns?: number | Record<string, number>;
    visible?: FieldClosure<boolean>;
    hidden?: FieldClosure<boolean>;
    columnSpan?: number | 'full';
    extraAttributes?: Record<string, string>;
} | {
    kind: 'placeholder';
    name: string;
    label?: string;
    content?: unknown | FieldClosure;
    visible?: FieldClosure<boolean>;
    hidden?: FieldClosure<boolean>;
    columnSpan?: number | 'full';
    extraAttributes?: Record<string, string>;
} | {
    kind: 'html';
    content?: string | FieldClosure<string>;
    visible?: FieldClosure<boolean>;
    hidden?: FieldClosure<boolean>;
    columnSpan?: number | 'full';
    extraAttributes?: Record<string, string>;
} | {
    kind: 'divider';
    visible?: FieldClosure<boolean>;
    hidden?: FieldClosure<boolean>;
    columnSpan?: number | 'full';
    extraAttributes?: Record<string, string>;
} | {
    kind: 'view';
    component: string;
    props?: Record<string, unknown>;
    visible?: FieldClosure<boolean>;
    hidden?: FieldClosure<boolean>;
    columnSpan?: number | 'full';
    extraAttributes?: Record<string, string>;
};

export type EntryDefinition = ExtensionEntryDefinition | TextEntryDefinition | IconEntryDefinition | ImageEntryDefinition | ColorEntryDefinition | KeyValueEntryDefinition | RepeatableEntryDefinition | CodeEntryDefinition | BadgeEntryDefinition;

export type SchemaNodeDefinition = FieldDefinitionUnion | LayoutDefinition | EntryDefinition;

export type SchemaComponent = SchemaNodeBuilder;

export type ComponentDefinition = SchemaNodeDefinition;

export interface TextBuilder extends FieldBuilderBase<TextFieldDefinition> {
    prefix(value: string): this;
    suffix(value: string): this;
    mask(value: string): this;
    prefixAction(value: ActionDefinition | ActionBuilder): this;
    suffixAction(value: ActionDefinition | ActionBuilder): this;
    autocomplete(value: string): this;
    datalist(value: readonly string[]): this;
    minLength(value: number): this;
    maxLength(value: number): this;
    regex(value: RegExp | string): this;
    alpha(): this;
    alphaNumeric(): this;
    email(): this;
    url(): this;
    tel(): this;
    telRegex(value: RegExp | string): this;
    in(value: readonly unknown[]): this;
    same(field: string): this;
    different(field: string): this;
    confirmed(): this;
    unique(value?: NonNullable<ValidationRules['unique']>): this;
    exists(value: NonNullable<ValidationRules['exists']>): this;
}

export interface PasswordBuilder extends TextBuilder {
    revealable(value?: boolean): this;
}

export interface NumberBuilder extends FieldBuilderBase<NumberFieldDefinition> {
    min(value: number): this;
    max(value: number): this;
    step(value: number): this;
    prefix(value: string): this;
    suffix(value: string): this;
    unique(value?: NonNullable<ValidationRules['unique']>): this;
}

export interface TextareaBuilder extends FieldBuilderBase<TextareaFieldDefinition> {
    rows(value: number): this;
    minLength(value: number): this;
    maxLength(value: number): this;
    autosize(value?: boolean): this;
}

export interface SelectBuilder extends FieldBuilderBase<Extract<SelectFieldDefinition, {
    kind: 'select';
}>> {
    options(value: SelectOptions | ((args: SelectOptionsContext) => unknown | Promise<unknown>)): this;
    relationship(name: string, titleColumn: string, scope?: RelationshipOptions['scope']): this;
    searchable(columns?: readonly string[]): this;
    preload(value?: boolean): this;
    getOptionLabelUsing(callback: NonNullable<Extract<SelectFieldDefinition, {
        kind: 'select';
    }>['getOptionLabelUsing']>): this;
    createOptionForm(value: readonly SchemaNodeBuilder[]): this;
    createOptionUsing(callback: NonNullable<Extract<SelectFieldDefinition, {
        kind: 'select';
    }>['createOptionUsing']>): this;
    prefixAction(value: ActionDefinition | ActionBuilder): this;
    suffixAction(value: ActionDefinition | ActionBuilder): this;
    clearable(value?: boolean): this;
    multiple(value?: boolean): this;
    in(value: readonly unknown[]): this;
    exists(value: NonNullable<ValidationRules['exists']>): this;
}

export interface MultiSelectBuilder extends FieldBuilderBase<Extract<SelectFieldDefinition, {
    kind: 'multiSelect';
}>> {
    options(value: SelectOptions | ((args: SelectOptionsContext) => unknown | Promise<unknown>)): this;
    relationship(name: string, titleColumn: string, scope?: RelationshipOptions['scope']): this;
    searchable(columns?: readonly string[]): this;
    preload(value?: boolean): this;
    getOptionLabelUsing(callback: NonNullable<Extract<SelectFieldDefinition, {
        kind: 'multiSelect';
    }>['getOptionLabelUsing']>): this;
    createOptionForm(value: readonly SchemaNodeBuilder[]): this;
    createOptionUsing(callback: NonNullable<Extract<SelectFieldDefinition, {
        kind: 'multiSelect';
    }>['createOptionUsing']>): this;
    prefixAction(value: ActionDefinition | ActionBuilder): this;
    suffixAction(value: ActionDefinition | ActionBuilder): this;
    clearable(value?: boolean): this;
    in(value: readonly unknown[]): this;
    exists(value: NonNullable<ValidationRules['exists']>): this;
}

export interface DateBuilder extends FieldBuilderBase<DateFieldDefinition> {
    minDate(value: string): this;
    maxDate(value: string): this;
    timezone(value: string): this;
    seconds(value?: boolean): this;
}

export interface RepeaterBuilder extends FieldBuilderBase<RepeaterFieldDefinition> {
    schema(value: readonly SchemaNodeBuilder[] | ((repeater: SchemaNamespace) => readonly SchemaNodeBuilder[])): this;
    table(columns?: readonly RepeaterTableColumnBuilder[]): this;
    minItems(value: number): this;
    maxItems(value: number): this;
    reorderable(value?: boolean): this;
    collapsible(value?: boolean): this;
    collapsed(value?: boolean): this;
    cloneable(value?: boolean): this;
    addLabel(value: string): this;
    itemLabel(value: string | FieldClosure<string>): this;
    defaultItems(value: number): this;
    relationship(name: string, options?: Omit<RepeaterRelationshipOptions, 'name'>): this;
    grid(columns: number | Record<string, number>): this;
}

export interface FileUploadBuilder extends FieldBuilderBase<FileUploadFieldDefinition> {
    disk(value: string): this;
    image(value?: boolean): this;
    maxSize(value: number | `${number}kb` | `${number}mb`): this;
    multiple(value?: boolean): this;
    maxFiles(value: number): this;
    accept(value: string | readonly string[]): this;
    directory(value: string): this;
    visibility(value: 'public' | 'private'): this;
    reorderable(value?: boolean): this;
    imageEditor(value?: boolean): this;
    imageEditorAspectRatios(value: readonly (string | null)[]): this;
    downloadable(value?: boolean): this;
    previewable(value?: boolean): this;
}

export interface RichEditorBuilder extends FieldBuilderBase<RichEditorFieldDefinition> {
    mergeTags(value: readonly string[] | Record<string, string>): this;
    mentions(value: readonly (MentionProviderBuilder | MentionProviderDefinition)[]): this;
    customBlocks(value: readonly (RichBlockBuilder | RichBlockDefinition)[]): this;
    toolbar(value: readonly string[]): this;
    minHeight(value: number): this;
    maxHeight(value: number): this;
    fileAttachmentsDisk(value: string): this;
    fileAttachmentsDirectory(value: string): this;
}

export interface CheckboxBuilder extends FieldBuilderBase<CheckboxFieldDefinition> {
    inline(value?: boolean): this;
}

export interface CheckboxListBuilder extends FieldBuilderBase<CheckboxListFieldDefinition> {
    options(value: Record<string, unknown> | readonly unknown[]): this;
    columns(value: number): this;
}

export interface RadioBuilder extends FieldBuilderBase<RadioFieldDefinition> {
    options(value: Record<string, unknown> | readonly unknown[]): this;
    descriptions(value: Record<string, string>): this;
    inline(value?: boolean): this;
}

export interface ToggleBuilder extends FieldBuilderBase<ToggleFieldDefinition> {
    onIcon(value: string): this;
    offIcon(value: string): this;
    onColor(value: string): this;
    offColor(value: string): this;
    inline(value?: boolean): this;
}

export interface ToggleButtonsBuilder extends FieldBuilderBase<ToggleButtonsFieldDefinition> {
    options(value: Record<string, unknown> | readonly unknown[]): this;
    multiple(value?: boolean): this;
    grouped(value?: boolean): this;
    icons(value: Record<string, string>): this;
    colors(value: Record<string, string>): this;
}

export interface ColorBuilder extends Omit<FieldBuilderBase<ColorFieldDefinition>, 'format'> {
    presets(value: readonly string[]): this;
}

export interface TagsBuilder extends FieldBuilderBase<TagsFieldDefinition> {
    suggestions(value: readonly string[]): this;
    separator(value: string): this;
    maxTags(value: number): this;
    reorderable(value?: boolean): this;
}

export interface KeyValueBuilder extends FieldBuilderBase<KeyValueFieldDefinition> {
    keyLabel(value: string): this;
    valueLabel(value: string): this;
    addable(value?: boolean): this;
    deletable(value?: boolean): this;
    reorderable(value?: boolean): this;
    keyPlaceholder(value: string): this;
    valuePlaceholder(value: string): this;
}

export interface LayoutBase<D extends LayoutDefinition> extends ComponentBuilder<D> {
    visible(value: FieldClosure<boolean>): this;
    hidden(value: FieldClosure<boolean>): this;
    columnSpan(value: number | 'full'): this;
    extraAttributes(value: Record<string, string>): this;
}

export interface GridBuilder extends LayoutBase<Extract<LayoutDefinition, {
    kind: 'grid';
}>> {
    components(value: readonly SchemaNodeBuilder[]): this;
    columns(value: number | Record<string, number>): this;
    gap(value: number): this;
}

export interface SectionBuilder extends LayoutBase<Extract<LayoutDefinition, {
    kind: 'section';
}>> {
    components(value: readonly SchemaNodeBuilder[]): this;
    heading(value: string): this;
    description(value: string): this;
    icon(value: string): this;
    collapsible(value?: boolean): this;
    collapsed(value?: boolean): this;
    aside(value?: boolean): this;
    compact(value?: boolean): this;
    columns(value: number | Record<string, number>): this;
}

export interface FieldsetBuilder extends LayoutBase<Extract<LayoutDefinition, {
    kind: 'fieldset';
}>> {
    components(value: readonly SchemaNodeBuilder[]): this;
    label(value: string): this;
    columns(value: number | Record<string, number>): this;
}

export interface ChildrenLayoutBuilder extends LayoutBase<Extract<LayoutDefinition, {
    kind: 'tabs' | 'tab' | 'group' | 'fragment';
}>> {
    components(value: readonly SchemaNodeBuilder[]): this;
}

export interface SplitBuilder extends LayoutBase<Extract<LayoutDefinition, {
    kind: 'split';
}>> {
    components(value: readonly SchemaNodeBuilder[]): this;
    columns(value: number | Record<string, number>): this;
}

export interface PlaceholderBuilder extends LayoutBase<Extract<LayoutDefinition, {
    kind: 'placeholder';
}>> {
    label(value: string): this;
    content(value: FieldClosure | string | number | boolean | null): this;
}

export interface HtmlBuilder extends LayoutBase<Extract<LayoutDefinition, {
    kind: 'html';
}>> {
    content(value: string | FieldClosure<string>): this;
}

export interface ViewBuilder extends LayoutBase<Extract<LayoutDefinition, {
    kind: 'view';
}>> {
    props(value: Record<string, unknown>): this;
}

export interface DividerBuilder extends LayoutBase<Extract<LayoutDefinition, {
    kind: 'divider';
}>> {
}

export interface TextEntryBuilder extends ComponentBuilder<Extract<EntryDefinition, {
    kind: 'textEntry';
}>> {
    label(value: string | null): this;
    badge(value?: boolean): this;
    copyable(value?: boolean): this;
    url(value: NonNullable<TextEntryDefinition['url']>): this;
    dateTime(value?: string): this;
    timezone(value: string): this;
    date(value?: string): this;
    since(value?: boolean): this;
    money(currency: string): this;
    limit(value: number): this;
    markdown(value?: boolean): this;
    html(value?: boolean): this;
    richContent(value: RichContentOptions | FieldClosure<RichContentOptions>): this;
    /** Display labels for stored option values, e.g. `{ draft: 'Draft' }`. */
    options(value: SelectOptions): this;
}

export interface IconEntryBuilder extends ComponentBuilder<Extract<EntryDefinition, {
    kind: 'iconEntry';
}>> {
    label(value: string | null): this;
    boolean(value?: boolean): this;
    icons(value: Record<string, string>): this;
    colors(value: Record<string, string>): this;
}

export interface ImageEntryBuilder extends ComponentBuilder<Extract<EntryDefinition, {
    kind: 'imageEntry';
}>> {
    label(value: string | null): this;
    circular(value?: boolean): this;
}

export interface BadgeEntryBuilder extends SimpleEntryBuilder<Extract<EntryDefinition, {
    kind: 'badgeEntry';
}>> {
    /** Badge colors keyed by the raw stored value. */
    colors(value: Record<string, string>): this;
    /** Display labels for stored option values; `colors` stay keyed by the raw value. */
    options(value: SelectOptions): this;
}

export interface RepeatableEntryBuilder extends SimpleEntryBuilder<Extract<EntryDefinition, {
    kind: 'repeatableEntry';
}>> {
    schema(value: readonly SimpleEntryBuilder<EntryDefinition>[]): this;
}

export type SchemaNodeBuilder = FieldBuilderBase<FieldDefinitionUnion> | TextBuilder | PasswordBuilder | NumberBuilder | SliderBuilder | TextareaBuilder | SelectBuilder | MultiSelectBuilder | DateBuilder | RepeaterBuilder | FileUploadBuilder | RichEditorBuilder | CheckboxBuilder | CheckboxListBuilder | RadioBuilder | ToggleBuilder | ToggleButtonsBuilder | ColorBuilder | TagsBuilder | KeyValueBuilder | BuilderBuilder | WizardBuilder | StepBuilder | GridBuilder | SectionBuilder | FieldsetBuilder | ChildrenLayoutBuilder | SplitBuilder | PlaceholderBuilder | HtmlBuilder | ViewBuilder | DividerBuilder | TextEntryBuilder | IconEntryBuilder | ImageEntryBuilder | SimpleEntryBuilder<EntryDefinition>;

export type FormSchema<M = never> = Omit<SchemaNamespace, keyof FieldConstructors<M> | 'components' | 'entries'> & FieldConstructors<M> & {
    components(value: readonly SchemaNodeBuilder[]): {
        components: SchemaNodeDefinition[];
    };
    entries(value: readonly SchemaNodeBuilder[]): {
        entries: SchemaNodeDefinition[];
    };
};

export type SchemaNamespace = FieldConstructors<never> & {
    grid(): GridBuilder;
    section(heading?: string): SectionBuilder;
    fieldset(label?: string): FieldsetBuilder;
    tabs(tabs?: readonly SchemaNodeBuilder[]): ChildrenLayoutBuilder;
    tab(name: string): ChildrenLayoutBuilder;
    group(name?: string): ChildrenLayoutBuilder;
    split(...children: readonly SchemaNodeBuilder[]): SplitBuilder;
    placeholder(name: string): PlaceholderBuilder;
    html(content?: string): HtmlBuilder;
    divider(): DividerBuilder;
    view(component: string, props?: Record<string, unknown>): ViewBuilder;
    fragment(children?: readonly SchemaNodeBuilder[]): ChildrenLayoutBuilder;
    block(name: string): BuilderBlockBuilder;
    wizard(steps?: readonly SchemaNodeBuilder[]): WizardBuilder;
    step(name: string): StepBuilder;
};
Navigation

Type to search…

↑↓ navigate↵ selectEsc close