Skip to content

API: Pages and widgets

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/builder/page.ts

Source

export type CustomPageBuilder = {
    readonly definition: CustomPageDefinition;
    path(value: string): CustomPageBuilder;
    title(value: string): CustomPageBuilder;
    icon(value: string): CustomPageBuilder;
    cluster(value: ClusterBuilder): CustomPageBuilder;
    navigation(value: NonNullable<CustomPageDefinition['navigation']>): CustomPageBuilder;
    canAccess(value: NonNullable<CustomPageDefinition['canAccess']>): CustomPageBuilder;
    form(callback: (schema: FormSchema<Record<string, unknown>>) => FormInput): CustomPageBuilder;
    fill(value: NonNullable<CustomPageDefinition['fill']>): CustomPageBuilder;
    save(value: NonNullable<CustomPageDefinition['save']>): CustomPageBuilder;
    actions(value: readonly ActionBuilder[]): CustomPageBuilder;
    component(value: string): CustomPageBuilder;
    widgets(value: readonly Pick<WidgetBuilder, 'toDefinition'>[]): CustomPageBuilder;
    filters(value: readonly WidgetFilterDefinition[]): CustomPageBuilder;
    toDefinition(): CustomPageDefinition;
    toJSON(): string;
};

export function definePage(slug: string): CustomPageBuilder;

src/builder/widget.ts

Source

export type StatBuilder = {
    readonly definition: WidgetStat;
    description(value: string): StatBuilder;
    descriptionIcon(value: string): StatBuilder;
    color(value: string): StatBuilder;
    chart(value: number[]): StatBuilder;
    toDefinition(): WidgetStat;
};

export function stat(label: string, value: string | number): StatBuilder;

export type WidgetBuilder = {
    readonly definition: WidgetDefinition;
    stats(callback: (args: WidgetContext) => StatInput[] | Promise<StatInput[]>): WidgetBuilder;
    timeline(callback: (args: WidgetContext) => TimelineItem[] | Promise<TimelineItem[]>): WidgetBuilder;
    chart<T extends NonNullable<WidgetDefinition['chartType']>>(type: T, callback: (args: WidgetContext) => ChartResult<T> | Promise<ChartResult<T>>): WidgetBuilder;
    table(callback: (schema: TableSchema) => TableSchema): WidgetBuilder;
    component(value: string, loader?: NonNullable<WidgetDefinition['load']>): WidgetBuilder;
    actions(value: readonly ActionBuilder[]): WidgetBuilder;
    span(value: number | 'full'): WidgetBuilder;
    sort(value: number): WidgetBuilder;
    poll(value: string): WidgetBuilder;
    heading(value: string): WidgetBuilder;
    description(value: string): WidgetBuilder;
    canView(value: NonNullable<WidgetDefinition['canView']>): WidgetBuilder;
    lazy(value: boolean): WidgetBuilder;
    toDefinition(): WidgetDefinition;
    toJSON(): string;
};

export function defineWidget(name: string, model?: LucidModel): WidgetBuilder;

src/definition/custom_page.ts

Source

export type CustomPageDefinition = {
    slug: string;
    /** Path relative to the panel (tenant) prefix, e.g. `/settings`. */
    path: string;
    title: string;
    icon?: string;
    cluster?: ClusterDefinition;
    navigation?: {
        group?: string;
        sort?: number;
        label?: string;
        badge?: (ctx: HttpContext) => unknown | Promise<unknown>;
    };
    /** Access gate (nav visibility + 403 on the route). Default: allowed. */
    canAccess?: (ctx: HttpContext) => boolean | Promise<boolean>;
    form?: SchemaNodeDefinition[];
    fill?: (ctx: HttpContext) => Record<string, unknown> | Promise<Record<string, unknown>>;
    save?: (args: {
        data: Record<string, unknown>;
        ctx: HttpContext;
    }) => unknown | Promise<unknown>;
    actions: ActionDefinition[];
    widgets?: WidgetDefinition[];
    filters?: WidgetFilterDefinition[];
    component?: string;
    toJSON(): string;
};

src/definition/widget.ts

Source

export type WidgetStat = {
    label: string;
    value: string | number;
    description?: string;
    descriptionIcon?: string;
    color?: string;
    chart?: number[];
};

export type TimelineItem = {
    title: string;
    description?: string;
    time: string;
    actor?: string;
    icon?: string;
    color?: string;
    changes?: {
        field: string;
        old: unknown;
        new: unknown;
    }[];
};

export type WidgetData = {
    kind: 'stats';
    stats: WidgetStat[];
} | {
    kind: 'chart';
    labels: string[];
    datasets: {
        label: string;
        data: number[];
        color?: string;
    }[];
} | {
    kind: 'scatter';
    datasets: {
        label: string;
        data: {
            x: number;
            y: number;
        }[];
        color?: string;
    }[];
} | {
    kind: 'table';
    data: unknown;
} | {
    kind: 'timeline';
    items: TimelineItem[];
} | {
    kind: 'component';
    data: unknown;
};

export type WidgetContext = {
    ctx: HttpContext;
    filters: Record<string, unknown>;
    record?: unknown;
};

export type WidgetDefinition = {
    name: string;
    kind: 'stats' | 'chart' | 'table' | 'timeline' | 'component';
    load?: (args: WidgetContext) => unknown | Promise<unknown>;
    chartType?: 'line' | 'bar' | 'area' | 'pie' | 'doughnut' | 'radar' | 'scatter';
    table?: TableDefinition;
    model?: LucidModel;
    component?: string;
    actions?: readonly ActionDefinition[];
    heading?: string;
    description?: string;
    span: number | 'full';
    sort: number;
    poll?: string;
    canView?: (ctx: HttpContext) => boolean | Promise<boolean>;
    lazy: boolean;
    toJSON(): string;
};
Navigation

Type to search…

↑↓ navigate↵ selectEsc close