UNPKG

@hilla/react-crud

Version:

Hilla CRUD utils for React

228 lines 9.37 kB
import { type AbstractModel, type DetachedModelConstructor, type Value } from '@hilla/form'; import { EndpointError } from '@hilla/frontend'; import { FormLayout } from '@hilla/react-components/FormLayout'; import { type UseFormResult } from '@hilla/react-form'; import { type ComponentType, type JSX, type ReactElement } from 'react'; import { type AutoFormFieldProps, type FieldOptions } from './autoform-field.js'; import type { FormService } from './crud.js'; import { type ComponentStyleProps } from './util.js'; export declare const emptyItem: unique symbol; /** * An event that is fired when an error occurs while submitting the form. */ export type SubmitErrorEvent = { /** * The error that occurred. */ error: EndpointError; /** * A function that can be used to set a custom error message. This will be * shown in the form at the same position as the default error message. * You are not required to call this function if you want to handle the * error differently. */ setMessage(message: string): void; }; /** * An event that is fired when the form has been successfully submitted. */ export type SubmitEvent<TItem> = { /** * The item that was submitted, as returned by the service. */ item: TItem; }; /** * An event that is fired when an error occurs while deleting an item. */ export type DeleteErrorEvent = { /** * The error that occurred. */ error: EndpointError; /** * A function that can be used to set a custom error message. This will be * shown in the form at the same position as the default error message. * You are not required to call this function if you want to handle the * error differently. */ setMessage(message: string): void; }; /** * An event that is fired when the form has been successfully deleted. */ export type DeleteEvent<TItem> = { /** * The item that was deleted, as returned by the service. */ item: TItem; }; export type AutoFormLayoutRendererProps<M extends AbstractModel> = Readonly<{ form: UseFormResult<M>; children: ReadonlyArray<ReactElement<AutoFormFieldProps>>; }>; export type AutoFormProps<M extends AbstractModel = AbstractModel> = ComponentStyleProps & Readonly<{ /** * The service to use for saving and deleting items. This must be a * TypeScript service that has been generated by Hilla from a backend Java * service that implements the `dev.hilla.crud.FormService` interface. */ service: FormService<Value<M>>; /** * The entity model to use, which determines which fields to show in the * form. This must be a Typescript model class that has been generated by * Hilla from a backend Java class. The model must match with the type of * the items handled by the service. For example, a `PersonModel` can be * used with a service that handles `Person` instances. * * By default, the form shows fields for all properties of the model which * have a type that is supported. Use the `visibleFields` option to customize * which fields to show and in which order. */ model: DetachedModelConstructor<M>; /** * The property to use to detect an item's ID. The item ID is required for * deleting items via the `FormService.delete` method. The delete button * will not be shown if no item ID can be found. * * By default, the component uses the property annotated with * `jakarta.persistence.Id`, or a property named `id`, in that order. * This option can be used to override the default behavior, or define the ID * property in case a class doesn't have a property matching the defaults. */ itemIdProperty?: string; /** * The item to edit in the form. The form fields are automatically populated * with values from the item's properties. In order to create a new item, * either pass `null`, or leave this prop as undefined. * * Use the `onSubmitSuccess` callback to get notified when the item has been * saved. * * When submitting a new item (i.e. when `item` is null or undefined), the * form will be automatically cleared, allowing to submit another new item. * In order to keep editing the same item after submitting, set the `item` * prop to the new item. */ item?: Value<M> | typeof emptyItem | null; /** * Whether the form should be disabled. This disables all form fields and * all buttons. */ disabled?: boolean; /** * Allows to customize the layout of the form by providing a custom * renderer. The renderer receives the form instance and the pre-rendered * fields as props. The renderer can either reuse the pre-rendered fields in * the custom layout, or render custom fields and connect them to the form * manually. * * Check the component documentation for details and examples. * * Example using pre-rendered fields: * ```tsx * <AutoForm layoutRenderer={({ children }) => * <VerticalLayout> * {children} * <p>All data is collected anonymously.</p> * </VerticalLayout> * } /> * ``` * * Example rendering custom fields: * ```tsx * <AutoForm layoutRenderer={({ form }) => * <VerticalLayout> * <TextField {...form.field(form.model.name)} /> * ... * </VerticalLayout> * } /> * ``` */ layoutRenderer?: ComponentType<AutoFormLayoutRendererProps<M>>; /** * Defines the fields to show in the form, and in which order. This takes * an array of property names. Properties that are not included in this * array will not be shown in the form, and properties that are included, * but don't exist in the model, will be ignored. */ visibleFields?: string[]; /** * Allows to customize the FormLayout used by default. This is especially useful * to define the `responsiveSteps`. See the * {@link https://hilla.dev/docs/react/components/form-layout | FormLayout documentation} * for details. */ formLayoutProps?: ComponentStyleProps & Pick<Parameters<typeof FormLayout>[0], 'responsiveSteps'>; /** * Allows to customize individual fields of the form. This takes an object * where the keys are property names, and the values are options for the * respective field for editing that property. */ fieldOptions?: Record<string, FieldOptions>; /** * Whether to show the delete button in the form. This is disabled by * default. If enabled, the delete button will only be shown when editing * an existing item, which means that `item` is not null. The delete button * will also only be shown if an item has a discernible ID. See the * `itemIdProperty` prop for details how the item ID is detected. * * Use the `onDeleteSuccess` callback to get notified when the item has been * deleted. * * NOTE: This only hides the button, it does not prevent from calling the * delete method on the service. To completely disable deleting, you must * override the `delete` method in the backend Java service to either throw * an exception or annotate it with `@DenyAll` to prevent access. */ deleteButtonVisible?: boolean; /** * A callback that will be called if an unexpected error occurs while * submitting the form. * * Note that this will not be called for validation errors, which are * handled automatically. */ onSubmitError?({ error }: SubmitErrorEvent): void; /** * A callback that will be called after the form has been successfully * submitted and the item has been saved. * * When submitting a new item (i.e. when `item` is null or undefined), the * form will be automatically cleared, allowing to submit another new item. * In order to keep editing the same item after submitting, set the `item` * prop to the new item. */ onSubmitSuccess?({ item }: SubmitEvent<Value<M>>): void; /** * A callback that will be called if an unexpected error occurs while * deleting an item. */ onDeleteError?({ error }: DeleteErrorEvent): void; /** * A callback that will be called after the form has been successfully * deleted. */ onDeleteSuccess?({ item }: DeleteEvent<Value<M>>): void; }>; /** * Auto Form is a component that automatically generates a form for editing, * updating and deleting items from a backend service. * * Example usage: * ```tsx * import { AutoForm } from '@hilla/react-crud'; * import PersonService from 'Frontend/generated/endpoints'; * import PersonModel from 'Frontend/generated/com/example/application/Person'; * * <AutoForm * service={PersonService} * model={PersonModel} * onSubmitSuccess={({ item }) => { * console.log('Submitted item:', item); * }} * /> * ``` */ export declare function AutoForm<M extends AbstractModel>({ service, model, itemIdProperty, item, onSubmitError, onSubmitSuccess, disabled, layoutRenderer: LayoutRenderer, visibleFields, formLayoutProps, fieldOptions, style, id, className, deleteButtonVisible, onDeleteSuccess, onDeleteError, }: AutoFormProps<M>): JSX.Element; //# sourceMappingURL=autoform.d.ts.map