instantdb-react-ui
Version:
Customizable react components for InstantDB (forms/lists/etc.)
70 lines • 4.38 kB
TypeScript
import { DataAttrDef, EntitiesDef, InstantReactWebDatabase, InstaQLParams, InstaQLResult, LinkAttrDef, LinksDef } from '@instantdb/react';
import { DeepValue, FieldApi, FormOptions } from '@tanstack/react-form';
import { z } from 'zod';
export type EntityLinks = Record<string, LinkAttrDef<any, any>>;
/** The type of form to be used. Either update or create */
export type IDBFormType = 'update' | 'create';
/** The schema of an InstantDB database. Using InstantSchemaDef causes major typescript inference lag, so we use this simplified version instead. */
export interface IDBSchema<Entities extends EntitiesDef, Links extends LinksDef<Entities>> {
entities: Entities;
links: Links;
}
export type IDBSchemaType = IDBSchema<EntitiesDef, any>;
export type IDBEntityType<T extends IDBSchemaType> = keyof T['entities'];
export type IDBQueryType<T extends IDBSchemaType> = InstaQLParams<T>;
/** Extract the type of an InstantDB entity from the InstantQL result */
export type ExtractIDBEntityType<TSchema extends IDBSchemaType, TEntity extends IDBEntityType<TSchema>, TQuery extends IDBQueryType<TSchema>> = NonNullable<InstaQLResult<TSchema, TQuery>[TEntity]> extends (infer U)[] ? U : never;
export interface InstantValue {
id: string;
}
/** API for the IDB Form. This is passed to the tanstackOptions callback and can be accessed by the returned form */
interface IDBFormApi {
/** Updates the database with the current form values */
handleIDBUpdate: () => void;
/** Creates a new entity in the database with the current form values, and returns the id */
handleIDBCreate: () => Promise<string | undefined>;
/** Zod schema for the form entity */
zodSchema: z.ZodObject<any>;
}
/** Checks if 2 values are different. Treats undefined and null as equal values */
export declare const isDifferent: (a: any, b: any) => boolean;
/** An InstantDB wrapper for Tanstack Form. Gain type-safety and automatic database syncing. */
export declare function useIDBForm<TSchema extends IDBSchema<EntitiesDef, any>, TEntity extends keyof TSchema['entities'], TQuery extends InstaQLParams<TSchema>>(options: {
idbOptions: {
type: IDBFormType;
schema: TSchema;
entity: TEntity;
query: TQuery;
db: InstantReactWebDatabase<any>;
linkPickerQueries?: Partial<Record<keyof TSchema['entities'][TEntity]['links'], InstaQLParams<TSchema>>>;
defaultValues?: Partial<{
[K in keyof TSchema['entities'][TEntity]['attrs']]: TSchema['entities'][TEntity]['attrs'][K] extends DataAttrDef<infer T, any> ? T : never;
}>;
serverDebounceFields?: Partial<Record<keyof ExtractIDBEntityType<TSchema, TEntity, TQuery>, number>>;
serverThrottleFields?: Partial<Record<keyof ExtractIDBEntityType<TSchema, TEntity, TQuery>, number>>;
};
tanstackOptions: (idbApi: IDBFormApi) => Omit<FormOptions<ExtractIDBEntityType<TSchema, TEntity, TQuery>, any, any, any, any, any, any, any, any, any>, 'defaultValues'>;
}): Omit<import("@tanstack/react-form").ReactFormExtendedApi<ExtractIDBEntityType<TSchema, TEntity, TQuery>, any, any, any, any, any, any, any, any, any>, "Field"> & {
/** API for the IDB Form. */
idb: IDBFormApi;
Field: <TName extends keyof ExtractIDBEntityType<TSchema, TEntity, TQuery> & string>(props: {
name: TName;
children: (field: IDBFieldApi<ExtractIDBEntityType<TSchema, TEntity, TQuery>, TName>) => React.ReactNode;
[key: string]: any;
}) => React.ReactNode;
};
type IDBFieldApi<TFormData, TName extends keyof TFormData & string, TValue extends DeepValue<TFormData, TName> = DeepValue<TFormData, TName>> = FieldApi<TFormData, TName, TValue, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined> & {
state: {
meta: IDBFieldMeta<TValue>;
};
};
declare const idbSyncedMetaName = "idbSynced";
declare const idbLinkDataMetaName = "idbLinkData";
export interface IDBFieldMeta<T = any> {
/** Whether the field has been synced with the database. Only for debounced fields, which don't update immediately */
[idbSyncedMetaName]: boolean;
/** Data for the relation picker */
[idbLinkDataMetaName]: T extends any[] ? T : T[];
}
export {};
//# sourceMappingURL=use-idb-form.d.ts.map