import * as React from 'react'; import { ReactNode } from 'react'; import { UseQueryOptions } from '@tanstack/react-query'; import { ReferenceFieldContextProvider } from './ReferenceFieldContext'; import { RaRecord } from '../../types'; import { useReferenceFieldController, UseReferenceFieldControllerResult, } from './useReferenceFieldController'; import { ResourceContextProvider } from '../../core'; import { RecordContextProvider } from '../record'; import { useFieldValue } from '../../util'; /** * Fetch reference record, and render its representation, or delegate rendering to child component. * * The reference prop should be the name of one of the components * added as child. * * @example // using recordRepresentation * * * @example // using a Field component to represent the record * * * * * @example // By default, includes a link to the page of the related record * // (`/users/:userId` in the previous example). * // Set the `link` prop to "show" to link to the page instead. * * * @example // You can also prevent `` from adding link to children * // by setting `link` to false. * * * @example // Alternatively, you can also pass a custom function to `link`. * // It must take reference and record as arguments and return a string * "/path/to/${reference}/${record}"} /> * * @default * In previous versions of React-Admin, the prop `linkType` was used. It is now deprecated and replaced with `link`. However * backward-compatibility is still kept */ export const ReferenceFieldBase = < ReferenceRecordType extends RaRecord = RaRecord, >( props: ReferenceFieldBaseProps ) => { const { children, render, loading, error, empty, offline } = props; const id = useFieldValue(props); const controllerProps = useReferenceFieldController(props); if (!render && !children) { throw new Error( " requires either a 'render' prop or 'children' prop" ); } const { error: controllerError, isPending, isPaused, referenceRecord, } = controllerProps; const shouldRenderLoading = id != null && !isPaused && isPending && loading !== false && loading !== undefined; const shouldRenderOffline = isPaused && isPending && offline !== false && offline !== undefined; const shouldRenderError = !!controllerError && error !== false && error !== undefined; const shouldRenderEmpty = !isPaused && (id == null || (!referenceRecord && !controllerError && !isPending && empty !== false && empty !== undefined)); return ( {shouldRenderLoading ? loading : shouldRenderOffline ? offline : shouldRenderError ? error : shouldRenderEmpty ? empty : render ? render(controllerProps) : children} ); }; export interface ReferenceFieldBaseProps< ReferenceRecordType extends RaRecord = RaRecord, RecordType extends Record = Record, > { children?: ReactNode; render?: ( props: UseReferenceFieldControllerResult ) => ReactNode; className?: string; empty?: ReactNode; error?: ReactNode; loading?: ReactNode; offline?: ReactNode; queryOptions?: Partial< UseQueryOptions & { meta?: any; } >; reference: string; record?: RecordType; source: string; }