import { HTMLAttributes } from "react"; import get from "lodash/get"; import type { ExtractRecordPaths, HintedString } from "ra-core"; import { useFieldValue, useTranslate } from "ra-core"; import { cn } from "@/lib/utils"; import type { FieldProps } from "@/lib/field.type"; /** * Displays a downloadable file link with customizable title and target. * * This field renders file URLs as clickable links that can open in new tabs or trigger downloads. * It supports arrays of files and prevents click bubbling in DataTable rows. * To be used with RecordField or DataTable.Col components, or anywhere a RecordContext is available. * * @see {@link https://marmelab.com/shadcn-admin-kit/docs/filefield/ FileField documentation} * * @example * import { FileField } from '@/components/admin/file-field'; * * * * // renders the record { id: 123, url: 'doc.pdf', title: 'Presentation' } as *
* Presentation *
*/ export const FileField = < // eslint-disable-next-line @typescript-eslint/no-explicit-any RecordType extends Record = Record, >( props: FileFieldProps, ) => { const { className, empty, title, src, target, download, defaultValue, source, record, ...rest } = props; const sourceValue = useFieldValue({ defaultValue, source, record }); const titleValue = useFieldValue({ ...props, // @ts-expect-error We ignore here because title might be a custom label or undefined instead of a field name source: title, })?.toString() ?? title; const translate = useTranslate(); if ( sourceValue == null || (Array.isArray(sourceValue) && sourceValue.length === 0) ) { if (!empty) { return null; } return (
{typeof empty === "string" ? translate(empty, { _: empty }) : empty}
); } if (Array.isArray(sourceValue)) { return (
    {sourceValue.map((file, index) => { const fileTitleValue = title ? get(file, title, title) : title; const srcValue = src ? get(file, src, title) : title; return (
  • e.stopPropagation()} > {fileTitleValue}
  • ); })}
); } return (
e.stopPropagation()} > {titleValue}
); }; export interface FileFieldProps< // eslint-disable-next-line @typescript-eslint/no-explicit-any RecordType extends Record = Record, > extends FieldProps, HTMLAttributes { /** * The source of the link to the file, for an array of files. */ src?: string; title?: HintedString>; target?: HTMLAnchorElement["target"]; download?: HTMLAnchorElement["download"]; }